simplified dreamcast structure so it can be reused with stubs by tests

This commit is contained in:
Anthony Pesch 2016-01-24 17:12:37 -08:00
parent 631a23c11f
commit f729894480
24 changed files with 231 additions and 289 deletions

View File

@ -24,17 +24,19 @@ DEFINE_string(bios, "dc_bios.bin", "Path to BIOS");
DEFINE_string(flash, "dc_flash.bin", "Path to flash ROM");
Emulator::Emulator()
: tile_renderer_(*dc_.texcache()),
trace_writer_(nullptr),
: trace_writer_(nullptr),
tile_renderer_(nullptr),
core_events_(MAX_EVENTS),
speed_() {
rb_ = new GLBackend(window_);
dc_.set_rb(rb_);
}
Emulator::~Emulator() {
delete rb_;
delete trace_writer_;
delete tile_renderer_;
DestroyDreamcast(dc_);
}
void Emulator::Run(const char *path) {
@ -46,10 +48,14 @@ void Emulator::Run(const char *path) {
return;
}
if (!dc_.Init()) {
if (!CreateDreamcast(dc_, rb_)) {
return;
}
// setup tile renderer with the renderer backend and the dreamcast's
// internal textue cache
tile_renderer_ = new TileRenderer(*rb_, *dc_.texcache);
if (!LoadBios(FLAGS_bios.c_str())) {
return;
}
@ -98,7 +104,7 @@ bool Emulator::LoadBios(const char *path) {
return false;
}
int n = static_cast<int>(fread(dc_.bios(), sizeof(uint8_t), size, fp));
int n = static_cast<int>(fread(dc_.bios, sizeof(uint8_t), size, fp));
fclose(fp);
if (n != size) {
@ -126,7 +132,7 @@ bool Emulator::LoadFlash(const char *path) {
return false;
}
int n = static_cast<int>(fread(dc_.flash(), sizeof(uint8_t), size, fp));
int n = static_cast<int>(fread(dc_.flash, sizeof(uint8_t), size, fp));
fclose(fp);
if (n != size) {
@ -158,10 +164,10 @@ bool Emulator::LaunchBIN(const char *path) {
// load to 0x0c010000 (area 3) which is where 1ST_READ.BIN is normally
// loaded to
dc_.memory()->Memcpy(0x0c010000, data, size);
dc_.memory->Memcpy(0x0c010000, data, size);
free(data);
dc_.sh4()->SetPC(0x0c010000);
dc_.sh4->SetPC(0x0c010000);
return true;
}
@ -173,8 +179,8 @@ bool Emulator::LaunchGDI(const char *path) {
return false;
}
dc_.gdrom()->SetDisc(std::move(gdi));
dc_.sh4()->SetPC(0xa0000000);
dc_.gdrom->SetDisc(std::move(gdi));
dc_.sh4->SetPC(0xa0000000);
return true;
}
@ -203,7 +209,7 @@ void Emulator::ToggleTracing() {
LOG_INFO("End tracing");
}
dc_.set_trace_writer(trace_writer_);
dc_.trace_writer = trace_writer_;
}
void Emulator::GraphicsThread() {
@ -249,14 +255,14 @@ void Emulator::RenderGraphics() {
rb_->BeginFrame();
// render the latest tile context
if (TileContext *tactx = dc_.ta()->GetLastContext()) {
tile_renderer_.RenderContext(tactx, rb_);
if (TileContext *tactx = dc_.ta->GetLastContext()) {
tile_renderer_->RenderContext(tactx);
}
// render stats
char stats[512];
float speed = *reinterpret_cast<float *>(&speed_);
snprintf(stats, sizeof(stats), "%.2f%%, %.2f rps", speed, dc_.pvr()->rps());
snprintf(stats, sizeof(stats), "%.2f%%, %.2f rps", speed, dc_.pvr->rps());
rb_->RenderText2D(0, 0, 12.0f, 0xffffffff, stats);
// render profiler
@ -343,7 +349,7 @@ void Emulator::PumpCoreEvents() {
ToggleTracing();
}
} else {
dc_.maple()->HandleInput(0, ev.key.code, ev.key.value);
dc_.maple->HandleInput(0, ev.key.code, ev.key.value);
}
} break;

View File

@ -40,9 +40,9 @@ class Emulator {
sys::Window window_;
hw::Dreamcast dc_;
hw::holly::TileRenderer tile_renderer_;
renderer::Backend *rb_;
trace::TraceWriter *trace_writer_;
hw::holly::TileRenderer *tile_renderer_;
// variables accessed by both the graphics and core thread
RingBuffer<sys::WindowEvent> core_events_;

View File

@ -9,7 +9,7 @@ AICA::AICA(Dreamcast *dc) : dc_(dc) {}
bool AICA::Init() {
// aica_regs_ = dc_->aica_regs();
wave_ram_ = dc_->wave_ram();
wave_ram_ = dc_->wave_ram;
return true;
}

View File

@ -5,7 +5,7 @@
namespace dvm {
namespace hw {
class Dreamcast;
struct Dreamcast;
namespace aica {

View File

@ -25,118 +25,30 @@ using namespace dvm::renderer;
using namespace dvm::sys;
using namespace dvm::trace;
Dreamcast::Dreamcast()
: // allocate registers and initialize references
holly_regs_(new Register[HOLLY_REG_SIZE >> 2]),
#define HOLLY_REG(offset, name, flags, default, type) \
name{reinterpret_cast<type &>(holly_regs_[name##_OFFSET].value)},
#include "hw/holly/holly_regs.inc"
#undef HOLLY_REG
pvr_regs_(new Register[PVR_REG_SIZE >> 2]),
#define PVR_REG(offset, name, flags, default, type) \
name{reinterpret_cast<type &>(pvr_regs_[name##_OFFSET].value)},
#include "hw/holly/pvr2_regs.inc"
#undef PVR_REG
rb_(nullptr),
trace_writer_(nullptr) {
// initialize register values
#define HOLLY_REG(addr, name, flags, default, type) \
holly_regs_[name##_OFFSET] = {flags, default};
#include "hw/holly/holly_regs.inc"
#undef HOLLY_REG
#define PVR_REG(addr, name, flags, default, type) \
pvr_regs_[name##_OFFSET] = {flags, default};
#include "hw/holly/pvr2_regs.inc"
#undef PVR_REG
scheduler_ = new Scheduler();
memory_ = new Memory();
aica_ = new AICA(this);
gdrom_ = new GDROM(this);
holly_ = new Holly(this);
maple_ = new Maple(this);
pvr_ = new PVR2(this);
sh4_ = new SH4(this);
ta_ = new TileAccelerator(this);
texcache_ = new TextureCache(this);
}
Dreamcast::~Dreamcast() {
delete[] holly_regs_;
delete[] pvr_regs_;
delete scheduler_;
delete memory_;
delete aica_;
delete gdrom_;
delete holly_;
delete maple_;
delete pvr_;
delete sh4_;
delete ta_;
delete texcache_;
}
bool Dreamcast::Init() {
if (!MapMemory()) {
return false;
}
if (!aica_->Init()) {
return false;
}
if (!gdrom_->Init()) {
return false;
}
if (!holly_->Init()) {
return false;
}
if (!maple_->Init()) {
return false;
}
if (!pvr_->Init()) {
return false;
}
if (!sh4_->Init()) {
return false;
}
if (!ta_->Init()) {
return false;
}
if (!texcache_->Init()) {
return false;
}
return true;
}
namespace dvm {
namespace hw {
// clang-format off
bool Dreamcast::MapMemory() {
if (!memory_->Init()) {
static bool MapMemory(Dreamcast &dc) {
Memory *memory = dc.memory;
if (!memory->Init()) {
return false;
}
// first, allocate static regions
RegionHandle a0_handle = memory_->AllocRegion(AREA0_START, AREA0_SIZE);
RegionHandle a1_handle = memory_->AllocRegion(AREA1_START, AREA1_SIZE);
RegionHandle a0_handle = memory->AllocRegion(AREA0_START, AREA0_SIZE);
RegionHandle a1_handle = memory->AllocRegion(AREA1_START, AREA1_SIZE);
// area 2 unused
RegionHandle a3_handle = memory_->AllocRegion(AREA3_START, AREA3_SIZE);
RegionHandle a3_handle = memory->AllocRegion(AREA3_START, AREA3_SIZE);
// area 4 unused
RegionHandle a5_handle = memory_->AllocRegion(AREA5_START, AREA5_SIZE);
RegionHandle a6_handle = memory_->AllocRegion(AREA6_START, AREA6_SIZE);
RegionHandle a7_handle = memory_->AllocRegion(AREA7_START, AREA7_SIZE);
RegionHandle a5_handle = memory->AllocRegion(AREA5_START, AREA5_SIZE);
RegionHandle a6_handle = memory->AllocRegion(AREA6_START, AREA6_SIZE);
RegionHandle a7_handle = memory->AllocRegion(AREA7_START, AREA7_SIZE);
// second, allocate dynamic regions that overlap static regions
RegionHandle holly_handle = memory_->AllocRegion(
HOLLY_REG_START, HOLLY_REG_SIZE, holly(),
RegionHandle holly_handle = memory->AllocRegion(
HOLLY_REG_START, HOLLY_REG_SIZE, dc.holly,
&Holly::ReadRegister<uint8_t>,
&Holly::ReadRegister<uint16_t>,
&Holly::ReadRegister<uint32_t>,
@ -145,8 +57,8 @@ bool Dreamcast::MapMemory() {
&Holly::WriteRegister<uint16_t>,
&Holly::WriteRegister<uint32_t>,
nullptr);
RegionHandle pvr_reg_handle = memory_->AllocRegion(
PVR_REG_START, PVR_REG_SIZE, pvr(),
RegionHandle pvr_reg_handle = memory->AllocRegion(
PVR_REG_START, PVR_REG_SIZE, dc.pvr,
nullptr,
nullptr,
&PVR2::ReadRegister,
@ -155,7 +67,7 @@ bool Dreamcast::MapMemory() {
nullptr,
&PVR2::WriteRegister,
nullptr);
// RegionHandle aica_reg_handle = memory_->AllocRegion(
// RegionHandle aica_reg_handle = memory->AllocRegion(
// AICA_REG_START, AICA_REG_SIZE, aica(),
// nullptr,
// nullptr,
@ -165,8 +77,8 @@ bool Dreamcast::MapMemory() {
// nullptr,
// &AICA::WriteRegister,
// nullptr);
RegionHandle wave_ram_handle = memory_->AllocRegion(
WAVE_RAM_START, WAVE_RAM_SIZE, aica(),
RegionHandle wave_ram_handle = memory->AllocRegion(
WAVE_RAM_START, WAVE_RAM_SIZE, dc.aica,
nullptr,
nullptr,
&AICA::ReadWave,
@ -175,8 +87,8 @@ bool Dreamcast::MapMemory() {
nullptr,
&AICA::WriteWave,
nullptr);
RegionHandle pvr_vram64_handle = memory_->AllocRegion(
PVR_VRAM64_START, PVR_VRAM64_SIZE, pvr(),
RegionHandle pvr_vram64_handle = memory->AllocRegion(
PVR_VRAM64_START, PVR_VRAM64_SIZE, dc.pvr,
&PVR2::ReadVRamInterleaved<uint8_t>,
&PVR2::ReadVRamInterleaved<uint16_t>,
&PVR2::ReadVRamInterleaved<uint32_t>,
@ -185,8 +97,8 @@ bool Dreamcast::MapMemory() {
&PVR2::WriteVRamInterleaved<uint16_t>,
&PVR2::WriteVRamInterleaved<uint32_t>,
nullptr);
RegionHandle ta_cmd_handle = memory_->AllocRegion(
TA_CMD_START, TA_CMD_SIZE, ta(),
RegionHandle ta_cmd_handle = memory->AllocRegion(
TA_CMD_START, TA_CMD_SIZE, dc.ta,
nullptr,
nullptr,
nullptr,
@ -195,8 +107,8 @@ bool Dreamcast::MapMemory() {
nullptr,
&TileAccelerator::WriteCommand,
nullptr);
RegionHandle ta_texture_handle = memory_->AllocRegion(
TA_TEXTURE_START, TA_TEXTURE_SIZE, ta(),
RegionHandle ta_texture_handle = memory->AllocRegion(
TA_TEXTURE_START, TA_TEXTURE_SIZE, dc.ta,
nullptr,
nullptr,
nullptr,
@ -205,8 +117,8 @@ bool Dreamcast::MapMemory() {
nullptr,
&TileAccelerator::WriteTexture,
nullptr);
RegionHandle sh4_reg_handle = memory_->AllocRegion(
SH4_REG_START, SH4_REG_SIZE, sh4(),
RegionHandle sh4_reg_handle = memory->AllocRegion(
SH4_REG_START, SH4_REG_SIZE, dc.sh4,
&SH4::ReadRegister<uint8_t>,
&SH4::ReadRegister<uint16_t>,
&SH4::ReadRegister<uint32_t>,
@ -215,8 +127,8 @@ bool Dreamcast::MapMemory() {
&SH4::WriteRegister<uint16_t>,
&SH4::WriteRegister<uint32_t>,
nullptr);
RegionHandle sh4_cache_handle = memory_->AllocRegion(
SH4_CACHE_START, SH4_CACHE_SIZE, sh4(),
RegionHandle sh4_cache_handle = memory->AllocRegion(
SH4_CACHE_START, SH4_CACHE_SIZE, dc.sh4,
&SH4::ReadCache<uint8_t>,
&SH4::ReadCache<uint16_t>,
&SH4::ReadCache<uint32_t>,
@ -225,8 +137,8 @@ bool Dreamcast::MapMemory() {
&SH4::WriteCache<uint16_t>,
&SH4::WriteCache<uint32_t>,
&SH4::WriteCache<uint64_t>);
RegionHandle sh4_sq_handle = memory_->AllocRegion(
SH4_SQ_START, SH4_SQ_SIZE, sh4(),
RegionHandle sh4_sq_handle = memory->AllocRegion(
SH4_SQ_START, SH4_SQ_SIZE, dc.sh4,
&SH4::ReadSQ<uint8_t>,
&SH4::ReadSQ<uint16_t>,
&SH4::ReadSQ<uint32_t>,
@ -273,18 +185,72 @@ bool Dreamcast::MapMemory() {
memmap.Mount(sh4_cache_handle, SH4_CACHE_SIZE, SH4_CACHE_START);
memmap.Mount(sh4_sq_handle, SH4_SQ_SIZE, SH4_SQ_START);
if (!memory_->Map(memmap)) {
if (!memory->Map(memmap)) {
return false;
}
bios_ = memory_->virtual_base() + BIOS_START;
flash_ = memory_->virtual_base() + FLASH_START;
wave_ram_ = memory_->virtual_base() + WAVE_RAM_START;
palette_ram_ = memory_->virtual_base() + PVR_PALETTE_START;
video_ram_ = memory_->virtual_base() + PVR_VRAM32_START;
// aica_regs_ = memory_->virtual_base() + AICA_REG_START;
ram_ = memory_->virtual_base() + MAIN_RAM_1_START;
dc.bios = memory->virtual_base() + BIOS_START;
dc.flash = memory->virtual_base() + FLASH_START;
dc.wave_ram = memory->virtual_base() + WAVE_RAM_START;
dc.palette_ram = memory->virtual_base() + PVR_PALETTE_START;
dc.video_ram = memory->virtual_base() + PVR_VRAM32_START;
// dc.aica_regs = memory->virtual_base() + AICA_REG_START;
dc.ram = memory->virtual_base() + MAIN_RAM_1_START;
return true;
}
// clang-format on
bool CreateDreamcast(Dreamcast &dc, renderer::Backend *rb) {
dc.scheduler = new Scheduler();
dc.memory = new Memory();
dc.aica = new AICA(&dc);
dc.gdrom = new GDROM(&dc);
dc.holly = new Holly(&dc);
dc.maple = new Maple(&dc);
dc.pvr = new PVR2(&dc);
dc.sh4 = new SH4(&dc);
dc.ta = new TileAccelerator(&dc);
dc.texcache = new TextureCache(&dc);
dc.rb = rb;
if (!MapMemory(dc) || //
!dc.aica->Init() || //
!dc.gdrom->Init() || //
!dc.holly->Init() || //
!dc.maple->Init() || //
!dc.pvr->Init() || //
!dc.sh4->Init() || //
!dc.ta->Init() || //
!dc.texcache->Init()) {
DestroyDreamcast(dc);
return false;
}
return true;
}
void DestroyDreamcast(Dreamcast &dc) {
delete dc.scheduler;
dc.scheduler = nullptr;
delete dc.memory;
dc.memory = nullptr;
delete dc.aica;
dc.aica = nullptr;
delete dc.gdrom;
dc.gdrom = nullptr;
delete dc.holly;
dc.holly = nullptr;
delete dc.maple;
dc.maple = nullptr;
delete dc.pvr;
dc.pvr = nullptr;
delete dc.sh4;
dc.sh4 = nullptr;
delete dc.ta;
dc.ta = nullptr;
delete dc.texcache;
dc.texcache = nullptr;
}
}
}

View File

@ -31,7 +31,6 @@ class Holly;
class PVR2;
class TextureCache;
class TileAccelerator;
class TileRenderer;
}
namespace maple {
@ -137,84 +136,58 @@ enum {
#undef PVR_REG
};
class Dreamcast {
public:
// uint8_t *aica_regs() { return aica_regs_; }
Register *holly_regs() { return holly_regs_; }
Register *pvr_regs() { return pvr_regs_; }
uint8_t *bios() { return bios_; }
uint8_t *flash() { return flash_; }
uint8_t *wave_ram() { return wave_ram_; }
uint8_t *palette_ram() { return palette_ram_; }
uint8_t *video_ram() { return video_ram_; }
hw::Memory *memory() { return memory_; }
hw::Scheduler *scheduler() { return scheduler_; }
hw::aica::AICA *aica() { return aica_; }
hw::gdrom::GDROM *gdrom() { return gdrom_; }
hw::holly::Holly *holly() { return holly_; }
hw::maple::Maple *maple() { return maple_; }
hw::holly::PVR2 *pvr() { return pvr_; }
hw::sh4::SH4 *sh4() { return sh4_; }
hw::holly::TileAccelerator *ta() { return ta_; }
hw::holly::TextureCache *texcache() { return texcache_; }
renderer::Backend *rb() { return rb_; }
void set_rb(renderer::Backend *rb) { rb_ = rb; }
trace::TraceWriter *trace_writer() { return trace_writer_; }
void set_trace_writer(trace::TraceWriter *trace_writer) {
trace_writer_ = trace_writer;
}
Dreamcast();
~Dreamcast();
bool Init();
private:
Register *holly_regs_;
public:
#define HOLLY_REG(offset, name, flags, default, type) type &name;
struct Dreamcast {
Dreamcast() {
#define HOLLY_REG(addr, name, flags, default, type) \
holly_regs[name##_OFFSET] = {flags, default};
#include "hw/holly/holly_regs.inc"
#undef HOLLY_REG
private:
Register *pvr_regs_;
#define PVR_REG(addr, name, flags, default, type) \
pvr_regs[name##_OFFSET] = {flags, default};
#include "hw/holly/pvr2_regs.inc"
#undef PVR_REG
}
public:
#define PVR_REG(offset, name, flags, default, type) type &name;
// uint8_t *aica_regs;
Register holly_regs[HOLLY_REG_SIZE >> 2];
Register pvr_regs[PVR_REG_SIZE >> 2];
#define HOLLY_REG(offset, name, flags, default, type) \
type &name{reinterpret_cast<type &>(holly_regs[name##_OFFSET].value)};
#include "hw/holly/holly_regs.inc"
#undef HOLLY_REG
#define PVR_REG(offset, name, flags, default, type) \
type &name{reinterpret_cast<type &>(pvr_regs[name##_OFFSET].value)};
#include "hw/holly/pvr2_regs.inc"
#undef PVR_REG
private:
bool MapMemory();
uint8_t *bios;
uint8_t *flash;
uint8_t *palette_ram;
uint8_t *ram;
uint8_t *video_ram;
uint8_t *wave_ram;
// uint8_t *aica_regs_;
uint8_t *bios_;
uint8_t *flash_;
uint8_t *palette_ram_;
uint8_t *ram_;
uint8_t *video_ram_;
uint8_t *wave_ram_;
hw::Memory *memory_;
hw::Scheduler *scheduler_;
hw::aica::AICA *aica_;
hw::gdrom::GDROM *gdrom_;
hw::holly::Holly *holly_;
hw::maple::Maple *maple_;
hw::holly::PVR2 *pvr_;
hw::sh4::SH4 *sh4_;
hw::holly::TileAccelerator *ta_;
hw::holly::TextureCache *texcache_;
hw::Memory *memory;
hw::Scheduler *scheduler;
hw::aica::AICA *aica;
hw::gdrom::GDROM *gdrom;
hw::holly::Holly *holly;
hw::maple::Maple *maple;
hw::holly::PVR2 *pvr;
hw::sh4::SH4 *sh4;
hw::holly::TileAccelerator *ta;
hw::holly::TextureCache *texcache;
// not owned by us
renderer::Backend *rb_;
trace::TraceWriter *trace_writer_;
renderer::Backend *rb;
trace::TraceWriter *trace_writer;
};
bool CreateDreamcast(Dreamcast &dc, renderer::Backend *rb);
void DestroyDreamcast(Dreamcast &dc);
}
}

View File

@ -31,9 +31,9 @@ GDROM::GDROM(Dreamcast *dc)
GDROM::~GDROM() { delete[] dma_buffer_; }
bool GDROM::Init() {
memory_ = dc_->memory();
holly_ = dc_->holly();
holly_regs_ = dc_->holly_regs();
memory_ = dc_->memory;
holly_ = dc_->holly;
holly_regs_ = dc_->holly_regs;
SetDisc(nullptr);

View File

@ -10,7 +10,7 @@ namespace holly {
class Holly;
}
class Dreamcast;
struct Dreamcast;
class Memory;
struct Register;

View File

@ -16,10 +16,10 @@ using namespace dvm::sys;
Holly::Holly(Dreamcast *dc) : dc_(dc) {}
bool Holly::Init() {
holly_regs_ = dc_->holly_regs();
gdrom_ = dc_->gdrom();
maple_ = dc_->maple();
sh4_ = dc_->sh4();
holly_regs_ = dc_->holly_regs;
gdrom_ = dc_->gdrom;
maple_ = dc_->maple;
sh4_ = dc_->sh4;
return true;
}
@ -30,7 +30,7 @@ void Holly::RequestInterrupt(HollyInterrupt intr) {
uint32_t irq = static_cast<uint32_t>(intr & ~HOLLY_INTC_MASK);
if (intr == HOLLY_INTC_PCVOINT) {
dc_->maple()->VBlank();
dc_->maple->VBlank();
}
switch (type) {

View File

@ -15,7 +15,7 @@ namespace sh4 {
class SH4;
}
class Dreamcast;
struct Dreamcast;
struct Register;
namespace holly {

View File

@ -12,13 +12,13 @@ PVR2::PVR2(Dreamcast *dc)
: dc_(dc), line_timer_(INVALID_TIMER), current_scanline_(0), rps_(0.0f) {}
bool PVR2::Init() {
scheduler_ = dc_->scheduler();
holly_ = dc_->holly();
ta_ = dc_->ta();
texcache_ = dc_->texcache();
pvr_regs_ = dc_->pvr_regs();
palette_ram_ = dc_->palette_ram();
video_ram_ = dc_->video_ram();
scheduler_ = dc_->scheduler;
holly_ = dc_->holly;
ta_ = dc_->ta;
texcache_ = dc_->texcache;
pvr_regs_ = dc_->pvr_regs;
palette_ram_ = dc_->palette_ram;
video_ram_ = dc_->video_ram;
ReconfigureSPG();

View File

@ -6,7 +6,7 @@
namespace dvm {
namespace hw {
class Dreamcast;
struct Dreamcast;
struct Register;
namespace holly {

View File

@ -23,9 +23,9 @@ TextureHandle TextureCache::GetTexture(const TSP &tsp, const TCW &tcw,
}
// if the trace writer has changed, clear the cache to force insert events
if (dc_->trace_writer() != trace_writer_) {
if (dc_->trace_writer != trace_writer_) {
Clear();
trace_writer_ = dc_->trace_writer();
trace_writer_ = dc_->trace_writer;
}
// see if an an entry already exists
@ -40,7 +40,7 @@ TextureHandle TextureCache::GetTexture(const TSP &tsp, const TCW &tcw,
uint32_t texture_addr = tcw.texture_addr << 3;
// get the texture data
uint8_t *video_ram = dc_->video_ram();
uint8_t *video_ram = dc_->video_ram;
uint8_t *texture = &video_ram[texture_addr];
int width = 8 << tsp.texture_u_size;
int height = 8 << tsp.texture_v_size;
@ -50,7 +50,7 @@ TextureHandle TextureCache::GetTexture(const TSP &tsp, const TCW &tcw,
int texture_size = (width * height * element_size_bits) >> 3;
// get the palette data
uint8_t *palette_ram = dc_->palette_ram();
uint8_t *palette_ram = dc_->palette_ram;
uint8_t *palette = nullptr;
uint32_t palette_addr = 0;
int palette_size = 0;
@ -175,7 +175,7 @@ void TextureCache::Invalidate(TextureCacheMap::iterator it) {
RemoveAccessWatch(entry.palette_watch);
}
dc_->rb()->FreeTexture(entry.handle);
dc_->rb->FreeTexture(entry.handle);
textures_.erase(it);
}

View File

@ -14,7 +14,7 @@ class TraceWriter;
}
namespace hw {
class Dreamcast;
struct Dreamcast;
namespace holly {
@ -37,7 +37,7 @@ class TextureCache : public TextureProvider {
bool Init();
renderer::TextureHandle GetTexture(const TSP &tsp, const TCW &tcw,
RegisterTextureCallback register_cb);
RegisterTextureCallback register_cb) final;
private:
static void HandleTextureWrite(void *ctx, const sys::Exception &ex,

View File

@ -212,10 +212,10 @@ TileAccelerator::TileAccelerator(Dreamcast *dc) : dc_(dc), contexts_() {
}
bool TileAccelerator::Init() {
memory_ = dc_->memory();
holly_ = dc_->holly();
texcache_ = dc_->texcache();
video_ram_ = dc_->video_ram();
memory_ = dc_->memory;
holly_ = dc_->holly;
texcache_ = dc_->texcache;
video_ram_ = dc_->video_ram;
return true;
}
@ -312,8 +312,8 @@ void TileAccelerator::FinalizeContext(uint32_t addr) {
WriteBackgroundState(tactx);
// add context to trace
if (dc_->trace_writer()) {
dc_->trace_writer()->WriteRenderContext(tactx);
if (dc_->trace_writer) {
dc_->trace_writer->WriteRenderContext(tactx);
}
// tell holly that rendering is complete

View File

@ -13,7 +13,7 @@ class TraceWriter;
}
namespace hw {
class Dreamcast;
struct Dreamcast;
class Memory;
namespace holly {

View File

@ -105,8 +105,9 @@ TextureKey TextureProvider::GetTextureKey(const TSP &tsp, const TCW &tcw) {
return ((uint64_t)tsp.full << 32) | tcw.full;
}
TileRenderer::TileRenderer(TextureProvider &texture_provider)
: texture_provider_(texture_provider) {
TileRenderer::TileRenderer(renderer::Backend &rb,
TextureProvider &texture_provider)
: rb_(rb), texture_provider_(texture_provider) {
surfs_ = new Surface[MAX_SURFACES];
verts_ = new Vertex[MAX_VERTICES];
sorted_surfs_ = new int[MAX_SURFACES];
@ -118,11 +119,11 @@ TileRenderer::~TileRenderer() {
delete[] sorted_surfs_;
}
void TileRenderer::RenderContext(const TileContext *tactx, Backend *rb) {
ParseContext(tactx, rb);
void TileRenderer::RenderContext(const TileContext *tactx) {
ParseContext(tactx);
const Eigen::Matrix4f &projection = GetProjectionMatrix(tactx);
rb->RenderSurfaces(projection, surfs_, num_surfs_, verts_, num_verts_,
rb_.RenderSurfaces(projection, surfs_, num_surfs_, verts_, num_verts_,
sorted_surfs_);
}
@ -305,7 +306,7 @@ void TileRenderer::ParseBackground(const TileContext *tactx) {
// NOTE this offset color implementation is not correct at all, see the
// Texture/Shading Instruction in the TSP instruction word
void TileRenderer::ParsePolyParam(const TileContext *tactx, Backend *rb,
void TileRenderer::ParsePolyParam(const TileContext *tactx,
const PolyParam *param) {
last_poly_ = param;
last_vertex_ = nullptr;
@ -336,10 +337,9 @@ void TileRenderer::ParsePolyParam(const TileContext *tactx, Backend *rb,
surf->depth_func = DEPTH_GEQUAL;
}
surf->texture =
param->type0.pcw.texture
? GetTexture(tactx, rb, param->type0.tsp, param->type0.tcw)
: 0;
surf->texture = param->type0.pcw.texture
? GetTexture(tactx, param->type0.tsp, param->type0.tcw)
: 0;
int poly_type = TileAccelerator::GetPolyType(param->type0.pcw);
switch (poly_type) {
@ -391,7 +391,7 @@ void TileRenderer::ParsePolyParam(const TileContext *tactx, Backend *rb,
}
}
void TileRenderer::ParseVertexParam(const TileContext *tactx, Backend *rb,
void TileRenderer::ParseVertexParam(const TileContext *tactx,
const VertexParam *param) {
// If there is no need to change the Global Parameters, a Vertex Parameter for
// the next polygon may be input immediately after inputting a Vertex
@ -608,7 +608,7 @@ void TileRenderer::ParseEndOfList(const TileContext *tactx) {
last_sorted_surf_ = num_surfs_;
}
void TileRenderer::ParseContext(const TileContext *tactx, Backend *rb) {
void TileRenderer::ParseContext(const TileContext *tactx) {
PROFILER_GPU("TileRenderer::ParseContext");
const uint8_t *data = tactx->data;
@ -643,17 +643,16 @@ void TileRenderer::ParseContext(const TileContext *tactx, Backend *rb) {
// global params
case TA_PARAM_POLY_OR_VOL:
ParsePolyParam(tactx, rb, reinterpret_cast<const PolyParam *>(data));
ParsePolyParam(tactx, reinterpret_cast<const PolyParam *>(data));
break;
case TA_PARAM_SPRITE:
ParsePolyParam(tactx, rb, reinterpret_cast<const PolyParam *>(data));
ParsePolyParam(tactx, reinterpret_cast<const PolyParam *>(data));
break;
// vertex params
case TA_PARAM_VERTEX:
ParseVertexParam(tactx, rb,
reinterpret_cast<const VertexParam *>(data));
ParseVertexParam(tactx, reinterpret_cast<const VertexParam *>(data));
break;
default:
@ -707,8 +706,7 @@ Eigen::Matrix4f TileRenderer::GetProjectionMatrix(const TileContext *tactx) {
}
TextureHandle TileRenderer::RegisterTexture(const TileContext *tactx,
Backend *rb, const TSP &tsp,
const TCW &tcw,
const TSP &tsp, const TCW &tcw,
const uint8_t *palette,
const uint8_t *texture) {
static uint8_t converted[1024 * 1024 * 4];
@ -883,7 +881,7 @@ TextureHandle TileRenderer::RegisterTexture(const TileContext *tactx,
? WRAP_CLAMP_TO_EDGE
: (tsp.flip_v ? WRAP_MIRRORED_REPEAT : WRAP_REPEAT);
TextureHandle handle = rb->RegisterTexture(pixel_fmt, filter, wrap_u, wrap_v,
TextureHandle handle = rb_.RegisterTexture(pixel_fmt, filter, wrap_u, wrap_v,
mip_mapped, width, height, output);
if (!handle) {
@ -894,10 +892,10 @@ TextureHandle TileRenderer::RegisterTexture(const TileContext *tactx,
return handle;
}
TextureHandle TileRenderer::GetTexture(const TileContext *tactx, Backend *rb,
const TSP &tsp, const TCW &tcw) {
TextureHandle TileRenderer::GetTexture(const TileContext *tactx, const TSP &tsp,
const TCW &tcw) {
return texture_provider_.GetTexture(
tsp, tcw, [&](const uint8_t *palette, const uint8_t *texture) {
return RegisterTexture(tactx, rb, tsp, tcw, palette, texture);
return RegisterTexture(tactx, tsp, tcw, palette, texture);
});
}

View File

@ -42,10 +42,10 @@ enum { MAX_SURFACES = 0x10000, MAX_VERTICES = 0x10000 };
class TileRenderer {
public:
TileRenderer(TextureProvider &texture_provider);
TileRenderer(renderer::Backend &rb, TextureProvider &texture_provider);
~TileRenderer();
void RenderContext(const TileContext *tactx, renderer::Backend *rb);
void RenderContext(const TileContext *tactx);
private:
void Reset();
@ -59,23 +59,20 @@ class TileRenderer {
void ParseOffsetColor(float r, float g, float b, float a, uint32_t *color);
void ParseOffsetColor(float intensity, uint32_t *color);
void ParseBackground(const TileContext *tactx);
void ParsePolyParam(const TileContext *tactx, renderer::Backend *rb,
const PolyParam *param);
void ParseVertexParam(const TileContext *tactx, renderer::Backend *rb,
const VertexParam *param);
void ParsePolyParam(const TileContext *tactx, const PolyParam *param);
void ParseVertexParam(const TileContext *tactx, const VertexParam *param);
void ParseEndOfList(const TileContext *tactx);
void ParseContext(const TileContext *tactx, renderer::Backend *rb);
void ParseContext(const TileContext *tactx);
Eigen::Matrix4f GetProjectionMatrix(const TileContext *tactx);
renderer::TextureHandle RegisterTexture(const TileContext *tactx,
renderer::Backend *rb, const TSP &tsp,
const TCW &tcw,
const TSP &tsp, const TCW &tcw,
const uint8_t *palette,
const uint8_t *texture);
renderer::TextureHandle GetTexture(const TileContext *tactx,
renderer::Backend *rb, const TSP &tsp,
renderer::TextureHandle GetTexture(const TileContext *tactx, const TSP &tsp,
const TCW &tcw);
renderer::Backend &rb_;
TextureProvider &texture_provider_;
// current global state

View File

@ -17,9 +17,9 @@ Maple::Maple(Dreamcast *dc) : dc_(dc), devices_() {
}
bool Maple::Init() {
memory_ = dc_->memory();
holly_ = dc_->holly();
holly_regs_ = dc_->holly_regs();
memory_ = dc_->memory;
holly_ = dc_->holly;
holly_regs_ = dc_->holly_regs;
return true;
}

View File

@ -10,7 +10,7 @@ namespace holly {
class Holly;
}
class Dreamcast;
struct Dreamcast;
class Memory;
struct Register;

View File

@ -37,8 +37,8 @@ SH4::SH4(Dreamcast *dc)
SH4::~SH4() { delete code_cache_; }
bool SH4::Init() {
memory_ = dc_->memory();
scheduler_ = dc_->scheduler();
memory_ = dc_->memory;
scheduler_ = dc_->scheduler;
code_cache_ = new SH4CodeCache(memory_, &SH4::CompilePC);

View File

@ -10,7 +10,7 @@ struct SH4Test;
namespace dvm {
namespace hw {
class Dreamcast;
struct Dreamcast;
namespace sh4 {

View File

@ -42,14 +42,16 @@ TextureHandle TraceTextureCache::GetTexture(
return texture.handle;
}
TraceViewer::TraceViewer() : tile_renderer_(texcache_) {
TraceViewer::TraceViewer() {
rb_ = new GLBackend(wnd_);
tile_renderer_ = new TileRenderer(*rb_, texcache_);
current_ctx_ = new TileContext();
}
TraceViewer::~TraceViewer() {
delete current_ctx_;
delete rb_;
delete tile_renderer_;
delete current_ctx_;
}
void TraceViewer::Run(const char *path) {
@ -124,7 +126,7 @@ void TraceViewer::PumpEvents() {
void TraceViewer::RenderFrame() {
rb_->BeginFrame();
tile_renderer_.RenderContext(current_ctx_, rb_);
tile_renderer_->RenderContext(current_ctx_);
// render stats
char stats[512];

View File

@ -54,8 +54,8 @@ class TraceViewer {
sys::Window wnd_;
TraceTextureCache texcache_;
hw::holly::TileRenderer tile_renderer_;
renderer::Backend *rb_;
hw::holly::TileRenderer *tile_renderer_;
TraceReader reader_;
TraceCommand *current_cmd_;