This commit is contained in:
Jack Andersen 2016-03-28 11:39:07 -10:00
commit 81de11f2c3
15 changed files with 1307 additions and 302 deletions

View File

@ -17,7 +17,8 @@ add_library(DNACommon
ANCS.hpp
ANIM.hpp ANIM.cpp
PART.hpp PART.cpp
SWHC.hpp
SWHC.hpp SWHC.cpp
CRSC.hpp CRSC.cpp
ELSC.hpp ELSC.cpp
ParticleCommon.cpp
FONT.hpp FONT.cpp

338
DataSpec/DNACommon/CRSC.cpp Normal file
View File

@ -0,0 +1,338 @@
#include "CRSC.hpp"
namespace DataSpec
{
namespace DNAParticle
{
static const std::vector<FourCC> GeneratorTypes =
{
SBIG('DEFS'),SBIG('CRTS'),SBIG('MTLS'),SBIG('GRAS'),
SBIG('ICEE'),SBIG('GOOO'),SBIG('WODS'),SBIG('WATR'),
SBIG('1MUD'),SBIG('1LAV'),SBIG('1SAN'),SBIG('1PRJ'),
SBIG('DCHR'),SBIG('DCHS'),SBIG('DCSH'),SBIG('DENM'),
SBIG('DESP'),SBIG('DESH'),SBIG('BTLE'),SBIG('WASP'),
SBIG('TALP'),SBIG('PTGM'),SBIG('SPIR'),SBIG('FPIR'),
SBIG('FFLE'),SBIG('PARA'),SBIG('BMON'),SBIG('BFLR'),
SBIG('PBOS'),SBIG('IBOS'),SBIG('1SVA'),SBIG('1RPR'),
SBIG('1MTR'),SBIG('1PDS'),SBIG('1FLB'),SBIG('1DRN'),
SBIG('1MRE'),SBIG('CHOZ'),SBIG('JZAP'),SBIG('1ISE'),
SBIG('1BSE'),SBIG('1ATB'),SBIG('1ATA'),SBIG('BTSP'),
SBIG('WWSP'),SBIG('TASP'),SBIG('TGSP'),SBIG('SPSP'),
SBIG('FPSP'),SBIG('FFSP'),SBIG('PSSP'),SBIG('BMSP'),
SBIG('BFSP'),SBIG('PBSP'),SBIG('IBSP'),SBIG('2SVA'),
SBIG('2RPR'),SBIG('2MTR'),SBIG('2PDS'),SBIG('2FLB'),
SBIG('2DRN'),SBIG('2MRE'),SBIG('CHSP'),SBIG('JZSP'),
SBIG('3ISE'),SBIG('3BSE'),SBIG('3ATB'),SBIG('3ATA'),
SBIG('BTSH'),SBIG('WWSH'),SBIG('TASH'),SBIG('TGSH'),
SBIG('SPSH'),SBIG('FPSH'),SBIG('FFSH'),SBIG('PSSH'),
SBIG('BMSH'),SBIG('BFSH'),SBIG('PBSH'),SBIG('IBSH'),
SBIG('3SVA'),SBIG('3RPR'),SBIG('3MTR'),SBIG('3PDS'),
SBIG('3FLB'),SBIG('3DRN'),SBIG('3MRE'),SBIG('CHSH'),
SBIG('JZSH'),SBIG('5ISE'),SBIG('5BSE'),SBIG('5ATB'),
SBIG('5ATA')
};
static const std::vector<FourCC> SFXTypes =
{
SBIG('DSFX'),SBIG('CSFX'),SBIG('MSFX'),SBIG('GRFX'),
SBIG('ICFX'),SBIG('GOFX'),SBIG('WSFX'),SBIG('WTFX'),
SBIG('2MUD'),SBIG('2LAV'),SBIG('2SAN'),SBIG('2PRJ'),
SBIG('DCFX'),SBIG('DSFX'),SBIG('DSHX'),SBIG('DEFX'),
SBIG('ESFX'),SBIG('SHFX'),SBIG('BEFX'),SBIG('WWFX'),
SBIG('TAFX'),SBIG('GTFX'),SBIG('SPFX'),SBIG('FPFX'),
SBIG('FFFX'),SBIG('PAFX'),SBIG('BMFX'),SBIG('BFFX'),
SBIG('PBFX'),SBIG('IBFX'),SBIG('4SVA'),SBIG('4RPR'),
SBIG('4MTR'),SBIG('4PDS'),SBIG('4FLB'),SBIG('4DRN'),
SBIG('4MRE'),SBIG('CZFX'),SBIG('JZAS'),SBIG('2ISE'),
SBIG('2BSE'),SBIG('2ATB'),SBIG('2ATA'),SBIG('BSFX'),
SBIG('WSFX'),SBIG('TSFX'),SBIG('GSFX'),SBIG('SSFX'),
SBIG('FSFX'),SBIG('SFFX'),SBIG('PSFX'),SBIG('MSFX'),
SBIG('SBFX'),SBIG('PBSX'),SBIG('IBSX'),SBIG('5SVA'),
SBIG('5RPR'),SBIG('5MTR'),SBIG('5PDS'),SBIG('5FLB'),
SBIG('5DRN'),SBIG('5MRE'),SBIG('CSFX'),SBIG('JZPS'),
SBIG('4ISE'),SBIG('4BSE'),SBIG('4ATB'),SBIG('4ATA'),
SBIG('BHFX'),SBIG('WHFX'),SBIG('THFX'),SBIG('GHFX'),
SBIG('SHFX'),SBIG('FHFX'),SBIG('HFFX'),SBIG('PHFX'),
SBIG('MHFX'),SBIG('HBFX'),SBIG('PBHX'),SBIG('IBHX'),
SBIG('6SVA'),SBIG('6RPR'),SBIG('6MTR'),SBIG('6PDS'),
SBIG('6FLB'),SBIG('6DRN'),SBIG('6MRE'),SBIG('CHFX'),
SBIG('JZHS'),SBIG('6ISE'),SBIG('6BSE'),SBIG('6ATB'),
SBIG('6ATA')
};
static const std::vector<FourCC> DecalTypes =
{
SBIG('NCDL'),SBIG('DDCL'),SBIG('CODL'),SBIG('MEDL'),
SBIG('GRDL'),SBIG('ICDL'),SBIG('GODL'),SBIG('WODL'),
SBIG('WTDL'),SBIG('3MUD'),SBIG('3LAV'),SBIG('3SAN'),
SBIG('CHDL'),SBIG('ENDL')
};
template <class IDType>
void CRSM<IDType>::read(athena::io::YAMLDocReader& r)
{
for (const auto& elem : r.getCurNode()->m_mapChildren)
{
if (elem.first.size() < 4)
{
LogModule.report(logvisor::Warning, "short FourCC in element '%s'", elem.first.c_str());
continue;
}
r.enterSubRecord(elem.first.c_str());
FourCC clsId(elem.first.c_str());
auto gen = std::find_if(GeneratorTypes.begin(), GeneratorTypes.end(), [&clsId](const FourCC& other) -> bool{
return clsId == other;
});
if (gen != GeneratorTypes.end())
{
x0_generators[clsId].read(r);
r.leaveSubRecord();
continue;
}
auto sfx = std::find_if(SFXTypes.begin(), SFXTypes.end(), [&clsId](const FourCC& other) -> bool{
return clsId == other;
});
if (sfx != SFXTypes.end())
{
x10_sfx[clsId] = r.readInt32(clsId.toString().c_str());
r.leaveSubRecord();
continue;
}
auto decal = std::find_if(DecalTypes.begin(), DecalTypes.end(), [&clsId](const FourCC& other) -> bool{
return clsId == other;
});
if (decal != DecalTypes.end())
{
x20_decals[clsId].read(r);
r.leaveSubRecord();
continue;
}
if (clsId == SBIG('RNGE'))
x30_RNGE = r.readFloat(nullptr);
else if (clsId == SBIG('FOFF'))
x34_FOFF = r.readFloat(nullptr);
r.leaveSubRecord();
}
}
template <class IDType>
void CRSM<IDType>::write(athena::io::YAMLDocWriter& w) const
{
for (const auto& pair : x0_generators)
{
if (pair.second)
{
w.enterSubRecord(pair.first.toString().c_str());
pair.second.write(w);
w.leaveSubRecord();
}
}
for (const auto& pair : x10_sfx)
{
if (pair.second != ~0)
w.writeUint32(pair.first.toString().c_str(), pair.second);
}
for (const auto& pair : x20_decals)
{
if (pair.second)
{
w.enterSubRecord(pair.first.toString().c_str());
pair.second.write(w);
w.leaveSubRecord();
}
}
if (x30_RNGE != 50.f)
w.writeFloat("RNGE", x30_RNGE);
if (x34_FOFF != 0.2f)
w.writeFloat("FOFF", x34_FOFF);
}
template <class IDType>
size_t CRSM<IDType>::binarySize(size_t __isz) const
{
__isz += 4;
for (const auto& pair : x0_generators)
{
if (pair.second)
__isz = pair.second.binarySize(__isz + 4);
}
for (const auto& pair : x10_sfx)
{
if (pair.second != ~0)
__isz += 12;
}
for (const auto& pair : x20_decals)
{
if (pair.second)
__isz = pair.second.binarySize(__isz + 4);
}
if (x30_RNGE != 50.f)
__isz += 12;
if (x34_FOFF != 0.2f)
__isz += 12;
return __isz;
}
template <class IDType>
void CRSM<IDType>::read(athena::io::IStreamReader &r)
{
uint32_t clsId;
r.readBytesToBuf(&clsId, 4);
if (clsId != SBIG('CRSM'))
{
LogModule.report(logvisor::Warning, "non CRSM provided to CRSM parser");
return;
}
while (clsId != SBIG('_END'))
{
r.readBytesToBuf(&clsId, 4);
auto gen = std::find_if(GeneratorTypes.begin(), GeneratorTypes.end(), [&clsId](const FourCC& other) -> bool{
return clsId == other;
});
if (gen != GeneratorTypes.end())
{
x0_generators[clsId].read(r);
continue;
}
auto sfx = std::find_if(SFXTypes.begin(), SFXTypes.end(), [&clsId](const FourCC& other) -> bool{
return clsId == other;
});
if (sfx != SFXTypes.end())
{
uint32_t fcc;
r.readBytesToBuf(&fcc, 4);
if (fcc != SBIG('NONE'))
x10_sfx[clsId] = r.readInt32Big();
else
x10_sfx[clsId] = ~0;
continue;
}
auto decal = std::find_if(DecalTypes.begin(), DecalTypes.end(), [&clsId](const FourCC& other) -> bool{
return clsId == other;
});
if (decal != DecalTypes.end())
{
x20_decals[clsId].read(r);
continue;
}
if (clsId == SBIG('RNGE'))
{
r.readUint32();
x30_RNGE = r.readFloatBig();
continue;
}
if (clsId == SBIG('FOFF'))
{
r.readUint32();
x34_FOFF = r.readFloatBig();
continue;
}
if (clsId != SBIG('_END'))
LogModule.report(logvisor::Fatal, "Unknown CRSM class %.4s @%" PRIi64, &clsId, r.position());
}
}
template <class IDType>
void CRSM<IDType>::write(athena::io::IStreamWriter& w) const
{
w.writeBytes("CRSM", 4);
for (const auto& pair : x0_generators)
{
if (pair.second)
{
w.writeBytes(pair.first.toString().c_str(), 4);
pair.second.write(w);
}
}
for (const auto& pair : x10_sfx)
{
if (pair.second != ~0)
{
w.writeBytes(pair.first.toString().c_str(), 4);
w.writeUint32Big(pair.second);
}
}
for (const auto& pair : x20_decals)
{
if (pair.second)
{
w.writeBytes(pair.first.toString().c_str(), 4);
pair.second.write(w);
}
}
if (x30_RNGE != 50.f)
{
w.writeBytes("RNGECNST", 8);
w.writeFloatBig(x30_RNGE);
}
if (x34_FOFF != 0.2f)
{
w.writeBytes("FOFFCNST", 8);
w.writeFloatBig(x34_FOFF);
}
w.writeBytes("_END", 4);
}
template <class IDType>
CRSM<IDType>::CRSM()
: x30_RNGE(50.f),
x34_FOFF(0.2f)
{
for (const auto& sfx : SFXTypes)
x10_sfx[sfx] = ~0;
}
template struct CRSM<UniqueID32>;
template struct CRSM<UniqueID64>;
template <class IDType>
bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
FILE* fp = hecl::Fopen(outPath.getAbsolutePath().c_str(), _S("w"));
if (fp)
{
CRSM<IDType> crsm;
crsm.read(rs);
crsm.toYAMLFile(fp);
fclose(fp);
return true;
}
return false;
}
template bool ExtractCRSM<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template bool ExtractCRSM<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteCRSM(const CRSM<IDType>& crsm, const hecl::ProjectPath& outPath)
{
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
crsm.write(w);
int64_t rem = w.position() % 32;
if (rem)
for (int64_t i=0 ; i<32-rem ; ++i)
w.writeBytes((atInt8*)"\xff", 1);
return true;
}
template bool WriteCRSM<UniqueID32>(const CRSM<UniqueID32>& crsm, const hecl::ProjectPath& outPath);
template bool WriteCRSM<UniqueID64>(const CRSM<UniqueID64>& crsm, const hecl::ProjectPath& outPath);
}
}

View File

@ -0,0 +1,40 @@
#ifndef CRSC_HPP
#define CRSC_HPP
#include "ParticleCommon.hpp"
#include "PAK.hpp"
#include "athena/FileWriter.hpp"
#include "optional.hpp"
namespace DataSpec
{
namespace DNAParticle
{
template <class IDType>
struct CRSM : BigYAML
{
static const char* DNAType() { return "CRSM"; }
const char* DNATypeV() const { return DNAType(); }
std::unordered_map<FourCC, ChildResourceFactory<IDType>> x0_generators;
std::unordered_map<FourCC, uint32_t> x10_sfx;
std::unordered_map<FourCC, ChildResourceFactory<IDType>> x20_decals;
float x30_RNGE;
float x34_FOFF;
void read(athena::io::YAMLDocReader& r);
void write(athena::io::YAMLDocWriter& w) const;
size_t binarySize(size_t __isz) const;
void read(athena::io::IStreamReader& r);
void write(athena::io::IStreamWriter& w) const;
CRSM();
};
template <class IDType>
bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteCRSM(const CRSM<IDType>& crsm, const hecl::ProjectPath& outPath);
}
}
#endif // CRSC_HPP

View File

@ -441,6 +441,7 @@ void ELSM<IDType>::write(athena::io::IStreamWriter& w) const
w.writeBytes((atInt8*)"ZERY", 4);
x70_ZERY.write(w);
}
w.writeBytes("_END", 4);
}
template struct ELSM<UniqueID32>;

View File

@ -21,246 +21,246 @@ void GPSM<IDType>::read(athena::io::YAMLDocReader& r)
{
case SBIG('PMCL'):
x78_PMCL.read(r);
break;
break;
case SBIG('LFOR'):
x118_LFOR.read(r);
break;
break;
case SBIG('IDTS'):
xa4_IDTS.read(r);
break;
break;
case SBIG('EMTR'):
x40_EMTR.read(r);
break;
break;
case SBIG('COLR'):
x30_COLR.read(r);
break;
break;
case SBIG('CIND'):
x45_30_CIND = r.readBool(nullptr);
break;
break;
case SBIG('AAPH'):
x44_26_AAPH = r.readBool(nullptr);
break;
break;
case SBIG('CSSD'):
xa0_CSSD.read(r);
break;
break;
case SBIG('GRTE'):
x2c_GRTE.read(r);
break;
break;
case SBIG('FXLL'):
x44_25_FXLL = r.readBool(nullptr);
break;
break;
case SBIG('ICTS'):
x8c_ICTS.read(r);
break;
break;
case SBIG('KSSM'):
xd0_KSSM.read(r);
break;
break;
case SBIG('ILOC'):
x38_ILOC.read(r);
break;
break;
case SBIG('IITS'):
xb8_IITS.read(r);
break;
break;
case SBIG('IVEC'):
x3c_IVEC.read(r);
break;
break;
case SBIG('LDIR'):
x110_LDIR.read(r);
break;
break;
case SBIG('LCLR'):
x104_LCLR.read(r);
break;
break;
case SBIG('LENG'):
x20_LENG.read(r);
break;
break;
case SBIG('MAXP'):
x28_MAXP.read(r);
break;
break;
case SBIG('LOFF'):
x10c_LOFF.read(r);
break;
break;
case SBIG('LINT'):
x108_LINT.read(r);
break;
break;
case SBIG('LINE'):
x44_24_LINE = r.readBool(nullptr);
break;
break;
case SBIG('LFOT'):
x114_LFOT.read(r);
break;
break;
case SBIG('LIT_'):
x44_29_LIT_ = r.readBool(nullptr);
break;
break;
case SBIG('LTME'):
x34_LTME.read(r);
break;
break;
case SBIG('LSLA'):
x11c_LSLA.read(r);
break;
break;
case SBIG('LTYP'):
x100_LTYP.read(r);
break;
break;
case SBIG('NDSY'):
xb4_NDSY.read(r);
break;
break;
case SBIG('MBSP'):
x48_MBSP.read(r);
break;
break;
case SBIG('MBLR'):
x44_30_MBLR = r.readBool(nullptr);
break;
break;
case SBIG('NCSY'):
x9c_NCSY.read(r);
break;
break;
case SBIG('PISY'):
xc8_PISY.read(r);
break;
break;
case SBIG('OPTS'):
x45_31_OPTS = r.readBool(nullptr);
break;
break;
case SBIG('PMAB'):
x44_31_PMAB = r.readBool(nullptr);
break;
break;
case SBIG('SESD'):
xf8_SESD.read(r);
break;
break;
case SBIG('SEPO'):
xfc_SEPO.read(r);
break;
break;
case SBIG('PSLT'):
xc_PSLT.read(r);
break;
break;
case SBIG('PMSC'):
x74_PMSC.read(r);
break;
break;
case SBIG('PMOP'):
x6c_PMOP.read(r);
break;
break;
case SBIG('PMDL'):
x5c_PMDL.read(r);
break;
break;
case SBIG('PMRT'):
x70_PMRT.read(r);
break;
break;
case SBIG('POFS'):
x18_POFS.read(r);
break;
break;
case SBIG('PMUS'):
x45_24_PMUS = r.readBool(nullptr);
break;
break;
case SBIG('PSIV'):
x0_PSIV.read(r);
break;
break;
case SBIG('ROTA'):
x50_ROTA.read(r);
break;
break;
case SBIG('PSVM'):
x4_PSVM.read(r);
break;
break;
case SBIG('PSTS'):
x14_PSTS.read(r);
break;
break;
case SBIG('PSOV'):
x8_PSOV.read(r);
break;
break;
case SBIG('PSWT'):
x10_PSWT.read(r);
break;
break;
case SBIG('PMLC'):
xec_PMLC.read(r);
break;
break;
case SBIG('SEED'):
x1c_SEED.read(r);
break;
break;
case SBIG('PMOO'):
x45_25_PMOO = r.readBool(nullptr);
break;
break;
case SBIG('SSSD'):
xe4_SSSD.read(r);
break;
break;
case SBIG('SORT'):
x44_28_SORT = r.readBool(nullptr);
break;
break;
case SBIG('SIZE'):
x4c_SIZE.read(r);
break;
break;
case SBIG('SISY'):
xcc_SISY.read(r);
break;
break;
case SBIG('SSPO'):
xe8_SSPO.read(r);
break;
break;
case SBIG('TEXR'):
x54_TEXR.read(r);
break;
break;
case SBIG('SSWH'):
xd4_SSWH.read(r);
break;
break;
case SBIG('TIND'):
x58_TIND.read(r);
break;
break;
case SBIG('VMD4'):
x45_29_VMD4 = r.readBool(nullptr);
break;
break;
case SBIG('VMD3'):
x45_28_VMD3 = r.readBool(nullptr);
break;
break;
case SBIG('VMD2'):
x45_27_VMD2 = r.readBool(nullptr);
break;
break;
case SBIG('VMD1'):
x45_26_VMD1 = r.readBool(nullptr);
break;
break;
case SBIG('VEL4'):
x88_VEL4.read(r);
break;
break;
case SBIG('VEL3'):
x84_VEL3.read(r);
break;
break;
case SBIG('VEL2'):
x80_VEL2.read(r);
break;
break;
case SBIG('VEL1'):
x7c_VEL1.read(r);
break;
break;
case SBIG('ZBUF'):
x44_27_ZBUF = r.readBool(nullptr);
break;
break;
case SBIG('WIDT'):
x24_WIDT.read(r);
break;
break;
case SBIG('ORNT'):
x30_30_ORNT = r.readBool(nullptr);
break;
break;
case SBIG('RSOP'):
x30_31_RSOP = r.readBool(nullptr);
break;
break;
case SBIG('ADV1'):
x10c_ADV1.read(r);
break;
break;
case SBIG('ADV2'):
x110_ADV2.read(r);
break;
break;
case SBIG('ADV3'):
x114_ADV3.read(r);
break;
break;
case SBIG('ADV4'):
x118_ADV4.read(r);
break;
break;
case SBIG('ADV5'):
x11c_ADV5.read(r);
break;
break;
case SBIG('ADV6'):
x120_ADV6.read(r);
break;
break;
case SBIG('ADV7'):
x124_ADV7.read(r);
break;
break;
case SBIG('SELC'):
xd8_SELC.read(r);
break;
break;
default:
break;
break;
}
r.leaveSubRecord();
}
@ -871,268 +871,268 @@ void GPSM<IDType>::read(athena::io::IStreamReader& r)
{
case SBIG('PMCL'):
x78_PMCL.read(r);
break;
break;
case SBIG('LFOR'):
x118_LFOR.read(r);
break;
break;
case SBIG('IDTS'):
xa4_IDTS.read(r);
break;
break;
case SBIG('EMTR'):
x40_EMTR.read(r);
break;
break;
case SBIG('COLR'):
x30_COLR.read(r);
break;
break;
case SBIG('CIND'):
r.readUint32Big();
x45_30_CIND = r.readBool();
break;
break;
case SBIG('AAPH'):
r.readUint32Big();
x44_26_AAPH = r.readBool();
break;
break;
case SBIG('CSSD'):
xa0_CSSD.read(r);
break;
break;
case SBIG('GRTE'):
x2c_GRTE.read(r);
break;
break;
case SBIG('FXLL'):
r.readUint32Big();
x44_25_FXLL = r.readBool();
break;
break;
case SBIG('ICTS'):
x8c_ICTS.read(r);
break;
break;
case SBIG('KSSM'):
xd0_KSSM.read(r);
break;
break;
case SBIG('ILOC'):
x38_ILOC.read(r);
break;
break;
case SBIG('IITS'):
xb8_IITS.read(r);
break;
break;
case SBIG('IVEC'):
x3c_IVEC.read(r);
break;
break;
case SBIG('LDIR'):
x110_LDIR.read(r);
break;
break;
case SBIG('LCLR'):
x104_LCLR.read(r);
break;
break;
case SBIG('LENG'):
x20_LENG.read(r);
break;
break;
case SBIG('MAXP'):
x28_MAXP.read(r);
break;
break;
case SBIG('LOFF'):
x10c_LOFF.read(r);
break;
break;
case SBIG('LINT'):
x108_LINT.read(r);
break;
break;
case SBIG('LINE'):
r.readUint32Big();
x44_24_LINE = r.readBool();
break;
break;
case SBIG('LFOT'):
x114_LFOT.read(r);
break;
break;
case SBIG('LIT_'):
r.readUint32Big();
x44_29_LIT_ = r.readBool();
break;
break;
case SBIG('LTME'):
x34_LTME.read(r);
break;
break;
case SBIG('LSLA'):
x11c_LSLA.read(r);
break;
break;
case SBIG('LTYP'):
x100_LTYP.read(r);
break;
break;
case SBIG('NDSY'):
xb4_NDSY.read(r);
break;
break;
case SBIG('MBSP'):
x48_MBSP.read(r);
break;
break;
case SBIG('MBLR'):
r.readUint32Big();
x44_30_MBLR = r.readBool();
break;
break;
case SBIG('NCSY'):
x9c_NCSY.read(r);
break;
break;
case SBIG('PISY'):
xc8_PISY.read(r);
break;
break;
case SBIG('OPTS'):
r.readUint32Big();
x45_31_OPTS = r.readBool();
break;
break;
case SBIG('PMAB'):
r.readUint32Big();
x44_31_PMAB = r.readBool();
break;
break;
case SBIG('SESD'):
xf8_SESD.read(r);
break;
break;
case SBIG('SEPO'):
xfc_SEPO.read(r);
break;
break;
case SBIG('PSLT'):
xc_PSLT.read(r);
break;
break;
case SBIG('PMSC'):
x74_PMSC.read(r);
break;
break;
case SBIG('PMOP'):
x6c_PMOP.read(r);
break;
break;
case SBIG('PMDL'):
x5c_PMDL.read(r);
break;
break;
case SBIG('PMRT'):
x70_PMRT.read(r);
break;
break;
case SBIG('POFS'):
x18_POFS.read(r);
break;
break;
case SBIG('PMUS'):
r.readUint32Big();
x45_24_PMUS = r.readBool();
break;
break;
case SBIG('PSIV'):
x0_PSIV.read(r);
break;
break;
case SBIG('ROTA'):
x50_ROTA.read(r);
break;
break;
case SBIG('PSVM'):
x4_PSVM.read(r);
break;
break;
case SBIG('PSTS'):
x14_PSTS.read(r);
break;
break;
case SBIG('PSOV'):
x8_PSOV.read(r);
break;
break;
case SBIG('PSWT'):
x10_PSWT.read(r);
break;
break;
case SBIG('PMLC'):
xec_PMLC.read(r);
break;
break;
case SBIG('SEED'):
x1c_SEED.read(r);
break;
break;
case SBIG('PMOO'):
r.readUint32Big();
x45_25_PMOO = r.readBool();
break;
break;
case SBIG('SSSD'):
xe4_SSSD.read(r);
break;
break;
case SBIG('SORT'):
r.readUint32Big();
x44_28_SORT = r.readBool();
break;
break;
case SBIG('SIZE'):
x4c_SIZE.read(r);
break;
break;
case SBIG('SISY'):
xcc_SISY.read(r);
break;
break;
case SBIG('SSPO'):
xe8_SSPO.read(r);
break;
break;
case SBIG('TEXR'):
x54_TEXR.read(r);
break;
break;
case SBIG('SSWH'):
xd4_SSWH.read(r);
break;
break;
case SBIG('TIND'):
x58_TIND.read(r);
break;
break;
case SBIG('VMD4'):
r.readUint32Big();
x45_29_VMD4 = r.readBool();
break;
break;
case SBIG('VMD3'):
r.readUint32Big();
x45_28_VMD3 = r.readBool();
break;
break;
case SBIG('VMD2'):
r.readUint32Big();
x45_27_VMD2 = r.readBool();
break;
break;
case SBIG('VMD1'):
r.readUint32Big();
x45_26_VMD1 = r.readBool();
break;
break;
case SBIG('VEL4'):
x88_VEL4.read(r);
break;
break;
case SBIG('VEL3'):
x84_VEL3.read(r);
break;
break;
case SBIG('VEL2'):
x80_VEL2.read(r);
break;
break;
case SBIG('VEL1'):
x7c_VEL1.read(r);
break;
break;
case SBIG('ZBUF'):
r.readUint32Big();
x44_27_ZBUF = r.readBool();
break;
break;
case SBIG('WIDT'):
x24_WIDT.read(r);
break;
break;
case SBIG('ORNT'):
r.readUint32Big();
x30_30_ORNT = r.readBool();
break;
break;
case SBIG('RSOP'):
r.readUint32Big();
x30_31_RSOP = r.readBool();
break;
break;
case SBIG('ADV1'):
x10c_ADV1.read(r);
break;
break;
case SBIG('ADV2'):
x110_ADV2.read(r);
break;
break;
case SBIG('ADV3'):
x114_ADV3.read(r);
break;
break;
case SBIG('ADV4'):
x118_ADV4.read(r);
break;
break;
case SBIG('ADV5'):
x11c_ADV5.read(r);
break;
break;
case SBIG('ADV6'):
x120_ADV6.read(r);
break;
break;
case SBIG('ADV7'):
x124_ADV7.read(r);
break;
break;
case SBIG('ADV8'):
x128_ADV8.read(r);
break;
break;
case SBIG('SELC'):
xd8_SELC.read(r);
break;
break;
default:
LogModule.report(logvisor::Fatal, "Unknown GPSM class %.4s @%" PRIi64, &clsId, r.position());
break;
break;
}
r.readBytesToBuf(&clsId, 4);
}
@ -1529,6 +1529,7 @@ void GPSM<IDType>::write(athena::io::IStreamWriter& w) const
w.writeBytes((atInt8*)"ADV8", 4);
x128_ADV8.write(w);
}
w.writeBytes("_END", 4);
}
template struct GPSM<UniqueID32>;

578
DataSpec/DNACommon/SWHC.cpp Normal file
View File

@ -0,0 +1,578 @@
#include "SWHC.hpp"
namespace DataSpec
{
namespace DNAParticle
{
template <class IDType>
void SWSH<IDType>::read(athena::io::YAMLDocReader& r)
{
for (const auto& elem : r.getCurNode()->m_mapChildren)
{
if (elem.first.size() < 4)
{
LogModule.report(logvisor::Warning, "short FourCC in element '%s'", elem.first.c_str());
continue;
}
r.enterSubRecord(elem.first.c_str());
switch(*reinterpret_cast<const uint32_t*>(elem.first.data()))
{
case SBIG('PSLT'):
x0_PSLT.read(r);
break;
case SBIG('TIME'):
x4_TIME.read(r);
break;
case SBIG('LRAD'):
x8_LRAD.read(r);
break;
case SBIG('RRAD'):
xc_RRAD.read(r);
break;
case SBIG('LENG'):
x10_LENG.read(r);
break;
case SBIG('COLR'):
x14_COLR.read(r);
break;
case SBIG('SIDE'):
x18_SIDE.read(r);
break;
case SBIG('IROT'):
x1c_IROT.read(r);
break;
case SBIG('ROTM'):
x20_ROTM.read(r);
break;
case SBIG('POFS'):
x24_POFS.read(r);
break;
case SBIG('IVEL'):
x28_IVEL.read(r);
break;
case SBIG('NPOS'):
x2c_NPOS.read(r);
break;
case SBIG('VELM'):
x30_VELM.read(r);
break;
case SBIG('VLM2'):
x34_VLM2.read(r);
break;
case SBIG('SPLN'):
x38_SPLN.read(r);
break;
case SBIG('TEXR'):
x3c_TEXR.read(r);
break;
case SBIG('TSPN'):
x40_TSPN.read(r);
break;
case SBIG('LLRD'):
x44_24_LLRD = r.readBool(nullptr);
break;
case SBIG('CROS'):
x44_25_CROS = r.readBool(nullptr);
break;
case SBIG('VLS1'):
x44_26_VLS1 = r.readBool(nullptr);
break;
case SBIG('VLS2'):
x44_27_VLS2 = r.readBool(nullptr);
break;
case SBIG('SROT'):
x44_28_SROT = r.readBool(nullptr);
break;
case SBIG('WIRE'):
x44_29_WIRE = r.readBool(nullptr);
break;
case SBIG('TEXW'):
x44_30_TEXW = r.readBool(nullptr);
break;
case SBIG('AALP'):
x44_31_AALP = r.readBool(nullptr);
break;
case SBIG('ZBUF'):
x45_24_ZBUF = r.readBool(nullptr);
break;
case SBIG('ORNT'):
x45_25_ORNT = r.readBool(nullptr);
break;
case SBIG('CRND'):
x45_26_CRND = r.readBool(nullptr);
break;
}
r.leaveSubRecord();
}
}
template <class IDType>
void SWSH<IDType>::write(athena::io::YAMLDocWriter& w) const
{
if (x0_PSLT)
{
w.enterSubRecord("PSLT");
x0_PSLT.write(w);
w.leaveSubRecord();
}
if (x4_TIME)
{
w.enterSubRecord("TIME");
x4_TIME.write(w);
w.leaveSubRecord();
}
if (x8_LRAD)
{
w.enterSubRecord("LRAD");
x8_LRAD.write(w);
w.leaveSubRecord();
}
if (xc_RRAD)
{
w.enterSubRecord("RRAD");
xc_RRAD.write(w);
w.leaveSubRecord();
}
if (x10_LENG)
{
w.enterSubRecord("LENG");
x10_LENG.write(w);
w.leaveSubRecord();
}
if (x14_COLR)
{
w.enterSubRecord("COLR");
x14_COLR.write(w);
w.leaveSubRecord();
}
if (x18_SIDE)
{
w.enterSubRecord("SIDE");
x18_SIDE.write(w);
w.leaveSubRecord();
}
if (x1c_IROT)
{
w.enterSubRecord("IROT");
x1c_IROT.write(w);
w.leaveSubRecord();
}
if (x20_ROTM)
{
w.enterSubRecord("ROTM");
x20_ROTM.write(w);
w.leaveSubRecord();
}
if (x24_POFS)
{
w.enterSubRecord("POFS");
x24_POFS.write(w);
w.leaveSubRecord();
}
if (x28_IVEL)
{
w.enterSubRecord("IVEL");
x28_IVEL.write(w);
w.leaveSubRecord();
}
if (x2c_NPOS)
{
w.enterSubRecord("NPOS");
x2c_NPOS.write(w);
w.leaveSubRecord();
}
if (x30_VELM)
{
w.enterSubRecord("VELM");
x30_VELM.write(w);
w.leaveSubRecord();
}
if (x34_VLM2)
{
w.enterSubRecord("VLM2");
x34_VLM2.write(w);
w.leaveSubRecord();
}
if (x38_SPLN)
{
w.enterSubRecord("SPLN");
x38_SPLN.write(w);
w.leaveSubRecord();
}
if (x3c_TEXR)
{
w.enterSubRecord("TEXR");
x3c_TEXR.write(w);
w.leaveSubRecord();
}
if (x40_TSPN)
{
w.enterSubRecord("TSPN");
x40_TSPN.write(w);
w.leaveSubRecord();
}
if (x44_24_LLRD)
w.writeBool("LLRD", true);
if (!x44_25_CROS)
w.writeBool("CROS", false);
if (x44_26_VLS1)
w.writeBool("VLS1", true);
if (x44_27_VLS2)
w.writeBool("VLS2", true);
if (x44_28_SROT)
w.writeBool("SROT", true);
if (x44_29_WIRE)
w.writeBool("WIRE", true);
if (x44_30_TEXW)
w.writeBool("TEXW", true);
if (x44_31_AALP)
w.writeBool("AALP", true);
if (x45_24_ZBUF)
w.writeBool("ZBUF", true);
if (x45_25_ORNT)
w.writeBool("ORNT", true);
if (x45_26_CRND)
w.writeBool("CRND", true);
}
template <class IDType>
size_t SWSH<IDType>::binarySize(size_t __isz) const
{
__isz += 4;
if (x0_PSLT)
__isz = x0_PSLT.binarySize(__isz + 4);
if (x4_TIME)
__isz = x4_TIME.binarySize(__isz + 4);
if (x8_LRAD)
__isz = x8_LRAD.binarySize(__isz + 4);
if (xc_RRAD)
__isz = xc_RRAD.binarySize(__isz + 4);
if (x10_LENG)
__isz = x10_LENG.binarySize(__isz + 4);
if (x14_COLR)
__isz = x14_COLR.binarySize(__isz + 4);
if (x18_SIDE)
__isz = x18_SIDE.binarySize(__isz + 4);
if (x1c_IROT)
__isz = x1c_IROT.binarySize(__isz + 4);
if (x20_ROTM)
__isz = x20_ROTM.binarySize(__isz + 4);
if (x24_POFS)
__isz = x24_POFS.binarySize(__isz + 4);
if (x28_IVEL)
__isz = x28_IVEL.binarySize(__isz + 4);
if (x2c_NPOS)
__isz = x2c_NPOS.binarySize(__isz + 4);
if (x30_VELM)
__isz = x30_VELM.binarySize(__isz + 4);
if (x34_VLM2)
__isz = x34_VLM2.binarySize(__isz + 4);
if (x38_SPLN)
__isz = x38_SPLN.binarySize(__isz + 4);
if (x3c_TEXR)
__isz = x3c_TEXR.binarySize(__isz + 4);
if (x40_TSPN)
__isz = x40_TSPN.binarySize(__isz + 4);
if (x44_24_LLRD)
__isz += 9;
if (!x44_25_CROS)
__isz += 9;
if (x44_26_VLS1)
__isz += 9;
if (x44_27_VLS2)
__isz += 9;
if (x44_28_SROT)
__isz += 9;
if (x44_29_WIRE)
__isz += 9;
if (x44_30_TEXW)
__isz += 9;
if (x44_31_AALP)
__isz += 9;
if (x45_24_ZBUF)
__isz += 9;
if (x45_25_ORNT)
__isz += 9;
if (x45_26_CRND)
__isz += 9;
return __isz;
}
template <class IDType>
void SWSH<IDType>::read(athena::io::IStreamReader& r)
{
uint32_t clsId;
r.readBytesToBuf(&clsId, 4);
if (clsId != SBIG('SWSH'))
{
LogModule.report(logvisor::Warning, "non SWSH provided to SWSH parser");
return;
}
r.readBytesToBuf(&clsId, 4);
while (clsId != SBIG('_END'))
{
switch(clsId)
{
case SBIG('PSLT'):
x0_PSLT.read(r);
break;
case SBIG('TIME'):
x4_TIME.read(r);
break;
case SBIG('LRAD'):
x8_LRAD.read(r);
break;
case SBIG('RRAD'):
xc_RRAD.read(r);
break;
case SBIG('LENG'):
x10_LENG.read(r);
break;
case SBIG('COLR'):
x14_COLR.read(r);
break;
case SBIG('SIDE'):
x18_SIDE.read(r);
break;
case SBIG('IROT'):
x1c_IROT.read(r);
break;
case SBIG('ROTM'):
x20_ROTM.read(r);
break;
case SBIG('POFS'):
x24_POFS.read(r);
break;
case SBIG('IVEL'):
x28_IVEL.read(r);
break;
case SBIG('NPOS'):
x2c_NPOS.read(r);
break;
case SBIG('VELM'):
x30_VELM.read(r);
break;
case SBIG('VLM2'):
x34_VLM2.read(r);
break;
case SBIG('SPLN'):
x38_SPLN.read(r);
break;
case SBIG('TEXR'):
x3c_TEXR.read(r);
break;
case SBIG('TSPN'):
x40_TSPN.read(r);
break;
case SBIG('LLRD'):
r.readUint32Big();
x44_24_LLRD = r.readBool();
break;
case SBIG('CROS'):
r.readUint32Big();
x44_25_CROS = r.readBool();
break;
case SBIG('VLS1'):
r.readUint32Big();
x44_26_VLS1 = r.readBool();
break;
case SBIG('VLS2'):
r.readUint32Big();
x44_27_VLS2 = r.readBool();
break;
case SBIG('SROT'):
r.readUint32Big();
x44_28_SROT = r.readBool();
break;
case SBIG('WIRE'):
r.readUint32Big();
x44_29_WIRE = r.readBool();
break;
case SBIG('TEXW'):
r.readUint32Big();
x44_30_TEXW = r.readBool();
break;
case SBIG('AALP'):
r.readUint32Big();
x44_31_AALP = r.readBool();
break;
case SBIG('ZBUF'):
r.readUint32Big();
x45_24_ZBUF = r.readBool();
break;
case SBIG('ORNT'):
r.readUint32Big();
x45_25_ORNT = r.readBool();
break;
case SBIG('CRND'):
r.readUint32Big();
x45_26_CRND = r.readBool();
break;
default:
LogModule.report(logvisor::Fatal, "Unknown SWSH class %.4s @%" PRIi64, &clsId, r.position());
break;
}
r.readBytesToBuf(&clsId, 4);
}
}
template <class IDType>
void SWSH<IDType>::write(athena::io::IStreamWriter& w) const
{
w.writeBytes((atInt8*)"SWSH", 4);
if (x0_PSLT)
{
w.writeBytes((atInt8*)"PSLT", 4);
x0_PSLT.write(w);
}
if (x4_TIME)
{
w.writeBytes((atInt8*)"TIME", 4);
x4_TIME.write(w);
}
if (x8_LRAD)
{
w.writeBytes((atInt8*)"LRAD", 4);
x8_LRAD.write(w);
}
if (xc_RRAD)
{
w.writeBytes((atInt8*)"RRAD", 4);
xc_RRAD.write(w);
}
if (x10_LENG)
{
w.writeBytes((atInt8*)"LENG", 4);
x10_LENG.write(w);
}
if (x14_COLR)
{
w.writeBytes((atInt8*)"COLR", 4);
x14_COLR.write(w);
}
if (x18_SIDE)
{
w.writeBytes((atInt8*)"SIDE", 4);
x18_SIDE.write(w);
}
if (x1c_IROT)
{
w.writeBytes((atInt8*)"IROT", 4);
x1c_IROT.write(w);
}
if (x20_ROTM)
{
w.writeBytes((atInt8*)"ROTM", 4);
x20_ROTM.write(w);
}
if (x24_POFS)
{
w.writeBytes((atInt8*)"POFS", 4);
x24_POFS.write(w);
}
if (x28_IVEL)
{
w.writeBytes((atInt8*)"IVEL", 4);
x28_IVEL.write(w);
}
if (x2c_NPOS)
{
w.writeBytes((atInt8*)"NPOS", 4);
x2c_NPOS.write(w);
}
if (x30_VELM)
{
w.writeBytes((atInt8*)"VELM", 4);
x30_VELM.write(w);
}
if (x34_VLM2)
{
w.writeBytes((atInt8*)"VLM2", 4);
x34_VLM2.write(w);
}
if (x38_SPLN)
{
w.writeBytes((atInt8*)"SPLN", 4);
x38_SPLN.write(w);
}
if (x3c_TEXR)
{
w.writeBytes((atInt8*)"TEXR", 4);
x3c_TEXR.write(w);
}
if (x40_TSPN)
{
w.writeBytes((atInt8*)"TSPN", 4);
x40_TSPN.write(w);
}
if (x44_24_LLRD)
w.writeBytes("LLRDCNST\x01", 9);
if (!x44_25_CROS)
w.writeBytes("CROSCNST\x00", 9);
if (x44_26_VLS1)
w.writeBytes("VLS1CNST\x01", 9);
if (x44_27_VLS2)
w.writeBytes("VLS2CNST\x01", 9);
if (x44_28_SROT)
w.writeBytes("SROTCNST\x01", 9);
if (x44_29_WIRE)
w.writeBytes("WIRECNST\x01", 9);
if (x44_30_TEXW)
w.writeBytes("TEXWCNST\x01", 9);
if (x44_31_AALP)
w.writeBytes("AALPCNST\x01", 9);
if (x45_24_ZBUF)
w.writeBytes("ZBUFCNST\x01", 9);
if (x45_25_ORNT)
w.writeBytes("ORNTCNST\x01", 9);
if (x45_26_CRND)
w.writeBytes("CRNDCNST\x01", 9);
w.writeBytes("_END", 4);
}
template struct SWSH<UniqueID32>;
template struct SWSH<UniqueID64>;
template <class IDType>
bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{
FILE* fp = hecl::Fopen(outPath.getAbsolutePath().c_str(), _S("w"));
if (fp)
{
SWSH<IDType> swsh;
swsh.read(rs);
swsh.toYAMLFile(fp);
fclose(fp);
return true;
}
return false;
}
template bool ExtractSWSH<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template bool ExtractSWSH<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteSWSH(const SWSH<IDType>& swsh, const hecl::ProjectPath& outPath)
{
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
swsh.write(w);
int64_t rem = w.position() % 32;
if (rem)
for (int64_t i=0 ; i<32-rem ; ++i)
w.writeBytes((atInt8*)"\xff", 1);
return true;
}
template bool WriteSWSH<UniqueID32>(const SWSH<UniqueID32>& swsh, const hecl::ProjectPath& outPath);
template bool WriteSWSH<UniqueID64>(const SWSH<UniqueID64>& swsh, const hecl::ProjectPath& outPath);
}
}

View File

@ -1,4 +1,67 @@
#ifndef __COMMON_SWHC_HPP__
#define __COMMON_SWHC_HPP__
#include "ParticleCommon.hpp"
#include "PAK.hpp"
#include "athena/FileWriter.hpp"
namespace DataSpec
{
namespace DNAParticle
{
template <class IDType>
struct SWSH : public BigYAML
{
static const char* DNAType() { return "SWSH"; }
const char* DNATypeV() const { return DNAType(); }
IntElementFactory x0_PSLT;
RealElementFactory x4_TIME;
RealElementFactory x8_LRAD;
RealElementFactory xc_RRAD;
IntElementFactory x10_LENG;
ColorElementFactory x14_COLR;
IntElementFactory x18_SIDE;
RealElementFactory x1c_IROT;
RealElementFactory x20_ROTM;
VectorElementFactory x24_POFS;
VectorElementFactory x28_IVEL;
VectorElementFactory x2c_NPOS;
ModVectorElementFactory x30_VELM;
ModVectorElementFactory x34_VLM2;
IntElementFactory x38_SPLN;
UVElementFactory<IDType> x3c_TEXR;
IntElementFactory x40_TSPN;
union
{
struct
{
bool x44_24_LLRD : 1; bool x44_25_CROS : 1; bool x44_26_VLS1 : 1; bool x44_27_VLS2 : 1;
bool x44_28_SROT : 1; bool x44_29_WIRE : 1; bool x44_30_TEXW : 1; bool x44_31_AALP : 1;
bool x45_24_ZBUF : 1; bool x45_25_ORNT : 1; bool x45_26_CRND : 1;
};
uint16_t dummy = 0;
};
void read(athena::io::YAMLDocReader& r);
void write(athena::io::YAMLDocWriter& w) const;
size_t binarySize(size_t __isz) const;
void read(athena::io::IStreamReader& r);
void write(athena::io::IStreamWriter& w) const;
SWSH()
{
x44_25_CROS = true;
}
};
template <class IDType>
bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteSWSH(const SWSH<IDType>& gpsm, const hecl::ProjectPath& outPath);
}
}
#endif // __COMMON_SWHC_HPP__

View File

@ -8,6 +8,8 @@
#include "../DNACommon/TXTR.hpp"
#include "../DNACommon/PART.hpp"
#include "../DNACommon/ELSC.hpp"
#include "../DNACommon/SWHC.hpp"
#include "../DNACommon/CRSC.hpp"
#include "../DNACommon/FONT.hpp"
#include "CMDL.hpp"
#include "AFSM.hpp"
@ -292,6 +294,10 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK::Entry& entry)
return {DNAParticle::ExtractGPSM<UniqueID32>, nullptr, {_S(".gpsm.yaml")}};
case SBIG('ELSC'):
return {DNAParticle::ExtractELSM<UniqueID32>, nullptr, {_S(".elsm.yaml")}};
case SBIG('SWHC'):
return {DNAParticle::ExtractSWSH<UniqueID32>, nullptr, {_S(".swsh.yaml")}};
case SBIG('CRSC'):
return {DNAParticle::ExtractCRSM<UniqueID32>, nullptr, {_S(".crsm.yaml")}};
case SBIG('FONT'):
return {DNAFont::ExtractFONT<UniqueID32>, nullptr, {_S(".yaml")}};
}

View File

@ -1,5 +1,6 @@
#include "CGameState.hpp"
#include "IOStreams.hpp"
#include "zeus/Math.hpp"
namespace urde
{
@ -12,4 +13,9 @@ void CGameState::SetCurrentWorldId(unsigned int id, const std::string& name)
{
}
void CGameState::SetTotalPlayTime(float time)
{
xa0_playTime = zeus::clamp<double>(0.0, time, 359999.0);
}
}

View File

@ -17,11 +17,13 @@ class CGameState
CWorldTransManager m_transManager;
float m_gameTime = 0.0;
CGameOptions m_gameOpts;
double xa0_playTime;
public:
CGameState() {}
CGameState(CBitStreamReader& stream);
void SetCurrentWorldId(unsigned int id, const std::string& name);
CWorldTransManager& WorldTransitionManager() {return m_transManager;}
void SetTotalPlayTime(float time);
};
}

View File

@ -4,12 +4,6 @@
namespace urde
{
/* TODO: Implement this properly */
/* NOTE: This is only to be used as a reference,
* and is not indicative of how the actual format is structured
* a proper RE is still required!
*/
const u32 CPlayerState::PowerUpMaxValues[41] =
{ 1, 1, 1, 1, 250, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 14, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
@ -60,126 +54,81 @@ const char* PowerUpNames[41]=
"Artifact of Newborn",
};
CPlayerState::CPlayerState(CBitStreamReader& in)
: x188_staticIntf(5)
CPlayerState::CPlayerState(CBitStreamReader& stream)
: CPlayerState()
{
x0_24_ = true;
u32 bitCount = 0;
std::for_each(std::cbegin(CPlayerState::PowerUpMaxValues), std::cend(CPlayerState::PowerUpMaxValues), [&bitCount](const u32& max){
bitCount += CBitStreamReader::GetBitCount(max);
});
#if 1
in.readUint32Big();
in.readBool();
in.readBool();
in.readBool();
atInt8 data[0xAE];
in.readBytesToBuf(data, 0xAE);
for (u32 k = 0; k < 3; k++)
x4_ = stream.ReadEncoded(0x20);
u32 tmp = stream.ReadEncoded(0x20);
xc_currentHealth = *reinterpret_cast<float*>(&tmp);
x8_currentBeam = EBeamId(stream.ReadEncoded(CBitStreamReader::GetBitCount(5)));
x20_currentSuit = EPlayerSuit(stream.ReadEncoded(CBitStreamReader::GetBitCount(4)));
x24_powerups.resize(41);
for (u32 i = 0; i < x24_powerups.size(); ++i)
{
atInt8 save[0x3AC];
in.readBytesToBuf(save, 0x3AC);
{
CBitStreamReader stream(save, 0x1000);
std::string filename = athena::utility::sprintf("Game%i.dat", k + 1);
std::string logFilename = athena::utility::sprintf("Game%i.txt", k + 1);
FILE * f = fopen(logFilename.c_str(), "w");
CBitStreamWriter w{filename};
if (PowerUpMaxValues[i] == 0)
continue;
fprintf(f, "Game State\n");
for (u32 i = 0; i < 0x80; i++)
{
u32 tmp = stream.ReadEncoded(8);
if (!(i % 16))
fprintf(f, "\n");
fprintf(f, "%.2i ", tmp);
w.WriteEncoded(tmp, 8);
}
fprintf(f, "\n\n");
s32 tmp = stream.ReadEncoded(32);
w.WriteEncoded(tmp, 0x20);
fprintf(f, "%i\n", tmp);
tmp = stream.ReadEncoded(1);
w.WriteEncoded(tmp, 1);
fprintf(f, "%i\n", tmp);
tmp = stream.ReadEncoded(1);
w.WriteEncoded(tmp, 1);
fprintf(f, "%i\n", tmp);
tmp = stream.ReadEncoded(32);
w.WriteEncoded(tmp, 0x20);
fprintf(f, "%f\n", *reinterpret_cast<float*>(&tmp));
tmp = stream.ReadEncoded(32);
w.WriteEncoded(tmp, 0x20);
fprintf(f, "%f\n", *reinterpret_cast<float*>(&tmp));
tmp = stream.ReadEncoded(32);
fprintf(f, "%x\n", tmp);
w.WriteEncoded(tmp, 0x20);
fprintf(f, "PlayerState\n");
x4_ = stream.ReadEncoded(0x20);
w.WriteEncoded(x4_, 0x20);
fprintf(f, "%x\n", x4_);
tmp = stream.ReadEncoded(0x20);
fprintf(f, "Base health %f\n", *reinterpret_cast<float*>(&tmp));
xc_currentHealth = *reinterpret_cast<float*>(&tmp);
w.WriteEncoded(tmp, 0x20);
x8_currentBeam = stream.ReadEncoded(CBitStreamReader::GetBitCount(5));
fprintf(f, "%i\n", x8_currentBeam);
w.WriteEncoded(x8_currentBeam, CBitStreamReader::GetBitCount(5));
x20_currentSuit = EPlayerSuit(stream.ReadEncoded(CBitStreamReader::GetBitCount(4)));
fprintf(f, "%i\n", x20_currentSuit);
w.WriteEncoded(u32(x20_currentSuit), CBitStreamReader::GetBitCount(4));
x24_powerups.resize(41);
fprintf(f, "Powerups\n");
for (u32 i = 0; i < x24_powerups.size(); ++i)
{
if (PowerUpMaxValues[i] == 0)
continue;
u32 a = stream.ReadEncoded(CBitStreamReader::GetBitCount(PowerUpMaxValues[i]));
u32 b = stream.ReadEncoded(CBitStreamReader::GetBitCount(PowerUpMaxValues[i]));
w.WriteEncoded(a, CBitStreamReader::GetBitCount(PowerUpMaxValues[i]));
w.WriteEncoded(b, CBitStreamReader::GetBitCount(PowerUpMaxValues[i]));
x24_powerups[i] = CPowerUp(a, b);
fprintf(f, "%2i(%21s): cur=%3i max=%3i\n", i, PowerUpNames[i], a, b);
}
for (u32 i = 0; i < 832; i++)
{
u32 tmp = stream.ReadEncoded(1);
if (!(i % 32))
fprintf(f, "\n");
fprintf(f, "%i ", tmp);
w.WriteEncoded(tmp, 1);
}
fprintf(f, "\n\n");
tmp = stream.ReadEncoded(CBitStreamReader::GetBitCount(0x100));
w.WriteEncoded(tmp, CBitStreamReader::GetBitCount(0x100));
fprintf(f, "%i\n", tmp);
tmp = stream.ReadEncoded(CBitStreamReader::GetBitCount(0x100));
w.WriteEncoded(tmp, CBitStreamReader::GetBitCount(0x100));
fprintf(f, "%i\n", tmp);
fprintf(f, "Final Offset %.8llx\n", stream.position());
fprintf(f, "Completion: %.2i%%\n", CalculateItemCollectionRate());
w.save();
}
u32 a = stream.ReadEncoded(CBitStreamReader::GetBitCount(PowerUpMaxValues[i]));
u32 b = stream.ReadEncoded(CBitStreamReader::GetBitCount(PowerUpMaxValues[i]));
x24_powerups[i] = CPowerUp(a, b);
}
#endif
x170_scanTimes.resize(846);
for (u32 i = 0; i < x170_scanTimes.size(); i++)
{
x170_scanTimes[i].first = stream.ReadEncoded(1);
if (x170_scanTimes[i].first)
x170_scanTimes[i].second = 1.f;
else
x170_scanTimes[i].second = 0.f;
}
x180_ = stream.ReadEncoded(CBitStreamReader::GetBitCount(0x100));
x184_ = stream.ReadEncoded(CBitStreamReader::GetBitCount(0x100));
}
float CPlayerState::GetBeamSwitchTime() const
void CPlayerState::PutTo(CBitStreamWriter &stream)
{
static const float switchTimes[4] {
0.2, 0.1, 0.2, 0.2
stream.WriteEncoded(x4_, 32);
u32 tmp = *reinterpret_cast<int*>(&xc_currentHealth);
stream.WriteEncoded(tmp, 32);
stream.WriteEncoded((u32)x8_currentBeam, CBitStreamWriter::GetBitCount(5));
stream.WriteEncoded((u32)x20_currentSuit, CBitStreamWriter::GetBitCount(4));
for (u32 i = 0; i < x24_powerups.size(); ++i)
{
const CPowerUp& pup = x24_powerups[i];
stream.WriteEncoded(pup.x0_amount, CBitStreamWriter::GetBitCount(PowerUpMaxValues[i]));
stream.WriteEncoded(pup.x4_capacity, CBitStreamWriter::GetBitCount(PowerUpMaxValues[i]));
}
for (const auto& scanTime : x170_scanTimes)
{
if (scanTime.second >= 1.f)
stream.WriteEncoded(true, 1);
else
stream.WriteEncoded(false, 1);
}
stream.WriteEncoded(x180_, CBitStreamWriter::GetBitCount(0x100));
stream.WriteEncoded(x184_, CBitStreamWriter::GetBitCount(0x100));
}
float CPlayerState::sub_80091204() const
{
static const float unk[] {
0.2f, 0.1f, 0.2f, 0.2f, 1.f
};
return switchTimes[u32(x8_currentBeam)];
return unk[u32(x8_currentBeam)];
}
u32 CPlayerState::GetMissileCostForAltAttack() const
{
static const u32 costs[] {
5, 10, 10, 10, 1
};
return costs[u32(x8_currentBeam)];
}
u32 CPlayerState::CalculateItemCollectionRate() const
@ -244,7 +193,7 @@ CPlayerState::EPlayerVisor CPlayerState::GetActiveVisor(const CStateManager& sta
#if 0
CFirstPersionCamera* cam = dynamic_cast<CFirstPersonCamera*>(stateMgr.GetCameraManager()->GetCurrentCamera(stateMgr));
if (!cam)
return EVisorType::Zero;
return EVisorType::Combat;
#endif
return x14_currentVisor;
}
@ -254,8 +203,9 @@ void CPlayerState::UpdateStaticInterference(CStateManager& stateMgr, const float
x188_staticIntf.Update(stateMgr, dt);
}
void CPlayerState::NewScanTime(u32 time)
void CPlayerState::IncreaseScanTime(u32 time, float val)
{
}
bool CPlayerState::GetIsVisorTransitioning() const

View File

@ -84,6 +84,15 @@ public:
FusionPhazon
};
enum class EBeamId : u32
{
Power,
Ice,
Plasma,
Wave,
Phazon
};
private:
static const u32 PowerUpMaxValues[41];
@ -101,7 +110,7 @@ private:
};
u32 x4_ = 0;
u32 x8_currentBeam = 0;
EBeamId x8_currentBeam = EBeamId::Power;
float xc_currentHealth = 99.f;
float x10_ = 50.f;
EPlayerVisor x14_currentVisor = EPlayerVisor::Combat;
@ -109,14 +118,17 @@ private:
float x1c_visorTransitionFactor = 0.2f;
EPlayerSuit x20_currentSuit = EPlayerSuit::Power;
rstl::reserved_vector<CPowerUp, 41> x24_powerups;
rstl::reserved_vector<std::pair<u32, float>, 846> x170_scanTimes;
u32 x180_ = 0;
u32 x184_ = 0;
CStaticInterference x188_staticIntf;
public:
float GetBeamSwitchTime() const;
float sub_80091204() const;
u32 GetMissileCostForAltAttack() const;
u32 CalculateItemCollectionRate() const;
u32 GetBaseHealthCapacityInt32() { return 99; }
u32 GetPickupTotal() { return 99; }
void SetFusion(bool val) { x0_26_fusion = val; }
bool GetFusion() const { return x0_26_fusion; }
EPlayerSuit GetCurrentSuit() const;
@ -124,7 +136,8 @@ public:
EPlayerVisor GetActiveVisor(const CStateManager& stateMgr) const;
void UpdateStaticInterference(CStateManager& stateMgr, const float& dt);
void IncreaseScanTime(u32 time, float val);
void NewScanTime(u32 time);
void SetScanTime(u32 time, float val);
float GetScanTime(u32 time, float val);
bool GetIsVisorTransitioning() const;
float GetVisorTransitionFactor() const;
void UpdateVisorTransition(float dt);
@ -146,6 +159,7 @@ public:
void InitializePowerUp(EItemType type, u32 capacity);
CPlayerState() : x188_staticIntf(5) { x0_24_ = true; }
CPlayerState(CBitStreamReader& stream);
void PutTo(CBitStreamWriter& stream);
};
}

View File

@ -79,9 +79,7 @@ void CCollisionResponseData::AddParticleSystemToResponse(EWeaponCollisionRespons
int i = int(type);
std::vector<TResId> tracker;
tracker.resize(8);
x0[i].first = std::move(CPF::GetChildGeneratorDesc(in, resPool, tracker).m_token);
if (x0[i].first)
x0[i].second = true;
x0_generators[i].emplace(std::move(CPF::GetChildGeneratorDesc(in, resPool, tracker).m_token));
}
bool CCollisionResponseData::CheckAndAddDecalToResponse(FourCC clsId, CInputStream& in, CSimplePool* resPool)
@ -99,10 +97,7 @@ bool CCollisionResponseData::CheckAndAddDecalToResponse(FourCC clsId, CInputStre
if (!id)
return true;
x20[i].first = std::move(resPool->GetObj({FOURCC('DPSC'), id}));
if (x0[i].first)
x0[i].second = true;
x20_decals[i].emplace(std::move(resPool->GetObj({FOURCC('DPSC'), id})));
return true;
}
i++;
@ -121,7 +116,7 @@ bool CCollisionResponseData::CheckAndAddSoundFXToResponse(FourCC clsId, CInputSt
if (cls == SBIG('NONE'))
return true;
x10[i] = CPF::GetInt(in);
x10_sfx[i] = CPF::GetInt(in);
return true;
}
i++;
@ -140,6 +135,7 @@ bool CCollisionResponseData::CheckAndAddParticleSystemToResponse(FourCC clsId, C
AddParticleSystemToResponse(EWeaponCollisionResponseTypes(i), in, resPool);
return true;
}
i++;
}
return false;
}
@ -159,9 +155,12 @@ bool CCollisionResponseData::CheckAndAddResourceToResponse(FourCC clsId, CInputS
CCollisionResponseData::CCollisionResponseData(CInputStream& in, CSimplePool* resPool)
: x30_RNGE(50.f), x34_FOFF(0.2f)
{
x0.resize(94);
x10.resize(94);
x20.resize(94);
x0_generators.resize(94);
x10_sfx.resize(94);
x20_decals.resize(94);
for (TResId& id : x10_sfx)
id = ~0;
FourCC clsId = CPF::GetClassID(in);
if (clsId == SBIG('CRSM'))
{

View File

@ -5,6 +5,7 @@
#include "IObj.hpp"
#include "CToken.hpp"
#include "IOStreams.hpp"
#include "optional.hpp"
namespace urde
{
@ -38,9 +39,9 @@ enum class EWeaponCollisionResponseTypes
class CCollisionResponseData
{
std::vector<std::pair<TLockedToken<CGenDescription>, bool>> x0;
std::vector<s32> x10;
std::vector<std::pair<TLockedToken<CDecalDescription>, bool>> x20;
std::vector<std::experimental::optional<TLockedToken<CGenDescription>>> x0_generators;
std::vector<TResId> x10_sfx;
std::vector<std::experimental::optional<TLockedToken<CDecalDescription>>> x20_decals;
float x30_RNGE;
float x34_FOFF;

View File

@ -41,6 +41,11 @@ public:
};
u16 dummy = 0;
};
CSwooshDescription()
{
x44_25_CROS = true;
}
};
}