From 77a6313bb3f4bd151709a31d1da65c78a674a3e9 Mon Sep 17 00:00:00 2001 From: scawful Date: Sat, 28 Dec 2024 17:18:19 -0500 Subject: [PATCH] Move OverworldEntrance, OverworldExit, OverworldItem to own files --- src/app/zelda3/overworld/overworld.h | 401 ++---------------- src/app/zelda3/overworld/overworld_entrance.h | 90 ++++ src/app/zelda3/overworld/overworld_exit.h | 210 +++++++++ src/app/zelda3/overworld/overworld_item.h | 108 +++++ 4 files changed, 436 insertions(+), 373 deletions(-) create mode 100644 src/app/zelda3/overworld/overworld_entrance.h create mode 100644 src/app/zelda3/overworld/overworld_exit.h create mode 100644 src/app/zelda3/overworld/overworld_item.h diff --git a/src/app/zelda3/overworld/overworld.h b/src/app/zelda3/overworld/overworld.h index 030547ed..054485ba 100644 --- a/src/app/zelda3/overworld/overworld.h +++ b/src/app/zelda3/overworld/overworld.h @@ -10,6 +10,9 @@ #include "app/gfx/snes_tile.h" #include "app/rom.h" #include "app/zelda3/common.h" +#include "app/zelda3/overworld/overworld_entrance.h" +#include "app/zelda3/overworld/overworld_exit.h" +#include "app/zelda3/overworld/overworld_item.h" #include "app/zelda3/overworld/overworld_map.h" #include "app/zelda3/sprite/sprite.h" @@ -23,365 +26,17 @@ namespace zelda3 { */ namespace overworld { -constexpr int GravesYTilePos = 0x49968; // short (0x0F entries) -constexpr int GravesXTilePos = 0x49986; // short (0x0F entries) -constexpr int GravesTilemapPos = 0x499A4; // short (0x0F entries) -constexpr int GravesGFX = 0x499C2; // short (0x0F entries) +constexpr int GravesYTilePos = 0x49968; // short (0x0F entries) +constexpr int GravesXTilePos = 0x49986; // short (0x0F entries) +constexpr int GravesTilemapPos = 0x499A4; // short (0x0F entries) +constexpr int GravesGFX = 0x499C2; // short (0x0F entries) -constexpr int GravesXPos = 0x4994A; // short (0x0F entries) -constexpr int GravesYLine = 0x4993A; // short (0x08 entries) -constexpr int GravesCountOnY = 0x499E0; // Byte 0x09 entries - -constexpr int GraveLinkSpecialHole = 0x46DD9; // short -constexpr int GraveLinkSpecialStairs = 0x46DE0; // short - -// List of secret item names -const std::vector kSecretItemNames = { - "Nothing", // 0 - "Green Rupee", // 1 - "Rock hoarder", // 2 - "Bee", // 3 - "Health pack", // 4 - "Bomb", // 5 - "Heart ", // 6 - "Blue Rupee", // 7 - "Key", // 8 - "Arrow", // 9 - "Bomb", // 10 - "Heart", // 11 - "Magic", // 12 - "Full Magic", // 13 - "Cucco", // 14 - "Green Soldier", // 15 - "Bush Stal", // 16 - "Blue Soldier", // 17 - "Landmine", // 18 - "Heart", // 19 - "Fairy", // 20 - "Heart", // 21 - "Nothing ", // 22 - "Hole", // 23 - "Warp", // 24 - "Staircase", // 25 - "Bombable", // 26 - "Switch" // 27 -}; - -constexpr int overworldItemsPointers = 0xDC2F9; -constexpr int kOverworldItemsAddress = 0xDC8B9; // 1BC2F9 -constexpr int overworldItemsBank = 0xDC8BF; -constexpr int overworldItemsEndData = 0xDC89C; // 0DC89E - -class OverworldItem : public GameEntity { - public: - bool bg2_ = false; - uint8_t id_; - uint8_t game_x_; - uint8_t game_y_; - uint16_t room_map_id_; - int unique_id = 0; - bool deleted = false; - OverworldItem() = default; - - OverworldItem(uint8_t id, uint16_t room_map_id, int x, int y, bool bg2) { - this->id_ = id; - this->x_ = x; - this->y_ = y; - this->bg2_ = bg2; - this->room_map_id_ = room_map_id; - this->map_id_ = room_map_id; - this->entity_id_ = id; - this->entity_type_ = kItem; - - int map_x = room_map_id - ((room_map_id / 8) * 8); - int map_y = room_map_id / 8; - - game_x_ = static_cast(std::abs(x - (map_x * 512)) / 16); - game_y_ = static_cast(std::abs(y - (map_y * 512)) / 16); - } - - void UpdateMapProperties(uint16_t room_map_id) override { - room_map_id_ = room_map_id; - - if (room_map_id_ >= 64) { - room_map_id_ -= 64; - } - - int map_x = room_map_id_ - ((room_map_id_ / 8) * 8); - int map_y = room_map_id_ / 8; - - game_x_ = static_cast(std::abs(x_ - (map_x * 512)) / 16); - game_y_ = static_cast(std::abs(y_ - (map_y * 512)) / 16); - - std::cout << "Item: " << std::hex << std::setw(2) << std::setfill('0') - << static_cast(id_) << " MapId: " << std::hex << std::setw(2) - << std::setfill('0') << static_cast(room_map_id_) - << " X: " << static_cast(game_x_) - << " Y: " << static_cast(game_y_) << std::endl; - } -}; - -constexpr int OWExitRoomId = 0x15D8A; // 0x15E07 Credits sequences -// 105C2 Ending maps -// 105E2 Sprite Group Table for Ending -constexpr int OWExitMapId = 0x15E28; -constexpr int OWExitVram = 0x15E77; -constexpr int OWExitYScroll = 0x15F15; -constexpr int OWExitXScroll = 0x15FB3; -constexpr int OWExitYPlayer = 0x16051; -constexpr int OWExitXPlayer = 0x160EF; -constexpr int OWExitYCamera = 0x1618D; -constexpr int OWExitXCamera = 0x1622B; -constexpr int OWExitDoorPosition = 0x15724; -constexpr int OWExitUnk1 = 0x162C9; -constexpr int OWExitUnk2 = 0x16318; -constexpr int OWExitDoorType1 = 0x16367; -constexpr int OWExitDoorType2 = 0x16405; - -constexpr int OWExitMapIdWhirlpool = 0x16AE5; // JP = ;016849 -constexpr int OWExitVramWhirlpool = 0x16B07; // JP = ;01686B -constexpr int OWExitYScrollWhirlpool = 0x16B29; // JP = ;01688D -constexpr int OWExitXScrollWhirlpool = 0x16B4B; // JP = ;016DE7 -constexpr int OWExitYPlayerWhirlpool = 0x16B6D; // JP = ;016E09 -constexpr int OWExitXPlayerWhirlpool = 0x16B8F; // JP = ;016E2B -constexpr int OWExitYCameraWhirlpool = 0x16BB1; // JP = ;016E4D -constexpr int OWExitXCameraWhirlpool = 0x16BD3; // JP = ;016E6F -constexpr int OWExitUnk1Whirlpool = 0x16BF5; // JP = ;016E91 -constexpr int OWExitUnk2Whirlpool = 0x16C17; // JP = ;016EB3 -constexpr int OWWhirlpoolPosition = 0x16CF8; // JP = ;016F94 - -class OverworldExit : public GameEntity { - public: - uint16_t y_scroll_; - uint16_t x_scroll_; - uchar y_player_; - uchar x_player_; - uchar y_camera_; - uchar x_camera_; - uchar scroll_mod_y_; - uchar scroll_mod_x_; - uint16_t door_type_1_; - uint16_t door_type_2_; - uint16_t room_id_; - uint16_t map_pos_; // Position in the vram - uchar entrance_id_; - uchar area_x_; - uchar area_y_; - bool is_hole_ = false; - bool deleted_ = false; - bool is_automatic_ = false; - bool large_map_ = false; - - OverworldExit() = default; - OverworldExit(uint16_t room_id, uchar map_id, uint16_t vram_location, - uint16_t y_scroll, uint16_t x_scroll, uint16_t player_y, - uint16_t player_x, uint16_t camera_y, uint16_t camera_x, - uchar scroll_mod_y, uchar scroll_mod_x, uint16_t door_type_1, - uint16_t door_type_2, bool deleted = false) - : map_pos_(vram_location), - entrance_id_(0), - area_x_(0), - area_y_(0), - room_id_(room_id), - y_scroll_(y_scroll), - x_scroll_(x_scroll), - y_player_(player_y), - x_player_(player_x), - y_camera_(camera_y), - x_camera_(camera_x), - scroll_mod_y_(scroll_mod_y), - scroll_mod_x_(scroll_mod_x), - door_type_1_(door_type_1), - door_type_2_(door_type_2), - is_hole_(false), - deleted_(deleted) { - // Initialize entity variables - x_ = player_x; - y_ = player_y; - map_id_ = map_id; - entity_type_ = kExit; - - int mapX = (map_id_ - ((map_id_ / 8) * 8)); - int mapY = (map_id_ / 8); - - area_x_ = (uchar)((std::abs(x_ - (mapX * 512)) / 16)); - area_y_ = (uchar)((std::abs(y_ - (mapY * 512)) / 16)); - - if (door_type_1 != 0) { - int p = (door_type_1 & 0x7FFF) >> 1; - entrance_id_ = (uchar)(p % 64); - area_y_ = (uchar)(p >> 6); - } - - if (door_type_2 != 0) { - int p = (door_type_2 & 0x7FFF) >> 1; - entrance_id_ = (uchar)(p % 64); - area_y_ = (uchar)(p >> 6); - } - - if (map_id_ >= 64) { - map_id_ -= 64; - } - - mapX = (map_id_ - ((map_id_ / 8) * 8)); - mapY = (map_id_ / 8); - - area_x_ = (uchar)((std::abs(x_ - (mapX * 512)) / 16)); - area_y_ = (uchar)((std::abs(y_ - (mapY * 512)) / 16)); - - map_pos_ = (uint16_t)((((area_y_) << 6) | (area_x_ & 0x3F)) << 1); - } - - // Overworld overworld - void UpdateMapProperties(uint16_t map_id) override { - map_id_ = map_id; - - int large = 256; - int mapid = map_id; - - if (map_id < 128) { - large = large_map_ ? 768 : 256; - // if (overworld.overworld_map(map_id)->Parent() != map_id) { - // mapid = overworld.overworld_map(map_id)->Parent(); - // } - } - - int mapX = map_id - ((map_id / 8) * 8); - int mapY = map_id / 8; - - area_x_ = (uchar)((std::abs(x_ - (mapX * 512)) / 16)); - area_y_ = (uchar)((std::abs(y_ - (mapY * 512)) / 16)); - - if (map_id >= 64) { - map_id -= 64; - } - - int mapx = (map_id & 7) << 9; - int mapy = (map_id & 56) << 6; - - if (is_automatic_) { - x_ = x_ - 120; - y_ = y_ - 80; - - if (x_ < mapx) { - x_ = mapx; - } - - if (y_ < mapy) { - y_ = mapy; - } - - if (x_ > mapx + large) { - x_ = mapx + large; - } - - if (y_ > mapy + large + 32) { - y_ = mapy + large + 32; - } - - x_camera_ = x_player_ + 0x07; - y_camera_ = y_player_ + 0x1F; - - if (x_camera_ < mapx + 127) { - x_camera_ = mapx + 127; - } - - if (y_camera_ < mapy + 111) { - y_camera_ = mapy + 111; - } - - if (x_camera_ > mapx + 127 + large) { - x_camera_ = mapx + 127 + large; - } - - if (y_camera_ > mapy + 143 + large) { - y_camera_ = mapy + 143 + large; - } - } - - short vram_x_scroll = (short)(x_ - mapx); - short vram_y_scroll = (short)(y_ - mapy); - - map_pos_ = (uint16_t)(((vram_y_scroll & 0xFFF0) << 3) | - ((vram_x_scroll & 0xFFF0) >> 3)); - - std::cout << "Exit: " << room_id_ << " MapId: " << std::hex << mapid - << " X: " << static_cast(area_x_) - << " Y: " << static_cast(area_y_) << std::endl; - } -}; - -constexpr int OWEntranceMap = 0xDB96F; -constexpr int OWEntrancePos = 0xDBA71; -constexpr int OWEntranceEntranceId = 0xDBB73; - -// (0x13 entries, 2 bytes each) modified(less 0x400) -// map16 coordinates for each hole -constexpr int OWHolePos = 0xDB800; - -// (0x13 entries, 2 bytes each) corresponding -// area numbers for each hole -constexpr int OWHoleArea = 0xDB826; - -//(0x13 entries, 1 byte each) corresponding entrance numbers -constexpr int OWHoleEntrance = 0xDB84C; - -// OWEntrances Expansion - -// Instructions for editors -// if byte at (PC) address 0xDB895 == B8 then it is vanilla -// Load normal overworld entrances data -// Otherwise load from the expanded space -// When saving just save in expanded space 256 values for each -// (PC Addresses) - you can find snes address at the orgs below -// 0x0DB35F = (short) Map16 tile address (mapPos in ZS) -// 0x0DB55F = (short) Screen ID (MapID in ZS) -// 0x0DB75F = (byte) Entrance leading to (EntranceID in ZS) - -// *Important* the Screen ID now also require bit 0x8000 (15) being set to tell -// entrance is a hole -class OverworldEntrance : public GameEntity { - public: - uint16_t map_pos_; - uchar entrance_id_; - uchar area_x_; - uchar area_y_; - bool is_hole_ = false; - bool deleted = false; - - OverworldEntrance() = default; - OverworldEntrance(int x, int y, uchar entrance_id, short map_id, - uint16_t map_pos, bool hole) - : map_pos_(map_pos), entrance_id_(entrance_id), is_hole_(hole) { - x_ = x; - y_ = y; - map_id_ = map_id; - entity_id_ = entrance_id; - entity_type_ = kEntrance; - - int mapX = (map_id_ - ((map_id_ / 8) * 8)); - int mapY = (map_id_ / 8); - area_x_ = (uchar)((std::abs(x - (mapX * 512)) / 16)); - area_y_ = (uchar)((std::abs(y - (mapY * 512)) / 16)); - } - - void UpdateMapProperties(uint16_t map_id) override { - map_id_ = map_id; - - if (map_id_ >= 64) { - map_id_ -= 64; - } - - int mapX = (map_id_ - ((map_id_ / 8) * 8)); - int mapY = (map_id_ / 8); - - area_x_ = (uchar)((std::abs(x_ - (mapX * 512)) / 16)); - area_y_ = (uchar)((std::abs(y_ - (mapY * 512)) / 16)); - - map_pos_ = (uint16_t)((((area_y_) << 6) | (area_x_ & 0x3F)) << 1); - } -}; +constexpr int GravesXPos = 0x4994A; // short (0x0F entries) +constexpr int GravesYLine = 0x4993A; // short (0x08 entries) +constexpr int GravesCountOnY = 0x499E0; // Byte 0x09 entries +constexpr int GraveLinkSpecialHole = 0x46DD9; // short +constexpr int GraveLinkSpecialStairs = 0x46DE0; // short constexpr int kOverworldMapPaletteIds = 0x7D1C; constexpr int kOverworldSpritePaletteIds = 0x7B41; constexpr int overworldMapPaletteGroup = 0x75504; @@ -446,8 +101,8 @@ constexpr int kMap16Tiles = 0x78000; constexpr int kNumOverworldMaps = 160; constexpr int kNumTile16Individual = 4096; constexpr int Map32PerScreen = 256; -constexpr int NumberOfMap16 = 3752; // 4096 -constexpr int NumberOfMap16Ex = 4096; // 4096 +constexpr int NumberOfMap16 = 3752; // 4096 +constexpr int NumberOfMap16Ex = 4096; // 4096 constexpr int LimitOfMap32 = 8864; constexpr int NumberOfOWSprites = 352; constexpr int NumberOfMap32 = Map32PerScreen * kNumOverworldMaps; @@ -459,7 +114,7 @@ constexpr int NumberOfMap32 = Map32PerScreen * kNumOverworldMaps; * as well as creating the tilesets and tilemaps for the overworld. */ class Overworld : public SharedRom, public core::ExperimentFlags { - public: +public: absl::Status Load(Rom &rom); absl::Status LoadOverworldMaps(); void LoadTileTypes(); @@ -510,14 +165,14 @@ class Overworld : public SharedRom, public core::ExperimentFlags { OWBlockset &GetMapTiles(int world_type) { switch (world_type) { - case 0: - return map_tiles_.light_world; - case 1: - return map_tiles_.dark_world; - case 2: - return map_tiles_.special_world; - default: - return map_tiles_.light_world; + case 0: + return map_tiles_.light_world; + case 1: + return map_tiles_.dark_world; + case 2: + return map_tiles_.special_world; + default: + return map_tiles_.light_world; } } @@ -557,7 +212,7 @@ class Overworld : public SharedRom, public core::ExperimentFlags { auto all_tiles_types() const { return all_tiles_types_; } auto mutable_all_tiles_types() { return &all_tiles_types_; } - private: +private: enum Dimension { map32TilesTL = 0, map32TilesTR = 1, @@ -620,9 +275,9 @@ class Overworld : public SharedRom, public core::ExperimentFlags { std::vector> usage_stats_; }; -} // namespace overworld -} // namespace zelda3 -} // namespace app -} // namespace yaze +} // namespace overworld +} // namespace zelda3 +} // namespace app +} // namespace yaze #endif diff --git a/src/app/zelda3/overworld/overworld_entrance.h b/src/app/zelda3/overworld/overworld_entrance.h new file mode 100644 index 00000000..ecef16ff --- /dev/null +++ b/src/app/zelda3/overworld/overworld_entrance.h @@ -0,0 +1,90 @@ +#ifndef YAZE_APP_ZELDA3_OVERWORLD_ENTRANCE_H +#define YAZE_APP_ZELDA3_OVERWORLD_ENTRANCE_H + +#include + +#include "app/core/constants.h" +#include "app/zelda3/common.h" + +namespace yaze { +namespace app { +namespace zelda3 { +namespace overworld { + +constexpr int OWEntranceMap = 0xDB96F; +constexpr int OWEntrancePos = 0xDBA71; +constexpr int OWEntranceEntranceId = 0xDBB73; + +// (0x13 entries, 2 bytes each) modified(less 0x400) +// map16 coordinates for each hole +constexpr int OWHolePos = 0xDB800; + +// (0x13 entries, 2 bytes each) corresponding +// area numbers for each hole +constexpr int OWHoleArea = 0xDB826; + +//(0x13 entries, 1 byte each) corresponding entrance numbers +constexpr int OWHoleEntrance = 0xDB84C; + +// OWEntrances Expansion + +// Instructions for editors +// if byte at (PC) address 0xDB895 == B8 then it is vanilla +// Load normal overworld entrances data +// Otherwise load from the expanded space +// When saving just save in expanded space 256 values for each +// (PC Addresses) - you can find snes address at the orgs below +// 0x0DB35F = (short) Map16 tile address (mapPos in ZS) +// 0x0DB55F = (short) Screen ID (MapID in ZS) +// 0x0DB75F = (byte) Entrance leading to (EntranceID in ZS) + +// *Important* the Screen ID now also require bit 0x8000 (15) being set to tell +// entrance is a hole +class OverworldEntrance : public GameEntity { +public: + uint16_t map_pos_; + uchar entrance_id_; + uchar area_x_; + uchar area_y_; + bool is_hole_ = false; + bool deleted = false; + + OverworldEntrance() = default; + OverworldEntrance(int x, int y, uchar entrance_id, short map_id, + uint16_t map_pos, bool hole) + : map_pos_(map_pos), entrance_id_(entrance_id), is_hole_(hole) { + x_ = x; + y_ = y; + map_id_ = map_id; + entity_id_ = entrance_id; + entity_type_ = kEntrance; + + int mapX = (map_id_ - ((map_id_ / 8) * 8)); + int mapY = (map_id_ / 8); + area_x_ = (uchar)((std::abs(x - (mapX * 512)) / 16)); + area_y_ = (uchar)((std::abs(y - (mapY * 512)) / 16)); + } + + void UpdateMapProperties(uint16_t map_id) override { + map_id_ = map_id; + + if (map_id_ >= 64) { + map_id_ -= 64; + } + + int mapX = (map_id_ - ((map_id_ / 8) * 8)); + int mapY = (map_id_ / 8); + + area_x_ = (uchar)((std::abs(x_ - (mapX * 512)) / 16)); + area_y_ = (uchar)((std::abs(y_ - (mapY * 512)) / 16)); + + map_pos_ = (uint16_t)((((area_y_) << 6) | (area_x_ & 0x3F)) << 1); + } +}; + +} // namespace overworld +} // namespace zelda3 +} // namespace app +} // namespace yaze + +#endif diff --git a/src/app/zelda3/overworld/overworld_exit.h b/src/app/zelda3/overworld/overworld_exit.h new file mode 100644 index 00000000..926dead9 --- /dev/null +++ b/src/app/zelda3/overworld/overworld_exit.h @@ -0,0 +1,210 @@ +#ifndef YAZE_APP_ZELDA3_OVERWORLD_EXIT_H +#define YAZE_APP_ZELDA3_OVERWORLD_EXIT_H + +#include +#include + +#include "app/core/constants.h" +#include "app/zelda3/common.h" + +namespace yaze { +namespace app { +namespace zelda3 { +namespace overworld { + +constexpr int OWExitRoomId = 0x15D8A; // 0x15E07 Credits sequences +// 105C2 Ending maps +// 105E2 Sprite Group Table for Ending +constexpr int OWExitMapId = 0x15E28; +constexpr int OWExitVram = 0x15E77; +constexpr int OWExitYScroll = 0x15F15; +constexpr int OWExitXScroll = 0x15FB3; +constexpr int OWExitYPlayer = 0x16051; +constexpr int OWExitXPlayer = 0x160EF; +constexpr int OWExitYCamera = 0x1618D; +constexpr int OWExitXCamera = 0x1622B; +constexpr int OWExitDoorPosition = 0x15724; +constexpr int OWExitUnk1 = 0x162C9; +constexpr int OWExitUnk2 = 0x16318; +constexpr int OWExitDoorType1 = 0x16367; +constexpr int OWExitDoorType2 = 0x16405; + +constexpr int OWExitMapIdWhirlpool = 0x16AE5; // JP = ;016849 +constexpr int OWExitVramWhirlpool = 0x16B07; // JP = ;01686B +constexpr int OWExitYScrollWhirlpool = 0x16B29; // JP = ;01688D +constexpr int OWExitXScrollWhirlpool = 0x16B4B; // JP = ;016DE7 +constexpr int OWExitYPlayerWhirlpool = 0x16B6D; // JP = ;016E09 +constexpr int OWExitXPlayerWhirlpool = 0x16B8F; // JP = ;016E2B +constexpr int OWExitYCameraWhirlpool = 0x16BB1; // JP = ;016E4D +constexpr int OWExitXCameraWhirlpool = 0x16BD3; // JP = ;016E6F +constexpr int OWExitUnk1Whirlpool = 0x16BF5; // JP = ;016E91 +constexpr int OWExitUnk2Whirlpool = 0x16C17; // JP = ;016EB3 +constexpr int OWWhirlpoolPosition = 0x16CF8; // JP = ;016F94 + +class OverworldExit : public GameEntity { + public: + uint16_t y_scroll_; + uint16_t x_scroll_; + uchar y_player_; + uchar x_player_; + uchar y_camera_; + uchar x_camera_; + uchar scroll_mod_y_; + uchar scroll_mod_x_; + uint16_t door_type_1_; + uint16_t door_type_2_; + uint16_t room_id_; + uint16_t map_pos_; // Position in the vram + uchar entrance_id_; + uchar area_x_; + uchar area_y_; + bool is_hole_ = false; + bool deleted_ = false; + bool is_automatic_ = false; + bool large_map_ = false; + + OverworldExit() = default; + OverworldExit(uint16_t room_id, uchar map_id, uint16_t vram_location, + uint16_t y_scroll, uint16_t x_scroll, uint16_t player_y, + uint16_t player_x, uint16_t camera_y, uint16_t camera_x, + uchar scroll_mod_y, uchar scroll_mod_x, uint16_t door_type_1, + uint16_t door_type_2, bool deleted = false) + : map_pos_(vram_location), + entrance_id_(0), + area_x_(0), + area_y_(0), + room_id_(room_id), + y_scroll_(y_scroll), + x_scroll_(x_scroll), + y_player_(player_y), + x_player_(player_x), + y_camera_(camera_y), + x_camera_(camera_x), + scroll_mod_y_(scroll_mod_y), + scroll_mod_x_(scroll_mod_x), + door_type_1_(door_type_1), + door_type_2_(door_type_2), + is_hole_(false), + deleted_(deleted) { + // Initialize entity variables + x_ = player_x; + y_ = player_y; + map_id_ = map_id; + entity_type_ = kExit; + + int mapX = (map_id_ - ((map_id_ / 8) * 8)); + int mapY = (map_id_ / 8); + + area_x_ = (uchar)((std::abs(x_ - (mapX * 512)) / 16)); + area_y_ = (uchar)((std::abs(y_ - (mapY * 512)) / 16)); + + if (door_type_1 != 0) { + int p = (door_type_1 & 0x7FFF) >> 1; + entrance_id_ = (uchar)(p % 64); + area_y_ = (uchar)(p >> 6); + } + + if (door_type_2 != 0) { + int p = (door_type_2 & 0x7FFF) >> 1; + entrance_id_ = (uchar)(p % 64); + area_y_ = (uchar)(p >> 6); + } + + if (map_id_ >= 64) { + map_id_ -= 64; + } + + mapX = (map_id_ - ((map_id_ / 8) * 8)); + mapY = (map_id_ / 8); + + area_x_ = (uchar)((std::abs(x_ - (mapX * 512)) / 16)); + area_y_ = (uchar)((std::abs(y_ - (mapY * 512)) / 16)); + + map_pos_ = (uint16_t)((((area_y_) << 6) | (area_x_ & 0x3F)) << 1); + } + + // Overworld overworld + void UpdateMapProperties(uint16_t map_id) override { + map_id_ = map_id; + + int large = 256; + int mapid = map_id; + + if (map_id < 128) { + large = large_map_ ? 768 : 256; + // if (overworld.overworld_map(map_id)->Parent() != map_id) { + // mapid = overworld.overworld_map(map_id)->Parent(); + // } + } + + int mapX = map_id - ((map_id / 8) * 8); + int mapY = map_id / 8; + + area_x_ = (uchar)((std::abs(x_ - (mapX * 512)) / 16)); + area_y_ = (uchar)((std::abs(y_ - (mapY * 512)) / 16)); + + if (map_id >= 64) { + map_id -= 64; + } + + int mapx = (map_id & 7) << 9; + int mapy = (map_id & 56) << 6; + + if (is_automatic_) { + x_ = x_ - 120; + y_ = y_ - 80; + + if (x_ < mapx) { + x_ = mapx; + } + + if (y_ < mapy) { + y_ = mapy; + } + + if (x_ > mapx + large) { + x_ = mapx + large; + } + + if (y_ > mapy + large + 32) { + y_ = mapy + large + 32; + } + + x_camera_ = x_player_ + 0x07; + y_camera_ = y_player_ + 0x1F; + + if (x_camera_ < mapx + 127) { + x_camera_ = mapx + 127; + } + + if (y_camera_ < mapy + 111) { + y_camera_ = mapy + 111; + } + + if (x_camera_ > mapx + 127 + large) { + x_camera_ = mapx + 127 + large; + } + + if (y_camera_ > mapy + 143 + large) { + y_camera_ = mapy + 143 + large; + } + } + + short vram_x_scroll = (short)(x_ - mapx); + short vram_y_scroll = (short)(y_ - mapy); + + map_pos_ = (uint16_t)(((vram_y_scroll & 0xFFF0) << 3) | + ((vram_x_scroll & 0xFFF0) >> 3)); + + std::cout << "Exit: " << room_id_ << " MapId: " << std::hex << mapid + << " X: " << static_cast(area_x_) + << " Y: " << static_cast(area_y_) << std::endl; + } +}; + +} // namespace overworld +} // namespace zelda3 +} // namespace app +} // namespace yaze + +#endif // YAZE_APP_ZELDA3_OVERWORLD_EXIT_H_ diff --git a/src/app/zelda3/overworld/overworld_item.h b/src/app/zelda3/overworld/overworld_item.h new file mode 100644 index 00000000..62b0a0e9 --- /dev/null +++ b/src/app/zelda3/overworld/overworld_item.h @@ -0,0 +1,108 @@ +#ifndef YAZE_APP_ZELDA3_OVERWORLD_ITEM_H_ +#define YAZE_APP_ZELDA3_OVERWORLD_ITEM_H_ + +#include +#include +#include +#include +#include + +#include "app/zelda3/common.h" + +namespace yaze { +namespace app { +namespace zelda3 { +namespace overworld { + +// List of secret item names +const std::vector kSecretItemNames = { + "Nothing", // 0 + "Green Rupee", // 1 + "Rock hoarder", // 2 + "Bee", // 3 + "Health pack", // 4 + "Bomb", // 5 + "Heart ", // 6 + "Blue Rupee", // 7 + "Key", // 8 + "Arrow", // 9 + "Bomb", // 10 + "Heart", // 11 + "Magic", // 12 + "Full Magic", // 13 + "Cucco", // 14 + "Green Soldier", // 15 + "Bush Stal", // 16 + "Blue Soldier", // 17 + "Landmine", // 18 + "Heart", // 19 + "Fairy", // 20 + "Heart", // 21 + "Nothing ", // 22 + "Hole", // 23 + "Warp", // 24 + "Staircase", // 25 + "Bombable", // 26 + "Switch" // 27 +}; + +constexpr int overworldItemsPointers = 0xDC2F9; +constexpr int kOverworldItemsAddress = 0xDC8B9; // 1BC2F9 +constexpr int overworldItemsBank = 0xDC8BF; +constexpr int overworldItemsEndData = 0xDC89C; // 0DC89E + +class OverworldItem : public GameEntity { +public: + bool bg2_ = false; + uint8_t id_; + uint8_t game_x_; + uint8_t game_y_; + uint16_t room_map_id_; + int unique_id = 0; + bool deleted = false; + OverworldItem() = default; + + OverworldItem(uint8_t id, uint16_t room_map_id, int x, int y, bool bg2) { + this->id_ = id; + this->x_ = x; + this->y_ = y; + this->bg2_ = bg2; + this->room_map_id_ = room_map_id; + this->map_id_ = room_map_id; + this->entity_id_ = id; + this->entity_type_ = kItem; + + int map_x = room_map_id - ((room_map_id / 8) * 8); + int map_y = room_map_id / 8; + + game_x_ = static_cast(std::abs(x - (map_x * 512)) / 16); + game_y_ = static_cast(std::abs(y - (map_y * 512)) / 16); + } + + void UpdateMapProperties(uint16_t room_map_id) override { + room_map_id_ = room_map_id; + + if (room_map_id_ >= 64) { + room_map_id_ -= 64; + } + + int map_x = room_map_id_ - ((room_map_id_ / 8) * 8); + int map_y = room_map_id_ / 8; + + game_x_ = static_cast(std::abs(x_ - (map_x * 512)) / 16); + game_y_ = static_cast(std::abs(y_ - (map_y * 512)) / 16); + + std::cout << "Item: " << std::hex << std::setw(2) << std::setfill('0') + << static_cast(id_) << " MapId: " << std::hex << std::setw(2) + << std::setfill('0') << static_cast(room_map_id_) + << " X: " << static_cast(game_x_) + << " Y: " << static_cast(game_y_) << std::endl; + } +}; + +} // namespace overworld +} // namespace zelda3 +} // namespace app +} // namespace yaze + +#endif // YAZE_APP_ZELDA3_OVERWORLD_ITEM_H_