From 78b8fc3e4fea1f1788ea793c4e9cf1e39898135a Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sat, 16 Jan 2021 16:43:02 +0100 Subject: Codechange: [Win32] Move GDI-specific variables and related functions into the GDI video driver class. --- src/video/win32_v.cpp | 185 ++++++++++++++++++++++++-------------------------- src/video/win32_v.h | 16 +++++ 2 files changed, 103 insertions(+), 98 deletions(-) (limited to 'src') diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp index 73c01dea1..58dad7851 100644 --- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -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(bool full_screen) _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(bool full_screen) 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(bool full_screen) 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::ChangeResolution(int w, int h) std::unique_lock lock; if (_draw_mutex != nullptr) lock = std::unique_lock(*_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::EditBoxLostFocus() std::unique_lock lock; if (_draw_mutex != nullptr) lock = std::unique_lock(*_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(const StringList ¶m) RegisterWndClass(); - MakePalette(); + this->MakePalette(); FindResolutions(); @@ -1204,9 +1137,9 @@ const char *VideoDriver_Win32GDI::Start(const StringList ¶m) 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::AllocateBackingStore(int w, int h, bool force) 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::AfterBlitterChange() 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::GetInstance()); + + drv->Paint(); + GdiFlush(); + + return _fooctr++; +} +#endif diff --git a/src/video/win32_v.h b/src/video/win32_v.h index cb1658cef..13115e8c9 100644 --- a/src/video/win32_v.h +++ b/src/video/win32_v.h @@ -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 ¶m) 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. */ -- cgit v1.2.3-70-g09d2