diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp index 88eecb41a..52ca3fb6d 100644 --- a/desmume/src/GPU.cpp +++ b/desmume/src/GPU.cpp @@ -2510,8 +2510,7 @@ static void GPU_ligne_layer(NDS_Screen * screen, u16 l) } } -// TODO: capture emulated not fully -static void GPU_ligne_DispCapture(u16 l) +template static void GPU_ligne_DispCapture(u16 l) { //this macro takes advantage of the fact that there are only two possible values for capx #define CAPCOPY(SRC,DST) \ @@ -2557,110 +2556,111 @@ static void GPU_ligne_DispCapture(u16 l) u8* cap_src = ARM9Mem.ARM9_LCD + cap_src_adr; u8* cap_dst = ARM9Mem.ARM9_LCD + cap_dst_adr; + if(!SKIP) if (l < gpu->dispCapCnt.capy) - { - switch (gpu->dispCapCnt.capSrc) { - case 0: // Capture source is SourceA - { - //INFO("Capture source is SourceA\n"); - switch (gpu->dispCapCnt.srcA) + switch (gpu->dispCapCnt.capSrc) + { + case 0: // Capture source is SourceA { - case 0: // Capture screen (BG + OBJ + 3D) - { - //INFO("Capture screen (BG + OBJ + 3D)\n"); - - u8 *src; - src = (u8*)(GPU_tempScanline); - CAPCOPY(src,cap_dst); - } - break; - case 1: // Capture 3D - { - //INFO("Capture 3D\n"); - u16* colorLine; - gfx3d_GetLineData(l, &colorLine, NULL); - CAPCOPY(((u8*)colorLine),cap_dst); - } - break; - } - } - break; - case 1: // Capture source is SourceB - { - //INFO("Capture source is SourceB\n"); - switch (gpu->dispCapCnt.srcB) - { - case 0: // Capture VRAM - { - //INFO("Capture VRAM\n"); - CAPCOPY(cap_src,cap_dst); - } - break; - case 1: // Capture Main Memory Display FIFO - { - //INFO("Capture Main Memory Display FIFO\n"); - } - break; - } - } - break; - default: // Capture source is SourceA+B blended - { - //INFO("Capture source is SourceA+B blended\n"); - u16 *srcA = NULL; - u16 *srcB = NULL; - - if (gpu->dispCapCnt.srcA == 0) - { - // Capture screen (BG + OBJ + 3D) - srcA = (u16*)(GPU_tempScanline); - } - else - { - gfx3d_GetLineData(l, &srcA, NULL); - } - - if (gpu->dispCapCnt.srcB == 0) // VRAM screen - srcB = (u16 *)cap_src; - else - srcB = NULL; // DISP FIFOS - - if ((srcA) && (srcB)) - { - u16 a, r, g, b; - const int todo = (gpu->dispCapCnt.capx==DISPCAPCNT::_128?128:256); - for(u16 i = 0; i < todo; i++) + //INFO("Capture source is SourceA\n"); + switch (gpu->dispCapCnt.srcA) { - a = r = g = b =0; + case 0: // Capture screen (BG + OBJ + 3D) + { + //INFO("Capture screen (BG + OBJ + 3D)\n"); - 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)); + u8 *src; + src = (u8*)(GPU_tempScanline); + CAPCOPY(src,cap_dst); + } + break; + case 1: // Capture 3D + { + //INFO("Capture 3D\n"); + u16* colorLine; + gfx3d_GetLineData(l, &colorLine, NULL); + CAPCOPY(((u8*)colorLine),cap_dst); + } + break; } } - } - break; + break; + case 1: // Capture source is SourceB + { + //INFO("Capture source is SourceB\n"); + switch (gpu->dispCapCnt.srcB) + { + case 0: // Capture VRAM + { + //INFO("Capture VRAM\n"); + CAPCOPY(cap_src,cap_dst); + } + break; + case 1: // Capture Main Memory Display FIFO + { + //INFO("Capture Main Memory Display FIFO\n"); + } + break; + } + } + break; + default: // Capture source is SourceA+B blended + { + //INFO("Capture source is SourceA+B blended\n"); + u16 *srcA = NULL; + u16 *srcB = NULL; + + if (gpu->dispCapCnt.srcA == 0) + { + // Capture screen (BG + OBJ + 3D) + srcA = (u16*)(GPU_tempScanline); + } + else + { + gfx3d_GetLineData(l, &srcA, NULL); + } + + if (gpu->dispCapCnt.srcB == 0) // VRAM screen + srcB = (u16 *)cap_src; + else + srcB = NULL; // DISP FIFOS + + if ((srcA) && (srcB)) + { + u16 a, r, g, b; + const int todo = (gpu->dispCapCnt.capx==DISPCAPCNT::_128?128:256); + for(u16 i = 0; i < todo; 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; + } } - } if (l>=191) { @@ -2810,7 +2810,7 @@ void GPU::update_winh(int WIN_NUM) } } -void GPU_ligne(NDS_Screen * screen, u16 l) +void GPU_ligne(NDS_Screen * screen, u16 l, bool skip) { GPU * gpu = screen->gpu; @@ -2830,6 +2830,17 @@ void GPU_ligne(NDS_Screen * screen, u16 l) gpu->refreshAffineStartRegs(-1,-1); } + if(skip) + { + gpu->currLine = l; + if (gpu->core == GPU_MAIN) + { + GPU_ligne_DispCapture(l); + if (l == 191) { disp_fifo.head = disp_fifo.tail = 0; } + } + return; + } + //if(gpu->core == 1) // printf("%d\n",l); @@ -2848,7 +2859,7 @@ void GPU_ligne(NDS_Screen * screen, u16 l) //} //cache some parameters which are assumed to be stable throughout the rendering of the entire line - gpu->currLine = (u8)l; + gpu->currLine = l; u16 mosaic_control = T1ReadWord((u8 *)&gpu->dispx_st->dispx_MISC.MOSAIC, 0); u16 mosaic_width = (mosaic_control & 0xF); u16 mosaic_height = ((mosaic_control>>4) & 0xF); @@ -2874,7 +2885,7 @@ void GPU_ligne(NDS_Screen * screen, u16 l) if (gpu->core == GPU_MAIN) { - GPU_ligne_DispCapture(l); + GPU_ligne_DispCapture(l); if (l == 191) { disp_fifo.head = disp_fifo.tail = 0; } } diff --git a/desmume/src/GPU.h b/desmume/src/GPU.h index 4fc28e68d..c2bd7830b 100644 --- a/desmume/src/GPU.h +++ b/desmume/src/GPU.h @@ -931,7 +931,7 @@ void GPU_addBack(GPU *, u8 num); int GPU_ChangeGraphicsCore(int coreid); void GPU_set_DISPCAPCNT(u32 val) ; -void GPU_ligne(NDS_Screen * screen, u16 l) ; +void GPU_ligne(NDS_Screen * screen, u16 l, bool skip = false) ; void GPU_setMasterBrightness (GPU *gpu, u16 val); inline void GPU_setWIN0_H(GPU* gpu, u16 val) { gpu->WIN0H0 = val >> 8; gpu->WIN0H1 = val&0xFF; gpu->need_update_winh[0] = true; } diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index dc54a8b7c..f3072e06e 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -1806,11 +1806,8 @@ void execHardware_hblank() //in practice we need to be more forgiving, in case things have overrun the scanline start. //this should be safe since games cannot do anything timing dependent until this next //scanline begins, anyway (as this scanline was in the middle of drawing) - if(!SkipCur2DFrame) - { - GPU_ligne(&MainScreen, nds.VCount); - GPU_ligne(&SubScreen, nds.VCount); - } + GPU_ligne(&MainScreen, nds.VCount, SkipCur2DFrame); + GPU_ligne(&SubScreen, nds.VCount, SkipCur2DFrame); //trigger hblank dmas //but notice, we do that just after we finished drawing the line diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index 507570893..5e2b8c65f 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -940,7 +940,6 @@ DWORD WINAPI run() if(!skipnextframe) { - framesskipped = 0; if (framestoskip > 0)