From 4ef2540d15f03f74e72a1f71265fb3bafae9a893 Mon Sep 17 00:00:00 2001 From: scawful Date: Mon, 20 Nov 2023 06:18:28 -0500 Subject: [PATCH] cleanup dungeon room constants --- src/app/core/constants.h | 59 ----------- src/app/editor/dungeon_editor.cc | 33 +++--- src/app/editor/dungeon_editor.h | 11 +- src/app/rom.h | 32 ++++-- src/app/zelda3/dungeon/room.cc | 173 +++++++++++++++---------------- src/app/zelda3/dungeon/room.h | 33 +++--- 6 files changed, 146 insertions(+), 195 deletions(-) diff --git a/src/app/core/constants.h b/src/app/core/constants.h index 9b61026e9..4c698c767 100644 --- a/src/app/core/constants.h +++ b/src/app/core/constants.h @@ -165,65 +165,6 @@ constexpr int kTilesheetWidth = 128; constexpr int kTilesheetHeight = 32; constexpr int kTilesheetDepth = 8; -// ============================================================================ -// Dungeon Related Variables -// ============================================================================ - -// That could be turned into a pointer : -constexpr int dungeons_palettes_groups = 0x75460; // JP 0x67DD0 -constexpr int dungeons_main_bg_palette_pointers = 0xDEC4B; // JP Same -constexpr int dungeons_palettes = - 0xDD734; // JP Same (where all dungeons palettes are) - -// That could be turned into a pointer : -constexpr int room_items_pointers = 0xDB69; // JP 0xDB67 - -constexpr int rooms_sprite_pointer = 0x4C298; // JP Same //2byte bank 09D62E -constexpr int room_header_pointer = 0xB5DD; // LONG -constexpr int room_header_pointers_bank = 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; -// constexpr int chests_data_pointer2 = 0xEC0A; //Disabled for now could be used -// for expansion constexpr int chests_data_pointer3 = 0xEC10; //Disabled for now -// could be used for expansion - -constexpr int blocks_length = 0x8896; // word value -constexpr int blocks_pointer1 = 0x15AFA; -constexpr int blocks_pointer2 = 0x15B01; -constexpr int blocks_pointer3 = 0x15B08; -constexpr int blocks_pointer4 = 0x15B0F; - -constexpr int torch_data = 0x2736A; // JP 0x2704A -constexpr int torches_length_pointer = 0x88C1; - -constexpr int sprites_data = - 0x4D8B0; // It use the unused pointers to have more space //Save purpose -constexpr int sprites_data_empty_room = 0x4D8AE; -constexpr int sprites_end_data = 0x4EC9E; - -constexpr int pit_pointer = 0x394AB; -constexpr int pit_count = 0x394A6; - -constexpr int doorPointers = 0xF83C0; - -// doors -constexpr int door_gfx_up = 0x4D9E; -constexpr int door_gfx_down = 0x4E06; -constexpr int door_gfx_cavexit_down = 0x4E06; -constexpr int door_gfx_left = 0x4E66; -constexpr int door_gfx_right = 0x4EC6; - -constexpr int door_pos_up = 0x197E; -constexpr int door_pos_down = 0x1996; -constexpr int door_pos_left = 0x19AE; -constexpr int door_pos_right = 0x19C6; - // TEXT EDITOR RELATED CONSTANTS constexpr int gfx_font = 0x70000; // 2bpp format constexpr int text_data = 0xE0000; diff --git a/src/app/editor/dungeon_editor.cc b/src/app/editor/dungeon_editor.cc index 3e9eee950..66565177f 100644 --- a/src/app/editor/dungeon_editor.cc +++ b/src/app/editor/dungeon_editor.cc @@ -14,12 +14,12 @@ namespace yaze { namespace app { namespace editor { -void DungeonEditor::Update() { +absl::Status DungeonEditor::Update() { if (!is_loaded_ && rom()->isLoaded()) { for (int i = 0; i < 0x100; i++) { rooms_.emplace_back(zelda3::dungeon::Room(i)); rooms_[i].LoadHeader(); - // rooms_[i].LoadRoomGraphics(rooms_[i].blockset); + rooms_[i].LoadRoomGraphics(rooms_[i].blockset); } is_loaded_ = true; } @@ -59,6 +59,7 @@ void DungeonEditor::Update() { DrawTileSelector(); ImGui::EndTable(); } + return absl::OkStatus(); } // Using ImGui Custom Tabs show each individual room the user selects from the @@ -66,13 +67,6 @@ void DungeonEditor::Update() { void DungeonEditor::DrawDungeonTabView() { static int next_tab_id = 0; - // TabItemButton() and Leading/Trailing flags are distinct features which we - // will demo together. (It is possible to submit regular tabs with - // Leading/Trailing flags, or TabItemButton tabs without Leading/Trailing - // flags... but they tend to make more sense together) - static bool show_trailing_button = true; - ImGui::Checkbox("Show Trailing TabItemButton()", &show_trailing_button); - // Expose some other flags which are useful to showcase how they interact with // Leading/Trailing tabs static ImGuiTabBarFlags tab_bar_flags = @@ -92,14 +86,11 @@ void DungeonEditor::DrawDungeonTabView() { ImGuiTabBarFlags_FittingPolicyScroll); if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags)) { - // Demo Trailing Tabs: click the "+" button to add a new tab (in your app - // you may want to use a font icon instead of the "+") Note that we submit - // it before the regular tabs, but because of the ImGuiTabItemFlags_Trailing - // flag it will always appear at the end. - if (show_trailing_button) - if (ImGui::TabItemButton( - "+", ImGuiTabItemFlags_Trailing | ImGuiTabItemFlags_NoTooltip)) - active_rooms_.push_back(next_tab_id++); // Add new tab + // TODO: Manage the room that is being added to the tab bar. + if (ImGui::TabItemButton( + "+", ImGuiTabItemFlags_Trailing | ImGuiTabItemFlags_NoTooltip)) { + active_rooms_.push_back(next_tab_id++); // Add new tab + } // Submit our regular tabs for (int n = 0; n < active_rooms_.Size;) { @@ -168,10 +159,14 @@ void DungeonEditor::DrawToolset() { ImGui::TableSetupColumn("#spriteTool"); ImGui::TableNextColumn(); - ImGui::Button(ICON_MD_UNDO); + if (ImGui::Button(ICON_MD_UNDO)) { + PRINT_IF_ERROR(Undo()); + } ImGui::TableNextColumn(); - ImGui::Button(ICON_MD_REDO); + if (ImGui::Button(ICON_MD_REDO)) { + PRINT_IF_ERROR(Redo()); + } ImGui::TableNextColumn(); ImGui::Button(ICON_MD_MANAGE_HISTORY); diff --git a/src/app/editor/dungeon_editor.h b/src/app/editor/dungeon_editor.h index 75c8a624b..b9c81cacf 100644 --- a/src/app/editor/dungeon_editor.h +++ b/src/app/editor/dungeon_editor.h @@ -4,6 +4,7 @@ #include #include "app/core/common.h" +#include "app/core/editor.h" #include "app/gui/canvas.h" #include "app/gui/icons.h" #include "app/rom.h" @@ -14,9 +15,14 @@ namespace yaze { namespace app { namespace editor { -class DungeonEditor : public SharedROM { +class DungeonEditor : public Editor, public SharedROM { public: - void Update(); + absl::Status Update() override; + absl::Status Cut() override { return absl::OkStatus(); } + absl::Status Copy() override { return absl::OkStatus(); } + absl::Status Paste() override { return absl::OkStatus(); } + absl::Status Undo() override { return absl::OkStatus(); } + absl::Status Redo() override { return absl::OkStatus(); } private: void DrawToolset(); @@ -26,6 +32,7 @@ class DungeonEditor : public SharedROM { void DrawRoomGraphics(); void DrawTileSelector(); + uint16_t current_room_id_ = 0; bool is_loaded_ = false; gfx::Bitmap room_gfx_bmp_; diff --git a/src/app/rom.h b/src/app/rom.h index 6d567b7e5..34c8ca565 100644 --- a/src/app/rom.h +++ b/src/app/rom.h @@ -51,7 +51,7 @@ enum class Z3_Version { // Define a struct to hold the version-specific constants struct VersionConstants { - uint32_t kGgxAnimatedPointer; + uint32_t kGfxAnimatedPointer; uint32_t kOverworldGfxGroups1; uint32_t kOverworldGfxGroups2; uint32_t kCompressedAllMap32PointersHigh; @@ -68,13 +68,14 @@ struct VersionConstants { uint32_t kMap32TileBL; uint32_t kMap32TileBR; uint32_t kSpriteBlocksetPointer; + uint32_t kDungeonPalettesGroups; }; // Define a map to hold the version constants for each version static const std::map kVersionConstantsMap = { {Z3_Version::US, { - 0x10275, // kGgxAnimatedPointer + 0x10275, // kGfxAnimatedPointer 0x5D97, // kOverworldGfxGroups1 0x6073, // kOverworldGfxGroups2 0x1794D, // kCompressedAllMap32PointersHigh @@ -91,10 +92,11 @@ static const std::map kVersionConstantsMap = { 0x20000, // kMap32TileBL 0x23400, // kMap32TileBR 0x5B57, // kSpriteBlocksetPointer + 0x75460, // kDungeonPalettesGroups }}, {Z3_Version::JP, { - 0x10624, // kGgxAnimatedPointer + 0x10624, // kGfxAnimatedPointer 0x5DD7, // kOverworldGfxGroups1 0x60B3, // kOverworldGfxGroups2 0x176B1, // kCompressedAllMap32PointersHigh @@ -111,6 +113,7 @@ static const std::map kVersionConstantsMap = { 0x20000, // kMap32TileBL 0x233C0, // kMap32TileBR 0x5B97, // kSpriteBlocksetPointer + 0x67DD0, // kDungeonPalettesGroups }}}; // Define some constants used throughout the ROM class @@ -125,6 +128,7 @@ constexpr uint32_t kNormalGfxSpaceStart = 0x87000; constexpr uint32_t kNormalGfxSpaceEnd = 0xC4200; constexpr uint32_t kLinkSpriteLocation = 0x80000; constexpr uint32_t kFontSpriteLocation = 0x70000; +constexpr uint32_t gfx_groups_pointer = 0x6237; struct WriteAction { int address; @@ -283,6 +287,15 @@ class ROM : public core::ExperimentFlags { return result; } + absl::StatusOr ReadShortLong(int offset) { + if (offset + 2 >= rom_data_.size()) { + return absl::InvalidArgumentError("Offset out of range"); + } + auto result = (uint32_t)(rom_data_[offset] | (rom_data_[offset + 1] << 8) | + (rom_data_[offset + 2] << 16)); + return result; + } + absl::StatusOr> ReadByteVector(uint32_t offset, uint32_t length) { if (offset + length > rom_data_.size()) { @@ -477,8 +490,8 @@ class ROM : public core::ExperimentFlags { spriteset_ids.resize(144, std::vector(4)); paletteset_ids.resize(72, std::vector(4)); - int gfxPointer = (rom_data_[core::gfx_groups_pointer + 1] << 8) + - rom_data_[core::gfx_groups_pointer]; + int gfxPointer = (rom_data_[gfx_groups_pointer + 1] << 8) + + rom_data_[gfx_groups_pointer]; gfxPointer = core::SnesToPc(gfxPointer); for (int i = 0; i < 37; i++) { @@ -505,14 +518,15 @@ class ROM : public core::ExperimentFlags { for (int i = 0; i < 72; i++) { for (int j = 0; j < 4; j++) { paletteset_ids[i][j] = - rom_data_[core::dungeons_palettes_groups + (i * 4) + j]; + rom_data_[GetVersionConstants().kDungeonPalettesGroups + (i * 4) + + j]; } } } bool SaveGroupsToROM() { - int gfxPointer = (rom_data_[core::gfx_groups_pointer + 1] << 8) + - rom_data_[core::gfx_groups_pointer]; + int gfxPointer = (rom_data_[gfx_groups_pointer + 1] << 8) + + rom_data_[gfx_groups_pointer]; gfxPointer = core::SnesToPc(gfxPointer); for (int i = 0; i < 37; i++) { @@ -537,7 +551,7 @@ class ROM : public core::ExperimentFlags { for (int i = 0; i < 72; i++) { for (int j = 0; j < 4; j++) { - rom_data_[core::dungeons_palettes_groups + (i * 4) + j] = + rom_data_[GetVersionConstants().kDungeonPalettesGroups + (i * 4) + j] = paletteset_ids[i][j]; } } diff --git a/src/app/zelda3/dungeon/room.cc b/src/app/zelda3/dungeon/room.cc index e41590bee..58b3994eb 100644 --- a/src/app/zelda3/dungeon/room.cc +++ b/src/app/zelda3/dungeon/room.cc @@ -80,14 +80,14 @@ void DrawDungeonRoomBG2(std::vector& tiles_bg2_buffer, void Room::LoadHeader() { // Address of the room header - int headerPointer = (rom()->data()[core::room_header_pointer + 2] << 16) + - (rom()->data()[core::room_header_pointer + 1] << 8) + - (rom()->data()[core::room_header_pointer]); - headerPointer = core::SnesToPc(headerPointer); + int header_pointer = (rom()->data()[kRoomHeaderPointer + 2] << 16) + + (rom()->data()[kRoomHeaderPointer + 1] << 8) + + (rom()->data()[kRoomHeaderPointer]); + header_pointer = core::SnesToPc(header_pointer); - int address = (rom()->data()[core::room_header_pointers_bank] << 16) + - (rom()->data()[(headerPointer + 1) + (room_id_ * 2)] << 8) + - rom()->data()[(headerPointer) + (room_id_ * 2)]; + int address = (rom()->data()[kRoomHeaderPointerBank] << 16) + + (rom()->data()[(header_pointer + 1) + (room_id_ * 2)] << 8) + + rom()->data()[(header_pointer) + (room_id_ * 2)]; auto header_location = core::SnesToPc(address); @@ -136,6 +136,79 @@ void Room::LoadHeader() { staircase_rooms[3] = (rom()->data()[header_location + 13]); } +void Room::LoadRoomGraphics(uchar entrance_blockset) { + auto mainGfx = rom()->main_blockset_ids; + auto roomGfx = rom()->room_blockset_ids; + auto spriteGfx = rom()->spriteset_ids; + current_gfx16_.reserve(0x4000); + + for (int i = 0; i < 8; i++) { + blocks[i] = mainGfx[BackgroundTileset][i]; + 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]; + } + } + } + } + + blocks[8] = 115 + 0; // Static Sprites Blocksets (fairy,pot,ect...) + blocks[9] = 115 + 10; + blocks[10] = 115 + 6; + blocks[11] = 115 + 7; + for (int i = 0; i < 4; i++) { + blocks[12 + i] = (uchar)(spriteGfx[SpriteTileset + 64][i] + 115); + } // 12-16 sprites + + auto gfx_buffer_data = rom()->GetGraphicsBuffer(); + + // Into "room gfx16" 16 of them + int sheetPos = 0; + for (int i = 0; i < 16; i++) { + int d = 0; + int ioff = blocks[i] * 2048; + while (d < 2048) { + // NOTE LOAD BLOCKSETS SOMEWHERE FIRST + uchar mapByte = gfx_buffer_data[d + ioff]; + if (i < 4) { + mapByte += 0x88; + } // Last line of 6, first line of 7 ? + + current_gfx16_[d + sheetPos] = mapByte; + d++; + } + + sheetPos += 2048; + } + + LoadAnimatedGraphics(); +} + +void Room::LoadAnimatedGraphics() { + int gfx_ptr = + core::SnesToPc(rom()->GetVersionConstants().kGfxAnimatedPointer); + + auto gfx_buffer_data = rom()->GetGraphicsBuffer(); + auto rom_data = rom()->vector(); + int data = 0; + while (data < 512) { + uchar mapByte = + gfx_buffer_data[data + (92 * 2048) + (512 * animated_frame)]; + current_gfx16_[data + (7 * 2048)] = mapByte; + + mapByte = + gfx_buffer_data[data + (rom_data[gfx_ptr + BackgroundTileset] * 2048) + + (512 * animated_frame)]; + current_gfx16_[data + (7 * 2048) - 512] = mapByte; + data++; + } +} + void Room::LoadSprites() { auto rom_data = rom()->vector(); int spritePointer = (0x04 << 16) + (rom_data[rooms_sprite_pointer + 1] << 8) + @@ -347,95 +420,15 @@ void Room::LoadObjects() { } } -RoomObject Room::AddObject(short oid, uint8_t x, uint8_t y, uint8_t size, - uint8_t layer) { - return RoomObject(oid, x, y, size, layer); -} - -void Room::LoadRoomGraphics(uchar entrance_blockset) { - auto mainGfx = rom()->main_blockset_ids; - auto roomGfx = rom()->room_blockset_ids; - auto spriteGfx = rom()->spriteset_ids; - - for (int i = 0; i < 8; i++) { - blocks[i] = mainGfx[BackgroundTileset][i]; - 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]; - } - } - } - } - - blocks[8] = 115 + 0; // Static Sprites Blocksets (fairy,pot,ect...) - blocks[9] = 115 + 10; - blocks[10] = 115 + 6; - blocks[11] = 115 + 7; - for (int i = 0; i < 4; i++) { - blocks[12 + i] = (uchar)(spriteGfx[SpriteTileset + 64][i] + 115); - } // 12-16 sprites - - auto newPdata = rom()->GetGraphicsBuffer(); - - uchar* sheetsData = current_graphics_.data(); - // Into "room gfx16" 16 of them - - int sheetPos = 0; - for (int i = 0; i < 16; i++) { - int d = 0; - int ioff = blocks[i] * 2048; - while (d < 2048) { - // NOTE LOAD BLOCKSETS SOMEWHERE FIRST - uchar mapByte = newPdata[d + ioff]; - if (i < 4) // removed switch - { - mapByte += 0x88; - } // Last line of 6, first line of 7 ? - - sheetsData[d + sheetPos] = mapByte; - d++; - } - - sheetPos += 2048; - } - - LoadAnimatedGraphics(); -} - -void Room::LoadAnimatedGraphics() { - int gfxanimatedPointer = core::SnesToPc(gfx_animated_pointer); - - auto newPdata = rom()->GetGraphicsBuffer(); - auto rom_data = rom()->vector(); - uchar* sheetsData = current_graphics_.data(); - int data = 0; - while (data < 512) { - uchar mapByte = newPdata[data + (92 * 2048) + (512 * animated_frame)]; - sheetsData[data + (7 * 2048)] = mapByte; - - mapByte = - newPdata[data + - (rom_data[gfxanimatedPointer + BackgroundTileset] * 2048) + - (512 * animated_frame)]; - sheetsData[data + (7 * 2048) - 512] = mapByte; - data++; - } -} - void Room::LoadRoomFromROM() { // Load dungeon header auto rom_data = rom()->vector(); - int headerPointer = core::SnesToPc(room_header_pointer); + int header_pointer = core::SnesToPc(kRoomHeaderPointer); message_id_ = messages_id_dungeon + (room_id_ * 2); - int hpos = core::SnesToPc((rom_data[room_header_pointers_bank] << 16) | - headerPointer + (room_id_ * 2)); + int hpos = core::SnesToPc((rom_data[kRoomHeaderPointerBank] << 16) | + header_pointer + (room_id_ * 2)); hpos++; uchar b = rom_data[hpos]; diff --git a/src/app/zelda3/dungeon/room.h b/src/app/zelda3/dungeon/room.h index 194b4b958..651d479ea 100644 --- a/src/app/zelda3/dungeon/room.h +++ b/src/app/zelda3/dungeon/room.h @@ -21,15 +21,12 @@ namespace zelda3 { namespace dungeon { constexpr int entrance_gfx_group = 0x5D97; -constexpr int gfx_animated_pointer = 0x10275; // JP 0x10624 //long pointer - -constexpr int dungeons_palettes_groups = 0x75460; // JP 0x67DD0 constexpr int dungeons_main_bg_palette_pointers = 0xDEC4B; // JP Same constexpr int dungeons_palettes = 0xDD734; -constexpr int room_items_pointers = 0xDB69; // JP 0xDB67 -constexpr int rooms_sprite_pointer = 0x4C298; // JP Same //2byte bank 09D62E -constexpr int room_header_pointer = 0xB5DD; // LONG -constexpr int room_header_pointers_bank = 0xB5E7; // JP Same +constexpr int room_items_pointers = 0xDB69; // JP 0xDB67 +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 @@ -119,19 +116,20 @@ class Room : public SharedROM { Room(int room_id) : room_id_(room_id) {} ~Room() = default; void LoadHeader(); + void LoadRoomGraphics(uchar entrance_blockset = 0xFF); + void LoadAnimatedGraphics(); + void LoadSprites(); void LoadChests(); - void LoadObjects(); - RoomObject AddObject(short oid, uint8_t x, uint8_t y, uint8_t size, - uint8_t layer); - - void LoadRoomGraphics(uchar entrance_blockset = 0xFF); - void LoadAnimatedGraphics(); - void LoadRoomFromROM(); + RoomObject AddObject(short oid, uint8_t x, uint8_t y, uint8_t size, + uint8_t layer) { + return RoomObject(oid, x, y, size, layer); + } + uint8_t floor1 = 0; uint8_t floor2 = 0; uint8_t blockset = 0; @@ -142,14 +140,18 @@ class Room : public SharedROM { uint16_t message_id_ = 0; gfx::Bitmap current_graphics_; + std::vector bg1_buffer_; + std::vector bg2_buffer_; + std::vector current_gfx16_; private: + bool is_loaded_ = false; + int animated_frame = 0; int room_id_ = 0; bool light; - bool is_loaded_ = false; Background2 bg2; uint8_t staircase_plane[4]; @@ -182,7 +184,6 @@ class Room : public SharedROM { // std::vector chest_list; std::vector chests_in_room; - std::vector current_gfx16_; std::vector tilesObjects; };