From fdb0f18d6a3c69449175ac2174e43097c449d228 Mon Sep 17 00:00:00 2001 From: scawful Date: Thu, 9 Oct 2025 10:54:11 -0400 Subject: [PATCH] feat: Enhance emulator functionality with card registration and UI improvements - Registered multiple emulator cards (CPU Debugger, Memory Viewer, PPU Viewer, Audio Mixer) with the EditorCardManager for improved access and organization. - Updated EditorManager to support the new Emulator editor type in context-sensitive card controls. - Improved GraphicsEditor loading process with enhanced logging and palette management for graphics sheets. - Refactored MessageEditor to streamline font bitmap creation and texture queuing, ensuring better performance and clarity in the rendering loop. --- src/app/editor/editor_manager.cc | 6 ++ src/app/editor/graphics/graphics_editor.cc | 68 +++++++++++++++------- src/app/editor/message/message_editor.cc | 7 ++- src/app/emu/emulator.cc | 41 +++++++++++++ src/app/emu/emulator.h | 13 +++++ src/app/gui/editor_card_manager.cc | 9 +-- 6 files changed, 117 insertions(+), 27 deletions(-) diff --git a/src/app/editor/editor_manager.cc b/src/app/editor/editor_manager.cc index ab1c00ee..0d422108 100644 --- a/src/app/editor/editor_manager.cc +++ b/src/app/editor/editor_manager.cc @@ -952,6 +952,12 @@ void EditorManager::DrawContextSensitiveCardControl() { case EditorType::kAssembly: // Assembly editor uses dynamic file tabs return; + case EditorType::kEmulator: + category = "Emulator"; + break; + case EditorType::kMusic: + // Music editor doesn't use cards yet + return; default: return; // No cards for this editor type } diff --git a/src/app/editor/graphics/graphics_editor.cc b/src/app/editor/graphics/graphics_editor.cc index 0f7b2643..6a9ce72e 100644 --- a/src/app/editor/graphics/graphics_editor.cc +++ b/src/app/editor/graphics/graphics_editor.cc @@ -25,6 +25,7 @@ #include "imgui/imgui.h" #include "imgui/misc/cpp/imgui_stdlib.h" #include "imgui_memory_editor.h" +#include "util/log.h" namespace yaze { namespace editor { @@ -92,6 +93,7 @@ absl::Status GraphicsEditor::Load() { gfx::ScopedTimer timer("GraphicsEditor::Load"); // Initialize all graphics sheets with appropriate palettes from ROM + // This ensures textures are created for editing if (rom()->is_loaded()) { auto& sheets = gfx::Arena::Get().gfx_sheets(); @@ -100,34 +102,56 @@ absl::Status GraphicsEditor::Load() { // Sheets 113-127: Use sprite palettes // Sheets 128-222: Use auxiliary/menu palettes + LOG_INFO("GraphicsEditor", "Initializing textures for %d graphics sheets", kNumGfxSheets); + + int sheets_initialized = 0; for (int i = 0; i < kNumGfxSheets; i++) { - if (sheets[i].is_active() && sheets[i].surface()) { - // Determine which palette group to use based on sheet index - gfx::SnesPalette sheet_palette; - - if (i < 113) { - // Overworld/Dungeon graphics - use main palette - auto palette_group = rom()->palette_group().dungeon_main; - sheet_palette = palette_group[0]; // Use first palette as default - } else if (i < 128) { - // Sprite graphics - use sprite palettes - auto palette_group = rom()->palette_group().sprites_aux1; + if (!sheets[i].is_active() || !sheets[i].surface()) { + continue; // Skip inactive or surface-less sheets + } + + // Determine which palette group to use based on sheet index + gfx::SnesPalette sheet_palette; + + if (i < 113) { + // Overworld/Dungeon graphics - use dungeon main palette + auto palette_group = rom()->palette_group().dungeon_main; + if (palette_group.size() > 0) { sheet_palette = palette_group[0]; - } else { - // Auxiliary graphics - use HUD/menu palettes - sheet_palette = rom()->palette_group().hud.palette(0); } - - // Apply palette and queue texture creation - sheets[i].SetPalette(sheet_palette); - - // Queue texture creation if not already created - if (!sheets[i].texture()) { - gfx::Arena::Get().QueueTextureCommand( - gfx::Arena::TextureCommandType::CREATE, &sheets[i]); + } else if (i < 128) { + // Sprite graphics - use sprite palettes + auto palette_group = rom()->palette_group().sprites_aux1; + if (palette_group.size() > 0) { + sheet_palette = palette_group[0]; + } + } else { + // Auxiliary graphics - use HUD/menu palettes + auto palette_group = rom()->palette_group().hud; + if (palette_group.size() > 0) { + sheet_palette = palette_group.palette(0); } } + + // CRITICAL: Apply palette BEFORE queueing texture creation + // The palette must be set on the surface before creating the texture + if (!sheet_palette.empty()) { + sheets[i].SetPalette(sheet_palette); + sheets_initialized++; + } else { + LOG_WARN("GraphicsEditor", "Sheet %d: Empty palette, skipping", i); + continue; + } + + // Queue texture creation if not already created + if (!sheets[i].texture()) { + gfx::Arena::Get().QueueTextureCommand( + gfx::Arena::TextureCommandType::CREATE, &sheets[i]); + } } + + LOG_INFO("GraphicsEditor", "Initialized %d sheets with palettes, queued for texture creation", + sheets_initialized); } return absl::OkStatus(); diff --git a/src/app/editor/message/message_editor.cc b/src/app/editor/message/message_editor.cc index 09df4e62..bbc91209 100644 --- a/src/app/editor/message/message_editor.cc +++ b/src/app/editor/message/message_editor.cc @@ -114,12 +114,17 @@ void MessageEditor::Initialize() { } message_preview_.font_gfx16_data_ = gfx::SnesTo8bppSheet(raw_font_gfx_data_, /*bpp=*/2, /*num_sheets=*/2); - // Create bitmap and queue texture creation + + // Create bitmap for font graphics font_gfx_bitmap_.Create(kFontGfxMessageSize, kFontGfxMessageSize, kFontGfxMessageDepth, message_preview_.font_gfx16_data_); font_gfx_bitmap_.SetPalette(font_preview_colors_); + + // Queue texture creation - will be processed in render loop gfx::Arena::Get().QueueTextureCommand( gfx::Arena::TextureCommandType::CREATE, &font_gfx_bitmap_); + + printf("[MessageEditor] Font bitmap created and texture queued\n"); *current_font_gfx16_bitmap_.mutable_palette() = font_preview_colors_; auto load_font = LoadFontGraphics(*rom()); diff --git a/src/app/emu/emulator.cc b/src/app/emu/emulator.cc index 5bb2bec6..3ed5c81a 100644 --- a/src/app/emu/emulator.cc +++ b/src/app/emu/emulator.cc @@ -49,6 +49,47 @@ void Emulator::Initialize(gfx::IRenderer* renderer, const std::vector& renderer_ = renderer; rom_data_ = rom_data; + // Register emulator cards with EditorCardManager + auto& card_manager = gui::EditorCardManager::Get(); + + card_manager.RegisterCard({ + .card_id = "emulator.cpu_debugger", + .display_name = "CPU Debugger", + .icon = ICON_MD_BUG_REPORT, + .category = "Emulator", + .visibility_flag = &show_cpu_debugger_, + .priority = 10 + }); + + card_manager.RegisterCard({ + .card_id = "emulator.memory_viewer", + .display_name = "Memory Viewer", + .icon = ICON_MD_MEMORY, + .category = "Emulator", + .visibility_flag = &show_memory_viewer_, + .priority = 20 + }); + + card_manager.RegisterCard({ + .card_id = "emulator.ppu_viewer", + .display_name = "PPU Viewer", + .icon = ICON_MD_GRID_VIEW, + .category = "Emulator", + .visibility_flag = &show_ppu_viewer_, + .priority = 30 + }); + + card_manager.RegisterCard({ + .card_id = "emulator.audio_mixer", + .display_name = "Audio Mixer", + .icon = ICON_MD_AUDIO_FILE, + .category = "Emulator", + .visibility_flag = &show_audio_mixer_, + .priority = 40 + }); + + printf("[Emulator] Registered 4 cards with EditorCardManager\n"); + // Reset state for new ROM running_ = false; snes_initialized_ = false; diff --git a/src/app/emu/emulator.h b/src/app/emu/emulator.h index 3c8e9923..034e4d4b 100644 --- a/src/app/emu/emulator.h +++ b/src/app/emu/emulator.h @@ -7,6 +7,7 @@ #include "app/emu/snes.h" #include "app/emu/audio/audio_backend.h" #include "app/emu/debug/breakpoint_manager.h" +#include "app/gui/editor_card_manager.h" #include "app/emu/debug/disassembly_viewer.h" #include "app/emu/input/input_manager.h" #include "app/rom.h" @@ -36,6 +37,12 @@ class Emulator { void Initialize(gfx::IRenderer* renderer, const std::vector& rom_data); void Run(Rom* rom); void Cleanup(); + + // Card visibility for emulator UI panels + bool& show_cpu_debugger() { return show_cpu_debugger_; } + bool& show_memory_viewer() { return show_memory_viewer_; } + bool& show_ppu_viewer() { return show_ppu_viewer_; } + bool& show_audio_mixer() { return show_audio_mixer_; } auto snes() -> Snes& { return snes_; } auto running() const -> bool { return running_; } @@ -156,6 +163,12 @@ class Emulator { gfx::IRenderer* renderer_ = nullptr; void* ppu_texture_ = nullptr; + // Card visibility states + bool show_cpu_debugger_ = false; + bool show_memory_viewer_ = false; + bool show_ppu_viewer_ = false; + bool show_audio_mixer_ = false; + // Debugger infrastructure BreakpointManager breakpoint_manager_; debug::DisassemblyViewer disassembly_viewer_; diff --git a/src/app/gui/editor_card_manager.cc b/src/app/gui/editor_card_manager.cc index 1ac56212..3981bca4 100644 --- a/src/app/gui/editor_card_manager.cc +++ b/src/app/gui/editor_card_manager.cc @@ -268,15 +268,16 @@ void EditorCardManager::DrawCompactCardControl(const std::string& category) { return; // Nothing to show } - // Draw as a small button with popup menu - 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)); + // Use theme colors for button + ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyleColorVec4(ImGuiCol_Button)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetStyleColorVec4(ImGuiCol_ButtonActive)); if (ImGui::SmallButton(ICON_MD_VIEW_MODULE)) { ImGui::OpenPopup("CardControlPopup"); } - ImGui::PopStyleColor(2); + ImGui::PopStyleColor(3); if (ImGui::IsItemHovered()) { ImGui::SetTooltip("%s Card Controls", category.c_str());