From a9a304ea583a16d863eb3347cdf1a8a7114e2e6a Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Mon, 28 Mar 2016 17:07:38 -0700 Subject: [PATCH] Add DPSC and WPSC Particle Fixes --- DataSpec/DNACommon/CMakeLists.txt | 2 + DataSpec/DNACommon/CRSC.hpp | 6 +- DataSpec/DNACommon/DPSC.cpp | 443 +++++++++++ DataSpec/DNACommon/DPSC.hpp | 64 ++ DataSpec/DNACommon/WPSC.cpp | 703 ++++++++++++++++++ DataSpec/DNACommon/WPSC.hpp | 70 ++ DataSpec/DNAMP1/DNAMP1.cpp | 6 + Runtime/Particle/CDecalDataFactory.cpp | 4 +- Runtime/Particle/CDecalDescription.hpp | 2 +- .../Particle/CProjectileWeaponDataFactory.cpp | 6 + Runtime/Particle/CWeaponDescription.hpp | 10 +- 11 files changed, 1306 insertions(+), 10 deletions(-) create mode 100644 DataSpec/DNACommon/DPSC.cpp create mode 100644 DataSpec/DNACommon/DPSC.hpp create mode 100644 DataSpec/DNACommon/WPSC.cpp create mode 100644 DataSpec/DNACommon/WPSC.hpp diff --git a/DataSpec/DNACommon/CMakeLists.txt b/DataSpec/DNACommon/CMakeLists.txt index e316add8e..9f31d59fc 100644 --- a/DataSpec/DNACommon/CMakeLists.txt +++ b/DataSpec/DNACommon/CMakeLists.txt @@ -20,6 +20,8 @@ add_library(DNACommon SWHC.hpp SWHC.cpp CRSC.hpp CRSC.cpp ELSC.hpp ELSC.cpp + WPSC.hpp WPSC.cpp + DPSC.hpp DPSC.cpp ParticleCommon.cpp FONT.hpp FONT.cpp DeafBabe.hpp diff --git a/DataSpec/DNACommon/CRSC.hpp b/DataSpec/DNACommon/CRSC.hpp index 3d8156d2b..360f95154 100644 --- a/DataSpec/DNACommon/CRSC.hpp +++ b/DataSpec/DNACommon/CRSC.hpp @@ -1,5 +1,5 @@ -#ifndef CRSC_HPP -#define CRSC_HPP +#ifndef __COMMON_CRSC_HPP__ +#define __COMMON_CRSC_HPP__ #include "ParticleCommon.hpp" #include "PAK.hpp" @@ -37,4 +37,4 @@ template bool WriteCRSM(const CRSM& crsm, const hecl::ProjectPath& outPath); } } -#endif // CRSC_HPP +#endif // __COMMON_CRSC_HPP__ diff --git a/DataSpec/DNACommon/DPSC.cpp b/DataSpec/DNACommon/DPSC.cpp new file mode 100644 index 000000000..a0a6d1f6f --- /dev/null +++ b/DataSpec/DNACommon/DPSC.cpp @@ -0,0 +1,443 @@ +#include "DPSC.hpp" + +namespace DataSpec +{ +namespace DNAParticle +{ +template +void DPSM::read(athena::io::YAMLDocReader& r) +{ + for (const auto& elem : r.getCurNode()->m_mapChildren) + { + if (elem.first.size() < 4) + { + LogModule.report(logvisor::Warning, "short FourCC in element '%s'", elem.first.c_str()); + continue; + } + + r.enterSubRecord(elem.first.c_str()); + bool loadFirstDesc = false; + uint32_t clsId = *reinterpret_cast(elem.first.c_str()); + switch(clsId) + { + case SBIG('1SZE'): + case SBIG('1LFT'): + case SBIG('1ROT'): + case SBIG('1OFF'): + case SBIG('1CLR'): + case SBIG('1TEX'): + case SBIG('1ADD'): + loadFirstDesc = true; + 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(nullptr); + break; + case SBIG('DMOO'): + x5c_25_DMOO = r.readBool(nullptr); + break; + } + + r.leaveSubRecord(); + } +} + +template +void DPSM::write(athena::io::YAMLDocWriter& w) const +{ + writeQuadDecalInfo(w, x0_quad, true); + writeQuadDecalInfo(w, x1c_quad, false); + + if (x38_DMDL) + { + w.enterSubRecord("DMDL"); + x38_DMDL.write(w); + w.leaveSubRecord(); + } + if (x48_DLFT) + { + w.enterSubRecord("DLFT"); + x48_DLFT.write(w); + w.leaveSubRecord(); + } + if (x4c_DMOP) + { + w.enterSubRecord("DMOP"); + x4c_DMOP.write(w); + w.leaveSubRecord(); + } + if (x50_DMRT) + { + w.enterSubRecord("DMRT"); + x50_DMRT.write(w); + w.leaveSubRecord(); + } + if (x54_DMSC) + { + w.enterSubRecord("DMSC"); + x54_DMSC.write(w); + w.leaveSubRecord(); + } + if (x58_DMCL) + { + w.enterSubRecord("DMCL"); + x54_DMSC.write(w); + w.leaveSubRecord(); + } + if (x5c_24_DMAB) + w.writeBool("DMAB", x5c_24_DMAB); + if (x5c_25_DMOO) + w.writeBool("DMOO", x5c_25_DMOO); +} + +template +template +void DPSM::readQuadDecalInfo(Reader& r, uint32_t clsId, DPSM::SQuadDescr& quad) +{ + switch(clsId) + { + case SBIG('1LFT'): + case SBIG('2LFT'): + quad.x0_LFT.read(r); + break; + case SBIG('1SZE'): + case SBIG('2SZE'): + quad.x4_SZE.read(r); + break; + case SBIG('1ROT'): + case SBIG('2ROT'): + quad.x8_ROT.read(r); + break; + case SBIG('1OFF'): + case SBIG('2OFF'): + quad.xc_OFF.read(r); + break; + case SBIG('1CLR'): + case SBIG('2CLR'): + quad.x10_CLR.read(r); + break; + case SBIG('1TEX'): + case SBIG('2TEX'): + quad.x14_TEX.read(r); + break; + case SBIG('1ADD'): + case SBIG('2ADD'): + quad.x18_ADD.read(r); + break; + } +} + +template +void DPSM::writeQuadDecalInfo(athena::io::YAMLDocWriter& w, const DPSM::SQuadDescr& quad, bool first) const +{ + if (quad.x0_LFT) + { + w.enterSubRecord((first ? "1LFT" : "2LFT")); + quad.x0_LFT.write(w); + w.leaveSubRecord(); + } + + if (quad.x4_SZE) + { + w.enterSubRecord((first ? "1SZE" : "2SZE")); + quad.x4_SZE.write(w); + w.leaveSubRecord(); + } + if (quad.x8_ROT) + { + w.enterSubRecord((first ? "1ROT" : "2ROT")); + quad.x8_ROT.write(w); + w.leaveSubRecord(); + } + if (quad.xc_OFF) + { + w.enterSubRecord((first ? "1OFF" : "2OFF")); + quad.xc_OFF.write(w); + w.leaveSubRecord(); + } + if (quad.x10_CLR) + { + w.enterSubRecord((first ? "1CLR" : "2CLR")); + quad.x10_CLR.write(w); + w.leaveSubRecord(); + } + if (quad.x14_TEX) + { + w.enterSubRecord((first ? "1TEX" : "2TEX")); + quad.x14_TEX.write(w); + w.leaveSubRecord(); + } + if (quad.x18_ADD) + { + w.enterSubRecord((first ? "1ADD" : "2ADD")); + quad.x18_ADD.write(w); + w.leaveSubRecord(); + } +} + +template +size_t DPSM::binarySize(size_t __isz) const +{ + __isz += 4; + __isz = getQuadDecalBinarySize(__isz, x0_quad); + __isz = getQuadDecalBinarySize(__isz, x1c_quad); + if (x38_DMDL) + __isz = x38_DMDL.binarySize(__isz + 4); + if (x48_DLFT) + __isz = x48_DLFT.binarySize(__isz + 4); + if (x4c_DMOP) + __isz = x4c_DMOP.binarySize(__isz + 4); + if (x50_DMRT) + __isz = x50_DMRT.binarySize(__isz + 4); + if (x54_DMSC) + __isz = x54_DMSC.binarySize(__isz + 4); + if (x58_DMCL) + __isz = x58_DMCL.binarySize(__isz + 4); + if (x5c_24_DMAB) + __isz += 9; + if (x5c_25_DMOO) + __isz += 9; + return __isz; +} + +template +size_t DPSM::getQuadDecalBinarySize(size_t __isz, const DPSM::SQuadDescr& quad) const +{ + if (quad.x0_LFT) + __isz = quad.x0_LFT.binarySize(__isz + 4); + if (quad.x4_SZE) + __isz = quad.x4_SZE.binarySize(__isz + 4); + if (quad.x8_ROT) + __isz = quad.x8_ROT.binarySize(__isz + 4); + if (quad.xc_OFF) + __isz = quad.xc_OFF.binarySize(__isz + 4); + if (quad.x10_CLR) + __isz = quad.x10_CLR.binarySize(__isz + 4); + if (quad.x14_TEX) + __isz = quad.x14_TEX.binarySize(__isz + 4); + if (quad.x18_ADD) + __isz = quad.x18_ADD.binarySize(__isz + 4); + + return __isz; +} + +template +void DPSM::read(athena::io::IStreamReader& r) +{ + uint32_t clsId; + r.readBytesToBuf(&clsId, 4); + if (clsId != SBIG('DPSM')) + { + LogModule.report(logvisor::Warning, "non DPSM provided to DPSM parser"); + return; + } + bool loadFirstDesc = false; + r.readBytesToBuf(&clsId, 4); + while (clsId != SBIG('_END')) + { + 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; + 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, "Unknown DPSM class %.4s @%" PRIi64, &clsId, r.position()); + break; + } + r.readBytesToBuf(&clsId, 4); + } +} + +template +void DPSM::write(athena::io::IStreamWriter& w) const +{ + w.writeBytes("DPSM", 4); + writeQuadDecalInfo(w, x0_quad, true); + writeQuadDecalInfo(w, x1c_quad, false); + if (x38_DMDL) + { + w.writeBytes("DMDL", 4); + x38_DMDL.write(w); + } + if (x48_DLFT) + { + w.writeBytes("DLFT", 4); + x48_DLFT.write(w); + } + if (x4c_DMOP) + { + w.writeBytes("DMOP", 4); + x4c_DMOP.write(w); + } + if (x50_DMRT) + { + w.writeBytes("DMRT", 4); + x50_DMRT.write(w); + } + if (x54_DMSC) + { + w.writeBytes("DMSC", 4); + x54_DMSC.write(w); + } + if (x58_DMCL) + { + w.writeBytes("DMCL", 4); + x58_DMCL.write(w); + } + if (x5c_24_DMAB) + w.writeBytes("DMABCNST\x01", 9); + if (x5c_25_DMOO) + w.writeBytes("DMABCNST\x01", 9); + w.writeBytes("_END", 4); +} + +template +void DPSM::writeQuadDecalInfo(athena::io::IStreamWriter& w, const DPSM::SQuadDescr& quad, bool first) const +{ + if (quad.x0_LFT) + { + w.writeBytes((first ? "1LFT" : "2LFT"), 4); + quad.x0_LFT.write(w); + } + if (quad.x4_SZE) + { + w.writeBytes((first ? "1SZE" : "2SZE"), 4); + quad.x4_SZE.write(w); + } + if (quad.x8_ROT) + { + w.writeBytes((first ? "1ROT" : "2ROT"), 4); + quad.x8_ROT.write(w); + } + if (quad.xc_OFF) + { + w.writeBytes((first ? "1OFF" : "2OFF"), 4); + quad.xc_OFF.write(w); + } + if (quad.x10_CLR) + { + w.writeBytes((first ? "1CLR" : "2LCR"), 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 struct DPSM; +template struct DPSM; + +template +bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) +{ + FILE* fp = hecl::Fopen(outPath.getAbsolutePath().c_str(), _S("w")); + if (fp) + { + DPSM dpsm; + dpsm.read(rs); + dpsm.toYAMLFile(fp); + fclose(fp); + return true; + } + return false; +} +template bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); +template bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); + +template +bool WriteDPSM(const DPSM& dpsm, const hecl::ProjectPath& outPath) +{ + athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); + if (w.hasError()) + return false; + dpsm.write(w); + int64_t rem = w.position() % 32; + if (rem) + for (int64_t i=0 ; i<32-rem ; ++i) + w.writeBytes((atInt8*)"\xff", 1); + return true; +} +template bool WriteDPSM(const DPSM& dpsm, const hecl::ProjectPath& outPath); +template bool WriteDPSM(const DPSM& dpsm, const hecl::ProjectPath& outPath); + + +} +} diff --git a/DataSpec/DNACommon/DPSC.hpp b/DataSpec/DNACommon/DPSC.hpp new file mode 100644 index 000000000..3cbe91396 --- /dev/null +++ b/DataSpec/DNACommon/DPSC.hpp @@ -0,0 +1,64 @@ +#ifndef __COMMON_DPSC_HPP__ +#define __COMMON_DPSC_HPP__ + +#include "ParticleCommon.hpp" +#include "PAK.hpp" +#include "athena/FileWriter.hpp" + +namespace DataSpec +{ +namespace DNAParticle +{ + +template +struct DPSM : BigYAML +{ + static const char* DNAType() { return "DPSM"; } + const char* DNATypeV() const { return DNAType(); } + + struct SQuadDescr + { + IntElementFactory x0_LFT; + RealElementFactory x4_SZE; + RealElementFactory x8_ROT; + VectorElementFactory xc_OFF; + ColorElementFactory x10_CLR; + UVElementFactory x14_TEX; + BoolHelper x18_ADD; + }; + + SQuadDescr x0_quad; + SQuadDescr x1c_quad; + ChildResourceFactory x38_DMDL; + IntElementFactory x48_DLFT; + VectorElementFactory x4c_DMOP; + VectorElementFactory x50_DMRT; + VectorElementFactory x54_DMSC; + ColorElementFactory x58_DMCL; + union + { + struct { bool x5c_24_DMAB : 1; bool x5c_25_DMOO : 1;}; + uint8_t dummy; + }; + void read(athena::io::YAMLDocReader& r); + void write(athena::io::YAMLDocWriter& w) const; + template + void readQuadDecalInfo(Reader& r, uint32_t clsId, SQuadDescr& quad); + void writeQuadDecalInfo(athena::io::YAMLDocWriter& w, const SQuadDescr& quad, bool first) const; + size_t binarySize(size_t __isz) const; + size_t getQuadDecalBinarySize(size_t __isz, const SQuadDescr& ) const; + void read(athena::io::IStreamReader& r); + void write(athena::io::IStreamWriter& w) const; + void writeQuadDecalInfo(athena::io::IStreamWriter& w, const SQuadDescr& quad, bool first) const; +}; + +template +bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); + +template +bool WriteDPSM(const DPSM& dpsm, const hecl::ProjectPath& outPath); + +} +} + +#endif // __COMMON_DPSC_HPP__ diff --git a/DataSpec/DNACommon/WPSC.cpp b/DataSpec/DNACommon/WPSC.cpp new file mode 100644 index 000000000..58880c5b5 --- /dev/null +++ b/DataSpec/DNACommon/WPSC.cpp @@ -0,0 +1,703 @@ +#include "WPSC.hpp" + +namespace DataSpec +{ +namespace DNAParticle +{ + +template +void WPSM::read(athena::io::YAMLDocReader& r) +{ + for (const auto& elem : r.getCurNode()->m_mapChildren) + { + if (elem.first.size() < 4) + { + LogModule.report(logvisor::Warning, "short FourCC in element '%s'", elem.first.c_str()); + continue; + } + + r.enterSubRecord(elem.first.c_str()); + + switch (*reinterpret_cast(elem.first.data())) + { + case SBIG('IORN'): + x0_IORN.read(r); + break; + case SBIG('IVEC'): + x4_IVEC.read(r); + break; + case SBIG('PSOV'): + x8_PSOV.read(r); + break; + case SBIG('PSVM'): + xc_PSVM.read(r); + break; + case SBIG('VMD2'): + x10_VMD2.read(r); + break; + case SBIG('PSLT'): + x14_PSLT.read(r); + break; + case SBIG('PSCL'): + x18_PSCL.read(r); + break; + case SBIG('PCOL'): + x1c_PCOL.read(r); + break; + case SBIG('POFS'): + x20_POFS.read(r); + break; + case SBIG('OFST'): + x24_OFST.read(r); + break; + case SBIG('APSO'): + x28_APSO.read(r); + break; + case SBIG('HOMG'): + x29_HOMG.read(r); + break; + case SBIG('AP11'): + x2a_AP11.read(r); + break; + case SBIG('AP21'): + x2b_AP21.read(r); + break; + case SBIG('AS11'): + x2c_AS11.read(r); + break; + case SBIG('AS12'): + x2d_AS12.read(r); + break; + case SBIG('AS13'): + x2e_AS13.read(r); + break; + case SBIG('TRAT'): + x30_TRAT.read(r); + break; + case SBIG('APSM'): + x34_APSM.read(r); + break; + case SBIG('APS2'): + x44_APS2.read(r); + break; + case SBIG('ASW1'): + x54_ASW1.read(r); + break; + case SBIG('ASW2'): + x64_ASW2.read(r); + break; + case SBIG('ASW3'): + x74_ASW3.read(r); + break; + case SBIG('OHEF'): + x84_OHEF.read(r); + break; + case SBIG('COLR'): + x94_COLR.read(r); + break; + case SBIG('EWTR'): + xa4_EWTR.read(r); + break; + case SBIG('LWTR'): + xa5_LWTR.read(r); + break; + case SBIG('SWTR'): + xa6_SWTR.read(r); + break; + case SBIG('PJFX'): + xa8_PJFX = r.readUint32(nullptr); + break; + case SBIG('RNGE'): + xac_RNGE.read(r); + break; + case SBIG('FOFF'): + xb0_FOFF.read(r); + break; + } + + r.leaveSubRecord(); + } +} + +template +void WPSM::write(athena::io::YAMLDocWriter& w) const +{ + if (x0_IORN) + { + w.enterSubRecord("IORN"); + x0_IORN.write(w); + w.leaveSubRecord(); + } + if (x4_IVEC) + { + w.enterSubRecord("IVEC"); + x4_IVEC.write(w); + w.leaveSubRecord(); + } + if (x8_PSOV) + { + w.enterSubRecord("PSOV"); + x8_PSOV.write(w); + w.leaveSubRecord(); + } + if (xc_PSVM) + { + w.enterSubRecord("PSVM"); + xc_PSVM.write(w); + w.leaveSubRecord(); + } + if (x10_VMD2) + { + w.enterSubRecord("VMD2"); + x10_VMD2.write(w); + w.leaveSubRecord(); + } + if (x14_PSLT) + { + w.enterSubRecord("PSLT"); + x14_PSLT.write(w); + w.leaveSubRecord(); + } + if (x18_PSCL) + { + w.enterSubRecord("PSCL"); + x18_PSCL.write(w); + w.leaveSubRecord(); + } + if (x1c_PCOL) + { + w.enterSubRecord("PCOL"); + x1c_PCOL.write(w); + w.leaveSubRecord(); + } + if (x20_POFS) + { + w.enterSubRecord("POFS"); + x20_POFS.write(w); + w.leaveSubRecord(); + } + if (x24_OFST) + { + w.enterSubRecord("OFST"); + x24_OFST.write(w); + w.leaveSubRecord(); + } + if (x28_APSO) + { + w.enterSubRecord("APSO"); + x28_APSO.write(w); + w.leaveSubRecord(); + } + if (x29_HOMG) + { + w.enterSubRecord("HOMG"); + x29_HOMG.write(w); + w.leaveSubRecord(); + } + if (x2a_AP11) + { + w.enterSubRecord("AP11"); + x2a_AP11.write(w); + w.leaveSubRecord(); + } + if (x2b_AP21) + { + w.enterSubRecord("AP21"); + x2b_AP21.write(w); + w.leaveSubRecord(); + } + if (x2c_AS11) + { + w.enterSubRecord("AS11"); + x2c_AS11.write(w); + w.leaveSubRecord(); + } + if (x2d_AS12) + { + w.enterSubRecord("AS12"); + x2d_AS12.write(w); + w.leaveSubRecord(); + } + if (x2e_AS13) + { + w.enterSubRecord("AS13"); + x2e_AS13.write(w); + w.leaveSubRecord(); + } + if (x30_TRAT) + { + w.enterSubRecord("TRAT"); + x30_TRAT.write(w); + w.leaveSubRecord(); + } + if (x34_APSM) + { + w.enterSubRecord("APSM"); + x34_APSM.write(w); + w.leaveSubRecord(); + } + if (x44_APS2) + { + w.enterSubRecord("APS2"); + x44_APS2.write(w); + w.leaveSubRecord(); + } + if (x54_ASW1) + { + w.enterSubRecord("ASW1"); + x54_ASW1.write(w); + w.leaveSubRecord(); + } + if (x64_ASW2) + { + w.enterSubRecord("ASW2"); + x64_ASW2.write(w); + w.leaveSubRecord(); + } + if (x74_ASW3) + { + w.enterSubRecord("ASW3"); + x74_ASW3.write(w); + w.leaveSubRecord(); + } + if (x84_OHEF) + { + w.enterSubRecord("OHEF"); + x84_OHEF.write(w); + w.leaveSubRecord(); + } + if (x94_COLR) + { + w.enterSubRecord("COLR"); + x94_COLR.write(w); + w.leaveSubRecord(); + } + if (!xa4_EWTR) + { + w.enterSubRecord("EWTR"); + xa4_EWTR.write(w); + w.leaveSubRecord(); + } + if (!xa5_LWTR) + { + w.enterSubRecord("LWTR"); + xa5_LWTR.write(w); + w.leaveSubRecord(); + } + if (!xa6_SWTR) + { + w.enterSubRecord("SWTR"); + xa6_SWTR.write(w); + w.leaveSubRecord(); + } + if (xa8_PJFX != ~0) + w.writeUint32("PJFX", xa8_PJFX); + if (xac_RNGE) + { + w.enterSubRecord("RNGE"); + xac_RNGE.write(w); + w.leaveSubRecord(); + } + if (xb0_FOFF) + { + w.enterSubRecord("FOFF"); + xb0_FOFF.write(w); + w.leaveSubRecord(); + } +} + +template +size_t WPSM::binarySize(size_t __isz) const +{ + __isz += 4; + if (x0_IORN) + __isz = x0_IORN.binarySize(__isz + 4); + if (x4_IVEC) + __isz = x4_IVEC.binarySize(__isz + 4); + if (x8_PSOV) + __isz = x8_PSOV.binarySize(__isz + 4); + if (xc_PSVM) + __isz = xc_PSVM.binarySize(__isz + 4); + if (x10_VMD2) + __isz = x10_VMD2.binarySize(__isz + 4); + if (x14_PSLT) + __isz = x14_PSLT.binarySize(__isz + 4); + if (x18_PSCL) + __isz = x18_PSCL.binarySize(__isz + 4); + if (x1c_PCOL) + __isz = x1c_PCOL.binarySize(__isz + 4); + if (x20_POFS) + __isz = x20_POFS.binarySize(__isz + 4); + if (x24_OFST) + __isz = x24_OFST.binarySize(__isz + 4); + if (x28_APSO) + __isz = x28_APSO.binarySize(__isz + 4); + if (x29_HOMG) + __isz = x29_HOMG.binarySize(__isz + 4); + if (x2a_AP11) + __isz = x2a_AP11.binarySize(__isz + 4); + if (x2b_AP21) + __isz = x2b_AP21.binarySize(__isz + 4); + if (x2c_AS11) + __isz = x2c_AS11.binarySize(__isz + 4); + if (x2d_AS12) + __isz = x2d_AS12.binarySize(__isz + 4); + if (x2e_AS13) + __isz = x2e_AS13.binarySize(__isz + 4); + if (x30_TRAT) + __isz = x30_TRAT.binarySize(__isz + 4); + if (x34_APSM) + __isz = x34_APSM.binarySize(__isz + 4); + if (x44_APS2) + __isz = x44_APS2.binarySize(__isz + 4); + if (x54_ASW1) + __isz = x54_ASW1.binarySize(__isz + 4); + if (x64_ASW2) + __isz = x64_ASW2.binarySize(__isz + 4); + if (x74_ASW3) + __isz = x74_ASW3.binarySize(__isz + 4); + if (x84_OHEF) + __isz = x84_OHEF.binarySize(__isz + 4); + if (x94_COLR) + __isz = x94_COLR.binarySize(__isz + 4); + if (!xa4_EWTR) + __isz = xa4_EWTR.binarySize(__isz + 4); + if (!xa5_LWTR) + __isz = xa5_LWTR.binarySize(__isz + 4); + if (!xa6_SWTR) + __isz = xa6_SWTR.binarySize(__isz + 4); + if (xa8_PJFX != ~0) + __isz += 12; + if (xac_RNGE) + __isz = xac_RNGE.binarySize(__isz + 4); + if (xb0_FOFF) + __isz = xb0_FOFF.binarySize(__isz + 4); + + return __isz; +} + +template +void WPSM::read(athena::io::IStreamReader& r) +{ + uint32_t clsId; + r.readBytesToBuf(&clsId, 4); + if (clsId != SBIG('WPSM')) + { + LogModule.report(logvisor::Warning, "non WPSM provided to WPSM parser"); + return; + } + r.readBytesToBuf(&clsId, 4); + while (clsId != SBIG('_END')) + { + switch(clsId) + { + 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; + default: + LogModule.report(logvisor::Fatal, "Unknown WPSM class %.4s @%" PRIi64, &clsId, r.position()); + break; + } + r.readBytesToBuf(&clsId, 4); + } +} + +template +void WPSM::write(athena::io::IStreamWriter &w) const +{ + 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 != ~0) + { + 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); + } + + w.writeBytes("_END", 4); +} + +template struct WPSM; +template struct WPSM; + +template +bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) +{ + FILE* fp = hecl::Fopen(outPath.getAbsolutePath().c_str(), _S("w")); + if (fp) + { + WPSM wpsm; + wpsm.read(rs); + wpsm.toYAMLFile(fp); + fclose(fp); + return true; + } + return false; +} +template bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); +template bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); + +template +bool WriteWPSM(const WPSM& wpsm, const hecl::ProjectPath& outPath) +{ + athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); + if (w.hasError()) + return false; + wpsm.write(w); + int64_t rem = w.position() % 32; + if (rem) + for (int64_t i=0 ; i<32-rem ; ++i) + w.writeBytes((atInt8*)"\xff", 1); + return true; +} +template bool WriteWPSM(const WPSM& wpsm, const hecl::ProjectPath& outPath); +template bool WriteWPSM(const WPSM& wpsm, const hecl::ProjectPath& outPath); + +} +} diff --git a/DataSpec/DNACommon/WPSC.hpp b/DataSpec/DNACommon/WPSC.hpp new file mode 100644 index 000000000..74c6c90f2 --- /dev/null +++ b/DataSpec/DNACommon/WPSC.hpp @@ -0,0 +1,70 @@ +#ifndef __COMMON_WPSC_HPP__ +#define __COMMON_WPSC_HPP__ + +#include "ParticleCommon.hpp" +#include "PAK.hpp" +#include "athena/FileWriter.hpp" + +namespace DataSpec +{ +namespace DNAParticle +{ +template +struct WPSM : BigYAML +{ + static const char* DNAType() { return "WPSM"; } + const char* DNATypeV() const { return DNAType(); } + VectorElementFactory x0_IORN; + VectorElementFactory x4_IVEC; + VectorElementFactory x8_PSOV; + ModVectorElementFactory xc_PSVM; + BoolHelper x10_VMD2; + IntElementFactory x14_PSLT; + VectorElementFactory x18_PSCL; + ColorElementFactory x1c_PCOL; + VectorElementFactory x20_POFS; + VectorElementFactory x24_OFST; + BoolHelper x28_APSO; + BoolHelper x29_HOMG; + BoolHelper x2a_AP11; + BoolHelper x2b_AP21; + BoolHelper x2c_AS11; + BoolHelper x2d_AS12; + BoolHelper x2e_AS13; + RealElementFactory x30_TRAT; + ChildResourceFactory x34_APSM; + ChildResourceFactory x44_APS2; + ChildResourceFactory x54_ASW1; + ChildResourceFactory x64_ASW2; + ChildResourceFactory x74_ASW3; + ChildResourceFactory x84_OHEF; + ChildResourceFactory x94_COLR; + BoolHelper xa4_EWTR; + BoolHelper xa5_LWTR; + BoolHelper xa6_SWTR; + uint32_t xa8_PJFX = ~0; + RealElementFactory xac_RNGE; + RealElementFactory xb0_FOFF; + + void read(athena::io::YAMLDocReader& r); + void write(athena::io::YAMLDocWriter& w) const; + size_t binarySize(size_t __isz) const; + void read(athena::io::IStreamReader& r); + void write(athena::io::IStreamWriter& w) const; + + WPSM() + { + xa4_EWTR = true; xa5_LWTR = true; xa6_SWTR = true; + } +}; + +template +bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); + +template +bool WriteWPSM(const WPSM& wpsm, const hecl::ProjectPath& outPath); + +} +} + +#endif // __COMMON_WPSC_HPP__ diff --git a/DataSpec/DNAMP1/DNAMP1.cpp b/DataSpec/DNAMP1/DNAMP1.cpp index fb08efab9..091b060c3 100644 --- a/DataSpec/DNAMP1/DNAMP1.cpp +++ b/DataSpec/DNAMP1/DNAMP1.cpp @@ -10,6 +10,8 @@ #include "../DNACommon/ELSC.hpp" #include "../DNACommon/SWHC.hpp" #include "../DNACommon/CRSC.hpp" +#include "../DNACommon/WPSC.hpp" +#include "../DNACommon/DPSC.hpp" #include "../DNACommon/FONT.hpp" #include "CMDL.hpp" #include "AFSM.hpp" @@ -298,6 +300,10 @@ ResExtractor PAKBridge::LookupExtractor(const PAK::Entry& entry) return {DNAParticle::ExtractSWSH, nullptr, {_S(".swsh.yaml")}}; case SBIG('CRSC'): return {DNAParticle::ExtractCRSM, nullptr, {_S(".crsm.yaml")}}; + case SBIG('WPSC'): + return {DNAParticle::ExtractWPSM, nullptr, {_S(".wpsm.yaml")}}; + case SBIG('DPSC'): + return {DNAParticle::ExtractDPSM, nullptr, {_S(".dpsm.yaml")}}; case SBIG('FONT'): return {DNAFont::ExtractFONT, nullptr, {_S(".yaml")}}; } diff --git a/Runtime/Particle/CDecalDataFactory.cpp b/Runtime/Particle/CDecalDataFactory.cpp index ca1646828..8635cc804 100644 --- a/Runtime/Particle/CDecalDataFactory.cpp +++ b/Runtime/Particle/CDecalDataFactory.cpp @@ -68,8 +68,8 @@ bool CDecalDataFactory::CreateDPSM(CDecalDescription* desc, CInputStream& in, CS case SBIG('DMDL'): desc->x38_DMDL = CPF::GetModel(in, resPool); break; - case SBIG('DFLT'): - desc->x48_DFLT.reset(CPF::GetIntElement(in)); + case SBIG('DLFT'): + desc->x48_DLFT.reset(CPF::GetIntElement(in)); break; case SBIG('DMOP'): desc->x4c_DMOP.reset(CPF::GetVectorElement(in)); diff --git a/Runtime/Particle/CDecalDescription.hpp b/Runtime/Particle/CDecalDescription.hpp index a91db91a2..8c4319f06 100644 --- a/Runtime/Particle/CDecalDescription.hpp +++ b/Runtime/Particle/CDecalDescription.hpp @@ -27,7 +27,7 @@ public: SQuadDescr x0_Quad; SQuadDescr x1c_Quad; SParticleModel x38_DMDL; - std::unique_ptr x48_DFLT; + std::unique_ptr x48_DLFT; std::unique_ptr x4c_DMOP; std::unique_ptr x50_DMRT; std::unique_ptr x54_DMSC; diff --git a/Runtime/Particle/CProjectileWeaponDataFactory.cpp b/Runtime/Particle/CProjectileWeaponDataFactory.cpp index 50d67a5c1..58ca818c8 100644 --- a/Runtime/Particle/CProjectileWeaponDataFactory.cpp +++ b/Runtime/Particle/CProjectileWeaponDataFactory.cpp @@ -146,6 +146,12 @@ bool CProjectileWeaponDataFactory::CreateWPSM(CWeaponDescription* desc, CInputSt desc->xa8_PJFX = CPF::GetInt(in); break; } + case SBIG('RNGE'): + desc->xac_RNGE.reset(CPF::GetRealElement(in)); + break; + case SBIG('FOFF'): + desc->xb0_FOFF.reset(CPF::GetRealElement(in)); + break; default: { uint32_t clsName = clsId.toUint32(); diff --git a/Runtime/Particle/CWeaponDescription.hpp b/Runtime/Particle/CWeaponDescription.hpp index f13b5020c..fc3678981 100644 --- a/Runtime/Particle/CWeaponDescription.hpp +++ b/Runtime/Particle/CWeaponDescription.hpp @@ -49,10 +49,12 @@ public: SSwooshGeneratorDesc x74_ASW3; SParticleModel x84_OHEF; SCollisionResponseData x94_COLR; - bool xa4_EWTR; - bool xa5_LWTR; - bool xa6_SWTR; - int xa8_PJFX; + bool xa4_EWTR = true; + bool xa5_LWTR = true; + bool xa6_SWTR = true; + u32 xa8_PJFX; + std::unique_ptr xac_RNGE; + std::unique_ptr xb0_FOFF; }; } #endif // __PSHAG_CWEAPONDESCRIPTION_HPP__