yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
overworld_editor.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EDITOR_OVERWORLDEDITOR_H
2#define YAZE_APP_EDITOR_OVERWORLDEDITOR_H
3
4#include <chrono>
5#include <memory>
6#include <optional>
7
8#include "absl/status/status.h"
9#include "app/editor/editor.h"
31#include "app/gfx/core/bitmap.h"
35#include "app/gui/core/input.h"
37#include "imgui/imgui.h"
38#include "rom/rom.h"
41
42// =============================================================================
43// Overworld Editor - UI Layer
44// =============================================================================
45//
46// ARCHITECTURE OVERVIEW:
47// ----------------------
48// The OverworldEditor is the main UI class for editing overworld maps.
49// It orchestrates several subsystems:
50//
51// 1. TILE EDITING SYSTEM
52// - Tile16Editor: Popup for editing individual 16x16 tiles
53// - Tile selection and painting on the main canvas
54// - Undo/Redo stack for paint operations
55//
56// 2. ENTITY SYSTEM
57// - OverworldEntityRenderer: Draws entities on the canvas
58// - entity_operations.cc: Insertion/deletion logic
59// - overworld_entity_interaction.cc: Drag/drop and click handling
60//
61// 3. MAP PROPERTIES SYSTEM
62// - MapPropertiesSystem: Toolbar and context menus
63// - OverworldSidebar: Property editing tabs
64// - Graphics, palettes, music per area
65//
66// 4. CANVAS SYSTEM
67// - ow_map_canvas_: Main overworld display (4096x4096)
68// - blockset_canvas_: Tile16 selector
69// - scratch_canvas_: Layout workspace
70//
71// EDITING MODES:
72// --------------
73// - DRAW_TILE: Left-click paints tiles, right-click opens tile16 editor
74// - MOUSE: Left-click selects entities, right-click opens context menus
75//
76// KEY WORKFLOWS:
77// --------------
78// See README.md in this directory for complete workflow documentation.
79//
80// SUBSYSTEM ORGANIZATION:
81// -----------------------
82// The class is organized into logical sections marked with comment blocks.
83// Each section groups related methods and state for a specific subsystem.
84// =============================================================================
85
86namespace yaze {
87namespace editor {
88
89struct OverworldItemsSnapshot;
90
91// =============================================================================
92// Constants
93// =============================================================================
94
95constexpr unsigned int k4BPP = 4;
96constexpr unsigned int kByteSize = 3;
97constexpr unsigned int kMessageIdSize = 5;
98constexpr unsigned int kNumSheetsToLoad = 223;
101constexpr ImVec2 kCurrentGfxCanvasSize(0x100 + 1, 0x10 * 0x40 + 1);
102constexpr ImVec2 kBlocksetCanvasSize(0x100 + 1, 0x4000 + 1);
103constexpr ImVec2 kGraphicsBinCanvasSize(0x100 + 1, kNumSheetsToLoad * 0x40 + 1);
104
105constexpr ImGuiTableFlags kOWMapFlags =
106 ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable |
107 ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingStretchProp;
108
109constexpr absl::string_view kWorldList =
110 "Light World\0Dark World\0Extra World\0";
111
112constexpr absl::string_view kGamePartComboString = "Part 0\0Part 1\0Part 2\0";
113
114constexpr absl::string_view kOWMapTable = "#MapSettingsTable";
115
134class OverworldEditor : public Editor, public gfx::GfxContext {
136
137 public:
138 // ===========================================================================
139 // Construction and Initialization
140 // ===========================================================================
141
146 // MapPropertiesSystem will be initialized after maps_bmp_ and canvas are
147 // ready
148 }
149
152 dependencies_ = deps;
153 }
154 ~OverworldEditor() override;
166
171
178
179 // ===========================================================================
180 // Editor Interface Implementation
181 // ===========================================================================
182
183 void Initialize() override;
184 absl::Status Load() override;
185 absl::Status Update() final;
186 absl::Status Undo() override;
187 absl::Status Redo() override;
188 absl::Status Cut() override { return absl::UnimplementedError("Cut"); }
189 absl::Status Copy() override;
190 absl::Status Paste() override;
191 absl::Status Find() override { return absl::UnimplementedError("Find"); }
192 absl::Status Save() override;
193 absl::Status BeginSaveTransaction() override;
194 void RollbackSaveTransaction() override;
195 void CommitSaveTransaction() override;
196 absl::Status Clear() override;
197 void ContributeStatus(StatusBar* status_bar) override;
199
202 // One 512x512 overworld screen for tools that draw areas outside this
203 // editor (the Cutscene Camera). Builds its texture on first use; nullptr
204 // for an invalid ID or a screen that is not built yet.
205 const gfx::Bitmap* AreaScreenBitmap(int map_id);
206
207 int jump_to_tab() { return jump_to_tab_; }
208 int jump_to_tab_ = -1;
209
210 // ===========================================================================
211 // ROM State
212 // ===========================================================================
213
214 bool IsRomLoaded() const override { return rom_ && rom_->is_loaded(); }
215 std::string GetRomStatus() const override {
216 if (!rom_)
217 return "No ROM loaded";
218 if (!rom_->is_loaded())
219 return "ROM failed to load";
220 return absl::StrFormat("ROM loaded: %s", rom_->title());
221 }
222
223 Rom* rom() const { return rom_; }
224 bool is_lyra_preview() const { return overworld_.is_lyra_preview(); }
225 // A Lyra preview retains pointers and caches derived from one ROM image.
226 // Session replacement must be checked before the manager mutates the ROM.
227 absl::Status CheckRomReplacement(const Rom& replacement) const;
229
232 static bool NormalizeMapSelection(int& current_world, int& current_map);
233
235 void set_current_map(int map_id) {
236 if (map_id >= 0 && map_id < overworld_.inspected_map_count()) {
237 // Finalize any pending paint operation before switching maps
239 current_map_ = map_id;
241 map_id / 0x40; // Calculate which world the map belongs to
242 if (const auto* map = overworld_.overworld_map(current_map_)) {
243 current_parent_ = map->parent();
244 } else {
246 }
249 }
250 }
251 void SetCurrentMap(int map_id) { set_current_map(map_id); }
252 void SelectMapForEditing(int map_id, bool respect_pin = true);
253
254 void set_current_tile16(int tile_id) { current_tile16_ = tile_id; }
255 int current_tile16_id() const { return current_tile16_; }
256 // Opens a Tile16's editable quadrants, focused on the requested quadrant.
257 // The selected map at invocation supplies the sheet and palette context.
258 absl::Status OpenGraphicsForTile16Quadrant(int tile16_id, int quadrant);
259 // Uses the map/tile captured by the context menu, not the hovered or pinned
260 // map. The clicked quadrant is focused first.
261 absl::Status OpenGraphicsForContextTile16(
262 const OverworldContextTarget& target);
264 return tile_painting_.get();
265 }
266 const gfx::Bitmap& map_bitmap(int map_id) const {
267 return maps_bmp_.at(map_id);
268 }
269 bool map_pinned() const { return current_map_lock_; }
270 int current_map_id() const { return current_map_; }
271 int current_world_id() const { return current_world_; }
272 int hovered_map_id() const { return hovered_map_; }
273
274 // ===========================================================================
275 // Graphics Loading
276 // ===========================================================================
277
285 absl::Status LoadGraphics();
286 absl::Status SyncProjectGraphicsPreview(bool force = false);
287
288 // ===========================================================================
289 // Entity Interaction API
290 // ===========================================================================
291
295
299
301 void RequestJumpToRoom(int room_id) { jump_to_tab_ = room_id; }
302
304 void RequestJumpToEntrance(int entrance_id) { jump_to_tab_ = entrance_id; }
305
310
315
316 std::optional<OverworldEntityInsertionRequest> TakePendingEntityInsertion() {
317 auto request = std::move(pending_entity_insertion_);
319 return request;
320 }
321 std::string& insert_error() { return insert_error_; }
322
324 int game_state() const { return game_state_; }
325 // Preview only; does not rewrite story progression or entity placements.
326 void SetPreviewStoryState(int state);
327
328 // ===========================================================================
329 // Entity System - Insertion and Editing
330 // ===========================================================================
331 // Entity operations are delegated to entity_operations.cc helper functions.
332 // Entity rendering is handled by OverworldEntityRenderer.
333 // Entity interaction (drag/drop) is in overworld_entity_interaction.cc.
334
337 void HandleEntityInsertion(const std::string& entity_type,
338 const OverworldContextTarget& target);
342 const std::optional<OverworldContextTarget>& target);
343 void DrawItemInsertPopup();
344 bool TryPlaceArmedItem();
345
348 void HandleTile16Edit(const OverworldContextTarget& target);
350
352 bool SelectItemByIdentity(const zelda3::OverworldItem& item_identity);
353
355 void ClearSelectedItem();
356
358 std::optional<zelda3::OverworldItem> selected_item_identity() const {
360 }
361
365
367 bool DuplicateSelectedItem(int offset_x = 16, int offset_y = 0);
368
370 bool NudgeSelectedItem(int delta_x, int delta_y);
371
373 bool DeleteSelectedItem();
374 bool DeleteItemByIdentity(const zelda3::OverworldItem& item_identity);
375
376 // ===========================================================================
377 // Keyboard Shortcuts
378 // ===========================================================================
379
381 if (tile_painting_)
382 tile_painting_->ToggleBrushTool();
383 }
385 if (tile_painting_)
386 tile_painting_->ActivateFillTool();
387 }
388 void CycleTileSelection(int delta);
389 // Map/view toggles bound through ShortcutManager (F11, Cmd/Ctrl+L,
390 // Cmd/Ctrl+T, Cmd/Ctrl+Shift+I).
391 void ToggleMapLock();
396 void SetEditingMode(EditingMode mode);
398 void SelectAdjacentMap(int dx, int dy);
401 void JumpToMap(int map_id);
402 // Navigate to an inspected Tile16 without changing ROM or edit history.
403 void LocateOverworldTile(int map_id, int world_x, int world_y);
404 void SwitchToWorld(int world);
405 // View requests; applied when the canvas child begins (safe anywhere).
406 void ZoomIn();
407 void ZoomOut();
408 void ZoomToFit();
409 void ResetOverworldView();
410 void CenterOverworldView();
414 bool entities_visible() const { return show_entities_; }
415 void ToggleGrid();
416 bool grid_visible() const;
420
424 void RequestTile16Selection(int tile_id);
425
427 return tile_painting_ && tile_painting_->PickTile16FromHoveredCanvas();
428 }
429
430 // ===========================================================================
431 // WindowContent View Hooks
432 // ===========================================================================
433 // These are used by focused WindowContent wrappers around Overworld views.
434 // Drawing is delegated to OverworldCanvasRenderer.
435
436 absl::Status DrawAreaGraphics() {
437 if (is_lyra_preview()) {
438 ImGui::TextDisabled("Lyra preview: area graphics editing unavailable");
439 return absl::OkStatus();
440 }
442 if (!canvas_renderer_)
443 return absl::FailedPreconditionError("Renderer not initialized");
444 return canvas_renderer_->DrawAreaGraphics();
445 }
446 absl::Status DrawTile16Selector() {
447 if (is_lyra_preview()) {
448 ImGui::TextDisabled("Lyra preview: Tile16 editing unavailable");
449 return absl::OkStatus();
450 }
451 if (!canvas_renderer_)
452 return absl::FailedPreconditionError("Renderer not initialized");
453 return canvas_renderer_->DrawTile16Selector();
454 }
456 if (is_lyra_preview()) {
457 ImGui::TextDisabled("Lyra preview: map properties editing unavailable");
458 return;
459 }
462 canvas_renderer_->DrawMapProperties();
463 }
464
468 void InvalidateGraphicsCache(int map_id = -1) {
469 if (map_refresh_)
470 map_refresh_->InvalidateGraphicsCache(map_id);
471 }
472 absl::Status DrawScratchSpace();
474 if (is_lyra_preview()) {
475 ImGui::TextDisabled("Lyra preview: Tile8 editing unavailable");
476 return;
477 }
479 canvas_renderer_->DrawTile8Selector();
480 }
481 absl::Status UpdateGfxGroupEditor();
483 if (is_lyra_preview()) {
484 ImGui::TextDisabled("Lyra preview: overworld settings unavailable");
485 return;
486 }
489 canvas_renderer_->DrawV3Settings();
490 }
491
494
497
500 const Tile16Editor& tile16_editor() const { return tile16_editor_; }
501
505 return current_gfx_bmp_;
506 }
507
510
512 void DrawOverworldCanvas();
513
514 private:
516
517 // Identifies the exact descriptor image bound to this model. The session
518 // reload path may restore those bytes after a refused ROM replacement.
521 // ===========================================================================
522 // Entity Interaction System
523 // ===========================================================================
524 // Handles mouse interactions with entities in MOUSE mode.
525
527
530
531 // ===========================================================================
532 // Map Refresh System (delegated to MapRefreshCoordinator)
533 // ===========================================================================
534
539
540 // Convenience delegation methods for internal use
541 void RefreshChildMap(int map_index) {
542 if (map_refresh_)
543 map_refresh_->RefreshChildMap(map_index);
544 }
546 if (map_refresh_)
547 map_refresh_->RefreshOverworldMap();
548 }
549 void RefreshOverworldMapOnDemand(int map_index) {
550 if (map_refresh_)
551 map_refresh_->RefreshOverworldMapOnDemand(map_index);
552 }
553 void RefreshChildMapOnDemand(int map_index) {
554 if (map_refresh_)
555 map_refresh_->RefreshChildMapOnDemand(map_index);
556 }
557 absl::Status RefreshMapPalette(int map_id = -1) {
558 if (map_refresh_)
559 return map_refresh_->RefreshMapPalette(map_id);
560 return absl::FailedPreconditionError(
561 "MapRefreshCoordinator not initialized");
562 }
563 void RefreshMapProperties(int map_id = -1) {
564 if (map_refresh_)
565 map_refresh_->RefreshMapProperties(map_id);
566 }
567 absl::Status RefreshTile16Blockset() {
568 if (map_refresh_)
569 return map_refresh_->RefreshTile16Blockset();
570 return absl::FailedPreconditionError(
571 "MapRefreshCoordinator not initialized");
572 }
574 if (map_refresh_)
575 map_refresh_->UpdateBlocksetWithPendingTileChanges();
576 }
577 void ForceRefreshGraphics(int map_index) {
578 if (map_refresh_)
579 map_refresh_->ForceRefreshGraphics(map_index);
580 }
581 void RefreshSiblingMapGraphics(int map_index, bool include_self = false) {
582 if (map_refresh_)
583 map_refresh_->RefreshSiblingMapGraphics(map_index, include_self);
584 }
585
586 // ===========================================================================
587 // Tile Editing System
588 // ===========================================================================
589 // Handles tile painting and selection on the main canvas.
590
593
596
598 absl::Status CheckForCurrentMap();
599
602
605
608
609 // Canvas navigation (delegated to CanvasNavigationManager)
614
615 // ===========================================================================
616 // Texture and Graphics Loading
617 // ===========================================================================
618
619 absl::Status LoadSpriteGraphics();
620
623
627
629 void EnsureMapTexture(int map_index);
630 void PrimeWorldMaps(int world, bool process_texture_queue = false);
631 // ===========================================================================
632 // Canvas Navigation (delegated to CanvasNavigationManager)
633 // ===========================================================================
634
635 // ===========================================================================
636 // Canvas Automation API
637 // ===========================================================================
638 // Integration with automation testing system.
639
642 bool AutomationSetTile(int x, int y, int tile_id);
643 int AutomationGetTile(int x, int y);
644
645 // ===========================================================================
646 // Scratch Space System
647 // ===========================================================================
648 // Workspace for planning tile layouts before placing them on the map.
649
650 absl::Status SaveCurrentSelectionToScratch();
651 absl::Status LoadScratchToSelection();
652 absl::Status ClearScratchSpace();
656 void UpdateScratchBitmapTile(int tile_x, int tile_y, int tile_id);
657 absl::Status LoadScratchPad();
658 absl::Status SaveScratchPad() const;
659 absl::Status FlushScratchPadIfDirty();
662
663 // ===========================================================================
664 // Undo/Redo System
665 // ===========================================================================
666 // Tracks tile paint operations for undo/redo functionality.
667 // Operations within 500ms are batched to reduce undo point count.
668
670 int map_id = 0;
671 int world = 0; // 0=Light, 1=Dark, 2=Special
672 std::vector<std::pair<std::pair<int, int>, int>>
673 tile_changes; // ((x,y), old_tile_id)
674 std::chrono::steady_clock::time_point timestamp;
675 };
676
677 void CreateUndoPoint(int map_id, int world, int x, int y, int old_tile_id);
679 auto& GetWorldTiles(int world);
683 std::string description);
684 absl::Status ApplyOverworldPropertyEdit(const OverworldPropertyEdit& edit,
685 bool record_undo = true);
686 absl::Status ApplyOverworldPropertyEdits(
687 const std::vector<OverworldPropertyEdit>& edits,
688 const std::string& description, bool record_undo = true);
689 absl::Status RenameProjectResourceLabelWithUndo(const std::string& type,
690 int id,
691 const std::string& label);
692
693 // ===========================================================================
694 // Editing Mode State
695 // ===========================================================================
696
700
715
716 // ===========================================================================
717 // Current Selection State
718 // ===========================================================================
719
720 int current_world_ = 0; // 0=Light, 1=Dark, 2=Special
721 int current_map_ = 0; // Current map index (0-159)
722 int current_parent_ = 0; // Parent map for multi-area
723 int hovered_map_ = -1; // Physical screen under the cursor, or -1
725 int game_state_ = 1; // 0=Beginning, 1=Pendants, 2=Crystals
726 int current_tile16_ = 0; // Selected tile16 for painting
729
730 // Selected tile IDs for rectangle selection
731 std::vector<int> selected_tile16_ids_;
732
733 // ===========================================================================
734 // Loading State
735 // ===========================================================================
736
737 bool all_gfx_loaded_ = false;
739
743
744 // ===========================================================================
745 // Canvas Interaction State
746 // ===========================================================================
747
751 std::optional<OverworldItemsSnapshot> drag_item_snapshot_;
753 bool current_map_lock_ = false;
754
755 // ===========================================================================
756 // Property Windows (Standalone, Not PanelManager)
757 // ===========================================================================
758
761 // Area subscreen overlays (sky, fog, lava, canopy, rain) are shown by
762 // default, like the game; the toolbar toggle hides them.
764 bool show_entities_ = true;
765
766 // ===========================================================================
767 // UI Subsystem Components
768 // ===========================================================================
769
770 std::unique_ptr<OverworldCanvasRenderer> canvas_renderer_;
771 std::unique_ptr<CanvasNavigationManager> canvas_nav_;
772 std::unique_ptr<TilePaintingManager> tile_painting_;
773 std::unique_ptr<zelda3::OverworldUpgradeSystem> upgrade_system_;
774 std::unique_ptr<EntityMutationService> entity_mutation_service_;
775 std::unique_ptr<OverworldInteractionCoordinator> interaction_coordinator_;
776 std::unique_ptr<MapRefreshCoordinator> map_refresh_;
777 std::unique_ptr<OverworldMapTextureCoordinator> map_texture_;
778 std::unique_ptr<MapPropertiesSystem> map_properties_system_;
779 std::unique_ptr<OverworldSidebar> sidebar_;
780 std::unique_ptr<OverworldEntityRenderer> entity_renderer_;
781 std::unique_ptr<OverworldToolbar> toolbar_;
782
783 // ===========================================================================
784 // Scratch Space System (Unified Single Workspace)
785 // ===========================================================================
786
789 std::array<std::array<int, 32>, 32> tile_data{};
790 bool in_use = false;
791 std::string name = "Scratch Space";
792 int width = 16;
793 int height = 16;
794 std::vector<ImVec2> selected_tiles;
795 std::vector<ImVec2> selected_points;
796 bool select_rect_active = false;
797 };
800
801 // ===========================================================================
802 // Core Data References
803 // ===========================================================================
804
806
810
811 // Sub-editors
815
816 // ===========================================================================
817 // Graphics Data
818 // ===========================================================================
819
825 std::array<gfx::Bitmap, zelda3::kExpandedMapCount> maps_bmp_;
827 std::vector<gfx::Bitmap> sprite_previews_;
828
829 // ===========================================================================
830 // Overworld Data Layer
831 // ===========================================================================
832
836
837 // ===========================================================================
838 // Entity State
839 // ===========================================================================
840
842
845 std::optional<zelda3::OverworldItem> selected_item_identity_;
846 std::optional<OverworldEntityEditingTarget> editing_target_;
847
848 // Edit buffers for popups (session-specific)
853
854 // Deferred entity insertion (needed for popup flow from context menu)
855 std::optional<OverworldEntityInsertionRequest> pending_entity_insertion_;
856 std::optional<OverworldContextTarget> item_insert_target_;
859 uint8_t armed_item_id_ = 0;
860 std::string insert_error_;
861
862 // ===========================================================================
863 // Canvas Components
864 // ===========================================================================
865
872 std::unique_ptr<gui::TileSelectorWidget> blockset_selector_;
876 gui::Canvas scratch_canvas_{"ScratchSpace", ImVec2(320, 480),
878
879 // ===========================================================================
880 // Panel Cards
881 // ===========================================================================
882
883 std::unique_ptr<UsageStatisticsCard> usage_stats_card_;
884 std::unique_ptr<DebugWindowCard> debug_window_card_;
885
886 absl::Status status_;
887
888 // ===========================================================================
889 // Undo/Redo State
890 // ===========================================================================
891
892 std::optional<OverworldUndoPoint> current_paint_operation_;
893
894 // ===========================================================================
895 // Event Listeners
896 // ===========================================================================
897
899};
900} // namespace editor
901} // namespace yaze
902
903#endif
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:49
bool is_loaded() const
Definition rom.h:187
auto title() const
Definition rom.h:199
Interface for editor classes.
Definition editor.h:249
UndoManager undo_manager_
Definition editor.h:371
virtual void SetDependencies(const EditorDependencies &deps)
Definition editor.h:254
zelda3::GameData * game_data() const
Definition editor.h:357
EditorDependencies dependencies_
Definition editor.h:370
EditorType type() const
Definition editor.h:343
EditorType type_
Definition editor.h:369
Editor-level service responsible for overworld entity mutations.
Manage graphics group configurations in a Rom.
std::function< absl::StatusOr< zelda3::RoomsetUsageReport >(int)> RoomsetUsageCallback
std::function< absl::StatusOr< zelda3::MainGroupUsageReport >(int, int)> MainUsageCallback
void SetRoomsetUsageCallback(RoomsetUsageCallback callback)
void SetMainUsageCallback(MainUsageCallback callback)
void SetWorkspaceState(GfxGroupWorkspaceState *state)
void SetUndoManager(UndoManager *undo)
void SetGameData(zelda3::GameData *data)
Handles all canvas drawing and panel rendering for the overworld editor.
Main UI class for editing overworld maps in A Link to the Past.
void LocateOverworldTile(int map_id, int world_x, int world_y)
std::unique_ptr< UsageStatisticsCard > usage_stats_card_
absl::Status Clear() override
std::unique_ptr< MapPropertiesSystem > map_properties_system_
std::unique_ptr< OverworldCanvasRenderer > canvas_renderer_
OverworldEntityWorkbench * GetWorkbench()
Resolve the entity workbench window content (may be null).
zelda3::OverworldEntranceTileTypes entrance_tiletypes_
void OpenEntityContextMenu(zelda3::GameEntity *entity)
std::array< gfx::Bitmap, zelda3::kExpandedMapCount > maps_bmp_
zelda3::OverworldExit & edit_exit()
EditorContextSnapshot BuildContextSnapshot() const override
std::optional< OverworldUndoPoint > current_paint_operation_
absl::Status BeginSaveTransaction() override
void PushItemUndoAction(OverworldItemsSnapshot before, std::string description)
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 Cut() override
void ForceRefreshGraphics(int map_index)
zelda3::GameEntity * ResolveEditingEntity()
void RestoreItemUndoSnapshot(const OverworldItemsSnapshot &snapshot)
std::vector< int > selected_tile16_ids_
absl::Status ApplyOverworldPropertyEdit(const OverworldPropertyEdit &edit, bool record_undo=true)
zelda3::OverworldEntrance edit_entrance_
const gfx::Tilemap & tile16_blockset() const
Read-only access for integration tests that verify refresh output.
void InitCanvasNavigationManager()
Initialize the canvas navigation manager (called during Initialize)
void InitMapRefreshCoordinator()
Initialize the map refresh coordinator (called during Initialize)
void RequestItemInsertPopup(const std::optional< OverworldContextTarget > &target)
std::optional< zelda3::OverworldItem > selected_item_identity_
absl::Status RefreshMapPalette(int map_id=-1)
zelda3::OverworldBlockset refresh_blockset_
zelda3::OverworldItem & edit_item()
std::unique_ptr< zelda3::OverworldUpgradeSystem > upgrade_system_
void RequestJumpToEntrance(int entrance_id)
Trigger a jump to a dungeon entrance.
absl::Status SyncProjectGraphicsPreview(bool force=false)
void SetDependencies(const EditorDependencies &deps) override
bool DeleteItemByIdentity(const zelda3::OverworldItem &item_identity)
void HandleEntityInsertion(const std::string &entity_type, const OverworldContextTarget &target)
Handle entity insertion from context menu.
void NotifyEntityModified(zelda3::GameEntity *entity)
Notify that an entity has been modified, marking ROM as dirty.
absl::Status CheckRomReplacement(const Rom &replacement) const
zelda3::GameEntity * dragged_entity_
std::unique_ptr< MapRefreshCoordinator > map_refresh_
void SelectAdjacentMap(int dx, int dy)
Alt+Arrow: select the neighbouring screen in the world grid and center it.
std::unique_ptr< OverworldMapTextureCoordinator > map_texture_
static bool NormalizeMapSelection(int &current_world, int &current_map)
Clamp a possibly stale world/map selection back into a valid overworld range.
void CheckForOverworldEdits()
Check for tile edits - delegates to TilePaintingManager.
void UpdateScratchBitmapTile(int tile_x, int tile_y, int tile_id)
UsageStatisticsCard * usage_stats_card()
Access usage statistics card for panel.
const gfx::Bitmap & map_bitmap(int map_id) const
void ContributeStatus(StatusBar *status_bar) override
EntityMutationService * entity_mutation_service()
Access the entity mutation service.
void SetGameData(zelda3::GameData *game_data) override
void RefreshSiblingMapGraphics(int map_index, bool include_self=false)
void PrimeWorldMaps(int world, bool process_texture_queue=false)
std::optional< zelda3::OverworldItem > selected_item_identity() const
Get current selected item identity snapshot.
bool SampleContextTile16(const OverworldContextTarget &target)
std::optional< OverworldContextTarget > item_insert_target_
absl::Status ApplyOverworldPropertyEdits(const std::vector< OverworldPropertyEdit > &edits, const std::string &description, bool record_undo=true)
void set_current_map(int map_id)
Set the current map for editing (also updates world)
void RefreshOverworldMapOnDemand(int map_index)
void RefreshMapsForSheetEdits()
Mark maps for a graphics rebuild when a sheet they use changed in the session's sheet store (an unsav...
std::unique_ptr< OverworldSidebar > sidebar_
void InvalidateGraphicsCache(int map_id=-1)
Invalidate cached graphics for a specific map or all maps.
DebugWindowCard * debug_window_card()
Access debug window card for panel.
std::optional< int > pending_tile16_selection_after_gfx_
void HandleTile16Edit(const OverworldContextTarget &target)
Handle tile16 editing from context menu (MOUSE mode) Opens the Tile16 captured at menu-open through t...
void SetEditingMode(EditingMode mode)
Tool change from the toolbar or keys 1/2: also leaves entity modes.
absl::Status RenameProjectResourceLabelWithUndo(const std::string &type, int id, const std::string &label)
absl::Status SaveCurrentSelectionToScratch()
zelda3::OverworldItem * GetSelectedItem()
Resolve selected item identity to the current live item pointer.
bool NormalizeCurrentSelectionState()
Handle overworld keyboard shortcuts and edit-mode hotkeys.
bool DuplicateSelectedItem(int offset_x=16, int offset_y=0)
Duplicate selected item with optional pixel offset.
bool AutomationSetTile(int x, int y, int tile_id)
Definition automation.cc:25
void DrawOverworldCanvas()
Draw the main overworld canvas.
void OpenEntityEditor(zelda3::GameEntity *entity)
zelda3::Overworld & overworld()
Access the underlying Overworld data.
void SetCurrentEntity(zelda3::GameEntity *entity)
Set the currently active entity for editing.
zelda3::OverworldItem edit_item_
std::optional< OverworldEntityInsertionRequest > TakePendingEntityInsertion()
std::optional< OverworldItemsSnapshot > drag_item_snapshot_
Item state before an in-progress canvas drag (drag undo).
void RefreshChildMap(int map_index)
std::unique_ptr< OverworldEntityRenderer > entity_renderer_
std::optional< OverworldEntityInsertionRequest > pending_entity_insertion_
absl::Status Load() override
absl::Status RebuildScratchBitmapFromTileData()
void EnsureMapTexture(int map_index)
Ensure a specific map has its texture created.
const gfx::Bitmap & current_gfx_bmp_for_testing() const
std::vector< gfx::Bitmap > sprite_previews_
absl::Status OpenGraphicsForTile16Quadrant(int tile16_id, int quadrant)
std::unique_ptr< CanvasNavigationManager > canvas_nav_
OverworldEditor(Rom *rom, const EditorDependencies &deps)
std::string GetRomStatus() const override
bool NudgeSelectedItem(int delta_x, int delta_y)
Move selected item by signed pixel deltas.
const gfx::Bitmap * AreaScreenBitmap(int map_id)
std::unique_ptr< OverworldToolbar > toolbar_
bool IsRomLoaded() const override
Tile16Editor & tile16_editor()
Access the Tile16 Editor for panel integration.
void ProcessDeferredTextures()
Create textures for deferred map bitmaps on demand.
absl::Status OpenGraphicsForContextTile16(const OverworldContextTarget &target)
const Tile16Editor & tile16_editor() const
zelda3::OverworldEntrance & edit_entrance()
std::unique_ptr< gui::TileSelectorWidget > blockset_selector_
std::optional< OverworldEntityEditingTarget > editing_target_
zelda3::GameEntity * current_entity() const
void RefreshMapProperties(int map_id=-1)
absl::Status Paste() override
void ScrollBlocksetCanvasToCurrentTile()
Scroll the blockset canvas to show the current selected tile16.
bool DeleteSelectedItem()
Delete selected item and preserve nearest-item selection continuity.
std::unique_ptr< TilePaintingManager > tile_painting_
absl::Status LoadGraphics()
Load the Bitmap objects for each OverworldMap.
void RefreshChildMapOnDemand(int map_index)
absl::Status Find() override
void SetRoomsetGraphicsUsageCallback(GfxGroupEditor::RoomsetUsageCallback callback)
OverworldItemsSnapshot CaptureItemUndoSnapshot() const
void RequestJumpToRoom(int room_id)
Trigger a jump to a dungeon room.
absl::Status SaveScratchPad() const
std::unique_ptr< DebugWindowCard > debug_window_card_
void SelectMapForEditing(int map_id, bool respect_pin=true)
std::unique_ptr< OverworldInteractionCoordinator > interaction_coordinator_
zelda3::GameEntity * current_entity_
void SetEntityEditMode(EntityEditMode mode)
Entity focus (entrances/exits/items/sprites); NONE = all entities.
zelda3::OverworldExit edit_exit_
void PrepareForSessionTeardown() override
int AutomationGetTile(int x, int y)
Definition automation.cc:54
std::unique_ptr< EntityMutationService > entity_mutation_service_
void ClearSelectedItem()
Clear active item selection.
void InitTilePaintingManager()
Initialize the tile painting manager (called after graphics load)
bool SelectItemByIdentity(const zelda3::OverworldItem &item_identity)
Select an overworld item using value identity matching.
void SetMainGraphicsUsageCallback(GfxGroupEditor::MainUsageCallback callback)
const TilePaintingManager * tile_painting() const
Authoritative component for entity editing state and UI.
Allows the user to view and edit in game palettes.
A session-aware status bar displayed at the bottom of the application.
Definition status_bar.h:57
ImGui façade for Tile16 editing; domain state lives in Tile16EditSession.
void SetGameData(zelda3::GameData *game_data)
Manages tile painting, fill, selection, and eyedropper operations.
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:70
uint8_t at(int i) const
Definition bitmap.h:412
Shared graphical context across editors.
Defines an abstract interface for all rendering operations.
Definition irenderer.h:60
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
Modern, robust canvas for drawing and manipulating graphics.
Definition canvas.h:64
Base class for all overworld and dungeon entities.
Definition common.h:31
Represents an overworld exit that transitions from dungeon to overworld.
void set_current_world(int world)
Definition overworld.h:810
void SetGameData(GameData *game_data)
Definition overworld.h:413
bool is_lyra_preview() const
Definition overworld.h:430
int inspected_map_count() const
Definition overworld.h:433
auto overworld_map(int i) const
Definition overworld.h:737
void set_current_map(int i)
Definition overworld.h:809
A class for managing sprites in the overworld and underworld.
Definition sprite.h:39
constexpr ImVec2 kOverworldCanvasSize(kOverworldMapSize *8, kOverworldMapSize *8)
constexpr absl::string_view kOWMapTable
constexpr ImGuiTableFlags kOWMapFlags
constexpr unsigned int kOverworldMapSize
constexpr absl::string_view kWorldList
constexpr absl::string_view kGamePartComboString
constexpr unsigned int kNumSheetsToLoad
constexpr ImVec2 kCurrentGfxCanvasSize(0x100+1, 0x10 *0x40+1)
constexpr ImVec2 kBlocksetCanvasSize(0x100+1, 0x4000+1)
constexpr ImVec2 kGraphicsBinCanvasSize(0x100+1, kNumSheetsToLoad *0x40+1)
constexpr unsigned int kByteSize
constexpr unsigned int k4BPP
constexpr unsigned int kMessageIdSize
std::unordered_map< int, std::unique_ptr< gfx::Bitmap > > BitmapTable
Definition bitmap.h:549
std::vector< std::vector< uint16_t > > OverworldBlockset
Represents tile32 data for the overworld.
Unified dependency container for all editor types.
Definition editor.h:170
GfxGroupWorkspaceState * gfx_group_workspace
Definition editor.h:179
std::vector< std::pair< std::pair< int, int >, int > > tile_changes
std::chrono::steady_clock::time_point timestamp
std::array< std::array< int, 32 >, 32 > tile_data
Snapshot of overworld item list + current item selection.
Tilemap structure for SNES tile-based graphics management.
Definition tilemap.h:118