mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2025-01-09 16:29:25 +01:00
android: Implemented custom layout customization GUI
This commit also changes the name of the 'Portrait' landscape layout to 'Original' Co-authored-by: OpenSauce04 <opensauce04@gmail.com>
This commit is contained in:
parent
7e5b83f126
commit
862fda4332
@ -156,11 +156,10 @@ object NativeLibrary {
|
|||||||
external fun getPerfStats(): DoubleArray
|
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.
|
* Swaps the top and bottom screens.
|
||||||
*/
|
*/
|
||||||
@ -263,14 +262,6 @@ object NativeLibrary {
|
|||||||
get() = LimeApplication.appContext.resources.configuration.orientation ==
|
get() = LimeApplication.appContext.resources.configuration.orientation ==
|
||||||
Configuration.ORIENTATION_PORTRAIT
|
Configuration.ORIENTATION_PORTRAIT
|
||||||
|
|
||||||
@Keep
|
|
||||||
@JvmStatic
|
|
||||||
fun landscapeScreenLayout(): Int = EmulationMenuSettings.landscapeScreenLayout
|
|
||||||
|
|
||||||
@Keep
|
|
||||||
@JvmStatic
|
|
||||||
fun portraitScreenLayout(): Int = EmulationMenuSettings.portraitScreenLayout
|
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun displayAlertMsg(title: String, message: String, yesNo: Boolean): Boolean {
|
fun displayAlertMsg(title: String, message: String, yesNo: Boolean): Boolean {
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,7 +3,6 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
package io.github.lime3ds.android.display
|
package io.github.lime3ds.android.display
|
||||||
|
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import io.github.lime3ds.android.NativeLibrary
|
import io.github.lime3ds.android.NativeLibrary
|
||||||
import io.github.lime3ds.android.features.settings.model.BooleanSetting
|
import io.github.lime3ds.android.features.settings.model.BooleanSetting
|
||||||
@ -26,40 +25,35 @@ class ScreenAdjustmentUtil(
|
|||||||
BooleanSetting.SWAP_SCREEN.boolean = isEnabled
|
BooleanSetting.SWAP_SCREEN.boolean = isEnabled
|
||||||
settings.saveSetting(BooleanSetting.SWAP_SCREEN, SettingsFile.FILE_NAME_CONFIG)
|
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() {
|
fun cycleLayouts() {
|
||||||
val nextLayout = if (NativeLibrary.isPortraitMode) {
|
// TODO: figure out how to pull these from R.array
|
||||||
(EmulationMenuSettings.portraitScreenLayout + 1) % (PortraitScreenLayout.entries.size - 1)
|
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 {
|
} 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) {
|
fun changePortraitOrientation(layoutOption: Int) {
|
||||||
EmulationMenuSettings.portraitScreenLayout = layoutOption
|
|
||||||
NativeLibrary.notifyPortraitLayoutChange(
|
|
||||||
EmulationMenuSettings.portraitScreenLayout,
|
|
||||||
windowManager.defaultDisplay.rotation,
|
|
||||||
NativeLibrary::isPortraitMode.get()
|
|
||||||
)
|
|
||||||
IntSetting.PORTRAIT_SCREEN_LAYOUT.int = layoutOption
|
IntSetting.PORTRAIT_SCREEN_LAYOUT.int = layoutOption
|
||||||
settings.saveSetting(IntSetting.PORTRAIT_SCREEN_LAYOUT, SettingsFile.FILE_NAME_CONFIG)
|
settings.saveSetting(IntSetting.PORTRAIT_SCREEN_LAYOUT, SettingsFile.FILE_NAME_CONFIG)
|
||||||
|
NativeLibrary.reloadSettings()
|
||||||
|
NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun changeScreenOrientation(layoutOption: Int) {
|
fun changeScreenOrientation(layoutOption: Int) {
|
||||||
EmulationMenuSettings.landscapeScreenLayout = layoutOption
|
|
||||||
NativeLibrary.notifyOrientationChange(
|
|
||||||
EmulationMenuSettings.landscapeScreenLayout,
|
|
||||||
windowManager.defaultDisplay.rotation,
|
|
||||||
NativeLibrary::isPortraitMode.get()
|
|
||||||
)
|
|
||||||
IntSetting.SCREEN_LAYOUT.int = layoutOption
|
IntSetting.SCREEN_LAYOUT.int = layoutOption
|
||||||
settings.saveSetting(IntSetting.SCREEN_LAYOUT, SettingsFile.FILE_NAME_CONFIG)
|
settings.saveSetting(IntSetting.SCREEN_LAYOUT, SettingsFile.FILE_NAME_CONFIG)
|
||||||
|
NativeLibrary.reloadSettings()
|
||||||
|
NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ package io.github.lime3ds.android.display
|
|||||||
|
|
||||||
enum class ScreenLayout(val int: Int) {
|
enum class ScreenLayout(val int: Int) {
|
||||||
// These must match what is defined in src/common/settings.h
|
// These must match what is defined in src/common/settings.h
|
||||||
TOP_BOTTOM(0),
|
ORIGINAL(0),
|
||||||
SINGLE_SCREEN(1),
|
SINGLE_SCREEN(1),
|
||||||
LARGE_SCREEN(2),
|
LARGE_SCREEN(2),
|
||||||
SIDE_SCREEN(3),
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -23,7 +23,23 @@ enum class IntSetting(
|
|||||||
CARDBOARD_X_SHIFT("cardboard_x_shift", Settings.SECTION_LAYOUT, 0),
|
CARDBOARD_X_SHIFT("cardboard_x_shift", Settings.SECTION_LAYOUT, 0),
|
||||||
CARDBOARD_Y_SHIFT("cardboard_y_shift", Settings.SECTION_LAYOUT, 0),
|
CARDBOARD_Y_SHIFT("cardboard_y_shift", Settings.SECTION_LAYOUT, 0),
|
||||||
SCREEN_LAYOUT("layout_option", 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_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),
|
AUDIO_INPUT_TYPE("output_type", Settings.SECTION_AUDIO, 0),
|
||||||
NEW_3DS("is_new_3ds", Settings.SECTION_SYSTEM, 1),
|
NEW_3DS("is_new_3ds", Settings.SECTION_SYSTEM, 1),
|
||||||
LLE_APPLETS("lle_applets", Settings.SECTION_SYSTEM, 0),
|
LLE_APPLETS("lle_applets", Settings.SECTION_SYSTEM, 0),
|
||||||
|
@ -109,6 +109,8 @@ class Settings {
|
|||||||
const val SECTION_AUDIO = "Audio"
|
const val SECTION_AUDIO = "Audio"
|
||||||
const val SECTION_DEBUG = "Debugging"
|
const val SECTION_DEBUG = "Debugging"
|
||||||
const val SECTION_THEME = "Theme"
|
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_A = "button_a"
|
||||||
const val KEY_BUTTON_B = "button_b"
|
const val KEY_BUTTON_B = "button_b"
|
||||||
|
@ -7,6 +7,7 @@ package io.github.lime3ds.android.features.settings.ui
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import io.github.lime3ds.android.NativeLibrary
|
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.features.settings.model.Settings
|
||||||
import io.github.lime3ds.android.utils.SystemSaveGame
|
import io.github.lime3ds.android.utils.SystemSaveGame
|
||||||
import io.github.lime3ds.android.utils.DirectoryInitialization
|
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...")
|
Log.debug("[SettingsActivity] Settings activity stopping. Saving settings to INI...")
|
||||||
settings.saveSettings(activityView)
|
settings.saveSettings(activityView)
|
||||||
SystemSaveGame.save()
|
SystemSaveGame.save()
|
||||||
|
//added to ensure that layout changes take effect as soon as settings window closes
|
||||||
|
NativeLibrary.reloadSettings()
|
||||||
|
NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode)
|
||||||
}
|
}
|
||||||
NativeLibrary.reloadSettings()
|
NativeLibrary.reloadSettings()
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,16 @@ package io.github.lime3ds.android.features.settings.ui
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
|
import android.graphics.Color
|
||||||
import android.icu.util.Calendar
|
import android.icu.util.Calendar
|
||||||
import android.icu.util.TimeZone
|
import android.icu.util.TimeZone
|
||||||
|
import android.text.Editable
|
||||||
import android.text.InputFilter
|
import android.text.InputFilter
|
||||||
|
import android.text.TextWatcher
|
||||||
import android.text.format.DateFormat
|
import android.text.format.DateFormat
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.TextView
|
import android.widget.EditText
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.widget.doOnTextChanged
|
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.datepicker.MaterialDatePicker
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.google.android.material.slider.Slider
|
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.MaterialTimePicker
|
||||||
import com.google.android.material.timepicker.TimeFormat
|
import com.google.android.material.timepicker.TimeFormat
|
||||||
import io.github.lime3ds.android.R
|
import io.github.lime3ds.android.R
|
||||||
@ -73,7 +78,8 @@ class SettingsAdapter(
|
|||||||
private var clickedPosition: Int
|
private var clickedPosition: Int
|
||||||
private var dialog: AlertDialog? = null
|
private var dialog: AlertDialog? = null
|
||||||
private var sliderProgress = 0
|
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 textInputValue: String = ""
|
||||||
|
|
||||||
private var defaultCancelListener =
|
private var defaultCancelListener =
|
||||||
@ -256,18 +262,36 @@ class SettingsAdapter(
|
|||||||
|
|
||||||
val inflater = LayoutInflater.from(context)
|
val inflater = LayoutInflater.from(context)
|
||||||
val sliderBinding = DialogSliderBinding.inflate(inflater)
|
val sliderBinding = DialogSliderBinding.inflate(inflater)
|
||||||
|
textInputLayout = sliderBinding.textInput
|
||||||
textSliderValue = sliderBinding.textValue
|
textSliderValue = sliderBinding.textValue
|
||||||
textSliderValue!!.text = sliderProgress.toString()
|
textSliderValue!!.setText(sliderProgress.toString())
|
||||||
sliderBinding.textUnits.text = item.units
|
//sliderBinding.textUnits.text = item.units
|
||||||
|
textInputLayout!!.suffixText = item.units
|
||||||
|
|
||||||
sliderBinding.slider.apply {
|
sliderBinding.slider.apply {
|
||||||
valueFrom = item.min.toFloat()
|
valueFrom = item.min.toFloat()
|
||||||
valueTo = item.max.toFloat()
|
valueTo = item.max.toFloat()
|
||||||
value = sliderProgress.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 ->
|
addOnChangeListener { _: Slider, value: Float, _: Boolean ->
|
||||||
sliderProgress = value.toInt()
|
sliderProgress = value.toInt()
|
||||||
textSliderValue!!.text = sliderProgress.toString()
|
if (textSliderValue!!.text.toString() != value.toInt().toString()) {
|
||||||
|
textSliderValue!!.setText(value.toInt().toString())
|
||||||
|
textSliderValue!!.setSelection(textSliderValue!!.length())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ package io.github.lime3ds.android.features.settings.ui
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import android.content.res.Resources
|
||||||
import android.hardware.camera2.CameraAccessException
|
import android.hardware.camera2.CameraAccessException
|
||||||
import android.hardware.camera2.CameraCharacteristics
|
import android.hardware.camera2.CameraCharacteristics
|
||||||
import android.hardware.camera2.CameraManager
|
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.Log
|
||||||
import io.github.lime3ds.android.utils.SystemSaveGame
|
import io.github.lime3ds.android.utils.SystemSaveGame
|
||||||
import io.github.lime3ds.android.utils.ThemeUtil
|
import io.github.lime3ds.android.utils.ThemeUtil
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) {
|
class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) {
|
||||||
private var menuTag: String? = null
|
private var menuTag: String? = null
|
||||||
@ -91,9 +93,12 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||||||
Settings.SECTION_CAMERA -> addCameraSettings(sl)
|
Settings.SECTION_CAMERA -> addCameraSettings(sl)
|
||||||
Settings.SECTION_CONTROLS -> addControlsSettings(sl)
|
Settings.SECTION_CONTROLS -> addControlsSettings(sl)
|
||||||
Settings.SECTION_RENDERER -> addGraphicsSettings(sl)
|
Settings.SECTION_RENDERER -> addGraphicsSettings(sl)
|
||||||
|
Settings.SECTION_LAYOUT -> addLayoutSettings(sl)
|
||||||
Settings.SECTION_AUDIO -> addAudioSettings(sl)
|
Settings.SECTION_AUDIO -> addAudioSettings(sl)
|
||||||
Settings.SECTION_DEBUG -> addDebugSettings(sl)
|
Settings.SECTION_DEBUG -> addDebugSettings(sl)
|
||||||
Settings.SECTION_THEME -> addThemeSettings(sl)
|
Settings.SECTION_THEME -> addThemeSettings(sl)
|
||||||
|
Settings.SECTION_CUSTOM_LANDSCAPE -> addCustomLandscapeSettings(sl)
|
||||||
|
Settings.SECTION_CUSTOM_PORTRAIT -> addCustomPortraitSettings(sl)
|
||||||
else -> {
|
else -> {
|
||||||
fragmentView.showToastMessage("Unimplemented menu", false)
|
fragmentView.showToastMessage("Unimplemented menu", false)
|
||||||
return
|
return
|
||||||
@ -103,6 +108,23 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||||||
fragmentView.showSettingsList(settingsList!!)
|
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<SettingsItem>) {
|
private fun addConfigSettings(sl: ArrayList<SettingsItem>) {
|
||||||
settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_settings))
|
settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_settings))
|
||||||
sl.apply {
|
sl.apply {
|
||||||
@ -146,6 +168,14 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||||||
Settings.SECTION_RENDERER
|
Settings.SECTION_RENDERER
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
add(
|
||||||
|
SubmenuSetting(
|
||||||
|
R.string.preferences_layout,
|
||||||
|
0,
|
||||||
|
R.drawable.ic_fit_screen,
|
||||||
|
Settings.SECTION_LAYOUT
|
||||||
|
)
|
||||||
|
)
|
||||||
add(
|
add(
|
||||||
SubmenuSetting(
|
SubmenuSetting(
|
||||||
R.string.preferences_audio,
|
R.string.preferences_audio,
|
||||||
@ -162,6 +192,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||||||
Settings.SECTION_DEBUG
|
Settings.SECTION_DEBUG
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
add(
|
add(
|
||||||
RunnableSetting(
|
RunnableSetting(
|
||||||
R.string.reset_to_default,
|
R.string.reset_to_default,
|
||||||
@ -873,6 +904,262 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addLayoutSettings(sl: ArrayList<SettingsItem>) {
|
||||||
|
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<SettingsItem>) {
|
||||||
|
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<SettingsItem>) {
|
||||||
|
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<SettingsItem>) {
|
private fun addAudioSettings(sl: ArrayList<SettingsItem>) {
|
||||||
settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_audio))
|
settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_audio))
|
||||||
sl.apply {
|
sl.apply {
|
||||||
|
@ -13,6 +13,8 @@ import android.os.Bundle
|
|||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
|
import android.text.Editable
|
||||||
|
import android.text.TextWatcher
|
||||||
import android.view.Choreographer
|
import android.view.Choreographer
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.MotionEvent
|
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.PortraitScreenLayout
|
||||||
import io.github.lime3ds.android.display.ScreenAdjustmentUtil
|
import io.github.lime3ds.android.display.ScreenAdjustmentUtil
|
||||||
import io.github.lime3ds.android.display.ScreenLayout
|
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.model.SettingsViewModel
|
||||||
import io.github.lime3ds.android.features.settings.ui.SettingsActivity
|
import io.github.lime3ds.android.features.settings.ui.SettingsActivity
|
||||||
import io.github.lime3ds.android.features.settings.utils.SettingsFile
|
import io.github.lime3ds.android.features.settings.utils.SettingsFile
|
||||||
@ -324,6 +327,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||||||
SettingsFile.FILE_NAME_CONFIG,
|
SettingsFile.FILE_NAME_CONFIG,
|
||||||
""
|
""
|
||||||
)
|
)
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -786,7 +790,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||||||
|
|
||||||
popupMenu.menuInflater.inflate(R.menu.menu_landscape_screen_layout, popupMenu.menu)
|
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 ->
|
ScreenLayout.SINGLE_SCREEN.int ->
|
||||||
R.id.menu_screen_layout_single
|
R.id.menu_screen_layout_single
|
||||||
|
|
||||||
@ -825,7 +832,17 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
R.id.menu_screen_layout_original -> {
|
||||||
|
screenAdjustmentUtil.changeScreenOrientation(ScreenLayout.ORIGINAL.int)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
R.id.menu_screen_layout_custom -> {
|
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)
|
screenAdjustmentUtil.changeScreenOrientation(ScreenLayout.CUSTOM_LAYOUT.int)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -845,7 +862,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||||||
|
|
||||||
popupMenu.menuInflater.inflate(R.menu.menu_portrait_screen_layout, popupMenu.menu)
|
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 ->
|
PortraitScreenLayout.TOP_FULL_WIDTH.int ->
|
||||||
R.id.menu_portrait_layout_top_full
|
R.id.menu_portrait_layout_top_full
|
||||||
|
|
||||||
@ -867,6 +884,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||||||
}
|
}
|
||||||
|
|
||||||
R.id.menu_portrait_layout_custom -> {
|
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)
|
screenAdjustmentUtil.changePortraitOrientation(PortraitScreenLayout.CUSTOM_PORTRAIT_LAYOUT.int)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -919,14 +941,32 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||||||
|
|
||||||
sliderBinding.apply {
|
sliderBinding.apply {
|
||||||
slider.valueTo = 150f
|
slider.valueTo = 150f
|
||||||
|
slider.valueFrom = 0f
|
||||||
slider.value = preferences.getInt(target, 50).toFloat()
|
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.addOnChangeListener(
|
||||||
Slider.OnChangeListener { slider: Slider, progress: Float, _: Boolean ->
|
Slider.OnChangeListener { slider: Slider, progress: Float, _: Boolean ->
|
||||||
textValue.text = (progress.toInt() + 50).toString()
|
if (textValue.text.toString() != (slider.value + 50).toInt().toString()) {
|
||||||
setControlScale(slider.value.toInt(), target)
|
textValue.setText((slider.value + 50).toInt().toString())
|
||||||
|
textValue.setSelection(textValue.length())
|
||||||
|
setControlScale(slider.value.toInt(), target)
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
textValue.text = (sliderBinding.slider.value.toInt() + 50).toString()
|
textInput.suffixText = "%"
|
||||||
textUnits.text = "%"
|
|
||||||
}
|
}
|
||||||
val previousProgress = sliderBinding.slider.value.toInt()
|
val previousProgress = sliderBinding.slider.value.toInt()
|
||||||
|
|
||||||
@ -949,15 +989,36 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||||||
val sliderBinding = DialogSliderBinding.inflate(layoutInflater)
|
val sliderBinding = DialogSliderBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
sliderBinding.apply {
|
sliderBinding.apply {
|
||||||
|
slider.valueFrom = 0f
|
||||||
slider.valueTo = 100f
|
slider.valueTo = 100f
|
||||||
slider.value = preferences.getInt("controlOpacity", 50).toFloat()
|
slider.value = preferences.getInt("controlOpacity", 50).toFloat()
|
||||||
slider.addOnChangeListener(
|
textValue.setText(slider.value.toInt().toString())
|
||||||
Slider.OnChangeListener { slider: Slider, progress: Float, _: Boolean ->
|
|
||||||
textValue.text = (progress.toInt()).toString()
|
textValue.addTextChangedListener( object : TextWatcher {
|
||||||
setControlOpacity(slider.value.toInt())
|
override fun afterTextChanged(s: Editable) {
|
||||||
})
|
val value = s.toString().toIntOrNull()
|
||||||
textValue.text = (sliderBinding.slider.value.toInt()).toString()
|
if (value == null || value < slider.valueFrom || value > slider.valueTo) {
|
||||||
textUnits.text = "%"
|
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()
|
val previousProgress = sliderBinding.slider.value.toInt()
|
||||||
|
|
||||||
@ -986,7 +1047,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||||||
private fun resetScale(target: String) {
|
private fun resetScale(target: String) {
|
||||||
preferences.edit().putInt(
|
preferences.edit().putInt(
|
||||||
target,
|
target,
|
||||||
50
|
100
|
||||||
).apply()
|
).apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,6 @@ package io.github.lime3ds.android.utils
|
|||||||
import androidx.drawerlayout.widget.DrawerLayout
|
import androidx.drawerlayout.widget.DrawerLayout
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import io.github.lime3ds.android.LimeApplication
|
import io.github.lime3ds.android.LimeApplication
|
||||||
import io.github.lime3ds.android.display.PortraitScreenLayout
|
|
||||||
import io.github.lime3ds.android.display.ScreenLayout
|
|
||||||
|
|
||||||
object EmulationMenuSettings {
|
object EmulationMenuSettings {
|
||||||
private val preferences =
|
private val preferences =
|
||||||
@ -28,26 +26,7 @@ object EmulationMenuSettings {
|
|||||||
.putBoolean("EmulationMenuSettings_DpadSlideEnable", value)
|
.putBoolean("EmulationMenuSettings_DpadSlideEnable", value)
|
||||||
.apply()
|
.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
|
var showFps: Boolean
|
||||||
get() = preferences.getBoolean("EmulationMenuSettings_ShowFps", false)
|
get() = preferences.getBoolean("EmulationMenuSettings_ShowFps", false)
|
||||||
set(value) {
|
set(value) {
|
||||||
|
@ -175,7 +175,6 @@ void Config::ReadValues() {
|
|||||||
// Layout
|
// Layout
|
||||||
Settings::values.layout_option = static_cast<Settings::LayoutOption>(sdl2_config->GetInteger(
|
Settings::values.layout_option = static_cast<Settings::LayoutOption>(sdl2_config->GetInteger(
|
||||||
"Layout", "layout_option", static_cast<int>(Settings::LayoutOption::LargeScreen)));
|
"Layout", "layout_option", static_cast<int>(Settings::LayoutOption::LargeScreen)));
|
||||||
ReadSetting("Layout", Settings::values.custom_layout);
|
|
||||||
ReadSetting("Layout", Settings::values.custom_top_x);
|
ReadSetting("Layout", Settings::values.custom_top_x);
|
||||||
ReadSetting("Layout", Settings::values.custom_top_y);
|
ReadSetting("Layout", Settings::values.custom_top_y);
|
||||||
ReadSetting("Layout", Settings::values.custom_top_width);
|
ReadSetting("Layout", Settings::values.custom_top_width);
|
||||||
|
@ -180,16 +180,19 @@ filter_mode =
|
|||||||
|
|
||||||
[Layout]
|
[Layout]
|
||||||
# Layout for the screen inside the render window, landscape mode
|
# 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,
|
# 1: Single Screen Only,
|
||||||
# 2: Large Screen Small Screen
|
# 2: *currently unsupported on android*
|
||||||
# 3: Side by Side
|
# 3: Side by Side
|
||||||
# 4: Hybrid
|
# 4: Hybrid
|
||||||
# 5: Custom Layout
|
# 5: Custom Layout
|
||||||
|
# 6: (default) Large screen / small screen
|
||||||
layout_option =
|
layout_option =
|
||||||
|
|
||||||
# Screen placement when using Custom layout option
|
# Screen placement when using Custom layout option
|
||||||
# 0x, 0y is the top left corner of the render window.
|
# 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_x =
|
||||||
custom_top_y =
|
custom_top_y =
|
||||||
custom_top_width =
|
custom_top_width =
|
||||||
|
@ -21,18 +21,6 @@ static bool IsPortraitMode() {
|
|||||||
IDCache::GetNativeLibraryClass(), IDCache::GetIsPortraitMode());
|
IDCache::GetNativeLibraryClass(), IDCache::GetIsPortraitMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UpdateLandscapeScreenLayout() {
|
|
||||||
Settings::values.layout_option =
|
|
||||||
static_cast<Settings::LayoutOption>(IDCache::GetEnvForThread()->CallStaticIntMethod(
|
|
||||||
IDCache::GetNativeLibraryClass(), IDCache::GetLandscapeScreenLayout()));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void UpdatePortraitScreenLayout() {
|
|
||||||
Settings::values.portrait_layout_option =
|
|
||||||
static_cast<Settings::PortraitLayoutOption>(IDCache::GetEnvForThread()->CallStaticIntMethod(
|
|
||||||
IDCache::GetNativeLibraryClass(), IDCache::GetPortraitScreenLayout()));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) {
|
bool EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) {
|
||||||
if (render_window == surface) {
|
if (render_window == surface) {
|
||||||
return false;
|
return false;
|
||||||
@ -63,8 +51,6 @@ void EmuWindow_Android::OnTouchMoved(int x, int y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EmuWindow_Android::OnFramebufferSizeChanged() {
|
void EmuWindow_Android::OnFramebufferSizeChanged() {
|
||||||
UpdateLandscapeScreenLayout();
|
|
||||||
UpdatePortraitScreenLayout();
|
|
||||||
const bool is_portrait_mode{IsPortraitMode()};
|
const bool is_portrait_mode{IsPortraitMode()};
|
||||||
|
|
||||||
const int bigger{window_width > window_height ? window_width : window_height};
|
const int bigger{window_width > window_height ? window_width : window_height};
|
||||||
|
@ -177,10 +177,6 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
|||||||
s_native_library_class, "onCoreError",
|
s_native_library_class, "onCoreError",
|
||||||
"(Lio/github/lime3ds/android/NativeLibrary$CoreError;Ljava/lang/String;)Z");
|
"(Lio/github/lime3ds/android/NativeLibrary$CoreError;Ljava/lang/String;)Z");
|
||||||
s_is_portrait_mode = env->GetStaticMethodID(s_native_library_class, "isPortraitMode", "()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 =
|
s_exit_emulation_activity =
|
||||||
env->GetStaticMethodID(s_native_library_class, "exitEmulationActivity", "(I)V");
|
env->GetStaticMethodID(s_native_library_class, "exitEmulationActivity", "(I)V");
|
||||||
s_request_camera_permission =
|
s_request_camera_permission =
|
||||||
|
@ -346,29 +346,13 @@ void JNICALL Java_io_github_lime3ds_android_NativeLibrary_enableAdrenoTurboMode(
|
|||||||
EnableAdrenoTurboMode(enable);
|
EnableAdrenoTurboMode(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Java_io_github_lime3ds_android_NativeLibrary_notifyOrientationChange(
|
void Java_io_github_lime3ds_android_NativeLibrary_updateFramebuffer([[maybe_unused]] JNIEnv* env,
|
||||||
[[maybe_unused]] JNIEnv* env, [[maybe_unused]] jobject obj, jint layout_option, jint rotation,
|
[[maybe_unused]] jobject obj,
|
||||||
jboolean portrait) {
|
jboolean is_portrait_mode) {
|
||||||
Settings::values.layout_option = static_cast<Settings::LayoutOption>(layout_option);
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
if (system.IsPoweredOn()) {
|
if (system.IsPoweredOn()) {
|
||||||
|
system.GPU().Renderer().UpdateCurrentFramebufferLayout(is_portrait_mode);
|
||||||
system.GPU().Renderer().UpdateCurrentFramebufferLayout(portrait);
|
|
||||||
}
|
}
|
||||||
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<Settings::PortraitLayoutOption>(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,
|
void Java_io_github_lime3ds_android_NativeLibrary_swapScreens([[maybe_unused]] JNIEnv* env,
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:fromDegrees="90"
|
||||||
|
android:toDegrees="0"
|
||||||
|
android:drawable="@drawable/ic_fit_screen">
|
||||||
|
</rotate>
|
@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
@ -13,25 +14,30 @@
|
|||||||
android:layout_marginRight="@dimen/spacing_large"
|
android:layout_marginRight="@dimen/spacing_large"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentStart="true"
|
||||||
android:layout_below="@+id/text_value"
|
android:layout_below="@+id/text_input"
|
||||||
android:layout_marginBottom="@dimen/spacing_medlarge" />
|
android:layout_marginBottom="@dimen/spacing_medlarge" />
|
||||||
|
|
||||||
<TextView
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
|
android:layout_marginLeft="@dimen/spacing_large"
|
||||||
|
android:layout_marginRight="@dimen/spacing_large"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/text_input"
|
||||||
|
app:suffixText="%">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:inputType="number"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
tools:text="75"
|
tools:text="75"
|
||||||
android:id="@+id/text_value"
|
android:id="@+id/text_value"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:layout_marginTop="@dimen/spacing_medlarge"
|
android:layout_marginTop="@dimen/spacing_medlarge"
|
||||||
android:layout_marginBottom="@dimen/spacing_medlarge" />
|
android:layout_marginBottom="@dimen/spacing_medlarge" />
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
tools:text="%"
|
|
||||||
android:id="@+id/text_units"
|
|
||||||
android:layout_alignTop="@+id/text_value"
|
|
||||||
android:layout_toEndOf="@+id/text_value" />
|
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
@ -1,127 +0,0 @@
|
|||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
tools:context="io.github.lime3ds.android.activities.EmulationActivity">
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_save_state"
|
|
||||||
android:title="@string/emulation_save_state">
|
|
||||||
<menu/>
|
|
||||||
</item>
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_load_state"
|
|
||||||
android:title="@string/emulation_load_state">
|
|
||||||
<menu/>
|
|
||||||
</item>
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_configure_controls"
|
|
||||||
android:title="@string/emulation_configure_controls">
|
|
||||||
<menu>
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_edit_layout"
|
|
||||||
android:title="@string/emulation_edit_layout" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_toggle_controls"
|
|
||||||
android:title="@string/emulation_toggle_controls" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_adjust_scale"
|
|
||||||
android:title="@string/emulation_control_scale" />
|
|
||||||
|
|
||||||
<group android:checkableBehavior="all">
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_joystick_rel_center"
|
|
||||||
android:checkable="true"
|
|
||||||
android:title="@string/emulation_control_joystick_rel_center"/>
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_dpad_slide_enable"
|
|
||||||
android:checkable="true"
|
|
||||||
android:title="@string/emulation_control_dpad_slide_enable" />
|
|
||||||
</group>
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_reset_overlay"
|
|
||||||
android:title="@string/emulation_touch_overlay_reset" />
|
|
||||||
</menu>
|
|
||||||
</item>
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_amiibo"
|
|
||||||
android:title="@string/menu_emulation_amiibo">
|
|
||||||
<menu>
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_amiibo_load"
|
|
||||||
android:title="@string/menu_emulation_amiibo_load" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_amiibo_remove"
|
|
||||||
android:title="@string/menu_emulation_amiibo_remove" />
|
|
||||||
</menu>
|
|
||||||
</item>
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_switch_screen_layout"
|
|
||||||
app:showAsAction="never"
|
|
||||||
android:title="@string/emulation_switch_screen_layout">
|
|
||||||
<menu>
|
|
||||||
<group android:checkableBehavior="single">
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_portrait_layout_top_full"
|
|
||||||
android:title="@string/emulation_screen_layout_landscape" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_screen_layout_portrait"
|
|
||||||
android:title="@string/emulation_screen_layout_portrait" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_screen_layout_single"
|
|
||||||
android:title="@string/emulation_screen_layout_single" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_screen_layout_sidebyside"
|
|
||||||
android:title="@string/emulation_screen_layout_sidebyside" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_screen_layout_hybrid"
|
|
||||||
android:title="@string/emulation_screen_layout_hybrid" />
|
|
||||||
</group>
|
|
||||||
</menu>
|
|
||||||
</item>
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_swap_screens"
|
|
||||||
app:showAsAction="never"
|
|
||||||
android:title="@string/emulation_swap_screens"
|
|
||||||
android:checkable="true" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_show_fps"
|
|
||||||
app:showAsAction="never"
|
|
||||||
android:title="@string/emulation_show_fps"
|
|
||||||
android:checkable="true" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_show_overlay"
|
|
||||||
app:showAsAction="never"
|
|
||||||
android:title="@string/emulation_show_overlay"
|
|
||||||
android:checkable="true" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_open_cheats"
|
|
||||||
app:showAsAction="never"
|
|
||||||
android:title="@string/emulation_open_cheats" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_open_settings"
|
|
||||||
app:showAsAction="never"
|
|
||||||
android:title="@string/emulation_open_settings" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_emulation_close_game"
|
|
||||||
app:showAsAction="never"
|
|
||||||
android:title="@string/emulation_close_game" />
|
|
||||||
|
|
||||||
</menu>
|
|
@ -29,12 +29,13 @@
|
|||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/menu_portrait_screen_layout"
|
android:id="@+id/menu_portrait_screen_layout"
|
||||||
android:icon="@drawable/ic_fit_screen"
|
android:icon="@drawable/ic_portrait_fit_screen"
|
||||||
android:title="@string/emulation_switch_portrait_layout" />
|
android:title="@string/emulation_switch_portrait_layout" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/menu_swap_screens"
|
android:id="@+id/menu_swap_screens"
|
||||||
android:icon="@drawable/ic_splitscreen"
|
android:icon="@drawable/ic_splitscreen"
|
||||||
|
|
||||||
android:title="@string/emulation_swap_screens" />
|
android:title="@string/emulation_swap_screens" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
|
@ -19,9 +19,14 @@
|
|||||||
android:id="@+id/menu_screen_layout_hybrid"
|
android:id="@+id/menu_screen_layout_hybrid"
|
||||||
android:title="@string/emulation_screen_layout_hybrid" />
|
android:title="@string/emulation_screen_layout_hybrid" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_screen_layout_original"
|
||||||
|
android:title="@string/emulation_screen_layout_original" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/menu_screen_layout_custom"
|
android:id="@+id/menu_screen_layout_custom"
|
||||||
android:title="@string/emulation_screen_layout_custom" />
|
android:title="@string/emulation_screen_layout_custom" />
|
||||||
|
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
</menu>
|
</menu>
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
<item
|
<item
|
||||||
android:id="@+id/menu_portrait_layout_custom"
|
android:id="@+id/menu_portrait_layout_custom"
|
||||||
android:title="@string/emulation_screen_layout_custom" />
|
android:title="@string/emulation_screen_layout_custom" />
|
||||||
|
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
</menu>
|
</menu>
|
||||||
|
@ -11,6 +11,37 @@
|
|||||||
<item>1</item>
|
<item>1</item>
|
||||||
</integer-array>
|
</integer-array>
|
||||||
|
|
||||||
|
<string-array name="landscapeLayouts">
|
||||||
|
<item>@string/emulation_screen_layout_landscape</item>
|
||||||
|
<item>@string/emulation_screen_layout_single</item>
|
||||||
|
<item>@string/emulation_screen_layout_sidebyside</item>
|
||||||
|
<item>@string/emulation_screen_layout_hybrid</item>
|
||||||
|
<item>@string/emulation_screen_layout_original</item>
|
||||||
|
<item>@string/emulation_screen_layout_custom</item>
|
||||||
|
</string-array>
|
||||||
|
<!-- start with 6 because that is the MobileLandscape layout in cpp files
|
||||||
|
- skip 0 because top/bottom rarely makes sense in landscape
|
||||||
|
- skip 2 because that is "Large Screen" which the default replaces in mobile
|
||||||
|
-->
|
||||||
|
<integer-array name="landscapeLayoutValues">
|
||||||
|
<item>6</item>
|
||||||
|
<item>1</item>
|
||||||
|
<item>3</item>
|
||||||
|
<item>4</item>
|
||||||
|
<item>0</item>
|
||||||
|
<item>5</item>
|
||||||
|
</integer-array>
|
||||||
|
|
||||||
|
<string-array name="portraitLayouts">
|
||||||
|
<item>@string/emulation_portrait_layout_top_full</item>
|
||||||
|
<item>@string/emulation_screen_layout_custom</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<integer-array name="portraitLayoutValues">
|
||||||
|
<item>0</item>
|
||||||
|
<item>1</item>
|
||||||
|
</integer-array>
|
||||||
|
|
||||||
<string-array name="regionNames">
|
<string-array name="regionNames">
|
||||||
<item>@string/auto_select</item>
|
<item>@string/auto_select</item>
|
||||||
<item>@string/system_region_jpn</item>
|
<item>@string/system_region_jpn</item>
|
||||||
|
@ -330,7 +330,7 @@
|
|||||||
<string name="preferences_audio">Audio</string>
|
<string name="preferences_audio">Audio</string>
|
||||||
<string name="preferences_debug">Debug</string>
|
<string name="preferences_debug">Debug</string>
|
||||||
<string name="preferences_theme">Theme and Color</string>
|
<string name="preferences_theme">Theme and Color</string>
|
||||||
|
<string name="preferences_layout">Layout</string>
|
||||||
<!-- ROM loading errors -->
|
<!-- ROM loading errors -->
|
||||||
<string name="loader_error_encrypted">Your ROM is Encrypted</string>
|
<string name="loader_error_encrypted">Your ROM is Encrypted</string>
|
||||||
<string name="loader_error_invalid_format">Invalid ROM format</string>
|
<string name="loader_error_invalid_format">Invalid ROM format</string>
|
||||||
@ -365,8 +365,18 @@
|
|||||||
<string name="emulation_screen_layout_single">Single Screen</string>
|
<string name="emulation_screen_layout_single">Single Screen</string>
|
||||||
<string name="emulation_screen_layout_sidebyside">Side by Side Screens</string>
|
<string name="emulation_screen_layout_sidebyside">Side by Side Screens</string>
|
||||||
<string name="emulation_screen_layout_hybrid">Hybrid Screens</string>
|
<string name="emulation_screen_layout_hybrid">Hybrid Screens</string>
|
||||||
|
<string name="emulation_screen_layout_original">Original</string>
|
||||||
<string name="emulation_portrait_layout_top_full">Default</string>
|
<string name="emulation_portrait_layout_top_full">Default</string>
|
||||||
<string name="emulation_screen_layout_custom">Custom Layout</string>
|
<string name="emulation_screen_layout_custom">Custom Layout</string>
|
||||||
|
<string name="emulation_adjust_custom_layout">Adjust Custom Layout in Settings</string>
|
||||||
|
<string name="emulation_landscape_custom_layout">Landscape Custom Layout</string>
|
||||||
|
<string name="emulation_portrait_custom_layout">Portrait Custom Layout</string>
|
||||||
|
<string name="emulation_top_screen">Top Screen</string>
|
||||||
|
<string name="emulation_bottom_screen">Bottom Screen</string>
|
||||||
|
<string name="emulation_custom_layout_x">X-Position</string>
|
||||||
|
<string name="emulation_custom_layout_y">Y-Position</string>
|
||||||
|
<string name="emulation_custom_layout_width">Width</string>
|
||||||
|
<string name="emulation_custom_layout_height">Height</string>
|
||||||
<string name="emulation_cycle_landscape_layouts">Cycle Layouts</string>
|
<string name="emulation_cycle_landscape_layouts">Cycle Layouts</string>
|
||||||
<string name="emulation_swap_screens">Swap Screens</string>
|
<string name="emulation_swap_screens">Swap Screens</string>
|
||||||
<string name="emulation_touch_overlay_reset">Reset Overlay</string>
|
<string name="emulation_touch_overlay_reset">Reset Overlay</string>
|
||||||
|
@ -490,9 +490,6 @@ struct Values {
|
|||||||
SwitchableSetting<bool> upright_screen{false, "upright_screen"};
|
SwitchableSetting<bool> upright_screen{false, "upright_screen"};
|
||||||
SwitchableSetting<float, true> large_screen_proportion{4.f, 1.f, 16.f,
|
SwitchableSetting<float, true> large_screen_proportion{4.f, 1.f, 16.f,
|
||||||
"large_screen_proportion"};
|
"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<bool> custom_layout{false, "custom_layout"};
|
|
||||||
Setting<u16> custom_top_x{0, "custom_top_x"};
|
Setting<u16> custom_top_x{0, "custom_top_x"};
|
||||||
Setting<u16> custom_top_y{0, "custom_top_y"};
|
Setting<u16> custom_top_y{0, "custom_top_y"};
|
||||||
Setting<u16> custom_top_width{800, "custom_top_width"};
|
Setting<u16> custom_top_width{800, "custom_top_width"};
|
||||||
|
@ -121,7 +121,7 @@ FramebufferLayout PortraitTopFullFrameLayout(u32 width, u32 height, bool swapped
|
|||||||
ASSERT(width > 0);
|
ASSERT(width > 0);
|
||||||
ASSERT(height > 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
|
// Default layout gives equal screen sizes to the top and bottom screen
|
||||||
Common::Rectangle<u32> screen_window_area{0, 0, width, height / 2};
|
Common::Rectangle<u32> screen_window_area{0, 0, width, height / 2};
|
||||||
Common::Rectangle<u32> top_screen = MaxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO);
|
Common::Rectangle<u32> 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(width > 0);
|
||||||
ASSERT(height > 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,
|
// 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
|
// 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(width > 0);
|
||||||
ASSERT(height > 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()
|
u16 top_x = is_portrait_mode ? Settings::values.custom_portrait_top_x.GetValue()
|
||||||
: Settings::values.custom_top_x.GetValue();
|
: Settings::values.custom_top_x.GetValue();
|
||||||
u16 top_width = is_portrait_mode ? Settings::values.custom_portrait_top_width.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;
|
return new_layout;
|
||||||
}
|
}
|
||||||
/*f
|
|
||||||
* TODO: remove this?
|
|
||||||
*/
|
|
||||||
std::pair<unsigned, unsigned> GetMinimumSizeFromPortraitLayout() {
|
std::pair<unsigned, unsigned> GetMinimumSizeFromPortraitLayout() {
|
||||||
u32 min_width, min_height;
|
u32 min_width, min_height;
|
||||||
min_width = Core::kScreenTopWidth;
|
min_width = Core::kScreenTopWidth;
|
||||||
|
@ -61,7 +61,7 @@ struct FramebufferLayout {
|
|||||||
Common::Rectangle<u32> top_screen;
|
Common::Rectangle<u32> top_screen;
|
||||||
Common::Rectangle<u32> bottom_screen;
|
Common::Rectangle<u32> bottom_screen;
|
||||||
bool is_rotated = true;
|
bool is_rotated = true;
|
||||||
|
bool is_portrait = false;
|
||||||
bool additional_screen_enabled;
|
bool additional_screen_enabled;
|
||||||
Common::Rectangle<u32> additional_screen;
|
Common::Rectangle<u32> additional_screen;
|
||||||
|
|
||||||
|
@ -164,8 +164,6 @@ void Config::ReadValues() {
|
|||||||
ReadSetting("Layout", Settings::values.swap_screen);
|
ReadSetting("Layout", Settings::values.swap_screen);
|
||||||
ReadSetting("Layout", Settings::values.upright_screen);
|
ReadSetting("Layout", Settings::values.upright_screen);
|
||||||
ReadSetting("Layout", Settings::values.large_screen_proportion);
|
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_x);
|
||||||
ReadSetting("Layout", Settings::values.custom_top_y);
|
ReadSetting("Layout", Settings::values.custom_top_y);
|
||||||
ReadSetting("Layout", Settings::values.custom_top_width);
|
ReadSetting("Layout", Settings::values.custom_top_width);
|
||||||
|
@ -182,7 +182,7 @@ filter_mode =
|
|||||||
|
|
||||||
[Layout]
|
[Layout]
|
||||||
# Layout for the screen inside the render window.
|
# Layout for the screen inside the render window.
|
||||||
# 0 (default): Default Top Bottom Screen
|
# 0 (default): Default Above/Below Screen
|
||||||
# 1: Single Screen Only
|
# 1: Single Screen Only
|
||||||
# 2: Large Screen Small Screen
|
# 2: Large Screen Small Screen
|
||||||
# 3: Side by Side
|
# 3: Side by Side
|
||||||
@ -191,10 +191,6 @@ filter_mode =
|
|||||||
# 6: Custom Layout
|
# 6: Custom Layout
|
||||||
layout_option =
|
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
|
# Screen placement when using Custom layout option
|
||||||
# 0x, 0y is the top left corner of the render window.
|
# 0x, 0y is the top left corner of the render window.
|
||||||
custom_top_x =
|
custom_top_x =
|
||||||
|
@ -520,8 +520,6 @@ void Config::ReadLayoutValues() {
|
|||||||
|
|
||||||
if (global) {
|
if (global) {
|
||||||
ReadBasicSetting(Settings::values.mono_render_option);
|
ReadBasicSetting(Settings::values.mono_render_option);
|
||||||
|
|
||||||
ReadBasicSetting(Settings::values.custom_layout);
|
|
||||||
ReadBasicSetting(Settings::values.custom_top_x);
|
ReadBasicSetting(Settings::values.custom_top_x);
|
||||||
ReadBasicSetting(Settings::values.custom_top_y);
|
ReadBasicSetting(Settings::values.custom_top_y);
|
||||||
ReadBasicSetting(Settings::values.custom_top_width);
|
ReadBasicSetting(Settings::values.custom_top_width);
|
||||||
@ -1081,8 +1079,6 @@ void Config::SaveLayoutValues() {
|
|||||||
|
|
||||||
if (global) {
|
if (global) {
|
||||||
WriteBasicSetting(Settings::values.mono_render_option);
|
WriteBasicSetting(Settings::values.mono_render_option);
|
||||||
|
|
||||||
WriteBasicSetting(Settings::values.custom_layout);
|
|
||||||
WriteBasicSetting(Settings::values.custom_top_x);
|
WriteBasicSetting(Settings::values.custom_top_x);
|
||||||
WriteBasicSetting(Settings::values.custom_top_y);
|
WriteBasicSetting(Settings::values.custom_top_y);
|
||||||
WriteBasicSetting(Settings::values.custom_top_width);
|
WriteBasicSetting(Settings::values.custom_top_width);
|
||||||
|
@ -634,10 +634,6 @@ void RendererOpenGL::DrawSingleScreenStereo(const ScreenInfo& screen_info_l,
|
|||||||
* Draws the emulated screens to the emulator window.
|
* Draws the emulated screens to the emulator window.
|
||||||
*/
|
*/
|
||||||
void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool flipped) {
|
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)) {
|
if (settings.bg_color_update_requested.exchange(false)) {
|
||||||
// Update background color before drawing
|
// Update background color before drawing
|
||||||
glClearColor(Settings::values.bg_red.GetValue(), Settings::values.bg_green.GetValue(),
|
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()) {
|
if (!Settings::values.swap_screen.GetValue()) {
|
||||||
DrawTopScreen(layout, top_screen);
|
DrawTopScreen(layout, top_screen);
|
||||||
glUniform1i(uniform_layer, 0);
|
glUniform1i(uniform_layer, 0);
|
||||||
ApplySecondLayerOpacity(isPortrait);
|
ApplySecondLayerOpacity(layout.is_portrait);
|
||||||
DrawBottomScreen(layout, bottom_screen);
|
DrawBottomScreen(layout, bottom_screen);
|
||||||
} else {
|
} else {
|
||||||
DrawBottomScreen(layout, bottom_screen);
|
DrawBottomScreen(layout, bottom_screen);
|
||||||
glUniform1i(uniform_layer, 0);
|
glUniform1i(uniform_layer, 0);
|
||||||
ApplySecondLayerOpacity(isPortrait);
|
ApplySecondLayerOpacity(layout.is_portrait);
|
||||||
DrawTopScreen(layout, top_screen);
|
DrawTopScreen(layout, top_screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -696,19 +692,14 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f
|
|||||||
DrawBottomScreen(layout, additional_screen);
|
DrawBottomScreen(layout, additional_screen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ResetSecondLayerOpacity(isPortrait);
|
ResetSecondLayerOpacity(layout.is_portrait);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererOpenGL::ApplySecondLayerOpacity(bool isPortrait) {
|
void RendererOpenGL::ApplySecondLayerOpacity(bool isPortrait) {
|
||||||
#ifdef ANDROID
|
|
||||||
// TODO: Allow for second layer opacity in portrait mode android
|
// TODO: Allow for second layer opacity in portrait mode android
|
||||||
if (isPortrait) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((Settings::values.layout_option.GetValue() == Settings::LayoutOption::CustomLayout ||
|
if (!isPortrait &&
|
||||||
Settings::values.custom_layout) &&
|
(Settings::values.layout_option.GetValue() == Settings::LayoutOption::CustomLayout) &&
|
||||||
Settings::values.custom_second_layer_opacity.GetValue() < 100) {
|
Settings::values.custom_second_layer_opacity.GetValue() < 100) {
|
||||||
state.blend.src_rgb_func = GL_CONSTANT_ALPHA;
|
state.blend.src_rgb_func = GL_CONSTANT_ALPHA;
|
||||||
state.blend.src_a_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) {
|
void RendererOpenGL::ResetSecondLayerOpacity(bool isPortrait) {
|
||||||
#ifdef ANDROID
|
if (!isPortrait &&
|
||||||
// TODO: Allow for second layer opacity in portrait mode android
|
(Settings::values.layout_option.GetValue() == Settings::LayoutOption::CustomLayout) &&
|
||||||
if (isPortrait) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((Settings::values.layout_option.GetValue() == Settings::LayoutOption::CustomLayout ||
|
|
||||||
Settings::values.custom_layout) &&
|
|
||||||
Settings::values.custom_second_layer_opacity.GetValue() < 100) {
|
Settings::values.custom_second_layer_opacity.GetValue() < 100) {
|
||||||
state.blend.src_rgb_func = GL_ONE;
|
state.blend.src_rgb_func = GL_ONE;
|
||||||
state.blend.dst_rgb_func = GL_ZERO;
|
state.blend.dst_rgb_func = GL_ZERO;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user