mirror of
https://github.com/isledecomp/isle.git
synced 2025-10-23 00:14:22 +00:00
CONFIG (#1627)
This commit is contained in:
@@ -3,140 +3,255 @@
|
||||
#include <ddraw.h>
|
||||
#include <dinput.h>
|
||||
|
||||
typedef HRESULT WINAPI DirectDrawCreate_fn(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnknown FAR* pUnkOuter);
|
||||
typedef HRESULT WINAPI
|
||||
DirectInputCreateA_fn(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA* ppDI, LPUNKNOWN punkOuter);
|
||||
typedef HRESULT(WINAPI* DIRECTDRAWCREATE)(GUID*, LPDIRECTDRAW*, IUnknown*);
|
||||
typedef HRESULT(WINAPI* DIRECTINPUTCREATE)(HINSTANCE, DWORD, LPDIRECTINPUT*, IUnknown*);
|
||||
|
||||
// FUNCTION: CONFIG 0x004048f0
|
||||
BOOL DetectDirectX5()
|
||||
{
|
||||
unsigned int version;
|
||||
BOOL found;
|
||||
DetectDirectX(&version, &found);
|
||||
DWORD version;
|
||||
DWORD platform;
|
||||
GetDXVersion(&version, &platform);
|
||||
return version >= 0x500;
|
||||
}
|
||||
|
||||
// FUNCTION: CONFIG 0x00404920
|
||||
void DetectDirectX(unsigned int* p_version, BOOL* p_found)
|
||||
void GetDXVersion(LPDWORD pdwDXVersion, LPDWORD pdwDXPlatform)
|
||||
{
|
||||
OSVERSIONINFOA os_version;
|
||||
// From GetDXVer.cpp
|
||||
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;
|
||||
|
||||
os_version.dwOSVersionInfoSize = sizeof(os_version);
|
||||
if (!GetVersionEx(&os_version)) {
|
||||
*p_version = 0;
|
||||
*p_found = 0;
|
||||
/*
|
||||
* First get the windows platform
|
||||
*/
|
||||
osVer.dwOSVersionInfoSize = sizeof(osVer);
|
||||
if (!GetVersionEx(&osVer)) {
|
||||
*pdwDXVersion = 0;
|
||||
*pdwDXPlatform = 0;
|
||||
return;
|
||||
}
|
||||
if (os_version.dwPlatformId == 2) {
|
||||
*p_found = 2;
|
||||
if (os_version.dwMajorVersion < 4) {
|
||||
*p_found = 0;
|
||||
|
||||
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 (os_version.dwMajorVersion != 4) {
|
||||
*p_version = 0x501;
|
||||
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
|
||||
*/
|
||||
OutputDebugString("Couldn't LoadLibrary DInput\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
DirectInputCreate = (DIRECTINPUTCREATE) GetProcAddress(DIHinst, "DirectInputCreateA");
|
||||
FreeLibrary(DIHinst);
|
||||
|
||||
if (DirectInputCreate == 0) {
|
||||
/*
|
||||
* No DInput... must be pre-SP3 DX2
|
||||
*/
|
||||
OutputDebugString("Couldn't GetProcAddress DInputCreate\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* It must be NT4, DX2
|
||||
*/
|
||||
*pdwDXVersion = 0x300; // DX3 on NT4 SP3 or higher
|
||||
return;
|
||||
}
|
||||
*p_version = 0x200;
|
||||
HMODULE dinput_module = LoadLibrary("DINPUT.DLL");
|
||||
if (!dinput_module) {
|
||||
OutputDebugString("Couldn't LoadLibrary DInput\r\n");
|
||||
return;
|
||||
}
|
||||
DirectInputCreateA_fn* func_DirectInputCreateA =
|
||||
(DirectInputCreateA_fn*) GetProcAddress(dinput_module, "DirectInputCreateA");
|
||||
FreeLibrary(dinput_module);
|
||||
if (!func_DirectInputCreateA) {
|
||||
OutputDebugString("Couldn't GetProcAddress DInputCreate\r\n");
|
||||
return;
|
||||
}
|
||||
*p_version = 0x300;
|
||||
/*
|
||||
* Else it's NT5 or higher, and it's DX5a or higher:
|
||||
*/
|
||||
*pdwDXVersion = 0x501; // DX5a on NT5
|
||||
return;
|
||||
}
|
||||
*p_found = 1;
|
||||
if (LOWORD(os_version.dwBuildNumber) >= 0x550) {
|
||||
*p_version = 0x501;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
HMODULE ddraw_module = LoadLibrary("DDRAW.DLL");
|
||||
if (!ddraw_module) {
|
||||
*p_version = 0;
|
||||
*p_found = 0;
|
||||
FreeLibrary(ddraw_module);
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
DirectDrawCreate_fn* func_DirectDrawCreate =
|
||||
(DirectDrawCreate_fn*) GetProcAddress(ddraw_module, "DirectDrawCreate");
|
||||
if (!func_DirectDrawCreate) {
|
||||
*p_version = 0;
|
||||
*p_found = 0;
|
||||
FreeLibrary(ddraw_module);
|
||||
|
||||
/*
|
||||
* See if we can create the DirectDraw object.
|
||||
*/
|
||||
DirectDrawCreate = (DIRECTDRAWCREATE) GetProcAddress(DDHinst, "DirectDrawCreate");
|
||||
if (DirectDrawCreate == 0) {
|
||||
*pdwDXVersion = 0;
|
||||
*pdwDXPlatform = 0;
|
||||
FreeLibrary(DDHinst);
|
||||
OutputDebugString("Couldn't LoadLibrary DDraw\r\n");
|
||||
return;
|
||||
}
|
||||
LPDIRECTDRAW ddraw;
|
||||
if (FAILED(func_DirectDrawCreate(NULL, &ddraw, NULL))) {
|
||||
*p_version = 0;
|
||||
*p_found = 0;
|
||||
FreeLibrary(ddraw_module);
|
||||
|
||||
hr = DirectDrawCreate(NULL, &pDDraw, NULL);
|
||||
if (FAILED(hr)) {
|
||||
*pdwDXVersion = 0;
|
||||
*pdwDXPlatform = 0;
|
||||
FreeLibrary(DDHinst);
|
||||
OutputDebugString("Couldn't create DDraw\r\n");
|
||||
return;
|
||||
}
|
||||
*p_version = 0x100;
|
||||
LPDIRECTDRAW2 ddraw2;
|
||||
if (FAILED(ddraw->QueryInterface(IID_IDirectDraw2, (LPVOID*) &ddraw2))) {
|
||||
ddraw->Release();
|
||||
FreeLibrary(ddraw_module);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
OutputDebugString("Couldn't QI DDraw2\r\n");
|
||||
return;
|
||||
}
|
||||
ddraw->Release();
|
||||
*p_version = 0x200;
|
||||
HMODULE dinput_module = LoadLibrary("DINPUT.DLL");
|
||||
if (!dinput_module) {
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
OutputDebugString("Couldn't LoadLibrary DInput\r\n");
|
||||
ddraw2->Release();
|
||||
FreeLibrary(ddraw_module);
|
||||
pDDraw->Release();
|
||||
FreeLibrary(DDHinst);
|
||||
return;
|
||||
}
|
||||
DirectInputCreateA_fn* func_DirectInputCreateA =
|
||||
(DirectInputCreateA_fn*) GetProcAddress(dinput_module, "DirectInputCreateA");
|
||||
FreeLibrary(dinput_module);
|
||||
if (!func_DirectInputCreateA) {
|
||||
FreeLibrary(ddraw_module);
|
||||
ddraw2->Release();
|
||||
|
||||
DirectInputCreate = (DIRECTINPUTCREATE) GetProcAddress(DIHinst, "DirectInputCreateA");
|
||||
FreeLibrary(DIHinst);
|
||||
|
||||
if (DirectInputCreate == 0) {
|
||||
/*
|
||||
* No DInput... must be DX2
|
||||
*/
|
||||
FreeLibrary(DDHinst);
|
||||
pDDraw->Release();
|
||||
OutputDebugString("Couldn't GetProcAddress DInputCreate\r\n");
|
||||
return;
|
||||
}
|
||||
*p_version = 0x300;
|
||||
DDSURFACEDESC surface_desc;
|
||||
memset(&surface_desc, 0, sizeof(surface_desc));
|
||||
surface_desc.dwSize = sizeof(surface_desc);
|
||||
surface_desc.dwFlags = DDSD_CAPS;
|
||||
surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
|
||||
if (FAILED(ddraw2->SetCooperativeLevel(NULL, DDSCL_NORMAL))) {
|
||||
ddraw2->Release();
|
||||
FreeLibrary(ddraw_module);
|
||||
*p_version = 0;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
OutputDebugString("Couldn't Set coop level\r\n");
|
||||
return;
|
||||
}
|
||||
LPDIRECTDRAWSURFACE surface;
|
||||
if (FAILED(ddraw2->CreateSurface(&surface_desc, &surface, NULL))) {
|
||||
ddraw2->Release();
|
||||
FreeLibrary(ddraw_module);
|
||||
*p_version = 0;
|
||||
|
||||
hr = pDDraw->CreateSurface(&desc, &pSurf, NULL);
|
||||
if (FAILED(hr)) {
|
||||
/*
|
||||
* Failure. This means DDraw isn't properly installed.
|
||||
*/
|
||||
pDDraw->Release();
|
||||
FreeLibrary(DDHinst);
|
||||
*pdwDXVersion = 0;
|
||||
OutputDebugString("Couldn't CreateSurface\r\n");
|
||||
return;
|
||||
}
|
||||
LPDIRECTDRAWSURFACE3 surface3;
|
||||
if (FAILED(surface->QueryInterface(IID_IDirectDrawSurface3, (LPVOID*) &surface3))) {
|
||||
ddraw2->Release();
|
||||
FreeLibrary(ddraw_module);
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
*p_version = 0x500;
|
||||
surface3->Release();
|
||||
ddraw2->Release();
|
||||
FreeLibrary(ddraw_module);
|
||||
|
||||
/*
|
||||
* QI for IDirectDrawSurface3 succeeded. We must be at least DX5
|
||||
*/
|
||||
*pdwDXVersion = 0x500;
|
||||
|
||||
pSurf->Release();
|
||||
pDDraw->Release();
|
||||
FreeLibrary(DDHinst);
|
||||
|
||||
return;
|
||||
}
|
||||
|
Reference in New Issue
Block a user