diff --git a/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.kt b/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.kt index dcf7b11c4..d93a6a69e 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.kt @@ -31,6 +31,7 @@ import org.citra.citra_emu.activities.EmulationActivity import org.citra.citra_emu.model.Game import org.citra.citra_emu.utils.BuildUtil import org.citra.citra_emu.utils.FileUtil +import org.citra.citra_emu.utils.GraphicsUtil import org.citra.citra_emu.utils.Log import org.citra.citra_emu.utils.RemovableStorageHelper import org.citra.citra_emu.viewmodel.CompressProgressDialogViewModel @@ -344,11 +345,12 @@ object NativeLibrary { return coreErrorAlertResult } - @get:Keep - @get:JvmStatic - val isPortraitMode: Boolean - get() = CitraApplication.appContext.resources.configuration.orientation == + @Keep + @JvmStatic + fun isPortraitMode(): Boolean = ( + CitraApplication.appContext.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT + ) @Keep @JvmStatic @@ -800,6 +802,10 @@ object NativeLibrary { @JvmStatic fun getBuildFlavor(): String = BuildConfig.FLAVOR + @Keep + @JvmStatic + fun isUsingAngleForOpenGL(): Boolean = GraphicsUtil.isUsingAngleForOpenGL() + @Keep @JvmStatic fun fileExists(path: String): Boolean = if (FileUtil.isNativePath(path)) { diff --git a/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenAdjustmentUtil.kt b/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenAdjustmentUtil.kt index 92cb1ea0e..b483ce2d3 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenAdjustmentUtil.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenAdjustmentUtil.kt @@ -44,7 +44,7 @@ class ScreenAdjustmentUtil( } val portraitValues = context.resources.getIntArray(R.array.portraitValues) - if (NativeLibrary.isPortraitMode) { + if (NativeLibrary.isPortraitMode()) { val currentLayout = IntSetting.PORTRAIT_SCREEN_LAYOUT.int val pos = portraitValues.indexOf(currentLayout) val layoutOption = portraitValues[(pos + 1) % portraitValues.size] @@ -61,21 +61,21 @@ class ScreenAdjustmentUtil( IntSetting.PORTRAIT_SCREEN_LAYOUT.int = layoutOption settings.saveSetting(IntSetting.PORTRAIT_SCREEN_LAYOUT, SettingsFile.FILE_NAME_CONFIG) NativeLibrary.reloadSettings() - NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode) + NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode()) } fun changeScreenOrientation(layoutOption: Int) { IntSetting.SCREEN_LAYOUT.int = layoutOption settings.saveSetting(IntSetting.SCREEN_LAYOUT, SettingsFile.FILE_NAME_CONFIG) NativeLibrary.reloadSettings() - NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode) + NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode()) } fun changeSecondaryOrientation(layoutOption: Int) { IntSetting.SECONDARY_DISPLAY_LAYOUT.int = layoutOption settings.saveSetting(IntSetting.SECONDARY_DISPLAY_LAYOUT, SettingsFile.FILE_NAME_CONFIG) NativeLibrary.reloadSettings() - NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode) + NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode()) } fun enableSecondaryDisplay(layoutOption: Int) { @@ -101,6 +101,6 @@ class ScreenAdjustmentUtil( BooleanSetting.UPRIGHT_SCREEN.boolean = !uprightBoolean settings.saveSetting(BooleanSetting.UPRIGHT_SCREEN, SettingsFile.FILE_NAME_CONFIG) NativeLibrary.reloadSettings() - NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode) + NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode()) } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/DateTimeSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/DateTimeSetting.kt index f1752614e..90686b4c1 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/DateTimeSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/DateTimeSetting.kt @@ -1,9 +1,11 @@ -// Copyright 2023 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. package org.citra.citra_emu.features.settings.model.view +import androidx.annotation.StringRes +import org.citra.citra_emu.R import org.citra.citra_emu.features.settings.model.AbstractSetting import org.citra.citra_emu.features.settings.model.AbstractStringSetting @@ -13,7 +15,9 @@ class DateTimeSetting( descriptionId: Int, val key: String? = null, private val defaultValue: String? = null, - override var isEnabled: Boolean = true + override var isEnabled: Boolean = true, + @StringRes override var disabledMessage: Int = + R.string.setting_disabled_description_incompatible_setting ) : SettingsItem(setting, titleId, descriptionId) { override val type = TYPE_DATETIME_SETTING diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/MultiChoiceSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/MultiChoiceSetting.kt index aab36c53f..42d23695f 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/MultiChoiceSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/MultiChoiceSetting.kt @@ -3,6 +3,8 @@ // Refer to the license.txt file included. package org.citra.citra_emu.features.settings.model.view +import androidx.annotation.StringRes +import org.citra.citra_emu.R import org.citra.citra_emu.features.settings.model.AbstractSetting import org.citra.citra_emu.features.settings.model.IntListSetting class MultiChoiceSetting( @@ -13,7 +15,9 @@ class MultiChoiceSetting( val valuesId: Int, val key: String? = null, val defaultValue: List? = null, - override var isEnabled: Boolean = true + override var isEnabled: Boolean = true, + @StringRes override var disabledMessage: Int = + R.string.setting_disabled_description_incompatible_setting ) : SettingsItem(setting, titleId, descriptionId) { override val type = TYPE_MULTI_CHOICE diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SettingsItem.kt index 6e1f31b0e..60087e3dd 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SettingsItem.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SettingsItem.kt @@ -4,6 +4,8 @@ package org.citra.citra_emu.features.settings.model.view +import androidx.annotation.StringRes +import org.citra.citra_emu.R import org.citra.citra_emu.activities.EmulationActivity import org.citra.citra_emu.features.settings.model.AbstractSetting @@ -29,6 +31,9 @@ abstract class SettingsItem( open var isEnabled: Boolean = true + @StringRes open var disabledMessage: Int = + R.string.setting_disabled_description_incompatible_setting + val isActive: Boolean get() { return this.isEditable && this.isEnabled diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SingleChoiceSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SingleChoiceSetting.kt index 9ba2fe8c5..e2450e572 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SingleChoiceSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SingleChoiceSetting.kt @@ -1,9 +1,11 @@ -// Copyright 2023 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. package org.citra.citra_emu.features.settings.model.view +import androidx.annotation.StringRes +import org.citra.citra_emu.R import org.citra.citra_emu.features.settings.model.AbstractIntSetting import org.citra.citra_emu.features.settings.model.AbstractSetting import org.citra.citra_emu.features.settings.model.AbstractShortSetting @@ -16,7 +18,9 @@ class SingleChoiceSetting( val valuesId: Int, val key: String? = null, val defaultValue: Int? = null, - override var isEnabled: Boolean = true + override var isEnabled: Boolean = true, + @StringRes override var disabledMessage: Int = + R.string.setting_disabled_description_incompatible_setting ) : SettingsItem(setting, titleId, descriptionId) { override val type = TYPE_SINGLE_CHOICE diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SliderSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SliderSetting.kt index 32fd722a7..39acd4223 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SliderSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SliderSetting.kt @@ -4,6 +4,8 @@ package org.citra.citra_emu.features.settings.model.view +import androidx.annotation.StringRes +import org.citra.citra_emu.R import org.citra.citra_emu.features.settings.model.AbstractFloatSetting import org.citra.citra_emu.features.settings.model.AbstractIntSetting import org.citra.citra_emu.features.settings.model.AbstractSetting @@ -20,7 +22,9 @@ class SliderSetting( val units: String, val key: String? = null, val defaultValue: Float? = null, - override var isEnabled: Boolean = true + override var isEnabled: Boolean = true, + @StringRes override var disabledMessage: Int = + R.string.setting_disabled_description_incompatible_setting ) : SettingsItem(setting, titleId, descriptionId) { override val type = TYPE_SLIDER val selectedFloat: Float diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/StringInputSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/StringInputSetting.kt index f32c078a6..4a1972e56 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/StringInputSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/StringInputSetting.kt @@ -1,9 +1,11 @@ -// Copyright 2023 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. package org.citra.citra_emu.features.settings.model.view +import androidx.annotation.StringRes +import org.citra.citra_emu.R import org.citra.citra_emu.features.settings.model.AbstractSetting import org.citra.citra_emu.features.settings.model.AbstractStringSetting @@ -13,7 +15,9 @@ class StringInputSetting( descriptionId: Int, val defaultValue: String, val characterLimit: Int = 0, - override var isEnabled: Boolean = true + override var isEnabled: Boolean = true, + @StringRes override var disabledMessage: Int = + R.string.setting_disabled_description_incompatible_setting ) : SettingsItem(setting, titleId, descriptionId) { override val type = TYPE_STRING_INPUT diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/StringSingleChoiceSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/StringSingleChoiceSetting.kt index 037a26ffc..99771f120 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/StringSingleChoiceSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/StringSingleChoiceSetting.kt @@ -1,9 +1,11 @@ -// Copyright 2023 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. package org.citra.citra_emu.features.settings.model.view +import androidx.annotation.StringRes +import org.citra.citra_emu.R import org.citra.citra_emu.features.settings.model.AbstractSetting import org.citra.citra_emu.features.settings.model.AbstractShortSetting import org.citra.citra_emu.features.settings.model.AbstractStringSetting @@ -16,7 +18,9 @@ class StringSingleChoiceSetting( val values: Array?, val key: String? = null, private val defaultValue: String? = null, - override var isEnabled: Boolean = true + override var isEnabled: Boolean = true, + @StringRes override var disabledMessage: Int = + R.string.setting_disabled_description_incompatible_setting ) : SettingsItem(setting, titleId, descriptionId) { override val type = TYPE_STRING_SINGLE_CHOICE diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SwitchSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SwitchSetting.kt index defcc6754..1b1a3d9ac 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SwitchSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SwitchSetting.kt @@ -4,6 +4,8 @@ package org.citra.citra_emu.features.settings.model.view +import androidx.annotation.StringRes +import org.citra.citra_emu.R import org.citra.citra_emu.features.settings.model.AbstractBooleanSetting class SwitchSetting( @@ -12,7 +14,9 @@ class SwitchSetting( descriptionId: Int, val key: String? = null, val defaultValue: Boolean = false, - override var isEnabled: Boolean = true + override var isEnabled: Boolean = true, + @StringRes override var disabledMessage: Int = + R.string.setting_disabled_description_incompatible_setting ) : SettingsItem(setting, titleId, descriptionId) { override val type = TYPE_SWITCH diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsActivityPresenter.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsActivityPresenter.kt index bc823066a..d77113ef0 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsActivityPresenter.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsActivityPresenter.kt @@ -101,7 +101,7 @@ class SettingsActivityPresenter(private val activityView: SettingsActivityView) settings.saveSettings(activityView) // added to ensure that layout changes take effect as soon as settings window closes NativeLibrary.reloadSettings() - NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode) + NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode()) updateAndroidImageVisibility() TurboHelper.reloadTurbo(false) // TODO: Can this go somewhere else? -OS } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsAdapter.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsAdapter.kt index 6e897bc5a..df41aa68c 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsAdapter.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsAdapter.kt @@ -16,6 +16,7 @@ import android.text.TextWatcher import android.text.format.DateFormat import android.view.LayoutInflater import android.view.ViewGroup +import androidx.annotation.StringRes import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.core.widget.doOnTextChanged @@ -641,7 +642,7 @@ class SettingsAdapter(private val fragmentView: SettingsFragmentView, public val return true } - fun onClickDisabledSetting(isRuntimeDisabled: Boolean) { + fun onClickDisabledSetting(isRuntimeDisabled: Boolean, @StringRes disabledMessage: Int) { val titleId = if (isRuntimeDisabled) { R.string.setting_not_editable } else { @@ -650,7 +651,7 @@ class SettingsAdapter(private val fragmentView: SettingsFragmentView, public val val messageId = if (isRuntimeDisabled) { R.string.setting_not_editable_description } else { - R.string.setting_disabled_description + disabledMessage } MessageDialogFragment.newInstance( diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt index 927772918..673354f06 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -46,6 +46,7 @@ import org.citra.citra_emu.features.settings.model.view.SwitchSetting import org.citra.citra_emu.features.settings.utils.SettingsFile import org.citra.citra_emu.fragments.ResetSettingsDialogFragment import org.citra.citra_emu.utils.BirthdayMonth +import org.citra.citra_emu.utils.GraphicsUtil import org.citra.citra_emu.utils.Log import org.citra.citra_emu.utils.SystemSaveGame import org.citra.citra_emu.utils.ThemeUtil @@ -900,7 +901,9 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) R.array.graphicsApiNames, R.array.graphicsApiValues, IntSetting.GRAPHICS_API.key, - IntSetting.GRAPHICS_API.defaultValue + IntSetting.GRAPHICS_API.defaultValue, + isEnabled = !GraphicsUtil.isUsingAngleForOpenGL(), + disabledMessage = R.string.setting_disabled_description_angle ) ) add( diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/DateTimeViewHolder.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/DateTimeViewHolder.kt index 58cbded3e..2738ce6fc 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/DateTimeViewHolder.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/DateTimeViewHolder.kt @@ -62,7 +62,7 @@ class DateTimeViewHolder(val binding: ListItemSettingBinding, adapter: SettingsA if (setting.isActive) { adapter.onDateTimeClick(setting, bindingAdapterPosition) } else { - adapter.onClickDisabledSetting(!setting.isEditable) + adapter.onClickDisabledSetting(!setting.isEditable, setting.disabledMessage) } } @@ -70,7 +70,7 @@ class DateTimeViewHolder(val binding: ListItemSettingBinding, adapter: SettingsA if (setting.isActive) { return adapter.onLongClick(setting.setting!!, bindingAdapterPosition) } else { - adapter.onClickDisabledSetting(!setting.isEditable) + adapter.onClickDisabledSetting(!setting.isEditable, setting.disabledMessage) } return false } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/InputBindingSettingViewHolder.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/InputBindingSettingViewHolder.kt index 5d2a812e0..3c9562f21 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/InputBindingSettingViewHolder.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/InputBindingSettingViewHolder.kt @@ -45,7 +45,7 @@ class InputBindingSettingViewHolder(val binding: ListItemSettingBinding, adapter if (setting.isEditable) { adapter.onInputBindingClick(setting, bindingAdapterPosition) } else { - adapter.onClickDisabledSetting(!setting.isEditable) + adapter.onClickDisabledSetting(!setting.isEditable, setting.disabledMessage) } } @@ -53,7 +53,7 @@ class InputBindingSettingViewHolder(val binding: ListItemSettingBinding, adapter if (setting.isEditable) { adapter.onInputBindingLongClick(setting, bindingAdapterPosition) } else { - adapter.onClickDisabledSetting(!setting.isEditable) + adapter.onClickDisabledSetting(!setting.isEditable, setting.disabledMessage) } return false } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/MultiChoiceViewHolder.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/MultiChoiceViewHolder.kt index 3c44cb800..a9eebfcc1 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/MultiChoiceViewHolder.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/MultiChoiceViewHolder.kt @@ -57,7 +57,7 @@ class MultiChoiceViewHolder(val binding: ListItemSettingBinding, adapter: Settin override fun onClick(clicked: View) { if (!setting.isEditable || !setting.isEnabled) { - adapter.onClickDisabledSetting(!setting.isEditable) + adapter.onClickDisabledSetting(!setting.isEditable, setting.disabledMessage) return } @@ -73,7 +73,7 @@ class MultiChoiceViewHolder(val binding: ListItemSettingBinding, adapter: Settin if (setting.isActive) { return adapter.onLongClick(setting.setting!!, bindingAdapterPosition) } else { - adapter.onClickDisabledSetting(!setting.isEditable) + adapter.onClickDisabledSetting(!setting.isEditable, setting.disabledMessage) } return false } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/RunnableViewHolder.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/RunnableViewHolder.kt index d4c375301..bd51fc2dd 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/RunnableViewHolder.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/RunnableViewHolder.kt @@ -59,7 +59,7 @@ class RunnableViewHolder(val binding: ListItemSettingBinding, adapter: SettingsA override fun onClick(clicked: View) { if (!setting.isRuntimeRunnable && EmulationActivity.isRunning()) { - adapter.onClickDisabledSetting(true) + adapter.onClickDisabledSetting(true, setting.disabledMessage) } else { setting.runnable.invoke() } @@ -67,7 +67,7 @@ class RunnableViewHolder(val binding: ListItemSettingBinding, adapter: SettingsA override fun onLongClick(clicked: View): Boolean { if (!setting.isEditable) { - adapter.onClickDisabledSetting(true) + adapter.onClickDisabledSetting(true, setting.disabledMessage) return true } return setting.onLongClick?.invoke() ?: true diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SingleChoiceViewHolder.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SingleChoiceViewHolder.kt index 6e899d946..8a73a7c9b 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SingleChoiceViewHolder.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SingleChoiceViewHolder.kt @@ -66,7 +66,7 @@ class SingleChoiceViewHolder(val binding: ListItemSettingBinding, adapter: Setti override fun onClick(clicked: View) { if (!setting.isEditable || !setting.isEnabled) { - adapter.onClickDisabledSetting(!setting.isEditable) + adapter.onClickDisabledSetting(!setting.isEditable, setting.disabledMessage) return } @@ -87,7 +87,7 @@ class SingleChoiceViewHolder(val binding: ListItemSettingBinding, adapter: Setti if (setting.isActive) { return adapter.onLongClick(setting.setting!!, bindingAdapterPosition) } else { - adapter.onClickDisabledSetting(!setting.isEditable) + adapter.onClickDisabledSetting(!setting.isEditable, setting.disabledMessage) } return false } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SliderViewHolder.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SliderViewHolder.kt index ca91edada..8d8458938 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SliderViewHolder.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SliderViewHolder.kt @@ -52,7 +52,7 @@ class SliderViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAda if (setting.isActive) { adapter.onSliderClick(setting, bindingAdapterPosition) } else { - adapter.onClickDisabledSetting(!setting.isEditable) + adapter.onClickDisabledSetting(!setting.isEditable, setting.disabledMessage) } } @@ -60,7 +60,7 @@ class SliderViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAda if (setting.isActive) { return adapter.onLongClick(setting.setting!!, bindingAdapterPosition) } else { - adapter.onClickDisabledSetting(!setting.isEditable) + adapter.onClickDisabledSetting(!setting.isEditable, setting.disabledMessage) } return false } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/StringInputViewHolder.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/StringInputViewHolder.kt index 09bc206d3..6cb817736 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/StringInputViewHolder.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/StringInputViewHolder.kt @@ -39,7 +39,7 @@ class StringInputViewHolder(val binding: ListItemSettingBinding, adapter: Settin override fun onClick(clicked: View) { if (!setting.isEditable || !setting.isEnabled) { - adapter.onClickDisabledSetting(!setting.isEditable) + adapter.onClickDisabledSetting(!setting.isEditable, setting.disabledMessage) return } adapter.onStringInputClick((setting as StringInputSetting), bindingAdapterPosition) @@ -49,7 +49,7 @@ class StringInputViewHolder(val binding: ListItemSettingBinding, adapter: Settin if (setting.isActive) { return adapter.onLongClick(setting.setting!!, bindingAdapterPosition) } else { - adapter.onClickDisabledSetting(!setting.isEditable) + adapter.onClickDisabledSetting(!setting.isEditable, setting.disabledMessage) } return false } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt index 72ebd8d0b..b4f676776 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt @@ -44,7 +44,7 @@ class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter if (setting.isActive) { binding.switchWidget.toggle() } else { - adapter.onClickDisabledSetting(!setting.isEditable) + adapter.onClickDisabledSetting(!setting.isEditable, setting.disabledMessage) } } @@ -52,7 +52,7 @@ class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter if (setting.isActive) { return adapter.onLongClick(setting.setting!!, bindingAdapterPosition) } else { - adapter.onClickDisabledSetting(!setting.isEditable) + adapter.onClickDisabledSetting(!setting.isEditable, setting.disabledMessage) } return false } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/GraphicsUtil.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/GraphicsUtil.kt index 407182155..1e0da3522 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/GraphicsUtil.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/GraphicsUtil.kt @@ -1,4 +1,4 @@ -// Copyright 2023 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -88,7 +88,7 @@ object GraphicsUtil { return UNKNOWN_RENDERER } - val openGLRendererString = GLES20.glGetString(GLES20.GL_RENDERER) ?: UNKNOWN_RENDERER + val rendererString = GLES20.glGetString(GLES20.GL_RENDERER) ?: UNKNOWN_RENDERER EGL14.eglMakeCurrent( glDisplay, @@ -100,6 +100,8 @@ object GraphicsUtil { EGL14.eglDestroyContext(glDisplay, glContext) EGL14.eglTerminate(glDisplay) - return openGLRendererString + return rendererString } + + fun isUsingAngleForOpenGL(): Boolean = (openGLRendererString.contains("ANGLE")) } diff --git a/src/android/app/src/main/jni/CMakeLists.txt b/src/android/app/src/main/jni/CMakeLists.txt index 9aa9bf1cc..89ffd242a 100644 --- a/src/android/app/src/main/jni/CMakeLists.txt +++ b/src/android/app/src/main/jni/CMakeLists.txt @@ -28,8 +28,6 @@ add_library(citra-android SHARED ndk_motion.h system_save_game.cpp native_log.cpp - util.cpp - util.h ) target_link_libraries(citra-android PRIVATE audio_core citra_common citra_core input_common network) diff --git a/src/android/app/src/main/jni/emu_window/emu_window.cpp b/src/android/app/src/main/jni/emu_window/emu_window.cpp index eb8eb92c6..afc25b1c2 100644 --- a/src/android/app/src/main/jni/emu_window/emu_window.cpp +++ b/src/android/app/src/main/jni/emu_window/emu_window.cpp @@ -7,13 +7,13 @@ #include #include #include +#include "common/android_utils.h" #include "common/logging/log.h" #include "common/settings.h" #include "input_common/main.h" #include "jni/emu_window/emu_window.h" #include "jni/id_cache.h" #include "jni/input_manager.h" -#include "jni/util.h" #include "network/network.h" #include "video_core/renderer_base.h" @@ -47,8 +47,7 @@ void EmuWindow_Android::OnTouchMoved(int x, int y) { } void EmuWindow_Android::OnFramebufferSizeChanged() { - const bool is_portrait_mode = (IsPortraitMode() && !is_secondary); - + const bool is_portrait_mode = (AndroidUtils::IsPortraitMode() && !is_secondary); UpdateCurrentFramebufferLayout(window_width, window_height, is_portrait_mode); } diff --git a/src/android/app/src/main/jni/id_cache.cpp b/src/android/app/src/main/jni/id_cache.cpp index 197e81aaa..a692c6395 100644 --- a/src/android/app/src/main/jni/id_cache.cpp +++ b/src/android/app/src/main/jni/id_cache.cpp @@ -2,7 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/android_storage.h" +#include "common/android_utils.h" #include "common/common_paths.h" #include "common/logging/backend.h" #include "common/logging/filter.h" @@ -84,10 +84,6 @@ jmethodID GetOnCoreError() { return s_on_core_error; } -jmethodID GetIsPortraitMode() { - return s_is_portrait_mode; -} - jmethodID GetLandscapeScreenLayout() { return s_landscape_screen_layout; } @@ -181,7 +177,6 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) { s_on_core_error = env->GetStaticMethodID( s_native_library_class, "onCoreError", "(Lorg/citra/citra_emu/NativeLibrary$CoreError;Ljava/lang/String;)Z"); - s_is_portrait_mode = env->GetStaticMethodID(s_native_library_class, "isPortraitMode", "()Z"); s_exit_emulation_activity = env->GetStaticMethodID(s_native_library_class, "exitEmulationActivity", "(I)V"); s_request_camera_permission = @@ -264,7 +259,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) { MiiSelector::InitJNI(env); SoftwareKeyboard::InitJNI(env); Camera::StillImage::InitJNI(env); - AndroidStorage::InitJNI(env, s_native_library_class); + AndroidUtils::InitJNI(env, s_native_library_class); return JNI_VERSION; } @@ -293,7 +288,7 @@ void JNI_OnUnload(JavaVM* vm, void* reserved) { MiiSelector::CleanupJNI(env); SoftwareKeyboard::CleanupJNI(env); Camera::StillImage::CleanupJNI(env); - AndroidStorage::CleanupJNI(); + AndroidUtils::CleanupJNI(); } #ifdef __cplusplus diff --git a/src/android/app/src/main/jni/id_cache.h b/src/android/app/src/main/jni/id_cache.h index d7aeb8074..2289103b8 100644 --- a/src/android/app/src/main/jni/id_cache.h +++ b/src/android/app/src/main/jni/id_cache.h @@ -25,7 +25,6 @@ jmethodID GetOnCoreError(); jmethodID GetDisplayAlertMsg(); jmethodID GetDisplayAlertPrompt(); jmethodID GetAlertPromptButton(); -jmethodID GetIsPortraitMode(); jmethodID GetLandscapeScreenLayout(); jmethodID GetPortraitScreenLayout(); jmethodID GetExitEmulationActivity(); diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 9888e5356..4ed0c3a85 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -63,10 +63,10 @@ #endif #endif +#include "common/android_utils.h" #include "jni/id_cache.h" #include "jni/input_manager.h" #include "jni/ndk_motion.h" -#include "jni/util.h" #include "video_core/debug_utils/debug_utils.h" #include "video_core/gpu.h" #include "video_core/renderer_base.h" @@ -189,7 +189,7 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) { system.InsertCartridge(inserted_cartridge); } - const auto graphics_api = Settings::values.graphics_api.GetValue(); + const auto graphics_api = Settings::GetWorkingGraphicsAPI(); EGLContext* shared_context; switch (graphics_api) { #ifdef ENABLE_OPENGL @@ -471,7 +471,7 @@ void Java_org_citra_citra_1emu_NativeLibrary_swapScreens([[maybe_unused]] JNIEnv Settings::values.swap_screen = swap_screens; auto& system = Core::System::GetInstance(); if (system.IsPoweredOn()) { - system.GPU().Renderer().UpdateCurrentFramebufferLayout(IsPortraitMode()); + system.GPU().Renderer().UpdateCurrentFramebufferLayout(AndroidUtils::IsPortraitMode()); } InputManager::screen_rotation = rotation; Camera::NDK::g_rotation = rotation; diff --git a/src/android/app/src/main/jni/util.cpp b/src/android/app/src/main/jni/util.cpp deleted file mode 100644 index 83a71c5a6..000000000 --- a/src/android/app/src/main/jni/util.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright Citra Emulator Project / Lime3DS Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include "jni/id_cache.h" - -bool IsPortraitMode() { - return JNI_FALSE != IDCache::GetEnvForThread()->CallStaticBooleanMethod( - IDCache::GetNativeLibraryClass(), IDCache::GetIsPortraitMode()); -} diff --git a/src/android/app/src/main/jni/util.h b/src/android/app/src/main/jni/util.h deleted file mode 100644 index ad86ddf82..000000000 --- a/src/android/app/src/main/jni/util.h +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright Citra Emulator Project / Lime3DS Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -/// Calls and returns the value of NativeLibrary.isPortraitMode -bool IsPortraitMode(); diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 412c3c134..30ba04091 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -411,7 +411,8 @@ Do you want to reset this setting back to its default value? You can\'t edit this now Setting disabled - This setting is currently disabled due to another setting not being the appropriate value. + This setting is currently disabled due to another setting not being the appropriate value. + The renderer can\'t be changed because the device is using ANGLE for OpenGL, which is currently incompatible with Azahar. Vulkan will be used. This option can\'t be changed while a game is running. Auto-Select Start diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 39649b8bf..c0d6f613f 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -650,7 +650,7 @@ bool GRenderWindow::InitRenderTarget() { first_frame = false; - const auto graphics_api = Settings::values.graphics_api.GetValue(); + const auto graphics_api = Settings::GetWorkingGraphicsAPI(); switch (graphics_api) { #ifdef ENABLE_SOFTWARE_RENDERER case Settings::GraphicsAPI::Software: @@ -837,7 +837,7 @@ void GRenderWindow::showEvent(QShowEvent* event) { std::unique_ptr GRenderWindow::CreateSharedContext() const { #ifdef ENABLE_OPENGL - const auto graphics_api = Settings::values.graphics_api.GetValue(); + const auto graphics_api = Settings::GetWorkingGraphicsAPI(); if (graphics_api == Settings::GraphicsAPI::OpenGL) { auto gl_context = static_cast(main_context.get()); // Bind the shared contexts to the main surface in case the backend wants to take over diff --git a/src/citra_qt/configuration/configure_enhancements.cpp b/src/citra_qt/configuration/configure_enhancements.cpp index 62afcbb77..a737882d5 100644 --- a/src/citra_qt/configuration/configure_enhancements.cpp +++ b/src/citra_qt/configuration/configure_enhancements.cpp @@ -18,7 +18,7 @@ ConfigureEnhancements::ConfigureEnhancements(QWidget* parent) SetupPerGameUI(); SetConfiguration(); - const auto graphics_api = Settings::values.graphics_api.GetValue(); + const auto graphics_api = Settings::GetWorkingGraphicsAPI(); const bool res_scale_enabled = graphics_api != Settings::GraphicsAPI::Software; ui->resolution_factor_combobox->setEnabled(res_scale_enabled); diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index ae812c89d..f7b1df1b6 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -130,8 +130,8 @@ endif() # Android storage is only used for non-libretro Android builds if (ANDROID AND NOT ENABLE_LIBRETRO) target_sources(citra_common PRIVATE - android_storage.cpp - android_storage.h + android_utils.cpp + android_utils.h ) endif() diff --git a/src/common/android_storage.cpp b/src/common/android_utils.cpp similarity index 88% rename from src/common/android_storage.cpp rename to src/common/android_utils.cpp index 0fb6ceaaf..ea3500771 100644 --- a/src/common/android_storage.cpp +++ b/src/common/android_utils.cpp @@ -6,11 +6,11 @@ #include #include #include -#include "common/android_storage.h" +#include "common/android_utils.h" #include "common/file_util.h" #include "common/logging/log.h" -namespace AndroidStorage { +namespace AndroidUtils { JNIEnv* GetEnvForThread() { thread_local static struct OwnedEnv { OwnedEnv() { @@ -36,21 +36,21 @@ AndroidOpenMode ParseOpenmode(const std::string_view openmode) { int o = 0; switch (*mode++) { case 'r': - android_open_mode = AndroidStorage::AndroidOpenMode::READ; + android_open_mode = AndroidUtils::AndroidOpenMode::READ; break; case 'w': - android_open_mode = AndroidStorage::AndroidOpenMode::WRITE; + android_open_mode = AndroidUtils::AndroidOpenMode::WRITE; o = O_TRUNC; break; case 'a': - android_open_mode = AndroidStorage::AndroidOpenMode::WRITE; + android_open_mode = AndroidUtils::AndroidOpenMode::WRITE; o = O_APPEND; break; } // [rwa]\+ or [rwa]b\+ means read and write if (*mode == '+' || (*mode == 'b' && mode[1] == '+')) { - android_open_mode = AndroidStorage::AndroidOpenMode::READ_WRITE; + android_open_mode = AndroidUtils::AndroidOpenMode::READ_WRITE; } return android_open_mode | o; @@ -67,7 +67,7 @@ void InitJNI(JNIEnv* env, jclass clazz) { #define F(JMethodID, JMethodName, Signature) \ JMethodID = env->GetStaticMethodID(native_library, JMethodName, Signature); ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR) - ANDROID_STORAGE_FUNCTIONS(FS) + ANDROID_JNI_FUNCTIONS(FS) #undef F #undef FS #undef FR @@ -78,7 +78,7 @@ void CleanupJNI() { #define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) F(JMethodID) #define F(JMethodID) JMethodID = nullptr; ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR) - ANDROID_STORAGE_FUNCTIONS(FS) + ANDROID_JNI_FUNCTIONS(FS) #undef F #undef FS #undef FR @@ -199,6 +199,16 @@ std::string GetBuildFlavor() { return env->GetStringUTFChars(jflavor, nullptr); } +bool IsPortraitMode() { + auto env = GetEnvForThread(); + return (JNI_FALSE != env->CallStaticBooleanMethod(native_library, is_portrait_mode)); +} + +bool IsUsingAngleForOpenGL() { + auto env = GetEnvForThread(); + return env->CallStaticBooleanMethod(native_library, is_using_angle_for_opengl); +} + bool CopyFile(const std::string& source, const std::string& destination_path, const std::string& destination_filename) { if (copy_file == nullptr) { @@ -268,14 +278,14 @@ bool MoveAndRenameFile(const std::string& src_full_path, const std::string& dest bool result; const std::string tmp_path = "/tmp"; - AndroidStorage::CreateDir("/", "tmp"); + AndroidUtils::CreateDir("/", "tmp"); // If a simultaneous move and rename are not necessary, use individual methods if (src_filename == dest_filename || src_parent_path == dest_parent_path) { if (src_filename != dest_filename) { - return AndroidStorage::RenameFile(src_full_path, dest_filename); + return AndroidUtils::RenameFile(src_full_path, dest_filename); } else if (src_parent_path != dest_parent_path) { - return AndroidStorage::MoveFile(src_filename, src_parent_path, dest_parent_path); + return AndroidUtils::MoveFile(src_filename, src_parent_path, dest_parent_path); } } @@ -283,28 +293,28 @@ bool MoveAndRenameFile(const std::string& src_full_path, const std::string& dest // This prevents clashes if files with the same name are moved simultaneously. const auto uuid = boost::uuids::to_string(boost::uuids::time_generator_v7()()); const auto allocated_tmp_path = tmp_path + "/" + uuid; - AndroidStorage::CreateDir(tmp_path, uuid); + AndroidUtils::CreateDir(tmp_path, uuid); // Step 2: Attempt to move to allocated temporary directory. // If this step fails, skip everything except the cleanup. - result = AndroidStorage::MoveFile(src_filename, src_parent_path, allocated_tmp_path); + result = AndroidUtils::MoveFile(src_filename, src_parent_path, allocated_tmp_path); if (result == true) { // Step 3: Rename to desired file name. - AndroidStorage::RenameFile((allocated_tmp_path + "/" + src_filename), dest_filename); + AndroidUtils::RenameFile((allocated_tmp_path + "/" + src_filename), dest_filename); // Step 4: If a file with the desired name in the destination exists, remove it. - AndroidStorage::DeleteDocument(dest_full_path); + AndroidUtils::DeleteDocument(dest_full_path); // Step 5: Attempt to move file to desired location. // If this step fails, move the file back to where it came from. - result = AndroidStorage::MoveFile(dest_filename, allocated_tmp_path, dest_parent_path); + result = AndroidUtils::MoveFile(dest_filename, allocated_tmp_path, dest_parent_path); if (result == false) { - AndroidStorage::MoveAndRenameFile((allocated_tmp_path + "/" + dest_filename), - src_full_path); + AndroidUtils::MoveAndRenameFile((allocated_tmp_path + "/" + dest_filename), + src_full_path); } } // Step 6: Clean up the allocated temp directory. - AndroidStorage::DeleteDocument(allocated_tmp_path); + AndroidUtils::DeleteDocument(allocated_tmp_path); return result; } @@ -326,7 +336,7 @@ std::string TranslateFilePath(const std::string& filepath) { } bool CanUseRawFS() { - return AndroidStorage::GetBuildFlavor() != AndroidBuildFlavors::GOOGLEPLAY; + return AndroidUtils::GetBuildFlavor() != AndroidBuildFlavors::GOOGLEPLAY; } #define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) \ @@ -344,5 +354,5 @@ ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR) #undef F #undef FR -} // namespace AndroidStorage +} // namespace AndroidUtils #endif diff --git a/src/common/android_storage.h b/src/common/android_utils.h similarity index 93% rename from src/common/android_storage.h rename to src/common/android_utils.h index b070ca53b..f547efba6 100644 --- a/src/common/android_storage.h +++ b/src/common/android_utils.h @@ -10,7 +10,7 @@ #include #include -#define ANDROID_STORAGE_FUNCTIONS(V) \ +#define ANDROID_JNI_FUNCTIONS(V) \ V(CreateFile, bool, (const std::string& directory, const std::string& filename), create_file, \ "createFile", "(Ljava/lang/String;Ljava/lang/String;)Z") \ V(CreateDir, bool, (const std::string& directory, const std::string& filename), create_dir, \ @@ -32,6 +32,8 @@ update_document_location, "updateDocumentLocation", \ "(Ljava/lang/String;Ljava/lang/String;)Z") \ V(GetBuildFlavor, std::string, (), get_build_flavor, "getBuildFlavor", "()Ljava/lang/String;") \ + V(IsPortraitMode, bool, (), is_portrait_mode, "isPortraitMode", "()Z") \ + V(IsUsingAngleForOpenGL, bool, (), is_using_angle_for_opengl, "isUsingAngleForOpenGL", "()Z") \ V(MoveFile, bool, \ (const std::string& filename, const std::string& source_dir_path, \ const std::string& destination_dir_path), \ @@ -44,7 +46,7 @@ V(GetSize, std::uint64_t, get_size, CallStaticLongMethod, "getSize", "(Ljava/lang/String;)J") \ V(DeleteDocument, bool, delete_document, CallStaticBooleanMethod, "deleteDocument", \ "(Ljava/lang/String;)Z") -namespace AndroidStorage { +namespace AndroidUtils { static JavaVM* g_jvm = nullptr; static jclass native_library = nullptr; @@ -52,7 +54,7 @@ static jclass native_library = nullptr; #define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) F(JMethodID) #define F(JMethodID) static jmethodID JMethodID = nullptr; ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR) -ANDROID_STORAGE_FUNCTIONS(FS) +ANDROID_JNI_FUNCTIONS(FS) #undef F #undef FS #undef FR @@ -91,7 +93,7 @@ void CleanupJNI(); #define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) \ F(FunctionName, Parameters, ReturnValue) #define F(FunctionName, Parameters, ReturnValue) ReturnValue FunctionName Parameters; -ANDROID_STORAGE_FUNCTIONS(FS) +ANDROID_JNI_FUNCTIONS(FS) #undef F #undef FS @@ -102,5 +104,5 @@ ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR) #undef F #undef FR -} // namespace AndroidStorage +} // namespace AndroidUtils #endif diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index 52f406226..6dda955fe 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -83,7 +83,7 @@ typedef struct stat file_stat_t; #endif #if defined(ANDROID) && !defined(HAVE_LIBRETRO_VFS) -#include "common/android_storage.h" +#include "common/android_utils.h" #include "common/string_util.h" #endif @@ -168,11 +168,11 @@ bool Exists(const std::string& filename) { int result = _wstat64(Common::UTF8ToUTF16W(copy).c_str(), &file_info); #elif defined(ANDROID) && !defined(HAVE_LIBRETRO_VFS) int result; - if (AndroidStorage::CanUseRawFS()) { + if (AndroidUtils::CanUseRawFS()) { struct stat file_info; - result = stat(AndroidStorage::TranslateFilePath(copy).c_str(), &file_info); + result = stat(AndroidUtils::TranslateFilePath(copy).c_str(), &file_info); } else { - result = AndroidStorage::FileExists(filename) ? 0 : -1; + result = AndroidUtils::FileExists(filename) ? 0 : -1; } #else struct stat file_info; @@ -197,10 +197,10 @@ bool IsDirectory(const std::string& filename) { #elif defined(ANDROID) && !defined(HAVE_LIBRETRO_VFS) struct stat file_info; int result; - if (AndroidStorage::CanUseRawFS()) { - result = stat(AndroidStorage::TranslateFilePath(copy).c_str(), &file_info); + if (AndroidUtils::CanUseRawFS()) { + result = stat(AndroidUtils::TranslateFilePath(copy).c_str(), &file_info); } else { - return AndroidStorage::IsDirectory(filename); + return AndroidUtils::IsDirectory(filename); } #else struct stat file_info; @@ -260,13 +260,13 @@ bool Delete(const std::string& filepath) { return false; #elif defined(ANDROID) && !defined(HAVE_LIBRETRO_VFS) - if (AndroidStorage::CanUseRawFS()) { - if (unlink(AndroidStorage::TranslateFilePath(filepath).c_str()) == -1) { + if (AndroidUtils::CanUseRawFS()) { + if (unlink(AndroidUtils::TranslateFilePath(filepath).c_str()) == -1) { LOG_ERROR(Common_Filesystem, "unlink failed on {}: {}", filepath, GetLastErrorMsg()); return false; } } else { - if (!AndroidStorage::DeleteDocument(filepath)) { + if (!AndroidUtils::DeleteDocument(filepath)) { LOG_ERROR(Common_Filesystem, "unlink failed on {}", filepath); return false; } @@ -294,8 +294,8 @@ bool CreateDir(const std::string& path) { LOG_ERROR(Common_Filesystem, "CreateDirectory failed on {}: {}", path, error); return false; #elif defined(ANDROID) && !defined(HAVE_LIBRETRO_VFS) - if (AndroidStorage::CanUseRawFS()) { - if (mkdir(AndroidStorage::TranslateFilePath(path).c_str(), 0755) == 0) + if (AndroidUtils::CanUseRawFS()) { + if (mkdir(AndroidUtils::TranslateFilePath(path).c_str(), 0755) == 0) return true; int err = errno; @@ -320,7 +320,7 @@ bool CreateDir(const std::string& path) { if (directory.empty()) { directory = "/"; } - if (!AndroidStorage::CreateDir(directory, filename)) { + if (!AndroidUtils::CreateDir(directory, filename)) { LOG_ERROR(Common_Filesystem, "mkdir failed on {}", path); return false; }; @@ -397,11 +397,11 @@ bool DeleteDir(const std::string& filename) { if (::RemoveDirectoryW(Common::UTF8ToUTF16W(filename).c_str())) return true; #elif defined(ANDROID) && !defined(HAVE_LIBRETRO_VFS) - if (AndroidStorage::CanUseRawFS()) { - if (rmdir(AndroidStorage::TranslateFilePath(filename).c_str()) == 0) + if (AndroidUtils::CanUseRawFS()) { + if (rmdir(AndroidUtils::TranslateFilePath(filename).c_str()) == 0) return true; } else { - if (AndroidStorage::DeleteDocument(filename)) + if (AndroidUtils::DeleteDocument(filename)) return true; } #else @@ -421,13 +421,13 @@ bool Rename(const std::string& srcFullPath, const std::string& destFullPath) { return true; } #elif defined(ANDROID) && !defined(HAVE_LIBRETRO_VFS) - if (AndroidStorage::CanUseRawFS()) { - if (rename(AndroidStorage::TranslateFilePath(srcFullPath).c_str(), - AndroidStorage::TranslateFilePath(destFullPath).c_str()) == 0) { + if (AndroidUtils::CanUseRawFS()) { + if (rename(AndroidUtils::TranslateFilePath(srcFullPath).c_str(), + AndroidUtils::TranslateFilePath(destFullPath).c_str()) == 0) { return true; } } else { - if (AndroidStorage::MoveAndRenameFile(srcFullPath, destFullPath)) { + if (AndroidUtils::MoveAndRenameFile(srcFullPath, destFullPath)) { return true; } } @@ -496,12 +496,12 @@ bool Copy(const std::string& srcFilename, const std::string& destFilename) { }; #if defined(ANDROID) && !defined(HAVE_LIBRETRO_VFS) - if (AndroidStorage::CanUseRawFS()) { - return copy_files(AndroidStorage::TranslateFilePath(srcFilename), - AndroidStorage::TranslateFilePath(destFilename)); + if (AndroidUtils::CanUseRawFS()) { + return copy_files(AndroidUtils::TranslateFilePath(srcFilename), + AndroidUtils::TranslateFilePath(destFilename)); } else { - return AndroidStorage::CopyFile(srcFilename, std::string(GetParentPath(destFilename)), - std::string(GetFilename(destFilename))); + return AndroidUtils::CopyFile(srcFilename, std::string(GetParentPath(destFilename)), + std::string(GetFilename(destFilename))); } #else return copy_files(srcFilename, destFilename); @@ -526,12 +526,12 @@ u64 GetSize(const std::string& filename) { struct _stat64 buf; if (_wstat64(Common::UTF8ToUTF16W(filename).c_str(), &buf) == 0) #elif defined(ANDROID) && !defined(HAVE_LIBRETRO_VFS) - if (AndroidStorage::CanUseRawFS()) { - if (stat(AndroidStorage::TranslateFilePath(filename).c_str(), &buf) == 0) { + if (AndroidUtils::CanUseRawFS()) { + if (stat(AndroidUtils::TranslateFilePath(filename).c_str(), &buf) == 0) { return buf.st_size; } } else { - u64 result = AndroidStorage::GetSize(filename); + u64 result = AndroidUtils::GetSize(filename); LOG_TRACE(Common_Filesystem, "{}: {}", filename, result); return result; } @@ -608,10 +608,10 @@ std::optional> ListDirectoryEntries(const std::string& #elif defined(ANDROID) && !defined(HAVE_LIBRETRO_VFS) std::optional> ListDirectoryEntries(const std::string& directory) { - if (AndroidStorage::CanUseRawFS()) { + if (AndroidUtils::CanUseRawFS()) { std::vector entries; - DIR* dirp = opendir(AndroidStorage::TranslateFilePath(directory).c_str()); + DIR* dirp = opendir(AndroidUtils::TranslateFilePath(directory).c_str()); if (!dirp) return std::nullopt; @@ -622,7 +622,7 @@ std::optional> ListDirectoryEntries(const std::string& closedir(dirp); return entries; } else { - return AndroidStorage::GetFilesName(directory); + return AndroidUtils::GetFilesName(directory); } } @@ -1354,27 +1354,27 @@ bool IOFile::Open() { m_good = m_file != nullptr; #elif defined(ANDROID) && !defined(HAVE_LIBRETRO_VFS) - if (AndroidStorage::CanUseRawFS()) { - m_file = FOPEN(AndroidStorage::TranslateFilePath(filename).c_str(), openmode.c_str()); + if (AndroidUtils::CanUseRawFS()) { + m_file = FOPEN(AndroidUtils::TranslateFilePath(filename).c_str(), openmode.c_str()); } else { // Check whether filepath is startsWith content - AndroidStorage::AndroidOpenMode android_open_mode = AndroidStorage::ParseOpenmode(openmode); - if (android_open_mode == AndroidStorage::AndroidOpenMode::WRITE || - android_open_mode == AndroidStorage::AndroidOpenMode::READ_WRITE || - android_open_mode == AndroidStorage::AndroidOpenMode::WRITE_APPEND || - android_open_mode == AndroidStorage::AndroidOpenMode::WRITE_TRUNCATE || - android_open_mode == AndroidStorage::AndroidOpenMode::READ_WRITE_TRUNCATE || - android_open_mode == AndroidStorage::AndroidOpenMode::READ_WRITE_APPEND) { + AndroidUtils::AndroidOpenMode android_open_mode = AndroidUtils::ParseOpenmode(openmode); + if (android_open_mode == AndroidUtils::AndroidOpenMode::WRITE || + android_open_mode == AndroidUtils::AndroidOpenMode::READ_WRITE || + android_open_mode == AndroidUtils::AndroidOpenMode::WRITE_APPEND || + android_open_mode == AndroidUtils::AndroidOpenMode::WRITE_TRUNCATE || + android_open_mode == AndroidUtils::AndroidOpenMode::READ_WRITE_TRUNCATE || + android_open_mode == AndroidUtils::AndroidOpenMode::READ_WRITE_APPEND) { if (!FileUtil::Exists(filename)) { std::string directory(GetParentPath(filename)); std::string display_name(GetFilename(filename)); - if (!AndroidStorage::CreateFile(directory, display_name)) { + if (!AndroidUtils::CreateFile(directory, display_name)) { m_good = m_file != nullptr; return m_good; } } } - m_fd = AndroidStorage::OpenContentUri(filename, android_open_mode); + m_fd = AndroidUtils::OpenContentUri(filename, android_open_mode); if (m_fd != -1) { int error_num = 0; m_file = fdopen(m_fd, openmode.c_str()); diff --git a/src/common/file_util.h b/src/common/file_util.h index 56dbeea93..8484b02a1 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -35,7 +35,7 @@ #include "common/string_util.h" #endif #if defined(ANDROID) && !defined(HAVE_LIBRETRO_VFS) -#include "android_storage.h" +#include "android_utils.h" #endif #ifdef HAVE_LIBRETRO_VFS @@ -443,7 +443,7 @@ public: return fileno(filestream_get_vfs_handle(m_file)->fp); #else #ifdef ANDROID - if (!AndroidStorage::CanUseRawFS()) { + if (!AndroidUtils::CanUseRawFS()) { return m_fd; } #endif // ANDROID diff --git a/src/common/settings.cpp b/src/common/settings.cpp index ba8a84bc4..23597de81 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -5,6 +5,9 @@ #include #include #include "audio_core/dsp_interface.h" +#if defined(ANDROID) && !defined(HAVE_LIBRETRO) +#include "common/android_utils.h" +#endif #include "common/file_util.h" #include "common/settings.h" @@ -243,6 +246,17 @@ void RestoreGlobalState(bool is_powered_on) { values.disable_right_eye_render.SetGlobal(true); } +/// Gets the graphics API that should be used; not necessarily one set in settings +Settings::GraphicsAPI GetWorkingGraphicsAPI() { + auto graphics_api = Settings::values.graphics_api.GetValue(); +#if defined(ANDROID) && !defined(HAVE_LIBRETRO) + if (AndroidUtils::IsUsingAngleForOpenGL()) { + graphics_api = Settings::GraphicsAPI::Vulkan; + } +#endif + return graphics_api; +} + void LoadProfile(int index) { Settings::values.current_input_profile = Settings::values.input_profiles[index]; Settings::values.current_input_profile_index = index; diff --git a/src/common/settings.h b/src/common/settings.h index 462d79736..99e7e7777 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -685,6 +685,9 @@ void LogSettings(); // Restore the global state of all applicable settings in the Values struct void RestoreGlobalState(bool is_powered_on); +/// Gets the graphics API that should be used; not necessarily one set in settings +Settings::GraphicsAPI GetWorkingGraphicsAPI(); + // Input profiles void LoadProfile(int index); void SaveProfile(int index); diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp index e78ab9c91..281a9a49e 100644 --- a/src/video_core/renderer_base.cpp +++ b/src/video_core/renderer_base.cpp @@ -18,7 +18,7 @@ RendererBase::RendererBase(Core::System& system_, Frontend::EmuWindow& window, RendererBase::~RendererBase() = default; u32 RendererBase::GetResolutionScaleFactor() { - const auto graphics_api = Settings::values.graphics_api.GetValue(); + const auto graphics_api = Settings::GetWorkingGraphicsAPI(); if (graphics_api == Settings::GraphicsAPI::Software) { // Software renderer always render at native resolution return 1; diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index b756c65ed..8a20b9749 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp @@ -25,7 +25,7 @@ namespace VideoCore { std::unique_ptr CreateRenderer(Frontend::EmuWindow& emu_window, Frontend::EmuWindow* secondary_window, Pica::PicaCore& pica, Core::System& system) { - const Settings::GraphicsAPI graphics_api = Settings::values.graphics_api.GetValue(); + const auto graphics_api = Settings::GetWorkingGraphicsAPI(); switch (graphics_api) { #ifdef ENABLE_SOFTWARE_RENDERER case Settings::GraphicsAPI::Software: