1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
8 /** @file win32_v.h Base of the Windows video driver. */
9 
10 #ifndef VIDEO_WIN32_H
11 #define VIDEO_WIN32_H
12 
13 #include "video_driver.hpp"
14 #include <mutex>
15 #include <condition_variable>
16 
17 /** Base class for Windows video drivers. */
18 class VideoDriver_Win32Base : public VideoDriver {
19 public:
VideoDriver_Win32Base()20 	VideoDriver_Win32Base() : main_wnd(nullptr), fullscreen(false), buffer_locked(false) {}
21 
22 	void Stop() override;
23 
24 	void MakeDirty(int left, int top, int width, int height) override;
25 
26 	void MainLoop() override;
27 
28 	bool ChangeResolution(int w, int h) override;
29 
30 	bool ToggleFullscreen(bool fullscreen) override;
31 
32 	bool ClaimMousePointer() override;
33 
34 	void EditBoxLostFocus() override;
35 
36 	std::vector<int> GetListOfMonitorRefreshRates() override;
37 
38 protected:
39 	HWND main_wnd;          ///< Handle to system window.
40 	bool fullscreen;        ///< Whether to use (true) fullscreen mode.
41 	bool has_focus = false; ///< Does our window have system focus?
42 	Rect dirty_rect;        ///< Region of the screen that needs redrawing.
43 	int width = 0;          ///< Width in pixels of our display surface.
44 	int height = 0;         ///< Height in pixels of our display surface.
45 	int width_org = 0;      ///< Original monitor resolution width, before we changed it.
46 	int height_org = 0;     ///< Original monitor resolution height, before we changed it.
47 
48 	bool buffer_locked;     ///< Video buffer was locked by the main thread.
49 
50 	Dimension GetScreenSize() const override;
51 	float GetDPIScale() override;
52 	void InputLoop() override;
53 	bool LockVideoBuffer() override;
54 	void UnlockVideoBuffer() override;
55 	void CheckPaletteAnim() override;
56 	bool PollEvent() override;
57 
58 	void Initialize();
59 	bool MakeWindow(bool full_screen, bool resize = true);
60 	void ClientSizeChanged(int w, int h, bool force = false);
61 
62 	/** Get screen depth to use for fullscreen mode. */
63 	virtual uint8 GetFullscreenBpp();
64 	/** (Re-)create the backing store. */
65 	virtual bool AllocateBackingStore(int w, int h, bool force = false) = 0;
66 	/** Get a pointer to the video buffer. */
67 	virtual void *GetVideoPointer() = 0;
68 	/** Hand video buffer back to the painting backend. */
ReleaseVideoPointer()69 	virtual void ReleaseVideoPointer() {}
70 	/** Palette of the window has changed. */
71 	virtual void PaletteChanged(HWND hWnd) = 0;
72 
73 private:
74 	friend LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
75 };
76 /** The GDI video driver for windows. */
77 class VideoDriver_Win32GDI : public VideoDriver_Win32Base {
78 public:
VideoDriver_Win32GDI()79 	VideoDriver_Win32GDI() : dib_sect(nullptr), gdi_palette(nullptr), buffer_bits(nullptr) {}
80 
81 	const char *Start(const StringList &param) override;
82 
83 	void Stop() override;
84 
85 	bool AfterBlitterChange() override;
86 
GetName()87 	const char *GetName() const override { return "win32"; }
88 
89 protected:
90 	HBITMAP  dib_sect;      ///< System bitmap object referencing our rendering buffer.
91 	HPALETTE gdi_palette;   ///< Palette object for 8bpp blitter.
92 	void     *buffer_bits;  ///< Internal rendering buffer.
93 
94 	void Paint() override;
GetVideoPointer()95 	void *GetVideoPointer() override { return this->buffer_bits; }
96 
97 	bool AllocateBackingStore(int w, int h, bool force = false) override;
98 	void PaletteChanged(HWND hWnd) override;
99 	void MakePalette();
100 	void UpdatePalette(HDC dc, uint start, uint count);
101 
102 #ifdef _DEBUG
103 public:
104 	static int RedrawScreenDebug();
105 #endif
106 };
107 
108 /** The factory for Windows' video driver. */
109 class FVideoDriver_Win32GDI : public DriverFactoryBase {
110 public:
FVideoDriver_Win32GDI()111 	FVideoDriver_Win32GDI() : DriverFactoryBase(Driver::DT_VIDEO, 9, "win32", "Win32 GDI Video Driver") {}
CreateInstance()112 	Driver *CreateInstance() const override { return new VideoDriver_Win32GDI(); }
113 };
114 
115 #ifdef WITH_OPENGL
116 
117 /** The OpenGL video driver for windows. */
118 class VideoDriver_Win32OpenGL : public VideoDriver_Win32Base {
119 public:
VideoDriver_Win32OpenGL()120 	VideoDriver_Win32OpenGL() : dc(nullptr), gl_rc(nullptr), anim_buffer(nullptr) {}
121 
122 	const char *Start(const StringList &param) override;
123 
124 	void Stop() override;
125 
126 	bool ToggleFullscreen(bool fullscreen) override;
127 
128 	bool AfterBlitterChange() override;
129 
HasEfficient8Bpp()130 	bool HasEfficient8Bpp() const override { return true; }
131 
UseSystemCursor()132 	bool UseSystemCursor() override { return true; }
133 
134 	void PopulateSystemSprites() override;
135 
136 	void ClearSystemSprites() override;
137 
HasAnimBuffer()138 	bool HasAnimBuffer() override { return true; }
GetAnimBuffer()139 	uint8 *GetAnimBuffer() override { return this->anim_buffer; }
140 
141 	void ToggleVsync(bool vsync) override;
142 
GetName()143 	const char *GetName() const override { return "win32-opengl"; }
144 
145 protected:
146 	HDC    dc;          ///< Window device context.
147 	HGLRC  gl_rc;       ///< OpenGL context.
148 	uint8 *anim_buffer; ///< Animation buffer from OpenGL back-end.
149 
GetFullscreenBpp()150 	uint8 GetFullscreenBpp() override { return 32; } // OpenGL is always 32 bpp.
151 
152 	void Paint() override;
153 
154 	bool AllocateBackingStore(int w, int h, bool force = false) override;
155 	void *GetVideoPointer() override;
156 	void ReleaseVideoPointer() override;
PaletteChanged(HWND hWnd)157 	void PaletteChanged(HWND hWnd) override {}
158 
159 	const char *AllocateContext();
160 	void DestroyContext();
161 };
162 
163 /** The factory for Windows' OpenGL video driver. */
164 class FVideoDriver_Win32OpenGL : public DriverFactoryBase {
165 public:
FVideoDriver_Win32OpenGL()166 	FVideoDriver_Win32OpenGL() : DriverFactoryBase(Driver::DT_VIDEO, 10, "win32-opengl", "Win32 OpenGL Video Driver") {}
CreateInstance()167 	/* virtual */ Driver *CreateInstance() const override { return new VideoDriver_Win32OpenGL(); }
168 
169 protected:
UsesHardwareAcceleration()170 	bool UsesHardwareAcceleration() const override { return true; }
171 };
172 
173 #endif /* WITH_OPENGL */
174 
175 #endif /* VIDEO_WIN32_H */
176