mirror of https://github.com/AxioDL/metaforce.git
Add texture cache containing information about textures
This commit is contained in:
parent
0ab08daae7
commit
9d2cbf61ed
|
@ -198,6 +198,12 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PAKEntryReadStream beginReadStreamForId(const IDType& id, bool silenceWarnings = false) {
|
||||||
|
const nod::Node* node;
|
||||||
|
const EntryType* entry = lookupEntry(id, &node, silenceWarnings);
|
||||||
|
return entry->beginReadStream(*node);
|
||||||
|
}
|
||||||
|
|
||||||
const typename CharacterAssociations<IDType>::RigPair* lookupCMDLRigPair(const IDType& id) const;
|
const typename CharacterAssociations<IDType>::RigPair* lookupCMDLRigPair(const IDType& id) const;
|
||||||
const typename CharacterAssociations<IDType>::MultimapIteratorPair
|
const typename CharacterAssociations<IDType>::MultimapIteratorPair
|
||||||
lookupCharacterAttachmentRigs(const IDType& id) const;
|
lookupCharacterAttachmentRigs(const IDType& id) const;
|
||||||
|
|
|
@ -1595,33 +1595,66 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class Op>
|
||||||
|
void DataSpec::TXTR::PaletteMeta::Enumerate(typename Op::StreamT& s) {
|
||||||
|
Do<Op>({"format"}, format, s);
|
||||||
|
Do<Op>({"elementCount"}, elementCount, s);
|
||||||
|
Do<Op>({"dolphinHash"}, dolphinHash, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
AT_SPECIALIZE_DNA_YAML(DataSpec::TXTR::PaletteMeta)
|
||||||
|
|
||||||
|
const char* DataSpec::TXTR::PaletteMeta::DNAType() {
|
||||||
|
return "DataSpec::TXTR::PaletteMeta";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Op>
|
||||||
|
void DataSpec::TXTR::Meta::Enumerate(typename Op::StreamT& s) {
|
||||||
|
Do<Op>({"format"}, format, s);
|
||||||
|
Do<Op>({"mips"}, mips, s);
|
||||||
|
Do<Op>({"width"}, width, s);
|
||||||
|
Do<Op>({"height"}, height, s);
|
||||||
|
Do<Op>({"dolphinHash"}, dolphinHash, s);
|
||||||
|
Do<Op>({"hasPalette"}, hasPalette, s);
|
||||||
|
if (hasPalette)
|
||||||
|
Do<Op>({"palette"}, palette, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
AT_SPECIALIZE_DNA_YAML(DataSpec::TXTR::Meta)
|
||||||
|
|
||||||
|
const char* DataSpec::TXTR::Meta::DNAType() {
|
||||||
|
return "DataSpec::TXTR::Meta";
|
||||||
|
}
|
||||||
|
|
||||||
static const atInt32 RetroToDol[11] {
|
static const atInt32 RetroToDol[11] {
|
||||||
0, 1, 2, 3, 8, 9, -1, 4, 5, 6, 14
|
0, 1, 2, 3, 8, 9, -1, 4, 5, 6, 14
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string TXTR::CalculateDolphinName(DataSpec::PAKEntryReadStream& rs) {
|
TXTR::Meta TXTR::GetMetaData(DataSpec::PAKEntryReadStream& rs) {
|
||||||
atUint32 format = RetroToDol[rs.readUint32Big()];
|
atUint32 retroFormat = rs.readUint32Big();
|
||||||
|
atUint32 format = RetroToDol[retroFormat];
|
||||||
if (format == UINT32_MAX)
|
if (format == UINT32_MAX)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
atUint16 width = rs.readUint16Big();
|
Meta meta;
|
||||||
atUint16 height = rs.readUint16Big();
|
meta.format = retroFormat;
|
||||||
atUint32 mips = rs.readUint32Big();
|
meta.width = rs.readUint16Big();
|
||||||
std::string res = fmt::format(fmt("tex1_{}x{}{}"), width, height, mips > 1 ? "_m" : "");
|
meta.height = rs.readUint16Big();
|
||||||
atUint64 palHash = 0;
|
meta.mips = rs.readUint32Big();
|
||||||
bool hasPalette = false;
|
atUint32 textureSize = meta.width * meta.height;
|
||||||
atUint32 textureSize = width * height;
|
|
||||||
if (format == 8 || format == 9) {
|
if (format == 8 || format == 9) {
|
||||||
hasPalette = true;
|
meta.hasPalette = true;
|
||||||
atUint32 paletteFormat = rs.readUint32Big();
|
PaletteMeta& palMeta = meta.palette;
|
||||||
|
palMeta.format = rs.readUint32Big();
|
||||||
atUint16 palWidth = rs.readUint16Big();
|
atUint16 palWidth = rs.readUint16Big();
|
||||||
atUint16 palHeight = rs.readUint16Big();
|
atUint16 palHeight = rs.readUint16Big();
|
||||||
|
palMeta.elementCount = palWidth * palHeight;
|
||||||
atUint32 palSize = atUint32(palWidth * palHeight * 2);
|
atUint32 palSize = atUint32(palWidth * palHeight * 2);
|
||||||
if (format == 4)
|
if (palMeta.format == 4)
|
||||||
textureSize /= 2;
|
textureSize /= 2;
|
||||||
std::unique_ptr<u8[]> palData(new u8[palSize]);
|
std::unique_ptr<u8[]> palData(new u8[palSize]);
|
||||||
rs.readUBytesToBuf(palData.get(), palSize);
|
rs.readUBytesToBuf(palData.get(), palSize);
|
||||||
palHash = XXH64(palData.get(), palSize, 0);
|
palMeta.dolphinHash = XXH64(palData.get(), palSize, 0);
|
||||||
} else {
|
} else {
|
||||||
switch(format) {
|
switch(format) {
|
||||||
case 0: // I4
|
case 0: // I4
|
||||||
|
@ -1642,13 +1675,9 @@ std::string TXTR::CalculateDolphinName(DataSpec::PAKEntryReadStream& rs) {
|
||||||
}
|
}
|
||||||
std::unique_ptr<u8[]> textureData(new u8[textureSize]);
|
std::unique_ptr<u8[]> textureData(new u8[textureSize]);
|
||||||
rs.readUBytesToBuf(textureData.get(), textureSize);
|
rs.readUBytesToBuf(textureData.get(), textureSize);
|
||||||
atUint64 texHash = XXH64(textureData.get(), textureSize, 0);
|
meta.dolphinHash = XXH64(textureData.get(), textureSize, 0);
|
||||||
res += fmt::format(fmt("_{:016X}"), texHash);
|
|
||||||
if (hasPalette)
|
|
||||||
res += fmt::format(fmt("_{:016X}"), palHash);
|
|
||||||
res += fmt::format(fmt("_{}"), format);
|
|
||||||
|
|
||||||
return res;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace DataSpec
|
} // namespace DataSpec
|
||||||
|
|
|
@ -6,10 +6,29 @@ namespace DataSpec {
|
||||||
class PAKEntryReadStream;
|
class PAKEntryReadStream;
|
||||||
|
|
||||||
struct TXTR {
|
struct TXTR {
|
||||||
|
struct PaletteMeta : BigDNAVYaml {
|
||||||
|
AT_DECL_EXPLICIT_DNA_YAML
|
||||||
|
AT_DECL_DNAV
|
||||||
|
Value<atUint32> format = UINT_MAX;
|
||||||
|
Value<atUint32> elementCount = 0;
|
||||||
|
Value<atUint64> dolphinHash = 0;
|
||||||
|
};
|
||||||
|
struct Meta : BigDNAVYaml {
|
||||||
|
AT_DECL_EXPLICIT_DNA_YAML
|
||||||
|
AT_DECL_DNAV
|
||||||
|
Value<atUint32> format = UINT_MAX;
|
||||||
|
Value<atUint32> mips = 0;
|
||||||
|
Value<atUint16> width = 0;
|
||||||
|
Value<atUint16> height = 0;
|
||||||
|
Value<atUint64> dolphinHash = 0;
|
||||||
|
Value<bool> hasPalette = false;
|
||||||
|
PaletteMeta palette;
|
||||||
|
};
|
||||||
|
|
||||||
static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
|
static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
|
||||||
static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath);
|
static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath);
|
||||||
static bool CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath);
|
static bool CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath);
|
||||||
static std::string CalculateDolphinName(PAKEntryReadStream& rs);
|
static TXTR::Meta GetMetaData(PAKEntryReadStream& rs);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace DataSpec
|
} // namespace DataSpec
|
||||||
|
|
|
@ -578,6 +578,8 @@ static void _ConstructMaterial(Stream& out, const MAT& material, unsigned groupI
|
||||||
_GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, TexLink("Alpha", 1, true)); break;
|
_GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, TexLink("Alpha", 1, true)); break;
|
||||||
case 0x54A92F25: /* RetroShader: ObjLightmap, KColorDiffuse, Alpha=KAlpha */
|
case 0x54A92F25: /* RetroShader: ObjLightmap, KColorDiffuse, Alpha=KAlpha */
|
||||||
_GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_kcol, "Alpha"_kcola); break;
|
_GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_kcol, "Alpha"_kcola); break;
|
||||||
|
case 0x54C6204C:
|
||||||
|
_GenerateRootShader(out, "RetroShader"); break;
|
||||||
case 0x5A62D5F0: /* RetroShader: Lightmap, Diffuse, UnusedExtendedSpecular?, Alpha=DiffuseAlpha */
|
case 0x5A62D5F0: /* RetroShader: Lightmap, Diffuse, UnusedExtendedSpecular?, Alpha=DiffuseAlpha */
|
||||||
_GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, TexLink("Alpha", 1, true)); break;
|
_GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, TexLink("Alpha", 1, true)); break;
|
||||||
case 0x5CB59821: /* RetroShader: Diffuse, UnusedSpecular?, Alpha=KAlpha */
|
case 0x5CB59821: /* RetroShader: Diffuse, UnusedSpecular?, Alpha=KAlpha */
|
||||||
|
@ -606,6 +608,8 @@ static void _ConstructMaterial(Stream& out, const MAT& material, unsigned groupI
|
||||||
_GenerateRootShader(out, "RetroShader", WhiteColorLink("Specular"), "Reflection"_tex); break;
|
_GenerateRootShader(out, "RetroShader", WhiteColorLink("Specular"), "Reflection"_tex); break;
|
||||||
case 0x846215DA: /* RetroShader: Diffuse, Specular, Reflection, Alpha=DiffuseAlpha, IndirectTex */
|
case 0x846215DA: /* RetroShader: Diffuse, Specular, Reflection, Alpha=DiffuseAlpha, IndirectTex */
|
||||||
_GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, "IndirectTex"_tex, TexLink("Alpha", 0, true)); break;
|
_GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, "IndirectTex"_tex, TexLink("Alpha", 0, true)); break;
|
||||||
|
case 0x8E916C01: /* RetroShader: NULL, all inputs 0 */
|
||||||
|
_GenerateRootShader(out, "RetroShader"); break;
|
||||||
case 0x957709F8: /* RetroShader: Emissive, Alpha=1.0 */
|
case 0x957709F8: /* RetroShader: Emissive, Alpha=1.0 */
|
||||||
_GenerateRootShader(out, "RetroShader", "Emissive"_tex); break;
|
_GenerateRootShader(out, "RetroShader", "Emissive"_tex); break;
|
||||||
case 0x96ABB2D3: /* RetroShader: Lightmap, Diffuse, Alpha=DiffuseAlpha */
|
case 0x96ABB2D3: /* RetroShader: Lightmap, Diffuse, Alpha=DiffuseAlpha */
|
||||||
|
|
|
@ -136,6 +136,32 @@ struct OriginalIDs {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TextureCache {
|
||||||
|
static void Generate(PAKRouter<DNAMP1::PAKBridge>& pakRouter, hecl::Database::Project& project) {
|
||||||
|
std::unordered_map<UniqueID32, TXTR::Meta> metaMap;
|
||||||
|
|
||||||
|
pakRouter.enumerateResources([&](const DNAMP1::PAK::Entry* ent) {
|
||||||
|
if (ent->type == FOURCC('TXTR') && metaMap.find(ent->id) == metaMap.end()) {
|
||||||
|
PAKEntryReadStream rs = pakRouter.beginReadStreamForId(ent->id);
|
||||||
|
metaMap[ent->id] = TXTR::GetMetaData(rs);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
athena::io::YAMLDocWriter yamlW("MP1TextureCache");
|
||||||
|
for (const auto& pair : metaMap) {
|
||||||
|
hecl::ProjectPath path = pakRouter.getWorking(pair.first);
|
||||||
|
auto rec = yamlW.enterSubRecord(path.getRelativePathUTF8().data());
|
||||||
|
pair.second.write(yamlW);
|
||||||
|
}
|
||||||
|
|
||||||
|
hecl::ProjectPath path(project.getProjectWorkingPath(), "MP1/!texture_cache.yaml");
|
||||||
|
path.makeDirChain(false);
|
||||||
|
athena::io::FileWriter fileW(path.getAbsolutePath());
|
||||||
|
yamlW.finish(&fileW);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct SpecMP1 : SpecBase {
|
struct SpecMP1 : SpecBase {
|
||||||
bool checkStandaloneID(const char* id) const { return !memcmp(id, "GM8", 3); }
|
bool checkStandaloneID(const char* id) const { return !memcmp(id, "GM8", 3); }
|
||||||
|
|
||||||
|
@ -394,6 +420,8 @@ struct SpecMP1 : SpecBase {
|
||||||
|
|
||||||
/* Generate original ID mapping for MLVL and SCAN entries - marks complete project */
|
/* Generate original ID mapping for MLVL and SCAN entries - marks complete project */
|
||||||
OriginalIDs::Generate(m_pakRouter, m_project);
|
OriginalIDs::Generate(m_pakRouter, m_project);
|
||||||
|
/* Generate Texture Cache containing meta data for every texture file */
|
||||||
|
TextureCache::Generate(m_pakRouter, m_project);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -744,8 +772,8 @@ struct SpecMP1 : SpecBase {
|
||||||
progress(_SYS_STR("Collision Mesh"));
|
progress(_SYS_STR("Collision Mesh"));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
meshCompiles.push_back(ds.compileMesh(
|
meshCompiles.push_back(
|
||||||
mesh, fast ? hecl::HMDLTopology::Triangles : hecl::HMDLTopology::TriStrips, -1, !m_pc));
|
ds.compileMesh(mesh, fast ? hecl::HMDLTopology::Triangles : hecl::HMDLTopology::TriStrips, -1, !m_pc));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!colMesh)
|
if (!colMesh)
|
||||||
|
|
Loading…
Reference in New Issue