3#include "absl/strings/str_format.h"
17 auto tile_id_str = parser.
GetString(
"tile").value();
20 if (!ParseHexString(tile_id_str, &tile_id)) {
21 return absl::InvalidArgumentError(
"Invalid tile ID format. Must be hex.");
26 auto ow_status = overworld.
Load(rom);
27 if (!ow_status.ok()) {
33 if (!matches_or.ok()) {
34 return matches_or.status();
36 const auto& matches = matches_or.value();
40 formatter.
AddField(
"tile_id", absl::StrFormat(
"0x%03X", tile_id));
41 formatter.
AddField(
"matches_found",
static_cast<int>(matches.size()));
44 for (
const auto& match : matches) {
46 formatter.
AddField(
"map_id", absl::StrFormat(
"0x%02X", match.map_id));
48 formatter.
AddField(
"local_x", match.local_x);
49 formatter.
AddField(
"local_y", match.local_y);
50 formatter.
AddField(
"global_x", match.global_x);
51 formatter.
AddField(
"global_y", match.global_y);
57 return absl::OkStatus();
63 auto screen_id_str = parser.
GetString(
"screen").value();
66 if (!ParseHexString(screen_id_str, &screen_id)) {
67 return absl::InvalidArgumentError(
"Invalid screen ID format. Must be hex.");
72 auto ow_status = overworld.
Load(rom);
73 if (!ow_status.ok()) {
79 if (!summary_or.ok()) {
80 return summary_or.status();
82 const auto& summary = summary_or.value();
86 formatter.
AddField(
"screen_id", absl::StrFormat(
"0x%02X", summary.map_id));
90 formatter.
AddField(
"x", summary.map_x);
91 formatter.
AddField(
"y", summary.map_y);
92 formatter.
AddField(
"local_index", summary.local_index);
96 formatter.
AddField(
"label", summary.area_size);
97 formatter.
AddField(
"is_large", summary.is_large_map);
98 formatter.
AddField(
"parent", absl::StrFormat(
"0x%02X", summary.parent_map));
99 formatter.
AddField(
"quadrant", summary.large_quadrant);
103 absl::StrFormat(
"0x%04X", summary.message_id));
105 absl::StrFormat(
"0x%02X", summary.area_graphics));
107 absl::StrFormat(
"0x%02X", summary.area_palette));
109 absl::StrFormat(
"0x%02X", summary.main_palette));
111 absl::StrFormat(
"0x%02X", summary.animated_gfx));
112 formatter.
AddField(
"subscreen_overlay",
113 absl::StrFormat(
"0x%04X", summary.subscreen_overlay));
114 formatter.
AddField(
"area_specific_bg_color",
115 absl::StrFormat(
"0x%04X", summary.area_specific_bg_color));
119 for (uint8_t gfx : summary.sprite_graphics) {
125 for (uint8_t pal : summary.sprite_palettes) {
131 for (uint8_t music : summary.area_music) {
132 formatter.
AddArrayItem(absl::StrFormat(
"0x%02X", music));
137 for (uint8_t sgfx : summary.static_graphics) {
138 formatter.
AddArrayItem(absl::StrFormat(
"0x%02X", sgfx));
143 formatter.
AddField(
"enabled", summary.has_overlay);
144 formatter.
AddField(
"id", absl::StrFormat(
"0x%04X", summary.overlay_id));
149 return absl::OkStatus();
155 auto screen_id_str = parser.
GetString(
"screen").value_or(
"all");
159 auto ow_status = overworld.
Load(rom);
160 if (!ow_status.ok()) {
166 if (screen_id_str !=
"all") {
168 if (!ParseHexString(screen_id_str, &map_id)) {
169 return absl::InvalidArgumentError(
170 "Invalid screen ID format. Must be hex.");
177 if (!warps_or.ok()) {
178 return warps_or.status();
180 const auto& warps = warps_or.value();
184 formatter.
AddField(
"screen_filter", screen_id_str);
185 formatter.
AddField(
"total_warps",
static_cast<int>(warps.size()));
188 for (
const auto& warp : warps) {
191 formatter.
AddField(
"map_id", absl::StrFormat(
"0x%02X", warp.map_id));
194 absl::StrFormat(
"(%d,%d)", warp.pixel_x, warp.pixel_y));
195 formatter.
AddField(
"map_pos", absl::StrFormat(
"0x%04X", warp.map_pos));
197 if (warp.entrance_id.has_value()) {
199 absl::StrFormat(
"0x%02X", warp.entrance_id.value()));
201 if (warp.entrance_name.has_value()) {
202 formatter.
AddField(
"entrance_name", warp.entrance_name.value());
204 if (warp.room_id.has_value()) {
206 absl::StrFormat(
"0x%04X", warp.room_id.value()));
209 formatter.
AddField(
"deleted", warp.deleted);
210 formatter.
AddField(
"is_hole", warp.is_hole);
216 return absl::OkStatus();
222 auto screen_id_str = parser.
GetString(
"screen").value_or(
"all");
226 auto ow_status = overworld.
Load(rom);
227 if (!ow_status.ok()) {
233 if (screen_id_str !=
"all") {
235 if (!ParseHexString(screen_id_str, &map_id)) {
236 return absl::InvalidArgumentError(
237 "Invalid screen ID format. Must be hex.");
244 if (!sprites_or.ok()) {
245 return sprites_or.status();
247 const auto& sprites = sprites_or.value();
251 formatter.
AddField(
"screen_filter", screen_id_str);
252 formatter.
AddField(
"total_sprites",
static_cast<int>(sprites.size()));
255 for (
const auto& sprite : sprites) {
258 absl::StrFormat(
"0x%02X", sprite.sprite_id));
259 formatter.
AddField(
"map_id", absl::StrFormat(
"0x%02X", sprite.map_id));
262 absl::StrFormat(
"(%d,%d)", sprite.x, sprite.y));
264 if (sprite.sprite_name.has_value()) {
265 formatter.
AddField(
"name", sprite.sprite_name.value());
273 return absl::OkStatus();
279 auto entrance_id_str = parser.
GetString(
"entrance").value();
282 if (!ParseHexString(entrance_id_str, &entrance_id)) {
283 return absl::InvalidArgumentError(
284 "Invalid entrance ID format. Must be hex.");
289 auto ow_status = overworld.
Load(rom);
290 if (!ow_status.ok()) {
296 if (!details_or.ok()) {
297 return details_or.status();
299 const auto& details = details_or.value();
304 absl::StrFormat(
"0x%02X", details.entrance_id));
305 formatter.
AddField(
"map_id", absl::StrFormat(
"0x%02X", details.map_id));
308 absl::StrFormat(
"(%d,%d)", details.x, details.y));
309 formatter.
AddField(
"area_position", absl::StrFormat(
"(%d,%d)", details.area_x,
311 formatter.
AddField(
"map_pos", absl::StrFormat(
"0x%04X", details.map_pos));
312 formatter.
AddField(
"is_hole", details.is_hole);
314 if (details.entrance_name.has_value()) {
315 formatter.
AddField(
"name", details.entrance_name.value());
320 return absl::OkStatus();
326 auto screen_id_str = parser.
GetString(
"screen").value_or(
"all");
330 auto ow_status = overworld.
Load(rom);
331 if (!ow_status.ok()) {
343 formatter.
BeginObject(
"Overworld Tile Statistics");
344 formatter.
AddField(
"screen_filter", screen_id_str);
345 formatter.
AddField(
"status",
"partial_implementation");
347 "Comprehensive tile statistics not yet implemented. "
348 "Use overworld-find-tile for specific tile analysis.");
349 formatter.
AddField(
"total_tiles", 0);
350 formatter.
AddField(
"unique_tiles", 0);
356 return absl::OkStatus();
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
Utility for parsing common CLI argument patterns.
std::optional< std::string > GetString(const std::string &name) const
Parse a named argument (e.g., –format=json or –format json)
Represents the full Overworld data, light and dark world.
absl::Status Load(Rom *rom)
Load all overworld data from ROM.
absl::StatusOr< MapSummary > BuildMapSummary(zelda3::Overworld &overworld, int map_id)
absl::StatusOr< std::vector< WarpEntry > > CollectWarpEntries(const zelda3::Overworld &overworld, const WarpQuery &query)
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< std::vector< TileMatch > > FindTileMatches(zelda3::Overworld &overworld, uint16_t tile_id, const TileSearchOptions &options)
std::string WarpTypeName(WarpType type)
std::string WorldName(int world)
bool ParseHexString(absl::string_view str, int *out)
std::optional< int > map_id
std::optional< int > map_id