diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
index a15c7fb73f..83746f8051 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
@@ -81,6 +81,25 @@ class SettingsFragmentPresenter(
sl.apply {
add(HeaderSetting(R.string.frame_gen))
+ val installed = LosslessScalingHelper.isInstalled()
+
+ add(
+ RunnableSetting(
+ titleId = if (installed) {
+ R.string.lossless_scaling_replace
+ } else {
+ R.string.lossless_scaling_install
+ },
+ descriptionId = if (installed) {
+ R.string.lossless_scaling_replace_description
+ } else {
+ R.string.lossless_scaling_install_description
+ },
+ isRunnable = !NativeLibrary.isRunning(),
+ iconId = R.drawable.ic_install
+ ) { settingsViewModel.setShouldShowLosslessInstaller(true) }
+ )
+
if (!LosslessScalingHelper.isSupportedByGpu()) {
add(
RunnableSetting(
@@ -92,28 +111,12 @@ class SettingsFragmentPresenter(
return@apply
}
- if (!LosslessScalingHelper.isInstalled()) {
- add(
- RunnableSetting(
- titleId = R.string.lossless_scaling_install,
- descriptionId = R.string.lossless_scaling_install_description,
- isRunnable = !NativeLibrary.isRunning(),
- iconId = R.drawable.ic_install
- ) { settingsViewModel.setShouldShowLosslessInstaller(true) }
- )
+ if (!installed) {
return@apply
}
add(BooleanSetting.RENDERER_FRAME_GEN.key)
add(BooleanSetting.RENDERER_FRAME_GEN_DUMP_FLOW.key)
- add(
- RunnableSetting(
- titleId = R.string.lossless_scaling_replace,
- descriptionId = R.string.lossless_scaling_replace_description,
- isRunnable = !NativeLibrary.isRunning(),
- iconId = R.drawable.ic_install
- ) { settingsViewModel.setShouldShowLosslessInstaller(true) }
- )
}
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SetupFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SetupFragment.kt
index 41f2da08a7..1bae6e5269 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SetupFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SetupFragment.kt
@@ -42,6 +42,7 @@ import org.yuzu.yuzu_emu.model.SetupPage
import org.yuzu.yuzu_emu.model.PageState
import org.yuzu.yuzu_emu.ui.main.MainActivity
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
+import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
import org.yuzu.yuzu_emu.utils.NativeConfig
import org.yuzu.yuzu_emu.utils.ViewUtils
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
@@ -202,6 +203,24 @@ class SetupFragment : Fragment() {
R.string.install_firmware_warning_help,
)
)
+ add(
+ PageButton(
+ R.drawable.ic_frames,
+ R.string.lossless_scaling,
+ R.string.lossless_scaling_setup_description,
+ {
+ pageButtonCallback = it
+ getLosslessDll.launch(arrayOf("*/*"))
+ },
+ {
+ if (LosslessScalingHelper.isInstalled()) {
+ ButtonState.BUTTON_ACTION_COMPLETE
+ } else {
+ ButtonState.BUTTON_ACTION_INCOMPLETE
+ }
+ }
+ )
+ )
add(
PageButton(
R.drawable.ic_controller,
@@ -446,6 +465,32 @@ class SetupFragment : Fragment() {
}
}
+ val getLosslessDll =
+ registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
+ if (result == null) {
+ return@registerForActivityResult
+ }
+
+ val resultStrings = resources.getStringArray(R.array.losslessDllResults)
+ ProgressDialogFragment.newInstance(
+ requireActivity(),
+ R.string.lossless_scaling_installing,
+ false
+ ) { _, _ ->
+ val installResult = LosslessScalingHelper.install(result)
+ if (installResult == LosslessScalingHelper.RESULT_OK) {
+ getString(R.string.lossless_scaling_install_success)
+ } else {
+ MessageDialogFragment.newInstance(
+ titleId = R.string.lossless_scaling_install_failed,
+ descriptionString = resultStrings[installResult]
+ )
+ }
+ }.apply {
+ onDialogComplete = { checkForButtonState.invoke() }
+ }.show(parentFragmentManager, ProgressDialogFragment.TAG)
+ }
+
val getGamesDirectory =
registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { result ->
if (result != null) {
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index d7abc3b42a..4153d77250 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -304,6 +304,7 @@
Write the optical flow mip levels to the lossless/debug folder once, for troubleshooting
Frame generation unavailable
This GPU driver does not support the Vulkan memory model, which the Lossless Scaling shaders require.
+ Optional. Provide your own Lossless.dll to enable frame generation later
Install Lossless.dll
Frame generation needs your own copy of Lossless.dll from Lossless Scaling
Select a different copy of Lossless.dll