diff options
-rw-r--r-- | src/GPU2D.cpp | 129 | ||||
-rw-r--r-- | src/GPU2D.h | 2 |
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; |