156 bool verbose = parser.
HasFlag(
"verbose");
157 bool all_rooms = parser.
HasFlag(
"all");
158 bool deep_scan = parser.
HasFlag(
"deep");
159 auto room_id_arg = parser.
GetInt(
"room");
160 bool is_json = formatter.
IsJson();
162 if (deep_scan) all_rooms =
true;
164 OutputTextBanner(is_json);
166 std::vector<RoomDiagnostic> diagnostics;
167 int total_objects = 0;
168 int total_sprites = 0;
170 int warning_rooms = 0;
173 if (room_id_arg.ok()) {
175 int room_id = room_id_arg.value();
176 if (room_id < 0 || room_id >= kNumRooms) {
177 return absl::InvalidArgumentError(
178 absl::StrFormat(
"Room ID must be between 0 and %d", kNumRooms - 1));
181 auto diag = DiagnoseRoom(rom, room_id);
182 diagnostics.push_back(diag);
183 total_objects = diag.object_count;
184 total_sprites = diag.sprite_count;
186 if (diag.IsValid() && diag.findings.empty()) {
189 bool has_errors =
false;
190 bool has_warnings =
false;
191 for (
const auto& finding : diag.findings) {
199 if (has_errors) error_rooms = 1;
200 else if (has_warnings) warning_rooms = 1;
201 else valid_rooms = 1;
204 }
else if (all_rooms) {
207 std::cout <<
"\nAnalyzing all " << kNumRooms <<
" rooms...\n";
210 for (
int room_id = 0; room_id < kNumRooms; ++room_id) {
211 auto diag = DiagnoseRoom(rom, room_id);
212 diagnostics.push_back(diag);
213 total_objects += diag.object_count;
214 total_sprites += diag.sprite_count;
216 bool has_errors =
false;
217 bool has_warnings =
false;
218 for (
const auto& finding : diag.findings) {
229 }
else if (has_warnings) {
237 std::vector<int> sample_rooms = {0, 1, 2, 3, 4, 5, 6, 7,
243 std::cout <<
"\nAnalyzing " << sample_rooms.size() <<
" sample rooms...\n";
244 std::cout <<
"(Use --all to analyze all " << kNumRooms <<
" rooms)\n";
247 for (
int room_id : sample_rooms) {
248 if (room_id >= kNumRooms)
continue;
249 auto diag = DiagnoseRoom(rom, room_id);
250 diagnostics.push_back(diag);
251 total_objects += diag.object_count;
252 total_sprites += diag.sprite_count;
254 bool has_errors =
false;
255 bool has_warnings =
false;
256 for (
const auto& finding : diag.findings) {
267 }
else if (has_warnings) {
276 std::vector<DiagnosticFinding> deep_findings;
278 CheckUnusedRooms(diagnostics, deep_findings);
282 formatter.
AddField(
"total_rooms",
static_cast<int>(diagnostics.size()));
283 formatter.
AddField(
"valid_rooms", valid_rooms);
284 formatter.
AddField(
"warning_rooms", warning_rooms);
285 formatter.
AddField(
"error_rooms", error_rooms);
286 formatter.
AddField(
"total_objects", total_objects);
287 formatter.
AddField(
"total_sprites", total_sprites);
290 for (
const auto& diag : diagnostics) {
293 }
else if (verbose || !diag.findings.empty()) {
295 std::string status = diag.IsValid() && diag.findings.empty() ?
"OK" :
"ISSUES";
297 "Room 0x%02X: %s (objects=%d, sprites=%d, chests=%d)",
298 diag.room_id, status, diag.object_count, diag.sprite_count,
305 std::vector<DiagnosticFinding> all_findings;
306 for (
const auto& diag : diagnostics) {
307 for (
const auto& finding : diag.findings) {
308 all_findings.push_back(finding);
312 for (
const auto& finding : deep_findings) {
313 all_findings.push_back(finding);
317 for (
const auto& finding : all_findings) {
324 OutputTextSummary(
static_cast<int>(diagnostics.size()), valid_rooms,
325 warning_rooms, error_rooms, total_objects, total_sprites);
327 if (!all_findings.empty()) {
328 std::cout <<
"\n=== Issues Found ===\n";
329 for (
const auto& finding : all_findings) {
330 std::cout <<
" " << finding.FormatText() <<
"\n";
335 return absl::OkStatus();