Changeset - r24875:dd67bf72984d
[Not reviewed]
master
0 2 0
Michael Lutz - 3 years ago 2021-01-16 15:42:59
michi@icosahedron.de
Codechange: [Win32] Split the video driver into a base class and a GDI backend class.
2 files changed with 97 insertions and 88 deletions:
0 comments (0 inline, 0 general)
src/video/win32_v.cpp
Show inline comments
 
@@ -99,25 +99,25 @@ static void UpdatePalette(HDC dc, uint s
 
	uint i;
 

	
 
	for (i = 0; i != count; i++) {
 
		rgb[i].rgbRed   = _local_palette.palette[start + i].r;
 
		rgb[i].rgbGreen = _local_palette.palette[start + i].g;
 
		rgb[i].rgbBlue  = _local_palette.palette[start + i].b;
 
		rgb[i].rgbReserved = 0;
 
	}
 

	
 
	SetDIBColorTable(dc, start, count, rgb);
 
}
 

	
 
bool VideoDriver_Win32::ClaimMousePointer()
 
bool VideoDriver_Win32Base::ClaimMousePointer()
 
{
 
	MyShowCursor(false, true);
 
	return true;
 
}
 

	
 
struct Win32VkMapping {
 
	byte vk_from;
 
	byte vk_count;
 
	byte map_to;
 
};
 

	
 
#define AS(x, z) {x, 0, z}
 
@@ -222,25 +222,25 @@ int RedrawScreenDebug()
 
	DeleteDC(dc2);
 
	ReleaseDC(_wnd.main_wnd, dc);
 

	
 
	return _fooctr++;
 
}
 
#endif
 

	
 
/**
 
 * Instantiate a new window.
 
 * @param full_screen Whether to make a full screen window or not.
 
 * @return True if the window could be created.
 
 */
 
bool VideoDriver_Win32::MakeWindow(bool full_screen)
 
bool VideoDriver_Win32Base::MakeWindow(bool full_screen)
 
{
 
	/* full_screen is whether the new window should be fullscreen,
 
	 * _wnd.fullscreen is whether the current window is. */
 
	_fullscreen = full_screen;
 

	
 
	/* recreate window? */
 
	if ((full_screen || _wnd.fullscreen) && _wnd.main_wnd) {
 
		DestroyWindow(_wnd.main_wnd);
 
		_wnd.main_wnd = 0;
 
	}
 

	
 
	if (full_screen) {
 
@@ -306,38 +306,38 @@ bool VideoDriver_Win32::MakeWindow(bool 
 
		w = r.right - r.left;
 
		h = r.bottom - r.top;
 

	
 
		if (_wnd.main_wnd != nullptr) {
 
			if (!_window_maximize) SetWindowPos(_wnd.main_wnd, 0, 0, 0, w, h, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
 
		} else {
 
			int x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2;
 
			int y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;
 

	
 
			char window_title[64];
 
			seprintf(window_title, lastof(window_title), "OpenTTD %s", _openttd_revision);
 

	
 
			_wnd.main_wnd = CreateWindow(_T("OTTD"), MB_TO_WIDE(window_title), style, x, y, w, h, 0, 0, GetModuleHandle(nullptr), 0);
 
			_wnd.main_wnd = CreateWindow(_T("OTTD"), MB_TO_WIDE(window_title), style, x, y, w, h, 0, 0, GetModuleHandle(nullptr), this);
 
			if (_wnd.main_wnd == nullptr) usererror("CreateWindow failed");
 
			ShowWindow(_wnd.main_wnd, showstyle);
 
		}
 
	}
 

	
 
	BlitterFactory::GetCurrentBlitter()->PostResize();
 

	
 
	GameSizeChanged(); // invalidate all windows, force redraw
 
	return true; // the request succeeded
 
}
 

	
 
/** Do palette animation and blit to the window. */
 
void VideoDriver_Win32::Paint()
 
void VideoDriver_Win32Base::Paint()
 
{
 
	PerformanceMeasurer framerate(PFE_VIDEO);
 

	
 
	if (IsEmptyRect(_dirty_rect)) return;
 

	
 
	HDC dc = GetDC(_wnd.main_wnd);
 
	HDC dc2 = CreateCompatibleDC(dc);
 

	
 
	HBITMAP old_bmp = (HBITMAP)SelectObject(dc2, _wnd.dib_sect);
 
	HPALETTE old_palette = SelectPalette(dc, _wnd.gdi_palette, FALSE);
 

	
 
	if (_cur_palette.count_dirty != 0) {
 
@@ -362,44 +362,44 @@ void VideoDriver_Win32::Paint()
 
	}
 

	
 
	BitBlt(dc, 0, 0, _wnd.width, _wnd.height, dc2, 0, 0, SRCCOPY);
 
	SelectPalette(dc, old_palette, TRUE);
 
	SelectObject(dc2, old_bmp);
 
	DeleteDC(dc2);
 

	
 
	ReleaseDC(_wnd.main_wnd, dc);
 

	
 
	_dirty_rect = {};
 
}
 

	
 
void VideoDriver_Win32::PaintThread()
 
void VideoDriver_Win32Base::PaintThread()
 
{
 
	/* First tell the main thread we're started */
 
	std::unique_lock<std::recursive_mutex> lock(*_draw_mutex);
 
	_draw_signal->notify_one();
 

	
 
	/* Now wait for the first thing to draw! */
 
	_draw_signal->wait(*_draw_mutex);
 

	
 
	while (_draw_continue) {
 
		this->Paint();
 

	
 
		/* Flush GDI buffer to ensure drawing here doesn't conflict with any GDI usage in the main WndProc. */
 
		GdiFlush();
 

	
 
		_draw_signal->wait(*_draw_mutex);
 
	}
 
}
 

	
 
/* static */ void VideoDriver_Win32::PaintThreadThunk(VideoDriver_Win32 *drv)
 
/* static */ void VideoDriver_Win32Base::PaintThreadThunk(VideoDriver_Win32Base *drv)
 
{
 
	drv->PaintThread();
 
}
 

	
 
/** Forward key presses to the window system. */
 
static LRESULT HandleCharMsg(uint keycode, WChar charcode)
 
{
 
#if !defined(UNICODE)
 
	static char prev_char = 0;
 

	
 
	char input[2] = {(char)charcode, 0};
 
	int input_len = 1;
 
@@ -585,58 +585,61 @@ static LRESULT HandleIMEComposition(HWND
 
}
 

	
 
/** Clear the current composition string. */
 
static void CancelIMEComposition(HWND hwnd)
 
{
 
	HIMC hIMC = ImmGetContext(hwnd);
 
	if (hIMC != NULL) ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
 
	ImmReleaseContext(hwnd, hIMC);
 
	/* Clear any marked string from the current edit box. */
 
	HandleTextInput(nullptr, true);
 
}
 

	
 
static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
{
 
	static uint32 keycode = 0;
 
	static bool console = false;
 

	
 
	VideoDriver_Win32Base *video_driver = (VideoDriver_Win32Base *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
 

	
 
	switch (msg) {
 
		case WM_CREATE:
 
			SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)((LPCREATESTRUCT)lParam)->lpCreateParams);
 
			_cursor.in_window = false; // Win32 has mouse tracking.
 
			SetCompositionPos(hwnd);
 
			_imm_props = ImmGetProperty(GetKeyboardLayout(0), IGP_PROPERTY);
 
			break;
 

	
 
		case WM_PAINT: {
 
			RECT r;
 
			GetUpdateRect(hwnd, &r, FALSE);
 
			static_cast<VideoDriver_Win32 *>(VideoDriver::GetInstance())->MakeDirty(r.left, r.top, r.right - r.left, r.bottom - r.top);
 
			video_driver->MakeDirty(r.left, r.top, r.right - r.left, r.bottom - r.top);
 

	
 
			ValidateRect(hwnd, nullptr);
 
			return 0;
 
		}
 

	
 
		case WM_PALETTECHANGED:
 
			if ((HWND)wParam == hwnd) return 0;
 
			FALLTHROUGH;
 

	
 
		case WM_QUERYNEWPALETTE: {
 
			HDC hDC = GetWindowDC(hwnd);
 
			HPALETTE hOldPalette = SelectPalette(hDC, _wnd.gdi_palette, FALSE);
 
			UINT nChanged = RealizePalette(hDC);
 

	
 
			SelectPalette(hDC, hOldPalette, TRUE);
 
			ReleaseDC(hwnd, hDC);
 
			if (nChanged != 0) {
 
				static_cast<VideoDriver_Win32 *>(VideoDriver::GetInstance())->MakeDirty(0, 0, _screen.width, _screen.height);
 
				video_driver->MakeDirty(0, 0, _screen.width, _screen.height);
 
			}
 
			return 0;
 
		}
 

	
 
		case WM_CLOSE:
 
			HandleExitGameRequest();
 
			return 0;
 

	
 
		case WM_DESTROY:
 
			if (_window_maximize) _cur_resolution = _bck_resolution;
 
			return 0;
 

	
 
@@ -928,25 +931,25 @@ static LRESULT CALLBACK WndProcGdi(HWND 
 
			break;
 

	
 
		case WM_ACTIVATE: {
 
			/* Don't do anything if we are closing openttd */
 
			if (_exit_game) break;
 

	
 
			bool active = (LOWORD(wParam) != WA_INACTIVE);
 
			bool minimized = (HIWORD(wParam) != 0);
 
			if (_wnd.fullscreen) {
 
				if (active && minimized) {
 
					/* Restore the game window */
 
					ShowWindow(hwnd, SW_RESTORE);
 
					static_cast<VideoDriver_Win32 *>(VideoDriver::GetInstance())->MakeWindow(true);
 
					video_driver->MakeWindow(true);
 
				} else if (!active && !minimized) {
 
					/* Minimise the window and restore desktop */
 
					ShowWindow(hwnd, SW_MINIMIZE);
 
					ChangeDisplaySettings(nullptr, 0);
 
				}
 
			}
 
			break;
 
		}
 
	}
 

	
 
	return DefWindowProc(hwnd, msg, wParam, lParam);
 
}
 
@@ -1044,81 +1047,39 @@ static void FindResolutions()
 
		if (std::find(_resolutions.begin(), _resolutions.end(), Dimension(dm.dmPelsWidth, dm.dmPelsHeight)) != _resolutions.end()) continue;
 
		_resolutions.emplace_back(dm.dmPelsWidth, dm.dmPelsHeight);
 
	}
 

	
 
	/* We have found no resolutions, show the default list */
 
	if (_resolutions.empty()) {
 
		_resolutions.assign(std::begin(default_resolutions), std::end(default_resolutions));
 
	}
 

	
 
	SortResolutions();
 
}
 

	
 
static FVideoDriver_Win32 iFVideoDriver_Win32;
 

	
 
const char *VideoDriver_Win32::Start(const StringList &parm)
 
{
 
	if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) return "Only real blitters supported";
 

	
 
	this->UpdateAutoResolution();
 

	
 
	memset(&_wnd, 0, sizeof(_wnd));
 

	
 
	RegisterWndClass();
 

	
 
	MakePalette();
 

	
 
	FindResolutions();
 

	
 
	DEBUG(driver, 2, "Resolution for display: %ux%u", _cur_resolution.width, _cur_resolution.height);
 

	
 
	/* fullscreen uses those */
 
	_wnd.width_org  = _cur_resolution.width;
 
	_wnd.height_org = _cur_resolution.height;
 

	
 
	AllocateDibSection(_cur_resolution.width, _cur_resolution.height);
 
	this->MakeWindow(_fullscreen);
 

	
 
	MarkWholeScreenDirty();
 

	
 
	_draw_threaded = !GetDriverParamBool(parm, "no_threads") && !GetDriverParamBool(parm, "no_thread") && std::thread::hardware_concurrency() > 1;
 

	
 
	return nullptr;
 
}
 

	
 
void VideoDriver_Win32::Stop()
 
{
 
	DeleteObject(_wnd.gdi_palette);
 
	DeleteObject(_wnd.dib_sect);
 
	DestroyWindow(_wnd.main_wnd);
 

	
 
	if (_wnd.fullscreen) ChangeDisplaySettings(nullptr, 0);
 
	MyShowCursor(true);
 
}
 

	
 
void VideoDriver_Win32::MakeDirty(int left, int top, int width, int height)
 
void VideoDriver_Win32Base::MakeDirty(int left, int top, int width, int height)
 
{
 
	Rect r = {left, top, left + width, top + height};
 
	_dirty_rect = BoundingRect(_dirty_rect, r);
 
}
 

	
 
void VideoDriver_Win32::CheckPaletteAnim()
 
void VideoDriver_Win32Base::CheckPaletteAnim()
 
{
 
	if (_cur_palette.count_dirty == 0) return;
 

	
 
	_local_palette = _cur_palette;
 
	this->MakeDirty(0, 0, _screen.width, _screen.height);
 
}
 

	
 
void VideoDriver_Win32::InputLoop()
 
void VideoDriver_Win32Base::InputLoop()
 
{
 
	bool old_ctrl_pressed = _ctrl_pressed;
 

	
 
	_ctrl_pressed = _wnd.has_focus && GetAsyncKeyState(VK_CONTROL) < 0;
 
	_shift_pressed = _wnd.has_focus && GetAsyncKeyState(VK_SHIFT) < 0;
 

	
 
#if defined(_DEBUG)
 
	if (_shift_pressed)
 
#else
 
	/* Speedup when pressing tab, except when using ALT+TAB
 
	 * to switch to another application. */
 
	if (_wnd.has_focus && GetAsyncKeyState(VK_TAB) < 0 && GetAsyncKeyState(VK_MENU) >= 0)
 
@@ -1134,45 +1095,45 @@ void VideoDriver_Win32::InputLoop()
 
		_dirkeys =
 
			(GetAsyncKeyState(VK_LEFT) < 0 ? 1 : 0) +
 
			(GetAsyncKeyState(VK_UP) < 0 ? 2 : 0) +
 
			(GetAsyncKeyState(VK_RIGHT) < 0 ? 4 : 0) +
 
			(GetAsyncKeyState(VK_DOWN) < 0 ? 8 : 0);
 
	} else {
 
		_dirkeys = 0;
 
	}
 

	
 
	if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
 
}
 

	
 
void VideoDriver_Win32::MainLoop()
 
void VideoDriver_Win32Base::MainLoop()
 
{
 
	MSG mesg;
 

	
 
	std::thread draw_thread;
 

	
 
	if (_draw_threaded) {
 
		/* Initialise the mutex first, because that's the thing we *need*
 
		 * directly in the newly created thread. */
 
		try {
 
			_draw_signal = new std::condition_variable_any();
 
			_draw_mutex = new std::recursive_mutex();
 
		} catch (...) {
 
			_draw_threaded = false;
 
		}
 

	
 
		if (_draw_threaded) {
 
			this->draw_lock = std::unique_lock<std::recursive_mutex>(*_draw_mutex);
 

	
 
			_draw_continue = true;
 
			_draw_threaded = StartNewThread(&draw_thread, "ottd:draw-win32", &VideoDriver_Win32::PaintThreadThunk, this);
 
			_draw_threaded = StartNewThread(&draw_thread, "ottd:draw-win32", &VideoDriver_Win32Base::PaintThreadThunk, this);
 

	
 
			/* Free the mutex if we won't be able to use it. */
 
			if (!_draw_threaded) {
 
				this->draw_lock.unlock();
 
				this->draw_lock.release();
 
				delete _draw_mutex;
 
				delete _draw_signal;
 
				_draw_mutex = nullptr;
 
				_draw_signal = nullptr;
 
			} else {
 
				DEBUG(driver, 1, "Threaded drawing enabled");
 
				/* Wait till the draw thread has started itself. */
 
@@ -1213,77 +1174,71 @@ void VideoDriver_Win32::MainLoop()
 
		_draw_signal->notify_all();
 
		if (this->draw_lock.owns_lock()) this->draw_lock.unlock();
 
		this->draw_lock.release();
 
		draw_thread.join();
 

	
 
		delete _draw_mutex;
 
		delete _draw_signal;
 

	
 
		_draw_mutex = nullptr;
 
	}
 
}
 

	
 
bool VideoDriver_Win32::ChangeResolution(int w, int h)
 
bool VideoDriver_Win32Base::ChangeResolution(int w, int h)
 
{
 
	std::unique_lock<std::recursive_mutex> lock;
 
	if (_draw_mutex != nullptr) lock = std::unique_lock<std::recursive_mutex>(*_draw_mutex);
 

	
 
	if (_window_maximize) ShowWindow(_wnd.main_wnd, SW_SHOWNORMAL);
 

	
 
	_wnd.width = _wnd.width_org = w;
 
	_wnd.height = _wnd.height_org = h;
 

	
 
	return this->MakeWindow(_fullscreen); // _wnd.fullscreen screws up ingame resolution switching
 
}
 

	
 
bool VideoDriver_Win32::ToggleFullscreen(bool full_screen)
 
bool VideoDriver_Win32Base::ToggleFullscreen(bool full_screen)
 
{
 
	std::unique_lock<std::recursive_mutex> lock;
 
	if (_draw_mutex != nullptr) lock = std::unique_lock<std::recursive_mutex>(*_draw_mutex);
 

	
 
	return this->MakeWindow(full_screen);
 
}
 

	
 
bool VideoDriver_Win32::AfterBlitterChange()
 
{
 
	assert(BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 0);
 
	return AllocateDibSection(_screen.width, _screen.height, true) && this->MakeWindow(_fullscreen);
 
}
 

	
 
void VideoDriver_Win32::AcquireBlitterLock()
 
void VideoDriver_Win32Base::AcquireBlitterLock()
 
{
 
	if (_draw_mutex != nullptr) _draw_mutex->lock();
 
}
 

	
 
void VideoDriver_Win32::ReleaseBlitterLock()
 
void VideoDriver_Win32Base::ReleaseBlitterLock()
 
{
 
	if (_draw_mutex != nullptr) _draw_mutex->unlock();
 
}
 

	
 
void VideoDriver_Win32::EditBoxLostFocus()
 
void VideoDriver_Win32Base::EditBoxLostFocus()
 
{
 
	std::unique_lock<std::recursive_mutex> lock;
 
	if (_draw_mutex != nullptr) lock = std::unique_lock<std::recursive_mutex>(*_draw_mutex);
 

	
 
	CancelIMEComposition(_wnd.main_wnd);
 
	SetCompositionPos(_wnd.main_wnd);
 
	SetCandidatePos(_wnd.main_wnd);
 
}
 

	
 
Dimension VideoDriver_Win32::GetScreenSize() const
 
Dimension VideoDriver_Win32Base::GetScreenSize() const
 
{
 
	return { static_cast<uint>(GetSystemMetrics(SM_CXSCREEN)), static_cast<uint>(GetSystemMetrics(SM_CYSCREEN)) };
 
}
 

	
 
float VideoDriver_Win32::GetDPIScale()
 
float VideoDriver_Win32Base::GetDPIScale()
 
{
 
	typedef UINT (WINAPI *PFNGETDPIFORWINDOW)(HWND hwnd);
 
	typedef UINT (WINAPI *PFNGETDPIFORSYSTEM)(VOID);
 
	typedef HRESULT (WINAPI *PFNGETDPIFORMONITOR)(HMONITOR hMonitor, int dpiType, UINT *dpiX, UINT *dpiY);
 

	
 
	static PFNGETDPIFORWINDOW _GetDpiForWindow = nullptr;
 
	static PFNGETDPIFORSYSTEM _GetDpiForSystem = nullptr;
 
	static PFNGETDPIFORMONITOR _GetDpiForMonitor = nullptr;
 

	
 
	static bool init_done = false;
 
	if (!init_done) {
 
		init_done = true;
 
@@ -1305,22 +1260,71 @@ float VideoDriver_Win32::GetDPIScale()
 
		if (SUCCEEDED(_GetDpiForMonitor(MonitorFromWindow(_wnd.main_wnd, MONITOR_DEFAULTTOPRIMARY), 0 /* MDT_EFFECTIVE_DPI */, &dpiX, &dpiY))) {
 
			cur_dpi = dpiX; // X and Y are always identical.
 
		}
 
	}
 
	if (cur_dpi == 0 && _GetDpiForSystem != nullptr) {
 
		/* Fall back to system DPI. */
 
		cur_dpi = _GetDpiForSystem();
 
	}
 

	
 
	return cur_dpi > 0 ? cur_dpi / 96.0f : 1.0f; // Default Windows DPI value is 96.
 
}
 

	
 
bool VideoDriver_Win32::LockVideoBuffer()
 
bool VideoDriver_Win32Base::LockVideoBuffer()
 
{
 
	if (_draw_threaded) this->draw_lock.lock();
 
	return true;
 
}
 

	
 
void VideoDriver_Win32::UnlockVideoBuffer()
 
void VideoDriver_Win32Base::UnlockVideoBuffer()
 
{
 
	if (_draw_threaded) this->draw_lock.unlock();
 
}
 

	
 

	
 
static FVideoDriver_Win32GDI iFVideoDriver_Win32GDI;
 

	
 
const char *VideoDriver_Win32GDI::Start(const StringList &param)
 
{
 
	if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) return "Only real blitters supported";
 

	
 
	this->UpdateAutoResolution();
 

	
 
	memset(&_wnd, 0, sizeof(_wnd));
 

	
 
	RegisterWndClass();
 

	
 
	MakePalette();
 

	
 
	FindResolutions();
 

	
 
	DEBUG(driver, 2, "Resolution for display: %ux%u", _cur_resolution.width, _cur_resolution.height);
 

	
 
	/* fullscreen uses those */
 
	_wnd.width_org = _cur_resolution.width;
 
	_wnd.height_org = _cur_resolution.height;
 

	
 
	AllocateDibSection(_cur_resolution.width, _cur_resolution.height);
 
	this->MakeWindow(_fullscreen);
 

	
 
	MarkWholeScreenDirty();
 

	
 
	_draw_threaded = !GetDriverParam(param, "no_threads") && !GetDriverParam(param, "no_thread") && std::thread::hardware_concurrency() > 1;
 

	
 
	return nullptr;
 
}
 

	
 
void VideoDriver_Win32GDI::Stop()
 
{
 
	DeleteObject(_wnd.gdi_palette);
 
	DeleteObject(_wnd.dib_sect);
 
	DestroyWindow(_wnd.main_wnd);
 

	
 
	if (_wnd.fullscreen) ChangeDisplaySettings(nullptr, 0);
 
	MyShowCursor(true);
 
}
 

	
 
bool VideoDriver_Win32GDI::AfterBlitterChange()
 
{
 
	assert(BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 0);
 
	return AllocateDibSection(_screen.width, _screen.height, true) && this->MakeWindow(_fullscreen);
 
}
src/video/win32_v.h
Show inline comments
 
@@ -3,65 +3,70 @@
 
 * 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 win32_v.h Base of the Windows video driver. */
 

	
 
#ifndef VIDEO_WIN32_H
 
#define VIDEO_WIN32_H
 

	
 
#include "video_driver.hpp"
 

	
 
/** The video driver for windows. */
 
class VideoDriver_Win32 : public VideoDriver {
 
/** Base class for Windows video drivers. */
 
class VideoDriver_Win32Base : public VideoDriver {
 
public:
 
	const char *Start(const StringList &param) override;
 

	
 
	void Stop() override;
 

	
 
	void MakeDirty(int left, int top, int width, int height) override;
 

	
 
	void MainLoop() override;
 

	
 
	bool ChangeResolution(int w, int h) override;
 

	
 
	bool ToggleFullscreen(bool fullscreen) override;
 

	
 
	bool AfterBlitterChange() override;
 

	
 
	void AcquireBlitterLock() override;
 

	
 
	void ReleaseBlitterLock() override;
 

	
 
	bool ClaimMousePointer() override;
 

	
 
	void EditBoxLostFocus() override;
 

	
 
	const char *GetName() const override { return "win32"; }
 

	
 
	bool MakeWindow(bool full_screen);
 

	
 
protected:
 
	Dimension GetScreenSize() const override;
 
	float GetDPIScale() override;
 
	void InputLoop() override;
 
	bool LockVideoBuffer() override;
 
	void UnlockVideoBuffer() override;
 
	void Paint() override;
 
	void PaintThread() override;
 
	void CheckPaletteAnim() override;
 

	
 
	bool MakeWindow(bool full_screen);
 

	
 
private:
 
	std::unique_lock<std::recursive_mutex> draw_lock;
 

	
 
	static void PaintThreadThunk(VideoDriver_Win32 *drv);
 
	static void PaintThreadThunk(VideoDriver_Win32Base *drv);
 

	
 
	friend LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
 
};
 
/** The GDI video driver for windows. */
 
class VideoDriver_Win32GDI : public VideoDriver_Win32Base {
 
public:
 
	const char *Start(const StringList &param) override;
 

	
 
	void Stop() override;
 

	
 
	bool AfterBlitterChange() override;
 

	
 
	const char *GetName() const override { return "win32"; }
 
};
 

	
 
/** The factory for Windows' video driver. */
 
class FVideoDriver_Win32 : public DriverFactoryBase {
 
class FVideoDriver_Win32GDI : public DriverFactoryBase {
 
public:
 
	FVideoDriver_Win32() : DriverFactoryBase(Driver::DT_VIDEO, 10, "win32", "Win32 GDI Video Driver") {}
 
	Driver *CreateInstance() const override { return new VideoDriver_Win32(); }
 
	FVideoDriver_Win32GDI() : DriverFactoryBase(Driver::DT_VIDEO, 10, "win32", "Win32 GDI Video Driver") {}
 
	Driver *CreateInstance() const override { return new VideoDriver_Win32GDI(); }
 
};
 

	
 
#endif /* VIDEO_WIN32_H */
0 comments (0 inline, 0 general)