summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authort895 <clombardo169@gmail.com>2023-12-11 02:45:02 +0100
committert895 <clombardo169@gmail.com>2023-12-12 23:25:37 +0100
commitf2eb3c579f2de15410681014b47779d44d77fd48 (patch)
treeda874862efd26f0ebfdc84e7ea9b56d295032dde
parentandroid: Add per-game settings (diff)
downloadyuzu-f2eb3c579f2de15410681014b47779d44d77fd48.tar
yuzu-f2eb3c579f2de15410681014b47779d44d77fd48.tar.gz
yuzu-f2eb3c579f2de15410681014b47779d44d77fd48.tar.bz2
yuzu-f2eb3c579f2de15410681014b47779d44d77fd48.tar.lz
yuzu-f2eb3c579f2de15410681014b47779d44d77fd48.tar.xz
yuzu-f2eb3c579f2de15410681014b47779d44d77fd48.tar.zst
yuzu-f2eb3c579f2de15410681014b47779d44d77fd48.zip
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/DriverAdapter.kt2
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriverManagerFragment.kt14
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriversLoadingDialogFragment.kt18
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt24
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt15
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt17
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt175
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt10
-rw-r--r--src/android/app/src/main/jni/android_config.cpp19
-rw-r--r--src/android/app/src/main/jni/android_config.h2
-rw-r--r--src/android/app/src/main/jni/android_settings.h3
-rw-r--r--src/android/app/src/main/res/navigation/home_navigation.xml11
-rw-r--r--src/common/settings.cpp2
-rw-r--r--src/common/settings_common.h1
14 files changed, 218 insertions, 95 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/DriverAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/DriverAdapter.kt
index 0e818cab9..d290a656c 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/DriverAdapter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/DriverAdapter.kt
@@ -42,7 +42,7 @@ class DriverAdapter(private val driverViewModel: DriverViewModel) :
if (driverViewModel.selectedDriver > position) {
driverViewModel.setSelectedDriverIndex(driverViewModel.selectedDriver - 1)
}
- if (GpuDriverHelper.customDriverData == driverData.second) {
+ if (GpuDriverHelper.customDriverSettingData == driverData.second) {
driverViewModel.setSelectedDriverIndex(0)
}
driverViewModel.driversToDelete.add(driverData.first)
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriverManagerFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriverManagerFragment.kt
index df21d74b2..cc71254dc 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriverManagerFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriverManagerFragment.kt
@@ -15,6 +15,7 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.findNavController
+import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.GridLayoutManager
import com.google.android.material.transition.MaterialSharedAxis
import kotlinx.coroutines.flow.collectLatest
@@ -36,6 +37,8 @@ class DriverManagerFragment : Fragment() {
private val homeViewModel: HomeViewModel by activityViewModels()
private val driverViewModel: DriverViewModel by activityViewModels()
+ private val args by navArgs<DriverManagerFragmentArgs>()
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
@@ -57,7 +60,9 @@ class DriverManagerFragment : Fragment() {
homeViewModel.setNavigationVisibility(visible = false, animated = true)
homeViewModel.setStatusBarShadeVisibility(visible = false)
- if (!driverViewModel.isInteractionAllowed) {
+ driverViewModel.onOpenDriverManager(args.game)
+
+ if (!driverViewModel.isInteractionAllowed.value) {
DriversLoadingDialogFragment().show(
childFragmentManager,
DriversLoadingDialogFragment.TAG
@@ -102,10 +107,9 @@ class DriverManagerFragment : Fragment() {
setInsets()
}
- // Start installing requested driver
- override fun onStop() {
- super.onStop()
- driverViewModel.onCloseDriverManager()
+ override fun onDestroy() {
+ super.onDestroy()
+ driverViewModel.onCloseDriverManager(args.game)
}
private fun setInsets() =
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriversLoadingDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriversLoadingDialogFragment.kt
index f8c34346a..6a47b29f0 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriversLoadingDialogFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriversLoadingDialogFragment.kt
@@ -47,25 +47,9 @@ class DriversLoadingDialogFragment : DialogFragment() {
viewLifecycleOwner.lifecycleScope.apply {
launch {
repeatOnLifecycle(Lifecycle.State.RESUMED) {
- driverViewModel.areDriversLoading.collect { checkForDismiss() }
+ driverViewModel.isInteractionAllowed.collect { if (it) dismiss() }
}
}
- launch {
- repeatOnLifecycle(Lifecycle.State.RESUMED) {
- driverViewModel.isDriverReady.collect { checkForDismiss() }
- }
- }
- launch {
- repeatOnLifecycle(Lifecycle.State.RESUMED) {
- driverViewModel.isDeletingDrivers.collect { checkForDismiss() }
- }
- }
- }
- }
-
- private fun checkForDismiss() {
- if (driverViewModel.isInteractionAllowed) {
- dismiss()
}
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
index 6466442d5..c40f5f41a 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
@@ -352,15 +352,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
launch {
repeatOnLifecycle(Lifecycle.State.RESUMED) {
- driverViewModel.isDriverReady.collect {
- if (it && !emulationState.isRunning) {
- if (!DirectoryInitialization.areDirectoriesReady) {
- DirectoryInitialization.start()
- }
-
- updateScreenLayout()
-
- emulationState.run(emulationActivity!!.isActivityRecreated)
+ driverViewModel.isInteractionAllowed.collect {
+ if (it) {
+ onEmulationStart()
}
}
}
@@ -368,6 +362,18 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
}
+ private fun onEmulationStart() {
+ if (!NativeLibrary.isRunning() && !NativeLibrary.isPaused()) {
+ if (!DirectoryInitialization.areDirectoriesReady) {
+ DirectoryInitialization.start()
+ }
+
+ updateScreenLayout()
+
+ emulationState.run(emulationActivity!!.isActivityRecreated)
+ }
+ }
+
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
if (_binding == null) {
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt
index 485989e2e..e062425a1 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt
@@ -148,6 +148,21 @@ class GamePropertiesFragment : Fragment() {
}
)
+ if (GpuDriverHelper.supportsCustomDriverLoading()) {
+ add(
+ SubmenuProperty(
+ R.string.gpu_driver_manager,
+ R.string.install_gpu_driver_description,
+ R.drawable.ic_build,
+ detailsFlow = driverViewModel.selectedDriverTitle
+ ) {
+ val action = GamePropertiesFragmentDirections
+ .actionPerGamePropertiesFragmentToDriverManagerFragment(args.game)
+ binding.root.findNavController().navigate(action)
+ }
+ )
+ }
+
if (!args.game.isHomebrew) {
add(
SubmenuProperty(
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt
index 3addc2e63..6ddd758e6 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt
@@ -68,6 +68,9 @@ class HomeSettingsFragment : Fragment() {
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ homeViewModel.setNavigationVisibility(visible = true, animated = true)
+ homeViewModel.setStatusBarShadeVisibility(visible = true)
mainActivity = requireActivity() as MainActivity
val optionsList: MutableList<HomeSetting> = mutableListOf<HomeSetting>().apply {
@@ -91,13 +94,14 @@ class HomeSettingsFragment : Fragment() {
R.string.install_gpu_driver_description,
R.drawable.ic_build,
{
- binding.root.findNavController()
- .navigate(R.id.action_homeSettingsFragment_to_driverManagerFragment)
+ val action = HomeSettingsFragmentDirections
+ .actionHomeSettingsFragmentToDriverManagerFragment(null)
+ binding.root.findNavController().navigate(action)
},
{ GpuDriverHelper.supportsCustomDriverLoading() },
R.string.custom_driver_not_supported,
R.string.custom_driver_not_supported_description,
- driverViewModel.selectedDriverMetadata
+ driverViewModel.selectedDriverTitle
)
)
add(
@@ -212,8 +216,11 @@ class HomeSettingsFragment : Fragment() {
override fun onStart() {
super.onStart()
exitTransition = null
- homeViewModel.setNavigationVisibility(visible = true, animated = true)
- homeViewModel.setStatusBarShadeVisibility(visible = true)
+ }
+
+ override fun onResume() {
+ super.onResume()
+ driverViewModel.updateDriverNameForGame(null)
}
override fun onDestroyView() {
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt
index 62945ad65..76accf8f3 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt
@@ -7,81 +7,83 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.YuzuApplication
+import org.yuzu.yuzu_emu.features.settings.model.StringSetting
+import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
import org.yuzu.yuzu_emu.utils.FileUtil
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
import org.yuzu.yuzu_emu.utils.GpuDriverMetadata
+import org.yuzu.yuzu_emu.utils.NativeConfig
import java.io.BufferedOutputStream
import java.io.File
class DriverViewModel : ViewModel() {
private val _areDriversLoading = MutableStateFlow(false)
- val areDriversLoading: StateFlow<Boolean> get() = _areDriversLoading
-
private val _isDriverReady = MutableStateFlow(true)
- val isDriverReady: StateFlow<Boolean> get() = _isDriverReady
-
private val _isDeletingDrivers = MutableStateFlow(false)
- val isDeletingDrivers: StateFlow<Boolean> get() = _isDeletingDrivers
- private val _driverList = MutableStateFlow(mutableListOf<Pair<String, GpuDriverMetadata>>())
+ val isInteractionAllowed: StateFlow<Boolean> =
+ combine(
+ _areDriversLoading,
+ _isDriverReady,
+ _isDeletingDrivers
+ ) { loading, ready, deleting ->
+ !loading && ready && !deleting
+ }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), initialValue = false)
+
+ private val _driverList = MutableStateFlow(GpuDriverHelper.getDrivers())
val driverList: StateFlow<MutableList<Pair<String, GpuDriverMetadata>>> get() = _driverList
var previouslySelectedDriver = 0
var selectedDriver = -1
- private val _selectedDriverMetadata =
- MutableStateFlow(
- GpuDriverHelper.customDriverData.name
- ?: YuzuApplication.appContext.getString(R.string.system_gpu_driver)
- )
- val selectedDriverMetadata: StateFlow<String> get() = _selectedDriverMetadata
+ // Used for showing which driver is currently installed within the driver manager card
+ private val _selectedDriverTitle = MutableStateFlow("")
+ val selectedDriverTitle: StateFlow<String> get() = _selectedDriverTitle
private val _newDriverInstalled = MutableStateFlow(false)
val newDriverInstalled: StateFlow<Boolean> get() = _newDriverInstalled
val driversToDelete = mutableListOf<String>()
- val isInteractionAllowed
- get() = !areDriversLoading.value && isDriverReady.value && !isDeletingDrivers.value
-
init {
- _areDriversLoading.value = true
- viewModelScope.launch {
- withContext(Dispatchers.IO) {
- val drivers = GpuDriverHelper.getDrivers()
- val currentDriverMetadata = GpuDriverHelper.customDriverData
- for (i in drivers.indices) {
- if (drivers[i].second == currentDriverMetadata) {
- setSelectedDriverIndex(i)
- break
- }
- }
-
- // If a user had installed a driver before the manager was implemented, this zips
- // the installed driver to UserData/gpu_drivers/CustomDriver.zip so that it can
- // be indexed and exported as expected.
- if (selectedDriver == -1) {
- val driverToSave =
- File(GpuDriverHelper.driverStoragePath, "CustomDriver.zip")
- driverToSave.createNewFile()
- FileUtil.zipFromInternalStorage(
- File(GpuDriverHelper.driverInstallationPath!!),
- GpuDriverHelper.driverInstallationPath!!,
- BufferedOutputStream(driverToSave.outputStream())
- )
- drivers.add(Pair(driverToSave.path, currentDriverMetadata))
- setSelectedDriverIndex(drivers.size - 1)
- }
+ val currentDriverMetadata = GpuDriverHelper.installedCustomDriverData
+ findSelectedDriver(currentDriverMetadata)
+
+ // If a user had installed a driver before the manager was implemented, this zips
+ // the installed driver to UserData/gpu_drivers/CustomDriver.zip so that it can
+ // be indexed and exported as expected.
+ if (selectedDriver == -1) {
+ val driverToSave =
+ File(GpuDriverHelper.driverStoragePath, "CustomDriver.zip")
+ driverToSave.createNewFile()
+ FileUtil.zipFromInternalStorage(
+ File(GpuDriverHelper.driverInstallationPath!!),
+ GpuDriverHelper.driverInstallationPath!!,
+ BufferedOutputStream(driverToSave.outputStream())
+ )
+ _driverList.value.add(Pair(driverToSave.path, currentDriverMetadata))
+ setSelectedDriverIndex(_driverList.value.size - 1)
+ }
- _driverList.value = drivers
- _areDriversLoading.value = false
- }
+ // If a user had installed a driver before the config was reworked to be multiplatform,
+ // we have save the path of the previously selected driver to the new setting.
+ if (StringSetting.DRIVER_PATH.getString(true).isEmpty() && selectedDriver > 0 &&
+ StringSetting.DRIVER_PATH.global
+ ) {
+ StringSetting.DRIVER_PATH.setString(_driverList.value[selectedDriver].first)
+ NativeConfig.saveGlobalConfig()
+ } else {
+ findSelectedDriver(GpuDriverHelper.customDriverSettingData)
}
+ updateDriverNameForGame(null)
}
fun setSelectedDriverIndex(value: Int) {
@@ -98,9 +100,9 @@ class DriverViewModel : ViewModel() {
fun addDriver(driverData: Pair<String, GpuDriverMetadata>) {
val driverIndex = _driverList.value.indexOfFirst { it == driverData }
if (driverIndex == -1) {
- setSelectedDriverIndex(_driverList.value.size)
_driverList.value.add(driverData)
- _selectedDriverMetadata.value = driverData.second.name
+ setSelectedDriverIndex(_driverList.value.size - 1)
+ _selectedDriverTitle.value = driverData.second.name
?: YuzuApplication.appContext.getString(R.string.system_gpu_driver)
} else {
setSelectedDriverIndex(driverIndex)
@@ -111,8 +113,31 @@ class DriverViewModel : ViewModel() {
_driverList.value.remove(driverData)
}
- fun onCloseDriverManager() {
+ fun onOpenDriverManager(game: Game?) {
+ if (game != null) {
+ SettingsFile.loadCustomConfig(game)
+ }
+
+ val driverPath = StringSetting.DRIVER_PATH.getString()
+ if (driverPath.isEmpty()) {
+ setSelectedDriverIndex(0)
+ } else {
+ findSelectedDriver(GpuDriverHelper.getMetadataFromZip(File(driverPath)))
+ }
+ }
+
+ fun onCloseDriverManager(game: Game?) {
_isDeletingDrivers.value = true
+ StringSetting.DRIVER_PATH.setString(driverList.value[selectedDriver].first)
+ updateDriverNameForGame(game)
+ if (game == null) {
+ NativeConfig.saveGlobalConfig()
+ } else {
+ NativeConfig.savePerGameConfig()
+ NativeConfig.unloadPerGameConfig()
+ NativeConfig.reloadGlobalConfig()
+ }
+
viewModelScope.launch {
withContext(Dispatchers.IO) {
driversToDelete.forEach {
@@ -125,23 +150,29 @@ class DriverViewModel : ViewModel() {
_isDeletingDrivers.value = false
}
}
+ }
+
+ // It is the Emulation Fragment's responsibility to load per-game settings so that this function
+ // knows what driver to load.
+ fun onLaunchGame() {
+ _isDriverReady.value = false
- if (GpuDriverHelper.customDriverData == driverList.value[selectedDriver].second) {
+ val selectedDriverFile = File(StringSetting.DRIVER_PATH.getString())
+ val selectedDriverMetadata = GpuDriverHelper.customDriverSettingData
+ if (GpuDriverHelper.installedCustomDriverData == selectedDriverMetadata) {
return
}
- _isDriverReady.value = false
viewModelScope.launch {
withContext(Dispatchers.IO) {
- if (selectedDriver == 0) {
+ if (selectedDriverMetadata.name == null) {
GpuDriverHelper.installDefaultDriver()
setDriverReady()
return@withContext
}
- val driverToInstall = File(driverList.value[selectedDriver].first)
- if (driverToInstall.exists()) {
- GpuDriverHelper.installCustomDriver(driverToInstall)
+ if (selectedDriverFile.exists()) {
+ GpuDriverHelper.installCustomDriver(selectedDriverFile)
} else {
GpuDriverHelper.installDefaultDriver()
}
@@ -150,9 +181,43 @@ class DriverViewModel : ViewModel() {
}
}
+ private fun findSelectedDriver(currentDriverMetadata: GpuDriverMetadata) {
+ if (driverList.value.size == 1) {
+ setSelectedDriverIndex(0)
+ return
+ }
+
+ driverList.value.forEachIndexed { i: Int, driver: Pair<String, GpuDriverMetadata> ->
+ if (driver.second == currentDriverMetadata) {
+ setSelectedDriverIndex(i)
+ return
+ }
+ }
+ }
+
+ fun updateDriverNameForGame(game: Game?) {
+ if (!GpuDriverHelper.supportsCustomDriverLoading()) {
+ return
+ }
+
+ if (game == null || NativeConfig.isPerGameConfigLoaded()) {
+ updateName()
+ } else {
+ SettingsFile.loadCustomConfig(game)
+ updateName()
+ NativeConfig.unloadPerGameConfig()
+ NativeConfig.reloadGlobalConfig()
+ }
+ }
+
+ private fun updateName() {
+ _selectedDriverTitle.value = GpuDriverHelper.customDriverSettingData.name
+ ?: YuzuApplication.appContext.getString(R.string.system_gpu_driver)
+ }
+
private fun setDriverReady() {
_isDriverReady.value = true
- _selectedDriverMetadata.value = GpuDriverHelper.customDriverData.name
+ _selectedDriverTitle.value = GpuDriverHelper.customDriverSettingData.name
?: YuzuApplication.appContext.getString(R.string.system_gpu_driver)
}
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt
index f6882ce6c..685272288 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt
@@ -10,6 +10,8 @@ import java.io.File
import java.io.IOException
import org.yuzu.yuzu_emu.NativeLibrary
import org.yuzu.yuzu_emu.YuzuApplication
+import org.yuzu.yuzu_emu.features.settings.model.StringSetting
+import java.io.FileNotFoundException
import java.util.zip.ZipException
import java.util.zip.ZipFile
@@ -44,7 +46,7 @@ object GpuDriverHelper {
NativeLibrary.initializeGpuDriver(
hookLibPath,
driverInstallationPath,
- customDriverData.libraryName,
+ installedCustomDriverData.libraryName,
fileRedirectionPath
)
}
@@ -190,6 +192,7 @@ object GpuDriverHelper {
}
}
} catch (_: ZipException) {
+ } catch (_: FileNotFoundException) {
}
return GpuDriverMetadata()
}
@@ -197,9 +200,12 @@ object GpuDriverHelper {
external fun supportsCustomDriverLoading(): Boolean
// Parse the custom driver metadata to retrieve the name.
- val customDriverData: GpuDriverMetadata
+ val installedCustomDriverData: GpuDriverMetadata
get() = GpuDriverMetadata(File(driverInstallationPath + META_JSON_FILENAME))
+ val customDriverSettingData: GpuDriverMetadata
+ get() = getMetadataFromZip(File(StringSetting.DRIVER_PATH.getString()))
+
fun initializeDirectories() {
// Ensure the file redirection directory exists.
val fileRedirectionDir = File(fileRedirectionPath!!)
diff --git a/src/android/app/src/main/jni/android_config.cpp b/src/android/app/src/main/jni/android_config.cpp
index 767d8ea83..9c3a5a9b2 100644
--- a/src/android/app/src/main/jni/android_config.cpp
+++ b/src/android/app/src/main/jni/android_config.cpp
@@ -36,6 +36,7 @@ void AndroidConfig::ReadAndroidValues() {
ReadAndroidUIValues();
ReadUIValues();
}
+ ReadDriverValues();
}
void AndroidConfig::ReadAndroidUIValues() {
@@ -57,6 +58,7 @@ void AndroidConfig::ReadUIValues() {
void AndroidConfig::ReadPathValues() {
BeginGroup(Settings::TranslateCategory(Settings::Category::Paths));
+ AndroidSettings::values.game_dirs.clear();
const int gamedirs_size = BeginArray(std::string("gamedirs"));
for (int i = 0; i < gamedirs_size; ++i) {
SetArrayIndex(i);
@@ -71,11 +73,20 @@ void AndroidConfig::ReadPathValues() {
EndGroup();
}
+void AndroidConfig::ReadDriverValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::GpuDriver));
+
+ ReadCategory(Settings::Category::GpuDriver);
+
+ EndGroup();
+}
+
void AndroidConfig::SaveAndroidValues() {
if (global) {
SaveAndroidUIValues();
SaveUIValues();
}
+ SaveDriverValues();
WriteToIni();
}
@@ -111,6 +122,14 @@ void AndroidConfig::SavePathValues() {
EndGroup();
}
+void AndroidConfig::SaveDriverValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::GpuDriver));
+
+ WriteCategory(Settings::Category::GpuDriver);
+
+ EndGroup();
+}
+
std::vector<Settings::BasicSetting*>& AndroidConfig::FindRelevantList(Settings::Category category) {
auto& map = Settings::values.linkage.by_category;
if (map.contains(category)) {
diff --git a/src/android/app/src/main/jni/android_config.h b/src/android/app/src/main/jni/android_config.h
index f490be016..2c12874e1 100644
--- a/src/android/app/src/main/jni/android_config.h
+++ b/src/android/app/src/main/jni/android_config.h
@@ -17,6 +17,7 @@ public:
protected:
void ReadAndroidValues();
void ReadAndroidUIValues();
+ void ReadDriverValues();
void ReadHidbusValues() override {}
void ReadDebugControlValues() override {}
void ReadPathValues() override;
@@ -28,6 +29,7 @@ protected:
void SaveAndroidValues();
void SaveAndroidUIValues();
+ void SaveDriverValues();
void SaveHidbusValues() override {}
void SaveDebugControlValues() override {}
void SavePathValues() override;
diff --git a/src/android/app/src/main/jni/android_settings.h b/src/android/app/src/main/jni/android_settings.h
index fc0523206..3733f5a3c 100644
--- a/src/android/app/src/main/jni/android_settings.h
+++ b/src/android/app/src/main/jni/android_settings.h
@@ -30,6 +30,9 @@ struct Values {
Settings::Specialization::Default,
true,
true};
+
+ Settings::SwitchableSetting<std::string, false> driver_path{linkage, "", "driver_path",
+ Settings::Category::GpuDriver};
};
extern Values values;
diff --git a/src/android/app/src/main/res/navigation/home_navigation.xml b/src/android/app/src/main/res/navigation/home_navigation.xml
index 226cf5600..37a03a8d1 100644
--- a/src/android/app/src/main/res/navigation/home_navigation.xml
+++ b/src/android/app/src/main/res/navigation/home_navigation.xml
@@ -111,7 +111,13 @@
<fragment
android:id="@+id/driverManagerFragment"
android:name="org.yuzu.yuzu_emu.fragments.DriverManagerFragment"
- android:label="DriverManagerFragment" />
+ android:label="DriverManagerFragment" >
+ <argument
+ android:name="game"
+ app:argType="org.yuzu.yuzu_emu.model.Game"
+ app:nullable="true"
+ android:defaultValue="@null" />
+ </fragment>
<fragment
android:id="@+id/appletLauncherFragment"
android:name="org.yuzu.yuzu_emu.fragments.AppletLauncherFragment"
@@ -141,6 +147,9 @@
<action
android:id="@+id/action_perGamePropertiesFragment_to_addonsFragment"
app:destination="@id/addonsFragment" />
+ <action
+ android:id="@+id/action_perGamePropertiesFragment_to_driverManagerFragment"
+ app:destination="@id/driverManagerFragment" />
</fragment>
<action
android:id="@+id/action_global_perGamePropertiesFragment"
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 88f509ba7..ea52bbfa6 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -211,6 +211,8 @@ const char* TranslateCategory(Category category) {
case Category::Debugging:
case Category::DebuggingGraphics:
return "Debugging";
+ case Category::GpuDriver:
+ return "GpuDriver";
case Category::Miscellaneous:
return "Miscellaneous";
case Category::Network:
diff --git a/src/common/settings_common.h b/src/common/settings_common.h
index 344c04439..c82e17495 100644
--- a/src/common/settings_common.h
+++ b/src/common/settings_common.h
@@ -26,6 +26,7 @@ enum class Category : u32 {
DataStorage,
Debugging,
DebuggingGraphics,
+ GpuDriver,
Miscellaneous,
Network,
WebService,