Merge remote-tracking branch 'origin/master' into elitepirate

# Conflicts:
#	Runtime/World/CPatterned.hpp
This commit is contained in:
Luke Street 2020-04-01 15:02:56 -04:00
commit 1e15e0d1f3
277 changed files with 3688 additions and 6747 deletions

View File

@ -1,15 +1,19 @@
#include "AROTBuilder.hpp"
#include <algorithm>
#include <array>
#include "hecl/Blender/Connection.hpp"
#include "../DNAMP1/PATH.hpp"
namespace DataSpec {
logvisor::Module Log("AROTBuilder");
#define AROT_MAX_LEVEL 10
#define AROT_MIN_SUBDIV 10.f
#define AROT_MIN_MODELS 8
#define COLLISION_MIN_NODE_TRIANGLES 8
#define PATH_MIN_NODE_REGIONS 16
constexpr s32 AROT_MAX_LEVEL = 10;
constexpr s32 AROT_MIN_MODELS = 8;
constexpr s32 COLLISION_MIN_NODE_TRIANGLES = 8;
constexpr s32 PATH_MIN_NODE_REGIONS = 16;
constexpr float AROT_MIN_SUBDIV = 10.f;
static zeus::CAABox SplitAABB(const zeus::CAABox& aabb, int i) {
zeus::CAABox pos, neg;
@ -128,7 +132,9 @@ size_t AROTBuilder::BitmapPool::addIndices(const std::set<int>& indices) {
return m_pool.size() - 1;
}
static const uint32_t AROTChildCounts[] = {0, 2, 2, 4, 2, 4, 4, 8};
constexpr std::array<uint32_t, 8> AROTChildCounts{
0, 2, 2, 4, 2, 4, 4, 8,
};
void AROTBuilder::Node::nodeCount(size_t& sz, size_t& idxRefs, BitmapPool& bmpPool, size_t& curOff) {
sz += 1;
@ -176,7 +182,7 @@ void AROTBuilder::Node::writeNodes(athena::io::MemoryWriter& w, int nodeIdx) {
if (curIdx > 65535)
Log.report(logvisor::Fatal, fmt("AROT node exceeds 16-bit node addressing; area too complex"));
int childIndices[8];
std::array<int, 8> childIndices;
for (int k = 0; k < 1 + ((compSubdivs & 0x4) != 0); ++k) {
for (int j = 0; j < 1 + ((compSubdivs & 0x2) != 0); ++j) {
@ -280,17 +286,16 @@ void AROTBuilder::Node::pathWrite(DNAMP1::PATH& path, const zeus::CAABox& curAAB
n.aabb[0] = curAABB.min;
n.aabb[1] = curAABB.max;
n.centroid = curAABB.center();
for (int i = 0; i < 8; ++i)
n.children[i] = 0xffffffff;
std::fill(std::begin(n.children), std::end(n.children), 0xFFFFFFFF);
n.regionCount = childIndices.size();
n.regionStart = path.octreeRegionLookup.size();
for (int r : childIndices)
path.octreeRegionLookup.push_back(r);
} else {
atUint32 children[8];
for (int i = 0; i < 8; ++i) {
std::array<atUint32, 8> children;
for (size_t i = 0; i < children.size(); ++i) {
/* Head recursion (first node will be a leaf) */
childNodes[i].pathWrite(path, SplitAABB(curAABB, i));
childNodes[i].pathWrite(path, SplitAABB(curAABB, static_cast<int>(i)));
children[i] = path.octree.size() - 1;
}
@ -300,8 +305,7 @@ void AROTBuilder::Node::pathWrite(DNAMP1::PATH& path, const zeus::CAABox& curAAB
n.aabb[0] = curAABB.min;
n.aabb[1] = curAABB.max;
n.centroid = curAABB.center();
for (int i = 0; i < 8; ++i)
n.children[i] = children[i];
std::copy(children.cbegin(), children.cend(), std::begin(n.children));
n.regionCount = 0;
n.regionStart = 0;
}
@ -343,18 +347,20 @@ void AROTBuilder::build(std::vector<std::vector<uint8_t>>& secs, const zeus::CAA
auto bmpIt = bmp.cbegin();
if (bmpIt != bmp.cend()) {
int curIdx = 0;
for (size_t w = 0; w < bmpWordCount; ++w) {
for (int b = 0; b < 32; ++b) {
for (size_t word = 0; word < bmpWordCount; ++word) {
for (u32 b = 0; b < 32; ++b) {
if (*bmpIt == curIdx) {
bmpWords[w] |= 1 << b;
bmpWords[word] |= 1U << b;
++bmpIt;
if (bmpIt == bmp.cend())
if (bmpIt == bmp.cend()) {
break;
}
}
++curIdx;
}
if (bmpIt == bmp.cend())
if (bmpIt == bmp.cend()) {
break;
}
}
}
@ -377,12 +383,11 @@ std::pair<std::unique_ptr<uint8_t[]>, uint32_t> AROTBuilder::buildCol(const ColM
std::vector<zeus::CAABox> triBoxes;
triBoxes.reserve(mesh.trianges.size());
for (const ColMesh::Triangle& tri : mesh.trianges) {
triBoxes.emplace_back();
zeus::CAABox& aabb = triBoxes.back();
for (int e = 0; e < 3; ++e) {
const ColMesh::Edge& edge = mesh.edges[tri.edges[e]];
for (int v = 0; v < 2; ++v) {
const auto& vert = mesh.verts[edge.verts[v]];
zeus::CAABox& aabb = triBoxes.emplace_back();
for (const u32 edgeIdx : tri.edges) {
const ColMesh::Edge& edge = mesh.edges[edgeIdx];
for (const u32 vertIdx : edge.verts) {
const auto& vert = mesh.verts[vertIdx];
aabb.accumulateBounds(zeus::CVector3f(vert));
}
}

View File

@ -48,9 +48,7 @@ bool ATBL::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
maxI = std::max(maxI, i);
}
std::vector<uint16_t> vecOut;
vecOut.resize(maxI + 1, 0xffff);
std::vector<uint16_t> vecOut(maxI + 1, 0xffff);
for (const auto& pair : dr.getRootNode()->m_mapChildren) {
unsigned long i = strtoul(pair.first.c_str(), nullptr, 0);
vecOut[i] = hecl::SBig(uint16_t(strtoul(pair.second->m_scalarString.c_str(), nullptr, 0)));

View File

@ -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());

222
DataSpec/DNACommon/CRSC.def Normal file
View File

@ -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

View File

@ -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);

View File

@ -118,40 +118,40 @@ public:
using value_type = uint32_t;
static UniqueID32 kInvalidId;
AT_DECL_EXPLICIT_DNA_YAML
bool isValid() const { return m_id != 0xffffffff && m_id != 0; }
void assign(uint32_t id) { m_id = id ? id : 0xffffffff; }
bool isValid() const noexcept { return m_id != 0xffffffff && m_id != 0; }
void assign(uint32_t id) noexcept { m_id = id ? id : 0xffffffff; }
UniqueID32& operator=(const hecl::ProjectPath& path) {
UniqueID32& operator=(const hecl::ProjectPath& path) noexcept {
assign(path.parsedHash32());
return *this;
}
bool operator!=(const UniqueID32& other) const { return m_id != other.m_id; }
bool operator==(const UniqueID32& other) const { return m_id == other.m_id; }
bool operator<(const UniqueID32& other) const { return m_id < other.m_id; }
uint32_t toUint32() const { return m_id; }
uint64_t toUint64() const { return m_id; }
bool operator!=(const UniqueID32& other) const noexcept { return m_id != other.m_id; }
bool operator==(const UniqueID32& other) const noexcept { return m_id == other.m_id; }
bool operator<(const UniqueID32& other) const noexcept { return m_id < other.m_id; }
uint32_t toUint32() const noexcept { return m_id; }
uint64_t toUint64() const noexcept { return m_id; }
std::string toString() const;
void clear() { m_id = 0xffffffff; }
void clear() noexcept { m_id = 0xffffffff; }
UniqueID32() = default;
UniqueID32(uint32_t idin) { assign(idin); }
UniqueID32() noexcept = default;
UniqueID32(uint32_t idin) noexcept { assign(idin); }
UniqueID32(athena::io::IStreamReader& reader) { read(reader); }
UniqueID32(const hecl::ProjectPath& path) { *this = path; }
UniqueID32(const char* hexStr) {
UniqueID32(const hecl::ProjectPath& path) noexcept { *this = path; }
UniqueID32(const char* hexStr) noexcept {
char copy[9];
strncpy(copy, hexStr, 8);
copy[8] = '\0';
assign(strtoul(copy, nullptr, 16));
}
UniqueID32(const wchar_t* hexStr) {
UniqueID32(const wchar_t* hexStr) noexcept{
wchar_t copy[9];
wcsncpy(copy, hexStr, 8);
copy[8] = L'\0';
assign(wcstoul(copy, nullptr, 16));
}
static constexpr size_t BinarySize() { return 4; }
static constexpr size_t BinarySize() noexcept { return 4; }
};
/** PAK 32-bit Unique ID - writes zero when invalid */
@ -169,39 +169,39 @@ class UniqueID64 : public BigDNA {
public:
using value_type = uint64_t;
AT_DECL_EXPLICIT_DNA_YAML
bool isValid() const { return m_id != 0xffffffffffffffff && m_id != 0; }
void assign(uint64_t id) { m_id = id ? id : 0xffffffffffffffff; }
bool isValid() const noexcept { return m_id != 0xffffffffffffffff && m_id != 0; }
void assign(uint64_t id) noexcept { m_id = id ? id : 0xffffffffffffffff; }
UniqueID64& operator=(const hecl::ProjectPath& path) {
UniqueID64& operator=(const hecl::ProjectPath& path) noexcept {
assign(path.hash().val64());
return *this;
}
bool operator!=(const UniqueID64& other) const { return m_id != other.m_id; }
bool operator==(const UniqueID64& other) const { return m_id == other.m_id; }
bool operator<(const UniqueID64& other) const { return m_id < other.m_id; }
uint64_t toUint64() const { return m_id; }
bool operator!=(const UniqueID64& other) const noexcept { return m_id != other.m_id; }
bool operator==(const UniqueID64& other) const noexcept { return m_id == other.m_id; }
bool operator<(const UniqueID64& other) const noexcept { return m_id < other.m_id; }
uint64_t toUint64() const noexcept { return m_id; }
std::string toString() const;
void clear() { m_id = 0xffffffffffffffff; }
void clear() noexcept { m_id = 0xffffffffffffffff; }
UniqueID64() = default;
UniqueID64(uint64_t idin) { assign(idin); }
UniqueID64() noexcept = default;
UniqueID64(uint64_t idin) noexcept { assign(idin); }
UniqueID64(athena::io::IStreamReader& reader) { read(reader); }
UniqueID64(const hecl::ProjectPath& path) { *this = path; }
UniqueID64(const char* hexStr) {
UniqueID64(const hecl::ProjectPath& path) noexcept { *this = path; }
UniqueID64(const char* hexStr) noexcept {
char copy[17];
std::strncpy(copy, hexStr, 16);
copy[16] = '\0';
assign(std::strtoull(copy, nullptr, 16));
}
UniqueID64(const wchar_t* hexStr) {
UniqueID64(const wchar_t* hexStr) noexcept {
wchar_t copy[17];
std::wcsncpy(copy, hexStr, 16);
copy[16] = L'\0';
assign(std::wcstoull(copy, nullptr, 16));
}
static constexpr size_t BinarySize() { return 8; }
static constexpr size_t BinarySize() noexcept { return 8; }
};
/** PAK 128-bit Unique ID */
@ -220,26 +220,26 @@ private:
public:
using value_type = uint64_t;
AT_DECL_EXPLICIT_DNA_YAML
UniqueID128() {
UniqueID128() noexcept {
m_id.id[0] = 0xffffffffffffffff;
m_id.id[1] = 0xffffffffffffffff;
}
UniqueID128(uint64_t idin) {
UniqueID128(uint64_t idin) noexcept {
m_id.id[0] = idin;
m_id.id[1] = 0;
}
bool isValid() const {
bool isValid() const noexcept {
return m_id.id[0] != 0xffffffffffffffff && m_id.id[0] != 0 && m_id.id[1] != 0xffffffffffffffff && m_id.id[1] != 0;
}
UniqueID128& operator=(const hecl::ProjectPath& path) {
UniqueID128& operator=(const hecl::ProjectPath& path) noexcept {
m_id.id[0] = path.hash().val64();
m_id.id[1] = 0;
return *this;
}
UniqueID128(const hecl::ProjectPath& path) { *this = path; }
UniqueID128(const hecl::ProjectPath& path) noexcept { *this = path; }
bool operator!=(const UniqueID128& other) const {
bool operator!=(const UniqueID128& other) const noexcept {
#if __SSE__
__m128i vcmp = _mm_cmpeq_epi32(m_id.id128, other.m_id.id128);
int vmask = _mm_movemask_epi8(vcmp);
@ -248,7 +248,7 @@ public:
return (m_id.id[0] != other.m_id.id[0]) || (m_id.id[1] != other.m_id.id[1]);
#endif
}
bool operator==(const UniqueID128& other) const {
bool operator==(const UniqueID128& other) const noexcept {
#if __SSE__
__m128i vcmp = _mm_cmpeq_epi32(m_id.id128, other.m_id.id128);
int vmask = _mm_movemask_epi8(vcmp);
@ -257,19 +257,19 @@ public:
return (m_id.id[0] == other.m_id.id[0]) && (m_id.id[1] == other.m_id.id[1]);
#endif
}
bool operator<(const UniqueID128& other) const {
bool operator<(const UniqueID128& other) const noexcept {
return m_id.id[0] < other.m_id.id[0] || (m_id.id[0] == other.m_id.id[0] && m_id.id[1] < other.m_id.id[1]);
}
void clear() {
void clear() noexcept {
m_id.id[0] = 0xffffffffffffffff;
m_id.id[1] = 0xffffffffffffffff;
}
uint64_t toUint64() const { return m_id.id[0]; }
uint64_t toHighUint64() const { return m_id.id[0]; }
uint64_t toLowUint64() const { return m_id.id[1]; }
uint64_t toUint64() const noexcept { return m_id.id[0]; }
uint64_t toHighUint64() const noexcept { return m_id.id[0]; }
uint64_t toLowUint64() const noexcept { return m_id.id[1]; }
std::string toString() const;
static constexpr size_t BinarySize() { return 16; }
static constexpr size_t BinarySize() noexcept { return 16; }
};
/** Casts ID type to its null-zero equivalent */
@ -340,7 +340,7 @@ public:
};
/** Resource cooker function */
typedef std::function<bool(const hecl::ProjectPath&, const hecl::ProjectPath&)> ResCooker;
using ResCooker = std::function<bool(const hecl::ProjectPath&, const hecl::ProjectPath&)>;
/** Mappings of resources involved in extracting characters */
template <class IDType>
@ -377,22 +377,22 @@ inline hecl::ProjectPath GetPathBeginsWith(const hecl::ProjectPath& parentPath,
namespace std {
template <>
struct hash<DataSpec::DNAFourCC> {
size_t operator()(const DataSpec::DNAFourCC& fcc) const { return fcc.toUint32(); }
size_t operator()(const DataSpec::DNAFourCC& fcc) const noexcept{ return fcc.toUint32(); }
};
template <>
struct hash<DataSpec::UniqueID32> {
size_t operator()(const DataSpec::UniqueID32& id) const { return id.toUint32(); }
size_t operator()(const DataSpec::UniqueID32& id) const noexcept{ return id.toUint32(); }
};
template <>
struct hash<DataSpec::UniqueID64> {
size_t operator()(const DataSpec::UniqueID64& id) const { return id.toUint64(); }
size_t operator()(const DataSpec::UniqueID64& id) const noexcept{ return id.toUint64(); }
};
template <>
struct hash<DataSpec::UniqueID128> {
size_t operator()(const DataSpec::UniqueID128& id) const { return id.toHighUint64() ^ id.toLowUint64(); }
size_t operator()(const DataSpec::UniqueID128& id) const noexcept { return id.toHighUint64() ^ id.toLowUint64(); }
};
} // namespace std

View File

@ -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());

View File

@ -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

View File

@ -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);

View File

@ -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());

View File

@ -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

View File

@ -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);

View File

@ -27,11 +27,11 @@ void MAPA::Enumerate<BigDNA::Read>(typename Read::StreamT& __dna_reader) {
/* version */
version = __dna_reader.readUint32Big();
if (version == 2)
header.reset(new HeaderMP1);
header = std::make_unique<HeaderMP1>();
else if (version == 3)
header.reset(new HeaderMP2);
header = std::make_unique<HeaderMP2>();
else if (version == 5)
header.reset(new HeaderMP3);
header = std::make_unique<HeaderMP3>();
else {
LogDNACommon.report(logvisor::Error, fmt("invalid MAPA version"));
return;
@ -41,10 +41,11 @@ void MAPA::Enumerate<BigDNA::Read>(typename Read::StreamT& __dna_reader) {
for (atUint32 i = 0; i < header->mappableObjectCount(); i++) {
std::unique_ptr<IMappableObject> mo = nullptr;
if (version != 5)
mo.reset(new MappableObjectMP1_2);
else
mo.reset(new MappableObjectMP3);
if (version != 5) {
mo = std::make_unique<MappableObjectMP1_2>();
} else {
mo = std::make_unique<MappableObjectMP3>();
}
mo->read(__dna_reader);
mappableObjects.push_back(std::move(mo));
}

File diff suppressed because it is too large Load Diff

141
DataSpec/DNACommon/PART.def Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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());

View File

@ -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

View File

@ -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);

View File

@ -17,9 +17,11 @@ static logvisor::Module Log("libpng");
static int CountBits(uint32_t n) {
int ret = 0;
for (int i = 0; i < 32; ++i)
if (((n >> i) & 1) != 0)
for (int i = 0; i < 32; ++i) {
if (((n >> i) & 1) != 0) {
++ret;
}
}
return ret;
}
@ -28,27 +30,29 @@ static void BoxFilter(const uint8_t* input, unsigned chanCount, unsigned inWidth
bool dxt1) {
unsigned mipWidth = 1;
unsigned mipHeight = 1;
if (inWidth > 1)
if (inWidth > 1) {
mipWidth = inWidth / 2;
if (inHeight > 1)
}
if (inHeight > 1) {
mipHeight = inHeight / 2;
}
unsigned y, x, c;
for (y = 0; y < mipHeight; ++y) {
unsigned miplineBase = mipWidth * y;
unsigned in1LineBase = inWidth * (y * 2);
unsigned in2LineBase = inWidth * (y * 2 + 1);
for (x = 0; x < mipWidth; ++x) {
for (unsigned y = 0; y < mipHeight; ++y) {
const unsigned miplineBase = mipWidth * y;
const unsigned in1LineBase = inWidth * (y * 2);
const unsigned in2LineBase = inWidth * (y * 2 + 1);
for (unsigned x = 0; x < mipWidth; ++x) {
uint8_t* out = &output[(miplineBase + x) * chanCount];
for (c = 0; c < chanCount; ++c) {
for (unsigned c = 0; c < chanCount; ++c) {
uint32_t tmp = 0;
tmp += input[(in1LineBase + (x * 2)) * chanCount + c];
tmp += input[(in1LineBase + (x * 2 + 1)) * chanCount + c];
tmp += input[(in2LineBase + (x * 2)) * chanCount + c];
tmp += input[(in2LineBase + (x * 2 + 1)) * chanCount + c];
out[c] = uint8_t(tmp / 4);
if (c == 3 && dxt1)
if (c == 3 && dxt1) {
out[c] = uint8_t(out[c] ? 0xff : 0x0);
}
}
}
}
@ -65,52 +69,52 @@ static size_t ComputeMippedTexelCount(unsigned inWidth, unsigned inHeight) {
}
/* GX uses this upsampling technique to extract full 8-bit range */
constexpr uint8_t Convert3To8(uint8_t v) {
static constexpr uint8_t Convert3To8(uint8_t v) {
/* Swizzle bits: 00000123 -> 12312312 */
return (v << 5) | (v << 2) | (v >> 1);
}
constexpr uint8_t Convert8To3(uint8_t v) { return v >> 5; }
static constexpr uint8_t Convert8To3(uint8_t v) { return v >> 5; }
constexpr uint8_t Convert4To8(uint8_t v) {
static constexpr uint8_t Convert4To8(uint8_t v) {
/* Swizzle bits: 00001234 -> 12341234 */
return (v << 4) | v;
}
constexpr uint8_t Convert8To4(uint8_t v) { return v >> 4; }
static constexpr uint8_t Convert8To4(uint8_t v) { return v >> 4; }
constexpr uint8_t Convert5To8(uint8_t v) {
static constexpr uint8_t Convert5To8(uint8_t v) {
/* Swizzle bits: 00012345 -> 12345123 */
return (v << 3) | (v >> 2);
}
constexpr uint8_t Convert8To5(uint8_t v) { return v >> 3; }
static constexpr uint8_t Convert8To5(uint8_t v) { return v >> 3; }
constexpr uint8_t Convert6To8(uint8_t v) {
static constexpr uint8_t Convert6To8(uint8_t v) {
/* Swizzle bits: 00123456 -> 12345612 */
return (v << 2) | (v >> 4);
}
constexpr uint8_t Convert8To6(uint8_t v) { return v >> 2; }
static constexpr uint8_t Convert8To6(uint8_t v) { return v >> 2; }
static uint8_t Lookup4BPP(const uint8_t* texels, int width, int x, int y) {
int bwidth = (width + 7) / 8;
int bx = x / 8;
int by = y / 8;
int rx = x % 8;
int ry = y % 8;
int bidx = by * bwidth + bx;
const int bwidth = (width + 7) / 8;
const int bx = x / 8;
const int by = y / 8;
const int rx = x % 8;
const int ry = y % 8;
const int bidx = by * bwidth + bx;
const uint8_t* btexels = &texels[32 * bidx];
return btexels[ry * 4 + rx / 2] >> ((rx & 1) ? 0 : 4) & 0xf;
}
static void Set4BPP(uint8_t* texels, int width, int x, int y, uint8_t val) {
int bwidth = (width + 7) / 8;
int bx = x / 8;
int by = y / 8;
int rx = x % 8;
int ry = y % 8;
int bidx = by * bwidth + bx;
const int bwidth = (width + 7) / 8;
const int bx = x / 8;
const int by = y / 8;
const int rx = x % 8;
const int ry = y % 8;
const int bidx = by * bwidth + bx;
uint8_t* btexels = &texels[32 * bidx];
btexels[ry * 4 + rx / 2] |= (val & 0xf) << ((rx & 1) ? 0 : 4);
}
@ -127,68 +131,68 @@ static uint8_t Lookup8BPP(const uint8_t* texels, int width, int x, int y) {
}
static void Set8BPP(uint8_t* texels, int width, int x, int y, uint8_t val) {
int bwidth = (width + 7) / 8;
int bx = x / 8;
int by = y / 4;
int rx = x % 8;
int ry = y % 4;
int bidx = by * bwidth + bx;
const int bwidth = (width + 7) / 8;
const int bx = x / 8;
const int by = y / 4;
const int rx = x % 8;
const int ry = y % 4;
const int bidx = by * bwidth + bx;
uint8_t* btexels = &texels[32 * bidx];
btexels[ry * 8 + rx] = val;
}
static uint16_t Lookup16BPP(const uint8_t* texels, int width, int x, int y) {
int bwidth = (width + 3) / 4;
int bx = x / 4;
int by = y / 4;
int rx = x % 4;
int ry = y % 4;
const int bwidth = (width + 3) / 4;
const int bx = x / 4;
const int by = y / 4;
const int rx = x % 4;
const int ry = y % 4;
int bidx = by * bwidth + bx;
const uint16_t* btexels = (uint16_t*)&texels[32 * bidx];
const uint16_t* btexels = reinterpret_cast<const uint16_t*>(&texels[32 * bidx]);
return btexels[ry * 4 + rx];
}
static void Set16BPP(uint8_t* texels, int width, int x, int y, uint16_t val) {
int bwidth = (width + 3) / 4;
int bx = x / 4;
int by = y / 4;
int rx = x % 4;
int ry = y % 4;
int bidx = by * bwidth + bx;
uint16_t* btexels = (uint16_t*)&texels[32 * bidx];
const int bwidth = (width + 3) / 4;
const int bx = x / 4;
const int by = y / 4;
const int rx = x % 4;
const int ry = y % 4;
const int bidx = by * bwidth + bx;
auto* btexels = reinterpret_cast<uint16_t*>(&texels[32 * bidx]);
btexels[ry * 4 + rx] = val;
}
static void LookupRGBA8(const uint8_t* texels, int width, int x, int y, uint8_t* r, uint8_t* g, uint8_t* b,
uint8_t* a) {
int bwidth = (width + 3) / 4;
int bx = x / 4;
int by = y / 4;
int rx = x % 4;
int ry = y % 4;
int bidx = (by * bwidth + bx) * 2;
const uint16_t* artexels = (uint16_t*)&texels[32 * bidx];
const uint16_t* gbtexels = (uint16_t*)&texels[32 * (bidx + 1)];
uint16_t ar = hecl::SBig(artexels[ry * 4 + rx]);
const int bwidth = (width + 3) / 4;
const int bx = x / 4;
const int by = y / 4;
const int rx = x % 4;
const int ry = y % 4;
const int bidx = (by * bwidth + bx) * 2;
const auto* artexels = reinterpret_cast<const uint16_t*>(&texels[32 * bidx]);
const auto* gbtexels = reinterpret_cast<const uint16_t*>(&texels[32 * (bidx + 1)]);
const uint16_t ar = hecl::SBig(artexels[ry * 4 + rx]);
*a = ar >> 8 & 0xff;
*r = ar & 0xff;
uint16_t gb = hecl::SBig(gbtexels[ry * 4 + rx]);
const uint16_t gb = hecl::SBig(gbtexels[ry * 4 + rx]);
*g = gb >> 8 & 0xff;
*b = gb & 0xff;
}
static void SetRGBA8(uint8_t* texels, int width, int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
int bwidth = (width + 3) / 4;
int bx = x / 4;
int by = y / 4;
int rx = x % 4;
int ry = y % 4;
int bidx = (by * bwidth + bx) * 2;
uint16_t* artexels = (uint16_t*)&texels[32 * bidx];
uint16_t* gbtexels = (uint16_t*)&texels[32 * (bidx + 1)];
uint16_t ar = (a << 8) | r;
const int bwidth = (width + 3) / 4;
const int bx = x / 4;
const int by = y / 4;
const int rx = x % 4;
const int ry = y % 4;
const int bidx = (by * bwidth + bx) * 2;
uint16_t* artexels = reinterpret_cast<uint16_t*>(&texels[32 * bidx]);
uint16_t* gbtexels = reinterpret_cast<uint16_t*>(&texels[32 * (bidx + 1)]);
const uint16_t ar = (a << 8) | r;
artexels[ry * 4 + rx] = hecl::SBig(ar);
uint16_t gb = (g << 8) | b;
const uint16_t gb = (g << 8) | b;
gbtexels[ry * 4 + rx] = hecl::SBig(gb);
}
@ -199,8 +203,9 @@ static void DecodeI4(png_structp png, png_infop info, const uint8_t* texels, int
std::unique_ptr<uint8_t[]> buf(new uint8_t[width]);
// memset(buf.get(), 0, width);
for (int y = height - 1; y >= 0; --y) {
for (int x = 0; x < width; ++x)
for (int x = 0; x < width; ++x) {
buf[x] = Convert4To8(Lookup4BPP(texels, width, x, y));
}
png_write_row(png, buf.get());
}
}
@ -223,16 +228,18 @@ static void DecodeI8(png_structp png, png_infop info, const uint8_t* texels, int
png_write_info(png, info);
std::unique_ptr<uint8_t[]> buf(new uint8_t[width]);
for (int y = height - 1; y >= 0; --y) {
for (int x = 0; x < width; ++x)
for (int x = 0; x < width; ++x) {
buf[x] = Lookup8BPP(texels, width, x, y);
}
png_write_row(png, buf.get());
}
}
static void EncodeI8(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) {
for (int y = height - 1; y >= 0; --y) {
for (int x = 0; x < width; ++x)
for (int x = 0; x < width; ++x) {
Set8BPP(texels, width, x, y, rgbaIn[x]);
}
rgbaIn += width;
}
}
@ -244,7 +251,7 @@ static void DecodeIA4(png_structp png, png_infop info, const uint8_t* texels, in
std::unique_ptr<uint8_t[]> buf(new uint8_t[width * 2]);
for (int y = height - 1; y >= 0; --y) {
for (int x = 0; x < width; ++x) {
uint8_t texel = Lookup8BPP(texels, width, x, y);
const uint8_t texel = Lookup8BPP(texels, width, x, y);
buf[x * 2 ] = Convert4To8(texel & 0xf);
buf[x * 2 + 1] = Convert4To8(texel >> 4 & 0xf);
}
@ -274,22 +281,24 @@ static void DecodeIA8(png_structp png, png_infop info, const uint8_t* texels, in
png_write_info(png, info);
std::unique_ptr<uint16_t[]> buf(new uint16_t[width]);
for (int y = height - 1; y >= 0; --y) {
for (int x = 0; x < width; ++x)
for (int x = 0; x < width; ++x) {
buf[x] = hecl::SBig(Lookup16BPP(texels, width, x, y));
png_write_row(png, (png_bytep)buf.get());
}
png_write_row(png, reinterpret_cast<png_bytep>(buf.get()));
}
}
static void EncodeIA8(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) {
for (int y = height - 1; y >= 0; --y) {
for (int x = 0; x < width; ++x)
Set16BPP(texels, width, x, y, hecl::SBig(((uint16_t*)rgbaIn)[x]));
for (int x = 0; x < width; ++x) {
Set16BPP(texels, width, x, y, hecl::SBig(reinterpret_cast<const uint16_t*>(rgbaIn)[x]));
}
rgbaIn += width * 2;
}
}
static const uint8_t* DecodePalette(png_structp png, png_infop info, int numEntries, const uint8_t* data) {
uint32_t format = hecl::SBig(*(uint32_t*)data);
const auto format = hecl::SBig(*reinterpret_cast<const uint32_t*>(data));
data += 8;
png_color cEntries[256];
png_byte aEntries[256];
@ -306,9 +315,9 @@ static const uint8_t* DecodePalette(png_structp png, png_infop info, int numEntr
}
case 1: {
/* RGB565 */
const uint16_t* data16 = (uint16_t*)data;
const auto* data16 = reinterpret_cast<const uint16_t*>(data);
for (int e = 0; e < numEntries; ++e) {
uint16_t texel = hecl::SBig(data16[e]);
const uint16_t texel = hecl::SBig(data16[e]);
cEntries[e].red = Convert5To8(texel >> 11 & 0x1f);
cEntries[e].green = Convert6To8(texel >> 5 & 0x3f);
cEntries[e].blue = Convert5To8(texel & 0x1f);
@ -317,9 +326,9 @@ static const uint8_t* DecodePalette(png_structp png, png_infop info, int numEntr
}
case 2: {
/* RGB5A3 */
const uint16_t* data16 = (uint16_t*)data;
const auto* data16 = reinterpret_cast<const uint16_t*>(data);
for (int e = 0; e < numEntries; ++e) {
uint16_t texel = hecl::SBig(data16[e]);
const uint16_t texel = hecl::SBig(data16[e]);
if (texel & 0x8000) {
cEntries[e].red = Convert5To8(texel >> 10 & 0x1f);
cEntries[e].green = Convert5To8(texel >> 5 & 0x1f);
@ -336,8 +345,9 @@ static const uint8_t* DecodePalette(png_structp png, png_infop info, int numEntr
}
}
png_set_PLTE(png, info, cEntries, numEntries);
if (format == 0 || format == 2)
if (format == 0 || format == 2) {
png_set_tRNS(png, info, aEntries, numEntries, nullptr);
}
data += numEntries * 2;
return data;
}
@ -360,20 +370,21 @@ static uint8_t* EncodePalette(png_structp png, png_infop info, int numEntries, u
uint32_t format = 0; /* Default IA8 */
for (int e = 0; e < pngNumEntries; ++e) {
png_colorp ent = &cEntries[e];
const png_const_colorp ent = &cEntries[e];
if (ent->red != ent->green || ent->red != ent->blue) {
if (pngNumAEntries)
if (pngNumAEntries) {
format = 2; /* RGB565 if not greyscale and has alpha */
else
} else {
format = 1; /* RGB565 if not greyscale */
}
break;
}
}
((uint32_t*)data)[0] = hecl::SBig(format);
reinterpret_cast<uint32_t*>(data)[0] = hecl::SBig(format);
data += 4;
((uint16_t*)data)[0] = hecl::SBig(uint16_t(numEntries));
((uint16_t*)data)[1] = hecl::SBig(uint16_t(1));
reinterpret_cast<uint16_t*>(data)[0] = hecl::SBig(uint16_t(numEntries));
reinterpret_cast<uint16_t*>(data)[1] = hecl::SBig(uint16_t(1));
data += 4;
switch (format) {
@ -393,7 +404,7 @@ static uint8_t* EncodePalette(png_structp png, png_infop info, int numEntries, u
}
case 1: {
/* RGB565 */
uint16_t* data16 = (uint16_t*)data;
uint16_t* data16 = reinterpret_cast<uint16_t*>(data);
for (int e = 0; e < numEntries; ++e) {
if (e < pngNumEntries) {
uint16_t texel = Convert8To5(cEntries[e].red) << 11;
@ -408,11 +419,12 @@ static uint8_t* EncodePalette(png_structp png, png_infop info, int numEntries, u
}
case 2: {
/* RGB5A3 */
uint16_t* data16 = (uint16_t*)data;
auto* data16 = reinterpret_cast<uint16_t*>(data);
for (int e = 0; e < numEntries; ++e) {
uint8_t alpha = 0;
if (e < pngNumAEntries)
if (e < pngNumAEntries) {
alpha = aEntries[e];
}
uint16_t texel = 0;
if (alpha == 0xff) {
@ -440,7 +452,7 @@ static uint8_t* EncodePalette(png_structp png, png_infop info, int numEntries, u
}
static const uint8_t* DecodePaletteSPLT(png_structp png, png_infop info, int numEntries, const uint8_t* data) {
uint32_t format = hecl::SBig(*(uint32_t*)data);
const auto format = hecl::SBig(*reinterpret_cast<const uint32_t*>(data));
data += 8;
png_sPLT_entry entries[256] = {};
png_sPLT_t GXEntry = {(char*)"GXPalette", 8, entries, numEntries};
@ -459,9 +471,9 @@ static const uint8_t* DecodePaletteSPLT(png_structp png, png_infop info, int num
case 1: {
/* RGB565 */
GXEntry.name = (char*)"GX_RGB565";
const uint16_t* data16 = (uint16_t*)data;
const auto* data16 = reinterpret_cast<const uint16_t*>(data);
for (int e = 0; e < numEntries; ++e) {
uint16_t texel = hecl::SBig(data16[e]);
const uint16_t texel = hecl::SBig(data16[e]);
entries[e].red = Convert5To8(texel >> 11 & 0x1f);
entries[e].green = Convert6To8(texel >> 5 & 0x3f);
entries[e].blue = Convert5To8(texel & 0x1f);
@ -472,9 +484,9 @@ static const uint8_t* DecodePaletteSPLT(png_structp png, png_infop info, int num
case 2: {
/* RGB5A3 */
GXEntry.name = (char*)"GX_RGB5A3";
const uint16_t* data16 = (uint16_t*)data;
const auto* data16 = reinterpret_cast<const uint16_t*>(data);
for (int e = 0; e < numEntries; ++e) {
uint16_t texel = hecl::SBig(data16[e]);
const uint16_t texel = hecl::SBig(data16[e]);
if (texel & 0x8000) {
entries[e].red = Convert5To8(texel >> 10 & 0x1f);
entries[e].green = Convert5To8(texel >> 5 & 0x1f);
@ -497,12 +509,12 @@ static const uint8_t* DecodePaletteSPLT(png_structp png, png_infop info, int num
static uint8_t* EncodePaletteSPLT(png_structp png, png_infop info, int numEntries, uint8_t* data) {
png_sPLT_tp palettes;
int pngNumPalettes = png_get_sPLT(png, info, &palettes);
const int pngNumPalettes = png_get_sPLT(png, info, &palettes);
int pngNumEntries = 0;
png_sPLT_entryp cEntries = nullptr;
for (int i = 0; i < pngNumPalettes; ++i) {
png_sPLT_tp palette = &palettes[i];
if (!strncmp(palette->name, "GX_", 3)) {
const png_const_sPLT_tp palette = &palettes[i];
if (strncmp(palette->name, "GX_", 3) == 0) {
pngNumEntries = palette->nentries;
cEntries = palette->entries;
break;
@ -511,20 +523,21 @@ static uint8_t* EncodePaletteSPLT(png_structp png, png_infop info, int numEntrie
uint32_t format = 2; /* Default RGB5A3 */
for (int e = 0; e < pngNumEntries; ++e) {
png_sPLT_entryp ent = &cEntries[e];
const png_const_sPLT_entryp ent = &cEntries[e];
if (ent->red != ent->green || ent->red != ent->blue) {
if (ent->alpha) {
format = 2;
break;
} else
} else {
format = 1;
}
}
}
((uint32_t*)data)[0] = hecl::SBig(format);
reinterpret_cast<uint32_t*>(data)[0] = hecl::SBig(format);
data += 4;
((uint16_t*)data)[0] = hecl::SBig(uint16_t(1));
((uint16_t*)data)[1] = hecl::SBig(uint16_t(numEntries));
reinterpret_cast<uint16_t*>(data)[0] = hecl::SBig(uint16_t(1));
reinterpret_cast<uint16_t*>(data)[1] = hecl::SBig(uint16_t(numEntries));
data += 4;
switch (format) {
@ -543,7 +556,7 @@ static uint8_t* EncodePaletteSPLT(png_structp png, png_infop info, int numEntrie
}
case 1: {
/* RGB565 */
uint16_t* data16 = (uint16_t*)data;
auto* data16 = reinterpret_cast<uint16_t*>(data);
for (int e = 0; e < numEntries; ++e) {
if (e < pngNumEntries) {
uint16_t texel = Convert8To5(cEntries[e].red) << 11;
@ -558,7 +571,7 @@ static uint8_t* EncodePaletteSPLT(png_structp png, png_infop info, int numEntrie
}
case 2: {
/* RGB5A3 */
uint16_t* data16 = (uint16_t*)data;
auto* data16 = reinterpret_cast<uint16_t*>(data);
for (int e = 0; e < numEntries; ++e) {
uint16_t texel = 0;
if (cEntries && cEntries[e].alpha == 0xff) {
@ -599,8 +612,9 @@ static void DecodeC4(png_structp png, png_infop info, const uint8_t* data, int w
png_write_info(png, info);
std::unique_ptr<uint8_t[]> buf(new uint8_t[width]);
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x)
for (int x = 0; x < width; ++x) {
buf[x] = Lookup4BPP(texels, width, x, y);
}
png_write_row(png, buf.get());
}
}
@ -608,8 +622,9 @@ static void DecodeC4(png_structp png, png_infop info, const uint8_t* data, int w
static void EncodeC4(png_structp png, png_infop info, const uint8_t* rgbaIn, uint8_t* data, int width, int height) {
uint8_t* texels = EncodePaletteSPLT(png, info, 16, data);
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x)
for (int x = 0; x < width; ++x) {
Set4BPP(texels, width, x, y, rgbaIn[x]);
}
rgbaIn += width;
}
}
@ -621,8 +636,9 @@ static void DecodeC8(png_structp png, png_infop info, const uint8_t* data, int w
png_write_info(png, info);
std::unique_ptr<uint8_t[]> buf(new uint8_t[width]);
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x)
for (int x = 0; x < width; ++x) {
buf[x] = Lookup8BPP(texels, width, x, y);
}
png_write_row(png, buf.get());
}
}
@ -630,8 +646,9 @@ static void DecodeC8(png_structp png, png_infop info, const uint8_t* data, int w
static void EncodeC8(png_structp png, png_infop info, const uint8_t* rgbaIn, uint8_t* data, int width, int height) {
uint8_t* texels = EncodePalette(png, info, 256, data);
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x)
for (int x = 0; x < width; ++x) {
Set8BPP(texels, width, x, y, rgbaIn[x]);
}
rgbaIn += width;
}
}
@ -643,7 +660,7 @@ static void DecodeRGB565(png_structp png, png_infop info, const uint8_t* texels,
std::unique_ptr<uint8_t[]> buf(new uint8_t[width * 3]);
for (int y = height - 1; y >= 0; --y) {
for (int x = 0; x < width; ++x) {
uint16_t texel = hecl::SBig(Lookup16BPP(texels, width, x, y));
const uint16_t texel = hecl::SBig(Lookup16BPP(texels, width, x, y));
buf[x * 3] = Convert5To8(texel >> 11 & 0x1f);
buf[x * 3 + 1] = Convert6To8(texel >> 5 & 0x3f);
buf[x * 3 + 2] = Convert5To8(texel & 0x1f);
@ -676,7 +693,7 @@ static void DecodeRGB5A3(png_structp png, png_infop info, const uint8_t* texels,
std::unique_ptr<uint8_t[]> buf(new uint8_t[width * 4]);
for (int y = height - 1; y >= 0; --y) {
for (int x = 0; x < width; ++x) {
uint16_t texel = hecl::SBig(Lookup16BPP(texels, width, x, y));
const uint16_t texel = hecl::SBig(Lookup16BPP(texels, width, x, y));
if (texel & 0x8000) {
buf[x * 4] = Convert5To8(texel >> 10 & 0x1f);
buf[x * 4 + 1] = Convert5To8(texel >> 5 & 0x1f);
@ -728,16 +745,18 @@ static void DecodeRGBA8(png_structp png, png_infop info, const uint8_t* texels,
png_write_info(png, info);
std::unique_ptr<uint8_t[]> buf(new uint8_t[width * 4]);
for (int y = height - 1; y >= 0; --y) {
for (int x = 0; x < width; ++x)
for (int x = 0; x < width; ++x) {
LookupRGBA8(texels, width, x, y, &buf[x * 4], &buf[x * 4 + 1], &buf[x * 4 + 2], &buf[x * 4 + 3]);
}
png_write_row(png, buf.get());
}
}
static void EncodeRGBA8(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) {
for (int y = height - 1; y >= 0; --y) {
for (int x = 0; x < width; ++x)
for (int x = 0; x < width; ++x) {
SetRGBA8(texels, width, x, y, rgbaIn[x * 4], rgbaIn[x * 4 + 1], rgbaIn[x * 4 + 2], rgbaIn[x * 4 + 3]);
}
rgbaIn += width * 4;
}
}
@ -754,50 +773,55 @@ static void DecodeCMPR(png_structp png, png_infop info, const uint8_t* texels, i
png_write_info(png, info);
/* Decode 8 rows at a time */
int bwidth = (width + 7) / 8;
int bpwidth = bwidth * 8;
const int bwidth = (width + 7) / 8;
const int bpwidth = bwidth * 8;
std::unique_ptr<uint32_t[]> buf(new uint32_t[bpwidth * 8]);
uint32_t* bTargets[4] = {buf.get(), buf.get() + 4, buf.get() + 4 * width, buf.get() + 4 * width + 4};
for (int y = height / 8 - 1; y >= 0; --y) {
const DXTBlock* blks = (DXTBlock*)(texels + 32 * bwidth * y);
const auto* blks = reinterpret_cast<const DXTBlock*>(texels + 32 * bwidth * y);
for (int x = 0; x < width; x += 8) {
uint32_t blkOut[4][4][4];
squish::Decompress((uint8_t*)blkOut[0][0], blks++, squish::kDxt1GCN);
squish::Decompress((uint8_t*)blkOut[1][0], blks++, squish::kDxt1GCN);
squish::Decompress((uint8_t*)blkOut[2][0], blks++, squish::kDxt1GCN);
squish::Decompress((uint8_t*)blkOut[3][0], blks++, squish::kDxt1GCN);
squish::Decompress(reinterpret_cast<uint8_t*>(blkOut[0][0]), blks++, squish::kDxt1GCN);
squish::Decompress(reinterpret_cast<uint8_t*>(blkOut[1][0]), blks++, squish::kDxt1GCN);
squish::Decompress(reinterpret_cast<uint8_t*>(blkOut[2][0]), blks++, squish::kDxt1GCN);
squish::Decompress(reinterpret_cast<uint8_t*>(blkOut[3][0]), blks++, squish::kDxt1GCN);
for (int bt = 0; bt < 4; ++bt)
for (int by = 0; by < 4; ++by)
memcpy(bTargets[bt] + x + width * by, blkOut[bt][by], 16);
for (int bt = 0; bt < 4; ++bt) {
for (int by = 0; by < 4; ++by) {
std::memcpy(bTargets[bt] + x + width * by, blkOut[bt][by], 16);
}
}
}
for (int r = 7; r >= 0; --r) {
png_write_row(png, reinterpret_cast<png_bytep>(bTargets[0] + width * r));
}
for (int r = 7; r >= 0; --r)
png_write_row(png, (png_bytep)(bTargets[0] + width * r));
}
}
static void EncodeCMPR(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) {
/* Encode 8 rows at a time */
int bwidth = (width + 7) / 8;
int bpwidth = bwidth * 8;
const int bwidth = (width + 7) / 8;
const int bpwidth = bwidth * 8;
std::unique_ptr<uint32_t[]> buf(new uint32_t[bpwidth * 8]);
uint32_t* bTargets[4] = {buf.get(), buf.get() + 4, buf.get() + 4 * width, buf.get() + 4 * width + 4};
for (int y = height / 8 - 1; y >= 0; --y) {
for (int r = 7; r >= 0; --r) {
memcpy(bTargets[0] + width * r, rgbaIn, width * 4);
std::memcpy(bTargets[0] + width * r, rgbaIn, width * 4);
rgbaIn += width * 4;
}
DXTBlock* blks = (DXTBlock*)(texels + 32 * bwidth * y);
auto* blks = reinterpret_cast<DXTBlock*>(texels + 32 * bwidth * y);
for (int x = 0; x < width; x += 8) {
uint32_t blkIn[4][4][4];
for (int bt = 0; bt < 4; ++bt)
for (int by = 0; by < 4; ++by)
memcpy(blkIn[bt][by], bTargets[bt] + x + width * by, 16);
for (int bt = 0; bt < 4; ++bt) {
for (int by = 0; by < 4; ++by) {
std::memcpy(blkIn[bt][by], bTargets[bt] + x + width * by, 16);
}
}
squish::Compress((uint8_t*)blkIn[0][0], blks++, squish::kDxt1GCN);
squish::Compress((uint8_t*)blkIn[1][0], blks++, squish::kDxt1GCN);
squish::Compress((uint8_t*)blkIn[2][0], blks++, squish::kDxt1GCN);
squish::Compress((uint8_t*)blkIn[3][0], blks++, squish::kDxt1GCN);
squish::Compress(reinterpret_cast<uint8_t*>(blkIn[0][0]), blks++, squish::kDxt1GCN);
squish::Compress(reinterpret_cast<uint8_t*>(blkIn[1][0]), blks++, squish::kDxt1GCN);
squish::Compress(reinterpret_cast<uint8_t*>(blkIn[2][0]), blks++, squish::kDxt1GCN);
squish::Compress(reinterpret_cast<uint8_t*>(blkIn[3][0]), blks++, squish::kDxt1GCN);
}
}
}
@ -807,10 +831,10 @@ static void PNGErr(png_structp png, png_const_charp msg) { Log.report(logvisor::
static void PNGWarn(png_structp png, png_const_charp msg) { Log.report(logvisor::Warning, fmt("{}"), msg); }
bool TXTR::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
uint32_t format = rs.readUint32Big();
uint16_t width = rs.readUint16Big();
uint16_t height = rs.readUint16Big();
uint32_t numMips = rs.readUint32Big();
const uint32_t format = rs.readUint32Big();
const uint16_t width = rs.readUint16Big();
const uint16_t height = rs.readUint16Big();
const uint32_t numMips = rs.readUint32Big();
auto fp = hecl::FopenUnique(outPath.getAbsolutePath().data(), _SYS_STR("wb"));
if (fp == nullptr) {
@ -869,11 +893,11 @@ bool TXTR::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
static std::unique_ptr<uint8_t[]> ReadPalette(png_structp png, png_infop info, size_t& szOut) {
std::unique_ptr<uint8_t[]> ret;
png_sPLT_tp palettes;
int paletteCount = png_get_sPLT(png, info, &palettes);
if (paletteCount) {
const int paletteCount = png_get_sPLT(png, info, &palettes);
if (paletteCount != 0) {
for (int i = 0; i < paletteCount; ++i) {
png_sPLT_tp palette = &palettes[i];
if (!strncmp(palette->name, "GX_", 3)) {
const png_const_sPLT_tp palette = &palettes[i];
if (strncmp(palette->name, "GX_", 3) == 0) {
if (palette->nentries > 16) {
/* This is a C8 palette */
ret.reset(new uint8_t[4 * 257]);
@ -882,7 +906,7 @@ static std::unique_ptr<uint8_t[]> ReadPalette(png_structp png, png_infop info, s
uint8_t* cur = ret.get() + 4;
for (int j = 0; j < 256; ++j) {
if (j < palette->nentries) {
png_sPLT_entryp entry = &palette->entries[j];
const png_const_sPLT_entryp entry = &palette->entries[j];
if (palette->depth == 16) {
*cur++ = entry->red >> 8;
*cur++ = entry->green >> 8;
@ -909,7 +933,7 @@ static std::unique_ptr<uint8_t[]> ReadPalette(png_structp png, png_infop info, s
uint8_t* cur = ret.get() + 4;
for (int j = 0; j < 16; ++j) {
if (j < palette->nentries) {
png_sPLT_entryp entry = &palette->entries[j];
const png_const_sPLT_entryp entry = &palette->entries[j];
if (palette->depth == 16) {
*cur++ = entry->red >> 8;
*cur++ = entry->green >> 8;
@ -933,9 +957,9 @@ static std::unique_ptr<uint8_t[]> ReadPalette(png_structp png, png_infop info, s
}
}
} else {
png_colorp palettes;
png_colorp palettes2;
int colorCount;
if (png_get_PLTE(png, info, &palettes, &colorCount) == PNG_INFO_PLTE) {
if (png_get_PLTE(png, info, &palettes2, &colorCount) == PNG_INFO_PLTE) {
if (colorCount > 16) {
/* This is a C8 palette */
ret.reset(new uint8_t[4 * 257]);
@ -944,7 +968,7 @@ static std::unique_ptr<uint8_t[]> ReadPalette(png_structp png, png_infop info, s
uint8_t* cur = ret.get() + 4;
for (int j = 0; j < 256; ++j) {
if (j < colorCount) {
png_colorp entry = &palettes[j];
const png_const_colorp entry = &palettes2[j];
*cur++ = entry->red;
*cur++ = entry->green;
*cur++ = entry->blue;
@ -964,7 +988,7 @@ static std::unique_ptr<uint8_t[]> ReadPalette(png_structp png, png_infop info, s
uint8_t* cur = ret.get() + 4;
for (int j = 0; j < 16; ++j) {
if (j < colorCount) {
png_colorp entry = &palettes[j];
const png_const_colorp entry = &palettes2[j];
*cur++ = entry->red;
*cur++ = entry->green;
*cur++ = entry->blue;
@ -984,11 +1008,11 @@ static std::unique_ptr<uint8_t[]> ReadPalette(png_structp png, png_infop info, s
static int GetNumPaletteEntriesForGCN(png_structp png, png_infop info) {
png_sPLT_tp palettes;
int paletteCount = png_get_sPLT(png, info, &palettes);
if (paletteCount) {
const int paletteCount = png_get_sPLT(png, info, &palettes);
if (paletteCount != 0) {
for (int i = 0; i < paletteCount; ++i) {
png_sPLT_tp palette = &palettes[i];
if (!strncmp(palette->name, "GX_", 3)) {
const png_const_sPLT_tp palette = &palettes[i];
if (strncmp(palette->name, "GX_", 3) == 0) {
if (palette->nentries > 16) {
/* This is a C8 palette */
return 256;
@ -996,13 +1020,12 @@ static int GetNumPaletteEntriesForGCN(png_structp png, png_infop info) {
/* This is a C4 palette */
return 16;
}
break;
}
}
} else {
png_colorp palettes;
png_colorp palletes2;
int colorCount;
if (png_get_PLTE(png, info, &palettes, &colorCount) == PNG_INFO_PLTE) {
if (png_get_PLTE(png, info, &palletes2, &colorCount) == PNG_INFO_PLTE) {
if (colorCount > 16) {
/* This is a C8 palette */
return 256;
@ -1054,10 +1077,10 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
png_read_info(pngRead, info);
png_uint_32 width = png_get_image_width(pngRead, info);
png_uint_32 height = png_get_image_height(pngRead, info);
png_byte colorType = png_get_color_type(pngRead, info);
png_byte bitDepth = png_get_bit_depth(pngRead, info);
const png_uint_32 width = png_get_image_width(pngRead, info);
const png_uint_32 height = png_get_image_height(pngRead, info);
const png_byte colorType = png_get_color_type(pngRead, info);
const png_byte bitDepth = png_get_bit_depth(pngRead, info);
if (width < 4 || height < 4) {
Log.report(logvisor::Error, fmt("image must be 4x4 or larger"));
@ -1070,18 +1093,22 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
png_text* textStruct;
int numText;
png_get_text(pngRead, info, &textStruct, &numText);
for (int i = 0; i < numText; ++i)
if (!strcmp(textStruct[i].key, "urde_nomip"))
for (int i = 0; i < numText; ++i) {
if (std::strcmp(textStruct[i].key, "urde_nomip") == 0) {
mipmap = false;
if (colorType == PNG_COLOR_TYPE_PALETTE)
}
}
if (colorType == PNG_COLOR_TYPE_PALETTE) {
mipmap = false;
}
/* Compute mipmap levels */
size_t numMips = 1;
if (mipmap && CountBits(width) == 1 && CountBits(height) == 1) {
size_t index = std::min(width, height);
while (index >>= 1)
while (index >>= 1) {
++numMips;
}
}
if (bitDepth != 8) {
@ -1149,8 +1176,8 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
if (colorType == PNG_COLOR_TYPE_RGB) {
png_read_row(pngRead, rowBuf.get(), nullptr);
for (unsigned i = 0; i < width; ++i) {
size_t inbase = i * 3;
size_t outbase = (r * width + i) * 4;
const size_t inbase = i * 3;
const size_t outbase = (r * width + i) * 4;
bufOut[outbase] = rowBuf[inbase];
bufOut[outbase + 1] = rowBuf[inbase + 1];
bufOut[outbase + 2] = rowBuf[inbase + 2];
@ -1160,9 +1187,10 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
png_read_row(pngRead, &bufOut[(r * width) * nComps], nullptr);
if (colorType == PNG_COLOR_TYPE_RGB_ALPHA) {
for (unsigned i = 0; i < width; ++i) {
size_t outbase = (r * width + i) * nComps;
if (bufOut[outbase + 3] != 0 && bufOut[outbase + 3] != 255)
const size_t outbase = (r * width + i) * nComps;
if (bufOut[outbase + 3] != 0 && bufOut[outbase + 3] != 255) {
doDXT1 = false;
}
}
}
}
@ -1253,9 +1281,9 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
filterHeight = height;
const uint8_t* rgbaIn = bufOut.get();
uint8_t* blocksOut = compOut.get();
memset(blocksOut, 0, compLen);
std::memset(blocksOut, 0, compLen);
for (size_t i = 0; i < numMips; ++i) {
int thisLen = squish::GetStorageRequirements(filterWidth, filterHeight, squish::kDxt1);
const int thisLen = squish::GetStorageRequirements(filterWidth, filterHeight, squish::kDxt1);
EncodeCMPR(rgbaIn, blocksOut, filterWidth, filterHeight);
rgbaIn += filterWidth * filterHeight * nComps;
blocksOut += thisLen;
@ -1269,14 +1297,15 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
int filterHeight = height;
compLen = bufLen;
if (colorType == PNG_COLOR_TYPE_PALETTE) {
if (nPaletteEntries == 16)
if (nPaletteEntries == 16) {
compLen /= 2;
}
compLen += 8 + nPaletteEntries * 2;
}
compOut.reset(new uint8_t[compLen]);
const uint8_t* rgbaIn = bufOut.get();
uint8_t* dataOut = compOut.get();
memset(dataOut, 0, compLen);
std::memset(dataOut, 0, compLen);
for (size_t i = 0; i < numMips; ++i) {
switch (colorType) {
case PNG_COLOR_TYPE_GRAY:
@ -1367,28 +1396,32 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP
png_read_info(pngRead, info);
png_uint_32 width = png_get_image_width(pngRead, info);
png_uint_32 height = png_get_image_height(pngRead, info);
png_byte colorType = png_get_color_type(pngRead, info);
png_byte bitDepth = png_get_bit_depth(pngRead, info);
const png_uint_32 width = png_get_image_width(pngRead, info);
const png_uint_32 height = png_get_image_height(pngRead, info);
const png_byte colorType = png_get_color_type(pngRead, info);
const png_byte bitDepth = png_get_bit_depth(pngRead, info);
/* Disable mipmapping if urde_nomip embedded */
bool mipmap = true;
png_text* textStruct;
int numText;
png_get_text(pngRead, info, &textStruct, &numText);
for (int i = 0; i < numText; ++i)
if (!strcmp(textStruct[i].key, "urde_nomip"))
for (int i = 0; i < numText; ++i) {
if (std::strcmp(textStruct[i].key, "urde_nomip") == 0) {
mipmap = false;
if (colorType == PNG_COLOR_TYPE_PALETTE)
}
}
if (colorType == PNG_COLOR_TYPE_PALETTE) {
mipmap = false;
}
/* Compute mipmap levels */
size_t numMips = 1;
if (mipmap && CountBits(width) == 1 && CountBits(height) == 1) {
size_t index = std::min(width, height);
while (index >>= 1)
while (index >>= 1) {
++numMips;
}
}
if (bitDepth != 8) {
@ -1454,7 +1487,7 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP
switch (colorType) {
case PNG_COLOR_TYPE_GRAY:
for (unsigned i = 0; i < width; ++i) {
size_t outbase = (r * width + i) * 4;
const size_t outbase = (r * width + i) * 4;
bufOut[outbase] = rowBuf[i];
bufOut[outbase + 1] = rowBuf[i];
bufOut[outbase + 2] = rowBuf[i];
@ -1463,8 +1496,8 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
for (unsigned i = 0; i < width; ++i) {
size_t inbase = i * 2;
size_t outbase = (r * width + i) * 4;
const size_t inbase = i * 2;
const size_t outbase = (r * width + i) * 4;
bufOut[outbase] = rowBuf[inbase];
bufOut[outbase + 1] = rowBuf[inbase];
bufOut[outbase + 2] = rowBuf[inbase];
@ -1473,8 +1506,8 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP
break;
case PNG_COLOR_TYPE_RGB:
for (unsigned i = 0; i < width; ++i) {
size_t inbase = i * 3;
size_t outbase = (r * width + i) * 4;
const size_t inbase = i * 3;
const size_t outbase = (r * width + i) * 4;
bufOut[outbase] = rowBuf[inbase];
bufOut[outbase + 1] = rowBuf[inbase + 1];
bufOut[outbase + 2] = rowBuf[inbase + 2];
@ -1483,8 +1516,8 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
for (unsigned i = 0; i < width; ++i) {
size_t inbase = i * 4;
size_t outbase = (r * width + i) * 4;
const size_t inbase = i * 4;
const size_t outbase = (r * width + i) * 4;
bufOut[outbase] = rowBuf[inbase];
bufOut[outbase + 1] = rowBuf[inbase + 1];
bufOut[outbase + 2] = rowBuf[inbase + 2];
@ -1548,7 +1581,7 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP
const uint8_t* rgbaIn = bufOut.get();
uint8_t* blocksOut = compOut.get();
for (i = 0; i < numMips; ++i) {
int thisLen = squish::GetStorageRequirements(filterWidth, filterHeight, compFlags);
const int thisLen = squish::GetStorageRequirements(filterWidth, filterHeight, compFlags);
squish::CompressImage(rgbaIn, filterWidth, filterHeight, blocksOut, compFlags);
rgbaIn += filterWidth * filterHeight * nComps;
blocksOut += thisLen;
@ -1621,8 +1654,8 @@ static const atInt32 RetroToDol[11] {
};
TXTR::Meta TXTR::GetMetaData(DataSpec::PAKEntryReadStream& rs) {
atUint32 retroFormat = rs.readUint32Big();
atUint32 format = RetroToDol[retroFormat];
const atUint32 retroFormat = rs.readUint32Big();
const atUint32 format = RetroToDol[retroFormat];
if (format == UINT32_MAX)
return {};
@ -1636,10 +1669,10 @@ TXTR::Meta TXTR::GetMetaData(DataSpec::PAKEntryReadStream& rs) {
meta.hasPalette = true;
PaletteMeta& palMeta = meta.palette;
palMeta.format = rs.readUint32Big();
atUint16 palWidth = rs.readUint16Big();
atUint16 palHeight = rs.readUint16Big();
const atUint16 palWidth = rs.readUint16Big();
const atUint16 palHeight = rs.readUint16Big();
palMeta.elementCount = palWidth * palHeight;
atUint32 palSize = atUint32(palWidth * palHeight * 2);
const atUint32 palSize = atUint32(palWidth * palHeight * 2);
if (format == 8)
textureSize /= 2;
std::unique_ptr<u8[]> palData(new u8[palSize]);

View File

@ -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());

View File

@ -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

View File

@ -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);

View File

@ -611,30 +611,30 @@ std::string_view ANCS::CharacterSet::CharacterInfo::DNAType() {
template <>
void ANCS::AnimationSet::MetaAnimFactory::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) {
IMetaAnim::Type type(IMetaAnim::Type(reader.readUint32Big()));
const auto type = IMetaAnim::Type(reader.readUint32Big());
switch (type) {
case IMetaAnim::Type::Primitive:
m_anim.reset(new struct MetaAnimPrimitive);
m_anim = std::make_unique<MetaAnimPrimitive>();
m_anim->read(reader);
break;
case IMetaAnim::Type::Blend:
m_anim.reset(new struct MetaAnimBlend);
m_anim = std::make_unique<MetaAnimBlend>();
m_anim->read(reader);
break;
case IMetaAnim::Type::PhaseBlend:
m_anim.reset(new struct MetaAnimPhaseBlend);
m_anim = std::make_unique<MetaAnimPhaseBlend>();
m_anim->read(reader);
break;
case IMetaAnim::Type::Random:
m_anim.reset(new struct MetaAnimRandom);
m_anim = std::make_unique<MetaAnimRandom>();
m_anim->read(reader);
break;
case IMetaAnim::Type::Sequence:
m_anim.reset(new struct MetaAnimSequence);
m_anim = std::make_unique<MetaAnimSequence>();
m_anim->read(reader);
break;
default:
m_anim.reset(nullptr);
m_anim.reset();
break;
}
}
@ -660,22 +660,22 @@ void ANCS::AnimationSet::MetaAnimFactory::Enumerate<BigDNA::ReadYaml>(athena::io
std::string type = reader.readString("type");
std::transform(type.begin(), type.end(), type.begin(), tolower);
if (type == "primitive") {
m_anim.reset(new struct MetaAnimPrimitive);
m_anim = std::make_unique<MetaAnimPrimitive>();
m_anim->read(reader);
} else if (type == "blend") {
m_anim.reset(new struct MetaAnimBlend);
m_anim = std::make_unique<MetaAnimBlend>();
m_anim->read(reader);
} else if (type == "phaseblend") {
m_anim.reset(new struct MetaAnimPhaseBlend);
m_anim = std::make_unique<MetaAnimPhaseBlend>();
m_anim->read(reader);
} else if (type == "random") {
m_anim.reset(new struct MetaAnimRandom);
m_anim = std::make_unique<MetaAnimRandom>();
m_anim->read(reader);
} else if (type == "sequence") {
m_anim.reset(new struct MetaAnimSequence);
m_anim = std::make_unique<MetaAnimSequence>();
m_anim->read(reader);
} else {
m_anim.reset(nullptr);
m_anim.reset();
}
}
@ -696,20 +696,20 @@ void ANCS::AnimationSet::MetaTransFactory::Enumerate<BigDNA::Read>(athena::io::I
IMetaTrans::Type type(IMetaTrans::Type(reader.readUint32Big()));
switch (type) {
case IMetaTrans::Type::MetaAnim:
m_trans.reset(new struct MetaTransMetaAnim);
m_trans = std::make_unique<MetaTransMetaAnim>();
m_trans->read(reader);
break;
case IMetaTrans::Type::Trans:
m_trans.reset(new struct MetaTransTrans);
m_trans = std::make_unique<MetaTransTrans>();
m_trans->read(reader);
break;
case IMetaTrans::Type::PhaseTrans:
m_trans.reset(new struct MetaTransPhaseTrans);
m_trans = std::make_unique<MetaTransPhaseTrans>();
m_trans->read(reader);
break;
case IMetaTrans::Type::NoTrans:
default:
m_trans.reset(nullptr);
m_trans.reset();
break;
}
}
@ -737,16 +737,16 @@ void ANCS::AnimationSet::MetaTransFactory::Enumerate<BigDNA::ReadYaml>(athena::i
std::string type = reader.readString("type");
std::transform(type.begin(), type.end(), type.begin(), tolower);
if (type == "metaanim") {
m_trans.reset(new struct MetaTransMetaAnim);
m_trans = std::make_unique<MetaTransMetaAnim>();
m_trans->read(reader);
} else if (type == "trans") {
m_trans.reset(new struct MetaTransTrans);
m_trans = std::make_unique<MetaTransTrans>();
m_trans->read(reader);
} else if (type == "phasetrans") {
m_trans.reset(new struct MetaTransPhaseTrans);
m_trans = std::make_unique<MetaTransPhaseTrans>();
m_trans->read(reader);
} else {
m_trans.reset(nullptr);
m_trans.reset();
}
}

View File

@ -122,15 +122,15 @@ void ANIM::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
atUint32 version = reader.readUint32Big();
switch (version) {
case 0:
m_anim.reset(new struct ANIM0);
m_anim = std::make_unique<ANIM0>();
m_anim->read(reader);
break;
case 2:
m_anim.reset(new struct ANIM2(false));
m_anim = std::make_unique<ANIM2>(false);
m_anim->read(reader);
break;
case 3:
m_anim.reset(new struct ANIM2(true));
m_anim = std::make_unique<ANIM2>(true);
m_anim->read(reader);
break;
default:
@ -548,7 +548,7 @@ void ANIM::ANIM2::Enumerate<BigDNA::BinarySize>(size_t& __isz) {
ANIM::ANIM(const BlenderAction& act, const std::unordered_map<std::string, atInt32>& idMap,
const DNAANIM::RigInverter<CINF>& rig, bool pc) {
m_anim.reset(new struct ANIM2(pc));
m_anim = std::make_unique<ANIM2>(pc);
IANIM& newAnim = *m_anim;
newAnim.looping = act.looping;

View File

@ -99,15 +99,18 @@ void DCLN::Collision::Node::Enumerate(typename Op::StreamT& s) {
Do<Op>(athena::io::PropId{"halfExtent"}, halfExtent, s);
Do<Op>(athena::io::PropId{"isLeaf"}, isLeaf, s);
if (isLeaf) {
if (!leafData)
leafData.reset(new LeafData);
if (!leafData) {
leafData = std::make_unique<LeafData>();
}
Do<Op>(athena::io::PropId{"leafData"}, *leafData, s);
} else {
if (!left)
left.reset(new Node);
if (!left) {
left = std::make_unique<Node>();
}
Do<Op>(athena::io::PropId{"left"}, *left, s);
if (!right)
right.reset(new Node);
if (!right) {
right = std::make_unique<Node>();
}
Do<Op>(athena::io::PropId{"right"}, *right, s);
}
}

View File

@ -54,43 +54,43 @@ void FRME::Widget::Enumerate<BigDNA::Read>(athena::io::IStreamReader& __dna_read
header.read(__dna_reader);
switch (type.toUint32()) {
case SBIG('BWIG'):
widgetInfo.reset(new BWIGInfo);
widgetInfo = std::make_unique<BWIGInfo>();
break;
case SBIG('HWIG'):
widgetInfo.reset(new HWIGInfo);
widgetInfo = std::make_unique<HWIGInfo>();
break;
case SBIG('CAMR'):
widgetInfo.reset(new CAMRInfo);
widgetInfo = std::make_unique<CAMRInfo>();
break;
case SBIG('LITE'):
widgetInfo.reset(new LITEInfo);
widgetInfo = std::make_unique<LITEInfo>();
break;
case SBIG('ENRG'):
widgetInfo.reset(new ENRGInfo);
widgetInfo = std::make_unique<ENRGInfo>();
break;
case SBIG('MODL'):
widgetInfo.reset(new MODLInfo);
widgetInfo = std::make_unique<MODLInfo>();
break;
case SBIG('METR'):
widgetInfo.reset(new METRInfo);
widgetInfo = std::make_unique<METRInfo>();
break;
case SBIG('GRUP'):
widgetInfo.reset(new GRUPInfo);
widgetInfo = std::make_unique<GRUPInfo>();
break;
case SBIG('PANE'):
widgetInfo.reset(new PANEInfo);
widgetInfo = std::make_unique<PANEInfo>();
break;
case SBIG('TXPN'):
widgetInfo.reset(new TXPNInfo(owner->version));
widgetInfo = std::make_unique<TXPNInfo>(owner->version);
break;
case SBIG('IMGP'):
widgetInfo.reset(new IMGPInfo);
widgetInfo = std::make_unique<IMGPInfo>();
break;
case SBIG('TBGP'):
widgetInfo.reset(new TBGPInfo);
widgetInfo = std::make_unique<TBGPInfo>();
break;
case SBIG('SLGP'):
widgetInfo.reset(new SLGPInfo);
widgetInfo = std::make_unique<SLGPInfo>();
break;
default:
Log.report(logvisor::Fatal, fmt(_SYS_STR("Unsupported FRME widget type {}")), type);
@ -169,12 +169,13 @@ void FRME::Widget::Enumerate<BigDNA::BinarySize>(size_t& __isz) {
template <>
void FRME::Widget::CAMRInfo::Enumerate<BigDNA::Read>(athena::io::IStreamReader& __dna_reader) {
projectionType = ProjectionType(__dna_reader.readUint32Big());
if (projectionType == ProjectionType::Perspective)
projection.reset(new PerspectiveProjection);
else if (projectionType == ProjectionType::Orthographic)
projection.reset(new OrthographicProjection);
else
if (projectionType == ProjectionType::Perspective) {
projection = std::make_unique<PerspectiveProjection>();
} else if (projectionType == ProjectionType::Orthographic) {
projection = std::make_unique<OrthographicProjection>();
} else {
Log.report(logvisor::Fatal, fmt(_SYS_STR("Invalid CAMR projection mode! {}")), int(projectionType));
}
projection->read(__dna_reader);
}

View File

@ -1,12 +1,16 @@
#include "SCAN.hpp"
#include <algorithm>
#include <array>
namespace DataSpec::DNAMP1 {
static const std::vector<std::string> PaneNames = {
"imagepane_pane0", "imagepane_pane1", "imagepane_pane2", "imagepane_pane3", "imagepane_pane01",
"imagepane_pane12", "imagepane_pane23", "imagepane_pane012", "imagepane_pane123", "imagepane_pane0123",
"imagepane_pane4", "imagepane_pane5", "imagepane_pane6", "imagepane_pane7", "imagepane_pane45",
"imagepane_pane56", "imagepane_pane67", "imagepane_pane456", "imagepane_pane567", "imagepane_pane4567"};
constexpr std::array PaneNames{
"imagepane_pane0"sv, "imagepane_pane1"sv, "imagepane_pane2"sv, "imagepane_pane3"sv, "imagepane_pane01"sv,
"imagepane_pane12"sv, "imagepane_pane23"sv, "imagepane_pane012"sv, "imagepane_pane123"sv, "imagepane_pane0123"sv,
"imagepane_pane4"sv, "imagepane_pane5"sv, "imagepane_pane6"sv, "imagepane_pane7"sv, "imagepane_pane45"sv,
"imagepane_pane56"sv, "imagepane_pane67"sv, "imagepane_pane456"sv, "imagepane_pane567"sv, "imagepane_pane4567"sv,
};
template <>
void SCAN::Texture::Enumerate<BigDNA::Read>(typename Read::StreamT& r) {

View File

@ -1,10 +1,14 @@
#include "STRG.hpp"
#include <array>
#include "DNAMP1.hpp"
namespace DataSpec::DNAMP1 {
const std::vector<FourCC> skLanguages = {FOURCC('ENGL'), FOURCC('FREN'), FOURCC('GERM'), FOURCC('SPAN'),
FOURCC('ITAL'), FOURCC('DUTC'), FOURCC('JAPN')};
constexpr std::array skLanguages{
FOURCC('ENGL'), FOURCC('FREN'), FOURCC('GERM'), FOURCC('SPAN'), FOURCC('ITAL'), FOURCC('DUTC'), FOURCC('JAPN'),
};
static uint32_t ParseTag(const char16_t* str) {
char parseStr[9];

View File

@ -126,11 +126,11 @@ void ANIM::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
atUint32 version = reader.readUint32Big();
switch (version) {
case 0:
m_anim.reset(new struct ANIM0);
m_anim = std::make_unique<ANIM0>();
m_anim->read(reader);
break;
case 2:
m_anim.reset(new struct ANIM2);
m_anim = std::make_unique<ANIM2>();
m_anim->read(reader);
break;
default:

View File

@ -151,7 +151,7 @@ void PAKBridge::build() {
}
void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssociations<UniqueID32>& charAssoc) const {
for (const std::pair<UniqueID32, DNAMP2::PAK::Entry>& entry : m_pak.m_entries) {
for (const auto& entry : m_pak.m_entries) {
if (entry.second.type == FOURCC('ANCS')) {
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
ANCS ancs;
@ -175,7 +175,7 @@ static const atVec4f BottomRow = {{0.f, 0.f, 0.f, 1.f}};
void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo,
std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const {
for (const std::pair<UniqueID32, DNAMP2::PAK::Entry>& entry : m_pak.m_entries) {
for (const auto& entry : m_pak.m_entries) {
if (entry.second.type == FOURCC('MLVL')) {
MLVL mlvl;
{

View File

@ -67,8 +67,8 @@ void STRG::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer) {
writer.writeUint32Big(strCount);
atUint32 offset = 0;
for (const std::pair<DNAFourCC, std::vector<std::u16string>>& lang : langs) {
lang.first.write(writer);
for (const auto& lang : langs) {
DNAFourCC{lang.first}.write(writer);
writer.writeUint32Big(offset);
offset += strCount * 4 + 4;
atUint32 langStrCount = lang.second.size();
@ -87,20 +87,22 @@ void STRG::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer) {
}
atUint32 nameTableSz = names.size() * 8;
for (const std::pair<std::string, int32_t>& name : names)
for (const auto& name : names) {
nameTableSz += name.first.size() + 1;
}
writer.writeUint32Big(names.size());
writer.writeUint32Big(nameTableSz);
offset = names.size() * 8;
for (const std::pair<std::string, int32_t>& name : names) {
for (const auto& name : names) {
writer.writeUint32Big(offset);
writer.writeInt32Big(name.second);
offset += name.first.size() + 1;
}
for (const std::pair<std::string, int32_t>& name : names)
for (const auto& name : names) {
writer.writeString(name.first);
}
for (const std::pair<DNAFourCC, std::vector<std::u16string>>& lang : langs) {
for (const auto& lang : langs) {
offset = strCount * 4;
atUint32 langStrCount = lang.second.size();
for (atUint32 s = 0; s < strCount; ++s) {
@ -128,11 +130,12 @@ void STRG::Enumerate<BigDNA::BinarySize>(size_t& __isz) {
__isz += 8;
__isz += names.size() * 8;
for (const std::pair<std::string, int32_t>& name : names)
for (const auto& name : names) {
__isz += name.first.size() + 1;
}
size_t strCount = STRG::count();
for (const std::pair<DNAFourCC, std::vector<std::u16string>>& lang : langs) {
for (const auto& lang : langs) {
atUint32 langStrCount = lang.second.size();
__isz += strCount * 4;

View File

@ -130,11 +130,11 @@ void ANIM::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
atUint32 version = reader.readUint32Big();
switch (version) {
case 0:
m_anim.reset(new struct ANIM0);
m_anim = std::make_unique<ANIM0>();
m_anim->read(reader);
break;
case 1:
m_anim.reset(new struct ANIM1);
m_anim = std::make_unique<ANIM1>();
m_anim->read(reader);
break;
default:

View File

@ -74,30 +74,30 @@ std::string_view CHAR::AnimationInfo::EVNT::SFXEvent::DNAType() {
template <>
void CHAR::AnimationInfo::MetaAnimFactory::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) {
IMetaAnim::Type type(IMetaAnim::Type(reader.readUint32Big()));
const auto type = IMetaAnim::Type(reader.readUint32Big());
switch (type) {
case IMetaAnim::Type::Primitive:
m_anim.reset(new struct MetaAnimPrimitive);
m_anim = std::make_unique<MetaAnimPrimitive>();
m_anim->read(reader);
break;
case IMetaAnim::Type::Blend:
m_anim.reset(new struct MetaAnimBlend);
m_anim = std::make_unique<MetaAnimBlend>();
m_anim->read(reader);
break;
case IMetaAnim::Type::PhaseBlend:
m_anim.reset(new struct MetaAnimPhaseBlend);
m_anim = std::make_unique<MetaAnimPhaseBlend>();
m_anim->read(reader);
break;
case IMetaAnim::Type::Random:
m_anim.reset(new struct MetaAnimRandom);
m_anim = std::make_unique<MetaAnimRandom>();
m_anim->read(reader);
break;
case IMetaAnim::Type::Sequence:
m_anim.reset(new struct MetaAnimSequence);
m_anim = std::make_unique<MetaAnimSequence>();
m_anim->read(reader);
break;
default:
m_anim.reset(nullptr);
m_anim.reset();
break;
}
}
@ -123,22 +123,22 @@ void CHAR::AnimationInfo::MetaAnimFactory::Enumerate<BigDNA::ReadYaml>(athena::i
std::string type = reader.readString("type");
std::transform(type.begin(), type.end(), type.begin(), tolower);
if (type == "primitive") {
m_anim.reset(new struct MetaAnimPrimitive);
m_anim = std::make_unique<MetaAnimPrimitive>();
m_anim->read(reader);
} else if (type == "blend") {
m_anim.reset(new struct MetaAnimBlend);
m_anim = std::make_unique<MetaAnimBlend>();
m_anim->read(reader);
} else if (type == "phaseblend") {
m_anim.reset(new struct MetaAnimPhaseBlend);
m_anim = std::make_unique<MetaAnimPhaseBlend>();
m_anim->read(reader);
} else if (type == "random") {
m_anim.reset(new struct MetaAnimRandom);
m_anim = std::make_unique<MetaAnimRandom>();
m_anim->read(reader);
} else if (type == "sequence") {
m_anim.reset(new struct MetaAnimSequence);
m_anim = std::make_unique<MetaAnimSequence>();
m_anim->read(reader);
} else {
m_anim.reset(nullptr);
m_anim.reset();
}
}

View File

@ -12,19 +12,19 @@ void MaterialSet::Material::SectionFactory::Enumerate<BigDNA::Read>(typename Rea
type.read(reader);
switch (ISection::Type(type.toUint32())) {
case ISection::Type::PASS:
section.reset(new struct SectionPASS);
section = std::make_unique<SectionPASS>();
section->read(reader);
break;
case ISection::Type::CLR:
section.reset(new struct SectionCLR);
section = std::make_unique<SectionCLR>();
section->read(reader);
break;
case ISection::Type::INT:
section.reset(new struct SectionINT);
section = std::make_unique<SectionINT>();
section->read(reader);
break;
default:
section.reset(nullptr);
section.reset();
break;
}
}

View File

@ -157,7 +157,7 @@ void PAKBridge::build() {
}
void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssociations<UniqueID64>& charAssoc) const {
for (const std::pair<UniqueID64, PAK::Entry>& entry : m_pak.m_entries) {
for (const auto& entry : m_pak.m_entries) {
if (entry.second.type == FOURCC('CHAR')) {
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
CHAR aChar;
@ -180,7 +180,7 @@ static const atVec4f BottomRow = {{0.f, 0.f, 0.f, 1.f}};
void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
std::unordered_map<UniqueID64, zeus::CMatrix4f>& addTo,
std::unordered_map<UniqueID64, hecl::ProjectPath>& pathOverrides) const {
for (const std::pair<UniqueID64, PAK::Entry>& entry : m_pak.m_entries) {
for (const auto& entry : m_pak.m_entries) {
if (entry.second.type == FOURCC('MLVL')) {
MLVL mlvl;
{

View File

@ -61,7 +61,7 @@ struct PAK : BigDNA {
bool mreaHasDupeResources(const UniqueID64& id) const { return m_dupeMREAs.find(id) != m_dupeMREAs.cend(); }
typedef UniqueID64 IDType;
using IDType = UniqueID64;
};
} // namespace DataSpec::DNAMP3

View File

@ -108,7 +108,7 @@ struct TextureCache {
auto rec = r.enterSubRecord(node.first.c_str());
TXTR::Meta meta;
meta.read(r);
metaPairs.push_back(std::make_pair(projectPath.parsedHash32(), meta));
metaPairs.emplace_back(projectPath.parsedHash32(), meta);
}
std::sort(metaPairs.begin(), metaPairs.end(), [](const auto& a, const auto& b) -> bool {
@ -201,11 +201,12 @@ struct SpecMP1 : SpecBase {
/* Assemble extract report */
rep.childOpts.reserve(m_orderedPaks.size());
for (const std::pair<std::string, DNAMP1::PAKBridge*>& item : m_orderedPaks) {
if (!item.second->m_doExtract)
for (const auto& item : m_orderedPaks) {
if (!item.second->m_doExtract) {
continue;
rep.childOpts.emplace_back();
ExtractReport& childRep = rep.childOpts.back();
}
ExtractReport& childRep = rep.childOpts.emplace_back();
hecl::SystemStringConv nameView(item.first);
childRep.name = nameView.sys_str();
childRep.desc = item.second->getLevelString();
@ -222,8 +223,7 @@ struct SpecMP1 : SpecBase {
return false;
/* Root Report */
reps.emplace_back();
ExtractReport& rep = reps.back();
ExtractReport& rep = reps.emplace_back();
rep.name = _SYS_STR("MP1");
rep.desc = _SYS_STR("Metroid Prime ") + regstr;
if (buildInfo) {
@ -277,8 +277,7 @@ struct SpecMP1 : SpecBase {
const char* buildInfo = (char*)memmem(m_dolBuf.get(), dolIt->size(), "MetroidBuildInfo", 16) + 19;
/* Root Report */
reps.emplace_back();
ExtractReport& rep = reps.back();
ExtractReport& rep = reps.emplace_back();
rep.name = _SYS_STR("MP1");
rep.desc = _SYS_STR("Metroid Prime ") + regstr;
if (buildInfo) {
@ -1023,7 +1022,7 @@ struct SpecMP1 : SpecBase {
for (const auto& dep : area.deps) {
urde::CAssetId newId = dep.id.toUint64();
if (dupeRes || addedTags.find(newId) == addedTags.end()) {
listOut.push_back({dep.type, newId});
listOut.emplace_back(dep.type, newId);
addedTags.insert(newId);
}
}
@ -1083,7 +1082,7 @@ struct SpecMP1 : SpecBase {
for (atUint32 i = 0; i < mapaCount; ++i) {
UniqueID32 id;
id.read(r);
listOut.push_back({FOURCC('MAPA'), id.toUint64()});
listOut.emplace_back(FOURCC('MAPA'), id.toUint64());
}
}
}

View File

@ -101,11 +101,12 @@ struct SpecMP2 : SpecBase {
m_orderedPaks[std::string(dpak.getName())] = &dpak;
/* Assemble extract report */
for (const std::pair<std::string, DNAMP2::PAKBridge*>& item : m_orderedPaks) {
if (!item.second->m_doExtract)
for (const auto& item : m_orderedPaks) {
if (!item.second->m_doExtract) {
continue;
rep.childOpts.emplace_back();
ExtractReport& childRep = rep.childOpts.back();
}
ExtractReport& childRep = rep.childOpts.emplace_back();
hecl::SystemStringConv nameView(item.first);
childRep.name = hecl::SystemString(nameView.sys_str());
childRep.desc = item.second->getLevelString();
@ -121,8 +122,7 @@ struct SpecMP2 : SpecBase {
return false;
/* Root Report */
reps.emplace_back();
ExtractReport& rep = reps.back();
ExtractReport& rep = reps.emplace_back();
rep.name = _SYS_STR("MP2");
rep.desc = _SYS_STR("Metroid Prime 2 ") + regstr;
std::string buildStr(buildInfo);
@ -174,8 +174,7 @@ struct SpecMP2 : SpecBase {
const char* buildInfo = (char*)memmem(dolBuf.get(), dolIt->size(), "MetroidBuildInfo", 16) + 19;
/* Root Report */
reps.emplace_back();
ExtractReport& rep = reps.back();
ExtractReport& rep = reps.emplace_back();
rep.name = _SYS_STR("MP2");
rep.desc = _SYS_STR("Metroid Prime 2 ") + regstr;
if (buildInfo) {

View File

@ -132,11 +132,11 @@ struct SpecMP3 : SpecBase {
}
/* Assemble extract report */
for (const std::pair<std::string, DNAMP3::PAKBridge*>& item : fe ? m_feOrderedPaks : m_orderedPaks) {
for (const auto& item : fe ? m_feOrderedPaks : m_orderedPaks) {
if (!item.second->m_doExtract)
continue;
rep.childOpts.emplace_back();
ExtractReport& childRep = rep.childOpts.back();
ExtractReport& childRep = rep.childOpts.emplace_back();
hecl::SystemStringConv nameView(item.first);
childRep.name = hecl::SystemString(nameView.sys_str());
if (item.first == "Worlds.pak")
@ -168,8 +168,7 @@ struct SpecMP3 : SpecBase {
return false;
/* Root Report */
reps.emplace_back();
ExtractReport& rep = reps.back();
ExtractReport& rep = reps.emplace_back();
rep.name = _SYS_STR("MP3");
rep.desc = _SYS_STR("Metroid Prime 3 ") + regstr;
std::string buildStr(buildInfo);
@ -250,8 +249,7 @@ struct SpecMP3 : SpecBase {
}
/* Root Report */
reps.emplace_back();
ExtractReport& rep = reps.back();
ExtractReport& rep = reps.emplace_back();
rep.name = _SYS_STR("MP3");
rep.desc = _SYS_STR("Metroid Prime 3 ") + regstr;
@ -281,8 +279,7 @@ struct SpecMP3 : SpecBase {
const char* buildInfo = (char*)memmem(dolBuf.get(), dolIt->size(), "MetroidBuildInfo", 16) + 19;
/* Root Report */
reps.emplace_back();
ExtractReport& rep = reps.back();
ExtractReport& rep = reps.emplace_back();
rep.name = _SYS_STR("fe");
rep.desc = _SYS_STR("Metroid Prime Trilogy Frontend ") + regstr;
if (buildInfo) {
@ -305,7 +302,7 @@ struct SpecMP3 : SpecBase {
}
bool extractFromDisc(nod::DiscBase& disc, bool force, const hecl::MultiProgressPrinter& progress) override {
hecl::SystemString currentTarget = _SYS_STR("");
hecl::SystemString currentTarget;
size_t nodeCount = 0;
int prog = 0;
nod::ExtractionContext ctx = {force, [&](std::string_view name, float) {
@ -394,7 +391,7 @@ struct SpecMP3 : SpecBase {
progress.startNewLine();
hecl::ClientProcess process;
for (std::pair<std::string, DNAMP3::PAKBridge*> pair : m_feOrderedPaks) {
for (auto& pair : m_feOrderedPaks) {
DNAMP3::PAKBridge& pak = *pair.second;
if (!pak.m_doExtract)
continue;

View File

@ -21,7 +21,7 @@ class CAudioGroupSet {
amuse::AudioGroupData LoadData();
public:
CAudioGroupSet(std::unique_ptr<u8[]>&& in);
explicit CAudioGroupSet(std::unique_ptr<u8[]>&& in);
const amuse::AudioGroupData& GetAudioGroupData() const { return m_data; }
std::string_view GetName() const { return x20_name; }
};

View File

@ -19,7 +19,7 @@ public:
u16 GetGroupId() const { return x2_groupId; }
CAssetId GetAGSCAssetId() const { return x4_agscId; }
const u8* GetArrData() const { return x8_arrData.get(); }
CMidiData(CInputStream& in);
explicit CMidiData(CInputStream& in);
};
class CMidiWrapper {

View File

@ -53,7 +53,7 @@ class CStaticAudioPlayer {
memset(data, 0, 4 * frames);
return frames;
}
AudioVoiceCallback(CStaticAudioPlayer& p) : m_parent(p) {}
explicit AudioVoiceCallback(CStaticAudioPlayer& p) : m_parent(p) {}
} m_voiceCallback;
boo::ObjToken<boo::IAudioVoice> m_voice;

View File

@ -50,7 +50,7 @@ struct SDSPStreamInfo {
s16 x1c_coef[8][2];
SDSPStreamInfo() = default;
SDSPStreamInfo(const CDSPStreamManager& stream);
explicit SDSPStreamInfo(const CDSPStreamManager& stream);
};
struct SDSPStream : boo::IAudioVoiceCallback {

View File

@ -224,7 +224,7 @@ private:
CAssetId GetAreaHintDescriptionString(CAssetId mreaId);
public:
CAutoMapper(CStateManager& stateMgr);
explicit CAutoMapper(CStateManager& stateMgr);
bool CheckLoadComplete();
bool CanLeaveMapScreen(const CStateManager& mgr) const;
float GetMapRotationX() const { return xa8_renderStates[0].x1c_camAngle; }

View File

@ -38,7 +38,7 @@ public:
std::vector<Instance> m_instances;
public:
CMapAreaSurface(const void* surfBuf);
explicit CMapAreaSurface(const void* surfBuf);
CMapAreaSurface(CMapAreaSurface&&) = default;
void PostConstruct(const u8* buf, std::vector<u32>& index);
void Draw(const zeus::CVector3f* verts, const zeus::CColor& surfColor, const zeus::CColor& lineColor,
@ -69,7 +69,7 @@ private:
boo::ObjToken<boo::IGraphicsBufferS> m_ibo;
public:
CMapArea(CInputStream& in, u32 size);
explicit CMapArea(CInputStream& in, u32 size);
void PostConstruct();
bool GetIsVisibleToAutoMapper(bool worldVis, bool areaVis) const;
zeus::CVector3f GetAreaCenterPoint() const { return x10_box.center(); }

View File

@ -84,7 +84,7 @@ public:
zeus::CVector3f x64_centerPoint = zeus::skZero3f;
public:
CMapWorldData(CInputStream& in, u32 version);
explicit CMapWorldData(CInputStream& in, u32 version);
CAssetId GetWorldAssetId() const { return x10_worldAssetId; }
const zeus::CVector3f& GetWorldCenterPoint() const { return x64_centerPoint; }
std::string_view GetWorldLabel() const { return x0_label; }
@ -105,7 +105,7 @@ private:
float x2c_universeRadius = 1600.f;
public:
CMapUniverse(CInputStream&, u32);
explicit CMapUniverse(CInputStream&, u32);
const CMapWorldData& GetMapWorldData(s32 idx) const { return x10_worldDatas[idx]; }
const CMapWorldData& GetMapWorldDataByWorldId(CAssetId id) const {
for (const CMapWorldData& data : x10_worldDatas)

View File

@ -1,6 +1,7 @@
#include "Runtime/AutoMapper/CMapWorld.hpp"
#include <algorithm>
#include <array>
#include "Runtime/CSimplePool.hpp"
#include "Runtime/CStateManager.hpp"
@ -9,6 +10,254 @@
#include "Runtime/World/CWorld.hpp"
namespace urde {
namespace {
struct Support {
int x0_;
std::array<int, 3> x4_;
};
struct Circle2 {
zeus::CVector2f x0_point;
float x8_radiusSq;
};
struct Circle {
zeus::CVector2f x0_point;
float x8_radius;
Circle(const Circle2& circ2) : x0_point(circ2.x0_point), x8_radius(std::sqrt(circ2.x8_radiusSq)) {}
};
Circle2 ExactCircle1(const zeus::CVector2f* a) { return {*a, 0.f}; }
Circle2 ExactCircle2(const zeus::CVector2f* a, const zeus::CVector2f* b) {
Circle2 ret = {};
ret.x0_point = 0.5f * (*a + *b);
ret.x8_radiusSq = (*b - *a).magSquared() * 0.25f;
return ret;
}
Circle2 ExactCircle3(const zeus::CVector2f* a, const zeus::CVector2f* b, const zeus::CVector2f* c) {
Circle2 ret = {};
zeus::CVector2f d1 = *b - *a;
zeus::CVector2f d2 = *c - *a;
float cross = d1.cross(d2);
zeus::CVector2f magVec(d1.magSquared() * 0.5f, d2.magSquared() * 0.5f);
if (std::fabs(cross) > 0.01f) {
zeus::CVector2f tmp((d2.y() * magVec.x() - d1.y() * magVec.y()) / cross,
(d1.x() * magVec.y() - d2.x() * magVec.x()) / cross);
ret.x0_point = *a + tmp;
ret.x8_radiusSq = tmp.magSquared();
} else {
ret.x8_radiusSq = FLT_MAX;
}
return ret;
}
bool PointInsideCircle(const zeus::CVector2f& point, const Circle2& circ, float& intersect) {
intersect = (point - circ.x0_point).magSquared() - circ.x8_radiusSq;
return intersect <= 0.f;
}
Circle2 UpdateSupport1(int idx, const zeus::CVector2f** list, Support& support) {
Circle2 ret = ExactCircle2(list[support.x4_[0]], list[idx]);
support.x0_ = 2;
support.x4_[1] = idx;
return ret;
}
Circle2 UpdateSupport2(int idx, const zeus::CVector2f** list, Support& support) {
std::array<Circle2, 3> circs{};
float intersect;
int circIdx = -1;
float minRad = FLT_MAX;
circs[0] = ExactCircle2(list[support.x4_[0]], list[idx]);
if (PointInsideCircle(*list[support.x4_[1]], circs[0], intersect)) {
minRad = circs[0].x8_radiusSq;
circIdx = 0;
}
circs[1] = ExactCircle2(list[support.x4_[1]], list[idx]);
if (circs[1].x8_radiusSq < minRad && PointInsideCircle(*list[support.x4_[0]], circs[1], intersect)) {
circIdx = 1;
}
Circle2 ret;
if (circIdx != -1) {
ret = circs[circIdx];
support.x4_[1 - circIdx] = idx;
} else {
ret = ExactCircle3(list[support.x4_[0]], list[support.x4_[1]], list[idx]);
support.x0_ = 3;
support.x4_[2] = idx;
}
return ret;
}
Circle2 UpdateSupport3(int idx, const zeus::CVector2f** list, Support& support) {
std::array<Circle2, 6> circs{};
float intersect;
int circIdxA = -1;
int circIdxB = -1;
float minRadA = FLT_MAX;
float minRadB = FLT_MAX;
circs[0] = ExactCircle2(list[support.x4_[0]], list[idx]);
if (PointInsideCircle(*list[support.x4_[1]], circs[0], intersect)) {
if (PointInsideCircle(*list[support.x4_[2]], circs[0], intersect)) {
minRadA = circs[0].x8_radiusSq;
circIdxA = 0;
} else {
minRadB = intersect;
circIdxB = 0;
}
} else {
minRadB = intersect;
circIdxB = 0;
}
circs[1] = ExactCircle2(list[support.x4_[1]], list[idx]);
if (circs[1].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[0]], circs[1], intersect)) {
if (PointInsideCircle(*list[support.x4_[2]], circs[1], intersect)) {
minRadA = circs[1].x8_radiusSq;
circIdxA = 1;
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 1;
}
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 1;
}
}
circs[2] = ExactCircle2(list[support.x4_[2]], list[idx]);
if (circs[2].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[0]], circs[2], intersect)) {
if (PointInsideCircle(*list[support.x4_[1]], circs[2], intersect)) {
minRadA = circs[2].x8_radiusSq;
circIdxA = 2;
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 2;
}
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 2;
}
}
circs[3] = ExactCircle3(list[support.x4_[0]], list[support.x4_[1]], list[idx]);
if (circs[3].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[2]], circs[3], intersect)) {
minRadA = circs[3].x8_radiusSq;
circIdxA = 3;
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 3;
}
}
circs[4] = ExactCircle3(list[support.x4_[0]], list[support.x4_[2]], list[idx]);
if (circs[4].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[1]], circs[4], intersect)) {
minRadA = circs[4].x8_radiusSq;
circIdxA = 4;
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 4;
}
}
circs[5] = ExactCircle3(list[support.x4_[1]], list[support.x4_[2]], list[idx]);
if (circs[5].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[0]], circs[5], intersect)) {
circIdxA = 5;
} else if (intersect < minRadB) {
circIdxB = 5;
}
}
if (circIdxA == -1)
circIdxA = circIdxB;
switch (circIdxA) {
case 0:
support.x0_ = 2;
support.x4_[1] = idx;
break;
case 1:
support.x0_ = 2;
support.x4_[0] = idx;
break;
case 2:
support.x0_ = 2;
support.x4_[0] = support.x4_[2];
support.x4_[1] = idx;
break;
case 3:
support.x4_[2] = idx;
break;
case 4:
support.x4_[1] = idx;
break;
case 5:
support.x4_[0] = idx;
break;
default:
break;
}
return circs[circIdxA];
}
using FSupport = Circle2 (*)(int idx, const zeus::CVector2f** list, Support& support);
constexpr std::array<FSupport, 4> SupportFuncs{
nullptr,
UpdateSupport1,
UpdateSupport2,
UpdateSupport3,
};
Circle MinCircle(const std::vector<zeus::CVector2f>& coords) {
Circle2 ret = {};
if (coords.size() >= 1) {
std::unique_ptr<const zeus::CVector2f*[]> randArr(new const zeus::CVector2f*[coords.size()]);
for (size_t i = 0; i < coords.size(); ++i)
randArr[i] = &coords[i];
for (int i = coords.size() - 1; i >= 0; --i) {
int shuf = rand() % (i + 1);
if (shuf != i)
std::swap(randArr[i], randArr[shuf]);
}
ret = ExactCircle1(randArr[0]);
Support support = {};
support.x0_ = 1;
for (size_t i = 1; i < coords.size();) {
bool broke = false;
for (int j = 0; j < support.x0_; ++j) {
if ((*randArr[i] - *randArr[support.x4_[j]]).magSquared() < 0.01f) {
broke = true;
break;
}
}
float intersect;
if (!broke && !PointInsideCircle(*randArr[i], ret, intersect)) {
Circle2 circ = SupportFuncs[support.x0_](i, randArr.get(), support);
if (circ.x8_radiusSq > ret.x8_radiusSq) {
i = 0;
ret = circ;
continue;
}
}
++i;
}
}
return ret;
}
} // Anonymous namespace
CMapWorld::CMapAreaData::CMapAreaData(CAssetId areaRes, EMapAreaList list, CMapAreaData* next)
: x0_area(g_SimplePool->GetObj(SObjectTag{FOURCC('MAPA'), areaRes})), x10_list(list), x14_next(next) {}
@ -378,248 +627,6 @@ void CMapWorld::DrawAreas(const CMapWorld::CMapWorldDrawParms& parms, int selAre
}
}
struct Support {
int x0_;
int x4_[3];
};
struct Circle2 {
zeus::CVector2f x0_point;
float x8_radiusSq;
};
struct Circle {
zeus::CVector2f x0_point;
float x8_radius;
Circle(const Circle2& circ2) : x0_point(circ2.x0_point), x8_radius(std::sqrt(circ2.x8_radiusSq)) {}
};
static Circle2 ExactCircle1(const zeus::CVector2f* a) { return {*a, 0.f}; }
static Circle2 ExactCircle2(const zeus::CVector2f* a, const zeus::CVector2f* b) {
Circle2 ret = {};
ret.x0_point = 0.5f * (*a + *b);
ret.x8_radiusSq = (*b - *a).magSquared() * 0.25f;
return ret;
}
static Circle2 ExactCircle3(const zeus::CVector2f* a, const zeus::CVector2f* b, const zeus::CVector2f* c) {
Circle2 ret = {};
zeus::CVector2f d1 = *b - *a;
zeus::CVector2f d2 = *c - *a;
float cross = d1.cross(d2);
zeus::CVector2f magVec(d1.magSquared() * 0.5f, d2.magSquared() * 0.5f);
if (std::fabs(cross) > 0.01f) {
zeus::CVector2f tmp((d2.y() * magVec.x() - d1.y() * magVec.y()) / cross,
(d1.x() * magVec.y() - d2.x() * magVec.x()) / cross);
ret.x0_point = *a + tmp;
ret.x8_radiusSq = tmp.magSquared();
} else {
ret.x8_radiusSq = FLT_MAX;
}
return ret;
}
static bool PointInsideCircle(const zeus::CVector2f& point, const Circle2& circ, float& intersect) {
intersect = (point - circ.x0_point).magSquared() - circ.x8_radiusSq;
return intersect <= 0.f;
}
static Circle2 UpdateSupport1(int idx, const zeus::CVector2f** list, Support& support) {
Circle2 ret = ExactCircle2(list[support.x4_[0]], list[idx]);
support.x0_ = 2;
support.x4_[1] = idx;
return ret;
}
static Circle2 UpdateSupport2(int idx, const zeus::CVector2f** list, Support& support) {
Circle2 circs[3] = {};
float intersect;
int circIdx = -1;
float minRad = FLT_MAX;
circs[0] = ExactCircle2(list[support.x4_[0]], list[idx]);
if (PointInsideCircle(*list[support.x4_[1]], circs[0], intersect)) {
minRad = circs[0].x8_radiusSq;
circIdx = 0;
}
circs[1] = ExactCircle2(list[support.x4_[1]], list[idx]);
if (circs[1].x8_radiusSq < minRad && PointInsideCircle(*list[support.x4_[0]], circs[1], intersect)) {
circIdx = 1;
}
Circle2 ret;
if (circIdx != -1) {
ret = circs[circIdx];
support.x4_[1 - circIdx] = idx;
} else {
ret = ExactCircle3(list[support.x4_[0]], list[support.x4_[1]], list[idx]);
support.x0_ = 3;
support.x4_[2] = idx;
}
return ret;
}
static Circle2 UpdateSupport3(int idx, const zeus::CVector2f** list, Support& support) {
Circle2 circs[6] = {};
float intersect;
int circIdxA = -1;
int circIdxB = -1;
float minRadA = FLT_MAX;
float minRadB = FLT_MAX;
circs[0] = ExactCircle2(list[support.x4_[0]], list[idx]);
if (PointInsideCircle(*list[support.x4_[1]], circs[0], intersect)) {
if (PointInsideCircle(*list[support.x4_[2]], circs[0], intersect)) {
minRadA = circs[0].x8_radiusSq;
circIdxA = 0;
} else {
minRadB = intersect;
circIdxB = 0;
}
} else {
minRadB = intersect;
circIdxB = 0;
}
circs[1] = ExactCircle2(list[support.x4_[1]], list[idx]);
if (circs[1].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[0]], circs[1], intersect)) {
if (PointInsideCircle(*list[support.x4_[2]], circs[1], intersect)) {
minRadA = circs[1].x8_radiusSq;
circIdxA = 1;
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 1;
}
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 1;
}
}
circs[2] = ExactCircle2(list[support.x4_[2]], list[idx]);
if (circs[2].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[0]], circs[2], intersect)) {
if (PointInsideCircle(*list[support.x4_[1]], circs[2], intersect)) {
minRadA = circs[2].x8_radiusSq;
circIdxA = 2;
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 2;
}
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 2;
}
}
circs[3] = ExactCircle3(list[support.x4_[0]], list[support.x4_[1]], list[idx]);
if (circs[3].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[2]], circs[3], intersect)) {
minRadA = circs[3].x8_radiusSq;
circIdxA = 3;
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 3;
}
}
circs[4] = ExactCircle3(list[support.x4_[0]], list[support.x4_[2]], list[idx]);
if (circs[4].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[1]], circs[4], intersect)) {
minRadA = circs[4].x8_radiusSq;
circIdxA = 4;
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 4;
}
}
circs[5] = ExactCircle3(list[support.x4_[1]], list[support.x4_[2]], list[idx]);
if (circs[5].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[0]], circs[5], intersect)) {
circIdxA = 5;
} else if (intersect < minRadB) {
circIdxB = 5;
}
}
if (circIdxA == -1)
circIdxA = circIdxB;
switch (circIdxA) {
case 0:
support.x0_ = 2;
support.x4_[1] = idx;
break;
case 1:
support.x0_ = 2;
support.x4_[0] = idx;
break;
case 2:
support.x0_ = 2;
support.x4_[0] = support.x4_[2];
support.x4_[1] = idx;
break;
case 3:
support.x4_[2] = idx;
break;
case 4:
support.x4_[1] = idx;
break;
case 5:
support.x4_[0] = idx;
break;
default:
break;
}
return circs[circIdxA];
}
typedef Circle2 (*FSupport)(int idx, const zeus::CVector2f** list, Support& support);
static const FSupport SupportFuncs[] = {nullptr, UpdateSupport1, UpdateSupport2, UpdateSupport3};
static Circle MinCircle(const std::vector<zeus::CVector2f>& coords) {
Circle2 ret = {};
if (coords.size() >= 1) {
std::unique_ptr<const zeus::CVector2f*[]> randArr(new const zeus::CVector2f*[coords.size()]);
for (size_t i = 0; i < coords.size(); ++i)
randArr[i] = &coords[i];
for (int i = coords.size() - 1; i >= 0; --i) {
int shuf = rand() % (i + 1);
if (shuf != i)
std::swap(randArr[i], randArr[shuf]);
}
ret = ExactCircle1(randArr[0]);
Support support = {};
support.x0_ = 1;
for (size_t i = 1; i < coords.size();) {
bool broke = false;
for (int j = 0; j < support.x0_; ++j) {
if ((*randArr[i] - *randArr[support.x4_[j]]).magSquared() < 0.01f) {
broke = true;
break;
}
}
float intersect;
if (!broke && !PointInsideCircle(*randArr[i], ret, intersect)) {
Circle2 circ = SupportFuncs[support.x0_](i, randArr.get(), support);
if (circ.x8_radiusSq > ret.x8_radiusSq) {
i = 0;
ret = circ;
continue;
}
}
++i;
}
}
return ret;
}
void CMapWorld::RecalculateWorldSphere(const CMapWorldInfo& mwInfo, const IWorld& wld) {
std::vector<zeus::CVector2f> coords;
coords.reserve(x0_areas.size() * 8);

View File

@ -18,7 +18,7 @@ class CMapWorldInfo {
public:
CMapWorldInfo() = default;
CMapWorldInfo(CBitStreamReader&, const CSaveWorld& saveWorld, CAssetId mlvlId);
explicit CMapWorldInfo(CBitStreamReader&, const CSaveWorld& saveWorld, CAssetId mlvlId);
void PutTo(CBitStreamWriter& writer, const CSaveWorld& savw, CAssetId mlvlId) const;
bool IsMapped(TAreaId) const;
void SetIsMapped(TAreaId, bool);

View File

@ -63,7 +63,7 @@ private:
struct DoorSurface {
CMapSurfaceShader m_surface;
CLineRenderer m_outline;
DoorSurface(boo::IGraphicsDataFactory::Context& ctx)
explicit DoorSurface(boo::IGraphicsDataFactory::Context& ctx)
: m_surface(ctx, g_doorVbo, g_doorIbo)
, m_outline(ctx, CLineRenderer::EPrimitiveMode::LineLoop, 5, nullptr, false, false, true) {}
};
@ -74,7 +74,7 @@ private:
std::pair<zeus::CColor, zeus::CColor> GetDoorColors(int idx, const CMapWorldInfo& mwInfo, float alpha) const;
public:
CMappableObject(const void* buf);
explicit CMappableObject(const void* buf);
CMappableObject(CMappableObject&&) = default;
void PostConstruct(const void*);
const zeus::CTransform& GetTransform() const { return x10_transform; }

View File

@ -8,7 +8,7 @@ class CDependencyGroup {
std::vector<SObjectTag> x0_objectTags;
public:
CDependencyGroup(CInputStream& in);
explicit CDependencyGroup(CInputStream& in);
void ReadFromStream(CInputStream& in);
const std::vector<SObjectTag>& GetObjectTagVector() const { return x0_objectTags; }
};

View File

@ -71,7 +71,7 @@ class CPersistentOptions {
public:
CPersistentOptions() = default;
CPersistentOptions(CBitStreamReader& stream);
explicit CPersistentOptions(CBitStreamReader& stream);
bool GetCinematicState(CAssetId mlvlId, TEditorId cineId) const;
void SetCinematicState(CAssetId mlvlId, TEditorId cineId, bool state);
@ -134,7 +134,7 @@ class CGameOptions {
public:
CGameOptions();
CGameOptions(CBitStreamReader& stream);
explicit CGameOptions(CBitStreamReader& stream);
void ResetToDefaults();
void InitSoundMode();
void EnsureSettings();
@ -201,7 +201,7 @@ private:
public:
CHintOptions() = default;
CHintOptions(CBitStreamReader& stream);
explicit CHintOptions(CBitStreamReader& stream);
void PutTo(CBitStreamWriter& writer) const;
void SetNextHintTime();
void InitializeMemoryState();

View File

@ -38,15 +38,17 @@ CWorldLayerState::CWorldLayerState(CBitStreamReader& reader, const CSaveWorld& s
void CWorldLayerState::PutTo(CBitStreamWriter& writer) const {
u32 totalLayerCount = 0;
for (int i = 0; i < x0_areaLayers.size(); ++i)
totalLayerCount += GetAreaLayerCount(i) - 1;
for (size_t i = 0; i < x0_areaLayers.size(); ++i) {
totalLayerCount += GetAreaLayerCount(s32(i)) - 1;
}
writer.WriteEncoded(totalLayerCount, 10);
for (int i = 0; i < x0_areaLayers.size(); ++i) {
u32 count = GetAreaLayerCount(i);
for (u32 l = 1; l < count; ++l)
writer.WriteEncoded(IsLayerActive(i, l), 1);
for (size_t i = 0; i < x0_areaLayers.size(); ++i) {
const u32 count = GetAreaLayerCount(s32(i));
for (u32 l = 1; l < count; ++l) {
writer.WriteEncoded(IsLayerActive(s32(i), s32(l)), 1);
}
}
}
@ -95,8 +97,9 @@ CGameState::GameFileStateInfo CGameState::LoadGameFileState(const u8* data) {
CBitStreamReader stream(data, 4096);
GameFileStateInfo ret;
for (u32 i = 0; i < 128; i++)
for (u32 i = 0; i < 128; i++) {
stream.ReadEncoded(8);
}
ret.x14_timestamp = stream.ReadEncoded(32);
ret.x20_hardMode = stream.ReadEncoded(1);
@ -143,8 +146,9 @@ CGameState::CGameState(CBitStreamReader& stream, u32 saveIdx) : x20c_saveFileIdx
x9c_transManager = std::make_shared<CWorldTransManager>();
x228_25_initPowerupsAtFirstSpawn = true;
for (u32 i = 0; i < 128; i++)
x0_[i] = stream.ReadEncoded(8);
for (bool& value : x0_) {
value = stream.ReadEncoded(8) != 0;
}
stream.ReadEncoded(32);
x228_24_hardMode = stream.ReadEncoded(1);
@ -205,9 +209,10 @@ void CGameState::WriteBackupBuf() {
PutTo(w);
}
void CGameState::PutTo(CBitStreamWriter& writer) const {
for (u32 i = 0; i < 128; i++)
writer.WriteEncoded(x0_[i], 8);
void CGameState::PutTo(CBitStreamWriter& writer) {
for (const bool value : x0_) {
writer.WriteEncoded(u32(value), 8);
}
writer.WriteEncoded(CBasics::ToWiiTime(std::chrono::system_clock::now()) / CBasics::TICKS_PER_SECOND, 32);
writer.WriteEncoded(x228_24_hardMode, 1);
@ -227,7 +232,7 @@ void CGameState::PutTo(CBitStreamWriter& writer) const {
for (const auto& memWorld : memWorlds) {
TLockedToken<CSaveWorld> saveWorld =
g_SimplePool->GetObj(SObjectTag{FOURCC('SAVW'), memWorld.second.GetSaveWorldAssetId()});
const CWorldState& wld = const_cast<CGameState&>(*this).StateForWorld(memWorld.first);
const CWorldState& wld = StateForWorld(memWorld.first);
wld.PutTo(writer, *saveWorld);
}
}

View File

@ -1,5 +1,6 @@
#pragma once
#include <array>
#include <memory>
#include <vector>
@ -67,7 +68,7 @@ public:
class CGameState {
friend class CStateManager;
bool x0_[128] = {};
std::array<bool, 128> x0_{};
u32 x80_;
CAssetId x84_mlvlId;
std::vector<CWorldState> x88_worldStates;
@ -116,7 +117,7 @@ public:
void SetFileIdx(u32 idx) { x20c_saveFileIdx = idx; }
void SetCardSerial(u64 serial) { x210_cardSerial = serial; }
u64 GetCardSerial() const { return x210_cardSerial; }
void PutTo(CBitStreamWriter& writer) const;
void PutTo(CBitStreamWriter& writer);
float GetHardModeDamageMultiplier() const;
float GetHardModeWeaponMultiplier() const;
void InitializeMemoryWorlds();

View File

@ -16,13 +16,13 @@ class CIOWin {
public:
enum class EMessageReturn { Normal = 0, Exit = 1, RemoveIOWinAndExit = 2, RemoveIOWin = 3 };
CIOWin(std::string_view name) : x4_name(name) { m_nameHash = std::hash<std::string_view>()(name); }
explicit CIOWin(std::string_view name) : x4_name(name) { m_nameHash = std::hash<std::string_view>()(name); }
virtual ~CIOWin() = default;
virtual EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&) = 0;
virtual bool GetIsContinueDraw() const { return true; }
virtual void Draw() const {}
virtual void PreDraw() const {}
virtual void Draw() {}
virtual void PreDraw() {}
std::string_view GetName() const { return x4_name; }
size_t GetNameHash() const { return m_nameHash; }

View File

@ -6,12 +6,12 @@ namespace urde {
class CMFGameBase : public CIOWin {
public:
CMFGameBase(const char* name) : CIOWin(name) {}
explicit CMFGameBase(const char* name) : CIOWin(name) {}
};
class CMFGameLoaderBase : public CIOWin {
public:
CMFGameLoaderBase(const char* name) : CIOWin(name) {}
explicit CMFGameLoaderBase(const char* name) : CIOWin(name) {}
};
} // namespace urde

View File

@ -11,7 +11,7 @@ protected:
EClientFlowStates x14_gameState = EClientFlowStates::Unspecified;
public:
CMainFlowBase(const char* name) : CIOWin(name) {}
explicit CMainFlowBase(const char* name) : CIOWin(name) {}
EMessageReturn OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue) override;
virtual void AdvanceGameState(CArchitectureQueue& queue) = 0;
virtual void SetGameState(EClientFlowStates state, CArchitectureQueue& queue) = 0;

View File

@ -11,7 +11,7 @@ class CPlayMovieBase : public CIOWin {
public:
CPlayMovieBase(const char* iowName, const char* path) : CIOWin(iowName), x18_moviePlayer(path, 0.0, false, false) {}
EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&) override { return EMessageReturn::Normal; }
void Draw() const override {}
void Draw() override {}
};
} // namespace urde

View File

@ -170,7 +170,7 @@ public:
CStaticInterference& GetStaticInterference() { return x188_staticIntf; }
const std::vector<std::pair<CAssetId, float>>& GetScanTimes() const { return x170_scanTimes; }
CPlayerState();
CPlayerState(CBitStreamReader& stream);
explicit CPlayerState(CBitStreamReader& stream);
void PutTo(CBitStreamWriter& stream);
static u32 GetPowerUpMaxValue(EItemType type);
static EItemType ItemNameToType(std::string_view name);

View File

@ -31,7 +31,7 @@ private:
std::vector<SScanState> x44_scans;
public:
CSaveWorld(CInputStream& in);
explicit CSaveWorld(CInputStream& in);
u32 GetAreaCount() const;
u32 GetCinematicCount() const;
s32 GetCinematicIndex(const TEditorId& id) const;

View File

@ -30,17 +30,19 @@ void CSortedListManager::Reset() {
}
}
void CSortedListManager::AddToLinkedList(s16 nodeId, s16& headId, s16& tailId) const {
void CSortedListManager::AddToLinkedList(s16 nodeId, s16& headId, s16& tailId) {
if (headId == -1) {
const_cast<SNode&>(AccessElement(x0_nodes, nodeId)).x28_next = headId;
AccessElement(x0_nodes, nodeId).x28_next = headId;
headId = nodeId;
tailId = nodeId;
} else {
if (AccessElement(x0_nodes, nodeId).x28_next != -1)
if (AccessElement(x0_nodes, nodeId).x28_next != -1) {
return;
if (tailId == nodeId)
}
if (tailId == nodeId) {
return;
const_cast<SNode&>(AccessElement(x0_nodes, nodeId)).x28_next = headId;
}
AccessElement(x0_nodes, nodeId).x28_next = headId;
headId = nodeId;
}
}
@ -114,19 +116,19 @@ void CSortedListManager::InsertInList(ESortedList list, SNode& node) {
++sl.x800_size;
}
s16 CSortedListManager::FindInListUpper(ESortedList list, float val) const {
s16 CSortedListManager::FindInListUpper(ESortedList list, float value) const {
const auto listIndex = static_cast<size_t>(list);
const SSortedList& sl = xb000_sortedLists[listIndex];
int idx = 0;
for (int i = sl.x800_size; i > 0;) {
/* Binary search cycle to find index */
if (!(val < AccessElement(x0_nodes, AccessElement(sl.x0_ids, idx + i / 2)).x4_box[listIndex])) {
/* Upper */
// Binary search cycle to find index
if (!(value < AccessElement(x0_nodes, AccessElement(sl.x0_ids, idx + i / 2)).x4_box[listIndex])) {
// Upper
idx = idx + i / 2 + 1;
i = i - i / 2 - 1;
} else {
/* Lower */
// Lower
i /= 2;
}
}
@ -134,19 +136,19 @@ s16 CSortedListManager::FindInListUpper(ESortedList list, float val) const {
return idx;
}
s16 CSortedListManager::FindInListLower(ESortedList list, float val) const {
s16 CSortedListManager::FindInListLower(ESortedList list, float value) const {
const auto listIndex = static_cast<size_t>(list);
const SSortedList& sl = xb000_sortedLists[listIndex];
int idx = 0;
for (int i = sl.x800_size; i > 0;) {
/* Binary search cycle to find index */
if (AccessElement(x0_nodes, AccessElement(sl.x0_ids, idx + i / 2)).x4_box[listIndex] < val) {
/* Upper */
// Binary search cycle to find index
if (AccessElement(x0_nodes, AccessElement(sl.x0_ids, idx + i / 2)).x4_box[listIndex] < value) {
// Upper
idx = idx + i / 2 + 1;
i = i - i / 2 - 1;
} else {
/* Lower */
// Lower
i /= 2;
}
}
@ -233,48 +235,52 @@ s16 CSortedListManager::CalculateIntersections(ESortedList la, ESortedList lb, s
void CSortedListManager::BuildNearList(rstl::reserved_vector<TUniqueId, 1024>& out, const zeus::CVector3f& pos,
const zeus::CVector3f& dir, float mag, const CMaterialFilter& filter,
const CActor* actor) const {
if (mag == 0.f)
const CActor* actor) {
if (mag == 0.f) {
mag = 8000.f;
}
const zeus::CVector3f ray = dir * mag;
const zeus::CVector3f sum = ray + pos;
zeus::CVector3f maxs(std::max(pos.x(), sum.x()), std::max(pos.y(), sum.y()), std::max(pos.z(), sum.z()));
zeus::CVector3f mins(std::min(sum.x(), pos.x()), std::min(sum.y(), pos.y()), std::min(sum.z(), pos.z()));
const zeus::CVector3f maxs(std::max(pos.x(), sum.x()), std::max(pos.y(), sum.y()), std::max(pos.z(), sum.z()));
const zeus::CVector3f mins(std::min(sum.x(), pos.x()), std::min(sum.y(), pos.y()), std::min(sum.z(), pos.z()));
BuildNearList(out, zeus::CAABox(mins, maxs), filter, actor);
}
void CSortedListManager::BuildNearList(rstl::reserved_vector<TUniqueId, 1024>& out, const CActor& actor,
const zeus::CAABox& aabb) const {
const zeus::CAABox& aabb) {
const CMaterialFilter& filter = actor.GetMaterialFilter();
s16 id = const_cast<CSortedListManager&>(*this).ConstructIntersectionArray(aabb);
s16 id = ConstructIntersectionArray(aabb);
while (id != -1) {
const SNode& node = AccessElement(x0_nodes, id);
SNode& node = AccessElement(x0_nodes, id);
if (&actor != node.x0_actor && filter.Passes(node.x0_actor->GetMaterialList()) &&
node.x0_actor->GetMaterialFilter().Passes(actor.GetMaterialList()))
node.x0_actor->GetMaterialFilter().Passes(actor.GetMaterialList())) {
out.push_back(node.x0_actor->GetUniqueId());
}
id = node.x28_next;
const_cast<SNode&>(node).x28_next = -1;
node.x28_next = -1;
}
}
void CSortedListManager::BuildNearList(rstl::reserved_vector<TUniqueId, 1024>& out, const zeus::CAABox& aabb,
const CMaterialFilter& filter, const CActor* actor) const {
s16 id = const_cast<CSortedListManager&>(*this).ConstructIntersectionArray(aabb);
const CMaterialFilter& filter, const CActor* actor) {
s16 id = ConstructIntersectionArray(aabb);
while (id != -1) {
const SNode& node = AccessElement(x0_nodes, id);
if (actor != node.x0_actor && filter.Passes(node.x0_actor->GetMaterialList()))
SNode& node = AccessElement(x0_nodes, id);
if (actor != node.x0_actor && filter.Passes(node.x0_actor->GetMaterialList())) {
out.push_back(node.x0_actor->GetUniqueId());
}
id = node.x28_next;
const_cast<SNode&>(node).x28_next = -1;
node.x28_next = -1;
}
}
void CSortedListManager::Remove(const CActor* act) {
SNode& node = AccessElement(x0_nodes, act->GetUniqueId().Value());
if (!node.x2a_populated)
void CSortedListManager::Remove(const CActor* actor) {
SNode& node = AccessElement(x0_nodes, actor->GetUniqueId().Value());
if (!node.x2a_populated) {
return;
}
RemoveFromList(ESortedList::MinX, node.x1c_selfIdxs[0]);
RemoveFromList(ESortedList::MaxX, node.x1c_selfIdxs[3]);
@ -285,8 +291,8 @@ void CSortedListManager::Remove(const CActor* act) {
node.x2a_populated = false;
}
void CSortedListManager::Move(const CActor* act, const zeus::CAABox& aabb) {
SNode& node = AccessElement(x0_nodes, act->GetUniqueId().Value());
void CSortedListManager::Move(const CActor* actor, const zeus::CAABox& aabb) {
SNode& node = AccessElement(x0_nodes, actor->GetUniqueId().Value());
node.x4_box = aabb;
MoveInList(ESortedList::MinX, node.x1c_selfIdxs[0]);
@ -297,14 +303,14 @@ void CSortedListManager::Move(const CActor* act, const zeus::CAABox& aabb) {
MoveInList(ESortedList::MaxZ, node.x1c_selfIdxs[5]);
}
void CSortedListManager::Insert(const CActor* act, const zeus::CAABox& aabb) {
SNode& node = AccessElement(x0_nodes, act->GetUniqueId().Value());
void CSortedListManager::Insert(const CActor* actor, const zeus::CAABox& aabb) {
SNode& node = AccessElement(x0_nodes, actor->GetUniqueId().Value());
if (node.x2a_populated) {
Move(act, aabb);
Move(actor, aabb);
return;
}
SNode newNode(act, aabb);
SNode newNode(actor, aabb);
InsertInList(ESortedList::MinX, newNode);
InsertInList(ESortedList::MaxX, newNode);
InsertInList(ESortedList::MinY, newNode);
@ -314,10 +320,11 @@ void CSortedListManager::Insert(const CActor* act, const zeus::CAABox& aabb) {
node = newNode;
}
bool CSortedListManager::ActorInLists(const CActor* act) const {
if (!act)
bool CSortedListManager::ActorInLists(const CActor* actor) const {
if (!actor) {
return false;
const SNode& node = AccessElement(x0_nodes, act->GetUniqueId().Value());
}
const SNode& node = AccessElement(x0_nodes, actor->GetUniqueId().Value());
return node.x2a_populated;
}

View File

@ -31,27 +31,27 @@ class CSortedListManager {
std::array<SNode, 1024> x0_nodes;
std::array<SSortedList, 6> xb000_sortedLists;
void Reset();
void AddToLinkedList(s16 a, s16& b, s16& c) const;
void RemoveFromList(ESortedList, s16);
void MoveInList(ESortedList, s16);
void InsertInList(ESortedList, SNode& node);
s16 FindInListUpper(ESortedList, float) const;
s16 FindInListLower(ESortedList, float) const;
s16 ConstructIntersectionArray(const zeus::CAABox&);
s16 CalculateIntersections(ESortedList, ESortedList, s16, s16, s16, s16, ESortedList, ESortedList, ESortedList,
ESortedList, const zeus::CAABox&);
void AddToLinkedList(s16 nodeId, s16& headId, s16& tailId);
void RemoveFromList(ESortedList list, s16 idx);
void MoveInList(ESortedList list, s16 idx);
void InsertInList(ESortedList list, SNode& node);
s16 FindInListUpper(ESortedList list, float value) const;
s16 FindInListLower(ESortedList list, float value) const;
s16 ConstructIntersectionArray(const zeus::CAABox& aabb);
s16 CalculateIntersections(ESortedList la, ESortedList lb, s16 a, s16 b, s16 c, s16 d, ESortedList slA,
ESortedList slB, ESortedList slC, ESortedList slD, const zeus::CAABox& aabb);
public:
CSortedListManager();
void BuildNearList(rstl::reserved_vector<TUniqueId, 1024>&, const zeus::CVector3f&, const zeus::CVector3f&, float,
const CMaterialFilter&, const CActor*) const;
void BuildNearList(rstl::reserved_vector<TUniqueId, 1024>&, const CActor&, const zeus::CAABox&) const;
void BuildNearList(rstl::reserved_vector<TUniqueId, 1024>&, const zeus::CAABox&, const CMaterialFilter&,
const CActor*) const;
void Remove(const CActor*);
void Move(const CActor* act, const zeus::CAABox& aabb);
void Insert(const CActor* act, const zeus::CAABox& aabb);
bool ActorInLists(const CActor* act) const;
void BuildNearList(rstl::reserved_vector<TUniqueId, 1024>& out, const zeus::CVector3f& pos,
const zeus::CVector3f& dir, float mag, const CMaterialFilter& filter, const CActor* actor);
void BuildNearList(rstl::reserved_vector<TUniqueId, 1024>& out, const CActor& actor, const zeus::CAABox& aabb);
void BuildNearList(rstl::reserved_vector<TUniqueId, 1024>& out, const zeus::CAABox& aabb,
const CMaterialFilter& filter, const CActor* actor);
void Remove(const CActor* actor);
void Move(const CActor* actor, const zeus::CAABox& aabb);
void Insert(const CActor* actor, const zeus::CAABox& aabb);
bool ActorInLists(const CActor* actor) const;
};
} // namespace urde

View File

@ -216,8 +216,8 @@ private:
u32 xf94_ = 0;
};
CColoredQuadFilter m_deathWhiteout = {EFilterType::Add};
CColoredQuadFilter m_escapeWhiteout = {EFilterType::Add};
CColoredQuadFilter m_deathWhiteout{EFilterType::Add};
CColoredQuadFilter m_escapeWhiteout{EFilterType::Add};
bool m_warping = false;
void UpdateThermalVisor();

View File

@ -16,7 +16,7 @@ class CStaticInterference {
std::vector<CStaticInterferenceSource> m_sources;
public:
CStaticInterference(int sourceCount);
explicit CStaticInterference(int sourceCount);
void RemoveSource(TUniqueId id);
void Update(CStateManager&, float dt);
float GetTotalInterference() const;

View File

@ -8,7 +8,7 @@ class CPaletteInfo {
u64 m_dolphinHash;
public:
CPaletteInfo(CInputStream& in)
explicit CPaletteInfo(CInputStream& in)
: m_format(in.readUint32Big()), m_elementCount(in.readUint32Big()), m_dolphinHash(in.readUint64Big()) {}
};
class CTextureInfo {
@ -20,7 +20,7 @@ class CTextureInfo {
std::optional<CPaletteInfo> m_paletteInfo;
public:
CTextureInfo(CInputStream& in)
explicit CTextureInfo(CInputStream& in)
: m_format(ETexelFormat(in.readUint32Big()))
, m_mipCount(in.readUint32Big())
, m_width(in.readUint16Big())
@ -36,7 +36,7 @@ public:
std::map<CAssetId, CTextureInfo> m_textureInfo;
public:
CTextureCache(CInputStream& in);
explicit CTextureCache(CInputStream& in);
const CTextureInfo* GetTextureInfo(CAssetId id) const;

View File

@ -112,7 +112,7 @@ CToken& CToken::operator=(const CToken& other) {
}
return *this;
}
CToken& CToken::operator=(CToken&& other) {
CToken& CToken::operator=(CToken&& other) noexcept {
Unlock();
RemoveRef();
x0_objRef = other.x0_objRef;

View File

@ -84,7 +84,7 @@ public:
IObj* GetObj();
const IObj* GetObj() const { return const_cast<CToken*>(this)->GetObj(); }
CToken& operator=(const CToken& other);
CToken& operator=(CToken&& other);
CToken& operator=(CToken&& other) noexcept;
CToken() = default;
CToken(const CToken& other);
CToken(CToken&& other) noexcept;
@ -137,13 +137,13 @@ public:
TCachedToken() = default;
TCachedToken(const CToken& other) : TToken<T>(other) {}
TCachedToken(CToken&& other) : TToken<T>(std::move(other)) {}
T* GetObj() {
T* GetObj() override {
if (!m_obj)
m_obj = TToken<T>::GetObj();
return m_obj;
}
const T* GetObj() const { return const_cast<TCachedToken<T>*>(this)->GetObj(); }
void Unlock() {
const T* GetObj() const override { return const_cast<TCachedToken<T>*>(this)->GetObj(); }
void Unlock() override {
TToken<T>::Unlock();
m_obj = nullptr;
}
@ -153,7 +153,7 @@ public:
m_obj = nullptr;
return *this;
}
TCachedToken& operator=(const CToken& other) {
TCachedToken& operator=(const CToken& other) override {
TToken<T>::operator=(other);
m_obj = nullptr;
return *this;
@ -172,7 +172,7 @@ public:
return *this;
}
TLockedToken(const CToken& other) : TCachedToken<T>(other) { CToken::Lock(); }
TLockedToken& operator=(const CToken& other) {
TLockedToken& operator=(const CToken& other) override {
CToken oldTok = std::move(*this);
TCachedToken<T>::operator=(other);
CToken::Lock();

View File

@ -80,7 +80,7 @@ class CCameraManager {
void EnterCinematic(CStateManager& mgr);
public:
CCameraManager(TUniqueId curCameraId = kInvalidUniqueId);
explicit CCameraManager(TUniqueId curCameraId = kInvalidUniqueId);
static float Aspect() { return 1.42f; }
static float FarPlane() { return 750.0f; }

View File

@ -61,7 +61,7 @@ public:
const CCameraShakerComponent& shaker1, const CCameraShakerComponent& shaker2,
const CCameraShakerComponent& shaker3);
CCameraShakeData(float duration, float magnitude);
CCameraShakeData(CInputStream&);
explicit CCameraShakeData(CInputStream&);
static CCameraShakeData BuildLandingCameraShakeData(float duration, float magnitude);
static CCameraShakeData BuildProjectileCameraShake(float duration, float magnitude);
static CCameraShakeData BuildMissileCameraShake(float duration, float magnitude, float sfxDistance,

View File

@ -296,11 +296,11 @@ void CCinematicCamera::GenerateMoveOutofIntoPoints(bool outOfEye, CStateManager&
behindDelta = -behindDelta;
}
for (int i = 0; i < 2; ++i) {
x188_viewPoints.push_back(behindPos);
x198_viewOrientations.push_back(q);
x1a8_viewPointArrivals.push_back(mgr.GetPlayer().GetUniqueId());
x1b8_targets.push_back(eyePos);
x1c8_targetArrivals.push_back(kInvalidUniqueId);
x188_viewPoints.emplace_back(behindPos);
x198_viewOrientations.emplace_back(q);
x1a8_viewPointArrivals.emplace_back(mgr.GetPlayer().GetUniqueId());
x1b8_targets.emplace_back(eyePos);
x1c8_targetArrivals.emplace_back(kInvalidUniqueId);
behindPos += behindDelta;
}
CalculateMoveOutofIntoEyePosition(outOfEye, mgr);

View File

@ -26,7 +26,7 @@ class CInterpolationCamera : public CGameCamera {
float maxTime, float curTime);
public:
CInterpolationCamera(TUniqueId uid, const zeus::CTransform& xf);
explicit CInterpolationCamera(TUniqueId uid, const zeus::CTransform& xf);
void Accept(IVisitor& visitor) override;
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override;
void ProcessInput(const CFinalInput&, CStateManager& mgr) override;

View File

@ -20,7 +20,7 @@ public:
x4_fadeOutDur = in.readFloatBig();
}
CAdditiveAnimationInfo() = default;
CAdditiveAnimationInfo(CInputStream& in) { read(in); }
explicit CAdditiveAnimationInfo(CInputStream& in) { read(in); }
float GetFadeInDuration() const { return x0_fadeInDur; }
float GetFadeOutDuration() const { return x4_fadeOutDur; }
};

View File

@ -26,7 +26,7 @@ class CAnimFormatUnion {
static void SubConstruct(u8* storage, EAnimFormat fmt, CInputStream& in, IObjectStore& store);
public:
CAnimFormatUnion(CInputStream& in, IObjectStore& store);
explicit CAnimFormatUnion(CInputStream& in, IObjectStore& store);
~CAnimFormatUnion();
EAnimFormat GetFormat() const { return x0_format; }
CAnimSource& GetAsCAnimSource() { return *reinterpret_cast<CAnimSource*>(x4_storage); }
@ -40,7 +40,7 @@ class CAllFormatsAnimSource : public CAnimFormatUnion {
SObjectTag x74_tag;
public:
CAllFormatsAnimSource(CInputStream& in, IObjectStore& store, const SObjectTag& tag);
explicit CAllFormatsAnimSource(CInputStream& in, IObjectStore& store, const SObjectTag& tag);
static std::shared_ptr<IAnimReader> GetNewReader(const TLockedToken<CAllFormatsAnimSource>& tok,
const CCharAnimTime& startTime);
};

View File

@ -12,7 +12,7 @@ class CAnimCharacterSet {
CAnimationSet x1c_animationSet;
public:
CAnimCharacterSet(CInputStream& in);
explicit CAnimCharacterSet(CInputStream& in);
const CCharacterSet& GetCharacterSet() const { return x4_characterSet; }
const CAnimationSet& GetAnimationSet() const { return x1c_animationSet; }
};

View File

@ -56,7 +56,7 @@ CAnimData::CAnimData(CAssetId id, const CCharacterInfo& character, int defaultAn
, x204_charIdx(charIdx)
, x208_defaultAnim(defaultAnim)
, x224_pose(layout->GetSegIdList().GetList().size())
, x2fc_poseBuilder(layout)
, x2fc_poseBuilder(CLayoutDescription{layout})
, m_drawInstCount(drawInstCount) {
x220_25_loop = loop;
@ -72,7 +72,7 @@ CAnimData::CAnimData(CAssetId id, const CCharacterInfo& character, int defaultAn
x108_aabb = xd8_modelData->GetModel()->GetAABB();
x120_particleDB.CacheParticleDesc(xc_charInfo.GetParticleResData());
CHierarchyPoseBuilder pb(xcc_layoutData);
CHierarchyPoseBuilder pb(CLayoutDescription{xcc_layoutData});
pb.BuildNoScale(x224_pose);
x220_30_poseBuilt = true;

View File

@ -10,11 +10,13 @@
#include "Runtime/Character/CAdditiveAnimPlayback.hpp"
#include "Runtime/Character/CAnimPlaybackParms.hpp"
#include "Runtime/Character/CCharLayoutInfo.hpp"
#include "Runtime/Character/CCharacterFactory.hpp"
#include "Runtime/Character/CCharacterInfo.hpp"
#include "Runtime/Character/CHierarchyPoseBuilder.hpp"
#include "Runtime/Character/CParticleDatabase.hpp"
#include "Runtime/Character/CPoseAsTransforms.hpp"
#include "Runtime/Character/IAnimReader.hpp"
#include "Runtime/Graphics/CSkinnedModel.hpp"
#include <zeus/CAABox.hpp>
#include <zeus/CQuaternion.hpp>
@ -64,7 +66,6 @@ class CAnimationManager;
class CBoolPOINode;
class CCharAnimTime;
class CCharLayoutInfo;
class CCharacterFactory;
class CInt32POINode;
class CModel;
class CMorphableSkinnedModel;
@ -74,7 +75,6 @@ class CRandom16;
class CSegIdList;
class CSegStatementSet;
class CSkinRules;
class CSkinnedModel;
class CSoundPOINode;
class CStateManager;
class CTransitionManager;
@ -251,7 +251,7 @@ public:
s32 GetCharacterIndex() const { return x204_charIdx; }
u16 GetDefaultAnimation() const { return x208_defaultAnim; }
TLockedToken<CMorphableSkinnedModel>& IceModel() { return xe4_iceModelData; }
TLockedToken<CMorphableSkinnedModel>& GetIceModel() { return xe4_iceModelData; }
const TLockedToken<CMorphableSkinnedModel>& GetIceModel() const { return xe4_iceModelData; }
void SetParticleLightIdx(s32 idx) { x21c_particleLightIdx = idx; }

View File

@ -19,7 +19,7 @@ class CAnimPOIData {
std::vector<CSoundPOINode> x34_soundNodes;
public:
CAnimPOIData(CInputStream& in);
explicit CAnimPOIData(CInputStream& in);
const std::vector<CBoolPOINode>& GetBoolPOIStream() const { return x4_boolNodes; }
const std::vector<CInt32POINode>& GetInt32POIStream() const { return x14_int32Nodes; }

View File

@ -39,7 +39,7 @@ public:
struct CRotationAndOffsetVectors {
std::vector<zeus::CQuaternion> x0_rotations;
std::vector<zeus::CVector3f> x10_offsets;
CRotationAndOffsetVectors(CInputStream& in);
explicit CRotationAndOffsetVectors(CInputStream& in);
};
u32 GetFrameSizeInBytes() const;
RotationAndOffsetStorage(const CRotationAndOffsetVectors& vectors, u32 frameCount);
@ -61,7 +61,7 @@ class CAnimSource {
void CalcAverageVelocity();
public:
CAnimSource(CInputStream& in, IObjectStore& store);
explicit CAnimSource(CInputStream& in, IObjectStore& store);
void GetSegStatementSet(const CSegIdList& list, CSegStatementSet& set, const CCharAnimTime& time) const;

View File

@ -172,7 +172,7 @@ u32 CAnimSourceReaderBase::VGetSoundPOIList(const CCharAnimTime& time, CSoundPOI
return 0;
}
bool CAnimSourceReaderBase::VGetBoolPOIState(const char* name) const {
bool CAnimSourceReaderBase::VGetBoolPOIState(std::string_view name) const {
const auto iter = std::find_if(x24_boolStates.cbegin(), x24_boolStates.cend(),
[name](const auto& entry) { return entry.first == name; });
@ -183,7 +183,7 @@ bool CAnimSourceReaderBase::VGetBoolPOIState(const char* name) const {
return iter->second;
}
s32 CAnimSourceReaderBase::VGetInt32POIState(const char* name) const {
s32 CAnimSourceReaderBase::VGetInt32POIState(std::string_view name) const {
const auto iter = std::find_if(x34_int32States.cbegin(), x34_int32States.cend(),
[name](const auto& entry) { return entry.first == name; });
@ -194,7 +194,7 @@ s32 CAnimSourceReaderBase::VGetInt32POIState(const char* name) const {
return iter->second;
}
CParticleData::EParentedMode CAnimSourceReaderBase::VGetParticlePOIState(const char* name) const {
CParticleData::EParentedMode CAnimSourceReaderBase::VGetParticlePOIState(std::string_view name) const {
const auto iter = std::find_if(x44_particleStates.cbegin(), x44_particleStates.cend(),
[name](const auto& entry) { return entry.first == name; });

View File

@ -68,9 +68,9 @@ public:
u32) const override;
u32 VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, u32 capacity, u32 iterator,
u32) const override;
bool VGetBoolPOIState(const char* name) const override;
s32 VGetInt32POIState(const char* name) const override;
CParticleData::EParentedMode VGetParticlePOIState(const char* name) const override;
bool VGetBoolPOIState(std::string_view name) const override;
s32 VGetInt32POIState(std::string_view name) const override;
CParticleData::EParentedMode VGetParticlePOIState(std::string_view name) const override;
using IAnimReader::VGetOffset;
virtual zeus::CVector3f VGetOffset(const CSegId& seg, const CCharAnimTime& b) const = 0;

View File

@ -58,15 +58,15 @@ u32 CAnimTreeAnimReaderContainer::VGetSoundPOIList(const CCharAnimTime& time, CS
return x14_reader->GetSoundPOIList(time, listOut, capacity, iterator, unk);
}
bool CAnimTreeAnimReaderContainer::VGetBoolPOIState(const char* name) const {
bool CAnimTreeAnimReaderContainer::VGetBoolPOIState(std::string_view name) const {
return x14_reader->VGetBoolPOIState(name);
}
s32 CAnimTreeAnimReaderContainer::VGetInt32POIState(const char* name) const {
return x14_reader->VGetBoolPOIState(name);
s32 CAnimTreeAnimReaderContainer::VGetInt32POIState(std::string_view name) const {
return x14_reader->VGetInt32POIState(name);
}
CParticleData::EParentedMode CAnimTreeAnimReaderContainer::VGetParticlePOIState(const char* name) const {
CParticleData::EParentedMode CAnimTreeAnimReaderContainer::VGetParticlePOIState(std::string_view name) const {
return x14_reader->VGetParticlePOIState(name);
}

View File

@ -37,9 +37,9 @@ public:
u32) const override;
u32 VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, u32 capacity, u32 iterator,
u32) const override;
bool VGetBoolPOIState(const char*) const override;
s32 VGetInt32POIState(const char*) const override;
CParticleData::EParentedMode VGetParticlePOIState(const char*) const override;
bool VGetBoolPOIState(std::string_view name) const override;
s32 VGetInt32POIState(std::string_view name) const override;
CParticleData::EParentedMode VGetParticlePOIState(std::string_view name) const override;
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const override;
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const override;
std::unique_ptr<IAnimReader> VClone() const override;

View File

@ -101,11 +101,11 @@ u32 CAnimTreeDoubleChild::VGetSoundPOIList(const CCharAnimTime& time, CSoundPOIN
return newCapacity;
}
bool CAnimTreeDoubleChild::VGetBoolPOIState(const char* name) const { return x18_b->VGetBoolPOIState(name); }
bool CAnimTreeDoubleChild::VGetBoolPOIState(std::string_view name) const { return x18_b->VGetBoolPOIState(name); }
s32 CAnimTreeDoubleChild::VGetInt32POIState(const char* name) const { return x18_b->VGetBoolPOIState(name); }
s32 CAnimTreeDoubleChild::VGetInt32POIState(std::string_view name) const { return x18_b->VGetInt32POIState(name); }
CParticleData::EParentedMode CAnimTreeDoubleChild::VGetParticlePOIState(const char* name) const {
CParticleData::EParentedMode CAnimTreeDoubleChild::VGetParticlePOIState(std::string_view name) const {
return x18_b->VGetParticlePOIState(name);
}

View File

@ -41,9 +41,9 @@ public:
u32) const override;
u32 VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, u32 capacity, u32 iterator,
u32) const override;
bool VGetBoolPOIState(const char* name) const override;
s32 VGetInt32POIState(const char* name) const override;
CParticleData::EParentedMode VGetParticlePOIState(const char* name) const override;
bool VGetBoolPOIState(std::string_view name) const override;
s32 VGetInt32POIState(std::string_view name) const override;
CParticleData::EParentedMode VGetParticlePOIState(std::string_view name) const override;
void VSetPhase(float) override;
SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const override;
u32 Depth() const override;

View File

@ -14,7 +14,7 @@ protected:
std::string x4_name;
public:
CAnimTreeNode(std::string_view name) : x4_name(name) {}
explicit CAnimTreeNode(std::string_view name) : x4_name(name) {}
bool IsCAnimTreeNode() const override { return true; }
static std::shared_ptr<CAnimTreeNode> Cast(std::unique_ptr<IAnimReader>&& ptr) {
if (ptr->IsCAnimTreeNode())

View File

@ -35,11 +35,11 @@ u32 CAnimTreeSingleChild::VGetSoundPOIList(const CCharAnimTime& time, CSoundPOIN
return x14_child->GetSoundPOIList(time, listOut, capacity, iterator, unk);
}
bool CAnimTreeSingleChild::VGetBoolPOIState(const char* name) const { return x14_child->VGetBoolPOIState(name); }
bool CAnimTreeSingleChild::VGetBoolPOIState(std::string_view name) const { return x14_child->VGetBoolPOIState(name); }
s32 CAnimTreeSingleChild::VGetInt32POIState(const char* name) const { return x14_child->VGetInt32POIState(name); }
s32 CAnimTreeSingleChild::VGetInt32POIState(std::string_view name) const { return x14_child->VGetInt32POIState(name); }
CParticleData::EParentedMode CAnimTreeSingleChild::VGetParticlePOIState(const char* name) const {
CParticleData::EParentedMode CAnimTreeSingleChild::VGetParticlePOIState(std::string_view name) const {
return x14_child->VGetParticlePOIState(name);
}

View File

@ -27,9 +27,9 @@ public:
u32) const override;
u32 VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, u32 capacity, u32 iterator,
u32) const override;
bool VGetBoolPOIState(const char* name) const override;
s32 VGetInt32POIState(const char* name) const override;
CParticleData::EParentedMode VGetParticlePOIState(const char* name) const override;
bool VGetBoolPOIState(std::string_view name) const override;
s32 VGetInt32POIState(std::string_view name) const override;
CParticleData::EParentedMode VGetParticlePOIState(std::string_view name) const override;
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const override;
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const override;
void VSetPhase(float) override;

View File

@ -99,11 +99,11 @@ u32 CAnimTreeTimeScale::VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINod
return ret;
}
bool CAnimTreeTimeScale::VGetBoolPOIState(const char* name) const { return x14_child->VGetBoolPOIState(name); }
bool CAnimTreeTimeScale::VGetBoolPOIState(std::string_view name) const { return x14_child->VGetBoolPOIState(name); }
s32 CAnimTreeTimeScale::VGetInt32POIState(const char* name) const { return x14_child->VGetInt32POIState(name); }
s32 CAnimTreeTimeScale::VGetInt32POIState(std::string_view name) const { return x14_child->VGetInt32POIState(name); }
CParticleData::EParentedMode CAnimTreeTimeScale::VGetParticlePOIState(const char* name) const {
CParticleData::EParentedMode CAnimTreeTimeScale::VGetParticlePOIState(std::string_view name) const {
return x14_child->VGetParticlePOIState(name);
}

View File

@ -34,9 +34,9 @@ public:
u32) const override;
u32 VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, u32 capacity, u32 iterator,
u32) const override;
bool VGetBoolPOIState(const char* name) const override;
s32 VGetInt32POIState(const char* name) const override;
CParticleData::EParentedMode VGetParticlePOIState(const char* name) const override;
bool VGetBoolPOIState(std::string_view name) const override;
s32 VGetInt32POIState(std::string_view name) const override;
CParticleData::EParentedMode VGetParticlePOIState(std::string_view name) const override;
CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const override;
std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const override;

View File

@ -14,7 +14,7 @@ class CAnimation {
std::shared_ptr<IMetaAnim> x10_anim;
public:
CAnimation(CInputStream& in);
explicit CAnimation(CInputStream& in);
const std::shared_ptr<IMetaAnim>& GetMetaAnim() const { return x10_anim; }
std::string_view GetMetaAnimName() const { return x0_name; }
};

View File

@ -12,7 +12,7 @@ class CAnimationDatabaseGame final : public CAnimationDatabase {
std::vector<std::shared_ptr<IMetaAnim>> x10_anims;
public:
CAnimationDatabaseGame(const std::vector<CAnimation>& anims);
explicit CAnimationDatabaseGame(const std::vector<CAnimation>& anims);
const std::shared_ptr<IMetaAnim>& GetMetaAnim(s32 idx) const override;
u32 GetNumMetaAnims() const override;
const char* GetMetaAnimName(s32 idx) const override;

View File

@ -24,7 +24,7 @@ class CAnimationSet {
std::vector<std::pair<CAssetId, CAssetId>> x50_animRes;
public:
CAnimationSet(CInputStream& in);
explicit CAnimationSet(CInputStream& in);
const std::vector<CAnimation>& GetAnimations() const { return x4_animations; }
const std::vector<CTransition>& GetTransitions() const { return x14_transitions; }

View File

@ -105,7 +105,7 @@ class CBSLieOnGround : public CBodyState {
pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc) const;
public:
CBSLieOnGround(CActor& actor);
explicit CBSLieOnGround(CActor& actor);
void Start(CBodyController& bc, CStateManager& mgr) override;
pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) override;
void Shutdown(CBodyController& bc) override;
@ -371,7 +371,7 @@ protected:
}
public:
CBSBiPedLocomotion(CActor& actor);
explicit CBSBiPedLocomotion(CActor& actor);
bool IsMoving() const override { return x3c4_anim != pas::ELocomotionAnim::Idle; }
void Start(CBodyController& bc, CStateManager& mgr) override;
pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) override;
@ -384,7 +384,7 @@ class CBSFlyerLocomotion : public CBSBiPedLocomotion {
bool x3cc_pitchable;
public:
CBSFlyerLocomotion(CActor& actor, bool pitchable);
explicit CBSFlyerLocomotion(CActor& actor, bool pitchable);
bool IsPitchable() const override { return x3cc_pitchable; }
float ApplyLocomotionPhysics(float dt, CBodyController& bc) override;
virtual bool IsBackPedal(CBodyController& bc) const { return false; }
@ -392,13 +392,13 @@ public:
class CBSWallWalkerLocomotion : public CBSBiPedLocomotion {
public:
CBSWallWalkerLocomotion(CActor& actor);
explicit CBSWallWalkerLocomotion(CActor& actor);
float ApplyLocomotionPhysics(float dt, CBodyController& bc) override;
};
class CBSNewFlyerLocomotion : public CBSBiPedLocomotion {
public:
CBSNewFlyerLocomotion(CActor& actor);
explicit CBSNewFlyerLocomotion(CActor& actor);
float ApplyLocomotionPhysics(float dt, CBodyController& bc) override;
float UpdateLocomotionAnimation(float dt, float velMag, CBodyController& bc, bool init) override;
};
@ -408,7 +408,7 @@ class CBSRestrictedLocomotion : public CBSLocomotion {
pas::ELocomotionAnim x44_anim = pas::ELocomotionAnim::Invalid;
public:
CBSRestrictedLocomotion(CActor& actor);
explicit CBSRestrictedLocomotion(CActor& actor);
bool IsMoving() const override { return false; }
float GetLocomotionSpeed(pas::ELocomotionType type, pas::ELocomotionAnim anim) const override { return 0.f; }
float UpdateLocomotionAnimation(float dt, float velMag, CBodyController& bc, bool init) override;
@ -416,7 +416,7 @@ public:
class CBSRestrictedFlyerLocomotion : public CBSRestrictedLocomotion {
public:
CBSRestrictedFlyerLocomotion(CActor& actor);
explicit CBSRestrictedFlyerLocomotion(CActor& actor);
float ApplyLocomotionPhysics(float dt, CBodyController& bc) override;
};
} // namespace urde

View File

@ -13,7 +13,7 @@ class CBodyStateCmd {
public:
virtual ~CBodyStateCmd() = default;
CBodyStateCmd(EBodyStateCmd cmd) : x4_cmd(cmd) {}
explicit CBodyStateCmd(EBodyStateCmd cmd) : x4_cmd(cmd) {}
EBodyStateCmd GetCommandId() const { return x4_cmd; }
};
@ -23,10 +23,11 @@ class CBCMeleeAttackCmd : public CBodyStateCmd {
bool x18_hasTargetPos = false;
public:
CBCMeleeAttackCmd() : CBodyStateCmd(EBodyStateCmd::MeleeAttack) {}
CBCMeleeAttackCmd(pas::ESeverity severity) : CBodyStateCmd(EBodyStateCmd::MeleeAttack), x8_severity(severity) {}
CBCMeleeAttackCmd(pas::ESeverity severity, const zeus::CVector3f& target) : CBodyStateCmd(EBodyStateCmd::MeleeAttack)
, x8_severity(severity), xc_targetPos(target), x18_hasTargetPos(true) {}
explicit CBCMeleeAttackCmd() : CBodyStateCmd(EBodyStateCmd::MeleeAttack) {}
explicit CBCMeleeAttackCmd(pas::ESeverity severity)
: CBodyStateCmd(EBodyStateCmd::MeleeAttack), x8_severity(severity) {}
explicit CBCMeleeAttackCmd(pas::ESeverity severity, const zeus::CVector3f& target)
: CBodyStateCmd(EBodyStateCmd::MeleeAttack), x8_severity(severity), xc_targetPos(target), x18_hasTargetPos(true) {}
pas::ESeverity GetAttackSeverity() const { return x8_severity; }
bool HasAttackTargetPos() const { return x18_hasTargetPos; }
const zeus::CVector3f& GetAttackTargetPos() const { return xc_targetPos; }
@ -38,8 +39,8 @@ class CBCProjectileAttackCmd : public CBodyStateCmd {
bool x18_blendAnims = false;
public:
CBCProjectileAttackCmd() : CBodyStateCmd(EBodyStateCmd::ProjectileAttack) {}
CBCProjectileAttackCmd(pas::ESeverity severity, const zeus::CVector3f& vec, bool b)
explicit CBCProjectileAttackCmd() : CBodyStateCmd(EBodyStateCmd::ProjectileAttack) {}
explicit CBCProjectileAttackCmd(pas::ESeverity severity, const zeus::CVector3f& vec, bool b)
: CBodyStateCmd(EBodyStateCmd::ProjectileAttack), x8_severity(severity), xc_target(vec), x18_blendAnims(b) {}
pas::ESeverity GetAttackSeverity() const { return x8_severity; }
const zeus::CVector3f& GetTargetPosition() const { return xc_target; }
@ -51,8 +52,8 @@ class CBCStepCmd : public CBodyStateCmd {
pas::EStepType xc_type = pas::EStepType::Normal;
public:
CBCStepCmd() : CBodyStateCmd(EBodyStateCmd::Step) {}
CBCStepCmd(pas::EStepDirection dir, pas::EStepType type)
explicit CBCStepCmd() : CBodyStateCmd(EBodyStateCmd::Step) {}
explicit CBCStepCmd(pas::EStepDirection dir, pas::EStepType type)
: CBodyStateCmd(EBodyStateCmd::Step), x8_dir(dir), xc_type(type) {}
pas::EStepDirection GetStepDirection() const { return x8_dir; }
pas::EStepType GetStepType() const { return xc_type; }
@ -66,16 +67,16 @@ class CBCJumpCmd : public CBodyStateCmd {
bool x24_25_startInJumpLoop : 1;
public:
CBCJumpCmd() : CBodyStateCmd(EBodyStateCmd::Jump) {
explicit CBCJumpCmd() : CBodyStateCmd(EBodyStateCmd::Jump) {
x24_24_wallJump = false;
x24_25_startInJumpLoop = false;
}
CBCJumpCmd(const zeus::CVector3f& wp1, pas::EJumpType type, bool startInLoop = false)
explicit CBCJumpCmd(const zeus::CVector3f& wp1, pas::EJumpType type, bool startInLoop = false)
: CBodyStateCmd(EBodyStateCmd::Jump), x8_type(type), xc_waypoint1(wp1) {
x24_24_wallJump = false;
x24_25_startInJumpLoop = startInLoop;
}
CBCJumpCmd(const zeus::CVector3f& wp1, const zeus::CVector3f& wp2, pas::EJumpType type)
explicit CBCJumpCmd(const zeus::CVector3f& wp1, const zeus::CVector3f& wp2, pas::EJumpType type)
: CBodyStateCmd(EBodyStateCmd::Jump), x8_type(type), xc_waypoint1(wp1), x18_waypoint2(wp2) {
x24_24_wallJump = true;
x24_25_startInJumpLoop = false;
@ -95,22 +96,22 @@ class CBCGenerateCmd : public CBodyStateCmd {
bool x1c_25_overrideAnim : 1;
public:
CBCGenerateCmd() : CBodyStateCmd(EBodyStateCmd::Generate) {
explicit CBCGenerateCmd() : CBodyStateCmd(EBodyStateCmd::Generate) {
x1c_24_targetTransform = false;
x1c_25_overrideAnim = false;
}
CBCGenerateCmd(pas::EGenerateType type)
explicit CBCGenerateCmd(pas::EGenerateType type)
: CBodyStateCmd(EBodyStateCmd::Generate), x8_type(type) {
x1c_24_targetTransform = false;
x1c_25_overrideAnim = false;
}
CBCGenerateCmd(pas::EGenerateType type, s32 animId)
explicit CBCGenerateCmd(pas::EGenerateType type, s32 animId)
: CBodyStateCmd(EBodyStateCmd::Generate), x8_type(type), x18_animId(animId) {
x1c_24_targetTransform = false;
x1c_25_overrideAnim = animId != -1;
}
CBCGenerateCmd(pas::EGenerateType type, const zeus::CVector3f& vec, bool targetTransform = false,
bool overrideAnim = false)
explicit CBCGenerateCmd(pas::EGenerateType type, const zeus::CVector3f& vec, bool targetTransform = false,
bool overrideAnim = false)
: CBodyStateCmd(EBodyStateCmd::Generate), x8_type(type), xc_targetPos(vec) {
x1c_24_targetTransform = targetTransform;
x1c_25_overrideAnim = overrideAnim;
@ -127,8 +128,8 @@ class CBCKnockBackCmd : public CBodyStateCmd {
pas::ESeverity x14_severity = pas::ESeverity::Invalid;
public:
CBCKnockBackCmd() : CBodyStateCmd(EBodyStateCmd::KnockBack) {}
CBCKnockBackCmd(const zeus::CVector3f& vec, pas::ESeverity severity)
explicit CBCKnockBackCmd() : CBodyStateCmd(EBodyStateCmd::KnockBack) {}
explicit CBCKnockBackCmd(const zeus::CVector3f& vec, pas::ESeverity severity)
: CBodyStateCmd(EBodyStateCmd::KnockBack), x8_dir(vec), x14_severity(severity) {}
const zeus::CVector3f& GetHitDirection() const { return x8_dir; }
pas::ESeverity GetHitSeverity() const { return x14_severity; }
@ -140,8 +141,8 @@ class CBCHurledCmd : public CBodyStateCmd {
bool x20_startInKnockLoop = false;
public:
CBCHurledCmd() : CBodyStateCmd(EBodyStateCmd::Hurled) {}
CBCHurledCmd(const zeus::CVector3f& dir, const zeus::CVector3f& launchVel, bool startInLoop = false)
explicit CBCHurledCmd() : CBodyStateCmd(EBodyStateCmd::Hurled) {}
explicit CBCHurledCmd(const zeus::CVector3f& dir, const zeus::CVector3f& launchVel, bool startInLoop = false)
: CBodyStateCmd(EBodyStateCmd::Hurled)
, x8_direction(dir)
, x14_launchVel(launchVel)
@ -156,8 +157,8 @@ class CBCGetupCmd : public CBodyStateCmd {
pas::EGetupType x8_type = pas::EGetupType::Invalid;
public:
CBCGetupCmd() : CBodyStateCmd(EBodyStateCmd::Getup) {}
CBCGetupCmd(pas::EGetupType type) : CBodyStateCmd(EBodyStateCmd::Getup), x8_type(type) {}
explicit CBCGetupCmd() : CBodyStateCmd(EBodyStateCmd::Getup) {}
explicit CBCGetupCmd(pas::EGetupType type) : CBodyStateCmd(EBodyStateCmd::Getup), x8_type(type) {}
pas::EGetupType GetGetupType() const { return x8_type; }
};
@ -165,8 +166,8 @@ class CBCLoopReactionCmd : public CBodyStateCmd {
pas::EReactionType x8_type = pas::EReactionType::Invalid;
public:
CBCLoopReactionCmd() : CBodyStateCmd(EBodyStateCmd::LoopReaction) {}
CBCLoopReactionCmd(pas::EReactionType type) : CBodyStateCmd(EBodyStateCmd::LoopReaction), x8_type(type) {}
explicit CBCLoopReactionCmd() : CBodyStateCmd(EBodyStateCmd::LoopReaction) {}
explicit CBCLoopReactionCmd(pas::EReactionType type) : CBodyStateCmd(EBodyStateCmd::LoopReaction), x8_type(type) {}
pas::EReactionType GetReactionType() const { return x8_type; }
};
@ -174,8 +175,8 @@ class CBCLoopHitReactionCmd : public CBodyStateCmd {
pas::EReactionType x8_type = pas::EReactionType::Invalid;
public:
CBCLoopHitReactionCmd() : CBodyStateCmd(EBodyStateCmd::LoopHitReaction) {}
CBCLoopHitReactionCmd(pas::EReactionType type) : CBodyStateCmd(EBodyStateCmd::LoopHitReaction), x8_type(type) {}
explicit CBCLoopHitReactionCmd() : CBodyStateCmd(EBodyStateCmd::LoopHitReaction) {}
explicit CBCLoopHitReactionCmd(pas::EReactionType type) : CBodyStateCmd(EBodyStateCmd::LoopHitReaction), x8_type(type) {}
pas::EReactionType GetReactionType() const { return x8_type; }
};
@ -184,8 +185,8 @@ class CBCKnockDownCmd : public CBodyStateCmd {
pas::ESeverity x14_severity = pas::ESeverity::Invalid;
public:
CBCKnockDownCmd() : CBodyStateCmd(EBodyStateCmd::KnockDown) {}
CBCKnockDownCmd(const zeus::CVector3f& vec, pas::ESeverity severity)
explicit CBCKnockDownCmd() : CBodyStateCmd(EBodyStateCmd::KnockDown) {}
explicit CBCKnockDownCmd(const zeus::CVector3f& vec, pas::ESeverity severity)
: CBodyStateCmd(EBodyStateCmd::KnockDown), x8_dir(vec), x14_severity(severity) {}
const zeus::CVector3f& GetHitDirection() const { return x8_dir; }
pas::ESeverity GetHitSeverity() const { return x14_severity; }
@ -196,8 +197,8 @@ class CBCSlideCmd : public CBodyStateCmd {
zeus::CVector3f xc_dir;
public:
CBCSlideCmd() : CBodyStateCmd(EBodyStateCmd::Slide) {}
CBCSlideCmd(pas::ESlideType type, const zeus::CVector3f& dir)
explicit CBCSlideCmd() : CBodyStateCmd(EBodyStateCmd::Slide) {}
explicit CBCSlideCmd(pas::ESlideType type, const zeus::CVector3f& dir)
: CBodyStateCmd(EBodyStateCmd::Slide), x8_type(type), xc_dir(dir) {}
pas::ESlideType GetSlideType() const { return x8_type; }
const zeus::CVector3f& GetSlideDirection() const { return xc_dir; }
@ -210,11 +211,11 @@ class CBCScriptedCmd : public CBodyStateCmd {
float x10_loopDur = 0.f;
public:
CBCScriptedCmd() : CBodyStateCmd(EBodyStateCmd::Scripted) {
explicit CBCScriptedCmd() : CBodyStateCmd(EBodyStateCmd::Scripted) {
xc_24_loopAnim = false;
xc_25_timedLoop = false;
}
CBCScriptedCmd(int i, bool b1, bool b2, float f)
explicit CBCScriptedCmd(int i, bool b1, bool b2, float f)
: CBodyStateCmd(EBodyStateCmd::Scripted), x8_anim(i), x10_loopDur(f) {
xc_24_loopAnim = b1;
xc_25_timedLoop = b2;
@ -231,8 +232,8 @@ class CBCCoverCmd : public CBodyStateCmd {
zeus::CVector3f x18_alignDir;
public:
CBCCoverCmd() : CBodyStateCmd(EBodyStateCmd::Cover) {}
CBCCoverCmd(pas::ECoverDirection dir, const zeus::CVector3f& v1, const zeus::CVector3f& v2)
explicit CBCCoverCmd() : CBodyStateCmd(EBodyStateCmd::Cover) {}
explicit CBCCoverCmd(pas::ECoverDirection dir, const zeus::CVector3f& v1, const zeus::CVector3f& v2)
: CBodyStateCmd(EBodyStateCmd::Cover), x8_dir(dir), xc_targetPos(v1), x18_alignDir(v2) {}
pas::ECoverDirection GetDirection() const { return x8_dir; }
const zeus::CVector3f& GetTarget() const { return xc_targetPos; }
@ -243,22 +244,22 @@ class CBCWallHangCmd : public CBodyStateCmd {
TUniqueId x8_wpId = kInvalidUniqueId;
public:
CBCWallHangCmd() : CBodyStateCmd(EBodyStateCmd::WallHang) {}
CBCWallHangCmd(TUniqueId uid) : CBodyStateCmd(EBodyStateCmd::WallHang), x8_wpId(uid) {}
explicit CBCWallHangCmd() : CBodyStateCmd(EBodyStateCmd::WallHang) {}
explicit CBCWallHangCmd(TUniqueId uid) : CBodyStateCmd(EBodyStateCmd::WallHang), x8_wpId(uid) {}
TUniqueId GetTarget() const { return x8_wpId; }
};
class CBCAdditiveAimCmd : public CBodyStateCmd {
public:
CBCAdditiveAimCmd() : CBodyStateCmd(EBodyStateCmd::AdditiveAim) {}
explicit CBCAdditiveAimCmd() : CBodyStateCmd(EBodyStateCmd::AdditiveAim) {}
};
class CBCAdditiveFlinchCmd : public CBodyStateCmd {
float x8_weight = 1.f;
public:
CBCAdditiveFlinchCmd() : CBodyStateCmd(EBodyStateCmd::AdditiveFlinch) {}
CBCAdditiveFlinchCmd(float f) : CBodyStateCmd(EBodyStateCmd::AdditiveFlinch), x8_weight(f) {}
explicit CBCAdditiveFlinchCmd() : CBodyStateCmd(EBodyStateCmd::AdditiveFlinch) {}
explicit CBCAdditiveFlinchCmd(float f) : CBodyStateCmd(EBodyStateCmd::AdditiveFlinch), x8_weight(f) {}
float GetWeight() const { return x8_weight; }
};
@ -268,9 +269,9 @@ class CBCAdditiveReactionCmd : public CBodyStateCmd {
bool x10_active = false;
public:
CBCAdditiveReactionCmd() : CBodyStateCmd(EBodyStateCmd::AdditiveReaction) {}
CBCAdditiveReactionCmd(pas::EAdditiveReactionType type, float f, bool active)
: CBodyStateCmd(EBodyStateCmd::AdditiveReaction), x8_weight(f), xc_type(type), x10_active(active) {}
explicit CBCAdditiveReactionCmd() : CBodyStateCmd(EBodyStateCmd::AdditiveReaction) {}
explicit CBCAdditiveReactionCmd(pas::EAdditiveReactionType type, float weight, bool active)
: CBodyStateCmd(EBodyStateCmd::AdditiveReaction), x8_weight(weight), xc_type(type), x10_active(active) {}
pas::EAdditiveReactionType GetType() const { return xc_type; }
float GetWeight() const { return x8_weight; }
bool GetIsActive() const { return x10_active; }
@ -281,8 +282,8 @@ class CBCLoopAttackCmd : public CBodyStateCmd {
u32 xc_waitForAnimOver = 0;
public:
CBCLoopAttackCmd() : CBodyStateCmd(EBodyStateCmd::LoopAttack) {}
CBCLoopAttackCmd(pas::ELoopAttackType type) : CBodyStateCmd(EBodyStateCmd::LoopAttack), x8_type(type) {}
explicit CBCLoopAttackCmd() : CBodyStateCmd(EBodyStateCmd::LoopAttack) {}
explicit CBCLoopAttackCmd(pas::ELoopAttackType type) : CBodyStateCmd(EBodyStateCmd::LoopAttack), x8_type(type) {}
pas::ELoopAttackType GetAttackType() const { return x8_type; }
bool WaitForAnimOver() const { return xc_waitForAnimOver == 1; }
};
@ -291,8 +292,8 @@ class CBCTauntCmd : public CBodyStateCmd {
pas::ETauntType x8_type = pas::ETauntType::Invalid;
public:
CBCTauntCmd() : CBodyStateCmd(EBodyStateCmd::Taunt) {}
CBCTauntCmd(pas::ETauntType type) : CBodyStateCmd(EBodyStateCmd::Taunt), x8_type(type) {}
explicit CBCTauntCmd() : CBodyStateCmd(EBodyStateCmd::Taunt) {}
explicit CBCTauntCmd(pas::ETauntType type) : CBodyStateCmd(EBodyStateCmd::Taunt), x8_type(type) {}
pas::ETauntType GetTauntType() const { return x8_type; }
};
@ -302,7 +303,7 @@ class CBCLocomotionCmd {
float x18_weight;
public:
CBCLocomotionCmd(const zeus::CVector3f& move, const zeus::CVector3f& face, float weight)
explicit CBCLocomotionCmd(const zeus::CVector3f& move, const zeus::CVector3f& face, float weight)
: x0_move(move), xc_face(face), x18_weight(weight) {}
const zeus::CVector3f& GetMoveVector() const { return x0_move; }
const zeus::CVector3f& GetFaceVector() const { return xc_face; }
@ -324,7 +325,7 @@ class CBodyStateCmdMgr {
u32 xb4_deliveredCmdMask = 0;
CBCGetupCmd xb8_getup;
CBCStepCmd xc4_step;
CBodyStateCmd xd4_die = {EBodyStateCmd::Die};
CBodyStateCmd xd4_die{EBodyStateCmd::Die};
CBCKnockDownCmd xdc_knockDown;
CBCKnockBackCmd xf4_knockBack;
CBCMeleeAttackCmd x10c_meleeAttack;
@ -332,10 +333,10 @@ class CBodyStateCmdMgr {
CBCLoopAttackCmd x144_loopAttack;
CBCLoopReactionCmd x154_loopReaction;
CBCLoopHitReactionCmd x160_loopHitReaction;
CBodyStateCmd x16c_exitState = {EBodyStateCmd::ExitState};
CBodyStateCmd x174_leanFromCover = {EBodyStateCmd::LeanFromCover};
CBodyStateCmd x17c_nextState = {EBodyStateCmd::NextState};
CBodyStateCmd x184_maintainVelocity = {EBodyStateCmd::MaintainVelocity};
CBodyStateCmd x16c_exitState{EBodyStateCmd::ExitState};
CBodyStateCmd x174_leanFromCover{EBodyStateCmd::LeanFromCover};
CBodyStateCmd x17c_nextState{EBodyStateCmd::NextState};
CBodyStateCmd x184_maintainVelocity{EBodyStateCmd::MaintainVelocity};
CBCGenerateCmd x18c_generate;
CBCHurledCmd x1ac_hurled;
CBCJumpCmd x1d0_jump;
@ -344,12 +345,12 @@ class CBodyStateCmdMgr {
CBCScriptedCmd x21c_scripted;
CBCCoverCmd x230_cover;
CBCWallHangCmd x254_wallHang;
CBodyStateCmd x260_locomotion = {EBodyStateCmd::Locomotion};
CBodyStateCmd x268_additiveIdle = {EBodyStateCmd::AdditiveIdle};
CBodyStateCmd x260_locomotion{EBodyStateCmd::Locomotion};
CBodyStateCmd x268_additiveIdle{EBodyStateCmd::AdditiveIdle};
CBCAdditiveAimCmd x270_additiveAim;
CBCAdditiveFlinchCmd x278_additiveFlinch;
CBCAdditiveReactionCmd x284_additiveReaction;
CBodyStateCmd x298_stopReaction = {EBodyStateCmd::StopReaction};
CBodyStateCmd x298_stopReaction{EBodyStateCmd::StopReaction};
void DeliverCmd(EBodyStateCmd cmd) { xb4_deliveredCmdMask |= (1 << int(cmd)); }
public:

View File

@ -42,10 +42,10 @@ CBodyStateInfo::CBodyStateInfo(CActor& actor, EBodyType type) {
}
x1c_additiveStates.reserve(4);
x1c_additiveStates.push_back({pas::EAnimationState::AdditiveIdle, std::make_unique<CABSIdle>()});
x1c_additiveStates.push_back({pas::EAnimationState::AdditiveAim, std::make_unique<CABSAim>()});
x1c_additiveStates.push_back({pas::EAnimationState::AdditiveFlinch, std::make_unique<CABSFlinch>()});
x1c_additiveStates.push_back({pas::EAnimationState::AdditiveReaction, std::make_unique<CABSReaction>()});
x1c_additiveStates.emplace_back(pas::EAnimationState::AdditiveIdle, std::make_unique<CABSIdle>());
x1c_additiveStates.emplace_back(pas::EAnimationState::AdditiveAim, std::make_unique<CABSAim>());
x1c_additiveStates.emplace_back(pas::EAnimationState::AdditiveFlinch, std::make_unique<CABSFlinch>());
x1c_additiveStates.emplace_back(pas::EAnimationState::AdditiveReaction, std::make_unique<CABSReaction>());
}
std::unique_ptr<CBodyState> CBodyStateInfo::SetupRestrictedFlyerBodyStates(int stateId, CActor& actor) const {

View File

@ -9,8 +9,8 @@ class CBoolPOINode : public CPOINode {
bool x38_val = false;
public:
CBoolPOINode();
CBoolPOINode(CInputStream& in);
explicit CBoolPOINode();
explicit CBoolPOINode(CInputStream& in);
bool GetValue() const { return x38_val; }
static CBoolPOINode CopyNodeMinusStartTime(const CBoolPOINode& node, const CCharAnimTime& startTime);
};

View File

@ -47,7 +47,7 @@ private:
std::vector<s32> xb0_animIdxs;
public:
CCharacterInfo(CInputStream& in);
explicit CCharacterInfo(CInputStream& in);
std::string_view GetCharacterName() const { return x4_name; }
CAssetId GetModelId() const { return x14_cmdl; }

View File

@ -13,7 +13,7 @@ class CCharacterSet {
std::map<u32, CCharacterInfo> x4_characters;
public:
CCharacterSet(CInputStream& in);
explicit CCharacterSet(CInputStream& in);
const std::map<u32, CCharacterInfo>& GetCharacterInfoMap() const { return x4_characters; }
};

Some files were not shown because too many files have changed in this diff Show More