aboutsummaryrefslogtreecommitdiff
path: root/src/GPU2D.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/GPU2D.cpp')
-rw-r--r--src/GPU2D.cpp166
1 files changed, 121 insertions, 45 deletions
diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp
index 7550562..4951404 100644
--- a/src/GPU2D.cpp
+++ b/src/GPU2D.cpp
@@ -1,5 +1,5 @@
/*
- Copyright 2016-2017 StapleButter
+ Copyright 2016-2019 StapleButter
This file is part of melonDS.
@@ -107,6 +107,9 @@ void GPU2D::Reset()
memset(Win1Coords, 0, 4);
memset(WinCnt, 0, 4);
+ Win0Active = 0;
+ Win1Active = 0;
+
BGMosaicSize[0] = 0;
BGMosaicSize[1] = 0;
OBJMosaicSize[0] = 0;
@@ -138,6 +141,75 @@ void GPU2D::Reset()
OBJExtPalStatus = 0;
}
+void GPU2D::DoSavestate(Savestate* file)
+{
+ file->Section((char*)(Num ? "GP2B" : "GP2A"));
+
+ file->Var32(&DispCnt);
+ file->VarArray(BGCnt, 4*2);
+ file->VarArray(BGXPos, 4*2);
+ file->VarArray(BGYPos, 4*2);
+ file->VarArray(BGXRef, 2*4);
+ file->VarArray(BGYRef, 2*4);
+ file->VarArray(BGXRefInternal, 2*4);
+ file->VarArray(BGYRefInternal, 2*4);
+ file->VarArray(BGRotA, 2*2);
+ file->VarArray(BGRotB, 2*2);
+ file->VarArray(BGRotC, 2*2);
+ file->VarArray(BGRotD, 2*2);
+
+ file->VarArray(Win0Coords, 4);
+ file->VarArray(Win1Coords, 4);
+ file->VarArray(WinCnt, 4);
+
+ file->VarArray(BGMosaicSize, 2);
+ file->VarArray(OBJMosaicSize, 2);
+ file->Var8(&BGMosaicY);
+ file->Var8(&BGMosaicYMax);
+ file->Var8(&OBJMosaicY);
+ file->Var8(&OBJMosaicYMax);
+
+ file->Var16(&BlendCnt);
+ file->Var16(&BlendAlpha);
+ file->Var8(&EVA);
+ file->Var8(&EVB);
+ file->Var8(&EVY);
+
+ file->Var16(&MasterBrightness);
+
+ if (!Num)
+ {
+ file->VarArray(DispFIFO, 16*2);
+ file->Var32(&DispFIFOReadPtr);
+ file->Var32(&DispFIFOWritePtr);
+
+ file->VarArray(DispFIFOBuffer, 256*2);
+
+ file->Var32(&CaptureCnt);
+ }
+
+ if (file->IsAtleastVersion(2, 1))
+ {
+ file->Var32(&Win0Active);
+ file->Var32(&Win1Active);
+ }
+ else
+ {
+ Win0Active = 0;
+ Win1Active = 0;
+ }
+
+ if (!file->Saving)
+ {
+ // refresh those
+ BGExtPalStatus[0] = 0;
+ BGExtPalStatus[1] = 0;
+ BGExtPalStatus[2] = 0;
+ BGExtPalStatus[3] = 0;
+ OBJExtPalStatus = 0;
+ }
+}
+
void GPU2D::SetFramebuffer(u32* buf)
{
Framebuffer = buf;
@@ -480,6 +552,15 @@ void GPU2D::DrawScanline(u32 line)
return;
}
+ // forced blank
+ // (checkme: are there still things that can run under this mode? likely not)
+ if (DispCnt & (1<<7))
+ {
+ for (int i = 0; i < 256; i++)
+ dst[i] = 0xFFFFFFFF;
+ return;
+ }
+
u32 dispmode = DispCnt >> 16;
dispmode &= (Num ? 0x1 : 0x3);
@@ -614,12 +695,12 @@ void GPU2D::DrawScanline(u32 line)
for (int i = 0; i < 256; i++)
{
u32 c = dst[i];
-
+
u32 r = c << 18;
u32 g = (c << 2) & 0xFC00;
u32 b = (c >> 14) & 0xFC;
c = r | g | b;
-
+
dst[i] = c | ((c & 0x00C0C0C0) >> 6) | 0xFF000000;
}
}
@@ -894,10 +975,10 @@ u16* GPU2D::GetOBJExtPal(u32 pal)
void GPU2D::CheckWindows(u32 line)
{
line &= 0xFF;
- if (line == Win0Coords[3]) Win0Active = false;
- else if (line == Win0Coords[2]) Win0Active = true;
- if (line == Win1Coords[3]) Win1Active = false;
- else if (line == Win1Coords[2]) Win1Active = true;
+ if (line == Win0Coords[3]) Win0Active &= ~0x1;
+ else if (line == Win0Coords[2]) Win0Active |= 0x1;
+ if (line == Win1Coords[3]) Win1Active &= ~0x1;
+ else if (line == Win1Coords[2]) Win1Active |= 0x1;
}
void GPU2D::CalculateWindowMask(u32 line, u8* mask)
@@ -905,41 +986,40 @@ void GPU2D::CalculateWindowMask(u32 line, u8* mask)
for (u32 i = 0; i < 256; i++)
mask[i] = WinCnt[2]; // window outside
- if ((DispCnt & (1<<15)) && (DispCnt & (1<<12)))
+ if (DispCnt & ((1<<15)|(1<<12)))
{
// OBJ window
- u8 objwin[256];
- memset(objwin, 0, 256);
- DrawSpritesWindow(line, objwin);
-
- for (u32 i = 0; i < 256; i++)
- {
- if (objwin[i]) mask[i] = WinCnt[3];
- }
+ DrawSpritesWindow(line, mask);
}
- if ((DispCnt & (1<<14)) && Win1Active)
+ if (DispCnt & (1<<14))
{
// window 1
- u32 x1 = Win1Coords[0];
- u32 x2 = Win1Coords[1];
- if (x2 == 0 && x1 > 0) x2 = 256;
- if (x1 > x2) x2 = 255; // checkme
+ u8 x1 = Win1Coords[0];
+ u8 x2 = Win1Coords[1];
+
+ for (int i = 0; i < 256; i++)
+ {
+ if (i == x2) Win1Active &= ~0x2;
+ else if (i == x1) Win1Active |= 0x2;
- for (u32 i = x1; i < x2; i++)
- mask[i] = WinCnt[1];
+ if (Win1Active == 0x3) mask[i] = WinCnt[1];
+ }
}
- if ((DispCnt & (1<<13)) && Win0Active)
+ if (DispCnt & (1<<13))
{
// window 0
- u32 x1 = Win0Coords[0];
- u32 x2 = Win0Coords[1];
- if (x2 == 0 && x1 > 0) x2 = 256;
- if (x1 > x2) x2 = 255; // checkme
+ u8 x1 = Win0Coords[0];
+ u8 x2 = Win0Coords[1];
+
+ for (int i = 0; i < 256; i++)
+ {
+ if (i == x2) Win0Active &= ~0x2;
+ else if (i == x1) Win0Active |= 0x2;
- for (u32 i = x1; i < x2; i++)
- mask[i] = WinCnt[0];
+ if (Win0Active == 0x3) mask[i] = WinCnt[0];
+ }
}
}
@@ -1087,11 +1167,7 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst)
else if (flag2 & 0x40) target2 = 0x0100;
else target2 = flag2 << 8;
- if (!(windowmask[i] & 0x20))
- {
- coloreffect = 0;
- }
- else if ((flag1 & 0x80) && (BlendCnt & target2))
+ if ((flag1 & 0x80) && (BlendCnt & target2))
{
// sprite blending
@@ -1134,7 +1210,7 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst)
continue;
}
- else if (BlendCnt & flag1)
+ else if ((BlendCnt & flag1) && (windowmask[i] & 0x20))
{
if ((bldcnteffect == 1) && (BlendCnt & target2))
{
@@ -2096,7 +2172,7 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
if (color & 0x8000)
{
- if (window) ((u8*)dst)[xpos] = 1;
+ if (window) ((u8*)dst)[xpos] = WinCnt[3];
else dst[xpos] = color | prio;
}
}
@@ -2160,7 +2236,7 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
if (color)
{
- if (window) ((u8*)dst)[xpos] = 1;
+ if (window) ((u8*)dst)[xpos] = WinCnt[3];
else dst[xpos] = pal[color] | prio;
}
}
@@ -2218,7 +2294,7 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32
if (color)
{
- if (window) ((u8*)dst)[xpos] = 1;
+ if (window) ((u8*)dst)[xpos] = WinCnt[3];
else dst[xpos] = pal[color] | prio;
}
}
@@ -2332,7 +2408,7 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* d
if (color & 0x8000)
{
- if (window) ((u8*)dst)[xpos] = 1;
+ if (window) ((u8*)dst)[xpos] = WinCnt[3];
else dst[xpos] = color | prio;
}
@@ -2359,7 +2435,7 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* d
if (color & 0x8000)
{
- if (window) ((u8*)dst)[xpos] = 1;
+ if (window) ((u8*)dst)[xpos] = WinCnt[3];
else dst[xpos] = color | prio;
}
@@ -2419,7 +2495,7 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* d
if (color)
{
- if (window) ((u8*)dst)[xpos] = 1;
+ if (window) ((u8*)dst)[xpos] = WinCnt[3];
else dst[xpos] = pal[color] | prio;
}
@@ -2448,7 +2524,7 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* d
if (color)
{
- if (window) ((u8*)dst)[xpos] = 1;
+ if (window) ((u8*)dst)[xpos] = WinCnt[3];
else dst[xpos] = pal[color] | prio;
}
@@ -2497,7 +2573,7 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* d
if (color)
{
- if (window) ((u8*)dst)[xpos] = 1;
+ if (window) ((u8*)dst)[xpos] = WinCnt[3];
else dst[xpos] = pal[color] | prio;
}
@@ -2531,7 +2607,7 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* d
if (color)
{
- if (window) ((u8*)dst)[xpos] = 1;
+ if (window) ((u8*)dst)[xpos] = WinCnt[3];
else dst[xpos] = pal[color] | prio;
}