Mercurial > sdl-ios-xcode
annotate src/video/macdsp/SDL_dspvideo.c @ 1133:609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
To: SDL Developers <sdl@libsdl.org>
From: =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb@algonet.se>
Date: Mon, 30 May 2005 23:29:04 +0200
Subject: [SDL] Mac OS X Video Drivers [patch]
I've updated/added the Carbon and X11 video drivers
to the Mac OS X port of SDL 1.2 (the CVS version),
and made the Cocoa driver and runtime *optional*.
The default is still Cocoa, and the "Quartz" driver.
But you can now also use "toolbox" for Carbon, and
"x11" for running with Apple's (or other) X11 server:
export SDL_VIDEODRIVER=x11
export SDL_VIDEO_GL_DRIVER=/usr/X11R6/lib/libGL.dylib
It also checks if the frameworks are available, by a:
#include <Carbon/Carbon.h> or #import <Cocoa/Cocoa.h>
(this should make it configure on plain Darwin as well?)
Here are the new configure targets:
--enable-video-cocoa use Cocoa/Quartz video driver default=yes
--enable-video-carbon use Carbon/QuickDraw video driver default=yes
--enable-video-x11 use X11 video driver default=no
./configure --enable-video-cocoa --enable-video-carbon
--enable-video-x11 \
--x-includes=/usr/X11R6/include --x-libraries=/usr/X11R6/lib
The Carbon version is just an updated version of the old
SDL driver for Mac OS 9, and could probably be improved...
(but it does work, including the Carbon version of SDLmain)
If you disable cocoa, you can run with -framework Carbon only,
and the C version of SDL_main.c. And if you disable carbon too,
you can still use the X11 version which doesn't require SDLmain.
I updated the DrawSprocket version, but did not include it.
(no blitters or VRAM GWorlds etc. available on OS X anyway)
Besides for Mac OS 9, I don't think there's any use for it ?
And note that any performance on Mac OS X equals OpenGL anyway...
You can get "fair" software SDL results on captured CG displays,
but for decent frame rates you need to be using GL for rendering.
Finally, here is the patch itself:
http://www.algonet.se/~afb/SDL-12CVS-macvideo.patch
--anders
PS. It says "video", but as usual it applies to mouse/keyboard too.
------
To: A list for developers using the SDL library <sdl@libsdl.org>
From: =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb@algonet.se>
Date: Sun, 4 Sep 2005 10:02:15 +0200
Subject: [SDL] Updated Mac patch
Updated the previous Mac patch to disable Carbon by default.
Also "fixed" the SDL.spec again, so that it builds on Darwin.
http://www.algonet.se/~afb/SDL-1.2.9-mac.patch
Also applied fine to SDL12 CVS, when I tried it.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Thu, 08 Sep 2005 06:16:14 +0000 |
parents | c1c2efca4548 |
children | cf6133247d34 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
3 Copyright (C) 1997-2004 Sam Lantinga |
0 | 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 | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
20 slouken@libsdl.org |
0 | 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 | |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
69 2. *MacOS 9 or later (but *not* Mac OS X) for hardware accelerated blit / fill |
0 | 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 | |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
133 #if defined(__APPLE__) && defined(__MACH__) |
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
134 #include <Carbon/Carbon.h> |
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
135 #include <DrawSprocket/DrawSprocket.h> |
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
136 #elif TARGET_API_MAC_CARBON && (UNIVERSAL_INTERFACES_VERSION > 0x0335) |
0 | 137 #include <Carbon.h> |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
138 #include <DrawSprocket.h> |
0 | 139 #else |
140 #include <LowMem.h> | |
141 #include <Gestalt.h> | |
142 #include <Devices.h> | |
143 #include <DiskInit.h> | |
144 #include <QDOffscreen.h> | |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
145 #include <DrawSprocket.h> |
0 | 146 #endif |
147 | |
148 #include "SDL_video.h" | |
149 #include "SDL_blit.h" | |
150 #include "SDL_error.h" | |
151 #include "SDL_syswm.h" | |
152 #include "SDL_sysvideo.h" | |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
153 #include "SDL_pixels_c.h" |
0 | 154 #include "SDL_dspvideo.h" |
155 #include "SDL_macgl_c.h" | |
156 #include "SDL_macwm_c.h" | |
157 #include "SDL_macmouse_c.h" | |
158 #include "SDL_macevents_c.h" | |
159 | |
160 /* Initialization/Query functions */ | |
161 static int DSp_VideoInit(_THIS, SDL_PixelFormat *vformat); | |
162 static SDL_Rect **DSp_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | |
163 static SDL_Surface *DSp_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | |
164 static int DSp_SetColors(_THIS, int firstcolor, int ncolors, | |
165 SDL_Color *colors); | |
166 static int DSp_CreatePalette(_THIS); | |
167 static int DSp_DestroyPalette(_THIS); | |
168 static void DSp_VideoQuit(_THIS); | |
169 | |
170 static int DSp_GetMainDevice (_THIS, GDHandle *device); | |
171 static void DSp_IsHWAvailable (_THIS, SDL_PixelFormat *vformat); | |
172 static void DSp_DSpUpdate(_THIS, int numrects, SDL_Rect *sdl_rects); | |
173 static void DSp_DirectUpdate(_THIS, int numrects, SDL_Rect *sdl_rects); | |
174 | |
175 /* Hardware surface functions */ | |
176 static int DSp_SetHWAlpha(_THIS, SDL_Surface *surface, UInt8 alpha); | |
177 static int DSp_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key); | |
178 static int DSp_NewHWSurface(_THIS, CGrafPtr *port, int depth, int width, int height); | |
179 static int DSp_AllocHWSurface(_THIS, SDL_Surface *surface); | |
180 static int DSp_LockHWSurface(_THIS, SDL_Surface *surface); | |
181 static void DSp_UnlockHWSurface(_THIS, SDL_Surface *surface); | |
182 static void DSp_FreeHWSurface(_THIS, SDL_Surface *surface); | |
183 static int DSp_FlipHWSurface(_THIS, SDL_Surface *surface); | |
184 static int DSp_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dest); | |
185 static int DSp_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, | |
186 SDL_Surface *dst, SDL_Rect *dstrect); | |
187 static int DSp_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color); | |
188 | |
189 #ifdef HAVE_OPENGL | |
190 static void DSp_GL_SwapBuffers (_THIS); | |
191 #endif | |
192 | |
193 #if ! TARGET_API_MAC_CARBON | |
194 | |
195 #define GetPortPixRowBytes(x) ( (*(x->portPixMap))->rowBytes ) | |
196 #define GetGDevPixMap(x) ((**(x)).gdPMap) | |
197 #define GetPortPixMap(x) ((*(x)).portPixMap) | |
198 | |
199 #define GetPixDepth(y) ((**(y)).pixelSize) | |
200 //#define GetPixRowBytes(y) ((**(y)).rowBytes) | |
201 //#define GetPixBaseAddr(y) ((**(y)).baseAddr) | |
202 #define GetPixCTab(y) ((**(y)).pmTable) | |
203 #define GetPortBitMapForCopyBits(x) (&(((GrafPtr)(x))->portBits)) | |
204 | |
205 #else | |
206 #define GetPortPixRowBytes(x) (GetPixRowBytes(GetPortPixMap(x)) ) | |
207 #define GetGDevPixMap(x) ((**(x)).gdPMap) | |
208 | |
209 #endif | |
210 | |
211 typedef struct private_hwdata { | |
212 | |
213 GWorldPtr offscreen; // offscreen gworld in VRAM or AGP | |
214 | |
215 #ifdef DSP_TRY_CC_AND_AA | |
216 GWorldPtr mask; // transparent mask | |
217 RGBColor alpha; // alpha color | |
218 RGBColor trans; // transparent color | |
219 #endif | |
220 | |
221 } private_hwdata; | |
222 | |
223 typedef private_hwdata private_swdata ; /* have same fields */ | |
224 | |
225 /* Macintosh toolbox driver bootstrap functions */ | |
226 | |
227 static int DSp_Available(void) | |
228 { | |
229 /* Check for DrawSprocket */ | |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
230 #if ! TARGET_API_MAC_OSX |
0 | 231 /* This check is only meaningful if you weak-link DrawSprocketLib */ |
232 return ((Ptr)DSpStartup != (Ptr)kUnresolvedCFragSymbolAddress); | |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
233 #else |
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
234 return 1; // DrawSprocket.framework doesn't have it all, but it's there |
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
235 #endif |
0 | 236 } |
237 | |
238 static void DSp_DeleteDevice(SDL_VideoDevice *device) | |
239 { | |
240 /* -dw- taking no chances with null pointers */ | |
241 if (device) { | |
242 | |
243 if (device->hidden) { | |
244 | |
245 if (device->hidden->dspinfo) | |
246 free(device->hidden->dspinfo); | |
247 | |
248 free(device->hidden); | |
249 } | |
250 free(device); | |
251 } | |
252 } | |
253 | |
254 static SDL_VideoDevice *DSp_CreateDevice(int devindex) | |
255 { | |
256 SDL_VideoDevice *device; | |
257 | |
258 /* Initialize all variables that we clean on shutdown */ | |
259 device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice)); | |
260 if ( device ) { | |
261 memset(device, 0, sizeof (*device)); | |
262 device->hidden = (struct SDL_PrivateVideoData *) | |
263 malloc((sizeof *device->hidden)); | |
264 if (device->hidden) | |
265 memset(device->hidden, 0, sizeof ( *(device->hidden) ) ); | |
266 } | |
267 if ( (device == NULL) || (device->hidden == NULL) ) { | |
268 SDL_OutOfMemory(); | |
269 | |
270 if ( device ) { | |
271 | |
272 if (device->hidden) | |
273 free (device->hidden); | |
274 | |
275 free(device); | |
276 } | |
277 | |
278 return(NULL); | |
279 } | |
280 | |
281 /* Allocate DrawSprocket information */ | |
282 device->hidden->dspinfo = (struct DSpInfo *)malloc( | |
283 (sizeof *device->hidden->dspinfo)); | |
284 if ( device->hidden->dspinfo == NULL ) { | |
285 SDL_OutOfMemory(); | |
286 free(device->hidden); | |
287 free(device); | |
288 return(0); | |
289 } | |
290 memset(device->hidden->dspinfo, 0, (sizeof *device->hidden->dspinfo)); | |
291 | |
292 /* Set the function pointers */ | |
293 device->VideoInit = DSp_VideoInit; | |
294 device->ListModes = DSp_ListModes; | |
295 device->SetVideoMode = DSp_SetVideoMode; | |
296 device->SetColors = DSp_SetColors; | |
297 device->UpdateRects = NULL; | |
298 device->VideoQuit = DSp_VideoQuit; | |
299 device->AllocHWSurface = DSp_AllocHWSurface; | |
300 device->CheckHWBlit = NULL; | |
301 device->FillHWRect = NULL; | |
302 device->SetHWColorKey = NULL; | |
303 device->SetHWAlpha = NULL; | |
304 device->LockHWSurface = DSp_LockHWSurface; | |
305 device->UnlockHWSurface = DSp_UnlockHWSurface; | |
306 device->FlipHWSurface = DSp_FlipHWSurface; | |
307 device->FreeHWSurface = DSp_FreeHWSurface; | |
308 #ifdef HAVE_OPENGL | |
309 device->GL_MakeCurrent = Mac_GL_MakeCurrent; | |
310 device->GL_SwapBuffers = DSp_GL_SwapBuffers; | |
1032
c1c2efca4548
Date: Mon, 24 Jan 2005 21:37:56 +0800
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
311 device->GL_LoadLibrary = Mac_GL_LoadLibrary; |
c1c2efca4548
Date: Mon, 24 Jan 2005 21:37:56 +0800
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
312 device->GL_GetProcAddress = Mac_GL_GetProcAddress; |
0 | 313 #endif |
314 device->SetCaption = NULL; | |
315 device->SetIcon = NULL; | |
316 device->IconifyWindow = NULL; | |
317 device->GrabInput = NULL; | |
318 device->GetWMInfo = NULL; | |
319 device->FreeWMCursor = Mac_FreeWMCursor; | |
320 device->CreateWMCursor = Mac_CreateWMCursor; | |
321 device->ShowWMCursor = Mac_ShowWMCursor; | |
322 device->WarpWMCursor = Mac_WarpWMCursor; | |
323 device->InitOSKeymap = Mac_InitOSKeymap; | |
324 device->PumpEvents = Mac_PumpEvents; | |
325 | |
326 device->GrabInput = NULL; | |
327 device->CheckMouseMode = NULL; | |
328 | |
329 device->free = DSp_DeleteDevice; | |
330 | |
331 return device; | |
332 } | |
333 | |
334 VideoBootStrap DSp_bootstrap = { | |
335 "DSp", "MacOS DrawSprocket", | |
336 DSp_Available, DSp_CreateDevice | |
337 }; | |
338 | |
339 /* Use DSp/Display Manager to build mode list for given screen */ | |
340 static SDL_Rect** DSp_BuildModeList (const GDHandle gDevice) | |
341 { | |
342 DSpContextAttributes attributes; | |
343 DSpContextReference context; | |
344 DisplayIDType displayID; | |
345 SDL_Rect temp_list [16]; | |
346 SDL_Rect **mode_list; | |
347 int width, height, i, j; | |
348 | |
349 #if TARGET_API_MAC_OSX | |
350 | |
351 displayID = 0; | |
352 | |
353 #else | |
354 /* Ask Display Manager for integer id of screen device */ | |
355 if ( DMGetDisplayIDByGDevice (gDevice, &displayID, SDL_TRUE) != noErr ) { | |
356 return NULL; | |
357 } | |
358 #endif | |
359 /* Get the first possible DSp context on this device */ | |
360 if ( DSpGetFirstContext (displayID, &context) != noErr ) { | |
361 return NULL; | |
362 } | |
363 | |
364 if ( DSpContext_GetAttributes (context, &attributes) != noErr ) | |
365 return NULL; | |
366 | |
367 for ( i = 0; i < SDL_TABLESIZE(temp_list); i++ ) { | |
368 width = attributes.displayWidth; | |
369 height = attributes.displayHeight; | |
370 | |
371 temp_list [i].x = 0 | attributes.displayBestDepth; | |
372 temp_list [i].y = 0; | |
373 temp_list [i].w = width; | |
374 temp_list [i].h = height; | |
375 | |
376 /* DSp will report many different contexts with the same width and height. */ | |
377 /* They will differ in bit depth and refresh rate. */ | |
378 /* We will ignore them until we reach one with a different width/height */ | |
379 /* When there are no more contexts to look at, we will quit building the list*/ | |
380 while ( width == attributes.displayWidth && height == attributes.displayHeight ) { | |
381 | |
382 OSStatus err = DSpGetNextContext (context, &context); | |
383 if (err != noErr) | |
384 if (err == kDSpContextNotFoundErr) | |
385 goto done; | |
386 else | |
387 return NULL; | |
388 | |
389 if ( DSpContext_GetAttributes (context, &attributes) != noErr ) | |
390 return NULL; | |
391 | |
392 temp_list [i].x |= attributes.displayBestDepth; | |
393 } | |
394 } | |
395 done: | |
396 i++; /* i was not incremented before kicking out of the loop */ | |
397 | |
398 mode_list = (SDL_Rect**) malloc (sizeof (SDL_Rect*) * (i+1)); | |
399 if (mode_list) { | |
400 | |
401 /* -dw- new stuff: build in reverse order so largest sizes list first */ | |
402 for (j = i-1; j >= 0; j--) { | |
403 mode_list [j] = (SDL_Rect*) malloc (sizeof (SDL_Rect)); | |
404 if (mode_list [j]) | |
405 memcpy (mode_list [j], &(temp_list [j]), sizeof (SDL_Rect)); | |
406 else { | |
407 SDL_OutOfMemory (); | |
408 return NULL; | |
409 } | |
410 } | |
411 mode_list [i] = NULL; /* append null to the end */ | |
412 } | |
413 else { | |
414 SDL_OutOfMemory (); | |
415 return NULL; | |
416 } | |
417 | |
418 return mode_list; | |
419 } | |
420 | |
421 static void DSp_IsHWAvailable (_THIS, SDL_PixelFormat *vformat) | |
422 { | |
423 /* | |
424 VRAM GWorlds are only available on OS 9 or later. | |
425 Even with OS 9, some display drivers won't support it, | |
426 so we create a test GWorld and check for errors. | |
427 */ | |
428 | |
429 long versionSystem; | |
430 | |
431 dsp_vram_available = SDL_FALSE; | |
432 dsp_agp_available = SDL_FALSE; | |
433 | |
434 Gestalt ('sysv', &versionSystem); | |
435 if (0x00000860 < (versionSystem & 0x0000FFFF)) { | |
436 | |
437 GWorldPtr offscreen; | |
438 OSStatus err; | |
439 Rect bounds; | |
440 | |
441 SetRect (&bounds, 0, 0, 320, 240); | |
442 | |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
443 #if useDistantHdwrMem && useLocalHdwrMem |
0 | 444 err = NewGWorld (&offscreen, vformat->BitsPerPixel, &bounds, NULL, SDL_Display, useDistantHdwrMem | noNewDevice); |
445 if (err == noErr) { | |
446 dsp_vram_available = SDL_TRUE; | |
447 DisposeGWorld (offscreen); | |
448 } | |
449 | |
450 err = NewGWorld (&offscreen, vformat->BitsPerPixel, &bounds, NULL, SDL_Display, useLocalHdwrMem | noNewDevice); | |
451 if (err == noErr) { | |
452 DisposeGWorld (offscreen); | |
453 dsp_agp_available = SDL_TRUE; | |
454 } | |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
455 #endif |
0 | 456 } |
457 } | |
458 | |
459 static int DSp_GetMainDevice (_THIS, GDHandle *device) | |
460 { | |
461 | |
462 #if TARGET_API_MAC_OSX | |
463 /* DSpUserSelectContext not available on OS X */ | |
464 *device = GetMainDevice(); | |
465 return 0; | |
466 #else | |
467 | |
468 DSpContextAttributes attrib; | |
469 DSpContextReference context; | |
470 DisplayIDType display_id; | |
471 GDHandle main_device; | |
472 GDHandle device_list; | |
473 | |
474 device_list = GetDeviceList (); | |
475 main_device = GetMainDevice (); | |
476 | |
477 /* Quick check to avoid slower method when only one display exists */ | |
478 if ( (**device_list).gdNextGD == NULL ) { | |
479 *device = main_device; | |
480 return 0; | |
481 } | |
482 | |
483 memset (&attrib, 0, sizeof (DSpContextAttributes)); | |
484 | |
485 /* These attributes are hopefully supported on all devices...*/ | |
486 attrib.displayWidth = 640; | |
487 attrib.displayHeight = 480; | |
488 attrib.displayBestDepth = 8; | |
489 attrib.backBufferBestDepth = 8; | |
490 attrib.displayDepthMask = kDSpDepthMask_All; | |
491 attrib.backBufferDepthMask = kDSpDepthMask_All; | |
492 attrib.colorNeeds = kDSpColorNeeds_Require; | |
493 attrib.pageCount = 1; | |
494 | |
495 if (noErr != DMGetDisplayIDByGDevice (main_device, &display_id, SDL_FALSE)) { | |
496 SDL_SetError ("Display Manager couldn't associate GDevice with a Display ID"); | |
497 return (-1); | |
498 } | |
499 | |
500 /* Put up dialog on main display to select which display to use */ | |
501 if (noErr != DSpUserSelectContext (&attrib, display_id, NULL, &context)) { | |
502 SDL_SetError ("DrawSprocket couldn't create a context"); | |
503 return (-1); | |
504 } | |
505 | |
506 if (noErr != DSpContext_GetDisplayID (context, &display_id)) { | |
507 SDL_SetError ("DrawSprocket couldn't get display ID"); | |
508 return (-1); | |
509 } | |
510 | |
511 if (noErr != DMGetGDeviceByDisplayID (display_id, &main_device, SDL_FALSE)) { | |
512 SDL_SetError ("Display Manager couldn't associate Display ID with GDevice"); | |
513 return (-1); | |
514 } | |
515 | |
516 *device = main_device; | |
517 return (0); | |
518 #endif | |
519 } | |
520 | |
521 static int DSp_VideoInit(_THIS, SDL_PixelFormat *vformat) | |
522 { | |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
523 NumVersion dsp_version; |
0 | 524 |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
525 dsp_version = DSpGetVersion (); |
0 | 526 |
527 if ( (dsp_version.majorRev == 1 && dsp_version.minorAndBugRev < 0x73) || | |
528 (dsp_version.majorRev < 1) ) { | |
529 | |
530 /* StandardAlert (kAlertStopAlert, "\pError!", | |
531 "\pI need DrawSprocket 1.7.3 or later!\n" | |
532 "You can find a newer version at http://www.apple.com/swupdates.", | |
533 NULL, NULL); | |
534 */ | |
535 SDL_SetError ("DrawSprocket version is too old. Need 1.7.3 or later."); | |
536 return (-1); | |
537 } | |
538 | |
539 if ( DSpStartup () != noErr ) { | |
540 SDL_SetError ("DrawSprocket couldn't startup"); | |
541 return(-1); | |
542 } | |
543 | |
544 /* Start DSpintosh events */ | |
545 Mac_InitEvents(this); | |
546 | |
547 /* Get a handle to the main monitor, or choose one on multiple monitor setups */ | |
548 if ( DSp_GetMainDevice(this, &SDL_Display) < 0) | |
549 return (-1); | |
550 | |
551 /* Determine pixel format */ | |
552 vformat->BitsPerPixel = GetPixDepth ( (**SDL_Display).gdPMap ); | |
553 dsp_old_depth = vformat->BitsPerPixel; | |
554 | |
555 switch (vformat->BitsPerPixel) { | |
556 case 16: | |
557 vformat->Rmask = 0x00007c00; | |
558 vformat->Gmask = 0x000003e0; | |
559 vformat->Bmask = 0x0000001f; | |
560 break; | |
561 default: | |
562 break; | |
563 } | |
564 | |
565 if ( DSp_CreatePalette (this) < 0 ) { | |
566 | |
567 SDL_SetError ("Could not create palette"); | |
568 return (-1); | |
569 } | |
570 | |
571 /* Get a list of available fullscreen modes */ | |
572 SDL_modelist = DSp_BuildModeList (SDL_Display); | |
573 if (SDL_modelist == NULL) { | |
574 SDL_SetError ("DrawSprocket could not build a mode list"); | |
575 return (-1); | |
576 } | |
577 | |
578 /* Check for VRAM and AGP GWorlds for HW Blitting */ | |
579 DSp_IsHWAvailable (this, vformat); | |
580 | |
581 this->info.wm_available = 0; | |
582 | |
583 if (dsp_vram_available || dsp_agp_available) { | |
584 | |
585 this->info.hw_available = SDL_TRUE; | |
586 | |
587 this->CheckHWBlit = DSp_CheckHWBlit; | |
588 this->info.blit_hw = SDL_TRUE; | |
589 | |
590 this->FillHWRect = DSp_FillHWRect; | |
591 this->info.blit_fill = SDL_TRUE; | |
592 | |
593 #ifdef DSP_TRY_CC_AND_AA | |
594 this->SetHWColorKey = DSp_SetHWColorKey; | |
595 this->info.blit_hw_CC = SDL_TRUE; | |
596 | |
597 this->SetHWAlpha = DSp_SetHWAlpha; | |
598 this->info.blit_hw_A = SDL_TRUE; | |
599 #endif | |
600 | |
601 } | |
602 | |
603 return(0); | |
604 } | |
605 | |
606 static SDL_Rect **DSp_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) | |
607 { | |
608 static SDL_Rect *dsp_modes[16]; | |
609 int i = 0, j = 0; | |
610 | |
611 if ( format->BitsPerPixel == 0 ) | |
612 return ( (SDL_Rect**) NULL ); | |
613 | |
614 while (SDL_modelist[i] != NULL) { | |
615 | |
616 if (SDL_modelist[i]->x & format->BitsPerPixel) { | |
617 dsp_modes[j] = SDL_modelist[i]; | |
618 j++; | |
619 } | |
620 i++; | |
621 } | |
622 | |
623 dsp_modes[j] = NULL; | |
624 | |
625 return dsp_modes; | |
626 } | |
627 | |
628 /* Various screen update functions available */ | |
629 static void DSp_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); | |
630 | |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
631 #if ! TARGET_API_MAC_OSX |
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
632 |
0 | 633 static volatile unsigned int retrace_count = 0; /* -dw- need volatile because it updates asychronously */ |
634 | |
635 Boolean DSp_VBLProc ( DSpContextReference context, void *ref_con ) | |
636 { | |
637 retrace_count++; | |
638 | |
639 return 1; /* Darrell, is this right? */ | |
640 } | |
641 | |
642 static void DSp_SetHWError (OSStatus err, int is_agp) | |
643 { | |
644 char message[1024]; | |
645 const char *fmt, *mem; | |
646 | |
647 if ( is_agp ) { | |
648 mem = "AGP Memory"; | |
649 } else { | |
650 mem = "VRAM"; | |
651 } | |
652 switch(err) { | |
653 case memFullErr: | |
654 fmt = "Hardware surface possible but not enough %s available"; | |
655 break; | |
656 case cDepthErr: | |
657 fmt = "Hardware surface possible but invalid color depth"; | |
658 break; | |
659 default: | |
660 fmt = "Hardware surface could not be allocated in %s - unknown error"; | |
661 break; | |
662 } | |
663 sprintf(message, fmt, mem); | |
664 SDL_SetError(message); | |
665 } | |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
666 #endif // TARGET_API_MAC_OSX |
0 | 667 |
668 /* put up a dialog to verify display change */ | |
669 static int DSp_ConfirmSwitch () { | |
670 | |
671 /* resource id's for dialog */ | |
672 const int rDialog = 1002; | |
673 const int bCancel = 1; | |
674 const int bOK = 2; | |
675 | |
676 DialogPtr dialog; | |
677 OSStatus err; | |
678 SInt32 response; | |
679 DialogItemIndex item = 0; | |
680 GrafPtr savePort; | |
681 | |
682 GetPort (&savePort); | |
683 | |
684 dialog = GetNewDialog (rDialog, NULL, (WindowPtr) -1); | |
685 if (dialog == NULL) | |
686 return (0); | |
687 | |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
688 #if TARGET_API_CARBON |
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
689 SetPort (GetDialogPort(dialog)); |
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
690 #else |
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
691 SetPort ((WindowPtr) dialog); |
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
692 #endif |
0 | 693 |
694 SetDialogDefaultItem (dialog, bCancel); | |
695 SetDialogCancelItem (dialog, bCancel); | |
696 | |
697 SetEventMask (everyEvent); | |
698 FlushEvents (everyEvent, 0); | |
699 | |
700 /* On MacOS 8.5 or later, we can make the dialog go away after 15 seconds */ | |
701 /* This is good since it's possible user can't even see the dialog! */ | |
702 /* Requires linking to DialogsLib */ | |
703 err = Gestalt(gestaltSystemVersion,&response); | |
704 if (err == noErr && response >= 0x00000850) { | |
705 SetDialogTimeout(dialog, bCancel, 15); | |
706 } | |
707 | |
708 do { | |
709 | |
710 ModalDialog ( NULL, &item ); | |
711 | |
712 } while ( item != bCancel && item != bOK && err != noErr); | |
713 | |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
714 |
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
715 DisposeDialog (dialog); |
0 | 716 SetPort (savePort); |
717 | |
718 SetEventMask(everyEvent - autoKeyMask); | |
719 FlushEvents(everyEvent, 0); | |
720 | |
721 return (item - 1); | |
722 } | |
723 | |
724 static void DSp_UnsetVideoMode(_THIS, SDL_Surface *current) | |
725 { | |
726 | |
727 | |
728 if ( current->flags & SDL_OPENGL ) { | |
729 Mac_GL_Quit (this); | |
730 } | |
731 | |
732 if (dsp_context != NULL) { | |
733 | |
734 GWorldPtr front; | |
735 DSpContext_GetFrontBuffer (dsp_context, &front); | |
736 | |
737 if (front != dsp_back_buffer) | |
738 DisposeGWorld (dsp_back_buffer); | |
739 | |
740 if (current->hwdata) | |
741 free (current->hwdata); | |
742 | |
743 DSpContext_SetState (dsp_context, kDSpContextState_Inactive ); | |
744 DSpContext_Release (dsp_context); | |
745 | |
746 dsp_context = NULL; | |
747 } | |
748 | |
749 if (SDL_Window != NULL) { | |
750 DisposeWindow (SDL_Window); | |
751 SDL_Window = NULL; | |
752 } | |
753 | |
754 current->pixels = NULL; | |
755 current->flags = 0; | |
756 } | |
757 | |
758 static SDL_Surface *DSp_SetVideoMode(_THIS, | |
759 SDL_Surface *current, int width, int height, int bpp, Uint32 flags) | |
760 { | |
761 | |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
762 #if !TARGET_API_MAC_OSX |
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
763 DisplayIDType display_id; |
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
764 Fixed freq; |
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
765 #endif |
0 | 766 DSpContextAttributes attrib; |
767 OSStatus err; | |
768 UInt32 rmask = 0, gmask = 0, bmask = 0; | |
769 | |
770 int page_count; | |
771 int double_buf; | |
772 int hw_surface; | |
773 int use_dsp_back_buffer; | |
774 | |
775 DSp_UnsetVideoMode (this, current); | |
776 | |
777 if (bpp != dsp_old_depth) | |
778 DSp_DestroyPalette (this); | |
779 | |
780 double_buf = (flags & SDL_DOUBLEBUF) != 0; | |
781 hw_surface = (flags & SDL_HWSURFACE) != 0; | |
782 use_dsp_back_buffer = !dsp_vram_available || !hw_surface ; | |
783 | |
784 current->flags |= SDL_FULLSCREEN; | |
785 | |
786 rebuild: | |
787 | |
788 if ( double_buf && use_dsp_back_buffer ) { | |
789 page_count = 2; | |
790 } else { | |
791 page_count = 1; | |
792 } | |
793 | |
794 memset (&attrib, 0, sizeof (DSpContextAttributes)); | |
795 attrib.displayWidth = width; | |
796 attrib.displayHeight = height; | |
797 attrib.displayBestDepth = bpp; | |
798 attrib.backBufferBestDepth = bpp; | |
799 attrib.displayDepthMask = kDSpDepthMask_All; | |
800 attrib.backBufferDepthMask = kDSpDepthMask_All; | |
801 attrib.colorNeeds = kDSpColorNeeds_Require; | |
802 attrib.colorTable = 0; | |
803 attrib.pageCount = page_count; | |
804 #if TARGET_API_MAC_OSX | |
805 | |
806 if ( DSpFindBestContext (&attrib, &dsp_context) != noErr ) { | |
807 SDL_SetError ("DrawSprocket couldn't find a context"); | |
808 return NULL; | |
809 } | |
810 | |
811 #else | |
812 if ( noErr != DMGetDisplayIDByGDevice (SDL_Display, &display_id, SDL_FALSE) ) { | |
813 SDL_SetError ("Display Manager couldn't associate GDevice with display_id"); | |
814 return NULL; | |
815 } | |
1032
c1c2efca4548
Date: Mon, 24 Jan 2005 21:37:56 +0800
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
816 if ( DSpFindBestContextOnDisplayID(&attrib, &dsp_context, display_id) != noErr ) { |
0 | 817 SDL_SetError ("DrawSprocket couldn't find a suitable context on given display"); |
818 return NULL; | |
819 } | |
820 | |
821 #endif | |
822 if ( DSpContext_Reserve (dsp_context, &attrib) != noErr ) { | |
823 SDL_SetError ("DrawSprocket couldn't get the needed resources to build the display"); | |
824 return NULL; | |
825 } | |
826 | |
827 if ( (err = DSpContext_SetState (dsp_context, kDSpContextState_Active)) != noErr ) { | |
828 | |
829 if (err == kDSpConfirmSwitchWarning) { | |
830 | |
831 if ( ! DSp_ConfirmSwitch () ) { | |
832 | |
833 DSpContext_Release (dsp_context); | |
834 dsp_context = NULL; | |
835 SDL_SetError ("User cancelled display switch"); | |
836 return NULL; | |
837 } | |
838 else | |
839 /* Have to reactivate context. Why? */ | |
840 DSpContext_SetState (dsp_context, kDSpContextState_Active); | |
841 | |
842 } | |
843 else { | |
844 SDL_SetError ("DrawSprocket couldn't activate the context"); | |
845 return NULL; | |
846 } | |
847 } | |
848 | |
849 | |
850 if (bpp != dsp_old_depth) { | |
851 | |
852 DSp_CreatePalette (this); | |
853 | |
854 /* update format if display depth changed */ | |
855 if (bpp == 16) { | |
856 | |
857 rmask = 0x00007c00; | |
858 gmask = 0x000003e0; | |
859 bmask = 0x0000001f; | |
860 } | |
861 if ( ! SDL_ReallocFormat (current, bpp, rmask, gmask, bmask, 0 ) ) { | |
862 | |
863 SDL_SetError ("Could not reallocate video format."); | |
864 return(NULL); | |
865 } | |
866 } | |
867 | |
868 if (!double_buf) { | |
869 | |
870 /* single-buffer context */ | |
871 DSpContext_GetFrontBuffer (dsp_context, &dsp_back_buffer); | |
872 | |
873 current->hwdata = (private_hwdata*) malloc (sizeof (private_hwdata)); | |
874 if (current ->hwdata == NULL) { | |
875 SDL_OutOfMemory (); | |
876 return NULL; | |
877 } | |
878 current->hwdata->offscreen = dsp_back_buffer; | |
879 current->flags |= SDL_HWSURFACE; | |
880 this->UpdateRects = DSp_DirectUpdate; | |
881 } | |
882 else if ( use_dsp_back_buffer ) { | |
883 | |
884 DSpContext_GetBackBuffer (dsp_context, kDSpBufferKind_Normal, &dsp_back_buffer); | |
885 | |
886 current->flags |= SDL_DOUBLEBUF | SDL_SWSURFACE; /* only front buffer is in VRAM */ | |
887 this->UpdateRects = DSp_DSpUpdate; | |
888 } | |
889 else if ( DSp_NewHWSurface(this, &dsp_back_buffer, bpp, width-1, height-1) == 0 ) { | |
890 | |
891 current->hwdata = (private_hwdata*) malloc (sizeof (private_hwdata)); | |
892 if (current ->hwdata == NULL) { | |
893 SDL_OutOfMemory (); | |
894 return NULL; | |
895 } | |
896 | |
897 memset (current->hwdata, 0, sizeof (private_hwdata)); | |
898 current->hwdata->offscreen = dsp_back_buffer; | |
899 current->flags |= SDL_DOUBLEBUF | SDL_HWSURFACE; | |
900 this->UpdateRects = DSp_DirectUpdate; /* hardware doesn't do update rects, must be page-flipped */ | |
901 } | |
902 else { | |
903 | |
904 DSpContext_Release (dsp_context); | |
905 use_dsp_back_buffer = SDL_TRUE; | |
906 goto rebuild; | |
907 } | |
908 | |
909 current->pitch = GetPortPixRowBytes(dsp_back_buffer) & 0x3FFF; | |
910 current->pixels = GetPixBaseAddr(GetPortPixMap(dsp_back_buffer)); | |
911 | |
912 current->w = width; | |
913 current->h = height; | |
914 | |
915 #if ! TARGET_API_MAC_OSX | |
916 | |
917 if (use_dsp_back_buffer) { | |
918 | |
919 DSpContext_GetMonitorFrequency (dsp_context, &freq); | |
920 DSpContext_SetMaxFrameRate (dsp_context, freq >> 16); | |
921 } | |
922 | |
923 | |
924 if ( (current->flags & SDL_HWSURFACE) || (current->flags & SDL_OPENGL) ) | |
925 DSpContext_SetVBLProc (dsp_context, DSp_VBLProc, NULL); | |
926 #endif | |
927 | |
928 if (bpp == 8) | |
929 current->flags |= SDL_HWPALETTE; | |
930 | |
931 if (flags & SDL_OPENGL) { | |
932 | |
933 Rect rect; | |
934 RGBColor rgb = { 0.0, 0.0, 0.0 }; | |
935 GrafPtr save_port; | |
936 | |
937 SetRect (&rect, 0, 0, width, height); | |
938 SDL_Window = NewCWindow(nil, &( (**SDL_Display).gdRect), "\p", SDL_TRUE, plainDBox, (WindowPtr)-1, SDL_FALSE, 0); | |
939 | |
940 if (SDL_Window == NULL) { | |
941 | |
942 SDL_SetError ("DSp_SetVideoMode : OpenGL window could not be created."); | |
943 return NULL; | |
944 } | |
945 | |
946 /* Set window color to black to avoid white flash*/ | |
947 GetPort (&save_port); | |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
948 #if TARGET_API_MAC_CARBON |
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
949 SetPort (GetWindowPort(SDL_Window)); |
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
950 #else |
0 | 951 SetPort (SDL_Window); |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
952 #endif |
0 | 953 RGBForeColor (&rgb); |
954 PaintRect (&rect); | |
955 SetPort (save_port); | |
956 | |
957 SetPortWindowPort (SDL_Window); | |
958 SelectWindow (SDL_Window); | |
959 | |
960 if ( Mac_GL_Init (this) < 0 ) { | |
961 | |
962 SDL_SetError ("DSp_SetVideoMode : could not create OpenGL context."); | |
963 return NULL; | |
964 } | |
965 | |
966 current->flags |= SDL_OPENGL; | |
967 } | |
968 | |
969 return current; | |
970 } | |
971 | |
972 #ifdef DSP_TRY_CC_AND_AA | |
973 | |
974 static int DSp_MakeHWMask (_THIS, SDL_Surface *surface) | |
975 { | |
976 GDHandle save_device; | |
977 CGrafPtr save_port; | |
978 GWorldPtr temp; | |
979 RGBColor black = { 0, 0, 0 }; | |
980 RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF }; | |
981 Rect rect; | |
982 | |
983 Uint32 depth = GetPixDepth ( GetGDevPixMap (SDL_Display) ); | |
984 | |
985 SetRect (&rect, 0, 0, surface->w, surface->h); | |
986 | |
987 if ( noErr != NewGWorld (&(surface->hwdata->mask), depth, &rect, 0, SDL_Display, 0 ) < 0 ) { | |
988 | |
989 SDL_OutOfMemory (); | |
990 return (-1); | |
991 } | |
992 | |
993 if ( noErr != NewGWorld (&temp, depth, &rect, 0 , SDL_Display, 0 ) ) { | |
994 | |
995 SDL_OutOfMemory (); | |
996 return (-1); | |
997 } | |
998 | |
999 | |
1000 GetGWorld (&save_port, &save_device); | |
1001 SetGWorld (surface->hwdata->mask, SDL_Display); | |
1002 | |
1003 RGBForeColor (&white); | |
1004 PaintRect (&rect); | |
1005 | |
1006 RGBBackColor (&(surface->hwdata->trans)); | |
1007 | |
1008 CopyBits ( GetPortBitMapForCopyBits(surface->hwdata->offscreen), | |
1009 GetPortBitMapForCopyBits(surface->hwdata->mask), | |
1010 &rect, &rect, transparent, NULL ); | |
1011 | |
1012 SetGWorld (surface->hwdata->mask, SDL_Display); | |
1013 SetGWorld (save_port, save_device); | |
1014 return (0); | |
1015 } | |
1016 | |
1017 static int DSp_SetHWAlpha(_THIS, SDL_Surface *surface, UInt8 alpha) | |
1018 { | |
1019 surface->hwdata->alpha.red = (alpha / 255.0) * 65535; | |
1020 surface->hwdata->alpha.blue = (alpha / 255.0) * 65535; | |
1021 surface->hwdata->alpha.green = (alpha / 255.0) * 65535; | |
1022 | |
1023 surface->flags |= SDL_SRCALPHA; | |
1024 | |
1025 if (surface->flags & SDL_SRCCOLORKEY) { | |
1026 return(DSp_MakeHWMask (this, surface)); | |
1027 } | |
1028 return(0); | |
1029 } | |
1030 | |
1031 static int DSp_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key) | |
1032 { | |
1033 CGrafPtr save_port; | |
1034 GDHandle save_device; | |
1035 | |
1036 GetGWorld (&save_port, &save_device); | |
1037 SetGWorld (surface->hwdata->offscreen, NULL); | |
1038 | |
1039 Index2Color (key, &(surface->hwdata->trans)); | |
1040 surface->flags |= SDL_SRCCOLORKEY; | |
1041 | |
1042 SetGWorld (save_port, save_device); | |
1043 | |
1044 if ( surface->flags & SDL_SRCALPHA ) { | |
1045 return(DSp_MakeHWMask (this, surface)); | |
1046 } | |
1047 return(0); | |
1048 } | |
1049 | |
1050 #endif /* DSP_TRY_CC_AND_AA */ | |
1051 | |
1052 static int DSp_NewHWSurface(_THIS, CGrafPtr *port, int depth, int width, int height) { | |
1053 | |
1054 OSStatus err; | |
1055 Rect bounds; | |
1056 | |
1057 SetRect (&bounds, 0, 0, width, height); | |
1058 | |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
1059 #if useDistantHdwrMem && useLocalHdwrMem |
0 | 1060 if (dsp_vram_available) { |
1061 /* try VRAM */ | |
1062 err = NewGWorld (port, depth, &bounds, 0 , SDL_Display, useDistantHdwrMem | noNewDevice ); | |
1063 if (err != noErr) | |
1064 DSp_SetHWError (err, SDL_FALSE); | |
1065 else | |
1066 return (0); | |
1067 } | |
1068 | |
1069 if (dsp_agp_available) { | |
1070 /* try AGP */ | |
1071 err = NewGWorld (port, depth, &bounds, 0 , SDL_Display, useLocalHdwrMem | noNewDevice ); | |
1072 | |
1073 if (err != noErr) | |
1074 DSp_SetHWError (err, SDL_TRUE); | |
1075 else | |
1076 return (0); | |
1077 } | |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
1078 #endif |
0 | 1079 |
1080 return (-1); | |
1081 } | |
1082 | |
1083 static int DSp_AllocHWSurface(_THIS, SDL_Surface *surface) | |
1084 { | |
1085 GWorldPtr temp; | |
1086 | |
1087 if ( DSp_NewHWSurface (this, &temp, surface->format->BitsPerPixel, surface->w, surface->h) < 0 ) | |
1088 return (-1); | |
1089 | |
1090 surface->hwdata = (private_hwdata*) malloc (sizeof (private_hwdata)); | |
1091 if (surface->hwdata == NULL) { | |
1092 SDL_OutOfMemory (); | |
1093 return -1; | |
1094 } | |
1095 | |
1096 memset (surface->hwdata, 0, sizeof(private_hwdata)); | |
1097 surface->hwdata->offscreen = temp; | |
1098 surface->pitch = GetPixRowBytes (GetPortPixMap (temp)) & 0x3FFF; | |
1099 surface->pixels = GetPixBaseAddr (GetPortPixMap (temp)); | |
1100 surface->flags |= SDL_HWSURFACE; | |
1101 #ifdef DSP_TRY_CC_AND_AA | |
1102 surface->flags |= SDL_HWACCEL; | |
1103 #endif | |
1104 return 0; | |
1105 } | |
1106 | |
1107 static void DSp_FreeHWSurface(_THIS, SDL_Surface *surface) | |
1108 { | |
1109 if (surface->hwdata->offscreen != NULL) | |
1110 DisposeGWorld (surface->hwdata->offscreen); | |
1111 free (surface->hwdata); | |
1112 | |
1113 surface->pixels = NULL; | |
1114 } | |
1115 | |
1116 static int DSp_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dest) | |
1117 { | |
1118 int accelerated; | |
1119 | |
1120 /* Set initial acceleration on */ | |
1121 src->flags |= SDL_HWACCEL; | |
1122 | |
1123 /* Set the surface attributes */ | |
1124 if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { | |
1125 if ( ! this->info.blit_hw_A ) { | |
1126 src->flags &= ~SDL_HWACCEL; | |
1127 } | |
1128 } | |
1129 if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { | |
1130 if ( ! this->info.blit_hw_CC ) { | |
1131 src->flags &= ~SDL_HWACCEL; | |
1132 } | |
1133 } | |
1134 | |
1135 /* Check to see if final surface blit is accelerated */ | |
1136 accelerated = !!(src->flags & SDL_HWACCEL); | |
1137 if ( accelerated ) { | |
1138 src->map->hw_blit = DSp_HWAccelBlit; | |
1139 } | |
1140 return(accelerated); | |
1141 } | |
1142 | |
1143 static int DSp_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, | |
1144 SDL_Surface *dst, SDL_Rect *dstrect) | |
1145 { | |
1146 CGrafPtr save_port; | |
1147 GDHandle save_device; | |
1148 Rect src_rect, dst_rect; | |
1149 RGBColor black = { 0, 0, 0 }; | |
1150 RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF }; | |
1151 | |
1152 #ifdef DSP_TRY_CC_AND_AA | |
1153 UInt32 mode; | |
1154 #endif | |
1155 | |
1156 SetRect (&src_rect, srcrect->x, srcrect->y, srcrect->x + srcrect->w, srcrect->y + srcrect->h); | |
1157 SetRect (&dst_rect, dstrect->x, dstrect->y, dstrect->x + dstrect->w, dstrect->y + dstrect->h); | |
1158 | |
1159 GetGWorld (&save_port, &save_device); | |
1160 SetGWorld (dst->hwdata->offscreen, NULL); | |
1161 | |
1162 RGBForeColor (&black); | |
1163 RGBBackColor (&white); | |
1164 | |
1165 #ifdef DSP_TRY_CC_AND_AA | |
1166 | |
1167 if ( (src->flags & SDL_SRCCOLORKEY) && | |
1168 (src->flags & SDL_SRCALPHA) ) { | |
1169 | |
1170 OpColor (&(src->hwdata->alpha)); | |
1171 | |
1172 CopyDeepMask ( GetPortBitMapForCopyBits(src->hwdata->offscreen), | |
1173 GetPortBitMapForCopyBits(src->hwdata->mask), | |
1174 GetPortBitMapForCopyBits(dst->hwdata->offscreen), | |
1175 &src_rect, &src_rect, &dst_rect, | |
1176 blend, | |
1177 NULL ); | |
1178 } | |
1179 else { | |
1180 | |
1181 if ( src->flags & SDL_SRCCOLORKEY) { | |
1182 RGBBackColor (&(src->hwdata->trans) ); | |
1183 mode = transparent; | |
1184 } | |
1185 else if (src->flags & SDL_SRCALPHA) { | |
1186 | |
1187 OpColor (&(src->hwdata->alpha)); | |
1188 mode = blend; | |
1189 } | |
1190 else { | |
1191 | |
1192 mode = srcCopy; | |
1193 } | |
1194 | |
1195 CopyBits ( GetPortBitMapForCopyBits(src->hwdata->offscreen), | |
1196 GetPortBitMapForCopyBits(dst->hwdata->offscreen), | |
1197 &src_rect, &dst_rect, mode, NULL ); | |
1198 } | |
1199 #else | |
1200 | |
1201 CopyBits ( &(((GrafPtr)(src->hwdata->offscreen))->portBits), | |
1202 &(((GrafPtr)(dst->hwdata->offscreen))->portBits), | |
1203 &src_rect, &dst_rect, srcCopy, NULL ); | |
1204 | |
1205 #endif /* DSP_TRY_CC_AND_AA */ | |
1206 | |
1207 SetGWorld (save_port, save_device); | |
1208 | |
1209 return(0); | |
1210 } | |
1211 | |
1212 static int DSp_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color) | |
1213 { | |
1214 CGrafPtr save_port; | |
1215 GDHandle save_device; | |
1216 Rect fill_rect; | |
1217 RGBColor rgb; | |
1218 | |
1219 SetRect (&fill_rect, rect->x, rect->y, rect->x + rect->w, rect->y + rect->h); | |
1220 | |
1221 GetGWorld (&save_port, &save_device); | |
1222 SetGWorld (dst->hwdata->offscreen, NULL); | |
1223 | |
1224 Index2Color (color, &rgb); | |
1225 | |
1226 RGBForeColor (&rgb); | |
1227 PaintRect (&fill_rect); | |
1228 | |
1229 SetGWorld (save_port, save_device); | |
1230 | |
1231 return(0); | |
1232 } | |
1233 | |
1234 static int DSp_FlipHWSurface(_THIS, SDL_Surface *surface) | |
1235 { | |
1236 if ( (surface->flags & SDL_HWSURFACE) ) { | |
1237 CGrafPtr dsp_front_buffer, save_port; | |
1238 Rect rect; | |
1239 | |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
1240 #if ! TARGET_API_MAC_OSX |
0 | 1241 unsigned int old_count; |
1133
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
1242 #endif |
609c060fd2a2
The MacOSX Carbon/Cocoa/X11 all in one library patch. Relevant emails:
Ryan C. Gordon <icculus@icculus.org>
parents:
1032
diff
changeset
|
1243 |
0 | 1244 /* pseudo page flipping for VRAM back buffer*/ |
1245 DSpContext_GetFrontBuffer (dsp_context, &dsp_front_buffer); | |
1246 SetRect (&rect, 0, 0, surface->w-1, surface->h-1); | |
1247 | |
1248 GetPort ((GrafPtr *)&save_port); | |
1249 SetPort ((GrafPtr)dsp_front_buffer); | |
1250 | |
1251 /* wait for retrace */ | |
1252 /* I have tried doing the swap in interrupt routine (VBL Proc) to do */ | |
1253 /* it asynchronously, but apparently CopyBits isn't interrupt safe */ | |
1254 | |
1255 #if ! TARGET_API_MAC_OSX | |
1256 #ifndef DSP_NO_SYNC_VBL | |
1257 old_count = retrace_count; | |
1258 while (old_count == retrace_count) | |
1259 ; | |
1260 #endif | |
1261 #endif | |
1262 | |
1263 CopyBits ( GetPortBitMapForCopyBits(dsp_back_buffer), | |
1264 GetPortBitMapForCopyBits(dsp_front_buffer), | |
1265 &rect, &rect, srcCopy, NULL ); | |
1266 | |
1267 SetPort ((GrafPtr)save_port); | |
1268 | |
1269 } else { | |
1270 /* not really page flipping at all: DSp just blits the dirty rectangles from DSp_UpdateRects */ | |
1271 Boolean busy_flag; | |
1272 DSpContext_SwapBuffers (dsp_context, NULL, &busy_flag); /* this waits for VBL */ | |
1273 DSpContext_GetBackBuffer (dsp_context, kDSpBufferKind_Normal, &dsp_back_buffer); | |
1274 surface->pixels = GetPixBaseAddr( GetPortPixMap(dsp_back_buffer) ); | |
1275 } | |
1276 return(0); | |
1277 } | |
1278 | |
1279 static int DSp_LockHWSurface(_THIS, SDL_Surface *surface) | |
1280 { | |
1281 if ( LockPixels (GetGWorldPixMap (surface->hwdata->offscreen)) ) | |
1282 return 0; | |
1283 else | |
1284 return -1; | |
1285 } | |
1286 | |
1287 static void DSp_UnlockHWSurface(_THIS, SDL_Surface *surface) | |
1288 { | |
1289 UnlockPixels (GetGWorldPixMap (surface->hwdata->offscreen)); | |
1290 } | |
1291 | |
1292 static void DSp_DirectUpdate(_THIS, int numrects, SDL_Rect *sdl_rects) | |
1293 { | |
1294 return; | |
1295 } | |
1296 | |
1297 static void DSp_DSpUpdate(_THIS, int numrects, SDL_Rect *sdl_rects) | |
1298 { | |
1299 #if ! TARGET_API_MAC_OSX /* Unsupported DSp in here */ | |
1300 int i; | |
1301 Rect rect; | |
1302 | |
1303 for (i = 0; i < numrects; i++) { | |
1304 | |
1305 rect.top = sdl_rects[i].y; | |
1306 rect.left = sdl_rects[i].x; | |
1307 rect.bottom = sdl_rects[i].h + sdl_rects[i].y; | |
1308 rect.right = sdl_rects[i].w + sdl_rects[i].x; | |
1309 | |
1310 DSpContext_InvalBackBufferRect (dsp_context, &rect); | |
1311 } | |
1312 #endif | |
1313 } | |
1314 | |
1315 static int DSp_CreatePalette(_THIS) { | |
1316 | |
1317 | |
1318 /* Create our palette */ | |
1319 SDL_CTab = (CTabHandle)NewHandle(sizeof(ColorSpec)*256 + 8); | |
1320 if ( SDL_CTab == nil ) { | |
1321 SDL_OutOfMemory(); | |
1322 return(-1); | |
1323 } | |
1324 (**SDL_CTab).ctSeed = GetCTSeed(); | |
1325 (**SDL_CTab).ctFlags = 0; | |
1326 (**SDL_CTab).ctSize = 255; | |
1327 CTabChanged(SDL_CTab); | |
1328 SDL_CPal = NewPalette(256, SDL_CTab, pmExplicit+pmTolerant, 0); | |
1329 | |
1330 return 0; | |
1331 } | |
1332 | |
1333 static int DSp_DestroyPalette(_THIS) { | |
1334 | |
1335 /* Free palette and restore original one */ | |
1336 if ( SDL_CTab != nil ) { | |
1337 DisposeHandle((Handle)SDL_CTab); | |
1338 SDL_CTab = nil; | |
1339 } | |
1340 if ( SDL_CPal != nil ) { | |
1341 DisposePalette(SDL_CPal); | |
1342 SDL_CPal = nil; | |
1343 } | |
1344 RestoreDeviceClut(SDL_Display); | |
1345 | |
1346 return (0); | |
1347 } | |
1348 | |
1349 static int DSp_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | |
1350 { | |
1351 CTabHandle cTab; | |
1352 | |
1353 int i; | |
1354 | |
1355 cTab = SDL_CTab; | |
1356 | |
1357 /* Verify the range of colors */ | |
1358 if ( (firstcolor+ncolors) > ((**cTab).ctSize+1) ) { | |
1359 return(0); | |
1360 } | |
1361 | |
1362 /* Set the screen palette and update the display */ | |
1363 for(i = 0; i < ncolors; i++) { | |
1364 int j = firstcolor + i; | |
1365 (**cTab).ctTable[j].value = j; | |
1366 (**cTab).ctTable[j].rgb.red = colors[i].r << 8 | colors[i].r; | |
1367 (**cTab).ctTable[j].rgb.green = colors[i].g << 8 | colors[i].g; | |
1368 (**cTab).ctTable[j].rgb.blue = colors[i].b << 8 | colors[i].b; | |
1369 } | |
1370 | |
1371 SetGDevice(SDL_Display); | |
1372 SetEntries(0, (**cTab).ctSize, (ColorSpec *)&(**cTab).ctTable); | |
1373 | |
1374 return(1); | |
1375 } | |
1376 | |
1377 void DSp_VideoQuit(_THIS) | |
1378 { | |
1379 int i; | |
1380 | |
1381 /* Free current video mode */ | |
1382 DSp_UnsetVideoMode(this, this->screen); | |
1383 | |
1384 /* Free Palette and restore original */ | |
1385 DSp_DestroyPalette (this); | |
1386 | |
1387 /* Free list of video modes */ | |
1388 if ( SDL_modelist != NULL ) { | |
1389 for ( i=0; SDL_modelist[i]; i++ ) { | |
1390 free(SDL_modelist[i]); | |
1391 } | |
1392 free(SDL_modelist); | |
1393 SDL_modelist = NULL; | |
1394 } | |
1395 | |
1396 /* Unload DrawSprocket */ | |
1397 DSpShutdown (); | |
1398 } | |
1399 | |
1400 #ifdef HAVE_OPENGL | |
1401 | |
1402 /* swap buffers with v-sync */ | |
1403 static void DSp_GL_SwapBuffers (_THIS) { | |
1404 | |
1405 #ifndef DSP_NO_SYNC_OPENGL | |
1406 | |
1407 unsigned int old_count; | |
1408 | |
1409 old_count = retrace_count; | |
1410 while (old_count == retrace_count) | |
1411 ; | |
1412 #endif | |
1413 | |
1414 aglSwapBuffers (glContext); | |
1415 } | |
1416 | |
1417 #endif |