From e93ff212af76c79216ffa345ed5d21d8f3d3a75e Mon Sep 17 00:00:00 2001 From: scawful Date: Wed, 22 Nov 2023 00:49:55 -0500 Subject: [PATCH] Dungeon graphics loaded per room --- src/app/editor/dungeon_editor.cc | 78 ++++---- src/app/gfx/bitmap.h | 11 +- src/app/zelda3/dungeon/room.cc | 27 +-- src/app/zelda3/dungeon/room.h | 16 +- src/app/zelda3/dungeon/room_object.cc | 50 +++--- src/app/zelda3/dungeon/room_object.h | 246 +++++++++++--------------- 6 files changed, 199 insertions(+), 229 deletions(-) diff --git a/src/app/editor/dungeon_editor.cc b/src/app/editor/dungeon_editor.cc index a5d9d085..06f09614 100644 --- a/src/app/editor/dungeon_editor.cc +++ b/src/app/editor/dungeon_editor.cc @@ -26,17 +26,9 @@ absl::Status DungeonEditor::Update() { for (int i = 0; i < 0x100; i++) { rooms_.emplace_back(zelda3::dungeon::Room(i)); rooms_[i].LoadHeader(); + rooms_[i].LoadRoomFromROM(); if (flags()->kDrawDungeonRoomGraphics) { rooms_[i].LoadRoomGraphics(); - - auto blocks = rooms_[i].blocks(); - room_graphics_.emplace_back(); - int current_sheet = 0; - for (auto& block : blocks) { - room_graphics_[i].CopyBitmap(rom()->bitmap_manager().GetBitmap(block), - current_sheet); - current_sheet += 1; - } } } is_loaded_ = true; @@ -68,7 +60,8 @@ absl::Status DungeonEditor::Update() { void DungeonEditor::DrawRoomSelector() { if (rom()->isLoaded()) { - ImGui::InputInt("Room ID", (int*)¤t_room_id_, 1, 1); + gui::InputHexWord("Room ID", ¤t_room_id_); + // gui::InputHexByte("Palette ID", &rooms_[current_room_id_].palette); if (ImGuiID child_id = ImGui::GetID((void*)(intptr_t)9); ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true, @@ -90,8 +83,6 @@ void DungeonEditor::DrawRoomSelector() { void DungeonEditor::DrawDungeonTabView() { static int next_tab_id = 0; - // Using ImGui Custom Tabs show each individual room the user selects from the - // Buttons above to open a canvas for each individual room. if (ImGui::BeginTabBar("MyTabBar", kDungeonTabBarFlags)) { // TODO: Manage the room that is being added to the tab bar. if (ImGui::TabItemButton("##tabitem", kDungeonTabFlags)) { @@ -154,19 +145,19 @@ void DungeonEditor::DrawDungeonCanvas(int room_id) { void DungeonEditor::DrawToolset() { if (ImGui::BeginTable("DWToolset", 12, ImGuiTableFlags_SizingFixedFit, ImVec2(0, 0))) { - ImGui::TableSetupColumn("#undoTool"); - ImGui::TableSetupColumn("#redoTool"); - ImGui::TableSetupColumn("#separator"); - ImGui::TableSetupColumn("#anyTool"); + TableSetupColumn("#undoTool"); + TableSetupColumn("#redoTool"); + TableSetupColumn("#separator"); + TableSetupColumn("#anyTool"); - ImGui::TableSetupColumn("#bg1Tool"); - ImGui::TableSetupColumn("#bg2Tool"); - ImGui::TableSetupColumn("#bg3Tool"); - ImGui::TableSetupColumn("#separator"); - ImGui::TableSetupColumn("#spriteTool"); - ImGui::TableSetupColumn("#itemTool"); - ImGui::TableSetupColumn("#doorTool"); - ImGui::TableSetupColumn("#blockTool"); + TableSetupColumn("#bg1Tool"); + TableSetupColumn("#bg2Tool"); + TableSetupColumn("#bg3Tool"); + TableSetupColumn("#separator"); + TableSetupColumn("#spriteTool"); + TableSetupColumn("#itemTool"); + TableSetupColumn("#doorTool"); + TableSetupColumn("#blockTool"); ImGui::TableNextColumn(); if (ImGui::Button(ICON_MD_UNDO)) { @@ -245,14 +236,30 @@ void DungeonEditor::DrawToolset() { } void DungeonEditor::DrawRoomGraphics() { - // room_gfx_canvas_.DrawBackground(ImVec2(256 + 1, 0x10 * 0x40 + 1)); - // room_gfx_canvas_.DrawContextMenu(); - // room_gfx_canvas_.DrawTileSelector(32); - // room_gfx_canvas_.DrawBitmap(room_gfx_bmp_, 2, is_loaded_); - // room_gfx_canvas_.DrawGrid(32.0f); - // room_gfx_canvas_.DrawOverlay(); - core::GraphicsManagerCanvasPipeline(256, 0x10 * 0x40, 32, 0x10, 0, is_loaded_, - room_graphics_[current_room_id_]); + const auto height = 0x40; + room_gfx_canvas_.DrawBackground(ImVec2(256 + 1, 0x10 * 0x40 + 1)); + room_gfx_canvas_.DrawContextMenu(); + room_gfx_canvas_.DrawTileSelector(32); + if (is_loaded_) { + auto blocks = rooms_[current_room_id_].blocks(); + int current_block = 0; + for (int block : blocks) { + auto bitmap = rom()->graphics_bin()[block]; + int offset = height * (current_block + 1); + int top_left_y = room_gfx_canvas_.GetZeroPoint().y + 2; + if (current_block >= 1) { + top_left_y = room_gfx_canvas_.GetZeroPoint().y + height * current_block; + } + room_gfx_canvas_.GetDrawList()->AddImage( + (void*)bitmap.texture(), + ImVec2(room_gfx_canvas_.GetZeroPoint().x + 2, top_left_y), + ImVec2(room_gfx_canvas_.GetZeroPoint().x + 0x100, + room_gfx_canvas_.GetZeroPoint().y + offset)); + current_block += 1; + } + } + room_gfx_canvas_.DrawGrid(32.0f); + room_gfx_canvas_.DrawOverlay(); } void DungeonEditor::DrawTileSelector() { @@ -282,10 +289,9 @@ void DungeonEditor::DrawObjectRenderer() { ImGuiTableFlags_Hideable | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV, ImVec2(0, 0))) { - ImGui::TableSetupColumn("Dungeon Objects", - ImGuiTableColumnFlags_WidthStretch, - ImGui::GetContentRegionAvail().x); - ImGui::TableSetupColumn("Canvas"); + TableSetupColumn("Dungeon Objects", ImGuiTableColumnFlags_WidthStretch, + ImGui::GetContentRegionAvail().x); + TableSetupColumn("Canvas"); ImGui::TableNextColumn(); ImGui::BeginChild("DungeonObjectButtons", ImVec2(0, 0), true); diff --git a/src/app/gfx/bitmap.h b/src/app/gfx/bitmap.h index 877e0c8b..20579657 100644 --- a/src/app/gfx/bitmap.h +++ b/src/app/gfx/bitmap.h @@ -150,12 +150,11 @@ class BitmapManager { return bitmap; } - std::shared_ptr CopyBitmap(std::shared_ptr bitmap, - int id) { - auto copy = std::make_shared(bitmap->width(), bitmap->height(), - bitmap->depth(), bitmap->data()); - bitmap_cache_[id] = copy; - return copy; + std::shared_ptr CopyBitmap(const gfx::Bitmap &bitmap, int id) { + auto new_bitmap = std::make_shared( + bitmap.width(), bitmap.height(), bitmap.depth(), bitmap.data()); + bitmap_cache_[id] = new_bitmap; + return new_bitmap; } std::shared_ptr operator[](int id) { diff --git a/src/app/zelda3/dungeon/room.cc b/src/app/zelda3/dungeon/room.cc index 0134efb7..7c52cf34 100644 --- a/src/app/zelda3/dungeon/room.cc +++ b/src/app/zelda3/dungeon/room.cc @@ -91,9 +91,9 @@ void Room::LoadHeader() { auto header_location = core::SnesToPc(address); - // bg2 = (Background2)((rom()->data()[header_location] >> 5) & 0x07); + bg2 = (Background2)((rom()->data()[header_location] >> 5) & 0x07); // collision = (CollisionKey)((rom()->data()[header_location] >> 2) & 0x07); - // light = ((rom()->data()[header_location]) & 0x01) == 1; + light = ((rom()->data()[header_location]) & 0x01) == 1; if (light) { bg2 = Background2::DarkRoom; @@ -137,13 +137,13 @@ void Room::LoadHeader() { } void Room::LoadRoomGraphics(uchar entrance_blockset) { - auto mainGfx = rom()->main_blockset_ids; - auto roomGfx = rom()->room_blockset_ids; - auto spriteGfx = rom()->spriteset_ids; + const auto& mainGfx = rom()->main_blockset_ids; + const auto& roomGfx = rom()->room_blockset_ids; + const auto& spriteGfx = rom()->spriteset_ids; current_gfx16_.reserve(0x4000); for (int i = 0; i < 8; i++) { - blocks_[i] = mainGfx[BackgroundTileset][i]; + blocks_[i] = mainGfx[blockset][i]; if (i >= 6 && i <= 6) { // 3-6 if (entrance_blockset != 0xFF) { @@ -162,7 +162,7 @@ void Room::LoadRoomGraphics(uchar entrance_blockset) { blocks_[10] = 115 + 6; blocks_[11] = 115 + 7; for (int i = 0; i < 4; i++) { - blocks_[12 + i] = (uchar)(spriteGfx[SpriteTileset + 64][i] + 115); + blocks_[12 + i] = (uchar)(spriteGfx[spriteset + 64][i] + 115); } // 12-16 sprites } @@ -427,12 +427,15 @@ void Room::LoadRoomFromROM() { message_id_ = messages_id_dungeon + (room_id_ * 2); - int hpos = core::SnesToPc((rom_data[kRoomHeaderPointerBank] << 16) | - header_pointer + (room_id_ * 2)); - hpos++; - uchar b = rom_data[hpos]; + int address = (rom()->data()[kRoomHeaderPointerBank] << 16) + + (rom()->data()[(header_pointer + 1) + (room_id_ * 2)] << 8) + + rom()->data()[(header_pointer) + (room_id_ * 2)]; - Layer2Mode = (uchar)(b >> 5); + int hpos = core::SnesToPc(address); + hpos++; + uint8_t b = rom_data[hpos]; + + Layer2Mode = (b >> 5); // TODO(@scawful): Make LayerMerging object. // LayerMerging = LayerMergeType.ListOf[(b & 0x0C) >> 2]; diff --git a/src/app/zelda3/dungeon/room.h b/src/app/zelda3/dungeon/room.h index 4de18158..55d8f16c 100644 --- a/src/app/zelda3/dungeon/room.h +++ b/src/app/zelda3/dungeon/room.h @@ -160,14 +160,14 @@ class Room : public SharedROM { uint8_t staircase_plane[4]; uint8_t staircase_rooms[4]; - uchar BackgroundTileset; - uchar SpriteTileset; - uchar Layer2Behavior; - uchar Palette; - uchar Floor1Graphics; - uchar Floor2Graphics; - uchar Layer2Mode; - std::array blocks_; + uint8_t BackgroundTileset; + uint8_t SpriteTileset; + uint8_t Layer2Behavior; + uint8_t Palette; + uint8_t Floor1Graphics; + uint8_t Floor2Graphics; + uint8_t Layer2Mode; + std::array blocks_; std::array ChestList; std::vector sprites_; diff --git a/src/app/zelda3/dungeon/room_object.cc b/src/app/zelda3/dungeon/room_object.cc index 52035e4c..ed68a02f 100644 --- a/src/app/zelda3/dungeon/room_object.cc +++ b/src/app/zelda3/dungeon/room_object.cc @@ -11,14 +11,14 @@ void RoomObject::DrawTile(Tile t, int xx, int yy, std::vector& tiles_bg2_buffer, ushort tileUnder) { bool preview = false; - if (width < xx + 8) { - width = xx + 8; + if (width_ < xx + 8) { + width_ = xx + 8; } - if (height < yy + 8) { - height = yy + 8; + if (height_ < yy + 8) { + height_ = yy + 8; } if (preview) { - if (xx < 57 && yy < 57 && xx >= 0 && yy >= 0) { + if (xx < 0x39 && yy < 0x39 && xx >= 0 && yy >= 0) { gfx::TileInfo ti; // t.GetTileInfo(); for (auto yl = 0; yl < 8; yl++) { for (auto xl = 0; xl < 4; xl++) { @@ -36,47 +36,51 @@ void RoomObject::DrawTile(Tile t, int xx, int yy, // Formula information to get tile index position in the array. //((ID / nbrofXtiles) * (imgwidth/2) + (ID - ((ID/16)*16) )) - int tx = - ((ti.id_ / 16) * 512) + ((ti.id_ - ((ti.id_ / 16) * 16)) * 4); - auto pixel = current_gfx16[tx + (yl * 64) + xl]; + int tx = ((ti.id_ / 0x10) * 0x200) + + ((ti.id_ - ((ti.id_ / 0x10) * 0x10)) * 4); + auto pixel = current_gfx16[tx + (yl * 0x40) + xl]; // nx,ny = object position, xx,yy = tile position, xl,yl = pixel // position int index = - ((xx / 8) * 8) + ((yy / 8) * 512) + ((mx * 2) + (my * 64)); + ((xx / 8) * 8) + ((yy / 8) * 0x200) + ((mx * 2) + (my * 0x40)); preview_object_data_[index + r ^ 1] = - (uint8_t)((pixel & 0x0F) + ti.palette_ * 16); + (uint8_t)((pixel & 0x0F) + ti.palette_ * 0x10); preview_object_data_[index + r] = - (uint8_t)(((pixel >> 4) & 0x0F) + ti.palette_ * 16); + (uint8_t)(((pixel >> 4) & 0x0F) + ti.palette_ * 0x10); } } } } else { - if (((xx / 8) + nx + offsetX) + ((ny + offsetY + (yy / 8)) * 64) < 4096 && - ((xx / 8) + nx + offsetX) + ((ny + offsetY + (yy / 8)) * 64) >= 0) { + if (((xx / 8) + nx_ + offset_x_) + ((ny_ + offset_y_ + (yy / 8)) * 0x40) < + 0x1000 && + ((xx / 8) + nx_ + offset_x_) + ((ny_ + offset_y_ + (yy / 8)) * 0x40) >= + 0) { ushort td = 0; // gfx::GetTilesInfo(); // TODO t.GetTileInfo() // collisionPoint.Add( // new Point(xx + ((nx + offsetX) * 8), yy + ((ny + +offsetY) * 8))); - if (Layer == 0 || (uint8_t)Layer == 2 || allBgs) { - if (tileUnder == tiles_bg1_buffer[((xx / 8) + offsetX + nx) + - ((ny + offsetY + (yy / 8)) * 64)]) { + if (layer_ == 0 || (uint8_t)layer_ == 2 || all_bgs_) { + if (tileUnder == + tiles_bg1_buffer[((xx / 8) + offset_x_ + nx_) + + ((ny_ + offset_y_ + (yy / 8)) * 0x40)]) { return; } - tiles_bg1_buffer[((xx / 8) + offsetX + nx) + - ((ny + offsetY + (yy / 8)) * 64)] = td; + tiles_bg1_buffer[((xx / 8) + offset_x_ + nx_) + + ((ny_ + offset_y_ + (yy / 8)) * 0x40)] = td; } - if ((uint8_t)Layer == 1 || allBgs) { - if (tileUnder == tiles_bg2_buffer[((xx / 8) + nx + offsetX) + - ((ny + offsetY + (yy / 8)) * 64)]) { + if ((uint8_t)layer_ == 1 || all_bgs_) { + if (tileUnder == + tiles_bg2_buffer[((xx / 8) + nx_ + offset_x_) + + ((ny_ + offset_y_ + (yy / 8)) * 0x40)]) { return; } - tiles_bg2_buffer[((xx / 8) + nx) + offsetX + - ((ny + offsetY + (yy / 8)) * 64)] = td; + tiles_bg2_buffer[((xx / 8) + nx_ + offset_x_) + + ((ny_ + offset_y_ + (yy / 8)) * 0x40)] = td; } } } diff --git a/src/app/zelda3/dungeon/room_object.h b/src/app/zelda3/dungeon/room_object.h index 7d2a1f47..662b0771 100644 --- a/src/app/zelda3/dungeon/room_object.h +++ b/src/app/zelda3/dungeon/room_object.h @@ -87,61 +87,30 @@ class DungeonObjectRenderer : public SharedROM { void ConfigureObject(const SubtypeInfo& info) { // TODO: Use the information in info to set up the object's initial state - // This may include setting CPU registers, loading specific tiles into VRAM, - // etc. } void RenderObject(const SubtypeInfo& info) { - // Assuming that the routine pointer and other necessary setup is done in - // ConfigureObject Start CPU at the routine's entry point - cpu.PC = - info.routinePtr; // info should be a member or passed as a parameter - cpu.PB = 0x01; // Set the program bank; adjust based on your memory mapping + cpu.PC = info.routinePtr; + cpu.PB = 0x01; - // Run the CPU emulation loop while (true) { - // Fetch the next opcode uint8_t opcode = cpu.FetchByte(); - - // Execute the fetched instruction cpu.ExecuteInstruction(opcode); - - // Handle any interrupts, if necessary cpu.HandleInterrupts(); - // Check if the end of the routine is reached (typically RTS instruction) + // Check if the end of the routine is reached if (opcode == 0x60) { // RTS opcode break; } - // Additional checks can be added here, e.g., maximum cycles or - // instructions - - // Update the PPU state if necessary - // ppu.Update(); - - // After PPU update, reflect any changes in the Bitmap(s) - // UpdateBitmapFromPPU(); + UpdateObjectBitmap(); } - - // Post-rendering operations (if any) - // PostRenderOperations(); } - // Helper function to update Bitmap from PPU state - void UpdateBitmapFromPPU() { - // TODO: Implement logic to transfer PPU state changes to the Bitmap - // This involves reading the tile data and other graphics info from PPU - // and rendering it to the Bitmap object + void UpdateObjectBitmap() { + // TODO: Implement logic to transfer object draw data to the Bitmap } - // Optional: Handle any operations after rendering - void PostRenderOperations() { - // TODO: Implement any cleanup or additional processing needed after - // rendering - } - - // Members std::vector rom_data_; emu::MemoryImpl memory_; emu::ClockImpl clock_; @@ -151,43 +120,6 @@ class DungeonObjectRenderer : public SharedROM { PseudoVram vram_; }; -// void CreateVramFromRoomBlockset() { -// // auto bitmap_manager = rom()->bitmap_manager(); -// // uint16_t room_id = 0; -// // auto room_blockset = rom()->room_blockset_ids[room_id]; - -// // for (const auto blockset_id : room_blockset) { -// // auto blockset = bitmap_manager[(uint16_t)blockset_id]; -// // vram_.sheets.push_back(*blockset.get()); -// // } -// } - -// int i = 0; -// for (const auto routine_ptr : routine_ptrs) { -// cpu.PC = routine_ptr - 2; -// cpu.PB = 0x01; - -// auto cycles_to_run = clock_.GetCycleCount(); - -// while (true) { -// auto opcode = cpu.FetchByte(); -// // Fetch and execute an instruction -// cpu.ExecuteInstruction(opcode); - -// // Handle any interrupts, if necessary -// cpu.HandleInterrupts(); - -// // Check if the instruction is RTS -// if (opcode == 0x60) { -// break; -// } -// i++; -// if (i > 50) { -// break; -// } -// } -// } - enum class SpecialObjectType { Chest, BigChest, InterroomStairs }; struct Tile {}; @@ -236,55 +168,55 @@ class RoomObject : public SharedROM { enum LayerType { BG1 = 0, BG2 = 1, BG3 = 2 }; RoomObject(int16_t id, uint8_t x, uint8_t y, uint8_t size, uint8_t layer = 0) - : id(id), + : id_(id), x_(x), y_(y), size_(size), - Layer(static_cast(layer)), - nx(x), - ny(y), - ox(x), - oy(y), - width(16), - height(16), - uniqueID(0) {} + layer_(static_cast(layer)), + nx_(x), + ny_(y), + ox_(x), + oy_(y), + width_(16), + height_(16), + unique_id_(0) {} virtual void Draw() { // ... Draw function implementation here } - void getObjectSize() { - previousSize = size_; + void GetObjectSize() { + previous_size_ = size_; size_ = 1; // Draw(); - getBaseSize(); + GetBaseSize(); UpdateSize(); size_ = 2; // Draw(); - getSizeSized(); + GetSizeSized(); UpdateSize(); - size_ = previousSize; - // collisionPoint.clear(); + size_ = previous_size_; + // collision_point_.clear(); } - void getBaseSize() { - basewidth = width; - baseheight = height; + void GetBaseSize() { + base_width_ = width_; + base_height_ = height_; } - void getSizeSized() { - sizeheight = height - baseheight; - sizewidth = width - basewidth; + void GetSizeSized() { + size_height_ = height_ - base_height_; + size_width_ = width_ - base_width_; } - // virtual void Draw() { collisionPoint.clear(); } + // virtual void Draw() { collision_point_.clear(); } void UpdateSize() { - width = 8; - height = 8; + width_ = 8; + height_ = 8; } - void addTiles(int nbr, int pos) { + void AddTiles(int nbr, int pos) { auto rom_data = rom()->data(); for (int i = 0; i < nbr; i++) { // tiles.push_back( @@ -295,46 +227,46 @@ class RoomObject : public SharedROM { void DrawTile(Tile t, int xx, int yy, std::vector& current_gfx16, std::vector& tiles_bg1_buffer, std::vector& tiles_bg2_buffer, - ushort tileUnder = 0xFFFF); + ushort tile_under = 0xFFFF); protected: - int16_t id; + int16_t id_; uint8_t x_; uint8_t y_; uint8_t size_; - LayerType Layer; + LayerType layer_; std::vector preview_object_data_; - bool allBgs = false; - bool lit = false; - std::vector tiles; - int tileIndex = 0; - std::string name; - uint8_t nx; - uint8_t ny; - uint8_t ox; - uint8_t oy; - int width; - int height; - int basewidth; - int baseheight; - int sizewidth; - int sizeheight; - ObjectOption options = ObjectOption::Nothing; - int offsetX = 0; - int offsetY = 0; - bool diagonalFix = false; - bool selected = false; - int previewId = 0; - uint8_t previousSize = 0; - bool showRectangle = false; - // std::vector collisionPoint; - int uniqueID = 0; - uint8_t z = 0; - bool deleted = false; + 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_; + int width_; + int height_; + int base_width_; + int base_height_; + int size_width_; + int size_height_; + ObjectOption options_ = ObjectOption::Nothing; + 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; }; class Subtype1 : public RoomObject { @@ -355,7 +287,7 @@ class Subtype1 : public RoomObject { static_cast( (rom_data[core::subtype1_tiles + ((id & 0xFF) * 2) + 1] << 8) + rom_data[core::subtype1_tiles + ((id & 0xFF) * 2)]); - addTiles(tile_count_, pos); + AddTiles(tile_count_, pos); sort = (Sorting)(Sorting::Horizontal | Sorting::Wall); } @@ -368,33 +300,59 @@ class Subtype1 : public RoomObject { } }; -class Subtype2_Multiple : public RoomObject { +class Subtype2 : public RoomObject { public: - int tx = 0; - int ty = 0; std::vector tiles; std::string name; bool allBgs; Sorting sort; - Subtype2_Multiple(int16_t id, uint8_t x, uint8_t y, uint8_t size, - uint8_t layer) + Subtype2(int16_t id, uint8_t x, uint8_t y, uint8_t size, uint8_t layer) : RoomObject(id, x, y, size, layer) { - // ... Constructor implementation here + auto rom_data = rom()->data(); + name = Type2RoomObjectNames[id & 0x7F]; + int pos = + core::tile_address + + static_cast( + (rom_data[core::subtype2_tiles + ((id & 0x7F) * 2) + 1] << 8) + + rom_data[core::subtype2_tiles + ((id & 0x7F) * 2)]); + AddTiles(8, pos); + sort = (Sorting)(Sorting::Horizontal | Sorting::Wall); } void Draw() override { - // ... Draw function implementation here + for (int i = 0; i < 8; i++) { + // DrawTile(tiles[i], x_ * 8, (y_ + i) * 8); + } } - - void setdata(const std::string& name, int tx, int ty, bool allbg = false) { - // ... setdata function implementation here - } - - // Other member functions and variables }; -class Subtype3 : public RoomObject {}; +class Subtype3 : public RoomObject { + public: + std::vector tiles; + std::string name; + bool allBgs; + Sorting sort; + + Subtype3(int16_t id, uint8_t x, uint8_t y, uint8_t size, uint8_t layer) + : RoomObject(id, x, y, size, layer) { + auto rom_data = rom()->data(); + name = Type3RoomObjectNames[id & 0xFF]; + int pos = + core::tile_address + + static_cast( + (rom_data[core::subtype3_tiles + ((id & 0xFF) * 2) + 1] << 8) + + rom_data[core::subtype3_tiles + ((id & 0xFF) * 2)]); + AddTiles(8, pos); + sort = (Sorting)(Sorting::Horizontal | Sorting::Wall); + } + + void Draw() override { + for (int i = 0; i < 8; i++) { + // DrawTile(tiles[i], x_ * 8, (y_ + i) * 8); + } + } +}; } // namespace dungeon } // namespace zelda3