source: Daodan/src/daodan_gl.c @ 326

Last change on this file since 326 was 326, checked in by rossy, 11 years ago

This is the first "non-working" commit of Daodan. For this reason, the last fully working release is in the /release/ folder while the current build is in the /build/ folder. The reason it's not working is that I'm trying to write a "proper" windowed mode by replacing ONrPlatform_Initialize and gl_platform_initialize. I'm currently in the middle of rewriting gl_platform_initialize and Oni's draw engine doesn't like the new code.

File size: 7.5 KB
Line 
1#include <windows.h>
2#include <math.h>
3
4#include "Oni.h"
5#include "Oni_Persistence.h"
6#include "Daodan_Utility.h"
7
8#include "BFW_Utility.h"
9
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
17const M3tDisplayMode daodan_reslist[] = {
18        { 720 , 480,  0, 0 },
19        { 720 , 576,  0, 0 },
20        { 768 , 480,  0, 0 },
21        { 800 , 480,  0, 0 },
22        { 852 , 480,  0, 0 },
23        { 856 , 480,  0, 0 },
24        { 960 , 540,  0, 0 },
25        { 960 , 720,  0, 0 },
26        { 1024, 576,  0, 0 },
27        { 1024, 600,  0, 0 },
28        { 1024, 640,  0, 0 },
29        { 1024, 768,  0, 0 },
30        { 1152, 768,  0, 0 },
31        { 1152, 864,  0, 0 },
32        { 1280, 720,  0, 0 },
33        { 1280, 768,  0, 0 },
34        { 1280, 800,  0, 0 },
35        { 1280, 960,  0, 0 },
36        { 1280, 1024, 0, 0 },
37        { 1366, 768,  0, 0 },
38        { 1400, 1050, 0, 0 },
39        { 1440, 900,  0, 0 },
40        { 1600, 900,  0, 0 },
41        { 1600, 1200, 0, 0 },
42        { 1920, 1080, 0, 0 },
43        { 1920, 1440, 0, 0 },
44};
45
46const short daodan_resdepths[] = { 16, 32 };
47
48DEVMODE orig_devmode, cur_devmode, new_devmode;
49
50void init_daodan_gl()
51{
52        memset(&orig_devmode, 0, sizeof(orig_devmode));
53        orig_devmode.dmSize = sizeof(orig_devmode);
54       
55        if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &orig_devmode))
56        {
57                orig_devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
58                orig_devmode.dmBitsPerPel = 32;
59                orig_devmode.dmPelsWidth  = GetSystemMetrics(SM_CXSCREEN);
60                orig_devmode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
61        }
62       
63        memcpy(&cur_devmode, &orig_devmode, sizeof(orig_devmode));
64        memcpy(&new_devmode, &orig_devmode, sizeof(orig_devmode));
65}
66
67void update_cdmode()
68{
69        if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &cur_devmode))
70        {
71                cur_devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
72                cur_devmode.dmBitsPerPel = 32;
73                cur_devmode.dmPelsWidth  = GetSystemMetrics(SM_CXSCREEN);
74                cur_devmode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
75        }
76}
77
78unsigned int ONICALL daodan_enumerate_valid_display_modes(M3tDisplayMode modes[max_modes])
79{
80        unsigned int vmodes = 0;
81        unsigned int screen_x = orig_devmode.dmPelsWidth;
82        unsigned int screen_y = orig_devmode.dmPelsHeight;
83       
84        int i, j;
85       
86        for (i = 0; i < builtin_depths; i ++)
87        {
88                modes[vmodes].Width  = 640;
89                modes[vmodes].Height = 480;
90                modes[vmodes].Depth  = daodan_resdepths[i];
91               
92                if (++vmodes == max_modes - builtin_modes + i)
93                        goto modesfull;
94               
95                for (j = 0; j < builtin_modes; j ++)
96                        if (!(daodan_reslist[j].Width == 640 && daodan_reslist[j].Height == 480) && !(daodan_reslist[j].Width == screen_x && daodan_reslist[j].Height == screen_y) &&
97                                ((daodan_reslist[j].Width < screen_x && daodan_reslist[j].Height < screen_y) || daodan_testmode(daodan_reslist[j])))
98                        {
99                                modes[vmodes].Width  = daodan_reslist[j].Width;
100                                modes[vmodes].Height = daodan_reslist[j].Height;
101                                modes[vmodes].Depth  = daodan_resdepths[i];
102                               
103                                if (++vmodes == max_modes - builtin_modes + i)
104                                        goto modesfull;
105                        }
106               
107                modes[vmodes].Width  = screen_x;
108                modes[vmodes].Height = screen_y;
109                modes[vmodes].Depth  = daodan_resdepths[i];
110               
111                if (++vmodes == max_modes - builtin_modes + i)
112                        goto modesfull;
113        }
114       
115        modesfull:
116        return vmodes;
117}
118
119bool daodan_testmode(M3tDisplayMode mode)
120{
121        DEVMODE devmode;
122        memset(&devmode, 0, sizeof(devmode));
123       
124        devmode.dmSize = sizeof(devmode);
125        devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
126        devmode.dmBitsPerPel = mode.Depth;
127        devmode.dmPelsWidth  = mode.Width;
128        devmode.dmPelsHeight = mode.Height;
129       
130        return (ChangeDisplaySettings(&devmode, CDS_TEST) == DISP_CHANGE_SUCCESSFUL);
131}
132
133int daodan_set_display_mode(short width, short height, short depth)
134{
135        if (M3gResolutionSwitch)
136        {
137                DEVMODE new_devmode;
138                new_devmode.dmSize = sizeof(new_devmode);
139                new_devmode.dmFields = DM_BITSPERPEL | DM_PELSHEIGHT | DM_PELSWIDTH;
140                new_devmode.dmPelsWidth = width;
141                new_devmode.dmPelsHeight = height;
142                new_devmode.dmBitsPerPel = depth;
143               
144                if (ChangeDisplaySettings(&new_devmode, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
145                        return 0;
146               
147                if (ChangeDisplaySettings(&new_devmode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
148                        return 0;
149               
150                update_cdmode();
151                gl->DisplayMode.Width = cur_devmode.dmPelsWidth;
152                gl->DisplayMode.Height = cur_devmode.dmPelsHeight;
153                if (cur_devmode.dmBitsPerPel > depth)
154                        gl->DisplayMode.Depth = cur_devmode.dmBitsPerPel;
155        }
156        else
157        {
158                update_cdmode();
159                if (cur_devmode.dmBitsPerPel > depth)
160                        gl->DisplayMode.Depth = cur_devmode.dmBitsPerPel;
161        }
162        return 1;
163}
164
165void daodan_set_gamma(float gamma)
166{
167        WORD ramp[3 * 256];
168        int i;
169
170        if (!gl_gamma_ramp_valid)
171                return;
172
173        gamma = (1.0f - gamma) * 1.2f + 0.4f;
174
175        for (i = 0; i < sizeof(ramp); i++) 
176        {
177                int value = (int)(pow(gl_gamma_ramp[i] / 65535.0f, gamma) * 65535.0f);
178
179                if (value < 0)
180                        value = 0;
181                else if (value > 65535)
182                        value = 65535;
183
184                ramp[i] = value;
185        }
186       
187        if (gl_api->wglSetDeviceGammaRamp3DFX)
188                gl_api->wglSetDeviceGammaRamp3DFX(gl->HDC, ramp);
189        else
190                SetDeviceGammaRamp(gl->HDC, ramp);
191}
192
193int ONICALL daodangl_platform_initialize()
194{
195        static M3tDisplayMode lastmode = {0, 0, 0, 0};
196       
197        if (lastmode.Width != gl->DisplayMode.Width || lastmode.Height != gl->DisplayMode.Height || lastmode.Depth != gl->DisplayMode.Depth)
198                if (!daodan_set_display_mode(gl->DisplayMode.Width, gl->DisplayMode.Height, gl->DisplayMode.Depth))
199                        if (gl->DisplayMode.Width != 640 || gl->DisplayMode.Height != 480 || gl->DisplayMode.Depth != 16)
200                        {
201                                gl->DisplayMode.Width = 640;
202                                gl->DisplayMode.Height = 480;
203                                if (!daodan_set_display_mode(640, 480, 16))
204                                        goto exit_err;
205                        }
206
207        if (lastmode.Width != gl->DisplayMode.Width || lastmode.Height != gl->DisplayMode.Height)
208        {
209                RECT Rect;
210                Rect.left = (GetSystemMetrics(SM_CXSCREEN) / 2) - (gl->DisplayMode.Width / 2);
211                Rect.top = (GetSystemMetrics(SM_CYSCREEN) / 2) - (gl->DisplayMode.Height / 2);
212                Rect.right = Rect.left + gl->DisplayMode.Width;
213                Rect.bottom = Rect.top + gl->DisplayMode.Height;
214                AdjustWindowRect(&Rect, WS_OVERLAPPED | WS_MAXIMIZEBOX | WS_MINIMIZEBOX, FALSE);
215               
216                SetWindowPos(ONgPlatformData.Window, NULL, Rect.left, Rect.top, Rect.right - Rect.left, Rect.bottom - Rect.top, SWP_NOACTIVATE | SWP_NOZORDER);
217        }
218
219        if (gl->HDC == NULL)
220                if ((gl->HDC = GetDC(ONgPlatformData.Window)) == NULL)
221                        goto exit_err;
222       
223        if (gl_api->wglGetDeviceGammaRamp3DFX != NULL)
224        {
225                DDrStartupMessage("Using 3DFX gamma adjustment");
226
227                if (gl_api->wglGetDeviceGammaRamp3DFX(gl->HDC, gl_gamma_ramp))
228                        gl_gamma_ramp_valid = 1;
229        }
230        else
231        {
232                DDrStartupMessage("Using standard Windows gamma adjustment");
233
234                if (GetDeviceGammaRamp(gl->HDC, gl_gamma_ramp))
235                        gl_gamma_ramp_valid = 1;
236        }
237       
238//      if (gl_gamma_ramp_valid)
239//              daodan_set_gamma(ONrPersist_GetGamma());  Its not working :(
240//      else
241                DDrStartupMessage("gamma adjustment not supported");
242       
243        if (!gl_platform_set_pixel_format(gl->HDC))
244                if (gl->DisplayMode.Depth != 16)
245                {
246                        if (!daodan_set_display_mode(gl->DisplayMode.Width, gl->DisplayMode.Height, 16))
247                                goto exit_err;
248                       
249                        if (!gl_platform_set_pixel_format(gl->HDC))
250                                goto exit_err;
251                }
252
253        lastmode.Width = gl->DisplayMode.Width;
254        lastmode.Height = gl->DisplayMode.Height;
255        lastmode.Depth = gl->DisplayMode.Depth;
256       
257        return 0;
258
259exit_err:
260        AUrMessageBox(1, "Failed to initialize OpenGL contexts; Oni will now exit.");
261        exit(0);
262        return 1;
263}
Note: See TracBrowser for help on using the repository browser.