2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-05-13 21:51:22 +00:00
Lioncash 7f7a18a708 DataSpec/DNACommon: Resolve indirect includes where applicable
Avoids indirect inclusions where applicable and includes the necessary
headers as used by the interface. This way, it prevents code from
failing to compile due to changes in other header inclusions.
2019-08-23 22:03:03 -04:00

275 lines
10 KiB
C++

#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'),
};
static const std::vector<FourCC> DecalTypes = {SBIG('NCDL'), SBIG('DDCL'), SBIG('CODL'), SBIG('MEDL'), SBIG('GRDL'),
SBIG('ICDL'), SBIG('GODL'), SBIG('WODL'), SBIG('WTDL'), SBIG('3MUD'),
SBIG('3LAV'), SBIG('3SAN'), SBIG('CHDL'), SBIG('ENDL')};
template <>
const char* CRSM<UniqueID32>::DNAType() {
return "CRSM<UniqueID32>";
}
template <>
const char* CRSM<UniqueID64>::DNAType() {
return "CRSM<UniqueID64>";
}
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) -> bool { return clsId == other; });
if (gen != GeneratorTypes.end()) {
x0_generators[clsId].read(r);
continue;
}
auto sfx = std::find_if(SFXTypes.begin(), SFXTypes.end(),
[&clsId](const FourCC& other) -> bool { return clsId == other; });
if (sfx != SFXTypes.end()) {
x10_sfx[clsId] = r.readInt32(clsId.toString().c_str());
continue;
}
auto decal = std::find_if(DecalTypes.begin(), DecalTypes.end(),
[&clsId](const FourCC& other) -> bool { return clsId == other; });
if (decal != DecalTypes.end()) {
x20_decals[clsId].read(r);
continue;
}
if (clsId == SBIG('RNGE'))
x30_RNGE = r.readFloat(nullptr);
else if (clsId == SBIG('FOFF'))
x34_FOFF = r.readFloat(nullptr);
}
}
}
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().c_str()))
pair.second.write(w);
for (const auto& pair : x10_sfx)
if (pair.second != UINT32_MAX)
w.writeUint32(pair.first.toString().c_str(), pair.second);
for (const auto& pair : x20_decals)
if (pair.second)
if (auto rec = w.enterSubRecord(pair.first.toString().c_str()))
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) -> bool { return clsId == other; });
if (gen != GeneratorTypes.end()) {
x0_generators[clsId].read(r);
continue;
}
auto sfx = std::find_if(SFXTypes.begin(), SFXTypes.end(),
[&clsId](const FourCC& other) -> bool { return clsId == other; });
if (sfx != SFXTypes.end()) {
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) -> bool { return clsId == other; });
if (decal != DecalTypes.end()) {
x20_decals[clsId].read(r);
continue;
}
if (clsId == SBIG('RNGE')) {
r.readUint32();
x30_RNGE = r.readFloatBig();
continue;
}
if (clsId == SBIG('FOFF')) {
r.readUint32();
x34_FOFF = r.readFloatBig();
continue;
}
if (clsId != SBIG('_END'))
LogModule.report(logvisor::Fatal, 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());
if (writer.isOpen()) {
CRSM<IDType> crsm;
crsm.read(rs);
athena::io::ToYAMLStream(crsm, writer);
return true;
}
return false;
}
template bool ExtractCRSM<UniqueID32>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template bool ExtractCRSM<UniqueID64>(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
template <class IDType>
bool WriteCRSM(const CRSM<IDType>& crsm, const hecl::ProjectPath& outPath) {
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
return false;
crsm.write(w);
int64_t rem = w.position() % 32;
if (rem)
for (int64_t i = 0; i < 32 - rem; ++i)
w.writeUByte(0xff);
return true;
}
template bool WriteCRSM<UniqueID32>(const CRSM<UniqueID32>& crsm, const hecl::ProjectPath& outPath);
template bool WriteCRSM<UniqueID64>(const CRSM<UniqueID64>& crsm, const hecl::ProjectPath& outPath);
} // namespace DataSpec::DNAParticle