SDL ghost update to work with SDL2.

this gives some problems because SDL2 Needs a window before fullscreen is set, the player currently doesnt have a window created when fullscreen is called.
This commit is contained in:
Campbell Barton
2012-03-13 20:24:05 +00:00
parent 01b3e9cc9f
commit 08f17b2a53

View File

@@ -32,6 +32,8 @@
#include "GHOST_SystemSDL.h" #include "GHOST_SystemSDL.h"
#include "GHOST_DisplayManagerSDL.h" #include "GHOST_DisplayManagerSDL.h"
#include "GHOST_WindowManager.h"
GHOST_DisplayManagerSDL::GHOST_DisplayManagerSDL(GHOST_SystemSDL *system) GHOST_DisplayManagerSDL::GHOST_DisplayManagerSDL(GHOST_SystemSDL *system)
: :
GHOST_DisplayManager(), GHOST_DisplayManager(),
@@ -52,22 +54,29 @@ GHOST_TSuccess GHOST_DisplayManagerSDL::getNumDisplaySettings(GHOST_TUns8 displa
GHOST_TInt32& numSettings) const GHOST_TInt32& numSettings) const
{ {
GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
int i;
SDL_Rect **vidmodes;
vidmodes = SDL_ListModes(NULL, SDL_HWSURFACE | SDL_OPENGL | numSettings = SDL_GetNumDisplayModes(display - 1);
SDL_FULLSCREEN | SDL_HWPALETTE);
if (!vidmodes) {
fprintf(stderr, "Could not get available video modes: %s.\n",
SDL_GetError());
return GHOST_kFailure;
}
for (i = 0; vidmodes[i]; i++);
numSettings = GHOST_TInt32(i);
return GHOST_kSuccess; return GHOST_kSuccess;
} }
static void ghost_mode_from_sdl(GHOST_DisplaySetting& setting, SDL_DisplayMode *mode)
{
setting.xPixels = mode->w;
setting.yPixels = mode->h;
setting.bpp = SDL_BYTESPERPIXEL(mode->format) * 8;
/* Just guess the frequency :( */
setting.frequency = mode->refresh_rate ? mode->refresh_rate : 60;
}
static void ghost_mode_to_sdl(const GHOST_DisplaySetting& setting, SDL_DisplayMode *mode)
{
mode->w = setting.xPixels;
mode->h = setting.yPixels;
// setting.bpp = SDL_BYTESPERPIXEL(mode->format) * 8; ???
mode->refresh_rate = setting.frequency;
}
GHOST_TSuccess GHOST_TSuccess
GHOST_DisplayManagerSDL::getDisplaySetting(GHOST_TUns8 display, GHOST_DisplayManagerSDL::getDisplaySetting(GHOST_TUns8 display,
GHOST_TInt32 index, GHOST_TInt32 index,
@@ -75,36 +84,10 @@ GHOST_DisplayManagerSDL::getDisplaySetting(GHOST_TUns8 display,
{ {
GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
int i; SDL_DisplayMode mode;
SDL_Rect **vidmodes; SDL_GetDisplayMode(display, index, &mode);
/* NULL is passed in here to get the modes for the current bit depth.
* Other bit depths may be possible; in that case, an SDL_PixelFormat struct
* should be passed in. To get a complete profile, all possible bit depths
* would need to be iterated over. - z0r */
vidmodes = SDL_ListModes(NULL, SDL_HWSURFACE | SDL_OPENGL |
SDL_FULLSCREEN | SDL_HWPALETTE);
if (!vidmodes) {
fprintf(stderr, "Could not get available video modes: %s.\n",
SDL_GetError());
return GHOST_kFailure;
}
for (i = 0; vidmodes[i]; i++);
GHOST_ASSERT(index < i, "Requested setting outside of valid range.\n");
setting.xPixels = vidmodes[index]->w; ghost_mode_from_sdl(setting, &mode);
setting.yPixels = vidmodes[index]->h;
SDL_Surface *surf;
surf = SDL_GetVideoSurface();
if (surf == NULL) {
fprintf(stderr, "Getting display setting: %s\n", SDL_GetError());
/* Just guess the bit depth */
setting.bpp = 32;
} else {
setting.bpp = surf->format->BitsPerPixel;
}
/* Just guess the frequency :( */
setting.frequency = 60;
return GHOST_kSuccess; return GHOST_kSuccess;
} }
@@ -113,30 +96,10 @@ GHOST_TSuccess
GHOST_DisplayManagerSDL::getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplayManagerSDL::getCurrentDisplaySetting(GHOST_TUns8 display,
GHOST_DisplaySetting& setting) const GHOST_DisplaySetting& setting) const
{ {
SDL_Surface *surf; SDL_DisplayMode mode;
const SDL_VideoInfo *info; SDL_GetCurrentDisplayMode(display, &mode);
/* Note: not using SDL_GetDesktopDisplayMode because that does not return ghost_mode_from_sdl(setting, &mode);
* the current mode. Try to use GetVideoSurface first, as it seems more
* accurate. If that fails, try other methods. - z0r */
surf = SDL_GetVideoSurface();
if (surf != NULL) {
setting.xPixels = surf->w;
setting.yPixels = surf->h;
setting.bpp = surf->format->BitsPerPixel;
/* Just guess the frequency :( */
setting.frequency = 60;
} else {
/* This may happen if the surface hasn't been created yet, e.g. on
* application startup. */
info = SDL_GetVideoInfo();
setting.xPixels = info->current_w;
setting.yPixels = info->current_h;
setting.bpp = info->vfmt->BitsPerPixel;
/* Just guess the frequency :( */
setting.frequency = 60;
}
return GHOST_kSuccess; return GHOST_kSuccess;
} }
@@ -145,7 +108,6 @@ GHOST_TSuccess
GHOST_DisplayManagerSDL:: setCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplayManagerSDL:: setCurrentDisplaySetting(GHOST_TUns8 display,
const GHOST_DisplaySetting& setting) const GHOST_DisplaySetting& setting)
{ {
/* /*
* Mode switching code ported from Quake 2 version 3.21 and bzflag version * Mode switching code ported from Quake 2 version 3.21 and bzflag version
* 2.4.0: * 2.4.0:
@@ -154,31 +116,28 @@ GHOST_DisplayManagerSDL:: setCurrentDisplaySetting(GHOST_TUns8 display,
* http://wiki.bzflag.org/BZFlag_Source * http://wiki.bzflag.org/BZFlag_Source
* See src/platform/SDLDisplay.cxx:SDLDisplay and createWindow * See src/platform/SDLDisplay.cxx:SDLDisplay and createWindow
*/ */
SDL_Surface *surf; SDL_DisplayMode mode;
const int num_modes = SDL_GetNumDisplayModes(display);
int best_fit, best_dist, dist, x, y; int best_fit, best_dist, dist, x, y;
SDL_Rect **vidmodes = SDL_ListModes(NULL, SDL_HWSURFACE | SDL_OPENGL |
SDL_FULLSCREEN | SDL_HWPALETTE);
if (!vidmodes) {
fprintf(stderr, "Could not get available video modes: %s.\n",
SDL_GetError());
}
best_dist = 9999999; best_dist = 9999999;
best_fit = -1; best_fit = -1;
if (vidmodes == (SDL_Rect **) -1) { if (num_modes == 0) {
/* Any mode is OK. */ /* Any mode is OK. */
x = setting.xPixels; ghost_mode_to_sdl(setting, &mode);
y = setting.yPixels; }
} else { else {
for (int i = 0; vidmodes[i]; i++) { for (int i = 0; i < num_modes; i++) {
if (setting.xPixels > vidmodes[i]->w ||
setting.yPixels > vidmodes[i]->h) SDL_GetDisplayMode(display, i, &mode);
if (setting.xPixels > mode.w ||
setting.yPixels > mode.h)
continue; continue;
x = setting.xPixels - vidmodes[i]->w; x = setting.xPixels - mode.w;
y = setting.yPixels - vidmodes[i]->h; y = setting.yPixels - mode.h;
dist = (x * x) + (y * y); dist = (x * x) + (y * y);
if (dist < best_dist) { if (dist < best_dist) {
best_dist = dist; best_dist = dist;
@@ -189,24 +148,26 @@ GHOST_DisplayManagerSDL:: setCurrentDisplaySetting(GHOST_TUns8 display,
if (best_fit == -1) if (best_fit == -1)
return GHOST_kFailure; return GHOST_kFailure;
x = vidmodes[best_fit]->w; SDL_GetDisplayMode(display, best_fit, &mode);
y = vidmodes[best_fit]->h;
} }
# ifdef _DEBUG /* evil, SDL2 needs a window to adjust display modes */
printf("Switching to video mode %dx%d\n", x, y); GHOST_WindowSDL *win = (GHOST_WindowSDL *)m_system->getWindowManager()->getActiveWindow();
# endif
// limit us to the main display if (win) {
static char singleDisplayEnv[] = "SDL_SINGLEDISPLAY=1"; SDL_Window *sdl_win = win->getSDLWindow();
putenv(singleDisplayEnv);
// change to the mode
surf = SDL_SetVideoMode(x, y, setting.bpp, SDL_OPENGL | SDL_FULLSCREEN); SDL_SetWindowDisplayMode(sdl_win, &mode);
if (surf == NULL) { SDL_ShowWindow(sdl_win);
fprintf(stderr, "Could not set video mode: %s.\n", SDL_GetError()); SDL_SetWindowFullscreen(sdl_win, SDL_TRUE);
return GHOST_kSuccess;
}
else {
/* this is a problem for the BGE player :S, perhaps SDL2 will resolve at some point.
* we really need SDL_SetDisplayModeForDisplay() to become an API func! - campbell */
printf("no windows available, cant fullscreen");
return GHOST_kFailure; return GHOST_kFailure;
} }
return GHOST_kSuccess;
} }