The Battle for Wesnoth  1.19.5+dev
video.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2024
3  by David White <dave@whitevine.net>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
18 #include "exceptions.hpp"
20 #include "sdl/point.hpp"
21 #include "sdl/rect.hpp"
22 #include "sdl/texture.hpp"
23 
24 #include <SDL2/SDL_render.h>
25 
26 #include <vector>
27 
28 class surface;
29 
30 namespace video
31 {
32 
33 /******************/
34 /* Initialization */
35 /******************/
36 
37 /**
38  * For describing the type of faked display, if any.
39  *
40  * fake::no_window never tries to create a window, or draw anything.
41  * fake::no_draw does create an offscreen window, but does not draw to it.
42  * fake::hide_window creates a window as normal, but does not display it.
43  */
45 
46 /**
47  * Initialize the video subsystem.
48  *
49  * This must be called before attempting to use any video functions.
50  */
51 void init(fake fake_type = fake::none);
52 
53 /**
54  * Deinitialize the video subsystem.
55  *
56  * This flushes all texture caches and disconnects the SDL video subsystem.
57  */
58 void deinit();
59 
60 /**
61  * Update buffers to match current resolution and pixel scale settings.
62  *
63  * If @p autoupdate is true and buffers are changed by this call,
64  * a full redraw is also triggered.
65  *
66  * If nothing has changed, it will not generate any new buffers or queue
67  * the redraw.
68  */
69 void update_buffers(bool autoupdate = true);
70 
71 
72 /**********************************/
73 /* Unit-test and headless support */
74 /**********************************/
75 
76 /** The game is running headless. There is no window or renderer. */
77 bool headless();
78 
79 /** The game is running unit tests. There is a window and offscreen
80  * render buffer, but performing actual rendering is unnecessary. */
81 bool testing();
82 
83 
84 /***********************/
85 /* Windowing functions */
86 /***********************/
87 
88 /** Whether the game has set up a window to render into */
89 bool has_window();
90 
91 /** Whether we are currently in fullscreen mode */
92 bool is_fullscreen();
93 
94 /**
95  * Set the fullscreen state.
96  *
97  * If the setting matches the current fullscreen state, the window state
98  * will not be changed.
99  *
100  * If false and the window is fullscreen, the window will be restored to
101  * its last saved non-fullscreen configuration.
102  */
103 void set_fullscreen(bool);
104 
105 /**
106  * Toggle fullscreen mode.
107  *
108  * Equivalent to set_fullscreen(!is_fullscreen()).
109  */
110 void toggle_fullscreen();
111 
112 /**
113  * Set the window resolution.
114  *
115  * @todo this is no longer useful as fullscreen is always native resolution.
116  *
117  * @param resolution The new width and height.
118  *
119  * @returns Whether the resolution was successfully changed.
120  */
121 bool set_resolution(const point& resolution);
122 
123 /** The current window size in desktop coordinates. */
125 
126 /** Returns the list of available screen resolutions. */
127 std::vector<point> get_available_resolutions(bool include_current = false);
128 
129 /** The current video driver in use, or else "<not initialized>". */
130 std::string current_driver();
131 
132 /** A list of available video drivers. */
133 std::vector<std::string> enumerate_drivers();
134 
135 /**
136  * The refresh rate of the screen.
137  *
138  * In most cases, this will be the native refresh rate of the display, but
139  * could be lower if FPS has been artificially capped (i.e., through --max-fps).
140  *
141  * If a refresh cannot be detected, this may return 0, or it may return a
142  * substitute value.
143  */
145 
146 /** True iff the window is not hidden. */
147 bool window_is_visible();
148 /** True iff the window has mouse or input focus */
149 bool window_has_focus();
150 /** True iff the window has mouse focus */
152 
153 /** Sets the title of the main window. */
154 void set_window_title(const std::string& title);
155 
156 /** Sets the icon of the main window. */
157 void set_window_icon(surface& icon);
158 
159 
160 /**********************/
161 /* Coordinate Systems */
162 /**********************/
163 
164 /**
165  * The game canvas area, in drawing coordinates.
166  *
167  * This is the "screen area", as seen by game systems, and as used for
168  * specifying where to draw things on-screen. It may differ, in high-dpi
169  * contexts, from input area, window area, and output area.
170  *
171  * Usually this is the only area game components should use or care about.
172  *
173  * The units it uses can be considered "pixels". Final output will be
174  * rendered in higher resolution automatically if and when appropriate.
175  */
176 rect game_canvas();
177 
178 /** The size of the game canvas, in drawing coordinates / game pixels. */
180 
181 /**
182  * The size of the current render target in drawing coordinates.
183  *
184  * This will be the same as game_canvas_size() unless the render target
185  * has been manually changed.
186  */
187 point draw_size();
188 
189 /**
190  * The current drawable area.
191  *
192  * Equivalent to {0, 0, draw_size().x, draw_size().y}.
193  */
194 rect draw_area();
195 
196 /**
197  * Returns the size of the final render target. This is irrelevant
198  * for most purposes. Use game_canvas_size() in stead.
199  */
201 
202 /** {0, 0, output_size().x, output_size().y} */
203 rect output_area();
204 
205 /**
206  * Returns the size of the window in display units / screen coordinates.
207  * This should match the value sent by window resize events, and also
208  * those used for setting resolution.
209  */
211 
212 /**
213  * Returns the input area of the window, in display coordinates.
214  *
215  * This can be slightly offset within the window, if the drawable area
216  * is not the same as the full window area. This will happen if output
217  * size is not a perfect multiple of the draw size.
218  *
219  * In general this will be almost, but not quite, equal to window_size().
220  *
221  * input_area() represents the portion of the window corresponding to
222  * game_canvas().
223  */
224 rect input_area();
225 
226 /**
227  * Get the current active pixel scale multiplier.
228  * This is equal to output_size() / game_canvas_size().
229  * Currently it is always integer, and the same in both dimensions.
230  *
231  * This may differ from prefs::get().pixel_scale() in some cases,
232  * For example if the window is too small to fit the desired scale.
233  *
234  * @returns The currently active pixel scale multiplier.
235  */
236 int get_pixel_scale();
237 
238 /**
239  * Convert coordinates in draw space to coordinates in render space.
240  */
241 rect to_output(const rect& draw_space_rect);
242 
243 
244 /******************/
245 /* Screen capture */
246 /******************/
247 // These functions are slow, and intended only for screenshots.
248 
249 /**
250  * Copy back a portion of the render target that is already drawn.
251  *
252  * This area is specified in draw coordinates, not render coordinates.
253  * Thus the size of the retrieved surface may not match the size of r.
254  *
255  * If not null, r will be automatically clipped to the drawing area.
256  *
257  * Note: This is a very slow function! Its use should be phased out
258  * for everything except maybe screenshots.
259  *
260  * @param r The portion of the render target to retrieve, in
261  * draw coordinates.
262  * If not null, this will be modified to reflect the
263  * portion of the draw area that has been returned.
264  */
265 surface read_pixels(SDL_Rect* r = nullptr);
266 
267 /**
268  * The same as read_pixels, but returns a low-resolution surface
269  * suitable for use with the old drawing system.
270  *
271  * This should be considered deprecated, and phased out ASAP.
272  */
273 surface read_pixels_low_res(SDL_Rect* r = nullptr);
274 
275 
276 /****************************/
277 /* Render target management */
278 /****************************/
279 
280 /**
281  * Set the render target, without any provided way of setting it back.
282  *
283  * End-users should not use this function directly. In stead use
284  * draw::set_render_target(), which returns a setter object which
285  * will automatically restore the render target upon leaving scope.
286  *
287  * @param t The new render target. This must be a texture created
288  * with SDL_TEXTUREACCESS_TARGET, or an empty texture to
289  * indicate the underlying window.
290  */
291 void force_render_target(const texture& t);
292 
293 /** Reset the render target to the main window / screen. */
294 void clear_render_target();
295 
296 /** Reset the render target to the primary render buffer. */
297 void reset_render_target();
298 
299 /** Get the current render target.
300  *
301  * Will return an empty texture if the render target is the underlying
302  * window.
303  */
305 
306 
307 /*******************/
308 /* Exception types */
309 /*******************/
310 
311 /** An error specifically indicating video subsystem problems. */
312 struct error : public game::error
313 {
314  error() : game::error("unspecified video subsystem error") {}
315  error(const std::string& msg) : game::error(msg) {}
316 };
317 
318 /** Type that can be thrown as an exception to quit to desktop. */
319 class quit final : public lua_jailbreak_exception
320 {
321 public:
324  {
325  this->store();
326  }
327 
328 private:
330 };
331 
332 
333 /***************/
334 /* Diagnostics */
335 /***************/
336 
337 /**
338  * Provides diagnostic information about the current renderer for the @a build_info API.
339  */
340 std::vector<std::pair<std::string, std::string>> renderer_report();
341 
342 /**
343  * Retrieves the current game screen DPI for the @a build_info API.
344  */
345 std::pair<float, float> get_dpi();
346 
347 
348 /**************************/
349 /* Implementation details */
350 /**************************/
351 
352 /* This should only be used by draw.cpp for drawing, and texture.cpp for
353  * texture creation. Try not to use it for anything else. */
354 SDL_Renderer* get_renderer();
355 
356 /* This should not be used unless absolutely necessary. It's currently used
357  * for Windows tray notification and that's it. If it can be refactored out
358  * somehow then that would be best. */
359 SDL_Window* get_window();
360 
361 } // namespace video
double t
Definition: astarsearch.cpp:63
Base class for exceptions that want to be thrown 'through' lua.
void store() const noexcept
Stores a copy the current exception to be rethrown.
Wrapper class to encapsulate creation and management of an SDL_Texture.
Definition: texture.hpp:33
Type that can be thrown as an exception to quit to desktop.
Definition: video.hpp:320
#define IMPLEMENT_LUA_JAILBREAK_EXCEPTION(type)
Helper macro for classes deriving from lua_jailbreak_exception.
bool window_has_mouse_focus()
True iff the window has mouse focus.
Definition: video.cpp:701
bool headless()
The game is running headless.
Definition: video.cpp:139
rect draw_area()
The current drawable area.
Definition: video.cpp:442
rect output_area()
{0, 0, output_size().x, output_size().y}
Definition: video.cpp:460
void set_window_title(const std::string &title)
Sets the title of the main window.
Definition: video.cpp:636
void clear_render_target()
Reset the render target to the main window / screen.
Definition: video.cpp:527
rect to_output(const rect &r)
Convert coordinates in draw space to coordinates in render space.
Definition: video.cpp:466
std::vector< std::pair< std::string, std::string > > renderer_report()
Provides diagnostic information about the current renderer for the build_info API.
Definition: video.cpp:865
void reset_render_target()
Reset the render target to the primary render buffer.
Definition: video.cpp:532
point output_size()
Returns the size of the final render target.
Definition: video.cpp:410
std::vector< point > get_available_resolutions(const bool include_current)
Returns the list of available screen resolutions.
Definition: video.cpp:706
void set_window_icon(surface &icon)
Sets the icon of the main window.
Definition: video.cpp:642
bool window_is_visible()
True iff the window is not hidden.
Definition: video.cpp:691
surface read_pixels_low_res(SDL_Rect *r)
The same as read_pixels, but returns a low-resolution surface suitable for use with the old drawing s...
Definition: video.cpp:622
surface read_pixels(SDL_Rect *r)
Copy back a portion of the render target that is already drawn.
Definition: video.cpp:582
void force_render_target(const texture &t)
Set the render target, without any provided way of setting it back.
Definition: video.cpp:496
point game_canvas_size()
The size of the game canvas, in drawing coordinates / game pixels.
Definition: video.cpp:432
SDL_Window * get_window()
Definition: video.cpp:657
bool window_has_focus()
True iff the window has mouse or input focus.
Definition: video.cpp:696
point window_size()
Returns the size of the window in display units / screen coordinates.
Definition: video.cpp:419
bool has_window()
Whether the game has set up a window to render into.
Definition: video.cpp:405
bool testing()
The game is running unit tests.
Definition: video.cpp:144
bool is_fullscreen()
Whether we are currently in fullscreen mode.
Definition: video.cpp:766
std::vector< std::string > enumerate_drivers()
A list of available video drivers.
Definition: video.cpp:668
rect game_canvas()
The game canvas area, in drawing coordinates.
Definition: video.cpp:427
std::pair< float, float > get_dpi()
Retrieves the current game screen DPI for the build_info API.
Definition: video.cpp:845
int get_pixel_scale()
Get the current active pixel scale multiplier.
Definition: video.cpp:481
point current_resolution()
The current window size in desktop coordinates.
Definition: video.cpp:758
void init(fake type)
Initialize the video subsystem.
Definition: video.cpp:81
void set_fullscreen(bool fullscreen)
Set the fullscreen state.
Definition: video.cpp:774
void deinit()
Deinitialize the video subsystem.
Definition: video.cpp:110
bool set_resolution(const point &resolution)
Set the window resolution.
Definition: video.cpp:803
int current_refresh_rate()
The refresh rate of the screen.
Definition: video.cpp:486
std::string current_driver()
The current video driver in use, or else "<not initialized>".
Definition: video.cpp:662
void toggle_fullscreen()
Toggle fullscreen mode.
Definition: video.cpp:798
SDL_Renderer * get_renderer()
Definition: video.cpp:648
void update_buffers(bool autoupdate)
Update buffers to match current resolution and pixel scale settings.
Definition: video.cpp:833
texture get_render_target()
Get the current render target.
Definition: video.cpp:537
fake
For describing the type of faked display, if any.
Definition: video.hpp:44
point draw_size()
The size of the current render target in drawing coordinates.
Definition: video.cpp:437
rect input_area()
Returns the input area of the window, in display coordinates.
Definition: video.cpp:476
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:109
Contains the SDL_Rect helper code.
Base class for all the errors encountered by the engine.
Definition: exceptions.hpp:29
Holds a 2D point.
Definition: point.hpp:25
An abstract description of a rectangle with integer coordinates.
Definition: rect.hpp:47
An error specifically indicating video subsystem problems.
Definition: video.hpp:313
error(const std::string &msg)
Definition: video.hpp:315