Add Debugger interface, RoomObject class
- Log instructions to debugger using experiment flag - Use BitmapManager for more functionality - Draw framebuffer and integrated debugger
This commit is contained in:
@@ -78,6 +78,64 @@ void DrawDungeonRoomBG2(std::vector<uint8_t>& tiles_bg2_buffer,
|
||||
}
|
||||
}
|
||||
|
||||
void Room::LoadHeader() {
|
||||
// Address of the room header
|
||||
int headerPointer = (rom()->data()[core::room_header_pointer + 2] << 16) +
|
||||
(rom()->data()[core::room_header_pointer + 1] << 8) +
|
||||
(rom()->data()[core::room_header_pointer]);
|
||||
headerPointer = core::SnesToPc(headerPointer);
|
||||
|
||||
int address = (rom()->data()[core::room_header_pointers_bank] << 16) +
|
||||
(rom()->data()[(headerPointer + 1) + (room_id_ * 2)] << 8) +
|
||||
rom()->data()[(headerPointer) + (room_id_ * 2)];
|
||||
|
||||
auto header_location = core::SnesToPc(address);
|
||||
|
||||
// bg2 = (Background2)((rom()->data()[header_location] >> 5) & 0x07);
|
||||
// collision = (CollisionKey)((rom()->data()[header_location] >> 2) & 0x07);
|
||||
// light = ((rom()->data()[header_location]) & 0x01) == 1;
|
||||
|
||||
if (light) {
|
||||
bg2 = Background2::DarkRoom;
|
||||
}
|
||||
|
||||
palette = ((rom()->data()[header_location + 1] & 0x3F));
|
||||
blockset = (rom()->data()[header_location + 2]);
|
||||
spriteset = (rom()->data()[header_location + 3]);
|
||||
// effect = (EffectKey)((rom()->data()[header_location + 4]));
|
||||
// tag1 = (TagKey)((rom()->data()[header_location + 5]));
|
||||
// tag2 = (TagKey)((rom()->data()[header_location + 6]));
|
||||
|
||||
// holewarpPlane = ((rom()->data()[header_location + 7]) & 0x03);
|
||||
staircase_plane[0] = ((rom()->data()[header_location + 7] >> 2) & 0x03);
|
||||
staircase_plane[1] = ((rom()->data()[header_location + 7] >> 4) & 0x03);
|
||||
staircase_plane[2] = ((rom()->data()[header_location + 7] >> 6) & 0x03);
|
||||
staircase_plane[3] = ((rom()->data()[header_location + 8]) & 0x03);
|
||||
|
||||
// if (holewarpPlane == 2) {
|
||||
// Console::WriteLine("Room Index Plane 1 : Used in room id = " +
|
||||
// index.ToString("X2"));
|
||||
// } else if (staircasePlane[0] == 2) {
|
||||
// Console::WriteLine("Room Index Plane 1 : Used in room id = " +
|
||||
// index.ToString("X2"));
|
||||
// } else if (staircasePlane[1] == 2) {
|
||||
// Console::WriteLine("Room Index Plane 1 : Used in room id = " +
|
||||
// index.ToString("X2"));
|
||||
// } else if (staircasePlane[2] == 2) {
|
||||
// Console::WriteLine("Room Index Plane 1 : Used in room id = " +
|
||||
// index.ToString("X2"));
|
||||
// } else if (staircasePlane[3] == 2) {
|
||||
// Console::WriteLine("Room Index Plane 1 : Used in room id = " +
|
||||
// index.ToString("X2"));
|
||||
// }
|
||||
|
||||
// holewarp = (rom()->data()[header_location + 9]);
|
||||
staircase_rooms[0] = (rom()->data()[header_location + 10]);
|
||||
staircase_rooms[1] = (rom()->data()[header_location + 11]);
|
||||
staircase_rooms[2] = (rom()->data()[header_location + 12]);
|
||||
staircase_rooms[3] = (rom()->data()[header_location + 13]);
|
||||
}
|
||||
|
||||
void Room::LoadSprites() {
|
||||
auto rom_data = rom()->vector();
|
||||
int spritePointer = (0x04 << 16) + (rom_data[rooms_sprite_pointer + 1] << 8) +
|
||||
@@ -295,6 +353,10 @@ RoomObject Room::AddObject(short oid, uint8_t x, uint8_t y, uint8_t size,
|
||||
}
|
||||
|
||||
void Room::LoadRoomGraphics(uchar entrance_blockset) {
|
||||
auto mainGfx = rom()->main_blockset_ids;
|
||||
auto roomGfx = rom()->room_blockset_ids;
|
||||
auto spriteGfx = rom()->spriteset_ids;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
blocks[i] = mainGfx[BackgroundTileset][i];
|
||||
if (i >= 6 && i <= 6) {
|
||||
|
||||
@@ -80,6 +80,8 @@ void DrawDungeonRoomBG2(std::vector<uint8_t>& tiles_bg2_buffer,
|
||||
|
||||
class DungeonDestination {
|
||||
public:
|
||||
DungeonDestination() = default;
|
||||
~DungeonDestination() = default;
|
||||
DungeonDestination(uint8_t i) : Index(i) {}
|
||||
|
||||
uint8_t Index;
|
||||
@@ -89,6 +91,7 @@ class DungeonDestination {
|
||||
};
|
||||
|
||||
struct object_door {
|
||||
object_door() = default;
|
||||
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) {}
|
||||
|
||||
@@ -101,6 +104,7 @@ struct object_door {
|
||||
};
|
||||
|
||||
struct ChestData {
|
||||
ChestData() = default;
|
||||
ChestData(uchar i, bool s) : id_(i), size_(s){};
|
||||
|
||||
uchar id_;
|
||||
@@ -111,6 +115,10 @@ struct StaircaseRooms {};
|
||||
|
||||
class Room : public SharedROM {
|
||||
public:
|
||||
Room() = default;
|
||||
Room(int room_id) : room_id_(room_id) {}
|
||||
~Room() = default;
|
||||
void LoadHeader();
|
||||
void LoadSprites();
|
||||
void LoadChests();
|
||||
|
||||
@@ -124,19 +132,29 @@ class Room : public SharedROM {
|
||||
|
||||
void LoadRoomFromROM();
|
||||
|
||||
uint8_t floor1 = 0;
|
||||
uint8_t floor2 = 0;
|
||||
uint8_t blockset = 0;
|
||||
uint8_t spriteset = 0;
|
||||
uint8_t palette = 0;
|
||||
uint8_t layout = 0;
|
||||
|
||||
uint16_t message_id_ = 0;
|
||||
|
||||
gfx::Bitmap current_graphics_;
|
||||
|
||||
private:
|
||||
int animated_frame = 0;
|
||||
|
||||
int room_id_ = 0;
|
||||
|
||||
uint8_t floor1;
|
||||
uint8_t floor2;
|
||||
uint8_t blockset;
|
||||
uint8_t spriteset;
|
||||
uint8_t palette;
|
||||
uint8_t layout;
|
||||
bool light;
|
||||
bool is_loaded_ = false;
|
||||
Background2 bg2;
|
||||
|
||||
uint8_t staircase_plane[4];
|
||||
uint8_t staircase_rooms[4];
|
||||
|
||||
ushort message_id_ = 0;
|
||||
uchar BackgroundTileset;
|
||||
uchar SpriteTileset;
|
||||
uchar Layer2Behavior;
|
||||
@@ -147,11 +165,6 @@ class Room : public SharedROM {
|
||||
std::array<uchar, 16> blocks;
|
||||
std::array<uchar, 16> ChestList;
|
||||
|
||||
uint8_t mainGfx[37][8];
|
||||
uint8_t roomGfx[82][4];
|
||||
uint8_t spriteGfx[144][4];
|
||||
uint8_t paletteGfx[72][4];
|
||||
|
||||
std::vector<zelda3::Sprite> sprites_;
|
||||
std::vector<StaircaseRooms> staircaseRooms;
|
||||
|
||||
@@ -171,8 +184,6 @@ class Room : public SharedROM {
|
||||
std::vector<ChestData> chests_in_room;
|
||||
std::vector<uint8_t> current_gfx16_;
|
||||
std::vector<RoomObject> tilesObjects;
|
||||
|
||||
gfx::Bitmap current_graphics_;
|
||||
};
|
||||
|
||||
} // namespace dungeon
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "app/emu/cpu.h"
|
||||
#include "app/emu/video/ppu.h"
|
||||
#include "app/gfx/snes_palette.h"
|
||||
#include "app/gfx/snes_tile.h"
|
||||
#include "app/rom.h"
|
||||
@@ -17,6 +19,61 @@ namespace app {
|
||||
namespace zelda3 {
|
||||
namespace dungeon {
|
||||
|
||||
class DungeonObjectRenderer : public SharedROM {
|
||||
public:
|
||||
|
||||
struct PseudoVram {
|
||||
std::vector<gfx::Bitmap> sheets;
|
||||
};
|
||||
|
||||
void CreateVramFromRoomBlockset() {
|
||||
auto bitmap_manager = rom()->BitmapManager();
|
||||
uint16_t room_id = 0;
|
||||
auto room_blockset = rom()->room_blockset_ids[room_id];
|
||||
|
||||
for (const auto blockset_id : room_blockset) {
|
||||
auto blockset = bitmap_manager[(uint16_t)blockset_id];
|
||||
vram_.sheets.push_back(*blockset.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RenderObjectsAsBitmaps() {
|
||||
auto subtype1_ptr = core::subtype1_tiles;
|
||||
auto subtype1_routine_ptr =
|
||||
core::subtype1_tiles + 0x200; // Where the draw routines start
|
||||
|
||||
auto subtype2_ptr = core::subtype2_tiles;
|
||||
auto subtype2_routine_ptr =
|
||||
core::subtype2_tiles + 0x80; // Where the draw routines start
|
||||
|
||||
auto subtype3_ptr = core::subtype3_tiles;
|
||||
auto subtype3_routine_ptr =
|
||||
core::subtype3_tiles + 0x100; // Where the draw routines start
|
||||
|
||||
auto data = (*rom()).vector();
|
||||
// Construct a copy of the rooms VRAM
|
||||
// Jump to the routine that draws the object based on the ID
|
||||
// Run the routine and get the VRAM data using the CPU and PPU
|
||||
// Render the VRAM data to a bitmap
|
||||
|
||||
memory_.Initialize(data);
|
||||
cpu.PC = subtype1_routine_ptr;
|
||||
cpu.JMP(cpu.FetchWord());
|
||||
auto dest = cpu.PC + 0x10;
|
||||
while (cpu.PC < dest) {
|
||||
cpu.ExecuteInstruction(cpu.FetchByte());
|
||||
}
|
||||
}
|
||||
|
||||
emu::MemoryImpl memory_;
|
||||
emu::ClockImpl clock_;
|
||||
emu::CPU cpu{memory_, clock_};
|
||||
emu::PPU ppu{memory_, clock_};
|
||||
gfx::Bitmap bitmap;
|
||||
PseudoVram vram_;
|
||||
};
|
||||
|
||||
enum class SpecialObjectType { Chest, BigChest, InterroomStairs };
|
||||
|
||||
struct Tile {};
|
||||
@@ -223,9 +280,7 @@ class Subtype2_Multiple : public RoomObject {
|
||||
// Other member functions and variables
|
||||
};
|
||||
|
||||
class Subtype3 : public RoomObject {
|
||||
|
||||
};
|
||||
class Subtype3 : public RoomObject {};
|
||||
|
||||
} // namespace dungeon
|
||||
} // namespace zelda3
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "app/core/constants.h"
|
||||
#include "app/core/common.h"
|
||||
#include "app/gfx/bitmap.h"
|
||||
#include "app/gfx/compression.h"
|
||||
#include "app/gfx/snes_tile.h"
|
||||
|
||||
Reference in New Issue
Block a user