Execute a batch of CPU cycles. Runs up to `CYCLES_PER_BATCH` cycles, then returns to check for commands. Frames and state are sent automatically when `VBlank` starts (natural frame boundary).
(&mut self)
| 528 | let species_bytes = species.to_le_bytes(); |
| 529 | let mut maps_patched = 0u32; |
| 530 | let mut i = 0; |
| 531 | |
| 532 | loop { |
| 533 | let pos = table_offset as usize + i * 20; |
| 534 | if pos + 20 > rom.len() { |
| 535 | break; |
| 536 | } |
| 537 | let map_group = rom[pos]; |
| 538 | let map_num = rom[pos + 1]; |
| 539 | // Terminator |
| 540 | if map_group == 0xFF && map_num == 0xFF { |
| 541 | break; |
| 542 | } |
| 543 | // Grass pointer (little-endian u32 at offset +4) |
| 544 | let grass_ptr = u32::from_le_bytes([ |
| 545 | rom[pos + 4], |
| 546 | rom[pos + 5], |
| 547 | rom[pos + 6], |
| 548 | rom[pos + 7], |
| 549 | ]); |
| 550 | // Valid ROM pointer |
| 551 | if (0x0800_0000..0x0A00_0000).contains(&grass_ptr) { |
| 552 | let info_offset = (grass_ptr - 0x0800_0000) as usize; |
| 553 | // WildPokemonInfo: { rate: u32, pokemon_ptr: u32 } |
| 554 | if info_offset + 8 <= rom.len() { |
| 555 | let pokemon_ptr = u32::from_le_bytes([ |
| 556 | rom[info_offset + 4], |
| 557 | rom[info_offset + 5], |
| 558 | rom[info_offset + 6], |
| 559 | rom[info_offset + 7], |
| 560 | ]); |
| 561 | if (0x0800_0000..0x0A00_0000).contains(&pokemon_ptr) { |
| 562 | let arr_offset = (pokemon_ptr - 0x0800_0000) as usize; |
| 563 | // Patch 12 entries: {min_level: u8, max_level: u8, species: u16} |
| 564 | for entry in 0..12usize { |
| 565 | let e = arr_offset + entry * 4; |
| 566 | if e + 4 <= rom.len() { |
| 567 | rom[e] = level; // min_level |
| 568 | rom[e + 1] = level; // max_level |
| 569 | rom[e + 2] = species_bytes[0]; |
| 570 | rom[e + 3] = species_bytes[1]; |
| 571 | } |
| 572 | } |
| 573 | maps_patched += 1; |
| 574 | } |
| 575 | } |
| 576 | } |
| 577 | i += 1; |
| 578 | } |
| 579 | |
| 580 | tracing::info!("Patched {maps_patched} maps: species={species}, level={level}"); |
| 581 | self.send_event(EmuEvent::WildEncounterPatched { |
| 582 | maps_patched, |
| 583 | message: format!("Patched {maps_patched} maps: Lv.{level}"), |
| 584 | }); |
| 585 | } |
| 586 | EmuCommand::SetDisasmEnabled(enabled) => { |
| 587 | // Gate the per-instruction push without tearing down the |
no test coverage detected