summaryrefslogtreecommitdiffstats
path: root/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt')
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt175
1 files changed, 120 insertions, 55 deletions
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)
}
}