Merged default into iOS-improvements
commit
fb6d185a8a
|
@ -8,6 +8,9 @@ Makefile
|
||||||
sdl-config
|
sdl-config
|
||||||
SDL2.spec
|
SDL2.spec
|
||||||
build
|
build
|
||||||
|
Build
|
||||||
|
*xcuserdata*
|
||||||
|
*xcworkspacedata*
|
||||||
|
|
||||||
# for Xcode
|
# for Xcode
|
||||||
*.orig
|
*.orig
|
||||||
|
|
|
@ -387,6 +387,9 @@ main(int argc, char *argv[])
|
||||||
SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0);
|
SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0);
|
||||||
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
|
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
|
||||||
|
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
|
||||||
|
|
||||||
/* create main window and renderer */
|
/* create main window and renderer */
|
||||||
window = SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
|
window = SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
|
||||||
SDL_WINDOW_OPENGL |
|
SDL_WINDOW_OPENGL |
|
||||||
|
|
|
@ -1274,8 +1274,14 @@
|
||||||
FD6526640DE8FCCB002AD96B /* Debug */ = {
|
FD6526640DE8FCCB002AD96B /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
|
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;
|
PRODUCT_NAME = SDL2;
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
};
|
};
|
||||||
|
@ -1284,8 +1290,14 @@
|
||||||
FD6526650DE8FCCB002AD96B /* Release */ = {
|
FD6526650DE8FCCB002AD96B /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
|
||||||
COPY_PHASE_STRIP = YES;
|
COPY_PHASE_STRIP = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
|
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;
|
PRODUCT_NAME = SDL2;
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
};
|
};
|
||||||
|
|
|
@ -261,8 +261,9 @@ extern "C" {
|
||||||
#define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS"
|
#define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief A variable controlling whether an Android built-in accelerometer should be
|
* \brief A variable controlling whether the Android / iOS built-in
|
||||||
* listed as a joystick device, rather than listing actual joysticks only.
|
* accelerometer should be listed as a joystick device, rather than listing
|
||||||
|
* actual joysticks only.
|
||||||
*
|
*
|
||||||
* This variable can be set to the following values:
|
* This variable can be set to the following values:
|
||||||
* "0" - List only real joysticks and accept input from them
|
* "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"
|
#define SDL_HINT_VIDEO_HIGHDPI_DISABLED "SDL_VIDEO_HIGHDPI_DISABLED"
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,16 @@ extern DECLSPEC SDL_bool SDLCALL SDL_DXGIGetOutputInfo( int displayIndex, int *a
|
||||||
extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam);
|
extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam);
|
||||||
extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled);
|
extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled);
|
||||||
|
|
||||||
|
/* Returns the OpenGL Renderbuffer Object associated with the window's main view.
|
||||||
|
The Renderbuffer must be bound when calling SDL_GL_SwapWindow.
|
||||||
|
*/
|
||||||
|
extern DECLSPEC Uint32 SDLCALL SDL_iPhoneGetViewRenderbuffer(SDL_Window * window);
|
||||||
|
|
||||||
|
/* Returns the OpenGL Framebuffer Object associated with the window's main view.
|
||||||
|
The Framebuffer must be bound when rendering to the screen.
|
||||||
|
*/
|
||||||
|
extern DECLSPEC Uint32 SDLCALL SDL_iPhoneGetViewFramebuffer(SDL_Window * window);
|
||||||
|
|
||||||
#endif /* __IPHONEOS__ */
|
#endif /* __IPHONEOS__ */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,14 +50,13 @@ FILE* SDL_OpenFPFromBundleOrFallback(const char *file, const char *mode)
|
||||||
NSString* full_path_with_file_to_try = [resource_path stringByAppendingPathComponent:ns_string_file_component];
|
NSString* full_path_with_file_to_try = [resource_path stringByAppendingPathComponent:ns_string_file_component];
|
||||||
if([file_manager fileExistsAtPath:full_path_with_file_to_try]) {
|
if([file_manager fileExistsAtPath:full_path_with_file_to_try]) {
|
||||||
fp = fopen([full_path_with_file_to_try fileSystemRepresentation], mode);
|
fp = fopen([full_path_with_file_to_try fileSystemRepresentation], mode);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
fp = fopen(file, mode);
|
fp = fopen(file, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fp;
|
return fp;
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#endif /* __MACOSX__ */
|
#endif /* __APPLE__ */
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -41,6 +41,7 @@ SDL_GetBasePath(void)
|
||||||
const char* baseType = [[[bundle infoDictionary] objectForKey:@"SDL_FILESYSTEM_BASE_DIR_TYPE"] UTF8String];
|
const char* baseType = [[[bundle infoDictionary] objectForKey:@"SDL_FILESYSTEM_BASE_DIR_TYPE"] UTF8String];
|
||||||
const char *base = NULL;
|
const char *base = NULL;
|
||||||
char *retval = NULL;
|
char *retval = NULL;
|
||||||
|
|
||||||
if (baseType == NULL) {
|
if (baseType == NULL) {
|
||||||
baseType = "resource";
|
baseType = "resource";
|
||||||
}
|
}
|
||||||
|
@ -52,6 +53,7 @@ SDL_GetBasePath(void)
|
||||||
/* this returns the exedir for non-bundled and the resourceDir for bundled apps */
|
/* this returns the exedir for non-bundled and the resourceDir for bundled apps */
|
||||||
base = [[bundle resourcePath] fileSystemRepresentation];
|
base = [[bundle resourcePath] fileSystemRepresentation];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base) {
|
if (base) {
|
||||||
const size_t len = SDL_strlen(base) + 2;
|
const size_t len = SDL_strlen(base) + 2;
|
||||||
retval = (char *) SDL_malloc(len);
|
retval = (char *) SDL_malloc(len);
|
||||||
|
@ -69,9 +71,10 @@ char *
|
||||||
SDL_GetPrefPath(const char *org, const char *app)
|
SDL_GetPrefPath(const char *org, const char *app)
|
||||||
{ @autoreleasepool
|
{ @autoreleasepool
|
||||||
{
|
{
|
||||||
NSArray *array = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
|
||||||
char *retval = NULL;
|
char *retval = NULL;
|
||||||
|
|
||||||
|
NSArray *array = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
||||||
|
|
||||||
if ([array count] > 0) { /* we only want the first item in the list. */
|
if ([array count] > 0) { /* we only want the first item in the list. */
|
||||||
NSString *str = [array objectAtIndex:0];
|
NSString *str = [array objectAtIndex:0];
|
||||||
const char *base = [str fileSystemRepresentation];
|
const char *base = [str fileSystemRepresentation];
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
/* This is the iOS implementation of the SDL joystick API */
|
/* This is the iOS implementation of the SDL joystick API */
|
||||||
|
|
||||||
#include "SDL_joystick.h"
|
#include "SDL_joystick.h"
|
||||||
|
#include "SDL_hints.h"
|
||||||
#include "SDL_stdinc.h"
|
#include "SDL_stdinc.h"
|
||||||
#include "../SDL_sysjoystick.h"
|
#include "../SDL_sysjoystick.h"
|
||||||
#include "../SDL_joystick_c.h"
|
#include "../SDL_joystick_c.h"
|
||||||
|
@ -32,9 +33,10 @@
|
||||||
/* needed for SDL_IPHONE_MAX_GFORCE macro */
|
/* needed for SDL_IPHONE_MAX_GFORCE macro */
|
||||||
#import "SDL_config_iphoneos.h"
|
#import "SDL_config_iphoneos.h"
|
||||||
|
|
||||||
const char *accelerometerName = "iOS accelerometer";
|
const char *accelerometerName = "iOS Accelerometer";
|
||||||
|
|
||||||
static CMMotionManager *motionManager = nil;
|
static CMMotionManager *motionManager = nil;
|
||||||
|
static int numjoysticks = 0;
|
||||||
|
|
||||||
/* Function to scan the system for joysticks.
|
/* Function to scan the system for joysticks.
|
||||||
* This function should set SDL_numjoysticks to the number of available
|
* This function should set SDL_numjoysticks to the number of available
|
||||||
|
@ -44,12 +46,18 @@ static CMMotionManager *motionManager = nil;
|
||||||
int
|
int
|
||||||
SDL_SYS_JoystickInit(void)
|
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()
|
int SDL_SYS_NumJoysticks()
|
||||||
{
|
{
|
||||||
return 1;
|
return numjoysticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL_SYS_JoystickDetect()
|
void SDL_SYS_JoystickDetect()
|
||||||
|
@ -82,13 +90,15 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
||||||
joystick->nballs = 0;
|
joystick->nballs = 0;
|
||||||
joystick->nbuttons = 0;
|
joystick->nbuttons = 0;
|
||||||
|
|
||||||
if (motionManager == nil) {
|
@autoreleasepool {
|
||||||
motionManager = [[CMMotionManager alloc] init];
|
if (motionManager == nil) {
|
||||||
}
|
motionManager = [[CMMotionManager alloc] init];
|
||||||
|
}
|
||||||
|
|
||||||
/* Shorter times between updates can significantly increase CPU usage. */
|
/* Shorter times between updates can significantly increase CPU usage. */
|
||||||
motionManager.accelerometerUpdateInterval = 0.1;
|
motionManager.accelerometerUpdateInterval = 0.1;
|
||||||
[motionManager startAccelerometerUpdates];
|
[motionManager startAccelerometerUpdates];
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -105,11 +115,13 @@ static void SDL_SYS_AccelerometerUpdate(SDL_Joystick * joystick)
|
||||||
const SInt16 maxsint16 = 0x7FFF;
|
const SInt16 maxsint16 = 0x7FFF;
|
||||||
CMAcceleration accel;
|
CMAcceleration accel;
|
||||||
|
|
||||||
if (!motionManager.accelerometerActive) {
|
@autoreleasepool {
|
||||||
return;
|
if (!motionManager.accelerometerActive) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
accel = [[motionManager accelerometerData] acceleration];
|
accel = motionManager.accelerometerData.acceleration;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Convert accelerometer data from floating point to Sint16, which is what
|
Convert accelerometer data from floating point to Sint16, which is what
|
||||||
|
@ -153,7 +165,9 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
|
||||||
void
|
void
|
||||||
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
||||||
{
|
{
|
||||||
[motionManager stopAccelerometerUpdates];
|
@autoreleasepool {
|
||||||
|
[motionManager stopAccelerometerUpdates];
|
||||||
|
}
|
||||||
joystick->closed = 1;
|
joystick->closed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,10 +175,11 @@ SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
||||||
void
|
void
|
||||||
SDL_SYS_JoystickQuit(void)
|
SDL_SYS_JoystickQuit(void)
|
||||||
{
|
{
|
||||||
if (motionManager != nil) {
|
@autoreleasepool {
|
||||||
[motionManager release];
|
|
||||||
motionManager = nil;
|
motionManager = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
numjoysticks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
|
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
|
||||||
|
|
|
@ -50,24 +50,24 @@ SDL_UIKit_UpdateBatteryMonitoring(void)
|
||||||
SDL_bool
|
SDL_bool
|
||||||
SDL_GetPowerInfo_UIKit(SDL_PowerState * state, int *seconds, int *percent)
|
SDL_GetPowerInfo_UIKit(SDL_PowerState * state, int *seconds, int *percent)
|
||||||
{
|
{
|
||||||
UIDevice *uidev = [UIDevice currentDevice];
|
@autoreleasepool {
|
||||||
|
UIDevice *uidev = [UIDevice currentDevice];
|
||||||
|
|
||||||
if (!SDL_UIKitLastPowerInfoQuery) {
|
if (!SDL_UIKitLastPowerInfoQuery) {
|
||||||
SDL_assert([uidev isBatteryMonitoringEnabled] == NO);
|
SDL_assert(uidev.isBatteryMonitoringEnabled == NO);
|
||||||
[uidev setBatteryMonitoringEnabled:YES];
|
uidev.batteryMonitoringEnabled = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* UIKit_GL_SwapWindow() (etc) will check this and disable the battery
|
/* UIKit_GL_SwapWindow() (etc) will check this and disable the battery
|
||||||
* monitoring if the app hasn't queried it in the last X seconds.
|
* monitoring if the app hasn't queried it in the last X seconds.
|
||||||
* Apparently monitoring the battery burns battery life. :)
|
* Apparently monitoring the battery burns battery life. :)
|
||||||
* Apple's docs say not to monitor the battery unless you need it.
|
* Apple's docs say not to monitor the battery unless you need it.
|
||||||
*/
|
*/
|
||||||
SDL_UIKitLastPowerInfoQuery = SDL_GetTicks();
|
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:
|
case UIDeviceBatteryStateCharging:
|
||||||
*state = SDL_POWERSTATE_CHARGING;
|
*state = SDL_POWERSTATE_CHARGING;
|
||||||
break;
|
break;
|
||||||
|
@ -84,11 +84,12 @@ SDL_GetPowerInfo_UIKit(SDL_PowerState * state, int *seconds, int *percent)
|
||||||
default:
|
default:
|
||||||
*state = SDL_POWERSTATE_UNKNOWN;
|
*state = SDL_POWERSTATE_UNKNOWN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float level = [uidev batteryLevel];
|
const float level = uidev.batteryLevel;
|
||||||
*percent = ( (level < 0.0f) ? -1 : ((int) ((level * 100) + 0.5f)) );
|
*percent = ( (level < 0.0f) ? -1 : ((int) ((level * 100) + 0.5f)) );
|
||||||
return SDL_TRUE; /* always the definitive answer on iOS. */
|
return SDL_TRUE; /* always the definitive answer on iOS. */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SDL_POWER_UIKIT */
|
#endif /* SDL_POWER_UIKIT */
|
||||||
|
|
|
@ -39,12 +39,10 @@
|
||||||
static int forward_argc;
|
static int forward_argc;
|
||||||
static char **forward_argv;
|
static char **forward_argv;
|
||||||
static int exit_status;
|
static int exit_status;
|
||||||
static UIWindow *launch_window;
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
|
||||||
|
|
||||||
/* store arguments */
|
/* store arguments */
|
||||||
forward_argc = argc;
|
forward_argc = argc;
|
||||||
|
@ -56,7 +54,9 @@ int main(int argc, char **argv)
|
||||||
forward_argv[i] = NULL;
|
forward_argv[i] = NULL;
|
||||||
|
|
||||||
/* Give over control to run loop, SDLUIKitDelegate will handle most things from here */
|
/* 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 */
|
/* free the memory we used to hold copies of argc and argv */
|
||||||
for (i = 0; i < forward_argc; i++) {
|
for (i = 0; i < forward_argc; i++) {
|
||||||
|
@ -64,7 +64,6 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
free(forward_argv);
|
free(forward_argv);
|
||||||
|
|
||||||
[pool release];
|
|
||||||
return exit_status;
|
return exit_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,97 +74,12 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
|
||||||
[UIApplication sharedApplication].idleTimerDisabled = disable;
|
[UIApplication sharedApplication].idleTimerDisabled = disable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@interface SDL_splashviewcontroller : UIViewController {
|
|
||||||
UIImageView *splash;
|
|
||||||
UIImage *splashPortrait;
|
|
||||||
UIImage *splashLandscape;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)updateSplashImage:(UIInterfaceOrientation)interfaceOrientation;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation SDL_splashviewcontroller
|
|
||||||
|
|
||||||
- (id)init
|
|
||||||
{
|
|
||||||
self = [super init];
|
|
||||||
if (self == nil) {
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
self->splash = [[UIImageView alloc] init];
|
|
||||||
[self setView:self->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"];
|
|
||||||
}
|
|
||||||
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];
|
|
||||||
}
|
|
||||||
|
|
||||||
[self updateSplashImage:[[UIApplication sharedApplication] statusBarOrientation]];
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSUInteger)supportedInterfaceOrientations
|
|
||||||
{
|
|
||||||
NSUInteger orientationMask = UIInterfaceOrientationMaskAll;
|
|
||||||
|
|
||||||
/* Don't allow upside-down orientation on the phone, so answering calls is in the natural orientation */
|
|
||||||
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
|
|
||||||
orientationMask &= ~UIInterfaceOrientationMaskPortraitUpsideDown;
|
|
||||||
}
|
|
||||||
return orientationMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient
|
|
||||||
{
|
|
||||||
NSUInteger orientationMask = [self supportedInterfaceOrientations];
|
|
||||||
return (orientationMask & (1 << orient));
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
|
|
||||||
{
|
|
||||||
[self updateSplashImage:interfaceOrientation];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)updateSplashImage:(UIInterfaceOrientation)interfaceOrientation
|
|
||||||
{
|
|
||||||
UIImage *image;
|
|
||||||
|
|
||||||
if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) {
|
|
||||||
image = self->splashLandscape;
|
|
||||||
} else {
|
|
||||||
image = self->splashPortrait;
|
|
||||||
}
|
|
||||||
if (image)
|
|
||||||
{
|
|
||||||
splash.image = image;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
|
|
||||||
@implementation SDLUIKitDelegate
|
@implementation SDLUIKitDelegate
|
||||||
|
|
||||||
/* convenience method */
|
/* convenience method */
|
||||||
+ (id) sharedAppDelegate
|
+ (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];
|
return [[UIApplication sharedApplication] delegate];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,12 +103,6 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
|
||||||
exit_status = SDL_main(forward_argc, forward_argv);
|
exit_status = SDL_main(forward_argc, forward_argv);
|
||||||
SDL_iPhoneSetEventPump(SDL_FALSE);
|
SDL_iPhoneSetEventPump(SDL_FALSE);
|
||||||
|
|
||||||
/* If we showed a splash image, clean it up */
|
|
||||||
if (launch_window) {
|
|
||||||
[launch_window release];
|
|
||||||
launch_window = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* exit, passing the return status from the user's application */
|
/* exit, passing the return status from the user's application */
|
||||||
/* We don't actually exit to support applications that do setup in
|
/* We don't actually exit to support applications that do setup in
|
||||||
* their main function and then allow the Cocoa event loop to run.
|
* their main function and then allow the Cocoa event loop to run.
|
||||||
|
@ -204,14 +112,6 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
|
||||||
|
|
||||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
- (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]];
|
|
||||||
|
|
||||||
UIViewController *splashViewController = [[SDL_splashviewcontroller alloc] init];
|
|
||||||
launch_window.rootViewController = splashViewController;
|
|
||||||
[launch_window addSubview:splashViewController.view];
|
|
||||||
[launch_window makeKeyAndVisible];
|
|
||||||
|
|
||||||
/* Set working directory to resource path */
|
/* Set working directory to resource path */
|
||||||
[[NSFileManager defaultManager] changeCurrentDirectoryPath: [[NSBundle mainBundle] resourcePath]];
|
[[NSFileManager defaultManager] changeCurrentDirectoryPath: [[NSBundle mainBundle] resourcePath]];
|
||||||
|
|
||||||
|
@ -235,6 +135,35 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
|
||||||
SDL_SendAppEvent(SDL_APP_LOWMEMORY);
|
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
|
- (void) applicationWillResignActive:(UIApplication*)application
|
||||||
{
|
{
|
||||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||||
|
|
|
@ -40,8 +40,9 @@ SDL_iPhoneSetEventPump(SDL_bool enabled)
|
||||||
void
|
void
|
||||||
UIKit_PumpEvents(_THIS)
|
UIKit_PumpEvents(_THIS)
|
||||||
{
|
{
|
||||||
if (!UIKit_EventPumpEnabled)
|
if (!UIKit_EventPumpEnabled) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Let the run loop run for a short amount of time: long enough for
|
/* 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
|
touch events to get processed (which is important to get certain
|
||||||
|
|
|
@ -30,17 +30,16 @@
|
||||||
|
|
||||||
static SDL_bool s_showingMessageBox = SDL_FALSE;
|
static SDL_bool s_showingMessageBox = SDL_FALSE;
|
||||||
|
|
||||||
@interface UIKit_UIAlertViewDelegate : NSObject <UIAlertViewDelegate> {
|
@interface UIKit_UIAlertViewDelegate : NSObject <UIAlertViewDelegate>
|
||||||
@private
|
|
||||||
int *clickedButtonIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithButtonIndex:(int *)_buttonIndex;
|
- (id)initWithButtonIndex:(int *)buttonIndex;
|
||||||
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex;
|
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation UIKit_UIAlertViewDelegate
|
@implementation UIKit_UIAlertViewDelegate {
|
||||||
|
int *clickedButtonIndex;
|
||||||
|
}
|
||||||
|
|
||||||
- (id)initWithButtonIndex:(int *)buttonIndex
|
- (id)initWithButtonIndex:(int *)buttonIndex
|
||||||
{
|
{
|
||||||
|
@ -48,12 +47,13 @@ static SDL_bool s_showingMessageBox = SDL_FALSE;
|
||||||
if (self == nil) {
|
if (self == nil) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
self->clickedButtonIndex = buttonIndex;
|
|
||||||
|
clickedButtonIndex = buttonIndex;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex;
|
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
|
||||||
{
|
{
|
||||||
*clickedButtonIndex = (int)buttonIndex;
|
*clickedButtonIndex = (int)buttonIndex;
|
||||||
}
|
}
|
||||||
|
@ -71,41 +71,39 @@ int
|
||||||
UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
||||||
{
|
{
|
||||||
int clicked;
|
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;
|
int i;
|
||||||
for (i = 0; i < messageboxdata->numbuttons; ++i) {
|
const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
|
||||||
[alert addButtonWithTitle:[[NSString alloc] initWithUTF8String:buttons[i].text]];
|
|
||||||
|
@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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,17 +25,17 @@
|
||||||
|
|
||||||
#include "SDL_uikitvideo.h"
|
#include "SDL_uikitvideo.h"
|
||||||
|
|
||||||
typedef struct
|
@interface SDL_DisplayData : NSObject
|
||||||
{
|
|
||||||
UIScreen *uiscreen;
|
|
||||||
CGFloat scale;
|
|
||||||
} SDL_DisplayData;
|
|
||||||
|
|
||||||
typedef struct
|
@property (nonatomic, strong) UIScreen *uiscreen;
|
||||||
{
|
|
||||||
UIScreenMode *uiscreenmode;
|
@end
|
||||||
CGFloat scale;
|
|
||||||
} SDL_DisplayModeData;
|
@interface SDL_DisplayModeData : NSObject
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIScreenMode *uiscreenmode;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen);
|
extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen);
|
||||||
|
|
||||||
|
|
|
@ -25,27 +25,36 @@
|
||||||
#include "SDL_assert.h"
|
#include "SDL_assert.h"
|
||||||
#include "SDL_uikitmodes.h"
|
#include "SDL_uikitmodes.h"
|
||||||
|
|
||||||
|
@implementation SDL_DisplayData
|
||||||
|
|
||||||
|
@synthesize uiscreen;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation SDL_DisplayModeData
|
||||||
|
|
||||||
|
@synthesize uiscreenmode;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode,
|
UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode,
|
||||||
UIScreenMode * uiscreenmode, CGFloat scale)
|
UIScreenMode * uiscreenmode)
|
||||||
{
|
{
|
||||||
SDL_DisplayModeData *data = NULL;
|
SDL_DisplayModeData *data = nil;
|
||||||
|
|
||||||
if (uiscreenmode != nil) {
|
if (uiscreenmode != nil) {
|
||||||
/* Allocate the display mode data */
|
/* Allocate the display mode data */
|
||||||
data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
|
data = [[SDL_DisplayModeData alloc] init];
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
data->uiscreenmode = uiscreenmode;
|
data.uiscreenmode = uiscreenmode;
|
||||||
[data->uiscreenmode retain];
|
|
||||||
|
|
||||||
data->scale = scale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mode->driverdata = data;
|
mode->driverdata = (void *) CFBridgingRetain(data);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -54,23 +63,21 @@ static void
|
||||||
UIKit_FreeDisplayModeData(SDL_DisplayMode * mode)
|
UIKit_FreeDisplayModeData(SDL_DisplayMode * mode)
|
||||||
{
|
{
|
||||||
if (mode->driverdata != NULL) {
|
if (mode->driverdata != NULL) {
|
||||||
SDL_DisplayModeData *data = (SDL_DisplayModeData *)mode->driverdata;
|
CFRelease(mode->driverdata);
|
||||||
[data->uiscreenmode release];
|
|
||||||
SDL_free(data);
|
|
||||||
mode->driverdata = NULL;
|
mode->driverdata = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h,
|
UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h,
|
||||||
UIScreenMode * uiscreenmode, CGFloat scale)
|
UIScreenMode * uiscreenmode)
|
||||||
{
|
{
|
||||||
SDL_DisplayMode mode;
|
SDL_DisplayMode mode;
|
||||||
SDL_zero(mode);
|
SDL_zero(mode);
|
||||||
|
|
||||||
mode.format = SDL_PIXELFORMAT_ABGR8888;
|
mode.format = SDL_PIXELFORMAT_ABGR8888;
|
||||||
mode.refresh_rate = 0;
|
mode.refresh_rate = 0;
|
||||||
if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode, scale) < 0) {
|
if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,16 +92,16 @@ UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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)
|
UIScreenMode * uiscreenmode, SDL_bool addRotation)
|
||||||
{
|
{
|
||||||
if (UIKit_AddSingleDisplayMode(display, w, h, uiscreenmode, scale) < 0) {
|
if (UIKit_AddSingleDisplayMode(display, w, h, uiscreenmode) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addRotation) {
|
if (addRotation) {
|
||||||
/* Add the rotated version */
|
/* Add the rotated version */
|
||||||
if (UIKit_AddSingleDisplayMode(display, h, w, uiscreenmode, scale) < 0) {
|
if (UIKit_AddSingleDisplayMode(display, h, w, uiscreenmode) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,24 +121,16 @@ UIKit_AddDisplay(UIScreen *uiscreen)
|
||||||
size.height = height;
|
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_VideoDisplay display;
|
||||||
SDL_DisplayMode mode;
|
SDL_DisplayMode mode;
|
||||||
SDL_zero(mode);
|
SDL_zero(mode);
|
||||||
mode.format = SDL_PIXELFORMAT_ABGR8888;
|
mode.format = SDL_PIXELFORMAT_ABGR8888;
|
||||||
mode.w = (int)(size.width * scale);
|
mode.w = (int) size.width;
|
||||||
mode.h = (int)(size.height * scale);
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,19 +139,18 @@ UIKit_AddDisplay(UIScreen *uiscreen)
|
||||||
display.current_mode = mode;
|
display.current_mode = mode;
|
||||||
|
|
||||||
/* Allocate the display data */
|
/* Allocate the display data */
|
||||||
SDL_DisplayData *data = (SDL_DisplayData *) SDL_malloc(sizeof(*data));
|
SDL_DisplayData *data = [[SDL_DisplayData alloc] init];
|
||||||
if (!data) {
|
if (!data) {
|
||||||
UIKit_FreeDisplayModeData(&display.desktop_mode);
|
UIKit_FreeDisplayModeData(&display.desktop_mode);
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
[uiscreen retain];
|
data.uiscreen = uiscreen;
|
||||||
data->uiscreen = uiscreen;
|
|
||||||
data->scale = scale;
|
|
||||||
|
|
||||||
display.driverdata = data;
|
display.driverdata = (void *) CFBridgingRetain(data);
|
||||||
SDL_AddVideoDisplay(&display);
|
SDL_AddVideoDisplay(&display);
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,9 +168,11 @@ UIKit_IsDisplayLandscape(UIScreen *uiscreen)
|
||||||
int
|
int
|
||||||
UIKit_InitModes(_THIS)
|
UIKit_InitModes(_THIS)
|
||||||
{
|
{
|
||||||
for (UIScreen *uiscreen in [UIScreen screens]) {
|
@autoreleasepool {
|
||||||
if (UIKit_AddDisplay(uiscreen) < 0) {
|
for (UIScreen *uiscreen in [UIScreen screens]) {
|
||||||
return -1;
|
if (UIKit_AddDisplay(uiscreen) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,34 +182,36 @@ UIKit_InitModes(_THIS)
|
||||||
void
|
void
|
||||||
UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
|
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 isLandscape = UIKit_IsDisplayLandscape(data.uiscreen);
|
||||||
SDL_bool addRotation = (data->uiscreen == [UIScreen mainScreen]);
|
SDL_bool addRotation = (data.uiscreen == [UIScreen mainScreen]);
|
||||||
|
CGFloat scale = data.uiscreen.scale;
|
||||||
|
|
||||||
for (UIScreenMode *uimode in [data->uiscreen availableModes]) {
|
#ifdef __IPHONE_8_0
|
||||||
CGSize size = [uimode size];
|
/* The UIScreenMode of an iPhone 6 Plus should be 1080x1920 rather than
|
||||||
int w = (int)size.width;
|
* 1242x2208 (414x736@3x), so we should use the native scale. */
|
||||||
int h = (int)size.height;
|
if ([data.uiscreen respondsToSelector:@selector(nativeScale)]) {
|
||||||
|
scale = data.uiscreen.nativeScale;
|
||||||
/* Make sure the width/height are oriented correctly */
|
|
||||||
if (isLandscape != (w > h)) {
|
|
||||||
int tmp = w;
|
|
||||||
w = h;
|
|
||||||
h = tmp;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Add the native screen resolution. */
|
for (UIScreenMode *uimode in [data.uiscreen availableModes]) {
|
||||||
UIKit_AddDisplayMode(display, w, h, data->scale, uimode, addRotation);
|
/* The size of a UIScreenMode is in pixels, but we deal exclusively
|
||||||
|
* in points (except in SDL_GL_GetDrawableSize.) */
|
||||||
|
int w = (int)(uimode.size.width / scale);
|
||||||
|
int h = (int)(uimode.size.height / scale);
|
||||||
|
|
||||||
if (data->scale != 1.0f) {
|
/* Make sure the width/height are oriented correctly */
|
||||||
/* Add the native screen resolution divided by its scale.
|
if (isLandscape != (w > h)) {
|
||||||
* This is so devices capable of e.g. 640x960 also advertise 320x480.
|
int tmp = w;
|
||||||
*/
|
w = h;
|
||||||
UIKit_AddDisplayMode(display,
|
h = tmp;
|
||||||
(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 +219,21 @@ UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
|
||||||
int
|
int
|
||||||
UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
|
UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
|
||||||
{
|
{
|
||||||
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
|
@autoreleasepool {
|
||||||
SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
|
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 (data.uiscreen == [UIScreen mainScreen]) {
|
||||||
if (mode->w > mode->h) {
|
if (mode->w > mode->h) {
|
||||||
if (!UIKit_IsDisplayLandscape(data->uiscreen)) {
|
if (!UIKit_IsDisplayLandscape(data.uiscreen)) {
|
||||||
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
|
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
|
||||||
}
|
}
|
||||||
} else if (mode->w < mode->h) {
|
} else if (mode->w < mode->h) {
|
||||||
if (UIKit_IsDisplayLandscape(data->uiscreen)) {
|
if (UIKit_IsDisplayLandscape(data.uiscreen)) {
|
||||||
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
|
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -242,19 +246,21 @@ UIKit_QuitModes(_THIS)
|
||||||
{
|
{
|
||||||
/* Release Objective-C objects, so higher level doesn't free() them. */
|
/* Release Objective-C objects, so higher level doesn't free() them. */
|
||||||
int i, j;
|
int i, j;
|
||||||
for (i = 0; i < _this->num_displays; i++) {
|
@autoreleasepool {
|
||||||
SDL_VideoDisplay *display = &_this->displays[i];
|
for (i = 0; i < _this->num_displays; i++) {
|
||||||
|
SDL_VideoDisplay *display = &_this->displays[i];
|
||||||
|
|
||||||
UIKit_FreeDisplayModeData(&display->desktop_mode);
|
UIKit_FreeDisplayModeData(&display->desktop_mode);
|
||||||
for (j = 0; j < display->num_display_modes; j++) {
|
for (j = 0; j < display->num_display_modes; j++) {
|
||||||
SDL_DisplayMode *mode = &display->display_modes[j];
|
SDL_DisplayMode *mode = &display->display_modes[j];
|
||||||
UIKit_FreeDisplayModeData(mode);
|
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,
|
extern int UIKit_GL_MakeCurrent(_THIS, SDL_Window * window,
|
||||||
SDL_GLContext context);
|
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 void UIKit_GL_SwapWindow(_THIS, SDL_Window * window);
|
||||||
extern SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window);
|
extern SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window);
|
||||||
extern void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context);
|
extern void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context);
|
||||||
|
|
|
@ -49,12 +49,30 @@ UIKit_GL_GetProcAddress(_THIS, const char *proc)
|
||||||
/*
|
/*
|
||||||
note that SDL_GL_Delete context makes it current without passing the window
|
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)
|
||||||
{
|
{
|
||||||
[EAGLContext setCurrentContext: context];
|
@autoreleasepool {
|
||||||
|
[EAGLContext setCurrentContext:(__bridge EAGLContext *)context];
|
||||||
|
}
|
||||||
return 0;
|
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
|
int
|
||||||
UIKit_GL_LoadLibrary(_THIS, const char *path)
|
UIKit_GL_LoadLibrary(_THIS, const char *path)
|
||||||
{
|
{
|
||||||
|
@ -71,117 +89,166 @@ UIKit_GL_LoadLibrary(_THIS, const char *path)
|
||||||
|
|
||||||
void UIKit_GL_SwapWindow(_THIS, SDL_Window * window)
|
void UIKit_GL_SwapWindow(_THIS, SDL_Window * window)
|
||||||
{
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
|
||||||
|
|
||||||
#if SDL_POWER_UIKIT
|
#if SDL_POWER_UIKIT
|
||||||
/* Check once a frame to see if we should turn off the battery monitor. */
|
/* Check once a frame to see if we should turn off the battery monitor. */
|
||||||
SDL_UIKit_UpdateBatteryMonitoring();
|
SDL_UIKit_UpdateBatteryMonitoring();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
|
if (data.view == nil) {
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
EAGLContext *context = view.context;
|
|
||||||
if (UIKit_GL_MakeCurrent(_this, window, context) < 0) {
|
|
||||||
UIKit_GL_DeleteContext(_this, context);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make this window the current mouse focus for touch input */
|
|
||||||
if (displaydata->uiscreen == [UIScreen mainScreen]) {
|
|
||||||
SDL_SetMouseFocus(window);
|
|
||||||
SDL_SetKeyboardFocus(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context)
|
|
||||||
{
|
|
||||||
SDL_Window *window;
|
|
||||||
|
|
||||||
/* Find the view associated with this context */
|
|
||||||
for (window = _this->windows; window; window = window->next) {
|
|
||||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
|
||||||
SDL_uikitopenglview *view = data->view;
|
|
||||||
if (view.context == context) {
|
|
||||||
/* the delegate has retained the view, this will release him */
|
|
||||||
if (view->viewcontroller) {
|
|
||||||
UIWindow *uiwindow = (UIWindow *)view.superview;
|
|
||||||
if (uiwindow.rootViewController == view->viewcontroller) {
|
|
||||||
uiwindow.rootViewController = nil;
|
|
||||||
}
|
|
||||||
[view->viewcontroller setView:nil];
|
|
||||||
[view->viewcontroller release];
|
|
||||||
}
|
|
||||||
[view removeFromSuperview];
|
|
||||||
|
|
||||||
/* FIXME: This doesn't actually call view dealloc - what is holding a reference to it? */
|
|
||||||
[view release];
|
|
||||||
return;
|
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)
|
||||||
|
{
|
||||||
|
@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.
|
||||||
|
*/
|
||||||
|
#ifdef __IPHONE_8_0
|
||||||
|
if ([uiwindow.screen respondsToSelector:@selector(nativeScale)]) {
|
||||||
|
scale = uiwindow.screen.nativeScale;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
scale = uiwindow.screen.scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_this->gl_config.share_with_current_context) {
|
||||||
|
EAGLContext *context = (__bridge EAGLContext *) SDL_GL_GetCurrentContext();
|
||||||
|
share_group = 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAGLContext *context = view.context;
|
||||||
|
if (UIKit_GL_MakeCurrent(_this, window, (__bridge SDL_GLContext) context) < 0) {
|
||||||
|
UIKit_GL_DeleteContext(_this, (SDL_GLContext) CFBridgingRetain(context));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make this window the current mouse focus for touch input */
|
||||||
|
if (uiwindow.screen == [UIScreen mainScreen]) {
|
||||||
|
SDL_SetMouseFocus(window);
|
||||||
|
SDL_SetKeyboardFocus(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We return a +1'd context. The window's driverdata owns the view. */
|
||||||
|
return (SDL_GLContext) CFBridgingRetain(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UIKit_GL_DeleteContext(_THIS, SDL_GLContext context)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
/* Transfer ownership the +1'd context to ARC. */
|
||||||
|
EAGLContext *eaglcontext = (EAGLContext *) CFBridgingRelease(context);
|
||||||
|
SDL_Window *window;
|
||||||
|
|
||||||
|
/* Find the view associated with this context */
|
||||||
|
for (window = _this->windows; window; window = window->next) {
|
||||||
|
SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
|
||||||
|
SDL_uikitopenglview *view = data.view;
|
||||||
|
if (view.context == eaglcontext) {
|
||||||
|
/* the delegate has retained the view, this will release him */
|
||||||
|
if (view.viewcontroller) {
|
||||||
|
UIWindow *uiwindow = (UIWindow *)view.superview;
|
||||||
|
if (uiwindow.rootViewController == view.viewcontroller) {
|
||||||
|
uiwindow.rootViewController = nil;
|
||||||
|
}
|
||||||
|
view.viewcontroller.view = nil;
|
||||||
|
view.viewcontroller = nil;
|
||||||
|
}
|
||||||
|
[view removeFromSuperview];
|
||||||
|
|
||||||
|
data.view = nil;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint32 SDL_iPhoneGetViewRenderbuffer(SDL_Window * window)
|
||||||
|
{
|
||||||
|
if (!window) {
|
||||||
|
SDL_SetError("Invalid window");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* View not found... delete the context anyway? */
|
@autoreleasepool {
|
||||||
[(EAGLContext *)context release];
|
SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
|
||||||
|
if (data.view != nil) {
|
||||||
|
return data.view.drawableRenderbuffer;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint32 SDL_iPhoneGetViewFramebuffer(SDL_Window * window)
|
||||||
|
{
|
||||||
|
if (!window) {
|
||||||
|
SDL_SetError("Invalid window");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@autoreleasepool {
|
||||||
|
SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
|
||||||
|
if (data.view != nil) {
|
||||||
|
return data.view.drawableFramebuffer;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SDL_VIDEO_DRIVER_UIKIT */
|
#endif /* SDL_VIDEO_DRIVER_UIKIT */
|
||||||
|
|
|
@ -21,60 +21,45 @@
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
#import <OpenGLES/EAGL.h>
|
#import <OpenGLES/EAGL.h>
|
||||||
#import <OpenGLES/ES1/gl.h>
|
#import <OpenGLES/gltypes.h>
|
||||||
#import <OpenGLES/ES1/glext.h>
|
|
||||||
#import "SDL_uikitview.h"
|
#import "SDL_uikitview.h"
|
||||||
/*
|
/*
|
||||||
This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass.
|
This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass.
|
||||||
The view content is basically an EAGL surface you render your OpenGL scene into.
|
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.
|
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
|
- (id)initWithFrame:(CGRect)frame
|
||||||
/* The pixel dimensions of the backbuffer */
|
scale:(CGFloat)scale
|
||||||
GLint backingWidth;
|
retainBacking:(BOOL)retained
|
||||||
GLint backingHeight;
|
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 */
|
/* The width and height of the drawable in pixels (as opposed to points.) */
|
||||||
GLuint viewRenderbuffer, viewFramebuffer;
|
@property (nonatomic, readonly) int backingWidth;
|
||||||
|
@property (nonatomic, readonly) int backingHeight;
|
||||||
|
|
||||||
/* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */
|
@property (nonatomic, readonly) GLuint drawableRenderbuffer;
|
||||||
GLuint depthRenderbuffer;
|
@property (nonatomic, readonly) GLuint drawableFramebuffer;
|
||||||
|
|
||||||
/* format of depthRenderbuffer */
|
|
||||||
GLenum depthBufferFormat;
|
|
||||||
|
|
||||||
id displayLink;
|
|
||||||
int animationInterval;
|
|
||||||
void (*animationCallback)(void*);
|
|
||||||
void *animationCallbackParam;
|
|
||||||
}
|
|
||||||
|
|
||||||
@property (nonatomic, retain, readonly) EAGLContext *context;
|
|
||||||
|
|
||||||
- (void)swapBuffers;
|
- (void)swapBuffers;
|
||||||
- (void)setCurrentContext;
|
- (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)updateFrame;
|
||||||
|
|
||||||
- (void)setAnimationCallback:(int)interval
|
- (void)setAnimationCallback:(int)interval
|
||||||
callback:(void (*)(void*))callback
|
callback:(void (*)(void*))callback
|
||||||
callbackParam:(void*)callbackParam;
|
callbackParam:(void*)callbackParam;
|
||||||
|
|
||||||
- (void)startAnimation;
|
- (void)startAnimation;
|
||||||
- (void)stopAnimation;
|
- (void)stopAnimation;
|
||||||
|
|
|
@ -24,44 +24,82 @@
|
||||||
|
|
||||||
#include <QuartzCore/QuartzCore.h>
|
#include <QuartzCore/QuartzCore.h>
|
||||||
#include <OpenGLES/EAGLDrawable.h>
|
#include <OpenGLES/EAGLDrawable.h>
|
||||||
|
#include <OpenGLES/ES2/gl.h>
|
||||||
|
#include <OpenGLES/ES2/glext.h>
|
||||||
#include "SDL_uikitopenglview.h"
|
#include "SDL_uikitopenglview.h"
|
||||||
#include "SDL_uikitmessagebox.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 context;
|
||||||
|
|
||||||
|
@synthesize backingWidth;
|
||||||
|
@synthesize backingHeight;
|
||||||
|
|
||||||
+ (Class)layerClass
|
+ (Class)layerClass
|
||||||
{
|
{
|
||||||
return [CAEAGLLayer class];
|
return [CAEAGLLayer class];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)frame
|
- (id)initWithFrame:(CGRect)frame
|
||||||
scale:(CGFloat)scale
|
scale:(CGFloat)scale
|
||||||
retainBacking:(BOOL)retained
|
retainBacking:(BOOL)retained
|
||||||
rBits:(int)rBits
|
rBits:(int)rBits
|
||||||
gBits:(int)gBits
|
gBits:(int)gBits
|
||||||
bBits:(int)bBits
|
bBits:(int)bBits
|
||||||
aBits:(int)aBits
|
aBits:(int)aBits
|
||||||
depthBits:(int)depthBits
|
depthBits:(int)depthBits
|
||||||
stencilBits:(int)stencilBits
|
stencilBits:(int)stencilBits
|
||||||
majorVersion:(int)majorVersion
|
sRGB:(BOOL)sRGB
|
||||||
shareGroup:(EAGLSharegroup*)shareGroup
|
majorVersion:(int)majorVersion
|
||||||
|
shareGroup:(EAGLSharegroup*)shareGroup
|
||||||
{
|
{
|
||||||
depthBufferFormat = 0;
|
|
||||||
|
|
||||||
if ((self = [super initWithFrame:frame])) {
|
if ((self = [super initWithFrame:frame])) {
|
||||||
const BOOL useStencilBuffer = (stencilBits != 0);
|
const BOOL useStencilBuffer = (stencilBits != 0);
|
||||||
const BOOL useDepthBuffer = (depthBits != 0);
|
const BOOL useDepthBuffer = (depthBits != 0);
|
||||||
NSString *colorFormat = nil;
|
NSString *colorFormat = nil;
|
||||||
|
|
||||||
|
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||||
|
self.autoresizesSubviews = YES;
|
||||||
|
|
||||||
/* The EAGLRenderingAPI enum values currently map 1:1 to major GLES
|
/* The EAGLRenderingAPI enum values currently map 1:1 to major GLES
|
||||||
versions, and this allows us to handle future OpenGL ES versions.
|
versions, and this allows us to handle future OpenGL ES versions.
|
||||||
*/
|
*/
|
||||||
EAGLRenderingAPI api = majorVersion;
|
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) {
|
||||||
|
/* sRGB EAGL drawable support was added in iOS 7. */
|
||||||
|
if (UIKit_IsSystemVersionAtLeast(@"7.0")) {
|
||||||
|
colorFormat = kEAGLColorFormatSRGBA8;
|
||||||
|
} else {
|
||||||
|
SDL_SetError("sRGB drawables are not supported.");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
} else if (rBits >= 8 || gBits >= 8 || bBits >= 8) {
|
||||||
/* if user specifically requests rbg888 or some color format higher than 16bpp */
|
/* if user specifically requests rbg888 or some color format higher than 16bpp */
|
||||||
colorFormat = kEAGLColorFormatRGBA8;
|
colorFormat = kEAGLColorFormatRGBA8;
|
||||||
} else {
|
} else {
|
||||||
|
@ -73,90 +111,100 @@
|
||||||
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
|
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
|
||||||
|
|
||||||
eaglLayer.opaque = YES;
|
eaglLayer.opaque = YES;
|
||||||
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
|
eaglLayer.drawableProperties = @{
|
||||||
[NSNumber numberWithBool: retained], kEAGLDrawablePropertyRetainedBacking, colorFormat, kEAGLDrawablePropertyColorFormat, nil];
|
kEAGLDrawablePropertyRetainedBacking: @(retained),
|
||||||
|
kEAGLDrawablePropertyColorFormat: colorFormat
|
||||||
context = [[EAGLContext alloc] initWithAPI:api sharegroup:shareGroup];
|
};
|
||||||
if (!context || ![EAGLContext setCurrentContext:context]) {
|
|
||||||
[self release];
|
|
||||||
SDL_SetError("OpenGL ES %d not supported", majorVersion);
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the appropriate scale (for retina display support) */
|
/* Set the appropriate scale (for retina display support) */
|
||||||
self.contentScaleFactor = scale;
|
self.contentScaleFactor = scale;
|
||||||
|
|
||||||
/* create the buffers */
|
/* Create the color Renderbuffer Object */
|
||||||
glGenFramebuffersOES(1, &viewFramebuffer);
|
glGenRenderbuffers(1, &viewRenderbuffer);
|
||||||
glGenRenderbuffersOES(1, &viewRenderbuffer);
|
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
|
||||||
|
|
||||||
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
|
if (![context renderbufferStorage:GL_RENDERBUFFER fromDrawable:eaglLayer]) {
|
||||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
|
SDL_SetError("Failed to create OpenGL ES drawable");
|
||||||
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
|
return nil;
|
||||||
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
|
}
|
||||||
|
|
||||||
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
|
/* Create the Framebuffer Object */
|
||||||
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
|
glGenFramebuffers(1, &viewFramebuffer);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
|
||||||
|
|
||||||
|
/* attach the color renderbuffer to the FBO */
|
||||||
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, viewRenderbuffer);
|
||||||
|
|
||||||
|
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
|
||||||
|
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
|
||||||
|
|
||||||
if ((useDepthBuffer) || (useStencilBuffer)) {
|
if ((useDepthBuffer) || (useStencilBuffer)) {
|
||||||
if (useStencilBuffer) {
|
if (useStencilBuffer) {
|
||||||
/* Apparently you need to pack stencil and depth into one buffer. */
|
/* Apparently you need to pack stencil and depth into one buffer. */
|
||||||
depthBufferFormat = GL_DEPTH24_STENCIL8_OES;
|
depthBufferFormat = GL_DEPTH24_STENCIL8_OES;
|
||||||
} else if (useDepthBuffer) {
|
} else if (useDepthBuffer) {
|
||||||
/* iOS only has 24-bit depth buffers, even with GL_DEPTH_COMPONENT16_OES */
|
/* iOS only has 24-bit depth buffers, even with GL_DEPTH_COMPONENT16 */
|
||||||
depthBufferFormat = GL_DEPTH_COMPONENT24_OES;
|
depthBufferFormat = GL_DEPTH_COMPONENT24_OES;
|
||||||
}
|
}
|
||||||
|
|
||||||
glGenRenderbuffersOES(1, &depthRenderbuffer);
|
glGenRenderbuffers(1, &depthRenderbuffer);
|
||||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
|
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
|
||||||
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, depthBufferFormat, backingWidth, backingHeight);
|
glRenderbufferStorage(GL_RENDERBUFFER, depthBufferFormat, backingWidth, backingHeight);
|
||||||
if (useDepthBuffer) {
|
if (useDepthBuffer) {
|
||||||
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
|
||||||
}
|
}
|
||||||
if (useStencilBuffer) {
|
if (useStencilBuffer) {
|
||||||
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
return NO;
|
SDL_SetError("Failed creating OpenGL ES framebuffer");
|
||||||
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
|
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
|
||||||
/* end create buffers */
|
|
||||||
|
|
||||||
self.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
|
|
||||||
self.autoresizesSubviews = YES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (GLuint)drawableRenderbuffer
|
||||||
|
{
|
||||||
|
return viewRenderbuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GLuint)drawableFramebuffer
|
||||||
|
{
|
||||||
|
return viewFramebuffer;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)updateFrame
|
- (void)updateFrame
|
||||||
{
|
{
|
||||||
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
|
glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
|
||||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, 0);
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||||
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, 0);
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0);
|
||||||
glDeleteRenderbuffersOES(1, &viewRenderbuffer);
|
glDeleteRenderbuffers(1, &viewRenderbuffer);
|
||||||
|
|
||||||
glGenRenderbuffersOES(1, &viewRenderbuffer);
|
glGenRenderbuffers(1, &viewRenderbuffer);
|
||||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
|
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
|
||||||
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
|
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)self.layer];
|
||||||
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, viewRenderbuffer);
|
||||||
|
|
||||||
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
|
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
|
||||||
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
|
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
|
||||||
|
|
||||||
if (depthRenderbuffer != 0) {
|
if (depthRenderbuffer != 0) {
|
||||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
|
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
|
||||||
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, depthBufferFormat, backingWidth, backingHeight);
|
glRenderbufferStorage(GL_RENDERBUFFER, depthBufferFormat, backingWidth, backingHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
|
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setAnimationCallback:(int)interval
|
- (void)setAnimationCallback:(int)interval
|
||||||
callback:(void (*)(void*))callback
|
callback:(void (*)(void*))callback
|
||||||
callbackParam:(void*)callbackParam
|
callbackParam:(void*)callbackParam
|
||||||
{
|
{
|
||||||
[self stopAnimation];
|
[self stopAnimation];
|
||||||
|
|
||||||
|
@ -164,8 +212,9 @@
|
||||||
animationCallback = callback;
|
animationCallback = callback;
|
||||||
animationCallbackParam = callbackParam;
|
animationCallbackParam = callbackParam;
|
||||||
|
|
||||||
if (animationCallback)
|
if (animationCallback) {
|
||||||
[self startAnimation];
|
[self startAnimation];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)startAnimation
|
- (void)startAnimation
|
||||||
|
@ -194,31 +243,36 @@
|
||||||
[EAGLContext setCurrentContext:context];
|
[EAGLContext setCurrentContext:context];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)swapBuffers
|
- (void)swapBuffers
|
||||||
{
|
{
|
||||||
/* viewRenderbuffer should always be bound here. Code that binds something
|
/* viewRenderbuffer should always be bound here. Code that binds something
|
||||||
else is responsible for rebinding viewRenderbuffer, to reduce
|
else is responsible for rebinding viewRenderbuffer, to reduce duplicate
|
||||||
duplicate state changes. */
|
state changes. */
|
||||||
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
|
[context presentRenderbuffer:GL_RENDERBUFFER];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)layoutSubviews
|
- (void)layoutSubviews
|
||||||
{
|
{
|
||||||
|
[super layoutSubviews];
|
||||||
|
|
||||||
[EAGLContext setCurrentContext:context];
|
[EAGLContext setCurrentContext:context];
|
||||||
[self updateFrame];
|
[self updateFrame];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)destroyFramebuffer
|
- (void)destroyFramebuffer
|
||||||
{
|
{
|
||||||
glDeleteFramebuffersOES(1, &viewFramebuffer);
|
if (viewFramebuffer != 0) {
|
||||||
viewFramebuffer = 0;
|
glDeleteFramebuffers(1, &viewFramebuffer);
|
||||||
glDeleteRenderbuffersOES(1, &viewRenderbuffer);
|
viewFramebuffer = 0;
|
||||||
viewRenderbuffer = 0;
|
}
|
||||||
|
|
||||||
if (depthRenderbuffer) {
|
if (viewRenderbuffer != 0) {
|
||||||
glDeleteRenderbuffersOES(1, &depthRenderbuffer);
|
glDeleteRenderbuffers(1, &viewRenderbuffer);
|
||||||
|
viewRenderbuffer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depthRenderbuffer != 0) {
|
||||||
|
glDeleteRenderbuffers(1, &depthRenderbuffer);
|
||||||
depthRenderbuffer = 0;
|
depthRenderbuffer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,12 +280,10 @@
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
[self destroyFramebuffer];
|
|
||||||
if ([EAGLContext currentContext] == context) {
|
if ([EAGLContext currentContext] == context) {
|
||||||
|
[self destroyFramebuffer];
|
||||||
[EAGLContext setCurrentContext:nil];
|
[EAGLContext setCurrentContext:nil];
|
||||||
}
|
}
|
||||||
[context release];
|
|
||||||
[super dealloc];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -25,20 +25,8 @@
|
||||||
|
|
||||||
#include "../SDL_sysvideo.h"
|
#include "../SDL_sysvideo.h"
|
||||||
|
|
||||||
#ifndef __IPHONE_6_0
|
BOOL UIKit_IsSystemVersionAtLeast(NSString *version);
|
||||||
/* 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 */
|
CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen);
|
||||||
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 */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _SDL_uikitvideo_h */
|
#endif /* _SDL_uikitvideo_h */
|
||||||
|
|
||||||
|
|
|
@ -78,12 +78,11 @@ UIKit_CreateDevice(int devindex)
|
||||||
device->ShowWindow = UIKit_ShowWindow;
|
device->ShowWindow = UIKit_ShowWindow;
|
||||||
device->HideWindow = UIKit_HideWindow;
|
device->HideWindow = UIKit_HideWindow;
|
||||||
device->RaiseWindow = UIKit_RaiseWindow;
|
device->RaiseWindow = UIKit_RaiseWindow;
|
||||||
|
device->SetWindowBordered = UIKit_SetWindowBordered;
|
||||||
device->SetWindowFullscreen = UIKit_SetWindowFullscreen;
|
device->SetWindowFullscreen = UIKit_SetWindowFullscreen;
|
||||||
device->DestroyWindow = UIKit_DestroyWindow;
|
device->DestroyWindow = UIKit_DestroyWindow;
|
||||||
device->GetWindowWMInfo = UIKit_GetWindowWMInfo;
|
device->GetWindowWMInfo = UIKit_GetWindowWMInfo;
|
||||||
|
|
||||||
/* !!! FIXME: implement SetWindowBordered */
|
|
||||||
|
|
||||||
#if SDL_IPHONE_KEYBOARD
|
#if SDL_IPHONE_KEYBOARD
|
||||||
device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport;
|
device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport;
|
||||||
device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard;
|
device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard;
|
||||||
|
@ -93,12 +92,13 @@ UIKit_CreateDevice(int devindex)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* OpenGL (ES) functions */
|
/* OpenGL (ES) functions */
|
||||||
device->GL_MakeCurrent = UIKit_GL_MakeCurrent;
|
device->GL_MakeCurrent = UIKit_GL_MakeCurrent;
|
||||||
device->GL_SwapWindow = UIKit_GL_SwapWindow;
|
device->GL_GetDrawableSize = UIKit_GL_GetDrawableSize;
|
||||||
|
device->GL_SwapWindow = UIKit_GL_SwapWindow;
|
||||||
device->GL_CreateContext = UIKit_GL_CreateContext;
|
device->GL_CreateContext = UIKit_GL_CreateContext;
|
||||||
device->GL_DeleteContext = UIKit_GL_DeleteContext;
|
device->GL_DeleteContext = UIKit_GL_DeleteContext;
|
||||||
device->GL_GetProcAddress = UIKit_GL_GetProcAddress;
|
device->GL_GetProcAddress = UIKit_GL_GetProcAddress;
|
||||||
device->GL_LoadLibrary = UIKit_GL_LoadLibrary;
|
device->GL_LoadLibrary = UIKit_GL_LoadLibrary;
|
||||||
device->free = UIKit_DeleteDevice;
|
device->free = UIKit_DeleteDevice;
|
||||||
|
|
||||||
device->gl_config.accelerated = 1;
|
device->gl_config.accelerated = 1;
|
||||||
|
@ -129,6 +129,26 @@ UIKit_VideoQuit(_THIS)
|
||||||
UIKit_QuitModes(_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.
|
* iOS log support.
|
||||||
*
|
*
|
||||||
|
|
|
@ -24,34 +24,14 @@
|
||||||
|
|
||||||
#include "SDL_touch.h"
|
#include "SDL_touch.h"
|
||||||
|
|
||||||
#define IPHONE_TOUCH_EFFICIENT_DANGEROUS
|
|
||||||
|
|
||||||
#ifndef IPHONE_TOUCH_EFFICIENT_DANGEROUS
|
|
||||||
#define MAX_SIMULTANEOUS_TOUCHES 5
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SDL_IPHONE_KEYBOARD
|
#if SDL_IPHONE_KEYBOARD
|
||||||
@interface SDL_uikitview : UIView<UITextFieldDelegate> {
|
@interface SDL_uikitview : UIView <UITextFieldDelegate>
|
||||||
#else
|
#else
|
||||||
@interface SDL_uikitview : UIView {
|
@interface SDL_uikitview : UIView
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SDL_TouchID touchId;
|
@property (nonatomic, weak) SDL_uikitviewcontroller *viewcontroller;
|
||||||
UITouch *leftFingerDown;
|
|
||||||
#ifndef IPHONE_TOUCH_EFFICIENT_DANGEROUS
|
|
||||||
UITouch *finger[MAX_SIMULTANEOUS_TOUCHES];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#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;
|
- (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize;
|
||||||
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
|
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
|
||||||
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
|
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
|
||||||
|
@ -61,9 +41,10 @@
|
||||||
- (void)showKeyboard;
|
- (void)showKeyboard;
|
||||||
- (void)hideKeyboard;
|
- (void)hideKeyboard;
|
||||||
- (void)initializeKeyboard;
|
- (void)initializeKeyboard;
|
||||||
@property (readonly) BOOL keyboardVisible;
|
|
||||||
@property (nonatomic,assign) SDL_Rect textInputRect;
|
@property (nonatomic, assign, getter=isKeyboardVisible) BOOL keyboardVisible;
|
||||||
@property (nonatomic,assign) int keyboardHeight;
|
@property (nonatomic, assign) SDL_Rect textInputRect;
|
||||||
|
@property (nonatomic, assign) int keyboardHeight;
|
||||||
|
|
||||||
SDL_bool UIKit_HasScreenKeyboardSupport(_THIS);
|
SDL_bool UIKit_HasScreenKeyboardSupport(_THIS);
|
||||||
void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window);
|
void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window);
|
||||||
|
|
|
@ -35,27 +35,33 @@
|
||||||
#include "SDL_uikitmodes.h"
|
#include "SDL_uikitmodes.h"
|
||||||
#include "SDL_uikitwindow.h"
|
#include "SDL_uikitwindow.h"
|
||||||
|
|
||||||
void _uikit_keyboard_init() ;
|
void _uikit_keyboard_init();
|
||||||
|
|
||||||
@implementation SDL_uikitview
|
@implementation SDL_uikitview {
|
||||||
|
|
||||||
|
SDL_TouchID touchId;
|
||||||
|
UITouch *leftFingerDown;
|
||||||
|
|
||||||
|
#if SDL_IPHONE_KEYBOARD
|
||||||
|
UITextField *textField;
|
||||||
|
#endif
|
||||||
|
|
||||||
- (void)dealloc
|
|
||||||
{
|
|
||||||
[super dealloc];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@synthesize viewcontroller;
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)frame
|
- (id)initWithFrame:(CGRect)frame
|
||||||
{
|
{
|
||||||
self = [super initWithFrame: frame];
|
if (self = [super initWithFrame: frame]) {
|
||||||
|
|
||||||
#if SDL_IPHONE_KEYBOARD
|
#if SDL_IPHONE_KEYBOARD
|
||||||
[self initializeKeyboard];
|
[self initializeKeyboard];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
self.multipleTouchEnabled = YES;
|
self.multipleTouchEnabled = YES;
|
||||||
|
|
||||||
touchId = 1;
|
touchId = 1;
|
||||||
SDL_AddTouch(touchId, "");
|
SDL_AddTouch(touchId, "");
|
||||||
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|
||||||
|
@ -65,91 +71,48 @@ void _uikit_keyboard_init() ;
|
||||||
{
|
{
|
||||||
CGPoint point = [touch locationInView: self];
|
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) {
|
if (normalize) {
|
||||||
CGRect bounds = [self bounds];
|
CGRect bounds = self.bounds;
|
||||||
point.x /= bounds.size.width;
|
point.x /= bounds.size.width;
|
||||||
point.y /= bounds.size.height;
|
point.y /= bounds.size.height;
|
||||||
} else {
|
|
||||||
point.x *= displaymodedata->scale;
|
|
||||||
point.y *= displaymodedata->scale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return point;
|
return point;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
|
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
|
||||||
{
|
{
|
||||||
NSEnumerator *enumerator = [touches objectEnumerator];
|
for (UITouch *touch in touches) {
|
||||||
UITouch *touch = (UITouch*)[enumerator nextObject];
|
|
||||||
|
|
||||||
while (touch) {
|
|
||||||
if (!leftFingerDown) {
|
if (!leftFingerDown) {
|
||||||
CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
|
CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
|
||||||
|
|
||||||
/* send moved event */
|
/* 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 */
|
/* 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;
|
leftFingerDown = touch;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
|
CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
|
||||||
#ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
|
|
||||||
/* FIXME: TODO: Using touch as the fingerId is potentially dangerous
|
|
||||||
* It is also much more efficient than storing the UITouch pointer
|
|
||||||
* and comparing it to the incoming event.
|
|
||||||
*/
|
|
||||||
SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch),
|
SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch),
|
||||||
SDL_TRUE, locationInView.x, locationInView.y, 1.0f);
|
SDL_TRUE, locationInView.x, locationInView.y, 1.0f);
|
||||||
#else
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < MAX_SIMULTANEOUS_TOUCHES; i++) {
|
|
||||||
if (finger[i] == NULL) {
|
|
||||||
finger[i] = touch;
|
|
||||||
SDL_SendTouch(touchId, i,
|
|
||||||
SDL_TRUE, locationInView.x, locationInView.y, 1.0f);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
touch = (UITouch*)[enumerator nextObject];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
|
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
|
||||||
{
|
{
|
||||||
NSEnumerator *enumerator = [touches objectEnumerator];
|
for (UITouch *touch in touches) {
|
||||||
UITouch *touch = (UITouch*)[enumerator nextObject];
|
|
||||||
|
|
||||||
while(touch) {
|
|
||||||
if (touch == leftFingerDown) {
|
if (touch == leftFingerDown) {
|
||||||
/* send mouse up */
|
/* 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;
|
leftFingerDown = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
|
CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
|
||||||
#ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
|
SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch),
|
||||||
SDL_SendTouch(touchId, (long)touch,
|
|
||||||
SDL_FALSE, locationInView.x, locationInView.y, 1.0f);
|
SDL_FALSE, locationInView.x, locationInView.y, 1.0f);
|
||||||
#else
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < MAX_SIMULTANEOUS_TOUCHES; i++) {
|
|
||||||
if (finger[i] == touch) {
|
|
||||||
SDL_SendTouch(touchId, i,
|
|
||||||
SDL_FALSE, locationInView.x, locationInView.y, 1.0f);
|
|
||||||
finger[i] = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
touch = (UITouch*)[enumerator nextObject];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,32 +128,17 @@ void _uikit_keyboard_init() ;
|
||||||
|
|
||||||
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
|
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
|
||||||
{
|
{
|
||||||
NSEnumerator *enumerator = [touches objectEnumerator];
|
for (UITouch *touch in touches) {
|
||||||
UITouch *touch = (UITouch*)[enumerator nextObject];
|
|
||||||
|
|
||||||
while (touch) {
|
|
||||||
if (touch == leftFingerDown) {
|
if (touch == leftFingerDown) {
|
||||||
CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
|
CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
|
||||||
|
|
||||||
/* send moved event */
|
/* 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];
|
CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
|
||||||
#ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
|
SDL_SendTouchMotion(touchId, (SDL_FingerID)((size_t)touch),
|
||||||
SDL_SendTouchMotion(touchId, (long)touch,
|
|
||||||
locationInView.x, locationInView.y, 1.0f);
|
locationInView.x, locationInView.y, 1.0f);
|
||||||
#else
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < MAX_SIMULTANEOUS_TOUCHES; i++) {
|
|
||||||
if (finger[i] == touch) {
|
|
||||||
SDL_SendTouchMotion(touchId, i,
|
|
||||||
locationInView.x, locationInView.y, 1.0f);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
touch = (UITouch*)[enumerator nextObject];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,14 +147,9 @@ void _uikit_keyboard_init() ;
|
||||||
*/
|
*/
|
||||||
#if SDL_IPHONE_KEYBOARD
|
#if SDL_IPHONE_KEYBOARD
|
||||||
|
|
||||||
@synthesize textInputRect = textInputRect;
|
@synthesize textInputRect;
|
||||||
@synthesize keyboardHeight = keyboardHeight;
|
@synthesize keyboardHeight;
|
||||||
|
@synthesize keyboardVisible;
|
||||||
/* Is the iPhone virtual keyboard visible onscreen? */
|
|
||||||
- (BOOL)keyboardVisible
|
|
||||||
{
|
|
||||||
return keyboardVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set ourselves up as a UITextFieldDelegate */
|
/* Set ourselves up as a UITextFieldDelegate */
|
||||||
- (void)initializeKeyboard
|
- (void)initializeKeyboard
|
||||||
|
@ -229,7 +172,6 @@ void _uikit_keyboard_init() ;
|
||||||
keyboardVisible = NO;
|
keyboardVisible = NO;
|
||||||
/* add the UITextField (hidden) to our view */
|
/* add the UITextField (hidden) to our view */
|
||||||
[self addSubview: textField];
|
[self addSubview: textField];
|
||||||
[textField release];
|
|
||||||
|
|
||||||
_uikit_keyboard_init();
|
_uikit_keyboard_init();
|
||||||
}
|
}
|
||||||
|
@ -318,8 +260,8 @@ static SDL_uikitview * getWindowView(SDL_Window * window)
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
|
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
|
||||||
SDL_uikitview *view = data != NULL ? data->view : nil;
|
SDL_uikitview *view = data != nil ? data.view : nil;
|
||||||
|
|
||||||
if (view == nil) {
|
if (view == nil) {
|
||||||
SDL_SetError("Window has no view");
|
SDL_SetError("Window has no view");
|
||||||
|
@ -335,44 +277,49 @@ SDL_bool UIKit_HasScreenKeyboardSupport(_THIS)
|
||||||
|
|
||||||
void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window)
|
void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window)
|
||||||
{
|
{
|
||||||
SDL_uikitview *view = getWindowView(window);
|
@autoreleasepool {
|
||||||
if (view != nil) {
|
SDL_uikitview *view = getWindowView(window);
|
||||||
[view showKeyboard];
|
if (view != nil) {
|
||||||
|
[view showKeyboard];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window)
|
void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window)
|
||||||
{
|
{
|
||||||
SDL_uikitview *view = getWindowView(window);
|
@autoreleasepool {
|
||||||
if (view != nil) {
|
SDL_uikitview *view = getWindowView(window);
|
||||||
[view hideKeyboard];
|
if (view != nil) {
|
||||||
|
[view hideKeyboard];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window)
|
SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window)
|
||||||
{
|
{
|
||||||
SDL_uikitview *view = getWindowView(window);
|
@autoreleasepool {
|
||||||
if (view == nil) {
|
SDL_uikitview *view = getWindowView(window);
|
||||||
return 0;
|
if (view == nil) {
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return view.keyboardVisible;
|
return view.isKeyboardVisible;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _uikit_keyboard_update() {
|
void _uikit_keyboard_update() {
|
||||||
SDL_Window *window = SDL_GetFocusWindow();
|
SDL_Window *window = SDL_GetFocusWindow();
|
||||||
if (!window) { return; }
|
if (!window) { return; }
|
||||||
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
|
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
|
||||||
if (!data) { return; }
|
if (!data) { return; }
|
||||||
SDL_uikitview *view = data->view;
|
SDL_uikitview *view = data.view;
|
||||||
if (!view) { return; }
|
if (!view) { return; }
|
||||||
|
|
||||||
SDL_Rect r = view.textInputRect;
|
SDL_Rect r = view.textInputRect;
|
||||||
int height = view.keyboardHeight;
|
int height = view.keyboardHeight;
|
||||||
int offsetx = 0;
|
int offsetx = 0;
|
||||||
int offsety = 0;
|
int offsety = 0;
|
||||||
float scale = [UIScreen mainScreen].scale;
|
|
||||||
if (height) {
|
if (height) {
|
||||||
int sw,sh;
|
int sw,sh;
|
||||||
SDL_GetWindowSize(window,&sw,&sh);
|
SDL_GetWindowSize(window,&sw,&sh);
|
||||||
|
@ -394,18 +341,16 @@ void _uikit_keyboard_update() {
|
||||||
offsety = -offsety;
|
offsety = -offsety;
|
||||||
}
|
}
|
||||||
|
|
||||||
offsetx /= scale;
|
|
||||||
offsety /= scale;
|
|
||||||
|
|
||||||
view.frame = CGRectMake(offsetx,offsety,view.frame.size.width,view.frame.size.height);
|
view.frame = CGRectMake(offsetx,offsety,view.frame.size.width,view.frame.size.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _uikit_keyboard_set_height(int height) {
|
void _uikit_keyboard_set_height(int height) {
|
||||||
SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
|
SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
|
||||||
if (view == nil) {
|
if (view == nil) {
|
||||||
return ;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
view.keyboardVisible = height > 0;
|
||||||
view.keyboardHeight = height;
|
view.keyboardHeight = height;
|
||||||
_uikit_keyboard_update();
|
_uikit_keyboard_update();
|
||||||
}
|
}
|
||||||
|
@ -418,13 +363,12 @@ void _uikit_keyboard_init() {
|
||||||
queue:queue
|
queue:queue
|
||||||
usingBlock:^(NSNotification *notification) {
|
usingBlock:^(NSNotification *notification) {
|
||||||
int height = 0;
|
int height = 0;
|
||||||
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
|
CGSize keyboardSize = [[notification userInfo][UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
|
||||||
height = keyboardSize.height;
|
height = keyboardSize.height;
|
||||||
UIInterfaceOrientation ui_orient = [[UIApplication sharedApplication] statusBarOrientation];
|
UIInterfaceOrientation ui_orient = [[UIApplication sharedApplication] statusBarOrientation];
|
||||||
if (ui_orient == UIInterfaceOrientationLandscapeRight || ui_orient == UIInterfaceOrientationLandscapeLeft) {
|
if (ui_orient == UIInterfaceOrientationLandscapeRight || ui_orient == UIInterfaceOrientationLandscapeLeft) {
|
||||||
height = keyboardSize.width;
|
height = keyboardSize.width;
|
||||||
}
|
}
|
||||||
height *= [UIScreen mainScreen].scale;
|
|
||||||
_uikit_keyboard_set_height(height);
|
_uikit_keyboard_set_height(height);
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -444,13 +388,15 @@ UIKit_SetTextInputRect(_THIS, SDL_Rect *rect)
|
||||||
SDL_InvalidParamError("rect");
|
SDL_InvalidParamError("rect");
|
||||||
return;
|
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"
|
#include "../SDL_sysvideo.h"
|
||||||
|
|
||||||
@interface SDL_uikitviewcontroller : UIViewController {
|
@interface SDL_uikitviewcontroller : UIViewController
|
||||||
@private
|
|
||||||
SDL_Window *window;
|
|
||||||
}
|
|
||||||
|
|
||||||
@property (readwrite) SDL_Window *window;
|
@property (nonatomic, assign) SDL_Window *window;
|
||||||
|
|
||||||
- (id)initWithSDLWindow:(SDL_Window *)_window;
|
- (id)initWithSDLWindow:(SDL_Window *)_window;
|
||||||
- (void)loadView;
|
- (void)loadView;
|
||||||
|
@ -36,5 +33,6 @@
|
||||||
- (NSUInteger)supportedInterfaceOrientations;
|
- (NSUInteger)supportedInterfaceOrientations;
|
||||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient;
|
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient;
|
||||||
- (BOOL)prefersStatusBarHidden;
|
- (BOOL)prefersStatusBarHidden;
|
||||||
|
- (UIStatusBarStyle)preferredStatusBarStyle;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -40,12 +40,9 @@
|
||||||
|
|
||||||
- (id)initWithSDLWindow:(SDL_Window *)_window
|
- (id)initWithSDLWindow:(SDL_Window *)_window
|
||||||
{
|
{
|
||||||
self = [self init];
|
if (self = [super initWithNibName:nil bundle:nil]) {
|
||||||
if (self == nil) {
|
self.window = _window;
|
||||||
return nil;
|
|
||||||
}
|
}
|
||||||
self.window = _window;
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,31 +53,20 @@
|
||||||
|
|
||||||
- (void)viewDidLayoutSubviews
|
- (void)viewDidLayoutSubviews
|
||||||
{
|
{
|
||||||
if (self->window->flags & SDL_WINDOW_RESIZABLE) {
|
const CGSize size = self.view.bounds.size;
|
||||||
SDL_WindowData *data = self->window->driverdata;
|
int w = (int) size.width;
|
||||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(self->window);
|
int h = (int) size.height;
|
||||||
SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata;
|
|
||||||
const CGSize size = data->view.bounds.size;
|
|
||||||
int w, h;
|
|
||||||
|
|
||||||
w = (int)(size.width * displaymodedata->scale);
|
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h);
|
||||||
h = (int)(size.height * displaymodedata->scale);
|
|
||||||
|
|
||||||
SDL_SendWindowEvent(self->window, SDL_WINDOWEVENT_RESIZED, w, h);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSUInteger)supportedInterfaceOrientations
|
- (NSUInteger)supportedInterfaceOrientations
|
||||||
{
|
{
|
||||||
NSUInteger orientationMask = 0;
|
NSUInteger orientationMask = 0;
|
||||||
|
const char *hint = SDL_GetHint(SDL_HINT_ORIENTATIONS);
|
||||||
|
|
||||||
const char *orientationsCString;
|
if (hint != NULL) {
|
||||||
if ((orientationsCString = SDL_GetHint(SDL_HINT_ORIENTATIONS)) != NULL) {
|
NSArray *orientations = [@(hint) componentsSeparatedByString:@" "];
|
||||||
BOOL rotate = NO;
|
|
||||||
NSString *orientationsNSString = [NSString stringWithCString:orientationsCString
|
|
||||||
encoding:NSUTF8StringEncoding];
|
|
||||||
NSArray *orientations = [orientationsNSString componentsSeparatedByCharactersInSet:
|
|
||||||
[NSCharacterSet characterSetWithCharactersInString:@" "]];
|
|
||||||
|
|
||||||
if ([orientations containsObject:@"LandscapeLeft"]) {
|
if ([orientations containsObject:@"LandscapeLeft"]) {
|
||||||
orientationMask |= UIInterfaceOrientationMaskLandscapeLeft;
|
orientationMask |= UIInterfaceOrientationMaskLandscapeLeft;
|
||||||
|
@ -94,14 +80,17 @@
|
||||||
if ([orientations containsObject:@"PortraitUpsideDown"]) {
|
if ([orientations containsObject:@"PortraitUpsideDown"]) {
|
||||||
orientationMask |= UIInterfaceOrientationMaskPortraitUpsideDown;
|
orientationMask |= UIInterfaceOrientationMaskPortraitUpsideDown;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else if (self->window->flags & SDL_WINDOW_RESIZABLE) {
|
if (orientationMask == 0 && (window->flags & SDL_WINDOW_RESIZABLE)) {
|
||||||
orientationMask = UIInterfaceOrientationMaskAll; /* any orientation is okay. */
|
orientationMask = UIInterfaceOrientationMaskAll; /* any orientation is okay. */
|
||||||
} else {
|
}
|
||||||
if (self->window->w >= self->window->h) {
|
|
||||||
|
if (orientationMask == 0) {
|
||||||
|
if (window->w >= window->h) {
|
||||||
orientationMask |= UIInterfaceOrientationMaskLandscape;
|
orientationMask |= UIInterfaceOrientationMaskLandscape;
|
||||||
}
|
}
|
||||||
if (self->window->h >= self->window->w) {
|
if (window->h >= window->w) {
|
||||||
orientationMask |= (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
|
orientationMask |= (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,13 +110,19 @@
|
||||||
|
|
||||||
- (BOOL)prefersStatusBarHidden
|
- (BOOL)prefersStatusBarHidden
|
||||||
{
|
{
|
||||||
if (self->window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
|
if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
|
||||||
return YES;
|
return YES;
|
||||||
} else {
|
} else {
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (UIStatusBarStyle)preferredStatusBarStyle
|
||||||
|
{
|
||||||
|
/* We assume most games don't have a bright white background. */
|
||||||
|
return UIStatusBarStyleLightContent;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif /* SDL_VIDEO_DRIVER_UIKIT */
|
#endif /* SDL_VIDEO_DRIVER_UIKIT */
|
||||||
|
|
|
@ -26,12 +26,11 @@
|
||||||
#import "SDL_uikitopenglview.h"
|
#import "SDL_uikitopenglview.h"
|
||||||
#import "SDL_uikitviewcontroller.h"
|
#import "SDL_uikitviewcontroller.h"
|
||||||
|
|
||||||
typedef struct SDL_WindowData SDL_WindowData;
|
|
||||||
|
|
||||||
extern int UIKit_CreateWindow(_THIS, SDL_Window * window);
|
extern int UIKit_CreateWindow(_THIS, SDL_Window * window);
|
||||||
extern void UIKit_ShowWindow(_THIS, SDL_Window * window);
|
extern void UIKit_ShowWindow(_THIS, SDL_Window * window);
|
||||||
extern void UIKit_HideWindow(_THIS, SDL_Window * window);
|
extern void UIKit_HideWindow(_THIS, SDL_Window * window);
|
||||||
extern void UIKit_RaiseWindow(_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_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
|
||||||
extern void UIKit_DestroyWindow(_THIS, SDL_Window * window);
|
extern void UIKit_DestroyWindow(_THIS, SDL_Window * window);
|
||||||
extern SDL_bool UIKit_GetWindowWMInfo(_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;
|
@class UIWindow;
|
||||||
|
|
||||||
struct SDL_WindowData
|
@interface SDL_uikitwindow : UIWindow
|
||||||
{
|
|
||||||
UIWindow *uiwindow;
|
@end
|
||||||
SDL_uikitopenglview *view;
|
|
||||||
SDL_uikitviewcontroller *viewcontroller;
|
@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 */
|
#endif /* _SDL_uikitwindow_h */
|
||||||
|
|
||||||
|
|
|
@ -41,43 +41,56 @@
|
||||||
|
|
||||||
#include <Foundation/Foundation.h>
|
#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, SDL_uikitwindow *uiwindow, SDL_bool created)
|
||||||
static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created)
|
|
||||||
{
|
{
|
||||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
||||||
SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata;
|
SDL_DisplayData *displaydata = (__bridge SDL_DisplayData *) display->driverdata;
|
||||||
SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
|
|
||||||
SDL_WindowData *data;
|
|
||||||
|
|
||||||
/* Allocate the window data */
|
/* Allocate the window data */
|
||||||
data = (SDL_WindowData *)SDL_malloc(sizeof(*data));
|
SDL_WindowData *data = [[SDL_WindowData alloc] init];
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
data->uiwindow = uiwindow;
|
|
||||||
data->viewcontroller = nil;
|
data.uiwindow = uiwindow;
|
||||||
data->view = nil;
|
|
||||||
|
|
||||||
/* Fill in the SDL window with the window data */
|
/* Fill in the SDL window with the window data */
|
||||||
{
|
{
|
||||||
window->x = 0;
|
window->x = 0;
|
||||||
window->y = 0;
|
window->y = 0;
|
||||||
|
|
||||||
CGRect bounds;
|
CGRect frame = UIKit_ComputeViewFrame(window, displaydata.uiscreen);
|
||||||
if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
|
|
||||||
bounds = [displaydata->uiscreen bounds];
|
|
||||||
} else {
|
|
||||||
bounds = [displaydata->uiscreen applicationFrame];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get frame dimensions in pixels */
|
/* Get frame dimensions */
|
||||||
int width = (int)(bounds.size.width * displaymodedata->scale);
|
int width = (int) frame.size.width;
|
||||||
int height = (int)(bounds.size.height * displaymodedata->scale);
|
int height = (int) frame.size.height;
|
||||||
|
|
||||||
/* Make sure the width/height are oriented correctly */
|
/* 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;
|
int temp = width;
|
||||||
width = height;
|
width = height;
|
||||||
height = temp;
|
height = temp;
|
||||||
|
@ -87,7 +100,7 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
|
||||||
window->h = height;
|
window->h = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
window->driverdata = data;
|
window->driverdata = (void *) CFBridgingRetain(data);
|
||||||
|
|
||||||
/* only one window on iOS, always shown */
|
/* only one window on iOS, always shown */
|
||||||
window->flags &= ~SDL_WINDOW_HIDDEN;
|
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
|
* This is only set if the window is on the main screen. Other screens
|
||||||
* just force the window to have the borderless flag.
|
* 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 */
|
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
|
/* 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
|
* device orientation changes. This will trigger resize events, if
|
||||||
* appropriate.
|
* appropriate.
|
||||||
*/
|
*/
|
||||||
SDL_uikitviewcontroller *controller;
|
data.viewcontroller = [[SDL_uikitviewcontroller alloc] initWithSDLWindow:window];
|
||||||
controller = [SDL_uikitviewcontroller alloc];
|
data.viewcontroller.title = @"SDL App"; /* !!! FIXME: hook up SDL_SetWindowTitle() */
|
||||||
data->viewcontroller = [controller initWithSDLWindow:window];
|
|
||||||
[data->viewcontroller setTitle:@"SDL App"]; /* !!! FIXME: hook up SDL_SetWindowTitle() */
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -127,105 +138,109 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
|
||||||
int
|
int
|
||||||
UIKit_CreateWindow(_THIS, SDL_Window *window)
|
UIKit_CreateWindow(_THIS, SDL_Window *window)
|
||||||
{
|
{
|
||||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
@autoreleasepool {
|
||||||
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
|
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
||||||
const BOOL external = ([UIScreen mainScreen] != data->uiscreen);
|
SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
|
||||||
const CGSize origsize = [[data->uiscreen currentMode] size];
|
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 currently puts this window at the start of display's linked list. We rely on this. */
|
||||||
SDL_assert(_this->windows == window);
|
SDL_assert(_this->windows == window);
|
||||||
|
|
||||||
/* We currently only handle a single window per display on iOS */
|
/* We currently only handle a single window per display on iOS */
|
||||||
if (window->next != NULL) {
|
if (window->next != NULL) {
|
||||||
return SDL_SetError("Only one window allowed per display.");
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
/* If monitor has a resolution of 0x0 (hasn't been explicitly set by the
|
||||||
const SDL_DisplayMode *bestmode = NULL;
|
* user, so it's in standby), try to force the display to a resolution
|
||||||
for (i = display->num_display_modes; i >= 0; i--) {
|
* that most closely matches the desired window size.
|
||||||
const SDL_DisplayMode *mode = &display->display_modes[i];
|
*/
|
||||||
if ((mode->w >= window->w) && (mode->h >= window->h))
|
if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) {
|
||||||
bestmode = mode;
|
if (display->num_display_modes == 0) {
|
||||||
}
|
_this->GetDisplayModes(_this, display);
|
||||||
|
|
||||||
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];
|
|
||||||
}
|
}
|
||||||
} else if (window->w < window->h) {
|
|
||||||
if (UIKit_IsDisplayLandscape(data->uiscreen)) {
|
int i;
|
||||||
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
|
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 */
|
if (data.uiscreen == [UIScreen mainScreen]) {
|
||||||
/* !!! FIXME: can we have a smaller view? */
|
if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
|
||||||
UIWindow *uiwindow = [UIWindow alloc];
|
[UIApplication sharedApplication].statusBarHidden = YES;
|
||||||
uiwindow = [uiwindow initWithFrame:[data->uiscreen bounds]];
|
} else {
|
||||||
|
[UIApplication sharedApplication].statusBarHidden = NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* put the window on an external display if appropriate. This implicitly
|
if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
|
||||||
* does [uiwindow setframe:[uiscreen bounds]], so don't do it on the
|
if (window->w > window->h) {
|
||||||
* main display, where we land by default, as that would eat the
|
if (!UIKit_IsDisplayLandscape(data.uiscreen)) {
|
||||||
* status bar real estate.
|
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
|
||||||
*/
|
}
|
||||||
if (external) {
|
} else if (window->w < window->h) {
|
||||||
[uiwindow setScreen:data->uiscreen];
|
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;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
UIKit_ShowWindow(_THIS, SDL_Window * window)
|
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
|
void
|
||||||
UIKit_HideWindow(_THIS, SDL_Window * window)
|
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
|
void
|
||||||
|
@ -239,91 +254,106 @@ UIKit_RaiseWindow(_THIS, SDL_Window * window)
|
||||||
_this->GL_MakeCurrent(_this, _this->current_glwin, _this->current_glctx);
|
_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
|
void
|
||||||
UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
|
UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
|
||||||
{
|
{
|
||||||
SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
|
@autoreleasepool {
|
||||||
SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata;
|
UIKit_UpdateWindowBorder(_this, window);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
UIKit_DestroyWindow(_THIS, SDL_Window * window)
|
UIKit_DestroyWindow(_THIS, SDL_Window * window)
|
||||||
{
|
{
|
||||||
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
|
@autoreleasepool {
|
||||||
|
if (window->driverdata != NULL) {
|
||||||
if (data) {
|
CFRelease(window->driverdata);
|
||||||
[data->viewcontroller release];
|
}
|
||||||
[data->uiwindow release];
|
|
||||||
SDL_free(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window->driverdata = NULL;
|
window->driverdata = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
SDL_bool
|
||||||
UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
|
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) {
|
if (info->version.major <= SDL_MAJOR_VERSION) {
|
||||||
info->subsystem = SDL_SYSWM_UIKIT;
|
info->subsystem = SDL_SYSWM_UIKIT;
|
||||||
info->info.uikit.window = uiwindow;
|
info->info.uikit.window = uiwindow;
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
} else {
|
} else {
|
||||||
SDL_SetError("Application not compiled with SDL %d.%d\n",
|
SDL_SetError("Application not compiled with SDL %d.%d\n",
|
||||||
SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
|
SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam)
|
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) {
|
if (!data || !data.view) {
|
||||||
return SDL_SetError("Invalid window or view not set");
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue