Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Work-in-progress patch to add OSX retina support to SDL 1.2.15
diff -r 4488c8602961 Xcode/SDL/SDL.xcodeproj/project.pbxproj
--- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj Wed Jul 18 14:14:55 2012 -0700
+++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj Tue Apr 09 07:45:32 2013 +1000
@@ -1742,6 +1742,7 @@
OTHER_CFLAGS_ppc = "";
OTHER_LDFLAGS_ppc = "-prebind -seg1addr 0x30000000";
PRODUCT_NAME = SDL;
+ SDKROOT = macosx10.7;
WRAPPER_EXTENSION = framework;
};
name = Release;
@@ -1834,6 +1835,7 @@
OTHER_CFLAGS_i386 = "";
OTHER_CFLAGS_ppc = "";
PRODUCT_NAME = SDL;
+ SDKROOT = macosx10.7;
WRAPPER_EXTENSION = framework;
};
name = Debug;
diff -r 4488c8602961 include/SDL_video.h
--- a/include/SDL_video.h Wed Jul 18 14:14:55 2012 -0700
+++ b/include/SDL_video.h Tue Apr 09 07:45:32 2013 +1000
@@ -143,6 +143,7 @@
#define SDL_OPENGLBLIT 0x0000000A /**< Create an OpenGL rendering context and use it for blitting */
#define SDL_RESIZABLE 0x00000010 /**< This video mode may be resized */
#define SDL_NOFRAME 0x00000020 /**< No window caption or edge frame */
+#define SDL_HIGHDENSITY 0x00000008 /**< This video mode is high-density (i.e. Retina displays -- this flag currently only implemented on OSX TODO: NOT CURRENTLY FULLY WORKING) */
/*@}*/
/** Used internally (read-only) */
@@ -314,11 +315,11 @@
/**
* Return a pointer to an array of available screen dimensions for the
- * given format and video flags, sorted largest to smallest. Returns
- * NULL if there are no dimensions available for a particular format,
+ * given format and video flags, sorted largest to smallest. Returns
+ * NULL if there are no dimensions available for a particular format,
* or (SDL_Rect **)-1 if any dimension is okay for the given format.
*
- * If 'format' is NULL, the mode list will be for the format given
+ * If 'format' is NULL, the mode list will be for the format given
* by SDL_GetVideoInfo()->vfmt
*/
extern DECLSPEC SDL_Rect ** SDLCALL SDL_ListModes(SDL_PixelFormat *format, Uint32 flags);
@@ -347,21 +348,21 @@
* Otherwise, in 8-bit mode, SDL_SetColors() may not be able to set all
* of the colors exactly the way they are requested, and you should look
* at the video surface structure to determine the actual palette.
- * If SDL cannot guarantee that the colors you request can be set,
+ * If SDL cannot guarantee that the colors you request can be set,
* i.e. if the colormap is shared, then the video surface may be created
* under emulation in system memory, overriding the SDL_HWSURFACE flag.
*
* If SDL_FULLSCREEN is set in 'flags', the SDL library will try to set
* a fullscreen video mode. The default is to create a windowed mode
* if the current graphics system has a window manager.
- * If the SDL library is able to set a fullscreen video mode, this flag
+ * If the SDL library is able to set a fullscreen video mode, this flag
* will be set in the surface that is returned.
*
* If SDL_DOUBLEBUF is set in 'flags', the SDL library will try to set up
- * two surfaces in video memory and swap between them when you call
+ * two surfaces in video memory and swap between them when you call
* SDL_Flip(). This is usually slower than the normal single-buffering
- * scheme, but prevents "tearing" artifacts caused by modifying video
- * memory while the monitor is refreshing. It should only be used by
+ * scheme, but prevents "tearing" artifacts caused by modifying video
+ * memory while the monitor is refreshing. It should only be used by
* applications that redraw the entire screen on every update.
*
* If SDL_RESIZABLE is set in 'flags', the SDL library will allow the
@@ -416,7 +417,7 @@
/**
* Set the gamma correction for each of the color channels.
* The gamma values range (approximately) between 0.1 and 10.0
- *
+ *
* If this function isn't supported directly by the hardware, it will
* be emulated using gamma ramps, if available. If successful, this
* function returns 0, otherwise it returns -1.
@@ -429,7 +430,7 @@
* representing a mapping between the input and output for that channel.
* The input is the index into the array, and the output is the 16-bit
* gamma value at that index, scaled to the output color precision.
- *
+ *
* You may pass NULL for any of the channels to leave it unchanged.
* If the call succeeds, it will return 0. If the display driver or
* hardware does not support gamma translation, or otherwise fails,
@@ -439,7 +440,7 @@
/**
* Retrieve the current values of the gamma translation tables.
- *
+ *
* You must pass in valid pointers to arrays of 256 16-bit quantities.
* Any of the pointers may be NULL to ignore that channel.
* If the call succeeds, it will return 0. If the display driver or
@@ -457,13 +458,13 @@
* determine the actual color palette.
*
* When 'surface' is the surface associated with the current display, the
- * display colormap will be updated with the requested colors. If
+ * display colormap will be updated with the requested colors. If
* SDL_HWPALETTE was set in SDL_SetVideoMode() flags, SDL_SetColors()
* will always return 1, and the palette is guaranteed to be set the way
* you desire, even if the window colormap has to be warped or run under
* emulation.
*/
-extern DECLSPEC int SDLCALL SDL_SetColors(SDL_Surface *surface,
+extern DECLSPEC int SDLCALL SDL_SetColors(SDL_Surface *surface,
SDL_Color *colors, int firstcolor, int ncolors);
/**
@@ -537,7 +538,7 @@
* two surfaces in video memory, SDL will try to place the surface in
* video memory. If this isn't possible or if there is no hardware
* acceleration available, the surface will be placed in system memory.
- * SDL_SRCALPHA means that the surface will be used for alpha blits and
+ * SDL_SRCALPHA means that the surface will be used for alpha blits and
* if the hardware supports hardware acceleration of alpha blits between
* two surfaces in video memory, to place the surface in video memory
* if possible, otherwise it will be placed in system memory.
@@ -551,7 +552,7 @@
* the SDL_HWSURFACE flag set, and will be created in system memory instead.
*/
extern DECLSPEC SDL_Surface * SDLCALL SDL_CreateRGBSurface
- (Uint32 flags, int width, int height, int depth,
+ (Uint32 flags, int width, int height, int depth,
Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
/** @sa SDL_CreateRGBSurface */
extern DECLSPEC SDL_Surface * SDLCALL SDL_CreateRGBSurfaceFrom(void *pixels,
@@ -562,8 +563,8 @@
/**
* SDL_LockSurface() sets up a surface for directly accessing the pixels.
* Between calls to SDL_LockSurface()/SDL_UnlockSurface(), you can write
- * to and read from 'surface->pixels', using the pixel format stored in
- * 'surface->format'. Once you are done accessing the surface, you should
+ * to and read from 'surface->pixels', using the pixel format stored in
+ * 'surface->format'. Once you are done accessing the surface, you should
* use SDL_UnlockSurface() to release it.
*
* Not all surfaces require locking. If SDL_MUSTLOCK(surface) evaluates
@@ -571,7 +572,7 @@
* pixel format of the surface will not change. In particular, if the
* SDL_HWSURFACE flag is not given when calling SDL_SetVideoMode(), you
* will not need to lock the display surface before accessing it.
- *
+ *
* No operating system or library calls should be made between lock/unlock
* pairs, as critical system locks may be held during this time.
*
@@ -605,7 +606,7 @@
/**
* Sets the color key (transparent pixel) in a blittable surface.
- * If 'flag' is SDL_SRCCOLORKEY (optionally OR'd with SDL_RLEACCEL),
+ * If 'flag' is SDL_SRCCOLORKEY (optionally OR'd with SDL_RLEACCEL),
* 'key' will be the transparent pixel in the source image of a blit.
* SDL_RLEACCEL requests RLE acceleration for the surface if present,
* and removes RLE acceleration if absent.
@@ -654,11 +655,11 @@
extern DECLSPEC void SDLCALL SDL_GetClipRect(SDL_Surface *surface, SDL_Rect *rect);
/**
- * Creates a new surface of the specified format, and then copies and maps
- * the given surface to it so the blit of the converted surface will be as
+ * Creates a new surface of the specified format, and then copies and maps
+ * the given surface to it so the blit of the converted surface will be as
* fast as possible. If this function fails, it returns NULL.
*
- * The 'flags' parameter is passed to SDL_CreateRGBSurface() and has those
+ * The 'flags' parameter is passed to SDL_CreateRGBSurface() and has those
* semantics. You can also pass SDL_RLEACCEL in the flags parameter and
* SDL will try to RLE accelerate colorkey and alpha blits in the resulting
* surface.
@@ -690,7 +691,7 @@
* if SDL_SRCCOLORKEY set, only copy the pixels matching the
* RGB values of the source colour key, ignoring alpha in the
* comparison.
- *
+ *
* RGB->RGBA:
* SDL_SRCALPHA set:
* alpha-blend (using the source per-surface alpha value);
@@ -700,7 +701,7 @@
* both:
* if SDL_SRCCOLORKEY set, only copy the pixels matching the
* source colour key.
- *
+ *
* RGBA->RGBA:
* SDL_SRCALPHA set:
* alpha-blend (using the source alpha channel) the RGB values;
@@ -711,8 +712,8 @@
* if SDL_SRCCOLORKEY set, only copy the pixels matching the
* RGB values of the source colour key, ignoring alpha in the
* comparison.
- *
- * RGB->RGB:
+ *
+ * RGB->RGB:
* SDL_SRCALPHA set:
* alpha-blend (using the source per-surface alpha value).
* SDL_SRCALPHA not set:
@@ -722,7 +723,7 @@
* source colour key.
*
* If either of the surfaces were in video memory, and the blit returns -2,
- * the video memory was lost, so it should be reloaded with artwork and
+ * the video memory was lost, so it should be reloaded with artwork and
* re-blitted:
* @code
* while ( SDL_BlitSurface(image, imgrect, screen, dstrect) == -2 ) {
@@ -760,7 +761,7 @@
* The given rectangle is clipped to the destination surface clip area
* and the final fill rectangle is saved in the passed in pointer.
* If 'dstrect' is NULL, the whole surface will be filled with 'color'
- * The color should be a pixel of the format used by the surface, and
+ * The color should be a pixel of the format used by the surface, and
* can be generated by the SDL_MapRGB() function.
* This function returns 0 on success, or -1 on error.
*/
@@ -813,7 +814,7 @@
/** Blit a video overlay to the display surface.
* The contents of the video surface underneath the blit destination are
- * not defined.
+ * not defined.
* The width and height of the destination rectangle may be different from
* that of the overlay, but currently only 2x scaling is supported.
*/
@@ -908,7 +909,7 @@
* If the display surface does not require locking before accessing
* the pixel information, then the memory pointers will not change.
*
- * If this function was able to toggle fullscreen mode (change from
+ * If this function was able to toggle fullscreen mode (change from
* running in a window to fullscreen, or vice-versa), it will return 1.
* If it is not implemented, or fails, it returns 0.
*
@@ -941,7 +942,7 @@
/** @internal Not in public API at the moment - do not use! */
extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect,
SDL_Surface *dst, SDL_Rect *dstrect);
-
+
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
diff -r 4488c8602961 src/video/quartz/SDL_QuartzEvents.m
--- a/src/video/quartz/SDL_QuartzEvents.m Wed Jul 18 14:14:55 2012 -0700
+++ b/src/video/quartz/SDL_QuartzEvents.m Tue Apr 09 07:45:32 2013 +1000
@@ -700,6 +700,9 @@
if (qz_window)
QZ_PrivateGlobalToLocal (this, p);
QZ_PrivateCocoaToSDL (this, p);
+ // now convert from points to pixels
+ *p = [ window_view convertPointToBacking:*p ];
+
}
void QZ_DoActivate (_THIS) {
diff -r 4488c8602961 src/video/quartz/SDL_QuartzVideo.m
--- a/src/video/quartz/SDL_QuartzVideo.m Wed Jul 18 14:14:55 2012 -0700
+++ b/src/video/quartz/SDL_QuartzVideo.m Tue Apr 09 07:45:32 2013 +1000
@@ -49,7 +49,7 @@
#if (MAC_OS_X_VERSION_MAX_ALLOWED < 1060) && !defined(__LP64__) /* Fixed in Snow Leopard */
/*
- Add methods to get at private members of NSScreen.
+ Add methods to get at private members of NSScreen.
Since there is a bug in Apple's screen switching code
that does not update this variable when switching
to fullscreen, we'll set it manually (but only for the
@@ -384,7 +384,7 @@
/* register for sleep notifications so wake from sleep generates SDL_VIDEOEXPOSE */
QZ_RegisterForSleepNotifications (this);
-
+
/* Fill in some window manager capabilities */
this->info.wm_available = 1;
@@ -435,6 +435,25 @@
QZ_GetModeInfo(this, onemode, &width, &height, &bpp);
+ // if we're on a retina device but NOT using retina mode,
+ // then we need to convert the width and height (which are expressed in retina pixels)
+ // into non-retina pixels (i.e.: "points").
+
+ //if ( 0 == (flags & SDL_HIGHDENSITY) )
+ {
+ /*CGPoint point;
+ point.x = width;
+ point.y = height;
+ CGContextRef context = CGDisplayGetDrawingContext(display_id);
+ point = CGContextConvertPointToUserSpace(context, point);
+ width = point.x;
+ height = point.y;*/
+
+ /*float scaleFactor = [[ NSScreen mainScreen ] backingScaleFactor];
+ width /= scaleFactor;
+ height /= scaleFactor;*/
+ }
+
if (bpp && (bpp == format->BitsPerPixel)) {
int hasMode = SDL_FALSE;
int i;
@@ -455,7 +474,7 @@
list_size++;
if (client_mode_list == NULL)
- client_mode_list = (SDL_Rect**)
+ client_mode_list = (SDL_Rect**)
SDL_malloc (sizeof(*client_mode_list) * (list_size+1) );
else {
/* !!! FIXME: this leaks memory if SDL_realloc() fails! */
@@ -552,7 +571,7 @@
CGContextRelease (cg_context);
cg_context = nil;
}
-
+
/* Release fullscreen resources */
if ( mode_flags & SDL_FULLSCREEN ) {
@@ -577,7 +596,7 @@
qz_window = nil;
window_view = nil;
}
- /*
+ /*
Release the OpenGL context
Do this first to avoid trash on the display before fade
*/
@@ -605,7 +624,7 @@
/* Restore original screen resolution/bpp */
QZ_RestoreDisplayMode (this);
CGReleaseAllDisplays ();
- /*
+ /*
Reset the main screen's rectangle
See comment in QZ_SetVideoFullscreen for why we do this
*/
@@ -699,7 +718,7 @@
if ( CGAcquireDisplayFadeReservation (5, &fade_token) == kCGErrorSuccess ) {
CGDisplayFade (fade_token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE);
}
-
+
/* Destroy any previous mode */
if (video_set == SDL_TRUE)
QZ_UnsetVideoMode (this, FALSE, save_gl);
@@ -726,7 +745,7 @@
error = CGDisplayCapture (display_id);
else
error = CGCaptureAllDisplays ();
-
+
if ( CGDisplayNoErr != error ) {
SDL_SetError ("Failed capturing display");
goto ERR_NO_CAPTURE;
@@ -753,19 +772,19 @@
/* Setup double-buffer emulation */
if ( flags & SDL_DOUBLEBUF ) {
-
+
/*
Setup a software backing store for reasonable results when
double buffering is requested (since a single-buffered hardware
surface looks hideous).
-
- The actual screen blit occurs in a separate thread to allow
+
+ The actual screen blit occurs in a separate thread to allow
other blitting while waiting on the VBL (and hence results in higher framerates).
*/
this->LockHWSurface = NULL;
this->UnlockHWSurface = NULL;
this->UpdateRects = NULL;
-
+
current->flags |= (SDL_HWSURFACE|SDL_DOUBLEBUF);
this->UpdateRects = QZ_DoubleBufferUpdate;
this->LockHWSurface = QZ_LockDoubleBuffer;
@@ -777,10 +796,10 @@
SDL_OutOfMemory ();
goto ERR_DOUBLEBUF;
}
-
+
sw_buffers[0] = current->pixels;
sw_buffers[1] = (Uint8*)current->pixels + current->pitch * current->h;
-
+
quit_thread = NO;
sem1 = SDL_CreateSemaphore (0);
sem2 = SDL_CreateSemaphore (1);
@@ -795,7 +814,7 @@
/* Check if we should recreate the window */
if (qz_window == nil) {
/* Manually create a window, avoids having a nib file resource */
- qz_window = [ [ SDL_QuartzWindow alloc ]
+ qz_window = [ [ SDL_QuartzWindow alloc ]
initWithContentRect:contentRect
styleMask:(isLion ? NSBorderlessWindowMask : 0)
backing:NSBackingStoreBuffered
@@ -828,6 +847,10 @@
/* Initialize the NSView and add it to our window. The presence of a valid window and
view allow the cursor to be changed whilst in fullscreen.*/
window_view = [ [ NSView alloc ] initWithFrame:contentRect ];
+ if ( [window_view respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:) ] )
+ {
+ [ window_view setWantsBestResolutionOpenGLSurface:YES ];
+ }
if ( isLion ) {
[ window_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ];
@@ -852,7 +875,7 @@
[ qz_window setLevel:NSNormalWindowLevel ];
ctx = QZ_GetCGLContextObj (gl_context);
err = CGLSetFullScreen (ctx);
-
+
if (err) {
SDL_SetError ("Error setting OpenGL fullscreen: %s", CGLErrorString(err));
goto ERR_NO_GL;
@@ -882,12 +905,12 @@
cgColorspace = CGColorSpaceCreateDeviceRGB();
current->pitch = 4 * current->w;
current->pixels = SDL_malloc (current->h * current->pitch);
-
+
cg_context = CGBitmapContextCreate (current->pixels, current->w, current->h,
8, current->pitch, cgColorspace,
kCGImageAlphaNoneSkipFirst);
CGColorSpaceRelease (cgColorspace);
-
+
current->flags |= SDL_SWSURFACE;
current->flags |= SDL_ASYNCBLIT;
current->hwdata = (void *) cg_context;
@@ -924,7 +947,7 @@
CGReleaseDisplayFadeReservation(fade_token);
}
- /*
+ /*
There is a bug in Cocoa where NSScreen doesn't synchronize
with CGDirectDisplay, so the main screen's frame is wrong.
As a result, coordinate translation produces incorrect results.
@@ -967,11 +990,18 @@
current->flags = 0;
current->w = width;
current->h = height;
-
+
contentRect = NSMakeRect (0, 0, width, height);
+ // Adjust for retina
+ {
+ float scaleFactor = [[ NSScreen mainScreen ] backingScaleFactor];
+ contentRect.size.width *= 1.0f / scaleFactor;
+ contentRect.size.height *= 1.0f / scaleFactor;
+ }
+
/*
- Check if we should completely destroy the previous mode
+ Check if we should completely destroy the previous mode
- If it is fullscreen
- If it has different noframe or resizable attribute
- If it is OpenGL (since gl attributes could be different)
@@ -987,12 +1017,12 @@
QZ_UnsetVideoMode (this, TRUE, save_gl);
}
else if ( ((mode_flags ^ flags) & (SDL_NOFRAME|SDL_RESIZABLE)) ||
- (mode_flags & SDL_OPENGL) ||
+ (mode_flags & SDL_OPENGL) ||
(flags & SDL_OPENGL) ) {
QZ_UnsetVideoMode (this, TRUE, save_gl);
}
}
-
+
/* Sorry, QuickDraw was ripped out. */
if (getenv("SDL_NSWindowPointer") || getenv("SDL_NSQuickDrawViewPointer")) {
SDL_SetError ("Embedded QuickDraw windows are no longer supported");
@@ -1005,7 +1035,7 @@
/* Check if we should recreate the window */
if (qz_window == nil) {
-
+
/* Set the window style based on input flags */
if ( flags & SDL_NOFRAME ) {
style = NSBorderlessWindowMask;
@@ -1020,12 +1050,12 @@
}
/* Manually create a window, avoids having a nib file resource */
- qz_window = [ [ SDL_QuartzWindow alloc ]
+ qz_window = [ [ SDL_QuartzWindow alloc ]
initWithContentRect:contentRect
- styleMask:style
+ styleMask:style
backing:NSBackingStoreBuffered
defer:NO ];
-
+
if (qz_window == nil) {
SDL_SetError ("Could not create the Cocoa window");
if (fade_token != kCGDisplayFadeReservationInvalidToken) {
@@ -1074,6 +1104,11 @@
window_view = [ [ NSView alloc ] initWithFrame:contentRect ];
[ window_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ];
+ // MY RETINA ADDITION
+ if ( [window_view respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:) ] )
+ {
+ [ window_view setWantsBestResolutionOpenGLSurface:YES ];
+ }
[ [ qz_window contentView ] addSubview:window_view ];
[ gl_context setView: window_view ];
[ window_view release ];
@@ -1087,23 +1122,23 @@
/* Only recreate the view if it doesn't already exist */
if (window_view == nil) {
-
+
window_view = [ [ NSView alloc ] initWithFrame:contentRect ];
[ window_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ];
[ [ qz_window contentView ] addSubview:window_view ];
[ window_view release ];
[ qz_window makeKeyAndOrderFront:nil ];
}
-
+
cgColorspace = CGColorSpaceCreateDeviceRGB();
current->pitch = 4 * current->w;
current->pixels = SDL_malloc (current->h * current->pitch);
-
+
cg_context = CGBitmapContextCreate (current->pixels, current->w, current->h,
8, current->pitch, cgColorspace,
kCGImageAlphaNoneSkipFirst);
CGColorSpaceRelease (cgColorspace);
-
+
current->flags |= SDL_SWSURFACE;
current->flags |= SDL_ASYNCBLIT;
current->hwdata = (void *) cg_context;
@@ -1287,9 +1322,9 @@
UInt64 i;
Nanoseconds ns;
} temp;
-
+
temp.i = seconds * 1000000000.0;
-
+
return NanosecondsToAbsolute ( temp.ns );
}
@@ -1297,7 +1332,7 @@
{
Uint8 *src, *dst;
int skip, len, h;
-
+
/*
Give this thread the highest scheduling priority possible,
in the hopes that it will immediately run after the VBL delay
@@ -1306,20 +1341,20 @@
pthread_t current_thread;
int policy;
struct sched_param param;
-
+
current_thread = pthread_self ();
pthread_getschedparam (current_thread, &policy, &param);
policy = SCHED_RR;
param.sched_priority = sched_get_priority_max (policy);
pthread_setschedparam (current_thread, policy, &param);
}
-
+
while (1) {
-
+
SDL_SemWait (sem1);
if (quit_thread)
return 0;
-
+
/*
* We have to add SDL_VideoSurface->offset here, since we might be a
* smaller surface in the center of the framebuffer (you asked for
@@ -1331,89 +1366,89 @@
len = SDL_VideoSurface->w * SDL_VideoSurface->format->BytesPerPixel;
h = SDL_VideoSurface->h;
skip = SDL_VideoSurface->pitch;
-
+
/* Wait for the VBL to occur (estimated since we don't have a hardware interrupt) */
{
-
+
/* The VBL delay is based on Ian Ollmann's RezLib <iano@cco.caltech.edu> */
double refreshRate;
double linesPerSecond;
double target;
double position;
double adjustment;
- AbsoluteTime nextTime;
+ AbsoluteTime nextTime;
CFNumberRef refreshRateCFNumber;
-
+
refreshRateCFNumber = CFDictionaryGetValue (mode, kCGDisplayRefreshRate);
if ( NULL == refreshRateCFNumber ) {
SDL_SetError ("Mode has no refresh rate");
goto ERROR;
}
-
+
if ( 0 == CFNumberGetValue (refreshRateCFNumber, kCFNumberDoubleType, &refreshRate) ) {
SDL_SetError ("Error getting refresh rate");
goto ERROR;
}
-
+
if ( 0 == refreshRate ) {
-
+
SDL_SetError ("Display has no refresh rate, using 60hz");
-
+
/* ok, for LCD's we'll emulate a 60hz refresh, which may or may not look right */
refreshRate = 60.0;
}
-
+
linesPerSecond = refreshRate * h;
target = h;
-
+
/* Figure out the first delay so we start off about right */
position = CGDisplayBeamPosition (display_id);
if (position > target)
position = 0;
-
- adjustment = (target - position) / linesPerSecond;
-
+
+ adjustment = (target - position) / linesPerSecond;
+
nextTime = AddAbsoluteToAbsolute (UpTime (), QZ_SecondsToAbsolute (adjustment));
-
+
MPDelayUntil (&nextTime);
}
-
-
+
+
/* On error, skip VBL delay */
ERROR:
-
+
/* TODO: use CGContextDrawImage here too! Create two CGContextRefs the same way we
create two buffers, replace current_buffer with current_context and set it
appropriately in QZ_FlipDoubleBuffer. */
while ( h-- ) {
-
+
SDL_memcpy (dst, src, len);
src += skip;
dst += skip;
}
-
+
/* signal flip completion */
SDL_SemPost (sem2);
}
-
+
return 0;
}
-
+
static int QZ_FlipDoubleBuffer (_THIS, SDL_Surface *surface)
{
/* wait for previous flip to complete */
SDL_SemWait (sem2);
-
+
current_buffer = surface->pixels;
-
+
if (surface->pixels == sw_buffers[0])
surface->pixels = sw_buffers[1];
else
surface->pixels = sw_buffers[0];
-
+
/* signal worker thread to do the flip */
SDL_SemPost (sem1);
-
+
return 0;
}
@@ -1473,29 +1508,29 @@
{
/* Check if we should draw the resize icon */
if (SDL_VideoSurface->flags & SDL_RESIZABLE) {
-
+
SDL_Rect icon_rect;
-
+
/* Create the icon image */
if (resize_icon == NULL) {
-
+
SDL_RWops *rw;
SDL_Surface *tmp;
-
+
rw = SDL_RWFromConstMem (QZ_ResizeIcon, sizeof(QZ_ResizeIcon));
tmp = SDL_LoadBMP_RW (rw, SDL_TRUE);
-
+
resize_icon = SDL_ConvertSurface (tmp, SDL_VideoSurface->format, SDL_SRCCOLORKEY);
SDL_SetColorKey (resize_icon, SDL_SRCCOLORKEY, 0xFFFFFF);
-
+
SDL_FreeSurface (tmp);
}
-
+
icon_rect.x = SDL_VideoSurface->w - 13;
icon_rect.y = SDL_VideoSurface->h - 13;
icon_rect.w = 13;
icon_rect.h = 13;
-
+
SDL_BlitSurface (resize_icon, NULL, SDL_VideoSurface, &icon_rect);
}
}
@@ -1506,10 +1541,10 @@
QZ_GL_SwapBuffers (this);
}
else if ( [ qz_window isMiniaturized ] ) {
-
+
/* Do nothing if miniaturized */
}
-
+
else {
NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
if (ctx != nsgfx_context) { /* uhoh, you might be rendering from another thread... */
@@ -1521,7 +1556,7 @@
CGContextFlush (cg_context);
CGImageRef image = CGBitmapContextCreateImage (cg_context);
CGRect rectangle = CGRectMake (0,0,[window_view frame].size.width,[window_view frame].size.height);
-
+
CGContextDrawImage (cgc, rectangle, image);
CGImageRelease(image);
CGContextFlush (cgc);
@@ -1538,7 +1573,7 @@
/* Ensure the cursor will be visible and working when we quit */
CGDisplayShowCursor (display_id);
CGAssociateMouseAndMouseCursorPosition (1);
-
+
if (mode_flags & SDL_FULLSCREEN) {
/* Fade to black to hide resolution-switching flicker (and garbage
that is displayed by a destroyed OpenGL context, if applicable) */
diff -r 4488c8602961 src/video/quartz/SDL_QuartzWM.m
--- a/src/video/quartz/SDL_QuartzWM.m Wed Jul 18 14:14:55 2012 -0700
+++ b/src/video/quartz/SDL_QuartzWM.m Tue Apr 09 07:45:32 2013 +1000
@@ -150,7 +150,9 @@
void QZ_PrivateGlobalToLocal (_THIS, NSPoint *p) {
if ( ! CGDisplayIsCaptured (display_id) )
+ {
*p = [ qz_window convertScreenToBase:*p ];
+ }
}
@@ -234,6 +236,8 @@
CGPoint cgp;
p = NSMakePoint (x, y);
+ // RETINA: convert from pixels to points
+ p = [ window_view convertPointFromBacking:p ];
cgp = QZ_PrivateSDLToCG (this, &p);
/* this is the magic call that fixes cursor "freezing" after warp */
diff -r 4488c8602961 src/video/quartz/SDL_QuartzWindow.m
--- a/src/video/quartz/SDL_QuartzWindow.m Wed Jul 18 14:14:55 2012 -0700
+++ b/src/video/quartz/SDL_QuartzWindow.m Tue Apr 09 07:45:32 2013 +1000
@@ -123,7 +123,13 @@
[ super setFrame:frameRect display:flag ];
newViewFrame = [ window_view frame ];
-
+ // Adjust for retina
+ {
+ float scaleFactor = [[ NSScreen mainScreen ] backingScaleFactor];
+ newViewFrame.size.width *= scaleFactor;
+ newViewFrame.size.height *= scaleFactor;
+ }
+
SDL_PrivateResize (newViewFrame.size.width, newViewFrame.size.height);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment