yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
overworld.h
Go to the documentation of this file.
1#ifndef YAZE_APP_DATA_OVERWORLD_H
2#define YAZE_APP_DATA_OVERWORLD_H
3
4#include <array>
5#include <cstddef>
6#include <cstdint>
7#include <deque>
8#include <mutex>
9#include <unordered_map>
10#include <vector>
11
12#include "absl/status/status.h"
13#include "absl/status/statusor.h"
15#include "core/rom_settings.h"
16#include "imgui.h"
17#include "rom/rom.h"
18#include "zelda3/common.h"
19#include "zelda3/game_data.h"
27
28// =============================================================================
29// Overworld Data Layer
30// =============================================================================
31//
32// ARCHITECTURE OVERVIEW:
33// ----------------------
34// The Overworld class is the central data manager for A Link to the Past's
35// overworld system. It handles 160 map screens across three worlds:
36// - Light World: Maps 0x00-0x3F (64 maps)
37// - Dark World: Maps 0x40-0x7F (64 maps)
38// - Special World: Maps 0x80-0x9F (32 maps, expandable to 0xBF with patches)
39//
40// DATA ORGANIZATION:
41// ------------------
42// The overworld uses a hierarchical tile system:
43// - Tile32: 32x32 pixel blocks composed of four Tile16s
44// - Tile16: 16x16 pixel blocks composed of four Tile8s
45// - Tile8: 8x8 pixel base tiles from graphics sheets
46//
47// Map tile data is stored as arrays of Tile16 IDs in OverworldBlockset:
48// - map_tiles_.light_world: 64 maps of 32x32 tile16 IDs each
49// - map_tiles_.dark_world: 64 maps of 32x32 tile16 IDs each
50// - map_tiles_.special_world: 32+ maps of 32x32 tile16 IDs each
51//
52// SAVE SYSTEM DOCUMENTATION:
53// --------------------------
54// The save workflow is controlled by feature flags in OverworldEditor::Save().
55// Each component saves independently but some have ordering dependencies.
56//
57// SAVE ORDER AND DEPENDENCIES:
58//
59// 1. TILE DEFINITIONS (must be saved first, others depend on these IDs):
60// - CreateTile32Tilemap(): Build tile32 from current tile16 data
61// - SaveMap32Tiles(): Write tile32 definitions to ROM
62// - SaveMap16Tiles(): Write tile16 definitions to ROM
63// - SaveOverworldMaps(): Write compressed map tile data
64//
65// 2. ENTITIES (independent, can save in any order):
66// - SaveEntrances(): Entrance warps to underworld
67// - SaveExits(): Exit points returning from underworld
68// - SaveItems(): Hidden items on overworld
69//
70// 3. PROPERTIES (independent, can save in any order):
71// - SaveMapProperties(): Graphics, palettes, messages per area
72// - SaveMusic(): Music IDs per area and game state
73// - SaveAreaSizes(): Area size enum for v3+ ROMs
74//
75// 4. CUSTOM FEATURES (v2+/v3+ only):
76// - SaveCustomOverworldASM(): Custom feature enable flags
77// - SaveAreaSpecificBGColors(): Per-area background colors (v2+)
78// - SaveMapOverlays(): Interactive overlay data
79//
80// TESTING SAVE FUNCTIONALITY:
81// ---------------------------
82// To test individual save components:
83// 1. Enable only one feature flag at a time in core::FeatureFlags
84// 2. Make changes to that component in the editor
85// 3. Save ROM and verify changes in an emulator
86// 4. Check for corruption by loading saved ROM back into editor
87//
88// Round-trip testing:
89// 1. Load vanilla ROM
90// 2. Make changes to all components
91// 3. Save ROM
92// 4. Close and reopen ROM
93// 5. Verify all changes persisted correctly
94//
95// See app/editor/overworld/README.md for complete workflow documentation.
96// =============================================================================
97
98namespace yaze::zelda3 {
99
100inline constexpr int kEssentialMapsPerWorld = 1;
101
102constexpr int GravesYTilePos = 0x49968; // short (0x0F entries)
103constexpr int GravesXTilePos = 0x49986; // short (0x0F entries)
104constexpr int GravesTilemapPos = 0x499A4; // short (0x0F entries)
105constexpr int GravesGFX = 0x499C2; // short (0x0F entries)
106constexpr int GravesXPos = 0x4994A; // short (0x0F entries)
107constexpr int GravesYLine = 0x4993A; // short (0x08 entries)
108constexpr int GravesCountOnY = 0x499E0; // Byte 0x09 entries
109constexpr int GraveLinkSpecialHole = 0x46DD9; // short
110constexpr int GraveLinkSpecialStairs = 0x46DE0; // short
111
112constexpr int kOverworldMapPaletteIds = 0x7D1C;
113constexpr int kOverworldSpritePaletteIds = 0x7B41;
114constexpr int kOverworldSpritePaletteGroup = 0x75580;
115constexpr int kOverworldSpriteset = 0x7A41;
116constexpr int kOverworldSpecialGfxGroup = 0x16821;
117constexpr int kOverworldSpecialPalGroup = 0x16831;
118constexpr int kOverworldSpritesBeginning = 0x4C881;
119constexpr int kOverworldSpritesAgahnim = 0x4CA21;
120constexpr int kOverworldSpritesZelda = 0x4C901;
121
122constexpr int kAreaGfxIdPtr = 0x7C9C;
123constexpr int kOverworldMessageIds = 0x3F51D;
124
125constexpr int kOverworldMusicBeginning = 0x14303;
126constexpr int kOverworldMusicZelda = 0x14303 + 0x40;
127constexpr int kOverworldMusicMasterSword = 0x14303 + 0x80;
128constexpr int kOverworldMusicAgahnim = 0x14303 + 0xC0;
129constexpr int kOverworldMusicDarkWorld = 0x14403;
132
133// 0x00 = small maps, 0x20 = large maps
134constexpr int kOverworldMapSize = 0x12844;
135
136// 0x01 = small maps, 0x03 = large maps
137constexpr int kOverworldMapSizeHighByte = 0x12884;
138
139// relative to the WORLD + 0x200 per map
140// large map that are not == parent id = same position as their parent!
141// eg for X position small maps :
142// 0000, 0200, 0400, 0600, 0800, 0A00, 0C00, 0E00
143// all Large map would be :
144// 0000, 0000, 0400, 0400, 0800, 0800, 0C00, 0C00
145constexpr int kOverworldMapParentId = 0x125EC;
146constexpr int kOverworldTransitionPositionY = 0x128C4;
147constexpr int kOverworldTransitionPositionX = 0x12944;
148constexpr int kOverworldScreenSize = 0x1788D;
149constexpr int kOverworldScreenSizeForLoading = 0x4C635;
150
155
156constexpr int kOverworldMapDataOverflow = 0x130000;
157
158constexpr int kTransitionTargetNorth = 0x13EE2;
159constexpr int kTransitionTargetWest = 0x13F62;
160constexpr int overworldCustomMosaicASM = 0x1301D0;
161constexpr int overworldCustomMosaicArray = 0x1301F0;
162
163// Expanded tile16 and tile32
164constexpr int kMap16TilesExpanded = 0x1E8000;
165constexpr int kMap32TileTRExpanded = 0x020000;
166constexpr int kMap32TileBLExpanded = 0x1F0000;
167constexpr int kMap32TileBRExpanded = 0x1F8000;
168constexpr int kMap32TileCountExpanded = 0x0067E0;
169constexpr int kMap32ExpandedFlagPos = 0x01772E; // 0x04
170constexpr int kMap16ExpandedFlagPos = 0x02FD28; // 0x0F
171
172constexpr int overworldSpritesBeginingExpanded = 0x141438;
173constexpr int overworldSpritesZeldaExpanded = 0x141578;
174constexpr int overworldSpritesAgahnimExpanded = 0x1416B8;
175constexpr int overworldSpritesDataStartExpanded = 0x04C881;
176
179
180constexpr int ExpandedOverlaySpace = 0x120000;
181
182// Expanded pointer table markers for tail map support (maps 0xA0-0xBF)
183// Set by TailMapExpansion.asm patch after ZSCustomOverworld v3
184constexpr int kExpandedPtrTableMarker = 0x1423FF; // Location of marker byte
185constexpr uint8_t kExpandedPtrTableMagic = 0xEA; // Marker value when applied
186constexpr int kExpandedPtrTableHigh = 0x142400; // New high table location
187constexpr int kExpandedPtrTableLow = 0x142640; // New low table location
188constexpr int kExpandedMapCount = 192; // 0x00-0xBF
189
190constexpr int overworldTilesType = 0x071459;
191constexpr int overworldMessages = 0x03F51D;
192constexpr int overworldMessagesExpanded = 0x1417F8;
193
198
203
208
213
219
224
229
234
235constexpr int kOverworldCompressedMapPos = 0x058000;
236constexpr int kOverworldCompressedOverflowPos = 0x137FFF;
237
238constexpr int kNumTileTypes = 0x200;
239constexpr int kMap16Tiles = 0x78000;
240
241constexpr int kNumTile16Individual = 4096;
242constexpr int Map32PerScreen = 256;
243constexpr int NumberOfMap16 = 3752; // 4096
244constexpr int NumberOfMap16Ex = 4096; // 4096
245// Tile32 definitions are packed four-at-a-time into six bytes in each of the
246// four quadrant tables. Keep byte spans and definition capacities distinct:
247// the expanded table length is a byte count, not a Tile32 count.
250constexpr int kMap32TileStorageBytesVanilla = 0x33F0;
252
253constexpr int Map32DefinitionCapacityForStorageBytes(int storage_bytes) {
254 return storage_bytes <= 0 ? 0
255 : (storage_bytes / kMap32BytesPerPackedGroup) *
257}
258
263
264// Compatibility alias for callers that still use the historical name.
266constexpr int NumberOfOWSprites = 352;
268constexpr int kNumMapsPerWorld = 0x40;
269
283
288
294
295inline bool IsValidRomAddress(const Rom& rom, int address) {
296 return address >= 0 && static_cast<size_t>(address) < rom.size();
297}
298
299inline uint8_t ReadRomByteOr(const Rom& rom, int address, uint8_t fallback) {
300 if (!IsValidRomAddress(rom, address)) {
301 return fallback;
302 }
303 return rom.data()[address];
304}
305
306inline bool IsSpecialTailMapExpansionEnabled(const Rom& rom) {
307 return ReadRomByteOr(rom, GetExpandedPtrTableMarker(), 0x00) ==
309}
310
312 OverworldRomProfile profile;
315 profile.is_vanilla = profile.version == OverworldVersion::kVanilla;
318 profile.supports_area_enum =
322
323 const uint8_t tile16_flag = ReadRomByteOr(rom, kMap16ExpandedFlagPos, 0x0F);
324 const uint8_t tile32_flag = ReadRomByteOr(rom, kMap32ExpandedFlagPos, 0x04);
325 const uint8_t entrance_flag =
327
328 profile.has_expanded_tile16 =
329 !profile.is_vanilla &&
330 (profile.supports_area_enum || tile16_flag != 0x0F);
331 profile.has_expanded_tile32 =
332 !profile.is_vanilla &&
333 (profile.supports_area_enum || tile32_flag != 0x04);
334 profile.has_expanded_entrances = !profile.is_vanilla && entrance_flag != 0xB8;
335 profile.has_tail_map_expansion =
337 profile.editable_map_count =
339 return profile;
340}
341
342inline int WorldForOverworldMap(int map_index) {
343 if (map_index >= kSpecialWorldMapIdStart) {
344 return 2;
345 }
346 if (map_index >= kDarkWorldMapIdStart) {
347 return 1;
348 }
349 return 0;
350}
351
352inline bool IsSameOverworldWorld(int a, int b) {
354}
355
356inline bool CanPersistLegacyMultiAreaMap(int map_index) {
357 return map_index >= 0 && map_index < kSpecialWorldMapIdStart;
358}
359
360inline bool CanPersistLegacyScreenSize(int map_index) {
361 return map_index >= 0 && map_index < kSpecialWorldMapIdStart;
362}
363
364inline int LegacyParentTableIndexForMap(int map_index) {
365 return map_index & 0x3F;
366}
367
368inline uint8_t LegacyParentTableValueForMap(int parent_index) {
369 return static_cast<uint8_t>(parent_index & 0x3F);
370}
371
372inline int LegacyScreenSizeTableIndexForMap(int map_index) {
373 return map_index;
374}
375
390 public:
391 Overworld(Rom* rom, GameData* game_data = nullptr)
392 : rom_(rom), game_data_(game_data) {}
393
394 void SetGameData(GameData* game_data) { game_data_ = game_data; }
395
398 return kVersionConstantsMap.at(game_data_ ? game_data_->version
399 : zelda3_version::US);
400 }
401
402 // ===========================================================================
403 // Loading Methods
404 // ===========================================================================
405
407 absl::Status Load(Rom* rom);
408
410 absl::Status LoadOverworldMaps();
411
413 void LoadTileTypes();
414
416 absl::Status LoadSprites();
417
419 absl::Status LoadSpritesFromMap(int sprite_start, int sprite_count,
420 int sprite_index);
421
422 // ===========================================================================
423 // Lazy Loading / Caching
424 // ===========================================================================
425
432 absl::Status EnsureMapBuilt(int map_index);
433
435 uint64_t ComputeGraphicsConfigHash(int map_index);
436
439 const std::vector<uint8_t>* GetCachedTileset(uint64_t config_hash);
440
442 void CacheTileset(uint64_t config_hash, const std::vector<uint8_t>& tileset);
443
447
450 void InvalidateMapCache(int map_index);
451
454 void InvalidateSiblingMapCaches(int map_index);
455
456 // ===========================================================================
457 // Save Methods - Tile Data (Order Matters!)
458 // ===========================================================================
459 // These methods must be called in order because later saves depend on
460 // tile definitions being written first.
461 //
462 // Required order:
463 // 1. CreateTile32Tilemap() - Build tile32 from tile16 data
464 // 2. SaveMap32Tiles() - Write tile32 definitions
465 // 3. SaveMap16Tiles() - Write tile16 definitions
466 // 4. SaveOverworldMaps() - Write compressed map data
467
469 absl::Status Save(Rom* rom);
470
472 absl::Status SaveOverworldMaps();
473
475 absl::Status SaveLargeMaps();
476
478 absl::Status SaveLargeMapsExpanded();
479
481 absl::Status SaveSmallAreaTransitions(
482 int i, int parent_x_pos, int parent_y_pos, int transition_target_north,
483 int transition_target_west, int transition_pos_x, int transition_pos_y,
484 int screen_change_1, int screen_change_2, int screen_change_3,
485 int screen_change_4);
486
488 absl::Status SaveLargeAreaTransitions(
489 int i, int parent_x_pos, int parent_y_pos, int transition_target_north,
490 int transition_target_west, int transition_pos_x, int transition_pos_y,
491 int screen_change_1, int screen_change_2, int screen_change_3,
492 int screen_change_4);
493
495 absl::Status SaveWideAreaTransitions(
496 int i, int parent_x_pos, int parent_y_pos, int transition_target_north,
497 int transition_target_west, int transition_pos_x, int transition_pos_y,
498 int screen_change_1, int screen_change_2, int screen_change_3,
499 int screen_change_4);
500
502 absl::Status SaveTallAreaTransitions(
503 int i, int parent_x_pos, int parent_y_pos, int transition_target_north,
504 int transition_target_west, int transition_pos_x, int transition_pos_y,
505 int screen_change_1, int screen_change_2, int screen_change_3,
506 int screen_change_4);
507
508 // ===========================================================================
509 // Save Methods - Entities (Independent, any order)
510 // ===========================================================================
511
513 absl::Status SaveEntrances();
514
516 absl::Status SaveExits();
517
519 absl::Status SaveItems();
520
522 absl::Status SaveMapOverlays();
523
525 absl::Status SaveOverworldTilesType();
526
527 // ===========================================================================
528 // Save Methods - Custom Features (v2+/v3+)
529 // ===========================================================================
530
532 absl::Status SaveCustomOverworldASM(bool enable_bg_color,
533 bool enable_main_palette,
534 bool enable_mosaic,
535 bool enable_gfx_groups,
536 bool enable_subscreen_overlay,
537 bool enable_animated);
538
540 absl::Status SaveAreaSpecificBGColors();
541
543 absl::Status SaveCustomOverworldData();
544
545 // ===========================================================================
546 // Save Methods - Tile Definitions
547 // ===========================================================================
548
551 absl::Status CreateTile32Tilemap();
552
554 absl::Status SaveMap16Expanded();
555
557 absl::Status SaveMap16Tiles();
558
560 absl::Status SaveMap32Expanded();
561
563 absl::Status SaveMap32Tiles();
564
565 // ===========================================================================
566 // Save Methods - Properties
567 // ===========================================================================
568
570 absl::Status SaveMapProperties();
571
573 absl::Status SaveMusic();
574
576 absl::Status SaveAreaSizes();
577
579 void AssignMapSizes(std::vector<OverworldMap>& maps);
580
589 absl::Status ConfigureMultiAreaMap(int parent_index, AreaSizeEnum size);
590
591 auto rom() const { return rom_; }
592 auto mutable_rom() { return rom_; }
593
602 std::vector<std::pair<uint32_t, uint32_t>> GetProjectedWriteRanges() const;
603
612 const int marker_addr = GetExpandedPtrTableMarker();
613 if (!rom_ || marker_addr >= rom_->size()) {
614 return false;
615 }
616 return rom_->data()[marker_addr] == GetExpandedPtrTableMagic();
617 }
618
619 void Destroy() {
620 for (auto& map : overworld_maps_) {
621 map.Destroy();
622 }
623 overworld_maps_.clear();
624 all_entrances_.clear();
625 all_exits_.clear();
626 all_items_.clear();
627 for (auto& sprites : all_sprites_) {
628 sprites.clear();
629 }
630 tiles16_.clear();
631 tiles32_.clear();
632 tiles32_unique_.clear();
633 is_loaded_ = false;
634 }
635
636 int GetTileFromPosition(ImVec2 position) const {
637 if (current_world_ == 0) {
638 return map_tiles_.light_world[position.x][position.y];
639 } else if (current_world_ == 1) {
640 return map_tiles_.dark_world[position.x][position.y];
641 } else {
642 return map_tiles_.special_world[position.x][position.y];
643 }
644 }
645
647 switch (world_type) {
648 case 0:
649 return map_tiles_.light_world;
650 case 1:
651 return map_tiles_.dark_world;
652 case 2:
654 default:
655 return map_tiles_.light_world;
656 }
657 }
658
659 const std::vector<OverworldMap>& overworld_maps() const {
660 return overworld_maps_;
661 }
662 auto overworld_map(int i) const {
663 if (i < 0 || i >= static_cast<int>(overworld_maps_.size())) {
664 return static_cast<const OverworldMap*>(nullptr);
665 }
666 return &overworld_maps_[i];
667 }
669 if (i < 0 || i >= static_cast<int>(overworld_maps_.size())) {
670 return static_cast<OverworldMap*>(nullptr);
671 }
672 return &overworld_maps_[i];
673 }
674 auto exits() const { return &all_exits_; }
675 auto mutable_exits() { return &all_exits_; }
676 const std::vector<gfx::Tile16>& tiles16() const { return tiles16_; }
677 auto tiles32_unique() const { return tiles32_unique_; }
678 auto mutable_tiles16() { return &tiles16_; }
679 auto sprites(int state) const {
680 if (state < 0 || state >= 3)
681 return std::vector<Sprite>{};
682 return all_sprites_[state];
683 }
684 auto mutable_sprites(int state) {
685 if (state < 0 || state >= 3)
686 return static_cast<std::vector<Sprite>*>(nullptr);
687 return &all_sprites_[state];
688 }
689 const std::vector<uint8_t>& current_graphics() const {
690 static const std::vector<uint8_t> kEmpty;
692 return kEmpty;
693 return overworld_maps_[current_map_].current_graphics();
694 }
695 const std::vector<OverworldEntrance>& entrances() const {
696 return all_entrances_;
697 }
698 auto& entrances() { return all_entrances_; }
700 const std::vector<OverworldEntrance>& holes() const { return all_holes_; }
701 auto& holes() { return all_holes_; }
702 auto mutable_holes() { return &all_holes_; }
703 auto deleted_entrances() const { return deleted_entrances_; }
706 static const gfx::SnesPalette kEmpty;
708 return kEmpty;
709 return overworld_maps_[current_map_].current_palette();
710 }
711 const std::vector<uint8_t>& current_map_bitmap_data() const {
712 static const std::vector<uint8_t> kEmpty;
714 return kEmpty;
715 return overworld_maps_[current_map_].bitmap_data();
716 }
717 const std::vector<uint8_t>& tile16_blockset_data() const {
718 static const std::vector<uint8_t> kEmpty;
720 return kEmpty;
721 return overworld_maps_[current_map_].current_tile16_blockset();
722 }
723
724 bool is_current_map_valid() const {
725 return current_map_ >= 0 &&
726 current_map_ < static_cast<int>(overworld_maps_.size());
727 }
728 auto is_loaded() const { return is_loaded_; }
729 auto expanded_tile16() const { return expanded_tile16_; }
730 auto expanded_tile32() const { return expanded_tile32_; }
732 int current_map_id() const { return current_map_; }
733 int current_world() const { return current_world_; }
734 void set_current_map(int i) { current_map_ = i; }
735 void set_current_world(int world) { current_world_ = world; }
736 uint16_t GetTile(int x, int y) const {
737 if (current_world_ == 0) {
738 return map_tiles_.light_world[x][y];
739 } else if (current_world_ == 1) {
740 return map_tiles_.dark_world[x][y];
741 } else {
742 return map_tiles_.special_world[x][y];
743 }
744 }
745 void SetTile(int x, int y, uint16_t tile_id) {
746 if (current_world_ == 0) {
747 map_tiles_.light_world[x][y] = tile_id;
748 } else if (current_world_ == 1) {
749 map_tiles_.dark_world[x][y] = tile_id;
750 } else {
751 map_tiles_.special_world[x][y] = tile_id;
752 }
753 }
754 auto map_tiles() const { return map_tiles_; }
755 auto mutable_map_tiles() { return &map_tiles_; }
756 auto all_items() const { return all_items_; }
757 auto mutable_all_items() { return &all_items_; }
758 auto all_tiles_types() const { return all_tiles_types_; }
760 auto all_sprites() const { return all_sprites_; }
761
762 // Diggable tiles management
765 absl::Status LoadDiggableTiles();
766 absl::Status SaveDiggableTiles();
767 absl::Status AutoDetectDiggableTiles();
768
769 private:
776
777 void FetchLargeMaps();
778 absl::StatusOr<uint16_t> GetTile16ForTile32(int index, int quadrant,
779 int dimension,
780 const uint32_t* map32address);
781 absl::Status AssembleMap32Tiles();
782 absl::Status AssembleMap16Tiles();
783 void AssignWorldTiles(int x, int y, int sx, int sy, int tpos,
784 OverworldBlockset& world);
785 void FillBlankMapTiles(int map_index);
786 OverworldBlockset& SelectWorldBlockset(int world_type);
787 void OrganizeMapTiles(std::vector<uint8_t>& bytes,
788 std::vector<uint8_t>& bytes2, int i, int sx, int sy,
789 int& ttpos);
790 absl::Status DecompressAllMapTilesParallel();
791
794
795 bool is_loaded_ = false;
796 bool expanded_tile16_ = false;
797 bool expanded_tile32_ = false;
799
800 int game_state_ = 0;
803
804 // Cached ROM version to avoid repeated detection during loading
806
808
809 // Thread safety for parallel operations
810 mutable std::mutex map_tiles_mutex_;
811
812 // LRU cache for built maps to prevent memory exhaustion.
813 // Keep this aligned with the essential preload set so the default startup
814 // world stays warm without permanently retaining dozens of maps.
815 static constexpr int kMaxBuiltMaps = 8;
816 std::deque<int> built_map_lru_;
817
818 // Graphics config cache for blockset reuse
819 // Key: Hash of static_graphics array, Value: Precomputed current_gfx data
820 // This avoids rebuilding the same tileset for maps with identical graphics
822 std::vector<uint8_t> current_gfx; // 64KB tileset
824 };
825 std::unordered_map<uint64_t, GraphicsConfigCache> gfx_config_cache_;
826#ifdef __EMSCRIPTEN__
827 // WASM: Increased cache for Special World maps (8 × 64KB = 512KB)
828 // Special World alone needs 6+ unique graphics configs
829 static constexpr int kMaxCachedConfigs = 8;
830#else
831 // Native: Larger cache for better performance (12 × 64KB = 768KB)
832 static constexpr int kMaxCachedConfigs = 12;
833#endif
834
835 std::vector<OverworldMap> overworld_maps_;
836 std::vector<OverworldEntrance> all_entrances_;
837 std::vector<OverworldEntrance> all_holes_;
838 std::vector<OverworldExit> all_exits_;
839 std::vector<OverworldItem> all_items_;
840
841 std::vector<gfx::Tile16> tiles16_;
842 std::vector<gfx::Tile32> tiles32_;
843 std::vector<gfx::Tile32> tiles32_unique_;
844
845 std::vector<uint16_t> tiles32_list_;
846 std::vector<uint64_t> deleted_entrances_;
847
848 std::array<uint8_t, kNumOverworldMaps> map_parent_ = {0};
849 std::array<uint8_t, kNumTileTypes> all_tiles_types_ = {0};
850 std::array<std::vector<Sprite>, 3> all_sprites_;
852 std::array<std::vector<uint8_t>, kNumOverworldMaps> map_data_p1;
853 std::array<std::vector<uint8_t>, kNumOverworldMaps> map_data_p2;
854 std::array<int, kNumOverworldMaps> map_pointers1_id;
855 std::array<int, kNumOverworldMaps> map_pointers2_id;
856 std::array<int, kNumOverworldMaps> map_pointers1;
857 std::array<int, kNumOverworldMaps> map_pointers2;
858};
859
860} // namespace yaze::zelda3
861
862#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:28
auto data() const
Definition rom.h:151
auto size() const
Definition rom.h:150
static RomSettings & Get()
uint32_t GetAddressOr(const std::string &key, uint32_t default_value) const
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
Manages diggable tile state as a 512-bit bitfield.
Represents a single Overworld map screen.
static bool SupportsCustomBGColors(OverworldVersion version)
Check if ROM supports custom background colors per area (v2+)
static OverworldVersion GetVersion(const Rom &rom)
Detect ROM version from ASM marker byte.
static uint8_t GetAsmVersion(const Rom &rom)
Get raw ASM version byte from ROM.
static bool SupportsAreaEnum(OverworldVersion version)
Check if ROM supports area enum system (v3+ only)
static bool SupportsExpandedSpace(OverworldVersion version)
Check if ROM uses expanded ROM space for overworld data.
Represents the full Overworld data, light and dark world.
Definition overworld.h:389
std::vector< uint64_t > deleted_entrances_
Definition overworld.h:846
absl::Status SaveMap32Expanded()
Save expanded tile32 definitions (v1+ ROMs)
absl::Status DecompressAllMapTilesParallel()
Definition overworld.cc:750
std::vector< uint16_t > tiles32_list_
Definition overworld.h:845
void set_current_world(int world)
Definition overworld.h:735
int GetTileFromPosition(ImVec2 position) const
Definition overworld.h:636
absl::Status Load(Rom *rom)
Load all overworld data from ROM.
Definition overworld.cc:131
int current_world() const
Definition overworld.h:733
std::vector< OverworldItem > all_items_
Definition overworld.h:839
void OrganizeMapTiles(std::vector< uint8_t > &bytes, std::vector< uint8_t > &bytes2, int i, int sx, int sy, int &ttpos)
Definition overworld.cc:730
auto expanded_tile32() const
Definition overworld.h:730
zelda3_version_pointers version_constants() const
Get version-specific ROM addresses.
Definition overworld.h:397
std::array< int, kNumOverworldMaps > map_pointers1
Definition overworld.h:856
std::vector< gfx::Tile32 > tiles32_unique_
Definition overworld.h:843
const std::vector< uint8_t > & current_graphics() const
Definition overworld.h:689
auto deleted_entrances() const
Definition overworld.h:703
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.
void ClearGraphicsConfigCache()
Clear entire graphics config cache Call when palette or graphics settings change globally.
Definition overworld.h:446
const std::vector< OverworldEntrance > & holes() const
Definition overworld.h:700
absl::Status SaveMap32Tiles()
Save tile32 definitions to ROM.
const gfx::SnesPalette & current_area_palette() const
Definition overworld.h:705
std::vector< OverworldEntrance > all_entrances_
Definition overworld.h:836
absl::Status SaveTallAreaTransitions(int i, int parent_x_pos, int parent_y_pos, int transition_target_north, int transition_target_west, int transition_pos_x, int transition_pos_y, int screen_change_1, int screen_change_2, int screen_change_3, int screen_change_4)
Save screen transition data for tall (1x2) areas (v3+ only)
OverworldMapTiles map_tiles_
Definition overworld.h:807
absl::Status SaveMap16Tiles()
Save tile16 definitions to ROM.
absl::Status SaveAreaSizes()
Save area size enum data (v3+ only)
auto all_sprites() const
Definition overworld.h:760
DiggableTiles * mutable_diggable_tiles()
Definition overworld.h:764
auto sprites(int state) const
Definition overworld.h:679
auto map_tiles() const
Definition overworld.h:754
void InvalidateSiblingMapCaches(int map_index)
Invalidate cached tilesets for a map and all its siblings.
absl::Status SaveLargeMaps()
Save large map parent/sibling relationships.
auto all_items() const
Definition overworld.h:756
const std::vector< gfx::Tile16 > & tiles16() const
Definition overworld.h:676
std::array< uint8_t, kNumOverworldMaps > map_parent_
Definition overworld.h:848
void AssignWorldTiles(int x, int y, int sx, int sy, int tpos, OverworldBlockset &world)
Definition overworld.cc:685
absl::Status SaveDiggableTiles()
void InvalidateMapCache(int map_index)
Invalidate cached tileset for a specific map.
void SetGameData(GameData *game_data)
Definition overworld.h:394
Overworld(Rom *rom, GameData *game_data=nullptr)
Definition overworld.h:391
auto is_loaded() const
Definition overworld.h:728
auto expanded_tile16() const
Definition overworld.h:729
std::array< uint8_t, kNumTileTypes > all_tiles_types_
Definition overworld.h:849
std::unordered_map< uint64_t, GraphicsConfigCache > gfx_config_cache_
Definition overworld.h:825
void LoadTileTypes()
Load tile type collision data.
absl::Status CreateTile32Tilemap()
Build tile32 tilemap from current tile16 data.
const std::vector< OverworldMap > & overworld_maps() const
Definition overworld.h:659
std::array< int, kNumOverworldMaps > map_pointers1_id
Definition overworld.h:854
auto overworld_map(int i) const
Definition overworld.h:662
int current_map_id() const
Definition overworld.h:732
const std::vector< uint8_t > * GetCachedTileset(uint64_t config_hash)
Try to get cached tileset data for a graphics configuration.
const std::vector< uint8_t > & tile16_blockset_data() const
Definition overworld.h:717
absl::Status SaveLargeAreaTransitions(int i, int parent_x_pos, int parent_y_pos, int transition_target_north, int transition_target_west, int transition_pos_x, int transition_pos_y, int screen_change_1, int screen_change_2, int screen_change_3, int screen_change_4)
Save screen transition data for large (2x2) areas.
OverworldBlockset & SelectWorldBlockset(int world_type)
Definition overworld.cc:697
bool HasExpandedPointerTables() const
Check if the ROM has expanded pointer tables for tail maps.
Definition overworld.h:611
static constexpr int kMaxCachedConfigs
Definition overworld.h:832
auto all_tiles_types() const
Definition overworld.h:758
absl::Status SaveCustomOverworldASM(bool enable_bg_color, bool enable_main_palette, bool enable_mosaic, bool enable_gfx_groups, bool enable_subscreen_overlay, bool enable_animated)
Save custom ASM feature enable flags.
absl::Status SaveCustomOverworldData()
Save all v2/v3 property tables using the ROM's current feature flags.
void set_current_map(int i)
Definition overworld.h:734
void FillBlankMapTiles(int map_index)
Definition overworld.cc:708
auto mutable_overworld_map(int i)
Definition overworld.h:668
absl::Status SaveEntrances()
Save entrance warp points to ROM.
absl::Status SaveExits()
Save exit return points to ROM.
absl::Status LoadSprites()
Load sprite data for all game states.
absl::Status EnsureMapBuilt(int map_index)
Build a map on-demand if it hasn't been built yet.
uint64_t ComputeGraphicsConfigHash(int map_index)
Compute hash of graphics configuration for cache lookup.
std::vector< OverworldMap > overworld_maps_
Definition overworld.h:835
void CacheTileset(uint64_t config_hash, const std::vector< uint8_t > &tileset)
Cache tileset data for future reuse.
absl::Status SaveItems()
Save hidden overworld items to ROM.
absl::Status SaveAreaSpecificBGColors()
Save per-area background colors (v2+)
absl::Status LoadDiggableTiles()
absl::Status Save(Rom *rom)
Master save method (calls sub-methods in correct order)
std::vector< gfx::Tile32 > tiles32_
Definition overworld.h:842
absl::Status SaveWideAreaTransitions(int i, int parent_x_pos, int parent_y_pos, int transition_target_north, int transition_target_west, int transition_pos_x, int transition_pos_y, int screen_change_1, int screen_change_2, int screen_change_3, int screen_change_4)
Save screen transition data for wide (2x1) areas (v3+ only)
uint16_t GetTile(int x, int y) const
Definition overworld.h:736
absl::Status SaveOverworldMaps()
Save compressed map tile data to ROM.
std::array< std::vector< Sprite >, 3 > all_sprites_
Definition overworld.h:850
OverworldVersion cached_version_
Definition overworld.h:805
std::array< int, kNumOverworldMaps > map_pointers2_id
Definition overworld.h:855
auto tiles32_unique() const
Definition overworld.h:677
void SetTile(int x, int y, uint16_t tile_id)
Definition overworld.h:745
absl::Status LoadOverworldMaps()
Load overworld map tile data.
Definition overworld.cc:860
std::vector< gfx::Tile16 > tiles16_
Definition overworld.h:841
absl::Status AutoDetectDiggableTiles()
auto expanded_entrances() const
Definition overworld.h:731
absl::Status AssembleMap16Tiles()
Definition overworld.cc:649
std::mutex map_tiles_mutex_
Definition overworld.h:810
const std::vector< uint8_t > & current_map_bitmap_data() const
Definition overworld.h:711
auto mutable_sprites(int state)
Definition overworld.h:684
absl::Status LoadSpritesFromMap(int sprite_start, int sprite_count, int sprite_index)
Load sprites from a specific map range.
const DiggableTiles & diggable_tiles() const
Definition overworld.h:763
const std::vector< OverworldEntrance > & entrances() const
Definition overworld.h:695
std::array< std::vector< uint8_t >, kNumOverworldMaps > map_data_p1
Definition overworld.h:852
absl::Status SaveLargeMapsExpanded()
Save expanded large map data (v1+ ROMs)
void AssignMapSizes(std::vector< OverworldMap > &maps)
Assign map sizes based on area size enum (v3+)
Definition overworld.cc:318
absl::Status SaveMap16Expanded()
Save expanded tile16 definitions (v1+ ROMs)
std::vector< OverworldExit > all_exits_
Definition overworld.h:838
std::array< int, kNumOverworldMaps > map_pointers2
Definition overworld.h:857
absl::StatusOr< uint16_t > GetTile16ForTile32(int index, int quadrant, int dimension, const uint32_t *map32address)
Definition overworld.cc:578
std::array< std::vector< uint8_t >, kNumOverworldMaps > map_data_p2
Definition overworld.h:853
absl::Status SaveSmallAreaTransitions(int i, int parent_x_pos, int parent_y_pos, int transition_target_north, int transition_target_west, int transition_pos_x, int transition_pos_y, int screen_change_1, int screen_change_2, int screen_change_3, int screen_change_4)
Save screen transition data for small (1x1) areas.
std::deque< int > built_map_lru_
Definition overworld.h:816
absl::Status SaveMapOverlays()
Save interactive overlay data to ROM.
absl::Status AssembleMap32Tiles()
Definition overworld.cc:589
bool is_current_map_valid() const
Definition overworld.h:724
DiggableTiles diggable_tiles_
Definition overworld.h:851
static constexpr int kMaxBuiltMaps
Definition overworld.h:815
OverworldBlockset & GetMapTiles(int world_type)
Definition overworld.h:646
absl::Status SaveOverworldTilesType()
Save tile type collision data to ROM.
absl::Status SaveMusic()
Save per-area music IDs.
absl::Status ConfigureMultiAreaMap(int parent_index, AreaSizeEnum size)
Configure a multi-area map structure (Large/Wide/Tall)
Definition overworld.cc:406
std::vector< OverworldEntrance > all_holes_
Definition overworld.h:837
constexpr char kOverworldExpandedPtrHigh[]
constexpr char kOverworldMap16Expanded[]
constexpr char kOverworldExpandedPtrMagic[]
constexpr char kOverworldMap32BlExpanded[]
constexpr char kOverworldExpandedPtrMarker[]
constexpr char kOverworldMap32TrExpanded[]
constexpr char kOverworldExpandedPtrLow[]
constexpr char kOverworldMap32BrExpanded[]
Zelda 3 specific classes and functions.
constexpr int GravesGFX
Definition overworld.h:105
constexpr int overworldSpecialSpritePaletteExpandedTemp
Definition overworld.h:178
constexpr int kAreaGfxIdPtr
Definition overworld.h:122
constexpr int kOverworldSpritePaletteGroup
Definition overworld.h:114
constexpr int kOverworldTransitionPositionY
Definition overworld.h:146
constexpr int kNumMapsPerWorld
Definition overworld.h:268
constexpr int kOverworldSpriteset
Definition overworld.h:115
int GetMap32TileBRExpanded()
Definition overworld.h:209
bool IsValidRomAddress(const Rom &rom, int address)
Definition overworld.h:295
constexpr int kMap16ExpandedFlagPos
Definition overworld.h:170
constexpr int LimitOfMap32
Definition overworld.h:265
constexpr int NumberOfMap16Ex
Definition overworld.h:244
constexpr int kOverworldScreenTileMapChangeByScreen1
Definition overworld.h:151
constexpr int kOverworldMapDataOverflow
Definition overworld.h:156
int LegacyParentTableIndexForMap(int map_index)
Definition overworld.h:364
constexpr int kMap32BytesPerPackedGroup
Definition overworld.h:249
constexpr int kOverworldMapSizeHighByte
Definition overworld.h:137
constexpr int overworldMessagesExpanded
Definition overworld.h:192
constexpr int GravesTilemapPos
Definition overworld.h:104
constexpr int overworldSpritesBeginingExpanded
Definition overworld.h:172
constexpr int kNumTileTypes
Definition overworld.h:238
uint8_t ReadRomByteOr(const Rom &rom, int address, uint8_t fallback)
Definition overworld.h:299
constexpr int NumberOfMap32
Definition overworld.h:267
constexpr int kOverworldScreenSize
Definition overworld.h:148
constexpr int kExpandedPtrTableLow
Definition overworld.h:187
constexpr int kOverworldScreenTileMapChangeByScreen4
Definition overworld.h:154
constexpr int kNumTile16Individual
Definition overworld.h:241
int GetMap32TileTRExpanded()
Definition overworld.h:199
constexpr int kSpecialWorldMapIdStart
constexpr int ExpandedOverlaySpace
Definition overworld.h:180
constexpr int kMap32DefinitionCapacityVanilla
Definition overworld.h:259
constexpr int GravesCountOnY
Definition overworld.h:108
constexpr int kMap16Tiles
Definition overworld.h:239
constexpr int overworldSpritesAgahnimExpanded
Definition overworld.h:174
int GetMap32TileBLExpanded()
Definition overworld.h:204
constexpr int kExpandedPtrTableMarker
Definition overworld.h:184
constexpr int Map32DefinitionCapacityForStorageBytes(int storage_bytes)
Definition overworld.h:253
constexpr int GravesYLine
Definition overworld.h:107
constexpr int kNumOverworldMaps
Definition common.h:85
int GetExpandedPtrTableHigh()
Definition overworld.h:225
constexpr int GravesXTilePos
Definition overworld.h:103
bool IsSpecialTailMapExpansionEnabled(const Rom &rom)
Definition overworld.h:306
constexpr int kOverworldMusicBeginning
Definition overworld.h:125
std::vector< std::vector< uint16_t > > OverworldBlockset
Represents tile32 data for the overworld.
int GetExpandedPtrTableMarker()
Definition overworld.h:214
constexpr int kMap32TileBLExpanded
Definition overworld.h:166
AreaSizeEnum
Area size enumeration for v3+ ROMs.
constexpr int kOverworldTransitionPositionX
Definition overworld.h:147
constexpr int kOverworldMusicDarkWorld
Definition overworld.h:129
constexpr int overworldSpecialSpriteGFXGroupExpandedTemp
Definition overworld.h:177
constexpr int kOverworldSpecialPalGroup
Definition overworld.h:117
constexpr int kOverworldScreenSizeForLoading
Definition overworld.h:149
constexpr int kOverworldSpritePaletteIds
Definition overworld.h:113
constexpr int overworldTilesType
Definition overworld.h:190
constexpr int kMap32TileBRExpanded
Definition overworld.h:167
constexpr int kMap32TileCountExpanded
Definition overworld.h:168
int GetExpandedPtrTableLow()
Definition overworld.h:230
constexpr int kTransitionTargetWest
Definition overworld.h:159
constexpr int overworldMessages
Definition overworld.h:191
constexpr int kMap32TileStorageBytesVanilla
Definition overworld.h:250
constexpr int kOverworldMusicAgahnim
Definition overworld.h:128
constexpr int kMap32TileStorageBytesExpanded
Definition overworld.h:251
constexpr int kOverworldSpritesZelda
Definition overworld.h:120
constexpr int kOverworldMapParentId
Definition overworld.h:145
constexpr int GraveLinkSpecialHole
Definition overworld.h:109
constexpr int Map32PerScreen
Definition overworld.h:242
constexpr int GravesXPos
Definition overworld.h:106
constexpr int kMap32ExpandedFlagPos
Definition overworld.h:169
constexpr int kMap32DefinitionsPerPackedGroup
Definition overworld.h:248
OverworldVersion
ROM version detection for overworld features.
@ kVanilla
0xFF in ROM, no ZScream ASM applied
bool IsSameOverworldWorld(int a, int b)
Definition overworld.h:352
constexpr int kExpandedPtrTableHigh
Definition overworld.h:186
constexpr int overworldCustomMosaicASM
Definition overworld.h:160
constexpr int kOverworldMusicMasterSword
Definition overworld.h:127
constexpr int kOverworldMusicZelda
Definition overworld.h:126
constexpr int kOverworldMessageIds
Definition overworld.h:123
constexpr int NumberOfMap16
Definition overworld.h:243
constexpr int kOverworldMapSize
Definition overworld.h:134
constexpr int kOverworldScreenTileMapChangeByScreen2
Definition overworld.h:152
constexpr int overworldSpritesDataStartExpanded
Definition overworld.h:175
constexpr int kDarkWorldMapIdStart
OverworldRomProfile DetectOverworldRomProfile(const Rom &rom)
Definition overworld.h:311
int GetOverworldEntranceFlagExpanded()
bool CanPersistLegacyScreenSize(int map_index)
Definition overworld.h:360
constexpr int kEssentialMapsPerWorld
Definition overworld.h:100
constexpr int kOverworldCompressedMapPos
Definition overworld.h:235
constexpr int overworldCustomMosaicArray
Definition overworld.h:161
int WorldForOverworldMap(int map_index)
Definition overworld.h:342
constexpr int kOverworldSpritesBeginning
Definition overworld.h:118
constexpr int kExpandedMapCount
Definition overworld.h:188
constexpr int kOverworldScreenTileMapChangeByScreen3
Definition overworld.h:153
bool CanPersistLegacyMultiAreaMap(int map_index)
Definition overworld.h:356
uint8_t LegacyParentTableValueForMap(int parent_index)
Definition overworld.h:368
int Map32DefinitionCapacityForProfile(const OverworldRomProfile &profile)
Definition overworld.h:289
uint8_t GetExpandedPtrTableMagic()
Definition overworld.h:220
constexpr int kMap16TilesExpanded
Definition overworld.h:164
constexpr uint8_t kExpandedPtrTableMagic
Definition overworld.h:185
int Map32StorageBytesForProfile(const OverworldRomProfile &profile)
Definition overworld.h:284
constexpr int kMap32DefinitionCapacityExpanded
Definition overworld.h:261
constexpr int kOverworldSpritesAgahnim
Definition overworld.h:119
int LegacyScreenSizeTableIndexForMap(int map_index)
Definition overworld.h:372
constexpr int kTransitionTargetNorth
Definition overworld.h:158
constexpr int overworldSpritesZeldaExpanded
Definition overworld.h:173
constexpr int kOverworldCompressedOverflowPos
Definition overworld.h:236
constexpr int GravesYTilePos
Definition overworld.h:102
constexpr int NumberOfOWSprites
Definition overworld.h:266
constexpr int kMap32TileTRExpanded
Definition overworld.h:165
int GetMap16TilesExpanded()
Definition overworld.h:194
constexpr int kOverworldMapPaletteIds
Definition overworld.h:112
constexpr int kOverworldEntranceAllowedTilesLeft
Definition overworld.h:130
constexpr int kOverworldSpecialGfxGroup
Definition overworld.h:116
constexpr int kOverworldEntranceAllowedTilesRight
Definition overworld.h:131
constexpr int GraveLinkSpecialStairs
Definition overworld.h:110
zelda3_version version
Definition game_data.h:80
Overworld map tile32 data.
ROM data pointers for different game versions.
Definition zelda.h:71