Commit 63a748e7 authored by Jack Andersen's avatar Jack Andersen

Replace manual particle streaming functions with metaclass generation

parent c4ecf972
......@@ -99,9 +99,9 @@ if(MSVC)
endif()
else()
if(${CMAKE_BUILD_TYPE} STREQUAL Debug)
# For libstdc++ shipped with GCC 9.1, this is required to summarize std::string
#add_compile_definitions(_GLIBCXX_DEBUG=1)
if("${CMAKE_BUILD_TYPE}" STREQUAL Debug AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL Clang)
# This is required to summarize std::string when compiled by clang
add_compile_options(-fno-limit-debug-info)
endif()
if(${URDE_VECTOR_ISA} STREQUAL "avx2")
......@@ -138,7 +138,7 @@ else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions")
add_compile_options(-Wall -Wno-multichar -Werror=implicit-fallthrough -Wno-unknown-warning-option
-Wno-lto-type-mismatch -Wno-unused-variable -Wno-unused-private-field
-Wno-unused-function -Wno-sign-compare -Wno-unknown-pragmas -Werror)
-Wno-unused-function -Wno-sign-compare -Wno-unknown-pragmas -Wno-error=cpp -Werror)
add_compile_definitions(FMT_EXCEPTIONS=0)
if(APPLE)
......
......@@ -7,242 +7,23 @@
#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 CPImpl<_CRSM<UniqueID32>>;
template struct CPImpl<_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());
......
This diff is collapsed.
......@@ -7,385 +7,22 @@
namespace DataSpec::DNAParticle {
template struct DPImpl<_DPSM<UniqueID32>>;
template struct DPImpl<_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);