aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorArisotura <thetotalworm@gmail.com>2019-11-03 04:32:47 +0100
committerArisotura <thetotalworm@gmail.com>2019-11-03 04:32:47 +0100
commit3561e93bf6b72debe61380e277b40b07d1fd22c3 (patch)
treef88f43fe7e577b0ac5d340115131f3c207a69a82 /src
parente117da235e939a47e4dd08fbded68abc3165271d (diff)
fix sprite y-flip
also, meaningless shenanigans
Diffstat (limited to 'src')
-rw-r--r--src/GPU2D.cpp64
-rw-r--r--src/GPU2D.h5
2 files changed, 54 insertions, 15 deletions
diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp
index b510767..52c7be2 100644
--- a/src/GPU2D.cpp
+++ b/src/GPU2D.cpp
@@ -2238,6 +2238,13 @@ void GPU2D::DrawBG_Large(u32 line) // BG is always BG2
BGYRefInternal[0] += rotD;
}
+// OBJ line buffer:
+// * bit0-15: color (bit15=1: direct color, bit15=0: palette index, bit12=0 to indicate extpal)
+// * bit16-17: BG-relative priority
+// * bit18: non-transparent sprite pixel exists here
+// * bit19: X mosaic should be applied here
+// * bit24-31: compositor flags
+
void GPU2D::ApplySpriteMosaicX()
{
// apply X mosaic if needed
@@ -2255,7 +2262,7 @@ void GPU2D::ApplySpriteMosaicX()
continue;
}
- if ((!(OBJLine[i-1] & 0x100000)) || (CurOBJXMosaicTable[i] == 0))
+ if ((OBJIndex[i] != OBJIndex[i-1]) || (CurOBJXMosaicTable[i] == 0))
lastcolor = OBJLine[i];
else
OBJLine[i] = lastcolor;
@@ -2327,6 +2334,8 @@ void GPU2D::DrawSprites(u32 line)
memset(OBJWindow, 0, 256);
if (!(DispCnt & 0x1000)) return;
+ memset(OBJIndex, 0xFF, 256);
+
u16* oam = (u16*)&GPU::OAM[Num ? 0x400 : 0];
const s32 spritewidth[16] =
@@ -2380,7 +2389,7 @@ void GPU2D::DrawSprites(u32 line)
u32 rotparamgroup = (attrib[1] >> 9) & 0x1F;
- DoDrawSprite(Rotscale, attrib, &oam[(rotparamgroup*16) + 3], boundwidth, boundheight, width, height, xpos, ypos);
+ DoDrawSprite(Rotscale, sprnum, boundwidth, boundheight, width, height, xpos, ypos);
NumSprites++;
}
@@ -2403,10 +2412,10 @@ void GPU2D::DrawSprites(u32 line)
continue;
// yflip
- if (attrib[1] & 0x2000)
- ypos = height-1 - ypos;
+ //if (attrib[1] & 0x2000)
+ // ypos = height-1 - ypos;
- DoDrawSprite(Normal, attrib, width, xpos, ypos);
+ DoDrawSprite(Normal, sprnum, width, height, xpos, ypos);
NumSprites++;
}
@@ -2415,8 +2424,12 @@ 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)
+void GPU2D::DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos)
{
+ u16* oam = (u16*)&GPU::OAM[Num ? 0x400 : 0];
+ u16* attrib = &oam[num * 4];
+ u16* rotparams = &oam[(((attrib[1] >> 9) & 0x1F) * 16) + 3];
+
u32 pixelattr = ((attrib[2] & 0x0C00) << 6) | 0xC0000;
u32 tilenum = attrib[2] & 0x03FF;
u32 spritemode = window ? 0 : ((attrib[0] >> 10) & 0x3);
@@ -2509,12 +2522,15 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
if (color & 0x8000)
{
if (window) OBJWindow[xpos] = 1;
- else OBJLine[xpos] = color | pixelattr;
+ else { OBJLine[xpos] = color | pixelattr; OBJIndex[xpos] = num; }
}
else if (!window)
{
if (OBJLine[xpos] == 0)
+ {
OBJLine[xpos] = pixelattr & 0x180000;
+ OBJIndex[xpos] = num;
+ }
}
}
@@ -2563,12 +2579,15 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
if (color)
{
if (window) OBJWindow[xpos] = 1;
- else OBJLine[xpos] = color | pixelattr;
+ else { OBJLine[xpos] = color | pixelattr; OBJIndex[xpos] = num; }
}
else if (!window)
{
if (OBJLine[xpos] == 0)
+ {
OBJLine[xpos] = pixelattr & 0x180000;
+ OBJIndex[xpos] = num;
+ }
}
}
@@ -2604,12 +2623,15 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
if (color)
{
if (window) OBJWindow[xpos] = 1;
- else OBJLine[xpos] = color | pixelattr;
+ else { OBJLine[xpos] = color | pixelattr; OBJIndex[xpos] = num; }
}
else if (!window)
{
if (OBJLine[xpos] == 0)
+ {
OBJLine[xpos] = pixelattr & 0x180000;
+ OBJIndex[xpos] = num;
+ }
}
}
@@ -2623,8 +2645,11 @@ 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)
+void GPU2D::DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 ypos)
{
+ u16* oam = (u16*)&GPU::OAM[Num ? 0x400 : 0];
+ u16* attrib = &oam[num * 4];
+
u32 pixelattr = ((attrib[2] & 0x0C00) << 6) | 0xC0000;
u32 tilenum = attrib[2] & 0x03FF;
u32 spritemode = window ? 0 : ((attrib[0] >> 10) & 0x3);
@@ -2640,6 +2665,10 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos)
pixelattr |= 0x100000;
}
+ // yflip
+ if (attrib[1] & 0x2000)
+ ypos = height-1 - ypos;
+
u32 xoff;
u32 xend = width;
if (xpos >= 0)
@@ -2719,12 +2748,15 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos)
if (color & 0x8000)
{
if (window) OBJWindow[xpos] = 1;
- else OBJLine[xpos] = color | pixelattr;
+ else { OBJLine[xpos] = color | pixelattr; OBJIndex[xpos] = num; }
}
else if (!window)
{
if (OBJLine[xpos] == 0)
+ {
OBJLine[xpos] = pixelattr & 0x180000;
+ OBJIndex[xpos] = num;
+ }
}
xoff++;
@@ -2786,12 +2818,15 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos)
if (color)
{
if (window) OBJWindow[xpos] = 1;
- else OBJLine[xpos] = color | pixelattr;
+ else { OBJLine[xpos] = color | pixelattr; OBJIndex[xpos] = num; }
}
else if (!window)
{
if (OBJLine[xpos] == 0)
+ {
OBJLine[xpos] = pixelattr & 0x180000;
+ OBJIndex[xpos] = num;
+ }
}
xoff++;
@@ -2847,12 +2882,15 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos)
if (color)
{
if (window) OBJWindow[xpos] = 1;
- else OBJLine[xpos] = color | pixelattr;
+ else { OBJLine[xpos] = color | pixelattr; OBJIndex[xpos] = num; }
}
else if (!window)
{
if (OBJLine[xpos] == 0)
+ {
OBJLine[xpos] = pixelattr & 0x180000;
+ OBJIndex[xpos] = num;
+ }
}
xoff++;
diff --git a/src/GPU2D.h b/src/GPU2D.h
index 8c6ec27..6675ce7 100644
--- a/src/GPU2D.h
+++ b/src/GPU2D.h
@@ -78,6 +78,7 @@ private:
u8 WindowMask[256] __attribute__((aligned (8)));
u32 OBJLine[256] __attribute__((aligned (8)));
u8 OBJWindow[256] __attribute__((aligned (8)));
+ u8 OBJIndex[256] __attribute__((aligned (8)));
u32 NumSprites;
@@ -156,8 +157,8 @@ private:
void ApplySpriteMosaicX();
void InterleaveSprites(u32 prio);
- template<bool window> void DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos);
- template<bool window> void DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos);
+ template<bool window> void DrawSprite_Rotscale(u32 num, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos);
+ template<bool window> void DrawSprite_Normal(u32 num, u32 width, u32 height, s32 xpos, s32 ypos);
void DoCapture(u32 line, u32 width);