From 13b588fa755deb166e173ceae84fba15fad3ef1c Mon Sep 17 00:00:00 2001 From: scawful Date: Sat, 3 Feb 2024 00:03:06 -0500 Subject: [PATCH] Dungeon Object Renderer updates --- src/app/emu/cpu/cpu.cc | 2 ++ src/app/emu/cpu/cpu.h | 13 +++++---- src/app/zelda3/dungeon/object_renderer.h | 35 ++++++++++-------------- src/app/zelda3/dungeon/room.cc | 15 +++++----- 4 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/app/emu/cpu/cpu.cc b/src/app/emu/cpu/cpu.cc index 78ea134e..45cb894a 100644 --- a/src/app/emu/cpu/cpu.cc +++ b/src/app/emu/cpu/cpu.cc @@ -1576,6 +1576,8 @@ void CPU::LogInstructions(uint16_t PC, uint8_t opcode, uint16_t operand, << static_cast(DB); std::cout << " D:" << std::hex << std::setw(2) << std::setfill('0') << static_cast(D); + std::cout << " SP:" << std::hex << std::setw(4) << std::setfill('0') + << SP(); std::cout << std::endl; } diff --git a/src/app/emu/cpu/cpu.h b/src/app/emu/cpu/cpu.h index 04707705..cc877fd4 100644 --- a/src/app/emu/cpu/cpu.h +++ b/src/app/emu/cpu/cpu.h @@ -394,6 +394,13 @@ class CPU : public Memory, public Loggable, public core::ExperimentFlags { } } + void PushByte(uint8_t value) override { memory.PushByte(value); } + void PushWord(uint16_t value) override { memory.PushWord(value); } + uint8_t PopByte() override { return memory.PopByte(); } + uint16_t PopWord() override { return memory.PopWord(); } + void PushLong(uint32_t value) override { memory.PushLong(value); } + uint32_t PopLong() override { return memory.PopLong(); } + // ====================================================== // Instructions @@ -702,12 +709,6 @@ class CPU : public Memory, public Loggable, public core::ExperimentFlags { } bool GetFlag(uint8_t mask) const { return (status & mask) != 0; } - void PushByte(uint8_t value) override { memory.PushByte(value); } - void PushWord(uint16_t value) override { memory.PushWord(value); } - uint8_t PopByte() override { return memory.PopByte(); } - uint16_t PopWord() override { return memory.PopWord(); } - void PushLong(uint32_t value) override { memory.PushLong(value); } - uint32_t PopLong() override { return memory.PopLong(); } void ClearMemory() override { memory.ClearMemory(); } uint8_t operator[](int i) const override { return 0; } uint8_t at(int i) const override { return 0; } diff --git a/src/app/zelda3/dungeon/object_renderer.h b/src/app/zelda3/dungeon/object_renderer.h index fd2f4277..006da19c 100644 --- a/src/app/zelda3/dungeon/object_renderer.h +++ b/src/app/zelda3/dungeon/object_renderer.h @@ -46,8 +46,7 @@ class DungeonObjectRenderer : public SharedROM { gfx::Bitmap* bitmap() { return &bitmap_; } auto memory() { return memory_; } - auto* memory_ptr() { return &memory_; } - auto mutable_memory() { return memory_.data(); } + auto mutable_memory() { return &memory_; } private: struct SubtypeInfo { @@ -85,15 +84,6 @@ class DungeonObjectRenderer : public SharedROM { std::to_string(object_id)); } - // Find the RTS of the subtype routine - while (true) { - uint8_t opcode = memory_.ReadByte(info.routine_ptr); - if (opcode == 0x60) { - break; - } - info.routine_ptr++; - } - return info; } @@ -142,13 +132,21 @@ class DungeonObjectRenderer : public SharedROM { cpu.PB = 0x01; cpu.PC = cpu.ReadWord(0x01 << 16 | info.routine_ptr); + // Push an initial value to the stack we can read later to confirm we are + // done + cpu.PushLong(0x01 << 16 | info.routine_ptr); + int i = 0; while (true) { uint8_t opcode = cpu.ReadByte(cpu.PB << 16 | cpu.PC); cpu.ExecuteInstruction(opcode); cpu.HandleInterrupts(); - if (i > 50) { + if ((i != 0 && (cpu.ReadWord((0x00 << 16 | cpu.SP() + 2)) == + info.routine_ptr) || + 0x8b93 == cpu.PC)) { + std::cout << std::hex << cpu.ReadWord((0x00 << 16 | cpu.SP() + 3)) + << std::endl; break; } i++; @@ -160,9 +158,6 @@ class DungeonObjectRenderer : public SharedROM { // In the underworld, this holds a copy of the entire BG tilemap for // Layer 1 (BG2) in TILEMAPA // Layer 2 (BG1) in TILEMAPB - // - // In the overworld, this holds the entire map16 space, using both blocks as a - // single array TILEMAPA = $7E2000 TILEMAPB = $7E4000 void UpdateObjectBitmap() { tilemap_.reserve(0x2000); for (int i = 0; i < 0x2000; ++i) { @@ -174,12 +169,13 @@ class DungeonObjectRenderer : public SharedROM { for (int tile_index = 0; tile_index < 512; tile_index++) { // Read the tile ID from memory int tile_id = memory_.ReadWord(0x7E2000 + tile_index); + std::cout << "Tile ID: " << std::hex << tile_id << std::endl; int sheet_number = tile_id / 32; - int local_id = tile_id % 32; + std::cout << "Sheet number: " << std::hex << sheet_number << std::endl; - int row = local_id / 8; - int column = local_id % 8; + int row = tile_id / 8; + int column = tile_id % 8; int x = column * 8; int y = row * 8; @@ -190,8 +186,7 @@ class DungeonObjectRenderer : public SharedROM { sheet->Get8x8Tile(tile_id, x, y, tilemap_, tilemap_offset); } - bitmap_.mutable_data() = tilemap_; - bitmap_.Create(256, 256, 8, tilemap_.size()); + bitmap_.Create(256, 256, 8, tilemap_); } std::vector tilemap_; diff --git a/src/app/zelda3/dungeon/room.cc b/src/app/zelda3/dungeon/room.cc index f1e7ee75..cba89cf5 100644 --- a/src/app/zelda3/dungeon/room.cc +++ b/src/app/zelda3/dungeon/room.cc @@ -190,9 +190,9 @@ void Room::LoadRoomFromROM() { hpos++; // Load room objects - // int objectPointer = core::SnesToPc(room_object_pointer); - // int room_address = objectPointer + (room_id_ * 3); - // int objects_location = core::SnesToPc(room_address); + int objectPointer = core::SnesToPc(room_object_pointer); + int room_address = objectPointer + (room_id_ * 3); + int objects_location = core::SnesToPc(room_address); // Load sprites // int spr_ptr = 0x040000 | rooms_sprite_pointer; @@ -423,11 +423,12 @@ void Room::LoadObjects() { void Room::LoadSprites() { auto rom_data = rom()->vector(); - int spritePointer = (0x04 << 16) + (rom_data[rooms_sprite_pointer + 1] << 8) + - (rom_data[rooms_sprite_pointer]); + int sprite_pointer = (0x04 << 16) + + (rom_data[rooms_sprite_pointer + 1] << 8) + + (rom_data[rooms_sprite_pointer]); int sprite_address_snes = - (0x09 << 16) + (rom_data[spritePointer + (room_id_ * 2) + 1] << 8) + - rom_data[spritePointer + (room_id_ * 2)]; + (0x09 << 16) + (rom_data[sprite_pointer + (room_id_ * 2) + 1] << 8) + + rom_data[sprite_pointer + (room_id_ * 2)]; int sprite_address = core::SnesToPc(sprite_address_snes); bool sortsprites = rom_data[sprite_address] == 1;