📄 cdxapp.cpp
字号:
#include "stdcdx.h"
#include <windowsx.h>
#include "CDXApp.h"
#include <stdio.h>
#include <memory.h>
#include <time.h>
#include <stdarg.h>
#ifdef _DEBUG
#define FRAME_INTERVAL 50
static struct
{
HFONT hFont;
SIZE sizeStats;
SIZE sizeInfo;
DWORD dwIntervalCount;
DWORD dwFrameCount;
DWORD dwLastFrames;
DWORD dwLastTriangles;
DWORD dwTPS;
float floatFPS;
time_t timeLast;
BOOL bValid;
} gStats;
#endif //_DEBUG
static BOOL bHardware=FALSE;
static BOOL bMono=FALSE;
extern LONG FAR PASCAL CDXWindowProc( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam );
static DWORD BPPToDDBD( int nBitsPerPixel )
{
switch( nBitsPerPixel )
{
case 1: return( DDBD_1 );
case 2: return( DDBD_2 );
case 4: return( DDBD_4 );
case 8: return( DDBD_8 );
case 16: return( DDBD_16 );
case 24: return( DDBD_24 );
case 32: return( DDBD_32 );
}
return( 0 );
}
static HRESULT WINAPI enumDeviceFunc( LPGUID lpGUID,LPSTR lpDeviceDesc,LPSTR lpDeviceName,LPD3DDEVICEDESC lpHWDesc,LPD3DDEVICEDESC lpHELDesc,LPVOID lpContext )
{
LPD3DDEVICEDESC lpDesc;
int *lpStartDriver=(int *)lpContext;
BOOL bFirstTime=(*lpStartDriver==-1);
/* Decide which device description should be used */
lpDesc = lpHWDesc->dcmColorModel ? lpHWDesc : lpHELDesc;
/* If this driver cannot support the required bit depth trivially reject it */
if ( !(lpDesc->dwDeviceRenderBitDepth&BPPToDDBD(pApp->GetBitDepth())) )
{
return( D3DENUMRET_OK );
}
/* Record this driver's name and GUID */
pApp->AddEnumDevice( lpGUID,lpDeviceName );
/* Choose hardware over software and RGB over mono lights */
if ( bFirstTime )
{
/* Initialise our determinant variables */
*lpStartDriver = pApp->GetNumDrivers() - 1;
bHardware = (lpDesc==lpHWDesc);
bMono = (lpDesc->dcmColorModel&D3DCOLOR_MONO)?TRUE:FALSE;
}
else if ( lpDesc==lpHWDesc && (!bHardware || lpDesc->dcmColorModel==pApp->GetPreferedColorModel()))
{
/* Choose this hardware driver */
*lpStartDriver = pApp->GetNumDrivers() - 1;
bHardware = (lpDesc==lpHWDesc);
bMono = (lpDesc->dcmColorModel&D3DCOLOR_MONO)?TRUE:FALSE;
}
else if ( (lpDesc==lpHWDesc && bHardware) || (lpDesc==lpHELDesc && !bHardware) )
{
/* Both the current and this device are the same (hardware/software). */
/* Choose this one if the lights are not mono and we have an MMX */
if ( (lpDesc->dcmColorModel==pApp->GetPreferedColorModel() && !bHardware) || (bMono && pApp->IsMMX() && lpDesc->dcmColorModel&D3DCOLOR_RGB) )
{
*lpStartDriver = pApp->GetNumDrivers() - 1;
bHardware = (lpDesc==lpHWDesc);
bMono = (lpDesc->dcmColorModel&D3DCOLOR_MONO)?TRUE:FALSE;
}
}
/* Don't enumerate more than allowed */
if ( pApp->GetNumDrivers() >= MAX_DRIVERS ) return( D3DENUMRET_CANCEL );
return( D3DENUMRET_OK );
}
typedef HRESULT (WINAPI *DIRECTDRAWCREATE)(GUID *, LPDIRECTDRAW *, IUnknown *);
typedef HRESULT (WINAPI *DIRECTINPUTCREATE)(HINSTANCE, DWORD, LPDIRECTINPUT *, IUnknown *);
static void GetDXVersion(LPDWORD pdwDXVersion, LPDWORD pdwDXPlatform)
{
HRESULT hr;
HINSTANCE DDHinst = 0;
HINSTANCE DIHinst = 0;
LPDIRECTDRAW pDDraw = 0;
LPDIRECTDRAW2 pDDraw2 = 0;
DIRECTDRAWCREATE DirectDrawCreate = 0;
DIRECTINPUTCREATE DirectInputCreate = 0;
OSVERSIONINFO osVer;
LPDIRECTDRAWSURFACE pSurf = 0;
LPDIRECTDRAWSURFACE3 pSurf3 = 0;
/*
* First get the windows platform
*/
osVer.dwOSVersionInfoSize = sizeof(osVer);
if (!GetVersionEx(&osVer))
{
*pdwDXVersion = 0;
*pdwDXPlatform = 0;
return;
}
if (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
*pdwDXPlatform = VER_PLATFORM_WIN32_NT;
/*
* NT is easy... NT 4.0 is DX2, 4.0 SP3 is DX3, 5.0 is DX5
* and no DX on earlier versions.
*/
if (osVer.dwMajorVersion < 4)
{
*pdwDXPlatform = 0; //No DX on NT3.51 or earlier
return;
}
if (osVer.dwMajorVersion == 4)
{
/*
* NT4 up to SP2 is DX2, and SP3 onwards is DX3, so we are at least DX2
*/
*pdwDXVersion = 0x200;
/*
* We're not supposed to be able to tell which SP we're on, so check for dinput
*/
DIHinst = LoadLibrary("DINPUT.DLL");
if (DIHinst == 0)
{
/*
* No DInput... must be DX2 on NT 4 pre-SP3
*/
pApp->ErrHandler( "GetDXVersion() Couldn't LoadLibrary DInput");
return;
}
DirectInputCreate = (DIRECTINPUTCREATE)GetProcAddress(DIHinst, "DirectInputCreateA");
FreeLibrary(DIHinst);
if (DirectInputCreate == 0)
{
/*
* No DInput... must be pre-SP3 DX2
*/
pApp->ErrHandler( "GetDXVersion() Couldn't GetProcAddress DInputCreate" );
return;
}
/*
* It must be NT4, DX2
*/
*pdwDXVersion = 0x300; //DX3 on NT4 SP3 or higher
return;
}
/*
* Else it's NT5 or higher, and it's DX5a or higher:
*/
*pdwDXVersion = 0x501; //DX5a on NT5
return;
}
/*
* Not NT... must be Win9x
*/
*pdwDXPlatform = VER_PLATFORM_WIN32_WINDOWS;
/*
* If we are on Memphis or higher, then we are at least DX5a
*/
if ( (osVer.dwBuildNumber & 0xffff) > 1353) //Check for higher than developer release
{
*pdwDXVersion = 0x501; //DX5a on Memphis or higher
return;
}
/*
* Now we know we are in Windows 9x (or maybe 3.1), so anything's possible.
* First see if DDRAW.DLL even exists.
*/
DDHinst = LoadLibrary("DDRAW.DLL");
if (DDHinst == 0)
{
*pdwDXVersion = 0;
*pdwDXPlatform = 0;
FreeLibrary(DDHinst);
return;
}
/*
* See if we can create the DirectDraw object.
*/
DirectDrawCreate = (DIRECTDRAWCREATE)GetProcAddress(DDHinst, "DirectDrawCreate");
if (DirectDrawCreate == 0)
{
*pdwDXVersion = 0;
*pdwDXPlatform = 0;
FreeLibrary(DDHinst);
pApp->ErrHandler( "GetDXVersion() Couldn't LoadLibrary DDraw" );
return;
}
hr = DirectDrawCreate(NULL, &pDDraw, NULL);
if (FAILED(hr))
{
*pdwDXVersion = 0;
*pdwDXPlatform = 0;
FreeLibrary(DDHinst);
pApp->ErrHandler("GetDXVersion() Couldn't create DDraw");
return;
}
/*
* So DirectDraw exists. We are at least DX1.
*/
*pdwDXVersion = 0x100;
/*
* Let's see if IID_IDirectDraw2 exists.
*/
hr = pDDraw->QueryInterface(IID_IDirectDraw2, (LPVOID *)&pDDraw2);
if (FAILED(hr))
{
/*
* No IDirectDraw2 exists... must be DX1
*/
pDDraw->Release();
FreeLibrary(DDHinst);
pApp->ErrHandler("GetDXVersion() Couldn't QI DDraw2");
return;
}
/*
* IDirectDraw2 exists. We must be at least DX2
*/
pDDraw2->Release();
*pdwDXVersion = 0x200;
/*
* See if we can create the DirectInput object.
*/
DIHinst = LoadLibrary("DINPUT.DLL");
if (DIHinst == 0)
{
/*
* No DInput... must be DX2
*/
pApp->ErrHandler("GetDXVersion() Couldn't LoadLibrary DInput");
pDDraw->Release();
FreeLibrary(DDHinst);
return;
}
DirectInputCreate = (DIRECTINPUTCREATE)GetProcAddress(DIHinst, "DirectInputCreateA");
FreeLibrary(DIHinst);
if (DirectInputCreate == 0)
{
/*
* No DInput... must be DX2
*/
FreeLibrary(DDHinst);
pDDraw->Release();
pApp->ErrHandler("GetDXVersion() Couldn't GetProcAddress DInputCreate");
return;
}
/*
* DirectInputCreate exists. That's enough to tell us that we are at least DX3
*/
*pdwDXVersion = 0x300;
/*
* Checks for 3a vs 3b?
*/
/*
* We can tell if DX5 is present by checking for the existence of IDirectDrawSurface3.
* First we need a surface to QI off of.
*/
DDSURFACEDESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_CAPS;
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
hr = pDDraw->SetCooperativeLevel(NULL,DDSCL_NORMAL);
if (FAILED(hr))
{
/*
* Failure. This means DDraw isn't properly installed.
*/
pDDraw->Release();
FreeLibrary(DDHinst);
*pdwDXVersion = 0;
pApp->ErrHandler("GetDXVersion() Couldn't Set coop level");
return;
}
hr = pDDraw->CreateSurface(&desc, &pSurf, NULL);
if (FAILED(hr))
{
/*
* Failure. This means DDraw isn't properly installed.
*/
pDDraw->Release();
FreeLibrary(DDHinst);
*pdwDXVersion = 0;
pApp->ErrHandler("GetDXVersion() Couldn't CreateSurface");
return;
}
/*
* Try for the IDirectDrawSurface3 interface. If it works, we're on DX5 at least
*/
if ( FAILED(pSurf->QueryInterface(IID_IDirectDrawSurface3,(LPVOID*)&pSurf3)) )
{
pDDraw->Release();
FreeLibrary(DDHinst);
return;
}
/*
* QI for IDirectDrawSurface3 succeeded. We must be at least DX5
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -