The Battle for Wesnoth  1.17.0-dev
video.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2021
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 "events.hpp"
19 #include "exceptions.hpp"
21 
22 #include <memory>
23 
24 class surface;
25 struct point;
26 
27 namespace sdl
28 {
29 class window;
30 }
31 
32 class CVideo
33 {
34 public:
35  CVideo(const CVideo&) = delete;
36  CVideo& operator=(const CVideo&) = delete;
37 
38  enum FAKE_TYPES { NO_FAKE, FAKE, FAKE_TEST };
39 
40  CVideo(FAKE_TYPES type = NO_FAKE);
41 
42  ~CVideo();
43 
44  static bool setup_completed()
45  {
46  return singleton_ != nullptr;
47  }
48 
50  {
51  return *singleton_;
52  }
53 
54  /***** ***** ***** ***** Unit test-related functions ***** ***** ****** *****/
55 
56  void make_fake();
57 
58  /**
59  * Creates a fake frame buffer for the unit tests.
60  *
61  * @param width The width of the buffer.
62  * @param height The height of the buffer.
63  */
64  void make_test_fake(const unsigned width = 1024, const unsigned height = 768);
65 
66  bool faked() const
67  {
68  return fake_screen_;
69  }
70 
71  bool non_interactive() const;
72 
73  /***** ***** ***** ***** Window-related functions ***** ***** ****** *****/
74 
75  /** Initializes a new SDL window instance, taking into account any preiously saved states. */
76  void init_window();
77 
78  /** Returns a pointer to the underlying SDL window. */
79  sdl::window* get_window();
80 
81  bool has_window()
82  {
83  return get_window() != nullptr;
84  }
85 
86  static std::string current_driver();
87 
88  static std::vector<std::string> enumerate_drivers();
89 
90 private:
91  enum MODE_EVENT { TO_RES, TO_FULLSCREEN, TO_WINDOWED, TO_MAXIMIZED_WINDOW };
92 
93  /**
94  * Sets the window's mode - ie, changing it to fullscreen, maximizing, etc.
95  *
96  * @param mode The action to perform.
97  * @param size The new window size. Utilized if @a mode is TO_RES.
98  */
99  void set_window_mode(const MODE_EVENT mode, const point& size);
100 
101 public:
102  void set_fullscreen(bool ison);
103 
104  void toggle_fullscreen();
105 
106  bool is_fullscreen() const;
107 
108  bool supports_vsync() const;
109 
110  bool set_resolution(const unsigned width, const unsigned height);
111 
112  /**
113  * Set the window resolution.
114  *
115  * @param resolution The new width and height.
116  *
117  * @returns Whether the resolution was successfully changed.
118  */
119  bool set_resolution(const point& resolution);
120 
121  point current_resolution();
122 
123  /** Returns the list of available screen resolutions. */
124  std::vector<point> get_available_resolutions(const bool include_current = false);
125 
126  /**
127  * Returns the current window renderer area, either in pixels or screen coordinates.
128  *
129  * @param as_pixels Whether to return the area in pixels (default true) or
130  * DPI-independent (DIP) screen coordinates.
131  */
132  SDL_Rect screen_area(bool as_pixels = true) const;
133 
134  /** Returns the window renderer width in pixels or screen coordinates. */
135  int get_width(bool as_pixels = true) const;
136 
137  /** Returns the window renderer height in pixels or in screen coordinates. */
138  int get_height(bool as_pixels = true) const;
139 
140  /** The current game screen dpi. */
141  std::pair<float, float> get_dpi() const;
142 
143  /** The current scale factor on High-DPI screens. */
144  std::pair<float, float> get_dpi_scale_factor() const;
145 
146  /**
147  * Tests whether the given flags are currently set on the SDL window.
148  *
149  * @param flags The flags to test, OR'd together.
150  */
151  bool window_has_flags(uint32_t flags) const;
152 
153  /**
154  * Sets the title of the main window.
155  *
156  * @param title The new title for the window.
157  */
158  void set_window_title(const std::string& title);
159 
160  /**
161  * Sets the icon of the main window.
162  *
163  * @param icon The new icon for the window.
164  */
165  void set_window_icon(surface& icon);
166 
168  {
169  return refresh_rate_;
170  }
171 
172  /***** ***** ***** ***** Drawing functions ***** ***** ****** *****/
173 
174  /**
175  * Draws a surface directly onto the screen framebuffer.
176  *
177  * @param x The x coordinate at which to draw.
178  * @param y The y coordinate at which to draw.
179  * @param surf The surface to draw.
180  * @param srcrect The area of the surface to draw. This defaults to nullptr,
181  * which implies the entire thing.
182  * @param clip_rect The clippin rect. If not null, the surface will only be drawn
183  * within the bounds of the given rectangle.
184  */
185  void blit_surface(int x, int y, surface surf, SDL_Rect* srcrect = nullptr, SDL_Rect* clip_rect = nullptr);
186 
187  /** Renders the screen. Should normally not be called directly! */
188  void flip();
189 
190  /**
191  * Updates and ensures the framebuffer surface is valid.
192  * This needs to be invoked immediately after a resize event or the game will crash.
193  */
194  void update_framebuffer();
195 
196  /** Clear the screen contents */
197  void clear_screen();
198 
199  /** Returns a reference to the framebuffer. */
200  surface& getSurface();
201 
202  /**
203  * Stop the screen being redrawn. Anything that happens while the updates are locked will
204  * be hidden from the user's view.
205  *
206  * Note that this function is re-entrant, meaning that if lock_updates(true) is called twice,
207  * lock_updates(false) must be called twice to unlock updates.
208  */
209  void lock_updates(bool value);
210 
211  /** Whether the screen has been 'locked' or not. */
212  bool update_locked() const;
213 
214  void lock_flips(bool);
215 
216  /***** ***** ***** ***** Help string functions ***** ***** ****** *****/
217 
218  /**
219  * Displays a help string with the given text. A 'help string' is like a tooltip,
220  * but appears at the bottom of the screen so as to not be intrusive.
221  *
222  * @param str The text to display.
223  *
224  * @returns The handle id of the new help string.
225  */
226  int set_help_string(const std::string& str);
227 
228  /** Removes the help string with the given handle. */
229  void clear_help_string(int handle);
230 
231  /** Removes all help strings. */
232  void clear_all_help_strings();
233 
234  /***** ***** ***** ***** General utils ***** ***** ****** *****/
235 
236  /** Waits a given number of milliseconds before returning. */
237  static void delay(unsigned int milliseconds);
238 
239  struct error : public game::error
240  {
242  : game::error("Video initialization failed")
243  {
244  }
245  };
246 
247  /** Type that can be thrown as an exception to quit to desktop. */
249  {
250  public:
253  {
254  }
255 
256  private:
258  };
259 
260 private:
262 
263  /** The SDL window object. */
264  std::unique_ptr<sdl::window> window;
265 
266  /** Initializes the SDL video subsystem. */
267  void initSDL();
268 
269  // if there is no display at all, but we 'fake' it for clients
271 
272  /** Helper class to manage SDL events. */
274  {
275  public:
276  virtual void handle_event(const SDL_Event&)
277  {
278  }
279 
280  virtual void handle_window_event(const SDL_Event& event);
281 
283  : sdl_handler(false)
284  {
285  }
286  };
287 
289 
290  /** Curent ID of the help string. */
292 
296 };
297 
298 /** An object which will lock the display for the duration of its lifetime. */
300 {
301  update_locker(CVideo& v, bool lock = true)
302  : video(v)
303  , unlock(lock)
304  {
305  if(lock) {
306  video.lock_updates(true);
307  }
308  }
309 
311  {
312  unlock_update();
313  }
314 
316  {
317  if(unlock) {
318  video.lock_updates(false);
319  unlock = false;
320  }
321  }
322 
323 private:
325  bool unlock;
326 };
327 
329 {
330 public:
332  : video_(video)
333  {
334  video_.lock_flips(true);
335  }
336 
338  {
339  video_.lock_flips(false);
340  }
341 
342 private:
344 };
345 
346 namespace video2
347 {
349 {
350 protected:
351  draw_layering(const bool auto_join = true);
352  virtual ~draw_layering();
353 };
354 
355 void trigger_full_redraw();
356 }
std::string current_driver()
Definition: sound.cpp:412
FAKE_TYPES
Definition: video.hpp:38
#define IMPLEMENT_LUA_JAILBREAK_EXCEPTION(type)
Helper macro for classes deriving from lua_jailbreak_exception.
int help_string_
Curent ID of the help string.
Definition: video.hpp:291
Definition: video.hpp:32
static CVideo * singleton_
Definition: video.hpp:261
Type that can be thrown as an exception to quit to desktop.
Definition: video.hpp:248
MODE_EVENT
Definition: video.hpp:91
int refresh_rate_
Definition: video.hpp:295
static CVideo & get_singleton()
Definition: video.hpp:49
int flip_locked_
Definition: video.hpp:294
int updated_locked_
Definition: video.hpp:293
void blit_surface(const surface &surf, const SDL_Rect *srcrect, surface &dst, const SDL_Rect *dstrect)
Replacement for sdl_blit.
Definition: utils.cpp:2010
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:87
The wrapper class for the SDL_Window class.
Definition: window.hpp:45
CVideo & video
Definition: video.hpp:324
void unlock_update()
Definition: video.hpp:315
bool has_window()
Definition: video.hpp:81
An object which will lock the display for the duration of its lifetime.
Definition: video.hpp:299
bool unlock
Definition: video.hpp:325
flip_locker(CVideo &video)
Definition: video.hpp:331
bool faked() const
Definition: video.hpp:66
Definition: video.cpp:51
int current_refresh_rate() const
Definition: video.hpp:167
CVideo & video_
Definition: video.hpp:343
Holds a 2D point.
Definition: point.hpp:24
~flip_locker()
Definition: video.hpp:337
~update_locker()
Definition: video.hpp:310
Base class for all the errors encountered by the engine.
Definition: exceptions.hpp:28
void trigger_full_redraw()
Definition: video.cpp:68
video_event_handler event_handler_
Definition: video.hpp:288
virtual void handle_event(const SDL_Event &)
Definition: video.hpp:276
bool fake_screen_
Definition: video.hpp:270
point resolution()
Definition: general.cpp:393
std::vector< std::string > enumerate_drivers()
Definition: sound.cpp:418
update_locker(CVideo &v, bool lock=true)
Definition: video.hpp:301
std::shared_ptr< halo_record > handle
Definition: halo.hpp:30
static bool setup_completed()
Definition: video.hpp:44
Base class for exceptions that want to be thrown &#39;through&#39; lua.
std::unique_ptr< sdl::window > window
The SDL window object.
Definition: video.hpp:264
Helper class to manage SDL events.
Definition: video.hpp:273