Skip to content

Commit

Permalink
Added SF64 XML Factories
Browse files Browse the repository at this point in the history
  • Loading branch information
KiritoDv committed Jan 3, 2025
1 parent 2e0af34 commit 417f2a8
Show file tree
Hide file tree
Showing 10 changed files with 397 additions and 1 deletion.
81 changes: 80 additions & 1 deletion src/factories/sf64/EnvironmentFactory.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#include "EnvironmentFactory.h"
#include "spdlog/spdlog.h"

#include <tinyxml2.h>
#include "Companion.h"
#include "utils/Decompressor.h"
#include "utils/TorchUtils.h"

#define VALUE_TO_ENUM(val, enumname, fallback) (Companion::Instance->GetEnumFromValue(enumname, val).value_or("/*" + std::string(fallback) + " */ " + std::to_string(val)));
#define VALUE_TO_XML_ENUM(val, enumname, fallback) (Companion::Instance->GetEnumFromValue(enumname, val).value_or(std::to_string(val)))

SF64::EnvironmentData::EnvironmentData(int32_t type, int32_t ground, uint16_t bgColor, uint16_t seqId, int32_t fogR, int32_t fogG, int32_t fogB, int32_t fogN, int32_t fogF, Vec3f lightDir, int32_t lightR, int32_t lightG, int32_t lightB, int32_t ambR, int32_t ambG, int32_t ambB): mType(type), mGround(ground), mBgColor(bgColor), mSeqId(seqId), mFogR(fogR), mFogG(fogG), mFogB(fogB), mFogN(fogN), mFogF(fogF), mLightDir(lightDir), mLightR(lightR), mLightG(lightG), mLightB(lightB), mAmbR(ambR), mAmbG(ambG), mAmbB(ambB) {

Expand Down Expand Up @@ -87,6 +88,84 @@ ExportResult SF64::EnvironmentBinaryExporter::Export(std::ostream &write, std::s
return std::nullopt;
}

void AppendNode(tinyxml2::XMLDocument& doc, tinyxml2::XMLElement* root, const std::string& name, const std::string value) {
auto node = doc.NewElement(name.c_str());
node->SetText(value.c_str());
root->InsertEndChild(node);
}

void AppendSeqNode(tinyxml2::XMLDocument& doc, tinyxml2::XMLElement* root, uint16_t id) {
auto node = doc.NewElement("Sequence");
if (id == 0xFFFF) {
node->SetAttribute("ID", "SEQ_ID_UNK");
node->SetAttribute("Flag", "0");
} else {
bool flag = id < 0x8000;
if(!flag) {
id &= 0x7FFF;
}
node->SetText(VALUE_TO_XML_ENUM(id, "BgmSeqIds", std::to_string(id)).c_str());
node->SetAttribute("Flag", flag ? "0" : "1");
}
root->InsertEndChild(node);
}

ExportResult SF64::EnvironmentXMLExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
const auto symbol = GetSafeNode(node, "symbol", entryName);
auto env = std::static_pointer_cast<SF64::EnvironmentData>(raw);

tinyxml2::XMLPrinter printer;
tinyxml2::XMLDocument environment;
tinyxml2::XMLElement* root = environment.NewElement("Environment");

*replacement += ".meta";

AppendNode(environment, root, "Type", VALUE_TO_XML_ENUM(env->mType, "LevelType", "LEVELTYPE_UNK"));
AppendNode(environment, root, "Ground", VALUE_TO_XML_ENUM(env->mGround, "GroundType", "GROUND_UNK"));
AppendSeqNode(environment, root, env->mSeqId);

{
auto item = environment.NewElement("Background");
item->SetAttribute("R", (env->mBgColor >> 10) & 0x1F);
item->SetAttribute("G", (env->mBgColor >> 5) & 0x1F);
item->SetAttribute("B", env->mBgColor & 0x1F);
root->InsertEndChild(item);
}
{
auto item = environment.NewElement("Fog");
item->SetAttribute("R", env->mFogR);
item->SetAttribute("G", env->mFogG);
item->SetAttribute("B", env->mFogB);
item->SetAttribute("Near", env->mFogN);
item->SetAttribute("Far", env->mFogF);
root->InsertEndChild(item);
}

{
auto item = environment.NewElement("Light");
item->SetAttribute("R", env->mLightR);
item->SetAttribute("G", env->mLightG);
item->SetAttribute("B", env->mLightB);
item->SetAttribute("xDir", env->mLightDir.x);
item->SetAttribute("yDir", env->mLightDir.y);
item->SetAttribute("zDir", env->mLightDir.z);
root->InsertEndChild(item);
}

{
auto item = environment.NewElement("Ambient");
item->SetAttribute("R", env->mAmbR);
item->SetAttribute("G", env->mAmbG);
item->SetAttribute("B", env->mAmbB);
root->InsertEndChild(item);
}

environment.InsertEndChild(root);
environment.Accept(&printer);
write.write(printer.CStr(), printer.CStrSize() - 1);
return std::nullopt;
}

std::optional<std::shared_ptr<IParsedData>> SF64::EnvironmentFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
auto [_, segment] = Decompressor::AutoDecode(node, buffer, sizeof(SF64::EnvironmentData));
LUS::BinaryReader reader(segment.data, segment.size);
Expand Down
6 changes: 6 additions & 0 deletions src/factories/sf64/EnvironmentFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,21 @@ class EnvironmentCodeExporter : public BaseExporter {
ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};

class EnvironmentXMLExporter : public BaseExporter {
ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};

class EnvironmentFactory : public BaseFactory {
public:
std::optional<std::shared_ptr<IParsedData>> parse(std::vector<uint8_t>& buffer, YAML::Node& data) override;
inline std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() override {
return {
REGISTER(XML, EnvironmentXMLExporter)
REGISTER(Code, EnvironmentCodeExporter)
REGISTER(Header, EnvironmentHeaderExporter)
REGISTER(Binary, EnvironmentBinaryExporter)
};
}
bool SupportModdedAssets() override { return true; }
};
}
29 changes: 29 additions & 0 deletions src/factories/sf64/MessageFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "Companion.h"
#include <regex>
#include <sstream>
#include <tinyxml2.h>

#define END_CODE 0
#define NEWLINE_CODE 1
Expand Down Expand Up @@ -149,6 +150,34 @@ ExportResult SF64::MessageModdingExporter::Export(std::ostream&write, std::share
return std::nullopt;
}

ExportResult SF64::MessageXMLExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
const auto data = std::static_pointer_cast<MessageData>(raw);
const auto symbol = GetSafeNode(node, "symbol", entryName);
*replacement += ".meta";

tinyxml2::XMLPrinter printer;
tinyxml2::XMLDocument message;
tinyxml2::XMLElement* root = message.NewElement("Message");
tinyxml2::XMLElement* line = message.NewElement("Line");
std::string str;

for(size_t i = 0; i < data->mMessage.size(); i++) {
if(data->mMessage[i] == NEWLINE_CODE){
line->SetText(str.c_str());
root->InsertEndChild(line);
line = message.NewElement("Line");
str.clear();
} else {
str += gASCIIFullTable[data->mMessage[i]];
}
}

message.InsertEndChild(root);
message.Accept(&printer);
write.write(printer.CStr(), printer.CStrSize() - 1);
return std::nullopt;
}

std::optional<std::shared_ptr<IParsedData>> SF64::MessageFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
std::vector<uint16_t> message;
std::ostringstream mesgStr;
Expand Down
5 changes: 5 additions & 0 deletions src/factories/sf64/MessageFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,17 @@ class MessageModdingExporter : public BaseExporter {
ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};

class MessageXMLExporter : public BaseExporter {
ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};

class MessageFactory : public BaseFactory {
public:
std::optional<std::shared_ptr<IParsedData>> parse(std::vector<uint8_t>& buffer, YAML::Node& data) override;
std::optional<std::shared_ptr<IParsedData>> parse_modding(std::vector<uint8_t>& buffer, YAML::Node& data) override;
inline std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() override {
return {
REGISTER(XML, MessageXMLExporter)
REGISTER(Code, MessageCodeExporter)
REGISTER(Header, MessageHeaderExporter)
REGISTER(Binary, MessageBinaryExporter)
Expand Down
31 changes: 31 additions & 0 deletions src/factories/sf64/MessageLookupFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "utils/Decompressor.h"
#include "spdlog/spdlog.h"
#include "Companion.h"
#include <tinyxml2.h>

ExportResult SF64::MessageLookupHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) {
const auto symbol = GetSafeNode(node, "symbol", entryName);
Expand Down Expand Up @@ -44,6 +45,36 @@ ExportResult SF64::MessageLookupCodeExporter::Export(std::ostream &write, std::s
return offset + table.size() * sizeof(uint16_t);
}

ExportResult SF64::MessageLookupXMLExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
auto table = std::static_pointer_cast<MessageTable>(raw)->mTable;
const auto symbol = GetSafeNode(node, "symbol", entryName);

tinyxml2::XMLPrinter printer;
tinyxml2::XMLDocument lookup;
tinyxml2::XMLElement* root = lookup.NewElement("MessageTable");
root->SetAttribute("Size", (int) table.size());

*replacement += ".meta";

for (auto m : table) {
auto item = lookup.NewElement("Entry");
auto dec = Companion::Instance->GetNodeByAddr(m.ptr);
std::string ref = "None";

if(dec.has_value()){
ref = std::get<0>(dec.value());
}

item->SetAttribute("Ref", ref.c_str());
root->InsertEndChild(item);
}

lookup.InsertEndChild(root);
lookup.Accept(&printer);
write.write(printer.CStr(), printer.CStrSize() - 1);
return std::nullopt;
}

ExportResult SF64::MessageLookupBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
auto writer = LUS::BinaryWriter();
const auto data = std::static_pointer_cast<MessageTable>(raw);
Expand Down
5 changes: 5 additions & 0 deletions src/factories/sf64/MessageLookupFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,16 @@ class MessageLookupBinaryExporter : public BaseExporter {
ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};

class MessageLookupXMLExporter : public BaseExporter {
ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};

class MessageLookupFactory : public BaseFactory {
public:
std::optional<std::shared_ptr<IParsedData>> parse(std::vector<uint8_t>& buffer, YAML::Node& data) override;
inline std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() override {
return {
REGISTER(XML, MessageLookupXMLExporter)
REGISTER(Code, MessageLookupCodeExporter)
REGISTER(Header, MessageLookupHeaderExporter)
REGISTER(Binary, MessageLookupBinaryExporter)
Expand Down
31 changes: 31 additions & 0 deletions src/factories/sf64/ObjInitFactory.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "ObjInitFactory.h"
#include "utils/Decompressor.h"
#include "Companion.h"
#include <tinyxml2.h>

#define NUM(x, w) std::dec << std::setfill(' ') << std::setw(w) << x
#define FLOAT(x, w) std::dec << std::setfill(' ') << std::setw(w) << std::fixed << std::setprecision(1) << x << "f"
Expand Down Expand Up @@ -66,6 +67,36 @@ ExportResult SF64::ObjInitBinaryExporter::Export(std::ostream &write, std::share
return std::nullopt;
}

ExportResult SF64::ObjInitXMLExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
auto data = std::static_pointer_cast<ObjInitData>(raw)->mObjInit;

tinyxml2::XMLPrinter printer;
tinyxml2::XMLDocument objects;
tinyxml2::XMLElement* root = objects.NewElement("ObjectList");

*replacement += ".meta";

for(auto & i : data) {
tinyxml2::XMLElement* obj = root->InsertNewChildElement("ObjInit");
auto enumName = Companion::Instance->GetEnumFromValue("ObjectId", i.id).value_or(std::to_string(i.id));

obj->SetAttribute("ID", enumName.c_str());
obj->SetAttribute("xPos", i.xPos);
obj->SetAttribute("yPos", i.yPos);
obj->SetAttribute("zPos1", i.zPos1);
obj->SetAttribute("zPos2", i.zPos2);
obj->SetAttribute("xRot", i.rot.x);
obj->SetAttribute("yRot", i.rot.y);
obj->SetAttribute("zRot", i.rot.z);
root->InsertEndChild(obj);
}

objects.InsertEndChild(root);
objects.Accept(&printer);
write.write(printer.CStr(), printer.CStrSize() - 1);
return std::nullopt;
}

std::optional<std::shared_ptr<IParsedData>> SF64::ObjInitFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
auto [_, segment] = Decompressor::AutoDecode(node, buffer);

Expand Down
6 changes: 6 additions & 0 deletions src/factories/sf64/ObjInitFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ class ObjInitCodeExporter : public BaseExporter {
ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};

class ObjInitXMLExporter : public BaseExporter {
ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};

class ObjInitFactory : public BaseFactory {
public:
std::optional<std::shared_ptr<IParsedData>> parse(std::vector<uint8_t>& buffer, YAML::Node& data) override;
Expand All @@ -41,7 +45,9 @@ class ObjInitFactory : public BaseFactory {
REGISTER(Header, ObjInitHeaderExporter)
REGISTER(Binary, ObjInitBinaryExporter)
REGISTER(Code, ObjInitCodeExporter)
REGISTER(XML, ObjInitXMLExporter)
};
}
bool SupportModdedAssets() override { return true; }
};
}
Loading

0 comments on commit 417f2a8

Please sign in to comment.