8#include "absl/strings/str_cat.h"
22 header_pointer =
SnesToPc(header_pointer);
25 (
rom()->data()[(header_pointer + 1) + (
room_id_ * 2)] << 8) +
28 auto header_location =
SnesToPc(address);
32 is_light_ = ((
rom()->data()[header_location]) & 0x01) == 1;
35 bg2_ = background2::DarkRoom;
38 palette = ((
rom()->data()[header_location + 1] & 0x3F));
73 auto room_size_address = 0xF8000 + (
room_id_ * 3);
75 std::cout <<
"Room #" <<
room_id_ <<
" Address: " << std::hex
76 << room_size_address << std::endl;
79 uint8_t low =
rom()->data()[room_size_address];
80 uint8_t high =
rom()->data()[room_size_address + 1];
81 uint8_t bank =
rom()->data()[room_size_address + 2];
84 int long_address = (bank << 16) | (high << 8) | low;
85 std::cout << std::hex << std::setfill(
'0') << std::setw(6) << long_address
89 if (long_address == 0x0A8000) {
91 std::cout <<
"Size of Room #" <<
room_id_ <<
": 0 bytes" << std::endl;
98 int next_room_address = 0xF8000 + ((
room_id_ + 1) * 3);
100 std::cout <<
"Next Room Address: " << std::hex << next_room_address
104 uint8_t next_low =
rom()->data()[next_room_address];
105 uint8_t next_high =
rom()->data()[next_room_address + 1];
106 uint8_t next_bank =
rom()->data()[next_room_address + 2];
109 int next_long_address = (next_bank << 16) | (next_high << 8) | next_low;
111 std::cout << std::hex << std::setfill(
'0') << std::setw(6)
112 << next_long_address << std::endl;
115 int room_size = next_long_address - long_address;
118 <<
" bytes" << std::endl;
120 }
catch (
const std::exception &e) {
121 std::cout <<
"Error: " << e.what() << std::endl;
126 auto rom_data =
rom()->vector();
132 (
rom()->data()[(header_pointer + 1) + (
room_id_ * 2)] << 8) +
137 uint8_t b = rom_data[hpos];
165 pits_.target_layer = (uint8_t)(b & 0x03);
166 stair1_.target_layer = (uint8_t)((b >> 2) & 0x03);
167 stair2_.target_layer = (uint8_t)((b >> 4) & 0x03);
168 stair3_.target_layer = (uint8_t)((b >> 6) & 0x03);
170 stair4_.target_layer = (uint8_t)(rom_data[hpos] & 0x03);
173 pits_.target = rom_data[hpos];
175 stair1_.target = rom_data[hpos];
177 stair2_.target = rom_data[hpos];
179 stair3_.target = rom_data[hpos];
181 stair4_.target = rom_data[hpos];
186 int room_address = object_pointer + (
room_id_ * 3);
187 int objects_location =
SnesToPc(room_address);
196 const auto &main_gfx =
rom()->main_blockset_ids;
197 const auto &room_gfx =
rom()->room_blockset_ids;
198 const auto &sprite_gfx =
rom()->spriteset_ids;
201 for (
int i = 0; i < 8; i++) {
203 if (i >= 6 && i <= 6) {
205 if (entrance_blockset != 0xFF) {
206 if (room_gfx[entrance_blockset][i - 3] != 0) {
207 blocks_[i] = room_gfx[entrance_blockset][i - 3];
217 for (
int i = 0; i < 4; i++) {
232 auto gfx_buffer_data =
rom()->graphics_buffer();
236 for (
int i = 0; i < 16; i++) {
240 uint8_t map_byte = gfx_buffer_data[data + block_offset];
256 int gfx_ptr =
SnesToPc(
rom()->version_constants().kGfxAnimatedPointer);
258 auto gfx_buffer_data =
rom()->graphics_buffer();
259 auto rom_data =
rom()->vector();
267 gfx_buffer_data[data +
276 auto rom_data =
rom()->vector();
280 object_pointer =
SnesToPc(object_pointer);
281 int room_address = object_pointer + (
room_id_ * 3);
283 int tile_address = (rom_data[room_address + 2] << 16) +
284 (rom_data[room_address + 1] << 8) + rom_data[room_address];
286 int objects_location =
SnesToPc(tile_address);
288 if (objects_location == 0x52CA2) {
289 std::cout <<
"Room ID : " <<
room_id_ << std::endl;
295 static_cast<uint8_t
>((rom_data[objects_location] >> 4) & 0x0F);
298 layout =
static_cast<uint8_t
>((rom_data[objects_location + 1] >> 2) & 0x07);
303 int nbr_of_staircase = 0;
305 int pos = objects_location + 2;
317 bool end_read =
false;
320 b2 = rom_data[pos + 1];
322 if (b1 == 0xFF && b2 == 0xFF) {
332 if (b1 == 0xF0 && b2 == 0xFF) {
338 b3 = rom_data[pos + 2];
347 oid =
static_cast<short>((b3 << 4) |
348 0x80 + (((b2 & 0x03) << 2) + ((b1 & 0x03))));
349 posX =
static_cast<uint8_t
>((b1 & 0xFC) >> 2);
350 posY =
static_cast<uint8_t
>((b2 & 0xFC) >> 2);
351 sizeXY =
static_cast<uint8_t
>((((b1 & 0x03) << 2) + (b2 & 0x03)));
354 posX =
static_cast<uint8_t
>((b1 & 0xFC) >> 2);
355 posY =
static_cast<uint8_t
>((b2 & 0xFC) >> 2);
356 sizeX =
static_cast<uint8_t
>((b1 & 0x03));
357 sizeY =
static_cast<uint8_t
>((b2 & 0x03));
358 sizeXY =
static_cast<uint8_t
>(((sizeX << 2) + sizeY));
362 oid =
static_cast<short>((b3 & 0x3F) + 0x100);
363 posX =
static_cast<uint8_t
>(((b2 & 0xF0) >> 4) + ((b1 & 0x3) << 4));
364 posY =
static_cast<uint8_t
>(((b2 & 0x0F) << 2) + ((b3 & 0xC0) >> 6));
368 RoomObject r(oid, posX, posY, sizeXY,
static_cast<uint8_t
>(layer));
373 if (nbr_of_staircase < 4) {
397 }
else if (oid == 0xFB1) {
417 auto rom_data =
rom()->vector();
418 int sprite_pointer = (0x04 << 16) +
421 int sprite_address_snes =
422 (0x09 << 16) + (rom_data[sprite_pointer + (
room_id_ * 2) + 1] << 8) +
423 rom_data[sprite_pointer + (
room_id_ * 2)];
425 int sprite_address =
SnesToPc(sprite_address_snes);
426 bool sortsprites = rom_data[sprite_address] == 1;
430 uint8_t b1 = rom_data[sprite_address];
431 uint8_t b2 = rom_data[sprite_address + 1];
432 uint8_t b3 = rom_data[sprite_address + 2];
438 sprites_.emplace_back(b3, (b2 & 0x1F), (b1 & 0x1F),
439 ((b2 & 0xE0) >> 5) + ((b1 & 0x60) >> 2),
446 if (spr.
id() == 0xE4 && spr.
x() == 0x00 && spr.
y() == 0x1E &&
452 if (spr.
id() == 0xE4 && spr.
x() == 0x00 && spr.
y() == 0x1D &&
464 auto rom_data =
rom()->vector();
471 for (
int i = 0; i < clength; i++) {
472 if ((((rom_data[cpos + (i * 3) + 1] << 8) + (rom_data[cpos + (i * 3)])) &
476 if ((((rom_data[cpos + (i * 3) + 1] << 8) + (rom_data[cpos + (i * 3)])) &
482 chest_data(rom_data[cpos + (i * 3) + 2], big));
std::vector< RoomObject > tile_objects_
uint8_t staircase_plane_[4]
std::vector< zelda3::Sprite > sprites_
std::vector< uint8_t > current_gfx16_
void CopyRoomGraphicsToBuffer()
void LoadRoomGraphics(uint8_t entrance_blockset=0xFF)
uint8_t staircase_rooms_[4]
std::array< uint8_t, 16 > blocks_
int64_t room_size_pointer_
void LoadAnimatedGraphics()
std::vector< chest_data > chests_in_room_
LayerMergeType layer_merging_
std::vector< staircase > z3_staircases_
uint8_t background_tileset_
A class for managing sprites in the overworld and underworld.
auto set_key_drop(int key)
struct chest_data chest_data
struct staircase staircase
Zelda 3 specific classes and functions.
constexpr int kGfxBufferAnimatedFrameStride
constexpr int kGfxBufferAnimatedFrameOffset
constexpr int chests_length_pointer
constexpr int chests_data_pointer1
constexpr int kGfxBufferRoomOffset
constexpr int rooms_sprite_pointer
constexpr int kGfxBufferRoomSpriteOffset
constexpr int messages_id_dungeon
constexpr int kGfxBufferRoomSpriteStride
constexpr uint16_t stairsObjects[]
constexpr int kRoomHeaderPointer
constexpr int kRoomHeaderPointerBank
constexpr int kGfxBufferStride
constexpr int room_object_pointer
constexpr int kGfxBufferRoomSpriteLastLineOffset
constexpr int kGfxBufferOffset
Main namespace for the application.
uint32_t SnesToPc(uint32_t addr) noexcept