changeset 20534:f8712ef4e225 draft

-Codechange: [Win32] Move GDI-specific variables and related functions into the GDI video driver class.
author Michael Lutz <michi@icosahedron.de>
date Thu, 31 Jan 2013 01:43:07 +0100
parents 259e6dd4e5e3
children 5b61107b0ef3
files src/video/win32_v.cpp src/video/win32_v.h
diffstat 2 files changed, 107 insertions(+), 101 deletions(-) [+]
line wrap: on
line diff
--- a/src/video/win32_v.cpp
+++ b/src/video/win32_v.cpp
@@ -25,11 +25,7 @@
 #include <windows.h>
 
 static struct {
-	HWND main_wnd;
-	HBITMAP dib_sect;
 	void *buffer_bits;
-	HPALETTE gdi_palette;
-	RECT update_rect;
 	int width;
 	int height;
 	int width_org;
@@ -61,43 +57,6 @@
 /** Local copy of the palette for use in the drawing thread. */
 static Palette _local_palette;
 
-static void MakePalette()
-{
-	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   = _cur_palette.palette[i].r;
-		pal->palPalEntry[i].peGreen = _cur_palette.palette[i].g;
-		pal->palPalEntry[i].peBlue  = _cur_palette.palette[i].b;
-		pal->palPalEntry[i].peFlags = 0;
-
-	}
-	_wnd.gdi_palette = CreatePalette(pal);
-	if (_wnd.gdi_palette == NULL) usererror("CreatePalette failed!\n");
-
-	_cur_palette.first_dirty = 0;
-	_cur_palette.count_dirty = 256;
-	_local_palette = _cur_palette;
-}
-
-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);
@@ -172,34 +131,6 @@
 	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;
-
-	_screen.dst_ptr = _wnd.buffer_bits;
-	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
-
 /* Windows 95 will not have a WM_MOUSELEAVE message, so define it if needed */
 #if !defined(WM_MOUSELEAVE)
 #define WM_MOUSELEAVE 0x02A3
@@ -235,9 +166,9 @@
 	_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 defined(WINCE)
@@ -313,8 +244,8 @@
 		w = r.right - r.left;
 		h = r.bottom - r.top;
 
-		if (_wnd.main_wnd != NULL) {
-			if (!_window_maximize) SetWindowPos(_wnd.main_wnd, 0, 0, 0, w, h, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
+		if (this->main_wnd != NULL) {
+			if (!_window_maximize) SetWindowPos(this->main_wnd, 0, 0, 0, w, h, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
 		} else {
 			TCHAR Windowtitle[50];
 			int x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2;
@@ -322,9 +253,9 @@
 
 			_sntprintf(Windowtitle, lengthof(Windowtitle), _T("OpenTTD %s"), MB_TO_WIDE(_openttd_revision));
 
-			_wnd.main_wnd = CreateWindow(_T("OTTD"), Windowtitle, style, x, y, w, h, 0, 0, GetModuleHandle(NULL), this);
-			if (_wnd.main_wnd == NULL) usererror("CreateWindow failed");
-			ShowWindow(_wnd.main_wnd, showstyle);
+			this->main_wnd = CreateWindow(_T("OTTD"), Windowtitle, style, x, y, w, h, 0, 0, GetModuleHandle(NULL), this);
+			if (this->main_wnd == NULL) usererror("CreateWindow failed");
+			ShowWindow(this->main_wnd, showstyle);
 		}
 	}
 
@@ -733,15 +664,15 @@
 {
 	RECT r = { left, top, left + width, top + height };
 
-	InvalidateRect(_wnd.main_wnd, &r, FALSE);
+	InvalidateRect(this->main_wnd, &r, FALSE);
 }
 
-static void CheckPaletteAnim()
+void VideoDriver_Win32Base::CheckPaletteAnim()
 {
 	if (_cur_palette.count_dirty == 0) return;
 
 	_local_palette = _cur_palette;
-	InvalidateRect(_wnd.main_wnd, NULL, FALSE);
+	InvalidateRect(this->main_wnd, NULL, FALSE);
 }
 
 /* static */ void VideoDriver_Win32Base::PaintWindowThreadThunk(void *data)
@@ -786,7 +717,7 @@
 
 	_wnd.running = true;
 
-	CheckPaletteAnim();
+	this->CheckPaletteAnim();
 	for (;;) {
 		uint32 prev_cur_ticks = cur_ticks; // to check for wrapping
 
@@ -848,7 +779,7 @@
 
 			_screen.dst_ptr = _wnd.buffer_bits;
 			UpdateWindows();
-			CheckPaletteAnim();
+			this->CheckPaletteAnim();
 		} else {
 #if !defined(WINCE)
 			/* Flush GDI buffer to ensure we don't conflict with the drawing thread. */
@@ -903,7 +834,7 @@
 
 bool VideoDriver_Win32Base::ChangeResolution(int w, int h)
 {
-	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;
@@ -925,7 +856,7 @@
 
 	RegisterWndClass();
 
-	MakePalette();
+	this->MakePalette();
 
 	FindResolutions();
 
@@ -947,9 +878,9 @@
 
 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 !defined(WINCE)
 	if (_wnd.fullscreen) ChangeDisplaySettings(NULL, 0);
@@ -984,11 +915,11 @@
 	bi->bmiHeader.biBitCount = BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth();
 	bi->bmiHeader.biCompression = BI_RGB;
 
-	if (_wnd.dib_sect) DeleteObject(_wnd.dib_sect);
+	if (this->dib_sect) DeleteObject(this->dib_sect);
 
 	dc = GetDC(0);
-	_wnd.dib_sect = CreateDIBSection(dc, bi, DIB_RGB_COLORS, (VOID**)&_wnd.buffer_bits, NULL, 0);
-	if (_wnd.dib_sect == NULL) usererror("CreateDIBSection failed");
+	this->dib_sect = CreateDIBSection(dc, bi, DIB_RGB_COLORS, (VOID**)&_wnd.buffer_bits, NULL, 0);
+	if (this->dib_sect == NULL) usererror("CreateDIBSection failed");
 	ReleaseDC(0, dc);
 
 	return true;
@@ -999,10 +930,47 @@
 	return this->AllocateBackingStore(_screen.width, _screen.height, true) && this->MakeWindow(_fullscreen);
 }
 
+void VideoDriver_Win32GDI::MakePalette()
+{
+	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   = _cur_palette.palette[i].r;
+		pal->palPalEntry[i].peGreen = _cur_palette.palette[i].g;
+		pal->palPalEntry[i].peBlue  = _cur_palette.palette[i].b;
+		pal->palPalEntry[i].peFlags = 0;
+
+	}
+	this->gdi_palette = CreatePalette(pal);
+	if (this->gdi_palette == NULL) usererror("CreatePalette failed!\n");
+
+	_cur_palette.first_dirty = 0;
+	_cur_palette.count_dirty = 256;
+	_local_palette = _cur_palette;
+}
+
+void VideoDriver_Win32GDI::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);
+}
+
 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);
@@ -1014,15 +982,15 @@
 void VideoDriver_Win32GDI::PaintWindow(HDC dc)
 {
 	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 = BlitterFactoryBase::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:
@@ -1056,19 +1024,19 @@
 	while (_draw_continue) {
 		/* Convert update region from logical to device coordinates. */
 		POINT pt = {0, 0};
-		ClientToScreen(_wnd.main_wnd, &pt);
-		OffsetRect(&_wnd.update_rect, pt.x, pt.y);
+		ClientToScreen(this->main_wnd, &pt);
+		OffsetRect(&this->update_rect, pt.x, pt.y);
 
 		/* Create a device context that is clipped to the region we need to draw.
 		 * GetDCEx 'consumes' the update region, so we may not destroy it ourself. */
-		HRGN rgn = CreateRectRgnIndirect(&_wnd.update_rect);
-		HDC dc = GetDCEx(_wnd.main_wnd, rgn, DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_INTERSECTRGN);
+		HRGN rgn = CreateRectRgnIndirect(&this->update_rect);
+		HDC dc = GetDCEx(this->main_wnd, rgn, DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_INTERSECTRGN);
 
 		this->PaintWindow(dc);
 
 		/* Clear update rect. */
-		SetRectEmpty(&_wnd.update_rect);
-		ReleaseDC(_wnd.main_wnd, dc);
+		SetRectEmpty(&this->update_rect);
+		ReleaseDC(this->main_wnd, dc);
 
 		/* Flush GDI buffer to ensure drawing here doesn't conflict with any GDI usage in the main WndProc. */
 		GdiFlush();
@@ -1085,7 +1053,7 @@
 		/* Get the union of the old update rect and the new update rect. */
 		RECT r;
 		GetUpdateRect(hWnd, &r, FALSE);
-		UnionRect(&_wnd.update_rect, &_wnd.update_rect, &r);
+		UnionRect(&this->update_rect, &this->update_rect, &r);
 
 		/* Mark the window as updated, otherwise Windows would send more WM_PAINT messages. */
 		ValidateRect(hWnd, NULL);
@@ -1098,3 +1066,23 @@
 		EndPaint(hWnd, &ps);
 	}
 }
+
+#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 *>(_video_driver);
+
+	HDC dc = GetDC(drv->main_wnd);
+	drv->PaintWindow(dc);
+	ReleaseDC(drv->main_wnd, dc);
+
+	return _fooctr++;
+}
+#endif
--- a/src/video/win32_v.h
+++ b/src/video/win32_v.h
@@ -17,6 +17,8 @@
 /** Base class for Windows video drivers. */
 class VideoDriver_Win32Base: public VideoDriver {
 public:
+	VideoDriver_Win32Base() : main_wnd(NULL) {}
+
 	/* virtual */ void MakeDirty(int left, int top, int width, int height);
 
 	/* virtual */ void MainLoop();
@@ -28,8 +30,11 @@
 	/* virtual */ bool ClaimMousePointer();
 
 protected:
+	HWND    main_wnd;      ///< Window handle.
+
 	bool MakeWindow(bool full_screen);
 	void ClientSizeChanged(int w, int h);
+	void CheckPaletteAnim();
 
 	/** (Re-)create the backing store. */
 	virtual bool AllocateBackingStore(int w, int h, bool force = false) = 0;
@@ -47,6 +52,8 @@
 /** The GDI video driver for windows. */
 class VideoDriver_Win32GDI: public VideoDriver_Win32Base {
 public:
+	VideoDriver_Win32GDI() : dib_sect(NULL), gdi_palette(NULL) {}
+
 	/* virtual */ const char *Start(const char * const *param);
 
 	/* virtual */ void Stop();
@@ -56,12 +63,23 @@
 	/* virtual */ const char *GetName() const { return "win32"; }
 
 protected:
+	HBITMAP  dib_sect;      ///< Blitter target.
+	HPALETTE gdi_palette;   ///< Handle to windows palette.
+	RECT     update_rect;   ///< Rectangle to update during the next paint event.
+
 	/* virtual */ bool AllocateBackingStore(int w, int h, bool force = false);
 	/* virtual */ void PaletteChanged(HWND hWnd);
 	/* virtual */ void Paint(HWND hWnd, bool in_sizemove);
 	/* virtual */ void PaintThread();
 
+	void MakePalette();
+	void UpdatePalette(HDC dc, uint start, uint count);
 	void PaintWindow(HDC dc);
+
+#ifdef _DEBUG
+public:
+	static int RedrawScreenDebug();
+#endif
 };
 
 /** The factory for Windows' video driver. */