T2DActivity.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platformAndroid/platformGL.h"
  23. #include "platformAndroid/AndroidWindow.h"
  24. #include "platformAndroid/platformAndroid.h"
  25. #include "graphics/dgl.h"
  26. #include <errno.h>
  27. #include <EGL/egl.h>
  28. //#include <android/sensor.h>
  29. #include <android/log.h>
  30. #include <android_native_app_glue.h>
  31. #include <android/asset_manager.h>
  32. /**
  33. * Our saved state data.
  34. */
  35. struct saved_state {
  36. float angle;
  37. int32_t x;
  38. int32_t y;
  39. };
  40. /**
  41. * Shared state for our app.
  42. */
  43. struct engine {
  44. struct android_app* app;
  45. int animating;
  46. EGLDisplay display;
  47. EGLSurface surface;
  48. EGLContext context;
  49. int32_t width;
  50. int32_t height;
  51. struct saved_state state;
  52. };
  53. static struct engine engine;
  54. extern AndroidPlatState platState;
  55. #define USE_DEPTH_BUFFER 0
  56. extern int _AndroidRunTorqueMain();
  57. extern bool createMouseMoveEvent(S32 i, S32 x, S32 y, S32 lastX, S32 lastY);
  58. extern bool createMouseDownEvent(S32 touchNumber, S32 x, S32 y, U32 numTouches);
  59. extern bool createMouseUpEvent(S32 touchNumber, S32 x, S32 y, S32 lastX, S32 lastY, U32 numTouches); //EFM
  60. extern void createMouseTapEvent( S32 nbrTaps, S32 x, S32 y );
  61. extern void _AndroidGameInnerLoop();
  62. extern void _AndroidGameResignActive();
  63. extern void _AndroidGameBecomeActive();
  64. extern void _AndroidGameWillTerminate();
  65. extern S32 _AndroidGameGetOrientation();
  66. // Store current orientation for easy access
  67. extern void _AndroidGameChangeOrientation(S32 newOrientation);
  68. //TODO: android
  69. /*
  70. UIDeviceOrientation currentOrientation;
  71. */
  72. bool _AndroidTorqueFatalError = false;
  73. //-Mat we should update the accelereometer once per frame
  74. extern U32 AccelerometerUpdateMS;
  75. extern void _AndroidGameInnerLoop();
  76. bool T2DActivity::createFramebuffer() {
  77. glGenFramebuffersOES(1, &viewFramebuffer);
  78. glGenRenderbuffersOES(1, &viewRenderbuffer);
  79. glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
  80. glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
  81. //TODO: android
  82. //[self.context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.view.layer];
  83. glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
  84. glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
  85. glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
  86. if (USE_DEPTH_BUFFER) {
  87. glGenRenderbuffersOES(1, &depthRenderbuffer);
  88. glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
  89. glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
  90. glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
  91. }
  92. if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
  93. //TODO: android
  94. //NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
  95. return false;
  96. }
  97. return true;
  98. }
  99. void T2DActivity::destroyFramebuffer() {
  100. glDeleteFramebuffersOES(1, &viewFramebuffer);
  101. viewFramebuffer = 0;
  102. glDeleteRenderbuffersOES(1, &viewRenderbuffer);
  103. viewRenderbuffer = 0;
  104. if(depthRenderbuffer) {
  105. glDeleteRenderbuffersOES(1, &depthRenderbuffer);
  106. depthRenderbuffer = 0;
  107. }
  108. }
  109. // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
  110. void T2DActivity::finishGLSetup()
  111. {
  112. //TODO: android
  113. //self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
  114. //if (!self.context) {
  115. // NSLog(@"Failed to create ES context");
  116. //}
  117. if( AccelerometerUpdateMS <= 0 ) {
  118. //Luma: This variable needs to be store MS value, not Seconds value
  119. AccelerometerUpdateMS = 33; // 33 ms
  120. }
  121. //[EAGLContext setCurrentContext:self.context];
  122. createFramebuffer();
  123. platState.multipleTouchesEnabled = true;
  124. //[self.view setMultipleTouchEnabled:YES];
  125. _AndroidTorqueFatalError = false;
  126. if(!_AndroidRunTorqueMain())
  127. {
  128. _AndroidTorqueFatalError = true;
  129. return;
  130. }
  131. }
  132. void T2DActivity::finishShutdown()
  133. {
  134. //TODO: android
  135. // Release any retained subviews of the main view.
  136. //if ([EAGLContext currentContext] == self.context) {
  137. // [EAGLContext setCurrentContext:nil];
  138. //}
  139. //self.context = nil;
  140. }
  141. void T2DActivity::update()
  142. {
  143. _AndroidGameInnerLoop();
  144. }
  145. Vector<Point2I> lastTouches;
  146. // Handle touch and keyboard input from android OS
  147. static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {
  148. struct engine* engine = (struct engine*)app->userData;
  149. if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) {
  150. if ((AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_DOWN) {
  151. size_t touchCount = AMotionEvent_getPointerCount(event);
  152. for (U8 i = 0; i < touchCount; i++)
  153. {
  154. Point2I point;
  155. point.x = AMotionEvent_getX(event, i);
  156. point.y = AMotionEvent_getY(event, i);
  157. if (lastTouches.size() < i)
  158. lastTouches.push_back(point);
  159. else
  160. {
  161. lastTouches[i].x = point.x;
  162. lastTouches[i].y = point.y;
  163. }
  164. S32 orientation = _AndroidGameGetOrientation();
  165. //TODO: android
  166. /* if (UIDeviceOrientationIsPortrait(orientation))
  167. {
  168. point.y -= _AndroidGetPortraitTouchoffset();
  169. }
  170. */
  171. createMouseDownEvent(i, point.x, point.y, touchCount);
  172. }
  173. }
  174. if ((AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_UP) {
  175. size_t touchCount = AMotionEvent_getPointerCount(event);
  176. for (U8 i = 0; i < touchCount; i++)
  177. {
  178. Point2I point;
  179. point.x = AMotionEvent_getX(event, i);
  180. point.y = AMotionEvent_getY(event, i);
  181. Point2I prevPoint = lastTouches[i];
  182. S32 orientation = _AndroidGameGetOrientation();
  183. //TODO: android
  184. /*if (UIDeviceOrientationIsPortrait(orientation))
  185. {
  186. point.y -= _AndroidGetPortraitTouchoffset();
  187. prevPoint.y -= _AndroidGetPortraitTouchoffset();
  188. }*/
  189. createMouseUpEvent(i, point.x, point.y, prevPoint.x, prevPoint.y, touchCount);
  190. //Luma: Tap support
  191. if (touchCount > 0)
  192. {
  193. // this was a tap, so create a tap event
  194. createMouseTapEvent(touchCount, (int) point.x, (int) point.y);
  195. }
  196. }
  197. }
  198. if ((AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_MOVE) {
  199. size_t touchCount = AMotionEvent_getPointerCount(event);
  200. for (U8 i = 0; i < touchCount; i++)
  201. {
  202. Point2I point;
  203. point.x = AMotionEvent_getX(event, i);
  204. point.y = AMotionEvent_getY(event, i);
  205. Point2I prevPoint = lastTouches[i];
  206. S32 orientation = _AndroidGameGetOrientation();
  207. //TODO: android
  208. /*
  209. if (UIDeviceOrientationIsPortrait(orientation))
  210. {
  211. point.y -= _AndroidGetPortraitTouchoffset();
  212. prevPoint.y -= _AndroidGetPortraitTouchoffset();
  213. }*/
  214. createMouseMoveEvent(i, point.x, point.y, prevPoint.x, prevPoint.y);
  215. lastTouches[i].x = point.x;
  216. lastTouches[i].y = point.y;
  217. }
  218. }
  219. if ((AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_CANCEL) {
  220. size_t touchCount = AMotionEvent_getPointerCount(event);
  221. for (U8 i = 0; i < touchCount; i++)
  222. {
  223. Point2I point;
  224. point.x = AMotionEvent_getX(event, i);
  225. point.y = AMotionEvent_getY(event, i);
  226. Point2I prevPoint = lastTouches[i];
  227. S32 orientation = _AndroidGameGetOrientation();
  228. //TODO: android
  229. /*
  230. if (UIDeviceOrientationIsPortrait(orientation))
  231. {
  232. point.y -= _AndroidGetPortraitTouchoffset();
  233. prevPoint.y -= _AndroidGetPortraitTouchoffset();
  234. }
  235. */
  236. createMouseUpEvent(i, point.x, point.y, prevPoint.x, prevPoint.y, touchCount);
  237. //Luma: Tap support
  238. if (touchCount > 0)
  239. {
  240. // this was a tap, so create a tap event
  241. createMouseTapEvent(touchCount, (int) point.x, (int) point.y);
  242. }
  243. }
  244. }
  245. return 1;
  246. } else if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) {
  247. int action = AKeyEvent_getAction(event);
  248. int key_val = AKeyEvent_getKeyCode(event);
  249. int metastate = AKeyEvent_getMetaState(event);
  250. switch(action)
  251. {
  252. case AKEY_EVENT_ACTION_DOWN:
  253. if (key_val == AKEYCODE_VOLUME_UP) {
  254. //TODO: android
  255. //ChangeVolume(true);
  256. } else if (key_val == AKEYCODE_VOLUME_DOWN) {
  257. //TODO: android
  258. //ChangeVolume(false);
  259. } else if (key_val == AKEYCODE_BACK) {
  260. //android back button
  261. } else {
  262. //TODO: android
  263. //convertAndroidToWindowsKeyCode(key_val);
  264. }
  265. break;
  266. case AKEY_EVENT_ACTION_UP:
  267. if (key_val == AKEYCODE_VOLUME_UP) {
  268. //TODO: android
  269. //ChangeVolume(true);
  270. } else if (key_val == AKEYCODE_VOLUME_DOWN) {
  271. //TODO: android
  272. //ChangeVolume(false);
  273. } else if (key_val == AKEYCODE_BACK) {
  274. //android back button
  275. } else {
  276. //TODO: android
  277. //convertAndroidToWindowsKeyCode(key_val);
  278. }
  279. break;
  280. }
  281. return 1;
  282. }
  283. return 0;
  284. }
  285. int _AndroidGetScreenWidth() {
  286. return engine.width;
  287. }
  288. int _AndroidGetScreenHeight() {
  289. return engine.height;
  290. }
  291. bool _AndroidGetFileDescriptor(const char* fileName, int32_t *mDescriptor, off_t *mStart, off_t* mLength) {
  292. AAsset* asset = AAssetManager_open(engine.app->activity->assetManager, fileName, AASSET_MODE_UNKNOWN);
  293. if (asset != NULL) {
  294. *mDescriptor = AAsset_openFileDescriptor(asset, mStart, mLength);
  295. AAsset_close(asset);
  296. return true;
  297. }
  298. *mDescriptor = 0;
  299. *mStart = 0;
  300. *mLength = 0;
  301. return false;
  302. }
  303. char* _AndroidLoadFile(const char* fileName, int *size) {
  304. AAsset *asset;
  305. uint8_t buf[1024];
  306. char* buffer = NULL;
  307. *size = 0;
  308. asset = AAssetManager_open(engine.app->activity->assetManager, fileName, AASSET_MODE_UNKNOWN);
  309. if(asset != NULL){
  310. *size = AAsset_getLength(asset);
  311. if (*size <= 0)
  312. return NULL;
  313. buffer = new char[*size + 1];
  314. int count = 0;
  315. while(true)
  316. {
  317. int read = AAsset_read(asset, buf, 1024);
  318. if (read <= 0)
  319. break;
  320. memcpy(buffer+count,buf, read);
  321. count += read;
  322. }
  323. buffer[*size] = '\0';
  324. AAsset_close(asset);
  325. }
  326. return buffer;
  327. }
  328. void _AndroidGetDeviceIPAddress(char* address) {
  329. int fd;
  330. strcpy(address, "error");
  331. // Attaches the current thread to the JVM.
  332. jint lResult;
  333. jint lFlags = 0;
  334. JavaVM* lJavaVM = engine.app->activity->vm;
  335. JNIEnv* lJNIEnv = engine.app->activity->env;
  336. JavaVMAttachArgs lJavaVMAttachArgs;
  337. lJavaVMAttachArgs.version = JNI_VERSION_1_6;
  338. lJavaVMAttachArgs.name = "NativeThread";
  339. lJavaVMAttachArgs.group = NULL;
  340. lResult=lJavaVM->AttachCurrentThread(&lJNIEnv, &lJavaVMAttachArgs);
  341. if (lResult == JNI_ERR) {
  342. return;
  343. }
  344. // Retrieves NativeActivity.
  345. jobject lNativeActivity = engine.app->activity->clazz;
  346. jclass ClassNativeActivity = lJNIEnv->GetObjectClass(lNativeActivity);
  347. // Retrieves Context.INPUT_METHOD_SERVICE.
  348. jclass ClassContext = lJNIEnv->FindClass("android/content/Context");
  349. jfieldID FieldWIFI_SERVICE =
  350. lJNIEnv->GetStaticFieldID(ClassContext,
  351. "WIFI_SERVICE", "Ljava/lang/String;");
  352. jobject WIFI_SERVICE =
  353. lJNIEnv->GetStaticObjectField(ClassContext,
  354. FieldWIFI_SERVICE);
  355. // Runs getSystemService(Context.WIFI_SERVICE).
  356. jclass ClassWifiManager = lJNIEnv->FindClass(
  357. "android/net/wifi/WifiManager");
  358. jclass ClassWifiInfo = lJNIEnv->FindClass(
  359. "android/net/wifi/WifiInfo");
  360. jmethodID MethodGetSystemService = lJNIEnv->GetMethodID(
  361. ClassNativeActivity, "getSystemService",
  362. "(Ljava/lang/String;)Ljava/lang/Object;");
  363. jobject lWifiManager = lJNIEnv->CallObjectMethod(
  364. lNativeActivity, MethodGetSystemService,
  365. WIFI_SERVICE);
  366. // Runs wifiManager.getConnectionInfo()
  367. jmethodID MethodGetConnectionInfo = lJNIEnv->GetMethodID(
  368. ClassWifiManager, "getConnectionInfo",
  369. "()Landroid/net/wifi/WifiInfo;");
  370. jobject lWifiInfo = lJNIEnv->CallObjectMethod(
  371. lWifiManager, MethodGetConnectionInfo);
  372. // Runs wifiInfo.getIpAddress()
  373. jmethodID MethodGetIPAddress = lJNIEnv->GetMethodID(
  374. ClassWifiInfo, "getIpAddress",
  375. "()I");
  376. jint lIPAddress = lJNIEnv->CallIntMethod(
  377. lWifiInfo, MethodGetIPAddress);
  378. int ip = lIPAddress;
  379. // Finished with the JVM.
  380. lJavaVM->DetachCurrentThread();
  381. char buffer[32];
  382. sprintf(buffer, "%d.%d.%d.%d", (ip & 0xFF), (ip >> 8 & 0xFF), (ip >> 16 & 0xFF), (ip >> 24 & 0xFF));
  383. strcpy(address, buffer);
  384. }
  385. /**
  386. * Initialize an EGL context for the current display.
  387. */
  388. static int engine_init_display(struct engine* engine) {
  389. // initialize OpenGL ES and EGL
  390. /*
  391. * Here specify the attributes of the desired configuration.
  392. * Below, we select an EGLConfig with at least 8 bits per color
  393. * component compatible with on-screen windows
  394. */
  395. const EGLint attribs[] = {
  396. EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
  397. EGL_BLUE_SIZE, 8,
  398. EGL_GREEN_SIZE, 8,
  399. EGL_RED_SIZE, 8,
  400. //EGL_ALPHA_SIZE, 8,
  401. //EGL_DEPTH_SIZE, 24,
  402. EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
  403. EGL_NONE
  404. };
  405. static const EGLint ctx_attribs[] = {
  406. EGL_CONTEXT_CLIENT_VERSION, 2,
  407. EGL_NONE
  408. };
  409. EGLint w, h, dummy, format;
  410. EGLint numConfigs;
  411. EGLConfig config;
  412. EGLSurface surface;
  413. EGLContext context;
  414. EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  415. eglInitialize(display, 0, 0);
  416. /* Here, the application chooses the configuration it desires. In this
  417. * sample, we have a very simplified selection process, where we pick
  418. * the first EGLConfig that matches our criteria */
  419. eglChooseConfig(display, attribs, &config, 1, &numConfigs);
  420. /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
  421. * guaranteed to be accepted by ANativeWindow_setBuffersGeometry().
  422. * As soon as we picked a EGLConfig, we can safely reconfigure the
  423. * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
  424. eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
  425. ANativeWindow_setBuffersGeometry(engine->app->window, 0, 0, format);
  426. surface = eglCreateWindowSurface(display, config, engine->app->window, NULL);
  427. context = eglCreateContext(display, config, EGL_NO_CONTEXT, ctx_attribs);
  428. if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {
  429. adprintf("Unable to eglMakeCurrent");
  430. return -1;
  431. }
  432. eglQuerySurface(display, surface, EGL_WIDTH, &w);
  433. eglQuerySurface(display, surface, EGL_HEIGHT, &h);
  434. engine->display = display;
  435. engine->context = context;
  436. engine->surface = surface;
  437. engine->width = w;
  438. engine->height = h;
  439. engine->state.angle = 0;
  440. glDisable(GL_DEPTH_TEST);
  441. glDisable(GL_CULL_FACE);
  442. engine->animating = 1;
  443. glViewport(0, 0, engine->width, engine->height);
  444. if (SetupCompleted == false)
  445. {
  446. //TODO: android
  447. }
  448. else
  449. {
  450. if(!_AndroidTorqueFatalError)
  451. _AndroidGameBecomeActive();
  452. }
  453. return 0;
  454. }
  455. /**
  456. * update callback
  457. */
  458. static void engine_update_frame(struct engine* engine) {
  459. if (bSuspended == true)
  460. return;
  461. double thisSysTime = timeGetTime();
  462. float timeElapsed = (thisSysTime-lastSystemTime)/1000.0f;
  463. if (timeElapsed > 1.0f)
  464. timeElapsed = 1.0f; // clamp it
  465. if (SetupCompleted == false) {
  466. if (timeElapsed > 0.25f) {
  467. PandaSetup();
  468. PandaRegainedDevice();
  469. backBufferFBO[0].Setup(engine_screenWidth(),engine_screenHeight());
  470. loadDeviceType();
  471. SetupCompleted = true;
  472. lastSystemTime = timeGetTime();
  473. }
  474. } else {
  475. lastSystemTime = thisSysTime;
  476. if (isDeviceiPhone()) {
  477. if (currentActiveBufferPerc < 1.0f) {
  478. if (currentBufferInTransition == false) {
  479. currentActiveBufferPerc += timeElapsed * 2.0f;
  480. if (currentActiveBufferPerc > 1.0f)
  481. currentActiveBufferPerc = 1.0f;
  482. }
  483. }
  484. }
  485. if (keyboardShowing) {
  486. if (keyboardTransition > 0.0f) {
  487. keyboardTransition -= timeElapsed * 2.0f;
  488. if (keyboardTransition < 0.0f)
  489. keyboardTransition = 0.0f;
  490. }
  491. } else {
  492. if (keyboardTransition < 1.0f) {
  493. keyboardTransition += timeElapsed * 2.0f;
  494. if (keyboardTransition > 1.0f)
  495. keyboardTransition = 1.0f;
  496. }
  497. }
  498. _AndroidGameInnerLoop();
  499. }
  500. }
  501. /**
  502. * Just the current frame in the display.
  503. */
  504. static void engine_draw_frame(struct engine* engine) {
  505. if (engine->display == NULL) {
  506. // No display.
  507. return;
  508. }
  509. if (bSuspended == true)
  510. return;
  511. if (SetupCompleted == false) {
  512. return;
  513. }
  514. if (keyboardShowing == true) {
  515. glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  516. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  517. }
  518. //backBufferFBO[currentActiveBuffer].AcceptRender(true);
  519. glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  520. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  521. //TODO: android
  522. //PandaDraw();
  523. //glBindFramebuffer(GL_FRAMEBUFFER, 0);
  524. //int height = engine_screenHeight() - (keyboardTransition * (engine_screenHeight()/2));
  525. //draw tp screen
  526. /*if (isDeviceiPhone()) {
  527. float scale = 1.0f;
  528. //shrink it to fit screen if we have blown it up
  529. //if (engine->height > 0 && engine->width == 1024 && engine->height < 768) {
  530. // scale = 1.0f / ARTIF_SCALE;
  531. //}
  532. if (currentActiveBufferPerc < 1.0f)
  533. backBufferFBO[otherBuffer].bitmap->DrawBuffer((engine_screenWidth()/2 - ((engine_screenWidth()*currentActiveBufferPerc) * currentBufferDirection)) * scale,height * scale, scale);
  534. backBufferFBO[currentActiveBuffer].bitmap->DrawBuffer((engine_screenWidth()/2 + ((engine_screenWidth()-(engine_screenWidth()*currentActiveBufferPerc)) * currentBufferDirection)) * scale,height * scale, scale);
  535. } else {
  536. float scale = 1.0f;
  537. float width = engine_screenWidth()/2;
  538. //shrink it to fit screen if we have blown it up
  539. //if (engine->height > 0 && engine->width == 1024 && engine->height < 768) {
  540. // scale = 1.0f / ARTIF_SCALE;
  541. //}
  542. backBufferFBO[currentActiveBuffer].bitmap->DrawBuffer(width*scale,height*scale, scale);
  543. }
  544. */
  545. eglSwapBuffers(engine->display, engine->surface);
  546. }
  547. /**
  548. * Tear down the EGL context currently associated with the display.
  549. */
  550. static void engine_term_display(struct engine* engine, bool shutdown) {
  551. if (shutdown == true) {
  552. _AndroidGameWillTerminate();
  553. } else {
  554. _AndroidGameResignActive();
  555. }
  556. if (engine->display != EGL_NO_DISPLAY) {
  557. eglMakeCurrent(engine->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
  558. if (engine->context != EGL_NO_CONTEXT) {
  559. eglDestroyContext(engine->display, engine->context);
  560. }
  561. if (engine->surface != EGL_NO_SURFACE) {
  562. eglDestroySurface(engine->display, engine->surface);
  563. }
  564. eglTerminate(engine->display);
  565. }
  566. engine->animating = 0;
  567. engine->display = EGL_NO_DISPLAY;
  568. engine->context = EGL_NO_CONTEXT;
  569. engine->surface = EGL_NO_SURFACE;
  570. }
  571. //TODO: android rotate
  572. /*- (void)didRotate:(NSNotification *)notification
  573. {
  574. //Default to landscape left
  575. UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
  576. if(currentOrientation != orientation)
  577. {
  578. //Change the orientation
  579. currentOrientation = orientation;
  580. //Tell the rest of the engine
  581. _AndroidGameChangeOrientation(currentOrientation);
  582. }
  583. }*/
  584. void supportLandscape( bool enable)
  585. {
  586. //TODO: android
  587. //platState.viewController->mOrientationLandscapeLeftSupported = enable;
  588. //platState.viewController->mOrientationLandscapeRightSupported = enable;
  589. }
  590. ConsoleFunction(supportLandscape, void, 2, 2, "supportLandscape( bool ) "
  591. "enable or disable Landscape")
  592. {
  593. bool enable = true;
  594. if( argc > 1 )
  595. enable = dAtob( argv[1] );
  596. supportLandscape(enable);
  597. }
  598. void supportPortrait( bool enable )
  599. {
  600. //TODO: android
  601. //platState.viewController->mOrientationPortraitSupported = enable;
  602. //platState.viewController->mOrientationPortraitUpsideDownSupported = enable;
  603. }
  604. ConsoleFunction(supportPortrait, void, 2, 2, "supportPortrait( bool ) "
  605. "enable or disable portrait")
  606. {
  607. bool enable = true;
  608. if( argc > 1 )
  609. enable = dAtob( argv[1] );
  610. supportPortrait(enable);
  611. }