aboutsummaryrefslogtreecommitdiff
path: root/src/GPU2D.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/GPU2D.cpp')
-rw-r--r--src/GPU2D.cpp369
1 files changed, 195 insertions, 174 deletions
diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp
index 7774c65..c1a2d47 100644
--- a/src/GPU2D.cpp
+++ b/src/GPU2D.cpp
@@ -148,12 +148,6 @@ void GPU2D::Reset()
CaptureCnt = 0;
MasterBrightness = 0;
-
- BGExtPalStatus[0] = 0;
- BGExtPalStatus[1] = 0;
- BGExtPalStatus[2] = 0;
- BGExtPalStatus[3] = 0;
- OBJExtPalStatus = 0;
}
void GPU2D::DoSavestate(Savestate* file)
@@ -208,13 +202,6 @@ void GPU2D::DoSavestate(Savestate* file)
if (!file->Saving)
{
- // refresh those
- BGExtPalStatus[0] = 0;
- BGExtPalStatus[1] = 0;
- BGExtPalStatus[2] = 0;
- BGExtPalStatus[3] = 0;
- OBJExtPalStatus = 0;
-
CurBGXMosaicTable = MosaicTable[BGMosaicSize[0]];
CurOBJXMosaicTable = MosaicTable[OBJMosaicSize[0]];
}
@@ -228,9 +215,6 @@ void GPU2D::SetFramebuffer(u32* buf)
void GPU2D::SetRenderSettings(bool accel)
{
Accelerated = accel;
-
- if (Accelerated) DrawPixel = DrawPixel_Accel;
- else DrawPixel = DrawPixel_Normal;
}
@@ -761,6 +745,25 @@ void GPU2D::DrawScanline(u32 line)
int n3dline = line;
line = GPU::VCount;
+ if (Num == 0)
+ {
+ auto bgDirty = GPU::VRAMDirty_ABG.DeriveState(GPU::VRAMMap_ABG);
+ GPU::MakeVRAMFlat_ABGCoherent(bgDirty);
+ auto bgExtPalDirty = GPU::VRAMDirty_ABGExtPal.DeriveState(GPU::VRAMMap_ABGExtPal);
+ GPU::MakeVRAMFlat_ABGExtPalCoherent(bgExtPalDirty);
+ auto objExtPalDirty = GPU::VRAMDirty_AOBJExtPal.DeriveState(&GPU::VRAMMap_AOBJExtPal);
+ GPU::MakeVRAMFlat_AOBJExtPalCoherent(objExtPalDirty);
+ }
+ else
+ {
+ auto bgDirty = GPU::VRAMDirty_BBG.DeriveState(GPU::VRAMMap_BBG);
+ GPU::MakeVRAMFlat_BBGCoherent(bgDirty);
+ auto bgExtPalDirty = GPU::VRAMDirty_BBGExtPal.DeriveState(GPU::VRAMMap_BBGExtPal);
+ GPU::MakeVRAMFlat_BBGExtPalCoherent(bgExtPalDirty);
+ auto objExtPalDirty = GPU::VRAMDirty_BOBJExtPal.DeriveState(&GPU::VRAMMap_BOBJExtPal);
+ GPU::MakeVRAMFlat_BOBJExtPalCoherent(objExtPalDirty);
+ }
+
bool forceblank = false;
// scanlines that end up outside of the GPU drawing range
@@ -973,6 +976,9 @@ void GPU2D::DoCapture(u32 line, u32 width)
u16* dst = (u16*)GPU::VRAM[dstvram];
u32 dstaddr = (((CaptureCnt >> 18) & 0x3) << 14) + (line * width);
+ static_assert(GPU::VRAMDirtyGranularity == 512);
+ GPU::VRAMDirty[dstvram][(dstaddr & 0x1FFFF) / GPU::VRAMDirtyGranularity] = true;
+
// TODO: handle 3D in accelerated mode!!
u32* srcA;
@@ -1191,85 +1197,20 @@ void GPU2D::SampleFIFO(u32 offset, u32 num)
}
}
-
-void GPU2D::BGExtPalDirty(u32 base)
-{
- BGExtPalStatus[base] = 0;
- BGExtPalStatus[base+1] = 0;
-}
-
-void GPU2D::OBJExtPalDirty()
-{
- OBJExtPalStatus = 0;
-}
-
-
u16* GPU2D::GetBGExtPal(u32 slot, u32 pal)
{
- u16* dst = &BGExtPalCache[slot][pal << 8];
-
- if (!(BGExtPalStatus[slot] & (1<<pal)))
- {
- if (Num)
- {
- if (GPU::VRAMMap_BBGExtPal[slot] & (1<<7))
- memcpy(dst, &GPU::VRAM_H[(slot << 13) + (pal << 9)], 256*2);
- else
- memset(dst, 0, 256*2);
- }
- else
- {
- memset(dst, 0, 256*2);
-
- if (GPU::VRAMMap_ABGExtPal[slot] & (1<<4))
- for (int i = 0; i < 256; i+=2)
- *(u32*)&dst[i] |= *(u32*)&GPU::VRAM_E[(slot << 13) + (pal << 9) + (i << 1)];
-
- if (GPU::VRAMMap_ABGExtPal[slot] & (1<<5))
- for (int i = 0; i < 256; i+=2)
- *(u32*)&dst[i] |= *(u32*)&GPU::VRAM_F[((slot&1) << 13) + (pal << 9) + (i << 1)];
-
- if (GPU::VRAMMap_ABGExtPal[slot] & (1<<6))
- for (int i = 0; i < 256; i+=2)
- *(u32*)&dst[i] |= *(u32*)&GPU::VRAM_G[((slot&1) << 13) + (pal << 9) + (i << 1)];
- }
-
- BGExtPalStatus[slot] |= (1<<pal);
- }
-
- return dst;
+ const u32 PaletteSize = 256 * 2;
+ const u32 SlotSize = PaletteSize * 16;
+ return (u16*)&(Num == 0
+ ? GPU::VRAMFlat_ABGExtPal
+ : GPU::VRAMFlat_BBGExtPal)[slot * SlotSize + pal * PaletteSize];
}
u16* GPU2D::GetOBJExtPal()
{
- u16* dst = OBJExtPalCache;
-
- if (!OBJExtPalStatus)
- {
- if (Num)
- {
- if (GPU::VRAMMap_BOBJExtPal & (1<<8))
- memcpy(dst, &GPU::VRAM_I[0], 16*256*2);
- else
- memset(dst, 0, 16*256*2);
- }
- else
- {
- memset(dst, 0, 16*256*2);
-
- if (GPU::VRAMMap_AOBJExtPal & (1<<5))
- for (int i = 0; i < 16*256; i+=2)
- *(u32*)&dst[i] |= *(u32*)&GPU::VRAM_F[i << 1];
-
- if (GPU::VRAMMap_AOBJExtPal & (1<<6))
- for (int i = 0; i < 16*256; i+=2)
- *(u32*)&dst[i] |= *(u32*)&GPU::VRAM_G[i << 1];
- }
-
- OBJExtPalStatus = 1;
- }
-
- return dst;
+ return Num == 0
+ ? (u16*)GPU::VRAMFlat_AOBJExtPal
+ : (u16*)GPU::VRAMFlat_BOBJExtPal;
}
@@ -1330,10 +1271,36 @@ void GPU2D::CalculateWindowMask(u32 line)
#define DoDrawBG(type, line, num) \
- { if ((BGCnt[num] & 0x0040) && (BGMosaicSize[0] > 0)) DrawBG_##type<true>(line, num); else DrawBG_##type<false>(line, num); }
+ { \
+ if ((BGCnt[num] & 0x0040) && (BGMosaicSize[0] > 0)) \
+ { \
+ if (Accelerated) DrawBG_##type<true, DrawPixel_Accel>(line, num); \
+ else DrawBG_##type<true, DrawPixel_Normal>(line, num); \
+ } \
+ else \
+ { \
+ if (Accelerated) DrawBG_##type<false, DrawPixel_Accel>(line, num); \
+ else DrawBG_##type<false, DrawPixel_Normal>(line, num); \
+ } \
+ }
#define DoDrawBG_Large(line) \
- { if ((BGCnt[2] & 0x0040) && (BGMosaicSize[0] > 0)) DrawBG_Large<true>(line); else DrawBG_Large<false>(line); }
+ do \
+ { \
+ if ((BGCnt[2] & 0x0040) && (BGMosaicSize[0] > 0)) \
+ { \
+ if (Accelerated) DrawBG_Large<true, DrawPixel_Accel>(line); \
+ else DrawBG_Large<true, DrawPixel_Normal>(line); \
+ } \
+ else \
+ { \
+ if (Accelerated) DrawBG_Large<false, DrawPixel_Accel>(line); \
+ else DrawBG_Large<false, DrawPixel_Normal>(line); \
+ } \
+ } while (false)
+
+#define DoInterleaveSprites(prio) \
+ if (Accelerated) InterleaveSprites<DrawPixel_Accel>(prio); else InterleaveSprites<DrawPixel_Normal>(prio);
template<u32 bgmode>
void GPU2D::DrawScanlineBGMode(u32 line)
@@ -1382,7 +1349,7 @@ void GPU2D::DrawScanlineBGMode(u32 line)
}
}
if ((DispCnt & 0x1000) && NumSprites)
- InterleaveSprites(0x40000 | (i<<16));
+ DoInterleaveSprites(0x40000 | (i<<16));
}
}
@@ -1394,7 +1361,7 @@ void GPU2D::DrawScanlineBGMode6(u32 line)
{
if (DispCnt & 0x0400)
{
- DoDrawBG_Large(line)
+ DoDrawBG_Large(line);
}
}
if ((BGCnt[0] & 0x3) == i)
@@ -1406,7 +1373,7 @@ void GPU2D::DrawScanlineBGMode6(u32 line)
}
}
if ((DispCnt & 0x1000) && NumSprites)
- InterleaveSprites(0x40000 | (i<<16));
+ DoInterleaveSprites(0x40000 | (i<<16))
}
}
@@ -1434,7 +1401,7 @@ void GPU2D::DrawScanlineBGMode7(u32 line)
}
}
if ((DispCnt & 0x1000) && NumSprites)
- InterleaveSprites(0x40000 | (i<<16));
+ DoInterleaveSprites(0x40000 | (i<<16))
}
}
@@ -1674,7 +1641,21 @@ void GPU2D::DrawBG_3D()
}
}
-template<bool mosaic>
+void GetBGVRAM(u32 num, u8*& data, u32& mask)
+{
+ if (num == 0)
+ {
+ data = GPU::VRAMFlat_ABG;
+ mask = 0x7FFFF;
+ }
+ else
+ {
+ data = GPU::VRAMFlat_BBG;
+ mask = 0x1FFFF;
+ }
+}
+
+template<bool mosaic, GPU2D::DrawPixel drawPixel>
void GPU2D::DrawBG_Text(u32 line, u32 bgnum)
{
u16 bgcnt = BGCnt[bgnum];
@@ -1697,17 +1678,20 @@ void GPU2D::DrawBG_Text(u32 line, u32 bgnum)
extpal = (DispCnt & 0x40000000);
if (extpal) extpalslot = ((bgnum<2) && (bgcnt&0x2000)) ? (2+bgnum) : bgnum;
+ u8* bgvram;
+ u32 bgvrammask;
+ GetBGVRAM(Num, bgvram, bgvrammask);
if (Num)
{
- tilesetaddr = 0x06200000 + ((bgcnt & 0x003C) << 12);
- tilemapaddr = 0x06200000 + ((bgcnt & 0x1F00) << 3);
+ tilesetaddr = ((bgcnt & 0x003C) << 12);
+ tilemapaddr = ((bgcnt & 0x1F00) << 3);
pal = (u16*)&GPU::Palette[0x400];
}
else
{
- tilesetaddr = 0x06000000 + ((DispCnt & 0x07000000) >> 8) + ((bgcnt & 0x003C) << 12);
- tilemapaddr = 0x06000000 + ((DispCnt & 0x38000000) >> 11) + ((bgcnt & 0x1F00) << 3);
+ tilesetaddr = ((DispCnt & 0x07000000) >> 8) + ((bgcnt & 0x003C) << 12);
+ tilemapaddr = ((DispCnt & 0x38000000) >> 11) + ((bgcnt & 0x1F00) << 3);
pal = (u16*)&GPU::Palette[0];
}
@@ -1735,7 +1719,7 @@ void GPU2D::DrawBG_Text(u32 line, u32 bgnum)
// preload shit as needed
if ((xoff & 0x7) || mosaic)
{
- curtile = GPU::ReadVRAM_BG<u16>(tilemapaddr + ((xoff & 0xF8) >> 2) + ((xoff & widexmask) << 3));
+ curtile = *(u16*)&bgvram[(tilemapaddr + ((xoff & 0xF8) >> 2) + ((xoff & widexmask) << 3)) & bgvrammask];
if (extpal) curpal = GetBGExtPal(extpalslot, curtile>>12);
else curpal = pal;
@@ -1756,7 +1740,7 @@ void GPU2D::DrawBG_Text(u32 line, u32 bgnum)
(mosaic && ((xpos >> 3) != (lastxpos >> 3))))
{
// load a new tile
- curtile = GPU::ReadVRAM_BG<u16>(tilemapaddr + ((xpos & 0xF8) >> 2) + ((xpos & widexmask) << 3));
+ curtile = *(u16*)&bgvram[(tilemapaddr + ((xpos & 0xF8) >> 2) + ((xpos & widexmask) << 3)) & bgvrammask];
if (extpal) curpal = GetBGExtPal(extpalslot, curtile>>12);
else curpal = pal;
@@ -1771,10 +1755,10 @@ void GPU2D::DrawBG_Text(u32 line, u32 bgnum)
if (WindowMask[i] & (1<<bgnum))
{
u32 tilexoff = (curtile & 0x0400) ? (7-(xpos&0x7)) : (xpos&0x7);
- color = GPU::ReadVRAM_BG<u8>(pixelsaddr + tilexoff);
+ color = bgvram[(pixelsaddr + tilexoff) & bgvrammask];
if (color)
- DrawPixel(&BGOBJLine[i], curpal[color], 0x01000000<<bgnum);
+ drawPixel(&BGOBJLine[i], curpal[color], 0x01000000<<bgnum);
}
xoff++;
@@ -1787,7 +1771,7 @@ void GPU2D::DrawBG_Text(u32 line, u32 bgnum)
// preload shit as needed
if ((xoff & 0x7) || mosaic)
{
- curtile = GPU::ReadVRAM_BG<u16>(tilemapaddr + ((xoff & 0xF8) >> 2) + ((xoff & widexmask) << 3));
+ curtile = *(u16*)&bgvram[((tilemapaddr + ((xoff & 0xF8) >> 2) + ((xoff & widexmask) << 3))) & bgvrammask];
curpal = pal + ((curtile & 0xF000) >> 8);
pixelsaddr = tilesetaddr + ((curtile & 0x03FF) << 5)
+ (((curtile & 0x0800) ? (7-(yoff&0x7)) : (yoff&0x7)) << 2);
@@ -1805,7 +1789,7 @@ void GPU2D::DrawBG_Text(u32 line, u32 bgnum)
(mosaic && ((xpos >> 3) != (lastxpos >> 3))))
{
// load a new tile
- curtile = GPU::ReadVRAM_BG<u16>(tilemapaddr + ((xpos & 0xF8) >> 2) + ((xpos & widexmask) << 3));
+ curtile = *(u16*)&bgvram[(tilemapaddr + ((xpos & 0xF8) >> 2) + ((xpos & widexmask) << 3)) & bgvrammask];
curpal = pal + ((curtile & 0xF000) >> 8);
pixelsaddr = tilesetaddr + ((curtile & 0x03FF) << 5)
+ (((curtile & 0x0800) ? (7-(yoff&0x7)) : (yoff&0x7)) << 2);
@@ -1819,15 +1803,15 @@ void GPU2D::DrawBG_Text(u32 line, u32 bgnum)
u32 tilexoff = (curtile & 0x0400) ? (7-(xpos&0x7)) : (xpos&0x7);
if (tilexoff & 0x1)
{
- color = GPU::ReadVRAM_BG<u8>(pixelsaddr + (tilexoff >> 1)) >> 4;
+ color = bgvram[(pixelsaddr + (tilexoff >> 1)) & bgvrammask] >> 4;
}
else
{
- color = GPU::ReadVRAM_BG<u8>(pixelsaddr + (tilexoff >> 1)) & 0x0F;
+ color = bgvram[(pixelsaddr + (tilexoff >> 1)) & bgvrammask] & 0x0F;
}
if (color)
- DrawPixel(&BGOBJLine[i], curpal[color], 0x01000000<<bgnum);
+ drawPixel(&BGOBJLine[i], curpal[color], 0x01000000<<bgnum);
}
xoff++;
@@ -1835,7 +1819,7 @@ void GPU2D::DrawBG_Text(u32 line, u32 bgnum)
}
}
-template<bool mosaic>
+template<bool mosaic, GPU2D::DrawPixel drawPixel>
void GPU2D::DrawBG_Affine(u32 line, u32 bgnum)
{
u16 bgcnt = BGCnt[bgnum];
@@ -1872,17 +1856,20 @@ void GPU2D::DrawBG_Affine(u32 line, u32 bgnum)
rotY -= (BGMosaicY * rotD);
}
+ u8* bgvram;
+ u32 bgvrammask;
+
if (Num)
{
- tilesetaddr = 0x06200000 + ((bgcnt & 0x003C) << 12);
- tilemapaddr = 0x06200000 + ((bgcnt & 0x1F00) << 3);
+ tilesetaddr = ((bgcnt & 0x003C) << 12);
+ tilemapaddr = ((bgcnt & 0x1F00) << 3);
pal = (u16*)&GPU::Palette[0x400];
}
else
{
- tilesetaddr = 0x06000000 + ((DispCnt & 0x07000000) >> 8) + ((bgcnt & 0x003C) << 12);
- tilemapaddr = 0x06000000 + ((DispCnt & 0x38000000) >> 11) + ((bgcnt & 0x1F00) << 3);
+ tilesetaddr = ((DispCnt & 0x07000000) >> 8) + ((bgcnt & 0x003C) << 12);
+ tilemapaddr = ((DispCnt & 0x38000000) >> 11) + ((bgcnt & 0x1F00) << 3);
pal = (u16*)&GPU::Palette[0];
}
@@ -1911,16 +1898,16 @@ void GPU2D::DrawBG_Affine(u32 line, u32 bgnum)
if ((!((finalX|finalY) & overflowmask)))
{
- curtile = GPU::ReadVRAM_BG<u8>(tilemapaddr + ((((finalY & coordmask) >> 11) << yshift) + ((finalX & coordmask) >> 11)));
+ curtile = bgvram[(tilemapaddr + ((((finalY & coordmask) >> 11) << yshift) + ((finalX & coordmask) >> 11))) & bgvrammask];
// draw pixel
u32 tilexoff = (finalX >> 8) & 0x7;
u32 tileyoff = (finalY >> 8) & 0x7;
- color = GPU::ReadVRAM_BG<u8>(tilesetaddr + (curtile << 6) + (tileyoff << 3) + tilexoff);
+ color = bgvram[(tilesetaddr + (curtile << 6) + (tileyoff << 3) + tilexoff) & bgvrammask];
if (color)
- DrawPixel(&BGOBJLine[i], pal[color], 0x01000000<<bgnum);
+ drawPixel(&BGOBJLine[i], pal[color], 0x01000000<<bgnum);
}
}
@@ -1932,7 +1919,7 @@ void GPU2D::DrawBG_Affine(u32 line, u32 bgnum)
BGYRefInternal[bgnum-2] += rotD;
}
-template<bool mosaic>
+template<bool mosaic, GPU2D::DrawPixel drawPixel>
void GPU2D::DrawBG_Extended(u32 line, u32 bgnum)
{
u16 bgcnt = BGCnt[bgnum];
@@ -1941,6 +1928,10 @@ void GPU2D::DrawBG_Extended(u32 line, u32 bgnum)
u16* pal;
u32 extpal;
+ u8* bgvram;
+ u32 bgvrammask;
+ GetBGVRAM(Num, bgvram, bgvrammask);
+
extpal = (DispCnt & 0x40000000);
s16 rotA = BGRotA[bgnum-2];
@@ -1984,8 +1975,8 @@ void GPU2D::DrawBG_Extended(u32 line, u32 bgnum)
ofymask = ~ymask;
}
- if (Num) tilemapaddr = 0x06200000 + ((bgcnt & 0x1F00) << 6);
- else tilemapaddr = 0x06000000 + ((bgcnt & 0x1F00) << 6);
+ if (Num) tilemapaddr = ((bgcnt & 0x1F00) << 6);
+ else tilemapaddr = ((bgcnt & 0x1F00) << 6);
if (bgcnt & 0x0004)
{
@@ -2012,10 +2003,10 @@ void GPU2D::DrawBG_Extended(u32 line, u32 bgnum)
if (!(finalX & ofxmask) && !(finalY & ofymask))
{
- color = GPU::ReadVRAM_BG<u16>(tilemapaddr + (((((finalY & ymask) >> 8) << yshift) + ((finalX & xmask) >> 8)) << 1));
+ color = *(u16*)&bgvram[(tilemapaddr + (((((finalY & ymask) >> 8) << yshift) + ((finalX & xmask) >> 8)) << 1)) & bgvrammask];
if (color & 0x8000)
- DrawPixel(&BGOBJLine[i], color, 0x01000000<<bgnum);
+ drawPixel(&BGOBJLine[i], color, 0x01000000<<bgnum);
}
}
@@ -2051,10 +2042,10 @@ void GPU2D::DrawBG_Extended(u32 line, u32 bgnum)
if (!(finalX & ofxmask) && !(finalY & ofymask))
{
- color = GPU::ReadVRAM_BG<u8>(tilemapaddr + (((finalY & ymask) >> 8) << yshift) + ((finalX & xmask) >> 8));
+ color = bgvram[(tilemapaddr + (((finalY & ymask) >> 8) << yshift) + ((finalX & xmask) >> 8)) & bgvrammask];
if (color)
- DrawPixel(&BGOBJLine[i], pal[color], 0x01000000<<bgnum);
+ drawPixel(&BGOBJLine[i], pal[color], 0x01000000<<bgnum);
}
}
@@ -2083,15 +2074,15 @@ void GPU2D::DrawBG_Extended(u32 line, u32 bgnum)
if (Num)
{
- tilesetaddr = 0x06200000 + ((bgcnt & 0x003C) << 12);
- tilemapaddr = 0x06200000 + ((bgcnt & 0x1F00) << 3);
+ tilesetaddr = ((bgcnt & 0x003C) << 12);
+ tilemapaddr = ((bgcnt & 0x1F00) << 3);
pal = (u16*)&GPU::Palette[0x400];
}
else
{
- tilesetaddr = 0x06000000 + ((DispCnt & 0x07000000) >> 8) + ((bgcnt & 0x003C) << 12);
- tilemapaddr = 0x06000000 + ((DispCnt & 0x38000000) >> 11) + ((bgcnt & 0x1F00) << 3);
+ tilesetaddr = ((DispCnt & 0x07000000) >> 8) + ((bgcnt & 0x003C) << 12);
+ tilemapaddr = ((DispCnt & 0x38000000) >> 11) + ((bgcnt & 0x1F00) << 3);
pal = (u16*)&GPU::Palette[0];
}
@@ -2121,7 +2112,7 @@ void GPU2D::DrawBG_Extended(u32 line, u32 bgnum)
if ((!((finalX|finalY) & overflowmask)))
{
- curtile = GPU::ReadVRAM_BG<u16>(tilemapaddr + (((((finalY & coordmask) >> 11) << yshift) + ((finalX & coordmask) >> 11)) << 1));
+ curtile = *(u16*)&bgvram[(tilemapaddr + (((((finalY & coordmask) >> 11) << yshift) + ((finalX & coordmask) >> 11)) << 1)) & bgvrammask];
if (extpal) curpal = GetBGExtPal(bgnum, curtile>>12);
else curpal = pal;
@@ -2133,10 +2124,10 @@ void GPU2D::DrawBG_Extended(u32 line, u32 bgnum)
if (curtile & 0x0400) tilexoff = 7-tilexoff;
if (curtile & 0x0800) tileyoff = 7-tileyoff;
- color = GPU::ReadVRAM_BG<u8>(tilesetaddr + ((curtile & 0x03FF) << 6) + (tileyoff << 3) + tilexoff);
+ color = bgvram[(tilesetaddr + ((curtile & 0x03FF) << 6) + (tileyoff << 3) + tilexoff) & bgvrammask];
if (color)
- DrawPixel(&BGOBJLine[i], curpal[color], 0x01000000<<bgnum);
+ drawPixel(&BGOBJLine[i], curpal[color], 0x01000000<<bgnum);
}
}
@@ -2149,7 +2140,7 @@ void GPU2D::DrawBG_Extended(u32 line, u32 bgnum)
BGYRefInternal[bgnum-2] += rotD;
}
-template<bool mosaic>
+template<bool mosaic, GPU2D::DrawPixel drawPixel>
void GPU2D::DrawBG_Large(u32 line) // BG is always BG2
{
u16 bgcnt = BGCnt[2];
@@ -2199,8 +2190,9 @@ void GPU2D::DrawBG_Large(u32 line) // BG is always BG2
rotY -= (BGMosaicY * rotD);
}
- if (Num) tilemapaddr = 0x06200000;
- else tilemapaddr = 0x06000000;
+ u8* bgvram;
+ u32 bgvrammask;
+ GetBGVRAM(Num, bgvram, bgvrammask);
// 256-color bitmap
@@ -2228,10 +2220,10 @@ void GPU2D::DrawBG_Large(u32 line) // BG is always BG2
if (!(finalX & ofxmask) && !(finalY & ofymask))
{
- color = GPU::ReadVRAM_BG<u8>(tilemapaddr + (((finalY & ymask) >> 8) << yshift) + ((finalX & xmask) >> 8));
+ color = bgvram[(tilemapaddr + (((finalY & ymask) >> 8) << yshift) + ((finalX & xmask) >> 8)) & bgvrammask];
if (color)
- DrawPixel(&BGOBJLine[i], pal[color], 0x01000000<<2);
+ drawPixel(&BGOBJLine[i], pal[color], 0x01000000<<2);
}
}
@@ -2274,6 +2266,7 @@ void GPU2D::ApplySpriteMosaicX()
}
}
+template <GPU2D::DrawPixel drawPixel>
void GPU2D::InterleaveSprites(u32 prio)
{
u16* pal = (u16*)&GPU::Palette[Num ? 0x600 : 0x200];
@@ -2297,7 +2290,7 @@ void GPU2D::InterleaveSprites(u32 prio)
else
color = extpal[pixel & 0xFFF];
- DrawPixel(&BGOBJLine[i], color, pixel & 0xFF000000);
+ drawPixel(&BGOBJLine[i], color, pixel & 0xFF000000);
}
}
else
@@ -2317,11 +2310,25 @@ void GPU2D::InterleaveSprites(u32 prio)
else
color = pal[pixel & 0xFF];
- DrawPixel(&BGOBJLine[i], color, pixel & 0xFF000000);
+ drawPixel(&BGOBJLine[i], color, pixel & 0xFF000000);
}
}
}
+void GetOBJVRAM(u32 num, u8*& data, u32& mask)
+{
+ if (num == 0)
+ {
+ data = GPU::VRAMFlat_AOBJ;
+ mask = 0x3FFFF;
+ }
+ else
+ {
+ data = GPU::VRAMFlat_BOBJ;
+ mask = 0x1FFFF;
+ }
+}
+
#define DoDrawSprite(type, ...) \
if (iswin) \
{ \
@@ -2346,6 +2353,17 @@ void GPU2D::DrawSprites(u32 line)
OBJMosaicYCount = 0;
}
+ if (Num == 0)
+ {
+ auto objDirty = GPU::VRAMDirty_AOBJ.DeriveState(GPU::VRAMMap_AOBJ);
+ GPU::MakeVRAMFlat_AOBJCoherent(objDirty);
+ }
+ else
+ {
+ auto objDirty = GPU::VRAMDirty_BOBJ.DeriveState(GPU::VRAMMap_BOBJ);
+ GPU::MakeVRAMFlat_BOBJCoherent(objDirty);
+ }
+
NumSprites = 0;
memset(OBJLine, 0, 256*4);
memset(OBJWindow, 0, 256);
@@ -2458,6 +2476,10 @@ void GPU2D::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u32 wi
u32 ytilefactor;
+ u8* objvram;
+ u32 objvrammask;
+ GetOBJVRAM(Num, objvram, objvrammask);
+
s32 centerX = boundwidth >> 1;
s32 centerY = boundheight >> 1;
@@ -2501,6 +2523,7 @@ void GPU2D::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u32 wi
pixelattr |= (0xC0000000 | (alpha << 24));
+ u32 pixelsaddr;
if (DispCnt & 0x40)
{
if (DispCnt & 0x20)
@@ -2512,7 +2535,7 @@ void GPU2D::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u32 wi
}
else
{
- tilenum <<= (7 + ((DispCnt >> 22) & 0x1));
+ pixelsaddr = tilenum << (7 + ((DispCnt >> 22) & 0x1));
ytilefactor = ((width >> 8) * 2);
}
}
@@ -2520,23 +2543,21 @@ void GPU2D::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u32 wi
{
if (DispCnt & 0x20)
{
- tilenum = ((tilenum & 0x01F) << 4) + ((tilenum & 0x3E0) << 7);
+ pixelsaddr = ((tilenum & 0x01F) << 4) + ((tilenum & 0x3E0) << 7);
ytilefactor = (256 * 2);
}
else
{
- tilenum = ((tilenum & 0x00F) << 4) + ((tilenum & 0x3F0) << 7);
+ pixelsaddr = ((tilenum & 0x00F) << 4) + ((tilenum & 0x3F0) << 7);
ytilefactor = (128 * 2);
}
}
- u32 pixelsaddr = (Num ? 0x06600000 : 0x06400000) + tilenum;
-
for (; xoff < boundwidth;)
{
if ((u32)rotX < width && (u32)rotY < height)
{
- color = GPU::ReadVRAM_OBJ<u16>(pixelsaddr + ((rotY >> 8) * ytilefactor) + ((rotX >> 8) << 1));
+ color = *(u16*)&objvram[(pixelsaddr + ((rotY >> 8) * ytilefactor) + ((rotX >> 8) << 1)) & objvrammask];
if (color & 0x8000)
{
@@ -2561,9 +2582,10 @@ void GPU2D::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u32 wi
}
else
{
+ u32 pixelsaddr = tilenum;
if (DispCnt & 0x10)
{
- tilenum <<= ((DispCnt >> 20) & 0x3);
+ pixelsaddr <<= ((DispCnt >> 20) & 0x3);
ytilefactor = (width >> 11) << ((attrib[0] & 0x2000) ? 1:0);
}
else
@@ -2574,12 +2596,12 @@ void GPU2D::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u32 wi
if (spritemode == 1) pixelattr |= 0x80000000;
else pixelattr |= 0x10000000;
+ ytilefactor <<= 5;
+ pixelsaddr <<= 5;
+
if (attrib[0] & 0x2000)
{
// 256-color
- tilenum <<= 5;
- ytilefactor <<= 5;
- u32 pixelsaddr = (Num ? 0x06600000 : 0x06400000) + tilenum;
if (!window)
{
@@ -2593,7 +2615,7 @@ void GPU2D::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u32 wi
{
if ((u32)rotX < width && (u32)rotY < height)
{
- color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr + ((rotY>>11)*ytilefactor) + ((rotY&0x700)>>5) + ((rotX>>11)*64) + ((rotX&0x700)>>8));
+ color = objvram[(pixelsaddr + ((rotY>>11)*ytilefactor) + ((rotY&0x700)>>5) + ((rotX>>11)*64) + ((rotX&0x700)>>8)) & objvrammask];
if (color)
{
@@ -2619,10 +2641,6 @@ void GPU2D::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u32 wi
else
{
// 16-color
- tilenum <<= 5;
- ytilefactor <<= 5;
- u32 pixelsaddr = (Num ? 0x06600000 : 0x06400000) + tilenum;
-
if (!window)
{
pixelattr |= 0x1000;
@@ -2633,7 +2651,7 @@ void GPU2D::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u32 wi
{
if ((u32)rotX < width && (u32)rotY < height)
{
- color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr + ((rotY>>11)*ytilefactor) + ((rotY&0x700)>>6) + ((rotX>>11)*32) + ((rotX&0x700)>>9));
+ color = objvram[(pixelsaddr + ((rotY>>11)*ytilefactor) + ((rotY&0x700)>>6) + ((rotX>>11)*32) + ((rotX&0x700)>>9)) & objvrammask];
if (rotX & 0x100)
color >>= 4;
else
@@ -2681,6 +2699,10 @@ void GPU2D::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 ypos
pixelattr |= 0x100000;
}
+ u8* objvram;
+ u32 objvrammask;
+ GetOBJVRAM(Num, objvram, objvrammask);
+
// yflip
if (attrib[1] & 0x2000)
ypos = height-1 - ypos;
@@ -2711,6 +2733,7 @@ void GPU2D::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 ypos
pixelattr |= (0xC0000000 | (alpha << 24));
+ u32 pixelsaddr = tilenum;
if (DispCnt & 0x40)
{
if (DispCnt & 0x20)
@@ -2722,25 +2745,24 @@ void GPU2D::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 ypos
}
else
{
- tilenum <<= (7 + ((DispCnt >> 22) & 0x1));
- tilenum += (ypos * width * 2);
+ pixelsaddr <<= (7 + ((DispCnt >> 22) & 0x1));
+ pixelsaddr += (ypos * width * 2);
}
}
else
{
if (DispCnt & 0x20)
{
- tilenum = ((tilenum & 0x01F) << 4) + ((tilenum & 0x3E0) << 7);
- tilenum += (ypos * 256 * 2);
+ pixelsaddr = ((tilenum & 0x01F) << 4) + ((tilenum & 0x3E0) << 7);
+ pixelsaddr += (ypos * 256 * 2);
}
else
{
- tilenum = ((tilenum & 0x00F) << 4) + ((tilenum & 0x3F0) << 7);
- tilenum += (ypos * 128 * 2);
+ pixelsaddr = ((tilenum & 0x00F) << 4) + ((tilenum & 0x3F0) << 7);
+ pixelsaddr += (ypos * 128 * 2);
}
}
- u32 pixelsaddr = (Num ? 0x06600000 : 0x06400000) + tilenum;
s32 pixelstride;
if (attrib[1] & 0x1000) // xflip
@@ -2757,7 +2779,7 @@ void GPU2D::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 ypos
for (; xoff < xend;)
{
- color = GPU::ReadVRAM_OBJ<u16>(pixelsaddr);
+ color = *(u16*)&objvram[pixelsaddr & objvrammask];
pixelsaddr += pixelstride;
@@ -2781,14 +2803,15 @@ void GPU2D::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 ypos
}
else
{
+ u32 pixelsaddr = tilenum;
if (DispCnt & 0x10)
{
- tilenum <<= ((DispCnt >> 20) & 0x3);
- tilenum += ((ypos >> 3) * (width >> 3)) << ((attrib[0] & 0x2000) ? 1:0);
+ pixelsaddr <<= ((DispCnt >> 20) & 0x3);
+ pixelsaddr += ((ypos >> 3) * (width >> 3)) << ((attrib[0] & 0x2000) ? 1:0);
}
else
{
- tilenum += ((ypos >> 3) * 0x20);
+ pixelsaddr += ((ypos >> 3) * 0x20);
}
if (spritemode == 1) pixelattr |= 0x80000000;
@@ -2797,8 +2820,7 @@ void GPU2D::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 ypos
if (attrib[0] & 0x2000)
{
// 256-color
- tilenum <<= 5;
- u32 pixelsaddr = (Num ? 0x06600000 : 0x06400000) + tilenum;
+ pixelsaddr <<= 5;
pixelsaddr += ((ypos & 0x7) << 3);
s32 pixelstride;
@@ -2827,7 +2849,7 @@ void GPU2D::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 ypos
for (; xoff < xend;)
{
- color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr);
+ color = objvram[pixelsaddr];
pixelsaddr += pixelstride;
@@ -2853,8 +2875,7 @@ void GPU2D::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 ypos
else
{
// 16-color
- tilenum <<= 5;
- u32 pixelsaddr = (Num ? 0x06600000 : 0x06400000) + tilenum;
+ pixelsaddr <<= 5;
pixelsaddr += ((ypos & 0x7) << 2);
s32 pixelstride;
@@ -2886,13 +2907,13 @@ void GPU2D::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 ypos
{
if (attrib[1] & 0x1000)
{
- if (xoff & 0x1) { color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) & 0x0F; pixelsaddr--; }
- else color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) >> 4;
+ if (xoff & 0x1) { color = objvram[pixelsaddr & objvrammask] & 0x0F; pixelsaddr--; }
+ else color = objvram[pixelsaddr & objvrammask] >> 4;
}
else
{
- if (xoff & 0x1) { color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) >> 4; pixelsaddr++; }
- else color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) & 0x0F;
+ if (xoff & 0x1) { color = objvram[pixelsaddr & objvrammask] >> 4; pixelsaddr++; }
+ else color = objvram[pixelsaddr & objvrammask] & 0x0F;
}
if (color)