diff --git a/zsnes/src/gui/gui.asm b/zsnes/src/gui/gui.asm index f9fa8db3..cbef9d06 100644 --- a/zsnes/src/gui/gui.asm +++ b/zsnes/src/gui/gui.asm @@ -176,6 +176,7 @@ EXTSYM numlockptr %ifdef __WIN32__ EXTSYM CheckPriority EXTSYM CheckAlwaysOnTop +EXTSYM initDirectDraw %endif NEWSYM GuiAsmStart diff --git a/zsnes/src/gui/guikeys.inc b/zsnes/src/gui/guikeys.inc index 5e8dab5d..221b0ec1 100644 --- a/zsnes/src/gui/guikeys.inc +++ b/zsnes/src/gui/guikeys.inc @@ -818,6 +818,13 @@ GUIOptionKeys: xor byte[vsyncon],1 mov al,[vsyncon] mov [cfgvsync],al +%ifdef __WIN32__ + cmp byte[OverlayEnabled],1 + jne .novsync + pushad + call initDirectDraw + popad +%endif .novsync %endif cmp dh,'M' @@ -892,6 +899,9 @@ GUIOptionKeys: cmp dh,'Y' jne .nooverlay xor byte[OverlayEnabled],1 + pushad + call initDirectDraw + popad .nooverlay cmp dh,'S' jne .noalttimer diff --git a/zsnes/src/gui/guimouse.inc b/zsnes/src/gui/guimouse.inc index 85843a15..7343e1dc 100644 --- a/zsnes/src/gui/guimouse.inc +++ b/zsnes/src/gui/guimouse.inc @@ -994,6 +994,24 @@ GUIWinClicked: %%noclick %endmacro +%ifdef __WIN32__ +%macro GUIClickCButtonov 3 + cmp eax,%1+1 + jl %%noclick + cmp edx,%2+3 + jl %%noclick + cmp eax,%1+6 + jg %%noclick + cmp edx,%2+8 + jg %%noclick + xor %3,1 + pushad + call initDirectDraw + popad +%%noclick +%endmacro +%endif + %macro GUIClickCButtonat 3 cmp eax,%1+1 jl %%noclick @@ -1133,6 +1151,32 @@ GUIWinClicked: %%noclick %endmacro +%ifndef __LINUX__ +%macro GUIClickCButton2ov 5 + cmp eax,%1+1 + jl %%noclick + cmp edx,%2+3 + jl %%noclick + cmp eax,%1+6 + jg %%noclick + cmp edx,%2+8 + jg %%noclick + xor %3,%5 + mov al,%3 + mov %4,al +%ifdef __WIN32__ + cmp byte[OverlayEnabled],1 + jne %%noinit + pushad + call initDirectDraw + popad +%%noinit +%endif + ret +%%noclick +%endmacro +%endif + %macro GUIClickCButton3 5 cmp eax,%1+1 jl %%noclick @@ -2100,7 +2144,7 @@ DisplayGUIOptionClick: GUIClickCButton2 11,36,byte[newengen],byte[cfgnewgfx],1 .invalidng %ifndef __LINUX__ - GUIClickCButton2 11,46,byte[vsyncon],byte[cfgvsync],1 + GUIClickCButton2ov 11,46,byte[vsyncon],byte[cfgvsync],1 %endif GUIClickCButton2 11,56,byte[FPUCopy],byte[cfgcopymethod],2 GUIClickCButtonM 11,66,byte[pl12s34] @@ -2120,7 +2164,7 @@ DisplayGUIOptionClick: GUIClickCButton 11,156,byte[AutoState] GUIClickCButton 11,166,byte[DontSavePath] %ifdef __WIN32__ - GUIClickCButton 11,176,byte[OverlayEnabled] + GUIClickCButtonov 11,176,byte[OverlayEnabled] GUIClickCButtonat 11,186,byte[AlternateTimer] %endif ; Frameskip = 0 diff --git a/zsnes/src/win/winlink.cpp b/zsnes/src/win/winlink.cpp index 908466cf..0419c48f 100644 --- a/zsnes/src/win/winlink.cpp +++ b/zsnes/src/win/winlink.cpp @@ -15,8 +15,6 @@ //along with this program; if not, write to the Free Software //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -#define OVERLAY_SUPPORT - #define DIRECTINPUT_VERSION 0x0800 #define DIRECTSOUND_VERSION 0x0800 @@ -46,9 +44,9 @@ DWORD FirstSound=1; int AllowDefault=0; int SoundEnabled=1; -#ifdef OVERLAY_SUPPORT +DWORD Overlay = 0; +DWORD Overlay_failed = 0; DWORD Overlay_Colorkey = 0; -#endif DWORD FirstActivate = 1; @@ -80,9 +78,7 @@ LPDIRECTDRAWSURFACE7 DD_Primary = NULL; LPDIRECTDRAWSURFACE7 DD_CFB = NULL; LPDIRECTDRAWSURFACE7 DD_BackBuffer = NULL; LPDIRECTDRAWCLIPPER lpDDClipper = NULL; -#ifdef OVERLAY_SUPPORT DDOVERLAYFX ddofx; -#endif RECT rcWindow; LPDIRECTINPUT8 DInput = NULL; @@ -154,6 +150,11 @@ extern "C" void drawscreenwin(void); DWORD LastUsedPos=0; DWORD CurMode=-1; + + void initDirectDraw() + { + InitDirectDraw(); + } } void DDrawError(){ @@ -165,18 +166,20 @@ void DDrawError(){ extern "C" BYTE vsyncon; extern "C" BYTE TripleBufferWin; +extern "C" BYTE OverlayEnabled; -void DrawScreen() +typedef DWORD (__fastcall* lpLockSurface)(); +DWORD __fastcall LockSurface_normal(); +DWORD __fastcall LockSurface_overlay(); +lpLockSurface LockSurface; + +typedef void (__fastcall* lpUnlockSurface)(); +void __fastcall UnlockSurface_normal(); +void __fastcall UnlockSurface_overlay(); +lpUnlockSurface UnlockSurface; + +void DrawScreen_normal() { -#ifdef OVERLAY_SUPPORT - if (vsyncon == 1) - { - if (DD_BackBuffer == NULL) InitDirectDraw(); - DD_CFB->Flip(NULL,DDFLIP_WAIT); - } - else - if (DD_BackBuffer) InitDirectDraw(); -#else if (vsyncon == 1) { if(FullScreen == 1) @@ -212,7 +215,12 @@ void DrawScreen() DD_Primary->Blt(&rcWindow, DD_CFB, NULL, DDBLT_WAIT, NULL); } } -#endif +} + +void DrawScreen_overlay() +{ + if (vsyncon == 1) + DD_CFB->Flip(NULL,DDFLIP_WAIT); } DWORD InputEn=0; @@ -275,6 +283,7 @@ extern "C" void CheckAlwaysOnTop() extern "C" void MinimizeWindow() { + if (Overlay && (DD_CFB)) DD_CFB->UpdateOverlay(NULL, DD_Primary, NULL, DDOVER_HIDE, NULL); ShowWindow(hMainWindow, SW_MINIMIZE); IsActivated = 0; } @@ -454,29 +463,30 @@ LRESULT CALLBACK Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_MOVE: break; case WM_PAINT: -#ifdef OVERLAY_SUPPORT - HDC hdc; - POINT pt; - RECT rc1; - struct tagPAINTSTRUCT ps; - DDBLTFX ddbfx; + if (Overlay && Overlay_Colorkey && (DD_Primary)) + { + HDC hdc; + POINT pt; + RECT rc1; + struct tagPAINTSTRUCT ps; + DDBLTFX ddbfx; - hdc = BeginPaint(hWnd, &ps); + hdc = BeginPaint(hWnd, &ps); - rc1 = ps.rcPaint; - ClientToScreen(hMainWindow, ( LPPOINT )&rc1 ); - ClientToScreen(hMainWindow, ( LPPOINT )&rc1 + 1 ); + rc1 = ps.rcPaint; + ClientToScreen(hMainWindow, ( LPPOINT )&rc1 ); + ClientToScreen(hMainWindow, ( LPPOINT )&rc1 + 1 ); - ddbfx.dwSize = sizeof(DDBLTFX); - ddbfx.dwFillColor = Overlay_Colorkey; + ddbfx.dwSize = sizeof(DDBLTFX); + ddbfx.dwFillColor = Overlay_Colorkey; - DD_Primary->Blt(&rc1, NULL, &rc1, DDBLT_COLORFILL | - DDBLT_WAIT, &ddbfx); + DD_Primary->Blt(&rc1, NULL, &rc1, DDBLT_COLORFILL | + DDBLT_WAIT, &ddbfx); - EndPaint(hWnd, &ps); -#else + EndPaint(hWnd, &ps); + } + else ValidateRect(hWnd,NULL); -#endif break; case WM_ACTIVATE: if (LOWORD(wParam) != WA_INACTIVE) @@ -484,11 +494,10 @@ LRESULT CALLBACK Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) IsActivated = 1; if(FirstActivate == 0) { -#ifdef OVERLAY_SUPPORT - ShowWindow(hMainWindow, SW_SHOWNORMAL); -#endif + if (Overlay == 1) + ShowWindow(hMainWindow, SW_SHOWNORMAL); initwinvideo(); -#ifdef OVERLAY_SUPPORT + if (Overlay == 1) { HRESULT hr; RECT rc1; @@ -519,8 +528,8 @@ LRESULT CALLBACK Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) sprintf(err,"IDirectDrawSurface7::UpdateOverlay failed: 0x%x", hr); MessageBox(NULL, err, "DirectDraw Error", MB_ICONERROR); } + } -#endif } InputAcquire(); if (FirstActivate == 1) FirstActivate = 0; @@ -1221,21 +1230,20 @@ int InitDirectDraw() } -#ifdef OVERLAY_SUPPORT - ddcaps.dwSize = sizeof(DDCAPS); - if(lpDD->GetCaps(&ddcaps, NULL) != DD_OK) + if (OverlayEnabled == 1 && !Overlay_failed) { - MessageBox(NULL, "IDirectDraw7::GetCaps failed.", "DirectDraw Error", MB_ICONERROR); + ddcaps.dwSize = sizeof(DDCAPS); + if(lpDD->GetCaps(&ddcaps, NULL) != DD_OK) + { + MessageBox(NULL, "IDirectDraw7::GetCaps failed.", "DirectDraw Error", MB_ICONERROR); + } + if ((ddcaps.dwCaps & DDCAPS_OVERLAY) && + (ddcaps.dwCaps & DDCAPS_OVERLAYSTRETCH)) + Overlay = 1; + if (ddcaps.dwCaps & DDCAPS_COLORKEY) + Overlay_Colorkey = 1; } - if ((ddcaps.dwCaps & DDCAPS_OVERLAY) == 0 || - (ddcaps.dwCaps & DDCAPS_OVERLAYSTRETCH) == 0) - { - MessageBox(NULL, "Sorry, no support for overlays.", "DirectDraw Error", MB_ICONERROR); - exit(0); - } - if (ddcaps.dwCaps & DDCAPS_COLORKEY) - Overlay_Colorkey = 1; -#endif + else Overlay = 0; if(FullScreen == 1) { @@ -1257,27 +1265,26 @@ int InitDirectDraw() CheckAlwaysOnTop(); } +overlay_failed: + ZeroMemory(&ddsd2, sizeof(DDSURFACEDESC2)); ddsd2.dwSize = sizeof(DDSURFACEDESC2); ddsd2.dwFlags = DDSD_CAPS; ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; -#ifndef OVERLAY_SUPPORT - if(FullScreen == 1) + if(!Overlay && FullScreen == 1) { ddsd2.dwFlags |= DDSD_BACKBUFFERCOUNT; ddsd2.dwBackBufferCount = 2; ddsd2.ddsCaps.dwCaps |= DDSCAPS_FLIP | DDSCAPS_COMPLEX; } -#endif if (lpDD->CreateSurface( &ddsd2, &DD_Primary, NULL) != DD_OK) { MessageBox(NULL, "IDirectDraw7::CreateSurface failed.", "DirectDraw Error", MB_ICONERROR); } -#ifndef OVERLAY_SUPPORT - if(FullScreen == 1) + if(!Overlay && FullScreen == 1) { ddsd2.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; if (DD_Primary->GetAttachedSurface(&ddsd2.ddsCaps, &DD_BackBuffer) != DD_OK) @@ -1285,7 +1292,6 @@ int InitDirectDraw() MessageBox(NULL, "IDirectDrawSurface7::GetAttachedSurface failed.", "DirectDraw Error", MB_ICONERROR); } } -#endif if(FullScreen == 0) { if (lpDD->CreateClipper(0,&lpDDClipper,NULL) != DD_OK) @@ -1318,13 +1324,11 @@ int InitDirectDraw() BitDepth=format.dwRGBBitCount; GBitMask=format.dwGBitMask; // 0x07E0 or not -#ifndef OVERLAY_SUPPORT - if (BitDepth==24) + if (BitDepth==24 && Overlay==0) { MessageBox(NULL,"ZSNESw does not support 24bit color.\nPlease change your resolution to either 16bit or 32bit color","Error",MB_OK); exit(0); } -#endif converta = (BitDepth==16 && GBitMask!=0x07E0); @@ -1332,9 +1336,8 @@ int InitDirectDraw() ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; ddsd2.dwWidth = SurfaceX; ddsd2.dwHeight = SurfaceY; - -#ifdef OVERLAY_SUPPORT - + if (Overlay) + { DWORD flags = DDOVER_SHOW, ddofx_ptr = NULL; ddsd2.ddsCaps.dwCaps = DDSCAPS_OVERLAY; @@ -1397,8 +1400,10 @@ int InitDirectDraw() { DD_Primary->Release(); - MessageBox(NULL,"Sorry, no overlay hardware available.", "DirectDraw Error", MB_ICONERROR); - exit(0); + Overlay = 0; + Overlay_failed = 1; + OverlayEnabled = 0; + goto overlay_failed; } if ( hr != DD_OK ) @@ -1472,7 +1477,12 @@ overlay_nocolorkey: DD_Primary->Blt(&rc1, NULL, &rc1, DDBLT_COLORFILL | DDBLT_WAIT, &ddbfx); } -#else + + LockSurface = (lpLockSurface) &LockSurface_overlay; + UnlockSurface = (lpUnlockSurface) &UnlockSurface_overlay; + } + else + { ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; @@ -1481,15 +1491,32 @@ overlay_nocolorkey: { MessageBox(NULL, "IDirectDraw7::CreateSurface failed.", "DirectDraw Error", MB_ICONERROR); } -#endif - + LockSurface = (lpLockSurface) &LockSurface_normal; + UnlockSurface = (lpUnlockSurface) &UnlockSurface_normal; + } return TRUE; } BYTE* SurfBuf; DDSURFACEDESC2 ddsd; -DWORD LockSurface() +DWORD __fastcall LockSurface_normal() +{ + if (DD_CFB == NULL) return(0); + + memset(&ddsd,0,sizeof(ddsd)); + ddsd.dwSize = sizeof( ddsd ); + ddsd.dwFlags = DDSD_LPSURFACE | DDSD_PITCH; + if (DD_CFB->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL) != DD_OK) + { + return(0); + } + + SurfBuf = (BYTE*)ddsd.lpSurface; + return(ddsd.lPitch); +} + +DWORD __fastcall LockSurface_overlay() { HRESULT hr; @@ -1499,11 +1526,9 @@ DWORD LockSurface() memset(&ddsd,0,sizeof(ddsd)); ddsd.dwSize = sizeof( ddsd ); ddsd.dwFlags = DDSD_LPSURFACE | DDSD_PITCH; -#ifdef OVERLAY_SUPPORT - if (vsyncon == 1 && (DD_BackBuffer)) + if (DD_BackBuffer) hr=DD_BackBuffer->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); else -#endif hr=DD_CFB->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); if (hr != DD_OK) @@ -1515,15 +1540,19 @@ DWORD LockSurface() return(ddsd.lPitch); } -void UnlockSurface() +void __fastcall UnlockSurface_normal() { -#ifdef OVERLAY_SUPPORT - if (vsyncon == 1 && (DD_BackBuffer)) + DD_CFB->Unlock((struct tagRECT *)ddsd.lpSurface); + DrawScreen_normal(); +} + +void __fastcall UnlockSurface_overlay() +{ + if (DD_BackBuffer) DD_BackBuffer->Unlock((struct tagRECT *)ddsd.lpSurface); else -#endif DD_CFB->Unlock((struct tagRECT *)ddsd.lpSurface); - DrawScreen(); + DrawScreen_overlay(); } extern "C" { @@ -2768,12 +2797,14 @@ int GetMouseButton(void) if (Y>(GetSystemMetrics( SM_CYSCREEN )-WindowHeight)) Y=(GetSystemMetrics( SM_CYSCREEN )-WindowHeight); InputRead(); initwinvideo(); + if (Overlay && (DD_CFB)) DD_CFB->SetOverlayPosition(X, Y); } } if (Moving==1) { Moving=0; initwinvideo(); + if (Overlay && (DD_CFB)) DD_CFB->SetOverlayPosition(X, Y); } return((int)MouseButton); }