Initial commit
This commit is contained in:
657
Torque/SDK/engine/platformWin32/winV2Video.cc
Normal file
657
Torque/SDK/engine/platformWin32/winV2Video.cc
Normal file
@@ -0,0 +1,657 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platformWin32/platformGL.h"
|
||||
#include "platformWin32/platformWin32.h"
|
||||
#include "platform/platformAudio.h"
|
||||
#include "platformWin32/winV2Video.h"
|
||||
#include "platform/3Dfx.h"
|
||||
#include "console/console.h"
|
||||
#include "math/mPoint.h"
|
||||
#include "platform/event.h"
|
||||
#include "platform/gameInterface.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "console/ast.h"
|
||||
#include "core/fileStream.h"
|
||||
|
||||
|
||||
static U8 sResCode; // Used for initializing the resolution list only
|
||||
|
||||
static void execScript(const char *scriptFile)
|
||||
{
|
||||
// execute the script
|
||||
FileStream str;
|
||||
|
||||
if (!str.open(scriptFile, FileStream::Read))
|
||||
return;
|
||||
|
||||
U32 size = str.getStreamSize();
|
||||
char *script = new char[size + 1];
|
||||
|
||||
str.read(size, script);
|
||||
str.close();
|
||||
|
||||
script[size] = 0;
|
||||
Con::executef(2, "eval", script);
|
||||
delete[] script;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Voodoo2Device::Voodoo2Device()
|
||||
{
|
||||
initDevice();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Voodoo2Device::initDevice()
|
||||
{
|
||||
// Set the device name:
|
||||
mDeviceName = "Voodoo2";
|
||||
|
||||
// Set some initial conditions:
|
||||
mResolutionList.clear();
|
||||
mFullScreenOnly = true;
|
||||
|
||||
// Enumerate all available resolutions:
|
||||
Resolution newRes;
|
||||
newRes = Resolution( 640, 480, 16 );
|
||||
mResolutionList.push_back( newRes );
|
||||
|
||||
if ( sResCode & 1 )
|
||||
{
|
||||
newRes = Resolution( 800, 600, 16 );
|
||||
mResolutionList.push_back( newRes );
|
||||
}
|
||||
|
||||
if ( sResCode & 2 )
|
||||
{
|
||||
Con::printf( "SLI detected." );
|
||||
|
||||
newRes = Resolution( 960, 720, 16 );
|
||||
mResolutionList.push_back( newRes );
|
||||
|
||||
newRes = Resolution( 1024, 768, 16 );
|
||||
mResolutionList.push_back( newRes );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Voodoo2Device::activate( U32 width, U32 height, U32 /*bpp*/, bool /*fullScreen*/ )
|
||||
{
|
||||
bool needResurrect = false;
|
||||
|
||||
// If the rendering context exists, delete it:
|
||||
if ( winState.hGLRC )
|
||||
{
|
||||
Con::printf( "Killing the texture manager..." );
|
||||
Game->textureKill();
|
||||
needResurrect = true;
|
||||
|
||||
Con::printf( "Making the rendering context not current..." );
|
||||
if ( !dwglMakeCurrent( NULL, NULL ) )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::activate\ndwglMakeCurrent( NULL, NULL ) failed!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
Con::printf( "Deleting the rendering context..." );
|
||||
if ( !dwglDeleteContext( winState.hGLRC ) )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::activate\ndwglDeleteContext failed!" );
|
||||
return false;
|
||||
}
|
||||
winState.hGLRC = NULL;
|
||||
}
|
||||
|
||||
// If window already exists, kill it so we can start fresh:
|
||||
if ( winState.appWindow )
|
||||
{
|
||||
Con::printf( "Releasing the device context..." );
|
||||
ReleaseDC( winState.appWindow, winState.appDC );
|
||||
winState.appDC = NULL;
|
||||
|
||||
Con::printf( "Destroying the window..." );
|
||||
DestroyWindow( winState.appWindow );
|
||||
winState.appWindow = NULL;
|
||||
}
|
||||
|
||||
// If OpenGL library already loaded, shut it down and reload the 3Dfx standalone driver:
|
||||
if ( winState.hinstOpenGL )
|
||||
GL_Shutdown();
|
||||
|
||||
GL_Init( "3dfxvgl", "glu32" );
|
||||
|
||||
// This device only supports full-screen, so force it:
|
||||
smIsFullScreen = true;
|
||||
Con::setVariable( "$pref::Video::fullScreen", "true" );
|
||||
|
||||
// Create the new window:
|
||||
Con::printf( "Creating a new full-screen window..." );
|
||||
winState.appWindow = CreateOpenGLWindow( width, height, true );
|
||||
if ( !winState.appWindow )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::activate\nFailed to create a window!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get a device context from the new window:
|
||||
HDC tempDC = GetDC( winState.appWindow );
|
||||
if ( !tempDC )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::activate\nFailed to get a device context!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the pixel format of the new window:
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
CreatePixelFormat( &pfd, 16, 16, 8, false );
|
||||
S32 chosenFormat = ChooseBestPixelFormat( tempDC, &pfd );
|
||||
dwglDescribePixelFormat( tempDC, chosenFormat, sizeof( pfd ), &pfd );
|
||||
bool test = dwglSetPixelFormat( tempDC, chosenFormat, &pfd );
|
||||
ReleaseDC( winState.appWindow, tempDC );
|
||||
if ( !test )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::activate\nFailed to set the pixel format of the device context!" );
|
||||
return false;
|
||||
}
|
||||
Con::printf( "Pixel format set:" );
|
||||
Con::printf( " %d color bits, %d depth bits, %d stencil bits", pfd.cColorBits, pfd.cDepthBits, pfd.cStencilBits );
|
||||
|
||||
// Set the resolution:
|
||||
smCurrentRes.bpp = 16; // Force 16-bit color.
|
||||
if ( !setScreenMode( width, height, 16, true, true, false ) )
|
||||
return false;
|
||||
|
||||
// Output some driver info to the console:
|
||||
const char* vendorString = (const char*) glGetString( GL_VENDOR );
|
||||
const char* rendererString = (const char*) glGetString( GL_RENDERER );
|
||||
const char* versionString = (const char*) glGetString( GL_VERSION );
|
||||
Con::printf( "OpenGL driver information:" );
|
||||
if ( vendorString )
|
||||
Con::printf( " Vendor: %s", vendorString );
|
||||
if ( rendererString )
|
||||
Con::printf( " Renderer: %s", rendererString );
|
||||
if ( versionString )
|
||||
Con::printf( " Version: %s", versionString );
|
||||
|
||||
// Set a few variables:
|
||||
if ( Con::getIntVariable( "$pref::OpenGL::mipReduction" ) < 1 )
|
||||
Con::setIntVariable( "$pref::OpenGL::mipReduction", 1 );
|
||||
if ( Con::getIntVariable( "$pref::OpenGL::interiorMipReduction" ) < 1 )
|
||||
Con::setIntVariable( "$pref::OpenGL::interiorMipReduction", 1 );
|
||||
if ( Con::getIntVariable( "$pref::OpenGL::skyMipReduction" ) < 1 )
|
||||
Con::setIntVariable( "$pref::OpenGL::skyMipReduction", 1 );
|
||||
|
||||
if (dStrcmp(vendorString, Con::getVariable("$pref::Video::profiledVendor")) ||
|
||||
dStrcmp(rendererString, Con::getVariable("$pref::Video::profiledRenderer")))
|
||||
{
|
||||
// Voodoo2 defaults
|
||||
Con::setBoolVariable("$pref::OpenGL::disableEXTCompiledVertexArray", false);
|
||||
Con::setBoolVariable("$pref::OpenGL::disableSubImage", false);
|
||||
Con::setBoolVariable("$pref::OpenGL::noEnvColor", true);
|
||||
Con::setBoolVariable("$pref::OpenGL::disableARBTextureCompression", false);
|
||||
Con::setBoolVariable("$pref::Interior::lockArrays", true);
|
||||
Con::setBoolVariable("$pref::TS::skipFirstFog", false);
|
||||
Con::setBoolVariable("$pref::OpenGL::noDrawArraysAlpha", true);
|
||||
}
|
||||
|
||||
if ( needResurrect )
|
||||
{
|
||||
// Reload the textures:
|
||||
Con::printf( "Resurrecting the texture manager..." );
|
||||
Game->textureResurrect();
|
||||
}
|
||||
|
||||
// Set the new window to the foreground:
|
||||
ShowWindow( winState.appWindow, SW_SHOW );
|
||||
SetForegroundWindow( winState.appWindow );
|
||||
SetFocus( winState.appWindow );
|
||||
|
||||
GL_EXT_Init();
|
||||
|
||||
Con::setBoolVariable( "$SwapIntervalSupported", false );
|
||||
Con::setVariable( "$pref::Video::displayDevice", mDeviceName );
|
||||
Con::setBoolVariable("$pref::OpenGL::allowTexGen", true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Voodoo2Device::shutdown()
|
||||
{
|
||||
if ( winState.hGLRC )
|
||||
{
|
||||
dwglMakeCurrent( NULL, NULL );
|
||||
dwglDeleteContext( winState.hGLRC );
|
||||
winState.hGLRC = NULL;
|
||||
}
|
||||
|
||||
if ( winState.appDC )
|
||||
{
|
||||
ReleaseDC( winState.appWindow, winState.appDC );
|
||||
winState.appDC = NULL;
|
||||
}
|
||||
|
||||
ChangeDisplaySettings( NULL, 0 );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Voodoo2Device::setScreenMode( U32 width, U32 height, U32 bpp, bool fullScreen, bool forceIt, bool repaint )
|
||||
{
|
||||
HWND curtain = NULL;
|
||||
bool needResurrect = false;
|
||||
Resolution newRes( width, height, bpp );
|
||||
|
||||
if ( !fullScreen )
|
||||
{
|
||||
// The 3Dfx Voodoo2 OpenGL driver only runs in full-screen, so ignore:
|
||||
Con::warnf( ConsoleLogEntry::General, "Sorry, the Voodoo 2 display device only supports full-screen!" );
|
||||
}
|
||||
|
||||
// Force the res to be one of the ones in the supported list:
|
||||
U32 resIndex = 0;
|
||||
U32 bestScore = 0, thisScore = 0;
|
||||
for ( U32 i = 0; i < mResolutionList.size(); i++ )
|
||||
{
|
||||
if ( newRes == mResolutionList[i] )
|
||||
{
|
||||
resIndex = i;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
thisScore = abs( S32( newRes.w ) - S32( mResolutionList[i].w ) ) + abs( S32( newRes.h ) - S32( mResolutionList[i].h ) );
|
||||
if ( !bestScore || thisScore < bestScore )
|
||||
{
|
||||
bestScore = thisScore;
|
||||
resIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
newRes = mResolutionList[resIndex];
|
||||
|
||||
// Return if we aren't forcing it and we are already in the desired resolution:
|
||||
if ( !forceIt && newRes == smCurrentRes )
|
||||
return true;
|
||||
|
||||
Con::printf( "Setting screen mode to %dx%dx16 (fs)...", newRes.w, newRes.h );
|
||||
|
||||
// Delete the rendering context:
|
||||
if ( winState.hGLRC )
|
||||
{
|
||||
Con::printf( "Killing the texture manager..." );
|
||||
Game->textureKill();
|
||||
needResurrect = true;
|
||||
|
||||
Con::printf( "Making the rendering context not current..." );
|
||||
if ( !dwglMakeCurrent( NULL, NULL ) )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::setScreenMode\ndwglMakeCurrent( NULL, NULL ) failed!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
Con::printf( "Deleting the rendering context..." );
|
||||
if ( !dwglDeleteContext( winState.hGLRC ) )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::setScreenMode\ndwglDeleteContext failed!" );
|
||||
return false;
|
||||
}
|
||||
winState.hGLRC = NULL;
|
||||
}
|
||||
|
||||
// Release the device context:
|
||||
if ( winState.appDC )
|
||||
{
|
||||
Con::printf( "Releasing the device context..." );
|
||||
ReleaseDC( winState.appWindow, winState.appDC );
|
||||
winState.appDC = NULL;
|
||||
}
|
||||
|
||||
// Change the display settings (shouldn't really be necessary, but is):
|
||||
U32 test;
|
||||
DEVMODE devMode;
|
||||
dMemset( &devMode, 0, sizeof( devMode ) );
|
||||
devMode.dmSize = sizeof( devMode );
|
||||
devMode.dmPelsWidth = newRes.w;
|
||||
devMode.dmPelsHeight = newRes.h;
|
||||
devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
|
||||
|
||||
Con::printf( "Changing the display settings to %dx%dx16...", newRes.w, newRes.h );
|
||||
curtain = CreateCurtain( newRes.w, newRes.h );
|
||||
test = ChangeDisplaySettings( &devMode, CDS_FULLSCREEN );
|
||||
if ( test != DISP_CHANGE_SUCCESSFUL )
|
||||
{
|
||||
ChangeDisplaySettings( NULL, 0 );
|
||||
switch( test )
|
||||
{
|
||||
case DISP_CHANGE_RESTART:
|
||||
Platform::AlertOK( "Display Change Failed", "You must restart your machine to get the specified mode." );
|
||||
break;
|
||||
|
||||
case DISP_CHANGE_BADMODE:
|
||||
Platform::AlertOK( "Display Change Failed", "The specified mode is not supported by this device." );
|
||||
break;
|
||||
|
||||
default:
|
||||
Platform::AlertOK( "Display Change Failed", "Hardware failed to switch to the specified mode." );
|
||||
break;
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
// Resize the window:
|
||||
if ( !SetWindowPos( winState.appWindow, NULL, 0, 0, newRes.w, newRes.h, SWP_NOZORDER | SWP_NOMOVE ) )
|
||||
{
|
||||
Con::printf( "Voodoo2Device::setScreenMode - SetWindowPos sizing to %dx%d failed.", newRes.w, newRes.h );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get a new device context:
|
||||
Con::printf( "Acquiring a new device context..." );
|
||||
winState.appDC = GetDC( winState.appWindow );
|
||||
if ( !winState.appDC )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::setScreenMode\nFailed to get a valid device context!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a new rendering context:
|
||||
Con::printf( "Creating a new rendering context..." );
|
||||
winState.hGLRC = dwglCreateContext( winState.appDC );
|
||||
if ( !winState.hGLRC )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::setScreenMode\nFailed to create a GL rendering context!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make the new rendering context current:
|
||||
Con::printf( "Making the new rendering context current..." );
|
||||
if ( !dwglMakeCurrent( winState.appDC, winState.hGLRC ) )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::setScreenMode\nFailed to make the rendering context current!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( needResurrect )
|
||||
{
|
||||
// Reload the textures:
|
||||
Con::printf( "Resurrecting the texture manager..." );
|
||||
Game->textureResurrect();
|
||||
}
|
||||
|
||||
smCurrentRes = newRes;
|
||||
Platform::setWindowSize( newRes.w, newRes.h );
|
||||
char tempBuf[15];
|
||||
dSprintf( tempBuf, sizeof( tempBuf ), "%d %d %d", smCurrentRes.w, smCurrentRes.h, smCurrentRes.bpp );
|
||||
Con::setVariable( "$pref::Video::resolution", tempBuf );
|
||||
|
||||
if ( curtain )
|
||||
DestroyWindow( curtain );
|
||||
|
||||
if ( repaint )
|
||||
Con::evaluate( "resetCanvas();" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Voodoo2Device::swapBuffers()
|
||||
{
|
||||
dwglSwapBuffers( winState.appDC );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const char* Voodoo2Device::getDriverInfo()
|
||||
{
|
||||
// Output some driver info to the console:
|
||||
const char* vendorString = (const char*) glGetString( GL_VENDOR );
|
||||
const char* rendererString = (const char*) glGetString( GL_RENDERER );
|
||||
const char* versionString = (const char*) glGetString( GL_VERSION );
|
||||
const char* extensionsString = (const char*) glGetString( GL_EXTENSIONS );
|
||||
|
||||
// TODO - move strings out of code and into script...
|
||||
U32 bufferLen = ( vendorString ? dStrlen( vendorString ) : 0 )
|
||||
+ ( rendererString ? dStrlen( rendererString ) : 0 )
|
||||
+ ( versionString ? dStrlen( versionString ) : 0 )
|
||||
+ ( extensionsString ? dStrlen( extensionsString ) : 0 )
|
||||
+ 4;
|
||||
|
||||
char* returnString = Con::getReturnBuffer( bufferLen );
|
||||
dSprintf( returnString, bufferLen, "%s\t%s\t%s\t%s",
|
||||
( vendorString ? vendorString : "" ),
|
||||
( rendererString ? rendererString : "" ),
|
||||
( versionString ? versionString : "" ),
|
||||
( extensionsString ? extensionsString : "" ) );
|
||||
|
||||
return( returnString );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Voodoo2Device::getGammaCorrection(F32 &g)
|
||||
{
|
||||
// apparently the qwlGetDeviceGammaRamp3DFX doesn't actually work. So, this
|
||||
// is a good default. We don't need to worry about restoring the original
|
||||
// gamma. Anything we do is wiped out once we destroy the Voodoo2 window.
|
||||
g = 0.8;
|
||||
|
||||
return true;
|
||||
|
||||
U16 ramp[256*3];
|
||||
|
||||
if (!dwglGetDeviceGammaRamp3DFX(winState.appDC, ramp))
|
||||
return false;
|
||||
|
||||
F32 csum = 0.0;
|
||||
U32 ccount = 0;
|
||||
|
||||
for (U16 i = 0; i < 256; ++i)
|
||||
{
|
||||
if (i != 0 && ramp[i] != 0 && ramp[i] != 65535)
|
||||
{
|
||||
F64 b = (F64) i/256.0;
|
||||
F64 a = (F64) ramp[i]/65535.0;
|
||||
F32 c = (F32) (mLog(a)/mLog(b));
|
||||
|
||||
csum += c;
|
||||
++ccount;
|
||||
}
|
||||
}
|
||||
g = csum/ccount;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Voodoo2Device::setGammaCorrection(F32 g)
|
||||
{
|
||||
U16 ramp[256*3];
|
||||
|
||||
for (U16 i = 0; i < 256; ++i)
|
||||
ramp[i] = mPow((F32) i/256.0f, g) * 65535.0f;
|
||||
dMemcpy(&ramp[256],ramp,256*sizeof(U16));
|
||||
dMemcpy(&ramp[512],ramp,256*sizeof(U16));
|
||||
|
||||
return dwglSetDeviceGammaRamp3DFX(winState.appDC, ramp);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Voodoo2Device::setVerticalSync( bool on )
|
||||
{
|
||||
on;
|
||||
return( false );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Stuff for Voodoo 2 detection:
|
||||
#ifndef GR_HARDWARE
|
||||
#define GR_HARDWARE 0xa1
|
||||
#endif
|
||||
|
||||
#define GLIDE_NUM_TMU 2
|
||||
#define MAX_NUM_SST 4
|
||||
|
||||
typedef S32 GrSstType;
|
||||
#define GR_SSTTYPE_VOODOO 0
|
||||
#define GR_SSTTYPE_SST96 1
|
||||
#define GR_SSTTYPE_AT3D 2
|
||||
|
||||
typedef struct GrTMUConfig_St
|
||||
{
|
||||
S32 tmuRev; /* Rev of Texelfx chip */
|
||||
S32 tmuRam; /* 1, 2, or 4 MB */
|
||||
} GrTMUConfig_t;
|
||||
|
||||
typedef struct GrVoodooConfig_St
|
||||
{
|
||||
S32 fbRam; /* 1, 2, or 4 MB */
|
||||
S32 fbiRev; /* Rev of Pixelfx chip */
|
||||
S32 nTexelfx; /* How many texelFX chips are there? */
|
||||
FxBool sliDetect; /* Is it a scan-line interleaved board? */
|
||||
GrTMUConfig_t tmuConfig[GLIDE_NUM_TMU]; /* Configuration of the Texelfx chips */
|
||||
} GrVoodooConfig_t;
|
||||
|
||||
typedef struct GrSst96Config_St
|
||||
{
|
||||
S32 fbRam; /* How much? */
|
||||
S32 nTexelfx;
|
||||
GrTMUConfig_t tmuConfig;
|
||||
} GrSst96Config_t;
|
||||
|
||||
typedef struct GrAT3DConfig_St
|
||||
{
|
||||
S32 rev;
|
||||
} GrAT3DConfig_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
S32 num_sst; /* # of HW units in the system */
|
||||
struct
|
||||
{
|
||||
GrSstType type; /* Which hardware is it? */
|
||||
union SstBoard_u
|
||||
{
|
||||
GrVoodooConfig_t VoodooConfig;
|
||||
GrSst96Config_t SST96Config;
|
||||
GrAT3DConfig_t AT3DConfig;
|
||||
} sstBoard;
|
||||
} SSTs[MAX_NUM_SST]; /* configuration for each board */
|
||||
} GrHwConfiguration;
|
||||
|
||||
typedef FxBool( FX_CALL *grSstQueryBoards_fpt )( GrHwConfiguration *hwconfig );
|
||||
typedef FxBool( FX_CALL *grSstQueryHardware_fpt )( GrHwConfiguration *hwconfig );
|
||||
|
||||
typedef void ( FX_CALL *grGlideInit_fpt )( void );
|
||||
typedef const char* ( FX_CALL *grGetString_fpt )( FxU32 pName );
|
||||
typedef void( FX_CALL *grGlideShutdown_fpt )( void );
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
DisplayDevice* Voodoo2Device::create()
|
||||
{
|
||||
// Detect the Voodoo2 OpenGL driver:
|
||||
GrHwConfiguration hwConfig;
|
||||
bool result = true;
|
||||
|
||||
// Reset the available resolution specifier code:
|
||||
sResCode = 0;
|
||||
|
||||
grGlideInit_fpt grGlideInit = NULL;
|
||||
grGlideShutdown_fpt grGlideShutdown = NULL;
|
||||
grSstQueryBoards_fpt grSstQueryBoards = NULL;
|
||||
grSstQueryHardware_fpt grSstQueryHardware = NULL;
|
||||
grGetString_fpt grGetString = NULL;
|
||||
|
||||
// Let the Glide 2 stuff go first:
|
||||
HINSTANCE glide2DLL = LoadLibrary( dT("glide2x") );
|
||||
|
||||
if ( !glide2DLL )
|
||||
return NULL;
|
||||
|
||||
grSstQueryBoards = (grSstQueryBoards_fpt) GetProcAddress( glide2DLL, "_grSstQueryBoards@4" );
|
||||
|
||||
if ( grSstQueryBoards )
|
||||
{
|
||||
grSstQueryBoards( &hwConfig );
|
||||
if ( hwConfig.num_sst == 0 )
|
||||
result = false;
|
||||
else
|
||||
{
|
||||
grGlideInit = (grGlideInit_fpt) GetProcAddress( glide2DLL, "_grGlideInit@0" );
|
||||
grSstQueryHardware = (grSstQueryHardware_fpt) GetProcAddress( glide2DLL, "_grSstQueryHardware@4" );
|
||||
grGlideShutdown = (grGlideShutdown_fpt) GetProcAddress( glide2DLL, "_grGlideShutdown@0" );
|
||||
|
||||
if ( grGlideInit && grSstQueryHardware && grGlideShutdown )
|
||||
{
|
||||
grGlideInit();
|
||||
grSstQueryHardware( &hwConfig );
|
||||
|
||||
// Find out what resolutions are available:
|
||||
if ( hwConfig.SSTs[0].sstBoard.VoodooConfig.sliDetect == 0 ) // SLI not detected.
|
||||
{
|
||||
if ( hwConfig.SSTs[0].sstBoard.VoodooConfig.fbRam >= 4 )
|
||||
sResCode = 1; // low bit indicates 800x600
|
||||
}
|
||||
else // SLI detected.
|
||||
{
|
||||
sResCode = 1;
|
||||
|
||||
if ( hwConfig.SSTs[0].sstBoard.VoodooConfig.fbRam >= 4 )
|
||||
sResCode += 2;
|
||||
}
|
||||
|
||||
grGlideShutdown();
|
||||
}
|
||||
|
||||
grGlideInit = NULL;
|
||||
grGlideShutdown = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
result = false;
|
||||
|
||||
FreeLibrary( glide2DLL );
|
||||
|
||||
if ( result )
|
||||
{
|
||||
// Glide 3's turn:
|
||||
HINSTANCE glide3DLL = LoadLibrary( dT("glide3x") );
|
||||
|
||||
if ( !glide3DLL )
|
||||
return NULL;
|
||||
|
||||
grGlideInit = (grGlideInit_fpt) GetProcAddress( glide3DLL, "_grGlideInit@0" );
|
||||
grGetString = (grGetString_fpt) GetProcAddress( glide3DLL, "_grGetString@4" );
|
||||
grGlideShutdown = (grGlideShutdown_fpt) GetProcAddress( glide3DLL, "_grGlideShutdown@0" );
|
||||
|
||||
if ( grGlideInit && grGetString && grGlideShutdown )
|
||||
{
|
||||
grGlideInit();
|
||||
|
||||
const char* hardware = grGetString( GR_HARDWARE );
|
||||
if ( dStrcmp( hardware, "Voodoo2" ) != 0 )
|
||||
result = false;
|
||||
|
||||
grGlideShutdown();
|
||||
}
|
||||
else
|
||||
result = false;
|
||||
|
||||
FreeLibrary( glide3DLL );
|
||||
}
|
||||
|
||||
if ( result )
|
||||
return new Voodoo2Device();
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
Reference in New Issue
Block a user