From 62230fbe5c7a965e3b0a9750d20b7633895be1a3 Mon Sep 17 00:00:00 2001 From: scawful Date: Mon, 29 Sep 2025 20:23:17 -0400 Subject: [PATCH] Remove Windows ARM64 build configuration and delete unused generate-vs-projects.py script - Removed the Windows ARM64 configuration from the GitHub Actions release workflow to streamline the build process. - Deleted the generate-vs-projects.py script as it was no longer needed for project setup, simplifying the codebase. - Updated the OverworldEditor header to improve clarity by renaming a method parameter for better understanding. - Refactored the Emulator class to enhance the rendering interface, improving the user experience in the emulator's GUI. --- .github/workflows/release.yml | 6 - scripts/generate-vs-projects.py | 543 ----------------- src/app/editor/overworld/overworld_editor.h | 2 +- src/app/emu/emulator.cc | 95 ++- src/app/emu/emulator.h | 73 +-- src/app/gui/gui.cmake | 1 - src/app/gui/zeml.cc | 621 -------------------- src/app/gui/zeml.h | 205 ------- src/app/zelda3/hyrule_magic.h | 5 - src/lib/asar | 2 +- src/lib/imgui | 2 +- 11 files changed, 88 insertions(+), 1467 deletions(-) delete mode 100644 scripts/generate-vs-projects.py delete mode 100644 src/app/gui/zeml.cc delete mode 100644 src/app/gui/zeml.h diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7bb5d378..548e6100 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -115,12 +115,6 @@ jobs: cmake_generator: "Visual Studio 17 2022" cmake_generator_platform: x64 artifact_name: "yaze-windows-x64" - - name: "Windows ARM64" - os: windows-2022 - vcpkg_triplet: arm64-windows - cmake_generator: "Visual Studio 17 2022" - cmake_generator_platform: ARM64 - artifact_name: "yaze-windows-arm64" - name: "macOS arm64" os: macos-14 vcpkg_triplet: arm64-osx diff --git a/scripts/generate-vs-projects.py b/scripts/generate-vs-projects.py deleted file mode 100644 index 65539729..00000000 --- a/scripts/generate-vs-projects.py +++ /dev/null @@ -1,543 +0,0 @@ -#!/usr/bin/env python3 -""" -Python script to generate proper Visual Studio project files for YAZE -This script creates a comprehensive .vcxproj file with all necessary source files -""" - -import os -import sys -from pathlib import Path - -def generate_vcxproj(): - """Generate the YAZE.vcxproj file with all source files""" - - # Source file lists (from CMake files) - app_core_src = [ - "app/core/controller.cc", - "app/emu/emulator.cc", - "app/core/project.cc", - "app/core/window.cc", - "app/core/asar_wrapper.cc", - "app/core/platform/font_loader.cc", - "app/core/platform/clipboard.cc", - "app/core/platform/file_dialog.cc" - ] - - app_emu_src = [ - "app/emu/audio/apu.cc", - "app/emu/audio/spc700.cc", - "app/emu/audio/dsp.cc", - "app/emu/audio/internal/addressing.cc", - "app/emu/audio/internal/instructions.cc", - "app/emu/cpu/internal/addressing.cc", - "app/emu/cpu/internal/instructions.cc", - "app/emu/cpu/cpu.cc", - "app/emu/video/ppu.cc", - "app/emu/memory/dma.cc", - "app/emu/memory/memory.cc", - "app/emu/snes.cc" - ] - - app_editor_src = [ - "app/editor/editor_manager.cc", - "app/editor/dungeon/dungeon_editor.cc", - "app/editor/dungeon/dungeon_room_selector.cc", - "app/editor/dungeon/dungeon_canvas_viewer.cc", - "app/editor/dungeon/dungeon_object_selector.cc", - "app/editor/dungeon/dungeon_toolset.cc", - "app/editor/dungeon/dungeon_object_interaction.cc", - "app/editor/dungeon/dungeon_renderer.cc", - "app/editor/dungeon/dungeon_room_loader.cc", - "app/editor/dungeon/dungeon_usage_tracker.cc", - "app/editor/overworld/overworld_editor.cc", - "app/editor/overworld/overworld_editor_manager.cc", - "app/editor/sprite/sprite_editor.cc", - "app/editor/music/music_editor.cc", - "app/editor/message/message_editor.cc", - "app/editor/message/message_data.cc", - "app/editor/message/message_preview.cc", - "app/editor/code/assembly_editor.cc", - "app/editor/graphics/screen_editor.cc", - "app/editor/graphics/graphics_editor.cc", - "app/editor/graphics/palette_editor.cc", - "app/editor/overworld/tile16_editor.cc", - "app/editor/overworld/map_properties.cc", - "app/editor/graphics/gfx_group_editor.cc", - "app/editor/overworld/entity.cc", - "app/editor/system/settings_editor.cc", - "app/editor/system/command_manager.cc", - "app/editor/system/extension_manager.cc", - "app/editor/system/shortcut_manager.cc", - "app/editor/system/popup_manager.cc", - "app/test/test_manager.cc" - ] - - app_gfx_src = [ - "app/gfx/arena.cc", - "app/gfx/background_buffer.cc", - "app/gfx/bitmap.cc", - "app/gfx/compression.cc", - "app/gfx/scad_format.cc", - "app/gfx/snes_palette.cc", - "app/gfx/snes_tile.cc", - "app/gfx/snes_color.cc", - "app/gfx/tilemap.cc" - ] - - app_zelda3_src = [ - "app/zelda3/hyrule_magic.cc", - "app/zelda3/overworld/overworld_map.cc", - "app/zelda3/overworld/overworld.cc", - "app/zelda3/screen/inventory.cc", - "app/zelda3/screen/title_screen.cc", - "app/zelda3/screen/dungeon_map.cc", - "app/zelda3/sprite/sprite.cc", - "app/zelda3/sprite/sprite_builder.cc", - "app/zelda3/music/tracker.cc", - "app/zelda3/dungeon/room.cc", - "app/zelda3/dungeon/room_object.cc", - "app/zelda3/dungeon/object_parser.cc", - "app/zelda3/dungeon/object_renderer.cc", - "app/zelda3/dungeon/room_layout.cc", - "app/zelda3/dungeon/dungeon_editor_system.cc", - "app/zelda3/dungeon/dungeon_object_editor.cc" - ] - - gui_src = [ - "app/gui/modules/asset_browser.cc", - "app/gui/modules/text_editor.cc", - "app/gui/canvas.cc", - "app/gui/canvas_utils.cc", - "app/gui/enhanced_palette_editor.cc", - "app/gui/input.cc", - "app/gui/style.cc", - "app/gui/color.cc", - "app/gui/zeml.cc", - "app/gui/theme_manager.cc", - "app/gui/background_renderer.cc" - ] - - util_src = [ - "util/bps.cc", - "util/flag.cc", - "util/hex.cc" - ] - - # Combine all source files - all_source_files = ( - ["yaze.cc", "app/main.cc", "app/rom.cc"] + - app_core_src + app_emu_src + app_editor_src + - app_gfx_src + app_zelda3_src + gui_src + util_src - ) - - # Header files - header_files = [ - "incl/yaze.h", - "incl/zelda.h", - "src/yaze_config.h.in" - ] - - # Generate the .vcxproj file content - vcxproj_content = ''' - - - - Debug - x64 - - - Debug - x86 - - - Debug - ARM64 - - - Release - x64 - - - Release - x86 - - - Release - ARM64 - - - RelWithDebInfo - x64 - - - RelWithDebInfo - x86 - - - RelWithDebInfo - ARM64 - - - MinSizeRel - x64 - - - MinSizeRel - x86 - - - MinSizeRel - ARM64 - - - - 17.0 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012} - Win32Proj - YAZE - 10.0 - YAZE - true - true - x86-windows - x64-windows - arm64-windows - - - - Application - true - v143 - Unicode - - - Application - true - v143 - Unicode - - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - - - Application - false - v143 - true - Unicode - - - Application - false - v143 - true - Unicode - - - Application - false - v143 - true - Unicode - - - Application - false - v143 - true - Unicode - - - Application - false - v143 - true - Unicode - - - Application - false - v143 - true - Unicode - - - Application - false - v143 - true - Unicode - - - Application - false - v143 - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - $(SolutionDir)build\\bin\\$(Configuration)\\ - $(SolutionDir)build\\obj\\$(Configuration)\\ - - - true - $(SolutionDir)build\\bin\\$(Configuration)\\ - $(SolutionDir)build\\obj\\$(Configuration)\\ - - - true - $(SolutionDir)build\\bin\\$(Configuration)\\ - $(SolutionDir)build\\obj\\$(Configuration)\\ - - - false - $(SolutionDir)build\\bin\\$(Configuration)\\ - $(SolutionDir)build\\obj\\$(Configuration)\\ - - - false - $(SolutionDir)build\\bin\\$(Configuration)\\ - $(SolutionDir)build\\obj\\$(Configuration)\\ - - - false - $(SolutionDir)build\\bin\\$(Configuration)\\ - $(SolutionDir)build\\obj\\$(Configuration)\\ - - - false - $(SolutionDir)build\\bin\\$(Configuration)\\ - $(SolutionDir)build\\obj\\$(Configuration)\\ - - - false - $(SolutionDir)build\\bin\\$(Configuration)\\ - $(SolutionDir)build\\obj\\$(Configuration)\\ - - - false - $(SolutionDir)build\\bin\\$(Configuration)\\ - $(SolutionDir)build\\obj\\$(Configuration)\\ - - - false - $(SolutionDir)build\\bin\\$(Configuration)\\ - $(SolutionDir)build\\obj\\$(Configuration)\\ - - - false - $(SolutionDir)build\\bin\\$(Configuration)\\ - $(SolutionDir)build\\obj\\$(Configuration)\\ - - - false - $(SolutionDir)build\\bin\\$(Configuration)\\ - $(SolutionDir)build\\obj\\$(Configuration)\\ - ''' - - # Add compiler and linker settings for all configurations - configurations = ["Debug", "Release", "RelWithDebInfo", "MinSizeRel"] - platforms = ["x64", "x86", "ARM64"] - - for config in configurations: - for platform in platforms: - is_debug = (config == "Debug") - debug_flags = "_DEBUG;_CONSOLE;%(PreprocessorDefinitions)" if is_debug else "NDEBUG;_CONSOLE;%(PreprocessorDefinitions)" - link_incremental = "true" if is_debug else "false" - generate_debug_info = "false" if config == "MinSizeRel" else "true" - - vcxproj_content += f''' - - - Level3 - true - {debug_flags} - true - $(ProjectDir)src;$(ProjectDir)incl;$(ProjectDir)src\\lib;$(ProjectDir)src\\lib\\asar\\src;$(ProjectDir)src\\lib\\asar\\src\\asar;$(ProjectDir)src\\lib\\asar\\src\\asar-dll-bindings\\c;$(ProjectDir)src\\lib\\imgui;$(ProjectDir)src\\lib\\imgui_test_engine;%(AdditionalIncludeDirectories) - stdcpp23 - true - true - MultiThreaded{"Debug" if is_debug else ""}DLL - - - Console - {generate_debug_info} - {"false" if is_debug else "true"} - {"false" if is_debug else "true"} - - ''' - - # Add source files - vcxproj_content += ''' - -''' - for header in header_files: - vcxproj_content += f' \n' - - vcxproj_content += ''' - -''' - for source in all_source_files: - vcxproj_content += f' \n' - - vcxproj_content += ''' - - - - - - - - - - -''' - - return vcxproj_content - -def generate_solution(): - """Generate the YAZE.sln file""" - return '''Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "YAZE", "YAZE.vcxproj", "{B2C3D4E5-F6G7-8901-BCDE-F23456789012}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Debug|ARM64 = Debug|ARM64 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - Release|ARM64 = Release|ARM64 - RelWithDebInfo|x64 = RelWithDebInfo|x64 - RelWithDebInfo|x86 = RelWithDebInfo|x86 - RelWithDebInfo|ARM64 = RelWithDebInfo|ARM64 - MinSizeRel|x64 = MinSizeRel|x64 - MinSizeRel|x86 = MinSizeRel|x86 - MinSizeRel|ARM64 = MinSizeRel|ARM64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Debug|x64.ActiveCfg = Debug|x64 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Debug|x64.Build.0 = Debug|x64 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Debug|x86.ActiveCfg = Debug|x86 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Debug|x86.Build.0 = Debug|x86 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Debug|ARM64.Build.0 = Debug|ARM64 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Release|x64.ActiveCfg = Release|x64 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Release|x64.Build.0 = Release|x64 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Release|x86.ActiveCfg = Release|x86 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Release|x86.Build.0 = Release|x86 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Release|ARM64.ActiveCfg = Release|ARM64 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Release|ARM64.Build.0 = Release|ARM64 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|x86 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|x86 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.RelWithDebInfo|ARM64.ActiveCfg = RelWithDebInfo|ARM64 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.RelWithDebInfo|ARM64.Build.0 = RelWithDebInfo|ARM64 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.MinSizeRel|x64.ActiveCfg = MinSizeRel|x64 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.MinSizeRel|x64.Build.0 = MinSizeRel|x64 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.MinSizeRel|x86.ActiveCfg = MinSizeRel|x86 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.MinSizeRel|x86.Build.0 = MinSizeRel|x86 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.MinSizeRel|ARM64.ActiveCfg = MinSizeRel|ARM64 - {B2C3D4E5-F6G7-8901-BCDE-F23456789012}.MinSizeRel|ARM64.Build.0 = MinSizeRel|ARM64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {A1B2C3D4-E5F6-7890-ABCD-EF1234567890} - EndGlobalSection -EndGlobal''' - -def main(): - """Main function to generate Visual Studio project files""" - print("Generating Visual Studio project files for YAZE...") - - # Get the project root directory - script_dir = Path(__file__).parent - project_root = script_dir.parent - - # Generate .vcxproj file - vcxproj_content = generate_vcxproj() - vcxproj_path = project_root / "YAZE.vcxproj" - - with open(vcxproj_path, 'w', encoding='utf-8') as f: - f.write(vcxproj_content) - - print(f"Generated: {vcxproj_path}") - - # Generate .sln file - solution_content = generate_solution() - solution_path = project_root / "YAZE.sln" - - with open(solution_path, 'w', encoding='utf-8') as f: - f.write(solution_content) - - print(f"Generated: {solution_path}") - - print("Visual Studio project files generated successfully!") - print("") - print("To build:") - print("1. Open YAZE.sln in Visual Studio 2022") - print("2. Ensure vcpkg is installed and configured") - print("3. Select your desired configuration (Debug/Release) and platform (x64/x86/ARM64)") - print("4. Build the solution (Ctrl+Shift+B)") - -if __name__ == "__main__": - main() diff --git a/src/app/editor/overworld/overworld_editor.h b/src/app/editor/overworld/overworld_editor.h index ecb6ee25..a8d66fbb 100644 --- a/src/app/editor/overworld/overworld_editor.h +++ b/src/app/editor/overworld/overworld_editor.h @@ -131,7 +131,7 @@ class OverworldEditor : public Editor, public gfx::GfxContext { void DrawOverworldMapSettings(); void DrawCustomOverworldMapSettings(); - void RefreshChildMap(int i); + void RefreshChildMap(int map_index); void RefreshOverworldMap(); void RefreshOverworldMapOnDemand(int map_index); void RefreshChildMapOnDemand(int map_index); diff --git a/src/app/emu/emulator.cc b/src/app/emu/emulator.cc index 1b462f74..929dedd1 100644 --- a/src/app/emu/emulator.cc +++ b/src/app/emu/emulator.cc @@ -8,7 +8,6 @@ #include "app/emu/cpu/internal/opcodes.h" #include "app/gui/icons.h" #include "app/gui/input.h" -#include "app/gui/zeml.h" #include "imgui/imgui.h" #include "imgui_memory_editor.h" @@ -105,7 +104,76 @@ void Emulator::Run() { } } - gui::zeml::Render(emulator_node_); + RenderEmulatorInterface(); +} + +void Emulator::RenderEmulatorInterface() { + if (ImGui::BeginTable("Emulator", 2, ImGuiTableFlags_Resizable | ImGuiTableFlags_ScrollY)) { + ImGui::TableSetupColumn("CPU"); + ImGui::TableSetupColumn("PPU"); + ImGui::TableHeadersRow(); + + // CPU Column + ImGui::TableNextColumn(); + + // CPU Register Values + if (ImGui::CollapsingHeader("Register Values", ImGuiTreeNodeFlags_DefaultOpen)) { + ImGui::BeginChild("##CpuState", ImVec2(0, 100), ImGuiChildFlags_None, + ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar); + ImGui::Columns(2, "registersColumns"); + + ImGui::Text("A: 0x%04X", snes_.cpu().A); + ImGui::Text("X: 0x%04X", snes_.cpu().X); + ImGui::Text("Y: 0x%04X", snes_.cpu().Y); + ImGui::Text("PC: 0x%04X", snes_.cpu().PC); + ImGui::Text("SP: 0x%02X", snes_.memory().mutable_sp()); + + ImGui::NextColumn(); + + ImGui::Text("D: 0x%04X", snes_.cpu().D); + ImGui::Text("DB: 0x%02X", snes_.cpu().DB); + ImGui::Text("PB: 0x%02X", snes_.cpu().PB); + ImGui::Text("PS: 0x%02X", snes_.cpu().status); + ImGui::Text("Cycle: %llu", snes_.mutable_cycles()); + + ImGui::Columns(1); + ImGui::EndChild(); + } + + // SPC Registers + if (ImGui::CollapsingHeader("SPC Registers", ImGuiTreeNodeFlags_DefaultOpen)) { + ImGui::BeginChild("##SpcState", ImVec2(0, 100), ImGuiChildFlags_None, + ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar); + ImGui::Columns(2, "spcRegistersColumns"); + + ImGui::Text("A: 0x%02X", snes_.apu().spc700().A); + ImGui::Text("X: 0x%02X", snes_.apu().spc700().X); + ImGui::Text("Y: 0x%02X", snes_.apu().spc700().Y); + + ImGui::NextColumn(); + + ImGui::Text("PC: 0x%04X", snes_.apu().spc700().PC); + ImGui::Text("SP: 0x%02X", snes_.apu().spc700().SP); + ImGui::Text("PSW: 0x%02X", snes_.apu().spc700().FlagsToByte(snes_.apu().spc700().PSW)); + + ImGui::Columns(1); + ImGui::EndChild(); + } + + // CPU Instruction Log + RenderCpuInstructionLog(snes_.cpu().instruction_log_); + + // PPU Column + ImGui::TableNextColumn(); + + // SNES PPU + RenderSnesPpu(); + + // Breakpoint List + RenderBreakpointList(); + + ImGui::EndTable(); + } } void Emulator::RenderSnesPpu() { @@ -132,18 +200,21 @@ void Emulator::RenderSnesPpu() { } void Emulator::RenderNavBar() { - std::string navbar_layout = R"( - BeginMenuBar { - BeginMenu title="Options" { - MenuItem title="Input" {} - MenuItem title="Audio" {} - MenuItem title="Video" {} + if (ImGui::BeginMenuBar()) { + if (ImGui::BeginMenu("Options")) { + if (ImGui::MenuItem("Input")) { + // Input options logic } + if (ImGui::MenuItem("Audio")) { + // Audio options logic + } + if (ImGui::MenuItem("Video")) { + // Video options logic + } + ImGui::EndMenu(); } - )"; - - static auto navbar_node = gui::zeml::Parse(navbar_layout); - gui::zeml::Render(navbar_node); + ImGui::EndMenuBar(); + } if (ImGui::Button(ICON_MD_PLAY_ARROW)) { running_ = true; diff --git a/src/app/emu/emulator.h b/src/app/emu/emulator.h index 53a5d431..4ff23919 100644 --- a/src/app/emu/emulator.h +++ b/src/app/emu/emulator.h @@ -5,7 +5,6 @@ #include #include "app/emu/snes.h" -#include "app/gui/zeml.h" #include "app/rom.h" #include "imgui/imgui.h" @@ -38,74 +37,7 @@ struct EmulatorKeybindings { */ class Emulator { public: - Emulator() { - std::string emulator_layout = R"( - Table id="Emulator" count="2" flags="Resizable|ScrollY" { - TableSetupColumn title="CPU", - TableSetupColumn title="PPU", - - TableHeadersRow, - TableNextColumn, - - CollapsingHeader id="cpuState" title="Register Values" flags="DefaultOpen" { - BeginChild id="##CpuState" size="0,100" flags="NoMove|NoScrollbar" { - Columns id="registersColumns" count="2" { - Text text="A: 0x%04X" data="cpu.A", - Text text="D: 0x%04X" data="cpu.D", - Text text="X: 0x%04X" data="cpu.X", - Text text="DB: 0x%02X" data="cpu.DB", - Text text="Y: 0x%04X" data="cpu.Y", - Text text="PB: 0x%02X" data="cpu.PB", - Text text="PC: 0x%04X" data="cpu.PC", - Text text="PS: 0x%02X" data="cpu.status", - Text text="SP: 0x%02X" data="cpu.SP", - Text text="Cycle: %d" data="snes.cycle_count", - } - } - } - CollapsingHeader id="spcState" title="SPC Registers" flags="DefaultOpen" { - BeginChild id="##SpcState" size="0,100" flags="NoMove|NoScrollbar" { - Columns id="spcRegistersColumns" count="2" { - Text text="A: 0x%02X" data="spc.A", - Text text="PC: 0x%04X" data="spc.PC", - Text text="X: 0x%02X" data="spc.X", - Text text="SP: 0x%02X" data="spc.SP", - Text text="Y: 0x%02X" data="spc.Y", - Text text="PSW: 0x%02X" data="spc.PSW", - } - } - } - Function id="CpuInstructionLog", - - TableNextColumn, - Function id="SnesPpu", - Function id="BreakpointList" - } - )"; - const std::map data_bindings = { - {"cpu.A", &snes_.cpu().A}, - {"cpu.D", &snes_.cpu().D}, - {"cpu.X", &snes_.cpu().X}, - {"cpu.DB", &snes_.cpu().DB}, - {"cpu.Y", &snes_.cpu().Y}, - {"cpu.PB", &snes_.cpu().PB}, - {"cpu.PC", &snes_.cpu().PC}, - {"cpu.status", &snes_.cpu().status}, - {"snes.cycle_count", &snes_.mutable_cycles()}, - {"cpu.SP", &snes_.memory().mutable_sp()}, - {"spc.A", &snes_.apu().spc700().A}, - {"spc.X", &snes_.apu().spc700().X}, - {"spc.Y", &snes_.apu().spc700().Y}, - {"spc.PC", &snes_.apu().spc700().PC}, - {"spc.SP", &snes_.apu().spc700().SP}, - {"spc.PSW", &snes_.apu().spc700().PSW}}; - emulator_node_ = gui::zeml::Parse(emulator_layout, data_bindings); - Bind(emulator_node_.GetNode("CpuInstructionLog"), - [&]() { RenderCpuInstructionLog(snes_.cpu().instruction_log_); }); - Bind(emulator_node_.GetNode("SnesPpu"), [&]() { RenderSnesPpu(); }); - Bind(emulator_node_.GetNode("BreakpointList"), - [&]() { RenderBreakpointList(); }); - } + Emulator() = default; void Run(); auto snes() -> Snes& { return snes_; } @@ -121,6 +53,7 @@ class Emulator { private: void RenderNavBar(); void HandleEvents(); + void RenderEmulatorInterface(); void RenderSnesPpu(); void RenderBreakpointList(); @@ -162,8 +95,6 @@ class Emulator { std::vector rom_data_; EmulatorKeybindings keybindings_; - - gui::zeml::Node emulator_node_; }; } // namespace emu diff --git a/src/app/gui/gui.cmake b/src/app/gui/gui.cmake index 0a7b7c8b..60d97bfe 100644 --- a/src/app/gui/gui.cmake +++ b/src/app/gui/gui.cmake @@ -8,7 +8,6 @@ set( app/gui/input.cc app/gui/style.cc app/gui/color.cc - app/gui/zeml.cc app/gui/theme_manager.cc app/gui/background_renderer.cc ) diff --git a/src/app/gui/zeml.cc b/src/app/gui/zeml.cc deleted file mode 100644 index 75df05f6..00000000 --- a/src/app/gui/zeml.cc +++ /dev/null @@ -1,621 +0,0 @@ - -#include "app/gui/zeml.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "app/core/platform/file_dialog.h" -#include "app/gui/canvas.h" -#include "app/gui/input.h" -#include "imgui/imgui.h" - -namespace yaze { -namespace gui { -namespace zeml { - -std::vector Tokenize(const std::string& input) { - std::vector tokens; - std::istringstream stream(input); - char ch; - - while (stream.get(ch)) { - if (isspace(ch)) continue; - - if (ch == '{') { - tokens.push_back({TokenType::OpenBrace, "{"}); - } else if (ch == '}') { - tokens.push_back({TokenType::CloseBrace, "}"}); - } else if (ch == ',') { - tokens.push_back({TokenType::Comma, ","}); - } else if (std::isalnum(ch) || ch == '_') { - std::string ident(1, ch); - while (stream.get(ch) && (std::isalnum(ch) || ch == '_')) { - ident += ch; - } - stream.unget(); - tokens.push_back({TokenType::Identifier, ident}); - } else if (ch == '"' || ch == '\'') { - std::string str; - char quoteType = ch; - while (stream.get(ch) && ch != quoteType) { - str += ch; - } - tokens.push_back({TokenType::String, str}); - } - } - - tokens.push_back({TokenType::EndOfStream, ""}); - return tokens; -} - -WidgetType MapType(const std::string& type) { - static std::map typeMap = { - {"Window", WidgetType::Window}, - {"Button", WidgetType::Button}, - {"Slider", WidgetType::Slider}, - {"Text", WidgetType::Text}, - {"CollapsingHeader", WidgetType::CollapsingHeader}, - {"Columns", WidgetType::Columns}, - {"Checkbox", WidgetType::Checkbox}, - {"HexInputByte", WidgetType::HexInputByte}, - {"HexInputWord", WidgetType::HexInputWord}, - {"Table", WidgetType::Table}, - {"Selectable", WidgetType::Selectable}, - {"TableSetupColumn", WidgetType::TableSetupColumn}, - {"TableHeadersRow", WidgetType::TableHeadersRow}, - {"TableNextColumn", WidgetType::TableNextColumn}, - {"Function", WidgetType::Function}, - {"BeginChild", WidgetType::BeginChild}, - {"BeginMenu", WidgetType::BeginMenu}, - {"MenuItem", WidgetType::MenuItem}, - {"BeginMenuBar", WidgetType::BeginMenuBar}, - {"Separator", WidgetType::Separator}, - {"BeginTabBar", WidgetType::BeginTabBar}, - {"BeginTabItem", WidgetType::BeginTabItem}, - {"Canvas", WidgetType::Canvas}, - {"ref", WidgetType::Definition}, - }; - return typeMap[type]; -} - -Node ParseNode(const std::vector& tokens, size_t& index, - const std::map& data_bindings, - const std::map& definitions) { - Node node; - if (index >= tokens.size() || tokens[index].type == TokenType::EndOfStream) { - return node; - } - - while (index < tokens.size() && - tokens[index].type != TokenType::EndOfStream) { - Token token = tokens[index]; - if (token.type == TokenType::Identifier) { - node.type = MapType(token.value); - index++; // Move to the next token for attributes - if (node.type == WidgetType::Definition) { - if (definitions.find(token.value) != definitions.end()) { - node = definitions.at(token.value); - } - } else { - node.attributes = - ParseAttributes(tokens, index, node.type, data_bindings); - } - } - - // Handle the opening brace indicating the start of child nodes - if (index < tokens.size() && tokens[index].type == TokenType::OpenBrace) { - index++; // Skip the opening brace - - while (index < tokens.size() && - tokens[index].type != TokenType::CloseBrace) { - if (tokens[index].type == TokenType::Comma) { - index++; // Skip commas - } else { - node.children.push_back(ParseNode(tokens, index, data_bindings)); - } - } - - if (index < tokens.size() && - tokens[index].type == TokenType::CloseBrace) { - index++; // Ensure closing brace is skipped before returning - } - } - - break; // Exit after processing one complete node - } - return node; -} - -void ParseFlags(const WidgetType& type, const std::string& flags, - WidgetAttributes& attributes) { - // Parse the flags for the `|` character - std::vector flag_tokens; - std::string token; - std::istringstream tokenStream(flags); - while (std::getline(tokenStream, token, '|')) { - flag_tokens.push_back(token); - } - - switch (type) { - case WidgetType::BeginChild: { - static std::map flagMap = { - {"None", ImGuiWindowFlags_None}, - {"NoTitleBar", ImGuiWindowFlags_NoTitleBar}, - {"NoResize", ImGuiWindowFlags_NoResize}, - {"NoMove", ImGuiWindowFlags_NoMove}, - {"NoScrollbar", ImGuiWindowFlags_NoScrollbar}, - {"NoScrollWithMouse", ImGuiWindowFlags_NoScrollWithMouse}, - {"NoCollapse", ImGuiWindowFlags_NoCollapse}, - {"AlwaysAutoResize", ImGuiWindowFlags_AlwaysAutoResize}, - {"NoSavedSettings", ImGuiWindowFlags_NoSavedSettings}, - {"NoInputs", ImGuiWindowFlags_NoInputs}, - {"MenuBar", ImGuiWindowFlags_MenuBar}, - {"HorizontalScrollbar", ImGuiWindowFlags_HorizontalScrollbar}, - {"NoFocusOnAppearing", ImGuiWindowFlags_NoFocusOnAppearing}, - {"NoBringToFrontOnFocus", ImGuiWindowFlags_NoBringToFrontOnFocus}, - {"AlwaysVerticalScrollbar", ImGuiWindowFlags_AlwaysVerticalScrollbar}, - {"AlwaysHorizontalScrollbar", - ImGuiWindowFlags_AlwaysHorizontalScrollbar}, - {"AlwaysUseWindowPadding", ImGuiWindowFlags_AlwaysUseWindowPadding}, - {"NoNavInputs", ImGuiWindowFlags_NoNavInputs}, - {"NoNavFocus", ImGuiWindowFlags_NoNavFocus}, - {"UnsavedDocument", ImGuiWindowFlags_UnsavedDocument}, - {"NoNav", ImGuiWindowFlags_NoNav}, - {"NoDecoration", ImGuiWindowFlags_NoDecoration}, - {"NoInputs", ImGuiWindowFlags_NoInputs}, - {"NoFocusOnAppearing", ImGuiWindowFlags_NoFocusOnAppearing}, - {"NoBringToFrontOnFocus", ImGuiWindowFlags_NoBringToFrontOnFocus}, - {"AlwaysAutoResize", ImGuiWindowFlags_AlwaysAutoResize}, - {"NoSavedSettings", ImGuiWindowFlags_NoSavedSettings}, - {"NoMouseInputs", ImGuiWindowFlags_NoMouseInputs}, - {"NoMouseInputs", ImGuiWindowFlags_NoMouseInputs}, - {"NoTitleBar", ImGuiWindowFlags_NoTitleBar}, - {"NoResize", ImGuiWindowFlags_NoResize}, - {"NoMove", ImGuiWindowFlags_NoMove}, - {"NoScrollbar", ImGuiWindowFlags_NoScrollbar}, - {"NoScrollWithMouse", ImGuiWindowFlags_NoScrollWithMouse}, - {"NoCollapse", ImGuiWindowFlags_NoCollapse}, - {"AlwaysVerticalScrollbar", ImGuiWindowFlags_AlwaysVerticalScrollbar}, - {"AlwaysHorizontalScrollbar", - ImGuiWindowFlags_AlwaysHorizontalScrollbar}}; - ImGuiWindowFlags windowFlags = ImGuiWindowFlags_None; - for (const auto& flag : flag_tokens) { - if (flagMap.find(flag) != flagMap.end()) { - windowFlags |= flagMap[flag]; - } - } - attributes.flags = std::make_unique(windowFlags); - break; - } - case WidgetType::CollapsingHeader: { - // Create a flag map using the tree node flags - static std::map flagMap = { - {"None", ImGuiTreeNodeFlags_None}, - {"Selected", ImGuiTreeNodeFlags_Selected}, - {"Framed", ImGuiTreeNodeFlags_Framed}, - {"AllowItemOverlap", ImGuiTreeNodeFlags_AllowItemOverlap}, - {"NoTreePushOnOpen", ImGuiTreeNodeFlags_NoTreePushOnOpen}, - {"NoAutoOpenOnLog", ImGuiTreeNodeFlags_NoAutoOpenOnLog}, - {"DefaultOpen", ImGuiTreeNodeFlags_DefaultOpen}, - {"OpenOnDoubleClick", ImGuiTreeNodeFlags_OpenOnDoubleClick}, - {"OpenOnArrow", ImGuiTreeNodeFlags_OpenOnArrow}, - {"Leaf", ImGuiTreeNodeFlags_Leaf}, - {"Bullet", ImGuiTreeNodeFlags_Bullet}, - {"FramePadding", ImGuiTreeNodeFlags_FramePadding}, - {"NavLeftJumpsBackHere", ImGuiTreeNodeFlags_NavLeftJumpsBackHere}, - {"CollapsingHeader", ImGuiTreeNodeFlags_CollapsingHeader}}; - ImGuiTreeNodeFlags treeFlags = ImGuiTreeNodeFlags_None; - for (const auto& flag : flag_tokens) { - if (flagMap.find(flag) != flagMap.end()) { - treeFlags |= flagMap[flag]; - } - } - attributes.flags = std::make_unique(treeFlags); - break; - } - case WidgetType::Table: { - // Create a flag map - static std::map flagMap = { - {"None", ImGuiTableFlags_None}, - {"Resizable", ImGuiTableFlags_Resizable}, - {"Reorderable", ImGuiTableFlags_Reorderable}, - {"Hideable", ImGuiTableFlags_Hideable}, - {"Sortable", ImGuiTableFlags_Sortable}, - {"NoSavedSettings", ImGuiTableFlags_NoSavedSettings}, - {"ContextMenuInBody", ImGuiTableFlags_ContextMenuInBody}, - {"RowBg", ImGuiTableFlags_RowBg}, - {"BordersInnerH", ImGuiTableFlags_BordersInnerH}, - {"BordersOuterH", ImGuiTableFlags_BordersOuterH}, - {"BordersInnerV", ImGuiTableFlags_BordersInnerV}, - {"BordersOuterV", ImGuiTableFlags_BordersOuterV}, - {"BordersH", ImGuiTableFlags_BordersH}, - {"BordersV", ImGuiTableFlags_BordersV}, - {"Borders", ImGuiTableFlags_Borders}, - {"NoBordersInBody", ImGuiTableFlags_NoBordersInBody}, - {"NoBordersInBodyUntilResize", - ImGuiTableFlags_NoBordersInBodyUntilResize}, - {"SizingFixedFit", ImGuiTableFlags_SizingFixedFit}, - {"SizingFixedSame", ImGuiTableFlags_SizingFixedSame}, - {"SizingStretchProp", ImGuiTableFlags_SizingStretchProp}, - {"SizingStretchSame", ImGuiTableFlags_SizingStretchSame}, - {"NoHostExtendX", ImGuiTableFlags_NoHostExtendX}, - {"NoHostExtendY", ImGuiTableFlags_NoHostExtendY}, - {"NoKeepColumnsVisible", ImGuiTableFlags_NoKeepColumnsVisible}, - {"PreciseWidths", ImGuiTableFlags_PreciseWidths}, - {"NoClip", ImGuiTableFlags_NoClip}, - {"PadOuterX", ImGuiTableFlags_PadOuterX}, - {"NoPadOuterX", ImGuiTableFlags_NoPadOuterX}, - {"NoPadInnerX", ImGuiTableFlags_NoPadInnerX}, - {"ScrollX", ImGuiTableFlags_ScrollX}, - {"ScrollY", ImGuiTableFlags_ScrollY}, - {"SortMulti", ImGuiTableFlags_SortMulti}, - {"SortTristate", ImGuiTableFlags_SortTristate}}; - ImGuiTableFlags tableFlags = ImGuiTableFlags_None; - for (const auto& flag : flag_tokens) { - if (flagMap.find(flag) != flagMap.end()) { - tableFlags |= flagMap[flag]; - } - } - // Reserve data to the void* pointer and assign flags - attributes.flags = std::make_unique(tableFlags); - } break; - case WidgetType::TableSetupColumn: { - static std::map flagMap = { - {"None", ImGuiTableColumnFlags_None}, - {"DefaultHide", ImGuiTableColumnFlags_DefaultHide}, - {"DefaultSort", ImGuiTableColumnFlags_DefaultSort}, - {"WidthStretch", ImGuiTableColumnFlags_WidthStretch}, - {"WidthFixed", ImGuiTableColumnFlags_WidthFixed}, - {"NoResize", ImGuiTableColumnFlags_NoResize}, - {"NoReorder", ImGuiTableColumnFlags_NoReorder}, - {"NoHide", ImGuiTableColumnFlags_NoHide}, - {"NoClip", ImGuiTableColumnFlags_NoClip}, - {"NoSort", ImGuiTableColumnFlags_NoSort}, - {"NoSortAscending", ImGuiTableColumnFlags_NoSortAscending}, - {"NoSortDescending", ImGuiTableColumnFlags_NoSortDescending}, - {"NoHeaderWidth", ImGuiTableColumnFlags_NoHeaderWidth}, - {"PreferSortAscending", ImGuiTableColumnFlags_PreferSortAscending}, - {"PreferSortDescending", ImGuiTableColumnFlags_PreferSortDescending}, - {"IndentEnable", ImGuiTableColumnFlags_IndentEnable}, - {"IndentDisable", ImGuiTableColumnFlags_IndentDisable}, - {"IsEnabled", ImGuiTableColumnFlags_IsEnabled}, - {"IsVisible", ImGuiTableColumnFlags_IsVisible}, - {"IsSorted", ImGuiTableColumnFlags_IsSorted}, - {"IsHovered", ImGuiTableColumnFlags_IsHovered}}; - ImGuiTableColumnFlags columnFlags = ImGuiTableColumnFlags_None; - for (const auto& flag : flag_tokens) { - if (flagMap.find(flag) != flagMap.end()) { - columnFlags |= flagMap[flag]; - } - } - // Reserve data to the void* pointer and assign flags - attributes.flags = std::make_unique(columnFlags); - } - default: - break; - } -} - -WidgetAttributes ParseAttributes( - const std::vector& tokens, size_t& index, const WidgetType& type, - const std::map& data_bindings) { - WidgetAttributes attributes; - - while (index < tokens.size() && tokens[index].type != TokenType::CloseBrace) { - if (tokens[index].type == TokenType::Identifier) { - Token keyToken = tokens[index]; - index++; // Move to the value token. - if (index < tokens.size() && tokens[index].type == TokenType::String) { - std::string value = tokens[index].value; - index++; // Move past the value. - - if (keyToken.value == "id") - attributes.id = value; - else if (keyToken.value == "title") - attributes.title = value; - else if (keyToken.value == "min") - attributes.min = std::stod(value); - else if (keyToken.value == "max") - attributes.max = std::stod(value); - else if (keyToken.value == "value") - attributes.value = std::stod(value); - else if (keyToken.value == "width") - if (value == "autox") - attributes.width = ImGui::GetContentRegionAvail().x; - else if (value == "autoy") - attributes.width = ImGui::GetContentRegionAvail().y; - else - attributes.width = std::stod(value); - else if (keyToken.value == "text") - attributes.text = value; - else if (keyToken.value == "data" && - data_bindings.find(value) != data_bindings.end()) { - attributes.data = data_bindings.at(value); - } else if (keyToken.value == "count") { - attributes.count = std::stoi(value); - } else if (keyToken.value == "flags") { - ParseFlags(type, value, attributes); - } else if (keyToken.value == "size") { - std::string sizeX, sizeY; - std::istringstream sizeStream(value); - std::getline(sizeStream, sizeX, ','); - std::getline(sizeStream, sizeY, ','); - attributes.size = ImVec2(std::stod(sizeX), std::stod(sizeY)); - } - } - } else { - // If it's not an identifier or we encounter an open brace, break out. - break; - } - } - return attributes; -} - -Node Parse(const std::string& yazon_input, - const std::map& data_bindings) { - size_t index = 0; - auto tokens = Tokenize(yazon_input); - - std::map definitions; - if (tokens[index].value == "Definitions") { - index++; // Skip the "Definitions" token - while (index < tokens.size() && - tokens[index].value != "Layout") { // Skip the definitions - // Get the definition name and parse the node - std::string definition_name = tokens[index].value; - index++; // Move to the definition node - definitions[definition_name] = ParseNode(tokens, index, data_bindings); - index++; - } - } - - return ParseNode(tokens, index, data_bindings); -} - -void Render(Node& node) { - switch (node.type) { - case WidgetType::Window: { - ImGuiWindowFlags flags = ImGuiWindowFlags_None; - if (node.attributes.flags) { - flags = *(ImGuiWindowFlags*)node.attributes.flags.get(); - } - if (ImGui::Begin(node.attributes.title.c_str(), nullptr, flags)) { - for (auto& child : node.children) { - Render(child); - } - } - ImGui::End(); - } break; - case WidgetType::Button: - if (node.attributes.data) { - // Format the text with the data value - char formattedText[256]; - snprintf(formattedText, sizeof(formattedText), - node.attributes.text.c_str(), *(int*)node.attributes.data); - if (ImGui::Button(formattedText)) { - ExecuteActions(node.actions, ActionType::Click); - } - } else { - if (ImGui::Button(node.attributes.text.c_str())) { - ExecuteActions(node.actions, ActionType::Click); - } - } - break; - case WidgetType::CollapsingHeader: { - ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_None; - if (node.attributes.flags) { - flags = *(ImGuiTreeNodeFlags*)node.attributes.flags.get(); - } - if (ImGui::CollapsingHeader(node.attributes.title.c_str(), flags)) { - for (auto& child : node.children) { - Render(child); - } - } - } break; - case WidgetType::Columns: - ImGui::Columns(node.attributes.count, node.attributes.title.c_str()); - ImGui::Separator(); - for (auto& child : node.children) { - Render(child); - ImGui::NextColumn(); - } - ImGui::Columns(1); - ImGui::Separator(); - break; - case WidgetType::Checkbox: - if (ImGui::Checkbox(node.attributes.title.c_str(), - (bool*)node.attributes.data)) { - ExecuteActions(node.actions, ActionType::Change); - } - break; - case WidgetType::Table: { - ImGuiTableFlags flags = ImGuiTableFlags_None; - if (node.attributes.flags) { - flags = *(ImGuiTableFlags*)node.attributes.flags.get(); - } - if (ImGui::BeginTable(node.attributes.id.c_str(), node.attributes.count, - flags)) { - for (auto& child : node.children) { - Render(child); - } - } - ImGui::EndTable(); - } break; - case WidgetType::TableSetupColumn: { - ImGuiTableColumnFlags flags = ImGuiTableColumnFlags_None; - if (node.attributes.flags) { - flags = *(ImGuiTableColumnFlags*)node.attributes.flags.get(); - } - ImGui::TableSetupColumn(node.attributes.title.c_str(), flags); - } break; - case WidgetType::TableHeadersRow: - ImGui::TableHeadersRow(); - break; - case WidgetType::TableNextColumn: - ImGui::TableNextColumn(); - break; - case WidgetType::Text: - if (node.attributes.data) { - // Assuming all data-bound Text widgets use string formatting - char formattedText[128]; - snprintf(formattedText, sizeof(formattedText), - node.attributes.text.c_str(), - *(int*)node.attributes.data & 0xFFFF); - ImGui::Text("%s", formattedText); - } else { - ImGui::Text("%s", node.attributes.text.c_str()); - } - break; - case WidgetType::Function: { - node.actions[0].callback(); - break; - } - case WidgetType::BeginChild: - if (ImGui::BeginChild(node.attributes.id.c_str(), node.attributes.size)) { - for (auto& child : node.children) { - Render(child); - } - ImGui::EndChild(); - } - break; - case WidgetType::BeginMenuBar: - if (ImGui::BeginMenuBar()) { - for (auto& child : node.children) { - Render(child); - } - ImGui::EndMenuBar(); - } - break; - case WidgetType::BeginMenu: { - if (ImGui::BeginMenu(node.attributes.title.c_str())) { - for (auto& child : node.children) { - Render(child); - } - ImGui::EndMenu(); - } - break; - } - case WidgetType::MenuItem: { - if (ImGui::MenuItem(node.attributes.title.c_str())) { - ExecuteActions(node.actions, ActionType::Click); - } - break; - } - case WidgetType::Separator: - ImGui::Separator(); - break; - case WidgetType::Selectable: - if (ImGui::Selectable(node.attributes.title.c_str(), - (bool*)node.attributes.selected)) { - ExecuteActions(node.actions, ActionType::Click); - } - break; - case WidgetType::BeginTabBar: - if (ImGui::BeginTabBar(node.attributes.title.c_str())) { - for (auto& child : node.children) { - Render(child); - } - ImGui::EndTabBar(); - } - break; - case WidgetType::BeginTabItem: - if (ImGui::BeginTabItem(node.attributes.title.c_str())) { - for (auto& child : node.children) { - Render(child); - } - ImGui::EndTabItem(); - } - break; - case WidgetType::HexInputByte: - gui::InputHexByte(node.attributes.id.c_str(), - (uint8_t*)node.attributes.data); - break; - case WidgetType::HexInputWord: - gui::InputHexWord(node.attributes.id.c_str(), - (uint16_t*)node.attributes.data); - break; - case WidgetType::Canvas: { - gui::Canvas* canvas = (gui::Canvas*)node.attributes.data; - if (canvas) { - canvas->DrawBackground(); - canvas->DrawContextMenu(); - - canvas->DrawGrid(); - canvas->DrawOverlay(); - } - break; - } - default: - break; - } -} - -void ExecuteActions(const std::vector& actions, ActionType type) { - for (const auto& action : actions) { - if (action.type == type) { - action.callback(); // Execute the callback associated with the action - } - } -} - -void Bind(Node* node, std::function callback) { - if (node) { - Action action = {ActionType::Click, callback}; - node->actions.push_back(action); - } -} - -void BindAction(Node* node, ActionType type, std::function callback) { - if (node) { - Action action = {type, callback}; - node->actions.push_back(action); - } -} - -void BindSelectable(Node* node, bool* selected, - std::function callback) { - if (node) { - Action action = {ActionType::Click, callback}; - node->actions.push_back(action); - node->attributes.selected = selected; - } -} - -std::string LoadFile(const std::string& filename) { - std::string fileContents; - const std::string kPath = "assets/layouts/"; - -#ifdef __APPLE__ -#if TARGET_OS_IOS == 1 - const std::string kBundlePath = core::GetBundleResourcePath(); - std::ifstream file(kBundlePath + filename); -#else - const std::string kBundlePath = core::GetBundleResourcePath(); - std::ifstream file(kBundlePath + "Contents/Resources/layouts/" + filename); -#endif -#else - std::ifstream file(kPath + filename); -#endif - - if (file.is_open()) { - std::string line; - while (std::getline(file, line)) { - fileContents += line; - } - file.close(); - } else { - fileContents = "File not found: " + filename; - std::cout << fileContents << std::endl; - } - return fileContents; -} - -} // namespace zeml -} // namespace gui - -} // namespace yaze diff --git a/src/app/gui/zeml.h b/src/app/gui/zeml.h deleted file mode 100644 index 79c68976..00000000 --- a/src/app/gui/zeml.h +++ /dev/null @@ -1,205 +0,0 @@ -#ifndef YAZE_APP_GUI_ZEML_H -#define YAZE_APP_GUI_ZEML_H - -#include -#include -#include -#include -#include -#include - -#include "imgui/imgui.h" - -namespace yaze { -namespace gui { - -/** - * @namespace yaze::gui::zeml - * @brief Zelda Editor Markup Language Functions - */ -namespace zeml { - -/** - * @enum TokenType - */ -enum class TokenType { - Identifier, - String, - OpenBrace, - CloseBrace, - Comma, - EndOfStream -}; - -/** - * @struct Token - */ -struct Token { - TokenType type; - std::string value; -} typedef Token; - -/** - * @enum WidgetType - */ -enum class WidgetType { - Window, - Button, - Slider, - Text, - Table, - TableSetupColumn, - TableHeadersRow, - TableNextColumn, - CollapsingHeader, - Columns, - Checkbox, - Selectable, - Function, - BeginChild, - BeginMenuBar, - BeginMenu, - BeginTabBar, - BeginTabItem, - MenuItem, - Separator, - HexInputByte, - HexInputWord, - Canvas, - Definition, -}; - -/** - * @struct WidgetAttributes - * @brief Attributes for a widget - * @details id, title, min, max, value, text, count, size, flags, data - * @details id: unique identifier for the widget - * @details title: title for the widget - * @details text: text for the widget - * @details min: minimum value for the widget - * @details max: maximum value for the widget - * @details value: value for the widget - * @details count: number of columns - * @details size: size of the widget - * @details flags: flags for the widget - * @details data: data to be binded using the data_binding map - */ -struct WidgetAttributes { - std::string id; - std::string title; // For Window, Button - std::string text; // For Text, Button - double min; // For Slider - double max; // For Slider - double value; // For Slidecar - float width; // For Columns - int count = 0; // For Columns - ImVec2 size = ImVec2(0, 0); // For BeginChild - bool* selected = nullptr; // For Selectable - std::shared_ptr flags = nullptr; // For Various - void* data = nullptr; // For Various -}; - -/** - * @enum ActionType - */ -enum class ActionType { Click, Change, Run }; - -/** - * @struct Action - */ -struct Action { - ActionType type; - std::function callback; -}; - -/** - * @brief Tokenize a zeml string - */ -std::vector Tokenize(const std::string& input); - -/** - * @struct Node - * @brief Node for a zeml tree - */ -struct Node { - WidgetType type; - WidgetAttributes attributes; - std::vector actions; - std::vector children; - - Node* parent = nullptr; - - Node* GetNode(const std::string& searchId) { - if (attributes.id == searchId) { - return this; - } - for (Node& child : children) { - Node* found = child.GetNode(searchId); - if (found != nullptr) { - return found; - } - } - return nullptr; - } -}; - -/** - * @brief Bind a callback to a node - */ -void Bind(Node* node, std::function callback); - -/** - * @brief Bind an action to a node - */ -void BindAction(Node* node, ActionType type, std::function callback); - -/** - * @brief Bind a selectable node - */ -void BindSelectable(Node* node, bool* selected, std::function callback); - -/** - * @brief Map a string to a widget type - */ -WidgetType MapType(const std::string& type); - -void ParseFlags(const WidgetType& type, const std::string& flags, - WidgetAttributes& flags_ptr); - -/** - * @brief ParseNode attributes for a widget - */ -WidgetAttributes ParseAttributes( - const std::vector& tokens, size_t& index, const WidgetType& type, - const std::map& data_bindings = {}); - -/** - * @brief Parse a zeml node - */ -Node ParseNode(const std::vector& tokens, size_t& index, - const std::map& data_bindings = {}, - const std::map& definitions = {}); - -/** - * @brief Parse a zeml string - */ -Node Parse(const std::string& yazon_input, - const std::map& data_bindings = {}); - -/** - * @brief Render a zeml tree - */ -void Render(Node& node); - -/** - * @brief Execute actions for a node - */ -void ExecuteActions(const std::vector& actions, ActionType type); - -std::string LoadFile(const std::string& filename); - -} // namespace zeml -} // namespace gui -} // namespace yaze - -#endif // YAZE_APP_GUI_ZEML_H diff --git a/src/app/zelda3/hyrule_magic.h b/src/app/zelda3/hyrule_magic.h index a37cf9b2..a6e6f1c5 100644 --- a/src/app/zelda3/hyrule_magic.h +++ b/src/app/zelda3/hyrule_magic.h @@ -3,11 +3,6 @@ #include #include -#include -#include - -#include "absl/strings/str_cat.h" -#include "absl/strings/str_format.h" namespace yaze { namespace zelda3 { diff --git a/src/lib/asar b/src/lib/asar index 9bd5a49e..5fd539cd 160000 --- a/src/lib/asar +++ b/src/lib/asar @@ -1 +1 @@ -Subproject commit 9bd5a49ef0f2965cd8c5b17e9de687c5df854783 +Subproject commit 5fd539cd510e4a26afef66fc14e35ca6d8ff0497 diff --git a/src/lib/imgui b/src/lib/imgui index 0ddc36f5..b4514ce6 160000 --- a/src/lib/imgui +++ b/src/lib/imgui @@ -1 +1 @@ -Subproject commit 0ddc36f54372225e28cdc8fb3bbd606797d52416 +Subproject commit b4514ce64a62322746af99b83a53187c6761c34a