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