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
|
||||
RigInverter.hpp RigInverter.cpp
|
||||
AROTBuilder.hpp AROTBuilder.cpp
|
||||
Tweaks/TweakWriter.hpp
|
||||
Tweaks/ITweakGame.hpp
|
||||
Tweaks/ITweakParticle.hpp
|
||||
Tweaks/ITweakPlayer.hpp
|
||||
|
|
|
@ -321,7 +321,7 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry) cons
|
|||
{
|
||||
if (!entry)
|
||||
return hecl::ProjectPath();
|
||||
return getWorking(entry, BRIDGETYPE::LookupExtractor(*entry));
|
||||
return getWorking(entry, BRIDGETYPE::LookupExtractor(*m_pak.get(), *entry));
|
||||
}
|
||||
|
||||
template <class BRIDGETYPE>
|
||||
|
@ -392,11 +392,11 @@ hecl::SystemString PAKRouter<BRIDGETYPE>::getResourceRelativePath(const EntryTyp
|
|||
const typename BRIDGETYPE::PAKType::Entry* be = lookupEntry(b);
|
||||
if (!be)
|
||||
return hecl::SystemString();
|
||||
hecl::ProjectPath aPath = getWorking(&a, BRIDGETYPE::LookupExtractor(a));
|
||||
hecl::ProjectPath aPath = getWorking(&a, BRIDGETYPE::LookupExtractor(*pak, a));
|
||||
hecl::SystemString ret;
|
||||
for (int i=0 ; i<aPath.levelCount() ; ++i)
|
||||
ret += _S("../");
|
||||
hecl::ProjectPath bPath = getWorking(be, BRIDGETYPE::LookupExtractor(*be));
|
||||
hecl::ProjectPath bPath = getWorking(be, BRIDGETYPE::LookupExtractor(*pak, *be));
|
||||
ret += bPath.getRelativePath();
|
||||
return ret;
|
||||
}
|
||||
|
@ -446,7 +446,7 @@ bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool f
|
|||
{
|
||||
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)
|
||||
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.writeString(name);
|
||||
cmdl.write(writer);
|
||||
cmdl.UniqueID32::write(writer);
|
||||
cskr.UniqueID32::write(writer);
|
||||
cinf.UniqueID32::write(writer);
|
||||
|
||||
|
@ -449,7 +449,7 @@ void ANCS::CharacterSet::CharacterInfo::write(athena::io::IStreamWriter& writer)
|
|||
|
||||
if (sectionCount > 3)
|
||||
{
|
||||
cmdlOverlay.write(writer);
|
||||
cmdlOverlay.UniqueID32::write(writer);
|
||||
cskrOverlay.UniqueID32::write(writer);
|
||||
}
|
||||
|
||||
|
@ -1107,6 +1107,12 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath,
|
|||
/* Set Character Resource IDs */
|
||||
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);
|
||||
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];
|
||||
hecl::SystemStringView armSysName(arm.name);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ch.cskrOverlay = inPath.ensureAuxInfo(chSysName.sys_str() + _S(".over.CSKR"));
|
||||
}
|
||||
|
||||
/* Set Animation Resource IDs */
|
||||
|
@ -1143,7 +1154,7 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath,
|
|||
for (const DNAANCS::Actor::Armature& arm : actor.armatures)
|
||||
{
|
||||
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);
|
||||
if (w.hasError())
|
||||
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
|
||||
|
@ -1214,7 +1225,7 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath,
|
|||
skinIO.close();
|
||||
|
||||
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);
|
||||
if (skinOut.hasError())
|
||||
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;
|
||||
boneOut.linked.push_back(parent);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#include "MAPA.hpp"
|
||||
#include "FRME.hpp"
|
||||
|
||||
#include "../DNACommon/Tweaks/TweakWriter.hpp"
|
||||
#include "Tweaks/CTweakPlayerRes.hpp"
|
||||
|
||||
namespace DataSpec
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -312,6 +315,17 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK::Entry& entry)
|
|||
return {DNAFont::ExtractFONT<UniqueID32>, nullptr, {_S(".yaml")}};
|
||||
case SBIG('DGRP'):
|
||||
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 {};
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
const nod::Node& node,
|
||||
bool doExtract=true);
|
||||
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 hecl::SystemString& getLevelString() const {return m_levelString;}
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
const nod::Node& node,
|
||||
bool doExtract=true);
|
||||
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 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)
|
||||
{
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
const nod::Node& node,
|
||||
bool doExtract=true);
|
||||
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 hecl::SystemString getLevelString() const {return m_levelString;}
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "DNACommon/CRSC.hpp"
|
||||
#include "DNACommon/DPSC.hpp"
|
||||
#include "DNACommon/DGRP.hpp"
|
||||
#include "DNACommon/Tweaks/TweakWriter.hpp"
|
||||
#include "DNAMP1/Tweaks/CTweakPlayerRes.hpp"
|
||||
|
||||
#include "hecl/ClientProcess.hpp"
|
||||
|
||||
|
@ -346,6 +348,8 @@ struct SpecMP1 : SpecBase
|
|||
return true;
|
||||
else if (!strcmp(classType, DNAFont::FONT<UniqueID32>::DNAType()))
|
||||
return true;
|
||||
else if (!strcmp(classType, DNAMP1::CTweakPlayerRes::DNAType()))
|
||||
return true;
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
@ -485,6 +489,12 @@ struct SpecMP1 : SpecBase
|
|||
font.read(reader);
|
||||
DNAFont::WriteFONT(font, out);
|
||||
}
|
||||
else if (!classStr.compare(DNAMP1::CTweakPlayerRes::DNAType()))
|
||||
{
|
||||
DNAMP1::CTweakPlayerRes playerRes;
|
||||
playerRes.read(reader);
|
||||
WriteTweak(playerRes, out);
|
||||
}
|
||||
}
|
||||
progress(_S("Done"));
|
||||
}
|
||||
|
|
|
@ -138,9 +138,9 @@ SObjectTag ProjectResourceFactoryMP1::TagFromPath(const hecl::ProjectPath& path,
|
|||
resTag.type = SBIG('STRG');
|
||||
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 false;
|
||||
|
|
|
@ -114,7 +114,8 @@ CCharacterFactory::CreateCharacter(int charIdx, bool loop,
|
|||
const_cast<CCharacterFactory*>(this)->x70_cacheResPool.GetObj({FourCC(), charInfo.GetModelId()}, charParm);
|
||||
|
||||
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));
|
||||
|
||||
return std::make_unique<CAnimData>(x68_selfId, charInfo, defaultAnim, charIdx, loop,
|
||||
|
|
Loading…
Reference in New Issue