From 950ef8ea575cfb136fe17b536ca2bd81e598e6ef Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Sun, 27 Apr 2025 17:29:22 -0600 Subject: [PATCH] Impl Import Minimap --- src/engine/editor/SceneManager.cpp | 57 ++++++++++++++++--- src/engine/editor/SceneManager.h | 1 + src/port/Engine.cpp | 4 ++ .../resource/importers/MinimapFactory.cpp | 36 ++++++++++++ src/port/resource/importers/MinimapFactory.h | 14 +++++ src/port/resource/type/Minimap.cpp | 16 ++++++ src/port/resource/type/Minimap.h | 29 ++++++++++ src/port/resource/type/ResourceType.h | 1 + src/port/ui/ContentBrowser.cpp | 2 + 9 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 src/port/resource/importers/MinimapFactory.cpp create mode 100644 src/port/resource/importers/MinimapFactory.h create mode 100644 src/port/resource/type/Minimap.cpp create mode 100644 src/port/resource/type/Minimap.h diff --git a/src/engine/editor/SceneManager.cpp b/src/engine/editor/SceneManager.cpp index 7efa7081b..1040bd16f 100644 --- a/src/engine/editor/SceneManager.cpp +++ b/src/engine/editor/SceneManager.cpp @@ -9,7 +9,9 @@ #include #include "port/Engine.h" #include +#include "port/resource/type/Minimap.h" #include +#include "port/resource/type/ResourceType.h" namespace Editor { @@ -24,12 +26,26 @@ namespace Editor { data["Props"] = props.to_json(); - nlohmann::json actors; + nlohmann::json staticMesh; - // for (const auto& actor : gWorldInstance.StaticMeshActors) { + for (const auto& mesh : gWorldInstance.StaticMeshActors) { + staticMesh.push_back(mesh->to_json()); + } + data["StaticMeshActors"] = staticMesh; + + // nlohmann::json actors; + + // for (const auto& actor : gWorldInstance.Actors) { // actors.push_back(actor->to_json()); - // } - // data["Actors"] = actors; + // } + // data["Actors"] = actors; + + // nlohmann::json objects; + + // for (const auto& object : gWorldInstance.Objects) { + // objects.push_back(object->to_json()); + // } + // data["Objects"] = objects; auto dat = data.dump(); std::vector stringify; @@ -73,10 +89,10 @@ namespace Editor { } else { std::cerr << "Props data not found in the JSON file!" << std::endl; } - + // Load the Actors (deserialize them) - if (data.contains("Actors")) { - auto& actorsJson = data["Actors"]; + if (data.contains("StaticMeshActors")) { + auto& actorsJson = data["StaticMeshActors"]; gWorldInstance.StaticMeshActors.clear(); // Clear existing actors, if any for (const auto& actorJson : actorsJson) { @@ -87,7 +103,7 @@ namespace Editor { } } } - + void Load_AddStaticMeshActor(const nlohmann::json& actorJson) { gWorldInstance.StaticMeshActors.push_back(new StaticMeshActor("", FVector(0, 0, 0), IRotator(0, 0, 0), FVector(1, 1, 1), "", nullptr)); auto actor = gWorldInstance.StaticMeshActors.back(); @@ -103,4 +119,29 @@ namespace Editor { CurrentArchive = archive; SceneFile = sceneFile; } + + void LoadMinimap(std::shared_ptr archive, Course* course, std::string filePath) { + printf("LOADING MINIMAP %s\n", filePath.c_str()); + if (archive) { + auto initData = std::make_shared(); + initData->Parent = archive; + initData->Format = RESOURCE_FORMAT_BINARY; + initData->ByteOrder = Ship::Endianness::Little; + initData->Type = static_cast(MK64::ResourceType::Minimap); + initData->ResourceVersion = 0; + + std::shared_ptr ptr = std::static_pointer_cast( + GameEngine::Instance->context->GetResourceManager()->LoadResource(filePath, true, initData)); + + if (ptr) { + MK64::MinimapTexture texture = ptr->Texture; + printf("LOADED MINIMAP!\n"); + course->Props.MinimapTexture = (const char*)texture.Data; + course->Props.MinimapDimensions = IVector2D(texture.Width, texture.Height); + } else { + course->Props.MinimapTexture = gTextureCourseOutlineMarioRaceway; + course->Props.MinimapDimensions = IVector2D(ResourceGetTexWidthByName(course->Props.MinimapTexture), ResourceGetTexHeightByName(course->Props.MinimapTexture)); + } + } + } } diff --git a/src/engine/editor/SceneManager.h b/src/engine/editor/SceneManager.h index c9fc97c6d..58699107e 100644 --- a/src/engine/editor/SceneManager.h +++ b/src/engine/editor/SceneManager.h @@ -6,6 +6,7 @@ namespace Editor { void LoadLevel(std::shared_ptr archive, Course* course, std::string sceneFile); void Load_AddStaticMeshActor(const nlohmann::json& actorJson); void SetSceneFile(std::shared_ptr archive, std::string sceneFile); + void LoadMinimap(std::shared_ptr archive, Course* course, std::string filePath); 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 4ed5b4aa4..f5c8a6a48 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -18,6 +18,7 @@ #include "resource/importers/ActorSpawnDataFactory.h" #include "resource/importers/UnkActorSpawnDataFactory.h" #include "resource/importers/ArrayFactory.h" +#include "resource/importers/MinimapFactory.h" #include #include #include "window/gui/resource/Font.h" @@ -170,6 +171,9 @@ GameEngine::GameEngine() { loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "UnkSpawnData", static_cast(MK64::ResourceType::UnkSpawnData), 0); + loader->RegisterResourceFactory(std::make_shared(), + RESOURCE_FORMAT_BINARY, "Minimap", + static_cast(MK64::ResourceType::Minimap), 0); fontMono = CreateFontWithSize(16.0f, "fonts/Inconsolata-Regular.ttf"); fontMonoLarger = CreateFontWithSize(20.0f, "fonts/Inconsolata-Regular.ttf"); diff --git a/src/port/resource/importers/MinimapFactory.cpp b/src/port/resource/importers/MinimapFactory.cpp new file mode 100644 index 000000000..abc786da0 --- /dev/null +++ b/src/port/resource/importers/MinimapFactory.cpp @@ -0,0 +1,36 @@ +#include "MinimapFactory.h" +#include "port/resource/type/Minimap.h" +#include "spdlog/spdlog.h" +#include "stb_image.h" + +namespace MK64 { + +std::shared_ptr +ResourceFactoryBinaryMinimapV0::ReadResource(std::shared_ptr file, + std::shared_ptr initData) { + if (!FileHasValidFormatAndReader(file, initData)) { + return nullptr; + } + + auto texture = std::make_shared(initData); + auto reader = std::get>(file->Reader); + + texture->Texture.Size = file->Buffer->size(); + texture->Texture.Width = 0; + texture->Texture.Height = 0; + texture->Texture.Channels = 4; // Always force 4 channels (RGBA) + texture->Texture.Data = stbi_load_from_memory(reinterpret_cast(file->Buffer->data()), texture->Texture.Size, + &texture->Texture.Width, &texture->Texture.Height, nullptr, 4); + + if (nullptr == texture->Texture.Data) { + SPDLOG_ERROR("MinimapFactory.cpp: Error loading minimap texture {}", stbi_failure_reason()); + return nullptr; + } + + + // stbi_image_free(imageData); + + return texture; +} + +} diff --git a/src/port/resource/importers/MinimapFactory.h b/src/port/resource/importers/MinimapFactory.h new file mode 100644 index 000000000..04346176d --- /dev/null +++ b/src/port/resource/importers/MinimapFactory.h @@ -0,0 +1,14 @@ +#pragma once + +#include "resource/Resource.h" +#include "resource/ResourceFactoryBinary.h" +#include "resource/ResourceFactoryXML.h" + +namespace MK64 { +class ResourceFactoryBinaryMinimapV0 : 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/Minimap.cpp b/src/port/resource/type/Minimap.cpp new file mode 100644 index 000000000..1389dc41e --- /dev/null +++ b/src/port/resource/type/Minimap.cpp @@ -0,0 +1,16 @@ +#include "Minimap.h" +#include "libultraship/libultra/gbi.h" + +namespace MK64 { +Minimap::Minimap() : Resource(std::shared_ptr()) { +} + +MinimapTexture* Minimap::GetPointer() { + return &Texture; +} + +size_t Minimap::GetPointerSize() { + return sizeof(Texture); +} + +} // namespace MK64 diff --git a/src/port/resource/type/Minimap.h b/src/port/resource/type/Minimap.h new file mode 100644 index 000000000..ea88d3d2f --- /dev/null +++ b/src/port/resource/type/Minimap.h @@ -0,0 +1,29 @@ +#pragma once + +#include "resource/Resource.h" +#include +#include + +namespace MK64 { + +struct MinimapTexture { + int32_t Width; + int32_t Height; + int32_t Channels; + size_t Size; + uint8_t* Data; +}; + +class Minimap : public Ship::Resource { + public: + using Resource::Resource; + + Minimap(); + + MinimapTexture* GetPointer() override; + size_t GetPointerSize() override; + + MinimapTexture Texture; +}; + +} // namespace MK64 diff --git a/src/port/resource/type/ResourceType.h b/src/port/resource/type/ResourceType.h index fe27a7930..72876e626 100644 --- a/src/port/resource/type/ResourceType.h +++ b/src/port/resource/type/ResourceType.h @@ -34,5 +34,6 @@ enum class ResourceType { SpawnData = 0x53444154, // SDAT UnkSpawnData = 0x55534454, // USDT KartAI = 0x44424856, // DBHV + Minimap = 0x4D4D4150, // MMAP }; } diff --git a/src/port/ui/ContentBrowser.cpp b/src/port/ui/ContentBrowser.cpp index 92dda316f..cac31f403 100644 --- a/src/port/ui/ContentBrowser.cpp +++ b/src/port/ui/ContentBrowser.cpp @@ -231,6 +231,7 @@ namespace Editor { for (const std::string& dir : dirs) { std::string name = dir.substr(dir.find_last_of('/') + 1); std::string sceneFile = dir + "/scene.json"; + std::string minimapFile = dir + "/minimap"; if (manager->HasFile(sceneFile)) { auto archive = manager->GetArchiveFromFile(sceneFile); @@ -238,6 +239,7 @@ namespace Editor { course->LoadO2R(dir); gWorldInstance.Courses.push_back(course); LoadLevel(archive, course, sceneFile); + LoadMinimap(archive, course, minimapFile); Tracks.push_back({course, sceneFile, name, dir, archive}); } else { const std::string file = dir + "/data_track_sections";