GPU2D: delay palette lookup for sprites
This commit is contained in:
parent
e8f4735c7f
commit
0010e296bd
129
src/GPU2D.cpp
129
src/GPU2D.cpp
|
@ -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++;
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
void OBJExtPalDirty();
|
||||
|
||||
u16* GetBGExtPal(u32 slot, u32 pal);
|
||||
u16* GetOBJExtPal(u32 pal);
|
||||
u16* GetOBJExtPal();
|
||||
|
||||
private:
|
||||
u32 Num;
|
||||
|
|
Loading…
Reference in New Issue