diff --git a/src/app/editor/dungeon_editor.cc b/src/app/editor/dungeon_editor.cc index b3c1a994..c1b192b2 100644 --- a/src/app/editor/dungeon_editor.cc +++ b/src/app/editor/dungeon_editor.cc @@ -17,6 +17,11 @@ namespace yaze { namespace app { namespace editor { +constexpr ImGuiTableFlags kDungeonObjectTableFlags = + ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | + ImGuiTableFlags_Hideable | ImGuiTableFlags_BordersOuter | + ImGuiTableFlags_BordersV; + using ImGui::TableHeadersRow; using ImGui::TableNextColumn; using ImGui::TableNextRow; @@ -34,9 +39,15 @@ absl::Status DungeonEditor::Update() { } graphics_bin_ = rom()->graphics_bin(); full_palette_ = - rom()->GetPaletteGroup("dungeon_main")[current_palette_group_id_]; + rom()->palette_group("dungeon_main")[current_palette_group_id_]; current_palette_group_ = gfx::CreatePaletteGroupFromLargePalette(full_palette_); + + // Create a vector of pointers to the current block bitmaps + for (int block : rooms_[current_room_id_].blocks()) { + room_gfx_sheets_.emplace_back(&graphics_bin_[block]); + } + is_loaded_ = true; } @@ -54,7 +65,7 @@ absl::Status DungeonEditor::Update() { if (palette_showing_) { ImGui::Begin("Palette Editor", &palette_showing_, 0); current_palette_ = - rom()->GetPaletteGroup("dungeon_main")[current_palette_group_id_]; + rom()->palette_group("dungeon_main")[current_palette_group_id_]; gui::SelectablePalettePipeline(current_palette_id_, refresh_graphics_, current_palette_); ImGui::End(); @@ -311,12 +322,8 @@ void DungeonEditor::DrawTileSelector() { } void DungeonEditor::DrawObjectRenderer() { - if (ImGui::BeginTable( - "DungeonObjectEditorTable", 2, - ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | - ImGuiTableFlags_Hideable | ImGuiTableFlags_BordersOuter | - ImGuiTableFlags_BordersV, - ImVec2(0, 0))) { + if (ImGui::BeginTable("DungeonObjectEditorTable", 2, kDungeonObjectTableFlags, + ImVec2(0, 0))) { TableSetupColumn("Dungeon Objects", ImGuiTableColumnFlags_WidthStretch, ImGui::GetContentRegionAvail().x); TableSetupColumn("Canvas"); @@ -330,7 +337,8 @@ void DungeonEditor::DrawObjectRenderer() { if (ImGui::Selectable(object_name.data(), selected_object == i)) { selected_object = i; current_object_ = i; - object_renderer_.LoadObject(i); + object_renderer_.LoadObject(i, + rooms_[current_room_id_].mutable_blocks()); rom()->RenderBitmap(object_renderer_.bitmap()); object_loaded_ = true; } @@ -347,25 +355,24 @@ void DungeonEditor::DrawObjectRenderer() { object_canvas_.DrawBackground(ImVec2(256 + 1, 0x10 * 0x40 + 1)); object_canvas_.DrawContextMenu(); object_canvas_.DrawTileSelector(32); - // if (object_loaded_) { - // object_canvas_.DrawBitmap(*object_renderer_.bitmap(), 0, 0); - // } + if (object_loaded_) { + object_canvas_.DrawBitmap(*object_renderer_.bitmap(), 0, 0); + } object_canvas_.DrawGrid(32.0f); object_canvas_.DrawOverlay(); ImGui::EndChild(); - ImGui::EndTable(); } - if (object_loaded_) { - ImGui::Begin("Memory Viewer", &object_loaded_, 0); - auto memory = object_renderer_.memory(); - static MemoryEditor mem_edit; - mem_edit.DrawContents((void*)object_renderer_.mutable_memory(), - memory.size()); - ImGui::End(); - } + // if (object_loaded_) { + // ImGui::Begin("Memory Viewer", &object_loaded_, 0); + // auto memory = object_renderer_.memory(); + // static MemoryEditor mem_edit; + // mem_edit.DrawContents((void*)object_renderer_.memory_ptr(), + // memory.size()); + // ImGui::End(); + // } } } // namespace editor diff --git a/src/app/editor/dungeon_editor.h b/src/app/editor/dungeon_editor.h index 4408be6c..cb158303 100644 --- a/src/app/editor/dungeon_editor.h +++ b/src/app/editor/dungeon_editor.h @@ -51,38 +51,6 @@ class DungeonEditor : public Editor, void DrawTileSelector(); void DrawObjectRenderer(); - bool is_loaded_ = false; - bool show_object_render_ = false; - bool object_loaded_ = false; - bool palette_showing_ = false; - - bool refresh_graphics_ = false; - int current_object_ = 0; - uint64_t current_palette_id_ = 0; - uint64_t current_palette_group_id_ = 0; - - uint16_t current_room_id_ = 0; - - gfx::Bitmap room_gfx_bmp_; - gfx::SNESPalette current_palette_; - - gfx::SNESPalette full_palette_; - - gfx::PaletteGroup current_palette_group_; - - gui::Canvas canvas_; - gui::Canvas room_gfx_canvas_; - gui::Canvas object_canvas_; - - gfx::BitmapTable graphics_bin_; - - ImVector active_rooms_; - std::vector rooms_; - std::vector room_graphics_; - zelda3::dungeon::DungeonObjectRenderer object_renderer_; - - PaletteEditor palette_editor_; - enum BackgroundType { kNoBackground, kBackground1, @@ -94,10 +62,36 @@ class DungeonEditor : public Editor, int background_type_ = kNoBackground; int placement_type_ = kNoType; + int current_object_ = 0; - ImGuiTableFlags toolset_table_flags_ = - ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Reorderable | - ImGuiTableFlags_Hideable | ImGuiTableFlags_Resizable; + bool is_loaded_ = false; + bool object_loaded_ = false; + bool palette_showing_ = false; + bool refresh_graphics_ = false; + bool show_object_render_ = false; + + uint16_t current_room_id_ = 0; + uint64_t current_palette_id_ = 0; + uint64_t current_palette_group_id_ = 0; + + ImVector active_rooms_; + + PaletteEditor palette_editor_; + gfx::SNESPalette current_palette_; + gfx::SNESPalette full_palette_; + gfx::PaletteGroup current_palette_group_; + + gui::Canvas canvas_; + gui::Canvas room_gfx_canvas_; + gui::Canvas object_canvas_; + + gfx::Bitmap room_gfx_bmp_; + gfx::BitmapTable graphics_bin_; + + std::vector room_gfx_sheets_; + std::vector rooms_; + std::vector room_graphics_; + zelda3::dungeon::DungeonObjectRenderer object_renderer_; }; } // namespace editor diff --git a/src/app/zelda3/dungeon/object_renderer.h b/src/app/zelda3/dungeon/object_renderer.h new file mode 100644 index 00000000..c7b30c8a --- /dev/null +++ b/src/app/zelda3/dungeon/object_renderer.h @@ -0,0 +1,208 @@ +#include +#include +#include +#include +#include + +#include "app/emu/cpu/cpu.h" +#include "app/emu/memory/memory.h" +#include "app/emu/video/ppu.h" +#include "app/gfx/bitmap.h" +#include "app/gfx/snes_palette.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" +#include "app/zelda3/dungeon/object_names.h" + +namespace yaze { +namespace app { +namespace zelda3 { +namespace dungeon { + +class DungeonObjectRenderer : public SharedROM { + public: + struct PseudoVram { + std::array sheets; + std::vector palettes; + }; + + DungeonObjectRenderer() = default; + + void LoadObject(uint16_t objectId, std::array& sheet_ids) { + vram_.sheets = sheet_ids; + + rom_data_ = rom()->vector(); + // Prepare the CPU and memory environment + memory_.Initialize(rom_data_); + + // Fetch the subtype pointers for the given object ID + auto subtypeInfo = FetchSubtypeInfo(objectId); + + // Configure the object based on the fetched information + ConfigureObject(subtypeInfo); + + // Run the CPU emulation for the object's draw routines + RenderObject(subtypeInfo); + } + + gfx::Bitmap* bitmap() { return &bitmap_; } + auto memory() { return memory_; } + auto* memory_ptr() { return &memory_; } + auto mutable_memory() { return memory_.data(); } + + private: + struct SubtypeInfo { + uint32_t subtypePtr; + uint32_t routinePtr; + }; + + SubtypeInfo FetchSubtypeInfo(uint16_t objectId) { + SubtypeInfo info; + + // Determine the subtype based on objectId + uint8_t subtype = 1; + + // Based on the subtype, fetch the correct pointers + switch (subtype) { + case 1: // Subtype 1 + info.subtypePtr = core::subtype1_tiles + (objectId & 0xFF) * 2; + info.routinePtr = core::subtype1_tiles + 0x200 + (objectId & 0xFF) * 2; + std::cout << "Subtype 1 " << std::hex << info.subtypePtr << std::endl; + std::cout << "Subtype 1 " << std::hex << info.routinePtr << std::endl; + break; + case 2: // Subtype 2 + info.subtypePtr = core::subtype2_tiles + (objectId & 0x7F) * 2; + info.routinePtr = core::subtype2_tiles + 0x80 + (objectId & 0x7F) * 2; + break; + case 3: // Subtype 3 + info.subtypePtr = core::subtype3_tiles + (objectId & 0xFF) * 2; + info.routinePtr = core::subtype3_tiles + 0x100 + (objectId & 0xFF) * 2; + break; + default: + // Handle unknown subtype + throw std::runtime_error("Unknown subtype for object ID: " + + std::to_string(objectId)); + } + + // Find the RTS of the subtype routine + while (true) { + uint8_t opcode = memory_.ReadByte(info.routinePtr); + if (opcode == 0x60) { + break; + } + info.routinePtr++; + } + + return info; + } + + void ConfigureObject(const SubtypeInfo& info) { + cpu.A = 0x03D8; + cpu.X = 0x03D8; + cpu.DB = 0x7E; + // VRAM target destinations + cpu.WriteLong(0xBF, 0x7E2000); + cpu.WriteLong(0xCB, 0x7E2080); + cpu.WriteLong(0xC2, 0x7E2002); + cpu.WriteLong(0xCE, 0x7E2082); + cpu.SetAccumulatorSize(false); + cpu.SetIndexSize(false); + } + + /** + * Example: + * the STA $BF, $CD, $C2, $CE are the location of the object in the room + * $B2 is used for size loop + * so if object size is setted on 07 that draw code will be repeated 7 times + * and since Y is increasing by 4 it makes the object draw from left to right + + RoomDraw_Rightwards2x2_1to15or32: + #_018B89: JSR RoomDraw_GetSize_1to15or32 + .next + #_018B8C: JSR RoomDraw_Rightwards2x2 + #_018B8F: DEC.b $B2 + #_018B91: BNE .next + #_018B93: RTS + + RoomDraw_Rightwards2x2: + #_019895: LDA.w RoomDrawObjectData+0,X + #_019898: STA.b [$BF],Y + #_01989A: LDA.w RoomDrawObjectData+2,X + #_01989D: STA.b [$CB],Y + #_01989F: LDA.w RoomDrawObjectData+4,X + #_0198A2: STA.b [$C2],Y + #_0198A4: LDA.w RoomDrawObjectData+6,X + #_0198A7: STA.b [$CE],Y + #_0198A9: INY #4 + #_0198AD: RTS + */ + + void RenderObject(const SubtypeInfo& info) { + cpu.PB = 0x01; + cpu.PC = cpu.ReadWord(0x01 << 16 | info.routinePtr); + + int i = 0; + while (true) { + uint8_t opcode = cpu.ReadByte(cpu.PB << 16 | cpu.PC); + cpu.ExecuteInstruction(opcode); + cpu.HandleInterrupts(); + + if (i > 50) { + break; + } + i++; + } + + UpdateObjectBitmap(); + } + + // 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) { + tilemap_.push_back(0); + } + int tilemap_offset = 0; + + // Iterate over tilemap in memory to read tile IDs + for (int tile_index = 0; tile_index < 512; tile_index++) { + // Read the tile ID from memory + int tile_id = memory_.ReadWord(0x7E4000 + tile_index); + + int sheet_number = tile_id / 32; + int local_id = tile_id % 32; + + int row = local_id / 8; + int column = local_id % 8; + + int x = column * 8; + int y = row * 8; + + auto sheet = rom()->mutable_graphics_sheet(vram_.sheets[sheet_number]); + + // Copy the tile from VRAM using the read tile_id + sheet->Get8x8Tile(tile_id, x, y, tilemap_, tilemap_offset); + } + + bitmap_.Create(256, 256, 8, tilemap_); + } + + std::vector tilemap_; + uint16_t pc_with_rts_; + std::vector rom_data_; + emu::MemoryImpl memory_; + emu::ClockImpl clock_; + emu::CPU cpu{memory_, clock_}; + emu::Ppu ppu{memory_, clock_}; + gfx::Bitmap bitmap_; + PseudoVram vram_; +}; + +} // namespace dungeon +} // namespace zelda3 +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/zelda3/dungeon/room.cc b/src/app/zelda3/dungeon/room.cc index 1287db63..507154ff 100644 --- a/src/app/zelda3/dungeon/room.cc +++ b/src/app/zelda3/dungeon/room.cc @@ -69,9 +69,6 @@ void Room::LoadRoomGraphics(uchar entrance_blockset) { if (i >= 6 && i <= 6) { // 3-6 if (entrance_blockset != 0xFF) { - // 6 is wrong for the entrance? -NOP need to fix that - // TODO: Find why this is wrong - Thats because of the stairs need to - // find a workaround if (roomGfx[entrance_blockset][i - 3] != 0) { blocks_[i] = roomGfx[entrance_blockset][i - 3]; } @@ -88,25 +85,34 @@ void Room::LoadRoomGraphics(uchar entrance_blockset) { } // 12-16 sprites } +constexpr int kGfxBufferOffset = 92 * 2048; +constexpr int kGfxBufferStride = 512; +constexpr int kGfxBufferAnimatedFrameOffset = 7 * 2048; +constexpr int kGfxBufferAnimatedFrameStride = 512; +constexpr int kGfxBufferRoomOffset = 2048; +constexpr int kGfxBufferRoomSpriteOffset = 512; +constexpr int kGfxBufferRoomSpriteStride = 2048; +constexpr int kGfxBufferRoomSpriteLastLineOffset = 0x88; + void Room::CopyRoomGraphicsToBuffer() { auto gfx_buffer_data = rom()->graphics_buffer(); - // Into "room gfx16" 16 of them - int sheetPos = 0; + // Copy room graphics to buffer + int sheet_pos = 0; for (int i = 0; i < 16; i++) { - int d = 0; - int ioff = blocks_[i] * 2048; - while (d < 2048) { - uchar mapByte = gfx_buffer_data[d + ioff]; + int data = 0; + int block_offset = blocks_[i] * kGfxBufferRoomOffset; + while (data < kGfxBufferRoomOffset) { + uchar map_byte = gfx_buffer_data[data + block_offset]; if (i < 4) { - mapByte += 0x88; - } // Last line of 6, first line of 7 ? + map_byte += kGfxBufferRoomSpriteLastLineOffset; + } - current_gfx16_[d + sheetPos] = mapByte; - d++; + current_gfx16_[data + sheet_pos] = map_byte; + data++; } - sheetPos += 2048; + sheet_pos += kGfxBufferRoomOffset; } LoadAnimatedGraphics(); @@ -243,8 +249,8 @@ void Room::LoadObjects() { short oid = 0; int layer = 0; bool door = false; - bool endRead = false; - while (!endRead) { + bool end_read = false; + while (!end_read) { b1 = rom_data[pos]; b2 = rom_data[pos + 1]; diff --git a/src/app/zelda3/dungeon/room.h b/src/app/zelda3/dungeon/room.h index 6619d98a..8bf13986 100644 --- a/src/app/zelda3/dungeon/room.h +++ b/src/app/zelda3/dungeon/room.h @@ -20,13 +20,9 @@ namespace app { namespace zelda3 { namespace dungeon { -// public static int room_object_layout_pointer = 0x882D; -// public static int room_object_pointer = 0x874C; // Long pointer -// oh eh -// in bank 01 ? lol -// those are pointer of pointers +// room_object_layout_pointer 0x882D +// room_object_pointer 0x874C // 0x882D -> readlong() -> 2FEF04 (04EF2F -> toPC->026F2F) -> -// that's all the layout "room" pointers // 47EF04 ; layout00 ptr // AFEF04 ; layout01 ptr @@ -40,6 +36,9 @@ namespace dungeon { // the object array is terminated by a 0xFFFF there's no layers // in normal room when you encounter a 0xFFFF it goes to the next layer +constexpr int room_object_layout_pointer = 0x882D; +constexpr int room_object_pointer = 0x874C; // Long pointer + constexpr int entrance_gfx_group = 0x5D97; constexpr int dungeons_main_bg_palette_pointers = 0xDEC4B; // JP Same constexpr int dungeons_palettes = 0xDD734; @@ -48,8 +47,6 @@ constexpr int rooms_sprite_pointer = 0x4C298; // JP Same //2byte bank 09D62E constexpr int kRoomHeaderPointer = 0xB5DD; // LONG constexpr int kRoomHeaderPointerBank = 0xB5E7; // JP Same constexpr int gfx_groups_pointer = 0x6237; -constexpr int room_object_layout_pointer = 0x882D; -constexpr int room_object_pointer = 0x874C; // Long pointer constexpr int chests_length_pointer = 0xEBF6; constexpr int chests_data_pointer1 = 0xEBFB; @@ -138,6 +135,7 @@ class Room : public SharedROM { void LoadRoomFromROM(); auto blocks() const { return blocks_; } + auto& mutable_blocks() { return blocks_; } RoomObject AddObject(short oid, uint8_t x, uint8_t y, uint8_t size, uint8_t layer) { @@ -160,14 +158,16 @@ class Room : public SharedROM { std::vector current_gfx16_; private: + bool light = false; bool is_loaded_ = false; - - int animated_frame = 0; + bool IsDark = false; + bool floor = false; int room_id_ = 0; + int animated_frame = 0; - bool light; - Background2 bg2; + uchar Tag1; + uchar Tag2; uint8_t staircase_plane[4]; uint8_t staircase_rooms[4]; @@ -179,6 +179,7 @@ class Room : public SharedROM { uint8_t Floor1Graphics; uint8_t Floor2Graphics; uint8_t Layer2Mode; + std::array blocks_; std::array ChestList; @@ -186,19 +187,13 @@ class Room : public SharedROM { std::vector sprites_; std::vector staircaseRooms; + Background2 bg2; DungeonDestination Pits; DungeonDestination Stair1; DungeonDestination Stair2; DungeonDestination Stair3; DungeonDestination Stair4; - uchar Tag1; - uchar Tag2; - bool IsDark; - - bool floor; - - // std::vector chest_list; std::vector chests_in_room; std::vector tilesObjects; }; diff --git a/src/app/zelda3/dungeon/room_object.h b/src/app/zelda3/dungeon/room_object.h index 308d6d0e..12ca9c25 100644 --- a/src/app/zelda3/dungeon/room_object.h +++ b/src/app/zelda3/dungeon/room_object.h @@ -14,188 +14,17 @@ #include "app/gfx/snes_tile.h" #include "app/rom.h" #include "app/zelda3/dungeon/object_names.h" +#include "app/zelda3/dungeon/object_renderer.h" namespace yaze { namespace app { namespace zelda3 { namespace dungeon { -class DungeonObjectRenderer : public SharedROM { - public: - struct PseudoVram { - std::vector sheets; - // TODO: Initialize with mock VRAM data - }; - - DungeonObjectRenderer() { - // TODO: Constructor implementation - } - - void LoadObject(uint16_t objectId) { - rom_data_ = rom()->vector(); - // Prepare the CPU and memory environment - memory_.Initialize(rom_data_); - - // Fetch the subtype pointers for the given object ID - auto subtypeInfo = FetchSubtypeInfo(objectId); - - // Configure the object based on the fetched information - ConfigureObject(subtypeInfo); - - // Run the CPU emulation for the object's draw routines - RenderObject(subtypeInfo); - } - - gfx::Bitmap* bitmap() { return &bitmap_; } - auto memory() { return memory_; } - auto mutable_memory() { return memory_.data(); } - - private: - struct SubtypeInfo { - uint32_t subtypePtr; - uint32_t routinePtr; - }; - - SubtypeInfo FetchSubtypeInfo(uint16_t objectId) { - SubtypeInfo info; - - // Determine the subtype based on objectId - // Assuming subtype is determined by some bits in objectId; modify as needed - uint8_t subtype = 1; // Example: top 8 bits - - // Based on the subtype, fetch the correct pointers - switch (subtype) { - case 1: // Subtype 1 - info.subtypePtr = core::subtype1_tiles + (objectId & 0xFF) * 2; - info.routinePtr = core::subtype1_tiles + 0x200 + (objectId & 0xFF) * 2; - std::cout << "Subtype 1 " << std::hex << info.subtypePtr << std::endl; - std::cout << "Subtype 1 " << std::hex << info.routinePtr << std::endl; - break; - case 2: // Subtype 2 - info.subtypePtr = core::subtype2_tiles + (objectId & 0x7F) * 2; - info.routinePtr = core::subtype2_tiles + 0x80 + (objectId & 0x7F) * 2; - break; - case 3: // Subtype 3 - info.subtypePtr = core::subtype3_tiles + (objectId & 0xFF) * 2; - info.routinePtr = core::subtype3_tiles + 0x100 + (objectId & 0xFF) * 2; - break; - default: - // Handle unknown subtype - throw std::runtime_error("Unknown subtype for object ID: " + - std::to_string(objectId)); - } - - // Convert pointers from ROM-relative to absolute (if necessary) - // info.subtypePtr = ConvertToAbsolutePtr(info.subtypePtr); - // info.routinePtr = ConvertToAbsolutePtr(info.routinePtr); - - return info; - } - - void ConfigureObject(const SubtypeInfo& info) { - cpu.A = 0x03D8; - cpu.X = 0x03D8; - cpu.DB = 0x7E; - // VRAM target destinations - cpu.WriteLong(0xBF, 0x7E2000); - cpu.WriteLong(0xCB, 0x7E2080); - cpu.WriteLong(0xC2, 0x7E2002); - cpu.WriteLong(0xCE, 0x7E2082); - cpu.SetAccumulatorSize(false); - cpu.SetIndexSize(false); - } - - /** - * Example: - * the STA $BF, $CD, $C2, $CE are the location of the object in the room - * $B2 is used for size loop - * so if object size is setted on 07 that draw code will be repeated 7 times - * and since Y is increasing by 4 it makes the object draw from left to right - - RoomDraw_Rightwards2x2_1to15or32: - #_018B89: JSR RoomDraw_GetSize_1to15or32 - - .next - #_018B8C: JSR RoomDraw_Rightwards2x2 - - #_018B8F: DEC.b $B2 - #_018B91: BNE .next - - #_018B93: RTS - - RoomDraw_Rightwards2x2: - #_019895: LDA.w RoomDrawObjectData+0,X - #_019898: STA.b [$BF],Y - - #_01989A: LDA.w RoomDrawObjectData+2,X - #_01989D: STA.b [$CB],Y - - #_01989F: LDA.w RoomDrawObjectData+4,X - #_0198A2: STA.b [$C2],Y - - #_0198A4: LDA.w RoomDrawObjectData+6,X - #_0198A7: STA.b [$CE],Y - - #_0198A9: INY - #_0198AA: INY - #_0198AB: INY - #_0198AC: INY - - #_0198AD: RTS - * - */ - - void RenderObject(const SubtypeInfo& info) { - cpu.PB = 0x01; - cpu.PC = cpu.ReadWord(0x01 << 16 | info.routinePtr); - - int i = 0; - while (true) { - uint8_t opcode = cpu.ReadByte(cpu.PB << 16 | cpu.PC); - cpu.ExecuteInstruction(opcode); - cpu.HandleInterrupts(); - - if (i > 50) { - break; - } - i++; - - // UpdateObjectBitmap(); - } - } - - void UpdateObjectBitmap() { - // Object draw data - uint8_t room_object_draw_data0 = memory_.ReadByte(0x7E00BF); - uint8_t room_object_draw_data1 = memory_.ReadByte(0x7E00CB); - uint8_t room_object_draw_data2 = memory_.ReadByte(0x7E00C2); - uint8_t room_object_draw_data3 = memory_.ReadByte(0x7E00CE); - - // Used with Y to index the room object draw data - uint8_t size_loop = memory_.ReadByte(0x7E00B2); - - // Update the bitmap with this data by copying the tiles from vram. - - std::cout << "Object draw data: " << std::hex << (int)room_object_draw_data0 - << " " << (int)room_object_draw_data1 << " " - << (int)room_object_draw_data2 << " " - << (int)room_object_draw_data3 << std::endl; - std::cout << "Size loop: " << std::hex << (int)size_loop << std::endl; - } - - std::vector rom_data_; - emu::MemoryImpl memory_; - emu::ClockImpl clock_; - emu::CPU cpu{memory_, clock_}; - emu::Ppu ppu{memory_, clock_}; - gfx::Bitmap bitmap_; - PseudoVram vram_; -}; +struct Tile {}; enum class SpecialObjectType { Chest, BigChest, InterroomStairs }; -struct Tile {}; - enum Background2 { Off, Parallax, @@ -229,12 +58,6 @@ enum ObjectOption { Stairs = 32 }; -struct LayerType { - LayerType(uint8_t t) : type(t) {} - - uint8_t type; -}; - class RoomObject : public SharedROM { public: enum LayerType { BG1 = 0, BG2 = 1, BG3 = 2 }; @@ -268,7 +91,6 @@ class RoomObject : public SharedROM { GetSizeSized(); UpdateSize(); size_ = previous_size_; - // collision_point_.clear(); } void GetBaseSize() { @@ -281,8 +103,6 @@ class RoomObject : public SharedROM { size_width_ = width_ - base_width_; } - // virtual void Draw() { collision_point_.clear(); } - void UpdateSize() { width_ = 8; height_ = 8; @@ -291,8 +111,8 @@ class RoomObject : public SharedROM { void AddTiles(int nbr, int pos) { auto rom_data = rom()->data(); for (int i = 0; i < nbr; i++) { - // tiles.push_back( - // gfx::Tile16(rom_data[pos + (i * 2)], rom_data[pos + (i * 2) + 1])); + ASSIGN_OR_LOG_ERROR(auto tile, rom()->ReadTile16(pos + (i * 2))); + tiles_.push_back(tile); } } @@ -302,43 +122,42 @@ class RoomObject : public SharedROM { ushort tile_under = 0xFFFF); protected: - int16_t id_; + bool all_bgs_ = false; + bool lit_ = false; + bool deleted_ = false; + bool show_rectangle_ = false; + bool diagonal_fix_ = false; + bool selected_ = false; + int16_t id_; uint8_t x_; uint8_t y_; uint8_t size_; - - LayerType layer_; - - std::vector preview_object_data_; - - bool all_bgs_ = false; - bool lit_ = false; - std::vector tiles_; - int tile_index_ = 0; - std::string name_; uint8_t nx_; uint8_t ny_; uint8_t ox_; uint8_t oy_; + uint8_t z_ = 0; + uint8_t previous_size_ = 0; + int width_; int height_; int base_width_; int base_height_; int size_width_; int size_height_; - ObjectOption options_ = ObjectOption::Nothing; + int tile_index_ = 0; int offset_x_ = 0; int offset_y_ = 0; - bool diagonal_fix_ = false; - bool selected_ = false; int preview_id_ = 0; - uint8_t previous_size_ = 0; - bool show_rectangle_ = false; - // std::vector collision_point_; int unique_id_ = 0; - uint8_t z_ = 0; - bool deleted_ = false; + + std::string name_; + + LayerType layer_; + ObjectOption options_ = ObjectOption::Nothing; + std::vector tiles_; + std::vector preview_object_data_; }; class Subtype1 : public RoomObject {