remove magic numbers, enforce const correctness
This commit is contained in:
@@ -5,7 +5,7 @@ namespace app {
|
||||
namespace zelda3 {
|
||||
namespace dungeon {
|
||||
|
||||
void DungeonObjectRenderer::LoadObject(uint16_t objectId,
|
||||
void DungeonObjectRenderer::LoadObject(uint32_t routine_ptr,
|
||||
std::array<uint8_t, 16>& sheet_ids) {
|
||||
vram_.sheets = sheet_ids;
|
||||
|
||||
@@ -13,48 +13,14 @@ void DungeonObjectRenderer::LoadObject(uint16_t objectId,
|
||||
// Prepare the CPU and memory environment
|
||||
memory_.Initialize(rom_data_);
|
||||
|
||||
// Fetch the subtype pointers for the given object ID
|
||||
auto subtypeInfo = FetchSubtypeInfo(objectId);
|
||||
|
||||
// Configure the object based on the fetched information
|
||||
ConfigureObject(subtypeInfo);
|
||||
ConfigureObject();
|
||||
|
||||
// Run the CPU emulation for the object's draw routines
|
||||
RenderObject(subtypeInfo);
|
||||
RenderObject(routine_ptr);
|
||||
}
|
||||
|
||||
SubtypeInfo DungeonObjectRenderer::FetchSubtypeInfo(uint16_t object_id) {
|
||||
SubtypeInfo info;
|
||||
|
||||
// Determine the subtype based on objectId
|
||||
uint8_t subtype = 1;
|
||||
|
||||
// Based on the subtype, fetch the correct pointers
|
||||
switch (subtype) {
|
||||
case 1: // Subtype 1
|
||||
info.subtype_ptr = core::subtype1_tiles + (object_id & 0xFF) * 2;
|
||||
info.routine_ptr = core::subtype1_tiles + 0x200 + (object_id & 0xFF) * 2;
|
||||
std::cout << "Subtype 1 " << std::hex << info.subtype_ptr << std::endl;
|
||||
std::cout << "Subtype 1 " << std::hex << info.routine_ptr << std::endl;
|
||||
break;
|
||||
case 2: // Subtype 2
|
||||
info.subtype_ptr = core::subtype2_tiles + (object_id & 0x7F) * 2;
|
||||
info.routine_ptr = core::subtype2_tiles + 0x80 + (object_id & 0x7F) * 2;
|
||||
break;
|
||||
case 3: // Subtype 3
|
||||
info.subtype_ptr = core::subtype3_tiles + (object_id & 0xFF) * 2;
|
||||
info.routine_ptr = core::subtype3_tiles + 0x100 + (object_id & 0xFF) * 2;
|
||||
break;
|
||||
default:
|
||||
// Handle unknown subtype
|
||||
throw std::runtime_error("Unknown subtype for object ID: " +
|
||||
std::to_string(object_id));
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
void DungeonObjectRenderer::ConfigureObject(const SubtypeInfo& info) {
|
||||
void DungeonObjectRenderer::ConfigureObject() {
|
||||
cpu.A = 0x03D8;
|
||||
cpu.X = 0x03D8;
|
||||
cpu.DB = 0x7E;
|
||||
@@ -94,12 +60,12 @@ void DungeonObjectRenderer::ConfigureObject(const SubtypeInfo& info) {
|
||||
#_0198A9: INY #4
|
||||
#_0198AD: RTS
|
||||
*/
|
||||
void DungeonObjectRenderer::RenderObject(const SubtypeInfo& info) {
|
||||
void DungeonObjectRenderer::RenderObject(uint32_t routine_ptr) {
|
||||
cpu.PB = 0x01;
|
||||
|
||||
// Push an initial value to the stack we can read later to confirm we are
|
||||
// done
|
||||
cpu.PushLong(0x01 << 16 | info.routine_ptr);
|
||||
cpu.PushLong(0x01 << 16 | routine_ptr);
|
||||
|
||||
int i = 0;
|
||||
while (true) {
|
||||
|
||||
@@ -23,36 +23,34 @@ struct PseudoVram {
|
||||
std::vector<gfx::SnesPalette> palettes;
|
||||
};
|
||||
|
||||
struct SubtypeInfo {
|
||||
uint32_t subtype_ptr;
|
||||
uint32_t routine_ptr;
|
||||
};
|
||||
|
||||
class DungeonObjectRenderer : public SharedRom {
|
||||
public:
|
||||
DungeonObjectRenderer() = default;
|
||||
|
||||
void LoadObject(uint16_t objectId, std::array<uint8_t, 16>& sheet_ids);
|
||||
void LoadObject(uint32_t routine_ptr, std::array<uint8_t, 16>& sheet_ids);
|
||||
void ConfigureObject();
|
||||
void RenderObject(uint32_t routine_ptr);
|
||||
void UpdateObjectBitmap();
|
||||
|
||||
gfx::Bitmap* bitmap() { return &bitmap_; }
|
||||
auto memory() { return memory_; }
|
||||
auto mutable_memory() { return &memory_; }
|
||||
|
||||
private:
|
||||
SubtypeInfo FetchSubtypeInfo(uint16_t object_id);
|
||||
void ConfigureObject(const SubtypeInfo& info);
|
||||
void RenderObject(const SubtypeInfo& info);
|
||||
void UpdateObjectBitmap();
|
||||
uint16_t pc_with_rts_;
|
||||
|
||||
std::vector<uint8_t> tilemap_;
|
||||
uint16_t pc_with_rts_;
|
||||
std::vector<uint8_t> rom_data_;
|
||||
emu::memory::MemoryImpl memory_;
|
||||
emu::ClockImpl clock_;
|
||||
emu::memory::CpuCallbacks cpu_callbacks_;
|
||||
emu::Cpu cpu{memory_, clock_, cpu_callbacks_};
|
||||
emu::video::Ppu ppu{memory_, clock_};
|
||||
gfx::Bitmap bitmap_;
|
||||
|
||||
PseudoVram vram_;
|
||||
|
||||
emu::ClockImpl clock_;
|
||||
emu::memory::MemoryImpl memory_;
|
||||
emu::memory::CpuCallbacks cpu_callbacks_;
|
||||
emu::video::Ppu ppu{memory_, clock_};
|
||||
emu::Cpu cpu{memory_, clock_, cpu_callbacks_};
|
||||
|
||||
gfx::Bitmap bitmap_;
|
||||
};
|
||||
|
||||
} // namespace dungeon
|
||||
|
||||
@@ -80,6 +80,8 @@ constexpr int door_pos_right = 0x19C6;
|
||||
|
||||
constexpr int dungeon_spr_ptrs = 0x090000;
|
||||
|
||||
constexpr int NumberOfRooms = 296;
|
||||
|
||||
constexpr ushort stairsObjects[] = {0x139, 0x138, 0x13B, 0x12E, 0x12D};
|
||||
|
||||
class DungeonDestination {
|
||||
|
||||
@@ -5,6 +5,32 @@ namespace app {
|
||||
namespace zelda3 {
|
||||
namespace dungeon {
|
||||
|
||||
SubtypeInfo FetchSubtypeInfo(uint16_t object_id) {
|
||||
SubtypeInfo info;
|
||||
|
||||
// TODO: Determine the subtype based on object_id
|
||||
uint8_t subtype = 1;
|
||||
|
||||
switch (subtype) {
|
||||
case 1: // Subtype 1
|
||||
info.subtype_ptr = kRoomObjectSubtype1 + (object_id & 0xFF) * 2;
|
||||
info.routine_ptr = kRoomObjectSubtype1 + 0x200 + (object_id & 0xFF) * 2;
|
||||
break;
|
||||
case 2: // Subtype 2
|
||||
info.subtype_ptr = kRoomObjectSubtype2 + (object_id & 0x7F) * 2;
|
||||
info.routine_ptr = kRoomObjectSubtype2 + 0x80 + (object_id & 0x7F) * 2;
|
||||
break;
|
||||
case 3: // Subtype 3
|
||||
info.subtype_ptr = kRoomObjectSubtype3 + (object_id & 0xFF) * 2;
|
||||
info.routine_ptr = kRoomObjectSubtype3 + 0x100 + (object_id & 0xFF) * 2;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Invalid object subtype");
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
void RoomObject::DrawTile(Tile t, int xx, int yy,
|
||||
std::vector<uint8_t>& current_gfx16,
|
||||
std::vector<uint8_t>& tiles_bg1_buffer,
|
||||
@@ -56,7 +82,7 @@ void RoomObject::DrawTile(Tile t, int xx, int yy,
|
||||
0x1000 &&
|
||||
((xx / 8) + nx_ + offset_x_) + ((ny_ + offset_y_ + (yy / 8)) * 0x40) >=
|
||||
0) {
|
||||
ushort td = 0; // gfx::GetTilesInfo(); // TODO t.GetTileInfo()
|
||||
ushort td = 0; // gfx::GetTilesInfo();
|
||||
|
||||
// collisionPoint.Add(
|
||||
// new Point(xx + ((nx + offsetX) * 8), yy + ((ny + +offsetY) * 8)));
|
||||
|
||||
@@ -21,6 +21,13 @@ namespace app {
|
||||
namespace zelda3 {
|
||||
namespace dungeon {
|
||||
|
||||
struct SubtypeInfo {
|
||||
uint32_t subtype_ptr;
|
||||
uint32_t routine_ptr;
|
||||
};
|
||||
|
||||
SubtypeInfo FetchSubtypeInfo(uint16_t object_id);
|
||||
|
||||
struct Tile {};
|
||||
|
||||
enum class SpecialObjectType { Chest, BigChest, InterroomStairs };
|
||||
@@ -34,7 +41,7 @@ enum Background2 {
|
||||
Addition,
|
||||
Normal,
|
||||
Transparent,
|
||||
DarkRoom // TODO: Determine if DarkRoom will stay there or not
|
||||
DarkRoom
|
||||
};
|
||||
|
||||
enum Sorting {
|
||||
@@ -58,6 +65,12 @@ enum ObjectOption {
|
||||
Stairs = 32
|
||||
};
|
||||
|
||||
constexpr int kRoomObjectSubtype1 = 0x8000; // JP = Same
|
||||
constexpr int kRoomObjectSubtype2 = 0x83F0; // JP = Same
|
||||
constexpr int kRoomObjectSubtype3 = 0x84F0; // JP = Same
|
||||
constexpr int kRoomObjectTileAddress = 0x1B52; // JP = Same
|
||||
constexpr int kRoomObjectTileAddressFloor = 0x1B5A; // JP = Same
|
||||
|
||||
class RoomObject : public SharedRom {
|
||||
public:
|
||||
enum LayerType { BG1 = 0, BG2 = 1, BG3 = 2 };
|
||||
@@ -166,11 +179,10 @@ class Subtype1 : public RoomObject {
|
||||
int tileCount)
|
||||
: RoomObject(id, x, y, size, layer), tile_count_(tileCount) {
|
||||
auto rom_data = rom()->data();
|
||||
int pos =
|
||||
core::tile_address +
|
||||
static_cast<int16_t>(
|
||||
(rom_data[core::subtype1_tiles + ((id & 0xFF) * 2) + 1] << 8) +
|
||||
rom_data[core::subtype1_tiles + ((id & 0xFF) * 2)]);
|
||||
int pos = kRoomObjectTileAddress +
|
||||
static_cast<int16_t>(
|
||||
(rom_data[kRoomObjectSubtype1 + ((id & 0xFF) * 2) + 1] << 8) +
|
||||
rom_data[kRoomObjectSubtype1 + ((id & 0xFF) * 2)]);
|
||||
AddTiles(tile_count_, pos);
|
||||
sort = (Sorting)(Sorting::Horizontal | Sorting::Wall);
|
||||
}
|
||||
@@ -194,11 +206,10 @@ class Subtype2 : public RoomObject {
|
||||
Subtype2(int16_t id, uint8_t x, uint8_t y, uint8_t size, uint8_t layer)
|
||||
: RoomObject(id, x, y, size, layer) {
|
||||
auto rom_data = rom()->data();
|
||||
int pos =
|
||||
core::tile_address +
|
||||
static_cast<int16_t>(
|
||||
(rom_data[core::subtype2_tiles + ((id & 0x7F) * 2) + 1] << 8) +
|
||||
rom_data[core::subtype2_tiles + ((id & 0x7F) * 2)]);
|
||||
int pos = kRoomObjectTileAddress +
|
||||
static_cast<int16_t>(
|
||||
(rom_data[kRoomObjectSubtype2 + ((id & 0x7F) * 2) + 1] << 8) +
|
||||
rom_data[kRoomObjectSubtype2 + ((id & 0x7F) * 2)]);
|
||||
AddTiles(8, pos);
|
||||
sort = (Sorting)(Sorting::Horizontal | Sorting::Wall);
|
||||
}
|
||||
@@ -220,11 +231,10 @@ class Subtype3 : public RoomObject {
|
||||
Subtype3(int16_t id, uint8_t x, uint8_t y, uint8_t size, uint8_t layer)
|
||||
: RoomObject(id, x, y, size, layer) {
|
||||
auto rom_data = rom()->data();
|
||||
int pos =
|
||||
core::tile_address +
|
||||
static_cast<int16_t>(
|
||||
(rom_data[core::subtype3_tiles + ((id & 0xFF) * 2) + 1] << 8) +
|
||||
rom_data[core::subtype3_tiles + ((id & 0xFF) * 2)]);
|
||||
int pos = kRoomObjectTileAddress +
|
||||
static_cast<int16_t>(
|
||||
(rom_data[kRoomObjectSubtype3 + ((id & 0xFF) * 2) + 1] << 8) +
|
||||
rom_data[kRoomObjectSubtype3 + ((id & 0xFF) * 2)]);
|
||||
AddTiles(8, pos);
|
||||
sort = (Sorting)(Sorting::Horizontal | Sorting::Wall);
|
||||
}
|
||||
|
||||
94
src/app/zelda3/dungeon/room_tag.h
Normal file
94
src/app/zelda3/dungeon/room_tag.h
Normal file
@@ -0,0 +1,94 @@
|
||||
#ifndef YAZE_APP_ZELDA3_DUNGEON_ROOM_TAG_H
|
||||
#define YAZE_APP_ZELDA3_DUNGEON_ROOM_TAG_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace yaze {
|
||||
namespace app {
|
||||
namespace zelda3 {
|
||||
namespace dungeon {
|
||||
|
||||
static const std::string RoomEffect[] = {"Nothing",
|
||||
"Nothing",
|
||||
"Moving Floor",
|
||||
"Moving Water",
|
||||
"Trinexx Shell",
|
||||
"Red Flashes",
|
||||
"Light Torch to See Floor",
|
||||
"Ganon's Darkness"};
|
||||
|
||||
static const std::string RoomTag[] = {"Nothing",
|
||||
"NW Kill Enemy to Open",
|
||||
"NE Kill Enemy to Open",
|
||||
"SW Kill Enemy to Open",
|
||||
"SE Kill Enemy to Open",
|
||||
"W Kill Enemy to Open",
|
||||
"E Kill Enemy to Open",
|
||||
"N Kill Enemy to Open",
|
||||
"S Kill Enemy to Open",
|
||||
"Clear Quadrant to Open",
|
||||
"Clear Full Tile to Open",
|
||||
|
||||
"NW Push Block to Open",
|
||||
"NE Push Block to Open",
|
||||
"SW Push Block to Open",
|
||||
"SE Push Block to Open",
|
||||
"W Push Block to Open",
|
||||
"E Push Block to Open",
|
||||
"N Push Block to Open",
|
||||
"S Push Block to Open",
|
||||
"Push Block to Open",
|
||||
"Pull Lever to Open",
|
||||
"Collect Prize to Open",
|
||||
|
||||
"Hold Switch Open Door",
|
||||
"Toggle Switch to Open Door",
|
||||
"Turn off Water",
|
||||
"Turn on Water",
|
||||
"Water Gate",
|
||||
"Water Twin",
|
||||
"Moving Wall Right",
|
||||
"Moving Wall Left",
|
||||
"Crash",
|
||||
"Crash",
|
||||
"Push Switch Exploding Wall",
|
||||
"Holes 0",
|
||||
"Open Chest (Holes 0)",
|
||||
"Holes 1",
|
||||
"Holes 2",
|
||||
"Defeat Boss for Dungeon Prize",
|
||||
|
||||
"SE Kill Enemy to Push Block",
|
||||
"Trigger Switch Chest",
|
||||
"Pull Lever Exploding Wall",
|
||||
"NW Kill Enemy for Chest",
|
||||
"NE Kill Enemy for Chest",
|
||||
"SW Kill Enemy for Chest",
|
||||
"SE Kill Enemy for Chest",
|
||||
"W Kill Enemy for Chest",
|
||||
"E Kill Enemy for Chest",
|
||||
"N Kill Enemy for Chest",
|
||||
"S Kill Enemy for Chest",
|
||||
"Clear Quadrant for Chest",
|
||||
"Clear Full Tile for Chest",
|
||||
|
||||
"Light Torches to Open",
|
||||
"Holes 3",
|
||||
"Holes 4",
|
||||
"Holes 5",
|
||||
"Holes 6",
|
||||
"Agahnim Room",
|
||||
"Holes 7",
|
||||
"Holes 8",
|
||||
"Open Chest for Holes 8",
|
||||
"Push Block for Chest",
|
||||
"Clear Room for Triforce Door",
|
||||
"Light Torches for Chest",
|
||||
"Kill Boss Again"};
|
||||
|
||||
} // namespace dungeon
|
||||
} // namespace zelda3
|
||||
} // namespace app
|
||||
} // namespace yaze
|
||||
|
||||
#endif // YAZE_APP_ZELDA3_DUNGEON_ROOM_TAG_H
|
||||
Reference in New Issue
Block a user