diff --git a/src/engine/World.h b/src/engine/World.h index aec00c228..bb8979090 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -97,7 +97,6 @@ public: Matrix Mtx; - // Holds all available courses Course* CurrentCourse; Cup* CurrentCup; @@ -118,6 +117,7 @@ public: TrainCrossing* AddCrossing(Vec3f position, u32 waypointMin, u32 waypointMax, f32 approachRadius, f32 exitRadius); std::vector> Crossings; + // Holds all available courses std::vector Courses; size_t CourseIndex = 0; // For browsing courses. private: diff --git a/src/engine/courses/Course.cpp b/src/engine/courses/Course.cpp index 5b28e6a28..b38d7dda6 100644 --- a/src/engine/courses/Course.cpp +++ b/src/engine/courses/Course.cpp @@ -79,6 +79,7 @@ Course::Course() { Props.Sequence = MusicSeq::MUSIC_SEQ_UNKNOWN; } +// Load custom track from code void Course::Load(Vtx* vtx, Gfx* gfx) { gSegmentTable[4] = reinterpret_cast(&vtx[0]); gSegmentTable[7] = reinterpret_cast(&gfx[0]); @@ -86,13 +87,18 @@ void Course::Load(Vtx* vtx, Gfx* gfx) { Course::Init(); } -void Course::Load() { +// Load custom track from o2r +void Course::Load(std::string dls) { + std::vector sections = LOAD_ASSET_RAW(dls); - if (Props.TrackModel) { - generate_collision_mesh_with_defaults((Gfx*)LOAD_ASSET_RAW(Props.TrackModel)); - return; + for (auto& section : sections) { + generate_collision_mesh((Gfx*)LOAD_ASSET_RAW(section.addr), section.surfaceType, section.sectionId); } + Course::Init(); +} +// Load stock track +void Course::Load() { size_t vtxSize = (ResourceGetSizeByName(this->vtx) / sizeof(CourseVtx)) * sizeof(Vtx); size_t texSegSize; diff --git a/src/engine/courses/Course.h b/src/engine/courses/Course.h index e6398739d..4889e081a 100644 --- a/src/engine/courses/Course.h +++ b/src/engine/courses/Course.h @@ -238,8 +238,9 @@ public: explicit Course(); - virtual void Load(); // Decompress and load stock courses. Must be overridden for custom courses - virtual void Load(Vtx* vtx, Gfx *gfx); // Load custom course + virtual void Load(); // Decompress and load stock courses + virtual void Load(Vtx* vtx, Gfx *gfx); // Load custom track from code + virtual void Load(std::string dls); // Load custom track from o2r virtual void LoadTextures(); /** diff --git a/src/engine/editor/SceneManager.cpp b/src/engine/editor/SceneManager.cpp index 8a125d1a1..677548660 100644 --- a/src/engine/editor/SceneManager.cpp +++ b/src/engine/editor/SceneManager.cpp @@ -37,7 +37,7 @@ namespace Editor { bool wrote = GameEngine::Instance->context->GetResourceManager()->GetArchiveManager()->WriteFile(CurrentArchive, SceneFile, stringify); if (wrote) { - printf("Successfully wrote scene file!\n"); + printf("Successfully wrote scene file!\n Wrote: %s\n", SceneFile.c_str()); } else { printf("Failed to write scene file!\n"); } @@ -102,7 +102,8 @@ namespace Editor { GameObject::CollisionType::BOUNDING_BOX, 20.0f, (int32_t*) &actor->bPendingDestroy, (int32_t) 1); } - void SetSceneFile(std::string sceneFile) { - SceneFile = sceneFile; + void SetSceneFile(std::string archive, std::string sceneFile) { + CurrentArchive = GameEngine::Instance->context->GetResourceManager()->GetArchiveManager()->GetArchiveFromFile(archive); + SceneFile = sceneFile+"/scene.json"; } } diff --git a/src/engine/editor/SceneManager.h b/src/engine/editor/SceneManager.h index 76aa02c02..8d3abbda4 100644 --- a/src/engine/editor/SceneManager.h +++ b/src/engine/editor/SceneManager.h @@ -5,7 +5,7 @@ namespace Editor { void SaveLevel(); void LoadLevel(std::string sceneFile); void Load_AddStaticMeshActor(const nlohmann::json& actorJson); - void SetSceneFile(std::string sceneFile); + void SetSceneFile(std::string archive, std::string sceneFile); extern std::shared_ptr CurrentArchive; // This is used to retrieve and write the scene data file extern std::string SceneFile; diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index ce214ee27..df2011647 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -155,6 +155,9 @@ GameEngine::GameEngine() { loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "TrackSections", static_cast(MK64::ResourceType::TrackSection), 0); + loader->RegisterResourceFactory(std::make_shared(), + RESOURCE_FORMAT_XML, "TrackSections", + static_cast(MK64::ResourceType::TrackSection), 0); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Waypoints", static_cast(MK64::ResourceType::Waypoints), 0); diff --git a/src/port/resource/importers/TrackSectionsFactory.cpp b/src/port/resource/importers/TrackSectionsFactory.cpp index f1614fbb4..b9c15878d 100644 --- a/src/port/resource/importers/TrackSectionsFactory.cpp +++ b/src/port/resource/importers/TrackSectionsFactory.cpp @@ -35,4 +35,30 @@ ResourceFactoryBinaryTrackSectionsV0::ReadResource(std::shared_ptr f return section; } + +std::shared_ptr +ResourceFactoryXMLTrackSectionsV0::ReadResource(std::shared_ptr file, + std::shared_ptr initData) { + + if (!FileHasValidFormatAndReader(file, initData)) { + return nullptr; + } + + auto section = std::make_shared(initData); + auto child = + std::get>(file->Reader)->FirstChildElement()->FirstChildElement(); + + while (child != nullptr) { + TrackSectionsO2R data; + // Convert n64 addr to native addr + data.addr = child->Attribute("gfx_path"); + data.surfaceType = child->IntAttribute("surface"); + data.sectionId = child->IntAttribute("section"); + data.flags = child->IntAttribute("flags"); + + section->TrackSectionsList.push_back(data); + } + + return section; +} } // namespace MK64 diff --git a/src/port/resource/importers/TrackSectionsFactory.h b/src/port/resource/importers/TrackSectionsFactory.h index 5b9e67d09..f0853682e 100644 --- a/src/port/resource/importers/TrackSectionsFactory.h +++ b/src/port/resource/importers/TrackSectionsFactory.h @@ -10,4 +10,10 @@ class ResourceFactoryBinaryTrackSectionsV0 : public Ship::ResourceFactoryBinary std::shared_ptr initData) override; }; +class ResourceFactoryXMLTrackSectionsV0 : public Ship::ResourceFactoryBinary { + public: + std::shared_ptr ReadResource(std::shared_ptr file, + std::shared_ptr initData) override; +}; + } // namespace MK64 diff --git a/src/port/resource/type/TrackSections.cpp b/src/port/resource/type/TrackSections.cpp index e87a15a2f..dcbdb4323 100644 --- a/src/port/resource/type/TrackSections.cpp +++ b/src/port/resource/type/TrackSections.cpp @@ -12,4 +12,15 @@ TrackSectionsI* TrackSectionsClass::GetPointer() { size_t TrackSectionsClass::GetPointerSize() { return TrackSectionsList.size() * sizeof(TrackSectionsI); } + +TrackSectionsO2RClass::TrackSectionsO2RClass() : Resource(std::shared_ptr()) { +} + +TrackSectionsO2R* TrackSectionsO2RClass::GetPointer() { + return TrackSectionsList.data(); +} + +size_t TrackSectionsO2RClass::GetPointerSize() { + return TrackSectionsList.size() *sizeof(TrackSectionsO2R); +} } // namespace MK64 diff --git a/src/port/resource/type/TrackSections.h b/src/port/resource/type/TrackSections.h index a615a95c2..17e3bc105 100644 --- a/src/port/resource/type/TrackSections.h +++ b/src/port/resource/type/TrackSections.h @@ -11,6 +11,13 @@ typedef struct { uint16_t flags; } TrackSectionsI; +typedef struct { + const char* addr; + uint8_t surfaceType; + uint8_t sectionId; + uint16_t flags; +} TrackSectionsO2R; + namespace MK64 { class TrackSectionsClass : public Ship::Resource { public: @@ -23,4 +30,17 @@ class TrackSectionsClass : public Ship::Resource { std::vector TrackSectionsList; }; + +class TrackSectionsO2RClass : public Ship::Resource { + public: + using Resource::Resource; + + TrackSectionsO2RClass(); + + TrackSectionsO2R* GetPointer() override; + size_t GetPointerSize() override; + + std::vector TrackSectionsList; +}; + } // namespace MK64 diff --git a/src/port/ui/ContentBrowser.cpp b/src/port/ui/ContentBrowser.cpp index 9e7c708e7..ba59dbb77 100644 --- a/src/port/ui/ContentBrowser.cpp +++ b/src/port/ui/ContentBrowser.cpp @@ -128,7 +128,7 @@ namespace Editor { bool foundTrackFile = false; for (auto& asset : TrackAssetMap[track]) { - if (asset.ends_with("track.json")) { + if (asset.ends_with("scene.json")) { foundTrackFile = true; if (ImGui::Button(label.c_str())) { @@ -144,7 +144,7 @@ namespace Editor { if (!foundTrackFile) { std::string label = fmt::format("{} {}", ICON_FA_EXCLAMATION_TRIANGLE, track); if (ImGui::Button(label.c_str())) { - SetSceneFile(TrackPath[track]); + SetSceneFile(TrackAssetMap[track][0], TrackPath[track]); SaveLevel(); Refresh = true; } @@ -242,10 +242,13 @@ namespace Editor { // Extract directory path (remove filename) size_t lastSlash = file.find_last_of('/'); + printf("file %s\n", file.c_str()); + std::string directoryPath = (lastSlash != std::string::npos) ? file.substr(0, lastSlash) : file; + printf("dir %s\n", directoryPath.c_str()); // Store in TrackPath - TrackPath[trackName] = directoryPath; + TrackPath[trackName] = file; } // Move unique tracks into the vector