summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpetrie911 <petrie911@yahoo.com>2024-03-12 11:25:51 -0500
committerLywx <kiritodev01@gmail.com>2024-03-12 11:57:53 -0600
commit84b6686f5b051ce729cc03d92dc71c94d0f19537 (patch)
tree7b188b7d9d89bc09a468ff3ecb1d9d4628986cc6
parent83adeb4b7f9e746d52c7d35f1964aa59e599a93d (diff)
script
-rw-r--r--TemplateFactory.cpp38
-rw-r--r--TemplateFactory.h41
-rw-r--r--src/Companion.cpp8
-rw-r--r--src/factories/sf64/ScriptFactory.cpp113
-rw-r--r--src/factories/sf64/ScriptFactory.h45
5 files changed, 243 insertions, 2 deletions
diff --git a/TemplateFactory.cpp b/TemplateFactory.cpp
new file mode 100644
index 0000000..1d89a6f
--- /dev/null
+++ b/TemplateFactory.cpp
@@ -0,0 +1,38 @@
+#include "TemplateFactory.h"
+#include "spdlog/spdlog.h"
+
+#include "Companion.h"
+#include "utils/Decompressor.h"
+#include "utils/TorchUtils.h"
+
+TypeData::TypeData(uint32_t data): mData(data) {
+
+}
+
+void TypeHeaderExporter::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);
+
+ if(Companion::Instance->IsOTRMode()){
+ write << "static const char " << symbol << "[] = \"__OTR__" << (*replacement) << "\";\n\n";
+ return;
+ }
+
+ write << "extern Type " << symbol << ";\n";
+ // write << "extern Type " << symbol << "[];\n";
+}
+
+void TypeCodeExporter::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);
+ const auto offset = GetSafeNode<uint32_t>(node, "offset");
+ auto data = std::static_pointer_cast<TypeData>(raw);
+
+}
+
+void TypeBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
+
+}
+
+std::optional<std::shared_ptr<IParsedData>> TypeFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
+
+ return std::make_shared<TypeData>();
+}
diff --git a/TemplateFactory.h b/TemplateFactory.h
new file mode 100644
index 0000000..34bb960
--- /dev/null
+++ b/TemplateFactory.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#include "../BaseFactory.h"
+
+// namespace GAME {
+
+class TypeData : public IParsedData {
+public:
+ uint32_t mData;
+
+ explicit TypeData(uint32_t data) {}
+};
+
+class TypeHeaderExporter : public BaseExporter {
+ void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
+};
+
+class TypeBinaryExporter : public BaseExporter {
+ void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
+};
+
+class TypeCodeExporter : public BaseExporter {
+ void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
+};
+
+class TypeFactory : 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 {
+ return std::nullopt;
+ }
+ inline std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() override {
+ return {
+ REGISTER(Code, TypeCodeExporter)
+ REGISTER(Header, TypeHeaderExporter)
+ REGISTER(Binary, TypeBinaryExporter)
+ };
+ }
+ bool SupportModdedAssets() override { return false; }
+};
+// }
diff --git a/src/Companion.cpp b/src/Companion.cpp
index ea14184..9fda03e 100644
--- a/src/Companion.cpp
+++ b/src/Companion.cpp
@@ -2,8 +2,7 @@
#include "storm/SWrapper.h"
#include "utils/Decompressor.h"
-#include "factories/sf64/SkeletonFactory.h"
-#include "factories/sf64/AnimFactory.h"
+
#include "factories/sm64/AnimationFactory.h"
#include "factories/sm64/DialogFactory.h"
#include "factories/sm64/DictionaryFactory.h"
@@ -31,6 +30,9 @@
#include <filesystem>
#include "factories/sf64/MessageFactory.h"
#include "factories/sf64/MessageLookupFactory.h"
+#include "factories/sf64/SkeletonFactory.h"
+#include "factories/sf64/AnimFactory.h"
+#include "factories/sf64/ScriptFactory.h"
using namespace std::chrono;
namespace fs = std::filesystem;
@@ -72,6 +74,8 @@ void Companion::Init(const ExportType type) {
this->RegisterFactory("SF64:SKELETON", std::make_shared<SF64::SkeletonFactory>());
this->RegisterFactory("SF64:MESSAGE", std::make_shared<SF64::MessageFactory>());
this->RegisterFactory("SF64:MSG_TABLE", std::make_shared<SF64::MessageLookupFactory>());
+ this->RegisterFactory("SF64:SCRIPT", std::make_shared<SF64::ScriptFactory>());
+
this->Process();
}
diff --git a/src/factories/sf64/ScriptFactory.cpp b/src/factories/sf64/ScriptFactory.cpp
new file mode 100644
index 0000000..1bf676c
--- /dev/null
+++ b/src/factories/sf64/ScriptFactory.cpp
@@ -0,0 +1,113 @@
+#include "ScriptFactory.h"
+#include "spdlog/spdlog.h"
+
+#include "Companion.h"
+#include "utils/Decompressor.h"
+#include "utils/TorchUtils.h"
+
+SF64::ScriptData::ScriptData(std::vector<uint32_t> ptrs, std::vector<uint16_t> cmds, std::map<uint32_t, int> sizeMap, uint32_t ptrsStart, uint32_t cmdsStart): mPtrs(ptrs), mCmds(cmds), mSizeMap(sizeMap), mPtrsStart(ptrsStart), mCmdsStart(cmdsStart) {
+
+}
+
+void SF64::ScriptHeaderExporter::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);
+
+ if(Companion::Instance->IsOTRMode()){
+ write << "static const char " << symbol << "[] = \"__OTR__" << (*replacement) << "\";\n\n";
+ return;
+ }
+
+ write << "extern u16* " << symbol << "[];\n";
+}
+
+std::string MakeScriptCmd(uint16_t s1, uint16_t s2) {
+ auto opcode = (s1 & 0xFE00) >> 9;
+ auto arg1 = s1 & 0x1FF;
+ std::ostringstream cmd;
+
+ cmd << "EVENT_CMD(EVOP_" << std::left << std::setw(3) << std::dec << opcode << ", " << std::right << std::setw(3) << std::dec << arg1 << ", " << std::setw(5) << std::dec << s2 << ")";
+
+ return cmd.str();
+}
+
+void SF64::ScriptCodeExporter::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);
+ const auto offset = GetSafeNode<uint32_t>(node, "offset");
+ auto script = std::static_pointer_cast<SF64::ScriptData>(raw);
+ auto sortedPtrs = script->mPtrs;
+ std::sort(sortedPtrs.begin(), sortedPtrs.end());
+ std::vector<std::string> scriptNames;
+ auto cmdOff = script->mCmdsStart;
+ auto cmdIndex = 0;
+
+ if(IS_SEGMENTED(cmdOff)) {
+ cmdOff = SEGMENT_OFFSET(cmdOff);
+ }
+
+ for(int i = 0; i < sortedPtrs.size(); i++) {
+ std::ostringstream scriptDefaultName;
+ scriptDefaultName << symbol << "_cmds_" << std::uppercase << std::hex << cmdOff + 2 * cmdIndex;
+ write << "u16 " << scriptDefaultName.str() << "[] = {";
+
+ for(int j = 0; j < script->mSizeMap[sortedPtrs[i]] / 2; j++, cmdIndex+=2) {
+ if((j % 3) == 0) {
+ write << "\n" << fourSpaceTab;
+ }
+ write << MakeScriptCmd(script->mCmds[cmdIndex], script->mCmds[cmdIndex + 1]) << ", ";
+ }
+ scriptNames.push_back(scriptDefaultName.str());
+ write << "\n};\n\n";
+ }
+ write << "u16* " << symbol << "[] = {";
+ for(int i = 0; i < script->mPtrs.size(); i++) {
+ if((i % 5) == 0) {
+ write << "\n" << fourSpaceTab;
+ }
+ write << scriptNames[i] << ", ";
+ }
+ write << "\n};\n\n";
+
+}
+
+void SF64::ScriptBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
+
+}
+
+std::optional<std::shared_ptr<IParsedData>> SF64::ScriptFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
+ const auto offset = GetSafeNode<uint32_t>(node, "offset");
+ auto ptrsStart = offset;
+ YAML::Node scriptNode;
+ std::vector<uint32_t> scriptPtrs;
+ std::vector<uint16_t> scriptCmds;
+ std::map<uint32_t, int> sizeMap;
+ auto [_, segment] = Decompressor::AutoDecode(node, buffer, 0x1000);
+ LUS::BinaryReader reader(segment.data, segment.size);
+ reader.SetEndianness(LUS::Endianness::Big);
+ auto ptr = reader.ReadUInt32();
+
+ while(SEGMENT_NUMBER(ptr) == SEGMENT_NUMBER(offset)) {
+ scriptPtrs.push_back(ptr);
+ ptr = reader.ReadUInt32();
+ }
+
+ auto sortedPtrs = scriptPtrs;
+ std::sort(sortedPtrs.begin(), sortedPtrs.end());
+
+ auto cmdsStart = sortedPtrs[0];
+
+ for(int i = 0; i < sortedPtrs.size() - 1; i++) {
+ sizeMap[sortedPtrs[i]] = (sortedPtrs[i+1] - sortedPtrs[i]) / sizeof(uint16_t);
+ }
+ sizeMap[sortedPtrs[sortedPtrs.size() - 1]] = (ptrsStart - sortedPtrs[sortedPtrs.size() - 1]) / sizeof(uint16_t);
+
+ auto scriptLen = (ptrsStart - cmdsStart) / sizeof(uint16_t);
+
+ scriptNode["offset"] = cmdsStart;
+ auto [__, scriptSegment] = Decompressor::AutoDecode(scriptNode, buffer, scriptLen * sizeof(uint16_t));
+ LUS::BinaryReader scriptReader(scriptSegment.data, scriptSegment.size);
+ scriptReader.SetEndianness(LUS::Endianness::Big);
+ for(int i = 0; i < scriptLen; i++) {
+ scriptCmds.push_back(scriptReader.ReadUInt16());
+ }
+ return std::make_shared<SF64::ScriptData>(scriptPtrs, scriptCmds, sizeMap, ptrsStart, cmdsStart);
+}
diff --git a/src/factories/sf64/ScriptFactory.h b/src/factories/sf64/ScriptFactory.h
new file mode 100644
index 0000000..24eaf71
--- /dev/null
+++ b/src/factories/sf64/ScriptFactory.h
@@ -0,0 +1,45 @@
+#pragma once
+
+#include "../BaseFactory.h"
+
+namespace SF64 {
+
+class ScriptData : public IParsedData {
+public:
+ std::vector<uint32_t> mPtrs;
+ std::vector<uint16_t> mCmds;
+ std::map<uint32_t, int> mSizeMap;
+ uint32_t mCmdsStart;
+ uint32_t mPtrsStart;
+
+ ScriptData(std::vector<uint32_t> ptrs, std::vector<uint16_t> cmds, std::map<uint32_t, int> sizeMap, uint32_t ptrsStart, uint32_t cmdsStart);
+};
+
+class ScriptHeaderExporter : public BaseExporter {
+ void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
+};
+
+class ScriptBinaryExporter : public BaseExporter {
+ void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
+};
+
+class ScriptCodeExporter : public BaseExporter {
+ void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
+};
+
+class ScriptFactory : 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 {
+ return std::nullopt;
+ }
+ inline std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() override {
+ return {
+ REGISTER(Code, ScriptCodeExporter)
+ REGISTER(Header, ScriptHeaderExporter)
+ REGISTER(Binary, ScriptBinaryExporter)
+ };
+ }
+ bool SupportModdedAssets() override { return false; }
+};
+}