mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-11-11 12:34:57 +00:00
android: Add per-game drivers
This commit is contained in:
parent
2fce812026
commit
f2eb3c579f
14 changed files with 218 additions and 95 deletions
|
@ -42,7 +42,7 @@ class DriverAdapter(private val driverViewModel: DriverViewModel) :
|
||||||
if (driverViewModel.selectedDriver > position) {
|
if (driverViewModel.selectedDriver > position) {
|
||||||
driverViewModel.setSelectedDriverIndex(driverViewModel.selectedDriver - 1)
|
driverViewModel.setSelectedDriverIndex(driverViewModel.selectedDriver - 1)
|
||||||
}
|
}
|
||||||
if (GpuDriverHelper.customDriverData == driverData.second) {
|
if (GpuDriverHelper.customDriverSettingData == driverData.second) {
|
||||||
driverViewModel.setSelectedDriverIndex(0)
|
driverViewModel.setSelectedDriverIndex(0)
|
||||||
}
|
}
|
||||||
driverViewModel.driversToDelete.add(driverData.first)
|
driverViewModel.driversToDelete.add(driverData.first)
|
||||||
|
|
|
@ -15,6 +15,7 @@ import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
|
import androidx.navigation.fragment.navArgs
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import com.google.android.material.transition.MaterialSharedAxis
|
import com.google.android.material.transition.MaterialSharedAxis
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
@ -36,6 +37,8 @@ class DriverManagerFragment : Fragment() {
|
||||||
private val homeViewModel: HomeViewModel by activityViewModels()
|
private val homeViewModel: HomeViewModel by activityViewModels()
|
||||||
private val driverViewModel: DriverViewModel by activityViewModels()
|
private val driverViewModel: DriverViewModel by activityViewModels()
|
||||||
|
|
||||||
|
private val args by navArgs<DriverManagerFragmentArgs>()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
|
enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
|
||||||
|
@ -57,7 +60,9 @@ class DriverManagerFragment : Fragment() {
|
||||||
homeViewModel.setNavigationVisibility(visible = false, animated = true)
|
homeViewModel.setNavigationVisibility(visible = false, animated = true)
|
||||||
homeViewModel.setStatusBarShadeVisibility(visible = false)
|
homeViewModel.setStatusBarShadeVisibility(visible = false)
|
||||||
|
|
||||||
if (!driverViewModel.isInteractionAllowed) {
|
driverViewModel.onOpenDriverManager(args.game)
|
||||||
|
|
||||||
|
if (!driverViewModel.isInteractionAllowed.value) {
|
||||||
DriversLoadingDialogFragment().show(
|
DriversLoadingDialogFragment().show(
|
||||||
childFragmentManager,
|
childFragmentManager,
|
||||||
DriversLoadingDialogFragment.TAG
|
DriversLoadingDialogFragment.TAG
|
||||||
|
@ -102,10 +107,9 @@ class DriverManagerFragment : Fragment() {
|
||||||
setInsets()
|
setInsets()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start installing requested driver
|
override fun onDestroy() {
|
||||||
override fun onStop() {
|
super.onDestroy()
|
||||||
super.onStop()
|
driverViewModel.onCloseDriverManager(args.game)
|
||||||
driverViewModel.onCloseDriverManager()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setInsets() =
|
private fun setInsets() =
|
||||||
|
|
|
@ -47,25 +47,9 @@ class DriversLoadingDialogFragment : DialogFragment() {
|
||||||
viewLifecycleOwner.lifecycleScope.apply {
|
viewLifecycleOwner.lifecycleScope.apply {
|
||||||
launch {
|
launch {
|
||||||
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -352,15 +352,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
}
|
}
|
||||||
launch {
|
launch {
|
||||||
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||||
driverViewModel.isDriverReady.collect {
|
driverViewModel.isInteractionAllowed.collect {
|
||||||
if (it && !emulationState.isRunning) {
|
if (it) {
|
||||||
if (!DirectoryInitialization.areDirectoriesReady) {
|
onEmulationStart()
|
||||||
DirectoryInitialization.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
updateScreenLayout()
|
|
||||||
|
|
||||||
emulationState.run(emulationActivity!!.isActivityRecreated)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||||
super.onConfigurationChanged(newConfig)
|
super.onConfigurationChanged(newConfig)
|
||||||
if (_binding == null) {
|
if (_binding == null) {
|
||||||
|
|
|
@ -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) {
|
if (!args.game.isHomebrew) {
|
||||||
add(
|
add(
|
||||||
SubmenuProperty(
|
SubmenuProperty(
|
||||||
|
|
|
@ -68,6 +68,9 @@ class HomeSettingsFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
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
|
mainActivity = requireActivity() as MainActivity
|
||||||
|
|
||||||
val optionsList: MutableList<HomeSetting> = mutableListOf<HomeSetting>().apply {
|
val optionsList: MutableList<HomeSetting> = mutableListOf<HomeSetting>().apply {
|
||||||
|
@ -91,13 +94,14 @@ class HomeSettingsFragment : Fragment() {
|
||||||
R.string.install_gpu_driver_description,
|
R.string.install_gpu_driver_description,
|
||||||
R.drawable.ic_build,
|
R.drawable.ic_build,
|
||||||
{
|
{
|
||||||
binding.root.findNavController()
|
val action = HomeSettingsFragmentDirections
|
||||||
.navigate(R.id.action_homeSettingsFragment_to_driverManagerFragment)
|
.actionHomeSettingsFragmentToDriverManagerFragment(null)
|
||||||
|
binding.root.findNavController().navigate(action)
|
||||||
},
|
},
|
||||||
{ GpuDriverHelper.supportsCustomDriverLoading() },
|
{ GpuDriverHelper.supportsCustomDriverLoading() },
|
||||||
R.string.custom_driver_not_supported,
|
R.string.custom_driver_not_supported,
|
||||||
R.string.custom_driver_not_supported_description,
|
R.string.custom_driver_not_supported_description,
|
||||||
driverViewModel.selectedDriverMetadata
|
driverViewModel.selectedDriverTitle
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
|
@ -212,8 +216,11 @@ class HomeSettingsFragment : Fragment() {
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
exitTransition = null
|
exitTransition = null
|
||||||
homeViewModel.setNavigationVisibility(visible = true, animated = true)
|
}
|
||||||
homeViewModel.setStatusBarShadeVisibility(visible = true)
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
driverViewModel.updateDriverNameForGame(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
|
|
@ -7,81 +7,83 @@ import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.yuzu.yuzu_emu.R
|
import org.yuzu.yuzu_emu.R
|
||||||
import org.yuzu.yuzu_emu.YuzuApplication
|
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.FileUtil
|
||||||
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
|
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
|
||||||
import org.yuzu.yuzu_emu.utils.GpuDriverMetadata
|
import org.yuzu.yuzu_emu.utils.GpuDriverMetadata
|
||||||
|
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||||
import java.io.BufferedOutputStream
|
import java.io.BufferedOutputStream
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class DriverViewModel : ViewModel() {
|
class DriverViewModel : ViewModel() {
|
||||||
private val _areDriversLoading = MutableStateFlow(false)
|
private val _areDriversLoading = MutableStateFlow(false)
|
||||||
val areDriversLoading: StateFlow<Boolean> get() = _areDriversLoading
|
|
||||||
|
|
||||||
private val _isDriverReady = MutableStateFlow(true)
|
private val _isDriverReady = MutableStateFlow(true)
|
||||||
val isDriverReady: StateFlow<Boolean> get() = _isDriverReady
|
|
||||||
|
|
||||||
private val _isDeletingDrivers = MutableStateFlow(false)
|
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
|
val driverList: StateFlow<MutableList<Pair<String, GpuDriverMetadata>>> get() = _driverList
|
||||||
|
|
||||||
var previouslySelectedDriver = 0
|
var previouslySelectedDriver = 0
|
||||||
var selectedDriver = -1
|
var selectedDriver = -1
|
||||||
|
|
||||||
private val _selectedDriverMetadata =
|
// Used for showing which driver is currently installed within the driver manager card
|
||||||
MutableStateFlow(
|
private val _selectedDriverTitle = MutableStateFlow("")
|
||||||
GpuDriverHelper.customDriverData.name
|
val selectedDriverTitle: StateFlow<String> get() = _selectedDriverTitle
|
||||||
?: YuzuApplication.appContext.getString(R.string.system_gpu_driver)
|
|
||||||
)
|
|
||||||
val selectedDriverMetadata: StateFlow<String> get() = _selectedDriverMetadata
|
|
||||||
|
|
||||||
private val _newDriverInstalled = MutableStateFlow(false)
|
private val _newDriverInstalled = MutableStateFlow(false)
|
||||||
val newDriverInstalled: StateFlow<Boolean> get() = _newDriverInstalled
|
val newDriverInstalled: StateFlow<Boolean> get() = _newDriverInstalled
|
||||||
|
|
||||||
val driversToDelete = mutableListOf<String>()
|
val driversToDelete = mutableListOf<String>()
|
||||||
|
|
||||||
val isInteractionAllowed
|
|
||||||
get() = !areDriversLoading.value && isDriverReady.value && !isDeletingDrivers.value
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
_areDriversLoading.value = true
|
val currentDriverMetadata = GpuDriverHelper.installedCustomDriverData
|
||||||
viewModelScope.launch {
|
findSelectedDriver(currentDriverMetadata)
|
||||||
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
|
// 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
|
// the installed driver to UserData/gpu_drivers/CustomDriver.zip so that it can
|
||||||
// be indexed and exported as expected.
|
// be indexed and exported as expected.
|
||||||
if (selectedDriver == -1) {
|
if (selectedDriver == -1) {
|
||||||
val driverToSave =
|
val driverToSave =
|
||||||
File(GpuDriverHelper.driverStoragePath, "CustomDriver.zip")
|
File(GpuDriverHelper.driverStoragePath, "CustomDriver.zip")
|
||||||
driverToSave.createNewFile()
|
driverToSave.createNewFile()
|
||||||
FileUtil.zipFromInternalStorage(
|
FileUtil.zipFromInternalStorage(
|
||||||
File(GpuDriverHelper.driverInstallationPath!!),
|
File(GpuDriverHelper.driverInstallationPath!!),
|
||||||
GpuDriverHelper.driverInstallationPath!!,
|
GpuDriverHelper.driverInstallationPath!!,
|
||||||
BufferedOutputStream(driverToSave.outputStream())
|
BufferedOutputStream(driverToSave.outputStream())
|
||||||
)
|
)
|
||||||
drivers.add(Pair(driverToSave.path, currentDriverMetadata))
|
_driverList.value.add(Pair(driverToSave.path, currentDriverMetadata))
|
||||||
setSelectedDriverIndex(drivers.size - 1)
|
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) {
|
fun setSelectedDriverIndex(value: Int) {
|
||||||
|
@ -98,9 +100,9 @@ class DriverViewModel : ViewModel() {
|
||||||
fun addDriver(driverData: Pair<String, GpuDriverMetadata>) {
|
fun addDriver(driverData: Pair<String, GpuDriverMetadata>) {
|
||||||
val driverIndex = _driverList.value.indexOfFirst { it == driverData }
|
val driverIndex = _driverList.value.indexOfFirst { it == driverData }
|
||||||
if (driverIndex == -1) {
|
if (driverIndex == -1) {
|
||||||
setSelectedDriverIndex(_driverList.value.size)
|
|
||||||
_driverList.value.add(driverData)
|
_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)
|
?: YuzuApplication.appContext.getString(R.string.system_gpu_driver)
|
||||||
} else {
|
} else {
|
||||||
setSelectedDriverIndex(driverIndex)
|
setSelectedDriverIndex(driverIndex)
|
||||||
|
@ -111,8 +113,31 @@ class DriverViewModel : ViewModel() {
|
||||||
_driverList.value.remove(driverData)
|
_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
|
_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 {
|
viewModelScope.launch {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
driversToDelete.forEach {
|
driversToDelete.forEach {
|
||||||
|
@ -125,23 +150,29 @@ class DriverViewModel : ViewModel() {
|
||||||
_isDeletingDrivers.value = false
|
_isDeletingDrivers.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (GpuDriverHelper.customDriverData == driverList.value[selectedDriver].second) {
|
// 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
|
||||||
|
|
||||||
|
val selectedDriverFile = File(StringSetting.DRIVER_PATH.getString())
|
||||||
|
val selectedDriverMetadata = GpuDriverHelper.customDriverSettingData
|
||||||
|
if (GpuDriverHelper.installedCustomDriverData == selectedDriverMetadata) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_isDriverReady.value = false
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
if (selectedDriver == 0) {
|
if (selectedDriverMetadata.name == null) {
|
||||||
GpuDriverHelper.installDefaultDriver()
|
GpuDriverHelper.installDefaultDriver()
|
||||||
setDriverReady()
|
setDriverReady()
|
||||||
return@withContext
|
return@withContext
|
||||||
}
|
}
|
||||||
|
|
||||||
val driverToInstall = File(driverList.value[selectedDriver].first)
|
if (selectedDriverFile.exists()) {
|
||||||
if (driverToInstall.exists()) {
|
GpuDriverHelper.installCustomDriver(selectedDriverFile)
|
||||||
GpuDriverHelper.installCustomDriver(driverToInstall)
|
|
||||||
} else {
|
} else {
|
||||||
GpuDriverHelper.installDefaultDriver()
|
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() {
|
private fun setDriverReady() {
|
||||||
_isDriverReady.value = true
|
_isDriverReady.value = true
|
||||||
_selectedDriverMetadata.value = GpuDriverHelper.customDriverData.name
|
_selectedDriverTitle.value = GpuDriverHelper.customDriverSettingData.name
|
||||||
?: YuzuApplication.appContext.getString(R.string.system_gpu_driver)
|
?: YuzuApplication.appContext.getString(R.string.system_gpu_driver)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import org.yuzu.yuzu_emu.NativeLibrary
|
import org.yuzu.yuzu_emu.NativeLibrary
|
||||||
import org.yuzu.yuzu_emu.YuzuApplication
|
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.ZipException
|
||||||
import java.util.zip.ZipFile
|
import java.util.zip.ZipFile
|
||||||
|
|
||||||
|
@ -44,7 +46,7 @@ object GpuDriverHelper {
|
||||||
NativeLibrary.initializeGpuDriver(
|
NativeLibrary.initializeGpuDriver(
|
||||||
hookLibPath,
|
hookLibPath,
|
||||||
driverInstallationPath,
|
driverInstallationPath,
|
||||||
customDriverData.libraryName,
|
installedCustomDriverData.libraryName,
|
||||||
fileRedirectionPath
|
fileRedirectionPath
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -190,6 +192,7 @@ object GpuDriverHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (_: ZipException) {
|
} catch (_: ZipException) {
|
||||||
|
} catch (_: FileNotFoundException) {
|
||||||
}
|
}
|
||||||
return GpuDriverMetadata()
|
return GpuDriverMetadata()
|
||||||
}
|
}
|
||||||
|
@ -197,9 +200,12 @@ object GpuDriverHelper {
|
||||||
external fun supportsCustomDriverLoading(): Boolean
|
external fun supportsCustomDriverLoading(): Boolean
|
||||||
|
|
||||||
// Parse the custom driver metadata to retrieve the name.
|
// Parse the custom driver metadata to retrieve the name.
|
||||||
val customDriverData: GpuDriverMetadata
|
val installedCustomDriverData: GpuDriverMetadata
|
||||||
get() = GpuDriverMetadata(File(driverInstallationPath + META_JSON_FILENAME))
|
get() = GpuDriverMetadata(File(driverInstallationPath + META_JSON_FILENAME))
|
||||||
|
|
||||||
|
val customDriverSettingData: GpuDriverMetadata
|
||||||
|
get() = getMetadataFromZip(File(StringSetting.DRIVER_PATH.getString()))
|
||||||
|
|
||||||
fun initializeDirectories() {
|
fun initializeDirectories() {
|
||||||
// Ensure the file redirection directory exists.
|
// Ensure the file redirection directory exists.
|
||||||
val fileRedirectionDir = File(fileRedirectionPath!!)
|
val fileRedirectionDir = File(fileRedirectionPath!!)
|
||||||
|
|
|
@ -36,6 +36,7 @@ void AndroidConfig::ReadAndroidValues() {
|
||||||
ReadAndroidUIValues();
|
ReadAndroidUIValues();
|
||||||
ReadUIValues();
|
ReadUIValues();
|
||||||
}
|
}
|
||||||
|
ReadDriverValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidConfig::ReadAndroidUIValues() {
|
void AndroidConfig::ReadAndroidUIValues() {
|
||||||
|
@ -57,6 +58,7 @@ void AndroidConfig::ReadUIValues() {
|
||||||
void AndroidConfig::ReadPathValues() {
|
void AndroidConfig::ReadPathValues() {
|
||||||
BeginGroup(Settings::TranslateCategory(Settings::Category::Paths));
|
BeginGroup(Settings::TranslateCategory(Settings::Category::Paths));
|
||||||
|
|
||||||
|
AndroidSettings::values.game_dirs.clear();
|
||||||
const int gamedirs_size = BeginArray(std::string("gamedirs"));
|
const int gamedirs_size = BeginArray(std::string("gamedirs"));
|
||||||
for (int i = 0; i < gamedirs_size; ++i) {
|
for (int i = 0; i < gamedirs_size; ++i) {
|
||||||
SetArrayIndex(i);
|
SetArrayIndex(i);
|
||||||
|
@ -71,11 +73,20 @@ void AndroidConfig::ReadPathValues() {
|
||||||
EndGroup();
|
EndGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AndroidConfig::ReadDriverValues() {
|
||||||
|
BeginGroup(Settings::TranslateCategory(Settings::Category::GpuDriver));
|
||||||
|
|
||||||
|
ReadCategory(Settings::Category::GpuDriver);
|
||||||
|
|
||||||
|
EndGroup();
|
||||||
|
}
|
||||||
|
|
||||||
void AndroidConfig::SaveAndroidValues() {
|
void AndroidConfig::SaveAndroidValues() {
|
||||||
if (global) {
|
if (global) {
|
||||||
SaveAndroidUIValues();
|
SaveAndroidUIValues();
|
||||||
SaveUIValues();
|
SaveUIValues();
|
||||||
}
|
}
|
||||||
|
SaveDriverValues();
|
||||||
|
|
||||||
WriteToIni();
|
WriteToIni();
|
||||||
}
|
}
|
||||||
|
@ -111,6 +122,14 @@ void AndroidConfig::SavePathValues() {
|
||||||
EndGroup();
|
EndGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AndroidConfig::SaveDriverValues() {
|
||||||
|
BeginGroup(Settings::TranslateCategory(Settings::Category::GpuDriver));
|
||||||
|
|
||||||
|
WriteCategory(Settings::Category::GpuDriver);
|
||||||
|
|
||||||
|
EndGroup();
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Settings::BasicSetting*>& AndroidConfig::FindRelevantList(Settings::Category category) {
|
std::vector<Settings::BasicSetting*>& AndroidConfig::FindRelevantList(Settings::Category category) {
|
||||||
auto& map = Settings::values.linkage.by_category;
|
auto& map = Settings::values.linkage.by_category;
|
||||||
if (map.contains(category)) {
|
if (map.contains(category)) {
|
||||||
|
|
|
@ -17,6 +17,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void ReadAndroidValues();
|
void ReadAndroidValues();
|
||||||
void ReadAndroidUIValues();
|
void ReadAndroidUIValues();
|
||||||
|
void ReadDriverValues();
|
||||||
void ReadHidbusValues() override {}
|
void ReadHidbusValues() override {}
|
||||||
void ReadDebugControlValues() override {}
|
void ReadDebugControlValues() override {}
|
||||||
void ReadPathValues() override;
|
void ReadPathValues() override;
|
||||||
|
@ -28,6 +29,7 @@ protected:
|
||||||
|
|
||||||
void SaveAndroidValues();
|
void SaveAndroidValues();
|
||||||
void SaveAndroidUIValues();
|
void SaveAndroidUIValues();
|
||||||
|
void SaveDriverValues();
|
||||||
void SaveHidbusValues() override {}
|
void SaveHidbusValues() override {}
|
||||||
void SaveDebugControlValues() override {}
|
void SaveDebugControlValues() override {}
|
||||||
void SavePathValues() override;
|
void SavePathValues() override;
|
||||||
|
|
|
@ -30,6 +30,9 @@ struct Values {
|
||||||
Settings::Specialization::Default,
|
Settings::Specialization::Default,
|
||||||
true,
|
true,
|
||||||
true};
|
true};
|
||||||
|
|
||||||
|
Settings::SwitchableSetting<std::string, false> driver_path{linkage, "", "driver_path",
|
||||||
|
Settings::Category::GpuDriver};
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Values values;
|
extern Values values;
|
||||||
|
|
|
@ -111,7 +111,13 @@
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/driverManagerFragment"
|
android:id="@+id/driverManagerFragment"
|
||||||
android:name="org.yuzu.yuzu_emu.fragments.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
|
<fragment
|
||||||
android:id="@+id/appletLauncherFragment"
|
android:id="@+id/appletLauncherFragment"
|
||||||
android:name="org.yuzu.yuzu_emu.fragments.AppletLauncherFragment"
|
android:name="org.yuzu.yuzu_emu.fragments.AppletLauncherFragment"
|
||||||
|
@ -141,6 +147,9 @@
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_perGamePropertiesFragment_to_addonsFragment"
|
android:id="@+id/action_perGamePropertiesFragment_to_addonsFragment"
|
||||||
app:destination="@id/addonsFragment" />
|
app:destination="@id/addonsFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_perGamePropertiesFragment_to_driverManagerFragment"
|
||||||
|
app:destination="@id/driverManagerFragment" />
|
||||||
</fragment>
|
</fragment>
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_global_perGamePropertiesFragment"
|
android:id="@+id/action_global_perGamePropertiesFragment"
|
||||||
|
|
|
@ -211,6 +211,8 @@ const char* TranslateCategory(Category category) {
|
||||||
case Category::Debugging:
|
case Category::Debugging:
|
||||||
case Category::DebuggingGraphics:
|
case Category::DebuggingGraphics:
|
||||||
return "Debugging";
|
return "Debugging";
|
||||||
|
case Category::GpuDriver:
|
||||||
|
return "GpuDriver";
|
||||||
case Category::Miscellaneous:
|
case Category::Miscellaneous:
|
||||||
return "Miscellaneous";
|
return "Miscellaneous";
|
||||||
case Category::Network:
|
case Category::Network:
|
||||||
|
|
|
@ -26,6 +26,7 @@ enum class Category : u32 {
|
||||||
DataStorage,
|
DataStorage,
|
||||||
Debugging,
|
Debugging,
|
||||||
DebuggingGraphics,
|
DebuggingGraphics,
|
||||||
|
GpuDriver,
|
||||||
Miscellaneous,
|
Miscellaneous,
|
||||||
Network,
|
Network,
|
||||||
WebService,
|
WebService,
|
||||||
|
|
Loading…
Reference in a new issue