diff options
author | RSDuck <RSDuck@users.noreply.github.com> | 2021-02-27 22:25:27 +0100 |
---|---|---|
committer | RSDuck <RSDuck@users.noreply.github.com> | 2021-02-27 22:25:42 +0100 |
commit | a046eb50384e5f55f7d6ca7e69417e8b013a8c5a (patch) | |
tree | 143d83a1f580adb1312f2623955a591dd66e84e3 /src | |
parent | f8692f85a437b4fc82b35fe80622f09e3346c78a (diff) |
separate GPU2D registers and renderer
Diffstat (limited to 'src')
-rw-r--r-- | src/GPU.cpp | 66 | ||||
-rw-r--r-- | src/GPU.h | 4 | ||||
-rw-r--r-- | src/GPU2D.cpp | 64 | ||||
-rw-r--r-- | src/GPU2D.h | 45 | ||||
-rw-r--r-- | src/GPU2D_Soft.cpp | 543 | ||||
-rw-r--r-- | src/GPU2D_Soft.h | 36 | ||||
-rw-r--r-- | src/NDS.cpp | 44 |
7 files changed, 418 insertions, 384 deletions
diff --git a/src/GPU.cpp b/src/GPU.cpp index d8e3d72..57df8ae 100644 --- a/src/GPU.cpp +++ b/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; diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index cbe09d6..aece209 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -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; } } + +}
\ No newline at end of file diff --git a/src/GPU2D.h b/src/GPU2D.h index e9ce8e1..e5c50bc 100644 --- a/src/GPU2D.h +++ b/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]; +class Renderer2D +{ +public: + virtual ~Renderer2D() {} - void UpdateMosaicCounters(u32 line); - void CalculateWindowMask(u32 line); + virtual void DrawScanline(u32 line, Unit* unit) = 0; + virtual void DrawSprites(u32 line, Unit* unit) = 0; + + virtual void VBlankEnd(Unit* unitA, Unit* unitB) = 0; - virtual void MosaicXSizeChanged() = 0; + void SetFramebuffer(u32* unitA, u32* unitB) + { + Framebuffer[0] = unitA; + Framebuffer[1] = unitB; + } +protected: + u32* Framebuffer[2]; + + Unit* CurUnit; }; +} + #endif diff --git a/src/GPU2D_Soft.cpp b/src/GPU2D_Soft.cpp index e455b7c..a244083 100644 --- a/src/GPU2D_Soft.cpp +++ b/src/GPU2D_Soft.cpp @@ -1,8 +1,11 @@ #include "GPU2D_Soft.h" #include "GPU.h" -GPU2D_Soft::GPU2D_Soft(u32 num) - : GPU2D(num) +namespace GPU2D +{ + +SoftRenderer::SoftRenderer() + : Renderer2D() { // initialize mosaic table for (int m = 0; m < 16; m++) @@ -15,7 +18,7 @@ GPU2D_Soft::GPU2D_Soft(u32 num) } } -u32 GPU2D_Soft::ColorBlend4(u32 val1, u32 val2, u32 eva, u32 evb) +u32 SoftRenderer::ColorBlend4(u32 val1, u32 val2, u32 eva, u32 evb) { u32 r = (((val1 & 0x00003F) * eva) + ((val2 & 0x00003F) * evb)) >> 4; u32 g = ((((val1 & 0x003F00) * eva) + ((val2 & 0x003F00) * evb)) >> 4) & 0x007F00; @@ -28,7 +31,7 @@ u32 GPU2D_Soft::ColorBlend4(u32 val1, u32 val2, u32 eva, u32 evb) return r | g | b | 0xFF000000; } -u32 GPU2D_Soft::ColorBlend5(u32 val1, u32 val2) +u32 SoftRenderer::ColorBlend5(u32 val1, u32 val2) { u32 eva = ((val1 >> 24) & 0x1F) + 1; u32 evb = 32 - eva; @@ -53,7 +56,7 @@ u32 GPU2D_Soft::ColorBlend5(u32 val1, u32 val2) return r | g | b | 0xFF000000; } -u32 GPU2D_Soft::ColorBrightnessUp(u32 val, u32 factor) +u32 SoftRenderer::ColorBrightnessUp(u32 val, u32 factor) { u32 rb = val & 0x3F003F; u32 g = val & 0x003F00; @@ -64,7 +67,7 @@ u32 GPU2D_Soft::ColorBrightnessUp(u32 val, u32 factor) return rb | g | 0xFF000000; } -u32 GPU2D_Soft::ColorBrightnessDown(u32 val, u32 factor) +u32 SoftRenderer::ColorBrightnessDown(u32 val, u32 factor) { u32 rb = val & 0x3F003F; u32 g = val & 0x003F00; @@ -75,7 +78,7 @@ u32 GPU2D_Soft::ColorBrightnessDown(u32 val, u32 factor) return rb | g | 0xFF000000; } -u32 GPU2D_Soft::ColorComposite(int i, u32 val1, u32 val2) +u32 SoftRenderer::ColorComposite(int i, u32 val1, u32 val2) { u32 coloreffect = 0; u32 eva, evb; @@ -83,12 +86,14 @@ u32 GPU2D_Soft::ColorComposite(int i, u32 val1, u32 val2) u32 flag1 = val1 >> 24; u32 flag2 = val2 >> 24; + u32 blendCnt = CurUnit->BlendCnt; + u32 target2; if (flag2 & 0x80) target2 = 0x1000; else if (flag2 & 0x40) target2 = 0x0100; else target2 = flag2 << 8; - if ((flag1 & 0x80) && (BlendCnt & target2)) + if ((flag1 & 0x80) && (blendCnt & target2)) { // sprite blending @@ -101,11 +106,11 @@ u32 GPU2D_Soft::ColorComposite(int i, u32 val1, u32 val2) } else { - eva = EVA; - evb = EVB; + eva = CurUnit->EVA; + evb = CurUnit->EVB; } } - else if ((flag1 & 0x40) && (BlendCnt & target2)) + else if ((flag1 & 0x40) && (blendCnt & target2)) { // 3D layer blending @@ -116,16 +121,16 @@ u32 GPU2D_Soft::ColorComposite(int i, u32 val1, u32 val2) if (flag1 & 0x80) flag1 = 0x10; else if (flag1 & 0x40) flag1 = 0x01; - if ((BlendCnt & flag1) && (WindowMask[i] & 0x20)) + if ((blendCnt & flag1) && (WindowMask[i] & 0x20)) { - coloreffect = (BlendCnt >> 6) & 0x3; + coloreffect = (blendCnt >> 6) & 0x3; if (coloreffect == 1) { - if (BlendCnt & target2) + if (blendCnt & target2) { - eva = EVA; - evb = EVB; + eva = CurUnit->EVA; + evb = CurUnit->EVB; } else coloreffect = 0; @@ -137,23 +142,25 @@ u32 GPU2D_Soft::ColorComposite(int i, u32 val1, u32 val2) { case 0: return val1; case 1: return ColorBlend4(val1, val2, eva, evb); - case 2: return ColorBrightnessUp(val1, EVY); - case 3: return ColorBrightnessDown(val1, EVY); + case 2: return ColorBrightnessUp(val1, CurUnit->EVY); + case 3: return ColorBrightnessDown(val1, CurUnit->EVY); case 4: return ColorBlend5(val1, val2); } return val1; } -void GPU2D_Soft::DrawScanline(u32 line) +void SoftRenderer::DrawScanline(u32 line, Unit* unit) { + CurUnit = unit; + int stride = GPU3D::CurrentRenderer->Accelerated ? (256*3 + 1) : 256; - u32* dst = &Framebuffer[stride * line]; + u32* dst = &Framebuffer[CurUnit->Num][stride * line]; int n3dline = line; line = GPU::VCount; - if (Num == 0) + if (CurUnit->Num == 0) { auto bgDirty = GPU::VRAMDirty_ABG.DeriveState(GPU::VRAMMap_ABG); GPU::MakeVRAMFlat_ABGCoherent(bgDirty); @@ -180,16 +187,16 @@ void GPU2D_Soft::DrawScanline(u32 line) // GPU B can be completely disabled by POWCNT1 // oddly that's not the case for GPU A - if (Num && !Enabled) forceblank = true; + if (CurUnit->Num && !CurUnit->Enabled) forceblank = true; - if (line == 0 && CaptureCnt & (1 << 31) && !forceblank) - CaptureLatch = true; + if (line == 0 && CurUnit->CaptureCnt & (1 << 31) && !forceblank) + CurUnit->CaptureLatch = true; - if (Num == 0) + if (CurUnit->Num == 0) { if (!GPU3D::CurrentRenderer->Accelerated) _3DLine = GPU3D::GetLine(n3dline); - else if (CaptureLatch && (((CaptureCnt >> 29) & 0x3) != 1)) + else if (CurUnit->CaptureLatch && (((CurUnit->CaptureCnt >> 29) & 0x3) != 1)) { _3DLine = GPU3D::GetLine(n3dline); //GPU3D::GLRenderer::PrepareCaptureFrame(); @@ -208,12 +215,12 @@ void GPU2D_Soft::DrawScanline(u32 line) return; } - u32 dispmode = DispCnt >> 16; - dispmode &= (Num ? 0x1 : 0x3); + u32 dispmode = CurUnit->DispCnt >> 16; + dispmode &= (CurUnit->Num ? 0x1 : 0x3); // always render regular graphics DrawScanline_BGOBJ(line); - UpdateMosaicCounters(line); + CurUnit->UpdateMosaicCounters(line); switch (dispmode) { @@ -234,7 +241,7 @@ void GPU2D_Soft::DrawScanline(u32 line) case 2: // VRAM display { - u32 vrambank = (DispCnt >> 18) & 0x3; + u32 vrambank = (CurUnit->DispCnt >> 18) & 0x3; if (GPU::VRAMMap_LCDC & (1<<vrambank)) { u16* vram = (u16*)GPU::VRAM[vrambank]; @@ -264,7 +271,7 @@ void GPU2D_Soft::DrawScanline(u32 line) { for (int i = 0; i < 256; i++) { - u16 color = DispFIFOBuffer[i]; + u16 color = CurUnit->DispFIFOBuffer[i]; u8 r = (color & 0x001F) << 1; u8 g = (color & 0x03E0) >> 4; u8 b = (color & 0x7C00) >> 9; @@ -276,10 +283,10 @@ void GPU2D_Soft::DrawScanline(u32 line) } // capture - if ((Num == 0) && CaptureLatch) + if ((CurUnit->Num == 0) && CurUnit->CaptureLatch) { u32 capwidth, capheight; - switch ((CaptureCnt >> 20) & 0x3) + switch ((CurUnit->CaptureCnt >> 20) & 0x3) { case 0: capwidth = 128; capheight = 128; break; case 1: capwidth = 256; capheight = 64; break; @@ -291,19 +298,21 @@ void GPU2D_Soft::DrawScanline(u32 line) DoCapture(line, capwidth); } + u32 masterBrightness = CurUnit->MasterBrightness; + if (GPU3D::CurrentRenderer->Accelerated) { - dst[256*3] = MasterBrightness | (DispCnt & 0x30000); + dst[256*3] = masterBrightness | (CurUnit->DispCnt & 0x30000); return; } // master brightness if (dispmode != 0) { - if ((MasterBrightness >> 14) == 1) + if ((masterBrightness >> 14) == 1) { // up - u32 factor = MasterBrightness & 0x1F; + u32 factor = masterBrightness & 0x1F; if (factor > 16) factor = 16; for (int i = 0; i < 256; i++) @@ -311,10 +320,10 @@ void GPU2D_Soft::DrawScanline(u32 line) dst[i] = ColorBrightnessUp(dst[i], factor); } } - else if ((MasterBrightness >> 14) == 2) + else if ((masterBrightness >> 14) == 2) { // down - u32 factor = MasterBrightness & 0x1F; + u32 factor = masterBrightness & 0x1F; if (factor > 16) factor = 16; for (int i = 0; i < 256; i++) @@ -340,14 +349,12 @@ void GPU2D_Soft::DrawScanline(u32 line) } } -void GPU2D_Soft::VBlankEnd() +void SoftRenderer::VBlankEnd(Unit* unitA, Unit* unitB) { - GPU2D::VBlankEnd(); - #ifdef OGLRENDERER_ENABLED if (GPU3D::CurrentRenderer->Accelerated) { - if ((Num == 0) && (CaptureCnt & (1<<31)) && (((CaptureCnt >> 29) & 0x3) != 1)) + if ((unitA->CaptureLatch) && (((unitA->CaptureCnt >> 29) & 0x3) != 1)) { reinterpret_cast<GPU3D::GLRenderer*>(GPU3D::CurrentRenderer.get())->PrepareCaptureFrame(); } @@ -355,9 +362,10 @@ void GPU2D_Soft::VBlankEnd() #endif } -void GPU2D_Soft::DoCapture(u32 line, u32 width) +void SoftRenderer::DoCapture(u32 line, u32 width) { - u32 dstvram = (CaptureCnt >> 16) & 0x3; + u32 captureCnt = CurUnit->CaptureCnt; + u32 dstvram = (captureCnt >> 16) & 0x3; // TODO: confirm this // it should work like VRAM display mode, which requires VRAM to be mapped to LCDC @@ -365,12 +373,12 @@ void GPU2D_Soft::DoCapture(u32 line, u32 width) return; u16* dst = (u16*)GPU::VRAM[dstvram]; - u32 dstaddr = (((CaptureCnt >> 18) & 0x3) << 14) + (line * width); + u32 dstaddr = (((captureCnt >> 18) & 0x3) << 14) + (line * width); // TODO: handle 3D in GPU3D::CurrentRenderer->Accelerated mode!! u32* srcA; - if (CaptureCnt & (1<<24)) + if (captureCnt & (1<<24)) { srcA = _3DLine; } @@ -441,19 +449,19 @@ void GPU2D_Soft::DoCapture(u32 line, u32 width) u16* srcB = NULL; u32 srcBaddr = line * 256; - if (CaptureCnt & (1<<25)) + if (captureCnt & (1<<25)) { - srcB = &DispFIFOBuffer[0]; + srcB = &CurUnit->DispFIFOBuffer[0]; srcBaddr = 0; } else { - u32 srcvram = (DispCnt >> 18) & 0x3; + u32 srcvram = (CurUnit->DispCnt >> 18) & 0x3; if (GPU::VRAMMap_LCDC & (1<<srcvram)) srcB = (u16*)GPU::VRAM[srcvram]; - if (((DispCnt >> 16) & 0x3) != 2) - srcBaddr += ((CaptureCnt >> 26) & 0x3) << 14; + if (((CurUnit->DispCnt >> 16) & 0x3) != 2) + srcBaddr += ((captureCnt >> 26) & 0x3) << 14; } dstaddr &= 0xFFFF; @@ -462,7 +470,7 @@ void GPU2D_Soft::DoCapture(u32 line, u32 width) static_assert(GPU::VRAMDirtyGranularity == 512, ""); GPU::VRAMDirty[dstvram][(dstaddr * 2) / GPU::VRAMDirtyGranularity] = true; - switch ((CaptureCnt >> 29) & 0x3) + switch ((captureCnt >> 29) & 0x3) { case 0: // source A { @@ -508,8 +516,8 @@ void GPU2D_Soft::DoCapture(u32 line, u32 width) case 2: // sources A+B case 3: { - u32 eva = CaptureCnt & 0x1F; - u32 evb = (CaptureCnt >> 8) & 0x1F; + u32 eva = captureCnt & 0x1F; + u32 evb = (captureCnt >> 8) & 0x1F; // checkme if (eva > 16) eva = 16; @@ -579,7 +587,7 @@ void GPU2D_Soft::DoCapture(u32 line, u32 width) #define DoDrawBG(type, line, num) \ do \ { \ - if ((BGCnt[num] & 0x0040) && (BGMosaicSize[0] > 0)) \ + if ((bgCnt[num] & 0x0040) && (CurUnit->BGMosaicSize[0] > 0)) \ { \ if (GPU3D::CurrentRenderer->Accelerated) DrawBG_##type<true, DrawPixel_Accel>(line, num); \ else DrawBG_##type<true, DrawPixel_Normal>(line, num); \ @@ -594,7 +602,7 @@ void GPU2D_Soft::DoCapture(u32 line, u32 width) #define DoDrawBG_Large(line) \ do \ { \ - if ((BGCnt[2] & 0x0040) && (BGMosaicSize[0] > 0)) \ + if ((bgCnt[2] & 0x0040) && (CurUnit->BGMosaicSize[0] > 0)) \ { \ if (GPU3D::CurrentRenderer->Accelerated) DrawBG_Large<true, DrawPixel_Accel>(line); \ else DrawBG_Large<true, DrawPixel_Normal>(line); \ @@ -610,13 +618,15 @@ void GPU2D_Soft::DoCapture(u32 line, u32 width) if (GPU3D::CurrentRenderer->Accelerated) InterleaveSprites<DrawPixel_Accel>(prio); else InterleaveSprites<DrawPixel_Normal>(prio); template<u32 bgmode> -void GPU2D_Soft::DrawScanlineBGMode(u32 line) +void SoftRenderer::DrawScanlineBGMode(u32 line) { + u32 dispCnt = CurUnit->DispCnt; + u16* bgCnt = CurUnit->BGCnt; for (int i = 3; i >= 0; i--) { - if ((BGCnt[3] & 0x3) == i) + if ((bgCnt[3] & 0x3) == i) { - if (DispCnt & 0x0800) + if (dispCnt & 0x0800) { if (bgmode >= 3) DoDrawBG(Extended, line, 3); @@ -626,9 +636,9 @@ void GPU2D_Soft::DrawScanlineBGMode(u32 line) DoDrawBG(Text, line, 3); } } - if ((BGCnt[2] & 0x3) == i) + if ((bgCnt[2] & 0x3) == i) { - if (DispCnt & 0x0400) + if (dispCnt & 0x0400) { if (bgmode == 5) DoDrawBG(Extended, line, 2); @@ -638,24 +648,24 @@ void GPU2D_Soft::DrawScanlineBGMode(u32 line) DoDrawBG(Text, line, 2); } } - if ((BGCnt[1] & 0x3) == i) + if ((bgCnt[1] & 0x3) == i) { - if (DispCnt & 0x0200) + if (dispCnt & 0x0200) { DoDrawBG(Text, line, 1); } } - if ((BGCnt[0] & 0x3) == i) + if ((bgCnt[0] & 0x3) == i) { - if (DispCnt & 0x0100) + if (dispCnt & 0x0100) { - if ((!Num) && (DispCnt & 0x8)) + if (!CurUnit->Num && (dispCnt & 0x8)) DrawBG_3D(); else DoDrawBG(Text, line, 0); } } - if ((DispCnt & 0x1000) && NumSprites) + if ((dispCnt & 0x1000) && NumSprites[CurUnit->Num]) { DoInterleaveSprites(0x40000 | (i<<16)); } @@ -663,66 +673,70 @@ void GPU2D_Soft::DrawScanlineBGMode(u32 line) } } -void GPU2D_Soft::DrawScanlineBGMode6(u32 line) +void SoftRenderer::DrawScanlineBGMode6(u32 line) { + u32 dispCnt = CurUnit->DispCnt; + u16* bgCnt = CurUnit->BGCnt; for (int i = 3; i >= 0; i--) { - if ((BGCnt[2] & 0x3) == i) + if ((bgCnt[2] & 0x3) == i) { - if (DispCnt & 0x0400) + if (dispCnt & 0x0400) { DoDrawBG_Large(line); } } - if ((BGCnt[0] & 0x3) == i) + if ((bgCnt[0] & 0x3) == i) { - if (DispCnt & 0x0100) + if (dispCnt & 0x0100) { - if ((!Num) && (DispCnt & 0x8)) + if ((!CurUnit->Num) && (dispCnt & 0x8)) DrawBG_3D(); } } - if ((DispCnt & 0x1000) && NumSprites) + if ((dispCnt & 0x1000) && NumSprites[CurUnit->Num]) { DoInterleaveSprites(0x40000 | (i<<16)) } } } -void GPU2D_Soft::DrawScanlineBGMode7(u32 line) +void SoftRenderer::DrawScanlineBGMode7(u32 line) { + u32 dispCnt = CurUnit->DispCnt; + u16* bgCnt = CurUnit->BGCnt; // mode 7 only has text-mode BG0 and BG1 for (int i = 3; i >= 0; i--) { - if ((BGCnt[1] & 0x3) == i) + if ((bgCnt[1] & 0x3) == i) { - if (DispCnt & 0x0200) + if (dispCnt & 0x0200) { DoDrawBG(Text, line, 1); } } - if ((BGCnt[0] & 0x3) == i) + if ((bgCnt[0] & 0x3) == i) { - if (DispCnt & 0x0100) + if (dispCnt & 0x0100) { - if ((!Num) && (DispCnt & 0x8)) + if (!CurUnit->Num && (dispCnt & 0x8)) DrawBG_3D(); else DoDrawBG(Text, line, 0); } } - if ((DispCnt & 0x1000) && NumSprites) + if ((dispCnt & 0x1000) && NumSprites[CurUnit->Num]) { DoInterleaveSprites(0x40000 | (i<<16)) } } } -void GPU2D_Soft::DrawScanline_BGOBJ(u32 line) +void SoftRenderer::DrawScanline_BGOBJ(u32 line) { // forced blank disables BG/OBJ compositing - if (DispCnt & (1<<7)) + if (CurUnit->DispCnt & (1<<7)) { for (int i = 0; i < 256; i++) BGOBJLine[i] = 0xFF3F3F3F; @@ -731,7 +745,7 @@ void GPU2D_Soft::DrawScanline_BGOBJ(u32 line) } u64 backdrop; - if (Num) backdrop = *(u16*)&GPU::Palette[0x400]; + if (CurUnit->Num) backdrop = *(u16*)&GPU::Palette[0x400]; else backdrop = *(u16*)&GPU::Palette[0]; { @@ -746,14 +760,15 @@ void GPU2D_Soft::DrawScanline_BGOBJ(u32 line) *(u64*)&BGOBJLine[i] = backdrop; } - if (DispCnt & 0xE000) - CalculateWindowMask(line); + if (CurUnit->DispCnt & 0xE000) + CurUnit->CalculateWindowMask(line, WindowMask, OBJWindow[CurUnit->Num]); else memset(WindowMask, 0xFF, 256); ApplySpriteMosaicX(); + CurBGXMosaicTable = MosaicTable[CurUnit->BGMosaicSize[0]]; - switch (DispCnt & 0x7) + switch (CurUnit->DispCnt & 0x7) { case 0: DrawScanlineBGMode<0>(line); break; case 1: DrawScanlineBGMode<1>(line); break; @@ -780,7 +795,7 @@ void GPU2D_Soft::DrawScanline_BGOBJ(u32 line) } else { - if (Num == 0) + if (CurUnit->Num == 0) { for (int i = 0; i < 256; i++) { @@ -791,7 +806,7 @@ void GPU2D_Soft::DrawScanline_BGOBJ(u32 line) u32 flag1 = val1 >> 24; u32 flag2 = val2 >> 24; - u32 bldcnteffect = (BlendCnt >> 6) & 0x3; + u32 bldcnteffect = (CurUnit->BlendCnt >> 6) & 0x3; u32 target1; if (flag1 & 0x80) target1 = 0x0010; @@ -803,7 +818,7 @@ void GPU2D_Soft::DrawScanline_BGOBJ(u32 line) else if (flag2 & 0x40) target2 = 0x0100; else target2 = flag2 << 8; - if (((flag1 & 0xC0) == 0x40) && (BlendCnt & target2)) + if (((flag1 & 0xC0) == 0x40) && (CurUnit->BlendCnt & target2)) { // 3D on top, blending @@ -815,15 +830,15 @@ void GPU2D_Soft::DrawScanline_BGOBJ(u32 line) { // 3D on top, normal/fade - if (bldcnteffect == 1) bldcnteffect = 0; - if (!(BlendCnt & 0x0001)) bldcnteffect = 0; - if (!(WindowMask[i] & 0x20)) bldcnteffect = 0; + if (bldcnteffect == 1) bldcnteffect = 0; + if (!(CurUnit->BlendCnt & 0x0001)) bldcnteffect = 0; + if (!(WindowMask[i] & 0x20)) bldcnteffect = 0; BGOBJLine[i] = val2; BGOBJLine[256+i] = ColorComposite(i, val2, val3); - BGOBJLine[512+i] = (bldcnteffect << 24) | (EVY << 8); + BGOBJLine[512+i] = (bldcnteffect << 24) | (CurUnit->EVY << 8); } - else if (((flag2 & 0xC0) == 0x40) && ((BlendCnt & 0x01C0) == 0x0140)) + else if (((flag2 & 0xC0) == 0x40) && ((CurUnit->BlendCnt & 0x01C0) == 0x0140)) { // 3D on bottom, blending @@ -833,18 +848,18 @@ void GPU2D_Soft::DrawScanline_BGOBJ(u32 line) eva = flag1 & 0x1F; evb = 16 - eva; } - else if (((BlendCnt & target1) && (WindowMask[i] & 0x20)) || - ((flag1 & 0xC0) == 0x80)) + else if (((CurUnit->BlendCnt & target1) && (WindowMask[i] & 0x20)) || + ((flag1 & 0xC0) == 0x80)) { - eva = EVA; - evb = EVB; + eva = CurUnit->EVA; + evb = CurUnit->EVB; } else bldcnteffect = 7; BGOBJLine[i] = val1; BGOBJLine[256+i] = ColorComposite(i, val1, val3); - BGOBJLine[512+i] = (bldcnteffect << 24) | (EVB << 16) | (EVA << 8); + BGOBJLine[512+i] = (bldcnteffect << 24) | (CurUnit->EVB << 16) | (CurUnit->EVA << 8); } else { @@ -870,13 +885,13 @@ void GPU2D_Soft::DrawScanline_BGOBJ(u32 line) } } - if (BGMosaicY >= BGMosaicYMax) + if (CurUnit->BGMosaicY >= CurUnit->BGMosaicYMax) { - BGMosaicY = 0; - BGMosaicYMax = BGMosaicSize[1]; + CurUnit->BGMosaicY = 0; + CurUnit->BGMosaicYMax = CurUnit->BGMosaicSize[1]; } else - BGMosaicY++; + CurUnit->BGMosaicY++; /*if (OBJMosaicY >= OBJMosaicYMax) { @@ -888,7 +903,7 @@ void GPU2D_Soft::DrawScanline_BGOBJ(u32 line) } -void GPU2D_Soft::DrawPixel_Normal(u32* dst, u16 color, u32 flag) +void SoftRenderer::DrawPixel_Normal(u32* dst, u16 color, u32 flag) { u8 r = (color & 0x001F) << 1; u8 g = (color & 0x03E0) >> 4; @@ -899,7 +914,7 @@ void GPU2D_Soft::DrawPixel_Normal(u32* dst, u16 color, u32 flag) *dst = r | (g << 8) | (b << 16) | flag; } -void GPU2D_Soft::DrawPixel_Accel(u32* dst, u16 color, u32 flag) +void SoftRenderer::DrawPixel_Accel(u32* dst, u16 color, u32 flag) { u8 r = (color & 0x001F) << 1; u8 g = (color & 0x03E0) >> 4; @@ -910,7 +925,7 @@ void GPU2D_Soft::DrawPixel_Accel(u32* dst, u16 color, u32 flag) *dst = r | (g << 8) | (b << 16) | flag; } -void GPU2D_Soft::DrawBG_3D() +void SoftRenderer::DrawBG_3D() { int i = 0; @@ -940,33 +955,33 @@ void GPU2D_Soft::DrawBG_3D() } } -template<bool mosaic, GPU2D_Soft::DrawPixel drawPixel> -void GPU2D_Soft::DrawBG_Text(u32 line, u32 bgnum) +template<bool mosaic, SoftRenderer::DrawPixel drawPixel> +void SoftRenderer::DrawBG_Text(u32 line, u32 bgnum) { - u16 bgcnt = BGCnt[bgnum]; + u16 bgcnt = CurUnit->BGCnt[bgnum]; u32 tilesetaddr, tilemapaddr; u16* pal; u32 extpal, extpalslot; - u16 xoff = BGXPos[bgnum]; - u16 yoff = BGYPos[bgnum] + line; + u16 xoff = CurUnit->BGXPos[bgnum]; + u16 yoff = CurUnit->BGYPos[bgnum] + line; if (bgcnt & 0x0040) { // vertical mosaic - yoff -= BGMosaicY; + yoff -= CurUnit->BGMosaicY; } u32 widexmask = (bgcnt & 0x4000) ? 0x100 : 0; - extpal = (DispCnt & 0x40000000); + extpal = (CurUnit->DispCnt & 0x40000000); if (extpal) extpalslot = ((bgnum<2) && (bgcnt&0x2000)) ? (2+bgnum) : bgnum; u8* bgvram; u32 bgvrammask; - GetBGVRAM(bgvram, bgvrammask); - if (Num) + CurUnit->GetBGVRAM(bgvram, bgvrammask); + if (CurUnit->Num) { tilesetaddr = ((bgcnt & 0x003C) << 12); tilemapaddr = ((bgcnt & 0x1F00) << 3); @@ -975,8 +990,8 @@ void GPU2D_Soft::DrawBG_Text(u32 line, u32 bgnum) } else { - tilesetaddr = ((DispCnt & 0x07000000) >> 8) + ((bgcnt & 0x003C) << 12); - tilemapaddr = ((DispCnt & 0x38000000) >> 11) + ((bgcnt & 0x1F00) << 3); + tilesetaddr = ((CurUnit->DispCnt & 0x07000000) >> 8) + ((bgcnt & 0x003C) << 12); + tilemapaddr = ((CurUnit->DispCnt & 0x38000000) >> 11) + ((bgcnt & 0x1F00) << 3); pal = (u16*)&GPU::Palette[0]; } @@ -1006,7 +1021,7 @@ void GPU2D_Soft::DrawBG_Text(u32 line, u32 bgnum) { curtile = *(u16*)&bgvram[(tilemapaddr + ((xoff & 0xF8) >> 2) + ((xoff & widexmask) << 3)) & bgvrammask]; - if (extpal) curpal = GetBGExtPal(extpalslot, curtile>>12); + if (extpal) curpal = CurUnit->GetBGExtPal(extpalslot, curtile>>12); else curpal = pal; pixelsaddr = tilesetaddr + ((curtile & 0x03FF) << 6) @@ -1027,7 +1042,7 @@ void GPU2D_Soft::DrawBG_Text(u32 line, u32 bgnum) // load a new tile curtile = *(u16*)&bgvram[(tilemapaddr + ((xpos & 0xF8) >> 2) + ((xpos & widexmask) << 3)) & bgvrammask]; - if (extpal) curpal = GetBGExtPal(extpalslot, curtile>>12); + if (extpal) curpal = CurUnit->GetBGExtPal(extpalslot, curtile>>12); else curpal = pal; pixelsaddr = tilesetaddr + ((curtile & 0x03FF) << 6) @@ -1104,10 +1119,10 @@ void GPU2D_Soft::DrawBG_Text(u32 line, u32 bgnum) } } -template<bool mosaic, GPU2D_Soft::DrawPixel drawPixel> -void GPU2D_Soft::DrawBG_Affine(u32 line, u32 bgnum) +template<bool mosaic, SoftRenderer::DrawPixel drawPixel> +void SoftRenderer::DrawBG_Affine(u32 line, u32 bgnum) { - u16 bgcnt = BGCnt[bgnum]; + u16 bgcnt = CurUnit->BGCnt[bgnum]; u32 tilesetaddr, tilemapaddr; u16* pal; @@ -1126,26 +1141,26 @@ void GPU2D_Soft::DrawBG_Affine(u32 line, u32 bgnum) if (bgcnt & 0x2000) overflowmask = 0; else overflowmask = ~(coordmask | 0x7FF); - s16 rotA = BGRotA[bgnum-2]; - s16 rotB = BGRotB[bgnum-2]; - s16 rotC = BGRotC[bgnum-2]; - s16 rotD = BGRotD[bgnum-2]; + s16 rotA = CurUnit->BGRotA[bgnum-2]; + s16 rotB = CurUnit->BGRotB[bgnum-2]; + s16 rotC = CurUnit->BGRotC[bgnum-2]; + s16 rotD = CurUnit->BGRotD[bgnum-2]; - s32 rotX = BGXRefInternal[bgnum-2]; - s32 rotY = BGYRefInternal[bgnum-2]; + s32 rotX = CurUnit->BGXRefInternal[bgnum-2]; + s32 rotY = CurUnit->BGYRefInternal[bgnum-2]; if (bgcnt & 0x0040) { // vertical mosaic - rotX -= (BGMosaicY * rotB); - rotY -= (BGMosaicY * rotD); + rotX -= (CurUnit->BGMosaicY * rotB); + rotY -= (CurUnit->BGMosaicY * rotD); } u8* bgvram; u32 bgvrammask; - GetBGVRAM(bgvram, bgvrammask); + CurUnit->GetBGVRAM(bgvram, bgvrammask); - if (Num) + if (CurUnit->Num) { tilesetaddr = ((bgcnt & 0x003C) << 12); tilemapaddr = ((bgcnt & 0x1F00) << 3); @@ -1154,8 +1169,8 @@ void GPU2D_Soft::DrawBG_Affine(u32 line, u32 bgnum) } else { - tilesetaddr = ((DispCnt & 0x07000000) >> 8) + ((bgcnt & 0x003C) << 12); - tilemapaddr = ((DispCnt & 0x38000000) >> 11) + ((bgcnt & 0x1F00) << 3); + tilesetaddr = ((CurUnit->DispCnt & 0x07000000) >> 8) + ((bgcnt & 0x003C) << 12); + tilemapaddr = ((CurUnit->DispCnt & 0x38000000) >> 11) + ((bgcnt & 0x1F00) << 3); pal = (u16*)&GPU::Palette[0]; } @@ -1201,14 +1216,14 @@ void GPU2D_Soft::DrawBG_Affine(u32 line, u32 bgnum) rotY += rotC; } - BGXRefInternal[bgnum-2] += rotB; - BGYRefInternal[bgnum-2] += rotD; + CurUnit->BGXRefInternal[bgnum-2] += rotB; + CurUnit->BGYRefInternal[bgnum-2] += rotD; } -template<bool mosaic, GPU2D_Soft::DrawPixel drawPixel> -void GPU2D_Soft::DrawBG_Extended(u32 line, u32 bgnum) +template<bool mosaic, SoftRenderer::DrawPixel drawPixel> +void SoftRenderer::DrawBG_Extended(u32 line, u32 bgnum) { - u16 bgcnt = BGCnt[bgnum]; + u16 bgcnt = CurUnit->BGCnt[bgnum]; u32 tilesetaddr, tilemapaddr; u16* pal; @@ -1216,23 +1231,23 @@ void GPU2D_Soft::DrawBG_Extended(u32 line, u32 bgnum) u8* bgvram; u32 bgvrammask; - GetBGVRAM(bgvram, bgvrammask); + CurUnit->GetBGVRAM(bgvram, bgvrammask); - extpal = (DispCnt & 0x40000000); + extpal = (CurUnit->DispCnt & 0x40000000); - s16 rotA = BGRotA[bgnum-2]; - s16 rotB = BGRotB[bgnum-2]; - s16 rotC = BGRotC[bgnum-2]; - s16 rotD = BGRotD[bgnum-2]; + s16 rotA = CurUnit->BGRotA[bgnum-2]; + s16 rotB = CurUnit->BGRotB[bgnum-2]; + s16 rotC = CurUnit->BGRotC[bgnum-2]; + s16 rotD = CurUnit->BGRotD[bgnum-2]; - s32 rotX = BGXRefInternal[bgnum-2]; - s32 rotY = BGYRefInternal[bgnum-2]; + s32 rotX = CurUnit->BGXRefInternal[bgnum-2]; + s32 rotY = CurUnit->BGYRefInternal[bgnum-2]; if (bgcnt & 0x0040) { // vertical mosaic - rotX -= (BGMosaicY * rotB); - rotY -= (BGMosaicY * rotD); + rotX -= (CurUnit->BGMosaicY * rotB); + rotY -= (CurUnit->BGMosaicY * rotD); } if (bgcnt & 0x0080) @@ -1261,8 +1276,8 @@ void GPU2D_Soft::DrawBG_Extended(u32 line, u32 bgnum) ofymask = ~ymask; } - if (Num) tilemapaddr = ((bgcnt & 0x1F00) << 6); - else tilemapaddr = ((bgcnt & 0x1F00) << 6); + if (CurUnit->Num) tilemapaddr = ((bgcnt & 0x1F00) << 6); + else tilemapaddr = ((bgcnt & 0x1F00) << 6); if (bgcnt & 0x0004) { @@ -1304,8 +1319,8 @@ void GPU2D_Soft::DrawBG_Extended(u32 line, u32 bgnum) { // 256-color bitmap - if (Num) pal = (u16*)&GPU::Palette[0x400]; - else pal = (u16*)&GPU::Palette[0]; + if (CurUnit->Num) pal = (u16*)&GPU::Palette[0x400]; + else pal = (u16*)&GPU::Palette[0]; u8 color; @@ -1358,7 +1373,7 @@ void GPU2D_Soft::DrawBG_Extended(u32 line, u32 bgnum) if (bgcnt & 0x2000) overflowmask = 0; else overflowmask = ~(coordmask | 0x7FF); - if (Num) + if (CurUnit->Num) { tilesetaddr = ((bgcnt & 0x003C) << 12); tilemapaddr = ((bgcnt & 0x1F00) << 3); @@ -1367,8 +1382,8 @@ void GPU2D_Soft::DrawBG_Extended(u32 line, u32 bgnum) } else { - tilesetaddr = ((DispCnt & 0x07000000) >> 8) + ((bgcnt & 0x003C) << 12); - tilemapaddr = ((DispCnt & 0x38000000) >> 11) + ((bgcnt & 0x1F00) << 3); + tilesetaddr = ((CurUnit->DispCnt & 0x07000000) >> 8) + ((bgcnt & 0x003C) << 12); + tilemapaddr = ((CurUnit->DispCnt & 0x38000000) >> 11) + ((bgcnt & 0x1F00) << 3); pal = (u16*)&GPU::Palette[0]; } @@ -1400,7 +1415,7 @@ void GPU2D_Soft::DrawBG_Extended(u32 line, u32 bgnum) { curtile = *(u16*)&bgvram[(tilemapaddr + (((((finalY & coordmask) >> 11) << yshift) + ((finalX & coordmask) >> 11)) << 1)) & bgvrammask]; - if (extpal) curpal = GetBGExtPal(bgnum, curtile>>12); + if (extpal) curpal = CurUnit->GetBGExtPal(bgnum, curtile>>12); else curpal = pal; // draw pixel @@ -1422,14 +1437,14 @@ void GPU2D_Soft::DrawBG_Extended(u32 line, u32 bgnum) } } - BGXRefInternal[bgnum-2] += rotB; - BGYRefInternal[bgnum-2] += rotD; + CurUnit->BGXRefInternal[bgnum-2] += rotB; + CurUnit->BGYRefInternal[bgnum-2] += rotD; } -template<bool mosaic, GPU2D_Soft::DrawPixel drawPixel> -void GPU2D_Soft::DrawBG_Large(u32 line) // BG is always BG2 +template<bool mosaic, SoftRenderer::DrawPixel drawPixel> +void SoftRenderer::DrawBG_Large(u32 line) // BG is always BG2 { - u16 bgcnt = BGCnt[2]; + u16 bgcnt = CurUnit->BGCnt[2]; u32 tilesetaddr, tilemapaddr; u16* pal; @@ -1461,28 +1476,28 @@ void GPU2D_Soft::DrawBG_Large(u32 line) // BG is always BG2 ofymask = ~ymask; } - s16 rotA = BGRotA[0]; - s16 rotB = BGRotB[0]; - s16 rotC = BGRotC[0]; - s16 rotD = BGRotD[0]; + s16 rotA = CurUnit->BGRotA[0]; + s16 rotB = CurUnit->BGRotB[0]; + s16 rotC = CurUnit->BGRotC[0]; + s16 rotD = CurUnit->BGRotD[0]; - s32 rotX = BGXRefInternal[0]; - s32 rotY = BGYRefInternal[0]; + s32 rotX = CurUnit->BGXRefInternal[0]; + s32 rotY = CurUnit->BGYRefInternal[0]; if (bgcnt & 0x0040) { // vertical mosaic - rotX -= (BGMosaicY * rotB); - rotY -= (BGMosaicY * rotD); + rotX -= (CurUnit->BGMosaicY * rotB); + rotY -= (CurUnit->BGMosaicY * rotD); } u8* bgvram; u32 bgvrammask; - GetBGVRAM(bgvram, bgvrammask); + CurUnit->GetBGVRAM(bgvram, bgvrammask); // 256-color bitmap - if (Num) pal = (u16*)&GPU::Palette[0x400]; + if (CurUnit->Num) pal = (u16*)&GPU::Palette[0x400]; else pal = (u16*)&GPU::Palette[0]; u8 color; @@ -1517,8 +1532,8 @@ void GPU2D_Soft::DrawBG_Large(u32 line) // BG is always BG2 rotY += rotC; } - BGXRefInternal[0] += rotB; - BGYRefInternal[0] += rotD; + CurUnit->BGXRefInternal[0] += rotB; + CurUnit->BGYRefInternal[0] += rotD; } // OBJ line buffer: @@ -1528,46 +1543,52 @@ void GPU2D_Soft::DrawBG_Large(u32 line) // BG is always BG2 // * bit19: X mosaic should be applied here // * bit24-31: compositor flags -void GPU2D_Soft::ApplySpriteMosaicX() +void SoftRenderer::ApplySpriteMosaicX() { // apply X mosaic if needed // X mosaic for sprites is applied after all sprites are rendered - if (OBJMosaicSize[0] == 0) return; + if (CurUnit->OBJMosaicSize[0] == 0) return; + + u32* objLine = OBJLine[CurUnit->Num]; + u8* objIndex = OBJIndex[CurUnit->Num]; - u32 lastcolor = OBJLine[0]; + u8* curOBJXMosaicTable = MosaicTable[CurUnit->OBJMosaicSize[1]]; + + u32 lastcolor = objLine[0]; for (u32 i = 1; i < 256; i++) { - if (!(OBJLine[i] & 0x100000)) + if (!(objLine[i] & 0x100000)) { // not a mosaic'd sprite pixel continue; } - if ((OBJIndex[i] != OBJIndex[i-1]) || (CurOBJXMosaicTable[i] == 0)) - lastcolor = OBJLine[i]; + if ((objIndex[i] != objIndex[i-1]) || (curOBJXMosaicTable[i] == 0)) + lastcolor = objLine[i]; else - OBJLine[i] = lastcolor; + objLine[i] = lastcolor; } } -template <GPU2D_Soft::DrawPixel drawPixel> -void GPU2D_Soft::InterleaveSprites(u32 prio) +template <SoftRenderer::DrawPixel drawPixel> +void SoftRenderer::InterleaveSprites(u32 prio) { - u16* pal = (u16*)&GPU::Palette[Num ? 0x600 : 0x200]; + u32* objLine = OBJLine[CurUnit->Num]; + u16* pal = (u16*)&GPU::Palette[CurUnit->Num ? 0x600 : 0x200]; - if (DispCnt & 0x80000000) + if (CurUnit->DispCnt & 0x80000000) { - u16* extpal = GetOBJExtPal(); + u16* extpal = CurUnit->GetOBJExtPal(); for (u32 i = 0; i < 256; i++) { - if ((OBJLine[i] & 0x70000) != prio) continue; + if ((objLine[i] & 0x70000) != prio) continue; if (!(WindowMask[i] & 0x10)) continue; u16 color; - u32 pixel = OBJLine[i]; + u32 pixel = objLine[i]; if (pixel & 0x8000) color = pixel & 0x7FFF; @@ -1585,11 +1606,11 @@ void GPU2D_Soft::InterleaveSprites(u32 prio) for (u32 i = 0; i < 256; i++) { - if ((OBJLine[i] & 0x70000) != prio) continue; + if ((objLine[i] & 0x70000) != prio) continue; if (!(WindowMask[i] & 0x10)) continue; u16 color; - u32 pixel = OBJLine[i]; + u32 pixel = objLine[i]; if (pixel & 0x8000) color = pixel & 0x7FFF; @@ -1611,8 +1632,10 @@ void GPU2D_Soft::InterleaveSprites(u32 prio) DrawSprite_##type<false>(__VA_ARGS__); \ } -void GPU2D_Soft::DrawSprites(u32 line) +void SoftRenderer::DrawSprites(u32 line, Unit* unit) { + CurUnit = unit; + if (line == 0) { // reset those counters here @@ -1621,11 +1644,11 @@ void GPU2D_Soft::DrawSprites(u32 line) // however, sprites are rendered one scanline in advance // so they need to be reset a bit earlier - OBJMosaicY = 0; - OBJMosaicYCount = 0; + CurUnit->OBJMosaicY = 0; + CurUnit->OBJMosaicYCount = 0; } - if (Num == 0) + if (CurUnit->Num == 0) { auto objDirty = GPU::VRAMDirty_AOBJ.DeriveState(GPU::VRAMMap_AOBJ); GPU::MakeVRAMFlat_AOBJCoherent(objDirty); @@ -1636,14 +1659,14 @@ void GPU2D_Soft::DrawSprites(u32 line) GPU::MakeVRAMFlat_BOBJCoherent(objDirty); } - NumSprites = 0; - memset(OBJLine, 0, 256*4); - memset(OBJWindow, 0, 256); - if (!(DispCnt & 0x1000)) return; + NumSprites[CurUnit->Num] = 0; + memset(OBJLine[CurUnit->Num], 0, 256*4); + memset(OBJWindow[CurUnit->Num], 0, 256); + if (!(CurUnit->DispCnt & 0x1000)) return; memset(OBJIndex, 0xFF, 256); - u16* oam = (u16*)&GPU::OAM[Num ? 0x400 : 0]; + u16* oam = (u16*)&GPU::OAM[CurUnit->Num ? 0x400 : 0]; const s32 spritewidth[16] = { @@ -1675,7 +1698,7 @@ void GPU2D_Soft::DrawSprites(u32 line) if ((attrib[0] & 0x1000) && !iswin) { // apply Y mosaic - sprline = OBJMosaicY; + sprline = CurUnit->OBJMosaicY; } else sprline = line; @@ -1707,7 +1730,7 @@ void GPU2D_Soft::DrawSprites(u32 line) DoDrawSprite(Rotscale, sprnum, boundwidth, boundheight, width, height, xpos, ypos); - NumSprites++; + NumSprites[CurUnit->Num]++; } else { @@ -1729,16 +1752,16 @@ void GPU2D_Soft::DrawSprites(u32 line) DoDrawSprite(Normal, sprnum, width, height, xpos, ypos); - NumSprites++; + NumSprites[CurUnit->Num]++; } } } } template<bool window> -void GPU2D_Soft::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos) +void SoftRenderer::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos) { - u16* oam = (u16*)&GPU::OAM[Num ? 0x400 : 0]; + u16* oam = (u16*)&GPU::OAM[CurUnit->Num ? 0x400 : 0]; u16* attrib = &oam[num * 4]; u16* rotparams = &oam[(((attrib[1] >> 9) & 0x1F) * 16) + 3]; @@ -1750,7 +1773,11 @@ void GPU2D_Soft::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u u8* objvram; u32 objvrammask; - GetOBJVRAM(objvram, objvrammask); + CurUnit->GetOBJVRAM(objvram, objvrammask); + + u32* objLine = OBJLine[CurUnit->Num]; + u8* objIndex = OBJIndex[CurUnit->Num]; + u8* objWindow = OBJWindow[CurUnit->Num]; s32 centerX = boundwidth >> 1; s32 centerY = boundheight >> 1; @@ -1796,9 +1823,9 @@ void GPU2D_Soft::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u pixelattr |= (0xC0000000 | (alpha << 24)); u32 pixelsaddr; - if (DispCnt & 0x40) + if (CurUnit->DispCnt & 0x40) { - if (DispCnt & 0x20) + if (CurUnit->DispCnt & 0x20) { // 'reserved' // draws nothing @@ -1807,13 +1834,13 @@ void GPU2D_Soft::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u } else { - pixelsaddr = tilenum << (7 + ((DispCnt >> 22) & 0x1)); + pixelsaddr = tilenum << (7 + ((CurUnit->DispCnt >> 22) & 0x1)); ytilefactor = ((width >> 8) * 2); } } else { - if (DispCnt & 0x20) + if (CurUnit->DispCnt & 0x20) { pixelsaddr = ((tilenum & 0x01F) << 4) + ((tilenum & 0x3E0) << 7); ytilefactor = (256 * 2); @@ -1833,15 +1860,15 @@ void GPU2D_Soft::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u if (color & 0x8000) { - if (window) OBJWindow[xpos] = 1; - else { OBJLine[xpos] = color | pixelattr; OBJIndex[xpos] = num; } + if (window) objWindow[xpos] = 1; + else { objLine[xpos] = color | pixelattr; objIndex[xpos] = num; } } else if (!window) { - if (OBJLine[xpos] == 0) + if (objLine[xpos] == 0) { - OBJLine[xpos] = pixelattr & 0x180000; - OBJIndex[xpos] = num; + objLine[xpos] = pixelattr & 0x180000; + objIndex[xpos] = num; } } } @@ -1855,9 +1882,9 @@ void GPU2D_Soft::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u else { u32 pixelsaddr = tilenum; - if (DispCnt & 0x10) + if (CurUnit->DispCnt & 0x10) { - pixelsaddr <<= ((DispCnt >> 20) & 0x3); + pixelsaddr <<= ((CurUnit->DispCnt >> 20) & 0x3); ytilefactor = (width >> 11) << ((attrib[0] & 0x2000) ? 1:0); } else @@ -1877,7 +1904,7 @@ void GPU2D_Soft::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u if (!window) { - if (!(DispCnt & 0x80000000)) + if (!(CurUnit->DispCnt & 0x80000000)) pixelattr |= 0x1000; else pixelattr |= ((attrib[2] & 0xF000) >> 4); @@ -1891,15 +1918,15 @@ void GPU2D_Soft::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u if (color) { - if (window) OBJWindow[xpos] = 1; - else { OBJLine[xpos] = color | pixelattr; OBJIndex[xpos] = num; } + if (window) objWindow[xpos] = 1; + else { objLine[xpos] = color | pixelattr; objIndex[xpos] = num; } } else if (!window) { - if (OBJLine[xpos] == 0) + if (objLine[xpos] == 0) { - OBJLine[xpos] = pixelattr & 0x180000; - OBJIndex[xpos] = num; + objLine[xpos] = pixelattr & 0x180000; + objIndex[xpos] = num; } } } @@ -1931,15 +1958,15 @@ void GPU2D_Soft::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u if (color) { - if (window) OBJWindow[xpos] = 1; - else { OBJLine[xpos] = color | pixelattr; OBJIndex[xpos] = num; } + if (window) objWindow[xpos] = 1; + else { objLine[xpos] = color | pixelattr; objIndex[xpos] = num; } } else if (!window) { - if (OBJLine[xpos] == 0) + if (objLine[xpos] == 0) { - OBJLine[xpos] = pixelattr & 0x180000; - OBJIndex[xpos] = num; + objLine[xpos] = pixelattr & 0x180000; + objIndex[xpos] = num; } } } @@ -1954,9 +1981,9 @@ void GPU2D_Soft::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u } template<bool window> -void GPU2D_Soft::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 ypos) +void SoftRenderer::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 ypos) { - u16* oam = (u16*)&GPU::OAM[Num ? 0x400 : 0]; + u16* oam = (u16*)&GPU::OAM[CurUnit->Num ? 0x400 : 0]; u16* attrib = &oam[num * 4]; u32 pixelattr = ((attrib[2] & 0x0C00) << 6) | 0xC0000; @@ -1973,7 +2000,11 @@ void GPU2D_Soft::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 u8* objvram; u32 objvrammask; - GetOBJVRAM(objvram, objvrammask); + CurUnit->GetOBJVRAM(objvram, objvrammask); + + u32* objLine = OBJLine[CurUnit->Num]; + u8* objIndex = OBJIndex[CurUnit->Num]; + u8* objWindow = OBJWindow[CurUnit->Num]; // yflip if (attrib[1] & 0x2000) @@ -2006,9 +2037,9 @@ void GPU2D_Soft::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 pixelattr |= (0xC0000000 | (alpha << 24)); u32 pixelsaddr = tilenum; - if (DispCnt & 0x40) + if (CurUnit->DispCnt & 0x40) { - if (DispCnt & 0x20) + if (CurUnit->DispCnt & 0x20) { // 'reserved' // draws nothing @@ -2017,13 +2048,13 @@ void GPU2D_Soft::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 } else { - pixelsaddr <<= (7 + ((DispCnt >> 22) & 0x1)); + pixelsaddr <<= (7 + ((CurUnit->DispCnt >> 22) & 0x1)); pixelsaddr += (ypos * width * 2); } } else { - if (DispCnt & 0x20) + if (CurUnit->DispCnt & 0x20) { pixelsaddr = ((tilenum & 0x01F) << 4) + ((tilenum & 0x3E0) << 7); pixelsaddr += (ypos * 256 * 2); @@ -2057,15 +2088,15 @@ void GPU2D_Soft::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 if (color & 0x8000) { - if (window) OBJWindow[xpos] = 1; - else { OBJLine[xpos] = color | pixelattr; OBJIndex[xpos] = num; } + if (window) objWindow[xpos] = 1; + else { objLine[xpos] = color | pixelattr; objIndex[xpos] = num; } } else if (!window) { - if (OBJLine[xpos] == 0) + if (objLine[xpos] == 0) { - OBJLine[xpos] = pixelattr & 0x180000; - OBJIndex[xpos] = num; + objLine[xpos] = pixelattr & 0x180000; + objIndex[xpos] = num; } } @@ -2076,9 +2107,9 @@ void GPU2D_Soft::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 else { u32 pixelsaddr = tilenum; - if (DispCnt & 0x10) + if (CurUnit->DispCnt & 0x10) { - pixelsaddr <<= ((DispCnt >> 20) & 0x3); + pixelsaddr <<= ((CurUnit->DispCnt >> 20) & 0x3); pixelsaddr += ((ypos >> 3) * (width >> 3)) << ((attrib[0] & 0x2000) ? 1:0); } else @@ -2098,7 +2129,7 @@ void GPU2D_Soft::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 if (!window) { - if (!(DispCnt & 0x80000000)) + if (!(CurUnit->DispCnt & 0x80000000)) pixelattr |= 0x1000; else pixelattr |= ((attrib[2] & 0xF000) >> 4); @@ -2127,15 +2158,15 @@ void GPU2D_Soft::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 if (color) { - if (window) OBJWindow[xpos] = 1; - else { OBJLine[xpos] = color | pixelattr; OBJIndex[xpos] = num; } + if (window) objWindow[xpos] = 1; + else { objLine[xpos] = color | pixelattr; objIndex[xpos] = num; } } else if (!window) { - if (OBJLine[xpos] == 0) + if (objLine[xpos] == 0) { - OBJLine[xpos] = pixelattr & 0x180000; - OBJIndex[xpos] = num; + objLine[xpos] = pixelattr & 0x180000; + objIndex[xpos] = num; } } @@ -2190,15 +2221,15 @@ void GPU2D_Soft::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 if (color) { - if (window) OBJWindow[xpos] = 1; - else { OBJLine[xpos] = color | pixelattr; OBJIndex[xpos] = num; } + if (window) objWindow[xpos] = 1; + else { objLine[xpos] = color | pixelattr; objIndex[xpos] = num; } } else if (!window) { - if (OBJLine[xpos] == 0) + if (objLine[xpos] == 0) { - OBJLine[xpos] = pixelattr & 0x180000; - OBJIndex[xpos] = num; + objLine[xpos] = pixelattr & 0x180000; + objIndex[xpos] = num; } } @@ -2210,8 +2241,4 @@ void GPU2D_Soft::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 } } -void GPU2D_Soft::MosaicXSizeChanged() -{ - CurBGXMosaicTable = MosaicTable[BGMosaicSize[0]]; - CurOBJXMosaicTable = MosaicTable[OBJMosaicSize[1]]; -} +}
\ No newline at end of file diff --git a/src/GPU2D_Soft.h b/src/GPU2D_Soft.h index 754f08a..b209810 100644 --- a/src/GPU2D_Soft.h +++ b/src/GPU2D_Soft.h @@ -20,32 +20,32 @@ #include "GPU2D.h" -class GPU2D_Soft : public GPU2D +namespace GPU2D { -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; +class SoftRenderer : public Renderer2D +{ +public: + 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); -};
\ No newline at end of file +}; + +}
\ No newline at end of file diff --git a/src/NDS.cpp b/src/NDS.cpp index 7313c2a..69d64b7 100644 --- a/src/NDS.cpp +++ b/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) |