T2DActivity.cpp 22 KB

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