summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorBastiaanOlij <mux213@gmail.com>2017-05-14 17:28:59 +1000
committerBastiaanOlij <mux213@gmail.com>2017-05-17 22:38:49 +1000
commit1f4f784e7dffa1ac508b50e5ceef6365a5b241a9 (patch)
treed2aaa40385d8e0edd7c35d1bb00c365d32e91a5c /platform
parent98a329670227c726a5d7a196e5cba8dbdd54301b (diff)
MFI gamepad support for iPhone
Diffstat (limited to 'platform')
-rw-r--r--platform/iphone/app_delegate.mm512
-rw-r--r--platform/iphone/os_iphone.cpp16
-rw-r--r--platform/iphone/os_iphone.h5
3 files changed, 452 insertions, 81 deletions
diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm
index e075941d36..5dc0fb08b1 100644
--- a/platform/iphone/app_delegate.mm
+++ b/platform/iphone/app_delegate.mm
@@ -49,6 +49,8 @@
#import <Parse/Parse.h>
#endif
+#import "GameController/GameController.h"
+
#define kFilteringFactor 0.1
#define kRenderingFrequency 60
#define kAccelerometerFrequency 100.0 // Hz
@@ -89,6 +91,282 @@ static ViewController *mainViewController = nil;
return mainViewController;
}
+NSMutableDictionary *ios_joysticks = nil;
+
+- (GCControllerPlayerIndex)getFreePlayerIndex {
+ bool have_player_1 = false;
+ bool have_player_2 = false;
+ bool have_player_3 = false;
+ bool have_player_4 = false;
+
+ if (ios_joysticks == nil) {
+ NSArray *keys = [ios_joysticks allKeys];
+ for (NSNumber *key in keys) {
+ GCController *controller = [ios_joysticks objectForKey:key];
+ if (controller.playerIndex == GCControllerPlayerIndex1) {
+ have_player_1 = true;
+ } else if (controller.playerIndex == GCControllerPlayerIndex2) {
+ have_player_2 = true;
+ } else if (controller.playerIndex == GCControllerPlayerIndex3) {
+ have_player_3 = true;
+ } else if (controller.playerIndex == GCControllerPlayerIndex4) {
+ have_player_4 = true;
+ };
+ };
+ };
+
+ if (!have_player_1) {
+ return GCControllerPlayerIndex1;
+ } else if (!have_player_2) {
+ return GCControllerPlayerIndex2;
+ } else if (!have_player_3) {
+ return GCControllerPlayerIndex3;
+ } else if (!have_player_4) {
+ return GCControllerPlayerIndex4;
+ } else {
+ return GCControllerPlayerIndexUnset;
+ };
+};
+
+- (void)controllerWasConnected:(NSNotification *)notification {
+ // create our dictionary if we don't have one yet
+ if (ios_joysticks == nil) {
+ ios_joysticks = [[NSMutableDictionary alloc] init];
+ };
+
+ // get our controller
+ GCController *controller = (GCController *)notification.object;
+ if (controller == nil) {
+ printf("Couldn't retrieve new controller\n");
+ } else if ([[ios_joysticks allKeysForObject:controller] count] != 0) {
+ printf("Controller is already registered\n");
+ } else {
+ // get a new id for our controller
+ int joy_id = OSIPhone::get_singleton()->get_unused_joy_id();
+ if (joy_id != -1) {
+ // assign our player index
+ if (controller.playerIndex == GCControllerPlayerIndexUnset) {
+ controller.playerIndex = [self getFreePlayerIndex];
+ };
+
+ // tell Godot about our new controller
+ OSIPhone::get_singleton()->joy_connection_changed(
+ joy_id, true, [controller.vendorName UTF8String]);
+
+ // add it to our dictionary, this will retain our controllers
+ [ios_joysticks setObject:controller
+ forKey:[NSNumber numberWithInt:joy_id]];
+
+ // set our input handler
+ [self setControllerInputHandler:controller];
+ } else {
+ printf("Couldn't retrieve new joy id\n");
+ };
+ };
+};
+
+- (void)controllerWasDisconnected:(NSNotification *)notification {
+ if (ios_joysticks != nil) {
+ // find our joystick, there should be only one in our dictionary
+ GCController *controller = (GCController *)notification.object;
+ NSArray *keys = [ios_joysticks allKeysForObject:controller];
+ for (NSNumber *key in keys) {
+ // tell Godot this joystick is no longer there
+ int joy_id = [key intValue];
+ OSIPhone::get_singleton()->joy_connection_changed(joy_id, false, "");
+
+ // and remove it from our dictionary
+ [ios_joysticks removeObjectForKey:key];
+ };
+ };
+};
+
+- (int)getJoyIdForController:(GCController *)controller {
+ if (ios_joysticks != nil) {
+ // find our joystick, there should be only one in our dictionary
+ NSArray *keys = [ios_joysticks allKeysForObject:controller];
+ for (NSNumber *key in keys) {
+ int joy_id = [key intValue];
+ return joy_id;
+ };
+ };
+
+ return -1;
+};
+
+- (void)setControllerInputHandler:(GCController *)controller {
+ // Hook in the callback handler for the correct gamepad profile.
+ // This is a bit of a weird design choice on Apples part.
+ // You need to select the most capable gamepad profile for the
+ // gamepad attached.
+ if (controller.extendedGamepad != nil) {
+ // The extended gamepad profile has all the input you could possibly find on
+ // a gamepad but will only be active if your gamepad actually has all of
+ // these...
+ controller.extendedGamepad.valueChangedHandler = ^(
+ GCExtendedGamepad *gamepad, GCControllerElement *element) {
+ int joy_id = [self getJoyIdForController:controller];
+
+ if (element == gamepad.buttonA) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_0,
+ gamepad.buttonA.isPressed);
+ } else if (element == gamepad.buttonB) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_1,
+ gamepad.buttonB.isPressed);
+ } else if (element == gamepad.buttonX) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_2,
+ gamepad.buttonX.isPressed);
+ } else if (element == gamepad.buttonY) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_3,
+ gamepad.buttonY.isPressed);
+ } else if (element == gamepad.leftShoulder) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_L,
+ gamepad.leftShoulder.isPressed);
+ } else if (element == gamepad.rightShoulder) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_R,
+ gamepad.rightShoulder.isPressed);
+ } else if (element == gamepad.leftTrigger) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_L2,
+ gamepad.leftTrigger.isPressed);
+ } else if (element == gamepad.rightTrigger) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_R2,
+ gamepad.rightTrigger.isPressed);
+ } else if (element == gamepad.dpad) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_UP,
+ gamepad.dpad.up.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_DOWN,
+ gamepad.dpad.down.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_LEFT,
+ gamepad.dpad.left.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_RIGHT,
+ gamepad.dpad.right.isPressed);
+ };
+
+ InputDefault::JoyAxis jx;
+ jx.min = -1;
+ if (element == gamepad.leftThumbstick) {
+ jx.value = gamepad.leftThumbstick.xAxis.value;
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_LX, jx);
+ jx.value = -gamepad.leftThumbstick.yAxis.value;
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_LY, jx);
+ } else if (element == gamepad.rightThumbstick) {
+ jx.value = gamepad.rightThumbstick.xAxis.value;
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_RX, jx);
+ jx.value = -gamepad.rightThumbstick.yAxis.value;
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_RY, jx);
+ } else if (element == gamepad.leftTrigger) {
+ jx.value = gamepad.leftTrigger.value;
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_L2, jx);
+ } else if (element == gamepad.rightTrigger) {
+ jx.value = gamepad.rightTrigger.value;
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_R2, jx);
+ };
+ };
+ } else if (controller.gamepad != nil) {
+ // gamepad is the standard profile with 4 buttons, shoulder buttons and a
+ // D-pad
+ controller.gamepad.valueChangedHandler = ^(GCGamepad *gamepad,
+ GCControllerElement *element) {
+ int joy_id = [self getJoyIdForController:controller];
+
+ if (element == gamepad.buttonA) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_0,
+ gamepad.buttonA.isPressed);
+ } else if (element == gamepad.buttonB) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_1,
+ gamepad.buttonB.isPressed);
+ } else if (element == gamepad.buttonX) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_2,
+ gamepad.buttonX.isPressed);
+ } else if (element == gamepad.buttonY) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_3,
+ gamepad.buttonY.isPressed);
+ } else if (element == gamepad.leftShoulder) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_L,
+ gamepad.leftShoulder.isPressed);
+ } else if (element == gamepad.rightShoulder) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_R,
+ gamepad.rightShoulder.isPressed);
+ } else if (element == gamepad.dpad) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_UP,
+ gamepad.dpad.up.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_DOWN,
+ gamepad.dpad.down.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_LEFT,
+ gamepad.dpad.left.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_RIGHT,
+ gamepad.dpad.right.isPressed);
+ };
+ };
+#ifdef ADD_MICRO_GAMEPAD // disabling this for now, only available on iOS 9+,
+ // while we are setting that as the minimum, seems our
+ // build environment doesn't like it
+ } else if (controller.microGamepad != nil) {
+ // micro gamepads were added in OS 9 and feature just 2 buttons and a d-pad
+ controller.microGamepad.valueChangedHandler =
+ ^(GCMicroGamepad *gamepad, GCControllerElement *element) {
+ int joy_id = [self getJoyIdForController:controller];
+
+ if (element == gamepad.buttonA) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_0,
+ gamepad.buttonA.isPressed);
+ } else if (element == gamepad.buttonX) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_2,
+ gamepad.buttonX.isPressed);
+ } else if (element == gamepad.dpad) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_UP,
+ gamepad.dpad.up.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_DOWN,
+ gamepad.dpad.down.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_LEFT,
+ gamepad.dpad.left.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_RIGHT,
+ gamepad.dpad.right.isPressed);
+ };
+ };
+#endif
+ };
+
+ ///@TODO need to add support for controller.motion which gives us access to
+ /// the orientation of the device (if supported)
+
+ ///@TODO need to add support for controllerPausedHandler which should be a
+ /// toggle
+};
+
+- (void)initGameControllers {
+ // get told when controllers connect, this will be called right away for
+ // already connected controllers
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(controllerWasConnected:)
+ name:GCControllerDidConnectNotification
+ object:nil];
+
+ // get told when controllers disconnect
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(controllerWasDisconnected:)
+ name:GCControllerDidDisconnectNotification
+ object:nil];
+};
+
+- (void)deinitGameControllers {
+ [[NSNotificationCenter defaultCenter]
+ removeObserver:self
+ name:GCControllerDidConnectNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter]
+ removeObserver:self
+ name:GCControllerDidDisconnectNotification
+ object:nil];
+
+ if (ios_joysticks != nil) {
+ [ios_joysticks dealloc];
+ ios_joysticks = nil;
+ };
+};
+
static int frame_count = 0;
- (void)drawView:(GLView *)view;
{
@@ -97,8 +375,10 @@ static int frame_count = 0;
case 0: {
int backingWidth;
int backingHeight;
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES,
+ GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES,
+ GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
OS::VideoMode vm;
vm.fullscreen = true;
@@ -112,25 +392,35 @@ static int frame_count = 0;
};
++frame_count;
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
+ NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
- //NSString *documentsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
- OSIPhone::get_singleton()->set_data_dir(String::utf8([documentsDirectory UTF8String]));
+ // NSString *documentsDirectory = [[[NSFileManager defaultManager]
+ // URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]
+ // lastObject];
+ OSIPhone::get_singleton()->set_data_dir(
+ String::utf8([documentsDirectory UTF8String]));
- NSString *locale_code = [[[NSLocale preferredLanguages] objectAtIndex:0] substringToIndex:2];
- OSIPhone::get_singleton()->set_locale(String::utf8([locale_code UTF8String]));
+ NSString *locale_code =
+ [[[NSLocale preferredLanguages] objectAtIndex:0] substringToIndex:2];
+ OSIPhone::get_singleton()->set_locale(
+ String::utf8([locale_code UTF8String]));
NSString *uuid;
- if ([[UIDevice currentDevice] respondsToSelector:@selector(identifierForVendor)]) {
+ if ([[UIDevice currentDevice]
+ respondsToSelector:@selector(identifierForVendor)]) {
uuid = [UIDevice currentDevice].identifierForVendor.UUIDString;
} else {
// before iOS 6, so just generate an identifier and store it
- uuid = [[NSUserDefaults standardUserDefaults] objectForKey:@"identiferForVendor"];
+ uuid = [[NSUserDefaults standardUserDefaults]
+ objectForKey:@"identiferForVendor"];
if (!uuid) {
CFUUIDRef cfuuid = CFUUIDCreate(NULL);
uuid = (__bridge_transfer NSString *)CFUUIDCreateString(NULL, cfuuid);
CFRelease(cfuuid);
- [[NSUserDefaults standardUserDefaults] setObject:uuid forKey:@"identifierForVendor"];
+ [[NSUserDefaults standardUserDefaults]
+ setObject:uuid
+ forKey:@"identifierForVendor"];
}
}
@@ -138,9 +428,9 @@ static int frame_count = 0;
}; break;
/*
- case 1: {
- ++frame_count;
- }; break;
+ case 1: {
+ ++frame_count;
+ }; break;
*/
case 1: {
@@ -173,9 +463,9 @@ static int frame_count = 0;
}; break;
/*
- case 3: {
- ++frame_count;
- }; break;
+ case 3: {
+ ++frame_count;
+ }; break;
*/
case 2: {
@@ -186,53 +476,85 @@ static int frame_count = 0;
default: {
if (OSIPhone::get_singleton()) {
- //OSIPhone::get_singleton()->update_accelerometer(accel[0], accel[1], accel[2]);
+ // OSIPhone::get_singleton()->update_accelerometer(accel[0], accel[1],
+ // accel[2]);
if (motionInitialised) {
- // Just using polling approach for now, we can set this up so it sends data to us in intervals, might be better.
- // See Apple reference pages for more details:
+ // Just using polling approach for now, we can set this up so it sends
+ // data to us in intervals, might be better. See Apple reference pages
+ // for more details:
// https://developer.apple.com/reference/coremotion/cmmotionmanager?language=objc
- // Apple splits our accelerometer date into a gravity and user movement component. We add them back together
+ // Apple splits our accelerometer date into a gravity and user movement
+ // component. We add them back together
CMAcceleration gravity = motionManager.deviceMotion.gravity;
- CMAcceleration acceleration = motionManager.deviceMotion.userAcceleration;
+ CMAcceleration acceleration =
+ motionManager.deviceMotion.userAcceleration;
- ///@TODO We don't seem to be getting data here, is my device broken or is this code incorrect?
- CMMagneticField magnetic = motionManager.deviceMotion.magneticField.field;
+ ///@TODO We don't seem to be getting data here, is my device broken or
+ /// is this code incorrect?
+ CMMagneticField magnetic =
+ motionManager.deviceMotion.magneticField.field;
- ///@TODO we can access rotationRate as a CMRotationRate variable (processed date) or CMGyroData (raw data), have to see what works best
+ ///@TODO we can access rotationRate as a CMRotationRate variable
+ ///(processed date) or CMGyroData (raw data), have to see what works
+ /// best
CMRotationRate rotation = motionManager.deviceMotion.rotationRate;
// Adjust for screen orientation.
- // [[UIDevice currentDevice] orientation] changes even if we've fixed our orientation which is not
- // a good thing when you're trying to get your user to move the screen in all directions and want consistent output
-
- ///@TODO Using [[UIApplication sharedApplication] statusBarOrientation] is a bit of a hack. Godot obviously knows the orientation so maybe we
+ // [[UIDevice currentDevice] orientation] changes even if we've fixed
+ // our orientation which is not a good thing when you're trying to get
+ // your user to move the screen in all directions and want consistent
+ // output
+
+ ///@TODO Using [[UIApplication sharedApplication] statusBarOrientation]
+ /// is a bit of a hack. Godot obviously knows the orientation so maybe
+ /// we
// can use that instead? (note that left and right seem swapped)
switch ([[UIApplication sharedApplication] statusBarOrientation]) {
case UIDeviceOrientationLandscapeLeft: {
- OSIPhone::get_singleton()->update_gravity(-gravity.y, gravity.x, gravity.z);
- OSIPhone::get_singleton()->update_accelerometer(-(acceleration.y + gravity.y), (acceleration.x + gravity.x), acceleration.z + gravity.z);
- OSIPhone::get_singleton()->update_magnetometer(-magnetic.y, magnetic.x, magnetic.z);
- OSIPhone::get_singleton()->update_gyroscope(-rotation.y, rotation.x, rotation.z);
+ OSIPhone::get_singleton()->update_gravity(-gravity.y, gravity.x,
+ gravity.z);
+ OSIPhone::get_singleton()->update_accelerometer(
+ -(acceleration.y + gravity.y), (acceleration.x + gravity.x),
+ acceleration.z + gravity.z);
+ OSIPhone::get_singleton()->update_magnetometer(
+ -magnetic.y, magnetic.x, magnetic.z);
+ OSIPhone::get_singleton()->update_gyroscope(-rotation.y, rotation.x,
+ rotation.z);
}; break;
case UIDeviceOrientationLandscapeRight: {
- OSIPhone::get_singleton()->update_gravity(gravity.y, -gravity.x, gravity.z);
- OSIPhone::get_singleton()->update_accelerometer((acceleration.y + gravity.y), -(acceleration.x + gravity.x), acceleration.z + gravity.z);
- OSIPhone::get_singleton()->update_magnetometer(magnetic.y, -magnetic.x, magnetic.z);
- OSIPhone::get_singleton()->update_gyroscope(rotation.y, -rotation.x, rotation.z);
+ OSIPhone::get_singleton()->update_gravity(gravity.y, -gravity.x,
+ gravity.z);
+ OSIPhone::get_singleton()->update_accelerometer(
+ (acceleration.y + gravity.y), -(acceleration.x + gravity.x),
+ acceleration.z + gravity.z);
+ OSIPhone::get_singleton()->update_magnetometer(
+ magnetic.y, -magnetic.x, magnetic.z);
+ OSIPhone::get_singleton()->update_gyroscope(rotation.y, -rotation.x,
+ rotation.z);
}; break;
case UIDeviceOrientationPortraitUpsideDown: {
- OSIPhone::get_singleton()->update_gravity(-gravity.x, gravity.y, gravity.z);
- OSIPhone::get_singleton()->update_accelerometer(-(acceleration.x + gravity.x), (acceleration.y + gravity.y), acceleration.z + gravity.z);
- OSIPhone::get_singleton()->update_magnetometer(-magnetic.x, magnetic.y, magnetic.z);
- OSIPhone::get_singleton()->update_gyroscope(-rotation.x, rotation.y, rotation.z);
+ OSIPhone::get_singleton()->update_gravity(-gravity.x, gravity.y,
+ gravity.z);
+ OSIPhone::get_singleton()->update_accelerometer(
+ -(acceleration.x + gravity.x), (acceleration.y + gravity.y),
+ acceleration.z + gravity.z);
+ OSIPhone::get_singleton()->update_magnetometer(
+ -magnetic.x, magnetic.y, magnetic.z);
+ OSIPhone::get_singleton()->update_gyroscope(-rotation.x, rotation.y,
+ rotation.z);
}; break;
default: { // assume portrait
- OSIPhone::get_singleton()->update_gravity(gravity.x, gravity.y, gravity.z);
- OSIPhone::get_singleton()->update_accelerometer(acceleration.x + gravity.x, acceleration.y + gravity.y, acceleration.z + gravity.z);
- OSIPhone::get_singleton()->update_magnetometer(magnetic.x, magnetic.y, magnetic.z);
- OSIPhone::get_singleton()->update_gyroscope(rotation.x, rotation.y, rotation.z);
+ OSIPhone::get_singleton()->update_gravity(gravity.x, gravity.y,
+ gravity.z);
+ OSIPhone::get_singleton()->update_accelerometer(
+ acceleration.x + gravity.x, acceleration.y + gravity.y,
+ acceleration.z + gravity.z);
+ OSIPhone::get_singleton()->update_magnetometer(magnetic.x, magnetic.y,
+ magnetic.z);
+ OSIPhone::get_singleton()->update_gyroscope(rotation.x, rotation.y,
+ rotation.z);
}; break;
};
}
@@ -247,7 +569,8 @@ static int frame_count = 0;
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
printf("****************** did receive memory warning!\n");
- OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_MEMORY_WARNING);
+ OS::get_singleton()->get_main_loop()->notification(
+ MainLoop::NOTIFICATION_OS_MEMORY_WARNING);
};
- (void)applicationDidFinishLaunching:(UIApplication *)application {
@@ -257,25 +580,29 @@ static int frame_count = 0;
[application setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
// disable idle timer
- //application.idleTimerDisabled = YES;
+ // application.idleTimerDisabled = YES;
- //Create a full-screen window
+ // Create a full-screen window
window = [[UIWindow alloc] initWithFrame:rect];
- //window.autoresizesSubviews = YES;
- //[window setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth];
+ // window.autoresizesSubviews = YES;
+ //[window setAutoresizingMask:UIViewAutoresizingFlexibleWidth |
+ // UIViewAutoresizingFlexibleWidth];
- //Create the OpenGL ES view and add it to the window
+ // Create the OpenGL ES view and add it to the window
GLView *glView = [[GLView alloc] initWithFrame:rect];
printf("glview is %p\n", glView);
//[window addSubview:glView];
glView.delegate = self;
- //glView.autoresizesSubviews = YES;
- //[glView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth];
+ // glView.autoresizesSubviews = YES;
+ //[glView setAutoresizingMask:UIViewAutoresizingFlexibleWidth |
+ // UIViewAutoresizingFlexibleWidth];
int backingWidth;
int backingHeight;
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES,
+ GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES,
+ GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
iphone_main(backingWidth, backingHeight, gargc, gargv);
@@ -284,26 +611,30 @@ static int frame_count = 0;
window.rootViewController = view_controller;
_set_keep_screen_on(bool(GLOBAL_DEF("display/keep_screen_on", true)) ? YES : NO);
- glView.useCADisplayLink = bool(GLOBAL_DEF("display.iOS/use_cadisplaylink", true)) ? YES : NO;
+ glView.useCADisplayLink =
+ bool(GLOBAL_DEF("display.iOS/use_cadisplaylink", true)) ? YES : NO;
printf("cadisaplylink: %d", glView.useCADisplayLink);
glView.animationInterval = 1.0 / kRenderingFrequency;
[glView startAnimation];
- //Show the window
+ // Show the window
[window makeKeyAndVisible];
- //Configure and start accelerometer
+ // Configure and start accelerometer
if (!motionInitialised) {
motionManager = [[CMMotionManager alloc] init];
if (motionManager.deviceMotionAvailable) {
motionManager.deviceMotionUpdateInterval = 1.0 / 70.0;
- [motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXMagneticNorthZVertical];
+ [motionManager startDeviceMotionUpdatesUsingReferenceFrame:
+ CMAttitudeReferenceFrameXMagneticNorthZVertical];
motionInitialised = YES;
};
};
- //OSIPhone::screen_width = rect.size.width - rect.origin.x;
- //OSIPhone::screen_height = rect.size.height - rect.origin.y;
+ [self initGameControllers];
+
+ // OSIPhone::screen_width = rect.size.width - rect.origin.x;
+ // OSIPhone::screen_height = rect.size.height - rect.origin.y;
mainViewController = view_controller;
@@ -319,16 +650,22 @@ static int frame_count = 0;
String adid = GLOBAL_DEF("mobileapptracker/advertiser_id", "");
String convkey = GLOBAL_DEF("mobileapptracker/conversion_key", "");
- NSString *advertiser_id = [NSString stringWithUTF8String:adid.utf8().get_data()];
- NSString *conversion_key = [NSString stringWithUTF8String:convkey.utf8().get_data()];
+ NSString *advertiser_id =
+ [NSString stringWithUTF8String:adid.utf8().get_data()];
+ NSString *conversion_key =
+ [NSString stringWithUTF8String:convkey.utf8().get_data()];
// Account Configuration info - must be set
- [MobileAppTracker initializeWithMATAdvertiserId:advertiser_id MATConversionKey:conversion_key];
+ [MobileAppTracker initializeWithMATAdvertiserId:advertiser_id
+ MATConversionKey:conversion_key];
// Used to pass us the IFA, enables highly accurate 1-to-1 attribution.
// Required for many advertising networks.
- [MobileAppTracker setAppleAdvertisingIdentifier:[[ASIdentifierManager sharedManager] advertisingIdentifier]
- advertisingTrackingEnabled:[[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]];
+ [MobileAppTracker
+ setAppleAdvertisingIdentifier:[[ASIdentifierManager sharedManager]
+ advertisingIdentifier]
+ advertisingTrackingEnabled:[[ASIdentifierManager sharedManager]
+ isAdvertisingTrackingEnabled]];
#endif
};
@@ -337,6 +674,8 @@ static int frame_count = 0;
printf("********************* will terminate\n");
+ [self deinitGameControllers];
+
if (motionInitialised) {
///@TODO is this the right place to clean this up?
[motionManager stopDeviceMotionUpdates];
@@ -353,7 +692,8 @@ static int frame_count = 0;
///@TODO maybe add pause motionManager? and where would we unpause it?
if (OS::get_singleton()->get_main_loop())
- OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
+ OS::get_singleton()->get_main_loop()->notification(
+ MainLoop::NOTIFICATION_WM_FOCUS_OUT);
[view_controller.view stopAnimation];
if (OS::get_singleton()->native_video_is_playing()) {
@@ -363,14 +703,15 @@ static int frame_count = 0;
- (void)applicationWillEnterForeground:(UIApplication *)application {
printf("********************* did enter foreground\n");
- //OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
+ // OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
[view_controller.view startAnimation];
}
- (void)applicationWillResignActive:(UIApplication *)application {
printf("********************* will resign active\n");
- //OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
- [view_controller.view stopAnimation]; // FIXME: pause seems to be recommended elsewhere
+ // OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
+ [view_controller.view
+ stopAnimation]; // FIXME: pause seems to be recommended elsewhere
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
@@ -380,9 +721,11 @@ static int frame_count = 0;
[MobileAppTracker measureSession];
#endif
if (OS::get_singleton()->get_main_loop())
- OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
+ OS::get_singleton()->get_main_loop()->notification(
+ MainLoop::NOTIFICATION_WM_FOCUS_IN);
- [view_controller.view startAnimation]; // FIXME: resume seems to be recommended elsewhere
+ [view_controller.view
+ startAnimation]; // FIXME: resume seems to be recommended elsewhere
if (OSIPhone::get_singleton()->native_video_is_playing()) {
OSIPhone::get_singleton()->native_video_unpause();
};
@@ -397,14 +740,17 @@ static int frame_count = 0;
}
// For 4.2+ support
-- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
+- (BOOL)application:(UIApplication *)application
+ openURL:(NSURL *)url
+ sourceApplication:(NSString *)sourceApplication
+ annotation:(id)annotation {
#ifdef MODULE_PARSE_ENABLED
NSLog(@"Handling application openURL");
- return [[FBSDKApplicationDelegate sharedInstance]
- application:application
- openURL:url
- sourceApplication:sourceApplication
- annotation:annotation];
+ return
+ [[FBSDKApplicationDelegate sharedInstance] application:application
+ openURL:url
+ sourceApplication:sourceApplication
+ annotation:annotation];
#endif
#ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED
@@ -414,21 +760,25 @@ static int frame_count = 0;
#endif
}
-- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
+- (void)application:(UIApplication *)application
+ didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
#ifdef MODULE_PARSE_ENABLED
// Store the deviceToken in the current installation and save it to Parse.
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
- //NSString* token = [[NSString alloc] initWithData:deviceToken encoding:NSUTF8StringEncoding];
+ // NSString* token = [[NSString alloc] initWithData:deviceToken
+ // encoding:NSUTF8StringEncoding];
NSLog(@"Device Token : %@ ", deviceToken);
[currentInstallation setDeviceTokenFromData:deviceToken];
[currentInstallation saveInBackground];
#endif
}
-- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
+- (void)application:(UIApplication *)application
+ didReceiveRemoteNotification:(NSDictionary *)userInfo {
#ifdef MODULE_PARSE_ENABLED
[PFPush handlePush:userInfo];
- NSDictionary *aps = [userInfo objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
+ NSDictionary *aps =
+ [userInfo objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSLog(@"Push Notification Payload (app active) %@", aps);
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index bc25afabea..0a9d776421 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -357,6 +357,22 @@ void OSIPhone::update_gyroscope(float p_x, float p_y, float p_z) {
input->set_gyroscope(Vector3(p_x, p_y, p_z));
};
+int OSIPhone::get_unused_joy_id() {
+ return input->get_unused_joy_id();
+};
+
+void OSIPhone::joy_connection_changed(int p_idx, bool p_connected, String p_name) {
+ input->joy_connection_changed(p_idx, p_connected, p_name);
+};
+
+void OSIPhone::joy_button(int p_device, int p_button, bool p_pressed) {
+ input->joy_button(p_device, p_button, p_pressed);
+};
+
+void OSIPhone::joy_axis(int p_device, int p_axis, const InputDefault::JoyAxis &p_value) {
+ input->joy_axis(p_device, p_axis, p_value);
+};
+
void OSIPhone::delete_main_loop() {
if (main_loop) {
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index 754dea073f..209bf00788 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -145,6 +145,11 @@ public:
void update_magnetometer(float p_x, float p_y, float p_z);
void update_gyroscope(float p_x, float p_y, float p_z);
+ int get_unused_joy_id();
+ void joy_connection_changed(int p_idx, bool p_connected, String p_name);
+ void joy_button(int p_device, int p_button, bool p_pressed);
+ void joy_axis(int p_device, int p_axis, const InputDefault::JoyAxis &p_value);
+
static OSIPhone *get_singleton();
virtual void set_mouse_show(bool p_show);