* display capture
* fix bug with bitmap BGs (wrong base offset)
This commit is contained in:
parent
5d9e9a5023
commit
247558a354
182
GPU2D.cpp
182
GPU2D.cpp
|
@ -83,6 +83,8 @@ void GPU2D::Reset()
|
|||
memset(BGRotC, 0, 2*2);
|
||||
memset(BGRotD, 0, 2*2);
|
||||
|
||||
CaptureCnt = 0;
|
||||
|
||||
MasterBrightness = 0;
|
||||
|
||||
BGExtPalStatus[0] = 0;
|
||||
|
@ -205,6 +207,12 @@ void GPU2D::Write32(u32 addr, u32 val)
|
|||
if (val & 0x08000000) val |= 0xF0000000;
|
||||
BGYCenter[1] = val;
|
||||
return;
|
||||
|
||||
case 0x064:
|
||||
// TODO: check what happens when writing to it during display
|
||||
// esp. if a capture is happening
|
||||
CaptureCnt = val & 0xEF3F1F1F;
|
||||
return;
|
||||
}
|
||||
|
||||
Write16(addr, val&0xFFFF);
|
||||
|
@ -264,11 +272,27 @@ void GPU2D::DrawScanline(u32 line)
|
|||
|
||||
case 3: // FIFO display
|
||||
{
|
||||
// uh, is there even anything that uses this?
|
||||
// TODO
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// capture
|
||||
if ((!Num) && (CaptureCnt & (1<<31)))
|
||||
{
|
||||
u32 capwidth, capheight;
|
||||
switch ((CaptureCnt >> 20) & 0x3)
|
||||
{
|
||||
case 0: capwidth = 128; capheight = 128; break;
|
||||
case 1: capwidth = 256; capheight = 64; break;
|
||||
case 2: capwidth = 256; capheight = 128; break;
|
||||
case 3: capwidth = 256; capheight = 192; break;
|
||||
}
|
||||
|
||||
if (line < capheight)
|
||||
DoCapture(line, capwidth, dst);
|
||||
}
|
||||
|
||||
// master brightness
|
||||
if (dispmode != 0)
|
||||
{
|
||||
|
@ -325,7 +349,153 @@ void GPU2D::DrawScanline(u32 line)
|
|||
|
||||
void GPU2D::VBlank()
|
||||
{
|
||||
//
|
||||
CaptureCnt &= ~(1<<31);
|
||||
}
|
||||
|
||||
|
||||
void GPU2D::DoCapture(u32 line, u32 width, u32* src)
|
||||
{
|
||||
u32 dstvram = (CaptureCnt >> 16) & 0x3;
|
||||
|
||||
// TODO: confirm this
|
||||
// it should work like VRAM display mode, which requires VRAM to be mapped to LCDC
|
||||
if (!(GPU::VRAMMap_LCDC & (1<<dstvram)))
|
||||
return;
|
||||
|
||||
u16* dst = (u16*)GPU::VRAM[dstvram];
|
||||
u32 dstaddr = (((CaptureCnt >> 18) & 0x3) << 14) + (line * width);
|
||||
|
||||
if (CaptureCnt & (1<<24))
|
||||
src = (u32*)GPU3D::GetLine(line);
|
||||
|
||||
u16* srcB = NULL;
|
||||
u32 srcBaddr = line * 256;
|
||||
|
||||
if (CaptureCnt & (1<<25))
|
||||
{
|
||||
// TODO: FIFO mode
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 srcvram = (DispCnt >> 18) & 0x3;
|
||||
if (GPU::VRAMMap_LCDC & (1<<srcvram))
|
||||
srcB = (u16*)GPU::VRAM[srcvram];
|
||||
|
||||
if (((DispCnt >> 16) & 0x3) != 2)
|
||||
srcBaddr += ((CaptureCnt >> 26) & 0x3) << 14;
|
||||
}
|
||||
|
||||
dstaddr &= 0xFFFF;
|
||||
srcBaddr &= 0xFFFF;
|
||||
|
||||
switch ((DispCnt >> 29) & 0x3)
|
||||
{
|
||||
case 0: // source A
|
||||
{
|
||||
for (u32 i = 0; i < width; i++)
|
||||
{
|
||||
u32 val = src[i];
|
||||
|
||||
// TODO: check what happens when alpha=0
|
||||
|
||||
u32 r = (val >> 1) & 0x1F;
|
||||
u32 g = (val >> 9) & 0x1F;
|
||||
u32 b = (val >> 17) & 0x1F;
|
||||
u32 a = ((val >> 24) != 0) ? 0x8000 : 0;
|
||||
|
||||
dst[dstaddr] = r | (g << 5) | (b << 10) | a;
|
||||
dstaddr = (dstaddr + 1) & 0xFFFF;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // source B
|
||||
{
|
||||
if (srcB)
|
||||
{
|
||||
for (u32 i = 0; i < width; i++)
|
||||
{
|
||||
dst[dstaddr] = srcB[srcBaddr];
|
||||
srcBaddr = (srcBaddr + 1) & 0xFFFF;
|
||||
dstaddr = (dstaddr + 1) & 0xFFFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = 0; i < width; i++)
|
||||
{
|
||||
dst[dstaddr] = 0;
|
||||
dstaddr = (dstaddr + 1) & 0xFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // sources A+B
|
||||
case 3:
|
||||
{
|
||||
u32 eva = DispCnt & 0x1F;
|
||||
u32 evb = (DispCnt >> 8) & 0x1F;
|
||||
|
||||
// checkme
|
||||
if (eva > 16) eva = 16;
|
||||
if (evb > 16) evb = 16;
|
||||
|
||||
if (srcB)
|
||||
{
|
||||
for (u32 i = 0; i < width; i++)
|
||||
{
|
||||
u32 val = src[i];
|
||||
|
||||
// TODO: check what happens when alpha=0
|
||||
|
||||
u32 rA = (val >> 1) & 0x1F;
|
||||
u32 gA = (val >> 9) & 0x1F;
|
||||
u32 bA = (val >> 17) & 0x1F;
|
||||
u32 aA = ((val >> 24) != 0) ? 1 : 0;
|
||||
|
||||
val = srcB[srcBaddr];
|
||||
|
||||
u32 rB = val & 0x1F;
|
||||
u32 gB = (val >> 5) & 0x1F;
|
||||
u32 bB = (val >> 10) & 0x1F;
|
||||
u32 aB = val >> 15;
|
||||
|
||||
u32 rD = ((rA * aA * eva) + (rB * aB * evb)) >> 4;
|
||||
u32 gD = ((gA * aA * eva) + (gB * aB * evb)) >> 4;
|
||||
u32 bD = ((bA * aA * eva) + (bB * aB * evb)) >> 4;
|
||||
u32 aD = (eva>0 ? aA : 0) | (evb>0 ? aB : 0);
|
||||
|
||||
dst[dstaddr] = rD | (gD << 5) | (bD << 10) | (aD << 15);
|
||||
srcBaddr = (srcBaddr + 1) & 0xFFFF;
|
||||
dstaddr = (dstaddr + 1) & 0xFFFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = 0; i < width; i++)
|
||||
{
|
||||
u32 val = src[i];
|
||||
|
||||
// TODO: check what happens when alpha=0
|
||||
|
||||
u32 rA = (val >> 1) & 0x1F;
|
||||
u32 gA = (val >> 9) & 0x1F;
|
||||
u32 bA = (val >> 17) & 0x1F;
|
||||
u32 aA = ((val >> 24) != 0) ? 1 : 0;
|
||||
|
||||
u32 rD = (rA * aA * eva) >> 4;
|
||||
u32 gD = (gA * aA * eva) >> 4;
|
||||
u32 bD = (bA * aA * eva) >> 4;
|
||||
u32 aD = (eva>0 ? aA : 0);
|
||||
|
||||
dst[dstaddr] = rD | (gD << 5) | (bD << 10) | (aD << 15);
|
||||
dstaddr = (dstaddr + 1) & 0xFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -709,8 +879,8 @@ void GPU2D::DrawBG_Extended(u32 line, u32* dst, u32 bgnum)
|
|||
{
|
||||
// bitmap modes
|
||||
|
||||
if (Num) tilesetaddr = 0x06200000 + ((bgcnt & 0x003C) << 12);
|
||||
else tilesetaddr = 0x06000000 + ((bgcnt & 0x003C) << 12);
|
||||
if (Num) tilemapaddr = 0x06200000 + ((bgcnt & 0x1F00) << 6);
|
||||
else tilemapaddr = 0x06000000 + ((bgcnt & 0x1F00) << 6);
|
||||
|
||||
coordmask |= 0x7FF;
|
||||
|
||||
|
@ -722,7 +892,7 @@ void GPU2D::DrawBG_Extended(u32 line, u32* dst, u32 bgnum)
|
|||
{
|
||||
if (!((rotX|rotY) & overflowmask))
|
||||
{
|
||||
u16 color = GPU::ReadVRAM_BG<u16>(tilesetaddr + (((((rotY & coordmask) >> 8) << yshift) + ((rotX & coordmask) >> 8)) << 1));
|
||||
u16 color = GPU::ReadVRAM_BG<u16>(tilemapaddr + (((((rotY & coordmask) >> 8) << yshift) + ((rotX & coordmask) >> 8)) << 1));
|
||||
|
||||
if (color & 0x8000)
|
||||
drawpixelfn(bgnum, &dst[i], color, BlendFunc);
|
||||
|
@ -743,7 +913,7 @@ void GPU2D::DrawBG_Extended(u32 line, u32* dst, u32 bgnum)
|
|||
{
|
||||
if (!((rotX|rotY) & overflowmask))
|
||||
{
|
||||
u8 color = GPU::ReadVRAM_BG<u8>(tilesetaddr + (((rotY & coordmask) >> 8) << yshift) + ((rotX & coordmask) >> 8));
|
||||
u8 color = GPU::ReadVRAM_BG<u8>(tilemapaddr + (((rotY & coordmask) >> 8) << yshift) + ((rotX & coordmask) >> 8));
|
||||
|
||||
if (color)
|
||||
drawpixelfn(bgnum, &dst[i], pal[color], BlendFunc);
|
||||
|
|
6
GPU2D.h
6
GPU2D.h
|
@ -63,6 +63,10 @@ private:
|
|||
s16 BGRotD[2];
|
||||
|
||||
u32 BlendFunc;
|
||||
u8 EVA, EVB;
|
||||
u8 EVY;
|
||||
|
||||
u32 CaptureCnt;
|
||||
|
||||
u16 MasterBrightness;
|
||||
|
||||
|
@ -84,6 +88,8 @@ private:
|
|||
void DrawSprites(u32 line, u32* dst);
|
||||
void DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, u32 ypos, u32* dst);
|
||||
void DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, u32 ypos, u32* dst);
|
||||
|
||||
void DoCapture(u32 line, u32 width, u32* src);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
1
NDS.cpp
1
NDS.cpp
|
@ -1648,6 +1648,7 @@ void ARM9IOWrite32(u32 addr, u32 val)
|
|||
switch (addr)
|
||||
{
|
||||
case 0x04000060: return;
|
||||
case 0x04000064: GPU::GPU2D_A->Write32(addr, val); return;
|
||||
|
||||
case 0x040000B0: DMAs[0]->SrcAddr = val; return;
|
||||
case 0x040000B4: DMAs[0]->DstAddr = val; return;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
1481161027 c:\documents\sources\melonds\types.h
|
||||
|
||||
1488393021 source:c:\documents\sources\melonds\nds.cpp
|
||||
1488396811 source:c:\documents\sources\melonds\nds.cpp
|
||||
<stdio.h>
|
||||
<string.h>
|
||||
"NDS.h"
|
||||
|
@ -93,7 +93,7 @@
|
|||
"NDS.h"
|
||||
"GPU.h"
|
||||
|
||||
1488392627 c:\documents\sources\melonds\gpu2d.h
|
||||
1488398363 c:\documents\sources\melonds\gpu2d.h
|
||||
|
||||
1481040524 c:\documents\sources\melonds\wifi.h
|
||||
|
||||
|
|
Loading…
Reference in New Issue