The Battle for Wesnoth  1.17.8+dev
video.cpp
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 #include "video.hpp"
17 
18 #include "display.hpp"
19 #include "draw_manager.hpp"
20 #include "floating_label.hpp"
21 #include "font/sdl_ttf_compat.hpp"
22 #include "font/text.hpp"
23 #include "log.hpp"
24 #include "picture.hpp"
25 #include "preferences/general.hpp"
26 #include "sdl/input.hpp"
27 #include "sdl/point.hpp"
28 #include "sdl/texture.hpp"
29 #include "sdl/userevent.hpp"
30 #include "sdl/utils.hpp"
31 #include "sdl/window.hpp"
32 #include "widgets/menu.hpp" // for bluebg_style.unload_images
33 
34 #ifdef TARGET_OS_OSX
35 #include "desktop/apple_video.hpp"
36 #include "game_version.hpp"
37 #endif
38 
39 #include <SDL2/SDL_render.h> // SDL_Texture
40 
41 #include <cassert>
42 #include <vector>
43 
44 static lg::log_domain log_display("display");
45 #define LOG_DP LOG_STREAM(info, log_display)
46 #define ERR_DP LOG_STREAM(err, log_display)
47 #define WRN_DP LOG_STREAM(warn, log_display)
48 #define DBG_DP LOG_STREAM(debug, log_display)
49 
50 namespace
51 {
52 /** The SDL window object. Will be null only if headless_. */
53 std::unique_ptr<sdl::window> window;
54 
55 /** The main offscreen render target. */
56 texture render_texture_ = {};
57 
58 /** The current offscreen render target. */
59 texture current_render_target_ = {};
60 
61 bool headless_ = false; /**< running with no window at all */
62 bool testing_ = false; /**< running unit tests */
63 point test_resolution_ = {1024, 768}; /**< resolution for unit tests */
64 int refresh_rate_ = 0;
65 point game_canvas_size_ = {0, 0};
66 int pixel_scale_ = 1;
67 rect input_area_ = {};
68 
69 } // anon namespace
70 
71 namespace video
72 {
73 
74 // Non-public interface
75 void render_screen(); // exposed and used only in draw_manager.cpp
76 
77 // Internal functions
78 static void init_window();
79 static void init_test_window();
80 static void init_fake();
81 static void init_test();
82 static bool update_framebuffer();
83 static bool update_test_framebuffer();
84 static point draw_offset();
85 
86 
87 void init(fake type)
88 {
89  LOG_DP << "initializing video";
90  if(SDL_WasInit(SDL_INIT_VIDEO)) {
91  throw error("video subsystem already initialized");
92  }
93  if(SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
94  ERR_DP << "Could not initialize SDL_video: " << SDL_GetError();
95  throw error("Video initialization failed");
96  }
97 
98  switch(type) {
99  case fake::none:
100  init_window();
101  break;
102  case fake::window:
103  init_fake();
104  break;
105  case fake::draw:
106  init_test();
107  break;
108  default:
109  throw error("unrecognized fake type passed to video::init");
110  }
111 }
112 
113 void deinit()
114 {
115  LOG_DP << "deinitializing video";
116 
117  // SDL_INIT_TIMER is always initialized at program start.
118  // If it is not initialized here, there is a problem.
119  assert(SDL_WasInit(SDL_INIT_TIMER));
120 
121  // Clear any static texture caches,
122  // lest they try to delete textures after SDL_Quit.
125  render_texture_.reset();
126  current_render_target_.reset();
128 
129  // Destroy the window, and thus also the renderer.
130  window.reset();
131 
132  // Close the video subsystem.
133  if(SDL_WasInit(SDL_INIT_VIDEO)) {
134  LOG_DP << "quitting SDL video subsystem";
135  SDL_QuitSubSystem(SDL_INIT_VIDEO);
136  }
137  if(SDL_WasInit(SDL_INIT_VIDEO)) {
138  // This should not have been initialized multiple times
139  throw error("video subsystem still initialized after deinit");
140  }
141 }
142 
143 bool headless()
144 {
145  return headless_;
146 }
147 
148 bool testing()
149 {
150  return testing_;
151 }
152 
153 void init_fake()
154 {
155  headless_ = true;
156  refresh_rate_ = 1;
157  game_canvas_size_ = {800,600};
158 }
159 
160 void init_test()
161 {
162  testing_ = true;
163  refresh_rate_ = 1;
165 }
166 
167 /** Returns true if the buffer was changed */
169 {
170  if (!window) {
171  throw("trying to update test framebuffer with no window");
172  }
173 
174  bool changed = false;
175 
176  // TODO: code unduplication
177  // Build or update the current render texture.
178  if (render_texture_) {
179  int w, h;
180  SDL_QueryTexture(render_texture_, nullptr, nullptr, &w, &h);
181  if (w != test_resolution_.x || h != test_resolution_.y) {
182  // Delete it and let it be recreated.
183  LOG_DP << "destroying old render texture";
184  render_texture_.reset();
185  }
186  }
187  if (!render_texture_) {
188  LOG_DP << "creating offscreen render texture";
189  render_texture_.assign(SDL_CreateTexture(
190  *window,
191  window->pixel_format(),
192  SDL_TEXTUREACCESS_TARGET,
193  test_resolution_.x, test_resolution_.y
194  ));
195  LOG_DP << "updated render target to " << test_resolution_.x
196  << "x" << test_resolution_.y;
197  changed = true;
198  }
199 
200  pixel_scale_ = 1;
201  game_canvas_size_ = test_resolution_;
202  input_area_ = {{}, test_resolution_};
203 
204  // The render texture is always the render target in this case.
205  force_render_target(render_texture_);
206 
207  return changed;
208 }
209 
211 {
212  if (!window) {
213  throw error("trying to update framebuffer with no window");
214  }
215 
216  if (testing_) {
217  return update_test_framebuffer();
218  }
219 
220  bool changed = false;
221 
222  // Make sure we're getting values from the native window.
223  SDL_SetRenderTarget(*window, nullptr);
224 
225  // Non-integer scales are not currently supported.
226  // This option makes things neater when window size is not a perfect
227  // multiple of logical size, which can happen when manually resizing.
228  SDL_RenderSetIntegerScale(*window, SDL_TRUE);
229 
230  // Find max valid pixel scale at current output size.
231  point osize(window->get_output_size());
232  int max_scale = std::min(
235  max_scale = std::min(max_scale, preferences::max_pixel_scale);
236 
237  // Determine best pixel scale according to preference and window size
238  int scale = 1;
240  // Try to match the default size (1280x720) but do not reduce below
241  int def_scale = std::min(
244  scale = std::min(max_scale, def_scale);
245  // Otherwise reduce to keep below the max window size (1920x1080).
246  int min_scale = std::min(
247  osize.x / (preferences::max_window_width+1) + 1,
248  osize.y / (preferences::max_window_height+1) + 1);
249  scale = std::max(scale, min_scale);
250  } else {
251  scale = std::min(max_scale, preferences::pixel_scale());
252  }
253  // Cache it for easy access.
254  if (pixel_scale_ != scale) {
255  pixel_scale_ = scale;
256  changed = true;
257  }
258 
259  // Update logical size if it doesn't match the current resolution and scale.
260  point lsize(window->get_logical_size());
261  point wsize(window->get_size());
262  if (lsize.x != osize.x / scale || lsize.y != osize.y / scale) {
264  LOG_DP << "reducing pixel scale from desired "
265  << preferences::pixel_scale() << " to maximum allowable "
266  << scale;
267  }
268  LOG_DP << "pixel scale: " << scale;
269  LOG_DP << "overriding logical size";
270  LOG_DP << " old lsize: " << lsize;
271  LOG_DP << " old wsize: " << wsize;
272  LOG_DP << " old osize: " << osize;
273  window->set_logical_size(osize.x / scale, osize.y / scale);
274  lsize = window->get_logical_size();
275  wsize = window->get_size();
276  osize = window->get_output_size();
277  LOG_DP << " new lsize: " << lsize;
278  LOG_DP << " new wsize: " << wsize;
279  LOG_DP << " new osize: " << osize;
280  float sx, sy;
281  SDL_RenderGetScale(*window, &sx, &sy);
282  LOG_DP << " render scale: " << sx << ", " << sy;
283  }
284  // Cache it for easy access
285  game_canvas_size_ = lsize;
286 
287  // Build or update the current render texture.
288  if (render_texture_) {
289  int w, h;
290  SDL_QueryTexture(render_texture_, nullptr, nullptr, &w, &h);
291  if (w != osize.x || h != osize.y) {
292  // Delete it and let it be recreated.
293  LOG_DP << "destroying old render texture";
294  render_texture_.reset();
295  }
296  }
297  if (!render_texture_) {
298  LOG_DP << "creating offscreen render texture";
299  render_texture_.assign(SDL_CreateTexture(
300  *window,
301  window->pixel_format(),
302  SDL_TEXTUREACCESS_TARGET,
303  osize.x, osize.y
304  ));
305  // This isn't really necessary, but might be nice to have attached
306  render_texture_.set_draw_size(lsize);
307  changed = true;
308  }
309 
310  // Assign the render texture now. It will be used for all drawing.
311  force_render_target(render_texture_);
312 
313  // By default input area is the same as the window area.
314  input_area_ = {{}, wsize};
315 
316  rect active_area = to_output(draw_area());
317  if (active_area.size() != osize) {
318  LOG_DP << "render target offset: LT " << active_area.pos() << " RB "
319  << osize - active_area.size() - active_area.pos();
320  // Translate active_area into display coordinates as input_area_
321  input_area_ = {
322  (active_area.pos() * wsize) / osize,
323  (active_area.size() * wsize) / osize
324  };
325  LOG_DP << "input area: " << input_area_;
326  }
327 
328  return changed;
329 }
330 
332 {
333  LOG_DP << "creating test window " << test_resolution_.x
334  << "x" << test_resolution_.y;
335 
336  uint32_t window_flags = 0;
337  window_flags |= SDL_WINDOW_HIDDEN;
338  // The actual window won't be used, as we'll be rendering to texture.
339 
340  uint32_t renderer_flags = 0;
341  renderer_flags |= SDL_RENDERER_TARGETTEXTURE;
342  // All we need is to be able to render to texture.
343 
344  window.reset(new sdl::window(
345  "", 0, 0, test_resolution_.x, test_resolution_.y,
346  window_flags, renderer_flags
347  ));
348 
350 }
351 
353 {
354  // Position
355  const int x = preferences::fullscreen() ? SDL_WINDOWPOS_UNDEFINED : SDL_WINDOWPOS_CENTERED;
356  const int y = preferences::fullscreen() ? SDL_WINDOWPOS_UNDEFINED : SDL_WINDOWPOS_CENTERED;
357 
358  // Dimensions
359  const point res = preferences::resolution();
360  const int w = res.x;
361  const int h = res.y;
362 
363  uint32_t window_flags = 0;
364 
365  // Add any more default flags here
366  window_flags |= SDL_WINDOW_RESIZABLE;
367  window_flags |= SDL_WINDOW_ALLOW_HIGHDPI;
368 
370  window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
371  } else if(preferences::maximized()) {
372  window_flags |= SDL_WINDOW_MAXIMIZED;
373  }
374 
375  uint32_t renderer_flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
376 
377  if(preferences::vsync()) {
378  LOG_DP << "VSYNC on";
379  renderer_flags |= SDL_RENDERER_PRESENTVSYNC;
380  }
381 
382  // Initialize window
383  window.reset(new sdl::window("", x, y, w, h, window_flags, renderer_flags));
384 
385  // It is assumed that this function is only ever called once.
386  // If that is no longer true, then you should clean things up.
387  assert(!render_texture_);
388 
389  PLAIN_LOG << "Setting mode to " << w << "x" << h;
390 
392 
393  SDL_DisplayMode currentDisplayMode;
394  SDL_GetCurrentDisplayMode(window->get_display_index(), &currentDisplayMode);
395  refresh_rate_ = currentDisplayMode.refresh_rate != 0 ? currentDisplayMode.refresh_rate : 60;
396 
398 }
399 
401 {
402  if (testing_) {
403  return test_resolution_;
404  }
405  // As we are rendering via an abstraction, we should never need this.
406  return window->get_output_size();
407 }
408 
410 {
411  if (testing_) {
412  return test_resolution_;
413  }
414  return window->get_size();
415 }
416 
418 {
419  return {0, 0, game_canvas_size_.x, game_canvas_size_.y};
420 }
421 
423 {
424  return game_canvas_size_;
425 }
426 
428 {
429  return current_render_target_.draw_size();
430 }
431 
433 {
434  return {0, 0, current_render_target_.w(), current_render_target_.h()};
435 }
436 
438 {
439  // As we are using SDL_RenderSetIntegerScale, there may be a slight
440  // offset of the drawable area on the render target if the target size
441  // is not perfectly divisble by the scale.
442  // SDL doesn't provide any way of retrieving this offset,
443  // so we just have to base our calculation on the known behaviour.
444  point osize = output_size();
445  point dsize = draw_size();
446  point scale = osize / dsize;
447  return (osize - (scale * dsize)) / 2;
448 }
449 
451 {
452  point p = output_size();
453  return {0, 0, p.x, p.y};
454 }
455 
456 rect to_output(const rect& r)
457 {
458  // Multiply r by integer scale, adding draw_offset to the position.
459  point dsize = current_render_target_.draw_size();
460  point osize = current_render_target_.get_raw_size();
461  point pos = (r.pos() * (osize / dsize)) + draw_offset();
462  point size = r.size() * (osize / dsize);
463  return {pos, size};
464 }
465 
467 {
468  return input_area_;
469 }
470 
472 {
473  return pixel_scale_;
474 }
475 
477 {
478  // TODO: this should be more clever, depending on usage
479  return refresh_rate_;
480 }
481 
483 {
484  if (SDL_SetRenderTarget(get_renderer(), t)) {
485  ERR_DP << "failed to set render target to "
486  << static_cast<void*>(t.get()) << ' '
487  << t.draw_size() << " / " << t.get_raw_size();
488  ERR_DP << "last SDL error: " << SDL_GetError();
489  throw error("failed to set render target");
490  }
491  current_render_target_ = t;
492 
493  if (testing_) {
494  return;
495  }
496 
497  // The scale factor gets reset when the render target changes,
498  // so make sure it gets set back appropriately.
499  if (!t) {
500  DBG_DP << "rendering to window / screen";
501  window->set_logical_size(game_canvas_size_);
502  } else if (t == render_texture_) {
503  DBG_DP << "rendering to primary buffer";
504  window->set_logical_size(game_canvas_size_);
505  } else {
506  DBG_DP << "rendering to custom target "
507  << static_cast<void*>(t.get()) << ' '
508  << t.draw_size() << " / " << t.get_raw_size();
509  window->set_logical_size(t.w(), t.h());
510  }
511 }
512 
514 {
516 }
517 
519 {
520  // This should always be up-to-date, but assert for sanity.
521  assert(current_render_target_ == SDL_GetRenderTarget(get_renderer()));
522  return current_render_target_;
523 }
524 
525 // Note: this is not thread-safe.
526 // Drawing functions should not be called while this is active.
527 // SDL renderer usage is not thread-safe anyway, so this is fine.
529 {
530  if(headless_ || testing_) {
531  // No need to present anything in this case
532  return;
533  }
534 
535  if(!window) {
536  WRN_DP << "trying to render with no window";
537  return;
538  }
539 
540  // This should only ever be called when the main render texture is the
541  // current render target. It could be adapted otherwise... but let's not.
542  if(SDL_GetRenderTarget(*window) != render_texture_) {
543  ERR_DP << "trying to render screen, but current render texture is "
544  << static_cast<void*>(SDL_GetRenderTarget(*window))
545  << " | " << static_cast<void*>(current_render_target_.get())
546  << ". It should be " << static_cast<void*>(render_texture_.get());
547  throw error("tried to render screen from wrong render target");
548  }
549 
550  // Clear the render target so we're drawing to the window.
552 
553  // Copy the render texture to the window.
554  SDL_RenderCopy(*window, render_texture_, nullptr, nullptr);
555 
556  // Finalize and display the frame.
557  SDL_RenderPresent(*window);
558 
559  // Reset the render target to the render texture.
560  force_render_target(render_texture_);
561 }
562 
563 surface read_pixels(SDL_Rect* r)
564 {
565  if (!window) {
566  WRN_DP << "trying to read pixels with no window";
567  return surface();
568  }
569 
570  // This should be what we want to read from.
571  texture& target = current_render_target_;
572 
573  // Make doubly sure.
574  if (target != SDL_GetRenderTarget(*window)) {
575  SDL_Texture* t = SDL_GetRenderTarget(*window);
576  ERR_DP << "render target " << static_cast<void*>(target.get())
577  << ' ' << target.draw_size() << " / " << target.get_raw_size()
578  << " doesn't match window render target "
579  << static_cast<void*>(t);
580  throw error("unexpected render target while reading pixels");
581  }
582 
583  // Intersect the draw area with the given rect.
584  rect r_clipped = draw_area();
585  if (r) {
586  r_clipped.clip(*r);
587  if (r_clipped != *r) {
588  DBG_DP << "modifying pixel read area from " << *r
589  << " to " << r_clipped;
590  *r = r_clipped;
591  }
592  }
593 
594  // Convert the rect to output coordinates, if necessary.
595  rect o = to_output(r_clipped);
596 
597  // Create surface and read pixels
598  surface s(o.w, o.h);
599  SDL_RenderReadPixels(*window, &o, s->format->format, s->pixels, s->pitch);
600  return s;
601 }
602 
604 {
605  if(!window) {
606  WRN_DP << "trying to read pixels with no window";
607  return surface();
608  }
609  surface s = read_pixels(r);
610  if(r) {
611  return scale_surface(s, r->w, r->h);
612  } else {
613  return scale_surface(s, draw_size().x, draw_size().y);
614  }
615 }
616 
617 void set_window_title(const std::string& title)
618 {
619  assert(window);
620  window->set_title(title);
621 }
622 
624 {
625  assert(window);
626  window->set_icon(icon);
627 }
628 
629 SDL_Renderer* get_renderer()
630 {
631  if(window) {
632  return *window;
633  } else {
634  return nullptr;
635  }
636 }
637 
638 SDL_Window* get_window()
639 {
640  return *window;
641 }
642 
643 std::string current_driver()
644 {
645  const char* const drvname = SDL_GetCurrentVideoDriver();
646  return drvname ? drvname : "<not initialized>";
647 }
648 
649 std::vector<std::string> enumerate_drivers()
650 {
651  std::vector<std::string> res;
652  int num_drivers = SDL_GetNumVideoDrivers();
653 
654  for(int n = 0; n < num_drivers; ++n) {
655  const char* drvname = SDL_GetVideoDriver(n);
656  res.emplace_back(drvname ? drvname : "<invalid driver>");
657  }
658 
659  return res;
660 }
661 
662 /**
663  * Tests whether the given flags are currently set on the SDL window.
664  *
665  * @param flags The flags to test, OR'd together.
666  */
667 static bool window_has_flags(uint32_t flags)
668 {
669  return window && (window->get_flags() & flags) != 0;
670 }
671 
673 {
674  return window_has_flags(SDL_WINDOW_SHOWN);
675 }
676 
678 {
679  return window_has_flags(SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_INPUT_FOCUS);
680 }
681 
683 {
684  return window_has_flags(SDL_WINDOW_MOUSE_FOCUS);
685 }
686 
687 std::vector<point> get_available_resolutions(const bool include_current)
688 {
689  std::vector<point> result;
690 
691  if(!window) {
692  return result;
693  }
694 
695  const int display_index = window->get_display_index();
696 
697  const int modes = SDL_GetNumDisplayModes(display_index);
698  if(modes <= 0) {
699  PLAIN_LOG << "No modes supported";
700  return result;
701  }
702 
704 
705  // The maximum size to which this window can be set. For some reason this won't
706  // pop up as a display mode of its own.
707  SDL_Rect bounds;
708  SDL_GetDisplayBounds(display_index, &bounds);
709 
710  SDL_DisplayMode mode;
711 
712  for(int i = 0; i < modes; ++i) {
713  if(SDL_GetDisplayMode(display_index, i, &mode) == 0) {
714  // Exclude any results outside the range of the current DPI.
715  if(mode.w > bounds.w && mode.h > bounds.h) {
716  continue;
717  }
718 
719  if(mode.w >= min_res.x && mode.h >= min_res.y) {
720  result.emplace_back(mode.w, mode.h);
721  }
722  }
723  }
724 
725  if(std::find(result.begin(), result.end(), min_res) == result.end()) {
726  result.push_back(min_res);
727  }
728 
729  if(include_current) {
730  result.push_back(current_resolution());
731  }
732 
733  std::sort(result.begin(), result.end());
734  result.erase(std::unique(result.begin(), result.end()), result.end());
735 
736  return result;
737 }
738 
740 {
741  if (testing_) {
742  return test_resolution_;
743  }
744  return point(window->get_size()); // Convert from plain SDL_Point
745 }
746 
748 {
749  if (testing_) {
750  return true;
751  }
752  return (window->get_flags() & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0;
753 }
754 
756 {
757  if (headless_ || testing_) {
758  return;
759  }
760 
761  // Only do anything if the current value differs from the desired value
762  if (window && is_fullscreen() != fullscreen) {
763  if (fullscreen) {
764  window->full_screen();
765  } else if (preferences::maximized()) {
766  window->to_window();
767  window->maximize();
768  } else {
769  window->to_window();
770  window->restore();
771  }
772  update_buffers();
773  }
774 
775  // Update the config value in any case.
776  preferences::_set_fullscreen(fullscreen);
777 }
778 
780 {
782 }
783 
785 {
786  if(resolution == current_resolution()) {
787  return false;
788  }
789 
790  if(!window) {
791  throw error("tried to set resolution with no window");
792  }
793 
794  if(testing_) {
795  LOG_DP << "resizing test resolution to " << resolution;
796  test_resolution_ = resolution;
797  return update_test_framebuffer();
798  }
799 
800  window->restore();
801  window->set_size(resolution.x, resolution.y);
802  window->center();
803 
804  update_buffers();
805 
806  // Change the saved values in preferences.
807  LOG_DP << "updating resolution to " << resolution;
808  preferences::_set_resolution(resolution);
810 
811  return true;
812 }
813 
814 void update_buffers(bool autoupdate)
815 {
816  if(headless_) {
817  return;
818  }
819 
820  LOG_DP << "updating video buffers";
821  if(update_framebuffer() && autoupdate) {
823  }
824 }
825 
826 } // namespace video
void init(fake type)
Initialize the video subsystem.
Definition: video.cpp:87
point pos() const
Definition: rect.hpp:64
void _set_fullscreen(bool ison)
Definition: general.cpp:458
#define PLAIN_LOG
Definition: log.hpp:256
#define DBG_DP
Definition: video.cpp:48
const int min_window_height
Definition: general.cpp:67
std::vector< point > get_available_resolutions(const bool include_current)
Returns the list of available screen resolutions.
Definition: video.cpp:687
surface read_pixels(SDL_Rect *r)
Copy back a portion of the render target that is already drawn.
Definition: video.cpp:563
int get_pixel_scale()
Get the current active pixel scale multiplier.
Definition: video.cpp:471
SDL_Renderer * get_renderer()
Definition: video.cpp:629
void _set_maximized(bool ison)
Definition: general.cpp:453
Interfaces for manipulating version numbers of engine, add-ons, etc.
int w() const
The draw-space width of the texture, in pixels.
Definition: texture.hpp:105
std::string current_driver()
The current video driver in use, or else "<not initialized>".
Definition: video.cpp:643
void render_screen()
Definition: video.cpp:528
An error specifically indicating video subsystem problems.
Definition: video.hpp:303
void set_window_title(const std::string &title)
Sets the title of the main window.
Definition: video.cpp:617
#define ERR_DP
Definition: video.cpp:46
rect output_area()
{0, 0, output_size().x, output_size().y}
Definition: video.cpp:450
bool is_fullscreen()
Whether we are currently in fullscreen mode.
Definition: video.cpp:747
#define WRN_DP
Definition: video.cpp:47
#define LOG_DP
Definition: video.cpp:45
bool window_has_focus()
True iff the window has mouse or input focus.
Definition: video.cpp:677
static bool update_test_framebuffer()
Returns true if the buffer was changed.
Definition: video.cpp:168
const int min_window_width
Definition: general.cpp:66
int h() const
The draw-space height of the texture, in pixels.
Definition: texture.hpp:114
point get_raw_size() const
The raw internal texture size.
Definition: texture.cpp:112
const int max_window_width
Definition: general.cpp:72
rect to_output(const rect &r)
Convert coordinates in draw space to coordinates in render space.
Definition: video.cpp:456
int current_refresh_rate()
The refresh rate of the screen.
Definition: video.cpp:476
bool vsync()
Definition: general.cpp:442
void _set_resolution(const point &res)
Definition: general.cpp:447
void deinit()
Deinitialize the video subsystem.
Definition: video.cpp:113
static void init_window()
Definition: video.cpp:352
void set_fullscreen(bool fullscreen)
Set the fullscreen state.
Definition: video.cpp:755
#define h
bool testing()
The game is running unit tests.
Definition: video.cpp:148
surface scale_surface(const surface &surf, int w, int h)
Scale a surface using alpha-weighted modified bilinear filtering Note: causes artifacts with alpha gr...
Definition: utils.cpp:129
static point draw_offset()
Definition: video.cpp:437
texture get_render_target()
Get the current render target.
Definition: video.cpp:518
static bool window_has_flags(uint32_t flags)
Tests whether the given flags are currently set on the SDL window.
Definition: video.cpp:667
std::vector< std::string > enumerate_drivers()
A list of available video drivers.
Definition: video.cpp:649
static bool update_framebuffer()
Definition: video.cpp:210
static imgsel_style bluebg_style
Definition: menu.hpp:96
Contains functions for cleanly handling SDL input.
Wrapper class to encapsulate creation and management of an SDL_Texture.
Definition: texture.hpp:32
bool maximized()
Definition: general.cpp:432
void invalidate_all()
Mark the entire screen as requiring redraw.
bool set_resolution(const point &resolution)
Set the window resolution.
Definition: video.cpp:784
void flush_cache()
Purges all image caches.
Definition: picture.cpp:236
void update_buffers(bool autoupdate)
Update buffers to match current resolution and pixel scale settings.
Definition: video.cpp:814
point current_resolution()
The current window size in desktop coordinates.
Definition: video.cpp:739
static void init_fake()
Definition: video.cpp:153
rect game_canvas()
The game canvas area, in drawing coordinates.
Definition: video.cpp:417
point size() const
Definition: rect.hpp:65
point draw_size() const
The size of the texture in draw-space.
Definition: texture.hpp:122
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:47
void scale(size_t factor, const uint32_t *src, uint32_t *trg, int srcWidth, int srcHeight, const ScalerCfg &cfg=ScalerCfg(), int yFirst=0, int yLast=std::numeric_limits< int >::max())
Definition: xbrz.cpp:1190
point output_size()
Returns the size of the final render target.
Definition: video.cpp:400
bool fullscreen()
Definition: general.cpp:437
static lg::log_domain log_display("display")
void clip(const SDL_Rect &r)
Clip this rectangle by the given rectangle.
Definition: rect.cpp:101
rect draw_area()
The current drawable area.
Definition: video.cpp:432
bool headless()
The game is running headless.
Definition: video.cpp:143
map_display and display: classes which take care of displaying the map and game-data on the screen...
const int max_pixel_scale
Definition: general.cpp:79
int pixel_scale()
Definition: general.cpp:411
void set_window_icon(surface &icon)
Sets the icon of the main window.
Definition: video.cpp:623
const int def_window_width
Definition: general.cpp:69
std::size_t i
Definition: function.cpp:967
mock_party p
static map_location::DIRECTION s
void force_render_target(const texture &t)
Set the render target, without any provided way of setting it back.
Definition: video.cpp:482
fake
For describing the type of faked display, if any.
Definition: video.hpp:44
point game_canvas_size()
The size of the game canvas, in drawing coordinates / game pixels.
Definition: video.cpp:422
An abstract description of a rectangle with integer coordinates.
Definition: rect.hpp:46
static void init_test_window()
Definition: video.cpp:331
Holds a 2D point.
Definition: point.hpp:24
void flush_texture_cache()
Flush the rendered text cache.
Definition: text.cpp:65
int w
bool window_has_mouse_focus()
True iff the window has mouse focus.
Definition: video.cpp:682
point draw_size()
The size of the current render target in drawing coordinates.
Definition: video.cpp:427
bool window_is_visible()
True iff the window is not hidden.
Definition: video.cpp:672
void toggle_fullscreen()
Toggle fullscreen mode.
Definition: video.cpp:779
const int def_window_height
Definition: general.cpp:70
SDL_Texture * get() const
Definition: texture.hpp:196
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:603
SDL_Window * get_window()
Definition: video.cpp:638
double t
Definition: astarsearch.cpp:65
Standard logging facilities (interface).
point window_size()
Returns the size of the window in display units / screen coordinates.
Definition: video.cpp:409
rect input_area()
Returns the input area of the window, in display coordinates.
Definition: video.cpp:466
Contains a wrapper class for the SDL_Window class.
void point(int x, int y)
Draw a single point.
Definition: draw.cpp:193
point resolution()
Definition: general.cpp:395
static map_location::DIRECTION n
Transitional API for porting SDL_ttf-based code to Pango.
const int max_window_height
Definition: general.cpp:73
bool auto_pixel_scale()
Definition: general.cpp:422
void clear_render_target()
Reset the render target to the main window / screen.
Definition: video.cpp:513
static void init_test()
Definition: video.cpp:160