]> git.lizzy.rs Git - irrlicht.git/blob - source/Irrlicht/CIrrDeviceiOS.mm
Bump revision early
[irrlicht.git] / source / Irrlicht / CIrrDeviceiOS.mm
1 // Copyright (C) 2002-2008 Nikolaus Gebhardt\r
2 // Copyright (C) 2008 Redshift Software, Inc.\r
3 // Copyright (C) 2012 Patryk Nadrowski\r
4 // This file is part of the "Irrlicht Engine".\r
5 // For conditions of distribution and use, see copyright notice in irrlicht.h\r
6 \r
7 #import "CIrrDeviceiOS.h"\r
8 \r
9 #ifdef _IRR_COMPILE_WITH_IOS_DEVICE_\r
10 \r
11 #include "IFileSystem.h"\r
12 #include "CTimer.h"\r
13 #include "CEAGLManager.h"\r
14 \r
15 #import <UIKit/UIKit.h>\r
16 #import <CoreMotion/CoreMotion.h>\r
17 \r
18 /* Important information */\r
19 \r
20 // The application state events and following methods: IrrlichtDevice::isWindowActive, IrrlichtDevice::isWindowFocused\r
21 // and IrrlichtDevice::isWindowMinimized works out of box only if you'll use built-in CIrrDelegateiOS,\r
22 // so _IRR_COMPILE_WITH_IOS_BUILTIN_MAIN_ must be enabled in this case. If you need a custom UIApplicationDelegate you must\r
23 // handle all application events yourself.\r
24 \r
25 #ifdef _IRR_COMPILE_WITH_IOS_BUILTIN_MAIN_\r
26 \r
27 namespace irr\r
28 {\r
29         class CIrrDeviceiOS;\r
30 }\r
31 \r
32 /* CIrrDelegateiOS */\r
33 \r
34 @interface CIrrDelegateiOS : NSObject<UIApplicationDelegate>\r
35 \r
36 - (void)setDevice:(irr::CIrrDeviceiOS*)device;\r
37 - (bool)isActive;\r
38 - (bool)hasFocus;\r
39 \r
40 @property (strong, nonatomic) UIWindow* window;\r
41 \r
42 @end\r
43 \r
44 @implementation CIrrDelegateiOS\r
45 {\r
46         irr::CIrrDeviceiOS* Device;\r
47         bool Active;\r
48         bool Focus;\r
49 }\r
50 \r
51 - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)options\r
52 {\r
53         Device = nil;\r
54         Active = true;\r
55         Focus = false;\r
56         \r
57         [self performSelectorOnMainThread:@selector(runIrrlicht) withObject:nil waitUntilDone:NO];\r
58         \r
59         return YES;\r
60 }\r
61 \r
62 - (void)applicationWillTerminate:(UIApplication*)application\r
63 {\r
64         if (Device != nil)\r
65         {\r
66                 irr::SEvent ev;\r
67                 ev.EventType = irr::EET_APPLICATION_EVENT;\r
68                 ev.ApplicationEvent.EventType = irr::EAET_WILL_TERMINATE;\r
69 \r
70                 Device->postEventFromUser(ev);\r
71                 \r
72                 Device->closeDevice();\r
73         }\r
74 }\r
75 \r
76 - (void)applicationDidReceiveMemoryWarning:(UIApplication*)application\r
77 {\r
78         if (Device != nil)\r
79         {\r
80                 irr::SEvent ev;\r
81                 ev.EventType = irr::EET_APPLICATION_EVENT;\r
82                 ev.ApplicationEvent.EventType = irr::EAET_MEMORY_WARNING;\r
83                 \r
84                 Device->postEventFromUser(ev);\r
85         }\r
86 }\r
87 \r
88 - (void)applicationWillResignActive:(UIApplication*)application\r
89 {\r
90         if (Device != nil)\r
91         {\r
92                 irr::SEvent ev;\r
93                 ev.EventType = irr::EET_APPLICATION_EVENT;\r
94                 ev.ApplicationEvent.EventType = irr::EAET_WILL_PAUSE;\r
95                 \r
96                 Device->postEventFromUser(ev);\r
97         }\r
98         \r
99         Focus = false;\r
100 }\r
101 \r
102 - (void)applicationDidEnterBackground:(UIApplication*)application\r
103 {\r
104         if (Device != nil)\r
105         {\r
106                 irr::SEvent ev;\r
107                 ev.EventType = irr::EET_APPLICATION_EVENT;\r
108                 ev.ApplicationEvent.EventType = irr::EAET_DID_PAUSE;\r
109                 \r
110                 Device->postEventFromUser(ev);\r
111         }\r
112         \r
113         Active = false;\r
114 }\r
115 \r
116 - (void)applicationWillEnterForeground:(UIApplication*)application\r
117 {\r
118         if (Device != nil)\r
119         {\r
120                 irr::SEvent ev;\r
121                 ev.EventType = irr::EET_APPLICATION_EVENT;\r
122                 ev.ApplicationEvent.EventType = irr::EAET_WILL_RESUME;\r
123                 \r
124                 Device->postEventFromUser(ev);\r
125         }\r
126         \r
127         Active = true;\r
128 }\r
129 \r
130 - (void)applicationDidBecomeActive:(UIApplication*)application\r
131 {\r
132         if (Device != nil)\r
133         {\r
134                 irr::SEvent ev;\r
135                 ev.EventType = irr::EET_APPLICATION_EVENT;\r
136                 ev.ApplicationEvent.EventType = irr::EAET_DID_RESUME;\r
137                 \r
138                 Device->postEventFromUser(ev);\r
139         }\r
140         \r
141         Focus = true;\r
142 }\r
143 \r
144 - (void)runIrrlicht\r
145 {\r
146         irrlicht_main();\r
147 }\r
148 \r
149 - (void)setDevice:(irr::CIrrDeviceiOS*)device\r
150 {\r
151         Device = device;\r
152 }\r
153 \r
154 - (bool)isActive\r
155 {\r
156         return Active;\r
157 }\r
158 \r
159 - (bool)hasFocus\r
160 {\r
161         return Focus;\r
162 }\r
163 \r
164 @end\r
165 \r
166 #endif\r
167 \r
168 /* CIrrViewiOS */\r
169 \r
170 @interface CIrrViewiOS : UIView\r
171 \r
172 - (id)initWithFrame:(CGRect)frame forDevice:(irr::CIrrDeviceiOS*)device;\r
173 \r
174 @end\r
175 \r
176 @implementation CIrrViewiOS\r
177 {\r
178     irr::CIrrDeviceiOS* Device;\r
179     float Scale;\r
180 }\r
181 \r
182 - (id)initWithFrame:(CGRect)frame forDevice:(irr::CIrrDeviceiOS*)device;\r
183 {\r
184     self = [super initWithFrame:frame];\r
185     \r
186     if (self)\r
187     {\r
188         Device = device;\r
189         Scale = ([self respondsToSelector:@selector(setContentScaleFactor:)]) ? [[UIScreen mainScreen] scale] : 1.f;\r
190     }\r
191     \r
192     return self;\r
193 }\r
194 \r
195 - (BOOL)isMultipleTouchEnabled\r
196 {\r
197         return YES;\r
198 }\r
199 \r
200 - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event\r
201 {\r
202         irr::SEvent ev;\r
203         ev.EventType = irr::EET_TOUCH_INPUT_EVENT;\r
204         ev.TouchInput.Event = irr::ETIE_PRESSED_DOWN;\r
205     \r
206         for (UITouch* touch in touches)\r
207         {\r
208         ev.TouchInput.ID = (size_t)touch;\r
209 \r
210                 CGPoint touchPoint = [touch locationInView:self];\r
211         \r
212         ev.TouchInput.X = touchPoint.x*Scale;\r
213         ev.TouchInput.Y = touchPoint.y*Scale;\r
214 \r
215         Device->postEventFromUser(ev);\r
216         }\r
217 }\r
218 \r
219 - (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event\r
220 {\r
221         irr::SEvent ev;\r
222         ev.EventType = irr::EET_TOUCH_INPUT_EVENT;\r
223         ev.TouchInput.Event = irr::ETIE_MOVED;\r
224     \r
225         for (UITouch* touch in touches)\r
226         {\r
227         ev.TouchInput.ID = (size_t)touch;\r
228 \r
229                 CGPoint touchPoint = [touch locationInView:self];\r
230         \r
231         ev.TouchInput.X = touchPoint.x*Scale;\r
232         ev.TouchInput.Y = touchPoint.y*Scale;\r
233         \r
234         Device->postEventFromUser(ev);\r
235         }\r
236 }\r
237 \r
238 - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event\r
239 {\r
240         irr::SEvent ev;\r
241         ev.EventType = irr::EET_TOUCH_INPUT_EVENT;\r
242         ev.TouchInput.Event = irr::ETIE_LEFT_UP;\r
243     \r
244         for (UITouch* touch in touches)\r
245         {\r
246         ev.TouchInput.ID = (size_t)touch;\r
247 \r
248                 CGPoint touchPoint = [touch locationInView:self];\r
249         \r
250         ev.TouchInput.X = touchPoint.x*Scale;\r
251         ev.TouchInput.Y = touchPoint.y*Scale;\r
252         \r
253         Device->postEventFromUser(ev);\r
254         }\r
255 }\r
256 \r
257 - (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event\r
258 {\r
259         irr::SEvent ev;\r
260         ev.EventType = irr::EET_TOUCH_INPUT_EVENT;\r
261         ev.TouchInput.Event = irr::ETIE_LEFT_UP;\r
262     \r
263         for (UITouch* touch in touches)\r
264         {\r
265         ev.TouchInput.ID = (size_t)touch;\r
266 \r
267                 CGPoint touchPoint = [touch locationInView:self];\r
268         \r
269         ev.TouchInput.X = touchPoint.x*Scale;\r
270         ev.TouchInput.Y = touchPoint.y*Scale;\r
271         \r
272         Device->postEventFromUser(ev);\r
273         }\r
274 }\r
275 \r
276 @end\r
277 \r
278 /* CIrrViewEAGLiOS */\r
279 \r
280 @interface CIrrViewEAGLiOS : CIrrViewiOS\r
281 \r
282 @end\r
283 \r
284 @implementation CIrrViewEAGLiOS\r
285 \r
286 + (Class)layerClass\r
287 {\r
288         return [CAEAGLLayer class];\r
289 }\r
290 \r
291 @end\r
292 \r
293 namespace irr\r
294 {\r
295         namespace video\r
296         {\r
297                 IVideoDriver* createOGLES1Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager);\r
298                 \r
299                 IVideoDriver* createOGLES2Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager);\r
300         }\r
301         \r
302     struct SIrrDeviceiOSDataStorage\r
303     {\r
304         SIrrDeviceiOSDataStorage() : Window(0), ViewController(0), View(0), MotionManager(0), ReferenceAttitude(0)\r
305         {\r
306             MotionManager = [[CMMotionManager alloc] init];\r
307         }\r
308         \r
309         UIWindow* Window;\r
310         UIViewController* ViewController;\r
311         CIrrViewiOS* View;\r
312         CMMotionManager* MotionManager;\r
313         CMAttitude* ReferenceAttitude;\r
314     };\r
315     \r
316     CIrrDeviceiOS::CIrrDeviceiOS(const SIrrlichtCreationParameters& params) : CIrrDeviceStub(params), DataStorage(0), Close(false)\r
317     {\r
318 #ifdef _DEBUG\r
319         setDebugName("CIrrDeviceiOS");\r
320 #endif\r
321                 \r
322 #ifdef _IRR_COMPILE_WITH_IOS_BUILTIN_MAIN_\r
323                 CIrrDelegateiOS* delegate = [UIApplication sharedApplication].delegate;\r
324                 [delegate setDevice:this];\r
325 #endif\r
326         \r
327         DataStorage = new SIrrDeviceiOSDataStorage();\r
328 \r
329         FileSystem->changeWorkingDirectoryTo([[[NSBundle mainBundle] resourcePath] UTF8String]);\r
330 \r
331                 createWindow();\r
332         createViewAndDriver();\r
333         \r
334         if (!VideoDriver)\r
335             return;\r
336         \r
337         createGUIAndScene();\r
338     }\r
339 \r
340     CIrrDeviceiOS::~CIrrDeviceiOS()\r
341     {\r
342         deactivateDeviceMotion();\r
343         deactivateGyroscope();\r
344         deactivateAccelerometer();\r
345         \r
346         delete static_cast<SIrrDeviceiOSDataStorage*>(DataStorage);\r
347 \r
348 #ifdef _IRR_COMPILE_WITH_IOS_BUILTIN_MAIN_\r
349                 CIrrDelegateiOS* delegate = [UIApplication sharedApplication].delegate;\r
350                 [delegate setDevice:nil];\r
351 #endif\r
352     }\r
353 \r
354     bool CIrrDeviceiOS::run()\r
355     {\r
356                 if (!Close)\r
357                 {\r
358                         const CFTimeInterval timeInSeconds = 0.000002;\r
359                         \r
360                         s32 result = 0;\r
361                         \r
362                         do\r
363                         {\r
364                                 result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, timeInSeconds, TRUE);\r
365                         }\r
366                         while (result == kCFRunLoopRunHandledSource);\r
367                         \r
368                         os::Timer::tick();\r
369                         \r
370                         //! Update events\r
371                         \r
372                         SIrrDeviceiOSDataStorage* dataStorage = static_cast<SIrrDeviceiOSDataStorage*>(DataStorage);\r
373                         CMMotionManager* motionManager = dataStorage->MotionManager;\r
374                         \r
375                         //! Accelerometer\r
376                         if (motionManager.isAccelerometerActive)\r
377                         {\r
378                                 irr::SEvent ev;\r
379                                 ev.EventType = irr::EET_ACCELEROMETER_EVENT;\r
380                                 ev.AccelerometerEvent.X = motionManager.accelerometerData.acceleration.x;\r
381                                 ev.AccelerometerEvent.Y = motionManager.accelerometerData.acceleration.y;\r
382                                 ev.AccelerometerEvent.Z = motionManager.accelerometerData.acceleration.z;\r
383                                 \r
384                                 postEventFromUser(ev);\r
385                         }\r
386                         \r
387                         //! Gyroscope\r
388                         if (motionManager.isGyroActive)\r
389                         {\r
390                                 irr::SEvent ev;\r
391                                 ev.EventType = irr::EET_GYROSCOPE_EVENT;\r
392                                 ev.GyroscopeEvent.X = motionManager.gyroData.rotationRate.x;\r
393                                 ev.GyroscopeEvent.Y = motionManager.gyroData.rotationRate.y;\r
394                                 ev.GyroscopeEvent.Z = motionManager.gyroData.rotationRate.z;\r
395                                 \r
396                                 postEventFromUser(ev);\r
397                         }\r
398                         \r
399                         //! Device Motion\r
400                         if (motionManager.isDeviceMotionActive)\r
401                         {\r
402                                 CMAttitude* currentAttitude = motionManager.deviceMotion.attitude;\r
403                                 CMAttitude* referenceAttitude = dataStorage->ReferenceAttitude;\r
404                                 \r
405                                 if (referenceAttitude != nil)\r
406                                         [currentAttitude multiplyByInverseOfAttitude: referenceAttitude];\r
407                                 else\r
408                                         referenceAttitude = motionManager.deviceMotion.attitude;\r
409                                 \r
410                                 irr::SEvent ev;\r
411                                 ev.EventType = irr::EET_DEVICE_MOTION_EVENT;\r
412                                 ev.AccelerometerEvent.X = currentAttitude.roll;\r
413                                 ev.AccelerometerEvent.Y = currentAttitude.pitch;\r
414                                 ev.AccelerometerEvent.Z = currentAttitude.yaw;\r
415                                 \r
416                                 postEventFromUser(ev);\r
417                         }\r
418                 }\r
419 \r
420                 return !Close;\r
421     }\r
422 \r
423     void CIrrDeviceiOS::yield()\r
424     {\r
425         struct timespec ts = {0,0};\r
426         nanosleep(&ts, NULL);\r
427     }\r
428 \r
429     void CIrrDeviceiOS::sleep(u32 timeMs, bool pauseTimer=false)\r
430     {\r
431         bool wasStopped = Timer ? Timer->isStopped() : true;\r
432                 \r
433         struct timespec ts;\r
434         ts.tv_sec = (time_t) (timeMs / 1000);\r
435         ts.tv_nsec = (long) (timeMs % 1000) * 1000000;\r
436         \r
437         if (pauseTimer && !wasStopped)\r
438             Timer->stop();\r
439         \r
440         nanosleep(&ts, NULL);\r
441         \r
442         if (pauseTimer && !wasStopped)\r
443             Timer->start();\r
444     }\r
445 \r
446     void CIrrDeviceiOS::setWindowCaption(const wchar_t* text)\r
447     {\r
448     }\r
449     \r
450     bool CIrrDeviceiOS::isWindowActive() const\r
451     {\r
452 #ifdef _IRR_COMPILE_WITH_IOS_BUILTIN_MAIN_\r
453                 CIrrDelegateiOS* delegate = [UIApplication sharedApplication].delegate;\r
454                 \r
455                 return [delegate isActive];\r
456 #else\r
457                 return false;\r
458 #endif\r
459     }\r
460     \r
461     bool CIrrDeviceiOS::isWindowFocused() const\r
462     {\r
463 #ifdef _IRR_COMPILE_WITH_IOS_BUILTIN_MAIN_\r
464                 CIrrDelegateiOS* delegate = [UIApplication sharedApplication].delegate;\r
465                 \r
466                 return [delegate hasFocus];\r
467 #else\r
468                 return false;\r
469 #endif\r
470     }\r
471     \r
472     bool CIrrDeviceiOS::isWindowMinimized() const\r
473     {\r
474 #ifdef _IRR_COMPILE_WITH_IOS_BUILTIN_MAIN_\r
475                 CIrrDelegateiOS* delegate = [UIApplication sharedApplication].delegate;\r
476                 \r
477                 return ![delegate isActive];\r
478 #else\r
479                 return false;\r
480 #endif\r
481     }\r
482 \r
483     void CIrrDeviceiOS::closeDevice()\r
484     {\r
485         CFRunLoopStop(CFRunLoopGetMain());\r
486                 \r
487                 Close = true;\r
488     }\r
489 \r
490     void CIrrDeviceiOS::setResizable(bool resize)\r
491     {\r
492     }\r
493 \r
494     void CIrrDeviceiOS::minimizeWindow()\r
495     {\r
496     }\r
497 \r
498     void CIrrDeviceiOS::maximizeWindow()\r
499     {\r
500     }\r
501 \r
502     void CIrrDeviceiOS::restoreWindow()\r
503     {\r
504     }\r
505     \r
506     core::position2di CIrrDeviceiOS::getWindowPosition()\r
507     {\r
508         return core::position2di(0, 0);\r
509     }\r
510 \r
511     bool CIrrDeviceiOS::activateAccelerometer(float updateInterval)\r
512     {\r
513         bool status = false;\r
514         \r
515         SIrrDeviceiOSDataStorage* dataStorage = static_cast<SIrrDeviceiOSDataStorage*>(DataStorage);\r
516         CMMotionManager* motionManager = dataStorage->MotionManager;\r
517         \r
518         if (motionManager.isAccelerometerAvailable)\r
519         {\r
520             if (!motionManager.isAccelerometerActive)\r
521             {\r
522                 motionManager.accelerometerUpdateInterval = updateInterval;\r
523                 [motionManager startAccelerometerUpdates];\r
524             }\r
525             \r
526             status = true;\r
527         }\r
528         \r
529         return status;\r
530     }\r
531 \r
532     bool CIrrDeviceiOS::deactivateAccelerometer()\r
533     {\r
534         bool status = false;\r
535         \r
536         SIrrDeviceiOSDataStorage* dataStorage = static_cast<SIrrDeviceiOSDataStorage*>(DataStorage);\r
537         CMMotionManager* motionManager = dataStorage->MotionManager;\r
538         \r
539         if (motionManager.isAccelerometerAvailable)\r
540         {\r
541             if (motionManager.isAccelerometerActive)\r
542                 [motionManager stopAccelerometerUpdates];\r
543             \r
544             status = true;\r
545         }\r
546         \r
547         return status;\r
548     }\r
549     \r
550     bool CIrrDeviceiOS::isAccelerometerActive()\r
551     {\r
552         SIrrDeviceiOSDataStorage* dataStorage = static_cast<SIrrDeviceiOSDataStorage*>(DataStorage);\r
553 \r
554         return (dataStorage->MotionManager.isAccelerometerActive);\r
555     }\r
556 \r
557     bool CIrrDeviceiOS::isAccelerometerAvailable()\r
558     {\r
559         SIrrDeviceiOSDataStorage* dataStorage = static_cast<SIrrDeviceiOSDataStorage*>(DataStorage);\r
560         \r
561         return (dataStorage->MotionManager.isAccelerometerAvailable);\r
562     }\r
563     \r
564     bool CIrrDeviceiOS::activateGyroscope(float updateInterval)\r
565     {\r
566         bool status = false;\r
567         \r
568         SIrrDeviceiOSDataStorage* dataStorage = static_cast<SIrrDeviceiOSDataStorage*>(DataStorage);\r
569         CMMotionManager* motionManager = dataStorage->MotionManager;\r
570         \r
571         if (motionManager.isGyroAvailable)\r
572         {\r
573             if (!motionManager.isGyroActive)\r
574             {\r
575                 motionManager.gyroUpdateInterval = updateInterval;\r
576                 [motionManager startGyroUpdates];\r
577             }\r
578             \r
579             status = true;\r
580         }\r
581         \r
582         return status;\r
583     }\r
584 \r
585     bool CIrrDeviceiOS::deactivateGyroscope()\r
586     {\r
587         bool status = false;\r
588         \r
589         SIrrDeviceiOSDataStorage* dataStorage = static_cast<SIrrDeviceiOSDataStorage*>(DataStorage);\r
590         CMMotionManager* motionManager = dataStorage->MotionManager;\r
591         \r
592         if (motionManager.isGyroAvailable)\r
593         {\r
594             if (motionManager.isGyroActive)\r
595                 [motionManager stopGyroUpdates];\r
596             \r
597             status = true;\r
598         }\r
599         \r
600         return status;\r
601     }\r
602     \r
603     bool CIrrDeviceiOS::isGyroscopeActive()\r
604     {\r
605         SIrrDeviceiOSDataStorage* dataStorage = static_cast<SIrrDeviceiOSDataStorage*>(DataStorage);\r
606         \r
607         return (dataStorage->MotionManager.isGyroActive);\r
608     }\r
609 \r
610     bool CIrrDeviceiOS::isGyroscopeAvailable()\r
611     {\r
612         SIrrDeviceiOSDataStorage* dataStorage = static_cast<SIrrDeviceiOSDataStorage*>(DataStorage);\r
613         \r
614         return (dataStorage->MotionManager.isGyroAvailable);\r
615     }\r
616     \r
617     bool CIrrDeviceiOS::activateDeviceMotion(float updateInterval)\r
618     {\r
619         bool status = false;\r
620         \r
621         SIrrDeviceiOSDataStorage* dataStorage = static_cast<SIrrDeviceiOSDataStorage*>(DataStorage);\r
622         CMMotionManager* motionManager = dataStorage->MotionManager;\r
623         \r
624         if (motionManager.isDeviceMotionAvailable)\r
625         {\r
626             if (!motionManager.isDeviceMotionActive)\r
627             {\r
628                 dataStorage->ReferenceAttitude = nil;\r
629                 \r
630                 motionManager.deviceMotionUpdateInterval = updateInterval;\r
631                 [motionManager startDeviceMotionUpdates];\r
632             }\r
633             \r
634             status = true;\r
635         }\r
636         \r
637         return status;\r
638     }\r
639     \r
640     bool CIrrDeviceiOS::deactivateDeviceMotion()\r
641     {\r
642         bool status = false;\r
643         \r
644         SIrrDeviceiOSDataStorage* dataStorage = static_cast<SIrrDeviceiOSDataStorage*>(DataStorage);\r
645         CMMotionManager* motionManager = dataStorage->MotionManager;\r
646         \r
647         if (motionManager.isDeviceMotionAvailable)\r
648         {\r
649             if (motionManager.isDeviceMotionActive)\r
650             {\r
651                 [motionManager stopDeviceMotionUpdates];\r
652                 \r
653                 dataStorage->ReferenceAttitude = nil;\r
654             }\r
655             \r
656             status = true;\r
657         }\r
658         \r
659         return status;\r
660     }\r
661     \r
662     bool CIrrDeviceiOS::isDeviceMotionActive()\r
663     {\r
664         SIrrDeviceiOSDataStorage* dataStorage = static_cast<SIrrDeviceiOSDataStorage*>(DataStorage);\r
665         \r
666         return (dataStorage->MotionManager.isDeviceMotionActive);\r
667     }\r
668     \r
669     bool CIrrDeviceiOS::isDeviceMotionAvailable()\r
670     {\r
671         SIrrDeviceiOSDataStorage* dataStorage = static_cast<SIrrDeviceiOSDataStorage*>(DataStorage);\r
672         \r
673         return (dataStorage->MotionManager.isDeviceMotionAvailable);\r
674     }\r
675     \r
676     E_DEVICE_TYPE CIrrDeviceiOS::getType() const\r
677     {\r
678         return EIDT_IOS;\r
679     }\r
680 \r
681     void CIrrDeviceiOS::createWindow()\r
682     {\r
683                 if (CreationParams.DriverType != video::EDT_NULL)\r
684                 {\r
685                         SIrrDeviceiOSDataStorage* dataStorage = static_cast<SIrrDeviceiOSDataStorage*>(DataStorage);\r
686                         \r
687                         UIView* externalView = (__bridge UIView*)CreationParams.WindowId;\r
688                         \r
689                         if (externalView == nil)\r
690                         {\r
691                                 dataStorage->Window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];\r
692                                 dataStorage->ViewController = [[UIViewController alloc] init];\r
693                                 dataStorage->Window.rootViewController = dataStorage->ViewController;\r
694                                 \r
695                                 [dataStorage->Window makeKeyAndVisible];\r
696                         }\r
697                         else\r
698                         {\r
699                                 dataStorage->Window = externalView.window;\r
700                                 \r
701                                 UIResponder* currentResponder = externalView.nextResponder;\r
702                                 \r
703                                 do\r
704                                 {\r
705                                         if ([currentResponder isKindOfClass:[UIViewController class]])\r
706                                         {\r
707                                                 dataStorage->ViewController = (UIViewController*)currentResponder;\r
708                                                 \r
709                                                 currentResponder = nil;\r
710                                         }\r
711                                         else if ([currentResponder isKindOfClass:[UIView class]])\r
712                                         {\r
713                                                 currentResponder = currentResponder.nextResponder;\r
714                                         }\r
715                                         else\r
716                                         {\r
717                                                 currentResponder = nil;\r
718                                                 \r
719                                                 // Could not find view controller.\r
720                                                 _IRR_DEBUG_BREAK_IF(true);\r
721                                         }\r
722                                 }\r
723                                 while (currentResponder != nil);\r
724                         }\r
725                 }\r
726     }\r
727     \r
728     void CIrrDeviceiOS::createViewAndDriver()\r
729     {\r
730                 SIrrDeviceiOSDataStorage* dataStorage = static_cast<SIrrDeviceiOSDataStorage*>(DataStorage);\r
731                 \r
732                 video::SExposedVideoData data;\r
733                 data.OpenGLiOS.Window = (__bridge void*)dataStorage->Window;\r
734                 data.OpenGLiOS.ViewController = (__bridge void*)dataStorage->ViewController;\r
735                 \r
736                 UIView* externalView = (__bridge UIView*)CreationParams.WindowId;\r
737                 \r
738                 CGRect resolution = (externalView == nil) ? [[UIScreen mainScreen] bounds] : externalView.bounds;\r
739 \r
740         switch (CreationParams.DriverType)\r
741         {\r
742             case video::EDT_OGLES1:\r
743 #ifdef _IRR_COMPILE_WITH_OGLES1_\r
744                 {\r
745                                         CIrrViewEAGLiOS* view = [[CIrrViewEAGLiOS alloc] initWithFrame:resolution forDevice:this];\r
746                                         CreationParams.WindowSize = core::dimension2d<u32>(view.frame.size.width, view.frame.size.height);\r
747                                         \r
748                                         dataStorage->View = view;\r
749                                         data.OpenGLiOS.View = (__bridge void*)view;\r
750 \r
751                     ContextManager = new video::CEAGLManager();\r
752                     ContextManager->initialize(CreationParams, data);\r
753                                         \r
754                     VideoDriver = video::createOGLES1Driver(CreationParams, FileSystem, ContextManager);\r
755                     \r
756                     if (!VideoDriver)\r
757                         os::Printer::log("Could not create OpenGL ES 1.x driver.", ELL_ERROR);\r
758                 }\r
759 #else\r
760                 os::Printer::log("No OpenGL ES 1.x support compiled in.", ELL_ERROR);\r
761 #endif\r
762                 break;\r
763                                 \r
764                         case video::EDT_OGLES2:\r
765 #ifdef _IRR_COMPILE_WITH_OGLES2_\r
766                                 {\r
767                                         CIrrViewEAGLiOS* view = [[CIrrViewEAGLiOS alloc] initWithFrame:resolution forDevice:this];\r
768                                         CreationParams.WindowSize = core::dimension2d<u32>(view.frame.size.width, view.frame.size.height);\r
769                                 \r
770                                         dataStorage->View = view;\r
771                                         data.OpenGLiOS.View = (__bridge void*)view;\r
772                                 \r
773                                         ContextManager = new video::CEAGLManager();\r
774                                         ContextManager->initialize(CreationParams, data);\r
775                                 \r
776                                         VideoDriver = video::createOGLES2Driver(CreationParams, FileSystem, ContextManager);\r
777                                 \r
778                                         if (!VideoDriver)\r
779                                                 os::Printer::log("Could not create OpenGL ES 2.x driver.", ELL_ERROR);\r
780                                 }\r
781 #else\r
782                                 os::Printer::log("No OpenGL ES 2.x support compiled in.", ELL_ERROR);\r
783 #endif\r
784                                 break;\r
785                                 \r
786             case video::EDT_SOFTWARE:\r
787             case video::EDT_BURNINGSVIDEO:\r
788             case video::DEPRECATED_EDT_DIRECT3D8_NO_LONGER_EXISTS:\r
789             case video::EDT_DIRECT3D9:\r
790             case video::EDT_OPENGL:\r
791                 os::Printer::log("This driver is not available in iOS. Try OpenGL ES.", ELL_ERROR);\r
792                 break;\r
793                 \r
794             case video::EDT_NULL:\r
795                 VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize);\r
796                 break;\r
797                 \r
798             default:\r
799                 os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR);\r
800                 break;\r
801         }\r
802                 \r
803                 if (externalView == nil)\r
804                         dataStorage->ViewController.view = dataStorage->View;\r
805                 else\r
806                         [externalView addSubview:dataStorage->View];\r
807         }\r
808 }\r
809 \r
810 #ifdef _IRR_COMPILE_WITH_IOS_BUILTIN_MAIN_\r
811 int main(int argc, char** argv)\r
812 {\r
813     int result = UIApplicationMain(argc, argv, 0, NSStringFromClass([CIrrDelegateiOS class]));\r
814     \r
815     return result;\r
816 }\r
817 #endif\r
818 \r
819 #endif\r