forked from moonpower/azahar-UWP
Add LLE modules for online features option + AM Refactor w/ various improvements/fixes
- Added option to enable required LLE modules for online features. - (Android) Fixed bug that would cause FS RenameFile to fail sometimes on Android. - (Android) Moved New 3DS mode and LLE applets to system settings tab on Android. - (Android) Fixed cfg save data related issues (mostly Console ID). - Made AM title scanning asynchronous, which makes game boot way faster on Android on most cases. - Made more AM functions asynchronous, to prevent stutter. - Fixed bug in SOC that could cause the emulator to crash when disconnecting. - Fixed keys not being initialized when processing console unique files.
This commit is contained in:
@@ -567,7 +567,11 @@ object NativeLibrary {
|
||||
@JvmStatic
|
||||
fun createDir(directory: String, directoryName: String): Boolean =
|
||||
if (FileUtil.isNativePath(directory)) {
|
||||
CitraApplication.documentsTree.createDir(directory, directoryName)
|
||||
try {
|
||||
CitraApplication.documentsTree.createDir(directory, directoryName)
|
||||
} catch (e: Exception) {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
FileUtil.createDir(directory, directoryName) != null
|
||||
}
|
||||
@@ -641,7 +645,11 @@ object NativeLibrary {
|
||||
@JvmStatic
|
||||
fun renameFile(path: String, destinationFilename: String): Boolean =
|
||||
if (FileUtil.isNativePath(path)) {
|
||||
CitraApplication.documentsTree.renameFile(path, destinationFilename)
|
||||
try {
|
||||
CitraApplication.documentsTree.renameFile(path, destinationFilename)
|
||||
} catch (e: Exception) {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
FileUtil.renameFile(path, destinationFilename)
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@ enum class BooleanSetting(
|
||||
INSTANT_DEBUG_LOG("instant_debug_log", Settings.SECTION_DEBUG, false),
|
||||
CUSTOM_LAYOUT("custom_layout",Settings.SECTION_LAYOUT,false),
|
||||
DELAY_START_LLE_MODULES("delay_start_for_lle_modules", Settings.SECTION_DEBUG, true),
|
||||
DETERMINISTIC_ASYNC_OPERATIONS("deterministic_async_operations", Settings.SECTION_DEBUG, false);
|
||||
DETERMINISTIC_ASYNC_OPERATIONS("deterministic_async_operations", Settings.SECTION_DEBUG, false),
|
||||
REQUIRED_ONLINE_LLE_MODULES("enable_required_online_lle_modules", Settings.SECTION_SYSTEM, false);
|
||||
|
||||
override var boolean: Boolean = defaultValue
|
||||
|
||||
@@ -41,6 +42,7 @@ enum class BooleanSetting(
|
||||
ASYNC_SHADERS,
|
||||
DELAY_START_LLE_MODULES,
|
||||
DETERMINISTIC_ASYNC_OPERATIONS,
|
||||
REQUIRED_ONLINE_LLE_MODULES,
|
||||
)
|
||||
|
||||
fun from(key: String): BooleanSetting? =
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
@@ -44,7 +44,7 @@ enum class IntSetting(
|
||||
PORTRAIT_BOTTOM_HEIGHT("custom_portrait_bottom_height",Settings.SECTION_LAYOUT,480),
|
||||
AUDIO_INPUT_TYPE("output_type", Settings.SECTION_AUDIO, 0),
|
||||
NEW_3DS("is_new_3ds", Settings.SECTION_SYSTEM, 1),
|
||||
LLE_APPLETS("lle_applets", Settings.SECTION_SYSTEM, 0),
|
||||
LLE_APPLETS("lle_applets", Settings.SECTION_SYSTEM, 1),
|
||||
CPU_CLOCK_SPEED("cpu_clock_percentage", Settings.SECTION_CORE, 100),
|
||||
LINEAR_FILTERING("filter_mode", Settings.SECTION_RENDERER, 1),
|
||||
SHADERS_ACCURATE_MUL("shaders_accurate_mul", Settings.SECTION_RENDERER, 0),
|
||||
|
||||
@@ -110,6 +110,16 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
|
||||
presenter.saveState(outState)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
presenter.onPause()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
presenter.onResume()
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
presenter.onStart()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
@@ -28,8 +28,15 @@ class SettingsActivityPresenter(private val activityView: SettingsActivityView)
|
||||
}
|
||||
}
|
||||
|
||||
fun onStart() {
|
||||
fun onResume() {
|
||||
SystemSaveGame.load()
|
||||
}
|
||||
|
||||
fun onPause() {
|
||||
SystemSaveGame.save()
|
||||
}
|
||||
|
||||
fun onStart() {
|
||||
prepareDirectoriesIfNeeded()
|
||||
}
|
||||
|
||||
@@ -56,7 +63,6 @@ class SettingsActivityPresenter(private val activityView: SettingsActivityView)
|
||||
if (finishing && shouldSave) {
|
||||
Log.debug("[SettingsActivity] Settings activity stopping. Saving settings to INI...")
|
||||
settings.saveSettings(activityView)
|
||||
SystemSaveGame.save()
|
||||
//added to ensure that layout changes take effect as soon as settings window closes
|
||||
NativeLibrary.reloadSettings()
|
||||
NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode)
|
||||
|
||||
@@ -253,6 +253,35 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
||||
override val valueAsString get() = string
|
||||
override val defaultValue = "AZAHAR"
|
||||
}
|
||||
add(HeaderSetting(R.string.emulation_settings))
|
||||
add(
|
||||
SwitchSetting(
|
||||
IntSetting.NEW_3DS,
|
||||
R.string.new_3ds,
|
||||
0,
|
||||
IntSetting.NEW_3DS.key,
|
||||
IntSetting.NEW_3DS.defaultValue
|
||||
)
|
||||
)
|
||||
add(
|
||||
SwitchSetting(
|
||||
IntSetting.LLE_APPLETS,
|
||||
R.string.lle_applets,
|
||||
0,
|
||||
IntSetting.LLE_APPLETS.key,
|
||||
IntSetting.LLE_APPLETS.defaultValue
|
||||
)
|
||||
)
|
||||
add(
|
||||
SwitchSetting(
|
||||
BooleanSetting.REQUIRED_ONLINE_LLE_MODULES,
|
||||
R.string.enable_required_online_lle_modules,
|
||||
R.string.enable_required_online_lle_modules_desc,
|
||||
BooleanSetting.REQUIRED_ONLINE_LLE_MODULES.key,
|
||||
BooleanSetting.REQUIRED_ONLINE_LLE_MODULES.defaultValue
|
||||
)
|
||||
)
|
||||
add(HeaderSetting(R.string.profile_settings))
|
||||
add(
|
||||
StringInputSetting(
|
||||
usernameSetting,
|
||||
@@ -1285,24 +1314,6 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
||||
settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_debug))
|
||||
sl.apply {
|
||||
add(HeaderSetting(R.string.debug_warning))
|
||||
add(
|
||||
SwitchSetting(
|
||||
IntSetting.NEW_3DS,
|
||||
R.string.new_3ds,
|
||||
0,
|
||||
IntSetting.NEW_3DS.key,
|
||||
IntSetting.NEW_3DS.defaultValue
|
||||
)
|
||||
)
|
||||
add(
|
||||
SwitchSetting(
|
||||
IntSetting.LLE_APPLETS,
|
||||
R.string.lle_applets,
|
||||
0,
|
||||
IntSetting.LLE_APPLETS.key,
|
||||
IntSetting.LLE_APPLETS.defaultValue
|
||||
)
|
||||
)
|
||||
add(
|
||||
SliderSetting(
|
||||
IntSetting.CPU_CLOCK_SPEED,
|
||||
|
||||
@@ -87,6 +87,11 @@ class SystemFilesFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
SystemSaveGame.load()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
SystemSaveGame.save()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Citra Emulator Project / Lime3DS Emulator Project
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
@@ -161,8 +161,8 @@ class DocumentsTree {
|
||||
val node = resolvePath(filepath) ?: return false
|
||||
try {
|
||||
val filename = URLDecoder.decode(destinationFilename, FileUtil.DECODE_METHOD)
|
||||
DocumentsContract.renameDocument(context.contentResolver, node.uri!!, filename)
|
||||
node.rename(filename)
|
||||
val newUri = DocumentsContract.renameDocument(context.contentResolver, node.uri!!, filename)
|
||||
node.rename(filename, newUri)
|
||||
return true
|
||||
} catch (e: Exception) {
|
||||
error("[DocumentsTree]: Cannot rename file, error: " + e.message)
|
||||
@@ -255,10 +255,11 @@ class DocumentsTree {
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun rename(name: String) {
|
||||
fun rename(name: String, uri: Uri?) {
|
||||
parent ?: return
|
||||
parent!!.removeChild(this)
|
||||
this.name = name
|
||||
this.uri = uri
|
||||
parent!!.addChild(this)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2014 Citra Emulator Project
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
@@ -235,6 +235,7 @@ void Config::ReadValues() {
|
||||
// System
|
||||
ReadSetting("System", Settings::values.is_new_3ds);
|
||||
ReadSetting("System", Settings::values.lle_applets);
|
||||
ReadSetting("System", Settings::values.enable_required_online_lle_modules);
|
||||
ReadSetting("System", Settings::values.region_value);
|
||||
ReadSetting("System", Settings::values.init_clock);
|
||||
{
|
||||
|
||||
@@ -326,9 +326,13 @@ use_virtual_sd =
|
||||
is_new_3ds =
|
||||
|
||||
# Whether to use LLE system applets, if installed
|
||||
# 0 (default): No, 1: Yes
|
||||
# 0: No, 1 (default): Yes
|
||||
lle_applets =
|
||||
|
||||
# Whether to enable LLE modules for online play
|
||||
# 0 (default): No, 1: Yes
|
||||
enable_required_online_lle_modules =
|
||||
|
||||
# The system region that Citra will use during emulation
|
||||
# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan
|
||||
region_value =
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
@@ -8,17 +8,22 @@
|
||||
#include <core/hle/service/ptm/ptm.h>
|
||||
#include "android_common/android_common.h"
|
||||
|
||||
static bool changes_pending = false;
|
||||
std::shared_ptr<Service::CFG::Module> cfg;
|
||||
|
||||
extern "C" {
|
||||
|
||||
void Java_org_citra_citra_1emu_utils_SystemSaveGame_save([[maybe_unused]] JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj) {
|
||||
cfg->UpdateConfigNANDSavegame();
|
||||
if (changes_pending) {
|
||||
changes_pending = false;
|
||||
cfg->UpdateConfigNANDSavegame();
|
||||
}
|
||||
}
|
||||
|
||||
void Java_org_citra_citra_1emu_utils_SystemSaveGame_load([[maybe_unused]] JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj) {
|
||||
cfg.reset();
|
||||
cfg = Service::CFG::GetModule(Core::System::GetInstance());
|
||||
}
|
||||
|
||||
@@ -30,6 +35,7 @@ jboolean Java_org_citra_citra_1emu_utils_SystemSaveGame_getIsSystemSetupNeeded(
|
||||
void Java_org_citra_citra_1emu_utils_SystemSaveGame_setSystemSetupNeeded(
|
||||
[[maybe_unused]] JNIEnv* env, [[maybe_unused]] jobject obj, jboolean needed) {
|
||||
cfg->SetSystemSetupNeeded(needed);
|
||||
changes_pending = true;
|
||||
}
|
||||
|
||||
jstring Java_org_citra_citra_1emu_utils_SystemSaveGame_getUsername([[maybe_unused]] JNIEnv* env,
|
||||
@@ -41,6 +47,7 @@ void Java_org_citra_citra_1emu_utils_SystemSaveGame_setUsername([[maybe_unused]]
|
||||
[[maybe_unused]] jobject obj,
|
||||
jstring username) {
|
||||
cfg->SetUsername(Common::UTF8ToUTF16(GetJString(env, username)));
|
||||
changes_pending = true;
|
||||
}
|
||||
|
||||
jshortArray Java_org_citra_citra_1emu_utils_SystemSaveGame_getBirthday(
|
||||
@@ -57,6 +64,7 @@ void Java_org_citra_citra_1emu_utils_SystemSaveGame_setBirthday([[maybe_unused]]
|
||||
[[maybe_unused]] jobject obj,
|
||||
jshort jmonth, jshort jday) {
|
||||
cfg->SetBirthday(static_cast<u8>(jmonth), static_cast<u8>(jday));
|
||||
changes_pending = true;
|
||||
}
|
||||
|
||||
jint Java_org_citra_citra_1emu_utils_SystemSaveGame_getSystemLanguage(
|
||||
@@ -68,6 +76,7 @@ void Java_org_citra_citra_1emu_utils_SystemSaveGame_setSystemLanguage([[maybe_un
|
||||
[[maybe_unused]] jobject obj,
|
||||
jint jsystemLanguage) {
|
||||
cfg->SetSystemLanguage(static_cast<Service::CFG::SystemLanguage>(jsystemLanguage));
|
||||
changes_pending = true;
|
||||
}
|
||||
|
||||
jint Java_org_citra_citra_1emu_utils_SystemSaveGame_getSoundOutputMode(
|
||||
@@ -79,6 +88,7 @@ void Java_org_citra_citra_1emu_utils_SystemSaveGame_setSoundOutputMode([[maybe_u
|
||||
[[maybe_unused]] jobject obj,
|
||||
jint jmode) {
|
||||
cfg->SetSoundOutputMode(static_cast<Service::CFG::SoundOutputMode>(jmode));
|
||||
changes_pending = true;
|
||||
}
|
||||
|
||||
jshort Java_org_citra_citra_1emu_utils_SystemSaveGame_getCountryCode([[maybe_unused]] JNIEnv* env,
|
||||
@@ -90,6 +100,7 @@ void Java_org_citra_citra_1emu_utils_SystemSaveGame_setCountryCode([[maybe_unuse
|
||||
[[maybe_unused]] jobject obj,
|
||||
jshort jmode) {
|
||||
cfg->SetCountryCode(static_cast<u8>(jmode));
|
||||
changes_pending = true;
|
||||
}
|
||||
|
||||
jint Java_org_citra_citra_1emu_utils_SystemSaveGame_getPlayCoins([[maybe_unused]] JNIEnv* env,
|
||||
@@ -101,6 +112,7 @@ void Java_org_citra_citra_1emu_utils_SystemSaveGame_setPlayCoins([[maybe_unused]
|
||||
[[maybe_unused]] jobject obj,
|
||||
jint jcoins) {
|
||||
Service::PTM::Module::SetPlayCoins(static_cast<u16>(jcoins));
|
||||
changes_pending = true;
|
||||
}
|
||||
|
||||
jlong Java_org_citra_citra_1emu_utils_SystemSaveGame_getConsoleId([[maybe_unused]] JNIEnv* env,
|
||||
@@ -112,7 +124,7 @@ void Java_org_citra_citra_1emu_utils_SystemSaveGame_regenerateConsoleId(
|
||||
[[maybe_unused]] JNIEnv* env, [[maybe_unused]] jobject obj) {
|
||||
const auto [random_number, console_id] = cfg->GenerateConsoleUniqueId();
|
||||
cfg->SetConsoleUniqueId(random_number, console_id);
|
||||
cfg->UpdateConfigNANDSavegame();
|
||||
changes_pending = true;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
@@ -190,7 +190,7 @@
|
||||
<string name="steps_per_hour_description">Number of steps per hour reported by the pedometer. Range from 0 to 65,535.</string>
|
||||
<string name="console_id">Console ID</string>
|
||||
<string name="regenerate_console_id">Regenerate Console ID</string>
|
||||
<string name="regenerate_console_id_description">This will replace your current virtual 3DS with a new one. Your current virtual 3DS will not be recoverable. This might have unexpected effects inside applications. This might fail if you use an outdated config save. Continue?</string>
|
||||
<string name="regenerate_console_id_description">This will replace your current virtual 3DS console ID with a new one. Your current virtual 3DS console ID will not be recoverable. This might have unexpected effects inside applications. This might fail if you use an outdated config save. Continue?</string>
|
||||
<string name="plugin_loader">3GX Plugin Loader</string>
|
||||
<string name="plugin_loader_description">Loads 3GX plugins from the emulated SD card if they are available.</string>
|
||||
<string name="allow_plugin_loader">Allow Applications to Change Plugin Loader State</string>
|
||||
@@ -778,5 +778,8 @@
|
||||
<string name="delay_start_lle_modules_description">Delays the start of the app when LLE modules are enabled.</string>
|
||||
<string name="deterministic_async_operations">Deterministic Async Operations</string>
|
||||
<string name="deterministic_async_operations_description">Makes async operations deterministic for debugging. Enabling this may cause freezes.</string>
|
||||
|
||||
<string name="enable_required_online_lle_modules">Enable required LLE modules for online features (if installed)</string>
|
||||
<string name="enable_required_online_lle_modules_desc">Enables the LLE modules required for online multiplayer, eShop access, etc.</string>
|
||||
<string name="emulation_settings">Emulation Settings</string>
|
||||
<string name="profile_settings">Profile Settings</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user