// SPDX-FileCopyrightText: 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include #include #include "android_config.h" #include "android_settings.h" #include "common/logging/log.h" #include "common/settings.h" #include "frontend_common/config.h" #include "jni/android_common/android_common.h" #include "jni/id_cache.h" std::unique_ptr config; template Settings::Setting* getSetting(JNIEnv* env, jstring jkey) { auto key = GetJString(env, jkey); auto basicSetting = Settings::values.linkage.by_key[key]; auto basicAndroidSetting = AndroidSettings::values.linkage.by_key[key]; if (basicSetting != 0) { return static_cast*>(basicSetting); } if (basicAndroidSetting != 0) { return static_cast*>(basicAndroidSetting); } LOG_ERROR(Frontend, "[Android Native] Could not find setting - {}", key); return nullptr; } extern "C" { void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_initializeConfig(JNIEnv* env, jobject obj) { config = std::make_unique(); } void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_unloadConfig(JNIEnv* env, jobject obj) { config.reset(); } void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_reloadSettings(JNIEnv* env, jobject obj) { config->AndroidConfig::ReloadAllValues(); } void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_saveSettings(JNIEnv* env, jobject obj) { config->AndroidConfig::SaveAllValues(); } jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getBoolean(JNIEnv* env, jobject obj, jstring jkey, jboolean needGlobal) { auto setting = getSetting(env, jkey); if (setting == nullptr) { return false; } return setting->GetValue(static_cast(needGlobal)); } void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setBoolean(JNIEnv* env, jobject obj, jstring jkey, jboolean value) { auto setting = getSetting(env, jkey); if (setting == nullptr) { return; } setting->SetValue(static_cast(value)); } jbyte Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getByte(JNIEnv* env, jobject obj, jstring jkey, jboolean needGlobal) { auto setting = getSetting(env, jkey); if (setting == nullptr) { return -1; } return setting->GetValue(static_cast(needGlobal)); } void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setByte(JNIEnv* env, jobject obj, jstring jkey, jbyte value) { auto setting = getSetting(env, jkey); if (setting == nullptr) { return; } setting->SetValue(value); } jshort Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getShort(JNIEnv* env, jobject obj, jstring jkey, jboolean needGlobal) { auto setting = getSetting(env, jkey); if (setting == nullptr) { return -1; } return setting->GetValue(static_cast(needGlobal)); } void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setShort(JNIEnv* env, jobject obj, jstring jkey, jshort value) { auto setting = getSetting(env, jkey); if (setting == nullptr) { return; } setting->SetValue(value); } jint Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getInt(JNIEnv* env, jobject obj, jstring jkey, jboolean needGlobal) { auto setting = getSetting(env, jkey); if (setting == nullptr) { return -1; } return setting->GetValue(needGlobal); } void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setInt(JNIEnv* env, jobject obj, jstring jkey, jint value) { auto setting = getSetting(env, jkey); if (setting == nullptr) { return; } setting->SetValue(value); } jfloat Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getFloat(JNIEnv* env, jobject obj, jstring jkey, jboolean needGlobal) { auto setting = getSetting(env, jkey); if (setting == nullptr) { return -1; } return setting->GetValue(static_cast(needGlobal)); } void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setFloat(JNIEnv* env, jobject obj, jstring jkey, jfloat value) { auto setting = getSetting(env, jkey); if (setting == nullptr) { return; } setting->SetValue(value); } jlong Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getLong(JNIEnv* env, jobject obj, jstring jkey, jboolean needGlobal) { auto setting = getSetting(env, jkey); if (setting == nullptr) { return -1; } return setting->GetValue(static_cast(needGlobal)); } void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setLong(JNIEnv* env, jobject obj, jstring jkey, jlong value) { auto setting = getSetting(env, jkey); if (setting == nullptr) { return; } setting->SetValue(value); } jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getString(JNIEnv* env, jobject obj, jstring jkey, jboolean needGlobal) { auto setting = getSetting(env, jkey); if (setting == nullptr) { return ToJString(env, ""); } return ToJString(env, setting->GetValue(static_cast(needGlobal))); } void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setString(JNIEnv* env, jobject obj, jstring jkey, jstring value) { auto setting = getSetting(env, jkey); if (setting == nullptr) { return; } setting->SetValue(GetJString(env, value)); } jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getIsRuntimeModifiable(JNIEnv* env, jobject obj, jstring jkey) { auto setting = getSetting(env, jkey); if (setting != nullptr) { return setting->RuntimeModfiable(); } return true; } jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getPairedSettingKey(JNIEnv* env, jobject obj, jstring jkey) { auto setting = getSetting(env, jkey); if (setting == nullptr) { return ToJString(env, ""); } if (setting->PairedSetting() == nullptr) { return ToJString(env, ""); } return ToJString(env, setting->PairedSetting()->GetLabel()); } jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getIsSwitchable(JNIEnv* env, jobject obj, jstring jkey) { auto setting = getSetting(env, jkey); if (setting != nullptr) { return setting->Switchable(); } return false; } jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_usingGlobal(JNIEnv* env, jobject obj, jstring jkey) { auto setting = getSetting(env, jkey); if (setting != nullptr) { return setting->UsingGlobal(); } return true; } void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setGlobal(JNIEnv* env, jobject obj, jstring jkey, jboolean global) { auto setting = getSetting(env, jkey); if (setting != nullptr) { setting->SetGlobal(static_cast(global)); } } jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getDefaultToString(JNIEnv* env, jobject obj, jstring jkey) { auto setting = getSetting(env, jkey); if (setting != nullptr) { return ToJString(env, setting->DefaultToString()); } return ToJString(env, ""); } jobjectArray Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getGameDirs(JNIEnv* env, jobject obj) { jclass gameDirClass = IDCache::GetGameDirClass(); jmethodID gameDirConstructor = IDCache::GetGameDirConstructor(); jobjectArray jgameDirArray = env->NewObjectArray(AndroidSettings::values.game_dirs.size(), gameDirClass, nullptr); for (size_t i = 0; i < AndroidSettings::values.game_dirs.size(); ++i) { jobject jgameDir = env->NewObject(gameDirClass, gameDirConstructor, ToJString(env, AndroidSettings::values.game_dirs[i].path), static_cast(AndroidSettings::values.game_dirs[i].deep_scan)); env->SetObjectArrayElement(jgameDirArray, i, jgameDir); } return jgameDirArray; } void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setGameDirs(JNIEnv* env, jobject obj, jobjectArray gameDirs) { AndroidSettings::values.game_dirs.clear(); int size = env->GetArrayLength(gameDirs); if (size == 0) { return; } jobject dir = env->GetObjectArrayElement(gameDirs, 0); jclass gameDirClass = IDCache::GetGameDirClass(); jfieldID uriStringField = env->GetFieldID(gameDirClass, "uriString", "Ljava/lang/String;"); jfieldID deepScanBooleanField = env->GetFieldID(gameDirClass, "deepScan", "Z"); for (int i = 0; i < size; ++i) { dir = env->GetObjectArrayElement(gameDirs, i); jstring juriString = static_cast(env->GetObjectField(dir, uriStringField)); jboolean jdeepScanBoolean = env->GetBooleanField(dir, deepScanBooleanField); std::string uriString = GetJString(env, juriString); AndroidSettings::values.game_dirs.push_back( AndroidSettings::GameDir{uriString, static_cast(jdeepScanBoolean)}); } } void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_addGameDir(JNIEnv* env, jobject obj, jobject gameDir) { jclass gameDirClass = IDCache::GetGameDirClass(); jfieldID uriStringField = env->GetFieldID(gameDirClass, "uriString", "Ljava/lang/String;"); jfieldID deepScanBooleanField = env->GetFieldID(gameDirClass, "deepScan", "Z"); jstring juriString = static_cast(env->GetObjectField(gameDir, uriStringField)); jboolean jdeepScanBoolean = env->GetBooleanField(gameDir, deepScanBooleanField); std::string uriString = GetJString(env, juriString); AndroidSettings::values.game_dirs.push_back( AndroidSettings::GameDir{uriString, static_cast(jdeepScanBoolean)}); } } // extern "C"