summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-03-21 20:54:14 -0400
committerJonathan Bradley <jcb@pikum.xyz>2025-03-21 21:40:21 -0400
commit677a3cbec2f7908ee0897b97d508a6bd66a0a344 (patch)
treefc88b21dd61dbb10dd8b5c8aef73702d15514f00 /editor
parentcae76dd98e301a4560bb46ecb59b5952dff04149 (diff)
pke: first-pass level is a collection of scenes
Diffstat (limited to 'editor')
-rw-r--r--editor/editor.cpp110
1 files changed, 73 insertions, 37 deletions
diff --git a/editor/editor.cpp b/editor/editor.cpp
index 685d402..2de4772 100644
--- a/editor/editor.cpp
+++ b/editor/editor.cpp
@@ -17,6 +17,7 @@
#include "player-input.hpp"
#include "plugins.hpp"
#include "project.hpp"
+#include "scene.hpp"
#include "static-ui.hpp"
#include "thread-pool.hpp"
#include "vendor-glm-include.hpp"
@@ -53,6 +54,14 @@ const char* const dbgCtrl_ClearSelection = "debug-clear-selection";
const char* const dbgCtrl_DeleteSelectedItem = "debug-delete-selected-item";
const char* const dbgCtrl_ImGui_Toggle = "debug-imgui-toggle";
+// TODO editor state (scene vs level)
+struct editor_master {
+ pke_scene *active_scene;
+ pk_str target_scene_name;
+ bool shouldLoadScene = false;
+ bool shouldSaveScene = false;
+} editor_mstr;
+
ThreadPoolHandle threadPoolHandle = ThreadPoolHandle_MAX;
InputActionSetHandle debugControlsHandle = InputActionSetHandle_MAX;
@@ -104,7 +113,7 @@ void PkeEditor_Tick(double delta) {
"pke-runtime",
"--plugin", pkeSettings.args.pluginPath == nullptr ? "libpke-example.o" : pkeSettings.args.pluginPath,
"--project", pkeSettings.args.projectPath == nullptr ? PKE_PROJ_DEFAULT_FILENAME : pkeSettings.args.projectPath,
- "--scene", pkeSettings.rt.sceneName == nullptr ? PKE_PROJ_DEFAULT_FILENAME : pkeSettings.rt.sceneName,
+ "--scene", (editor_mstr.active_scene != nullptr && editor_mstr.active_scene->name[0] != '\0') ? editor_mstr.active_scene->name : PKE_PROJ_DEFAULT_FILENAME ,
NULL,
};
status = execvp("pke-runtime", const_cast<char **>(argv));
@@ -130,12 +139,12 @@ void PkeEditor_Tick(double delta) {
}
if (shouldOpenNewScene) {
shouldOpenNewScene = false;
- // queues unloading
- pkeSettings.rt.previousLevel = pkeSettings.rt.activeLevel;
- // bypasses loading a level by setting a new active one
- pkeSettings.rt.activeLevel = PkeLevel_Create("editorLevel");
- pkeSettings.rt.sceneName = newSceneName;
+ if (editor_mstr.active_scene != nullptr) {
+ pke_scene_remove(editor_mstr.active_scene->scene_handle);
+ }
ActiveCamera = &NullCamera;
+ editor_mstr.active_scene = pke_scene_create(newSceneName);
+ return;
}
if (shouldSaveProjectFile) {
shouldSaveProjectFile = false;
@@ -147,33 +156,52 @@ void PkeEditor_Tick(double delta) {
new (task) std::packaged_task<void()>( [] {
const char * patterns[1] = {"*.pstf"};
char *selectedScene = tinyfd_openFileDialog(nullptr, "cafebabe.pstf", 1, patterns, "Pke Scene Text File", 0);
- if (selectedScene != nullptr) {
- pkeSettings.rt.sceneName = selectedScene;
- pkeSettings.rt.shouldLoadScene = true;
- ActiveCamera = &NullCamera;
+ if (editor_mstr.active_scene != nullptr) {
+ pke_scene_remove(editor_mstr.active_scene->scene_handle);
}
+ ActiveCamera = &NullCamera;
+ editor_mstr.active_scene = pke_scene_create(selectedScene);
+ return;
});
PkeThreads_Enqueue(threadPoolHandle, task);
}
if (shouldOpenSaveSceneDialog) {
+ assert(editor_mstr.active_scene != nullptr);
shouldOpenSaveSceneDialog = false;
auto *task = pk_new<std::packaged_task<void()>>();
new (task) std::packaged_task<void()>( [] {
const char * patterns[1] = {"*.pstf"};
- char *selectedScene = tinyfd_saveFileDialog(nullptr, pkeSettings.rt.sceneName, 1, patterns, "Pke Scene Text File");
+ char *selectedScene = tinyfd_saveFileDialog(nullptr, editor_mstr.active_scene->file_path.val, 1, patterns, "Pke Scene Text File");
if (selectedScene != nullptr) {
- pkeSettings.rt.sceneName = selectedScene;
- pkeSettings.rt.shouldSaveScene = true;
+ if (editor_mstr.active_scene->file_path.reserved > 0) {
+ pk_delete<char>(editor_mstr.active_scene->file_path.val, editor_mstr.active_scene->file_path.reserved);
+ }
+ editor_mstr.active_scene->file_path.length = strlen(selectedScene);
+ editor_mstr.active_scene->file_path.reserved = editor_mstr.active_scene->file_path.length + 1;
+ editor_mstr.active_scene->file_path.val = pk_new<char>(editor_mstr.active_scene->file_path.reserved);
+ strcpy(editor_mstr.active_scene->file_path.val, selectedScene);
+ editor_mstr.shouldSaveScene = true;
}
});
PkeThreads_Enqueue(threadPoolHandle, task);
}
- if (pkeSettings.rt.shouldSaveScene && pkeSettings.rt.sceneName) {
- pkeSettings.rt.shouldSaveScene = false;
- Game_SaveSceneFile(pkeSettings.rt.sceneName);
+ if (editor_mstr.shouldSaveScene && editor_mstr.active_scene->file_path.val) {
+ editor_mstr.shouldSaveScene = false;
+ Game_SaveSceneFile(editor_mstr.active_scene->file_path.val);
shouldRebuildProjectDir = true;
}
+ if (editor_mstr.target_scene_name.val != nullptr) {
+ if (editor_mstr.active_scene != nullptr) {
+ pke_scene_remove(editor_mstr.active_scene->scene_handle);
+ }
+ ActiveCamera = &NullCamera;
+ Game_LoadSceneFile(editor_mstr.target_scene_name.val);
+ editor_mstr.active_scene = pke_scene_get_by_name(editor_mstr.target_scene_name.val);
+ pk_delete<char>(editor_mstr.target_scene_name.val, editor_mstr.target_scene_name.reserved);
+ editor_mstr.target_scene_name = {};
+ return;
+ }
if (selectedEntity && EntitiesToBeRemoved.Has(ECS_GetEntity(selectedEntity->entHandle))) {
selectedEntity = nullptr;
@@ -608,26 +636,28 @@ void RecordImGuiEditorWrapper() {
* - the goal is not to prevent a specific scene name,
* I just want to know if they clicked the "New Scene" button
*/
- ImGui::BeginDisabled(pkeSettings.rt.sceneName == newSceneName);
+ ImGui::BeginDisabled(editor_mstr.active_scene && editor_mstr.active_scene->name == newSceneName);
if (ImGui::MenuItem("Save")) {
shouldSaveProjectFile = true;
- pkeSettings.rt.shouldSaveScene = true;
+ editor_mstr.shouldSaveScene = true;
}
- if (pkeSettings.rt.sceneName) {
+ if (editor_mstr.active_scene != nullptr) {
ImGui::SameLine();
int offset = 0;
- const auto *slash = strrchr(pkeSettings.rt.sceneName, '\\');
- slash = slash != nullptr ? slash : strrchr(pkeSettings.rt.sceneName, '/');
+ const auto *slash = strrchr(editor_mstr.active_scene->name, '\\');
+ slash = slash != nullptr ? slash : strrchr(editor_mstr.active_scene->name, '/');
if (slash != nullptr) {
- offset = slash - pkeSettings.rt.sceneName;
+ offset = slash - editor_mstr.active_scene->name;
}
- ImGui::Text("%s", pkeSettings.rt.sceneName + offset);
+ ImGui::Text("%s", editor_mstr.active_scene->name + offset);
}
ImGui::EndDisabled();
+
if (ImGui::MenuItem("Save As...")) {
shouldSaveProjectFile = true;
shouldOpenSaveSceneDialog = true;
}
+
if (ImGui::MenuItem("Exit")) {
glfwSetWindowShouldClose(window, true);
}
@@ -1075,7 +1105,7 @@ void RecordImGuiCameras() {
cam.type = ActiveCamera->type;
cam.view = ActiveCamera->view;
cam.isPrimary = false;
- PkeLevel_RegisterCamera(pkeSettings.rt.activeLevel, cam.camHandle);
+ pke_scene_register_camera(editor_mstr.active_scene->scene_handle, cam.camHandle);
}
static ImGuiTableFlags tableFlags{
@@ -1337,18 +1367,20 @@ void RecordImGuiLevels() {
if (ImGui::BeginTable("PkeLevels", 3, tableFlags)) {
ImGui::TableSetupColumn("Name");
ImGui::TableSetupColumn("Handle");
- ImGui::TableSetupColumn("CameraCount");
ImGui::TableHeadersRow();
- for (long i = 0; i < MAX_LEVEL_COUNT; ++i) {
- if (LEVELS[i].levelHandle == LevelHandle_MAX)
- continue;
- ImGui::TableNextRow();
- ImGui::TableSetColumnIndex(0);
- ImGui::Text("%s", LEVELS[i].name);
- ImGui::TableSetColumnIndex(1);
- ImGui::Text("0x%04hx", static_cast<unsigned short>(LEVELS[i].levelHandle));
- ImGui::TableSetColumnIndex(2);
- ImGui::Text("%u", LEVELS[i].cameras.next - 1);
+ pk_handle_bucket_index_T b, bb;
+ pk_handle_item_index_T i, ii;
+ PkeLevel *lvls;
+ bb = pke_level_get_bucket_count();
+ for (b = 0; b < bb; ++b) {
+ lvls = pke_level_get_levels(b, &ii);
+ for (i = 0; i < ii; ++i) {
+ ImGui::TableNextRow();
+ ImGui::TableSetColumnIndex(0);
+ ImGui::Text("%s", lvls[i].name);
+ ImGui::TableSetColumnIndex(1);
+ ImGui::Text("0x%08X 0x%08X", b, i);
+ }
}
ImGui::EndTable();
}
@@ -1574,8 +1606,11 @@ void BuildDirRecursive(const std::filesystem::directory_entry &de, fsEntry *dirF
void BuildProjectMenuRecursive(fsEntry &entry) {
if (entry.type == 1) {
if (ImGui::Selectable(entry.name, false, ImGuiSelectableFlags_AllowDoubleClick) && ImGui::IsMouseDoubleClicked(0)) {
- pkeSettings.rt.sceneName = entry.name;
- pkeSettings.rt.shouldLoadScene = true;
+ assert(editor_mstr.target_scene_name.val == nullptr);
+ editor_mstr.target_scene_name.length = strlen(entry.name);
+ editor_mstr.target_scene_name.reserved = editor_mstr.target_scene_name.length + 1;
+ editor_mstr.target_scene_name.val = pk_new<char>(editor_mstr.target_scene_name.reserved);
+ strcpy(editor_mstr.target_scene_name.val, entry.name);
ActiveCamera = &NullCamera;
}
} else if (entry.type == 0) {
@@ -1626,6 +1661,7 @@ void RecordImGuiSceneBrowser() {
for (i = 0; i < bucketCount; ++i) {
instances = ECS_GetInstances(0, itemCount);
for (k = 0; k < itemCount; ++k) {
+ if (instances[k].instanceHandle == InstanceHandle_MAX) continue;
entType = EntityType_FindByEntityHandle(instances[k].entHandle);
sprintf(text, "%s: %08x %08x", entType != nullptr ? entType->entityTypeCode.val : "(no type)", instances[k].instanceHandle.bucketIndex, instances[k].instanceHandle.itemIndex);
if (ImGui::Button(text)) {