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.
This commit is contained in:
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -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
|
||||
|
||||
@@ -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 = '''<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="17.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x86">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x86</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x86">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x86</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="RelWithDebInfo|x64">
|
||||
<Configuration>RelWithDebInfo</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="RelWithDebInfo|x86">
|
||||
<Configuration>RelWithDebInfo</Configuration>
|
||||
<Platform>x86</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="RelWithDebInfo|ARM64">
|
||||
<Configuration>RelWithDebInfo</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="MinSizeRel|x64">
|
||||
<Configuration>MinSizeRel</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="MinSizeRel|x86">
|
||||
<Configuration>MinSizeRel</Configuration>
|
||||
<Platform>x86</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="MinSizeRel|ARM64">
|
||||
<Configuration>MinSizeRel</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<ProjectGuid>{B2C3D4E5-F6G7-8901-BCDE-F23456789012}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>YAZE</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>YAZE</ProjectName>
|
||||
<VcpkgEnabled>true</VcpkgEnabled>
|
||||
<VcpkgManifestInstall>true</VcpkgManifestInstall>
|
||||
<VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows</VcpkgTriplet>
|
||||
<VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows</VcpkgTriplet>
|
||||
<VcpkgTriplet Condition="'$(Platform)'=='ARM64'">arm64-windows</VcpkgTriplet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x86'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x86'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
|
||||
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
|
||||
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">
|
||||
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x86'">
|
||||
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">
|
||||
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x64'">
|
||||
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x86'">
|
||||
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|ARM64'">
|
||||
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x86'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x86'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|ARM64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||
</PropertyGroup>'''
|
||||
|
||||
# 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'''
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='{config}|{platform}'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>{debug_flags}</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(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)</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp23</LanguageStandard>
|
||||
<BigObj>true</BigObj>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeLibrary>MultiThreaded{"Debug" if is_debug else ""}DLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>{generate_debug_info}</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>{"false" if is_debug else "true"}</EnableCOMDATFolding>
|
||||
<OptimizeReferences>{"false" if is_debug else "true"}</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>'''
|
||||
|
||||
# Add source files
|
||||
vcxproj_content += '''
|
||||
<ItemGroup>
|
||||
'''
|
||||
for header in header_files:
|
||||
vcxproj_content += f' <ClInclude Include="{header}" />\n'
|
||||
|
||||
vcxproj_content += ''' </ItemGroup>
|
||||
<ItemGroup>
|
||||
'''
|
||||
for source in all_source_files:
|
||||
vcxproj_content += f' <ClCompile Include="src\\{source}" />\n'
|
||||
|
||||
vcxproj_content += ''' </ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CMakeLists.txt" />
|
||||
<None Include="CMakePresets.json" />
|
||||
<None Include="vcpkg.json" />
|
||||
<None Include="README.md" />
|
||||
<None Include="LICENSE" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>'''
|
||||
|
||||
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()
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <vector>
|
||||
|
||||
#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<std::string, void*> 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<uint8_t> rom_data_;
|
||||
|
||||
EmulatorKeybindings keybindings_;
|
||||
|
||||
gui::zeml::Node emulator_node_;
|
||||
};
|
||||
|
||||
} // namespace emu
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -1,621 +0,0 @@
|
||||
|
||||
#include "app/gui/zeml.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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<Token> Tokenize(const std::string& input) {
|
||||
std::vector<Token> 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<std::string, WidgetType> 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<Token>& tokens, size_t& index,
|
||||
const std::map<std::string, void*>& data_bindings,
|
||||
const std::map<std::string, Node>& 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<std::string> 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<std::string, ImGuiWindowFlags> 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<ImGuiWindowFlags>(windowFlags);
|
||||
break;
|
||||
}
|
||||
case WidgetType::CollapsingHeader: {
|
||||
// Create a flag map using the tree node flags
|
||||
static std::map<std::string, ImGuiTreeNodeFlags> 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<ImGuiTreeNodeFlags>(treeFlags);
|
||||
break;
|
||||
}
|
||||
case WidgetType::Table: {
|
||||
// Create a flag map
|
||||
static std::map<std::string, ImGuiTableFlags> 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<ImGuiTableFlags>(tableFlags);
|
||||
} break;
|
||||
case WidgetType::TableSetupColumn: {
|
||||
static std::map<std::string, ImGuiTableColumnFlags> 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<ImGuiTableColumnFlags>(columnFlags);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WidgetAttributes ParseAttributes(
|
||||
const std::vector<Token>& tokens, size_t& index, const WidgetType& type,
|
||||
const std::map<std::string, void*>& 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<std::string, void*>& data_bindings) {
|
||||
size_t index = 0;
|
||||
auto tokens = Tokenize(yazon_input);
|
||||
|
||||
std::map<std::string, Node> 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<Action>& 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<void()> callback) {
|
||||
if (node) {
|
||||
Action action = {ActionType::Click, callback};
|
||||
node->actions.push_back(action);
|
||||
}
|
||||
}
|
||||
|
||||
void BindAction(Node* node, ActionType type, std::function<void()> callback) {
|
||||
if (node) {
|
||||
Action action = {type, callback};
|
||||
node->actions.push_back(action);
|
||||
}
|
||||
}
|
||||
|
||||
void BindSelectable(Node* node, bool* selected,
|
||||
std::function<void()> 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
|
||||
@@ -1,205 +0,0 @@
|
||||
#ifndef YAZE_APP_GUI_ZEML_H
|
||||
#define YAZE_APP_GUI_ZEML_H
|
||||
|
||||
#include <cctype>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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<void> 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<void()> callback;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Tokenize a zeml string
|
||||
*/
|
||||
std::vector<Token> Tokenize(const std::string& input);
|
||||
|
||||
/**
|
||||
* @struct Node
|
||||
* @brief Node for a zeml tree
|
||||
*/
|
||||
struct Node {
|
||||
WidgetType type;
|
||||
WidgetAttributes attributes;
|
||||
std::vector<Action> actions;
|
||||
std::vector<Node> 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<void()> callback);
|
||||
|
||||
/**
|
||||
* @brief Bind an action to a node
|
||||
*/
|
||||
void BindAction(Node* node, ActionType type, std::function<void()> callback);
|
||||
|
||||
/**
|
||||
* @brief Bind a selectable node
|
||||
*/
|
||||
void BindSelectable(Node* node, bool* selected, std::function<void()> 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<Token>& tokens, size_t& index, const WidgetType& type,
|
||||
const std::map<std::string, void*>& data_bindings = {});
|
||||
|
||||
/**
|
||||
* @brief Parse a zeml node
|
||||
*/
|
||||
Node ParseNode(const std::vector<Token>& tokens, size_t& index,
|
||||
const std::map<std::string, void*>& data_bindings = {},
|
||||
const std::map<std::string, Node>& definitions = {});
|
||||
|
||||
/**
|
||||
* @brief Parse a zeml string
|
||||
*/
|
||||
Node Parse(const std::string& yazon_input,
|
||||
const std::map<std::string, void*>& data_bindings = {});
|
||||
|
||||
/**
|
||||
* @brief Render a zeml tree
|
||||
*/
|
||||
void Render(Node& node);
|
||||
|
||||
/**
|
||||
* @brief Execute actions for a node
|
||||
*/
|
||||
void ExecuteActions(const std::vector<Action>& actions, ActionType type);
|
||||
|
||||
std::string LoadFile(const std::string& filename);
|
||||
|
||||
} // namespace zeml
|
||||
} // namespace gui
|
||||
} // namespace yaze
|
||||
|
||||
#endif // YAZE_APP_GUI_ZEML_H
|
||||
@@ -3,11 +3,6 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace zelda3 {
|
||||
|
||||
Submodule src/lib/asar updated: 9bd5a49ef0...5fd539cd51
Submodule src/lib/imgui updated: 0ddc36f543...b4514ce64a
Reference in New Issue
Block a user