📄 sdl_dspvideo.c
字号:
if ( (**device_list).gdNextGD == NULL ) {
*device = main_device;
return 0;
}
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 = DSpGetVersion ();
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);
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);
static volatile unsigned int retrace_count = 0; /* -dw- need volatile because it updates asychronously */
#if ! TARGET_API_MAC_OSX
Boolean DSp_VBLProc ( DSpContextReference context, void *ref_con )
{
retrace_count++;
return 1; /* Darrell, is this right? */
}
#endif
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;
}
sprintf(message, fmt, mem);
SDL_SetError(message);
}
/* 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);
SetPort (dialog);
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);
DisposeWindow (dialog);
SetPort (savePort);
SetEventMask(everyEvent - autoKeyMask);
FlushEvents(everyEvent, 0);
return (item - 1);
}
static void DSp_UnsetVideoMode(_THIS, SDL_Surface *current)
{
if ( current->flags & SDL_OPENGL ) {
Mac_GL_Quit (this);
}
if (dsp_context != NULL) {
GWorldPtr front;
DSpContext_GetFrontBuffer (dsp_context, &front);
if (front != dsp_back_buffer)
DisposeGWorld (dsp_back_buffer);
if (current->hwdata)
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)
{
DisplayIDType display_id;
DSpContextAttributes attrib;
Fixed freq;
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;
}
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
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*) 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*) malloc (sizeof (private_hwdata));
if (current ->hwdata == NULL) {
SDL_OutOfMemory ();
return NULL;
}
memset (current->hwdata, 0, sizeof (private_hwdata));
current->hwdata->offscreen = dsp_back_buffer;
current->flags |= SDL_DOUBLEBUF | SDL_HWSURFACE;
this->UpdateRects = DSp_DirectUpdate; /* hardware doesn't do update rects, must be page-flipped */
}
else {
DSpContext_Release (dsp_context);
use_dsp_back_buffer = SDL_TRUE;
goto rebuild;
}
current->pitch = GetPortPixRowBytes(dsp_back_buffer) & 0x3FFF;
current->pixels = GetPixBaseAddr(GetPortPixMap(dsp_back_buffer));
current->w = width;
current->h = height;
#if ! TARGET_API_MAC_OSX
if (use_dsp_back_buffer) {
DSpContext_GetMonitorFrequency (dsp_context, &freq);
DSpContext_SetMaxFrameRate (dsp_context, freq >> 16);
}
if ( (current->flags & SDL_HWSURFACE) || (current->flags & SDL_OPENGL) )
DSpContext_SetVBLProc (dsp_context, DSp_VBLProc, NULL);
#endif
if (bpp == 8)
current->flags |= SDL_HWPALETTE;
if (flags & SDL_OPENGL) {
Rect rect;
RGBColor rgb = { 0.0, 0.0, 0.0 };
GrafPtr save_port;
SetRect (&rect, 0, 0, width, height);
SDL_Window = NewCWindow(nil, &( (**SDL_Display).gdRect), "\p", SDL_TRUE, plainDBox, (WindowPtr)-1, SDL_FALSE, 0);
if (SDL_Window == NULL) {
SDL_SetError ("DSp_SetVideoMode : OpenGL window could not be created.");
return NULL;
}
/* Set window color to black to avoid white flash*/
GetPort (&save_port);
SetPort (SDL_Window);
RGBForeColor (&rgb);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -