PlatformiOS.mm 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325
  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. BOOL updateFramebuffer;
  46. GLuint defaultFramebuffer;
  47. GLuint colorRenderbuffer;
  48. GLuint depthRenderbuffer;
  49. GLint framebufferWidth;
  50. GLint framebufferHeight;
  51. GLuint multisampleFramebuffer;
  52. GLuint multisampleRenderbuffer;
  53. GLuint multisampleDepthbuffer;
  54. NSInteger swapInterval;
  55. BOOL updating;
  56. Game* game;
  57. BOOL oglDiscardSupported;
  58. UITapGestureRecognizer *_tapRecognizer;
  59. UIPinchGestureRecognizer *_pinchRecognizer;
  60. UISwipeGestureRecognizer *_swipeRecognizer;
  61. }
  62. @property (readonly, nonatomic, getter=isUpdating) BOOL updating;
  63. @property (readonly, nonatomic, getter=getContext) EAGLContext* context;
  64. - (void)startGame;
  65. - (void)startUpdating;
  66. - (void)stopUpdating;
  67. - (void)update:(id)sender;
  68. - (void)setSwapInterval:(NSInteger)interval;
  69. - (int)swapInterval;
  70. - (void)swapBuffers;
  71. - (BOOL)showKeyboard;
  72. - (BOOL)dismissKeyboard;
  73. @end
  74. @interface View (Private)
  75. - (BOOL)createFramebuffer;
  76. - (void)deleteFramebuffer;
  77. @end
  78. @implementation View
  79. @synthesize updating;
  80. @synthesize context;
  81. + (Class) layerClass
  82. {
  83. return [CAEAGLLayer class];
  84. }
  85. - (id) initWithFrame:(CGRect)frame
  86. {
  87. if ((self = [super initWithFrame:frame]))
  88. {
  89. // A system version of 3.1 or greater is required to use CADisplayLink.
  90. NSString *reqSysVer = @"3.1";
  91. NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
  92. if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
  93. {
  94. // Log the system version
  95. NSLog(@"System Version: %@", currSysVer);
  96. }
  97. else
  98. {
  99. GP_ERROR("Invalid OS Version: %s\n", (currSysVer == NULL?"NULL":[currSysVer cStringUsingEncoding:NSASCIIStringEncoding]));
  100. [self release];
  101. return nil;
  102. }
  103. // Check for OS 4.0+ features
  104. if ([currSysVer compare:@"4.0" options:NSNumericSearch] != NSOrderedAscending)
  105. {
  106. oglDiscardSupported = YES;
  107. }
  108. else
  109. {
  110. oglDiscardSupported = NO;
  111. }
  112. // Configure the CAEAGLLayer and setup out the rendering context
  113. CGFloat scale = [[UIScreen mainScreen] scale];
  114. CAEAGLLayer* layer = (CAEAGLLayer *)self.layer;
  115. layer.opaque = TRUE;
  116. layer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
  117. [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking,
  118. kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
  119. self.contentScaleFactor = scale;
  120. layer.contentsScale = scale;
  121. context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
  122. if (!context || ![EAGLContext setCurrentContext:context])
  123. {
  124. GP_ERROR("Failed to make context current.");
  125. [self release];
  126. return nil;
  127. }
  128. // Initialize Internal Defaults
  129. displayLink = nil;
  130. updateFramebuffer = YES;
  131. defaultFramebuffer = 0;
  132. colorRenderbuffer = 0;
  133. depthRenderbuffer = 0;
  134. framebufferWidth = 0;
  135. framebufferHeight = 0;
  136. multisampleFramebuffer = 0;
  137. multisampleRenderbuffer = 0;
  138. multisampleDepthbuffer = 0;
  139. swapInterval = 1;
  140. updating = FALSE;
  141. game = nil;
  142. // Set the resource path and initalize the game
  143. NSString* bundlePath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/"];
  144. FileSystem::setResourcePath([bundlePath fileSystemRepresentation]);
  145. }
  146. return self;
  147. }
  148. - (void) dealloc
  149. {
  150. if (game)
  151. game->exit();
  152. [self deleteFramebuffer];
  153. if ([EAGLContext currentContext] == context)
  154. {
  155. [EAGLContext setCurrentContext:nil];
  156. }
  157. [context release];
  158. [super dealloc];
  159. }
  160. - (BOOL)canBecomeFirstResponder
  161. {
  162. // Override so we can control the keyboard
  163. return YES;
  164. }
  165. - (void) layoutSubviews
  166. {
  167. // Called on 'resize'.
  168. // Mark that framebuffer needs to be updated.
  169. // NOTE: Current disabled since we need to have a way to reset the default frame buffer handle
  170. // in FrameBuffer.cpp (for FrameBuffer:bindDefault). This means that changing orientation at
  171. // runtime is currently not supported until we fix this.
  172. //updateFramebuffer = YES;
  173. }
  174. - (BOOL)createFramebuffer
  175. {
  176. // iOS Requires all content go to a rendering buffer then it is swapped into the windows rendering surface
  177. assert(defaultFramebuffer == 0);
  178. // Create the default frame buffer
  179. GL_ASSERT( glGenFramebuffers(1, &defaultFramebuffer) );
  180. GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer) );
  181. // Create a color buffer to attach to the frame buffer
  182. GL_ASSERT( glGenRenderbuffers(1, &colorRenderbuffer) );
  183. GL_ASSERT( glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer) );
  184. // Associate render buffer storage with CAEAGLLauyer so that the rendered content is display on our UI layer.
  185. [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
  186. // Attach the color buffer to our frame buffer
  187. GL_ASSERT( glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer) );
  188. // Retrieve framebuffer size
  189. GL_ASSERT( glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth) );
  190. GL_ASSERT( glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight) );
  191. NSLog(@"width: %d, height: %d", framebufferWidth, framebufferHeight);
  192. // If multisampling is enabled in config, create and setup a multisample buffer
  193. Properties* config = Game::getInstance()->getConfig()->getNamespace("window", true);
  194. int samples = config ? config->getInt("samples") : 0;
  195. if (samples < 0)
  196. samples = 0;
  197. if (samples)
  198. {
  199. // Create multisample framebuffer
  200. GL_ASSERT( glGenFramebuffers(1, &multisampleFramebuffer) );
  201. GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, multisampleFramebuffer) );
  202. // Create multisample render and depth buffers
  203. GL_ASSERT( glGenRenderbuffers(1, &multisampleRenderbuffer) );
  204. GL_ASSERT( glGenRenderbuffers(1, &multisampleDepthbuffer) );
  205. // Try to find a supported multisample configuration starting with the defined sample count
  206. while (samples)
  207. {
  208. GL_ASSERT( glBindRenderbuffer(GL_RENDERBUFFER, multisampleRenderbuffer) );
  209. GL_ASSERT( glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER, samples, GL_RGBA8_OES, framebufferWidth, framebufferHeight) );
  210. GL_ASSERT( glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, multisampleRenderbuffer) );
  211. GL_ASSERT( glBindRenderbuffer(GL_RENDERBUFFER, multisampleDepthbuffer) );
  212. GL_ASSERT( glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT24_OES, framebufferWidth, framebufferHeight) );
  213. GL_ASSERT( glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, multisampleDepthbuffer) );
  214. if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
  215. break; // success!
  216. NSLog(@"Creation of multisample buffer with samples=%d failed. Attempting to use configuration with samples=%d instead: %x", samples, samples / 2, glCheckFramebufferStatus(GL_FRAMEBUFFER));
  217. samples /= 2;
  218. }
  219. // Re-bind the default framebuffer
  220. GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer) );
  221. if (samples == 0)
  222. {
  223. // Unable to find a valid/supported multisample configuratoin - fallback to no multisampling
  224. GL_ASSERT( glDeleteRenderbuffers(1, &multisampleRenderbuffer) );
  225. GL_ASSERT( glDeleteRenderbuffers(1, &multisampleDepthbuffer) );
  226. GL_ASSERT( glDeleteFramebuffers(1, &multisampleFramebuffer) );
  227. multisampleFramebuffer = multisampleRenderbuffer = multisampleDepthbuffer = 0;
  228. }
  229. }
  230. // Create default depth buffer and attach to the frame buffer.
  231. // Note: If we are using multisample buffers, we can skip depth buffer creation here since we only
  232. // need the color buffer to resolve to.
  233. if (multisampleFramebuffer == 0)
  234. {
  235. GL_ASSERT( glGenRenderbuffers(1, &depthRenderbuffer) );
  236. GL_ASSERT( glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer) );
  237. GL_ASSERT( glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, framebufferWidth, framebufferHeight) );
  238. GL_ASSERT( glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer) );
  239. }
  240. // Sanity check, ensure that the framebuffer is valid
  241. if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
  242. {
  243. NSLog(@"ERROR: Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
  244. [self deleteFramebuffer];
  245. return NO;
  246. }
  247. // If multisampling is enabled, set the currently bound framebuffer to the multisample buffer
  248. // since that is the buffer code should be drawing into (and FrameBuffr::initialize will detect
  249. // and set this bound buffer as the default one during initialization.
  250. if (multisampleFramebuffer)
  251. GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, multisampleFramebuffer) );
  252. return YES;
  253. }
  254. - (void)deleteFramebuffer
  255. {
  256. if (context)
  257. {
  258. [EAGLContext setCurrentContext:context];
  259. if (defaultFramebuffer)
  260. {
  261. GL_ASSERT( glDeleteFramebuffers(1, &defaultFramebuffer) );
  262. defaultFramebuffer = 0;
  263. }
  264. if (colorRenderbuffer)
  265. {
  266. GL_ASSERT( glDeleteRenderbuffers(1, &colorRenderbuffer) );
  267. colorRenderbuffer = 0;
  268. }
  269. if (depthRenderbuffer)
  270. {
  271. GL_ASSERT( glDeleteRenderbuffers(1, &depthRenderbuffer) );
  272. depthRenderbuffer = 0;
  273. }
  274. if (multisampleFramebuffer)
  275. {
  276. GL_ASSERT( glDeleteFramebuffers(1, &multisampleFramebuffer) );
  277. multisampleFramebuffer = 0;
  278. }
  279. if (multisampleRenderbuffer)
  280. {
  281. GL_ASSERT( glDeleteRenderbuffers(1, &multisampleRenderbuffer) );
  282. multisampleRenderbuffer = 0;
  283. }
  284. if (multisampleDepthbuffer)
  285. {
  286. GL_ASSERT( glDeleteRenderbuffers(1, &multisampleDepthbuffer) );
  287. multisampleDepthbuffer = 0;
  288. }
  289. }
  290. }
  291. - (void)setSwapInterval:(NSInteger)interval
  292. {
  293. if (interval >= 1)
  294. {
  295. swapInterval = interval;
  296. if (updating)
  297. {
  298. [self stopUpdating];
  299. [self startUpdating];
  300. }
  301. }
  302. }
  303. - (int)swapInterval
  304. {
  305. return swapInterval;
  306. }
  307. - (void)swapBuffers
  308. {
  309. if (context)
  310. {
  311. if (multisampleFramebuffer)
  312. {
  313. // Multisampling is enabled: resolve the multisample buffer into the default framebuffer
  314. GL_ASSERT( glBindFramebuffer(GL_DRAW_FRAMEBUFFER_APPLE, defaultFramebuffer) );
  315. GL_ASSERT( glBindFramebuffer(GL_READ_FRAMEBUFFER_APPLE, multisampleFramebuffer) );
  316. GL_ASSERT( glResolveMultisampleFramebufferAPPLE() );
  317. if (oglDiscardSupported)
  318. {
  319. // Performance hint that the GL driver can discard the contents of the multisample buffers
  320. // since they have now been resolved into the default framebuffer
  321. const GLenum discards[] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT };
  322. GL_ASSERT( glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 2, discards) );
  323. }
  324. }
  325. else
  326. {
  327. if (oglDiscardSupported)
  328. {
  329. // Performance hint to the GL driver that the depth buffer is no longer required.
  330. const GLenum discards[] = { GL_DEPTH_ATTACHMENT };
  331. GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer) );
  332. GL_ASSERT( glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards) );
  333. }
  334. }
  335. // Present the color buffer
  336. GL_ASSERT( glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer) );
  337. [context presentRenderbuffer:GL_RENDERBUFFER];
  338. }
  339. }
  340. - (void)startGame
  341. {
  342. if (game == nil)
  343. {
  344. game = Game::getInstance();
  345. __timeStart = getMachTimeInMilliseconds();
  346. game->run();
  347. }
  348. }
  349. - (void)startUpdating
  350. {
  351. if (!updating)
  352. {
  353. displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(update:)];
  354. [displayLink setFrameInterval:swapInterval];
  355. [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
  356. if (game)
  357. game->resume();
  358. updating = TRUE;
  359. }
  360. }
  361. - (void)stopUpdating
  362. {
  363. if (updating)
  364. {
  365. if (game)
  366. game->pause();
  367. [displayLink invalidate];
  368. displayLink = nil;
  369. updating = FALSE;
  370. }
  371. }
  372. - (void)update:(id)sender
  373. {
  374. if (context != nil)
  375. {
  376. // Ensure our context is current
  377. [EAGLContext setCurrentContext:context];
  378. // If the framebuffer needs (re)creating, do so
  379. if (updateFramebuffer)
  380. {
  381. updateFramebuffer = NO;
  382. [self deleteFramebuffer];
  383. [self createFramebuffer];
  384. // Start the game after our framebuffer is created for the first time.
  385. if (game == nil)
  386. {
  387. [self startGame];
  388. // HACK: Skip the first display update after creating buffers and initializing the game.
  389. // If we don't do this, the first frame (which includes any drawing during initialization)
  390. // does not make it to the display for some reason.
  391. return;
  392. }
  393. }
  394. // Bind our framebuffer for rendering.
  395. // If multisampling is enabled, bind the multisample buffer - otherwise bind the default buffer
  396. GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, multisampleFramebuffer ? multisampleFramebuffer : defaultFramebuffer) );
  397. GL_ASSERT( glViewport(0, 0, framebufferWidth, framebufferHeight) );
  398. // Execute a single game frame
  399. if (game)
  400. game->frame();
  401. // Present the contents of the color buffer
  402. [self swapBuffers];
  403. }
  404. }
  405. - (BOOL)showKeyboard
  406. {
  407. return [self becomeFirstResponder];
  408. }
  409. - (BOOL)dismissKeyboard
  410. {
  411. return [self resignFirstResponder];
  412. }
  413. - (void)insertText:(NSString*)text
  414. {
  415. if([text length] == 0) return;
  416. assert([text length] == 1);
  417. unichar c = [text characterAtIndex:0];
  418. int key = getKey(c);
  419. Platform::keyEventInternal(Keyboard::KEY_PRESS, key);
  420. Platform::keyEventInternal(Keyboard::KEY_RELEASE, key);
  421. }
  422. - (void)deleteBackward
  423. {
  424. Platform::keyEventInternal(Keyboard::KEY_PRESS, Keyboard::KEY_BACKSPACE);
  425. Platform::keyEventInternal(Keyboard::KEY_RELEASE, Keyboard::KEY_BACKSPACE);
  426. }
  427. - (BOOL)hasText
  428. {
  429. return YES;
  430. }
  431. - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
  432. {
  433. unsigned int touchID = 0;
  434. for(UITouch* touch in touches)
  435. {
  436. CGPoint touchPoint = [touch locationInView:self];
  437. if(self.multipleTouchEnabled == YES)
  438. {
  439. touchID = [touch hash];
  440. }
  441. Platform::touchEventInternal(Touch::TOUCH_PRESS, touchPoint.x * WINDOW_SCALE, touchPoint.y * WINDOW_SCALE, touchID);
  442. }
  443. }
  444. - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
  445. {
  446. unsigned int touchID = 0;
  447. for(UITouch* touch in touches)
  448. {
  449. CGPoint touchPoint = [touch locationInView:self];
  450. if(self.multipleTouchEnabled == YES)
  451. touchID = [touch hash];
  452. Platform::touchEventInternal(Touch::TOUCH_RELEASE, touchPoint.x * WINDOW_SCALE, touchPoint.y * WINDOW_SCALE, touchID);
  453. }
  454. }
  455. - (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event
  456. {
  457. // No equivalent for this in GamePlay -- treat as touch end
  458. [self touchesEnded:touches withEvent:event];
  459. }
  460. - (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
  461. {
  462. unsigned int touchID = 0;
  463. for(UITouch* touch in touches)
  464. {
  465. CGPoint touchPoint = [touch locationInView:self];
  466. if(self.multipleTouchEnabled == YES)
  467. touchID = [touch hash];
  468. Platform::touchEventInternal(Touch::TOUCH_MOVE, touchPoint.x * WINDOW_SCALE, touchPoint.y * WINDOW_SCALE, touchID);
  469. }
  470. }
  471. // Gesture support for Mac OS X Trackpads
  472. - (bool)isGestureRegistered: (Gesture::GestureEvent) evt
  473. {
  474. switch(evt) {
  475. case Gesture::GESTURE_SWIPE:
  476. return (_swipeRecognizer != NULL);
  477. case Gesture::GESTURE_PINCH:
  478. return (_pinchRecognizer != NULL);
  479. case Gesture::GESTURE_TAP:
  480. return (_tapRecognizer != NULL);
  481. default:
  482. break;
  483. }
  484. return false;
  485. }
  486. - (void)registerGesture: (Gesture::GestureEvent) evt
  487. {
  488. if((evt & Gesture::GESTURE_SWIPE) == Gesture::GESTURE_SWIPE && _swipeRecognizer == NULL)
  489. {
  490. _swipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGesture:)];
  491. [self addGestureRecognizer:_swipeRecognizer];
  492. }
  493. if((evt & Gesture::GESTURE_PINCH) == Gesture::GESTURE_PINCH && _pinchRecognizer == NULL)
  494. {
  495. _pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinchGesture:)];
  496. [self addGestureRecognizer:_pinchRecognizer];
  497. }
  498. if((evt & Gesture::GESTURE_TAP) == Gesture::GESTURE_TAP && _tapRecognizer == NULL)
  499. {
  500. _tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
  501. [self addGestureRecognizer:_tapRecognizer];
  502. }
  503. }
  504. - (void)unregisterGesture: (Gesture::GestureEvent) evt
  505. {
  506. if((evt & Gesture::GESTURE_SWIPE) == Gesture::GESTURE_SWIPE && _swipeRecognizer != NULL)
  507. {
  508. [self removeGestureRecognizer:_swipeRecognizer];
  509. [_swipeRecognizer release];
  510. _swipeRecognizer = NULL;
  511. }
  512. if((evt & Gesture::GESTURE_PINCH) == Gesture::GESTURE_PINCH && _pinchRecognizer != NULL)
  513. {
  514. [self removeGestureRecognizer:_pinchRecognizer];
  515. [_pinchRecognizer release];
  516. _pinchRecognizer = NULL;
  517. }
  518. if((evt & Gesture::GESTURE_TAP) == Gesture::GESTURE_TAP && _tapRecognizer != NULL)
  519. {
  520. [self removeGestureRecognizer:_tapRecognizer];
  521. [_tapRecognizer release];
  522. _tapRecognizer = NULL;
  523. }
  524. }
  525. - (void)handleTapGesture:(UITapGestureRecognizer*)sender
  526. {
  527. CGPoint location = [sender locationInView:self];
  528. game->gestureTapEvent(location.x, location.y);
  529. }
  530. - (void)handlePinchGesture:(UIPinchGestureRecognizer*)sender
  531. {
  532. CGFloat factor = [sender scale];
  533. CGPoint location = [sender locationInView:self];
  534. game->gesturePinchEvent(location.x, location.y, factor);
  535. }
  536. - (void)handleSwipeGesture:(UISwipeGestureRecognizer*)sender
  537. {
  538. UISwipeGestureRecognizerDirection direction = [sender direction];
  539. CGPoint location = [sender locationInView:self];
  540. int gameplayDirection = 0;
  541. switch(direction) {
  542. case UISwipeGestureRecognizerDirectionRight:
  543. gameplayDirection = Gesture::SWIPE_DIRECTION_RIGHT;
  544. break;
  545. case UISwipeGestureRecognizerDirectionLeft:
  546. gameplayDirection = Gesture::SWIPE_DIRECTION_LEFT;
  547. break;
  548. case UISwipeGestureRecognizerDirectionUp:
  549. gameplayDirection = Gesture::SWIPE_DIRECTION_UP;
  550. break;
  551. case UISwipeGestureRecognizerDirectionDown:
  552. gameplayDirection = Gesture::SWIPE_DIRECTION_DOWN;
  553. break;
  554. }
  555. game->gestureSwipeEvent(location.x, location.y, gameplayDirection);
  556. }
  557. @end
  558. @interface ViewController : UIViewController
  559. - (void)startUpdating;
  560. - (void)stopUpdating;
  561. @end
  562. @implementation ViewController
  563. - (id)init
  564. {
  565. if((self = [super init]))
  566. {
  567. }
  568. return self;
  569. }
  570. - (void)dealloc
  571. {
  572. __view = nil;
  573. [super dealloc];
  574. }
  575. - (void)didReceiveMemoryWarning
  576. {
  577. [super didReceiveMemoryWarning];
  578. }
  579. #pragma mark - View lifecycle
  580. - (void)loadView
  581. {
  582. self.view = [[[View alloc] init] autorelease];
  583. if(__view == nil)
  584. {
  585. __view = (View*)self.view;
  586. }
  587. }
  588. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
  589. {
  590. // Fetch the supported orientations array
  591. NSArray *supportedOrientations = NULL;
  592. if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
  593. {
  594. supportedOrientations = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UISupportedInterfaceOrientations~ipad"];
  595. }
  596. else if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
  597. {
  598. supportedOrientations = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UISupportedInterfaceOrientations~iphone"];
  599. }
  600. if(supportedOrientations == NULL)
  601. {
  602. supportedOrientations = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UISupportedInterfaceOrientations"];
  603. }
  604. // If no supported orientations default to v1.0 handling (landscape only)
  605. if(supportedOrientations == nil) {
  606. return UIInterfaceOrientationIsLandscape(interfaceOrientation);
  607. }
  608. for(NSString *s in supportedOrientations) {
  609. if(interfaceOrientation == UIInterfaceOrientationEnum(s)) return YES;
  610. }
  611. return NO;
  612. }
  613. - (void)startUpdating
  614. {
  615. [(View*)self.view startUpdating];
  616. }
  617. - (void)stopUpdating
  618. {
  619. [(View*)self.view stopUpdating];
  620. }
  621. @end
  622. @interface AppDelegate : UIApplication <UIApplicationDelegate>
  623. {
  624. UIWindow* window;
  625. ViewController* viewController;
  626. CMMotionManager *motionManager;
  627. }
  628. @property (nonatomic, retain) ViewController *viewController;
  629. @end
  630. @implementation AppDelegate
  631. @synthesize viewController;
  632. - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
  633. {
  634. __appDelegate = self;
  635. [UIApplication sharedApplication].statusBarHidden = YES;
  636. [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
  637. motionManager = [[CMMotionManager alloc] init];
  638. if([motionManager isAccelerometerAvailable] == YES)
  639. {
  640. motionManager.accelerometerUpdateInterval = 1 / 40.0; // 40Hz
  641. [motionManager startAccelerometerUpdates];
  642. }
  643. window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  644. viewController = [[ViewController alloc] init];
  645. [window setRootViewController:viewController];
  646. [window makeKeyAndVisible];
  647. return YES;
  648. }
  649. - (void)getAccelerometerPitch:(float*)pitch roll:(float*)roll
  650. {
  651. float p = 0.0f;
  652. float r = 0.0f;
  653. CMAccelerometerData* accelerometerData = motionManager.accelerometerData;
  654. if(accelerometerData != nil)
  655. {
  656. float tx, ty, tz;
  657. switch ([[UIApplication sharedApplication] statusBarOrientation])
  658. {
  659. case UIInterfaceOrientationLandscapeRight:
  660. tx = -accelerometerData.acceleration.y;
  661. ty = accelerometerData.acceleration.x;
  662. break;
  663. case UIInterfaceOrientationLandscapeLeft:
  664. tx = accelerometerData.acceleration.y;
  665. ty = -accelerometerData.acceleration.x;
  666. break;
  667. case UIInterfaceOrientationPortraitUpsideDown:
  668. tx = -accelerometerData.acceleration.y;
  669. ty = -accelerometerData.acceleration.x;
  670. break;
  671. case UIInterfaceOrientationPortrait:
  672. tx = accelerometerData.acceleration.x;
  673. ty = accelerometerData.acceleration.y;
  674. break;
  675. }
  676. tz = accelerometerData.acceleration.z;
  677. p = atan(ty / sqrt(tx * tx + tz * tz)) * 180.0f * M_1_PI;
  678. r = atan(tx / sqrt(ty * ty + tz * tz)) * 180.0f * M_1_PI;
  679. }
  680. if(pitch != NULL)
  681. *pitch = p;
  682. if(roll != NULL)
  683. *roll = r;
  684. }
  685. - (void)applicationWillResignActive:(UIApplication*)application
  686. {
  687. [viewController stopUpdating];
  688. }
  689. - (void)applicationDidEnterBackground:(UIApplication*)application
  690. {
  691. [viewController stopUpdating];
  692. }
  693. - (void)applicationWillEnterForeground:(UIApplication*)application
  694. {
  695. [viewController startUpdating];
  696. }
  697. - (void)applicationDidBecomeActive:(UIApplication*)application
  698. {
  699. [viewController startUpdating];
  700. }
  701. - (void)applicationWillTerminate:(UIApplication*)application
  702. {
  703. [viewController stopUpdating];
  704. }
  705. - (void)dealloc
  706. {
  707. [window setRootViewController:nil];
  708. [viewController release];
  709. [window release];
  710. [motionManager release];
  711. [super dealloc];
  712. }
  713. @end
  714. double getMachTimeInMilliseconds()
  715. {
  716. static const double kOneMillion = 1000 * 1000;
  717. static mach_timebase_info_data_t s_timebase_info;
  718. if (s_timebase_info.denom == 0)
  719. (void) mach_timebase_info(&s_timebase_info);
  720. // mach_absolute_time() returns billionth of seconds, so divide by one million to get milliseconds
  721. GP_ASSERT(s_timebase_info.denom);
  722. return ((double)mach_absolute_time() * (double)s_timebase_info.numer) / (kOneMillion * (double)s_timebase_info.denom);
  723. }
  724. int getKey(unichar keyCode)
  725. {
  726. switch(keyCode)
  727. {
  728. case 0x30:
  729. return Keyboard::KEY_ZERO;
  730. case 0x31:
  731. return Keyboard::KEY_ONE;
  732. case 0x32:
  733. return Keyboard::KEY_TWO;
  734. case 0x33:
  735. return Keyboard::KEY_THREE;
  736. case 0x34:
  737. return Keyboard::KEY_FOUR;
  738. case 0x35:
  739. return Keyboard::KEY_FIVE;
  740. case 0x36:
  741. return Keyboard::KEY_SIX;
  742. case 0x37:
  743. return Keyboard::KEY_SEVEN;
  744. case 0x38:
  745. return Keyboard::KEY_EIGHT;
  746. case 0x39:
  747. return Keyboard::KEY_NINE;
  748. case 0x41:
  749. return Keyboard::KEY_CAPITAL_A;
  750. case 0x42:
  751. return Keyboard::KEY_CAPITAL_B;
  752. case 0x43:
  753. return Keyboard::KEY_CAPITAL_C;
  754. case 0x44:
  755. return Keyboard::KEY_CAPITAL_D;
  756. case 0x45:
  757. return Keyboard::KEY_CAPITAL_E;
  758. case 0x46:
  759. return Keyboard::KEY_CAPITAL_F;
  760. case 0x47:
  761. return Keyboard::KEY_CAPITAL_G;
  762. case 0x48:
  763. return Keyboard::KEY_CAPITAL_H;
  764. case 0x49:
  765. return Keyboard::KEY_CAPITAL_I;
  766. case 0x4A:
  767. return Keyboard::KEY_CAPITAL_J;
  768. case 0x4B:
  769. return Keyboard::KEY_CAPITAL_K;
  770. case 0x4C:
  771. return Keyboard::KEY_CAPITAL_L;
  772. case 0x4D:
  773. return Keyboard::KEY_CAPITAL_M;
  774. case 0x4E:
  775. return Keyboard::KEY_CAPITAL_N;
  776. case 0x4F:
  777. return Keyboard::KEY_CAPITAL_O;
  778. case 0x50:
  779. return Keyboard::KEY_CAPITAL_P;
  780. case 0x51:
  781. return Keyboard::KEY_CAPITAL_Q;
  782. case 0x52:
  783. return Keyboard::KEY_CAPITAL_R;
  784. case 0x53:
  785. return Keyboard::KEY_CAPITAL_S;
  786. case 0x54:
  787. return Keyboard::KEY_CAPITAL_T;
  788. case 0x55:
  789. return Keyboard::KEY_CAPITAL_U;
  790. case 0x56:
  791. return Keyboard::KEY_CAPITAL_V;
  792. case 0x57:
  793. return Keyboard::KEY_CAPITAL_W;
  794. case 0x58:
  795. return Keyboard::KEY_CAPITAL_X;
  796. case 0x59:
  797. return Keyboard::KEY_CAPITAL_Y;
  798. case 0x5A:
  799. return Keyboard::KEY_CAPITAL_Z;
  800. case 0x61:
  801. return Keyboard::KEY_A;
  802. case 0x62:
  803. return Keyboard::KEY_B;
  804. case 0x63:
  805. return Keyboard::KEY_C;
  806. case 0x64:
  807. return Keyboard::KEY_D;
  808. case 0x65:
  809. return Keyboard::KEY_E;
  810. case 0x66:
  811. return Keyboard::KEY_F;
  812. case 0x67:
  813. return Keyboard::KEY_G;
  814. case 0x68:
  815. return Keyboard::KEY_H;
  816. case 0x69:
  817. return Keyboard::KEY_I;
  818. case 0x6A:
  819. return Keyboard::KEY_J;
  820. case 0x6B:
  821. return Keyboard::KEY_K;
  822. case 0x6C:
  823. return Keyboard::KEY_L;
  824. case 0x6D:
  825. return Keyboard::KEY_M;
  826. case 0x6E:
  827. return Keyboard::KEY_N;
  828. case 0x6F:
  829. return Keyboard::KEY_O;
  830. case 0x70:
  831. return Keyboard::KEY_P;
  832. case 0x71:
  833. return Keyboard::KEY_Q;
  834. case 0x72:
  835. return Keyboard::KEY_R;
  836. case 0x73:
  837. return Keyboard::KEY_S;
  838. case 0x74:
  839. return Keyboard::KEY_T;
  840. case 0x75:
  841. return Keyboard::KEY_U;
  842. case 0x76:
  843. return Keyboard::KEY_V;
  844. case 0x77:
  845. return Keyboard::KEY_W;
  846. case 0x78:
  847. return Keyboard::KEY_X;
  848. case 0x79:
  849. return Keyboard::KEY_Y;
  850. case 0x7A:
  851. return Keyboard::KEY_Z;
  852. default:
  853. break;
  854. // Symbol Row 3
  855. case 0x2E:
  856. return Keyboard::KEY_PERIOD;
  857. case 0x2C:
  858. return Keyboard::KEY_COMMA;
  859. case 0x3F:
  860. return Keyboard::KEY_QUESTION;
  861. case 0x21:
  862. return Keyboard::KEY_EXCLAM;
  863. case 0x27:
  864. return Keyboard::KEY_APOSTROPHE;
  865. // Symbols Row 2
  866. case 0x2D:
  867. return Keyboard::KEY_MINUS;
  868. case 0x2F:
  869. return Keyboard::KEY_SLASH;
  870. case 0x3A:
  871. return Keyboard::KEY_COLON;
  872. case 0x3B:
  873. return Keyboard::KEY_SEMICOLON;
  874. case 0x28:
  875. return Keyboard::KEY_LEFT_PARENTHESIS;
  876. case 0x29:
  877. return Keyboard::KEY_RIGHT_PARENTHESIS;
  878. case 0x24:
  879. return Keyboard::KEY_DOLLAR;
  880. case 0x26:
  881. return Keyboard::KEY_AMPERSAND;
  882. case 0x40:
  883. return Keyboard::KEY_AT;
  884. case 0x22:
  885. return Keyboard::KEY_QUOTE;
  886. // Numeric Symbols Row 1
  887. case 0x5B:
  888. return Keyboard::KEY_LEFT_BRACKET;
  889. case 0x5D:
  890. return Keyboard::KEY_RIGHT_BRACKET;
  891. case 0x7B:
  892. return Keyboard::KEY_LEFT_BRACE;
  893. case 0x7D:
  894. return Keyboard::KEY_RIGHT_BRACE;
  895. case 0x23:
  896. return Keyboard::KEY_NUMBER;
  897. case 0x25:
  898. return Keyboard::KEY_PERCENT;
  899. case 0x5E:
  900. return Keyboard::KEY_CIRCUMFLEX;
  901. case 0x2A:
  902. return Keyboard::KEY_ASTERISK;
  903. case 0x2B:
  904. return Keyboard::KEY_PLUS;
  905. case 0x3D:
  906. return Keyboard::KEY_EQUAL;
  907. // Numeric Symbols Row 2
  908. case 0x5F:
  909. return Keyboard::KEY_UNDERSCORE;
  910. case 0x5C:
  911. return Keyboard::KEY_BACK_SLASH;
  912. case 0x7C:
  913. return Keyboard::KEY_BAR;
  914. case 0x7E:
  915. return Keyboard::KEY_TILDE;
  916. case 0x3C:
  917. return Keyboard::KEY_LESS_THAN;
  918. case 0x3E:
  919. return Keyboard::KEY_GREATER_THAN;
  920. case 0x80:
  921. return Keyboard::KEY_EURO;
  922. case 0xA3:
  923. return Keyboard::KEY_POUND;
  924. case 0xA5:
  925. return Keyboard::KEY_YEN;
  926. case 0xB7:
  927. return Keyboard::KEY_MIDDLE_DOT;
  928. }
  929. return Keyboard::KEY_NONE;
  930. }
  931. namespace gameplay
  932. {
  933. extern void print(const char* format, ...)
  934. {
  935. GP_ASSERT(format);
  936. va_list argptr;
  937. va_start(argptr, format);
  938. vfprintf(stderr, format, argptr);
  939. va_end(argptr);
  940. }
  941. Platform::Platform(Game* game) : _game(game)
  942. {
  943. }
  944. Platform::~Platform()
  945. {
  946. }
  947. Platform* Platform::create(Game* game, void* attachToWindow)
  948. {
  949. Platform* platform = new Platform(game);
  950. return platform;
  951. }
  952. int Platform::enterMessagePump()
  953. {
  954. NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  955. [AppDelegate load];
  956. UIApplicationMain(0, nil, NSStringFromClass([AppDelegate class]), NSStringFromClass([AppDelegate class]));
  957. [pool release];
  958. return EXIT_SUCCESS;
  959. }
  960. void Platform::signalShutdown()
  961. {
  962. // Cannot 'exit' an iOS Application
  963. assert(false);
  964. [__view stopUpdating];
  965. exit(0);
  966. }
  967. bool Platform::canExit()
  968. {
  969. return false;
  970. }
  971. unsigned int Platform::getDisplayWidth()
  972. {
  973. CGSize size = DeviceOrientedSize([__appDelegate.viewController interfaceOrientation]);
  974. return size.width;
  975. }
  976. unsigned int Platform::getDisplayHeight()
  977. {
  978. CGSize size = DeviceOrientedSize([__appDelegate.viewController interfaceOrientation]);
  979. return size.height;
  980. }
  981. double Platform::getAbsoluteTime()
  982. {
  983. __timeAbsolute = getMachTimeInMilliseconds();
  984. return __timeAbsolute;
  985. }
  986. void Platform::setAbsoluteTime(double time)
  987. {
  988. __timeAbsolute = time;
  989. }
  990. bool Platform::isVsync()
  991. {
  992. return __vsync;
  993. }
  994. void Platform::setVsync(bool enable)
  995. {
  996. __vsync = enable;
  997. }
  998. void Platform::swapBuffers()
  999. {
  1000. if (__view)
  1001. [__view swapBuffers];
  1002. }
  1003. void Platform::sleep(long ms)
  1004. {
  1005. usleep(ms * 1000);
  1006. }
  1007. void Platform::getAccelerometerValues(float* pitch, float* roll)
  1008. {
  1009. [__appDelegate getAccelerometerPitch:pitch roll:roll];
  1010. }
  1011. bool Platform::hasMouse()
  1012. {
  1013. // not supported
  1014. return false;
  1015. }
  1016. void Platform::setMouseCaptured(bool captured)
  1017. {
  1018. // not supported
  1019. }
  1020. bool Platform::isMouseCaptured()
  1021. {
  1022. // not supported
  1023. return false;
  1024. }
  1025. void Platform::setCursorVisible(bool visible)
  1026. {
  1027. // not supported
  1028. }
  1029. bool Platform::isCursorVisible()
  1030. {
  1031. // not supported
  1032. return false;
  1033. }
  1034. void Platform::setMultiTouch(bool enabled)
  1035. {
  1036. __view.multipleTouchEnabled = enabled;
  1037. }
  1038. bool Platform::isMultiTouch()
  1039. {
  1040. return __view.multipleTouchEnabled;
  1041. }
  1042. void Platform::displayKeyboard(bool display)
  1043. {
  1044. if(__view)
  1045. {
  1046. if(display)
  1047. {
  1048. [__view showKeyboard];
  1049. }
  1050. else
  1051. {
  1052. [__view dismissKeyboard];
  1053. }
  1054. }
  1055. }
  1056. void Platform::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
  1057. {
  1058. if (!Form::touchEventInternal(evt, x, y, contactIndex))
  1059. {
  1060. Game::getInstance()->touchEvent(evt, x, y, contactIndex);
  1061. Game::getInstance()->getScriptController()->touchEvent(evt, x, y, contactIndex);
  1062. }
  1063. }
  1064. void Platform::keyEventInternal(Keyboard::KeyEvent evt, int key)
  1065. {
  1066. if (!Form::keyEventInternal(evt, key))
  1067. {
  1068. Game::getInstance()->keyEvent(evt, key);
  1069. Game::getInstance()->getScriptController()->keyEvent(evt, key);
  1070. }
  1071. }
  1072. bool Platform::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
  1073. {
  1074. if (Form::mouseEventInternal(evt, x, y, wheelDelta))
  1075. {
  1076. return true;
  1077. }
  1078. else if (Game::getInstance()->mouseEvent(evt, x, y, wheelDelta))
  1079. {
  1080. return true;
  1081. }
  1082. else
  1083. {
  1084. return Game::getInstance()->getScriptController()->mouseEvent(evt, x, y, wheelDelta);
  1085. }
  1086. }
  1087. bool Platform::isGestureSupported(Gesture::GestureEvent evt)
  1088. {
  1089. return true;
  1090. }
  1091. void Platform::registerGesture(Gesture::GestureEvent evt)
  1092. {
  1093. [__view registerGesture:evt];
  1094. }
  1095. void Platform::unregisterGesture(Gesture::GestureEvent evt)
  1096. {
  1097. [__view unregisterGesture:evt];
  1098. }
  1099. bool Platform::isGestureRegistered(Gesture::GestureEvent evt)
  1100. {
  1101. return [__view isGestureRegistered:evt];
  1102. }
  1103. unsigned int Platform::getGamepadsConnected()
  1104. {
  1105. return 0;
  1106. }
  1107. bool Platform::isGamepadConnected(unsigned int gamepadHandle)
  1108. {
  1109. return false;
  1110. }
  1111. const char* Platform::getGamepadId(unsigned int gamepadHandle)
  1112. {
  1113. return NULL;
  1114. }
  1115. unsigned int Platform::getGamepadButtonCount(unsigned int gamepadHandle)
  1116. {
  1117. return 0;
  1118. }
  1119. bool Platform::getGamepadButtonState(unsigned int gamepadHandle, unsigned int buttonIndex)
  1120. {
  1121. return false;
  1122. }
  1123. unsigned int Platform::getGamepadJoystickCount(unsigned int gamepadHandle)
  1124. {
  1125. return 0;
  1126. }
  1127. bool Platform::isGamepadJoystickActive(unsigned int gamepadHandle, unsigned int joystickIndex)
  1128. {
  1129. return false;
  1130. }
  1131. float Platform::getGamepadJoystickAxisX(unsigned int gamepadHandle, unsigned int joystickIndex)
  1132. {
  1133. return 0.0f;
  1134. }
  1135. float Platform::getGamepadJoystickAxisY(unsigned int gamepadHandle, unsigned int joystickIndex)
  1136. {
  1137. return 0.0f;
  1138. }
  1139. void Platform::getGamepadJoystickAxisValues(unsigned int gamepadHandle, unsigned int joystickIndex, Vector2* outValue)
  1140. {
  1141. }
  1142. unsigned int Platform::getGamepadTriggerCount(unsigned int gamepadHandle)
  1143. {
  1144. return 0;
  1145. }
  1146. float Platform::getGamepadTriggerValue(unsigned int gamepadHandle, unsigned int triggerIndex)
  1147. {
  1148. return 0.0f;
  1149. }
  1150. }
  1151. #endif