152 lines
4.2 KiB
C++
152 lines
4.2 KiB
C++
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
* Mode switching
|
|
* Copyright 1997-2001 Id Software, Inc.
|
|
* Copyright 1993-2011 Tim Riker
|
|
* Copyright 2012 Alex Fraser */
|
|
|
|
/** \file
|
|
* \ingroup GHOST
|
|
*/
|
|
|
|
#include "GHOST_DisplayManagerSDL.h"
|
|
#include "GHOST_SystemSDL.h"
|
|
|
|
#include "GHOST_WindowManager.h"
|
|
|
|
GHOST_DisplayManagerSDL::GHOST_DisplayManagerSDL(GHOST_SystemSDL *system)
|
|
: GHOST_DisplayManager(), m_system(system)
|
|
{
|
|
memset(&m_mode, 0, sizeof(m_mode));
|
|
}
|
|
|
|
GHOST_TSuccess GHOST_DisplayManagerSDL::getNumDisplays(uint8_t &numDisplays) const
|
|
{
|
|
numDisplays = SDL_GetNumVideoDisplays();
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
GHOST_TSuccess GHOST_DisplayManagerSDL::getNumDisplaySettings(uint8_t display,
|
|
int32_t &numSettings) const
|
|
{
|
|
GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
|
|
|
|
numSettings = SDL_GetNumDisplayModes(display - 1);
|
|
|
|
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_DisplayManagerSDL::getDisplaySetting(uint8_t display,
|
|
int32_t index,
|
|
GHOST_DisplaySetting &setting) const
|
|
{
|
|
GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
|
|
|
|
SDL_DisplayMode mode;
|
|
SDL_GetDisplayMode(display, index, &mode);
|
|
|
|
ghost_mode_from_sdl(setting, &mode);
|
|
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
GHOST_TSuccess GHOST_DisplayManagerSDL::getCurrentDisplaySetting(
|
|
uint8_t display, GHOST_DisplaySetting &setting) const
|
|
{
|
|
SDL_DisplayMode mode;
|
|
SDL_GetCurrentDisplayMode(display, &mode);
|
|
|
|
ghost_mode_from_sdl(setting, &mode);
|
|
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
GHOST_TSuccess GHOST_DisplayManagerSDL::getCurrentDisplayModeSDL(SDL_DisplayMode &mode) const
|
|
{
|
|
mode = m_mode;
|
|
return GHOST_kSuccess;
|
|
}
|
|
|
|
GHOST_TSuccess GHOST_DisplayManagerSDL::setCurrentDisplaySetting(
|
|
uint8_t display, const GHOST_DisplaySetting &setting)
|
|
{
|
|
/*
|
|
* Mode switching code ported from Quake 2 version 3.21 and BZFLAG version 2.4.0:
|
|
* ftp://ftp.idsoftware.com/idstuff/source/q2source-3.21.zip
|
|
* See linux/gl_glx.c:GLimp_SetMode
|
|
* http://wiki.bzflag.org/BZFlag_Source
|
|
* See: `src/platform/SDLDisplay.cxx:SDLDisplay` and `createWindow`.
|
|
*/
|
|
SDL_DisplayMode mode;
|
|
const int num_modes = SDL_GetNumDisplayModes(display);
|
|
int best_fit, best_dist, dist, x, y;
|
|
|
|
best_dist = 9999999;
|
|
best_fit = -1;
|
|
|
|
if (num_modes == 0) {
|
|
/* Any mode is OK. */
|
|
ghost_mode_to_sdl(setting, &mode);
|
|
}
|
|
else {
|
|
for (int i = 0; i < num_modes; i++) {
|
|
|
|
SDL_GetDisplayMode(display, i, &mode);
|
|
|
|
if ((int)setting.xPixels > mode.w || (int)setting.yPixels > mode.h) {
|
|
continue;
|
|
}
|
|
|
|
x = setting.xPixels - mode.w;
|
|
y = setting.yPixels - mode.h;
|
|
dist = (x * x) + (y * y);
|
|
if (dist < best_dist) {
|
|
best_dist = dist;
|
|
best_fit = i;
|
|
}
|
|
}
|
|
|
|
if (best_fit == -1) {
|
|
return GHOST_kFailure;
|
|
}
|
|
SDL_GetDisplayMode(display, best_fit, &mode);
|
|
}
|
|
|
|
m_mode = mode;
|
|
|
|
/* evil, SDL2 needs a window to adjust display modes */
|
|
GHOST_WindowSDL *win = (GHOST_WindowSDL *)m_system->getWindowManager()->getActiveWindow();
|
|
|
|
if (win) {
|
|
SDL_Window *sdl_win = win->getSDLWindow();
|
|
|
|
SDL_SetWindowDisplayMode(sdl_win, &mode);
|
|
SDL_ShowWindow(sdl_win);
|
|
SDL_SetWindowFullscreen(sdl_win, SDL_TRUE);
|
|
|
|
return GHOST_kSuccess;
|
|
}
|
|
/* 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, can't fullscreen\n");
|
|
|
|
/* do not fail, we will try again later when the window is created - wander */
|
|
return GHOST_kSuccess;
|
|
}
|