More progress on refactoring window handling under SDL2

General changes in this commit:
* Split window initialization out of setMode and into its own function
* Remove local flags for window state and instead get them directly from the
  window itself.
* Improve handling of distinct window change cases in setMode.
* Refactored and cleaned up several functions.
This commit is contained in:
Charles Dang 2016-01-03 04:55:41 +11:00
parent d920cf9bd1
commit 3c5e6cbdb6
3 changed files with 133 additions and 92 deletions

View file

@ -245,11 +245,7 @@ game_launcher::game_launcher(const commandline_options& cmdline_opts, const char
const int xres = cmdline_opts_.resolution->get<0>();
const int yres = cmdline_opts_.resolution->get<1>();
if(xres > 0 && yres > 0) {
const std::pair<int,int> resolution(xres,yres);
video_.set_resolution(resolution);
// Override previously saved maximized state
preferences::_set_maximized(false);
video_.set_resolution(xres, yres);
}
}
if (cmdline_opts_.screenshot) {
@ -393,24 +389,8 @@ bool game_launcher::init_video()
return true;
}
// Create window with any saved settings
std::pair<int,int> resolution = preferences::resolution();
int video_flags = 0;
video_flags = preferences::fullscreen() ? SDL_FULLSCREEN : 0;
video_flags |= preferences::maximized() ? SDL_WINDOW_MAXIMIZED : 0;
int bpp = CVideo::DefaultBpp;
std::cerr << "Setting mode to " << resolution.first << "x" << resolution.second << "x" << bpp << "\n";
// Set window state
const int res = video_.setMode(resolution.first, resolution.second, bpp, video_flags);
if(res == 0) {
std::cerr << "Required video mode, " << resolution.first << "x"
<< resolution.second << "x" << bpp << " is not supported\n";
return false;
}
// Initialize a new window
video_.init_window();
// Set window title and icon
std::string wm_title_string = _("The Battle for Wesnoth");

View file

@ -37,16 +37,15 @@
#include <map>
#include <algorithm>
#include <assert.h>
static lg::log_domain log_display("display");
#define LOG_DP LOG_STREAM(info, log_display)
#define ERR_DP LOG_STREAM(err, log_display)
namespace {
bool is_fullscreen = false;
#if SDL_VERSION_ATLEAST(2, 0, 0)
bool is_maximized = false;
#endif
#if !SDL_VERSION_ATLEAST(2, 0, 0)
bool is_fullscreen = false;
int disallow_resize = 0;
#endif
#ifdef SDL_GPU
@ -70,7 +69,7 @@ void resize_monitor::process(events::pump_info &info) {
resize_lock::resize_lock()
{
#if !SDL_VERSION_ATLEAST(2, 0, 0)
++disallow_resize;
#endif
@ -593,44 +592,83 @@ void update_framebuffer()
frameBuffer.assign(fb);
}
int CVideo::setMode( int x, int y, int bits_per_pixel, int flags )
/**
* Creates a new window instance.
*/
bool CVideo::init_window()
{
// Position
const int x = preferences::fullscreen() ? SDL_WINDOWPOS_UNDEFINED : SDL_WINDOWPOS_CENTERED;
const int y = preferences::fullscreen() ? SDL_WINDOWPOS_UNDEFINED : SDL_WINDOWPOS_CENTERED;
// Dimensions
const int w = preferences::resolution().first;
const int h = preferences::resolution().second;
// Video flags
int video_flags = 0;
video_flags = get_flags(video_flags);
if (preferences::fullscreen()) {
video_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
} else if (preferences::maximized()) {
video_flags |= SDL_WINDOW_MAXIMIZED;
}
// Initialize window
window = new sdl::twindow("", x, y, w, h, video_flags, SDL_RENDERER_SOFTWARE);
std::cerr << "Setting mode to " << w << "x" << h << std::endl;
window->set_minimum_size(
preferences::min_allowed_width(),
preferences::min_allowed_height()
);
event_handler_.join_global();
update_framebuffer();
if(frameBuffer) {
image::set_pixel_format(frameBuffer->format);
}
return true;
}
void CVideo::setMode(int x, int y, const MODE_EVENT mode)
{
assert(window);
update_rects.clear();
if (fake_screen_) return 0;
if (fake_screen_) return;
mode_changed_ = true;
flags = get_flags(flags);
if (!window) {
// SDL_WINDOWPOS_UNDEFINED allows SDL to centre the window in the display instead of using a fixed initial position.
// Note that x and y in this particular case refer to width and height of the window, not co-ordinates.
window = new sdl::twindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, x, y, flags, SDL_RENDERER_SOFTWARE);
window->set_minimum_size(preferences::min_allowed_width(), preferences::min_allowed_height());
event_handler_.join_global();
} else {
int window_flags = window->get_flags();
is_fullscreen = (window_flags & SDL_FULLSCREEN ) != 0;
is_maximized = (window_flags & SDL_WINDOW_MAXIMIZED) != 0;
window->set_size(x, y);
if (is_fullscreen) {
switch(mode) {
case TO_FULLSCREEN:
window->full_screen();
} else if (is_maximized) {
break;
case TO_WINDOWED:
window->to_window();
window->restore();
break;
case TO_MAXIMIZED_WINDOW:
window->to_window();
window->maximize();
} else {
break;
case TO_RES:
window->restore();
window->set_size(x, y);
window->center();
}
break;
}
update_framebuffer();
if(frameBuffer != NULL) {
if(frameBuffer) {
image::set_pixel_format(frameBuffer->format);
return bits_per_pixel;
} else {
return 0;
}
}
#else
@ -893,7 +931,13 @@ std::pair<int,int> CVideo::current_resolution()
return std::make_pair(getSurface()->w, getSurface()->h);
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
bool CVideo::isFullScreen() const {
return (window->get_flags() & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0;
}
#else
bool CVideo::isFullScreen() const { return is_fullscreen; }
#endif
#if !SDL_VERSION_ATLEAST(2, 0, 0)
void CVideo::setBpp( int bpp )
@ -1001,64 +1045,62 @@ bool CVideo::detect_video_settings(std::pair<int,int>& resolution, int& bpp, int
void CVideo::set_fullscreen(bool ison)
{
// Change the config value.
preferences::_set_fullscreen(ison);
if (display::get_singleton() && isFullScreen() != ison) {
const int flags = ison ? SDL_FULLSCREEN : 0;
const std::pair<int,int>& res = preferences::resolution();
#if SDL_VERSION_ATLEAST(2, 0, 0)
int bpp = DefaultBpp;
MODE_EVENT mode;
if (ison) {
mode = TO_FULLSCREEN;
} else {
mode = preferences::maximized() ? TO_MAXIMIZED_WINDOW : TO_WINDOWED;
}
setMode(res.first, res.second, mode);
#else
const int flags = ison ? SDL_FULLSCREEN : 0;
int bpp = bppForMode(res.first, res.second, flags);
#endif
setMode(res.first, res.second, bpp, flags);
#endif
display::get_singleton()->redraw_everything();
}
// Change the config value.
preferences::_set_fullscreen(ison);
}
void CVideo::set_resolution(const std::pair<int,int>& resolution)
{
if(display::get_singleton()) {
set_resolution(resolution.first, resolution.second);
} else {
// Only change the config value. This part is needed when wesnoth is
// started with the -r parameter.
preferences::_set_resolution(resolution);
}
set_resolution(resolution.first, resolution.second);
}
bool CVideo::set_resolution(const unsigned width, const unsigned height)
void CVideo::set_resolution(const unsigned width, const unsigned height)
{
SDL_Rect rect;
SDL_GetClipRect(getSurface(), &rect);
if(static_cast<unsigned int> (rect.w) == width && static_cast<unsigned int>(rect.h) == height) {
return true;
}
if(display::get_singleton()) {
if (static_cast<unsigned int> (current_resolution().first) == width &&
static_cast<unsigned int> (current_resolution().second) == height) {
return;
}
const int flags = preferences::fullscreen() ? SDL_FULLSCREEN : 0;
#if SDL_VERSION_ATLEAST(2, 0, 0)
int bpp = DefaultBpp;
setMode(width, height, TO_RES);
#else
int bpp = bppForMode(width, height, flags);
#endif
const int flags = preferences::fullscreen() ? SDL_FULLSCREEN : 0;
int bpp = bppForMode(width, height, flags);
if(bpp != 0) {
setMode(width, height, bpp, flags);
#if !SDL_VERSION_ATLEAST(2, 0, 0)
if(display::get_singleton()) {
display::get_singleton()->redraw_everything();
if(bpp != 0) {
setMode(width, height, bpp, flags);
}
#endif
display::get_singleton()->redraw_everything();
}
// Change the config values.
preferences::_set_resolution(std::make_pair(width, height));
preferences::_set_maximized(false);
return true;
}

View file

@ -66,12 +66,19 @@ void update_rect(const SDL_Rect& rect);
void update_whole_screen();
class CVideo : private boost::noncopyable {
public:
enum FAKE_TYPES {
NO_FAKE,
FAKE,
FAKE_TEST
};
public:
enum FAKE_TYPES {
NO_FAKE
, FAKE
, FAKE_TEST
};
enum MODE_EVENT {
TO_RES
, TO_FULLSCREEN
, TO_WINDOWED
, TO_MAXIMIZED_WINDOW
};
CVideo(FAKE_TYPES type = NO_FAKE);
~CVideo();
@ -82,8 +89,19 @@ class CVideo : private boost::noncopyable {
int bppForMode( int x, int y, int flags);
int modePossible( int x, int y, int bits_per_pixel, int flags, bool current_screen_optimal=false);
#endif
int setMode( int x, int y, int bits_per_pixel, int flags );
/**
* Initializes a new window, taking into account any preiously saved states.
*/
bool init_window();
#if SDL_VERSION_ATLEAST(2, 0, 0)
void setMode( int x, int y, const MODE_EVENT mode );
#else
int setMode( int x, int y, int bits_per_pixel, int flags );
#endif
#if !SDL_VERSION_ATLEAST(2, 0, 0)
/**
* Detect a good resolution.
*
@ -95,6 +113,7 @@ class CVideo : private boost::noncopyable {
* @returns Whether valid video settings were found.
*/
bool detect_video_settings(std::pair<int,int>& resolution, int& bpp, int& video_flags);
#endif
void set_fullscreen(bool ison);
@ -108,7 +127,7 @@ class CVideo : private boost::noncopyable {
* size of the framebuffer, false otherwise.
*/
void set_resolution(const std::pair<int,int>& res);
bool set_resolution(const unsigned width, const unsigned height);
void set_resolution(const unsigned width, const unsigned height);
std::pair<int,int> current_resolution();