ANCS cook fixes; initial Tweak DNA pipeline

This commit is contained in:
Jack Andersen 2016-08-31 09:58:21 -10:00
parent 405a344fdf
commit 4a7d3e8b40
14 changed files with 96 additions and 20 deletions

View File

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

View File

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

View File

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

View File

@ -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"),

View File

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

View File

@ -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 {};
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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