diff options
| author | MegaMech <MegaMech@users.noreply.github.com> | 2025-12-15 12:29:58 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-12-15 12:29:58 -0700 |
| commit | eb11374093b07bd968ccb955eecd06133db0ab74 (patch) | |
| tree | 8e584cd21b9ea22403c903621d300d8223a62c86 /src | |
| parent | 2995361eb152a5c0c8add52c590e30ec916b81ec (diff) | |
Edit TrackInfo Properties (#594)
* Fix finishline for toads turnpike in extra
* Fixed trash bin in extra
* Refactor fov
* Update scene.json
* Allow setting fog
* impl fog save & load
* Fix modifying resourceName and rename editor namespace to trackeditor
* small change
Diffstat (limited to 'src')
41 files changed, 221 insertions, 119 deletions
diff --git a/src/engine/Actor.cpp b/src/engine/Actor.cpp index ccec1cb9e..72f7b3289 100644 --- a/src/engine/Actor.cpp +++ b/src/engine/Actor.cpp @@ -25,7 +25,7 @@ void AActor::BeginPlay() { if ((nullptr != Model) && (Model[0] != '\0')) { // Prevent collision mesh from being generated extra times. if (Triangles.size() == 0) { - Editor::GenerateCollisionMesh(this, (Gfx*)LOAD_ASSET_RAW(Model), 1.0f); + TrackEditor::GenerateCollisionMesh(this, (Gfx*)LOAD_ASSET_RAW(Model), 1.0f); } } } diff --git a/src/engine/RegisterContent.cpp b/src/engine/RegisterContent.cpp index 41dd41f58..d2dba2675 100644 --- a/src/engine/RegisterContent.cpp +++ b/src/engine/RegisterContent.cpp @@ -495,7 +495,7 @@ void RegisterTracks(Registry<TrackInfo>& r) { r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<BigDonut>()); }); info = { - .ResourceName = "mk:test_track", + .ResourceName = "hm:test_track", .Name = "test track", .DebugName = "test track", .Length = "100m", diff --git a/src/engine/Registry.h b/src/engine/Registry.h index 7777266d5..7b4af0f2b 100644 --- a/src/engine/Registry.h +++ b/src/engine/Registry.h @@ -97,6 +97,17 @@ public: return list; } + // Returns true if item succesfully removed + // Note that mCounter is not decremented on remove + bool Remove(const std::string& resourceName) { + auto it = mMap.find(resourceName); + if (it != mMap.end()) { + mMap.erase(it); + return true; + } + return false; + } + void Clear() { mMap.clear(); mCounter = 0; diff --git a/src/engine/TrackBrowser.cpp b/src/engine/TrackBrowser.cpp index 7d76a46bc..7fd5dddad 100644 --- a/src/engine/TrackBrowser.cpp +++ b/src/engine/TrackBrowser.cpp @@ -1,6 +1,7 @@ #include "TrackBrowser.h" #include "port/Engine.h" #include "engine/editor/SceneManager.h" +#include <imgui.h> TrackBrowser* TrackBrowser::Instance; @@ -8,65 +9,63 @@ void TrackBrowser::FindCustomTracks() { auto manager = GameEngine::Instance->context->GetResourceManager()->GetArchiveManager(); auto ptr2 = manager->ListDirectories("tracks/*"); - if (ptr2) { - auto dirs = *ptr2; - - 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.png"; - - // The track has a valid scene file, add it to the registry - if (manager->HasFile(sceneFile)) { - auto archive = manager->GetArchiveFromFile(sceneFile); + if (!ptr2) { + return; + } + auto dirs = *ptr2; + + 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.png"; + + // The track has a valid scene file, add it to the registry + if (manager->HasFile(sceneFile)) { + auto archive = manager->GetArchiveFromFile(sceneFile); + + TrackInfo info; + info.Path = dir; + TrackEditor::LoadTrackInfo(info, archive, sceneFile); + printf("[TrackBrowser] Added custom track %s\n", info.Name.c_str()); + gTrackRegistry.Add(info, [info, archive]() { + auto track = std::make_unique<Track>(); + track->ResourceName = info.ResourceName; + track->Archive = archive; + GetWorld()->SetCurrentTrack(std::move(track)); + }); + } else { // The track does not have a valid scene file + const std::string file = dir + "/data_track_sections"; + // If the track has a data_track_sections file, + // then it must at least be a valid track. + // So lets add it as an uninitialized track. + if (manager->HasFile(file)) { + printf("[TrackBrowser] [FindCustomTracks] Found a new custom track!\n"); + printf(" Creating scene.json so the track can be configured in the editor\n"); TrackInfo info; + std::string resName = std::string("mods:") + name; + info.ResourceName = resName; + info.Name = name; + info.DebugName = name; info.Path = dir; - Editor::LoadTrackInfo(info, archive, sceneFile); - printf("Added custom track %s\n", info.Name.c_str()); + + // Create the track + auto archive = manager->GetArchiveFromFile(file); + auto track = std::make_unique<Track>(); + track->Archive = archive; + track->ResourceName = info.ResourceName; + TrackEditor::SaveLevel(track.get(), static_cast<const TrackInfo*>(&info)); // Write scene file so it will show up in the track browser + printf("[TrackBrowser] [FindCustomTracks] Saved scene.json to new track!\n"); + + // Passing these through seems kinda bad. But it works? gTrackRegistry.Add(info, [info, archive]() { auto track = std::make_unique<Track>(); - track->ResourceName = info.ResourceName; track->Archive = archive; + track->ResourceName = info.ResourceName; GetWorld()->SetCurrentTrack(std::move(track)); }); - } else { // The track does not have a valid scene file - const std::string file = dir + "/data_track_sections"; - - // If the track has a data_track_sections file, - // then it must at least be a valid track. - // So lets add it as an uninitialized track. - if (manager->HasFile(file)) { - printf("[TrackBrowser] [FindCustomTracks] Found a new custom track!\n"); - printf(" Creating scene.json so the track can be configured in the editor\n"); - - TrackInfo info; - - std::string resName = std::string("mods:") + name; - info.ResourceName = resName; - info.Name = name; - info.DebugName = name; - info.Path = dir; - - auto archive = manager->GetArchiveFromFile(file); - //mNewTracks.push_back({info, "", dir, archive}); - auto track = std::make_unique<Track>(); - track->Archive = archive; - track->ResourceName = info.ResourceName; - Editor::SaveLevel(track.get(), &info); // Write scene file so it will show up in the track browser - printf("[TrackBrowser] [FindCustomTracks] Saved scene.json to new track!\n"); - - // Passing these through seems kinda bad. But it works? - gTrackRegistry.Add(info, [info, archive]() { - auto track = std::make_unique<Track>(); - track->Archive = archive; - track->ResourceName = info.ResourceName; - GetWorld()->SetCurrentTrack(std::move(track)); - }); - - } else { - printf("ContentBrowser.cpp: Track '%s' missing required track files. Cannot add to game\n Missing %s/data_track_sections file\n", name.c_str(), dir.c_str()); - } + } else { + printf("[TrackBrowser] Track '%s' missing required track files. Cannot add to game\n Missing %s/data_track_sections file\n", name.c_str(), dir.c_str()); } } } diff --git a/src/engine/actors/Cloud.cpp b/src/engine/actors/Cloud.cpp index fe7dff63c..f4c48ea75 100644 --- a/src/engine/actors/Cloud.cpp +++ b/src/engine/actors/Cloud.cpp @@ -50,7 +50,7 @@ void ACloud::BeginPlay() { // Prevent collision mesh from being generated extra times. if (Editor_IsEnabled()) { if (Triangles.size() == 0) { - Editor::GenerateCollisionMesh(this, (Gfx*)cloud_mesh, 1.0f); + TrackEditor::GenerateCollisionMesh(this, (Gfx*) cloud_mesh, 1.0f); } } } diff --git a/src/engine/actors/Finishline.cpp b/src/engine/actors/Finishline.cpp index 18478dac1..ec9a5f97b 100644 --- a/src/engine/actors/Finishline.cpp +++ b/src/engine/actors/Finishline.cpp @@ -53,7 +53,7 @@ void AFinishline::BeginPlay() { // Prevent collision mesh from being generated extra times. if (Editor_IsEnabled()) { if (Triangles.size() == 0) { - Editor::GenerateCollisionMesh(this, (Gfx*)LOAD_ASSET_RAW(D_0D001B90), 1.0f); + TrackEditor::GenerateCollisionMesh(this, (Gfx*)LOAD_ASSET_RAW(D_0D001B90), 1.0f); } } } diff --git a/src/engine/actors/Ship.cpp b/src/engine/actors/Ship.cpp index c1aef72a5..934943768 100644 --- a/src/engine/actors/Ship.cpp +++ b/src/engine/actors/Ship.cpp @@ -55,7 +55,7 @@ void AShip::BeginPlay() { // Prevent collision mesh from being generated extra times. if (Editor_IsEnabled()) { if (Triangles.size() == 0) { - Editor::GenerateCollisionMesh(this, (Gfx*)_skin, Scale.y); + TrackEditor::GenerateCollisionMesh(this, (Gfx*) _skin, Scale.y); } } } diff --git a/src/engine/actors/Starship.cpp b/src/engine/actors/Starship.cpp index e801f1029..bdafbbb4a 100644 --- a/src/engine/actors/Starship.cpp +++ b/src/engine/actors/Starship.cpp @@ -35,7 +35,7 @@ void AStarship::BeginPlay() { // Prevent collision mesh from being generated extra times. if (Editor_IsEnabled()) { if (Triangles.size() == 0) { - Editor::GenerateCollisionMesh(this, (Gfx*)Model, 1.0f); + TrackEditor::GenerateCollisionMesh(this, (Gfx*)Model, 1.0f); } } } diff --git a/src/engine/editor/Collision.cpp b/src/engine/editor/Collision.cpp index f79865899..d872963d1 100644 --- a/src/engine/editor/Collision.cpp +++ b/src/engine/editor/Collision.cpp @@ -14,7 +14,7 @@ extern "C" { #include "assets/textures/other_textures.h" } -namespace Editor { +namespace TrackEditor { void GenerateCollisionMesh(std::variant<AActor*, OObject*, GameObject*> object, Gfx* model, float scale) { int8_t opcode; uintptr_t lo; diff --git a/src/engine/editor/Collision.h b/src/engine/editor/Collision.h index d761bf04c..1583cdcc6 100644 --- a/src/engine/editor/Collision.h +++ b/src/engine/editor/Collision.h @@ -19,7 +19,7 @@ #define EDITOR_GFX_GET_OPCODE(var) ((uint32_t) ((var) & 0xFF000000)) -namespace Editor { +namespace TrackEditor { void GenerateCollisionMesh(std::variant<AActor*, OObject*, GameObject*> object, Gfx* model, float scale); void DebugCollision(GameObject* obj, FVector pos, IRotator rot, FVector scale, const std::vector<Triangle>& triangles); } diff --git a/src/engine/editor/Editor.cpp b/src/engine/editor/Editor.cpp index 698a6cc40..87bca2a82 100644 --- a/src/engine/editor/Editor.cpp +++ b/src/engine/editor/Editor.cpp @@ -24,7 +24,7 @@ extern "C" { #include "camera.h" } -namespace Editor { +namespace TrackEditor { Editor* Editor::Instance; Editor::Editor() { diff --git a/src/engine/editor/Editor.h b/src/engine/editor/Editor.h index 77169de46..bfd7b1290 100644 --- a/src/engine/editor/Editor.h +++ b/src/engine/editor/Editor.h @@ -12,7 +12,7 @@ extern "C" { } #include "ObjectPicker.h" -namespace Editor { +namespace TrackEditor { class ObjectPicker; class Editor { @@ -54,7 +54,7 @@ private: void Copy(MtxF* src, MtxF* dest); void Clear(MtxF* mf); }; -} // namespace Editor +} // namespace TrackEditor #endif // __cplusplus diff --git a/src/engine/editor/GameObject.cpp b/src/engine/editor/GameObject.cpp index 30a1722f4..aeda2eb5b 100644 --- a/src/engine/editor/GameObject.cpp +++ b/src/engine/editor/GameObject.cpp @@ -1,7 +1,7 @@ #include <libultraship/libultraship.h> #include "GameObject.h" -namespace Editor { +namespace TrackEditor { GameObject::GameObject(FVector pos, IRotator rot, FVector scale, const char* model, std::vector<Triangle> triangles, CollisionType collision, float boundingBoxSize) { Pos = pos; @@ -38,4 +38,4 @@ namespace Editor { Scale = scale; }; -} // namespace Editor +} // namespace TrackEditor diff --git a/src/engine/editor/GameObject.h b/src/engine/editor/GameObject.h index 35ce90dbf..00087105e 100644 --- a/src/engine/editor/GameObject.h +++ b/src/engine/editor/GameObject.h @@ -16,7 +16,7 @@ extern "C" { struct Triangle; -namespace Editor { +namespace TrackEditor { class GameObject { public: enum class CollisionType { diff --git a/src/engine/editor/Gizmo.cpp b/src/engine/editor/Gizmo.cpp index 4d3c86d25..4301f7db4 100644 --- a/src/engine/editor/Gizmo.cpp +++ b/src/engine/editor/Gizmo.cpp @@ -29,7 +29,7 @@ extern "C" { #include "math_util.h" } -namespace Editor { +namespace TrackEditor { void Gizmo::Load() { /* Translate handle collision */ diff --git a/src/engine/editor/Gizmo.h b/src/engine/editor/Gizmo.h index f98b634b1..bb1f037cc 100644 --- a/src/engine/editor/Gizmo.h +++ b/src/engine/editor/Gizmo.h @@ -8,7 +8,7 @@ #include "engine/objects/Object.h" #include <variant> -namespace Editor { +namespace TrackEditor { class Gizmo { public: diff --git a/src/engine/editor/Handles.cpp b/src/engine/editor/Handles.cpp index 532af6af6..577256690 100644 --- a/src/engine/editor/Handles.cpp +++ b/src/engine/editor/Handles.cpp @@ -3,7 +3,7 @@ #include "Handles.h" -namespace Editor { +namespace TrackEditor { Handles::Handles() { } diff --git a/src/engine/editor/Handles.h b/src/engine/editor/Handles.h index ecd8f8f90..c8fae7f14 100644 --- a/src/engine/editor/Handles.h +++ b/src/engine/editor/Handles.h @@ -4,7 +4,7 @@ #include <libultra/gbi.h> #include "GameObject.h" -namespace Editor { +namespace TrackEditor { class Handles : public GameObject { Handles(); diff --git a/src/engine/editor/Light.cpp b/src/engine/editor/Light.cpp index 53dc00864..477793540 100644 --- a/src/engine/editor/Light.cpp +++ b/src/engine/editor/Light.cpp @@ -27,7 +27,7 @@ extern "C" { #include "math_util_2.h" } -namespace Editor { +namespace TrackEditor { size_t LightObject::NumLights = 0; diff --git a/src/engine/editor/Light.h b/src/engine/editor/Light.h index 3a177053e..5af0b9466 100644 --- a/src/engine/editor/Light.h +++ b/src/engine/editor/Light.h @@ -5,7 +5,7 @@ #include "Collision.h" #include "GameObject.h" -namespace Editor { +namespace TrackEditor { class LightObject : public GameObject { public: diff --git a/src/engine/editor/ObjectPicker.cpp b/src/engine/editor/ObjectPicker.cpp index cbce7dd09..7fd4cc407 100644 --- a/src/engine/editor/ObjectPicker.cpp +++ b/src/engine/editor/ObjectPicker.cpp @@ -25,7 +25,7 @@ extern "C" { #include "camera.h" } -namespace Editor { +namespace TrackEditor { void ObjectPicker::Load() { eGizmo.Load(); @@ -230,7 +230,7 @@ std::pair<GameObject*, float> ObjectPicker::CheckEditorObjectRay(Ray ray) { break; } case GameObject::CollisionType::BOUNDING_SPHERE: - printf("Editor::ObjectPicker.cpp Bounding sphere collision type not yet supported\n"); + printf("[ObjectPicker] [CheckEditorObjectRay] Bounding sphere collision type not yet supported\n"); break; } } diff --git a/src/engine/editor/ObjectPicker.h b/src/engine/editor/ObjectPicker.h index 0dbdca215..cf1e4e12d 100644 --- a/src/engine/editor/ObjectPicker.h +++ b/src/engine/editor/ObjectPicker.h @@ -7,7 +7,7 @@ #include "GameObject.h" #include "engine/Matrix.h" -namespace Editor { +namespace TrackEditor { class ObjectPicker { public: void SelectObject(std::vector<GameObject*> objects); diff --git a/src/engine/editor/SceneManager.cpp b/src/engine/editor/SceneManager.cpp index 026dfbfe0..1a0c129c0 100644 --- a/src/engine/editor/SceneManager.cpp +++ b/src/engine/editor/SceneManager.cpp @@ -33,7 +33,7 @@ extern "C" { #include "render_courses.h" } -namespace Editor { +namespace TrackEditor { void SaveLevel(Track* track, const TrackInfo* info) { nlohmann::json data; @@ -42,6 +42,7 @@ namespace Editor { */ try { data["Props"] = track->Props.to_json(); + data["Props"]["ResourceName"] = track->ResourceName.c_str(); } catch (...) { SPDLOG_ERROR("[SceneManager] [SaveLevel] Failed serializing track Props"); } @@ -331,6 +332,7 @@ namespace Editor { try { track->Props.from_json(data["Props"]); + track->ResourceName = data["Props"].at("ResourceName").get<std::string>(); } catch(const std::exception& e) { std::cerr << " Error parsing track properties: " << e.what() << std::endl; std::cerr << " Is your scene.json file out of date?" << std::endl; diff --git a/src/engine/editor/SceneManager.h b/src/engine/editor/SceneManager.h index 7adff2af9..44c2f538f 100644 --- a/src/engine/editor/SceneManager.h +++ b/src/engine/editor/SceneManager.h @@ -6,7 +6,7 @@ #include <optional> #include <nlohmann/json.hpp> -namespace Editor { +namespace TrackEditor { void SaveLevel(Track* track, const TrackInfo* info); void LoadTrackDataFromJson(Track* track, const std::string& trackPath); void LoadTrackInfo(TrackInfo& info, std::shared_ptr<Ship::Archive> archive, std::string sceneFile); diff --git a/src/engine/tracks/TestTrack.cpp b/src/engine/tracks/TestTrack.cpp index d60505180..1df75d0b9 100644 --- a/src/engine/tracks/TestTrack.cpp +++ b/src/engine/tracks/TestTrack.cpp @@ -71,7 +71,7 @@ TestTrack::TestTrack() { Props.Minimap.Colour = {255, 255, 255}; ResizeMinimap(&Props.Minimap); - ResourceName = "mk:test_track"; + ResourceName = "hm:test_track"; Props.SetText(Props.Name, "Test Track", sizeof(Props.Name)); Props.SetText(Props.DebugName, "test track", sizeof(Props.DebugName)); diff --git a/src/engine/tracks/Track.cpp b/src/engine/tracks/Track.cpp index 49fcddabf..8db929986 100644 --- a/src/engine/tracks/Track.cpp +++ b/src/engine/tracks/Track.cpp @@ -350,7 +350,6 @@ bool IsTriangleWindingInverted() { return !gModifiedGfxSet.empty(); } - Track::Track() { Props.SetText(Props.ResourceName, "mod:blank_track", sizeof(Props.ResourceName)); Props.SetText(Props.Name, "Blank Track", sizeof(Props.Name)); @@ -358,7 +357,7 @@ Track::Track() { Props.SetText(Props.TrackLength, "100m", sizeof(Props.TrackLength)); // Props.Cup = FLOWER_CUP; // Props.CupIndex = 3; - ResourceName = ""; + ResourceName = "mod:blank_track"; Props.Minimap.Texture = minimap_mario_raceway; Props.Minimap.Width = ResourceGetTexWidthByName(Props.Minimap.Texture); Props.Minimap.Height = ResourceGetTexHeightByName(Props.Minimap.Texture); @@ -450,7 +449,7 @@ void Track::Load() { } else { // Load custom track bIsMod = true; - Editor::LoadTrackDataFromJson(this, trackPath); + TrackEditor::LoadTrackDataFromJson(this, trackPath); const std::string trackSectionPath = (trackPath + "/data_track_sections"); TrackSections* sections = (TrackSections*) LOAD_ASSET_RAW(trackSectionPath.c_str()); @@ -647,6 +646,10 @@ void Track::Draw(ScreenContext* arg0) { } const TrackInfo* info = gTrackRegistry.GetInfo(ResourceName); + if (nullptr == info) { + printf("[Track] [Draw] Resource name did not return a valid TrackInfo %s\n", ResourceName.c_str()); + return; + } std::string res = info->Path + "/data_track_sections"; TrackSections* sections = (TrackSections*) LOAD_ASSET_RAW(res.c_str()); diff --git a/src/engine/tracks/Track.h b/src/engine/tracks/Track.h index 14b923262..2deb20b62 100644 --- a/src/engine/tracks/Track.h +++ b/src/engine/tracks/Track.h @@ -86,7 +86,6 @@ typedef struct { } TrackSections; typedef struct Properties { - char ResourceName[128]; char Name[128]; char DebugName[128]; char TrackLength[128]; @@ -116,8 +115,6 @@ typedef struct Properties { #ifdef __cplusplus nlohmann::json to_json() const { nlohmann::json j; - // j["Id"] = Id ? Id : ""; - j["ResourceName"] = ResourceName ? ResourceName : ""; j["Name"] = Name ? Name : ""; j["DebugName"] = DebugName ? DebugName : ""; j["TrackLength"] = TrackLength ? TrackLength : ""; @@ -180,19 +177,12 @@ typedef struct Properties { // Function to load struct from JSON void from_json(const nlohmann::json& j) { - //Id = j.at("Id").get<std::string>().c_str(); -// Name = j.at("Name").get<std::string>().c_str(); - strncpy(ResourceName, j.at("ResourceName").get<std::string>().c_str(), sizeof(ResourceName) - 1); - ResourceName[sizeof(ResourceName) - 1] = '\0'; // Ensure null termination - strncpy(Name, j.at("Name").get<std::string>().c_str(), sizeof(Name) - 1); Name[sizeof(Name) - 1] = '\0'; // Ensure null termination -// DebugName = j.at("DebugName").get<std::string>().c_str(); strncpy(DebugName, j.at("DebugName").get<std::string>().c_str(), sizeof(DebugName) - 1); DebugName[sizeof(DebugName) - 1] = '\0'; // Ensure null termination - // TrackLength = j.at("TrackLength").get<std::string>().c_str(); strncpy(TrackLength, j.at("TrackLength").get<std::string>().c_str(), sizeof(TrackLength) - 1); TrackLength[sizeof(TrackLength) - 1] = '\0'; // Ensure null termination diff --git a/src/menus.c b/src/menus.c index 60361fd0d..59db38443 100644 --- a/src/menus.c +++ b/src/menus.c @@ -1177,7 +1177,7 @@ void splash_menu_act(struct Controller* controller, u16 controllerIdx) { } case DEBUG_MENU_LAUNCH_EDITOR: { if (btnAndStick & (A_BUTTON | START_BUTTON)) { - Editor_Launch("mk:test_track"); + Editor_Launch("hm:test_track"); play_sound2(SOUND_INTRO_ENTER_MENU); } diff --git a/src/port/Game.cpp b/src/port/Game.cpp index 83a49ecfd..efd4eb1be 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -69,7 +69,7 @@ Cup* gBattleCup; HarbourMastersIntro gMenuIntro; -Editor::Editor gEditor; +TrackEditor::Editor gEditor; s32 gTrophyIndex = NULL; @@ -757,7 +757,7 @@ void CM_ActorGenerateCollision(struct Actor* actor) { if ((nullptr != act->Model) && (act->Model[0] != '\0')) { if (act->Triangles.size() == 0) { - Editor::GenerateCollisionMesh(act, (Gfx*)LOAD_ASSET_RAW(act->Model), 1.0f); + TrackEditor::GenerateCollisionMesh(act, (Gfx*)LOAD_ASSET_RAW(act->Model), 1.0f); } } } diff --git a/src/port/Game.h b/src/port/Game.h index 19d6bca6e..d1f6ec3df 100644 --- a/src/port/Game.h +++ b/src/port/Game.h @@ -25,7 +25,7 @@ extern "C" { extern s32 gTrophyIndex; #ifdef __cplusplus -extern Editor::Editor gEditor; +extern TrackEditor::Editor gEditor; extern HarbourMastersIntro gMenuIntro; extern bool bCleanWorld; extern Registry<TrackInfo> gTrackRegistry; diff --git a/src/port/ui/ContentBrowser.cpp b/src/port/ui/ContentBrowser.cpp index c6a3c2551..a5ef9baa3 100644 --- a/src/port/ui/ContentBrowser.cpp +++ b/src/port/ui/ContentBrowser.cpp @@ -29,7 +29,7 @@ extern "C" { #include "collision.h" } -namespace Editor { +namespace TrackEditor { bool bIsTrainWindowOpen = false; // Global because member variables do not work in lambdas ContentBrowserWindow::~ContentBrowserWindow() { diff --git a/src/port/ui/ContentBrowser.h b/src/port/ui/ContentBrowser.h index b259e0b78..5d4e4c338 100644 --- a/src/port/ui/ContentBrowser.h +++ b/src/port/ui/ContentBrowser.h @@ -4,7 +4,7 @@ #include "engine/tracks/Track.h" #include "AllActors.h" -namespace Editor { +namespace TrackEditor { class ContentBrowserWindow : public Ship::GuiWindow { public: using Ship::GuiWindow::GuiWindow; diff --git a/src/port/ui/ImguiUI.cpp b/src/port/ui/ImguiUI.cpp index ddfde0781..7ee262cb4 100644 --- a/src/port/ui/ImguiUI.cpp +++ b/src/port/ui/ImguiUI.cpp @@ -69,21 +69,21 @@ void SetupGuiElements() { SPDLOG_ERROR("Could not find input GfxDebuggerWindow"); } - mToolsWindow = std::make_shared<Editor::ToolsWindow>("gEditorEnabled", "Tools", ImVec2(100, 100), + mToolsWindow = std::make_shared<TrackEditor::ToolsWindow>("gEditorEnabled", "Tools", ImVec2(100, 100), (ImGuiWindowFlags_NoTitleBar)); gui->AddGuiWindow(mToolsWindow); - mSceneExplorerWindow = std::make_shared<Editor::SceneExplorerWindow>("gEditorEnabled", "Scene Explorer"); + mSceneExplorerWindow = std::make_shared<TrackEditor::SceneExplorerWindow>("gEditorEnabled", "Scene Explorer"); gui->AddGuiWindow(mSceneExplorerWindow); - mPropertiesWindow = std::make_shared<Editor::PropertiesWindow>("gEditorEnabled", "Properties"); + mPropertiesWindow = std::make_shared<TrackEditor::PropertiesWindow>("gEditorEnabled", "Properties"); gui->AddGuiWindow(mPropertiesWindow); - mTrackPropertiesWindow = std::make_shared<Editor::TrackPropertiesWindow>("gEditorEnabled", "Track Properties"); + mTrackPropertiesWindow = std::make_shared<TrackEditor::TrackPropertiesWindow>("gEditorEnabled", "Track Properties"); gui->AddGuiWindow(mTrackPropertiesWindow); mContentBrowserWindow = - std::make_shared<Editor::ContentBrowserWindow>("gEditorEnabled", "Content Browser"); + std::make_shared<TrackEditor::ContentBrowserWindow>("gEditorEnabled", "Content Browser"); gui->AddGuiWindow(mContentBrowserWindow); } diff --git a/src/port/ui/Properties.cpp b/src/port/ui/Properties.cpp index 216efa2c1..fc3eb2d1e 100644 --- a/src/port/ui/Properties.cpp +++ b/src/port/ui/Properties.cpp @@ -23,7 +23,7 @@ extern "C" { #include "actors.h" } -namespace Editor { +namespace TrackEditor { PropertiesWindow::~PropertiesWindow() { SPDLOG_TRACE("destruct properties window"); diff --git a/src/port/ui/Properties.h b/src/port/ui/Properties.h index 64af1b4f8..2330a1f0c 100644 --- a/src/port/ui/Properties.h +++ b/src/port/ui/Properties.h @@ -3,7 +3,7 @@ #include <libultraship/libultraship.h> #include "port/Game.h" -namespace Editor { +namespace TrackEditor { class PropertiesWindow : public Ship::GuiWindow { public: using Ship::GuiWindow::GuiWindow; diff --git a/src/port/ui/SceneExplorer.cpp b/src/port/ui/SceneExplorer.cpp index 11affa50e..a6526ca22 100644 --- a/src/port/ui/SceneExplorer.cpp +++ b/src/port/ui/SceneExplorer.cpp @@ -18,7 +18,7 @@ extern "C" { #include "actors.h" } -namespace Editor { +namespace TrackEditor { SceneExplorerWindow::~SceneExplorerWindow() { SPDLOG_TRACE("destruct scene explorer window"); diff --git a/src/port/ui/SceneExplorer.h b/src/port/ui/SceneExplorer.h index f9e926148..69ee476e7 100644 --- a/src/port/ui/SceneExplorer.h +++ b/src/port/ui/SceneExplorer.h @@ -4,7 +4,7 @@ #include "port/Game.h" -namespace Editor { +namespace TrackEditor { class SceneExplorerWindow : public Ship::GuiWindow { public: using Ship::GuiWindow::GuiWindow; diff --git a/src/port/ui/Tools.cpp b/src/port/ui/Tools.cpp index 75dd3ac10..531a1c773 100644 --- a/src/port/ui/Tools.cpp +++ b/src/port/ui/Tools.cpp @@ -12,13 +12,14 @@ #include <defines.h> #include "port/Game.h" #include "engine/editor/SceneManager.h" +#include "engine/TrackBrowser.h" extern "C" { #include "code_800029B0.h" #include "code_80057C60.h" } -namespace Editor { +namespace TrackEditor { ToolsWindow::~ToolsWindow() { SPDLOG_TRACE("destruct tools window"); @@ -37,6 +38,7 @@ namespace Editor { if (ImGui::Button(ICON_FA_FLOPPY_O, ImVec2(50, 25))) { if (gEditor.IsPaused()) { SaveLevel(GetWorld()->GetTrack(), gTrackRegistry.GetInfo(GetWorld()->GetTrack()->ResourceName)); + TrackBrowser::Instance->Refresh(gTrackRegistry); } else { printf("[Editor] Cannot save during simulation\n Please switch back to edit mode!\n\n"); } @@ -140,7 +142,8 @@ namespace Editor { ImGui::PushStyleColor(ImGuiCol_Button, defaultColor); if (ImGui::Button(gEditor.IsPaused() ? ICON_FA_PLAY : ICON_FA_STOP, ImVec2(50, 25))) { if (gEditor.IsPaused()) { - SaveLevel(GetWorld()->GetTrack(), gTrackRegistry.GetInfo(GetWorld()->GetTrack()->ResourceName)); + SaveLevel(GetWorld()->GetTrack(), gTrackRegistry.GetInfo(GetWorld()->GetTrack()->ResourceName)); + TrackBrowser::Instance->Refresh(gTrackRegistry); CVarSetInteger("gFreecam", false); CM_SetFreeCamera(false); } else { diff --git a/src/port/ui/Tools.h b/src/port/ui/Tools.h index 7ef3450a7..12bd58adc 100644 --- a/src/port/ui/Tools.h +++ b/src/port/ui/Tools.h @@ -2,7 +2,7 @@ #include <libultraship/libultraship.h> -namespace Editor { +namespace TrackEditor { class ToolsWindow : public Ship::GuiWindow { public: using Ship::GuiWindow::GuiWindow; diff --git a/src/port/ui/TrackProperties.cpp b/src/port/ui/TrackProperties.cpp index 3f95de411..d3ef44ad4 100644 --- a/src/port/ui/TrackProperties.cpp +++ b/src/port/ui/TrackProperties.cpp @@ -14,6 +14,9 @@ #include "port/Game.h" #include "engine/cameras/TourCamera.h" +#include "engine/TrackBrowser.h" +#include "engine/editor/SceneManager.h" +#include "engine/Registry.h" extern "C" { #include "code_800029B0.h" @@ -23,26 +26,23 @@ extern "C" { #include "render_objects.h" } -namespace Editor { +namespace TrackEditor { TrackPropertiesWindow::~TrackPropertiesWindow() { SPDLOG_TRACE("destruct track properties window"); } void TrackPropertiesWindow::DrawElement() { - static char idBuffer[256] = "mk:mario_raceway"; - static char nameBuffer[256] = "Mario Raceway"; - static char debugNameBuffer[256] = "m circuit"; - static char lengthBuffer[256] = "567m"; - if (nullptr == GetWorld()->GetTrack()) { return; } - ImGui::InputText("ID", idBuffer, IM_ARRAYSIZE(idBuffer)); - ImGui::InputText("Name", GetWorld()->GetTrack()->Props.Name, IM_ARRAYSIZE(nameBuffer)); - ImGui::InputText("Debug Name", GetWorld()->GetTrack()->Props.DebugName, IM_ARRAYSIZE(debugNameBuffer)); - ImGui::InputText("Track Length", GetWorld()->GetTrack()->Props.TrackLength, IM_ARRAYSIZE(lengthBuffer)); + if (ImGui::Button("Edit TrackInfo")) { + ImGui::OpenPopup("Edit TrackInfo"); + } + + DrawResourceNameEdit(); + ImGui::InputFloat("Water Level", &GetWorld()->GetTrack()->Props.WaterLevel); if (ImGui::CollapsingHeader("Camera")) { @@ -175,6 +175,99 @@ namespace Editor { TrackPropertiesWindow::DrawTourCamera(); } + void TrackPropertiesWindow::DrawResourceNameEdit() { + Track* track = GetWorld()->GetTrack(); + if (!track) { + return; + } + + static char resourceNameBuffer[128] = {}; + static char nameBuffer[128] = "blank_track"; + static char debugNameBuffer[128] = "blanktrack"; + static char lengthBuffer[128] = "100m"; + static bool initialized = false; + static std::string oldResourceName = track->ResourceName; + + // Auto-sizing fills the height of the screen for a single frame. + // Because there's no content in the window in the first frame. + // This forces the window size to prevent that + ImGui::SetNextWindowSize(ImVec2(400, 275), ImGuiCond_Always); + if (ImGui::BeginPopupModal("Edit TrackInfo", nullptr, + ImGuiWindowFlags_AlwaysAutoResize)) { + + // Initialize once per popup open + if (!initialized) { + strncpy(resourceNameBuffer, track->ResourceName.c_str(), sizeof(resourceNameBuffer)); + resourceNameBuffer[sizeof(resourceNameBuffer) - 1] = '\0'; + oldResourceName = track->ResourceName; + initialized = true; + } + + ImGui::TextWrapped( + "Changing these fields will:\n" + "- Save the current track\n" + "- Reload the track\n" + "- Update the registry\n\n" + ); + + gEditor.Pause(); + + ImGui::Spacing(); + ImGui::Separator(); + ImGui::Spacing(); + + ImGui::InputText("ResourceName", resourceNameBuffer, IM_ARRAYSIZE(resourceNameBuffer)); + ImGui::InputText("Name", GetWorld()->GetTrack()->Props.Name, IM_ARRAYSIZE(nameBuffer)); + ImGui::InputText("Debug Name", GetWorld()->GetTrack()->Props.DebugName, IM_ARRAYSIZE(debugNameBuffer)); + ImGui::InputText("Track Length", GetWorld()->GetTrack()->Props.TrackLength, IM_ARRAYSIZE(lengthBuffer)); + + ImGui::Spacing(); + ImGui::Separator(); + ImGui::Spacing(); + + bool cancel = ImGui::Button("Cancel", ImVec2(120, 0)); + + ImGui::SameLine(); + + bool confirm = ImGui::Button("Confirm", ImVec2(120, 0)); + + if (confirm) { + if (oldResourceName != resourceNameBuffer) { + track->ResourceName = resourceNameBuffer; + const TrackInfo* oldInfo = gTrackRegistry.GetInfo(oldResourceName); + TrackInfo info; + info.ResourceName = track->ResourceName; + info.Name = track->Props.Name; + info.DebugName = track->Props.DebugName; + info.Path = oldInfo->Path; + + TrackEditor::SaveLevel(track, static_cast<const TrackInfo*>(&info)); + auto archive = track->Archive; + gTrackRegistry.Remove(oldResourceName); + gTrackRegistry.Add(info, [info, archive]() { + auto track = std::make_unique<Track>(); + track->Archive = archive; + track->ResourceName = info.ResourceName; + GetWorld()->SetCurrentTrack(std::move(track)); + }); + TrackBrowser::Instance->Refresh(gTrackRegistry); + gGotoMode = RACING; + + } + initialized = false; + + ImGui::CloseCurrentPopup(); + } + + if (cancel) { + initialized = false; + ImGui::CloseCurrentPopup(); + } + + ImGui::EndPopup(); + } + } + void TrackPropertiesWindow::DrawMusic() { const char* items[] = { "None", "Title Screen", "Main Menu", "Wario Stadium", "Moo Moo Farm", diff --git a/src/port/ui/TrackProperties.h b/src/port/ui/TrackProperties.h index a3c151b32..d08560bf9 100644 --- a/src/port/ui/TrackProperties.h +++ b/src/port/ui/TrackProperties.h @@ -6,7 +6,7 @@ extern "C" { #include "sounds.h" } -namespace Editor { +namespace TrackEditor { class TrackPropertiesWindow : public Ship::GuiWindow { public: using Ship::GuiWindow::GuiWindow; @@ -15,6 +15,7 @@ public: protected: void InitElement() override {}; void DrawElement() override; + void DrawResourceNameEdit(); void DrawMusic(); void DrawFog(); void DrawLight(); |
