GPU2D: delay palette lookup for sprites

This commit is contained in:
Arisotura 2019-09-05 11:42:08 +02:00
parent e8f4735c7f
commit 0010e296bd
2 changed files with 80 additions and 51 deletions

View File

@ -1193,33 +1193,33 @@ u16* GPU2D::GetBGExtPal(u32 slot, u32 pal)
return dst;
}
u16* GPU2D::GetOBJExtPal(u32 pal)
u16* GPU2D::GetOBJExtPal()
{
u16* dst = &OBJExtPalCache[pal << 8];
u16* dst = OBJExtPalCache;
if (!(OBJExtPalStatus & (1<<pal)))
if (!OBJExtPalStatus)
{
if (Num)
{
if (GPU::VRAMMap_BOBJExtPal & (1<<8))
memcpy(dst, &GPU::VRAM_I[(pal << 9)], 256*2);
memcpy(dst, &GPU::VRAM_I[0], 16*256*2);
else
memset(dst, 0, 256*2);
memset(dst, 0, 16*256*2);
}
else
{
memset(dst, 0, 256*2);
memset(dst, 0, 16*256*2);
if (GPU::VRAMMap_AOBJExtPal & (1<<5))
for (int i = 0; i < 256; i+=2)
*(u32*)&dst[i] |= *(u32*)&GPU::VRAM_F[(pal << 9) + (i << 1)];
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 < 256; i+=2)
*(u32*)&dst[i] |= *(u32*)&GPU::VRAM_G[(pal << 9) + (i << 1)];
for (int i = 0; i < 16*256; i+=2)
*(u32*)&dst[i] |= *(u32*)&GPU::VRAM_G[i << 1];
}
OBJExtPalStatus |= (1<<pal);
OBJExtPalStatus = 1;
}
return dst;
@ -1329,7 +1329,7 @@ void GPU2D::DrawScanlineBGMode(u32 line)
}
}
if ((DispCnt & 0x1000) && NumSprites)
InterleaveSprites(0x8000 | (i<<16));
InterleaveSprites(0x40000 | (i<<16));
}
}
@ -1353,7 +1353,7 @@ void GPU2D::DrawScanlineBGMode6(u32 line)
}
}
if ((DispCnt & 0x1000) && NumSprites)
InterleaveSprites(0x8000 | (i<<16));
InterleaveSprites(0x40000 | (i<<16));
}
}
@ -1381,7 +1381,7 @@ void GPU2D::DrawScanlineBGMode7(u32 line)
}
}
if ((DispCnt & 0x1000) && NumSprites)
InterleaveSprites(0x8000 | (i<<16));
InterleaveSprites(0x40000 | (i<<16));
}
}
@ -2172,11 +2172,48 @@ void GPU2D::DrawBG_Large(u32 line) // BG is always BG2
void GPU2D::InterleaveSprites(u32 prio)
{
for (u32 i = 0; i < 256; i++)
u16* pal = (u16*)&GPU::Palette[Num ? 0x600 : 0x200];
if (DispCnt & 0x80000000)
{
if (((OBJLine[i] & 0xF8000) == prio) && (WindowMask[i] & 0x10))
u16* extpal = GetOBJExtPal();
for (u32 i = 0; i < 256; i++)
{
DrawPixel(&BGOBJLine[i], OBJLine[i] & 0x7FFF, OBJLine[i] & 0xFF000000);
if ((OBJLine[i] & 0x70000) != prio) continue;
if (!(WindowMask[i] & 0x10)) continue;
u16 color;
u32 pixel = OBJLine[i];
if (pixel & 0x8000)
color = pixel & 0x7FFF;
else if (pixel & 0x1000)
color = pal[pixel & 0xFF];
else
color = extpal[pixel & 0xFFF];
DrawPixel(&BGOBJLine[i], color, pixel & 0xFF000000);
}
}
else
{
// optimized no-extpal version
for (u32 i = 0; i < 256; i++)
{
if ((OBJLine[i] & 0x70000) != prio) continue;
if (!(WindowMask[i] & 0x10)) continue;
u16 color;
u32 pixel = OBJLine[i];
if (pixel & 0x8000)
color = pixel & 0x7FFF;
else
color = pal[pixel & 0xFF];
DrawPixel(&BGOBJLine[i], color, pixel & 0xFF000000);
}
}
}
@ -2284,7 +2321,7 @@ void GPU2D::DrawSprites(u32 line)
template<bool window>
void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos)
{
u32 prio = ((attrib[2] & 0x0C00) << 6) | 0x8000;
u32 pixelattr = ((attrib[2] & 0x0C00) << 6) | 0x40000;
u32 tilenum = attrib[2] & 0x03FF;
u32 spritemode = window ? 0 : ((attrib[0] >> 10) & 0x3);
u32 xmos = 0, xmossize = 0;
@ -2337,7 +2374,7 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
if (!alpha) return;
alpha++;
prio |= (0xC0000000 | (alpha << 24));
pixelattr |= (0xC0000000 | (alpha << 24));
if (DispCnt & 0x40)
{
@ -2387,7 +2424,7 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
if (color & 0x8000)
{
if (window) OBJWindow[xpos] = 1;
else OBJLine[xpos] = color | prio;
else OBJLine[xpos] = color | pixelattr;
}
}
else
@ -2414,8 +2451,8 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
ytilefactor = 0x20;
}
if (spritemode == 1) prio |= 0x80000000;
else prio |= 0x10000000;
if (spritemode == 1) pixelattr |= 0x80000000;
else pixelattr |= 0x10000000;
if (attrib[0] & 0x2000)
{
@ -2424,13 +2461,9 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
ytilefactor <<= 5;
u32 pixelsaddr = (Num ? 0x06600000 : 0x06400000) + tilenum;
u32 extpal = (DispCnt & 0x80000000);
u16* pal;
if (!window)
{
if (extpal) pal = GetOBJExtPal(attrib[2] >> 12);
else pal = (u16*)&GPU::Palette[Num ? 0x600 : 0x200];
if (!(DispCnt & 0x80000000)) pixelattr |= 0x1000;
}
if (xmos && !(attrib[0]&0x0200))
@ -2451,7 +2484,7 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
if (color)
{
if (window) OBJWindow[xpos] = 1;
else OBJLine[xpos] = pal[color] | prio;
else OBJLine[xpos] = color | pixelattr;
}
}
else
@ -2473,11 +2506,10 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
ytilefactor <<= 5;
u32 pixelsaddr = (Num ? 0x06600000 : 0x06400000) + tilenum;
u16* pal;
if (!window)
{
pal = (u16*)&GPU::Palette[Num ? 0x600 : 0x200];
pal += (attrib[2] & 0xF000) >> 8;
pixelattr |= 0x1000;
pixelattr |= ((attrib[2] & 0xF000) >> 8);
}
if (xmos && !(attrib[0]&0x0200))
@ -2509,7 +2541,7 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
if (color)
{
if (window) OBJWindow[xpos] = 1;
else OBJLine[xpos] = pal[color] | prio;
else OBJLine[xpos] = color | pixelattr;
}
}
else
@ -2530,7 +2562,7 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
template<bool window>
void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos)
{
u32 prio = ((attrib[2] & 0x0C00) << 6) | 0x8000;
u32 pixelattr = ((attrib[2] & 0x0C00) << 6) | 0x40000;
u32 tilenum = attrib[2] & 0x03FF;
u32 spritemode = window ? 0 : ((attrib[0] >> 10) & 0x3);
u32 xmos = 0, xmossize = 0;
@ -2572,7 +2604,7 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos)
if (!alpha) return;
alpha++;
prio |= (0xC0000000 | (alpha << 24));
pixelattr |= (0xC0000000 | (alpha << 24));
if (DispCnt & 0x40)
{
@ -2625,7 +2657,7 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos)
if (color & 0x8000)
{
if (window) OBJWindow[xpos] = 1;
else OBJLine[xpos] = color | prio;
else OBJLine[xpos] = color | pixelattr;
}
xoff++;
@ -2652,7 +2684,7 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos)
if (color & 0x8000)
{
if (window) OBJWindow[xpos] = 1;
else OBJLine[xpos] = color | prio;
else OBJLine[xpos] = color | pixelattr;
}
xoff++;
@ -2672,8 +2704,8 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos)
tilenum += ((ypos >> 3) * 0x20);
}
if (spritemode == 1) prio |= 0x80000000;
else prio |= 0x10000000;
if (spritemode == 1) pixelattr |= 0x80000000;
else pixelattr |= 0x10000000;
if (attrib[0] & 0x2000)
{
@ -2682,13 +2714,9 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos)
u32 pixelsaddr = (Num ? 0x06600000 : 0x06400000) + tilenum;
pixelsaddr += ((ypos & 0x7) << 3);
u32 extpal = (DispCnt & 0x80000000);
u16* pal;
if (!window)
{
if (extpal) pal = GetOBJExtPal(attrib[2] >> 12);
else pal = (u16*)&GPU::Palette[Num ? 0x600 : 0x200];
if (!(DispCnt & 0x80000000)) pixelattr |= 0x1000;
}
if (attrib[1] & 0x1000) // xflip. TODO: do better? oh well for now this works
@ -2712,7 +2740,7 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos)
if (color)
{
if (window) OBJWindow[xpos] = 1;
else OBJLine[xpos] = pal[color] | prio;
else OBJLine[xpos] = color | pixelattr;
}
xoff++;
@ -2741,7 +2769,7 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos)
if (color)
{
if (window) OBJWindow[xpos] = 1;
else OBJLine[xpos] = pal[color] | prio;
else OBJLine[xpos] = color | pixelattr;
}
xoff++;
@ -2757,13 +2785,14 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos)
u32 pixelsaddr = (Num ? 0x06600000 : 0x06400000) + tilenum;
pixelsaddr += ((ypos & 0x7) << 2);
u16* pal;
if (!window)
{
pal = (u16*)&GPU::Palette[Num ? 0x600 : 0x200];
pal += (attrib[2] & 0xF000) >> 8;
pixelattr |= 0x1000;
pixelattr |= ((attrib[2] & 0xF000) >> 8);
}
// TODO: optimize VRAM access!!
if (attrib[1] & 0x1000) // xflip. TODO: do better? oh well for now this works
{
pixelsaddr += (((width-1 - xoff) & wmask) << 2);
@ -2790,7 +2819,7 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos)
if (color)
{
if (window) OBJWindow[xpos] = 1;
else OBJLine[xpos] = pal[color] | prio;
else OBJLine[xpos] = color | pixelattr;
}
xoff++;
@ -2824,7 +2853,7 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos)
if (color)
{
if (window) OBJWindow[xpos] = 1;
else OBJLine[xpos] = pal[color] | prio;
else OBJLine[xpos] = color | pixelattr;
}
xoff++;

View File

@ -63,7 +63,7 @@ public:
void OBJExtPalDirty();
u16* GetBGExtPal(u32 slot, u32 pal);
u16* GetOBJExtPal(u32 pal);
u16* GetOBJExtPal();
private:
u32 Num;