14 changed files with 12 additions and 573 deletions
-
89src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/GpuUnswizzleSetting.kt
-
30src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
-
206src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/GpuUnswizzleDialogFragment.kt
-
12src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt
-
71src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/GpuUnswizzleViewHolder.kt
-
18src/android/app/src/main/res/values-ar/strings.xml
-
15src/android/app/src/main/res/values-de/strings.xml
-
18src/android/app/src/main/res/values-es/strings.xml
-
18src/android/app/src/main/res/values-ru/strings.xml
-
18src/android/app/src/main/res/values-uk/strings.xml
-
18src/android/app/src/main/res/values-zh-rCN/strings.xml
-
48src/android/app/src/main/res/values/arrays.xml
-
18src/android/app/src/main/res/values/strings.xml
-
6src/common/settings.h
@ -1,89 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
|
|
||||
package org.yuzu.yuzu_emu.features.settings.model.view |
|
||||
|
|
||||
import androidx.annotation.ArrayRes |
|
||||
import androidx.annotation.StringRes |
|
||||
import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting |
|
||||
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting |
|
||||
import org.yuzu.yuzu_emu.features.settings.model.IntSetting |
|
||||
|
|
||||
class GpuUnswizzleSetting( |
|
||||
@StringRes titleId: Int = 0, |
|
||||
titleString: String = "", |
|
||||
@StringRes descriptionId: Int = 0, |
|
||||
descriptionString: String = "", |
|
||||
@ArrayRes val textureSizeChoicesId: Int, |
|
||||
@ArrayRes val textureSizeValuesId: Int, |
|
||||
@ArrayRes val streamSizeChoicesId: Int, |
|
||||
@ArrayRes val streamSizeValuesId: Int, |
|
||||
@ArrayRes val chunkSizeChoicesId: Int, |
|
||||
@ArrayRes val chunkSizeValuesId: Int |
|
||||
) : SettingsItem( |
|
||||
object : AbstractSetting { |
|
||||
override val key: String = SettingsItem.GPU_UNSWIZZLE_COMBINED |
|
||||
override val defaultValue: Any = false |
|
||||
override val isSaveable = true |
|
||||
override val isRuntimeModifiable = true |
|
||||
override val isSwitchable = true |
|
||||
override val pairedSettingKey: String = "" |
|
||||
override var global: Boolean |
|
||||
get() { |
|
||||
return BooleanSetting.GPU_UNSWIZZLE_ENABLED.global && |
|
||||
IntSetting.GPU_UNSWIZZLE_TEXTURE_SIZE.global && |
|
||||
IntSetting.GPU_UNSWIZZLE_STREAM_SIZE.global && |
|
||||
IntSetting.GPU_UNSWIZZLE_CHUNK_SIZE.global |
|
||||
} |
|
||||
set(value) { |
|
||||
BooleanSetting.GPU_UNSWIZZLE_ENABLED.global = value |
|
||||
IntSetting.GPU_UNSWIZZLE_TEXTURE_SIZE.global = value |
|
||||
IntSetting.GPU_UNSWIZZLE_STREAM_SIZE.global = value |
|
||||
IntSetting.GPU_UNSWIZZLE_CHUNK_SIZE.global = value |
|
||||
} |
|
||||
override fun getValueAsString(needsGlobal: Boolean): String = "combined" |
|
||||
override fun reset() { |
|
||||
BooleanSetting.GPU_UNSWIZZLE_ENABLED.reset() |
|
||||
IntSetting.GPU_UNSWIZZLE_TEXTURE_SIZE.reset() |
|
||||
IntSetting.GPU_UNSWIZZLE_STREAM_SIZE.reset() |
|
||||
IntSetting.GPU_UNSWIZZLE_CHUNK_SIZE.reset() |
|
||||
} |
|
||||
}, |
|
||||
titleId, |
|
||||
titleString, |
|
||||
descriptionId, |
|
||||
descriptionString |
|
||||
) { |
|
||||
override val type = SettingsItem.TYPE_GPU_UNSWIZZLE |
|
||||
|
|
||||
// Check if GPU unswizzle is enabled via the dedicated boolean setting |
|
||||
fun isEnabled(needsGlobal: Boolean = false): Boolean = |
|
||||
BooleanSetting.GPU_UNSWIZZLE_ENABLED.getBoolean(needsGlobal) |
|
||||
|
|
||||
fun setEnabled(value: Boolean) = |
|
||||
BooleanSetting.GPU_UNSWIZZLE_ENABLED.setBoolean(value) |
|
||||
|
|
||||
fun enable() = setEnabled(true) |
|
||||
|
|
||||
fun disable() = setEnabled(false) |
|
||||
|
|
||||
fun getTextureSize(needsGlobal: Boolean = false): Int = |
|
||||
IntSetting.GPU_UNSWIZZLE_TEXTURE_SIZE.getInt(needsGlobal) |
|
||||
|
|
||||
fun setTextureSize(value: Int) = |
|
||||
IntSetting.GPU_UNSWIZZLE_TEXTURE_SIZE.setInt(value) |
|
||||
|
|
||||
fun getStreamSize(needsGlobal: Boolean = false): Int = |
|
||||
IntSetting.GPU_UNSWIZZLE_STREAM_SIZE.getInt(needsGlobal) |
|
||||
|
|
||||
fun setStreamSize(value: Int) = |
|
||||
IntSetting.GPU_UNSWIZZLE_STREAM_SIZE.setInt(value) |
|
||||
|
|
||||
fun getChunkSize(needsGlobal: Boolean = false): Int = |
|
||||
IntSetting.GPU_UNSWIZZLE_CHUNK_SIZE.getInt(needsGlobal) |
|
||||
|
|
||||
fun setChunkSize(value: Int) = |
|
||||
IntSetting.GPU_UNSWIZZLE_CHUNK_SIZE.setInt(value) |
|
||||
|
|
||||
fun reset() = setting.reset() |
|
||||
} |
|
||||
@ -1,206 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
|
|
||||
package org.yuzu.yuzu_emu.features.settings.ui |
|
||||
|
|
||||
import android.app.Dialog |
|
||||
import android.content.DialogInterface |
|
||||
import android.os.Bundle |
|
||||
import android.view.LayoutInflater |
|
||||
import android.widget.ArrayAdapter |
|
||||
import androidx.fragment.app.DialogFragment |
|
||||
import androidx.fragment.app.activityViewModels |
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder |
|
||||
import org.yuzu.yuzu_emu.R |
|
||||
import org.yuzu.yuzu_emu.databinding.DialogGpuUnswizzleBinding |
|
||||
import org.yuzu.yuzu_emu.features.settings.model.view.GpuUnswizzleSetting |
|
||||
|
|
||||
class GpuUnswizzleDialogFragment : DialogFragment() { |
|
||||
private var position = 0 |
|
||||
private val settingsViewModel: SettingsViewModel by activityViewModels() |
|
||||
private lateinit var binding: DialogGpuUnswizzleBinding |
|
||||
|
|
||||
override fun onCreate(savedInstanceState: Bundle?) { |
|
||||
super.onCreate(savedInstanceState) |
|
||||
position = requireArguments().getInt(POSITION) |
|
||||
|
|
||||
if (settingsViewModel.clickedItem == null) dismiss() |
|
||||
} |
|
||||
|
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { |
|
||||
binding = DialogGpuUnswizzleBinding.inflate(LayoutInflater.from(requireContext())) |
|
||||
val item = settingsViewModel.clickedItem as GpuUnswizzleSetting |
|
||||
|
|
||||
// Setup texture size dropdown |
|
||||
val textureSizeEntries = resources.getStringArray(item.textureSizeChoicesId) |
|
||||
val textureSizeValues = resources.getIntArray(item.textureSizeValuesId) |
|
||||
val textureSizeAdapter = ArrayAdapter( |
|
||||
requireContext(), |
|
||||
android.R.layout.simple_dropdown_item_1line, |
|
||||
textureSizeEntries.toMutableList() |
|
||||
) |
|
||||
binding.dropdownTextureSize.setAdapter(textureSizeAdapter) |
|
||||
|
|
||||
// Setup stream size dropdown |
|
||||
val streamSizeEntries = resources.getStringArray(item.streamSizeChoicesId) |
|
||||
val streamSizeValues = resources.getIntArray(item.streamSizeValuesId) |
|
||||
val streamSizeAdapter = ArrayAdapter( |
|
||||
requireContext(), |
|
||||
android.R.layout.simple_dropdown_item_1line, |
|
||||
streamSizeEntries.toMutableList() |
|
||||
) |
|
||||
binding.dropdownStreamSize.setAdapter(streamSizeAdapter) |
|
||||
|
|
||||
// Setup chunk size dropdown |
|
||||
val chunkSizeEntries = resources.getStringArray(item.chunkSizeChoicesId) |
|
||||
val chunkSizeValues = resources.getIntArray(item.chunkSizeValuesId) |
|
||||
val chunkSizeAdapter = ArrayAdapter( |
|
||||
requireContext(), |
|
||||
android.R.layout.simple_dropdown_item_1line, |
|
||||
chunkSizeEntries.toMutableList() |
|
||||
) |
|
||||
binding.dropdownChunkSize.setAdapter(chunkSizeAdapter) |
|
||||
|
|
||||
// Load current values |
|
||||
val isEnabled = item.isEnabled() |
|
||||
binding.switchEnable.isChecked = isEnabled |
|
||||
|
|
||||
if (isEnabled) { |
|
||||
val textureSizeIndex = textureSizeValues.indexOf(item.getTextureSize()) |
|
||||
if (textureSizeIndex >= 0) { |
|
||||
binding.dropdownTextureSize.setText(textureSizeEntries[textureSizeIndex], false) |
|
||||
} |
|
||||
|
|
||||
val streamSizeIndex = streamSizeValues.indexOf(item.getStreamSize()) |
|
||||
if (streamSizeIndex >= 0) { |
|
||||
binding.dropdownStreamSize.setText(streamSizeEntries[streamSizeIndex], false) |
|
||||
} |
|
||||
|
|
||||
val chunkSizeIndex = chunkSizeValues.indexOf(item.getChunkSize()) |
|
||||
if (chunkSizeIndex >= 0) { |
|
||||
binding.dropdownChunkSize.setText(chunkSizeEntries[chunkSizeIndex], false) |
|
||||
} |
|
||||
} else { |
|
||||
// Set default/recommended values when disabling |
|
||||
binding.dropdownTextureSize.setText(textureSizeEntries[3], false) |
|
||||
binding.dropdownStreamSize.setText(streamSizeEntries[3], false) |
|
||||
binding.dropdownChunkSize.setText(chunkSizeEntries[3], false) |
|
||||
} |
|
||||
|
|
||||
// Clear adapter filters after setText to fix rotation bug |
|
||||
textureSizeAdapter.filter.filter(null) |
|
||||
streamSizeAdapter.filter.filter(null) |
|
||||
chunkSizeAdapter.filter.filter(null) |
|
||||
|
|
||||
// Enable/disable dropdowns based on switch state |
|
||||
updateDropdownsState(isEnabled) |
|
||||
binding.switchEnable.setOnCheckedChangeListener { _, checked -> |
|
||||
updateDropdownsState(checked) |
|
||||
} |
|
||||
|
|
||||
val dialog = MaterialAlertDialogBuilder(requireContext()) |
|
||||
.setTitle(item.title) |
|
||||
.setView(binding.root) |
|
||||
.create() |
|
||||
|
|
||||
// Setup button listeners |
|
||||
binding.btnDefault.setOnClickListener { |
|
||||
// Reset to defaults |
|
||||
item.reset() |
|
||||
// Refresh values with adapters reset |
|
||||
val textureSizeIndex = textureSizeValues.indexOf(item.getTextureSize()) |
|
||||
if (textureSizeIndex >= 0) { |
|
||||
binding.dropdownTextureSize.setText(textureSizeEntries[textureSizeIndex], false) |
|
||||
} |
|
||||
val streamSizeIndex = streamSizeValues.indexOf(item.getStreamSize()) |
|
||||
if (streamSizeIndex >= 0) { |
|
||||
binding.dropdownStreamSize.setText(streamSizeEntries[streamSizeIndex], false) |
|
||||
} |
|
||||
val chunkSizeIndex = chunkSizeValues.indexOf(item.getChunkSize()) |
|
||||
if (chunkSizeIndex >= 0) { |
|
||||
binding.dropdownChunkSize.setText(chunkSizeEntries[chunkSizeIndex], false) |
|
||||
} |
|
||||
// Clear filters |
|
||||
textureSizeAdapter.filter.filter(null) |
|
||||
streamSizeAdapter.filter.filter(null) |
|
||||
chunkSizeAdapter.filter.filter(null) |
|
||||
|
|
||||
settingsViewModel.setAdapterItemChanged(position) |
|
||||
settingsViewModel.setShouldReloadSettingsList(true) |
|
||||
} |
|
||||
|
|
||||
binding.btnCancel.setOnClickListener { |
|
||||
dialog.dismiss() |
|
||||
} |
|
||||
|
|
||||
binding.btnOk.setOnClickListener { |
|
||||
if (binding.switchEnable.isChecked) { |
|
||||
item.enable() |
|
||||
// Save the selected values |
|
||||
val selectedTextureIndex = textureSizeEntries.indexOf( |
|
||||
binding.dropdownTextureSize.text.toString() |
|
||||
) |
|
||||
if (selectedTextureIndex >= 0) { |
|
||||
item.setTextureSize(textureSizeValues[selectedTextureIndex]) |
|
||||
} |
|
||||
|
|
||||
val selectedStreamIndex = streamSizeEntries.indexOf( |
|
||||
binding.dropdownStreamSize.text.toString() |
|
||||
) |
|
||||
if (selectedStreamIndex >= 0) { |
|
||||
item.setStreamSize(streamSizeValues[selectedStreamIndex]) |
|
||||
} |
|
||||
|
|
||||
val selectedChunkIndex = chunkSizeEntries.indexOf( |
|
||||
binding.dropdownChunkSize.text.toString() |
|
||||
) |
|
||||
if (selectedChunkIndex >= 0) { |
|
||||
item.setChunkSize(chunkSizeValues[selectedChunkIndex]) |
|
||||
} |
|
||||
} else { |
|
||||
// Disable GPU unswizzle |
|
||||
item.disable() |
|
||||
} |
|
||||
|
|
||||
settingsViewModel.setAdapterItemChanged(position) |
|
||||
settingsViewModel.setShouldReloadSettingsList(true) |
|
||||
dialog.dismiss() |
|
||||
} |
|
||||
|
|
||||
// Ensure filters are cleared after dialog is shown |
|
||||
binding.root.post { |
|
||||
textureSizeAdapter.filter.filter(null) |
|
||||
streamSizeAdapter.filter.filter(null) |
|
||||
chunkSizeAdapter.filter.filter(null) |
|
||||
} |
|
||||
|
|
||||
return dialog |
|
||||
} |
|
||||
|
|
||||
private fun updateDropdownsState(enabled: Boolean) { |
|
||||
binding.layoutTextureSize.isEnabled = enabled |
|
||||
binding.dropdownTextureSize.isEnabled = enabled |
|
||||
binding.layoutStreamSize.isEnabled = enabled |
|
||||
binding.dropdownStreamSize.isEnabled = enabled |
|
||||
binding.layoutChunkSize.isEnabled = enabled |
|
||||
binding.dropdownChunkSize.isEnabled = enabled |
|
||||
} |
|
||||
|
|
||||
companion object { |
|
||||
const val TAG = "GpuUnswizzleDialogFragment" |
|
||||
const val POSITION = "Position" |
|
||||
|
|
||||
fun newInstance( |
|
||||
settingsViewModel: SettingsViewModel, |
|
||||
item: GpuUnswizzleSetting, |
|
||||
position: Int |
|
||||
): GpuUnswizzleDialogFragment { |
|
||||
val dialog = GpuUnswizzleDialogFragment() |
|
||||
val args = Bundle() |
|
||||
args.putInt(POSITION, position) |
|
||||
dialog.arguments = args |
|
||||
settingsViewModel.clickedItem = item |
|
||||
return dialog |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,71 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
|
|
||||
package org.yuzu.yuzu_emu.features.settings.ui.viewholder |
|
||||
|
|
||||
import android.view.View |
|
||||
import org.yuzu.yuzu_emu.R |
|
||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding |
|
||||
import org.yuzu.yuzu_emu.features.settings.model.view.GpuUnswizzleSetting |
|
||||
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem |
|
||||
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter |
|
||||
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible |
|
||||
|
|
||||
class GpuUnswizzleViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : |
|
||||
SettingViewHolder(binding.root, adapter) { |
|
||||
private lateinit var setting: GpuUnswizzleSetting |
|
||||
|
|
||||
override fun bind(item: SettingsItem) { |
|
||||
setting = item as GpuUnswizzleSetting |
|
||||
binding.textSettingName.text = setting.title |
|
||||
binding.textSettingDescription.setVisible(item.description.isNotEmpty()) |
|
||||
binding.textSettingDescription.text = item.description |
|
||||
|
|
||||
binding.textSettingValue.setVisible(true) |
|
||||
val resMgr = binding.root.context.resources |
|
||||
|
|
||||
if (setting.isEnabled()) { |
|
||||
// Show a summary of current settings |
|
||||
val textureSizeEntries = resMgr.getStringArray(setting.textureSizeChoicesId) |
|
||||
val textureSizeValues = resMgr.getIntArray(setting.textureSizeValuesId) |
|
||||
val textureSizeIndex = textureSizeValues.indexOf(setting.getTextureSize()) |
|
||||
val textureSizeLabel = if (textureSizeIndex >= 0) textureSizeEntries[textureSizeIndex] else "?" |
|
||||
|
|
||||
val streamSizeEntries = resMgr.getStringArray(setting.streamSizeChoicesId) |
|
||||
val streamSizeValues = resMgr.getIntArray(setting.streamSizeValuesId) |
|
||||
val streamSizeIndex = streamSizeValues.indexOf(setting.getStreamSize()) |
|
||||
val streamSizeLabel = if (streamSizeIndex >= 0) streamSizeEntries[streamSizeIndex] else "?" |
|
||||
|
|
||||
val chunkSizeEntries = resMgr.getStringArray(setting.chunkSizeChoicesId) |
|
||||
val chunkSizeValues = resMgr.getIntArray(setting.chunkSizeValuesId) |
|
||||
val chunkSizeIndex = chunkSizeValues.indexOf(setting.getChunkSize()) |
|
||||
val chunkSizeLabel = if (chunkSizeIndex >= 0) chunkSizeEntries[chunkSizeIndex] else "?" |
|
||||
|
|
||||
binding.textSettingValue.text = "$textureSizeLabel ⋅ $streamSizeLabel ⋅ $chunkSizeLabel" |
|
||||
} else { |
|
||||
binding.textSettingValue.text = resMgr.getString(R.string.gpu_unswizzle_disabled) |
|
||||
} |
|
||||
|
|
||||
binding.buttonClear.setVisible(setting.clearable) |
|
||||
binding.buttonClear.setOnClickListener { |
|
||||
adapter.onClearClick(setting, bindingAdapterPosition) |
|
||||
} |
|
||||
|
|
||||
setStyle(setting.isEditable, binding) |
|
||||
} |
|
||||
|
|
||||
override fun onClick(clicked: View) { |
|
||||
if (!setting.isEditable) { |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
adapter.onGpuUnswizzleClick(setting, bindingAdapterPosition) |
|
||||
} |
|
||||
|
|
||||
override fun onLongClick(clicked: View): Boolean { |
|
||||
if (setting.isEditable) { |
|
||||
return adapter.onLongClick(setting, bindingAdapterPosition) |
|
||||
} |
|
||||
return false |
|
||||
} |
|
||||
} |
|
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue