📄 ddraw.c
字号:
/****************************************************************************** SciTech Multi-platform Graphics Library** ========================================================================** The contents of this file are subject to the SciTech MGL Public* License Version 1.0 (the "License"); you may not use this file* except in compliance with the License. You may obtain a copy of* the License at http://www.scitechsoft.com/mgl-license.txt** Software distributed under the License is distributed on an* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or* implied. See the License for the specific language governing* rights and limitations under the License.** The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.** The Initial Developer of the Original Code is SciTech Software, Inc.* All Rights Reserved.** ========================================================================** Language: ANSI C* Environment: Win32** Description: Win32 implementation for the SciTech cross platform* event library.*****************************************************************************/#include "event.h"#include "pmapi.h"#include <stdio.h>#include "win32/oshdr.h"/*---------------------------- Global Variables ---------------------------*/#if 0/* Publicly accessible variables */int _PM_deskX,_PM_deskY;/* Desktop dimentions */HWND _PM_hwndConsole; /* Window handle for console */HWND _PM_hwndUser; /* User window handle */HINSTANCE _PM_hInstDD = NULL; /* Handle to DirectDraw DLL */LPDIRECTDRAW _PM_lpDD1 = NULL; /* DirectDraw object */LPDIRECTDRAW2 _PM_lpDD = NULL; /* DirectDraw2 object *//* Private internal variables */static HINSTANCE hInstApp = NULL;/* Application instance handle */#if 0static LONG oldWndStyle; /* Info about old user window */static LONG oldExWndStyle; /* Info about old user window */static int oldWinPosX; /* Old window position X coordinate */static int oldWinPosY; /* Old window pisition Y coordinate */static int oldWinSizeX; /* Old window size X */static int oldWinSizeY; /* Old window size Y */static WNDPROC oldWndProc = NULL;#endif/* Internal strings */static char *szWinClassName = "SciTechDirectDrawWindow";static char *szAutoPlayKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer";static char *szAutoPlayValue = "NoDriveTypeAutoRun";/* Dynalinks to DirectDraw functions */HRESULT (WINAPI *pDirectDrawCreate)(GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter);/* Declare all GUID's as static variables within this module */#undef DEFINE_GUID#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ static const GUID name \ = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }DEFINE_GUID( IID_IDirectDraw2, 0xB3A6F3E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56 );#endif/*---------------------------- Implementation -----------------------------*/#if 0/****************************************************************************REMARKS:Temporarily disables AutoPlay operation while we are running in fullscreengraphics modes.****************************************************************************/void _PM_disableAutoPlay(void){ DWORD dwAutoPlay,dwSize = sizeof(dwAutoPlay); HKEY hKey; if (RegOpenKeyEx(HKEY_CURRENT_USER,szAutoPlayKey,0,KEY_EXECUTE | KEY_WRITE,&hKey) == ERROR_SUCCESS) { RegQueryValueEx(hKey,szAutoPlayValue,NULL,NULL,(void*)&dwAutoPlay,&dwSize); dwAutoPlay |= AUTOPLAY_DRIVE_CDROM; RegSetValueEx(hKey,szAutoPlayValue,0,REG_DWORD,(void*)&dwAutoPlay,dwSize); RegCloseKey(hKey); }}/****************************************************************************REMARKS:Re-enables AutoPlay operation when we return to regular GDI mode.****************************************************************************/void _PM_restoreAutoPlay(void){ DWORD dwAutoPlay,dwSize = sizeof(dwAutoPlay); HKEY hKey; if (RegOpenKeyEx(HKEY_CURRENT_USER,szAutoPlayKey,0,KEY_EXECUTE | KEY_WRITE,&hKey) == ERROR_SUCCESS) { RegQueryValueEx(hKey,szAutoPlayValue,NULL,NULL,(void*)&dwAutoPlay,&dwSize); dwAutoPlay &= ~AUTOPLAY_DRIVE_CDROM; RegSetValueEx(hKey,szAutoPlayValue,0,REG_DWORD,(void*)&dwAutoPlay,dwSize); RegCloseKey(hKey); }}static void RestoreFullScreen(void)/****************************************************************************** Function: RestoreFullScreen** Description: Reactivate all the surfaces for DirectDraw and set the* system back up for fullscreen rendering. *****************************************************************************/{ static ibool firstTime = true; if (firstTime) { int oldActivePage,oldVisualPage; ibool isActive; MGLDC *dc = _LST_first(DEV.dispDCList); MGLDC *cntDC = _PM_dcPtr; /* Clear the message queue while waiting for the surfaces to be * restored. */ firstTime = false; while (1) { /* Restore all the surfaces that we have lost */ _EVT_pumpMessages(); isActive = (GetActiveWindow() == _PM_hwndFullScreen); if (isActive) { if (_PM_lpPrimary) { if (IDirectDrawSurface_Restore(_PM_lpPrimary) != DD_OK) isActive = false; else if (_PM_lpOffscreen) IDirectDrawSurface_Restore(_PM_lpOffscreen); } if (_PM_winDirectMode == -1) _WIN_restoreFullScreenMode(dc); if (_PM_isFSOpenGLDC(dc)) fglSetFocus(true); if (isActive) { /* Restore our fullscreen window and the users display */ if (dc->mi.bitsPerPixel == 8) { HDC hdc = GetDC(NULL); SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC); ReleaseDC(NULL,hdc); } oldActivePage = MGL_getActivePage(dc); oldVisualPage = MGL_getVisualPage(dc); MGL_makeCurrentDC(NULL); MGL_makeCurrentDC(dc); MGL_makeCurrentDC(cntDC); MGL_realizePalette(dc,MGL_getPaletteSize(dc),0,false); if (_PM_lpPrimary) _PM_enumerateSurfaces(dc); MGL_setActivePage(dc,oldActivePage); MGL_setVisualPage(dc,oldVisualPage,false); if (_PM_suspendApp) _PM_suspendApp(dc,MGL_REACTIVATE); _MS_restoreState(); _PM_disableAutoPlay(); _PM_backInGDI = false; waitActive = false; firstTime = true; return; } } Sleep(200); } }}/* {secret} */void _PM_doSuspendApp(void)/****************************************************************************** Function: _PM_doSuspendApp* Parameters: flags - Flags indicating which key started the suspend** Description: Suspends the application by switching back to the GDI* desktop, allowing normal application code to be processed,* and then waiting for the application activate command to* bring us back to fullscreen mode with our window minimised.** This version only gets called if we have not captured the* screen switch in our activate message loops and will* occur if we lose a surface for some reason while rendering.* This should not normally happen, but it is included just to* be sure (note that this code will always spin loop, and we* cannot disable the spin looping from this version).*****************************************************************************/{ static ibool firstTime = true; MGLDC *dc = _LST_first(DEV.dispDCList); if (firstTime) { if (_PM_suspendApp) _PM_suspendApp(dc,MGL_DEACTIVATE); if (_PM_isFSOpenGLDC(dc)) fglSetFocus(false); _MS_saveState(); firstTime = false; if (dc->mi.bitsPerPixel == 8) { HDC hdc = GetDC(NULL); SetSystemPaletteUse(hdc, SYSPAL_STATIC); ReleaseDC(NULL,hdc); } _PM_restoreAutoPlay(); _PM_backInGDI = true; } RestoreFullScreen(); firstTime = true;}/* {secret} */void _PM_deactivate(void)/****************************************************************************** Function: _PM_deactivate* Parameters: flags - Flags indicating which key started the suspend** Description: Suspends the application by switching back to the GDI* desktop, allowing normal application code to be processed,* and then waiting for the application activate command to* bring us back to fullscreen mode with our window minimised.*****************************************************************************/{ MGLDC *dc = _LST_first(DEV.dispDCList); int retCode = MGL_SUSPEND_APP; if (_PM_backInGDI) return; if (_PM_suspendApp) retCode = _PM_suspendApp(dc,MGL_DEACTIVATE); if (_PM_isFSOpenGLDC(dc)) fglSetFocus(false); _MS_saveState(); if (dc->mi.bitsPerPixel == 8) { HDC hdc = GetDC(NULL); SetSystemPaletteUse(hdc, SYSPAL_STATIC); ReleaseDC(NULL,hdc); } if (_PM_winDirectMode == -1) _WIN_restoreDisplayMode(true); _PM_restoreAutoPlay(); _PM_backInGDI = true; /* Now process messages normally until we are re-activated */ waitActive = true; if (retCode != MGL_NO_SUSPEND_APP) { while (waitActive) { _EVT_pumpMessages(); Sleep(200); } }}/****************************************************************************REMARKS:Main Window proc for the full screen DirectDraw Window that we create whilerunning in full screen mode. Here we capture all mouse and keyboard eventsfor the window and plug them into our event queue.****************************************************************************/static LONG CALLBACK PM_winProc( HWND hwnd, UINT msg, WPARAM wParam, LONG lParam){#if 0 int isAlt,doSwitch; int where_x,where_y; switch (msg) { case WM_SYSCHAR: /* Stop Alt-Space from pausing our game */ return 0; case WM_KEYDOWN: case WM_SYSKEYDOWN: if (HIWORD(lParam) & KF_REPEAT) { if (msg == WM_SYSKEYDOWN) return 0; break; } /* Fall through for keydown events */ case WM_KEYUP: case WM_SYSKEYUP: if (_PM_winDirectMode == -1) { /* Handle Alt-Tabbing for fullscreen DIB modes */ isAlt = (HIWORD(lParam) & KF_ALTDOWN); doSwitch = false; if (isAlt && wParam == VK_TAB) doSwitch = true; /* Alt-Tab */ else if (isAlt && wParam == VK_ESCAPE) doSwitch = true; /* Alt-Esc */ else if (wParam == VK_ESCAPE) { if (GetKeyState(VK_CONTROL) & 0x8000U) doSwitch = true; /* Ctrl-Esc */ } if (doSwitch) { MGLDC *dc = _LST_first(DEV.dispDCList); /* Check the app wants to block switching and block it */ if (!_PM_haveWinNT && (_PM_suspendApp && (_PM_suspendApp(dc,MGL_DEACTIVATE) == MGL_NO_DEACTIVATE))) return 0; ShowWindow(_PM_hwndFullScreen,SW_MINIMIZE); } } if (msg == WM_SYSKEYDOWN || msg == WM_SYSKEYUP) { if ((HIWORD(lParam) & KF_ALTDOWN) && wParam == VK_RETURN) break; /* We ignore the remainder of the sysyetm keys to stop the * system menu from being activated from the keyboard and pausing * our app while fullscreen (ie: pressing the Alt key). */ return 0; } break; case WM_SYSCOMMAND: switch (wParam & ~0x0F) { case SC_SCREENSAVE: case SC_MONITORPOWER: /* Ignore screensaver requests in fullscreen modes */ return 0; } break; case WM_MOUSEMOVE: where_x = (LOWORD(lParam) * _PM_xRes) / _PM_deskX; where_y = (HIWORD(lParam) * _PM_yRes) / _PM_deskY; if (_PM_mx != where_x || _PM_my != where_y) _MS_moveCursor(_PM_mx = where_x,_PM_my = where_y); break; case WM_SIZE: if (waitActive && _PM_backInGDI && (wParam != SIZE_MINIMIZED)) { /* Start the re-activation process */ PostMessage(hwnd,WM_DO_SUSPEND_APP,WM_PM_RESTORE_FULLSCREEN,0); } else if (!waitActive && _PM_fullScreen && !_PM_backInGDI && (wParam == SIZE_MINIMIZED)) { /* Start the de-activation process */ PostMessage(hwnd,WM_DO_SUSPEND_APP,WM_PM_DEACTIVATE,0); } break; case WM_DO_SUSPEND_APP: switch (wParam) { case WM_PM_RESTORE_FULLSCREEN: RestoreFullScreen(); break; case WM_PM_DEACTIVATE: _PM_deactivate(); break; } return 0; } if (oldWndProc) return oldWndProc(hwnd,msg,wParam,lParam); else if (_PM_userEventProc) return _PM_userEventProc(hwnd,msg,wParam,lParam);#endif return DefWindowProc(hwnd,msg,wParam,lParam);}/* {secret} */LONG WINAPI PM_subWinProc(HWND hwnd, UINT msg, WPARAM wParam, LONG lParam)/****************************************************************************** Function: PM_subWinProc** Description: Main Window proc for the full screen WinDirect Window that* we create while running in full screen mode. Here we* capture all mouse and keyboard events for the window and* plug them into our event queue.*****************************************************************************/{ int isAlt,doSwitch; switch (msg) { case WM_KEYUP: case WM_SYSKEYUP: /* Filter out the keyup events in DirectDraw that can cause us to * lose our surfaces when a switch occurs. */ isAlt = (HIWORD(lParam) & KF_ALTDOWN); doSwitch = false; if (isAlt && wParam == VK_TAB) doSwitch = true; /* Alt-Tab */ else if (isAlt && wParam == VK_ESCAPE) doSwitch = true; /* Alt-Esc */ else if (wParam == VK_ESCAPE) { if (GetKeyState(VK_CONTROL) & 0x8000U) doSwitch = true; /* Ctrl-Esc */ } if (doSwitch) { MGLDC *dc = _LST_first(DEV.dispDCList); /* Check the app wants to block switching and block it */ if (!_PM_haveWinNT && (_PM_suspendApp && (_PM_suspendApp(dc,MGL_DEACTIVATE) == MGL_NO_DEACTIVATE))) return 0; } break; } return _PM_orgWinProc(hwnd,msg,wParam,lParam);}/* {secret} */void _PM_subClassWindow(HWND hwnd)/****************************************************************************** Function: _PM_subClassWindow* Parameters: hwnd - Handle of DirectDraw window to subclass** Description: Subclasses the DirectDraw window after DirectDraw has* gone into exclusive mode so that we can stop DirectDraw* from allowing us to Alt-Tab away from the application. Note* that this may get called after the window has already been* subclassed once.*****************************************************************************/{ WNDPROC oldWinProc = (WNDPROC)SetWindowLong(hwnd, GWL_WNDPROC, (LPARAM)PM_subWinProc); if (!_PM_orgWinProc) _PM_orgWinProc = oldWinProc;}/* {secret} */void _PM_unsubClassWindow(HWND hwnd)/****************************************************************************** Function: _PM_unsubClassWindow* Parameters: hwnd - Handle of DirectDraw window to subclass*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -