diff options
| author | petrie911 <petrie911@yahoo.com> | 2024-03-12 11:25:51 -0500 |
|---|---|---|
| committer | Lywx <kiritodev01@gmail.com> | 2024-03-12 11:57:53 -0600 |
| commit | 84b6686f5b051ce729cc03d92dc71c94d0f19537 (patch) | |
| tree | 7b188b7d9d89bc09a468ff3ecb1d9d4628986cc6 | |
| parent | 83adeb4b7f9e746d52c7d35f1964aa59e599a93d (diff) | |
script
| -rw-r--r-- | TemplateFactory.cpp | 38 | ||||
| -rw-r--r-- | TemplateFactory.h | 41 | ||||
| -rw-r--r-- | src/Companion.cpp | 8 | ||||
| -rw-r--r-- | src/factories/sf64/ScriptFactory.cpp | 113 | ||||
| -rw-r--r-- | src/factories/sf64/ScriptFactory.h | 45 |
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; } +}; +} |
