separate GPU2D registers and renderer
This commit is contained in:
parent
f8692f85a4
commit
a046eb5038
66
src/GPU.cpp
66
src/GPU.cpp
|
@ -82,8 +82,10 @@ int FrontBuffer;
|
|||
u32* Framebuffer[2][2];
|
||||
int Renderer = 0;
|
||||
|
||||
std::unique_ptr<GPU2D> GPU2D_A = {};
|
||||
std::unique_ptr<GPU2D> GPU2D_B = {};
|
||||
GPU2D::Unit GPU2D_A(0);
|
||||
GPU2D::Unit GPU2D_B(1);
|
||||
|
||||
std::unique_ptr<GPU2D::Renderer2D> GPU2D_Renderer = {};
|
||||
|
||||
/*
|
||||
VRAM invalidation tracking
|
||||
|
@ -143,8 +145,7 @@ std::unique_ptr<GLCompositor> CurGLCompositor = {};
|
|||
|
||||
bool Init()
|
||||
{
|
||||
GPU2D_A = std::make_unique<GPU2D_Soft>(0);
|
||||
GPU2D_B = std::make_unique<GPU2D_Soft>(1);
|
||||
GPU2D_Renderer = std::make_unique<GPU2D::SoftRenderer>();
|
||||
if (!GPU3D::Init()) return false;
|
||||
|
||||
FrontBuffer = 0;
|
||||
|
@ -157,8 +158,7 @@ bool Init()
|
|||
|
||||
void DeInit()
|
||||
{
|
||||
GPU2D_A.reset();
|
||||
GPU2D_B.reset();
|
||||
GPU2D_Renderer.reset();
|
||||
GPU3D::DeInit();
|
||||
|
||||
if (Framebuffer[0][0]) delete[] Framebuffer[0][0];
|
||||
|
@ -262,13 +262,12 @@ void Reset()
|
|||
Framebuffer[1][1][i] = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
GPU2D_A->Reset();
|
||||
GPU2D_B->Reset();
|
||||
GPU2D_A.Reset();
|
||||
GPU2D_B.Reset();
|
||||
GPU3D::Reset();
|
||||
|
||||
int backbuf = FrontBuffer ? 0 : 1;
|
||||
GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]);
|
||||
GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]);
|
||||
GPU2D_Renderer->SetFramebuffer(Framebuffer[backbuf][1], Framebuffer[backbuf][0]);
|
||||
|
||||
ResetRenderer();
|
||||
|
||||
|
@ -358,8 +357,8 @@ void DoSavestate(Savestate* file)
|
|||
VRAMPtr_BOBJ[i] = GetUniqueBankPtr(VRAMMap_BOBJ[i], i << 14);
|
||||
}
|
||||
|
||||
GPU2D_A->DoSavestate(file);
|
||||
GPU2D_B->DoSavestate(file);
|
||||
GPU2D_A.DoSavestate(file);
|
||||
GPU2D_B.DoSavestate(file);
|
||||
GPU3D::DoSavestate(file);
|
||||
|
||||
ResetVRAMCache();
|
||||
|
@ -370,13 +369,11 @@ void AssignFramebuffers()
|
|||
int backbuf = FrontBuffer ? 0 : 1;
|
||||
if (NDS::PowerControl9 & (1<<15))
|
||||
{
|
||||
GPU2D_A->SetFramebuffer(Framebuffer[backbuf][0]);
|
||||
GPU2D_B->SetFramebuffer(Framebuffer[backbuf][1]);
|
||||
GPU2D_Renderer->SetFramebuffer(Framebuffer[backbuf][0], Framebuffer[backbuf][1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]);
|
||||
GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]);
|
||||
GPU2D_Renderer->SetFramebuffer(Framebuffer[backbuf][1], Framebuffer[backbuf][0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -973,8 +970,8 @@ void SetPowerCnt(u32 val)
|
|||
|
||||
if (!(val & (1<<0))) printf("!!! CLEARING POWCNT BIT0. DANGER\n");
|
||||
|
||||
GPU2D_A->SetEnabled(val & (1<<1));
|
||||
GPU2D_B->SetEnabled(val & (1<<9));
|
||||
GPU2D_A.SetEnabled(val & (1<<1));
|
||||
GPU2D_B.SetEnabled(val & (1<<9));
|
||||
GPU3D::SetEnabled(val & (1<<3), val & (1<<2));
|
||||
|
||||
AssignFramebuffers();
|
||||
|
@ -989,9 +986,9 @@ void DisplayFIFO(u32 x)
|
|||
if (x > 0)
|
||||
{
|
||||
if (x == 8)
|
||||
GPU2D_A->SampleFIFO(0, 5);
|
||||
GPU2D_A.SampleFIFO(0, 5);
|
||||
else
|
||||
GPU2D_A->SampleFIFO(x-11, 8);
|
||||
GPU2D_A.SampleFIFO(x-11, 8);
|
||||
}
|
||||
|
||||
if (x < 256)
|
||||
|
@ -1001,7 +998,7 @@ void DisplayFIFO(u32 x)
|
|||
NDS::ScheduleEvent(NDS::Event_DisplayFIFO, true, 6*8, DisplayFIFO, x+8);
|
||||
}
|
||||
else
|
||||
GPU2D_A->SampleFIFO(253, 3); // sample the remaining pixels
|
||||
GPU2D_A.SampleFIFO(253, 3); // sample the remaining pixels
|
||||
}
|
||||
|
||||
void StartFrame()
|
||||
|
@ -1009,7 +1006,7 @@ void StartFrame()
|
|||
// only run the display FIFO if needed:
|
||||
// * if it is used for display or capture
|
||||
// * if we have display FIFO DMA
|
||||
RunFIFO = GPU2D_A->UsesFIFO() || NDS::DMAsInMode(0, 0x04);
|
||||
RunFIFO = GPU2D_A.UsesFIFO() || NDS::DMAsInMode(0, 0x04);
|
||||
|
||||
TotalScanlines = 0;
|
||||
StartScanline(0);
|
||||
|
@ -1026,15 +1023,15 @@ void StartHBlank(u32 line)
|
|||
// note: this should start 48 cycles after the scanline start
|
||||
if (line < 192)
|
||||
{
|
||||
GPU2D_A->DrawScanline(line);
|
||||
GPU2D_B->DrawScanline(line);
|
||||
GPU2D_Renderer->DrawScanline(line, &GPU2D_A);
|
||||
GPU2D_Renderer->DrawScanline(line, &GPU2D_B);
|
||||
}
|
||||
|
||||
// sprites are pre-rendered one scanline in advance
|
||||
if (line < 191)
|
||||
{
|
||||
GPU2D_A->DrawSprites(line+1);
|
||||
GPU2D_B->DrawSprites(line+1);
|
||||
GPU2D_Renderer->DrawSprites(line+1, &GPU2D_A);
|
||||
GPU2D_Renderer->DrawSprites(line+1, &GPU2D_B);
|
||||
}
|
||||
|
||||
NDS::CheckDMAs(0, 0x02);
|
||||
|
@ -1045,8 +1042,8 @@ void StartHBlank(u32 line)
|
|||
}
|
||||
else if (VCount == 262)
|
||||
{
|
||||
GPU2D_A->DrawSprites(0);
|
||||
GPU2D_B->DrawSprites(0);
|
||||
GPU2D_Renderer->DrawSprites(0, &GPU2D_A);
|
||||
GPU2D_Renderer->DrawSprites(0, &GPU2D_B);
|
||||
}
|
||||
|
||||
if (DispStat[0] & (1<<4)) NDS::SetIRQ(0, NDS::IRQ_HBlank);
|
||||
|
@ -1098,8 +1095,8 @@ void StartScanline(u32 line)
|
|||
else
|
||||
DispStat[1] &= ~(1<<2);
|
||||
|
||||
GPU2D_A->CheckWindows(VCount);
|
||||
GPU2D_B->CheckWindows(VCount);
|
||||
GPU2D_A.CheckWindows(VCount);
|
||||
GPU2D_B.CheckWindows(VCount);
|
||||
|
||||
if (VCount >= 2 && VCount < 194)
|
||||
NDS::CheckDMAs(0, 0x03);
|
||||
|
@ -1110,8 +1107,8 @@ void StartScanline(u32 line)
|
|||
{
|
||||
if (line == 0)
|
||||
{
|
||||
GPU2D_A->VBlankEnd();
|
||||
GPU2D_B->VBlankEnd();
|
||||
GPU2D_A.VBlankEnd();
|
||||
GPU2D_B.VBlankEnd();
|
||||
}
|
||||
|
||||
if (RunFIFO)
|
||||
|
@ -1149,8 +1146,9 @@ void StartScanline(u32 line)
|
|||
if (DispStat[0] & (1<<3)) NDS::SetIRQ(0, NDS::IRQ_VBlank);
|
||||
if (DispStat[1] & (1<<3)) NDS::SetIRQ(1, NDS::IRQ_VBlank);
|
||||
|
||||
GPU2D_A->VBlank();
|
||||
GPU2D_B->VBlank();
|
||||
GPU2D_Renderer->VBlankEnd(&GPU2D_A, &GPU2D_B);
|
||||
GPU2D_A.VBlank();
|
||||
GPU2D_B.VBlank();
|
||||
GPU3D::VBlank();
|
||||
|
||||
#ifdef OGLRENDERER_ENABLED
|
||||
|
|
|
@ -75,8 +75,8 @@ extern u8* VRAMPtr_BOBJ[0x8];
|
|||
extern int FrontBuffer;
|
||||
extern u32* Framebuffer[2][2];
|
||||
|
||||
extern std::unique_ptr<GPU2D> GPU2D_A;
|
||||
extern std::unique_ptr<GPU2D> GPU2D_B;
|
||||
extern GPU2D::Unit GPU2D_A;
|
||||
extern GPU2D::Unit GPU2D_B;
|
||||
|
||||
extern int Renderer;
|
||||
|
||||
|
|
|
@ -80,13 +80,15 @@
|
|||
// for example these aren't affected by POWCNT GPU-disable bits.
|
||||
// to model the hardware more accurately, the relevant logic should be moved to GPU.cpp.
|
||||
|
||||
namespace GPU2D
|
||||
{
|
||||
|
||||
GPU2D::GPU2D(u32 num)
|
||||
Unit::Unit(u32 num)
|
||||
{
|
||||
Num = num;
|
||||
}
|
||||
|
||||
void GPU2D::Reset()
|
||||
void Unit::Reset()
|
||||
{
|
||||
Enabled = false;
|
||||
DispCnt = 0;
|
||||
|
@ -134,11 +136,9 @@ void GPU2D::Reset()
|
|||
CaptureLatch = false;
|
||||
|
||||
MasterBrightness = 0;
|
||||
|
||||
MosaicXSizeChanged();
|
||||
}
|
||||
|
||||
void GPU2D::DoSavestate(Savestate* file)
|
||||
void Unit::DoSavestate(Savestate* file)
|
||||
{
|
||||
file->Section((char*)(Num ? "GP2B" : "GP2A"));
|
||||
|
||||
|
@ -187,16 +187,9 @@ void GPU2D::DoSavestate(Savestate* file)
|
|||
|
||||
file->Var32(&Win0Active);
|
||||
file->Var32(&Win1Active);
|
||||
|
||||
MosaicXSizeChanged();
|
||||
}
|
||||
|
||||
void GPU2D::SetFramebuffer(u32* buf)
|
||||
{
|
||||
Framebuffer = buf;
|
||||
}
|
||||
|
||||
u8 GPU2D::Read8(u32 addr)
|
||||
u8 Unit::Read8(u32 addr)
|
||||
{
|
||||
switch (addr & 0x00000FFF)
|
||||
{
|
||||
|
@ -229,7 +222,7 @@ u8 GPU2D::Read8(u32 addr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
u16 GPU2D::Read16(u32 addr)
|
||||
u16 Unit::Read16(u32 addr)
|
||||
{
|
||||
switch (addr & 0x00000FFF)
|
||||
{
|
||||
|
@ -258,7 +251,7 @@ u16 GPU2D::Read16(u32 addr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
u32 GPU2D::Read32(u32 addr)
|
||||
u32 Unit::Read32(u32 addr)
|
||||
{
|
||||
switch (addr & 0x00000FFF)
|
||||
{
|
||||
|
@ -270,7 +263,7 @@ u32 GPU2D::Read32(u32 addr)
|
|||
return Read16(addr) | (Read16(addr+2) << 16);
|
||||
}
|
||||
|
||||
void GPU2D::Write8(u32 addr, u8 val)
|
||||
void Unit::Write8(u32 addr, u8 val)
|
||||
{
|
||||
switch (addr & 0x00000FFF)
|
||||
{
|
||||
|
@ -347,12 +340,10 @@ void GPU2D::Write8(u32 addr, u8 val)
|
|||
case 0x04C:
|
||||
BGMosaicSize[0] = val & 0xF;
|
||||
BGMosaicSize[1] = val >> 4;
|
||||
MosaicXSizeChanged();
|
||||
return;
|
||||
case 0x04D:
|
||||
OBJMosaicSize[0] = val & 0xF;
|
||||
OBJMosaicSize[1] = val >> 4;
|
||||
MosaicXSizeChanged();
|
||||
return;
|
||||
|
||||
case 0x050: BlendCnt = (BlendCnt & 0x3F00) | val; return;
|
||||
|
@ -376,7 +367,7 @@ void GPU2D::Write8(u32 addr, u8 val)
|
|||
printf("unknown GPU write8 %08X %02X\n", addr, val);
|
||||
}
|
||||
|
||||
void GPU2D::Write16(u32 addr, u16 val)
|
||||
void Unit::Write16(u32 addr, u16 val)
|
||||
{
|
||||
switch (addr & 0x00000FFF)
|
||||
{
|
||||
|
@ -501,7 +492,6 @@ void GPU2D::Write16(u32 addr, u16 val)
|
|||
BGMosaicSize[1] = (val >> 4) & 0xF;
|
||||
OBJMosaicSize[0] = (val >> 8) & 0xF;
|
||||
OBJMosaicSize[1] = val >> 12;
|
||||
MosaicXSizeChanged();
|
||||
return;
|
||||
|
||||
case 0x050: BlendCnt = val & 0x3FFF; return;
|
||||
|
@ -521,7 +511,7 @@ void GPU2D::Write16(u32 addr, u16 val)
|
|||
//printf("unknown GPU write16 %08X %04X\n", addr, val);
|
||||
}
|
||||
|
||||
void GPU2D::Write32(u32 addr, u32 val)
|
||||
void Unit::Write32(u32 addr, u32 val)
|
||||
{
|
||||
switch (addr & 0x00000FFF)
|
||||
{
|
||||
|
@ -575,7 +565,7 @@ void GPU2D::Write32(u32 addr, u32 val)
|
|||
Write16(addr+2, val>>16);
|
||||
}
|
||||
|
||||
void GPU2D::UpdateMosaicCounters(u32 line)
|
||||
void Unit::UpdateMosaicCounters(u32 line)
|
||||
{
|
||||
// Y mosaic uses incrementing 4-bit counters
|
||||
// the transformed Y position is updated every time the counter matches the MOSAIC register
|
||||
|
@ -592,7 +582,7 @@ void GPU2D::UpdateMosaicCounters(u32 line)
|
|||
}
|
||||
}
|
||||
|
||||
void GPU2D::VBlank()
|
||||
void Unit::VBlank()
|
||||
{
|
||||
if (CaptureLatch)
|
||||
{
|
||||
|
@ -604,7 +594,7 @@ void GPU2D::VBlank()
|
|||
DispFIFOWritePtr = 0;
|
||||
}
|
||||
|
||||
void GPU2D::VBlankEnd()
|
||||
void Unit::VBlankEnd()
|
||||
{
|
||||
// TODO: find out the exact time this happens
|
||||
BGXRefInternal[0] = BGXRef[0];
|
||||
|
@ -620,7 +610,7 @@ void GPU2D::VBlankEnd()
|
|||
//OBJMosaicYCount = 0;
|
||||
}
|
||||
|
||||
void GPU2D::SampleFIFO(u32 offset, u32 num)
|
||||
void Unit::SampleFIFO(u32 offset, u32 num)
|
||||
{
|
||||
for (u32 i = 0; i < num; i++)
|
||||
{
|
||||
|
@ -632,7 +622,7 @@ void GPU2D::SampleFIFO(u32 offset, u32 num)
|
|||
}
|
||||
}
|
||||
|
||||
u16* GPU2D::GetBGExtPal(u32 slot, u32 pal)
|
||||
u16* Unit::GetBGExtPal(u32 slot, u32 pal)
|
||||
{
|
||||
const u32 PaletteSize = 256 * 2;
|
||||
const u32 SlotSize = PaletteSize * 16;
|
||||
|
@ -641,14 +631,14 @@ u16* GPU2D::GetBGExtPal(u32 slot, u32 pal)
|
|||
: GPU::VRAMFlat_BBGExtPal)[slot * SlotSize + pal * PaletteSize];
|
||||
}
|
||||
|
||||
u16* GPU2D::GetOBJExtPal()
|
||||
u16* Unit::GetOBJExtPal()
|
||||
{
|
||||
return Num == 0
|
||||
? (u16*)GPU::VRAMFlat_AOBJExtPal
|
||||
: (u16*)GPU::VRAMFlat_BOBJExtPal;
|
||||
}
|
||||
|
||||
void GPU2D::CheckWindows(u32 line)
|
||||
void Unit::CheckWindows(u32 line)
|
||||
{
|
||||
line &= 0xFF;
|
||||
if (line == Win0Coords[3]) Win0Active &= ~0x1;
|
||||
|
@ -657,18 +647,18 @@ void GPU2D::CheckWindows(u32 line)
|
|||
else if (line == Win1Coords[2]) Win1Active |= 0x1;
|
||||
}
|
||||
|
||||
void GPU2D::CalculateWindowMask(u32 line)
|
||||
void Unit::CalculateWindowMask(u32 line, u8* windowMask, u8* objWindow)
|
||||
{
|
||||
for (u32 i = 0; i < 256; i++)
|
||||
WindowMask[i] = WinCnt[2]; // window outside
|
||||
windowMask[i] = WinCnt[2]; // window outside
|
||||
|
||||
if (DispCnt & (1<<15))
|
||||
{
|
||||
// OBJ window
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
if (OBJWindow[i])
|
||||
WindowMask[i] = WinCnt[3];
|
||||
if (objWindow[i])
|
||||
windowMask[i] = WinCnt[3];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -683,7 +673,7 @@ void GPU2D::CalculateWindowMask(u32 line)
|
|||
if (i == x2) Win1Active &= ~0x2;
|
||||
else if (i == x1) Win1Active |= 0x2;
|
||||
|
||||
if (Win1Active == 0x3) WindowMask[i] = WinCnt[1];
|
||||
if (Win1Active == 0x3) windowMask[i] = WinCnt[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -698,12 +688,12 @@ void GPU2D::CalculateWindowMask(u32 line)
|
|||
if (i == x2) Win0Active &= ~0x2;
|
||||
else if (i == x1) Win0Active |= 0x2;
|
||||
|
||||
if (Win0Active == 0x3) WindowMask[i] = WinCnt[0];
|
||||
if (Win0Active == 0x3) windowMask[i] = WinCnt[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GPU2D::GetBGVRAM(u8*& data, u32& mask)
|
||||
void Unit::GetBGVRAM(u8*& data, u32& mask)
|
||||
{
|
||||
if (Num == 0)
|
||||
{
|
||||
|
@ -717,7 +707,7 @@ void GPU2D::GetBGVRAM(u8*& data, u32& mask)
|
|||
}
|
||||
}
|
||||
|
||||
void GPU2D::GetOBJVRAM(u8*& data, u32& mask)
|
||||
void Unit::GetOBJVRAM(u8*& data, u32& mask)
|
||||
{
|
||||
if (Num == 0)
|
||||
{
|
||||
|
@ -730,3 +720,5 @@ void GPU2D::GetOBJVRAM(u8*& data, u32& mask)
|
|||
mask = 0x1FFFF;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
51
src/GPU2D.h
51
src/GPU2D.h
|
@ -22,21 +22,22 @@
|
|||
#include "types.h"
|
||||
#include "Savestate.h"
|
||||
|
||||
class GPU2D
|
||||
namespace GPU2D
|
||||
{
|
||||
|
||||
class Unit
|
||||
{
|
||||
public:
|
||||
GPU2D(u32 num);
|
||||
virtual ~GPU2D() {}
|
||||
Unit(u32 num);
|
||||
|
||||
GPU2D(const GPU2D&) = delete;
|
||||
GPU2D& operator=(const GPU2D&) = delete;
|
||||
Unit(const Unit&) = delete;
|
||||
Unit& operator=(const Unit&) = delete;
|
||||
|
||||
void Reset();
|
||||
|
||||
void DoSavestate(Savestate* file);
|
||||
|
||||
void SetEnabled(bool enable) { Enabled = enable; }
|
||||
void SetFramebuffer(u32* buf);
|
||||
|
||||
u8 Read8(u32 addr);
|
||||
u16 Read16(u32 addr);
|
||||
|
@ -57,8 +58,6 @@ public:
|
|||
|
||||
void SampleFIFO(u32 offset, u32 num);
|
||||
|
||||
virtual void DrawScanline(u32 line) = 0;
|
||||
virtual void DrawSprites(u32 line) = 0;
|
||||
void VBlank();
|
||||
virtual void VBlankEnd();
|
||||
|
||||
|
@ -70,10 +69,11 @@ public:
|
|||
void GetBGVRAM(u8*& data, u32& mask);
|
||||
void GetOBJVRAM(u8*& data, u32& mask);
|
||||
|
||||
protected:
|
||||
void UpdateMosaicCounters(u32 line);
|
||||
void CalculateWindowMask(u32 line, u8* windowMask, u8* objWindow);
|
||||
|
||||
u32 Num;
|
||||
bool Enabled;
|
||||
u32* Framebuffer;
|
||||
|
||||
u16 DispFIFO[16];
|
||||
u32 DispFIFOReadPtr;
|
||||
|
@ -116,14 +116,29 @@ protected:
|
|||
u32 CaptureCnt;
|
||||
|
||||
u16 MasterBrightness;
|
||||
|
||||
alignas(8) u8 WindowMask[256];
|
||||
alignas(8) u8 OBJWindow[256];
|
||||
|
||||
void UpdateMosaicCounters(u32 line);
|
||||
void CalculateWindowMask(u32 line);
|
||||
|
||||
virtual void MosaicXSizeChanged() = 0;
|
||||
};
|
||||
|
||||
class Renderer2D
|
||||
{
|
||||
public:
|
||||
virtual ~Renderer2D() {}
|
||||
|
||||
virtual void DrawScanline(u32 line, Unit* unit) = 0;
|
||||
virtual void DrawSprites(u32 line, Unit* unit) = 0;
|
||||
|
||||
virtual void VBlankEnd(Unit* unitA, Unit* unitB) = 0;
|
||||
|
||||
void SetFramebuffer(u32* unitA, u32* unitB)
|
||||
{
|
||||
Framebuffer[0] = unitA;
|
||||
Framebuffer[1] = unitB;
|
||||
}
|
||||
protected:
|
||||
u32* Framebuffer[2];
|
||||
|
||||
Unit* CurUnit;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -20,32 +20,32 @@
|
|||
|
||||
#include "GPU2D.h"
|
||||
|
||||
class GPU2D_Soft : public GPU2D
|
||||
namespace GPU2D
|
||||
{
|
||||
|
||||
class SoftRenderer : public Renderer2D
|
||||
{
|
||||
public:
|
||||
GPU2D_Soft(u32 num);
|
||||
~GPU2D_Soft() override {}
|
||||
|
||||
void DrawScanline(u32 line) override;
|
||||
void DrawSprites(u32 line) override;
|
||||
void VBlankEnd() override;
|
||||
|
||||
protected:
|
||||
void MosaicXSizeChanged() override;
|
||||
SoftRenderer();
|
||||
~SoftRenderer() override {}
|
||||
|
||||
void DrawScanline(u32 line, Unit* unit) override;
|
||||
void DrawSprites(u32 line, Unit* unit) override;
|
||||
void VBlankEnd(Unit* unitA, Unit* unitB) override;
|
||||
private:
|
||||
|
||||
alignas(8) u32 BGOBJLine[256*3];
|
||||
u32* _3DLine;
|
||||
|
||||
alignas(8) u32 OBJLine[256];
|
||||
alignas(8) u8 OBJIndex[256];
|
||||
alignas(8) u8 WindowMask[256];
|
||||
|
||||
u32 NumSprites;
|
||||
alignas(8) u32 OBJLine[2][256];
|
||||
alignas(8) u8 OBJIndex[2][256];
|
||||
alignas(8) u8 OBJWindow[2][256];
|
||||
|
||||
u32 NumSprites[2];
|
||||
|
||||
u8 MosaicTable[16][256];
|
||||
u8* CurBGXMosaicTable;
|
||||
u8* CurOBJXMosaicTable;
|
||||
u8 MosaicTable[16][256];
|
||||
|
||||
u32 ColorBlend4(u32 val1, u32 val2, u32 eva, u32 evb);
|
||||
u32 ColorBlend5(u32 val1, u32 val2);
|
||||
|
@ -76,4 +76,6 @@ private:
|
|||
template<bool window> void DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 ypos);
|
||||
|
||||
void DoCapture(u32 line, u32 width);
|
||||
};
|
||||
};
|
||||
|
||||
}
|
44
src/NDS.cpp
44
src/NDS.cpp
|
@ -2882,11 +2882,11 @@ u8 ARM9IORead8(u32 addr)
|
|||
|
||||
if (addr >= 0x04000000 && addr < 0x04000060)
|
||||
{
|
||||
return GPU::GPU2D_A->Read8(addr);
|
||||
return GPU::GPU2D_A.Read8(addr);
|
||||
}
|
||||
if (addr >= 0x04001000 && addr < 0x04001060)
|
||||
{
|
||||
return GPU::GPU2D_B->Read8(addr);
|
||||
return GPU::GPU2D_B.Read8(addr);
|
||||
}
|
||||
if (addr >= 0x04000320 && addr < 0x040006A4)
|
||||
{
|
||||
|
@ -2906,7 +2906,7 @@ u16 ARM9IORead16(u32 addr)
|
|||
|
||||
case 0x04000060: return GPU3D::Read16(addr);
|
||||
case 0x04000064:
|
||||
case 0x04000066: return GPU::GPU2D_A->Read16(addr);
|
||||
case 0x04000066: return GPU::GPU2D_A.Read16(addr);
|
||||
|
||||
case 0x040000B8: return DMAs[0]->Cnt & 0xFFFF;
|
||||
case 0x040000BA: return DMAs[0]->Cnt >> 16;
|
||||
|
@ -3004,11 +3004,11 @@ u16 ARM9IORead16(u32 addr)
|
|||
|
||||
if ((addr >= 0x04000000 && addr < 0x04000060) || (addr == 0x0400006C))
|
||||
{
|
||||
return GPU::GPU2D_A->Read16(addr);
|
||||
return GPU::GPU2D_A.Read16(addr);
|
||||
}
|
||||
if ((addr >= 0x04001000 && addr < 0x04001060) || (addr == 0x0400106C))
|
||||
{
|
||||
return GPU::GPU2D_B->Read16(addr);
|
||||
return GPU::GPU2D_B.Read16(addr);
|
||||
}
|
||||
if (addr >= 0x04000320 && addr < 0x040006A4)
|
||||
{
|
||||
|
@ -3026,7 +3026,7 @@ u32 ARM9IORead32(u32 addr)
|
|||
case 0x04000004: return GPU::DispStat[0] | (GPU::VCount << 16);
|
||||
|
||||
case 0x04000060: return GPU3D::Read32(addr);
|
||||
case 0x04000064: return GPU::GPU2D_A->Read32(addr);
|
||||
case 0x04000064: return GPU::GPU2D_A.Read32(addr);
|
||||
|
||||
case 0x040000B0: return DMAs[0]->SrcAddr;
|
||||
case 0x040000B4: return DMAs[0]->DstAddr;
|
||||
|
@ -3124,11 +3124,11 @@ u32 ARM9IORead32(u32 addr)
|
|||
|
||||
if ((addr >= 0x04000000 && addr < 0x04000060) || (addr == 0x0400006C))
|
||||
{
|
||||
return GPU::GPU2D_A->Read32(addr);
|
||||
return GPU::GPU2D_A.Read32(addr);
|
||||
}
|
||||
if ((addr >= 0x04001000 && addr < 0x04001060) || (addr == 0x0400106C))
|
||||
{
|
||||
return GPU::GPU2D_B->Read32(addr);
|
||||
return GPU::GPU2D_B.Read32(addr);
|
||||
}
|
||||
if (addr >= 0x04000320 && addr < 0x040006A4)
|
||||
{
|
||||
|
@ -3144,9 +3144,9 @@ void ARM9IOWrite8(u32 addr, u8 val)
|
|||
switch (addr)
|
||||
{
|
||||
case 0x0400006C:
|
||||
case 0x0400006D: GPU::GPU2D_A->Write8(addr, val); return;
|
||||
case 0x0400006D: GPU::GPU2D_A.Write8(addr, val); return;
|
||||
case 0x0400106C:
|
||||
case 0x0400106D: GPU::GPU2D_B->Write8(addr, val); return;
|
||||
case 0x0400106D: GPU::GPU2D_B.Write8(addr, val); return;
|
||||
|
||||
case 0x04000132:
|
||||
KeyCnt = (KeyCnt & 0xFF00) | val;
|
||||
|
@ -3205,12 +3205,12 @@ void ARM9IOWrite8(u32 addr, u8 val)
|
|||
|
||||
if (addr >= 0x04000000 && addr < 0x04000060)
|
||||
{
|
||||
GPU::GPU2D_A->Write8(addr, val);
|
||||
GPU::GPU2D_A.Write8(addr, val);
|
||||
return;
|
||||
}
|
||||
if (addr >= 0x04001000 && addr < 0x04001060)
|
||||
{
|
||||
GPU::GPU2D_B->Write8(addr, val);
|
||||
GPU::GPU2D_B.Write8(addr, val);
|
||||
return;
|
||||
}
|
||||
if (addr >= 0x04000320 && addr < 0x040006A4)
|
||||
|
@ -3232,10 +3232,10 @@ void ARM9IOWrite16(u32 addr, u16 val)
|
|||
case 0x04000060: GPU3D::Write16(addr, val); return;
|
||||
|
||||
case 0x04000068:
|
||||
case 0x0400006A: GPU::GPU2D_A->Write16(addr, val); return;
|
||||
case 0x0400006A: GPU::GPU2D_A.Write16(addr, val); return;
|
||||
|
||||
case 0x0400006C: GPU::GPU2D_A->Write16(addr, val); return;
|
||||
case 0x0400106C: GPU::GPU2D_B->Write16(addr, val); return;
|
||||
case 0x0400006C: GPU::GPU2D_A.Write16(addr, val); return;
|
||||
case 0x0400106C: GPU::GPU2D_B.Write16(addr, val); return;
|
||||
|
||||
case 0x040000B8: DMAs[0]->WriteCnt((DMAs[0]->Cnt & 0xFFFF0000) | val); return;
|
||||
case 0x040000BA: DMAs[0]->WriteCnt((DMAs[0]->Cnt & 0x0000FFFF) | (val << 16)); return;
|
||||
|
@ -3371,12 +3371,12 @@ void ARM9IOWrite16(u32 addr, u16 val)
|
|||
|
||||
if (addr >= 0x04000000 && addr < 0x04000060)
|
||||
{
|
||||
GPU::GPU2D_A->Write16(addr, val);
|
||||
GPU::GPU2D_A.Write16(addr, val);
|
||||
return;
|
||||
}
|
||||
if (addr >= 0x04001000 && addr < 0x04001060)
|
||||
{
|
||||
GPU::GPU2D_B->Write16(addr, val);
|
||||
GPU::GPU2D_B.Write16(addr, val);
|
||||
return;
|
||||
}
|
||||
if (addr >= 0x04000320 && addr < 0x040006A4)
|
||||
|
@ -3399,10 +3399,10 @@ void ARM9IOWrite32(u32 addr, u32 val)
|
|||
|
||||
case 0x04000060: GPU3D::Write32(addr, val); return;
|
||||
case 0x04000064:
|
||||
case 0x04000068: GPU::GPU2D_A->Write32(addr, val); return;
|
||||
case 0x04000068: GPU::GPU2D_A.Write32(addr, val); return;
|
||||
|
||||
case 0x0400006C: GPU::GPU2D_A->Write16(addr, val&0xFFFF); return;
|
||||
case 0x0400106C: GPU::GPU2D_B->Write16(addr, val&0xFFFF); return;
|
||||
case 0x0400006C: GPU::GPU2D_A.Write16(addr, val&0xFFFF); return;
|
||||
case 0x0400106C: GPU::GPU2D_B.Write16(addr, val&0xFFFF); return;
|
||||
|
||||
case 0x040000B0: DMAs[0]->SrcAddr = val; return;
|
||||
case 0x040000B4: DMAs[0]->DstAddr = val; return;
|
||||
|
@ -3534,12 +3534,12 @@ void ARM9IOWrite32(u32 addr, u32 val)
|
|||
|
||||
if (addr >= 0x04000000 && addr < 0x04000060)
|
||||
{
|
||||
GPU::GPU2D_A->Write32(addr, val);
|
||||
GPU::GPU2D_A.Write32(addr, val);
|
||||
return;
|
||||
}
|
||||
if (addr >= 0x04001000 && addr < 0x04001060)
|
||||
{
|
||||
GPU::GPU2D_B->Write32(addr, val);
|
||||
GPU::GPU2D_B.Write32(addr, val);
|
||||
return;
|
||||
}
|
||||
if (addr >= 0x04000320 && addr < 0x040006A4)
|
||||
|
|
Loading…
Reference in New Issue