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) {
|
||||
driverViewModel.setSelectedDriverIndex(driverViewModel.selectedDriver - 1)
|
||||
}
|
||||
if (GpuDriverHelper.customDriverData == driverData.second) {
|
||||
if (GpuDriverHelper.customDriverSettingData == driverData.second) {
|
||||
driverViewModel.setSelectedDriverIndex(0)
|
||||
}
|
||||
driverViewModel.driversToDelete.add(driverData.first)
|
||||
|
|
|
@ -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() =
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
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())
|
||||
)
|
||||
drivers.add(Pair(driverToSave.path, currentDriverMetadata))
|
||||
setSelectedDriverIndex(drivers.size - 1)
|
||||
}
|
||||
|
||||
_driverList.value = drivers
|
||||
_areDriversLoading.value = false
|
||||
}
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
_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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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!!)
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -26,6 +26,7 @@ enum class Category : u32 {
|
|||
DataStorage,
|
||||
Debugging,
|
||||
DebuggingGraphics,
|
||||
GpuDriver,
|
||||
Miscellaneous,
|
||||
Network,
|
||||
WebService,
|
||||
|
|
Loading…
Reference in a new issue