Refactor Emulator and Snes classes for improved memory access
- Updated Emulator class to remove inheritance from SharedRom and streamline ROM handling. - Refactored memory access methods in Emulator and Snes classes to use consistent naming conventions. - Enhanced DungeonObjectRenderer to utilize the updated Snes class for CPU and memory operations, improving clarity and maintainability. - Cleaned up unnecessary comments and improved code formatting for better readability.
This commit is contained in:
@@ -58,8 +58,8 @@ void Emulator::Run() {
|
|||||||
}
|
}
|
||||||
rom_data_ = rom()->vector();
|
rom_data_ = rom()->vector();
|
||||||
snes_.Init(rom_data_);
|
snes_.Init(rom_data_);
|
||||||
wanted_frames_ = 1.0 / (snes_.Memory().pal_timing() ? 50.0 : 60.0);
|
wanted_frames_ = 1.0 / (snes_.memory().pal_timing() ? 50.0 : 60.0);
|
||||||
wanted_samples_ = 48000 / (snes_.Memory().pal_timing() ? 50 : 60);
|
wanted_samples_ = 48000 / (snes_.memory().pal_timing() ? 50 : 60);
|
||||||
loaded = true;
|
loaded = true;
|
||||||
|
|
||||||
count_frequency = SDL_GetPerformanceFrequency();
|
count_frequency = SDL_GetPerformanceFrequency();
|
||||||
@@ -491,8 +491,8 @@ void Emulator::RenderMemoryViewer() {
|
|||||||
ImGuiWindowFlags_NoMove |
|
ImGuiWindowFlags_NoMove |
|
||||||
ImGuiWindowFlags_NoScrollbar |
|
ImGuiWindowFlags_NoScrollbar |
|
||||||
ImGuiWindowFlags_NoScrollWithMouse)) {
|
ImGuiWindowFlags_NoScrollWithMouse)) {
|
||||||
mem_edit.DrawContents((void*)snes_.Memory().rom_.data(),
|
mem_edit.DrawContents((void*)snes_.memory().rom_.data(),
|
||||||
snes_.Memory().rom_.size());
|
snes_.memory().rom_.size());
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ struct EmulatorKeybindings {
|
|||||||
* @class Emulator
|
* @class Emulator
|
||||||
* @brief A class for emulating and debugging SNES games.
|
* @brief A class for emulating and debugging SNES games.
|
||||||
*/
|
*/
|
||||||
class Emulator : public SharedRom {
|
class Emulator {
|
||||||
public:
|
public:
|
||||||
Emulator() {
|
Emulator() {
|
||||||
std::string emulator_layout = R"(
|
std::string emulator_layout = R"(
|
||||||
@@ -92,7 +92,7 @@ class Emulator : public SharedRom {
|
|||||||
{"cpu.PC", &snes_.cpu().PC},
|
{"cpu.PC", &snes_.cpu().PC},
|
||||||
{"cpu.status", &snes_.cpu().status},
|
{"cpu.status", &snes_.cpu().status},
|
||||||
{"snes.cycle_count", &snes_.mutable_cycles()},
|
{"snes.cycle_count", &snes_.mutable_cycles()},
|
||||||
{"cpu.SP", &snes_.Memory().mutable_sp()},
|
{"cpu.SP", &snes_.memory().mutable_sp()},
|
||||||
{"spc.A", &snes_.apu().spc700().A},
|
{"spc.A", &snes_.apu().spc700().A},
|
||||||
{"spc.X", &snes_.apu().spc700().X},
|
{"spc.X", &snes_.apu().spc700().X},
|
||||||
{"spc.Y", &snes_.apu().spc700().Y},
|
{"spc.Y", &snes_.apu().spc700().Y},
|
||||||
@@ -115,6 +115,8 @@ class Emulator : public SharedRom {
|
|||||||
audio_device_ = audio_device;
|
audio_device_ = audio_device;
|
||||||
}
|
}
|
||||||
auto wanted_samples() const -> int { return wanted_samples_; }
|
auto wanted_samples() const -> int { return wanted_samples_; }
|
||||||
|
auto rom() { return rom_; }
|
||||||
|
auto mutable_rom() { return rom_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void RenderNavBar();
|
void RenderNavBar();
|
||||||
@@ -153,6 +155,7 @@ class Emulator : public SharedRom {
|
|||||||
int16_t* audio_buffer_;
|
int16_t* audio_buffer_;
|
||||||
SDL_AudioDeviceID audio_device_;
|
SDL_AudioDeviceID audio_device_;
|
||||||
|
|
||||||
|
Rom* rom_;
|
||||||
Snes snes_;
|
Snes snes_;
|
||||||
SDL_Texture* ppu_texture_;
|
SDL_Texture* ppu_texture_;
|
||||||
|
|
||||||
|
|||||||
@@ -30,27 +30,27 @@ typedef struct DmaChannel {
|
|||||||
uint8_t b_addr;
|
uint8_t b_addr;
|
||||||
uint16_t a_addr;
|
uint16_t a_addr;
|
||||||
uint8_t a_bank;
|
uint8_t a_bank;
|
||||||
uint16_t size; // also indirect hdma adr
|
uint16_t size; // also indirect hdma adr
|
||||||
uint8_t ind_bank; // hdma
|
uint8_t ind_bank; // hdma
|
||||||
uint16_t table_addr; // hdma
|
uint16_t table_addr; // hdma
|
||||||
uint8_t rep_count; // hdma
|
uint8_t rep_count; // hdma
|
||||||
uint8_t unusedByte;
|
uint8_t unusedByte;
|
||||||
bool dma_active;
|
bool dma_active;
|
||||||
bool hdma_active;
|
bool hdma_active;
|
||||||
uint8_t mode;
|
uint8_t mode;
|
||||||
bool fixed;
|
bool fixed;
|
||||||
bool decrement;
|
bool decrement;
|
||||||
bool indirect; // hdma
|
bool indirect; // hdma
|
||||||
bool from_b;
|
bool from_b;
|
||||||
bool unusedBit;
|
bool unusedBit;
|
||||||
bool do_transfer; // hdma
|
bool do_transfer; // hdma
|
||||||
bool terminated; // hdma
|
bool terminated; // hdma
|
||||||
} DmaChannel;
|
} DmaChannel;
|
||||||
|
|
||||||
typedef struct CpuCallbacks {
|
typedef struct CpuCallbacks {
|
||||||
std::function<uint8_t(uint32_t)> read_byte;
|
std::function<uint8_t(uint32_t)> read_byte = nullptr;
|
||||||
std::function<void(uint32_t, uint8_t)> write_byte;
|
std::function<void(uint32_t, uint8_t)> write_byte = nullptr;
|
||||||
std::function<void(bool waiting)> idle;
|
std::function<void(bool waiting)> idle = nullptr;
|
||||||
} CpuCallbacks;
|
} CpuCallbacks;
|
||||||
|
|
||||||
constexpr uint32_t kROMStart = 0x008000;
|
constexpr uint32_t kROMStart = 0x008000;
|
||||||
@@ -62,7 +62,7 @@ constexpr uint32_t kRAMSize = 0x20000;
|
|||||||
* @brief Memory interface
|
* @brief Memory interface
|
||||||
*/
|
*/
|
||||||
class Memory {
|
class Memory {
|
||||||
public:
|
public:
|
||||||
virtual ~Memory() = default;
|
virtual ~Memory() = default;
|
||||||
virtual uint8_t ReadByte(uint32_t address) const = 0;
|
virtual uint8_t ReadByte(uint32_t address) const = 0;
|
||||||
virtual uint16_t ReadWord(uint32_t address) const = 0;
|
virtual uint16_t ReadWord(uint32_t address) const = 0;
|
||||||
@@ -116,25 +116,25 @@ public:
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class MemoryImpl : public Memory {
|
class MemoryImpl : public Memory {
|
||||||
public:
|
public:
|
||||||
void Initialize(const std::vector<uint8_t> &romData, bool verbose = false);
|
void Initialize(const std::vector<uint8_t> &romData, bool verbose = false);
|
||||||
|
|
||||||
uint16_t GetHeaderOffset() {
|
uint16_t GetHeaderOffset() {
|
||||||
uint16_t offset;
|
uint16_t offset;
|
||||||
switch (memory_[(0x00 << 16) + 0xFFD5] & 0x07) {
|
switch (memory_[(0x00 << 16) + 0xFFD5] & 0x07) {
|
||||||
case 0: // LoROM
|
case 0: // LoROM
|
||||||
offset = 0x7FC0;
|
offset = 0x7FC0;
|
||||||
break;
|
break;
|
||||||
case 1: // HiROM
|
case 1: // HiROM
|
||||||
offset = 0xFFC0;
|
offset = 0xFFC0;
|
||||||
break;
|
break;
|
||||||
case 5: // ExHiROM
|
case 5: // ExHiROM
|
||||||
offset = 0x40;
|
offset = 0x40;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw std::invalid_argument(
|
throw std::invalid_argument(
|
||||||
"Unable to locate supported ROM mapping mode in the provided ROM "
|
"Unable to locate supported ROM mapping mode in the provided ROM "
|
||||||
"file. Please try another ROM file.");
|
"file. Please try another ROM file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
@@ -285,7 +285,7 @@ public:
|
|||||||
std::vector<uint8_t> rom_;
|
std::vector<uint8_t> rom_;
|
||||||
std::vector<uint8_t> ram_;
|
std::vector<uint8_t> ram_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t GetMappedAddress(uint32_t address) const;
|
uint32_t GetMappedAddress(uint32_t address) const;
|
||||||
|
|
||||||
bool verbose_ = false;
|
bool verbose_ = false;
|
||||||
@@ -323,7 +323,7 @@ private:
|
|||||||
std::vector<uint8_t> memory_;
|
std::vector<uint8_t> memory_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace emu
|
} // namespace emu
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|
||||||
#endif // YAZE_APP_EMU_MEMORY_H
|
#endif // YAZE_APP_EMU_MEMORY_H
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class Snes {
|
|||||||
auto cpu() -> Cpu& { return cpu_; }
|
auto cpu() -> Cpu& { return cpu_; }
|
||||||
auto ppu() -> Ppu& { return ppu_; }
|
auto ppu() -> Ppu& { return ppu_; }
|
||||||
auto apu() -> Apu& { return apu_; }
|
auto apu() -> Apu& { return apu_; }
|
||||||
auto Memory() -> MemoryImpl& { return memory_; }
|
auto memory() -> MemoryImpl& { return memory_; }
|
||||||
auto get_ram() -> uint8_t* { return ram; }
|
auto get_ram() -> uint8_t* { return ram; }
|
||||||
auto mutable_cycles() -> uint64_t& { return cycles_; }
|
auto mutable_cycles() -> uint64_t& { return cycles_; }
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "app/zelda3/dungeon/object_renderer.h"
|
#include "app/zelda3/dungeon/object_renderer.h"
|
||||||
|
|
||||||
|
#include "app/gfx/arena.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace zelda3 {
|
namespace zelda3 {
|
||||||
|
|
||||||
@@ -8,8 +10,7 @@ void DungeonObjectRenderer::LoadObject(uint32_t routine_ptr,
|
|||||||
vram_.sheets = sheet_ids;
|
vram_.sheets = sheet_ids;
|
||||||
|
|
||||||
rom_data_ = rom()->vector();
|
rom_data_ = rom()->vector();
|
||||||
// Prepare the CPU and memory environment
|
snes_.memory().Initialize(rom_data_);
|
||||||
memory_.Initialize(rom_data_);
|
|
||||||
|
|
||||||
// Configure the object based on the fetched information
|
// Configure the object based on the fetched information
|
||||||
ConfigureObject();
|
ConfigureObject();
|
||||||
@@ -19,16 +20,16 @@ void DungeonObjectRenderer::LoadObject(uint32_t routine_ptr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DungeonObjectRenderer::ConfigureObject() {
|
void DungeonObjectRenderer::ConfigureObject() {
|
||||||
cpu.A = 0x03D8;
|
snes_.cpu().A = 0x03D8;
|
||||||
cpu.X = 0x03D8;
|
snes_.cpu().X = 0x03D8;
|
||||||
cpu.DB = 0x7E;
|
snes_.cpu().DB = 0x7E;
|
||||||
// VRAM target destinations
|
// VRAM target destinations
|
||||||
cpu.WriteLong(0xBF, 0x7E2000);
|
snes_.cpu().WriteLong(0xBF, 0x7E2000);
|
||||||
cpu.WriteLong(0xCB, 0x7E2080);
|
snes_.cpu().WriteLong(0xCB, 0x7E2080);
|
||||||
cpu.WriteLong(0xC2, 0x7E2002);
|
snes_.cpu().WriteLong(0xC2, 0x7E2002);
|
||||||
cpu.WriteLong(0xCE, 0x7E2082);
|
snes_.cpu().WriteLong(0xCE, 0x7E2082);
|
||||||
cpu.SetAccumulatorSize(false);
|
snes_.cpu().SetAccumulatorSize(false);
|
||||||
cpu.SetIndexSize(false);
|
snes_.cpu().SetIndexSize(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,15 +60,15 @@ void DungeonObjectRenderer::ConfigureObject() {
|
|||||||
#_0198AD: RTS
|
#_0198AD: RTS
|
||||||
*/
|
*/
|
||||||
void DungeonObjectRenderer::RenderObject(uint32_t routine_ptr) {
|
void DungeonObjectRenderer::RenderObject(uint32_t routine_ptr) {
|
||||||
cpu.PB = 0x01;
|
snes_.cpu().PB = 0x01;
|
||||||
cpu.PC = routine_ptr;
|
snes_.cpu().PC = routine_ptr;
|
||||||
|
|
||||||
// Set up initial state for object drawing
|
// Set up initial state for object drawing
|
||||||
cpu.Y = 0; // Start at the beginning of the tilemap
|
snes_.cpu().Y = 0; // Start at the beginning of the tilemap
|
||||||
cpu.D = 0x7E; // Direct page register for memory access
|
snes_.cpu().D = 0x7E; // Direct page register for memory access
|
||||||
|
|
||||||
// Push return address to stack
|
// Push return address to stack
|
||||||
cpu.PushLong(0x01 << 16 | 0xFFFF); // Push a dummy return address
|
snes_.cpu().PushLong(0x01 << 16 | 0xFFFF); // Push a dummy return address
|
||||||
|
|
||||||
// Set up a maximum instruction count to prevent infinite loops
|
// Set up a maximum instruction count to prevent infinite loops
|
||||||
const int MAX_INSTRUCTIONS = 10000;
|
const int MAX_INSTRUCTIONS = 10000;
|
||||||
@@ -75,17 +76,18 @@ void DungeonObjectRenderer::RenderObject(uint32_t routine_ptr) {
|
|||||||
|
|
||||||
// Execute instructions until we hit a return instruction or max count
|
// Execute instructions until we hit a return instruction or max count
|
||||||
while (instruction_count < MAX_INSTRUCTIONS) {
|
while (instruction_count < MAX_INSTRUCTIONS) {
|
||||||
uint8_t opcode = cpu.ReadByte(cpu.PB << 16 | cpu.PC);
|
uint8_t opcode =
|
||||||
|
snes_.cpu().ReadByte(snes_.cpu().PB << 16 | snes_.cpu().PC);
|
||||||
|
|
||||||
// Check for RTS (Return from Subroutine) instruction
|
// Check for RTS (Return from Subroutine) instruction
|
||||||
if (opcode == 0x60) {
|
if (opcode == 0x60) {
|
||||||
// Execute the RTS instruction
|
// Execute the RTS instruction
|
||||||
cpu.ExecuteInstruction(opcode);
|
snes_.cpu().ExecuteInstruction(opcode);
|
||||||
break; // Exit the loop after RTS
|
break; // Exit the loop after RTS
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute the instruction
|
// Execute the instruction
|
||||||
cpu.ExecuteInstruction(opcode);
|
snes_.cpu().ExecuteInstruction(opcode);
|
||||||
instruction_count++;
|
instruction_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +110,7 @@ void DungeonObjectRenderer::UpdateObjectBitmap() {
|
|||||||
// Iterate over tilemap in memory to read tile IDs
|
// Iterate over tilemap in memory to read tile IDs
|
||||||
for (int tile_index = 0; tile_index < 512; tile_index++) {
|
for (int tile_index = 0; tile_index < 512; tile_index++) {
|
||||||
// Read the tile ID from memory
|
// Read the tile ID from memory
|
||||||
uint16_t tile_id = memory_.ReadWord(0x7E2000 + tile_index * 2);
|
uint16_t tile_id = snes_.memory().ReadWord(0x7E2000 + tile_index * 2);
|
||||||
|
|
||||||
// Skip empty tiles (0x0000)
|
// Skip empty tiles (0x0000)
|
||||||
if (tile_id == 0) continue;
|
if (tile_id == 0) continue;
|
||||||
@@ -128,8 +130,8 @@ void DungeonObjectRenderer::UpdateObjectBitmap() {
|
|||||||
int tile_y = (tile_index / 32) * 8;
|
int tile_y = (tile_index / 32) * 8;
|
||||||
|
|
||||||
// Get the graphics sheet
|
// Get the graphics sheet
|
||||||
auto& sheet = GraphicsSheetManager::GetInstance().mutable_gfx_sheets()->at(
|
auto& sheet =
|
||||||
vram_.sheets[sheet_number]);
|
gfx::Arena::Get().mutable_gfx_sheets()->at(vram_.sheets[sheet_number]);
|
||||||
|
|
||||||
// Calculate the offset in the tilemap
|
// Calculate the offset in the tilemap
|
||||||
int tilemap_offset = tile_y * 256 + tile_x;
|
int tilemap_offset = tile_y * 256 + tile_x;
|
||||||
@@ -137,19 +139,6 @@ void DungeonObjectRenderer::UpdateObjectBitmap() {
|
|||||||
// Copy the tile from the graphics sheet to the tilemap
|
// Copy the tile from the graphics sheet to the tilemap
|
||||||
sheet.Get8x8Tile(tile_id % 32, 0, 0, tilemap_, tilemap_offset);
|
sheet.Get8x8Tile(tile_id % 32, 0, 0, tilemap_, tilemap_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the bitmap from the tilemap
|
|
||||||
bitmap_.Create(256, 256, 8, tilemap_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DungeonObjectRenderer::SetPalette(const gfx::SnesPalette& palette,
|
|
||||||
size_t transparent_index) {
|
|
||||||
// Apply the palette to the bitmap
|
|
||||||
bitmap_.SetPaletteWithTransparent(palette, transparent_index);
|
|
||||||
|
|
||||||
// Store the palette in the VRAM structure for future reference
|
|
||||||
vram_.palettes.clear();
|
|
||||||
vram_.palettes.push_back(palette);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace zelda3
|
} // namespace zelda3
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "app/emu/cpu/cpu.h"
|
#include "app/emu/snes.h"
|
||||||
#include "app/emu/memory/memory.h"
|
|
||||||
#include "app/emu/video/ppu.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/rom.h"
|
#include "app/rom.h"
|
||||||
@@ -14,80 +12,55 @@ namespace zelda3 {
|
|||||||
/**
|
/**
|
||||||
* @struct PseudoVram
|
* @struct PseudoVram
|
||||||
* @brief Simulates the SNES VRAM for object rendering
|
* @brief Simulates the SNES VRAM for object rendering
|
||||||
*
|
*
|
||||||
* This structure holds the sheet IDs and palettes needed for rendering
|
* This structure holds the sheet IDs and palettes needed for rendering
|
||||||
* dungeon objects in Link to the Past.
|
* dungeon objects in Link to the Past.
|
||||||
*/
|
*/
|
||||||
struct PseudoVram {
|
struct PseudoVram {
|
||||||
std::array<uint8_t, 16> sheets = { 0 };
|
std::array<uint8_t, 16> sheets = {0};
|
||||||
std::vector<gfx::SnesPalette> palettes;
|
std::vector<gfx::SnesPalette> palettes;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class DungeonObjectRenderer
|
* @class DungeonObjectRenderer
|
||||||
* @brief Renders dungeon objects from Link to the Past
|
* @brief Renders dungeon objects from Link to the Past
|
||||||
*
|
*
|
||||||
* This class uses the emulator subsystem to simulate the SNES CPU
|
* This class uses the emulator subsystem to simulate the SNES CPU
|
||||||
* drawing routines for dungeon objects. It captures the tile data
|
* drawing routines for dungeon objects. It captures the tile data
|
||||||
* written to memory and renders it to a bitmap.
|
* written to memory and renders it to a bitmap.
|
||||||
*/
|
*/
|
||||||
class DungeonObjectRenderer : public SharedRom {
|
class DungeonObjectRenderer {
|
||||||
public:
|
public:
|
||||||
DungeonObjectRenderer() = default;
|
DungeonObjectRenderer() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Loads and renders a dungeon object
|
* @brief Loads and renders a dungeon object
|
||||||
*
|
*
|
||||||
* @param routine_ptr Pointer to the drawing routine in ROM
|
* @param routine_ptr Pointer to the drawing routine in ROM
|
||||||
* @param sheet_ids Array of graphics sheet IDs used by the object
|
* @param sheet_ids Array of graphics sheet IDs used by the object
|
||||||
*/
|
*/
|
||||||
void LoadObject(uint32_t routine_ptr, std::array<uint8_t, 16>& sheet_ids);
|
void LoadObject(uint32_t routine_ptr, std::array<uint8_t, 16>& sheet_ids);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures the CPU state for object rendering
|
* @brief Configures the CPU state for object rendering
|
||||||
*/
|
*/
|
||||||
void ConfigureObject();
|
void ConfigureObject();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Executes the object drawing routine
|
* @brief Executes the object drawing routine
|
||||||
*
|
*
|
||||||
* @param routine_ptr Pointer to the drawing routine in ROM
|
* @param routine_ptr Pointer to the drawing routine in ROM
|
||||||
*/
|
*/
|
||||||
void RenderObject(uint32_t routine_ptr);
|
void RenderObject(uint32_t routine_ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Updates the bitmap with the rendered object
|
* @brief Updates the bitmap with the rendered object
|
||||||
*/
|
*/
|
||||||
void UpdateObjectBitmap();
|
void UpdateObjectBitmap();
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Sets the palette for the rendered object
|
|
||||||
*
|
|
||||||
* @param palette The palette to use for the object
|
|
||||||
* @param transparent_index Index of the transparent color (default: 0)
|
|
||||||
*/
|
|
||||||
void SetPalette(const gfx::SnesPalette& palette, size_t transparent_index = 0);
|
|
||||||
|
|
||||||
/**
|
auto mutable_memory() { return &tilemap_; }
|
||||||
* @brief Gets the rendered bitmap
|
auto rom() { return rom_; }
|
||||||
*
|
auto mutable_rom() { return &rom_; }
|
||||||
* @return gfx::Bitmap* Pointer to the bitmap
|
|
||||||
*/
|
|
||||||
gfx::Bitmap* bitmap() { return &bitmap_; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Gets the memory implementation
|
|
||||||
*
|
|
||||||
* @return Memory implementation
|
|
||||||
*/
|
|
||||||
auto memory() { return memory_; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Gets a mutable pointer to the memory implementation
|
|
||||||
*
|
|
||||||
* @return Mutable pointer to the memory implementation
|
|
||||||
*/
|
|
||||||
auto mutable_memory() { return &memory_; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<uint8_t> tilemap_;
|
std::vector<uint8_t> tilemap_;
|
||||||
@@ -95,11 +68,8 @@ class DungeonObjectRenderer : public SharedRom {
|
|||||||
|
|
||||||
PseudoVram vram_;
|
PseudoVram vram_;
|
||||||
|
|
||||||
emu::MemoryImpl memory_;
|
Rom* rom_;
|
||||||
emu::CpuCallbacks cpu_callbacks_;
|
emu::Snes snes_;
|
||||||
emu::Ppu ppu{memory_};
|
|
||||||
emu::Cpu cpu{memory_, cpu_callbacks_};
|
|
||||||
|
|
||||||
gfx::Bitmap bitmap_;
|
gfx::Bitmap bitmap_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user