示例#1
0
static void frontend_android_init(void *data)
{
   JNIEnv *env;
   ALooper *looper;
   jclass class = NULL;
   jobject obj = NULL;
   struct android_app* android_app = (struct android_app*)data;

   if (!android_app)
      return;

   looper = (ALooper*)ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
   ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL, NULL);
   android_app->looper = looper;

   slock_lock(android_app->mutex);
   android_app->running = 1;
   scond_broadcast(android_app->cond);
   slock_unlock(android_app->mutex);

   memset(&g_android, 0, sizeof(g_android));
   g_android = (struct android_app*)android_app;

   RARCH_LOG("Waiting for Android Native Window to be initialized ...\n");

   while (!android_app->window)
   {
      if (!android_run_events(android_app))
      {
         frontend_android_deinit(android_app);
         frontend_android_shutdown(android_app);
         return;
      }
   }

   RARCH_LOG("Android Native Window initialized.\n");

   env = jni_thread_getenv();
   if (!env)
      return;

   GET_OBJECT_CLASS(env, class, android_app->activity->clazz);
   GET_METHOD_ID(env, android_app->getIntent, class, "getIntent", "()Landroid/content/Intent;");
   CALL_OBJ_METHOD(env, obj, android_app->activity->clazz, android_app->getIntent);
#if 0
   GET_METHOD_ID(env, android_app->hasPendingIntent, class, "hasPendingIntent", "()Z");
   GET_METHOD_ID(env, android_app->clearPendingIntent, class, "clearPendingIntent", "()V");
   GET_METHOD_ID(env, android_app->getPendingIntentConfigPath, class, "getPendingIntentConfigPath",
         "()Ljava/lang/String;");
   GET_METHOD_ID(env, android_app->getPendingIntentLibretroPath, class, "getPendingIntentLibretroPath",
         "()Ljava/lang/String;");
   GET_METHOD_ID(env, android_app->getPendingIntentFullPath, class, "getPendingIntentFullPath",
         "()Ljava/lang/String;");
   GET_METHOD_ID(env, android_app->getPendingIntentIME, class, "getPendingIntentIME",
         "()Ljava/lang/String;");
#endif

   GET_OBJECT_CLASS(env, class, obj);
   GET_METHOD_ID(env, android_app->getStringExtra, class, "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
}
示例#2
0
static int frontend_android_process_events(void *data)
{
#if 0
   jboolean hasPendingIntent;
   JNIEnv *env;
#endif
   struct android_app* android_app = (struct android_app*)data;

   if (g_extern.is_paused)
         android_run_events(android_app);

#if 0
   env = jni_thread_getenv();
   if (!env)
      return -1;

   CALL_BOOLEAN_METHOD(env, hasPendingIntent, android_app->activity->clazz,
         android_app->hasPendingIntent);

   if (hasPendingIntent)
      process_pending_intent(android_app);
#endif

   return 0;
}
static void *android_app_entry(void *data)
{
   struct android_app* android_app = (struct android_app*)data;

   android_app->config = AConfiguration_new();
   AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager);

   print_cur_config(android_app);

   ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
   ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL, NULL);
   android_app->looper = looper;

   pthread_mutex_lock(&android_app->mutex);
   android_app->running = 1;
   pthread_cond_broadcast(&android_app->cond);
   pthread_mutex_unlock(&android_app->mutex);

   memset(&g_android, 0, sizeof(g_android));
   g_android = android_app;

   RARCH_LOG("Native Activity started.\n");
   rarch_main_clear_state();

   while (!android_app->window)
   {
      if (!android_run_events(android_app))
         goto exit;
   }

   rarch_init_msg_queue();

   if (!android_app_start_main(android_app))
   {
      g_settings.input.overlay[0] = 0;
      // threaded video doesn't work right for just displaying one frame
      g_settings.video.threaded = false;
      init_drivers();
      driver.video_poke->set_aspect_ratio(driver.video_data, ASPECT_RATIO_SQUARE);
      rarch_render_cached_frame();
      sleep(2);
      goto exit;
   }

   if (!g_extern.libretro_dummy)
      menu_rom_history_push_current();

   for (;;)
   {
      if (g_extern.system.shutdown)
         break;
      else if (g_extern.lifecycle_mode_state & (1ULL << MODE_LOAD_GAME))
      {
         load_menu_game_prepare();

         // If ROM load fails, we exit RetroArch. On console it might make more sense to go back to menu though ...
         if (load_menu_game())
            g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME);
         else
         {
#ifdef RARCH_CONSOLE
            g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU);
#else
            return NULL;
#endif
         }

         g_extern.lifecycle_mode_state &= ~(1ULL << MODE_LOAD_GAME);
      }
      else if (g_extern.lifecycle_mode_state & (1ULL << MODE_GAME))
      {
         driver.input->poll(NULL);

         if (driver.video_poke->set_aspect_ratio)
            driver.video_poke->set_aspect_ratio(driver.video_data, g_settings.video.aspect_ratio_idx);

         if (g_extern.lifecycle_mode_state & (1ULL << MODE_VIDEO_THROTTLE_ENABLE))
            audio_start_func();

         // Main loop
         while (rarch_main_iterate());

         if (g_extern.lifecycle_mode_state & (1ULL << MODE_VIDEO_THROTTLE_ENABLE))
            audio_stop_func();
         g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME);
      }
      else if(g_extern.lifecycle_mode_state & (1ULL << MODE_MENU))
      {
         g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU_PREINIT);
         while((input_key_pressed_func(RARCH_PAUSE_TOGGLE)) ?
               android_run_events(android_app) : menu_iterate());

         g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU);
      }
      else
         break;
   }

exit:
   android_app->activityState = APP_CMD_DEAD;
   RARCH_LOG("Deinitializing RetroArch...\n");

   menu_free();

   if (g_extern.config_save_on_exit && *g_extern.config_path)
      config_save_file(g_extern.config_path);

   if (g_extern.main_is_init)
      rarch_main_deinit();

   rarch_deinit_msg_queue();
#ifdef PERF_TEST
   rarch_perf_log();
#endif
   rarch_main_clear_state();

   RARCH_LOG("android_app_destroy!");
   if (android_app->inputQueue != NULL)
      AInputQueue_detachLooper(android_app->inputQueue);
   AConfiguration_delete(android_app->config);

   // exit() here is nasty.
   // pthread_exit(NULL) or return NULL; causes hanging ...
   // Should probably called ANativeActivity_finsih(), but it's bugged, it will hang our app.
   exit(0);
}