PlatformiOS.mm 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056
  1. #ifdef __APPLE__
  2. #include "Base.h"
  3. #include "Platform.h"
  4. #include "FileSystem.h"
  5. #include "Game.h"
  6. #include "Form.h"
  7. #include "ScriptController.h"
  8. #include <unistd.h>
  9. #import <UIKit/UIKit.h>
  10. #import <QuartzCore/QuartzCore.h>
  11. #import <CoreMotion/CoreMotion.h>
  12. #import <OpenGLES/EAGL.h>
  13. #import <OpenGLES/EAGLDrawable.h>
  14. #import <OpenGLES/ES2/gl.h>
  15. #import <OpenGLES/ES2/glext.h>
  16. #import <mach/mach_time.h>
  17. #define UIInterfaceOrientationEnum(x) ([x isEqualToString:@"UIInterfaceOrientationPortrait"]?UIInterfaceOrientationPortrait: \
  18. ([x isEqualToString:@"UIInterfaceOrientationPortraitUpsideDown"]?UIInterfaceOrientationPortraitUpsideDown: \
  19. ([x isEqualToString:@"UIInterfaceOrientationLandscapeLeft"]?UIInterfaceOrientationLandscapeLeft: \
  20. UIInterfaceOrientationLandscapeRight)))
  21. #define DeviceOrientedSize(o) ((o == UIInterfaceOrientationPortrait || o == UIInterfaceOrientationPortraitUpsideDown)? \
  22. CGSizeMake([[UIScreen mainScreen] bounds].size.width * [[UIScreen mainScreen] scale], [[UIScreen mainScreen] bounds].size.height * [[UIScreen mainScreen] scale]): \
  23. CGSizeMake([[UIScreen mainScreen] bounds].size.height * [[UIScreen mainScreen] scale], [[UIScreen mainScreen] bounds].size.width * [[UIScreen mainScreen] scale]))
  24. using namespace std;
  25. using namespace gameplay;
  26. // UIScreen bounds are provided as if device was in portrait mode Gameplay defaults to landscape
  27. extern const int WINDOW_WIDTH = [[UIScreen mainScreen] bounds].size.height * [[UIScreen mainScreen] scale];
  28. extern const int WINDOW_HEIGHT = [[UIScreen mainScreen] bounds].size.width * [[UIScreen mainScreen] scale];
  29. extern const int WINDOW_SCALE = [[UIScreen mainScreen] scale];
  30. @class AppDelegate;
  31. @class View;
  32. static AppDelegate *__appDelegate = NULL;
  33. static View* __view = NULL;
  34. static double __timeStart;
  35. static double __timeAbsolute;
  36. static bool __vsync = WINDOW_VSYNC;
  37. static float __pitch;
  38. static float __roll;
  39. double getMachTimeInMilliseconds();
  40. int getKey(unichar keyCode);
  41. @interface View : UIView <UIKeyInput>
  42. {
  43. EAGLContext* context;
  44. CADisplayLink* displayLink;
  45. GLuint defaultFramebuffer;
  46. GLuint colorRenderbuffer;
  47. GLuint depthRenderbuffer;
  48. GLint framebufferWidth;
  49. GLint framebufferHeight;
  50. NSInteger swapInterval;
  51. BOOL updating;
  52. Game* _game;
  53. }
  54. @property (readonly, nonatomic, getter=isUpdating) BOOL updating;
  55. @property (readonly, nonatomic, getter=getContext) EAGLContext* context;
  56. - (void)startGame;
  57. - (void)startUpdating;
  58. - (void)stopUpdating;
  59. - (void)update:(id)sender;
  60. - (void)setSwapInterval:(NSInteger)interval;
  61. - (int)swapInterval;
  62. - (void)swapBuffers;
  63. - (BOOL)showKeyboard;
  64. - (BOOL)dismissKeyboard;
  65. @end
  66. @interface View (Private)
  67. - (void)createFramebuffer;
  68. - (void)deleteFramebuffer;
  69. @end
  70. @implementation View
  71. @synthesize updating;
  72. @synthesize context;
  73. + (Class) layerClass
  74. {
  75. return [CAEAGLLayer class];
  76. }
  77. - (id) initWithFrame:(CGRect)frame
  78. {
  79. if ((self = [super initWithFrame:frame]))
  80. {
  81. // A system version of 3.1 or greater is required to use CADisplayLink.
  82. NSString *reqSysVer = @"3.1";
  83. NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
  84. if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
  85. {
  86. // Log the system version
  87. NSLog(@"System Version: %@", currSysVer);
  88. }
  89. else
  90. {
  91. print("Invalid OS Version: %s\n", (currSysVer == NULL?"NULL":[currSysVer cStringUsingEncoding:NSASCIIStringEncoding]));
  92. [self release];
  93. return nil;
  94. }
  95. // Configure the CAEAGLLayer and setup out the rendering context
  96. CGFloat scale = [[UIScreen mainScreen] scale];
  97. CAEAGLLayer* layer = (CAEAGLLayer *)self.layer;
  98. layer.opaque = TRUE;
  99. layer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
  100. [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking,
  101. kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
  102. self.contentScaleFactor = scale;
  103. layer.contentsScale = scale;
  104. context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
  105. if (!context || ![EAGLContext setCurrentContext:context])
  106. {
  107. [self release];
  108. return nil;
  109. }
  110. if (!defaultFramebuffer)
  111. {
  112. [self createFramebuffer];
  113. }
  114. glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
  115. glViewport(0, 0, framebufferWidth, framebufferHeight);
  116. // Initialize Internal Defaults
  117. displayLink = nil;
  118. defaultFramebuffer = 0;
  119. colorRenderbuffer = 0;
  120. depthRenderbuffer = 0;
  121. framebufferWidth = 0;
  122. framebufferHeight = 0;
  123. swapInterval = 1;
  124. updating = FALSE;
  125. [self createFramebuffer];
  126. // Set the resource path and initalize the game
  127. NSString* bundlePath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/"];
  128. FileSystem::setResourcePath([bundlePath fileSystemRepresentation]);
  129. }
  130. return self;
  131. }
  132. - (void) dealloc
  133. {
  134. _game->exit();
  135. [self deleteFramebuffer];
  136. if ([EAGLContext currentContext] == context)
  137. {
  138. [EAGLContext setCurrentContext:nil];
  139. }
  140. [context release];
  141. [super dealloc];
  142. }
  143. - (BOOL)canBecomeFirstResponder
  144. {
  145. // Override so we can control the keyboard
  146. return YES;
  147. }
  148. - (void) layoutSubviews
  149. {
  150. // Called on 'resize'
  151. [self deleteFramebuffer];
  152. }
  153. - (void)createFramebuffer
  154. {
  155. // iOS Requires all content go to a rendering buffer then it is swapped into the windows rendering surface
  156. assert(defaultFramebuffer == 0);
  157. // Create the default frame buffer, and render buffer
  158. glGenFramebuffers(1, &defaultFramebuffer);
  159. glGenRenderbuffers(1, &colorRenderbuffer);
  160. glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
  161. glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
  162. // request storage, width, and height of the view that we will render in
  163. [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
  164. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);
  165. glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth);
  166. glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight);
  167. glGenRenderbuffers(1, &depthRenderbuffer);
  168. glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
  169. glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, framebufferWidth, framebufferHeight);
  170. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
  171. // Sanity check, ensure that the framebuffer is valid
  172. if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
  173. NSLog(@"ERROR: Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
  174. }
  175. - (void)deleteFramebuffer
  176. {
  177. if (context)
  178. {
  179. [EAGLContext setCurrentContext:context];
  180. if (defaultFramebuffer)
  181. {
  182. glDeleteFramebuffers(1, &defaultFramebuffer);
  183. defaultFramebuffer = 0;
  184. }
  185. if (colorRenderbuffer)
  186. {
  187. glDeleteRenderbuffers(1, &colorRenderbuffer);
  188. colorRenderbuffer = 0;
  189. }
  190. if (depthRenderbuffer)
  191. {
  192. glDeleteRenderbuffers(1, &depthRenderbuffer);
  193. depthRenderbuffer = 0;
  194. }
  195. }
  196. }
  197. - (void)setSwapInterval:(NSInteger)interval
  198. {
  199. if (interval >= 1)
  200. {
  201. swapInterval = interval;
  202. if (updating)
  203. {
  204. [self stopUpdating];
  205. [self startUpdating];
  206. }
  207. }
  208. }
  209. - (int)swapInterval
  210. {
  211. return swapInterval;
  212. }
  213. - (void)swapBuffers
  214. {
  215. if (context != nil)
  216. {
  217. glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
  218. [context presentRenderbuffer:GL_RENDERBUFFER];
  219. }
  220. }
  221. - (void)startGame
  222. {
  223. _game = Game::getInstance();
  224. __timeStart = getMachTimeInMilliseconds();
  225. _game->run();
  226. }
  227. - (void)startUpdating
  228. {
  229. if (!updating)
  230. {
  231. displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(update:)];
  232. [displayLink setFrameInterval:swapInterval];
  233. [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
  234. _game->resume();
  235. updating = TRUE;
  236. }
  237. }
  238. - (void)stopUpdating
  239. {
  240. if (updating)
  241. {
  242. _game->pause();
  243. [displayLink invalidate];
  244. displayLink = nil;
  245. updating = FALSE;
  246. }
  247. }
  248. - (void)update:(id)sender
  249. {
  250. if (context != nil)
  251. {
  252. [EAGLContext setCurrentContext:context];
  253. if (!defaultFramebuffer)
  254. [self createFramebuffer];
  255. glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
  256. glViewport(0, 0, framebufferWidth, framebufferHeight);
  257. if (_game && _game->getState() == Game::RUNNING)
  258. _game->frame();
  259. glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
  260. [context presentRenderbuffer:GL_RENDERBUFFER];
  261. }
  262. }
  263. - (BOOL)showKeyboard
  264. {
  265. return [self becomeFirstResponder];
  266. }
  267. - (BOOL)dismissKeyboard
  268. {
  269. return [self resignFirstResponder];
  270. }
  271. - (void)insertText:(NSString*)text
  272. {
  273. if([text length] == 0) return;
  274. assert([text length] == 1);
  275. unichar c = [text characterAtIndex:0];
  276. int key = getKey(c);
  277. Platform::keyEventInternal(Keyboard::KEY_PRESS, key);
  278. Platform::keyEventInternal(Keyboard::KEY_RELEASE, key);
  279. }
  280. - (void)deleteBackward
  281. {
  282. Platform::keyEventInternal(Keyboard::KEY_PRESS, Keyboard::KEY_BACKSPACE);
  283. Platform::keyEventInternal(Keyboard::KEY_RELEASE, Keyboard::KEY_BACKSPACE);
  284. }
  285. - (BOOL)hasText
  286. {
  287. return YES;
  288. }
  289. - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
  290. {
  291. unsigned int touchID = 0;
  292. for(UITouch* touch in touches)
  293. {
  294. CGPoint touchPoint = [touch locationInView:self];
  295. if(self.multipleTouchEnabled == YES)
  296. {
  297. touchID = [touch hash];
  298. }
  299. Platform::touchEventInternal(Touch::TOUCH_PRESS, touchPoint.x * WINDOW_SCALE, touchPoint.y * WINDOW_SCALE, touchID);
  300. }
  301. }
  302. - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
  303. {
  304. unsigned int touchID = 0;
  305. for(UITouch* touch in touches)
  306. {
  307. CGPoint touchPoint = [touch locationInView:self];
  308. if(self.multipleTouchEnabled == YES)
  309. touchID = [touch hash];
  310. Platform::touchEventInternal(Touch::TOUCH_RELEASE, touchPoint.x * WINDOW_SCALE, touchPoint.y * WINDOW_SCALE, touchID);
  311. }
  312. }
  313. - (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event
  314. {
  315. // No equivalent for this in GamePlay -- treat as touch end
  316. [self touchesEnded:touches withEvent:event];
  317. }
  318. - (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
  319. {
  320. unsigned int touchID = 0;
  321. for(UITouch* touch in touches)
  322. {
  323. CGPoint touchPoint = [touch locationInView:self];
  324. if(self.multipleTouchEnabled == YES)
  325. touchID = [touch hash];
  326. Platform::touchEventInternal(Touch::TOUCH_MOVE, touchPoint.x * WINDOW_SCALE, touchPoint.y * WINDOW_SCALE, touchID);
  327. }
  328. }
  329. @end
  330. @interface ViewController : UIViewController
  331. - (void)startUpdating;
  332. - (void)stopUpdating;
  333. @end
  334. @implementation ViewController
  335. - (id)init
  336. {
  337. if((self = [super init]))
  338. {
  339. }
  340. return self;
  341. }
  342. - (void)dealloc
  343. {
  344. __view = nil;
  345. [super dealloc];
  346. }
  347. - (void)didReceiveMemoryWarning
  348. {
  349. [super didReceiveMemoryWarning];
  350. }
  351. #pragma mark - View lifecycle
  352. - (void)loadView
  353. {
  354. self.view = [[[View alloc] init] autorelease];
  355. if(__view == nil)
  356. {
  357. __view = (View*)self.view;
  358. }
  359. // Start the game after assigning __view so Platform object knows about it on game start
  360. [(View*)self.view startGame];
  361. }
  362. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
  363. {
  364. // Fetch the supported orientations array
  365. NSArray *supportedOrientations = NULL;
  366. if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
  367. {
  368. supportedOrientations = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UISupportedInterfaceOrientations~ipad"];
  369. }
  370. else if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
  371. {
  372. supportedOrientations = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UISupportedInterfaceOrientations~iphone"];
  373. }
  374. if(supportedOrientations == NULL)
  375. {
  376. supportedOrientations = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UISupportedInterfaceOrientations"];
  377. }
  378. // If no supported orientations default to v1.0 handling (landscape only)
  379. if(supportedOrientations == nil) {
  380. return UIInterfaceOrientationIsLandscape(interfaceOrientation);
  381. }
  382. for(NSString *s in supportedOrientations) {
  383. if(interfaceOrientation == UIInterfaceOrientationEnum(s)) return YES;
  384. }
  385. return NO;
  386. }
  387. - (void)startUpdating
  388. {
  389. [(View*)self.view startUpdating];
  390. }
  391. - (void)stopUpdating
  392. {
  393. [(View*)self.view stopUpdating];
  394. }
  395. @end
  396. @interface AppDelegate : UIApplication <UIApplicationDelegate>
  397. {
  398. UIWindow* window;
  399. ViewController* viewController;
  400. CMMotionManager *motionManager;
  401. }
  402. @property (nonatomic, retain) ViewController *viewController;
  403. @end
  404. @implementation AppDelegate
  405. @synthesize viewController;
  406. - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
  407. {
  408. __appDelegate = self;
  409. [UIApplication sharedApplication].statusBarHidden = YES;
  410. [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
  411. motionManager = [[CMMotionManager alloc] init];
  412. if([motionManager isAccelerometerAvailable] == YES)
  413. {
  414. motionManager.accelerometerUpdateInterval = 1 / 40.0; // 40Hz
  415. [motionManager startAccelerometerUpdates];
  416. }
  417. window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  418. viewController = [[ViewController alloc] init];
  419. [window setRootViewController:viewController];
  420. [window makeKeyAndVisible];
  421. return YES;
  422. }
  423. - (void)getAccelerometerPitch:(float*)pitch roll:(float*)roll
  424. {
  425. float p = 0.0f;
  426. float r = 0.0f;
  427. CMAccelerometerData* accelerometerData = motionManager.accelerometerData;
  428. if(accelerometerData != nil)
  429. {
  430. float tx, ty, tz;
  431. switch ([[UIApplication sharedApplication] statusBarOrientation])
  432. {
  433. case UIInterfaceOrientationLandscapeRight:
  434. tx = -accelerometerData.acceleration.y;
  435. ty = accelerometerData.acceleration.x;
  436. break;
  437. case UIInterfaceOrientationLandscapeLeft:
  438. tx = accelerometerData.acceleration.y;
  439. ty = -accelerometerData.acceleration.x;
  440. break;
  441. case UIInterfaceOrientationPortraitUpsideDown:
  442. tx = -accelerometerData.acceleration.y;
  443. ty = -accelerometerData.acceleration.x;
  444. break;
  445. case UIInterfaceOrientationPortrait:
  446. tx = accelerometerData.acceleration.x;
  447. ty = accelerometerData.acceleration.y;
  448. break;
  449. }
  450. tz = accelerometerData.acceleration.z;
  451. p = atan(ty / sqrt(tx * tx + tz * tz)) * 180.0f * M_1_PI;
  452. r = atan(tx / sqrt(ty * ty + tz * tz)) * 180.0f * M_1_PI;
  453. }
  454. if(pitch != NULL)
  455. *pitch = p;
  456. if(roll != NULL)
  457. *roll = r;
  458. }
  459. - (void)applicationWillResignActive:(UIApplication*)application
  460. {
  461. [viewController stopUpdating];
  462. }
  463. - (void)applicationDidEnterBackground:(UIApplication*)application
  464. {
  465. [viewController stopUpdating];
  466. }
  467. - (void)applicationWillEnterForeground:(UIApplication*)application
  468. {
  469. [viewController startUpdating];
  470. }
  471. - (void)applicationDidBecomeActive:(UIApplication*)application
  472. {
  473. [viewController startUpdating];
  474. }
  475. - (void)applicationWillTerminate:(UIApplication*)application
  476. {
  477. [viewController stopUpdating];
  478. }
  479. - (void)dealloc
  480. {
  481. [window setRootViewController:nil];
  482. [viewController release];
  483. [window release];
  484. [motionManager release];
  485. [super dealloc];
  486. }
  487. @end
  488. double getMachTimeInMilliseconds()
  489. {
  490. static const double kOneMillion = 1000 * 1000;
  491. static mach_timebase_info_data_t s_timebase_info;
  492. if (s_timebase_info.denom == 0)
  493. (void) mach_timebase_info(&s_timebase_info);
  494. // mach_absolute_time() returns billionth of seconds, so divide by one million to get milliseconds
  495. GP_ASSERT(s_timebase_info.denom);
  496. return ((double)mach_absolute_time() * (double)s_timebase_info.numer) / (kOneMillion * (double)s_timebase_info.denom);
  497. }
  498. int getKey(unichar keyCode)
  499. {
  500. switch(keyCode)
  501. {
  502. case 0x30:
  503. return Keyboard::KEY_ZERO;
  504. case 0x31:
  505. return Keyboard::KEY_ONE;
  506. case 0x32:
  507. return Keyboard::KEY_TWO;
  508. case 0x33:
  509. return Keyboard::KEY_THREE;
  510. case 0x34:
  511. return Keyboard::KEY_FOUR;
  512. case 0x35:
  513. return Keyboard::KEY_FIVE;
  514. case 0x36:
  515. return Keyboard::KEY_SIX;
  516. case 0x37:
  517. return Keyboard::KEY_SEVEN;
  518. case 0x38:
  519. return Keyboard::KEY_EIGHT;
  520. case 0x39:
  521. return Keyboard::KEY_NINE;
  522. case 0x41:
  523. return Keyboard::KEY_CAPITAL_A;
  524. case 0x42:
  525. return Keyboard::KEY_CAPITAL_B;
  526. case 0x43:
  527. return Keyboard::KEY_CAPITAL_C;
  528. case 0x44:
  529. return Keyboard::KEY_CAPITAL_D;
  530. case 0x45:
  531. return Keyboard::KEY_CAPITAL_E;
  532. case 0x46:
  533. return Keyboard::KEY_CAPITAL_F;
  534. case 0x47:
  535. return Keyboard::KEY_CAPITAL_G;
  536. case 0x48:
  537. return Keyboard::KEY_CAPITAL_H;
  538. case 0x49:
  539. return Keyboard::KEY_CAPITAL_I;
  540. case 0x4A:
  541. return Keyboard::KEY_CAPITAL_J;
  542. case 0x4B:
  543. return Keyboard::KEY_CAPITAL_K;
  544. case 0x4C:
  545. return Keyboard::KEY_CAPITAL_L;
  546. case 0x4D:
  547. return Keyboard::KEY_CAPITAL_M;
  548. case 0x4E:
  549. return Keyboard::KEY_CAPITAL_N;
  550. case 0x4F:
  551. return Keyboard::KEY_CAPITAL_O;
  552. case 0x50:
  553. return Keyboard::KEY_CAPITAL_P;
  554. case 0x51:
  555. return Keyboard::KEY_CAPITAL_Q;
  556. case 0x52:
  557. return Keyboard::KEY_CAPITAL_R;
  558. case 0x53:
  559. return Keyboard::KEY_CAPITAL_S;
  560. case 0x54:
  561. return Keyboard::KEY_CAPITAL_T;
  562. case 0x55:
  563. return Keyboard::KEY_CAPITAL_U;
  564. case 0x56:
  565. return Keyboard::KEY_CAPITAL_V;
  566. case 0x57:
  567. return Keyboard::KEY_CAPITAL_W;
  568. case 0x58:
  569. return Keyboard::KEY_CAPITAL_X;
  570. case 0x59:
  571. return Keyboard::KEY_CAPITAL_Y;
  572. case 0x5A:
  573. return Keyboard::KEY_CAPITAL_Z;
  574. case 0x61:
  575. return Keyboard::KEY_A;
  576. case 0x62:
  577. return Keyboard::KEY_B;
  578. case 0x63:
  579. return Keyboard::KEY_C;
  580. case 0x64:
  581. return Keyboard::KEY_D;
  582. case 0x65:
  583. return Keyboard::KEY_E;
  584. case 0x66:
  585. return Keyboard::KEY_F;
  586. case 0x67:
  587. return Keyboard::KEY_G;
  588. case 0x68:
  589. return Keyboard::KEY_H;
  590. case 0x69:
  591. return Keyboard::KEY_I;
  592. case 0x6A:
  593. return Keyboard::KEY_J;
  594. case 0x6B:
  595. return Keyboard::KEY_K;
  596. case 0x6C:
  597. return Keyboard::KEY_L;
  598. case 0x6D:
  599. return Keyboard::KEY_M;
  600. case 0x6E:
  601. return Keyboard::KEY_N;
  602. case 0x6F:
  603. return Keyboard::KEY_O;
  604. case 0x70:
  605. return Keyboard::KEY_P;
  606. case 0x71:
  607. return Keyboard::KEY_Q;
  608. case 0x72:
  609. return Keyboard::KEY_R;
  610. case 0x73:
  611. return Keyboard::KEY_S;
  612. case 0x74:
  613. return Keyboard::KEY_T;
  614. case 0x75:
  615. return Keyboard::KEY_U;
  616. case 0x76:
  617. return Keyboard::KEY_V;
  618. case 0x77:
  619. return Keyboard::KEY_W;
  620. case 0x78:
  621. return Keyboard::KEY_X;
  622. case 0x79:
  623. return Keyboard::KEY_Y;
  624. case 0x7A:
  625. return Keyboard::KEY_Z;
  626. default:
  627. break;
  628. // Symbol Row 3
  629. case 0x2E:
  630. return Keyboard::KEY_PERIOD;
  631. case 0x2C:
  632. return Keyboard::KEY_COMMA;
  633. case 0x3F:
  634. return Keyboard::KEY_QUESTION;
  635. case 0x21:
  636. return Keyboard::KEY_EXCLAM;
  637. case 0x27:
  638. return Keyboard::KEY_APOSTROPHE;
  639. // Symbols Row 2
  640. case 0x2D:
  641. return Keyboard::KEY_MINUS;
  642. case 0x2F:
  643. return Keyboard::KEY_SLASH;
  644. case 0x3A:
  645. return Keyboard::KEY_COLON;
  646. case 0x3B:
  647. return Keyboard::KEY_SEMICOLON;
  648. case 0x28:
  649. return Keyboard::KEY_LEFT_PARENTHESIS;
  650. case 0x29:
  651. return Keyboard::KEY_RIGHT_PARENTHESIS;
  652. case 0x24:
  653. return Keyboard::KEY_DOLLAR;
  654. case 0x26:
  655. return Keyboard::KEY_AMPERSAND;
  656. case 0x40:
  657. return Keyboard::KEY_AT;
  658. case 0x22:
  659. return Keyboard::KEY_QUOTE;
  660. // Numeric Symbols Row 1
  661. case 0x5B:
  662. return Keyboard::KEY_LEFT_BRACKET;
  663. case 0x5D:
  664. return Keyboard::KEY_RIGHT_BRACKET;
  665. case 0x7B:
  666. return Keyboard::KEY_LEFT_BRACE;
  667. case 0x7D:
  668. return Keyboard::KEY_RIGHT_BRACE;
  669. case 0x23:
  670. return Keyboard::KEY_NUMBER;
  671. case 0x25:
  672. return Keyboard::KEY_PERCENT;
  673. case 0x5E:
  674. return Keyboard::KEY_CIRCUMFLEX;
  675. case 0x2A:
  676. return Keyboard::KEY_ASTERISK;
  677. case 0x2B:
  678. return Keyboard::KEY_PLUS;
  679. case 0x3D:
  680. return Keyboard::KEY_EQUAL;
  681. // Numeric Symbols Row 2
  682. case 0x5F:
  683. return Keyboard::KEY_UNDERSCORE;
  684. case 0x5C:
  685. return Keyboard::KEY_BACK_SLASH;
  686. case 0x7C:
  687. return Keyboard::KEY_BAR;
  688. case 0x7E:
  689. return Keyboard::KEY_TILDE;
  690. case 0x3C:
  691. return Keyboard::KEY_LESS_THAN;
  692. case 0x3E:
  693. return Keyboard::KEY_GREATER_THAN;
  694. case 0x80:
  695. return Keyboard::KEY_EURO;
  696. case 0xA3:
  697. return Keyboard::KEY_POUND;
  698. case 0xA5:
  699. return Keyboard::KEY_YEN;
  700. case 0xB7:
  701. return Keyboard::KEY_MIDDLE_DOT;
  702. }
  703. return Keyboard::KEY_NONE;
  704. }
  705. namespace gameplay
  706. {
  707. extern void print(const char* format, ...)
  708. {
  709. GP_ASSERT(format);
  710. va_list argptr;
  711. va_start(argptr, format);
  712. vfprintf(stderr, format, argptr);
  713. va_end(argptr);
  714. }
  715. Platform::Platform(Game* game) : _game(game)
  716. {
  717. }
  718. Platform::~Platform()
  719. {
  720. }
  721. Platform* Platform::create(Game* game, void* attachToWindow)
  722. {
  723. Platform* platform = new Platform(game);
  724. return platform;
  725. }
  726. int Platform::enterMessagePump()
  727. {
  728. NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  729. [AppDelegate load];
  730. UIApplicationMain(0, nil, NSStringFromClass([AppDelegate class]), NSStringFromClass([AppDelegate class]));
  731. [pool release];
  732. return EXIT_SUCCESS;
  733. }
  734. void Platform::signalShutdown()
  735. {
  736. // Cannot 'exit' an iOS Application
  737. assert(false);
  738. [__view stopUpdating];
  739. exit(0);
  740. }
  741. unsigned int Platform::getDisplayWidth()
  742. {
  743. CGSize size = DeviceOrientedSize([__appDelegate.viewController interfaceOrientation]);
  744. return size.width;
  745. }
  746. unsigned int Platform::getDisplayHeight()
  747. {
  748. CGSize size = DeviceOrientedSize([__appDelegate.viewController interfaceOrientation]);
  749. return size.height;
  750. }
  751. double Platform::getAbsoluteTime()
  752. {
  753. __timeAbsolute = getMachTimeInMilliseconds();
  754. return __timeAbsolute;
  755. }
  756. void Platform::setAbsoluteTime(double time)
  757. {
  758. __timeAbsolute = time;
  759. }
  760. bool Platform::isVsync()
  761. {
  762. return __vsync;
  763. }
  764. void Platform::setVsync(bool enable)
  765. {
  766. __vsync = enable;
  767. }
  768. void Platform::swapBuffers()
  769. {
  770. if (__view)
  771. [__view swapBuffers];
  772. }
  773. void Platform::sleep(long ms)
  774. {
  775. usleep(ms * 1000);
  776. }
  777. void Platform::getAccelerometerValues(float* pitch, float* roll)
  778. {
  779. [__appDelegate getAccelerometerPitch:pitch roll:roll];
  780. }
  781. bool Platform::hasMouse()
  782. {
  783. // not supported
  784. return false;
  785. }
  786. void Platform::setMouseCaptured(bool captured)
  787. {
  788. // not supported
  789. }
  790. bool Platform::isMouseCaptured()
  791. {
  792. // not supported
  793. return false;
  794. }
  795. void Platform::setCursorVisible(bool visible)
  796. {
  797. // not supported
  798. }
  799. bool Platform::isCursorVisible()
  800. {
  801. // not supported
  802. return false;
  803. }
  804. void Platform::setMultiTouch(bool enabled)
  805. {
  806. __view.multipleTouchEnabled = enabled;
  807. }
  808. bool Platform::isMultiTouch()
  809. {
  810. return __view.multipleTouchEnabled;
  811. }
  812. void Platform::displayKeyboard(bool display)
  813. {
  814. if(__view)
  815. {
  816. if(display)
  817. {
  818. [__view showKeyboard];
  819. }
  820. else
  821. {
  822. [__view dismissKeyboard];
  823. }
  824. }
  825. }
  826. void Platform::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
  827. {
  828. if (!Form::touchEventInternal(evt, x, y, contactIndex))
  829. {
  830. Game::getInstance()->touchEvent(evt, x, y, contactIndex);
  831. Game::getInstance()->getScriptController()->touchEvent(evt, x, y, contactIndex);
  832. }
  833. }
  834. void Platform::keyEventInternal(Keyboard::KeyEvent evt, int key)
  835. {
  836. if (!Form::keyEventInternal(evt, key))
  837. {
  838. Game::getInstance()->keyEvent(evt, key);
  839. Game::getInstance()->getScriptController()->keyEvent(evt, key);
  840. }
  841. }
  842. bool Platform::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
  843. {
  844. if (Form::mouseEventInternal(evt, x, y, wheelDelta))
  845. {
  846. return true;
  847. }
  848. else if (Game::getInstance()->mouseEvent(evt, x, y, wheelDelta))
  849. {
  850. return true;
  851. }
  852. else
  853. {
  854. return Game::getInstance()->getScriptController()->mouseEvent(evt, x, y, wheelDelta);
  855. }
  856. }
  857. void Platform::recognizeGesture(Gesture::GestureEvent evt)
  858. {
  859. }
  860. unsigned int Platform::getGamepadsConnected()
  861. {
  862. return 0;
  863. }
  864. bool Platform::isGamepadConnected(unsigned int gamepadHandle)
  865. {
  866. return false;
  867. }
  868. const char* Platform::getGamepadId(unsigned int gamepadHandle)
  869. {
  870. return NULL;
  871. }
  872. unsigned int Platform::getGamepadButtonCount(unsigned int gamepadHandle)
  873. {
  874. return 0;
  875. }
  876. bool Platform::getGamepadButtonState(unsigned int gamepadHandle, unsigned int buttonIndex)
  877. {
  878. return false;
  879. }
  880. unsigned int Platform::getGamepadJoystickCount(unsigned int gamepadHandle)
  881. {
  882. return 0;
  883. }
  884. bool Platform::isGamepadJoystickActive(unsigned int gamepadHandle, unsigned int joystickIndex)
  885. {
  886. return false;
  887. }
  888. float Platform::getGamepadJoystickAxisX(unsigned int gamepadHandle, unsigned int joystickIndex)
  889. {
  890. return 0.0f;
  891. }
  892. float Platform::getGamepadJoystickAxisY(unsigned int gamepadHandle, unsigned int joystickIndex)
  893. {
  894. return 0.0f;
  895. }
  896. void Platform::getGamepadJoystickAxisValues(unsigned int gamepadHandle, unsigned int joystickIndex, Vector2* outValue)
  897. {
  898. }
  899. unsigned int Platform::getGamepadTriggerCount(unsigned int gamepadHandle)
  900. {
  901. return 0;
  902. }
  903. float Platform::getGamepadTriggerValue(unsigned int gamepadHandle, unsigned int triggerIndex)
  904. {
  905. return 0.0f;
  906. }
  907. }
  908. #endif