5#define IM_PI 3.14159265358979323846f
22#include <unordered_map>
27#include "absl/status/status.h"
28#include "absl/strings/str_format.h"
29#include "imgui/imgui.h"
132 toolbar_ = std::make_unique<OverworldToolbar>();
133 toolbar_->on_refresh_graphics = [
this]() {
139 toolbar_->on_refresh_map = [
this]() {
143 toolbar_->on_save_to_scratch = [
this]() {
146 toolbar_->on_load_from_scratch = [
this]() {
192 tile_painting_ = std::make_unique<TilePaintingManager>(deps, callbacks);
229 canvas_nav_ = std::make_unique<CanvasNavigationManager>();
236 LOG_DEBUG(
"OverworldEditor",
"Loading overworld.");
238 return absl::FailedPreconditionError(
"ROM not loaded");
263 "Overworld editor refreshed after Tile16 changes");
264 return absl::OkStatus();
270 [
this](
const std::string& entity_type) {
284 [
this](
const std::string& group_name,
int palette_index) {
286 if (group_name ==
"ow_main" || group_name ==
"ow_animated" ||
287 group_name ==
"ow_aux" || group_name ==
"grass") {
289 "Palette change detected: %s, refreshing current map",
297 LOG_DEBUG(
"OverworldEditor",
"Registered as palette listener (ID: %d)",
302 return absl::OkStatus();
311 return absl::OkStatus();
316 return absl::OkStatus();
352 ImGui::SetNextWindowSize(ImVec2(400, 500), ImGuiCond_FirstUseEver);
366 ImGui::SetNextWindowSize(ImVec2(500, 450), ImGuiCond_FirstUseEver);
367 if (ImGui::Begin(
ICON_MD_LAYERS " Visual Effects Editor###OverlayEditor",
387 if (ImGui::BeginPopupModal(
"Entity Insert Error",
nullptr,
388 ImGuiWindowFlags_AlwaysAutoResize)) {
390 ImGui::TextColored(theme.status_error,
395 ImGui::TextDisabled(
"Tip: Delete an existing entity to free up a slot.");
397 if (ImGui::Button(
"OK", ImVec2(120, 0))) {
399 ImGui::CloseCurrentPopup();
406 if (ImGui::BeginPopupModal(
"UpgradeROMVersion",
nullptr,
407 ImGuiWindowFlags_AlwaysAutoResize)) {
411 "This will apply the ZSCustomOverworld ASM patch to your ROM,\n"
412 "enabling advanced features like custom tile graphics, animated GFX,\n"
413 "wide/tall areas, and more.");
417 ImGui::Text(
"Current Version: %s",
418 current_version == 0xFF
420 : absl::StrFormat(
"v%d", current_version).c_str());
422 static int target_version = 3;
423 ImGui::RadioButton(
"v2 (Basic features)", &target_version, 2);
425 ImGui::RadioButton(
"v3 (All features)", &target_version, 3);
429 if (ImGui::Button(
ICON_MD_CHECK " Apply Upgrade", ImVec2(150, 0))) {
435 ImGui::CloseCurrentPopup();
437 LOG_ERROR(
"OverworldEditor",
"Upgrade failed: %s",
438 status.message().data());
443 ImGui::CloseCurrentPopup();
463 return absl::OkStatus();
468 if (ImGui::IsAnyItemActive()) {
474 const bool ctrl_held = ImGui::IsKeyDown(ImGuiKey_LeftCtrl) ||
475 ImGui::IsKeyDown(ImGuiKey_RightCtrl);
476 const bool alt_held = ImGui::IsKeyDown(ImGuiKey_LeftAlt) ||
477 ImGui::IsKeyDown(ImGuiKey_RightAlt);
483 if (ImGui::IsKeyPressed(ImGuiKey_1,
false)) {
485 }
else if (ImGui::IsKeyPressed(ImGuiKey_2,
false)) {
490 if (!ctrl_held && !alt_held) {
491 if (ImGui::IsKeyPressed(ImGuiKey_B,
false)) {
494 if (ImGui::IsKeyPressed(ImGuiKey_F,
false)) {
497 if (ImGui::IsKeyPressed(ImGuiKey_I,
false)) {
516 if (ImGui::IsKeyPressed(ImGuiKey_F11,
false)) {
521 if (ctrl_held && ImGui::IsKeyPressed(ImGuiKey_L,
false)) {
526 if (ctrl_held && ImGui::IsKeyPressed(ImGuiKey_T,
false)) {
539 if (ImGui::IsKeyDown(ImGuiKey_3)) {
543 }
else if (ImGui::IsKeyDown(ImGuiKey_4)) {
547 }
else if (ImGui::IsKeyDown(ImGuiKey_5)) {
551 }
else if (ImGui::IsKeyDown(ImGuiKey_6)) {
555 }
else if (ImGui::IsKeyDown(ImGuiKey_7)) {
559 }
else if (ImGui::IsKeyDown(ImGuiKey_8)) {
568 bool ctrl_held = ImGui::IsKeyDown(ImGuiKey_LeftCtrl) ||
569 ImGui::IsKeyDown(ImGuiKey_RightCtrl);
575 if (ImGui::IsKeyPressed(ImGuiKey_Z,
false)) {
576 bool shift_held = ImGui::IsKeyDown(ImGuiKey_LeftShift) ||
577 ImGui::IsKeyDown(ImGuiKey_RightShift);
586 if (ImGui::IsKeyPressed(ImGuiKey_Y,
false)) {
613 if (!ImGui::IsMouseClicked(ImGuiMouseButton_Right)) {
617 if (!hovered_entity) {
655 if (!hovered_entity || !ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
713 return absl::FailedPreconditionError(
"Clipboard unavailable");
718 std::vector<int> ids;
723 static_cast<int>(std::floor(std::min(start.x, end.x) / 16.0f));
725 static_cast<int>(std::floor(std::max(start.x, end.x) / 16.0f));
727 static_cast<int>(std::floor(std::min(start.y, end.y) / 16.0f));
729 static_cast<int>(std::floor(std::max(start.y, end.y) / 16.0f));
730 const int width = end_x - start_x + 1;
731 const int height = end_y - start_y + 1;
732 ids.reserve(width * height);
735 for (
int y = start_y; y <= end_y; ++y) {
736 for (
int x = start_x; x <= end_x; ++x) {
745 return absl::OkStatus();
753 return absl::OkStatus();
755 return absl::FailedPreconditionError(
"Nothing selected to copy");
760 return absl::FailedPreconditionError(
"Clipboard unavailable");
763 return absl::FailedPreconditionError(
"Clipboard empty");
767 return absl::FailedPreconditionError(
"No paste target");
776 const ImVec2 anchor =
777 ImVec2(scaled_anchor.x / scale, scaled_anchor.y / scale);
785 auto& selected_world =
792 const int superY = local_map / 8;
793 const int superX = local_map % 8;
800 if (width * height !=
static_cast<int>(ids.size())) {
801 return absl::InternalError(
"Clipboard dimensions mismatch");
804 bool any_changed =
false;
805 for (
int dy = 0; dy < height; ++dy) {
806 for (
int dx = 0; dx < width; ++dx) {
807 const int id = ids[dy * width + dx];
808 const int gx = tile16_x + dx;
809 const int gy = tile16_y + dy;
811 const int global_x = superX * 32 + gx;
812 const int global_y = superY * 32 + gy;
813 if (global_x < 0 || global_x >= 256 || global_y < 0 || global_y >= 256)
815 const int old_tile_id = selected_world[global_x][global_y];
816 if (old_tile_id ==
id) {
821 selected_world[global_x][global_y] = id;
831 return absl::OkStatus();
836 return absl::OkStatus();
845 return absl::OkStatus();
865 auto conflicts = manifest.AnalyzePcWriteRanges(ranges);
866 if (!conflicts.empty()) {
867 std::string error_msg =
868 "Hack manifest write conflicts while saving overworld maps:\n\n";
869 for (
const auto& conflict : conflicts) {
872 absl::StrFormat(
"- Address 0x%06X is %s", conflict.address,
874 if (!conflict.module.empty()) {
875 absl::StrAppend(&error_msg,
" (Module: ", conflict.module,
")");
877 absl::StrAppend(&error_msg,
"\n");
881 LOG_DEBUG(
"OverworldEditor",
"%s", error_msg.c_str());
883 LOG_WARN(
"OverworldEditor",
"%s", error_msg.c_str());
889 "Save warning: write conflict with hack manifest (see log)",
896 "Save blocked: write conflict with hack manifest (see log)",
899 return absl::PermissionDeniedError(
"Write conflict with Hack Manifest");
923 return absl::OkStatus();
943 auto now = std::chrono::steady_clock::now();
962 .tile_changes = {{{x, y}, old_tile_id}},
976 std::vector<OverworldTileChange> changes;
978 for (
const auto& [coords, old_tile_id] :
980 auto [x, y] = coords;
981 int new_tile_id = world_tiles[x][y];
982 changes.push_back({x, y, old_tile_id, new_tile_id});
984 auto action = std::make_unique<OverworldTilePaintAction>(
987 [
this]() { RefreshOverworldMap(); });
1009 LOG_DEBUG(
"OverworldEditor",
"Loading overworld.");
1025 LOG_DEBUG(
"OverworldEditor",
"Loading overworld graphics (optimized).");
1039 "Loading overworld tileset (deferred textures).");
1052 LOG_DEBUG(
"OverworldEditor",
"Loading overworld tile16 graphics.");
1071#ifdef __EMSCRIPTEN__
1072 constexpr int kEssentialMapsPerWorld = 4;
1074 constexpr int kEssentialMapsPerWorld =
1077 constexpr int kLightWorldEssential = kEssentialMapsPerWorld;
1078 constexpr int kDarkWorldEssential =
1080 constexpr int kSpecialWorldEssential =
1085 "Creating bitmaps for essential maps only (first %d maps per world)",
1086 kEssentialMapsPerWorld);
1088 std::vector<gfx::Bitmap*> maps_to_texture;
1089 maps_to_texture.reserve(kEssentialMapsPerWorld *
1095 bool is_essential =
false;
1098 if (i < kLightWorldEssential) {
1099 is_essential =
true;
1101 is_essential =
true;
1103 i < kSpecialWorldEssential) {
1104 is_essential =
true;
1115 maps_to_texture.push_back(&
maps_bmp_[i]);
1116 }
catch (
const std::bad_alloc& e) {
1117 std::cout <<
"Error allocating map " << i <<
": " << e.what()
1128 const int initial_texture_count =
1129 std::min(4,
static_cast<int>(maps_to_texture.size()));
1132 for (
int i = 0; i < initial_texture_count; ++i) {
1142 for (
size_t i = initial_texture_count; i < maps_to_texture.size(); ++i) {
1146 if (&
maps_bmp_[j] == maps_to_texture[i]) {
1153 if (map_index >= 0) {
1154 int map_world = map_index / 0x40;
1173 return absl::OkStatus();
1178 const int depth = 0x10;
1179 for (
int i = 0; i < 3; i++)
1181 int width = sprite.width();
1182 int height = sprite.height();
1183 if (width == 0 || height == 0) {
1190 *sprite.preview_graphics());
1196 return absl::OkStatus();
1206 int refresh_count = 0;
1207 const int max_refreshes_per_frame = 2;
1217 if (is_current_map || is_current_world) {
1233 LOG_ERROR(
"OverworldEditor",
"Failed to build map %d: %s", map_index,
1241 if (!bitmap.is_active()) {
1247 bitmap.SetPalette(palette);
1248 }
catch (
const std::bad_alloc& e) {
1249 LOG_ERROR(
"OverworldEditor",
"Error allocating bitmap for map %d: %s",
1250 map_index, e.what());
1255 if (!bitmap.texture() && bitmap.is_active()) {
1282 map_refresh_ = std::make_unique<MapRefreshCoordinator>(ctx);
1304 return absl::OkStatus();
1312 if (target_version < 2 || target_version > 3) {
1313 return absl::InvalidArgumentError(absl::StrFormat(
1314 "Invalid target version: %d. Must be 2 or 3.", target_version));
1319 if (current_version != 0xFF && current_version >= target_version) {
1320 return absl::AlreadyExistsError(absl::StrFormat(
1321 "ROM is already version %d or higher", current_version));
1324 LOG_DEBUG(
"OverworldEditor",
"Applying ZSCustomOverworld ASM v%d to ROM...",
1328 auto asar_wrapper = std::make_unique<core::AsarWrapper>();
1332 std::vector<uint8_t> original_rom_data =
rom_->
vector();
1333 std::vector<uint8_t> working_rom_data = original_rom_data;
1338 std::string asm_file_name =
1339 (target_version == 3) ?
"asm/yaze.asm"
1340 :
"asm/ZSCustomOverworld.asm";
1346 LOG_DEBUG(
"OverworldEditor",
"Using ASM file: %s", asm_file_path.c_str());
1349 if (!std::filesystem::exists(asm_file_path)) {
1350 return absl::NotFoundError(
1351 absl::StrFormat(
"ASM file not found at: %s\n\n"
1352 "Expected location: assets/%s\n"
1353 "Make sure the assets directory is accessible.",
1354 asm_file_path, asm_file_name));
1359 asar_wrapper->ApplyPatch(asm_file_path, working_rom_data);
1360 if (!patch_result.ok()) {
1361 return absl::InternalError(absl::StrFormat(
1362 "Failed to apply ASM patch: %s", patch_result.status().message()));
1365 const auto& result = patch_result.value();
1366 if (!result.success) {
1367 std::string error_details =
"ASM patch failed with errors:\n";
1368 for (
const auto& error : result.errors) {
1369 error_details +=
" - " + error +
"\n";
1371 if (!result.warnings.empty()) {
1372 error_details +=
"Warnings:\n";
1373 for (
const auto& warning : result.warnings) {
1374 error_details +=
" - " + warning +
"\n";
1377 return absl::InternalError(error_details);
1388 "ASM patch applied successfully. Found %zu symbols:",
1389 result.symbols.size());
1390 for (
const auto& symbol : result.symbols) {
1391 LOG_DEBUG(
"OverworldEditor",
" %s @ $%06X", symbol.name.c_str(),
1399 "ZSCustomOverworld v%d successfully applied to ROM",
1401 return absl::OkStatus();
1403 }
catch (
const std::exception& e) {
1406 if (!restore_result.ok()) {
1407 LOG_ERROR(
"OverworldEditor",
"Failed to restore ROM data: %s",
1408 restore_result.message().data());
1410 return absl::InternalError(
1411 absl::StrFormat(
"Exception during ASM application: %s", e.what()));
1418 static_cast<uint8_t
>(target_version);
1421 if (target_version >= 2) {
1427 "Enabled v2+ features: Custom BG colors, Main palettes");
1430 if (target_version >= 3) {
1439 "Enabled v3+ features: Subscreen overlays, Animated GFX, Tile GFX "
1443 for (
int i = 0; i < 0xA0; i++) {
1449 const std::vector<int> large_areas = {
1450 0x00, 0x02, 0x05, 0x07, 0x0A, 0x0B, 0x0F, 0x10, 0x11, 0x12,
1451 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1D,
1452 0x1E, 0x25, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2E, 0x2F, 0x30,
1453 0x32, 0x33, 0x34, 0x35, 0x37, 0x3A, 0x3B, 0x3C, 0x3F};
1455 for (
int area_id : large_areas) {
1456 if (area_id < 0xA0) {
1462 LOG_DEBUG(
"OverworldEditor",
"Initialized area size data for %zu areas",
1463 large_areas.size());
1466 LOG_DEBUG(
"OverworldEditor",
"ROM version markers updated to v%d",
1468 return absl::OkStatus();
void set_dirty(bool dirty)
const auto & vector() const
absl::Status LoadFromData(const std::vector< uint8_t > &data, const LoadOptions &options=LoadOptions::Defaults())
bool loaded() const
Check if the manifest has been loaded.
UndoManager undo_manager_
EditorDependencies dependencies_
std::unique_ptr< UsageStatisticsCard > usage_stats_card_
absl::Status Clear() override
std::unique_ptr< MapPropertiesSystem > map_properties_system_
std::unique_ptr< OverworldCanvasRenderer > canvas_renderer_
zelda3::OverworldItem current_item_
void HandleMapInteraction()
bool overworld_canvas_fullscreen_
bool map_blockset_loaded_
void HandleEntityInteraction()
Handle entity interaction in MOUSE mode Includes: right-click context menus, double-click navigation,...
zelda3::OverworldEntranceTileTypes entrance_tiletypes_
zelda3::OverworldEntrance current_entrance_
void HandleTile16Edit()
Handle tile16 editing from context menu (MOUSE mode) Gets the tile16 under the cursor and opens the T...
absl::Status ApplyZSCustomOverworldASM(int target_version)
Apply ZSCustomOverworld ASM patch to upgrade ROM version.
zelda3::Sprite current_sprite_
std::optional< OverworldUndoPoint > current_paint_operation_
std::string entity_insert_error_message_
absl::Status CheckForCurrentMap()
Check for map changes and refresh if needed.
void CreateUndoPoint(int map_id, int world, int x, int y, int old_tile_id)
absl::Status LoadScratchToSelection()
void ForceRefreshGraphics(int map_index)
std::vector< int > selected_tile16_ids_
gfx::Bitmap current_gfx_bmp_
gfx::Tilemap tile16_blockset_
void ProcessPendingEntityInsertion()
Process any pending entity insertion request Called from Update() - needed because ImGui::OpenPopup()...
void InitCanvasNavigationManager()
Initialize the canvas navigation manager (called during Initialize)
void InitMapRefreshCoordinator()
Initialize the map refresh coordinator (called during Initialize)
void CycleTileSelection(int delta)
Tile16Editor tile16_editor_
gui::Canvas ow_map_canvas_
absl::Status Undo() override
void HandleEntityInsertion(const std::string &entity_type)
Handle entity insertion from context menu.
std::unique_ptr< MapRefreshCoordinator > map_refresh_
std::array< gfx::Bitmap, zelda3::kNumOverworldMaps > maps_bmp_
bool PickTile16FromHoveredCanvas()
bool show_map_properties_panel_
void RefreshOverworldMap()
void CheckForOverworldEdits()
Check for tile edits - delegates to TilePaintingManager.
absl::Status UpdateROMVersionMarkers(int target_version)
Update ROM version markers and feature flags after ASM patching.
zelda3::OverworldExit current_exit_
void UpdateBlocksetWithPendingTileChanges()
void RefreshMapProperties()
void RefreshSiblingMapGraphics(int map_index, bool include_self=false)
void RefreshOverworldMapOnDemand(int map_index)
void Initialize() override
bool show_overlay_editor_
std::unique_ptr< OverworldSidebar > sidebar_
absl::Status Redo() override
void SetupCanvasAutomation()
std::chrono::steady_clock::time_point last_paint_time_
void InvalidateGraphicsCache(int map_id=-1)
Invalidate cached graphics for a specific map or all maps.
void HandleEntityDoubleClick(zelda3::GameEntity *hovered_entity)
Handle double-click actions on entities (e.g., jump to room)
void HandleEntityContextMenus(zelda3::GameEntity *hovered_entity)
Handle right-click context menus for entities.
absl::Status SaveCurrentSelectionToScratch()
absl::Status RefreshMapPalette()
absl::Status RefreshTile16Blockset()
zelda3::Overworld & overworld()
Access the underlying Overworld data.
void UpdateBlocksetSelectorState()
void FinalizePaintOperation()
std::unique_ptr< OverworldEntityRenderer > entity_renderer_
auto & GetWorldTiles(int world)
absl::Status Load() override
absl::Status UpdateGfxGroupEditor()
void EnsureMapTexture(int map_index)
Ensure a specific map has its texture created.
std::vector< gfx::Bitmap > sprite_previews_
std::unique_ptr< CanvasNavigationManager > canvas_nav_
absl::Status Copy() override
EntityEditMode entity_edit_mode_
std::unique_ptr< OverworldToolbar > toolbar_
GfxGroupEditor gfx_group_editor_
void ProcessDeferredTextures()
Create textures for deferred map bitmaps on demand.
absl::Status Update() final
std::unique_ptr< gui::TileSelectorWidget > blockset_selector_
void DrawEntityEditorPopups()
Draw entity editor popups and update entity data.
absl::Status Paste() override
void HandleEntityEditingShortcuts()
void ScrollBlocksetCanvasToCurrentTile()
Scroll the blockset canvas to show the current selected tile16.
static constexpr auto kPaintBatchTimeout
std::unique_ptr< TilePaintingManager > tile_painting_
gfx::BitmapTable current_graphics_set_
bool show_custom_bg_color_editor_
zelda3::Overworld overworld_
absl::Status LoadGraphics()
Load the Bitmap objects for each OverworldMap.
absl::Status LoadSpriteGraphics()
gfx::IRenderer * renderer_
absl::Status Save() override
std::unique_ptr< DebugWindowCard > debug_window_card_
zelda3::GameEntity * current_entity_
void HandleUndoRedoShortcuts()
void HandleKeyboardShortcuts()
Handle keyboard shortcuts for the Overworld Editor Shortcuts: 1-2 (modes), 3-8 (entities),...
gfx::SnesPalette palette_
gfx::Bitmap tile16_blockset_bmp_
void InitTilePaintingManager()
Initialize the tile painting manager (called after graphics load)
bool TogglePanel(size_t session_id, const std::string &base_card_id)
absl::Status Initialize(const gfx::Bitmap &tile16_blockset_bmp, const gfx::Bitmap ¤t_gfx_bmp, std::array< uint8_t, 0x200 > &all_tiles_types)
bool has_pending_changes() const
Check if any tiles have uncommitted changes.
void set_palette(const gfx::SnesPalette &palette)
void set_on_changes_committed(std::function< absl::Status()> callback)
void Show(const std::string &message, ToastType type=ToastType::kInfo, float ttl_seconds=3.0f)
void Push(std::unique_ptr< UndoAction > action)
absl::Status Redo()
Redo the top action. Returns error if stack is empty.
absl::Status Undo()
Undo the top action. Returns error if stack is empty.
void QueueTextureCommand(TextureCommandType type, Bitmap *bitmap)
int RegisterPaletteListener(PaletteChangeCallback callback)
Register a callback for palette change notifications.
void ProcessTextureQueue(IRenderer *renderer)
void UnregisterPaletteListener(int listener_id)
Unregister a palette change listener.
void Create(int width, int height, int depth, std::span< uint8_t > data)
Create a bitmap with the given dimensions and data.
void SetPalette(const SnesPalette &palette)
Set the palette for the bitmap using SNES palette format.
SDL_Surface * surface() const
RAII timer for automatic timing management.
auto selected_tile_pos() const
auto global_scale() const
auto select_rect_active() const
void SetUsageMode(CanvasUsage usage)
auto drawn_tile_position() const
const ImVector< ImVec2 > & points() const
auto selected_points() const
Base class for all overworld and dungeon entities.
enum yaze::zelda3::GameEntity::EntityType entity_type_
Represents an overworld exit that transitions from dungeon to overworld.
auto tile16_blockset_data() const
auto current_area_palette() const
void set_current_world(int world)
absl::Status Load(Rom *rom)
Load all overworld data from ROM.
absl::Status SaveMapProperties()
Save per-area graphics, palettes, and messages.
std::vector< std::pair< uint32_t, uint32_t > > GetProjectedWriteRanges() const
Get the projected write ranges (PC offsets) for overworld map saves.
absl::Status SaveMap32Tiles()
Save tile32 definitions to ROM.
absl::Status SaveMap16Tiles()
Save tile16 definitions to ROM.
auto current_graphics() const
absl::Status CreateTile32Tilemap()
Build tile32 tilemap from current tile16 data.
void set_current_map(int i)
absl::Status SaveEntrances()
Save entrance warp points to ROM.
absl::Status SaveExits()
Save exit return points to ROM.
absl::Status EnsureMapBuilt(int map_index)
Build a map on-demand if it hasn't been built yet.
absl::Status SaveItems()
Save hidden overworld items to ROM.
uint16_t GetTile(int x, int y) const
absl::Status SaveOverworldMaps()
Save compressed map tile data to ROM.
auto mutable_all_tiles_types()
auto mutable_sprites(int state)
auto current_map_bitmap_data() const
absl::Status SaveMusic()
Save per-area music IDs.
A class for managing sprites in the overworld and underworld.
#define ICON_MD_FORMAT_COLOR_FILL
#define LOG_DEBUG(category, format,...)
#define LOG_ERROR(category, format,...)
#define LOG_WARN(category, format,...)
#define ASSIGN_OR_RETURN(type_variable_name, expression)
std::string AddressOwnershipToString(AddressOwnership ownership)
const AgentUITheme & GetTheme()
Editors are the view controllers for the application.
constexpr unsigned int kOverworldMapSize
bool DrawSpriteEditorPopup(zelda3::Sprite &sprite)
bool DrawOverworldEntrancePopup(zelda3::OverworldEntrance &entrance)
bool DrawItemEditorPopup(zelda3::OverworldItem &item)
constexpr int kTile16Size
bool DrawExitEditorPopup(zelda3::OverworldExit &exit)
Tilemap CreateTilemap(IRenderer *renderer, std::vector< uint8_t > &data, int width, int height, int tile_size, int num_tiles, SnesPalette &palette)
constexpr const char * kOverworld
void CenterText(const char *text)
std::string MakePopupId(size_t session_id, const std::string &editor_name, const std::string &popup_name)
Generate session-aware popup IDs to prevent conflicts in multi-editor layouts.
std::string GetResourcePath(const std::string &resource_path)
constexpr int OverworldCustomTileGFXGroupEnabled
constexpr int OverworldCustomAreaSpecificBGEnabled
constexpr int kOverworldScreenSize
constexpr int kNumTile16Individual
constexpr int kSpecialWorldMapIdStart
constexpr int OverworldCustomAnimatedGFXEnabled
constexpr int OverworldCustomMainPaletteEnabled
constexpr int kNumOverworldMaps
constexpr int OverworldCustomASMHasBeenApplied
constexpr int kDarkWorldMapIdStart
absl::StatusOr< OverworldEntranceTileTypes > LoadEntranceTileTypes(Rom *rom)
constexpr int OverworldCustomMosaicEnabled
constexpr int OverworldCustomSubscreenOverlayEnabled
#define RETURN_IF_ERROR(expr)
struct yaze::core::FeatureFlags::Flags::Overworld overworld
Callbacks for operations that remain in the OverworldEditor.
std::function< void()> refresh_overworld_map
std::function< absl::Status()> refresh_tile16_blockset
std::function< bool()> is_entity_hovered
Returns true if an entity is currently hovered (for pan suppression).
std::function< bool()> pick_tile16_from_hovered_canvas
std::function< void(int)> ensure_map_texture
Shared state pointers that the navigation manager reads/writes.
bool * show_map_properties_panel
std::unique_ptr< gui::TileSelectorWidget > * blockset_selector
std::array< gfx::Bitmap, zelda3::kNumOverworldMaps > * maps_bmp
gui::Canvas * ow_map_canvas
zelda3::Overworld * overworld
bool * is_dragging_entity
gfx::Tilemap * tile16_blockset
EditingMode * current_mode
project::YazeProject * project
ToastManager * toast_manager
SharedClipboard * shared_clipboard
gfx::IRenderer * renderer
PanelManager * panel_manager
Context struct holding all data dependencies for map refresh operations. All pointers/references must...
gfx::Tilemap * tile16_blockset
gfx::SnesPalette * palette
zelda3::Overworld * overworld
std::function< void(int map_index)> ensure_map_texture
Callback to ensure a map texture is created (stays in OverworldEditor)
gfx::IRenderer * renderer
Tile16Editor * tile16_editor
std::array< gfx::Bitmap, zelda3::kNumOverworldMaps > * maps_bmp
gfx::Bitmap * current_gfx_bmp
bool * map_blockset_loaded
gfx::BitmapTable * current_graphics_set
static constexpr const char * kTile16Editor
std::vector< int > overworld_tile16_ids
bool has_overworld_tile16
Callbacks for undo integration and map refresh.
std::function< void(int map_index)> refresh_overworld_map_on_demand
std::function< void()> scroll_blockset_to_current_tile
std::function< void()> finalize_paint_operation
std::function< void()> refresh_overworld_map
std::function< void(int map_id, int world, int x, int y, int old_tile_id)> create_undo_point
Shared state for the tile painting system.
Tile16Editor * tile16_editor
gui::Canvas * ow_map_canvas
zelda3::Overworld * overworld
std::vector< int > * selected_tile16_ids
std::array< gfx::Bitmap, zelda3::kNumOverworldMaps > * maps_bmp
gfx::Tilemap * tile16_blockset
EditingMode * current_mode
Bitmap atlas
Master bitmap containing all tiles.
core::HackManifest hack_manifest