8#include "absl/strings/str_cat.h"
37 auto room_size_address = 0xF8000 + (room_id * 3);
38 util::logf(
"Room #%#03X Addresss: %#06X", room_id, room_size_address);
41 uint8_t low = rom->
data()[room_size_address];
42 uint8_t high = rom->
data()[room_size_address + 1];
43 uint8_t bank = rom->
data()[room_size_address + 2];
46 int long_address = (bank << 16) | (high << 8) | low;
47 util::logf(
"%#06X", long_address);
50 if (long_address == 0x0A8000) {
52 util::logf(
"Size of Room #%#03X: 0 bytes", room_id);
59 int next_room_address = 0xF8000 + ((room_id + 1) * 3);
60 util::logf(
"Next Room Address: %#06X", next_room_address);
63 uint8_t next_low = rom->
data()[next_room_address];
64 uint8_t next_high = rom->
data()[next_room_address + 1];
65 uint8_t next_bank = rom->
data()[next_room_address + 2];
68 int next_long_address = (next_bank << 16) | (next_high << 8) | next_low;
69 util::logf(
"%#06X", next_long_address);
72 int actual_room_size = next_long_address - long_address;
74 util::logf(
"Size of Room #%#03X: %d bytes", room_id, actual_room_size);
81 Room room(room_id, rom);
86 header_pointer =
SnesToPc(header_pointer);
89 (rom->
data()[(header_pointer + 1) + (room_id * 2)] << 8) +
90 rom->
data()[(header_pointer) + (room_id * 2)];
92 auto header_location =
SnesToPc(address);
96 room.
is_light_ = ((rom->
data()[header_location]) & 0x01) == 1;
99 room.
bg2_ = background2::DarkRoom;
102 room.
palette = ((rom->
data()[header_location + 1] & 0x3F));
125 header_pointer_2 =
SnesToPc(header_pointer_2);
128 (rom->
data()[(header_pointer_2 + 1) + (room_id * 2)] << 8) +
129 rom->
data()[(header_pointer_2) + (room_id * 2)];
135 uint8_t b = rom->
data()[hpos];
160 b = rom->
data()[hpos];
183 int room_address = object_pointer + (room_id * 3);
184 int objects_location =
SnesToPc(room_address);
194 const auto &room_gfx =
rom()->room_blockset_ids;
195 const auto &sprite_gfx =
rom()->spriteset_ids;
197 for (
int i = 0; i < 8; i++) {
199 if (i >= 6 && i <= 6) {
201 if (entrance_blockset != 0xFF &&
202 room_gfx[entrance_blockset][i - 3] != 0) {
203 blocks_[i] = room_gfx[entrance_blockset][i - 3];
212 for (
int i = 0; i < 4; i++) {
227 auto gfx_buffer_data =
rom()->mutable_graphics_buffer();
231 for (
int i = 0; i < 16; i++) {
235 uint8_t map_byte = (*gfx_buffer_data)[data + block_offset];
262 rom()->mutable_palette_group()->get_group(
"dungeon_main")[0].palette(0);
279 int gfx_ptr =
SnesToPc(
rom()->version_constants().kGfxAnimatedPointer);
281 auto gfx_buffer_data =
rom()->mutable_graphics_buffer();
282 auto rom_data =
rom()->vector();
290 (*gfx_buffer_data)[data +
299 auto rom_data =
rom()->vector();
303 object_pointer =
SnesToPc(object_pointer);
304 int room_address = object_pointer + (
room_id_ * 3);
307 (rom_data[room_address + 1] << 8) + rom_data[room_address];
311 if (objects_location == 0x52CA2) {
312 std::cout <<
"Room ID : " <<
room_id_ << std::endl;
318 static_cast<uint8_t
>((rom_data[objects_location] >> 4) & 0x0F);
321 layout =
static_cast<uint8_t
>((rom_data[objects_location + 1] >> 2) & 0x07);
326 int nbr_of_staircase = 0;
328 int pos = objects_location + 2;
340 bool end_read =
false;
343 b2 = rom_data[pos + 1];
345 if (b1 == 0xFF && b2 == 0xFF) {
355 if (b1 == 0xF0 && b2 == 0xFF) {
361 b3 = rom_data[pos + 2];
370 oid =
static_cast<short>((b3 << 4) |
371 0x80 + (((b2 & 0x03) << 2) + ((b1 & 0x03))));
372 posX =
static_cast<uint8_t
>((b1 & 0xFC) >> 2);
373 posY =
static_cast<uint8_t
>((b2 & 0xFC) >> 2);
374 sizeXY =
static_cast<uint8_t
>((((b1 & 0x03) << 2) + (b2 & 0x03)));
377 posX =
static_cast<uint8_t
>((b1 & 0xFC) >> 2);
378 posY =
static_cast<uint8_t
>((b2 & 0xFC) >> 2);
379 sizeX =
static_cast<uint8_t
>((b1 & 0x03));
380 sizeY =
static_cast<uint8_t
>((b2 & 0x03));
381 sizeXY =
static_cast<uint8_t
>(((sizeX << 2) + sizeY));
385 oid =
static_cast<short>((b3 & 0x3F) + 0x100);
386 posX =
static_cast<uint8_t
>(((b2 & 0xF0) >> 4) + ((b1 & 0x3) << 4));
387 posY =
static_cast<uint8_t
>(((b2 & 0x0F) << 2) + ((b3 & 0xC0) >> 6));
391 RoomObject r(oid, posX, posY, sizeXY,
static_cast<uint8_t
>(layer));
396 if (nbr_of_staircase < 4) {
420 }
else if (oid == 0xFB1) {
440 auto rom_data =
rom()->vector();
441 int sprite_pointer = (0x04 << 16) +
444 int sprite_address_snes =
445 (0x09 << 16) + (rom_data[sprite_pointer + (
room_id_ * 2) + 1] << 8) +
446 rom_data[sprite_pointer + (
room_id_ * 2)];
448 int sprite_address =
SnesToPc(sprite_address_snes);
449 bool sortsprites = rom_data[sprite_address] == 1;
453 uint8_t b1 = rom_data[sprite_address];
454 uint8_t b2 = rom_data[sprite_address + 1];
455 uint8_t b3 = rom_data[sprite_address + 2];
461 sprites_.emplace_back(b3, (b2 & 0x1F), (b1 & 0x1F),
462 ((b2 & 0xE0) >> 5) + ((b1 & 0x60) >> 2),
469 if (spr.
id() == 0xE4 && spr.
x() == 0x00 && spr.
y() == 0x1E &&
475 if (spr.
id() == 0xE4 && spr.
x() == 0x00 && spr.
y() == 0x1D &&
487 auto rom_data =
rom()->vector();
494 for (
int i = 0; i < clength; i++) {
495 if ((((rom_data[cpos + (i * 3) + 1] << 8) + (rom_data[cpos + (i * 3)])) &
499 if ((((rom_data[cpos + (i * 3) + 1] << 8) + (rom_data[cpos + (i * 3)])) &
505 chest_data(rom_data[cpos + (i * 3) + 2], big));
The Rom class is used to load, save, and modify Rom data.
void CreateAndRenderBitmap(int width, int height, int depth, const std::vector< uint8_t > &data, gfx::Bitmap &bitmap, gfx::SnesPalette &palette)
void UpdateBitmap(gfx::Bitmap *bitmap)
std::vector< RoomObject > tile_objects_
uint8_t staircase_plane_[4]
std::vector< zelda3::Sprite > sprites_
std::array< uint8_t, 0x4000 > current_gfx16_
void CopyRoomGraphicsToBuffer()
void LoadRoomGraphics(uint8_t entrance_blockset=0xFF)
void RenderRoomGraphics()
uint8_t staircase_rooms_[4]
std::array< uint8_t, 16 > blocks_
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)
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
RoomSize CalculateRoomSize(Rom *rom, int room_id)
constexpr int messages_id_dungeon
constexpr int tile_address_floor
constexpr int kGfxBufferRoomSpriteStride
constexpr uint16_t stairsObjects[]
Room LoadRoomFromRom(Rom *rom, int room_id)
constexpr int kRoomHeaderPointer
constexpr int kRoomHeaderPointerBank
constexpr int kGfxBufferStride
constexpr int room_object_pointer
constexpr int kGfxBufferRoomSpriteLastLineOffset
constexpr int tile_address
constexpr int dungeon_spr_ptrs
constexpr int kGfxBufferOffset
Main namespace for the application.
uint32_t SnesToPc(uint32_t addr) noexcept
int64_t room_size_pointer
struct chest_data chest_data
struct staircase staircase