OpenTTD Source: src/video/video_driver.hpp Source File

OpenTTD Source 15.0-RC2

video_driver.hpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#ifndef VIDEO_VIDEO_DRIVER_HPP
11#define VIDEO_VIDEO_DRIVER_HPP
12
13#include "../debug.h"
14#include "../driver.h"
15#include "../core/geometry_type.hpp"
16#include "../core/math_func.hpp"
17#include "../gfx_func.h"
18#include "../settings_type.h"
19#include "../zoom_type.h"
20#include "../network/network_func.h"
21#include <atomic>
22#include <chrono>
23#include <condition_variable>
24#include <mutex>
25#include <thread>
26
27extern std::string _ini_videodriver;
28extern std::vector<Dimension> _resolutions;
29extern Dimension _cur_resolution;
30extern bool _rightclick_emulate;
31extern bool _video_hw_accel;
32extern bool _video_vsync;
33
35 class VideoDriver : public Driver {
36 const uint DEFAULT_WINDOW_WIDTH = 640u;
37 const uint DEFAULT_WINDOW_HEIGHT = 480u;
38
39public:
40 VideoDriver(bool uses_hardware_acceleration = false) : fast_forward_key_pressed(false), fast_forward_via_key(false), is_game_threaded(true), uses_hardware_acceleration(uses_hardware_acceleration) {}
41
49 virtual void MakeDirty(int left, int top, int width, int height) = 0;
50
54 virtual void MainLoop() = 0;
55
62 virtual bool ChangeResolution(int w, int h) = 0;
63
69 virtual bool ToggleFullscreen(bool fullscreen) = 0;
70
75 virtual void ToggleVsync([[maybe_unused]] bool vsync) {}
76
81 virtual bool AfterBlitterChange()
82 {
83 return true;
84 }
85
86 virtual bool ClaimMousePointer()
87 {
88 return true;
89 }
90
95 virtual bool UseSystemCursor()
96 {
97 return false;
98 }
99
103 virtual void PopulateSystemSprites() {}
104
108 virtual void ClearSystemSprites() {}
109
118 virtual bool HasGUI() const
119 {
120 return true;
121 }
122
127 virtual bool HasEfficient8Bpp() const
128 {
129 return false;
130 }
131
136 virtual bool HasAnimBuffer()
137 {
138 return false;
139 }
140
145 virtual uint8_t *GetAnimBuffer()
146 {
147 return nullptr;
148 }
149
153 virtual void EditBoxLostFocus() {}
154
158 virtual void EditBoxGainedFocus() {}
159
164 virtual std::vector<int> GetListOfMonitorRefreshRates()
165 {
166 return {};
167 }
168
169 virtual std::string_view GetInfoString() const
170 {
171 return this->GetName();
172 }
173
180 void QueueOnMainThread(std::function<void()> &&func)
181 {
182 std::lock_guard<std::mutex> lock(this->cmd_queue_mutex);
183
184 this->cmd_queue.emplace_back(std::forward<std::function<void()>>(func));
185 }
186
187 void GameLoopPause();
188
192 static VideoDriver *GetInstance()
193 {
194 return static_cast<VideoDriver *>(DriverFactoryBase::GetActiveDriver(Driver::DT_VIDEO).get());
195 }
196
197 static std::string GetCaption();
198
203 struct VideoBufferLocker {
204 VideoBufferLocker()
205 {
206 this->unlock = VideoDriver::GetInstance()->LockVideoBuffer();
207 }
208
209 ~VideoBufferLocker()
210 {
211 if (this->unlock) VideoDriver::GetInstance()->UnlockVideoBuffer();
212 }
213
214 private:
215 bool unlock;
216 };
217
218protected:
219 const uint ALLOWED_DRIFT = 5;
220
224 virtual Dimension GetScreenSize() const { return { DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT }; }
225
229 void UpdateAutoResolution()
230 {
231 if (_cur_resolution.width == 0 || _cur_resolution.height == 0) {
232 /* Auto-detect a good resolution. We aim for 75% of the screen size.
233 * Limit width times height times bytes per pixel to fit a 32 bit
234 * integer, This way all internal drawing routines work correctly. */
235 Dimension res = this->GetScreenSize();
236 _cur_resolution.width = ClampU(res.width * 3 / 4, DEFAULT_WINDOW_WIDTH, UINT16_MAX / 2);
237 _cur_resolution.height = ClampU(res.height * 3 / 4, DEFAULT_WINDOW_HEIGHT, UINT16_MAX / 2);
238 }
239 }
240
244 virtual void InputLoop() {}
245
250 virtual bool LockVideoBuffer()
251 {
252 return false;
253 }
254
258 virtual void UnlockVideoBuffer() {}
259
263 virtual void Paint() {}
264
268 virtual void CheckPaletteAnim() {}
269
274 virtual bool PollEvent() { return false; };
275
279 void StartGameThread();
280
284 void StopGameThread();
285
291 void Tick();
292
296 void SleepTillNextTick();
297
298 std::chrono::steady_clock::duration GetGameInterval()
299 {
300#ifdef DEBUG_DUMP_COMMANDS
301 /* When replaying, run as fast as we can. */
302 extern bool _ddc_fastforward;
303 if (_ddc_fastforward) return std::chrono::microseconds(0);
304#endif /* DEBUG_DUMP_COMMANDS */
305
306 TicToc::Tick("GameTick");
307
308 /* If we are paused, run on normal speed. */
309 if (_pause_mode.Any()) return std::chrono::milliseconds(MILLISECONDS_PER_TICK);
310 /* Infinite speed, as quickly as you can. */
311 if (_game_speed == 0) return std::chrono::microseconds(0);
312
313 return std::chrono::microseconds(MILLISECONDS_PER_TICK * 1000 * 100 / _game_speed);
314 }
315
316 std::chrono::steady_clock::duration GetDrawInterval()
317 {
318 TicToc::Tick("DrawTick");
319
320 /* If vsync, draw interval is decided by the display driver */
321 if (_video_vsync && this->uses_hardware_acceleration) return std::chrono::microseconds(0);
322 return std::chrono::microseconds(1000000 / _settings_client.gui.refresh_rate);
323 }
324
326 void DrainCommandQueue()
327 {
328 std::vector<std::function<void()>> cmds{};
329
330 {
331 /* Exchange queue with an empty one to limit the time we
332 * hold the mutex. This also ensures that queued functions can
333 * add new functions to the queue without everything blocking. */
334 std::lock_guard<std::mutex> lock(this->cmd_queue_mutex);
335 cmds.swap(this->cmd_queue);
336 }
337
338 for (auto &f : cmds) {
339 f();
340 }
341 }
342
343 std::chrono::steady_clock::time_point next_game_tick;
344 std::chrono::steady_clock::time_point next_draw_tick;
345
346 bool fast_forward_key_pressed;
347 bool fast_forward_via_key;
348
349 bool is_game_threaded;
350 std::thread game_thread;
351 std::mutex game_state_mutex;
352 std::mutex game_thread_wait_mutex;
353
354 bool uses_hardware_acceleration;
355
356 static void GameThreadThunk(VideoDriver *drv);
357
358private:
359 std::mutex cmd_queue_mutex;
360 std::vector<std::function<void()>> cmd_queue;
361
362 void GameLoop();
363 void GameThread();
364};
365
366#endif /* VIDEO_VIDEO_DRIVER_HPP */
BaseBitSet::Any
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Definition base_bitset_type.hpp:170
DriverFactoryBase::GetActiveDriver
static std::unique_ptr< Driver > & GetActiveDriver(Driver::Type type)
Get the active driver for the given type.
Definition driver.h:84
Driver
A driver for communicating with the user.
Definition driver.h:21
Driver::GetName
virtual std::string_view GetName() const =0
Get the name of this driver.
Driver::DT_VIDEO
@ DT_VIDEO
A video driver.
Definition driver.h:42
VideoDriver
The base of all video drivers.
Definition video_driver.hpp:35
VideoDriver::InputLoop
virtual void InputLoop()
Handle input logic, is CTRL pressed, should we fast-forward, etc.
Definition video_driver.hpp:244
VideoDriver::ToggleFullscreen
virtual bool ToggleFullscreen(bool fullscreen)=0
Change the full screen setting.
VideoDriver::GetScreenSize
virtual Dimension GetScreenSize() const
Get the resolution of the main screen.
Definition video_driver.hpp:224
VideoDriver::PopulateSystemSprites
virtual void PopulateSystemSprites()
Populate all sprites in cache.
Definition video_driver.hpp:103
VideoDriver::QueueOnMainThread
void QueueOnMainThread(std::function< void()> &&func)
Queue a function to be called on the main thread with game state lock held and video buffer locked.
Definition video_driver.hpp:180
VideoDriver::DEFAULT_WINDOW_WIDTH
const uint DEFAULT_WINDOW_WIDTH
Default window width.
Definition video_driver.hpp:36
VideoDriver::fast_forward_key_pressed
bool fast_forward_key_pressed
The fast-forward key is being pressed.
Definition video_driver.hpp:346
VideoDriver::ClearSystemSprites
virtual void ClearSystemSprites()
Clear all cached sprites.
Definition video_driver.hpp:108
VideoDriver::UseSystemCursor
virtual bool UseSystemCursor()
Get whether the mouse cursor is drawn by the video driver.
Definition video_driver.hpp:95
VideoDriver::Tick
void Tick()
Give the video-driver a tick.
Definition video_driver.cpp:104
VideoDriver::DEFAULT_WINDOW_HEIGHT
const uint DEFAULT_WINDOW_HEIGHT
Default window height.
Definition video_driver.hpp:37
VideoDriver::MakeDirty
virtual void MakeDirty(int left, int top, int width, int height)=0
Mark a particular area dirty.
VideoDriver::SleepTillNextTick
void SleepTillNextTick()
Sleep till the next tick is about to happen.
Definition video_driver.cpp:173
VideoDriver::StartGameThread
void StartGameThread()
Start the loop for game-tick.
Definition video_driver.cpp:88
VideoDriver::EditBoxLostFocus
virtual void EditBoxLostFocus()
An edit box lost the input focus.
Definition video_driver.hpp:153
VideoDriver::HasAnimBuffer
virtual bool HasAnimBuffer()
Does this video driver support a separate animation buffer in addition to the colour buffer?
Definition video_driver.hpp:136
VideoDriver::ChangeResolution
virtual bool ChangeResolution(int w, int h)=0
Change the resolution of the window.
VideoDriver::HasGUI
virtual bool HasGUI() const
Whether the driver has a graphical user interface with the end user.
Definition video_driver.hpp:118
VideoDriver::GetCaption
static std::string GetCaption()
Get the caption to use for the game's title bar.
Definition video_driver.cpp:191
VideoDriver::ToggleVsync
virtual void ToggleVsync(bool vsync)
Change the vsync setting.
Definition video_driver.hpp:75
VideoDriver::AfterBlitterChange
virtual bool AfterBlitterChange()
Callback invoked after the blitter was changed.
Definition video_driver.hpp:81
VideoDriver::StopGameThread
void StopGameThread()
Stop the loop for the game-tick.
Definition video_driver.cpp:97
VideoDriver::GetInstance
static VideoDriver * GetInstance()
Get the currently active instance of the video driver.
Definition video_driver.hpp:192
VideoDriver::ALLOWED_DRIFT
const uint ALLOWED_DRIFT
How many times videodriver can miss deadlines without it being overly compensated.
Definition video_driver.hpp:219
VideoDriver::MainLoop
virtual void MainLoop()=0
Perform the actual drawing.
VideoDriver::EditBoxGainedFocus
virtual void EditBoxGainedFocus()
An edit box gained the input focus.
Definition video_driver.hpp:158
VideoDriver::PollEvent
virtual bool PollEvent()
Process a single system event.
Definition video_driver.hpp:274
VideoDriver::HasEfficient8Bpp
virtual bool HasEfficient8Bpp() const
Has this video driver an efficient code path for palette animated 8-bpp sprites?
Definition video_driver.hpp:127
VideoDriver::Paint
virtual void Paint()
Paint the window.
Definition video_driver.hpp:263
VideoDriver::UnlockVideoBuffer
virtual void UnlockVideoBuffer()
Unlock a previously locked video buffer.
Definition video_driver.hpp:258
VideoDriver::fast_forward_via_key
bool fast_forward_via_key
The fast-forward was enabled by key press.
Definition video_driver.hpp:347
VideoDriver::GetAnimBuffer
virtual uint8_t * GetAnimBuffer()
Get a pointer to the animation buffer of the video back-end.
Definition video_driver.hpp:145
VideoDriver::GetListOfMonitorRefreshRates
virtual std::vector< int > GetListOfMonitorRefreshRates()
Get a list of refresh rates of each available monitor.
Definition video_driver.hpp:164
VideoDriver::CheckPaletteAnim
virtual void CheckPaletteAnim()
Process any pending palette animation.
Definition video_driver.hpp:268
VideoDriver::LockVideoBuffer
virtual bool LockVideoBuffer()
Make sure the video buffer is ready for drawing.
Definition video_driver.hpp:250
VideoDriver::GameLoopPause
void GameLoopPause()
Pause the game-loop for a bit, releasing the game-state lock.
Definition video_driver.cpp:68
VideoDriver::DrainCommandQueue
void DrainCommandQueue()
Execute all queued commands.
Definition video_driver.hpp:326
VideoDriver::UpdateAutoResolution
void UpdateAutoResolution()
Apply resolution auto-detection and clamp to sensible defaults.
Definition video_driver.hpp:229
_game_speed
uint16_t _game_speed
Current game-speed; 100 is 1x, 0 is infinite.
Definition gfx.cpp:40
_pause_mode
PauseModes _pause_mode
The current pause mode.
Definition gfx.cpp:50
MILLISECONDS_PER_TICK
static const uint MILLISECONDS_PER_TICK
The number of milliseconds per game tick.
Definition gfx_type.h:370
ClampU
constexpr uint ClampU(const uint a, const uint min, const uint max)
Clamp an unsigned integer between an interval.
Definition math_func.hpp:150
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
ClientSettings::gui
GUISettings gui
settings related to the GUI
Definition settings_type.h:650
Dimension
Dimensions (a width and height) of a rectangle in 2D.
Definition geometry_type.hpp:56
GUISettings::refresh_rate
uint16_t refresh_rate
How often we refresh the screen (time between draw-ticks).
Definition settings_type.h:236
VideoDriver::VideoBufferLocker
Helper struct to ensure the video buffer is locked and ready for drawing.
Definition video_driver.hpp:203
VideoDriver::VideoBufferLocker::unlock
bool unlock
Stores if the lock did anything that has to be undone.
Definition video_driver.hpp:215
_video_vsync
bool _video_vsync
Whether we should use vsync (only if active video driver supports HW acceleration).
Definition video_driver.cpp:28
_video_hw_accel
bool _video_hw_accel
Whether to consider hardware accelerated video drivers on startup.
Definition video_driver.cpp:27
_ini_videodriver
std::string _ini_videodriver
The video driver a stored in the configuration file.
Definition driver.cpp:27
_resolutions
std::vector< Dimension > _resolutions
List of resolutions.
Definition driver.cpp:28
_cur_resolution
Dimension _cur_resolution
The current resolution.
Definition driver.cpp:29
_rightclick_emulate
bool _rightclick_emulate
Whether right clicking is emulated.
Definition driver.cpp:30
lock
std::mutex lock
synchronization for playback status fields
Definition win32_m.cpp:35