mirror of https://github.com/AxioDL/metaforce.git
ANCS cook fixes; initial Tweak DNA pipeline
This commit is contained in:
parent
405a344fdf
commit
4a7d3e8b40
|
@ -31,6 +31,7 @@ add_library(DNACommon
|
||||||
BabeDead.hpp BabeDead.cpp
|
BabeDead.hpp BabeDead.cpp
|
||||||
RigInverter.hpp RigInverter.cpp
|
RigInverter.hpp RigInverter.cpp
|
||||||
AROTBuilder.hpp AROTBuilder.cpp
|
AROTBuilder.hpp AROTBuilder.cpp
|
||||||
|
Tweaks/TweakWriter.hpp
|
||||||
Tweaks/ITweakGame.hpp
|
Tweaks/ITweakGame.hpp
|
||||||
Tweaks/ITweakParticle.hpp
|
Tweaks/ITweakParticle.hpp
|
||||||
Tweaks/ITweakPlayer.hpp
|
Tweaks/ITweakPlayer.hpp
|
||||||
|
|
|
@ -321,7 +321,7 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry) cons
|
||||||
{
|
{
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return hecl::ProjectPath();
|
return hecl::ProjectPath();
|
||||||
return getWorking(entry, BRIDGETYPE::LookupExtractor(*entry));
|
return getWorking(entry, BRIDGETYPE::LookupExtractor(*m_pak.get(), *entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class BRIDGETYPE>
|
template <class BRIDGETYPE>
|
||||||
|
@ -392,11 +392,11 @@ hecl::SystemString PAKRouter<BRIDGETYPE>::getResourceRelativePath(const EntryTyp
|
||||||
const typename BRIDGETYPE::PAKType::Entry* be = lookupEntry(b);
|
const typename BRIDGETYPE::PAKType::Entry* be = lookupEntry(b);
|
||||||
if (!be)
|
if (!be)
|
||||||
return hecl::SystemString();
|
return hecl::SystemString();
|
||||||
hecl::ProjectPath aPath = getWorking(&a, BRIDGETYPE::LookupExtractor(a));
|
hecl::ProjectPath aPath = getWorking(&a, BRIDGETYPE::LookupExtractor(*pak, a));
|
||||||
hecl::SystemString ret;
|
hecl::SystemString ret;
|
||||||
for (int i=0 ; i<aPath.levelCount() ; ++i)
|
for (int i=0 ; i<aPath.levelCount() ; ++i)
|
||||||
ret += _S("../");
|
ret += _S("../");
|
||||||
hecl::ProjectPath bPath = getWorking(be, BRIDGETYPE::LookupExtractor(*be));
|
hecl::ProjectPath bPath = getWorking(be, BRIDGETYPE::LookupExtractor(*pak, *be));
|
||||||
ret += bPath.getRelativePath();
|
ret += bPath.getRelativePath();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -446,7 +446,7 @@ bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool f
|
||||||
{
|
{
|
||||||
for (const auto& item : m_pak->m_firstEntries)
|
for (const auto& item : m_pak->m_firstEntries)
|
||||||
{
|
{
|
||||||
ResExtractor<BRIDGETYPE> extractor = BRIDGETYPE::LookupExtractor(*item);
|
ResExtractor<BRIDGETYPE> extractor = BRIDGETYPE::LookupExtractor(*m_pak.get(), *item);
|
||||||
if (extractor.weight != w)
|
if (extractor.weight != w)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef __DNACOMMON_TWEAKWRITER_HPP__
|
||||||
|
#define __DNACOMMON_TWEAKWRITER_HPP__
|
||||||
|
|
||||||
|
#include "../PAK.hpp"
|
||||||
|
|
||||||
|
namespace DataSpec
|
||||||
|
{
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
bool WriteTweak(const T& tweak, const hecl::ProjectPath& outPath)
|
||||||
|
{
|
||||||
|
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
|
||||||
|
if (w.hasError())
|
||||||
|
return false;
|
||||||
|
tweak.write(w);
|
||||||
|
int64_t rem = w.position() % 32;
|
||||||
|
if (rem)
|
||||||
|
for (int64_t i=0 ; i<32-rem ; ++i)
|
||||||
|
w.writeBytes((atInt8*)"\xff", 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
bool ExtractTweak(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
|
||||||
|
{
|
||||||
|
athena::io::FileWriter writer(outPath.getAbsolutePath());
|
||||||
|
if (writer.isOpen())
|
||||||
|
{
|
||||||
|
T tweak;
|
||||||
|
tweak.read(rs);
|
||||||
|
tweak.toYAMLStream(writer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __DNACOMMON_TWEAKWRITER_HPP__
|
|
@ -409,7 +409,7 @@ void ANCS::CharacterSet::CharacterInfo::write(athena::io::IStreamWriter& writer)
|
||||||
writer.writeUint16Big(sectionCount);
|
writer.writeUint16Big(sectionCount);
|
||||||
|
|
||||||
writer.writeString(name);
|
writer.writeString(name);
|
||||||
cmdl.write(writer);
|
cmdl.UniqueID32::write(writer);
|
||||||
cskr.UniqueID32::write(writer);
|
cskr.UniqueID32::write(writer);
|
||||||
cinf.UniqueID32::write(writer);
|
cinf.UniqueID32::write(writer);
|
||||||
|
|
||||||
|
@ -449,7 +449,7 @@ void ANCS::CharacterSet::CharacterInfo::write(athena::io::IStreamWriter& writer)
|
||||||
|
|
||||||
if (sectionCount > 3)
|
if (sectionCount > 3)
|
||||||
{
|
{
|
||||||
cmdlOverlay.write(writer);
|
cmdlOverlay.UniqueID32::write(writer);
|
||||||
cskrOverlay.UniqueID32::write(writer);
|
cskrOverlay.UniqueID32::write(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1107,6 +1107,12 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath,
|
||||||
/* Set Character Resource IDs */
|
/* Set Character Resource IDs */
|
||||||
for (ANCS::CharacterSet::CharacterInfo& ch : ancs.characterSet.characters)
|
for (ANCS::CharacterSet::CharacterInfo& ch : ancs.characterSet.characters)
|
||||||
{
|
{
|
||||||
|
ch.cmdl = UniqueID32{};
|
||||||
|
ch.cskr = UniqueID32{};
|
||||||
|
ch.cinf = UniqueID32{};
|
||||||
|
ch.cmdlOverlay = UniqueID32{};
|
||||||
|
ch.cskrOverlay = UniqueID32{};
|
||||||
|
|
||||||
hecl::SystemStringView chSysName(ch.name);
|
hecl::SystemStringView chSysName(ch.name);
|
||||||
ch.cskr = inPath.ensureAuxInfo(chSysName.sys_str() + _S(".CSKR"));
|
ch.cskr = inPath.ensureAuxInfo(chSysName.sys_str() + _S(".CSKR"));
|
||||||
|
|
||||||
|
@ -1119,12 +1125,17 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath,
|
||||||
const DNAANCS::Actor::Armature& arm = actor.armatures[sub.armature];
|
const DNAANCS::Actor::Armature& arm = actor.armatures[sub.armature];
|
||||||
hecl::SystemStringView armSysName(arm.name);
|
hecl::SystemStringView armSysName(arm.name);
|
||||||
ch.cinf = inPath.ensureAuxInfo(armSysName.sys_str() + _S(".CINF"));
|
ch.cinf = inPath.ensureAuxInfo(armSysName.sys_str() + _S(".CINF"));
|
||||||
|
ch.cmdl = sub.mesh;
|
||||||
|
if (sub.overlayMeshes.size())
|
||||||
|
{
|
||||||
|
ch.cmdlOverlay = sub.overlayMeshes[0].second;
|
||||||
|
ch.cskrOverlay = inPath.ensureAuxInfo(chSysName.sys_str() + _S(".over.CSKR"));
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ch.cskrOverlay = inPath.ensureAuxInfo(chSysName.sys_str() + _S(".over.CSKR"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set Animation Resource IDs */
|
/* Set Animation Resource IDs */
|
||||||
|
@ -1143,7 +1154,7 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath,
|
||||||
for (const DNAANCS::Actor::Armature& arm : actor.armatures)
|
for (const DNAANCS::Actor::Armature& arm : actor.armatures)
|
||||||
{
|
{
|
||||||
hecl::SystemStringView sysStr(arm.name);
|
hecl::SystemStringView sysStr(arm.name);
|
||||||
hecl::ProjectPath pathOut = inPath.getCookedPath(SpecEntMP1).ensureAuxInfo(sysStr.sys_str() + _S(".CINF"));
|
hecl::ProjectPath pathOut = inPath.ensureAuxInfo(sysStr.sys_str() + _S(".CINF")).getCookedPath(SpecEntMP1);
|
||||||
athena::io::FileWriter w(pathOut.getAbsolutePath(), true, false);
|
athena::io::FileWriter w(pathOut.getAbsolutePath(), true, false);
|
||||||
if (w.hasError())
|
if (w.hasError())
|
||||||
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
|
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
|
||||||
|
@ -1214,7 +1225,7 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath,
|
||||||
skinIO.close();
|
skinIO.close();
|
||||||
|
|
||||||
hecl::SystemStringView sysStr(ch.name);
|
hecl::SystemStringView sysStr(ch.name);
|
||||||
hecl::ProjectPath skinPath = inPath.getCookedPath(SpecEntMP1PC).ensureAuxInfo(sysStr.sys_str() + _S(".CSKR"));
|
hecl::ProjectPath skinPath = inPath.ensureAuxInfo(sysStr.sys_str() + _S(".CSKR")).getCookedPath(SpecEntMP1PC);
|
||||||
athena::io::FileWriter skinOut(skinPath.getAbsolutePath(), true, false);
|
athena::io::FileWriter skinOut(skinPath.getAbsolutePath(), true, false);
|
||||||
if (skinOut.hasError())
|
if (skinOut.hasError())
|
||||||
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
|
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
|
||||||
|
|
|
@ -117,7 +117,7 @@ int CINF::RecursiveAddArmatureBone(const Armature& armature, const Armature::Bon
|
||||||
const Armature::Bone* child;
|
const Armature::Bone* child;
|
||||||
boneOut.linked.push_back(parent);
|
boneOut.linked.push_back(parent);
|
||||||
for (size_t i=0 ; (child = armature.getChild(bone, i)) ; ++i)
|
for (size_t i=0 ; (child = armature.getChild(bone, i)) ; ++i)
|
||||||
boneOut.linked.push_back(RecursiveAddArmatureBone(armature, child, boneOut.id, selId, idMap, nameMap));
|
boneOut.linked.push_back(RecursiveAddArmatureBone(armature, child, boneOut.id, curId, idMap, nameMap));
|
||||||
|
|
||||||
return boneOut.id;
|
return boneOut.id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
#include "MAPA.hpp"
|
#include "MAPA.hpp"
|
||||||
#include "FRME.hpp"
|
#include "FRME.hpp"
|
||||||
|
|
||||||
|
#include "../DNACommon/Tweaks/TweakWriter.hpp"
|
||||||
|
#include "Tweaks/CTweakPlayerRes.hpp"
|
||||||
|
|
||||||
namespace DataSpec
|
namespace DataSpec
|
||||||
{
|
{
|
||||||
namespace DNAMP1
|
namespace DNAMP1
|
||||||
|
@ -270,7 +273,7 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK::Entry& entry)
|
ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK& pak, const PAK::Entry& entry)
|
||||||
{
|
{
|
||||||
switch (entry.type)
|
switch (entry.type)
|
||||||
{
|
{
|
||||||
|
@ -312,6 +315,17 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK::Entry& entry)
|
||||||
return {DNAFont::ExtractFONT<UniqueID32>, nullptr, {_S(".yaml")}};
|
return {DNAFont::ExtractFONT<UniqueID32>, nullptr, {_S(".yaml")}};
|
||||||
case SBIG('DGRP'):
|
case SBIG('DGRP'):
|
||||||
return {DNADGRP::ExtractDGRP<UniqueID32>, nullptr, {_S(".yaml")}};
|
return {DNADGRP::ExtractDGRP<UniqueID32>, nullptr, {_S(".yaml")}};
|
||||||
|
case SBIG('CTWK'):
|
||||||
|
{
|
||||||
|
bool named;
|
||||||
|
std::string name = pak.bestEntryName(entry, named);
|
||||||
|
if (named)
|
||||||
|
{
|
||||||
|
if (!name.compare("PlayerRes"))
|
||||||
|
return {ExtractTweak<CTweakPlayerRes>, nullptr, {_S(".yaml")}};
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
const nod::Node& node,
|
const nod::Node& node,
|
||||||
bool doExtract=true);
|
bool doExtract=true);
|
||||||
void build();
|
void build();
|
||||||
static ResExtractor<PAKBridge> LookupExtractor(const PAK::Entry& entry);
|
static ResExtractor<PAKBridge> LookupExtractor(const PAK& pak, const PAK::Entry& entry);
|
||||||
const std::string& getName() const {return m_node.getName();}
|
const std::string& getName() const {return m_node.getName();}
|
||||||
const hecl::SystemString& getLevelString() const {return m_levelString;}
|
const hecl::SystemString& getLevelString() const {return m_levelString;}
|
||||||
using PAKType = PAK;
|
using PAKType = PAK;
|
||||||
|
|
|
@ -213,7 +213,7 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const DNAMP1::PAK::Entry& entry)
|
ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const DNAMP1::PAK& pak, const DNAMP1::PAK::Entry& entry)
|
||||||
{
|
{
|
||||||
switch (entry.type)
|
switch (entry.type)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
const nod::Node& node,
|
const nod::Node& node,
|
||||||
bool doExtract=true);
|
bool doExtract=true);
|
||||||
void build();
|
void build();
|
||||||
static ResExtractor<PAKBridge> LookupExtractor(const DNAMP1::PAK::Entry& entry);
|
static ResExtractor<PAKBridge> LookupExtractor(const DNAMP1::PAK& pak, const DNAMP1::PAK::Entry& entry);
|
||||||
const std::string& getName() const {return m_node.getName();}
|
const std::string& getName() const {return m_node.getName();}
|
||||||
const hecl::SystemString& getLevelString() const {return m_levelString;}
|
const hecl::SystemString& getLevelString() const {return m_levelString;}
|
||||||
|
|
||||||
|
|
|
@ -223,7 +223,7 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK::Entry& entry)
|
ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK& pak, const PAK::Entry& entry)
|
||||||
{
|
{
|
||||||
switch (entry.type)
|
switch (entry.type)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
const nod::Node& node,
|
const nod::Node& node,
|
||||||
bool doExtract=true);
|
bool doExtract=true);
|
||||||
void build();
|
void build();
|
||||||
static ResExtractor<PAKBridge> LookupExtractor(const PAK::Entry& entry);
|
static ResExtractor<PAKBridge> LookupExtractor(const PAK& pak, const PAK::Entry& entry);
|
||||||
inline const std::string& getName() const {return m_node.getName();}
|
inline const std::string& getName() const {return m_node.getName();}
|
||||||
inline hecl::SystemString getLevelString() const {return m_levelString;}
|
inline hecl::SystemString getLevelString() const {return m_levelString;}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#include "DNACommon/CRSC.hpp"
|
#include "DNACommon/CRSC.hpp"
|
||||||
#include "DNACommon/DPSC.hpp"
|
#include "DNACommon/DPSC.hpp"
|
||||||
#include "DNACommon/DGRP.hpp"
|
#include "DNACommon/DGRP.hpp"
|
||||||
|
#include "DNACommon/Tweaks/TweakWriter.hpp"
|
||||||
|
#include "DNAMP1/Tweaks/CTweakPlayerRes.hpp"
|
||||||
|
|
||||||
#include "hecl/ClientProcess.hpp"
|
#include "hecl/ClientProcess.hpp"
|
||||||
|
|
||||||
|
@ -346,6 +348,8 @@ struct SpecMP1 : SpecBase
|
||||||
return true;
|
return true;
|
||||||
else if (!strcmp(classType, DNAFont::FONT<UniqueID32>::DNAType()))
|
else if (!strcmp(classType, DNAFont::FONT<UniqueID32>::DNAType()))
|
||||||
return true;
|
return true;
|
||||||
|
else if (!strcmp(classType, DNAMP1::CTweakPlayerRes::DNAType()))
|
||||||
|
return true;
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -485,6 +489,12 @@ struct SpecMP1 : SpecBase
|
||||||
font.read(reader);
|
font.read(reader);
|
||||||
DNAFont::WriteFONT(font, out);
|
DNAFont::WriteFONT(font, out);
|
||||||
}
|
}
|
||||||
|
else if (!classStr.compare(DNAMP1::CTweakPlayerRes::DNAType()))
|
||||||
|
{
|
||||||
|
DNAMP1::CTweakPlayerRes playerRes;
|
||||||
|
playerRes.read(reader);
|
||||||
|
WriteTweak(playerRes, out);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
progress(_S("Done"));
|
progress(_S("Done"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,9 +138,9 @@ SObjectTag ProjectResourceFactoryMP1::TagFromPath(const hecl::ProjectPath& path,
|
||||||
resTag.type = SBIG('STRG');
|
resTag.type = SBIG('STRG');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (!strcmp(className, "FONT"))
|
else if (!strcmp(className, "DataSpec::DNAMP1::CTweakPlayerRes"))
|
||||||
{
|
{
|
||||||
resTag.type = SBIG('FONT');
|
resTag.type = SBIG('CTWK');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -114,7 +114,8 @@ CCharacterFactory::CreateCharacter(int charIdx, bool loop,
|
||||||
const_cast<CCharacterFactory*>(this)->x70_cacheResPool.GetObj({FourCC(), charInfo.GetModelId()}, charParm);
|
const_cast<CCharacterFactory*>(this)->x70_cacheResPool.GetObj({FourCC(), charInfo.GetModelId()}, charParm);
|
||||||
|
|
||||||
rstl::optional_object<TToken<CMorphableSkinnedModel>> iceModel;
|
rstl::optional_object<TToken<CMorphableSkinnedModel>> iceModel;
|
||||||
if (charInfo.GetIceModelId() && charInfo.GetIceSkinRulesId())
|
if (charInfo.GetIceModelId() != 0xffffffff &&
|
||||||
|
charInfo.GetIceSkinRulesId() != 0xffffffff)
|
||||||
iceModel.emplace(const_cast<CCharacterFactory*>(this)->x70_cacheResPool.GetObj({FourCC(1), charInfo.GetIceModelId()}, charParm));
|
iceModel.emplace(const_cast<CCharacterFactory*>(this)->x70_cacheResPool.GetObj({FourCC(1), charInfo.GetIceModelId()}, charParm));
|
||||||
|
|
||||||
return std::make_unique<CAnimData>(x68_selfId, charInfo, defaultAnim, charIdx, loop,
|
return std::make_unique<CAnimData>(x68_selfId, charInfo, defaultAnim, charIdx, loop,
|
||||||
|
|
Loading…
Reference in New Issue