1127 lines
35 KiB
C
1127 lines
35 KiB
C
/*
|
|
** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
|
|
** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
|
|
** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
|
|
** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
|
|
** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
|
|
** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
|
|
** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
|
|
**
|
|
** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
|
|
** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
|
|
** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
|
|
** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
|
|
** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
|
|
** THE UNITED STATES.
|
|
**
|
|
** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
|
|
**
|
|
** $Log:
|
|
** 6 GlideXP 1.0.5 18/10/01 Ryan Nunn Updating getModesRegPath
|
|
** 5 GlideXP 1.0.4 18/10/01 Ryan Nunn Fixing another multimonitor bug
|
|
** 4 GlideXP 1.0.3 18/10/01 Ryan Nunn Properly check refresh rates
|
|
** 3 GlideXP 1.0.2 15/10/01 Ryan Nunn Fixing a multimonitor bug
|
|
** 2 GlideXP 1.0.1 14/10/01 Ryan Nunn Check refresh rates
|
|
** 1 GlideXP 1.0 12/10/01 Ryan Nunn Getting to compile
|
|
** In windows for H5 Glide3. Copied from H3 Glide3.
|
|
** 7 1.11 11/30/02 KoolSmoky moved CEASE_ALL_GDBG because we need
|
|
** debug info for certain apps to run.
|
|
** 6 ve3d 1.10 06/24/02 KoolSmoky ditch changing display modes with ddraw
|
|
** and use changedisplaysettings instead. also removed ddraw from checkresolutions.
|
|
** 5 ve3d 1.04 12/27/01 KoolSmoky added a switch to cease all debug info.
|
|
** 4 ve3d 1.03 11/30/01 KoolSmoky output minimum debug info on release compiles.
|
|
** 3 ve3d 1.02 11/29/01 KoolSmoky better displaymode enum. checks for bpp & refresh
|
|
** 2 ve3d 1.01 11/28/01 KoolSmoky modified setVideoMode() to accept h3pixelSize
|
|
** and checkResolutions() to accept stride from minihwc.c. Misc fixes to compile.
|
|
** 1 ve3d 1.00 11/25/01 KoolSmoky copied from Glide\h3\minihwc\win_mode.c
|
|
**
|
|
*/
|
|
|
|
#if !defined(GDBG_INFO_ON) || (GDBG_INFO_ON == 0)
|
|
#if defined(GDBG_INFO_ON)
|
|
#undef GDBG_INFO_ON
|
|
#endif /* defined(GDBG_INFO_ON) */
|
|
#define GDBG_INFO_ON
|
|
#endif /* !defined(GDBG_INFO_ON) || (GDBG_INFO_ON == 0) */
|
|
|
|
#include <stdio.h>
|
|
#include <3dfx.h>
|
|
#include <gdebug.h>
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#endif
|
|
#include <windows.h>
|
|
#include <ddraw.h>
|
|
#include <sst1vid.h>
|
|
#include "qmodes.h"
|
|
#include "setmode.h"
|
|
#include "minihwc.h"
|
|
#define IS_32
|
|
#define Not_VxD
|
|
#include <minivdd.h>
|
|
#include <vmm.h>
|
|
#include <configmg.h>
|
|
|
|
/* Windows */
|
|
#define SEPARATOR '\\'
|
|
/* UNIX */
|
|
#define SEPARATOR2 '/'
|
|
|
|
/* Things Added */
|
|
#ifdef IS_ALT_TAB
|
|
static DEVMODE curDevMode;
|
|
static char *curDeviceName;
|
|
#endif
|
|
|
|
static HWND hwndApp = 0;
|
|
//static GUID fooGuid;
|
|
//static FxU32 _stride;
|
|
|
|
/* Direct Draw stuff */
|
|
LPDIRECTDRAW lpDD1 = NULL;
|
|
LPDIRECTDRAW2 lpDD = NULL;
|
|
|
|
#if WINXP_ALT_TAB_FIX
|
|
LPDIRECTDRAW4 lpDD4 = NULL;
|
|
#endif
|
|
|
|
char *opengl_regpath; /* KoolSmoky - registry path passed from grEnable */
|
|
|
|
#ifdef IS_ALT_TAB
|
|
FxBool is_opengl; /* KoolSmoky - OpenGL flag */
|
|
FxBool is_fullscreen; /* KoolSmoky - full screen flag */
|
|
#endif
|
|
|
|
/*
|
|
* parseFilename
|
|
*
|
|
* Return the file name portion of a filename/path.
|
|
*/
|
|
|
|
static char *
|
|
_parseFilename(char *name)
|
|
{
|
|
int i;
|
|
|
|
if (name == NULL)
|
|
return NULL;
|
|
for(i = strlen(name); i >= 0; i--)
|
|
if ((name[i] == SEPARATOR) ||
|
|
(name[i] == SEPARATOR2))
|
|
return (name + i + 1);
|
|
return name;
|
|
} /* End of parseFilename*/
|
|
|
|
|
|
static int _set_exclusive_relaxed;
|
|
static int _set_vidmode_relaxed;
|
|
|
|
typedef struct _enumInfoStruct {
|
|
GUID guid;
|
|
HMONITOR hmon;
|
|
} EnumInfo;
|
|
|
|
static BOOL FAR PASCAL
|
|
ddEnumCbEx( GUID FAR *guid, LPSTR desc, LPSTR name, LPVOID ctx, HMONITOR hmon )
|
|
{
|
|
#if 0
|
|
DWORD *data = (DWORD*)ctx;
|
|
HMONITOR target = (HMONITOR)data[0];
|
|
BOOL rv = DDENUMRET_OK;
|
|
#else
|
|
EnumInfo* pEnumInfo = (EnumInfo*)ctx;
|
|
BOOL rv = DDENUMRET_OK;
|
|
#endif
|
|
|
|
#if 0
|
|
if ( target == hmon ) {
|
|
if ( guid ) {
|
|
fooGuid = *guid;
|
|
data[1] = (DWORD)&fooGuid;
|
|
} else {
|
|
/* guid for primary display device */
|
|
data[1] = 0;
|
|
}
|
|
rv = DDENUMRET_CANCEL;
|
|
}
|
|
#else
|
|
if(pEnumInfo->hmon == hmon) {
|
|
if ( guid ) CopyMemory(&pEnumInfo->guid, guid, sizeof(GUID));
|
|
rv = DDENUMRET_CANCEL;
|
|
}
|
|
#endif
|
|
|
|
return rv;
|
|
}
|
|
|
|
typedef struct _emcStruct {
|
|
FxU32 xRes, yRes, Refresh;
|
|
FxU32 bpp;
|
|
FxBool modeOK;
|
|
} EMCData;
|
|
|
|
static HRESULT WINAPI
|
|
enumModesCallback(LPDDSURFACEDESC surfaceDesc, LPVOID lpContext)
|
|
{
|
|
EMCData *emcData = (EMCData *) lpContext;
|
|
|
|
GDBG_INFO(80, "enumModesCallbac:\n");
|
|
GDBG_INFO(80, "\tsurfaceDesc->dwWidth == %d\n", surfaceDesc->dwWidth);
|
|
GDBG_INFO(80, "\tsurfaceDesc->dwHeight == %d\n", surfaceDesc->dwHeight);
|
|
GDBG_INFO(80,
|
|
"\tsurfaceDesc->dwRefreshRate == %d\n",surfaceDesc->dwRefreshRate);
|
|
GDBG_INFO(80, "\tsurfaceDesc->ddpfPixelFormat.dwRGBBitCount == %d\n",
|
|
surfaceDesc->ddpfPixelFormat.dwRGBBitCount);
|
|
if (
|
|
(surfaceDesc->dwWidth == emcData->xRes) &&
|
|
(surfaceDesc->dwHeight == emcData->yRes) &&
|
|
(surfaceDesc->ddpfPixelFormat.dwRGBBitCount == emcData->bpp) &&
|
|
((surfaceDesc->dwRefreshRate == emcData->Refresh) ||
|
|
(surfaceDesc->dwRefreshRate == 0) ||
|
|
(emcData->Refresh == 0))) {
|
|
emcData->modeOK = FXTRUE;
|
|
return DDENUMRET_CANCEL;
|
|
} else
|
|
return DDENUMRET_OK;
|
|
|
|
} /* enumModesCallback */
|
|
|
|
static void
|
|
msgModeSetFailure(HRESULT hResult)
|
|
{
|
|
|
|
if (hResult& DDERR_GENERIC)
|
|
GDBG_INFO(80, "Mode set failed due to DDERR_GENERIC\n");
|
|
|
|
if (hResult & DDERR_INVALIDMODE)
|
|
GDBG_INFO(80, "Mode set failed due to DDERR_INVALIDMODE\n");
|
|
|
|
if (hResult & DDERR_INVALIDOBJECT)
|
|
GDBG_INFO(80, "Mode set failed due to DDERR_INVALIDOBJECT\n");
|
|
|
|
if (hResult & DDERR_INVALIDPARAMS)
|
|
GDBG_INFO(80, "Mode set failed due to DDERR_INVALIDPARAMS\n");
|
|
|
|
if (hResult & DDERR_LOCKEDSURFACES)
|
|
GDBG_INFO(80, "Mode set failed due to DDERR_LOCKEDSURFACES\n");
|
|
|
|
if (hResult & DDERR_NOEXCLUSIVEMODE)
|
|
GDBG_INFO(80, "Mode set failed due to DDERR_NOEXCLUSIVEMODE\n");
|
|
|
|
if (hResult & DDERR_SURFACEBUSY)
|
|
GDBG_INFO(80, "Mode set failed due to DDERR_SURFACEBUSY\n");
|
|
|
|
if (hResult & DDERR_UNSUPPORTED)
|
|
GDBG_INFO(80, "Mode set failed due to DDERR_UNSUPPORTED\n");
|
|
|
|
if (hResult & DDERR_UNSUPPORTEDMODE)
|
|
GDBG_INFO(80, "Mode set failed due to DDERR_UNSUPPORTEDMODE\n");
|
|
|
|
if (hResult & DDERR_WASSTILLDRAWING)
|
|
GDBG_INFO(80, "Mode set failed due to DDERR_WASSTILLDRAWING\n");
|
|
|
|
} /* msgModeSetFailure */
|
|
|
|
static void
|
|
msgEnumDisplayModes(hResult)
|
|
{
|
|
if (hResult & DDERR_INVALIDOBJECT)
|
|
GDBG_INFO(80, "DDERR_INVALIDOBJECT\n");
|
|
|
|
if (hResult & DDERR_INVALIDPARAMS)
|
|
GDBG_INFO(80, "DDERR_INVALIDPARAMS\n");
|
|
|
|
} /* msgEnumDisplayModes */
|
|
|
|
#ifdef __WIN32__
|
|
static char *
|
|
getModesRegPath()
|
|
{
|
|
char *retVal = NULL;
|
|
FxU32 OS = hwcGetOS();
|
|
|
|
if ((OS == OS_WIN32_NT4) ||
|
|
(OS == OS_WIN32_2K) ||
|
|
(OS == OS_WIN32_XP))
|
|
{
|
|
HKEY hKey;
|
|
DWORD type ;
|
|
static char strval[255];
|
|
DWORD szData = sizeof(strval) ;
|
|
|
|
/* Go fishing for the registry path on Win2K */
|
|
if (RegOpenKey(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\VIDEO", &hKey) == ERROR_SUCCESS)
|
|
{
|
|
if (RegQueryValueEx(hKey, "\\Device\\Video0", NULL, &type, strval, &szData) == ERROR_SUCCESS)
|
|
{
|
|
if (type != REG_SZ)
|
|
{
|
|
/* It is hardcoded on NT via Display Control code. see:
|
|
* $/devel/swtools/bansheecp2 */
|
|
retVal = "SYSTEM\\CurrentControlSet\\Services\\3Dfx\\Device0\\modes\\";
|
|
}
|
|
else
|
|
{
|
|
strcat(strval, "\\modes\\") ;
|
|
retVal = (char*)((int)strval + strlen("\\REGISTRY\\Machine\\")) ;
|
|
}
|
|
}
|
|
else
|
|
retVal = "SYSTEM\\CurrentControlSet\\Services\\3Dfx\\Device0\\modes\\";
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
} else {
|
|
QDEVNODE QDevNode;
|
|
QIN Qin;
|
|
int status;
|
|
|
|
GDBG_INFO(80, "OS == W9X\n");
|
|
|
|
Qin.dwSubFunc = QUERYDEVNODE;
|
|
{
|
|
HDC curDC = GetDC(NULL);
|
|
|
|
status = ExtEscape ( (HDC)curDC, QUERYESCMODE,
|
|
sizeof(Qin), (LPCSTR)&Qin,
|
|
sizeof(QDevNode), (LPSTR)&QDevNode );
|
|
ReleaseDC(NULL, curDC);
|
|
}
|
|
|
|
if ( status > 0 ) {
|
|
static char regPath[255];
|
|
|
|
CM_Get_DevNode_Key( QDevNode.dwDevNode, NULL,
|
|
®Path, sizeof(regPath),
|
|
CM_REGISTRY_SOFTWARE );
|
|
strcat(regPath, "\\modes\\");
|
|
|
|
retVal = regPath;
|
|
}
|
|
}
|
|
|
|
GDBG_INFO( 80, "REGPATH: %s\n", retVal );
|
|
|
|
return retVal;
|
|
} /* getRegPath */
|
|
#endif
|
|
|
|
FxBool
|
|
setVideoMode( HWND hwnd, int xRes, int yRes, int h3pixelSize, int refresh, void *hmon, char *regpath , char *devicename )
|
|
{
|
|
LPGUID ddGuid = NULL;
|
|
HMODULE ddraw = NULL;
|
|
#if (WINXP_FASTER_ALT_TAB_FIX || WINXP_ALT_TAB_FIX)
|
|
DDSURFACEDESC ddsd;
|
|
EMCData emcData; /* Enum Modes Callbac Data */
|
|
#endif
|
|
HRESULT hResult;
|
|
DEVMODE devMode;
|
|
FxU32 bpp = 16;
|
|
//HRESULT ddRVal;
|
|
//DWORD style;
|
|
#ifdef IS_ALT_TAB
|
|
FxU32 OS = hwcGetOS();
|
|
|
|
/* reset fullscreen flag */
|
|
is_fullscreen = FXFALSE;
|
|
#endif
|
|
|
|
#ifdef FX_GLIDE_NAPALM
|
|
if (h3pixelSize == 4) bpp = 32;
|
|
GDBG_INFO( 80, "Glide mode: %dx%dx%dbpp@%dHz\n",
|
|
xRes,
|
|
yRes,
|
|
bpp,
|
|
refresh);
|
|
#endif
|
|
|
|
GDBG_INFO( 80, "setVideoMode sees hwnd %x\n", hwnd);
|
|
hwndApp = ( hwnd == NULL ) ? GetActiveWindow() : hwnd;
|
|
|
|
if ( hwndApp == NULL ) {
|
|
GDBG_INFO( 80, "Couldn't get a valid window handle\n" );
|
|
}
|
|
|
|
/* KoolSmoky - Window style and dimensions are not important,
|
|
** since they will be adjusted elsewhere. It's important to call
|
|
** ShowWindow to ensure that any activity from other windows is
|
|
** obscured.*/
|
|
//ShowWindow( hwndApp, SW_SHOW );
|
|
//SetForegroundWindow(hwndApp);
|
|
// HACK //
|
|
//Sleep(100);
|
|
|
|
ddGuid = NULL;
|
|
ddraw = GetModuleHandle( "ddraw.dll" );
|
|
if ( ddraw != NULL ) {
|
|
LPDIRECTDRAWENUMERATEEXA ddEnumEx;
|
|
ddEnumEx = (void*)GetProcAddress( ddraw, "DirectDrawEnumerateExA" );
|
|
if ( ddEnumEx ) {
|
|
#if 0
|
|
DWORD data[2];
|
|
data[0] = (DWORD)hmon;
|
|
data[1] = 0;
|
|
ddEnumEx( ddEnumCbEx, data, DDENUM_ATTACHEDSECONDARYDEVICES );
|
|
if ( data[1] ) {
|
|
ddGuid = (LPGUID)data[1];
|
|
}
|
|
#else
|
|
EnumInfo enumInfo;
|
|
|
|
ZeroMemory(&enumInfo, sizeof(enumInfo));
|
|
ZeroMemory(&enumInfo.guid, sizeof(GUID));
|
|
enumInfo.hmon = (HMONITOR)hmon;
|
|
ddEnumEx( ddEnumCbEx, &enumInfo, DDENUM_ATTACHEDSECONDARYDEVICES );
|
|
ddGuid = &enumInfo.guid;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/* KoolSmoky - this only covers the PRIMARY VGA? */
|
|
// EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode);
|
|
/* KooSmoky - save display mode to restore at exit */
|
|
#ifdef IS_ALT_TAB
|
|
curDeviceName=devicename;
|
|
EnumDisplaySettings(curDeviceName, ENUM_REGISTRY_SETTINGS, &curDevMode);
|
|
|
|
/* KoolSmoky - Hack for win95. make a disp struct if we don't get anything
|
|
* from EnumDisplaySettings.
|
|
*/
|
|
if ((curDevMode.dmBitsPerPel < 8UL) || (curDevMode.dmBitsPerPel > 32UL)) {
|
|
HDC hdc = GetDC(NULL);
|
|
curDevMode.dmSize = sizeof(DEVMODE) ;
|
|
curDevMode.dmPelsWidth = GetSystemMetrics(SM_CXSCREEN) ;
|
|
curDevMode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN) ;
|
|
curDevMode.dmBitsPerPel = (DWORD)GetDeviceCaps(hdc, BITSPIXEL) ;
|
|
curDevMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT ;
|
|
ReleaseDC(NULL, hdc) ;
|
|
}
|
|
|
|
GDBG_INFO(80, "DeviceName: %s Display mode: %dx%dx%dbpp!\n", curDeviceName, curDevMode.dmPelsWidth, curDevMode.dmPelsHeight, curDevMode.dmBitsPerPel);
|
|
|
|
#endif
|
|
|
|
#if (WINXP_FASTER_ALT_TAB_FIX || WINXP_ALT_TAB_FIX)
|
|
EnumDisplaySettings(devicename, ENUM_REGISTRY_SETTINGS, &devMode);
|
|
|
|
/* KoolSmoky - Hack for win95. make a disp struct if we don't get anything
|
|
* from EnumDisplaySettings.
|
|
*/
|
|
if ((devMode.dmBitsPerPel < 8UL) || (devMode.dmBitsPerPel > 32UL)) {
|
|
HDC hdc = GetDC(NULL);
|
|
devMode.dmSize = sizeof(DEVMODE) ;
|
|
devMode.dmPelsWidth = GetSystemMetrics(SM_CXSCREEN) ;
|
|
devMode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN) ;
|
|
devMode.dmBitsPerPel = (DWORD)GetDeviceCaps(hdc, BITSPIXEL) ;
|
|
devMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT ;
|
|
ReleaseDC(NULL, hdc) ;
|
|
}
|
|
|
|
GDBG_INFO(80, "DeviceName: %s Display mode: %dx%dx%dbpp!\n", devicename, devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmBitsPerPel);
|
|
|
|
/*
|
|
** Oh, this is lovely. What we have here is a failure to
|
|
** communicate. If the current mode is exactly the same as the
|
|
** mode in which Glide wishes to run, then the DirectDraw driver
|
|
** doesn't get called when we restore the video (or on an alt-tab)
|
|
** this would be fine, except Glide has its way with the video
|
|
** overlay registers. So, if we detect this case, we ask DDraw for
|
|
** an 8-bit display, and fix up vidProcCfg in the minihwc.
|
|
*/
|
|
/* KoolSmoky - what would happen if we run from 8bpp? */
|
|
if ((devMode.dmPelsWidth == (FxU32) xRes) &&
|
|
(devMode.dmPelsHeight == (FxU32) yRes)) {
|
|
GDBG_INFO(80, "DDraw communication hack: setting to 8bpp!\n");
|
|
bpp = 8;
|
|
}
|
|
#endif
|
|
|
|
|
|
// checkSpecialList();
|
|
|
|
if (lpDD == NULL) {
|
|
/* only create directdraw object once */
|
|
if ( DirectDrawCreate( ddGuid, &lpDD1, NULL ) != DD_OK) {
|
|
GDBG_INFO(80, "DDraw Obj Create Failed!\n");
|
|
}
|
|
else GDBG_INFO(80, "DDraw Obj created!\n");
|
|
if ( IDirectDraw_QueryInterface( lpDD1, &IID_IDirectDraw2,
|
|
(LPVOID*)&lpDD ) != DD_OK ) {
|
|
IDirectDraw_Release( lpDD1 );
|
|
#if WINXP_ALT_TAB_FIX
|
|
lpDD4 = NULL;
|
|
#endif
|
|
lpDD1 = NULL;
|
|
lpDD = NULL;
|
|
GDBG_INFO(80, "DDraw Obj Create Failed!\n");
|
|
return FXFALSE;
|
|
}
|
|
else GDBG_INFO(80, "DDraw2 Obj created!\n");
|
|
#if WINXP_ALT_TAB_FIX
|
|
if ( IDirectDraw_QueryInterface( lpDD1, &IID_IDirectDraw4,
|
|
(LPVOID*)&lpDD4 ) != DD_OK ) {
|
|
IDirectDraw_Release( lpDD );
|
|
IDirectDraw_Release( lpDD1 );
|
|
lpDD4 = NULL;
|
|
lpDD1 = NULL;
|
|
lpDD = NULL;
|
|
GDBG_INFO(80, "DDraw Obj Create Failed!\n");
|
|
return FXFALSE;
|
|
}
|
|
else GDBG_INFO(80, "DDraw4 Obj created!\n");
|
|
#endif
|
|
}
|
|
|
|
/* KoolSmoky - moves all of the pieces of surface memory
|
|
* on the display card to a contiguous block to make the
|
|
* largest single amount of free memory available.
|
|
IDirectDraw2_Compact(lpDD);
|
|
IDirectDraw_Compact(lpDD1);*/
|
|
|
|
/* Set Exclusive Mode, change resolution, */
|
|
GDBG_INFO(80, "Setting Full screen exclusive mode!\n");
|
|
GDBG_INFO(80, "Calling IDD2_SetCoop: 0x%x, 0x%x, 0x%x\n", lpDD, hwndApp, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
|
|
|
|
hResult = IDirectDraw2_SetCooperativeLevel(lpDD, hwndApp,
|
|
/*DDSCL_ALLOWREBOOT |*/
|
|
DDSCL_EXCLUSIVE |
|
|
DDSCL_FULLSCREEN);
|
|
if(hResult != DD_OK)
|
|
{
|
|
GDBG_INFO(80, "Couldn't set cooperative level: " );
|
|
if (hResult & DDERR_EXCLUSIVEMODEALREADYSET)
|
|
GDBG_INFO_MORE(80, "DDERR_EXCLUSIVEMODEALREADYSET\n" );
|
|
|
|
if (hResult & DDERR_HWNDALREADYSET) {
|
|
GDBG_INFO_MORE(80, "DDERR_HWNDALREADYSET\n" );
|
|
if (hResult == DDERR_HWNDALREADYSET)
|
|
_set_exclusive_relaxed = 1;
|
|
}
|
|
if (hResult & DDERR_HWNDSUBCLASSED)
|
|
GDBG_INFO_MORE(80, "DDERR_HWNDSUBCLASSED\n" );
|
|
|
|
if (hResult & DDERR_INVALIDOBJECT)
|
|
GDBG_INFO_MORE(80, "DDERR_INVALIDOBJECT\n" );
|
|
|
|
if (hResult & DDERR_INVALIDPARAMS)
|
|
GDBG_INFO_MORE(80, "DDERR_INVALIDPARAMS\n" );
|
|
|
|
if (hResult & DDERR_OUTOFMEMORY)
|
|
GDBG_INFO_MORE(80, "DDERR_OUTOFMEMORY\n" );
|
|
|
|
if (!_set_exclusive_relaxed)
|
|
return FXFALSE;
|
|
}
|
|
|
|
GDBG_INFO(80, "FSEM Set\n" );
|
|
GDBG_INFO(80, "Enumerating Display Modes.\n");
|
|
|
|
/* Figure out if we can support the requested display mode. If not,
|
|
try to use the same x & y res, but the default refresh rate.*/
|
|
/* KoolSmoky - ditch ddraw and use changedisplaysettings to switch modes */
|
|
GDBG_INFO(80, "Setting Display Mode!\n");
|
|
|
|
#ifdef IS_ALT_TAB
|
|
devMode.dmSize = sizeof(DEVMODE);
|
|
devMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
|
|
devMode.dmPelsWidth = xRes;
|
|
devMode.dmPelsHeight = yRes;
|
|
devMode.dmBitsPerPel = bpp;
|
|
devMode.dmDisplayFrequency = refresh;
|
|
|
|
if ((OS == OS_WIN32_95) ||
|
|
(OS == OS_WIN32_NT4))
|
|
{
|
|
// win95,nt4
|
|
if(ChangeDisplaySettings(&devMode, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL)
|
|
{
|
|
/*style = GetWindowLong(hwndApp, GWL_STYLE);
|
|
style &= ~(WS_MAXIMIZE|WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX);
|
|
style |= WS_POPUP;
|
|
SetWindowLong(hwndApp, GWL_STYLE, style);*/
|
|
|
|
is_fullscreen = FXTRUE;
|
|
|
|
GDBG_INFO(80, "Display Mode Set\n" );
|
|
} else {
|
|
GDBG_INFO(80, "Setting display mode at default refresh\n");
|
|
|
|
devMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT ;
|
|
|
|
if(ChangeDisplaySettings(&devMode, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL)
|
|
{
|
|
/*style = GetWindowLong(hwndApp, GWL_STYLE);
|
|
style &= ~(WS_MAXIMIZE|WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX);
|
|
style |= WS_POPUP;
|
|
SetWindowLong(hwndApp, GWL_STYLE, style);*/
|
|
|
|
is_fullscreen = FXTRUE;
|
|
|
|
GDBG_INFO(80, "Display Mode Set\n" );
|
|
}
|
|
}
|
|
|
|
} else {
|
|
// win98,win2k,winxp
|
|
if(ChangeDisplaySettingsEx(curDeviceName, &devMode, NULL, CDS_FULLSCREEN, NULL) == DISP_CHANGE_SUCCESSFUL)
|
|
{
|
|
/*style = GetWindowLong(hwndApp, GWL_STYLE);
|
|
style &= ~(WS_MAXIMIZE|WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX);
|
|
style |= WS_POPUP;
|
|
SetWindowLong(hwndApp, GWL_STYLE, style);*/
|
|
|
|
is_fullscreen = FXTRUE;
|
|
|
|
GDBG_INFO(80, "Display Mode Set\n" );
|
|
} else {
|
|
GDBG_INFO(80, "Setting display mode at default refresh\n");
|
|
|
|
devMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT ;
|
|
|
|
if(ChangeDisplaySettingsEx(curDeviceName, &devMode, NULL, CDS_FULLSCREEN, NULL) == DISP_CHANGE_SUCCESSFUL)
|
|
{
|
|
/*style = GetWindowLong(hwndApp, GWL_STYLE);
|
|
style &= ~(WS_MAXIMIZE|WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX);
|
|
style |= WS_POPUP;
|
|
SetWindowLong(hwndApp, GWL_STYLE, style);*/
|
|
|
|
is_fullscreen = FXTRUE;
|
|
|
|
GDBG_INFO(80, "Display Mode Set\n" );
|
|
}
|
|
}
|
|
}
|
|
#endif /* IS_ALT_TAB */
|
|
|
|
#if (WINXP_FASTER_ALT_TAB_FIX || WINXP_ALT_TAB_FIX)
|
|
ddsd.dwSize = sizeof(ddsd);
|
|
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
|
|
ddsd.dwWidth = xRes;
|
|
ddsd.dwHeight = yRes;
|
|
ddsd.dwRefreshRate = refresh;
|
|
|
|
/* Set these for use by the callback */
|
|
emcData.xRes = xRes;
|
|
emcData.yRes = yRes;
|
|
emcData.Refresh = refresh;
|
|
emcData.modeOK = FXFALSE;
|
|
emcData.bpp = bpp;
|
|
|
|
hResult = IDirectDraw2_EnumDisplayModes(lpDD, 0, &ddsd,
|
|
(LPVOID) &emcData, enumModesCallback);
|
|
|
|
if (hResult != DD_OK) {
|
|
GDBG_INFO(80, "Warning: EnumDisplayModes failed due to: \n");
|
|
msgEnumDisplayModes(hResult);
|
|
}
|
|
|
|
GDBG_INFO(80, "Setting Display Mode!\n");
|
|
|
|
if (emcData.modeOK) {
|
|
GDBG_INFO(80, "Found mode %dx%d. Attempting at %dHz\n", xRes,
|
|
yRes, refresh);
|
|
hResult = IDirectDraw2_SetDisplayMode( lpDD, xRes, yRes, bpp, refresh, 0);
|
|
if (hResult != DD_OK) {
|
|
GDBG_INFO(80, "Couldn't set display mode\n" );
|
|
msgModeSetFailure(hResult);
|
|
GDBG_INFO(80, "Retrying at default resolution\n");
|
|
hResult = IDirectDraw2_SetDisplayMode( lpDD, xRes, yRes, bpp, 0, 0 );
|
|
|
|
if (hResult != DD_OK) {
|
|
GDBG_INFO(80, "Setting video mode %dx%d@default refresh failed!\n",
|
|
xRes, yRes);
|
|
msgModeSetFailure(hResult);
|
|
|
|
if (!_set_vidmode_relaxed) {
|
|
GDBG_INFO(80, "Returning FXFALSE\n");
|
|
return FXFALSE;
|
|
} else {
|
|
GDBG_INFO(80, "Continuing operation due to relaxation condition\n");
|
|
}
|
|
}
|
|
}
|
|
GDBG_INFO(80, "Display Mode Set\n" );
|
|
} else {
|
|
|
|
GDBG_INFO(80, "Did not find mode %dx%d@any refresh\n", xRes, yRes);
|
|
GDBG_INFO(80, "Setting video mode %dx%d@default refresh\n", xRes, yRes);
|
|
|
|
#if 0 /* This only works for single display systems */
|
|
/*
|
|
** This is really a hack here. We use the registry key entry to work
|
|
** around DDraw refresh rate problem.
|
|
*/
|
|
{
|
|
static char *regPath = NULL;
|
|
char mpath[256], mpath_8[256], tmp[32];
|
|
FxU32 reg_flag = 1;
|
|
if (regPath == NULL) {
|
|
regPath = getModesRegPath();
|
|
}
|
|
if ((regPath) && (bpp == 8)) {
|
|
HKEY hKey, hKey8;
|
|
FxU32 retVal;
|
|
DWORD type, szData, type8, szData8;
|
|
static char strval[255], strval8[255];
|
|
|
|
/* get the current bpp path */
|
|
szData = sizeof(strval);
|
|
strcpy(mpath, regPath);
|
|
sprintf(tmp, "%d\\%d,%d",devMode.dmBitsPerPel,xRes,yRes);
|
|
strcat(mpath, tmp);
|
|
/* get the 8 bpp path */
|
|
szData8 = sizeof(strval8);
|
|
strcpy(mpath_8, regPath);
|
|
sprintf(tmp, "8\\%d,%d",xRes,yRes);
|
|
strcat(mpath_8, tmp);
|
|
/*
|
|
** Get the original refresh rate from registry key
|
|
*/
|
|
if (RegOpenKey(HKEY_LOCAL_MACHINE, mpath, &hKey) == ERROR_SUCCESS) {
|
|
if (RegQueryValueEx(hKey, "RefreshRate", NULL, &type, strval,
|
|
&szData) == ERROR_SUCCESS) {
|
|
/*
|
|
** overwrite 8 bit registry with glide refresh rate and set
|
|
** the display mode. this is a workaround of the DDraw
|
|
** refresh rate problem
|
|
*/
|
|
if (RegOpenKey(HKEY_LOCAL_MACHINE, mpath_8, &hKey8)
|
|
== ERROR_SUCCESS) {
|
|
if (RegQueryValueEx(hKey8, "RefreshRate", NULL, &type8,
|
|
strval8, &szData8) == ERROR_SUCCESS) {
|
|
retVal = 1;
|
|
} else {
|
|
retVal = 0;
|
|
}
|
|
RegSetValueEx(hKey8, "RefreshRate", 0, REG_SZ, strval,
|
|
strlen(strval));
|
|
hResult = IDirectDraw2_SetDisplayMode(lpDD, xRes, yRes,
|
|
bpp, 0, 0);
|
|
reg_flag = 0;
|
|
/*
|
|
** reset the original refresh rate
|
|
*/
|
|
if (retVal) {
|
|
RegSetValueEx(hKey8, "RefreshRate", 0,
|
|
REG_SZ, strval8, strlen(strval8));
|
|
}
|
|
RegCloseKey(hKey8);
|
|
/*
|
|
** delete the key if the refresh rate isn't there in the
|
|
** first place
|
|
*/
|
|
if (!retVal) {
|
|
RegDeleteValue(hKey8, "RefreshRate" );
|
|
RegDeleteKey(hKey8, "RefreshRate" );
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
} else {
|
|
/*
|
|
** We did not find the "RefreshRate" key in the
|
|
** devMode.dmBitsPerPel node so let's see if it exists for
|
|
** this resolution under the 8 bpp node:
|
|
*/
|
|
if (RegOpenKey(HKEY_LOCAL_MACHINE, mpath_8, &hKey8)
|
|
== ERROR_SUCCESS) {
|
|
if (RegQueryValueEx(hKey8, "RefreshRate", NULL, &type8, strval8,
|
|
&szData8) == ERROR_SUCCESS) {
|
|
retVal = 1;
|
|
} else {
|
|
retVal = 0;
|
|
}
|
|
RegSetValueEx(hKey8, "RefreshRate", 0, REG_SZ, strval,
|
|
strlen(strval));
|
|
hResult = IDirectDraw2_SetDisplayMode(lpDD, xRes, yRes,
|
|
bpp, 0, 0);
|
|
reg_flag = 0;
|
|
/*
|
|
** reset the original refresh rate
|
|
*/
|
|
if (retVal) {
|
|
RegSetValueEx(hKey8, "RefreshRate", 0,
|
|
REG_SZ, strval8, strlen(strval8));
|
|
}
|
|
RegCloseKey(hKey8);
|
|
/*
|
|
** delete the key if the refresh rate isn't there in the
|
|
** first place
|
|
*/
|
|
if (!retVal) {
|
|
RegDeleteValue(hKey8, "RefreshRate" );
|
|
RegDeleteKey(hKey8, "RefreshRate" );
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (reg_flag)
|
|
hResult = IDirectDraw2_SetDisplayMode( lpDD, xRes, yRes, bpp, 0, 0 );
|
|
}
|
|
#else
|
|
hResult = IDirectDraw2_SetDisplayMode( lpDD, xRes, yRes, bpp, 0, 0 );
|
|
#endif
|
|
|
|
if (hResult != DD_OK) {
|
|
GDBG_INFO(80, "Failed!\n",
|
|
xRes, yRes);
|
|
msgModeSetFailure(hResult);
|
|
if (!_set_vidmode_relaxed) {
|
|
GDBG_INFO(80, "Returning FXFALSE\n");
|
|
return FXFALSE;
|
|
} else {
|
|
GDBG_INFO(80, "Continuing operation due to relaxation condition\n");
|
|
}
|
|
}
|
|
}
|
|
#endif /* WINXP_FASTER_ALT_TAB_FIX || WINXP_ALT_TAB_FIX */
|
|
|
|
return FXTRUE;
|
|
|
|
} /* setVideoMode */
|
|
|
|
void
|
|
resetVideo( void )
|
|
{
|
|
#define FN_NAME "resetVideo"
|
|
|
|
#ifdef IS_ALT_TAB
|
|
FxU32 OS = hwcGetOS();
|
|
#endif
|
|
|
|
GDBG_INFO(80, "%s: called!\n", FN_NAME);
|
|
|
|
if ( lpDD != NULL ) {
|
|
GDBG_INFO(80, "%s: has lpDD!\n", FN_NAME);
|
|
|
|
#if (WINXP_FASTER_ALT_TAB_FIX || WINXP_ALT_TAB_FIX)
|
|
IDirectDraw2_RestoreDisplayMode( lpDD );
|
|
GDBG_INFO(80, "%s: Restored Display Mode!\n", FN_NAME);
|
|
#endif
|
|
|
|
IDirectDraw2_SetCooperativeLevel( lpDD, hwndApp, DDSCL_NORMAL );
|
|
GDBG_INFO(80, "%s: Set cooperative level!\n", FN_NAME);
|
|
|
|
IDirectDraw2_Release( lpDD );
|
|
GDBG_INFO(80, "%s: Released lpDD!\n", FN_NAME);
|
|
|
|
#if WINXP_ALT_TAB_FIX
|
|
if ( lpDD4 ) {
|
|
IDirectDraw_Release( lpDD4 );
|
|
GDBG_INFO(80, "%s: Released lpDD4!\n", FN_NAME);
|
|
}
|
|
#endif
|
|
|
|
if ( lpDD1 != NULL ) {
|
|
GDBG_INFO(80, "%s: has lpDD1!\n", FN_NAME);
|
|
IDirectDraw_Release( lpDD1 );
|
|
GDBG_INFO(80, "%s: Released lpDD1!\n", FN_NAME);
|
|
}
|
|
}
|
|
|
|
lpDD = NULL;
|
|
lpDD1 = NULL;
|
|
#if WINXP_ALT_TAB_FIX
|
|
lpDD4 = NULL;
|
|
#endif
|
|
|
|
#ifdef IS_ALT_TAB
|
|
//ChangeDisplaySettings(NULL, 0);
|
|
if ((OS == OS_WIN32_95) ||
|
|
(OS == OS_WIN32_NT4))
|
|
{
|
|
// win95,nt4
|
|
/* KoolSmoky - ripped from quake3 */
|
|
ChangeDisplaySettings(&curDevMode, CDS_RESET);
|
|
} else {
|
|
// win98,win2k,winxp
|
|
/* KoolSmoky - ripped from quake3 */
|
|
ChangeDisplaySettingsEx(curDeviceName, &curDevMode, NULL, CDS_RESET, NULL);
|
|
}
|
|
#endif
|
|
|
|
return;
|
|
#undef FN_NAME
|
|
} /* resetVideo */
|
|
|
|
typedef struct WidthHeight_s {
|
|
FxU32 width;
|
|
FxU32 height;
|
|
} WidthHeight_t;
|
|
|
|
static WidthHeight_t widthHeightByResolution[] = {
|
|
{320, 200}, /* GR_RESOLUTION_320x200 */
|
|
{320, 240}, /* GR_RESOLUTION_320x240 */
|
|
{400, 256}, /* GR_RESOLUTION_400x256 */
|
|
{512, 384}, /* GR_RESOLUTION_512x384 */
|
|
{640, 200}, /* GR_RESOLUTION_640x200 */
|
|
{640, 350}, /* GR_RESOLUTION_640x350 */
|
|
{640, 400}, /* GR_RESOLUTION_640x400 */
|
|
{640, 480}, /* GR_RESOLUTION_640x480 */
|
|
{800, 600}, /* GR_RESOLUTION_800x600 */
|
|
{960, 720}, /* GR_RESOLUTION_960x720 */
|
|
{856, 480}, /* GR_RESOLUTION_856x480 */
|
|
{512, 256}, /* GR_RESOLUTION_512x256 */
|
|
{1024, 768}, /* GR_RESOLUTION_1024x768 */
|
|
{1280, 1024}, /* GR_RESOLUTION_1280x1024 */
|
|
{1600, 1200}, /* GR_RESOLUTION_1600x1200 */
|
|
{400, 300}, /* GR_RESOLUTION_400x300 */
|
|
{1152, 864}, /* GR_RESOLUTION_1152x864 */
|
|
{1280, 960}, /* GR_RESOLUTION_1280x960 */
|
|
{1600, 1024}, /* GR_RESOLUTION_1600x1024 */
|
|
{1792, 1344}, /* GR_RESOLUTION_1792x1344 */
|
|
{1856, 1392}, /* GR_RESOLUTION_1856x1392 */
|
|
{1920, 1440}, /* GR_RESOLUTION_1920x1440 */
|
|
{2048, 1536}, /* GR_RESOLUTION_2048x1536 */
|
|
{2048, 2048} /* GR_RESOLUTION_2048x2048 */
|
|
};
|
|
|
|
static char *resNames[] = {
|
|
"GR_RESOLUTION_320x200",
|
|
"GR_RESOLUTION_320x240",
|
|
"GR_RESOLUTION_400x256",
|
|
"GR_RESOLUTION_512x384",
|
|
"GR_RESOLUTION_640x200",
|
|
"GR_RESOLUTION_640x350",
|
|
"GR_RESOLUTION_640x400",
|
|
"GR_RESOLUTION_640x480",
|
|
"GR_RESOLUTION_800x600",
|
|
"GR_RESOLUTION_960x720",
|
|
"GR_RESOLUTION_856x480",
|
|
"GR_RESOLUTION_512x256",
|
|
"GR_RESOLUTION_1024x768",
|
|
"GR_RESOLUTION_1280x1024",
|
|
"GR_RESOLUTION_1600x1200",
|
|
"GR_RESOLUTION_400x300",
|
|
"GR_RESOLUTION_1152x864",
|
|
"GR_RESOLUTION_1280x960",
|
|
"GR_RESOLUTION_1600x1024",
|
|
"GR_RESOLUTION_1792x1344",
|
|
"GR_RESOLUTION_1856x1392",
|
|
"GR_RESOLUTION_1920x1440",
|
|
"GR_RESOLUTION_2048x1536",
|
|
"GR_RESOLUTION_2048x2048"
|
|
};
|
|
|
|
static FxU32 refresh[] = {
|
|
60, //"GR_REFRESH_60Hz",
|
|
70, //"GR_REFRESH_70Hz",
|
|
72, //"GR_REFRESH_72Hz",
|
|
75, //"GR_REFRESH_75Hz",
|
|
80, //"GR_REFRESH_80Hz",
|
|
90, //"GR_REFRESH_90Hz",
|
|
100, //"GR_REFRESH_100Hz",
|
|
85, //"GR_REFRESH_85Hz",
|
|
120 //"GR_REFRESH_120Hz"
|
|
};
|
|
|
|
|
|
#ifdef IS_ALT_TAB
|
|
/*
|
|
** checkResolution - check to see if a given resolution is available
|
|
**
|
|
** This routine may only be called once and IT MUST BE CALLED FROM
|
|
** hwcInit().
|
|
** Any other useage will be very very bad, as it will mess with the
|
|
** app's DirectDraw context.
|
|
*/
|
|
/* KoolSmoky - we won't mess with ddraw context anymore, we will be
|
|
** very very good.
|
|
*/
|
|
FxBool
|
|
checkResolutions( FxBool *supportedByResolution, FxU32 stride, void *hmon, int h3pixelSize, char *devicename)
|
|
{
|
|
#define FN_NAME "checkResolution"
|
|
DEVMODE chkDevMode;
|
|
DWORD chkRes, chkRefresh;
|
|
FxU32 OS = hwcGetOS();
|
|
|
|
GDBG_INFO(80, "%s: called!\n", FN_NAME);
|
|
|
|
chkDevMode.dmSize = sizeof(DEVMODE);
|
|
chkDevMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
|
|
|
|
for(chkRes = 0x0;
|
|
chkRes < (sizeof(widthHeightByResolution) / sizeof(WidthHeight_t));
|
|
chkRes++) {
|
|
for (chkRefresh = 0 ;
|
|
chkRefresh < (sizeof(refresh) / sizeof(FxU32)) ;
|
|
chkRefresh++) {
|
|
chkDevMode.dmPelsWidth = widthHeightByResolution[chkRes].width;
|
|
chkDevMode.dmPelsHeight = widthHeightByResolution[chkRes].height;
|
|
|
|
if(h3pixelSize == 4)
|
|
chkDevMode.dmBitsPerPel = 32UL;
|
|
else
|
|
chkDevMode.dmBitsPerPel = 16UL;
|
|
|
|
chkDevMode.dmDisplayFrequency = refresh[chkRefresh];
|
|
|
|
//ChangeDisplaySettings(NULL, 0);
|
|
if ((OS == OS_WIN32_95) ||
|
|
(OS == OS_WIN32_NT4))
|
|
{
|
|
// win95,nt4
|
|
if(ChangeDisplaySettings(&chkDevMode, CDS_TEST) == DISP_CHANGE_SUCCESSFUL)
|
|
supportedByResolution[chkRes*stride + chkRefresh] = FXTRUE;
|
|
else
|
|
supportedByResolution[chkRes*stride + chkRefresh] = FXFALSE;
|
|
} else {
|
|
// win98,win2k,winxp
|
|
if(ChangeDisplaySettingsEx(devicename, &chkDevMode, NULL, CDS_TEST, NULL) == DISP_CHANGE_SUCCESSFUL)
|
|
supportedByResolution[chkRes*stride + chkRefresh] = FXTRUE;
|
|
else
|
|
supportedByResolution[chkRes*stride + chkRefresh] = FXFALSE;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return FXTRUE;
|
|
#undef FN_NAME
|
|
} /* checkResolutions */
|
|
#endif /* IS_ALT_TAB */
|
|
|
|
#if (WINXP_FASTER_ALT_TAB_FIX || WINXP_ALT_TAB_FIX)
|
|
|
|
static FxU32 resStride = 0;
|
|
|
|
static HRESULT WINAPI
|
|
checkResEMCallback(LPDDSURFACEDESC surfaceDesc, LPVOID lpContext)
|
|
{
|
|
#define FN_NAME "checkResEMCallback"
|
|
FxBool *resList = (FxBool *) lpContext;
|
|
int res, ref;
|
|
|
|
GDBG_INFO(80, FN_NAME ":\n");
|
|
GDBG_INFO(80, FN_NAME "\tsurfaceDesc->dwWidth == %d\n",surfaceDesc->dwWidth);
|
|
GDBG_INFO(80, FN_NAME
|
|
"\tsurfaceDesc->dwHeight == %d\n",surfaceDesc->dwHeight);
|
|
GDBG_INFO(80, FN_NAME
|
|
"\tsurfaceDesc->dwRefreshRate == %d\n",surfaceDesc->dwRefreshRate);
|
|
GDBG_INFO(80, FN_NAME
|
|
"\tsurfaceDesc->ddpfPixelFormat.dwRGBBitCount == %d\n",
|
|
surfaceDesc->ddpfPixelFormat.dwRGBBitCount);
|
|
|
|
for (
|
|
res = 0x0;
|
|
res < (sizeof(widthHeightByResolution) / sizeof(WidthHeight_t));
|
|
res++) {
|
|
if (
|
|
(surfaceDesc->dwWidth == widthHeightByResolution[res].width) &&
|
|
(surfaceDesc->dwHeight == widthHeightByResolution[res].height)
|
|
) {
|
|
for (ref = 0; ref < (sizeof(refresh) / sizeof(FxU32)); ref++) {
|
|
if (surfaceDesc->dwRefreshRate == 0 || surfaceDesc->dwRefreshRate == refresh[ref])
|
|
resList[res*resStride+ref] = FXTRUE;
|
|
}
|
|
return DDENUMRET_OK;
|
|
}
|
|
}
|
|
|
|
return DDENUMRET_OK;
|
|
#undef FN_NAME
|
|
} /* checkResEMCallback */
|
|
|
|
/*
|
|
** checkResolution - check to see if a given resolution is available
|
|
**
|
|
** This routine may only be called once and IT MUST BE CALLED FROM
|
|
** hwcInit().
|
|
** Any other useage will be very very bad, as it will mess with the
|
|
** app's DirectDraw context.
|
|
*/
|
|
FxBool
|
|
checkResolutions(FxBool *supportedByResolution, FxU32 stride, void *hmon)
|
|
{
|
|
#define FN_NAME "checkResolution"
|
|
LPGUID ddGuid = NULL;
|
|
HMODULE ddraw = NULL;
|
|
HRESULT hResult;
|
|
|
|
hwndApp = GetActiveWindow();
|
|
|
|
if ( hwndApp == NULL ) {
|
|
GDBG_INFO( 80, "Couldn't get a valid window handle\n" );
|
|
}
|
|
|
|
resStride = stride;
|
|
|
|
ddGuid = NULL;
|
|
ddraw = GetModuleHandle( "ddraw.dll" );
|
|
if ( ddraw ) {
|
|
LPDIRECTDRAWENUMERATEEXA ddEnumEx;
|
|
ddEnumEx = (void*)GetProcAddress( ddraw, "DirectDrawEnumerateExA" );
|
|
if ( ddEnumEx ) {
|
|
DWORD data[2];
|
|
data[0] = (DWORD)hmon;
|
|
data[1] = 0;
|
|
ddEnumEx( ddEnumCbEx, data, DDENUM_ATTACHEDSECONDARYDEVICES );
|
|
if ( data[1] ) {
|
|
ddGuid = (LPGUID)data[1];
|
|
}
|
|
}
|
|
}
|
|
|
|
//checkSpecialList();
|
|
if (lpDD == NULL) {
|
|
/* only create directdraw object once */
|
|
if ( DirectDrawCreate( ddGuid, &lpDD1, NULL ) != DD_OK) {
|
|
GDBG_INFO(80, "DDraw Obj Create Failed!\n");
|
|
}
|
|
else GDBG_INFO(80, "DDraw Obj created!\n");
|
|
if ( IDirectDraw_QueryInterface( lpDD1, &IID_IDirectDraw2,
|
|
(LPVOID*)&lpDD ) != DD_OK ) {
|
|
IDirectDraw_Release( lpDD1 );
|
|
#if WINXP_ALT_TAB_FIX
|
|
lpDD4 = NULL;
|
|
#endif
|
|
lpDD1 = NULL;
|
|
lpDD = NULL;
|
|
GDBG_INFO(80, "DDraw Obj Create Failed!\n");
|
|
return FXFALSE;
|
|
}
|
|
else GDBG_INFO(80, "DDraw2 Obj created!\n");
|
|
#if WINXP_ALT_TAB_FIX
|
|
if ( IDirectDraw_QueryInterface( lpDD1, &IID_IDirectDraw4,
|
|
(LPVOID*)&lpDD4 ) != DD_OK ) {
|
|
IDirectDraw_Release( lpDD );
|
|
IDirectDraw_Release( lpDD1 );
|
|
lpDD4 = NULL;
|
|
lpDD1 = NULL;
|
|
lpDD = NULL;
|
|
GDBG_INFO(80, "DDraw Obj Create Failed!\n");
|
|
return FXFALSE;
|
|
}
|
|
else GDBG_INFO(80, "DDraw4 Obj created!\n");
|
|
#endif
|
|
}
|
|
|
|
hResult = IDirectDraw2_EnumDisplayModes(lpDD, 0, NULL,
|
|
(LPVOID) supportedByResolution,
|
|
checkResEMCallback);
|
|
|
|
resetVideo();
|
|
return FXTRUE;
|
|
#undef FN_NAME
|
|
} /* checkResolutions */
|
|
|
|
#endif /* WINXP_FASTER_ALT_TAB_FIX || WINXP_ALT_TAB_FIX */
|
|
|
|
|
|
void EnableOpenGL( char *regpath )
|
|
{
|
|
GDBG_INFO(80, "EnableOpenGL: called!\n");
|
|
|
|
opengl_regpath = regpath;
|
|
|
|
#ifdef IS_ALT_TAB
|
|
is_opengl = FXTRUE;
|
|
#endif
|
|
|
|
GDBG_INFO(80, "opengl regpath: %s\n", opengl_regpath);
|
|
|
|
} /* EnableOpenGL */ |