comparison src/video/macdsp/SDL_dspvideo.c @ 0:74212992fb08

Initial revision
author Sam Lantinga <slouken@lokigames.com>
date Thu, 26 Apr 2001 16:45:43 +0000
parents
children e8157fcb3114
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 /*
24 Written by Darrell Walisser <dwaliss1@purdue.edu>
25
26 Implementation notes ----------------------------------------------------------------------
27
28 A bit on GWorlds in VRAM from technote 1182:
29
30 There are two important things to note about GWorld's allocated in
31 VRAM. First, the base address retrieved through GetPixBaseAddr or
32 read directly from the PixMap structure can become invalid anytime
33 memory is allocated in VRAM. This can occur either by explicit
34 allocations, such as calls to NewGWorld, or by implicit ones, such as
35 those associated with the internal texture allocation of OpenGL. The
36 stored pixel images themselves will still be valid but may have been
37 moved in VRAM, thus rendering any stored base addresses invalid.
38 You should never store an image's base address for longer than is
39 necessary and especially never across calls to NewGWorld or
40 texture-creation routines.
41
42 Secondly, an offscreen pixel image allocated in VRAM can be
43 purged at system task time by the display driver. This means any
44 time your application yields time such by calling WaitNextEvent or
45 SystemTask you can lose your VRAM GWorld contents. While this
46 happens infrequently, usually associated with display resolution or
47 pixel depth changes you must code for this eventuality. This purge
48 can occur whether or not the GWorld is locked or not. A return value
49 of false from LockPixels, a NULL return value from GetPixBaseAddr
50 or NULL in the baseAddr field of the PixMap mean that the pixel
51 image has been purged. To reallocate it you can either call
52 UpdateGWorld or Dispose your current GWorld through
53 DisposeGWorld and reallocate it via NewGWorld. Either way you must
54 then rebuild the pixel image.
55
56 ------------------------------------------------------------------------------------
57
58 Currently, I don't account for (1). In my testing, NewGWorld never invalidated
59 other existing GWorlds in VRAM. However, I do have protection for (2).
60 Namely, I am using GetOSEvent() instead of WaitNextEvent() so that there are no
61 context switches (the app hogs the CPU). Eventually a book-keeping system should
62 be coded to take care of (1) and (2).
63
64 ------------------------------------------------------------------------------------
65
66 System requirements (* denotes optional):
67
68 1. DrawSprocket 1.7.3
69 2. *MacOS 9 or later for hardware accelerated blit / fill
70 3. *May also require certain graphics hardware for (2). I trust that all Apple OEM
71 hardware will work. Third party accelerators may work if they have QuickDraw
72 acceleration in the drivers and the drivers have been updated for OS 9. The current
73 Voodoo 3 drivers (1.0b12) do not work.
74
75 Coding suggestions:
76
77 1. Use SDL_UpdateRects !
78
79 If no QuickDraw acceleration is present, double-buffered surfaces will use a back buffer
80 in System memory. I recommend you use SDL_UpdateRects with double-buffered surfaces
81 for best performance on these cards, since the overhead is nearly zero for VRAM back buffer.
82
83 2. Load most-resident surfaces first.
84
85 If you fill up VRAM or AGP memory, there is no contingency for purging to make room for the next one.
86 Therefore, you should load the surfaces you plan to use the most frequently first.
87 Sooner or later, I will code LRU replacement to help this.
88
89 TODO:
90 Some kind of posterized mode for resolutions < 640x480.
91 Window support / fullscreen toggle.
92 Figure out how much VRAM is available. Put in video->info->video_mem.
93 Track VRAM usage.
94
95 BUGS:
96 I can't create a hardware surface the same size as the screen?! How to fix?
97
98
99
100 COMPILE OPTIONS:
101
102 DSP_TRY_CC_AND_AA - Define if you want to try HWA color-key and alpha blitters
103 HW color-key blitting gives substantial improvements,
104 but hw alpha is neck-and-neck with SDL's soft bitter.
105
106 DSP_NO_SYNC_VBL - Define for HWA double-buffered surfaces: don't sync
107 pseudo-flip to monitor redraw.
108
109 DSP_NO_SYNC_OPENGL - Define for OpenGL surfaces: don't sync buffer swap. Synching buffer
110 swap may result in reduced performance, but can eliminate some
111 tearing artifacts.
112 CHANGELOG:
113 09/17/00 Lots of little tweaks. Build modelist in reverse order so largest contexts
114 list first. Compared various methods with ROM methods and fixed rez switch
115 crashing bug in GL Tron. (Woohoo!)
116 */
117
118 #define DSP_TRY_CC_AND_AA
119
120 /* #define DSP_NO_SYNC_VBL */
121
122 #define DSP_NO_SYNC_OPENGL
123
124
125 #ifdef SAVE_RCSID
126 static char rcsid =
127 "@(#) $Id$";
128 #endif
129
130 #include <stdio.h>
131 #include <stdlib.h>
132
133 #if TARGET_API_MAC_CARBON
134 #include <Carbon.h>
135 #else
136 #include <LowMem.h>
137 #include <Gestalt.h>
138 #include <Devices.h>
139 #include <DiskInit.h>
140 #include <QDOffscreen.h>
141 #endif
142
143 #include "SDL_video.h"
144 #include "SDL_blit.h"
145 #include "SDL_error.h"
146 #include "SDL_syswm.h"
147 #include "SDL_sysvideo.h"
148 #include "SDL_dspvideo.h"
149 #include "SDL_macgl_c.h"
150 #include "SDL_macwm_c.h"
151 #include "SDL_macmouse_c.h"
152 #include "SDL_macevents_c.h"
153
154 /* Initialization/Query functions */
155 static int DSp_VideoInit(_THIS, SDL_PixelFormat *vformat);
156 static SDL_Rect **DSp_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
157 static SDL_Surface *DSp_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
158 static int DSp_SetColors(_THIS, int firstcolor, int ncolors,
159 SDL_Color *colors);
160 static int DSp_CreatePalette(_THIS);
161 static int DSp_DestroyPalette(_THIS);
162 static void DSp_VideoQuit(_THIS);
163
164 static int DSp_GetMainDevice (_THIS, GDHandle *device);
165 static void DSp_IsHWAvailable (_THIS, SDL_PixelFormat *vformat);
166 static void DSp_DSpUpdate(_THIS, int numrects, SDL_Rect *sdl_rects);
167 static void DSp_DirectUpdate(_THIS, int numrects, SDL_Rect *sdl_rects);
168
169 /* Hardware surface functions */
170 static int DSp_SetHWAlpha(_THIS, SDL_Surface *surface, UInt8 alpha);
171 static int DSp_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key);
172 static int DSp_NewHWSurface(_THIS, CGrafPtr *port, int depth, int width, int height);
173 static int DSp_AllocHWSurface(_THIS, SDL_Surface *surface);
174 static int DSp_LockHWSurface(_THIS, SDL_Surface *surface);
175 static void DSp_UnlockHWSurface(_THIS, SDL_Surface *surface);
176 static void DSp_FreeHWSurface(_THIS, SDL_Surface *surface);
177 static int DSp_FlipHWSurface(_THIS, SDL_Surface *surface);
178 static int DSp_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dest);
179 static int DSp_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
180 SDL_Surface *dst, SDL_Rect *dstrect);
181 static int DSp_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color);
182
183 #ifdef HAVE_OPENGL
184 static void DSp_GL_SwapBuffers (_THIS);
185 #endif
186
187 #if ! TARGET_API_MAC_CARBON
188
189 #define GetPortPixRowBytes(x) ( (*(x->portPixMap))->rowBytes )
190 #define GetGDevPixMap(x) ((**(x)).gdPMap)
191 #define GetPortPixMap(x) ((*(x)).portPixMap)
192
193 #define GetPixDepth(y) ((**(y)).pixelSize)
194 //#define GetPixRowBytes(y) ((**(y)).rowBytes)
195 //#define GetPixBaseAddr(y) ((**(y)).baseAddr)
196 #define GetPixCTab(y) ((**(y)).pmTable)
197 #define GetPortBitMapForCopyBits(x) (&(((GrafPtr)(x))->portBits))
198
199 #else
200 #define GetPortPixRowBytes(x) (GetPixRowBytes(GetPortPixMap(x)) )
201 #define GetGDevPixMap(x) ((**(x)).gdPMap)
202
203 #endif
204
205 typedef struct private_hwdata {
206
207 GWorldPtr offscreen; // offscreen gworld in VRAM or AGP
208
209 #ifdef DSP_TRY_CC_AND_AA
210 GWorldPtr mask; // transparent mask
211 RGBColor alpha; // alpha color
212 RGBColor trans; // transparent color
213 #endif
214
215 } private_hwdata;
216
217 typedef private_hwdata private_swdata ; /* have same fields */
218
219 /* Macintosh toolbox driver bootstrap functions */
220
221 static int DSp_Available(void)
222 {
223 /* Check for DrawSprocket */
224 /* This check is only meaningful if you weak-link DrawSprocketLib */
225 return ((Ptr)DSpStartup != (Ptr)kUnresolvedCFragSymbolAddress);
226 }
227
228 static void DSp_DeleteDevice(SDL_VideoDevice *device)
229 {
230 /* -dw- taking no chances with null pointers */
231 if (device) {
232
233 if (device->hidden) {
234
235 if (device->hidden->dspinfo)
236 free(device->hidden->dspinfo);
237
238 free(device->hidden);
239 }
240 free(device);
241 }
242 }
243
244 static SDL_VideoDevice *DSp_CreateDevice(int devindex)
245 {
246 SDL_VideoDevice *device;
247
248 /* Initialize all variables that we clean on shutdown */
249 device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
250 if ( device ) {
251 memset(device, 0, sizeof (*device));
252 device->hidden = (struct SDL_PrivateVideoData *)
253 malloc((sizeof *device->hidden));
254 if (device->hidden)
255 memset(device->hidden, 0, sizeof ( *(device->hidden) ) );
256 }
257 if ( (device == NULL) || (device->hidden == NULL) ) {
258 SDL_OutOfMemory();
259
260 if ( device ) {
261
262 if (device->hidden)
263 free (device->hidden);
264
265 free(device);
266 }
267
268 return(NULL);
269 }
270
271 /* Allocate DrawSprocket information */
272 device->hidden->dspinfo = (struct DSpInfo *)malloc(
273 (sizeof *device->hidden->dspinfo));
274 if ( device->hidden->dspinfo == NULL ) {
275 SDL_OutOfMemory();
276 free(device->hidden);
277 free(device);
278 return(0);
279 }
280 memset(device->hidden->dspinfo, 0, (sizeof *device->hidden->dspinfo));
281
282 /* Set the function pointers */
283 device->VideoInit = DSp_VideoInit;
284 device->ListModes = DSp_ListModes;
285 device->SetVideoMode = DSp_SetVideoMode;
286 device->SetColors = DSp_SetColors;
287 device->UpdateRects = NULL;
288 device->VideoQuit = DSp_VideoQuit;
289 device->AllocHWSurface = DSp_AllocHWSurface;
290 device->CheckHWBlit = NULL;
291 device->FillHWRect = NULL;
292 device->SetHWColorKey = NULL;
293 device->SetHWAlpha = NULL;
294 device->LockHWSurface = DSp_LockHWSurface;
295 device->UnlockHWSurface = DSp_UnlockHWSurface;
296 device->FlipHWSurface = DSp_FlipHWSurface;
297 device->FreeHWSurface = DSp_FreeHWSurface;
298 #ifdef HAVE_OPENGL
299 device->GL_MakeCurrent = Mac_GL_MakeCurrent;
300 device->GL_SwapBuffers = DSp_GL_SwapBuffers;
301 #endif
302 device->SetCaption = NULL;
303 device->SetIcon = NULL;
304 device->IconifyWindow = NULL;
305 device->GrabInput = NULL;
306 device->GetWMInfo = NULL;
307 device->FreeWMCursor = Mac_FreeWMCursor;
308 device->CreateWMCursor = Mac_CreateWMCursor;
309 device->ShowWMCursor = Mac_ShowWMCursor;
310 device->WarpWMCursor = Mac_WarpWMCursor;
311 device->InitOSKeymap = Mac_InitOSKeymap;
312 device->PumpEvents = Mac_PumpEvents;
313
314 device->GrabInput = NULL;
315 device->CheckMouseMode = NULL;
316
317 device->free = DSp_DeleteDevice;
318
319 return device;
320 }
321
322 VideoBootStrap DSp_bootstrap = {
323 "DSp", "MacOS DrawSprocket",
324 DSp_Available, DSp_CreateDevice
325 };
326
327 /* Use DSp/Display Manager to build mode list for given screen */
328 static SDL_Rect** DSp_BuildModeList (const GDHandle gDevice)
329 {
330 DSpContextAttributes attributes;
331 DSpContextReference context;
332 DisplayIDType displayID;
333 SDL_Rect temp_list [16];
334 SDL_Rect **mode_list;
335 int width, height, i, j;
336
337 #if TARGET_API_MAC_OSX
338
339 displayID = 0;
340
341 #else
342 /* Ask Display Manager for integer id of screen device */
343 if ( DMGetDisplayIDByGDevice (gDevice, &displayID, SDL_TRUE) != noErr ) {
344 return NULL;
345 }
346 #endif
347 /* Get the first possible DSp context on this device */
348 if ( DSpGetFirstContext (displayID, &context) != noErr ) {
349 return NULL;
350 }
351
352 if ( DSpContext_GetAttributes (context, &attributes) != noErr )
353 return NULL;
354
355 for ( i = 0; i < SDL_TABLESIZE(temp_list); i++ ) {
356 width = attributes.displayWidth;
357 height = attributes.displayHeight;
358
359 temp_list [i].x = 0 | attributes.displayBestDepth;
360 temp_list [i].y = 0;
361 temp_list [i].w = width;
362 temp_list [i].h = height;
363
364 /* DSp will report many different contexts with the same width and height. */
365 /* They will differ in bit depth and refresh rate. */
366 /* We will ignore them until we reach one with a different width/height */
367 /* When there are no more contexts to look at, we will quit building the list*/
368 while ( width == attributes.displayWidth && height == attributes.displayHeight ) {
369
370 OSStatus err = DSpGetNextContext (context, &context);
371 if (err != noErr)
372 if (err == kDSpContextNotFoundErr)
373 goto done;
374 else
375 return NULL;
376
377 if ( DSpContext_GetAttributes (context, &attributes) != noErr )
378 return NULL;
379
380 temp_list [i].x |= attributes.displayBestDepth;
381 }
382 }
383 done:
384 i++; /* i was not incremented before kicking out of the loop */
385
386 mode_list = (SDL_Rect**) malloc (sizeof (SDL_Rect*) * (i+1));
387 if (mode_list) {
388
389 /* -dw- new stuff: build in reverse order so largest sizes list first */
390 for (j = i-1; j >= 0; j--) {
391 mode_list [j] = (SDL_Rect*) malloc (sizeof (SDL_Rect));
392 if (mode_list [j])
393 memcpy (mode_list [j], &(temp_list [j]), sizeof (SDL_Rect));
394 else {
395 SDL_OutOfMemory ();
396 return NULL;
397 }
398 }
399 mode_list [i] = NULL; /* append null to the end */
400 }
401 else {
402 SDL_OutOfMemory ();
403 return NULL;
404 }
405
406 return mode_list;
407 }
408
409 static void DSp_IsHWAvailable (_THIS, SDL_PixelFormat *vformat)
410 {
411 /*
412 VRAM GWorlds are only available on OS 9 or later.
413 Even with OS 9, some display drivers won't support it,
414 so we create a test GWorld and check for errors.
415 */
416
417 long versionSystem;
418
419 dsp_vram_available = SDL_FALSE;
420 dsp_agp_available = SDL_FALSE;
421
422 Gestalt ('sysv', &versionSystem);
423 if (0x00000860 < (versionSystem & 0x0000FFFF)) {
424
425 GWorldPtr offscreen;
426 OSStatus err;
427 Rect bounds;
428
429 SetRect (&bounds, 0, 0, 320, 240);
430
431 err = NewGWorld (&offscreen, vformat->BitsPerPixel, &bounds, NULL, SDL_Display, useDistantHdwrMem | noNewDevice);
432 if (err == noErr) {
433 dsp_vram_available = SDL_TRUE;
434 DisposeGWorld (offscreen);
435 }
436
437 err = NewGWorld (&offscreen, vformat->BitsPerPixel, &bounds, NULL, SDL_Display, useLocalHdwrMem | noNewDevice);
438 if (err == noErr) {
439 DisposeGWorld (offscreen);
440 dsp_agp_available = SDL_TRUE;
441 }
442 }
443 }
444
445 static int DSp_GetMainDevice (_THIS, GDHandle *device)
446 {
447
448 #if TARGET_API_MAC_OSX
449 /* DSpUserSelectContext not available on OS X */
450 *device = GetMainDevice();
451 return 0;
452 #else
453
454 DSpContextAttributes attrib;
455 DSpContextReference context;
456 DisplayIDType display_id;
457 GDHandle main_device;
458 GDHandle device_list;
459
460 device_list = GetDeviceList ();
461 main_device = GetMainDevice ();
462
463 /* Quick check to avoid slower method when only one display exists */
464 if ( (**device_list).gdNextGD == NULL ) {
465 *device = main_device;
466 return 0;
467 }
468
469 memset (&attrib, 0, sizeof (DSpContextAttributes));
470
471 /* These attributes are hopefully supported on all devices...*/
472 attrib.displayWidth = 640;
473 attrib.displayHeight = 480;
474 attrib.displayBestDepth = 8;
475 attrib.backBufferBestDepth = 8;
476 attrib.displayDepthMask = kDSpDepthMask_All;
477 attrib.backBufferDepthMask = kDSpDepthMask_All;
478 attrib.colorNeeds = kDSpColorNeeds_Require;
479 attrib.pageCount = 1;
480
481 if (noErr != DMGetDisplayIDByGDevice (main_device, &display_id, SDL_FALSE)) {
482 SDL_SetError ("Display Manager couldn't associate GDevice with a Display ID");
483 return (-1);
484 }
485
486 /* Put up dialog on main display to select which display to use */
487 if (noErr != DSpUserSelectContext (&attrib, display_id, NULL, &context)) {
488 SDL_SetError ("DrawSprocket couldn't create a context");
489 return (-1);
490 }
491
492 if (noErr != DSpContext_GetDisplayID (context, &display_id)) {
493 SDL_SetError ("DrawSprocket couldn't get display ID");
494 return (-1);
495 }
496
497 if (noErr != DMGetGDeviceByDisplayID (display_id, &main_device, SDL_FALSE)) {
498 SDL_SetError ("Display Manager couldn't associate Display ID with GDevice");
499 return (-1);
500 }
501
502 *device = main_device;
503 return (0);
504 #endif
505 }
506
507 static int DSp_VideoInit(_THIS, SDL_PixelFormat *vformat)
508 {
509
510 NumVersion dsp_version = DSpGetVersion ();
511
512 if ( (dsp_version.majorRev == 1 && dsp_version.minorAndBugRev < 0x73) ||
513 (dsp_version.majorRev < 1) ) {
514
515 /* StandardAlert (kAlertStopAlert, "\pError!",
516 "\pI need DrawSprocket 1.7.3 or later!\n"
517 "You can find a newer version at http://www.apple.com/swupdates.",
518 NULL, NULL);
519 */
520 SDL_SetError ("DrawSprocket version is too old. Need 1.7.3 or later.");
521 return (-1);
522 }
523
524 if ( DSpStartup () != noErr ) {
525 SDL_SetError ("DrawSprocket couldn't startup");
526 return(-1);
527 }
528
529 /* Start DSpintosh events */
530 Mac_InitEvents(this);
531
532 /* Get a handle to the main monitor, or choose one on multiple monitor setups */
533 if ( DSp_GetMainDevice(this, &SDL_Display) < 0)
534 return (-1);
535
536 /* Determine pixel format */
537 vformat->BitsPerPixel = GetPixDepth ( (**SDL_Display).gdPMap );
538 dsp_old_depth = vformat->BitsPerPixel;
539
540 switch (vformat->BitsPerPixel) {
541 case 16:
542 vformat->Rmask = 0x00007c00;
543 vformat->Gmask = 0x000003e0;
544 vformat->Bmask = 0x0000001f;
545 break;
546 default:
547 break;
548 }
549
550 if ( DSp_CreatePalette (this) < 0 ) {
551
552 SDL_SetError ("Could not create palette");
553 return (-1);
554 }
555
556 /* Get a list of available fullscreen modes */
557 SDL_modelist = DSp_BuildModeList (SDL_Display);
558 if (SDL_modelist == NULL) {
559 SDL_SetError ("DrawSprocket could not build a mode list");
560 return (-1);
561 }
562
563 /* Check for VRAM and AGP GWorlds for HW Blitting */
564 DSp_IsHWAvailable (this, vformat);
565
566 this->info.wm_available = 0;
567
568 if (dsp_vram_available || dsp_agp_available) {
569
570 this->info.hw_available = SDL_TRUE;
571
572 this->CheckHWBlit = DSp_CheckHWBlit;
573 this->info.blit_hw = SDL_TRUE;
574
575 this->FillHWRect = DSp_FillHWRect;
576 this->info.blit_fill = SDL_TRUE;
577
578 #ifdef DSP_TRY_CC_AND_AA
579 this->SetHWColorKey = DSp_SetHWColorKey;
580 this->info.blit_hw_CC = SDL_TRUE;
581
582 this->SetHWAlpha = DSp_SetHWAlpha;
583 this->info.blit_hw_A = SDL_TRUE;
584 #endif
585
586 }
587
588 return(0);
589 }
590
591 static SDL_Rect **DSp_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
592 {
593 static SDL_Rect *dsp_modes[16];
594 int i = 0, j = 0;
595
596 if ( format->BitsPerPixel == 0 )
597 return ( (SDL_Rect**) NULL );
598
599 while (SDL_modelist[i] != NULL) {
600
601 if (SDL_modelist[i]->x & format->BitsPerPixel) {
602 dsp_modes[j] = SDL_modelist[i];
603 j++;
604 }
605 i++;
606 }
607
608 dsp_modes[j] = NULL;
609
610 return dsp_modes;
611 }
612
613 /* Various screen update functions available */
614 static void DSp_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
615
616 static volatile unsigned int retrace_count = 0; /* -dw- need volatile because it updates asychronously */
617
618 #if ! TARGET_API_MAC_OSX
619 Boolean DSp_VBLProc ( DSpContextReference context, void *ref_con )
620 {
621 retrace_count++;
622
623 return 1; /* Darrell, is this right? */
624 }
625 #endif
626
627 static void DSp_SetHWError (OSStatus err, int is_agp)
628 {
629 char message[1024];
630 const char *fmt, *mem;
631
632 if ( is_agp ) {
633 mem = "AGP Memory";
634 } else {
635 mem = "VRAM";
636 }
637 switch(err) {
638 case memFullErr:
639 fmt = "Hardware surface possible but not enough %s available";
640 break;
641 case cDepthErr:
642 fmt = "Hardware surface possible but invalid color depth";
643 break;
644 default:
645 fmt = "Hardware surface could not be allocated in %s - unknown error";
646 break;
647 }
648 sprintf(message, fmt, mem);
649 SDL_SetError(message);
650 }
651
652 /* put up a dialog to verify display change */
653 static int DSp_ConfirmSwitch () {
654
655 /* resource id's for dialog */
656 const int rDialog = 1002;
657 const int bCancel = 1;
658 const int bOK = 2;
659
660 DialogPtr dialog;
661 OSStatus err;
662 SInt32 response;
663 DialogItemIndex item = 0;
664 GrafPtr savePort;
665
666 GetPort (&savePort);
667
668 dialog = GetNewDialog (rDialog, NULL, (WindowPtr) -1);
669 if (dialog == NULL)
670 return (0);
671
672 SetPort (dialog);
673
674 SetDialogDefaultItem (dialog, bCancel);
675 SetDialogCancelItem (dialog, bCancel);
676
677 SetEventMask (everyEvent);
678 FlushEvents (everyEvent, 0);
679
680 /* On MacOS 8.5 or later, we can make the dialog go away after 15 seconds */
681 /* This is good since it's possible user can't even see the dialog! */
682 /* Requires linking to DialogsLib */
683 err = Gestalt(gestaltSystemVersion,&response);
684 if (err == noErr && response >= 0x00000850) {
685 SetDialogTimeout(dialog, bCancel, 15);
686 }
687
688 do {
689
690 ModalDialog ( NULL, &item );
691
692 } while ( item != bCancel && item != bOK && err != noErr);
693
694 DisposeWindow (dialog);
695 SetPort (savePort);
696
697 SetEventMask(everyEvent - autoKeyMask);
698 FlushEvents(everyEvent, 0);
699
700 return (item - 1);
701 }
702
703 static void DSp_UnsetVideoMode(_THIS, SDL_Surface *current)
704 {
705
706
707 if ( current->flags & SDL_OPENGL ) {
708 Mac_GL_Quit (this);
709 }
710
711 if (dsp_context != NULL) {
712
713 GWorldPtr front;
714 DSpContext_GetFrontBuffer (dsp_context, &front);
715
716 if (front != dsp_back_buffer)
717 DisposeGWorld (dsp_back_buffer);
718
719 if (current->hwdata)
720 free (current->hwdata);
721
722 DSpContext_SetState (dsp_context, kDSpContextState_Inactive );
723 DSpContext_Release (dsp_context);
724
725 dsp_context = NULL;
726 }
727
728 if (SDL_Window != NULL) {
729 DisposeWindow (SDL_Window);
730 SDL_Window = NULL;
731 }
732
733 current->pixels = NULL;
734 current->flags = 0;
735 }
736
737 static SDL_Surface *DSp_SetVideoMode(_THIS,
738 SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
739 {
740
741 DisplayIDType display_id;
742 DSpContextAttributes attrib;
743 Fixed freq;
744 OSStatus err;
745 UInt32 rmask = 0, gmask = 0, bmask = 0;
746
747 int page_count;
748 int double_buf;
749 int hw_surface;
750 int use_dsp_back_buffer;
751
752 DSp_UnsetVideoMode (this, current);
753
754 if (bpp != dsp_old_depth)
755 DSp_DestroyPalette (this);
756
757 double_buf = (flags & SDL_DOUBLEBUF) != 0;
758 hw_surface = (flags & SDL_HWSURFACE) != 0;
759 use_dsp_back_buffer = !dsp_vram_available || !hw_surface ;
760
761 current->flags |= SDL_FULLSCREEN;
762
763 rebuild:
764
765 if ( double_buf && use_dsp_back_buffer ) {
766 page_count = 2;
767 } else {
768 page_count = 1;
769 }
770
771 memset (&attrib, 0, sizeof (DSpContextAttributes));
772 attrib.displayWidth = width;
773 attrib.displayHeight = height;
774 attrib.displayBestDepth = bpp;
775 attrib.backBufferBestDepth = bpp;
776 attrib.displayDepthMask = kDSpDepthMask_All;
777 attrib.backBufferDepthMask = kDSpDepthMask_All;
778 attrib.colorNeeds = kDSpColorNeeds_Require;
779 attrib.colorTable = 0;
780 attrib.pageCount = page_count;
781 #if TARGET_API_MAC_OSX
782
783 if ( DSpFindBestContext (&attrib, &dsp_context) != noErr ) {
784 SDL_SetError ("DrawSprocket couldn't find a context");
785 return NULL;
786 }
787
788 #else
789 if ( noErr != DMGetDisplayIDByGDevice (SDL_Display, &display_id, SDL_FALSE) ) {
790 SDL_SetError ("Display Manager couldn't associate GDevice with display_id");
791 return NULL;
792 }
793 if ( DSpFindBestContextOnDisplayID (&attrib, &dsp_context, display_id) != noErr ) {
794 SDL_SetError ("DrawSprocket couldn't find a suitable context on given display");
795 return NULL;
796 }
797
798 #endif
799 if ( DSpContext_Reserve (dsp_context, &attrib) != noErr ) {
800 SDL_SetError ("DrawSprocket couldn't get the needed resources to build the display");
801 return NULL;
802 }
803
804 if ( (err = DSpContext_SetState (dsp_context, kDSpContextState_Active)) != noErr ) {
805
806 if (err == kDSpConfirmSwitchWarning) {
807
808 if ( ! DSp_ConfirmSwitch () ) {
809
810 DSpContext_Release (dsp_context);
811 dsp_context = NULL;
812 SDL_SetError ("User cancelled display switch");
813 return NULL;
814 }
815 else
816 /* Have to reactivate context. Why? */
817 DSpContext_SetState (dsp_context, kDSpContextState_Active);
818
819 }
820 else {
821 SDL_SetError ("DrawSprocket couldn't activate the context");
822 return NULL;
823 }
824 }
825
826
827 if (bpp != dsp_old_depth) {
828
829 DSp_CreatePalette (this);
830
831 /* update format if display depth changed */
832 if (bpp == 16) {
833
834 rmask = 0x00007c00;
835 gmask = 0x000003e0;
836 bmask = 0x0000001f;
837 }
838 if ( ! SDL_ReallocFormat (current, bpp, rmask, gmask, bmask, 0 ) ) {
839
840 SDL_SetError ("Could not reallocate video format.");
841 return(NULL);
842 }
843 }
844
845 if (!double_buf) {
846
847 /* single-buffer context */
848 DSpContext_GetFrontBuffer (dsp_context, &dsp_back_buffer);
849
850 current->hwdata = (private_hwdata*) malloc (sizeof (private_hwdata));
851 if (current ->hwdata == NULL) {
852 SDL_OutOfMemory ();
853 return NULL;
854 }
855 current->hwdata->offscreen = dsp_back_buffer;
856 current->flags |= SDL_HWSURFACE;
857 this->UpdateRects = DSp_DirectUpdate;
858 }
859 else if ( use_dsp_back_buffer ) {
860
861 DSpContext_GetBackBuffer (dsp_context, kDSpBufferKind_Normal, &dsp_back_buffer);
862
863 current->flags |= SDL_DOUBLEBUF | SDL_SWSURFACE; /* only front buffer is in VRAM */
864 this->UpdateRects = DSp_DSpUpdate;
865 }
866 else if ( DSp_NewHWSurface(this, &dsp_back_buffer, bpp, width-1, height-1) == 0 ) {
867
868 current->hwdata = (private_hwdata*) malloc (sizeof (private_hwdata));
869 if (current ->hwdata == NULL) {
870 SDL_OutOfMemory ();
871 return NULL;
872 }
873
874 memset (current->hwdata, 0, sizeof (private_hwdata));
875 current->hwdata->offscreen = dsp_back_buffer;
876 current->flags |= SDL_DOUBLEBUF | SDL_HWSURFACE;
877 this->UpdateRects = DSp_DirectUpdate; /* hardware doesn't do update rects, must be page-flipped */
878 }
879 else {
880
881 DSpContext_Release (dsp_context);
882 use_dsp_back_buffer = SDL_TRUE;
883 goto rebuild;
884 }
885
886 current->pitch = GetPortPixRowBytes(dsp_back_buffer) & 0x3FFF;
887 current->pixels = GetPixBaseAddr(GetPortPixMap(dsp_back_buffer));
888
889 current->w = width;
890 current->h = height;
891
892 #if ! TARGET_API_MAC_OSX
893
894 if (use_dsp_back_buffer) {
895
896 DSpContext_GetMonitorFrequency (dsp_context, &freq);
897 DSpContext_SetMaxFrameRate (dsp_context, freq >> 16);
898 }
899
900
901 if ( (current->flags & SDL_HWSURFACE) || (current->flags & SDL_OPENGL) )
902 DSpContext_SetVBLProc (dsp_context, DSp_VBLProc, NULL);
903 #endif
904
905 if (bpp == 8)
906 current->flags |= SDL_HWPALETTE;
907
908 if (flags & SDL_OPENGL) {
909
910 Rect rect;
911 RGBColor rgb = { 0.0, 0.0, 0.0 };
912 GrafPtr save_port;
913
914 SetRect (&rect, 0, 0, width, height);
915 SDL_Window = NewCWindow(nil, &( (**SDL_Display).gdRect), "\p", SDL_TRUE, plainDBox, (WindowPtr)-1, SDL_FALSE, 0);
916
917 if (SDL_Window == NULL) {
918
919 SDL_SetError ("DSp_SetVideoMode : OpenGL window could not be created.");
920 return NULL;
921 }
922
923 /* Set window color to black to avoid white flash*/
924 GetPort (&save_port);
925 SetPort (SDL_Window);
926 RGBForeColor (&rgb);
927 PaintRect (&rect);
928 SetPort (save_port);
929
930 SetPortWindowPort (SDL_Window);
931 SelectWindow (SDL_Window);
932
933 if ( Mac_GL_Init (this) < 0 ) {
934
935 SDL_SetError ("DSp_SetVideoMode : could not create OpenGL context.");
936 return NULL;
937 }
938
939 current->flags |= SDL_OPENGL;
940 }
941
942 return current;
943 }
944
945 #ifdef DSP_TRY_CC_AND_AA
946
947 static int DSp_MakeHWMask (_THIS, SDL_Surface *surface)
948 {
949 GDHandle save_device;
950 CGrafPtr save_port;
951 GWorldPtr temp;
952 RGBColor black = { 0, 0, 0 };
953 RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF };
954 Rect rect;
955
956 Uint32 depth = GetPixDepth ( GetGDevPixMap (SDL_Display) );
957
958 SetRect (&rect, 0, 0, surface->w, surface->h);
959
960 if ( noErr != NewGWorld (&(surface->hwdata->mask), depth, &rect, 0, SDL_Display, 0 ) < 0 ) {
961
962 SDL_OutOfMemory ();
963 return (-1);
964 }
965
966 if ( noErr != NewGWorld (&temp, depth, &rect, 0 , SDL_Display, 0 ) ) {
967
968 SDL_OutOfMemory ();
969 return (-1);
970 }
971
972
973 GetGWorld (&save_port, &save_device);
974 SetGWorld (surface->hwdata->mask, SDL_Display);
975
976 RGBForeColor (&white);
977 PaintRect (&rect);
978
979 RGBBackColor (&(surface->hwdata->trans));
980
981 CopyBits ( GetPortBitMapForCopyBits(surface->hwdata->offscreen),
982 GetPortBitMapForCopyBits(surface->hwdata->mask),
983 &rect, &rect, transparent, NULL );
984
985 SetGWorld (surface->hwdata->mask, SDL_Display);
986 SetGWorld (save_port, save_device);
987 return (0);
988 }
989
990 static int DSp_SetHWAlpha(_THIS, SDL_Surface *surface, UInt8 alpha)
991 {
992 surface->hwdata->alpha.red = (alpha / 255.0) * 65535;
993 surface->hwdata->alpha.blue = (alpha / 255.0) * 65535;
994 surface->hwdata->alpha.green = (alpha / 255.0) * 65535;
995
996 surface->flags |= SDL_SRCALPHA;
997
998 if (surface->flags & SDL_SRCCOLORKEY) {
999 return(DSp_MakeHWMask (this, surface));
1000 }
1001 return(0);
1002 }
1003
1004 static int DSp_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
1005 {
1006 CGrafPtr save_port;
1007 GDHandle save_device;
1008
1009 GetGWorld (&save_port, &save_device);
1010 SetGWorld (surface->hwdata->offscreen, NULL);
1011
1012 Index2Color (key, &(surface->hwdata->trans));
1013 surface->flags |= SDL_SRCCOLORKEY;
1014
1015 SetGWorld (save_port, save_device);
1016
1017 if ( surface->flags & SDL_SRCALPHA ) {
1018 return(DSp_MakeHWMask (this, surface));
1019 }
1020 return(0);
1021 }
1022
1023 #endif /* DSP_TRY_CC_AND_AA */
1024
1025 static int DSp_NewHWSurface(_THIS, CGrafPtr *port, int depth, int width, int height) {
1026
1027 OSStatus err;
1028 Rect bounds;
1029
1030 SetRect (&bounds, 0, 0, width, height);
1031
1032 if (dsp_vram_available) {
1033 /* try VRAM */
1034 err = NewGWorld (port, depth, &bounds, 0 , SDL_Display, useDistantHdwrMem | noNewDevice );
1035 if (err != noErr)
1036 DSp_SetHWError (err, SDL_FALSE);
1037 else
1038 return (0);
1039 }
1040
1041 if (dsp_agp_available) {
1042 /* try AGP */
1043 err = NewGWorld (port, depth, &bounds, 0 , SDL_Display, useLocalHdwrMem | noNewDevice );
1044
1045 if (err != noErr)
1046 DSp_SetHWError (err, SDL_TRUE);
1047 else
1048 return (0);
1049 }
1050
1051 return (-1);
1052 }
1053
1054 static int DSp_AllocHWSurface(_THIS, SDL_Surface *surface)
1055 {
1056 GWorldPtr temp;
1057
1058 if ( DSp_NewHWSurface (this, &temp, surface->format->BitsPerPixel, surface->w, surface->h) < 0 )
1059 return (-1);
1060
1061 surface->hwdata = (private_hwdata*) malloc (sizeof (private_hwdata));
1062 if (surface->hwdata == NULL) {
1063 SDL_OutOfMemory ();
1064 return -1;
1065 }
1066
1067 memset (surface->hwdata, 0, sizeof(private_hwdata));
1068 surface->hwdata->offscreen = temp;
1069 surface->pitch = GetPixRowBytes (GetPortPixMap (temp)) & 0x3FFF;
1070 surface->pixels = GetPixBaseAddr (GetPortPixMap (temp));
1071 surface->flags |= SDL_HWSURFACE;
1072 #ifdef DSP_TRY_CC_AND_AA
1073 surface->flags |= SDL_HWACCEL;
1074 #endif
1075 return 0;
1076 }
1077
1078 static void DSp_FreeHWSurface(_THIS, SDL_Surface *surface)
1079 {
1080 if (surface->hwdata->offscreen != NULL)
1081 DisposeGWorld (surface->hwdata->offscreen);
1082 free (surface->hwdata);
1083
1084 surface->pixels = NULL;
1085 }
1086
1087 static int DSp_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dest)
1088 {
1089 int accelerated;
1090
1091 /* Set initial acceleration on */
1092 src->flags |= SDL_HWACCEL;
1093
1094 /* Set the surface attributes */
1095 if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
1096 if ( ! this->info.blit_hw_A ) {
1097 src->flags &= ~SDL_HWACCEL;
1098 }
1099 }
1100 if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
1101 if ( ! this->info.blit_hw_CC ) {
1102 src->flags &= ~SDL_HWACCEL;
1103 }
1104 }
1105
1106 /* Check to see if final surface blit is accelerated */
1107 accelerated = !!(src->flags & SDL_HWACCEL);
1108 if ( accelerated ) {
1109 src->map->hw_blit = DSp_HWAccelBlit;
1110 }
1111 return(accelerated);
1112 }
1113
1114 static int DSp_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
1115 SDL_Surface *dst, SDL_Rect *dstrect)
1116 {
1117 CGrafPtr save_port;
1118 GDHandle save_device;
1119 Rect src_rect, dst_rect;
1120 RGBColor black = { 0, 0, 0 };
1121 RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF };
1122
1123 #ifdef DSP_TRY_CC_AND_AA
1124 UInt32 mode;
1125 #endif
1126
1127 SetRect (&src_rect, srcrect->x, srcrect->y, srcrect->x + srcrect->w, srcrect->y + srcrect->h);
1128 SetRect (&dst_rect, dstrect->x, dstrect->y, dstrect->x + dstrect->w, dstrect->y + dstrect->h);
1129
1130 GetGWorld (&save_port, &save_device);
1131 SetGWorld (dst->hwdata->offscreen, NULL);
1132
1133 RGBForeColor (&black);
1134 RGBBackColor (&white);
1135
1136 #ifdef DSP_TRY_CC_AND_AA
1137
1138 if ( (src->flags & SDL_SRCCOLORKEY) &&
1139 (src->flags & SDL_SRCALPHA) ) {
1140
1141 OpColor (&(src->hwdata->alpha));
1142
1143 CopyDeepMask ( GetPortBitMapForCopyBits(src->hwdata->offscreen),
1144 GetPortBitMapForCopyBits(src->hwdata->mask),
1145 GetPortBitMapForCopyBits(dst->hwdata->offscreen),
1146 &src_rect, &src_rect, &dst_rect,
1147 blend,
1148 NULL );
1149 }
1150 else {
1151
1152 if ( src->flags & SDL_SRCCOLORKEY) {
1153 RGBBackColor (&(src->hwdata->trans) );
1154 mode = transparent;
1155 }
1156 else if (src->flags & SDL_SRCALPHA) {
1157
1158 OpColor (&(src->hwdata->alpha));
1159 mode = blend;
1160 }
1161 else {
1162
1163 mode = srcCopy;
1164 }
1165
1166 CopyBits ( GetPortBitMapForCopyBits(src->hwdata->offscreen),
1167 GetPortBitMapForCopyBits(dst->hwdata->offscreen),
1168 &src_rect, &dst_rect, mode, NULL );
1169 }
1170 #else
1171
1172 CopyBits ( &(((GrafPtr)(src->hwdata->offscreen))->portBits),
1173 &(((GrafPtr)(dst->hwdata->offscreen))->portBits),
1174 &src_rect, &dst_rect, srcCopy, NULL );
1175
1176 #endif /* DSP_TRY_CC_AND_AA */
1177
1178 SetGWorld (save_port, save_device);
1179
1180 return(0);
1181 }
1182
1183 static int DSp_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color)
1184 {
1185 CGrafPtr save_port;
1186 GDHandle save_device;
1187 Rect fill_rect;
1188 RGBColor rgb;
1189
1190 SetRect (&fill_rect, rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
1191
1192 GetGWorld (&save_port, &save_device);
1193 SetGWorld (dst->hwdata->offscreen, NULL);
1194
1195 Index2Color (color, &rgb);
1196
1197 RGBForeColor (&rgb);
1198 PaintRect (&fill_rect);
1199
1200 SetGWorld (save_port, save_device);
1201
1202 return(0);
1203 }
1204
1205 static int DSp_FlipHWSurface(_THIS, SDL_Surface *surface)
1206 {
1207 if ( (surface->flags & SDL_HWSURFACE) ) {
1208 CGrafPtr dsp_front_buffer, save_port;
1209 Rect rect;
1210
1211 unsigned int old_count;
1212
1213 /* pseudo page flipping for VRAM back buffer*/
1214 DSpContext_GetFrontBuffer (dsp_context, &dsp_front_buffer);
1215 SetRect (&rect, 0, 0, surface->w-1, surface->h-1);
1216
1217 GetPort ((GrafPtr *)&save_port);
1218 SetPort ((GrafPtr)dsp_front_buffer);
1219
1220 /* wait for retrace */
1221 /* I have tried doing the swap in interrupt routine (VBL Proc) to do */
1222 /* it asynchronously, but apparently CopyBits isn't interrupt safe */
1223
1224 #if ! TARGET_API_MAC_OSX
1225 #ifndef DSP_NO_SYNC_VBL
1226 old_count = retrace_count;
1227 while (old_count == retrace_count)
1228 ;
1229 #endif
1230 #endif
1231
1232 CopyBits ( GetPortBitMapForCopyBits(dsp_back_buffer),
1233 GetPortBitMapForCopyBits(dsp_front_buffer),
1234 &rect, &rect, srcCopy, NULL );
1235
1236 SetPort ((GrafPtr)save_port);
1237
1238 } else {
1239 /* not really page flipping at all: DSp just blits the dirty rectangles from DSp_UpdateRects */
1240 Boolean busy_flag;
1241 DSpContext_SwapBuffers (dsp_context, NULL, &busy_flag); /* this waits for VBL */
1242 DSpContext_GetBackBuffer (dsp_context, kDSpBufferKind_Normal, &dsp_back_buffer);
1243 surface->pixels = GetPixBaseAddr( GetPortPixMap(dsp_back_buffer) );
1244 }
1245 return(0);
1246 }
1247
1248 static int DSp_LockHWSurface(_THIS, SDL_Surface *surface)
1249 {
1250 if ( LockPixels (GetGWorldPixMap (surface->hwdata->offscreen)) )
1251 return 0;
1252 else
1253 return -1;
1254 }
1255
1256 static void DSp_UnlockHWSurface(_THIS, SDL_Surface *surface)
1257 {
1258 UnlockPixels (GetGWorldPixMap (surface->hwdata->offscreen));
1259 }
1260
1261 static void DSp_DirectUpdate(_THIS, int numrects, SDL_Rect *sdl_rects)
1262 {
1263 return;
1264 }
1265
1266 static void DSp_DSpUpdate(_THIS, int numrects, SDL_Rect *sdl_rects)
1267 {
1268 #if ! TARGET_API_MAC_OSX /* Unsupported DSp in here */
1269 int i;
1270 Rect rect;
1271
1272 for (i = 0; i < numrects; i++) {
1273
1274 rect.top = sdl_rects[i].y;
1275 rect.left = sdl_rects[i].x;
1276 rect.bottom = sdl_rects[i].h + sdl_rects[i].y;
1277 rect.right = sdl_rects[i].w + sdl_rects[i].x;
1278
1279 DSpContext_InvalBackBufferRect (dsp_context, &rect);
1280 }
1281 #endif
1282 }
1283
1284 static int DSp_CreatePalette(_THIS) {
1285
1286
1287 /* Create our palette */
1288 SDL_CTab = (CTabHandle)NewHandle(sizeof(ColorSpec)*256 + 8);
1289 if ( SDL_CTab == nil ) {
1290 SDL_OutOfMemory();
1291 return(-1);
1292 }
1293 (**SDL_CTab).ctSeed = GetCTSeed();
1294 (**SDL_CTab).ctFlags = 0;
1295 (**SDL_CTab).ctSize = 255;
1296 CTabChanged(SDL_CTab);
1297 SDL_CPal = NewPalette(256, SDL_CTab, pmExplicit+pmTolerant, 0);
1298
1299 return 0;
1300 }
1301
1302 static int DSp_DestroyPalette(_THIS) {
1303
1304 /* Free palette and restore original one */
1305 if ( SDL_CTab != nil ) {
1306 DisposeHandle((Handle)SDL_CTab);
1307 SDL_CTab = nil;
1308 }
1309 if ( SDL_CPal != nil ) {
1310 DisposePalette(SDL_CPal);
1311 SDL_CPal = nil;
1312 }
1313 RestoreDeviceClut(SDL_Display);
1314
1315 return (0);
1316 }
1317
1318 static int DSp_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
1319 {
1320 CTabHandle cTab;
1321
1322 int i;
1323
1324 cTab = SDL_CTab;
1325
1326 /* Verify the range of colors */
1327 if ( (firstcolor+ncolors) > ((**cTab).ctSize+1) ) {
1328 return(0);
1329 }
1330
1331 /* Set the screen palette and update the display */
1332 for(i = 0; i < ncolors; i++) {
1333 int j = firstcolor + i;
1334 (**cTab).ctTable[j].value = j;
1335 (**cTab).ctTable[j].rgb.red = colors[i].r << 8 | colors[i].r;
1336 (**cTab).ctTable[j].rgb.green = colors[i].g << 8 | colors[i].g;
1337 (**cTab).ctTable[j].rgb.blue = colors[i].b << 8 | colors[i].b;
1338 }
1339
1340 SetGDevice(SDL_Display);
1341 SetEntries(0, (**cTab).ctSize, (ColorSpec *)&(**cTab).ctTable);
1342
1343 return(1);
1344 }
1345
1346 void DSp_VideoQuit(_THIS)
1347 {
1348 int i;
1349
1350 /* Free current video mode */
1351 DSp_UnsetVideoMode(this, this->screen);
1352
1353 /* Free Palette and restore original */
1354 DSp_DestroyPalette (this);
1355
1356 /* Free list of video modes */
1357 if ( SDL_modelist != NULL ) {
1358 for ( i=0; SDL_modelist[i]; i++ ) {
1359 free(SDL_modelist[i]);
1360 }
1361 free(SDL_modelist);
1362 SDL_modelist = NULL;
1363 }
1364
1365 /* Unload DrawSprocket */
1366 DSpShutdown ();
1367 }
1368
1369 #ifdef HAVE_OPENGL
1370
1371 /* swap buffers with v-sync */
1372 static void DSp_GL_SwapBuffers (_THIS) {
1373
1374 #ifndef DSP_NO_SYNC_OPENGL
1375
1376 unsigned int old_count;
1377
1378 old_count = retrace_count;
1379 while (old_count == retrace_count)
1380 ;
1381 #endif
1382
1383 aglSwapBuffers (glContext);
1384 }
1385
1386 #endif