diff options
Diffstat (limited to 'src/android/app/src/main/jni')
-rw-r--r-- | src/android/app/src/main/jni/id_cache.cpp | 40 | ||||
-rw-r--r-- | src/android/app/src/main/jni/id_cache.h | 6 | ||||
-rw-r--r-- | src/android/app/src/main/jni/native.cpp | 108 | ||||
-rw-r--r-- | src/android/app/src/main/jni/native.h | 2 | ||||
-rw-r--r-- | src/android/app/src/main/jni/native_config.cpp | 26 |
5 files changed, 172 insertions, 10 deletions
diff --git a/src/android/app/src/main/jni/id_cache.cpp b/src/android/app/src/main/jni/id_cache.cpp index a56ed5662..df8935178 100644 --- a/src/android/app/src/main/jni/id_cache.cpp +++ b/src/android/app/src/main/jni/id_cache.cpp @@ -20,6 +20,12 @@ static jmethodID s_disk_cache_load_progress; static jmethodID s_on_emulation_started; static jmethodID s_on_emulation_stopped; +static jclass s_string_class; +static jclass s_pair_class; +static jmethodID s_pair_constructor; +static jfieldID s_pair_first_field; +static jfieldID s_pair_second_field; + static constexpr jint JNI_VERSION = JNI_VERSION_1_6; namespace IDCache { @@ -79,6 +85,26 @@ jmethodID GetOnEmulationStopped() { return s_on_emulation_stopped; } +jclass GetStringClass() { + return s_string_class; +} + +jclass GetPairClass() { + return s_pair_class; +} + +jmethodID GetPairConstructor() { + return s_pair_constructor; +} + +jfieldID GetPairFirstField() { + return s_pair_first_field; +} + +jfieldID GetPairSecondField() { + return s_pair_second_field; +} + } // namespace IDCache #ifdef __cplusplus @@ -115,6 +141,18 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) { s_on_emulation_stopped = env->GetStaticMethodID(s_native_library_class, "onEmulationStopped", "(I)V"); + const jclass string_class = env->FindClass("java/lang/String"); + s_string_class = reinterpret_cast<jclass>(env->NewGlobalRef(string_class)); + env->DeleteLocalRef(string_class); + + const jclass pair_class = env->FindClass("kotlin/Pair"); + s_pair_class = reinterpret_cast<jclass>(env->NewGlobalRef(pair_class)); + s_pair_constructor = + env->GetMethodID(pair_class, "<init>", "(Ljava/lang/Object;Ljava/lang/Object;)V"); + s_pair_first_field = env->GetFieldID(pair_class, "first", "Ljava/lang/Object;"); + s_pair_second_field = env->GetFieldID(pair_class, "second", "Ljava/lang/Object;"); + env->DeleteLocalRef(pair_class); + // Initialize Android Storage Common::FS::Android::RegisterCallbacks(env, s_native_library_class); @@ -136,6 +174,8 @@ void JNI_OnUnload(JavaVM* vm, void* reserved) { env->DeleteGlobalRef(s_disk_cache_progress_class); env->DeleteGlobalRef(s_load_callback_stage_class); env->DeleteGlobalRef(s_game_dir_class); + env->DeleteGlobalRef(s_string_class); + env->DeleteGlobalRef(s_pair_class); // UnInitialize applets SoftwareKeyboard::CleanupJNI(env); diff --git a/src/android/app/src/main/jni/id_cache.h b/src/android/app/src/main/jni/id_cache.h index 855649efa..36233423e 100644 --- a/src/android/app/src/main/jni/id_cache.h +++ b/src/android/app/src/main/jni/id_cache.h @@ -20,4 +20,10 @@ jmethodID GetDiskCacheLoadProgress(); jmethodID GetOnEmulationStarted(); jmethodID GetOnEmulationStopped(); +jclass GetStringClass(); +jclass GetPairClass(); +jmethodID GetPairConstructor(); +jfieldID GetPairFirstField(); +jfieldID GetPairSecondField(); + } // namespace IDCache diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index e5d3158c8..ce570b811 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -14,6 +14,7 @@ #include <android/api-level.h> #include <android/native_window_jni.h> #include <common/fs/fs.h> +#include <core/file_sys/patch_manager.h> #include <core/file_sys/savedata_factory.h> #include <core/loader/nro.h> #include <jni.h> @@ -79,6 +80,10 @@ Core::System& EmulationSession::System() { return m_system; } +FileSys::ManualContentProvider* EmulationSession::ContentProvider() { + return m_manual_provider.get(); +} + const EmuWindow_Android& EmulationSession::Window() const { return *m_window; } @@ -455,6 +460,15 @@ void EmulationSession::OnEmulationStopped(Core::SystemResultStatus result) { static_cast<jint>(result)); } +u64 EmulationSession::GetProgramId(JNIEnv* env, jstring jprogramId) { + auto program_id_string = GetJString(env, jprogramId); + try { + return std::stoull(program_id_string); + } catch (...) { + return 0; + } +} + static Core::SystemResultStatus RunEmulation(const std::string& filepath) { MicroProfileOnThreadCreate("EmuThread"); SCOPE_EXIT({ MicroProfileShutdown(); }); @@ -504,6 +518,27 @@ int Java_org_yuzu_yuzu_1emu_NativeLibrary_installFileToNand(JNIEnv* env, jobject GetJString(env, j_file_extension)); } +jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_doesUpdateMatchProgram(JNIEnv* env, jobject jobj, + jstring jprogramId, + jstring jupdatePath) { + u64 program_id = EmulationSession::GetProgramId(env, jprogramId); + std::string updatePath = GetJString(env, jupdatePath); + std::shared_ptr<FileSys::NSP> nsp = std::make_shared<FileSys::NSP>( + EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(updatePath, + FileSys::Mode::Read)); + for (const auto& item : nsp->GetNCAs()) { + for (const auto& nca_details : item.second) { + if (nca_details.second->GetName().ends_with(".cnmt.nca")) { + auto update_id = nca_details.second->GetTitleId() & ~0xFFFULL; + if (update_id == program_id) { + return true; + } + } + } + } + return false; +} + void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeGpuDriver(JNIEnv* env, jclass clazz, jstring hook_lib_dir, jstring custom_driver_dir, @@ -665,13 +700,6 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeSystem(JNIEnv* env, jclass EmulationSession::GetInstance().InitializeSystem(reload); } -jint Java_org_yuzu_yuzu_1emu_NativeLibrary_defaultCPUCore(JNIEnv* env, jclass clazz) { - return {}; -} - -void Java_org_yuzu_yuzu_1emu_NativeLibrary_run__Ljava_lang_String_2Ljava_lang_String_2Z( - JNIEnv* env, jclass clazz, jstring j_file, jstring j_savestate, jboolean j_delete_savestate) {} - jdoubleArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPerfStats(JNIEnv* env, jclass clazz) { jdoubleArray j_stats = env->NewDoubleArray(4); @@ -696,9 +724,13 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCpuBackend(JNIEnv* env, jclass return ToJString(env, "JIT"); } -void Java_org_yuzu_yuzu_1emu_utils_DirectoryInitialization_setSysDirectory(JNIEnv* env, - jclass clazz, - jstring j_path) {} +void Java_org_yuzu_yuzu_1emu_NativeLibrary_applySettings(JNIEnv* env, jobject jobj) { + EmulationSession::GetInstance().System().ApplySettings(); +} + +void Java_org_yuzu_yuzu_1emu_NativeLibrary_logSettings(JNIEnv* env, jobject jobj) { + Settings::LogSettings(); +} void Java_org_yuzu_yuzu_1emu_NativeLibrary_run__Ljava_lang_String_2(JNIEnv* env, jclass clazz, jstring j_path) { @@ -792,4 +824,60 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isFirmwareAvailable(JNIEnv* env, return true; } +jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getAddonsForFile(JNIEnv* env, jobject jobj, + jstring jpath, + jstring jprogramId) { + const auto path = GetJString(env, jpath); + const auto vFile = + Core::GetGameFileFromPath(EmulationSession::GetInstance().System().GetFilesystem(), path); + if (vFile == nullptr) { + return nullptr; + } + + auto& system = EmulationSession::GetInstance().System(); + auto program_id = EmulationSession::GetProgramId(env, jprogramId); + const FileSys::PatchManager pm{program_id, system.GetFileSystemController(), + system.GetContentProvider()}; + const auto loader = Loader::GetLoader(system, vFile); + + FileSys::VirtualFile update_raw; + loader->ReadUpdateRaw(update_raw); + + auto addons = pm.GetPatchVersionNames(update_raw); + auto jemptyString = ToJString(env, ""); + auto jemptyStringPair = env->NewObject(IDCache::GetPairClass(), IDCache::GetPairConstructor(), + jemptyString, jemptyString); + jobjectArray jaddonsArray = + env->NewObjectArray(addons.size(), IDCache::GetPairClass(), jemptyStringPair); + int i = 0; + for (const auto& addon : addons) { + jobject jaddon = env->NewObject(IDCache::GetPairClass(), IDCache::GetPairConstructor(), + ToJString(env, addon.first), ToJString(env, addon.second)); + env->SetObjectArrayElement(jaddonsArray, i, jaddon); + ++i; + } + return jaddonsArray; +} + +jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject jobj, + jstring jprogramId) { + auto program_id = EmulationSession::GetProgramId(env, jprogramId); + + auto& system = EmulationSession::GetInstance().System(); + + Service::Account::ProfileManager manager; + // TODO: Pass in a selected user once we get the relevant UI working + const auto user_id = manager.GetUser(static_cast<std::size_t>(0)); + ASSERT(user_id); + + const auto nandDir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir); + auto vfsNandDir = system.GetFilesystem()->OpenDirectory(Common::FS::PathToUTF8String(nandDir), + FileSys::Mode::Read); + + const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath( + system, vfsNandDir, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData, + program_id, user_id->AsU128(), 0); + return ToJString(env, user_save_data_path); +} + } // extern "C" diff --git a/src/android/app/src/main/jni/native.h b/src/android/app/src/main/jni/native.h index f1457bd1f..96c22d52b 100644 --- a/src/android/app/src/main/jni/native.h +++ b/src/android/app/src/main/jni/native.h @@ -54,6 +54,8 @@ public: static void OnEmulationStarted(); + static u64 GetProgramId(JNIEnv* env, jstring jprogramId); + private: static void LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress, int max); static void OnEmulationStopped(Core::SystemResultStatus result); diff --git a/src/android/app/src/main/jni/native_config.cpp b/src/android/app/src/main/jni/native_config.cpp index 9439d11e1..7f2485720 100644 --- a/src/android/app/src/main/jni/native_config.cpp +++ b/src/android/app/src/main/jni/native_config.cpp @@ -283,4 +283,30 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_addGameDir(JNIEnv* env, jobject AndroidSettings::GameDir{uriString, static_cast<bool>(jdeepScanBoolean)}); } +jobjectArray Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getDisabledAddons(JNIEnv* env, jobject obj, + jstring jprogramId) { + auto program_id = EmulationSession::GetProgramId(env, jprogramId); + auto& disabledAddons = Settings::values.disabled_addons[program_id]; + jobjectArray jdisabledAddonsArray = + env->NewObjectArray(disabledAddons.size(), IDCache::GetStringClass(), ToJString(env, "")); + for (size_t i = 0; i < disabledAddons.size(); ++i) { + env->SetObjectArrayElement(jdisabledAddonsArray, i, ToJString(env, disabledAddons[i])); + } + return jdisabledAddonsArray; +} + +void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setDisabledAddons(JNIEnv* env, jobject obj, + jstring jprogramId, + jobjectArray jdisabledAddons) { + auto program_id = EmulationSession::GetProgramId(env, jprogramId); + Settings::values.disabled_addons[program_id].clear(); + std::vector<std::string> disabled_addons; + const int size = env->GetArrayLength(jdisabledAddons); + for (int i = 0; i < size; ++i) { + auto jaddon = static_cast<jstring>(env->GetObjectArrayElement(jdisabledAddons, i)); + disabled_addons.push_back(GetJString(env, jaddon)); + } + Settings::values.disabled_addons[program_id] = disabled_addons; +} + } // extern "C" |