36 if (ImGui::Begin(
"Dungeon Object Emulator Preview", &
show_window_, ImGuiWindowFlags_AlwaysAutoResize)) {
41 ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f),
"ROM: Loaded ✓");
43 ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f),
"ROM: Not loaded ✗");
52 ImGui::BeginChild(
"PreviewRegion", ImVec2(260, 260),
true, ImGuiWindowFlags_NoScrollbar);
56 ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f),
"No texture available");
61 ImGui::Text(
"Execution:");
68 ImGui::Text(
"Status:");
71 ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f),
"✓ OK");
73 ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f),
"✗ %s",
last_error_.c_str());
79 ImGui::TextWrapped(
"This tool uses the SNES emulator to render objects by "
80 "executing the game's native drawing routines from bank $01.");
145 int palette_id = default_room.
palette;
146 if (palette_id < 0 || palette_id >=
static_cast<int>(dungeon_main_pal_group.size())) {
147 printf(
"[EMU] Warning: Room palette %d out of bounds, using palette 0\n", palette_id);
151 auto palette = dungeon_main_pal_group[palette_id];
152 for (
size_t i = 0; i < palette.size() && i < 256; ++i) {
153 ppu.cgram[i] = palette[i].snes();
160 for (
size_t i = 0; i < gfx_buffer.size() / 2 && i < 0x8000; ++i) {
161 ppu.vram[i] = gfx_buffer[i * 2] | (gfx_buffer[i * 2 + 1] << 8);
166 for (uint32_t i = 0; i < 0x2000; i++) {
189 const uint32_t object_data_addr = 0x7E1000;
213 uint16_t handler_offset = 0;
215 uint32_t table_addr = 0;
220 table_addr = 0x018470 + ((
object_id_ - 0x100) * 2);
222 table_addr = 0x0185F0 + ((
object_id_ - 0x200) * 2);
225 if (table_addr < rom_->size() - 1) {
226 uint8_t lo = rom_data[table_addr];
227 uint8_t hi = rom_data[table_addr + 1];
228 handler_offset = lo | (hi << 8);
230 last_error_ =
"Object ID out of bounds for handler lookup";
234 if (handler_offset == 0x0000) {
236 snprintf(buf,
sizeof(buf),
"Object $%04X has no drawing routine",
object_id_);
242 const uint16_t return_addr = 0x8000;
246 uint16_t sp = cpu.SP();
253 cpu.PC = handler_offset;
255 printf(
"[EMU] Rendering object $%04X at (%d,%d), handler=$%04X\n",
259 int max_cycles = 100000;
261 while (cycles < max_cycles) {
262 if (cpu.PB == 0x01 && cpu.PC == return_addr) {
271 printf(
"[EMU] Completed after %d cycles, PC=$%02X:%04X\n",
272 cycles, cpu.PB, cpu.PC);
274 if (cycles >= max_cycles) {
280 ppu.HandleFrameStart();
281 for (
int line = 0; line < 224; line++) {
287 void* pixels =
nullptr;