feat(build-system): enhance CMake configuration and introduce new utility files

- Refactored CMakeLists.txt to streamline project configuration and improve readability.
- Introduced new utility functions in `utils.cmake` for setting compiler flags and managing dependencies.
- Added `dependencies.cmake` to centralize third-party dependency management, enhancing modularity.
- Updated CI workflows to include new build options and improved logging for better feedback during configuration.
- Implemented precompiled headers in various libraries to speed up compilation times.

Benefits:
- Improved maintainability and clarity of the build system.
- Enhanced build performance through precompiled headers.
- Streamlined dependency management for easier integration of third-party libraries.
This commit is contained in:
scawful
2025-10-11 02:44:17 -04:00
parent 31d0337b11
commit f54949bdd8
56 changed files with 2673 additions and 4872 deletions

View File

@@ -1,288 +1,77 @@
include(app/core/core_library.cmake)
include(app/editor/editor_library.cmake)
include(app/gfx/gfx_library.cmake)
include(app/gui/gui_library.cmake)
include(app/zelda3/zelda3_library.cmake)
# This file defines the main `yaze` application executable.
if (APPLE)
add_executable(
yaze
MACOSX_BUNDLE
app/main.cc
# Bundled Resources
${YAZE_RESOURCE_FILES}
)
add_executable(yaze MACOSX_BUNDLE app/main.cc ${YAZE_RESOURCE_FILES})
# Add the app icon to the macOS bundle
set(ICON_FILE "${CMAKE_SOURCE_DIR}/assets/yaze.icns")
target_sources(yaze PRIVATE ${ICON_FILE})
set_source_files_properties(${ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
# Set macOS bundle properties
set_target_properties(yaze PROPERTIES
MACOSX_BUNDLE_ICON_FILE "yaze.icns"
MACOSX_BUNDLE_BUNDLE_NAME "Yaze"
MACOSX_BUNDLE_EXECUTABLE_NAME "yaze"
MACOSX_BUNDLE_GUI_IDENTIFIER "com.scawful.yaze"
MACOSX_BUNDLE_INFO_STRING "Yet Another Zelda3 Editor"
MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_VERSION}"
MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}"
MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_VERSION}"
MACOSX_BUNDLE_COPYRIGHT "Copyright © 2024 scawful. All rights reserved."
)
else()
# Windows/Linux builds
add_executable(
yaze
app/main.cc
)
# Add asset files for Windows/Linux builds
add_executable(yaze app/main.cc)
if(WIN32 OR UNIX)
target_sources(yaze PRIVATE ${YAZE_RESOURCE_FILES})
# Set up asset deployment for Visual Studio
if(WIN32)
foreach(ASSET_FILE ${YAZE_RESOURCE_FILES})
file(RELATIVE_PATH ASSET_REL_PATH "${CMAKE_SOURCE_DIR}/assets" ${ASSET_FILE})
get_filename_component(ASSET_DIR ${ASSET_REL_PATH} DIRECTORY)
set_source_files_properties(${ASSET_FILE}
PROPERTIES
VS_DEPLOYMENT_CONTENT 1
VS_DEPLOYMENT_LOCATION "assets/${ASSET_DIR}"
)
endforeach()
endif()
endif()
endif()
target_include_directories(
yaze PUBLIC
${CMAKE_SOURCE_DIR}/src/lib/
${CMAKE_SOURCE_DIR}/src/app/
${CMAKE_SOURCE_DIR}/src/lib/asar/src
${CMAKE_SOURCE_DIR}/src/lib/asar/src/asar
${CMAKE_SOURCE_DIR}/src/lib/asar/src/asar-dll-bindings/c
${CMAKE_SOURCE_DIR}/incl/
${CMAKE_SOURCE_DIR}/src/
${CMAKE_SOURCE_DIR}/src/lib/imgui_test_engine
${CMAKE_SOURCE_DIR}/third_party/httplib
${SDL2_INCLUDE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
target_include_directories(yaze PUBLIC
${CMAKE_SOURCE_DIR}/src
${CMAKE_SOURCE_DIR}/incl
${PROJECT_BINARY_DIR}
)
target_sources(yaze PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/yaze_config.h)
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/yaze_config.h PROPERTIES GENERATED TRUE)
# 4) Tell the IDE its generated
set_source_files_properties(
${CMAKE_CURRENT_BINARY_DIR}/yaze_config.h
PROPERTIES GENERATED TRUE
# Link modular libraries
target_link_libraries(yaze PRIVATE
yaze_editor
yaze_emulator
yaze_agent
absl::failure_signal_handler
absl::flags
absl::flags_parse
)
# (Optional) put it under a neat filter in VS Solution Explorer
source_group(TREE ${CMAKE_CURRENT_BINARY_DIR}
FILES ${CMAKE_CURRENT_BINARY_DIR}/yaze_config.h)
# Conditionally add PNG include dirs if available
if(PNG_FOUND)
target_include_directories(yaze PUBLIC ${PNG_INCLUDE_DIRS})
if(YAZE_BUILD_TESTS AND TARGET yaze_test_support)
target_link_libraries(yaze PRIVATE yaze_test_support)
endif()
# Conditionally link nfd if available
if(YAZE_HAS_NFD)
target_link_libraries(yaze PRIVATE nfd)
target_compile_definitions(yaze PRIVATE YAZE_ENABLE_NFD=1)
else()
target_compile_definitions(yaze PRIVATE YAZE_ENABLE_NFD=0)
endif()
if(YAZE_USE_MODULAR_BUILD)
set(_yaze_modular_links yaze_editor)
if(TARGET yaze_agent)
list(APPEND _yaze_modular_links yaze_agent)
endif()
if(YAZE_BUILD_EMU AND TARGET yaze_emulator)
list(APPEND _yaze_modular_links yaze_emulator)
endif()
# Link once against the editor library and allow its PUBLIC dependencies
# (core, gfx, util, absl, etc.) to propagate transitively. This avoids
# duplicate static archives on the link line while keeping absl symbols
# available for main and other entry points.
target_link_libraries(yaze PRIVATE ${_yaze_modular_links})
else()
target_link_libraries(yaze PRIVATE yaze_core)
endif()
# Enable policy framework in main yaze target
target_compile_definitions(yaze PRIVATE YAZE_ENABLE_POLICY_FRAMEWORK=1)
# Increase stack size on Windows to prevent stack overflow during asset loading
# Windows default is 1MB, macOS/Linux is typically 8MB
# LoadAssets() loads 223 graphics sheets and initializes multiple editors
# Platform-specific settings
if(WIN32)
if(MSVC)
# Set Windows subsystem to WINDOWS (GUI app, no console)
# But keep main() as entry point (SDL_MAIN_HANDLED is set globally)
target_link_options(yaze PRIVATE
/STACK:8388608 # 8MB stack
/SUBSYSTEM:WINDOWS # Windows GUI subsystem
/ENTRY:mainCRTStartup # Use main() instead of WinMain()
)
message(STATUS "Configuring yaze as Windows GUI application with main() entry point")
target_link_options(yaze PRIVATE /STACK:8388608 /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup)
elseif(MINGW OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_link_options(yaze PRIVATE
-Wl,--stack,8388608 # 8MB stack
-Wl,--subsystem,windows # Windows GUI subsystem
-Wl,-emain # Use main() as entry point
)
message(STATUS "Configuring yaze as Windows GUI application with main() entry point (MinGW)")
target_link_options(yaze PRIVATE -Wl,--stack,8388608 -Wl,--subsystem,windows -Wl,-emain)
endif()
endif()
# Conditionally link ImGui Test Engine
if(YAZE_ENABLE_UI_TESTS)
if(TARGET ImGuiTestEngine)
target_include_directories(yaze PUBLIC ${CMAKE_SOURCE_DIR}/src/lib/imgui_test_engine)
target_link_libraries(yaze PUBLIC ImGuiTestEngine)
target_compile_definitions(yaze PRIVATE
YAZE_ENABLE_IMGUI_TEST_ENGINE=1
${IMGUI_TEST_ENGINE_DEFINITIONS})
else()
target_compile_definitions(yaze PRIVATE YAZE_ENABLE_IMGUI_TEST_ENGINE=0)
endif()
else()
target_compile_definitions(yaze PRIVATE YAZE_ENABLE_IMGUI_TEST_ENGINE=0)
endif()
# Link Google Test if available for integrated testing (but NOT gtest_main to avoid main() conflicts)
if(YAZE_BUILD_TESTS AND TARGET gtest)
target_link_libraries(yaze PRIVATE gtest)
target_compile_definitions(yaze PRIVATE YAZE_ENABLE_GTEST=1)
target_compile_definitions(yaze PRIVATE YAZE_ENABLE_TESTING=1)
else()
target_compile_definitions(yaze PRIVATE YAZE_ENABLE_GTEST=0)
target_compile_definitions(yaze PRIVATE YAZE_ENABLE_TESTING=0)
endif()
# Conditionally link PNG if available
if(PNG_FOUND)
target_link_libraries(yaze PUBLIC ${PNG_LIBRARIES})
endif()
if (APPLE)
target_link_libraries(yaze PUBLIC ${COCOA_LIBRARY})
endif()
# Post-build step to copy assets to output directory
if(APPLE)
# macOS: Copy to bundle Resources
target_link_libraries(yaze PUBLIC "-framework Cocoa")
endif()
# Post-build asset copying for non-macOS platforms
if(NOT APPLE)
add_custom_command(TARGET yaze POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory
$<TARGET_FILE_DIR:yaze>/../Resources/agent
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/assets/agent
$<TARGET_FILE_DIR:yaze>/../Resources/agent
COMMENT "Copying agent assets to macOS bundle"
)
elseif(NOT APPLE)
# Add post-build commands directly to the yaze target
# Copy fonts
add_custom_command(TARGET yaze POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory
$<TARGET_FILE_DIR:yaze>/assets/font
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/assets/font
$<TARGET_FILE_DIR:yaze>/assets/font
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/assets/font $<TARGET_FILE_DIR:yaze>/assets/font
COMMENT "Copying font assets"
)
# Copy themes
add_custom_command(TARGET yaze POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory
$<TARGET_FILE_DIR:yaze>/assets/themes
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/assets/themes
$<TARGET_FILE_DIR:yaze>/assets/themes
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/assets/themes $<TARGET_FILE_DIR:yaze>/assets/themes
COMMENT "Copying theme assets"
)
# Copy agent assets (system prompts, etc.)
if(EXISTS ${CMAKE_SOURCE_DIR}/assets/agent)
add_custom_command(TARGET yaze POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory
$<TARGET_FILE_DIR:yaze>/assets/agent
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/assets/agent
$<TARGET_FILE_DIR:yaze>/assets/agent
COMMENT "Copying agent assets (prompts, schemas)"
)
endif()
# Copy other assets if they exist
if(EXISTS ${CMAKE_SOURCE_DIR}/assets/layouts)
add_custom_command(TARGET yaze POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory
$<TARGET_FILE_DIR:yaze>/assets/layouts
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/assets/layouts
$<TARGET_FILE_DIR:yaze>/assets/layouts
COMMENT "Copying layout assets"
)
endif()
if(EXISTS ${CMAKE_SOURCE_DIR}/assets/lib)
add_custom_command(TARGET yaze POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory
$<TARGET_FILE_DIR:yaze>/assets/lib
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/assets/lib
$<TARGET_FILE_DIR:yaze>/assets/lib
COMMENT "Copying library assets"
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/assets/agent $<TARGET_FILE_DIR:yaze>/assets/agent
COMMENT "Copying agent assets"
)
endif()
endif()
# ============================================================================
# Optional gRPC Support for ImGuiTestHarness
# ============================================================================
if(YAZE_WITH_GRPC)
message(STATUS "Adding gRPC ImGuiTestHarness to yaze target")
target_include_directories(yaze PRIVATE
${CMAKE_SOURCE_DIR}/third_party/json/include)
target_compile_definitions(yaze PRIVATE YAZE_WITH_JSON)
if(NOT YAZE_USE_MODULAR_BUILD)
# Generate C++ code from .proto using the helper function from cmake/grpc.cmake
target_add_protobuf(yaze
${CMAKE_SOURCE_DIR}/src/protos/imgui_test_harness.proto
${CMAKE_SOURCE_DIR}/src/protos/canvas_automation.proto)
# Add service implementation sources
target_sources(yaze PRIVATE
${CMAKE_SOURCE_DIR}/src/app/core/service/imgui_test_harness_service.cc
${CMAKE_SOURCE_DIR}/src/app/core/service/imgui_test_harness_service.h
${CMAKE_SOURCE_DIR}/src/app/core/service/screenshot_utils.cc
${CMAKE_SOURCE_DIR}/src/app/core/service/screenshot_utils.h
${CMAKE_SOURCE_DIR}/src/app/core/service/widget_discovery_service.cc
${CMAKE_SOURCE_DIR}/src/app/core/service/widget_discovery_service.h
${CMAKE_SOURCE_DIR}/src/app/core/testing/test_recorder.cc
${CMAKE_SOURCE_DIR}/src/app/core/testing/test_recorder.h
${CMAKE_SOURCE_DIR}/src/app/core/testing/test_script_parser.cc
${CMAKE_SOURCE_DIR}/src/app/core/testing/test_script_parser.h)
endif()
# Link gRPC libraries
target_link_libraries(yaze PRIVATE
grpc++
grpc++_reflection
libprotobuf)
message(STATUS "✓ gRPC ImGuiTestHarness integrated")
message(STATUS "✓ AI Agent services integrated into yaze GUI")
endif()

View File

@@ -1,10 +1,9 @@
set(
YAZE_APP_CORE_SRC
app/core/asar_wrapper.cc
app/core/controller.cc
app/emu/emulator.cc
app/core/project.cc
app/core/window.cc
app/core/asar_wrapper.cc
)
if (WIN32 OR MINGW OR (UNIX AND NOT APPLE))
@@ -16,13 +15,37 @@ endif()
if(APPLE)
list(APPEND YAZE_APP_CORE_SRC
app/platform/file_dialog.mm
app/platform/app_delegate.mm
app/platform/font_loader.cc
app/platform/font_loader.mm
app/platform/asset_loader.cc
)
set(YAZE_APPLE_OBJCXX_SRC
app/platform/file_dialog.mm
app/platform/app_delegate.mm
app/platform/font_loader.mm
)
add_library(yaze_core_objcxx OBJECT ${YAZE_APPLE_OBJCXX_SRC})
set_target_properties(yaze_core_objcxx PROPERTIES
OBJCXX_STANDARD 20
OBJCXX_STANDARD_REQUIRED ON
)
target_include_directories(yaze_core_objcxx PUBLIC
${CMAKE_SOURCE_DIR}/src
${CMAKE_SOURCE_DIR}/src/app
${CMAKE_SOURCE_DIR}/src/lib
${CMAKE_SOURCE_DIR}/src/lib/imgui
${CMAKE_SOURCE_DIR}/src/lib/asar/src
${CMAKE_SOURCE_DIR}/src/lib/asar/src/asar
${CMAKE_SOURCE_DIR}/src/lib/asar/src/asar-dll-bindings/c
${CMAKE_SOURCE_DIR}/incl
${SDL2_INCLUDE_DIR}
${PROJECT_BINARY_DIR}
)
target_link_libraries(yaze_core_objcxx PUBLIC ${ABSL_TARGETS} yaze_util)
target_compile_definitions(yaze_core_objcxx PUBLIC MACOS)
find_library(COCOA_LIBRARY Cocoa)
if(NOT COCOA_LIBRARY)
message(FATAL_ERROR "Cocoa not found")
@@ -48,6 +71,11 @@ endif()
add_library(yaze_core_lib STATIC
app/rom.cc
${YAZE_APP_CORE_SRC}
$<$<BOOL:${APPLE}>:$<TARGET_OBJECTS:yaze_core_objcxx>>
)
target_precompile_headers(yaze_core_lib PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_SOURCE_DIR}/src/yaze_pch.h>"
)
target_include_directories(yaze_core_lib PUBLIC

View File

@@ -17,7 +17,8 @@ namespace {
constexpr absl::Duration kTestCompletionTimeout = absl::Seconds(10);
constexpr absl::Duration kPollInterval = absl::Milliseconds(50);
const char* HarnessStatusToString(HarnessTestStatus status) {
#if defined(YAZE_WITH_GRPC)
const char* HarnessStatusToString(test::HarnessTestStatus status) {
switch (status) {
case HarnessTestStatus::kQueued:
return "queued";
@@ -31,9 +32,10 @@ const char* HarnessStatusToString(HarnessTestStatus status) {
return "timeout";
case HarnessTestStatus::kUnspecified:
default:
return "unknown";
return "unspecified";
}
}
#endif // defined(YAZE_WITH_GRPC)
} // namespace
@@ -152,7 +154,11 @@ absl::StatusOr<TestRecorder::StopRecordingSummary> TestRecorder::StopLocked(
script_step.region = step.region;
script_step.format = step.format;
script_step.expect_success = step.success;
#if defined(YAZE_WITH_GRPC)
script_step.expect_status = ::yaze::test::HarnessStatusToString(step.final_status);
#else
script_step.expect_status.clear();
#endif
if (!step.final_error_message.empty()) {
script_step.expect_message = step.final_error_message;
} else {
@@ -194,6 +200,9 @@ absl::Status TestRecorder::PopulateFinalStatusLocked() {
return absl::FailedPreconditionError("TestManager unavailable");
}
#if !defined(YAZE_WITH_GRPC)
return absl::OkStatus();
#else
for (auto& step : steps_) {
if (step.test_id.empty()) {
continue;
@@ -201,7 +210,7 @@ absl::Status TestRecorder::PopulateFinalStatusLocked() {
const absl::Time deadline = absl::Now() + kTestCompletionTimeout;
while (absl::Now() < deadline) {
absl::StatusOr<HarnessTestExecution> execution =
absl::StatusOr<test::HarnessTestExecution> execution =
test_manager_->GetHarnessTestExecution(step.test_id);
if (!execution.ok()) {
absl::SleepFor(kPollInterval);
@@ -213,8 +222,8 @@ absl::Status TestRecorder::PopulateFinalStatusLocked() {
step.assertion_failures = execution->assertion_failures;
step.metrics = execution->metrics;
if (execution->status == HarnessTestStatus::kQueued ||
execution->status == HarnessTestStatus::kRunning) {
if (execution->status == test::HarnessTestStatus::kQueued ||
execution->status == test::HarnessTestStatus::kRunning) {
absl::SleepFor(kPollInterval);
continue;
}
@@ -223,6 +232,7 @@ absl::Status TestRecorder::PopulateFinalStatusLocked() {
}
return absl::OkStatus();
#endif // defined(YAZE_WITH_GRPC)
}
std::string TestRecorder::GenerateRecordingId() {

View File

@@ -52,7 +52,9 @@ class TestRecorder {
std::vector<std::string> assertion_failures;
std::string expected_value;
std::string actual_value;
#if defined(YAZE_WITH_GRPC)
HarnessTestStatus final_status = HarnessTestStatus::kUnspecified;
#endif
std::string final_error_message;
std::map<std::string, int32_t> metrics;
absl::Time captured_at = absl::InfinitePast();

View File

@@ -38,9 +38,9 @@ AgentUITheme AgentUITheme::FromCurrentTheme() {
);
// Content colors
theme.json_text_color = ImVec4(0.78f, 0.83f, 0.90f, 1.0f);
theme.command_text_color = ImVec4(1.0f, 0.647f, 0.0f, 1.0f);
theme.code_bg_color = ImVec4(0.08f, 0.08f, 0.10f, 0.95f);
theme.json_text_color = ConvertColorToImVec4(current.text_secondary);
theme.command_text_color = ConvertColorToImVec4(current.accent);
theme.code_bg_color = ConvertColorToImVec4(current.code_background);
theme.text_secondary_color = ConvertColorToImVec4(current.text_secondary);

View File

@@ -1,46 +1,55 @@
set(
YAZE_APP_EDITOR_SRC
app/editor/editor_manager.cc
app/editor/ui/menu_builder.cc
app/editor/ui/editor_selection_dialog.cc
app/editor/ui/welcome_screen.cc
app/editor/ui/workspace_manager.cc
app/editor/system/user_settings.cc
app/editor/ui/background_renderer.cc
app/editor/dungeon/dungeon_editor_v2.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_room_loader.cc
app/editor/dungeon/dungeon_usage_tracker.cc
app/editor/dungeon/object_editor_card.cc
app/editor/overworld/overworld_editor.cc
app/editor/overworld/scratch_space.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/agent/agent_chat_history_codec.cc
app/editor/agent/agent_chat_history_popup.cc
app/editor/agent/agent_chat_widget.cc
app/editor/agent/agent_collaboration_coordinator.cc
app/editor/agent/agent_editor.cc
app/editor/agent/agent_ui_theme.cc
app/editor/agent/automation_bridge.cc
app/editor/agent/network_collaboration_coordinator.cc
app/editor/code/assembly_editor.cc
app/editor/code/memory_editor.cc
app/editor/code/project_file_editor.cc
app/editor/graphics/screen_editor.cc
app/editor/dungeon/dungeon_canvas_viewer.cc
app/editor/dungeon/dungeon_editor_v2.cc
app/editor/dungeon/dungeon_object_interaction.cc
app/editor/dungeon/dungeon_object_selector.cc
app/editor/dungeon/dungeon_room_loader.cc
app/editor/dungeon/dungeon_room_selector.cc
app/editor/dungeon/dungeon_toolset.cc
app/editor/dungeon/dungeon_usage_tracker.cc
app/editor/dungeon/object_editor_card.cc
app/editor/editor_manager.cc
app/editor/graphics/gfx_group_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/graphics/screen_editor.cc
app/editor/message/message_data.cc
app/editor/message/message_editor.cc
app/editor/message/message_preview.cc
app/editor/music/music_editor.cc
app/editor/overworld/entity.cc
app/editor/overworld/map_properties.cc
app/editor/overworld/overworld_editor.cc
app/editor/overworld/overworld_entity_renderer.cc
app/editor/system/settings_editor.cc
app/editor/overworld/scratch_space.cc
app/editor/overworld/tile16_editor.cc
app/editor/sprite/sprite_editor.cc
app/editor/system/command_manager.cc
app/editor/system/command_palette.cc
app/editor/system/extension_manager.cc
app/editor/system/shortcut_manager.cc
app/editor/system/popup_manager.cc
app/editor/system/proposal_drawer.cc
app/editor/agent/agent_chat_history_codec.cc
app/editor/system/settings_editor.cc
app/editor/system/shortcut_manager.cc
app/editor/system/user_settings.cc
app/editor/ui/background_renderer.cc
app/editor/ui/editor_selection_dialog.cc
app/editor/ui/menu_builder.cc
app/editor/ui/menu_manager.cc
app/editor/ui/welcome_screen.cc
app/editor/ui/workspace_manager.cc
)
if(YAZE_WITH_GRPC)
@@ -76,12 +85,7 @@ endif()
add_library(yaze_editor STATIC ${YAZE_APP_EDITOR_SRC})
target_precompile_headers(yaze_editor PRIVATE
<array>
<cstdint>
<memory>
<set>
<string>
<vector>
"$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_SOURCE_DIR}/src/yaze_pch.h>"
)
target_include_directories(yaze_editor PUBLIC

View File

@@ -1337,9 +1337,71 @@ void EditorManager::BuildModernMenu() {
menu_builder_.Draw();
}
void EditorManager::DrawMenuBarExtras() {
auto* current_rom = GetCurrentRom();
std::string version_text = absl::StrFormat("v%s", version_.c_str());
float version_width = ImGui::CalcTextSize(version_text.c_str()).x;
float session_rom_area_width = 280.0f;
SameLine(ImGui::GetWindowWidth() - version_width - 10 - session_rom_area_width);
if (GetActiveSessionCount() > 1) {
if (ImGui::SmallButton(absl::StrFormat("%s%zu", ICON_MD_TAB, GetActiveSessionCount()).c_str())) {
ShowSessionSwitcher();
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Sessions: %zu active\nClick to switch", GetActiveSessionCount());
}
ImGui::SameLine();
}
if (current_rom && current_rom->is_loaded()) {
if (ImGui::SmallButton(ICON_MD_APPS)) {
ShowEditorSelection();
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(ICON_MD_DASHBOARD " Editor Selection (Ctrl+E)");
}
ImGui::SameLine();
if (ImGui::SmallButton(ICON_MD_DISPLAY_SETTINGS)) {
ShowDisplaySettings();
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(ICON_MD_TUNE " Display Settings");
}
ImGui::SameLine();
ImGui::Separator();
ImGui::SameLine();
}
if (current_rom && current_rom->is_loaded()) {
std::string rom_display = current_rom->title();
if (rom_display.length() > 22) {
rom_display = rom_display.substr(0, 19) + "...";
}
if (ImGui::SmallButton(absl::StrFormat("%s%s", rom_display.c_str(), current_rom->dirty() ? "*" : "").c_str())) {
ImGui::OpenPopup("ROM Details");
}
} else {
ImGui::TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1.0f), "No ROM");
ImGui::SameLine();
}
SameLine(ImGui::GetWindowWidth() - version_width - 10);
ImGui::Text("%s", version_text.c_str());
}
void EditorManager::ShowSessionSwitcher() { show_session_switcher_ = true; }
void EditorManager::ShowEditorSelection() { show_editor_selection_ = true; }
void EditorManager::ShowDisplaySettings() { if (popup_manager_) popup_manager_->Show("Display Settings"); }
void EditorManager::DrawMenuBar() {
static bool show_display_settings = false;
static bool save_as_menu = false;
std::string version_text = absl::StrFormat("v%s", version_.c_str());
float version_width = ImGui::CalcTextSize(version_text.c_str()).x;
if (BeginMenuBar()) {
BuildModernMenu();
@@ -1347,173 +1409,7 @@ void EditorManager::DrawMenuBar() {
// Inline ROM selector and status
status_ = DrawRomSelector();
// Calculate proper right-side positioning
std::string version_text = absl::StrFormat("v%s", version_.c_str());
float version_width = CalcTextSize(version_text.c_str()).x;
// Allocate space for ROM status and sessions (wider for better ROM title display)
float session_rom_area_width = 280.0f; // Increased for wider ROM title
SameLine(GetWindowWidth() - version_width - 10 - session_rom_area_width);
// Multi-session indicator
if (sessions_.size() > 1) {
if (SmallButton(absl::StrFormat("%s%zu", ICON_MD_TAB, sessions_.size())
.c_str())) {
show_session_switcher_ = true;
}
if (IsItemHovered()) {
SetTooltip("Sessions: %zu active\nClick to switch", sessions_.size());
}
SameLine();
}
// Editor selection and display settings quick buttons (when ROM loaded)
if (current_rom_ && current_rom_->is_loaded()) {
// Editor selection button
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.3f, 0.3f, 0.4f, 0.8f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.4f, 0.4f, 0.5f, 1.0f));
if (SmallButton(ICON_MD_APPS)) {
show_editor_selection_ = true;
}
ImGui::PopStyleColor(2);
if (IsItemHovered()) {
SetTooltip(ICON_MD_DASHBOARD " Editor Selection (Ctrl+E)");
}
SameLine();
// Display settings button
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.3f, 0.3f, 0.4f, 0.8f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.4f, 0.4f, 0.5f, 1.0f));
if (SmallButton(ICON_MD_DISPLAY_SETTINGS)) {
show_display_settings = !show_display_settings;
}
ImGui::PopStyleColor(2);
if (IsItemHovered()) {
SetTooltip(ICON_MD_TUNE " Display Settings");
}
SameLine();
ImGui::Separator();
SameLine();
}
// Compact ROM status with metadata popup
if (current_rom_ && current_rom_->is_loaded()) {
// Truncate long ROM titles for wider display
std::string rom_display = current_rom_->title();
if (rom_display.length() > 22) {
rom_display = rom_display.substr(0, 19) + "...";
}
ImVec4 status_color =
current_rom_->dirty() ? ImVec4(1.0f, 0.5f, 0.0f, 1.0f)
: // Orange for modified
ImVec4(0.0f, 0.8f, 0.0f, 1.0f); // Green for clean
// Compact ROM status button
if (SmallButton(absl::StrFormat("%s%s", rom_display.c_str(),
current_rom_->dirty() ? "*" : "")
.c_str())) {
ImGui::OpenPopup("ROM Details");
}
// Enhanced tooltip on hover
if (IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::Text("%s ROM Information", ICON_MD_INFO);
ImGui::Separator();
ImGui::Text("%s Title: %s", ICON_MD_TITLE,
current_rom_->title().c_str());
ImGui::Text("%s File: %s", ICON_MD_FOLDER_OPEN,
current_rom_->filename().c_str());
ImGui::Text("%s Size: %.1f MB (%zu bytes)", ICON_MD_STORAGE,
current_rom_->size() / 1048576.0f, current_rom_->size());
ImGui::Text("%s Status: %s",
current_rom_->dirty() ? ICON_MD_EDIT : ICON_MD_CHECK_CIRCLE,
current_rom_->dirty() ? "Modified" : "Clean");
ImGui::Text("%s Click for detailed view", ICON_MD_LAUNCH);
ImGui::EndTooltip();
}
// Detailed ROM popup
if (ImGui::BeginPopup("ROM Details")) {
ImGui::Text("%s ROM Detailed Information", ICON_MD_INFO);
ImGui::Separator();
ImGui::Spacing();
// Basic info with icons
if (ImGui::BeginTable("ROMDetailsTable", 2,
ImGuiTableFlags_SizingFixedFit)) {
ImGui::TableSetupColumn("Property", ImGuiTableColumnFlags_WidthFixed,
120);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("%s Title", ICON_MD_TITLE);
ImGui::TableNextColumn();
ImGui::Text("%s", current_rom_->title().c_str());
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("%s File", ICON_MD_FOLDER_OPEN);
ImGui::TableNextColumn();
ImGui::Text("%s", current_rom_->filename().c_str());
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("%s Size", ICON_MD_STORAGE);
ImGui::TableNextColumn();
ImGui::Text("%.1f MB (%zu bytes)", current_rom_->size() / 1048576.0f,
current_rom_->size());
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("%s Status", current_rom_->dirty()
? ICON_MD_EDIT
: ICON_MD_CHECK_CIRCLE);
ImGui::TableNextColumn();
ImGui::TextColored(status_color, "%s",
current_rom_->dirty() ? "Modified" : "Clean");
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("%s Session", ICON_MD_TAB);
ImGui::TableNextColumn();
size_t current_session_idx = GetCurrentSessionIndex();
ImGui::Text("Session %zu of %zu", current_session_idx + 1,
sessions_.size());
ImGui::EndTable();
}
ImGui::Spacing();
ImGui::Separator();
// Quick actions
ImGui::Text("%s Quick Actions", ICON_MD_FLASH_ON);
if (ImGui::Button(absl::StrFormat("%s Save ROM", ICON_MD_SAVE).c_str(),
ImVec2(120, 0))) {
status_ = SaveRom();
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
if (ImGui::Button(
absl::StrFormat("%s Switch Session", ICON_MD_SWITCH_ACCOUNT)
.c_str(),
ImVec2(120, 0))) {
show_session_switcher_ = true;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
SameLine();
} else {
TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1.0f), "No ROM");
SameLine();
}
DrawMenuBarExtras();
// Version display on far right
SameLine(GetWindowWidth() - version_width - 10);

View File

@@ -122,6 +122,11 @@ class EditorManager {
auto emulator() -> emu::Emulator& { return emulator_; }
auto quit() const { return quit_; }
auto version() const { return version_; }
void DrawMenuBarExtras();
MenuBuilder& menu_builder() { return menu_builder_; }
void ShowSessionSwitcher();
void ShowEditorSelection();
void ShowDisplaySettings();
absl::Status SetCurrentRom(Rom* rom);
auto GetCurrentRom() -> Rom* { return current_rom_; }

View File

@@ -11,63 +11,13 @@ MenuManager::MenuManager(EditorManager* editor_manager)
: editor_manager_(editor_manager) {}
void MenuManager::BuildAndDraw() {
if (!editor_manager_) {
return;
}
if (ImGui::BeginMenuBar()) {
editor_manager_->BuildModernMenu(); // This contains the menu_builder_ logic
editor_manager_->menu_builder_.Draw();
// This is the logic from the second half of DrawMenuBar
auto* current_rom = editor_manager_->GetCurrentRom();
std::string version_text = absl::StrFormat("v%s", editor_manager_->version().c_str());
float version_width = ImGui::CalcTextSize(version_text.c_str()).x;
float session_rom_area_width = 280.0f;
ImGui::SameLine(ImGui::GetWindowWidth() - version_width - 10 - session_rom_area_width);
if (editor_manager_->GetActiveSessionCount() > 1) {
if (ImGui::SmallButton(absl::StrFormat("%s%zu", ICON_MD_TAB, editor_manager_->GetActiveSessionCount()).c_str())) {
editor_manager_->show_session_switcher_ = true;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Sessions: %zu active\nClick to switch", editor_manager_->GetActiveSessionCount());
}
ImGui::SameLine();
}
if (current_rom && current_rom->is_loaded()) {
if (ImGui::SmallButton(ICON_MD_APPS)) {
editor_manager_->show_editor_selection_ = true;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(ICON_MD_DASHBOARD " Editor Selection (Ctrl+E)");
}
ImGui::SameLine();
if (ImGui::SmallButton(ICON_MD_DISPLAY_SETTINGS)) {
editor_manager_->popup_manager_->Show("Display Settings");
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(ICON_MD_TUNE " Display Settings");
}
ImGui::SameLine();
ImGui::Separator();
ImGui::SameLine();
}
if (current_rom && current_rom->is_loaded()) {
std::string rom_display = current_rom->title();
if (rom_display.length() > 22) {
rom_display = rom_display.substr(0, 19) + "...";
}
ImVec4 status_color = current_rom->dirty() ? ImVec4(1.0f, 0.5f, 0.0f, 1.0f) : ImVec4(0.0f, 0.8f, 0.0f, 1.0f);
if (ImGui::SmallButton(absl::StrFormat("%s%s", rom_display.c_str(), current_rom->dirty() ? "*" : "").c_str())) {
ImGui::OpenPopup("ROM Details");
}
// ... (rest of the popup logic from DrawMenuBar)
} else {
ImGui::TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1.0f), "No ROM");
ImGui::SameLine();
}
ImGui::SameLine(ImGui::GetWindowWidth() - version_width - 10);
ImGui::Text("%s", version_text.c_str());
editor_manager_->BuildModernMenu();
editor_manager_->DrawMenuBarExtras();
ImGui::EndMenuBar();
}
}

View File

@@ -16,7 +16,6 @@ class MenuManager {
private:
EditorManager* editor_manager_;
MenuBuilder menu_builder_;
};
} // namespace editor

View File

@@ -1,76 +1,55 @@
# Yaze Emulator Standalone Application (skip in minimal builds)
if (NOT YAZE_MINIMAL_BUILD AND APPLE)
add_executable(
yaze_emu
MACOSX_BUNDLE
app/main.cc
app/rom.cc
app/platform/app_delegate.mm
${YAZE_APP_EMU_SRC}
${YAZE_APP_CORE_SRC}
${YAZE_APP_EDITOR_SRC}
${YAZE_APP_GFX_SRC}
${YAZE_APP_ZELDA3_SRC}
${YAZE_UTIL_SRC}
${YAZE_GUI_SRC}
${IMGUI_SRC}
# CLI service sources (needed for ProposalDrawer)
cli/service/planning/proposal_registry.cc
cli/service/rom/rom_sandbox_manager.cc
)
target_link_libraries(yaze_emu PUBLIC ${COCOA_LIBRARY})
elseif(NOT YAZE_MINIMAL_BUILD)
add_executable(
yaze_emu
app/rom.cc
app/emu/emu.cc
${YAZE_APP_EMU_SRC}
${YAZE_APP_CORE_SRC}
${YAZE_APP_EDITOR_SRC}
${YAZE_APP_GFX_SRC}
${YAZE_APP_ZELDA3_SRC}
${YAZE_UTIL_SRC}
${YAZE_GUI_SRC}
${IMGUI_SRC}
# CLI service sources (needed for ProposalDrawer)
cli/service/planning/proposal_registry.cc
cli/service/rom/rom_sandbox_manager.cc
)
endif()
# This file defines the yaze_emu standalone executable.
# Note: The yaze_emulator library is ALWAYS built (via emu_library.cmake)
# because it's used by the main yaze app and test suites.
# This file only controls the STANDALONE emulator executable.
# Only configure emulator target if it was created
if(NOT YAZE_MINIMAL_BUILD)
target_include_directories(
yaze_emu PUBLIC
${CMAKE_SOURCE_DIR}/src/lib/
${CMAKE_SOURCE_DIR}/src/app/
${CMAKE_SOURCE_DIR}/src/lib/asar/src
${CMAKE_SOURCE_DIR}/src/lib/asar/src/asar
${CMAKE_SOURCE_DIR}/src/lib/asar/src/asar-dll-bindings/c
${CMAKE_SOURCE_DIR}/incl/
${CMAKE_SOURCE_DIR}/src/
${CMAKE_SOURCE_DIR}/src/lib/imgui_test_engine
${PNG_INCLUDE_DIRS}
${SDL2_INCLUDE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
if(YAZE_BUILD_EMU AND NOT YAZE_MINIMAL_BUILD)
if(APPLE)
add_executable(yaze_emu MACOSX_BUNDLE app/emu/emu.cc app/platform/app_delegate.mm)
target_link_libraries(yaze_emu PUBLIC "-framework Cocoa")
else()
add_executable(yaze_emu app/emu/emu.cc)
endif()
target_include_directories(yaze_emu PUBLIC
${CMAKE_SOURCE_DIR}/src
${CMAKE_SOURCE_DIR}/incl
${PROJECT_BINARY_DIR}
)
target_link_libraries(
yaze_emu PUBLIC
${ABSL_TARGETS}
${SDL_TARGETS}
${PNG_LIBRARIES}
${CMAKE_DL_LIBS}
ImGui
asar-static
target_link_libraries(yaze_emu PRIVATE
yaze_editor
yaze_emulator
yaze_agent
yaze_test_support
absl::flags
absl::flags_parse
absl::failure_signal_handler
)
# Conditionally link ImGui Test Engine
if(YAZE_ENABLE_UI_TESTS)
target_link_libraries(yaze_emu PUBLIC ImGuiTestEngine)
target_compile_definitions(yaze_emu PRIVATE YAZE_ENABLE_IMGUI_TEST_ENGINE=1)
else()
target_compile_definitions(yaze_emu PRIVATE YAZE_ENABLE_IMGUI_TEST_ENGINE=0)
endif()
# Headless Emulator Test Harness
add_executable(yaze_emu_test emu_test.cc)
target_include_directories(yaze_emu_test PRIVATE
${CMAKE_SOURCE_DIR}/src
${CMAKE_SOURCE_DIR}/incl
${PROJECT_BINARY_DIR}
)
target_link_libraries(yaze_emu_test PRIVATE
yaze_emulator
yaze_util
absl::flags
absl::flags_parse
absl::status
absl::strings
absl::str_format
)
message(STATUS "✓ yaze_emu_test: Headless emulator test harness configured")
message(STATUS "✓ yaze_emu: Standalone emulator executable configured")
else()
message(STATUS "○ Standalone emulator builds disabled (YAZE_BUILD_EMU=OFF or YAZE_MINIMAL_BUILD=ON)")
message(STATUS " Note: yaze_emulator library still available for main app and tests")
endif()

View File

@@ -13,6 +13,10 @@
add_library(yaze_emulator STATIC ${YAZE_APP_EMU_SRC})
target_precompile_headers(yaze_emulator PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_SOURCE_DIR}/src/yaze_pch.h>"
)
target_include_directories(yaze_emulator PUBLIC
${CMAKE_SOURCE_DIR}/src
${CMAKE_SOURCE_DIR}/src/app

View File

@@ -36,9 +36,7 @@ set(
add_library(yaze_gfx STATIC ${YAZE_APP_GFX_SRC})
target_precompile_headers(yaze_gfx PRIVATE
<vector>
<string>
<memory>
"$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_SOURCE_DIR}/src/yaze_pch.h>"
)
target_include_directories(yaze_gfx PUBLIC

View File

@@ -1,33 +1,34 @@
set(
YAZE_GUI_SRC
app/gui/canvas.cc
app/gui/canvas/bpp_format_ui.cc
app/gui/canvas/canvas_automation_api.cc
app/gui/canvas/canvas_context_menu.cc
app/gui/canvas/canvas_interaction_handler.cc
app/gui/canvas/canvas_modals.cc
app/gui/canvas/canvas_performance_integration.cc
app/gui/canvas/canvas_usage_tracker.cc
app/gui/canvas/canvas_utils.cc
app/gui/color.cc
app/gui/editor_card_manager.cc
app/gui/editor_layout.cc
app/gui/input.cc
app/gui/modules/asset_browser.cc
app/gui/modules/text_editor.cc
app/gui/widgets/agent_chat_widget.cc
app/gui/widgets/dungeon_object_emulator_preview.cc
app/gui/widgets/collaboration_panel.cc
app/gui/canvas.cc
app/gui/canvas/canvas_utils.cc
app/gui/widgets/palette_widget.cc
app/gui/widgets/palette_editor_widget.cc
app/gui/input.cc
app/gui/style.cc
app/gui/color.cc
app/gui/theme_manager.cc
app/gui/canvas/bpp_format_ui.cc
app/gui/widgets/widget_id_registry.cc
app/gui/widgets/widget_auto_register.cc
app/gui/widgets/widget_state_capture.cc
app/gui/ui_helpers.cc
app/gui/editor_layout.cc
app/gui/editor_card_manager.cc
# Canvas system components
app/gui/canvas/canvas_modals.cc
app/gui/canvas/canvas_context_menu.cc
app/gui/canvas/canvas_usage_tracker.cc
app/gui/canvas/canvas_performance_integration.cc
app/gui/canvas/canvas_interaction_handler.cc
app/gui/canvas/canvas_automation_api.cc
app/gui/widgets/agent_chat_widget.cc
app/gui/widgets/collaboration_panel.cc
app/gui/widgets/dungeon_object_emulator_preview.cc
app/gui/widgets/palette_editor_widget.cc
app/gui/widgets/palette_widget.cc
app/gui/widgets/tile_selector_widget.cc
app/gui/widgets/widget_auto_register.cc
app/gui/widgets/widget_id_registry.cc
app/gui/widgets/widget_measurement.cc
app/gui/widgets/widget_state_capture.cc
# Canvas system components
)
# ==============================================================================
@@ -47,12 +48,7 @@ set(
add_library(yaze_gui STATIC ${YAZE_GUI_SRC})
target_precompile_headers(yaze_gui PRIVATE
<array>
<memory>
<set>
<string>
<string_view>
<vector>
"$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_SOURCE_DIR}/src/yaze_pch.h>"
)
target_include_directories(yaze_gui PUBLIC

View File

@@ -67,6 +67,8 @@ void EnhancedTheme::ApplyToImGui() const {
colors[ImGuiCol_Tab] = ConvertColorToImVec4(tab);
colors[ImGuiCol_TabHovered] = ConvertColorToImVec4(tab_hovered);
colors[ImGuiCol_TabSelected] = ConvertColorToImVec4(tab_active);
colors[ImGuiCol_TabUnfocused] = ConvertColorToImVec4(tab_unfocused);
colors[ImGuiCol_TabUnfocusedActive] = ConvertColorToImVec4(tab_unfocused_active);
colors[ImGuiCol_DockingPreview] = ConvertColorToImVec4(docking_preview);
colors[ImGuiCol_DockingEmptyBg] = ConvertColorToImVec4(docking_empty_bg);
@@ -170,6 +172,8 @@ void ThemeManager::CreateFallbackYazeClassic() {
theme.tab = RGBA(46, 66, 46); // alttpDarkGreen
theme.tab_hovered = RGBA(71, 92, 71); // alttpMidGreen
theme.tab_active = RGBA(89, 119, 89); // TabActive
theme.tab_unfocused = RGBA(37, 52, 37); // Darker version of tab
theme.tab_unfocused_active = RGBA(62, 83, 62); // Darker version of tab_active
// Complete all remaining ImGui colors from original ColorsYaze() function
theme.title_bg = RGBA(71, 92, 71); // alttpMidGreen
@@ -875,6 +879,8 @@ void ThemeManager::ApplyClassicYazeTheme() {
classic_theme.tab = RGBA(46, 66, 46); // alttpDarkGreen
classic_theme.tab_hovered = RGBA(71, 92, 71); // alttpMidGreen
classic_theme.tab_active = RGBA(89, 119, 89); // TabActive
classic_theme.tab_unfocused = RGBA(37, 52, 37); // Darker version of tab
classic_theme.tab_unfocused_active = RGBA(62, 83, 62); // Darker version of tab_active
// Complete all remaining ImGui colors from original ColorsYaze() function
classic_theme.title_bg = RGBA(71, 92, 71); // alttpMidGreen
@@ -1432,6 +1438,8 @@ void ThemeManager::ShowSimpleThemeEditor(bool* p_open) {
{"Tab", &edit_theme.tab},
{"Tab Hovered", &edit_theme.tab_hovered},
{"Tab Active", &edit_theme.tab_active},
{"Tab Unfocused", &edit_theme.tab_unfocused},
{"Tab Unfocused Active", &edit_theme.tab_unfocused_active},
{"Tab Dimmed", &edit_theme.tab_dimmed},
{"Tab Dimmed Selected", &edit_theme.tab_dimmed_selected},
{"Title Background", &edit_theme.title_bg},

View File

@@ -108,6 +108,8 @@ struct EnhancedTheme {
Color tree_lines;
// Additional ImGui colors for complete coverage
Color tab_unfocused;
Color tab_unfocused_active;
Color tab_dimmed;
Color tab_dimmed_selected;
Color tab_dimmed_selected_overline;

View File

@@ -23,6 +23,10 @@ endif()
add_library(yaze_net STATIC ${YAZE_NET_SRC})
target_precompile_headers(yaze_net PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_SOURCE_DIR}/src/yaze_pch.h>"
)
target_include_directories(yaze_net PUBLIC
${CMAKE_SOURCE_DIR}/src
${CMAKE_SOURCE_DIR}/src/lib

View File

@@ -4,6 +4,10 @@
#import "util/file_util.h"
#import "app/editor/editor.h"
#import "app/rom.h"
#include <span>
#include <vector>
using std::span;
#if defined(__APPLE__) && defined(__MACH__)
/* Apple OSX and iOS (Darwin). */

View File

@@ -18,16 +18,13 @@ set(YAZE_TEST_SOURCES
add_library(yaze_test_support STATIC ${YAZE_TEST_SOURCES})
target_precompile_headers(yaze_test_support PRIVATE
<memory>
<set>
<string>
<string_view>
<vector>
"$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_SOURCE_DIR}/src/yaze_pch.h>"
)
target_include_directories(yaze_test_support PUBLIC
${CMAKE_SOURCE_DIR}/src
${CMAKE_SOURCE_DIR}/incl
${CMAKE_SOURCE_DIR}/src/lib
${PROJECT_BINARY_DIR}
)
@@ -41,11 +38,17 @@ target_link_libraries(yaze_test_support PUBLIC
yaze_common
)
# Link agent library if gRPC is enabled (for z3ed test suites)
# Link agent library if available (for z3ed test suites)
# yaze_agent contains all the CLI service code (tile16_proposal_generator, gui_automation_client, etc.)
if(YAZE_WITH_GRPC)
if(TARGET yaze_agent)
target_link_libraries(yaze_test_support PUBLIC yaze_agent)
message(STATUS "✓ z3ed test suites enabled (YAZE_WITH_GRPC=ON)")
if(YAZE_WITH_GRPC)
message(STATUS "✓ z3ed test suites enabled with gRPC support")
else()
message(STATUS "✓ z3ed test suites enabled (without gRPC)")
endif()
else()
message(STATUS "○ z3ed test suites disabled (yaze_agent not built)")
endif()
message(STATUS "✓ yaze_test_support library configured")

View File

@@ -1675,9 +1675,9 @@ absl::Status TestManager::TestRomDataIntegrity(Rom* rom) {
});
}
#if defined(YAZE_WITH_GRPC)
std::string TestManager::RegisterHarnessTest(const std::string& name,
const std::string& category) {
#if defined(YAZE_WITH_GRPC)
absl::MutexLock lock(&harness_history_mutex_);
std::string test_id = absl::StrCat("harness_", absl::ToUnixMicros(absl::Now()), "_", harness_history_.size());
HarnessTestExecution execution;
@@ -1693,12 +1693,15 @@ std::string TestManager::RegisterHarnessTest(const std::string& name,
aggregate.latest_execution = execution;
harness_history_order_.push_back(test_id);
return test_id;
}
#else
std::string TestManager::RegisterHarnessTest(const std::string& name,
const std::string& category) {
(void)name;
(void)category;
return {};
#endif
}
#endif
#if defined(YAZE_WITH_GRPC)
void TestManager::MarkHarnessTestRunning(const std::string& test_id) {
@@ -1852,10 +1855,12 @@ void TestManager::CaptureFailureContext(const std::string& test_id) {
if (harness_listener_) {
harness_listener_->OnHarnessTestUpdated(execution);
}
#else
(void)test_id;
#endif
}
#else
void TestManager::CaptureFailureContext(const std::string& test_id) {
(void)test_id;
}
#endif
#if defined(YAZE_WITH_GRPC)
void TestManager::TrimHarnessHistoryLocked() {
@@ -1870,14 +1875,6 @@ absl::Status TestManager::ReplayLastPlan() {
return absl::FailedPreconditionError("Harness plan replay not available");
}
absl::Status TestManager::ShowHarnessDashboard() {
return absl::OkStatus();
}
absl::Status TestManager::ShowHarnessActiveTests() {
return absl::OkStatus();
}
void TestManager::SetHarnessListener(HarnessListener* listener) {
absl::MutexLock lock(&mutex_);
harness_listener_ = listener;
@@ -1886,15 +1883,24 @@ void TestManager::SetHarnessListener(HarnessListener* listener) {
absl::Status TestManager::ReplayLastPlan() {
return absl::UnimplementedError("Harness features require YAZE_WITH_GRPC");
}
#endif
absl::Status TestManager::ShowHarnessDashboard() {
// These methods are always available, but may return unimplemented without GRPC
#if defined(YAZE_WITH_GRPC)
return absl::OkStatus();
#else
return absl::UnimplementedError("Harness features require YAZE_WITH_GRPC");
#endif
}
absl::Status TestManager::ShowHarnessActiveTests() {
#if defined(YAZE_WITH_GRPC)
return absl::OkStatus();
#else
return absl::UnimplementedError("Harness features require YAZE_WITH_GRPC");
}
#endif
}
void TestManager::RecordPlanSummary(const std::string& summary) {
(void)summary;

View File

@@ -299,8 +299,16 @@ class TestManager {
void SetHarnessListener(HarnessListener* listener);
absl::Status ReplayLastPlan();
#else
// Stub implementations when GRPC is not available
std::string RegisterHarnessTest(const std::string& name,
const std::string& category);
void CaptureFailureContext(const std::string& test_id);
absl::Status ReplayLastPlan();
#endif
// These methods are always available
absl::Status ShowHarnessDashboard();
absl::Status ShowHarnessActiveTests();
void RecordPlanSummary(const std::string& summary);

View File

@@ -1,21 +1,22 @@
set(
YAZE_APP_ZELDA3_SRC
app/zelda3/hyrule_magic.cc
app/zelda3/zelda3_labels.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_drawer.cc
app/zelda3/dungeon/dungeon_editor_system.cc
app/zelda3/dungeon/dungeon_object_editor.cc
app/zelda3/dungeon/object_drawer.cc
app/zelda3/dungeon/object_parser.cc
app/zelda3/dungeon/room.cc
app/zelda3/dungeon/room_layout.cc
app/zelda3/dungeon/room_object.cc
app/zelda3/hyrule_magic.cc
app/zelda3/music/tracker.cc
app/zelda3/overworld/overworld.cc
app/zelda3/overworld/overworld_map.cc
app/zelda3/screen/dungeon_map.cc
app/zelda3/screen/inventory.cc
app/zelda3/screen/title_screen.cc
app/zelda3/sprite/sprite.cc
app/zelda3/sprite/sprite_builder.cc
app/zelda3/zelda3_labels.cc
)
# ==============================================================================
@@ -34,12 +35,7 @@ set(
add_library(yaze_zelda3 STATIC ${YAZE_APP_ZELDA3_SRC})
target_precompile_headers(yaze_zelda3 PRIVATE
<array>
<memory>
<set>
<string>
<string_view>
<vector>
"$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_SOURCE_DIR}/src/yaze_pch.h>"
)
target_include_directories(yaze_zelda3 PUBLIC