diff options
| author | inspectredc <78732756+inspectredc@users.noreply.github.com> | 2025-03-31 00:30:16 +0100 |
|---|---|---|
| committer | Lywx <kiritodev01@gmail.com> | 2025-04-23 07:54:00 -0600 |
| commit | 5c3ff9a40132d3d98211b2d37ad4cb7b6e208bd2 (patch) | |
| tree | 30faf5107ce2bbbdd0bccb39c0177063cad14927 /src | |
| parent | 580350a2c2a0987811b31e562133106c4979bf05 (diff) | |
Factory Shell
Diffstat (limited to 'src')
| -rw-r--r-- | src/factories/ResourceType.h | 1 | ||||
| -rw-r--r-- | src/factories/fzerox/GhostRecordFactory.cpp | 84 | ||||
| -rw-r--r-- | src/factories/fzerox/GhostRecordFactory.h | 72 |
3 files changed, 157 insertions, 0 deletions
diff --git a/src/factories/ResourceType.h b/src/factories/ResourceType.h index 5758e9d..f133491 100644 --- a/src/factories/ResourceType.h +++ b/src/factories/ResourceType.h @@ -63,6 +63,7 @@ enum class ResourceType { // F-ZERO X CourseData = 0x58435253, // XCRS + GhostRecord = 0x58475244, // XGRD // NAudio v0 Bank = 0x42414E4B, // BANK diff --git a/src/factories/fzerox/GhostRecordFactory.cpp b/src/factories/fzerox/GhostRecordFactory.cpp new file mode 100644 index 0000000..9536d80 --- /dev/null +++ b/src/factories/fzerox/GhostRecordFactory.cpp @@ -0,0 +1,84 @@ +#include "GhostRecordFactory.h" + +#include "utils/Decompressor.h" +#include "spdlog/spdlog.h" +#include "Companion.h" + +ExportResult FZX::GhostRecordHeaderExporter::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 ALIGN_ASSET(2) char " << symbol << "[] = \"__OTR__" << (*replacement) << "\";\n\n"; + return std::nullopt; + } + + write << "extern GhostRecord " << symbol << ";\n"; + + return std::nullopt; +} + +ExportResult FZX::GhostRecordCodeExporter::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"); + const auto record = std::static_pointer_cast<GhostRecordData>(raw); + + write << "GhostRecord " << symbol << " = {\n"; + + return offset; +} + +ExportResult FZX::GhostRecordBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) { + auto writer = LUS::BinaryWriter(); + const auto record = std::static_pointer_cast<GhostRecordData>(raw); + + WriteHeader(writer, Torch::ResourceType::GhostRecord, 0); + + writer.Finish(write); + return std::nullopt; +} + +ExportResult FZX::GhostRecordModdingExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) { + const auto record = std::static_pointer_cast<GhostRecordData>(raw); + const auto symbol = GetSafeNode(node, "symbol", entryName); + + *replacement += ".yaml"; + + std::stringstream stream; + YAML::Emitter out; + + out << YAML::BeginMap; + out << YAML::Key << symbol; + out << YAML::Value; + + out << YAML::EndMap; + + write.write(out.c_str(), out.size()); + + return std::nullopt; +} + +std::optional<std::shared_ptr<IParsedData>> FZX::GhostRecordFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { + auto [_, segment] = Decompressor::AutoDecode(node, buffer); + LUS::BinaryReader reader(segment.data, segment.size); + + reader.SetEndianness(Torch::Endianness::Big); + + return std::make_shared<GhostRecordData>(); +} + +std::optional<std::shared_ptr<IParsedData>> FZX::GhostRecordFactory::parse_modding(std::vector<uint8_t>& buffer, YAML::Node& node) { + YAML::Node assetNode; + + try { + std::string text((char*) buffer.data(), buffer.size()); + assetNode = YAML::Load(text.c_str()); + } catch (YAML::ParserException& e) { + SPDLOG_ERROR("Failed to parse message data: {}", e.what()); + SPDLOG_ERROR("{}", (char*) buffer.data()); + return std::nullopt; + } + + const auto info = assetNode.begin()->second; + + return std::make_shared<GhostRecordData>(); +} diff --git a/src/factories/fzerox/GhostRecordFactory.h b/src/factories/fzerox/GhostRecordFactory.h new file mode 100644 index 0000000..aaf8ae1 --- /dev/null +++ b/src/factories/fzerox/GhostRecordFactory.h @@ -0,0 +1,72 @@ +#pragma once + +#include <factories/BaseFactory.h> + +namespace FZX { + +typedef struct GhostMachineInfo { + /* 0x00 */ uint8_t character; + /* 0x01 */ uint8_t customType; + /* 0x02 */ uint8_t frontType; + /* 0x03 */ uint8_t rearType; + /* 0x04 */ uint8_t wingType; + /* 0x05 */ uint8_t logo; + /* 0x06 */ uint8_t number; + /* 0x07 */ uint8_t decal; + /* 0x08 */ uint8_t bodyR; + /* 0x09 */ uint8_t bodyG; + /* 0x0A */ uint8_t bodyB; + /* 0x0B */ uint8_t numberR; + /* 0x0C */ uint8_t numberG; + /* 0x0D */ uint8_t numberB; + /* 0x0E */ uint8_t decalR; + /* 0x0F */ uint8_t decalG; + /* 0x10 */ uint8_t decalB; + /* 0x11 */ uint8_t cockpitR; + /* 0x12 */ uint8_t cockpitG; + /* 0x13 */ uint8_t cockpitB; +} GhostMachineInfo; + +class GhostRecordData : public IParsedData { +public: + uint16_t mGhostType; + int32_t mReplayChecksum; + int32_t mCourseEncoding; + int32_t mRaceTime; + std::string mTrackName; // empty for normal tracks + GhostMachineInfo mGhostMachineInfo; + + GhostRecordData(uint16_t ghostType, int32_t replayChecksum, int32_t courseEncoding, int32_t raceTime, std::string trackName, GhostMachineInfo& ghostMachineInfo) : mGhostType(ghostType), mReplayChecksum(replayChecksum), mCourseEncoding(courseEncoding), mRaceTime(raceTime), mTrackName(trackName), mGhostMachineInfo(ghostMachineInfo) {} +}; + +class GhostRecordHeaderExporter : public BaseExporter { + ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override; +}; + +class GhostRecordBinaryExporter : public BaseExporter { + ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override; +}; + +class GhostRecordCodeExporter : public BaseExporter { + ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override; +}; + +class GhostRecordModdingExporter : public BaseExporter { + ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override; +}; + +class GhostRecordFactory : 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(Code, GhostRecordCodeExporter) + REGISTER(Header, GhostRecordHeaderExporter) + REGISTER(Binary, GhostRecordBinaryExporter) + REGISTER(Modding, GhostRecordModdingExporter) + }; + } + bool SupportModdedAssets() override { return true; } +}; +} // namespace FZX |
