comparison src/video/photon/SDL_ph_modes.c @ 0:74212992fb08

Initial revision
author Sam Lantinga <slouken@lokigames.com>
date Thu, 26 Apr 2001 16:45:43 +0000
parents
children 62bad9a82022
comparison
equal deleted inserted replaced
-1:000000000000 0:74212992fb08
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Sam Lantinga
20 slouken@devolution.com
21 */
22
23 #ifdef SAVE_RCSID
24 static char rcsid =
25 "@(#) $Id$";
26 #endif
27
28
29 #include "SDL_ph_modes_c.h"
30
31 static unsigned long key1, key2;
32 static PgVideoModeInfo_t mode_info;
33 static PgVideoModes_t mode_list;
34 /* The current list of available video modes */
35 SDL_Rect SDL_modelist[127];
36 SDL_Rect *SDLmod_ptr;
37 SDL_Rect **SDLmod_ptrptr ;
38
39 static int compare_modes_by_res(const void* mode1, const void* mode2)
40 {
41
42 if (PgGetVideoModeInfo(*(unsigned short*)mode1, &mode_info) < 0)
43 {
44 fprintf(stderr,"error: In compare_modes_by_res PgGetVideoModeInfo failed on mode: 0x%x\n",
45 *(unsigned short*)mode1);
46 return 0;
47 }
48 key1 = mode_info.width * mode_info.height;
49
50 if (PgGetVideoModeInfo(*(unsigned short*)mode2, &mode_info) < 0)
51 {
52 fprintf(stderr,"error: In compare_modes_by_res PgGetVideoModeInfo failed on mode: 0x%x\n",
53 *(unsigned short*)mode2);
54 return 0;
55 }
56 key2 = mode_info.width * mode_info.height;
57
58 if (key1 > key2)
59 return 1;
60 else if (key1 == key2)
61 return 0;
62 else
63 return -1;
64 }
65
66 static int compare_modes_by_bpp(const void* mode1, const void* mode2)
67 {
68
69 if (PgGetVideoModeInfo(*(unsigned short*)mode1, &mode_info) < 0)
70 {
71 fprintf(stderr,"error: In compare_modes_by_bpp PgGetVideoModeInfo failed on mode: 0x%x\n",
72 *(unsigned short*)mode1);
73 return 0;
74 }
75 key1 = mode_info.bits_per_pixel;
76
77 if (PgGetVideoModeInfo(*(unsigned short*)mode2, &mode_info) < 0)
78 {
79 fprintf(stderr,"error: In compare_modes_by_bpp PgGetVideoModeInfo failed on mode: 0x%x\n",
80 *(unsigned short*)mode2);
81 return 0;
82 }
83 key2 = mode_info.bits_per_pixel;
84
85 if (key1 > key2)
86 return 1;
87 else if (key1 == key2)
88 return 0;
89 else
90 return -1;
91 }
92
93 int ph_GetVideoModes(_THIS)
94 {
95 unsigned short *front;
96 int i, bpp_group_size;
97
98 // TODO: add mode_list member to _THIS
99 if (PgGetVideoModeList( &mode_list ) < 0)
100 {
101 fprintf(stderr,"error: PgGetVideoModeList failed\n");
102 return -1;
103 }
104
105 // sort list first by bits per pixel (bpp),
106 // then sort groups with same bpp by resolution.
107 qsort(mode_list.modes, mode_list.num_modes, sizeof(unsigned short), compare_modes_by_bpp);
108 bpp_group_size = 1;
109 front = &mode_list.modes[0];
110 for(i=0;i<mode_list.num_modes-2;i++)
111 {
112 if (compare_modes_by_bpp(&mode_list.modes[i],&mode_list.modes[i+1]))
113 {
114 qsort(front, bpp_group_size, sizeof(unsigned short), compare_modes_by_res);
115 front = &mode_list.modes[i+1];
116 bpp_group_size = 1;
117 }
118 else
119 {
120 bpp_group_size++;
121 }
122 }
123
124 //SDL_modelist = (SDL_Rect **)malloc((mode_list.num_modes+1)*sizeof(SDL_Rect *));
125 if ( SDL_modelist ) {
126 for (i=0;i<mode_list.num_modes;i++) {
127 // SDL_modelist[i] = (SDL_Rect *)malloc(sizeof(SDL_Rect));
128 // if ( SDL_modelist[i] == NULL ) {
129 // break;
130 // }
131 if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
132 {
133 fprintf(stderr,"error: PgGetVideoModeInfo failed on mode: 0x%x\n",
134 mode_list.modes[i]);
135 return -1;
136 }
137 SDL_modelist[i].x = 0;
138 SDL_modelist[i].y = 0;
139 SDL_modelist[i].w = mode_info.height;
140 SDL_modelist[i].h = mode_info.width;
141 }
142 //SDL_modelist[i] = NULL;
143 }
144 else
145 {
146 fprintf(stderr,"error: malloc failed on SDL_modelist\n");
147 return -1;
148 }
149
150 return 0;
151 }
152
153 static SDL_Rect** ph_SupportedVisual( SDL_PixelFormat *format)
154 {
155 int i = 0;
156 int j = 0;
157 SDL_Rect Amodelist[127];
158
159
160 if (PgGetVideoModeList( &mode_list ) < 0)
161 {
162 fprintf(stderr,"error: PgGetVideoModeList failed\n");
163 return NULL;
164 }
165
166 mode_info.bits_per_pixel = 0;
167
168 for (i=0; i < mode_list.num_modes; i++)
169 {
170 if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
171 {
172 fprintf(stderr,"error: PgGetVideoModeInfo failed on mode: 0x%x\n",
173 mode_list.modes[i]);
174 return NULL;
175 }
176
177 if(mode_info.bits_per_pixel == format->BitsPerPixel)
178 {
179 Amodelist[j].w = mode_info.width;
180 Amodelist[j].h = mode_info.height;
181 Amodelist[j].x = 0;
182 Amodelist[j].y = 0;
183 j++;
184 }
185 }
186
187 //reorder biggest for smallest , assume width dominates
188 for(i=0; i< j ; i++)
189 {
190 SDL_modelist[i].w = Amodelist[j - i -1].w;
191 SDL_modelist[i].h = Amodelist[j - i -1].h;
192 SDL_modelist[i].x = Amodelist[j - i -1].x;
193 SDL_modelist[i].y = Amodelist[j - i -1].y;
194 }
195
196 SDLmod_ptr = SDL_modelist;
197 SDLmod_ptrptr = &SDLmod_ptr;
198 return SDLmod_ptrptr;
199 }
200
201 SDL_Rect **ph_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
202 {
203 return ph_SupportedVisual( format);
204 }
205
206 void ph_FreeVideoModes(_THIS)
207 {
208 int i;
209
210 // if ( SDL_modelist ) {
211 // for ( i=0; SDL_modelist[i]; ++i ) {
212 // free(SDL_modelist[i]);
213 // }
214 // free(SDL_modelist);
215 // SDL_modelist = NULL;
216 // }
217 }
218
219 static void set_best_resolution(_THIS, int width, int height)
220 {
221
222 if ( use_vidmode ) {
223 PgDisplaySettings_t settings;
224 PgVideoModeInfo_t current_mode_info;
225 unsigned short current_bpp;
226 int i;
227
228 if (PgGetVideoMode( &settings ) < 0)
229 {
230 fprintf(stderr,"error: PgGetVideoMode failed\n");
231 return;
232 }
233 if (PgGetVideoModeInfo( settings.mode, &current_mode_info ) < 0)
234 {
235 fprintf(stderr,"error: PgGetVideoModeInfo failed\n");
236 return;
237 }
238 current_bpp = current_mode_info.bits_per_pixel;
239
240 if (PgGetVideoModeList(&mode_list) >= 0)
241 {
242 qsort(mode_list.modes, mode_list.num_modes, sizeof(unsigned short), compare_modes_by_res);
243 #ifdef PH_DEBUG
244 printf("Available modes:\n");
245 for ( i = 0; i < mode_list.num_modes; ++i )
246 {
247 PgGetVideoModeInfo(mode_list.modes[i], &mode_info);
248 printf("Mode %d: %dx%d\n", i, mode_info.width, mode_info.height);
249 }
250 #endif
251 for ( i = mode_list.num_modes-1; i >= 0 ; --i )
252 {
253 if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
254 {
255 fprintf(stderr,"error: PgGetVideoModeInfo failed\n");
256 }
257 if ( (mode_info.width >= width) &&
258 (mode_info.height >= height) &&
259 (mode_info.bits_per_pixel == current_bpp) )
260 break;
261 }
262 if (i >= 0)
263 {
264 if ( (mode_info.width != current_mode_info.width) ||
265 (mode_info.height != current_mode_info.height) )
266 {
267 settings.mode = mode_list.modes[i];
268 if(PgSetVideoMode( &settings ) < 0)
269 {
270 fprintf(stderr,"error: PgSetVideoMode failed\n");
271 }
272 }
273 }
274 }
275 }
276 }
277
278 static void get_real_resolution(_THIS, int* w, int* h)
279 {
280
281 if ( use_vidmode ) {
282 PgDisplaySettings_t settings;
283 int unused;
284
285 if (PgGetVideoMode( &settings ) >= 0) {
286 *w = settings.xres;
287 *h = settings.yres;
288 return;
289 }
290 }
291 // *w = DisplayWidth(SDL_Display, SDL_Screen);
292 // *h = DisplayHeight(SDL_Display, SDL_Screen);
293 }
294
295 int ph_ResizeFullScreen(_THIS)
296 {
297
298 if ( currently_fullscreen ) {
299 set_best_resolution(this, current_w, current_h);
300 }
301 return(1);
302 }
303
304 int get_mode(int width, int height, int bpp)
305 /* return the mode associated with width, height and bpp */
306 /* if there is no mode then zero is returned */
307 {
308 int i;
309
310
311 if(width <640)
312 width = 640;
313 if(height < 480)
314 height = 480;
315
316
317 if (PgGetVideoModeList( &mode_list ) < 0)
318 {
319 fprintf(stderr,"error: PgGetVideoModeList failed\n");
320 return -1;
321 }
322
323 // search list for exact match
324 for (i=0;i<mode_list.num_modes;i++)
325 {
326 if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
327 {
328 fprintf(stderr,"error: PgGetVideoModeInfo failed\n");
329 return 0;
330 }
331
332
333 if ((mode_info.width == width) &&
334 (mode_info.height == height) &&
335 (mode_info.bits_per_pixel == bpp))
336 {
337 return mode_list.modes[i];
338 }
339 }
340 return (i == mode_list.num_modes) ? 0 : mode_list.modes[i];
341 }
342
343 int get_mode_any_format(int width, int height, int bpp)
344 /* return the mode associated with width, height and bpp */
345 /* if requested bpp is not found the mode with closest bpp is returned */
346 {
347 int i, closest, delta, min_delta;
348
349 if (PgGetVideoModeList( &mode_list ) < 0)
350 {
351 fprintf(stderr,"error: PgGetVideoModeList failed\n");
352 return -1;
353 }
354
355 qsort(mode_list.modes, mode_list.num_modes, sizeof(unsigned short), compare_modes_by_res);
356 for(i=0;i<mode_list.num_modes;i++)
357 {
358 if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
359 {
360 fprintf(stderr,"error: PgGetVideoModeInfo failed\n");
361 return 0;
362 }
363 if ((mode_info.width == width) &&
364 (mode_info.height == height))
365 break;
366 }
367 if (i<mode_list.num_modes)
368 {
369 // get closest bpp
370 closest = i++;
371 if (mode_info.bits_per_pixel == bpp)
372 return mode_list.modes[ closest ];
373
374 min_delta = abs(mode_info.bits_per_pixel - bpp);
375 while(1)
376 {
377 if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
378 {
379 fprintf(stderr,"error: PgGetVideoModeInfo failed\n");
380 return 0;
381 }
382
383 if ((mode_info.width != width) ||
384 (mode_info.height != height))
385 break;
386 else if (mode_info.bits_per_pixel == bpp)
387 {
388 closest = i;
389 break;
390 }
391 else
392 {
393 delta = abs(mode_info.bits_per_pixel - bpp);
394 if (delta < min_delta)
395 {
396 closest = i;
397 min_delta = delta;
398 }
399 i++;
400 }
401 }
402 return mode_list.modes[ closest ];
403 }
404 else
405 return 0;
406 }
407
408 void ph_WaitMapped(_THIS);
409 void ph_WaitUnmapped(_THIS);
410 void ph_QueueEnterFullScreen(_THIS);
411
412 int ph_ToggleFullScreen(_THIS, int on)
413 {
414
415 if(currently_fullscreen)
416 ph_LeaveFullScreen(this);
417 else
418 ph_EnterFullScreen(this);
419
420 return 0;
421
422 }
423
424 int ph_EnterFullScreen(_THIS)
425 {
426 if ( ! currently_fullscreen )
427 {
428
429 if (old_video_mode==-1)
430 {
431 PgGetGraphicsHWCaps(&graphics_card_caps);
432 old_video_mode=graphics_card_caps.current_video_mode;
433 old_refresh_rate=graphics_card_caps.current_rrate;
434 }
435
436
437 if(OCImage.direct_context == NULL)
438 OCImage.direct_context=(PdDirectContext_t*)PdCreateDirectContext();
439 if( !OCImage.direct_context )
440 fprintf(stderr, "error: Can't create direct context\n" );
441
442
443 /* Remove the cursor if in full screen mode */
444 /*
445 region_info.cursor_type = Ph_CURSOR_NONE;
446 region_info.rid=PtWidgetRid(window);
447 PhRegionChange(Ph_REGION_CURSOR,0,&region_info,NULL,NULL);
448 */
449
450 PdDirectStart( OCImage.direct_context );
451
452 currently_fullscreen = 1;
453 }
454
455
456
457 return 1;
458 }
459
460 int ph_LeaveFullScreen(_THIS )
461 {
462 PgDisplaySettings_t mymode_settings;
463
464 if ( currently_fullscreen )
465 {
466 PdDirectStop(OCImage.direct_context);
467 PdReleaseDirectContext(OCImage.direct_context);
468
469 //Restore old video mode
470 if (old_video_mode != -1)
471 {
472 mymode_settings.mode= (unsigned short) old_video_mode;
473 mymode_settings.refresh= (unsigned short) old_refresh_rate;
474 mymode_settings.flags = 0;
475 if(PgSetVideoMode(&mymode_settings) < 0)
476 {
477 fprintf(stderr,"error: PgSetVideoMode failed\n");
478 }
479 }
480
481 old_video_mode=-1;
482 old_refresh_rate=-1;
483
484 // Restore cursor
485
486 }
487 return 1;
488 }