remove magic numbers, enforce const correctness

This commit is contained in:
scawful
2024-08-20 21:31:59 -04:00
parent e404eabe64
commit a8ed9b7f92
27 changed files with 832 additions and 814 deletions

View File

@@ -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) {

View File

@@ -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

View File

@@ -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 {

View File

@@ -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)));

View File

@@ -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);
}

View 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