Merged default into iOS-improvements
commit
292eedffe8
|
@ -8,6 +8,9 @@ Makefile
|
|||
sdl-config
|
||||
SDL2.spec
|
||||
build
|
||||
Build
|
||||
*xcuserdata*
|
||||
*xcworkspacedata*
|
||||
|
||||
# for Xcode
|
||||
*.orig
|
||||
|
|
|
@ -1274,8 +1274,14 @@
|
|||
FD6526640DE8FCCB002AD96B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
|
||||
GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES;
|
||||
GCC_WARN_STRICT_SELECTOR_MATCH = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
PRODUCT_NAME = SDL2;
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
|
@ -1284,8 +1290,14 @@
|
|||
FD6526650DE8FCCB002AD96B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
|
||||
GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES;
|
||||
GCC_WARN_STRICT_SELECTOR_MATCH = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
PRODUCT_NAME = SDL2;
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
|
|
|
@ -261,8 +261,9 @@ extern "C" {
|
|||
#define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether an Android built-in accelerometer should be
|
||||
* listed as a joystick device, rather than listing actual joysticks only.
|
||||
* \brief A variable controlling whether the Android / iOS built-in
|
||||
* accelerometer should be listed as a joystick device, rather than listing
|
||||
* actual joysticks only.
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - List only real joysticks and accept input from them
|
||||
|
@ -345,7 +346,7 @@ extern "C" {
|
|||
|
||||
|
||||
/**
|
||||
* \brief If set to 1, then do not allow high-DPI windows. ("Retina" on Mac)
|
||||
* \brief If set to 1, then do not allow high-DPI windows. ("Retina" on Mac and iOS)
|
||||
*/
|
||||
#define SDL_HINT_VIDEO_HIGHDPI_DISABLED "SDL_VIDEO_HIGHDPI_DISABLED"
|
||||
|
||||
|
|
|
@ -209,9 +209,9 @@ struct SDL_SysWMinfo
|
|||
struct
|
||||
{
|
||||
#if defined(__OBJC__) && __has_feature(objc_arc)
|
||||
NSWindow __unsafe_unretained *window; /* The Cocoa window */
|
||||
NSWindow * __unsafe_unretained window; /* The Cocoa window */
|
||||
#else
|
||||
NSWindow *window; /* The Cocoa window */
|
||||
NSWindow *window; /* The Cocoa window */
|
||||
#endif
|
||||
} cocoa;
|
||||
#endif
|
||||
|
@ -219,9 +219,9 @@ struct SDL_SysWMinfo
|
|||
struct
|
||||
{
|
||||
#if defined(__OBJC__) && __has_feature(objc_arc)
|
||||
UIWindow __unsafe_unretained *window; /* The UIKit window */
|
||||
UIWindow * __unsafe_unretained window; /* The UIKit window */
|
||||
#else
|
||||
UIWindow *window; /* The UIKit window */
|
||||
UIWindow *window; /* The UIKit window */
|
||||
#endif
|
||||
} uikit;
|
||||
#endif
|
||||
|
|
|
@ -41,27 +41,23 @@ FILE* SDL_OpenFPFromBundleOrFallback(const char *file, const char *mode)
|
|||
return fopen(file, mode);
|
||||
}
|
||||
|
||||
NSAutoreleasePool* autorelease_pool = [[NSAutoreleasePool alloc] init];
|
||||
@autoreleasepool {
|
||||
NSFileManager* file_manager = [NSFileManager defaultManager];
|
||||
NSString* resource_path = [[NSBundle mainBundle] resourcePath];
|
||||
|
||||
NSString* ns_string_file_component = [file_manager stringWithFileSystemRepresentation:file length:strlen(file)];
|
||||
|
||||
NSFileManager* file_manager = [NSFileManager defaultManager];
|
||||
NSString* resource_path = [[NSBundle mainBundle] resourcePath];
|
||||
|
||||
NSString* ns_string_file_component = [file_manager stringWithFileSystemRepresentation:file length:strlen(file)];
|
||||
|
||||
NSString* full_path_with_file_to_try = [resource_path stringByAppendingPathComponent:ns_string_file_component];
|
||||
if([file_manager fileExistsAtPath:full_path_with_file_to_try]) {
|
||||
fp = fopen([full_path_with_file_to_try fileSystemRepresentation], mode);
|
||||
NSString* full_path_with_file_to_try = [resource_path stringByAppendingPathComponent:ns_string_file_component];
|
||||
if([file_manager fileExistsAtPath:full_path_with_file_to_try]) {
|
||||
fp = fopen([full_path_with_file_to_try fileSystemRepresentation], mode);
|
||||
} else {
|
||||
fp = fopen(file, mode);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fp = fopen(file, mode);
|
||||
}
|
||||
|
||||
[autorelease_pool drain];
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
#endif /* __MACOSX__ */
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -36,67 +36,69 @@
|
|||
char *
|
||||
SDL_GetBasePath(void)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
const char* baseType = [[[bundle infoDictionary] objectForKey:@"SDL_FILESYSTEM_BASE_DIR_TYPE"] UTF8String];
|
||||
const char *base = NULL;
|
||||
char *retval = NULL;
|
||||
if (baseType == NULL) {
|
||||
baseType = "resource";
|
||||
}
|
||||
if (SDL_strcasecmp(baseType, "bundle")==0) {
|
||||
base = [[bundle bundlePath] fileSystemRepresentation];
|
||||
} else if (SDL_strcasecmp(baseType, "parent")==0) {
|
||||
base = [[[bundle bundlePath] stringByDeletingLastPathComponent] fileSystemRepresentation];
|
||||
} else {
|
||||
/* this returns the exedir for non-bundled and the resourceDir for bundled apps */
|
||||
base = [[bundle resourcePath] fileSystemRepresentation];
|
||||
}
|
||||
if (base) {
|
||||
const size_t len = SDL_strlen(base) + 2;
|
||||
retval = (char *) SDL_malloc(len);
|
||||
if (retval == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
|
||||
@autoreleasepool {
|
||||
const char *base = NULL;
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
const char* baseType = [[[bundle infoDictionary] objectForKey:@"SDL_FILESYSTEM_BASE_DIR_TYPE"] UTF8String];
|
||||
if (baseType == NULL) {
|
||||
baseType = "resource";
|
||||
}
|
||||
if (SDL_strcasecmp(baseType, "bundle")==0) {
|
||||
base = [[bundle bundlePath] fileSystemRepresentation];
|
||||
} else if (SDL_strcasecmp(baseType, "parent")==0) {
|
||||
base = [[[bundle bundlePath] stringByDeletingLastPathComponent] fileSystemRepresentation];
|
||||
} else {
|
||||
SDL_snprintf(retval, len, "%s/", base);
|
||||
/* this returns the exedir for non-bundled and the resourceDir for bundled apps */
|
||||
base = [[bundle resourcePath] fileSystemRepresentation];
|
||||
}
|
||||
|
||||
if (base) {
|
||||
const size_t len = SDL_strlen(base) + 2;
|
||||
retval = (char *) SDL_malloc(len);
|
||||
if (retval == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
} else {
|
||||
SDL_snprintf(retval, len, "%s/", base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[pool release];
|
||||
return retval;
|
||||
}
|
||||
|
||||
char *
|
||||
SDL_GetPrefPath(const char *org, const char *app)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
NSArray *array = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
||||
char *retval = NULL;
|
||||
|
||||
if ([array count] > 0) { /* we only want the first item in the list. */
|
||||
NSString *str = [array objectAtIndex:0];
|
||||
const char *base = [str fileSystemRepresentation];
|
||||
if (base) {
|
||||
const size_t len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4;
|
||||
retval = (char *) SDL_malloc(len);
|
||||
if (retval == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
} else {
|
||||
char *ptr;
|
||||
SDL_snprintf(retval, len, "%s/%s/%s/", base, org, app);
|
||||
for (ptr = retval+1; *ptr; ptr++) {
|
||||
if (*ptr == '/') {
|
||||
*ptr = '\0';
|
||||
mkdir(retval, 0700);
|
||||
*ptr = '/';
|
||||
@autoreleasepool {
|
||||
NSArray *array = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
||||
|
||||
if ([array count] > 0) { /* we only want the first item in the list. */
|
||||
NSString *str = [array objectAtIndex:0];
|
||||
const char *base = [str fileSystemRepresentation];
|
||||
if (base) {
|
||||
const size_t len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4;
|
||||
retval = (char *) SDL_malloc(len);
|
||||
if (retval == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
} else {
|
||||
char *ptr;
|
||||
SDL_snprintf(retval, len, "%s/%s/%s/", base, org, app);
|
||||
for (ptr = retval+1; *ptr; ptr++) {
|
||||
if (*ptr == '/') {
|
||||
*ptr = '\0';
|
||||
mkdir(retval, 0700);
|
||||
*ptr = '/';
|
||||
}
|
||||
}
|
||||
mkdir(retval, 0700);
|
||||
}
|
||||
mkdir(retval, 0700);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[pool release];
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
/* This is the iOS implementation of the SDL joystick API */
|
||||
|
||||
#include "SDL_joystick.h"
|
||||
#include "SDL_hints.h"
|
||||
#include "SDL_stdinc.h"
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "../SDL_joystick_c.h"
|
||||
|
@ -32,9 +33,10 @@
|
|||
/* needed for SDL_IPHONE_MAX_GFORCE macro */
|
||||
#import "SDL_config_iphoneos.h"
|
||||
|
||||
const char *accelerometerName = "iOS accelerometer";
|
||||
const char *accelerometerName = "iOS Accelerometer";
|
||||
|
||||
static CMMotionManager *motionManager = nil;
|
||||
static int numjoysticks = 0;
|
||||
|
||||
/* Function to scan the system for joysticks.
|
||||
* This function should set SDL_numjoysticks to the number of available
|
||||
|
@ -44,12 +46,18 @@ static CMMotionManager *motionManager = nil;
|
|||
int
|
||||
SDL_SYS_JoystickInit(void)
|
||||
{
|
||||
return (1);
|
||||
const char *hint = SDL_GetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK);
|
||||
if (!hint || SDL_atoi(hint)) {
|
||||
/* Default behavior, accelerometer as joystick */
|
||||
numjoysticks = 1;
|
||||
}
|
||||
|
||||
return numjoysticks;
|
||||
}
|
||||
|
||||
int SDL_SYS_NumJoysticks()
|
||||
{
|
||||
return 1;
|
||||
return numjoysticks;
|
||||
}
|
||||
|
||||
void SDL_SYS_JoystickDetect()
|
||||
|
@ -82,13 +90,15 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
|||
joystick->nballs = 0;
|
||||
joystick->nbuttons = 0;
|
||||
|
||||
if (motionManager == nil) {
|
||||
motionManager = [[CMMotionManager alloc] init];
|
||||
}
|
||||
@autoreleasepool {
|
||||
if (motionManager == nil) {
|
||||
motionManager = [[CMMotionManager alloc] init];
|
||||
}
|
||||
|
||||
/* Shorter times between updates can significantly increase CPU usage. */
|
||||
motionManager.accelerometerUpdateInterval = 0.1;
|
||||
[motionManager startAccelerometerUpdates];
|
||||
/* Shorter times between updates can significantly increase CPU usage. */
|
||||
motionManager.accelerometerUpdateInterval = 0.1;
|
||||
[motionManager startAccelerometerUpdates];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -105,11 +115,13 @@ static void SDL_SYS_AccelerometerUpdate(SDL_Joystick * joystick)
|
|||
const SInt16 maxsint16 = 0x7FFF;
|
||||
CMAcceleration accel;
|
||||
|
||||
if (!motionManager.accelerometerActive) {
|
||||
return;
|
||||
}
|
||||
@autoreleasepool {
|
||||
if (!motionManager.accelerometerActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
accel = [[motionManager accelerometerData] acceleration];
|
||||
accel = motionManager.accelerometerData.acceleration;
|
||||
}
|
||||
|
||||
/*
|
||||
Convert accelerometer data from floating point to Sint16, which is what
|
||||
|
@ -153,7 +165,9 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
|
|||
void
|
||||
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
||||
{
|
||||
[motionManager stopAccelerometerUpdates];
|
||||
@autoreleasepool {
|
||||
[motionManager stopAccelerometerUpdates];
|
||||
}
|
||||
joystick->closed = 1;
|
||||
}
|
||||
|
||||
|
@ -161,10 +175,11 @@ SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
|||
void
|
||||
SDL_SYS_JoystickQuit(void)
|
||||
{
|
||||
if (motionManager != nil) {
|
||||
[motionManager release];
|
||||
@autoreleasepool {
|
||||
motionManager = nil;
|
||||
}
|
||||
|
||||
numjoysticks = 0;
|
||||
}
|
||||
|
||||
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
|
||||
|
|
|
@ -50,24 +50,24 @@ SDL_UIKit_UpdateBatteryMonitoring(void)
|
|||
SDL_bool
|
||||
SDL_GetPowerInfo_UIKit(SDL_PowerState * state, int *seconds, int *percent)
|
||||
{
|
||||
UIDevice *uidev = [UIDevice currentDevice];
|
||||
@autoreleasepool {
|
||||
UIDevice *uidev = [UIDevice currentDevice];
|
||||
|
||||
if (!SDL_UIKitLastPowerInfoQuery) {
|
||||
SDL_assert([uidev isBatteryMonitoringEnabled] == NO);
|
||||
[uidev setBatteryMonitoringEnabled:YES];
|
||||
}
|
||||
if (!SDL_UIKitLastPowerInfoQuery) {
|
||||
SDL_assert(uidev.isBatteryMonitoringEnabled == NO);
|
||||
uidev.batteryMonitoringEnabled = YES;
|
||||
}
|
||||
|
||||
/* UIKit_GL_SwapWindow() (etc) will check this and disable the battery
|
||||
* monitoring if the app hasn't queried it in the last X seconds.
|
||||
* Apparently monitoring the battery burns battery life. :)
|
||||
* Apple's docs say not to monitor the battery unless you need it.
|
||||
*/
|
||||
SDL_UIKitLastPowerInfoQuery = SDL_GetTicks();
|
||||
/* UIKit_GL_SwapWindow() (etc) will check this and disable the battery
|
||||
* monitoring if the app hasn't queried it in the last X seconds.
|
||||
* Apparently monitoring the battery burns battery life. :)
|
||||
* Apple's docs say not to monitor the battery unless you need it.
|
||||
*/
|
||||
SDL_UIKitLastPowerInfoQuery = SDL_GetTicks();
|
||||
|
||||
*seconds = -1; /* no API to estimate this in UIKit. */
|
||||
*seconds = -1; /* no API to estimate this in UIKit. */
|
||||
|
||||
switch ([uidev batteryState])
|
||||
{
|
||||
switch (uidev.batteryState) {
|
||||
case UIDeviceBatteryStateCharging:
|
||||
*state = SDL_POWERSTATE_CHARGING;
|
||||
break;
|
||||
|
@ -84,11 +84,12 @@ SDL_GetPowerInfo_UIKit(SDL_PowerState * state, int *seconds, int *percent)
|
|||
default:
|
||||
*state = SDL_POWERSTATE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const float level = [uidev batteryLevel];
|
||||
*percent = ( (level < 0.0f) ? -1 : ((int) ((level * 100) + 0.5f)) );
|
||||
return SDL_TRUE; /* always the definitive answer on iOS. */
|
||||
const float level = uidev.batteryLevel;
|
||||
*percent = ( (level < 0.0f) ? -1 : ((int) ((level * 100) + 0.5f)) );
|
||||
return SDL_TRUE; /* always the definitive answer on iOS. */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_POWER_UIKIT */
|
||||
|
|
|
@ -44,7 +44,6 @@ static UIWindow *launch_window;
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
/* store arguments */
|
||||
forward_argc = argc;
|
||||
|
@ -56,7 +55,9 @@ int main(int argc, char **argv)
|
|||
forward_argv[i] = NULL;
|
||||
|
||||
/* Give over control to run loop, SDLUIKitDelegate will handle most things from here */
|
||||
UIApplicationMain(argc, argv, NULL, [SDLUIKitDelegate getAppDelegateClassName]);
|
||||
@autoreleasepool {
|
||||
UIApplicationMain(argc, argv, nil, [SDLUIKitDelegate getAppDelegateClassName]);
|
||||
}
|
||||
|
||||
/* free the memory we used to hold copies of argc and argv */
|
||||
for (i = 0; i < forward_argc; i++) {
|
||||
|
@ -64,7 +65,6 @@ int main(int argc, char **argv)
|
|||
}
|
||||
free(forward_argv);
|
||||
|
||||
[pool release];
|
||||
return exit_status;
|
||||
}
|
||||
|
||||
|
@ -75,17 +75,18 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
|
|||
[UIApplication sharedApplication].idleTimerDisabled = disable;
|
||||
}
|
||||
|
||||
@interface SDL_splashviewcontroller : UIViewController {
|
||||
@interface SDL_splashviewcontroller : UIViewController
|
||||
|
||||
- (void)updateSplashImage:(UIInterfaceOrientation)interfaceOrientation;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SDL_splashviewcontroller {
|
||||
UIImageView *splash;
|
||||
UIImage *splashPortrait;
|
||||
UIImage *splashLandscape;
|
||||
}
|
||||
|
||||
- (void)updateSplashImage:(UIInterfaceOrientation)interfaceOrientation;
|
||||
@end
|
||||
|
||||
@implementation SDL_splashviewcontroller
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
|
@ -93,26 +94,20 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
|
|||
return nil;
|
||||
}
|
||||
|
||||
self->splash = [[UIImageView alloc] init];
|
||||
[self setView:self->splash];
|
||||
splash = [[UIImageView alloc] init];
|
||||
self.view = splash;
|
||||
|
||||
CGSize size = [UIScreen mainScreen].bounds.size;
|
||||
float height = SDL_max(size.width, size.height);
|
||||
self->splashPortrait = [UIImage imageNamed:[NSString stringWithFormat:@"Default-%dh.png", (int)height]];
|
||||
if (!self->splashPortrait) {
|
||||
self->splashPortrait = [UIImage imageNamed:@"Default.png"];
|
||||
splashPortrait = [UIImage imageNamed:[NSString stringWithFormat:@"Default-%dh.png", (int)height]];
|
||||
if (!splashPortrait) {
|
||||
splashPortrait = [UIImage imageNamed:@"Default.png"];
|
||||
}
|
||||
self->splashLandscape = [UIImage imageNamed:@"Default-Landscape.png"];
|
||||
if (!self->splashLandscape && self->splashPortrait) {
|
||||
self->splashLandscape = [[UIImage alloc] initWithCGImage: self->splashPortrait.CGImage
|
||||
scale: 1.0
|
||||
orientation: UIImageOrientationRight];
|
||||
}
|
||||
if (self->splashPortrait) {
|
||||
[self->splashPortrait retain];
|
||||
}
|
||||
if (self->splashLandscape) {
|
||||
[self->splashLandscape retain];
|
||||
splashLandscape = [UIImage imageNamed:@"Default-Landscape.png"];
|
||||
if (!splashLandscape && splashPortrait) {
|
||||
splashLandscape = [[UIImage alloc] initWithCGImage: splashPortrait.CGImage
|
||||
scale: 1.0
|
||||
orientation: UIImageOrientationRight];
|
||||
}
|
||||
|
||||
[self updateSplashImage:[[UIApplication sharedApplication] statusBarOrientation]];
|
||||
|
@ -147,12 +142,12 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
|
|||
UIImage *image;
|
||||
|
||||
if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) {
|
||||
image = self->splashLandscape;
|
||||
image = splashLandscape;
|
||||
} else {
|
||||
image = self->splashPortrait;
|
||||
image = splashPortrait;
|
||||
}
|
||||
if (image)
|
||||
{
|
||||
|
||||
if (image) {
|
||||
splash.image = image;
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +160,7 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
|
|||
/* convenience method */
|
||||
+ (id) sharedAppDelegate
|
||||
{
|
||||
/* the delegate is set in UIApplicationMain(), which is garaunteed to be called before this method */
|
||||
/* the delegate is set in UIApplicationMain(), which is guaranteed to be called before this method */
|
||||
return [[UIApplication sharedApplication] delegate];
|
||||
}
|
||||
|
||||
|
@ -191,8 +186,7 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
|
|||
|
||||
/* If we showed a splash image, clean it up */
|
||||
if (launch_window) {
|
||||
[launch_window release];
|
||||
launch_window = NULL;
|
||||
launch_window = nil;
|
||||
}
|
||||
|
||||
/* exit, passing the return status from the user's application */
|
||||
|
@ -205,12 +199,18 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
|
|||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
/* Keep the launch image up until we set a video mode */
|
||||
launch_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
|
||||
/* This is disabled temporarily because the splash viewcontroller is
|
||||
* interfering with rotation once a regular window is created: the view's
|
||||
* orientations are incorrect and the status bar rotates without the view.
|
||||
* Additionally, the splash viewcontroller doesn't load the correct launch
|
||||
* images on iOS 7 and modern devices. */
|
||||
/*launch_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
|
||||
UIViewController *splashViewController = [[SDL_splashviewcontroller alloc] init];
|
||||
launch_window.rootViewController = splashViewController;
|
||||
[launch_window addSubview:splashViewController.view];
|
||||
[launch_window makeKeyAndVisible];
|
||||
[launch_window makeKeyAndVisible];*/
|
||||
|
||||
/* Set working directory to resource path */
|
||||
[[NSFileManager defaultManager] changeCurrentDirectoryPath: [[NSBundle mainBundle] resourcePath]];
|
||||
|
@ -235,6 +235,35 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
|
|||
SDL_SendAppEvent(SDL_APP_LOWMEMORY);
|
||||
}
|
||||
|
||||
- (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation
|
||||
{
|
||||
BOOL isLandscape = UIInterfaceOrientationIsLandscape(application.statusBarOrientation);
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
|
||||
if (_this && _this->num_displays > 0) {
|
||||
SDL_DisplayMode *desktopmode = &_this->displays[0].desktop_mode;
|
||||
SDL_DisplayMode *currentmode = &_this->displays[0].current_mode;
|
||||
|
||||
/* The desktop display mode should be kept in sync with the screen
|
||||
* orientation so that updating a window's fullscreen state to
|
||||
* SDL_WINDOW_FULLSCREEN_DESKTOP keeps the window dimensions in the
|
||||
* correct orientation.
|
||||
*/
|
||||
if (isLandscape != (desktopmode->w > desktopmode->h)) {
|
||||
int height = desktopmode->w;
|
||||
desktopmode->w = desktopmode->h;
|
||||
desktopmode->h = height;
|
||||
}
|
||||
|
||||
/* Same deal with the current mode + SDL_GetCurrentDisplayMode. */
|
||||
if (isLandscape != (currentmode->w > currentmode->h)) {
|
||||
int height = currentmode->w;
|
||||
currentmode->w = currentmode->h;
|
||||
currentmode->h = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) applicationWillResignActive:(UIApplication*)application
|
||||
{
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
|
|
|
@ -40,8 +40,9 @@ SDL_iPhoneSetEventPump(SDL_bool enabled)
|
|||
void
|
||||
UIKit_PumpEvents(_THIS)
|
||||
{
|
||||
if (!UIKit_EventPumpEnabled)
|
||||
if (!UIKit_EventPumpEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Let the run loop run for a short amount of time: long enough for
|
||||
touch events to get processed (which is important to get certain
|
||||
|
|
|
@ -30,17 +30,16 @@
|
|||
|
||||
static SDL_bool s_showingMessageBox = SDL_FALSE;
|
||||
|
||||
@interface UIKit_UIAlertViewDelegate : NSObject <UIAlertViewDelegate> {
|
||||
@private
|
||||
int *clickedButtonIndex;
|
||||
}
|
||||
@interface UIKit_UIAlertViewDelegate : NSObject <UIAlertViewDelegate>
|
||||
|
||||
- (id)initWithButtonIndex:(int *)_buttonIndex;
|
||||
- (id)initWithButtonIndex:(int *)buttonIndex;
|
||||
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex;
|
||||
|
||||
@end
|
||||
|
||||
@implementation UIKit_UIAlertViewDelegate
|
||||
@implementation UIKit_UIAlertViewDelegate {
|
||||
int *clickedButtonIndex;
|
||||
}
|
||||
|
||||
- (id)initWithButtonIndex:(int *)buttonIndex
|
||||
{
|
||||
|
@ -48,12 +47,13 @@ static SDL_bool s_showingMessageBox = SDL_FALSE;
|
|||
if (self == nil) {
|
||||
return nil;
|
||||
}
|
||||
self->clickedButtonIndex = buttonIndex;
|
||||
|
||||
clickedButtonIndex = buttonIndex;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex;
|
||||
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
*clickedButtonIndex = (int)buttonIndex;
|
||||
}
|
||||
|
@ -71,41 +71,39 @@ int
|
|||
UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
||||
{
|
||||
int clicked;
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
UIAlertView* alert = [[UIAlertView alloc] init];
|
||||
|
||||
alert.title = [NSString stringWithUTF8String:messageboxdata->title];
|
||||
alert.message = [NSString stringWithUTF8String:messageboxdata->message];
|
||||
alert.delegate = [[UIKit_UIAlertViewDelegate alloc] initWithButtonIndex:&clicked];
|
||||
|
||||
const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
|
||||
int i;
|
||||
for (i = 0; i < messageboxdata->numbuttons; ++i) {
|
||||
[alert addButtonWithTitle:[[NSString alloc] initWithUTF8String:buttons[i].text]];
|
||||
const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
|
||||
|
||||
@autoreleasepool {
|
||||
UIAlertView* alert = [[UIAlertView alloc] init];
|
||||
UIKit_UIAlertViewDelegate *delegate = [[UIKit_UIAlertViewDelegate alloc] initWithButtonIndex:&clicked];
|
||||
|
||||
alert.title = @(messageboxdata->title);
|
||||
alert.message = @(messageboxdata->message);
|
||||
alert.delegate = delegate;
|
||||
|
||||
for (i = 0; i < messageboxdata->numbuttons; ++i) {
|
||||
[alert addButtonWithTitle:@(buttons[i].text)];
|
||||
}
|
||||
|
||||
/* Set up for showing the alert */
|
||||
clicked = messageboxdata->numbuttons;
|
||||
|
||||
[alert show];
|
||||
|
||||
/* Run the main event loop until the alert has finished */
|
||||
/* Note that this needs to be done on the main thread */
|
||||
s_showingMessageBox = SDL_TRUE;
|
||||
while (clicked == messageboxdata->numbuttons) {
|
||||
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
|
||||
}
|
||||
s_showingMessageBox = SDL_FALSE;
|
||||
|
||||
*buttonid = messageboxdata->buttons[clicked].buttonid;
|
||||
|
||||
alert.delegate = nil;
|
||||
}
|
||||
|
||||
/* Set up for showing the alert */
|
||||
clicked = messageboxdata->numbuttons;
|
||||
|
||||
[alert show];
|
||||
|
||||
/* Run the main event loop until the alert has finished */
|
||||
/* Note that this needs to be done on the main thread */
|
||||
s_showingMessageBox = SDL_TRUE;
|
||||
while (clicked == messageboxdata->numbuttons) {
|
||||
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
|
||||
}
|
||||
s_showingMessageBox = SDL_FALSE;
|
||||
|
||||
*buttonid = messageboxdata->buttons[clicked].buttonid;
|
||||
|
||||
[alert.delegate release];
|
||||
[alert release];
|
||||
|
||||
[pool release];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,17 +25,17 @@
|
|||
|
||||
#include "SDL_uikitvideo.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UIScreen *uiscreen;
|
||||
CGFloat scale;
|
||||
} SDL_DisplayData;
|
||||
@interface SDL_DisplayData : NSObject
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UIScreenMode *uiscreenmode;
|
||||
CGFloat scale;
|
||||
} SDL_DisplayModeData;
|
||||
@property (nonatomic, strong) UIScreen *uiscreen;
|
||||
|
||||
@end
|
||||
|
||||
@interface SDL_DisplayModeData : NSObject
|
||||
|
||||
@property (nonatomic, strong) UIScreenMode *uiscreenmode;
|
||||
|
||||
@end
|
||||
|
||||
extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen);
|
||||
|
||||
|
|
|
@ -25,27 +25,36 @@
|
|||
#include "SDL_assert.h"
|
||||
#include "SDL_uikitmodes.h"
|
||||
|
||||
@implementation SDL_DisplayData
|
||||
|
||||
@synthesize uiscreen;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SDL_DisplayModeData
|
||||
|
||||
@synthesize uiscreenmode;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
static int
|
||||
UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode,
|
||||
UIScreenMode * uiscreenmode, CGFloat scale)
|
||||
UIScreenMode * uiscreenmode)
|
||||
{
|
||||
SDL_DisplayModeData *data = NULL;
|
||||
SDL_DisplayModeData *data = nil;
|
||||
|
||||
if (uiscreenmode != nil) {
|
||||
/* Allocate the display mode data */
|
||||
data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
|
||||
data = [[SDL_DisplayModeData alloc] init];
|
||||
if (!data) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
data->uiscreenmode = uiscreenmode;
|
||||
[data->uiscreenmode retain];
|
||||
|
||||
data->scale = scale;
|
||||
data.uiscreenmode = uiscreenmode;
|
||||
}
|
||||
|
||||
mode->driverdata = data;
|
||||
mode->driverdata = (void *) CFBridgingRetain(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -54,23 +63,21 @@ static void
|
|||
UIKit_FreeDisplayModeData(SDL_DisplayMode * mode)
|
||||
{
|
||||
if (mode->driverdata != NULL) {
|
||||
SDL_DisplayModeData *data = (SDL_DisplayModeData *)mode->driverdata;
|
||||
[data->uiscreenmode release];
|
||||
SDL_free(data);
|
||||
CFRelease(mode->driverdata);
|
||||
mode->driverdata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h,
|
||||
UIScreenMode * uiscreenmode, CGFloat scale)
|
||||
UIScreenMode * uiscreenmode)
|
||||
{
|
||||
SDL_DisplayMode mode;
|
||||
SDL_zero(mode);
|
||||
|
||||
mode.format = SDL_PIXELFORMAT_ABGR8888;
|
||||
mode.refresh_rate = 0;
|
||||
if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode, scale) < 0) {
|
||||
if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -85,16 +92,16 @@ UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h,
|
|||
}
|
||||
|
||||
static int
|
||||
UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h, CGFloat scale,
|
||||
UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h,
|
||||
UIScreenMode * uiscreenmode, SDL_bool addRotation)
|
||||
{
|
||||
if (UIKit_AddSingleDisplayMode(display, w, h, uiscreenmode, scale) < 0) {
|
||||
if (UIKit_AddSingleDisplayMode(display, w, h, uiscreenmode) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (addRotation) {
|
||||
/* Add the rotated version */
|
||||
if (UIKit_AddSingleDisplayMode(display, h, w, uiscreenmode, scale) < 0) {
|
||||
if (UIKit_AddSingleDisplayMode(display, h, w, uiscreenmode) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -114,24 +121,16 @@ UIKit_AddDisplay(UIScreen *uiscreen)
|
|||
size.height = height;
|
||||
}
|
||||
|
||||
/* When dealing with UIKit all coordinates are specified in terms of
|
||||
* what Apple refers to as points. [UIScreen scale] indicates the
|
||||
* relationship between points and pixels. Since SDL has no notion
|
||||
* of points, we must compensate in all cases where dealing with such
|
||||
* units.
|
||||
*/
|
||||
CGFloat scale = [uiscreen scale];
|
||||
|
||||
SDL_VideoDisplay display;
|
||||
SDL_DisplayMode mode;
|
||||
SDL_zero(mode);
|
||||
mode.format = SDL_PIXELFORMAT_ABGR8888;
|
||||
mode.w = (int)(size.width * scale);
|
||||
mode.h = (int)(size.height * scale);
|
||||
mode.w = (int) size.width;
|
||||
mode.h = (int) size.height;
|
||||
|
||||
UIScreenMode * uiscreenmode = [uiscreen currentMode];
|
||||
UIScreenMode *uiscreenmode = [uiscreen currentMode];
|
||||
|
||||
if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode, scale) < 0) {
|
||||
if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -140,19 +139,18 @@ UIKit_AddDisplay(UIScreen *uiscreen)
|
|||
display.current_mode = mode;
|
||||
|
||||
/* Allocate the display data */
|
||||
SDL_DisplayData *data = (SDL_DisplayData *) SDL_malloc(sizeof(*data));
|
||||
SDL_DisplayData *data = [[SDL_DisplayData alloc] init];
|
||||
if (!data) {
|
||||
UIKit_FreeDisplayModeData(&display.desktop_mode);
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
[uiscreen retain];
|
||||
data->uiscreen = uiscreen;
|
||||
data->scale = scale;
|
||||
data.uiscreen = uiscreen;
|
||||
|
||||
display.driverdata = data;
|
||||
display.driverdata = (void *) CFBridgingRetain(data);
|
||||
SDL_AddVideoDisplay(&display);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -170,9 +168,11 @@ UIKit_IsDisplayLandscape(UIScreen *uiscreen)
|
|||
int
|
||||
UIKit_InitModes(_THIS)
|
||||
{
|
||||
for (UIScreen *uiscreen in [UIScreen screens]) {
|
||||
if (UIKit_AddDisplay(uiscreen) < 0) {
|
||||
return -1;
|
||||
@autoreleasepool {
|
||||
for (UIScreen *uiscreen in [UIScreen screens]) {
|
||||
if (UIKit_AddDisplay(uiscreen) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,34 +182,29 @@ UIKit_InitModes(_THIS)
|
|||
void
|
||||
UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
|
||||
{
|
||||
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
|
||||
@autoreleasepool {
|
||||
SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
|
||||
|
||||
SDL_bool isLandscape = UIKit_IsDisplayLandscape(data->uiscreen);
|
||||
SDL_bool addRotation = (data->uiscreen == [UIScreen mainScreen]);
|
||||
SDL_bool isLandscape = UIKit_IsDisplayLandscape(data.uiscreen);
|
||||
SDL_bool addRotation = (data.uiscreen == [UIScreen mainScreen]);
|
||||
CGFloat scale = data.uiscreen.scale;
|
||||
|
||||
for (UIScreenMode *uimode in [data->uiscreen availableModes]) {
|
||||
CGSize size = [uimode size];
|
||||
int w = (int)size.width;
|
||||
int h = (int)size.height;
|
||||
for (UIScreenMode *uimode in [data.uiscreen availableModes]) {
|
||||
/* The size of a UIScreenMode is in pixels, but we deal exclusively in
|
||||
* points (except in SDL_GL_GetDrawableSize.) */
|
||||
CGSize size = [uimode size];
|
||||
int w = (int)(size.width / scale);
|
||||
int h = (int)(size.height / scale);
|
||||
|
||||
/* Make sure the width/height are oriented correctly */
|
||||
if (isLandscape != (w > h)) {
|
||||
int tmp = w;
|
||||
w = h;
|
||||
h = tmp;
|
||||
}
|
||||
/* Make sure the width/height are oriented correctly */
|
||||
if (isLandscape != (w > h)) {
|
||||
int tmp = w;
|
||||
w = h;
|
||||
h = tmp;
|
||||
}
|
||||
|
||||
/* Add the native screen resolution. */
|
||||
UIKit_AddDisplayMode(display, w, h, data->scale, uimode, addRotation);
|
||||
|
||||
if (data->scale != 1.0f) {
|
||||
/* Add the native screen resolution divided by its scale.
|
||||
* This is so devices capable of e.g. 640x960 also advertise 320x480.
|
||||
*/
|
||||
UIKit_AddDisplayMode(display,
|
||||
(int)(size.width / data->scale),
|
||||
(int)(size.height / data->scale),
|
||||
1.0f, uimode, addRotation);
|
||||
/* Add the native screen resolution. */
|
||||
UIKit_AddDisplayMode(display, w, h, uimode, addRotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -217,19 +212,21 @@ UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
|
|||
int
|
||||
UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
|
||||
{
|
||||
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
|
||||
SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
|
||||
@autoreleasepool {
|
||||
SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
|
||||
SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)mode->driverdata;
|
||||
|
||||
[data->uiscreen setCurrentMode:modedata->uiscreenmode];
|
||||
[data.uiscreen setCurrentMode:modedata.uiscreenmode];
|
||||
|
||||
if (data->uiscreen == [UIScreen mainScreen]) {
|
||||
if (mode->w > mode->h) {
|
||||
if (!UIKit_IsDisplayLandscape(data->uiscreen)) {
|
||||
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
|
||||
}
|
||||
} else if (mode->w < mode->h) {
|
||||
if (UIKit_IsDisplayLandscape(data->uiscreen)) {
|
||||
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
|
||||
if (data.uiscreen == [UIScreen mainScreen]) {
|
||||
if (mode->w > mode->h) {
|
||||
if (!UIKit_IsDisplayLandscape(data.uiscreen)) {
|
||||
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
|
||||
}
|
||||
} else if (mode->w < mode->h) {
|
||||
if (UIKit_IsDisplayLandscape(data.uiscreen)) {
|
||||
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -242,19 +239,21 @@ UIKit_QuitModes(_THIS)
|
|||
{
|
||||
/* Release Objective-C objects, so higher level doesn't free() them. */
|
||||
int i, j;
|
||||
for (i = 0; i < _this->num_displays; i++) {
|
||||
SDL_VideoDisplay *display = &_this->displays[i];
|
||||
@autoreleasepool {
|
||||
for (i = 0; i < _this->num_displays; i++) {
|
||||
SDL_VideoDisplay *display = &_this->displays[i];
|
||||
|
||||
UIKit_FreeDisplayModeData(&display->desktop_mode);
|
||||
for (j = 0; j < display->num_display_modes; j++) {
|
||||
SDL_DisplayMode *mode = &display->display_modes[j];
|
||||
UIKit_FreeDisplayModeData(mode);
|
||||
UIKit_FreeDisplayModeData(&display->desktop_mode);
|
||||
for (j = 0; j < display->num_display_modes; j++) {
|
||||
SDL_DisplayMode *mode = &display->display_modes[j];
|
||||
UIKit_FreeDisplayModeData(mode);
|
||||
}
|
||||
|
||||
if (display->driverdata != NULL) {
|
||||
CFRelease(display->driverdata);
|
||||
display->driverdata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
|
||||
[data->uiscreen release];
|
||||
SDL_free(data);
|
||||
display->driverdata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
extern int UIKit_GL_MakeCurrent(_THIS, SDL_Window * window,
|
||||
SDL_GLContext context);
|
||||
extern void UIKit_GL_GetDrawableSize(_THIS, SDL_Window * window,
|
||||
int * w, int * h);
|
||||
extern void UIKit_GL_SwapWindow(_THIS, SDL_Window * window);
|
||||
extern SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window);
|
||||
extern void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context);
|
||||
|
|
|
@ -49,19 +49,37 @@ UIKit_GL_GetProcAddress(_THIS, const char *proc)
|
|||
/*
|
||||
note that SDL_GL_Delete context makes it current without passing the window
|
||||
*/
|
||||
int UIKit_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
|
||||
int
|
||||
UIKit_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
|
||||
{
|
||||
if (context) {
|
||||
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
|
||||
[data->view setCurrentContext];
|
||||
}
|
||||
else {
|
||||
[EAGLContext setCurrentContext: nil];
|
||||
@autoreleasepool {
|
||||
if (context) {
|
||||
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
|
||||
[data.view setCurrentContext];
|
||||
}
|
||||
else {
|
||||
[EAGLContext setCurrentContext: nil];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UIKit_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
|
||||
{
|
||||
@autoreleasepool {
|
||||
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
|
||||
|
||||
if (w) {
|
||||
*w = data.view.backingWidth;
|
||||
}
|
||||
if (h) {
|
||||
*h = data.view.backingHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
UIKit_GL_LoadLibrary(_THIS, const char *path)
|
||||
{
|
||||
|
@ -78,102 +96,109 @@ UIKit_GL_LoadLibrary(_THIS, const char *path)
|
|||
|
||||
void UIKit_GL_SwapWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
@autoreleasepool {
|
||||
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
|
||||
|
||||
#if SDL_POWER_UIKIT
|
||||
/* Check once a frame to see if we should turn off the battery monitor. */
|
||||
SDL_UIKit_UpdateBatteryMonitoring();
|
||||
/* Check once a frame to see if we should turn off the battery monitor. */
|
||||
SDL_UIKit_UpdateBatteryMonitoring();
|
||||
#endif
|
||||
|
||||
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
|
||||
|
||||
if (nil == data->view) {
|
||||
return;
|
||||
}
|
||||
[data->view swapBuffers];
|
||||
|
||||
/* You need to pump events in order for the OS to make changes visible.
|
||||
We don't pump events here because we don't want iOS application events
|
||||
(low memory, terminate, etc.) to happen inside low level rendering.
|
||||
*/
|
||||
}
|
||||
|
||||
SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_uikitopenglview *view;
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
||||
SDL_DisplayData *displaydata = display->driverdata;
|
||||
SDL_DisplayModeData *displaymodedata = display->current_mode.driverdata;
|
||||
UIWindow *uiwindow = data->uiwindow;
|
||||
EAGLSharegroup *share_group = nil;
|
||||
|
||||
if (_this->gl_config.share_with_current_context) {
|
||||
SDL_uikitopenglview *view = (SDL_uikitopenglview *) SDL_GL_GetCurrentContext();
|
||||
share_group = [view.context sharegroup];
|
||||
}
|
||||
|
||||
/* construct our view, passing in SDL's OpenGL configuration data */
|
||||
CGRect frame;
|
||||
if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
|
||||
frame = [displaydata->uiscreen bounds];
|
||||
} else {
|
||||
frame = [displaydata->uiscreen applicationFrame];
|
||||
}
|
||||
view = [[SDL_uikitopenglview alloc] initWithFrame: frame
|
||||
scale: displaymodedata->scale
|
||||
retainBacking: _this->gl_config.retained_backing
|
||||
rBits: _this->gl_config.red_size
|
||||
gBits: _this->gl_config.green_size
|
||||
bBits: _this->gl_config.blue_size
|
||||
aBits: _this->gl_config.alpha_size
|
||||
depthBits: _this->gl_config.depth_size
|
||||
stencilBits: _this->gl_config.stencil_size
|
||||
majorVersion: _this->gl_config.major_version
|
||||
shareGroup: share_group];
|
||||
if (!view) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data->view = view;
|
||||
view->viewcontroller = data->viewcontroller;
|
||||
if (view->viewcontroller != nil) {
|
||||
[view->viewcontroller setView:view];
|
||||
[view->viewcontroller retain];
|
||||
}
|
||||
[uiwindow addSubview: view];
|
||||
|
||||
/* The view controller needs to be the root in order to control rotation on iOS 6.0 */
|
||||
if (uiwindow.rootViewController == nil) {
|
||||
uiwindow.rootViewController = view->viewcontroller;
|
||||
}
|
||||
|
||||
if (UIKit_GL_MakeCurrent(_this, window, view) < 0) {
|
||||
UIKit_GL_DeleteContext(_this, view);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Make this window the current mouse focus for touch input */
|
||||
if (displaydata->uiscreen == [UIScreen mainScreen]) {
|
||||
SDL_SetMouseFocus(window);
|
||||
SDL_SetKeyboardFocus(window);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context)
|
||||
{
|
||||
/* the delegate has retained the view, this will release him */
|
||||
SDL_uikitopenglview *view = (SDL_uikitopenglview *)context;
|
||||
if (view->viewcontroller) {
|
||||
UIWindow *uiwindow = (UIWindow *)view.superview;
|
||||
if (uiwindow.rootViewController == view->viewcontroller) {
|
||||
uiwindow.rootViewController = nil;
|
||||
if (data.view == nil) {
|
||||
return;
|
||||
}
|
||||
[view->viewcontroller setView:nil];
|
||||
[view->viewcontroller release];
|
||||
[data.view swapBuffers];
|
||||
|
||||
/* You need to pump events in order for the OS to make changes visible.
|
||||
We don't pump events here because we don't want iOS application events
|
||||
(low memory, terminate, etc.) to happen inside low level rendering.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
SDL_GLContext
|
||||
UIKit_GL_CreateContext(_THIS, SDL_Window * window)
|
||||
{
|
||||
@autoreleasepool {
|
||||
SDL_uikitopenglview *view;
|
||||
SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
|
||||
UIWindow *uiwindow = data.uiwindow;
|
||||
CGRect frame = UIKit_ComputeViewFrame(window, uiwindow.screen);
|
||||
EAGLSharegroup *share_group = nil;
|
||||
CGFloat scale = 1.0;
|
||||
|
||||
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
|
||||
/* Set the scale to the natural scale factor of the screen - the backing
|
||||
dimensions of the OpenGL view will match the pixel dimensions of the
|
||||
screen rather than the dimensions in points.
|
||||
*/
|
||||
scale = uiwindow.screen.scale;
|
||||
}
|
||||
|
||||
if (_this->gl_config.share_with_current_context) {
|
||||
SDL_uikitopenglview *view = (__bridge SDL_uikitopenglview *) SDL_GL_GetCurrentContext();
|
||||
share_group = [view.context sharegroup];
|
||||
}
|
||||
|
||||
/* construct our view, passing in SDL's OpenGL configuration data */
|
||||
view = [[SDL_uikitopenglview alloc] initWithFrame: frame
|
||||
scale: scale
|
||||
retainBacking: _this->gl_config.retained_backing
|
||||
rBits: _this->gl_config.red_size
|
||||
gBits: _this->gl_config.green_size
|
||||
bBits: _this->gl_config.blue_size
|
||||
aBits: _this->gl_config.alpha_size
|
||||
depthBits: _this->gl_config.depth_size
|
||||
stencilBits: _this->gl_config.stencil_size
|
||||
sRGB: _this->gl_config.framebuffer_srgb_capable
|
||||
majorVersion: _this->gl_config.major_version
|
||||
shareGroup: share_group];
|
||||
if (!view) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data.view = view;
|
||||
view.viewcontroller = data.viewcontroller;
|
||||
if (view.viewcontroller != nil) {
|
||||
view.viewcontroller.view = view;
|
||||
}
|
||||
[uiwindow addSubview: view];
|
||||
|
||||
/* The view controller needs to be the root in order to control rotation on iOS 6.0 */
|
||||
if (uiwindow.rootViewController == nil) {
|
||||
uiwindow.rootViewController = view.viewcontroller;
|
||||
}
|
||||
|
||||
if (UIKit_GL_MakeCurrent(_this, window, (__bridge SDL_GLContext)(view)) < 0) {
|
||||
UIKit_GL_DeleteContext(_this, (SDL_GLContext) CFBridgingRetain(view));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Make this window the current mouse focus for touch input */
|
||||
if (uiwindow.screen == [UIScreen mainScreen]) {
|
||||
SDL_SetMouseFocus(window);
|
||||
SDL_SetKeyboardFocus(window);
|
||||
}
|
||||
|
||||
return (SDL_GLContext) CFBridgingRetain(view);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UIKit_GL_DeleteContext(_THIS, SDL_GLContext context)
|
||||
{
|
||||
@autoreleasepool {
|
||||
/* the delegate has retained the view, this will release him */
|
||||
SDL_uikitopenglview *view = (SDL_uikitopenglview *)CFBridgingRelease(context);
|
||||
if (view.viewcontroller) {
|
||||
UIWindow *uiwindow = (UIWindow *)view.superview;
|
||||
if (uiwindow.rootViewController == view.viewcontroller) {
|
||||
uiwindow.rootViewController = nil;
|
||||
}
|
||||
view.viewcontroller.view = nil;
|
||||
}
|
||||
[view removeFromSuperview];
|
||||
}
|
||||
[view removeFromSuperview];
|
||||
[view release];
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_UIKIT */
|
||||
|
|
|
@ -29,52 +29,35 @@
|
|||
The view content is basically an EAGL surface you render your OpenGL scene into.
|
||||
Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel.
|
||||
*/
|
||||
@interface SDL_uikitopenglview : SDL_uikitview {
|
||||
@interface SDL_uikitopenglview : SDL_uikitview
|
||||
|
||||
@private
|
||||
/* The pixel dimensions of the backbuffer */
|
||||
GLint backingWidth;
|
||||
GLint backingHeight;
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
scale:(CGFloat)scale
|
||||
retainBacking:(BOOL)retained
|
||||
rBits:(int)rBits
|
||||
gBits:(int)gBits
|
||||
bBits:(int)bBits
|
||||
aBits:(int)aBits
|
||||
depthBits:(int)depthBits
|
||||
stencilBits:(int)stencilBits
|
||||
sRGB:(BOOL)sRGB
|
||||
majorVersion:(int)majorVersion
|
||||
shareGroup:(EAGLSharegroup*)shareGroup;
|
||||
|
||||
EAGLContext *context;
|
||||
@property (nonatomic, strong, readonly) EAGLContext *context;
|
||||
|
||||
/* OpenGL names for the renderbuffer and framebuffers used to render to this view */
|
||||
GLuint viewRenderbuffer, viewFramebuffer;
|
||||
|
||||
/* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */
|
||||
GLuint depthRenderbuffer;
|
||||
|
||||
/* format of depthRenderbuffer */
|
||||
GLenum depthBufferFormat;
|
||||
|
||||
id displayLink;
|
||||
int animationInterval;
|
||||
void (*animationCallback)(void*);
|
||||
void *animationCallbackParam;
|
||||
}
|
||||
|
||||
@property (nonatomic, retain, readonly) EAGLContext *context;
|
||||
/* The width and height of the drawable in pixels (as opposed to points.) */
|
||||
@property (nonatomic, readonly) int backingWidth;
|
||||
@property (nonatomic, readonly) int backingHeight;
|
||||
|
||||
- (void)swapBuffers;
|
||||
- (void)setCurrentContext;
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
scale:(CGFloat)scale
|
||||
retainBacking:(BOOL)retained
|
||||
rBits:(int)rBits
|
||||
gBits:(int)gBits
|
||||
bBits:(int)bBits
|
||||
aBits:(int)aBits
|
||||
depthBits:(int)depthBits
|
||||
stencilBits:(int)stencilBits
|
||||
majorVersion:(int)majorVersion
|
||||
shareGroup:(EAGLSharegroup*)shareGroup;
|
||||
|
||||
- (void)updateFrame;
|
||||
|
||||
- (void)setAnimationCallback:(int)interval
|
||||
callback:(void (*)(void*))callback
|
||||
callbackParam:(void*)callbackParam;
|
||||
callback:(void (*)(void*))callback
|
||||
callbackParam:(void*)callbackParam;
|
||||
|
||||
- (void)startAnimation;
|
||||
- (void)stopAnimation;
|
||||
|
|
|
@ -26,42 +26,73 @@
|
|||
#include <OpenGLES/EAGLDrawable.h>
|
||||
#include "SDL_uikitopenglview.h"
|
||||
#include "SDL_uikitmessagebox.h"
|
||||
#include "SDL_uikitvideo.h"
|
||||
|
||||
|
||||
@implementation SDL_uikitopenglview
|
||||
@implementation SDL_uikitopenglview {
|
||||
|
||||
/* OpenGL names for the renderbuffer and framebuffers used to render to this view */
|
||||
GLuint viewRenderbuffer, viewFramebuffer;
|
||||
|
||||
/* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */
|
||||
GLuint depthRenderbuffer;
|
||||
|
||||
/* format of depthRenderbuffer */
|
||||
GLenum depthBufferFormat;
|
||||
|
||||
id displayLink;
|
||||
int animationInterval;
|
||||
void (*animationCallback)(void*);
|
||||
void *animationCallbackParam;
|
||||
|
||||
}
|
||||
|
||||
@synthesize context;
|
||||
|
||||
@synthesize backingWidth;
|
||||
@synthesize backingHeight;
|
||||
|
||||
+ (Class)layerClass
|
||||
{
|
||||
return [CAEAGLLayer class];
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
scale:(CGFloat)scale
|
||||
scale:(CGFloat)scale
|
||||
retainBacking:(BOOL)retained
|
||||
rBits:(int)rBits
|
||||
gBits:(int)gBits
|
||||
bBits:(int)bBits
|
||||
aBits:(int)aBits
|
||||
depthBits:(int)depthBits
|
||||
stencilBits:(int)stencilBits
|
||||
majorVersion:(int)majorVersion
|
||||
shareGroup:(EAGLSharegroup*)shareGroup
|
||||
rBits:(int)rBits
|
||||
gBits:(int)gBits
|
||||
bBits:(int)bBits
|
||||
aBits:(int)aBits
|
||||
depthBits:(int)depthBits
|
||||
stencilBits:(int)stencilBits
|
||||
sRGB:(BOOL)sRGB
|
||||
majorVersion:(int)majorVersion
|
||||
shareGroup:(EAGLSharegroup*)shareGroup
|
||||
{
|
||||
depthBufferFormat = 0;
|
||||
|
||||
if ((self = [super initWithFrame:frame])) {
|
||||
const BOOL useStencilBuffer = (stencilBits != 0);
|
||||
const BOOL useDepthBuffer = (depthBits != 0);
|
||||
NSString *colorFormat = nil;
|
||||
|
||||
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
self.autoresizesSubviews = YES;
|
||||
|
||||
/* The EAGLRenderingAPI enum values currently map 1:1 to major GLES
|
||||
versions, and this allows us to handle future OpenGL ES versions.
|
||||
*/
|
||||
EAGLRenderingAPI api = majorVersion;
|
||||
|
||||
if (rBits == 8 && gBits == 8 && bBits == 8) {
|
||||
context = [[EAGLContext alloc] initWithAPI:api sharegroup:shareGroup];
|
||||
if (!context || ![EAGLContext setCurrentContext:context]) {
|
||||
SDL_SetError("OpenGL ES %d not supported", majorVersion);
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (sRGB && UIKit_IsSystemVersionAtLeast(@"7.0")) {
|
||||
/* sRGB EAGL drawable support was added in iOS 7 */
|
||||
colorFormat = kEAGLColorFormatSRGBA8;
|
||||
} else if (rBits >= 8 && gBits >= 8 && bBits >= 8) {
|
||||
/* if user specifically requests rbg888 or some color format higher than 16bpp */
|
||||
colorFormat = kEAGLColorFormatRGBA8;
|
||||
} else {
|
||||
|
@ -73,26 +104,28 @@
|
|||
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
|
||||
|
||||
eaglLayer.opaque = YES;
|
||||
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithBool: retained], kEAGLDrawablePropertyRetainedBacking, colorFormat, kEAGLDrawablePropertyColorFormat, nil];
|
||||
|
||||
context = [[EAGLContext alloc] initWithAPI:api sharegroup:shareGroup];
|
||||
if (!context || ![EAGLContext setCurrentContext:context]) {
|
||||
[self release];
|
||||
SDL_SetError("OpenGL ES %d not supported", majorVersion);
|
||||
return nil;
|
||||
}
|
||||
eaglLayer.drawableProperties = @{
|
||||
kEAGLDrawablePropertyRetainedBacking: @(retained),
|
||||
kEAGLDrawablePropertyColorFormat: colorFormat
|
||||
};
|
||||
|
||||
/* Set the appropriate scale (for retina display support) */
|
||||
self.contentScaleFactor = scale;
|
||||
|
||||
/* create the buffers */
|
||||
glGenFramebuffersOES(1, &viewFramebuffer);
|
||||
/* Create the color Renderbuffer Object */
|
||||
glGenRenderbuffersOES(1, &viewRenderbuffer);
|
||||
|
||||
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
|
||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
|
||||
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
|
||||
|
||||
if (![context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:eaglLayer]) {
|
||||
SDL_SetError("Failed creating OpenGL ES drawable");
|
||||
return nil;
|
||||
}
|
||||
|
||||
/* Create the Framebuffer Object */
|
||||
glGenFramebuffersOES(1, &viewFramebuffer);
|
||||
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
|
||||
|
||||
/* attach the color renderbuffer to the FBO */
|
||||
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
|
||||
|
||||
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
|
||||
|
@ -119,15 +152,13 @@
|
|||
}
|
||||
|
||||
if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
|
||||
return NO;
|
||||
SDL_SetError("Failed creating OpenGL ES framebuffer");
|
||||
return nil;
|
||||
}
|
||||
|
||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
|
||||
/* end create buffers */
|
||||
|
||||
self.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
|
||||
self.autoresizesSubviews = YES;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -164,8 +195,9 @@
|
|||
animationCallback = callback;
|
||||
animationCallbackParam = callbackParam;
|
||||
|
||||
if (animationCallback)
|
||||
if (animationCallback) {
|
||||
[self startAnimation];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)startAnimation
|
||||
|
@ -206,18 +238,25 @@
|
|||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
[EAGLContext setCurrentContext:context];
|
||||
[self updateFrame];
|
||||
}
|
||||
|
||||
- (void)destroyFramebuffer
|
||||
{
|
||||
glDeleteFramebuffersOES(1, &viewFramebuffer);
|
||||
viewFramebuffer = 0;
|
||||
glDeleteRenderbuffersOES(1, &viewRenderbuffer);
|
||||
viewRenderbuffer = 0;
|
||||
if (viewFramebuffer != 0) {
|
||||
glDeleteFramebuffersOES(1, &viewFramebuffer);
|
||||
viewFramebuffer = 0;
|
||||
}
|
||||
|
||||
if (depthRenderbuffer) {
|
||||
if (viewRenderbuffer != 0) {
|
||||
glDeleteRenderbuffersOES(1, &viewRenderbuffer);
|
||||
viewRenderbuffer = 0;
|
||||
}
|
||||
|
||||
if (depthRenderbuffer != 0) {
|
||||
glDeleteRenderbuffersOES(1, &depthRenderbuffer);
|
||||
depthRenderbuffer = 0;
|
||||
}
|
||||
|
@ -226,12 +265,10 @@
|
|||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self destroyFramebuffer];
|
||||
if ([EAGLContext currentContext] == context) {
|
||||
[self destroyFramebuffer];
|
||||
[EAGLContext setCurrentContext:nil];
|
||||
}
|
||||
[context release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -25,20 +25,8 @@
|
|||
|
||||
#include "../SDL_sysvideo.h"
|
||||
|
||||
#ifndef __IPHONE_6_0
|
||||
/* This enum isn't available in older SDKs, but we use it for our own purposes on iOS 5.1 and for the system on iOS 6.0 */
|
||||
enum UIInterfaceOrientationMask
|
||||
{
|
||||
UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait),
|
||||
UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft),
|
||||
UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight),
|
||||
UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown),
|
||||
UIInterfaceOrientationMaskLandscape = (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
|
||||
UIInterfaceOrientationMaskAll = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown),
|
||||
UIInterfaceOrientationMaskAllButUpsideDown = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
|
||||
};
|
||||
#endif /* !__IPHONE_6_0 */
|
||||
|
||||
BOOL UIKit_IsSystemVersionAtLeast(NSString *version);
|
||||
CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen);
|
||||
|
||||
#endif /* _SDL_uikitvideo_h */
|
||||
|
||||
|
|
|
@ -78,12 +78,11 @@ UIKit_CreateDevice(int devindex)
|
|||
device->ShowWindow = UIKit_ShowWindow;
|
||||
device->HideWindow = UIKit_HideWindow;
|
||||
device->RaiseWindow = UIKit_RaiseWindow;
|
||||
device->SetWindowBordered = UIKit_SetWindowBordered;
|
||||
device->SetWindowFullscreen = UIKit_SetWindowFullscreen;
|
||||
device->DestroyWindow = UIKit_DestroyWindow;
|
||||
device->GetWindowWMInfo = UIKit_GetWindowWMInfo;
|
||||
|
||||
/* !!! FIXME: implement SetWindowBordered */
|
||||
|
||||
#if SDL_IPHONE_KEYBOARD
|
||||
device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport;
|
||||
device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard;
|
||||
|
@ -93,12 +92,13 @@ UIKit_CreateDevice(int devindex)
|
|||
#endif
|
||||
|
||||
/* OpenGL (ES) functions */
|
||||
device->GL_MakeCurrent = UIKit_GL_MakeCurrent;
|
||||
device->GL_SwapWindow = UIKit_GL_SwapWindow;
|
||||
device->GL_MakeCurrent = UIKit_GL_MakeCurrent;
|
||||
device->GL_GetDrawableSize = UIKit_GL_GetDrawableSize;
|
||||
device->GL_SwapWindow = UIKit_GL_SwapWindow;
|
||||
device->GL_CreateContext = UIKit_GL_CreateContext;
|
||||
device->GL_DeleteContext = UIKit_GL_DeleteContext;
|
||||
device->GL_GetProcAddress = UIKit_GL_GetProcAddress;
|
||||
device->GL_LoadLibrary = UIKit_GL_LoadLibrary;
|
||||
device->GL_LoadLibrary = UIKit_GL_LoadLibrary;
|
||||
device->free = UIKit_DeleteDevice;
|
||||
|
||||
device->gl_config.accelerated = 1;
|
||||
|
@ -129,6 +129,26 @@ UIKit_VideoQuit(_THIS)
|
|||
UIKit_QuitModes(_this);
|
||||
}
|
||||
|
||||
BOOL
|
||||
UIKit_IsSystemVersionAtLeast(NSString *version)
|
||||
{
|
||||
NSString *sysversion = [UIDevice currentDevice].systemVersion;
|
||||
return [sysversion compare:version options:NSNumericSearch] != NSOrderedAscending;
|
||||
}
|
||||
|
||||
CGRect
|
||||
UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen)
|
||||
{
|
||||
BOOL hasiOS7 = UIKit_IsSystemVersionAtLeast(@"7.0");
|
||||
|
||||
if (hasiOS7 || (window->flags & (SDL_WINDOW_BORDERLESS|SDL_WINDOW_FULLSCREEN))) {
|
||||
/* The view should always show behind the status bar in iOS 7+. */
|
||||
return screen.bounds;
|
||||
} else {
|
||||
return screen.applicationFrame;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* iOS log support.
|
||||
*
|
||||
|
|
|
@ -31,27 +31,13 @@
|
|||
#endif
|
||||
|
||||
#if SDL_IPHONE_KEYBOARD
|
||||
@interface SDL_uikitview : UIView<UITextFieldDelegate> {
|
||||
@interface SDL_uikitview : UIView <UITextFieldDelegate>
|
||||
#else
|
||||
@interface SDL_uikitview : UIView {
|
||||
@interface SDL_uikitview : UIView
|
||||
#endif
|
||||
|
||||
SDL_TouchID touchId;
|
||||
UITouch *leftFingerDown;
|
||||
#ifndef IPHONE_TOUCH_EFFICIENT_DANGEROUS
|
||||
UITouch *finger[MAX_SIMULTANEOUS_TOUCHES];
|
||||
#endif
|
||||
@property (nonatomic, weak) SDL_uikitviewcontroller *viewcontroller;
|
||||
|
||||
#if SDL_IPHONE_KEYBOARD
|
||||
UITextField *textField;
|
||||
BOOL keyboardVisible;
|
||||
SDL_Rect textInputRect;
|
||||
int keyboardHeight;
|
||||
#endif
|
||||
|
||||
@public
|
||||
SDL_uikitviewcontroller *viewcontroller;
|
||||
}
|
||||
- (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize;
|
||||
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
|
||||
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
|
||||
|
@ -61,9 +47,10 @@
|
|||
- (void)showKeyboard;
|
||||
- (void)hideKeyboard;
|
||||
- (void)initializeKeyboard;
|
||||
@property (readonly) BOOL keyboardVisible;
|
||||
@property (nonatomic,assign) SDL_Rect textInputRect;
|
||||
@property (nonatomic,assign) int keyboardHeight;
|
||||
|
||||
@property (nonatomic, assign, getter=isKeyboardVisible) BOOL keyboardVisible;
|
||||
@property (nonatomic, assign) SDL_Rect textInputRect;
|
||||
@property (nonatomic, assign) int keyboardHeight;
|
||||
|
||||
SDL_bool UIKit_HasScreenKeyboardSupport(_THIS);
|
||||
void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window);
|
||||
|
|
|
@ -35,27 +35,36 @@
|
|||
#include "SDL_uikitmodes.h"
|
||||
#include "SDL_uikitwindow.h"
|
||||
|
||||
void _uikit_keyboard_init() ;
|
||||
void _uikit_keyboard_init();
|
||||
|
||||
@implementation SDL_uikitview
|
||||
@implementation SDL_uikitview {
|
||||
|
||||
SDL_TouchID touchId;
|
||||
UITouch *leftFingerDown;
|
||||
#ifndef IPHONE_TOUCH_EFFICIENT_DANGEROUS
|
||||
UITouch *finger[MAX_SIMULTANEOUS_TOUCHES];
|
||||
#endif
|
||||
|
||||
#if SDL_IPHONE_KEYBOARD
|
||||
UITextField *textField;
|
||||
#endif
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@synthesize viewcontroller;
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame: frame];
|
||||
|
||||
if (self = [super initWithFrame: frame]) {
|
||||
#if SDL_IPHONE_KEYBOARD
|
||||
[self initializeKeyboard];
|
||||
[self initializeKeyboard];
|
||||
#endif
|
||||
|
||||
self.multipleTouchEnabled = YES;
|
||||
self.multipleTouchEnabled = YES;
|
||||
|
||||
touchId = 1;
|
||||
SDL_AddTouch(touchId, "");
|
||||
touchId = 1;
|
||||
SDL_AddTouch(touchId, "");
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||
|
@ -65,36 +74,26 @@ void _uikit_keyboard_init() ;
|
|||
{
|
||||
CGPoint point = [touch locationInView: self];
|
||||
|
||||
/* Get the display scale and apply that to the input coordinates */
|
||||
SDL_Window *window = self->viewcontroller.window;
|
||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
||||
SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata;
|
||||
|
||||
if (normalize) {
|
||||
CGRect bounds = [self bounds];
|
||||
CGRect bounds = self.bounds;
|
||||
point.x /= bounds.size.width;
|
||||
point.y /= bounds.size.height;
|
||||
} else {
|
||||
point.x *= displaymodedata->scale;
|
||||
point.y *= displaymodedata->scale;
|
||||
}
|
||||
|
||||
return point;
|
||||
}
|
||||
|
||||
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
NSEnumerator *enumerator = [touches objectEnumerator];
|
||||
UITouch *touch = (UITouch*)[enumerator nextObject];
|
||||
|
||||
while (touch) {
|
||||
for (UITouch *touch in touches) {
|
||||
if (!leftFingerDown) {
|
||||
CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
|
||||
|
||||
/* send moved event */
|
||||
SDL_SendMouseMotion(self->viewcontroller.window, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
|
||||
SDL_SendMouseMotion(self.viewcontroller.window, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
|
||||
|
||||
/* send mouse down event */
|
||||
SDL_SendMouseButton(self->viewcontroller.window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
|
||||
SDL_SendMouseButton(self.viewcontroller.window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
|
||||
|
||||
leftFingerDown = touch;
|
||||
}
|
||||
|
@ -118,25 +117,21 @@ void _uikit_keyboard_init() ;
|
|||
}
|
||||
}
|
||||
#endif
|
||||
touch = (UITouch*)[enumerator nextObject];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
NSEnumerator *enumerator = [touches objectEnumerator];
|
||||
UITouch *touch = (UITouch*)[enumerator nextObject];
|
||||
|
||||
while(touch) {
|
||||
for (UITouch *touch in touches) {
|
||||
if (touch == leftFingerDown) {
|
||||
/* send mouse up */
|
||||
SDL_SendMouseButton(self->viewcontroller.window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
|
||||
SDL_SendMouseButton(self.viewcontroller.window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
|
||||
leftFingerDown = nil;
|
||||
}
|
||||
|
||||
CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
|
||||
#ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
|
||||
SDL_SendTouch(touchId, (long)touch,
|
||||
SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch),
|
||||
SDL_FALSE, locationInView.x, locationInView.y, 1.0f);
|
||||
#else
|
||||
int i;
|
||||
|
@ -149,7 +144,6 @@ void _uikit_keyboard_init() ;
|
|||
}
|
||||
}
|
||||
#endif
|
||||
touch = (UITouch*)[enumerator nextObject];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,20 +159,17 @@ void _uikit_keyboard_init() ;
|
|||
|
||||
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
NSEnumerator *enumerator = [touches objectEnumerator];
|
||||
UITouch *touch = (UITouch*)[enumerator nextObject];
|
||||
|
||||
while (touch) {
|
||||
for (UITouch *touch in touches) {
|
||||
if (touch == leftFingerDown) {
|
||||
CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
|
||||
|
||||
/* send moved event */
|
||||
SDL_SendMouseMotion(self->viewcontroller.window, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
|
||||
SDL_SendMouseMotion(self.viewcontroller.window, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
|
||||
}
|
||||
|
||||
CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
|
||||
#ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
|
||||
SDL_SendTouchMotion(touchId, (long)touch,
|
||||
SDL_SendTouchMotion(touchId, (SDL_FingerID)((size_t)touch),
|
||||
locationInView.x, locationInView.y, 1.0f);
|
||||
#else
|
||||
int i;
|
||||
|
@ -190,7 +181,6 @@ void _uikit_keyboard_init() ;
|
|||
}
|
||||
}
|
||||
#endif
|
||||
touch = (UITouch*)[enumerator nextObject];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,14 +189,9 @@ void _uikit_keyboard_init() ;
|
|||
*/
|
||||
#if SDL_IPHONE_KEYBOARD
|
||||
|
||||
@synthesize textInputRect = textInputRect;
|
||||
@synthesize keyboardHeight = keyboardHeight;
|
||||
|
||||
/* Is the iPhone virtual keyboard visible onscreen? */
|
||||
- (BOOL)keyboardVisible
|
||||
{
|
||||
return keyboardVisible;
|
||||
}
|
||||
@synthesize textInputRect;
|
||||
@synthesize keyboardHeight;
|
||||
@synthesize keyboardVisible;
|
||||
|
||||
/* Set ourselves up as a UITextFieldDelegate */
|
||||
- (void)initializeKeyboard
|
||||
|
@ -229,7 +214,6 @@ void _uikit_keyboard_init() ;
|
|||
keyboardVisible = NO;
|
||||
/* add the UITextField (hidden) to our view */
|
||||
[self addSubview: textField];
|
||||
[textField release];
|
||||
|
||||
_uikit_keyboard_init();
|
||||
}
|
||||
|
@ -318,8 +302,8 @@ static SDL_uikitview * getWindowView(SDL_Window * window)
|
|||
return nil;
|
||||
}
|
||||
|
||||
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
|
||||
SDL_uikitview *view = data != NULL ? data->view : nil;
|
||||
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
|
||||
SDL_uikitview *view = data != nil ? data.view : nil;
|
||||
|
||||
if (view == nil) {
|
||||
SDL_SetError("Window has no view");
|
||||
|
@ -335,44 +319,49 @@ SDL_bool UIKit_HasScreenKeyboardSupport(_THIS)
|
|||
|
||||
void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window)
|
||||
{
|
||||
SDL_uikitview *view = getWindowView(window);
|
||||
if (view != nil) {
|
||||
[view showKeyboard];
|
||||
@autoreleasepool {
|
||||
SDL_uikitview *view = getWindowView(window);
|
||||
if (view != nil) {
|
||||
[view showKeyboard];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window)
|
||||
{
|
||||
SDL_uikitview *view = getWindowView(window);
|
||||
if (view != nil) {
|
||||
[view hideKeyboard];
|
||||
@autoreleasepool {
|
||||
SDL_uikitview *view = getWindowView(window);
|
||||
if (view != nil) {
|
||||
[view hideKeyboard];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window)
|
||||
{
|
||||
SDL_uikitview *view = getWindowView(window);
|
||||
if (view == nil) {
|
||||
return 0;
|
||||
}
|
||||
@autoreleasepool {
|
||||
SDL_uikitview *view = getWindowView(window);
|
||||
if (view == nil) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return view.keyboardVisible;
|
||||
return view.isKeyboardVisible;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _uikit_keyboard_update() {
|
||||
SDL_Window *window = SDL_GetFocusWindow();
|
||||
if (!window) { return; }
|
||||
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
|
||||
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
|
||||
if (!data) { return; }
|
||||
SDL_uikitview *view = data->view;
|
||||
SDL_uikitview *view = data.view;
|
||||
if (!view) { return; }
|
||||
|
||||
|
||||
SDL_Rect r = view.textInputRect;
|
||||
int height = view.keyboardHeight;
|
||||
int offsetx = 0;
|
||||
int offsety = 0;
|
||||
float scale = [UIScreen mainScreen].scale;
|
||||
if (height) {
|
||||
int sw,sh;
|
||||
SDL_GetWindowSize(window,&sw,&sh);
|
||||
|
@ -394,18 +383,16 @@ void _uikit_keyboard_update() {
|
|||
offsety = -offsety;
|
||||
}
|
||||
|
||||
offsetx /= scale;
|
||||
offsety /= scale;
|
||||
|
||||
view.frame = CGRectMake(offsetx,offsety,view.frame.size.width,view.frame.size.height);
|
||||
}
|
||||
|
||||
void _uikit_keyboard_set_height(int height) {
|
||||
SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
|
||||
if (view == nil) {
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
view.keyboardVisible = height > 0;
|
||||
view.keyboardHeight = height;
|
||||
_uikit_keyboard_update();
|
||||
}
|
||||
|
@ -418,13 +405,12 @@ void _uikit_keyboard_init() {
|
|||
queue:queue
|
||||
usingBlock:^(NSNotification *notification) {
|
||||
int height = 0;
|
||||
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
|
||||
CGSize keyboardSize = [[notification userInfo][UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
|
||||
height = keyboardSize.height;
|
||||
UIInterfaceOrientation ui_orient = [[UIApplication sharedApplication] statusBarOrientation];
|
||||
if (ui_orient == UIInterfaceOrientationLandscapeRight || ui_orient == UIInterfaceOrientationLandscapeLeft) {
|
||||
height = keyboardSize.width;
|
||||
}
|
||||
height *= [UIScreen mainScreen].scale;
|
||||
_uikit_keyboard_set_height(height);
|
||||
}
|
||||
];
|
||||
|
@ -444,13 +430,15 @@ UIKit_SetTextInputRect(_THIS, SDL_Rect *rect)
|
|||
SDL_InvalidParamError("rect");
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
|
||||
if (view == nil) {
|
||||
return ;
|
||||
}
|
||||
|
||||
view.textInputRect = *rect;
|
||||
@autoreleasepool {
|
||||
SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
|
||||
if (view == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
view.textInputRect = *rect;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -23,12 +23,9 @@
|
|||
|
||||
#include "../SDL_sysvideo.h"
|
||||
|
||||
@interface SDL_uikitviewcontroller : UIViewController {
|
||||
@private
|
||||
SDL_Window *window;
|
||||
}
|
||||
@interface SDL_uikitviewcontroller : UIViewController
|
||||
|
||||
@property (readwrite) SDL_Window *window;
|
||||
@property (nonatomic, assign) SDL_Window *window;
|
||||
|
||||
- (id)initWithSDLWindow:(SDL_Window *)_window;
|
||||
- (void)loadView;
|
||||
|
@ -36,5 +33,6 @@
|
|||
- (NSUInteger)supportedInterfaceOrientations;
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient;
|
||||
- (BOOL)prefersStatusBarHidden;
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle;
|
||||
|
||||
@end
|
||||
|
|
|
@ -40,12 +40,9 @@
|
|||
|
||||
- (id)initWithSDLWindow:(SDL_Window *)_window
|
||||
{
|
||||
self = [self init];
|
||||
if (self == nil) {
|
||||
return nil;
|
||||
if (self = [super initWithNibName:nil bundle:nil]) {
|
||||
self.window = _window;
|
||||
}
|
||||
self.window = _window;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -56,31 +53,20 @@
|
|||
|
||||
- (void)viewDidLayoutSubviews
|
||||
{
|
||||
if (self->window->flags & SDL_WINDOW_RESIZABLE) {
|
||||
SDL_WindowData *data = self->window->driverdata;
|
||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(self->window);
|
||||
SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata;
|
||||
const CGSize size = data->view.bounds.size;
|
||||
int w, h;
|
||||
const CGSize size = self.view.bounds.size;
|
||||
int w = (int) size.width;
|
||||
int h = (int) size.height;
|
||||
|
||||
w = (int)(size.width * displaymodedata->scale);
|
||||
h = (int)(size.height * displaymodedata->scale);
|
||||
|
||||
SDL_SendWindowEvent(self->window, SDL_WINDOWEVENT_RESIZED, w, h);
|
||||
}
|
||||
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h);
|
||||
}
|
||||
|
||||
- (NSUInteger)supportedInterfaceOrientations
|
||||
{
|
||||
NSUInteger orientationMask = 0;
|
||||
const char *hint = SDL_GetHint(SDL_HINT_ORIENTATIONS);
|
||||
|
||||
const char *orientationsCString;
|
||||
if ((orientationsCString = SDL_GetHint(SDL_HINT_ORIENTATIONS)) != NULL) {
|
||||
BOOL rotate = NO;
|
||||
NSString *orientationsNSString = [NSString stringWithCString:orientationsCString
|
||||
encoding:NSUTF8StringEncoding];
|
||||
NSArray *orientations = [orientationsNSString componentsSeparatedByCharactersInSet:
|
||||
[NSCharacterSet characterSetWithCharactersInString:@" "]];
|
||||
if (hint != NULL) {
|
||||
NSArray *orientations = [@(hint) componentsSeparatedByString:@" "];
|
||||
|
||||
if ([orientations containsObject:@"LandscapeLeft"]) {
|
||||
orientationMask |= UIInterfaceOrientationMaskLandscapeLeft;
|
||||
|
@ -94,14 +80,17 @@
|
|||
if ([orientations containsObject:@"PortraitUpsideDown"]) {
|
||||
orientationMask |= UIInterfaceOrientationMaskPortraitUpsideDown;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (self->window->flags & SDL_WINDOW_RESIZABLE) {
|
||||
if (orientationMask == 0 && (window->flags & SDL_WINDOW_RESIZABLE)) {
|
||||
orientationMask = UIInterfaceOrientationMaskAll; /* any orientation is okay. */
|
||||
} else {
|
||||
if (self->window->w >= self->window->h) {
|
||||
}
|
||||
|
||||
if (orientationMask == 0) {
|
||||
if (window->w >= window->h) {
|
||||
orientationMask |= UIInterfaceOrientationMaskLandscape;
|
||||
}
|
||||
if (self->window->h >= self->window->w) {
|
||||
if (window->h >= window->w) {
|
||||
orientationMask |= (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
|
||||
}
|
||||
}
|
||||
|
@ -121,13 +110,19 @@
|
|||
|
||||
- (BOOL)prefersStatusBarHidden
|
||||
{
|
||||
if (self->window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
|
||||
if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
|
||||
return YES;
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle
|
||||
{
|
||||
/* We assume most games don't have a bright white background. */
|
||||
return UIStatusBarStyleLightContent;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_UIKIT */
|
||||
|
|
|
@ -26,12 +26,11 @@
|
|||
#import "SDL_uikitopenglview.h"
|
||||
#import "SDL_uikitviewcontroller.h"
|
||||
|
||||
typedef struct SDL_WindowData SDL_WindowData;
|
||||
|
||||
extern int UIKit_CreateWindow(_THIS, SDL_Window * window);
|
||||
extern void UIKit_ShowWindow(_THIS, SDL_Window * window);
|
||||
extern void UIKit_HideWindow(_THIS, SDL_Window * window);
|
||||
extern void UIKit_RaiseWindow(_THIS, SDL_Window * window);
|
||||
extern void UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
|
||||
extern void UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
|
||||
extern void UIKit_DestroyWindow(_THIS, SDL_Window * window);
|
||||
extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window,
|
||||
|
@ -39,12 +38,17 @@ extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window,
|
|||
|
||||
@class UIWindow;
|
||||
|
||||
struct SDL_WindowData
|
||||
{
|
||||
UIWindow *uiwindow;
|
||||
SDL_uikitopenglview *view;
|
||||
SDL_uikitviewcontroller *viewcontroller;
|
||||
};
|
||||
@interface SDL_uikitwindow : UIWindow
|
||||
|
||||
@end
|
||||
|
||||
@interface SDL_WindowData : NSObject
|
||||
|
||||
@property (nonatomic, strong) SDL_uikitwindow *uiwindow;
|
||||
@property (nonatomic, strong) SDL_uikitopenglview *view;
|
||||
@property (nonatomic, strong) SDL_uikitviewcontroller *viewcontroller;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* _SDL_uikitwindow_h */
|
||||
|
||||
|
|
|
@ -41,43 +41,56 @@
|
|||
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
@implementation SDL_uikitwindow
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
/* This seems to be needed on iOS 8, otherwise the window's frame is put in
|
||||
* an unexpected position when the screen or device is rotated.
|
||||
* FIXME: is there a better solution to that problem than this ugly hack?
|
||||
*/
|
||||
self.frame = self.screen.bounds;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation SDL_WindowData
|
||||
|
||||
@synthesize uiwindow;
|
||||
@synthesize view;
|
||||
@synthesize viewcontroller;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created)
|
||||
static int SetupWindowData(_THIS, SDL_Window *window, SDL_uikitwindow *uiwindow, SDL_bool created)
|
||||
{
|
||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
||||
SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata;
|
||||
SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
|
||||
SDL_WindowData *data;
|
||||
SDL_DisplayData *displaydata = (__bridge SDL_DisplayData *) display->driverdata;
|
||||
|
||||
/* Allocate the window data */
|
||||
data = (SDL_WindowData *)SDL_malloc(sizeof(*data));
|
||||
SDL_WindowData *data = [[SDL_WindowData alloc] init];
|
||||
if (!data) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
data->uiwindow = uiwindow;
|
||||
data->viewcontroller = nil;
|
||||
data->view = nil;
|
||||
|
||||
data.uiwindow = uiwindow;
|
||||
|
||||
/* Fill in the SDL window with the window data */
|
||||
{
|
||||
window->x = 0;
|
||||
window->y = 0;
|
||||
|
||||
CGRect bounds;
|
||||
if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
|
||||
bounds = [displaydata->uiscreen bounds];
|
||||
} else {
|
||||
bounds = [displaydata->uiscreen applicationFrame];
|
||||
}
|
||||
CGRect frame = UIKit_ComputeViewFrame(window, displaydata.uiscreen);
|
||||
|
||||
/* Get frame dimensions in pixels */
|
||||
int width = (int)(bounds.size.width * displaymodedata->scale);
|
||||
int height = (int)(bounds.size.height * displaymodedata->scale);
|
||||
/* Get frame dimensions */
|
||||
int width = (int) frame.size.width;
|
||||
int height = (int) frame.size.height;
|
||||
|
||||
/* Make sure the width/height are oriented correctly */
|
||||
if (UIKit_IsDisplayLandscape(displaydata->uiscreen) != (width > height)) {
|
||||
if (UIKit_IsDisplayLandscape(displaydata.uiscreen) != (width > height)) {
|
||||
int temp = width;
|
||||
width = height;
|
||||
height = temp;
|
||||
|
@ -87,7 +100,7 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
|
|||
window->h = height;
|
||||
}
|
||||
|
||||
window->driverdata = data;
|
||||
window->driverdata = (void *) CFBridgingRetain(data);
|
||||
|
||||
/* only one window on iOS, always shown */
|
||||
window->flags &= ~SDL_WINDOW_HIDDEN;
|
||||
|
@ -96,7 +109,7 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
|
|||
* This is only set if the window is on the main screen. Other screens
|
||||
* just force the window to have the borderless flag.
|
||||
*/
|
||||
if (displaydata->uiscreen == [UIScreen mainScreen]) {
|
||||
if (displaydata.uiscreen == [UIScreen mainScreen]) {
|
||||
window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */
|
||||
|
||||
/* This was setup earlier for our window, and in iOS 7 is controlled by the view, not the application
|
||||
|
@ -116,10 +129,8 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
|
|||
* device orientation changes. This will trigger resize events, if
|
||||
* appropriate.
|
||||
*/
|
||||
SDL_uikitviewcontroller *controller;
|
||||
controller = [SDL_uikitviewcontroller alloc];
|
||||
data->viewcontroller = [controller initWithSDLWindow:window];
|
||||
[data->viewcontroller setTitle:@"SDL App"]; /* !!! FIXME: hook up SDL_SetWindowTitle() */
|
||||
data.viewcontroller = [[SDL_uikitviewcontroller alloc] initWithSDLWindow:window];
|
||||
data.viewcontroller.title = @"SDL App"; /* !!! FIXME: hook up SDL_SetWindowTitle() */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -127,105 +138,109 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
|
|||
int
|
||||
UIKit_CreateWindow(_THIS, SDL_Window *window)
|
||||
{
|
||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
||||
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
|
||||
const BOOL external = ([UIScreen mainScreen] != data->uiscreen);
|
||||
const CGSize origsize = [[data->uiscreen currentMode] size];
|
||||
@autoreleasepool {
|
||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
||||
SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
|
||||
const BOOL external = ([UIScreen mainScreen] != data.uiscreen);
|
||||
const CGSize origsize = [[data.uiscreen currentMode] size];
|
||||
|
||||
/* SDL currently puts this window at the start of display's linked list. We rely on this. */
|
||||
SDL_assert(_this->windows == window);
|
||||
/* SDL currently puts this window at the start of display's linked list. We rely on this. */
|
||||
SDL_assert(_this->windows == window);
|
||||
|
||||
/* We currently only handle a single window per display on iOS */
|
||||
if (window->next != NULL) {
|
||||
return SDL_SetError("Only one window allowed per display.");
|
||||
}
|
||||
|
||||
/* If monitor has a resolution of 0x0 (hasn't been explicitly set by the
|
||||
* user, so it's in standby), try to force the display to a resolution
|
||||
* that most closely matches the desired window size.
|
||||
*/
|
||||
if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) {
|
||||
if (display->num_display_modes == 0) {
|
||||
_this->GetDisplayModes(_this, display);
|
||||
/* We currently only handle a single window per display on iOS */
|
||||
if (window->next != NULL) {
|
||||
return SDL_SetError("Only one window allowed per display.");
|
||||
}
|
||||
|
||||
int i;
|
||||
const SDL_DisplayMode *bestmode = NULL;
|
||||
for (i = display->num_display_modes; i >= 0; i--) {
|
||||
const SDL_DisplayMode *mode = &display->display_modes[i];
|
||||
if ((mode->w >= window->w) && (mode->h >= window->h))
|
||||
bestmode = mode;
|
||||
}
|
||||
|
||||
if (bestmode) {
|
||||
SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)bestmode->driverdata;
|
||||
[data->uiscreen setCurrentMode:modedata->uiscreenmode];
|
||||
|
||||
/* desktop_mode doesn't change here (the higher level will
|
||||
* use it to set all the screens back to their defaults
|
||||
* upon window destruction, SDL_Quit(), etc.
|
||||
*/
|
||||
display->current_mode = *bestmode;
|
||||
}
|
||||
}
|
||||
|
||||
if (data->uiscreen == [UIScreen mainScreen]) {
|
||||
if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
|
||||
[UIApplication sharedApplication].statusBarHidden = YES;
|
||||
} else {
|
||||
[UIApplication sharedApplication].statusBarHidden = NO;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
|
||||
if (window->w > window->h) {
|
||||
if (!UIKit_IsDisplayLandscape(data->uiscreen)) {
|
||||
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
|
||||
/* If monitor has a resolution of 0x0 (hasn't been explicitly set by the
|
||||
* user, so it's in standby), try to force the display to a resolution
|
||||
* that most closely matches the desired window size.
|
||||
*/
|
||||
if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) {
|
||||
if (display->num_display_modes == 0) {
|
||||
_this->GetDisplayModes(_this, display);
|
||||
}
|
||||
} else if (window->w < window->h) {
|
||||
if (UIKit_IsDisplayLandscape(data->uiscreen)) {
|
||||
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
|
||||
|
||||
int i;
|
||||
const SDL_DisplayMode *bestmode = NULL;
|
||||
for (i = display->num_display_modes; i >= 0; i--) {
|
||||
const SDL_DisplayMode *mode = &display->display_modes[i];
|
||||
if ((mode->w >= window->w) && (mode->h >= window->h))
|
||||
bestmode = mode;
|
||||
}
|
||||
|
||||
if (bestmode) {
|
||||
SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)bestmode->driverdata;
|
||||
[data.uiscreen setCurrentMode:modedata.uiscreenmode];
|
||||
|
||||
/* desktop_mode doesn't change here (the higher level will
|
||||
* use it to set all the screens back to their defaults
|
||||
* upon window destruction, SDL_Quit(), etc.
|
||||
*/
|
||||
display->current_mode = *bestmode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ignore the size user requested, and make a fullscreen window */
|
||||
/* !!! FIXME: can we have a smaller view? */
|
||||
UIWindow *uiwindow = [UIWindow alloc];
|
||||
uiwindow = [uiwindow initWithFrame:[data->uiscreen bounds]];
|
||||
if (data.uiscreen == [UIScreen mainScreen]) {
|
||||
if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
|
||||
[UIApplication sharedApplication].statusBarHidden = YES;
|
||||
} else {
|
||||
[UIApplication sharedApplication].statusBarHidden = NO;
|
||||
}
|
||||
}
|
||||
|
||||
/* put the window on an external display if appropriate. This implicitly
|
||||
* does [uiwindow setframe:[uiscreen bounds]], so don't do it on the
|
||||
* main display, where we land by default, as that would eat the
|
||||
* status bar real estate.
|
||||
*/
|
||||
if (external) {
|
||||
[uiwindow setScreen:data->uiscreen];
|
||||
}
|
||||
if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
|
||||
if (window->w > window->h) {
|
||||
if (!UIKit_IsDisplayLandscape(data.uiscreen)) {
|
||||
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
|
||||
}
|
||||
} else if (window->w < window->h) {
|
||||
if (UIKit_IsDisplayLandscape(data.uiscreen)) {
|
||||
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ignore the size user requested, and make a fullscreen window */
|
||||
/* !!! FIXME: can we have a smaller view? */
|
||||
SDL_uikitwindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data.uiscreen.bounds];
|
||||
|
||||
/* put the window on an external display if appropriate. This implicitly
|
||||
* does [uiwindow setframe:[uiscreen bounds]], so don't do it on the
|
||||
* main display, where we land by default, as that would eat the
|
||||
* status bar real estate.
|
||||
*/
|
||||
if (external) {
|
||||
[uiwindow setScreen:data.uiscreen];
|
||||
}
|
||||
|
||||
if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
|
||||
[uiwindow release];
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
UIKit_ShowWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
|
||||
@autoreleasepool {
|
||||
UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow;
|
||||
|
||||
[uiwindow makeKeyAndVisible];
|
||||
[uiwindow makeKeyAndVisible];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UIKit_HideWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
|
||||
@autoreleasepool {
|
||||
UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow;
|
||||
|
||||
uiwindow.hidden = YES;
|
||||
uiwindow.hidden = YES;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -239,91 +254,106 @@ UIKit_RaiseWindow(_THIS, SDL_Window * window)
|
|||
_this->GL_MakeCurrent(_this, _this->current_glwin, _this->current_glctx);
|
||||
}
|
||||
|
||||
static void
|
||||
UIKit_UpdateWindowBorder(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_WindowData *windowdata = (__bridge SDL_WindowData *) window->driverdata;
|
||||
SDL_uikitviewcontroller *viewcontroller = windowdata.viewcontroller;
|
||||
CGRect frame;
|
||||
|
||||
if (windowdata.uiwindow.screen == [UIScreen mainScreen]) {
|
||||
if (window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS)) {
|
||||
[UIApplication sharedApplication].statusBarHidden = YES;
|
||||
} else {
|
||||
[UIApplication sharedApplication].statusBarHidden = NO;
|
||||
}
|
||||
|
||||
/* iOS 7+ won't update the status bar until we tell it to. */
|
||||
if ([viewcontroller respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) {
|
||||
[viewcontroller setNeedsStatusBarAppearanceUpdate];
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the view's frame to account for the status bar change. */
|
||||
frame = UIKit_ComputeViewFrame(window, windowdata.uiwindow.screen);
|
||||
|
||||
windowdata.view.frame = frame;
|
||||
[windowdata.view setNeedsLayout];
|
||||
[windowdata.view layoutIfNeeded];
|
||||
|
||||
/* Get frame dimensions */
|
||||
int width = (int) frame.size.width;
|
||||
int height = (int) frame.size.height;
|
||||
|
||||
/* We can pick either width or height here and we'll rotate the
|
||||
screen to match, so we pick the closest to what we wanted.
|
||||
*/
|
||||
if (window->w >= window->h) {
|
||||
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, SDL_max(width, height), SDL_min(width, height));
|
||||
} else {
|
||||
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, SDL_min(width, height), SDL_max(width, height));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
|
||||
{
|
||||
@autoreleasepool {
|
||||
UIKit_UpdateWindowBorder(_this, window);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
|
||||
{
|
||||
SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
|
||||
SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata;
|
||||
UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
|
||||
|
||||
if (fullscreen) {
|
||||
[UIApplication sharedApplication].statusBarHidden = YES;
|
||||
} else {
|
||||
[UIApplication sharedApplication].statusBarHidden = NO;
|
||||
}
|
||||
|
||||
CGRect bounds;
|
||||
if (fullscreen) {
|
||||
bounds = [displaydata->uiscreen bounds];
|
||||
} else {
|
||||
bounds = [displaydata->uiscreen applicationFrame];
|
||||
}
|
||||
|
||||
/* Get frame dimensions in pixels */
|
||||
int width = (int)(bounds.size.width * displaymodedata->scale);
|
||||
int height = (int)(bounds.size.height * displaymodedata->scale);
|
||||
|
||||
/* We can pick either width or height here and we'll rotate the
|
||||
screen to match, so we pick the closest to what we wanted.
|
||||
*/
|
||||
if (window->w >= window->h) {
|
||||
if (width > height) {
|
||||
window->w = width;
|
||||
window->h = height;
|
||||
} else {
|
||||
window->w = height;
|
||||
window->h = width;
|
||||
}
|
||||
} else {
|
||||
if (width > height) {
|
||||
window->w = height;
|
||||
window->h = width;
|
||||
} else {
|
||||
window->w = width;
|
||||
window->h = height;
|
||||
}
|
||||
@autoreleasepool {
|
||||
UIKit_UpdateWindowBorder(_this, window);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UIKit_DestroyWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
|
||||
|
||||
if (data) {
|
||||
[data->viewcontroller release];
|
||||
[data->uiwindow release];
|
||||
SDL_free(data);
|
||||
@autoreleasepool {
|
||||
if (window->driverdata != NULL) {
|
||||
CFRelease(window->driverdata);
|
||||
}
|
||||
}
|
||||
|
||||
window->driverdata = NULL;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
|
||||
{
|
||||
UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
|
||||
@autoreleasepool {
|
||||
UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow;
|
||||
|
||||
if (info->version.major <= SDL_MAJOR_VERSION) {
|
||||
info->subsystem = SDL_SYSWM_UIKIT;
|
||||
info->info.uikit.window = uiwindow;
|
||||
return SDL_TRUE;
|
||||
} else {
|
||||
SDL_SetError("Application not compiled with SDL %d.%d\n",
|
||||
SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
|
||||
return SDL_FALSE;
|
||||
if (info->version.major <= SDL_MAJOR_VERSION) {
|
||||
info->subsystem = SDL_SYSWM_UIKIT;
|
||||
info->info.uikit.window = uiwindow;
|
||||
return SDL_TRUE;
|
||||
} else {
|
||||
SDL_SetError("Application not compiled with SDL %d.%d\n",
|
||||
SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam)
|
||||
{
|
||||
SDL_WindowData *data = window ? (SDL_WindowData *)window->driverdata : NULL;
|
||||
@autoreleasepool {
|
||||
SDL_WindowData *data = window ? (__bridge SDL_WindowData *)window->driverdata : nil;
|
||||
|
||||
if (!data || !data->view) {
|
||||
return SDL_SetError("Invalid window or view not set");
|
||||
if (!data || !data.view) {
|
||||
return SDL_SetError("Invalid window or view not set");
|
||||
}
|
||||
|
||||
[data.view setAnimationCallback:interval callback:callback callbackParam:callbackParam];
|
||||
}
|
||||
|
||||
[data->view setAnimationCallback:interval callback:callback callbackParam:callbackParam];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue