Update Room, Add RoomObject, RoomNames
This commit is contained in:
@@ -9,7 +9,7 @@ project(yaze VERSION 0.01)
|
|||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
set(CMAKE_CXX_EXTENSIONS ON)
|
set(CMAKE_CXX_EXTENSIONS ON)
|
||||||
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||||
@@ -52,10 +52,11 @@ find_library(SDL_MIXER_LIBRARY
|
|||||||
PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
|
PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
|
||||||
)
|
)
|
||||||
add_subdirectory(src/lib/SDL_mixer)
|
add_subdirectory(src/lib/SDL_mixer)
|
||||||
|
find_package(SDL2_image)
|
||||||
|
|
||||||
# Asar ------------------------------------------------------------------------
|
# Asar ------------------------------------------------------------------------
|
||||||
add_subdirectory(src/lib/asar/src)
|
# add_subdirectory(src/lib/asar/src)
|
||||||
include(cmake/asar.cmake)
|
# include(cmake/asar.cmake)
|
||||||
|
|
||||||
# snes-spc --------------------------------------------------------------------
|
# snes-spc --------------------------------------------------------------------
|
||||||
ADD_DEFINITIONS(-DSNES_SPC_EXPORTS)
|
ADD_DEFINITIONS(-DSNES_SPC_EXPORTS)
|
||||||
|
|||||||
@@ -1,107 +1,364 @@
|
|||||||
#include "room.h"
|
#include "room.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "app/core/common.h"
|
#include "app/core/common.h"
|
||||||
|
#include "app/core/constants.h"
|
||||||
#include "app/gfx/bitmap.h"
|
#include "app/gfx/bitmap.h"
|
||||||
#include "app/gfx/snes_palette.h"
|
#include "app/gfx/snes_palette.h"
|
||||||
#include "app/gfx/snes_tile.h"
|
#include "app/gfx/snes_tile.h"
|
||||||
#include "app/gui/canvas.h"
|
#include "app/gui/canvas.h"
|
||||||
#include "app/rom.h"
|
#include "app/rom.h"
|
||||||
|
#include "app/zelda3/dungeon/room_object.h"
|
||||||
|
#include "app/zelda3/sprite/sprite.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace zelda3 {
|
namespace zelda3 {
|
||||||
namespace dungeon {
|
namespace dungeon {
|
||||||
|
|
||||||
|
void DrawDungeonRoomBG1(std::vector<uint8_t>& tiles_bg1_buffer,
|
||||||
|
std::vector<uint8_t>& current_gfx16,
|
||||||
|
std::vector<uint8_t>& room_bg1_data) {
|
||||||
|
for (int yy = 0; yy < 64; ++yy) {
|
||||||
|
for (int xx = 0; xx < 64; ++xx) {
|
||||||
|
if (tiles_bg1_buffer[xx + (yy * 64)] != 0xFFFF) {
|
||||||
|
auto t = gfx::GetTilesInfo(tiles_bg1_buffer[xx + (yy * 64)]);
|
||||||
|
for (int yl = 0; yl < 8; ++yl) {
|
||||||
|
for (int xl = 0; xl < 4; ++xl) {
|
||||||
|
int mx = xl * (1 - t.horizontal_mirror_) +
|
||||||
|
(3 - xl) * t.horizontal_mirror_;
|
||||||
|
int my =
|
||||||
|
yl * (1 - t.vertical_mirror_) + (7 - yl) * t.vertical_mirror_;
|
||||||
|
|
||||||
|
int ty = (t.id_ / 16) * 512;
|
||||||
|
int tx = (t.id_ % 16) * 4;
|
||||||
|
uint8_t pixel = current_gfx16[(tx + ty) + (yl * 64) + xl];
|
||||||
|
|
||||||
|
int index = (xx * 8) + (yy * 4096) + ((mx * 2) + (my * 512));
|
||||||
|
room_bg1_data[index + t.horizontal_mirror_ ^ 1] =
|
||||||
|
static_cast<uint8_t>((pixel & 0x0F) + t.palette_ * 16);
|
||||||
|
room_bg1_data[index + t.horizontal_mirror_] =
|
||||||
|
static_cast<uint8_t>(((pixel >> 4) & 0x0F) + t.palette_ * 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawDungeonRoomBG2(std::vector<uint8_t>& tiles_bg2_buffer,
|
||||||
|
std::vector<uint8_t>& current_gfx16,
|
||||||
|
std::vector<uint8_t>& room_bg2_data) {
|
||||||
|
for (int yy = 0; yy < 64; ++yy) {
|
||||||
|
for (int xx = 0; xx < 64; ++xx) {
|
||||||
|
if (tiles_bg2_buffer[xx + (yy * 64)] != 0xFFFF) {
|
||||||
|
auto t = gfx::GetTilesInfo(tiles_bg2_buffer[xx + (yy * 64)]);
|
||||||
|
for (int yl = 0; yl < 8; ++yl) {
|
||||||
|
for (int xl = 0; xl < 4; ++xl) {
|
||||||
|
int mx = xl * (1 - t.horizontal_mirror_) +
|
||||||
|
(3 - xl) * t.horizontal_mirror_;
|
||||||
|
int my =
|
||||||
|
yl * (1 - t.vertical_mirror_) + (7 - yl) * t.vertical_mirror_;
|
||||||
|
|
||||||
|
int ty = (t.id_ / 16) * 512;
|
||||||
|
int tx = (t.id_ % 16) * 4;
|
||||||
|
uint8_t pixel = current_gfx16[(tx + ty) + (yl * 64) + xl];
|
||||||
|
|
||||||
|
int index = (xx * 8) + (yy * 4096) + ((mx * 2) + (my * 512));
|
||||||
|
room_bg2_data[index + t.horizontal_mirror_ ^ 1] =
|
||||||
|
static_cast<uint8_t>((pixel & 0x0F) + t.palette_ * 16);
|
||||||
|
room_bg2_data[index + t.horizontal_mirror_] =
|
||||||
|
static_cast<uint8_t>(((pixel >> 4) & 0x0F) + t.palette_ * 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================================================================
|
||||||
|
|
||||||
void Room::LoadGfxGroups() {
|
void Room::LoadGfxGroups() {
|
||||||
|
auto rom_data = rom()->vector();
|
||||||
int gfxPointer =
|
int gfxPointer =
|
||||||
(rom_[gfx_groups_pointer + 1] << 8) + rom_[gfx_groups_pointer];
|
(rom_data[gfx_groups_pointer + 1] << 8) + rom_data[gfx_groups_pointer];
|
||||||
gfxPointer = core::SnesToPc(gfxPointer);
|
gfxPointer = core::SnesToPc(gfxPointer);
|
||||||
|
|
||||||
for (int i = 0; i < 37; i++) {
|
for (int i = 0; i < 37; i++) {
|
||||||
for (int j = 0; j < 8; j++) {
|
for (int j = 0; j < 8; j++) {
|
||||||
mainGfx[i][j] = rom_[gfxPointer + (i * 8) + j];
|
mainGfx[i][j] = rom_data[gfxPointer + (i * 8) + j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 82; i++) {
|
for (int i = 0; i < 82; i++) {
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
roomGfx[i][j] = rom_[entrance_gfx_group + (i * 4) + j];
|
roomGfx[i][j] = rom_data[entrance_gfx_group + (i * 4) + j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 144; i++) {
|
for (int i = 0; i < 144; i++) {
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
spriteGfx[i][j] = rom_[sprite_blockset_pointer + (i * 4) + j];
|
spriteGfx[i][j] = rom_data[sprite_blockset_pointer + (i * 4) + j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 72; i++) {
|
for (int i = 0; i < 72; i++) {
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
paletteGfx[i][j] = rom_[dungeons_palettes_groups + (i * 4) + j];
|
paletteGfx[i][j] = rom_data[dungeons_palettes_groups + (i * 4) + j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Room::SaveGroupsToROM() {
|
bool Room::SaveGroupsToROM() {
|
||||||
|
auto rom_data = rom()->vector();
|
||||||
int gfxPointer =
|
int gfxPointer =
|
||||||
(rom_[gfx_groups_pointer + 1] << 8) + rom_[gfx_groups_pointer];
|
(rom_data[gfx_groups_pointer + 1] << 8) + rom_data[gfx_groups_pointer];
|
||||||
gfxPointer = core::SnesToPc(gfxPointer);
|
gfxPointer = core::SnesToPc(gfxPointer);
|
||||||
|
|
||||||
for (int i = 0; i < 37; i++) {
|
for (int i = 0; i < 37; i++) {
|
||||||
for (int j = 0; j < 8; j++) {
|
for (int j = 0; j < 8; j++) {
|
||||||
rom_.Write(gfxPointer + (i * 8) + j, mainGfx[i][j]);
|
rom()->Write(gfxPointer + (i * 8) + j, mainGfx[i][j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 82; i++) {
|
for (int i = 0; i < 82; i++) {
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
rom_.Write(entrance_gfx_group + (i * 4) + j, roomGfx[i][j]);
|
rom()->Write(entrance_gfx_group + (i * 4) + j, roomGfx[i][j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 144; i++) {
|
for (int i = 0; i < 144; i++) {
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
rom_.Write(sprite_blockset_pointer + (i * 4) + j, spriteGfx[i][j]);
|
rom()->Write(sprite_blockset_pointer + (i * 4) + j, spriteGfx[i][j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 72; i++) {
|
for (int i = 0; i < 72; i++) {
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
rom_.Write(dungeons_palettes_groups + (i * 4) + j, paletteGfx[i][j]);
|
rom()->Write(dungeons_palettes_groups + (i * 4) + j, paletteGfx[i][j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Room::LoadChests() {
|
void Room::LoadSprites() {
|
||||||
// ChestList.Clear();
|
auto rom_data = rom()->vector();
|
||||||
|
int spritePointer = (0x04 << 16) + (rom_data[rooms_sprite_pointer + 1] << 8) +
|
||||||
|
(rom_data[rooms_sprite_pointer]);
|
||||||
|
int sprite_address_snes =
|
||||||
|
(0x09 << 16) + (rom_data[spritePointer + (room_id_ * 2) + 1] << 8) +
|
||||||
|
rom_data[spritePointer + (room_id_ * 2)];
|
||||||
|
|
||||||
// int cpos = rom_.Read24(core::constants::chests_data_pointer1).SNEStoPC();
|
int sprite_address = core::SnesToPc(sprite_address_snes);
|
||||||
// int clength = rom_.Read16(core::constants::chests_length_pointer);
|
bool sortsprites = rom_data[sprite_address] == 1;
|
||||||
|
sprite_address += 1;
|
||||||
|
|
||||||
// for (int i = 0; i < clength; i += 3) {
|
while (true) {
|
||||||
// ushort roomid = (ushort)(rom_.Read16(cpos) & 0x7FFF);
|
uint8_t b1 = rom_data[sprite_address];
|
||||||
// cpos += 2;
|
uint8_t b2 = rom_data[sprite_address + 1];
|
||||||
// uchar item = rom_[cpos++]; // get now so cpos is incremented too
|
uint8_t b3 = rom_data[sprite_address + 2];
|
||||||
|
|
||||||
// if (roomid == RoomID) {
|
if (b1 == 0xFF) {
|
||||||
// ChestList.Add(new DungeonChestItem(ItemReceipt.GetTypeFromID(item)));
|
break;
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
|
// sprites_.emplace_back(this, b3, (b2 & 0x1F), (b1 & 0x1F),
|
||||||
|
// ((b2 & 0xE0) >> 5) + ((b1 & 0x60) >> 2),
|
||||||
|
// (b1 & 0x80) >> 7);
|
||||||
|
|
||||||
|
if (sprites_.size() > 1) {
|
||||||
|
Sprite& spr = sprites_.back();
|
||||||
|
Sprite& prevSprite = sprites_[sprites_.size() - 2];
|
||||||
|
|
||||||
|
if (spr.id() == 0xE4 && spr.x() == 0x00 && spr.y() == 0x1E &&
|
||||||
|
spr.layer() == 1 && spr.subtype() == 0x18) {
|
||||||
|
// prevSprite.keyDrop() = 1;
|
||||||
|
sprites_.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spr.id() == 0xE4 && spr.x() == 0x00 && spr.y() == 0x1D &&
|
||||||
|
spr.layer() == 1 && spr.subtype() == 0x18) {
|
||||||
|
// prevSprite.keyDrop() = 2;
|
||||||
|
sprites_.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sprite_address += 3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Room::LoadBlocks() {}
|
void Room::LoadChests() {
|
||||||
|
auto rom_data = rom()->vector();
|
||||||
|
int cpos = (rom_data[chests_data_pointer1 + 2] << 16) +
|
||||||
|
(rom_data[chests_data_pointer1 + 1] << 8) +
|
||||||
|
(rom_data[chests_data_pointer1]);
|
||||||
|
cpos = core::SnesToPc(cpos);
|
||||||
|
int clength = (rom_data[chests_length_pointer + 1] << 8) +
|
||||||
|
(rom_data[chests_length_pointer]);
|
||||||
|
|
||||||
void Room::LoadTorches() {}
|
for (int i = 0; i < clength; i++) {
|
||||||
|
if ((((rom_data[cpos + (i * 3) + 1] << 8) + (rom_data[cpos + (i * 3)])) &
|
||||||
|
0x7FFF) == room_id_) {
|
||||||
|
// There's a chest in that room !
|
||||||
|
bool big = false;
|
||||||
|
if ((((rom_data[cpos + (i * 3) + 1] << 8) + (rom_data[cpos + (i * 3)])) &
|
||||||
|
0x8000) == 0x8000) // ?????
|
||||||
|
{
|
||||||
|
big = true;
|
||||||
|
}
|
||||||
|
|
||||||
void Room::LoadSecrets() {}
|
chests_in_room.emplace_back(ChestData(rom_data[cpos + (i * 3) + 2], big));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Room::Resync() {}
|
void Room::LoadObjects() {
|
||||||
|
auto rom_data = rom()->vector();
|
||||||
|
int objectPointer = (rom_data[room_object_pointer + 2] << 16) +
|
||||||
|
(rom_data[room_object_pointer + 1] << 8) +
|
||||||
|
(rom_data[room_object_pointer]);
|
||||||
|
objectPointer = core::SnesToPc(objectPointer);
|
||||||
|
int room_address = objectPointer + (room_id_ * 3);
|
||||||
|
|
||||||
void Room::LoadObjectsFromArray(int loc) {}
|
int tile_address = (rom_data[room_address + 2] << 16) +
|
||||||
|
(rom_data[room_address + 1] << 8) + rom_data[room_address];
|
||||||
|
|
||||||
void Room::LoadSpritesFromArray(int loc) {}
|
int objects_location = core::SnesToPc(tile_address);
|
||||||
|
|
||||||
|
if (objects_location == 0x52CA2) {
|
||||||
|
std::cout << "Room ID : " << room_id_ << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (floor) {
|
||||||
|
floor1 = static_cast<uint8_t>(rom_data[objects_location] & 0x0F);
|
||||||
|
floor2 = static_cast<uint8_t>((rom_data[objects_location] >> 4) & 0x0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
layout = static_cast<uint8_t>((rom_data[objects_location + 1] >> 2) & 0x07);
|
||||||
|
|
||||||
|
LoadChests();
|
||||||
|
|
||||||
|
staircaseRooms.clear();
|
||||||
|
int nbr_of_staircase = 0;
|
||||||
|
|
||||||
|
int pos = objects_location + 2;
|
||||||
|
uint8_t b1 = 0;
|
||||||
|
uint8_t b2 = 0;
|
||||||
|
uint8_t b3 = 0;
|
||||||
|
uint8_t posX = 0;
|
||||||
|
uint8_t posY = 0;
|
||||||
|
uint8_t sizeX = 0;
|
||||||
|
uint8_t sizeY = 0;
|
||||||
|
uint8_t sizeXY = 0;
|
||||||
|
short oid = 0;
|
||||||
|
int layer = 0;
|
||||||
|
bool door = false;
|
||||||
|
bool endRead = false;
|
||||||
|
while (!endRead) {
|
||||||
|
b1 = rom_data[pos];
|
||||||
|
b2 = rom_data[pos + 1];
|
||||||
|
|
||||||
|
if (b1 == 0xFF && b2 == 0xFF) {
|
||||||
|
pos += 2; // We jump to layer2
|
||||||
|
layer++;
|
||||||
|
door = false;
|
||||||
|
if (layer == 3) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b1 == 0xF0 && b2 == 0xFF) {
|
||||||
|
pos += 2; // We jump to layer2
|
||||||
|
door = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
b3 = rom_data[pos + 2];
|
||||||
|
if (door) {
|
||||||
|
pos += 2;
|
||||||
|
} else {
|
||||||
|
pos += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!door) {
|
||||||
|
if (b3 >= 0xF8) {
|
||||||
|
oid = static_cast<short>((b3 << 4) |
|
||||||
|
0x80 + (((b2 & 0x03) << 2) + ((b1 & 0x03))));
|
||||||
|
posX = static_cast<uint8_t>((b1 & 0xFC) >> 2);
|
||||||
|
posY = static_cast<uint8_t>((b2 & 0xFC) >> 2);
|
||||||
|
sizeXY = static_cast<uint8_t>((((b1 & 0x03) << 2) + (b2 & 0x03)));
|
||||||
|
} else {
|
||||||
|
oid = b3;
|
||||||
|
posX = static_cast<uint8_t>((b1 & 0xFC) >> 2);
|
||||||
|
posY = static_cast<uint8_t>((b2 & 0xFC) >> 2);
|
||||||
|
sizeX = static_cast<uint8_t>((b1 & 0x03));
|
||||||
|
sizeY = static_cast<uint8_t>((b2 & 0x03));
|
||||||
|
sizeXY = static_cast<uint8_t>(((sizeX << 2) + sizeY));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b1 >= 0xFC) {
|
||||||
|
oid = static_cast<short>((b3 & 0x3F) + 0x100);
|
||||||
|
posX = static_cast<uint8_t>(((b2 & 0xF0) >> 4) + ((b1 & 0x3) << 4));
|
||||||
|
posY = static_cast<uint8_t>(((b2 & 0x0F) << 2) + ((b3 & 0xC0) >> 6));
|
||||||
|
sizeXY = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RoomObject r =
|
||||||
|
AddObject(oid, posX, posY, sizeXY, static_cast<uint8_t>(layer));
|
||||||
|
|
||||||
|
/**
|
||||||
|
if (r != nullptr) {
|
||||||
|
tilesObjects.push_back(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (short stair : stairsObjects) {
|
||||||
|
if (stair == oid) {
|
||||||
|
if (nbr_of_staircase < 4) {
|
||||||
|
tilesObjects.back().options |= ObjectOption::Stairs;
|
||||||
|
staircaseRooms.push_back(StaircaseRoom(
|
||||||
|
posX, posY, "To " + staircase_rooms[nbr_of_staircase]));
|
||||||
|
nbr_of_staircase++;
|
||||||
|
} else {
|
||||||
|
tilesObjects.back().options |= ObjectOption::Stairs;
|
||||||
|
staircaseRooms.push_back(StaircaseRoom(posX, posY, "To ???"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oid == 0xF99) {
|
||||||
|
if (chests_in_room.size() > 0) {
|
||||||
|
tilesObjects.back().options |= ObjectOption::Chest;
|
||||||
|
chest_list.push_back(
|
||||||
|
Chest(posX, posY, chests_in_room.front().itemIn, false));
|
||||||
|
chests_in_room.erase(chests_in_room.begin());
|
||||||
|
}
|
||||||
|
} else if (oid == 0xFB1) {
|
||||||
|
if (chests_in_room.size() > 0) {
|
||||||
|
tilesObjects.back().options |= ObjectOption::Chest;
|
||||||
|
chest_list.push_back(
|
||||||
|
Chest(posX + 1, posY, chests_in_room.front().itemIn, true));
|
||||||
|
chests_in_room.erase(chests_in_room.begin());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tilesObjects.push_back(object_door(static_cast<short>((b2 << 8) + b1), 0,
|
||||||
|
0, 0, static_cast<uint8_t>(layer)));
|
||||||
|
}
|
||||||
|
|
||||||
|
**/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
void Room::LoadRoomGraphics(uchar entrance_blockset) {
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
@@ -127,7 +384,7 @@ void Room::LoadRoomGraphics(uchar entrance_blockset) {
|
|||||||
blocks[12 + i] = (uchar)(spriteGfx[SpriteTileset + 64][i] + 115);
|
blocks[12 + i] = (uchar)(spriteGfx[SpriteTileset + 64][i] + 115);
|
||||||
} // 12-16 sprites
|
} // 12-16 sprites
|
||||||
|
|
||||||
auto newPdata = rom_.GetGraphicsBuffer();
|
auto newPdata = rom()->GetGraphicsBuffer();
|
||||||
|
|
||||||
uchar* sheetsData = current_graphics_.data();
|
uchar* sheetsData = current_graphics_.data();
|
||||||
// Into "room gfx16" 16 of them
|
// Into "room gfx16" 16 of them
|
||||||
@@ -157,8 +414,8 @@ void Room::LoadRoomGraphics(uchar entrance_blockset) {
|
|||||||
void Room::LoadAnimatedGraphics() {
|
void Room::LoadAnimatedGraphics() {
|
||||||
int gfxanimatedPointer = core::SnesToPc(gfx_animated_pointer);
|
int gfxanimatedPointer = core::SnesToPc(gfx_animated_pointer);
|
||||||
|
|
||||||
auto newPdata = rom_.GetGraphicsBuffer();
|
auto newPdata = rom()->GetGraphicsBuffer();
|
||||||
|
auto rom_data = rom()->vector();
|
||||||
uchar* sheetsData = current_graphics_.data();
|
uchar* sheetsData = current_graphics_.data();
|
||||||
int data = 0;
|
int data = 0;
|
||||||
while (data < 512) {
|
while (data < 512) {
|
||||||
@@ -166,7 +423,8 @@ void Room::LoadAnimatedGraphics() {
|
|||||||
sheetsData[data + (7 * 2048)] = mapByte;
|
sheetsData[data + (7 * 2048)] = mapByte;
|
||||||
|
|
||||||
mapByte =
|
mapByte =
|
||||||
newPdata[data + (rom_[gfxanimatedPointer + BackgroundTileset] * 2048) +
|
newPdata[data +
|
||||||
|
(rom_data[gfxanimatedPointer + BackgroundTileset] * 2048) +
|
||||||
(512 * animated_frame)];
|
(512 * animated_frame)];
|
||||||
sheetsData[data + (7 * 2048) - 512] = mapByte;
|
sheetsData[data + (7 * 2048) - 512] = mapByte;
|
||||||
data++;
|
data++;
|
||||||
@@ -175,14 +433,15 @@ void Room::LoadAnimatedGraphics() {
|
|||||||
|
|
||||||
void Room::LoadRoomFromROM() {
|
void Room::LoadRoomFromROM() {
|
||||||
// Load dungeon header
|
// Load dungeon header
|
||||||
|
auto rom_data = rom()->vector();
|
||||||
int headerPointer = core::SnesToPc(room_header_pointer);
|
int headerPointer = core::SnesToPc(room_header_pointer);
|
||||||
|
|
||||||
MessageID = messages_id_dungeon + (RoomID * 2);
|
message_id_ = messages_id_dungeon + (room_id_ * 2);
|
||||||
|
|
||||||
int hpos = core::SnesToPc((rom_[room_header_pointers_bank] << 16) |
|
int hpos = core::SnesToPc((rom_data[room_header_pointers_bank] << 16) |
|
||||||
headerPointer + (RoomID * 2));
|
headerPointer + (room_id_ * 2));
|
||||||
hpos++;
|
hpos++;
|
||||||
uchar b = rom_[hpos];
|
uchar b = rom_data[hpos];
|
||||||
|
|
||||||
Layer2Mode = (uchar)(b >> 5);
|
Layer2Mode = (uchar)(b >> 5);
|
||||||
// TODO(@scawful): Make LayerMerging object.
|
// TODO(@scawful): Make LayerMerging object.
|
||||||
@@ -191,65 +450,54 @@ void Room::LoadRoomFromROM() {
|
|||||||
IsDark = (b & 0x01) == 0x01;
|
IsDark = (b & 0x01) == 0x01;
|
||||||
hpos++;
|
hpos++;
|
||||||
|
|
||||||
Palette = rom_[hpos];
|
Palette = rom_data[hpos];
|
||||||
hpos++;
|
hpos++;
|
||||||
|
|
||||||
BackgroundTileset = rom_[hpos];
|
BackgroundTileset = rom_data[hpos];
|
||||||
hpos++;
|
hpos++;
|
||||||
|
|
||||||
SpriteTileset = rom_[hpos];
|
SpriteTileset = rom_data[hpos];
|
||||||
hpos++;
|
hpos++;
|
||||||
|
|
||||||
Layer2Behavior = rom_[hpos];
|
Layer2Behavior = rom_data[hpos];
|
||||||
hpos++;
|
hpos++;
|
||||||
|
|
||||||
Tag1 = rom_[hpos];
|
Tag1 = rom_data[hpos];
|
||||||
hpos++;
|
hpos++;
|
||||||
|
|
||||||
Tag2 = rom_[hpos];
|
Tag2 = rom_data[hpos];
|
||||||
hpos++;
|
hpos++;
|
||||||
|
|
||||||
b = rom_[hpos];
|
b = rom_data[hpos];
|
||||||
|
|
||||||
Pits.TargetLayer = (uchar)(b & 0x03);
|
Pits.TargetLayer = (uchar)(b & 0x03);
|
||||||
Stair1.TargetLayer = (uchar)((b >> 2) & 0x03);
|
Stair1.TargetLayer = (uchar)((b >> 2) & 0x03);
|
||||||
Stair2.TargetLayer = (uchar)((b >> 4) & 0x03);
|
Stair2.TargetLayer = (uchar)((b >> 4) & 0x03);
|
||||||
Stair3.TargetLayer = (uchar)((b >> 6) & 0x03);
|
Stair3.TargetLayer = (uchar)((b >> 6) & 0x03);
|
||||||
hpos++;
|
hpos++;
|
||||||
Stair4.TargetLayer = (uchar)(rom_[hpos] & 0x03);
|
Stair4.TargetLayer = (uchar)(rom_data[hpos] & 0x03);
|
||||||
hpos++;
|
hpos++;
|
||||||
|
|
||||||
Pits.Target = rom_[hpos];
|
Pits.Target = rom_data[hpos];
|
||||||
hpos++;
|
hpos++;
|
||||||
Stair1.Target = rom_[hpos];
|
Stair1.Target = rom_data[hpos];
|
||||||
hpos++;
|
hpos++;
|
||||||
Stair2.Target = rom_[hpos];
|
Stair2.Target = rom_data[hpos];
|
||||||
hpos++;
|
hpos++;
|
||||||
Stair3.Target = rom_[hpos];
|
Stair3.Target = rom_data[hpos];
|
||||||
hpos++;
|
hpos++;
|
||||||
Stair4.Target = rom_[hpos];
|
Stair4.Target = rom_data[hpos];
|
||||||
hpos++;
|
hpos++;
|
||||||
|
|
||||||
// Load room objects
|
// Load room objects
|
||||||
int objectPointer = core::SnesToPc(room_object_pointer);
|
// int objectPointer = core::SnesToPc(room_object_pointer);
|
||||||
int room_address = objectPointer + (RoomID * 3);
|
// int room_address = objectPointer + (room_id_ * 3);
|
||||||
|
// int objects_location = core::SnesToPc(room_address);
|
||||||
int objects_location = core::SnesToPc(room_address);
|
|
||||||
|
|
||||||
LoadObjectsFromArray(objects_location);
|
|
||||||
|
|
||||||
// Load sprites
|
// Load sprites
|
||||||
int spr_ptr = 0x040000 | rooms_sprite_pointer;
|
// int spr_ptr = 0x040000 | rooms_sprite_pointer;
|
||||||
int sprite_address =
|
// int sprite_address =
|
||||||
core::SnesToPc(dungeon_spr_ptrs | spr_ptr + (RoomID * 2));
|
// core::SnesToPc(dungeon_spr_ptrs | spr_ptr + (room_id_ * 2));
|
||||||
LoadSpritesFromArray(sprite_address);
|
|
||||||
|
|
||||||
// Load other stuff
|
|
||||||
LoadChests();
|
|
||||||
LoadBlocks();
|
|
||||||
LoadTorches();
|
|
||||||
LoadSecrets();
|
|
||||||
Resync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace dungeon
|
} // namespace dungeon
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#ifndef YAZE_APP_ZELDA3_DUNGEON_ROOM_H
|
#ifndef YAZE_APP_ZELDA3_DUNGEON_ROOM_H
|
||||||
#define YAZE_APP_ZELDA3_DUNGEON_ROOM_H
|
#define YAZE_APP_ZELDA3_DUNGEON_ROOM_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "app/core/common.h"
|
#include "app/core/common.h"
|
||||||
#include "app/core/constants.h"
|
#include "app/core/constants.h"
|
||||||
#include "app/gfx/bitmap.h"
|
#include "app/gfx/bitmap.h"
|
||||||
@@ -8,6 +11,9 @@
|
|||||||
#include "app/gfx/snes_tile.h"
|
#include "app/gfx/snes_tile.h"
|
||||||
#include "app/gui/canvas.h"
|
#include "app/gui/canvas.h"
|
||||||
#include "app/rom.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 yaze {
|
||||||
namespace app {
|
namespace app {
|
||||||
@@ -82,37 +88,68 @@ constexpr int door_pos_right = 0x19C6;
|
|||||||
|
|
||||||
constexpr int dungeon_spr_ptrs = 0x090000;
|
constexpr int dungeon_spr_ptrs = 0x090000;
|
||||||
|
|
||||||
class Room {
|
constexpr ushort stairsObjects[] = {0x139, 0x138, 0x13B, 0x12E, 0x12D};
|
||||||
public:
|
|
||||||
Room() = default;
|
|
||||||
|
|
||||||
private:
|
void DrawDungeonRoomBG1(std::vector<uint8_t>& tiles_bg1_buffer,
|
||||||
|
std::vector<uint8_t>& current_gfx16,
|
||||||
|
std::vector<uint8_t>& room_bg1_ptr);
|
||||||
|
|
||||||
|
void DrawDungeonRoomBG2(std::vector<uint8_t>& tiles_bg2_buffer,
|
||||||
|
std::vector<uint8_t>& current_gfx16,
|
||||||
|
std::vector<uint8_t>& room_bg2_ptr);
|
||||||
|
|
||||||
|
struct object_door {
|
||||||
|
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(uchar i, bool s) : id_(i), size_(s){};
|
||||||
|
|
||||||
|
uchar id_;
|
||||||
|
bool size_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StaircaseRooms {};
|
||||||
|
|
||||||
|
class Room : public SharedROM {
|
||||||
|
public:
|
||||||
void LoadGfxGroups();
|
void LoadGfxGroups();
|
||||||
bool SaveGroupsToROM();
|
bool SaveGroupsToROM();
|
||||||
void LoadChests();
|
|
||||||
void LoadBlocks();
|
|
||||||
void LoadTorches();
|
|
||||||
void LoadSecrets();
|
|
||||||
void Resync();
|
|
||||||
|
|
||||||
void LoadObjectsFromArray(int loc);
|
void LoadSprites();
|
||||||
void LoadSpritesFromArray(int loc);
|
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 LoadRoomGraphics(uchar entrance_blockset = 0xFF);
|
||||||
void LoadAnimatedGraphics();
|
void LoadAnimatedGraphics();
|
||||||
|
|
||||||
void LoadRoomFromROM();
|
void LoadRoomFromROM();
|
||||||
|
|
||||||
DungeonDestination Pits;
|
private:
|
||||||
DungeonDestination Stair1;
|
|
||||||
DungeonDestination Stair2;
|
|
||||||
DungeonDestination Stair3;
|
|
||||||
DungeonDestination Stair4;
|
|
||||||
|
|
||||||
int animated_frame = 0;
|
int animated_frame = 0;
|
||||||
|
|
||||||
int RoomID = 0;
|
int room_id_ = 0;
|
||||||
ushort MessageID = 0;
|
|
||||||
|
uint8_t floor1;
|
||||||
|
uint8_t floor2;
|
||||||
|
uint8_t blockset;
|
||||||
|
uint8_t spriteset;
|
||||||
|
uint8_t palette;
|
||||||
|
uint8_t layout;
|
||||||
|
|
||||||
|
ushort message_id_ = 0;
|
||||||
uchar BackgroundTileset;
|
uchar BackgroundTileset;
|
||||||
uchar SpriteTileset;
|
uchar SpriteTileset;
|
||||||
uchar Layer2Behavior;
|
uchar Layer2Behavior;
|
||||||
@@ -128,12 +165,25 @@ class Room {
|
|||||||
uint8_t spriteGfx[144][4];
|
uint8_t spriteGfx[144][4];
|
||||||
uint8_t paletteGfx[72][4];
|
uint8_t paletteGfx[72][4];
|
||||||
|
|
||||||
// LayerMergeType LayerMerging;
|
std::vector<zelda3::Sprite> sprites_;
|
||||||
|
std::vector<StaircaseRooms> staircaseRooms;
|
||||||
|
|
||||||
|
DungeonDestination Pits;
|
||||||
|
DungeonDestination Stair1;
|
||||||
|
DungeonDestination Stair2;
|
||||||
|
DungeonDestination Stair3;
|
||||||
|
DungeonDestination Stair4;
|
||||||
|
|
||||||
uchar Tag1;
|
uchar Tag1;
|
||||||
uchar Tag2;
|
uchar Tag2;
|
||||||
bool IsDark;
|
bool IsDark;
|
||||||
|
|
||||||
ROM rom_;
|
bool floor;
|
||||||
|
|
||||||
|
// std::vector<Chest> chest_list;
|
||||||
|
std::vector<ChestData> chests_in_room;
|
||||||
|
std::vector<uint8_t> current_gfx16_;
|
||||||
|
std::vector<RoomObject> tilesObjects;
|
||||||
|
|
||||||
gfx::Bitmap current_graphics_;
|
gfx::Bitmap current_graphics_;
|
||||||
};
|
};
|
||||||
|
|||||||
352
src/app/zelda3/dungeon/room_names.h
Normal file
352
src/app/zelda3/dungeon/room_names.h
Normal file
@@ -0,0 +1,352 @@
|
|||||||
|
#ifndef YAZE_APP_ZELDA3_DUNGEON_ROOM_NAMES_H
|
||||||
|
#define YAZE_APP_ZELDA3_DUNGEON_ROOM_NAMES_H
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
namespace yaze {
|
||||||
|
namespace app {
|
||||||
|
namespace zelda3 {
|
||||||
|
namespace dungeon {
|
||||||
|
|
||||||
|
constexpr std::string_view kRoomNames[] = {
|
||||||
|
"Ganon",
|
||||||
|
"Hyrule Castle (North Corridor)",
|
||||||
|
"Behind Sanctuary (Switch)",
|
||||||
|
"Houlihan",
|
||||||
|
"Turtle Rock (Crysta-Roller)",
|
||||||
|
"Empty",
|
||||||
|
"Swamp Palace (Arrghus[Boss])",
|
||||||
|
"Tower of Hera (Moldorm[Boss])",
|
||||||
|
"Cave (Healing Fairy)",
|
||||||
|
"Palace of Darkness",
|
||||||
|
"Palace of Darkness (Stalfos Trap)",
|
||||||
|
"Palace of Darkness (Turtle)",
|
||||||
|
"Ganon's Tower (Entrance)",
|
||||||
|
"Ganon's Tower (Agahnim2[Boss])",
|
||||||
|
"Ice Palace (Entrance )",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Ganon Evacuation Route",
|
||||||
|
"Hyrule Castle (Bombable Stock )",
|
||||||
|
"Sanctuary",
|
||||||
|
"Turtle Rock (Hokku-Bokku Key 2)",
|
||||||
|
"Turtle Rock (Big Key )",
|
||||||
|
"Turtle Rock",
|
||||||
|
"Swamp Palace (Swimming Treadmill)",
|
||||||
|
"Tower of Hera (Moldorm Fall )",
|
||||||
|
"Cave",
|
||||||
|
"Palace of Darkness (Dark Maze)",
|
||||||
|
"Palace of Darkness (Big Chest )",
|
||||||
|
"Palace of Darkness (Mimics / Moving Wall )",
|
||||||
|
"Ganon's Tower (Ice Armos)",
|
||||||
|
"Ganon's Tower (Final Hallway)",
|
||||||
|
"Ice Palace (Bomb Floor / Bari )",
|
||||||
|
"Ice Palace (Pengator / Big Key )",
|
||||||
|
"Agahnim's Tower (Agahnim[Boss])",
|
||||||
|
"Hyrule Castle (Key-rat )",
|
||||||
|
"Hyrule Castle (Sewer Text Trigger )",
|
||||||
|
"Turtle Rock (West Exit to Balcony)",
|
||||||
|
"Turtle Rock (Double Hokku-Bokku / Big chest )",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Swamp Palace (Statue )",
|
||||||
|
"Tower of Hera (Big Chest)",
|
||||||
|
"Swamp Palace (Entrance )",
|
||||||
|
"Skull Woods (Mothula[Boss])",
|
||||||
|
"Palace of Darkness (Big Hub )",
|
||||||
|
"Palace of Darkness (Map Chest / Fairy )",
|
||||||
|
"Cave",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Ice Palace (Compass )",
|
||||||
|
"Cave (Kakariko Well HP)",
|
||||||
|
"Agahnim's Tower (Maiden Sacrifice Chamber)",
|
||||||
|
"Tower of Hera (Hardhat Beetles )",
|
||||||
|
"Hyrule Castle (Sewer Key Chest )",
|
||||||
|
"Desert Palace (Lanmolas[Boss])",
|
||||||
|
"Swamp Palace (Push Block Puzzle / Pre-Big Key )",
|
||||||
|
"Swamp Palace (Big Key / BS )",
|
||||||
|
"Swamp Palace (Big Chest )",
|
||||||
|
"Swamp Palace (Map Chest / Water Fill )",
|
||||||
|
"Swamp Palace (Key Pot )",
|
||||||
|
"Skull Woods (Gibdo Key / Mothula Hole )",
|
||||||
|
"Palace of Darkness (Bombable Floor )",
|
||||||
|
"Palace of Darkness (Spike Block / Conveyor )",
|
||||||
|
"Cave",
|
||||||
|
"Ganon's Tower (Torch 2)",
|
||||||
|
"Ice Palace (Stalfos Knights / Conveyor Hellway)",
|
||||||
|
"Ice Palace (Map Chest )",
|
||||||
|
"Agahnim's Tower (Final Bridge )",
|
||||||
|
"Hyrule Castle (First Dark )",
|
||||||
|
"Hyrule Castle (6 Ropes )",
|
||||||
|
"Desert Palace (Torch Puzzle / Moving Wall )",
|
||||||
|
"Thieves Town (Big Chest )",
|
||||||
|
"Thieves Town (Jail Cells )",
|
||||||
|
"Swamp Palace (Compass Chest )",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Skull Woods (Gibdo Torch Puzzle )",
|
||||||
|
"Palace of Darkness (Entrance )",
|
||||||
|
"Palace of Darkness (Warps / South Mimics )",
|
||||||
|
"Ganon's Tower (Mini-Helmasaur Conveyor )",
|
||||||
|
"Ganon's Tower (Moldorm )",
|
||||||
|
"Ice Palace (Bomb-Jump )",
|
||||||
|
"Ice Palace Clone (Fairy )",
|
||||||
|
"Hyrule Castle (West Corridor)",
|
||||||
|
"Hyrule Castle (Throne )",
|
||||||
|
"Hyrule Castle (East Corridor)",
|
||||||
|
"Desert Palace (Popos 2 / Beamos Hellway )",
|
||||||
|
"Swamp Palace (Upstairs Pits )",
|
||||||
|
"Castle Secret Entrance / Uncle Death ",
|
||||||
|
"Skull Woods (Key Pot / Trap )",
|
||||||
|
"Skull Woods (Big Key )",
|
||||||
|
"Skull Woods (Big Chest )",
|
||||||
|
"Skull Woods (Final Section Entrance )",
|
||||||
|
"Palace of Darkness (Helmasaur King[Boss])",
|
||||||
|
"Ganon's Tower (Spike Pit )",
|
||||||
|
"Ganon's Tower (Ganon-Ball Z)",
|
||||||
|
"Ganon's Tower (Gauntlet 1/2/3)",
|
||||||
|
"Ice Palace (Lonely Firebar)",
|
||||||
|
"Ice Palace (Hidden Chest / Spike Floor )",
|
||||||
|
"Hyrule Castle (West Entrance )",
|
||||||
|
"Hyrule Castle (Main Entrance )",
|
||||||
|
"Hyrule Castle (East Entrance )",
|
||||||
|
"Desert Palace (Final Section Entrance )",
|
||||||
|
"Thieves Town (West Attic )",
|
||||||
|
"Thieves Town (East Attic )",
|
||||||
|
"Swamp Palace (Hidden Chest / Hidden Door )",
|
||||||
|
"Skull Woods (Compass Chest )",
|
||||||
|
"Skull Woods (Key Chest / Trap )",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Palace of Darkness (Rupee )",
|
||||||
|
"Ganon's Tower (Mimics s)",
|
||||||
|
"Ganon's Tower (Lanmolas )",
|
||||||
|
"Ganon's Tower (Gauntlet 4/5)",
|
||||||
|
"Ice Palace (Pengators )",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Hyrule Castle (Small Corridor to Jail Cells)",
|
||||||
|
"Hyrule Castle (Boomerang Chest )",
|
||||||
|
"Hyrule Castle (Map Chest )",
|
||||||
|
"Desert Palace (Big Chest )",
|
||||||
|
"Desert Palace (Map Chest )",
|
||||||
|
"Desert Palace (Big Key Chest )",
|
||||||
|
"Swamp Palace (Water Drain )",
|
||||||
|
"Tower of Hera (Entrance )",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Ganon's Tower",
|
||||||
|
"Ganon's Tower (East Side Collapsing Bridge / Exploding Wall )",
|
||||||
|
"Ganon's Tower (Winder / Warp Maze )",
|
||||||
|
"Ice Palace (Hidden Chest / Bombable Floor )",
|
||||||
|
"Ice Palace ( Big Spike Traps )",
|
||||||
|
"Hyrule Castle (Jail Cell )",
|
||||||
|
"Hyrule Castle",
|
||||||
|
"Hyrule Castle (Basement Chasm )",
|
||||||
|
"Desert Palace (West Entrance )",
|
||||||
|
"Desert Palace (Main Entrance )",
|
||||||
|
"Desert Palace (East Entrance )",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Tower of Hera (Tile )",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Eastern Palace (Fairy )",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Ganon's Tower (Block Puzzle / Spike Skip / Map Chest )",
|
||||||
|
"Ganon's Tower (East and West Downstairs / Big Chest )",
|
||||||
|
"Ganon's Tower (Tile / Torch Puzzle )",
|
||||||
|
"Ice Palace",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Misery Mire (Vitreous[Boss])",
|
||||||
|
"Misery Mire (Final Switch )",
|
||||||
|
"Misery Mire (Dark Bomb Wall / Switches )",
|
||||||
|
"Misery Mire (Dark Cane Floor Switch Puzzle )",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Ganon's Tower (Final Collapsing Bridge )",
|
||||||
|
"Ganon's Tower (Torches 1 )",
|
||||||
|
"Misery Mire (Torch Puzzle / Moving Wall )",
|
||||||
|
"Misery Mire (Entrance )",
|
||||||
|
"Eastern Palace (Eyegore Key )",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Ganon's Tower (Many Spikes / Warp Maze )",
|
||||||
|
"Ganon's Tower (Invisible Floor Maze )",
|
||||||
|
"Ganon's Tower (Compass Chest / Invisible Floor )",
|
||||||
|
"Ice Palace (Big Chest )",
|
||||||
|
"Ice Palace",
|
||||||
|
"Misery Mire (Pre-Vitreous )",
|
||||||
|
"Misery Mire (Fish )",
|
||||||
|
"Misery Mire (Bridge Key Chest )",
|
||||||
|
"Misery Mire",
|
||||||
|
"Turtle Rock (Trinexx[Boss])",
|
||||||
|
"Ganon's Tower (Wizzrobes s)",
|
||||||
|
"Ganon's Tower (Moldorm Fall )",
|
||||||
|
"Tower of Hera (Fairy )",
|
||||||
|
"Eastern Palace (Stalfos Spawn )",
|
||||||
|
"Eastern Palace (Big Chest )",
|
||||||
|
"Eastern Palace (Map Chest )",
|
||||||
|
"Thieves Town (Moving Spikes / Key Pot )",
|
||||||
|
"Thieves Town (Blind The Thief[Boss])",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Ice Palace",
|
||||||
|
"Ice Palace (Ice Bridge )",
|
||||||
|
"Agahnim's Tower (Circle of Pots)",
|
||||||
|
"Misery Mire (Hourglass )",
|
||||||
|
"Misery Mire (Slug )",
|
||||||
|
"Misery Mire (Spike Key Chest )",
|
||||||
|
"Turtle Rock (Pre-Trinexx )",
|
||||||
|
"Turtle Rock (Dark Maze)",
|
||||||
|
"Turtle Rock (Chain Chomps )",
|
||||||
|
"Turtle Rock (Map Chest / Key Chest / Roller )",
|
||||||
|
"Eastern Palace (Big Key )",
|
||||||
|
"Eastern Palace (Lobby Cannonballs )",
|
||||||
|
"Eastern Palace (Dark Antifairy / Key Pot )",
|
||||||
|
"Thieves Town (Hellway)",
|
||||||
|
"Thieves Town (Conveyor Toilet)",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Ice Palace (Block Puzzle )",
|
||||||
|
"Ice Palace Clone (Switch )",
|
||||||
|
"Agahnim's Tower (Dark Bridge )",
|
||||||
|
"Misery Mire (Compass Chest / Tile )",
|
||||||
|
"Misery Mire (Big Hub )",
|
||||||
|
"Misery Mire (Big Chest )",
|
||||||
|
"Turtle Rock (Final Crystal Switch Puzzle )",
|
||||||
|
"Turtle Rock (Laser Bridge)",
|
||||||
|
"Turtle Rock",
|
||||||
|
"Turtle Rock (Torch Puzzle)",
|
||||||
|
"Eastern Palace (Armos Knights[Boss])",
|
||||||
|
"Eastern Palace (Entrance )",
|
||||||
|
"??",
|
||||||
|
"Thieves Town (North West Entrance )",
|
||||||
|
"Thieves Town (North East Entrance )",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Ice Palace (Hole to Kholdstare )",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Agahnim's Tower (Dark Maze)",
|
||||||
|
"Misery Mire (Conveyor Slug / Big Key )",
|
||||||
|
"Misery Mire (Mire02 / Wizzrobes )",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Turtle Rock (Laser Key )",
|
||||||
|
"Turtle Rock (Entrance )",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Eastern Palace (Zeldagamer / Pre-Armos Knights )",
|
||||||
|
"Eastern Palace (Canonball ",
|
||||||
|
"Eastern Palace",
|
||||||
|
"Thieves Town (Main (South West) Entrance )",
|
||||||
|
"Thieves Town (South East Entrance )",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Ice Palace (Kholdstare[Boss])",
|
||||||
|
"Cave",
|
||||||
|
"Agahnim's Tower (Entrance )",
|
||||||
|
"Cave (Lost Woods HP)",
|
||||||
|
"Cave (Lumberjack's Tree HP)",
|
||||||
|
"Cave (1/2 Magic)",
|
||||||
|
"Cave (Lost Old Man Final Cave)",
|
||||||
|
"Cave (Lost Old Man Final Cave)",
|
||||||
|
"Cave",
|
||||||
|
"Cave",
|
||||||
|
"Cave",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Cave (Spectacle Rock HP)",
|
||||||
|
"Cave",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Cave",
|
||||||
|
"Cave (Spiral Cave)",
|
||||||
|
"Cave (Crystal Switch / 5 Chests )",
|
||||||
|
"Cave (Lost Old Man Starting Cave)",
|
||||||
|
"Cave (Lost Old Man Starting Cave)",
|
||||||
|
"House",
|
||||||
|
"House (Old Woman (Sahasrahla's Wife?))",
|
||||||
|
"House (Angry Brothers)",
|
||||||
|
"House (Angry Brothers)",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Cave",
|
||||||
|
"Cave",
|
||||||
|
"Cave",
|
||||||
|
"Cave",
|
||||||
|
"Empty Clone ",
|
||||||
|
"Cave",
|
||||||
|
"Cave",
|
||||||
|
"Cave",
|
||||||
|
|
||||||
|
"Chest Minigame",
|
||||||
|
"Houses",
|
||||||
|
"Sick Boy house",
|
||||||
|
"Tavern",
|
||||||
|
"Link's House",
|
||||||
|
"Sarashrala Hut",
|
||||||
|
"Chest Minigame",
|
||||||
|
"Library",
|
||||||
|
"Chicken House",
|
||||||
|
"Witch Shop",
|
||||||
|
"A Aginah's Cave",
|
||||||
|
"Dam",
|
||||||
|
"Mimic Cave",
|
||||||
|
"Mire Shed",
|
||||||
|
"Cave",
|
||||||
|
"Shop",
|
||||||
|
"Shop",
|
||||||
|
"Archery Minigame",
|
||||||
|
"DW Church/Shop",
|
||||||
|
"Grave Cave",
|
||||||
|
"Fairy Fountain",
|
||||||
|
"Fairy Upgrade",
|
||||||
|
"Pyramid Fairy",
|
||||||
|
"Spike Cave",
|
||||||
|
"Chest Minigame",
|
||||||
|
"Blind Hut",
|
||||||
|
"Bonzai Cave",
|
||||||
|
"Circle of bush Cave",
|
||||||
|
"Big Bomb Shop, C-House",
|
||||||
|
"Blind Hut 2",
|
||||||
|
"Hype Cave",
|
||||||
|
"Shop",
|
||||||
|
"Ice Cave",
|
||||||
|
"Smith",
|
||||||
|
"Fortune Teller",
|
||||||
|
"MiniMoldorm Cave",
|
||||||
|
"Under Rock Caves",
|
||||||
|
"Smith",
|
||||||
|
"Cave",
|
||||||
|
"Mazeblock Cave",
|
||||||
|
"Smith Peg Cave"};
|
||||||
|
|
||||||
|
class Room_Name {
|
||||||
|
public:
|
||||||
|
static std::vector<std::string> room_name;
|
||||||
|
|
||||||
|
static void loadFromFile(const std::string& file = "DefaultNames.txt") {
|
||||||
|
std::ifstream ifs(file);
|
||||||
|
std::string line;
|
||||||
|
int l = 0;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
while (getline(ifs, line)) {
|
||||||
|
if (line == "[Rooms Names]") {
|
||||||
|
l = 0;
|
||||||
|
found = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
if (line.length() > 0) {
|
||||||
|
if (line[0] == '/' && line[1] == '/') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (l >= 0x4B) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
room_name[l] = line;
|
||||||
|
l++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dungeon
|
||||||
|
} // namespace zelda3
|
||||||
|
} // namespace app
|
||||||
|
} // namespace yaze
|
||||||
|
|
||||||
|
#endif // YAZE_APP_ZELDA3_DUNGEON_ROOM_NAMES_H
|
||||||
87
src/app/zelda3/dungeon/room_object.cc
Normal file
87
src/app/zelda3/dungeon/room_object.cc
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
#include "room_object.h"
|
||||||
|
|
||||||
|
namespace yaze {
|
||||||
|
namespace app {
|
||||||
|
namespace zelda3 {
|
||||||
|
namespace dungeon {
|
||||||
|
|
||||||
|
void RoomObject::DrawTile(Tile t, int xx, int yy,
|
||||||
|
std::vector<uint8_t>& current_gfx16,
|
||||||
|
std::vector<uint8_t>& tiles_bg1_buffer,
|
||||||
|
std::vector<uint8_t>& tiles_bg2_buffer,
|
||||||
|
ushort tileUnder) {
|
||||||
|
if (width < xx + 8) {
|
||||||
|
width = xx + 8;
|
||||||
|
}
|
||||||
|
if (height < yy + 8) {
|
||||||
|
height = yy + 8;
|
||||||
|
}
|
||||||
|
if (preview) {
|
||||||
|
if (xx < 57 && yy < 57 && xx >= 0 && yy >= 0) {
|
||||||
|
gfx::TileInfo ti; // t.GetTileInfo();
|
||||||
|
for (auto yl = 0; yl < 8; yl++) {
|
||||||
|
for (auto xl = 0; xl < 4; xl++) {
|
||||||
|
int mx = xl;
|
||||||
|
int my = yl;
|
||||||
|
uint8_t r = 0;
|
||||||
|
|
||||||
|
if (ti.horizontal_mirror_) {
|
||||||
|
mx = 3 - xl;
|
||||||
|
r = 1;
|
||||||
|
}
|
||||||
|
if (ti.vertical_mirror_) {
|
||||||
|
my = 7 - yl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Formula information to get tile index position in the array.
|
||||||
|
//((ID / nbrofXtiles) * (imgwidth/2) + (ID - ((ID/16)*16) ))
|
||||||
|
int tx =
|
||||||
|
((ti.id_ / 16) * 512) + ((ti.id_ - ((ti.id_ / 16) * 16)) * 4);
|
||||||
|
auto pixel = current_gfx16[tx + (yl * 64) + xl];
|
||||||
|
// nx,ny = object position, xx,yy = tile position, xl,yl = pixel
|
||||||
|
// position
|
||||||
|
|
||||||
|
int index =
|
||||||
|
((xx / 8) * 8) + ((yy / 8) * 512) + ((mx * 2) + (my * 64));
|
||||||
|
preview_object_data_[index + r ^ 1] =
|
||||||
|
(uint8_t)((pixel & 0x0F) + ti.palette_ * 16);
|
||||||
|
preview_object_data_[index + r] =
|
||||||
|
(uint8_t)(((pixel >> 4) & 0x0F) + ti.palette_ * 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (((xx / 8) + nx + offsetX) + ((ny + offsetY + (yy / 8)) * 64) < 4096 &&
|
||||||
|
((xx / 8) + nx + offsetX) + ((ny + offsetY + (yy / 8)) * 64) >= 0) {
|
||||||
|
ushort td = 0; // gfx::GetTilesInfo(); // TODO t.GetTileInfo()
|
||||||
|
|
||||||
|
// collisionPoint.Add(
|
||||||
|
// new Point(xx + ((nx + offsetX) * 8), yy + ((ny + +offsetY) * 8)));
|
||||||
|
|
||||||
|
if (Layer == 0 || (uint8_t)Layer == 2 || allBgs) {
|
||||||
|
if (tileUnder == tiles_bg1_buffer[((xx / 8) + offsetX + nx) +
|
||||||
|
((ny + offsetY + (yy / 8)) * 64)]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tiles_bg1_buffer[((xx / 8) + offsetX + nx) +
|
||||||
|
((ny + offsetY + (yy / 8)) * 64)] = td;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((uint8_t)Layer == 1 || allBgs) {
|
||||||
|
if (tileUnder == tiles_bg2_buffer[((xx / 8) + nx + offsetX) +
|
||||||
|
((ny + offsetY + (yy / 8)) * 64)]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tiles_bg2_buffer[((xx / 8) + nx) + offsetX +
|
||||||
|
((ny + offsetY + (yy / 8)) * 64)] = td;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dungeon
|
||||||
|
} // namespace zelda3
|
||||||
|
} // namespace app
|
||||||
|
} // namespace yaze
|
||||||
169
src/app/zelda3/dungeon/room_object.h
Normal file
169
src/app/zelda3/dungeon/room_object.h
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
#ifndef YAZE_APP_ZELDA3_DUNGEON_ROOM_OBJECT_H
|
||||||
|
#define YAZE_APP_ZELDA3_DUNGEON_ROOM_OBJECT_H
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "app/gfx/snes_palette.h"
|
||||||
|
#include "app/gfx/snes_tile.h"
|
||||||
|
#include "app/rom.h"
|
||||||
|
|
||||||
|
namespace yaze {
|
||||||
|
namespace app {
|
||||||
|
namespace zelda3 {
|
||||||
|
namespace dungeon {
|
||||||
|
|
||||||
|
enum class SpecialObjectType { Chest, BigChest, InterroomStairs };
|
||||||
|
|
||||||
|
struct Tile {};
|
||||||
|
|
||||||
|
enum Background2 {
|
||||||
|
Off,
|
||||||
|
Parallax,
|
||||||
|
Dark,
|
||||||
|
OnTop,
|
||||||
|
Translucent,
|
||||||
|
Addition,
|
||||||
|
Normal,
|
||||||
|
Transparent,
|
||||||
|
DarkRoom // TODO: Determine if DarkRoom will stay there or not
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Sorting {
|
||||||
|
All = 0,
|
||||||
|
Wall = 1,
|
||||||
|
Horizontal = 2,
|
||||||
|
Vertical = 4,
|
||||||
|
NonScalable = 8,
|
||||||
|
Dungeons = 16,
|
||||||
|
Floors = 32,
|
||||||
|
SortStairs = 64
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ObjectOption {
|
||||||
|
Nothing = 0,
|
||||||
|
Door = 1,
|
||||||
|
Chest = 2,
|
||||||
|
Block = 4,
|
||||||
|
Torch = 8,
|
||||||
|
Bgr = 16,
|
||||||
|
Stairs = 32
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LayerType {
|
||||||
|
LayerType(uint8_t t) : type(t) {}
|
||||||
|
|
||||||
|
uint8_t type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RoomObject : public SharedROM {
|
||||||
|
public:
|
||||||
|
enum LayerType { BG1 = 0, BG2 = 1, BG3 = 2 };
|
||||||
|
|
||||||
|
RoomObject(int16_t id, uint8_t x, uint8_t y, uint8_t size, uint8_t layer = 0)
|
||||||
|
: id(id),
|
||||||
|
x_(x),
|
||||||
|
y_(y),
|
||||||
|
size_(size),
|
||||||
|
Layer(static_cast<LayerType>(layer)),
|
||||||
|
nx(x),
|
||||||
|
ny(y),
|
||||||
|
ox(x),
|
||||||
|
oy(y),
|
||||||
|
width(16),
|
||||||
|
height(16),
|
||||||
|
uniqueID(0) {}
|
||||||
|
|
||||||
|
void getObjectSize() {
|
||||||
|
previousSize = size_;
|
||||||
|
size_ = 1;
|
||||||
|
// Draw();
|
||||||
|
getBaseSize();
|
||||||
|
UpdateSize();
|
||||||
|
size_ = 2;
|
||||||
|
// Draw();
|
||||||
|
getSizeSized();
|
||||||
|
UpdateSize();
|
||||||
|
size_ = previousSize;
|
||||||
|
// collisionPoint.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void getBaseSize() {
|
||||||
|
basewidth = width;
|
||||||
|
baseheight = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getSizeSized() {
|
||||||
|
sizeheight = height - baseheight;
|
||||||
|
sizewidth = width - basewidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual void Draw() { collisionPoint.clear(); }
|
||||||
|
|
||||||
|
void UpdateSize() {
|
||||||
|
width = 8;
|
||||||
|
height = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addTiles(int nbr, int pos) {
|
||||||
|
auto rom_data = rom()->data();
|
||||||
|
for (int i = 0; i < nbr; i++) {
|
||||||
|
// tiles.push_back(
|
||||||
|
// gfx::Tile16(rom_data[pos + (i * 2)], rom_data[pos + (i * 2) + 1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawTile(Tile t, int xx, int yy, std::vector<uint8_t>& current_gfx16,
|
||||||
|
std::vector<uint8_t>& tiles_bg1_buffer, std::vector<uint8_t>& tiles_bg2_buffer,
|
||||||
|
ushort tileUnder = 0xFFFF);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int16_t id;
|
||||||
|
|
||||||
|
uint8_t x_;
|
||||||
|
uint8_t y_;
|
||||||
|
uint8_t size_;
|
||||||
|
|
||||||
|
LayerType Layer;
|
||||||
|
|
||||||
|
std::vector<uint8_t> preview_object_data_;
|
||||||
|
|
||||||
|
bool allBgs = false;
|
||||||
|
bool lit = false;
|
||||||
|
std::vector<gfx::Tile16> tiles;
|
||||||
|
int tileIndex = 0;
|
||||||
|
std::string name;
|
||||||
|
uint8_t nx;
|
||||||
|
uint8_t ny;
|
||||||
|
uint8_t ox;
|
||||||
|
uint8_t oy;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int basewidth;
|
||||||
|
int baseheight;
|
||||||
|
int sizewidth;
|
||||||
|
int sizeheight;
|
||||||
|
ObjectOption options = ObjectOption::Nothing;
|
||||||
|
int offsetX = 0;
|
||||||
|
int offsetY = 0;
|
||||||
|
bool diagonalFix = false;
|
||||||
|
bool selected = false;
|
||||||
|
bool redraw = false;
|
||||||
|
bool preview = false;
|
||||||
|
int previewId = 0;
|
||||||
|
uint8_t previousSize = 0;
|
||||||
|
bool showRectangle = false;
|
||||||
|
// std::vector<Point> collisionPoint;
|
||||||
|
int uniqueID = 0;
|
||||||
|
uint8_t z = 0;
|
||||||
|
bool deleted = false;
|
||||||
|
};
|
||||||
|
} // namespace dungeon
|
||||||
|
} // namespace zelda3
|
||||||
|
} // namespace app
|
||||||
|
} // namespace yaze
|
||||||
|
|
||||||
|
#endif // YAZE_APP_ZELDA3_DUNGEON_ROOM_OBJECT_H
|
||||||
Reference in New Issue
Block a user