~ppsspp/ppsspp/ppsspp_1.3.0

« back to all changes in this revision

Viewing changes to ios/ViewController.mm

  • Committer: Sérgio Benjamim
  • Date: 2017-01-02 00:12:05 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20170102001205-cxbta9za203nmjwm
1.3.0 source (from ppsspp_1.3.0-r160.p5.l1762.a165.t83~56~ubuntu16.04.1.tar.xz).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// ViewController.m
 
3
//
 
4
// Created by rock88
 
5
// Modified by xSacha
 
6
//
 
7
 
 
8
#import "ViewController.h"
 
9
#import "AudioEngine.h"
 
10
#import <GLKit/GLKit.h>
 
11
 
 
12
#include "base/display.h"
 
13
#include "base/timeutil.h"
 
14
#include "file/zip_read.h"
 
15
#include "input/input_state.h"
 
16
#include "net/resolve.h"
 
17
#include "ui/screen.h"
 
18
#include "thin3d/thin3d.h"
 
19
#include "input/keycodes.h"
 
20
#include "gfx_es2/gpu_features.h"
 
21
 
 
22
#include "Core/Config.h"
 
23
#include "Common/GraphicsContext.h"
 
24
#include "GPU/GLES/FBO.h"
 
25
 
 
26
#include <sys/types.h>
 
27
#include <sys/sysctl.h>
 
28
#include <mach/machine.h>
 
29
 
 
30
#define IS_IPAD() ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
 
31
#define IS_IPHONE() ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)
 
32
 
 
33
#ifndef kCFCoreFoundationVersionNumber_IOS_9_0
 
34
#define kCFCoreFoundationVersionNumber_IOS_9_0 1240.10
 
35
#endif
 
36
 
 
37
class IOSDummyGraphicsContext : public DummyGraphicsContext {
 
38
public:
 
39
    Thin3DContext *CreateThin3DContext() override {
 
40
        CheckGLExtensions();
 
41
        return T3DCreateGLContext();
 
42
    }
 
43
};
 
44
 
 
45
float dp_xscale = 1.0f;
 
46
float dp_yscale = 1.0f;
 
47
 
 
48
double lastSelectPress = 0.0f;
 
49
double lastStartPress = 0.0f;
 
50
bool simulateAnalog = false;
 
51
 
 
52
extern ScreenManager *screenManager;
 
53
InputState input_state;
 
54
 
 
55
extern std::string ram_temp_file;
 
56
extern bool iosCanUseJit;
 
57
extern bool targetIsJailbroken;
 
58
 
 
59
ViewController* sharedViewController;
 
60
static GraphicsContext *graphicsContext;
 
61
 
 
62
@interface ViewController ()
 
63
{
 
64
        std::map<uint16_t, uint16_t> iCadeToKeyMap;
 
65
}
 
66
 
 
67
@property (nonatomic) EAGLContext* context;
 
68
@property (nonatomic) NSString* documentsPath;
 
69
@property (nonatomic) NSString* bundlePath;
 
70
@property (nonatomic) NSMutableArray* touches;
 
71
@property (nonatomic) AudioEngine* audioEngine;
 
72
@property (nonatomic) iCadeReaderView* iCadeView;
 
73
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1
 
74
@property (nonatomic) GCController *gameController __attribute__((weak_import));
 
75
#endif
 
76
 
 
77
@end
 
78
 
 
79
@implementation ViewController
 
80
-(bool) isArm64 {
 
81
        size_t size;
 
82
        cpu_type_t type;
 
83
        size = sizeof(type);
 
84
        sysctlbyname("hw.cputype", &type, &size, NULL, 0);
 
85
        return type == CPU_TYPE_ARM64;
 
86
}
 
87
 
 
88
-(id) init {
 
89
        self = [super init];
 
90
        if (self) {
 
91
                sharedViewController = self;
 
92
                self.touches = [NSMutableArray array];
 
93
                self.documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
 
94
                self.bundlePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/assets/"];
 
95
 
 
96
                memset(&input_state, 0, sizeof(input_state));
 
97
 
 
98
                net::Init();
 
99
 
 
100
                ram_temp_file = [[NSTemporaryDirectory() stringByAppendingPathComponent:@"ram_tmp.file"] fileSystemRepresentation];
 
101
                
 
102
                iosCanUseJit = true;
 
103
                targetIsJailbroken = false;
 
104
                NSArray *jailPath = [NSArray arrayWithObjects:
 
105
                                                        @"/Applications/Cydia.app",
 
106
                                                        @"/private/var/lib/apt",
 
107
                                                        @"/private/var/stash",
 
108
                                                        @"/usr/sbin/sshd",
 
109
                                                        @"/usr/bin/sshd", nil];
 
110
 
 
111
                for (NSString *string in jailPath) {
 
112
                        if ([[NSFileManager defaultManager] fileExistsAtPath:string]) {
 
113
                                // checking device jailbreak status in order to determine which message to show in GameSettingsScreen
 
114
                                targetIsJailbroken = true;
 
115
                        }
 
116
                }
 
117
                
 
118
                NativeInit(0, NULL, [self.documentsPath UTF8String], [self.bundlePath UTF8String], NULL);
 
119
 
 
120
                iCadeToKeyMap[iCadeJoystickUp]          = NKCODE_DPAD_UP;
 
121
                iCadeToKeyMap[iCadeJoystickRight]       = NKCODE_DPAD_RIGHT;
 
122
                iCadeToKeyMap[iCadeJoystickDown]        = NKCODE_DPAD_DOWN;
 
123
                iCadeToKeyMap[iCadeJoystickLeft]        = NKCODE_DPAD_LEFT;
 
124
                iCadeToKeyMap[iCadeButtonA]                     = NKCODE_BUTTON_9; // Select
 
125
                iCadeToKeyMap[iCadeButtonB]                     = NKCODE_BUTTON_7; // LTrigger
 
126
                iCadeToKeyMap[iCadeButtonC]                     = NKCODE_BUTTON_10; // Start
 
127
                iCadeToKeyMap[iCadeButtonD]                     = NKCODE_BUTTON_8; // RTrigger
 
128
                iCadeToKeyMap[iCadeButtonE]                     = NKCODE_BUTTON_4; // Square
 
129
                iCadeToKeyMap[iCadeButtonF]                     = NKCODE_BUTTON_2; // Cross
 
130
                iCadeToKeyMap[iCadeButtonG]                     = NKCODE_BUTTON_1; // Triangle
 
131
                iCadeToKeyMap[iCadeButtonH]                     = NKCODE_BUTTON_3; // Circle
 
132
 
 
133
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1
 
134
                if ([GCController class]) // Checking the availability of a GameController framework
 
135
                {
 
136
                        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controllerDidConnect:) name:GCControllerDidConnectNotification object:nil];
 
137
                        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controllerDidDisconnect:) name:GCControllerDidDisconnectNotification object:nil];
 
138
                }
 
139
#endif
 
140
        }
 
141
        return self;
 
142
}
 
143
 
 
144
- (void)viewDidLoad {
 
145
        [super viewDidLoad];
 
146
 
 
147
        self.view.frame = [[UIScreen mainScreen] bounds];
 
148
        self.view.multipleTouchEnabled = YES;
 
149
        self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
 
150
        
 
151
        if (!self.context)
 
152
        {
 
153
                self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
 
154
        }
 
155
 
 
156
        GLKView* view = (GLKView *)self.view;
 
157
        view.context = self.context;
 
158
        view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
 
159
        [EAGLContext setCurrentContext:self.context];
 
160
        self.preferredFramesPerSecond = 60;
 
161
 
 
162
        float scale = [UIScreen mainScreen].scale;
 
163
        
 
164
        if ([[UIScreen mainScreen] respondsToSelector:@selector(nativeScale)]) {
 
165
                scale = [UIScreen mainScreen].nativeScale;
 
166
        }
 
167
 
 
168
        CGSize size = [[UIApplication sharedApplication].delegate window].frame.size;
 
169
 
 
170
        if (size.height > size.width)
 
171
                {
 
172
                float h = size.height;
 
173
                size.height = size.width;
 
174
                size.width = h;
 
175
        }
 
176
 
 
177
        g_dpi = (IS_IPAD() ? 200 : 150) * scale;
 
178
        g_dpi_scale = 240.0f / (float)g_dpi;
 
179
        pixel_xres = size.width * scale;
 
180
        pixel_yres = size.height * scale;
 
181
 
 
182
        dp_xres = pixel_xres * g_dpi_scale;
 
183
        dp_yres = pixel_yres * g_dpi_scale;
 
184
 
 
185
        pixel_in_dps = (float)pixel_xres / (float)dp_xres;
 
186
 
 
187
        graphicsContext = new IOSDummyGraphicsContext();
 
188
 
 
189
        NativeInitGraphics(graphicsContext);
 
190
 
 
191
        dp_xscale = (float)dp_xres / (float)pixel_xres;
 
192
        dp_yscale = (float)dp_yres / (float)pixel_yres;
 
193
        
 
194
        self.iCadeView = [[iCadeReaderView alloc] init];
 
195
        [self.view addSubview:self.iCadeView];
 
196
        self.iCadeView.delegate = self;
 
197
        self.iCadeView.active = YES;
 
198
        
 
199
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1
 
200
        if ([GCController class]) {
 
201
                if ([[GCController controllers] count] > 0) {
 
202
                        [self setupController:[[GCController controllers] firstObject]];
 
203
                }
 
204
        }
 
205
#endif
 
206
}
 
207
 
 
208
- (void)viewDidUnload
 
209
{
 
210
        [super viewDidUnload];
 
211
 
 
212
        if ([EAGLContext currentContext] == self.context) {
 
213
                [EAGLContext setCurrentContext:nil];
 
214
        }
 
215
        self.context = nil;
 
216
}
 
217
 
 
218
- (void)didReceiveMemoryWarning
 
219
{
 
220
        [super didReceiveMemoryWarning];
 
221
}
 
222
 
 
223
- (void)dealloc
 
224
{
 
225
        [self viewDidUnload];
 
226
 
 
227
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1
 
228
        if ([GCController class]) {
 
229
                [[NSNotificationCenter defaultCenter] removeObserver:self name:GCControllerDidConnectNotification object:nil];
 
230
                [[NSNotificationCenter defaultCenter] removeObserver:self name:GCControllerDidDisconnectNotification object:nil];
 
231
                self.gameController = nil;
 
232
        }
 
233
#endif
 
234
        NativeShutdownGraphics();
 
235
        graphicsContext->Shutdown();
 
236
        delete graphicsContext;
 
237
        graphicsContext = NULL;
 
238
        NativeShutdown();
 
239
}
 
240
 
 
241
// For iOS before 6.0
 
242
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
 
243
{
 
244
        return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
 
245
}
 
246
 
 
247
// For iOS 6.0 and up
 
248
- (NSUInteger)supportedInterfaceOrientations
 
249
{
 
250
        return UIInterfaceOrientationMaskLandscape;
 
251
}
 
252
 
 
253
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
 
254
{
 
255
        {
 
256
                lock_guard guard(input_state.lock);
 
257
                UpdateInputState(&input_state);
 
258
                NativeUpdate(input_state);
 
259
                EndInputState(&input_state);
 
260
        }
 
261
 
 
262
        NativeRender(graphicsContext);
 
263
        time_update();
 
264
}
 
265
 
 
266
- (void)touchX:(float)x y:(float)y code:(int)code pointerId:(int)pointerId
 
267
{
 
268
        lock_guard guard(input_state.lock);
 
269
 
 
270
        float scale = [UIScreen mainScreen].scale;
 
271
        
 
272
        if ([[UIScreen mainScreen] respondsToSelector:@selector(nativeScale)]) {
 
273
                scale = [UIScreen mainScreen].nativeScale;
 
274
        }
 
275
 
 
276
        float scaledX = (int)(x * dp_xscale) * scale;
 
277
        float scaledY = (int)(y * dp_yscale) * scale;
 
278
 
 
279
        TouchInput input;
 
280
 
 
281
        input_state.pointer_x[pointerId] = scaledX;
 
282
        input_state.pointer_y[pointerId] = scaledY;
 
283
        input.x = scaledX;
 
284
        input.y = scaledY;
 
285
        switch (code) {
 
286
                case 1 :
 
287
                        input_state.pointer_down[pointerId] = true;
 
288
                        input.flags = TOUCH_DOWN;
 
289
                        break;
 
290
 
 
291
                case 2 :
 
292
                        input_state.pointer_down[pointerId] = false;
 
293
                        input.flags = TOUCH_UP;
 
294
                        break;
 
295
 
 
296
                default :
 
297
                        input.flags = TOUCH_MOVE;
 
298
                        break;
 
299
        }
 
300
        input_state.mouse_valid = true;
 
301
        input.id = pointerId;
 
302
        NativeTouch(input);
 
303
}
 
304
 
 
305
- (NSDictionary*)touchDictBy:(UITouch*)touch
 
306
{
 
307
        for (NSDictionary* dict in self.touches) {
 
308
                if ([dict objectForKey:@"touch"] == touch)
 
309
                        return dict;
 
310
        }
 
311
        return nil;
 
312
}
 
313
 
 
314
- (int)freeTouchIndex
 
315
{
 
316
        int index = 0;
 
317
 
 
318
        for (NSDictionary* dict in self.touches)
 
319
        {
 
320
                int i = [[dict objectForKey:@"index"] intValue];
 
321
                if (index == i)
 
322
                        index = i+1;
 
323
        }
 
324
 
 
325
        return index;
 
326
}
 
327
 
 
328
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
 
329
{
 
330
        for(UITouch* touch in touches)
 
331
        {
 
332
                NSDictionary* dict = @{@"touch":touch,@"index":@([self freeTouchIndex])};
 
333
                [self.touches addObject:dict];
 
334
                CGPoint point = [touch locationInView:self.view];
 
335
                [self touchX:point.x y:point.y code:1 pointerId:[[dict objectForKey:@"index"] intValue]];
 
336
        }
 
337
}
 
338
 
 
339
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
 
340
{
 
341
        for(UITouch* touch in touches)
 
342
        {
 
343
                CGPoint point = [touch locationInView:self.view];
 
344
                NSDictionary* dict = [self touchDictBy:touch];
 
345
                [self touchX:point.x y:point.y code:0 pointerId:[[dict objectForKey:@"index"] intValue]];
 
346
        }
 
347
}
 
348
 
 
349
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
 
350
{
 
351
        for(UITouch* touch in touches)
 
352
        {
 
353
                CGPoint point = [touch locationInView:self.view];
 
354
                NSDictionary* dict = [self touchDictBy:touch];
 
355
                [self touchX:point.x y:point.y code:2 pointerId:[[dict objectForKey:@"index"] intValue]];
 
356
                [self.touches removeObject:dict];
 
357
        }
 
358
}
 
359
 
 
360
- (void)bindDefaultFBO
 
361
{
 
362
        [(GLKView*)self.view bindDrawable];
 
363
}
 
364
 
 
365
- (void)buttonDown:(iCadeState)button
 
366
{
 
367
        if (simulateAnalog &&
 
368
                ((button == iCadeJoystickUp) ||
 
369
                 (button == iCadeJoystickDown) ||
 
370
                 (button == iCadeJoystickLeft) ||
 
371
                 (button == iCadeJoystickRight))) {
 
372
                        AxisInput axis;
 
373
                        switch (button) {
 
374
                                case iCadeJoystickUp :
 
375
                                        axis.axisId = JOYSTICK_AXIS_Y;
 
376
                                        axis.value = -1.0f;
 
377
                                        break;
 
378
                                        
 
379
                                case iCadeJoystickDown :
 
380
                                        axis.axisId = JOYSTICK_AXIS_Y;
 
381
                                        axis.value = 1.0f;
 
382
                                        break;
 
383
                                        
 
384
                                case iCadeJoystickLeft :
 
385
                                        axis.axisId = JOYSTICK_AXIS_X;
 
386
                                        axis.value = -1.0f;
 
387
                                        break;
 
388
                                        
 
389
                                case iCadeJoystickRight :
 
390
                                        axis.axisId = JOYSTICK_AXIS_X;
 
391
                                        axis.value = 1.0f;
 
392
                                        break;
 
393
                                        
 
394
                                default:
 
395
                                        break;
 
396
                        }
 
397
                        axis.deviceId = DEVICE_ID_PAD_0;
 
398
                        axis.flags = 0;
 
399
                        NativeAxis(axis);
 
400
                } else {
 
401
                        KeyInput key;
 
402
                        key.flags = KEY_DOWN;
 
403
                        key.keyCode = iCadeToKeyMap[button];
 
404
                        key.deviceId = DEVICE_ID_PAD_0;
 
405
                        NativeKey(key);
 
406
                }
 
407
}
 
408
 
 
409
- (void)buttonUp:(iCadeState)button
 
410
{
 
411
        if (button == iCadeButtonA) {
 
412
                // Pressing Select twice within 1 second toggles the DPad between
 
413
                //     normal operation and simulating the Analog stick.
 
414
                if ((lastSelectPress + 1.0f) > time_now_d())
 
415
                        simulateAnalog = !simulateAnalog;
 
416
                lastSelectPress = time_now_d();
 
417
        }
 
418
        
 
419
        if (button == iCadeButtonC) {
 
420
                // Pressing Start twice within 1 second will take to the Emu menu
 
421
                if ((lastStartPress + 1.0f) > time_now_d()) {
 
422
                        KeyInput key;
 
423
                        key.flags = KEY_DOWN;
 
424
                        key.keyCode = NKCODE_ESCAPE;
 
425
                        key.deviceId = DEVICE_ID_KEYBOARD;
 
426
                        NativeKey(key);
 
427
                        return;
 
428
                }
 
429
                lastStartPress = time_now_d();
 
430
        }
 
431
        
 
432
        if (simulateAnalog &&
 
433
                ((button == iCadeJoystickUp) ||
 
434
                 (button == iCadeJoystickDown) ||
 
435
                 (button == iCadeJoystickLeft) ||
 
436
                 (button == iCadeJoystickRight))) {
 
437
                AxisInput axis;
 
438
                switch (button) {
 
439
                        case iCadeJoystickUp :
 
440
                                axis.axisId = JOYSTICK_AXIS_Y;
 
441
                                axis.value = 0.0f;
 
442
                                break;
 
443
                                
 
444
                        case iCadeJoystickDown :
 
445
                                axis.axisId = JOYSTICK_AXIS_Y;
 
446
                                axis.value = 0.0f;
 
447
                                break;
 
448
                                
 
449
                        case iCadeJoystickLeft :
 
450
                                axis.axisId = JOYSTICK_AXIS_X;
 
451
                                axis.value = 0.0f;
 
452
                                break;
 
453
                                
 
454
                        case iCadeJoystickRight :
 
455
                                axis.axisId = JOYSTICK_AXIS_X;
 
456
                                axis.value = 0.0f;
 
457
                                break;
 
458
                                
 
459
                        default:
 
460
                                break;
 
461
                }
 
462
                axis.deviceId = DEVICE_ID_PAD_0;
 
463
                axis.flags = 0;
 
464
                NativeAxis(axis);
 
465
        } else {
 
466
                KeyInput key;
 
467
                key.flags = KEY_UP;
 
468
                key.keyCode = iCadeToKeyMap[button];
 
469
                key.deviceId = DEVICE_ID_PAD_0;
 
470
                NativeKey(key);
 
471
        }
 
472
        
 
473
}
 
474
 
 
475
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1
 
476
- (void)controllerDidConnect:(NSNotification *)note
 
477
{
 
478
        if (![[GCController controllers] containsObject:self.gameController]) self.gameController = nil;
 
479
        
 
480
        if (self.gameController != nil) return; // already have a connected controller
 
481
        
 
482
        [self setupController:(GCController *)note.object];
 
483
}
 
484
 
 
485
- (void)controllerDidDisconnect:(NSNotification *)note
 
486
{
 
487
        if (self.gameController == note.object) {
 
488
                self.gameController = nil;
 
489
                
 
490
                if ([[GCController controllers] count] > 0) {
 
491
                        [self setupController:[[GCController controllers] firstObject]];
 
492
                } else {
 
493
                        [[UIApplication sharedApplication] setIdleTimerDisabled:NO];
 
494
                }
 
495
        }
 
496
}
 
497
 
 
498
- (void)controllerButtonPressed:(BOOL)pressed keyCode:(keycode_t)keyCode
 
499
{
 
500
        KeyInput key;
 
501
        key.deviceId = DEVICE_ID_PAD_0;
 
502
        key.flags = pressed ? KEY_DOWN : KEY_UP;
 
503
        key.keyCode = keyCode;
 
504
        NativeKey(key);
 
505
}
 
506
 
 
507
- (void)setupController:(GCController *)controller
 
508
{
 
509
        self.gameController = controller;
 
510
        
 
511
        GCGamepad *baseProfile = self.gameController.gamepad;
 
512
        if (baseProfile == nil) {
 
513
                self.gameController = nil;
 
514
                return;
 
515
        }
 
516
        
 
517
        [[UIApplication sharedApplication] setIdleTimerDisabled:YES];   // prevent auto-lock
 
518
        
 
519
        self.gameController.controllerPausedHandler = ^(GCController *controller) {
 
520
                KeyInput key;
 
521
                key.flags = KEY_DOWN;
 
522
                key.keyCode = NKCODE_ESCAPE;
 
523
                key.deviceId = DEVICE_ID_KEYBOARD;
 
524
                NativeKey(key);
 
525
        };
 
526
        
 
527
        baseProfile.buttonA.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
 
528
                [self controllerButtonPressed:pressed keyCode:NKCODE_BUTTON_2]; // Cross
 
529
        };
 
530
        
 
531
        baseProfile.buttonB.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
 
532
                [self controllerButtonPressed:pressed keyCode:NKCODE_BUTTON_3]; // Circle
 
533
        };
 
534
        
 
535
        baseProfile.buttonX.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
 
536
                [self controllerButtonPressed:pressed keyCode:NKCODE_BUTTON_4]; // Square
 
537
        };
 
538
        
 
539
        baseProfile.buttonY.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
 
540
                [self controllerButtonPressed:pressed keyCode:NKCODE_BUTTON_1]; // Triangle
 
541
        };
 
542
        
 
543
        baseProfile.leftShoulder.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
 
544
                [self controllerButtonPressed:pressed keyCode:NKCODE_BUTTON_7]; // LTrigger
 
545
        };
 
546
        
 
547
        baseProfile.rightShoulder.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
 
548
                [self controllerButtonPressed:pressed keyCode:NKCODE_BUTTON_8]; // RTrigger
 
549
        };
 
550
        
 
551
        baseProfile.dpad.up.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
 
552
                [self controllerButtonPressed:pressed keyCode:NKCODE_DPAD_UP];
 
553
        };
 
554
        
 
555
        baseProfile.dpad.down.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
 
556
                [self controllerButtonPressed:pressed keyCode:NKCODE_DPAD_DOWN];
 
557
        };
 
558
        
 
559
        baseProfile.dpad.left.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
 
560
                [self controllerButtonPressed:pressed keyCode:NKCODE_DPAD_LEFT];
 
561
        };
 
562
        
 
563
        baseProfile.dpad.right.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
 
564
                [self controllerButtonPressed:pressed keyCode:NKCODE_DPAD_RIGHT];
 
565
        };
 
566
        
 
567
        GCExtendedGamepad *extendedProfile = self.gameController.extendedGamepad;
 
568
        if (extendedProfile == nil)
 
569
                return; // controller doesn't support extendedGamepad profile
 
570
        
 
571
        extendedProfile.leftTrigger.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
 
572
                [self controllerButtonPressed:pressed keyCode:NKCODE_BUTTON_9]; // Select
 
573
        };
 
574
        
 
575
        extendedProfile.rightTrigger.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
 
576
                [self controllerButtonPressed:pressed keyCode:NKCODE_BUTTON_10]; // Start
 
577
        };
 
578
        
 
579
        extendedProfile.leftThumbstick.xAxis.valueChangedHandler = ^(GCControllerAxisInput *axis, float value) {
 
580
                AxisInput axisInput;
 
581
                axisInput.deviceId = DEVICE_ID_PAD_0;
 
582
                axisInput.flags = 0;
 
583
                axisInput.axisId = JOYSTICK_AXIS_X;
 
584
                axisInput.value = value;
 
585
                NativeAxis(axisInput);
 
586
        };
 
587
        
 
588
        extendedProfile.leftThumbstick.yAxis.valueChangedHandler = ^(GCControllerAxisInput *axis, float value) {
 
589
                AxisInput axisInput;
 
590
                axisInput.deviceId = DEVICE_ID_PAD_0;
 
591
                axisInput.flags = 0;
 
592
                axisInput.axisId = JOYSTICK_AXIS_Y;
 
593
                axisInput.value = -value;
 
594
                NativeAxis(axisInput);
 
595
        };
 
596
        
 
597
        // Map right thumbstick as another analog stick, particularly useful for controllers like the DualShock 3/4 when connected to an iOS device
 
598
        extendedProfile.rightThumbstick.xAxis.valueChangedHandler = ^(GCControllerAxisInput *axis, float value) {
 
599
                AxisInput axisInput;
 
600
                axisInput.deviceId = DEVICE_ID_PAD_0;
 
601
                axisInput.flags = 0;
 
602
                axisInput.axisId = JOYSTICK_AXIS_Z;
 
603
                axisInput.value = value;
 
604
                NativeAxis(axisInput);
 
605
        };
 
606
        
 
607
        extendedProfile.rightThumbstick.yAxis.valueChangedHandler = ^(GCControllerAxisInput *axis, float value) {
 
608
                AxisInput axisInput;
 
609
                axisInput.deviceId = DEVICE_ID_PAD_0;
 
610
                axisInput.flags = 0;
 
611
                axisInput.axisId = JOYSTICK_AXIS_RZ;
 
612
                axisInput.value = -value;
 
613
                NativeAxis(axisInput);
 
614
        };
 
615
}
 
616
#endif
 
617
 
 
618
@end
 
619
 
 
620
void LaunchBrowser(char const* url)
 
621
{
 
622
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithCString:url encoding:NSStringEncodingConversionAllowLossy]]];
 
623
}
 
624
 
 
625
void bindDefaultFBO()
 
626
{
 
627
        [sharedViewController bindDefaultFBO];
 
628
}
 
629
 
 
630
void EnableFZ(){};
 
631
void DisableFZ(){};