Commit aba4b443 authored by Sam Lantinga's avatar Sam Lantinga

Date: Sat, 1 Jun 2002 17:56:45 -0500

From: Darrell Walisser <dwaliss1@purdue.edu>
Subject: mac patch

In this patch:

- yuv code
- links to QuickTime
- tabs -> 4 spaces
- mouse events fix
- SDLMain path parsing fix
- BUGS updates
- some miscellaneous docs/comments/code cleanup

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40391
parent 455d014f
......@@ -72,26 +72,20 @@ MacOS X:
Joystick code is not extensively tested yet.
Window may not close when unsetting video mode and resetting.
Resizeable windows aren't implemented yet.
Depth switching for windowed mode isn't implemented yet.
Palette handling isn't implemented in windowed mode yet.
Command-line arguments Dialog is not implemented yet.
Command-line arguments dialog is not implemented yet.
Fullscreen drawing has some artifacts.
Fullscreen window covers *all* other windows - even force quit.
Fullscreen OpenGL for the software renderer is broken.
Some OpenGL parameters are not accounted for, for example color bits customization.
Getting OpenGL context parameters is not implemented.
Continuous mouse motion perhaps is not as smooth as it should be.
SDL_WM_GrabInput() is implemented, but it "freezes" the hardware
......
......@@ -51,6 +51,9 @@ static BOOL gFinderLaunch;
/* Set the working directory to the .app's parent directory */
- (void) setupWorkingDirectory:(BOOL)shouldChdir
{
if (shouldChdir)
{
char parentdir[MAXPATHLEN];
char *c;
......@@ -65,8 +68,6 @@ static BOOL gFinderLaunch;
*c++ = '\0'; /* cut off last part (binary name) */
if (shouldChdir)
{
assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */
assert ( chdir ("../../../") == 0 ); /* chdir to the .app's parent */
}
......
......@@ -254,8 +254,7 @@ static void QZ_DoModifiers (unsigned int newMods) {
SDL_PrivateKeyboard (SDL_PRESSED, &key);
SDL_PrivateKeyboard (SDL_RELEASED, &key);
}
else
if ( newMask &&
else if ( newMask &&
currentMask != newMask ) { /* modifier down event */
key.sym = mapping[i];
......@@ -306,7 +305,6 @@ static void QZ_DoDeactivate (_THIS) {
static void QZ_PumpEvents (_THIS)
{
static NSPoint lastMouse;
NSPoint mouse, saveMouse;
Point qdMouse;
......@@ -338,7 +336,8 @@ static void QZ_PumpEvents (_THIS)
if (mouse.x != lastMouse.x || mouse.y != lastMouse.y) {
QZ_PrivateCGToSDL (this, &mouse);
if (inForeground && NSPointInRect (mouse, winRect)) {
/* -note- we now generate mouse motion events if the mouse isn't over the window */
if (inForeground /* && NSPointInRect (mouse, winRect)*/) {
//printf ("Mouse Loc: (%f, %f)\n", mouse.x, mouse.y);
SDL_PrivateMouseMotion (0, 0, mouse.x, mouse.y);
}
......@@ -359,6 +358,7 @@ static void QZ_PumpEvents (_THIS)
inMode: NSDefaultRunLoopMode dequeue:YES ];
if (event != nil) {
unsigned int type;
BOOL isForGameWin;
......@@ -401,7 +401,6 @@ static void QZ_PumpEvents (_THIS)
case NSOtherMouseDown: DO_MOUSE_DOWN (2, 0); break;
case NSRightMouseDown: DO_MOUSE_DOWN (3, 0); break;
case NSLeftMouseUp:
if ( last_virtual_button != 0 ) {
DO_MOUSE_UP (last_virtual_button, 0);
last_virtual_button = 0;
......@@ -422,7 +421,6 @@ static void QZ_PumpEvents (_THIS)
case NSRightMouseDragged:
case 27:
case NSMouseMoved:
if (currentGrabMode == SDL_GRAB_ON) {
/**
......@@ -452,10 +450,8 @@ static void QZ_PumpEvents (_THIS)
warp_flag = 0;
}
}
break;
case NSScrollWheel:
{
if (NSPointInRect([ event locationInWindow ], winRect)) {
float dy;
dy = [ event deltaY ];
......@@ -464,7 +460,6 @@ static void QZ_PumpEvents (_THIS)
else /* Scroll down */
SDL_PrivateMouseButton (SDL_PRESSED, 5, 0, 0);
}
}
break;
case NSKeyUp:
QZ_DoKey (SDL_RELEASED, event);
......@@ -489,7 +484,6 @@ static void QZ_PumpEvents (_THIS)
/* case NSApplicationDefined: break; */
/* case NSPeriodic: break; */
/* case NSCursorUpdate: break; */
default:
[ NSApp sendEvent:event ];
}
......
......@@ -18,7 +18,7 @@
Sam Lantinga
slouken@libsdl.org
*/
*/
/* These are the Macintosh key scancode constants -- from Inside Macintosh */
......
......@@ -33,16 +33,15 @@
- Keyboard repeat/mouse speed adjust (if needed)
- Multiple monitor support (currently only main display)
- Accelerated blitting support
- Set the window icon (dock icon when API is available)
- Fix white OpenGL window on minimize
- Fix white OpenGL window on minimize (fixed)
- Find out what events should be sent/ignored if window is mimimized
- Find a better way to deal with resolution/depth switch while app is running
- Find a way to deal with external resolution/depth switch while app is running
- Resizeable windows
- Check accuracy of QZ_SetGamma()
Problems:
- OGL not working in full screen with software renderer
- SetColors sets palette correctly but clears framebuffer
- Crash in CG after several mode switches
- Crash in CG after several mode switches (I think this has been fixed)
- Retained windows don't draw their title bar quite right (OS Bug) (not using retained windows)
- Cursor in 8 bit modes is screwy (might just be Radeon PCI bug)
- Warping cursor delays mouse events for a fraction of a second,
......@@ -52,6 +51,7 @@
#include <Cocoa/Cocoa.h>
#include <OpenGL/OpenGL.h>
#include <Carbon/Carbon.h>
#include <QuickTime/QuickTime.h>
#include "SDL_video.h"
#include "SDL_error.h"
......@@ -102,6 +102,13 @@ typedef struct SDL_PrivateVideoData {
Uint32 warp_ticks; /* timestamp when the warp occured */
NSWindow *window; /* Cocoa window to implement the SDL window */
NSQuickDrawView *view; /* the window's view; draw 2D into this view */
ImageDescriptionHandle yuv_idh;
MatrixRecordPtr yuv_matrix;
DecompressorComponent yuv_codec;
ImageSequence yuv_seq;
PlanarPixmapInfoYUV420 *yuv_pixmap;
Sint16 yuv_width, yuv_height;
CGrafPtr yuv_port;
} SDL_PrivateVideoData ;
......@@ -121,6 +128,15 @@ typedef struct SDL_PrivateVideoData {
#define video_set (this->hidden->video_set)
#define warp_ticks (this->hidden->warp_ticks)
#define warp_flag (this->hidden->warp_flag)
#define yuv_idh (this->hidden->yuv_idh)
#define yuv_matrix (this->hidden->yuv_matrix)
#define yuv_codec (this->hidden->yuv_codec)
#define yuv_seq (this->hidden->yuv_seq)
#define yuv_pixmap (this->hidden->yuv_pixmap)
#define yuv_data (this->hidden->yuv_data)
#define yuv_width (this->hidden->yuv_width)
#define yuv_height (this->hidden->yuv_height)
#define yuv_port (this->hidden->yuv_port)
/* Obscuring code: maximum number of windows above ours (inclusive) */
#define kMaxWindows 256
......@@ -241,3 +257,7 @@ static int QZ_IconifyWindow (_THIS);
static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode);
/*static int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info);*/
/* YUV functions */
static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
Uint32 format, SDL_Surface *display);
......@@ -32,7 +32,6 @@ static char QZ_Error[255]; /* Global error buffer to temporarily store more info
#include "SDL_QuartzEvents.m"
#include "SDL_QuartzWindow.m"
/* Bootstrap binding, enables entry point into the driver */
VideoBootStrap QZ_bootstrap = {
"Quartz", "Mac OS X CoreGraphics", QZ_Available, QZ_CreateDevice
......@@ -100,6 +99,8 @@ static SDL_VideoDevice* QZ_CreateDevice (int device_index) {
/*device->GetWMInfo = QZ_GetWMInfo;*/
device->GrabInput = QZ_GrabInput;
device->CreateYUVOverlay = QZ_CreateYUVOverlay;
device->free = QZ_DeleteDevice;
return device;
......@@ -489,10 +490,10 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt
return current;
/* Since the blanking window covers *all* windows (even force quit) correct recovery is crucial */
ERR_NO_GL: CGDisplaySwitchToMode (display_id, save_mode);
ERR_NO_SWITCH: CGDisplayRelease (display_id);
ERR_NO_CAPTURE: if (!gamma_error) { QZ_FadeGammaIn (this, &gamma_table); }
ERR_NO_MATCH: return NULL;
ERR_NO_GL: CGDisplaySwitchToMode (display_id, save_mode);
ERR_NO_SWITCH: CGDisplayRelease (display_id);
ERR_NO_CAPTURE: if (!gamma_error) { QZ_FadeGammaIn (this, &gamma_table); }
ERR_NO_MATCH: return NULL;
}
static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
......@@ -669,7 +670,7 @@ static int QZ_SetColors (_THIS, int first_color, int num_colors,
}
static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects) {
#pragma unused(this,num_rects,rects)
#pragma unused(this,num_rects,rects)
}
/**
......@@ -678,7 +679,7 @@ static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects) {
**/
static int QZ_IsWindowObscured (NSWindow *window) {
//#define TEST_OBSCURED 1
//#define TEST_OBSCURED 1
#if TEST_OBSCURED
......@@ -1006,10 +1007,10 @@ static void QZ_FreeHWSurface (_THIS, SDL_Surface *surface) {
}
/*
int QZ_FlipHWSurface (_THIS, SDL_Surface *surface) {
int QZ_FlipHWSurface (_THIS, SDL_Surface *surface) {
return 0;
}
*/
}
*/
/* Gamma functions */
static int QZ_SetGamma (_THIS, float red, float green, float blue) {
......@@ -1254,4 +1255,298 @@ static void QZ_GL_SwapBuffers (_THIS) {
[ gl_context flushBuffer ];
}
static int QZ_LockYUV (_THIS, SDL_Overlay *overlay) {
return 0;
}
static void QZ_UnlockYUV (_THIS, SDL_Overlay *overlay) {
;
}
static int QZ_DisplayYUV (_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect) {
OSErr err;
CodecFlags flags;
if (dstrect->x != 0 || dstrect->y != 0) {
SDL_SetError ("Need a dstrect at (0,0)");
return -1;
}
if (dstrect->w != yuv_width || dstrect->h != yuv_height) {
Fixed scale_x, scale_y;
scale_x = FixDiv ( Long2Fix (dstrect->w), Long2Fix (overlay->w) );
scale_y = FixDiv ( Long2Fix (dstrect->h), Long2Fix (overlay->h) );
SetIdentityMatrix (yuv_matrix);
ScaleMatrix (yuv_matrix, scale_x, scale_y, Long2Fix (0), Long2Fix (0));
SetDSequenceMatrix (yuv_seq, yuv_matrix);
yuv_width = dstrect->w;
yuv_height = dstrect->h;
}
if( ( err = DecompressSequenceFrameS(
yuv_seq,
(void*)yuv_pixmap,
sizeof (PlanarPixmapInfoYUV420),
codecFlagUseImageBuffer, &flags, nil ) != noErr ) )
{
SDL_SetError ("DecompressSequenceFrameS failed");
}
return err == noErr;
}
static void QZ_FreeHWYUV (_THIS, SDL_Overlay *overlay) {
CDSequenceEnd (yuv_seq);
ExitMovies();
free (overlay->hwfuncs);
free (overlay->pitches);
free (overlay->pixels);
if (SDL_VideoSurface->flags & SDL_FULLSCREEN) {
[ qz_window close ];
qz_window = nil;
}
free (yuv_matrix);
DisposeHandle ((Handle)yuv_idh);
}
#include "SDL_yuvfuncs.h"
/**
* check for 16 byte alignment, bail otherwise
**/
#define CHECK_ALIGN(x) do { if ((Uint32)x & 15) { SDL_SetError("Alignment error"); return NULL; } } while(0)
/**
* align a byte offset, return how much to add to make it
* a multiple of 16
**/
#define ALIGN(x) ((16 - (x & 15)) & 15)
static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
Uint32 format, SDL_Surface *display) {
Uint32 codec;
OSStatus err;
CGrafPtr port;
SDL_Overlay *overlay;
if (format == SDL_YV12_OVERLAY ||
format == SDL_IYUV_OVERLAY) {
codec = kYUV420CodecType;
}
else {
SDL_SetError ("Hardware: unsupported video format");
return NULL;
}
yuv_idh = (ImageDescriptionHandle) NewHandleClear (sizeof(ImageDescription));
if (yuv_idh == NULL) {
SDL_OutOfMemory();
return NULL;
}
yuv_matrix = (MatrixRecordPtr) malloc (sizeof(MatrixRecord));
if (yuv_matrix == NULL) {
SDL_OutOfMemory();
return NULL;
}
if ( EnterMovies() != noErr ) {
SDL_SetError ("Could not init QuickTime for YUV playback");
return NULL;
}
err = FindCodec (codec, bestSpeedCodec, nil, &yuv_codec);
if (err != noErr) {
SDL_SetError ("Could not find QuickTime codec for format");
return NULL;
}
if (SDL_VideoSurface->flags & SDL_FULLSCREEN) {
/**
* Good acceleration requires a window to be present.
* A CGrafPtr that points to the screen isn't good enough
**/
NSRect content = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
qz_window = [ [ SDL_QuartzWindow alloc ]
initWithContentRect:content
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered defer:NO ];
if (qz_window == nil) {
SDL_SetError ("Could not create the Cocoa window");
return NULL;
}
[ qz_window setContentView:[ [ SDL_QuartzWindowView alloc ] init ] ];
[ qz_window setReleasedWhenClosed:YES ];
[ qz_window center ];
[ qz_window setAcceptsMouseMovedEvents:YES ];
[ qz_window setLevel:CGShieldingWindowLevel() ];
[ qz_window makeKeyAndOrderFront:nil ];
port = [ [ qz_window contentView ] qdPort ];
SetPort (port);
// BUG: would like to remove white flash when window kicks in
//{
// Rect r;
// SetRect (&r, 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
// PaintRect (&r);
// QDFlushPortBuffer (port, nil);
//}
}
else {
port = [ [ qz_window contentView ] qdPort ];
SetPort (port);
}
SetIdentityMatrix (yuv_matrix);
HLock ((Handle)yuv_idh);
(**yuv_idh).idSize = sizeof(ImageDescription);
(**yuv_idh).cType = codec;
(**yuv_idh).version = 1;
(**yuv_idh).revisionLevel = 0;
(**yuv_idh).width = width;
(**yuv_idh).height = height;
(**yuv_idh).hRes = Long2Fix(72);
(**yuv_idh).vRes = Long2Fix(72);
(**yuv_idh).spatialQuality = codecLosslessQuality;
(**yuv_idh).frameCount = 1;
(**yuv_idh).clutID = -1;
(**yuv_idh).dataSize = 0;
(**yuv_idh).depth = 12;
HUnlock ((Handle)yuv_idh);
err = DecompressSequenceBeginS (
&yuv_seq,
yuv_idh,
NULL,
0,
port,
NULL,
NULL,
yuv_matrix,
0,
NULL,
codecFlagUseImageBuffer,
codecLosslessQuality,
yuv_codec);
if (err != noErr) {
SDL_SetError ("Error trying to start YUV codec.");
return NULL;
}
overlay = (SDL_Overlay*) malloc (sizeof(*overlay));
if (overlay == NULL) {
SDL_OutOfMemory();
return NULL;
}
overlay->format = format;
overlay->w = width;
overlay->h = height;
overlay->planes = 3;
overlay->hw_overlay = 1;
{
int offset;
Uint8 **pixels;
Uint16 *pitches;
int plane2, plane3;
if (format == SDL_IYUV_OVERLAY) {
plane2 = 1; /* Native codec format */
plane3 = 2;
}
else if (format == SDL_YV12_OVERLAY) {
/* switch the U and V planes */
plane2 = 2; /* U plane maps to plane 3 */
plane3 = 1; /* V plane maps to plane 2 */
}
else {
SDL_SetError("Unsupported YUV format");
return NULL;
}
pixels = (Uint8**) malloc (sizeof(*pixels) * 3);
pitches = (Uint16*) malloc (sizeof(*pitches) * 3);
if (pixels == NULL || pitches == NULL) {
SDL_OutOfMemory();
return NULL;
}
yuv_pixmap = (PlanarPixmapInfoYUV420*)
malloc (sizeof(PlanarPixmapInfoYUV420) +
(width * height * 2));
if (yuv_pixmap == NULL) {
SDL_OutOfMemory ();
return NULL;
}
//CHECK_ALIGN(yuv_pixmap);
offset = sizeof(PlanarPixmapInfoYUV420);
//offset += ALIGN(offset);
//CHECK_ALIGN(offset);
pixels[0] = (Uint8*)yuv_pixmap + offset;
//CHECK_ALIGN(pixels[0]);
pitches[0] = width;
yuv_pixmap->componentInfoY.offset = offset;
yuv_pixmap->componentInfoY.rowBytes = width;
offset += width * height;
pixels[plane2] = (Uint8*)yuv_pixmap + offset;
pitches[plane2] = width / 2;
yuv_pixmap->componentInfoCb.offset = offset;
yuv_pixmap->componentInfoCb.rowBytes = width / 2;
offset += (width * height / 4);
pixels[plane3] = (Uint8*)yuv_pixmap + offset;
pitches[plane3] = width / 2;
yuv_pixmap->componentInfoCr.offset = offset;
yuv_pixmap->componentInfoCr.rowBytes = width / 2;
overlay->pixels = pixels;
overlay->pitches = pitches;
}
overlay->hwfuncs = malloc (sizeof(*overlay->hwfuncs));
if (overlay->hwfuncs == NULL) {
SDL_OutOfMemory();
return NULL;
}
overlay->hwfuncs->Lock = QZ_LockYUV;
overlay->hwfuncs->Unlock = QZ_UnlockYUV;
overlay->hwfuncs->Display = QZ_DisplayYUV;
overlay->hwfuncs->FreeHW = QZ_FreeHWYUV;
yuv_width = overlay->w;
yuv_height = overlay->h;
return overlay;
}
......@@ -246,18 +246,18 @@ static void QZ_SetIcon (_THIS, SDL_Surface *icon, Uint8 *mask)
#define ALPHASHIFT 3
for (i=0;i<masksize;i+=8)
for (j=0;j<8;j++)
surfPtr[ALPHASHIFT+((i+j)<<2)]=(mask[i>>3]&(1<<(7-j)))?0xFF:0x00;
surfPtr[ALPHASHIFT+((i+j)<<2)]=(mask[i>>3]&(1<<(7-j)))?0xFF:0x00;
}
imgrep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:(unsigned char **)&mergedSurface->pixels
pixelsWide:icon->w pixelsHigh:icon->h bitsPerSample:8 samplesPerPixel:4
hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:icon->w<<2 bitsPerPixel:32];
img = [[NSImage alloc] initWithSize:imgSize];
[img addRepresentation: imgrep];
[NSApp setApplicationIconImage:img];
[img release];
[imgrep release];
imgrep = [ [ NSBitmapImageRep alloc]
initWithBitmapDataPlanes:(unsigned char **)&mergedSurface->pixels
pixelsWide:icon->w pixelsHigh:icon->h bitsPerSample:8 samplesPerPixel:4
hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:icon->w<<2 bitsPerPixel:32 ];
img = [ [ NSImage alloc ] initWithSize:imgSize ];
[ img addRepresentation: imgrep ];
[ NSApp setApplicationIconImage:img ];
[ img release ];
[ imgrep release ];
SDL_FreeSurface(mergedSurface);
freePool:
[pool release];
......@@ -297,7 +297,6 @@ static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode) {
currentGrabMode = SDL_GRAB_ON;
break;
case SDL_GRAB_FULLSCREEN:
break;
}
......
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