ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/Daodan/src/Daodan_GL.c
(Generate patch)

Comparing Daodan/src/Daodan_GL.c (file contents):
Revision 694 by alloc, Fri Mar 8 00:31:30 2013 UTC vs.
Revision 705 by alloc, Tue Mar 19 15:00:23 2013 UTC

# Line 10 | Line 10
10   #include "Daodan_GL.h"
11   #include "Oni_GL.h"
12  
13 < #define max_modes (104) // Dirty hack to add more resolutions, it really should only be 16 ^_^
14 < #define builtin_modes  (sizeof(daodan_reslist) / sizeof(M3tDisplayMode))
15 < #define builtin_depths (sizeof(daodan_resdepths) / sizeof(short))
16 <
17 < bool daodan_testmode(M3tDisplayMode mode);
18 <
19 < const M3tDisplayMode daodan_reslist[] = {
20 <        { 720 , 480,  0, 0 },
21 <        { 720 , 576,  0, 0 },
22 <        { 768 , 480,  0, 0 },
23 <        { 800 , 480,  0, 0 },
24 <        { 800 , 600,  0, 0 },
25 <        { 852 , 480,  0, 0 },
26 <        { 856 , 480,  0, 0 },
27 <        { 960 , 540,  0, 0 },
28 <        { 960 , 720,  0, 0 },
13 > static const M3tDisplayMode daodan_reslist[] =
14 > {
15 >        { 640,  480,  0, 0 },
16 >        { 720,  480,  0, 0 },
17 >        { 720,  576,  0, 0 },
18 >        { 768,  480,  0, 0 },
19 >        { 800,  480,  0, 0 },
20 >        { 800,  600,  0, 0 },
21 >        { 852,  480,  0, 0 },
22 >        { 856,  480,  0, 0 },
23 >        { 960,  540,  0, 0 },
24 >        { 960,  720,  0, 0 },
25          { 1024, 576,  0, 0 },
26          { 1024, 600,  0, 0 },
27          { 1024, 640,  0, 0 },
# Line 46 | Line 42 | const M3tDisplayMode daodan_reslist[] =
42          { 1920, 1200, 0, 0 },
43          { 1920, 1440, 0, 0 },
44   };
49 //Just going to always use 32 bits for now...
50 //short daodan_resdepths[] = { 16, 32 };
51 short daodan_resdepths[] = { 32 };
52 DEVMODE orig_devmode, cur_devmode, new_devmode;
45  
46 < /* Never called
55 < void init_daodan_gl()
56 < {
57 <        DDrStartupMessage("initalizing daodan gl");
58 <        
59 <        memset(&orig_devmode, 0, sizeof(orig_devmode));
60 <        orig_devmode.dmSize = sizeof(orig_devmode);
61 <        
62 <        if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &orig_devmode))
63 <        {
64 <                orig_devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
65 <                orig_devmode.dmBitsPerPel = 32;
66 <                orig_devmode.dmPelsWidth  = GetSystemMetrics(SM_CXSCREEN);
67 <                orig_devmode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
68 <        }
69 <        
70 <        memcpy(&cur_devmode, &orig_devmode, sizeof(orig_devmode));
71 <        memcpy(&new_devmode, &orig_devmode, sizeof(orig_devmode));
72 < }
73 < */
46 > static DWORD window_style, window_exstyle;
47  
48 < void update_cdmode()
49 < {
50 <        if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &cur_devmode))
51 <        {
52 <                cur_devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
53 <                cur_devmode.dmBitsPerPel = 32;
54 <                cur_devmode.dmPelsWidth  = GetSystemMetrics(SM_CXSCREEN);
55 <                cur_devmode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
56 <        }
57 < }
48 > // HACK: use additional device entries to store display modes. It would give us
49 > // 67 mode slots total (far more than enough). I absolutely have no idea where
50 > // Rossy got his 104 (it would take up to 0x660 bytes while the whole GL state
51 > // is only 0x63c bytes). Maybe it was just octal (67 + 1).
52 > // This hack would break (crash!) "m3_display_list" script command.
53 > #define DD_MAX_MODES ((offsetof(M3tDrawEngineCaps,__unknown) - \
54 >                                                offsetof(M3tDrawEngineCaps,DisplayDevices) - \
55 >                                                offsetof(M3tDisplayDevice,Modes)) / sizeof(M3tDisplayMode))
56 >
57 > // Former daodan_resdepths.
58 > #define DD_MIN_DEPTH 16
59  
60 < unsigned int ONICALL daodan_enumerate_valid_display_modes(M3tDisplayMode modes[max_modes])
60 > unsigned short ONICALL DD_GLrEnumerateDisplayModes(M3tDisplayMode* modes)
61   {
62          unsigned int vmodes = 0;
63          unsigned int screen_x = GetSystemMetrics(SM_CXSCREEN);
64          unsigned int screen_y = GetSystemMetrics(SM_CYSCREEN);
65          
66 <        uint16_t i, j;
66 >        unsigned int i;
67 >        signed int j;
68          
69          DDrStartupMessage("listing display modes");
70 <        /*
71 <        if (!M3gResolutionSwitch)
72 <                daodan_resdepths[0] = orig_devmode.dmBitsPerPel;
73 <        */
99 <        for (i = 0; i < builtin_depths; i ++)
70 >
71 >        memset(modes, 0, sizeof(M3tDisplayMode) * DD_MAX_MODES);
72 >
73 >        if (M3gResolutionSwitch)
74          {
75 <                bool scrInsert = false;
76 <                
77 <                modes[vmodes].Width  = 640;
78 <                modes[vmodes].Height = 480;
79 <                modes[vmodes].Depth  = daodan_resdepths[i];
80 <                
81 <                if (++vmodes == max_modes - builtin_modes + i)
82 <                        goto modesfull;
83 <                
84 <                for (j = 0; j < builtin_modes; j ++)
85 <                        if (!(daodan_reslist[j].Width == 640 && daodan_reslist[j].Height == 480) && !(daodan_reslist[j].Width == screen_x && daodan_reslist[j].Height == screen_y) &&
86 <                                ((daodan_reslist[j].Width < screen_x && daodan_reslist[j].Height < screen_y) || (M3gResolutionSwitch && daodan_testmode(daodan_reslist[j]))))
75 >                // Enumerate in -switch mode. "67 slots ought to be enough for anybody".
76 >
77 >                DEVMODE dm;
78 >
79 >                dm.dmSize        = sizeof(dm);
80 >                dm.dmDriverExtra = 0;
81 >
82 >                for (i = 0; EnumDisplaySettings(NULL, i, &dm); ++i)
83 >                {
84 >                        if (dm.dmBitsPerPel < DD_MIN_DEPTH || dm.dmPelsWidth < 640 || dm.dmPelsHeight < 480)
85 >                                continue;
86 >
87 >                        // Already exists? Search backwards as modes are sorted most of the times
88 >                        for (j = vmodes - 1; j >= 0; --j)
89 >                                if (modes[j].Width == dm.dmPelsWidth && modes[j].Height == dm.dmPelsHeight &&
90 >                                        modes[j].Depth == dm.dmBitsPerPel)
91 >                                        break;
92 >
93 >                        if (j >= 0)
94 >                                continue; // We've found a match.
95 >
96 >                        modes[vmodes].Width  = dm.dmPelsWidth;
97 >                        modes[vmodes].Height = dm.dmPelsHeight;
98 >                        modes[vmodes].Depth  = dm.dmBitsPerPel;
99 >
100 >                        if (++vmodes >= DD_MAX_MODES)
101 >                                break;
102 >                }
103 >        }
104 >        else
105 >        {
106 >                // In -noswtich we put predefined window sizes which don't overlap
107 >                // deskbar(s) plus one "native" fullscreen mode.
108 >
109 >                unsigned int workarea_width, workarea_height, frame_width, frame_height;
110 >                DWORD style, exstyle;
111 >                RECT rc;
112 >
113 >                if (SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, 0))
114 >                {
115 >                        workarea_width  = rc.right - rc.left;
116 >                        workarea_height = rc.bottom - rc.top;
117 >                }
118 >                else
119 >                {
120 >                        workarea_width  = screen_x;
121 >                        workarea_height = screen_y;
122 >                }
123 >
124 >                style   = (DWORD) GetWindowLongPtr(ONgPlatformData.Window, GWL_STYLE);
125 >                exstyle = (DWORD) GetWindowLongPtr(ONgPlatformData.Window, GWL_EXSTYLE);
126 >
127 >                // Calculate additional width and height for window borders. Don't
128 >                // bother with system metrics. Let Windows calculate this.
129 >                rc.left  = rc.top = 0;
130 >                rc.right = rc.bottom = 300;
131 >
132 >                if (AdjustWindowRectEx(&rc, style, FALSE, exstyle))
133 >                {
134 >                        frame_width  = rc.right - rc.left - 300;
135 >                        frame_height = rc.bottom - rc.top - 300;
136 >                }
137 >                else
138 >                {
139 >                        frame_width  = 0;
140 >                        frame_height = 0;
141 >                }
142 >
143 >                for (i = 0; i < sizeof(daodan_reslist) / sizeof(daodan_reslist[0]); ++i)
144 >                {
145 >                        // Don't check the mode which has the same rect as screen. We would
146 >                        // add it later as a special case.
147 >                        if (daodan_reslist[i].Width == screen_x && daodan_reslist[i].Height == screen_y)
148 >                                continue;
149 >                        
150 >                        if (daodan_reslist[i].Width + frame_width <= workarea_width &&
151 >                                daodan_reslist[i].Height + frame_height <= workarea_height)
152                          {
153 <                                if (!scrInsert && (daodan_reslist[j].Width > screen_x || (daodan_reslist[j].Width == screen_x &&  daodan_reslist[j].Height > screen_y)))
153 >                                modes[vmodes] = daodan_reslist[i];
154 >                                modes[vmodes].Depth = GLgInitialMode.dmBitsPerPel;
155 >
156 >                                if (++vmodes >= DD_MAX_MODES)
157                                  {
158 <                                        modes[vmodes].Width  = screen_x;
159 <                                        modes[vmodes].Height = screen_y;
118 <                                        modes[vmodes].Depth  = daodan_resdepths[i];
119 <                                        
120 <                                        if (++vmodes == max_modes - builtin_modes + i)
121 <                                                goto modesfull;
122 <                                        
123 <                                        scrInsert = true;
158 >                                        --vmodes; // Remove the last mode to make room for "fullscreen" mode.
159 >                                        break;
160                                  }
125                                
126                                modes[vmodes].Width  = daodan_reslist[j].Width;
127                                modes[vmodes].Height = daodan_reslist[j].Height;
128                                modes[vmodes].Depth  = daodan_resdepths[i];
129                                
130                                if (++vmodes == max_modes - builtin_modes + i)
131                                        goto modesfull;
161                          }
133                
134                if (!scrInsert)
135                {
136                        modes[vmodes].Width  = screen_x;
137                        modes[vmodes].Height = screen_y;
138                        modes[vmodes].Depth  = daodan_resdepths[i];
139                        
140                        if (++vmodes == max_modes - builtin_modes + i)
141                                goto modesfull;
162                  }
163 <                
164 <                if (!M3gResolutionSwitch)
165 <                        goto modesfull;
163 >
164 >                modes[vmodes].Width  = GLgInitialMode.dmPelsWidth;
165 >                modes[vmodes].Height = GLgInitialMode.dmPelsHeight;
166 >                modes[vmodes].Depth  = GLgInitialMode.dmBitsPerPel;
167 >                ++vmodes;
168          }
169 <        
170 <        modesfull:
171 <        DDrStartupMessage("%d modes available", vmodes);
169 >
170 >        DDrStartupMessage("%u modes available:", vmodes);
171 >        for (i = 0; i < vmodes; ++i)
172 >                DDrStartupMessage("  %ux%ux%u", modes[i].Width, modes[i].Height, modes[i].Depth);
173 >
174          return vmodes;
175   }
176  
177 < bool daodan_testmode(M3tDisplayMode mode)
177 > // Sets a new display mode (if it is somehow different from a current mode).
178 > // NOTE: signature for this function was changed to simplify code.
179 > UUtBool DD_GLrPlatform_SetDisplayMode(M3tDisplayMode* mode)
180   {
181 <        DEVMODE devmode;
182 <        memset(&devmode, 0, sizeof(devmode));
157 <        
158 <        devmode.dmSize = sizeof(devmode);
159 <        devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
160 <        devmode.dmBitsPerPel = mode.Depth;
161 <        devmode.dmPelsWidth  = mode.Width;
162 <        devmode.dmPelsHeight = mode.Height;
163 <        
164 <        return (ChangeDisplaySettings(&devmode, CDS_TEST | CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
165 < }
181 >        if (mode->Height < 480)
182 >                return UUcFalse;
183  
167 int daodan_set_display_mode(short width, short height, short depth)
168 {
184          if (M3gResolutionSwitch)
185          {
186 <                DEVMODE new_devmode;
187 <                new_devmode.dmSize = sizeof(new_devmode);
188 <                new_devmode.dmFields = DM_BITSPERPEL | DM_PELSHEIGHT | DM_PELSWIDTH;
189 <                new_devmode.dmPelsWidth = width;
190 <                new_devmode.dmPelsHeight = height;
191 <                new_devmode.dmBitsPerPel = depth;
192 <                
193 <                if (ChangeDisplaySettings(&new_devmode, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
194 <                        return 0;
195 <                
196 <                if (ChangeDisplaySettings(&new_devmode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
197 <                        return 0;
186 >                DEVMODE new_mode, cur_mode;
187 >
188 >                cur_mode.dmSize        = sizeof(cur_mode);
189 >                cur_mode.dmDriverExtra = 0;
190 >
191 >                // We don't need this check. Windows does this too (see CDS_RESET).
192 >                if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &cur_mode) ||
193 >                        cur_mode.dmPelsWidth != mode->Width || cur_mode.dmPelsHeight !=  mode->Height ||
194 >                        cur_mode.dmBitsPerPel != mode->Depth)
195 >                {
196 >                        new_mode.dmSize       = sizeof(new_mode);
197 >                        new_mode.dmFields     = DM_BITSPERPEL | DM_PELSHEIGHT | DM_PELSWIDTH;
198 >                        new_mode.dmPelsWidth  = mode->Width;
199 >                        new_mode.dmPelsHeight = mode->Height;
200 >                        new_mode.dmBitsPerPel = mode->Depth;
201 >
202 >                        if (ChangeDisplaySettings(&new_mode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
203 >                                return UUcFalse;
204 >                }
205                  
206 <                update_cdmode();
207 <                gl_eng->DisplayMode.Width = cur_devmode.dmPelsWidth;
208 <                gl_eng->DisplayMode.Height = cur_devmode.dmPelsHeight;
209 <                if (cur_devmode.dmBitsPerPel > (unsigned short)depth)
210 <                        gl_eng->DisplayMode.Depth = cur_devmode.dmBitsPerPel;
206 >                // We didn't change window size in DD_GLrPlatform_Initialize so we need
207 >                // to change it here.
208 >                SetWindowPos(ONgPlatformData.Window, NULL, 0, 0, mode->Width, mode->Height,
209 >                        SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_NOZORDER);
210 >
211 >                return UUcTrue;
212          }
213          else
214          {
215 <                update_cdmode();
216 <                if (cur_devmode.dmBitsPerPel > (unsigned short)depth)
217 <                        gl_eng->DisplayMode.Depth = cur_devmode.dmBitsPerPel;
218 <        }
219 <        return 1;
220 < }
221 < int ONICALL daodangl_platform_initialize()
222 < {
223 <        static M3tDisplayMode lastmode = {0, 0, 0, 0};
224 <        
225 <        if (lastmode.Width != gl_eng->DisplayMode.Width || lastmode.Height != gl_eng->DisplayMode.Height || lastmode.Depth != gl_eng->DisplayMode.Depth)
226 <                if (!daodan_set_display_mode(gl_eng->DisplayMode.Width, gl_eng->DisplayMode.Height, gl_eng->DisplayMode.Depth))
227 <                        if (gl_eng->DisplayMode.Width != 640 || gl_eng->DisplayMode.Height != 480 || gl_eng->DisplayMode.Depth != 16)
215 >                unsigned screen_x, screen_y;
216 >                DWORD style, exstyle, new_style, new_exstyle;
217 >                DWORD flags;
218 >                RECT rc, workarea_rc;
219 >                POINT pt;
220 >
221 >                screen_x = GetSystemMetrics(SM_CXSCREEN);
222 >                screen_y = GetSystemMetrics(SM_CYSCREEN);
223 >
224 >                GetClientRect(ONgPlatformData.Window, &rc);
225 >                
226 >                // Don't do anything if the mode was not changed.
227 >                if (rc.right == mode->Width && rc.bottom == mode->Height)
228 >                        return UUcTrue;
229 >
230 >                style   = (DWORD) GetWindowLongPtr(ONgPlatformData.Window, GWL_STYLE);
231 >                exstyle = (DWORD) GetWindowLongPtr(ONgPlatformData.Window, GWL_EXSTYLE);
232 >                flags   = SWP_NOACTIVATE | SWP_NOZORDER;
233 >
234 >                // Remember initial window style to correctly restore from fullscreen.
235 >                if (window_style == 0)
236 >                {
237 >                        window_style = style;
238 >                        window_exstyle = exstyle;
239 >                }
240 >
241 >                if (mode->Width == screen_x && mode->Height == screen_y)
242 >                {
243 >                        // "Fullscreen" mode.
244 >                        new_exstyle = exstyle & ~(WS_EX_CLIENTEDGE | WS_EX_DLGMODALFRAME | WS_EX_STATICEDGE | WS_EX_WINDOWEDGE);
245 >                        new_style   = style & ~(WS_CAPTION | WS_BORDER | WS_THICKFRAME | WS_DLGFRAME);
246 >                        new_style   = new_style | WS_POPUP;
247 >                        rc.left     = 0;
248 >                        rc.top      = 0;
249 >                        rc.right    = mode->Width;
250 >                        rc.bottom   = mode->Height;
251 >                }
252 >                else
253 >                {
254 >                        if (opt_border)
255 >                        {
256 >                                pt.x = rc.left;
257 >                                pt.y = rc.top;
258 >                                ClientToScreen(ONgPlatformData.Window, &pt);
259 >                        }
260 >                        else
261 >                        {
262 >                                pt.x = screen_x / 2 - mode->Width / 2;
263 >                                pt.y = screen_y / 2 - mode->Height / 2;
264 >                        }
265 >
266 >                        new_exstyle = window_exstyle;
267 >                        new_style   = window_style;
268 >                        rc.left     = pt.x;
269 >                        rc.top      = pt.y;
270 >                        rc.right    = rc.left + mode->Width;
271 >                        rc.bottom   = rc.top + mode->Height;
272 >
273 >                        AdjustWindowRectEx(&rc, new_style, FALSE, new_exstyle);
274 >
275 >                        // Convert to width and height.
276 >                        rc.right  -= rc.left;
277 >                        rc.bottom -= rc.top;
278 >
279 >                        if (SystemParametersInfo(SPI_GETWORKAREA, 0, &workarea_rc, 0))
280                          {
281 <                                gl_eng->DisplayMode.Width = 640;
282 <                                gl_eng->DisplayMode.Height = 480;
283 <                                if (!daodan_set_display_mode(640, 480, 16))
284 <                                        goto exit_err;
281 >                                // We try to keep window position, but we should prevent window
282 >                                // from going off screen.
283 >
284 >                                if (rc.left + rc.right > workarea_rc.right)
285 >                                        rc.left = workarea_rc.right - rc.right;
286 >                                if (rc.top + rc.bottom > workarea_rc.bottom)
287 >                                        rc.top = workarea_rc.bottom - rc.bottom;
288 >
289 >                                //  Titlebar should always be visible.
290 >
291 >                                if (rc.left < workarea_rc.left)
292 >                                        rc.left = workarea_rc.left;
293 >                                if (rc.top < workarea_rc.top)
294 >                                        rc.top = workarea_rc.top;
295                          }
296 +                }
297 +
298 +                if (new_style != style)
299 +                {
300 +                        SetWindowLongPtr(ONgPlatformData.Window, GWL_STYLE, (LONG_PTR) new_style);
301 +                        flags |= SWP_FRAMECHANGED | SWP_DRAWFRAME;
302 +                }
303 +
304 +                if (new_exstyle != exstyle)
305 +                {
306 +                        SetWindowLongPtr(ONgPlatformData.Window, GWL_EXSTYLE, (LONG_PTR) new_exstyle);
307 +                        flags |= SWP_FRAMECHANGED | SWP_DRAWFRAME;
308 +                }
309  
310 <        if (lastmode.Width != gl_eng->DisplayMode.Width || lastmode.Height != gl_eng->DisplayMode.Height)
310 >                SetWindowPos(ONgPlatformData.Window, NULL, rc.left, rc.top, rc.right, rc.bottom, flags);
311 >                return UUcTrue;
312 >        }
313 > }
314 >
315 > static void ONICALL DD_GLiGamma_Restore(void)
316 > {
317 >        if (opt_gamma)
318          {
319 <                RECT Rect;
320 <                Rect.left = (GetSystemMetrics(SM_CXSCREEN) / 2) - (gl_eng->DisplayMode.Width / 2);
321 <                Rect.top = (GetSystemMetrics(SM_CYSCREEN) / 2) - (gl_eng->DisplayMode.Height / 2);
322 <                Rect.right = Rect.left + gl_eng->DisplayMode.Width;
218 <                Rect.bottom = Rect.top + gl_eng->DisplayMode.Height;
219 <                AdjustWindowRect(&Rect, WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_CAPTION |WS_TILEDWINDOW , FALSE);
220 <                
221 <                SetWindowPos(ONgPlatformData.Window, NULL, Rect.left, Rect.top, Rect.right - Rect.left, Rect.bottom - Rect.top, SWP_NOACTIVATE | SWP_NOZORDER);
319 >                if (gl_api->wglSetDeviceGammaRamp3DFX)
320 >                        gl_api->wglSetDeviceGammaRamp3DFX(gl->hDC, GLgInitialGammaRamp);
321 >                else
322 >                        SetDeviceGammaRamp(gl->hDC, GLgInitialGammaRamp);
323          }
324 + }
325  
326 <        if (gl_eng->HDC == NULL)
327 <                if ((gl_eng->HDC = GetDC(ONgPlatformData.Window)) == NULL)
328 <                        goto exit_err;
227 <        
228 <        if (gl_api->wglGetDeviceGammaRamp3DFX != NULL)
326 > static void ONICALL DD_GLiGamma_Initialize(void)
327 > {
328 >        if (opt_gamma)
329          {
330 <                DDrStartupMessage("Using 3DFX gamma adjustment");
330 >                if (gl_api->wglSetDeviceGammaRamp3DFX)
331 >                {
332 >                        UUrStartupMessage("Using 3dfx gamma adjustment");
333 >                        GLgGammaRampValid = gl_api->wglGetDeviceGammaRamp3DFX(gl->hDC, GLgInitialGammaRamp);
334 >                }
335 >                else
336 >                {
337 >                        UUrStartupMessage("Using Windows gamma adjustment");
338 >                        GLgGammaRampValid = GetDeviceGammaRamp(gl->hDC, GLgInitialGammaRamp);
339 >                }
340  
341 <                if (gl_api->wglGetDeviceGammaRamp3DFX(gl_eng->HDC, gl_gamma_ramp))
233 <                        gl_gamma_ramp_valid = 1;
341 >                M3rSetGamma(ONrPersist_GetGamma());
342          }
343          else
344          {
345 <                DDrStartupMessage("Using standard Windows gamma adjustment");
345 >                GLgGammaRampValid = FALSE;
346 >        }
347 > }
348 >
349 > // Disposes OpenGL engine. Called once.
350 > void ONICALL DD_GLrPlatform_Dispose(void)
351 > {
352 >        DEVMODE dm;
353 >        
354 >        DD_GLiGamma_Restore();
355  
356 <                if (GetDeviceGammaRamp(gl_eng->HDC, gl_gamma_ramp))
357 <                        gl_gamma_ramp_valid = 1;
356 >        gl_api->wglMakeCurrent(NULL, NULL);
357 >        gl_api->wglDeleteContext(gl->hGLRC);
358 >        ReleaseDC(ONgPlatformData.Window, gl->hDC);
359 >
360 >        // Restore initial display mode if it does not match current mode.
361 >        
362 >        dm.dmSize        = sizeof(dm);
363 >        dm.dmDriverExtra = 0;
364 >        
365 >        if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm) ||
366 >                dm.dmPelsWidth != GLgInitialMode.dmPelsWidth ||
367 >                dm.dmPelsHeight != GLgInitialMode.dmPelsHeight ||
368 >                dm.dmBitsPerPel != GLgInitialMode.dmBitsPerPel)
369 >        {
370 >                ChangeDisplaySettings(&GLgInitialMode, 0);
371          }
372          
373 <        /*if (gl_gamma_ramp_valid)
374 <                daodan_set_gamma(ONrPersist_GetGamma());  
375 <        else*/
376 <                DDrStartupMessage("gamma adjustment not supported");
373 >        // (skipping SetWindowPos as it only adds flickering)
374 >        gl_unload_library();
375 > }
376 >
377 > // Initializes (and re-initializes) OpenGL.
378 > UUtBool ONICALL DD_GLrPlatform_Initialize(void)
379 > {
380 >        static const M3tDisplayMode FallbackMode = { 640, 480, 16, 0 };
381 >
382 >        if (!DD_GLrPlatform_SetDisplayMode(&gl->DisplayMode))
383 >        {
384 >                gl->DisplayMode = FallbackMode;
385 >                
386 >                if (!DD_GLrPlatform_SetDisplayMode(&gl->DisplayMode))
387 >                {
388 >                        goto exit_err;
389 >                }
390 >        }
391 >
392 >        // (DD_GLrPlatform_SetDisplayMode updates a window rectangle for us)
393          
394 <        if (!gl_platform_set_pixel_format(gl_eng->HDC))
395 <                if (gl_eng->DisplayMode.Depth != 16)
394 >        if (!gl->hDC && !(gl->hDC = GetDC(ONgPlatformData.Window)))
395 >        {
396 >                goto exit_err;
397 >        }
398 >
399 >        if (!M3gResolutionSwitch && opt_gamma)
400 >        {
401 >                UUrStartupMessage("Ignoring gamma setting for a windowed mode");
402 >                opt_gamma = false;
403 >        }
404 >
405 >        DD_GLiGamma_Initialize();
406 >
407 >        // This creates a rendering context too.
408 >        if (!gl_platform_set_pixel_format(gl->hDC))
409 >        {
410 >                if (gl->DisplayMode.Depth != 16)
411                  {
412 <                        if (!daodan_set_display_mode(gl_eng->DisplayMode.Width, gl_eng->DisplayMode.Height, 16))
412 >                        gl->DisplayMode.Depth = 16;
413 >                        if (!DD_GLrPlatform_SetDisplayMode(&gl->DisplayMode))
414                                  goto exit_err;
415                          
416 <                        if (!gl_platform_set_pixel_format(gl_eng->HDC))
416 >                        if (!gl_platform_set_pixel_format(gl->hDC))
417                                  goto exit_err;
418                  }
419 +        }
420  
421 <        lastmode.Width = gl_eng->DisplayMode.Width;
259 <        lastmode.Height = gl_eng->DisplayMode.Height;
260 <        lastmode.Depth = gl_eng->DisplayMode.Depth;
261 <        return 1;
421 >        return UUcTrue;
422  
423   exit_err:
424          AUrMessageBox(1, "Failed to initialize OpenGL contexts; Oni will now exit.");

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)