diff options
Diffstat (limited to 'distrib/sdl-1.2.12/src/video/macdsp/SDL_dspvideo.c')
-rw-r--r-- | distrib/sdl-1.2.12/src/video/macdsp/SDL_dspvideo.c | 1422 |
1 files changed, 0 insertions, 1422 deletions
diff --git a/distrib/sdl-1.2.12/src/video/macdsp/SDL_dspvideo.c b/distrib/sdl-1.2.12/src/video/macdsp/SDL_dspvideo.c deleted file mode 100644 index ed3f8c4..0000000 --- a/distrib/sdl-1.2.12/src/video/macdsp/SDL_dspvideo.c +++ /dev/null @@ -1,1422 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* - Written by Darrell Walisser <dwaliss1@purdue.edu> - - Implementation notes ---------------------------------------------------------------------- - - A bit on GWorlds in VRAM from technote 1182: - - There are two important things to note about GWorld's allocated in - VRAM. First, the base address retrieved through GetPixBaseAddr or - read directly from the PixMap structure can become invalid anytime - memory is allocated in VRAM. This can occur either by explicit - allocations, such as calls to NewGWorld, or by implicit ones, such as - those associated with the internal texture allocation of OpenGL. The - stored pixel images themselves will still be valid but may have been - moved in VRAM, thus rendering any stored base addresses invalid. - You should never store an image's base address for longer than is - necessary and especially never across calls to NewGWorld or - texture-creation routines. - - Secondly, an offscreen pixel image allocated in VRAM can be - purged at system task time by the display driver. This means any - time your application yields time such by calling WaitNextEvent or - SystemTask you can lose your VRAM GWorld contents. While this - happens infrequently, usually associated with display resolution or - pixel depth changes you must code for this eventuality. This purge - can occur whether or not the GWorld is locked or not. A return value - of false from LockPixels, a NULL return value from GetPixBaseAddr - or NULL in the baseAddr field of the PixMap mean that the pixel - image has been purged. To reallocate it you can either call - UpdateGWorld or Dispose your current GWorld through - DisposeGWorld and reallocate it via NewGWorld. Either way you must - then rebuild the pixel image. - ------------------------------------------------------------------------------------- - - Currently, I don't account for (1). In my testing, NewGWorld never invalidated - other existing GWorlds in VRAM. However, I do have protection for (2). - Namely, I am using GetOSEvent() instead of WaitNextEvent() so that there are no - context switches (the app hogs the CPU). Eventually a book-keeping system should - be coded to take care of (1) and (2). - ------------------------------------------------------------------------------------- - - System requirements (* denotes optional): - - 1. DrawSprocket 1.7.3 - 2. *MacOS 9 or later (but *not* Mac OS X) for hardware accelerated blit / fill - 3. *May also require certain graphics hardware for (2). I trust that all Apple OEM - hardware will work. Third party accelerators may work if they have QuickDraw - acceleration in the drivers and the drivers have been updated for OS 9. The current - Voodoo 3 drivers (1.0b12) do not work. - - Coding suggestions: - - 1. Use SDL_UpdateRects ! - - If no QuickDraw acceleration is present, double-buffered surfaces will use a back buffer - in System memory. I recommend you use SDL_UpdateRects with double-buffered surfaces - for best performance on these cards, since the overhead is nearly zero for VRAM back buffer. - - 2. Load most-resident surfaces first. - - If you fill up VRAM or AGP memory, there is no contingency for purging to make room for the next one. - Therefore, you should load the surfaces you plan to use the most frequently first. - Sooner or later, I will code LRU replacement to help this. - - TODO: - Some kind of posterized mode for resolutions < 640x480. - Window support / fullscreen toggle. - Figure out how much VRAM is available. Put in video->info->video_mem. - Track VRAM usage. - - BUGS: - I can't create a hardware surface the same size as the screen?! How to fix? - - - - COMPILE OPTIONS: - - DSP_TRY_CC_AND_AA - Define if you want to try HWA color-key and alpha blitters - HW color-key blitting gives substantial improvements, - but hw alpha is neck-and-neck with SDL's soft bitter. - - DSP_NO_SYNC_VBL - Define for HWA double-buffered surfaces: don't sync - pseudo-flip to monitor redraw. - - DSP_NO_SYNC_OPENGL - Define for OpenGL surfaces: don't sync buffer swap. Synching buffer - swap may result in reduced performance, but can eliminate some - tearing artifacts. - CHANGELOG: - 09/17/00 Lots of little tweaks. Build modelist in reverse order so largest contexts - list first. Compared various methods with ROM methods and fixed rez switch - crashing bug in GL Tron. (Woohoo!) -*/ - -#define DSP_TRY_CC_AND_AA - -/* #define DSP_NO_SYNC_VBL */ - -#define DSP_NO_SYNC_OPENGL - - -#if defined(__APPLE__) && defined(__MACH__) -#include <Carbon/Carbon.h> -#include <DrawSprocket/DrawSprocket.h> -#elif TARGET_API_MAC_CARBON && (UNIVERSAL_INTERFACES_VERSION > 0x0335) -#include <Carbon.h> -#include <DrawSprocket.h> -#else -#include <LowMem.h> -#include <Gestalt.h> -#include <Devices.h> -#include <DiskInit.h> -#include <QDOffscreen.h> -#include <DrawSprocket.h> -#endif - -#include "SDL_video.h" -#include "SDL_syswm.h" -#include "../SDL_sysvideo.h" -#include "../SDL_blit.h" -#include "../SDL_pixels_c.h" -#include "SDL_dspvideo.h" -#include "../maccommon/SDL_macgl_c.h" -#include "../maccommon/SDL_macwm_c.h" -#include "../maccommon/SDL_macmouse_c.h" -#include "../maccommon/SDL_macevents_c.h" - -/* Initialization/Query functions */ -static int DSp_VideoInit(_THIS, SDL_PixelFormat *vformat); -static SDL_Rect **DSp_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); -static SDL_Surface *DSp_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); -static int DSp_SetColors(_THIS, int firstcolor, int ncolors, - SDL_Color *colors); -static int DSp_CreatePalette(_THIS); -static int DSp_DestroyPalette(_THIS); -static void DSp_VideoQuit(_THIS); - -static int DSp_GetMainDevice (_THIS, GDHandle *device); -static void DSp_IsHWAvailable (_THIS, SDL_PixelFormat *vformat); -static void DSp_DSpUpdate(_THIS, int numrects, SDL_Rect *sdl_rects); -static void DSp_DirectUpdate(_THIS, int numrects, SDL_Rect *sdl_rects); - -/* Hardware surface functions */ -static int DSp_SetHWAlpha(_THIS, SDL_Surface *surface, UInt8 alpha); -static int DSp_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key); -static int DSp_NewHWSurface(_THIS, CGrafPtr *port, int depth, int width, int height); -static int DSp_AllocHWSurface(_THIS, SDL_Surface *surface); -static int DSp_LockHWSurface(_THIS, SDL_Surface *surface); -static void DSp_UnlockHWSurface(_THIS, SDL_Surface *surface); -static void DSp_FreeHWSurface(_THIS, SDL_Surface *surface); -static int DSp_FlipHWSurface(_THIS, SDL_Surface *surface); -static int DSp_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dest); -static int DSp_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, - SDL_Surface *dst, SDL_Rect *dstrect); -static int DSp_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color); - -#if SDL_VIDEO_OPENGL - static void DSp_GL_SwapBuffers (_THIS); -#endif - -#if ! TARGET_API_MAC_CARBON - - #define GetPortPixRowBytes(x) ( (*(x->portPixMap))->rowBytes ) - #define GetGDevPixMap(x) ((**(x)).gdPMap) - #define GetPortPixMap(x) ((*(x)).portPixMap) - - #define GetPixDepth(y) ((**(y)).pixelSize) - //#define GetPixRowBytes(y) ((**(y)).rowBytes) - //#define GetPixBaseAddr(y) ((**(y)).baseAddr) - #define GetPixCTab(y) ((**(y)).pmTable) - #define GetPortBitMapForCopyBits(x) (&(((GrafPtr)(x))->portBits)) - -#else - #define GetPortPixRowBytes(x) (GetPixRowBytes(GetPortPixMap(x)) ) - #define GetGDevPixMap(x) ((**(x)).gdPMap) - -#endif - -typedef struct private_hwdata { - - GWorldPtr offscreen; // offscreen gworld in VRAM or AGP - - #ifdef DSP_TRY_CC_AND_AA - GWorldPtr mask; // transparent mask - RGBColor alpha; // alpha color - RGBColor trans; // transparent color - #endif - -} private_hwdata; - -typedef private_hwdata private_swdata ; /* have same fields */ - -/* Macintosh toolbox driver bootstrap functions */ - -static int DSp_Available(void) -{ - /* Check for DrawSprocket */ -#if ! TARGET_API_MAC_OSX - /* This check is only meaningful if you weak-link DrawSprocketLib */ - return ((Ptr)DSpStartup != (Ptr)kUnresolvedCFragSymbolAddress); -#else - return 1; // DrawSprocket.framework doesn't have it all, but it's there -#endif -} - -static void DSp_DeleteDevice(SDL_VideoDevice *device) -{ - /* -dw- taking no chances with null pointers */ - if (device) { - - if (device->hidden) { - - if (device->hidden->dspinfo) - SDL_free(device->hidden->dspinfo); - - SDL_free(device->hidden); - } - SDL_free(device); - } -} - -static SDL_VideoDevice *DSp_CreateDevice(int devindex) -{ - SDL_VideoDevice *device; - - /* Initialize all variables that we clean on shutdown */ - device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); - if ( device ) { - SDL_memset(device, 0, sizeof (*device)); - device->hidden = (struct SDL_PrivateVideoData *) - SDL_malloc((sizeof *device->hidden)); - if (device->hidden) - SDL_memset(device->hidden, 0, sizeof ( *(device->hidden) ) ); - } - if ( (device == NULL) || (device->hidden == NULL) ) { - SDL_OutOfMemory(); - - if ( device ) { - - if (device->hidden) - SDL_free(device->hidden); - - SDL_free(device); - } - - return(NULL); - } - - /* Allocate DrawSprocket information */ - device->hidden->dspinfo = (struct DSpInfo *)SDL_malloc( - (sizeof *device->hidden->dspinfo)); - if ( device->hidden->dspinfo == NULL ) { - SDL_OutOfMemory(); - SDL_free(device->hidden); - SDL_free(device); - return(0); - } - SDL_memset(device->hidden->dspinfo, 0, (sizeof *device->hidden->dspinfo)); - - /* Set the function pointers */ - device->VideoInit = DSp_VideoInit; - device->ListModes = DSp_ListModes; - device->SetVideoMode = DSp_SetVideoMode; - device->SetColors = DSp_SetColors; - device->UpdateRects = NULL; - device->VideoQuit = DSp_VideoQuit; - device->AllocHWSurface = DSp_AllocHWSurface; - device->CheckHWBlit = NULL; - device->FillHWRect = NULL; - device->SetHWColorKey = NULL; - device->SetHWAlpha = NULL; - device->LockHWSurface = DSp_LockHWSurface; - device->UnlockHWSurface = DSp_UnlockHWSurface; - device->FlipHWSurface = DSp_FlipHWSurface; - device->FreeHWSurface = DSp_FreeHWSurface; -#if SDL_MACCLASSIC_GAMMA_SUPPORT - device->SetGammaRamp = Mac_SetGammaRamp; - device->GetGammaRamp = Mac_GetGammaRamp; -#endif -#if SDL_VIDEO_OPENGL - device->GL_MakeCurrent = Mac_GL_MakeCurrent; - device->GL_SwapBuffers = DSp_GL_SwapBuffers; - device->GL_LoadLibrary = Mac_GL_LoadLibrary; - device->GL_GetProcAddress = Mac_GL_GetProcAddress; -#endif - device->SetCaption = NULL; - device->SetIcon = NULL; - device->IconifyWindow = NULL; - device->GrabInput = NULL; - device->GetWMInfo = NULL; - device->FreeWMCursor = Mac_FreeWMCursor; - device->CreateWMCursor = Mac_CreateWMCursor; - device->ShowWMCursor = Mac_ShowWMCursor; - device->WarpWMCursor = Mac_WarpWMCursor; - device->InitOSKeymap = Mac_InitOSKeymap; - device->PumpEvents = Mac_PumpEvents; - - device->GrabInput = NULL; - device->CheckMouseMode = NULL; - - device->free = DSp_DeleteDevice; - - return device; -} - -VideoBootStrap DSp_bootstrap = { - "DSp", "MacOS DrawSprocket", - DSp_Available, DSp_CreateDevice -}; - -/* Use DSp/Display Manager to build mode list for given screen */ -static SDL_Rect** DSp_BuildModeList (const GDHandle gDevice, int *displayWidth, int *displayHeight) -{ - DSpContextAttributes attributes; - DSpContextReference context; - DisplayIDType displayID; - SDL_Rect temp_list [16]; - SDL_Rect **mode_list; - int width, height, i, j; - - #if TARGET_API_MAC_OSX - - displayID = 0; - - #else - /* Ask Display Manager for integer id of screen device */ - if ( DMGetDisplayIDByGDevice (gDevice, &displayID, SDL_TRUE) != noErr ) { - return NULL; - } - #endif - /* Get the first possible DSp context on this device */ - if ( DSpGetFirstContext (displayID, &context) != noErr ) { - return NULL; - } - - if ( DSpContext_GetAttributes (context, &attributes) != noErr ) - return NULL; - - *displayWidth = attributes.displayWidth; - *displayHeight = attributes.displayHeight; - - for ( i = 0; i < SDL_arraysize(temp_list); i++ ) { - width = attributes.displayWidth; - height = attributes.displayHeight; - - temp_list [i].x = 0 | attributes.displayBestDepth; - temp_list [i].y = 0; - temp_list [i].w = width; - temp_list [i].h = height; - - /* DSp will report many different contexts with the same width and height. */ - /* They will differ in bit depth and refresh rate. */ - /* We will ignore them until we reach one with a different width/height */ - /* When there are no more contexts to look at, we will quit building the list*/ - while ( width == attributes.displayWidth && height == attributes.displayHeight ) { - - OSStatus err = DSpGetNextContext (context, &context); - if (err != noErr) - if (err == kDSpContextNotFoundErr) - goto done; - else - return NULL; - - if ( DSpContext_GetAttributes (context, &attributes) != noErr ) - return NULL; - - temp_list [i].x |= attributes.displayBestDepth; - } - } -done: - i++; /* i was not incremented before kicking out of the loop */ - - mode_list = (SDL_Rect**) SDL_malloc (sizeof (SDL_Rect*) * (i+1)); - if (mode_list) { - - /* -dw- new stuff: build in reverse order so largest sizes list first */ - for (j = i-1; j >= 0; j--) { - mode_list [j] = (SDL_Rect*) SDL_malloc (sizeof (SDL_Rect)); - if (mode_list [j]) - SDL_memcpy (mode_list [j], &(temp_list [j]), sizeof (SDL_Rect)); - else { - SDL_OutOfMemory (); - return NULL; - } - } - mode_list [i] = NULL; /* append null to the end */ - } - else { - SDL_OutOfMemory (); - return NULL; - } - - return mode_list; -} - -static void DSp_IsHWAvailable (_THIS, SDL_PixelFormat *vformat) -{ - /* - VRAM GWorlds are only available on OS 9 or later. - Even with OS 9, some display drivers won't support it, - so we create a test GWorld and check for errors. - */ - - long versionSystem; - - dsp_vram_available = SDL_FALSE; - dsp_agp_available = SDL_FALSE; - - Gestalt ('sysv', &versionSystem); - if (0x00000860 < (versionSystem & 0x0000FFFF)) { - - GWorldPtr offscreen; - OSStatus err; - Rect bounds; - - SetRect (&bounds, 0, 0, 320, 240); - -#if useDistantHdwrMem && useLocalHdwrMem - err = NewGWorld (&offscreen, vformat->BitsPerPixel, &bounds, NULL, SDL_Display, useDistantHdwrMem | noNewDevice); - if (err == noErr) { - dsp_vram_available = SDL_TRUE; - DisposeGWorld (offscreen); - } - - err = NewGWorld (&offscreen, vformat->BitsPerPixel, &bounds, NULL, SDL_Display, useLocalHdwrMem | noNewDevice); - if (err == noErr) { - DisposeGWorld (offscreen); - dsp_agp_available = SDL_TRUE; - } -#endif - } -} - -static int DSp_GetMainDevice (_THIS, GDHandle *device) -{ - -#if TARGET_API_MAC_OSX - /* DSpUserSelectContext not available on OS X */ - *device = GetMainDevice(); - return 0; -#else - - DSpContextAttributes attrib; - DSpContextReference context; - DisplayIDType display_id; - GDHandle main_device; - GDHandle device_list; - - device_list = GetDeviceList (); - main_device = GetMainDevice (); - - /* Quick check to avoid slower method when only one display exists */ - if ( (**device_list).gdNextGD == NULL ) { - *device = main_device; - return 0; - } - - SDL_memset (&attrib, 0, sizeof (DSpContextAttributes)); - - /* These attributes are hopefully supported on all devices...*/ - attrib.displayWidth = 640; - attrib.displayHeight = 480; - attrib.displayBestDepth = 8; - attrib.backBufferBestDepth = 8; - attrib.displayDepthMask = kDSpDepthMask_All; - attrib.backBufferDepthMask = kDSpDepthMask_All; - attrib.colorNeeds = kDSpColorNeeds_Require; - attrib.pageCount = 1; - - if (noErr != DMGetDisplayIDByGDevice (main_device, &display_id, SDL_FALSE)) { - SDL_SetError ("Display Manager couldn't associate GDevice with a Display ID"); - return (-1); - } - - /* Put up dialog on main display to select which display to use */ - if (noErr != DSpUserSelectContext (&attrib, display_id, NULL, &context)) { - SDL_SetError ("DrawSprocket couldn't create a context"); - return (-1); - } - - if (noErr != DSpContext_GetDisplayID (context, &display_id)) { - SDL_SetError ("DrawSprocket couldn't get display ID"); - return (-1); - } - - if (noErr != DMGetGDeviceByDisplayID (display_id, &main_device, SDL_FALSE)) { - SDL_SetError ("Display Manager couldn't associate Display ID with GDevice"); - return (-1); - } - - *device = main_device; - return (0); -#endif -} - -static int DSp_VideoInit(_THIS, SDL_PixelFormat *vformat) -{ - NumVersion dsp_version = { 0x01, 0x00, 0x00, 0x00 }; - -#if UNIVERSAL_INTERFACES_VERSION > 0x0320 - dsp_version = DSpGetVersion (); -#endif - - if ( (dsp_version.majorRev == 1 && dsp_version.minorAndBugRev < 0x73) || - (dsp_version.majorRev < 1) ) { - - /* StandardAlert (kAlertStopAlert, "\pError!", - "\pI need DrawSprocket 1.7.3 or later!\n" - "You can find a newer version at http://www.apple.com/swupdates.", - NULL, NULL); - */ - SDL_SetError ("DrawSprocket version is too old. Need 1.7.3 or later."); - return (-1); - } - - if ( DSpStartup () != noErr ) { - SDL_SetError ("DrawSprocket couldn't startup"); - return(-1); - } - - /* Start DSpintosh events */ - Mac_InitEvents(this); - - /* Get a handle to the main monitor, or choose one on multiple monitor setups */ - if ( DSp_GetMainDevice(this, &SDL_Display) < 0) - return (-1); - - /* Determine pixel format */ - vformat->BitsPerPixel = GetPixDepth ( (**SDL_Display).gdPMap ); - dsp_old_depth = vformat->BitsPerPixel; - - switch (vformat->BitsPerPixel) { - case 16: - vformat->Rmask = 0x00007c00; - vformat->Gmask = 0x000003e0; - vformat->Bmask = 0x0000001f; - break; - default: - break; - } - - if ( DSp_CreatePalette (this) < 0 ) { - SDL_SetError ("Could not create palette"); - return (-1); - } - - /* Get a list of available fullscreen modes */ - SDL_modelist = DSp_BuildModeList (SDL_Display, - &this->info.current_w, &this->info.current_h); - if (SDL_modelist == NULL) { - SDL_SetError ("DrawSprocket could not build a mode list"); - return (-1); - } - - /* Check for VRAM and AGP GWorlds for HW Blitting */ - DSp_IsHWAvailable (this, vformat); - - this->info.wm_available = 0; - - if (dsp_vram_available || dsp_agp_available) { - - this->info.hw_available = SDL_TRUE; - - this->CheckHWBlit = DSp_CheckHWBlit; - this->info.blit_hw = SDL_TRUE; - - this->FillHWRect = DSp_FillHWRect; - this->info.blit_fill = SDL_TRUE; - - #ifdef DSP_TRY_CC_AND_AA - this->SetHWColorKey = DSp_SetHWColorKey; - this->info.blit_hw_CC = SDL_TRUE; - - this->SetHWAlpha = DSp_SetHWAlpha; - this->info.blit_hw_A = SDL_TRUE; - #endif - - } - - return(0); -} - -static SDL_Rect **DSp_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) -{ - static SDL_Rect *dsp_modes[16]; - int i = 0, j = 0; - - if ( format->BitsPerPixel == 0 ) - return ( (SDL_Rect**) NULL ); - - while (SDL_modelist[i] != NULL) { - - if (SDL_modelist[i]->x & format->BitsPerPixel) { - dsp_modes[j] = SDL_modelist[i]; - j++; - } - i++; - } - - dsp_modes[j] = NULL; - - return dsp_modes; -} - -/* Various screen update functions available */ -static void DSp_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); - -#if ! TARGET_API_MAC_OSX - -static volatile unsigned int retrace_count = 0; /* -dw- need volatile because it updates asychronously */ - -Boolean DSp_VBLProc ( DSpContextReference context, void *ref_con ) -{ - retrace_count++; - - return 1; /* Darrell, is this right? */ -} - -static void DSp_SetHWError (OSStatus err, int is_agp) -{ - char message[1024]; - const char *fmt, *mem; - - if ( is_agp ) { - mem = "AGP Memory"; - } else { - mem = "VRAM"; - } - switch(err) { - case memFullErr: - fmt = "Hardware surface possible but not enough %s available"; - break; - case cDepthErr: - fmt = "Hardware surface possible but invalid color depth"; - break; - default: - fmt = "Hardware surface could not be allocated in %s - unknown error"; - break; - } - SDL_snprintf(message, SDL_arraysize(message), fmt, mem); - SDL_SetError(message); -} -#endif // TARGET_API_MAC_OSX - -/* put up a dialog to verify display change */ -static int DSp_ConfirmSwitch () { - - /* resource id's for dialog */ - const int rDialog = 1002; - const int bCancel = 1; - const int bOK = 2; - - DialogPtr dialog; - OSStatus err; - SInt32 response; - DialogItemIndex item = 0; - GrafPtr savePort; - - GetPort (&savePort); - - dialog = GetNewDialog (rDialog, NULL, (WindowPtr) -1); - if (dialog == NULL) - return (0); - -#if TARGET_API_MAC_CARBON - SetPort (GetDialogPort(dialog)); -#else - SetPort ((WindowPtr) dialog); -#endif - - SetDialogDefaultItem (dialog, bCancel); - SetDialogCancelItem (dialog, bCancel); - - SetEventMask (everyEvent); - FlushEvents (everyEvent, 0); - - /* On MacOS 8.5 or later, we can make the dialog go away after 15 seconds */ - /* This is good since it's possible user can't even see the dialog! */ - /* Requires linking to DialogsLib */ - err = Gestalt(gestaltSystemVersion,&response); - if (err == noErr && response >= 0x00000850) { - SetDialogTimeout(dialog, bCancel, 15); - } - - do { - - ModalDialog ( NULL, &item ); - - } while ( item != bCancel && item != bOK && err != noErr); - - - DisposeDialog (dialog); - SetPort (savePort); - - SetEventMask(everyEvent - autoKeyMask); - FlushEvents(everyEvent, 0); - - return (item - 1); -} - -static void DSp_UnsetVideoMode(_THIS, SDL_Surface *current) -{ - - - if ( current->flags & SDL_OPENGL ) { - Mac_GL_Quit (this); - } - - if (dsp_context != NULL) { - - GWorldPtr front; - DSpContext_GetFrontBuffer (dsp_context, &front); - - if (front != dsp_back_buffer) - DisposeGWorld (dsp_back_buffer); - - if (current->hwdata) - SDL_free(current->hwdata); - - DSpContext_SetState (dsp_context, kDSpContextState_Inactive ); - DSpContext_Release (dsp_context); - - dsp_context = NULL; - } - - if (SDL_Window != NULL) { - DisposeWindow (SDL_Window); - SDL_Window = NULL; - } - - current->pixels = NULL; - current->flags = 0; -} - -static SDL_Surface *DSp_SetVideoMode(_THIS, - SDL_Surface *current, int width, int height, int bpp, Uint32 flags) -{ - -#if !TARGET_API_MAC_OSX - DisplayIDType display_id; - Fixed freq; -#endif - DSpContextAttributes attrib; - OSStatus err; - UInt32 rmask = 0, gmask = 0, bmask = 0; - - int page_count; - int double_buf; - int hw_surface; - int use_dsp_back_buffer; - - DSp_UnsetVideoMode (this, current); - - if (bpp != dsp_old_depth) - DSp_DestroyPalette (this); - - double_buf = (flags & SDL_DOUBLEBUF) != 0; - hw_surface = (flags & SDL_HWSURFACE) != 0; - use_dsp_back_buffer = !dsp_vram_available || !hw_surface ; - - current->flags |= SDL_FULLSCREEN; - -rebuild: - - if ( double_buf && use_dsp_back_buffer ) { - page_count = 2; - } else { - page_count = 1; - } - - SDL_memset (&attrib, 0, sizeof (DSpContextAttributes)); - attrib.displayWidth = width; - attrib.displayHeight = height; - attrib.displayBestDepth = bpp; - attrib.backBufferBestDepth = bpp; - attrib.displayDepthMask = kDSpDepthMask_All; - attrib.backBufferDepthMask = kDSpDepthMask_All; - attrib.colorNeeds = kDSpColorNeeds_Require; - attrib.colorTable = 0; - attrib.pageCount = page_count; - #if TARGET_API_MAC_OSX || UNIVERSAL_INTERFACES_VERSION == 0x0320 - - if ( DSpFindBestContext (&attrib, &dsp_context) != noErr ) { - SDL_SetError ("DrawSprocket couldn't find a context"); - return NULL; - } - - #else - if ( noErr != DMGetDisplayIDByGDevice (SDL_Display, &display_id, SDL_FALSE) ) { - SDL_SetError ("Display Manager couldn't associate GDevice with display_id"); - return NULL; - } - if ( DSpFindBestContextOnDisplayID(&attrib, &dsp_context, display_id) != noErr ) { - SDL_SetError ("DrawSprocket couldn't find a suitable context on given display"); - return NULL; - } - - #endif - if ( DSpContext_Reserve (dsp_context, &attrib) != noErr ) { - SDL_SetError ("DrawSprocket couldn't get the needed resources to build the display"); - return NULL; - } - - if ( (err = DSpContext_SetState (dsp_context, kDSpContextState_Active)) != noErr ) { - - if (err == kDSpConfirmSwitchWarning) { - - if ( ! DSp_ConfirmSwitch () ) { - - DSpContext_Release (dsp_context); - dsp_context = NULL; - SDL_SetError ("User cancelled display switch"); - return NULL; - } - else - /* Have to reactivate context. Why? */ - DSpContext_SetState (dsp_context, kDSpContextState_Active); - - } - else { - SDL_SetError ("DrawSprocket couldn't activate the context"); - return NULL; - } - } - - - if (bpp != dsp_old_depth) { - - DSp_CreatePalette (this); - - /* update format if display depth changed */ - if (bpp == 16) { - - rmask = 0x00007c00; - gmask = 0x000003e0; - bmask = 0x0000001f; - } - if ( ! SDL_ReallocFormat (current, bpp, rmask, gmask, bmask, 0 ) ) { - - SDL_SetError ("Could not reallocate video format."); - return(NULL); - } - } - - if (!double_buf) { - - /* single-buffer context */ - DSpContext_GetFrontBuffer (dsp_context, &dsp_back_buffer); - - current->hwdata = (private_hwdata*) SDL_malloc (sizeof (private_hwdata)); - if (current ->hwdata == NULL) { - SDL_OutOfMemory (); - return NULL; - } - current->hwdata->offscreen = dsp_back_buffer; - current->flags |= SDL_HWSURFACE; - this->UpdateRects = DSp_DirectUpdate; - } - else if ( use_dsp_back_buffer ) { - - DSpContext_GetBackBuffer (dsp_context, kDSpBufferKind_Normal, &dsp_back_buffer); - - current->flags |= SDL_DOUBLEBUF | SDL_SWSURFACE; /* only front buffer is in VRAM */ - this->UpdateRects = DSp_DSpUpdate; - } - else if ( DSp_NewHWSurface(this, &dsp_back_buffer, bpp, width-1, height-1) == 0 ) { - - current->hwdata = (private_hwdata*) SDL_malloc (sizeof (private_hwdata)); - if (current ->hwdata == NULL) { - SDL_OutOfMemory (); - return NULL; - } - - SDL_memset (current->hwdata, 0, sizeof (private_hwdata)); - current->hwdata->offscreen = dsp_back_buffer; - current->flags |= SDL_DOUBLEBUF | SDL_HWSURFACE; - this->UpdateRects = DSp_DirectUpdate; /* hardware doesn't do update rects, must be page-flipped */ - } - else { - - DSpContext_Release (dsp_context); - use_dsp_back_buffer = SDL_TRUE; - goto rebuild; - } - - current->pitch = GetPortPixRowBytes(dsp_back_buffer) & 0x3FFF; - current->pixels = GetPixBaseAddr(GetPortPixMap(dsp_back_buffer)); - - current->w = width; - current->h = height; - - #if ! TARGET_API_MAC_OSX - - if (use_dsp_back_buffer) { - - DSpContext_GetMonitorFrequency (dsp_context, &freq); - DSpContext_SetMaxFrameRate (dsp_context, freq >> 16); - } - - - if ( (current->flags & SDL_HWSURFACE) || (current->flags & SDL_OPENGL) ) - DSpContext_SetVBLProc (dsp_context, DSp_VBLProc, NULL); - #endif - - if (bpp == 8) - current->flags |= SDL_HWPALETTE; - - if (flags & SDL_OPENGL) { - - Rect rect; - RGBColor rgb = { 0.0, 0.0, 0.0 }; - GrafPtr save_port; - - SetRect (&rect, 0, 0, width, height); - SDL_Window = NewCWindow(nil, &( (**SDL_Display).gdRect), "\p", SDL_TRUE, plainDBox, (WindowPtr)-1, SDL_FALSE, 0); - - if (SDL_Window == NULL) { - - SDL_SetError ("DSp_SetVideoMode : OpenGL window could not be created."); - return NULL; - } - - /* Set window color to black to avoid white flash*/ - GetPort (&save_port); -#if TARGET_API_MAC_CARBON - SetPort (GetWindowPort(SDL_Window)); -#else - SetPort (SDL_Window); -#endif - RGBForeColor (&rgb); - PaintRect (&rect); - SetPort (save_port); - - SetPortWindowPort (SDL_Window); - SelectWindow (SDL_Window); - - if ( Mac_GL_Init (this) < 0 ) { - - SDL_SetError ("DSp_SetVideoMode : could not create OpenGL context."); - return NULL; - } - - current->flags |= SDL_OPENGL; - } - - return current; -} - -#ifdef DSP_TRY_CC_AND_AA - -static int DSp_MakeHWMask (_THIS, SDL_Surface *surface) -{ - GDHandle save_device; - CGrafPtr save_port; - GWorldPtr temp; - RGBColor black = { 0, 0, 0 }; - RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF }; - Rect rect; - - Uint32 depth = GetPixDepth ( GetGDevPixMap (SDL_Display) ); - - SetRect (&rect, 0, 0, surface->w, surface->h); - - if ( noErr != NewGWorld (&(surface->hwdata->mask), depth, &rect, 0, SDL_Display, 0 ) < 0 ) { - - SDL_OutOfMemory (); - return (-1); - } - - if ( noErr != NewGWorld (&temp, depth, &rect, 0 , SDL_Display, 0 ) ) { - - SDL_OutOfMemory (); - return (-1); - } - - - GetGWorld (&save_port, &save_device); - SetGWorld (surface->hwdata->mask, SDL_Display); - - RGBForeColor (&white); - PaintRect (&rect); - - RGBBackColor (&(surface->hwdata->trans)); - - CopyBits ( GetPortBitMapForCopyBits(surface->hwdata->offscreen), - GetPortBitMapForCopyBits(surface->hwdata->mask), - &rect, &rect, transparent, NULL ); - - SetGWorld (surface->hwdata->mask, SDL_Display); - SetGWorld (save_port, save_device); - return (0); -} - -static int DSp_SetHWAlpha(_THIS, SDL_Surface *surface, UInt8 alpha) -{ - surface->hwdata->alpha.red = (alpha / 255.0) * 65535; - surface->hwdata->alpha.blue = (alpha / 255.0) * 65535; - surface->hwdata->alpha.green = (alpha / 255.0) * 65535; - - surface->flags |= SDL_SRCALPHA; - - if (surface->flags & SDL_SRCCOLORKEY) { - return(DSp_MakeHWMask (this, surface)); - } - return(0); -} - -static int DSp_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key) -{ - CGrafPtr save_port; - GDHandle save_device; - - GetGWorld (&save_port, &save_device); - SetGWorld (surface->hwdata->offscreen, NULL); - - Index2Color (key, &(surface->hwdata->trans)); - surface->flags |= SDL_SRCCOLORKEY; - - SetGWorld (save_port, save_device); - - if ( surface->flags & SDL_SRCALPHA ) { - return(DSp_MakeHWMask (this, surface)); - } - return(0); -} - -#endif /* DSP_TRY_CC_AND_AA */ - -static int DSp_NewHWSurface(_THIS, CGrafPtr *port, int depth, int width, int height) { - - OSStatus err; - Rect bounds; - - SetRect (&bounds, 0, 0, width, height); - - #if useDistantHdwrMem && useLocalHdwrMem - if (dsp_vram_available) { - /* try VRAM */ - err = NewGWorld (port, depth, &bounds, 0 , SDL_Display, useDistantHdwrMem | noNewDevice ); - if (err != noErr) - DSp_SetHWError (err, SDL_FALSE); - else - return (0); - } - - if (dsp_agp_available) { - /* try AGP */ - err = NewGWorld (port, depth, &bounds, 0 , SDL_Display, useLocalHdwrMem | noNewDevice ); - - if (err != noErr) - DSp_SetHWError (err, SDL_TRUE); - else - return (0); - } -#endif - - return (-1); -} - -static int DSp_AllocHWSurface(_THIS, SDL_Surface *surface) -{ - GWorldPtr temp; - - if ( DSp_NewHWSurface (this, &temp, surface->format->BitsPerPixel, surface->w, surface->h) < 0 ) - return (-1); - - surface->hwdata = (private_hwdata*) SDL_malloc (sizeof (private_hwdata)); - if (surface->hwdata == NULL) { - SDL_OutOfMemory (); - return -1; - } - - SDL_memset (surface->hwdata, 0, sizeof(private_hwdata)); - surface->hwdata->offscreen = temp; - surface->pitch = GetPixRowBytes (GetPortPixMap (temp)) & 0x3FFF; - surface->pixels = GetPixBaseAddr (GetPortPixMap (temp)); - surface->flags |= SDL_HWSURFACE; -#ifdef DSP_TRY_CC_AND_AA - surface->flags |= SDL_HWACCEL; -#endif - return 0; -} - -static void DSp_FreeHWSurface(_THIS, SDL_Surface *surface) -{ - if (surface->hwdata->offscreen != NULL) - DisposeGWorld (surface->hwdata->offscreen); - SDL_free(surface->hwdata); - - surface->pixels = NULL; -} - -static int DSp_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dest) -{ - int accelerated; - - /* Set initial acceleration on */ - src->flags |= SDL_HWACCEL; - - /* Set the surface attributes */ - if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { - if ( ! this->info.blit_hw_A ) { - src->flags &= ~SDL_HWACCEL; - } - } - if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { - if ( ! this->info.blit_hw_CC ) { - src->flags &= ~SDL_HWACCEL; - } - } - - /* Check to see if final surface blit is accelerated */ - accelerated = !!(src->flags & SDL_HWACCEL); - if ( accelerated ) { - src->map->hw_blit = DSp_HWAccelBlit; - } - return(accelerated); -} - -static int DSp_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, - SDL_Surface *dst, SDL_Rect *dstrect) -{ - CGrafPtr save_port; - GDHandle save_device; - Rect src_rect, dst_rect; - RGBColor black = { 0, 0, 0 }; - RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF }; - -#ifdef DSP_TRY_CC_AND_AA - UInt32 mode; -#endif - - SetRect (&src_rect, srcrect->x, srcrect->y, srcrect->x + srcrect->w, srcrect->y + srcrect->h); - SetRect (&dst_rect, dstrect->x, dstrect->y, dstrect->x + dstrect->w, dstrect->y + dstrect->h); - - GetGWorld (&save_port, &save_device); - SetGWorld (dst->hwdata->offscreen, NULL); - - RGBForeColor (&black); - RGBBackColor (&white); - -#ifdef DSP_TRY_CC_AND_AA - - if ( (src->flags & SDL_SRCCOLORKEY) && - (src->flags & SDL_SRCALPHA) ) { - - OpColor (&(src->hwdata->alpha)); - - CopyDeepMask ( GetPortBitMapForCopyBits(src->hwdata->offscreen), - GetPortBitMapForCopyBits(src->hwdata->mask), - GetPortBitMapForCopyBits(dst->hwdata->offscreen), - &src_rect, &src_rect, &dst_rect, - blend, - NULL ); - } - else { - - if ( src->flags & SDL_SRCCOLORKEY) { - RGBBackColor (&(src->hwdata->trans) ); - mode = transparent; - } - else if (src->flags & SDL_SRCALPHA) { - - OpColor (&(src->hwdata->alpha)); - mode = blend; - } - else { - - mode = srcCopy; - } - - CopyBits ( GetPortBitMapForCopyBits(src->hwdata->offscreen), - GetPortBitMapForCopyBits(dst->hwdata->offscreen), - &src_rect, &dst_rect, mode, NULL ); - } -#else - - CopyBits ( &(((GrafPtr)(src->hwdata->offscreen))->portBits), - &(((GrafPtr)(dst->hwdata->offscreen))->portBits), - &src_rect, &dst_rect, srcCopy, NULL ); - -#endif /* DSP_TRY_CC_AND_AA */ - - SetGWorld (save_port, save_device); - - return(0); -} - -static int DSp_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color) -{ - CGrafPtr save_port; - GDHandle save_device; - Rect fill_rect; - RGBColor rgb; - - SetRect (&fill_rect, rect->x, rect->y, rect->x + rect->w, rect->y + rect->h); - - GetGWorld (&save_port, &save_device); - SetGWorld (dst->hwdata->offscreen, NULL); - - Index2Color (color, &rgb); - - RGBForeColor (&rgb); - PaintRect (&fill_rect); - - SetGWorld (save_port, save_device); - - return(0); -} - -static int DSp_FlipHWSurface(_THIS, SDL_Surface *surface) -{ - if ( (surface->flags & SDL_HWSURFACE) ) { - CGrafPtr dsp_front_buffer, save_port; - Rect rect; - - #if ! TARGET_API_MAC_OSX - unsigned int old_count; - #endif - - /* pseudo page flipping for VRAM back buffer*/ - DSpContext_GetFrontBuffer (dsp_context, &dsp_front_buffer); - SetRect (&rect, 0, 0, surface->w-1, surface->h-1); - - GetPort ((GrafPtr *)&save_port); - SetPort ((GrafPtr)dsp_front_buffer); - - /* wait for retrace */ - /* I have tried doing the swap in interrupt routine (VBL Proc) to do */ - /* it asynchronously, but apparently CopyBits isn't interrupt safe */ - - #if ! TARGET_API_MAC_OSX - #ifndef DSP_NO_SYNC_VBL - old_count = retrace_count; - while (old_count == retrace_count) - ; - #endif - #endif - - CopyBits ( GetPortBitMapForCopyBits(dsp_back_buffer), - GetPortBitMapForCopyBits(dsp_front_buffer), - &rect, &rect, srcCopy, NULL ); - - SetPort ((GrafPtr)save_port); - - } else { - /* not really page flipping at all: DSp just blits the dirty rectangles from DSp_UpdateRects */ - Boolean busy_flag; - DSpContext_SwapBuffers (dsp_context, NULL, &busy_flag); /* this waits for VBL */ - DSpContext_GetBackBuffer (dsp_context, kDSpBufferKind_Normal, &dsp_back_buffer); - surface->pixels = GetPixBaseAddr( GetPortPixMap(dsp_back_buffer) ); - } - return(0); -} - -static int DSp_LockHWSurface(_THIS, SDL_Surface *surface) -{ - if ( LockPixels (GetGWorldPixMap (surface->hwdata->offscreen)) ) - return 0; - else - return -1; -} - -static void DSp_UnlockHWSurface(_THIS, SDL_Surface *surface) -{ - UnlockPixels (GetGWorldPixMap (surface->hwdata->offscreen)); -} - -static void DSp_DirectUpdate(_THIS, int numrects, SDL_Rect *sdl_rects) -{ - return; -} - -static void DSp_DSpUpdate(_THIS, int numrects, SDL_Rect *sdl_rects) -{ -#if ! TARGET_API_MAC_OSX /* Unsupported DSp in here */ - int i; - Rect rect; - - for (i = 0; i < numrects; i++) { - - rect.top = sdl_rects[i].y; - rect.left = sdl_rects[i].x; - rect.bottom = sdl_rects[i].h + sdl_rects[i].y; - rect.right = sdl_rects[i].w + sdl_rects[i].x; - - DSpContext_InvalBackBufferRect (dsp_context, &rect); - } -#endif -} - -static int DSp_CreatePalette(_THIS) { - - - /* Create our palette */ - SDL_CTab = (CTabHandle)NewHandle(sizeof(ColorSpec)*256 + 8); - if ( SDL_CTab == nil ) { - SDL_OutOfMemory(); - return(-1); - } - (**SDL_CTab).ctSeed = GetCTSeed(); - (**SDL_CTab).ctFlags = 0; - (**SDL_CTab).ctSize = 255; - CTabChanged(SDL_CTab); - SDL_CPal = NewPalette(256, SDL_CTab, pmExplicit+pmTolerant, 0); - - return 0; -} - -static int DSp_DestroyPalette(_THIS) { - - /* Free palette and restore original one */ - if ( SDL_CTab != nil ) { - DisposeHandle((Handle)SDL_CTab); - SDL_CTab = nil; - } - if ( SDL_CPal != nil ) { - DisposePalette(SDL_CPal); - SDL_CPal = nil; - } - RestoreDeviceClut(SDL_Display); - - return (0); -} - -static int DSp_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) -{ - CTabHandle cTab; - - int i; - - cTab = SDL_CTab; - - /* Verify the range of colors */ - if ( (firstcolor+ncolors) > ((**cTab).ctSize+1) ) { - return(0); - } - - /* Set the screen palette and update the display */ - for(i = 0; i < ncolors; i++) { - int j = firstcolor + i; - (**cTab).ctTable[j].value = j; - (**cTab).ctTable[j].rgb.red = colors[i].r << 8 | colors[i].r; - (**cTab).ctTable[j].rgb.green = colors[i].g << 8 | colors[i].g; - (**cTab).ctTable[j].rgb.blue = colors[i].b << 8 | colors[i].b; - } - - SetGDevice(SDL_Display); - SetEntries(0, (**cTab).ctSize, (ColorSpec *)&(**cTab).ctTable); - - return(1); -} - -void DSp_VideoQuit(_THIS) -{ - int i; - - /* Free current video mode */ - DSp_UnsetVideoMode(this, this->screen); - - /* Free Palette and restore original */ - DSp_DestroyPalette (this); - -#if SDL_MACCLASSIC_GAMMA_SUPPORT - Mac_QuitGamma(this); -#endif - - /* Free list of video modes */ - if ( SDL_modelist != NULL ) { - for ( i=0; SDL_modelist[i]; i++ ) { - SDL_free(SDL_modelist[i]); - } - SDL_free(SDL_modelist); - SDL_modelist = NULL; - } - - /* Unload DrawSprocket */ - DSpShutdown (); -} - -#if SDL_VIDEO_OPENGL - -/* swap buffers with v-sync */ -static void DSp_GL_SwapBuffers (_THIS) { - - #ifndef DSP_NO_SYNC_OPENGL - - unsigned int old_count; - - old_count = retrace_count; - while (old_count == retrace_count) - ; - #endif - - aglSwapBuffers (glContext); -} - -#endif |