Move DungeonObjectRenderer to its own file

This commit is contained in:
scawful
2023-12-17 20:59:42 -05:00
parent 813b2e2a62
commit 10785357ef
6 changed files with 323 additions and 294 deletions

View File

@@ -17,6 +17,11 @@ namespace yaze {
namespace app {
namespace editor {
constexpr ImGuiTableFlags kDungeonObjectTableFlags =
ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable |
ImGuiTableFlags_Hideable | ImGuiTableFlags_BordersOuter |
ImGuiTableFlags_BordersV;
using ImGui::TableHeadersRow;
using ImGui::TableNextColumn;
using ImGui::TableNextRow;
@@ -34,9 +39,15 @@ absl::Status DungeonEditor::Update() {
}
graphics_bin_ = rom()->graphics_bin();
full_palette_ =
rom()->GetPaletteGroup("dungeon_main")[current_palette_group_id_];
rom()->palette_group("dungeon_main")[current_palette_group_id_];
current_palette_group_ =
gfx::CreatePaletteGroupFromLargePalette(full_palette_);
// Create a vector of pointers to the current block bitmaps
for (int block : rooms_[current_room_id_].blocks()) {
room_gfx_sheets_.emplace_back(&graphics_bin_[block]);
}
is_loaded_ = true;
}
@@ -54,7 +65,7 @@ absl::Status DungeonEditor::Update() {
if (palette_showing_) {
ImGui::Begin("Palette Editor", &palette_showing_, 0);
current_palette_ =
rom()->GetPaletteGroup("dungeon_main")[current_palette_group_id_];
rom()->palette_group("dungeon_main")[current_palette_group_id_];
gui::SelectablePalettePipeline(current_palette_id_, refresh_graphics_,
current_palette_);
ImGui::End();
@@ -311,12 +322,8 @@ void DungeonEditor::DrawTileSelector() {
}
void DungeonEditor::DrawObjectRenderer() {
if (ImGui::BeginTable(
"DungeonObjectEditorTable", 2,
ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable |
ImGuiTableFlags_Hideable | ImGuiTableFlags_BordersOuter |
ImGuiTableFlags_BordersV,
ImVec2(0, 0))) {
if (ImGui::BeginTable("DungeonObjectEditorTable", 2, kDungeonObjectTableFlags,
ImVec2(0, 0))) {
TableSetupColumn("Dungeon Objects", ImGuiTableColumnFlags_WidthStretch,
ImGui::GetContentRegionAvail().x);
TableSetupColumn("Canvas");
@@ -330,7 +337,8 @@ void DungeonEditor::DrawObjectRenderer() {
if (ImGui::Selectable(object_name.data(), selected_object == i)) {
selected_object = i;
current_object_ = i;
object_renderer_.LoadObject(i);
object_renderer_.LoadObject(i,
rooms_[current_room_id_].mutable_blocks());
rom()->RenderBitmap(object_renderer_.bitmap());
object_loaded_ = true;
}
@@ -347,25 +355,24 @@ void DungeonEditor::DrawObjectRenderer() {
object_canvas_.DrawBackground(ImVec2(256 + 1, 0x10 * 0x40 + 1));
object_canvas_.DrawContextMenu();
object_canvas_.DrawTileSelector(32);
// if (object_loaded_) {
// object_canvas_.DrawBitmap(*object_renderer_.bitmap(), 0, 0);
// }
if (object_loaded_) {
object_canvas_.DrawBitmap(*object_renderer_.bitmap(), 0, 0);
}
object_canvas_.DrawGrid(32.0f);
object_canvas_.DrawOverlay();
ImGui::EndChild();
ImGui::EndTable();
}
if (object_loaded_) {
ImGui::Begin("Memory Viewer", &object_loaded_, 0);
auto memory = object_renderer_.memory();
static MemoryEditor mem_edit;
mem_edit.DrawContents((void*)object_renderer_.mutable_memory(),
memory.size());
ImGui::End();
}
// if (object_loaded_) {
// ImGui::Begin("Memory Viewer", &object_loaded_, 0);
// auto memory = object_renderer_.memory();
// static MemoryEditor mem_edit;
// mem_edit.DrawContents((void*)object_renderer_.memory_ptr(),
// memory.size());
// ImGui::End();
// }
}
} // namespace editor

View File

@@ -51,38 +51,6 @@ class DungeonEditor : public Editor,
void DrawTileSelector();
void DrawObjectRenderer();
bool is_loaded_ = false;
bool show_object_render_ = false;
bool object_loaded_ = false;
bool palette_showing_ = false;
bool refresh_graphics_ = false;
int current_object_ = 0;
uint64_t current_palette_id_ = 0;
uint64_t current_palette_group_id_ = 0;
uint16_t current_room_id_ = 0;
gfx::Bitmap room_gfx_bmp_;
gfx::SNESPalette current_palette_;
gfx::SNESPalette full_palette_;
gfx::PaletteGroup current_palette_group_;
gui::Canvas canvas_;
gui::Canvas room_gfx_canvas_;
gui::Canvas object_canvas_;
gfx::BitmapTable graphics_bin_;
ImVector<int> active_rooms_;
std::vector<zelda3::dungeon::Room> rooms_;
std::vector<gfx::BitmapManager> room_graphics_;
zelda3::dungeon::DungeonObjectRenderer object_renderer_;
PaletteEditor palette_editor_;
enum BackgroundType {
kNoBackground,
kBackground1,
@@ -94,10 +62,36 @@ class DungeonEditor : public Editor,
int background_type_ = kNoBackground;
int placement_type_ = kNoType;
int current_object_ = 0;
ImGuiTableFlags toolset_table_flags_ =
ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Reorderable |
ImGuiTableFlags_Hideable | ImGuiTableFlags_Resizable;
bool is_loaded_ = false;
bool object_loaded_ = false;
bool palette_showing_ = false;
bool refresh_graphics_ = false;
bool show_object_render_ = false;
uint16_t current_room_id_ = 0;
uint64_t current_palette_id_ = 0;
uint64_t current_palette_group_id_ = 0;
ImVector<int> active_rooms_;
PaletteEditor palette_editor_;
gfx::SNESPalette current_palette_;
gfx::SNESPalette full_palette_;
gfx::PaletteGroup current_palette_group_;
gui::Canvas canvas_;
gui::Canvas room_gfx_canvas_;
gui::Canvas object_canvas_;
gfx::Bitmap room_gfx_bmp_;
gfx::BitmapTable graphics_bin_;
std::vector<gfx::Bitmap*> room_gfx_sheets_;
std::vector<zelda3::dungeon::Room> rooms_;
std::vector<gfx::BitmapManager> room_graphics_;
zelda3::dungeon::DungeonObjectRenderer object_renderer_;
};
} // namespace editor

View File

@@ -0,0 +1,208 @@
#include <cstdint>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
#include "app/emu/cpu/cpu.h"
#include "app/emu/memory/memory.h"
#include "app/emu/video/ppu.h"
#include "app/gfx/bitmap.h"
#include "app/gfx/snes_palette.h"
#include "app/gfx/snes_tile.h"
#include "app/rom.h"
#include "app/zelda3/dungeon/object_names.h"
namespace yaze {
namespace app {
namespace zelda3 {
namespace dungeon {
class DungeonObjectRenderer : public SharedROM {
public:
struct PseudoVram {
std::array<uint8_t, 16> sheets;
std::vector<gfx::SNESPalette> palettes;
};
DungeonObjectRenderer() = default;
void LoadObject(uint16_t objectId, std::array<uint8_t, 16>& sheet_ids) {
vram_.sheets = sheet_ids;
rom_data_ = rom()->vector();
// 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);
// Run the CPU emulation for the object's draw routines
RenderObject(subtypeInfo);
}
gfx::Bitmap* bitmap() { return &bitmap_; }
auto memory() { return memory_; }
auto* memory_ptr() { return &memory_; }
auto mutable_memory() { return memory_.data(); }
private:
struct SubtypeInfo {
uint32_t subtypePtr;
uint32_t routinePtr;
};
SubtypeInfo FetchSubtypeInfo(uint16_t objectId) {
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.subtypePtr = core::subtype1_tiles + (objectId & 0xFF) * 2;
info.routinePtr = core::subtype1_tiles + 0x200 + (objectId & 0xFF) * 2;
std::cout << "Subtype 1 " << std::hex << info.subtypePtr << std::endl;
std::cout << "Subtype 1 " << std::hex << info.routinePtr << std::endl;
break;
case 2: // Subtype 2
info.subtypePtr = core::subtype2_tiles + (objectId & 0x7F) * 2;
info.routinePtr = core::subtype2_tiles + 0x80 + (objectId & 0x7F) * 2;
break;
case 3: // Subtype 3
info.subtypePtr = core::subtype3_tiles + (objectId & 0xFF) * 2;
info.routinePtr = core::subtype3_tiles + 0x100 + (objectId & 0xFF) * 2;
break;
default:
// Handle unknown subtype
throw std::runtime_error("Unknown subtype for object ID: " +
std::to_string(objectId));
}
// Find the RTS of the subtype routine
while (true) {
uint8_t opcode = memory_.ReadByte(info.routinePtr);
if (opcode == 0x60) {
break;
}
info.routinePtr++;
}
return info;
}
void ConfigureObject(const SubtypeInfo& info) {
cpu.A = 0x03D8;
cpu.X = 0x03D8;
cpu.DB = 0x7E;
// VRAM target destinations
cpu.WriteLong(0xBF, 0x7E2000);
cpu.WriteLong(0xCB, 0x7E2080);
cpu.WriteLong(0xC2, 0x7E2002);
cpu.WriteLong(0xCE, 0x7E2082);
cpu.SetAccumulatorSize(false);
cpu.SetIndexSize(false);
}
/**
* Example:
* the STA $BF, $CD, $C2, $CE are the location of the object in the room
* $B2 is used for size loop
* so if object size is setted on 07 that draw code will be repeated 7 times
* and since Y is increasing by 4 it makes the object draw from left to right
RoomDraw_Rightwards2x2_1to15or32:
#_018B89: JSR RoomDraw_GetSize_1to15or32
.next
#_018B8C: JSR RoomDraw_Rightwards2x2
#_018B8F: DEC.b $B2
#_018B91: BNE .next
#_018B93: RTS
RoomDraw_Rightwards2x2:
#_019895: LDA.w RoomDrawObjectData+0,X
#_019898: STA.b [$BF],Y
#_01989A: LDA.w RoomDrawObjectData+2,X
#_01989D: STA.b [$CB],Y
#_01989F: LDA.w RoomDrawObjectData+4,X
#_0198A2: STA.b [$C2],Y
#_0198A4: LDA.w RoomDrawObjectData+6,X
#_0198A7: STA.b [$CE],Y
#_0198A9: INY #4
#_0198AD: RTS
*/
void RenderObject(const SubtypeInfo& info) {
cpu.PB = 0x01;
cpu.PC = cpu.ReadWord(0x01 << 16 | info.routinePtr);
int i = 0;
while (true) {
uint8_t opcode = cpu.ReadByte(cpu.PB << 16 | cpu.PC);
cpu.ExecuteInstruction(opcode);
cpu.HandleInterrupts();
if (i > 50) {
break;
}
i++;
}
UpdateObjectBitmap();
}
// In the underworld, this holds a copy of the entire BG tilemap for
// Layer 1 (BG2) in TILEMAPA
// Layer 2 (BG1) in TILEMAPB
//
// In the overworld, this holds the entire map16 space, using both blocks as a
// single array TILEMAPA = $7E2000 TILEMAPB = $7E4000
void UpdateObjectBitmap() {
tilemap_.reserve(0x2000);
for (int i = 0; i < 0x2000; ++i) {
tilemap_.push_back(0);
}
int tilemap_offset = 0;
// Iterate over tilemap in memory to read tile IDs
for (int tile_index = 0; tile_index < 512; tile_index++) {
// Read the tile ID from memory
int tile_id = memory_.ReadWord(0x7E4000 + tile_index);
int sheet_number = tile_id / 32;
int local_id = tile_id % 32;
int row = local_id / 8;
int column = local_id % 8;
int x = column * 8;
int y = row * 8;
auto sheet = rom()->mutable_graphics_sheet(vram_.sheets[sheet_number]);
// Copy the tile from VRAM using the read tile_id
sheet->Get8x8Tile(tile_id, x, y, tilemap_, tilemap_offset);
}
bitmap_.Create(256, 256, 8, tilemap_);
}
std::vector<uint8_t> tilemap_;
uint16_t pc_with_rts_;
std::vector<uint8_t> rom_data_;
emu::MemoryImpl memory_;
emu::ClockImpl clock_;
emu::CPU cpu{memory_, clock_};
emu::Ppu ppu{memory_, clock_};
gfx::Bitmap bitmap_;
PseudoVram vram_;
};
} // namespace dungeon
} // namespace zelda3
} // namespace app
} // namespace yaze

View File

@@ -69,9 +69,6 @@ void Room::LoadRoomGraphics(uchar entrance_blockset) {
if (i >= 6 && i <= 6) {
// 3-6
if (entrance_blockset != 0xFF) {
// 6 is wrong for the entrance? -NOP need to fix that
// TODO: Find why this is wrong - Thats because of the stairs need to
// find a workaround
if (roomGfx[entrance_blockset][i - 3] != 0) {
blocks_[i] = roomGfx[entrance_blockset][i - 3];
}
@@ -88,25 +85,34 @@ void Room::LoadRoomGraphics(uchar entrance_blockset) {
} // 12-16 sprites
}
constexpr int kGfxBufferOffset = 92 * 2048;
constexpr int kGfxBufferStride = 512;
constexpr int kGfxBufferAnimatedFrameOffset = 7 * 2048;
constexpr int kGfxBufferAnimatedFrameStride = 512;
constexpr int kGfxBufferRoomOffset = 2048;
constexpr int kGfxBufferRoomSpriteOffset = 512;
constexpr int kGfxBufferRoomSpriteStride = 2048;
constexpr int kGfxBufferRoomSpriteLastLineOffset = 0x88;
void Room::CopyRoomGraphicsToBuffer() {
auto gfx_buffer_data = rom()->graphics_buffer();
// Into "room gfx16" 16 of them
int sheetPos = 0;
// Copy room graphics to buffer
int sheet_pos = 0;
for (int i = 0; i < 16; i++) {
int d = 0;
int ioff = blocks_[i] * 2048;
while (d < 2048) {
uchar mapByte = gfx_buffer_data[d + ioff];
int data = 0;
int block_offset = blocks_[i] * kGfxBufferRoomOffset;
while (data < kGfxBufferRoomOffset) {
uchar map_byte = gfx_buffer_data[data + block_offset];
if (i < 4) {
mapByte += 0x88;
} // Last line of 6, first line of 7 ?
map_byte += kGfxBufferRoomSpriteLastLineOffset;
}
current_gfx16_[d + sheetPos] = mapByte;
d++;
current_gfx16_[data + sheet_pos] = map_byte;
data++;
}
sheetPos += 2048;
sheet_pos += kGfxBufferRoomOffset;
}
LoadAnimatedGraphics();
@@ -243,8 +249,8 @@ void Room::LoadObjects() {
short oid = 0;
int layer = 0;
bool door = false;
bool endRead = false;
while (!endRead) {
bool end_read = false;
while (!end_read) {
b1 = rom_data[pos];
b2 = rom_data[pos + 1];

View File

@@ -20,13 +20,9 @@ namespace app {
namespace zelda3 {
namespace dungeon {
// public static int room_object_layout_pointer = 0x882D;
// public static int room_object_pointer = 0x874C; // Long pointer
// oh eh
// in bank 01 ? lol
// those are pointer of pointers
// room_object_layout_pointer 0x882D
// room_object_pointer 0x874C
// 0x882D -> readlong() -> 2FEF04 (04EF2F -> toPC->026F2F) ->
// that's all the layout "room" pointers
// 47EF04 ; layout00 ptr
// AFEF04 ; layout01 ptr
@@ -40,6 +36,9 @@ namespace dungeon {
// the object array is terminated by a 0xFFFF there's no layers
// in normal room when you encounter a 0xFFFF it goes to the next layer
constexpr int room_object_layout_pointer = 0x882D;
constexpr int room_object_pointer = 0x874C; // Long pointer
constexpr int entrance_gfx_group = 0x5D97;
constexpr int dungeons_main_bg_palette_pointers = 0xDEC4B; // JP Same
constexpr int dungeons_palettes = 0xDD734;
@@ -48,8 +47,6 @@ constexpr int rooms_sprite_pointer = 0x4C298; // JP Same //2byte bank 09D62E
constexpr int kRoomHeaderPointer = 0xB5DD; // LONG
constexpr int kRoomHeaderPointerBank = 0xB5E7; // JP Same
constexpr int gfx_groups_pointer = 0x6237;
constexpr int room_object_layout_pointer = 0x882D;
constexpr int room_object_pointer = 0x874C; // Long pointer
constexpr int chests_length_pointer = 0xEBF6;
constexpr int chests_data_pointer1 = 0xEBFB;
@@ -138,6 +135,7 @@ class Room : public SharedROM {
void LoadRoomFromROM();
auto blocks() const { return blocks_; }
auto& mutable_blocks() { return blocks_; }
RoomObject AddObject(short oid, uint8_t x, uint8_t y, uint8_t size,
uint8_t layer) {
@@ -160,14 +158,16 @@ class Room : public SharedROM {
std::vector<uint8_t> current_gfx16_;
private:
bool light = false;
bool is_loaded_ = false;
int animated_frame = 0;
bool IsDark = false;
bool floor = false;
int room_id_ = 0;
int animated_frame = 0;
bool light;
Background2 bg2;
uchar Tag1;
uchar Tag2;
uint8_t staircase_plane[4];
uint8_t staircase_rooms[4];
@@ -179,6 +179,7 @@ class Room : public SharedROM {
uint8_t Floor1Graphics;
uint8_t Floor2Graphics;
uint8_t Layer2Mode;
std::array<uint8_t, 16> blocks_;
std::array<uchar, 16> ChestList;
@@ -186,19 +187,13 @@ class Room : public SharedROM {
std::vector<zelda3::Sprite> sprites_;
std::vector<StaircaseRooms> staircaseRooms;
Background2 bg2;
DungeonDestination Pits;
DungeonDestination Stair1;
DungeonDestination Stair2;
DungeonDestination Stair3;
DungeonDestination Stair4;
uchar Tag1;
uchar Tag2;
bool IsDark;
bool floor;
// std::vector<Chest> chest_list;
std::vector<ChestData> chests_in_room;
std::vector<RoomObject> tilesObjects;
};

View File

@@ -14,188 +14,17 @@
#include "app/gfx/snes_tile.h"
#include "app/rom.h"
#include "app/zelda3/dungeon/object_names.h"
#include "app/zelda3/dungeon/object_renderer.h"
namespace yaze {
namespace app {
namespace zelda3 {
namespace dungeon {
class DungeonObjectRenderer : public SharedROM {
public:
struct PseudoVram {
std::vector<gfx::Bitmap> sheets;
// TODO: Initialize with mock VRAM data
};
DungeonObjectRenderer() {
// TODO: Constructor implementation
}
void LoadObject(uint16_t objectId) {
rom_data_ = rom()->vector();
// 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);
// Run the CPU emulation for the object's draw routines
RenderObject(subtypeInfo);
}
gfx::Bitmap* bitmap() { return &bitmap_; }
auto memory() { return memory_; }
auto mutable_memory() { return memory_.data(); }
private:
struct SubtypeInfo {
uint32_t subtypePtr;
uint32_t routinePtr;
};
SubtypeInfo FetchSubtypeInfo(uint16_t objectId) {
SubtypeInfo info;
// Determine the subtype based on objectId
// Assuming subtype is determined by some bits in objectId; modify as needed
uint8_t subtype = 1; // Example: top 8 bits
// Based on the subtype, fetch the correct pointers
switch (subtype) {
case 1: // Subtype 1
info.subtypePtr = core::subtype1_tiles + (objectId & 0xFF) * 2;
info.routinePtr = core::subtype1_tiles + 0x200 + (objectId & 0xFF) * 2;
std::cout << "Subtype 1 " << std::hex << info.subtypePtr << std::endl;
std::cout << "Subtype 1 " << std::hex << info.routinePtr << std::endl;
break;
case 2: // Subtype 2
info.subtypePtr = core::subtype2_tiles + (objectId & 0x7F) * 2;
info.routinePtr = core::subtype2_tiles + 0x80 + (objectId & 0x7F) * 2;
break;
case 3: // Subtype 3
info.subtypePtr = core::subtype3_tiles + (objectId & 0xFF) * 2;
info.routinePtr = core::subtype3_tiles + 0x100 + (objectId & 0xFF) * 2;
break;
default:
// Handle unknown subtype
throw std::runtime_error("Unknown subtype for object ID: " +
std::to_string(objectId));
}
// Convert pointers from ROM-relative to absolute (if necessary)
// info.subtypePtr = ConvertToAbsolutePtr(info.subtypePtr);
// info.routinePtr = ConvertToAbsolutePtr(info.routinePtr);
return info;
}
void ConfigureObject(const SubtypeInfo& info) {
cpu.A = 0x03D8;
cpu.X = 0x03D8;
cpu.DB = 0x7E;
// VRAM target destinations
cpu.WriteLong(0xBF, 0x7E2000);
cpu.WriteLong(0xCB, 0x7E2080);
cpu.WriteLong(0xC2, 0x7E2002);
cpu.WriteLong(0xCE, 0x7E2082);
cpu.SetAccumulatorSize(false);
cpu.SetIndexSize(false);
}
/**
* Example:
* the STA $BF, $CD, $C2, $CE are the location of the object in the room
* $B2 is used for size loop
* so if object size is setted on 07 that draw code will be repeated 7 times
* and since Y is increasing by 4 it makes the object draw from left to right
RoomDraw_Rightwards2x2_1to15or32:
#_018B89: JSR RoomDraw_GetSize_1to15or32
.next
#_018B8C: JSR RoomDraw_Rightwards2x2
#_018B8F: DEC.b $B2
#_018B91: BNE .next
#_018B93: RTS
RoomDraw_Rightwards2x2:
#_019895: LDA.w RoomDrawObjectData+0,X
#_019898: STA.b [$BF],Y
#_01989A: LDA.w RoomDrawObjectData+2,X
#_01989D: STA.b [$CB],Y
#_01989F: LDA.w RoomDrawObjectData+4,X
#_0198A2: STA.b [$C2],Y
#_0198A4: LDA.w RoomDrawObjectData+6,X
#_0198A7: STA.b [$CE],Y
#_0198A9: INY
#_0198AA: INY
#_0198AB: INY
#_0198AC: INY
#_0198AD: RTS
*
*/
void RenderObject(const SubtypeInfo& info) {
cpu.PB = 0x01;
cpu.PC = cpu.ReadWord(0x01 << 16 | info.routinePtr);
int i = 0;
while (true) {
uint8_t opcode = cpu.ReadByte(cpu.PB << 16 | cpu.PC);
cpu.ExecuteInstruction(opcode);
cpu.HandleInterrupts();
if (i > 50) {
break;
}
i++;
// UpdateObjectBitmap();
}
}
void UpdateObjectBitmap() {
// Object draw data
uint8_t room_object_draw_data0 = memory_.ReadByte(0x7E00BF);
uint8_t room_object_draw_data1 = memory_.ReadByte(0x7E00CB);
uint8_t room_object_draw_data2 = memory_.ReadByte(0x7E00C2);
uint8_t room_object_draw_data3 = memory_.ReadByte(0x7E00CE);
// Used with Y to index the room object draw data
uint8_t size_loop = memory_.ReadByte(0x7E00B2);
// Update the bitmap with this data by copying the tiles from vram.
std::cout << "Object draw data: " << std::hex << (int)room_object_draw_data0
<< " " << (int)room_object_draw_data1 << " "
<< (int)room_object_draw_data2 << " "
<< (int)room_object_draw_data3 << std::endl;
std::cout << "Size loop: " << std::hex << (int)size_loop << std::endl;
}
std::vector<uint8_t> rom_data_;
emu::MemoryImpl memory_;
emu::ClockImpl clock_;
emu::CPU cpu{memory_, clock_};
emu::Ppu ppu{memory_, clock_};
gfx::Bitmap bitmap_;
PseudoVram vram_;
};
struct Tile {};
enum class SpecialObjectType { Chest, BigChest, InterroomStairs };
struct Tile {};
enum Background2 {
Off,
Parallax,
@@ -229,12 +58,6 @@ enum ObjectOption {
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 };
@@ -268,7 +91,6 @@ class RoomObject : public SharedROM {
GetSizeSized();
UpdateSize();
size_ = previous_size_;
// collision_point_.clear();
}
void GetBaseSize() {
@@ -281,8 +103,6 @@ class RoomObject : public SharedROM {
size_width_ = width_ - base_width_;
}
// virtual void Draw() { collision_point_.clear(); }
void UpdateSize() {
width_ = 8;
height_ = 8;
@@ -291,8 +111,8 @@ class RoomObject : public SharedROM {
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]));
ASSIGN_OR_LOG_ERROR(auto tile, rom()->ReadTile16(pos + (i * 2)));
tiles_.push_back(tile);
}
}
@@ -302,43 +122,42 @@ class RoomObject : public SharedROM {
ushort tile_under = 0xFFFF);
protected:
int16_t id_;
bool all_bgs_ = false;
bool lit_ = false;
bool deleted_ = false;
bool show_rectangle_ = false;
bool diagonal_fix_ = false;
bool selected_ = false;
int16_t id_;
uint8_t x_;
uint8_t y_;
uint8_t size_;
LayerType layer_;
std::vector<uint8_t> preview_object_data_;
bool all_bgs_ = false;
bool lit_ = false;
std::vector<gfx::Tile16> tiles_;
int tile_index_ = 0;
std::string name_;
uint8_t nx_;
uint8_t ny_;
uint8_t ox_;
uint8_t oy_;
uint8_t z_ = 0;
uint8_t previous_size_ = 0;
int width_;
int height_;
int base_width_;
int base_height_;
int size_width_;
int size_height_;
ObjectOption options_ = ObjectOption::Nothing;
int tile_index_ = 0;
int offset_x_ = 0;
int offset_y_ = 0;
bool diagonal_fix_ = false;
bool selected_ = false;
int preview_id_ = 0;
uint8_t previous_size_ = 0;
bool show_rectangle_ = false;
// std::vector<Point> collision_point_;
int unique_id_ = 0;
uint8_t z_ = 0;
bool deleted_ = false;
std::string name_;
LayerType layer_;
ObjectOption options_ = ObjectOption::Nothing;
std::vector<gfx::Tile16> tiles_;
std::vector<uint8_t> preview_object_data_;
};
class Subtype1 : public RoomObject {