Enhance Overworld Editor and Map Properties System
- Updated the DrawOverworldEntrancePopup to include new options for deleting entrances and improved UI labels for better clarity. - Integrated new UI constants for consistent styling across the editor. - Refactored MapPropertiesSystem to support additional toolset functionalities, including editing tools and view controls. - Improved overlay handling in OverworldMap, consolidating vanilla and custom overlay loading logic. - Enhanced user interaction with new buttons and streamlined layout for better usability in the editor.
This commit is contained in:
@@ -126,50 +126,70 @@ bool DrawEntranceInserterPopup() {
|
|||||||
return set_done;
|
return set_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement deleting OverworldEntrance objects, currently only hides them
|
|
||||||
bool DrawOverworldEntrancePopup(zelda3::OverworldEntrance &entrance) {
|
bool DrawOverworldEntrancePopup(zelda3::OverworldEntrance &entrance) {
|
||||||
static bool set_done = false;
|
static bool set_done = false;
|
||||||
if (set_done) {
|
if (set_done) {
|
||||||
set_done = false;
|
set_done = false;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (ImGui::BeginPopupModal("Entrance editor", NULL,
|
|
||||||
|
if (ImGui::BeginPopupModal("Entrance Editor", NULL,
|
||||||
ImGuiWindowFlags_AlwaysAutoResize)) {
|
ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||||
|
ImGui::Text("Entrance ID: %d", entrance.entrance_id_);
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
gui::InputHexWord("Map ID", &entrance.map_id_);
|
gui::InputHexWord("Map ID", &entrance.map_id_);
|
||||||
gui::InputHexByte("Entrance ID", &entrance.entrance_id_,
|
gui::InputHexByte("Entrance ID", &entrance.entrance_id_,
|
||||||
kInputFieldSize + 20);
|
kInputFieldSize + 20);
|
||||||
gui::InputHex("X", &entrance.x_);
|
gui::InputHex("X Position", &entrance.x_);
|
||||||
gui::InputHex("Y", &entrance.y_);
|
gui::InputHex("Y Position", &entrance.y_);
|
||||||
|
|
||||||
if (Button(ICON_MD_DONE)) {
|
ImGui::Checkbox("Is Hole", &entrance.is_hole_);
|
||||||
ImGui::CloseCurrentPopup();
|
|
||||||
}
|
ImGui::Separator();
|
||||||
SameLine();
|
|
||||||
if (Button(ICON_MD_CANCEL)) {
|
if (Button("Save")) {
|
||||||
set_done = true;
|
set_done = true;
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
SameLine();
|
ImGui::SameLine();
|
||||||
if (Button(ICON_MD_DELETE)) {
|
if (Button("Delete")) {
|
||||||
entrance.deleted = true;
|
entrance.deleted = true;
|
||||||
|
set_done = true;
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (Button("Cancel")) {
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
return set_done;
|
return set_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement deleting OverworldExit objects
|
|
||||||
void DrawExitInserterPopup() {
|
void DrawExitInserterPopup() {
|
||||||
if (ImGui::BeginPopup("Exit Inserter")) {
|
if (ImGui::BeginPopup("Exit Inserter")) {
|
||||||
static int exit_id = 0;
|
static int exit_id = 0;
|
||||||
|
static int room_id = 0;
|
||||||
|
static int x_pos = 0;
|
||||||
|
static int y_pos = 0;
|
||||||
|
|
||||||
|
ImGui::Text("Insert New Exit");
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
gui::InputHex("Exit ID", &exit_id);
|
gui::InputHex("Exit ID", &exit_id);
|
||||||
|
gui::InputHex("Room ID", &room_id);
|
||||||
|
gui::InputHex("X Position", &x_pos);
|
||||||
|
gui::InputHex("Y Position", &y_pos);
|
||||||
|
|
||||||
if (Button(ICON_MD_DONE)) {
|
if (Button("Create Exit")) {
|
||||||
|
// This would need to be connected to the overworld editor to actually create the exit
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
SameLine();
|
SameLine();
|
||||||
if (Button(ICON_MD_CANCEL)) {
|
if (Button("Cancel")) {
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,30 +444,35 @@ void DrawSpriteTable(std::function<void(int)> onSpriteSelect) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement deleting OverworldSprite objects
|
|
||||||
void DrawSpriteInserterPopup() {
|
void DrawSpriteInserterPopup() {
|
||||||
if (ImGui::BeginPopup("Sprite Inserter")) {
|
if (ImGui::BeginPopup("Sprite Inserter")) {
|
||||||
static int new_sprite_id = 0;
|
static int new_sprite_id = 0;
|
||||||
Text("Add Sprite");
|
static int x_pos = 0;
|
||||||
BeginChild("ScrollRegion", ImVec2(250, 250), true,
|
static int y_pos = 0;
|
||||||
|
|
||||||
|
ImGui::Text("Add New Sprite");
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
BeginChild("ScrollRegion", ImVec2(250, 200), true,
|
||||||
ImGuiWindowFlags_AlwaysVerticalScrollbar);
|
ImGuiWindowFlags_AlwaysVerticalScrollbar);
|
||||||
DrawSpriteTable([](int selected_id) { new_sprite_id = selected_id; });
|
DrawSpriteTable([](int selected_id) { new_sprite_id = selected_id; });
|
||||||
EndChild();
|
EndChild();
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::Text("Position:");
|
||||||
|
gui::InputHex("X Position", &x_pos);
|
||||||
|
gui::InputHex("Y Position", &y_pos);
|
||||||
|
|
||||||
if (Button(ICON_MD_DONE)) {
|
if (Button("Add Sprite")) {
|
||||||
// Add the new item to the overworld
|
// This would need to be connected to the overworld editor to actually create the sprite
|
||||||
new_sprite_id = 0;
|
new_sprite_id = 0;
|
||||||
|
x_pos = 0;
|
||||||
|
y_pos = 0;
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
SameLine();
|
SameLine();
|
||||||
|
|
||||||
if (Button(ICON_MD_DELETE)) {
|
if (Button("Cancel")) {
|
||||||
new_sprite_id = -1;
|
|
||||||
ImGui::CloseCurrentPopup();
|
|
||||||
}
|
|
||||||
SameLine();
|
|
||||||
|
|
||||||
if (Button(ICON_MD_CANCEL)) {
|
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
#include "app/gui/icons.h"
|
#include "app/gui/icons.h"
|
||||||
#include "app/gui/input.h"
|
#include "app/gui/input.h"
|
||||||
#include "app/zelda3/overworld/overworld_map.h"
|
#include "app/zelda3/overworld/overworld_map.h"
|
||||||
|
#include "app/editor/overworld/overworld_editor.h"
|
||||||
|
#include "app/editor/overworld/ui_constants.h"
|
||||||
#include "imgui/imgui.h"
|
#include "imgui/imgui.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
@@ -16,28 +18,28 @@ using ImGui::Separator;
|
|||||||
using ImGui::TableNextColumn;
|
using ImGui::TableNextColumn;
|
||||||
using ImGui::Text;
|
using ImGui::Text;
|
||||||
|
|
||||||
// Static constants
|
// Using centralized UI constants
|
||||||
constexpr const char* kWorldList[] = {"Light World", "Dark World", "Special World"};
|
|
||||||
constexpr const char* kGamePartComboString[] = {"Light World", "Dark World", "Special World"};
|
|
||||||
|
|
||||||
void MapPropertiesSystem::DrawSimplifiedMapSettings(int& current_world, int& current_map,
|
void MapPropertiesSystem::DrawSimplifiedMapSettings(int& current_world, int& current_map,
|
||||||
bool& current_map_lock, bool& show_map_properties_panel,
|
bool& current_map_lock, bool& show_map_properties_panel,
|
||||||
bool& show_custom_bg_color_editor, bool& show_overlay_editor,
|
bool& show_custom_bg_color_editor, bool& show_overlay_editor,
|
||||||
bool& show_overlay_preview, int& game_state) {
|
bool& show_overlay_preview, int& game_state, int& current_mode) {
|
||||||
// Enhanced settings table with popup buttons for quick access
|
// Enhanced settings table with popup buttons for quick access and integrated toolset
|
||||||
if (BeginTable("SimplifiedMapSettings", 8, ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit, ImVec2(0, 0), -1)) {
|
if (BeginTable("SimplifiedMapSettings", 10, ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit, ImVec2(0, 0), -1)) {
|
||||||
ImGui::TableSetupColumn("World", ImGuiTableColumnFlags_WidthFixed, 100);
|
ImGui::TableSetupColumn("World", ImGuiTableColumnFlags_WidthFixed, 100);
|
||||||
ImGui::TableSetupColumn("Map", ImGuiTableColumnFlags_WidthFixed, 60);
|
ImGui::TableSetupColumn("Map", ImGuiTableColumnFlags_WidthFixed, 60);
|
||||||
ImGui::TableSetupColumn("Area Size", ImGuiTableColumnFlags_WidthFixed, 100);
|
ImGui::TableSetupColumn("Area Size", ImGuiTableColumnFlags_WidthFixed, 100);
|
||||||
ImGui::TableSetupColumn("Lock", ImGuiTableColumnFlags_WidthFixed, 60);
|
ImGui::TableSetupColumn("Lock", ImGuiTableColumnFlags_WidthFixed, 60);
|
||||||
ImGui::TableSetupColumn("Graphics", ImGuiTableColumnFlags_WidthFixed, 90);
|
ImGui::TableSetupColumn("Graphics", ImGuiTableColumnFlags_WidthFixed, 90);
|
||||||
ImGui::TableSetupColumn("Palettes", ImGuiTableColumnFlags_WidthFixed, 90);
|
ImGui::TableSetupColumn("Palettes", ImGuiTableColumnFlags_WidthFixed, 90);
|
||||||
ImGui::TableSetupColumn("Overlays", ImGuiTableColumnFlags_WidthFixed, 90);
|
|
||||||
ImGui::TableSetupColumn("Properties", ImGuiTableColumnFlags_WidthFixed, 100);
|
ImGui::TableSetupColumn("Properties", ImGuiTableColumnFlags_WidthFixed, 100);
|
||||||
|
ImGui::TableSetupColumn("Tools", ImGuiTableColumnFlags_WidthFixed, 120);
|
||||||
|
ImGui::TableSetupColumn("View", ImGuiTableColumnFlags_WidthFixed, 120);
|
||||||
|
ImGui::TableSetupColumn("Quick", ImGuiTableColumnFlags_WidthFixed, 100);
|
||||||
|
|
||||||
TableNextColumn();
|
TableNextColumn();
|
||||||
ImGui::SetNextItemWidth(90.f);
|
ImGui::SetNextItemWidth(90.f);
|
||||||
if (ImGui::Combo("##world", ¤t_world, kWorldList, 3)) {
|
if (ImGui::Combo("##world", ¤t_world, kWorldNames, 3)) {
|
||||||
// World changed, update current map if needed
|
// World changed, update current map if needed
|
||||||
if (current_map >= 0x40 && current_world == 0) {
|
if (current_map >= 0x40 && current_world == 0) {
|
||||||
current_map -= 0x40;
|
current_map -= 0x40;
|
||||||
@@ -56,10 +58,9 @@ void MapPropertiesSystem::DrawSimplifiedMapSettings(int& current_world, int& cur
|
|||||||
TableNextColumn();
|
TableNextColumn();
|
||||||
static uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
static uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||||
if (asm_version != 0xFF) {
|
if (asm_version != 0xFF) {
|
||||||
static const char *area_size_names[] = {"Small (1x1)", "Large (2x2)", "Wide (2x1)", "Tall (1x2)"};
|
|
||||||
int current_area_size = static_cast<int>(overworld_->overworld_map(current_map)->area_size());
|
int current_area_size = static_cast<int>(overworld_->overworld_map(current_map)->area_size());
|
||||||
ImGui::SetNextItemWidth(90.f);
|
ImGui::SetNextItemWidth(90.f);
|
||||||
if (ImGui::Combo("##AreaSize", ¤t_area_size, area_size_names, 4)) {
|
if (ImGui::Combo("##AreaSize", ¤t_area_size, kAreaSizeNames, 4)) {
|
||||||
overworld_->mutable_overworld_map(current_map)->SetAreaSize(static_cast<zelda3::AreaSizeEnum>(current_area_size));
|
overworld_->mutable_overworld_map(current_map)->SetAreaSize(static_cast<zelda3::AreaSizeEnum>(current_area_size));
|
||||||
RefreshOverworldMap();
|
RefreshOverworldMap();
|
||||||
}
|
}
|
||||||
@@ -74,28 +75,50 @@ void MapPropertiesSystem::DrawSimplifiedMapSettings(int& current_world, int& cur
|
|||||||
HOVER_HINT(current_map_lock ? "Unlock Map" : "Lock Map");
|
HOVER_HINT(current_map_lock ? "Unlock Map" : "Lock Map");
|
||||||
|
|
||||||
TableNextColumn();
|
TableNextColumn();
|
||||||
if (ImGui::Button("Graphics", ImVec2(80, 0))) {
|
if (ImGui::Button("Graphics", ImVec2(kSmallButtonWidth, 0))) {
|
||||||
ImGui::OpenPopup("GraphicsPopup");
|
ImGui::OpenPopup("GraphicsPopup");
|
||||||
}
|
}
|
||||||
HOVER_HINT("Graphics Settings");
|
HOVER_HINT("Graphics Settings");
|
||||||
DrawGraphicsPopup(current_map);
|
DrawGraphicsPopup(current_map, game_state);
|
||||||
|
|
||||||
TableNextColumn();
|
TableNextColumn();
|
||||||
if (ImGui::Button("Palettes", ImVec2(80, 0))) {
|
if (ImGui::Button("Palettes", ImVec2(kSmallButtonWidth, 0))) {
|
||||||
ImGui::OpenPopup("PalettesPopup");
|
ImGui::OpenPopup("PalettesPopup");
|
||||||
}
|
}
|
||||||
HOVER_HINT("Palette Settings");
|
HOVER_HINT("Palette Settings");
|
||||||
DrawPalettesPopup(current_map, show_custom_bg_color_editor);
|
DrawPalettesPopup(current_map, game_state, show_custom_bg_color_editor);
|
||||||
|
|
||||||
// Overlays are now integrated into Properties popup
|
|
||||||
|
|
||||||
TableNextColumn();
|
TableNextColumn();
|
||||||
if (ImGui::Button("Properties", ImVec2(90, 0))) {
|
if (ImGui::Button("Properties", ImVec2(kMediumButtonWidth, 0))) {
|
||||||
ImGui::OpenPopup("PropertiesPopup");
|
ImGui::OpenPopup("PropertiesPopup");
|
||||||
}
|
}
|
||||||
HOVER_HINT("Map Properties");
|
HOVER_HINT("Map Properties & Overlays");
|
||||||
DrawPropertiesPopup(current_map, show_map_properties_panel, show_overlay_preview, game_state);
|
DrawPropertiesPopup(current_map, show_map_properties_panel, show_overlay_preview, game_state);
|
||||||
|
|
||||||
|
TableNextColumn();
|
||||||
|
// Editing Tools
|
||||||
|
if (ImGui::Button("Tools", ImVec2(kSmallButtonWidth, 0))) {
|
||||||
|
ImGui::OpenPopup("ToolsPopup");
|
||||||
|
}
|
||||||
|
HOVER_HINT("Editing Tools");
|
||||||
|
DrawToolsPopup(current_mode);
|
||||||
|
|
||||||
|
TableNextColumn();
|
||||||
|
// View Controls
|
||||||
|
if (ImGui::Button("View", ImVec2(kSmallButtonWidth, 0))) {
|
||||||
|
ImGui::OpenPopup("ViewPopup");
|
||||||
|
}
|
||||||
|
HOVER_HINT("View Controls");
|
||||||
|
DrawViewPopup();
|
||||||
|
|
||||||
|
TableNextColumn();
|
||||||
|
// Quick Access Tools
|
||||||
|
if (ImGui::Button("Quick", ImVec2(kSmallButtonWidth, 0))) {
|
||||||
|
ImGui::OpenPopup("QuickPopup");
|
||||||
|
}
|
||||||
|
HOVER_HINT("Quick Access Tools");
|
||||||
|
DrawQuickAccessPopup();
|
||||||
|
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -291,8 +314,11 @@ void MapPropertiesSystem::SetupCanvasContextMenu(gui::Canvas& canvas, int curren
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Private method implementations
|
// Private method implementations
|
||||||
void MapPropertiesSystem::DrawGraphicsPopup(int current_map) {
|
void MapPropertiesSystem::DrawGraphicsPopup(int current_map, int game_state) {
|
||||||
if (ImGui::BeginPopup("GraphicsPopup")) {
|
if (ImGui::BeginPopup("GraphicsPopup")) {
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(kCompactItemSpacing, kCompactFramePadding));
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(kCompactItemSpacing, kCompactFramePadding));
|
||||||
|
|
||||||
ImGui::Text("Graphics Settings");
|
ImGui::Text("Graphics Settings");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
@@ -303,15 +329,8 @@ void MapPropertiesSystem::DrawGraphicsPopup(int current_map) {
|
|||||||
RefreshOverworldMap();
|
RefreshOverworldMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gui::InputHexByte("Sprite GFX 1",
|
if (gui::InputHexByte(absl::StrFormat("Sprite GFX (%s)", kGameStateNames[game_state]).c_str(),
|
||||||
overworld_->mutable_overworld_map(current_map)->mutable_sprite_graphics(1),
|
overworld_->mutable_overworld_map(current_map)->mutable_sprite_graphics(game_state),
|
||||||
kInputFieldSize)) {
|
|
||||||
RefreshMapProperties();
|
|
||||||
RefreshOverworldMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gui::InputHexByte("Sprite GFX 2",
|
|
||||||
overworld_->mutable_overworld_map(current_map)->mutable_sprite_graphics(2),
|
|
||||||
kInputFieldSize)) {
|
kInputFieldSize)) {
|
||||||
RefreshMapProperties();
|
RefreshMapProperties();
|
||||||
RefreshOverworldMap();
|
RefreshOverworldMap();
|
||||||
@@ -345,8 +364,11 @@ void MapPropertiesSystem::DrawGraphicsPopup(int current_map) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapPropertiesSystem::DrawPalettesPopup(int current_map, bool& show_custom_bg_color_editor) {
|
void MapPropertiesSystem::DrawPalettesPopup(int current_map, int game_state, bool& show_custom_bg_color_editor) {
|
||||||
if (ImGui::BeginPopup("PalettesPopup")) {
|
if (ImGui::BeginPopup("PalettesPopup")) {
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(kCompactItemSpacing, kCompactFramePadding));
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(kCompactItemSpacing, kCompactFramePadding));
|
||||||
|
|
||||||
ImGui::Text("Palette Settings");
|
ImGui::Text("Palette Settings");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
@@ -369,15 +391,8 @@ void MapPropertiesSystem::DrawPalettesPopup(int current_map, bool& show_custom_b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gui::InputHexByte("Sprite Palette 1",
|
if (gui::InputHexByte(absl::StrFormat("Sprite Palette (%s)", kGameStateNames[game_state]).c_str(),
|
||||||
overworld_->mutable_overworld_map(current_map)->mutable_sprite_palette(1),
|
overworld_->mutable_overworld_map(current_map)->mutable_sprite_palette(game_state),
|
||||||
kInputFieldSize)) {
|
|
||||||
RefreshMapProperties();
|
|
||||||
RefreshOverworldMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gui::InputHexByte("Sprite Palette 2",
|
|
||||||
overworld_->mutable_overworld_map(current_map)->mutable_sprite_palette(2),
|
|
||||||
kInputFieldSize)) {
|
kInputFieldSize)) {
|
||||||
RefreshMapProperties();
|
RefreshMapProperties();
|
||||||
RefreshOverworldMap();
|
RefreshOverworldMap();
|
||||||
@@ -417,7 +432,7 @@ void MapPropertiesSystem::DrawPropertiesPopup(int current_map, bool& show_map_pr
|
|||||||
DrawOverlayControls(current_map, show_overlay_preview);
|
DrawOverlayControls(current_map, show_overlay_preview);
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(100.f);
|
ImGui::SetNextItemWidth(100.f);
|
||||||
if (ImGui::Combo("Game State", &game_state, kGamePartComboString, 3)) {
|
if (ImGui::Combo("Game State", &game_state, kGameStateNames, 3)) {
|
||||||
RefreshMapProperties();
|
RefreshMapProperties();
|
||||||
RefreshOverworldMap();
|
RefreshOverworldMap();
|
||||||
}
|
}
|
||||||
@@ -501,7 +516,7 @@ void MapPropertiesSystem::DrawSpritePropertiesTab(int current_map) {
|
|||||||
TableNextColumn();
|
TableNextColumn();
|
||||||
static int game_state = 0;
|
static int game_state = 0;
|
||||||
ImGui::SetNextItemWidth(100.f);
|
ImGui::SetNextItemWidth(100.f);
|
||||||
if (ImGui::Combo("##GameState", &game_state, kGamePartComboString, 3)) {
|
if (ImGui::Combo("##GameState", &game_state, kGameStateNames, 3)) {
|
||||||
RefreshMapProperties();
|
RefreshMapProperties();
|
||||||
RefreshOverworldMap();
|
RefreshOverworldMap();
|
||||||
}
|
}
|
||||||
@@ -680,51 +695,77 @@ void MapPropertiesSystem::DrawOverlayControls(int current_map, bool& show_overla
|
|||||||
// Determine if this is a special overworld map (0x80-0x9F)
|
// Determine if this is a special overworld map (0x80-0x9F)
|
||||||
bool is_special_overworld_map = (current_map >= 0x80 && current_map < 0xA0);
|
bool is_special_overworld_map = (current_map >= 0x80 && current_map < 0xA0);
|
||||||
|
|
||||||
if (asm_version == 0xFF) {
|
if (is_special_overworld_map) {
|
||||||
// Vanilla ROM - read-only overlay info
|
// Special overworld maps (0x80-0x9F) do not support subscreen overlays
|
||||||
auto *current_map_ptr = overworld_->overworld_map(current_map);
|
ImGui::Text("Special overworld maps (0x80-0x9F) do not support");
|
||||||
if (current_map_ptr->has_vanilla_overlay()) {
|
ImGui::Text("subscreen overlays (visual effects).");
|
||||||
ImGui::Text("Vanilla Overlay: 0x%04X", current_map_ptr->vanilla_overlay_id());
|
|
||||||
|
|
||||||
// Show overlay description
|
|
||||||
uint16_t overlay_id = current_map_ptr->vanilla_overlay_id();
|
|
||||||
std::string overlay_desc = GetOverlayDescription(overlay_id);
|
|
||||||
ImGui::Text("Description: %s", overlay_desc.c_str());
|
|
||||||
|
|
||||||
// Preview checkbox for vanilla
|
|
||||||
if (ImGui::Checkbox("Preview Overlay on Map", &show_overlay_preview)) {
|
|
||||||
// Toggle overlay preview
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ImGui::Text("No vanilla overlay for this map");
|
|
||||||
}
|
|
||||||
} else if (is_special_overworld_map && asm_version < 3) {
|
|
||||||
// Special overworld maps (0x80-0x9F) require ZSCustomOverworld v3+
|
|
||||||
ImGui::Text("Special overworld maps require ZSCustomOverworld v3+");
|
|
||||||
ImGui::Text("Current version: v%d", asm_version);
|
|
||||||
ImGui::Text("Map 0x%02X is a special overworld map", current_map);
|
ImGui::Text("Map 0x%02X is a special overworld map", current_map);
|
||||||
} else {
|
} else {
|
||||||
// Light World (0x00-0x3F) and Dark World (0x40-0x7F) maps always support overlays
|
// Light World (0x00-0x3F) and Dark World (0x40-0x7F) maps support subscreen overlays for all versions
|
||||||
// Special overworld maps (0x80-0x9F) support overlays with v3+
|
|
||||||
|
// Subscreen Overlay Section
|
||||||
|
ImGui::Text("Subscreen Overlay (Visual Effects)");
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("?")) {
|
||||||
|
ImGui::OpenPopup("SubscreenOverlayHelp");
|
||||||
|
}
|
||||||
|
if (ImGui::BeginPopup("SubscreenOverlayHelp")) {
|
||||||
|
ImGui::Text("Subscreen overlays are visual effects like fog, rain, canopy,");
|
||||||
|
ImGui::Text("and backgrounds that are displayed using tile16 graphics.");
|
||||||
|
ImGui::Text("They reference special area maps (0x80-0x9F) for their tile data.");
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t current_overlay = overworld_->mutable_overworld_map(current_map)->subscreen_overlay();
|
uint16_t current_overlay = overworld_->mutable_overworld_map(current_map)->subscreen_overlay();
|
||||||
if (gui::InputHexWord("Subscreen Overlay", ¤t_overlay, kInputFieldSize + 20)) {
|
if (gui::InputHexWord("Subscreen Overlay ID", ¤t_overlay, kInputFieldSize + 20)) {
|
||||||
overworld_->mutable_overworld_map(current_map)->set_subscreen_overlay(current_overlay);
|
overworld_->mutable_overworld_map(current_map)->set_subscreen_overlay(current_overlay);
|
||||||
RefreshMapProperties();
|
RefreshMapProperties();
|
||||||
RefreshOverworldMap();
|
RefreshOverworldMap();
|
||||||
}
|
}
|
||||||
|
HOVER_HINT("Subscreen overlay ID - visual effects like fog, rain, backgrounds");
|
||||||
|
|
||||||
// Show overlay description
|
// Show subscreen overlay description
|
||||||
std::string overlay_desc = GetOverlayDescription(current_overlay);
|
std::string overlay_desc = GetOverlayDescription(current_overlay);
|
||||||
ImGui::Text("Description: %s", overlay_desc.c_str());
|
ImGui::Text("Description: %s", overlay_desc.c_str());
|
||||||
|
|
||||||
// Preview checkbox
|
// Preview checkbox
|
||||||
if (ImGui::Checkbox("Preview Overlay on Map", &show_overlay_preview)) {
|
if (ImGui::Checkbox("Preview Subscreen Overlay on Map", &show_overlay_preview)) {
|
||||||
// Toggle overlay preview
|
// Toggle subscreen overlay preview
|
||||||
|
}
|
||||||
|
HOVER_HINT("Show semi-transparent preview of subscreen overlay on the map");
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
// Interactive Overlay Section (for vanilla ROMs)
|
||||||
|
if (asm_version == 0xFF) {
|
||||||
|
ImGui::Text("Interactive Overlay (Holes/Changes)");
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("?")) {
|
||||||
|
ImGui::OpenPopup("InteractiveOverlayHelp");
|
||||||
|
}
|
||||||
|
if (ImGui::BeginPopup("InteractiveOverlayHelp")) {
|
||||||
|
ImGui::Text("Interactive overlays reveal holes or change elements on top");
|
||||||
|
ImGui::Text("of the map. They use tile16 graphics and are present in");
|
||||||
|
ImGui::Text("vanilla ROMs. ZSCustomOverworld expands this functionality.");
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto *current_map_ptr = overworld_->overworld_map(current_map);
|
||||||
|
if (current_map_ptr->has_overlay()) {
|
||||||
|
ImGui::Text("Interactive Overlay ID: 0x%04X", current_map_ptr->overlay_id());
|
||||||
|
ImGui::Text("Overlay Data Size: %d bytes", static_cast<int>(current_map_ptr->overlay_data().size()));
|
||||||
|
} else {
|
||||||
|
ImGui::Text("No interactive overlay data for this map");
|
||||||
|
}
|
||||||
|
HOVER_HINT("Interactive overlay for revealing holes/changing elements (read-only in vanilla)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show version info for special maps
|
// Show version info
|
||||||
if (is_special_overworld_map) {
|
if (asm_version == 0xFF) {
|
||||||
ImGui::Text("Special overworld map (v%d)", asm_version);
|
ImGui::Text("Vanilla ROM - subscreen overlays reference special area maps");
|
||||||
|
ImGui::Text("(0x80-0x9F) for visual effects like fog, rain, backgrounds.");
|
||||||
|
} else {
|
||||||
|
ImGui::Text("ZSCustomOverworld v%d", asm_version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -758,33 +799,25 @@ std::string MapPropertiesSystem::GetOverlayDescription(uint16_t overlay_id) {
|
|||||||
void MapPropertiesSystem::DrawOverlayPreviewOnMap(int current_map, int current_world, bool show_overlay_preview) {
|
void MapPropertiesSystem::DrawOverlayPreviewOnMap(int current_map, int current_world, bool show_overlay_preview) {
|
||||||
if (!show_overlay_preview || !maps_bmp_ || !canvas_) return;
|
if (!show_overlay_preview || !maps_bmp_ || !canvas_) return;
|
||||||
|
|
||||||
// Get overlay information based on ROM version and map type
|
// Get subscreen overlay information based on ROM version and map type
|
||||||
uint16_t overlay_id = 0x00FF;
|
uint16_t overlay_id = 0x00FF;
|
||||||
bool has_overlay = false;
|
bool has_subscreen_overlay = false;
|
||||||
|
|
||||||
static uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
static uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||||
bool is_special_overworld_map = (current_map >= 0x80 && current_map < 0xA0);
|
bool is_special_overworld_map = (current_map >= 0x80 && current_map < 0xA0);
|
||||||
|
|
||||||
if (asm_version == 0xFF) {
|
if (is_special_overworld_map) {
|
||||||
// Vanilla ROM - use vanilla overlay
|
// Special overworld maps (0x80-0x9F) do not support subscreen overlays
|
||||||
auto *current_map_ptr = overworld_->overworld_map(current_map);
|
|
||||||
if (current_map_ptr->has_vanilla_overlay()) {
|
|
||||||
overlay_id = current_map_ptr->vanilla_overlay_id();
|
|
||||||
has_overlay = true;
|
|
||||||
}
|
|
||||||
} else if (is_special_overworld_map && asm_version < 3) {
|
|
||||||
// Special overworld maps require v3+ - no overlay support
|
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
// Light World (0x00-0x3F) and Dark World (0x40-0x7F) maps always support overlays
|
|
||||||
// Special overworld maps (0x80-0x9F) support overlays with v3+
|
|
||||||
overlay_id = overworld_->overworld_map(current_map)->subscreen_overlay();
|
|
||||||
has_overlay = (overlay_id != 0x00FF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!has_overlay) return;
|
// Light World (0x00-0x3F) and Dark World (0x40-0x7F) maps support subscreen overlays for all versions
|
||||||
|
overlay_id = overworld_->overworld_map(current_map)->subscreen_overlay();
|
||||||
|
has_subscreen_overlay = (overlay_id != 0x00FF);
|
||||||
|
|
||||||
// Map overlay ID to special area map for bitmap
|
if (!has_subscreen_overlay) return;
|
||||||
|
|
||||||
|
// Map subscreen overlay ID to special area map for bitmap
|
||||||
int overlay_map_index = -1;
|
int overlay_map_index = -1;
|
||||||
if (overlay_id >= 0x80 && overlay_id < 0xA0) {
|
if (overlay_id >= 0x80 && overlay_id < 0xA0) {
|
||||||
overlay_map_index = overlay_id;
|
overlay_map_index = overlay_id;
|
||||||
@@ -792,11 +825,11 @@ void MapPropertiesSystem::DrawOverlayPreviewOnMap(int current_map, int current_w
|
|||||||
|
|
||||||
if (overlay_map_index < 0 || overlay_map_index >= zelda3::kNumOverworldMaps) return;
|
if (overlay_map_index < 0 || overlay_map_index >= zelda3::kNumOverworldMaps) return;
|
||||||
|
|
||||||
// Get the overlay map's bitmap
|
// Get the subscreen overlay map's bitmap
|
||||||
const auto &overlay_bitmap = (*maps_bmp_)[overlay_map_index];
|
const auto &overlay_bitmap = (*maps_bmp_)[overlay_map_index];
|
||||||
if (!overlay_bitmap.is_active()) return;
|
if (!overlay_bitmap.is_active()) return;
|
||||||
|
|
||||||
// Calculate position for overlay preview on the current map
|
// Calculate position for subscreen overlay preview on the current map
|
||||||
int current_map_x = current_map % 8;
|
int current_map_x = current_map % 8;
|
||||||
int current_map_y = current_map / 8;
|
int current_map_y = current_map / 8;
|
||||||
if (current_world == 1) {
|
if (current_world == 1) {
|
||||||
@@ -811,15 +844,15 @@ void MapPropertiesSystem::DrawOverlayPreviewOnMap(int current_map, int current_w
|
|||||||
int map_x = current_map_x * kOverworldMapSize * scale;
|
int map_x = current_map_x * kOverworldMapSize * scale;
|
||||||
int map_y = current_map_y * kOverworldMapSize * scale;
|
int map_y = current_map_y * kOverworldMapSize * scale;
|
||||||
|
|
||||||
// Determine if this is a background or foreground overlay
|
// Determine if this is a background or foreground subscreen overlay
|
||||||
bool is_background_overlay = (overlay_id == 0x0095 || overlay_id == 0x0096 || overlay_id == 0x009C);
|
bool is_background_overlay = (overlay_id == 0x0095 || overlay_id == 0x0096 || overlay_id == 0x009C);
|
||||||
|
|
||||||
// Set alpha for semi-transparent preview
|
// Set alpha for semi-transparent preview
|
||||||
ImU32 overlay_color = is_background_overlay ?
|
ImU32 overlay_color = is_background_overlay ?
|
||||||
IM_COL32(255, 255, 255, 128) : // Background overlays - lighter
|
IM_COL32(255, 255, 255, 128) : // Background subscreen overlays - lighter
|
||||||
IM_COL32(255, 255, 255, 180); // Foreground overlays - more opaque
|
IM_COL32(255, 255, 255, 180); // Foreground subscreen overlays - more opaque
|
||||||
|
|
||||||
// Draw the overlay bitmap with semi-transparency
|
// Draw the subscreen overlay bitmap with semi-transparency
|
||||||
canvas_->draw_list()->AddImage(
|
canvas_->draw_list()->AddImage(
|
||||||
(ImTextureID)(intptr_t)overlay_bitmap.texture(),
|
(ImTextureID)(intptr_t)overlay_bitmap.texture(),
|
||||||
ImVec2(map_x, map_y),
|
ImVec2(map_x, map_y),
|
||||||
@@ -829,5 +862,120 @@ void MapPropertiesSystem::DrawOverlayPreviewOnMap(int current_map, int current_w
|
|||||||
overlay_color);
|
overlay_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MapPropertiesSystem::DrawToolsPopup(int& current_mode) {
|
||||||
|
if (ImGui::BeginPopup("ToolsPopup")) {
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(kCompactItemSpacing, kCompactFramePadding));
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(kCompactItemSpacing, kCompactFramePadding));
|
||||||
|
|
||||||
|
ImGui::Text("Editing Tools");
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
// Row 1: Navigation and Drawing
|
||||||
|
if (ImGui::Button(ICON_MD_PAN_TOOL_ALT " Pan", ImVec2(kCompactButtonWidth, 0))) {
|
||||||
|
current_mode = 7;
|
||||||
|
}
|
||||||
|
HOVER_HINT("Pan tool (1)");
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button(ICON_MD_DRAW " Draw", ImVec2(kCompactButtonWidth, 0))) {
|
||||||
|
current_mode = 0;
|
||||||
|
}
|
||||||
|
HOVER_HINT("Draw tile tool (2)");
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button(ICON_MD_DOOR_FRONT " Ent", ImVec2(kCompactButtonWidth, 0))) {
|
||||||
|
current_mode = 1;
|
||||||
|
}
|
||||||
|
HOVER_HINT("Edit entrances (3)");
|
||||||
|
|
||||||
|
// Row 2: Entities
|
||||||
|
if (ImGui::Button(ICON_MD_DOOR_BACK " Exit", ImVec2(kCompactButtonWidth, 0))) {
|
||||||
|
current_mode = 2;
|
||||||
|
}
|
||||||
|
HOVER_HINT("Edit exits (4)");
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button(ICON_MD_GRASS " Item", ImVec2(kCompactButtonWidth, 0))) {
|
||||||
|
current_mode = 3;
|
||||||
|
}
|
||||||
|
HOVER_HINT("Edit items (5)");
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button(ICON_MD_PEST_CONTROL_RODENT " Spr", ImVec2(kCompactButtonWidth, 0))) {
|
||||||
|
current_mode = 4;
|
||||||
|
}
|
||||||
|
HOVER_HINT("Edit sprites (6)");
|
||||||
|
|
||||||
|
// Row 3: Advanced
|
||||||
|
if (ImGui::Button(ICON_MD_ADD_LOCATION " Trans", ImVec2(kCompactButtonWidth, 0))) {
|
||||||
|
current_mode = 5;
|
||||||
|
}
|
||||||
|
HOVER_HINT("Edit transports (7)");
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button(ICON_MD_MUSIC_NOTE " Music", ImVec2(kCompactButtonWidth, 0))) {
|
||||||
|
current_mode = 6;
|
||||||
|
}
|
||||||
|
HOVER_HINT("Edit music (8)");
|
||||||
|
|
||||||
|
ImGui::PopStyleVar(2);
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapPropertiesSystem::DrawViewPopup() {
|
||||||
|
if (ImGui::BeginPopup("ViewPopup")) {
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(kCompactItemSpacing, kCompactFramePadding));
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(kCompactItemSpacing, kCompactFramePadding));
|
||||||
|
|
||||||
|
ImGui::Text("View Controls");
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
// Horizontal layout for view controls
|
||||||
|
if (ImGui::Button(ICON_MD_ZOOM_OUT, ImVec2(kIconButtonWidth, 0))) {
|
||||||
|
// This would need to be connected to the canvas zoom function
|
||||||
|
// For now, just show the option
|
||||||
|
}
|
||||||
|
HOVER_HINT("Zoom out on the canvas");
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button(ICON_MD_ZOOM_IN, ImVec2(kIconButtonWidth, 0))) {
|
||||||
|
// This would need to be connected to the canvas zoom function
|
||||||
|
// For now, just show the option
|
||||||
|
}
|
||||||
|
HOVER_HINT("Zoom in on the canvas");
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button(ICON_MD_OPEN_IN_FULL, ImVec2(kIconButtonWidth, 0))) {
|
||||||
|
// This would need to be connected to the fullscreen toggle
|
||||||
|
// For now, just show the option
|
||||||
|
}
|
||||||
|
HOVER_HINT("Toggle fullscreen canvas (F11)");
|
||||||
|
|
||||||
|
ImGui::PopStyleVar(2);
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapPropertiesSystem::DrawQuickAccessPopup() {
|
||||||
|
if (ImGui::BeginPopup("QuickPopup")) {
|
||||||
|
ImGui::Text("Quick Access");
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
if (ImGui::Button(ICON_MD_GRID_VIEW " Tile16 Editor")) {
|
||||||
|
// This would need to be connected to the Tile16 editor toggle
|
||||||
|
// For now, just show the option
|
||||||
|
}
|
||||||
|
HOVER_HINT("Open Tile16 Editor (Ctrl+T)");
|
||||||
|
|
||||||
|
if (ImGui::Button(ICON_MD_CONTENT_COPY " Copy Map")) {
|
||||||
|
// This would need to be connected to the copy map function
|
||||||
|
// For now, just show the option
|
||||||
|
}
|
||||||
|
HOVER_HINT("Copy current map to clipboard");
|
||||||
|
|
||||||
|
if (ImGui::Button(ICON_MD_LOCK " Lock Map (Ctrl+L)")) {
|
||||||
|
// This would need to be connected to the map lock toggle
|
||||||
|
// For now, just show the option
|
||||||
|
}
|
||||||
|
HOVER_HINT("Lock/unlock current map");
|
||||||
|
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace editor
|
} // namespace editor
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|||||||
@@ -5,6 +5,13 @@
|
|||||||
#include "app/rom.h"
|
#include "app/rom.h"
|
||||||
#include "app/gui/canvas.h"
|
#include "app/gui/canvas.h"
|
||||||
|
|
||||||
|
// Forward declaration
|
||||||
|
namespace yaze {
|
||||||
|
namespace editor {
|
||||||
|
class OverworldEditor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace editor {
|
namespace editor {
|
||||||
|
|
||||||
@@ -19,7 +26,7 @@ class MapPropertiesSystem {
|
|||||||
void DrawSimplifiedMapSettings(int& current_world, int& current_map,
|
void DrawSimplifiedMapSettings(int& current_world, int& current_map,
|
||||||
bool& current_map_lock, bool& show_map_properties_panel,
|
bool& current_map_lock, bool& show_map_properties_panel,
|
||||||
bool& show_custom_bg_color_editor, bool& show_overlay_editor,
|
bool& show_custom_bg_color_editor, bool& show_overlay_editor,
|
||||||
bool& show_overlay_preview, int& game_state);
|
bool& show_overlay_preview, int& game_state, int& current_mode);
|
||||||
|
|
||||||
void DrawMapPropertiesPanel(int current_map, bool& show_map_properties_panel);
|
void DrawMapPropertiesPanel(int current_map, bool& show_map_properties_panel);
|
||||||
|
|
||||||
@@ -37,8 +44,8 @@ class MapPropertiesSystem {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Property category drawers
|
// Property category drawers
|
||||||
void DrawGraphicsPopup(int current_map);
|
void DrawGraphicsPopup(int current_map, int game_state);
|
||||||
void DrawPalettesPopup(int current_map, bool& show_custom_bg_color_editor);
|
void DrawPalettesPopup(int current_map, int game_state, bool& show_custom_bg_color_editor);
|
||||||
void DrawPropertiesPopup(int current_map, bool& show_map_properties_panel,
|
void DrawPropertiesPopup(int current_map, bool& show_map_properties_panel,
|
||||||
bool& show_overlay_preview, int& game_state);
|
bool& show_overlay_preview, int& game_state);
|
||||||
|
|
||||||
@@ -47,6 +54,11 @@ class MapPropertiesSystem {
|
|||||||
void DrawOverlayControls(int current_map, bool& show_overlay_preview);
|
void DrawOverlayControls(int current_map, bool& show_overlay_preview);
|
||||||
std::string GetOverlayDescription(uint16_t overlay_id);
|
std::string GetOverlayDescription(uint16_t overlay_id);
|
||||||
|
|
||||||
|
// Integrated toolset popup functions
|
||||||
|
void DrawToolsPopup(int& current_mode);
|
||||||
|
void DrawViewPopup();
|
||||||
|
void DrawQuickAccessPopup();
|
||||||
|
|
||||||
// Tab content drawers
|
// Tab content drawers
|
||||||
void DrawBasicPropertiesTab(int current_map);
|
void DrawBasicPropertiesTab(int current_map);
|
||||||
void DrawSpritePropertiesTab(int current_map);
|
void DrawSpritePropertiesTab(int current_map);
|
||||||
@@ -63,9 +75,7 @@ class MapPropertiesSystem {
|
|||||||
std::array<gfx::Bitmap, zelda3::kNumOverworldMaps>* maps_bmp_;
|
std::array<gfx::Bitmap, zelda3::kNumOverworldMaps>* maps_bmp_;
|
||||||
gui::Canvas* canvas_;
|
gui::Canvas* canvas_;
|
||||||
|
|
||||||
// Static constants
|
// Using centralized UI constants from ui_constants.h
|
||||||
static constexpr float kInputFieldSize = 30.f;
|
|
||||||
static constexpr int kOverworldMapSize = 512;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace editor
|
} // namespace editor
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
#include "app/core/features.h"
|
#include "app/core/features.h"
|
||||||
#include "app/core/platform/clipboard.h"
|
#include "app/core/platform/clipboard.h"
|
||||||
#include "app/core/window.h"
|
#include "app/core/window.h"
|
||||||
#include "app/editor/graphics/palette_editor.h"
|
|
||||||
#include "app/editor/overworld/entity.h"
|
#include "app/editor/overworld/entity.h"
|
||||||
#include "app/editor/overworld/map_properties.h"
|
#include "app/editor/overworld/map_properties.h"
|
||||||
#include "app/gfx/arena.h"
|
#include "app/gfx/arena.h"
|
||||||
@@ -74,80 +73,73 @@ void OverworldEditor::Initialize() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
gui::AddTableColumn(toolset_table_, "##Undo", [&]() {
|
// Core editing tools
|
||||||
if (Button(ICON_MD_UNDO)) status_ = Undo();
|
|
||||||
});
|
|
||||||
gui::AddTableColumn(toolset_table_, "##Redo", [&]() {
|
|
||||||
if (Button(ICON_MD_REDO)) status_ = Redo();
|
|
||||||
});
|
|
||||||
gui::AddTableColumn(toolset_table_, "##Sep1", ICON_MD_MORE_VERT);
|
|
||||||
gui::AddTableColumn(toolset_table_, "##ZoomOut", [&]() {
|
|
||||||
if (Button(ICON_MD_ZOOM_OUT)) ow_map_canvas_.ZoomOut();
|
|
||||||
});
|
|
||||||
gui::AddTableColumn(toolset_table_, "##ZoomIn", [&]() {
|
|
||||||
if (Button(ICON_MD_ZOOM_IN)) ow_map_canvas_.ZoomIn();
|
|
||||||
});
|
|
||||||
gui::AddTableColumn(toolset_table_, "##Fullscreen", [&]() {
|
|
||||||
if (Button(ICON_MD_OPEN_IN_FULL))
|
|
||||||
overworld_canvas_fullscreen_ = !overworld_canvas_fullscreen_;
|
|
||||||
HOVER_HINT("Fullscreen Canvas");
|
|
||||||
});
|
|
||||||
gui::AddTableColumn(toolset_table_, "##Sep2", ICON_MD_MORE_VERT);
|
|
||||||
gui::AddTableColumn(toolset_table_, "##Pan", [&]() {
|
gui::AddTableColumn(toolset_table_, "##Pan", [&]() {
|
||||||
if (Selectable(ICON_MD_PAN_TOOL_ALT, current_mode == EditingMode::PAN)) {
|
if (Selectable(ICON_MD_PAN_TOOL_ALT, current_mode == EditingMode::PAN)) {
|
||||||
current_mode = EditingMode::PAN;
|
current_mode = EditingMode::PAN;
|
||||||
ow_map_canvas_.set_draggable(true);
|
ow_map_canvas_.set_draggable(true);
|
||||||
}
|
}
|
||||||
HOVER_HINT("Pan (Right click and drag)");
|
HOVER_HINT("Pan (1) - Middle click and drag");
|
||||||
});
|
});
|
||||||
gui::AddTableColumn(toolset_table_, "##DrawTile", [&]() {
|
gui::AddTableColumn(toolset_table_, "##DrawTile", [&]() {
|
||||||
if (Selectable(ICON_MD_DRAW, current_mode == EditingMode::DRAW_TILE)) {
|
if (Selectable(ICON_MD_DRAW, current_mode == EditingMode::DRAW_TILE)) {
|
||||||
current_mode = EditingMode::DRAW_TILE;
|
current_mode = EditingMode::DRAW_TILE;
|
||||||
}
|
}
|
||||||
HOVER_HINT("Draw Tile");
|
HOVER_HINT("Draw Tile (2)");
|
||||||
});
|
});
|
||||||
gui::AddTableColumn(toolset_table_, "##Entrances", [&]() {
|
gui::AddTableColumn(toolset_table_, "##Entrances", [&]() {
|
||||||
if (Selectable(ICON_MD_DOOR_FRONT, current_mode == EditingMode::ENTRANCES))
|
if (Selectable(ICON_MD_DOOR_FRONT, current_mode == EditingMode::ENTRANCES))
|
||||||
current_mode = EditingMode::ENTRANCES;
|
current_mode = EditingMode::ENTRANCES;
|
||||||
HOVER_HINT("Entrances");
|
HOVER_HINT("Entrances (3)");
|
||||||
});
|
});
|
||||||
gui::AddTableColumn(toolset_table_, "##Exits", [&]() {
|
gui::AddTableColumn(toolset_table_, "##Exits", [&]() {
|
||||||
if (Selectable(ICON_MD_DOOR_BACK, current_mode == EditingMode::EXITS))
|
if (Selectable(ICON_MD_DOOR_BACK, current_mode == EditingMode::EXITS))
|
||||||
current_mode = EditingMode::EXITS;
|
current_mode = EditingMode::EXITS;
|
||||||
HOVER_HINT("Exits");
|
HOVER_HINT("Exits (4)");
|
||||||
});
|
});
|
||||||
gui::AddTableColumn(toolset_table_, "##Items", [&]() {
|
gui::AddTableColumn(toolset_table_, "##Items", [&]() {
|
||||||
if (Selectable(ICON_MD_GRASS, current_mode == EditingMode::ITEMS))
|
if (Selectable(ICON_MD_GRASS, current_mode == EditingMode::ITEMS))
|
||||||
current_mode = EditingMode::ITEMS;
|
current_mode = EditingMode::ITEMS;
|
||||||
HOVER_HINT("Items");
|
HOVER_HINT("Items (5)");
|
||||||
});
|
});
|
||||||
gui::AddTableColumn(toolset_table_, "##Sprites", [&]() {
|
gui::AddTableColumn(toolset_table_, "##Sprites", [&]() {
|
||||||
if (Selectable(ICON_MD_PEST_CONTROL_RODENT,
|
if (Selectable(ICON_MD_PEST_CONTROL_RODENT,
|
||||||
current_mode == EditingMode::SPRITES))
|
current_mode == EditingMode::SPRITES))
|
||||||
current_mode = EditingMode::SPRITES;
|
current_mode = EditingMode::SPRITES;
|
||||||
HOVER_HINT("Sprites");
|
HOVER_HINT("Sprites (6)");
|
||||||
});
|
});
|
||||||
gui::AddTableColumn(toolset_table_, "##Transports", [&]() {
|
gui::AddTableColumn(toolset_table_, "##Transports", [&]() {
|
||||||
if (Selectable(ICON_MD_ADD_LOCATION,
|
if (Selectable(ICON_MD_ADD_LOCATION,
|
||||||
current_mode == EditingMode::TRANSPORTS))
|
current_mode == EditingMode::TRANSPORTS))
|
||||||
current_mode = EditingMode::TRANSPORTS;
|
current_mode = EditingMode::TRANSPORTS;
|
||||||
HOVER_HINT("Transports");
|
HOVER_HINT("Transports (7)");
|
||||||
});
|
});
|
||||||
gui::AddTableColumn(toolset_table_, "##Music", [&]() {
|
gui::AddTableColumn(toolset_table_, "##Music", [&]() {
|
||||||
if (Selectable(ICON_MD_MUSIC_NOTE, current_mode == EditingMode::MUSIC))
|
if (Selectable(ICON_MD_MUSIC_NOTE, current_mode == EditingMode::MUSIC))
|
||||||
current_mode = EditingMode::MUSIC;
|
current_mode = EditingMode::MUSIC;
|
||||||
HOVER_HINT("Music");
|
HOVER_HINT("Music (8)");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// View controls
|
||||||
|
gui::AddTableColumn(toolset_table_, "##ZoomOut", [&]() {
|
||||||
|
if (Button(ICON_MD_ZOOM_OUT)) ow_map_canvas_.ZoomOut();
|
||||||
|
HOVER_HINT("Zoom Out");
|
||||||
|
});
|
||||||
|
gui::AddTableColumn(toolset_table_, "##ZoomIn", [&]() {
|
||||||
|
if (Button(ICON_MD_ZOOM_IN)) ow_map_canvas_.ZoomIn();
|
||||||
|
HOVER_HINT("Zoom In");
|
||||||
|
});
|
||||||
|
gui::AddTableColumn(toolset_table_, "##Fullscreen", [&]() {
|
||||||
|
if (Button(ICON_MD_OPEN_IN_FULL))
|
||||||
|
overworld_canvas_fullscreen_ = !overworld_canvas_fullscreen_;
|
||||||
|
HOVER_HINT("Fullscreen Canvas (F11)");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Quick access tools
|
||||||
gui::AddTableColumn(toolset_table_, "##Tile16Editor", [&]() {
|
gui::AddTableColumn(toolset_table_, "##Tile16Editor", [&]() {
|
||||||
if (Button(ICON_MD_GRID_VIEW)) show_tile16_editor_ = !show_tile16_editor_;
|
if (Button(ICON_MD_GRID_VIEW)) show_tile16_editor_ = !show_tile16_editor_;
|
||||||
HOVER_HINT("Tile16 Editor");
|
HOVER_HINT("Tile16 Editor (Ctrl+T)");
|
||||||
});
|
});
|
||||||
gui::AddTableColumn(toolset_table_, "##GfxGroupEditor", [&]() {
|
|
||||||
if (Button(ICON_MD_TABLE_CHART))
|
|
||||||
show_gfx_group_editor_ = !show_gfx_group_editor_;
|
|
||||||
HOVER_HINT("Gfx Group Editor");
|
|
||||||
});
|
|
||||||
gui::AddTableColumn(toolset_table_, "##sep3", ICON_MD_MORE_VERT);
|
|
||||||
gui::AddTableColumn(toolset_table_, "##CopyMap", [&]() {
|
gui::AddTableColumn(toolset_table_, "##CopyMap", [&]() {
|
||||||
if (Button(ICON_MD_CONTENT_COPY)) {
|
if (Button(ICON_MD_CONTENT_COPY)) {
|
||||||
std::vector<uint8_t> png_data;
|
std::vector<uint8_t> png_data;
|
||||||
@@ -161,31 +153,6 @@ void OverworldEditor::Initialize() {
|
|||||||
}
|
}
|
||||||
HOVER_HINT("Copy Map to Clipboard");
|
HOVER_HINT("Copy Map to Clipboard");
|
||||||
});
|
});
|
||||||
gui::AddTableColumn(toolset_table_, "##Palette", [&]() {
|
|
||||||
status_ = DisplayPalette(palette_, overworld_.is_loaded());
|
|
||||||
});
|
|
||||||
gui::AddTableColumn(toolset_table_, "##Sep4", ICON_MD_MORE_VERT);
|
|
||||||
gui::AddTableColumn(toolset_table_, "##Properties", [&]() {
|
|
||||||
Checkbox("Properties", &show_properties_editor_);
|
|
||||||
});
|
|
||||||
gui::AddTableColumn(toolset_table_, "##MapLock", [&]() {
|
|
||||||
if (Button(current_map_lock_ ? ICON_MD_LOCK : ICON_MD_LOCK_OPEN)) {
|
|
||||||
current_map_lock_ = !current_map_lock_;
|
|
||||||
}
|
|
||||||
HOVER_HINT(current_map_lock_ ? "Unlock Map" : "Lock Map");
|
|
||||||
});
|
|
||||||
gui::AddTableColumn(toolset_table_, "##CustomBG", [&]() {
|
|
||||||
if (Button(ICON_MD_PALETTE)) {
|
|
||||||
show_custom_bg_color_editor_ = !show_custom_bg_color_editor_;
|
|
||||||
}
|
|
||||||
HOVER_HINT("Custom Background Colors");
|
|
||||||
});
|
|
||||||
gui::AddTableColumn(toolset_table_, "##Overlay", [&]() {
|
|
||||||
if (Button(ICON_MD_LAYERS)) {
|
|
||||||
show_overlay_editor_ = !show_overlay_editor_;
|
|
||||||
}
|
|
||||||
HOVER_HINT("Overlay Editor");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status OverworldEditor::Load() {
|
absl::Status OverworldEditor::Load() {
|
||||||
@@ -263,9 +230,11 @@ void OverworldEditor::DrawToolset() {
|
|||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Customizable shortcuts for the Overworld Editor
|
// Keyboard shortcuts for the Overworld Editor
|
||||||
if (!ImGui::IsAnyItemActive()) {
|
if (!ImGui::IsAnyItemActive()) {
|
||||||
using enum EditingMode;
|
using enum EditingMode;
|
||||||
|
|
||||||
|
// Tool shortcuts
|
||||||
if (ImGui::IsKeyDown(ImGuiKey_1)) {
|
if (ImGui::IsKeyDown(ImGuiKey_1)) {
|
||||||
current_mode = PAN;
|
current_mode = PAN;
|
||||||
} else if (ImGui::IsKeyDown(ImGuiKey_2)) {
|
} else if (ImGui::IsKeyDown(ImGuiKey_2)) {
|
||||||
@@ -283,6 +252,21 @@ void OverworldEditor::DrawToolset() {
|
|||||||
} else if (ImGui::IsKeyDown(ImGuiKey_8)) {
|
} else if (ImGui::IsKeyDown(ImGuiKey_8)) {
|
||||||
current_mode = MUSIC;
|
current_mode = MUSIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// View shortcuts
|
||||||
|
if (ImGui::IsKeyDown(ImGuiKey_F11)) {
|
||||||
|
overworld_canvas_fullscreen_ = !overworld_canvas_fullscreen_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle map lock with L key
|
||||||
|
if (ImGui::IsKeyDown(ImGuiKey_L) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) {
|
||||||
|
current_map_lock_ = !current_map_lock_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle Tile16 editor with T key
|
||||||
|
if (ImGui::IsKeyDown(ImGuiKey_T) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) {
|
||||||
|
show_tile16_editor_ = !show_tile16_editor_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -848,7 +832,8 @@ void OverworldEditor::DrawOverworldCanvas() {
|
|||||||
if (core::FeatureFlags::get().overworld.kLoadCustomOverworld) {
|
if (core::FeatureFlags::get().overworld.kLoadCustomOverworld) {
|
||||||
map_properties_system_->DrawSimplifiedMapSettings(
|
map_properties_system_->DrawSimplifiedMapSettings(
|
||||||
current_world_, current_map_, current_map_lock_, show_map_properties_panel_,
|
current_world_, current_map_, current_map_lock_, show_map_properties_panel_,
|
||||||
show_custom_bg_color_editor_, show_overlay_editor_, show_overlay_preview_, game_state_);
|
show_custom_bg_color_editor_, show_overlay_editor_, show_overlay_preview_, game_state_,
|
||||||
|
reinterpret_cast<int&>(current_mode));
|
||||||
} else {
|
} else {
|
||||||
DrawOverworldMapSettings();
|
DrawOverworldMapSettings();
|
||||||
}
|
}
|
||||||
@@ -1531,56 +1516,49 @@ void OverworldEditor::DrawOverlayEditor() {
|
|||||||
|
|
||||||
Text("Current Map: %d (0x%02X)", current_map_, current_map_);
|
Text("Current Map: %d (0x%02X)", current_map_, current_map_);
|
||||||
|
|
||||||
// Show vanilla overlay information
|
// Show vanilla subscreen overlay information
|
||||||
auto *current_map = overworld_.overworld_map(current_map_);
|
Text("Vanilla ROM - Subscreen Overlays:");
|
||||||
if (current_map->has_vanilla_overlay()) {
|
Text("Subscreen overlays in vanilla ROMs reference special area maps");
|
||||||
Text("Vanilla Overlay ID: 0x%04X", current_map->vanilla_overlay_id());
|
Text("(0x80-0x9F) for visual effects like fog, rain, backgrounds.");
|
||||||
Text("Overlay Data Size: %d bytes",
|
|
||||||
static_cast<int>(current_map->vanilla_overlay_data().size()));
|
Separator();
|
||||||
|
if (Checkbox("Show Subscreen Overlay Preview", &show_overlay_preview_)) {
|
||||||
|
// Toggle subscreen overlay preview
|
||||||
|
}
|
||||||
|
|
||||||
Separator();
|
if (show_overlay_preview_) {
|
||||||
if (Checkbox("Show Overlay Preview", &show_overlay_preview_)) {
|
DrawOverlayPreview();
|
||||||
// Toggle overlay preview
|
|
||||||
}
|
|
||||||
|
|
||||||
if (show_overlay_preview_) {
|
|
||||||
DrawOverlayPreview();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Text("No vanilla overlay data for this map");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Separator();
|
Separator();
|
||||||
Text(
|
Text(
|
||||||
"Note: Vanilla overlays are read-only. Use ZSCustomOverworld v1+ for "
|
"Note: Vanilla subscreen overlays are read-only. Use ZSCustomOverworld v1+ for "
|
||||||
"editable overlays.");
|
"editable subscreen overlays.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (asm_version < 1) {
|
// Subscreen overlays are available for all versions for LW and DW maps
|
||||||
Text("Overlay editor is only available in ZSCustomOverworld v1+");
|
// Check if subscreen overlays are enabled (for custom overworld ROMs)
|
||||||
return;
|
if (asm_version != 0xFF) {
|
||||||
}
|
bool overlay_enabled =
|
||||||
|
(*rom_)[zelda3::OverworldCustomSubscreenOverlayEnabled] != 0x00;
|
||||||
|
if (Checkbox("Enable Subscreen Overlays", &overlay_enabled)) {
|
||||||
|
(*rom_)[zelda3::OverworldCustomSubscreenOverlayEnabled] =
|
||||||
|
overlay_enabled ? 0x01 : 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if subscreen overlays are enabled
|
if (!overlay_enabled) {
|
||||||
bool overlay_enabled =
|
Text("Subscreen overlays are disabled.");
|
||||||
(*rom_)[zelda3::OverworldCustomSubscreenOverlayEnabled] != 0x00;
|
return;
|
||||||
if (Checkbox("Enable Subscreen Overlays", &overlay_enabled)) {
|
}
|
||||||
(*rom_)[zelda3::OverworldCustomSubscreenOverlayEnabled] =
|
|
||||||
overlay_enabled ? 0x01 : 0x00;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!overlay_enabled) {
|
|
||||||
Text("Subscreen overlays are disabled.");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Separator();
|
Separator();
|
||||||
|
|
||||||
// Display current map's overlay
|
// Display current map's subscreen overlay
|
||||||
Text("Current Map: %d (0x%02X)", current_map_, current_map_);
|
Text("Current Map: %d (0x%02X)", current_map_, current_map_);
|
||||||
|
|
||||||
// Get current overlay ID
|
// Get current subscreen overlay ID
|
||||||
uint16_t current_overlay =
|
uint16_t current_overlay =
|
||||||
(*rom_)[zelda3::OverworldCustomSubscreenOverlayArray +
|
(*rom_)[zelda3::OverworldCustomSubscreenOverlayArray +
|
||||||
(current_map_ * 2)] |
|
(current_map_ * 2)] |
|
||||||
@@ -1588,8 +1566,8 @@ void OverworldEditor::DrawOverlayEditor() {
|
|||||||
(current_map_ * 2) + 1]
|
(current_map_ * 2) + 1]
|
||||||
<< 8);
|
<< 8);
|
||||||
|
|
||||||
// Overlay ID input
|
// Subscreen overlay ID input
|
||||||
if (gui::InputHexWord("Overlay ID", ¤t_overlay, 100)) {
|
if (gui::InputHexWord("Subscreen Overlay ID", ¤t_overlay, 100)) {
|
||||||
// Write to ROM
|
// Write to ROM
|
||||||
(*rom_)[zelda3::OverworldCustomSubscreenOverlayArray + (current_map_ * 2)] =
|
(*rom_)[zelda3::OverworldCustomSubscreenOverlayArray + (current_map_ * 2)] =
|
||||||
current_overlay & 0xFF;
|
current_overlay & 0xFF;
|
||||||
@@ -1606,8 +1584,8 @@ void OverworldEditor::DrawOverlayEditor() {
|
|||||||
|
|
||||||
Separator();
|
Separator();
|
||||||
|
|
||||||
// Show overlay information
|
// Show subscreen overlay information
|
||||||
Text("Overlay Information:");
|
Text("Subscreen Overlay Information:");
|
||||||
Text("ID: 0x%04X", current_overlay);
|
Text("ID: 0x%04X", current_overlay);
|
||||||
|
|
||||||
if (current_overlay == 0x00FF) {
|
if (current_overlay == 0x00FF) {
|
||||||
@@ -1638,19 +1616,16 @@ void OverworldEditor::DrawOverlayEditor() {
|
|||||||
void OverworldEditor::DrawOverlayPreview() {
|
void OverworldEditor::DrawOverlayPreview() {
|
||||||
if (!show_overlay_preview_) return;
|
if (!show_overlay_preview_) return;
|
||||||
|
|
||||||
auto *current_map = overworld_.overworld_map(current_map_);
|
Text("Subscreen Overlay Preview:");
|
||||||
if (!current_map->has_vanilla_overlay()) return;
|
|
||||||
|
|
||||||
Text("Overlay Preview:");
|
|
||||||
Separator();
|
Separator();
|
||||||
|
|
||||||
// Get the overlay ID to determine what visual effect this is
|
// Get the subscreen overlay ID from the current map
|
||||||
uint16_t overlay_id = current_map->vanilla_overlay_id();
|
uint16_t overlay_id = overworld_.overworld_map(current_map_)->subscreen_overlay();
|
||||||
|
|
||||||
// Show overlay information
|
// Show subscreen overlay information
|
||||||
Text("Overlay ID: 0x%04X", overlay_id);
|
Text("Subscreen Overlay ID: 0x%04X", overlay_id);
|
||||||
|
|
||||||
// Show overlay description based on common overlay IDs
|
// Show subscreen overlay description based on common overlay IDs
|
||||||
std::string overlay_desc = "";
|
std::string overlay_desc = "";
|
||||||
if (overlay_id == 0x0093) {
|
if (overlay_id == 0x0093) {
|
||||||
overlay_desc = "Triforce Room Curtain";
|
overlay_desc = "Triforce Room Curtain";
|
||||||
@@ -1671,49 +1646,49 @@ void OverworldEditor::DrawOverlayPreview() {
|
|||||||
} else if (overlay_id == 0x009F) {
|
} else if (overlay_id == 0x009F) {
|
||||||
overlay_desc = "Rain Effect (Misery Mire)";
|
overlay_desc = "Rain Effect (Misery Mire)";
|
||||||
} else if (overlay_id == 0x00FF) {
|
} else if (overlay_id == 0x00FF) {
|
||||||
overlay_desc = "No Overlay";
|
overlay_desc = "No Subscreen Overlay";
|
||||||
} else {
|
} else {
|
||||||
overlay_desc = "Custom overlay effect";
|
overlay_desc = "Custom subscreen overlay effect";
|
||||||
}
|
}
|
||||||
Text("Description: %s", overlay_desc.c_str());
|
Text("Description: %s", overlay_desc.c_str());
|
||||||
|
|
||||||
Separator();
|
Separator();
|
||||||
|
|
||||||
// Map overlay ID to special area map for preview
|
// Map subscreen overlay ID to special area map for preview
|
||||||
int overlay_map_index = -1;
|
int overlay_map_index = -1;
|
||||||
if (overlay_id >= 0x80 && overlay_id < 0xA0) {
|
if (overlay_id >= 0x80 && overlay_id < 0xA0) {
|
||||||
overlay_map_index = overlay_id;
|
overlay_map_index = overlay_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overlay_map_index >= 0 && overlay_map_index < zelda3::kNumOverworldMaps) {
|
if (overlay_map_index >= 0 && overlay_map_index < zelda3::kNumOverworldMaps) {
|
||||||
Text("Overlay Source Map: %d (0x%02X)", overlay_map_index, overlay_map_index);
|
Text("Subscreen Overlay Source Map: %d (0x%02X)", overlay_map_index, overlay_map_index);
|
||||||
|
|
||||||
// Get the overlay map's bitmap
|
// Get the subscreen overlay map's bitmap
|
||||||
const auto &overlay_bitmap = maps_bmp_[overlay_map_index];
|
const auto &overlay_bitmap = maps_bmp_[overlay_map_index];
|
||||||
|
|
||||||
if (overlay_bitmap.is_active()) {
|
if (overlay_bitmap.is_active()) {
|
||||||
// Display the overlay map bitmap
|
// Display the subscreen overlay map bitmap
|
||||||
ImVec2 image_size(256, 256); // Scale down for preview
|
ImVec2 image_size(256, 256); // Scale down for preview
|
||||||
ImGui::Image((ImTextureID)(intptr_t)overlay_bitmap.texture(), image_size);
|
ImGui::Image((ImTextureID)(intptr_t)overlay_bitmap.texture(), image_size);
|
||||||
|
|
||||||
Separator();
|
Separator();
|
||||||
Text("This overlay would be displayed semi-transparently");
|
Text("This subscreen overlay would be displayed semi-transparently");
|
||||||
Text("on top of the current map when active.");
|
Text("on top of the current map when active.");
|
||||||
|
|
||||||
// Show drawing order info
|
// Show drawing order info
|
||||||
if (overlay_id == 0x0095 || overlay_id == 0x0096) {
|
if (overlay_id == 0x0095 || overlay_id == 0x0096 || overlay_id == 0x009C) {
|
||||||
Text("Note: This overlay is drawn as a background");
|
Text("Note: This subscreen overlay is drawn as a background");
|
||||||
Text("(behind the main map tiles).");
|
Text("(behind the main map tiles).");
|
||||||
} else {
|
} else {
|
||||||
Text("Note: This overlay is drawn on top of");
|
Text("Note: This subscreen overlay is drawn on top of");
|
||||||
Text("the main map tiles.");
|
Text("the main map tiles.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Text("Overlay map bitmap not available");
|
Text("Subscreen overlay map bitmap not available");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Text("Unknown overlay ID: 0x%04X", overlay_id);
|
Text("Unknown subscreen overlay ID: 0x%04X", overlay_id);
|
||||||
Text("Could not determine overlay source map");
|
Text("Could not determine subscreen overlay source map");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1785,15 +1760,15 @@ void OverworldEditor::DrawOverworldContextMenu() {
|
|||||||
current_map_ = hovered_map;
|
current_map_ = hovered_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MenuItem("Overlay Settings")) {
|
if (MenuItem("Subscreen Overlay Settings")) {
|
||||||
show_overlay_editor_ = true;
|
show_overlay_editor_ = true;
|
||||||
current_map_ = hovered_map;
|
current_map_ = hovered_map;
|
||||||
}
|
}
|
||||||
} else if (asm_version == 0xFF) {
|
} else if (asm_version == 0xFF) {
|
||||||
// Show vanilla overlay information
|
// Show vanilla subscreen overlay information for LW and DW maps only
|
||||||
auto *hovered_map_obj = overworld_.overworld_map(hovered_map);
|
bool is_special_overworld_map = (hovered_map >= 0x80 && hovered_map < 0xA0);
|
||||||
if (hovered_map_obj->has_vanilla_overlay()) {
|
if (!is_special_overworld_map) {
|
||||||
if (MenuItem("View Vanilla Overlay")) {
|
if (MenuItem("View Subscreen Overlay")) {
|
||||||
show_overlay_editor_ = true;
|
show_overlay_editor_ = true;
|
||||||
current_map_ = hovered_map;
|
current_map_ = hovered_map;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ class OverworldEditor : public Editor, public gfx::GfxContext {
|
|||||||
gui::CanvasGridSize::k16x16};
|
gui::CanvasGridSize::k16x16};
|
||||||
gui::Canvas properties_canvas_;
|
gui::Canvas properties_canvas_;
|
||||||
|
|
||||||
gui::Table toolset_table_{"##ToolsetTable0", 25, kToolsetTableFlags};
|
gui::Table toolset_table_{"##ToolsetTable0", 12, kToolsetTableFlags};
|
||||||
gui::Table map_settings_table_{kOWMapTable.data(), 8, kOWMapFlags,
|
gui::Table map_settings_table_{kOWMapTable.data(), 8, kOWMapFlags,
|
||||||
ImVec2(0, 0)};
|
ImVec2(0, 0)};
|
||||||
|
|
||||||
|
|||||||
@@ -72,44 +72,34 @@ absl::Status Tile16Editor::Update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (BeginMenu("Edit")) {
|
if (BeginMenu("Edit")) {
|
||||||
if (MenuItem("Copy Current Tile16")) {
|
if (MenuItem("Copy Current Tile16", "Ctrl+C")) {
|
||||||
RETURN_IF_ERROR(CopyTile16ToClipboard(current_tile16_));
|
RETURN_IF_ERROR(CopyTile16ToClipboard(current_tile16_));
|
||||||
}
|
}
|
||||||
if (MenuItem("Paste to Current Tile16")) {
|
if (MenuItem("Paste to Current Tile16", "Ctrl+V")) {
|
||||||
RETURN_IF_ERROR(PasteTile16FromClipboard());
|
RETURN_IF_ERROR(PasteTile16FromClipboard());
|
||||||
}
|
}
|
||||||
Separator();
|
|
||||||
if (MenuItem("Save to Scratch Space 1")) {
|
|
||||||
RETURN_IF_ERROR(SaveTile16ToScratchSpace(0));
|
|
||||||
}
|
|
||||||
if (MenuItem("Save to Scratch Space 2")) {
|
|
||||||
RETURN_IF_ERROR(SaveTile16ToScratchSpace(1));
|
|
||||||
}
|
|
||||||
if (MenuItem("Save to Scratch Space 3")) {
|
|
||||||
RETURN_IF_ERROR(SaveTile16ToScratchSpace(2));
|
|
||||||
}
|
|
||||||
if (MenuItem("Save to Scratch Space 4")) {
|
|
||||||
RETURN_IF_ERROR(SaveTile16ToScratchSpace(3));
|
|
||||||
}
|
|
||||||
Separator();
|
|
||||||
if (MenuItem("Load from Scratch Space 1")) {
|
|
||||||
RETURN_IF_ERROR(LoadTile16FromScratchSpace(0));
|
|
||||||
}
|
|
||||||
if (MenuItem("Load from Scratch Space 2")) {
|
|
||||||
RETURN_IF_ERROR(LoadTile16FromScratchSpace(1));
|
|
||||||
}
|
|
||||||
if (MenuItem("Load from Scratch Space 3")) {
|
|
||||||
RETURN_IF_ERROR(LoadTile16FromScratchSpace(2));
|
|
||||||
}
|
|
||||||
if (MenuItem("Load from Scratch Space 4")) {
|
|
||||||
RETURN_IF_ERROR(LoadTile16FromScratchSpace(3));
|
|
||||||
}
|
|
||||||
EndMenu();
|
EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BeginMenu("Help")) {
|
if (BeginMenu("Scratch Space")) {
|
||||||
if (MenuItem("About Tile16 Editor")) {
|
for (int i = 0; i < 4; i++) {
|
||||||
OpenPopup("About Tile16 Editor");
|
std::string slot_name = "Slot " + std::to_string(i + 1);
|
||||||
|
if (scratch_space_used_[i]) {
|
||||||
|
if (MenuItem((slot_name + " (Load)").c_str())) {
|
||||||
|
RETURN_IF_ERROR(LoadTile16FromScratchSpace(i));
|
||||||
|
}
|
||||||
|
if (MenuItem((slot_name + " (Save)").c_str())) {
|
||||||
|
RETURN_IF_ERROR(SaveTile16ToScratchSpace(i));
|
||||||
|
}
|
||||||
|
if (MenuItem((slot_name + " (Clear)").c_str())) {
|
||||||
|
RETURN_IF_ERROR(ClearScratchSpace(i));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (MenuItem((slot_name + " (Save)").c_str())) {
|
||||||
|
RETURN_IF_ERROR(SaveTile16ToScratchSpace(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i < 3) Separator();
|
||||||
}
|
}
|
||||||
EndMenu();
|
EndMenu();
|
||||||
}
|
}
|
||||||
@@ -350,38 +340,43 @@ absl::Status Tile16Editor::UpdateTile16Edit() {
|
|||||||
|
|
||||||
// Actions column
|
// Actions column
|
||||||
TableNextColumn();
|
TableNextColumn();
|
||||||
Text("Actions:");
|
Text("Quick Actions:");
|
||||||
|
|
||||||
// Clipboard actions
|
// Clipboard actions in a more compact layout
|
||||||
if (Button("Copy Current Tile16")) {
|
if (BeginTable("##ClipboardActions", 2, ImGuiTableFlags_SizingFixedFit)) {
|
||||||
RETURN_IF_ERROR(CopyTile16ToClipboard(current_tile16_));
|
TableNextColumn();
|
||||||
}
|
if (Button("Copy", ImVec2(60, 0))) {
|
||||||
SameLine();
|
RETURN_IF_ERROR(CopyTile16ToClipboard(current_tile16_));
|
||||||
if (Button("Paste to Current Tile16")) {
|
}
|
||||||
RETURN_IF_ERROR(PasteTile16FromClipboard());
|
TableNextColumn();
|
||||||
|
if (Button("Paste", ImVec2(60, 0))) {
|
||||||
|
RETURN_IF_ERROR(PasteTile16FromClipboard());
|
||||||
|
}
|
||||||
|
EndTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scratch space actions
|
// Scratch space in a compact 2x2 grid
|
||||||
Separator();
|
|
||||||
Text("Scratch Space:");
|
Text("Scratch Space:");
|
||||||
|
if (BeginTable("##ScratchSpace", 2, ImGuiTableFlags_SizingFixedFit)) {
|
||||||
// Create a grid of 4 buttons for scratch space
|
for (int i = 0; i < 4; i++) {
|
||||||
for (int i = 0; i < 4; i++) {
|
TableNextColumn();
|
||||||
if (i > 0) SameLine();
|
std::string slot_name = "Slot " + std::to_string(i + 1);
|
||||||
|
|
||||||
if (scratch_space_used_[i]) {
|
if (scratch_space_used_[i]) {
|
||||||
if (Button(("Slot " + std::to_string(i)).c_str())) {
|
if (Button((slot_name + " (Load)").c_str(), ImVec2(80, 0))) {
|
||||||
RETURN_IF_ERROR(LoadTile16FromScratchSpace(i));
|
RETURN_IF_ERROR(LoadTile16FromScratchSpace(i));
|
||||||
}
|
}
|
||||||
SameLine();
|
SameLine();
|
||||||
if (Button(("Clear##" + std::to_string(i)).c_str())) {
|
if (Button("Clear", ImVec2(40, 0))) {
|
||||||
RETURN_IF_ERROR(ClearScratchSpace(i));
|
RETURN_IF_ERROR(ClearScratchSpace(i));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (Button(("Empty##" + std::to_string(i)).c_str())) {
|
if (Button((slot_name + " (Empty)").c_str(), ImVec2(120, 0))) {
|
||||||
RETURN_IF_ERROR(SaveTile16ToScratchSpace(i));
|
RETURN_IF_ERROR(SaveTile16ToScratchSpace(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
EndTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
EndTable();
|
EndTable();
|
||||||
|
|||||||
46
src/app/editor/overworld/ui_constants.h
Normal file
46
src/app/editor/overworld/ui_constants.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#ifndef YAZE_APP_EDITOR_OVERWORLD_UI_CONSTANTS_H
|
||||||
|
#define YAZE_APP_EDITOR_OVERWORLD_UI_CONSTANTS_H
|
||||||
|
|
||||||
|
namespace yaze {
|
||||||
|
namespace editor {
|
||||||
|
|
||||||
|
// Game State Labels
|
||||||
|
inline constexpr const char* kGameStateNames[] = {
|
||||||
|
"Rain & Rescue Zelda",
|
||||||
|
"Pendants",
|
||||||
|
"Crystals"
|
||||||
|
};
|
||||||
|
|
||||||
|
// World Labels
|
||||||
|
inline constexpr const char* kWorldNames[] = {
|
||||||
|
"Light World",
|
||||||
|
"Dark World",
|
||||||
|
"Special World"
|
||||||
|
};
|
||||||
|
|
||||||
|
// Area Size Names
|
||||||
|
inline constexpr const char* kAreaSizeNames[] = {
|
||||||
|
"Small (1x1)",
|
||||||
|
"Large (2x2)",
|
||||||
|
"Wide (2x1)",
|
||||||
|
"Tall (1x2)"
|
||||||
|
};
|
||||||
|
|
||||||
|
// UI Styling Constants
|
||||||
|
inline constexpr float kInputFieldSize = 30.f;
|
||||||
|
inline constexpr float kCompactButtonWidth = 60.f;
|
||||||
|
inline constexpr float kIconButtonWidth = 30.f;
|
||||||
|
inline constexpr float kSmallButtonWidth = 80.f;
|
||||||
|
inline constexpr float kMediumButtonWidth = 90.f;
|
||||||
|
inline constexpr float kLargeButtonWidth = 100.f;
|
||||||
|
|
||||||
|
// Spacing and Padding
|
||||||
|
inline constexpr float kCompactItemSpacing = 4.f;
|
||||||
|
inline constexpr float kCompactFramePadding = 2.f;
|
||||||
|
|
||||||
|
// Map Size Constants - using the one from overworld_editor.h
|
||||||
|
|
||||||
|
} // namespace editor
|
||||||
|
} // namespace yaze
|
||||||
|
|
||||||
|
#endif // YAZE_APP_EDITOR_OVERWORLD_UI_CONSTANTS_H
|
||||||
@@ -58,7 +58,7 @@ absl::Status OverworldMap::BuildMap(int count, int game_state, int world,
|
|||||||
RETURN_IF_ERROR(BuildTileset())
|
RETURN_IF_ERROR(BuildTileset())
|
||||||
RETURN_IF_ERROR(BuildTiles16Gfx(tiles16, count))
|
RETURN_IF_ERROR(BuildTiles16Gfx(tiles16, count))
|
||||||
RETURN_IF_ERROR(LoadPalette());
|
RETURN_IF_ERROR(LoadPalette());
|
||||||
RETURN_IF_ERROR(LoadVanillaOverlay());
|
RETURN_IF_ERROR(LoadOverlay());
|
||||||
RETURN_IF_ERROR(BuildBitmap(world_blockset))
|
RETURN_IF_ERROR(BuildBitmap(world_blockset))
|
||||||
built_ = true;
|
built_ = true;
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
@@ -825,18 +825,25 @@ absl::Status OverworldMap::LoadPalette() {
|
|||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status OverworldMap::LoadVanillaOverlay() {
|
absl::Status OverworldMap::LoadOverlay() {
|
||||||
uint8_t asm_version = (*rom_)[OverworldCustomASMHasBeenApplied];
|
uint8_t asm_version = (*rom_)[OverworldCustomASMHasBeenApplied];
|
||||||
|
|
||||||
// Only load vanilla overlays if this is a vanilla ROM (asm_version == 0xFF)
|
// Load overlays based on ROM version
|
||||||
if (asm_version != 0xFF) {
|
if (asm_version == 0xFF) {
|
||||||
has_vanilla_overlay_ = false;
|
// Vanilla ROM - load overlay from overlay pointers
|
||||||
vanilla_overlay_id_ = 0;
|
return LoadVanillaOverlayData();
|
||||||
vanilla_overlay_data_.clear();
|
} else {
|
||||||
|
// Custom overworld ROM - use overlay from custom data
|
||||||
|
overlay_id_ = subscreen_overlay_;
|
||||||
|
has_overlay_ = (overlay_id_ != 0x00FF);
|
||||||
|
overlay_data_.clear();
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::Status OverworldMap::LoadVanillaOverlayData() {
|
||||||
|
|
||||||
// Load vanilla overlay for this map
|
// Load vanilla overlay for this map (interactive overlays for revealing holes/changing elements)
|
||||||
int address = (kOverlayPointersBank << 16) +
|
int address = (kOverlayPointersBank << 16) +
|
||||||
((*rom_)[kOverlayPointers + (index_ * 2) + 1] << 8) +
|
((*rom_)[kOverlayPointers + (index_ * 2) + 1] << 8) +
|
||||||
(*rom_)[kOverlayPointers + (index_ * 2)];
|
(*rom_)[kOverlayPointers + (index_ * 2)];
|
||||||
@@ -855,26 +862,26 @@ absl::Status OverworldMap::LoadVanillaOverlay() {
|
|||||||
|
|
||||||
// Validate address
|
// Validate address
|
||||||
if (address >= rom_->size()) {
|
if (address >= rom_->size()) {
|
||||||
has_vanilla_overlay_ = false;
|
has_overlay_ = false;
|
||||||
vanilla_overlay_id_ = 0;
|
overlay_id_ = 0;
|
||||||
vanilla_overlay_data_.clear();
|
overlay_data_.clear();
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse overlay data
|
// Parse overlay data (interactive overlays)
|
||||||
vanilla_overlay_data_.clear();
|
overlay_data_.clear();
|
||||||
uint8_t b = (*rom_)[address];
|
uint8_t b = (*rom_)[address];
|
||||||
|
|
||||||
// Parse overlay commands until we hit END (0x60)
|
// Parse overlay commands until we hit END (0x60)
|
||||||
while (b != 0x60 && address < rom_->size()) {
|
while (b != 0x60 && address < rom_->size()) {
|
||||||
vanilla_overlay_data_.push_back(b);
|
overlay_data_.push_back(b);
|
||||||
|
|
||||||
// Handle different overlay commands
|
// Handle different overlay commands
|
||||||
switch (b) {
|
switch (b) {
|
||||||
case 0xA9: // LDA #$
|
case 0xA9: // LDA #$
|
||||||
if (address + 2 < rom_->size()) {
|
if (address + 2 < rom_->size()) {
|
||||||
vanilla_overlay_data_.push_back((*rom_)[address + 1]);
|
overlay_data_.push_back((*rom_)[address + 1]);
|
||||||
vanilla_overlay_data_.push_back((*rom_)[address + 2]);
|
overlay_data_.push_back((*rom_)[address + 2]);
|
||||||
address += 3;
|
address += 3;
|
||||||
} else {
|
} else {
|
||||||
address++;
|
address++;
|
||||||
@@ -882,8 +889,8 @@ absl::Status OverworldMap::LoadVanillaOverlay() {
|
|||||||
break;
|
break;
|
||||||
case 0xA2: // LDX #$
|
case 0xA2: // LDX #$
|
||||||
if (address + 2 < rom_->size()) {
|
if (address + 2 < rom_->size()) {
|
||||||
vanilla_overlay_data_.push_back((*rom_)[address + 1]);
|
overlay_data_.push_back((*rom_)[address + 1]);
|
||||||
vanilla_overlay_data_.push_back((*rom_)[address + 2]);
|
overlay_data_.push_back((*rom_)[address + 2]);
|
||||||
address += 3;
|
address += 3;
|
||||||
} else {
|
} else {
|
||||||
address++;
|
address++;
|
||||||
@@ -891,9 +898,9 @@ absl::Status OverworldMap::LoadVanillaOverlay() {
|
|||||||
break;
|
break;
|
||||||
case 0x8D: // STA $xxxx
|
case 0x8D: // STA $xxxx
|
||||||
if (address + 3 < rom_->size()) {
|
if (address + 3 < rom_->size()) {
|
||||||
vanilla_overlay_data_.push_back((*rom_)[address + 1]);
|
overlay_data_.push_back((*rom_)[address + 1]);
|
||||||
vanilla_overlay_data_.push_back((*rom_)[address + 2]);
|
overlay_data_.push_back((*rom_)[address + 2]);
|
||||||
vanilla_overlay_data_.push_back((*rom_)[address + 3]);
|
overlay_data_.push_back((*rom_)[address + 3]);
|
||||||
address += 4;
|
address += 4;
|
||||||
} else {
|
} else {
|
||||||
address++;
|
address++;
|
||||||
@@ -901,9 +908,9 @@ absl::Status OverworldMap::LoadVanillaOverlay() {
|
|||||||
break;
|
break;
|
||||||
case 0x9D: // STA $xxxx,x
|
case 0x9D: // STA $xxxx,x
|
||||||
if (address + 3 < rom_->size()) {
|
if (address + 3 < rom_->size()) {
|
||||||
vanilla_overlay_data_.push_back((*rom_)[address + 1]);
|
overlay_data_.push_back((*rom_)[address + 1]);
|
||||||
vanilla_overlay_data_.push_back((*rom_)[address + 2]);
|
overlay_data_.push_back((*rom_)[address + 2]);
|
||||||
vanilla_overlay_data_.push_back((*rom_)[address + 3]);
|
overlay_data_.push_back((*rom_)[address + 3]);
|
||||||
address += 4;
|
address += 4;
|
||||||
} else {
|
} else {
|
||||||
address++;
|
address++;
|
||||||
@@ -911,10 +918,10 @@ absl::Status OverworldMap::LoadVanillaOverlay() {
|
|||||||
break;
|
break;
|
||||||
case 0x8F: // STA $xxxxxx
|
case 0x8F: // STA $xxxxxx
|
||||||
if (address + 4 < rom_->size()) {
|
if (address + 4 < rom_->size()) {
|
||||||
vanilla_overlay_data_.push_back((*rom_)[address + 1]);
|
overlay_data_.push_back((*rom_)[address + 1]);
|
||||||
vanilla_overlay_data_.push_back((*rom_)[address + 2]);
|
overlay_data_.push_back((*rom_)[address + 2]);
|
||||||
vanilla_overlay_data_.push_back((*rom_)[address + 3]);
|
overlay_data_.push_back((*rom_)[address + 3]);
|
||||||
vanilla_overlay_data_.push_back((*rom_)[address + 4]);
|
overlay_data_.push_back((*rom_)[address + 4]);
|
||||||
address += 5;
|
address += 5;
|
||||||
} else {
|
} else {
|
||||||
address++;
|
address++;
|
||||||
@@ -925,9 +932,9 @@ absl::Status OverworldMap::LoadVanillaOverlay() {
|
|||||||
break;
|
break;
|
||||||
case 0x4C: // JMP
|
case 0x4C: // JMP
|
||||||
if (address + 3 < rom_->size()) {
|
if (address + 3 < rom_->size()) {
|
||||||
vanilla_overlay_data_.push_back((*rom_)[address + 1]);
|
overlay_data_.push_back((*rom_)[address + 1]);
|
||||||
vanilla_overlay_data_.push_back((*rom_)[address + 2]);
|
overlay_data_.push_back((*rom_)[address + 2]);
|
||||||
vanilla_overlay_data_.push_back((*rom_)[address + 3]);
|
overlay_data_.push_back((*rom_)[address + 3]);
|
||||||
address += 4;
|
address += 4;
|
||||||
} else {
|
} else {
|
||||||
address++;
|
address++;
|
||||||
@@ -947,12 +954,12 @@ absl::Status OverworldMap::LoadVanillaOverlay() {
|
|||||||
|
|
||||||
// Add the END command if we found it
|
// Add the END command if we found it
|
||||||
if (b == 0x60) {
|
if (b == 0x60) {
|
||||||
vanilla_overlay_data_.push_back(0x60);
|
overlay_data_.push_back(0x60);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set overlay ID based on map index (simplified)
|
// Set overlay ID based on map index (simplified)
|
||||||
vanilla_overlay_id_ = index_;
|
overlay_id_ = index_;
|
||||||
has_vanilla_overlay_ = !vanilla_overlay_data_.empty();
|
has_overlay_ = !overlay_data_.empty();
|
||||||
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,7 +105,8 @@ class OverworldMap : public gfx::GfxContext {
|
|||||||
|
|
||||||
void LoadAreaGraphics();
|
void LoadAreaGraphics();
|
||||||
absl::Status LoadPalette();
|
absl::Status LoadPalette();
|
||||||
absl::Status LoadVanillaOverlay();
|
absl::Status LoadOverlay();
|
||||||
|
absl::Status LoadVanillaOverlayData();
|
||||||
absl::Status BuildTileset();
|
absl::Status BuildTileset();
|
||||||
absl::Status BuildTiles16Gfx(std::vector<gfx::Tile16>& tiles16, int count);
|
absl::Status BuildTiles16Gfx(std::vector<gfx::Tile16>& tiles16, int count);
|
||||||
absl::Status BuildBitmap(OverworldBlockset& world_blockset);
|
absl::Status BuildBitmap(OverworldBlockset& world_blockset);
|
||||||
@@ -148,10 +149,10 @@ class OverworldMap : public gfx::GfxContext {
|
|||||||
|
|
||||||
auto custom_tileset(int index) const { return custom_gfx_ids_[index]; }
|
auto custom_tileset(int index) const { return custom_gfx_ids_[index]; }
|
||||||
|
|
||||||
// Vanilla overlay accessors
|
// Overlay accessors (interactive overlays)
|
||||||
auto vanilla_overlay_id() const { return vanilla_overlay_id_; }
|
auto overlay_id() const { return overlay_id_; }
|
||||||
auto has_vanilla_overlay() const { return has_vanilla_overlay_; }
|
auto has_overlay() const { return has_overlay_; }
|
||||||
const auto& vanilla_overlay_data() const { return vanilla_overlay_data_; }
|
const auto& overlay_data() const { return overlay_data_; }
|
||||||
|
|
||||||
// Mosaic expanded accessors
|
// Mosaic expanded accessors
|
||||||
const std::array<bool, 4>& mosaic_expanded() const { return mosaic_expanded_; }
|
const std::array<bool, 4>& mosaic_expanded() const { return mosaic_expanded_; }
|
||||||
@@ -233,9 +234,9 @@ class OverworldMap : public gfx::GfxContext {
|
|||||||
static_graphics_.fill(0);
|
static_graphics_.fill(0);
|
||||||
mosaic_expanded_.fill(false);
|
mosaic_expanded_.fill(false);
|
||||||
area_size_ = AreaSizeEnum::SmallArea;
|
area_size_ = AreaSizeEnum::SmallArea;
|
||||||
vanilla_overlay_id_ = 0;
|
overlay_id_ = 0;
|
||||||
has_vanilla_overlay_ = false;
|
has_overlay_ = false;
|
||||||
vanilla_overlay_data_.clear();
|
overlay_data_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -287,10 +288,10 @@ class OverworldMap : public gfx::GfxContext {
|
|||||||
|
|
||||||
std::array<bool, 4> mosaic_expanded_;
|
std::array<bool, 4> mosaic_expanded_;
|
||||||
|
|
||||||
// Vanilla overlay support
|
// Overlay support (interactive overlays that reveal holes/change elements)
|
||||||
uint16_t vanilla_overlay_id_ = 0;
|
uint16_t overlay_id_ = 0;
|
||||||
bool has_vanilla_overlay_ = false;
|
bool has_overlay_ = false;
|
||||||
std::vector<uint8_t> vanilla_overlay_data_;
|
std::vector<uint8_t> overlay_data_;
|
||||||
|
|
||||||
std::vector<uint8_t> current_blockset_;
|
std::vector<uint8_t> current_blockset_;
|
||||||
std::vector<uint8_t> current_gfx_;
|
std::vector<uint8_t> current_gfx_;
|
||||||
|
|||||||
Reference in New Issue
Block a user