Line data Source code
1 : /* Copyright (C) 2023 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifndef INCLUDED_VIDEOMODE
19 : #define INCLUDED_VIDEOMODE
20 :
21 : #include "ps/CStrForward.h"
22 : #include "renderer/backend/Backend.h"
23 :
24 : #include <memory>
25 :
26 : typedef struct SDL_Window SDL_Window;
27 :
28 : namespace Renderer
29 : {
30 : namespace Backend
31 : {
32 : class IDevice;
33 : }
34 : }
35 :
36 1 : class CVideoMode
37 : {
38 : public:
39 : CVideoMode();
40 : ~CVideoMode();
41 :
42 : /**
43 : * Initialise the video mode, for use in an SDL-using application.
44 : */
45 : bool InitSDL();
46 :
47 : /**
48 : * Initialise parts of the video mode, for use in Atlas (which uses
49 : * wxWidgets instead of SDL for GL).
50 : */
51 : bool InitNonSDL();
52 :
53 : /**
54 : * Shut down after InitSDL/InitNonSDL, so that they can be used again.
55 : */
56 : void Shutdown();
57 :
58 : /**
59 : * Creates a backend device. Also we use wxWidgets in Atlas so we don't need
60 : * to create one for that case.
61 : */
62 : bool CreateBackendDevice(const bool createSDLContext);
63 :
64 : /**
65 : * Resize the SDL window and associated graphics stuff to the new size.
66 : */
67 : bool ResizeWindow(int w, int h);
68 :
69 : /**
70 : * Set scale and tell dependent compoenent to recompute sizes.
71 : */
72 : void Rescale(float scale);
73 :
74 : /**
75 : * Switch to fullscreen or windowed mode.
76 : */
77 : bool SetFullscreen(bool fullscreen);
78 :
79 : /**
80 : * Returns true if window runs in fullscreen mode.
81 : */
82 : bool IsInFullscreen() const;
83 :
84 : /**
85 : * Switch between fullscreen and windowed mode.
86 : */
87 : bool ToggleFullscreen();
88 :
89 : /**
90 : * Update window position, to restore later if necessary (SDL2 only).
91 : */
92 : void UpdatePosition(int x, int y);
93 :
94 : /**
95 : * Update the graphics code to start drawing to the new size.
96 : * This should be called after the GL context has been resized.
97 : * This can also be used when the GL context is managed externally, not via SDL.
98 : */
99 : static void UpdateRenderer(int w, int h);
100 :
101 : int GetXRes() const;
102 : int GetYRes() const;
103 : int GetBPP() const;
104 :
105 : bool IsVSyncEnabled() const;
106 :
107 : int GetDesktopXRes() const;
108 : int GetDesktopYRes() const;
109 : int GetDesktopBPP() const;
110 : int GetDesktopFreq() const;
111 :
112 : float GetScale() const;
113 :
114 : SDL_Window* GetWindow();
115 :
116 : void SetWindowIcon();
117 :
118 : void SetCursor(const CStrW& name);
119 : void ResetCursor();
120 :
121 115 : Renderer::Backend::IDevice* GetBackendDevice() { return m_BackendDevice.get(); }
122 :
123 : private:
124 : void ReadConfig();
125 : int GetBestBPP();
126 : bool SetVideoMode(int w, int h, int bpp, bool fullscreen);
127 :
128 : bool TryCreateBackendDevice(SDL_Window* window);
129 : void DowngradeBackendSettingAfterCreationFailure();
130 :
131 : /**
132 : * Remember whether Init has been called. (This isn't used for anything
133 : * important, just for verifying that the callers call our methods in
134 : * the right order.)
135 : */
136 : bool m_IsInitialised = false;
137 :
138 : SDL_Window* m_Window = nullptr;
139 :
140 : // Initial desktop settings.
141 : // Frequency is in Hz, and BPP means bits per pixels (not bytes per pixels).
142 : int m_PreferredW = 0;
143 : int m_PreferredH = 0;
144 : int m_PreferredBPP = 0;
145 : int m_PreferredFreq = 0;
146 :
147 : float m_Scale = 1.0f;
148 :
149 : // Config file settings (0 if unspecified)
150 : int m_ConfigW = 0;
151 : int m_ConfigH = 0;
152 : int m_ConfigBPP = 0;
153 : int m_ConfigDisplay = 0;
154 : bool m_ConfigEnableHiDPI = false;
155 : bool m_ConfigVSync = false;
156 :
157 : // (m_ConfigFullscreen defaults to false, so users don't get stuck if
158 : // e.g. half the filesystem is missing and the config files aren't loaded).
159 : bool m_ConfigFullscreen = false;
160 :
161 : // If we're fullscreen, size/position of window when we were last windowed (or the default window
162 : // size/position if we started fullscreen), to support switching back to the old window size/position
163 : int m_WindowedW;
164 : int m_WindowedH;
165 : int m_WindowedX;
166 : int m_WindowedY;
167 :
168 : // Whether we're currently being displayed fullscreen
169 : bool m_IsFullscreen = false;
170 :
171 : // The last mode selected
172 : int m_CurrentW;
173 : int m_CurrentH;
174 : int m_CurrentBPP;
175 :
176 : class CCursor;
177 : std::unique_ptr<CCursor> m_Cursor;
178 :
179 : Renderer::Backend::Backend m_Backend = Renderer::Backend::Backend::GL;
180 : std::unique_ptr<Renderer::Backend::IDevice> m_BackendDevice;
181 : };
182 :
183 : extern CVideoMode g_VideoMode;
184 :
185 : #endif // INCLUDED_VIDEOMODE
|