diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp index a4e8d7296..0d77f04dc 100644 --- a/desmume/src/GPU.cpp +++ b/desmume/src/GPU.cpp @@ -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; } diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index 0911e84ef..84c392deb 100644 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -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 }; diff --git a/desmume/src/render3D.cpp b/desmume/src/render3D.cpp index dc6324c48..85352a30a 100644 --- a/desmume/src/render3D.cpp +++ b/desmume/src/render3D.cpp @@ -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; diff --git a/desmume/src/render3D.h b/desmume/src/render3D.h index 0f05b1df2..8ff6ef749 100644 --- a/desmume/src/render3D.h +++ b/desmume/src/render3D.h @@ -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;