#ifndef YAZE_APP_ZELDA3_DUNGEON_ROOM_H #define YAZE_APP_ZELDA3_DUNGEON_ROOM_H #include #include #include "app/core/common.h" #include "app/core/constants.h" #include "app/gfx/bitmap.h" #include "app/gfx/snes_palette.h" #include "app/gfx/snes_tile.h" #include "app/gui/canvas.h" #include "app/rom.h" #include "app/zelda3/dungeon/room_names.h" #include "app/zelda3/dungeon/room_object.h" #include "app/zelda3/sprite/sprite.h" namespace yaze { namespace app { namespace zelda3 { namespace dungeon { // room_object_layout_pointer 0x882D // room_object_pointer 0x874C // 0x882D -> readlong() -> 2FEF04 (04EF2F -> toPC->026F2F) -> // 47EF04 ; layout00 ptr // AFEF04 ; layout01 ptr // F0EF04 ; layout02 ptr // 4CF004 ; layout03 ptr // A8F004 ; layout04 ptr // ECF004 ; layout05 ptr // 48F104 ; layout06 ptr // A4F104 ; layout07 ptr // also they are not exactly the same as rooms // 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 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 kRoomHeaderPointer = 0xB5DD; // LONG constexpr int kRoomHeaderPointerBank = 0xB5E7; // JP Same constexpr int gfx_groups_pointer = 0x6237; constexpr int chests_length_pointer = 0xEBF6; constexpr int chests_data_pointer1 = 0xEBFB; constexpr int messages_id_dungeon = 0x3F61D; 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 sprite_blockset_pointer = 0x5B57; constexpr int sprites_data = 0x4D8B0; 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; constexpr int dungeon_spr_ptrs = 0x090000; constexpr ushort stairsObjects[] = {0x139, 0x138, 0x13B, 0x12E, 0x12D}; class DungeonDestination { public: DungeonDestination() = default; ~DungeonDestination() = default; DungeonDestination(uint8_t i) : Index(i) {} uint8_t Index; uint8_t Target = 0; uint8_t TargetLayer = 0; }; struct object_door { object_door() = default; object_door(short id, uint8_t x, uint8_t y, uint8_t size, uint8_t layer) : id_(id), x_(x), y_(y), size_(size), layer_(layer) {} short id_; uint8_t x_; uint8_t y_; uint8_t size_; uint8_t type_; uint8_t layer_; }; struct ChestData { ChestData() = default; ChestData(uchar i, bool s) : id_(i), size_(s){}; uchar id_; bool size_; }; struct StaircaseRooms {}; class Room : public SharedRom, public core::ExperimentFlags { public: Room() = default; Room(int room_id) : room_id_(room_id) {} ~Room() = default; void LoadHeader(); void LoadRoomFromROM(); void LoadRoomGraphics(uchar entrance_blockset = 0xFF); void CopyRoomGraphicsToBuffer(); void LoadAnimatedGraphics(); void LoadObjects(); void LoadSprites(); void LoadChests(); auto blocks() const { return blocks_; } auto& mutable_blocks() { return blocks_; } auto layer1() const { return background_bmps_[0]; } auto layer2() const { return background_bmps_[1]; } auto layer3() const { return background_bmps_[2]; } auto room_size() const { return room_size_; } auto room_size_ptr() const { return room_size_pointer_; } auto set_room_size(uint64_t size) { room_size_ = size; } 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 blockset = 0; uint8_t spriteset = 0; uint8_t palette = 0; uint8_t layout = 0; uint8_t holewarp = 0; uint8_t floor1 = 0; uint8_t floor2 = 0; uint16_t message_id_ = 0; gfx::Bitmap current_graphics_; std::vector bg1_buffer_; std::vector bg2_buffer_; std::vector current_gfx16_; private: bool is_light_; bool is_loaded_; bool is_dark_; bool is_floor_; int room_id_; int animated_frame_; uchar tag1_; uchar tag2_; uint8_t staircase_plane_[4]; uint8_t staircase_rooms_[4]; uint8_t background_tileset_; uint8_t sprite_tileset_; uint8_t layer2_behavior_; uint8_t palette_; uint8_t floor1_graphics_; uint8_t floor2_graphics_; uint8_t layer2_mode_; uint64_t room_size_; int64_t room_size_pointer_; std::array blocks_; std::array chest_list_; std::array background_bmps_; std::vector sprites_; std::vector staircase_rooms_vec_; Background2 bg2_; DungeonDestination pits_; DungeonDestination stair1_; DungeonDestination stair2_; DungeonDestination stair3_; DungeonDestination stair4_; std::vector chests_in_room_; std::vector tile_objects_; std::vector room_addresses_; }; } // namespace dungeon } // namespace zelda3 } // namespace app } // namespace yaze #endif