summaryrefslogtreecommitdiff
path: root/src/factories/mk64/CourseMetadata.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/factories/mk64/CourseMetadata.cpp')
-rw-r--r--src/factories/mk64/CourseMetadata.cpp375
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