mirror of https://github.com/AxioDL/metaforce.git
Refactor particle serialization to use generative meta-information
This commit is contained in:
parent
3e07a06355
commit
566b15766c
|
@ -1,248 +1,24 @@
|
|||
#include "DataSpec/DNACommon/CRSC.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "DataSpec/DNACommon/PAK.hpp"
|
||||
|
||||
#include <logvisor/logvisor.hpp>
|
||||
|
||||
namespace DataSpec::DNAParticle {
|
||||
static const std::vector<FourCC> 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<FourCC> 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<UniqueID32>>;
|
||||
template struct PPImpl<_CRSM<UniqueID64>>;
|
||||
|
||||
static const std::vector<FourCC> DecalTypes = {SBIG('NCDL'), SBIG('DDCL'), SBIG('CODL'), SBIG('MEDL'), SBIG('GRDL'),
|
||||
SBIG('ICDL'), SBIG('GODL'), SBIG('WODL'), SBIG('WTDL'), SBIG('3MUD'),
|
||||
SBIG('3LAV'), SBIG('3SAN'), SBIG('CHDL'), SBIG('ENDL')};
|
||||
AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_CRSM<UniqueID32>>)
|
||||
AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_CRSM<UniqueID64>>)
|
||||
|
||||
template <>
|
||||
std::string_view CRSM<UniqueID32>::DNAType() {
|
||||
return "CRSM<UniqueID32>"sv;
|
||||
std::string_view PPImpl<_CRSM<UniqueID32>>::DNAType() {
|
||||
return "urde::CRSM<UniqueID32>"sv;
|
||||
}
|
||||
|
||||
template <>
|
||||
std::string_view CRSM<UniqueID64>::DNAType() {
|
||||
return "CRSM<UniqueID64>"sv;
|
||||
std::string_view PPImpl<_CRSM<UniqueID64>>::DNAType() {
|
||||
return "urde::CRSM<UniqueID64>"sv;
|
||||
}
|
||||
|
||||
template <class IDType>
|
||||
void CRSM<IDType>::_read(athena::io::YAMLDocReader& r) {
|
||||
for (const auto& elem : r.getCurNode()->m_mapChildren) {
|
||||
if (elem.first.size() < 4) {
|
||||
LogModule.report(logvisor::Warning, 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 <class IDType>
|
||||
void CRSM<IDType>::_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 <class IDType>
|
||||
void CRSM<IDType>::_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 <class IDType>
|
||||
void CRSM<IDType>::_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 <class IDType>
|
||||
void CRSM<IDType>::_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<UniqueID32>)
|
||||
AT_SUBSPECIALIZE_DNA_YAML(CRSM<UniqueID64>)
|
||||
|
||||
template <class IDType>
|
||||
void CRSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& 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 <class IDType>
|
||||
CRSM<IDType>::CRSM() : x30_RNGE(50.f), x34_FOFF(0.2f) {
|
||||
for (const auto& sfx : SFXTypes)
|
||||
x10_sfx[sfx] = ~0;
|
||||
}
|
||||
|
||||
template struct CRSM<UniqueID32>;
|
||||
template struct CRSM<UniqueID64>;
|
||||
|
||||
template <class IDType>
|
||||
bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
|
||||
athena::io::FileWriter writer(outPath.getAbsolutePath());
|
||||
|
|
|
@ -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
|
|
@ -18,20 +18,33 @@ class ProjectPath;
|
|||
}
|
||||
|
||||
namespace DataSpec::DNAParticle {
|
||||
|
||||
template <class IDType>
|
||||
struct CRSM : BigDNA {
|
||||
AT_DECL_EXPLICIT_DNA_YAML
|
||||
AT_SUBDECL_DNA
|
||||
std::unordered_map<FourCC, ChildResourceFactory<IDType>> x0_generators;
|
||||
std::unordered_map<FourCC, uint32_t> x10_sfx;
|
||||
std::unordered_map<FourCC, ChildResourceFactory<IDType>> x20_decals;
|
||||
float x30_RNGE;
|
||||
float x34_FOFF;
|
||||
struct _CRSM {
|
||||
static constexpr ParticleType Type = ParticleType::CRSM;
|
||||
#define RES_ENTRY(name, identifier) ChildResourceFactory<IDType> identifier;
|
||||
#define U32_ENTRY(name, identifier) uint32_t identifier = ~0;
|
||||
#define FLOAT_ENTRY(name, identifier) float identifier = 0.f;
|
||||
#include "CRSC.def"
|
||||
|
||||
CRSM();
|
||||
template<typename _Func>
|
||||
void constexpr Enumerate(_Func f) {
|
||||
#define ENTRY(name, identifier) f(FOURCC(name), identifier);
|
||||
#include "CRSC.def"
|
||||
}
|
||||
|
||||
void gatherDependencies(std::vector<hecl::ProjectPath>&) const;
|
||||
template<typename _Func>
|
||||
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 <class IDType>
|
||||
using CRSM = PPImpl<_CRSM<IDType>>;
|
||||
|
||||
template <class IDType>
|
||||
bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
|
||||
|
||||
|
|
|
@ -1,391 +1,24 @@
|
|||
#include "DataSpec/DNACommon/DPSC.hpp"
|
||||
|
||||
#include "DataSpec/DNACommon/PAK.hpp"
|
||||
|
||||
#include <athena/DNAYaml.hpp>
|
||||
#include <logvisor/logvisor.hpp>
|
||||
|
||||
namespace DataSpec::DNAParticle {
|
||||
|
||||
template struct PPImpl<_DPSM<UniqueID32>>;
|
||||
template struct PPImpl<_DPSM<UniqueID64>>;
|
||||
|
||||
AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_DPSM<UniqueID32>>)
|
||||
AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_DPSM<UniqueID64>>)
|
||||
|
||||
template <>
|
||||
std::string_view DPSM<UniqueID32>::DNAType() {
|
||||
std::string_view PPImpl<_DPSM<UniqueID32>>::DNAType() {
|
||||
return "DPSM<UniqueID32>"sv;
|
||||
}
|
||||
|
||||
template <>
|
||||
std::string_view DPSM<UniqueID64>::DNAType() {
|
||||
std::string_view PPImpl<_DPSM<UniqueID64>>::DNAType() {
|
||||
return "DPSM<UniqueID64>"sv;
|
||||
}
|
||||
|
||||
template <class IDType>
|
||||
void DPSM<IDType>::_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<const uint32_t*>(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 <class IDType>
|
||||
void DPSM<IDType>::_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 <class IDType>
|
||||
template <class Reader>
|
||||
void DPSM<IDType>::readQuadDecalInfo(Reader& r, FourCC clsId, typename DPSM<IDType>::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 <class IDType>
|
||||
void DPSM<IDType>::writeQuadDecalInfo(athena::io::YAMLDocWriter& w, const typename DPSM<IDType>::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 <class IDType>
|
||||
void DPSM<IDType>::_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 <class IDType>
|
||||
void DPSM<IDType>::getQuadDecalBinarySize(size_t& s, const typename DPSM<IDType>::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 <class IDType>
|
||||
void DPSM<IDType>::_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 <class IDType>
|
||||
void DPSM<IDType>::_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 <class IDType>
|
||||
void DPSM<IDType>::writeQuadDecalInfo(athena::io::IStreamWriter& w, const typename DPSM<IDType>::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 <class IDType>
|
||||
void DPSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& 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<UniqueID32>)
|
||||
AT_SUBSPECIALIZE_DNA_YAML(DPSM<UniqueID64>)
|
||||
template struct DPSM<UniqueID32>;
|
||||
template struct DPSM<UniqueID64>;
|
||||
|
||||
template <class IDType>
|
||||
bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
|
||||
athena::io::FileWriter writer(outPath.getAbsolutePath());
|
||||
|
|
|
@ -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
|
|
@ -20,9 +20,8 @@ class ProjectPath;
|
|||
namespace DataSpec::DNAParticle {
|
||||
|
||||
template <class IDType>
|
||||
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<IDType> 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 <class Reader>
|
||||
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<hecl::ProjectPath>&) const;
|
||||
bool x5c_24_DMAB = false;
|
||||
bool x5c_25_DMOO = false;
|
||||
|
||||
template<typename _Func>
|
||||
void constexpr Enumerate(_Func f) {
|
||||
#define ENTRY(name, identifier) f(FOURCC(name), identifier);
|
||||
#include "DPSC.def"
|
||||
}
|
||||
|
||||
template<typename _Func>
|
||||
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 <class IDType>
|
||||
using DPSM = PPImpl<_DPSM<IDType>>;
|
||||
|
||||
template <class IDType>
|
||||
bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
|
||||
|
|
|
@ -1,403 +1,13 @@
|
|||
#include "DataSpec/DNACommon/ELSC.hpp"
|
||||
|
||||
#include <logvisor/logvisor.hpp>
|
||||
#include "DataSpec/DNACommon/PAK.hpp"
|
||||
|
||||
namespace DataSpec::DNAParticle {
|
||||
|
||||
template <class IDType>
|
||||
void ELSM<IDType>::_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<UniqueID32>>;
|
||||
template struct PPImpl<_ELSM<UniqueID64>>;
|
||||
|
||||
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 <class IDType>
|
||||
void ELSM<IDType>::_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 <class IDType>
|
||||
void ELSM<IDType>::_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 <class IDType>
|
||||
void ELSM<IDType>::_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<const uint32_t*>(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 <class IDType>
|
||||
void ELSM<IDType>::_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<UniqueID32>)
|
||||
AT_SUBSPECIALIZE_DNA_YAML(ELSM<UniqueID64>)
|
||||
AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_ELSM<UniqueID32>>)
|
||||
AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_ELSM<UniqueID64>>)
|
||||
|
||||
template <>
|
||||
std::string_view ELSM<UniqueID32>::DNAType() {
|
||||
|
@ -409,16 +19,6 @@ std::string_view ELSM<UniqueID64>::DNAType() {
|
|||
return "urde::ELSM<UniqueID64>"sv;
|
||||
}
|
||||
|
||||
template <class IDType>
|
||||
void ELSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& 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<UniqueID32>;
|
||||
template struct ELSM<UniqueID64>;
|
||||
|
||||
template <class IDType>
|
||||
bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
|
||||
athena::io::FileWriter writer(outPath.getAbsolutePath());
|
||||
|
|
|
@ -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
|
|
@ -12,33 +12,36 @@ class ProjectPath;
|
|||
}
|
||||
|
||||
namespace DataSpec::DNAParticle {
|
||||
template <class IDType>
|
||||
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<IDType> x40_SSWH;
|
||||
ChildResourceFactory<IDType> x50_GPSM;
|
||||
ChildResourceFactory<IDType> x60_EPSM;
|
||||
BoolHelper x70_ZERY;
|
||||
|
||||
void gatherDependencies(std::vector<hecl::ProjectPath>&) const;
|
||||
template <class IDType>
|
||||
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<IDType> identifier;
|
||||
#define BOOL_ENTRY(name, identifier) bool identifier = false;
|
||||
#include "ELSC.def"
|
||||
|
||||
template<typename _Func>
|
||||
void constexpr Enumerate(_Func f) {
|
||||
#define ENTRY(name, identifier) f(FOURCC(name), identifier);
|
||||
#include "ELSC.def"
|
||||
}
|
||||
|
||||
template<typename _Func>
|
||||
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 <class IDType>
|
||||
using ELSM = PPImpl<_ELSM<IDType>>;
|
||||
|
||||
template <class IDType>
|
||||
bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -17,107 +17,39 @@ class ProjectPath;
|
|||
namespace DataSpec::DNAParticle {
|
||||
|
||||
template <class IDType>
|
||||
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<IDType> x54_TEXR;
|
||||
UVElementFactory<IDType> x58_TIND;
|
||||
ChildResourceFactory<IDType> 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<IDType> x8c_ICTS;
|
||||
IntElementFactory x9c_NCSY;
|
||||
IntElementFactory xa0_CSSD;
|
||||
ChildResourceFactory<IDType> xa4_IDTS;
|
||||
IntElementFactory xb4_NDSY;
|
||||
ChildResourceFactory<IDType> xb8_IITS;
|
||||
IntElementFactory xc8_PISY;
|
||||
IntElementFactory xcc_SISY;
|
||||
SpawnSystemKeyframeData<IDType> xd0_KSSM;
|
||||
ChildResourceFactory<IDType> xd4_SSWH;
|
||||
IntElementFactory xe4_SSSD;
|
||||
VectorElementFactory xe8_SSPO;
|
||||
IntElementFactory xf8_SESD;
|
||||
VectorElementFactory xfc_SEPO;
|
||||
ChildResourceFactory<IDType> 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<IDType> 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<IDType> identifier;
|
||||
#define RES_ENTRY(name, identifier) ChildResourceFactory<IDType> identifier;
|
||||
#define KSSM_ENTRY(name, identifier) SpawnSystemKeyframeData<IDType> identifier;
|
||||
#define BOOL_ENTRY(name, identifier, def) bool identifier = def;
|
||||
#include "PART.def"
|
||||
|
||||
GPSM() { x45_25_PMOO = true; }
|
||||
template<typename _Func>
|
||||
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<hecl::ProjectPath>&) const;
|
||||
template<typename _Func>
|
||||
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 <class IDType>
|
||||
using GPSM = PPImpl<_GPSM<IDType>>;
|
||||
|
||||
template <class IDType>
|
||||
bool ExtractGPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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 <class _Basis>
|
||||
struct PPImpl : BigDNA, _Basis {
|
||||
AT_DECL_EXPLICIT_DNA_YAML
|
||||
|
||||
template<typename T>
|
||||
static constexpr bool _shouldStore(T& p, bool defaultBool) {
|
||||
if constexpr (std::is_same_v<T, bool>) {
|
||||
return p != defaultBool;
|
||||
} else if constexpr (std::is_same_v<T, uint32_t>) {
|
||||
return p != 0xffffffff;
|
||||
} else if constexpr (std::is_same_v<T, float>) {
|
||||
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<decltype(p)>;
|
||||
if constexpr (std::is_same_v<Tp, bool>) {
|
||||
DNAFourCC tp(r);
|
||||
if (tp == SBIG('CNST'))
|
||||
p = r.readBool();
|
||||
} else if constexpr (std::is_same_v<Tp, uint32_t>) {
|
||||
DNAFourCC tp(r);
|
||||
if (tp == SBIG('CNST'))
|
||||
p = r.readUint32Big();
|
||||
} else if constexpr (std::is_same_v<Tp, float>) {
|
||||
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<decltype(p)>;
|
||||
DNAFourCC(fcc).write(w);
|
||||
if constexpr (std::is_same_v<Tp, bool>) {
|
||||
w.writeBytes("CNST", 4);
|
||||
w.writeBool(p);
|
||||
} else if constexpr (std::is_same_v<Tp, uint32_t>) {
|
||||
w.writeBytes("CNST", 4);
|
||||
w.writeUint32Big(p);
|
||||
} else if constexpr (std::is_same_v<Tp, float>) {
|
||||
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<decltype(p)>;
|
||||
DNAFourCC(fcc).binarySize(s);
|
||||
if constexpr (std::is_same_v<Tp, bool>) {
|
||||
s += 5;
|
||||
} else if constexpr (std::is_same_v<Tp, uint32_t> || std::is_same_v<Tp, float>) {
|
||||
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<decltype(p)>;
|
||||
if constexpr (std::is_same_v<Tp, bool>) {
|
||||
p = r.readBool();
|
||||
} else if constexpr (std::is_same_v<Tp, uint32_t>) {
|
||||
p = r.readUint32();
|
||||
} else if constexpr (std::is_same_v<Tp, float>) {
|
||||
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<decltype(p)>;
|
||||
if (auto rec = w.enterSubRecord(fcc.toStringView())) {
|
||||
if constexpr (std::is_same_v<Tp, bool>) {
|
||||
w.writeBool(p);
|
||||
} else if constexpr (std::is_same_v<Tp, uint32_t>) {
|
||||
w.writeUint32(p);
|
||||
} else if constexpr (std::is_same_v<Tp, float>) {
|
||||
w.writeFloat(p);
|
||||
} else {
|
||||
p.write(w);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
constexpr void gatherDependencies(std::vector<hecl::ProjectPath>& deps) {
|
||||
_Basis::Enumerate([&](FourCC fcc, auto& p, bool defaultBool = false) {
|
||||
using Tp = std::decay_t<decltype(p)>;
|
||||
if constexpr (!std::is_same_v<Tp, bool> && !std::is_same_v<Tp, uint32_t> && !std::is_same_v<Tp, float>)
|
||||
p.gatherDependencies(deps);
|
||||
});
|
||||
}
|
||||
|
||||
constexpr void gatherDependencies(std::vector<hecl::ProjectPath>& deps) const {
|
||||
const_cast<PPImpl&>(*this).gatherDependencies(deps);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename _Type>
|
||||
struct PEType {
|
||||
using Type = _Type;
|
||||
};
|
||||
|
||||
template <class _Basis>
|
||||
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<decltype(p)>;
|
||||
m_elem = std::make_unique<typename Tp::Type>();
|
||||
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<decltype(p)>;
|
||||
m_elem = std::make_unique<typename Tp::Type>();
|
||||
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<hecl::ProjectPath>& 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<IRealElement> 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<typename _Func>
|
||||
static bool constexpr Lookup(FourCC fcc, _Func f) {
|
||||
switch (fcc.toUint32()) {
|
||||
case SBIG('LFTW'): f(PEType<RELifetimeTween>{}); return true;
|
||||
case SBIG('CNST'): f(PEType<REConstant>{}); return true;
|
||||
case SBIG('CHAN'): f(PEType<RETimeChain>{}); return true;
|
||||
case SBIG('ADD_'): f(PEType<REAdd>{}); return true;
|
||||
case SBIG('CLMP'): f(PEType<REClamp>{}); return true;
|
||||
case SBIG('KEYE'): f(PEType<REKeyframeEmitter>{}); return true;
|
||||
case SBIG('KEYP'): f(PEType<REKeyframeEmitter>{}); return true;
|
||||
case SBIG('IRND'): f(PEType<REInitialRandom>{}); return true;
|
||||
case SBIG('RAND'): f(PEType<RERandom>{}); return true;
|
||||
case SBIG('MULT'): f(PEType<REMultiply>{}); return true;
|
||||
case SBIG('PULS'): f(PEType<REPulse>{}); return true;
|
||||
case SBIG('SCAL'): f(PEType<RETimeScale>{}); return true;
|
||||
case SBIG('RLPT'): f(PEType<RELifetimePercent>{}); return true;
|
||||
case SBIG('SINE'): f(PEType<RESineWave>{}); return true;
|
||||
case SBIG('ISWT'): f(PEType<REInitialSwitch>{}); return true;
|
||||
case SBIG('CLTN'): f(PEType<RECompareLessThan>{}); return true;
|
||||
case SBIG('CEQL'): f(PEType<RECompareEquals>{}); return true;
|
||||
case SBIG('PAP1'): f(PEType<REParticleAdvanceParam1>{}); return true;
|
||||
case SBIG('PAP2'): f(PEType<REParticleAdvanceParam2>{}); return true;
|
||||
case SBIG('PAP3'): f(PEType<REParticleAdvanceParam3>{}); return true;
|
||||
case SBIG('PAP4'): f(PEType<REParticleAdvanceParam4>{}); return true;
|
||||
case SBIG('PAP5'): f(PEType<REParticleAdvanceParam5>{}); return true;
|
||||
case SBIG('PAP6'): f(PEType<REParticleAdvanceParam6>{}); return true;
|
||||
case SBIG('PAP7'): f(PEType<REParticleAdvanceParam7>{}); return true;
|
||||
case SBIG('PAP8'): f(PEType<REParticleAdvanceParam8>{}); return true;
|
||||
case SBIG('PSLL'): f(PEType<REParticleSizeOrLineLength>{}); return true;
|
||||
case SBIG('PRLW'): f(PEType<REParticleRotationOrLineWidth>{}); return true;
|
||||
case SBIG('SUB_'): f(PEType<RESubtract>{}); return true;
|
||||
case SBIG('VMAG'): f(PEType<REVectorMagnitude>{}); return true;
|
||||
case SBIG('VXTR'): f(PEType<REVectorXToReal>{}); return true;
|
||||
case SBIG('VYTR'): f(PEType<REVectorYToReal>{}); return true;
|
||||
case SBIG('VZTR'): f(PEType<REVectorZToReal>{}); return true;
|
||||
case SBIG('CEXT'): f(PEType<RECEXT>{}); return true;
|
||||
case SBIG('ITRL'): f(PEType<REIntTimesReal>{}); return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
static constexpr void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut,
|
||||
const std::unique_ptr<IRealElement>& 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<IIntElement> 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<typename _Func>
|
||||
static bool constexpr Lookup(FourCC fcc, _Func f) {
|
||||
switch (fcc.toUint32()) {
|
||||
case SBIG('KEYE'): f(PEType<IEKeyframeEmitter>{}); return true;
|
||||
case SBIG('KEYP'): f(PEType<IEKeyframeEmitter>{}); return true;
|
||||
case SBIG('DETH'): f(PEType<IEDeath>{}); return true;
|
||||
case SBIG('CLMP'): f(PEType<IEClamp>{}); return true;
|
||||
case SBIG('CHAN'): f(PEType<IETimeChain>{}); return true;
|
||||
case SBIG('ADD_'): f(PEType<IEAdd>{}); return true;
|
||||
case SBIG('CNST'): f(PEType<IEConstant>{}); return true;
|
||||
case SBIG('IMPL'): f(PEType<IEImpulse>{}); return true;
|
||||
case SBIG('ILPT'): f(PEType<IELifetimePercent>{}); return true;
|
||||
case SBIG('IRND'): f(PEType<IEInitialRandom>{}); return true;
|
||||
case SBIG('PULS'): f(PEType<IEPulse>{}); return true;
|
||||
case SBIG('MULT'): f(PEType<IEMultiply>{}); return true;
|
||||
case SBIG('SPAH'): f(PEType<IESampleAndHold>{}); return true;
|
||||
case SBIG('RAND'): f(PEType<IERandom>{}); return true;
|
||||
case SBIG('TSCL'): f(PEType<IETimeScale>{}); return true;
|
||||
case SBIG('GTCP'): f(PEType<IEGTCP>{}); return true;
|
||||
case SBIG('MODU'): f(PEType<IEModulo>{}); return true;
|
||||
case SBIG('SUB_'): f(PEType<IESubtract>{}); return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
static constexpr void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut,
|
||||
const std::unique_ptr<IIntElement>& 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<IVectorElement> 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<typename _Func>
|
||||
static bool constexpr Lookup(FourCC fcc, _Func f) {
|
||||
switch (fcc.toUint32()) {
|
||||
case SBIG('CONE'): f(PEType<VECone>{}); return true;
|
||||
case SBIG('CHAN'): f(PEType<VETimeChain>{}); return true;
|
||||
case SBIG('ANGC'): f(PEType<VEAngleCone>{}); return true;
|
||||
case SBIG('ADD_'): f(PEType<VEAdd>{}); return true;
|
||||
case SBIG('CCLU'): f(PEType<VECircleCluster>{}); return true;
|
||||
case SBIG('CNST'): f(PEType<VEConstant>{}); return true;
|
||||
case SBIG('CIRC'): f(PEType<VECircle>{}); return true;
|
||||
case SBIG('KEYE'): f(PEType<VEKeyframeEmitter>{}); return true;
|
||||
case SBIG('KEYP'): f(PEType<VEKeyframeEmitter>{}); return true;
|
||||
case SBIG('MULT'): f(PEType<VEMultiply>{}); return true;
|
||||
case SBIG('RTOV'): f(PEType<VERealToVector>{}); return true;
|
||||
case SBIG('PULS'): f(PEType<VEPulse>{}); return true;
|
||||
case SBIG('PVEL'): f(PEType<VEParticleVelocity>{}); return true;
|
||||
case SBIG('SPOS'): f(PEType<VESPOS>{}); return true;
|
||||
case SBIG('PLCO'): f(PEType<VEPLCO>{}); return true;
|
||||
case SBIG('PLOC'): f(PEType<VEPLOC>{}); return true;
|
||||
case SBIG('PSOR'): f(PEType<VEPSOR>{}); return true;
|
||||
case SBIG('PSOF'): f(PEType<VEPSOF>{}); return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
static constexpr void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut,
|
||||
const std::unique_ptr<IVectorElement>& 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<IColorElement> 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<typename _Func>
|
||||
static bool constexpr Lookup(FourCC fcc, _Func f) {
|
||||
switch (fcc.toUint32()) {
|
||||
case SBIG('KEYE'): f(PEType<CEKeyframeEmitter>{}); return true;
|
||||
case SBIG('KEYP'): f(PEType<CEKeyframeEmitter>{}); return true;
|
||||
case SBIG('CNST'): f(PEType<CEConstant>{}); return true;
|
||||
case SBIG('CHAN'): f(PEType<CETimeChain>{}); return true;
|
||||
case SBIG('CFDE'): f(PEType<CEFadeEnd>{}); return true;
|
||||
case SBIG('FADE'): f(PEType<CEFade>{}); return true;
|
||||
case SBIG('PULS'): f(PEType<CEPulse>{}); return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
static constexpr void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut,
|
||||
const std::unique_ptr<IColorElement>& 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<IModVectorElement> 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<typename _Func>
|
||||
static bool constexpr Lookup(FourCC fcc, _Func f) {
|
||||
switch (fcc.toUint32()) {
|
||||
case SBIG('IMPL'): f(PEType<MVEImplosion>{}); return true;
|
||||
case SBIG('EMPL'): f(PEType<MVEExponentialImplosion>{}); return true;
|
||||
case SBIG('CHAN'): f(PEType<MVETimeChain>{}); return true;
|
||||
case SBIG('BNCE'): f(PEType<MVEBounce>{}); return true;
|
||||
case SBIG('CNST'): f(PEType<MVEConstant>{}); return true;
|
||||
case SBIG('GRAV'): f(PEType<MVEGravity>{}); return true;
|
||||
case SBIG('EXPL'): f(PEType<MVEExplode>{}); return true;
|
||||
case SBIG('SPOS'): f(PEType<MVESetPosition>{}); return true;
|
||||
case SBIG('LMPL'): f(PEType<MVELinearImplosion>{}); return true;
|
||||
case SBIG('PULS'): f(PEType<MVEPulse>{}); return true;
|
||||
case SBIG('WIND'): f(PEType<MVEWind>{}); return true;
|
||||
case SBIG('SWRL'): f(PEType<MVESwirl>{}); return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
static constexpr void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut,
|
||||
const std::unique_ptr<IModVectorElement>& 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<IEmitterElement> m_elem;
|
||||
operator bool() const { return m_elem.operator bool(); }
|
||||
struct EESimpleEmitterTR;
|
||||
struct EESimpleEmitter;
|
||||
struct VESphere;
|
||||
struct VEAngleSphere;
|
||||
struct _EmitterElementFactory {
|
||||
using PtrType = IEmitterElement;
|
||||
template<typename _Func>
|
||||
static bool constexpr Lookup(FourCC fcc, _Func f) {
|
||||
switch (fcc.toUint32()) {
|
||||
case SBIG('SETR'): f(PEType<EESimpleEmitterTR>{}); return true;
|
||||
case SBIG('SEMR'): f(PEType<EESimpleEmitter>{}); return true;
|
||||
case SBIG('SPHE'): f(PEType<VESphere>{}); return true;
|
||||
case SBIG('ASPH'): f(PEType<VEAngleSphere>{}); return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
static constexpr void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut,
|
||||
const std::unique_ptr<IEmitterElement>& elemPtr) {}
|
||||
};
|
||||
using EmitterElementFactory = PEImpl<_EmitterElementFactory>;
|
||||
|
||||
struct IUVElement : IElement {
|
||||
Delete _d2;
|
||||
virtual void gatherDependencies(std::vector<hecl::ProjectPath>& 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 <typename Tp>
|
||||
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<athena::io::PropType::None>::Do<Tp, athena::Endian::Big>({}, value.emplace(), r);
|
||||
else
|
||||
value = std::nullopt;
|
||||
}
|
||||
void _write(athena::io::IStreamWriter& w) {
|
||||
if (value) {
|
||||
w.writeBytes("CNST", 4);
|
||||
athena::io::Write<athena::io::PropType::None>::Do<Tp, athena::Endian::Big>({}, *value, w);
|
||||
} else {
|
||||
w.writeBytes("NONE", 4);
|
||||
}
|
||||
}
|
||||
void _binarySize(std::size_t& s) {
|
||||
s += 4;
|
||||
if (value)
|
||||
athena::io::BinarySize<athena::io::PropType::None>::Do<Tp, athena::Endian::Big>({}, *value, s);
|
||||
}
|
||||
void _read(athena::io::YAMLDocReader& r) {
|
||||
athena::io::ReadYaml<athena::io::PropType::None>::Do<Tp, athena::Endian::Big>({}, value.emplace(), r);
|
||||
}
|
||||
void _write(athena::io::YAMLDocWriter& w) {
|
||||
athena::io::WriteYaml<athena::io::PropType::None>::Do<Tp, athena::Endian::Big>({}, *value, w);
|
||||
}
|
||||
|
||||
static constexpr void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) {}
|
||||
|
||||
std::optional<Tp> 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<hecl::ProjectPath>& 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<hecl::ProjectPath>& pathsOut) const override {
|
||||
g_curSpec->flattenDependencies(tex, pathsOut);
|
||||
if (tex.isValid())
|
||||
g_curSpec->flattenDependencies(tex, pathsOut);
|
||||
}
|
||||
};
|
||||
|
||||
template <class IDType>
|
||||
struct UVElementFactory : BigDNA {
|
||||
AT_DECL_EXPLICIT_DNA_YAML
|
||||
AT_SUBDECL_DNA
|
||||
DNAFourCC m_type;
|
||||
std::unique_ptr<IUVElement> m_elem;
|
||||
operator bool() const { return m_elem.operator bool(); }
|
||||
struct _UVElementFactory {
|
||||
using PtrType = IUVElement;
|
||||
template<typename _Func>
|
||||
static bool constexpr Lookup(FourCC fcc, _Func f) {
|
||||
switch (fcc.toUint32()) {
|
||||
case SBIG('CNST'): f(PEType<UVEConstant<IDType>>{}); return true;
|
||||
case SBIG('ATEX'): f(PEType<UVEAnimTexture<IDType>>{}); return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
static constexpr void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut,
|
||||
const std::unique_ptr<IUVElement>& elemPtr) {
|
||||
if (elemPtr)
|
||||
elemPtr->gatherDependencies(pathsOut);
|
||||
}
|
||||
};
|
||||
template <class IDType>
|
||||
using UVElementFactory = PEImpl<_UVElementFactory<IDType>>;
|
||||
|
||||
template <class IDType>
|
||||
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<hecl::ProjectPath>& pathsOut) const {
|
||||
if (id.isValid())
|
||||
g_curSpec->flattenDependencies(id, pathsOut);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace DataSpec::DNAParticle
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
#include "DataSpec/DNACommon/SWHC.hpp"
|
||||
|
||||
#include "DataSpec/DNACommon/PAK.hpp"
|
||||
|
||||
#include <logvisor/logvisor.hpp>
|
||||
|
||||
namespace DataSpec::DNAParticle {
|
||||
|
||||
template struct PPImpl<_SWSH<UniqueID32>>;
|
||||
template struct PPImpl<_SWSH<UniqueID64>>;
|
||||
|
||||
AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_SWSH<UniqueID32>>)
|
||||
AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_SWSH<UniqueID64>>)
|
||||
|
||||
template <>
|
||||
std::string_view SWSH<UniqueID32>::DNAType() {
|
||||
return "SWSH<UniqueID32>"sv;
|
||||
|
@ -16,504 +19,6 @@ std::string_view SWSH<UniqueID64>::DNAType() {
|
|||
return "SWSH<UniqueID64>"sv;
|
||||
}
|
||||
|
||||
template <class IDType>
|
||||
void SWSH<IDType>::_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<const uint32_t*>(elem.first.data())) {
|
||||
case SBIG('PSLT'):
|
||||
x0_PSLT.read(r);
|
||||
break;
|
||||
case SBIG('TIME'):
|
||||
x4_TIME.read(r);
|
||||
break;
|
||||
case SBIG('LRAD'):
|
||||
x8_LRAD.read(r);
|
||||
break;
|
||||
case SBIG('RRAD'):
|
||||
xc_RRAD.read(r);
|
||||
break;
|
||||
case SBIG('LENG'):
|
||||
x10_LENG.read(r);
|
||||
break;
|
||||
case SBIG('COLR'):
|
||||
x14_COLR.read(r);
|
||||
break;
|
||||
case SBIG('SIDE'):
|
||||
x18_SIDE.read(r);
|
||||
break;
|
||||
case SBIG('IROT'):
|
||||
x1c_IROT.read(r);
|
||||
break;
|
||||
case SBIG('ROTM'):
|
||||
x20_ROTM.read(r);
|
||||
break;
|
||||
case SBIG('POFS'):
|
||||
x24_POFS.read(r);
|
||||
break;
|
||||
case SBIG('IVEL'):
|
||||
x28_IVEL.read(r);
|
||||
break;
|
||||
case SBIG('NPOS'):
|
||||
x2c_NPOS.read(r);
|
||||
break;
|
||||
case SBIG('VELM'):
|
||||
x30_VELM.read(r);
|
||||
break;
|
||||
case SBIG('VLM2'):
|
||||
x34_VLM2.read(r);
|
||||
break;
|
||||
case SBIG('SPLN'):
|
||||
x38_SPLN.read(r);
|
||||
break;
|
||||
case SBIG('TEXR'):
|
||||
x3c_TEXR.read(r);
|
||||
break;
|
||||
case SBIG('TSPN'):
|
||||
x40_TSPN.read(r);
|
||||
break;
|
||||
case SBIG('LLRD'):
|
||||
x44_24_LLRD = r.readBool();
|
||||
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 <class IDType>
|
||||
void SWSH<IDType>::_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 <class IDType>
|
||||
void SWSH<IDType>::_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 <class IDType>
|
||||
void SWSH<IDType>::_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 <class IDType>
|
||||
void SWSH<IDType>::_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<UniqueID32>)
|
||||
AT_SUBSPECIALIZE_DNA_YAML(SWSH<UniqueID64>)
|
||||
|
||||
template <class IDType>
|
||||
void SWSH<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const {
|
||||
if (x3c_TEXR.m_elem)
|
||||
x3c_TEXR.m_elem->gatherDependencies(pathsOut);
|
||||
}
|
||||
|
||||
template struct SWSH<UniqueID32>;
|
||||
template struct SWSH<UniqueID64>;
|
||||
|
||||
template <class IDType>
|
||||
bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
|
||||
athena::io::FileWriter writer(outPath.getAbsolutePath());
|
||||
|
|
|
@ -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
|
|
@ -16,48 +16,36 @@ class ProjectPath;
|
|||
namespace DataSpec::DNAParticle {
|
||||
|
||||
template <class IDType>
|
||||
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<IDType> x3c_TEXR;
|
||||
IntElementFactory x40_TSPN;
|
||||
union {
|
||||
struct {
|
||||
bool x44_24_LLRD : 1;
|
||||
bool x44_25_CROS : 1;
|
||||
bool x44_26_VLS1 : 1;
|
||||
bool x44_27_VLS2 : 1;
|
||||
bool x44_28_SROT : 1;
|
||||
bool x44_29_WIRE : 1;
|
||||
bool x44_30_TEXW : 1;
|
||||
bool x44_31_AALP : 1;
|
||||
bool x45_24_ZBUF : 1;
|
||||
bool x45_25_ORNT : 1;
|
||||
bool x45_26_CRND : 1;
|
||||
};
|
||||
uint16_t dummy = 0;
|
||||
};
|
||||
#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<IDType> identifier;
|
||||
#define BOOL_ENTRY(name, identifier, def) bool identifier = def;
|
||||
#include "SWHC.def"
|
||||
|
||||
SWSH() { x44_25_CROS = true; }
|
||||
template<typename _Func>
|
||||
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<hecl::ProjectPath>&) const;
|
||||
template<typename _Func>
|
||||
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 <class IDType>
|
||||
using SWSH = PPImpl<_SWSH<IDType>>;
|
||||
|
||||
template <class IDType>
|
||||
bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
|
||||
|
|
|
@ -1,645 +1,13 @@
|
|||
#include "DataSpec/DNACommon/WPSC.hpp"
|
||||
|
||||
#include "DataSpec/DNACommon/PAK.hpp"
|
||||
|
||||
#include <logvisor/logvisor.hpp>
|
||||
|
||||
namespace DataSpec::DNAParticle {
|
||||
|
||||
template <class IDType>
|
||||
void WPSM<IDType>::_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<UniqueID32>>;
|
||||
template struct PPImpl<_WPSM<UniqueID64>>;
|
||||
|
||||
if (auto rec = r.enterSubRecord(elem.first.c_str())) {
|
||||
switch (*reinterpret_cast<const uint32_t*>(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 <class IDType>
|
||||
void WPSM<IDType>::_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 <class IDType>
|
||||
void WPSM<IDType>::_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 <class IDType>
|
||||
void WPSM<IDType>::_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 <class IDType>
|
||||
void WPSM<IDType>::_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<UniqueID32>)
|
||||
AT_SUBSPECIALIZE_DNA_YAML(WPSM<UniqueID64>)
|
||||
AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_WPSM<UniqueID32>>)
|
||||
AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_WPSM<UniqueID64>>)
|
||||
|
||||
template <>
|
||||
std::string_view WPSM<UniqueID32>::DNAType() {
|
||||
|
@ -651,20 +19,6 @@ std::string_view WPSM<UniqueID64>::DNAType() {
|
|||
return "WPSM<UniqueID64>"sv;
|
||||
}
|
||||
|
||||
template <class IDType>
|
||||
void WPSM<IDType>::gatherDependencies(std::vector<hecl::ProjectPath>& 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<UniqueID32>;
|
||||
template struct WPSM<UniqueID64>;
|
||||
|
||||
template <class IDType>
|
||||
bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
|
||||
athena::io::FileWriter writer(outPath.getAbsolutePath());
|
||||
|
|
|
@ -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
|
|
@ -12,53 +12,40 @@ class ProjectPath;
|
|||
}
|
||||
|
||||
namespace DataSpec::DNAParticle {
|
||||
template <class IDType>
|
||||
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<IDType> x34_APSM;
|
||||
ChildResourceFactory<IDType> x44_APS2;
|
||||
ChildResourceFactory<IDType> x54_ASW1;
|
||||
ChildResourceFactory<IDType> x64_ASW2;
|
||||
ChildResourceFactory<IDType> x74_ASW3;
|
||||
ChildResourceFactory<IDType> x84_OHEF;
|
||||
ChildResourceFactory<IDType> 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 <class IDType>
|
||||
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<IDType> identifier;
|
||||
#define RES_ENTRY(name, identifier) ChildResourceFactory<IDType> identifier;
|
||||
#define BOOL_ENTRY(name, identifier, def) bool identifier = def;
|
||||
#include "WPSC.def"
|
||||
|
||||
template<typename _Func>
|
||||
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<hecl::ProjectPath>&) const;
|
||||
template<typename _Func>
|
||||
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 <class IDType>
|
||||
using WPSM = PPImpl<_WPSM<IDType>>;
|
||||
|
||||
template <class IDType>
|
||||
bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
|
||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
|||
Subproject commit db10f0c2ca2ea4ab4b779798b041b3bae0d79937
|
||||
Subproject commit 0b42de34d0439ed46e393e0bb6de1b02641399a1
|
Loading…
Reference in New Issue