Re #320 Fixes the best Open GL feature detection system through a 2-pass method with possible game auto-restart

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@3535 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: 236286aec370f597c406726b5101c1262b433f6e
Former-commit-id: a5db6ccff24f2e41e4763ae36e4860b67b1600cb
This commit is contained in:
pouillot 2011-05-03 09:58:19 +00:00
parent 2c23d7a135
commit 764a4497a1
9 changed files with 916 additions and 504 deletions

View file

@ -465,20 +465,24 @@ void GfInit(void)
*/
void GfShutdown(void)
{
GfLogDebug("Shutting down gaming framework.\n");
// Shudown SDL.
SDL_Quit();
// Shutdown the active profilers and dump the report if any.
GfProfStopActiveProfiles();
GfProfPrintReport();
GfProfPrintReport();
}
/** Restart the gaming framework (restart the current process).
@ingroup tgf
@param bHardwareMouse If true, use hardware mouse cursor
@return None
@warning Never returns (restart the process).
@warning GfShutdown should be called before ; never returns (restart the process).
*/
// TODO: Move this to the GfApplication/GfuiApplication separate scheme.
void GfRestart(bool bHardwareMouse)
{
int retcode = 0;
@ -549,7 +553,7 @@ void GfRestart(bool bHardwareMouse)
// Finally, last null arg.
args[argInd] = 0;
// Exec the command : restart the game (simply replacing current process)
GfLogInfo("Restarting ");
for (i = 0; args[i]; i++)

File diff suppressed because it is too large Load diff

View file

@ -52,9 +52,8 @@
A feature that is not supported can not be selected (or enabled).
A feature that is selected is not necessarily enabled (not done here).
Warning: GfglFeatures::checkSupport() mustn't be used before the 1st successfull call
to SDL_SetVideoMode() (needs an up-and-running frame buffer).
Integer features must follow an "increasing order" : a value better value is greater,
and thus a selected value can't be greater than a supported one.
*/
class TGFCLIENT_API GfglFeatures
@ -64,19 +63,33 @@ class TGFCLIENT_API GfglFeatures
// Access to the unique instance.
static GfglFeatures& self();
// Load selected features from the config file (default = GFSCR_CONF_FILE).
// Check best supported OpenGL features, and store report to the config file
// (default = GFSCR_CONF_FILE). May restart the game.
bool checkBestSupport(int nWidth, int nHeight, int nDepth,
bool bAlpha, bool bFullScreen, void* hparmConfig = 0);
// Detect standard supported features. Don't restart the game.
// Precondiftion: SDL_setVideoMode(...)
void detectStandardSupport();
// Dump detected supported features (in the current trace stream).
void dumpSupport() const;
// Load user-selected features from the config file (default = GFSCR_CONF_FILE).
// Precondiftion: checkBestSupport() or checkStandardSupport().
void loadSelection(void* hparmConfig = 0);
// Check supported features (ask OpenGL), and update selection as needed.
// Warning: Must not be called before any successfull call to SDL_SetVideoMode()
void checkSupport();
// Store selected features to the config file (default = GFSCR_CONF_FILE).
// Store user-selected features to the config file (default = GFSCR_CONF_FILE).
// Precondiftion: loadSelection()
void storeSelection(void* hparmConfig = 0) const;
// Dump selected features (in the current trace stream).
// Dump user-selected features (in the current trace stream).
void dumpSelection() const;
// Dump info about the underlying hardware
// Precondiftion: SDL_setVideoMode(...)
void dumpHardwareInfo() const;
// Bool-valued features.
enum EFeatureBool
{
@ -90,9 +103,10 @@ class TGFCLIENT_API GfglFeatures
void select(EFeatureBool eFeature, bool bSelected);
bool isSelected(EFeatureBool eFeature) const;
bool isSupported(EFeatureBool eFeature) const;
void setSupported(EFeatureBool eFeature, bool bSupported);
//void setSupported(EFeatureBool eFeature, bool bSupported);
// Integer-valued features (WARNING: For the moment, -1 means "not supported").
// Integer-valued features (use InvalidInt for the "not supported" / "not selected" cases).
static int InvalidInt;
enum EFeatureInt
{
ColorDepth, AlphaDepth,
@ -103,25 +117,42 @@ class TGFCLIENT_API GfglFeatures
void select(EFeatureInt eFeature, int nSelectedValue);
int getSelected(EFeatureInt eFeature) const;
int getSupported(EFeatureInt eFeature) const;
void setSupported(EFeatureInt eFeature, int nSupportedValue);
//void setSupported(EFeatureInt eFeature, int nSupportedValue);
// Get the pointer to the named OpenGL extension function.
static void* getProcAddress(const char* pszName);
private:
GfglFeatures(); // Singleton pattern => private constructor.
//! Singleton pattern => private constructor.
GfglFeatures();
// Update supported OpenGL features according to the given frame buffer specs.
bool detectBestSupport(int& nWidth, int& nHeight, int& nDepth,
bool& bAlpha, bool& bFullScreen);
bool loadSupport(int &nWidth, int &nHeight, int &nDepth,
bool &bAlpha, bool &bFullScreen, void* hparmConfig = 0);
void storeSupport(int nWidth, int nHeight, int nDepth,
bool bAlpha, bool bFullScreen, void* hparmConfig = 0);
static void* openConfigFile();
static void closeConfigFile(void* hparmConfig, bool bWrite = false);
private:
// The unique instance.
//! The unique instance (singleton pattern).
static GfglFeatures* _pSelf;
// Maps of supported features (bool and int-valued).
//! The config files params pointer.
//void* hparmConfig;
//! Maps of supported features (bool and int-valued).
std::map<EFeatureBool, bool> _mapSupportedBool;
std::map<EFeatureInt, int> _mapSupportedInt;
// Maps of selected features (bool and int-valued).
//! Maps of selected features (bool and int-valued).
std::map<EFeatureBool, bool> _mapSelectedBool;
std::map<EFeatureInt, int> _mapSelectedInt;
};

View file

@ -72,8 +72,8 @@ void GfuiEventLoop::injectKeyboardEvent(int code, int modifier, int state,
// its WM keyboard shortcuts (didn't find any other way yet).
if (code == SDLK_RETURN && (modifier & KMOD_ALT) && state == 0)
{
if (!SDL_WM_ToggleFullScreen(gfScrGetScreenSurface()))
GfLogError("SDL_WM_ToggleFullScreen failed\n");
if (!GfScrToggleFullScreen())
GfLogError("Failed to toggle on/off the full-screen mode\n");
}
else
#endif

View file

@ -40,6 +40,7 @@
#endif
#include <SDL/SDL.h>
#include <SDL/SDL_video.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
@ -62,7 +63,7 @@ static int GfScrCenX;
static int GfScrCenY;
// The screen surface.
SDL_Surface *ScreenSurface = NULL;
static SDL_Surface *PScreenSurface = NULL;
/* Default list of screen color depths (bits per pixel, alpha included) in case
something went wrong during hardware / driver capabilities detection */
@ -311,11 +312,11 @@ int* GfScrGetSupportedColorDepths(int* pnDepths)
static void gfScrReshapeViewport(int width, int height)
{
glViewport( (width-GfViewWidth)/2, (height-GfViewHeight)/2, GfViewWidth, GfViewHeight);
glMatrixMode( GL_PROJECTION );
glViewport((width-GfViewWidth)/2, (height-GfViewHeight)/2, GfViewWidth, GfViewHeight);
glMatrixMode(GL_PROJECTION );
glLoadIdentity();
glOrtho( 0.0, 640.0, 0.0, 480.0, -1.0, 1.0 );
glMatrixMode( GL_MODELVIEW );
glOrtho(0.0, 640.0, 0.0, 480.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GfScrWidth = width;
@ -337,6 +338,23 @@ bool GfScrInit(void)
// (SDL_InitSubSystem(SDL_INIT_VIDEO) seems to break it).
SDL_EnableUNICODE(/*enable=*/1);
// Set window/icon captions
char pszCaption[64];
sprintf(pszCaption, "Speed Dreams %s", VERSION_LONG);
SDL_WM_SetCaption(pszCaption, pszCaption);
// Set window icon (MUST be a 32x32 icon for Windows, and with black pixels as alpha ones,
// as BMP doesn't support transparency).
char pszIconFilename[256];
sprintf(pszIconFilename, "%sdata/icons/icon.bmp", GfDataDir());
SDL_Surface* surfIcon = SDL_LoadBMP(pszIconFilename);
if (surfIcon)
{
SDL_SetColorKey(surfIcon, SDL_SRCCOLORKEY, SDL_MapRGB(surfIcon->format, 0, 0, 0));
SDL_WM_SetIcon(surfIcon, 0);
SDL_FreeSurface(surfIcon);
}
// Query system video capabilities.
// Note: Does not work very well as long as you don't force SDL to use
// a special hardware driver ... which we don't want at all (the default is the one).
@ -369,253 +387,151 @@ bool GfScrInit(void)
// GfLogInfo(" Hardware acceleration : %s\n", sdlVideoInfo->hw_available ? "Yes" : "No");
// GfLogInfo(" Total video memory : %u Kb\n", sdlVideoInfo->video_mem);
// Get graphical settings from config file.
char buf[512];
sprintf(buf, "%s%s", GfLocalDir(), GFSCR_CONF_FILE);
void* hparmScreen = GfParmReadFile(buf, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
// Get selected frame buffer specs from config file.
char pszConfigFilename[256];
sprintf(pszConfigFilename, "%s%s", GfLocalDir(), GFSCR_CONF_FILE);
void* hparmScreen = GfParmReadFile(pszConfigFilename, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
int winX = (int)GfParmGetNum(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_WIN_X, (char*)NULL, 800);
int winY = (int)GfParmGetNum(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_WIN_Y, (char*)NULL, 600);
int depth = (int)GfParmGetNum(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_BPP, (char*)NULL, 32);
//int maxfreq = (int)GfParmGetNum(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_MAXREFRESH, (char*)NULL, 160);
const std::string strFullScreen =
GfParmGetStr(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_FSCR, GFSCR_VAL_NO);
const std::string strVideoInit =
GfParmGetStr(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_VINIT, GFSCR_VAL_VINIT_COMPATIBLE);
int nWinWidth =
(int)GfParmGetNum(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_WIN_X, (char*)NULL, 800);
int nWinHeight =
(int)GfParmGetNum(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_WIN_Y, (char*)NULL, 600);
int nTotalDepth =
(int)GfParmGetNum(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_BPP, (char*)NULL, 32);
bool bAlphaChannel =
std::string(GfParmGetStr(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_ALPHACHANNEL,
GFSCR_VAL_YES))
== GFSCR_VAL_YES;
bool bFullScreen =
std::string(GfParmGetStr(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_FSCR, GFSCR_VAL_NO))
== GFSCR_VAL_YES;
bool bBestVideoInitMode =
std::string(GfParmGetStr(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_VINIT,
GFSCR_VAL_VINIT_BEST))
== GFSCR_VAL_VINIT_BEST;
// Load Open GL settings from config file.
GfglFeatures::self().loadSelection();
// Prepare video mode.
int bfVideoMode = SDL_OPENGL;
if (bFullScreen)
bfVideoMode |= SDL_FULLSCREEN;
// If specified, try best possible settings.
PScreenSurface = 0;
if (bBestVideoInitMode)
{
GfLogInfo("Trying 'best possible mode' for video initialization.\n");
// Detect best supported features for the specified frame buffer specs.
// Warning: Restarts the game if the frame buffer specs changed since last call.
bBestVideoInitMode =
GfglFeatures::self().checkBestSupport(nWinWidth, nWinHeight, nTotalDepth,
bAlphaChannel, bFullScreen, hparmScreen);
// If successfull detection, setup the user-selected mode.
if (bBestVideoInitMode)
{
// Load Open GL user settings from the config file.
GfglFeatures::self().loadSelection();
// Set window/icon captions
sprintf(buf, "Speed Dreams %s", VERSION_LONG);
SDL_WM_SetCaption(buf, buf);
// Set window icon (MUST be a 32x32 icon for Windows, and with black pixels as alpha ones,
// as BMP doesn't support transparency).
sprintf(buf, "%sdata/icons/icon.bmp", GfDataDir());
SDL_Surface* surfIcon = SDL_LoadBMP(buf);
if (surfIcon)
{
SDL_SetColorKey(surfIcon, SDL_SRCCOLORKEY, SDL_MapRGB(surfIcon->format, 0, 0, 0));
SDL_WM_SetIcon(surfIcon, 0);
SDL_FreeSurface(surfIcon);
}
// Set full screen mode if selected.
int videomode = SDL_OPENGL; // What about SDL_DOUBLEBUFFER ?
if (strFullScreen == "yes")
videomode |= SDL_FULLSCREEN;
// Video initialization with best possible settings.
ScreenSurface = 0;
if (strVideoInit == GFSCR_VAL_VINIT_BEST)
{
GfLogInfo("Detecting 'best possible mode' for video initialization.\n");
// Set the minimum requirements for the OpenGL window
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
// Try to get "best" videomode with maximum anti-aliasing support :
// 24 bit z-buffer with alpha channel
// (even if not selected : we 1st detect what we can do at most).
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
// Detect the max supported number of samples.
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
int nSamples = 32; // Hard coded max value for the moment.
while (!ScreenSurface && nSamples > 1)
{
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, nSamples);
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
if (!ScreenSurface)
{
GfLogTrace("Can't get a video mode for a 24+8 bit "
"%dx anti-aliased double-buffer\n", nSamples);
nSamples /= 2;
}
}
// Store the detected anti-aliasing supported features.
GfglFeatures::self().setSupported(GfglFeatures::MultiSampling, ScreenSurface != 0);
if (ScreenSurface)
GfglFeatures::self().setSupported(GfglFeatures::MultiSamplingSamples, nSamples);
if (ScreenSurface)
SDL_FreeSurface(ScreenSurface);
// Then, back to the user selection (may have been updated by the detection above).
GfLogInfo("Trying user selected 'best possible mode' for video initialization.\n");
if (GfglFeatures::self().isSelected(GfglFeatures::MultiSampling))
{
nSamples = GfglFeatures::self().getSelected(GfglFeatures::MultiSamplingSamples);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, nSamples);
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
if (!ScreenSurface)
GfLogTrace("Can't get a video mode for a 24+8 bit "
"%dx anti-aliased double-buffer\n", nSamples);
}
else
{
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 1);
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
if (!ScreenSurface)
GfLogTrace("Can't get a video mode for a 24+8 bit double-buffer\n");
}
// Failed : try with anti-aliasing if selected, but without alpha channel.
if (!ScreenSurface)
{
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
if (GfglFeatures::self().isSelected(GfglFeatures::MultiSampling))
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
if (!ScreenSurface)
GfLogTrace("Can't get a video mode for a 24 bit anti-aliased double-buffer\n");
}
// Failed : try without anti-aliasing if selected, and without alpha channel.
if (!ScreenSurface && GfglFeatures::self().isSelected(GfglFeatures::MultiSampling))
{
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
if (!ScreenSurface)
GfLogTrace("Can't get a video mode for a 24 bit double-buffer\n");
}
// Failed : try 16 bit z-buffer and back with alpha channel and anti-aliasing if selected.
if (!ScreenSurface)
{
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
if (GfglFeatures::self().isSelected(GfglFeatures::MultiSampling))
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
if (!ScreenSurface)
GfLogTrace("Can't get a video mode for a 16+8 bit anti-aliased double-buffer\n");
}
// Failed : try without anti-aliasing if selected.
if (!ScreenSurface && GfglFeatures::self().isSelected(GfglFeatures::MultiSampling))
{
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
if (!ScreenSurface)
GfLogTrace("Can't get a video mode for a 16+8 bit double-buffer\n");
}
// Failed : try with anti-aliasing if selected, but without alpha channel.
if (!ScreenSurface)
{
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
if (GfglFeatures::self().isSelected(GfglFeatures::MultiSampling))
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
if (!ScreenSurface)
GfLogTrace("Can't get a video mode for a 16 bit anti-aliased double-buffer\n");
}
// Failed : try without anti-aliasing if selected, and without alpha channel.
if (!ScreenSurface && GfglFeatures::self().isSelected(GfglFeatures::MultiSampling))
{
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
if (!ScreenSurface)
GfLogTrace("Can't get a video mode for a 16 bit double-buffer\n");
}
// Failed : Change display / Open GL settings and restart.
if (!ScreenSurface)
{
// Retry without anti-aliasing if selected if it was requested.
if (GfglFeatures::self().isSelected(GfglFeatures::MultiSampling))
{
GfLogWarning("Failed to setup best supported video mode : "
"retrying without anti-aliasing at all ...\n");
GfglFeatures::self().select(GfglFeatures::MultiSampling, false);
GfglFeatures::self().storeSelection(hparmScreen);
}
// Setup the video mode parameters.
const int nColorDepth =
GfglFeatures::self().getSelected(GfglFeatures::ColorDepth);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, nColorDepth/3);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, nColorDepth/3);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, nColorDepth/3);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, nColorDepth);
// Otherwise, retry a "compatible" = "all defaults" initialization mode.
else if (strFullScreen == "yes")
{
GfLogWarning("Failed to setup full-screen best supported video mode : "
"retrying in windowed mode ...\n");
GfParmSetStr(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_FSCR, GFSCR_VAL_NO);
GfParmWriteFile(NULL, hparmScreen, "Screen");
}
const int nAlphaDepth =
GfglFeatures::self().getSelected(GfglFeatures::AlphaDepth);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, nAlphaDepth);
// Otherwise, retry a "compatible" = "all defaults" initialization mode.
else
const int nDoubleBuffer =
GfglFeatures::self().isSelected(GfglFeatures::DoubleBuffer) ? 1 : 0;
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, nDoubleBuffer);
const int nMultiSampling =
GfglFeatures::self().isSelected(GfglFeatures::MultiSampling) ? 1 : 0;
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, nMultiSampling);
if (nMultiSampling)
{
GfLogWarning("Failed to setup best supported video mode : "
"falling back to a more compatible default mode ...\n");
const int nMaxMultiSamples =
GfglFeatures::self().getSelected(GfglFeatures::MultiSamplingSamples);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, nMaxMultiSamples);
}
// Try the video mode with these parameters : should always work
// (unless you upgraded you hardware / OS and didn't clear your config file).
PScreenSurface = SDL_SetVideoMode(nWinWidth, nWinHeight, nTotalDepth, bfVideoMode);
if (!PScreenSurface)
{
// Should not happen, as we tested it in checkBestSupport ...
GfLogWarning("Failed to setup best supported video mode "
"whereas previously detected !\n");
GfLogWarning("Falling back to a more compatible default mode ...\n");
GfLogInfo("Tip: You should remove your %s%s file and restart,\n",
GfLocalDir(), GFSCR_CONF_FILE);
GfLogInfo(" if something changed in your OS"
" or video hardware/driver configuration.\n");
// Forcing compatible video init. mode.
GfParmSetStr(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_VINIT,
GFSCR_VAL_VINIT_COMPATIBLE);
GfParmWriteFile(NULL, hparmScreen, "Screen");
GfParmReleaseHandle(hparmScreen);
// And restart the game.
GfuiApp().restart(); // Never returns.
}
GfParmReleaseHandle(hparmScreen);
GfRestart(); // Never returns.
}
}
else
{
// Store the detected anti-aliasing supported features.
GfglFeatures::self().setSupported(GfglFeatures::MultiSampling, false);
GfglFeatures::self().setSupported(GfglFeatures::MultiSamplingSamples, -1);
}
// No more need for the config file.
GfParmReleaseHandle(hparmScreen);
// Video initialization with generic compatible settings.
if (!ScreenSurface)
if (!PScreenSurface)
{
GfLogInfo("Trying 'default compatible' mode for video initialization.\n");
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
if (!ScreenSurface)
PScreenSurface = SDL_SetVideoMode(nWinWidth, nWinHeight, nTotalDepth, bfVideoMode);
if (!PScreenSurface)
GfLogTrace("Can't get a %s%dx%dx%d compatible video mode\n",
strFullScreen == "yes" ? "full-screen " : "", winX, winY, depth);
bFullScreen ? "full-screen " : "", nWinWidth, nWinHeight, nTotalDepth);
}
// Failed : Try and remove the full-screen requirement if present ...
if (!ScreenSurface && strFullScreen == "yes")
if (!PScreenSurface && bFullScreen)
{
videomode &= ~SDL_FULLSCREEN;
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
if (!ScreenSurface)
bfVideoMode &= ~SDL_FULLSCREEN;
PScreenSurface = SDL_SetVideoMode(nWinWidth, nWinHeight, nTotalDepth, bfVideoMode);
if (!PScreenSurface)
GfLogTrace("Can't get a non-full-screen %dx%dx%d compatible video mode\n",
winX, winY, depth);
nWinWidth, nWinHeight, nTotalDepth);
}
// Failed : Try with a lower fallback size : should be supported everywhere ...
if (!ScreenSurface)
if (!PScreenSurface)
{
winX = ADefScreenSizes[0].width;
winY = ADefScreenSizes[0].height;
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
if (!ScreenSurface)
GfLogTrace("Can't get a %dx%dx%d compatible video mode\n", winX, winY, depth);
nWinWidth = ADefScreenSizes[0].width;
nWinHeight = ADefScreenSizes[0].height;
PScreenSurface = SDL_SetVideoMode(nWinWidth, nWinHeight, nTotalDepth, bfVideoMode);
if (!PScreenSurface)
GfLogTrace("Can't get a %dx%dx%d compatible video mode\n",
nWinWidth, nWinHeight, nTotalDepth);
}
// Failed : Try with a lower fallback color depth : should be supported everywhere ...
if (!ScreenSurface)
if (!PScreenSurface)
{
depth = ADefScreenColorDepths[0];
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
if (!ScreenSurface)
GfLogTrace("Can't get a %dx%dx%d compatible video mode\n", winX, winY, depth);
nTotalDepth = ADefScreenColorDepths[0];
PScreenSurface = SDL_SetVideoMode(nWinWidth, nWinHeight, nTotalDepth, bfVideoMode);
if (!PScreenSurface)
GfLogTrace("Can't get a %dx%dx%d compatible video mode\n",
nWinWidth, nWinHeight, nTotalDepth);
}
// Failed : No way ... no more ideas !
if (!ScreenSurface)
if (!PScreenSurface)
{
GfLogError("Unable to get any compatible video mode"
" (fallback resolution / color depth not supported) : giving up !\n\n");
@ -624,43 +540,51 @@ bool GfScrInit(void)
// If we get here, that's because we succeeded in getting a valid video mode :-)
// If 'compatible mode' selected, detect only standard Open GL features
// and load settings from the config file.
if (!bBestVideoInitMode)
{
GfglFeatures::self().detectStandardSupport();
GfglFeatures::self().dumpSupport();
GfglFeatures::self().loadSelection();
}
// Save view geometry and screen center.
GfViewWidth = winX;
GfViewHeight = winY;
GfScrCenX = winX / 2;
GfScrCenY = winY / 2;
GfViewWidth = nWinWidth;
GfViewHeight = nWinHeight;
GfScrCenX = nWinWidth / 2;
GfScrCenY = nWinHeight / 2;
// Report about selected SDL video mode.
GfLogInfo("Selected SDL video mode :\n");
GfLogInfo(" Full screen : %s\n", (videomode & SDL_FULLSCREEN) ? "Yes" : "No");
GfLogInfo(" Size : %dx%d\n", winX, winY);
GfLogInfo(" Color depth : %d bits\n", depth);
GfLogInfo(" Full screen : %s\n", (bfVideoMode & SDL_FULLSCREEN) ? "Yes" : "No");
GfLogInfo(" Size : %dx%d\n", nWinWidth, nWinHeight);
GfLogInfo(" Color depth : %d bits\n", nTotalDepth);
// Report about underlying hardware (needs a running frame buffer).
GfglFeatures::self().dumpHardwareInfo();
// Initialize the Open GL feature management layer and report about the supported features
// (may appear double work for anti-aliasing support - see above -
// but we can't check such support before a successfull call to SDL_SetVideoMode()).
GfglFeatures::self().checkSupport();
// Report about the actually selected support, after checking support.
GfglFeatures::self().dumpSelection();
#ifdef WIN32
// Under Windows, give an initial position to the window if not full-screen mode
// (under Linux/Mac OS X, no need, the window manager smartly takes care of this).
if (!(videomode & SDL_FULLSCREEN))
if (!(bfVideoMode & SDL_FULLSCREEN))
{
// Try to center the game Window on the desktop, but keep the title bar visible if any.
const HWND hDesktop = GetDesktopWindow();
RECT rectDesktop;
GetWindowRect(hDesktop, &rectDesktop);
const int nWMWinXPos = winX >= rectDesktop.right ? 0 : (rectDesktop.right - winX) / 2;
const int nWMWinYPos = winY >= rectDesktop.bottom ? 0 : (rectDesktop.bottom - winY) / 2;
GfuiInitWindowPositionAndSize(nWMWinXPos, nWMWinYPos, winX, winY);
const int nWMWinXPos =
nWinWidth >= rectDesktop.right ? 0 : (rectDesktop.right - nWinWidth) / 2;
const int nWMWinYPos =
nWinHeight >= rectDesktop.bottom ? 0 : (rectDesktop.bottom - nWinHeight) / 2;
GfuiInitWindowPositionAndSize(nWMWinXPos, nWMWinYPos, nWinWidth, nWinHeight);
}
#endif
// Initialize the Open GL viewport.
gfScrReshapeViewport(winX, winY);
gfScrReshapeViewport(nWinWidth, nWinHeight);
// Setup the event loop about the new display.
GfuiApp().eventLoop().setReshapeCB(gfScrReshapeViewport);
@ -675,6 +599,9 @@ bool GfScrInit(void)
*/
void GfScrShutdown(void)
{
GfLogTrace("Shutting down screen.\n");
SDL_QuitSubSystem(SDL_INIT_VIDEO);
}
@ -694,6 +621,11 @@ void GfScrGetSize(int *scrW, int *scrH, int *viewW, int *viewH)
*viewH = GfViewHeight;
}
bool GfScrToggleFullScreen()
{
return SDL_WM_ToggleFullScreen(PScreenSurface) != 0;
}
/** Capture screen pixels into an RGB buffer (caller must free the here-allocated buffer).
@ingroup screen
@param scrw address of screen with
@ -755,9 +687,3 @@ int GfScrCaptureAsPNG(const char *filename)
return nStatus;
}
// Accessor to the SDL screen surface.
SDL_Surface* gfScrGetScreenSurface()
{
return ScreenSurface;
}

View file

@ -18,7 +18,7 @@
***************************************************************************/
/** @file
Constants for screen / Open GL features config file
@author <a href=mailto:torcs@free.fr>Eric Espie</a>
@version $Id$
*/
@ -26,9 +26,6 @@
#ifndef _GUISCREEN_H_
#define _GUISCREEN_H_
#include <SDL/SDL_video.h>
#define GFSCR_CONF_FILE "config/screen.xml"
#define GFSCR_SECT_PROP "Screen Properties"
@ -37,10 +34,11 @@
#define GFSCR_ATT_WIN_X "window width"
#define GFSCR_ATT_WIN_Y "window height"
#define GFSCR_ATT_MAXREFRESH "maximum refresh frequency"
#define GFSCR_ATT_FSCR "fullscreen"
#define GFSCR_ATT_FSCR "full-screen"
#define GFSCR_VAL_YES "yes"
#define GFSCR_VAL_NO "no"
#define GFSCR_ATT_GAMMA "gamma"
#define GFSCR_ATT_ALPHACHANNEL "alpha channel"
#define GFSCR_ATT_VDETECT "video mode detect"
#define GFSCR_VAL_VDETECT_AUTO "auto"
@ -86,25 +84,37 @@
#define GFSCR_ATTR_BLUE "blue"
#define GFSCR_ATTR_ALPHA "alpha"
#define GfSCR_SECT_GLFEATURES "OpenGL Features"
// Open GL user-selected features
#define GFSCR_SECT_GLSELFEATURES "OpenGL Selected Features"
#define GfSCR_ATT_TEXTURECOMPRESSION "texture compression"
#define GfSCR_ATT_TEXTURECOMPRESSION_ENABLED "enabled"
#define GfSCR_ATT_TEXTURECOMPRESSION_DISABLED "disabled"
#define GFSCR_ATT_TEXTURECOMPRESSION "texture compression"
#define GFSCR_ATT_TEXTURECOMPRESSION_ENABLED "enabled"
#define GFSCR_ATT_TEXTURECOMPRESSION_DISABLED "disabled"
#define GfSCR_ATT_MAXTEXTURESIZE "max texture size"
#define GFSCR_ATT_MAXTEXTURESIZE "max texture size"
#define GfSCR_ATT_MULTITEXTURING "multi-texturing"
#define GfSCR_ATT_MULTITEXTURING_ENABLED "enabled"
#define GfSCR_ATT_MULTITEXTURING_DISABLED "disabled"
#define GFSCR_ATT_MULTITEXTURING "multi-texturing"
#define GFSCR_ATT_MULTITEXTURING_ENABLED "enabled"
#define GFSCR_ATT_MULTITEXTURING_DISABLED "disabled"
#define GfSCR_ATT_MULTISAMPLING "multi-sampling"
#define GfSCR_ATT_MULTISAMPLING_ENABLED "enabled"
#define GfSCR_ATT_MULTISAMPLING_DISABLED "disabled"
#define GFSCR_ATT_MULTISAMPLING "multi-sampling"
#define GFSCR_ATT_MULTISAMPLING_ENABLED "enabled"
#define GFSCR_ATT_MULTISAMPLING_DISABLED "disabled"
#define GfSCR_ATT_MULTISAMPLING_SAMPLES "multi-sampling samples"
#define GFSCR_ATT_MULTISAMPLINGSAMPLES "multi-sampling samples"
SDL_Surface* gfScrGetScreenSurface();
// Open GL auto-detected features
#define GFSCR_SECT_GLDETFEATURES "OpenGL Detected Features"
#define GFSCR_ATT_DOUBLEBUFFER "double buffer"
#define GFSCR_ATT_COLORDEPTH "color depth"
#define GFSCR_ATT_ALPHADEPTH "alpha depth"
#define GFSCR_ATT_RECTANGLETEXTURES "rectangle textures"
#define GFSCR_ATT_NONPOTTEXTURES "non-pot textures"
#define GFSCR_ATT_MULTITEXTURINGUNITS "multi-texturing units"
// Open GL detection specs
#define GFSCR_SECT_GLDETSPECS "OpenGL Detection Specs"
#endif /* _GUISCREEN_H_ */

View file

@ -16,13 +16,14 @@
<!DOCTYPE params SYSTEM "../tgf/params.dtd">
<params name="Screen" version="1.2">
<params name="Screen" version="1.3">
<section name="Screen Properties">
<attnum name="window width" val="800"/>
<attnum name="window height" val="600"/>
<attnum name="bpp" val="24"/>
<attstr name="fullscreen" in="yes,no" val="no"/>
<attnum name="bpp" val="32"/>
<attstr name="full-screen" in="yes,no" val="no"/>
<attstr name="alpha channel" in="yes,no" val="yes"/>
<attnum name="gamma" val="2"/>
<attstr name="video mode detect" in="auto,manual" val="auto"/>
<attstr name="video mode init" in="compatible,best" val="best"/>
@ -238,11 +239,12 @@
</section>
<section name="OpenGL Features">
<section name="OpenGL Selected Features">
<attstr name="texture compression" val="enabled"/>
<attnum name="max texture size" val="8192"/>
<attstr name="multi-texturing" val="enabled"/>
<attstr name="multi-sampling" val="enabled"/>
<attstr name="multi-sampling samples" val="8"/>
</section>
</params>

View file

@ -115,13 +115,11 @@ void DisplayMenu::onAccept(void *pDisplayMenu)
// Save display settings.
pMenu->storeSettings();
// TODO: Simply call GfuiApp().restart() (when it is implemented ;-).
// Shutdown the user interface.
LegacyMenu::self().shutdown();
// Restart the game.
GfRestart(GfuiMouseIsHWPresent());
GfuiApp().restart();
// TODO: A nice system to get back to previous display settings if the chosen ones
// keep the game from really restarting (ex: unsupported full screen size) ?
@ -238,8 +236,8 @@ void DisplayMenu::storeSettings() const
// Deselect anti-aliasing from the Open GL settings if 'compatible' mode
// selected for the video initialization (anti-aliasing not supported in this mode).
if (_eVideoInitMode == eCompatible)
GfParmSetStr(hScrConfParams, GfSCR_SECT_GLFEATURES, GfSCR_ATT_MULTISAMPLING,
GfSCR_ATT_MULTISAMPLING_DISABLED);
GfParmSetStr(hScrConfParams, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_MULTISAMPLING,
GFSCR_ATT_MULTISAMPLING_DISABLED);
// Write and release screen config params file.
GfParmWriteFile(NULL, hScrConfParams, "Screen");

View file

@ -39,7 +39,7 @@
// Texture compression.
static const char *ATextureCompTexts[] =
{GfSCR_ATT_TEXTURECOMPRESSION_DISABLED, GfSCR_ATT_TEXTURECOMPRESSION_ENABLED};
{GFSCR_ATT_TEXTURECOMPRESSION_DISABLED, GFSCR_ATT_TEXTURECOMPRESSION_ENABLED};
static const int NTextureComps =
sizeof(ATextureCompTexts) / sizeof(ATextureCompTexts[0]);
static int NCurTextureCompIndex = 0;
@ -57,7 +57,7 @@ static const int NDefaultTextureSize = 64; // In case everything goes wrong.
// Multi-texturing.
static const char *AMultiTextureTexts[] =
{GfSCR_ATT_MULTITEXTURING_DISABLED, GfSCR_ATT_MULTITEXTURING_ENABLED};
{GFSCR_ATT_MULTITEXTURING_DISABLED, GFSCR_ATT_MULTITEXTURING_ENABLED};
static const int NMultiTextures =
sizeof(AMultiTextureTexts) / sizeof(AMultiTextureTexts[0]);
static int NCurMultiTextureIndex = 0;
@ -87,16 +87,16 @@ static void onAccept(void *)
// Store current state of settings to the GL features layer.
GfglFeatures::self().select(GfglFeatures::TextureCompression,
strcmp(ATextureCompTexts[NCurTextureCompIndex],
GfSCR_ATT_TEXTURECOMPRESSION_ENABLED) ? false : true);
GFSCR_ATT_TEXTURECOMPRESSION_ENABLED) ? false : true);
GfglFeatures::self().select(GfglFeatures::TextureMaxSize,
AMaxTextureSizeTexts[NCurMaxTextureSizeIndex]);
GfglFeatures::self().select(GfglFeatures::MultiTexturing,
strcmp(AMultiTextureTexts[NCurMultiTextureIndex],
GfSCR_ATT_MULTITEXTURING_ENABLED) ? false : true);
GFSCR_ATT_MULTITEXTURING_ENABLED) ? false : true);
GfglFeatures::self().select(GfglFeatures::MultiSampling,
VecMultiSampleTexts[NCurMultiSampleIndex]
!= GfSCR_ATT_MULTISAMPLING_DISABLED);
if (VecMultiSampleTexts[NCurMultiSampleIndex] != GfSCR_ATT_MULTISAMPLING_DISABLED)
!= GFSCR_ATT_MULTISAMPLING_DISABLED);
if (VecMultiSampleTexts[NCurMultiSampleIndex] != GFSCR_ATT_MULTISAMPLING_DISABLED)
GfglFeatures::self().select(GfglFeatures::MultiSamplingSamples,
(int)pow(2.0, (double)NCurMultiSampleIndex));
@ -111,14 +111,12 @@ static void onAccept(void *)
if (GfglFeatures::self().isSelected(GfglFeatures::MultiSampling) != BMultiSamplingWasSelected
|| GfglFeatures::self().getSelected(GfglFeatures::MultiSamplingSamples) != BPrevMultiSamplingSamples)
{
// TODO: Simply call GfuiApp().restart() (when it is implemented ;-).
// Shutdown the user interface.
LegacyMenu::self().shutdown();
// Restart the game.
GfRestart(GfuiMouseIsHWPresent());
GfuiApp().restart();
// TODO: A nice system to get back to previous display settings if the chosen ones
// keep the game from really restarting (ex: unsupported full screen size) ?
}
@ -178,7 +176,7 @@ static void onActivate(void * /* dummy */)
{
const char *pszTexComp =
GfglFeatures::self().isSelected(GfglFeatures::TextureCompression)
? GfSCR_ATT_TEXTURECOMPRESSION_ENABLED : GfSCR_ATT_TEXTURECOMPRESSION_DISABLED;
? GFSCR_ATT_TEXTURECOMPRESSION_ENABLED : GFSCR_ATT_TEXTURECOMPRESSION_DISABLED;
for (i = 0; i < NTextureComps; i++)
{
if (!strcmp(pszTexComp, ATextureCompTexts[i]))
@ -251,7 +249,7 @@ static void onActivate(void * /* dummy */)
{
const char *pszMultiTex =
GfglFeatures::self().isSelected(GfglFeatures::MultiTexturing)
? GfSCR_ATT_MULTITEXTURING_ENABLED : GfSCR_ATT_MULTITEXTURING_DISABLED;
? GFSCR_ATT_MULTITEXTURING_ENABLED : GFSCR_ATT_MULTITEXTURING_DISABLED;
for (i = 0; i < NMultiTextures; i++)
{
if (!strcmp(pszMultiTex, AMultiTextureTexts[i]))
@ -365,7 +363,7 @@ void* OpenGLMenuInit(void *prevMenu)
// Initialize multi-sampling levels.
NMultiSamples = 1;
VecMultiSampleTexts.push_back(GfSCR_ATT_MULTISAMPLING_DISABLED);
VecMultiSampleTexts.push_back(GFSCR_ATT_MULTISAMPLING_DISABLED);
if (GfglFeatures::self().isSupported(GfglFeatures::MultiSampling)
&& GfglFeatures::self().getSupported(GfglFeatures::MultiSamplingSamples) > 1)
{