summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/engine/Actor.cpp2
-rw-r--r--src/engine/RegisterContent.cpp2
-rw-r--r--src/engine/Registry.h11
-rw-r--r--src/engine/TrackBrowser.cpp101
-rw-r--r--src/engine/actors/Cloud.cpp2
-rw-r--r--src/engine/actors/Finishline.cpp2
-rw-r--r--src/engine/actors/Ship.cpp2
-rw-r--r--src/engine/actors/Starship.cpp2
-rw-r--r--src/engine/editor/Collision.cpp2
-rw-r--r--src/engine/editor/Collision.h2
-rw-r--r--src/engine/editor/Editor.cpp2
-rw-r--r--src/engine/editor/Editor.h4
-rw-r--r--src/engine/editor/GameObject.cpp4
-rw-r--r--src/engine/editor/GameObject.h2
-rw-r--r--src/engine/editor/Gizmo.cpp2
-rw-r--r--src/engine/editor/Gizmo.h2
-rw-r--r--src/engine/editor/Handles.cpp2
-rw-r--r--src/engine/editor/Handles.h2
-rw-r--r--src/engine/editor/Light.cpp2
-rw-r--r--src/engine/editor/Light.h2
-rw-r--r--src/engine/editor/ObjectPicker.cpp4
-rw-r--r--src/engine/editor/ObjectPicker.h2
-rw-r--r--src/engine/editor/SceneManager.cpp4
-rw-r--r--src/engine/editor/SceneManager.h2
-rw-r--r--src/engine/tracks/TestTrack.cpp2
-rw-r--r--src/engine/tracks/Track.cpp9
-rw-r--r--src/engine/tracks/Track.h10
-rw-r--r--src/menus.c2
-rw-r--r--src/port/Game.cpp4
-rw-r--r--src/port/Game.h2
-rw-r--r--src/port/ui/ContentBrowser.cpp2
-rw-r--r--src/port/ui/ContentBrowser.h2
-rw-r--r--src/port/ui/ImguiUI.cpp10
-rw-r--r--src/port/ui/Properties.cpp2
-rw-r--r--src/port/ui/Properties.h2
-rw-r--r--src/port/ui/SceneExplorer.cpp2
-rw-r--r--src/port/ui/SceneExplorer.h2
-rw-r--r--src/port/ui/Tools.cpp7
-rw-r--r--src/port/ui/Tools.h2
-rw-r--r--src/port/ui/TrackProperties.cpp113
-rw-r--r--src/port/ui/TrackProperties.h3
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();