summaryrefslogtreecommitdiff
path: root/src/engine/editor/SceneManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/editor/SceneManager.cpp')
-rw-r--r--src/engine/editor/SceneManager.cpp179
1 files changed, 132 insertions, 47 deletions
diff --git a/src/engine/editor/SceneManager.cpp b/src/engine/editor/SceneManager.cpp
index 0165f5c81..135079a57 100644
--- a/src/engine/editor/SceneManager.cpp
+++ b/src/engine/editor/SceneManager.cpp
@@ -7,6 +7,7 @@
#include <iostream>
#include <fstream>
+#include <memory>
#include <optional> // Must be before json.hpp
#include <nlohmann/json.hpp>
#include "port/Engine.h"
@@ -21,28 +22,23 @@
#include "engine/objects/Thwomp.h"
#include "engine/objects/Snowman.h"
#include "engine/cameras/TourCamera.h"
+#include "port/resource/type/TrackPathPointData.h"
extern "C" {
#include "common_structs.h"
#include "actors.h"
#include "actor_types.h"
+#include "code_80005FD0.h"
}
namespace Editor {
- std::shared_ptr<Ship::Archive> CurrentArchive;
- std::string SceneFile = "";
-
- void SaveLevel() {
- if ((!CurrentArchive) || (SceneFile.empty())) {
- SPDLOG_INFO("[SceneManager] [SaveLevel] Could not save scene file, SceneFile or CurrentArchive not set");
- return;
- }
+ void SaveLevel(Track* track) {
nlohmann::json data;
/**
* Save track properties, static mesh actors, actors, and tour camera
*/
- data["Props"] = gWorldInstance.GetTrack()->Props.to_json();
+ data["Props"] = track->Props.to_json();
nlohmann::json staticMesh;
SaveStaticMeshActors(staticMesh);
@@ -54,12 +50,17 @@ namespace Editor {
data["Actors"] = actors;
- if (gWorldInstance.GetTrack()->TourShots.size() != 0) {
+ if (track->TourShots.size() != 0) {
nlohmann::json tour;
- SaveTour(tour);
+ SaveTour(track, tour);
data["Tour"] = tour;
}
+ if (nullptr == track->Archive) {
+ SPDLOG_INFO("[SceneManager] [SaveLevel] Track archive nullptr");
+ return;
+ }
+
/**
* Write data to file
*/
@@ -68,11 +69,14 @@ namespace Editor {
std::vector<uint8_t> bytes; // Turn the str into raw data
bytes.assign(jsonStr.begin(), jsonStr.end());
+ const TrackInfo* info = gTrackRegistry.GetInfo(track->ResourceName);
+ std::string sceneFile = info->Path + "/scene.json";
+
// Write file to disk
- bool wrote = GameEngine::Instance->context->GetResourceManager()->GetArchiveManager()->WriteFile(CurrentArchive, SceneFile, bytes);
+ bool wrote = GameEngine::Instance->context->GetResourceManager()->GetArchiveManager()->WriteFile(track->Archive, sceneFile, bytes);
if (wrote) {
// Tell the cache this file needs to be reloaded
- auto resource = GameEngine::Instance->context->GetResourceManager()->GetCachedResource(SceneFile);
+ auto resource = GameEngine::Instance->context->GetResourceManager()->GetCachedResource(sceneFile);
if (resource) {
resource->Dirty();
}
@@ -84,11 +88,18 @@ namespace Editor {
}
}
- /** Do not use gWorldInstance.CurrentCourse during loading! The current track is not guaranteed! **/
- void LoadLevel(Track* track, std::string sceneFile) {
- SceneFile = sceneFile;
- if ((nullptr == track) || (nullptr == track->RootArchive)) {
- SPDLOG_INFO("[SceneManager] [LoadLevel] Failed to load scenefile, track or rootarchive were null");
+ /** Do not use GetWorld()->CurrentCourse during loading! The current track is not guaranteed! **/
+ void LoadTrackDataFromJson(Track* track, const std::string& trackPath) {
+ SPDLOG_INFO("[SceneManager] [LoadTrackDataFromJson] Loading track scenefile...");
+
+ if (trackPath.empty()) {
+ SPDLOG_INFO(" Unable to load track. trackPath empty.");
+ return;
+ }
+
+ std::string sceneFile = trackPath + "/scene.json";
+ if ((nullptr == track) || (nullptr == track->Archive)) {
+ SPDLOG_INFO(" Failed to load scenefile, track or archive were null");
return;
}
@@ -97,7 +108,7 @@ namespace Editor {
* the init data needs to be manually populated
*/
auto initData = std::make_shared<Ship::ResourceInitData>();
- initData->Parent = track->RootArchive;
+ initData->Parent = track->Archive;
initData->Format = RESOURCE_FORMAT_BINARY;
initData->ByteOrder = Ship::Endianness::Little;
initData->Type = static_cast<uint32_t>(Ship::ResourceType::Json);
@@ -109,56 +120,80 @@ namespace Editor {
// Check that the data is valid
if (data.is_null() || !data.is_object() || data.empty()) {
- SPDLOG_INFO("[SceneManager] [LoadLevel] Scenefile corrupted or contained no data");
+ SPDLOG_INFO(" Scenefile corrupted or contained no data");
return;
}
- SPDLOG_INFO("[SceneManager] [LoadLevel] Loading track scenefile...");
+ SPDLOG_INFO(" Loading Props, Actors, Static Mesh Actors, and Tour...");
// Load the Props, and populate actors
LoadProps(track, data);
+ LoadPaths(track, trackPath);
+ LoadMinimap(track, trackPath);
LoadActors(track, data);
LoadStaticMeshActors(track, data);
LoadTour(track, data);
- SPDLOG_INFO("[SceneManager] [LoadLevel] Scene File Loaded!");
+ SPDLOG_INFO("[SceneManager] [LoadTrackDataFromJson] Scene File Loaded!");
+ }
+
+ void LoadTrackInfo(TrackInfo& info, std::shared_ptr<Ship::Archive> archive, std::string sceneFile) {
+ if (nullptr == archive) {
+ SPDLOG_INFO("[SceneManager] [LoadTrackDataFromJson] Failed to load scenefile, track or rootarchive were null");
+ return;
+ }
+
+ /*
+ * Manually loading a custom asset file (scene.json) with no extractor class means that
+ * the init data needs to be manually populated
+ */
+ auto initData = std::make_shared<Ship::ResourceInitData>();
+ initData->Parent = archive;
+ initData->Format = RESOURCE_FORMAT_BINARY;
+ initData->ByteOrder = Ship::Endianness::Little;
+ initData->Type = static_cast<uint32_t>(Ship::ResourceType::Json);
+ initData->ResourceVersion = 0;
+
+ // Load the scene file and return the json data
+ nlohmann::json data = std::static_pointer_cast<Ship::Json>(
+ GameEngine::Instance->context->GetResourceManager()->LoadResource(sceneFile, true, initData))->Data;
+
+ // Check that the data is valid
+ if (data.is_null() || !data.is_object() || data.empty()) {
+ SPDLOG_INFO("[SceneManager] [LoadTrackInfo] Scenefile corrupted or contained no data");
+ return;
+ }
+
+ LoadTrackInfoData(info, data);
+
+ SPDLOG_INFO("[SceneManager] [LoadTrackInfo] Loaded track info!");
}
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();
+ GetWorld()->StaticMeshActors.push_back(std::make_unique<StaticMeshActor>("", FVector(0, 0, 0), IRotator(0, 0, 0), FVector(1, 1, 1), "", nullptr));
+ auto& actor = GetWorld()->StaticMeshActors.back();
actor->from_json(actorJson);
printf("After from_json: Pos(%f, %f, %f), Name: %s, Model: %s\n",
actor->Pos.x, actor->Pos.y, actor->Pos.z, actor->Name.c_str(), actor->Model.c_str());
}
- void SetSceneFile(std::shared_ptr<Ship::Archive> archive, std::string sceneFile) {
- CurrentArchive = archive;
- SceneFile = sceneFile;
- }
-
- // Called from ContentBrowser.cpp
void LoadMinimap(Track* track, std::string filePath) {
+ std::string minimapPath = filePath + "/minimap.png";
SPDLOG_INFO(" Loading {} minimap...", filePath);
- if (nullptr == track->RootArchive) {
- SPDLOG_INFO("[SceneManager] [LoadMinimap] Root archive is nullptr");
- SetDefaultMinimap(track);
- return;
- }
/*
* Manually loading a custom asset file with no extractor class means that
* the init data needs to be manually populated
*/
auto initData = std::make_shared<Ship::ResourceInitData>();
- initData->Parent = track->RootArchive;
+ initData->Parent = track->Archive;
initData->Format = RESOURCE_FORMAT_BINARY;
initData->ByteOrder = Ship::Endianness::Little;
initData->Type = static_cast<uint32_t>(MK64::ResourceType::Minimap);
initData->ResourceVersion = 0;
std::shared_ptr<MK64::Minimap> ptr = std::static_pointer_cast<MK64::Minimap>(
- GameEngine::Instance->context->GetResourceManager()->LoadResource(filePath, true, initData));
+ GameEngine::Instance->context->GetResourceManager()->LoadResource(minimapPath, true, initData));
if (ptr) {
SPDLOG_INFO(" Minimap Loaded!");
@@ -180,7 +215,7 @@ namespace Editor {
}
void SaveActors(nlohmann::json& actorList) {
- for (const auto& actor : gWorldInstance.Actors) {
+ for (const auto& actor : GetWorld()->Actors) {
SpawnParams params{};
bool alreadyProcessed = false;
@@ -234,7 +269,7 @@ namespace Editor {
}
}
- for (const auto& object : gWorldInstance.Objects) {
+ for (const auto& object : GetWorld()->Objects) {
SpawnParams params;
object->SetSpawnParams(params);
@@ -247,17 +282,17 @@ namespace Editor {
}
void SaveStaticMeshActors(nlohmann::json& actorList) {
- for (const auto& mesh : gWorldInstance.StaticMeshActors) {
+ for (const auto& mesh : GetWorld()->StaticMeshActors) {
actorList.push_back(mesh->to_json());
}
}
- void SaveTour(nlohmann::json& tour) {
- tour["Enabled"] = gWorldInstance.GetTrack()->bTourEnabled;
+ void SaveTour(Track* track, nlohmann::json& tour) {
+ tour["Enabled"] = track->bTourEnabled;
// Camera shots
tour["Shots"] = nlohmann::json::array();
- for (const auto& shot : gWorldInstance.GetTrack()->TourShots) {
+ for (const auto& shot : track->TourShots) {
tour["Shots"].push_back(ToJson(shot));
}
}
@@ -276,8 +311,58 @@ namespace Editor {
}
}
+ void LoadPaths(Track* track, const std::string& trackPath) {
+ std::string path_file = (trackPath + "/data_paths").c_str();
+
+ auto res = std::dynamic_pointer_cast<MK64::Paths>(ResourceLoad(path_file.c_str()));
+
+ if (res != nullptr) {
+ auto& paths = res->PathList;
+
+ size_t i = 0;
+ u16* ptr = &track->Props.PathSizes.unk0;
+ for (auto& path : paths) {
+ if (i >= ARRAY_COUNT(track->Props.PathTable2)) {
+ printf("[Track.cpp] The game can only import 5 paths. Found more than 5. Skipping the rest\n");
+ break; // Only 5 paths allowed. 4 track, 1 vehicle
+ }
+ ptr[i] = path.size();
+ track->Props.PathTable2[i] = (TrackPathPoint*) path.data();
+
+ i += 1;
+ }
+ }
+ gVehiclePathSize = track->Props.PathSizes.unk0; // This is likely incorrect.
+ }
+
+ void LoadTrackInfoData(TrackInfo& info, nlohmann::json& data) {
+ if (!data.contains("Props") || !data["Props"].is_object()) {
+ SPDLOG_INFO("[SceneManager] [LoadTrackInfoData] Track is missing props data. Is the scene.json file corrupt?");
+ return;
+ }
+
+ try {
+ nlohmann::json& j = data.at("Props");
+
+ info.ResourceName = j.at("ResourceName").get<std::string>();
+ info.Name = j.at("Name").get<std::string>();
+ info.DebugName = j.at("DebugName").get<std::string>();
+ info.Length = j.at("TrackLength").get<std::string>();
+
+ printf("[SceneManager] [LoadTrackInfoData] ResourceName: %s, Name: %s, DebugName: %s, Length: %s\n",
+ info.ResourceName.c_str(),
+ info.Name.c_str(),
+ info.DebugName.c_str(),
+ info.Length.c_str()
+ );
+ } 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;
+ }
+ }
+
void LoadActors(Track* track, nlohmann::json& data) {
- if (!data.contains("Actors") || !data["Actors"].is_object()) {
+ if (!data.contains("Actors") || !data["Actors"].is_array()) {
SPDLOG_INFO(" This track contains no actors");
return;
}
@@ -294,12 +379,12 @@ namespace Editor {
}
void LoadStaticMeshActors(Track* track, nlohmann::json& data) {
- if (!data.contains("StaticMeshActors") || !data["StaticMeshActors"].is_object()) {
+ if (!data.contains("StaticMeshActors") || !data["StaticMeshActors"].is_array()) {
SPDLOG_INFO(" This track contains no StaticMeshActors!");
return;
}
- gWorldInstance.StaticMeshActors.clear(); // Clear existing actors, if any
+ GetWorld()->StaticMeshActors.clear(); // Clear existing actors, if any
for (const auto& actorJson : data["StaticMeshActors"]) {
Load_AddStaticMeshActor(actorJson);
@@ -308,7 +393,7 @@ namespace Editor {
void LoadTour(Track* track, nlohmann::json& data) {
if (!data.contains("Tour") || !data["Tour"].is_object()) {
- SPDLOG_INFO(" This track does not contain a camera tour");
+ SPDLOG_INFO(" This track does not contain a camera tour");
return;
}