summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video/CMakeLists.txt2
-rw-r--r--src/video/sdl2_default_v.cpp199
-rw-r--r--src/video/sdl2_default_v.h40
-rw-r--r--src/video/sdl2_opengl_v.cpp6
-rw-r--r--src/video/sdl2_opengl_v.h4
-rw-r--r--src/video/sdl2_v.cpp217
-rw-r--r--src/video/sdl2_v.h26
7 files changed, 280 insertions, 214 deletions
diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt
index 77b0b0302..3b74e1046 100644
--- a/src/video/CMakeLists.txt
+++ b/src/video/CMakeLists.txt
@@ -22,6 +22,8 @@ if(NOT OPTION_DEDICATED)
add_files(
sdl2_v.cpp
sdl2_v.h
+ sdl2_default_v.cpp
+ sdl2_default_v.h
CONDITION SDL2_FOUND
)
diff --git a/src/video/sdl2_default_v.cpp b/src/video/sdl2_default_v.cpp
new file mode 100644
index 000000000..b8e769ede
--- /dev/null
+++ b/src/video/sdl2_default_v.cpp
@@ -0,0 +1,199 @@
+/*
+ * This file is part of OpenTTD.
+ * 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.
+ * 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.
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/** @file sdl2_default_v.cpp Implementation of the default backend for SDL2 video driver. */
+
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "../gfx_func.h"
+#include "../rev.h"
+#include "../blitter/factory.hpp"
+#include "../network/network.h"
+#include "../thread.h"
+#include "../progress.h"
+#include "../core/random_func.hpp"
+#include "../core/math_func.hpp"
+#include "../core/mem_func.hpp"
+#include "../core/geometry_func.hpp"
+#include "../fileio_func.h"
+#include "../framerate_type.h"
+#include "../window_func.h"
+#include "sdl2_default_v.h"
+#include <SDL.h>
+#include <mutex>
+#include <condition_variable>
+#ifdef __EMSCRIPTEN__
+# include <emscripten.h>
+# include <emscripten/html5.h>
+#endif
+
+#include "../safeguards.h"
+
+static FVideoDriver_SDL_Default iFVideoDriver_SDL_Default;
+
+static SDL_Surface *_sdl_surface;
+static SDL_Surface *_sdl_rgb_surface;
+static SDL_Surface *_sdl_real_surface;
+static SDL_Palette *_sdl_palette;
+
+void VideoDriver_SDL_Default::UpdatePalette()
+{
+ SDL_Color pal[256];
+
+ for (int i = 0; i != this->local_palette.count_dirty; i++) {
+ pal[i].r = this->local_palette.palette[this->local_palette.first_dirty + i].r;
+ pal[i].g = this->local_palette.palette[this->local_palette.first_dirty + i].g;
+ pal[i].b = this->local_palette.palette[this->local_palette.first_dirty + i].b;
+ pal[i].a = 0;
+ }
+
+ SDL_SetPaletteColors(_sdl_palette, pal, this->local_palette.first_dirty, this->local_palette.count_dirty);
+ SDL_SetSurfacePalette(_sdl_surface, _sdl_palette);
+}
+
+void VideoDriver_SDL_Default::MakePalette()
+{
+ if (_sdl_palette == nullptr) {
+ _sdl_palette = SDL_AllocPalette(256);
+ if (_sdl_palette == nullptr) usererror("SDL2: Couldn't allocate palette: %s", SDL_GetError());
+ }
+
+ _cur_palette.first_dirty = 0;
+ _cur_palette.count_dirty = 256;
+ this->local_palette = _cur_palette;
+ this->UpdatePalette();
+
+ if (_sdl_surface != _sdl_real_surface) {
+ /* When using a shadow surface, also set our palette on the real screen. This lets SDL
+ * allocate as many colors (or approximations) as
+ * possible, instead of using only the default SDL
+ * palette. This allows us to get more colors exactly
+ * right and might allow using better approximations for
+ * other colors.
+ *
+ * Note that colors allocations are tried in-order, so
+ * this favors colors further up into the palette. Also
+ * note that if two colors from the same animation
+ * sequence are approximated using the same color, that
+ * animation will stop working.
+ *
+ * Since changing the system palette causes the colours
+ * to change right away, and allocations might
+ * drastically change, we can't use this for animation,
+ * since that could cause weird coloring between the
+ * palette change and the blitting below, so we only set
+ * the real palette during initialisation.
+ */
+ SDL_SetSurfacePalette(_sdl_real_surface, _sdl_palette);
+ }
+}
+
+void VideoDriver_SDL_Default::Paint()
+{
+ PerformanceMeasurer framerate(PFE_VIDEO);
+
+ if (IsEmptyRect(this->dirty_rect) && _cur_palette.count_dirty == 0) return;
+
+ if (_cur_palette.count_dirty != 0) {
+ Blitter *blitter = BlitterFactory::GetCurrentBlitter();
+
+ switch (blitter->UsePaletteAnimation()) {
+ case Blitter::PALETTE_ANIMATION_VIDEO_BACKEND:
+ this->UpdatePalette();
+ break;
+
+ case Blitter::PALETTE_ANIMATION_BLITTER: {
+ bool need_buf = _screen.dst_ptr == nullptr;
+ if (need_buf) _screen.dst_ptr = this->GetVideoPointer();
+ blitter->PaletteAnimate(this->local_palette);
+ if (need_buf) {
+ this->ReleaseVideoPointer();
+ _screen.dst_ptr = nullptr;
+ }
+ break;
+ }
+
+ case Blitter::PALETTE_ANIMATION_NONE:
+ break;
+
+ default:
+ NOT_REACHED();
+ }
+ _cur_palette.count_dirty = 0;
+ }
+
+ SDL_Rect r = { this->dirty_rect.left, this->dirty_rect.top, this->dirty_rect.right - this->dirty_rect.left, this->dirty_rect.bottom - this->dirty_rect.top };
+
+ if (_sdl_surface != _sdl_real_surface) {
+ SDL_BlitSurface(_sdl_surface, &r, _sdl_real_surface, &r);
+ }
+ SDL_UpdateWindowSurfaceRects(this->sdl_window, &r, 1);
+
+ this->dirty_rect = {};
+}
+
+void VideoDriver_SDL_Default::PaintThread()
+{
+ /* First tell the main thread we're started */
+ std::unique_lock<std::recursive_mutex> lock(*this->draw_mutex);
+ this->draw_signal->notify_one();
+
+ /* Now wait for the first thing to draw! */
+ this->draw_signal->wait(*this->draw_mutex);
+
+ while (this->draw_continue) {
+ /* Then just draw and wait till we stop */
+ this->Paint();
+ this->draw_signal->wait(lock);
+ }
+}
+
+bool VideoDriver_SDL_Default::AllocateBackingStore(int w, int h, bool force)
+{
+ int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
+
+ _sdl_real_surface = SDL_GetWindowSurface(this->sdl_window);
+ if (_sdl_real_surface == nullptr) usererror("SDL2: Couldn't get window surface: %s", SDL_GetError());
+
+ if (!force && w == _sdl_real_surface->w && h == _sdl_real_surface->h) return false;
+
+ /* Free any previously allocated rgb surface. */
+ if (_sdl_rgb_surface != nullptr) {
+ SDL_FreeSurface(_sdl_rgb_surface);
+ _sdl_rgb_surface = nullptr;
+ }
+
+ if (bpp == 8) {
+ _sdl_rgb_surface = SDL_CreateRGBSurface(0, w, h, 8, 0, 0, 0, 0);
+ if (_sdl_rgb_surface == nullptr) usererror("SDL2: Couldn't allocate shadow surface: %s", SDL_GetError());
+
+ _sdl_surface = _sdl_rgb_surface;
+ } else {
+ _sdl_surface = _sdl_real_surface;
+ }
+
+ /* X11 doesn't appreciate it if we invalidate areas outside the window
+ * if shared memory is enabled (read: it crashes). So, as we might have
+ * gotten smaller, reset our dirty rects. GameSizeChanged() a bit lower
+ * will mark the whole screen dirty again anyway, but this time with the
+ * new dimensions. */
+ this->dirty_rect = {};
+
+ _screen.width = _sdl_surface->w;
+ _screen.height = _sdl_surface->h;
+ _screen.pitch = _sdl_surface->pitch / (bpp / 8);
+ _screen.dst_ptr = this->GetVideoPointer();
+
+ this->MakePalette();
+
+ return true;
+}
+
+void *VideoDriver_SDL_Default::GetVideoPointer()
+{
+ return _sdl_surface->pixels;
+}
diff --git a/src/video/sdl2_default_v.h b/src/video/sdl2_default_v.h
new file mode 100644
index 000000000..1b67be5d3
--- /dev/null
+++ b/src/video/sdl2_default_v.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of OpenTTD.
+ * 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.
+ * 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.
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/** @file sdl2_default_v.h Default backend of the SDL2 video driver. */
+
+#ifndef VIDEO_SDL2_DEFAULT_H
+#define VIDEO_SDL2_DEFAULT_H
+
+#include "sdl2_v.h"
+
+/** The SDL video driver using default SDL backend. */
+class VideoDriver_SDL_Default : public VideoDriver_SDL_Base {
+public:
+ const char *GetName() const override { return "sdl"; }
+
+protected:
+ bool AllocateBackingStore(int w, int h, bool force = false) override;
+ void *GetVideoPointer() override;
+ void Paint() override;
+ void PaintThread() override;
+
+ void ReleaseVideoPointer() override {}
+
+private:
+ void UpdatePalette();
+ void MakePalette();
+};
+
+/** Factory for the SDL video driver. */
+class FVideoDriver_SDL_Default : public DriverFactoryBase {
+public:
+ FVideoDriver_SDL_Default() : DriverFactoryBase(Driver::DT_VIDEO, 5, "sdl", "SDL Video Driver") {}
+ Driver *CreateInstance() const override { return new VideoDriver_SDL_Default(); }
+};
+
+#endif /* VIDEO_SDL2_DEFAULT_H */
diff --git a/src/video/sdl2_opengl_v.cpp b/src/video/sdl2_opengl_v.cpp
index a24d6cf2f..9c9a9c6fa 100644
--- a/src/video/sdl2_opengl_v.cpp
+++ b/src/video/sdl2_opengl_v.cpp
@@ -50,12 +50,12 @@ static OGLProc GetOGLProcAddressCallback(const char *proc)
bool VideoDriver_SDL_OpenGL::CreateMainWindow(uint w, uint h, uint flags)
{
- return this->VideoDriver_SDL::CreateMainWindow(w, h, SDL_WINDOW_OPENGL);
+ return this->VideoDriver_SDL_Base::CreateMainWindow(w, h, SDL_WINDOW_OPENGL);
}
const char *VideoDriver_SDL_OpenGL::Start(const StringList &param)
{
- const char *error = VideoDriver_SDL::Start(param);
+ const char *error = VideoDriver_SDL_Base::Start(param);
if (error != nullptr) return error;
error = this->AllocateContext();
@@ -79,7 +79,7 @@ const char *VideoDriver_SDL_OpenGL::Start(const StringList &param)
void VideoDriver_SDL_OpenGL::Stop()
{
this->DestroyContext();
- this->VideoDriver_SDL::Stop();
+ this->VideoDriver_SDL_Base::Stop();
}
void VideoDriver_SDL_OpenGL::DestroyContext()
diff --git a/src/video/sdl2_opengl_v.h b/src/video/sdl2_opengl_v.h
index 6aff3b5f5..a59233db6 100644
--- a/src/video/sdl2_opengl_v.h
+++ b/src/video/sdl2_opengl_v.h
@@ -10,7 +10,7 @@
#include "sdl2_v.h"
/** The OpenGL video driver for windows. */
-class VideoDriver_SDL_OpenGL : public VideoDriver_SDL {
+class VideoDriver_SDL_OpenGL : public VideoDriver_SDL_Base {
public:
VideoDriver_SDL_OpenGL() : gl_context(nullptr), anim_buffer(nullptr) {}
@@ -36,6 +36,8 @@ protected:
void Paint() override;
bool CreateMainWindow(uint w, uint h, uint flags) override;
+ void PaintThread() override {}
+
private:
void *gl_context; ///< OpenGL context.
uint8 *anim_buffer; ///< Animation buffer from OpenGL back-end.
diff --git a/src/video/sdl2_v.cpp b/src/video/sdl2_v.cpp
index 86774fc56..818389b80 100644
--- a/src/video/sdl2_v.cpp
+++ b/src/video/sdl2_v.cpp
@@ -32,77 +32,18 @@
#include "../safeguards.h"
-static FVideoDriver_SDL iFVideoDriver_SDL;
-
-static SDL_Surface *_sdl_surface;
-static SDL_Surface *_sdl_rgb_surface;
-static SDL_Surface *_sdl_real_surface;
-static SDL_Palette *_sdl_palette;
-
#ifdef __EMSCRIPTEN__
/** Whether we just had a window-enter event. */
static bool _cursor_new_in_window = false;
#endif
-void VideoDriver_SDL::MakeDirty(int left, int top, int width, int height)
+void VideoDriver_SDL_Base::MakeDirty(int left, int top, int width, int height)
{
Rect r = {left, top, left + width, top + height};
this->dirty_rect = BoundingRect(this->dirty_rect, r);
}
-void VideoDriver_SDL::UpdatePalette()
-{
- SDL_Color pal[256];
-
- for (int i = 0; i != this->local_palette.count_dirty; i++) {
- pal[i].r = this->local_palette.palette[this->local_palette.first_dirty + i].r;
- pal[i].g = this->local_palette.palette[this->local_palette.first_dirty + i].g;
- pal[i].b = this->local_palette.palette[this->local_palette.first_dirty + i].b;
- pal[i].a = 0;
- }
-
- SDL_SetPaletteColors(_sdl_palette, pal, this->local_palette.first_dirty, this->local_palette.count_dirty);
- SDL_SetSurfacePalette(_sdl_surface, _sdl_palette);
-}
-
-void VideoDriver_SDL::MakePalette()
-{
- if (_sdl_palette == nullptr) {
- _sdl_palette = SDL_AllocPalette(256);
- if (_sdl_palette == nullptr) usererror("SDL2: Couldn't allocate palette: %s", SDL_GetError());
- }
-
- _cur_palette.first_dirty = 0;
- _cur_palette.count_dirty = 256;
- this->local_palette = _cur_palette;
- this->UpdatePalette();
-
- if (_sdl_surface != _sdl_real_surface) {
- /* When using a shadow surface, also set our palette on the real screen. This lets SDL
- * allocate as many colors (or approximations) as
- * possible, instead of using only the default SDL
- * palette. This allows us to get more colors exactly
- * right and might allow using better approximations for
- * other colors.
- *
- * Note that colors allocations are tried in-order, so
- * this favors colors further up into the palette. Also
- * note that if two colors from the same animation
- * sequence are approximated using the same color, that
- * animation will stop working.
- *
- * Since changing the system palette causes the colours
- * to change right away, and allocations might
- * drastically change, we can't use this for animation,
- * since that could cause weird coloring between the
- * palette change and the blitting below, so we only set
- * the real palette during initialisation.
- */
- SDL_SetSurfacePalette(_sdl_real_surface, _sdl_palette);
- }
-}
-
-void VideoDriver_SDL::CheckPaletteAnim()
+void VideoDriver_SDL_Base::CheckPaletteAnim()
{
if (_cur_palette.count_dirty == 0) return;
@@ -110,67 +51,7 @@ void VideoDriver_SDL::CheckPaletteAnim()
this->MakeDirty(0, 0, _screen.width, _screen.height);
}
-void VideoDriver_SDL::Paint()
-{
- PerformanceMeasurer framerate(PFE_VIDEO);
-
- if (IsEmptyRect(this->dirty_rect) && _cur_palette.count_dirty == 0) return;
-
- if (_cur_palette.count_dirty != 0) {
- Blitter *blitter = BlitterFactory::GetCurrentBlitter();
-
- switch (blitter->UsePaletteAnimation()) {
- case Blitter::PALETTE_ANIMATION_VIDEO_BACKEND:
- this->UpdatePalette();
- break;
-
- case Blitter::PALETTE_ANIMATION_BLITTER: {
- bool need_buf = _screen.dst_ptr == nullptr;
- if (need_buf) _screen.dst_ptr = this->GetVideoPointer();
- blitter->PaletteAnimate(this->local_palette);
- if (need_buf) {
- this->ReleaseVideoPointer();
- _screen.dst_ptr = nullptr;
- }
- break;
- }
-
- case Blitter::PALETTE_ANIMATION_NONE:
- break;
-
- default:
- NOT_REACHED();
- }
- _cur_palette.count_dirty = 0;
- }
-
- SDL_Rect r = { this->dirty_rect.left, this->dirty_rect.top, this->dirty_rect.right - this->dirty_rect.left, this->dirty_rect.bottom - this->dirty_rect.top };
-
- if (_sdl_surface != _sdl_real_surface) {
- SDL_BlitSurface(_sdl_surface, &r, _sdl_real_surface, &r);
- }
- SDL_UpdateWindowSurfaceRects(this->sdl_window, &r, 1);
-
- this->dirty_rect = {};
-}
-
-void VideoDriver_SDL::PaintThread()
-{
- /* First tell the main thread we're started */
- std::unique_lock<std::recursive_mutex> lock(*this->draw_mutex);
- this->draw_signal->notify_one();
-
- /* Now wait for the first thing to draw! */
- this->draw_signal->wait(*this->draw_mutex);
-
- while (this->draw_continue) {
- /* Then just draw and wait till we stop */
- this->Paint();
- this->draw_signal->wait(lock);
- }
-}
-
-/* static */ void VideoDriver_SDL::PaintThreadThunk(VideoDriver_SDL *drv)
+/* static */ void VideoDriver_SDL_Base::PaintThreadThunk(VideoDriver_SDL_Base *drv)
{
drv->PaintThread();
}
@@ -253,7 +134,7 @@ static uint FindStartupDisplay(uint startup_display)
return 0;
}
-void VideoDriver_SDL::ClientSizeChanged(int w, int h, bool force)
+void VideoDriver_SDL_Base::ClientSizeChanged(int w, int h, bool force)
{
/* Allocate backing store of the new size. */
if (this->AllocateBackingStore(w, h, force)) {
@@ -268,7 +149,7 @@ void VideoDriver_SDL::ClientSizeChanged(int w, int h, bool force)
}
}
-bool VideoDriver_SDL::CreateMainWindow(uint w, uint h, uint flags)
+bool VideoDriver_SDL_Base::CreateMainWindow(uint w, uint h, uint flags)
{
if (this->sdl_window != nullptr) return true;
@@ -315,7 +196,7 @@ bool VideoDriver_SDL::CreateMainWindow(uint w, uint h, uint flags)
return true;
}
-bool VideoDriver_SDL::CreateMainSurface(uint w, uint h, bool resize)
+bool VideoDriver_SDL_Base::CreateMainSurface(uint w, uint h, bool resize)
{
GetAvailableVideoMode(&w, &h);
DEBUG(driver, 1, "SDL2: using mode %ux%u", w, h);
@@ -332,53 +213,7 @@ bool VideoDriver_SDL::CreateMainSurface(uint w, uint h, bool resize)
return true;
}
-bool VideoDriver_SDL::AllocateBackingStore(int w, int h, bool force)
-{
- int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
-
- _sdl_real_surface = SDL_GetWindowSurface(this->sdl_window);
- if (_sdl_real_surface == nullptr) usererror("SDL2: Couldn't get window surface: %s", SDL_GetError());
-
- if (!force && w == _sdl_real_surface->w && h == _sdl_real_surface->h) return false;
-
- /* Free any previously allocated rgb surface. */
- if (_sdl_rgb_surface != nullptr) {
- SDL_FreeSurface(_sdl_rgb_surface);
- _sdl_rgb_surface = nullptr;
- }
-
- if (bpp == 8) {
- _sdl_rgb_surface = SDL_CreateRGBSurface(0, w, h, 8, 0, 0, 0, 0);
- if (_sdl_rgb_surface == nullptr) usererror("SDL2: Couldn't allocate shadow surface: %s", SDL_GetError());
-
- _sdl_surface = _sdl_rgb_surface;
- } else {
- _sdl_surface = _sdl_real_surface;
- }
-
- /* X11 doesn't appreciate it if we invalidate areas outside the window
- * if shared memory is enabled (read: it crashes). So, as we might have
- * gotten smaller, reset our dirty rects. GameSizeChanged() a bit lower
- * will mark the whole screen dirty again anyway, but this time with the
- * new dimensions. */
- this->dirty_rect = {};
-
- _screen.width = _sdl_surface->w;
- _screen.height = _sdl_surface->h;
- _screen.pitch = _sdl_surface->pitch / (bpp / 8);
- _screen.dst_ptr = this->GetVideoPointer();
-
- this->MakePalette();
-
- return true;
-}
-
-void *VideoDriver_SDL::GetVideoPointer()
-{
- return _sdl_surface->pixels;
-}
-
-bool VideoDriver_SDL::ClaimMousePointer()
+bool VideoDriver_SDL_Base::ClaimMousePointer()
{
SDL_ShowCursor(0);
#ifdef __EMSCRIPTEN__
@@ -390,7 +225,7 @@ bool VideoDriver_SDL::ClaimMousePointer()
/**
* This is called to indicate that an edit box has gained focus, text input mode should be enabled.
*/
-void VideoDriver_SDL::EditBoxGainedFocus()
+void VideoDriver_SDL_Base::EditBoxGainedFocus()
{
if (!this->edit_box_focused) {
SDL_StartTextInput();
@@ -401,7 +236,7 @@ void VideoDriver_SDL::EditBoxGainedFocus()
/**
* This is called to indicate that an edit box has lost focus, text input mode should be disabled.
*/
-void VideoDriver_SDL::EditBoxLostFocus()
+void VideoDriver_SDL_Base::EditBoxLostFocus()
{
if (this->edit_box_focused) {
SDL_StopTextInput();
@@ -535,7 +370,7 @@ static uint ConvertSdlKeycodeIntoMy(SDL_Keycode kc)
return key;
}
-int VideoDriver_SDL::PollEvent()
+int VideoDriver_SDL_Base::PollEvent()
{
SDL_Event ev;
@@ -699,7 +534,7 @@ static const char *InitializeSDL()
return nullptr;
}
-const char *VideoDriver_SDL::Initialize()
+const char *VideoDriver_SDL_Base::Initialize()
{
this->UpdateAutoResolution();
@@ -712,7 +547,7 @@ const char *VideoDriver_SDL::Initialize()
return nullptr;
}
-const char *VideoDriver_SDL::Start(const StringList &parm)
+const char *VideoDriver_SDL_Base::Start(const StringList &parm)
{
if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) return "Only real blitters supported";
@@ -749,7 +584,7 @@ const char *VideoDriver_SDL::Start(const StringList &parm)
return nullptr;
}
-void VideoDriver_SDL::Stop()
+void VideoDriver_SDL_Base::Stop()
{
SDL_QuitSubSystem(SDL_INIT_VIDEO);
if (SDL_WasInit(SDL_INIT_EVERYTHING) == 0) {
@@ -757,7 +592,7 @@ void VideoDriver_SDL::Stop()
}
}
-void VideoDriver_SDL::InputLoop()
+void VideoDriver_SDL_Base::InputLoop()
{
uint32 mod = SDL_GetModState();
const Uint8 *keys = SDL_GetKeyboardState(NULL);
@@ -790,7 +625,7 @@ void VideoDriver_SDL::InputLoop()
if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
}
-void VideoDriver_SDL::LoopOnce()
+void VideoDriver_SDL_Base::LoopOnce()
{
InteractiveRandom(); // randomness
@@ -824,7 +659,7 @@ void VideoDriver_SDL::LoopOnce()
#endif
}
-void VideoDriver_SDL::MainLoop()
+void VideoDriver_SDL_Base::MainLoop()
{
if (this->draw_threaded) {
/* Initialise the mutex first, because that's the thing we *need*
@@ -837,7 +672,7 @@ void VideoDriver_SDL::MainLoop()
this->draw_signal = new std::condition_variable_any();
this->draw_continue = true;
- this->draw_threaded = StartNewThread(&draw_thread, "ottd:draw-sdl", &VideoDriver_SDL::PaintThreadThunk, this);
+ this->draw_threaded = StartNewThread(&draw_thread, "ottd:draw-sdl", &VideoDriver_SDL_Base::PaintThreadThunk, this);
/* Free the mutex if we won't be able to use it. */
if (!this->draw_threaded) {
@@ -868,7 +703,7 @@ void VideoDriver_SDL::MainLoop()
#endif
}
-void VideoDriver_SDL::MainLoopCleanup()
+void VideoDriver_SDL_Base::MainLoopCleanup()
{
if (this->draw_mutex != nullptr) {
this->draw_continue = false;
@@ -896,7 +731,7 @@ void VideoDriver_SDL::MainLoopCleanup()
#endif
}
-bool VideoDriver_SDL::ChangeResolution(int w, int h)
+bool VideoDriver_SDL_Base::ChangeResolution(int w, int h)
{
std::unique_lock<std::recursive_mutex> lock;
if (this->draw_mutex != nullptr) lock = std::unique_lock<std::recursive_mutex>(*this->draw_mutex);
@@ -904,7 +739,7 @@ bool VideoDriver_SDL::ChangeResolution(int w, int h)
return CreateMainSurface(w, h, true);
}
-bool VideoDriver_SDL::ToggleFullscreen(bool fullscreen)
+bool VideoDriver_SDL_Base::ToggleFullscreen(bool fullscreen)
{
std::unique_lock<std::recursive_mutex> lock;
if (this->draw_mutex != nullptr) lock = std::unique_lock<std::recursive_mutex>(*this->draw_mutex);
@@ -937,7 +772,7 @@ bool VideoDriver_SDL::ToggleFullscreen(bool fullscreen)
return ret == 0;
}
-bool VideoDriver_SDL::AfterBlitterChange()
+bool VideoDriver_SDL_Base::AfterBlitterChange()
{
assert(BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 0);
int w, h;
@@ -945,17 +780,17 @@ bool VideoDriver_SDL::AfterBlitterChange()
return CreateMainSurface(w, h, false);
}
-void VideoDriver_SDL::AcquireBlitterLock()
+void VideoDriver_SDL_Base::AcquireBlitterLock()
{
if (this->draw_mutex != nullptr) this->draw_mutex->lock();
}
-void VideoDriver_SDL::ReleaseBlitterLock()
+void VideoDriver_SDL_Base::ReleaseBlitterLock()
{
if (this->draw_mutex != nullptr) this->draw_mutex->unlock();
}
-Dimension VideoDriver_SDL::GetScreenSize() const
+Dimension VideoDriver_SDL_Base::GetScreenSize() const
{
SDL_DisplayMode mode;
if (SDL_GetCurrentDisplayMode(this->startup_display, &mode) != 0) return VideoDriver::GetScreenSize();
@@ -963,7 +798,7 @@ Dimension VideoDriver_SDL::GetScreenSize() const
return { static_cast<uint>(mode.w), static_cast<uint>(mode.h) };
}
-bool VideoDriver_SDL::LockVideoBuffer()
+bool VideoDriver_SDL_Base::LockVideoBuffer()
{
if (this->buffer_locked) return false;
this->buffer_locked = true;
@@ -976,7 +811,7 @@ bool VideoDriver_SDL::LockVideoBuffer()
return true;
}
-void VideoDriver_SDL::UnlockVideoBuffer()
+void VideoDriver_SDL_Base::UnlockVideoBuffer()
{
if (_screen.dst_ptr != nullptr) {
/* Hand video buffer back to the drawing backend. */
diff --git a/src/video/sdl2_v.h b/src/video/sdl2_v.h
index cfd82d151..7042bf270 100644
--- a/src/video/sdl2_v.h
+++ b/src/video/sdl2_v.h
@@ -15,9 +15,9 @@
#include "video_driver.hpp"
/** The SDL video driver. */
-class VideoDriver_SDL : public VideoDriver {
+class VideoDriver_SDL_Base : public VideoDriver {
public:
- VideoDriver_SDL() : sdl_window(nullptr) {}
+ VideoDriver_SDL_Base() : sdl_window(nullptr) {}
const char *Start(const StringList &param) override;
@@ -59,19 +59,17 @@ protected:
void InputLoop() override;
bool LockVideoBuffer() override;
void UnlockVideoBuffer() override;
- void Paint() override;
- void PaintThread() override;
void CheckPaletteAnim() override;
/** Indicate to the driver the client-side might have changed. */
void ClientSizeChanged(int w, int h, bool force);
/** (Re-)create the backing store. */
- virtual bool AllocateBackingStore(int w, int h, bool force = false);
+ virtual bool AllocateBackingStore(int w, int h, bool force = false) = 0;
/** Get a pointer to the video buffer. */
- virtual void *GetVideoPointer();
+ virtual void *GetVideoPointer() = 0;
/** Hand video buffer back to the painting backend. */
- virtual void ReleaseVideoPointer() {}
+ virtual void ReleaseVideoPointer() = 0;
/** Create the main window. */
virtual bool CreateMainWindow(uint w, uint h, uint flags = 0);
@@ -81,13 +79,10 @@ private:
void MainLoopCleanup();
bool CreateMainSurface(uint w, uint h, bool resize);
const char *Initialize();
- bool CreateMainWindow(uint w, uint h);
- void UpdatePalette();
- void MakePalette();
#ifdef __EMSCRIPTEN__
/* Convert a constant pointer back to a non-constant pointer to a member function. */
- static void EmscriptenLoop(void *self) { ((VideoDriver_SDL *)self)->LoopOnce(); }
+ static void EmscriptenLoop(void *self) { ((VideoDriver_SDL_Base *)self)->LoopOnce(); }
#endif
/**
@@ -99,14 +94,7 @@ private:
std::thread draw_thread;
std::unique_lock<std::recursive_mutex> draw_lock;
- static void PaintThreadThunk(VideoDriver_SDL *drv);
-};
-
-/** Factory for the SDL video driver. */
-class FVideoDriver_SDL : public DriverFactoryBase {
-public:
- FVideoDriver_SDL() : DriverFactoryBase(Driver::DT_VIDEO, 5, "sdl", "SDL Video Driver") {}
- Driver *CreateInstance() const override { return new VideoDriver_SDL(); }
+ static void PaintThreadThunk(VideoDriver_SDL_Base *drv);
};
#endif /* VIDEO_SDL_H */