diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp --- 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(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 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::EditBoxLostF 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( 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::GetInstance()); + + drv->Paint(); + GdiFlush(); + + return _fooctr++; +} +#endif