MP1 YAML STRG integration

This commit is contained in:
Jack Andersen 2015-07-31 14:38:35 -10:00
parent 5075cb6dc4
commit df2adc10da
5 changed files with 100 additions and 27 deletions

View File

@ -2,7 +2,7 @@
#define __DNA_COMMON_HPP__ #define __DNA_COMMON_HPP__
#include <stdio.h> #include <stdio.h>
#include <Athena/DNA.hpp> #include <Athena/DNAYaml.hpp>
#include <NOD/DiscBase.hpp> #include <NOD/DiscBase.hpp>
#include "HECL/HECL.hpp" #include "HECL/HECL.hpp"
#include "HECL/Database.hpp" #include "HECL/Database.hpp"
@ -14,9 +14,10 @@ extern LogVisor::LogModule LogDNACommon;
/* This comes up a great deal */ /* This comes up a great deal */
typedef Athena::io::DNA<Athena::BigEndian> BigDNA; typedef Athena::io::DNA<Athena::BigEndian> BigDNA;
typedef Athena::io::DNAYaml<Athena::BigEndian> BigYAML;
/* FourCC with DNA read/write */ /* FourCC with DNA read/write */
class FourCC final : public BigDNA, public HECL::FourCC class FourCC final : public BigYAML, public HECL::FourCC
{ {
public: public:
FourCC() : HECL::FourCC() {} FourCC() : HECL::FourCC() {}
@ -30,10 +31,14 @@ public:
{reader.readUBytesToBuf(fcc, 4);} {reader.readUBytesToBuf(fcc, 4);}
inline void write(Athena::io::IStreamWriter& writer) const inline void write(Athena::io::IStreamWriter& writer) const
{writer.writeUBytes((atUint8*)fcc, 4);} {writer.writeUBytes((atUint8*)fcc, 4);}
inline void fromYAML(Athena::io::YAMLDocReader& reader)
{std::string rs = reader.readString(nullptr); strncpy(fcc, rs.c_str(), 4);}
inline void toYAML(Athena::io::YAMLDocWriter& writer) const
{writer.writeString(nullptr, std::string(fcc, 4));}
}; };
/* PAK 32-bit Unique ID */ /* PAK 32-bit Unique ID */
class UniqueID32 : public BigDNA class UniqueID32 : public BigYAML
{ {
uint32_t m_id; uint32_t m_id;
public: public:
@ -42,6 +47,10 @@ public:
{m_id = reader.readUint32();} {m_id = reader.readUint32();}
inline void write(Athena::io::IStreamWriter& writer) const inline void write(Athena::io::IStreamWriter& writer) const
{writer.writeUint32(m_id);} {writer.writeUint32(m_id);}
inline void fromYAML(Athena::io::YAMLDocReader& reader)
{m_id = reader.readUint32(nullptr);}
inline void toYAML(Athena::io::YAMLDocWriter& writer) const
{writer.writeUint32(nullptr, m_id);}
inline bool operator!=(const UniqueID32& other) const {return m_id != other.m_id;} inline bool operator!=(const UniqueID32& other) const {return m_id != other.m_id;}
inline bool operator==(const UniqueID32& other) const {return m_id == other.m_id;} inline bool operator==(const UniqueID32& other) const {return m_id == other.m_id;}

View File

@ -50,7 +50,7 @@ ResExtractor PAKBridge::LookupExtractor(const PAK::Entry& entry)
switch (entry.type.toUint32()) switch (entry.type.toUint32())
{ {
case SBIG('STRG'): case SBIG('STRG'):
return {STRG::Extract, ".as"}; return {STRG::Extract, ".yaml"};
case SBIG('TXTR'): case SBIG('TXTR'):
return {TXTR::Extract, ".png"}; return {TXTR::Extract, ".png"};
case SBIG('CMDL'): case SBIG('CMDL'):

View File

@ -8,9 +8,9 @@ namespace Retro
namespace DNAMP1 namespace DNAMP1
{ {
struct MLVL : BigDNA struct MLVL : BigYAML
{ {
DECL_DNA DECL_YAML
Value<atUint32> magic; Value<atUint32> magic;
Value<atUint32> version; Value<atUint32> version;
UniqueID32 worldNameId; UniqueID32 worldNameId;
@ -18,9 +18,9 @@ struct MLVL : BigDNA
UniqueID32 worldSkyboxId; UniqueID32 worldSkyboxId;
Value<atUint32> memRelayLinkCount; Value<atUint32> memRelayLinkCount;
struct MemRelayLink : BigDNA struct MemRelayLink : BigYAML
{ {
DECL_DNA DECL_YAML
Value<atUint32> memRelayId; Value<atUint32> memRelayId;
Value<atUint32> targetId; Value<atUint32> targetId;
Value<atUint16> msg; Value<atUint16> msg;
@ -30,9 +30,9 @@ struct MLVL : BigDNA
Value<atUint32> areaCount; Value<atUint32> areaCount;
Value<atUint32> unknown1; Value<atUint32> unknown1;
struct Area : BigDNA struct Area : BigYAML
{ {
DECL_DNA DECL_YAML
UniqueID32 areaNameId; UniqueID32 areaNameId;
Value<atVec4f> transformMtx[3]; Value<atVec4f> transformMtx[3];
Value<atVec3f> aabb[2]; Value<atVec3f> aabb[2];
@ -44,9 +44,9 @@ struct MLVL : BigDNA
Value<atUint32> padding; Value<atUint32> padding;
Value<atUint32> depCount; Value<atUint32> depCount;
struct Dependency : BigDNA struct Dependency : BigYAML
{ {
DECL_DNA DECL_YAML
UniqueID32 id; UniqueID32 id;
FourCC type; FourCC type;
}; };
@ -56,13 +56,13 @@ struct MLVL : BigDNA
Vector<atUint32, DNA_COUNT(depLayerCount)> depLayers; Vector<atUint32, DNA_COUNT(depLayerCount)> depLayers;
Value<atUint32> dockCount; Value<atUint32> dockCount;
struct Dock : BigDNA struct Dock : BigYAML
{ {
DECL_DNA DECL_YAML
Value<atUint32> endpointCount; Value<atUint32> endpointCount;
struct Endpoint : BigDNA struct Endpoint : BigYAML
{ {
DECL_DNA DECL_YAML
Value<atUint32> areaIdx; Value<atUint32> areaIdx;
Value<atUint32> dockIdx; Value<atUint32> dockIdx;
}; };
@ -80,9 +80,9 @@ struct MLVL : BigDNA
Value<atUint32> unknown3; Value<atUint32> unknown3;
Value<atUint32> audioGroupCount; Value<atUint32> audioGroupCount;
struct AudioGroup : BigDNA struct AudioGroup : BigYAML
{ {
DECL_DNA DECL_YAML
Value<atUint32> unknown; Value<atUint32> unknown;
UniqueID32 agscId; UniqueID32 agscId;
}; };
@ -90,9 +90,9 @@ struct MLVL : BigDNA
String<-1> unkString; String<-1> unkString;
Value<atUint32> layerFlagCount; Value<atUint32> layerFlagCount;
struct LayerFlags : BigDNA struct LayerFlags : BigYAML
{ {
DECL_DNA DECL_YAML
Value<atUint32> layerCount; Value<atUint32> layerCount;
Value<atUint64> flags; Value<atUint64> flags;
}; };

View File

@ -111,6 +111,69 @@ void STRG::write(Athena::io::IStreamWriter& writer) const
} }
} }
void STRG::fromYAML(Athena::io::YAMLDocReader& reader)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> wconv;
const Athena::io::YAMLNode* root = reader.getRootNode();
/* Validate Pass */
if (root->m_type == YAML_MAPPING_NODE)
{
for (const auto& lang : root->m_mapChildren)
{
if (lang.first.size() != 4)
{
Log.report(LogVisor::Warning, "STRG language string '%s' must be exactly 4 characters; skipping", lang.first.c_str());
return;
}
if (lang.second->m_type != YAML_SEQUENCE_NODE)
{
Log.report(LogVisor::Warning, "STRG language string '%s' must contain a sequence; skipping", lang.first.c_str());
return;
}
for (const auto& str : lang.second->m_seqChildren)
{
if (str->m_type != YAML_SCALAR_NODE)
{
Log.report(LogVisor::Warning, "STRG language '%s' must contain all scalars; skipping", lang.first.c_str());
return;
}
}
}
}
else
{
Log.report(LogVisor::Warning, "STRG must have a mapping root node; skipping");
return;
}
/* Read Pass */
langs.clear();
for (const auto& lang : root->m_mapChildren)
{
std::vector<std::wstring> strs;
for (const auto& str : lang.second->m_seqChildren)
strs.emplace_back(wconv.from_bytes(str->m_scalarString));
langs.emplace_back(FourCC(lang.first.c_str()), strs);
}
langMap.clear();
langMap.reserve(langs.size());
for (std::pair<FourCC, std::vector<std::wstring>>& item : langs)
langMap.emplace(item.first, &item.second);
}
void STRG::toYAML(Athena::io::YAMLDocWriter& writer) const
{
for (const std::pair<FourCC, std::vector<std::wstring>>& lang : langs)
{
writer.enterSubVector(lang.first.toString().c_str());
for (const std::wstring& str : lang.second)
writer.writeWString(nullptr, str);
writer.leaveSubVector();
}
}
bool STRG::readAngelScript(const AngelScript::asIScriptModule& in) bool STRG::readAngelScript(const AngelScript::asIScriptModule& in)
{ {
std::wstring_convert<std::codecvt_utf8<wchar_t>> wconv; std::wstring_convert<std::codecvt_utf8<wchar_t>> wconv;

View File

@ -10,9 +10,10 @@ namespace Retro
namespace DNAMP1 namespace DNAMP1
{ {
struct STRG : ISTRG, BigDNA struct STRG : ISTRG, BigYAML
{ {
DECL_EXPLICIT_DNA DECL_EXPLICIT_DNA
DECL_EXPLICIT_YAML
void _read(Athena::io::IStreamReader& reader); void _read(Athena::io::IStreamReader& reader);
std::vector<std::pair<FourCC, std::vector<std::wstring>>> langs; std::vector<std::pair<FourCC, std::vector<std::wstring>>> langs;
std::unordered_map<FourCC, std::vector<std::wstring>*> langMap; std::unordered_map<FourCC, std::vector<std::wstring>*> langMap;
@ -63,18 +64,18 @@ struct STRG : ISTRG, BigDNA
{ {
STRG strg; STRG strg;
strg.read(rs); strg.read(rs);
std::ofstream strgOut(outPath.getAbsolutePath()); FILE* fp = HECL::Fopen(outPath.getAbsolutePath().c_str(), _S("w"));
strg.writeAngelScript(strgOut); strg.toYAMLFile(fp);
fclose(fp);
return true; return true;
} }
static bool Cook(const HECL::ProjectPath& inPath, const HECL::ProjectPath& outPath) static bool Cook(const HECL::ProjectPath& inPath, const HECL::ProjectPath& outPath)
{ {
STRG strg; STRG strg;
HECL::Database::ASUniqueModule mod = HECL::Database::ASUniqueModule::CreateFromPath(inPath); FILE* fp = HECL::Fopen(inPath.getAbsolutePath().c_str(), _S("r"));
if (!mod) strg.fromYAMLFile(fp);
return false; fclose(fp);
strg.readAngelScript(mod);
Athena::io::FileWriter ws(outPath.getAbsolutePath()); Athena::io::FileWriter ws(outPath.getAbsolutePath());
strg.write(ws); strg.write(ws);
return true; return true;