yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
overworld_inspect.h
Go to the documentation of this file.
1#ifndef YAZE_CLI_HANDLERS_OVERWORLD_INSPECT_H_
2#define YAZE_CLI_HANDLERS_OVERWORLD_INSPECT_H_
3
4#include <cstdint>
5#include <optional>
6#include <string>
7#include <string_view>
8#include <utility>
9#include <vector>
10
11#include "absl/status/statusor.h"
12
13namespace yaze {
14class Rom;
15
16namespace zelda3 {
17class Overworld;
18class OverworldEntrance;
19class OverworldExit;
20class OverworldMap;
21} // namespace zelda3
22
23namespace cli {
24namespace overworld {
25
26enum class WarpType {
28 kHole,
29 kExit,
30};
31
32struct MapSummary {
33 int map_id;
34 int world;
36 int map_x;
37 int map_y;
41 std::string area_size;
42 uint16_t message_id;
44 uint8_t area_palette;
45 uint8_t main_palette;
46 uint8_t animated_gfx;
49 std::vector<uint8_t> sprite_graphics;
50 std::vector<uint8_t> sprite_palettes;
51 std::vector<uint8_t> area_music;
52 std::vector<uint8_t> static_graphics;
54 uint16_t overlay_id;
55};
56
57struct WarpEntry {
59 uint16_t raw_map_id;
60 int map_id;
61 int world;
63 int map_x;
64 int map_y;
69 uint16_t map_pos;
70 bool deleted;
71 bool is_hole;
72 std::optional<uint8_t> entrance_id;
73 std::optional<std::string> entrance_name;
74 std::optional<uint16_t> room_id;
75 std::optional<uint16_t> door_type_1;
76 std::optional<uint16_t> door_type_2;
77};
78
79struct WarpQuery {
80 std::optional<int> world;
81 std::optional<int> map_id;
82 std::optional<WarpType> type;
83};
84
85struct TileMatch {
86 int map_id;
87 int world;
92};
93
95 std::optional<int> map_id;
96 std::optional<int> world;
97};
98
99// Where one tile16 of an overworld area lives. Tile commands take x/y
100// relative to the top-left of the area's parent screen: 0-31 per axis for a
101// small area, 0-63 on each doubled axis of a large, wide, or tall area. The
102// world blockset (Overworld::GetMapTiles) is indexed [world_x][world_y] where
103// each screen owns a 32x32 block at ((local % 8) * 32, (local / 8) * 32);
104// world_x/world_y are also the editor canvas tile coordinates.
106 int map_id = 0; // screen the caller named
107 int parent_map = 0; // screen at the area's top-left
108 int world = 0; // 0 light, 1 dark, 2 special
109 int area_width = 32; // tile16 columns in the area
110 int area_height = 32; // tile16 rows in the area
111 int area_x = 0; // caller coordinates, relative to parent_map
112 int area_y = 0;
113 int screen_id = 0; // screen that contains the tile
114 int screen_x = 0; // 0-31 within screen_id
115 int screen_y = 0;
116 int world_x = 0; // index into the world blockset
117 int world_y = 0;
118};
119
120// Screens spanned by an area: {columns, rows}, each 1 or 2.
121std::pair<int, int> AreaScreenSpan(const zelda3::OverworldMap& parent_map);
122
123// Pure address math, independent of ROM loading. Fails when the parent is in
124// another world, the named screen is outside the parent's span, or x/y fall
125// outside the area.
126absl::StatusOr<AreaTileLocation> ResolveAreaTileLocation(
127 int map_id, int parent_map, int area_columns, int area_rows, int x, int y);
128
129// Resolves the parent and span of map_id from a loaded overworld.
130absl::StatusOr<AreaTileLocation> ResolveAreaTileForMap(
131 const zelda3::Overworld& overworld, int map_id, int x, int y);
132
133// Converts a screen-local tile (0-31) to its area-relative location.
134absl::StatusOr<AreaTileLocation> LocateScreenTile(
135 const zelda3::Overworld& overworld, int screen_id, int screen_x,
136 int screen_y);
137
138absl::StatusOr<uint16_t> ReadAreaTile(zelda3::Overworld& overworld,
139 const AreaTileLocation& location);
140absl::Status WriteAreaTile(zelda3::Overworld& overworld,
141 const AreaTileLocation& location, uint16_t tile_id);
142
144 uint8_t sprite_id;
146 int world;
147 int x;
148 int y;
149 std::optional<std::string> sprite_name;
150 // Game-state sprite list this entry came from (0 = beginning, 1 = first
151 // part, 2 = second part) and its index within that map's list.
152 int phase = 0;
153 int list_index = 0;
154 // Raw 16px tile coordinates within the parent area (list byte low 6 bits).
155 int local_x = 0;
156 int local_y = 0;
157};
158
159// Game-state (phase) names used by overworld sprite commands.
160const char* SpritePhaseName(int phase);
161
163 std::optional<int> map_id;
164 std::optional<int> world;
165 std::optional<uint8_t> sprite_id;
166 std::optional<int> phase;
167};
168
170 uint8_t entrance_id;
172 int world;
173 int x;
174 int y;
175 uint8_t area_x;
176 uint8_t area_y;
177 uint16_t map_pos;
179 std::optional<std::string> entrance_name;
180};
181
184 int world;
185 uint16_t tile_id;
186 int count;
187 std::vector<std::pair<int, int>> positions; // (x, y) positions
188};
189
190// Tile16 placement counts over the 32x32 tile grid of each screen. Every
191// screen of a multi-screen area is its own 32x32 block of the world grid, so
192// counting per screen covers each placed tile exactly once.
194 uint16_t tile_id = 0;
195 int count = 0; // placements in the scanned screens
196 int screens = 0; // scanned screens that place it at least once
197};
198
200 int map_id = 0;
201 int world = 0;
202 int parent_map = 0;
203 int total_tiles = 0; // always 1024 (32x32)
205 uint16_t top_tile = 0;
207 int tile_count = 0; // placements of TileUsageQuery::tile_id, if set
208};
209
211 int world = 0;
212 int screens = 0;
213 int total_tiles = 0;
215};
216
218 std::optional<int> map_id; // one screen
219 std::optional<int> world;
220 std::optional<uint16_t> tile_id; // also count this tile per screen
221};
222
225 int total_tiles = 0;
226 std::vector<TileUsageCount> tiles; // most placed first, then by tile id
227 std::vector<WorldTileUsage> worlds;
228 std::vector<ScreenTileUsage> screens; // by map id
229};
230
231// Counts tile16 usage from the loaded world grids. Fails when a scanned
232// world's grid is not loaded.
233absl::StatusOr<TileUsageSummary> CollectTileUsage(zelda3::Overworld& overworld,
234 const TileUsageQuery& query);
235
236absl::StatusOr<int> ParseNumeric(std::string_view value, int base = 0);
237absl::StatusOr<int> ParseWorldSpecifier(std::string_view value);
238absl::StatusOr<int> InferWorldFromMapId(int map_id);
239std::string WorldName(int world);
240std::string WarpTypeName(WarpType type);
241
242absl::StatusOr<MapSummary> BuildMapSummary(zelda3::Overworld& overworld,
243 int map_id);
244
245absl::StatusOr<std::vector<WarpEntry>> CollectWarpEntries(
246 const zelda3::Overworld& overworld, const WarpQuery& query);
247
248absl::StatusOr<std::vector<TileMatch>> FindTileMatches(
249 zelda3::Overworld& overworld, uint16_t tile_id,
250 const TileSearchOptions& options = {});
251
252absl::StatusOr<std::vector<OverworldSprite>> CollectOverworldSprites(
253 const zelda3::Overworld& overworld, const SpriteQuery& query);
254
255absl::StatusOr<EntranceDetails> GetEntranceDetails(
256 const zelda3::Overworld& overworld, uint8_t entrance_id);
257
258absl::StatusOr<TileStatistics> AnalyzeTileUsage(
259 zelda3::Overworld& overworld, uint16_t tile_id,
260 const TileSearchOptions& options = {});
261
262} // namespace overworld
263} // namespace cli
264} // namespace yaze
265
266#endif // YAZE_CLI_HANDLERS_OVERWORLD_INSPECT_H_
Represents a single Overworld map screen.
absl::StatusOr< TileUsageSummary > CollectTileUsage(zelda3::Overworld &overworld, const TileUsageQuery &query)
absl::StatusOr< int > InferWorldFromMapId(int map_id)
absl::StatusOr< MapSummary > BuildMapSummary(zelda3::Overworld &overworld, int map_id)
absl::Status WriteAreaTile(zelda3::Overworld &overworld, const AreaTileLocation &location, uint16_t tile_id)
absl::StatusOr< AreaTileLocation > ResolveAreaTileLocation(int map_id, int parent_map, int area_columns, int area_rows, int x, int y)
absl::StatusOr< std::vector< WarpEntry > > CollectWarpEntries(const zelda3::Overworld &overworld, const WarpQuery &query)
absl::StatusOr< int > ParseNumeric(std::string_view value, int base)
absl::StatusOr< TileStatistics > AnalyzeTileUsage(zelda3::Overworld &overworld, uint16_t tile_id, const TileSearchOptions &options)
absl::StatusOr< int > ParseWorldSpecifier(std::string_view value)
absl::StatusOr< AreaTileLocation > ResolveAreaTileForMap(const zelda3::Overworld &overworld, int map_id, int x, int y)
absl::StatusOr< EntranceDetails > GetEntranceDetails(const zelda3::Overworld &overworld, uint8_t entrance_id)
absl::StatusOr< std::vector< OverworldSprite > > CollectOverworldSprites(const zelda3::Overworld &overworld, const SpriteQuery &query)
absl::StatusOr< uint16_t > ReadAreaTile(zelda3::Overworld &overworld, const AreaTileLocation &location)
absl::StatusOr< AreaTileLocation > LocateScreenTile(const zelda3::Overworld &overworld, int screen_id, int screen_x, int screen_y)
absl::StatusOr< std::vector< TileMatch > > FindTileMatches(zelda3::Overworld &overworld, uint16_t tile_id, const TileSearchOptions &options)
std::string WarpTypeName(WarpType type)
const char * SpritePhaseName(int phase)
std::string WorldName(int world)
std::pair< int, int > AreaScreenSpan(const zelda3::OverworldMap &parent_map)
std::optional< std::string > entrance_name
std::vector< uint8_t > sprite_graphics
std::vector< uint8_t > static_graphics
std::vector< uint8_t > sprite_palettes
std::vector< uint8_t > area_music
std::optional< std::string > sprite_name
std::optional< uint8_t > sprite_id
std::vector< std::pair< int, int > > positions
std::vector< ScreenTileUsage > screens
std::vector< TileUsageCount > tiles
std::vector< WorldTileUsage > worlds
std::optional< std::string > entrance_name
std::optional< uint16_t > door_type_1
std::optional< uint16_t > door_type_2
std::optional< uint8_t > entrance_id
std::optional< uint16_t > room_id
std::optional< WarpType > type