SDL_dspvideo.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:40k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

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