From de4af9c4e45e8fb5247a3c14023a4c8f49baa169 Mon Sep 17 00:00:00 2001 From: scawful Date: Sun, 5 Oct 2025 20:32:54 -0400 Subject: [PATCH] refactor: Update ASM Version Handling in MapPropertiesSystem and OverworldEditor - Changed static asm_version declarations to non-static to ensure fresh reads from ROM, reflecting upgrades accurately. - Improved comments to clarify the importance of reading the asm_version dynamically. - Enhanced the DrawToolset method in OverworldEditor to include a new ROM Upgrade Popup for applying ASM patches, improving user experience and functionality. --- src/app/editor/overworld/map_properties.cc | 30 ++++++------- src/app/editor/overworld/overworld_editor.cc | 47 ++++++++++++++++++-- 2 files changed, 59 insertions(+), 18 deletions(-) diff --git a/src/app/editor/overworld/map_properties.cc b/src/app/editor/overworld/map_properties.cc index c7f19110..be29b02b 100644 --- a/src/app/editor/overworld/map_properties.cc +++ b/src/app/editor/overworld/map_properties.cc @@ -59,8 +59,8 @@ void MapPropertiesSystem::DrawSimplifiedMapSettings( ImGui::Text("%d (0x%02X)", current_map, current_map); TableNextColumn(); - static uint8_t asm_version = - (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; + // IMPORTANT: Don't cache - read fresh to reflect ROM upgrades + uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; // ALL ROMs support Small/Large. Only v3+ supports Wide/Tall. int current_area_size = @@ -222,7 +222,7 @@ void MapPropertiesSystem::DrawMapPropertiesPanel( } // Custom Overworld Features Tab - static uint8_t asm_version = + uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; if (asm_version != 0xFF && ImGui::BeginTabItem("Custom Features")) { DrawCustomFeaturesTab(current_map); @@ -253,7 +253,7 @@ void MapPropertiesSystem::DrawCustomBackgroundColorEditor( return; } - static uint8_t asm_version = + uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; if (asm_version < 2) { Text("Custom background colors require ZSCustomOverworld v2+"); @@ -308,7 +308,7 @@ void MapPropertiesSystem::DrawOverlayEditor(int current_map, return; } - static uint8_t asm_version = + uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; ImGui::TextColored(ImVec4(0.4f, 0.8f, 1.0f, 1.0f), @@ -432,7 +432,7 @@ void MapPropertiesSystem::SetupCanvasContextMenu( canvas.AddContextMenuItem(properties_item); // Custom overworld features (only show if v3+) - static uint8_t asm_version = + uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; if (asm_version >= 3 && asm_version != 0xFF) { // Custom Background Color @@ -518,7 +518,7 @@ void MapPropertiesSystem::DrawGraphicsPopup(int current_map, int game_state) { } HOVER_HINT("Sprite graphics sheet for current game state"); - static uint8_t asm_version = + uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; if (asm_version >= 3) { if (gui::InputHexByte(ICON_MD_ANIMATION " Animated GFX", @@ -596,8 +596,8 @@ void MapPropertiesSystem::DrawPalettesPopup(int current_map, int game_state, } HOVER_HINT("Main color palette for background tiles"); - static uint8_t asm_version = - (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; + // Read fresh to reflect ROM upgrades + uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; if (asm_version >= 2) { if (gui::InputHexByte(ICON_MD_COLOR_LENS " Main Palette", overworld_->mutable_overworld_map(current_map) @@ -686,7 +686,7 @@ void MapPropertiesSystem::DrawPropertiesPopup(int current_map, ImGui::Separator(); // ALL ROMs support Small/Large. Only v3+ supports Wide/Tall. - static uint8_t asm_version = + uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; int current_area_size = @@ -957,7 +957,7 @@ void MapPropertiesSystem::DrawCustomFeaturesTab(int current_map) { ImGui::Text(ICON_MD_PHOTO_SIZE_SELECT_LARGE " Area Size"); TableNextColumn(); // ALL ROMs support Small/Large. Only v3+ supports Wide/Tall. - static uint8_t asm_version = + uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; int current_area_size = @@ -1051,7 +1051,7 @@ void MapPropertiesSystem::DrawCustomFeaturesTab(int current_map) { } void MapPropertiesSystem::DrawTileGraphicsTab(int current_map) { - static uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; + uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; // Only show custom tile graphics for v1+ ROMs if (asm_version >= 1 && asm_version != 0xFF) { @@ -1270,7 +1270,7 @@ void MapPropertiesSystem::RefreshSiblingMapGraphics(int map_index, bool include_ } void MapPropertiesSystem::DrawMosaicControls(int current_map) { - static uint8_t asm_version = + uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; if (asm_version >= 2) { ImGui::Separator(); @@ -1299,7 +1299,7 @@ void MapPropertiesSystem::DrawMosaicControls(int current_map) { void MapPropertiesSystem::DrawOverlayControls(int current_map, bool& show_overlay_preview) { - static uint8_t asm_version = + uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; // Determine if this is a special overworld map (0x80-0x9F) @@ -1512,7 +1512,7 @@ void MapPropertiesSystem::DrawOverlayPreviewOnMap(int current_map, uint16_t overlay_id = 0x00FF; bool has_subscreen_overlay = false; - static uint8_t asm_version = + uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; bool is_special_overworld_map = (current_map >= 0x80 && current_map < 0xA0); diff --git a/src/app/editor/overworld/overworld_editor.cc b/src/app/editor/overworld/overworld_editor.cc index c3e13286..6f8df002 100644 --- a/src/app/editor/overworld/overworld_editor.cc +++ b/src/app/editor/overworld/overworld_editor.cc @@ -272,7 +272,9 @@ void OverworldEditor::DrawFullscreenCanvas() { void OverworldEditor::DrawToolset() { // Modern adaptive toolbar with inline mode switching and properties static gui::Toolset toolbar; - static uint8_t asm_version = 0xFF; + + // IMPORTANT: Don't make asm_version static - it needs to update after ROM upgrade + uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; // Don't use WidgetIdScope here - it conflicts with ImGui::Begin/End ID stack in cards // Widgets register themselves individually instead @@ -317,8 +319,7 @@ void OverworldEditor::DrawToolset() { toolbar.EndModeGroup(); - // ROM version badge - asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; + // ROM version badge (already read above) toolbar.AddRomBadge(asm_version, [this]() { ImGui::OpenPopup("UpgradeROMVersion"); }); @@ -417,6 +418,46 @@ void OverworldEditor::DrawToolset() { } toolbar.End(); + + // ROM Upgrade Popup (rendered outside toolbar to avoid ID conflicts) + if (ImGui::BeginPopupModal("UpgradeROMVersion", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::Text(ICON_MD_UPGRADE " Upgrade ROM to ZSCustomOverworld"); + ImGui::Separator(); + ImGui::TextWrapped( + "This will apply the ZSCustomOverworld ASM patch to your ROM,\n" + "enabling advanced features like custom tile graphics, animated GFX,\n" + "wide/tall areas, and more."); + ImGui::Separator(); + + uint8_t current_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; + ImGui::Text("Current Version: %s", + current_version == 0xFF ? "Vanilla" : absl::StrFormat("v%d", current_version).c_str()); + + static int target_version = 3; + ImGui::RadioButton("v2 (Basic features)", &target_version, 2); + ImGui::SameLine(); + ImGui::RadioButton("v3 (All features)", &target_version, 3); + + ImGui::Separator(); + + if (ImGui::Button(ICON_MD_CHECK " Apply Upgrade", ImVec2(150, 0))) { + auto status = ApplyZSCustomOverworldASM(target_version); + if (status.ok()) { + // CRITICAL: Reload the editor to reflect changes + status_ = Clear(); + status_ = Load(); + ImGui::CloseCurrentPopup(); + } else { + LOG_ERROR("OverworldEditor", "Upgrade failed: %s", status.message().data()); + } + } + ImGui::SameLine(); + if (ImGui::Button(ICON_MD_CANCEL " Cancel", ImVec2(150, 0))) { + ImGui::CloseCurrentPopup(); + } + + ImGui::EndPopup(); + } // All editor windows are now rendered in Update() using either EditorCard system // or MapPropertiesSystem for map-specific panels. This keeps the toolset clean