diff --git a/src/android/app/src/main/java/io/github/lime3ds/android/NativeLibrary.kt b/src/android/app/src/main/java/io/github/lime3ds/android/NativeLibrary.kt index 1959eaba9..6aa59e513 100644 --- a/src/android/app/src/main/java/io/github/lime3ds/android/NativeLibrary.kt +++ b/src/android/app/src/main/java/io/github/lime3ds/android/NativeLibrary.kt @@ -156,11 +156,10 @@ object NativeLibrary { external fun getPerfStats(): DoubleArray /** - * Notifies the core emulation that the orientation has changed. + * Notifies the core emulation that the layout should be updated */ - external fun notifyOrientationChange(layoutOption: Int, rotation: Int, isPortrait: Boolean) + external fun updateFramebuffer(isPortrait: Boolean) - external fun notifyPortraitLayoutChange(layoutOption: Int, rotation: Int, isPortrait: Boolean) /** * Swaps the top and bottom screens. */ @@ -263,14 +262,6 @@ object NativeLibrary { get() = LimeApplication.appContext.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT - @Keep - @JvmStatic - fun landscapeScreenLayout(): Int = EmulationMenuSettings.landscapeScreenLayout - - @Keep - @JvmStatic - fun portraitScreenLayout(): Int = EmulationMenuSettings.portraitScreenLayout - @Keep @JvmStatic fun displayAlertMsg(title: String, message: String, yesNo: Boolean): Boolean { diff --git a/src/android/app/src/main/java/io/github/lime3ds/android/display/PortraitScreenLayout.kt b/src/android/app/src/main/java/io/github/lime3ds/android/display/PortraitScreenLayout.kt deleted file mode 100644 index 74d9c1820..000000000 --- a/src/android/app/src/main/java/io/github/lime3ds/android/display/PortraitScreenLayout.kt +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2023 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -package io.github.lime3ds.android.display - -enum class PortraitScreenLayout(val int: Int) { - // These must match what is defined in src/common/settings.h - TOP_FULL_WIDTH(0), - CUSTOM_PORTRAIT_LAYOUT(1); - - companion object { - fun from(int: Int): PortraitScreenLayout { - return entries.firstOrNull { it.int == int } ?: TOP_FULL_WIDTH; - } - } -} diff --git a/src/android/app/src/main/java/io/github/lime3ds/android/display/ScreenAdjustmentUtil.kt b/src/android/app/src/main/java/io/github/lime3ds/android/display/ScreenAdjustmentUtil.kt index 8d4734e29..035da2487 100644 --- a/src/android/app/src/main/java/io/github/lime3ds/android/display/ScreenAdjustmentUtil.kt +++ b/src/android/app/src/main/java/io/github/lime3ds/android/display/ScreenAdjustmentUtil.kt @@ -3,7 +3,6 @@ // Refer to the license.txt file included. package io.github.lime3ds.android.display - import android.view.WindowManager import io.github.lime3ds.android.NativeLibrary import io.github.lime3ds.android.features.settings.model.BooleanSetting @@ -26,40 +25,35 @@ class ScreenAdjustmentUtil( BooleanSetting.SWAP_SCREEN.boolean = isEnabled settings.saveSetting(BooleanSetting.SWAP_SCREEN, SettingsFile.FILE_NAME_CONFIG) } - - // TODO: Consider how cycling should handle custom layout - // right now it simply skips it fun cycleLayouts() { - val nextLayout = if (NativeLibrary.isPortraitMode) { - (EmulationMenuSettings.portraitScreenLayout + 1) % (PortraitScreenLayout.entries.size - 1) + // TODO: figure out how to pull these from R.array + val landscape_values = intArrayOf(6,1,3,4,0,5); + val portrait_values = intArrayOf(0,1); + if (NativeLibrary.isPortraitMode) { + val current_layout = IntSetting.PORTRAIT_SCREEN_LAYOUT.int + val pos = portrait_values.indexOf(current_layout) + val layout_option = portrait_values[(pos + 1) % portrait_values.size] + changePortraitOrientation(layout_option) } else { - (EmulationMenuSettings.landscapeScreenLayout + 1) % (ScreenLayout.entries.size - 1) + val current_layout = IntSetting.SCREEN_LAYOUT.int + val pos = landscape_values.indexOf(current_layout) + val layout_option = landscape_values[(pos + 1) % landscape_values.size] + changeScreenOrientation(layout_option) } - settings.loadSettings() - changeScreenOrientation(nextLayout) } fun changePortraitOrientation(layoutOption: Int) { - EmulationMenuSettings.portraitScreenLayout = layoutOption - NativeLibrary.notifyPortraitLayoutChange( - EmulationMenuSettings.portraitScreenLayout, - windowManager.defaultDisplay.rotation, - NativeLibrary::isPortraitMode.get() - ) IntSetting.PORTRAIT_SCREEN_LAYOUT.int = layoutOption settings.saveSetting(IntSetting.PORTRAIT_SCREEN_LAYOUT, SettingsFile.FILE_NAME_CONFIG) + NativeLibrary.reloadSettings() + NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode) } fun changeScreenOrientation(layoutOption: Int) { - EmulationMenuSettings.landscapeScreenLayout = layoutOption - NativeLibrary.notifyOrientationChange( - EmulationMenuSettings.landscapeScreenLayout, - windowManager.defaultDisplay.rotation, - NativeLibrary::isPortraitMode.get() - ) IntSetting.SCREEN_LAYOUT.int = layoutOption settings.saveSetting(IntSetting.SCREEN_LAYOUT, SettingsFile.FILE_NAME_CONFIG) - + NativeLibrary.reloadSettings() + NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode) } } diff --git a/src/android/app/src/main/java/io/github/lime3ds/android/display/ScreenLayout.kt b/src/android/app/src/main/java/io/github/lime3ds/android/display/ScreenLayout.kt index a6fc57e10..293b2a605 100644 --- a/src/android/app/src/main/java/io/github/lime3ds/android/display/ScreenLayout.kt +++ b/src/android/app/src/main/java/io/github/lime3ds/android/display/ScreenLayout.kt @@ -6,7 +6,7 @@ package io.github.lime3ds.android.display enum class ScreenLayout(val int: Int) { // These must match what is defined in src/common/settings.h - TOP_BOTTOM(0), + ORIGINAL(0), SINGLE_SCREEN(1), LARGE_SCREEN(2), SIDE_SCREEN(3), @@ -21,3 +21,15 @@ enum class ScreenLayout(val int: Int) { } } } + +enum class PortraitScreenLayout(val int: Int) { + // These must match what is defined in src/common/settings.h + TOP_FULL_WIDTH(0), + CUSTOM_PORTRAIT_LAYOUT(1); + + companion object { + fun from(int: Int): PortraitScreenLayout { + return entries.firstOrNull { it.int == int } ?: TOP_FULL_WIDTH; + } + } +} \ No newline at end of file diff --git a/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/model/IntSetting.kt b/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/model/IntSetting.kt index 4e240c3a5..8e6c1942d 100644 --- a/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/model/IntSetting.kt +++ b/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/model/IntSetting.kt @@ -23,7 +23,23 @@ enum class IntSetting( CARDBOARD_X_SHIFT("cardboard_x_shift", Settings.SECTION_LAYOUT, 0), CARDBOARD_Y_SHIFT("cardboard_y_shift", Settings.SECTION_LAYOUT, 0), SCREEN_LAYOUT("layout_option", Settings.SECTION_LAYOUT, 0), + LANDSCAPE_TOP_X("custom_top_x",Settings.SECTION_LAYOUT,0), + LANDSCAPE_TOP_Y("custom_top_y",Settings.SECTION_LAYOUT,0), + LANDSCAPE_TOP_WIDTH("custom_top_width",Settings.SECTION_LAYOUT,800), + LANDSCAPE_TOP_HEIGHT("custom_top_height",Settings.SECTION_LAYOUT,480), + LANDSCAPE_BOTTOM_X("custom_bottom_x",Settings.SECTION_LAYOUT,80), + LANDSCAPE_BOTTOM_Y("custom_bottom_y",Settings.SECTION_LAYOUT,480), + LANDSCAPE_BOTTOM_WIDTH("custom_bottom_width",Settings.SECTION_LAYOUT,640), + LANDSCAPE_BOTTOM_HEIGHT("custom_bottom_height",Settings.SECTION_LAYOUT,480), PORTRAIT_SCREEN_LAYOUT("portrait_layout_option",Settings.SECTION_LAYOUT,0), + PORTRAIT_TOP_X("custom_portrait_top_x",Settings.SECTION_LAYOUT,0), + PORTRAIT_TOP_Y("custom_portrait_top_y",Settings.SECTION_LAYOUT,0), + PORTRAIT_TOP_WIDTH("custom_portrait_top_width",Settings.SECTION_LAYOUT,800), + PORTRAIT_TOP_HEIGHT("custom_portrait_top_height",Settings.SECTION_LAYOUT,480), + PORTRAIT_BOTTOM_X("custom_portrait_bottom_x",Settings.SECTION_LAYOUT,80), + PORTRAIT_BOTTOM_Y("custom_portrait_bottom_y",Settings.SECTION_LAYOUT,480), + PORTRAIT_BOTTOM_WIDTH("custom_portrait_bottom_width",Settings.SECTION_LAYOUT,640), + PORTRAIT_BOTTOM_HEIGHT("custom_portrait_bottom_height",Settings.SECTION_LAYOUT,480), AUDIO_INPUT_TYPE("output_type", Settings.SECTION_AUDIO, 0), NEW_3DS("is_new_3ds", Settings.SECTION_SYSTEM, 1), LLE_APPLETS("lle_applets", Settings.SECTION_SYSTEM, 0), diff --git a/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/model/Settings.kt b/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/model/Settings.kt index d13d324d7..32227833b 100644 --- a/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/model/Settings.kt +++ b/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/model/Settings.kt @@ -109,6 +109,8 @@ class Settings { const val SECTION_AUDIO = "Audio" const val SECTION_DEBUG = "Debugging" const val SECTION_THEME = "Theme" + const val SECTION_CUSTOM_LANDSCAPE = "Custom Landscape Layout" + const val SECTION_CUSTOM_PORTRAIT = "Custom Portrait Layout" const val KEY_BUTTON_A = "button_a" const val KEY_BUTTON_B = "button_b" diff --git a/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/ui/SettingsActivityPresenter.kt b/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/ui/SettingsActivityPresenter.kt index 65307d0d2..6e04bd8d5 100644 --- a/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/ui/SettingsActivityPresenter.kt +++ b/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/ui/SettingsActivityPresenter.kt @@ -7,6 +7,7 @@ package io.github.lime3ds.android.features.settings.ui import android.os.Bundle import android.text.TextUtils import io.github.lime3ds.android.NativeLibrary +import io.github.lime3ds.android.features.settings.model.IntSetting import io.github.lime3ds.android.features.settings.model.Settings import io.github.lime3ds.android.utils.SystemSaveGame import io.github.lime3ds.android.utils.DirectoryInitialization @@ -56,6 +57,9 @@ class SettingsActivityPresenter(private val activityView: SettingsActivityView) Log.debug("[SettingsActivity] Settings activity stopping. Saving settings to INI...") settings.saveSettings(activityView) SystemSaveGame.save() + //added to ensure that layout changes take effect as soon as settings window closes + NativeLibrary.reloadSettings() + NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode) } NativeLibrary.reloadSettings() } diff --git a/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/ui/SettingsAdapter.kt b/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/ui/SettingsAdapter.kt index 6806991a8..d50269eff 100644 --- a/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/ui/SettingsAdapter.kt +++ b/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/ui/SettingsAdapter.kt @@ -7,13 +7,16 @@ package io.github.lime3ds.android.features.settings.ui import android.annotation.SuppressLint import android.content.Context import android.content.DialogInterface +import android.graphics.Color import android.icu.util.Calendar import android.icu.util.TimeZone +import android.text.Editable import android.text.InputFilter +import android.text.TextWatcher import android.text.format.DateFormat import android.view.LayoutInflater import android.view.ViewGroup -import android.widget.TextView +import android.widget.EditText import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.core.widget.doOnTextChanged @@ -22,6 +25,8 @@ import androidx.recyclerview.widget.RecyclerView import com.google.android.material.datepicker.MaterialDatePicker import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.slider.Slider +import com.google.android.material.textfield.TextInputEditText +import com.google.android.material.textfield.TextInputLayout import com.google.android.material.timepicker.MaterialTimePicker import com.google.android.material.timepicker.TimeFormat import io.github.lime3ds.android.R @@ -73,7 +78,8 @@ class SettingsAdapter( private var clickedPosition: Int private var dialog: AlertDialog? = null private var sliderProgress = 0 - private var textSliderValue: TextView? = null + private var textSliderValue: TextInputEditText? = null + private var textInputLayout: TextInputLayout? = null private var textInputValue: String = "" private var defaultCancelListener = @@ -256,18 +262,36 @@ class SettingsAdapter( val inflater = LayoutInflater.from(context) val sliderBinding = DialogSliderBinding.inflate(inflater) - + textInputLayout = sliderBinding.textInput textSliderValue = sliderBinding.textValue - textSliderValue!!.text = sliderProgress.toString() - sliderBinding.textUnits.text = item.units + textSliderValue!!.setText(sliderProgress.toString()) + //sliderBinding.textUnits.text = item.units + textInputLayout!!.suffixText = item.units sliderBinding.slider.apply { valueFrom = item.min.toFloat() valueTo = item.max.toFloat() value = sliderProgress.toFloat() + textSliderValue!!.addTextChangedListener( object : TextWatcher { + override fun afterTextChanged(s: Editable) { + val textValue = s.toString().toIntOrNull(); + if (textValue == null || textValue < valueFrom || textValue > valueTo) { + textInputLayout!!.error ="Inappropriate value" + } else { + textInputLayout!!.error = null + value = textValue.toFloat(); + } + } + override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {} + override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {} + }) + addOnChangeListener { _: Slider, value: Float, _: Boolean -> sliderProgress = value.toInt() - textSliderValue!!.text = sliderProgress.toString() + if (textSliderValue!!.text.toString() != value.toInt().toString()) { + textSliderValue!!.setText(value.toInt().toString()) + textSliderValue!!.setSelection(textSliderValue!!.length()) + } } } diff --git a/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/ui/SettingsFragmentPresenter.kt index df0231d4f..18448ce1e 100644 --- a/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/io/github/lime3ds/android/features/settings/ui/SettingsFragmentPresenter.kt @@ -6,6 +6,7 @@ package io.github.lime3ds.android.features.settings.ui import android.content.Context import android.content.SharedPreferences +import android.content.res.Resources import android.hardware.camera2.CameraAccessException import android.hardware.camera2.CameraCharacteristics import android.hardware.camera2.CameraManager @@ -42,6 +43,7 @@ import io.github.lime3ds.android.utils.GpuDriverHelper import io.github.lime3ds.android.utils.Log import io.github.lime3ds.android.utils.SystemSaveGame import io.github.lime3ds.android.utils.ThemeUtil +import kotlin.math.min class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) { private var menuTag: String? = null @@ -91,9 +93,12 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) Settings.SECTION_CAMERA -> addCameraSettings(sl) Settings.SECTION_CONTROLS -> addControlsSettings(sl) Settings.SECTION_RENDERER -> addGraphicsSettings(sl) + Settings.SECTION_LAYOUT -> addLayoutSettings(sl) Settings.SECTION_AUDIO -> addAudioSettings(sl) Settings.SECTION_DEBUG -> addDebugSettings(sl) Settings.SECTION_THEME -> addThemeSettings(sl) + Settings.SECTION_CUSTOM_LANDSCAPE -> addCustomLandscapeSettings(sl) + Settings.SECTION_CUSTOM_PORTRAIT -> addCustomPortraitSettings(sl) else -> { fragmentView.showToastMessage("Unimplemented menu", false) return @@ -103,6 +108,23 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) fragmentView.showSettingsList(settingsList!!) } + /** Returns the portrait mode width */ + private fun getWidth(): Int { + val dm = Resources.getSystem().displayMetrics; + return if (dm.widthPixels < dm.heightPixels) + dm.widthPixels + else + dm.heightPixels + } + + private fun getHeight(): Int { + val dm = Resources.getSystem().displayMetrics; + return if (dm.widthPixels < dm.heightPixels) + dm.heightPixels + else + dm.widthPixels + } + private fun addConfigSettings(sl: ArrayList) { settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_settings)) sl.apply { @@ -146,6 +168,14 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) Settings.SECTION_RENDERER ) ) + add( + SubmenuSetting( + R.string.preferences_layout, + 0, + R.drawable.ic_fit_screen, + Settings.SECTION_LAYOUT + ) + ) add( SubmenuSetting( R.string.preferences_audio, @@ -162,6 +192,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) Settings.SECTION_DEBUG ) ) + add( RunnableSetting( R.string.reset_to_default, @@ -873,6 +904,262 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) } } + private fun addLayoutSettings(sl: ArrayList) { + settingsActivity.setToolbarTitle("Layout") + sl.apply { + add( + SingleChoiceSetting( + IntSetting.SCREEN_LAYOUT, + R.string.emulation_switch_screen_layout, + 0, + R.array.landscapeLayouts, + R.array.landscapeLayoutValues, + IntSetting.SCREEN_LAYOUT.key, + IntSetting.SCREEN_LAYOUT.defaultValue + ) + ) + add( + SingleChoiceSetting( + IntSetting.PORTRAIT_SCREEN_LAYOUT, + R.string.emulation_switch_portrait_layout, + 0, + R.array.portraitLayouts, + R.array.portraitLayoutValues, + IntSetting.PORTRAIT_SCREEN_LAYOUT.key, + IntSetting.PORTRAIT_SCREEN_LAYOUT.defaultValue + ) + ) + add( + SubmenuSetting( + R.string.emulation_landscape_custom_layout, + 0, + R.drawable.ic_fit_screen, + Settings.SECTION_CUSTOM_LANDSCAPE + ) + ) + add( + SubmenuSetting( + R.string.emulation_portrait_custom_layout, + 0, + R.drawable.ic_portrait_fit_screen, + Settings.SECTION_CUSTOM_PORTRAIT + ) + ) + + + } + } + + private fun addCustomLandscapeSettings(sl: ArrayList) { + settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.emulation_landscape_custom_layout)) + sl.apply { + add(HeaderSetting(R.string.emulation_top_screen)) + add( + SliderSetting( + IntSetting.LANDSCAPE_TOP_X, + R.string.emulation_custom_layout_x, + 0, + 0, + getHeight(), + "px", + IntSetting.LANDSCAPE_TOP_X.key, + IntSetting.LANDSCAPE_TOP_X.defaultValue.toFloat() + ) + ) + add( + SliderSetting( + IntSetting.LANDSCAPE_TOP_Y, + R.string.emulation_custom_layout_y, + 0, + 0, + getWidth(), + "px", + IntSetting.LANDSCAPE_TOP_Y.key, + IntSetting.LANDSCAPE_TOP_Y.defaultValue.toFloat() + ) + ) + add( + SliderSetting( + IntSetting.LANDSCAPE_TOP_WIDTH, + R.string.emulation_custom_layout_width, + 0, + 0, + getHeight(), + "px", + IntSetting.LANDSCAPE_TOP_WIDTH.key, + IntSetting.LANDSCAPE_TOP_WIDTH.defaultValue.toFloat() + ) + ) + add( + SliderSetting( + IntSetting.LANDSCAPE_TOP_HEIGHT, + R.string.emulation_custom_layout_height, + 0, + 0, + getWidth(), + "px", + IntSetting.LANDSCAPE_TOP_HEIGHT.key, + IntSetting.LANDSCAPE_TOP_HEIGHT.defaultValue.toFloat() + ) + ) + add(HeaderSetting(R.string.emulation_bottom_screen)) + add( + SliderSetting( + IntSetting.LANDSCAPE_BOTTOM_X, + R.string.emulation_custom_layout_x, + 0, + 0, + getHeight(), + "px", + IntSetting.LANDSCAPE_BOTTOM_X.key, + IntSetting.LANDSCAPE_BOTTOM_X.defaultValue.toFloat() + ) + ) + add( + SliderSetting( + IntSetting.LANDSCAPE_BOTTOM_Y, + R.string.emulation_custom_layout_y, + 0, + 0, + getWidth(), + "px", + IntSetting.LANDSCAPE_BOTTOM_Y.key, + IntSetting.LANDSCAPE_BOTTOM_Y.defaultValue.toFloat() + ) + ) + add( + SliderSetting( + IntSetting.LANDSCAPE_BOTTOM_WIDTH, + R.string.emulation_custom_layout_width, + 0, + 0, + getHeight(), + "px", + IntSetting.LANDSCAPE_BOTTOM_WIDTH.key, + IntSetting.LANDSCAPE_BOTTOM_WIDTH.defaultValue.toFloat() + ) + ) + add( + SliderSetting( + IntSetting.LANDSCAPE_BOTTOM_HEIGHT, + R.string.emulation_custom_layout_height, + 0, + 0, + getWidth(), + "px", + IntSetting.LANDSCAPE_BOTTOM_HEIGHT.key, + IntSetting.LANDSCAPE_BOTTOM_HEIGHT.defaultValue.toFloat() + ) + ) + } + + } + + private fun addCustomPortraitSettings(sl: ArrayList) { + settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.emulation_portrait_custom_layout)) + sl.apply { + add(HeaderSetting(R.string.emulation_top_screen)) + add( + SliderSetting( + IntSetting.PORTRAIT_TOP_X, + R.string.emulation_custom_layout_x, + 0, + 0, + getWidth(), + "px", + IntSetting.PORTRAIT_TOP_X.key, + IntSetting.PORTRAIT_TOP_X.defaultValue.toFloat() + ) + ) + add( + SliderSetting( + IntSetting.PORTRAIT_TOP_Y, + R.string.emulation_custom_layout_y, + 0, + 0, + getHeight(), + "px", + IntSetting.PORTRAIT_TOP_Y.key, + IntSetting.PORTRAIT_TOP_Y.defaultValue.toFloat() + ) + ) + add( + SliderSetting( + IntSetting.PORTRAIT_TOP_WIDTH, + R.string.emulation_custom_layout_width, + 0, + 0, + getWidth(), + "px", + IntSetting.PORTRAIT_TOP_WIDTH.key, + IntSetting.PORTRAIT_TOP_WIDTH.defaultValue.toFloat() + ) + ) + add( + SliderSetting( + IntSetting.PORTRAIT_TOP_HEIGHT, + R.string.emulation_custom_layout_height, + 0, + 0, + getHeight(), + "px", + IntSetting.PORTRAIT_TOP_HEIGHT.key, + IntSetting.PORTRAIT_TOP_HEIGHT.defaultValue.toFloat() + ) + ) + add(HeaderSetting(R.string.emulation_bottom_screen)) + add( + SliderSetting( + IntSetting.PORTRAIT_BOTTOM_X, + R.string.emulation_custom_layout_x, + 0, + 0, + getWidth(), + "px", + IntSetting.PORTRAIT_BOTTOM_X.key, + IntSetting.PORTRAIT_BOTTOM_X.defaultValue.toFloat() + ) + ) + add( + SliderSetting( + IntSetting.PORTRAIT_BOTTOM_Y, + R.string.emulation_custom_layout_y, + 0, + 0, + getHeight(), + "px", + IntSetting.PORTRAIT_BOTTOM_Y.key, + IntSetting.PORTRAIT_BOTTOM_Y.defaultValue.toFloat() + ) + ) + add( + SliderSetting( + IntSetting.PORTRAIT_BOTTOM_WIDTH, + R.string.emulation_custom_layout_width, + 0, + 0, + getWidth(), + "px", + IntSetting.PORTRAIT_BOTTOM_WIDTH.key, + IntSetting.PORTRAIT_BOTTOM_WIDTH.defaultValue.toFloat() + ) + ) + add( + SliderSetting( + IntSetting.PORTRAIT_BOTTOM_HEIGHT, + R.string.emulation_custom_layout_height, + 0, + 0, + getHeight(), + "px", + IntSetting.PORTRAIT_BOTTOM_HEIGHT.key, + IntSetting.PORTRAIT_BOTTOM_HEIGHT.defaultValue.toFloat() + ) + ) + } + + } + private fun addAudioSettings(sl: ArrayList) { settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_audio)) sl.apply { diff --git a/src/android/app/src/main/java/io/github/lime3ds/android/fragments/EmulationFragment.kt b/src/android/app/src/main/java/io/github/lime3ds/android/fragments/EmulationFragment.kt index 455ce3e89..a67d4a775 100644 --- a/src/android/app/src/main/java/io/github/lime3ds/android/fragments/EmulationFragment.kt +++ b/src/android/app/src/main/java/io/github/lime3ds/android/fragments/EmulationFragment.kt @@ -13,6 +13,8 @@ import android.os.Bundle import android.os.Handler import android.os.Looper import android.os.SystemClock +import android.text.Editable +import android.text.TextWatcher import android.view.Choreographer import android.view.LayoutInflater import android.view.MotionEvent @@ -54,6 +56,7 @@ import io.github.lime3ds.android.databinding.FragmentEmulationBinding import io.github.lime3ds.android.display.PortraitScreenLayout import io.github.lime3ds.android.display.ScreenAdjustmentUtil import io.github.lime3ds.android.display.ScreenLayout +import io.github.lime3ds.android.features.settings.model.IntSetting import io.github.lime3ds.android.features.settings.model.SettingsViewModel import io.github.lime3ds.android.features.settings.ui.SettingsActivity import io.github.lime3ds.android.features.settings.utils.SettingsFile @@ -324,6 +327,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram SettingsFile.FILE_NAME_CONFIG, "" ) + true } @@ -786,7 +790,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram popupMenu.menuInflater.inflate(R.menu.menu_landscape_screen_layout, popupMenu.menu) - val layoutOptionMenuItem = when (EmulationMenuSettings.landscapeScreenLayout) { + val layoutOptionMenuItem = when (IntSetting.SCREEN_LAYOUT.int) { + ScreenLayout.ORIGINAL.int -> + R.id.menu_screen_layout_original + ScreenLayout.SINGLE_SCREEN.int -> R.id.menu_screen_layout_single @@ -825,7 +832,17 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram true } + R.id.menu_screen_layout_original -> { + screenAdjustmentUtil.changeScreenOrientation(ScreenLayout.ORIGINAL.int) + true + } + R.id.menu_screen_layout_custom -> { + Toast.makeText( + requireContext(), + R.string.emulation_adjust_custom_layout, + Toast.LENGTH_LONG + ).show() screenAdjustmentUtil.changeScreenOrientation(ScreenLayout.CUSTOM_LAYOUT.int) true } @@ -845,7 +862,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram popupMenu.menuInflater.inflate(R.menu.menu_portrait_screen_layout, popupMenu.menu) - val layoutOptionMenuItem = when (EmulationMenuSettings.portraitScreenLayout) { + val layoutOptionMenuItem = when (IntSetting.PORTRAIT_SCREEN_LAYOUT.int) { PortraitScreenLayout.TOP_FULL_WIDTH.int -> R.id.menu_portrait_layout_top_full @@ -867,6 +884,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram } R.id.menu_portrait_layout_custom -> { + Toast.makeText( + requireContext(), + R.string.emulation_adjust_custom_layout, + Toast.LENGTH_LONG + ).show() screenAdjustmentUtil.changePortraitOrientation(PortraitScreenLayout.CUSTOM_PORTRAIT_LAYOUT.int) true } @@ -919,14 +941,32 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram sliderBinding.apply { slider.valueTo = 150f + slider.valueFrom = 0f slider.value = preferences.getInt(target, 50).toFloat() + textValue.setText((slider.value + 50).toInt().toString()) + textValue.addTextChangedListener( object : TextWatcher { + override fun afterTextChanged(s: Editable) { + val value = s.toString().toIntOrNull() + if (value == null || value < 50 || value > 150) { + textInput.error = "Inappropriate Value" + } else { + textInput.error = null + slider.value = value.toFloat() - 50 + } + } + override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {} + override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {} + }) slider.addOnChangeListener( Slider.OnChangeListener { slider: Slider, progress: Float, _: Boolean -> - textValue.text = (progress.toInt() + 50).toString() - setControlScale(slider.value.toInt(), target) + if (textValue.text.toString() != (slider.value + 50).toInt().toString()) { + textValue.setText((slider.value + 50).toInt().toString()) + textValue.setSelection(textValue.length()) + setControlScale(slider.value.toInt(), target) + } + }) - textValue.text = (sliderBinding.slider.value.toInt() + 50).toString() - textUnits.text = "%" + textInput.suffixText = "%" } val previousProgress = sliderBinding.slider.value.toInt() @@ -949,15 +989,36 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram val sliderBinding = DialogSliderBinding.inflate(layoutInflater) sliderBinding.apply { + slider.valueFrom = 0f slider.valueTo = 100f slider.value = preferences.getInt("controlOpacity", 50).toFloat() - slider.addOnChangeListener( - Slider.OnChangeListener { slider: Slider, progress: Float, _: Boolean -> - textValue.text = (progress.toInt()).toString() - setControlOpacity(slider.value.toInt()) - }) - textValue.text = (sliderBinding.slider.value.toInt()).toString() - textUnits.text = "%" + textValue.setText(slider.value.toInt().toString()) + + textValue.addTextChangedListener( object : TextWatcher { + override fun afterTextChanged(s: Editable) { + val value = s.toString().toIntOrNull() + if (value == null || value < slider.valueFrom || value > slider.valueTo) { + textInput.error = "Inappropriate Value" + } else { + textInput.error = null + slider.value = value.toFloat() + } + } + override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {} + override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {} + }) + + + slider.addOnChangeListener { _: Slider, value: Float, _: Boolean -> + + if (textValue.text.toString() != slider.value.toInt().toString()) { + textValue.setText(slider.value.toInt().toString()) + textValue.setSelection(textValue.length()) + setControlOpacity(slider.value.toInt()) + } + } + + textInput.suffixText = "%" } val previousProgress = sliderBinding.slider.value.toInt() @@ -986,7 +1047,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram private fun resetScale(target: String) { preferences.edit().putInt( target, - 50 + 100 ).apply() } diff --git a/src/android/app/src/main/java/io/github/lime3ds/android/utils/EmulationMenuSettings.kt b/src/android/app/src/main/java/io/github/lime3ds/android/utils/EmulationMenuSettings.kt index eead8dc9e..d81db7ede 100644 --- a/src/android/app/src/main/java/io/github/lime3ds/android/utils/EmulationMenuSettings.kt +++ b/src/android/app/src/main/java/io/github/lime3ds/android/utils/EmulationMenuSettings.kt @@ -7,8 +7,6 @@ package io.github.lime3ds.android.utils import androidx.drawerlayout.widget.DrawerLayout import androidx.preference.PreferenceManager import io.github.lime3ds.android.LimeApplication -import io.github.lime3ds.android.display.PortraitScreenLayout -import io.github.lime3ds.android.display.ScreenLayout object EmulationMenuSettings { private val preferences = @@ -28,26 +26,7 @@ object EmulationMenuSettings { .putBoolean("EmulationMenuSettings_DpadSlideEnable", value) .apply() } - var landscapeScreenLayout: Int - get() = preferences.getInt( - "EmulationMenuSettings_LandscapeScreenLayout", - ScreenLayout.LARGE_SCREEN.int - ) - set(value) { - preferences.edit() - .putInt("EmulationMenuSettings_LandscapeScreenLayout", value) - .apply() - } - var portraitScreenLayout: Int - get() = preferences.getInt( - "EmulationMenuSettings_PortraitScreenLayout", - PortraitScreenLayout.TOP_FULL_WIDTH.int - ) - set(value) { - preferences.edit() - .putInt("EmulationMenuSettings_PortraitScreenLayout", value) - .apply() - } + var showFps: Boolean get() = preferences.getBoolean("EmulationMenuSettings_ShowFps", false) set(value) { diff --git a/src/android/app/src/main/jni/config.cpp b/src/android/app/src/main/jni/config.cpp index ff016a8e5..a880e3985 100644 --- a/src/android/app/src/main/jni/config.cpp +++ b/src/android/app/src/main/jni/config.cpp @@ -175,7 +175,6 @@ void Config::ReadValues() { // Layout Settings::values.layout_option = static_cast(sdl2_config->GetInteger( "Layout", "layout_option", static_cast(Settings::LayoutOption::LargeScreen))); - ReadSetting("Layout", Settings::values.custom_layout); ReadSetting("Layout", Settings::values.custom_top_x); ReadSetting("Layout", Settings::values.custom_top_y); ReadSetting("Layout", Settings::values.custom_top_width); diff --git a/src/android/app/src/main/jni/default_ini.h b/src/android/app/src/main/jni/default_ini.h index e7e67e646..544c0c716 100644 --- a/src/android/app/src/main/jni/default_ini.h +++ b/src/android/app/src/main/jni/default_ini.h @@ -180,16 +180,19 @@ filter_mode = [Layout] # Layout for the screen inside the render window, landscape mode -# 0 (default): Default Top Bottom Screen, +# 0: Top/Bottom *currently unsupported on android* # 1: Single Screen Only, -# 2: Large Screen Small Screen +# 2: *currently unsupported on android* # 3: Side by Side # 4: Hybrid # 5: Custom Layout +# 6: (default) Large screen / small screen layout_option = # Screen placement when using Custom layout option # 0x, 0y is the top left corner of the render window. +# suggested aspect ratio for top screen is 5:3 +# suggested aspect ratio for bottom screen is 4:3 custom_top_x = custom_top_y = custom_top_width = 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 c589ce54c..6442c3b88 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 @@ -21,18 +21,6 @@ static bool IsPortraitMode() { IDCache::GetNativeLibraryClass(), IDCache::GetIsPortraitMode()); } -static void UpdateLandscapeScreenLayout() { - Settings::values.layout_option = - static_cast(IDCache::GetEnvForThread()->CallStaticIntMethod( - IDCache::GetNativeLibraryClass(), IDCache::GetLandscapeScreenLayout())); -} - -static void UpdatePortraitScreenLayout() { - Settings::values.portrait_layout_option = - static_cast(IDCache::GetEnvForThread()->CallStaticIntMethod( - IDCache::GetNativeLibraryClass(), IDCache::GetPortraitScreenLayout())); -} - bool EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) { if (render_window == surface) { return false; @@ -63,8 +51,6 @@ void EmuWindow_Android::OnTouchMoved(int x, int y) { } void EmuWindow_Android::OnFramebufferSizeChanged() { - UpdateLandscapeScreenLayout(); - UpdatePortraitScreenLayout(); const bool is_portrait_mode{IsPortraitMode()}; const int bigger{window_width > window_height ? window_width : window_height}; diff --git a/src/android/app/src/main/jni/id_cache.cpp b/src/android/app/src/main/jni/id_cache.cpp index b3bf27f96..c9cb0baca 100644 --- a/src/android/app/src/main/jni/id_cache.cpp +++ b/src/android/app/src/main/jni/id_cache.cpp @@ -177,10 +177,6 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) { s_native_library_class, "onCoreError", "(Lio/github/lime3ds/android/NativeLibrary$CoreError;Ljava/lang/String;)Z"); s_is_portrait_mode = env->GetStaticMethodID(s_native_library_class, "isPortraitMode", "()Z"); - s_landscape_screen_layout = - env->GetStaticMethodID(s_native_library_class, "landscapeScreenLayout", "()I"); - s_portrait_screen_layout = - env->GetStaticMethodID(s_native_library_class, "portraitScreenLayout", "()I"); s_exit_emulation_activity = env->GetStaticMethodID(s_native_library_class, "exitEmulationActivity", "(I)V"); s_request_camera_permission = diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index ff1636730..c9ddcf863 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -346,29 +346,13 @@ void JNICALL Java_io_github_lime3ds_android_NativeLibrary_enableAdrenoTurboMode( EnableAdrenoTurboMode(enable); } -void Java_io_github_lime3ds_android_NativeLibrary_notifyOrientationChange( - [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jobject obj, jint layout_option, jint rotation, - jboolean portrait) { - Settings::values.layout_option = static_cast(layout_option); +void Java_io_github_lime3ds_android_NativeLibrary_updateFramebuffer([[maybe_unused]] JNIEnv* env, + [[maybe_unused]] jobject obj, + jboolean is_portrait_mode) { auto& system = Core::System::GetInstance(); if (system.IsPoweredOn()) { - - system.GPU().Renderer().UpdateCurrentFramebufferLayout(portrait); + system.GPU().Renderer().UpdateCurrentFramebufferLayout(is_portrait_mode); } - InputManager::screen_rotation = rotation; - Camera::NDK::g_rotation = rotation; -} - -void Java_io_github_lime3ds_android_NativeLibrary_notifyPortraitLayoutChange( - [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jobject obj, jint layout_option, jint rotation) { - Settings::values.portrait_layout_option = - static_cast(layout_option); - auto& system = Core::System::GetInstance(); - if (system.IsPoweredOn()) { - system.GPU().Renderer().UpdateCurrentFramebufferLayout(!(rotation % 2)); - } - InputManager::screen_rotation = rotation; - Camera::NDK::g_rotation = rotation; } void Java_io_github_lime3ds_android_NativeLibrary_swapScreens([[maybe_unused]] JNIEnv* env, diff --git a/src/android/app/src/main/res/drawable/ic_portrait_fit_screen.xml b/src/android/app/src/main/res/drawable/ic_portrait_fit_screen.xml new file mode 100644 index 000000000..299572089 --- /dev/null +++ b/src/android/app/src/main/res/drawable/ic_portrait_fit_screen.xml @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/src/android/app/src/main/res/layout/dialog_slider.xml b/src/android/app/src/main/res/layout/dialog_slider.xml index 59719e013..cb0cb2207 100644 --- a/src/android/app/src/main/res/layout/dialog_slider.xml +++ b/src/android/app/src/main/res/layout/dialog_slider.xml @@ -1,6 +1,7 @@ @@ -13,25 +14,30 @@ android:layout_marginRight="@dimen/spacing_large" android:layout_alignParentEnd="true" android:layout_alignParentStart="true" - android:layout_below="@+id/text_value" + android:layout_below="@+id/text_input" android:layout_marginBottom="@dimen/spacing_medlarge" /> - + + + android:id="@+id/text_value" + android:layout_alignParentTop="true" + android:layout_centerHorizontal="true" + android:layout_marginTop="@dimen/spacing_medlarge" + android:layout_marginBottom="@dimen/spacing_medlarge" /> - + diff --git a/src/android/app/src/main/res/menu/menu_emulation.xml b/src/android/app/src/main/res/menu/menu_emulation.xml deleted file mode 100644 index d09f99d93..000000000 --- a/src/android/app/src/main/res/menu/menu_emulation.xml +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/android/app/src/main/res/menu/menu_in_game.xml b/src/android/app/src/main/res/menu/menu_in_game.xml index 4dcfdcb47..d42d59264 100644 --- a/src/android/app/src/main/res/menu/menu_in_game.xml +++ b/src/android/app/src/main/res/menu/menu_in_game.xml @@ -29,12 +29,13 @@ + + + diff --git a/src/android/app/src/main/res/menu/menu_portrait_screen_layout.xml b/src/android/app/src/main/res/menu/menu_portrait_screen_layout.xml index 33bb729a6..afa9f27e0 100644 --- a/src/android/app/src/main/res/menu/menu_portrait_screen_layout.xml +++ b/src/android/app/src/main/res/menu/menu_portrait_screen_layout.xml @@ -10,6 +10,7 @@ + diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml index 0cb329253..3439f727b 100644 --- a/src/android/app/src/main/res/values/arrays.xml +++ b/src/android/app/src/main/res/values/arrays.xml @@ -11,6 +11,37 @@ 1 + + @string/emulation_screen_layout_landscape + @string/emulation_screen_layout_single + @string/emulation_screen_layout_sidebyside + @string/emulation_screen_layout_hybrid + @string/emulation_screen_layout_original + @string/emulation_screen_layout_custom + + + + 6 + 1 + 3 + 4 + 0 + 5 + + + + @string/emulation_portrait_layout_top_full + @string/emulation_screen_layout_custom + + + + 0 + 1 + + @string/auto_select @string/system_region_jpn diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 744683d30..21a39d58e 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -330,7 +330,7 @@ Audio Debug Theme and Color - + Layout Your ROM is Encrypted Invalid ROM format @@ -365,8 +365,18 @@ Single Screen Side by Side Screens Hybrid Screens + Original Default Custom Layout + Adjust Custom Layout in Settings + Landscape Custom Layout + Portrait Custom Layout + Top Screen + Bottom Screen + X-Position + Y-Position + Width + Height Cycle Layouts Swap Screens Reset Overlay diff --git a/src/common/settings.h b/src/common/settings.h index 4d91f81b4..d2c6fd938 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -490,9 +490,6 @@ struct Values { SwitchableSetting upright_screen{false, "upright_screen"}; SwitchableSetting large_screen_proportion{4.f, 1.f, 16.f, "large_screen_proportion"}; - // I think the custom_layout setting below is no longer needed - // since custom layout is now just part of the layout option above? - Setting custom_layout{false, "custom_layout"}; Setting custom_top_x{0, "custom_top_x"}; Setting custom_top_y{0, "custom_top_y"}; Setting custom_top_width{800, "custom_top_width"}; diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp index 8c67aa7c1..b2e74cf9b 100644 --- a/src/core/frontend/framebuffer_layout.cpp +++ b/src/core/frontend/framebuffer_layout.cpp @@ -121,7 +121,7 @@ FramebufferLayout PortraitTopFullFrameLayout(u32 width, u32 height, bool swapped ASSERT(width > 0); ASSERT(height > 0); - FramebufferLayout res{width, height, true, true, {}, {}}; + FramebufferLayout res{width, height, true, true, {}, {}, true, true}; // Default layout gives equal screen sizes to the top and bottom screen Common::Rectangle screen_window_area{0, 0, width, height / 2}; Common::Rectangle top_screen = MaxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO); @@ -305,7 +305,7 @@ FramebufferLayout HybridScreenLayout(u32 width, u32 height, bool swapped, bool u ASSERT(width > 0); ASSERT(height > 0); - FramebufferLayout res{width, height, true, true, {}, {}, !upright, true, {}}; + FramebufferLayout res{width, height, true, true, {}, {}, !upright, false, true, {}}; // Split the window into two parts. Give 2.25x width to the main screen, // and make a bar on the right side with 1x width top screen and 1.25x width bottom screen @@ -386,7 +386,8 @@ FramebufferLayout CustomFrameLayout(u32 width, u32 height, bool is_swapped, bool ASSERT(width > 0); ASSERT(height > 0); - FramebufferLayout res{width, height, true, true, {}, {}, !Settings::values.upright_screen}; + FramebufferLayout res{ + width, height, true, true, {}, {}, !Settings::values.upright_screen, is_portrait_mode}; u16 top_x = is_portrait_mode ? Settings::values.custom_portrait_top_x.GetValue() : Settings::values.custom_top_x.GetValue(); u16 top_width = is_portrait_mode ? Settings::values.custom_portrait_top_width.GetValue() @@ -629,9 +630,7 @@ FramebufferLayout GetCardboardSettings(const FramebufferLayout& layout) { return new_layout; } -/*f - * TODO: remove this? - */ + std::pair GetMinimumSizeFromPortraitLayout() { u32 min_width, min_height; min_width = Core::kScreenTopWidth; diff --git a/src/core/frontend/framebuffer_layout.h b/src/core/frontend/framebuffer_layout.h index 98565ed7c..054072006 100644 --- a/src/core/frontend/framebuffer_layout.h +++ b/src/core/frontend/framebuffer_layout.h @@ -61,7 +61,7 @@ struct FramebufferLayout { Common::Rectangle top_screen; Common::Rectangle bottom_screen; bool is_rotated = true; - + bool is_portrait = false; bool additional_screen_enabled; Common::Rectangle additional_screen; diff --git a/src/lime/config.cpp b/src/lime/config.cpp index 49962b1d2..81c520bf5 100644 --- a/src/lime/config.cpp +++ b/src/lime/config.cpp @@ -164,8 +164,6 @@ void Config::ReadValues() { ReadSetting("Layout", Settings::values.swap_screen); ReadSetting("Layout", Settings::values.upright_screen); ReadSetting("Layout", Settings::values.large_screen_proportion); - - ReadSetting("Layout", Settings::values.custom_layout); ReadSetting("Layout", Settings::values.custom_top_x); ReadSetting("Layout", Settings::values.custom_top_y); ReadSetting("Layout", Settings::values.custom_top_width); diff --git a/src/lime/default_ini.h b/src/lime/default_ini.h index fa1911971..a597a3839 100644 --- a/src/lime/default_ini.h +++ b/src/lime/default_ini.h @@ -182,7 +182,7 @@ filter_mode = [Layout] # Layout for the screen inside the render window. -# 0 (default): Default Top Bottom Screen +# 0 (default): Default Above/Below Screen # 1: Single Screen Only # 2: Large Screen Small Screen # 3: Side by Side @@ -191,10 +191,6 @@ filter_mode = # 6: Custom Layout layout_option = -# Toggle custom layout (using the settings below) on or off. -# 0 (default): Off, 1: On -custom_layout = - # Screen placement when using Custom layout option # 0x, 0y is the top left corner of the render window. custom_top_x = diff --git a/src/lime_qt/configuration/config.cpp b/src/lime_qt/configuration/config.cpp index ce5c632ac..349141dd5 100644 --- a/src/lime_qt/configuration/config.cpp +++ b/src/lime_qt/configuration/config.cpp @@ -520,8 +520,6 @@ void Config::ReadLayoutValues() { if (global) { ReadBasicSetting(Settings::values.mono_render_option); - - ReadBasicSetting(Settings::values.custom_layout); ReadBasicSetting(Settings::values.custom_top_x); ReadBasicSetting(Settings::values.custom_top_y); ReadBasicSetting(Settings::values.custom_top_width); @@ -1081,8 +1079,6 @@ void Config::SaveLayoutValues() { if (global) { WriteBasicSetting(Settings::values.mono_render_option); - - WriteBasicSetting(Settings::values.custom_layout); WriteBasicSetting(Settings::values.custom_top_x); WriteBasicSetting(Settings::values.custom_top_y); WriteBasicSetting(Settings::values.custom_top_width); diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 80cf549e9..1426ac380 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -634,10 +634,6 @@ void RendererOpenGL::DrawSingleScreenStereo(const ScreenInfo& screen_info_l, * Draws the emulated screens to the emulator window. */ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool flipped) { - bool isPortrait = false; -#ifdef ANDROID - isPortrait = layout.height > layout.width; -#endif if (settings.bg_color_update_requested.exchange(false)) { // Update background color before drawing glClearColor(Settings::values.bg_red.GetValue(), Settings::values.bg_green.GetValue(), @@ -679,12 +675,12 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f if (!Settings::values.swap_screen.GetValue()) { DrawTopScreen(layout, top_screen); glUniform1i(uniform_layer, 0); - ApplySecondLayerOpacity(isPortrait); + ApplySecondLayerOpacity(layout.is_portrait); DrawBottomScreen(layout, bottom_screen); } else { DrawBottomScreen(layout, bottom_screen); glUniform1i(uniform_layer, 0); - ApplySecondLayerOpacity(isPortrait); + ApplySecondLayerOpacity(layout.is_portrait); DrawTopScreen(layout, top_screen); } @@ -696,19 +692,14 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f DrawBottomScreen(layout, additional_screen); } } - ResetSecondLayerOpacity(isPortrait); + ResetSecondLayerOpacity(layout.is_portrait); } void RendererOpenGL::ApplySecondLayerOpacity(bool isPortrait) { -#ifdef ANDROID // TODO: Allow for second layer opacity in portrait mode android - if (isPortrait) { - return; - } -#endif - if ((Settings::values.layout_option.GetValue() == Settings::LayoutOption::CustomLayout || - Settings::values.custom_layout) && + if (!isPortrait && + (Settings::values.layout_option.GetValue() == Settings::LayoutOption::CustomLayout) && Settings::values.custom_second_layer_opacity.GetValue() < 100) { state.blend.src_rgb_func = GL_CONSTANT_ALPHA; state.blend.src_a_func = GL_CONSTANT_ALPHA; @@ -719,15 +710,8 @@ void RendererOpenGL::ApplySecondLayerOpacity(bool isPortrait) { } void RendererOpenGL::ResetSecondLayerOpacity(bool isPortrait) { -#ifdef ANDROID - // TODO: Allow for second layer opacity in portrait mode android - if (isPortrait) { - return; - } -#endif - - if ((Settings::values.layout_option.GetValue() == Settings::LayoutOption::CustomLayout || - Settings::values.custom_layout) && + if (!isPortrait && + (Settings::values.layout_option.GetValue() == Settings::LayoutOption::CustomLayout) && Settings::values.custom_second_layer_opacity.GetValue() < 100) { state.blend.src_rgb_func = GL_ONE; state.blend.dst_rgb_func = GL_ZERO;