mirror of
https://github.com/libretro/RetroArch.git
synced 2025-02-01 22:42:22 +00:00
(Android) Big changes -
- both MainMenuActivity and RetroActivity are single instances now - AKEYCODE_BACK gets eaten and onBackPressed in Java is triggered - onBackPressed right now calls an instance of MainMenuActivity (reuses the existing activity on the stack) - User can switch back and forth between RetroActivity and MainMenuActivity with AKEYCODE_BACK / Back button - When a subsequent intent is launched after RetroActivity has already been started up once, the pending intent gets passed to the existing RetroActivity throug onNewIntent - in C land it will look every frame if an intent is pending - if it is, it will look up certain variables through JNI to launch a new game - or whatever it is that the intent wants to do - With this we can now switch seamlessly between Android UI and RetroArch itself.
This commit is contained in:
parent
1d06b07a16
commit
6c638f91f4
@ -1692,7 +1692,13 @@ static void android_input_poll(void *data)
|
||||
|
||||
if (keycode == AKEYCODE_BACK)
|
||||
{
|
||||
if (android->onBackPressed)
|
||||
uint8_t unpacked = (android->keycode_lut[AKEYCODE_BACK] >> ((state_id+1) << 3)) - 1;
|
||||
uint64_t input_state = (1ULL << unpacked);
|
||||
if (type_event == AINPUT_EVENT_TYPE_KEY && input_state < (1ULL << RARCH_FIRST_META_KEY)
|
||||
&& input_state > 0)
|
||||
{
|
||||
}
|
||||
else if (android->onBackPressed)
|
||||
{
|
||||
RARCH_LOG("Invoke onBackPressed through JNI.\n");
|
||||
JNIEnv *env = jni_thread_getenv();
|
||||
@ -1701,43 +1707,6 @@ static void android_input_poll(void *data)
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz, android->onBackPressed);
|
||||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
uint8_t unpacked = (android->keycode_lut[AKEYCODE_BACK] >> ((state_id+1) << 3)) - 1;
|
||||
uint64_t input_state = (1ULL << unpacked);
|
||||
// FIXME: all of the below will probably all have to be refactored
|
||||
if (g_extern.lifecycle_state & (1ULL << MODE_INPUT_XPERIA_PLAY_HACK))
|
||||
{
|
||||
int meta = AKeyEvent_getMetaState(event);
|
||||
if (!(meta & AMETA_ALT_ON))
|
||||
{
|
||||
*lifecycle_state |= (1ULL << RARCH_QUIT_KEY);
|
||||
AInputQueue_finishEvent(android_app->inputQueue, event, handled);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (type_event == AINPUT_EVENT_TYPE_KEY && input_state < (1ULL << RARCH_FIRST_META_KEY)
|
||||
&& input_state > 0)
|
||||
{
|
||||
}
|
||||
else if (g_settings.input.back_behavior == BACK_BUTTON_MENU_TOGGLE)
|
||||
{
|
||||
int action = AKeyEvent_getAction(event);
|
||||
if (action == AKEY_EVENT_ACTION_DOWN)
|
||||
*lifecycle_state |= (1ULL << RARCH_MENU_TOGGLE);
|
||||
else if (action == AKEY_EVENT_ACTION_UP)
|
||||
*lifecycle_state &= ~(1ULL << RARCH_MENU_TOGGLE);
|
||||
AInputQueue_finishEvent(android_app->inputQueue, event, handled);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// exits the app, so no need to check for up/down action
|
||||
*lifecycle_state |= (1ULL << RARCH_QUIT_KEY);
|
||||
AInputQueue_finishEvent(android_app->inputQueue, event, handled);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (type_event == AINPUT_EVENT_TYPE_MOTION)
|
||||
|
@ -17,7 +17,7 @@
|
||||
android:label="@string/app_name"
|
||||
android:hasCode="true">
|
||||
<activity android:name="com.retroarch.browser.DisplayRefreshRateTest"/>
|
||||
<activity android:name="com.retroarch.browser.mainmenu.MainMenuActivity" android:exported="true">
|
||||
<activity android:name="com.retroarch.browser.mainmenu.MainMenuActivity" android:exported="true" android:launchMode="singleInstance">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
@ -30,7 +30,7 @@
|
||||
<activity android:name="com.retroarch.browser.preferences.PreferenceActivity" android:theme="@style/Theme.AppCompat" />
|
||||
<activity android:name="com.retroarch.browser.coremanager.CoreManagerActivity" android:theme="@style/Theme.AppCompat"/>
|
||||
|
||||
<activity android:name="com.retroarch.browser.RetroActivity" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
|
||||
<activity android:name="com.retroarch.browser.RetroActivity" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:launchMode="singleInstance">
|
||||
<meta-data android:name="android.app.lib_name" android:value="retroarch-activity" />
|
||||
<meta-data android:name="android.app.func_name" android:value="ANativeActivity_onCreate" />
|
||||
</activity>
|
||||
|
@ -13,13 +13,14 @@
|
||||
|
||||
<!-- Main Menu Strings -->
|
||||
<string name="mainmenu_title">RetroArch - Main Menu</string>
|
||||
<string name="tv_mode">TV Mode</string>
|
||||
<string name="tv_mode">Resume Game</string>
|
||||
<string name="load_core">Load Core</string>
|
||||
<string name="load_game">Load Game</string>
|
||||
<string name="load_game_history">Load Game (History)</string>
|
||||
<string name="settings">Settings</string>
|
||||
<string name="help">Help</string>
|
||||
<string name="about">About</string>
|
||||
<string name="quit">Quit RetroArch</string>
|
||||
|
||||
<!-- Core Selection Class -->
|
||||
<string name="select_libretro_core">Select a libretro core</string>
|
||||
|
@ -62,4 +62,9 @@
|
||||
</Preference>
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
|
||||
<!-- Quit RetroArch -->
|
||||
<Preference
|
||||
android:key="quitRetroArch"
|
||||
android:title="@string/quit"/>
|
||||
</PreferenceScreen>
|
||||
|
@ -106,7 +106,6 @@ public final class HistorySelection extends DialogFragment
|
||||
retro.putExtra("LIBRETRO", corePath);
|
||||
retro.putExtra("CONFIGFILE", UserPreferences.getDefaultConfigPath(ctx));
|
||||
retro.putExtra("IME", current_ime);
|
||||
retro.putExtra("USED", "false");
|
||||
startActivity(retro);
|
||||
dismiss();
|
||||
}
|
||||
|
@ -2,10 +2,12 @@ package com.retroarch.browser;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.retroarch.browser.mainmenu.MainMenuActivity;
|
||||
import com.retroarch.browser.preferences.util.UserPreferences;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.NativeActivity;
|
||||
import android.content.Intent;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.hardware.Camera;
|
||||
import android.os.Build;
|
||||
@ -17,6 +19,7 @@ public final class RetroActivity extends NativeActivity
|
||||
private long lastTimestamp = 0;
|
||||
private SurfaceTexture texture;
|
||||
private Boolean updateSurface = true;
|
||||
private Intent pendingIntent = null;
|
||||
|
||||
public void onCameraStart()
|
||||
{
|
||||
@ -114,9 +117,53 @@ public final class RetroActivity extends NativeActivity
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewIntent(Intent intent)
|
||||
{
|
||||
Log.i("RetroActivity", "onNewIntent invoked.");
|
||||
super.onNewIntent(intent);
|
||||
setIntent(intent);
|
||||
pendingIntent = intent;
|
||||
}
|
||||
|
||||
public String getPendingIntentFullPath()
|
||||
{
|
||||
return pendingIntent.getStringExtra("ROM");
|
||||
}
|
||||
|
||||
public String getPendingIntentLibretroPath()
|
||||
{
|
||||
return pendingIntent.getStringExtra("LIBRETRO");
|
||||
}
|
||||
|
||||
public String getPendingIntentConfigPath()
|
||||
{
|
||||
return pendingIntent.getStringExtra("CONFIGFILE");
|
||||
}
|
||||
|
||||
public String getPendingIntentIME()
|
||||
{
|
||||
return pendingIntent.getStringExtra("IME");
|
||||
}
|
||||
|
||||
public boolean hasPendingIntent()
|
||||
{
|
||||
if (pendingIntent == null)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void clearPendingIntent()
|
||||
{
|
||||
pendingIntent = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed()
|
||||
{
|
||||
Log.i("RetroActivity", "onBackKeyPressed");
|
||||
Intent retro = new Intent(this, MainMenuActivity.class);
|
||||
retro.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||
startActivity(retro);
|
||||
}
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ public final class MainMenuFragment extends PreferenceListFragment implements On
|
||||
findPreference("loadCorePref").setOnPreferenceClickListener(this);
|
||||
findPreference("loadRomPref").setOnPreferenceClickListener(this);
|
||||
findPreference("loadRomHistoryPref").setOnPreferenceClickListener(this);
|
||||
findPreference("quitRetroArch").setOnPreferenceClickListener(this);
|
||||
|
||||
// Extract assets.
|
||||
extractAssets();
|
||||
@ -341,7 +342,6 @@ public final class MainMenuFragment extends PreferenceListFragment implements On
|
||||
retro.putExtra("LIBRETRO", libretro_path);
|
||||
retro.putExtra("CONFIGFILE", UserPreferences.getDefaultConfigPath(ctx));
|
||||
retro.putExtra("IME", current_ime);
|
||||
retro.putExtra("USED", "false");
|
||||
startActivity(retro);
|
||||
}
|
||||
// Load Core Preference
|
||||
@ -350,6 +350,12 @@ public final class MainMenuFragment extends PreferenceListFragment implements On
|
||||
final CoreSelection coreSelection = new CoreSelection();
|
||||
coreSelection.show(getFragmentManager(), "core_selection");
|
||||
}
|
||||
// Quit RetroArch preference
|
||||
else if (prefKey.equals("quitRetroArch"))
|
||||
{
|
||||
// TODO - needs to close entire app gracefully - including
|
||||
// NativeActivity if possible
|
||||
}
|
||||
// Load ROM Preference
|
||||
else if (prefKey.equals("loadRomPref"))
|
||||
{
|
||||
@ -397,7 +403,6 @@ public final class MainMenuFragment extends PreferenceListFragment implements On
|
||||
retro.putExtra("LIBRETRO", libretro_path);
|
||||
retro.putExtra("CONFIGFILE", UserPreferences.getDefaultConfigPath(ctx));
|
||||
retro.putExtra("IME", current_ime);
|
||||
retro.putExtra("USED", "false");
|
||||
startActivity(retro);
|
||||
}
|
||||
}
|
||||
|
@ -976,6 +976,20 @@ static void menu_flush_stack_type(void *data, unsigned final_type)
|
||||
}
|
||||
}
|
||||
|
||||
void load_menu_game_new_core(void)
|
||||
{
|
||||
#ifdef HAVE_DYNAMIC
|
||||
libretro_free_system_info(&rgui->info);
|
||||
libretro_get_system_info(g_settings.libretro, &rgui->info,
|
||||
&rgui->load_no_rom);
|
||||
|
||||
g_extern.lifecycle_state |= (1ULL << MODE_LOAD_GAME);
|
||||
#else
|
||||
rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, (void*)g_settings.libretro);
|
||||
rarch_environment_cb(RETRO_ENVIRONMENT_EXEC, (void*)g_extern.fullpath);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int menu_iterate_func(void *data, unsigned action)
|
||||
{
|
||||
rgui_handle_t *rgui = (rgui_handle_t*)data;
|
||||
@ -1118,16 +1132,7 @@ static int menu_iterate_func(void *data, unsigned action)
|
||||
// FIXME: Add for consoles.
|
||||
strlcpy(g_settings.libretro, path, sizeof(g_settings.libretro));
|
||||
strlcpy(g_extern.fullpath, rgui->deferred_path, sizeof(g_extern.fullpath));
|
||||
#ifdef HAVE_DYNAMIC
|
||||
libretro_free_system_info(&rgui->info);
|
||||
libretro_get_system_info(g_settings.libretro, &rgui->info,
|
||||
&rgui->load_no_rom);
|
||||
|
||||
g_extern.lifecycle_state |= (1ULL << MODE_LOAD_GAME);
|
||||
#else
|
||||
rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, (void*)g_settings.libretro);
|
||||
rarch_environment_cb(RETRO_ENVIRONMENT_EXEC, (void*)g_extern.fullpath);
|
||||
#endif
|
||||
load_menu_game_new_core();
|
||||
rgui->msg_force = true;
|
||||
ret = -1;
|
||||
menu_flush_stack_type(rgui, RGUI_SETTINGS);
|
||||
|
@ -355,6 +355,7 @@ void menu_init_core_info(void *data);
|
||||
void load_menu_game_prepare(void);
|
||||
bool load_menu_game(void);
|
||||
void load_menu_game_history(unsigned game_index);
|
||||
extern void load_menu_game_new_core(void);
|
||||
void menu_rom_history_push(const char *path, const char *core_path,
|
||||
const char *core_name);
|
||||
void menu_rom_history_push_current(void);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "platform_android.h"
|
||||
#include "../menu/menu_common.h"
|
||||
#include "../../android/native/jni/jni_macros.h"
|
||||
|
||||
#include "../../conf/config_file.h"
|
||||
@ -460,13 +461,110 @@ static void get_environment_settings(int argc, char *argv[], void *data)
|
||||
|
||||
}
|
||||
|
||||
static void process_pending_intent(void *data)
|
||||
{
|
||||
RARCH_LOG("process_pending_intent.\n");
|
||||
JNIEnv *env;
|
||||
struct android_app* android_app = (struct android_app*)data;
|
||||
jstring jstr = NULL;
|
||||
bool valschanged = false;
|
||||
bool startgame = false;
|
||||
|
||||
if (!android_app)
|
||||
return;
|
||||
|
||||
env = jni_thread_getenv();
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
// ROM
|
||||
jstr = (*env)->CallObjectMethod(env, android_app->activity->clazz, android_app->getPendingIntentFullPath);
|
||||
JNI_EXCEPTION(env);
|
||||
RARCH_LOG("Checking arguments passed from intent...\n");
|
||||
if (android_app->getPendingIntentFullPath && jstr)
|
||||
{
|
||||
const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
|
||||
strlcpy(g_extern.fullpath, argv, sizeof(g_extern.fullpath));
|
||||
(*env)->ReleaseStringUTFChars(env, jstr, argv);
|
||||
|
||||
valschanged = true;
|
||||
startgame = true;
|
||||
RARCH_LOG("ROM Filename: [%s].\n", g_extern.fullpath);
|
||||
}
|
||||
|
||||
// Config file
|
||||
jstr = (*env)->CallObjectMethod(env, android_app->activity->clazz, android_app->getPendingIntentConfigPath);
|
||||
JNI_EXCEPTION(env);
|
||||
if (android_app->getPendingIntentConfigPath && jstr)
|
||||
{
|
||||
const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
|
||||
strlcpy(g_extern.config_path, argv, sizeof(g_extern.config_path));
|
||||
(*env)->ReleaseStringUTFChars(env, jstr, argv);
|
||||
|
||||
valschanged = true;
|
||||
RARCH_LOG("Config file: [%s].\n", g_extern.config_path);
|
||||
}
|
||||
|
||||
// Current IME
|
||||
jstr = (*env)->CallObjectMethod(env, android_app->activity->clazz, android_app->getPendingIntentIME);
|
||||
JNI_EXCEPTION(env);
|
||||
if (android_app->getPendingIntentIME && jstr)
|
||||
{
|
||||
const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
|
||||
strlcpy(android_app->current_ime, argv, sizeof(android_app->current_ime));
|
||||
(*env)->ReleaseStringUTFChars(env, jstr, argv);
|
||||
|
||||
valschanged = true;
|
||||
RARCH_LOG("Current IME: [%s].\n", android_app->current_ime);
|
||||
}
|
||||
|
||||
if (valschanged)
|
||||
{
|
||||
g_extern.block_config_read = false;
|
||||
config_load();
|
||||
g_extern.block_config_read = true;
|
||||
}
|
||||
|
||||
//LIBRETRO
|
||||
jstr = (*env)->CallObjectMethod(env, android_app->activity->clazz, android_app->getPendingIntentLibretroPath);
|
||||
JNI_EXCEPTION(env);
|
||||
if (android_app->getPendingIntentLibretroPath && jstr)
|
||||
{
|
||||
const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
|
||||
strlcpy(g_settings.libretro, argv, sizeof(g_settings.libretro));
|
||||
(*env)->ReleaseStringUTFChars(env, jstr, argv);
|
||||
}
|
||||
|
||||
RARCH_LOG("Libretro path: [%s].\n", g_settings.libretro);
|
||||
|
||||
if (startgame)
|
||||
{
|
||||
RARCH_LOG("Starting new game %s...\n", g_extern.fullpath);
|
||||
g_extern.lifecycle_state &= ~(1ULL << MODE_MENU);
|
||||
g_extern.lifecycle_state &= ~(1ULL << MODE_GAME);
|
||||
load_menu_game_new_core();
|
||||
}
|
||||
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz, android_app->clearPendingIntent);
|
||||
}
|
||||
|
||||
static int process_events(void *data)
|
||||
{
|
||||
jboolean hasPendingIntent;
|
||||
JNIEnv *env;
|
||||
struct android_app* android_app = (struct android_app*)data;
|
||||
|
||||
if (input_key_pressed_func(RARCH_PAUSE_TOGGLE))
|
||||
android_run_events(android_app);
|
||||
|
||||
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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -509,6 +607,16 @@ static void system_init(void *data)
|
||||
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);
|
||||
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;");
|
||||
|
||||
GET_OBJECT_CLASS(env, class, obj);
|
||||
GET_METHOD_ID(env, android_app->getStringExtra, class, "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
|
||||
|
@ -49,6 +49,12 @@ struct android_app
|
||||
char current_ime[PATH_MAX];
|
||||
jmethodID getIntent;
|
||||
jmethodID getStringExtra;
|
||||
jmethodID clearPendingIntent;
|
||||
jmethodID hasPendingIntent;
|
||||
jmethodID getPendingIntentConfigPath;
|
||||
jmethodID getPendingIntentLibretroPath;
|
||||
jmethodID getPendingIntentFullPath;
|
||||
jmethodID getPendingIntentIME;
|
||||
};
|
||||
|
||||
enum {
|
||||
|
Loading…
x
Reference in New Issue
Block a user