123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- /* Copyright (c) 2002-2012 Croteam Ltd.
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as published by
- the Free Software Foundation
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
- #include "stdh.h"
- #include <Engine/Graphics/Adapter.h>
- #include <Engine/Graphics/GfxLibrary.h>
- #include <Engine/Base/Translation.h>
- #include <Engine/Base/Console.h>
- extern BOOL _bDedicatedServer;
- #ifdef SE1_D3D
- extern const D3DDEVTYPE d3dDevType;
- #endif // SE1_D3D
- // list of all modes avaliable through CDS
- static CListHead _lhCDSModes;
- class CResolution {
- public:
- PIX re_pixSizeI;
- PIX re_pixSizeJ;
- };
- static CResolution _areResolutions[] =
- {
- { 320, 240 },
- { 400, 300 },
- { 480, 360 },
- { 512, 384 },
- { 640, 480 },
- { 720, 540 },
- { 720, 576 },
- { 800, 600 },
- { 960, 720 },
- { 1024, 768 },
- { 1152, 864 },
- { 1280, 960 },
- { 1280, 1024 },
- { 1600, 1200 },
- { 1792, 1344 },
- { 1856, 1392 },
- { 1920, 1440 },
- { 2048, 1536 },
- // matrox dualhead modes
- { 1280, 480 },
- { 1600, 600 },
- { 2048, 768 },
- // NTSC HDTV widescreen
- { 848, 480 },
- { 856, 480 },
- };
- // THIS NUMBER MUST NOT BE OVER 25! (otherwise change it in adapter.h)
- static const INDEX MAX_RESOLUTIONS = sizeof(_areResolutions)/sizeof(_areResolutions[0]);
- // initialize CDS support (enumerate modes at startup)
- void CGfxLibrary::InitAPIs(void)
- {
- // no need for gfx when dedicated server is on
- if( _bDedicatedServer) return;
- CDisplayAdapter *pda;
- INDEX iResolution;
- // detect current mode and print to console
- DEVMODE devmode;
- memset( &devmode, 0, sizeof(devmode));
- devmode.dmSize = sizeof(devmode);
- LONG lRes = EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devmode);
- CPrintF( TRANS("Current display: '%s' version %d - %dx%dx%d\n\n"),
- devmode.dmDeviceName, devmode.dmDriverVersion,
- devmode.dmPelsWidth, devmode.dmPelsHeight, devmode.dmBitsPerPel);
- // fill OpenGL adapter info
- gl_gaAPI[GAT_OGL].ga_ctAdapters = 1;
- gl_gaAPI[GAT_OGL].ga_iCurrentAdapter = 0;
- pda = &gl_gaAPI[GAT_OGL].ga_adaAdapter[0];
- pda->da_ulFlags = DAF_USEGDIFUNCTIONS;
- pda->da_strVendor = TRANS( "unknown");
- pda->da_strRenderer = TRANS( "Default ICD");
- pda->da_strVersion = "1.1+";
- // detect modes for OpenGL ICD
- pda->da_ctDisplayModes = 0;
- pda->da_iCurrentDisplayMode = -1;
- // enumerate modes thru resolution list
- for( iResolution=0; iResolution<MAX_RESOLUTIONS; iResolution++)
- {
- DEVMODE devmode;
- memset( &devmode, 0, sizeof(devmode));
- CResolution &re = _areResolutions[iResolution];
- // ask windows if they could set the mode
- devmode.dmSize = sizeof(devmode);
- devmode.dmPelsWidth = re.re_pixSizeI;
- devmode.dmPelsHeight = re.re_pixSizeJ;
- devmode.dmDisplayFlags = CDS_FULLSCREEN;
- devmode.dmFields = DM_PELSWIDTH|DM_PELSHEIGHT|DM_DISPLAYFLAGS;
- LONG lRes = ChangeDisplaySettings( &devmode, CDS_TEST|CDS_FULLSCREEN);
- // skip if not successfull
- if( lRes!=DISP_CHANGE_SUCCESSFUL) continue;
- // make a new display mode
- CDisplayMode &dm = pda->da_admDisplayModes[pda->da_ctDisplayModes];
- dm.dm_pixSizeI = re.re_pixSizeI;
- dm.dm_pixSizeJ = re.re_pixSizeJ;
- dm.dm_ddDepth = DD_DEFAULT;
- pda->da_ctDisplayModes++;
- }
- // detect presence of 3Dfx standalone OpenGL driver (for Voodoo1/2)
- char *strDummy;
- char strBuffer[_MAX_PATH+1];
- int iRes = SearchPathA( NULL, "3DFXVGL.DLL", NULL, _MAX_PATH, strBuffer, &strDummy);
- // if present
- if(iRes) {
- // set adapter and force some enumeration of voodoo1/2 display modes
- gl_gaAPI[GAT_OGL].ga_ctAdapters++;
- pda = &gl_gaAPI[GAT_OGL].ga_adaAdapter[1];
- pda->da_ctDisplayModes = 4; // voodoos have only 4 display modes
- pda->da_ulFlags = DAF_ONEWINDOW | DAF_FULLSCREENONLY | DAF_16BITONLY;
- pda->da_strVendor = "3Dfx";
- pda->da_strRenderer = "3Dfx Voodoo2";
- pda->da_strVersion = "1.1+";
- CDisplayMode *adm = &pda->da_admDisplayModes[0];
- adm[0].dm_pixSizeI = 512; adm[0].dm_pixSizeJ = 384; adm[0].dm_ddDepth = DD_16BIT;
- adm[1].dm_pixSizeI = 640; adm[1].dm_pixSizeJ = 480; adm[1].dm_ddDepth = DD_16BIT;
- adm[2].dm_pixSizeI = 800; adm[2].dm_pixSizeJ = 600; adm[2].dm_ddDepth = DD_16BIT;
- adm[3].dm_pixSizeI = 1024; adm[3].dm_pixSizeJ = 768; adm[3].dm_ddDepth = DD_16BIT;
- }
- // try to init Direct3D 8
- #ifdef SE1_D3D
- BOOL bRes = InitDriver_D3D();
- if( !bRes) return; // didn't made it?
-
- // determine DX8 adapters and display modes
- const INDEX ctMaxAdapters = gl_pD3D->GetAdapterCount();
- INDEX &ctAdapters = gl_gaAPI[GAT_D3D].ga_ctAdapters;
- ctAdapters = 0;
- for( INDEX iAdapter=0; iAdapter<ctMaxAdapters; iAdapter++)
- {
- pda = &gl_gaAPI[1].ga_adaAdapter[ctAdapters];
- pda->da_ulFlags = NONE;
- pda->da_ctDisplayModes = 0;
- INDEX ctModes = gl_pD3D->GetAdapterModeCount(iAdapter);
- INDEX iMode;
- HRESULT hr;
- // check whether 32-bits rendering modes are supported
- hr = gl_pD3D->CheckDeviceType( iAdapter, d3dDevType, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE);
- if( hr!=D3D_OK) {
- hr = gl_pD3D->CheckDeviceType( iAdapter, d3dDevType, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, FALSE);
- if( hr!=D3D_OK) pda->da_ulFlags |= DAF_16BITONLY;
- }
- // check whether windowed rendering modes are supported
- D3DCAPS8 d3dCaps;
- gl_pD3D->GetDeviceCaps( iAdapter, d3dDevType, &d3dCaps);
- if( !(d3dCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED)) pda->da_ulFlags |= DAF_FULLSCREENONLY;
- // enumerate modes thru resolution list
- for( iResolution=0; iResolution<MAX_RESOLUTIONS; iResolution++)
- {
- CResolution &re = _areResolutions[iResolution];
- for( iMode=0; iMode<ctModes; iMode++) {
- // if resolution matches and display depth is 16 or 32 bit
- D3DDISPLAYMODE d3dDisplayMode;
- gl_pD3D->EnumAdapterModes( iAdapter, iMode, &d3dDisplayMode);
- if( d3dDisplayMode.Width==re.re_pixSizeI && d3dDisplayMode.Height==re.re_pixSizeJ
- && (d3dDisplayMode.Format==D3DFMT_A8R8G8B8 || d3dDisplayMode.Format==D3DFMT_X8R8G8B8
- || d3dDisplayMode.Format==D3DFMT_A1R5G5B5 || d3dDisplayMode.Format==D3DFMT_X1R5G5B5
- || d3dDisplayMode.Format==D3DFMT_R5G6B5)) {
- hr = gl_pD3D->CheckDeviceType( iAdapter, d3dDevType, d3dDisplayMode.Format, d3dDisplayMode.Format, FALSE);
- if( hr!=D3D_OK) continue;
- // make a new display mode
- CDisplayMode &dm = pda->da_admDisplayModes[pda->da_ctDisplayModes];
- dm.dm_pixSizeI = re.re_pixSizeI;
- dm.dm_pixSizeJ = re.re_pixSizeJ;
- dm.dm_ddDepth = DD_DEFAULT;
- pda->da_ctDisplayModes++;
- break;
- }
- }
- }
- // get adapter identifier
- ctAdapters++;
- D3DADAPTER_IDENTIFIER8 d3dAdapterIdentifier;
- gl_pD3D->GetAdapterIdentifier( iAdapter, D3DENUM_NO_WHQL_LEVEL, &d3dAdapterIdentifier);
- pda->da_strVendor = "MS DirectX 8";
- pda->da_strRenderer = d3dAdapterIdentifier.Description;
- pda->da_strVersion.PrintF("%d.%d.%d.%d", d3dAdapterIdentifier.DriverVersion.HighPart >>16,
- d3dAdapterIdentifier.DriverVersion.HighPart & 0xFFFF,
- d3dAdapterIdentifier.DriverVersion.LowPart >>16,
- d3dAdapterIdentifier.DriverVersion.LowPart & 0xFFFF);
- }
- // shutdown DX8 (we'll start it again if needed)
- D3DRELEASE( gl_pD3D, TRUE);
- if( gl_hiDriver!=NONE) FreeLibrary(gl_hiDriver);
- gl_hiDriver = NONE;
- #endif // SE1_D3D
- }
- // get list of all modes avaliable through CDS -- do not modify/free the returned list
- CListHead &CDS_GetModes(void)
- {
- return _lhCDSModes;
- }
- // set given display mode
- BOOL CDS_SetMode( PIX pixSizeI, PIX pixSizeJ, enum DisplayDepth dd)
- {
- // no need for gfx when dedicated server is on
- if( _bDedicatedServer) return FALSE;
- // prepare general mode parameters
- DEVMODE devmode;
- memset(&devmode, 0, sizeof(devmode));
- devmode.dmSize = sizeof(devmode);
- devmode.dmPelsWidth = pixSizeI;
- devmode.dmPelsHeight = pixSizeJ;
- devmode.dmDisplayFlags = CDS_FULLSCREEN;
- devmode.dmFields = DM_PELSWIDTH|DM_PELSHEIGHT|DM_DISPLAYFLAGS;
- extern INDEX gap_iRefreshRate;
- if( gap_iRefreshRate>0) {
- devmode.dmFields |= DM_DISPLAYFREQUENCY;
- devmode.dmDisplayFrequency = gap_iRefreshRate;
- }
- // determine bits per pixel to try to set
- SLONG slBPP2 = 0;
- switch(dd) {
- case DD_16BIT:
- devmode.dmBitsPerPel = 16;
- slBPP2 = 15;
- devmode.dmFields |= DM_BITSPERPEL;
- break;
- case DD_32BIT:
- devmode.dmBitsPerPel = 32;
- slBPP2 = 24;
- devmode.dmFields |= DM_BITSPERPEL;
- break;
- case DD_DEFAULT:
- NOTHING;
- break;
- default:
- ASSERT(FALSE);
- NOTHING;
- }
- // try to set primary depth
- LONG lRes = ChangeDisplaySettings(&devmode, CDS_FULLSCREEN);
- // if failed
- if( lRes!=DISP_CHANGE_SUCCESSFUL) {
- // try to set secondary depth
- devmode.dmBitsPerPel = slBPP2;
- LONG lRes2 = ChangeDisplaySettings(&devmode, CDS_FULLSCREEN);
- // if failed
- if( lRes2!=DISP_CHANGE_SUCCESSFUL) {
- CTString strError;
- switch(lRes) {
- case DISP_CHANGE_SUCCESSFUL: strError = "DISP_CHANGE_SUCCESSFUL"; break;
- case DISP_CHANGE_RESTART: strError = "DISP_CHANGE_RESTART"; break;
- case DISP_CHANGE_BADFLAGS: strError = "DISP_CHANGE_BADFLAGS"; break;
- case DISP_CHANGE_BADPARAM: strError = "DISP_CHANGE_BADPARAM"; break;
- case DISP_CHANGE_FAILED: strError = "DISP_CHANGE_FAILED"; break;
- case DISP_CHANGE_BADMODE: strError = "DISP_CHANGE_BADMODE"; break;
- case DISP_CHANGE_NOTUPDATED: strError = "DISP_CHANGE_NOTUPDATED"; break;
- default: strError.PrintF("%d", lRes); break;
- }
- CPrintF(TRANS("CDS error: %s\n"), strError);
- return FALSE;
- }
- }
- // report
- CPrintF(TRANS(" CDS: mode set to %dx%dx%d\n"), pixSizeI, pixSizeJ, devmode.dmBitsPerPel);
- return TRUE;
- }
- // reset windows to mode chosen by user within windows diplay properties
- void CDS_ResetMode(void)
- {
- // no need for gfx when dedicated server is on
- if( _bDedicatedServer) return;
- LONG lRes = ChangeDisplaySettings( NULL, 0);
- ASSERT(lRes==DISP_CHANGE_SUCCESSFUL);
- CPrintF(TRANS(" CDS: mode reset to original desktop settings\n"));
- }
|