aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/GPU2D.cpp129
-rw-r--r--src/GPU2D.h2
2 files changed, 80 insertions, 51 deletions
diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp
index 288ee58..ef9be41 100644
--- a/src/GPU2D.cpp
+++ b/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)
+ {
+ u16* extpal = GetOBJExtPal();
+
+ 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 if (pixel & 0x1000)
+ color = pal[pixel & 0xFF];
+ else
+ color = extpal[pixel & 0xFFF];
+
+ DrawPixel(&BGOBJLine[i], color, pixel & 0xFF000000);
+ }
+ }
+ else
{
- if (((OBJLine[i] & 0xF8000) == prio) && (WindowMask[i] & 0x10))
+ // optimized no-extpal version
+
+ 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
+ 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++;
diff --git a/src/GPU2D.h b/src/GPU2D.h
index 6ad9783..9184215 100644
--- a/src/GPU2D.h
+++ b/src/GPU2D.h
@@ -63,7 +63,7 @@ public:
void OBJExtPalDirty();
u16* GetBGExtPal(u32 slot, u32 pal);
- u16* GetOBJExtPal(u32 pal);
+ u16* GetOBJExtPal();
private:
u32 Num;