diff --git a/DataSpec/DNACommon/CRSC.cpp b/DataSpec/DNACommon/CRSC.cpp index e5e8c7878..45069cd35 100644 --- a/DataSpec/DNACommon/CRSC.cpp +++ b/DataSpec/DNACommon/CRSC.cpp @@ -1,248 +1,24 @@ #include "DataSpec/DNACommon/CRSC.hpp" - -#include - #include "DataSpec/DNACommon/PAK.hpp" -#include - namespace DataSpec::DNAParticle { -static const std::vector GeneratorTypes = { - SBIG('NODP'), 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 SFXTypes = { - SBIG('DSFX'), SBIG('CSFX'), SBIG('MSFX'), SBIG('GRFX'), SBIG('NSFX'), 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'), -}; +template struct PPImpl<_CRSM>; +template struct PPImpl<_CRSM>; -static const std::vector 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')}; +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_CRSM>) +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_CRSM>) template <> -std::string_view CRSM::DNAType() { - return "CRSM"sv; +std::string_view PPImpl<_CRSM>::DNAType() { + return "urde::CRSM"sv; } template <> -std::string_view CRSM::DNAType() { - return "CRSM"sv; +std::string_view PPImpl<_CRSM>::DNAType() { + return "urde::CRSM"sv; } -template -void CRSM::_read(athena::io::YAMLDocReader& r) { - for (const auto& elem : r.getCurNode()->m_mapChildren) { - if (elem.first.size() < 4) { - LogModule.report(logvisor::Warning, fmt("short FourCC in element '{}'"), elem.first); - continue; - } - - if (auto rec = 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) { 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) { return clsId == other; }); - if (sfx != SFXTypes.end()) { - x10_sfx[clsId] = r.readInt32(clsId.toString()); - continue; - } - - auto decal = std::find_if(DecalTypes.begin(), DecalTypes.end(), - [&clsId](const FourCC& other) { return clsId == other; }); - if (decal != DecalTypes.end()) { - x20_decals[clsId].read(r); - continue; - } - if (clsId == SBIG('RNGE')) - x30_RNGE = r.readFloat(); - else if (clsId == SBIG('FOFF')) - x34_FOFF = r.readFloat(); - } - } -} - -template -void CRSM::_write(athena::io::YAMLDocWriter& w) const { - for (const auto& pair : x0_generators) - if (pair.second) - if (auto rec = w.enterSubRecord(pair.first.toString())) - pair.second.write(w); - - for (const auto& pair : x10_sfx) - if (pair.second != UINT32_MAX) - w.writeUint32(pair.first.toString(), pair.second); - - for (const auto& pair : x20_decals) - if (pair.second) - if (auto rec = w.enterSubRecord(pair.first.toString())) - pair.second.write(w); - - if (x30_RNGE != 50.f) - w.writeFloat("RNGE", x30_RNGE); - if (x34_FOFF != 0.2f) - w.writeFloat("FOFF", x34_FOFF); -} - -template -void CRSM::_binarySize(size_t& __isz) const { - __isz += 4; - for (const auto& pair : x0_generators) { - if (pair.second) { - __isz += 4; - pair.second.binarySize(__isz); - } - } - for (const auto& pair : x10_sfx) { - if (pair.second != UINT32_MAX) - __isz += 12; - } - - for (const auto& pair : x20_decals) { - if (pair.second) { - __isz += 4; - pair.second.binarySize(__isz); - } - } - - if (x30_RNGE != 50.f) - __isz += 12; - if (x34_FOFF != 0.2f) - __isz += 12; -} - -template -void CRSM::_read(athena::io::IStreamReader& r) { - DNAFourCC clsId; - clsId.read(r); - if (clsId != SBIG('CRSM')) { - LogModule.report(logvisor::Warning, fmt("non CRSM provided to CRSM parser")); - return; - } - - while (clsId != SBIG('_END')) { - clsId.read(r); - auto gen = std::find_if(GeneratorTypes.begin(), GeneratorTypes.end(), - [&clsId](const FourCC& other) { 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) { return clsId == other; }); - if (sfx != SFXTypes.end()) { - DNAFourCC fcc; - fcc.read(r); - 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) { 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, fmt("Unknown CRSM class {} @{}"), clsId, r.position()); - } -} - -template -void CRSM::_write(athena::io::IStreamWriter& w) const { - w.writeBytes("CRSM", 4); - for (const auto& pair : x0_generators) { - w.writeBytes(pair.first.getChars(), 4); - pair.second.write(w); - } - - for (const auto& pair : x10_sfx) { - w.writeBytes(pair.first.getChars(), 4); - if (pair.second != UINT32_MAX) { - w.writeBytes("CNST", 4); - w.writeUint32Big(pair.second); - } else { - w.writeBytes("NONE", 4); - } - } - - for (const auto& pair : x20_decals) { - w.writeBytes(pair.first.getChars(), 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); -} - -AT_SUBSPECIALIZE_DNA_YAML(CRSM) -AT_SUBSPECIALIZE_DNA_YAML(CRSM) - -template -void CRSM::gatherDependencies(std::vector& pathsOut) const { - for (const auto& p : x0_generators) - g_curSpec->flattenDependencies(p.second.id, pathsOut); - for (const auto& p : x20_decals) - g_curSpec->flattenDependencies(p.second.id, pathsOut); -} - -template -CRSM::CRSM() : x30_RNGE(50.f), x34_FOFF(0.2f) { - for (const auto& sfx : SFXTypes) - x10_sfx[sfx] = ~0; -} - -template struct CRSM; -template struct CRSM; - template bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { athena::io::FileWriter writer(outPath.getAbsolutePath()); diff --git a/DataSpec/DNACommon/CRSC.def b/DataSpec/DNACommon/CRSC.def new file mode 100644 index 000000000..6fe2e2b7e --- /dev/null +++ b/DataSpec/DNACommon/CRSC.def @@ -0,0 +1,222 @@ +#ifndef ENTRY +#define ENTRY(name, identifier) +#endif + +#ifndef RES_ENTRY +#define RES_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef U32_ENTRY +#define U32_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef FLOAT_ENTRY +#define FLOAT_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +RES_ENTRY('NODP', NODP) +RES_ENTRY('DEFS', DEFS) +RES_ENTRY('CRTS', CRTS) +RES_ENTRY('MTLS', MTLS) +RES_ENTRY('GRAS', GRAS) +RES_ENTRY('ICEE', ICEE) +RES_ENTRY('GOOO', GOOO) +RES_ENTRY('WODS', WODS) +RES_ENTRY('WATR', WATR) +RES_ENTRY('1MUD', _1MUD) +RES_ENTRY('1LAV', _1LAV) +RES_ENTRY('1SAN', _1SAN) +RES_ENTRY('1PRJ', _1PRJ) +RES_ENTRY('DCHR', DCHR) +RES_ENTRY('DCHS', DCHS) +RES_ENTRY('DCSH', DCSH) +RES_ENTRY('DENM', DENM) +RES_ENTRY('DESP', DESP) +RES_ENTRY('DESH', DESH) +RES_ENTRY('BTLE', BTLE) +RES_ENTRY('WASP', WASP) +RES_ENTRY('TALP', TALP) +RES_ENTRY('PTGM', PTGM) +RES_ENTRY('SPIR', SPIR) +RES_ENTRY('FPIR', FPIR) +RES_ENTRY('FFLE', FFLE) +RES_ENTRY('PARA', PARA) +RES_ENTRY('BMON', BMON) +RES_ENTRY('BFLR', BFLR) +RES_ENTRY('PBOS', PBOS) +RES_ENTRY('IBOS', IBOS) +RES_ENTRY('1SVA', _1SVA) +RES_ENTRY('1RPR', _1RPR) +RES_ENTRY('1MTR', _1MTR) +RES_ENTRY('1PDS', _1PDS) +RES_ENTRY('1FLB', _1FLB) +RES_ENTRY('1DRN', _1DRN) +RES_ENTRY('1MRE', _1MRE) +RES_ENTRY('CHOZ', CHOZ) +RES_ENTRY('JZAP', JZAP) +RES_ENTRY('1ISE', _1ISE) +RES_ENTRY('1BSE', _1BSE) +RES_ENTRY('1ATB', _1ATB) +RES_ENTRY('1ATA', _1ATA) +RES_ENTRY('BTSP', BTSP) +RES_ENTRY('WWSP', WWSP) +RES_ENTRY('TASP', TASP) +RES_ENTRY('TGSP', TGSP) +RES_ENTRY('SPSP', SPSP) +RES_ENTRY('FPSP', FPSP) +RES_ENTRY('FFSP', FFSP) +RES_ENTRY('PSSP', PSSP) +RES_ENTRY('BMSP', BMSP) +RES_ENTRY('BFSP', BFSP) +RES_ENTRY('PBSP', PBSP) +RES_ENTRY('IBSP', IBSP) +RES_ENTRY('2SVA', _2SVA) +RES_ENTRY('2RPR', _2RPR) +RES_ENTRY('2MTR', _2MTR) +RES_ENTRY('2PDS', _2PDS) +RES_ENTRY('2FLB', _2FLB) +RES_ENTRY('2DRN', _2DRN) +RES_ENTRY('2MRE', _2MRE) +RES_ENTRY('CHSP', CHSP) +RES_ENTRY('JZSP', JZSP) +RES_ENTRY('3ISE', _3ISE) +RES_ENTRY('3BSE', _3BSE) +RES_ENTRY('3ATB', _3ATB) +RES_ENTRY('3ATA', _3ATA) +RES_ENTRY('BTSH', BTSH) +RES_ENTRY('WWSH', WWSH) +RES_ENTRY('TASH', TASH) +RES_ENTRY('TGSH', TGSH) +RES_ENTRY('SPSH', SPSH) +RES_ENTRY('FPSH', FPSH) +RES_ENTRY('FFSH', FFSH) +RES_ENTRY('PSSH', PSSH) +RES_ENTRY('BMSH', BMSH) +RES_ENTRY('BFSH', BFSH) +RES_ENTRY('PBSH', PBSH) +RES_ENTRY('IBSH', IBSH) +RES_ENTRY('3SVA', _3SVA) +RES_ENTRY('3RPR', _3RPR) +RES_ENTRY('3MTR', _3MTR) +RES_ENTRY('3PDS', _3PDS) +RES_ENTRY('3FLB', _3FLB) +RES_ENTRY('3DRN', _3DRN) +RES_ENTRY('3MRE', _3MRE) +RES_ENTRY('CHSH', CHSH) +RES_ENTRY('JZSH', JZSH) +RES_ENTRY('5ISE', _5ISE) +RES_ENTRY('5BSE', _5BSE) +RES_ENTRY('5ATB', _5ATB) +RES_ENTRY('5ATA', _5ATA) +RES_ENTRY('NCDL', NCDL) +RES_ENTRY('DDCL', DDCL) +RES_ENTRY('CODL', CODL) +RES_ENTRY('MEDL', MEDL) +RES_ENTRY('GRDL', GRDL) +RES_ENTRY('ICDL', ICDL) +RES_ENTRY('GODL', GODL) +RES_ENTRY('WODL', WODL) +RES_ENTRY('WTDL', WTDL) +RES_ENTRY('3MUD', _3MUD) +RES_ENTRY('3LAV', _3LAV) +RES_ENTRY('3SAN', _3SAN) +RES_ENTRY('CHDL', CHDL) +RES_ENTRY('ENDL', ENDL) + +U32_ENTRY('NSFX', NSFX) +U32_ENTRY('DSFX', DSFX) +U32_ENTRY('CSFX', CSFX) +U32_ENTRY('MSFX', MSFX) +U32_ENTRY('GRFX', GRFX) +U32_ENTRY('ICFX', ICFX) +U32_ENTRY('GOFX', GOFX) +U32_ENTRY('WSFX', WSFX) +U32_ENTRY('WTFX', WTFX) +U32_ENTRY('2MUD', _2MUD) +U32_ENTRY('2LAV', _2LAV) +U32_ENTRY('2SAN', _2SAN) +U32_ENTRY('2PRJ', _2PRJ) +U32_ENTRY('DCFX', DCFX) +U32_ENTRY('DSHX', DSHX) +U32_ENTRY('DEFX', DEFX) +U32_ENTRY('ESFX', ESFX) +U32_ENTRY('SHFX', SHFX) +U32_ENTRY('BEFX', BEFX) +U32_ENTRY('WWFX', WWFX) +U32_ENTRY('TAFX', TAFX) +U32_ENTRY('GTFX', GTFX) +U32_ENTRY('SPFX', SPFX) +U32_ENTRY('FPFX', FPFX) +U32_ENTRY('FFFX', FFFX) +U32_ENTRY('PAFX', PAFX) +U32_ENTRY('BMFX', BMFX) +U32_ENTRY('BFFX', BFFX) +U32_ENTRY('PBFX', PBFX) +U32_ENTRY('IBFX', IBFX) +U32_ENTRY('4SVA', _4SVA) +U32_ENTRY('4RPR', _4RPR) +U32_ENTRY('4MTR', _4MTR) +U32_ENTRY('4PDS', _4PDS) +U32_ENTRY('4FLB', _4FLB) +U32_ENTRY('4DRN', _4DRN) +U32_ENTRY('4MRE', _4MRE) +U32_ENTRY('CZFX', CZFX) +U32_ENTRY('JZAS', JZAS) +U32_ENTRY('2ISE', _2ISE) +U32_ENTRY('2BSE', _2BSE) +U32_ENTRY('2ATB', _2ATB) +U32_ENTRY('2ATA', _2ATA) +U32_ENTRY('BSFX', BSFX) +U32_ENTRY('TSFX', TSFX) +U32_ENTRY('GSFX', GSFX) +U32_ENTRY('SSFX', SSFX) +U32_ENTRY('FSFX', FSFX) +U32_ENTRY('SFFX', SFFX) +U32_ENTRY('PSFX', PSFX) +U32_ENTRY('SBFX', SBFX) +U32_ENTRY('PBSX', PBSX) +U32_ENTRY('IBSX', IBSX) +U32_ENTRY('5SVA', _5SVA) +U32_ENTRY('5RPR', _5RPR) +U32_ENTRY('5MTR', _5MTR) +U32_ENTRY('5PDS', _5PDS) +U32_ENTRY('5FLB', _5FLB) +U32_ENTRY('5DRN', _5DRN) +U32_ENTRY('5MRE', _5MRE) +U32_ENTRY('JZPS', JZPS) +U32_ENTRY('4ISE', _4ISE) +U32_ENTRY('4BSE', _4BSE) +U32_ENTRY('4ATB', _4ATB) +U32_ENTRY('4ATA', _4ATA) +U32_ENTRY('BHFX', BHFX) +U32_ENTRY('WHFX', WHFX) +U32_ENTRY('THFX', THFX) +U32_ENTRY('GHFX', GHFX) +U32_ENTRY('FHFX', FHFX) +U32_ENTRY('HFFX', HFFX) +U32_ENTRY('PHFX', PHFX) +U32_ENTRY('MHFX', MHFX) +U32_ENTRY('HBFX', HBFX) +U32_ENTRY('PBHX', PBHX) +U32_ENTRY('IBHX', IBHX) +U32_ENTRY('6SVA', _6SVA) +U32_ENTRY('6RPR', _6RPR) +U32_ENTRY('6MTR', _6MTR) +U32_ENTRY('6PDS', _6PDS) +U32_ENTRY('6FLB', _6FLB) +U32_ENTRY('6DRN', _6DRN) +U32_ENTRY('6MRE', _6MRE) +U32_ENTRY('CHFX', CHFX) +U32_ENTRY('JZHS', JZHS) +U32_ENTRY('6ISE', _6ISE) +U32_ENTRY('6BSE', _6BSE) +U32_ENTRY('6ATB', _6ATB) +U32_ENTRY('6ATA', _6ATA) + +FLOAT_ENTRY('RNGE', x30_RNGE) +FLOAT_ENTRY('FOFF', x34_FOFF) + +#undef ENTRY +#undef RES_ENTRY +#undef U32_ENTRY +#undef FLOAT_ENTRY diff --git a/DataSpec/DNACommon/CRSC.hpp b/DataSpec/DNACommon/CRSC.hpp index 3bc7ff2f1..bab40f942 100644 --- a/DataSpec/DNACommon/CRSC.hpp +++ b/DataSpec/DNACommon/CRSC.hpp @@ -18,20 +18,33 @@ class ProjectPath; } namespace DataSpec::DNAParticle { + template -struct CRSM : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA - std::unordered_map> x0_generators; - std::unordered_map x10_sfx; - std::unordered_map> x20_decals; - float x30_RNGE; - float x34_FOFF; +struct _CRSM { + static constexpr ParticleType Type = ParticleType::CRSM; +#define RES_ENTRY(name, identifier) ChildResourceFactory identifier; +#define U32_ENTRY(name, identifier) uint32_t identifier = ~0; +#define FLOAT_ENTRY(name, identifier) float identifier = 0.f; +#include "CRSC.def" - CRSM(); + template + void constexpr Enumerate(_Func f) { +#define ENTRY(name, identifier) f(FOURCC(name), identifier); +#include "CRSC.def" + } - void gatherDependencies(std::vector&) const; + template + bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { +#define ENTRY(name, identifier) case SBIG(name): f(identifier); return true; +#include "CRSC.def" + default: return false; + } + } }; +template +using CRSM = PPImpl<_CRSM>; + template bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); diff --git a/DataSpec/DNACommon/DPSC.cpp b/DataSpec/DNACommon/DPSC.cpp index ed3bc334d..4b88eda08 100644 --- a/DataSpec/DNACommon/DPSC.cpp +++ b/DataSpec/DNACommon/DPSC.cpp @@ -1,391 +1,24 @@ #include "DataSpec/DNACommon/DPSC.hpp" - #include "DataSpec/DNACommon/PAK.hpp" -#include -#include - namespace DataSpec::DNAParticle { +template struct PPImpl<_DPSM>; +template struct PPImpl<_DPSM>; + +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_DPSM>) +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_DPSM>) + template <> -std::string_view DPSM::DNAType() { +std::string_view PPImpl<_DPSM>::DNAType() { return "DPSM"sv; } template <> -std::string_view DPSM::DNAType() { +std::string_view PPImpl<_DPSM>::DNAType() { return "DPSM"sv; } -template -void DPSM::_read(athena::io::YAMLDocReader& r) { - for (const auto& elem : r.getCurNode()->m_mapChildren) { - if (elem.first.size() < 4) { - LogModule.report(logvisor::Warning, fmt("short FourCC in element '{}'"), elem.first); - continue; - } - - if (auto rec = r.enterSubRecord(elem.first.c_str())) { - bool loadFirstDesc = false; - uint32_t clsId = *reinterpret_cast(elem.first.c_str()); - switch (clsId) { - case SBIG('1SZE'): - case SBIG('1LFT'): - case SBIG('1ROT'): - case SBIG('1OFF'): - case SBIG('1CLR'): - case SBIG('1TEX'): - case SBIG('1ADD'): - loadFirstDesc = true; - [[fallthrough]]; - case SBIG('2SZE'): - case SBIG('2LFT'): - case SBIG('2ROT'): - case SBIG('2OFF'): - case SBIG('2CLR'): - case SBIG('2TEX'): - case SBIG('2ADD'): - if (loadFirstDesc) - readQuadDecalInfo(r, clsId, x0_quad); - else - readQuadDecalInfo(r, clsId, x1c_quad); - break; - case SBIG('DMDL'): - x38_DMDL.read(r); - break; - case SBIG('DLFT'): - x48_DLFT.read(r); - break; - case SBIG('DMOP'): - x4c_DMOP.read(r); - break; - case SBIG('DMRT'): - x50_DMRT.read(r); - break; - case SBIG('DMSC'): - x54_DMSC.read(r); - break; - case SBIG('DMCL'): - x58_DMCL.read(r); - break; - case SBIG('DMAB'): - x5c_24_DMAB = r.readBool(); - break; - case SBIG('DMOO'): - x5c_25_DMOO = r.readBool(); - break; - } - } - } -} - -template -void DPSM::_write(athena::io::YAMLDocWriter& w) const { - writeQuadDecalInfo(w, x0_quad, true); - writeQuadDecalInfo(w, x1c_quad, false); - - if (x38_DMDL) - if (auto rec = w.enterSubRecord("DMDL")) - x38_DMDL.write(w); - if (x48_DLFT) - if (auto rec = w.enterSubRecord("DLFT")) - x48_DLFT.write(w); - if (x4c_DMOP) - if (auto rec = w.enterSubRecord("DMOP")) - x4c_DMOP.write(w); - if (x50_DMRT) - if (auto rec = w.enterSubRecord("DMRT")) - x50_DMRT.write(w); - if (x54_DMSC) - if (auto rec = w.enterSubRecord("DMSC")) - x54_DMSC.write(w); - if (x58_DMCL) - if (auto rec = w.enterSubRecord("DMCL")) - x54_DMSC.write(w); - - if (x5c_24_DMAB) - w.writeBool("DMAB", x5c_24_DMAB); - if (x5c_25_DMOO) - w.writeBool("DMOO", x5c_25_DMOO); -} - -template -template -void DPSM::readQuadDecalInfo(Reader& r, FourCC clsId, typename DPSM::SQuadDescr& quad) { - switch (clsId.toUint32()) { - case SBIG('1LFT'): - case SBIG('2LFT'): - quad.x0_LFT.read(r); - break; - case SBIG('1SZE'): - case SBIG('2SZE'): - quad.x4_SZE.read(r); - break; - case SBIG('1ROT'): - case SBIG('2ROT'): - quad.x8_ROT.read(r); - break; - case SBIG('1OFF'): - case SBIG('2OFF'): - quad.xc_OFF.read(r); - break; - case SBIG('1CLR'): - case SBIG('2CLR'): - quad.x10_CLR.read(r); - break; - case SBIG('1TEX'): - case SBIG('2TEX'): - quad.x14_TEX.read(r); - break; - case SBIG('1ADD'): - case SBIG('2ADD'): - quad.x18_ADD.read(r); - break; - } -} - -template -void DPSM::writeQuadDecalInfo(athena::io::YAMLDocWriter& w, const typename DPSM::SQuadDescr& quad, - bool first) const { - if (quad.x0_LFT) - if (auto rec = w.enterSubRecord((first ? "1LFT" : "2LFT"))) - quad.x0_LFT.write(w); - if (quad.x4_SZE) - if (auto rec = w.enterSubRecord((first ? "1SZE" : "2SZE"))) - quad.x4_SZE.write(w); - if (quad.x8_ROT) - if (auto rec = w.enterSubRecord((first ? "1ROT" : "2ROT"))) - quad.x8_ROT.write(w); - if (quad.xc_OFF) - if (auto rec = w.enterSubRecord((first ? "1OFF" : "2OFF"))) - quad.xc_OFF.write(w); - if (quad.x10_CLR) - if (auto rec = w.enterSubRecord((first ? "1CLR" : "2CLR"))) - quad.x10_CLR.write(w); - if (quad.x14_TEX) - if (auto rec = w.enterSubRecord((first ? "1TEX" : "2TEX"))) - quad.x14_TEX.write(w); - if (quad.x18_ADD) - if (auto rec = w.enterSubRecord((first ? "1ADD" : "2ADD"))) - quad.x18_ADD.write(w); -} - -template -void DPSM::_binarySize(size_t& s) const { - s += 4; - getQuadDecalBinarySize(s, x0_quad); - getQuadDecalBinarySize(s, x1c_quad); - if (x38_DMDL) { - s += 4; - x38_DMDL.binarySize(s); - } - if (x48_DLFT) { - s += 4; - x48_DLFT.binarySize(s); - } - if (x4c_DMOP) { - s += 4; - x4c_DMOP.binarySize(s); - } - if (x50_DMRT) { - s += 4; - x50_DMRT.binarySize(s); - } - if (x54_DMSC) { - s += 4; - x54_DMSC.binarySize(s); - } - if (x58_DMCL) { - x58_DMCL.binarySize(s); - } - if (x5c_24_DMAB) - s += 9; - if (x5c_25_DMOO) - s += 9; -} - -template -void DPSM::getQuadDecalBinarySize(size_t& s, const typename DPSM::SQuadDescr& quad) const { - if (quad.x0_LFT) { - s += 4; - quad.x0_LFT.binarySize(s); - } - if (quad.x4_SZE) { - s += 4; - quad.x4_SZE.binarySize(s); - } - if (quad.x8_ROT) { - s += 4; - quad.x8_ROT.binarySize(s); - } - if (quad.xc_OFF) { - s += 4; - quad.xc_OFF.binarySize(s); - } - if (quad.x10_CLR) { - s += 4; - quad.x10_CLR.binarySize(s); - } - if (quad.x14_TEX) { - s += 4; - quad.x14_TEX.binarySize(s); - } - if (quad.x18_ADD) { - s += 4; - quad.x18_ADD.binarySize(s); - } -} - -template -void DPSM::_read(athena::io::IStreamReader& r) { - DNAFourCC clsId; - clsId.read(r); - if (clsId != SBIG('DPSM')) { - LogModule.report(logvisor::Warning, fmt("non DPSM provided to DPSM parser")); - return; - } - bool loadFirstDesc = false; - clsId.read(r); - while (clsId != SBIG('_END')) { - switch (clsId.toUint32()) { - case SBIG('1SZE'): - case SBIG('1LFT'): - case SBIG('1ROT'): - case SBIG('1OFF'): - case SBIG('1CLR'): - case SBIG('1TEX'): - case SBIG('1ADD'): - loadFirstDesc = true; - [[fallthrough]]; - case SBIG('2SZE'): - case SBIG('2LFT'): - case SBIG('2ROT'): - case SBIG('2OFF'): - case SBIG('2CLR'): - case SBIG('2TEX'): - case SBIG('2ADD'): - if (loadFirstDesc) - readQuadDecalInfo(r, clsId, x0_quad); - else - readQuadDecalInfo(r, clsId, x1c_quad); - break; - case SBIG('DMDL'): - x38_DMDL.read(r); - break; - case SBIG('DLFT'): - x48_DLFT.read(r); - break; - case SBIG('DMOP'): - x4c_DMOP.read(r); - break; - case SBIG('DMRT'): - x50_DMRT.read(r); - break; - case SBIG('DMSC'): - x54_DMSC.read(r); - break; - case SBIG('DMCL'): - x58_DMCL.read(r); - break; - case SBIG('DMAB'): - r.readUint32(); - x5c_24_DMAB = r.readBool(); - break; - case SBIG('DMOO'): - r.readUint32(); - x5c_25_DMOO = r.readBool(); - break; - default: - LogModule.report(logvisor::Fatal, fmt("Unknown DPSM class {} @{}"), clsId, r.position()); - break; - } - clsId.read(r); - } -} - -template -void DPSM::_write(athena::io::IStreamWriter& w) const { - w.writeBytes("DPSM", 4); - writeQuadDecalInfo(w, x0_quad, true); - writeQuadDecalInfo(w, x1c_quad, false); - if (x38_DMDL) { - w.writeBytes("DMDL", 4); - x38_DMDL.write(w); - } - if (x48_DLFT) { - w.writeBytes("DLFT", 4); - x48_DLFT.write(w); - } - if (x4c_DMOP) { - w.writeBytes("DMOP", 4); - x4c_DMOP.write(w); - } - if (x50_DMRT) { - w.writeBytes("DMRT", 4); - x50_DMRT.write(w); - } - if (x54_DMSC) { - w.writeBytes("DMSC", 4); - x54_DMSC.write(w); - } - if (x58_DMCL) { - w.writeBytes("DMCL", 4); - x58_DMCL.write(w); - } - if (x5c_24_DMAB) - w.writeBytes("DMABCNST\x01", 9); - if (x5c_25_DMOO) - w.writeBytes("DMOOCNST\x01", 9); - w.writeBytes("_END", 4); -} - -template -void DPSM::writeQuadDecalInfo(athena::io::IStreamWriter& w, const typename DPSM::SQuadDescr& quad, - bool first) const { - if (quad.x0_LFT) { - w.writeBytes((first ? "1LFT" : "2LFT"), 4); - quad.x0_LFT.write(w); - } - if (quad.x4_SZE) { - w.writeBytes((first ? "1SZE" : "2SZE"), 4); - quad.x4_SZE.write(w); - } - if (quad.x8_ROT) { - w.writeBytes((first ? "1ROT" : "2ROT"), 4); - quad.x8_ROT.write(w); - } - if (quad.xc_OFF) { - w.writeBytes((first ? "1OFF" : "2OFF"), 4); - quad.xc_OFF.write(w); - } - if (quad.x10_CLR) { - w.writeBytes((first ? "1CLR" : "2CLR"), 4); - quad.x10_CLR.write(w); - } - if (quad.x14_TEX) { - w.writeBytes((first ? "1TEX" : "2TEX"), 4); - quad.x14_TEX.write(w); - } - if (quad.x18_ADD) { - w.writeBytes((first ? "1ADD" : "2ADD"), 4); - quad.x18_ADD.write(w); - } -} - -template -void DPSM::gatherDependencies(std::vector& pathsOut) const { - if (x0_quad.x14_TEX.m_elem) - x0_quad.x14_TEX.m_elem->gatherDependencies(pathsOut); - if (x1c_quad.x14_TEX.m_elem) - x1c_quad.x14_TEX.m_elem->gatherDependencies(pathsOut); - g_curSpec->flattenDependencies(x38_DMDL.id, pathsOut); -} - -AT_SUBSPECIALIZE_DNA_YAML(DPSM) -AT_SUBSPECIALIZE_DNA_YAML(DPSM) -template struct DPSM; -template struct DPSM; - template bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { athena::io::FileWriter writer(outPath.getAbsolutePath()); diff --git a/DataSpec/DNACommon/DPSC.def b/DataSpec/DNACommon/DPSC.def new file mode 100644 index 000000000..ac61eb49f --- /dev/null +++ b/DataSpec/DNACommon/DPSC.def @@ -0,0 +1,28 @@ +#ifndef ENTRY +#define ENTRY(name, identifier) +#endif + +ENTRY('1LFT', x0_quad.x0_LFT) +ENTRY('1SZE', x0_quad.x4_SZE) +ENTRY('1ROT', x0_quad.x8_ROT) +ENTRY('1OFF', x0_quad.xc_OFF) +ENTRY('1CLR', x0_quad.x10_CLR) +ENTRY('1TEX', x0_quad.x14_TEX) +ENTRY('1ADD', x0_quad.x18_ADD) +ENTRY('2LFT', x1c_quad.x0_LFT) +ENTRY('2SZE', x1c_quad.x4_SZE) +ENTRY('2ROT', x1c_quad.x8_ROT) +ENTRY('2OFF', x1c_quad.xc_OFF) +ENTRY('2CLR', x1c_quad.x10_CLR) +ENTRY('2TEX', x1c_quad.x14_TEX) +ENTRY('2ADD', x1c_quad.x18_ADD) +ENTRY('DMDL', x38_DMDL) +ENTRY('DLFT', x48_DLFT) +ENTRY('DMOP', x4c_DMOP) +ENTRY('DMRT', x50_DMRT) +ENTRY('DMSC', x54_DMSC) +ENTRY('DMCL', x58_DMCL) +ENTRY('DMAB', x5c_24_DMAB) +ENTRY('DMOO', x5c_25_DMOO) + +#undef ENTRY diff --git a/DataSpec/DNACommon/DPSC.hpp b/DataSpec/DNACommon/DPSC.hpp index f8feab5eb..2ef2c547c 100644 --- a/DataSpec/DNACommon/DPSC.hpp +++ b/DataSpec/DNACommon/DPSC.hpp @@ -20,9 +20,8 @@ class ProjectPath; namespace DataSpec::DNAParticle { template -struct DPSM : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA +struct _DPSM { + static constexpr ParticleType Type = ParticleType::DPSM; struct SQuadDescr { IntElementFactory x0_LFT; @@ -31,7 +30,7 @@ struct DPSM : BigDNA { VectorElementFactory xc_OFF; ColorElementFactory x10_CLR; UVElementFactory x14_TEX; - BoolHelper x18_ADD; + bool x18_ADD = false; }; SQuadDescr x0_quad; @@ -42,21 +41,27 @@ struct DPSM : BigDNA { VectorElementFactory x50_DMRT; VectorElementFactory x54_DMSC; ColorElementFactory x58_DMCL; - union { - struct { - bool x5c_24_DMAB : 1; - bool x5c_25_DMOO : 1; - }; - uint8_t dummy; - }; - template - void readQuadDecalInfo(Reader& r, FourCC clsId, SQuadDescr& quad); - void writeQuadDecalInfo(athena::io::YAMLDocWriter& w, const SQuadDescr& quad, bool first) const; - void getQuadDecalBinarySize(size_t& s, const SQuadDescr& desc) const; - void writeQuadDecalInfo(athena::io::IStreamWriter& w, const SQuadDescr& quad, bool first) const; - void gatherDependencies(std::vector&) const; + bool x5c_24_DMAB = false; + bool x5c_25_DMOO = false; + + template + void constexpr Enumerate(_Func f) { +#define ENTRY(name, identifier) f(FOURCC(name), identifier); +#include "DPSC.def" + } + + template + bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { +#define ENTRY(name, identifier) case SBIG(name): f(identifier); return true; +#include "DPSC.def" + default: return false; + } + } }; +template +using DPSM = PPImpl<_DPSM>; template bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); diff --git a/DataSpec/DNACommon/ELSC.cpp b/DataSpec/DNACommon/ELSC.cpp index b0e4703c7..7ea266f71 100644 --- a/DataSpec/DNACommon/ELSC.cpp +++ b/DataSpec/DNACommon/ELSC.cpp @@ -1,403 +1,13 @@ #include "DataSpec/DNACommon/ELSC.hpp" - -#include +#include "DataSpec/DNACommon/PAK.hpp" namespace DataSpec::DNAParticle { -template -void ELSM::_read(athena::io::IStreamReader& r) { - DNAFourCC clsId; - clsId.read(r); - if (clsId != SBIG('ELSM')) { - LogModule.report(logvisor::Warning, fmt("non ELSM provided to ELSM parser")); - return; - } +template struct PPImpl<_ELSM>; +template struct PPImpl<_ELSM>; - clsId.read(r); - while (clsId != SBIG('_END')) { - switch (clsId.toUint32()) { - case SBIG('LIFE'): - x0_LIFE.read(r); - break; - case SBIG('SLIF'): - x4_SLIF.read(r); - break; - case SBIG('GRAT'): - x8_GRAT.read(r); - break; - case SBIG('SCNT'): - xc_SCNT.read(r); - break; - case SBIG('SSEG'): - x10_SSEG.read(r); - break; - case SBIG('COLR'): - x14_COLR.read(r); - break; - case SBIG('IEMT'): - x18_IEMT.read(r); - break; - case SBIG('FEMT'): - x1c_FEMT.read(r); - break; - case SBIG('AMPL'): - x20_AMPL.read(r); - break; - case SBIG('AMPD'): - x24_AMPD.read(r); - break; - case SBIG('LWD1'): - x28_LWD1.read(r); - break; - case SBIG('LWD2'): - x2c_LWD2.read(r); - break; - case SBIG('LWD3'): - x30_LWD3.read(r); - break; - case SBIG('LCL1'): - x34_LCL1.read(r); - break; - case SBIG('LCL2'): - x38_LCL2.read(r); - break; - case SBIG('LCL3'): - x3c_LCL3.read(r); - break; - case SBIG('SSWH'): - x40_SSWH.read(r); - break; - case SBIG('GPSM'): - x50_GPSM.read(r); - break; - case SBIG('EPSM'): - x60_EPSM.read(r); - break; - case SBIG('ZERY'): - x70_ZERY.read(r); - break; - default: - LogModule.report(logvisor::Fatal, fmt("Unknown ELSM class {} @{}"), clsId, r.position()); - break; - } - clsId.read(r); - } -} - -template -void ELSM::_write(athena::io::IStreamWriter& w) const { - w.writeBytes((atInt8*)"ELSM", 4); - if (x0_LIFE) { - w.writeBytes((atInt8*)"LIFE", 4); - x0_LIFE.write(w); - } - if (x4_SLIF) { - w.writeBytes((atInt8*)"SLIF", 4); - x4_SLIF.write(w); - } - if (x8_GRAT) { - w.writeBytes((atInt8*)"GRAT", 4); - x8_GRAT.write(w); - } - if (xc_SCNT) { - w.writeBytes((atInt8*)"SCNT", 4); - xc_SCNT.write(w); - } - if (x10_SSEG) { - w.writeBytes((atInt8*)"SSEG", 4); - x10_SSEG.write(w); - } - if (x14_COLR) { - w.writeBytes((atInt8*)"COLR", 4); - x14_COLR.write(w); - } - if (x18_IEMT) { - w.writeBytes((atInt8*)"IEMT", 4); - x18_IEMT.write(w); - } - if (x1c_FEMT) { - w.writeBytes((atInt8*)"FEMT", 4); - x1c_FEMT.write(w); - } - if (x20_AMPL) { - w.writeBytes((atInt8*)"AMPL", 4); - x20_AMPL.write(w); - } - if (x24_AMPD) { - w.writeBytes((atInt8*)"AMPD", 4); - x24_AMPD.write(w); - } - if (x28_LWD1) { - w.writeBytes((atInt8*)"LWD1", 4); - x28_LWD1.write(w); - } - if (x2c_LWD2) { - w.writeBytes((atInt8*)"LWD2", 4); - x2c_LWD2.write(w); - } - if (x30_LWD3) { - w.writeBytes((atInt8*)"LWD3", 4); - x30_LWD3.write(w); - } - if (x34_LCL1) { - w.writeBytes((atInt8*)"LCL1", 4); - x34_LCL1.write(w); - } - if (x38_LCL2) { - w.writeBytes((atInt8*)"LCL2", 4); - x38_LCL2.write(w); - } - if (x3c_LCL3) { - w.writeBytes((atInt8*)"LCL3", 4); - x3c_LCL3.write(w); - } - if (x40_SSWH) { - w.writeBytes((atInt8*)"SSWH", 4); - x40_SSWH.write(w); - } - if (x50_GPSM) { - w.writeBytes((atInt8*)"GPSM", 4); - x50_GPSM.write(w); - } - if (x60_EPSM) { - w.writeBytes((atInt8*)"EPSM", 4); - x60_EPSM.write(w); - } - if (x70_ZERY) { - w.writeBytes((atInt8*)"ZERY", 4); - x70_ZERY.write(w); - } - w.writeBytes("_END", 4); -} - -template -void ELSM::_binarySize(size_t& s) const { - s += 4; - if (x0_LIFE) { - s += 4; - x0_LIFE.binarySize(s); - } - if (x4_SLIF) { - s += 4; - x4_SLIF.binarySize(s); - } - if (x8_GRAT) { - s += 4; - x8_GRAT.binarySize(s); - } - if (xc_SCNT) { - s += 4; - xc_SCNT.binarySize(s); - } - if (x10_SSEG) { - s += 4; - x10_SSEG.binarySize(s); - } - if (x14_COLR) { - s += 4; - x14_COLR.binarySize(s); - } - if (x18_IEMT) { - s += 4; - x18_IEMT.binarySize(s); - } - if (x1c_FEMT) { - s += 4; - x1c_FEMT.binarySize(s); - } - if (x20_AMPL) { - s += 4; - x20_AMPL.binarySize(s); - } - if (x24_AMPD) { - s += 4; - x24_AMPD.binarySize(s); - } - if (x28_LWD1) { - s += 4; - x28_LWD1.binarySize(s); - } - if (x2c_LWD2) { - s += 4; - x2c_LWD2.binarySize(s); - } - if (x30_LWD3) { - s += 4; - x30_LWD3.binarySize(s); - } - if (x34_LCL1) { - s += 4; - x34_LCL1.binarySize(s); - } - if (x38_LCL2) { - s += 4; - x38_LCL2.binarySize(s); - } - if (x3c_LCL3) { - s += 4; - x3c_LCL3.binarySize(s); - } - if (x40_SSWH) { - s += 4; - x40_SSWH.binarySize(s); - } - if (x50_GPSM) { - s += 4; - x50_GPSM.binarySize(s); - } - if (x60_EPSM) { - s += 4; - x60_EPSM.binarySize(s); - } - if (x70_ZERY) { - s += 4; - x70_ZERY.binarySize(s); - } -} - -template -void ELSM::_read(athena::io::YAMLDocReader& r) { - for (const auto& elem : r.getCurNode()->m_mapChildren) { - if (elem.first.size() < 4) { - LogModule.report(logvisor::Warning, fmt("short FourCC in element '{}'"), elem.first); - continue; - } - - if (auto rec = r.enterSubRecord(elem.first.c_str())) { - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('LIFE'): - x0_LIFE.read(r); - break; - case SBIG('SLIF'): - x4_SLIF.read(r); - break; - case SBIG('GRAT'): - x8_GRAT.read(r); - break; - case SBIG('SCNT'): - xc_SCNT.read(r); - break; - case SBIG('SSEG'): - x10_SSEG.read(r); - break; - case SBIG('COLR'): - x14_COLR.read(r); - break; - case SBIG('IEMT'): - x18_IEMT.read(r); - break; - case SBIG('FEMT'): - x1c_FEMT.read(r); - break; - case SBIG('AMPL'): - x20_AMPL.read(r); - break; - case SBIG('AMPD'): - x24_AMPD.read(r); - break; - case SBIG('LWD1'): - x28_LWD1.read(r); - break; - case SBIG('LWD2'): - x2c_LWD2.read(r); - break; - case SBIG('LWD3'): - x30_LWD3.read(r); - break; - case SBIG('LCL1'): - x34_LCL1.read(r); - break; - case SBIG('LCL2'): - x38_LCL2.read(r); - break; - case SBIG('LCL3'): - x3c_LCL3.read(r); - break; - case SBIG('SSWH'): - x40_SSWH.read(r); - break; - case SBIG('GPSM'): - x50_GPSM.read(r); - break; - case SBIG('EPSM'): - x60_EPSM.read(r); - break; - case SBIG('ZERY'): - x70_ZERY.read(r); - break; - default: - break; - } - } - } -} - -template -void ELSM::_write(athena::io::YAMLDocWriter& w) const { - if (x0_LIFE) - if (auto rec = w.enterSubRecord("LIFE")) - x0_LIFE.write(w); - if (x4_SLIF) - if (auto rec = w.enterSubRecord("SLIF")) - x4_SLIF.write(w); - if (x8_GRAT) - if (auto rec = w.enterSubRecord("GRAT")) - x8_GRAT.write(w); - if (xc_SCNT) - if (auto rec = w.enterSubRecord("SCNT")) - xc_SCNT.write(w); - if (x10_SSEG) - if (auto rec = w.enterSubRecord("SSEG")) - x10_SSEG.write(w); - if (x14_COLR) - if (auto rec = w.enterSubRecord("COLR")) - x14_COLR.write(w); - if (x18_IEMT) - if (auto rec = w.enterSubRecord("IEMT")) - x18_IEMT.write(w); - if (x1c_FEMT) - if (auto rec = w.enterSubRecord("FEMT")) - x1c_FEMT.write(w); - if (x20_AMPL) - if (auto rec = w.enterSubRecord("AMPL")) - x20_AMPL.write(w); - if (x24_AMPD) - if (auto rec = w.enterSubRecord("AMPD")) - x24_AMPD.write(w); - if (x28_LWD1) - if (auto rec = w.enterSubRecord("LWD1")) - x28_LWD1.write(w); - if (x2c_LWD2) - if (auto rec = w.enterSubRecord("LWD2")) - x2c_LWD2.write(w); - if (x30_LWD3) - if (auto rec = w.enterSubRecord("LWD3")) - x30_LWD3.write(w); - if (x34_LCL1) - if (auto rec = w.enterSubRecord("LCL1")) - x34_LCL1.write(w); - if (x38_LCL2) - if (auto rec = w.enterSubRecord("LCL2")) - x38_LCL2.write(w); - if (x3c_LCL3) - if (auto rec = w.enterSubRecord("LCL3")) - x3c_LCL3.write(w); - if (x40_SSWH) - if (auto rec = w.enterSubRecord("SSWH")) - x40_SSWH.write(w); - if (x50_GPSM) - if (auto rec = w.enterSubRecord("GPSM")) - x50_GPSM.write(w); - if (x60_EPSM) - if (auto rec = w.enterSubRecord("EPSM")) - x60_EPSM.write(w); - if (x70_ZERY) - if (auto rec = w.enterSubRecord("ZERY")) - x70_ZERY.write(w); -} - -AT_SUBSPECIALIZE_DNA_YAML(ELSM) -AT_SUBSPECIALIZE_DNA_YAML(ELSM) +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_ELSM>) +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_ELSM>) template <> std::string_view ELSM::DNAType() { @@ -409,16 +19,6 @@ std::string_view ELSM::DNAType() { return "urde::ELSM"sv; } -template -void ELSM::gatherDependencies(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(x40_SSWH.id, pathsOut); - g_curSpec->flattenDependencies(x50_GPSM.id, pathsOut); - g_curSpec->flattenDependencies(x60_EPSM.id, pathsOut); -} - -template struct ELSM; -template struct ELSM; - template bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { athena::io::FileWriter writer(outPath.getAbsolutePath()); diff --git a/DataSpec/DNACommon/ELSC.def b/DataSpec/DNACommon/ELSC.def new file mode 100644 index 000000000..b8498ab1a --- /dev/null +++ b/DataSpec/DNACommon/ELSC.def @@ -0,0 +1,56 @@ +#ifndef ENTRY +#define ENTRY(name, identifier) +#endif + +#ifndef INT_ENTRY +#define INT_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef REAL_ENTRY +#define REAL_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef COLOR_ENTRY +#define COLOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef EMITTER_ENTRY +#define EMITTER_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef RES_ENTRY +#define RES_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef BOOL_ENTRY +#define BOOL_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +INT_ENTRY('LIFE', x0_LIFE) +INT_ENTRY('SLIF', x4_SLIF) +REAL_ENTRY('GRAT', x8_GRAT) +INT_ENTRY('SCNT', xc_SCNT) +INT_ENTRY('SSEG', x10_SSEG) +COLOR_ENTRY('COLR', x14_COLR) +EMITTER_ENTRY('IEMT', x18_IEMT) +EMITTER_ENTRY('FEMT', x1c_FEMT) +REAL_ENTRY('AMPL', x20_AMPL) +REAL_ENTRY('AMPD', x24_AMPD) +REAL_ENTRY('LWD1', x28_LWD1) +REAL_ENTRY('LWD2', x2c_LWD2) +REAL_ENTRY('LWD3', x30_LWD3) +COLOR_ENTRY('LCL1', x34_LCL1) +COLOR_ENTRY('LCL2', x38_LCL2) +COLOR_ENTRY('LCL3', x3c_LCL3) +RES_ENTRY('SSWH', x40_SSWH) +RES_ENTRY('GPSM', x50_GPSM) +RES_ENTRY('EPSM', x60_EPSM) +BOOL_ENTRY('ZERY', x70_ZERY) + +#undef ENTRY +#undef INT_ENTRY +#undef REAL_ENTRY +#undef COLOR_ENTRY +#undef EMITTER_ENTRY +#undef RES_ENTRY +#undef BOOL_ENTRY diff --git a/DataSpec/DNACommon/ELSC.hpp b/DataSpec/DNACommon/ELSC.hpp index 52ff09e35..a6eaaf41d 100644 --- a/DataSpec/DNACommon/ELSC.hpp +++ b/DataSpec/DNACommon/ELSC.hpp @@ -12,33 +12,36 @@ class ProjectPath; } namespace DataSpec::DNAParticle { -template -struct ELSM : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA - IntElementFactory x0_LIFE; - IntElementFactory x4_SLIF; - RealElementFactory x8_GRAT; - IntElementFactory xc_SCNT; - IntElementFactory x10_SSEG; - ColorElementFactory x14_COLR; - EmitterElementFactory x18_IEMT; - EmitterElementFactory x1c_FEMT; - RealElementFactory x20_AMPL; - RealElementFactory x24_AMPD; - RealElementFactory x28_LWD1; - RealElementFactory x2c_LWD2; - RealElementFactory x30_LWD3; - ColorElementFactory x34_LCL1; - ColorElementFactory x38_LCL2; - ColorElementFactory x3c_LCL3; - ChildResourceFactory x40_SSWH; - ChildResourceFactory x50_GPSM; - ChildResourceFactory x60_EPSM; - BoolHelper x70_ZERY; - void gatherDependencies(std::vector&) const; +template +struct _ELSM { + static constexpr ParticleType Type = ParticleType::ELSM; + +#define INT_ENTRY(name, identifier) IntElementFactory identifier; +#define REAL_ENTRY(name, identifier) RealElementFactory identifier; +#define COLOR_ENTRY(name, identifier) ColorElementFactory identifier; +#define EMITTER_ENTRY(name, identifier) EmitterElementFactory identifier; +#define RES_ENTRY(name, identifier) ChildResourceFactory identifier; +#define BOOL_ENTRY(name, identifier) bool identifier = false; +#include "ELSC.def" + + template + void constexpr Enumerate(_Func f) { +#define ENTRY(name, identifier) f(FOURCC(name), identifier); +#include "ELSC.def" + } + + template + bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { +#define ENTRY(name, identifier) case SBIG(name): f(identifier); return true; +#include "ELSC.def" + default: return false; + } + } }; +template +using ELSM = PPImpl<_ELSM>; template bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); diff --git a/DataSpec/DNACommon/PART.cpp b/DataSpec/DNACommon/PART.cpp index abdeea0d2..23176e42a 100644 --- a/DataSpec/DNACommon/PART.cpp +++ b/DataSpec/DNACommon/PART.cpp @@ -1,9 +1,14 @@ #include "DataSpec/DNACommon/PART.hpp" - #include "DataSpec/DNACommon/PAK.hpp" namespace DataSpec::DNAParticle { +template struct PPImpl<_GPSM>; +template struct PPImpl<_GPSM>; + +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_GPSM>) +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_GPSM>) + template <> std::string_view GPSM::DNAType() { return "GPSM"sv; @@ -14,1399 +19,6 @@ std::string_view GPSM::DNAType() { return "GPSM"sv; } -template -void GPSM::_read(typename ReadYaml::StreamT& r) { - for (const auto& elem : r.getCurNode()->m_mapChildren) { - if (elem.first.size() < 4) { - LogModule.report(logvisor::Warning, fmt("short FourCC in element '{}'"), elem.first); - continue; - } - - if (auto rec = r.enterSubRecord(elem.first.c_str())) { - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('PMCL'): - x78_PMCL.read(r); - break; - case SBIG('LFOR'): - x118_LFOR.read(r); - break; - case SBIG('IDTS'): - xa4_IDTS.read(r); - break; - case SBIG('EMTR'): - x40_EMTR.read(r); - break; - case SBIG('COLR'): - x30_COLR.read(r); - break; - case SBIG('CIND'): - x45_30_CIND = r.readBool(); - break; - case SBIG('AAPH'): - x44_26_AAPH = r.readBool(); - break; - case SBIG('CSSD'): - xa0_CSSD.read(r); - break; - case SBIG('GRTE'): - x2c_GRTE.read(r); - break; - case SBIG('FXLL'): - x44_25_FXLL = r.readBool(); - break; - case SBIG('ICTS'): - x8c_ICTS.read(r); - break; - case SBIG('KSSM'): - xd0_KSSM.read(r); - break; - case SBIG('ILOC'): - x38_ILOC.read(r); - break; - case SBIG('IITS'): - xb8_IITS.read(r); - break; - case SBIG('IVEC'): - x3c_IVEC.read(r); - break; - case SBIG('LDIR'): - x110_LDIR.read(r); - break; - case SBIG('LCLR'): - x104_LCLR.read(r); - break; - case SBIG('LENG'): - x20_LENG.read(r); - break; - case SBIG('MAXP'): - x28_MAXP.read(r); - break; - case SBIG('LOFF'): - x10c_LOFF.read(r); - break; - case SBIG('LINT'): - x108_LINT.read(r); - break; - case SBIG('LINE'): - x44_24_LINE = r.readBool(); - break; - case SBIG('LFOT'): - x114_LFOT.read(r); - break; - case SBIG('LIT_'): - x44_29_LIT_ = r.readBool(); - break; - case SBIG('LTME'): - x34_LTME.read(r); - break; - case SBIG('LSLA'): - x11c_LSLA.read(r); - break; - case SBIG('LTYP'): - x100_LTYP.read(r); - break; - case SBIG('NDSY'): - xb4_NDSY.read(r); - break; - case SBIG('MBSP'): - x48_MBSP.read(r); - break; - case SBIG('MBLR'): - x44_30_MBLR = r.readBool(); - break; - case SBIG('NCSY'): - x9c_NCSY.read(r); - break; - case SBIG('PISY'): - xc8_PISY.read(r); - break; - case SBIG('OPTS'): - x45_31_OPTS = r.readBool(); - break; - case SBIG('PMAB'): - x44_31_PMAB = r.readBool(); - break; - case SBIG('SESD'): - xf8_SESD.read(r); - break; - case SBIG('SEPO'): - xfc_SEPO.read(r); - break; - case SBIG('PSLT'): - xc_PSLT.read(r); - break; - case SBIG('PMSC'): - x74_PMSC.read(r); - break; - case SBIG('PMOP'): - x6c_PMOP.read(r); - break; - case SBIG('PMDL'): - x5c_PMDL.read(r); - break; - case SBIG('PMRT'): - x70_PMRT.read(r); - break; - case SBIG('POFS'): - x18_POFS.read(r); - break; - case SBIG('PMUS'): - x45_24_PMUS = r.readBool(); - break; - case SBIG('PSIV'): - x0_PSIV.read(r); - break; - case SBIG('ROTA'): - x50_ROTA.read(r); - break; - case SBIG('PSVM'): - x4_PSVM.read(r); - break; - case SBIG('PSTS'): - x14_PSTS.read(r); - break; - case SBIG('PSOV'): - x8_PSOV.read(r); - break; - case SBIG('PSWT'): - x10_PSWT.read(r); - break; - case SBIG('PMLC'): - xec_PMLC.read(r); - break; - case SBIG('SEED'): - x1c_SEED.read(r); - break; - case SBIG('PMOO'): - x45_25_PMOO = r.readBool(); - break; - case SBIG('SSSD'): - xe4_SSSD.read(r); - break; - case SBIG('SORT'): - x44_28_SORT = r.readBool(); - break; - case SBIG('SIZE'): - x4c_SIZE.read(r); - break; - case SBIG('SISY'): - xcc_SISY.read(r); - break; - case SBIG('SSPO'): - xe8_SSPO.read(r); - break; - case SBIG('TEXR'): - x54_TEXR.read(r); - break; - case SBIG('SSWH'): - xd4_SSWH.read(r); - break; - case SBIG('TIND'): - x58_TIND.read(r); - break; - case SBIG('VMD4'): - x45_29_VMD4 = r.readBool(); - break; - case SBIG('VMD3'): - x45_28_VMD3 = r.readBool(); - break; - case SBIG('VMD2'): - x45_27_VMD2 = r.readBool(); - break; - case SBIG('VMD1'): - x45_26_VMD1 = r.readBool(); - break; - case SBIG('VEL4'): - x88_VEL4.read(r); - break; - case SBIG('VEL3'): - x84_VEL3.read(r); - break; - case SBIG('VEL2'): - x80_VEL2.read(r); - break; - case SBIG('VEL1'): - x7c_VEL1.read(r); - break; - case SBIG('ZBUF'): - x44_27_ZBUF = r.readBool(); - break; - case SBIG('WIDT'): - x24_WIDT.read(r); - break; - case SBIG('ORNT'): - x30_30_ORNT = r.readBool(); - break; - case SBIG('RSOP'): - x30_31_RSOP = r.readBool(); - break; - case SBIG('ADV1'): - x10c_ADV1.read(r); - break; - case SBIG('ADV2'): - x110_ADV2.read(r); - break; - case SBIG('ADV3'): - x114_ADV3.read(r); - break; - case SBIG('ADV4'): - x118_ADV4.read(r); - break; - case SBIG('ADV5'): - x11c_ADV5.read(r); - break; - case SBIG('ADV6'): - x120_ADV6.read(r); - break; - case SBIG('ADV7'): - x124_ADV7.read(r); - break; - case SBIG('SELC'): - xd8_SELC.read(r); - break; - default: - break; - } - } - } -} - -template -void GPSM::_write(typename WriteYaml::StreamT& w) const { - if (x0_PSIV) - if (auto rec = w.enterSubRecord("PSIV")) - x0_PSIV.write(w); - if (x4_PSVM) - if (auto rec = w.enterSubRecord("PSVM")) - x4_PSVM.write(w); - if (x8_PSOV) - if (auto rec = w.enterSubRecord("PSOV")) - x8_PSOV.write(w); - if (xc_PSLT) - if (auto rec = w.enterSubRecord("PSLT")) - xc_PSLT.write(w); - if (x10_PSWT) - if (auto rec = w.enterSubRecord("PSWT")) - x10_PSWT.write(w); - if (x14_PSTS) - if (auto rec = w.enterSubRecord("PSTS")) - x14_PSTS.write(w); - if (x18_POFS) - if (auto rec = w.enterSubRecord("POFS")) - x18_POFS.write(w); - if (x1c_SEED) - if (auto rec = w.enterSubRecord("SEED")) - x1c_SEED.write(w); - if (x20_LENG) - if (auto rec = w.enterSubRecord("LENG")) - x20_LENG.write(w); - if (x24_WIDT) - if (auto rec = w.enterSubRecord("WIDT")) - x24_WIDT.write(w); - if (x28_MAXP) - if (auto rec = w.enterSubRecord("MAXP")) - x28_MAXP.write(w); - if (x2c_GRTE) - if (auto rec = w.enterSubRecord("GRTE")) - x2c_GRTE.write(w); - if (x30_COLR) - if (auto rec = w.enterSubRecord("COLR")) - x30_COLR.write(w); - if (x34_LTME) - if (auto rec = w.enterSubRecord("LTME")) - x34_LTME.write(w); - if (x38_ILOC) - if (auto rec = w.enterSubRecord("ILOC")) - x38_ILOC.write(w); - if (x3c_IVEC) - if (auto rec = w.enterSubRecord("IVEC")) - x3c_IVEC.write(w); - if (x40_EMTR) - if (auto rec = w.enterSubRecord("EMTR")) - x40_EMTR.write(w); - if (x44_24_LINE) - w.writeBool("LINE", true); - if (x44_25_FXLL) - w.writeBool("FXLL", true); - if (x44_26_AAPH) - w.writeBool("AAPH", true); - if (x44_27_ZBUF) - w.writeBool("ZBUF", true); - if (x44_28_SORT) - w.writeBool("SORT", true); - if (x44_29_LIT_) - w.writeBool("LIT_", true); - if (x44_30_MBLR) - w.writeBool("MBLR", true); - if (x44_31_PMAB) - w.writeBool("PMAB", true); - if (x45_24_PMUS) - w.writeBool("PMUS", true); - if (!x45_25_PMOO) - w.writeBool("PMOO", false); - if (x45_26_VMD1) - w.writeBool("VMD1", true); - if (x45_27_VMD2) - w.writeBool("VMD2", true); - if (x45_28_VMD3) - w.writeBool("VMD3", true); - if (x45_29_VMD4) - w.writeBool("VMD4", true); - if (x45_30_CIND) - w.writeBool("CIND", true); - if (x45_31_OPTS) - w.writeBool("OPTS", true); - if (x30_30_ORNT) - w.writeBool("ORNT", true); - if (x30_31_RSOP) - w.writeBool("RSOP", true); - if (x48_MBSP) - if (auto rec = w.enterSubRecord("MBSP")) - x48_MBSP.write(w); - if (x4c_SIZE) - if (auto rec = w.enterSubRecord("SIZE")) - x4c_SIZE.write(w); - if (x50_ROTA) - if (auto rec = w.enterSubRecord("ROTA")) - x50_ROTA.write(w); - if (x54_TEXR) - if (auto rec = w.enterSubRecord("TEXR")) - x54_TEXR.write(w); - if (x58_TIND) - if (auto rec = w.enterSubRecord("TIND")) - x58_TIND.write(w); - if (x5c_PMDL) - if (auto rec = w.enterSubRecord("PMDL")) - x5c_PMDL.write(w); - if (x6c_PMOP) - if (auto rec = w.enterSubRecord("PMOP")) - x6c_PMOP.write(w); - if (x70_PMRT) - if (auto rec = w.enterSubRecord("PMRT")) - x70_PMRT.write(w); - if (x74_PMSC) - if (auto rec = w.enterSubRecord("PMSC")) - x74_PMSC.write(w); - if (x78_PMCL) - if (auto rec = w.enterSubRecord("PMCL")) - x78_PMCL.write(w); - if (x7c_VEL1) - if (auto rec = w.enterSubRecord("VEL1")) - x7c_VEL1.write(w); - if (x80_VEL2) - if (auto rec = w.enterSubRecord("VEL2")) - x80_VEL2.write(w); - if (x84_VEL3) - if (auto rec = w.enterSubRecord("VEL3")) - x84_VEL3.write(w); - if (x88_VEL4) - if (auto rec = w.enterSubRecord("VEL4")) - x88_VEL4.write(w); - if (x8c_ICTS) - if (auto rec = w.enterSubRecord("ICTS")) - x8c_ICTS.write(w); - if (x9c_NCSY) - if (auto rec = w.enterSubRecord("NCSY")) - x9c_NCSY.write(w); - if (xa0_CSSD) - if (auto rec = w.enterSubRecord("CSSD")) - xa0_CSSD.write(w); - if (xa4_IDTS) - if (auto rec = w.enterSubRecord("IDTS")) - xa4_IDTS.write(w); - if (xb4_NDSY) - if (auto rec = w.enterSubRecord("NDSY")) - xb4_NDSY.write(w); - if (xb8_IITS) - if (auto rec = w.enterSubRecord("IITS")) - xb8_IITS.write(w); - if (xc8_PISY) - if (auto rec = w.enterSubRecord("PISY")) - xc8_PISY.write(w); - if (xcc_SISY) - if (auto rec = w.enterSubRecord("SISY")) - xcc_SISY.write(w); - if (xd0_KSSM) - if (auto rec = w.enterSubRecord("KSSM")) - xd0_KSSM.write(w); - if (xd4_SSWH) - if (auto rec = w.enterSubRecord("SSWH")) - xd4_SSWH.write(w); - if (xd8_SELC) - if (auto rec = w.enterSubRecord("SELC")) - xd8_SELC.write(w); - if (xe4_SSSD) - if (auto rec = w.enterSubRecord("SSSD")) - xe4_SSSD.write(w); - if (xe8_SSPO) - if (auto rec = w.enterSubRecord("SSPO")) - xe8_SSPO.write(w); - if (xf8_SESD) - if (auto rec = w.enterSubRecord("SESD")) - xf8_SESD.write(w); - if (xfc_SEPO) - if (auto rec = w.enterSubRecord("SEPO")) - xfc_SEPO.write(w); - if (xec_PMLC) - if (auto rec = w.enterSubRecord("PMLC")) - xec_PMLC.write(w); - if (x100_LTYP) - if (auto rec = w.enterSubRecord("LTYP")) - x100_LTYP.write(w); - if (x104_LCLR) - if (auto rec = w.enterSubRecord("LCLR")) - x104_LCLR.write(w); - if (x108_LINT) - if (auto rec = w.enterSubRecord("LINT")) - x108_LINT.write(w); - if (x10c_LOFF) - if (auto rec = w.enterSubRecord("LOFF")) - x10c_LOFF.write(w); - if (x110_LDIR) - if (auto rec = w.enterSubRecord("LDIR")) - x110_LDIR.write(w); - if (x114_LFOT) - if (auto rec = w.enterSubRecord("LFOT")) - x114_LFOT.write(w); - if (x118_LFOR) - if (auto rec = w.enterSubRecord("LFOR")) - x118_LFOR.write(w); - if (x11c_LSLA) - if (auto rec = w.enterSubRecord("LSLA")) - x11c_LSLA.write(w); - if (x10c_ADV1) - if (auto rec = w.enterSubRecord("ADV1")) - x10c_ADV1.write(w); - if (x110_ADV2) - if (auto rec = w.enterSubRecord("ADV2")) - x110_ADV2.write(w); - if (x114_ADV3) - if (auto rec = w.enterSubRecord("ADV3")) - x114_ADV3.write(w); - if (x118_ADV4) - if (auto rec = w.enterSubRecord("ADV4")) - x118_ADV4.write(w); - if (x11c_ADV5) - if (auto rec = w.enterSubRecord("ADV5")) - x11c_ADV5.write(w); - if (x120_ADV6) - if (auto rec = w.enterSubRecord("ADV6")) - x120_ADV6.write(w); - if (x124_ADV7) - if (auto rec = w.enterSubRecord("ADV7")) - x124_ADV7.write(w); - if (x128_ADV8) - if (auto rec = w.enterSubRecord("ADV8")) - x128_ADV8.write(w); -} - -template -void GPSM::_binarySize(typename BinarySize::StreamT& s) const { - s += 4; - if (x0_PSIV) { - s += 4; - x0_PSIV.binarySize(s); - } - if (x4_PSVM) { - s += 4; - x4_PSVM.binarySize(s); - } - if (x8_PSOV) { - s += 4; - x8_PSOV.binarySize(s); - } - if (xc_PSLT) { - s += 4; - xc_PSLT.binarySize(s); - } - if (x10_PSWT) { - s += 4; - x10_PSWT.binarySize(s); - } - if (x14_PSTS) { - s += 4; - x14_PSTS.binarySize(s); - } - if (x18_POFS) { - s += 4; - x18_POFS.binarySize(s); - } - if (x1c_SEED) { - s += 4; - x1c_SEED.binarySize(s); - } - if (x20_LENG) { - s += 4; - x20_LENG.binarySize(s); - } - if (x24_WIDT) { - s += 4; - x24_WIDT.binarySize(s); - } - if (x28_MAXP) { - s += 4; - x28_MAXP.binarySize(s); - } - if (x2c_GRTE) { - s += 4; - x2c_GRTE.binarySize(s); - } - if (x30_COLR) { - s += 4; - x30_COLR.binarySize(s); - } - if (x34_LTME) { - s += 4; - x34_LTME.binarySize(s); - } - if (x38_ILOC) { - s += 4; - x38_ILOC.binarySize(s); - } - if (x3c_IVEC) { - s += 4; - x3c_IVEC.binarySize(s); - } - if (x40_EMTR) { - s += 4; - x40_EMTR.binarySize(s); - } - if (x44_24_LINE) - s += 9; - if (x44_25_FXLL) - s += 9; - if (x44_26_AAPH) - s += 9; - if (x44_27_ZBUF) - s += 9; - if (x44_28_SORT) - s += 9; - if (x44_29_LIT_) - s += 9; - if (x44_30_MBLR) - s += 9; - if (x44_31_PMAB) - s += 9; - if (x45_24_PMUS) - s += 9; - if (!x45_25_PMOO) - s += 9; - if (x45_26_VMD1) - s += 9; - if (x45_27_VMD2) - s += 9; - if (x45_28_VMD3) - s += 9; - if (x45_29_VMD4) - s += 9; - if (x45_30_CIND) - s += 9; - if (x45_31_OPTS) - s += 9; - if (x30_30_ORNT) - s += 9; - if (x30_31_RSOP) - s += 9; - if (x48_MBSP) { - s += 4; - x48_MBSP.binarySize(s); - } - if (x4c_SIZE) { - s += 4; - x4c_SIZE.binarySize(s); - } - if (x50_ROTA) { - s += 4; - x50_ROTA.binarySize(s); - } - if (x54_TEXR) { - s += 4; - x54_TEXR.binarySize(s); - } - if (x58_TIND) { - s += 4; - x58_TIND.binarySize(s); - } - if (x5c_PMDL) { - s += 4; - x5c_PMDL.binarySize(s); - } - if (x6c_PMOP) { - s += 4; - x6c_PMOP.binarySize(s); - } - if (x70_PMRT) { - s += 4; - x70_PMRT.binarySize(s); - } - if (x74_PMSC) { - s += 4; - x74_PMSC.binarySize(s); - } - if (x78_PMCL) { - s += 4; - x78_PMCL.binarySize(s); - } - if (x7c_VEL1) { - s += 4; - x7c_VEL1.binarySize(s); - } - if (x80_VEL2) { - s += 4; - x80_VEL2.binarySize(s); - } - if (x84_VEL3) { - s += 4; - x84_VEL3.binarySize(s); - } - if (x88_VEL4) { - s += 4; - x88_VEL4.binarySize(s); - } - if (x8c_ICTS) { - s += 4; - x8c_ICTS.binarySize(s); - } - if (x9c_NCSY) { - s += 4; - x9c_NCSY.binarySize(s); - } - if (xa0_CSSD) { - s += 4; - xa0_CSSD.binarySize(s); - } - if (xa4_IDTS) { - s += 4; - xa4_IDTS.binarySize(s); - } - if (xb4_NDSY) { - s += 4; - xb4_NDSY.binarySize(s); - } - if (xb8_IITS) { - s += 4; - xb8_IITS.binarySize(s); - } - if (xc8_PISY) { - s += 4; - xc8_PISY.binarySize(s); - } - if (xcc_SISY) { - s += 4; - xcc_SISY.binarySize(s); - } - if (xd0_KSSM) { - s += 4; - xd0_KSSM.binarySize(s); - } - if (xd4_SSWH) { - s += 4; - xd4_SSWH.binarySize(s); - } - if (xd8_SELC) { - s += 4; - xd8_SELC.binarySize(s); - } - if (xe4_SSSD) { - s += 4; - xe4_SSSD.binarySize(s); - } - if (xe8_SSPO) { - s += 4; - xe8_SSPO.binarySize(s); - } - if (xf8_SESD) { - s += 4; - xf8_SESD.binarySize(s); - } - if (xfc_SEPO) { - s += 4; - xfc_SEPO.binarySize(s); - } - if (xec_PMLC) { - s += 4; - xec_PMLC.binarySize(s); - } - if (x100_LTYP) { - s += 4; - x100_LTYP.binarySize(s); - } - if (x104_LCLR) { - s += 4; - x104_LCLR.binarySize(s); - } - if (x108_LINT) { - s += 4; - x108_LINT.binarySize(s); - } - if (x10c_LOFF) { - s += 4; - x10c_LOFF.binarySize(s); - } - if (x110_LDIR) { - s += 4; - x110_LDIR.binarySize(s); - } - if (x114_LFOT) { - s += 4; - x114_LFOT.binarySize(s); - } - if (x118_LFOR) { - s += 4; - x118_LFOR.binarySize(s); - } - if (x11c_LSLA) { - s += 4; - x11c_LSLA.binarySize(s); - } - if (x10c_ADV1) { - s += 4; - x10c_ADV1.binarySize(s); - } - if (x110_ADV2) { - s += 4; - x110_ADV2.binarySize(s); - } - if (x114_ADV3) { - s += 4; - x114_ADV3.binarySize(s); - } - if (x118_ADV4) { - s += 4; - x118_ADV4.binarySize(s); - } - if (x11c_ADV5) { - s += 4; - x11c_ADV5.binarySize(s); - } - if (x120_ADV6) { - s += 4; - x120_ADV6.binarySize(s); - } - if (x124_ADV7) { - s += 4; - x124_ADV7.binarySize(s); - } - if (x128_ADV8) { - s += 4; - x128_ADV8.binarySize(s); - } -} - -template -void GPSM::_read(typename Read::StreamT& r) { - DNAFourCC clsId; - clsId.read(r); - if (clsId != SBIG('GPSM')) { - LogModule.report(logvisor::Warning, fmt("non GPSM provided to GPSM parser")); - return; - } - clsId.read(r); - while (clsId != SBIG('_END')) { - switch (clsId.toUint32()) { - case SBIG('PMCL'): - x78_PMCL.read(r); - break; - case SBIG('LFOR'): - x118_LFOR.read(r); - break; - case SBIG('IDTS'): - xa4_IDTS.read(r); - break; - case SBIG('EMTR'): - x40_EMTR.read(r); - break; - case SBIG('COLR'): - x30_COLR.read(r); - break; - case SBIG('CIND'): - r.readUint32Big(); - x45_30_CIND = r.readBool(); - break; - case SBIG('AAPH'): - r.readUint32Big(); - x44_26_AAPH = r.readBool(); - break; - case SBIG('CSSD'): - xa0_CSSD.read(r); - break; - case SBIG('GRTE'): - x2c_GRTE.read(r); - break; - case SBIG('FXLL'): - r.readUint32Big(); - x44_25_FXLL = r.readBool(); - break; - case SBIG('ICTS'): - x8c_ICTS.read(r); - break; - case SBIG('KSSM'): - xd0_KSSM.read(r); - break; - case SBIG('ILOC'): - x38_ILOC.read(r); - break; - case SBIG('IITS'): - xb8_IITS.read(r); - break; - case SBIG('IVEC'): - x3c_IVEC.read(r); - break; - case SBIG('LDIR'): - x110_LDIR.read(r); - break; - case SBIG('LCLR'): - x104_LCLR.read(r); - break; - case SBIG('LENG'): - x20_LENG.read(r); - break; - case SBIG('MAXP'): - x28_MAXP.read(r); - break; - case SBIG('LOFF'): - x10c_LOFF.read(r); - break; - case SBIG('LINT'): - x108_LINT.read(r); - break; - case SBIG('LINE'): - r.readUint32Big(); - x44_24_LINE = r.readBool(); - break; - case SBIG('LFOT'): - x114_LFOT.read(r); - break; - case SBIG('LIT_'): - r.readUint32Big(); - x44_29_LIT_ = r.readBool(); - break; - case SBIG('LTME'): - x34_LTME.read(r); - break; - case SBIG('LSLA'): - x11c_LSLA.read(r); - break; - case SBIG('LTYP'): - x100_LTYP.read(r); - break; - case SBIG('NDSY'): - xb4_NDSY.read(r); - break; - case SBIG('MBSP'): - x48_MBSP.read(r); - break; - case SBIG('MBLR'): - r.readUint32Big(); - x44_30_MBLR = r.readBool(); - break; - case SBIG('NCSY'): - x9c_NCSY.read(r); - break; - case SBIG('PISY'): - xc8_PISY.read(r); - break; - case SBIG('OPTS'): - r.readUint32Big(); - x45_31_OPTS = r.readBool(); - break; - case SBIG('PMAB'): - r.readUint32Big(); - x44_31_PMAB = r.readBool(); - break; - case SBIG('SESD'): - xf8_SESD.read(r); - break; - case SBIG('SEPO'): - xfc_SEPO.read(r); - break; - case SBIG('PSLT'): - xc_PSLT.read(r); - break; - case SBIG('PMSC'): - x74_PMSC.read(r); - break; - case SBIG('PMOP'): - x6c_PMOP.read(r); - break; - case SBIG('PMDL'): - x5c_PMDL.read(r); - break; - case SBIG('PMRT'): - x70_PMRT.read(r); - break; - case SBIG('POFS'): - x18_POFS.read(r); - break; - case SBIG('PMUS'): - r.readUint32Big(); - x45_24_PMUS = r.readBool(); - break; - case SBIG('PSIV'): - x0_PSIV.read(r); - break; - case SBIG('ROTA'): - x50_ROTA.read(r); - break; - case SBIG('PSVM'): - x4_PSVM.read(r); - break; - case SBIG('PSTS'): - x14_PSTS.read(r); - break; - case SBIG('PSOV'): - x8_PSOV.read(r); - break; - case SBIG('PSWT'): - x10_PSWT.read(r); - break; - case SBIG('PMLC'): - xec_PMLC.read(r); - break; - case SBIG('SEED'): - x1c_SEED.read(r); - break; - case SBIG('PMOO'): - r.readUint32Big(); - x45_25_PMOO = r.readBool(); - break; - case SBIG('SSSD'): - xe4_SSSD.read(r); - break; - case SBIG('SORT'): - r.readUint32Big(); - x44_28_SORT = r.readBool(); - break; - case SBIG('SIZE'): - x4c_SIZE.read(r); - break; - case SBIG('SISY'): - xcc_SISY.read(r); - break; - case SBIG('SSPO'): - xe8_SSPO.read(r); - break; - case SBIG('TEXR'): - x54_TEXR.read(r); - break; - case SBIG('SSWH'): - xd4_SSWH.read(r); - break; - case SBIG('TIND'): - x58_TIND.read(r); - break; - case SBIG('VMD4'): - r.readUint32Big(); - x45_29_VMD4 = r.readBool(); - break; - case SBIG('VMD3'): - r.readUint32Big(); - x45_28_VMD3 = r.readBool(); - break; - case SBIG('VMD2'): - r.readUint32Big(); - x45_27_VMD2 = r.readBool(); - break; - case SBIG('VMD1'): - r.readUint32Big(); - x45_26_VMD1 = r.readBool(); - break; - case SBIG('VEL4'): - x88_VEL4.read(r); - break; - case SBIG('VEL3'): - x84_VEL3.read(r); - break; - case SBIG('VEL2'): - x80_VEL2.read(r); - break; - case SBIG('VEL1'): - x7c_VEL1.read(r); - break; - case SBIG('ZBUF'): - r.readUint32Big(); - x44_27_ZBUF = r.readBool(); - break; - case SBIG('WIDT'): - x24_WIDT.read(r); - break; - case SBIG('ORNT'): - r.readUint32Big(); - x30_30_ORNT = r.readBool(); - break; - case SBIG('RSOP'): - r.readUint32Big(); - x30_31_RSOP = r.readBool(); - break; - case SBIG('ADV1'): - x10c_ADV1.read(r); - break; - case SBIG('ADV2'): - x110_ADV2.read(r); - break; - case SBIG('ADV3'): - x114_ADV3.read(r); - break; - case SBIG('ADV4'): - x118_ADV4.read(r); - break; - case SBIG('ADV5'): - x11c_ADV5.read(r); - break; - case SBIG('ADV6'): - x120_ADV6.read(r); - break; - case SBIG('ADV7'): - x124_ADV7.read(r); - break; - case SBIG('ADV8'): - x128_ADV8.read(r); - break; - case SBIG('SELC'): - xd8_SELC.read(r); - break; - default: - LogModule.report(logvisor::Fatal, fmt("Unknown GPSM class {} @{}"), clsId, r.position()); - break; - } - clsId.read(r); - } -} - -template -void GPSM::_write(typename Write::StreamT& w) const { - w.writeBytes((atInt8*)"GPSM", 4); - if (x0_PSIV) { - w.writeBytes((atInt8*)"PSIV", 4); - x0_PSIV.write(w); - } - if (x4_PSVM) { - w.writeBytes((atInt8*)"PSVM", 4); - x4_PSVM.write(w); - } - if (x8_PSOV) { - w.writeBytes((atInt8*)"PSOV", 4); - x8_PSOV.write(w); - } - if (xc_PSLT) { - w.writeBytes((atInt8*)"PSLT", 4); - xc_PSLT.write(w); - } - if (x10_PSWT) { - w.writeBytes((atInt8*)"PSWT", 4); - x10_PSWT.write(w); - } - if (x14_PSTS) { - w.writeBytes((atInt8*)"PSTS", 4); - x14_PSTS.write(w); - } - if (x18_POFS) { - w.writeBytes((atInt8*)"POFS", 4); - x18_POFS.write(w); - } - if (x1c_SEED) { - w.writeBytes((atInt8*)"SEED", 4); - x1c_SEED.write(w); - } - if (x20_LENG) { - w.writeBytes((atInt8*)"LENG", 4); - x20_LENG.write(w); - } - if (x24_WIDT) { - w.writeBytes((atInt8*)"WIDT", 4); - x24_WIDT.write(w); - } - if (x28_MAXP) { - w.writeBytes((atInt8*)"MAXP", 4); - x28_MAXP.write(w); - } - if (x2c_GRTE) { - w.writeBytes((atInt8*)"GRTE", 4); - x2c_GRTE.write(w); - } - if (x30_COLR) { - w.writeBytes((atInt8*)"COLR", 4); - x30_COLR.write(w); - } - if (x34_LTME) { - w.writeBytes((atInt8*)"LTME", 4); - x34_LTME.write(w); - } - if (x38_ILOC) { - w.writeBytes((atInt8*)"ILOC", 4); - x38_ILOC.write(w); - } - if (x3c_IVEC) { - w.writeBytes((atInt8*)"IVEC", 4); - x3c_IVEC.write(w); - } - if (x40_EMTR) { - w.writeBytes((atInt8*)"EMTR", 4); - x40_EMTR.write(w); - } - if (x44_24_LINE) { - w.writeBytes((atInt8*)"LINECNST\x01", 9); - } - if (x44_25_FXLL) { - w.writeBytes((atInt8*)"FXLLCNST\x01", 9); - } - if (x44_26_AAPH) { - w.writeBytes((atInt8*)"AAPHCNST\x01", 9); - } - if (x44_27_ZBUF) { - w.writeBytes((atInt8*)"ZBUFCNST\x01", 9); - } - if (x44_28_SORT) { - w.writeBytes((atInt8*)"SORTCNST\x01", 9); - } - if (x44_29_LIT_) { - w.writeBytes((atInt8*)"LIT_CNST\x01", 9); - } - if (x44_30_MBLR) { - w.writeBytes((atInt8*)"MBLRCNST\x01", 9); - } - if (x44_31_PMAB) { - w.writeBytes((atInt8*)"PMABCNST\x01", 9); - } - if (x45_24_PMUS) { - w.writeBytes((atInt8*)"PMUSCNST\x01", 9); - } - if (!x45_25_PMOO) { - w.writeBytes((atInt8*)"PMOOCNST\x00", 9); - } - if (x45_26_VMD1) { - w.writeBytes((atInt8*)"VMD1CNST\x01", 9); - } - if (x45_27_VMD2) { - w.writeBytes((atInt8*)"VMD2CNST\x01", 9); - } - if (x45_28_VMD3) { - w.writeBytes((atInt8*)"VMD3CNST\x01", 9); - } - if (x45_29_VMD4) { - w.writeBytes((atInt8*)"VMD4CNST\x01", 9); - } - if (x45_30_CIND) { - w.writeBytes((atInt8*)"CINDCNST\x01", 9); - } - if (x45_31_OPTS) { - w.writeBytes((atInt8*)"OPTSCNST\x01", 9); - } - if (x30_30_ORNT) { - w.writeBytes((atInt8*)"ORNTCNST\x01", 9); - } - if (x30_31_RSOP) { - w.writeBytes((atInt8*)"RSOPCNST\x01", 9); - } - if (x48_MBSP) { - w.writeBytes((atInt8*)"MBSP", 4); - x48_MBSP.write(w); - } - if (x4c_SIZE) { - w.writeBytes((atInt8*)"SIZE", 4); - x4c_SIZE.write(w); - } - if (x50_ROTA) { - w.writeBytes((atInt8*)"ROTA", 4); - x50_ROTA.write(w); - } - if (x54_TEXR) { - w.writeBytes((atInt8*)"TEXR", 4); - x54_TEXR.write(w); - } - if (x58_TIND) { - w.writeBytes((atInt8*)"TIND", 4); - x58_TIND.write(w); - } - if (x5c_PMDL) { - w.writeBytes((atInt8*)"PMDL", 4); - x5c_PMDL.write(w); - } - if (x6c_PMOP) { - w.writeBytes((atInt8*)"PMOP", 4); - x6c_PMOP.write(w); - } - if (x70_PMRT) { - w.writeBytes((atInt8*)"PMRT", 4); - x70_PMRT.write(w); - } - if (x74_PMSC) { - w.writeBytes((atInt8*)"PMSC", 4); - x74_PMSC.write(w); - } - if (x78_PMCL) { - w.writeBytes((atInt8*)"PMCL", 4); - x78_PMCL.write(w); - } - if (x7c_VEL1) { - w.writeBytes((atInt8*)"VEL1", 4); - x7c_VEL1.write(w); - } - if (x80_VEL2) { - w.writeBytes((atInt8*)"VEL2", 4); - x80_VEL2.write(w); - } - if (x84_VEL3) { - w.writeBytes((atInt8*)"VEL3", 4); - x84_VEL3.write(w); - } - if (x88_VEL4) { - w.writeBytes((atInt8*)"VEL4", 4); - x88_VEL4.write(w); - } - if (x8c_ICTS) { - w.writeBytes((atInt8*)"ICTS", 4); - x8c_ICTS.write(w); - } - if (x9c_NCSY) { - w.writeBytes((atInt8*)"NCSY", 4); - x9c_NCSY.write(w); - } - if (xa0_CSSD) { - w.writeBytes((atInt8*)"CSSD", 4); - xa0_CSSD.write(w); - } - if (xa4_IDTS) { - w.writeBytes((atInt8*)"IDTS", 4); - xa4_IDTS.write(w); - } - if (xb4_NDSY) { - w.writeBytes((atInt8*)"NDSY", 4); - xb4_NDSY.write(w); - } - if (xb8_IITS) { - w.writeBytes((atInt8*)"IITS", 4); - xb8_IITS.write(w); - } - if (xc8_PISY) { - w.writeBytes((atInt8*)"PISY", 4); - xc8_PISY.write(w); - } - if (xcc_SISY) { - w.writeBytes((atInt8*)"SISY", 4); - xcc_SISY.write(w); - } - if (xd0_KSSM) { - w.writeBytes((atInt8*)"KSSM", 4); - xd0_KSSM.write(w); - } - if (xd4_SSWH) { - w.writeBytes((atInt8*)"SSWH", 4); - xd4_SSWH.write(w); - } - if (xd8_SELC) { - w.writeBytes((atInt8*)"SELC", 4); - xd8_SELC.write(w); - } - if (xe4_SSSD) { - w.writeBytes((atInt8*)"SSSD", 4); - xe4_SSSD.write(w); - } - if (xe8_SSPO) { - w.writeBytes((atInt8*)"SSPO", 4); - xe8_SSPO.write(w); - } - if (xf8_SESD) { - w.writeBytes((atInt8*)"SESD", 4); - xf8_SESD.write(w); - } - if (xfc_SEPO) { - w.writeBytes((atInt8*)"SEPO", 4); - xfc_SEPO.write(w); - } - if (xec_PMLC) { - w.writeBytes((atInt8*)"PMLC", 4); - xec_PMLC.write(w); - } - if (x100_LTYP) { - w.writeBytes((atInt8*)"LTYP", 4); - x100_LTYP.write(w); - } - if (x104_LCLR) { - w.writeBytes((atInt8*)"LCLR", 4); - x104_LCLR.write(w); - } - if (x108_LINT) { - w.writeBytes((atInt8*)"LINT", 4); - x108_LINT.write(w); - } - if (x10c_LOFF) { - w.writeBytes((atInt8*)"LOFF", 4); - x10c_LOFF.write(w); - } - if (x110_LDIR) { - w.writeBytes((atInt8*)"LDIR", 4); - x110_LDIR.write(w); - } - if (x114_LFOT) { - w.writeBytes((atInt8*)"LFOT", 4); - x114_LFOT.write(w); - } - if (x118_LFOR) { - w.writeBytes((atInt8*)"LFOR", 4); - x118_LFOR.write(w); - } - if (x11c_LSLA) { - w.writeBytes((atInt8*)"LSLA", 4); - x11c_LSLA.write(w); - } - if (x10c_ADV1) { - w.writeBytes((atInt8*)"ADV1", 4); - x10c_ADV1.write(w); - } - if (x110_ADV2) { - w.writeBytes((atInt8*)"ADV2", 4); - x110_ADV2.write(w); - } - if (x114_ADV3) { - w.writeBytes((atInt8*)"ADV3", 4); - x114_ADV3.write(w); - } - if (x118_ADV4) { - w.writeBytes((atInt8*)"ADV4", 4); - x118_ADV4.write(w); - } - if (x11c_ADV5) { - w.writeBytes((atInt8*)"ADV5", 4); - x11c_ADV5.write(w); - } - if (x120_ADV6) { - w.writeBytes((atInt8*)"ADV6", 4); - x120_ADV6.write(w); - } - if (x124_ADV7) { - w.writeBytes((atInt8*)"ADV7", 4); - x124_ADV7.write(w); - } - if (x128_ADV8) { - w.writeBytes((atInt8*)"ADV8", 4); - x128_ADV8.write(w); - } - w.writeBytes("_END", 4); -} - -AT_SUBSPECIALIZE_DNA_YAML(GPSM) -AT_SUBSPECIALIZE_DNA_YAML(GPSM) - -template -void GPSM::gatherDependencies(std::vector& pathsOut) const { - if (x54_TEXR.m_elem) - x54_TEXR.m_elem->gatherDependencies(pathsOut); - if (x58_TIND.m_elem) - x58_TIND.m_elem->gatherDependencies(pathsOut); - g_curSpec->flattenDependencies(x5c_PMDL.id, pathsOut); - g_curSpec->flattenDependencies(x8c_ICTS.id, pathsOut); - g_curSpec->flattenDependencies(xa4_IDTS.id, pathsOut); - g_curSpec->flattenDependencies(xb8_IITS.id, pathsOut); - xd0_KSSM.gatherDependencies(pathsOut); - g_curSpec->flattenDependencies(xd4_SSWH.id, pathsOut); - g_curSpec->flattenDependencies(xec_PMLC.id, pathsOut); - g_curSpec->flattenDependencies(xd8_SELC.id, pathsOut); -} - -template struct GPSM; -template struct GPSM; - template bool ExtractGPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { athena::io::FileWriter writer(outPath.getAbsolutePath()); diff --git a/DataSpec/DNACommon/PART.def b/DataSpec/DNACommon/PART.def new file mode 100644 index 000000000..8b932cbf3 --- /dev/null +++ b/DataSpec/DNACommon/PART.def @@ -0,0 +1,141 @@ +#ifndef ENTRY +#define ENTRY(name, identifier) +#endif + +#ifndef INT_ENTRY +#define INT_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef REAL_ENTRY +#define REAL_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef VECTOR_ENTRY +#define VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef MOD_VECTOR_ENTRY +#define MOD_VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef COLOR_ENTRY +#define COLOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef EMITTER_ENTRY +#define EMITTER_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef UV_ENTRY +#define UV_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef RES_ENTRY +#define RES_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef KSSM_ENTRY +#define KSSM_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef BOOL_ENTRY +#define BOOL_ENTRY(name, identifier, def) ENTRY(name, identifier) +#endif + +VECTOR_ENTRY('PSIV', x0_PSIV) +MOD_VECTOR_ENTRY('PSVM', x4_PSVM) +VECTOR_ENTRY('PSOV', x8_PSOV) +INT_ENTRY('PSLT', xc_PSLT) +INT_ENTRY('PSWT', x10_PSWT) +REAL_ENTRY('PSTS', x14_PSTS) +VECTOR_ENTRY('POFS', x18_POFS) +INT_ENTRY('SEED', x1c_SEED) +REAL_ENTRY('LENG', x20_LENG) +REAL_ENTRY('WIDT', x24_WIDT) +INT_ENTRY('MAXP', x28_MAXP) +REAL_ENTRY('GRTE', x2c_GRTE) +COLOR_ENTRY('COLR', x30_COLR) +INT_ENTRY('LTME', x34_LTME) +VECTOR_ENTRY('ILOC', x38_ILOC) +VECTOR_ENTRY('IVEC', x3c_IVEC) +EMITTER_ENTRY('EMTR', x40_EMTR) +INT_ENTRY('MBSP', x48_MBSP) +REAL_ENTRY('SIZE', x4c_SIZE) +REAL_ENTRY('ROTA', x50_ROTA) +UV_ENTRY('TEXR', x54_TEXR) +UV_ENTRY('TIND', x58_TIND) +RES_ENTRY('PMDL', x5c_PMDL) +VECTOR_ENTRY('PMOP', x6c_PMOP) +VECTOR_ENTRY('PMRT', x70_PMRT) +VECTOR_ENTRY('PMSC', x74_PMSC) +COLOR_ENTRY('PMCL', x78_PMCL) +MOD_VECTOR_ENTRY('VEL1', x7c_VEL1) +MOD_VECTOR_ENTRY('VEL2', x80_VEL2) +MOD_VECTOR_ENTRY('VEL3', x84_VEL3) +MOD_VECTOR_ENTRY('VEL4', x88_VEL4) +RES_ENTRY('ICTS', x8c_ICTS) +INT_ENTRY('NCSY', x9c_NCSY) +INT_ENTRY('CSSD', xa0_CSSD) +RES_ENTRY('IDTS', xa4_IDTS) +INT_ENTRY('NDSY', xb4_NDSY) +RES_ENTRY('IITS', xb8_IITS) +INT_ENTRY('PISY', xc8_PISY) +INT_ENTRY('SISY', xcc_SISY) +KSSM_ENTRY('KSSM', xd0_KSSM) +RES_ENTRY('SSWH', xd4_SSWH) +INT_ENTRY('SSSD', xe4_SSSD) +VECTOR_ENTRY('SSPO', xe8_SSPO) +INT_ENTRY('SESD', xf8_SESD) +VECTOR_ENTRY('SEPO', xfc_SEPO) +RES_ENTRY('PMLC', xec_PMLC) +INT_ENTRY('LTYP', x100_LTYP) +COLOR_ENTRY('LCLR', x104_LCLR) +REAL_ENTRY('LINT', x108_LINT) +VECTOR_ENTRY('LOFF', x10c_LOFF) +VECTOR_ENTRY('LDIR', x110_LDIR) +INT_ENTRY('LFOT', x114_LFOT) +REAL_ENTRY('LFOR', x118_LFOR) +REAL_ENTRY('LSLA', x11c_LSLA) + +/* 0-00 additions */ +RES_ENTRY('SELC', xd8_SELC) +REAL_ENTRY('ADV1', x10c_ADV1) +REAL_ENTRY('ADV2', x110_ADV2) +REAL_ENTRY('ADV3', x114_ADV3) +REAL_ENTRY('ADV4', x118_ADV4) +REAL_ENTRY('ADV5', x11c_ADV5) +REAL_ENTRY('ADV6', x120_ADV6) +REAL_ENTRY('ADV7', x124_ADV7) +REAL_ENTRY('ADV8', x128_ADV8) + +BOOL_ENTRY('SORT', x44_28_SORT, false) +BOOL_ENTRY('MBLR', x44_30_MBLR, false) +BOOL_ENTRY('LINE', x44_24_LINE, false) +BOOL_ENTRY('LIT_', x44_29_LIT_, false) +BOOL_ENTRY('AAPH', x44_26_AAPH, false) +BOOL_ENTRY('ZBUF', x44_27_ZBUF, false) +BOOL_ENTRY('FXLL', x44_25_FXLL, false) +BOOL_ENTRY('PMAB', x44_31_PMAB, false) +BOOL_ENTRY('VMD4', x45_29_VMD4, false) +BOOL_ENTRY('VMD3', x45_28_VMD3, false) +BOOL_ENTRY('VMD2', x45_27_VMD2, false) +BOOL_ENTRY('VMD1', x45_26_VMD1, false) +BOOL_ENTRY('OPTS', x45_31_OPTS, false) +BOOL_ENTRY('PMUS', x45_24_PMUS, false) +BOOL_ENTRY('PMOO', x45_25_PMOO, true) +BOOL_ENTRY('CIND', x45_30_CIND, false) + +BOOL_ENTRY('ORNT', x30_30_ORNT, false) +BOOL_ENTRY('RSOP', x30_31_RSOP, false) + +#undef ENTRY +#undef INT_ENTRY +#undef REAL_ENTRY +#undef VECTOR_ENTRY +#undef MOD_VECTOR_ENTRY +#undef COLOR_ENTRY +#undef EMITTER_ENTRY +#undef UV_ENTRY +#undef RES_ENTRY +#undef KSSM_ENTRY +#undef BOOL_ENTRY diff --git a/DataSpec/DNACommon/PART.hpp b/DataSpec/DNACommon/PART.hpp index 0475dc217..8c30dc28d 100644 --- a/DataSpec/DNACommon/PART.hpp +++ b/DataSpec/DNACommon/PART.hpp @@ -17,107 +17,39 @@ class ProjectPath; namespace DataSpec::DNAParticle { template -struct GPSM : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA - VectorElementFactory x0_PSIV; - ModVectorElementFactory x4_PSVM; - VectorElementFactory x8_PSOV; - IntElementFactory xc_PSLT; - IntElementFactory x10_PSWT; - RealElementFactory x14_PSTS; - VectorElementFactory x18_POFS; - IntElementFactory x1c_SEED; - RealElementFactory x20_LENG; - RealElementFactory x24_WIDT; - IntElementFactory x28_MAXP; - RealElementFactory x2c_GRTE; - ColorElementFactory x30_COLR; - IntElementFactory x34_LTME; - VectorElementFactory x38_ILOC; - VectorElementFactory x3c_IVEC; - EmitterElementFactory x40_EMTR; - union { - struct { - bool x44_28_SORT : 1; - bool x44_30_MBLR : 1; - bool x44_24_LINE : 1; - bool x44_29_LIT_ : 1; - bool x44_26_AAPH : 1; - bool x44_27_ZBUF : 1; - bool x44_25_FXLL : 1; - bool x44_31_PMAB : 1; - bool x45_29_VMD4 : 1; - bool x45_28_VMD3 : 1; - bool x45_27_VMD2 : 1; - bool x45_26_VMD1 : 1; - bool x45_31_OPTS : 1; - bool x45_24_PMUS : 1; - bool x45_25_PMOO : 1; - bool x45_30_CIND : 1; - }; - uint16_t dummy1 = 0; - }; - IntElementFactory x48_MBSP; - RealElementFactory x4c_SIZE; - RealElementFactory x50_ROTA; - UVElementFactory x54_TEXR; - UVElementFactory x58_TIND; - ChildResourceFactory x5c_PMDL; - VectorElementFactory x6c_PMOP; - VectorElementFactory x70_PMRT; - VectorElementFactory x74_PMSC; - ColorElementFactory x78_PMCL; - ModVectorElementFactory x7c_VEL1; - ModVectorElementFactory x80_VEL2; - ModVectorElementFactory x84_VEL3; - ModVectorElementFactory x88_VEL4; - ChildResourceFactory x8c_ICTS; - IntElementFactory x9c_NCSY; - IntElementFactory xa0_CSSD; - ChildResourceFactory xa4_IDTS; - IntElementFactory xb4_NDSY; - ChildResourceFactory xb8_IITS; - IntElementFactory xc8_PISY; - IntElementFactory xcc_SISY; - SpawnSystemKeyframeData xd0_KSSM; - ChildResourceFactory xd4_SSWH; - IntElementFactory xe4_SSSD; - VectorElementFactory xe8_SSPO; - IntElementFactory xf8_SESD; - VectorElementFactory xfc_SEPO; - ChildResourceFactory xec_PMLC; - IntElementFactory x100_LTYP; - ColorElementFactory x104_LCLR; - RealElementFactory x108_LINT; - VectorElementFactory x10c_LOFF; - VectorElementFactory x110_LDIR; - IntElementFactory x114_LFOT; - RealElementFactory x118_LFOR; - RealElementFactory x11c_LSLA; +struct _GPSM { + static constexpr ParticleType Type = ParticleType::GPSM; - /* 0-00 additions */ - ChildResourceFactory xd8_SELC; - union { - struct { - bool x30_30_ORNT : 1; - bool x30_31_RSOP : 1; - }; - uint16_t dummy2 = 0; - }; - RealElementFactory x10c_ADV1; - RealElementFactory x110_ADV2; - RealElementFactory x114_ADV3; - RealElementFactory x118_ADV4; - RealElementFactory x11c_ADV5; - RealElementFactory x120_ADV6; - RealElementFactory x124_ADV7; - RealElementFactory x128_ADV8; +#define INT_ENTRY(name, identifier) IntElementFactory identifier; +#define REAL_ENTRY(name, identifier) RealElementFactory identifier; +#define VECTOR_ENTRY(name, identifier) VectorElementFactory identifier; +#define MOD_VECTOR_ENTRY(name, identifier) ModVectorElementFactory identifier; +#define COLOR_ENTRY(name, identifier) ColorElementFactory identifier; +#define EMITTER_ENTRY(name, identifier) EmitterElementFactory identifier; +#define UV_ENTRY(name, identifier) UVElementFactory identifier; +#define RES_ENTRY(name, identifier) ChildResourceFactory identifier; +#define KSSM_ENTRY(name, identifier) SpawnSystemKeyframeData identifier; +#define BOOL_ENTRY(name, identifier, def) bool identifier = def; +#include "PART.def" - GPSM() { x45_25_PMOO = true; } + template + void constexpr Enumerate(_Func f) { +#define ENTRY(name, identifier) f(FOURCC(name), identifier); +#define BOOL_ENTRY(name, identifier, def) f(FOURCC(name), identifier, def); +#include "PART.def" + } - void gatherDependencies(std::vector&) const; + template + bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { +#define ENTRY(name, identifier) case SBIG(name): f(identifier); return true; +#include "PART.def" + default: return false; + } + } }; +template +using GPSM = PPImpl<_GPSM>; template bool ExtractGPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); diff --git a/DataSpec/DNACommon/ParticleCommon.cpp b/DataSpec/DNACommon/ParticleCommon.cpp index 7ef172e8b..301f6ac56 100644 --- a/DataSpec/DNACommon/ParticleCommon.cpp +++ b/DataSpec/DNACommon/ParticleCommon.cpp @@ -3,6 +3,24 @@ namespace DataSpec::DNAParticle { logvisor::Module LogModule("urde::DNAParticle"); +template struct PEImpl<_RealElementFactory>; +template struct PEImpl<_IntElementFactory>; +template struct PEImpl<_VectorElementFactory>; +template struct PEImpl<_ColorElementFactory>; +template struct PEImpl<_ModVectorElementFactory>; +template struct PEImpl<_EmitterElementFactory>; +template struct PEImpl<_UVElementFactory>; +template struct PEImpl<_UVElementFactory>; + +AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_RealElementFactory>) +AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_IntElementFactory>) +AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_VectorElementFactory>) +AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_ColorElementFactory>) +AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_ModVectorElementFactory>) +AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_EmitterElementFactory>) +AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_UVElementFactory>) +AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_UVElementFactory>) + template <> void REConstant::Enumerate(typename ReadYaml::StreamT& r) { val = r.readFloat(); @@ -148,908 +166,6 @@ void MVEConstant::Enumerate(typename Write::StreamT& w) { comps[2].write(w); } -template <> -void RealElementFactory::Enumerate(typename ReadYaml::StreamT& r) { - const auto& mapChildren = r.getCurNode()->m_mapChildren; - if (mapChildren.empty()) { - m_elem.reset(); - return; - } - - const auto& elem = mapChildren[0]; - if (elem.first.size() < 4) - LogModule.report(logvisor::Fatal, fmt("short FourCC in element '{}'"), elem.first); - - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('LFTW'): - m_elem.reset(new struct RELifetimeTween); - break; - case SBIG('CNST'): - m_elem.reset(new struct REConstant); - break; - case SBIG('CHAN'): - m_elem.reset(new struct RETimeChain); - break; - case SBIG('ADD_'): - m_elem.reset(new struct REAdd); - break; - case SBIG('CLMP'): - m_elem.reset(new struct REClamp); - break; - case SBIG('KEYE'): - case SBIG('KEYP'): - m_elem.reset(new struct REKeyframeEmitter); - break; - case SBIG('IRND'): - m_elem.reset(new struct REInitialRandom); - break; - case SBIG('RAND'): - m_elem.reset(new struct RERandom); - break; - case SBIG('MULT'): - m_elem.reset(new struct REMultiply); - break; - case SBIG('PULS'): - m_elem.reset(new struct REPulse); - break; - case SBIG('SCAL'): - m_elem.reset(new struct RETimeScale); - break; - case SBIG('RLPT'): - m_elem.reset(new struct RELifetimePercent); - break; - case SBIG('SINE'): - m_elem.reset(new struct RESineWave); - break; - case SBIG('ISWT'): - m_elem.reset(new struct REInitialSwitch); - break; - case SBIG('CLTN'): - m_elem.reset(new struct RECompareLessThan); - break; - case SBIG('CEQL'): - m_elem.reset(new struct RECompareEquals); - break; - case SBIG('PAP1'): - m_elem.reset(new struct REParticleAdvanceParam1); - break; - case SBIG('PAP2'): - m_elem.reset(new struct REParticleAdvanceParam2); - break; - case SBIG('PAP3'): - m_elem.reset(new struct REParticleAdvanceParam3); - break; - case SBIG('PAP4'): - m_elem.reset(new struct REParticleAdvanceParam4); - break; - case SBIG('PAP5'): - m_elem.reset(new struct REParticleAdvanceParam5); - break; - case SBIG('PAP6'): - m_elem.reset(new struct REParticleAdvanceParam6); - break; - case SBIG('PAP7'): - m_elem.reset(new struct REParticleAdvanceParam7); - break; - case SBIG('PAP8'): - m_elem.reset(new struct REParticleAdvanceParam8); - break; - case SBIG('PSLL'): - m_elem.reset(new struct REParticleSizeOrLineLength); - break; - case SBIG('PRLW'): - m_elem.reset(new struct REParticleRotationOrLineWidth); - break; - case SBIG('SUB_'): - m_elem.reset(new struct RESubtract); - break; - case SBIG('VMAG'): - m_elem.reset(new struct REVectorMagnitude); - break; - case SBIG('VXTR'): - m_elem.reset(new struct REVectorXToReal); - break; - case SBIG('VYTR'): - m_elem.reset(new struct REVectorYToReal); - break; - case SBIG('VZTR'): - m_elem.reset(new struct REVectorZToReal); - break; - case SBIG('CEXT'): - m_elem.reset(new struct RECEXT); - break; - case SBIG('ITRL'): - m_elem.reset(new struct REIntTimesReal); - break; - default: - m_elem.reset(); - return; - } - if (auto rec = r.enterSubRecord(elem.first.c_str())) - m_elem->read(r); -} - -template <> -void RealElementFactory::Enumerate(typename WriteYaml::StreamT& w) { - if (m_elem) - if (auto rec = w.enterSubRecord(m_elem->ClassID())) - m_elem->write(w); -} - -template <> -void RealElementFactory::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - if (m_elem) - m_elem->binarySize(s); -} - -template <> -void RealElementFactory::Enumerate(typename Read::StreamT& r) { - DNAFourCC clsId; - clsId.read(r); - switch (clsId.toUint32()) { - case SBIG('LFTW'): - m_elem.reset(new struct RELifetimeTween); - break; - case SBIG('CNST'): - m_elem.reset(new struct REConstant); - break; - case SBIG('CHAN'): - m_elem.reset(new struct RETimeChain); - break; - case SBIG('ADD_'): - m_elem.reset(new struct REAdd); - break; - case SBIG('CLMP'): - m_elem.reset(new struct REClamp); - break; - case SBIG('KEYE'): - case SBIG('KEYP'): - m_elem.reset(new struct REKeyframeEmitter); - break; - case SBIG('IRND'): - m_elem.reset(new struct REInitialRandom); - break; - case SBIG('RAND'): - m_elem.reset(new struct RERandom); - break; - case SBIG('MULT'): - m_elem.reset(new struct REMultiply); - break; - case SBIG('PULS'): - m_elem.reset(new struct REPulse); - break; - case SBIG('SCAL'): - m_elem.reset(new struct RETimeScale); - break; - case SBIG('RLPT'): - m_elem.reset(new struct RELifetimePercent); - break; - case SBIG('SINE'): - m_elem.reset(new struct RESineWave); - break; - case SBIG('ISWT'): - m_elem.reset(new struct REInitialSwitch); - break; - case SBIG('CLTN'): - m_elem.reset(new struct RECompareLessThan); - break; - case SBIG('CEQL'): - m_elem.reset(new struct RECompareEquals); - break; - case SBIG('PAP1'): - m_elem.reset(new struct REParticleAdvanceParam1); - break; - case SBIG('PAP2'): - m_elem.reset(new struct REParticleAdvanceParam2); - break; - case SBIG('PAP3'): - m_elem.reset(new struct REParticleAdvanceParam3); - break; - case SBIG('PAP4'): - m_elem.reset(new struct REParticleAdvanceParam4); - break; - case SBIG('PAP5'): - m_elem.reset(new struct REParticleAdvanceParam5); - break; - case SBIG('PAP6'): - m_elem.reset(new struct REParticleAdvanceParam6); - break; - case SBIG('PAP7'): - m_elem.reset(new struct REParticleAdvanceParam7); - break; - case SBIG('PAP8'): - m_elem.reset(new struct REParticleAdvanceParam8); - break; - case SBIG('PSLL'): - m_elem.reset(new struct REParticleSizeOrLineLength); - break; - case SBIG('PRLW'): - m_elem.reset(new struct REParticleRotationOrLineWidth); - break; - case SBIG('SUB_'): - m_elem.reset(new struct RESubtract); - break; - case SBIG('VMAG'): - m_elem.reset(new struct REVectorMagnitude); - break; - case SBIG('VXTR'): - m_elem.reset(new struct REVectorXToReal); - break; - case SBIG('VYTR'): - m_elem.reset(new struct REVectorYToReal); - break; - case SBIG('VZTR'): - m_elem.reset(new struct REVectorZToReal); - break; - case SBIG('CEXT'): - m_elem.reset(new struct RECEXT); - break; - case SBIG('ITRL'): - m_elem.reset(new struct REIntTimesReal); - break; - case SBIG('NONE'): - m_elem.reset(); - return; - default: - m_elem.reset(); - LogModule.report(logvisor::Fatal, fmt("Unknown RealElement class {} @{}"), clsId, r.position()); - return; - } - m_elem->read(r); -} - -template <> -void RealElementFactory::Enumerate(typename Write::StreamT& w) { - if (m_elem) { - w.writeBytes((atInt8*)m_elem->ClassID().data(), 4); - m_elem->write(w); - } else - w.writeBytes((atInt8*)"NONE", 4); -} - -template <> -void IntElementFactory::Enumerate(typename ReadYaml::StreamT& r) { - const auto& mapChildren = r.getCurNode()->m_mapChildren; - if (mapChildren.empty()) { - m_elem.reset(); - return; - } - - const auto& elem = mapChildren[0]; - if (elem.first.size() < 4) - LogModule.report(logvisor::Fatal, fmt("short FourCC in element '{}'"), elem.first); - - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('KEYE'): - case SBIG('KEYP'): - m_elem.reset(new struct IEKeyframeEmitter); - break; - case SBIG('DETH'): - m_elem.reset(new struct IEDeath); - break; - case SBIG('CLMP'): - m_elem.reset(new struct IEClamp); - break; - case SBIG('CHAN'): - m_elem.reset(new struct IETimeChain); - break; - case SBIG('ADD_'): - m_elem.reset(new struct IEAdd); - break; - case SBIG('CNST'): - m_elem.reset(new struct IEConstant); - break; - case SBIG('IMPL'): - m_elem.reset(new struct IEImpulse); - break; - case SBIG('ILPT'): - m_elem.reset(new struct IELifetimePercent); - break; - case SBIG('IRND'): - m_elem.reset(new struct IEInitialRandom); - break; - case SBIG('PULS'): - m_elem.reset(new struct IEPulse); - break; - case SBIG('MULT'): - m_elem.reset(new struct IEMultiply); - break; - case SBIG('SPAH'): - m_elem.reset(new struct IESampleAndHold); - break; - case SBIG('RAND'): - m_elem.reset(new struct IERandom); - break; - case SBIG('TSCL'): - m_elem.reset(new struct IETimeScale); - break; - case SBIG('GTCP'): - m_elem.reset(new struct IEGTCP); - break; - case SBIG('MODU'): - m_elem.reset(new struct IEModulo); - break; - case SBIG('SUB_'): - m_elem.reset(new struct IESubtract); - break; - default: - m_elem.reset(); - return; - } - if (auto rec = r.enterSubRecord(elem.first.c_str())) - m_elem->read(r); -} - -template <> -void IntElementFactory::Enumerate(typename WriteYaml::StreamT& w) { - if (m_elem) - if (auto rec = w.enterSubRecord(m_elem->ClassID())) - m_elem->write(w); -} - -template <> -void IntElementFactory::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - if (m_elem) - m_elem->binarySize(s); -} - -template <> -void IntElementFactory::Enumerate(typename Read::StreamT& r) { - DNAFourCC clsId; - clsId.read(r); - switch (clsId.toUint32()) { - case SBIG('KEYE'): - case SBIG('KEYP'): - m_elem.reset(new struct IEKeyframeEmitter); - break; - case SBIG('DETH'): - m_elem.reset(new struct IEDeath); - break; - case SBIG('CLMP'): - m_elem.reset(new struct IEClamp); - break; - case SBIG('CHAN'): - m_elem.reset(new struct IETimeChain); - break; - case SBIG('ADD_'): - m_elem.reset(new struct IEAdd); - break; - case SBIG('CNST'): - m_elem.reset(new struct IEConstant); - break; - case SBIG('IMPL'): - m_elem.reset(new struct IEImpulse); - break; - case SBIG('ILPT'): - m_elem.reset(new struct IELifetimePercent); - break; - case SBIG('IRND'): - m_elem.reset(new struct IEInitialRandom); - break; - case SBIG('PULS'): - m_elem.reset(new struct IEPulse); - break; - case SBIG('MULT'): - m_elem.reset(new struct IEMultiply); - break; - case SBIG('SPAH'): - m_elem.reset(new struct IESampleAndHold); - break; - case SBIG('RAND'): - m_elem.reset(new struct IERandom); - break; - case SBIG('TSCL'): - m_elem.reset(new struct IETimeScale); - break; - case SBIG('GTCP'): - m_elem.reset(new struct IEGTCP); - break; - case SBIG('MODU'): - m_elem.reset(new struct IEModulo); - break; - case SBIG('SUB_'): - m_elem.reset(new struct IESubtract); - break; - case SBIG('NONE'): - m_elem.reset(); - return; - default: - m_elem.reset(); - LogModule.report(logvisor::Fatal, fmt("Unknown IntElement class {} @{}"), clsId, r.position()); - return; - } - m_elem->read(r); -} - -template <> -void IntElementFactory::Enumerate(typename Write::StreamT& w) { - if (m_elem) { - w.writeBytes((atInt8*)m_elem->ClassID().data(), 4); - m_elem->write(w); - } else - w.writeBytes((atInt8*)"NONE", 4); -} - -template <> -void VectorElementFactory::Enumerate(typename ReadYaml::StreamT& r) { - const auto& mapChildren = r.getCurNode()->m_mapChildren; - if (mapChildren.empty()) { - m_elem.reset(); - return; - } - - const auto& elem = mapChildren[0]; - if (elem.first.size() < 4) - LogModule.report(logvisor::Fatal, fmt("short FourCC in element '{}'"), elem.first); - - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('CONE'): - m_elem.reset(new struct VECone); - break; - case SBIG('CHAN'): - m_elem.reset(new struct VETimeChain); - break; - case SBIG('ANGC'): - m_elem.reset(new struct VEAngleCone); - break; - case SBIG('ADD_'): - m_elem.reset(new struct VEAdd); - break; - case SBIG('CCLU'): - m_elem.reset(new struct VECircleCluster); - break; - case SBIG('CNST'): - m_elem.reset(new struct VEConstant); - break; - case SBIG('CIRC'): - m_elem.reset(new struct VECircle); - break; - case SBIG('KEYE'): - case SBIG('KEYP'): - m_elem.reset(new struct VEKeyframeEmitter); - break; - case SBIG('MULT'): - m_elem.reset(new struct VEMultiply); - break; - case SBIG('RTOV'): - m_elem.reset(new struct VERealToVector); - break; - case SBIG('PULS'): - m_elem.reset(new struct VEPulse); - break; - case SBIG('PVEL'): - m_elem.reset(new struct VEParticleVelocity); - break; - case SBIG('SPOS'): - m_elem.reset(new struct VESPOS); - break; - case SBIG('PLCO'): - m_elem.reset(new struct VEPLCO); - break; - case SBIG('PLOC'): - m_elem.reset(new struct VEPLOC); - break; - case SBIG('PSOR'): - m_elem.reset(new struct VEPSOR); - break; - case SBIG('PSOF'): - m_elem.reset(new struct VEPSOF); - break; - default: - m_elem.reset(); - return; - } - if (auto rec = r.enterSubRecord(elem.first.c_str())) - m_elem->read(r); -} - -template <> -void VectorElementFactory::Enumerate(typename WriteYaml::StreamT& w) { - if (m_elem) - if (auto rec = w.enterSubRecord(m_elem->ClassID())) - m_elem->write(w); -} - -template <> -void VectorElementFactory::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - if (m_elem) - m_elem->binarySize(s); -} - -template <> -void VectorElementFactory::Enumerate(typename Read::StreamT& r) { - DNAFourCC clsId; - clsId.read(r); - switch (clsId.toUint32()) { - case SBIG('CONE'): - m_elem.reset(new struct VECone); - break; - case SBIG('CHAN'): - m_elem.reset(new struct VETimeChain); - break; - case SBIG('ANGC'): - m_elem.reset(new struct VEAngleCone); - break; - case SBIG('ADD_'): - m_elem.reset(new struct VEAdd); - break; - case SBIG('CCLU'): - m_elem.reset(new struct VECircleCluster); - break; - case SBIG('CNST'): - m_elem.reset(new struct VEConstant); - break; - case SBIG('CIRC'): - m_elem.reset(new struct VECircle); - break; - case SBIG('KEYE'): - case SBIG('KEYP'): - m_elem.reset(new struct VEKeyframeEmitter); - break; - case SBIG('MULT'): - m_elem.reset(new struct VEMultiply); - break; - case SBIG('RTOV'): - m_elem.reset(new struct VERealToVector); - break; - case SBIG('PULS'): - m_elem.reset(new struct VEPulse); - break; - case SBIG('PVEL'): - m_elem.reset(new struct VEParticleVelocity); - break; - case SBIG('SPOS'): - m_elem.reset(new struct VESPOS); - break; - case SBIG('PLCO'): - m_elem.reset(new struct VEPLCO); - break; - case SBIG('PLOC'): - m_elem.reset(new struct VEPLOC); - break; - case SBIG('PSOR'): - m_elem.reset(new struct VEPSOR); - break; - case SBIG('PSOF'): - m_elem.reset(new struct VEPSOF); - break; - case SBIG('NONE'): - m_elem.reset(); - return; - default: - m_elem.reset(); - LogModule.report(logvisor::Fatal, fmt("Unknown VectorElement class {} @{}"), clsId, r.position()); - return; - } - m_elem->read(r); -} - -template <> -void VectorElementFactory::Enumerate(typename Write::StreamT& w) { - if (m_elem) { - w.writeBytes((atInt8*)m_elem->ClassID().data(), 4); - m_elem->write(w); - } else - w.writeBytes((atInt8*)"NONE", 4); -} - -template <> -void ColorElementFactory::Enumerate(typename ReadYaml::StreamT& r) { - const auto& mapChildren = r.getCurNode()->m_mapChildren; - if (mapChildren.empty()) { - m_elem.reset(); - return; - } - - const auto& elem = mapChildren[0]; - if (elem.first.size() < 4) - LogModule.report(logvisor::Fatal, fmt("short FourCC in element '{}'"), elem.first); - - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('KEYE'): - case SBIG('KEYP'): - m_elem.reset(new struct CEKeyframeEmitter); - break; - case SBIG('CNST'): - m_elem.reset(new struct CEConstant); - break; - case SBIG('CHAN'): - m_elem.reset(new struct CETimeChain); - break; - case SBIG('CFDE'): - m_elem.reset(new struct CEFadeEnd); - break; - case SBIG('FADE'): - m_elem.reset(new struct CEFade); - break; - case SBIG('PULS'): - m_elem.reset(new struct CEPulse); - break; - default: - m_elem.reset(); - return; - } - if (auto rec = r.enterSubRecord(elem.first.c_str())) - m_elem->read(r); -} - -template <> -void ColorElementFactory::Enumerate(typename WriteYaml::StreamT& w) { - if (m_elem) - if (auto rec = w.enterSubRecord(m_elem->ClassID())) - m_elem->write(w); -} - -template <> -void ColorElementFactory::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - if (m_elem) - m_elem->binarySize(s); -} - -template <> -void ColorElementFactory::Enumerate(typename Read::StreamT& r) { - DNAFourCC clsId; - clsId.read(r); - switch (clsId.toUint32()) { - case SBIG('KEYE'): - case SBIG('KEYP'): - m_elem.reset(new struct CEKeyframeEmitter); - break; - case SBIG('CNST'): - m_elem.reset(new struct CEConstant); - break; - case SBIG('CHAN'): - m_elem.reset(new struct CETimeChain); - break; - case SBIG('CFDE'): - m_elem.reset(new struct CEFadeEnd); - break; - case SBIG('FADE'): - m_elem.reset(new struct CEFade); - break; - case SBIG('PULS'): - m_elem.reset(new struct CEPulse); - break; - case SBIG('NONE'): - m_elem.reset(); - return; - default: - m_elem.reset(); - LogModule.report(logvisor::Fatal, fmt("Unknown ColorElement class {} @{}"), clsId, r.position()); - return; - } - m_elem->read(r); -} - -template <> -void ColorElementFactory::Enumerate(typename Write::StreamT& w) { - if (m_elem) { - w.writeBytes((atInt8*)m_elem->ClassID().data(), 4); - m_elem->write(w); - } else - w.writeBytes((atInt8*)"NONE", 4); -} - -template <> -void ModVectorElementFactory::Enumerate(typename ReadYaml::StreamT& r) { - const auto& mapChildren = r.getCurNode()->m_mapChildren; - if (mapChildren.empty()) { - m_elem.reset(); - return; - } - - const auto& elem = mapChildren[0]; - if (elem.first.size() < 4) - LogModule.report(logvisor::Fatal, fmt("short FourCC in element '{}'"), elem.first); - - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('IMPL'): - m_elem.reset(new struct MVEImplosion); - break; - case SBIG('EMPL'): - m_elem.reset(new struct MVEExponentialImplosion); - break; - case SBIG('CHAN'): - m_elem.reset(new struct MVETimeChain); - break; - case SBIG('BNCE'): - m_elem.reset(new struct MVEBounce); - break; - case SBIG('CNST'): - m_elem.reset(new struct MVEConstant); - break; - case SBIG('GRAV'): - m_elem.reset(new struct MVEGravity); - break; - case SBIG('EXPL'): - m_elem.reset(new struct MVEExplode); - break; - case SBIG('SPOS'): - m_elem.reset(new struct MVESetPosition); - break; - case SBIG('LMPL'): - m_elem.reset(new struct MVELinearImplosion); - break; - case SBIG('PULS'): - m_elem.reset(new struct MVEPulse); - break; - case SBIG('WIND'): - m_elem.reset(new struct MVEWind); - break; - case SBIG('SWRL'): - m_elem.reset(new struct MVESwirl); - break; - default: - m_elem.reset(); - return; - } - if (auto rec = r.enterSubRecord(elem.first.c_str())) - m_elem->read(r); -} - -template <> -void ModVectorElementFactory::Enumerate(typename WriteYaml::StreamT& w) { - if (m_elem) - if (auto rec = w.enterSubRecord(m_elem->ClassID())) - m_elem->write(w); -} - -template <> -void ModVectorElementFactory::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - if (m_elem) - m_elem->binarySize(s); -} - -template <> -void ModVectorElementFactory::Enumerate(typename Read::StreamT& r) { - DNAFourCC clsId; - clsId.read(r); - switch (clsId.toUint32()) { - case SBIG('IMPL'): - m_elem.reset(new struct MVEImplosion); - break; - case SBIG('EMPL'): - m_elem.reset(new struct MVEExponentialImplosion); - break; - case SBIG('CHAN'): - m_elem.reset(new struct MVETimeChain); - break; - case SBIG('BNCE'): - m_elem.reset(new struct MVEBounce); - break; - case SBIG('CNST'): - m_elem.reset(new struct MVEConstant); - break; - case SBIG('GRAV'): - m_elem.reset(new struct MVEGravity); - break; - case SBIG('EXPL'): - m_elem.reset(new struct MVEExplode); - break; - case SBIG('SPOS'): - m_elem.reset(new struct MVESetPosition); - break; - case SBIG('LMPL'): - m_elem.reset(new struct MVELinearImplosion); - break; - case SBIG('PULS'): - m_elem.reset(new struct MVEPulse); - break; - case SBIG('WIND'): - m_elem.reset(new struct MVEWind); - break; - case SBIG('SWRL'): - m_elem.reset(new struct MVESwirl); - break; - case SBIG('NONE'): - m_elem.reset(); - return; - default: - m_elem.reset(); - LogModule.report(logvisor::Fatal, fmt("Unknown ModVectorElement class {} @{}"), clsId, r.position()); - return; - } - m_elem->read(r); -} - -template <> -void ModVectorElementFactory::Enumerate(typename Write::StreamT& w) { - if (m_elem) { - w.writeBytes((atInt8*)m_elem->ClassID().data(), 4); - m_elem->write(w); - } else - w.writeBytes((atInt8*)"NONE", 4); -} - -template <> -void EmitterElementFactory::Enumerate(typename ReadYaml::StreamT& r) { - const auto& mapChildren = r.getCurNode()->m_mapChildren; - if (mapChildren.empty()) { - m_elem.reset(); - return; - } - - const auto& elem = mapChildren[0]; - if (elem.first.size() < 4) - LogModule.report(logvisor::Fatal, fmt("short FourCC in element '{}'"), elem.first); - - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('SETR'): - m_elem.reset(new struct EESimpleEmitterTR); - break; - case SBIG('SEMR'): - m_elem.reset(new struct EESimpleEmitter); - break; - case SBIG('SPHE'): - m_elem.reset(new struct VESphere); - break; - case SBIG('ASPH'): - m_elem.reset(new struct VEAngleSphere); - break; - default: - m_elem.reset(); - return; - } - if (auto rec = r.enterSubRecord(elem.first.c_str())) - m_elem->read(r); -} - -template <> -void EmitterElementFactory::Enumerate(typename WriteYaml::StreamT& w) { - if (m_elem) - if (auto rec = w.enterSubRecord(m_elem->ClassID())) - m_elem->write(w); -} - -template <> -void EmitterElementFactory::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - if (m_elem) - m_elem->binarySize(s); -} - -template <> -void EmitterElementFactory::Enumerate(typename Read::StreamT& r) { - DNAFourCC clsId; - clsId.read(r); - switch (clsId.toUint32()) { - case SBIG('SETR'): - m_elem.reset(new struct EESimpleEmitterTR); - break; - case SBIG('SEMR'): - m_elem.reset(new struct EESimpleEmitter); - break; - case SBIG('SPHE'): - m_elem.reset(new struct VESphere); - break; - case SBIG('ASPH'): - m_elem.reset(new struct VEAngleSphere); - break; - case SBIG('NONE'): - m_elem.reset(); - return; - default: - m_elem.reset(); - LogModule.report(logvisor::Fatal, fmt("Unknown EmitterElement class {} @{}"), clsId, r.position()); - return; - } - m_elem->read(r); -} - -template <> -void EmitterElementFactory::Enumerate(typename Write::StreamT& w) { - if (m_elem) { - w.writeBytes((atInt8*)m_elem->ClassID().data(), 4); - m_elem->write(w); - } else - w.writeBytes((atInt8*)"NONE", 4); -} - template <> void BoolHelper::Enumerate(typename ReadYaml::StreamT& r) { value = r.readBool(); @@ -1073,14 +189,20 @@ void BoolHelper::Enumerate(typename Read::StreamT& r) { } template <> void BoolHelper::Enumerate(typename Write::StreamT& w) { - w.writeBytes((atInt8*)"CNST", 4); + w.writeBytes("CNST", 4); w.writeBool(value); } +template struct ValueHelper; +template struct ValueHelper; + +AT_SUBSPECIALIZE_DNA_YAML(ValueHelper) +AT_SUBSPECIALIZE_DNA_YAML(ValueHelper) + template <> void EESimpleEmitterTR::Enumerate(typename ReadYaml::StreamT& r) { - position.m_elem.reset(); - velocity.m_elem.reset(); + position.reset(); + velocity.reset(); if (auto rec = r.enterSubRecord("ILOC")) position.read(r); if (auto rec = r.enterSubRecord("IVEC")) @@ -1101,8 +223,8 @@ void EESimpleEmitterTR::Enumerate(typename BinarySize::Strea } template <> void EESimpleEmitterTR::Enumerate(typename Read::StreamT& r) { - position.m_elem.reset(); - velocity.m_elem.reset(); + position.reset(); + velocity.reset(); uint32_t clsId; r.readBytesToBuf(&clsId, 4); if (clsId == SBIG('ILOC')) { @@ -1114,9 +236,9 @@ void EESimpleEmitterTR::Enumerate(typename Read::StreamT& r) { } template <> void EESimpleEmitterTR::Enumerate(typename Write::StreamT& w) { - w.writeBytes((atInt8*)"ILOC", 4); + w.writeBytes("ILOC", 4); position.write(w); - w.writeBytes((atInt8*)"IVEC", 4); + w.writeBytes("IVEC", 4); velocity.write(w); } @@ -1155,7 +277,7 @@ void UVEConstant::_read(typename Read::StreamT& r) { } template void UVEConstant::_write(typename Write::StreamT& w) const { - w.writeBytes((atInt8*)"CNST", 4); + w.writeBytes("CNST", 4); tex.write(w); } @@ -1236,14 +358,14 @@ void UVEAnimTexture::_read(typename Read::StreamT& r) { } template void UVEAnimTexture::_write(typename Write::StreamT& w) const { - w.writeBytes((atInt8*)"CNST", 4); + w.writeBytes("CNST", 4); tex.write(w); tileW.write(w); tileH.write(w); strideW.write(w); strideH.write(w); cycleFrames.write(w); - w.writeBytes((atInt8*)"CNST", 4); + w.writeBytes("CNST", 4); w.writeBool(loop); } @@ -1262,61 +384,6 @@ std::string_view UVElementFactory::DNAType() { return "UVElementFactory"sv; } -template -void UVElementFactory::_read(typename Read::StreamT& r) { - uint32_t clsId; - r.readBytesToBuf(&clsId, 4); - switch (clsId) { - case SBIG('CNST'): - m_elem.reset(new struct UVEConstant); - break; - case SBIG('ATEX'): - m_elem.reset(new struct UVEAnimTexture); - break; - default: - m_elem.reset(); - return; - } - m_elem->read(r); -} -template -void UVElementFactory::_write(typename Write::StreamT& w) const { - if (m_elem) { - w.writeBytes((atInt8*)m_elem->ClassID().data(), 4); - m_elem->write(w); - } else - w.writeBytes((atInt8*)"NONE", 4); -} -template -void UVElementFactory::_read(typename ReadYaml::StreamT& r) { - if (auto rec = r.enterSubRecord("CNST")) { - m_elem.reset(new struct UVEConstant); - m_elem->read(r); - } else if (auto rec = r.enterSubRecord("ATEX")) { - m_elem.reset(new struct UVEAnimTexture); - m_elem->read(r); - } else - m_elem.reset(); -} -template -void UVElementFactory::_write(typename WriteYaml::StreamT& w) const { - if (m_elem) - if (auto rec = w.enterSubRecord(m_elem->ClassID())) - m_elem->write(w); -} -template -void UVElementFactory::_binarySize(typename BinarySize::StreamT& _s) const { - if (m_elem) - m_elem->binarySize(_s); - _s += 4; -} - -AT_SUBSPECIALIZE_DNA_YAML(UVElementFactory) -AT_SUBSPECIALIZE_DNA_YAML(UVElementFactory) - -template struct UVElementFactory; -template struct UVElementFactory; - template <> std::string_view SpawnSystemKeyframeData::SpawnSystemKeyframeInfo::DNAType() { return "SpawnSystemKeyframeData::SpawnSystemKeyframeInfo"sv; @@ -1439,10 +506,10 @@ void SpawnSystemKeyframeData::_read(typename Read::StreamT& r) { template void SpawnSystemKeyframeData::_write(typename Write::StreamT& w) const { if (spawns.empty()) { - w.writeBytes((atInt8*)"NONE", 4); + w.writeBytes("NONE", 4); return; } - w.writeBytes((atInt8*)"CNST", 4); + w.writeBytes("CNST", 4); w.writeUint32Big(a); w.writeUint32Big(b); w.writeUint32Big(endFrame); @@ -1504,10 +571,10 @@ void ChildResourceFactory::_read(typename Read::StreamT& r) { template void ChildResourceFactory::_write(typename Write::StreamT& w) const { if (id.isValid()) { - w.writeBytes((atInt8*)"CNST", 4); + w.writeBytes("CNST", 4); id.write(w); } else - w.writeBytes((atInt8*)"NONE", 4); + w.writeBytes("NONE", 4); } AT_SUBSPECIALIZE_DNA_YAML(ChildResourceFactory) diff --git a/DataSpec/DNACommon/ParticleCommon.hpp b/DataSpec/DNACommon/ParticleCommon.hpp index 803a02f41..159cc85fd 100644 --- a/DataSpec/DNACommon/ParticleCommon.hpp +++ b/DataSpec/DNACommon/ParticleCommon.hpp @@ -10,6 +10,257 @@ namespace DataSpec::DNAParticle { extern logvisor::Module LogModule; +enum class ParticleType { + GPSM = SBIG('GPSM'), + SWSH = SBIG('SWSH'), + ELSM = SBIG('ELSM'), + DPSM = SBIG('DPSM'), + CRSM = SBIG('CRSM'), + WPSM = SBIG('WPSM') +}; + +/* + * The particle property (PP) metaclass system provides common compile-time utilities + * for storing, enumerating, and streaming particle scripts. + */ + +template +struct PPImpl : BigDNA, _Basis { + AT_DECL_EXPLICIT_DNA_YAML + + template + static constexpr bool _shouldStore(T& p, bool defaultBool) { + if constexpr (std::is_same_v) { + return p != defaultBool; + } else if constexpr (std::is_same_v) { + return p != 0xffffffff; + } else if constexpr (std::is_same_v) { + return true; + } else { + return p.operator bool(); + } + } + + constexpr void _read(athena::io::IStreamReader& r) { + constexpr FourCC RefType = uint32_t(_Basis::Type); + DNAFourCC clsId(r); + if (clsId != RefType) { + LogModule.report(logvisor::Warning, fmt("non {} provided to {} parser"), RefType, RefType); + return; + } + clsId.read(r); + while (clsId != SBIG('_END')) { + if (!_Basis::Lookup(clsId, [&](auto& p) { + using Tp = std::decay_t; + if constexpr (std::is_same_v) { + DNAFourCC tp(r); + if (tp == SBIG('CNST')) + p = r.readBool(); + } else if constexpr (std::is_same_v) { + DNAFourCC tp(r); + if (tp == SBIG('CNST')) + p = r.readUint32Big(); + } else if constexpr (std::is_same_v) { + DNAFourCC tp(r); + if (tp == SBIG('CNST')) + p = r.readFloatBig(); + } else { + p.read(r); + } + })) { + LogModule.report(logvisor::Fatal, fmt("Unknown {} class {} @{}"), RefType, clsId, r.position()); + } + clsId.read(r); + } + } + + constexpr void _write(athena::io::IStreamWriter& w) { + constexpr DNAFourCC RefType = uint32_t(_Basis::Type); + RefType.write(w); + _Basis::Enumerate([&](FourCC fcc, auto& p, bool defaultBool = false) { + if (_shouldStore(p, defaultBool)) { + using Tp = std::decay_t; + DNAFourCC(fcc).write(w); + if constexpr (std::is_same_v) { + w.writeBytes("CNST", 4); + w.writeBool(p); + } else if constexpr (std::is_same_v) { + w.writeBytes("CNST", 4); + w.writeUint32Big(p); + } else if constexpr (std::is_same_v) { + w.writeBytes("CNST", 4); + w.writeFloatBig(p); + } else { + p.write(w); + } + } + }); + w.writeBytes("_END", 4); + } + + constexpr void _binarySize(std::size_t& s) { + constexpr DNAFourCC RefType = uint32_t(_Basis::Type); + RefType.binarySize(s); + _Basis::Enumerate([&](FourCC fcc, auto& p, bool defaultBool = false) { + if (_shouldStore(p, defaultBool)) { + using Tp = std::decay_t; + DNAFourCC(fcc).binarySize(s); + if constexpr (std::is_same_v) { + s += 5; + } else if constexpr (std::is_same_v || std::is_same_v) { + s += 8; + } else { + p.binarySize(s); + } + } + }); + s += 4; + } + + void _read(athena::io::YAMLDocReader& r) { + constexpr DNAFourCC RefType = uint32_t(_Basis::Type); + + for (const auto& [key, value] : r.getCurNode()->m_mapChildren) { + if (key == "DNAType"sv) + continue; + if (key.size() < 4) { + LogModule.report(logvisor::Warning, fmt("short FourCC in element '{}'"), key); + continue; + } + + if (auto rec = r.enterSubRecord(key)) { + const DNAFourCC clsId = key.c_str(); + if (!_Basis::Lookup(clsId, [&](auto& p) { + using Tp = std::decay_t; + if constexpr (std::is_same_v) { + p = r.readBool(); + } else if constexpr (std::is_same_v) { + p = r.readUint32(); + } else if constexpr (std::is_same_v) { + p = r.readFloat(); + } else { + p.read(r); + } + })) { + LogModule.report(logvisor::Fatal, fmt("Unknown {} class {}"), RefType, clsId); + } + } + } + } + + constexpr void _write(athena::io::YAMLDocWriter& w) { + _Basis::Enumerate([&](FourCC fcc, auto& p, bool defaultBool = false) { + if (_shouldStore(p, defaultBool)) { + using Tp = std::decay_t; + if (auto rec = w.enterSubRecord(fcc.toStringView())) { + if constexpr (std::is_same_v) { + w.writeBool(p); + } else if constexpr (std::is_same_v) { + w.writeUint32(p); + } else if constexpr (std::is_same_v) { + w.writeFloat(p); + } else { + p.write(w); + } + } + } + }); + } + + constexpr void gatherDependencies(std::vector& deps) { + _Basis::Enumerate([&](FourCC fcc, auto& p, bool defaultBool = false) { + using Tp = std::decay_t; + if constexpr (!std::is_same_v && !std::is_same_v && !std::is_same_v) + p.gatherDependencies(deps); + }); + } + + constexpr void gatherDependencies(std::vector& deps) const { + const_cast(*this).gatherDependencies(deps); + } +}; + +template +struct PEType { + using Type = _Type; +}; + +template +struct PEImpl : BigDNA { + AT_DECL_EXPLICIT_DNA_YAML + using _PtrType = typename _Basis::PtrType; + + void _read(athena::io::IStreamReader& r) { + DNAFourCC clsId(r); + if (clsId == FOURCC('NONE')) { + m_elem.reset(); + return; + } + if (!_Basis::Lookup(clsId, [&](auto&& p) { + using Tp = std::decay_t; + m_elem = std::make_unique(); + m_elem->read(r); + })) { + LogModule.report(logvisor::Fatal, fmt("Unknown {} class {} @{}"), _PtrType::TypeName, clsId, r.position()); + } + } + + void _write(athena::io::IStreamWriter& w) { + if (m_elem) { + w.writeBytes(m_elem->ClassID().data(), 4); + m_elem->write(w); + } else { + w.writeBytes("NONE", 4); + } + } + + void _binarySize(std::size_t& s) { + if (m_elem) + m_elem->binarySize(s); + s += 4; + } + + void _read(athena::io::YAMLDocReader& r) { + const auto& mapChildren = r.getCurNode()->m_mapChildren; + if (mapChildren.empty()) { + m_elem.reset(); + return; + } + + const auto& [key, value] = mapChildren[0]; + if (key.size() < 4) + LogModule.report(logvisor::Fatal, fmt("short FourCC in element '{}'"), key); + + if (auto rec = r.enterSubRecord(key)) { + const DNAFourCC clsId = key.c_str(); + if (!_Basis::Lookup(clsId, [&](auto&& p) { + using Tp = std::decay_t; + m_elem = std::make_unique(); + m_elem->read(r); + })) { + LogModule.report(logvisor::Fatal, fmt("Unknown {} class {}"), _PtrType::TypeName, clsId); + } + } + } + + void _write(athena::io::YAMLDocWriter& w) { + if (m_elem) + if (auto rec = w.enterSubRecord(m_elem->ClassID())) + m_elem->write(w); + } + + void gatherDependencies(std::vector& deps) const { + _Basis::gatherDependencies(deps, m_elem); + } + + operator bool() const { return m_elem.operator bool(); } + auto* get() const { return m_elem.get(); } + auto* operator->() const { return get(); } + void reset() { m_elem.reset(); } +private: + std::unique_ptr<_PtrType> m_elem; +}; + struct IElement : BigDNAVYaml { Delete _d; ~IElement() override = default; @@ -19,61 +270,296 @@ struct IElement : BigDNAVYaml { struct IRealElement : IElement { Delete _d2; + static constexpr std::string_view TypeName = "RealElement"sv; }; -struct RealElementFactory : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - std::unique_ptr m_elem; - operator bool() const { return m_elem.operator bool(); } +struct RELifetimeTween; +struct REConstant; +struct RETimeChain; +struct REAdd; +struct REClamp; +struct REKeyframeEmitter; +struct REKeyframeEmitter; +struct REInitialRandom; +struct RERandom; +struct REMultiply; +struct REPulse; +struct RETimeScale; +struct RELifetimePercent; +struct RESineWave; +struct REInitialSwitch; +struct RECompareLessThan; +struct RECompareEquals; +struct REParticleAdvanceParam1; +struct REParticleAdvanceParam2; +struct REParticleAdvanceParam3; +struct REParticleAdvanceParam4; +struct REParticleAdvanceParam5; +struct REParticleAdvanceParam6; +struct REParticleAdvanceParam7; +struct REParticleAdvanceParam8; +struct REParticleSizeOrLineLength; +struct REParticleRotationOrLineWidth; +struct RESubtract; +struct REVectorMagnitude; +struct REVectorXToReal; +struct REVectorYToReal; +struct REVectorZToReal; +struct RECEXT; +struct REIntTimesReal; +struct _RealElementFactory { + using PtrType = IRealElement; + template + static bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { + case SBIG('LFTW'): f(PEType{}); return true; + case SBIG('CNST'): f(PEType{}); return true; + case SBIG('CHAN'): f(PEType{}); return true; + case SBIG('ADD_'): f(PEType{}); return true; + case SBIG('CLMP'): f(PEType{}); return true; + case SBIG('KEYE'): f(PEType{}); return true; + case SBIG('KEYP'): f(PEType{}); return true; + case SBIG('IRND'): f(PEType{}); return true; + case SBIG('RAND'): f(PEType{}); return true; + case SBIG('MULT'): f(PEType{}); return true; + case SBIG('PULS'): f(PEType{}); return true; + case SBIG('SCAL'): f(PEType{}); return true; + case SBIG('RLPT'): f(PEType{}); return true; + case SBIG('SINE'): f(PEType{}); return true; + case SBIG('ISWT'): f(PEType{}); return true; + case SBIG('CLTN'): f(PEType{}); return true; + case SBIG('CEQL'): f(PEType{}); return true; + case SBIG('PAP1'): f(PEType{}); return true; + case SBIG('PAP2'): f(PEType{}); return true; + case SBIG('PAP3'): f(PEType{}); return true; + case SBIG('PAP4'): f(PEType{}); return true; + case SBIG('PAP5'): f(PEType{}); return true; + case SBIG('PAP6'): f(PEType{}); return true; + case SBIG('PAP7'): f(PEType{}); return true; + case SBIG('PAP8'): f(PEType{}); return true; + case SBIG('PSLL'): f(PEType{}); return true; + case SBIG('PRLW'): f(PEType{}); return true; + case SBIG('SUB_'): f(PEType{}); return true; + case SBIG('VMAG'): f(PEType{}); return true; + case SBIG('VXTR'): f(PEType{}); return true; + case SBIG('VYTR'): f(PEType{}); return true; + case SBIG('VZTR'): f(PEType{}); return true; + case SBIG('CEXT'): f(PEType{}); return true; + case SBIG('ITRL'): f(PEType{}); return true; + default: return false; + } + } + static constexpr void gatherDependencies(std::vector& pathsOut, + const std::unique_ptr& elemPtr) {} }; +using RealElementFactory = PEImpl<_RealElementFactory>; struct IIntElement : IElement { Delete _d2; + static constexpr std::string_view TypeName = "IntElement"sv; }; -struct IntElementFactory : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - std::unique_ptr m_elem; - operator bool() const { return m_elem.operator bool(); } +struct IEKeyframeEmitter; +struct IEKeyframeEmitter; +struct IEDeath; +struct IEClamp; +struct IETimeChain; +struct IEAdd; +struct IEConstant; +struct IEImpulse; +struct IELifetimePercent; +struct IEInitialRandom; +struct IEPulse; +struct IEMultiply; +struct IESampleAndHold; +struct IERandom; +struct IETimeScale; +struct IEGTCP; +struct IEModulo; +struct IESubtract; +struct _IntElementFactory { + using PtrType = IIntElement; + template + static bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { + case SBIG('KEYE'): f(PEType{}); return true; + case SBIG('KEYP'): f(PEType{}); return true; + case SBIG('DETH'): f(PEType{}); return true; + case SBIG('CLMP'): f(PEType{}); return true; + case SBIG('CHAN'): f(PEType{}); return true; + case SBIG('ADD_'): f(PEType{}); return true; + case SBIG('CNST'): f(PEType{}); return true; + case SBIG('IMPL'): f(PEType{}); return true; + case SBIG('ILPT'): f(PEType{}); return true; + case SBIG('IRND'): f(PEType{}); return true; + case SBIG('PULS'): f(PEType{}); return true; + case SBIG('MULT'): f(PEType{}); return true; + case SBIG('SPAH'): f(PEType{}); return true; + case SBIG('RAND'): f(PEType{}); return true; + case SBIG('TSCL'): f(PEType{}); return true; + case SBIG('GTCP'): f(PEType{}); return true; + case SBIG('MODU'): f(PEType{}); return true; + case SBIG('SUB_'): f(PEType{}); return true; + default: return false; + } + } + static constexpr void gatherDependencies(std::vector& pathsOut, + const std::unique_ptr& elemPtr) {} }; +using IntElementFactory = PEImpl<_IntElementFactory>; struct IVectorElement : IElement { Delete _d2; + static constexpr std::string_view TypeName = "VectorElement"sv; }; -struct VectorElementFactory : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - std::unique_ptr m_elem; - operator bool() const { return m_elem.operator bool(); } +struct VECone; +struct VETimeChain; +struct VEAngleCone; +struct VEAdd; +struct VECircleCluster; +struct VEConstant; +struct VECircle; +struct VEKeyframeEmitter; +struct VEKeyframeEmitter; +struct VEMultiply; +struct VERealToVector; +struct VEPulse; +struct VEParticleVelocity; +struct VESPOS; +struct VEPLCO; +struct VEPLOC; +struct VEPSOR; +struct VEPSOF; +struct _VectorElementFactory { + using PtrType = IVectorElement; + template + static bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { + case SBIG('CONE'): f(PEType{}); return true; + case SBIG('CHAN'): f(PEType{}); return true; + case SBIG('ANGC'): f(PEType{}); return true; + case SBIG('ADD_'): f(PEType{}); return true; + case SBIG('CCLU'): f(PEType{}); return true; + case SBIG('CNST'): f(PEType{}); return true; + case SBIG('CIRC'): f(PEType{}); return true; + case SBIG('KEYE'): f(PEType{}); return true; + case SBIG('KEYP'): f(PEType{}); return true; + case SBIG('MULT'): f(PEType{}); return true; + case SBIG('RTOV'): f(PEType{}); return true; + case SBIG('PULS'): f(PEType{}); return true; + case SBIG('PVEL'): f(PEType{}); return true; + case SBIG('SPOS'): f(PEType{}); return true; + case SBIG('PLCO'): f(PEType{}); return true; + case SBIG('PLOC'): f(PEType{}); return true; + case SBIG('PSOR'): f(PEType{}); return true; + case SBIG('PSOF'): f(PEType{}); return true; + default: return false; + } + } + static constexpr void gatherDependencies(std::vector& pathsOut, + const std::unique_ptr& elemPtr) {} }; +using VectorElementFactory = PEImpl<_VectorElementFactory>; struct IColorElement : IElement { Delete _d2; + static constexpr std::string_view TypeName = "ColorElement"sv; }; -struct ColorElementFactory : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - std::unique_ptr m_elem; - operator bool() const { return m_elem.operator bool(); } +struct CEKeyframeEmitter; +struct CEKeyframeEmitter; +struct CEConstant; +struct CETimeChain; +struct CEFadeEnd; +struct CEFade; +struct CEPulse; +struct _ColorElementFactory { + using PtrType = IColorElement; + template + static bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { + case SBIG('KEYE'): f(PEType{}); return true; + case SBIG('KEYP'): f(PEType{}); return true; + case SBIG('CNST'): f(PEType{}); return true; + case SBIG('CHAN'): f(PEType{}); return true; + case SBIG('CFDE'): f(PEType{}); return true; + case SBIG('FADE'): f(PEType{}); return true; + case SBIG('PULS'): f(PEType{}); return true; + default: return false; + } + } + static constexpr void gatherDependencies(std::vector& pathsOut, + const std::unique_ptr& elemPtr) {} }; +using ColorElementFactory = PEImpl<_ColorElementFactory>; struct IModVectorElement : IElement { Delete _d2; + static constexpr std::string_view TypeName = "ModVectorElement"sv; }; -struct ModVectorElementFactory : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - std::unique_ptr m_elem; - operator bool() const { return m_elem.operator bool(); } +struct MVEImplosion; +struct MVEExponentialImplosion; +struct MVETimeChain; +struct MVEBounce; +struct MVEConstant; +struct MVEGravity; +struct MVEExplode; +struct MVESetPosition; +struct MVELinearImplosion; +struct MVEPulse; +struct MVEWind; +struct MVESwirl; +struct _ModVectorElementFactory { + using PtrType = IModVectorElement; + template + static bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { + case SBIG('IMPL'): f(PEType{}); return true; + case SBIG('EMPL'): f(PEType{}); return true; + case SBIG('CHAN'): f(PEType{}); return true; + case SBIG('BNCE'): f(PEType{}); return true; + case SBIG('CNST'): f(PEType{}); return true; + case SBIG('GRAV'): f(PEType{}); return true; + case SBIG('EXPL'): f(PEType{}); return true; + case SBIG('SPOS'): f(PEType{}); return true; + case SBIG('LMPL'): f(PEType{}); return true; + case SBIG('PULS'): f(PEType{}); return true; + case SBIG('WIND'): f(PEType{}); return true; + case SBIG('SWRL'): f(PEType{}); return true; + default: return false; + } + } + static constexpr void gatherDependencies(std::vector& pathsOut, + const std::unique_ptr& elemPtr) {} }; +using ModVectorElementFactory = PEImpl<_ModVectorElementFactory>; struct IEmitterElement : IElement { Delete _d2; + static constexpr std::string_view TypeName = "EmitterElement"sv; }; -struct EmitterElementFactory : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - std::unique_ptr m_elem; - operator bool() const { return m_elem.operator bool(); } +struct EESimpleEmitterTR; +struct EESimpleEmitter; +struct VESphere; +struct VEAngleSphere; +struct _EmitterElementFactory { + using PtrType = IEmitterElement; + template + static bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { + case SBIG('SETR'): f(PEType{}); return true; + case SBIG('SEMR'): f(PEType{}); return true; + case SBIG('SPHE'): f(PEType{}); return true; + case SBIG('ASPH'): f(PEType{}); return true; + default: return false; + } + } + static constexpr void gatherDependencies(std::vector& pathsOut, + const std::unique_ptr& elemPtr) {} }; +using EmitterElementFactory = PEImpl<_EmitterElementFactory>; struct IUVElement : IElement { Delete _d2; virtual void gatherDependencies(std::vector& pathsOut) const = 0; + static constexpr std::string_view TypeName = "UVElement"sv; }; struct BoolHelper : IElement { @@ -87,6 +573,46 @@ struct BoolHelper : IElement { std::string_view ClassID() const override { return "BoolHelper"sv; } }; +template +struct ValueHelper : BigDNA { + AT_DECL_EXPLICIT_DNA_YAML + + void _read(athena::io::IStreamReader& r) { + hecl::DNAFourCC ValueType; + ValueType.read(r); + if (ValueType == FOURCC('CNST')) + athena::io::Read::Do({}, value.emplace(), r); + else + value = std::nullopt; + } + void _write(athena::io::IStreamWriter& w) { + if (value) { + w.writeBytes("CNST", 4); + athena::io::Write::Do({}, *value, w); + } else { + w.writeBytes("NONE", 4); + } + } + void _binarySize(std::size_t& s) { + s += 4; + if (value) + athena::io::BinarySize::Do({}, *value, s); + } + void _read(athena::io::YAMLDocReader& r) { + athena::io::ReadYaml::Do({}, value.emplace(), r); + } + void _write(athena::io::YAMLDocWriter& w) { + athena::io::WriteYaml::Do({}, *value, w); + } + + static constexpr void gatherDependencies(std::vector& pathsOut) {} + + std::optional value = {}; + void emplace(Tp val) { value.emplace(val); } + Tp operator*() const { return *value; } + operator bool() const { return value.operator bool(); } +}; + struct RELifetimeTween : IRealElement { AT_DECL_DNA_YAMLV_NO_TYPE RealElementFactory a; @@ -743,7 +1269,8 @@ struct UVEConstant : IUVElement { std::string_view ClassID() const override { return "CNST"sv; } void gatherDependencies(std::vector& pathsOut) const override { - g_curSpec->flattenDependencies(tex, pathsOut); + if (tex.isValid()) + g_curSpec->flattenDependencies(tex, pathsOut); } }; @@ -761,18 +1288,30 @@ struct UVEAnimTexture : IUVElement { std::string_view ClassID() const override { return "ATEX"sv; } void gatherDependencies(std::vector& pathsOut) const override { - g_curSpec->flattenDependencies(tex, pathsOut); + if (tex.isValid()) + g_curSpec->flattenDependencies(tex, pathsOut); } }; template -struct UVElementFactory : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA - DNAFourCC m_type; - std::unique_ptr m_elem; - operator bool() const { return m_elem.operator bool(); } +struct _UVElementFactory { + using PtrType = IUVElement; + template + static bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { + case SBIG('CNST'): f(PEType>{}); return true; + case SBIG('ATEX'): f(PEType>{}); return true; + default: return false; + } + } + static constexpr void gatherDependencies(std::vector& pathsOut, + const std::unique_ptr& elemPtr) { + if (elemPtr) + elemPtr->gatherDependencies(pathsOut); + } }; +template +using UVElementFactory = PEImpl<_UVElementFactory>; template struct SpawnSystemKeyframeData : BigDNA { @@ -809,6 +1348,10 @@ struct ChildResourceFactory : BigDNA { AT_DECL_EXPLICIT_DNA_YAML AT_SUBDECL_DNA operator bool() const { return id.isValid(); } + void gatherDependencies(std::vector& pathsOut) const { + if (id.isValid()) + g_curSpec->flattenDependencies(id, pathsOut); + } }; } // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/SWHC.cpp b/DataSpec/DNACommon/SWHC.cpp index 3ff2b8ebd..404de21af 100644 --- a/DataSpec/DNACommon/SWHC.cpp +++ b/DataSpec/DNACommon/SWHC.cpp @@ -1,11 +1,14 @@ #include "DataSpec/DNACommon/SWHC.hpp" - #include "DataSpec/DNACommon/PAK.hpp" -#include - namespace DataSpec::DNAParticle { +template struct PPImpl<_SWSH>; +template struct PPImpl<_SWSH>; + +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_SWSH>) +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_SWSH>) + template <> std::string_view SWSH::DNAType() { return "SWSH"sv; @@ -16,504 +19,6 @@ std::string_view SWSH::DNAType() { return "SWSH"sv; } -template -void SWSH::_read(typename BigDNA::ReadYaml::StreamT& r) { - for (const auto& elem : r.getCurNode()->m_mapChildren) { - if (elem.first.size() < 4) { - LogModule.report(logvisor::Warning, fmt("short FourCC in element '{}'"), elem.first); - continue; - } - - if (auto rec = r.enterSubRecord(elem.first.c_str())) { - switch (*reinterpret_cast(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(); - break; - case SBIG('CROS'): - x44_25_CROS = r.readBool(); - break; - case SBIG('VLS1'): - x44_26_VLS1 = r.readBool(); - break; - case SBIG('VLS2'): - x44_27_VLS2 = r.readBool(); - break; - case SBIG('SROT'): - x44_28_SROT = r.readBool(); - break; - case SBIG('WIRE'): - x44_29_WIRE = r.readBool(); - break; - case SBIG('TEXW'): - x44_30_TEXW = r.readBool(); - break; - case SBIG('AALP'): - x44_31_AALP = r.readBool(); - break; - case SBIG('ZBUF'): - x45_24_ZBUF = r.readBool(); - break; - case SBIG('ORNT'): - x45_25_ORNT = r.readBool(); - break; - case SBIG('CRND'): - x45_26_CRND = r.readBool(); - break; - default: - break; - } - } - } -} - -template -void SWSH::_write(typename BigDNA::WriteYaml::StreamT& w) const { - if (x0_PSLT) - if (auto rec = w.enterSubRecord("PSLT")) - x0_PSLT.write(w); - if (x4_TIME) - if (auto rec = w.enterSubRecord("TIME")) - x4_TIME.write(w); - if (x8_LRAD) - if (auto rec = w.enterSubRecord("LRAD")) - x8_LRAD.write(w); - if (xc_RRAD) - if (auto rec = w.enterSubRecord("RRAD")) - xc_RRAD.write(w); - if (x10_LENG) - if (auto rec = w.enterSubRecord("LENG")) - x10_LENG.write(w); - if (x14_COLR) - if (auto rec = w.enterSubRecord("COLR")) - x14_COLR.write(w); - if (x18_SIDE) - if (auto rec = w.enterSubRecord("SIDE")) - x18_SIDE.write(w); - if (x1c_IROT) - if (auto rec = w.enterSubRecord("IROT")) - x1c_IROT.write(w); - if (x20_ROTM) - if (auto rec = w.enterSubRecord("ROTM")) - x20_ROTM.write(w); - if (x24_POFS) - if (auto rec = w.enterSubRecord("POFS")) - x24_POFS.write(w); - if (x28_IVEL) - if (auto rec = w.enterSubRecord("IVEL")) - x28_IVEL.write(w); - if (x2c_NPOS) - if (auto rec = w.enterSubRecord("NPOS")) - x2c_NPOS.write(w); - if (x30_VELM) - if (auto rec = w.enterSubRecord("VELM")) - x30_VELM.write(w); - if (x34_VLM2) - if (auto rec = w.enterSubRecord("VLM2")) - x34_VLM2.write(w); - if (x38_SPLN) - if (auto rec = w.enterSubRecord("SPLN")) - x38_SPLN.write(w); - if (x3c_TEXR) - if (auto rec = w.enterSubRecord("TEXR")) - x3c_TEXR.write(w); - if (x40_TSPN) - if (auto rec = w.enterSubRecord("TSPN")) - x40_TSPN.write(w); - - 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 -void SWSH::_binarySize(typename BigDNA::BinarySize::StreamT& s) const { - s += 4; - if (x0_PSLT) { - s += 4; - x0_PSLT.binarySize(s); - } - if (x4_TIME) { - s += 4; - x4_TIME.binarySize(s); - } - if (x8_LRAD) { - s += 4; - x8_LRAD.binarySize(s); - } - if (xc_RRAD) { - s += 4; - xc_RRAD.binarySize(s); - } - if (x10_LENG) { - s += 4; - x10_LENG.binarySize(s); - } - if (x14_COLR) { - s += 4; - x14_COLR.binarySize(s); - } - if (x18_SIDE) { - s += 4; - x18_SIDE.binarySize(s); - } - if (x1c_IROT) { - s += 4; - x1c_IROT.binarySize(s); - } - if (x20_ROTM) { - s += 4; - x20_ROTM.binarySize(s); - } - if (x24_POFS) { - s += 4; - x24_POFS.binarySize(s); - } - if (x28_IVEL) { - s += 4; - x28_IVEL.binarySize(s); - } - if (x2c_NPOS) { - s += 4; - x2c_NPOS.binarySize(s); - } - if (x30_VELM) { - s += 4; - x30_VELM.binarySize(s); - } - if (x34_VLM2) { - s += 4; - x34_VLM2.binarySize(s); - } - if (x38_SPLN) { - s += 4; - x38_SPLN.binarySize(s); - } - if (x3c_TEXR) { - s += 4; - x3c_TEXR.binarySize(s); - } - if (x40_TSPN) { - s += 4; - x40_TSPN.binarySize(s); - } - if (x44_24_LLRD) - s += 9; - if (!x44_25_CROS) - s += 9; - if (x44_26_VLS1) - s += 9; - if (x44_27_VLS2) - s += 9; - if (x44_28_SROT) - s += 9; - if (x44_29_WIRE) - s += 9; - if (x44_30_TEXW) - s += 9; - if (x44_31_AALP) - s += 9; - if (x45_24_ZBUF) - s += 9; - if (x45_25_ORNT) - s += 9; - if (x45_26_CRND) - s += 9; -} - -template -void SWSH::_read(typename BigDNA::Read::StreamT& r) { - DNAFourCC clsId; - clsId.read(r); - if (clsId != SBIG('SWSH')) { - LogModule.report(logvisor::Warning, fmt("non SWSH provided to SWSH parser")); - return; - } - - clsId.read(r); - while (clsId != SBIG('_END')) { - switch (clsId.toUint32()) { - 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, fmt("Unknown SWSH class {} @{}"), clsId, r.position()); - break; - } - clsId.read(r); - } -} - -template -void SWSH::_write(typename BigDNA::Write::StreamT& 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); -} - -AT_SUBSPECIALIZE_DNA_YAML(SWSH) -AT_SUBSPECIALIZE_DNA_YAML(SWSH) - -template -void SWSH::gatherDependencies(std::vector& pathsOut) const { - if (x3c_TEXR.m_elem) - x3c_TEXR.m_elem->gatherDependencies(pathsOut); -} - -template struct SWSH; -template struct SWSH; - template bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { athena::io::FileWriter writer(outPath.getAbsolutePath()); diff --git a/DataSpec/DNACommon/SWHC.def b/DataSpec/DNACommon/SWHC.def new file mode 100644 index 000000000..675d8b5ec --- /dev/null +++ b/DataSpec/DNACommon/SWHC.def @@ -0,0 +1,69 @@ +#ifndef ENTRY +#define ENTRY(name, identifier) +#endif + +#ifndef INT_ENTRY +#define INT_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef REAL_ENTRY +#define REAL_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef VECTOR_ENTRY +#define VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef MOD_VECTOR_ENTRY +#define MOD_VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef COLOR_ENTRY +#define COLOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef UV_ENTRY +#define UV_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef BOOL_ENTRY +#define BOOL_ENTRY(name, identifier, def) ENTRY(name, identifier) +#endif + +INT_ENTRY('PSLT', x0_PSLT) +REAL_ENTRY('TIME', x4_TIME) +REAL_ENTRY('LRAD', x8_LRAD) +REAL_ENTRY('RRAD', xc_RRAD) +INT_ENTRY('LENG', x10_LENG) +COLOR_ENTRY('COLR', x14_COLR) +INT_ENTRY('SIDE', x18_SIDE) +REAL_ENTRY('IROT', x1c_IROT) +REAL_ENTRY('ROTM', x20_ROTM) +VECTOR_ENTRY('POFS', x24_POFS) +VECTOR_ENTRY('IVEL', x28_IVEL) +VECTOR_ENTRY('NPOS', x2c_NPOS) +MOD_VECTOR_ENTRY('VELM', x30_VELM) +MOD_VECTOR_ENTRY('VLM2', x34_VLM2) +INT_ENTRY('SPLN', x38_SPLN) +UV_ENTRY('TEXR', x3c_TEXR) +INT_ENTRY('TSPN', x40_TSPN) +BOOL_ENTRY('LLRD', x44_24_LLRD, false) +BOOL_ENTRY('CROS', x44_25_CROS, true) +BOOL_ENTRY('VLS1', x44_26_VLS1, false) +BOOL_ENTRY('VLS2', x44_27_VLS2, false) +BOOL_ENTRY('SROT', x44_28_SROT, false) +BOOL_ENTRY('WIRE', x44_29_WIRE, false) +BOOL_ENTRY('TEXW', x44_30_TEXW, false) +BOOL_ENTRY('AALP', x44_31_AALP, false) +BOOL_ENTRY('ZBUF', x45_24_ZBUF, false) +BOOL_ENTRY('ORNT', x45_25_ORNT, false) +BOOL_ENTRY('CRND', x45_26_CRND, false) + +#undef ENTRY +#undef INT_ENTRY +#undef REAL_ENTRY +#undef VECTOR_ENTRY +#undef MOD_VECTOR_ENTRY +#undef COLOR_ENTRY +#undef UV_ENTRY +#undef BOOL_ENTRY diff --git a/DataSpec/DNACommon/SWHC.hpp b/DataSpec/DNACommon/SWHC.hpp index 3c81344c0..269828ed2 100644 --- a/DataSpec/DNACommon/SWHC.hpp +++ b/DataSpec/DNACommon/SWHC.hpp @@ -16,48 +16,36 @@ class ProjectPath; namespace DataSpec::DNAParticle { template -struct SWSH : public BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA +struct _SWSH { + static constexpr ParticleType Type = ParticleType::SWSH; - 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 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; - }; +#define INT_ENTRY(name, identifier) IntElementFactory identifier; +#define REAL_ENTRY(name, identifier) RealElementFactory identifier; +#define VECTOR_ENTRY(name, identifier) VectorElementFactory identifier; +#define MOD_VECTOR_ENTRY(name, identifier) ModVectorElementFactory identifier; +#define COLOR_ENTRY(name, identifier) ColorElementFactory identifier; +#define UV_ENTRY(name, identifier) UVElementFactory identifier; +#define BOOL_ENTRY(name, identifier, def) bool identifier = def; +#include "SWHC.def" - SWSH() { x44_25_CROS = true; } + template + void constexpr Enumerate(_Func f) { +#define ENTRY(name, identifier) f(FOURCC(name), identifier); +#define BOOL_ENTRY(name, identifier, def) f(FOURCC(name), identifier, def); +#include "SWHC.def" + } - void gatherDependencies(std::vector&) const; + template + bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { +#define ENTRY(name, identifier) case SBIG(name): f(identifier); return true; +#include "SWHC.def" + default: return false; + } + } }; +template +using SWSH = PPImpl<_SWSH>; template bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); diff --git a/DataSpec/DNACommon/WPSC.cpp b/DataSpec/DNACommon/WPSC.cpp index 67fcfb57c..c801d8789 100644 --- a/DataSpec/DNACommon/WPSC.cpp +++ b/DataSpec/DNACommon/WPSC.cpp @@ -1,645 +1,13 @@ #include "DataSpec/DNACommon/WPSC.hpp" - #include "DataSpec/DNACommon/PAK.hpp" -#include - namespace DataSpec::DNAParticle { -template -void WPSM::_read(athena::io::YAMLDocReader& r) { - for (const auto& elem : r.getCurNode()->m_mapChildren) { - if (elem.first.size() < 4) { - LogModule.report(logvisor::Warning, fmt("short FourCC in element '{}'"), elem.first); - continue; - } +template struct PPImpl<_WPSM>; +template struct PPImpl<_WPSM>; - if (auto rec = r.enterSubRecord(elem.first.c_str())) { - switch (*reinterpret_cast(elem.first.data())) { - case SBIG('IORN'): - x0_IORN.read(r); - break; - case SBIG('IVEC'): - x4_IVEC.read(r); - break; - case SBIG('PSOV'): - x8_PSOV.read(r); - break; - case SBIG('PSVM'): - xc_PSVM.read(r); - break; - case SBIG('VMD2'): - x10_VMD2.read(r); - break; - case SBIG('PSLT'): - x14_PSLT.read(r); - break; - case SBIG('PSCL'): - x18_PSCL.read(r); - break; - case SBIG('PCOL'): - x1c_PCOL.read(r); - break; - case SBIG('POFS'): - x20_POFS.read(r); - break; - case SBIG('OFST'): - x24_OFST.read(r); - break; - case SBIG('APSO'): - x28_APSO.read(r); - break; - case SBIG('HOMG'): - x29_HOMG.read(r); - break; - case SBIG('AP11'): - x2a_AP11.read(r); - break; - case SBIG('AP21'): - x2b_AP21.read(r); - break; - case SBIG('AS11'): - x2c_AS11.read(r); - break; - case SBIG('AS12'): - x2d_AS12.read(r); - break; - case SBIG('AS13'): - x2e_AS13.read(r); - break; - case SBIG('TRAT'): - x30_TRAT.read(r); - break; - case SBIG('APSM'): - x34_APSM.read(r); - break; - case SBIG('APS2'): - x44_APS2.read(r); - break; - case SBIG('ASW1'): - x54_ASW1.read(r); - break; - case SBIG('ASW2'): - x64_ASW2.read(r); - break; - case SBIG('ASW3'): - x74_ASW3.read(r); - break; - case SBIG('OHEF'): - x84_OHEF.read(r); - break; - case SBIG('COLR'): - x94_COLR.read(r); - break; - case SBIG('EWTR'): - xa4_EWTR.read(r); - break; - case SBIG('LWTR'): - xa5_LWTR.read(r); - break; - case SBIG('SWTR'): - xa6_SWTR.read(r); - break; - case SBIG('PJFX'): - xa8_PJFX = r.readUint32(); - break; - case SBIG('RNGE'): - xac_RNGE.read(r); - break; - case SBIG('FOFF'): - xb0_FOFF.read(r); - break; - case SBIG('FC60'): - xunk_FC60.read(r); - break; - case SBIG('SPS1'): - xunk_SPS1.read(r); - break; - case SBIG('SPS2'): - xunk_SPS2.read(r); - break; - } - } - } -} - -template -void WPSM::_write(athena::io::YAMLDocWriter& w) const { - if (x0_IORN) - if (auto rec = w.enterSubRecord("IORN")) - x0_IORN.write(w); - if (x4_IVEC) - if (auto rec = w.enterSubRecord("IVEC")) - x4_IVEC.write(w); - if (x8_PSOV) - if (auto rec = w.enterSubRecord("PSOV")) - x8_PSOV.write(w); - if (xc_PSVM) - if (auto rec = w.enterSubRecord("PSVM")) - xc_PSVM.write(w); - if (x10_VMD2) - if (auto rec = w.enterSubRecord("VMD2")) - x10_VMD2.write(w); - if (x14_PSLT) - if (auto rec = w.enterSubRecord("PSLT")) - x14_PSLT.write(w); - if (x18_PSCL) - if (auto rec = w.enterSubRecord("PSCL")) - x18_PSCL.write(w); - if (x1c_PCOL) - if (auto rec = w.enterSubRecord("PCOL")) - x1c_PCOL.write(w); - if (x20_POFS) - if (auto rec = w.enterSubRecord("POFS")) - x20_POFS.write(w); - if (x24_OFST) - if (auto rec = w.enterSubRecord("OFST")) - x24_OFST.write(w); - if (x28_APSO) - if (auto rec = w.enterSubRecord("APSO")) - x28_APSO.write(w); - if (x29_HOMG) - if (auto rec = w.enterSubRecord("HOMG")) - x29_HOMG.write(w); - if (x2a_AP11) - if (auto rec = w.enterSubRecord("AP11")) - x2a_AP11.write(w); - if (x2b_AP21) - if (auto rec = w.enterSubRecord("AP21")) - x2b_AP21.write(w); - if (x2c_AS11) - if (auto rec = w.enterSubRecord("AS11")) - x2c_AS11.write(w); - if (x2d_AS12) - if (auto rec = w.enterSubRecord("AS12")) - x2d_AS12.write(w); - if (x2e_AS13) - if (auto rec = w.enterSubRecord("AS13")) - x2e_AS13.write(w); - if (x30_TRAT) - if (auto rec = w.enterSubRecord("TRAT")) - x30_TRAT.write(w); - if (x34_APSM) - if (auto rec = w.enterSubRecord("APSM")) - x34_APSM.write(w); - if (x44_APS2) - if (auto rec = w.enterSubRecord("APS2")) - x44_APS2.write(w); - if (x54_ASW1) - if (auto rec = w.enterSubRecord("ASW1")) - x54_ASW1.write(w); - if (x64_ASW2) - if (auto rec = w.enterSubRecord("ASW2")) - x64_ASW2.write(w); - if (x74_ASW3) - if (auto rec = w.enterSubRecord("ASW3")) - x74_ASW3.write(w); - if (x84_OHEF) - if (auto rec = w.enterSubRecord("OHEF")) - x84_OHEF.write(w); - if (x94_COLR) - if (auto rec = w.enterSubRecord("COLR")) - x94_COLR.write(w); - if (!xa4_EWTR) - if (auto rec = w.enterSubRecord("EWTR")) - xa4_EWTR.write(w); - if (!xa5_LWTR) - if (auto rec = w.enterSubRecord("LWTR")) - xa5_LWTR.write(w); - if (!xa6_SWTR) - if (auto rec = w.enterSubRecord("SWTR")) - xa6_SWTR.write(w); - if (xa8_PJFX != UINT32_MAX) - w.writeUint32("PJFX", xa8_PJFX); - if (xac_RNGE) - if (auto rec = w.enterSubRecord("RNGE")) - xac_RNGE.write(w); - if (xb0_FOFF) - if (auto rec = w.enterSubRecord("FOFF")) - xb0_FOFF.write(w); - if (xunk_FC60) - if (auto rec = w.enterSubRecord("FC60")) - xunk_FC60.write(w); - if (xunk_SPS1) - if (auto rec = w.enterSubRecord("SPS1")) - xunk_SPS1.write(w); - if (xunk_SPS1) - if (auto rec = w.enterSubRecord("SPS2")) - xunk_SPS2.write(w); -} - -template -void WPSM::_binarySize(size_t& __isz) const { - __isz += 4; - if (x0_IORN) { - __isz += 4; - x0_IORN.binarySize(__isz); - } - if (x4_IVEC) { - __isz += 4; - x4_IVEC.binarySize(__isz); - } - if (x8_PSOV) { - __isz += 4; - x8_PSOV.binarySize(__isz); - } - if (xc_PSVM) { - __isz += 4; - xc_PSVM.binarySize(__isz); - } - if (x10_VMD2) { - __isz += 4; - x10_VMD2.binarySize(__isz); - } - if (x14_PSLT) { - __isz += 4; - x14_PSLT.binarySize(__isz); - } - if (x18_PSCL) { - __isz += 4; - x18_PSCL.binarySize(__isz); - } - if (x1c_PCOL) { - __isz += 4; - x1c_PCOL.binarySize(__isz); - } - if (x20_POFS) { - __isz += 4; - x20_POFS.binarySize(__isz); - } - if (x24_OFST) { - __isz += 4; - x24_OFST.binarySize(__isz); - } - if (x28_APSO) { - __isz += 4; - x28_APSO.binarySize(__isz); - } - if (x29_HOMG) { - __isz += 4; - x29_HOMG.binarySize(__isz); - } - if (x2a_AP11) { - __isz += 4; - x2a_AP11.binarySize(__isz); - } - if (x2b_AP21) { - __isz += 4; - x2b_AP21.binarySize(__isz); - } - if (x2c_AS11) { - __isz += 4; - x2c_AS11.binarySize(__isz); - } - if (x2d_AS12) { - __isz += 4; - x2d_AS12.binarySize(__isz); - } - if (x2e_AS13) { - __isz += 4; - x2e_AS13.binarySize(__isz); - } - if (x30_TRAT) { - __isz += 4; - x30_TRAT.binarySize(__isz); - } - if (x34_APSM) { - __isz += 4; - x34_APSM.binarySize(__isz); - } - if (x44_APS2) { - __isz += 4; - x44_APS2.binarySize(__isz); - } - if (x54_ASW1) { - __isz += 4; - x54_ASW1.binarySize(__isz); - } - if (x64_ASW2) { - __isz += 4; - x64_ASW2.binarySize(__isz); - } - if (x74_ASW3) { - __isz += 4; - x74_ASW3.binarySize(__isz); - } - if (x84_OHEF) { - __isz += 4; - x84_OHEF.binarySize(__isz); - } - if (x94_COLR) { - __isz += 4; - x94_COLR.binarySize(__isz); - } - if (!xa4_EWTR) { - __isz += 4; - xa4_EWTR.binarySize(__isz); - } - if (!xa5_LWTR) { - __isz += 4; - xa5_LWTR.binarySize(__isz); - } - if (!xa6_SWTR) { - __isz += 4; - xa6_SWTR.binarySize(__isz); - } - if (xa8_PJFX != UINT32_MAX) - __isz += 12; - if (xac_RNGE) { - __isz += 4; - xac_RNGE.binarySize(__isz); - } - if (xb0_FOFF) { - __isz += 4; - xb0_FOFF.binarySize(__isz); - } - if (xunk_FC60) { - __isz += 4; - xunk_FC60.binarySize(__isz); - } - if (xunk_SPS1) { - __isz += 4; - xunk_SPS1.binarySize(__isz); - } - if (xunk_SPS2) { - __isz += 4; - xunk_SPS2.binarySize(__isz); - } -} - -template -void WPSM::_read(athena::io::IStreamReader& r) { - DNAFourCC clsId; - clsId.read(r); - if (clsId != SBIG('WPSM')) { - LogModule.report(logvisor::Warning, fmt("non WPSM provided to WPSM parser")); - return; - } - clsId.read(r); - while (clsId != SBIG('_END')) { - switch (clsId.toUint32()) { - case SBIG('IORN'): - x0_IORN.read(r); - break; - case SBIG('IVEC'): - x4_IVEC.read(r); - break; - case SBIG('PSOV'): - x8_PSOV.read(r); - break; - case SBIG('PSVM'): - xc_PSVM.read(r); - break; - case SBIG('VMD2'): - x10_VMD2.read(r); - break; - case SBIG('PSLT'): - x14_PSLT.read(r); - break; - case SBIG('PSCL'): - x18_PSCL.read(r); - break; - case SBIG('PCOL'): - x1c_PCOL.read(r); - break; - case SBIG('POFS'): - x20_POFS.read(r); - break; - case SBIG('OFST'): - x24_OFST.read(r); - break; - case SBIG('APSO'): - r.readUint32(); - x28_APSO = r.readBool(); - break; - case SBIG('HOMG'): - x29_HOMG.read(r); - break; - case SBIG('AP11'): - x2a_AP11.read(r); - break; - case SBIG('AP21'): - x2b_AP21.read(r); - break; - case SBIG('AS11'): - x2c_AS11.read(r); - break; - case SBIG('AS12'): - x2d_AS12.read(r); - break; - case SBIG('AS13'): - x2e_AS13.read(r); - break; - case SBIG('TRAT'): - x30_TRAT.read(r); - break; - case SBIG('APSM'): - x34_APSM.read(r); - break; - case SBIG('APS2'): - x44_APS2.read(r); - break; - case SBIG('ASW1'): - x54_ASW1.read(r); - break; - case SBIG('ASW2'): - x64_ASW2.read(r); - break; - case SBIG('ASW3'): - x74_ASW3.read(r); - break; - case SBIG('OHEF'): - x84_OHEF.read(r); - break; - case SBIG('COLR'): - x94_COLR.read(r); - break; - case SBIG('EWTR'): - r.readUint32(); - xa4_EWTR = r.readBool(); - break; - case SBIG('LWTR'): - r.readUint32(); - xa5_LWTR = r.readBool(); - break; - case SBIG('SWTR'): - r.readUint32(); - xa6_SWTR = r.readBool(); - break; - case SBIG('PJFX'): { - uint32_t fcc; - r.readBytesToBuf(&fcc, 4); - if (fcc != SBIG('NONE')) - xa8_PJFX = r.readUint32Big(); - } break; - case SBIG('RNGE'): - xac_RNGE.read(r); - break; - case SBIG('FOFF'): - xb0_FOFF.read(r); - break; - case SBIG('FC60'): - xunk_FC60.read(r); - break; - case SBIG('SPS1'): - xunk_SPS1.read(r); - break; - case SBIG('SPS2'): - xunk_SPS2.read(r); - break; - default: - LogModule.report(logvisor::Fatal, fmt("Unknown WPSM class {} @{}"), clsId, r.position()); - break; - } - clsId.read(r); - } -} - -template -void WPSM::_write(athena::io::IStreamWriter& w) const { - w.writeBytes("WPSM", 4); - if (x0_IORN) { - w.writeBytes("IORN", 4); - x0_IORN.write(w); - } - if (x4_IVEC) { - w.writeBytes("IVEC", 4); - x4_IVEC.write(w); - } - if (x8_PSOV) { - w.writeBytes("PSOV", 4); - x8_PSOV.write(w); - } - if (xc_PSVM) { - w.writeBytes("PSVM", 4); - xc_PSVM.write(w); - } - if (x10_VMD2) { - w.writeBytes("VMD2", 4); - x10_VMD2.write(w); - } - if (x14_PSLT) { - w.writeBytes("PSLT", 4); - x14_PSLT.write(w); - } - if (x18_PSCL) { - w.writeBytes("PSCL", 4); - x18_PSCL.write(w); - } - if (x1c_PCOL) { - w.writeBytes("PCOL", 4); - x1c_PCOL.write(w); - } - if (x20_POFS) { - w.writeBytes("POFS", 4); - x20_POFS.write(w); - } - if (x24_OFST) { - w.writeBytes("OFST", 4); - x24_OFST.write(w); - } - if (x28_APSO) { - w.writeBytes("APSO", 4); - x28_APSO.write(w); - } - if (x29_HOMG) { - w.writeBytes("HOMG", 4); - x29_HOMG.write(w); - } - if (x2a_AP11) { - w.writeBytes("AP11", 4); - x2a_AP11.write(w); - } - if (x2b_AP21) { - w.writeBytes("AP21", 4); - x2b_AP21.write(w); - } - if (x2c_AS11) { - w.writeBytes("AS11", 4); - x2c_AS11.write(w); - } - if (x2d_AS12) { - w.writeBytes("AS12", 4); - x2d_AS12.write(w); - } - if (x2e_AS13) { - w.writeBytes("AS13", 4); - x2e_AS13.write(w); - } - if (x30_TRAT) { - w.writeBytes("TRAT", 4); - x30_TRAT.write(w); - } - if (x34_APSM) { - w.writeBytes("APSM", 4); - x34_APSM.write(w); - } - if (x44_APS2) { - w.writeBytes("APS2", 4); - x44_APS2.write(w); - } - if (x54_ASW1) { - w.writeBytes("ASW1", 4); - x54_ASW1.write(w); - } - if (x64_ASW2) { - w.writeBytes("ASW2", 4); - x64_ASW2.write(w); - } - if (x74_ASW3) { - w.writeBytes("ASW3", 4); - x74_ASW3.write(w); - } - if (x84_OHEF) { - w.writeBytes("OHEF", 4); - x84_OHEF.write(w); - } - if (x94_COLR) { - w.writeBytes("COLR", 4); - x94_COLR.write(w); - } - if (!xa4_EWTR) { - w.writeBytes("EWTR", 4); - xa4_EWTR.write(w); - } - if (!xa5_LWTR) { - w.writeBytes("LWTR", 4); - xa5_LWTR.write(w); - } - if (!xa6_SWTR) { - w.writeBytes("SWTR", 4); - xa6_SWTR.write(w); - } - if (xa8_PJFX != UINT32_MAX) { - w.writeBytes("PJFXCNST", 8); - w.writeUint32(xa8_PJFX); - } - if (xac_RNGE) { - w.writeBytes("RNGE", 4); - xac_RNGE.write(w); - } - if (xb0_FOFF) { - w.writeBytes("FOFF", 4); - xb0_FOFF.write(w); - } - if (xunk_FC60) { - w.writeBytes("FC60", 4); - xunk_FC60.write(w); - } - if (xunk_SPS1) { - w.writeBytes("SPS1", 4); - xunk_SPS1.write(w); - } - if (xunk_SPS2) { - w.writeBytes("SPS2", 4); - xunk_SPS2.write(w); - } - - w.writeBytes("_END", 4); -} - -AT_SUBSPECIALIZE_DNA_YAML(WPSM) -AT_SUBSPECIALIZE_DNA_YAML(WPSM) +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_WPSM>) +AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_WPSM>) template <> std::string_view WPSM::DNAType() { @@ -651,20 +19,6 @@ std::string_view WPSM::DNAType() { return "WPSM"sv; } -template -void WPSM::gatherDependencies(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(x34_APSM.id, pathsOut); - g_curSpec->flattenDependencies(x44_APS2.id, pathsOut); - g_curSpec->flattenDependencies(x54_ASW1.id, pathsOut); - g_curSpec->flattenDependencies(x64_ASW2.id, pathsOut); - g_curSpec->flattenDependencies(x74_ASW3.id, pathsOut); - g_curSpec->flattenDependencies(x84_OHEF.id, pathsOut); - g_curSpec->flattenDependencies(x94_COLR.id, pathsOut); -} - -template struct WPSM; -template struct WPSM; - template bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { athena::io::FileWriter writer(outPath.getAbsolutePath()); diff --git a/DataSpec/DNACommon/WPSC.def b/DataSpec/DNACommon/WPSC.def new file mode 100644 index 000000000..04b6ce33f --- /dev/null +++ b/DataSpec/DNACommon/WPSC.def @@ -0,0 +1,87 @@ +#ifndef ENTRY +#define ENTRY(name, identifier) +#endif + +#ifndef INT_ENTRY +#define INT_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef U32_ENTRY +#define U32_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef REAL_ENTRY +#define REAL_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef VECTOR_ENTRY +#define VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef MOD_VECTOR_ENTRY +#define MOD_VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef COLOR_ENTRY +#define COLOR_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef UV_ENTRY +#define UV_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef RES_ENTRY +#define RES_ENTRY(name, identifier) ENTRY(name, identifier) +#endif + +#ifndef BOOL_ENTRY +#define BOOL_ENTRY(name, identifier, def) ENTRY(name, identifier) +#endif + +VECTOR_ENTRY('IORN', x0_IORN) +VECTOR_ENTRY('IVEC', x4_IVEC) +VECTOR_ENTRY('PSOV', x8_PSOV) +MOD_VECTOR_ENTRY('PSVM', xc_PSVM) +INT_ENTRY('PSLT', x14_PSLT) +VECTOR_ENTRY('PSCL', x18_PSCL) +COLOR_ENTRY('PCOL', x1c_PCOL) +VECTOR_ENTRY('POFS', x20_POFS) +VECTOR_ENTRY('OFST', x24_OFST) + +REAL_ENTRY('TRAT', x30_TRAT) +RES_ENTRY('APSM', x34_APSM) +RES_ENTRY('APS2', x44_APS2) +RES_ENTRY('ASW1', x54_ASW1) +RES_ENTRY('ASW2', x64_ASW2) +RES_ENTRY('ASW3', x74_ASW3) +RES_ENTRY('OHEF', x84_OHEF) +RES_ENTRY('COLR', x94_COLR) +U32_ENTRY('PJFX', xa8_PJFX) +REAL_ENTRY('RNGE', xac_RNGE) +REAL_ENTRY('FOFF', xb0_FOFF) + +BOOL_ENTRY('VMD2', x10_VMD2, false) +BOOL_ENTRY('APSO', x28_APSO, false) +BOOL_ENTRY('HOMG', x29_HOMG, false) +BOOL_ENTRY('AP11', x2a_AP11, false) +BOOL_ENTRY('AP21', x2b_AP21, false) +BOOL_ENTRY('AS11', x2c_AS11, false) +BOOL_ENTRY('AS12', x2d_AS12, false) +BOOL_ENTRY('AS13', x2e_AS13, false) +BOOL_ENTRY('EWTR', xa4_EWTR, true) +BOOL_ENTRY('LWTR', xa5_LWTR, true) +BOOL_ENTRY('SWTR', xa6_SWTR, true) +BOOL_ENTRY('FC60', xunk_FC60, false) +BOOL_ENTRY('SPS1', xunk_SPS1, false) +BOOL_ENTRY('SPS2', xunk_SPS2, false) + +#undef ENTRY +#undef INT_ENTRY +#undef U32_ENTRY +#undef REAL_ENTRY +#undef VECTOR_ENTRY +#undef MOD_VECTOR_ENTRY +#undef COLOR_ENTRY +#undef UV_ENTRY +#undef RES_ENTRY +#undef BOOL_ENTRY diff --git a/DataSpec/DNACommon/WPSC.hpp b/DataSpec/DNACommon/WPSC.hpp index 3df67b7bd..6a387ef7a 100644 --- a/DataSpec/DNACommon/WPSC.hpp +++ b/DataSpec/DNACommon/WPSC.hpp @@ -12,53 +12,40 @@ class ProjectPath; } namespace DataSpec::DNAParticle { -template -struct WPSM : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA - VectorElementFactory x0_IORN; - VectorElementFactory x4_IVEC; - VectorElementFactory x8_PSOV; - ModVectorElementFactory xc_PSVM; - BoolHelper x10_VMD2; - IntElementFactory x14_PSLT; - VectorElementFactory x18_PSCL; - ColorElementFactory x1c_PCOL; - VectorElementFactory x20_POFS; - VectorElementFactory x24_OFST; - BoolHelper x28_APSO; - BoolHelper x29_HOMG; - BoolHelper x2a_AP11; - BoolHelper x2b_AP21; - BoolHelper x2c_AS11; - BoolHelper x2d_AS12; - BoolHelper x2e_AS13; - RealElementFactory x30_TRAT; - ChildResourceFactory x34_APSM; - ChildResourceFactory x44_APS2; - ChildResourceFactory x54_ASW1; - ChildResourceFactory x64_ASW2; - ChildResourceFactory x74_ASW3; - ChildResourceFactory x84_OHEF; - ChildResourceFactory x94_COLR; - BoolHelper xa4_EWTR; - BoolHelper xa5_LWTR; - BoolHelper xa6_SWTR; - uint32_t xa8_PJFX = ~0; - RealElementFactory xac_RNGE; - RealElementFactory xb0_FOFF; - BoolHelper xunk_FC60; - BoolHelper xunk_SPS1; - BoolHelper xunk_SPS2; - WPSM() { - xa4_EWTR = true; - xa5_LWTR = true; - xa6_SWTR = true; +template +struct _WPSM { + static constexpr ParticleType Type = ParticleType::WPSM; + +#define INT_ENTRY(name, identifier) IntElementFactory identifier; +#define U32_ENTRY(name, identifier) uint32_t identifier = ~0; +#define REAL_ENTRY(name, identifier) RealElementFactory identifier; +#define VECTOR_ENTRY(name, identifier) VectorElementFactory identifier; +#define MOD_VECTOR_ENTRY(name, identifier) ModVectorElementFactory identifier; +#define COLOR_ENTRY(name, identifier) ColorElementFactory identifier; +#define UV_ENTRY(name, identifier) UVElementFactory identifier; +#define RES_ENTRY(name, identifier) ChildResourceFactory identifier; +#define BOOL_ENTRY(name, identifier, def) bool identifier = def; +#include "WPSC.def" + + template + void constexpr Enumerate(_Func f) { +#define ENTRY(name, identifier) f(FOURCC(name), identifier); +#define BOOL_ENTRY(name, identifier, def) f(FOURCC(name), identifier, def); +#include "WPSC.def" } - void gatherDependencies(std::vector&) const; + template + bool constexpr Lookup(FourCC fcc, _Func f) { + switch (fcc.toUint32()) { +#define ENTRY(name, identifier) case SBIG(name): f(identifier); return true; +#include "WPSC.def" + default: return false; + } + } }; +template +using WPSM = PPImpl<_WPSM>; template bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); diff --git a/hecl b/hecl index db10f0c2c..0b42de34d 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit db10f0c2ca2ea4ab4b779798b041b3bae0d79937 +Subproject commit 0b42de34d0439ed46e393e0bb6de1b02641399a1