PlatformiOS.mm 23 KB

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