mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-04 06:00:15 +00:00
Codechange: [Win32] Move GDI-specific variables and related functions into the GDI video driver class.
This commit is contained in:
parent
8b90d4abe0
commit
78b8fc3e4f
@ -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<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::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);
|
||||
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_Win32GDI *>(VideoDriver::GetInstance());
|
||||
|
||||
drv->Paint();
|
||||
GdiFlush();
|
||||
|
||||
return _fooctr++;
|
||||
}
|
||||
#endif
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user