/
SDL_ph_modes.c
398 lines (344 loc) · 10.4 KB
1
2
/*
SDL - Simple DirectMedia Layer
3
Copyright (C) 1997-2006 Sam Lantinga
4
5
This library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Lesser General Public
7
License as published by the Free Software Foundation; either
8
version 2.1 of the License, or (at your option) any later version.
9
10
11
12
This library 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. See the GNU
13
Lesser General Public License for more details.
14
15
16
17
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19
Sam Lantinga
20
slouken@libsdl.org
21
22
*/
23
#include "SDL_error.h"
24
25
26
27
#include "SDL_ph_modes_c.h"
static PgVideoModeInfo_t mode_info;
static PgVideoModes_t mode_list;
28
29
/* The current list of available video modes */
30
31
SDL_Rect SDL_modelist[PH_MAX_VIDEOMODES];
SDL_Rect* SDL_modearray[PH_MAX_VIDEOMODES];
32
33
34
static int compare_modes_by_res(const void* mode1, const void* mode2)
{
35
36
37
38
PgVideoModeInfo_t mode1_info;
PgVideoModeInfo_t mode2_info;
if (PgGetVideoModeInfo(*(unsigned short*)mode1, &mode1_info) < 0)
39
40
41
{
return 0;
}
42
43
if (PgGetVideoModeInfo(*(unsigned short*)mode2, &mode2_info) < 0)
44
45
46
{
return 0;
}
47
48
if (mode1_info.width == mode2_info.width)
49
{
50
return mode2_info.height - mode1_info.height;
51
}
52
else
53
{
54
return mode2_info.width - mode1_info.width;
55
}
56
57
}
58
SDL_Rect **ph_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
59
{
60
61
62
int i = 0;
int j = 0;
SDL_Rect Amodelist[PH_MAX_VIDEOMODES];
63
64
65
66
67
for (i=0; i<PH_MAX_VIDEOMODES; i++)
{
SDL_modearray[i]=&SDL_modelist[i];
}
68
69
if (PgGetVideoModeList(&mode_list) < 0)
70
{
71
SDL_SetError("ph_ListModes(): PgGetVideoModeList() function failed !\n");
72
73
return NULL;
}
74
75
mode_info.bits_per_pixel = 0;
76
77
78
79
80
for (i=0; i < mode_list.num_modes; i++)
{
if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
{
81
SDL_SetError("ph_ListModes(): PgGetVideoModeInfo() function failed on mode: 0x%X.\n", mode_list.modes[i]);
82
83
84
85
86
87
88
89
90
91
92
return NULL;
}
if(mode_info.bits_per_pixel == format->BitsPerPixel)
{
Amodelist[j].w = mode_info.width;
Amodelist[j].h = mode_info.height;
Amodelist[j].x = 0;
Amodelist[j].y = 0;
j++;
}
}
93
94
/* reorder biggest for smallest, assume width dominates */
95
96
97
for(i=0; i<j; i++)
{
98
99
100
101
SDL_modelist[i].w = Amodelist[j - i - 1].w;
SDL_modelist[i].h = Amodelist[j - i - 1].h;
SDL_modelist[i].x = Amodelist[j - i - 1].x;
SDL_modelist[i].y = Amodelist[j - i - 1].y;
102
103
}
SDL_modearray[j]=NULL;
104
105
return SDL_modearray;
106
107
108
109
}
void ph_FreeVideoModes(_THIS)
{
110
return;
111
112
113
}
/* return the mode associated with width, height and bpp */
114
/* if there is no mode then zero is returned */
115
int ph_GetVideoMode(int width, int height, int bpp)
116
{
117
int i;
118
119
int modestage=0;
int closestmode=0;
120
121
122
123
124
if (PgGetVideoModeList(&mode_list) < 0)
{
return -1;
}
125
126
127
128
129
130
131
/* special case for the double-sized 320x200 mode */
if ((width==640) && (height==400))
{
modestage=1;
}
132
/* search list for exact match */
133
for (i=0; i<mode_list.num_modes; i++)
134
135
136
137
138
{
if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
{
return 0;
}
139
140
if ((mode_info.width == width) && (mode_info.height == height) &&
141
142
143
144
(mode_info.bits_per_pixel == bpp))
{
return mode_list.modes[i];
}
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
else
{
if ((modestage) && (mode_info.width == width) && (mode_info.height == height+80) &&
(mode_info.bits_per_pixel == bpp))
{
modestage=2;
closestmode=mode_list.modes[i];
}
}
}
/* if we are here, then no 640x400xbpp mode found and we'll emulate it via 640x480xbpp mode */
if (modestage==2)
{
return closestmode;
160
}
161
162
return (i == mode_list.num_modes) ? 0 : mode_list.modes[i];
163
164
}
165
/* return the mode associated with width, height and bpp */
166
/* if requested bpp is not found the mode with closest bpp is returned */
167
int get_mode_any_format(int width, int height, int bpp)
168
169
170
{
int i, closest, delta, min_delta;
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
if (PgGetVideoModeList(&mode_list) < 0)
{
return -1;
}
qsort(mode_list.modes, mode_list.num_modes, sizeof(unsigned short), compare_modes_by_res);
for(i=0;i<mode_list.num_modes;i++)
{
if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
{
return 0;
}
if ((mode_info.width == width) && (mode_info.height == height))
{
186
break;
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
}
}
if (i<mode_list.num_modes)
{
/* get closest bpp */
closest = i++;
if (mode_info.bits_per_pixel == bpp)
{
return mode_list.modes[closest];
}
min_delta = abs(mode_info.bits_per_pixel - bpp);
while(1)
{
if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
{
return 0;
}
if ((mode_info.width != width) || (mode_info.height != height))
{
break;
}
else
{
if (mode_info.bits_per_pixel == bpp)
{
closest = i;
break;
}
else
{
delta = abs(mode_info.bits_per_pixel - bpp);
if (delta < min_delta)
{
closest = i;
min_delta = delta;
}
i++;
}
}
}
return mode_list.modes[closest];
}
234
return 0;
235
236
237
238
}
int ph_ToggleFullScreen(_THIS, int on)
{
239
return -1;
240
241
}
242
int ph_EnterFullScreen(_THIS, SDL_Surface* screen, int fmode)
243
{
244
245
PgDisplaySettings_t settings;
int mode;
246
247
char* refreshrate;
int refreshratenum;
248
249
250
if (!currently_fullscreen)
{
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/* Get the video mode and set it */
if (screen->flags & SDL_ANYFORMAT)
{
if ((mode = get_mode_any_format(screen->w, screen->h, screen->format->BitsPerPixel)) == 0)
{
SDL_SetError("ph_EnterFullScreen(): can't find appropriate video mode !\n");
return 0;
}
}
else
{
if ((mode = ph_GetVideoMode(screen->w, screen->h, screen->format->BitsPerPixel)) == 0)
{
SDL_SetError("ph_EnterFullScreen(): can't find appropriate video mode !\n");
return 0;
}
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
if (PgGetVideoModeInfo(mode, &mode_info) < 0)
{
SDL_SetError("ph_EnterFullScreen(): can't get video mode capabilities !\n");
return 0;
}
if (mode_info.height != screen->h)
{
if ((mode_info.height==480) && (screen->h==400))
{
videomode_emulatemode=1;
}
}
else
{
videomode_emulatemode=0;
}
283
284
285
286
287
288
289
290
291
292
293
294
}
/* save old video mode caps */
PgGetVideoMode(&settings);
old_video_mode=settings.mode;
old_refresh_rate=settings.refresh;
/* setup new video mode */
settings.mode = mode;
settings.refresh = 0;
settings.flags = 0;
295
refreshrate=SDL_getenv("SDL_PHOTON_FULLSCREEN_REFRESH");
296
297
if (refreshrate!=NULL)
{
298
if (SDL_sscanf(refreshrate, "%d", &refreshratenum)==1)
299
300
301
302
303
{
settings.refresh = refreshratenum;
}
}
304
305
306
307
308
309
if (PgSetVideoMode(&settings) < 0)
{
SDL_SetError("ph_EnterFullScreen(): PgSetVideoMode() call failed !\n");
return 0;
}
310
if (this->screen)
311
{
312
313
if ((this->screen->flags & SDL_OPENGL)==SDL_OPENGL)
{
314
#ifdef HAVE_OPENGL
315
316
317
318
#if (_NTO_VERSION < 630)
return 0;
#endif /* 6.3.0 */
#else
319
return 0;
320
#endif /* HAVE_OPENGL */
321
}
322
}
323
324
if (fmode==0)
325
{
326
if (OCImage.direct_context==NULL)
327
{
328
329
330
331
332
333
334
OCImage.direct_context=(PdDirectContext_t*)PdCreateDirectContext();
if (!OCImage.direct_context)
{
SDL_SetError("ph_EnterFullScreen(): Can't create direct context !\n");
ph_LeaveFullScreen(this);
return 0;
}
335
}
336
OCImage.oldDC=PdDirectStart(OCImage.direct_context);
337
}
338
339
currently_fullscreen = 1;
340
}
341
PgFlush();
342
343
return 1;
344
345
}
346
int ph_LeaveFullScreen(_THIS)
347
{
348
PgDisplaySettings_t oldmode_settings;
349
350
351
if (currently_fullscreen)
{
352
if ((this->screen) && ((this->screen->flags & SDL_OPENGL)==SDL_OPENGL))
353
354
{
#ifdef HAVE_OPENGL
355
356
357
358
359
#if (_NTO_VERSION < 630)
return 0;
#endif /* 6.3.0 */
#else
return 0;
360
361
#endif /* HAVE_OPENGL */
}
362
363
/* release routines starts here */
364
{
365
366
367
368
369
370
371
372
373
374
375
if (OCImage.direct_context)
{
PdDirectStop(OCImage.direct_context);
PdReleaseDirectContext(OCImage.direct_context);
OCImage.direct_context=NULL;
}
if (OCImage.oldDC)
{
PhDCSetCurrent(OCImage.oldDC);
OCImage.oldDC=NULL;
}
376
377
currently_fullscreen=0;
378
379
380
381
/* Restore old video mode */
if (old_video_mode != -1)
{
382
383
384
oldmode_settings.mode = (unsigned short) old_video_mode;
oldmode_settings.refresh = (unsigned short) old_refresh_rate;
oldmode_settings.flags = 0;
385
386
if (PgSetVideoMode(&oldmode_settings) < 0)
387
{
388
SDL_SetError("Ph_LeaveFullScreen(): PgSetVideoMode() function failed !\n");
389
return 0;
390
391
392
393
}
}
old_video_mode=-1;
394
old_refresh_rate=-1;
395
396
397
}
}
return 1;
398
}