12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199 |
- /*=============================================================================
- Name : rinit.cpp
- Purpose : rGL / OpenGL enumeration initialization routines
- Created 1/5/1999 by khent
- Copyright Relic Entertainment, Inc. All rights reserved.
- =============================================================================*/
- #define WIN32_LEAN_AND_MEAN
- #define STRICT
- #define D3D_OVERLOADS
- #include <windows.h>
- #include <windowsx.h>
- #include <ddraw.h>
- #include <dinput.h>
- #include <d3drm.h>
- #include <stdio.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "rinit.h"
- #include "devstats.h"
- extern "C" unsigned int glNT;
- extern "C" unsigned int gl95;
- extern "C" unsigned int mainSoftwareDirectDraw;
- extern "C" unsigned int mainOutputCRC;
- extern "C" unsigned long strCurLanguage;
- #define RIN_MODESINDEVSTATLIST 10
- unsigned int rinDevstatModeTable[RIN_MODESINDEVSTATLIST][3] =
- {
- 16, 640, DEVSTAT_NO_64048016,
- 16, 800, DEVSTAT_NO_80060016,
- 16, 1024, DEVSTAT_NO_102476816,
- 16, 1280, DEVSTAT_NO_1280102416,
- 16, 1600, DEVSTAT_NO_1600120016,
- 32, 640, DEVSTAT_NO_64048032,
- 32, 800, DEVSTAT_NO_80060032,
- 32, 1024, DEVSTAT_NO_102476832,
- 32, 1280, DEVSTAT_NO_1280102432,
- 32, 1600, DEVSTAT_NO_1600120032,
- };
- extern "C" unsigned int* devTable;
- extern "C" int devTableLength;
- //3dfx fullscreen-only present boolean
- static bool bFullscreenDevice;
- static rdevice* rDeviceList;
- static int nDevices;
- extern "C" unsigned int gDevcaps = 0xFFFFFFFF;
- extern "C" unsigned int gDevcaps2 = 0x00000000;
- char* gDescription = NULL;
- char* gDriverName = NULL;
- typedef HRESULT(WINAPI * DIRECTDRAWCREATE)(GUID*, LPDIRECTDRAW*, IUnknown*);
- typedef HRESULT(WINAPI * DIRECTINPUTCREATE)(HINSTANCE, DWORD, LPDIRECTINPUT*, IUnknown*);
- #define SST_VOODOO 0
- #define SST_VOODOO2 1
- #define SST_OTHER 2
- extern "C" unsigned int sstHardwareExists(int*);
- extern "C" unsigned int glCapNT(void);
- void* memAlloc(int size)
- {
- unsigned char* block;
- block = (unsigned char*)malloc(size);
- memset(block, 0, size);
- return (void*)block;
- }
- void memFree(void* memblock)
- {
- free(memblock);
- }
- extern "C" unsigned int crc32Compute(void*, unsigned int);
- /*-----------------------------------------------------------------------------
- Name : rinDeviceCRC
- Description : generate a CRC of the detected devices for detection of
- changing hardware (light assurance that previous video
- mode will still be working correctly)
- Inputs :
- Outputs :
- Return : crc32
- ----------------------------------------------------------------------------*/
- unsigned int rinDeviceCRC(void)
- {
- rdevice* cdev;
- rdevice* devlist;
- rdevice* pdevlist;
- unsigned int crc;
- if (nDevices == 0 || rDeviceList == NULL)
- {
- return 0;
- }
- devlist = (rdevice*)memAlloc(nDevices * sizeof(rdevice));
- pdevlist = devlist;
- cdev = rDeviceList;
- do
- {
- memcpy(pdevlist, cdev, sizeof(rdevice));
- pdevlist->modes = NULL;
- pdevlist->next = NULL;
- pdevlist++;
- cdev = cdev->next;
- } while (cdev != NULL);
- crc = crc32Compute((void*)devlist, nDevices * sizeof(rdevice));
- memFree(devlist);
- return crc;
- }
- /*-----------------------------------------------------------------------------
- Name : rinAddMode
- Description : add a display mode to a video driver
- Inputs : dev - the device to add the mode to
- width, height - dimensions
- depth - bitdepth
- Outputs :
- Return :
- ----------------------------------------------------------------------------*/
- void rinAddMode(rdevice* dev, int width, int height, int depth)
- {
- rmode* mode;
- rmode* cmode;
- mode = (rmode*)memAlloc(sizeof(rmode));
- mode->width = width;
- mode->height = height;
- mode->depth = depth;
- if (dev->modes == NULL)
- {
- //no modes yet
- dev->modes = mode;
- mode->next = NULL;
- }
- else
- {
- //add to tail
- cmode = dev->modes;
- while (cmode->next != NULL)
- {
- cmode = cmode->next;
- }
- cmode->next = mode;
- mode->next = NULL;
- }
- }
- /*-----------------------------------------------------------------------------
- Name : rinModeAccepted
- Description : decides whether a given mode is supported
- Inputs : dev - the device in question
- width, height, depth - display mode characteristics
- Outputs :
- Return : true or false
- ----------------------------------------------------------------------------*/
- static bool rinModeAccepted(rdevice* dev, int width, int height, int depth)
- {
- int index;
- //accept 16 & 32 bit mode only
- if (depth != 16 && depth != 32)
- {
- return false;
- }
- //possibly eliminate 32bit modes, if devstats tells us to
- if (depth == 32)
- {
- if (dev->type == RIN_TYPE_DIRECT3D)
- {
- if (dev->devcaps & DEVSTAT_NO_32BIT)
- {
- return false;
- }
- }
- else if (dev->type == RIN_TYPE_OPENGL)
- {
- if ((dev->devcaps & DEVSTAT_NO_32BIT_GL) ||
- (dev->devcaps & DEVSTAT_NO_32BIT))
- {
- return false;
- }
- }
- }
- //only sane, supported, modes
- switch (width)
- {
- case 640:
- if (height != 480) return false;
- break;
- case 800:
- if (height != 600) return false;
- break;
- case 1024:
- if (height != 768) return false;
- break;
- case 1280:
- if (height != 1024) return false;
- break;
- case 1600:
- if (height != 1200) return false;
- break;
- default:
- return false;
- }
- //check for specifically disabled display modes
- for (index = 0; index < RIN_MODESINDEVSTATLIST; index++)
- {
- if (rinDevstatModeTable[index][0] == depth &&
- rinDevstatModeTable[index][1] == width)
- {
- if (dev->devcaps & rinDevstatModeTable[index][2])
- {
- return false;
- }
- }
- }
- return true;
- }
- /*-----------------------------------------------------------------------------
- Name : rinSortModes
- Description : sorts a device's display modes the way I like them
- (one bitdepth at a time)
- Inputs : dev - the device whose modes are to be sorted
- Outputs :
- Return :
- ----------------------------------------------------------------------------*/
- void rinSortModes(rdevice* dev)
- {
- rmode* cmode;
- rmode* freeMode;
- rdevice dummy;
- int depths[] = {16,32,0};
- int depth;
- if (dev->modes == NULL)
- {
- return;
- }
- memset(&dummy, 0, sizeof(rdevice));
- for (depth = 0; depths[depth] != 0; depth++)
- {
- cmode = dev->modes;
- do
- {
- if (cmode->depth == depths[depth])
- {
- if (rinModeAccepted(dev, cmode->width, cmode->height, cmode->depth))
- {
- rinAddMode(&dummy, cmode->width, cmode->height, cmode->depth);
- }
- }
- cmode = cmode->next;
- } while (cmode != NULL);
- }
- //free modes on dev
- cmode = dev->modes;
- while (cmode != NULL)
- {
- freeMode = cmode; //save to free
- cmode = cmode->next; //next
- memFree(freeMode); //free
- }
- //attach new modes
- dev->modes = dummy.modes;
- }
- /*-----------------------------------------------------------------------------
- Name : rinCopyModes
- Description : copy one driver's display modes to another
- Inputs : devOut - output device
- devIn - input device
- Outputs :
- Return :
- ----------------------------------------------------------------------------*/
- void rinCopyModes(rdevice* devOut, rdevice* devIn)
- {
- rmode* cmode;
- cmode = devIn->modes;
- if (cmode == NULL)
- {
- devOut->modes = NULL;
- }
- else
- {
- do
- {
- rinAddMode(devOut, cmode->width, cmode->height, cmode->depth);
- cmode = cmode->next;
- } while (cmode != NULL);
- }
- }
- /*-----------------------------------------------------------------------------
- Name : rinCopyModesSelectively
- Description : copy certain display modes from one device to another
- Inputs : devOut - output device
- devIn - input device
- depth - bitdepth of acceptable modes
- maxWidth - maximum acceptable width
- Outputs :
- Return :
- ----------------------------------------------------------------------------*/
- void rinCopyModesSelectively(rdevice* devOut, rdevice* devIn, int depth, int maxWidth)
- {
- rmode* cmode;
- cmode = devIn->modes;
- if (cmode == NULL)
- {
- devOut->modes = NULL;
- }
- else
- {
- do
- {
- if ((cmode->depth == depth) &&
- (cmode->width <= maxWidth))
- {
- rinAddMode(devOut, cmode->width, cmode->height, cmode->depth);
- }
- cmode = cmode->next;
- } while (cmode != NULL);
- }
- }
- /*-----------------------------------------------------------------------------
- Name : rinAddDevice
- Description : add a device to the head of the device list
- Inputs : dev - the device to add
- Outputs : rDeviceList is modified
- Return :
- ----------------------------------------------------------------------------*/
- void rinAddDevice(rdevice* dev)
- {
- rdevice* cdev;
- if (rDeviceList == NULL)
- {
- rDeviceList = dev;
- dev->next = NULL;
- }
- else
- {
- //add to head
- cdev = rDeviceList;
- dev->next = cdev;
- rDeviceList = dev;
- }
- }
- /*-----------------------------------------------------------------------------
- Name : rinGetDeviceList
- Description : return pointer to device list
- Inputs :
- Outputs :
- Return : rDeviceList
- ----------------------------------------------------------------------------*/
- rdevice* rinGetDeviceList(void)
- {
- return rDeviceList;
- }
- /*-----------------------------------------------------------------------------
- Name : rinFreeDevices
- Description : clear the device list (free memory and such)
- Inputs :
- Outputs : rDeviceList and constituents are freed
- Return :
- ----------------------------------------------------------------------------*/
- int rinFreeDevices(void)
- {
- rdevice* dev;
- rdevice* freeDev;
- rmode* mode;
- rmode* freeMode;
- //device loop
- dev = rDeviceList;
- while (dev != NULL)
- {
- //mode loop
- mode = dev->modes;
- while (mode != NULL)
- {
- freeMode = mode; //save to free
- mode = mode->next; //next
- memFree(freeMode); //free
- }
- freeDev = dev; //save to free
- dev = dev->next; //next
- memFree(freeDev); //free
- }
- rDeviceList = NULL;
- //success
- return 1;
- }
- /*-----------------------------------------------------------------------------
- Name : rinEnumDisplayModes_cb
- Description : callback during display mode enumeration
- Inputs : ...
- Outputs :
- Return :
- ----------------------------------------------------------------------------*/
- static HRESULT WINAPI rinEnumDisplayModes_cb(LPDDSURFACEDESC2 ddsd, LPVOID lpContext)
- {
- rdevice* dev;
- dev = (rdevice*)lpContext;
- if ((ddsd->dwFlags & DDSD_WIDTH) &&
- (ddsd->dwFlags & DDSD_HEIGHT) &&
- (ddsd->dwFlags & DDSD_PIXELFORMAT))
- {
- if (ddsd->ddpfPixelFormat.dwRGBBitCount != 16 &&
- ddsd->ddpfPixelFormat.dwRGBBitCount != 32)
- {
- goto SKIP_MODE;
- }
- if (ddsd->dwWidth < 640 || ddsd->dwHeight < 480)
- {
- goto SKIP_MODE;
- }
- if (ddsd->dwWidth > 1600)
- {
- goto SKIP_MODE;
- }
- rinAddMode(dev,
- ddsd->dwWidth, ddsd->dwHeight,
- ddsd->ddpfPixelFormat.dwRGBBitCount);
- }
- SKIP_MODE:
- return D3DENUMRET_OK;
- }
- /*-----------------------------------------------------------------------------
- Name : rinEnumPrimaryDisplayModes_cb
- Description : callback during display mode enumeration, old DDraw
- Inputs : ...
- Outputs :
- Return :
- ----------------------------------------------------------------------------*/
- static HRESULT WINAPI rinEnumPrimaryDisplayModes_cb(LPDDSURFACEDESC ddsd, LPVOID lpContext)
- {
- rdevice* dev;
- dev = (rdevice*)lpContext;
- if (dev == NULL)
- {
- goto SKIP_MODE;
- }
- if ((ddsd->dwFlags & DDSD_WIDTH) &&
- (ddsd->dwFlags & DDSD_HEIGHT) &&
- (ddsd->dwFlags & DDSD_PIXELFORMAT))
- {
- if (ddsd->ddpfPixelFormat.dwRGBBitCount != 16 &&
- ddsd->ddpfPixelFormat.dwRGBBitCount != 32)
- {
- goto SKIP_MODE;
- }
- if (ddsd->dwWidth < 640 || ddsd->dwHeight < 480)
- {
- goto SKIP_MODE;
- }
- if (ddsd->dwWidth > 1600)
- {
- goto SKIP_MODE;
- }
- rinAddMode(dev,
- ddsd->dwWidth, ddsd->dwHeight,
- ddsd->ddpfPixelFormat.dwRGBBitCount);
- }
- SKIP_MODE:
- return D3DENUMRET_OK;
- }
- static FILE* crcLog;
- static void rinResetCRCLog(void)
- {
- crcLog = fopen("d3dDeviceCRC.txt", "wt");
- }
- static void rinOutputCRC(LPSTR desc, LPSTR name, unsigned int crc)
- {
- if (crcLog != NULL)
- {
- fprintf(crcLog, "%08X [%s][%s]\n", crc, desc, name);
- }
- }
- static void rinCloseCRCLog(void)
- {
- if (crcLog != NULL)
- {
- fclose(crcLog);
- crcLog = NULL;
- }
- }
- D3DDEVICEDESC _caps;
- /*-----------------------------------------------------------------------------
- Name : rinEnoughCaps
- Description : check for at least alphablending and depthbuffering before
- considering this a valid device
- Inputs :
- Outputs :
- Return :
- ----------------------------------------------------------------------------*/
- bool rinEnoughCaps(LPSTR strDesc, LPSTR strName, LPD3DDEVICEDESC caps)
- {
- D3DPRIMCAPS* tri = &caps->dpcTriCaps;
- _caps = *caps;
- //reset some possibly variable fields
- _caps.dwSize = 0;
- _caps.dwFlags = 0;
- _caps.dcmColorModel = 0;
- _caps.dwDevCaps = 0;
- _caps.bClipping = 0;
- //check for alphablending, source caps first
- if (!(tri->dwSrcBlendCaps & D3DPBLENDCAPS_SRCALPHA) &&
- !(tri->dwSrcBlendCaps & D3DPBLENDCAPS_ONE))
- {
- return false;
- }
- //check dest blend caps
- if (!(tri->dwDestBlendCaps & D3DPBLENDCAPS_INVSRCALPHA) &&
- !(tri->dwDestBlendCaps & D3DPBLENDCAPS_ONE) &&
- !(tri->dwDestBlendCaps & D3DPBLENDCAPS_ZERO))
- {
- return false;
- }
- //it can blend, but can it depthbuffer ?
- if (!(tri->dwZCmpCaps & D3DPCMPCAPS_LESS) &&
- !(tri->dwZCmpCaps & D3DPCMPCAPS_LESSEQUAL))
- {
- return false;
- }
- //check for some kind of texture filtering
- if (!(tri->dwTextureFilterCaps & D3DPTFILTERCAPS_LINEAR) &&
- !(tri->dwTextureFilterCaps & D3DPTFILTERCAPS_NEAREST))
- {
- return false;
- }
- //check texture address caps
- if (!(tri->dwTextureAddressCaps & D3DPTADDRESSCAPS_CLAMP) &&
- !(tri->dwTextureAddressCaps & D3DPTADDRESSCAPS_WRAP))
- {
- return false;
- }
- return true;
- }
- //internal count of num valid devs on D3D object
- static int D3Ddevs;
- static int numD3Ddevs;
- static HRESULT WINAPI rinEnumDirect3DDevices_cb(
- GUID* pGUID, LPSTR strDesc, LPSTR strName, LPD3DDEVICEDESC pHALDesc,
- LPD3DDEVICEDESC pHELDesc, LPVOID pvContext)
- {
- int* devs = (int*)pvContext;
- if (pGUID == NULL || pHALDesc == NULL || pHELDesc == NULL)
- {
- return D3DENUMRET_CANCEL;
- }
- if (pHALDesc->dwFlags != 0)
- {
- //has a HAL, might be something we want. check caps
- if (rinEnoughCaps(strDesc, strName, pHALDesc))
- {
- D3Ddevs++;
- }
- }
- return D3DENUMRET_OK;
- }
- /*-----------------------------------------------------------------------------
- Name : rinEnumPrimary_cb
- Description : callback during DirectDraw <= 3 device enumeration
- Inputs : ...
- Outputs :
- Return :
- ----------------------------------------------------------------------------*/
- static BOOL WINAPI rinEnumPrimary_cb(
- GUID FAR* lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, LPVOID lpContext)
- {
- LPDIRECTDRAW ddraw;
- //only want primary
- if (lpGUID != NULL)
- {
- return D3DENUMRET_OK;
- }
- if (FAILED(DirectDrawCreate(lpGUID, &ddraw, NULL)))
- {
- return D3DENUMRET_OK;
- }
- ddraw->EnumDisplayModes(0, NULL, lpContext, rinEnumPrimaryDisplayModes_cb);
- return D3DENUMRET_OK;
- }
- static BOOL WINAPI rinEnum3Dfx_cb(
- GUID FAR* lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, LPVOID lpContext)
- {
- LPDIRECTDRAW ddraw;
- if (lpGUID == NULL)
- {
- //not interested in primary devices
- return D3DENUMRET_OK;
- }
- if (FAILED(DirectDrawCreate(lpGUID, &ddraw, NULL)))
- {
- //broken DirectDraw
- return D3DENUMRET_OK;
- }
- //enumerate display modes on this secondary device
- ddraw->EnumDisplayModes(0, NULL, lpContext, rinEnumPrimaryDisplayModes_cb);
- rdevice* dev = (rdevice*)lpContext;
- if (dev != NULL)
- {
- //setup 3dfx OpenGL device info
- dev->type = RIN_TYPE_OPENGL;
- strncpy(dev->data, lpDriverName, 63);
- strncpy(dev->name, lpDriverDescription, 63);
- dev->data[63] = '\0';
- dev->name[63] = '\0';
- }
- return D3DENUMRET_CANCEL;
- }
- void rinRemoveDriverFromName(char* name)
- {
- int pos;
- char buf[64];
- char* pdest;
- if (strlen(name) < 7)
- {
- return;
- }
- strncpy(buf, name, 63);
- buf[63] = '\0';
- _strlwr(buf);
- pdest = strstr(buf, "driver");
- if (pdest != NULL && pdest != name)
- {
- if (name[pdest - buf - 1] == ' ')
- {
- name[pdest - buf - 1] = '\0';
- }
- }
- }
- /*-----------------------------------------------------------------------------
- Name : rinFindDevCaps
- Description : find a given device's eliminated caps in the devTable
- Inputs : crc0 - crc of driver's caps
- crc1 - crc of device type
- cap[01] - where the cap flags go
- Outputs : cap[01] holds cap flags, or 0
- Return :
- ----------------------------------------------------------------------------*/
- static void rinFindDevCaps(unsigned int crc0, unsigned int crc1, unsigned int* cap0, unsigned int* cap1)
- {
- int index;
- if (cap0 == NULL || cap1 == NULL)
- {
- return;
- }
- if (crc1 != 0x00000000)
- {
- //try device-specific crclist first
- for (index = 0; index < (4*devTableLength); index += 4)
- {
- if (devTable[index+2] == crc1)
- {
- *cap0 = devTable[index+1];
- *cap1 = devTable[index+3];
- return;
- }
- }
- }
- //try driver-specific crclist next
- for (index = 0; index < (4*devTableLength); index += 4)
- {
- if (devTable[index] == crc0)
- {
- *cap0 = devTable[index+1];
- *cap1 = devTable[index+3];
- return;
- }
- }
- *cap0 = 0;
- *cap1 = 0;
- }
- typedef struct
- {
- DWORD vendor;
- WORD product;
- DWORD device;
- } hwDat;
- /*-----------------------------------------------------------------------------
- Name : rinEnumDirectDraw_cb
- Description : callback during DirectDraw device enumeration
- Inputs : ...
- Outputs :
- Return :
- ----------------------------------------------------------------------------*/
- static BOOL WINAPI rinEnumDirectDraw_cb(
- GUID FAR* lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, LPVOID lpContext)
- {
- LPDIRECTDRAW ddraw1;
- LPDIRECTDRAW4 ddraw4;
- LPDIRECT3D3 d3dObject;
- DDCAPS hal, hel;
- HRESULT hr;
- rdevice* dev;
- unsigned int cap0, cap1;
- DDDEVICEIDENTIFIER dddi;
- hwDat dat;
- gDescription = lpDriverDescription;
- gDriverName = lpDriverName;
- if (FAILED(DirectDrawCreate(lpGUID, &ddraw1, NULL)))
- {
- return D3DENUMRET_OK;
- }
- hr = ddraw1->QueryInterface(IID_IDirectDraw4, (void**)&ddraw4);
- if (FAILED(hr))
- {
- ddraw1->Release();
- return D3DENUMRET_OK;
- }
- hr = ddraw4->QueryInterface(IID_IDirect3D3, (void**)&d3dObject);
- if (FAILED(hr))
- {
- ddraw4->Release();
- ddraw1->Release();
- return D3DENUMRET_OK;
- }
- //query caps for fullscreen-only-ness
- ZeroMemory(&hal, sizeof(DDCAPS));
- ZeroMemory(&hel, sizeof(DDCAPS));
- hal.dwSize = sizeof(DDCAPS);
- hel.dwSize = sizeof(DDCAPS);
- hr = ddraw4->GetCaps(&hal, &hel);
- if (FAILED(hr))
- {
- d3dObject->Release();
- ddraw4->Release();
- ddraw1->Release();
- return D3DENUMRET_OK;
- }
- D3Ddevs = 0;
- d3dObject->EnumDevices(rinEnumDirect3DDevices_cb, NULL);
- if (D3Ddevs == 0)
- {
- d3dObject->Release();
- ddraw4->Release();
- ddraw1->Release();
- return D3DENUMRET_OK;
- }
- d3dObject->Release();
- if (!(hal.dwCaps2 & DDCAPS2_CANRENDERWINDOWED))
- {
- //no 3dfx fullscreen devices
- // ddraw4->Release();
- // ddraw1->Release();
- bFullscreenDevice = true;
- // return D3DENUMRET_OK;
- }
- memset(&dat, 0, sizeof(hwDat));
- if (FAILED(ddraw4->GetDeviceIdentifier(&dddi, 0)))
- {
- ddraw4->Release();
- ddraw1->Release();
- return D3DENUMRET_OK;
- }
- dat.vendor = dddi.dwVendorId;
- dat.product = 4;//HIWORD(dddi.liDriverVersion.HighPart);
- dat.device = dddi.dwDeviceId;
- dev = (rdevice*)memAlloc(sizeof(rdevice));
- dev->type = RIN_TYPE_DIRECT3D;
- rinFindDevCaps(crc32Compute((void*)&_caps, sizeof(D3DDEVICEDESC)),
- crc32Compute((void*)&dat, sizeof(hwDat)),
- &cap0, &cap1);
- if (mainOutputCRC)
- {
- rinOutputCRC(dddi.szDescription,
- dddi.szDriver,
- crc32Compute((void*)&dat, sizeof(hwDat)));
- }
- dev->devcaps = cap0;
- dev->devcaps2 = cap1;
- if (gDevcaps == 0xFFFFFFFF)
- {
- //only update global devcaps for primary
- gDevcaps = dev->devcaps;
- gDevcaps2 = dev->devcaps2;
- }
- strncpy(dev->data, lpDriverName, 63);
- strncpy(dev->name, lpDriverDescription, 63);
- dev->data[63] = '\0';
- dev->name[63] = '\0';
- rinRemoveDriverFromName(dev->name);
- if (lpGUID == NULL)
- {
- dev->data[0] = '\0';
- }
- dev->modes = NULL;
- ddraw4->EnumDisplayModes(0, NULL, (LPVOID)dev, rinEnumDisplayModes_cb);
- ddraw4->Release();
- ddraw1->Release();
- if (!(dev->devcaps & DEVSTAT_NOD3D_9X))
- {
- if (gl95)
- {
- if (dev->devcaps2 & DEVSTAT2_NOD3D_95)
- {
- return D3DENUMRET_OK;
- }
- }
- //only add device if Direct3D allowed for it
- rinAddDevice(dev);
- rinSortModes(dev);
- numD3Ddevs++;
- D3Ddevs++;
- }
- return D3DENUMRET_OK;
- }
- /*-----------------------------------------------------------------------------
- Name : rinEnumerateDirect3D
- Description : enumerate available Direct3D devices and populate the device list
- Inputs :
- Outputs : rDeviceList is added to, if any compatible devices exist
- Return : number of D3D devices found
- ----------------------------------------------------------------------------*/
- int rinEnumerateDirect3D(void)
- {
- numD3Ddevs = 0;
- HRESULT hr = DirectDrawEnumerate(rinEnumDirectDraw_cb, NULL);
- if (FAILED(hr))
- {
- return 0;
- }
- return numD3Ddevs;
- }
- /*-----------------------------------------------------------------------------
- Name : rinEnumeratePrimary
- Description : enumerate available display modes on the primary display
- Inputs : dev - the device whose modes are to be filled
- Outputs :
- Return : true or false (could or couldn't enumerate)
- ----------------------------------------------------------------------------*/
- bool rinEnumeratePrimary(rdevice* dev)
- {
- HRESULT hr = DirectDrawEnumerate(rinEnumPrimary_cb, dev);
- if (FAILED(hr))
- {
- return false;
- }
- if (dev == NULL)
- {
- return false;
- }
- return (dev->modes == NULL) ? false : true;
- }
- /*-----------------------------------------------------------------------------
- Name : rinEnumerate3Dfx
- Description : enumerate available display modes on possible 3Dfx display
- Inputs : dev - the device whose modes are to be filled
- Outputs :
- Return : true or false (could or couldn't enumerate)
- ----------------------------------------------------------------------------*/
- bool rinEnumerate3Dfx(rdevice* dev)
- {
- HRESULT hr = DirectDrawEnumerate(rinEnum3Dfx_cb, dev);
- if (FAILED(hr))
- {
- return false;
- }
- if (dev == NULL)
- {
- return false;
- }
- return (dev->modes == NULL) ? false : true;
- }
- /*-----------------------------------------------------------------------------
- Name : rinMaxWidth
- Description : return max width from all modes of all devices
- Inputs :
- Outputs :
- Return : max available width, or 9999 if no devices available
- ----------------------------------------------------------------------------*/
- int rinMaxWidth(void)
- {
- rdevice* cdev;
- rmode* cmode;
- int maxWidth;
- if (nDevices == 0)
- {
- return 9999;
- }
- cdev = rDeviceList;
- maxWidth = 0;
- while (cdev != NULL)
- {
- cmode = cdev->modes;
- while (cmode != NULL)
- {
- if (cmode->width > maxWidth)
- {
- maxWidth = cmode->width;
- }
- cmode = cmode->next;
- }
- cdev = cdev->next;
- }
- return (maxWidth == 0) ? 9999 : maxWidth;
- }
- /*-----------------------------------------------------------------------------
- Name : rinEnumerateDevices
- Description : populate the device list by enumerating available renderers
- Inputs :
- Outputs : rDeviceList is filled
- Return :
- ----------------------------------------------------------------------------*/
- int rinEnumerateDevices(void)
- {
- rdevice* dev;
- rdevice* gldev;
- rdevice primaryDev;
- bool primaryVal;
- int voodoo, maxWidth;
- if (mainOutputCRC)
- {
- rinResetCRCLog();
- }
- rDeviceList = NULL;
- nDevices = 0;
- gDevcaps = 0xFFFFFFFF;
- gDevcaps2 = 0x00000000;
- bFullscreenDevice = false;
- //add Direct3D devices
- nDevices += rinEnumerateDirect3D();
- //add OpenGL device
- dev = (rdevice*)memAlloc(sizeof(rdevice));
- if (nDevices == 1)
- {
- dev->devcaps = rDeviceList->devcaps;
- dev->devcaps2 = rDeviceList->devcaps2;
- }
- else if (nDevices == 2)
- {
- dev->devcaps = rDeviceList->next->devcaps;
- dev->devcaps2 = rDeviceList->next->devcaps2;
- }
- else if (gDevcaps != 0xFFFFFFFF)
- {
- dev->devcaps = gDevcaps;
- dev->devcaps2 = gDevcaps2;
- }
- else
- {
- dev->devcaps = gDevcaps = 0;
- dev->devcaps2 = gDevcaps2 = 0;
- }
- if (dev->devcaps & DEVSTAT_NO_DDRAWSW)
- {
- mainSoftwareDirectDraw = FALSE;
- }
- dev->type = RIN_TYPE_OPENGL;
- dev->data[0] = '\0';
- if (strCurLanguage == 1)
- {
- strncpy(dev->name, "OpenGL Standard", 63);
- }
- else if (strCurLanguage == 2)
- {
- strncpy(dev->name, "Standard-OpenGL", 63);
- }
- if (strCurLanguage == 3)
- {
- strncpy(dev->name, "OpenGL predeterminado", 63);
- }
- else if (strCurLanguage == 4)
- {
- strncpy(dev->name, "OpenGL di Default", 63);
- }
- else
- {
- strncpy(dev->name, "Default OpenGL", 63);
- }
- dev->modes = NULL;
- //try good old DirectDraw <= 3 enumeration
- memset(&primaryDev, 0, sizeof(rdevice));
- primaryVal = rinEnumeratePrimary(&primaryDev);
- if (primaryVal)
- {
- rinCopyModes(dev, &primaryDev);
- }
- else
- {
- //assume these are supported
- rinAddMode(dev, 640, 480, 16);
- rinAddMode(dev, 800, 600, 16);
- rinAddMode(dev, 1024, 768, 16);
- }
- rinSortModes(dev);
- gldev = dev;
- nDevices++;
- //add possible 3dfx OpenGL device
- voodoo = SST_VOODOO2; //sane default if sstHardwareExists doesn't get called
- if (!(gDevcaps & DEVSTAT_NO_3DFXGL) &&
- (bFullscreenDevice || sstHardwareExists(&voodoo)))
- {
- rdevice* odev = dev;
- dev = (rdevice*)memAlloc(sizeof(rdevice));
- dev->devcaps = 0;
- dev->type = RIN_TYPE_OPENGL;
- dev->data[0] = '\0';
- dev->modes = NULL;
- (void)rinEnumerate3Dfx(dev);
- strncpy(dev->name, "3dfx OpenGL", 63);
- if (dev->modes == NULL)
- {
- switch (voodoo)
- {
- case SST_VOODOO:
- maxWidth = 800;
- break;
- case SST_VOODOO2:
- maxWidth = 1024;
- break;
- default:
- maxWidth = 0;
- }
- rinCopyModesSelectively(dev, odev, 16, maxWidth);
- }
- rinAddDevice(dev);
- rinSortModes(dev);
- nDevices++;
- }
- if (!(gDevcaps & DEVSTAT_NOGL_9X))
- {
- if (gl95)
- {
- if (!(gDevcaps2 & DEVSTAT2_NOGL_95))
- {
- rinAddDevice(gldev);
- }
- }
- else
- {
- rinAddDevice(gldev);
- }
- }
- //add software renderer, an explicitly known device
- dev = (rdevice*)memAlloc(sizeof(rdevice));
- dev->devcaps = 0;
- dev->type = RIN_TYPE_SOFTWARE;
- dev->data[0] = '\0';
- strncpy(dev->name, "Software", 63);
- dev->modes = NULL;
- if (primaryVal)
- {
- if (gDevcaps & DEVSTAT_DISABLE_SW)
- {
- primaryDev.devcaps = gDevcaps;
- rinSortModes(&primaryDev);
- }
- rinCopyModesSelectively(dev, &primaryDev, 16, 1600);
- }
- else
- {
- maxWidth = rinMaxWidth();
- rinAddMode(dev, 640, 480, 16);
- rinAddMode(dev, 800, 600, 16);
- rinAddMode(dev, 1024, 768, 16);
- if (maxWidth >= 1280)
- {
- rinAddMode(dev, 1280, 1024, 16);
- }
- if (maxWidth >= 1600)
- {
- rinAddMode(dev, 1600, 1200, 16);
- }
- }
- rinSortModes(dev);
- rinAddDevice(dev);
- nDevices++;
- if (mainOutputCRC)
- {
- rinCloseCRCLog();
- }
- //success
- return 1;
- }
|