Commit d942ec32 authored by Sam Lantinga's avatar Sam Lantinga

MacOS Classic is no longer supported.

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402025
parent f63cb9f2
...@@ -38,7 +38,7 @@ SDLMAIN_TARGET = libSDLmain.a ...@@ -38,7 +38,7 @@ SDLMAIN_TARGET = libSDLmain.a
SDLMAIN_SOURCES = @SDLMAIN_SOURCES@ SDLMAIN_SOURCES = @SDLMAIN_SOURCES@
SDLMAIN_OBJECTS = @SDLMAIN_OBJECTS@ SDLMAIN_OBJECTS = @SDLMAIN_OBJECTS@
DIST = acinclude.m4 autogen.sh Borland.html Borland.zip BUGS build-scripts configure configure.in COPYING CREDITS CWprojects.sea.bin docs docs.html EpocBuildFiles.zip include INSTALL Makefile.dc Makefile.minimal Makefile.in MPWmake.sea.bin README* sdl-config.in sdl.m4 sdl.pc.in SDL.qpg.in SDL.spec SDL.spec.in src test TODO VisualCE.zip VisualC.html VisualC.zip Watcom-OS2.zip Watcom-Win32.zip WhatsNew Xcode.tar.gz DIST = acinclude.m4 autogen.sh Borland.html Borland.zip BUGS build-scripts configure configure.in COPYING CREDITS docs docs.html EpocBuildFiles.zip include INSTALL Makefile.dc Makefile.minimal Makefile.in README* sdl-config.in sdl.m4 sdl.pc.in SDL.qpg.in SDL.spec SDL.spec.in src test TODO VisualCE.zip VisualC.html VisualC.zip Watcom-OS2.zip Watcom-Win32.zip WhatsNew Xcode.tar.gz
LT_AGE = @LT_AGE@ LT_AGE = @LT_AGE@
LT_CURRENT = @LT_CURRENT@ LT_CURRENT = @LT_CURRENT@
......
...@@ -30,8 +30,6 @@ ...@@ -30,8 +30,6 @@
#include "SDL_config_amiga.h" #include "SDL_config_amiga.h"
#elif defined(__DREAMCAST__) #elif defined(__DREAMCAST__)
#include "SDL_config_dreamcast.h" #include "SDL_config_dreamcast.h"
#elif defined(__MACOS__)
#include "SDL_config_macos.h"
#elif defined(__MACOSX__) #elif defined(__MACOSX__)
#include "SDL_config_macosx.h" #include "SDL_config_macosx.h"
#elif defined(__WIN32__) #elif defined(__WIN32__)
......
...@@ -184,7 +184,6 @@ ...@@ -184,7 +184,6 @@
#undef SDL_CDROM_DUMMY #undef SDL_CDROM_DUMMY
#undef SDL_CDROM_FREEBSD #undef SDL_CDROM_FREEBSD
#undef SDL_CDROM_LINUX #undef SDL_CDROM_LINUX
#undef SDL_CDROM_MACOS
#undef SDL_CDROM_MACOSX #undef SDL_CDROM_MACOSX
#undef SDL_CDROM_MINT #undef SDL_CDROM_MINT
#undef SDL_CDROM_OPENBSD #undef SDL_CDROM_OPENBSD
...@@ -203,7 +202,6 @@ ...@@ -203,7 +202,6 @@
#undef SDL_JOYSTICK_IOKIT #undef SDL_JOYSTICK_IOKIT
#undef SDL_JOYSTICK_LINUX #undef SDL_JOYSTICK_LINUX
#undef SDL_JOYSTICK_LINUXEV #undef SDL_JOYSTICK_LINUXEV
#undef SDL_JOYSTICK_MACOS
#undef SDL_JOYSTICK_MINT #undef SDL_JOYSTICK_MINT
#undef SDL_JOYSTICK_OS2 #undef SDL_JOYSTICK_OS2
#undef SDL_JOYSTICK_RISCOS #undef SDL_JOYSTICK_RISCOS
...@@ -217,7 +215,6 @@ ...@@ -217,7 +215,6 @@
#undef SDL_LOADSO_DLOPEN #undef SDL_LOADSO_DLOPEN
#undef SDL_LOADSO_DUMMY #undef SDL_LOADSO_DUMMY
#undef SDL_LOADSO_LDG #undef SDL_LOADSO_LDG
#undef SDL_LOADSO_MACOS
#undef SDL_LOADSO_OS2 #undef SDL_LOADSO_OS2
#undef SDL_LOADSO_WIN32 #undef SDL_LOADSO_WIN32
...@@ -240,7 +237,6 @@ ...@@ -240,7 +237,6 @@
#undef SDL_TIMER_DC #undef SDL_TIMER_DC
#undef SDL_TIMER_DUMMY #undef SDL_TIMER_DUMMY
#undef SDL_TIMER_EPOC #undef SDL_TIMER_EPOC
#undef SDL_TIMER_MACOS
#undef SDL_TIMER_MINT #undef SDL_TIMER_MINT
#undef SDL_TIMER_OS2 #undef SDL_TIMER_OS2
#undef SDL_TIMER_RISCOS #undef SDL_TIMER_RISCOS
...@@ -254,7 +250,6 @@ ...@@ -254,7 +250,6 @@
#undef SDL_VIDEO_DRIVER_CYBERGRAPHICS #undef SDL_VIDEO_DRIVER_CYBERGRAPHICS
#undef SDL_VIDEO_DRIVER_DC #undef SDL_VIDEO_DRIVER_DC
#undef SDL_VIDEO_DRIVER_DIRECTFB #undef SDL_VIDEO_DRIVER_DIRECTFB
#undef SDL_VIDEO_DRIVER_DRAWSPROCKET
#undef SDL_VIDEO_DRIVER_DUMMY #undef SDL_VIDEO_DRIVER_DUMMY
#undef SDL_VIDEO_DRIVER_EPOC #undef SDL_VIDEO_DRIVER_EPOC
#undef SDL_VIDEO_DRIVER_FBCON #undef SDL_VIDEO_DRIVER_FBCON
...@@ -268,7 +263,6 @@ ...@@ -268,7 +263,6 @@
#undef SDL_VIDEO_DRIVER_PS2GS #undef SDL_VIDEO_DRIVER_PS2GS
#undef SDL_VIDEO_DRIVER_RISCOS #undef SDL_VIDEO_DRIVER_RISCOS
#undef SDL_VIDEO_DRIVER_SVGALIB #undef SDL_VIDEO_DRIVER_SVGALIB
#undef SDL_VIDEO_DRIVER_TOOLBOX
#undef SDL_VIDEO_DRIVER_VGL #undef SDL_VIDEO_DRIVER_VGL
#undef SDL_VIDEO_DRIVER_WIN32 #undef SDL_VIDEO_DRIVER_WIN32
#undef SDL_VIDEO_DRIVER_WSCONS #undef SDL_VIDEO_DRIVER_WSCONS
......
/*
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
*/
#ifndef _SDL_config_macos_h
#define _SDL_config_macos_h
#include "SDL_platform.h"
/* This is a set of defines to configure the SDL features */
#include <MacTypes.h>
typedef SInt8 int8_t;
typedef UInt8 uint8_t;
typedef SInt16 int16_t;
typedef UInt16 uint16_t;
typedef SInt32 int32_t;
typedef UInt32 uint32_t;
typedef SInt64 int64_t;
typedef UInt64 uint64_t;
typedef unsigned long uintptr_t;
#define SDL_HAS_64BIT_TYPE 1
/* Useful headers */
#define HAVE_STDIO_H 1
#define STDC_HEADERS 1
#define HAVE_STRING_H 1
#define HAVE_CTYPE_H 1
#define HAVE_MATH_H 1
#define HAVE_SIGNAL_H 1
/* C library functions */
#define HAVE_MALLOC 1
#define HAVE_CALLOC 1
#define HAVE_REALLOC 1
#define HAVE_FREE 1
#define HAVE_ALLOCA 1
#define HAVE_ABS 1
#define HAVE_MEMSET 1
#define HAVE_MEMCPY 1
#define HAVE_MEMMOVE 1
#define HAVE_MEMCMP 1
#define HAVE_STRLEN 1
#define HAVE_STRCHR 1
#define HAVE_STRRCHR 1
#define HAVE_STRSTR 1
#define HAVE_ITOA 1
#define HAVE_STRTOL 1
#define HAVE_STRTOD 1
#define HAVE_ATOI 1
#define HAVE_ATOF 1
#define HAVE_STRCMP 1
#define HAVE_STRNCMP 1
#define HAVE_SSCANF 1
/* Enable various audio drivers */
#define SDL_AUDIO_DRIVER_SNDMGR 1
#define SDL_AUDIO_DRIVER_DISK 1
#define SDL_AUDIO_DRIVER_DUMMY 1
/* Enable various cdrom drivers */
#if TARGET_API_MAC_CARBON
#define SDL_CDROM_DUMMY 1
#else
#define SDL_CDROM_MACOS 1
#endif
/* Enable various input drivers */
#if TARGET_API_MAC_CARBON
#define SDL_JOYSTICK_DUMMY 1
#else
#define SDL_JOYSTICK_MACOS 1
#endif
/* Enable various shared object loading systems */
#define SDL_LOADSO_MACOS 1
/* Enable various threading systems */
#define SDL_THREADS_DISABLED 1
/* Enable various timer systems */
#define SDL_TIMER_MACOS 1
/* Enable various video drivers */
#define SDL_VIDEO_DRIVER_DUMMY 1
#define SDL_VIDEO_DRIVER_DRAWSPROCKET 1
#define SDL_VIDEO_DRIVER_TOOLBOX 1
/* Enable OpenGL support */
#define SDL_VIDEO_OPENGL 1
#endif /* _SDL_config_macos_h */
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#if defined(__WIN32__) || \ #if defined(__WIN32__) || \
(defined(__MWERKS__) && !defined(__BEOS__)) || \ (defined(__MWERKS__) && !defined(__BEOS__)) || \
defined(__MACOS__) || \
defined(__SYMBIAN32__) || defined(QWS) defined(__SYMBIAN32__) || defined(QWS)
#ifdef __cplusplus #ifdef __cplusplus
...@@ -76,30 +75,6 @@ extern DECLSPEC void SDLCALL SDL_UnregisterApp(void); ...@@ -76,30 +75,6 @@ extern DECLSPEC void SDLCALL SDL_UnregisterApp(void);
#include "close_code.h" #include "close_code.h"
#endif #endif
/* From the SDL library code -- needed for registering QuickDraw on MacOS */
#if defined(__MACOS__)
#include "begin_code.h"
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
/* Forward declaration so we don't need to include QuickDraw.h */
struct QDGlobals;
/* This should be called from your main() function, if any */
extern DECLSPEC void SDLCALL SDL_InitQuickDraw(struct QDGlobals *the_qd);
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif
#include "close_code.h"
#endif
#endif /* Need to redefine main()? */ #endif /* Need to redefine main()? */
#endif /* _SDL_main_h */ #endif /* _SDL_main_h */
......
...@@ -37,9 +37,6 @@ ...@@ -37,9 +37,6 @@
#if defined(__MACOSX__) #if defined(__MACOSX__)
#include <OpenGL/gl.h> /* Header File For The OpenGL Library */ #include <OpenGL/gl.h> /* Header File For The OpenGL Library */
#include <OpenGL/glu.h> /* Header File For The GLU Library */ #include <OpenGL/glu.h> /* Header File For The GLU Library */
#elif defined(__MACOS__)
#include <gl.h> /* Header File For The OpenGL Library */
#include <glu.h> /* Header File For The GLU Library */
#else #else
#include <GL/gl.h> /* Header File For The OpenGL Library */ #include <GL/gl.h> /* Header File For The OpenGL Library */
#include <GL/glu.h> /* Header File For The GLU Library */ #include <GL/glu.h> /* Header File For The GLU Library */
......
...@@ -102,9 +102,6 @@ ...@@ -102,9 +102,6 @@
#pragma nopackwarning #pragma nopackwarning
#endif #endif
#pragma pack(push,4) #pragma pack(push,4)
#elif (defined(__MWERKS__) && defined(__MACOS__))
#pragma options align=mac68k4byte
#pragma enumsalwaysint on
#endif /* Compiler needs structure packing set */ #endif /* Compiler needs structure packing set */
/* Set up compiler-specific options for inlining functions */ /* Set up compiler-specific options for inlining functions */
......
...@@ -31,10 +31,5 @@ ...@@ -31,10 +31,5 @@
#ifdef __BORLANDC__ #ifdef __BORLANDC__
#pragma nopackwarning #pragma nopackwarning
#endif #endif
#if (defined(__MWERKS__) && defined(__MACOS__))
#pragma options align=reset
#pragma enumsalwaysint reset
#else
#pragma pack(pop) #pragma pack(pop)
#endif
#endif /* Compiler needs structure packing set */ #endif /* Compiler needs structure packing set */
...@@ -532,9 +532,6 @@ SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained) ...@@ -532,9 +532,6 @@ SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
SDL_SetError("SDL_OpenAudio() passed a NULL callback"); SDL_SetError("SDL_OpenAudio() passed a NULL callback");
return (-1); return (-1);
} }
#if defined(__MACOS__) || (defined(__RISCOS__) && SDL_THREADS_DISABLED)
/* FIXME: Need to implement PPC interrupt asm for SDL_LockAudio() */
#else
#if defined(__MINT__) && SDL_THREADS_DISABLED #if defined(__MINT__) && SDL_THREADS_DISABLED
/* Uses interrupt driven audio, without thread */ /* Uses interrupt driven audio, without thread */
#else #else
...@@ -546,7 +543,6 @@ SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained) ...@@ -546,7 +543,6 @@ SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
return (-1); return (-1);
} }
#endif /* __MINT__ */ #endif /* __MINT__ */
#endif /* __MACOS__ */
/* Calculate the silence and size of the audio specification */ /* Calculate the silence and size of the audio specification */
SDL_CalculateAudioSpec(desired); SDL_CalculateAudioSpec(desired);
......
...@@ -26,9 +26,7 @@ ...@@ -26,9 +26,7 @@
#include "SDL_cdrom.h" #include "SDL_cdrom.h"
#include "SDL_syscdrom.h" #include "SDL_syscdrom.h"
#if !defined(__MACOS__)
#define CLIP_FRAMES 10 /* Some CD-ROMs won't go all the way */ #define CLIP_FRAMES 10 /* Some CD-ROMs won't go all the way */
#endif
static int SDL_cdinitted = 0; static int SDL_cdinitted = 0;
static SDL_CD *default_cdrom; static SDL_CD *default_cdrom;
......
...@@ -74,4 +74,5 @@ extern int SDL_SYS_CDInit(void); ...@@ -74,4 +74,5 @@ extern int SDL_SYS_CDInit(void);
/* Function to perform any system-specific CD-ROM related cleanup */ /* Function to perform any system-specific CD-ROM related cleanup */
extern void SDL_SYS_CDQuit(void); extern void SDL_SYS_CDQuit(void);
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
/*
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"
#ifdef SDL_CDROM_MACOS
/* MacOS functions for system-level CD-ROM audio control */
#include <Devices.h>
#include <Files.h>
#include <LowMem.h> /* Use entry table macros, not functions in InterfaceLib */
#include "SDL_cdrom.h"
#include "../SDL_syscdrom.h"
#include "SDL_syscdrom_c.h"
/* Added by Matt Slot */
#if !defined(LMGetUnitTableEntryCount)
#define LMGetUnitTableEntryCount() *(short *)0x01D2
#endif
/* The maximum number of CD-ROM drives we'll detect */
#define MAX_DRIVES 26
/* A list of available CD-ROM drives */
static long SDL_cdversion = 0;
static struct
{
short dRefNum;
short driveNum;
long frames;
char name[256];
Boolean hasAudio;
} SDL_cdlist[MAX_DRIVES];
static StringPtr gDriverName = "\p.AppleCD";
/* The system-dependent CD control functions */
static const char *SDL_SYS_CDName(int drive);
static int SDL_SYS_CDOpen(int drive);
static int SDL_SYS_CDGetTOC(SDL_CD * cdrom);
static CDstatus SDL_SYS_CDStatus(SDL_CD * cdrom, int *position);
static int SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length);
static int SDL_SYS_CDPause(SDL_CD * cdrom);
static int SDL_SYS_CDResume(SDL_CD * cdrom);
static int SDL_SYS_CDStop(SDL_CD * cdrom);
static int SDL_SYS_CDEject(SDL_CD * cdrom);
static void SDL_SYS_CDClose(SDL_CD * cdrom);
static short
SDL_SYS_ShortToBCD(short value)
{
return ((value % 10) + (value / 10) * 0x10); /* Convert value to BCD */
}
static short
SDL_SYS_BCDToShort(short value)
{
return ((value % 0x10) + (value / 0x10) * 10); /* Convert value from BCD */
}
int
SDL_SYS_CDInit(void)
{
SInt16 dRefNum = 0;
SInt16 first, last;
SDL_numcds = 0;
/* Check that the software is available */
if (Gestalt(kGestaltAudioCDSelector, &SDL_cdversion) || !SDL_cdversion)
return (0);
/* Fill in our driver capabilities */
SDL_CDcaps.Name = SDL_SYS_CDName;
SDL_CDcaps.Open = SDL_SYS_CDOpen;
SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC;
SDL_CDcaps.Status = SDL_SYS_CDStatus;
SDL_CDcaps.Play = SDL_SYS_CDPlay;
SDL_CDcaps.Pause = SDL_SYS_CDPause;
SDL_CDcaps.Resume = SDL_SYS_CDResume;
SDL_CDcaps.Stop = SDL_SYS_CDStop;
SDL_CDcaps.Eject = SDL_SYS_CDEject;
SDL_CDcaps.Close = SDL_SYS_CDClose;
/* Walk the list, count each AudioCD driver, and save the refnums */
first = -1;
last = 0 - LMGetUnitTableEntryCount();
for (dRefNum = first; dRefNum >= last; dRefNum--) {
Str255 driverName;
StringPtr namePtr;
DCtlHandle deviceEntry;
deviceEntry = GetDCtlEntry(dRefNum);
if (!deviceEntry)
continue;
/* Is this an .AppleCD ? */
namePtr = (*deviceEntry)->dCtlFlags & (1L << dRAMBased) ?
((StringPtr) ((DCtlPtr) deviceEntry)->dCtlDriver + 18) :
((StringPtr) (*deviceEntry)->dCtlDriver + 18);
BlockMoveData(namePtr, driverName, namePtr[0] + 1);
if (driverName[0] > gDriverName[0])
driverName[0] = gDriverName[0];
if (!EqualString(driverName, gDriverName, false, false))
continue;
/* Record the basic info for each drive */
SDL_cdlist[SDL_numcds].dRefNum = dRefNum;
BlockMoveData(namePtr + 1, SDL_cdlist[SDL_numcds].name, namePtr[0]);
SDL_cdlist[SDL_numcds].name[namePtr[0]] = 0;
SDL_cdlist[SDL_numcds].hasAudio = false;
SDL_numcds++;
}
return (0);
}
static const char *
SDL_SYS_CDName(int drive)
{
return (SDL_cdlist[drive].name);
}
static int
get_drivenum(int drive)
{
QHdr *driveQ = GetDrvQHdr();
DrvQEl *driveElem;
/* Update the drive number */
SDL_cdlist[drive].driveNum = 0;
if (driveQ->qTail) {
driveQ->qTail->qLink = 0;
}
for (driveElem = (DrvQEl *) driveQ->qHead; driveElem;
driveElem = (DrvQEl *) driveElem->qLink) {
if (driveElem->dQRefNum == SDL_cdlist[drive].dRefNum) {
SDL_cdlist[drive].driveNum = driveElem->dQDrive;
break;
}
}
return (SDL_cdlist[drive].driveNum);
}
static int
SDL_SYS_CDOpen(int drive)
{
return (drive);
}
static int
SDL_SYS_CDGetTOC(SDL_CD * cdrom)
{
CDCntrlParam cdpb;
CDTrackData tracks[SDL_MAX_TRACKS];
long i, leadout;
/* Get the number of tracks on the CD by examining the TOC */
SDL_memset(&cdpb, 0, sizeof(cdpb));
cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
cdpb.csCode = kReadTOC;
cdpb.csParam.words[0] = kGetTrackRange;
if (PBControlSync((ParmBlkPtr) & cdpb) != noErr) {
SDL_SetError("PBControlSync() failed");
return (-1);
}
cdrom->numtracks =
SDL_SYS_BCDToShort(cdpb.csParam.bytes[1]) -
SDL_SYS_BCDToShort(cdpb.csParam.bytes[0]) + 1;
if (cdrom->numtracks > SDL_MAX_TRACKS)
cdrom->numtracks = SDL_MAX_TRACKS;
cdrom->status = CD_STOPPED;
cdrom->cur_track = 0; /* Apparently these are set elsewhere */
cdrom->cur_frame = 0; /* Apparently these are set elsewhere */
/* Get the lead out area of the CD by examining the TOC */
SDL_memset(&cdpb, 0, sizeof(cdpb));
cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
cdpb.csCode = kReadTOC;
cdpb.csParam.words[0] = kGetLeadOutArea;
if (PBControlSync((ParmBlkPtr) & cdpb) != noErr) {
SDL_SetError("PBControlSync() failed");
return (-1);
}
leadout = MSF_TO_FRAMES(SDL_SYS_BCDToShort(cdpb.csParam.bytes[0]),
SDL_SYS_BCDToShort(cdpb.csParam.bytes[1]),
SDL_SYS_BCDToShort(cdpb.csParam.bytes[2]));
/* Get an array of track locations by examining the TOC */
SDL_memset(tracks, 0, sizeof(tracks));
SDL_memset(&cdpb, 0, sizeof(cdpb));
cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
cdpb.csCode = kReadTOC;
cdpb.csParam.words[0] = kGetTrackEntries; /* Type of Query */
*((long *) (cdpb.csParam.words + 1)) = (long) tracks;
cdpb.csParam.words[3] = cdrom->numtracks * sizeof(tracks[0]);
*((char *) (cdpb.csParam.words + 4)) = 1; /* First track */
if (PBControlSync((ParmBlkPtr) & cdpb) != noErr) {
SDL_SetError("PBControlSync() failed");
return (-1);
}
/* Read all the track TOC entries */
SDL_cdlist[cdrom->id].hasAudio = false;
for (i = 0; i < cdrom->numtracks; ++i) {
cdrom->track[i].id = i + 1;
if (tracks[i].entry.control & kDataTrackMask)
cdrom->track[i].type = SDL_DATA_TRACK;
else {
cdrom->track[i].type = SDL_AUDIO_TRACK;
SDL_cdlist[SDL_numcds].hasAudio = true;
}
cdrom->track[i].offset =
MSF_TO_FRAMES(SDL_SYS_BCDToShort(tracks[i].entry.min),
SDL_SYS_BCDToShort(tracks[i].entry.min),
SDL_SYS_BCDToShort(tracks[i].entry.frame));
cdrom->track[i].length =
MSF_TO_FRAMES(SDL_SYS_BCDToShort(tracks[i + 1].entry.min),
SDL_SYS_BCDToShort(tracks[i + 1].entry.min),
SDL_SYS_BCDToShort(tracks[i + 1].entry.frame)) -
cdrom->track[i].offset;
}
/* Apparently SDL wants a fake last entry */
cdrom->track[i].offset = leadout;
cdrom->track[i].length = 0;
return (0);
}
/* Get CD-ROM status */
static CDstatus
SDL_SYS_CDStatus(SDL_CD * cdrom, int *position)
{
CDCntrlParam cdpb;
CDstatus status = CD_ERROR;
Boolean spinning = false;
if (position)
*position = 0;
/* Get the number of tracks on the CD by examining the TOC */
if (!get_drivenum(cdrom->id)) {
return (CD_TRAYEMPTY);
}
SDL_memset(&cdpb, 0, sizeof(cdpb));
cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
cdpb.csCode = kReadTOC;
cdpb.csParam.words[0] = kGetTrackRange;
if (PBControlSync((ParmBlkPtr) & cdpb) != noErr) {
SDL_SetError("PBControlSync() failed");
return (CD_ERROR);
}
cdrom->numtracks =
SDL_SYS_BCDToShort(cdpb.csParam.bytes[1]) -
SDL_SYS_BCDToShort(cdpb.csParam.bytes[0]) + 1;
if (cdrom->numtracks > SDL_MAX_TRACKS)
cdrom->numtracks = SDL_MAX_TRACKS;
cdrom->cur_track = 0; /* Apparently these are set elsewhere */
cdrom->cur_frame = 0; /* Apparently these are set elsewhere */
if (1 || SDL_cdlist[cdrom->id].hasAudio) {
/* Get the current playback status */
SDL_memset(&cdpb, 0, sizeof(cdpb));
cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
cdpb.csCode = kAudioStatus;
if (PBControlSync((ParmBlkPtr) & cdpb) != noErr) {
SDL_SetError("PBControlSync() failed");
return (-1);
}
switch (cdpb.csParam.cd.status) {
case kStatusPlaying:
status = CD_PLAYING;
spinning = true;
break;
case kStatusPaused:
status = CD_PAUSED;
spinning = true;
break;
case kStatusMuted:
status = CD_PLAYING; /* What should I do here? */
spinning = true;
break;
case kStatusDone:
status = CD_STOPPED;
spinning = true;
break;
case kStatusStopped:
status = CD_STOPPED;
spinning = false;
break;
case kStatusError:
default:
status = CD_ERROR;
spinning = false;
break;
}
if (spinning && position)
*position =
MSF_TO_FRAMES(SDL_SYS_BCDToShort(cdpb.csParam.cd.minute),
SDL_SYS_BCDToShort(cdpb.csParam.cd.second),
SDL_SYS_BCDToShort(cdpb.csParam.cd.frame));
} else
status = CD_ERROR; /* What should I do here? */
return (status);
}
/* Start play */
static int
SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length)
{
CDCntrlParam cdpb;
/* Pause the current audio playback to avoid audible artifacts */
if (SDL_SYS_CDPause(cdrom) < 0) {
return (-1);
}
/* Specify the AudioCD playback mode */
SDL_memset(&cdpb, 0, sizeof(cdpb));
cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
cdpb.csCode = kSetPlayMode;
cdpb.csParam.bytes[0] = false; /* Repeat? */
cdpb.csParam.bytes[1] = kPlayModeSequential; /* Play mode */
/* Treat as soft error, NEC Drive doesnt support this call */
PBControlSync((ParmBlkPtr) & cdpb);
#if 1
/* Specify the end of audio playback */
SDL_memset(&cdpb, 0, sizeof(cdpb));
cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
cdpb.csCode = kAudioStop;
cdpb.csParam.words[0] = kBlockPosition; /* Position Mode */
*(long *) (cdpb.csParam.words + 1) = start + length - 1; /* Search Address */
if (PBControlSync((ParmBlkPtr) & cdpb) != noErr) {
SDL_SetError("PBControlSync() failed");
return (-1);
}
/* Specify the start of audio playback, and start it */
SDL_memset(&cdpb, 0, sizeof(cdpb));
cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
cdpb.csCode = kAudioPlay;
cdpb.csParam.words[0] = kBlockPosition; /* Position Mode */
*(long *) (cdpb.csParam.words + 1) = start + 1; /* Search Address */
cdpb.csParam.words[3] = false; /* Stop address? */
cdpb.csParam.words[4] = kStereoPlayMode; /* Audio Play Mode */
if (PBControlSync((ParmBlkPtr) & cdpb) != noErr) {
SDL_SetError("PBControlSync() failed");
return (-1);
}
#else
/* Specify the end of audio playback */
FRAMES_TO_MSF(start + length, &m, &s, &f);
SDL_memset(&cdpb, 0, sizeof(cdpb));
cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
cdpb.csCode = kAudioStop;
cdpb.csParam.words[0] = kTrackPosition; /* Position Mode */
cdpb.csParam.words[1] = 0; /* Search Address (hiword) */
cdpb.csParam.words[2] = /* Search Address (loword) */
SDL_SYS_ShortToBCD(cdrom->numtracks);
if (PBControlSync((ParmBlkPtr) & cdpb) != noErr) {
SDL_SetError("PBControlSync() failed");
return (-1);
}
/* Specify the start of audio playback, and start it */
FRAMES_TO_MSF(start, &m, &s, &f);
SDL_memset(&cdpb, 0, sizeof(cdpb));
cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
cdpb.csCode = kAudioPlay;
cdpb.csParam.words[0] = kTrackPosition; /* Position Mode */
cdpb.csParam.words[1] = 0; /* Search Address (hiword) */
cdpb.csParam.words[2] = SDL_SYS_ShortToBCD(1); /* Search Address (loword) */
cdpb.csParam.words[3] = false; /* Stop address? */
cdpb.csParam.words[4] = kStereoPlayMode; /* Audio Play Mode */
if (PBControlSync((ParmBlkPtr) & cdpb) != noErr) {
SDL_SetError("PBControlSync() failed");
return (-1);
}
#endif
return (0);
}
/* Pause play */
static int
SDL_SYS_CDPause(SDL_CD * cdrom)
{
CDCntrlParam cdpb;
SDL_memset(&cdpb, 0, sizeof(cdpb));
cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
cdpb.csCode = kAudioPause;
cdpb.csParam.words[0] = 0; /* Pause/Continue Flag (hiword) */
cdpb.csParam.words[1] = 1; /* Pause/Continue Flag (loword) */
if (PBControlSync((ParmBlkPtr) & cdpb) != noErr) {
SDL_SetError("PBControlSync() failed");
return (-1);
}
return (0);
}
/* Resume play */
static int
SDL_SYS_CDResume(SDL_CD * cdrom)
{
CDCntrlParam cdpb;
SDL_memset(&cdpb, 0, sizeof(cdpb));
cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
cdpb.csCode = kAudioPause;
cdpb.csParam.words[0] = 0; /* Pause/Continue Flag (hiword) */
cdpb.csParam.words[1] = 0; /* Pause/Continue Flag (loword) */
if (PBControlSync((ParmBlkPtr) & cdpb) != noErr) {
SDL_SetError("PBControlSync() failed");
return (-1);
}
return (0);
}
/* Stop play */
static int
SDL_SYS_CDStop(SDL_CD * cdrom)
{
CDCntrlParam cdpb;
SDL_memset(&cdpb, 0, sizeof(cdpb));
cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
cdpb.csCode = kAudioStop;
cdpb.csParam.words[0] = 0; /* Position Mode */
cdpb.csParam.words[1] = 0; /* Search Address (hiword) */
cdpb.csParam.words[2] = 0; /* Search Address (loword) */
if (PBControlSync((ParmBlkPtr) & cdpb) != noErr) {
SDL_SetError("PBControlSync() failed");
return (-1);
}
return (0);
}
/* Eject the CD-ROM */
static int
SDL_SYS_CDEject(SDL_CD * cdrom)
{
Boolean disk = false;
QHdr *driveQ = GetDrvQHdr();
DrvQEl *driveElem;
HParamBlockRec hpb;
ParamBlockRec cpb;
for (driveElem = (DrvQEl *) driveQ->qHead; driveElem; driveElem =
(driveElem) ? ((DrvQEl *) driveElem->qLink) :
((DrvQEl *) driveQ->qHead)) {
if (driveQ->qTail) {
driveQ->qTail->qLink = 0;
}
if (driveElem->dQRefNum != SDL_cdlist[cdrom->id].dRefNum) {
continue;
}
/* Does drive contain mounted volume? If not, skip */
SDL_memset(&hpb, 0, sizeof(hpb));
hpb.volumeParam.ioVRefNum = driveElem->dQDrive;
if (PBHGetVInfoSync(&hpb) != noErr) {
continue;
}
if ((UnmountVol(0, driveElem->dQDrive) == noErr) &&
(Eject(0, driveElem->dQDrive) == noErr)) {
driveElem = 0; /* Clear pointer to reset our loop */
disk = true;
}
}
/* If no disk is present, just eject the tray */
if (!disk) {
SDL_memset(&cpb, 0, sizeof(cpb));
cpb.cntrlParam.ioVRefNum = 0; /* No Drive */
cpb.cntrlParam.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
cpb.cntrlParam.csCode = kEjectTheDisc;
if (PBControlSync((ParmBlkPtr) & cpb) != noErr) {
SDL_SetError("PBControlSync() failed");
return (-1);
}
}
return (0);
}
/* Close the CD-ROM handle */
static void
SDL_SYS_CDClose(SDL_CD * cdrom)
{
return;
}
void
SDL_SYS_CDQuit(void)
{
while (SDL_numcds--)
SDL_memset(SDL_cdlist + SDL_numcds, 0, sizeof(SDL_cdlist[0]));
}
#endif /* SDL_CDROM_MACOS */
/* vi: set ts=4 sw=4 expandtab: */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/* This is the MacOS specific header for the SDL CD-ROM API
Contributed by Matt Slot
*/
/* AppleCD Control calls */
#define kVerifyTheDisc 5 /* Returns noErr if there is disc inserted */
#define kEjectTheDisc 7 /* Eject disc from drive */
#define kUserEject 80 /* Enable/disable the CD-ROM eject button */
#define kReadTOC 100 /* Extract various TOC information from the disc */
#define kReadQ 101 /* Extract Q subcode info for the current track */
#define kAudioTrackSearch 103 /* Start playback from the indicated position */
#define kAudioPlay 104 /* Start playback from the indicated position */
#define kAudioPause 105 /* Pause/continue the playback */
#define kAudioStop 106 /* Stop playback at the indicated position */
#define kAudioStatus 107 /* Return audio play status */
#define kAudioControl 109 /* Set the output volume for the audio channels */
#define kReadAudioVolume 112 /* Get the output volume for the audio channels */
#define kSetTrackList 122 /* Set the track program for the audio CD to play */
#define kGetTrackList 123 /* Get the track program the audio CD is playing */
#define kGetTrackIndex 124 /* Get the track index the audio CD is playing */
#define kSetPlayMode 125 /* Set the audio tracks play mode */
#define kGetPlayMode 126 /* Get the audio tracks play mode */
/* AppleCD Status calls */
#define kGetDriveType 96 /* Get the type of the physical CD-ROM drive */
#define kWhoIsThere 97 /* Get a bitmap of SCSI IDs the driver controls */
#define kGetBlockSize 98 /* Get current block size of the CD-ROM drive */
/* AppleCD other constants */
#define kBlockPosition 0 /* Position at the specified logical block number */
#define kAbsMSFPosition 1 /* Position at the specified Min/Sec/Frame (in BCD) */
#define kTrackPosition 2 /* Position at the specified track number (in BCD) */
#define kIndexPosition 3 /* Position at the nth track in program (in BCD) */
#define kMutedPlayMode 0 /* Play the audio track with no output */
#define kStereoPlayMode 9 /* Play the audio track in normal stereo */
#define kControlFieldMask 0x0D /* Bits 3,2,0 in the nibble */
#define kDataTrackMask 0x04 /* Indicates Data Track */
#define kGetTrackRange 1 /* Query TOC for track numbers */
#define kGetLeadOutArea 2 /* Query TOC for "Lead Out" end of audio data */
#define kGetTrackEntries 3 /* Query TOC for track starts and data types */
#define kStatusPlaying 0 /* Audio Play operation in progress */
#define kStatusPaused 1 /* CD-ROM device in Hold Track ("Pause") state */
#define kStatusMuted 2 /* MUTING-ON operation in progress */
#define kStatusDone 3 /* Audio Play completed */
#define kStatusError 4 /* Error occurred during audio play operation */
#define kStatusStopped 5 /* Audio play operation not requested */
#define kPlayModeSequential 0 /* Play tracks in order */
#define kPlayModeShuffled 1 /* Play tracks randomly */
#define kPlayModeProgrammed 2 /* Use custom playlist */
/* AppleCD Gestalt selectors */
#define kGestaltAudioCDSelector 'aucd'
#define kDriverVersion52 0x00000520
#define kDriverVersion51 0x00000510
#define kDriverVersion50 0x00000500
/* Drive type constants */
#define kDriveAppleCD_SC 1
#define kDriveAppleCD_SCPlus_or_150 2
#define kDriveAppleCD_300_or_300Plus 3
/* Misc constants */
#define kFirstSCSIDevice -33
#define kLastSCSIDevice -40
#if PRAGMA_STRUCT_ALIGN
#pragma options align=mac68k
#endif
/* AppleCD driver parameter block */
typedef struct CDCntrlParam
{
QElemPtr qLink;
short qType;
short ioTrap;
Ptr ioCmdAddr;
IOCompletionUPP ioCompletion;
OSErr ioResult;
StringPtr ioNamePtr;
short ioVRefNum;
short ioCRefNum;
short csCode;
union
{
long longs[6];
short words[11];
unsigned char bytes[22];
struct
{
unsigned char status;
unsigned char play;
unsigned char control;
unsigned char minute;
unsigned char second;
unsigned char frame;
} cd;
} csParam;
} CDCntrlParam, *CDCntrlParamPtr;
typedef union CDTrackData
{
long value; /* Treat as a longword value */
struct
{
unsigned char reserved:4; /* Unused by AppleCD driver */
unsigned char control:4; /* Track flags (data track?) */
unsigned char min; /* Start of track (BCD) */
unsigned char sec; /* Start of track (BCD) */
unsigned char frame; /* Start of track (BCD) */
} entry; /* Broken into fields */
} CDTrackData, *CDTrackPtr;
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
/* vi: set ts=4 sw=4 expandtab: */
...@@ -157,11 +157,7 @@ SDL_StartEventThread(Uint32 flags) ...@@ -157,11 +157,7 @@ SDL_StartEventThread(Uint32 flags)
#if !SDL_THREADS_DISABLED #if !SDL_THREADS_DISABLED
SDL_EventQ.lock = SDL_CreateMutex(); SDL_EventQ.lock = SDL_CreateMutex();
if (SDL_EventQ.lock == NULL) { if (SDL_EventQ.lock == NULL) {
#ifdef __MACOS__ /* MacOS classic you can't multithread, so no lock needed */
;
#else
return (-1); return (-1);
#endif
} }
#endif /* !SDL_THREADS_DISABLED */ #endif /* !SDL_THREADS_DISABLED */
SDL_EventQ.active = 1; SDL_EventQ.active = 1;
......
...@@ -37,11 +37,8 @@ ...@@ -37,11 +37,8 @@
#define CANT_THREAD_EVENTS #define CANT_THREAD_EVENTS
#endif #endif
#ifdef __MACOS__ /* MacOS 7/8 don't support preemptive multi-tasking */
#define CANT_THREAD_EVENTS
#endif
#ifdef __OS2__ /* The OS/2 event loop runs in a separate thread */ #ifdef __OS2__ /* The OS/2 event loop runs in a separate thread */
#define MUST_THREAD_EVENTS #define MUST_THREAD_EVENTS
#endif #endif
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
...@@ -349,51 +349,6 @@ mem_close(SDL_RWops * context) ...@@ -349,51 +349,6 @@ mem_close(SDL_RWops * context)
/* Functions to create SDL_RWops structures from various data sources */ /* Functions to create SDL_RWops structures from various data sources */
#ifdef __MACOS__
/*
* translate unix-style slash-separated filename to mac-style colon-separated
* name; return malloced string
*/
static char *
unix_to_mac(const char *file)
{
int flen = SDL_strlen(file);
char *path = SDL_malloc(flen + 2);
const char *src = file;
char *dst = path;
if (*src == '/') {
/* really depends on filesystem layout, hope for the best */
src++;
} else {
/* Check if this is a MacOS path to begin with */
if (*src != ':')
*dst++ = ':'; /* relative paths begin with ':' */
}
while (src < file + flen) {
const char *end = SDL_strchr(src, '/');
int len;
if (!end)
end = file + flen; /* last component */
len = end - src;
if (len == 0 || (len == 1 && src[0] == '.')) {
/* remove repeated slashes and . */
} else {
if (len == 2 && src[0] == '.' && src[1] == '.') {
/* replace .. with the empty string */
} else {
SDL_memcpy(dst, src, len);
dst += len;
}
if (end < file + flen)
*dst++ = ':';
}
src = end + 1;
}
*dst++ = '\0';
return path;
}
#endif /* __MACOS__ */
SDL_RWops * SDL_RWops *
SDL_RWFromFile(const char *file, const char *mode) SDL_RWFromFile(const char *file, const char *mode)
{ {
...@@ -421,15 +376,7 @@ SDL_RWFromFile(const char *file, const char *mode) ...@@ -421,15 +376,7 @@ SDL_RWFromFile(const char *file, const char *mode)
#elif HAVE_STDIO_H #elif HAVE_STDIO_H
#ifdef __MACOS__
{
char *mpath = unix_to_mac(file);
fp = fopen(mpath, mode);
SDL_free(mpath);
}
#else
fp = fopen(file, mode); fp = fopen(file, mode);
#endif
if (fp == NULL) { if (fp == NULL) {
SDL_SetError("Couldn't open %s", file); SDL_SetError("Couldn't open %s", file);
} else { } else {
......
...@@ -81,4 +81,5 @@ extern void SDL_SYS_JoystickClose(SDL_Joystick * joystick); ...@@ -81,4 +81,5 @@ extern void SDL_SYS_JoystickClose(SDL_Joystick * joystick);
/* Function to perform any system-specific joystick related cleanup */ /* Function to perform any system-specific joystick related cleanup */
extern void SDL_SYS_JoystickQuit(void); extern void SDL_SYS_JoystickQuit(void);
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
/*
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"
#ifdef SDL_JOYSTICK_MACOS
/* SDL stuff -- "SDL_sysjoystick.c"
MacOS joystick functions by Frederick Reitberger
The code that follows is meant for SDL. Use at your own risk.
*/
#include <InputSprocket.h>
#include "SDL_joystick.h"
#include "../SDL_sysjoystick.h"
#include "../SDL_joystick_c.h"
/* The max number of joysticks we will detect */
#define MAX_JOYSTICKS 16
/* Limit ourselves to 32 elements per device */
#define kMaxReferences 32
#define ISpSymmetricAxisToFloat(axis) ((((float) axis) - kISpAxisMiddle) / (kISpAxisMaximum-kISpAxisMiddle))
#define ISpAsymmetricAxisToFloat(axis) (((float) axis) / (kISpAxisMaximum))
static ISpDeviceReference SYS_Joysticks[MAX_JOYSTICKS];
static ISpElementListReference SYS_Elements[MAX_JOYSTICKS];
static ISpDeviceDefinition SYS_DevDef[MAX_JOYSTICKS];
struct joystick_hwdata
{
char name[64];
/* Uint8 id;*/
ISpElementReference refs[kMaxReferences];
/* gonna need some sort of mapping info */
};
/* Function to scan the system for joysticks.
* Joystick 0 should be the system default joystick.
* This function should return the number of available joysticks, or -1
* on an unrecoverable fatal error.
*/
int
SDL_SYS_JoystickInit(void)
{
static ISpDeviceClass classes[4] = {
kISpDeviceClass_Joystick,
#if kISpDeviceClass_Gamepad
kISpDeviceClass_Gamepad,
#endif
kISpDeviceClass_Wheel,
0
};
OSErr err;
int i;
UInt32 count, numJoysticks;
if ((Ptr) 0 == (Ptr) ISpStartup) {
SDL_SetError("InputSprocket not installed");
return -1; // InputSprocket not installed
}
if ((Ptr) 0 == (Ptr) ISpGetVersion) {
SDL_SetError("InputSprocket not version 1.1 or newer");
return -1; // old version of ISp (not at least 1.1)
}
ISpStartup();
/* Get all the joysticks */
numJoysticks = 0;
for (i = 0; classes[i]; ++i) {
count = 0;
err = ISpDevices_ExtractByClass(classes[i],
MAX_JOYSTICKS - numJoysticks,
&count, &SYS_Joysticks[numJoysticks]);
numJoysticks += count;
}
for (i = 0; i < numJoysticks; i++) {
ISpDevice_GetDefinition(SYS_Joysticks[i],
sizeof(ISpDeviceDefinition), &SYS_DevDef[i]);
err = ISpElementList_New(0, NULL, &SYS_Elements[i], 0);
if (err) {
SDL_OutOfMemory();
return -1;
}
ISpDevice_GetElementList(SYS_Joysticks[i], &SYS_Elements[i]);
}
ISpDevices_Deactivate(numJoysticks, SYS_Joysticks);
return numJoysticks;
}
/* Function to get the device-dependent name of a joystick */
const char *
SDL_SYS_JoystickName(int index)
{
static char name[64];
int len;
/* convert pascal string to c-string */
len = SYS_DevDef[index].deviceName[0];
if (len >= sizeof(name)) {
len = (sizeof(name) - 1);
}
SDL_memcpy(name, &SYS_DevDef[index].deviceName[1], len);
name[len] = '\0';
return name;
}
/* Function to open a joystick for use.
The joystick to open is specified by the index field of the joystick.
This should fill the nbuttons and naxes fields of the joystick structure.
It returns 0, or -1 if there is an error.
*/
int
SDL_SYS_JoystickOpen(SDL_Joystick * joystick)
{
int index;
UInt32 count, gotCount, count2;
long numAxis, numButtons, numHats, numBalls;
count = kMaxReferences;
count2 = 0;
numAxis = numButtons = numHats = numBalls = 0;
index = joystick->index;
/* allocate memory for system specific hardware data */
joystick->hwdata =
(struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata));
if (joystick->hwdata == NULL) {
SDL_OutOfMemory();
return (-1);
}
SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
SDL_strlcpy(joystick->hwdata->name, SDL_SYS_JoystickName(index),
SDL_arraysize(joystick->hwdata->name));
joystick->name = joystick->hwdata->name;
ISpElementList_ExtractByKind(SYS_Elements[index],
kISpElementKind_Axis,
count, &gotCount, joystick->hwdata->refs);
numAxis = gotCount;
count -= gotCount;
count2 += gotCount;
ISpElementList_ExtractByKind(SYS_Elements[index],
kISpElementKind_DPad,
count,
&gotCount,
&(joystick->hwdata->refs[count2]));
numHats = gotCount;
count -= gotCount;
count2 += gotCount;
ISpElementList_ExtractByKind(SYS_Elements[index],
kISpElementKind_Button,
count,
&gotCount,
&(joystick->hwdata->refs[count2]));
numButtons = gotCount;
count -= gotCount;
count2 += gotCount;
joystick->naxes = numAxis;
joystick->nhats = numHats;
joystick->nballs = numBalls;
joystick->nbuttons = numButtons;
ISpDevices_Activate(1, &SYS_Joysticks[index]);
return 0;
}
/* Function to update the state of a joystick - called as a device poll.
* This function shouldn't update the joystick structure directly,
* but instead should call SDL_PrivateJoystick*() to deliver events
* and update joystick device state.
*/
void
SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
{
int i, j;
ISpAxisData a;
ISpDPadData b;
//ISpDeltaData c;
ISpButtonData d;
for (i = 0, j = 0; i < joystick->naxes; i++, j++) {
Sint16 value;
ISpElement_GetSimpleState(joystick->hwdata->refs[j], &a);
value = (ISpSymmetricAxisToFloat(a) * 32767.0);
if (value != joystick->axes[i]) {
SDL_PrivateJoystickAxis(joystick, i, value);
}
}
for (i = 0; i < joystick->nhats; i++, j++) {
Uint8 pos;
ISpElement_GetSimpleState(joystick->hwdata->refs[j], &b);
switch (b) {
case kISpPadIdle:
pos = SDL_HAT_CENTERED;
break;
case kISpPadLeft:
pos = SDL_HAT_LEFT;
break;
case kISpPadUpLeft:
pos = SDL_HAT_LEFTUP;
break;
case kISpPadUp:
pos = SDL_HAT_UP;
break;
case kISpPadUpRight:
pos = SDL_HAT_RIGHTUP;
break;
case kISpPadRight:
pos = SDL_HAT_RIGHT;
break;
case kISpPadDownRight:
pos = SDL_HAT_RIGHTDOWN;
break;
case kISpPadDown:
pos = SDL_HAT_DOWN;
break;
case kISpPadDownLeft:
pos = SDL_HAT_LEFTDOWN;
break;
}
if (pos != joystick->hats[i]) {
SDL_PrivateJoystickHat(joystick, i, pos);
}
}
for (i = 0; i < joystick->nballs; i++, j++) {
/* ignore balls right now */
}
for (i = 0; i < joystick->nbuttons; i++, j++) {
ISpElement_GetSimpleState(joystick->hwdata->refs[j], &d);
if (d != joystick->buttons[i]) {
SDL_PrivateJoystickButton(joystick, i, d);
}
}
}
/* Function to close a joystick after use */
void
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
{
int index;
index = joystick->index;
ISpDevices_Deactivate(1, &SYS_Joysticks[index]);
}
/* Function to perform any system-specific joystick related cleanup */
void
SDL_SYS_JoystickQuit(void)
{
ISpShutdown();
}
#endif /* SDL_JOYSTICK_MACOS */
/* vi: set ts=4 sw=4 expandtab: */
/*
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"
#ifdef SDL_LOADSO_MACOS
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent library loading routines */
#include <stdio.h>
#include <string.h>
#define OLDP2C 1
#include <Strings.h>
#include <CodeFragments.h>
#include <Errors.h>
#include "SDL_loadso.h"
void *
SDL_LoadObject(const char *sofile)
{
void *handle = NULL;
const char *loaderror = NULL;
CFragConnectionID library_id;
Ptr mainAddr;
Str255 errName;
OSErr error;
char psofile[512];
SDL_strlcpy(psofile, sofile, SDL_arraysize(psofile));
error = GetSharedLibrary(C2PStr(psofile), kCompiledCFragArch,
kLoadCFrag, &library_id, &mainAddr, errName);
switch (error) {
case noErr:
loaderror = NULL;
break;
case cfragNoLibraryErr:
loaderror = "Library not found";
break;
case cfragUnresolvedErr:
loaderror = "Unabled to resolve symbols";
break;
case cfragNoPrivateMemErr:
case cfragNoClientMemErr:
loaderror = "Out of memory";
break;
default:
loaderror = "Unknown Code Fragment Manager error";
break;
}
if (loaderror == NULL) {
handle = (void *) (library_id);
} else {
SDL_SetError("Failed loading %s: %s", sofile, loaderror);
}
return (handle);
}
void *
SDL_LoadFunction(void *handle, const char *name)
{
void *symbol = NULL;
const char *loaderror = NULL;
CFragSymbolClass class;
CFragConnectionID library_id = (CFragConnectionID) handle;
char pname[512];
SDL_strlcpy(pname, name, SDL_arraysize(pname));
if (FindSymbol(library_id, C2PStr(pname),
(char **) &symbol, &class) != noErr) {
loaderror = "Symbol not found";
}
if (symbol == NULL) {
SDL_SetError("Failed loading %s: %s", name, loaderror);
}
return (symbol);
}
void
SDL_UnloadObject(void *handle)
{
CFragConnectionID library_id;
if (handle != NULL) {
library_id = (CFragConnectionID) handle;
CloseConnection(&library_id);
}
}
#endif /* SDL_LOADSO_MACOS */
/* vi: set ts=4 sw=4 expandtab: */
data 'DLOG' (1000) {
$"0072 0040 00EA 01B3 0001 0100 0000 0000 0000 03E8 0C43 6F6D 6D61 6E64 204C 696E" /* .r.@..............Command Lin */
$"6500 280A" /* e.( */
};
data 'DLOG' (1001) {
$"0072 0040 00DB 01AC 0001 0100 0000 0000 0000 03E9 0C45 7272 6F72 2057 696E 646F" /* .r.@..............Error Windo */
$"7700 280A" /* w.( */
};
data 'DLOG' (1002) {
$"00B8 00BE 0147 01D8 0005 0100 0000 0000 0000 03EA 1643 6F6E 6669 726D 2044 6973" /* ...G.............Confirm Dis */
$"706C 6179 2043 6861 6E67 6510 280A" /* play Change.( */
};
data 'DITL' (1000) {
$"0005 0000 0000 0052 0113 0066 0158 0402 4F4B 0000 0000 0052 00C2 0066 0107 0406" /* .......R...f.X..OK.....R..f.... */
$"4361 6E63 656C 0000 0000 000F 0084 001F 0155 1000 0000 0000 0054 0019 0066 007D" /* Cancel..........U.......T...f.} */
$"050E 4F75 7470 7574 2074 6F20 6669 6C65 0000 0000 000F 0018 001F 007F 080D 436F" /* ..Output to file..............Co */
$"6D6D 616E 6420 4C69 6E65 3A00 0000 0000 0030 0018 0040 0158 0702 0080" /* mmand Line:......0...@.X... */
};
data 'DITL' (1001) {
$"0001 0000 0000 0046 0120 005A 015A 0402 4F4B 0000 0000 0010 000A 0038 0160 0800" /* .......F. .Z.Z..OK........8.`.. */
};
data 'DITL' (1002) {
$"0002 0000 0000 006F 001E 0083 0058 0406 4361 6E63 656C 0000 0000 006E 00C0 0082" /* .......o....X..Cancel.....n.. */
$"00FA 0402 4F4B 0000 0000 000E 000F 005F 010C 88B3 5468 6520 7365 7474 696E 6720" /* ...OK........._..The setting */
$"666F 7220 796F 7572 206D 6F6E 6974 6F72 2068 6173 2062 6565 6E20 6368 616E 6765" /* for your monitor has been change */
$"642C 2061 6E64 2069 7420 6D61 7920 6E6F 7420 6265 2064 6973 706C 6179 6564 2063" /* d, and it may not be displayed c */
$"6F72 7265 6374 6C79 2E20 546F 2063 6F6E 6669 726D 2074 6865 2064 6973 706C 6179" /* orrectly. To confirm the display */
$"2069 7320 636F 7272 6563 742C 2063 6C69 636B 204F 4B2E 2054 6F20 7265 7475 726E" /* is correct, click OK. To return */
$"2074 6F20 7468 6520 6F72 6967 696E 616C 2073 6574 7469 6E67 2C20 636C 6963 6B20" /* to the original setting, click */
$"4361 6E63 656C 2E00" /* Cancel.. */
};
data 'MENU' (128, preload) {
$"0080 0000 0000 0000 0000 FFFF FFFB 0114 0C41 626F 7574 2053 444C 2E2E 2E00 0000" /* ............About SDL...... */
$"0001 2D00 0000 0000" /* ..-..... */
};
data 'MENU' (129) {
$"0081 0000 0000 0000 0000 FFFF FFFF 0C56 6964 656F 2044 7269 7665 7219 4472 6177" /* ..........Video Driver.Draw */
$"5370 726F 636B 6574 2028 4675 6C6C 7363 7265 656E 2900 0000 001E 546F 6F6C 426F" /* Sprocket (Fullscreen).....ToolBo */
$"7820 2028 4675 6C6C 7363 7265 656E 2F57 696E 646F 7765 6429 0000 0000 00" /* x (Fullscreen/Windowed)..... */
};
data 'CNTL' (128) {
$"0000 0000 0010 0140 0000 0100 0064 0081 03F0 0000 0000 0D56 6964 656F 2044 7269" /* .......@.....d.......Video Dri */
$"7665 723A" /* ver: */
};
data 'TMPL' (128, "CLne") {
$"0C43 6F6D 6D61 6E64 204C 696E 6550 5354 520C 5669 6465 6F20 4472 6976 6572 5053" /* .Command LinePSTR.Video DriverPS */
$"5452 0C53 6176 6520 546F 2046 696C 6542 4F4F 4C" /* TR.Save To FileBOOL */
};
/*
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
*/
/* This file takes care of command line argument parsing, and stdio redirection
in the MacOS environment. (stdio/stderr is *not* directed for Mach-O builds)
*/
#if defined(__APPLE__) && defined(__MACH__)
#include <Carbon/Carbon.h>
#elif TARGET_API_MAC_CARBON && (UNIVERSAL_INTERFACES_VERSION > 0x0335)
#include <Carbon.h>
#else
#include <Dialogs.h>
#include <Fonts.h>
#include <Events.h>
#include <Resources.h>
#include <Folders.h>
#endif
/* Include the SDL main definition header */
#include "SDL.h"
#include "SDL_main.h"
#ifdef main
#undef main
#endif
#if !(defined(__APPLE__) && defined(__MACH__))
/* The standard output files */
#define STDOUT_FILE "stdout.txt"
#define STDERR_FILE "stderr.txt"
#endif
#if !defined(__MWERKS__) && !TARGET_API_MAC_CARBON
/* In MPW, the qd global has been removed from the libraries */
QDGlobals qd;
#endif
/* Structure for keeping prefs in 1 variable */
typedef struct
{
Str255 command_line;
Str255 video_driver_name;
Boolean output_to_file;
} PrefsRecord;
/* See if the command key is held down at startup */
static Boolean
CommandKeyIsDown(void)
{
KeyMap theKeyMap;
GetKeys(theKeyMap);
if (((unsigned char *) theKeyMap)[6] & 0x80) {
return (true);
}
return (false);
}
#if !(defined(__APPLE__) && defined(__MACH__))
/* Parse a command line buffer into arguments */
static int
ParseCommandLine(char *cmdline, char **argv)
{
char *bufp;
int argc;
argc = 0;
for (bufp = cmdline; *bufp;) {
/* Skip leading whitespace */
while (SDL_isspace(*bufp)) {
++bufp;
}
/* Skip over argument */
if (*bufp == '"') {
++bufp;
if (*bufp) {
if (argv) {
argv[argc] = bufp;
}
++argc;
}
/* Skip over word */
while (*bufp && (*bufp != '"')) {
++bufp;
}
} else {
if (*bufp) {
if (argv) {
argv[argc] = bufp;
}
++argc;
}
/* Skip over word */
while (*bufp && !SDL_isspace(*bufp)) {
++bufp;
}
}
if (*bufp) {
if (argv) {
*bufp = '\0';
}
++bufp;
}
}
if (argv) {
argv[argc] = NULL;
}
return (argc);
}
/* Remove the output files if there was no output written */
static void
cleanup_output(void)
{
FILE *file;
int empty;
/* Flush the output in case anything is queued */
fclose(stdout);
fclose(stderr);
/* See if the files have any output in them */
file = fopen(STDOUT_FILE, "rb");
if (file) {
empty = (fgetc(file) == EOF) ? 1 : 0;
fclose(file);
if (empty) {
remove(STDOUT_FILE);
}
}
file = fopen(STDERR_FILE, "rb");
if (file) {
empty = (fgetc(file) == EOF) ? 1 : 0;
fclose(file);
if (empty) {
remove(STDERR_FILE);
}
}
}
#endif //!(defined(__APPLE__) && defined(__MACH__))
static int
getCurrentAppName(StrFileName name)
{
ProcessSerialNumber process;
ProcessInfoRec process_info;
FSSpec process_fsp;
process.highLongOfPSN = 0;
process.lowLongOfPSN = kCurrentProcess;
process_info.processInfoLength = sizeof(process_info);
process_info.processName = NULL;
process_info.processAppSpec = &process_fsp;
if (noErr != GetProcessInformation(&process, &process_info))
return 0;
SDL_memcpy(name, process_fsp.name, process_fsp.name[0] + 1);
return 1;
}
static int
getPrefsFile(FSSpec * prefs_fsp, int create)
{
/* The prefs file name is the application name, possibly truncated, */
/* plus " Preferences */
#define SUFFIX " Preferences"
#define MAX_NAME 19 /* 31 - strlen (SUFFIX) */
short volume_ref_number;
long directory_id;
StrFileName prefs_name;
StrFileName app_name;
/* Get Preferences folder - works with Multiple Users */
if (noErr !=
FindFolder(kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder,
&volume_ref_number, &directory_id))
exit(-1);
if (!getCurrentAppName(app_name))
exit(-1);
/* Truncate if name is too long */
if (app_name[0] > MAX_NAME)
app_name[0] = MAX_NAME;
SDL_memcpy(prefs_name + 1, app_name + 1, app_name[0]);
SDL_memcpy(prefs_name + app_name[0] + 1, SUFFIX, strlen(SUFFIX));
prefs_name[0] = app_name[0] + strlen(SUFFIX);
/* Make the file spec for prefs file */
if (noErr !=
FSMakeFSSpec(volume_ref_number, directory_id, prefs_name, prefs_fsp))
{
if (!create)
return 0;
else {
/* Create the prefs file */
SDL_memcpy(prefs_fsp->name, prefs_name, prefs_name[0] + 1);
prefs_fsp->parID = directory_id;
prefs_fsp->vRefNum = volume_ref_number;
FSpCreateResFile(prefs_fsp, 0x3f3f3f3f, 'pref', 0); // '????' parsed as trigraph
if (noErr != ResError())
return 0;
}
}
return 1;
}
static int
readPrefsResource(PrefsRecord * prefs)
{
Handle prefs_handle;
prefs_handle = Get1Resource('CLne', 128);
if (prefs_handle != NULL) {
int offset = 0;
// int j = 0;
HLock(prefs_handle);
/* Get command line string */
SDL_memcpy(prefs->command_line, *prefs_handle,
(*prefs_handle)[0] + 1);
/* Get video driver name */
offset += (*prefs_handle)[0] + 1;
SDL_memcpy(prefs->video_driver_name, *prefs_handle + offset,
(*prefs_handle)[offset] + 1);
/* Get save-to-file option (1 or 0) */
offset += (*prefs_handle)[offset] + 1;
prefs->output_to_file = (*prefs_handle)[offset];
ReleaseResource(prefs_handle);
return ResError() == noErr;
}
return 0;
}
static int
writePrefsResource(PrefsRecord * prefs, short resource_file)
{
Handle prefs_handle;
UseResFile(resource_file);
prefs_handle = Get1Resource('CLne', 128);
if (prefs_handle != NULL)
RemoveResource(prefs_handle);
prefs_handle =
NewHandle(prefs->command_line[0] + prefs->video_driver_name[0] + 4);
if (prefs_handle != NULL) {
int offset;
HLock(prefs_handle);
/* Command line text */
offset = 0;
SDL_memcpy(*prefs_handle, prefs->command_line,
prefs->command_line[0] + 1);
/* Video driver name */
offset += prefs->command_line[0] + 1;
SDL_memcpy(*prefs_handle + offset, prefs->video_driver_name,
prefs->video_driver_name[0] + 1);
/* Output-to-file option */
offset += prefs->video_driver_name[0] + 1;
*(*((char **) prefs_handle) + offset) = (char) prefs->output_to_file;
*(*((char **) prefs_handle) + offset + 1) = 0;
AddResource(prefs_handle, 'CLne', 128, "\pCommand Line");
WriteResource(prefs_handle);
UpdateResFile(resource_file);
DisposeHandle(prefs_handle);
return ResError() == noErr;
}
return 0;
}
static int
readPreferences(PrefsRecord * prefs)
{
int no_error = 1;
FSSpec prefs_fsp;
/* Check for prefs file first */
if (getPrefsFile(&prefs_fsp, 0)) {
short prefs_resource;
prefs_resource = FSpOpenResFile(&prefs_fsp, fsRdPerm);
if (prefs_resource == -1) /* this shouldn't happen, but... */
return 0;
UseResFile(prefs_resource);
no_error = readPrefsResource(prefs);
CloseResFile(prefs_resource);
}
/* Fall back to application's resource fork (reading only, so this is safe) */
else {
no_error = readPrefsResource(prefs);
}
return no_error;
}
static int
writePreferences(PrefsRecord * prefs)
{
int no_error = 1;
FSSpec prefs_fsp;
/* Get prefs file, create if it doesn't exist */
if (getPrefsFile(&prefs_fsp, 1)) {
short prefs_resource;
prefs_resource = FSpOpenResFile(&prefs_fsp, fsRdWrPerm);
if (prefs_resource == -1)
return 0;
no_error = writePrefsResource(prefs, prefs_resource);
CloseResFile(prefs_resource);
}
return no_error;
}
/* This is where execution begins */
int
main(int argc, char *argv[])
{
#if !(defined(__APPLE__) && defined(__MACH__))
#pragma unused(argc, argv)
#endif
#define DEFAULT_ARGS "\p" /* pascal string for default args */
#define DEFAULT_VIDEO_DRIVER "\ptoolbox" /* pascal string for default video driver name */
#define DEFAULT_OUTPUT_TO_FILE 1 /* 1 == output to file, 0 == no output */
#define VIDEO_ID_DRAWSPROCKET 1 /* these correspond to popup menu choices */
#define VIDEO_ID_TOOLBOX 2
PrefsRecord prefs =
{ DEFAULT_ARGS, DEFAULT_VIDEO_DRIVER, DEFAULT_OUTPUT_TO_FILE };
#if !(defined(__APPLE__) && defined(__MACH__))
int nargs;
char **args;
char *commandLine;
StrFileName appNameText;
#endif
int videodriver = VIDEO_ID_TOOLBOX;
int settingsChanged = 0;
long i;
/* Kyle's SDL command-line dialog code ... */
#if !TARGET_API_MAC_CARBON
InitGraf(&qd.thePort);
InitFonts();
InitWindows();
InitMenus();
InitDialogs(nil);
#endif
InitCursor();
FlushEvents(everyEvent, 0);
#if !TARGET_API_MAC_CARBON
MaxApplZone();
#endif
MoreMasters();
MoreMasters();
#if 0
/* Intialize SDL, and put up a dialog if we fail */
if (SDL_Init(0) < 0) {
#define kErr_OK 1
#define kErr_Text 2
DialogPtr errorDialog;
short dummyType;
Rect dummyRect;
Handle dummyHandle;
short itemHit;
errorDialog = GetNewDialog(1001, nil, (WindowPtr) - 1);
if (errorDialog == NULL)
return -1;
DrawDialog(errorDialog);
GetDialogItem(errorDialog, kErr_Text, &dummyType, &dummyHandle,
&dummyRect);
SetDialogItemText(dummyHandle, "\pError Initializing SDL");
#if TARGET_API_MAC_CARBON
SetPort(GetDialogPort(errorDialog));
#else
SetPort(errorDialog);
#endif
do {
ModalDialog(nil, &itemHit);
}
while (itemHit != kErr_OK);
DisposeDialog(errorDialog);
exit(-1);
}
atexit(cleanup_output);
atexit(SDL_Quit);
#endif
/* Set up SDL's QuickDraw environment */
#if !TARGET_API_MAC_CARBON
SDL_InitQuickDraw(&qd);
#endif
if (readPreferences(&prefs)) {
if (SDL_memcmp(prefs.video_driver_name + 1, "DSp", 3) == 0)
videodriver = 1;
else if (SDL_memcmp(prefs.video_driver_name + 1, "toolbox", 7) == 0)
videodriver = 2;
}
if (CommandKeyIsDown()) {
#define kCL_OK 1
#define kCL_Cancel 2
#define kCL_Text 3
#define kCL_File 4
#define kCL_Video 6
DialogPtr commandDialog;
short dummyType;
Rect dummyRect;
Handle dummyHandle;
short itemHit;
#if TARGET_API_MAC_CARBON
ControlRef control;
#endif
/* Assume that they will change settings, rather than do exhaustive check */
settingsChanged = 1;
/* Create dialog and display it */
commandDialog = GetNewDialog(1000, nil, (WindowPtr) - 1);
#if TARGET_API_MAC_CARBON
SetPort(GetDialogPort(commandDialog));
#else
SetPort(commandDialog);
#endif
/* Setup controls */
#if TARGET_API_MAC_CARBON
GetDialogItemAsControl(commandDialog, kCL_File, &control);
SetControlValue(control, prefs.output_to_file);
#else
GetDialogItem(commandDialog, kCL_File, &dummyType, &dummyHandle, &dummyRect); /* MJS */
SetControlValue((ControlHandle) dummyHandle, prefs.output_to_file);
#endif
GetDialogItem(commandDialog, kCL_Text, &dummyType, &dummyHandle,
&dummyRect);
SetDialogItemText(dummyHandle, prefs.command_line);
#if TARGET_API_MAC_CARBON
GetDialogItemAsControl(commandDialog, kCL_Video, &control);
SetControlValue(control, videodriver);
#else
GetDialogItem(commandDialog, kCL_Video, &dummyType, &dummyHandle,
&dummyRect);
SetControlValue((ControlRef) dummyHandle, videodriver);
#endif
SetDialogDefaultItem(commandDialog, kCL_OK);
SetDialogCancelItem(commandDialog, kCL_Cancel);
do {
ModalDialog(nil, &itemHit); /* wait for user response */
/* Toggle command-line output checkbox */
if (itemHit == kCL_File) {
#if TARGET_API_MAC_CARBON
GetDialogItemAsControl(commandDialog, kCL_File, &control);
SetControlValue(control, !GetControlValue(control));
#else
GetDialogItem(commandDialog, kCL_File, &dummyType, &dummyHandle, &dummyRect); /* MJS */
SetControlValue((ControlHandle) dummyHandle,
!GetControlValue((ControlHandle)
dummyHandle));
#endif
}
}
while (itemHit != kCL_OK && itemHit != kCL_Cancel);
/* Get control values, even if they did not change */
GetDialogItem(commandDialog, kCL_Text, &dummyType, &dummyHandle, &dummyRect); /* MJS */
GetDialogItemText(dummyHandle, prefs.command_line);
#if TARGET_API_MAC_CARBON
GetDialogItemAsControl(commandDialog, kCL_File, &control);
prefs.output_to_file = GetControlValue(control);
#else
GetDialogItem(commandDialog, kCL_File, &dummyType, &dummyHandle, &dummyRect); /* MJS */
prefs.output_to_file = GetControlValue((ControlHandle) dummyHandle);
#endif
#if TARGET_API_MAC_CARBON
GetDialogItemAsControl(commandDialog, kCL_Video, &control);
videodriver = GetControlValue(control);
#else
GetDialogItem(commandDialog, kCL_Video, &dummyType, &dummyHandle,
&dummyRect);
videodriver = GetControlValue((ControlRef) dummyHandle);
#endif
DisposeDialog(commandDialog);
if (itemHit == kCL_Cancel) {
exit(0);
}
}
/* Set pseudo-environment variables for video driver, update prefs */
switch (videodriver) {
case VIDEO_ID_DRAWSPROCKET:
SDL_putenv("SDL_VIDEODRIVER=DSp");
SDL_memcpy(prefs.video_driver_name, "\pDSp", 4);
break;
case VIDEO_ID_TOOLBOX:
SDL_putenv("SDL_VIDEODRIVER=toolbox");
SDL_memcpy(prefs.video_driver_name, "\ptoolbox", 8);
break;
}
#if !(defined(__APPLE__) && defined(__MACH__))
/* Redirect standard I/O to files */
if (prefs.output_to_file) {
freopen(STDOUT_FILE, "w", stdout);
freopen(STDERR_FILE, "w", stderr);
} else {
fclose(stdout);
fclose(stderr);
}
#endif
if (settingsChanged) {
/* Save the prefs, even if they might not have changed (but probably did) */
if (!writePreferences(&prefs))
fprintf(stderr, "WARNING: Could not save preferences!\n");
}
#if !(defined(__APPLE__) && defined(__MACH__))
appNameText[0] = 0;
getCurrentAppName(appNameText); /* check for error here ? */
commandLine = (char *) malloc(appNameText[0] + prefs.command_line[0] + 2);
if (commandLine == NULL) {
exit(-1);
}
/* Rather than rewrite ParseCommandLine method, let's replace */
/* any spaces in application name with underscores, */
/* so that the app name is only 1 argument */
for (i = 1; i < 1 + appNameText[0]; i++)
if (appNameText[i] == ' ')
appNameText[i] = '_';
/* Copy app name & full command text to command-line C-string */
SDL_memcpy(commandLine, appNameText + 1, appNameText[0]);
commandLine[appNameText[0]] = ' ';
SDL_memcpy(commandLine + appNameText[0] + 1, prefs.command_line + 1,
prefs.command_line[0]);
commandLine[appNameText[0] + 1 + prefs.command_line[0]] = '\0';
/* Parse C-string into argv and argc */
nargs = ParseCommandLine(commandLine, NULL);
args = (char **) malloc((nargs + 1) * (sizeof *args));
if (args == NULL) {
exit(-1);
}
ParseCommandLine(commandLine, args);
/* Run the main application code */
SDL_main(nargs, args);
free(args);
free(commandLine);
/* Remove useless stdout.txt and stderr.txt */
cleanup_output();
#else // defined(__APPLE__) && defined(__MACH__)
SDL_main(argc, argv);
#endif
/* Exit cleanly, calling atexit() functions */
exit(0);
/* Never reached, but keeps the compiler quiet */
return (0);
}
/* vi: set ts=4 sw=4 expandtab: */
#include "Processes.r"
resource 'SIZE' (-1) {
reserved,
acceptSuspendResumeEvents,
reserved,
canBackground,
doesActivateOnFGSwitch,
backgroundAndForeground,
getFrontClicks,
ignoreAppDiedEvents,
is32BitCompatible,
isHighLevelEventAware,
onlyLocalHLEvents,
notStationeryAware,
useTextEditServices,
reserved,
reserved,
reserved,
5242880, // 5 megs minimum
5242880 // 5 megs maximum
};
EXPORTS = SDL.x
HEADERS = \
../../../../include/SDL.h \
../../../../include/SDL_active.h \
../../../../include/SDL_audio.h \
../../../../include/SDL_cdrom.h \
../../../../include/SDL_copying.h \
../../../../include/SDL_cpuinfo.h \
../../../../include/SDL_endian.h \
../../../../include/SDL_error.h \
../../../../include/SDL_events.h \
../../../../include/SDL_joystick.h \
../../../../include/SDL_keyboard.h \
../../../../include/SDL_keysym.h \
../../../../include/SDL_loadso.h \
../../../../include/SDL_mouse.h \
../../../../include/SDL_mutex.h \
../../../../include/SDL_quit.h \
../../../../include/SDL_rwops.h \
../../../../include/SDL_syswm.h \
../../../../include/SDL_thread.h \
../../../../include/SDL_timer.h \
../../../../include/SDL_version.h \
../../../../include/SDL_video.h
all: $(EXPORTS)
$(EXPORTS): Makefile gendef.pl $(HEADERS)
perl gendef.pl $(HEADERS) >$@ || rm $@
clean:
rm -f $(EXPORTS)
SDL_Init
SDL_InitSubSystem
SDL_QuitSubSystem
SDL_WasInit
SDL_Quit
SDL_GetAppState
SDL_AudioInit
SDL_AudioQuit
SDL_AudioDriverName
SDL_OpenAudio
SDL_GetAudioStatus
SDL_PauseAudio
SDL_LoadWAV_RW
SDL_FreeWAV
SDL_BuildAudioCVT
SDL_ConvertAudio
SDL_MixAudio
SDL_LockAudio
SDL_UnlockAudio
SDL_CloseAudio
SDL_CDNumDrives
SDL_CDName
SDL_CDOpen
SDL_CDStatus
SDL_CDPlayTracks
SDL_CDPlay
SDL_CDPause
SDL_CDResume
SDL_CDStop
SDL_CDEject
SDL_CDClose
SDL_HasRDTSC
SDL_HasMMX
SDL_HasMMXExt
SDL_Has3DNow
SDL_Has3DNowExt
SDL_HasSSE
SDL_HasSSE2
SDL_HasAltiVec
SDL_SetError
SDL_GetError
SDL_ClearError
SDL_Error
SDL_PumpEvents
SDL_PeepEvents
SDL_PollEvent
SDL_WaitEvent
SDL_PushEvent
SDL_SetEventFilter
SDL_GetEventFilter
SDL_EventState
SDL_NumJoysticks
SDL_JoystickName
SDL_JoystickOpen
SDL_JoystickOpened
SDL_JoystickIndex
SDL_JoystickNumAxes
SDL_JoystickNumBalls
SDL_JoystickNumHats
SDL_JoystickNumButtons
SDL_JoystickUpdate
SDL_JoystickEventState
SDL_JoystickGetAxis
SDL_JoystickGetHat
SDL_JoystickGetBall
SDL_JoystickGetButton
SDL_JoystickClose
SDL_EnableUNICODE
SDL_EnableKeyRepeat
SDL_GetKeyRepeat
SDL_GetKeyState
SDL_GetModState
SDL_SetModState
SDL_GetKeyName
SDL_LoadObject
SDL_LoadFunction
SDL_UnloadObject
SDL_GetMouseState
SDL_GetRelativeMouseState
SDL_WarpMouse
SDL_CreateCursor
SDL_SetCursor
SDL_GetCursor
SDL_FreeCursor
SDL_ShowCursor
SDL_CreateMutex
SDL_mutexP
SDL_mutexV
SDL_DestroyMutex
SDL_CreateSemaphore
SDL_DestroySemaphore
SDL_SemWait
SDL_SemTryWait
SDL_SemWaitTimeout
SDL_SemPost
SDL_SemValue
SDL_CreateCond
SDL_DestroyCond
SDL_CondSignal
SDL_CondBroadcast
SDL_CondWait
SDL_CondWaitTimeout
SDL_RWFromFile
SDL_RWFromFP
SDL_RWFromMem
SDL_RWFromConstMem
SDL_AllocRW
SDL_FreeRW
SDL_ReadLE16
SDL_ReadBE16
SDL_ReadLE32
SDL_ReadBE32
SDL_ReadLE64
SDL_ReadBE64
SDL_WriteLE16
SDL_WriteBE16
SDL_WriteLE32
SDL_WriteBE32
SDL_WriteLE64
SDL_WriteBE64
SDL_GetWMInfo
SDL_CreateThread
SDL_CreateThread
SDL_ThreadID
SDL_GetThreadID
SDL_WaitThread
SDL_KillThread
SDL_GetTicks
SDL_Delay
SDL_SetTimer
SDL_AddTimer
SDL_RemoveTimer
SDL_Linked_Version
SDL_VideoInit
SDL_VideoQuit
SDL_VideoDriverName
SDL_GetVideoSurface
SDL_GetVideoInfo
SDL_VideoModeOK
SDL_ListModes
SDL_SetVideoMode
SDL_UpdateRects
SDL_UpdateRect
SDL_Flip
SDL_SetGamma
SDL_SetGammaRamp
SDL_GetGammaRamp
SDL_SetColors
SDL_SetPalette
SDL_MapRGB
SDL_MapRGBA
SDL_GetRGB
SDL_GetRGBA
SDL_CreateRGBSurface
SDL_CreateRGBSurfaceFrom
SDL_FreeSurface
SDL_LockSurface
SDL_UnlockSurface
SDL_LoadBMP_RW
SDL_SaveBMP_RW
SDL_SetColorKey
SDL_SetAlpha
SDL_SetClipRect
SDL_GetClipRect
SDL_ConvertSurface
SDL_UpperBlit
SDL_LowerBlit
SDL_FillRect
SDL_DisplayFormat
SDL_DisplayFormatAlpha
SDL_CreateYUVOverlay
SDL_LockYUVOverlay
SDL_UnlockYUVOverlay
SDL_DisplayYUVOverlay
SDL_FreeYUVOverlay
SDL_GL_LoadLibrary
SDL_GL_GetProcAddress
SDL_GL_SetAttribute
SDL_GL_GetAttribute
SDL_GL_SwapBuffers
SDL_WM_SetCaption
SDL_WM_GetCaption
SDL_WM_SetIcon
SDL_WM_IconifyWindow
SDL_WM_ToggleFullScreen
SDL_WM_GrabInput
SDL_SoftStretch
SDL_putenv
SDL_getenv
SDL_qsort
SDL_revcpy
SDL_strlcpy
SDL_strlcat
SDL_strdup
SDL_strrev
SDL_strupr
SDL_strlwr
SDL_ltoa
SDL_ultoa
SDL_strcasecmp
SDL_strncasecmp
SDL_snprintf
SDL_vsnprintf
SDL_iconv
SDL_iconv_string
SDL_InitQuickDraw
#!/usr/bin/perl
#
# Program to take a set of header files and generate DLL export definitions
# Special exports to ignore for this platform
while ( ($file = shift(@ARGV)) ) {
if ( ! defined(open(FILE, $file)) ) {
warn "Couldn't open $file: $!\n";
next;
}
$printed_header = 0;
$file =~ s,.*/,,;
while (<FILE>) {
if ( / DECLSPEC.* SDLCALL ([^\s\(]+)/ ) {
if ( not $exclude{$1} ) {
print "\t$1\n";
}
}
}
close(FILE);
}
# Special exports to include for this platform
print "\tSDL_putenv\n";
print "\tSDL_getenv\n";
print "\tSDL_qsort\n";
print "\tSDL_revcpy\n";
print "\tSDL_strlcpy\n";
print "\tSDL_strlcat\n";
print "\tSDL_strdup\n";
print "\tSDL_strrev\n";
print "\tSDL_strupr\n";
print "\tSDL_strlwr\n";
print "\tSDL_ltoa\n";
print "\tSDL_ultoa\n";
print "\tSDL_strcasecmp\n";
print "\tSDL_strncasecmp\n";
print "\tSDL_snprintf\n";
print "\tSDL_vsnprintf\n";
print "\tSDL_iconv\n";
print "\tSDL_iconv_string\n";
print "\tSDL_InitQuickDraw\n";
/* File "FastTimes.c" - Original code by Matt Slot <fprefect@ambrosiasw.com> */
/* Created 4/24/99 - This file is hereby placed in the public domain */
/* Updated 5/21/99 - Calibrate to VIA, add TBR support, renamed functions */
/* Updated 10/4/99 - Use AbsoluteToNanoseconds() in case Absolute = double */
/* Updated 2/15/00 - Check for native Time Manager, no need to calibrate */
/* Updated 2/19/00 - Fixed default value for gScale under native Time Mgr */
/* Updated 3/21/00 - Fixed ns conversion, create 2 different scale factors */
/* Updated 5/03/00 - Added copyright and placed into PD. No code changes */
/* Updated 8/01/00 - Made "Carbon-compatible" by replacing LMGetTicks() */
/* This file is Copyright (C) Matt Slot, 1999-2000. It is hereby placed into
the public domain. The author makes no warranty as to fitness or stability */
#include <Gestalt.h>
#include <LowMem.h>
#include <CodeFragments.h>
#include <DriverServices.h>
#include <Timer.h>
#include "FastTimes.h"
#ifdef TARGET_CPU_PPC
#undef GENERATINGPOWERPC /* stop whining */
#define GENERATINGPOWERPC TARGET_CPU_PPC
#endif
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/*
On 680x0 machines, we just use Microseconds().
On PowerPC machines, we try several methods:
* DriverServicesLib is available on all PCI PowerMacs, and perhaps
some NuBus PowerMacs. If it is, we use UpTime() : Overhead = 2.1 sec.
* The PowerPC 601 has a built-in "real time clock" RTC, and we fall
back to that, accessing it directly from asm. Overhead = 1.3 sec.
* Later PowerPCs have an accurate "time base register" TBR, and we
fall back to that, access it from PowerPC asm. Overhead = 1.3 sec.
* We can also try Microseconds() which is emulated : Overhead = 36 sec.
On PowerPC machines, we avoid the following:
* OpenTransport is available on all PCI and some NuBus PowerMacs, but it
uses UpTime() if available and falls back to Microseconds() otherwise.
* InputSprocket is available on many PowerMacs, but again it uses
UpTime() if available and falls back to Microseconds() otherwise.
Another PowerPC note: certain configurations, especially 3rd party upgrade
cards, may return inaccurate timings for the CPU or memory bus -- causing
skew in various system routines (up to 20% drift!). The VIA chip is very
accurate, and it's the basis for the Time Manager and Microseconds().
Unfortunately, it's also very slow because the MacOS has to (a) switch to
68K and (b) poll for a VIA event.
We compensate for the drift by calibrating a floating point scale factor
between our fast method and the accurate timer at startup, then convert
each sample quickly on the fly. I'd rather not have the initialization
overhead -- but it's simply necessary for accurate timing. You can drop
it down to 30 ticks if you prefer, but that's as low as I'd recommend.
Under MacOS 9, "new world" Macs (iMacs, B+W G3s and G+W G4s) have a native
Time Manager implementation: UpTime(), Microseconds(), and TickCount() are
all based on the same underlying counter. This makes it silly to calibrate
UpTime() against TickCount(). We now check for this feature using Gestalt(),
and skip the whole calibration step if possible.
*/
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
#define RTCToNano(w) ((double) (w).hi * 1000000000.0 + (double) (w).lo)
#define WideTo64bit(w) (*(UInt64 *) &(w))
/* LMGetTicks() is not in Carbon and TickCount() has a fair bit of overhead,
so for speed we always read lowmem directly. This is a Mac OS X no-no, but
it always work on those systems that don't have a native Time Manager (ie,
anything before MacOS 9) -- regardless whether we are in Carbon or not! */
#define MyLMGetTicks() (*(volatile UInt32 *) 0x16A)
#if GENERATINGPOWERPC
static asm UnsignedWide PollRTC(void);
static asm UnsignedWide PollTBR(void);
static Ptr FindFunctionInSharedLib(StringPtr libName, StringPtr funcName);
static Boolean gInited = false;
static Boolean gNative = false;
static Boolean gUseRTC = false;
static Boolean gUseTBR = false;
static double gScaleUSec = 1.0 / 1000.0; /* 1 / ( nsec / usec) */
static double gScaleMSec = 1.0 / 1000000.0; /* 1 / ( nsec / msec) */
/* Functions loaded from DriverServicesLib */
typedef AbsoluteTime(*UpTimeProcPtr) (void);
typedef Nanoseconds(*A2NSProcPtr) (AbsoluteTime);
static UpTimeProcPtr gUpTime = NULL;
static A2NSProcPtr gA2NS = NULL;
#endif /* GENERATINGPOWERPC */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
void
FastInitialize()
{
SInt32 result;
if (!gInited) {
#if GENERATINGPOWERPC
/* Initialize the feature flags */
gNative = gUseRTC = gUseTBR = false;
/* We use CFM to find and load needed symbols from shared libraries, so
the application doesn't have to weak-link them, for convenience. */
gUpTime =
(UpTimeProcPtr) FindFunctionInSharedLib("\pDriverServicesLib",
"\pUpTime");
if (gUpTime)
gA2NS = (A2NSProcPtr)
FindFunctionInSharedLib("\pDriverServicesLib",
"\pAbsoluteToNanoseconds");
if (!gA2NS)
gUpTime = nil; /* Pedantic but necessary */
if (gUpTime) {
/* If we loaded UpTime(), then we need to know if the system has
a native implementation of the Time Manager. If so, then it's
pointless to calculate a scale factor against the missing VIA */
/* gestaltNativeTimeMgr = 4 in some future version of the headers */
if (!Gestalt(gestaltTimeMgrVersion, &result) &&
(result > gestaltExtendedTimeMgr))
gNative = true;
} else {
/* If no DriverServicesLib, use Gestalt() to get the processor type.
Only NuBus PowerMacs with old System Software won't have DSL, so
we know it should either be a 601 or 603. */
/* Use the processor gestalt to determine which register to use */
if (!Gestalt(gestaltNativeCPUtype, &result)) {
if (result == gestaltCPU601)
gUseRTC = true;
else if (result > gestaltCPU601)
gUseTBR = true;
}
}
/* Now calculate a scale factor to keep us accurate. */
if ((gUpTime && !gNative) || gUseRTC || gUseTBR) {
UInt64 tick, usec1, usec2;
UnsignedWide wide;
/* Wait for the beginning of the very next tick */
for (tick = MyLMGetTicks() + 1; tick > MyLMGetTicks(););
/* Poll the selected timer and prepare it (since we have time) */
wide = (gUpTime) ? (*gA2NS) ((*gUpTime) ()) :
((gUseRTC) ? PollRTC() : PollTBR());
usec1 = (gUseRTC) ? RTCToNano(wide) : WideTo64bit(wide);
/* Wait for the exact 60th tick to roll over */
while (tick + 60 > MyLMGetTicks());
/* Poll the selected timer again and prepare it */
wide = (gUpTime) ? (*gA2NS) ((*gUpTime) ()) :
((gUseRTC) ? PollRTC() : PollTBR());
usec2 = (gUseRTC) ? RTCToNano(wide) : WideTo64bit(wide);
/* Calculate a scale value that will give microseconds per second.
Remember, there are actually 60.15 ticks in a second, not 60. */
gScaleUSec = (60.0 * 1000000.0) / ((usec2 - usec1) * 60.15);
gScaleMSec = gScaleUSec / 1000.0;
}
#endif /* GENERATINGPOWERPC */
/* We've initialized our globals */
gInited = true;
}
}
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
UInt64
FastMicroseconds()
{
UnsignedWide wide;
UInt64 usec;
#if GENERATINGPOWERPC
/* Initialize globals the first time we are called */
if (!gInited)
FastInitialize();
if (gNative) {
/* Use DriverServices if it's available -- it's fast and compatible */
wide = (*gA2NS) ((*gUpTime) ());
usec = (double) WideTo64bit(wide) * gScaleUSec + 0.5;
} else if (gUpTime) {
/* Use DriverServices if it's available -- it's fast and compatible */
wide = (*gA2NS) ((*gUpTime) ());
usec = (double) WideTo64bit(wide) * gScaleUSec + 0.5;
} else if (gUseTBR) {
/* On a recent PowerPC, we poll the TBR directly */
wide = PollTBR();
usec = (double) WideTo64bit(wide) * gScaleUSec + 0.5;
} else if (gUseRTC) {
/* On a 601, we can poll the RTC instead */
wide = PollRTC();
usec = (double) RTCToNano(wide) * gScaleUSec + 0.5;
} else
#endif /* GENERATINGPOWERPC */
{
/* If all else fails, suffer the mixed mode overhead */
Microseconds(&wide);
usec = WideTo64bit(wide);
}
return (usec);
}
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
UInt64
FastMilliseconds()
{
UnsignedWide wide;
UInt64 msec;
#if GENERATINGPOWERPC
/* Initialize globals the first time we are called */
if (!gInited)
FastInitialize();
if (gNative) {
/* Use DriverServices if it's available -- it's fast and compatible */
wide = (*gA2NS) ((*gUpTime) ());
msec = (double) WideTo64bit(wide) * gScaleMSec + 0.5;
} else if (gUpTime) {
/* Use DriverServices if it's available -- it's fast and compatible */
wide = (*gA2NS) ((*gUpTime) ());
msec = (double) WideTo64bit(wide) * gScaleMSec + 0.5;
} else if (gUseTBR) {
/* On a recent PowerPC, we poll the TBR directly */
wide = PollTBR();
msec = (double) WideTo64bit(wide) * gScaleMSec + 0.5;
} else if (gUseRTC) {
/* On a 601, we can poll the RTC instead */
wide = PollRTC();
msec = (double) RTCToNano(wide) * gScaleMSec + 0.5;
} else
#endif /* GENERATINGPOWERPC */
{
/* If all else fails, suffer the mixed mode overhead */
Microseconds(&wide);
msec = ((double) WideTo64bit(wide) + 500.0) / 1000.0;
}
return (msec);
}
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
StringPtr
FastMethod()
{
StringPtr method = "\p<Unknown>";
#if GENERATINGPOWERPC
/* Initialize globals the first time we are called */
if (!gInited)
FastInitialize();
if (gNative) {
/* The Time Manager and UpTime() are entirely native on this machine */
method = "\pNative UpTime()";
} else if (gUpTime) {
/* Use DriverServices if it's available -- it's fast and compatible */
method = "\pUpTime()";
} else if (gUseTBR) {
/* On a recent PowerPC, we poll the TBR directly */
method = "\pPowerPC TBR";
} else if (gUseRTC) {
/* On a 601, we can poll the RTC instead */
method = "\pPowerPC RTC";
} else
#endif /* GENERATINGPOWERPC */
{
/* If all else fails, suffer the mixed mode overhead */
method = "\pMicroseconds()";
}
return (method);
}
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
#pragma mark -
#if GENERATINGPOWERPC
asm static UnsignedWide
PollRTC_()
{
entry PollRTC /* Avoid CodeWarrior glue */
machine 601 @ AGAIN:mfrtcu r4 /* RTCU = SPR 4 */
mfrtcl r5 /* RTCL = SPR 5 */
mfrtcu r6 cmpw r4, r6 bne @ AGAIN stw r4, 0(r3) stw r5, 4(r3) blr}
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
asm static UnsignedWide
PollTBR_()
{
entry PollTBR /* Avoid CodeWarrior glue */
machine 604 @ AGAIN:mftbu r4 /* TBRU = SPR 268 */
mftb r5 /* TBRL = SPR 269 */
mftbu r6 cmpw r4, r6 bne @ AGAIN stw r4, 0(r3) stw r5, 4(r3) blr}
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
static Ptr
FindFunctionInSharedLib(StringPtr libName, StringPtr funcName)
{
OSErr error = noErr;
Str255 errorStr;
Ptr func = NULL;
Ptr entry = NULL;
CFragSymbolClass symClass;
CFragConnectionID connID;
/* Find CFM containers for the current archecture -- CFM-PPC or CFM-68K */
if ( /* error = */ GetSharedLibrary(libName, kCompiledCFragArch,
kLoadCFrag, &connID, &entry,
errorStr))
return (NULL);
if ( /* error = */ FindSymbol(connID, funcName, &func, &symClass))
return (NULL);
return (func);
}
#endif /* GENERATINGPOWERPC */
/* vi: set ts=4 sw=4 expandtab: */
/* File "FastTimes.h" - Original code by Matt Slot <fprefect@ambrosiasw.com> */
#include "SDL_config.h"
/* Created 4/24/99 - This file is hereby placed in the public domain */
/* Updated 5/21/99 - Calibrate to VIA, add TBR support, renamed functions */
/* Updated 10/4/99 - Use AbsoluteToNanoseconds() in case Absolute = double */
/* Updated 2/15/00 - Check for native Time Manager, no need to calibrate */
/* Updated 3/21/00 - Fixed ns conversion, create 2 different scale factors */
/* Updated 5/03/00 - Added copyright and placed into PD. No code changes */
/* This file is Copyright (C) Matt Slot, 1999-2000. It is hereby placed into
the public domain. The author makes no warranty as to fitness or stability */
#ifndef __FAST_TIMES_HEADER__
#define __FAST_TIMES_HEADER__
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
extern void FastInitialize(void);
extern UInt64 FastMicroseconds(void);
extern UInt64 FastMilliseconds(void);
extern StringPtr FastMethod(void);
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
#endif /* __FAST_TIMES_HEADER__ */
/* vi: set ts=4 sw=4 expandtab: */
/*
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"
#ifdef SDL_TIMER_MACOS
#include <Types.h>
#include <Timer.h>
#include <OSUtils.h>
#include <Gestalt.h>
#include <Processes.h>
#include <LowMem.h>
#include "SDL_timer.h"
#include "../SDL_timer_c.h"
#define MS_PER_TICK (1000/60) /* MacOS tick = 1/60 second */
/* Note: This is only a step above the original 1/60s implementation.
* For a good implementation, see FastTimes.[ch], by Matt Slot.
*/
#define USE_MICROSECONDS
#define WideTo64bit(w) (*(UInt64 *) &(w))
UInt64 start;
void
SDL_StartTicks(void)
{
#ifdef USE_MICROSECONDS
UnsignedWide now;
Microseconds(&now);
start = WideTo64bit(now);
#else
/* FIXME: Should we implement a wrapping algorithm, like Win32? */
#endif
}
Uint32
SDL_GetTicks(void)
{
#ifdef USE_MICROSECONDS
UnsignedWide now;
Microseconds(&now);
return (Uint32) ((WideTo64bit(now) - start) / 1000);
#else
return (LMGetTicks() * MS_PER_TICK);
#endif
}
void
SDL_Delay(Uint32 ms)
{
#ifdef USE_MICROSECONDS
Uint32 end_ms;
end_ms = SDL_GetTicks() + ms;
do {
/* FIXME: Yield CPU? */ ;
}
while (SDL_GetTicks() < end_ms);
#else
UInt32 unused; /* MJS */
Delay(ms / MS_PER_TICK, &unused);
#endif
}
/* Data to handle a single periodic alarm */
typedef struct _ExtendedTimerRec
{
TMTask tmTask;
ProcessSerialNumber taskPSN;
} ExtendedTimerRec, *ExtendedTimerPtr;
static ExtendedTimerRec gExtendedTimerRec;
int
SDL_SYS_TimerInit(void)
{
/* We don't need a setup? */
return (0);
}
void
SDL_SYS_TimerQuit(void)
{
/* We don't need a cleanup? */
return;
}
/* Our Stub routine to set up and then call the real routine. */
pascal void
TimerCallbackProc(TMTaskPtr tmTaskPtr)
{
Uint32 ms;
WakeUpProcess(&((ExtendedTimerPtr) tmTaskPtr)->taskPSN);
ms = SDL_alarm_callback(SDL_alarm_interval);
if (ms) {
SDL_alarm_interval = ROUND_RESOLUTION(ms);
PrimeTime((QElemPtr) & gExtendedTimerRec.tmTask, SDL_alarm_interval);
} else {
SDL_alarm_interval = 0;
}
}
int
SDL_SYS_StartTimer(void)
{
/*
* Configure the global structure that stores the timing information.
*/
gExtendedTimerRec.tmTask.qLink = NULL;
gExtendedTimerRec.tmTask.qType = 0;
gExtendedTimerRec.tmTask.tmAddr = NewTimerUPP(TimerCallbackProc);
gExtendedTimerRec.tmTask.tmCount = 0;
gExtendedTimerRec.tmTask.tmWakeUp = 0;
gExtendedTimerRec.tmTask.tmReserved = 0;
GetCurrentProcess(&gExtendedTimerRec.taskPSN);
/* Install the task record */
InsXTime((QElemPtr) & gExtendedTimerRec.tmTask);
/* Go! */
PrimeTime((QElemPtr) & gExtendedTimerRec.tmTask, SDL_alarm_interval);
return (0);
}
void
SDL_SYS_StopTimer(void)
{
RmvTime((QElemPtr) & gExtendedTimerRec.tmTask);
}
#endif /* SDL_TIMER_MACOS */
/* vi: set ts=4 sw=4 expandtab: */
/*
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"
#ifdef SDL_TIMER_MACOS
#include <Types.h>
#include <Timer.h>
#include <OSUtils.h>
#include <Gestalt.h>
#include <Processes.h>
#include <LowMem.h>
#include "SDL_timer.h"
#include "../SDL_timer_c.h"
#include "FastTimes.h"
#if TARGET_API_MAC_CARBON
#define NewTimerProc NewTimerUPP
#endif
#define MS_PER_TICK (1000.0/60.0) /* MacOS tick = 1/60 second */
#define kTwoPower32 (4294967296.0) /* 2^32 */
static double start_tick;
static int is_fast_inited = 0;
void
SDL_StartTicks(void)
{
if (!is_fast_inited) // important to check or FastTime may hang machine!
SDL_SYS_TimerInit();
start_tick = FastMicroseconds();
}
Uint32
SDL_GetTicks(void)
{
if (!is_fast_inited)
SDL_SYS_TimerInit();
return FastMilliseconds();
}
void
SDL_Delay(Uint32 ms)
{
Uint32 stop, now;
stop = SDL_GetTicks() + ms;
do {
#if TARGET_API_MAC_CARBON
MPYield();
#else
SystemTask();
#endif
now = SDL_GetTicks();
}
while (stop > now);
}
/*
void SDL_StartTicks(void)
{
// FIXME: Should we implement a wrapping algorithm, like Win32?
}
Uint32 SDL_GetTicks(void)
{
UnsignedWide ms;
Microseconds (&ms);
return ( ms.lo / 1000 );
}
void SDL_Delay(Uint32 ms)
{
UnsignedWide microsecs;
UInt32 stop;
Microseconds (&microsecs);
stop = microsecs.lo + (ms * 1000);
while ( stop > microsecs.lo ) {
SystemTask ();
Microseconds (&microsecs);
}
}*/
/* Data to handle a single periodic alarm */
typedef struct _ExtendedTimerRec
{
TMTask tmTask;
ProcessSerialNumber taskPSN;
} ExtendedTimerRec, *ExtendedTimerPtr;
static ExtendedTimerRec gExtendedTimerRec;
int
SDL_SYS_TimerInit(void)
{
FastInitialize();
is_fast_inited = 1;
return (0);
}
void
SDL_SYS_TimerQuit(void)
{
/* We don't need a cleanup? */
return;
}
/* Our Stub routine to set up and then call the real routine. */
pascal void
TimerCallbackProc(TMTaskPtr tmTaskPtr)
{
Uint32 ms;
WakeUpProcess(&((ExtendedTimerPtr) tmTaskPtr)->taskPSN);
ms = SDL_alarm_callback(SDL_alarm_interval);
if (ms) {
SDL_alarm_interval = ROUND_RESOLUTION(ms);
PrimeTime((QElemPtr) & gExtendedTimerRec.tmTask, SDL_alarm_interval);
} else {
SDL_alarm_interval = 0;
}
}
int
SDL_SYS_StartTimer(void)
{
/*
* Configure the global structure that stores the timing information.
*/
gExtendedTimerRec.tmTask.qLink = NULL;
gExtendedTimerRec.tmTask.qType = 0;
gExtendedTimerRec.tmTask.tmAddr = NewTimerProc(TimerCallbackProc);
gExtendedTimerRec.tmTask.tmCount = 0;
gExtendedTimerRec.tmTask.tmWakeUp = 0;
gExtendedTimerRec.tmTask.tmReserved = 0;
GetCurrentProcess(&gExtendedTimerRec.taskPSN);
/* Install the task record */
InsXTime((QElemPtr) & gExtendedTimerRec.tmTask);
/* Go! */
PrimeTime((QElemPtr) & gExtendedTimerRec.tmTask, SDL_alarm_interval);
return (0);
}
void
SDL_SYS_StopTimer(void)
{
RmvTime((QElemPtr) & gExtendedTimerRec.tmTask);
}
#endif /* SDL_TIMER_MACOS */
/* vi: set ts=4 sw=4 expandtab: */
...@@ -336,12 +336,6 @@ extern VideoBootStrap WIN32_bootstrap; ...@@ -336,12 +336,6 @@ extern VideoBootStrap WIN32_bootstrap;
#if SDL_VIDEO_DRIVER_BWINDOW #if SDL_VIDEO_DRIVER_BWINDOW
extern VideoBootStrap BWINDOW_bootstrap; extern VideoBootStrap BWINDOW_bootstrap;
#endif #endif
#if SDL_VIDEO_DRIVER_TOOLBOX
extern VideoBootStrap TOOLBOX_bootstrap;
#endif
#if SDL_VIDEO_DRIVER_DRAWSPROCKET
extern VideoBootStrap DSp_bootstrap;
#endif
#if SDL_VIDEO_DRIVER_CYBERGRAPHICS #if SDL_VIDEO_DRIVER_CYBERGRAPHICS
extern VideoBootStrap CGX_bootstrap; extern VideoBootStrap CGX_bootstrap;
#endif #endif
......
...@@ -85,12 +85,6 @@ static VideoBootStrap *bootstrap[] = { ...@@ -85,12 +85,6 @@ static VideoBootStrap *bootstrap[] = {
#if SDL_VIDEO_DRIVER_BWINDOW #if SDL_VIDEO_DRIVER_BWINDOW
&BWINDOW_bootstrap, &BWINDOW_bootstrap,
#endif #endif
#if SDL_VIDEO_DRIVER_TOOLBOX
&TOOLBOX_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_DRAWSPROCKET
&DSp_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_CYBERGRAPHICS #if SDL_VIDEO_DRIVER_CYBERGRAPHICS
&CGX_bootstrap, &CGX_bootstrap,
#endif #endif
......
/*
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"
#ifndef _SDL_lowvideo_h
#define _SDL_lowvideo_h
#if defined(__APPLE__) && defined(__MACH__)
#include <Carbon/Carbon.h>
#elif TARGET_API_MAC_CARBON && (UNIVERSAL_INTERFACES_VERSION > 0x0335)
#include <Carbon.h>
#else
#include <Quickdraw.h>
#include <Palettes.h>
#include <Menus.h>
#include <DrawSprocket.h>
#endif
#if SDL_VIDEO_OPENGL
typedef struct __AGLContextRec *AGLContext;
#endif
#include "SDL_video.h"
#include "../SDL_sysvideo.h"
/* Hidden "this" pointer for the video functions */
#define _THIS SDL_VideoDevice *this
#if !TARGET_API_MAC_CARBON /* not available in OS X (or more accurately, Carbon) */
/* Global QuickDraw data */
extern QDGlobals *theQD;
#endif
/* Private display data */
struct SDL_PrivateVideoData
{
GDevice **SDL_Display;
WindowRef SDL_Window;
SDL_Rect **SDL_modelist;
CTabHandle SDL_CTab;
PaletteHandle SDL_CPal;
#if TARGET_API_MAC_CARBON
/* For entering and leaving fullscreen mode */
Ptr fullscreen_ctx;
#endif
/* The current window document style */
int current_style;
/* Information about the last cursor position */
Point last_where;
/* Information about the last keys down */
EventModifiers last_mods;
KeyMap last_keys;
/* A handle to the Apple Menu */
MenuRef apple_menu;
/* Information used by DrawSprocket driver */
struct DSpInfo *dspinfo;
#if SDL_VIDEO_OPENGL
AGLContext appleGLContext;
void *libraryHandle;
#endif
};
/* Old variable names */
#define SDL_Display (this->hidden->SDL_Display)
#define SDL_Window (this->hidden->SDL_Window)
#define SDL_modelist (this->hidden->SDL_modelist)
#define SDL_CTab (this->hidden->SDL_CTab)
#define SDL_CPal (this->hidden->SDL_CPal)
#define fullscreen_ctx (this->hidden->fullscreen_ctx)
#define current_style (this->hidden->current_style)
#define last_where (this->hidden->last_where)
#define last_mods (this->hidden->last_mods)
#define last_keys (this->hidden->last_keys)
#define apple_menu (this->hidden->apple_menu)
#define glContext (this->hidden->appleGLContext)
#endif /* _SDL_lowvideo_h */
/* vi: set ts=4 sw=4 expandtab: */
/*
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"
#include <stdio.h>
#if defined(__APPLE__) && defined(__MACH__)
#include <Carbon/Carbon.h>
#elif TARGET_API_MAC_CARBON && (UNIVERSAL_INTERFACES_VERSION > 0x0335)
#include <Carbon.h>
#else
#include <Script.h>
#include <LowMem.h>
#include <Devices.h>
#include <DiskInit.h>
#include <ToolUtils.h>
#endif
#include "SDL_events.h"
#include "SDL_video.h"
#include "SDL_syswm.h"
#include "../../events/SDL_events_c.h"
#include "../../events/SDL_sysevents.h"
#include "../SDL_cursor_c.h"
#include "SDL_macevents_c.h"
#include "SDL_mackeys.h"
#include "SDL_macmouse_c.h"
/* Define this to be able to collapse SDL windows.
#define USE_APPEARANCE_MANAGER
*/
/* Macintosh resource constants */
#define mApple 128 /* Apple menu resource */
#define iAbout 1 /* About menu item */
/* Functions to handle the About menu */
static void Mac_DoAppleMenu(_THIS, long item);
/* The translation table from a macintosh key scancode to a SDL keysym */
static SDLKey MAC_keymap[256];
static SDL_keysym *TranslateKey(int scancode, int modifiers,
SDL_keysym * keysym, int pressed);
/* Handle activation and deactivation -- returns whether an event was posted */
static int
Mac_HandleActivate(int activate)
{
if (activate) {
/* Show the current SDL application cursor */
SDL_SetCursor(NULL);
/* put our mask back case it changed during context switch */
SetEventMask(everyEvent & ~autoKeyMask);
} else {
#if TARGET_API_MAC_CARBON
{
Cursor cursor;
SetCursor(GetQDGlobalsArrow(&cursor));
}
#else
SetCursor(&theQD->arrow);
#endif
if (!Mac_cursor_showing) {
ShowCursor();
Mac_cursor_showing = 1;
}
}
return (SDL_PrivateAppActive(activate, SDL_APPINPUTFOCUS));
}
static void
myGlobalToLocal(_THIS, Point * pt)
{
if (SDL_VideoSurface && !(SDL_VideoSurface->flags & SDL_FULLSCREEN)) {
GrafPtr saveport;
GetPort(&saveport);
#if TARGET_API_MAC_CARBON
SetPort(GetWindowPort(SDL_Window));
#else
SetPort(SDL_Window);
#endif
GlobalToLocal(pt);
SetPort(saveport);
}
}
/* The main MacOS event handler */
static int
Mac_HandleEvents(_THIS, int wait4it)
{
static int mouse_button = 1;
int i;
EventRecord event;
#if TARGET_API_MAC_CARBON
/* There's no GetOSEvent() in the Carbon API. *sigh* */
#define cooperative_multitasking 1
#else
int cooperative_multitasking;
/* If we're running fullscreen, we can hog the MacOS events,
otherwise we had better play nicely with the other apps.
*/
if (this->screen && (this->screen->flags & SDL_FULLSCREEN)) {
cooperative_multitasking = 0;
} else {
cooperative_multitasking = 1;
}
#endif
/* If we call WaitNextEvent(), MacOS will check other processes
* and allow them to run, and perform other high-level processing.
*/
if (cooperative_multitasking || wait4it) {
UInt32 wait_time;
/* Are we polling or not? */
if (wait4it) {
wait_time = 2147483647;
} else {
wait_time = 0;
}
WaitNextEvent(everyEvent, &event, wait_time, nil);
} else {
#if ! TARGET_API_MAC_CARBON
GetOSEvent(everyEvent, &event);
#endif
}
#if TARGET_API_MAC_CARBON
/* for some reason, event.where isn't set ? */
GetGlobalMouse(&event.where);
#endif
/* Check for mouse motion */
if ((event.where.h != last_where.h) || (event.where.v != last_where.v)) {
Point pt;
pt = last_where = event.where;
myGlobalToLocal(this, &pt);
SDL_PrivateMouseMotion(0, 0, pt.h, pt.v);
}
/* Check the current state of the keyboard */
if (SDL_GetAppState() & SDL_APPINPUTFOCUS) {
KeyMap keys;
/* Check for special non-event keys */
if (event.modifiers != last_mods) {
static struct
{
EventModifiers mask;
SDLKey key;
} mods[] = {
{
alphaLock, SDLK_CAPSLOCK},
#if 0 /* These are handled below in the GetKeys() code */
{
cmdKey, SDLK_LMETA}, {
shiftKey, SDLK_LSHIFT}, {
rightShiftKey, SDLK_RSHIFT}, {
optionKey, SDLK_LALT}, {
rightOptionKey, SDLK_RALT}, {
controlKey, SDLK_LCTRL}, {
rightControlKey, SDLK_RCTRL},
#endif /* 0 */
{
0, 0}
};
SDL_keysym keysym;
Uint8 mode;
EventModifiers mod, mask;
/* Set up the keyboard event */
keysym.scancode = 0;
keysym.sym = SDLK_UNKNOWN;
keysym.mod = KMOD_NONE;
keysym.unicode = 0;
/* See what has changed, and generate events */
mod = event.modifiers;
for (i = 0; mods[i].mask; ++i) {
mask = mods[i].mask;
if ((mod & mask) != (last_mods & mask)) {
keysym.sym = mods[i].key;
if ((mod & mask) || (mods[i].key == SDLK_CAPSLOCK)) {
mode = SDL_PRESSED;
} else {
mode = SDL_RELEASED;
}
SDL_PrivateKeyboard(mode, &keysym);
}
}
/* Save state for next time */
last_mods = mod;
}
/* Check for normal event keys, but we have to scan the
actual keyboard state because on Mac OS X a keydown event
is immediately followed by a keyup event.
*/
GetKeys(keys);
if ((keys[0] != last_keys[0]) || (keys[1] != last_keys[1]) ||
(keys[2] != last_keys[2]) || (keys[3] != last_keys[3])) {
SDL_keysym keysym;
int old_bit, new_bit;
#ifdef DEBUG_KEYBOARD
fprintf(sterr, "New keys: 0x%x 0x%x 0x%x 0x%x\n",
new_keys[0], new_keys[1], new_keys[2], new_keys[3]);
#endif
for (i = 0; i < 128; ++i) {
old_bit = (((Uint8 *) last_keys)[i / 8] >> (i % 8)) & 0x01;
new_bit = (((Uint8 *) keys)[i / 8] >> (i % 8)) & 0x01;
if (old_bit != new_bit) {
/* Post the keyboard event */
#ifdef DEBUG_KEYBOARD
fprintf(stderr, "Scancode: 0x%2.2X\n", i);
#endif
SDL_PrivateKeyboard(new_bit,
TranslateKey(i,
event.
modifiers,
&keysym, new_bit));
}
}
/* Save state for next time */
last_keys[0] = keys[0];
last_keys[1] = keys[1];
last_keys[2] = keys[2];
last_keys[3] = keys[3];
}
}
/* Handle normal events */
switch (event.what) {
case mouseDown:
{
WindowRef win;
short area;
area = FindWindow(event.where, &win);
/* Support switching between the SIOUX console
and SDL_Window by clicking in the window.
*/
if (win && (win != FrontWindow())) {
SelectWindow(win);
}
switch (area) {
case inMenuBar: /* Only the apple menu exists */
Mac_DoAppleMenu(this, MenuSelect(event.where));
HiliteMenu(0);
break;
case inDrag:
#if TARGET_API_MAC_CARBON
DragWindow(win, event.where, NULL);
#else
DragWindow(win, event.where, &theQD->screenBits.bounds);
#endif
break;
case inGoAway:
if (TrackGoAway(win, event.where)) {
SDL_PrivateQuit();
}
break;
case inContent:
myGlobalToLocal(this, &event.where);
/* Treat command-click as right mouse button */
if (event.modifiers & optionKey) {
mouse_button = 2;
} else if (event.modifiers & cmdKey) {
mouse_button = 3;
} else {
mouse_button = 1;
}
SDL_PrivateMouseButton(SDL_PRESSED,
mouse_button, event.where.h,
event.where.v);
break;
case inGrow:
{
int newSize;
/* Don't allow resize if video mode isn't resizable */
if (!SDL_PublicSurface ||
!(SDL_PublicSurface->flags & SDL_RESIZABLE)) {
break;
}
#if TARGET_API_MAC_CARBON
newSize = GrowWindow(win, event.where, NULL);
#else
newSize =
GrowWindow(win, event.where,
&theQD->screenBits.bounds);
#endif
if (newSize) {
#if !TARGET_API_MAC_CARBON
EraseRect(&theQD->screenBits.bounds);
#endif
SizeWindow(win, LoWord(newSize), HiWord(newSize), 1);
SDL_PrivateResize(LoWord(newSize), HiWord(newSize));
}
}
break;
case inZoomIn:
case inZoomOut:
if (TrackBox(win, event.where, area)) {
Rect rect;
#if !TARGET_API_MAC_CARBON
EraseRect(&theQD->screenBits.bounds);
#endif
ZoomWindow(win, area, 0);
if (area == inZoomIn) {
GetWindowUserState(SDL_Window, &rect);
} else {
GetWindowStandardState(SDL_Window, &rect);
}
SDL_PrivateResize(rect.right - rect.left,
rect.bottom - rect.top);
}
break;
#if TARGET_API_MAC_CARBON
case inCollapseBox:
if (TrackBox(win, event.where, area)) {
if (IsWindowCollapsable(win)) {
CollapseWindow(win, !IsWindowCollapsed(win));
/* There should be something done like in inGrow case, but... */
}
}
break;
#endif /* TARGET_API_MAC_CARBON */
case inSysWindow:
#if TARGET_API_MAC_CARBON
/* Never happens in Carbon? */
#else
SystemClick(&event, win);
#endif
break;
default:
break;
}
}
break;
case mouseUp:
{
myGlobalToLocal(this, &event.where);
/* Release the mouse button we simulated in the last press.
The drawback of this methos is we cannot press more than
one button. However, this doesn't matter, since there is
only a single logical mouse button, even if you have a
multi-button mouse, this doesn't matter at all.
*/
SDL_PrivateMouseButton(SDL_RELEASED,
mouse_button, event.where.h,
event.where.v);
}
break;
#if 0 /* Handled above the switch statement */
case keyDown:
{
SDL_keysym keysym;
SDL_PrivateKeyboard(SDL_PRESSED,
TranslateKey((event.
message & keyCodeMask) >> 8
event.modifiers, &keysym, 1));
}
break;
case keyUp:
{
SDL_keysym keysym;
SDL_PrivateKeyboard(SDL_RELEASED,
TranslateKey((event.
message & keyCodeMask) >> 8
event.modifiers, &keysym, 0));
}
break;
#endif
case updateEvt:
{
BeginUpdate(SDL_Window);
#if SDL_VIDEO_OPENGL
if (SDL_VideoSurface->flags & SDL_INTERNALOPENGL)
SDL_GL_SwapBuffers();
else
#endif
if ((SDL_VideoSurface->flags & SDL_HWSURFACE) == SDL_SWSURFACE) {
SDL_UpdateRect(SDL_VideoSurface, 0, 0, 0, 0);
}
EndUpdate(SDL_Window);
}
/* If this was an update event for the SIOUX console, we return 0
in order to stop an endless series of updates being triggered.
*/
if ((WindowRef) event.message != SDL_Window) {
return 0;
}
break;
case activateEvt:
{
Mac_HandleActivate(!!(event.modifiers & activeFlag));
}
break;
case diskEvt:
{
#if TARGET_API_MAC_CARBON
/* What are we supposed to do? */ ;
#else
if (((event.message >> 16) & 0xFFFF) != noErr) {
Point spot;
SetPt(&spot, 0x0070, 0x0050);
DIBadMount(spot, event.message);
}
#endif
}
break;
case osEvt:
{
switch ((event.message >> 24) & 0xFF) {
#if 0 /* Handled above the switch statement */
case mouseMovedMessage:
{
myGlobalToLocal(this, &event.where);
SDL_PrivateMouseMotion(0, 0,
event.where.h, event.where.v);
}
break;
#endif /* 0 */
case suspendResumeMessage:
{
Mac_HandleActivate(!!(event.message & resumeFlag));
}
break;
}
}
break;
default:
{
;
}
break;
}
return (event.what != nullEvent);
}
void
Mac_PumpEvents(_THIS)
{
/* Process pending MacOS events */
while (Mac_HandleEvents(this, 0)) {
/* Loop and check again */ ;
}
}
void
Mac_InitOSKeymap(_THIS)
{
const void *KCHRPtr;
UInt32 state;
UInt32 value;
int i;
int world = SDLK_WORLD_0;
/* Map the MAC keysyms */
for (i = 0; i < SDL_arraysize(MAC_keymap); ++i)
MAC_keymap[i] = SDLK_UNKNOWN;
/* Defined MAC_* constants */
MAC_keymap[MK_ESCAPE] = SDLK_ESCAPE;
MAC_keymap[MK_F1] = SDLK_F1;
MAC_keymap[MK_F2] = SDLK_F2;
MAC_keymap[MK_F3] = SDLK_F3;
MAC_keymap[MK_F4] = SDLK_F4;
MAC_keymap[MK_F5] = SDLK_F5;
MAC_keymap[MK_F6] = SDLK_F6;
MAC_keymap[MK_F7] = SDLK_F7;
MAC_keymap[MK_F8] = SDLK_F8;
MAC_keymap[MK_F9] = SDLK_F9;
MAC_keymap[MK_F10] = SDLK_F10;
MAC_keymap[MK_F11] = SDLK_F11;
MAC_keymap[MK_F12] = SDLK_F12;
MAC_keymap[MK_PRINT] = SDLK_PRINT;
MAC_keymap[MK_SCROLLOCK] = SDLK_SCROLLOCK;
MAC_keymap[MK_PAUSE] = SDLK_PAUSE;
MAC_keymap[MK_POWER] = SDLK_POWER;
MAC_keymap[MK_BACKQUOTE] = SDLK_BACKQUOTE;
MAC_keymap[MK_1] = SDLK_1;
MAC_keymap[MK_2] = SDLK_2;
MAC_keymap[MK_3] = SDLK_3;
MAC_keymap[MK_4] = SDLK_4;
MAC_keymap[MK_5] = SDLK_5;
MAC_keymap[MK_6] = SDLK_6;
MAC_keymap[MK_7] = SDLK_7;
MAC_keymap[MK_8] = SDLK_8;
MAC_keymap[MK_9] = SDLK_9;
MAC_keymap[MK_0] = SDLK_0;
MAC_keymap[MK_MINUS] = SDLK_MINUS;
MAC_keymap[MK_EQUALS] = SDLK_EQUALS;
MAC_keymap[MK_BACKSPACE] = SDLK_BACKSPACE;
MAC_keymap[MK_INSERT] = SDLK_INSERT;
MAC_keymap[MK_HOME] = SDLK_HOME;
MAC_keymap[MK_PAGEUP] = SDLK_PAGEUP;
MAC_keymap[MK_NUMLOCK] = SDLK_NUMLOCK;
MAC_keymap[MK_KP_EQUALS] = SDLK_KP_EQUALS;
MAC_keymap[MK_KP_DIVIDE] = SDLK_KP_DIVIDE;
MAC_keymap[MK_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
MAC_keymap[MK_TAB] = SDLK_TAB;
MAC_keymap[MK_q] = SDLK_q;
MAC_keymap[MK_w] = SDLK_w;
MAC_keymap[MK_e] = SDLK_e;
MAC_keymap[MK_r] = SDLK_r;
MAC_keymap[MK_t] = SDLK_t;
MAC_keymap[MK_y] = SDLK_y;
MAC_keymap[MK_u] = SDLK_u;
MAC_keymap[MK_i] = SDLK_i;
MAC_keymap[MK_o] = SDLK_o;
MAC_keymap[MK_p] = SDLK_p;
MAC_keymap[MK_LEFTBRACKET] = SDLK_LEFTBRACKET;
MAC_keymap[MK_RIGHTBRACKET] = SDLK_RIGHTBRACKET;
MAC_keymap[MK_BACKSLASH] = SDLK_BACKSLASH;
MAC_keymap[MK_DELETE] = SDLK_DELETE;
MAC_keymap[MK_END] = SDLK_END;
MAC_keymap[MK_PAGEDOWN] = SDLK_PAGEDOWN;
MAC_keymap[MK_KP7] = SDLK_KP7;
MAC_keymap[MK_KP8] = SDLK_KP8;
MAC_keymap[MK_KP9] = SDLK_KP9;
MAC_keymap[MK_KP_MINUS] = SDLK_KP_MINUS;
MAC_keymap[MK_CAPSLOCK] = SDLK_CAPSLOCK;
MAC_keymap[MK_a] = SDLK_a;
MAC_keymap[MK_s] = SDLK_s;
MAC_keymap[MK_d] = SDLK_d;
MAC_keymap[MK_f] = SDLK_f;
MAC_keymap[MK_g] = SDLK_g;
MAC_keymap[MK_h] = SDLK_h;
MAC_keymap[MK_j] = SDLK_j;
MAC_keymap[MK_k] = SDLK_k;
MAC_keymap[MK_l] = SDLK_l;
MAC_keymap[MK_SEMICOLON] = SDLK_SEMICOLON;
MAC_keymap[MK_QUOTE] = SDLK_QUOTE;
MAC_keymap[MK_RETURN] = SDLK_RETURN;
MAC_keymap[MK_KP4] = SDLK_KP4;
MAC_keymap[MK_KP5] = SDLK_KP5;
MAC_keymap[MK_KP6] = SDLK_KP6;
MAC_keymap[MK_KP_PLUS] = SDLK_KP_PLUS;
MAC_keymap[MK_LSHIFT] = SDLK_LSHIFT;
MAC_keymap[MK_z] = SDLK_z;
MAC_keymap[MK_x] = SDLK_x;
MAC_keymap[MK_c] = SDLK_c;
MAC_keymap[MK_v] = SDLK_v;
MAC_keymap[MK_b] = SDLK_b;
MAC_keymap[MK_n] = SDLK_n;
MAC_keymap[MK_m] = SDLK_m;
MAC_keymap[MK_COMMA] = SDLK_COMMA;
MAC_keymap[MK_PERIOD] = SDLK_PERIOD;
MAC_keymap[MK_SLASH] = SDLK_SLASH;
#if 0 /* These are the same as the left versions - use left by default */
MAC_keymap[MK_RSHIFT] = SDLK_RSHIFT;
#endif
MAC_keymap[MK_UP] = SDLK_UP;
MAC_keymap[MK_KP1] = SDLK_KP1;
MAC_keymap[MK_KP2] = SDLK_KP2;
MAC_keymap[MK_KP3] = SDLK_KP3;
MAC_keymap[MK_KP_ENTER] = SDLK_KP_ENTER;
MAC_keymap[MK_LCTRL] = SDLK_LCTRL;
MAC_keymap[MK_LALT] = SDLK_LALT;
MAC_keymap[MK_LMETA] = SDLK_LMETA;
MAC_keymap[MK_SPACE] = SDLK_SPACE;
#if 0 /* These are the same as the left versions - use left by default */
MAC_keymap[MK_RMETA] = SDLK_RMETA;
MAC_keymap[MK_RALT] = SDLK_RALT;
MAC_keymap[MK_RCTRL] = SDLK_RCTRL;
#endif
MAC_keymap[MK_LEFT] = SDLK_LEFT;
MAC_keymap[MK_DOWN] = SDLK_DOWN;
MAC_keymap[MK_RIGHT] = SDLK_RIGHT;
MAC_keymap[MK_KP0] = SDLK_KP0;
MAC_keymap[MK_KP_PERIOD] = SDLK_KP_PERIOD;
#if defined(__APPLE__) && defined(__MACH__)
/* Wierd, these keys are on my iBook under Mac OS X
Note that the left arrow keysym is the same as left ctrl!?
*/
MAC_keymap[MK_IBOOK_ENTER] = SDLK_KP_ENTER;
MAC_keymap[MK_IBOOK_RIGHT] = SDLK_RIGHT;
MAC_keymap[MK_IBOOK_DOWN] = SDLK_DOWN;
MAC_keymap[MK_IBOOK_UP] = SDLK_UP;
MAC_keymap[MK_IBOOK_LEFT] = SDLK_LEFT;
#endif /* Mac OS X */
/* Up there we setup a static scancode->keysym map. However, it will not
* work very well on international keyboard. Hence we now query MacOS
* for its own keymap to adjust our own mapping table. However, this is
* bascially only useful for ascii char keys. This is also the reason
* why we keep the static table, too.
*/
/* Get a pointer to the systems cached KCHR */
KCHRPtr = (void *) GetScriptManagerVariable(smKCHRCache);
if (KCHRPtr) {
/* Loop over all 127 possible scan codes */
for (i = 0; i < 0x7F; i++) {
/* We pretend a clean start to begin with (i.e. no dead keys active */
state = 0;
/* Now translate the key code to a key value */
value = KeyTranslate(KCHRPtr, i, &state) & 0xff;
/* If the state become 0, it was a dead key. We need to translate again,
passing in the new state, to get the actual key value */
if (state != 0)
value = KeyTranslate(KCHRPtr, i, &state) & 0xff;
/* Now we should have an ascii value, or 0. Try to figure out to which SDL symbol it maps */
if (value >= 128) /* Some non-ASCII char, map it to SDLK_WORLD_* */
MAC_keymap[i] = world++;
else if (value >= 32) /* non-control ASCII char */
MAC_keymap[i] = value;
}
}
/* The keypad codes are re-setup here, because the loop above cannot
* distinguish between a key on the keypad and a regular key. We maybe
* could get around this problem in another fashion: NSEvent's flags
* include a "NSNumericPadKeyMask" bit; we could check that and modify
* the symbol we return on the fly. However, this flag seems to exhibit
* some weird behaviour related to the num lock key
*/
MAC_keymap[MK_KP0] = SDLK_KP0;
MAC_keymap[MK_KP1] = SDLK_KP1;
MAC_keymap[MK_KP2] = SDLK_KP2;
MAC_keymap[MK_KP3] = SDLK_KP3;
MAC_keymap[MK_KP4] = SDLK_KP4;
MAC_keymap[MK_KP5] = SDLK_KP5;
MAC_keymap[MK_KP6] = SDLK_KP6;
MAC_keymap[MK_KP7] = SDLK_KP7;
MAC_keymap[MK_KP8] = SDLK_KP8;
MAC_keymap[MK_KP9] = SDLK_KP9;
MAC_keymap[MK_KP_MINUS] = SDLK_KP_MINUS;
MAC_keymap[MK_KP_PLUS] = SDLK_KP_PLUS;
MAC_keymap[MK_KP_PERIOD] = SDLK_KP_PERIOD;
MAC_keymap[MK_KP_EQUALS] = SDLK_KP_EQUALS;
MAC_keymap[MK_KP_DIVIDE] = SDLK_KP_DIVIDE;
MAC_keymap[MK_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
MAC_keymap[MK_KP_ENTER] = SDLK_KP_ENTER;
}
static SDL_keysym *
TranslateKey(int scancode, int modifiers, SDL_keysym * keysym, int pressed)
{
/* Set the keysym information */
keysym->scancode = scancode;
keysym->sym = MAC_keymap[keysym->scancode];
keysym->mod = KMOD_NONE;
keysym->unicode = 0;
if (pressed && SDL_TranslateUNICODE) {
static unsigned long state = 0;
static Ptr keymap = nil;
Ptr new_keymap;
/* Get the current keyboard map resource */
new_keymap = (Ptr) GetScriptManagerVariable(smKCHRCache);
if (new_keymap != keymap) {
keymap = new_keymap;
state = 0;
}
keysym->unicode = KeyTranslate(keymap,
keysym->scancode | modifiers,
&state) & 0xFFFF;
}
return (keysym);
}
void
Mac_InitEvents(_THIS)
{
/* Create apple menu bar */
apple_menu = GetMenu(mApple);
if (apple_menu != nil) {
AppendResMenu(apple_menu, 'DRVR');
InsertMenu(apple_menu, 0);
}
DrawMenuBar();
/* Get rid of spurious events at startup */
FlushEvents(everyEvent, 0);
/* Allow every event but keyrepeat */
SetEventMask(everyEvent & ~autoKeyMask);
}
void
Mac_QuitEvents(_THIS)
{
ClearMenuBar();
if (apple_menu != nil) {
ReleaseResource((char **) apple_menu);
}
/* Clean up pending events */
FlushEvents(everyEvent, 0);
}
static void
Mac_DoAppleMenu(_THIS, long choice)
{
#if !TARGET_API_MAC_CARBON /* No Apple menu in OS X */
short menu, item;
item = (choice & 0xFFFF);
choice >>= 16;
menu = (choice & 0xFFFF);
switch (menu) {
case mApple:
{
switch (item) {
case iAbout:
{
/* Run the about box */ ;
}
break;
default:
{
Str255 name;
GetMenuItemText(apple_menu, item, name);
OpenDeskAcc(name);
}
break;
}
}
break;
default:
{
/* Ignore other menus */ ;
}
}
#endif /* !TARGET_API_MAC_CARBON */
}
#if !TARGET_API_MAC_CARBON
/* Since we don't initialize QuickDraw, we need to get a pointer to qd */
QDGlobals *theQD = NULL;
#endif
/* Exported to the macmain code */
void
SDL_InitQuickDraw(struct QDGlobals *the_qd)
{
#if !TARGET_API_MAC_CARBON
theQD = the_qd;
#endif
}
/* vi: set ts=4 sw=4 expandtab: */
/*
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"
#include "../macrom/SDL_romvideo.h"
/* Functions exported by SDL_macevents.c for the video subsystem
*/
extern void Mac_InitEvents(_THIS);
extern void Mac_QuitEvents(_THIS);
extern void Mac_InitOSKeymap(_THIS);
extern void Mac_PumpEvents(_THIS);
/* vi: set ts=4 sw=4 expandtab: */
/*
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"
/* AGL implementation of SDL OpenGL support */
#include "SDL_lowvideo.h"
#include "SDL_macgl_c.h"
#include "SDL_loadso.h"
/* krat: adding OpenGL support */
int
Mac_GL_Init(_THIS)
{
#if SDL_VIDEO_OPENGL
AGLPixelFormat format;
int i = 0;
GLint attributes[26]; /* 26 is max possible in this setup */
GLboolean noerr;
/* load the gl driver from a default path */
if (!this->gl_config.driver_loaded) {
/* no driver has been loaded, use default (ourselves) */
if (Mac_GL_LoadLibrary(this, NULL) < 0) {
return (-1);
}
}
attributes[i++] = AGL_RGBA;
if (this->gl_config.red_size != 0 &&
this->gl_config.blue_size != 0 && this->gl_config.green_size != 0) {
attributes[i++] = AGL_RED_SIZE;
attributes[i++] = this->gl_config.red_size;
attributes[i++] = AGL_GREEN_SIZE;
attributes[i++] = this->gl_config.green_size;
attributes[i++] = AGL_BLUE_SIZE;
attributes[i++] = this->gl_config.blue_size;
attributes[i++] = AGL_ALPHA_SIZE;
attributes[i++] = this->gl_config.alpha_size;
}
if (this->gl_config.double_buffer) {
attributes[i++] = AGL_DOUBLEBUFFER;
}
if (this->gl_config.depth_size != 0) {
attributes[i++] = AGL_DEPTH_SIZE;
attributes[i++] = this->gl_config.depth_size;
}
if (this->gl_config.stencil_size != 0) {
attributes[i++] = AGL_STENCIL_SIZE;
attributes[i++] = this->gl_config.stencil_size;
}
if (this->gl_config.accum_red_size != 0 &&
this->gl_config.accum_blue_size != 0 &&
this->gl_config.accum_green_size != 0) {
attributes[i++] = AGL_ACCUM_RED_SIZE;
attributes[i++] = this->gl_config.accum_red_size;
attributes[i++] = AGL_ACCUM_GREEN_SIZE;
attributes[i++] = this->gl_config.accum_green_size;
attributes[i++] = AGL_ACCUM_BLUE_SIZE;
attributes[i++] = this->gl_config.accum_blue_size;
attributes[i++] = AGL_ACCUM_ALPHA_SIZE;
attributes[i++] = this->gl_config.accum_alpha_size;
}
if (this->gl_config.stereo) {
attributes[i++] = AGL_STEREO;
}
#if defined(AGL_SAMPLE_BUFFERS_ARB) && defined(AGL_SAMPLES_ARB)
if (this->gl_config.multisamplebuffers != 0) {
attributes[i++] = AGL_SAMPLE_BUFFERS_ARB;
attributes[i++] = this->gl_config.multisamplebuffers;
}
if (this->gl_config.multisamplesamples != 0) {
attributes[i++] = AGL_SAMPLES_ARB;
attributes[i++] = this->gl_config.multisamplesamples;
}
#endif
if (this->gl_config.accelerated > 0) {
attributes[i++] = AGL_ACCELERATED;
attributes[i++] = AGL_NO_RECOVERY;
}
attributes[i++] = AGL_ALL_RENDERERS;
attributes[i] = AGL_NONE;
format = aglChoosePixelFormat(NULL, 0, attributes);
if (format == NULL) {
SDL_SetError("Couldn't match OpenGL desired format");
return (-1);
}
glContext = aglCreateContext(format, NULL);
if (glContext == NULL) {
SDL_SetError("Couldn't create OpenGL context");
return (-1);
}
aglDestroyPixelFormat(format);
#if TARGET_API_MAC_CARBON
noerr = aglSetDrawable(glContext, GetWindowPort(SDL_Window));
#else
noerr = aglSetDrawable(glContext, (AGLDrawable) SDL_Window);
#endif
if (!noerr) {
SDL_SetError("Unable to bind GL context to window");
return (-1);
}
return (0);
#else
SDL_SetError("OpenGL support not configured");
return (-1);
#endif
}
void
Mac_GL_Quit(_THIS)
{
#if SDL_VIDEO_OPENGL
if (glContext != NULL) {
aglSetCurrentContext(NULL);
aglSetDrawable(glContext, NULL);
aglDestroyContext(glContext);
glContext = NULL;
}
#endif
}
#if SDL_VIDEO_OPENGL
/* Make the current context active */
int
Mac_GL_MakeCurrent(_THIS)
{
int retval;
retval = 0;
if (!aglSetCurrentContext(glContext)) {
SDL_SetError("Unable to make GL context current");
retval = -1;
}
return (retval);
}
void
Mac_GL_SwapBuffers(_THIS)
{
aglSwapBuffers(glContext);
}
int
Mac_GL_LoadLibrary(_THIS, const char *location)
{
if (location == NULL)
#if __MACH__
location = "/System/Library/Frameworks/OpenGL.framework/OpenGL";
#else
location = "OpenGLLibrary";
#endif
this->hidden->libraryHandle = SDL_LoadObject(location);
this->gl_config.driver_loaded = 1;
return (this->hidden->libraryHandle != NULL) ? 0 : -1;
}
void
Mac_GL_UnloadLibrary(_THIS)
{
SDL_UnloadObject(this->hidden->libraryHandle);
this->hidden->libraryHandle = NULL;
this->gl_config.driver_loaded = 0;
}
void *
Mac_GL_GetProcAddress(_THIS, const char *proc)
{
return SDL_LoadFunction(this->hidden->libraryHandle, proc);
}
#endif /* SDL_VIDEO_OPENGL */
/* vi: set ts=4 sw=4 expandtab: */
/*
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
*/
/* AGL implementation of SDL OpenGL support */
#include "SDL_config.h"
#if SDL_VIDEO_OPENGL
#include "SDL_opengl.h"
#if __MACOSX__
#include <AGL/agl.h> /* AGL.framework */
#else
#include <agl.h>
#endif
#endif /* SDL_VIDEO_OPENGL */
/* OpenGL functions */
extern int Mac_GL_Init(_THIS);
extern void Mac_GL_Quit(_THIS);
#if SDL_VIDEO_OPENGL
extern int Mac_GL_MakeCurrent(_THIS);
extern int Mac_GL_GetAttribute(_THIS, SDL_GLattr attrib, int *value);
extern void Mac_GL_SwapBuffers(_THIS);
extern int Mac_GL_LoadLibrary(_THIS, const char *location);
extern void Mac_GL_UnloadLibrary(_THIS);
extern void *Mac_GL_GetProcAddress(_THIS, const char *proc);
#endif
/* vi: set ts=4 sw=4 expandtab: */
/*
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
*/
/* These are the Macintosh key scancode constants -- from Inside Macintosh */
#define MK_ESCAPE 0x35
#define MK_F1 0x7A
#define MK_F2 0x78
#define MK_F3 0x63
#define MK_F4 0x76
#define MK_F5 0x60
#define MK_F6 0x61
#define MK_F7 0x62
#define MK_F8 0x64
#define MK_F9 0x65
#define MK_F10 0x6D
#define MK_F11 0x67
#define MK_F12 0x6F
#define MK_PRINT 0x69
#define MK_SCROLLOCK 0x6B
#define MK_PAUSE 0x71
#define MK_POWER 0x7F
#define MK_BACKQUOTE 0x32
#define MK_1 0x12
#define MK_2 0x13
#define MK_3 0x14
#define MK_4 0x15
#define MK_5 0x17
#define MK_6 0x16
#define MK_7 0x1A
#define MK_8 0x1C
#define MK_9 0x19
#define MK_0 0x1D
#define MK_MINUS 0x1B
#define MK_EQUALS 0x18
#define MK_BACKSPACE 0x33
#define MK_INSERT 0x72
#define MK_HOME 0x73
#define MK_PAGEUP 0x74
#define MK_NUMLOCK 0x47
#define MK_KP_EQUALS 0x51
#define MK_KP_DIVIDE 0x4B
#define MK_KP_MULTIPLY 0x43
#define MK_TAB 0x30
#define MK_q 0x0C
#define MK_w 0x0D
#define MK_e 0x0E
#define MK_r 0x0F
#define MK_t 0x11
#define MK_y 0x10
#define MK_u 0x20
#define MK_i 0x22
#define MK_o 0x1F
#define MK_p 0x23
#define MK_LEFTBRACKET 0x21
#define MK_RIGHTBRACKET 0x1E
#define MK_BACKSLASH 0x2A
#define MK_DELETE 0x75
#define MK_END 0x77
#define MK_PAGEDOWN 0x79
#define MK_KP7 0x59
#define MK_KP8 0x5B
#define MK_KP9 0x5C
#define MK_KP_MINUS 0x4E
#define MK_CAPSLOCK 0x39
#define MK_a 0x00
#define MK_s 0x01
#define MK_d 0x02
#define MK_f 0x03
#define MK_g 0x05
#define MK_h 0x04
#define MK_j 0x26
#define MK_k 0x28
#define MK_l 0x25
#define MK_SEMICOLON 0x29
#define MK_QUOTE 0x27
#define MK_RETURN 0x24
#define MK_KP4 0x56
#define MK_KP5 0x57
#define MK_KP6 0x58
#define MK_KP_PLUS 0x45
#define MK_LSHIFT 0x38
#define MK_z 0x06
#define MK_x 0x07
#define MK_c 0x08
#define MK_v 0x09
#define MK_b 0x0B
#define MK_n 0x2D
#define MK_m 0x2E
#define MK_COMMA 0x2B
#define MK_PERIOD 0x2F
#define MK_SLASH 0x2C
#if 0 /* These are the same as the left versions - use left by default */
#define MK_RSHIFT 0x38
#endif
#define MK_UP 0x7E
#define MK_KP1 0x53
#define MK_KP2 0x54
#define MK_KP3 0x55
#define MK_KP_ENTER 0x4C
#define MK_LCTRL 0x3B
#define MK_LALT 0x3A
#define MK_LMETA 0x37
#define MK_SPACE 0x31
#if 0 /* These are the same as the left versions - use left by default */
#define MK_RMETA 0x37
#define MK_RALT 0x3A
#define MK_RCTRL 0x3B
#endif
#define MK_LEFT 0x7B
#define MK_DOWN 0x7D
#define MK_RIGHT 0x7C
#define MK_KP0 0x52
#define MK_KP_PERIOD 0x41
/* Wierd, these keys are on my iBook under Mac OS X */
#define MK_IBOOK_ENTER 0x34
#define MK_IBOOK_LEFT 0x3B
#define MK_IBOOK_RIGHT 0x3C
#define MK_IBOOK_DOWN 0x3D
#define MK_IBOOK_UP 0x3E
/* vi: set ts=4 sw=4 expandtab: */
/*
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"
#if defined(__APPLE__) && defined(__MACH__)
#include <Carbon/Carbon.h>
#elif TARGET_API_MAC_CARBON && (UNIVERSAL_INTERFACES_VERSION > 0x0335)
#include <Carbon.h>
#else
#include <Quickdraw.h>
#endif
/* Routines that are not supported by the Carbon API... */
#if !TARGET_API_MAC_CARBON
#include <CursorDevices.h>
#endif
#include "SDL_mouse.h"
#include "SDL_macmouse_c.h"
/* The implementation dependent data for the window manager cursor */
struct WMcursor
{
Cursor curs;
};
void
Mac_FreeWMCursor(_THIS, WMcursor * cursor)
{
SDL_free(cursor);
}
WMcursor *
Mac_CreateWMCursor(_THIS,
Uint8 * data, Uint8 * mask, int w, int h, int hot_x,
int hot_y)
{
WMcursor *cursor;
int row, bytes;
/* Allocate the cursor memory */
cursor = (WMcursor *) SDL_malloc(sizeof(WMcursor));
if (cursor == NULL) {
SDL_OutOfMemory();
return (NULL);
}
SDL_memset(cursor, 0, sizeof(*cursor));
if (w > 16)
w = 16;
if (h > 16)
h = 16;
bytes = (w + 7) / 8;
for (row = 0; row < h; ++row) {
SDL_memcpy(&cursor->curs.data[row], data, bytes);
data += bytes;
}
for (row = 0; row < h; ++row) {
SDL_memcpy(&cursor->curs.mask[row], mask, bytes);
mask += bytes;
}
cursor->curs.hotSpot.h = hot_x;
cursor->curs.hotSpot.v = hot_y;
/* That was easy. :) */
return (cursor);
}
int Mac_cursor_showing = 1;
int
Mac_ShowWMCursor(_THIS, WMcursor * cursor)
{
if (cursor == NULL) {
if (Mac_cursor_showing) {
HideCursor();
Mac_cursor_showing = 0;
}
} else {
SetCursor(&cursor->curs);
if (!Mac_cursor_showing) {
ShowCursor();
Mac_cursor_showing = 1;
}
}
return (1);
}
void
Mac_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
{
#if !TARGET_API_MAC_CARBON
CursorDevice *cursordevice;
cursordevice = nil;
CursorDeviceNextDevice(&cursordevice);
if (cursordevice != nil) {
WindowPtr saveport;
Point where;
GetPort(&saveport);
SetPort(SDL_Window);
where.h = x;
where.v = y;
LocalToGlobal(&where);
SetPort(saveport);
CursorDeviceMoveTo(cursordevice, where.h, where.v);
}
#endif /* !TARGET_API_MAC_CARBON */
}
/* vi: set ts=4 sw=4 expandtab: */
/*
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"
#include "../macrom/SDL_romvideo.h"
/* Functions to be exported */
extern void Mac_FreeWMCursor(_THIS, WMcursor * cursor);
extern WMcursor *Mac_CreateWMCursor(_THIS,
Uint8 * data, Uint8 * mask, int w, int h,
int hot_x, int hot_y);
extern int Mac_ShowWMCursor(_THIS, WMcursor * cursor);
extern void Mac_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
/* Data to be exported */
extern int Mac_cursor_showing;
/* vi: set ts=4 sw=4 expandtab: */
/*
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"
#if defined(__APPLE__) && defined(__MACH__)
#include <Carbon/Carbon.h>
#elif TARGET_API_MAC_CARBON && (UNIVERSAL_INTERFACES_VERSION > 0x0335)
#include <Carbon.h>
#else
#include <Windows.h>
#include <Strings.h>
#endif
#include "SDL_stdinc.h"
#include "SDL_macwm_c.h"
void
Mac_SetCaption(_THIS, const char *title, const char *icon)
{
/* Don't convert C to P string in place, because it may be read-only */
Str255 ptitle; /* MJS */
ptitle[0] = strlen(title);
SDL_memcpy(ptitle + 1, title, ptitle[0]); /* MJS */
if (SDL_Window)
SetWTitle(SDL_Window, ptitle); /* MJS */
}
/* vi: set ts=4 sw=4 expandtab: */
/*
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"
#include "../macrom/SDL_romvideo.h"
/* Functions to be exported */
extern void Mac_SetCaption(_THIS, const char *title, const char *icon);
/* vi: set ts=4 sw=4 expandtab: */
/*
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_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_INTERNALOPENGL) {
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_INTERNALOPENGL))
DSpContext_SetVBLProc(dsp_context, DSp_VBLProc, NULL);
#endif
if (bpp == 8)
current->flags |= SDL_HWPALETTE;
if (flags & SDL_INTERNALOPENGL) {
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_INTERNALOPENGL;
}
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);
/* 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
/* vi: set ts=4 sw=4 expandtab: */
/*
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"
#ifndef _SDL_dspvideo_h
#define _SDL_dspvideo_h
#if TARGET_API_MAC_OSX
# include <DrawSprocket/DrawSprocket.h> /* Drawsprocket.framework */
#else
#include <DrawSprocket.h>
#endif
#include "../maccommon/SDL_lowvideo.h"
/* DrawSprocket specific information */
struct DSpInfo
{
DSpContextReference dsp_context;
CGrafPtr dsp_back_buffer;
int dsp_old_depth;
/* Flags for hw acceleration */
int dsp_vram_available;
int dsp_agp_available;
};
/* Old variable names */
#define dsp_context (this->hidden->dspinfo->dsp_context)
#define dsp_back_buffer (this->hidden->dspinfo->dsp_back_buffer)
#define dsp_old_depth (this->hidden->dspinfo->dsp_old_depth)
#define dsp_vram_available (this->hidden->dspinfo->dsp_vram_available)
#define dsp_agp_available (this->hidden->dspinfo->dsp_agp_available)
#endif /* _SDL_dspvideo_h */
/* vi: set ts=4 sw=4 expandtab: */
/*
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"
#if defined(__APPLE__) && defined(__MACH__)
#include <Carbon/Carbon.h>
#if USE_QUICKTIME
#include <QuickTime/Movies.h>
#endif
#elif TARGET_API_MAC_CARBON && (UNIVERSAL_INTERFACES_VERSION > 0x0335)
#include <Carbon.h>
/* The fullscreen code requires the QuickTime framework, and the window
is still at the back on Mac OS X, which is where this code is needed.
*/
#if USE_QUICKTIME
#include <Movies.h>
#endif
#else
#include <Quickdraw.h>
#include <LowMem.h>
#include <Gestalt.h>
#include <Devices.h>
#include <DiskInit.h>
#include <QDOffscreen.h>
#endif
#include "SDL_video.h"
#include "SDL_syswm.h"
#include "../SDL_sysvideo.h"
#include "SDL_romvideo.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 ROM_VideoInit(_THIS, SDL_PixelFormat * vformat);
static SDL_Rect **ROM_ListModes(_THIS, SDL_PixelFormat * format,
Uint32 flags);
static SDL_Surface *ROM_SetVideoMode(_THIS, SDL_Surface * current, int width,
int height, int bpp, Uint32 flags);
static int ROM_SetColors(_THIS, int firstcolor, int ncolors,
SDL_Color * colors);
static void ROM_VideoQuit(_THIS);
/* Hardware surface functions */
static int ROM_AllocHWSurface(_THIS, SDL_Surface * surface);
static int ROM_LockHWSurface(_THIS, SDL_Surface * surface);
static void ROM_UnlockHWSurface(_THIS, SDL_Surface * surface);
static void ROM_FreeHWSurface(_THIS, SDL_Surface * surface);
#if !TARGET_API_MAC_CARBON /* This seems not to be available? -sts Aug 2000 */
/* Saved state for the menu bar */
static RgnHandle gSaveGrayRgn = nil;
static short gSaveMenuBar = 0;
static Boolean gSaveCSVis = true;
#if powerc
/* Mixed mode glue to activate the 68K emulator and twiddle a register */
#define ONEWORDSTUB(p1) \
{ 0x41FA, 0x0010, 0x209F, (p1), 0x41FA, \
0x0008, 0x2F10, 0x4E75, 0x0000, 0x0000, 0x0000 }
#define TWOWORDSTUB(p1,p2) \
{ 0x41FA, 0x0012, 0x209F, (p1), (p2), 0x41FA, \
0x0008, 0x2F10, 0x4E75, 0x0000, 0x0000, 0x0000 }
#define THREEWORDSTUB(p1,p2,p3) \
{ 0x41FA, 0x0014, 0x209F, (p1), (p2), (p3), 0x41FA, \
0x0008, 0x2F10, 0x4E75, 0x0000, 0x0000, 0x0000 }
/* ControlStrip inline glue for PowerPC */
static pascal Boolean
SBIsControlStripVisible(void)
{
static short procData[] = TWOWORDSTUB(0x7000, 0xAAF2);
ProcInfoType procInfo = kD0DispatchedPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean)))
| DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kFourByteCode);
return ((Boolean)
CallUniversalProc((UniversalProcPtr) procData, procInfo, 0x00));
}
static pascal void
SBShowHideControlStrip(Boolean showIt)
{
static short procData[] = THREEWORDSTUB(0x303C, 0x0101, 0xAAF2);
ProcInfoType procInfo = kD0DispatchedPascalStackBased
| DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kFourByteCode)
| DISPATCHED_STACK_ROUTINE_PARAMETER(1,
SIZE_CODE(sizeof(Boolean)));
CallUniversalProc((UniversalProcPtr) procData, procInfo, 0x01, showIt);
}
#endif /* powerc */
#endif /* !TARGET_API_MAC_CARBON */
/* Macintosh toolbox driver bootstrap functions */
static int
ROM_Available(void)
{
return (1);
}
static void
ROM_DeleteDevice(SDL_VideoDevice * device)
{
SDL_free(device->hidden);
SDL_free(device);
}
static SDL_VideoDevice *
ROM_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 == NULL) || (device->hidden == NULL)) {
SDL_OutOfMemory();
if (device) {
SDL_free(device);
}
return (0);
}
SDL_memset(device->hidden, 0, (sizeof *device->hidden));
/* Set the function pointers */
device->VideoInit = ROM_VideoInit;
device->ListModes = ROM_ListModes;
device->SetVideoMode = ROM_SetVideoMode;
device->SetColors = ROM_SetColors;
device->UpdateRects = NULL;
device->VideoQuit = ROM_VideoQuit;
device->AllocHWSurface = ROM_AllocHWSurface;
device->CheckHWBlit = NULL;
device->FillHWRect = NULL;
device->SetHWColorKey = NULL;
device->SetHWAlpha = NULL;
device->LockHWSurface = ROM_LockHWSurface;
device->UnlockHWSurface = ROM_UnlockHWSurface;
device->FlipHWSurface = NULL;
device->FreeHWSurface = ROM_FreeHWSurface;
#if SDL_VIDEO_OPENGL
device->GL_MakeCurrent = Mac_GL_MakeCurrent;
device->GL_SwapBuffers = Mac_GL_SwapBuffers;
device->GL_LoadLibrary = Mac_GL_LoadLibrary;
device->GL_GetProcAddress = Mac_GL_GetProcAddress;
#endif // Have OpenGL
device->SetCaption = Mac_SetCaption;
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->free = ROM_DeleteDevice;
return device;
}
VideoBootStrap TOOLBOX_bootstrap = {
"toolbox", "MacOS ROM Toolbox",
ROM_Available, ROM_CreateDevice
};
static int
ROM_VideoInit(_THIS, SDL_PixelFormat * vformat)
{
long info;
/* Check out some things about the system */
Gestalt(gestaltQuickdrawVersion, &info);
if (info == gestaltOriginalQD) {
SDL_SetError("Color Quickdraw not available");
return (-1);
}
/* Start ROMintosh events */
Mac_InitEvents(this);
/* Get a handle to the main monitor */
SDL_Display = GetMainDevice();
/* Determine the current screen size */
this->info.current_w = (**SDL_Display).gdRect.right;
this->info.current_h = (**SDL_Display).gdRect.bottom;
/* Determine pixel format */
vformat->BitsPerPixel = (**(**SDL_Display).gdPMap).pixelSize;
switch (vformat->BitsPerPixel) {
case 16: /* 5-5-5 RGB */
vformat->Rmask = 0x00007c00;
vformat->Gmask = 0x000003e0;
vformat->Bmask = 0x0000001f;
break;
default:
break;
}
/* 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);
/* Get a list of available fullscreen modes */
SDL_modelist = (SDL_Rect **) SDL_malloc((1 + 1) * sizeof(SDL_Rect *));
if (SDL_modelist) {
SDL_modelist[0] = (SDL_Rect *) SDL_malloc(sizeof(SDL_Rect));
if (SDL_modelist[0]) {
SDL_modelist[0]->x = 0;
SDL_modelist[0]->y = 0;
SDL_modelist[0]->w = (**SDL_Display).gdRect.right;
SDL_modelist[0]->h = (**SDL_Display).gdRect.bottom;
}
SDL_modelist[1] = NULL;
}
/* Fill in some window manager capabilities */
this->info.wm_available = 1;
/* We're done! */
return (0);
}
static SDL_Rect **
ROM_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags)
{
if (this->screen->format->BitsPerPixel == format->BitsPerPixel) {
if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
return (SDL_modelist);
} else {
return ((SDL_Rect **) - 1);
}
} else {
return ((SDL_Rect **) 0);
}
}
static void
ROM_HideMenuBar(_THIS)
{
#if !TARGET_API_MAC_CARBON /* This seems not to be available? -sts Aug 2000 */
RgnHandle drawRgn = nil;
RgnHandle tempRgn = nil;
RgnHandle grayRgn = nil;
WindowPtr window = nil;
GDHandle gd = nil;
GrafPtr savePort;
long response;
short height;
EventRecord theEvent;
height = GetMBarHeight();
if (height > 0) {
tempRgn = NewRgn();
drawRgn = NewRgn();
gSaveGrayRgn = NewRgn();
if (!tempRgn || !drawRgn || !gSaveGrayRgn) {
goto CLEANUP;
}
grayRgn = GetGrayRgn(); /* No need to check for this */
GetPort(&savePort);
/* Hide the control strip if it's present, and record its
previous position into the dirty region for redrawing.
This isn't necessary, but may help catch stray bits. */
CopyRgn(grayRgn, tempRgn);
if (!Gestalt(gestaltControlStripAttr, &response) &&
(response & (1L << gestaltControlStripExists))) {
gSaveCSVis = SBIsControlStripVisible();
if (gSaveCSVis)
SBShowHideControlStrip(false);
}
DiffRgn(grayRgn, tempRgn, drawRgn);
/* Save the gray region once the control strip is hidden */
CopyRgn(grayRgn, gSaveGrayRgn);
/* Change the menu height in lowmem */
gSaveMenuBar = height;
LMSetMBarHeight(0);
/* Walk the monitor rectangles, and combine any pieces that
aren't in GrayRgn: menubar, round corners, fake floaters. */
for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) {
if (!TestDeviceAttribute(gd, screenDevice))
continue;
if (!TestDeviceAttribute(gd, screenActive))
continue;
RectRgn(tempRgn, &(*gd)->gdRect); /* Get the whole screen */
DiffRgn(tempRgn, grayRgn, tempRgn); /* Subtract out GrayRgn */
UnionRgn(tempRgn, drawRgn, drawRgn); /* Combine all the bits */
}
/* Add the bits into the GrayRgn */
UnionRgn(drawRgn, grayRgn, grayRgn);
/* Modify the vis regions of exposed windows */
window = (FrontWindow())? FrontWindow() : (WindowPtr) - 1L;
PaintBehind(window, drawRgn);
CalcVisBehind(window, drawRgn);
SetPort(savePort);
/* Yield time so that floaters can catch up */
EventAvail(0, &theEvent);
EventAvail(0, &theEvent);
EventAvail(0, &theEvent);
EventAvail(0, &theEvent);
}
CLEANUP:
if (tempRgn)
DisposeRgn(tempRgn);
if (drawRgn)
DisposeRgn(drawRgn);
#endif /* !TARGET_API_MAC_CARBON */
}
static void
ROM_ShowMenuBar(_THIS)
{
#if !TARGET_API_MAC_CARBON /* This seems not to be available? -sts Aug 2000 */
RgnHandle drawRgn = nil;
RgnHandle menuRgn = nil;
RgnHandle tempRgn = nil;
RgnHandle grayRgn = nil;
WindowPtr window = nil;
GrafPtr wMgrPort;
GrafPtr savePort;
Rect menuRect;
long response;
short height;
EventRecord theEvent;
RGBColor saveRGB;
RGBColor blackRGB = { 0, 0, 0 };
height = GetMBarHeight();
if ((height <= 0) && (gSaveMenuBar > 0)) {
drawRgn = NewRgn();
menuRgn = NewRgn();
tempRgn = NewRgn();
if (!tempRgn || !drawRgn || !gSaveGrayRgn) {
goto CLEANUP;
}
grayRgn = GetGrayRgn(); /* No need to check for this */
GetPort(&savePort);
GetWMgrPort(&wMgrPort);
/* Set the height properly */
LMSetMBarHeight(gSaveMenuBar);
/* Restore the old GrayRgn: rounded corners, etc, but not
the menubar -- subtract that out first! */
if (gSaveGrayRgn) {
menuRect = (*GetMainDevice())->gdRect;
menuRect.bottom = menuRect.top + gSaveMenuBar;
RectRgn(menuRgn, &menuRect);
DiffRgn(grayRgn, gSaveGrayRgn, drawRgn); /* What do we inval? */
DiffRgn(drawRgn, menuRgn, drawRgn); /* Clip out the menu */
/* Now redraw the corners and other bits black */
SetPort(wMgrPort);
GetClip(tempRgn);
SetClip(drawRgn);
GetForeColor(&saveRGB);
RGBForeColor(&blackRGB);
PaintRgn(drawRgn);
RGBForeColor(&saveRGB);
SetClip(tempRgn);
SetPort(savePort);
UnionRgn(drawRgn, menuRgn, drawRgn); /* Put back the menu */
/* Now actually restore the GrayRgn */
CopyRgn(gSaveGrayRgn, grayRgn);
DisposeRgn(gSaveGrayRgn);
gSaveGrayRgn = nil;
}
/* Modify the vis regions of exposed windows and draw menubar */
window = (FrontWindow())? FrontWindow() : (WindowPtr) - 1L;
PaintBehind(window, drawRgn);
CalcVisBehind(window, drawRgn);
DrawMenuBar();
SetPort(savePort);
gSaveMenuBar = 0;
/* Now show the control strip if it's present */
if (!Gestalt(gestaltControlStripAttr, &response) &&
(response & (1L << gestaltControlStripExists))) {
if (gSaveCSVis && !SBIsControlStripVisible())
SBShowHideControlStrip(true);
gSaveCSVis = true;
}
/* Yield time so that floaters can catch up */
EventAvail(0, &theEvent);
EventAvail(0, &theEvent);
EventAvail(0, &theEvent);
EventAvail(0, &theEvent);
}
CLEANUP:
if (drawRgn)
DisposeRgn(drawRgn);
if (menuRgn)
DisposeRgn(menuRgn);
if (tempRgn)
DisposeRgn(tempRgn);
#endif /* !TARGET_API_MAC_CARBON */
}
/* Various screen update functions available */
static void ROM_DirectUpdate(_THIS, int numrects, SDL_Rect * rects);
static void ROM_WindowUpdate(_THIS, int numrects, SDL_Rect * rects);
static void
ROM_UnsetVideoMode(_THIS, SDL_Surface * current)
{
/* Free the current window, if any */
if (SDL_Window != nil) {
GWorldPtr memworld;
/* Handle OpenGL support */
Mac_GL_Quit(this);
memworld = (GWorldPtr) GetWRefCon(SDL_Window);
if (memworld != nil) {
UnlockPixels(GetGWorldPixMap(memworld));
DisposeGWorld(memworld);
}
if ((current->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
#if USE_QUICKTIME
EndFullScreen(fullscreen_ctx, nil);
SDL_Window = nil;
#else
ROM_ShowMenuBar(this);
#endif
}
}
current->pixels = NULL;
current->flags &= ~(SDL_HWSURFACE | SDL_FULLSCREEN);
}
static SDL_Surface *
ROM_SetVideoMode(_THIS, SDL_Surface * current,
int width, int height, int bpp, Uint32 flags)
{
Rect wrect, orect;
#if TARGET_API_MAC_CARBON
Rect tmprect;
#endif
/* Free any previous video mode */
ROM_UnsetVideoMode(this, current);
/* Create the ROM window and SDL video surface */
current->flags = 0; /* Clear flags */
current->w = width;
current->h = height;
SetRect(&wrect, 0, 0, width, height);
if (SDL_Window) {
/* If we recreate the window, don't move it around */
#if TARGET_API_MAC_CARBON
orect = *GetWindowPortBounds(SDL_Window, &tmprect);
#else
orect = SDL_Window->portRect;
#endif
OffsetRect(&wrect, orect.left, orect.top);
} else {
/* Center the window the first time we show it */
OffsetRect(&wrect,
(SDL_modelist[0]->w - width) / 2,
(SDL_modelist[0]->h - height) / 2);
}
#if defined(__MACOSX__) && !USE_QUICKTIME
/* Hum.. fullscreen mode is broken */
flags &= ~SDL_FULLSCREEN;
#endif
if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
/* Create the fullscreen window and use screen bits */
current->flags |= SDL_HWSURFACE | SDL_FULLSCREEN;
if (SDL_Window) {
DisposeWindow(SDL_Window);
}
#if USE_QUICKTIME
BeginFullScreen(&fullscreen_ctx, nil, 0, 0, &SDL_Window, nil, 0);
#else
SDL_Window = NewCWindow(nil, &wrect, "\p", true, plainDBox,
(WindowPtr) - 1, false, 0);
ROM_HideMenuBar(this);
#endif
current->pitch = (**(**SDL_Display).gdPMap).rowBytes & 0x3FFF;
current->pixels = (**(**SDL_Display).gdPMap).baseAddr;
this->UpdateRects = ROM_DirectUpdate;
} else {
GWorldPtr memworld;
PixMapHandle pixmap;
int style;
style = noGrowDocProc;
if (flags & SDL_NOFRAME) {
style = plainDBox;
current->flags |= SDL_NOFRAME;
} else if (flags & SDL_RESIZABLE) {
style = zoomDocProc;
current->flags |= SDL_RESIZABLE;
}
if (SDL_Window && (style == current_style)) {
/* Resize existing window, if necessary */
if (((orect.right - orect.left) != width) ||
((orect.bottom - orect.top) != height)) {
SizeWindow(SDL_Window, width, height, false);
}
} else {
/* Recreate the window in the new style */
if (SDL_Window) {
DisposeWindow(SDL_Window);
}
SDL_Window = NewCWindow(nil, &wrect, "\p", true,
style, (WindowPtr) - 1, true, 0);
/* Set the window title, if any */
{
char *title;
SDL_WM_GetCaption(&title, NULL);
if (title) {
Mac_SetCaption(this, title, NULL);
}
}
}
current_style = style;
SetPalette(SDL_Window, SDL_CPal, false);
ActivatePalette(SDL_Window);
if (NewGWorld(&memworld, 0,
#if TARGET_API_MAC_CARBON
GetWindowPortBounds(SDL_Window, &tmprect),
#else
&SDL_Window->portRect,
#endif
SDL_CTab, nil, 0) != noErr) {
SDL_SetError("NewGWorld() failed");
return (NULL);
}
SetWRefCon(SDL_Window, (long) memworld);
pixmap = GetGWorldPixMap(memworld);
LockPixels(pixmap);
current->pitch = (**pixmap).rowBytes & 0x3FFF;
current->pixels = GetPixBaseAddr(pixmap);
this->UpdateRects = ROM_WindowUpdate;
}
SetPortWindowPort(SDL_Window);
SelectWindow(SDL_Window);
/* Handle OpenGL support */
if (flags & SDL_INTERNALOPENGL) {
if (Mac_GL_Init(this) == 0) {
current->flags |= SDL_INTERNALOPENGL;
} else {
current = NULL;
}
}
if ((flags & SDL_HWPALETTE) && (flags & SDL_FULLSCREEN))
current->flags |= SDL_HWPALETTE;
/* We're live! */
return (current);
}
/* We don't actually allow hardware surfaces other than the main one */
static int
ROM_AllocHWSurface(_THIS, SDL_Surface * surface)
{
return (-1);
}
static void
ROM_FreeHWSurface(_THIS, SDL_Surface * surface)
{
return;
}
static int
ROM_LockHWSurface(_THIS, SDL_Surface * surface)
{
return (0);
}
static void
ROM_UnlockHWSurface(_THIS, SDL_Surface * surface)
{
return;
}
static void
ROM_DirectUpdate(_THIS, int numrects, SDL_Rect * rects)
{
/* The application is already updating the visible video memory */
return;
}
static void
ROM_WindowUpdate(_THIS, int numrects, SDL_Rect * rects)
{
GWorldPtr memworld;
GrafPtr saveport;
CGrafPtr thePort;
const BitMap *memBits;
const BitMap *winBits;
int i;
Rect update;
/* Copy from the offscreen GWorld to the window port */
GetPort(&saveport);
SetPortWindowPort(SDL_Window);
thePort = GetWindowPort(SDL_Window);
memworld = (GWorldPtr) GetWRefCon(SDL_Window);
#if TARGET_API_MAC_CARBON && ACCESSOR_CALLS_ARE_FUNCTIONS
memBits = GetPortBitMapForCopyBits((CGrafPtr) memworld);
#else
memBits = &((GrafPtr) memworld)->portBits;
#endif
#if TARGET_API_MAC_CARBON && ACCESSOR_CALLS_ARE_FUNCTIONS
winBits = GetPortBitMapForCopyBits(thePort);
#else
winBits = &SDL_Window->portBits;
#endif
for (i = 0; i < numrects; ++i) {
update.left = rects[i].x;
update.right = rects[i].x + rects[i].w;
update.top = rects[i].y;
update.bottom = rects[i].y + rects[i].h;
CopyBits(memBits, winBits, &update, &update, srcCopy, nil);
}
#if TARGET_API_MAC_CARBON
if (QDIsPortBuffered(thePort)) {
QDFlushPortBuffer(thePort, NULL);
}
#endif
SetPort(saveport);
}
static int
ROM_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors)
{
CTabHandle cTab;
int i;
/* Get the colortable from the either the display or window */
if ((this->screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
cTab = (**(**SDL_Display).gdPMap).pmTable;
} else {
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;
}
// if ( (this->screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN )
{
GDevice **odisplay;
odisplay = GetGDevice();
SetGDevice(SDL_Display);
SetEntries(0, (**cTab).ctSize, (ColorSpec *) & (**cTab).ctTable);
SetGDevice(odisplay);
}
return (1);
}
void
ROM_VideoQuit(_THIS)
{
int i;
/* Free current video mode */
ROM_UnsetVideoMode(this, this->screen);
if (SDL_Window) {
DisposeWindow(SDL_Window);
SDL_Window = nil;
}
/* 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(GetMainDevice());
/* 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;
}
}
/* vi: set ts=4 sw=4 expandtab: */
/*
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"
#ifndef _SDL_romvideo_h
#define _SDL_romvideo_h
#include "../maccommon/SDL_lowvideo.h"
#endif /* _SDL_romvideo_h */
/* vi: set ts=4 sw=4 expandtab: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment