1// SuperTux
2// Copyright (C) 2018 Ingo Ruhnke <grumbel@gmail.com>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17#include "video/sdlbase_video_system.hpp"
18
19#include "supertux/gameconfig.hpp"
20#include "supertux/globals.hpp"
21#include "util/log.hpp"
22
23SDLBaseVideoSystem::SDLBaseVideoSystem() :
24 m_sdl_window(nullptr, &SDL_DestroyWindow),
25 m_desktop_size()
26{
27 SDL_DisplayMode mode;
28 if (SDL_GetDesktopDisplayMode(0, &mode) != 0)
29 {
30 log_warning << "Couldn't get desktop display mode: " << SDL_GetError() << std::endl;
31 }
32 else
33 {
34 m_desktop_size = Size(mode.w, mode.h);
35 }
36}
37
38SDLBaseVideoSystem::~SDLBaseVideoSystem()
39{
40}
41
42void
43SDLBaseVideoSystem::set_title(const std::string& title)
44{
45 SDL_SetWindowTitle(m_sdl_window.get(), title.c_str());
46}
47
48void
49SDLBaseVideoSystem::set_gamma(float gamma)
50{
51 Uint16 ramp[256];
52 SDL_CalculateGammaRamp(gamma, ramp);
53 SDL_SetWindowGammaRamp(m_sdl_window.get(), ramp, ramp, ramp);
54}
55
56void
57SDLBaseVideoSystem::set_icon(const SDL_Surface& icon)
58{
59 SDL_SetWindowIcon(m_sdl_window.get(), const_cast<SDL_Surface*>(&icon));
60}
61
62Size
63SDLBaseVideoSystem::get_window_size() const
64{
65 Size size;
66 SDL_GetWindowSize(m_sdl_window.get(), &size.width, &size.height);
67 return size;
68}
69
70void
71SDLBaseVideoSystem::on_resize(int w, int h)
72{
73 g_config->window_size = Size(w, h);
74 apply_config();
75}
76
77void
78SDLBaseVideoSystem::create_sdl_window(Uint32 flags)
79{
80 flags |= SDL_WINDOW_RESIZABLE;
81
82 Size size;
83 if (g_config->use_fullscreen)
84 {
85 if (g_config->fullscreen_size == Size(0, 0))
86 {
87 flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
88 size = m_desktop_size;
89 }
90 else
91 {
92 flags |= SDL_WINDOW_FULLSCREEN;
93 size.width = g_config->fullscreen_size.width;
94 size.height = g_config->fullscreen_size.height;
95 }
96 }
97 else
98 {
99 size = g_config->window_size;
100 }
101
102 m_sdl_window.reset(SDL_CreateWindow("SuperTux",
103 SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
104 size.width, size.height,
105 flags));
106 if (!m_sdl_window)
107 {
108 std::ostringstream msg;
109 msg << "Couldn't set video mode " << size.width << "x" << size.height << ": " << SDL_GetError();
110 throw std::runtime_error(msg.str());
111 }
112}
113
114void
115SDLBaseVideoSystem::apply_video_mode()
116{
117 if (!g_config->use_fullscreen)
118 {
119 SDL_SetWindowFullscreen(m_sdl_window.get(), 0);
120
121 Size window_size;
122 SDL_GetWindowSize(m_sdl_window.get(), &window_size.width, &window_size.height);
123 if (g_config->window_size.width != window_size.width ||
124 g_config->window_size.height != window_size.height)
125 {
126 SDL_SetWindowSize(m_sdl_window.get(), g_config->window_size.width, g_config->window_size.height);
127 }
128
129#if SDL_VERSION_ATLEAST(2,0,5)
130 SDL_SetWindowResizable(m_sdl_window.get(), static_cast<SDL_bool>(g_config->window_resizable));
131#endif
132 }
133 else
134 {
135 if (g_config->fullscreen_size.width == 0 &&
136 g_config->fullscreen_size.height == 0)
137 {
138 if (SDL_SetWindowFullscreen(m_sdl_window.get(), SDL_WINDOW_FULLSCREEN_DESKTOP) != 0)
139 {
140 log_warning << "failed to switch to desktop fullscreen mode: "
141 << SDL_GetError() << std::endl;
142 }
143 else
144 {
145 log_info << "switched to desktop fullscreen mode" << std::endl;
146 }
147 }
148 else
149 {
150 SDL_DisplayMode mode;
151 mode.format = SDL_PIXELFORMAT_RGB888;
152 mode.w = g_config->fullscreen_size.width;
153 mode.h = g_config->fullscreen_size.height;
154 mode.refresh_rate = g_config->fullscreen_refresh_rate;
155 mode.driverdata = nullptr;
156
157 if (SDL_SetWindowDisplayMode(m_sdl_window.get(), &mode) != 0)
158 {
159 log_warning << "failed to set display mode: "
160 << mode.w << "x" << mode.h << "@" << mode.refresh_rate << ": "
161 << SDL_GetError() << std::endl;
162 }
163 else
164 {
165 if (SDL_SetWindowFullscreen(m_sdl_window.get(), SDL_WINDOW_FULLSCREEN) != 0)
166 {
167 log_warning << "failed to switch to fullscreen mode: "
168 << mode.w << "x" << mode.h << "@" << mode.refresh_rate << ": "
169 << SDL_GetError() << std::endl;
170 }
171 else
172 {
173 log_info << "switched to fullscreen mode: "
174 << mode.w << "x" << mode.h << "@" << mode.refresh_rate << std::endl;
175 }
176 }
177 }
178 }
179}
180
181/* EOF */
182