2D: mosaic
sprites might be mosaiced wrong, esp. rotscaled ones. blrgdfgdf
This commit is contained in:
parent
e6f5507c9e
commit
82e42c5be7
399
src/GPU2D.cpp
399
src/GPU2D.cpp
|
@ -73,6 +73,8 @@
|
|||
//
|
||||
// mosaic:
|
||||
// * mosaic grid starts at 0,0 regardless of the BG/sprite position
|
||||
// * when changing it midframe: new X setting is applied immediately, new Y setting is applied only
|
||||
// after the end of the current mosaic row
|
||||
|
||||
// TODO: find which parts of DISPCNT are latched. for example, not possible to change video mode midframe.
|
||||
|
||||
|
@ -109,6 +111,10 @@ void GPU2D::Reset()
|
|||
BGMosaicSize[1] = 0;
|
||||
OBJMosaicSize[0] = 0;
|
||||
OBJMosaicSize[1] = 0;
|
||||
BGMosaicY = 0;
|
||||
BGMosaicYMax = 0;
|
||||
OBJMosaicY = 0;
|
||||
OBJMosaicYMax = 0;
|
||||
|
||||
BlendCnt = 0;
|
||||
EVA = 16;
|
||||
|
@ -624,6 +630,11 @@ void GPU2D::VBlankEnd()
|
|||
BGXRefInternal[1] = BGXRef[1];
|
||||
BGYRefInternal[0] = BGYRef[0];
|
||||
BGYRefInternal[1] = BGYRef[1];
|
||||
|
||||
BGMosaicY = 0;
|
||||
BGMosaicYMax = BGMosaicSize[1];
|
||||
OBJMosaicY = 0;
|
||||
OBJMosaicYMax = OBJMosaicSize[1];
|
||||
}
|
||||
|
||||
|
||||
|
@ -1179,6 +1190,22 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (BGMosaicY >= BGMosaicYMax)
|
||||
{
|
||||
BGMosaicY = 0;
|
||||
BGMosaicYMax = BGMosaicSize[1];
|
||||
}
|
||||
else
|
||||
BGMosaicY++;
|
||||
|
||||
if (OBJMosaicY >= OBJMosaicYMax)
|
||||
{
|
||||
OBJMosaicY = 0;
|
||||
OBJMosaicYMax = OBJMosaicSize[1];
|
||||
}
|
||||
else
|
||||
OBJMosaicY++;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1230,6 +1257,7 @@ void GPU2D::DrawBG_Text(u32 line, u32* dst, u32 bgnum)
|
|||
{
|
||||
u8* windowmask = (u8*)&dst[256*2];
|
||||
u16 bgcnt = BGCnt[bgnum];
|
||||
u32 xmos = 0, xmossize = 0;
|
||||
|
||||
u32 tilesetaddr, tilemapaddr;
|
||||
u16* pal;
|
||||
|
@ -1238,6 +1266,13 @@ void GPU2D::DrawBG_Text(u32 line, u32* dst, u32 bgnum)
|
|||
u16 xoff = BGXPos[bgnum];
|
||||
u16 yoff = BGYPos[bgnum] + line;
|
||||
|
||||
if (bgcnt & 0x0040)
|
||||
{
|
||||
// mosaic
|
||||
yoff -= BGMosaicY;
|
||||
xmossize = BGMosaicSize[0];
|
||||
}
|
||||
|
||||
u32 widexmask = (bgcnt & 0x4000) ? 0x100 : 0;
|
||||
|
||||
extpal = (DispCnt & 0x40000000);
|
||||
|
@ -1271,6 +1306,7 @@ void GPU2D::DrawBG_Text(u32 line, u32* dst, u32 bgnum)
|
|||
u16 curtile;
|
||||
u16* curpal;
|
||||
u32 pixelsaddr;
|
||||
u8 color;
|
||||
|
||||
if (bgcnt & 0x0080)
|
||||
{
|
||||
|
@ -1306,9 +1342,14 @@ void GPU2D::DrawBG_Text(u32 line, u32* dst, u32 bgnum)
|
|||
// draw pixel
|
||||
if (windowmask[i] & (1<<bgnum))
|
||||
{
|
||||
u8 color;
|
||||
u32 tilexoff = (curtile & 0x0400) ? (7-(xoff&0x7)) : (xoff&0x7);
|
||||
color = GPU::ReadVRAM_BG<u8>(pixelsaddr + tilexoff);
|
||||
if (xmos == 0)
|
||||
{
|
||||
u32 tilexoff = (curtile & 0x0400) ? (7-(xoff&0x7)) : (xoff&0x7);
|
||||
color = GPU::ReadVRAM_BG<u8>(pixelsaddr + tilexoff);
|
||||
xmos = xmossize;
|
||||
}
|
||||
else
|
||||
xmos--;
|
||||
|
||||
if (color)
|
||||
DrawPixel(&dst[i], curpal[color], 0x01000000<<bgnum);
|
||||
|
@ -1346,16 +1387,21 @@ void GPU2D::DrawBG_Text(u32 line, u32* dst, u32 bgnum)
|
|||
// TODO: optimize VRAM access
|
||||
if (windowmask[i] & (1<<bgnum))
|
||||
{
|
||||
u8 color;
|
||||
u32 tilexoff = (curtile & 0x0400) ? (7-(xoff&0x7)) : (xoff&0x7);
|
||||
if (tilexoff & 0x1)
|
||||
if (xmos == 0)
|
||||
{
|
||||
color = GPU::ReadVRAM_BG<u8>(pixelsaddr + (tilexoff >> 1)) >> 4;
|
||||
u32 tilexoff = (curtile & 0x0400) ? (7-(xoff&0x7)) : (xoff&0x7);
|
||||
if (tilexoff & 0x1)
|
||||
{
|
||||
color = GPU::ReadVRAM_BG<u8>(pixelsaddr + (tilexoff >> 1)) >> 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = GPU::ReadVRAM_BG<u8>(pixelsaddr + (tilexoff >> 1)) & 0x0F;
|
||||
}
|
||||
xmos = xmossize;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = GPU::ReadVRAM_BG<u8>(pixelsaddr + (tilexoff >> 1)) & 0x0F;
|
||||
}
|
||||
xmos--;
|
||||
|
||||
if (color)
|
||||
DrawPixel(&dst[i], curpal[color], 0x01000000<<bgnum);
|
||||
|
@ -1370,6 +1416,7 @@ void GPU2D::DrawBG_Affine(u32 line, u32* dst, u32 bgnum)
|
|||
{
|
||||
u8* windowmask = (u8*)&dst[256*2];
|
||||
u16 bgcnt = BGCnt[bgnum];
|
||||
u32 xmos = 0, xmossize = 0;
|
||||
|
||||
u32 tilesetaddr, tilemapaddr;
|
||||
u16* pal;
|
||||
|
@ -1396,6 +1443,14 @@ void GPU2D::DrawBG_Affine(u32 line, u32* dst, u32 bgnum)
|
|||
s32 rotX = BGXRefInternal[bgnum-2];
|
||||
s32 rotY = BGYRefInternal[bgnum-2];
|
||||
|
||||
if (bgcnt & 0x0040)
|
||||
{
|
||||
// mosaic
|
||||
rotX -= (BGMosaicY * rotB);
|
||||
rotY -= (BGMosaicY * rotD);
|
||||
xmossize = BGMosaicSize[0];
|
||||
}
|
||||
|
||||
if (Num)
|
||||
{
|
||||
tilesetaddr = 0x06200000 + ((bgcnt & 0x003C) << 12);
|
||||
|
@ -1412,24 +1467,37 @@ void GPU2D::DrawBG_Affine(u32 line, u32* dst, u32 bgnum)
|
|||
}
|
||||
|
||||
u16 curtile;
|
||||
u8 color;
|
||||
|
||||
yshift -= 3;
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
if ((!((rotX|rotY) & overflowmask)) && (windowmask[i] & (1<<bgnum)))
|
||||
if (windowmask[i] & (1<<bgnum))
|
||||
{
|
||||
curtile = GPU::ReadVRAM_BG<u8>(tilemapaddr + ((((rotY & coordmask) >> 11) << yshift) + ((rotX & coordmask) >> 11)));
|
||||
if (xmos > 0)
|
||||
{
|
||||
if (color)
|
||||
DrawPixel(&dst[i], pal[color], 0x01000000<<bgnum);
|
||||
|
||||
// draw pixel
|
||||
u8 color;
|
||||
u32 tilexoff = (rotX >> 8) & 0x7;
|
||||
u32 tileyoff = (rotY >> 8) & 0x7;
|
||||
xmos--;
|
||||
}
|
||||
else
|
||||
if ((!((rotX|rotY) & overflowmask)))
|
||||
{
|
||||
curtile = GPU::ReadVRAM_BG<u8>(tilemapaddr + ((((rotY & coordmask) >> 11) << yshift) + ((rotX & coordmask) >> 11)));
|
||||
|
||||
color = GPU::ReadVRAM_BG<u8>(tilesetaddr + (curtile << 6) + (tileyoff << 3) + tilexoff);
|
||||
// draw pixel
|
||||
u32 tilexoff = (rotX >> 8) & 0x7;
|
||||
u32 tileyoff = (rotY >> 8) & 0x7;
|
||||
|
||||
if (color)
|
||||
DrawPixel(&dst[i], pal[color], 0x01000000<<bgnum);
|
||||
color = GPU::ReadVRAM_BG<u8>(tilesetaddr + (curtile << 6) + (tileyoff << 3) + tilexoff);
|
||||
|
||||
if (color)
|
||||
DrawPixel(&dst[i], pal[color], 0x01000000<<bgnum);
|
||||
|
||||
xmos = xmossize;
|
||||
}
|
||||
}
|
||||
|
||||
rotX += rotA;
|
||||
|
@ -1444,6 +1512,7 @@ void GPU2D::DrawBG_Extended(u32 line, u32* dst, u32 bgnum)
|
|||
{
|
||||
u8* windowmask = (u8*)&dst[256*2];
|
||||
u16 bgcnt = BGCnt[bgnum];
|
||||
u32 xmos = 0, xmossize = 0;
|
||||
|
||||
u32 tilesetaddr, tilemapaddr;
|
||||
u16* pal;
|
||||
|
@ -1459,6 +1528,14 @@ void GPU2D::DrawBG_Extended(u32 line, u32* dst, u32 bgnum)
|
|||
s32 rotX = BGXRefInternal[bgnum-2];
|
||||
s32 rotY = BGYRefInternal[bgnum-2];
|
||||
|
||||
if (bgcnt & 0x0040)
|
||||
{
|
||||
// mosaic
|
||||
rotX -= (BGMosaicY * rotB);
|
||||
rotY -= (BGMosaicY * rotD);
|
||||
xmossize = BGMosaicSize[0];
|
||||
}
|
||||
|
||||
if (bgcnt & 0x0080)
|
||||
{
|
||||
// bitmap modes
|
||||
|
@ -1492,14 +1569,29 @@ void GPU2D::DrawBG_Extended(u32 line, u32* dst, u32 bgnum)
|
|||
{
|
||||
// direct color bitmap
|
||||
|
||||
u16 color;
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
if (!(rotX & ofxmask) && !(rotY & ofymask) && (windowmask[i] & (1<<bgnum)))
|
||||
if (windowmask[i] & (1<<bgnum))
|
||||
{
|
||||
u16 color = GPU::ReadVRAM_BG<u16>(tilemapaddr + (((((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8)) << 1));
|
||||
if (xmos > 0)
|
||||
{
|
||||
if (color & 0x8000)
|
||||
DrawPixel(&dst[i], color, 0x01000000<<bgnum);
|
||||
|
||||
if (color & 0x8000)
|
||||
DrawPixel(&dst[i], color, 0x01000000<<bgnum);
|
||||
xmos--;
|
||||
}
|
||||
else
|
||||
if (!(rotX & ofxmask) && !(rotY & ofymask))
|
||||
{
|
||||
color = GPU::ReadVRAM_BG<u16>(tilemapaddr + (((((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8)) << 1));
|
||||
|
||||
if (color & 0x8000)
|
||||
DrawPixel(&dst[i], color, 0x01000000<<bgnum);
|
||||
|
||||
xmos = xmossize;
|
||||
}
|
||||
}
|
||||
|
||||
rotX += rotA;
|
||||
|
@ -1513,14 +1605,29 @@ void GPU2D::DrawBG_Extended(u32 line, u32* dst, u32 bgnum)
|
|||
if (Num) pal = (u16*)&GPU::Palette[0x400];
|
||||
else pal = (u16*)&GPU::Palette[0];
|
||||
|
||||
u8 color;
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
if (!(rotX & ofxmask) && !(rotY & ofymask) && (windowmask[i] & (1<<bgnum)))
|
||||
if (windowmask[i] & (1<<bgnum))
|
||||
{
|
||||
u8 color = GPU::ReadVRAM_BG<u8>(tilemapaddr + (((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8));
|
||||
if (xmos > 0)
|
||||
{
|
||||
if (color)
|
||||
DrawPixel(&dst[i], pal[color], 0x01000000<<bgnum);
|
||||
|
||||
if (color)
|
||||
DrawPixel(&dst[i], pal[color], 0x01000000<<bgnum);
|
||||
xmos--;
|
||||
}
|
||||
else
|
||||
if (!(rotX & ofxmask) && !(rotY & ofymask))
|
||||
{
|
||||
color = GPU::ReadVRAM_BG<u8>(tilemapaddr + (((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8));
|
||||
|
||||
if (color)
|
||||
DrawPixel(&dst[i], pal[color], 0x01000000<<bgnum);
|
||||
|
||||
xmos = xmossize;
|
||||
}
|
||||
}
|
||||
|
||||
rotX += rotA;
|
||||
|
@ -1563,30 +1670,43 @@ void GPU2D::DrawBG_Extended(u32 line, u32* dst, u32 bgnum)
|
|||
|
||||
u16 curtile;
|
||||
u16* curpal;
|
||||
u8 color;
|
||||
|
||||
yshift -= 3;
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
if ((!((rotX|rotY) & overflowmask)) && (windowmask[i] & (1<<bgnum)))
|
||||
if (windowmask[i] & (1<<bgnum))
|
||||
{
|
||||
curtile = GPU::ReadVRAM_BG<u16>(tilemapaddr + (((((rotY & coordmask) >> 11) << yshift) + ((rotX & coordmask) >> 11)) << 1));
|
||||
if (xmos > 0)
|
||||
{
|
||||
if (color)
|
||||
DrawPixel(&dst[i], curpal[color], 0x01000000<<bgnum);
|
||||
|
||||
if (extpal) curpal = GetBGExtPal(bgnum, curtile>>12);
|
||||
else curpal = pal;
|
||||
xmos--;
|
||||
}
|
||||
else
|
||||
if ((!((rotX|rotY) & overflowmask)))
|
||||
{
|
||||
curtile = GPU::ReadVRAM_BG<u16>(tilemapaddr + (((((rotY & coordmask) >> 11) << yshift) + ((rotX & coordmask) >> 11)) << 1));
|
||||
|
||||
// draw pixel
|
||||
u8 color;
|
||||
u32 tilexoff = (rotX >> 8) & 0x7;
|
||||
u32 tileyoff = (rotY >> 8) & 0x7;
|
||||
if (extpal) curpal = GetBGExtPal(bgnum, curtile>>12);
|
||||
else curpal = pal;
|
||||
|
||||
if (curtile & 0x0400) tilexoff = 7-tilexoff;
|
||||
if (curtile & 0x0800) tileyoff = 7-tileyoff;
|
||||
// draw pixel
|
||||
u32 tilexoff = (rotX >> 8) & 0x7;
|
||||
u32 tileyoff = (rotY >> 8) & 0x7;
|
||||
|
||||
color = GPU::ReadVRAM_BG<u8>(tilesetaddr + ((curtile & 0x03FF) << 6) + (tileyoff << 3) + tilexoff);
|
||||
if (curtile & 0x0400) tilexoff = 7-tilexoff;
|
||||
if (curtile & 0x0800) tileyoff = 7-tileyoff;
|
||||
|
||||
if (color)
|
||||
DrawPixel(&dst[i], curpal[color], 0x01000000<<bgnum);
|
||||
color = GPU::ReadVRAM_BG<u8>(tilesetaddr + ((curtile & 0x03FF) << 6) + (tileyoff << 3) + tilexoff);
|
||||
|
||||
if (color)
|
||||
DrawPixel(&dst[i], curpal[color], 0x01000000<<bgnum);
|
||||
|
||||
xmos = xmossize;
|
||||
}
|
||||
}
|
||||
|
||||
rotX += rotA;
|
||||
|
@ -1602,6 +1722,7 @@ void GPU2D::DrawBG_Large(u32 line, u32* dst) // BG is always BG2
|
|||
{
|
||||
u8* windowmask = (u8*)&dst[256*2];
|
||||
u16 bgcnt = BGCnt[2];
|
||||
u32 xmos = 0, xmossize = 0;
|
||||
|
||||
u32 tilesetaddr, tilemapaddr;
|
||||
u16* pal;
|
||||
|
@ -1636,6 +1757,14 @@ void GPU2D::DrawBG_Large(u32 line, u32* dst) // BG is always BG2
|
|||
s32 rotX = BGXRefInternal[0];
|
||||
s32 rotY = BGYRefInternal[0];
|
||||
|
||||
if (bgcnt & 0x0040)
|
||||
{
|
||||
// mosaic
|
||||
rotX -= (BGMosaicY * rotB);
|
||||
rotY -= (BGMosaicY * rotD);
|
||||
xmossize = BGMosaicSize[0];
|
||||
}
|
||||
|
||||
if (Num) tilemapaddr = 0x06200000;
|
||||
else tilemapaddr = 0x06000000;
|
||||
|
||||
|
@ -1644,14 +1773,27 @@ void GPU2D::DrawBG_Large(u32 line, u32* dst) // BG is always BG2
|
|||
if (Num) pal = (u16*)&GPU::Palette[0x400];
|
||||
else pal = (u16*)&GPU::Palette[0];
|
||||
|
||||
u8 color;
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
if (!(rotX & ofxmask) && !(rotY & ofymask) && (windowmask[i] & (1<<2)))
|
||||
if (windowmask[i] & (1<<2))
|
||||
{
|
||||
u8 color = GPU::ReadVRAM_BG<u8>(tilemapaddr + (((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8));
|
||||
if (xmos > 0)
|
||||
{
|
||||
if (color)
|
||||
DrawPixel(&dst[i], pal[color], 0x01000000<<2);
|
||||
|
||||
if (color)
|
||||
DrawPixel(&dst[i], pal[color], 0x01000000<<2);
|
||||
xmos--;
|
||||
}
|
||||
else
|
||||
if (!(rotX & ofxmask) && !(rotY & ofymask))
|
||||
{
|
||||
color = GPU::ReadVRAM_BG<u8>(tilemapaddr + (((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8));
|
||||
|
||||
if (color)
|
||||
DrawPixel(&dst[i], pal[color], 0x01000000<<2);
|
||||
}
|
||||
}
|
||||
|
||||
rotX += rotA;
|
||||
|
@ -1843,17 +1985,29 @@ void GPU2D::DrawSpritesWindow(u32 line, u8* dst)
|
|||
}
|
||||
|
||||
template<bool window>
|
||||
void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, u32 ypos, u32* dst)
|
||||
void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos, u32* dst)
|
||||
{
|
||||
u32 prio = ((attrib[2] & 0x0C00) << 6) | 0x8000;
|
||||
u32 tilenum = attrib[2] & 0x03FF;
|
||||
u32 spritemode = window ? 0 : ((attrib[0] >> 10) & 0x3);
|
||||
u32 xmos = 0, xmossize = 0;
|
||||
|
||||
u32 ytilefactor;
|
||||
|
||||
s32 centerX = boundwidth >> 1;
|
||||
s32 centerY = boundheight >> 1;
|
||||
|
||||
if (attrib[0] & 0x1000)
|
||||
{
|
||||
// mosaic
|
||||
ypos -= OBJMosaicY;
|
||||
if (ypos < 0) ypos = 0;
|
||||
xmossize = OBJMosaicSize[0];
|
||||
|
||||
if (xpos > 0)
|
||||
xmos = (xmossize+1) - (xpos % (xmossize+1));
|
||||
}
|
||||
|
||||
u32 xoff;
|
||||
if (xpos >= 0)
|
||||
{
|
||||
|
@ -1878,6 +2032,8 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
|
|||
width <<= 8;
|
||||
height <<= 8;
|
||||
|
||||
u16 color = 0; // transparent in all cases
|
||||
|
||||
if (spritemode == 3)
|
||||
{
|
||||
u32 alpha = attrib[2] >> 12;
|
||||
|
@ -1914,12 +2070,20 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
|
|||
}
|
||||
|
||||
u32 pixelsaddr = (Num ? 0x06600000 : 0x06400000) + tilenum;
|
||||
if (xmos && !(attrib[0]&0x0200))
|
||||
color = GPU::ReadVRAM_OBJ<u16>(pixelsaddr + ((rotY >> 8) * ytilefactor) + ((rotX >> 8) << 1));
|
||||
|
||||
for (; xoff < boundwidth;)
|
||||
{
|
||||
if ((u32)rotX < width && (u32)rotY < height)
|
||||
{
|
||||
u16 color = GPU::ReadVRAM_OBJ<u16>(pixelsaddr + ((rotY >> 8) * ytilefactor) + ((rotX >> 8) << 1));
|
||||
if (xmos == 0)
|
||||
{
|
||||
color = GPU::ReadVRAM_OBJ<u16>(pixelsaddr + ((rotY >> 8) * ytilefactor) + ((rotX >> 8) << 1));
|
||||
xmos = xmossize;
|
||||
}
|
||||
else
|
||||
xmos--;
|
||||
|
||||
if (color & 0x8000)
|
||||
{
|
||||
|
@ -1927,6 +2091,11 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
|
|||
else dst[xpos] = color | prio;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xmos == 0) xmos = xmossize;
|
||||
else xmos--;
|
||||
}
|
||||
|
||||
rotX += rotA;
|
||||
rotY += rotC;
|
||||
|
@ -1965,11 +2134,20 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
|
|||
else pal = (u16*)&GPU::Palette[Num ? 0x600 : 0x200];
|
||||
}
|
||||
|
||||
if (xmos && !(attrib[0]&0x0200))
|
||||
color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr + ((rotY>>11)*ytilefactor) + ((rotY&0x700)>>5) + ((rotX>>11)*64) + ((rotX&0x700)>>8));
|
||||
|
||||
for (; xoff < boundwidth;)
|
||||
{
|
||||
if ((u32)rotX < width && (u32)rotY < height)
|
||||
{
|
||||
u8 color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr + ((rotY>>11)*ytilefactor) + ((rotY&0x700)>>5) + ((rotX>>11)*64) + ((rotX&0x700)>>8));
|
||||
if (xmos == 0)
|
||||
{
|
||||
color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr + ((rotY>>11)*ytilefactor) + ((rotY&0x700)>>5) + ((rotX>>11)*64) + ((rotX&0x700)>>8));
|
||||
xmos = xmossize;
|
||||
}
|
||||
else
|
||||
xmos--;
|
||||
|
||||
if (color)
|
||||
{
|
||||
|
@ -1977,6 +2155,11 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
|
|||
else dst[xpos] = pal[color] | prio;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xmos == 0) xmos = xmossize;
|
||||
else xmos--;
|
||||
}
|
||||
|
||||
rotX += rotA;
|
||||
rotY += rotC;
|
||||
|
@ -1998,16 +2181,31 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
|
|||
pal += (attrib[2] & 0xF000) >> 8;
|
||||
}
|
||||
|
||||
if (xmos && !(attrib[0]&0x0200))
|
||||
{
|
||||
color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr + ((rotY>>11)*ytilefactor) + ((rotY&0x700)>>6) + ((rotX>>11)*32) + ((rotX&0x700)>>9));
|
||||
if (rotX & 0x100)
|
||||
color >>= 4;
|
||||
else
|
||||
color &= 0x0F;
|
||||
}
|
||||
|
||||
for (; xoff < boundwidth;)
|
||||
{
|
||||
if ((u32)rotX < width && (u32)rotY < height)
|
||||
{
|
||||
u8 color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr + ((rotY>>11)*ytilefactor) + ((rotY&0x700)>>6) + ((rotX>>11)*32) + ((rotX&0x700)>>9));
|
||||
if (xmos == 0)
|
||||
{
|
||||
color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr + ((rotY>>11)*ytilefactor) + ((rotY&0x700)>>6) + ((rotX>>11)*32) + ((rotX&0x700)>>9));
|
||||
if (rotX & 0x100)
|
||||
color >>= 4;
|
||||
else
|
||||
color &= 0x0F;
|
||||
|
||||
if (rotX & 0x100)
|
||||
color >>= 4;
|
||||
xmos = xmossize;
|
||||
}
|
||||
else
|
||||
color &= 0x0F;
|
||||
xmos--;
|
||||
|
||||
if (color)
|
||||
{
|
||||
|
@ -2015,6 +2213,11 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
|
|||
else dst[xpos] = pal[color] | prio;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xmos == 0) xmos = xmossize;
|
||||
else xmos--;
|
||||
}
|
||||
|
||||
rotX += rotA;
|
||||
rotY += rotC;
|
||||
|
@ -2026,14 +2229,26 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
|
|||
}
|
||||
|
||||
template<bool window>
|
||||
void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, u32 ypos, u32* dst)
|
||||
void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* dst)
|
||||
{
|
||||
u32 prio = ((attrib[2] & 0x0C00) << 6) | 0x8000;
|
||||
u32 tilenum = attrib[2] & 0x03FF;
|
||||
u32 spritemode = window ? 0 : ((attrib[0] >> 10) & 0x3);
|
||||
u32 xmos = 0, xmossize = 0;
|
||||
|
||||
u32 wmask = width - 8; // really ((width - 1) & ~0x7)
|
||||
|
||||
if (attrib[0] & 0x1000)
|
||||
{
|
||||
// mosaic
|
||||
ypos -= OBJMosaicY;
|
||||
if (ypos < 0) ypos = 0;
|
||||
xmossize = OBJMosaicSize[0];
|
||||
|
||||
if (xpos > 0)
|
||||
xmos = (xmossize+1) - (xpos % (xmossize+1));
|
||||
}
|
||||
|
||||
u32 xoff;
|
||||
u32 xend = width;
|
||||
if (xpos >= 0)
|
||||
|
@ -2048,6 +2263,8 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, u32 ypos, u32* d
|
|||
xpos = 0;
|
||||
}
|
||||
|
||||
u16 color = 0; // transparent in all cases
|
||||
|
||||
if (spritemode == 3)
|
||||
{
|
||||
// bitmap sprite
|
||||
|
@ -2090,10 +2307,18 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, u32 ypos, u32* d
|
|||
if (attrib[1] & 0x1000)
|
||||
{
|
||||
pixelsaddr += ((width-1 - xoff) << 1);
|
||||
if (xmos) color = GPU::ReadVRAM_OBJ<u16>(pixelsaddr);
|
||||
|
||||
for (; xoff < xend;)
|
||||
{
|
||||
u16 color = GPU::ReadVRAM_OBJ<u16>(pixelsaddr);
|
||||
if (xmos == 0)
|
||||
{
|
||||
color = GPU::ReadVRAM_OBJ<u16>(pixelsaddr);
|
||||
xmos = xmossize;
|
||||
}
|
||||
else
|
||||
xmos--;
|
||||
|
||||
pixelsaddr -= 2;
|
||||
|
||||
if (color & 0x8000)
|
||||
|
@ -2109,10 +2334,18 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, u32 ypos, u32* d
|
|||
else
|
||||
{
|
||||
pixelsaddr += (xoff << 1);
|
||||
if (xmos) color = GPU::ReadVRAM_OBJ<u16>(pixelsaddr);
|
||||
|
||||
for (; xoff < xend;)
|
||||
{
|
||||
u16 color = GPU::ReadVRAM_OBJ<u16>(pixelsaddr);
|
||||
if (xmos == 0)
|
||||
{
|
||||
color = GPU::ReadVRAM_OBJ<u16>(pixelsaddr);
|
||||
xmos = xmossize;
|
||||
}
|
||||
else
|
||||
xmos--;
|
||||
|
||||
pixelsaddr += 2;
|
||||
|
||||
if (color & 0x8000)
|
||||
|
@ -2161,10 +2394,18 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, u32 ypos, u32* d
|
|||
{
|
||||
pixelsaddr += (((width-1 - xoff) & wmask) << 3);
|
||||
pixelsaddr += ((width-1 - xoff) & 0x7);
|
||||
if (xmos) color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr);
|
||||
|
||||
for (; xoff < xend;)
|
||||
{
|
||||
u8 color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr);
|
||||
if (xmos == 0)
|
||||
{
|
||||
color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr);
|
||||
xmos = xmossize;
|
||||
}
|
||||
else
|
||||
xmos--;
|
||||
|
||||
pixelsaddr--;
|
||||
|
||||
if (color)
|
||||
|
@ -2182,10 +2423,18 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, u32 ypos, u32* d
|
|||
{
|
||||
pixelsaddr += ((xoff & wmask) << 3);
|
||||
pixelsaddr += (xoff & 0x7);
|
||||
if (xmos) color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr);
|
||||
|
||||
for (; xoff < xend;)
|
||||
{
|
||||
u8 color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr);
|
||||
if (xmos == 0)
|
||||
{
|
||||
color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr);
|
||||
xmos = xmossize;
|
||||
}
|
||||
else
|
||||
xmos--;
|
||||
|
||||
pixelsaddr++;
|
||||
|
||||
if (color)
|
||||
|
@ -2218,19 +2467,24 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, u32 ypos, u32* d
|
|||
{
|
||||
pixelsaddr += (((width-1 - xoff) & wmask) << 2);
|
||||
pixelsaddr += (((width-1 - xoff) & 0x7) >> 1);
|
||||
if (xmos)
|
||||
{
|
||||
if (xoff & 0x1) color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) & 0x0F;
|
||||
else color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) >> 4;
|
||||
}
|
||||
|
||||
for (; xoff < xend;)
|
||||
{
|
||||
u8 color;
|
||||
if (xoff & 0x1)
|
||||
if (xmos == 0)
|
||||
{
|
||||
color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) & 0x0F;
|
||||
pixelsaddr--;
|
||||
if (xoff & 0x1) color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) & 0x0F;
|
||||
else color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) >> 4;
|
||||
xmos = xmossize;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) >> 4;
|
||||
}
|
||||
xmos--;
|
||||
|
||||
if (xoff & 0x1) pixelsaddr--;
|
||||
|
||||
if (color)
|
||||
{
|
||||
|
@ -2247,19 +2501,24 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, u32 ypos, u32* d
|
|||
{
|
||||
pixelsaddr += ((xoff & wmask) << 2);
|
||||
pixelsaddr += ((xoff & 0x7) >> 1);
|
||||
if (xmos)
|
||||
{
|
||||
if (xoff & 0x1) color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) >> 4;
|
||||
else color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) & 0x0F;
|
||||
}
|
||||
|
||||
for (; xoff < xend;)
|
||||
{
|
||||
u8 color;
|
||||
if (xoff & 0x1)
|
||||
if (xmos == 0)
|
||||
{
|
||||
color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) >> 4;
|
||||
pixelsaddr++;
|
||||
if (xoff & 0x1) color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) >> 4;
|
||||
else color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) & 0x0F;
|
||||
xmos = xmossize;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) & 0x0F;
|
||||
}
|
||||
xmos--;
|
||||
|
||||
pixelsaddr++;
|
||||
|
||||
if (color)
|
||||
{
|
||||
|
|
|
@ -93,6 +93,8 @@ private:
|
|||
|
||||
u8 BGMosaicSize[2];
|
||||
u8 OBJMosaicSize[2];
|
||||
u8 BGMosaicY, BGMosaicYMax;
|
||||
u8 OBJMosaicY, OBJMosaicYMax;
|
||||
|
||||
u16 BlendCnt;
|
||||
u16 BlendAlpha;
|
||||
|
@ -123,8 +125,8 @@ private:
|
|||
void InterleaveSprites(u32* buf, u32 prio, u32* dst);
|
||||
void DrawSprites(u32 line, u32* dst);
|
||||
void DrawSpritesWindow(u32 line, u8* dst);
|
||||
template<bool window> void DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, u32 ypos, u32* dst);
|
||||
template<bool window> void DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, u32 ypos, u32* dst);
|
||||
template<bool window> void DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos, u32* dst);
|
||||
template<bool window> void DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* dst);
|
||||
|
||||
void DoCapture(u32 line, u32 width, u32* src);
|
||||
|
||||
|
|
Loading…
Reference in New Issue