* 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(BGRotC, 0, 2*2);
|
||||||
memset(BGRotD, 0, 2*2);
|
memset(BGRotD, 0, 2*2);
|
||||||
|
|
||||||
|
CaptureCnt = 0;
|
||||||
|
|
||||||
MasterBrightness = 0;
|
MasterBrightness = 0;
|
||||||
|
|
||||||
BGExtPalStatus[0] = 0;
|
BGExtPalStatus[0] = 0;
|
||||||
|
@ -205,6 +207,12 @@ void GPU2D::Write32(u32 addr, u32 val)
|
||||||
if (val & 0x08000000) val |= 0xF0000000;
|
if (val & 0x08000000) val |= 0xF0000000;
|
||||||
BGYCenter[1] = val;
|
BGYCenter[1] = val;
|
||||||
return;
|
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);
|
Write16(addr, val&0xFFFF);
|
||||||
|
@ -264,11 +272,27 @@ void GPU2D::DrawScanline(u32 line)
|
||||||
|
|
||||||
case 3: // FIFO display
|
case 3: // FIFO display
|
||||||
{
|
{
|
||||||
// uh, is there even anything that uses this?
|
// TODO
|
||||||
}
|
}
|
||||||
break;
|
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
|
// master brightness
|
||||||
if (dispmode != 0)
|
if (dispmode != 0)
|
||||||
{
|
{
|
||||||
|
@ -325,7 +349,153 @@ void GPU2D::DrawScanline(u32 line)
|
||||||
|
|
||||||
void GPU2D::VBlank()
|
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
|
// bitmap modes
|
||||||
|
|
||||||
if (Num) tilesetaddr = 0x06200000 + ((bgcnt & 0x003C) << 12);
|
if (Num) tilemapaddr = 0x06200000 + ((bgcnt & 0x1F00) << 6);
|
||||||
else tilesetaddr = 0x06000000 + ((bgcnt & 0x003C) << 12);
|
else tilemapaddr = 0x06000000 + ((bgcnt & 0x1F00) << 6);
|
||||||
|
|
||||||
coordmask |= 0x7FF;
|
coordmask |= 0x7FF;
|
||||||
|
|
||||||
|
@ -722,7 +892,7 @@ void GPU2D::DrawBG_Extended(u32 line, u32* dst, u32 bgnum)
|
||||||
{
|
{
|
||||||
if (!((rotX|rotY) & overflowmask))
|
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)
|
if (color & 0x8000)
|
||||||
drawpixelfn(bgnum, &dst[i], color, BlendFunc);
|
drawpixelfn(bgnum, &dst[i], color, BlendFunc);
|
||||||
|
@ -743,7 +913,7 @@ void GPU2D::DrawBG_Extended(u32 line, u32* dst, u32 bgnum)
|
||||||
{
|
{
|
||||||
if (!((rotX|rotY) & overflowmask))
|
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)
|
if (color)
|
||||||
drawpixelfn(bgnum, &dst[i], pal[color], BlendFunc);
|
drawpixelfn(bgnum, &dst[i], pal[color], BlendFunc);
|
||||||
|
|
6
GPU2D.h
6
GPU2D.h
|
@ -63,6 +63,10 @@ private:
|
||||||
s16 BGRotD[2];
|
s16 BGRotD[2];
|
||||||
|
|
||||||
u32 BlendFunc;
|
u32 BlendFunc;
|
||||||
|
u8 EVA, EVB;
|
||||||
|
u8 EVY;
|
||||||
|
|
||||||
|
u32 CaptureCnt;
|
||||||
|
|
||||||
u16 MasterBrightness;
|
u16 MasterBrightness;
|
||||||
|
|
||||||
|
@ -84,6 +88,8 @@ private:
|
||||||
void DrawSprites(u32 line, u32* dst);
|
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_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 DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, u32 ypos, u32* dst);
|
||||||
|
|
||||||
|
void DoCapture(u32 line, u32 width, u32* src);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
1
NDS.cpp
1
NDS.cpp
|
@ -1648,6 +1648,7 @@ void ARM9IOWrite32(u32 addr, u32 val)
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x04000060: return;
|
case 0x04000060: return;
|
||||||
|
case 0x04000064: GPU::GPU2D_A->Write32(addr, val); return;
|
||||||
|
|
||||||
case 0x040000B0: DMAs[0]->SrcAddr = val; return;
|
case 0x040000B0: DMAs[0]->SrcAddr = val; return;
|
||||||
case 0x040000B4: DMAs[0]->DstAddr = val; return;
|
case 0x040000B4: DMAs[0]->DstAddr = val; return;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
1481161027 c:\documents\sources\melonds\types.h
|
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>
|
<stdio.h>
|
||||||
<string.h>
|
<string.h>
|
||||||
"NDS.h"
|
"NDS.h"
|
||||||
|
@ -93,7 +93,7 @@
|
||||||
"NDS.h"
|
"NDS.h"
|
||||||
"GPU.h"
|
"GPU.h"
|
||||||
|
|
||||||
1488392627 c:\documents\sources\melonds\gpu2d.h
|
1488398363 c:\documents\sources\melonds\gpu2d.h
|
||||||
|
|
||||||
1481040524 c:\documents\sources\melonds\wifi.h
|
1481040524 c:\documents\sources\melonds\wifi.h
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue