- added to capture display support for 3D and blend sources A+B capturing;
This commit is contained in:
mtabachenko 2008-12-23 21:16:27 +00:00
parent 0eff66ec25
commit 5d48cdbca9
4 changed files with 86 additions and 6 deletions

View File

@ -2047,7 +2047,7 @@ void GPU_set_DISPCAPCNT(u32 val)
}
/*INFO("Capture 0x%X:\n EVA=%i, EVB=%i, wBlock=%i, wOffset=%i, capX=%i, capY=%i\n rBlock=%i, rOffset=%i, srcCap=%i, dst=0x%X, src=0x%X\n srcA=%i, srcB=%i\n\n",
val, gpu->dispCapCnt.EVA, gpu->dispCapCnt.EVB, gpu->dispCapCnt.writeBlock, gpu->dispCapCnt.writeOffset,
val, gpu->dispCapCnt.EVA, gpu->dispCapCnt.EVB, gpu->dispCapCnt.writeBlock, gpu->dispCapCnt.writeOffset,
gpu->dispCapCnt.capx, gpu->dispCapCnt.capy, gpu->dispCapCnt.readBlock, gpu->dispCapCnt.readOffset,
gpu->dispCapCnt.capSrc, gpu->dispCapCnt.dst - ARM9Mem.ARM9_LCD, gpu->dispCapCnt.src - ARM9Mem.ARM9_LCD,
gpu->dispCapCnt.srcA, gpu->dispCapCnt.srcB);*/
@ -2232,10 +2232,9 @@ static INLINE void GPU_ligne_DispCapture(u16 l)
{
//INFO("Capture 3D\n");
u16 cap3DLine[512];
memset(cap3DLine, 0, 512);
//gpu3D->NDS_3D_GetLine (l, (u16*)cap3DLine);
gpu3D->NDS_3D_GetLineCaptured(l, (u16*)cap3DLine);
for (int i = 0; i < gpu->dispCapCnt.capx; i++)
T2WriteWord(cap_dst, i << 1, T2ReadWord((u8 *)cap3DLine, i << 1) | (1<<15));
T2WriteWord(cap_dst, i << 1, (u16)cap3DLine[i]);
}
break;
}
@ -2265,6 +2264,53 @@ static INLINE void GPU_ligne_DispCapture(u16 l)
default: // Capture source is SourceA+B blended
{
//INFO("Capture source is SourceA+B blended\n");
u16 *srcA = NULL;
u16 *srcB = NULL;
u16 cap3DLine[512];
if (gpu->dispCapCnt.srcA == 0) // Capture screen (BG + OBJ + 3D)
srcA = (u16 *)(GPU_screen) + (MainScreen.offset + l) * 512;
else
{
gpu3D->NDS_3D_GetLineCaptured(l, (u16*)cap3DLine);
srcA = (u16 *)cap3DLine; // 3D screen
}
if (gpu->dispCapCnt.srcB == 0) // VRAM screen
srcB = (u16 *)(gpu->dispCapCnt.src) + (l * 512);
else
srcB = NULL; // DISP FIFOS
if ((srcA) && (srcB))
{
u16 a, r, g, b;
for(u16 i = 0; i < gpu->dispCapCnt.capx; i++)
{
a = r = g = b =0;
if (gpu->dispCapCnt.EVA && (srcA[i] & 0x8000))
{
a = 0x8000;
r = ((srcA[i] & 0x1F) * gpu->dispCapCnt.EVA);
g = (((srcA[i] >> 5) & 0x1F) * gpu->dispCapCnt.EVA);
b = (((srcA[i] >> 10) & 0x1F) * gpu->dispCapCnt.EVA);
}
if (gpu->dispCapCnt.EVB && (srcB[i] & 0x8000))
{
a = 0x8000;
r += ((srcB[i] & 0x1F) * gpu->dispCapCnt.EVB);
g += (((srcB[i] >> 5) & 0x1F) * gpu->dispCapCnt.EVB);
b += (((srcB[i] >> 10) & 0x1F) * gpu->dispCapCnt.EVB);
}
r >>= 4;
g >>= 4;
b >>= 4;
T2WriteWord(cap_dst, i << 1, (u16)(a | (b << 10) | (g << 5) | r));
}
}
}
break;
}

View File

@ -1062,7 +1062,6 @@ static void Control()
}
}
static void Render()
{
if(!BEGINGL()) return;
@ -1183,6 +1182,36 @@ static void GL_ReadFramebuffer()
//}
}
static void GetLineCaptured(int line, u16* dst)
{
if(needRefreshFramebuffer) {
needRefreshFramebuffer = false;
GL_ReadFramebuffer();
}
u8 *screen3D = (u8*)GPU_screen3D+((191-line)<<10);
u8 *screenStencil = (u8*)GPU_screenStencil+((191-line)<<8);
for(int i = 0; i < 256; i++)
{
u32 stencil = screenStencil[i];
if(!stencil)
{
dst[i] = 0x0000;
continue;
}
int t=i<<2;
u32 r = screen3D[t+0];
u32 g = screen3D[t+1];
u32 b = screen3D[t+2];
dst[i] = ((b>>3)<<10) | ((g>>3)<<5) | (r>>3) | 0x8000;
}
}
//NHerve mod3 - Fixed blending with 2D backgrounds (New Super Mario Bros looks better)
//zeromus post-mod3: fix even better
static void GetLine (int line, u16* dst)
@ -1252,7 +1281,8 @@ GPU3DInterface gpu3Dgl = {
Close,
Render,
VramReconfigureSignal,
GetLine
GetLine,
GetLineCaptured
};

View File

@ -31,6 +31,7 @@ GPU3DInterface gpu3DNull = {
NDS_nullFunc1, //NDS_3D_Render
NDS_nullFunc1, //NDS_3D_VramReconfigureSignal
NDS_nullFunc3, //NDS_3D_GetLine
NDS_nullFunc3 //NDS_3D_GetLineCaptured
};
GPU3DInterface *gpu3D = &gpu3DNull;

View File

@ -43,6 +43,9 @@ typedef struct Render3DInterface
//Retrieves a line of color buffer data
void (CALL_CONVENTION* NDS_3D_GetLine) (int line, unsigned short* dst);
//Retrieves a line of color buffer data for capture
void (CALL_CONVENTION* NDS_3D_GetLineCaptured) (int line, unsigned short* dst);
} GPU3DInterface;