diff --git a/zsnes/src/gui/gui.asm b/zsnes/src/gui/gui.asm index 3bb6b5c1..ab5e113c 100644 --- a/zsnes/src/gui/gui.asm +++ b/zsnes/src/gui/gui.asm @@ -171,6 +171,10 @@ EXTSYM TCPIPGetByte,GUIBIFIL EXTSYM ModemSendChar EXTSYM firstsaveinc EXTSYM nssdip1,nssdip2,nssdip3,nssdip4,nssdip5,nssdip6 +%ifndef __MSDOS__ +EXTSYM GUIMBVID +%endif + %ifdef __LINUX__ EXTSYM numlockptr %endif @@ -597,6 +601,7 @@ NEWSYM SoundInterpType, db 1 NEWSYM KeyDisplayFPS, dd 0 NEWSYM KeyIncStateSlot, dd 0 NEWSYM KeyDecStateSlot, dd 0 +NEWSYM MotionBlur, dd 0 GUIsave equ $-GUIRAdd diff --git a/zsnes/src/gui/guikeys.inc b/zsnes/src/gui/guikeys.inc index c9ad7478..e56b042d 100644 --- a/zsnes/src/gui/guikeys.inc +++ b/zsnes/src/gui/guikeys.inc @@ -1158,6 +1158,13 @@ GUIVideoKeys: je .nohiresmode7 xor byte[Mode7HiRes16b],1 .nohiresmode7 + cmp dh,'M' + jne .nomotionblur + xor ebx,ebx + cmp byte[GUIMBVID+ebx],0 + je .nomotionblur + xor byte[MotionBlur],1 +.nomotionblur cmp dh,'B' jne .nobilinearfilter xor ebx,ebx diff --git a/zsnes/src/gui/guimouse.inc b/zsnes/src/gui/guimouse.inc index 8390e54c..45d6e3d8 100644 --- a/zsnes/src/gui/guimouse.inc +++ b/zsnes/src/gui/guimouse.inc @@ -2254,6 +2254,10 @@ DisplayGUIVideoClick: je .nocheckboxtm7 GUIClickCButton5 11,173,byte[Mode7HiRes16b],1 .nocheckboxtm7 + cmp byte[GUIMBVID+ebx],0 + je .nocheckboxtmb + GUIClickCButton5 11,173,byte[MotionBlur],1 +.nocheckboxtmb xor ebx,ebx mov bl,[cvidmode] cmp byte[GUIHSVID+ebx],0 diff --git a/zsnes/src/gui/guiwindp.inc b/zsnes/src/gui/guiwindp.inc index 56808176..ba7daa30 100644 --- a/zsnes/src/gui/guiwindp.inc +++ b/zsnes/src/gui/guiwindp.inc @@ -1742,6 +1742,10 @@ DisplayGUIVideo: je .notext8 GUIOuttextwin2u 5,26,178,GUIVideoText8b,0 .notext8 + cmp byte[GUIMBVID+eax],0 + je .notext82 + GUIOuttextwin2u 5,26,178,GUIVideoText8b2,0 +.notext82 GUIOuttextwin2u 5,26,188,GUIVideoText8c,0 %ifndef __LINUX__ GUIOuttextwin2u 5,130,188,GUIVideoText9,0 @@ -1843,6 +1847,10 @@ DisplayGUIVideo: je .notext8b GUIOuttextwin2 5,25,177,GUIVideoText8b .notext8b + cmp byte[GUIMBVID+eax],0 + je .notext8b2 + GUIOuttextwin2 5,25,177,GUIVideoText8b2 +.notext8b2 GUIOuttextwin2 5,25,187,GUIVideoText8c %ifndef __LINUX__ GUIOuttextwin2 5,129,187,GUIVideoText9 @@ -1968,13 +1976,22 @@ DisplayGUIVideo: .nocheckbox1m72 GUIDisplayIconWin 5,11,173,[GUITemp] .nocheckboxm72 + cmp byte[GUIMBVID+eax],0 + je .nocheckboxmb2 + mov dword[GUITemp],GUIIconDataCheckBoxUC + cmp byte[MotionBlur],0 + je .nocheckboxmb + mov dword[GUITemp],GUIIconDataCheckBoxC +.nocheckboxmb + GUIDisplayIconWin 5,11,173,[GUITemp] +.nocheckboxmb2 mov dword[GUITemp],GUIIconDataCheckBoxUC cmp byte[GrayscaleMode],0 je .nocheckboxm73 mov dword[GUITemp],GUIIconDataCheckBoxC .nocheckboxm73 GUIDisplayIconWin 5,11,183,[GUITemp] -%ifndef __LINUX__ +%ifndef __LINUX__s mov dword[GUITemp],GUIIconDataCheckBoxUC cmp byte[vsyncon],0 je .nocheckboxm74 @@ -2138,6 +2155,7 @@ GUIVideoText5b db 'WIDE SCREEN',0 ; -c GUIVideoText6 db 'SMALL SCREEN',0 ; -c GUIVideoText7 db 'TRIPLE BUFFERING',0 ; -c GUIVideoText8b db 'HI-RESOLUTION MODE7',0 ; -c +GUIVideoText8b2 db 'MOTION BLUR',0 ; -c GUIVideoText8c db 'GRAYSCALE MODE',0 ; -c GUIVideoText8 db 'SET',0 ; set button GUIVideoText9 db 'VSYNC',0 ; -c diff --git a/zsnes/src/video/sw_draw.asm b/zsnes/src/video/sw_draw.asm index 0111e6a0..38d6687a 100644 --- a/zsnes/src/video/sw_draw.asm +++ b/zsnes/src/video/sw_draw.asm @@ -132,41 +132,149 @@ NEWSYM DrawWin256x224x16 popad ret +EXTSYM copymaskRB,copymaskG,copymagic + NEWSYM DrawWin256x224x32 pushad mov ax,ds mov es,ax xor eax,eax -%ifdef __WIN32__ - mov ebx, [BitConv32Ptr] -%endif mov esi, [ScreenPtr] mov edi, [SurfBufD] + movq mm4, [copymaskRB] + movq mm5, [copymaskG] + movq mm6, [copymagic] .Copying32b: - mov ecx,256 - push eax - xor eax,eax + mov ecx,64 .CopyLoop32b: - mov ax,[esi] - add esi,2 - mov edx,[ebx+eax*4] - mov [edi],edx - add edi,4 + movq mm0, [esi] + movq mm1,mm0 + punpcklwd mm0,mm0 + movq mm2,mm0 + pand mm0,mm4 + pmaddwd mm0,mm6 + punpckhwd mm1,mm1 + movq mm3,mm1 + pand mm1,mm4 + pmaddwd mm1,mm6 + pslld mm2,5 + pslld mm3,5 + pand mm2,mm5 + pand mm3,mm5 + por mm0,mm2 + add esi,8 + por mm1,mm3 + movq [edi],mm0 + movq [edi+8],mm1 + add edi,16 dec ecx jnz .CopyLoop32b - pop eax inc eax add edi, [pitch] sub edi,1024 sub esi,512 add esi,576 -%ifdef __WIN32__ cmp eax,239 -%else - cmp eax,223 -%endif jne .Copying32b popad + emms + ret + +EXTSYM blur_buffer,blur_temp,coef + +NEWSYM DrawWin256x224x32MB + pushad + mov ax,ds + mov es,ax + xor eax,eax + mov esi,[ScreenPtr] + mov edi,[blur_temp] + or edi,edi + jnz .blur_it2 + mov edi,[SurfBufD] +.blur_it2: + movq mm4, [copymaskRB] + movq mm5, [copymaskG] + movq mm6, [copymagic] +.Copying32b: + mov ecx,64 ;256 +.CopyLoop32b: + movq mm0,[esi] + movq mm1,mm0 + punpcklwd mm0,mm0 + movq mm2,mm0 + pand mm0,mm4 + pmaddwd mm0,mm6 + punpckhwd mm1,mm1 + movq mm3,mm1 + pand mm1,mm4 + pmaddwd mm1,mm6 + pslld mm2,5 + pslld mm3,5 + pand mm2,mm5 + pand mm3,mm5 + por mm0,mm2 + add esi, 8 + por mm1,mm3 + movq [edi],mm0 + movq [edi+8],mm1 + add edi,16 + dec ecx + jnz .CopyLoop32b + inc eax + add edi, [pitch] + sub edi,1024 + sub esi,512 + add esi,576 + cmp eax,239 + jne .Copying32b + mov esi, [blur_buffer] + or esi,esi + jz near .no_blur2 + mov edi,[SurfBufD] + mov ebx,[blur_temp] + add esi,256*240*4 + add edi,256*240*4 + add ebx,256*240*4 + mov ecx,-(256*240) + movq mm5, [coef] + pxor mm6,mm6 +.blur_loop2: + movq mm0, [esi+ecx*4] + movq mm1, mm0 + movq mm3, [ebx+ecx*4] + movq mm4, mm3 + punpcklbw mm0,mm6 + punpckhbw mm1,mm6 + punpcklbw mm3,mm6 + punpckhbw mm4,mm6 + movq mm2, mm3 + movq mm3, mm0 + punpcklwd mm0,mm2 + punpckhwd mm3,mm2 + movq mm2, mm4 + movq mm4, mm1 + punpcklwd mm1,mm2 + punpckhwd mm4,mm2 + pmaddwd mm0,mm5 + psrld mm0,8 + pmaddwd mm1,mm5 + psrld mm1,8 + pmaddwd mm3,mm5 + psrld mm3,8 + pmaddwd mm4,mm5 + psrld mm4,8 + packssdw mm0,mm3 + packssdw mm1,mm4 + packuswb mm0,mm1 + movq [esi+ecx*4],mm0 + movq [edi+ecx*4],mm0 + inc ecx + inc ecx + jnz .blur_loop2 +.no_blur2: + popad + emms ret NEWSYM DrawWin320x240x16 diff --git a/zsnes/src/win/winintrf.asm b/zsnes/src/win/winintrf.asm index 41e3f7db..7ad60339 100644 --- a/zsnes/src/win/winintrf.asm +++ b/zsnes/src/win/winintrf.asm @@ -1257,6 +1257,7 @@ NEWSYM GUIBIFIL, db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, NEWSYM GUITBWVID, db 0,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,1,1,1 ; Triple Buffering (Win) NEWSYM GUISMODE, db 0,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1,0,1,0,0,1,0,1,0,0 NEWSYM GUIDSMODE, db 0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1 +NEWSYM GUIMBVID, db 1,1,1,0,1,0,0,0,1,1,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,1,0,0,1,0,1,0,0 SECTION .text diff --git a/zsnes/src/win/winlink.cpp b/zsnes/src/win/winlink.cpp index 44905575..9ed209ae 100644 --- a/zsnes/src/win/winlink.cpp +++ b/zsnes/src/win/winlink.cpp @@ -130,7 +130,8 @@ extern "C" { DWORD MouseButton; DWORD SurfaceX=0; DWORD SurfaceY=0; - +VOID *blur_temp=0; +VOID *blur_buffer=0; } static char dinput8_dll[] = {"dinput8.dll\0"}; @@ -440,6 +441,8 @@ void ExitFunction() ReleaseDirectInput(); ReleaseDirectSound(); ReleaseDirectDraw(); + if (blur_temp) free(blur_temp); + if (blur_buffer) free(blur_buffer); FreeLibrary(hM_dsound); FreeLibrary(hM_ddraw); FreeLibrary(hM_dinput8); @@ -1364,6 +1367,11 @@ int InitDirectDraw() return FALSE; } + if (!blur_buffer) blur_buffer = malloc(SurfaceX * SurfaceY * (BitDepth == 16 ? 2 : 4)); + else blur_buffer = realloc(blur_buffer, SurfaceX * SurfaceY * (BitDepth == 16 ? 2 : 4)); + if (!blur_temp) blur_temp = malloc(SurfaceX * SurfaceY * (BitDepth == 16 ? 2 : 4)); + else blur_temp = realloc(blur_temp, SurfaceX * SurfaceY * (BitDepth == 16 ? 2 : 4)); + return TRUE; } @@ -2044,8 +2052,16 @@ void clearwin() extern void DrawWin256x224x16(); extern void DrawWin256x224x32(); +extern void DrawWin256x224x32MB(); extern void DrawWin320x240x16(); +extern _int64 copymaskRB = 0x001FF800001FF800; +extern _int64 copymaskG = 0x0000FC000000FC00; +extern _int64 copymagic = 0x0008010000080100; +extern _int64 coef = 0x0066009a0066009a; + +extern BYTE MotionBlur; + void drawscreenwin(void) { DWORD i,j,color32; @@ -2104,8 +2120,9 @@ void drawscreenwin(void) } case 32: { - DrawWin256x224x32(); - break; + if (MotionBlur == 1) DrawWin256x224x32MB(); + else DrawWin256x224x32(); + break; } SURFDW=(DWORD *) &SurfBuf[(resolutn-1)*pitch];