Changeset - r24877:41f1a39844df
[Not reviewed]
master
0 2 0
Michael Lutz - 3 years ago 2021-01-16 15:43:02
michi@icosahedron.de
Codechange: [Win32] Move GDI-specific variables and related functions into the GDI video driver class.
2 files changed with 103 insertions and 98 deletions:
0 comments (0 inline, 0 general)
src/video/win32_v.cpp
Show inline comments
 
@@ -41,10 +41,7 @@
 
#endif
 

	
 
static struct {
 
	HWND main_wnd;        ///< Handle to system window.
 
	HBITMAP dib_sect;     ///< System bitmap object referencing our rendering buffer.
 
	void *buffer_bits;    ///< Internal rendering buffer.
 
	HPALETTE gdi_palette; ///< Palette object for 8bpp blitter.
 
	int width;            ///< Width in pixels of our display surface.
 
	int height;           ///< Height in pixels of our display surface.
 
	int width_org;        ///< Original monitor resolution width, before we changed it.
 
@@ -71,43 +68,6 @@ static Palette _local_palette;
 
/** Region of the screen that needs redrawing. */
 
static Rect _dirty_rect;
 

	
 
static void MakePalette()
 
{
 
	_cur_palette.first_dirty = 0;
 
	_cur_palette.count_dirty = 256;
 
	_local_palette = _cur_palette;
 

	
 
	LOGPALETTE *pal = (LOGPALETTE*)alloca(sizeof(LOGPALETTE) + (256 - 1) * sizeof(PALETTEENTRY));
 

	
 
	pal->palVersion = 0x300;
 
	pal->palNumEntries = 256;
 

	
 
	for (uint i = 0; i != 256; i++) {
 
		pal->palPalEntry[i].peRed   = _local_palette.palette[i].r;
 
		pal->palPalEntry[i].peGreen = _local_palette.palette[i].g;
 
		pal->palPalEntry[i].peBlue  = _local_palette.palette[i].b;
 
		pal->palPalEntry[i].peFlags = 0;
 

	
 
	}
 
	_wnd.gdi_palette = CreatePalette(pal);
 
	if (_wnd.gdi_palette == nullptr) usererror("CreatePalette failed!\n");
 
}
 

	
 
static void UpdatePalette(HDC dc, uint start, uint count)
 
{
 
	RGBQUAD rgb[256];
 
	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_Win32Base::ClaimMousePointer()
 
{
 
	MyShowCursor(false, true);
 
@@ -182,33 +142,6 @@ static uint MapWindowsKey(uint sym)
 
	return key;
 
}
 

	
 
#ifdef _DEBUG
 
/* Keep this function here..
 
 * It allows you to redraw the screen from within the MSVC debugger */
 
int RedrawScreenDebug()
 
{
 
	HDC dc, dc2;
 
	static int _fooctr;
 
	HBITMAP old_bmp;
 
	HPALETTE old_palette;
 

	
 
	UpdateWindows();
 

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

	
 
	old_bmp = (HBITMAP)SelectObject(dc2, _wnd.dib_sect);
 
	old_palette = SelectPalette(dc, _wnd.gdi_palette, FALSE);
 
	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);
 

	
 
	return _fooctr++;
 
}
 
#endif
 

	
 
/**
 
 * Instantiate a new window.
 
 * @param full_screen Whether to make a full screen window or not.
 
@@ -221,9 +154,9 @@ bool VideoDriver_Win32Base::MakeWindow(b
 
	_fullscreen = full_screen;
 

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

	
 
	if (full_screen) {
 
@@ -289,8 +222,8 @@ bool VideoDriver_Win32Base::MakeWindow(b
 
		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);
 
		if (this->main_wnd != nullptr) {
 
			if (!_window_maximize) SetWindowPos(this->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;
 
@@ -298,16 +231,16 @@ bool VideoDriver_Win32Base::MakeWindow(b
 
			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), this);
 
			if (_wnd.main_wnd == nullptr) usererror("CreateWindow failed");
 
			ShowWindow(_wnd.main_wnd, showstyle);
 
			this->main_wnd = CreateWindow(_T("OTTD"), MB_TO_WIDE(window_title), style, x, y, w, h, 0, 0, GetModuleHandle(nullptr), this);
 
			if (this->main_wnd == nullptr) usererror("CreateWindow failed");
 
			ShowWindow(this->main_wnd, showstyle);
 
		}
 
	}
 

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

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

	
 
/* static */ void VideoDriver_Win32Base::PaintThreadThunk(VideoDriver_Win32Base *drv)
 
@@ -1077,7 +1010,7 @@ bool VideoDriver_Win32Base::ChangeResolu
 
	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);
 
	if (_window_maximize) ShowWindow(this->main_wnd, SW_SHOWNORMAL);
 

	
 
	_wnd.width = _wnd.width_org = w;
 
	_wnd.height = _wnd.height_org = h;
 
@@ -1108,9 +1041,9 @@ void VideoDriver_Win32Base::EditBoxLostF
 
	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);
 
	CancelIMEComposition(this->main_wnd);
 
	SetCompositionPos(this->main_wnd);
 
	SetCandidatePos(this->main_wnd);
 
}
 

	
 
Dimension VideoDriver_Win32Base::GetScreenSize() const
 
@@ -1139,14 +1072,14 @@ float VideoDriver_Win32Base::GetDPIScale
 

	
 
	UINT cur_dpi = 0;
 

	
 
	if (cur_dpi == 0 && _GetDpiForWindow != nullptr && _wnd.main_wnd != nullptr) {
 
	if (cur_dpi == 0 && _GetDpiForWindow != nullptr && this->main_wnd != nullptr) {
 
		/* Per window DPI is supported since Windows 10 Ver 1607. */
 
		cur_dpi = _GetDpiForWindow(_wnd.main_wnd);
 
		cur_dpi = _GetDpiForWindow(this->main_wnd);
 
	}
 
	if (cur_dpi == 0 && _GetDpiForMonitor != nullptr && _wnd.main_wnd != nullptr) {
 
	if (cur_dpi == 0 && _GetDpiForMonitor != nullptr && this->main_wnd != nullptr) {
 
		/* Per monitor is supported since Windows 8.1. */
 
		UINT dpiX, dpiY;
 
		if (SUCCEEDED(_GetDpiForMonitor(MonitorFromWindow(_wnd.main_wnd, MONITOR_DEFAULTTOPRIMARY), 0 /* MDT_EFFECTIVE_DPI */, &dpiX, &dpiY))) {
 
		if (SUCCEEDED(_GetDpiForMonitor(MonitorFromWindow(this->main_wnd, MONITOR_DEFAULTTOPRIMARY), 0 /* MDT_EFFECTIVE_DPI */, &dpiX, &dpiY))) {
 
			cur_dpi = dpiX; // X and Y are always identical.
 
		}
 
	}
 
@@ -1182,7 +1115,7 @@ const char *VideoDriver_Win32GDI::Start(
 

	
 
	RegisterWndClass();
 

	
 
	MakePalette();
 
	this->MakePalette();
 

	
 
	FindResolutions();
 

	
 
@@ -1204,9 +1137,9 @@ const char *VideoDriver_Win32GDI::Start(
 

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

	
 
	if (_wnd.fullscreen) ChangeDisplaySettings(nullptr, 0);
 
	MyShowCursor(true);
 
@@ -1232,11 +1165,11 @@ bool VideoDriver_Win32GDI::AllocateBacki
 
	bi->bmiHeader.biBitCount = bpp;
 
	bi->bmiHeader.biCompression = BI_RGB;
 

	
 
	if (_wnd.dib_sect) DeleteObject(_wnd.dib_sect);
 
	if (this->dib_sect) DeleteObject(this->dib_sect);
 

	
 
	HDC dc = GetDC(0);
 
	_wnd.dib_sect = CreateDIBSection(dc, bi, DIB_RGB_COLORS, (VOID **)&_wnd.buffer_bits, nullptr, 0);
 
	if (_wnd.dib_sect == nullptr) usererror("CreateDIBSection failed");
 
	this->dib_sect = CreateDIBSection(dc, bi, DIB_RGB_COLORS, (VOID **)&_wnd.buffer_bits, nullptr, 0);
 
	if (this->dib_sect == nullptr) usererror("CreateDIBSection failed");
 
	ReleaseDC(0, dc);
 

	
 
	_screen.width = w;
 
@@ -1253,10 +1186,46 @@ bool VideoDriver_Win32GDI::AfterBlitterC
 
	return this->AllocateBackingStore(_screen.width, _screen.height, true) && this->MakeWindow(_fullscreen);
 
}
 

	
 
void VideoDriver_Win32GDI::MakePalette()
 
{
 
	_cur_palette.first_dirty = 0;
 
	_cur_palette.count_dirty = 256;
 
	_local_palette = _cur_palette;
 

	
 
	LOGPALETTE *pal = (LOGPALETTE*)alloca(sizeof(LOGPALETTE) + (256 - 1) * sizeof(PALETTEENTRY));
 

	
 
	pal->palVersion = 0x300;
 
	pal->palNumEntries = 256;
 

	
 
	for (uint i = 0; i != 256; i++) {
 
		pal->palPalEntry[i].peRed   = _local_palette.palette[i].r;
 
		pal->palPalEntry[i].peGreen = _local_palette.palette[i].g;
 
		pal->palPalEntry[i].peBlue  = _local_palette.palette[i].b;
 
		pal->palPalEntry[i].peFlags = 0;
 

	
 
	}
 
	this->gdi_palette = CreatePalette(pal);
 
	if (this->gdi_palette == nullptr) usererror("CreatePalette failed!\n");
 
}
 

	
 
void VideoDriver_Win32GDI::UpdatePalette(HDC dc, uint start, uint count)
 
{
 
	RGBQUAD rgb[256];
 

	
 
	for (uint 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);
 
}
 

	
 
void VideoDriver_Win32GDI::PaletteChanged(HWND hWnd)
 
{
 
	HDC hDC = GetWindowDC(hWnd);
 
	HPALETTE hOldPalette = SelectPalette(hDC, _wnd.gdi_palette, FALSE);
 
	HPALETTE hOldPalette = SelectPalette(hDC, this->gdi_palette, FALSE);
 
	UINT nChanged = RealizePalette(hDC);
 

	
 
	SelectPalette(hDC, hOldPalette, TRUE);
 
@@ -1270,18 +1239,18 @@ void VideoDriver_Win32GDI::Paint()
 

	
 
	if (IsEmptyRect(_dirty_rect)) return;
 

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

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

	
 
	if (_cur_palette.count_dirty != 0) {
 
		Blitter *blitter = BlitterFactory::GetCurrentBlitter();
 

	
 
		switch (blitter->UsePaletteAnimation()) {
 
			case Blitter::PALETTE_ANIMATION_VIDEO_BACKEND:
 
				UpdatePalette(dc2, _local_palette.first_dirty, _local_palette.count_dirty);
 
				this->UpdatePalette(dc2, _local_palette.first_dirty, _local_palette.count_dirty);
 
				break;
 

	
 
			case Blitter::PALETTE_ANIMATION_BLITTER:
 
@@ -1302,7 +1271,7 @@ void VideoDriver_Win32GDI::Paint()
 
	SelectObject(dc2, old_bmp);
 
	DeleteDC(dc2);
 

	
 
	ReleaseDC(_wnd.main_wnd, dc);
 
	ReleaseDC(this->main_wnd, dc);
 

	
 
	_dirty_rect = {};
 
}
 
@@ -1325,3 +1294,23 @@ void VideoDriver_Win32GDI::PaintThread()
 
		_draw_signal->wait(*_draw_mutex);
 
	}
 
}
 

	
 

	
 
#ifdef _DEBUG
 
/* Keep this function here..
 
 * It allows you to redraw the screen from within the MSVC debugger */
 
/* static */ int VideoDriver_Win32GDI::RedrawScreenDebug()
 
{
 
	static int _fooctr;
 

	
 
	_screen.dst_ptr = _wnd.buffer_bits;
 
	UpdateWindows();
 

	
 
	VideoDriver_Win32GDI *drv = static_cast<VideoDriver_Win32GDI *>(VideoDriver::GetInstance());
 

	
 
	drv->Paint();
 
	GdiFlush();
 

	
 
	return _fooctr++;
 
}
 
#endif
src/video/win32_v.h
Show inline comments
 
@@ -15,6 +15,8 @@
 
/** Base class for Windows video drivers. */
 
class VideoDriver_Win32Base : public VideoDriver {
 
public:
 
	VideoDriver_Win32Base() : main_wnd(nullptr) {}
 

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

	
 
	void MainLoop() override;
 
@@ -32,6 +34,8 @@ public:
 
	void EditBoxLostFocus() override;
 

	
 
protected:
 
	HWND    main_wnd;      ///< Handle to system window.
 

	
 
	Dimension GetScreenSize() const override;
 
	float GetDPIScale() override;
 
	void InputLoop() override;
 
@@ -58,6 +62,8 @@ private:
 
/** The GDI video driver for windows. */
 
class VideoDriver_Win32GDI : public VideoDriver_Win32Base {
 
public:
 
	VideoDriver_Win32GDI() : dib_sect(nullptr), gdi_palette(nullptr) {}
 

	
 
	const char *Start(const StringList &param) override;
 

	
 
	void Stop() override;
 
@@ -67,11 +73,21 @@ public:
 
	const char *GetName() const override { return "win32"; }
 

	
 
protected:
 
	HBITMAP  dib_sect;      ///< System bitmap object referencing our rendering buffer.
 
	HPALETTE gdi_palette;   ///< Palette object for 8bpp blitter.
 

	
 
	void Paint() override;
 
	void PaintThread() override;
 

	
 
	bool AllocateBackingStore(int w, int h, bool force = false) override;
 
	void PaletteChanged(HWND hWnd) override;
 
	void MakePalette();
 
	void UpdatePalette(HDC dc, uint start, uint count);
 

	
 
#ifdef _DEBUG
 
public:
 
	static int RedrawScreenDebug();
 
#endif
 
};
 

	
 
/** The factory for Windows' video driver. */
0 comments (0 inline, 0 general)