diff options
Diffstat (limited to 'src/GPU2D.cpp')
-rw-r--r-- | src/GPU2D.cpp | 166 |
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; } |