diff options
Diffstat (limited to 'src/factories/mk64/CourseMetadata.cpp')
| -rw-r--r-- | src/factories/mk64/CourseMetadata.cpp | 375 |
1 files changed, 375 insertions, 0 deletions
diff --git a/src/factories/mk64/CourseMetadata.cpp b/src/factories/mk64/CourseMetadata.cpp new file mode 100644 index 0000000..083f553 --- /dev/null +++ b/src/factories/mk64/CourseMetadata.cpp @@ -0,0 +1,375 @@ +#include "CourseMetadata.h" + +#include "Companion.h" +#include "spdlog/spdlog.h" +#include <algorithm> + +#define NUM(x) std::dec << std::setfill(' ') << std::setw(6) << x +#define COL(c) "0x" << std::hex << std::setw(2) << std::setfill('0') << c + +ExportResult MK64::CourseMetadataCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { + auto metadata = std::static_pointer_cast<MetadataData>(raw)->mMetadata; + + if (metadata.empty()) { + throw std::runtime_error("Course metadata null"); + } + + // Sort the data by id, 0 to 20 and beyond. + std::sort(metadata.begin(), metadata.end(), + [this](const CourseMetadata& a, const CourseMetadata& b) { + return a.id < b.id; + }); + + std::ofstream file; + auto outDir = GetSafeNode<std::string>(node, "out_directory") + "/"; + + file.open(outDir+"gCourseNames.inc.c"); + if (file.is_open()) { + // file << "char *gCourseNames[] = {\n" << fourSpaceTab; + for (const auto& m : metadata) { + if (m.name == "null") { continue; } + // Remove debug line once proven that sort worked right (start at id 0 and go up) + SPDLOG_INFO("Processing Course Id: "+std::to_string(m.id)); + file << '"' << m.name << "\", "; + } + // file << "\n};\n\n"; + file.close(); + } else if (file.fail()) { + throw std::runtime_error("Course metadata output folder is likely bad or the file is in-use"); + } + + file.open(outDir+"gCourseDebugNames.inc.c"); + if (file.is_open()) { + // file << "char *gDebugCourseNames[] = {\n" << fourSpaceTab; + for (const auto& m : metadata) { + if (m.name == "null") { continue; } + file << '"' << m.debugName << "\", "; + } + //file << "\n};\n\n"; + file.close(); + } + + file.open(outDir+"gCupSelectionByCourseId.inc.c"); + if (file.is_open()) { + //file << "char *gCupSelectionByCourseId[] = {\n" << fourSpaceTab; + for (const auto& m : metadata) { + if (m.cup == "null") { continue; } + file << m.cup << ", "; + } + // file << "\n};\n\n"; + file.close(); + } + + file.open(outDir+"gPerCupIndexByCourseId.inc.c"); + if (file.is_open()) { + //file << "const u8 gPerCupIndexByCourseId[] = {\n" << fourSpaceTab; + for (const auto& m : metadata) { + if (m.cupIndex == -1) { continue; } + file << m.cupIndex << ", "; + } + //file << "\n};\n\n"; + file.close(); + } + + file.open(outDir+"sCourseLengths.inc.c"); + if (file.is_open()) { + for (const auto& m : metadata) { + if (m.courseLength == "null") { continue; } + file << '"' << m.courseLength << "\", "; + } + file.close(); + } + + file.open(outDir+"gKartAIBehaviourLUT.inc.c"); + if (file.is_open()) { + for (const auto& m : metadata) { + file << m.kartAIBehaviourLUT << ", "; + } + file << 0; // @WARNING TRAILING ZERO IN ARRAY + file.close(); + } + + file.open(outDir+"gKartAICourseMaximumSeparation.inc.c"); + if (file.is_open()) { + // file << "f32 gWaypointWidth[] = {\n" << fourSpaceTab; + for (const auto& m : metadata) { + file << m.kartAIMaximumSeparation << ", "; + } + // file << "\n};\n\n"; + file.close(); + } + + file.open(outDir+"gKartAICourseMinimumSeparation.inc.c"); + if (file.is_open()) { + // file << "f32 gWaypointWidth2[] = {\n" << fourSpaceTab; + for (const auto& m : metadata) { + file << m.kartAIMinimumSeparation << ", "; + } + // file << "\n};\n\n"; + file.close(); + } + + file.open(outDir+"D_800DCBB4.inc.c"); + if (file.is_open()) { + //file << "uintptr_t *D_800DCBB4[] = {\n" << fourSpaceTab; + for (const auto& m : metadata) { + file << m.D_800DCBB4 << ", "; + } + //file << "\n};\n\n"; + file.close(); + } + + file.open(outDir+"gCPUSteeringSensitivity.inc.c"); + + // @WARNING THIS FILE HAS A TRAILING ZERO + if (file.is_open()) { + //file << "u16 gCPUSteeringSensitivity[] = {\n" << fourSpaceTab; + for (const auto& m : metadata) { + file << m.steeringSensitivity << ", "; + } + file << 0; + //file << "\n};\n\n"; + file.close(); + } + + file.open(outDir+"gBombKartSpawns.inc.c"); + if (file.is_open()) { + //file << "u16 gCPUSteeringSensitivity[] = {\n" << fourSpaceTab; + for (const auto& m : metadata) { + file << "{ // " << m.name << "\n"; + for (const auto& bombKart : m.bombKartSpawns) { + file << "{ "; + file << bombKart.waypointIndex << ", "; + file << bombKart.startingState << ", "; + file << bombKart.unk_04 << ", "; + file << bombKart.x << ", "; + file << bombKart.z << ", "; + file << bombKart.unk10 << ", "; + file << bombKart.unk14; + file << " },\n"; + } + file << "},\n"; + } + file.close(); + } + + file.open(outDir+"gCoursePathSizes.inc.c"); + if (file.is_open()) { + for (const auto& m : metadata) { + file << "// " << m.name << "\n"; + file << "{ "; + for (const auto& size : m.pathSizes) { + file << size << ", "; + } + file << "},\n"; + } + file.close(); + } + + file.open(outDir+"D_0D009418.inc.c"); + if (file.is_open()) { + for (const auto& m : metadata) { + file << "// " << m.name << "\n"; + file << "{ "; + for (const auto size : m.D_0D009418) { + file << size << ", "; + } + file << "},\n"; + } + file.close(); + } + + file.open(outDir+"D_0D009568.inc.c"); + if (file.is_open()) { + for (const auto& m : metadata) { + file << "// " << m.name << "\n"; + file << "{ "; + for (const auto& size : m.D_0D009568) { + file << size << ", "; + } + file << "},\n"; + } + file.close(); + } + + file.open(outDir+"D_0D0096B8.inc.c"); + if (file.is_open()) { + for (const auto& m : metadata) { + file << "// " << m.name << "\n"; + file << "{ "; + for (const auto& size : m.D_0D0096B8) { + file << size << ", "; + } + file << "},\n"; + } + file.close(); + } + + file.open(outDir+"D_0D009808.inc.c"); + if (file.is_open()) { + for (const auto& m : metadata) { + file << "// " << m.name << "\n"; + file << "{ "; + for (const auto& size : m.D_0D009808) { + file << size << ", "; + } + file << "},\n"; + } + file.close(); + } + + file.open(outDir+"gCoursePathTable.inc.c"); + if (file.is_open()) { + for (const auto& m : metadata) { + file << "// " << m.name << "\n"; + file << "{ "; + for (const auto& size : m.pathTable) { + file << size << ", "; + } + file << "},\n"; + } + file.close(); + } + + file.open(outDir+"gCoursePathTableUnknown.inc.c"); + if (file.is_open()) { + for (const auto& m : metadata) { + file << "// " << m.name << "\n"; + file << "{ "; + for (const auto& size : m.pathTableUnknown) { + file << size << ", "; + } + file << "},\n"; + } + file.close(); + } + + file.open(outDir+"sSkyColors.inc.c"); + if (file.is_open()) { + for (const auto& m : metadata) { + file << "// " << m.name << "\n"; + file << "{ "; + for (const auto& size : m.skyColors) { + file << size << ", "; + } + file << "},\n"; + } + file.close(); + } + + file.open(outDir+"sSkyColors2.inc.c"); + if (file.is_open()) { + for (const auto& m : metadata) { + file << "// " << m.name << "\n"; + file << "{ "; + for (const auto& size : m.skyColors2) { + file << size << ", "; + } + file << "},\n"; + } + file.close(); + } + return std::nullopt; +} + +ExportResult MK64::CourseMetadataBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { + //auto metadata = std::static_pointer_cast<MetadataData>(raw)->mMetadata; + //auto writer = LUS::BinaryWriter(); + + throw std::runtime_error("CourseMetadata not implemented for OTR"); + + // WriteHeader(writer, LUS::ResourceType::Metadata, 0); + // writer.Write((uint32_t) metadata.size()); + //writer.Finish(write); + return std::nullopt; +} + +std::optional<std::shared_ptr<IParsedData>> MK64::CourseMetadataFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { + auto dir = GetSafeNode<std::string>(node, "input_directory"); + + auto m = Companion::Instance->GetCourseMetadata(); + SPDLOG_INFO("RUNNING"); + std::vector<CourseMetadata> yamlData; + for (const auto &yamls : m[dir]) { + + if (!yamls["course"]) { + for (auto &node : yamls) { + std::cout << node << std::endl; + } + throw std::runtime_error("Course yaml missing root label of course\nEx. course:"); + } + + auto metadata = yamls["course"]; + + CourseMetadata data; + + data.id = GetSafeNode<uint32_t>(metadata, "id"); + data.name = GetSafeNode<std::string>(metadata, "name"); + data.debugName = GetSafeNode<std::string>(metadata, "debug_name"); + data.cup = GetSafeNode<std::string>(metadata, "cup"); + data.cupIndex = GetSafeNode<int32_t>(metadata, "cup_index"); + data.courseLength = GetSafeNode<std::string>(metadata, "course_length"); + + data.kartAIBehaviourLUT = GetSafeNode<std::string>(metadata, "kart_ai_behaviour_ptr"); + data.kartAIMaximumSeparation = GetSafeNode<std::string>(metadata, "kart_ai_maximum_separation"); + data.kartAIMinimumSeparation = GetSafeNode<std::string>(metadata, "kart_ai_minimum_separation"); + + data.D_800DCBB4 = GetSafeNode<std::string>(metadata, "D_800DCBB4"); + data.steeringSensitivity = GetSafeNode<uint32_t>(metadata, "cpu_steering_sensitivity"); + SPDLOG_INFO("BEFORE"); + for (const auto& bombKart : GetSafeNode<YAML::Node>(metadata, "bomb_kart_spawns")) { + data.bombKartSpawns.push_back(BombKartSpawns({ + bombKart[0].as<uint16_t>(), + bombKart[1].as<uint16_t>(), + bombKart[2].as<std::string>(), // Parse as string because floating-point outputs incorrect values. + bombKart[3].as<float>(), + bombKart[4].as<float>(), + bombKart[5].as<float>(), + bombKart[6].as<float>(), + })); + } + + for (const auto& size : GetSafeNode<YAML::Node>(metadata, "path_sizes")) { + data.pathSizes.push_back(size.as<uint16_t>()); + } + + for (const auto& value : GetSafeNode<YAML::Node>(metadata, "D_0D009418")) { + data.D_0D009418.push_back(value.as<std::string>()); + } + + for (const auto& value : GetSafeNode<YAML::Node>(metadata, "D_0D009568")) { + data.D_0D009568.push_back(value.as<std::string>()); + } + + for (const auto& value : GetSafeNode<YAML::Node>(metadata, "D_0D0096B8")) { + data.D_0D0096B8.push_back(value.as<std::string>()); + } + SPDLOG_INFO("MIDDLE"); + for (const auto& value : GetSafeNode<YAML::Node>(metadata, "D_0D009808")) { + data.D_0D009808.push_back(value.as<std::string>()); + } + + for (const auto& str : GetSafeNode<YAML::Node>(metadata, "path_table")) { + data.pathTable.push_back(str.as<std::string>()); + } + + for (const auto& str : GetSafeNode<YAML::Node>(metadata, "path_table_unknown")) { + data.pathTableUnknown.push_back(str.as<std::string>()); + } + SPDLOG_INFO("BEFORE COLOUR"); + for (const auto& value : GetSafeNode<YAML::Node>(metadata, "sky_colors")) { + data.skyColors.push_back(value.as<uint16_t>()); + } + SPDLOG_INFO("BEFORE COLOUR2"); + for (const auto& value : GetSafeNode<YAML::Node>(metadata, "sky_colors2")) { + data.skyColors2.push_back(value.as<uint16_t>()); + } + + yamlData.push_back(CourseMetadata( + {data} + )); + } + SPDLOG_INFO("END RUNNING"); + + return std::make_shared<MetadataData>(yamlData); +}
\ No newline at end of file |
