early-access version 4041
parent
05d9419e78
commit
d950efa077
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 4040.
|
This is the source code for early-access 4041.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -10,7 +10,7 @@ plugins {
|
||||||
id("com.android.application")
|
id("com.android.application")
|
||||||
id("org.jetbrains.kotlin.android")
|
id("org.jetbrains.kotlin.android")
|
||||||
id("kotlin-parcelize")
|
id("kotlin-parcelize")
|
||||||
kotlin("plugin.serialization") version "1.8.21"
|
kotlin("plugin.serialization") version "1.9.20"
|
||||||
id("androidx.navigation.safeargs.kotlin")
|
id("androidx.navigation.safeargs.kotlin")
|
||||||
id("org.jlleitschuh.gradle.ktlint") version "11.4.0"
|
id("org.jlleitschuh.gradle.ktlint") version "11.4.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ import org.yuzu.yuzu_emu.utils.ForegroundService
|
||||||
import org.yuzu.yuzu_emu.utils.InputHandler
|
import org.yuzu.yuzu_emu.utils.InputHandler
|
||||||
import org.yuzu.yuzu_emu.utils.Log
|
import org.yuzu.yuzu_emu.utils.Log
|
||||||
import org.yuzu.yuzu_emu.utils.MemoryUtil
|
import org.yuzu.yuzu_emu.utils.MemoryUtil
|
||||||
|
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||||
import org.yuzu.yuzu_emu.utils.NfcReader
|
import org.yuzu.yuzu_emu.utils.NfcReader
|
||||||
import org.yuzu.yuzu_emu.utils.ThemeHelper
|
import org.yuzu.yuzu_emu.utils.ThemeHelper
|
||||||
import java.text.NumberFormat
|
import java.text.NumberFormat
|
||||||
|
@ -170,6 +171,11 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
|
||||||
stopMotionSensorListener()
|
stopMotionSensorListener()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
super.onStop()
|
||||||
|
NativeConfig.saveGlobalConfig()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onUserLeaveHint() {
|
override fun onUserLeaveHint() {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
||||||
if (BooleanSetting.PICTURE_IN_PICTURE.getBoolean() && !isInPictureInPictureMode) {
|
if (BooleanSetting.PICTURE_IN_PICTURE.getBoolean() && !isInPictureInPictureMode) {
|
||||||
|
|
|
@ -18,7 +18,14 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
||||||
RENDERER_REACTIVE_FLUSHING("use_reactive_flushing"),
|
RENDERER_REACTIVE_FLUSHING("use_reactive_flushing"),
|
||||||
RENDERER_DEBUG("debug"),
|
RENDERER_DEBUG("debug"),
|
||||||
PICTURE_IN_PICTURE("picture_in_picture"),
|
PICTURE_IN_PICTURE("picture_in_picture"),
|
||||||
USE_CUSTOM_RTC("custom_rtc_enabled");
|
USE_CUSTOM_RTC("custom_rtc_enabled"),
|
||||||
|
BLACK_BACKGROUNDS("black_backgrounds"),
|
||||||
|
JOYSTICK_REL_CENTER("joystick_rel_center"),
|
||||||
|
DPAD_SLIDE("dpad_slide"),
|
||||||
|
HAPTIC_FEEDBACK("haptic_feedback"),
|
||||||
|
SHOW_PERFORMANCE_OVERLAY("show_performance_overlay"),
|
||||||
|
SHOW_INPUT_OVERLAY("show_input_overlay"),
|
||||||
|
TOUCHSCREEN("touchscreen");
|
||||||
|
|
||||||
override fun getBoolean(needsGlobal: Boolean): Boolean =
|
override fun getBoolean(needsGlobal: Boolean): Boolean =
|
||||||
NativeConfig.getBoolean(key, needsGlobal)
|
NativeConfig.getBoolean(key, needsGlobal)
|
||||||
|
|
|
@ -19,7 +19,11 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
|
||||||
RENDERER_SCREEN_LAYOUT("screen_layout"),
|
RENDERER_SCREEN_LAYOUT("screen_layout"),
|
||||||
RENDERER_ASPECT_RATIO("aspect_ratio"),
|
RENDERER_ASPECT_RATIO("aspect_ratio"),
|
||||||
AUDIO_OUTPUT_ENGINE("output_engine"),
|
AUDIO_OUTPUT_ENGINE("output_engine"),
|
||||||
MAX_ANISOTROPY("max_anisotropy");
|
MAX_ANISOTROPY("max_anisotropy"),
|
||||||
|
THEME("theme"),
|
||||||
|
THEME_MODE("theme_mode"),
|
||||||
|
OVERLAY_SCALE("control_scale"),
|
||||||
|
OVERLAY_OPACITY("control_opacity");
|
||||||
|
|
||||||
override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal)
|
override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal)
|
||||||
|
|
||||||
|
|
|
@ -15,18 +15,10 @@ object Settings {
|
||||||
SECTION_DEBUG(R.string.preferences_debug);
|
SECTION_DEBUG(R.string.preferences_debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const val PREF_FIRST_APP_LAUNCH = "FirstApplicationLaunch"
|
||||||
const val PREF_MEMORY_WARNING_SHOWN = "MemoryWarningShown"
|
const val PREF_MEMORY_WARNING_SHOWN = "MemoryWarningShown"
|
||||||
|
|
||||||
const val PREF_OVERLAY_VERSION = "OverlayVersion"
|
// Deprecated input overlay preference keys
|
||||||
const val PREF_LANDSCAPE_OVERLAY_VERSION = "LandscapeOverlayVersion"
|
|
||||||
const val PREF_PORTRAIT_OVERLAY_VERSION = "PortraitOverlayVersion"
|
|
||||||
const val PREF_FOLDABLE_OVERLAY_VERSION = "FoldableOverlayVersion"
|
|
||||||
val overlayLayoutPrefs = listOf(
|
|
||||||
PREF_LANDSCAPE_OVERLAY_VERSION,
|
|
||||||
PREF_PORTRAIT_OVERLAY_VERSION,
|
|
||||||
PREF_FOLDABLE_OVERLAY_VERSION
|
|
||||||
)
|
|
||||||
|
|
||||||
const val PREF_CONTROL_SCALE = "controlScale"
|
const val PREF_CONTROL_SCALE = "controlScale"
|
||||||
const val PREF_CONTROL_OPACITY = "controlOpacity"
|
const val PREF_CONTROL_OPACITY = "controlOpacity"
|
||||||
const val PREF_TOUCH_ENABLED = "isTouchEnabled"
|
const val PREF_TOUCH_ENABLED = "isTouchEnabled"
|
||||||
|
@ -47,23 +39,12 @@ object Settings {
|
||||||
const val PREF_BUTTON_STICK_R = "buttonToggle14"
|
const val PREF_BUTTON_STICK_R = "buttonToggle14"
|
||||||
const val PREF_BUTTON_HOME = "buttonToggle15"
|
const val PREF_BUTTON_HOME = "buttonToggle15"
|
||||||
const val PREF_BUTTON_SCREENSHOT = "buttonToggle16"
|
const val PREF_BUTTON_SCREENSHOT = "buttonToggle16"
|
||||||
|
|
||||||
const val PREF_MENU_SETTINGS_JOYSTICK_REL_CENTER = "EmulationMenuSettings_JoystickRelCenter"
|
const val PREF_MENU_SETTINGS_JOYSTICK_REL_CENTER = "EmulationMenuSettings_JoystickRelCenter"
|
||||||
const val PREF_MENU_SETTINGS_DPAD_SLIDE = "EmulationMenuSettings_DpadSlideEnable"
|
const val PREF_MENU_SETTINGS_DPAD_SLIDE = "EmulationMenuSettings_DpadSlideEnable"
|
||||||
const val PREF_MENU_SETTINGS_HAPTICS = "EmulationMenuSettings_Haptics"
|
const val PREF_MENU_SETTINGS_HAPTICS = "EmulationMenuSettings_Haptics"
|
||||||
const val PREF_MENU_SETTINGS_SHOW_FPS = "EmulationMenuSettings_ShowFps"
|
const val PREF_MENU_SETTINGS_SHOW_FPS = "EmulationMenuSettings_ShowFps"
|
||||||
const val PREF_MENU_SETTINGS_SHOW_OVERLAY = "EmulationMenuSettings_ShowOverlay"
|
const val PREF_MENU_SETTINGS_SHOW_OVERLAY = "EmulationMenuSettings_ShowOverlay"
|
||||||
|
|
||||||
const val PREF_FIRST_APP_LAUNCH = "FirstApplicationLaunch"
|
|
||||||
const val PREF_THEME = "Theme"
|
|
||||||
const val PREF_THEME_MODE = "ThemeMode"
|
|
||||||
const val PREF_BLACK_BACKGROUNDS = "BlackBackgrounds"
|
|
||||||
|
|
||||||
val overlayPreferences = listOf(
|
val overlayPreferences = listOf(
|
||||||
PREF_OVERLAY_VERSION,
|
|
||||||
PREF_CONTROL_SCALE,
|
|
||||||
PREF_CONTROL_OPACITY,
|
|
||||||
PREF_TOUCH_ENABLED,
|
|
||||||
PREF_BUTTON_A,
|
PREF_BUTTON_A,
|
||||||
PREF_BUTTON_B,
|
PREF_BUTTON_B,
|
||||||
PREF_BUTTON_X,
|
PREF_BUTTON_X,
|
||||||
|
@ -83,6 +64,21 @@ object Settings {
|
||||||
PREF_BUTTON_STICK_R
|
PREF_BUTTON_STICK_R
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Deprecated layout preference keys
|
||||||
|
const val PREF_LANDSCAPE_SUFFIX = "_Landscape"
|
||||||
|
const val PREF_PORTRAIT_SUFFIX = "_Portrait"
|
||||||
|
const val PREF_FOLDABLE_SUFFIX = "_Foldable"
|
||||||
|
val overlayLayoutSuffixes = listOf(
|
||||||
|
PREF_LANDSCAPE_SUFFIX,
|
||||||
|
PREF_PORTRAIT_SUFFIX,
|
||||||
|
PREF_FOLDABLE_SUFFIX
|
||||||
|
)
|
||||||
|
|
||||||
|
// Deprecated theme preference keys
|
||||||
|
const val PREF_THEME = "Theme"
|
||||||
|
const val PREF_THEME_MODE = "ThemeMode"
|
||||||
|
const val PREF_BLACK_BACKGROUNDS = "BlackBackgrounds"
|
||||||
|
|
||||||
const val LayoutOption_Unspecified = 0
|
const val LayoutOption_Unspecified = 0
|
||||||
const val LayoutOption_MobilePortrait = 4
|
const val LayoutOption_MobilePortrait = 4
|
||||||
const val LayoutOption_MobileLandscape = 5
|
const val LayoutOption_MobileLandscape = 5
|
||||||
|
|
|
@ -3,10 +3,8 @@
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.ui
|
package org.yuzu.yuzu_emu.features.settings.ui
|
||||||
|
|
||||||
import android.content.SharedPreferences
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.preference.PreferenceManager
|
|
||||||
import org.yuzu.yuzu_emu.NativeLibrary
|
import org.yuzu.yuzu_emu.NativeLibrary
|
||||||
import org.yuzu.yuzu_emu.R
|
import org.yuzu.yuzu_emu.R
|
||||||
import org.yuzu.yuzu_emu.YuzuApplication
|
import org.yuzu.yuzu_emu.YuzuApplication
|
||||||
|
@ -29,9 +27,6 @@ class SettingsFragmentPresenter(
|
||||||
) {
|
) {
|
||||||
private var settingsList = ArrayList<SettingsItem>()
|
private var settingsList = ArrayList<SettingsItem>()
|
||||||
|
|
||||||
private val preferences: SharedPreferences
|
|
||||||
get() = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
|
||||||
|
|
||||||
// Extension for altering settings list based on each setting's properties
|
// Extension for altering settings list based on each setting's properties
|
||||||
fun ArrayList<SettingsItem>.add(key: String) {
|
fun ArrayList<SettingsItem>.add(key: String) {
|
||||||
val item = SettingsItem.settingsItems[key]!!
|
val item = SettingsItem.settingsItems[key]!!
|
||||||
|
@ -170,25 +165,19 @@ class SettingsFragmentPresenter(
|
||||||
private fun addThemeSettings(sl: ArrayList<SettingsItem>) {
|
private fun addThemeSettings(sl: ArrayList<SettingsItem>) {
|
||||||
sl.apply {
|
sl.apply {
|
||||||
val theme: AbstractIntSetting = object : AbstractIntSetting {
|
val theme: AbstractIntSetting = object : AbstractIntSetting {
|
||||||
override fun getInt(needsGlobal: Boolean): Int =
|
override fun getInt(needsGlobal: Boolean): Int = IntSetting.THEME.getInt()
|
||||||
preferences.getInt(Settings.PREF_THEME, 0)
|
|
||||||
|
|
||||||
override fun setInt(value: Int) {
|
override fun setInt(value: Int) {
|
||||||
preferences.edit()
|
IntSetting.THEME.setInt(value)
|
||||||
.putInt(Settings.PREF_THEME, value)
|
|
||||||
.apply()
|
|
||||||
settingsViewModel.setShouldRecreate(true)
|
settingsViewModel.setShouldRecreate(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val key: String = Settings.PREF_THEME
|
override val key: String = IntSetting.THEME.key
|
||||||
override val isRuntimeModifiable: Boolean = false
|
override val isRuntimeModifiable: Boolean = IntSetting.THEME.isRuntimeModifiable
|
||||||
override fun getValueAsString(needsGlobal: Boolean): String = getInt().toString()
|
override fun getValueAsString(needsGlobal: Boolean): String =
|
||||||
override val defaultValue: Int = 0
|
IntSetting.THEME.getValueAsString()
|
||||||
override fun reset() {
|
|
||||||
preferences.edit()
|
override val defaultValue: Int = IntSetting.THEME.defaultValue
|
||||||
.putInt(Settings.PREF_THEME, defaultValue)
|
override fun reset() = IntSetting.THEME.setInt(defaultValue)
|
||||||
.apply()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
@ -214,24 +203,22 @@ class SettingsFragmentPresenter(
|
||||||
}
|
}
|
||||||
|
|
||||||
val themeMode: AbstractIntSetting = object : AbstractIntSetting {
|
val themeMode: AbstractIntSetting = object : AbstractIntSetting {
|
||||||
override fun getInt(needsGlobal: Boolean): Int =
|
override fun getInt(needsGlobal: Boolean): Int = IntSetting.THEME_MODE.getInt()
|
||||||
preferences.getInt(Settings.PREF_THEME_MODE, -1)
|
|
||||||
|
|
||||||
override fun setInt(value: Int) {
|
override fun setInt(value: Int) {
|
||||||
preferences.edit()
|
IntSetting.THEME_MODE.setInt(value)
|
||||||
.putInt(Settings.PREF_THEME_MODE, value)
|
|
||||||
.apply()
|
|
||||||
settingsViewModel.setShouldRecreate(true)
|
settingsViewModel.setShouldRecreate(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val key: String = Settings.PREF_THEME_MODE
|
override val key: String = IntSetting.THEME_MODE.key
|
||||||
override val isRuntimeModifiable: Boolean = false
|
override val isRuntimeModifiable: Boolean =
|
||||||
override fun getValueAsString(needsGlobal: Boolean): String = getInt().toString()
|
IntSetting.THEME_MODE.isRuntimeModifiable
|
||||||
override val defaultValue: Int = -1
|
|
||||||
|
override fun getValueAsString(needsGlobal: Boolean): String =
|
||||||
|
IntSetting.THEME_MODE.getValueAsString()
|
||||||
|
|
||||||
|
override val defaultValue: Int = IntSetting.THEME_MODE.defaultValue
|
||||||
override fun reset() {
|
override fun reset() {
|
||||||
preferences.edit()
|
IntSetting.THEME_MODE.setInt(defaultValue)
|
||||||
.putInt(Settings.PREF_BLACK_BACKGROUNDS, defaultValue)
|
|
||||||
.apply()
|
|
||||||
settingsViewModel.setShouldRecreate(true)
|
settingsViewModel.setShouldRecreate(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,25 +235,24 @@ class SettingsFragmentPresenter(
|
||||||
|
|
||||||
val blackBackgrounds: AbstractBooleanSetting = object : AbstractBooleanSetting {
|
val blackBackgrounds: AbstractBooleanSetting = object : AbstractBooleanSetting {
|
||||||
override fun getBoolean(needsGlobal: Boolean): Boolean =
|
override fun getBoolean(needsGlobal: Boolean): Boolean =
|
||||||
preferences.getBoolean(Settings.PREF_BLACK_BACKGROUNDS, false)
|
BooleanSetting.BLACK_BACKGROUNDS.getBoolean()
|
||||||
|
|
||||||
override fun setBoolean(value: Boolean) {
|
override fun setBoolean(value: Boolean) {
|
||||||
preferences.edit()
|
BooleanSetting.BLACK_BACKGROUNDS.setBoolean(value)
|
||||||
.putBoolean(Settings.PREF_BLACK_BACKGROUNDS, value)
|
|
||||||
.apply()
|
|
||||||
settingsViewModel.setShouldRecreate(true)
|
settingsViewModel.setShouldRecreate(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val key: String = Settings.PREF_BLACK_BACKGROUNDS
|
override val key: String = BooleanSetting.BLACK_BACKGROUNDS.key
|
||||||
override val isRuntimeModifiable: Boolean = false
|
override val isRuntimeModifiable: Boolean =
|
||||||
override fun getValueAsString(needsGlobal: Boolean): String =
|
BooleanSetting.BLACK_BACKGROUNDS.isRuntimeModifiable
|
||||||
getBoolean().toString()
|
|
||||||
|
|
||||||
override val defaultValue: Boolean = false
|
override fun getValueAsString(needsGlobal: Boolean): String =
|
||||||
|
BooleanSetting.BLACK_BACKGROUNDS.getValueAsString()
|
||||||
|
|
||||||
|
override val defaultValue: Boolean = BooleanSetting.BLACK_BACKGROUNDS.defaultValue
|
||||||
override fun reset() {
|
override fun reset() {
|
||||||
preferences.edit()
|
BooleanSetting.BLACK_BACKGROUNDS
|
||||||
.putBoolean(Settings.PREF_BLACK_BACKGROUNDS, defaultValue)
|
.setBoolean(BooleanSetting.BLACK_BACKGROUNDS.defaultValue)
|
||||||
.apply()
|
|
||||||
settingsViewModel.setShouldRecreate(true)
|
settingsViewModel.setShouldRecreate(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import android.annotation.SuppressLint
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
import android.content.SharedPreferences
|
|
||||||
import android.content.pm.ActivityInfo
|
import android.content.pm.ActivityInfo
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
@ -33,7 +32,6 @@ import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import androidx.preference.PreferenceManager
|
|
||||||
import androidx.window.layout.FoldingFeature
|
import androidx.window.layout.FoldingFeature
|
||||||
import androidx.window.layout.WindowInfoTracker
|
import androidx.window.layout.WindowInfoTracker
|
||||||
import androidx.window.layout.WindowLayoutInfo
|
import androidx.window.layout.WindowLayoutInfo
|
||||||
|
@ -46,22 +44,22 @@ import kotlinx.coroutines.launch
|
||||||
import org.yuzu.yuzu_emu.HomeNavigationDirections
|
import org.yuzu.yuzu_emu.HomeNavigationDirections
|
||||||
import org.yuzu.yuzu_emu.NativeLibrary
|
import org.yuzu.yuzu_emu.NativeLibrary
|
||||||
import org.yuzu.yuzu_emu.R
|
import org.yuzu.yuzu_emu.R
|
||||||
import org.yuzu.yuzu_emu.YuzuApplication
|
|
||||||
import org.yuzu.yuzu_emu.activities.EmulationActivity
|
import org.yuzu.yuzu_emu.activities.EmulationActivity
|
||||||
import org.yuzu.yuzu_emu.databinding.DialogOverlayAdjustBinding
|
import org.yuzu.yuzu_emu.databinding.DialogOverlayAdjustBinding
|
||||||
import org.yuzu.yuzu_emu.databinding.FragmentEmulationBinding
|
import org.yuzu.yuzu_emu.databinding.FragmentEmulationBinding
|
||||||
|
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
||||||
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
|
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
|
||||||
import org.yuzu.yuzu_emu.model.DriverViewModel
|
import org.yuzu.yuzu_emu.model.DriverViewModel
|
||||||
import org.yuzu.yuzu_emu.model.Game
|
import org.yuzu.yuzu_emu.model.Game
|
||||||
import org.yuzu.yuzu_emu.model.EmulationViewModel
|
import org.yuzu.yuzu_emu.model.EmulationViewModel
|
||||||
import org.yuzu.yuzu_emu.overlay.InputOverlay
|
import org.yuzu.yuzu_emu.overlay.model.OverlayControl
|
||||||
|
import org.yuzu.yuzu_emu.overlay.model.OverlayLayout
|
||||||
import org.yuzu.yuzu_emu.utils.*
|
import org.yuzu.yuzu_emu.utils.*
|
||||||
import java.lang.NullPointerException
|
import java.lang.NullPointerException
|
||||||
|
|
||||||
class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
private lateinit var preferences: SharedPreferences
|
|
||||||
private lateinit var emulationState: EmulationState
|
private lateinit var emulationState: EmulationState
|
||||||
private var emulationActivity: EmulationActivity? = null
|
private var emulationActivity: EmulationActivity? = null
|
||||||
private var perfStatsUpdater: (() -> Unit)? = null
|
private var perfStatsUpdater: (() -> Unit)? = null
|
||||||
|
@ -141,7 +139,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
|
|
||||||
// So this fragment doesn't restart on configuration changes; i.e. rotation.
|
// So this fragment doesn't restart on configuration changes; i.e. rotation.
|
||||||
retainInstance = true
|
retainInstance = true
|
||||||
preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
|
||||||
emulationState = EmulationState(game.path)
|
emulationState = EmulationState(game.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,24 +379,25 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateScreenLayout()
|
updateScreenLayout()
|
||||||
|
val showInputOverlay = BooleanSetting.SHOW_INPUT_OVERLAY.getBoolean()
|
||||||
if (emulationActivity?.isInPictureInPictureMode == true) {
|
if (emulationActivity?.isInPictureInPictureMode == true) {
|
||||||
if (binding.drawerLayout.isOpen) {
|
if (binding.drawerLayout.isOpen) {
|
||||||
binding.drawerLayout.close()
|
binding.drawerLayout.close()
|
||||||
}
|
}
|
||||||
if (EmulationMenuSettings.showOverlay) {
|
if (showInputOverlay) {
|
||||||
binding.surfaceInputOverlay.visibility = View.INVISIBLE
|
binding.surfaceInputOverlay.visibility = View.INVISIBLE
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (EmulationMenuSettings.showOverlay && emulationViewModel.emulationStarted.value) {
|
if (showInputOverlay && emulationViewModel.emulationStarted.value) {
|
||||||
binding.surfaceInputOverlay.visibility = View.VISIBLE
|
binding.surfaceInputOverlay.visibility = View.VISIBLE
|
||||||
} else {
|
} else {
|
||||||
binding.surfaceInputOverlay.visibility = View.INVISIBLE
|
binding.surfaceInputOverlay.visibility = View.INVISIBLE
|
||||||
}
|
}
|
||||||
if (!isInFoldableLayout) {
|
if (!isInFoldableLayout) {
|
||||||
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||||
binding.surfaceInputOverlay.layout = InputOverlay.PORTRAIT
|
binding.surfaceInputOverlay.layout = OverlayLayout.Portrait
|
||||||
} else {
|
} else {
|
||||||
binding.surfaceInputOverlay.layout = InputOverlay.LANDSCAPE
|
binding.surfaceInputOverlay.layout = OverlayLayout.Landscape
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -423,17 +421,15 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resetInputOverlay() {
|
private fun resetInputOverlay() {
|
||||||
preferences.edit()
|
IntSetting.OVERLAY_SCALE.reset()
|
||||||
.remove(Settings.PREF_CONTROL_SCALE)
|
IntSetting.OVERLAY_OPACITY.reset()
|
||||||
.remove(Settings.PREF_CONTROL_OPACITY)
|
|
||||||
.apply()
|
|
||||||
binding.surfaceInputOverlay.post {
|
binding.surfaceInputOverlay.post {
|
||||||
binding.surfaceInputOverlay.resetLayoutVisibilityAndPlacement()
|
binding.surfaceInputOverlay.resetLayoutVisibilityAndPlacement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateShowFpsOverlay() {
|
private fun updateShowFpsOverlay() {
|
||||||
if (EmulationMenuSettings.showFps) {
|
if (BooleanSetting.SHOW_PERFORMANCE_OVERLAY.getBoolean()) {
|
||||||
val SYSTEM_FPS = 0
|
val SYSTEM_FPS = 0
|
||||||
val FPS = 1
|
val FPS = 1
|
||||||
val FRAMETIME = 2
|
val FRAMETIME = 2
|
||||||
|
@ -496,7 +492,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
binding.inGameMenu.layoutParams.height = it.bounds.bottom
|
binding.inGameMenu.layoutParams.height = it.bounds.bottom
|
||||||
|
|
||||||
isInFoldableLayout = true
|
isInFoldableLayout = true
|
||||||
binding.surfaceInputOverlay.layout = InputOverlay.FOLDABLE
|
binding.surfaceInputOverlay.layout = OverlayLayout.Foldable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
it.isSeparating
|
it.isSeparating
|
||||||
|
@ -535,18 +531,22 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
popup.menuInflater.inflate(R.menu.menu_overlay_options, popup.menu)
|
popup.menuInflater.inflate(R.menu.menu_overlay_options, popup.menu)
|
||||||
|
|
||||||
popup.menu.apply {
|
popup.menu.apply {
|
||||||
findItem(R.id.menu_toggle_fps).isChecked = EmulationMenuSettings.showFps
|
findItem(R.id.menu_toggle_fps).isChecked =
|
||||||
findItem(R.id.menu_rel_stick_center).isChecked = EmulationMenuSettings.joystickRelCenter
|
BooleanSetting.SHOW_PERFORMANCE_OVERLAY.getBoolean()
|
||||||
findItem(R.id.menu_dpad_slide).isChecked = EmulationMenuSettings.dpadSlide
|
findItem(R.id.menu_rel_stick_center).isChecked =
|
||||||
findItem(R.id.menu_show_overlay).isChecked = EmulationMenuSettings.showOverlay
|
BooleanSetting.JOYSTICK_REL_CENTER.getBoolean()
|
||||||
findItem(R.id.menu_haptics).isChecked = EmulationMenuSettings.hapticFeedback
|
findItem(R.id.menu_dpad_slide).isChecked = BooleanSetting.DPAD_SLIDE.getBoolean()
|
||||||
|
findItem(R.id.menu_show_overlay).isChecked =
|
||||||
|
BooleanSetting.SHOW_INPUT_OVERLAY.getBoolean()
|
||||||
|
findItem(R.id.menu_haptics).isChecked = BooleanSetting.HAPTIC_FEEDBACK.getBoolean()
|
||||||
|
findItem(R.id.menu_touchscreen).isChecked = BooleanSetting.TOUCHSCREEN.getBoolean()
|
||||||
}
|
}
|
||||||
|
|
||||||
popup.setOnMenuItemClickListener {
|
popup.setOnMenuItemClickListener {
|
||||||
when (it.itemId) {
|
when (it.itemId) {
|
||||||
R.id.menu_toggle_fps -> {
|
R.id.menu_toggle_fps -> {
|
||||||
it.isChecked = !it.isChecked
|
it.isChecked = !it.isChecked
|
||||||
EmulationMenuSettings.showFps = it.isChecked
|
BooleanSetting.SHOW_PERFORMANCE_OVERLAY.setBoolean(it.isChecked)
|
||||||
updateShowFpsOverlay()
|
updateShowFpsOverlay()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -564,11 +564,12 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.menu_toggle_controls -> {
|
R.id.menu_toggle_controls -> {
|
||||||
val preferences =
|
val overlayControlData = NativeConfig.getOverlayControlData()
|
||||||
PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
val optionsArray = BooleanArray(overlayControlData.size)
|
||||||
val optionsArray = BooleanArray(Settings.overlayPreferences.size)
|
overlayControlData.forEachIndexed { i, _ ->
|
||||||
Settings.overlayPreferences.forEachIndexed { i, _ ->
|
optionsArray[i] = overlayControlData.firstOrNull { data ->
|
||||||
optionsArray[i] = preferences.getBoolean("buttonToggle$i", i < 15)
|
OverlayControl.entries[i].id == data.id
|
||||||
|
}?.enabled == true
|
||||||
}
|
}
|
||||||
|
|
||||||
val dialog = MaterialAlertDialogBuilder(requireContext())
|
val dialog = MaterialAlertDialogBuilder(requireContext())
|
||||||
|
@ -577,11 +578,13 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
R.array.gamepadButtons,
|
R.array.gamepadButtons,
|
||||||
optionsArray
|
optionsArray
|
||||||
) { _, indexSelected, isChecked ->
|
) { _, indexSelected, isChecked ->
|
||||||
preferences.edit()
|
overlayControlData.firstOrNull { data ->
|
||||||
.putBoolean("buttonToggle$indexSelected", isChecked)
|
OverlayControl.entries[indexSelected].id == data.id
|
||||||
.apply()
|
}?.enabled = isChecked
|
||||||
}
|
}
|
||||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||||
|
NativeConfig.setOverlayControlData(overlayControlData)
|
||||||
|
NativeConfig.saveGlobalConfig()
|
||||||
binding.surfaceInputOverlay.refreshControls()
|
binding.surfaceInputOverlay.refreshControls()
|
||||||
}
|
}
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
|
@ -592,12 +595,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
dialog.getButton(AlertDialog.BUTTON_NEUTRAL)
|
dialog.getButton(AlertDialog.BUTTON_NEUTRAL)
|
||||||
.setOnClickListener {
|
.setOnClickListener {
|
||||||
val isChecked = !optionsArray[0]
|
val isChecked = !optionsArray[0]
|
||||||
Settings.overlayPreferences.forEachIndexed { i, _ ->
|
overlayControlData.forEachIndexed { i, _ ->
|
||||||
optionsArray[i] = isChecked
|
optionsArray[i] = isChecked
|
||||||
dialog.listView.setItemChecked(i, isChecked)
|
dialog.listView.setItemChecked(i, isChecked)
|
||||||
preferences.edit()
|
overlayControlData[i].enabled = isChecked
|
||||||
.putBoolean("buttonToggle$i", isChecked)
|
|
||||||
.apply()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
|
@ -605,26 +606,32 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
|
|
||||||
R.id.menu_show_overlay -> {
|
R.id.menu_show_overlay -> {
|
||||||
it.isChecked = !it.isChecked
|
it.isChecked = !it.isChecked
|
||||||
EmulationMenuSettings.showOverlay = it.isChecked
|
BooleanSetting.SHOW_INPUT_OVERLAY.setBoolean(it.isChecked)
|
||||||
binding.surfaceInputOverlay.refreshControls()
|
binding.surfaceInputOverlay.refreshControls()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.menu_rel_stick_center -> {
|
R.id.menu_rel_stick_center -> {
|
||||||
it.isChecked = !it.isChecked
|
it.isChecked = !it.isChecked
|
||||||
EmulationMenuSettings.joystickRelCenter = it.isChecked
|
BooleanSetting.JOYSTICK_REL_CENTER.setBoolean(it.isChecked)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.menu_dpad_slide -> {
|
R.id.menu_dpad_slide -> {
|
||||||
it.isChecked = !it.isChecked
|
it.isChecked = !it.isChecked
|
||||||
EmulationMenuSettings.dpadSlide = it.isChecked
|
BooleanSetting.DPAD_SLIDE.setBoolean(it.isChecked)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.menu_haptics -> {
|
R.id.menu_haptics -> {
|
||||||
it.isChecked = !it.isChecked
|
it.isChecked = !it.isChecked
|
||||||
EmulationMenuSettings.hapticFeedback = it.isChecked
|
BooleanSetting.HAPTIC_FEEDBACK.setBoolean(it.isChecked)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
R.id.menu_touchscreen -> {
|
||||||
|
it.isChecked = !it.isChecked
|
||||||
|
BooleanSetting.TOUCHSCREEN.setBoolean(it.isChecked)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -667,6 +674,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
it.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
|
it.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
NativeConfig.saveGlobalConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
|
@ -675,7 +683,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
adjustBinding.apply {
|
adjustBinding.apply {
|
||||||
inputScaleSlider.apply {
|
inputScaleSlider.apply {
|
||||||
valueTo = 150F
|
valueTo = 150F
|
||||||
value = preferences.getInt(Settings.PREF_CONTROL_SCALE, 50).toFloat()
|
value = IntSetting.OVERLAY_SCALE.getInt().toFloat()
|
||||||
addOnChangeListener(
|
addOnChangeListener(
|
||||||
Slider.OnChangeListener { _, value, _ ->
|
Slider.OnChangeListener { _, value, _ ->
|
||||||
inputScaleValue.text = "${value.toInt()}%"
|
inputScaleValue.text = "${value.toInt()}%"
|
||||||
|
@ -685,7 +693,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
}
|
}
|
||||||
inputOpacitySlider.apply {
|
inputOpacitySlider.apply {
|
||||||
valueTo = 100F
|
valueTo = 100F
|
||||||
value = preferences.getInt(Settings.PREF_CONTROL_OPACITY, 100).toFloat()
|
value = IntSetting.OVERLAY_OPACITY.getInt().toFloat()
|
||||||
addOnChangeListener(
|
addOnChangeListener(
|
||||||
Slider.OnChangeListener { _, value, _ ->
|
Slider.OnChangeListener { _, value, _ ->
|
||||||
inputOpacityValue.text = "${value.toInt()}%"
|
inputOpacityValue.text = "${value.toInt()}%"
|
||||||
|
@ -709,16 +717,12 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setControlScale(scale: Int) {
|
private fun setControlScale(scale: Int) {
|
||||||
preferences.edit()
|
IntSetting.OVERLAY_SCALE.setInt(scale)
|
||||||
.putInt(Settings.PREF_CONTROL_SCALE, scale)
|
|
||||||
.apply()
|
|
||||||
binding.surfaceInputOverlay.refreshControls()
|
binding.surfaceInputOverlay.refreshControls()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setControlOpacity(opacity: Int) {
|
private fun setControlOpacity(opacity: Int) {
|
||||||
preferences.edit()
|
IntSetting.OVERLAY_OPACITY.setInt(opacity)
|
||||||
.putInt(Settings.PREF_CONTROL_OPACITY, opacity)
|
|
||||||
.apply()
|
|
||||||
binding.surfaceInputOverlay.refreshControls()
|
binding.surfaceInputOverlay.refreshControls()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,6 +10,7 @@ import android.graphics.Rect
|
||||||
import android.graphics.drawable.BitmapDrawable
|
import android.graphics.drawable.BitmapDrawable
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import org.yuzu.yuzu_emu.NativeLibrary.ButtonState
|
import org.yuzu.yuzu_emu.NativeLibrary.ButtonState
|
||||||
|
import org.yuzu.yuzu_emu.overlay.model.OverlayControlData
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom [BitmapDrawable] that is capable
|
* Custom [BitmapDrawable] that is capable
|
||||||
|
@ -25,7 +26,7 @@ class InputOverlayDrawableButton(
|
||||||
defaultStateBitmap: Bitmap,
|
defaultStateBitmap: Bitmap,
|
||||||
pressedStateBitmap: Bitmap,
|
pressedStateBitmap: Bitmap,
|
||||||
val buttonId: Int,
|
val buttonId: Int,
|
||||||
val prefId: String
|
val overlayControlData: OverlayControlData
|
||||||
) {
|
) {
|
||||||
// The ID value what motion event is tracking
|
// The ID value what motion event is tracking
|
||||||
var trackId: Int
|
var trackId: Int
|
||||||
|
|
|
@ -14,7 +14,7 @@ import kotlin.math.cos
|
||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
import org.yuzu.yuzu_emu.NativeLibrary
|
import org.yuzu.yuzu_emu.NativeLibrary
|
||||||
import org.yuzu.yuzu_emu.utils.EmulationMenuSettings
|
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom [BitmapDrawable] that is capable
|
* Custom [BitmapDrawable] that is capable
|
||||||
|
@ -125,7 +125,7 @@ class InputOverlayDrawableJoystick(
|
||||||
pressedState = true
|
pressedState = true
|
||||||
outerBitmap.alpha = 0
|
outerBitmap.alpha = 0
|
||||||
boundsBoxBitmap.alpha = opacity
|
boundsBoxBitmap.alpha = opacity
|
||||||
if (EmulationMenuSettings.joystickRelCenter) {
|
if (BooleanSetting.JOYSTICK_REL_CENTER.getBoolean()) {
|
||||||
virtBounds.offset(
|
virtBounds.offset(
|
||||||
xPosition - virtBounds.centerX(),
|
xPosition - virtBounds.centerX(),
|
||||||
yPosition - virtBounds.centerY()
|
yPosition - virtBounds.centerY()
|
||||||
|
|
|
@ -0,0 +1,188 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.overlay.model
|
||||||
|
|
||||||
|
import androidx.annotation.IntegerRes
|
||||||
|
import org.yuzu.yuzu_emu.R
|
||||||
|
import org.yuzu.yuzu_emu.YuzuApplication
|
||||||
|
|
||||||
|
enum class OverlayControl(
|
||||||
|
val id: String,
|
||||||
|
val defaultVisibility: Boolean,
|
||||||
|
@IntegerRes val defaultLandscapePositionResources: Pair<Int, Int>,
|
||||||
|
@IntegerRes val defaultPortraitPositionResources: Pair<Int, Int>,
|
||||||
|
@IntegerRes val defaultFoldablePositionResources: Pair<Int, Int>
|
||||||
|
) {
|
||||||
|
BUTTON_A(
|
||||||
|
"button_a",
|
||||||
|
true,
|
||||||
|
Pair(R.integer.BUTTON_A_X, R.integer.BUTTON_A_Y),
|
||||||
|
Pair(R.integer.BUTTON_A_X_PORTRAIT, R.integer.BUTTON_A_Y_PORTRAIT),
|
||||||
|
Pair(R.integer.BUTTON_A_X_FOLDABLE, R.integer.BUTTON_A_Y_FOLDABLE)
|
||||||
|
),
|
||||||
|
BUTTON_B(
|
||||||
|
"button_b",
|
||||||
|
true,
|
||||||
|
Pair(R.integer.BUTTON_B_X, R.integer.BUTTON_B_Y),
|
||||||
|
Pair(R.integer.BUTTON_B_X_PORTRAIT, R.integer.BUTTON_B_Y_PORTRAIT),
|
||||||
|
Pair(R.integer.BUTTON_B_X_FOLDABLE, R.integer.BUTTON_B_Y_FOLDABLE)
|
||||||
|
),
|
||||||
|
BUTTON_X(
|
||||||
|
"button_x",
|
||||||
|
true,
|
||||||
|
Pair(R.integer.BUTTON_X_X, R.integer.BUTTON_X_Y),
|
||||||
|
Pair(R.integer.BUTTON_X_X_PORTRAIT, R.integer.BUTTON_X_Y_PORTRAIT),
|
||||||
|
Pair(R.integer.BUTTON_X_X_FOLDABLE, R.integer.BUTTON_X_Y_FOLDABLE)
|
||||||
|
),
|
||||||
|
BUTTON_Y(
|
||||||
|
"button_y",
|
||||||
|
true,
|
||||||
|
Pair(R.integer.BUTTON_Y_X, R.integer.BUTTON_Y_Y),
|
||||||
|
Pair(R.integer.BUTTON_Y_X_PORTRAIT, R.integer.BUTTON_Y_Y_PORTRAIT),
|
||||||
|
Pair(R.integer.BUTTON_Y_X_FOLDABLE, R.integer.BUTTON_Y_Y_FOLDABLE)
|
||||||
|
),
|
||||||
|
BUTTON_PLUS(
|
||||||
|
"button_plus",
|
||||||
|
true,
|
||||||
|
Pair(R.integer.BUTTON_PLUS_X, R.integer.BUTTON_PLUS_Y),
|
||||||
|
Pair(R.integer.BUTTON_PLUS_X_PORTRAIT, R.integer.BUTTON_PLUS_Y_PORTRAIT),
|
||||||
|
Pair(R.integer.BUTTON_PLUS_X_FOLDABLE, R.integer.BUTTON_PLUS_Y_FOLDABLE)
|
||||||
|
),
|
||||||
|
BUTTON_MINUS(
|
||||||
|
"button_minus",
|
||||||
|
true,
|
||||||
|
Pair(R.integer.BUTTON_MINUS_X, R.integer.BUTTON_MINUS_Y),
|
||||||
|
Pair(R.integer.BUTTON_MINUS_X_PORTRAIT, R.integer.BUTTON_MINUS_Y_PORTRAIT),
|
||||||
|
Pair(R.integer.BUTTON_MINUS_X_FOLDABLE, R.integer.BUTTON_MINUS_Y_FOLDABLE)
|
||||||
|
),
|
||||||
|
BUTTON_HOME(
|
||||||
|
"button_home",
|
||||||
|
false,
|
||||||
|
Pair(R.integer.BUTTON_HOME_X, R.integer.BUTTON_HOME_Y),
|
||||||
|
Pair(R.integer.BUTTON_HOME_X_PORTRAIT, R.integer.BUTTON_HOME_Y_PORTRAIT),
|
||||||
|
Pair(R.integer.BUTTON_HOME_X_FOLDABLE, R.integer.BUTTON_HOME_Y_FOLDABLE)
|
||||||
|
),
|
||||||
|
BUTTON_CAPTURE(
|
||||||
|
"button_capture",
|
||||||
|
false,
|
||||||
|
Pair(R.integer.BUTTON_CAPTURE_X, R.integer.BUTTON_CAPTURE_Y),
|
||||||
|
Pair(R.integer.BUTTON_CAPTURE_X_PORTRAIT, R.integer.BUTTON_CAPTURE_Y_PORTRAIT),
|
||||||
|
Pair(R.integer.BUTTON_CAPTURE_X_FOLDABLE, R.integer.BUTTON_CAPTURE_Y_FOLDABLE)
|
||||||
|
),
|
||||||
|
BUTTON_L(
|
||||||
|
"button_l",
|
||||||
|
true,
|
||||||
|
Pair(R.integer.BUTTON_L_X, R.integer.BUTTON_L_Y),
|
||||||
|
Pair(R.integer.BUTTON_L_X_PORTRAIT, R.integer.BUTTON_L_Y_PORTRAIT),
|
||||||
|
Pair(R.integer.BUTTON_L_X_FOLDABLE, R.integer.BUTTON_L_Y_FOLDABLE)
|
||||||
|
),
|
||||||
|
BUTTON_R(
|
||||||
|
"button_r",
|
||||||
|
true,
|
||||||
|
Pair(R.integer.BUTTON_R_X, R.integer.BUTTON_R_Y),
|
||||||
|
Pair(R.integer.BUTTON_R_X_PORTRAIT, R.integer.BUTTON_R_Y_PORTRAIT),
|
||||||
|
Pair(R.integer.BUTTON_R_X_FOLDABLE, R.integer.BUTTON_R_Y_FOLDABLE)
|
||||||
|
),
|
||||||
|
BUTTON_ZL(
|
||||||
|
"button_zl",
|
||||||
|
true,
|
||||||
|
Pair(R.integer.BUTTON_ZL_X, R.integer.BUTTON_ZL_Y),
|
||||||
|
Pair(R.integer.BUTTON_ZL_X_PORTRAIT, R.integer.BUTTON_ZL_Y_PORTRAIT),
|
||||||
|
Pair(R.integer.BUTTON_ZL_X_FOLDABLE, R.integer.BUTTON_ZL_Y_FOLDABLE)
|
||||||
|
),
|
||||||
|
BUTTON_ZR(
|
||||||
|
"button_zr",
|
||||||
|
true,
|
||||||
|
Pair(R.integer.BUTTON_ZR_X, R.integer.BUTTON_ZR_Y),
|
||||||
|
Pair(R.integer.BUTTON_ZR_X_PORTRAIT, R.integer.BUTTON_ZR_Y_PORTRAIT),
|
||||||
|
Pair(R.integer.BUTTON_ZR_X_FOLDABLE, R.integer.BUTTON_ZR_Y_FOLDABLE)
|
||||||
|
),
|
||||||
|
BUTTON_STICK_L(
|
||||||
|
"button_stick_l",
|
||||||
|
true,
|
||||||
|
Pair(R.integer.BUTTON_STICK_L_X, R.integer.BUTTON_STICK_L_Y),
|
||||||
|
Pair(R.integer.BUTTON_STICK_L_X_PORTRAIT, R.integer.BUTTON_STICK_L_Y_PORTRAIT),
|
||||||
|
Pair(R.integer.BUTTON_STICK_L_X_FOLDABLE, R.integer.BUTTON_STICK_L_Y_FOLDABLE)
|
||||||
|
),
|
||||||
|
BUTTON_STICK_R(
|
||||||
|
"button_stick_r",
|
||||||
|
true,
|
||||||
|
Pair(R.integer.BUTTON_STICK_R_X, R.integer.BUTTON_STICK_R_Y),
|
||||||
|
Pair(R.integer.BUTTON_STICK_R_X_PORTRAIT, R.integer.BUTTON_STICK_R_Y_PORTRAIT),
|
||||||
|
Pair(R.integer.BUTTON_STICK_R_X_FOLDABLE, R.integer.BUTTON_STICK_R_Y_FOLDABLE)
|
||||||
|
),
|
||||||
|
STICK_L(
|
||||||
|
"stick_l",
|
||||||
|
true,
|
||||||
|
Pair(R.integer.STICK_L_X, R.integer.STICK_L_Y),
|
||||||
|
Pair(R.integer.STICK_L_X_PORTRAIT, R.integer.STICK_L_Y_PORTRAIT),
|
||||||
|
Pair(R.integer.STICK_L_X_FOLDABLE, R.integer.STICK_L_Y_FOLDABLE)
|
||||||
|
),
|
||||||
|
STICK_R(
|
||||||
|
"stick_r",
|
||||||
|
true,
|
||||||
|
Pair(R.integer.STICK_R_X, R.integer.STICK_R_Y),
|
||||||
|
Pair(R.integer.STICK_R_X_PORTRAIT, R.integer.STICK_R_Y_PORTRAIT),
|
||||||
|
Pair(R.integer.STICK_R_X_FOLDABLE, R.integer.STICK_R_Y_FOLDABLE)
|
||||||
|
),
|
||||||
|
COMBINED_DPAD(
|
||||||
|
"combined_dpad",
|
||||||
|
true,
|
||||||
|
Pair(R.integer.COMBINED_DPAD_X, R.integer.COMBINED_DPAD_Y),
|
||||||
|
Pair(R.integer.COMBINED_DPAD_X_PORTRAIT, R.integer.COMBINED_DPAD_Y_PORTRAIT),
|
||||||
|
Pair(R.integer.COMBINED_DPAD_X_FOLDABLE, R.integer.COMBINED_DPAD_Y_FOLDABLE)
|
||||||
|
);
|
||||||
|
|
||||||
|
fun getDefaultPositionForLayout(layout: OverlayLayout): Pair<Double, Double> {
|
||||||
|
val rawResourcePair: Pair<Int, Int>
|
||||||
|
YuzuApplication.appContext.resources.apply {
|
||||||
|
rawResourcePair = when (layout) {
|
||||||
|
OverlayLayout.Landscape -> {
|
||||||
|
Pair(
|
||||||
|
getInteger(this@OverlayControl.defaultLandscapePositionResources.first),
|
||||||
|
getInteger(this@OverlayControl.defaultLandscapePositionResources.second)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
OverlayLayout.Portrait -> {
|
||||||
|
Pair(
|
||||||
|
getInteger(this@OverlayControl.defaultPortraitPositionResources.first),
|
||||||
|
getInteger(this@OverlayControl.defaultPortraitPositionResources.second)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
OverlayLayout.Foldable -> {
|
||||||
|
Pair(
|
||||||
|
getInteger(this@OverlayControl.defaultFoldablePositionResources.first),
|
||||||
|
getInteger(this@OverlayControl.defaultFoldablePositionResources.second)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Pair(
|
||||||
|
rawResourcePair.first.toDouble() / 1000,
|
||||||
|
rawResourcePair.second.toDouble() / 1000
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toOverlayControlData(): OverlayControlData =
|
||||||
|
OverlayControlData(
|
||||||
|
id,
|
||||||
|
defaultVisibility,
|
||||||
|
getDefaultPositionForLayout(OverlayLayout.Landscape),
|
||||||
|
getDefaultPositionForLayout(OverlayLayout.Portrait),
|
||||||
|
getDefaultPositionForLayout(OverlayLayout.Foldable)
|
||||||
|
)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val map: HashMap<String, OverlayControl> by lazy {
|
||||||
|
val hashMap = hashMapOf<String, OverlayControl>()
|
||||||
|
entries.forEach { hashMap[it.id] = it }
|
||||||
|
hashMap
|
||||||
|
}
|
||||||
|
|
||||||
|
fun from(id: String): OverlayControl? = map[id]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.overlay.model
|
||||||
|
|
||||||
|
data class OverlayControlData(
|
||||||
|
val id: String,
|
||||||
|
var enabled: Boolean,
|
||||||
|
var landscapePosition: Pair<Double, Double>,
|
||||||
|
var portraitPosition: Pair<Double, Double>,
|
||||||
|
var foldablePosition: Pair<Double, Double>
|
||||||
|
) {
|
||||||
|
fun positionFromLayout(layout: OverlayLayout): Pair<Double, Double> =
|
||||||
|
when (layout) {
|
||||||
|
OverlayLayout.Landscape -> landscapePosition
|
||||||
|
OverlayLayout.Portrait -> portraitPosition
|
||||||
|
OverlayLayout.Foldable -> foldablePosition
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.overlay.model
|
||||||
|
|
||||||
|
import androidx.annotation.IntegerRes
|
||||||
|
|
||||||
|
data class OverlayControlDefault(
|
||||||
|
val buttonId: String,
|
||||||
|
@IntegerRes val landscapePositionResource: Pair<Int, Int>,
|
||||||
|
@IntegerRes val portraitPositionResource: Pair<Int, Int>,
|
||||||
|
@IntegerRes val foldablePositionResource: Pair<Int, Int>
|
||||||
|
)
|
|
@ -0,0 +1,10 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.overlay.model
|
||||||
|
|
||||||
|
enum class OverlayLayout(val id: String) {
|
||||||
|
Landscape("Landscape"),
|
||||||
|
Portrait("Portrait"),
|
||||||
|
Foldable("Foldable")
|
||||||
|
}
|
|
@ -3,9 +3,17 @@
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.utils
|
package org.yuzu.yuzu_emu.utils
|
||||||
|
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import org.yuzu.yuzu_emu.NativeLibrary
|
import org.yuzu.yuzu_emu.NativeLibrary
|
||||||
import org.yuzu.yuzu_emu.YuzuApplication
|
import org.yuzu.yuzu_emu.YuzuApplication
|
||||||
|
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||||
|
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||||
|
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
||||||
|
import org.yuzu.yuzu_emu.overlay.model.OverlayControlData
|
||||||
|
import org.yuzu.yuzu_emu.overlay.model.OverlayControl
|
||||||
|
import org.yuzu.yuzu_emu.overlay.model.OverlayLayout
|
||||||
|
import org.yuzu.yuzu_emu.utils.PreferenceUtil.migratePreference
|
||||||
|
|
||||||
object DirectoryInitialization {
|
object DirectoryInitialization {
|
||||||
private var userPath: String? = null
|
private var userPath: String? = null
|
||||||
|
@ -17,6 +25,7 @@ object DirectoryInitialization {
|
||||||
initializeInternalStorage()
|
initializeInternalStorage()
|
||||||
NativeLibrary.initializeSystem(false)
|
NativeLibrary.initializeSystem(false)
|
||||||
NativeConfig.initializeGlobalConfig()
|
NativeConfig.initializeGlobalConfig()
|
||||||
|
migrateSettings()
|
||||||
areDirectoriesReady = true
|
areDirectoriesReady = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,4 +44,170 @@ object DirectoryInitialization {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun migrateSettings() {
|
||||||
|
val preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
||||||
|
var saveConfig = false
|
||||||
|
val theme = preferences.migratePreference<Int>(Settings.PREF_THEME)
|
||||||
|
if (theme != null) {
|
||||||
|
IntSetting.THEME.setInt(theme)
|
||||||
|
saveConfig = true
|
||||||
|
}
|
||||||
|
|
||||||
|
val themeMode = preferences.migratePreference<Int>(Settings.PREF_THEME_MODE)
|
||||||
|
if (themeMode != null) {
|
||||||
|
IntSetting.THEME_MODE.setInt(themeMode)
|
||||||
|
saveConfig = true
|
||||||
|
}
|
||||||
|
|
||||||
|
val blackBackgrounds =
|
||||||
|
preferences.migratePreference<Boolean>(Settings.PREF_BLACK_BACKGROUNDS)
|
||||||
|
if (blackBackgrounds != null) {
|
||||||
|
BooleanSetting.BLACK_BACKGROUNDS.setBoolean(blackBackgrounds)
|
||||||
|
saveConfig = true
|
||||||
|
}
|
||||||
|
|
||||||
|
val joystickRelCenter =
|
||||||
|
preferences.migratePreference<Boolean>(Settings.PREF_MENU_SETTINGS_JOYSTICK_REL_CENTER)
|
||||||
|
if (joystickRelCenter != null) {
|
||||||
|
BooleanSetting.JOYSTICK_REL_CENTER.setBoolean(joystickRelCenter)
|
||||||
|
saveConfig = true
|
||||||
|
}
|
||||||
|
|
||||||
|
val dpadSlide =
|
||||||
|
preferences.migratePreference<Boolean>(Settings.PREF_MENU_SETTINGS_DPAD_SLIDE)
|
||||||
|
if (dpadSlide != null) {
|
||||||
|
BooleanSetting.DPAD_SLIDE.setBoolean(dpadSlide)
|
||||||
|
saveConfig = true
|
||||||
|
}
|
||||||
|
|
||||||
|
val hapticFeedback =
|
||||||
|
preferences.migratePreference<Boolean>(Settings.PREF_MENU_SETTINGS_HAPTICS)
|
||||||
|
if (hapticFeedback != null) {
|
||||||
|
BooleanSetting.HAPTIC_FEEDBACK.setBoolean(hapticFeedback)
|
||||||
|
saveConfig = true
|
||||||
|
}
|
||||||
|
|
||||||
|
val showPerformanceOverlay =
|
||||||
|
preferences.migratePreference<Boolean>(Settings.PREF_MENU_SETTINGS_SHOW_FPS)
|
||||||
|
if (showPerformanceOverlay != null) {
|
||||||
|
BooleanSetting.SHOW_PERFORMANCE_OVERLAY.setBoolean(showPerformanceOverlay)
|
||||||
|
saveConfig = true
|
||||||
|
}
|
||||||
|
|
||||||
|
val showInputOverlay =
|
||||||
|
preferences.migratePreference<Boolean>(Settings.PREF_MENU_SETTINGS_SHOW_OVERLAY)
|
||||||
|
if (showInputOverlay != null) {
|
||||||
|
BooleanSetting.SHOW_INPUT_OVERLAY.setBoolean(showInputOverlay)
|
||||||
|
saveConfig = true
|
||||||
|
}
|
||||||
|
|
||||||
|
val overlayOpacity = preferences.migratePreference<Int>(Settings.PREF_CONTROL_OPACITY)
|
||||||
|
if (overlayOpacity != null) {
|
||||||
|
IntSetting.OVERLAY_OPACITY.setInt(overlayOpacity)
|
||||||
|
saveConfig = true
|
||||||
|
}
|
||||||
|
|
||||||
|
val overlayScale = preferences.migratePreference<Int>(Settings.PREF_CONTROL_SCALE)
|
||||||
|
if (overlayScale != null) {
|
||||||
|
IntSetting.OVERLAY_SCALE.setInt(overlayScale)
|
||||||
|
saveConfig = true
|
||||||
|
}
|
||||||
|
|
||||||
|
var setOverlayData = false
|
||||||
|
val overlayControlData = NativeConfig.getOverlayControlData()
|
||||||
|
if (overlayControlData.isEmpty()) {
|
||||||
|
val overlayControlDataMap =
|
||||||
|
NativeConfig.getOverlayControlData().associateBy { it.id }.toMutableMap()
|
||||||
|
for (button in Settings.overlayPreferences) {
|
||||||
|
val buttonId = convertButtonId(button)
|
||||||
|
var buttonEnabled = preferences.migratePreference<Boolean>(button)
|
||||||
|
if (buttonEnabled == null) {
|
||||||
|
buttonEnabled = OverlayControl.map[buttonId]?.defaultVisibility == true
|
||||||
|
}
|
||||||
|
|
||||||
|
var landscapeXPosition = preferences.migratePreference<Float>(
|
||||||
|
"$button-X${Settings.PREF_LANDSCAPE_SUFFIX}"
|
||||||
|
)?.toDouble()
|
||||||
|
var landscapeYPosition = preferences.migratePreference<Float>(
|
||||||
|
"$button-Y${Settings.PREF_LANDSCAPE_SUFFIX}"
|
||||||
|
)?.toDouble()
|
||||||
|
if (landscapeXPosition == null || landscapeYPosition == null) {
|
||||||
|
val landscapePosition = OverlayControl.map[buttonId]
|
||||||
|
?.getDefaultPositionForLayout(OverlayLayout.Landscape) ?: Pair(0.0, 0.0)
|
||||||
|
landscapeXPosition = landscapePosition.first
|
||||||
|
landscapeYPosition = landscapePosition.second
|
||||||
|
}
|
||||||
|
|
||||||
|
var portraitXPosition = preferences.migratePreference<Float>(
|
||||||
|
"$button-X${Settings.PREF_PORTRAIT_SUFFIX}"
|
||||||
|
)?.toDouble()
|
||||||
|
var portraitYPosition = preferences.migratePreference<Float>(
|
||||||
|
"$button-Y${Settings.PREF_PORTRAIT_SUFFIX}"
|
||||||
|
)?.toDouble()
|
||||||
|
if (portraitXPosition == null || portraitYPosition == null) {
|
||||||
|
val portraitPosition = OverlayControl.map[buttonId]
|
||||||
|
?.getDefaultPositionForLayout(OverlayLayout.Portrait) ?: Pair(0.0, 0.0)
|
||||||
|
portraitXPosition = portraitPosition.first
|
||||||
|
portraitYPosition = portraitPosition.second
|
||||||
|
}
|
||||||
|
|
||||||
|
var foldableXPosition = preferences.migratePreference<Float>(
|
||||||
|
"$button-X${Settings.PREF_FOLDABLE_SUFFIX}"
|
||||||
|
)?.toDouble()
|
||||||
|
var foldableYPosition = preferences.migratePreference<Float>(
|
||||||
|
"$button-Y${Settings.PREF_FOLDABLE_SUFFIX}"
|
||||||
|
)?.toDouble()
|
||||||
|
if (foldableXPosition == null || foldableYPosition == null) {
|
||||||
|
val foldablePosition = OverlayControl.map[buttonId]
|
||||||
|
?.getDefaultPositionForLayout(OverlayLayout.Foldable) ?: Pair(0.0, 0.0)
|
||||||
|
foldableXPosition = foldablePosition.first
|
||||||
|
foldableYPosition = foldablePosition.second
|
||||||
|
}
|
||||||
|
|
||||||
|
val controlData = OverlayControlData(
|
||||||
|
buttonId,
|
||||||
|
buttonEnabled,
|
||||||
|
Pair(landscapeXPosition, landscapeYPosition),
|
||||||
|
Pair(portraitXPosition, portraitYPosition),
|
||||||
|
Pair(foldableXPosition, foldableYPosition)
|
||||||
|
)
|
||||||
|
overlayControlDataMap[buttonId] = controlData
|
||||||
|
setOverlayData = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setOverlayData) {
|
||||||
|
NativeConfig.setOverlayControlData(
|
||||||
|
overlayControlDataMap.map { it.value }.toTypedArray()
|
||||||
|
)
|
||||||
|
saveConfig = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saveConfig) {
|
||||||
|
NativeConfig.saveGlobalConfig()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun convertButtonId(buttonId: String): String =
|
||||||
|
when (buttonId) {
|
||||||
|
Settings.PREF_BUTTON_A -> OverlayControl.BUTTON_A.id
|
||||||
|
Settings.PREF_BUTTON_B -> OverlayControl.BUTTON_B.id
|
||||||
|
Settings.PREF_BUTTON_X -> OverlayControl.BUTTON_X.id
|
||||||
|
Settings.PREF_BUTTON_Y -> OverlayControl.BUTTON_Y.id
|
||||||
|
Settings.PREF_BUTTON_L -> OverlayControl.BUTTON_L.id
|
||||||
|
Settings.PREF_BUTTON_R -> OverlayControl.BUTTON_R.id
|
||||||
|
Settings.PREF_BUTTON_ZL -> OverlayControl.BUTTON_ZL.id
|
||||||
|
Settings.PREF_BUTTON_ZR -> OverlayControl.BUTTON_ZR.id
|
||||||
|
Settings.PREF_BUTTON_PLUS -> OverlayControl.BUTTON_PLUS.id
|
||||||
|
Settings.PREF_BUTTON_MINUS -> OverlayControl.BUTTON_MINUS.id
|
||||||
|
Settings.PREF_BUTTON_DPAD -> OverlayControl.COMBINED_DPAD.id
|
||||||
|
Settings.PREF_STICK_L -> OverlayControl.STICK_L.id
|
||||||
|
Settings.PREF_STICK_R -> OverlayControl.STICK_R.id
|
||||||
|
Settings.PREF_BUTTON_HOME -> OverlayControl.BUTTON_HOME.id
|
||||||
|
Settings.PREF_BUTTON_SCREENSHOT -> OverlayControl.BUTTON_CAPTURE.id
|
||||||
|
Settings.PREF_BUTTON_STICK_L -> OverlayControl.BUTTON_STICK_L.id
|
||||||
|
Settings.PREF_BUTTON_STICK_R -> OverlayControl.BUTTON_STICK_R.id
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
package org.yuzu.yuzu_emu.utils
|
package org.yuzu.yuzu_emu.utils
|
||||||
|
|
||||||
import org.yuzu.yuzu_emu.model.GameDir
|
import org.yuzu.yuzu_emu.model.GameDir
|
||||||
|
import org.yuzu.yuzu_emu.overlay.model.OverlayControlData
|
||||||
|
|
||||||
object NativeConfig {
|
object NativeConfig {
|
||||||
/**
|
/**
|
||||||
|
@ -150,4 +151,21 @@ object NativeConfig {
|
||||||
*/
|
*/
|
||||||
@Synchronized
|
@Synchronized
|
||||||
external fun setDisabledAddons(programId: String, disabledAddons: Array<String>)
|
external fun setDisabledAddons(programId: String, disabledAddons: Array<String>)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an array of [OverlayControlData] from settings
|
||||||
|
*
|
||||||
|
* @return An array of [OverlayControlData]
|
||||||
|
*/
|
||||||
|
@Synchronized
|
||||||
|
external fun getOverlayControlData(): Array<OverlayControlData>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the AndroidSettings::values.overlay_control_data array and replaces its values
|
||||||
|
* with [overlayControlData]
|
||||||
|
*
|
||||||
|
* @param overlayControlData Replacement array of [OverlayControlData]
|
||||||
|
*/
|
||||||
|
@Synchronized
|
||||||
|
external fun setOverlayControlData(overlayControlData: Array<OverlayControlData>)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.utils
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
|
||||||
|
object PreferenceUtil {
|
||||||
|
/**
|
||||||
|
* Retrieves a shared preference value and then deletes the value in storage.
|
||||||
|
* @param key Associated key for the value in this preferences instance
|
||||||
|
* @return Typed value associated with [key]. Null if no such key exists.
|
||||||
|
*/
|
||||||
|
inline fun <reified T> SharedPreferences.migratePreference(key: String): T? {
|
||||||
|
if (!this.contains(key)) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val value: Any = when (T::class) {
|
||||||
|
String::class -> this.getString(key, "")!!
|
||||||
|
|
||||||
|
Boolean::class -> this.getBoolean(key, false)
|
||||||
|
|
||||||
|
Int::class -> this.getInt(key, 0)
|
||||||
|
|
||||||
|
Float::class -> this.getFloat(key, 0f)
|
||||||
|
|
||||||
|
Long::class -> this.getLong(key, 0)
|
||||||
|
|
||||||
|
else -> throw IllegalStateException("Tried to migrate preference with invalid type!")
|
||||||
|
}
|
||||||
|
deletePreference(key)
|
||||||
|
return value as T
|
||||||
|
}
|
||||||
|
|
||||||
|
fun SharedPreferences.deletePreference(key: String) = this.edit().remove(key).apply()
|
||||||
|
}
|
|
@ -5,38 +5,38 @@ package org.yuzu.yuzu_emu.utils
|
||||||
|
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
|
import android.os.Build
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.core.view.WindowInsetsControllerCompat
|
import androidx.core.view.WindowInsetsControllerCompat
|
||||||
import androidx.preference.PreferenceManager
|
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
import org.yuzu.yuzu_emu.R
|
import org.yuzu.yuzu_emu.R
|
||||||
import org.yuzu.yuzu_emu.YuzuApplication
|
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||||
import org.yuzu.yuzu_emu.ui.main.ThemeProvider
|
import org.yuzu.yuzu_emu.ui.main.ThemeProvider
|
||||||
|
|
||||||
object ThemeHelper {
|
object ThemeHelper {
|
||||||
const val SYSTEM_BAR_ALPHA = 0.9f
|
const val SYSTEM_BAR_ALPHA = 0.9f
|
||||||
|
|
||||||
private const val DEFAULT = 0
|
|
||||||
private const val MATERIAL_YOU = 1
|
|
||||||
|
|
||||||
fun setTheme(activity: AppCompatActivity) {
|
fun setTheme(activity: AppCompatActivity) {
|
||||||
val preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
|
||||||
setThemeMode(activity)
|
setThemeMode(activity)
|
||||||
when (preferences.getInt(Settings.PREF_THEME, 0)) {
|
when (Theme.from(IntSetting.THEME.getInt())) {
|
||||||
DEFAULT -> activity.setTheme(R.style.Theme_Yuzu_Main)
|
Theme.Default -> activity.setTheme(R.style.Theme_Yuzu_Main)
|
||||||
MATERIAL_YOU -> activity.setTheme(R.style.Theme_Yuzu_Main_MaterialYou)
|
Theme.MaterialYou -> {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
activity.setTheme(R.style.Theme_Yuzu_Main_MaterialYou)
|
||||||
|
} else {
|
||||||
|
activity.setTheme(R.style.Theme_Yuzu_Main)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Using a specific night mode check because this could apply incorrectly when using the
|
// Using a specific night mode check because this could apply incorrectly when using the
|
||||||
// light app mode, dark system mode, and black backgrounds. Launching the settings activity
|
// light app mode, dark system mode, and black backgrounds. Launching the settings activity
|
||||||
// will then show light mode colors/navigation bars but with black backgrounds.
|
// will then show light mode colors/navigation bars but with black backgrounds.
|
||||||
if (preferences.getBoolean(Settings.PREF_BLACK_BACKGROUNDS, false) &&
|
if (BooleanSetting.BLACK_BACKGROUNDS.getBoolean() && isNightMode(activity)) {
|
||||||
isNightMode(activity)
|
|
||||||
) {
|
|
||||||
activity.setTheme(R.style.ThemeOverlay_Yuzu_Dark)
|
activity.setTheme(R.style.ThemeOverlay_Yuzu_Dark)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,8 +60,7 @@ object ThemeHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setThemeMode(activity: AppCompatActivity) {
|
fun setThemeMode(activity: AppCompatActivity) {
|
||||||
val themeMode = PreferenceManager.getDefaultSharedPreferences(activity.applicationContext)
|
val themeMode = IntSetting.THEME_MODE.getInt()
|
||||||
.getInt(Settings.PREF_THEME_MODE, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
|
||||||
activity.delegate.localNightMode = themeMode
|
activity.delegate.localNightMode = themeMode
|
||||||
val windowController = WindowCompat.getInsetsController(
|
val windowController = WindowCompat.getInsetsController(
|
||||||
activity.window,
|
activity.window,
|
||||||
|
@ -95,3 +94,12 @@ object ThemeHelper {
|
||||||
windowController.isAppearanceLightNavigationBars = false
|
windowController.isAppearanceLightNavigationBars = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class Theme(val int: Int) {
|
||||||
|
Default(0),
|
||||||
|
MaterialYou(1);
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun from(int: Int): Theme = entries.firstOrNull { it.int == int } ?: Default
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
#include "jni/id_cache.h"
|
||||||
|
|
||||||
std::string GetJString(JNIEnv* env, jstring jstr) {
|
std::string GetJString(JNIEnv* env, jstring jstr) {
|
||||||
if (!jstr) {
|
if (!jstr) {
|
||||||
|
@ -33,3 +34,11 @@ jstring ToJString(JNIEnv* env, std::string_view str) {
|
||||||
jstring ToJString(JNIEnv* env, std::u16string_view str) {
|
jstring ToJString(JNIEnv* env, std::u16string_view str) {
|
||||||
return ToJString(env, Common::UTF16ToUTF8(str));
|
return ToJString(env, Common::UTF16ToUTF8(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double GetJDouble(JNIEnv* env, jobject jdouble) {
|
||||||
|
return env->GetDoubleField(jdouble, IDCache::GetDoubleValueField());
|
||||||
|
}
|
||||||
|
|
||||||
|
jobject ToJDouble(JNIEnv* env, double value) {
|
||||||
|
return env->NewObject(IDCache::GetDoubleClass(), IDCache::GetDoubleConstructor(), value);
|
||||||
|
}
|
||||||
|
|
|
@ -10,3 +10,6 @@
|
||||||
std::string GetJString(JNIEnv* env, jstring jstr);
|
std::string GetJString(JNIEnv* env, jstring jstr);
|
||||||
jstring ToJString(JNIEnv* env, std::string_view str);
|
jstring ToJString(JNIEnv* env, std::string_view str);
|
||||||
jstring ToJString(JNIEnv* env, std::u16string_view str);
|
jstring ToJString(JNIEnv* env, std::u16string_view str);
|
||||||
|
|
||||||
|
double GetJDouble(JNIEnv* env, jobject jdouble);
|
||||||
|
jobject ToJDouble(JNIEnv* env, double value);
|
||||||
|
|
|
@ -35,6 +35,7 @@ void AndroidConfig::ReadAndroidValues() {
|
||||||
if (global) {
|
if (global) {
|
||||||
ReadAndroidUIValues();
|
ReadAndroidUIValues();
|
||||||
ReadUIValues();
|
ReadUIValues();
|
||||||
|
ReadOverlayValues();
|
||||||
}
|
}
|
||||||
ReadDriverValues();
|
ReadDriverValues();
|
||||||
}
|
}
|
||||||
|
@ -81,10 +82,42 @@ void AndroidConfig::ReadDriverValues() {
|
||||||
EndGroup();
|
EndGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AndroidConfig::ReadOverlayValues() {
|
||||||
|
BeginGroup(Settings::TranslateCategory(Settings::Category::Overlay));
|
||||||
|
|
||||||
|
ReadCategory(Settings::Category::Overlay);
|
||||||
|
|
||||||
|
AndroidSettings::values.overlay_control_data.clear();
|
||||||
|
const int control_data_size = BeginArray("control_data");
|
||||||
|
for (int i = 0; i < control_data_size; ++i) {
|
||||||
|
SetArrayIndex(i);
|
||||||
|
AndroidSettings::OverlayControlData control_data;
|
||||||
|
control_data.id = ReadStringSetting(std::string("id"));
|
||||||
|
control_data.enabled = ReadBooleanSetting(std::string("enabled"));
|
||||||
|
control_data.landscape_position.first =
|
||||||
|
ReadDoubleSetting(std::string("landscape\\x_position"));
|
||||||
|
control_data.landscape_position.second =
|
||||||
|
ReadDoubleSetting(std::string("landscape\\y_position"));
|
||||||
|
control_data.portrait_position.first =
|
||||||
|
ReadDoubleSetting(std::string("portrait\\x_position"));
|
||||||
|
control_data.portrait_position.second =
|
||||||
|
ReadDoubleSetting(std::string("portrait\\y_position"));
|
||||||
|
control_data.foldable_position.first =
|
||||||
|
ReadDoubleSetting(std::string("foldable\\x_position"));
|
||||||
|
control_data.foldable_position.second =
|
||||||
|
ReadDoubleSetting(std::string("foldable\\y_position"));
|
||||||
|
AndroidSettings::values.overlay_control_data.push_back(control_data);
|
||||||
|
}
|
||||||
|
EndArray();
|
||||||
|
|
||||||
|
EndGroup();
|
||||||
|
}
|
||||||
|
|
||||||
void AndroidConfig::SaveAndroidValues() {
|
void AndroidConfig::SaveAndroidValues() {
|
||||||
if (global) {
|
if (global) {
|
||||||
SaveAndroidUIValues();
|
SaveAndroidUIValues();
|
||||||
SaveUIValues();
|
SaveUIValues();
|
||||||
|
SaveOverlayValues();
|
||||||
}
|
}
|
||||||
SaveDriverValues();
|
SaveDriverValues();
|
||||||
|
|
||||||
|
@ -114,8 +147,9 @@ void AndroidConfig::SavePathValues() {
|
||||||
for (size_t i = 0; i < AndroidSettings::values.game_dirs.size(); ++i) {
|
for (size_t i = 0; i < AndroidSettings::values.game_dirs.size(); ++i) {
|
||||||
SetArrayIndex(i);
|
SetArrayIndex(i);
|
||||||
const auto& game_dir = AndroidSettings::values.game_dirs[i];
|
const auto& game_dir = AndroidSettings::values.game_dirs[i];
|
||||||
WriteSetting(std::string("path"), game_dir.path);
|
WriteStringSetting(std::string("path"), game_dir.path);
|
||||||
WriteSetting(std::string("deep_scan"), game_dir.deep_scan, std::make_optional(false));
|
WriteBooleanSetting(std::string("deep_scan"), game_dir.deep_scan,
|
||||||
|
std::make_optional(false));
|
||||||
}
|
}
|
||||||
EndArray();
|
EndArray();
|
||||||
|
|
||||||
|
@ -130,6 +164,35 @@ void AndroidConfig::SaveDriverValues() {
|
||||||
EndGroup();
|
EndGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AndroidConfig::SaveOverlayValues() {
|
||||||
|
BeginGroup(Settings::TranslateCategory(Settings::Category::Overlay));
|
||||||
|
|
||||||
|
WriteCategory(Settings::Category::Overlay);
|
||||||
|
|
||||||
|
BeginArray("control_data");
|
||||||
|
for (size_t i = 0; i < AndroidSettings::values.overlay_control_data.size(); ++i) {
|
||||||
|
SetArrayIndex(i);
|
||||||
|
const auto& control_data = AndroidSettings::values.overlay_control_data[i];
|
||||||
|
WriteStringSetting(std::string("id"), control_data.id);
|
||||||
|
WriteBooleanSetting(std::string("enabled"), control_data.enabled);
|
||||||
|
WriteDoubleSetting(std::string("landscape\\x_position"),
|
||||||
|
control_data.landscape_position.first);
|
||||||
|
WriteDoubleSetting(std::string("landscape\\y_position"),
|
||||||
|
control_data.landscape_position.second);
|
||||||
|
WriteDoubleSetting(std::string("portrait\\x_position"),
|
||||||
|
control_data.portrait_position.first);
|
||||||
|
WriteDoubleSetting(std::string("portrait\\y_position"),
|
||||||
|
control_data.portrait_position.second);
|
||||||
|
WriteDoubleSetting(std::string("foldable\\x_position"),
|
||||||
|
control_data.foldable_position.first);
|
||||||
|
WriteDoubleSetting(std::string("foldable\\y_position"),
|
||||||
|
control_data.foldable_position.second);
|
||||||
|
}
|
||||||
|
EndArray();
|
||||||
|
|
||||||
|
EndGroup();
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Settings::BasicSetting*>& AndroidConfig::FindRelevantList(Settings::Category category) {
|
std::vector<Settings::BasicSetting*>& AndroidConfig::FindRelevantList(Settings::Category category) {
|
||||||
auto& map = Settings::values.linkage.by_category;
|
auto& map = Settings::values.linkage.by_category;
|
||||||
if (map.contains(category)) {
|
if (map.contains(category)) {
|
||||||
|
|
|
@ -18,6 +18,7 @@ protected:
|
||||||
void ReadAndroidValues();
|
void ReadAndroidValues();
|
||||||
void ReadAndroidUIValues();
|
void ReadAndroidUIValues();
|
||||||
void ReadDriverValues();
|
void ReadDriverValues();
|
||||||
|
void ReadOverlayValues();
|
||||||
void ReadHidbusValues() override {}
|
void ReadHidbusValues() override {}
|
||||||
void ReadDebugControlValues() override {}
|
void ReadDebugControlValues() override {}
|
||||||
void ReadPathValues() override;
|
void ReadPathValues() override;
|
||||||
|
@ -30,6 +31,7 @@ protected:
|
||||||
void SaveAndroidValues();
|
void SaveAndroidValues();
|
||||||
void SaveAndroidUIValues();
|
void SaveAndroidUIValues();
|
||||||
void SaveDriverValues();
|
void SaveDriverValues();
|
||||||
|
void SaveOverlayValues();
|
||||||
void SaveHidbusValues() override {}
|
void SaveHidbusValues() override {}
|
||||||
void SaveDebugControlValues() override {}
|
void SaveDebugControlValues() override {}
|
||||||
void SavePathValues() override;
|
void SavePathValues() override;
|
||||||
|
|
|
@ -14,6 +14,14 @@ struct GameDir {
|
||||||
bool deep_scan = false;
|
bool deep_scan = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct OverlayControlData {
|
||||||
|
std::string id;
|
||||||
|
bool enabled;
|
||||||
|
std::pair<double, double> landscape_position;
|
||||||
|
std::pair<double, double> portrait_position;
|
||||||
|
std::pair<double, double> foldable_position;
|
||||||
|
};
|
||||||
|
|
||||||
struct Values {
|
struct Values {
|
||||||
Settings::Linkage linkage;
|
Settings::Linkage linkage;
|
||||||
|
|
||||||
|
@ -33,6 +41,28 @@ struct Values {
|
||||||
|
|
||||||
Settings::SwitchableSetting<std::string, false> driver_path{linkage, "", "driver_path",
|
Settings::SwitchableSetting<std::string, false> driver_path{linkage, "", "driver_path",
|
||||||
Settings::Category::GpuDriver};
|
Settings::Category::GpuDriver};
|
||||||
|
|
||||||
|
Settings::Setting<s32> theme{linkage, 0, "theme", Settings::Category::Android};
|
||||||
|
Settings::Setting<s32> theme_mode{linkage, -1, "theme_mode", Settings::Category::Android};
|
||||||
|
Settings::Setting<bool> black_backgrounds{linkage, false, "black_backgrounds",
|
||||||
|
Settings::Category::Android};
|
||||||
|
|
||||||
|
// Input/performance overlay settings
|
||||||
|
std::vector<OverlayControlData> overlay_control_data;
|
||||||
|
Settings::Setting<s32> overlay_scale{linkage, 50, "control_scale", Settings::Category::Overlay};
|
||||||
|
Settings::Setting<s32> overlay_opacity{linkage, 100, "control_opacity",
|
||||||
|
Settings::Category::Overlay};
|
||||||
|
|
||||||
|
Settings::Setting<bool> joystick_rel_center{linkage, true, "joystick_rel_center",
|
||||||
|
Settings::Category::Overlay};
|
||||||
|
Settings::Setting<bool> dpad_slide{linkage, true, "dpad_slide", Settings::Category::Overlay};
|
||||||
|
Settings::Setting<bool> haptic_feedback{linkage, true, "haptic_feedback",
|
||||||
|
Settings::Category::Overlay};
|
||||||
|
Settings::Setting<bool> show_performance_overlay{linkage, true, "show_performance_overlay",
|
||||||
|
Settings::Category::Overlay};
|
||||||
|
Settings::Setting<bool> show_input_overlay{linkage, true, "show_input_overlay",
|
||||||
|
Settings::Category::Overlay};
|
||||||
|
Settings::Setting<bool> touchscreen{linkage, true, "touchscreen", Settings::Category::Overlay};
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Values values;
|
extern Values values;
|
||||||
|
|
|
@ -35,6 +35,18 @@ static jmethodID s_pair_constructor;
|
||||||
static jfieldID s_pair_first_field;
|
static jfieldID s_pair_first_field;
|
||||||
static jfieldID s_pair_second_field;
|
static jfieldID s_pair_second_field;
|
||||||
|
|
||||||
|
static jclass s_overlay_control_data_class;
|
||||||
|
static jmethodID s_overlay_control_data_constructor;
|
||||||
|
static jfieldID s_overlay_control_data_id_field;
|
||||||
|
static jfieldID s_overlay_control_data_enabled_field;
|
||||||
|
static jfieldID s_overlay_control_data_landscape_position_field;
|
||||||
|
static jfieldID s_overlay_control_data_portrait_position_field;
|
||||||
|
static jfieldID s_overlay_control_data_foldable_position_field;
|
||||||
|
|
||||||
|
static jclass s_double_class;
|
||||||
|
static jmethodID s_double_constructor;
|
||||||
|
static jfieldID s_double_value_field;
|
||||||
|
|
||||||
static constexpr jint JNI_VERSION = JNI_VERSION_1_6;
|
static constexpr jint JNI_VERSION = JNI_VERSION_1_6;
|
||||||
|
|
||||||
namespace IDCache {
|
namespace IDCache {
|
||||||
|
@ -146,6 +158,46 @@ jfieldID GetPairSecondField() {
|
||||||
return s_pair_second_field;
|
return s_pair_second_field;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jclass GetOverlayControlDataClass() {
|
||||||
|
return s_overlay_control_data_class;
|
||||||
|
}
|
||||||
|
|
||||||
|
jmethodID GetOverlayControlDataConstructor() {
|
||||||
|
return s_overlay_control_data_constructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
jfieldID GetOverlayControlDataIdField() {
|
||||||
|
return s_overlay_control_data_id_field;
|
||||||
|
}
|
||||||
|
|
||||||
|
jfieldID GetOverlayControlDataEnabledField() {
|
||||||
|
return s_overlay_control_data_enabled_field;
|
||||||
|
}
|
||||||
|
|
||||||
|
jfieldID GetOverlayControlDataLandscapePositionField() {
|
||||||
|
return s_overlay_control_data_landscape_position_field;
|
||||||
|
}
|
||||||
|
|
||||||
|
jfieldID GetOverlayControlDataPortraitPositionField() {
|
||||||
|
return s_overlay_control_data_portrait_position_field;
|
||||||
|
}
|
||||||
|
|
||||||
|
jfieldID GetOverlayControlDataFoldablePositionField() {
|
||||||
|
return s_overlay_control_data_foldable_position_field;
|
||||||
|
}
|
||||||
|
|
||||||
|
jclass GetDoubleClass() {
|
||||||
|
return s_double_class;
|
||||||
|
}
|
||||||
|
|
||||||
|
jmethodID GetDoubleConstructor() {
|
||||||
|
return s_double_constructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
jfieldID GetDoubleValueField() {
|
||||||
|
return s_double_value_field;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace IDCache
|
} // namespace IDCache
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -207,6 +259,31 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||||
s_pair_second_field = env->GetFieldID(pair_class, "second", "Ljava/lang/Object;");
|
s_pair_second_field = env->GetFieldID(pair_class, "second", "Ljava/lang/Object;");
|
||||||
env->DeleteLocalRef(pair_class);
|
env->DeleteLocalRef(pair_class);
|
||||||
|
|
||||||
|
const jclass overlay_control_data_class =
|
||||||
|
env->FindClass("org/yuzu/yuzu_emu/overlay/model/OverlayControlData");
|
||||||
|
s_overlay_control_data_class =
|
||||||
|
reinterpret_cast<jclass>(env->NewGlobalRef(overlay_control_data_class));
|
||||||
|
s_overlay_control_data_constructor =
|
||||||
|
env->GetMethodID(overlay_control_data_class, "<init>",
|
||||||
|
"(Ljava/lang/String;ZLkotlin/Pair;Lkotlin/Pair;Lkotlin/Pair;)V");
|
||||||
|
s_overlay_control_data_id_field =
|
||||||
|
env->GetFieldID(overlay_control_data_class, "id", "Ljava/lang/String;");
|
||||||
|
s_overlay_control_data_enabled_field =
|
||||||
|
env->GetFieldID(overlay_control_data_class, "enabled", "Z");
|
||||||
|
s_overlay_control_data_landscape_position_field =
|
||||||
|
env->GetFieldID(overlay_control_data_class, "landscapePosition", "Lkotlin/Pair;");
|
||||||
|
s_overlay_control_data_portrait_position_field =
|
||||||
|
env->GetFieldID(overlay_control_data_class, "portraitPosition", "Lkotlin/Pair;");
|
||||||
|
s_overlay_control_data_foldable_position_field =
|
||||||
|
env->GetFieldID(overlay_control_data_class, "foldablePosition", "Lkotlin/Pair;");
|
||||||
|
env->DeleteLocalRef(overlay_control_data_class);
|
||||||
|
|
||||||
|
const jclass double_class = env->FindClass("java/lang/Double");
|
||||||
|
s_double_class = reinterpret_cast<jclass>(env->NewGlobalRef(double_class));
|
||||||
|
s_double_constructor = env->GetMethodID(double_class, "<init>", "(D)V");
|
||||||
|
s_double_value_field = env->GetFieldID(double_class, "value", "D");
|
||||||
|
env->DeleteLocalRef(double_class);
|
||||||
|
|
||||||
// Initialize Android Storage
|
// Initialize Android Storage
|
||||||
Common::FS::Android::RegisterCallbacks(env, s_native_library_class);
|
Common::FS::Android::RegisterCallbacks(env, s_native_library_class);
|
||||||
|
|
||||||
|
@ -231,6 +308,8 @@ void JNI_OnUnload(JavaVM* vm, void* reserved) {
|
||||||
env->DeleteGlobalRef(s_game_class);
|
env->DeleteGlobalRef(s_game_class);
|
||||||
env->DeleteGlobalRef(s_string_class);
|
env->DeleteGlobalRef(s_string_class);
|
||||||
env->DeleteGlobalRef(s_pair_class);
|
env->DeleteGlobalRef(s_pair_class);
|
||||||
|
env->DeleteGlobalRef(s_overlay_control_data_class);
|
||||||
|
env->DeleteGlobalRef(s_double_class);
|
||||||
|
|
||||||
// UnInitialize applets
|
// UnInitialize applets
|
||||||
SoftwareKeyboard::CleanupJNI(env);
|
SoftwareKeyboard::CleanupJNI(env);
|
||||||
|
|
|
@ -35,4 +35,16 @@ jmethodID GetPairConstructor();
|
||||||
jfieldID GetPairFirstField();
|
jfieldID GetPairFirstField();
|
||||||
jfieldID GetPairSecondField();
|
jfieldID GetPairSecondField();
|
||||||
|
|
||||||
|
jclass GetOverlayControlDataClass();
|
||||||
|
jmethodID GetOverlayControlDataConstructor();
|
||||||
|
jfieldID GetOverlayControlDataIdField();
|
||||||
|
jfieldID GetOverlayControlDataEnabledField();
|
||||||
|
jfieldID GetOverlayControlDataLandscapePositionField();
|
||||||
|
jfieldID GetOverlayControlDataPortraitPositionField();
|
||||||
|
jfieldID GetOverlayControlDataFoldablePositionField();
|
||||||
|
|
||||||
|
jclass GetDoubleClass();
|
||||||
|
jmethodID GetDoubleConstructor();
|
||||||
|
jfieldID GetDoubleValueField();
|
||||||
|
|
||||||
} // namespace IDCache
|
} // namespace IDCache
|
||||||
|
|
|
@ -344,4 +344,74 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setDisabledAddons(JNIEnv* env, j
|
||||||
Settings::values.disabled_addons[program_id] = disabled_addons;
|
Settings::values.disabled_addons[program_id] = disabled_addons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jobjectArray Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getOverlayControlData(JNIEnv* env,
|
||||||
|
jobject obj) {
|
||||||
|
jobjectArray joverlayControlDataArray =
|
||||||
|
env->NewObjectArray(AndroidSettings::values.overlay_control_data.size(),
|
||||||
|
IDCache::GetOverlayControlDataClass(), nullptr);
|
||||||
|
for (size_t i = 0; i < AndroidSettings::values.overlay_control_data.size(); ++i) {
|
||||||
|
const auto& control_data = AndroidSettings::values.overlay_control_data[i];
|
||||||
|
jobject jlandscapePosition =
|
||||||
|
env->NewObject(IDCache::GetPairClass(), IDCache::GetPairConstructor(),
|
||||||
|
ToJDouble(env, control_data.landscape_position.first),
|
||||||
|
ToJDouble(env, control_data.landscape_position.second));
|
||||||
|
jobject jportraitPosition =
|
||||||
|
env->NewObject(IDCache::GetPairClass(), IDCache::GetPairConstructor(),
|
||||||
|
ToJDouble(env, control_data.portrait_position.first),
|
||||||
|
ToJDouble(env, control_data.portrait_position.second));
|
||||||
|
jobject jfoldablePosition =
|
||||||
|
env->NewObject(IDCache::GetPairClass(), IDCache::GetPairConstructor(),
|
||||||
|
ToJDouble(env, control_data.foldable_position.first),
|
||||||
|
ToJDouble(env, control_data.foldable_position.second));
|
||||||
|
|
||||||
|
jobject jcontrolData = env->NewObject(
|
||||||
|
IDCache::GetOverlayControlDataClass(), IDCache::GetOverlayControlDataConstructor(),
|
||||||
|
ToJString(env, control_data.id), control_data.enabled, jlandscapePosition,
|
||||||
|
jportraitPosition, jfoldablePosition);
|
||||||
|
env->SetObjectArrayElement(joverlayControlDataArray, i, jcontrolData);
|
||||||
|
}
|
||||||
|
return joverlayControlDataArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setOverlayControlData(
|
||||||
|
JNIEnv* env, jobject obj, jobjectArray joverlayControlDataArray) {
|
||||||
|
AndroidSettings::values.overlay_control_data.clear();
|
||||||
|
int size = env->GetArrayLength(joverlayControlDataArray);
|
||||||
|
|
||||||
|
if (size == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
jobject joverlayControlData = env->GetObjectArrayElement(joverlayControlDataArray, i);
|
||||||
|
jstring jidString = static_cast<jstring>(
|
||||||
|
env->GetObjectField(joverlayControlData, IDCache::GetOverlayControlDataIdField()));
|
||||||
|
bool enabled = static_cast<bool>(env->GetBooleanField(
|
||||||
|
joverlayControlData, IDCache::GetOverlayControlDataEnabledField()));
|
||||||
|
|
||||||
|
jobject jlandscapePosition = env->GetObjectField(
|
||||||
|
joverlayControlData, IDCache::GetOverlayControlDataLandscapePositionField());
|
||||||
|
std::pair<double, double> landscape_position = std::make_pair(
|
||||||
|
GetJDouble(env, env->GetObjectField(jlandscapePosition, IDCache::GetPairFirstField())),
|
||||||
|
GetJDouble(env,
|
||||||
|
env->GetObjectField(jlandscapePosition, IDCache::GetPairSecondField())));
|
||||||
|
|
||||||
|
jobject jportraitPosition = env->GetObjectField(
|
||||||
|
joverlayControlData, IDCache::GetOverlayControlDataPortraitPositionField());
|
||||||
|
std::pair<double, double> portrait_position = std::make_pair(
|
||||||
|
GetJDouble(env, env->GetObjectField(jportraitPosition, IDCache::GetPairFirstField())),
|
||||||
|
GetJDouble(env, env->GetObjectField(jportraitPosition, IDCache::GetPairSecondField())));
|
||||||
|
|
||||||
|
jobject jfoldablePosition = env->GetObjectField(
|
||||||
|
joverlayControlData, IDCache::GetOverlayControlDataFoldablePositionField());
|
||||||
|
std::pair<double, double> foldable_position = std::make_pair(
|
||||||
|
GetJDouble(env, env->GetObjectField(jfoldablePosition, IDCache::GetPairFirstField())),
|
||||||
|
GetJDouble(env, env->GetObjectField(jfoldablePosition, IDCache::GetPairSecondField())));
|
||||||
|
|
||||||
|
AndroidSettings::values.overlay_control_data.push_back(AndroidSettings::OverlayControlData{
|
||||||
|
GetJString(env, jidString), enabled, landscape_position, portrait_position,
|
||||||
|
foldable_position});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
|
@ -38,6 +38,11 @@
|
||||||
android:title="@string/emulation_haptics"
|
android:title="@string/emulation_haptics"
|
||||||
android:checkable="true" />
|
android:checkable="true" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_touchscreen"
|
||||||
|
android:title="@string/touchscreen"
|
||||||
|
android:checkable="true" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/menu_reset_overlay"
|
android:id="@+id/menu_reset_overlay"
|
||||||
android:title="@string/emulation_touch_overlay_reset" />
|
android:title="@string/emulation_touch_overlay_reset" />
|
||||||
|
|
|
@ -212,19 +212,19 @@
|
||||||
<item>B</item>
|
<item>B</item>
|
||||||
<item>X</item>
|
<item>X</item>
|
||||||
<item>Y</item>
|
<item>Y</item>
|
||||||
|
<item>+</item>
|
||||||
|
<item>-</item>
|
||||||
|
<item>@string/gamepad_home</item>
|
||||||
|
<item>@string/gamepad_screenshot</item>
|
||||||
<item>L</item>
|
<item>L</item>
|
||||||
<item>R</item>
|
<item>R</item>
|
||||||
<item>ZL</item>
|
<item>ZL</item>
|
||||||
<item>ZR</item>
|
<item>ZR</item>
|
||||||
<item>+</item>
|
|
||||||
<item>-</item>
|
|
||||||
<item>@string/gamepad_d_pad</item>
|
|
||||||
<item>@string/gamepad_left_stick</item>
|
<item>@string/gamepad_left_stick</item>
|
||||||
<item>@string/gamepad_right_stick</item>
|
<item>@string/gamepad_right_stick</item>
|
||||||
<item>L3</item>
|
<item>L3</item>
|
||||||
<item>R3</item>
|
<item>R3</item>
|
||||||
<item>@string/gamepad_home</item>
|
<item>@string/gamepad_d_pad</item>
|
||||||
<item>@string/gamepad_screenshot</item>
|
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="themeEntries">
|
<string-array name="themeEntries">
|
||||||
|
|
|
@ -3,111 +3,111 @@
|
||||||
<integer name="grid_columns">1</integer>
|
<integer name="grid_columns">1</integer>
|
||||||
|
|
||||||
<!-- Default SWITCH landscape layout -->
|
<!-- Default SWITCH landscape layout -->
|
||||||
<integer name="SWITCH_BUTTON_A_X">760</integer>
|
<integer name="BUTTON_A_X">760</integer>
|
||||||
<integer name="SWITCH_BUTTON_A_Y">790</integer>
|
<integer name="BUTTON_A_Y">790</integer>
|
||||||
<integer name="SWITCH_BUTTON_B_X">710</integer>
|
<integer name="BUTTON_B_X">710</integer>
|
||||||
<integer name="SWITCH_BUTTON_B_Y">900</integer>
|
<integer name="BUTTON_B_Y">900</integer>
|
||||||
<integer name="SWITCH_BUTTON_X_X">710</integer>
|
<integer name="BUTTON_X_X">710</integer>
|
||||||
<integer name="SWITCH_BUTTON_X_Y">680</integer>
|
<integer name="BUTTON_X_Y">680</integer>
|
||||||
<integer name="SWITCH_BUTTON_Y_X">660</integer>
|
<integer name="BUTTON_Y_X">660</integer>
|
||||||
<integer name="SWITCH_BUTTON_Y_Y">790</integer>
|
<integer name="BUTTON_Y_Y">790</integer>
|
||||||
<integer name="SWITCH_STICK_L_X">100</integer>
|
<integer name="BUTTON_PLUS_X">540</integer>
|
||||||
<integer name="SWITCH_STICK_L_Y">670</integer>
|
<integer name="BUTTON_PLUS_Y">950</integer>
|
||||||
<integer name="SWITCH_STICK_R_X">900</integer>
|
<integer name="BUTTON_MINUS_X">460</integer>
|
||||||
<integer name="SWITCH_STICK_R_Y">670</integer>
|
<integer name="BUTTON_MINUS_Y">950</integer>
|
||||||
<integer name="SWITCH_TRIGGER_L_X">70</integer>
|
<integer name="BUTTON_HOME_X">600</integer>
|
||||||
<integer name="SWITCH_TRIGGER_L_Y">220</integer>
|
<integer name="BUTTON_HOME_Y">950</integer>
|
||||||
<integer name="SWITCH_TRIGGER_R_X">930</integer>
|
<integer name="BUTTON_CAPTURE_X">400</integer>
|
||||||
<integer name="SWITCH_TRIGGER_R_Y">220</integer>
|
<integer name="BUTTON_CAPTURE_Y">950</integer>
|
||||||
<integer name="SWITCH_TRIGGER_ZL_X">70</integer>
|
<integer name="BUTTON_L_X">70</integer>
|
||||||
<integer name="SWITCH_TRIGGER_ZL_Y">90</integer>
|
<integer name="BUTTON_L_Y">220</integer>
|
||||||
<integer name="SWITCH_TRIGGER_ZR_X">930</integer>
|
<integer name="BUTTON_R_X">930</integer>
|
||||||
<integer name="SWITCH_TRIGGER_ZR_Y">90</integer>
|
<integer name="BUTTON_R_Y">220</integer>
|
||||||
<integer name="SWITCH_BUTTON_MINUS_X">460</integer>
|
<integer name="BUTTON_ZL_X">70</integer>
|
||||||
<integer name="SWITCH_BUTTON_MINUS_Y">950</integer>
|
<integer name="BUTTON_ZL_Y">90</integer>
|
||||||
<integer name="SWITCH_BUTTON_PLUS_X">540</integer>
|
<integer name="BUTTON_ZR_X">930</integer>
|
||||||
<integer name="SWITCH_BUTTON_PLUS_Y">950</integer>
|
<integer name="BUTTON_ZR_Y">90</integer>
|
||||||
<integer name="SWITCH_BUTTON_HOME_X">600</integer>
|
<integer name="BUTTON_STICK_L_X">870</integer>
|
||||||
<integer name="SWITCH_BUTTON_HOME_Y">950</integer>
|
<integer name="BUTTON_STICK_L_Y">400</integer>
|
||||||
<integer name="SWITCH_BUTTON_CAPTURE_X">400</integer>
|
<integer name="BUTTON_STICK_R_X">960</integer>
|
||||||
<integer name="SWITCH_BUTTON_CAPTURE_Y">950</integer>
|
<integer name="BUTTON_STICK_R_Y">430</integer>
|
||||||
<integer name="SWITCH_BUTTON_DPAD_X">260</integer>
|
<integer name="STICK_L_X">100</integer>
|
||||||
<integer name="SWITCH_BUTTON_DPAD_Y">790</integer>
|
<integer name="STICK_L_Y">670</integer>
|
||||||
<integer name="SWITCH_BUTTON_STICK_L_X">870</integer>
|
<integer name="STICK_R_X">900</integer>
|
||||||
<integer name="SWITCH_BUTTON_STICK_L_Y">400</integer>
|
<integer name="STICK_R_Y">670</integer>
|
||||||
<integer name="SWITCH_BUTTON_STICK_R_X">960</integer>
|
<integer name="COMBINED_DPAD_X">260</integer>
|
||||||
<integer name="SWITCH_BUTTON_STICK_R_Y">430</integer>
|
<integer name="COMBINED_DPAD_Y">790</integer>
|
||||||
|
|
||||||
<!-- Default SWITCH portrait layout -->
|
<!-- Default SWITCH portrait layout -->
|
||||||
<integer name="SWITCH_BUTTON_A_X_PORTRAIT">840</integer>
|
<integer name="BUTTON_A_X_PORTRAIT">840</integer>
|
||||||
<integer name="SWITCH_BUTTON_A_Y_PORTRAIT">840</integer>
|
<integer name="BUTTON_A_Y_PORTRAIT">840</integer>
|
||||||
<integer name="SWITCH_BUTTON_B_X_PORTRAIT">740</integer>
|
<integer name="BUTTON_B_X_PORTRAIT">740</integer>
|
||||||
<integer name="SWITCH_BUTTON_B_Y_PORTRAIT">880</integer>
|
<integer name="BUTTON_B_Y_PORTRAIT">880</integer>
|
||||||
<integer name="SWITCH_BUTTON_X_X_PORTRAIT">740</integer>
|
<integer name="BUTTON_X_X_PORTRAIT">740</integer>
|
||||||
<integer name="SWITCH_BUTTON_X_Y_PORTRAIT">800</integer>
|
<integer name="BUTTON_X_Y_PORTRAIT">800</integer>
|
||||||
<integer name="SWITCH_BUTTON_Y_X_PORTRAIT">640</integer>
|
<integer name="BUTTON_Y_X_PORTRAIT">640</integer>
|
||||||
<integer name="SWITCH_BUTTON_Y_Y_PORTRAIT">840</integer>
|
<integer name="BUTTON_Y_Y_PORTRAIT">840</integer>
|
||||||
<integer name="SWITCH_STICK_L_X_PORTRAIT">180</integer>
|
<integer name="BUTTON_PLUS_Y_PORTRAIT">950</integer>
|
||||||
<integer name="SWITCH_STICK_L_Y_PORTRAIT">660</integer>
|
<integer name="BUTTON_MINUS_X_PORTRAIT">440</integer>
|
||||||
<integer name="SWITCH_STICK_R_X_PORTRAIT">820</integer>
|
<integer name="BUTTON_MINUS_Y_PORTRAIT">950</integer>
|
||||||
<integer name="SWITCH_STICK_R_Y_PORTRAIT">660</integer>
|
<integer name="BUTTON_HOME_X_PORTRAIT">680</integer>
|
||||||
<integer name="SWITCH_TRIGGER_L_X_PORTRAIT">140</integer>
|
<integer name="BUTTON_HOME_Y_PORTRAIT">950</integer>
|
||||||
<integer name="SWITCH_TRIGGER_L_Y_PORTRAIT">260</integer>
|
<integer name="BUTTON_CAPTURE_X_PORTRAIT">320</integer>
|
||||||
<integer name="SWITCH_TRIGGER_R_X_PORTRAIT">860</integer>
|
<integer name="BUTTON_CAPTURE_Y_PORTRAIT">950</integer>
|
||||||
<integer name="SWITCH_TRIGGER_R_Y_PORTRAIT">260</integer>
|
<integer name="BUTTON_L_X_PORTRAIT">140</integer>
|
||||||
<integer name="SWITCH_TRIGGER_ZL_X_PORTRAIT">140</integer>
|
<integer name="BUTTON_L_Y_PORTRAIT">260</integer>
|
||||||
<integer name="SWITCH_TRIGGER_ZL_Y_PORTRAIT">200</integer>
|
<integer name="BUTTON_R_X_PORTRAIT">860</integer>
|
||||||
<integer name="SWITCH_TRIGGER_ZR_X_PORTRAIT">860</integer>
|
<integer name="BUTTON_R_Y_PORTRAIT">260</integer>
|
||||||
<integer name="SWITCH_TRIGGER_ZR_Y_PORTRAIT">200</integer>
|
<integer name="BUTTON_ZL_X_PORTRAIT">140</integer>
|
||||||
<integer name="SWITCH_BUTTON_MINUS_X_PORTRAIT">440</integer>
|
<integer name="BUTTON_ZL_Y_PORTRAIT">200</integer>
|
||||||
<integer name="SWITCH_BUTTON_MINUS_Y_PORTRAIT">950</integer>
|
<integer name="BUTTON_ZR_X_PORTRAIT">860</integer>
|
||||||
<integer name="SWITCH_BUTTON_PLUS_X_PORTRAIT">560</integer>
|
<integer name="BUTTON_ZR_Y_PORTRAIT">200</integer>
|
||||||
<integer name="SWITCH_BUTTON_PLUS_Y_PORTRAIT">950</integer>
|
<integer name="BUTTON_PLUS_X_PORTRAIT">560</integer>
|
||||||
<integer name="SWITCH_BUTTON_HOME_X_PORTRAIT">680</integer>
|
<integer name="BUTTON_STICK_L_X_PORTRAIT">730</integer>
|
||||||
<integer name="SWITCH_BUTTON_HOME_Y_PORTRAIT">950</integer>
|
<integer name="BUTTON_STICK_L_Y_PORTRAIT">510</integer>
|
||||||
<integer name="SWITCH_BUTTON_CAPTURE_X_PORTRAIT">320</integer>
|
<integer name="BUTTON_STICK_R_X_PORTRAIT">900</integer>
|
||||||
<integer name="SWITCH_BUTTON_CAPTURE_Y_PORTRAIT">950</integer>
|
<integer name="BUTTON_STICK_R_Y_PORTRAIT">540</integer>
|
||||||
<integer name="SWITCH_BUTTON_DPAD_X_PORTRAIT">240</integer>
|
<integer name="STICK_L_X_PORTRAIT">180</integer>
|
||||||
<integer name="SWITCH_BUTTON_DPAD_Y_PORTRAIT">840</integer>
|
<integer name="STICK_L_Y_PORTRAIT">660</integer>
|
||||||
<integer name="SWITCH_BUTTON_STICK_L_X_PORTRAIT">730</integer>
|
<integer name="STICK_R_X_PORTRAIT">820</integer>
|
||||||
<integer name="SWITCH_BUTTON_STICK_L_Y_PORTRAIT">510</integer>
|
<integer name="STICK_R_Y_PORTRAIT">660</integer>
|
||||||
<integer name="SWITCH_BUTTON_STICK_R_X_PORTRAIT">900</integer>
|
<integer name="COMBINED_DPAD_X_PORTRAIT">240</integer>
|
||||||
<integer name="SWITCH_BUTTON_STICK_R_Y_PORTRAIT">540</integer>
|
<integer name="COMBINED_DPAD_Y_PORTRAIT">840</integer>
|
||||||
|
|
||||||
<!-- Default SWITCH foldable layout -->
|
<!-- Default SWITCH foldable layout -->
|
||||||
<integer name="SWITCH_BUTTON_A_X_FOLDABLE">840</integer>
|
<integer name="BUTTON_A_X_FOLDABLE">840</integer>
|
||||||
<integer name="SWITCH_BUTTON_A_Y_FOLDABLE">390</integer>
|
<integer name="BUTTON_A_Y_FOLDABLE">390</integer>
|
||||||
<integer name="SWITCH_BUTTON_B_X_FOLDABLE">740</integer>
|
<integer name="BUTTON_B_X_FOLDABLE">740</integer>
|
||||||
<integer name="SWITCH_BUTTON_B_Y_FOLDABLE">430</integer>
|
<integer name="BUTTON_B_Y_FOLDABLE">430</integer>
|
||||||
<integer name="SWITCH_BUTTON_X_X_FOLDABLE">740</integer>
|
<integer name="BUTTON_X_X_FOLDABLE">740</integer>
|
||||||
<integer name="SWITCH_BUTTON_X_Y_FOLDABLE">350</integer>
|
<integer name="BUTTON_X_Y_FOLDABLE">350</integer>
|
||||||
<integer name="SWITCH_BUTTON_Y_X_FOLDABLE">640</integer>
|
<integer name="BUTTON_Y_X_FOLDABLE">640</integer>
|
||||||
<integer name="SWITCH_BUTTON_Y_Y_FOLDABLE">390</integer>
|
<integer name="BUTTON_Y_Y_FOLDABLE">390</integer>
|
||||||
<integer name="SWITCH_STICK_L_X_FOLDABLE">180</integer>
|
<integer name="BUTTON_PLUS_X_FOLDABLE">560</integer>
|
||||||
<integer name="SWITCH_STICK_L_Y_FOLDABLE">250</integer>
|
<integer name="BUTTON_PLUS_Y_FOLDABLE">470</integer>
|
||||||
<integer name="SWITCH_STICK_R_X_FOLDABLE">820</integer>
|
<integer name="BUTTON_MINUS_X_FOLDABLE">440</integer>
|
||||||
<integer name="SWITCH_STICK_R_Y_FOLDABLE">250</integer>
|
<integer name="BUTTON_MINUS_Y_FOLDABLE">470</integer>
|
||||||
<integer name="SWITCH_TRIGGER_L_X_FOLDABLE">140</integer>
|
<integer name="BUTTON_HOME_X_FOLDABLE">680</integer>
|
||||||
<integer name="SWITCH_TRIGGER_L_Y_FOLDABLE">130</integer>
|
<integer name="BUTTON_HOME_Y_FOLDABLE">470</integer>
|
||||||
<integer name="SWITCH_TRIGGER_R_X_FOLDABLE">860</integer>
|
<integer name="BUTTON_CAPTURE_X_FOLDABLE">320</integer>
|
||||||
<integer name="SWITCH_TRIGGER_R_Y_FOLDABLE">130</integer>
|
<integer name="BUTTON_CAPTURE_Y_FOLDABLE">470</integer>
|
||||||
<integer name="SWITCH_TRIGGER_ZL_X_FOLDABLE">140</integer>
|
<integer name="BUTTON_L_X_FOLDABLE">140</integer>
|
||||||
<integer name="SWITCH_TRIGGER_ZL_Y_FOLDABLE">70</integer>
|
<integer name="BUTTON_L_Y_FOLDABLE">130</integer>
|
||||||
<integer name="SWITCH_TRIGGER_ZR_X_FOLDABLE">860</integer>
|
<integer name="BUTTON_R_X_FOLDABLE">860</integer>
|
||||||
<integer name="SWITCH_TRIGGER_ZR_Y_FOLDABLE">70</integer>
|
<integer name="BUTTON_R_Y_FOLDABLE">130</integer>
|
||||||
<integer name="SWITCH_BUTTON_MINUS_X_FOLDABLE">440</integer>
|
<integer name="BUTTON_ZL_X_FOLDABLE">140</integer>
|
||||||
<integer name="SWITCH_BUTTON_MINUS_Y_FOLDABLE">470</integer>
|
<integer name="BUTTON_ZL_Y_FOLDABLE">70</integer>
|
||||||
<integer name="SWITCH_BUTTON_PLUS_X_FOLDABLE">560</integer>
|
<integer name="BUTTON_ZR_X_FOLDABLE">860</integer>
|
||||||
<integer name="SWITCH_BUTTON_PLUS_Y_FOLDABLE">470</integer>
|
<integer name="BUTTON_ZR_Y_FOLDABLE">70</integer>
|
||||||
<integer name="SWITCH_BUTTON_HOME_X_FOLDABLE">680</integer>
|
<integer name="BUTTON_STICK_L_X_FOLDABLE">550</integer>
|
||||||
<integer name="SWITCH_BUTTON_HOME_Y_FOLDABLE">470</integer>
|
<integer name="BUTTON_STICK_L_Y_FOLDABLE">210</integer>
|
||||||
<integer name="SWITCH_BUTTON_CAPTURE_X_FOLDABLE">320</integer>
|
<integer name="BUTTON_STICK_R_X_FOLDABLE">550</integer>
|
||||||
<integer name="SWITCH_BUTTON_CAPTURE_Y_FOLDABLE">470</integer>
|
<integer name="BUTTON_STICK_R_Y_FOLDABLE">280</integer>
|
||||||
<integer name="SWITCH_BUTTON_DPAD_X_FOLDABLE">240</integer>
|
<integer name="STICK_L_X_FOLDABLE">180</integer>
|
||||||
<integer name="SWITCH_BUTTON_DPAD_Y_FOLDABLE">390</integer>
|
<integer name="STICK_L_Y_FOLDABLE">250</integer>
|
||||||
<integer name="SWITCH_BUTTON_STICK_L_X_FOLDABLE">550</integer>
|
<integer name="STICK_R_X_FOLDABLE">820</integer>
|
||||||
<integer name="SWITCH_BUTTON_STICK_L_Y_FOLDABLE">210</integer>
|
<integer name="STICK_R_Y_FOLDABLE">250</integer>
|
||||||
<integer name="SWITCH_BUTTON_STICK_R_X_FOLDABLE">550</integer>
|
<integer name="COMBINED_DPAD_X_FOLDABLE">240</integer>
|
||||||
<integer name="SWITCH_BUTTON_STICK_R_Y_FOLDABLE">280</integer>
|
<integer name="COMBINED_DPAD_Y_FOLDABLE">390</integer>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -366,6 +366,7 @@
|
||||||
<string name="emulation_pause">Pause emulation</string>
|
<string name="emulation_pause">Pause emulation</string>
|
||||||
<string name="emulation_unpause">Unpause emulation</string>
|
<string name="emulation_unpause">Unpause emulation</string>
|
||||||
<string name="emulation_input_overlay">Overlay options</string>
|
<string name="emulation_input_overlay">Overlay options</string>
|
||||||
|
<string name="touchscreen">Touchscreen</string>
|
||||||
|
|
||||||
<string name="load_settings">Loading settings…</string>
|
<string name="load_settings">Loading settings…</string>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
plugins {
|
plugins {
|
||||||
id("com.android.application") version "8.1.2" apply false
|
id("com.android.application") version "8.1.2" apply false
|
||||||
id("com.android.library") version "8.1.2" apply false
|
id("com.android.library") version "8.1.2" apply false
|
||||||
id("org.jetbrains.kotlin.android") version "1.8.21" apply false
|
id("org.jetbrains.kotlin.android") version "1.9.20" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register("clean").configure {
|
tasks.register("clean").configure {
|
||||||
|
|
|
@ -199,6 +199,8 @@ const char* TranslateCategory(Category category) {
|
||||||
case Category::CpuDebug:
|
case Category::CpuDebug:
|
||||||
case Category::CpuUnsafe:
|
case Category::CpuUnsafe:
|
||||||
return "Cpu";
|
return "Cpu";
|
||||||
|
case Category::Overlay:
|
||||||
|
return "Overlay";
|
||||||
case Category::Renderer:
|
case Category::Renderer:
|
||||||
case Category::RendererAdvanced:
|
case Category::RendererAdvanced:
|
||||||
case Category::RendererDebug:
|
case Category::RendererDebug:
|
||||||
|
|
|
@ -18,6 +18,7 @@ enum class Category : u32 {
|
||||||
Cpu,
|
Cpu,
|
||||||
CpuDebug,
|
CpuDebug,
|
||||||
CpuUnsafe,
|
CpuUnsafe,
|
||||||
|
Overlay,
|
||||||
Renderer,
|
Renderer,
|
||||||
RendererAdvanced,
|
RendererAdvanced,
|
||||||
RendererDebug,
|
RendererDebug,
|
||||||
|
|
|
@ -553,17 +553,26 @@ add_library(core STATIC
|
||||||
hle/service/hid/controllers/types/keyboard_types.h
|
hle/service/hid/controllers/types/keyboard_types.h
|
||||||
hle/service/hid/controllers/types/mouse_types.h
|
hle/service/hid/controllers/types/mouse_types.h
|
||||||
hle/service/hid/controllers/types/npad_types.h
|
hle/service/hid/controllers/types/npad_types.h
|
||||||
|
hle/service/hid/controllers/types/shared_memory_format.h
|
||||||
hle/service/hid/controllers/types/touch_types.h
|
hle/service/hid/controllers/types/touch_types.h
|
||||||
hle/service/hid/controllers/applet_resource.cpp
|
hle/service/hid/controllers/applet_resource.cpp
|
||||||
hle/service/hid/controllers/applet_resource.h
|
hle/service/hid/controllers/applet_resource.h
|
||||||
|
hle/service/hid/controllers/capture_button.cpp
|
||||||
|
hle/service/hid/controllers/capture_button.h
|
||||||
hle/service/hid/controllers/console_six_axis.cpp
|
hle/service/hid/controllers/console_six_axis.cpp
|
||||||
hle/service/hid/controllers/console_six_axis.h
|
hle/service/hid/controllers/console_six_axis.h
|
||||||
hle/service/hid/controllers/controller_base.cpp
|
hle/service/hid/controllers/controller_base.cpp
|
||||||
hle/service/hid/controllers/controller_base.h
|
hle/service/hid/controllers/controller_base.h
|
||||||
|
hle/service/hid/controllers/debug_mouse.cpp
|
||||||
|
hle/service/hid/controllers/debug_mouse.h
|
||||||
hle/service/hid/controllers/debug_pad.cpp
|
hle/service/hid/controllers/debug_pad.cpp
|
||||||
hle/service/hid/controllers/debug_pad.h
|
hle/service/hid/controllers/debug_pad.h
|
||||||
|
hle/service/hid/controllers/digitizer.cpp
|
||||||
|
hle/service/hid/controllers/digitizer.h
|
||||||
hle/service/hid/controllers/gesture.cpp
|
hle/service/hid/controllers/gesture.cpp
|
||||||
hle/service/hid/controllers/gesture.h
|
hle/service/hid/controllers/gesture.h
|
||||||
|
hle/service/hid/controllers/home_button.cpp
|
||||||
|
hle/service/hid/controllers/home_button.h
|
||||||
hle/service/hid/controllers/keyboard.cpp
|
hle/service/hid/controllers/keyboard.cpp
|
||||||
hle/service/hid/controllers/keyboard.h
|
hle/service/hid/controllers/keyboard.h
|
||||||
hle/service/hid/controllers/mouse.cpp
|
hle/service/hid/controllers/mouse.cpp
|
||||||
|
@ -574,15 +583,16 @@ add_library(core STATIC
|
||||||
hle/service/hid/controllers/palma.h
|
hle/service/hid/controllers/palma.h
|
||||||
hle/service/hid/controllers/seven_six_axis.cpp
|
hle/service/hid/controllers/seven_six_axis.cpp
|
||||||
hle/service/hid/controllers/seven_six_axis.h
|
hle/service/hid/controllers/seven_six_axis.h
|
||||||
hle/service/hid/controllers/shared_memory_format.h
|
|
||||||
hle/service/hid/controllers/shared_memory_holder.cpp
|
hle/service/hid/controllers/shared_memory_holder.cpp
|
||||||
hle/service/hid/controllers/shared_memory_holder.h
|
hle/service/hid/controllers/shared_memory_holder.h
|
||||||
hle/service/hid/controllers/six_axis.cpp
|
hle/service/hid/controllers/six_axis.cpp
|
||||||
hle/service/hid/controllers/six_axis.h
|
hle/service/hid/controllers/six_axis.h
|
||||||
hle/service/hid/controllers/stubbed.cpp
|
hle/service/hid/controllers/sleep_button.cpp
|
||||||
hle/service/hid/controllers/stubbed.h
|
hle/service/hid/controllers/sleep_button.h
|
||||||
hle/service/hid/controllers/touchscreen.cpp
|
hle/service/hid/controllers/touchscreen.cpp
|
||||||
hle/service/hid/controllers/touchscreen.h
|
hle/service/hid/controllers/touchscreen.h
|
||||||
|
hle/service/hid/controllers/unique_pad.cpp
|
||||||
|
hle/service/hid/controllers/unique_pad.h
|
||||||
hle/service/hid/hidbus/hidbus_base.cpp
|
hle/service/hid/hidbus/hidbus_base.cpp
|
||||||
hle/service/hid/hidbus/hidbus_base.h
|
hle/service/hid/hidbus/hidbus_base.h
|
||||||
hle/service/hid/hidbus/ringcon.cpp
|
hle/service/hid/hidbus/ringcon.cpp
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/kernel/k_shared_memory.h"
|
#include "core/hle/kernel/k_shared_memory.h"
|
||||||
#include "core/hle/service/hid/controllers/applet_resource.h"
|
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||||
#include "core/hle/service/hid/controllers/shared_memory_format.h"
|
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||||
#include "core/hle/service/hid/errors.h"
|
#include "core/hle/service/hid/errors.h"
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
|
@ -164,6 +164,22 @@ Result AppletResource::GetSharedMemoryFormat(SharedMemoryFormat** out_shared_mem
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AruidData* AppletResource::GetAruidData(u64 aruid) {
|
||||||
|
const u64 aruid_index = GetIndexFromAruid(aruid);
|
||||||
|
if (aruid_index == AruidIndexMax) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return &data[aruid_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
AruidData* AppletResource::GetAruidDataByIndex(std::size_t aruid_index) {
|
||||||
|
return &data[aruid_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AppletResource::IsVibrationAruidActive(u64 aruid) const {
|
||||||
|
return aruid == 0 || aruid == active_vibration_aruid;
|
||||||
|
}
|
||||||
|
|
||||||
u64 AppletResource::GetIndexFromAruid(u64 aruid) {
|
u64 AppletResource::GetIndexFromAruid(u64 aruid) {
|
||||||
for (std::size_t i = 0; i < AruidIndexMax; i++) {
|
for (std::size_t i = 0; i < AruidIndexMax; i++) {
|
||||||
if (registration_list.flag[i] == RegistrationStatus::Initialized &&
|
if (registration_list.flag[i] == RegistrationStatus::Initialized &&
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include "common/bit_field.h"
|
#include "common/bit_field.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
@ -20,6 +21,59 @@ class KSharedMemory;
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
struct SharedMemoryFormat;
|
struct SharedMemoryFormat;
|
||||||
|
class AppletResource;
|
||||||
|
class NPadResource;
|
||||||
|
|
||||||
|
static constexpr std::size_t AruidIndexMax = 0x20;
|
||||||
|
|
||||||
|
enum class RegistrationStatus : u32 {
|
||||||
|
None,
|
||||||
|
Initialized,
|
||||||
|
PendingDelete,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DataStatusFlag {
|
||||||
|
union {
|
||||||
|
u32 raw{};
|
||||||
|
|
||||||
|
BitField<0, 1, u32> is_initialized;
|
||||||
|
BitField<1, 1, u32> is_assigned;
|
||||||
|
BitField<16, 1, u32> enable_pad_input;
|
||||||
|
BitField<17, 1, u32> enable_six_axis_sensor;
|
||||||
|
BitField<18, 1, u32> bit_18;
|
||||||
|
BitField<19, 1, u32> is_palma_connectable;
|
||||||
|
BitField<20, 1, u32> enable_palma_boost_mode;
|
||||||
|
BitField<21, 1, u32> enable_touchscreen;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AruidRegisterList {
|
||||||
|
std::array<RegistrationStatus, AruidIndexMax> flag{};
|
||||||
|
std::array<u64, AruidIndexMax> aruid{};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(AruidRegisterList) == 0x180, "AruidRegisterList is an invalid size");
|
||||||
|
|
||||||
|
struct AruidData {
|
||||||
|
DataStatusFlag flag{};
|
||||||
|
u64 aruid{};
|
||||||
|
SharedMemoryFormat* shared_memory_format{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HandheldConfig {
|
||||||
|
bool is_handheld_hid_enabled;
|
||||||
|
bool is_force_handheld;
|
||||||
|
bool is_joycon_rail_enabled;
|
||||||
|
bool is_force_handheld_style_vibration;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(HandheldConfig) == 0x4, "HandheldConfig is an invalid size");
|
||||||
|
|
||||||
|
struct AppletResourceHolder {
|
||||||
|
std::shared_ptr<AppletResource> applet_resource{nullptr};
|
||||||
|
std::recursive_mutex* shared_mutex{nullptr};
|
||||||
|
NPadResource* shared_npad_resource{nullptr};
|
||||||
|
std::shared_ptr<HandheldConfig> handheld_config{nullptr};
|
||||||
|
long* handle_1;
|
||||||
|
};
|
||||||
|
|
||||||
class AppletResource {
|
class AppletResource {
|
||||||
public:
|
public:
|
||||||
|
@ -36,6 +90,10 @@ public:
|
||||||
u64 GetActiveAruid();
|
u64 GetActiveAruid();
|
||||||
Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid);
|
Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid);
|
||||||
Result GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format, u64 aruid);
|
Result GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format, u64 aruid);
|
||||||
|
AruidData* GetAruidData(u64 aruid);
|
||||||
|
AruidData* GetAruidDataByIndex(std::size_t aruid_index);
|
||||||
|
|
||||||
|
bool IsVibrationAruidActive(u64 aruid) const;
|
||||||
|
|
||||||
u64 GetIndexFromAruid(u64 aruid);
|
u64 GetIndexFromAruid(u64 aruid);
|
||||||
|
|
||||||
|
@ -52,46 +110,12 @@ public:
|
||||||
Result UnregisterCoreAppletResource();
|
Result UnregisterCoreAppletResource();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr std::size_t AruidIndexMax = 0x20;
|
|
||||||
|
|
||||||
enum RegistrationStatus : u32 {
|
|
||||||
None,
|
|
||||||
Initialized,
|
|
||||||
PendingDelete,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DataStatusFlag {
|
|
||||||
union {
|
|
||||||
u32 raw{};
|
|
||||||
|
|
||||||
BitField<0, 1, u32> is_initialized;
|
|
||||||
BitField<1, 1, u32> is_assigned;
|
|
||||||
BitField<16, 1, u32> enable_pad_input;
|
|
||||||
BitField<17, 1, u32> enable_six_axis_sensor;
|
|
||||||
BitField<18, 1, u32> bit_18;
|
|
||||||
BitField<19, 1, u32> is_palma_connectable;
|
|
||||||
BitField<20, 1, u32> enable_palma_boost_mode;
|
|
||||||
BitField<21, 1, u32> enable_touchscreen;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AruidRegisterList {
|
|
||||||
std::array<RegistrationStatus, AruidIndexMax> flag{};
|
|
||||||
std::array<u64, AruidIndexMax> aruid{};
|
|
||||||
};
|
|
||||||
static_assert(sizeof(AruidRegisterList) == 0x180, "AruidRegisterList is an invalid size");
|
|
||||||
|
|
||||||
struct AruidData {
|
|
||||||
DataStatusFlag flag{};
|
|
||||||
u64 aruid{};
|
|
||||||
SharedMemoryFormat* shared_memory_format{nullptr};
|
|
||||||
};
|
|
||||||
|
|
||||||
u64 active_aruid{};
|
u64 active_aruid{};
|
||||||
AruidRegisterList registration_list{};
|
AruidRegisterList registration_list{};
|
||||||
std::array<AruidData, AruidIndexMax> data{};
|
std::array<AruidData, AruidIndexMax> data{};
|
||||||
std::array<SharedMemoryHolder, AruidIndexMax> shared_memory_holder{};
|
std::array<SharedMemoryHolder, AruidIndexMax> shared_memory_holder{};
|
||||||
s32 ref_counter{};
|
s32 ref_counter{};
|
||||||
|
u64 active_vibration_aruid;
|
||||||
|
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/core_timing.h"
|
||||||
|
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||||
|
#include "core/hle/service/hid/controllers/capture_button.h"
|
||||||
|
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||||
|
|
||||||
|
namespace Service::HID {
|
||||||
|
|
||||||
|
CaptureButton::CaptureButton(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {}
|
||||||
|
|
||||||
|
CaptureButton::~CaptureButton() = default;
|
||||||
|
|
||||||
|
void CaptureButton::OnInit() {}
|
||||||
|
|
||||||
|
void CaptureButton::OnRelease() {}
|
||||||
|
|
||||||
|
void CaptureButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
|
if (!smart_update) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u64 aruid = applet_resource->GetActiveAruid();
|
||||||
|
auto* data = applet_resource->GetAruidData(aruid);
|
||||||
|
|
||||||
|
if (data == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& header = data->shared_memory_format->capture_button.header;
|
||||||
|
header.timestamp = core_timing.GetGlobalTimeNs().count();
|
||||||
|
header.total_entry_count = 17;
|
||||||
|
header.entry_count = 0;
|
||||||
|
header.last_entry_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Service::HID
|
|
@ -0,0 +1,27 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||||
|
|
||||||
|
namespace Service::HID {
|
||||||
|
|
||||||
|
class CaptureButton final : public ControllerBase {
|
||||||
|
public:
|
||||||
|
explicit CaptureButton(Core::HID::HIDCore& hid_core_);
|
||||||
|
~CaptureButton() override;
|
||||||
|
|
||||||
|
// Called when the controller is initialized
|
||||||
|
void OnInit() override;
|
||||||
|
|
||||||
|
// When the controller is released
|
||||||
|
void OnRelease() override;
|
||||||
|
|
||||||
|
// When the controller is requesting an update for the shared memory
|
||||||
|
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool smart_update{};
|
||||||
|
};
|
||||||
|
} // namespace Service::HID
|
|
@ -5,13 +5,11 @@
|
||||||
#include "core/hid/emulated_console.h"
|
#include "core/hid/emulated_console.h"
|
||||||
#include "core/hid/hid_core.h"
|
#include "core/hid/hid_core.h"
|
||||||
#include "core/hle/service/hid/controllers/console_six_axis.h"
|
#include "core/hle/service/hid/controllers/console_six_axis.h"
|
||||||
#include "core/hle/service/hid/controllers/shared_memory_format.h"
|
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
|
|
||||||
ConsoleSixAxis::ConsoleSixAxis(Core::HID::HIDCore& hid_core_,
|
ConsoleSixAxis::ConsoleSixAxis(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {
|
||||||
ConsoleSixAxisSensorSharedMemoryFormat& console_shared_memory)
|
|
||||||
: ControllerBase{hid_core_}, shared_memory{console_shared_memory} {
|
|
||||||
console = hid_core.GetEmulatedConsole();
|
console = hid_core.GetEmulatedConsole();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +20,15 @@ void ConsoleSixAxis::OnInit() {}
|
||||||
void ConsoleSixAxis::OnRelease() {}
|
void ConsoleSixAxis::OnRelease() {}
|
||||||
|
|
||||||
void ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
void ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
|
const u64 aruid = applet_resource->GetActiveAruid();
|
||||||
|
auto* data = applet_resource->GetAruidData(aruid);
|
||||||
|
|
||||||
|
if (data == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsoleSixAxisSensorSharedMemoryFormat& shared_memory = data->shared_memory_format->console;
|
||||||
|
|
||||||
if (!IsControllerActivated()) {
|
if (!IsControllerActivated()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,12 +10,9 @@ class EmulatedConsole;
|
||||||
} // namespace Core::HID
|
} // namespace Core::HID
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
struct ConsoleSixAxisSensorSharedMemoryFormat;
|
|
||||||
|
|
||||||
class ConsoleSixAxis final : public ControllerBase {
|
class ConsoleSixAxis final : public ControllerBase {
|
||||||
public:
|
public:
|
||||||
explicit ConsoleSixAxis(Core::HID::HIDCore& hid_core_,
|
explicit ConsoleSixAxis(Core::HID::HIDCore& hid_core_);
|
||||||
ConsoleSixAxisSensorSharedMemoryFormat& console_shared_memory);
|
|
||||||
~ConsoleSixAxis() override;
|
~ConsoleSixAxis() override;
|
||||||
|
|
||||||
// Called when the controller is initialized
|
// Called when the controller is initialized
|
||||||
|
@ -28,7 +25,6 @@ public:
|
||||||
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
|
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConsoleSixAxisSensorSharedMemoryFormat& shared_memory;
|
|
||||||
Core::HID::EmulatedConsole* console = nullptr;
|
Core::HID::EmulatedConsole* console = nullptr;
|
||||||
};
|
};
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
|
@ -31,4 +31,9 @@ void ControllerBase::DeactivateController() {
|
||||||
bool ControllerBase::IsControllerActivated() const {
|
bool ControllerBase::IsControllerActivated() const {
|
||||||
return is_activated;
|
return is_activated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ControllerBase::SetAppletResource(std::shared_ptr<AppletResource> resource) {
|
||||||
|
applet_resource = resource;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
|
@ -3,8 +3,11 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
|
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||||
|
|
||||||
namespace Core::Timing {
|
namespace Core::Timing {
|
||||||
class CoreTiming;
|
class CoreTiming;
|
||||||
|
@ -12,7 +15,7 @@ class CoreTiming;
|
||||||
|
|
||||||
namespace Core::HID {
|
namespace Core::HID {
|
||||||
class HIDCore;
|
class HIDCore;
|
||||||
}
|
} // namespace Core::HID
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
class ControllerBase {
|
class ControllerBase {
|
||||||
|
@ -39,8 +42,11 @@ public:
|
||||||
|
|
||||||
bool IsControllerActivated() const;
|
bool IsControllerActivated() const;
|
||||||
|
|
||||||
|
void SetAppletResource(std::shared_ptr<AppletResource> resource);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool is_activated{false};
|
bool is_activated{false};
|
||||||
|
std::shared_ptr<AppletResource> applet_resource{nullptr};
|
||||||
|
|
||||||
Core::HID::HIDCore& hid_core;
|
Core::HID::HIDCore& hid_core;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/core_timing.h"
|
||||||
|
#include "core/frontend/emu_window.h"
|
||||||
|
#include "core/hid/emulated_devices.h"
|
||||||
|
#include "core/hid/hid_core.h"
|
||||||
|
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||||
|
#include "core/hle/service/hid/controllers/debug_mouse.h"
|
||||||
|
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||||
|
|
||||||
|
namespace Service::HID {
|
||||||
|
|
||||||
|
DebugMouse::DebugMouse(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {
|
||||||
|
emulated_devices = hid_core.GetEmulatedDevices();
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugMouse::~DebugMouse() = default;
|
||||||
|
|
||||||
|
void DebugMouse::OnInit() {}
|
||||||
|
void DebugMouse::OnRelease() {}
|
||||||
|
|
||||||
|
void DebugMouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
|
const u64 aruid = applet_resource->GetActiveAruid();
|
||||||
|
auto* data = applet_resource->GetAruidData(aruid);
|
||||||
|
|
||||||
|
if (data == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseSharedMemoryFormat& shared_memory = data->shared_memory_format->debug_mouse;
|
||||||
|
|
||||||
|
if (!IsControllerActivated()) {
|
||||||
|
shared_memory.mouse_lifo.buffer_count = 0;
|
||||||
|
shared_memory.mouse_lifo.buffer_tail = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
next_state = {};
|
||||||
|
|
||||||
|
const auto& last_entry = shared_memory.mouse_lifo.ReadCurrentEntry().state;
|
||||||
|
next_state.sampling_number = last_entry.sampling_number + 1;
|
||||||
|
|
||||||
|
if (Settings::values.mouse_enabled) {
|
||||||
|
const auto& mouse_button_state = emulated_devices->GetMouseButtons();
|
||||||
|
const auto& mouse_position_state = emulated_devices->GetMousePosition();
|
||||||
|
const auto& mouse_wheel_state = emulated_devices->GetMouseWheel();
|
||||||
|
next_state.attribute.is_connected.Assign(1);
|
||||||
|
next_state.x = static_cast<s32>(mouse_position_state.x * Layout::ScreenUndocked::Width);
|
||||||
|
next_state.y = static_cast<s32>(mouse_position_state.y * Layout::ScreenUndocked::Height);
|
||||||
|
next_state.delta_x = next_state.x - last_entry.x;
|
||||||
|
next_state.delta_y = next_state.y - last_entry.y;
|
||||||
|
next_state.delta_wheel_x = mouse_wheel_state.x - last_mouse_wheel_state.x;
|
||||||
|
next_state.delta_wheel_y = mouse_wheel_state.y - last_mouse_wheel_state.y;
|
||||||
|
|
||||||
|
last_mouse_wheel_state = mouse_wheel_state;
|
||||||
|
next_state.button = mouse_button_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_memory.mouse_lifo.WriteNextEntry(next_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Service::HID
|
|
@ -0,0 +1,34 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||||
|
|
||||||
|
namespace Core::HID {
|
||||||
|
class EmulatedDevices;
|
||||||
|
struct MouseState;
|
||||||
|
struct AnalogStickState;
|
||||||
|
} // namespace Core::HID
|
||||||
|
|
||||||
|
namespace Service::HID {
|
||||||
|
class DebugMouse final : public ControllerBase {
|
||||||
|
public:
|
||||||
|
explicit DebugMouse(Core::HID::HIDCore& hid_core_);
|
||||||
|
~DebugMouse() override;
|
||||||
|
|
||||||
|
// Called when the controller is initialized
|
||||||
|
void OnInit() override;
|
||||||
|
|
||||||
|
// When the controller is released
|
||||||
|
void OnRelease() override;
|
||||||
|
|
||||||
|
// When the controller is requesting an update for the shared memory
|
||||||
|
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Core::HID::MouseState next_state{};
|
||||||
|
Core::HID::AnalogStickState last_mouse_wheel_state{};
|
||||||
|
Core::HID::EmulatedDevices* emulated_devices = nullptr;
|
||||||
|
};
|
||||||
|
} // namespace Service::HID
|
|
@ -6,14 +6,13 @@
|
||||||
#include "core/hid/emulated_controller.h"
|
#include "core/hid/emulated_controller.h"
|
||||||
#include "core/hid/hid_core.h"
|
#include "core/hid/hid_core.h"
|
||||||
#include "core/hid/hid_types.h"
|
#include "core/hid/hid_types.h"
|
||||||
|
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||||
#include "core/hle/service/hid/controllers/debug_pad.h"
|
#include "core/hle/service/hid/controllers/debug_pad.h"
|
||||||
#include "core/hle/service/hid/controllers/shared_memory_format.h"
|
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
|
|
||||||
DebugPad::DebugPad(Core::HID::HIDCore& hid_core_,
|
DebugPad::DebugPad(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {
|
||||||
DebugPadSharedMemoryFormat& debug_pad_shared_memory)
|
|
||||||
: ControllerBase{hid_core_}, shared_memory{debug_pad_shared_memory} {
|
|
||||||
controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other);
|
controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +23,15 @@ void DebugPad::OnInit() {}
|
||||||
void DebugPad::OnRelease() {}
|
void DebugPad::OnRelease() {}
|
||||||
|
|
||||||
void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
|
const u64 aruid = applet_resource->GetActiveAruid();
|
||||||
|
auto* data = applet_resource->GetAruidData(aruid);
|
||||||
|
|
||||||
|
if (data == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugPadSharedMemoryFormat& shared_memory = data->shared_memory_format->debug_pad;
|
||||||
|
|
||||||
if (!IsControllerActivated()) {
|
if (!IsControllerActivated()) {
|
||||||
shared_memory.debug_pad_lifo.buffer_count = 0;
|
shared_memory.debug_pad_lifo.buffer_count = 0;
|
||||||
shared_memory.debug_pad_lifo.buffer_tail = 0;
|
shared_memory.debug_pad_lifo.buffer_tail = 0;
|
||||||
|
|
|
@ -15,12 +15,9 @@ class CoreTiming;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
struct DebugPadSharedMemoryFormat;
|
|
||||||
|
|
||||||
class DebugPad final : public ControllerBase {
|
class DebugPad final : public ControllerBase {
|
||||||
public:
|
public:
|
||||||
explicit DebugPad(Core::HID::HIDCore& hid_core_,
|
explicit DebugPad(Core::HID::HIDCore& hid_core_);
|
||||||
DebugPadSharedMemoryFormat& debug_pad_shared_memory);
|
|
||||||
~DebugPad() override;
|
~DebugPad() override;
|
||||||
|
|
||||||
// Called when the controller is initialized
|
// Called when the controller is initialized
|
||||||
|
@ -34,7 +31,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DebugPadState next_state{};
|
DebugPadState next_state{};
|
||||||
DebugPadSharedMemoryFormat& shared_memory;
|
|
||||||
Core::HID::EmulatedController* controller = nullptr;
|
Core::HID::EmulatedController* controller = nullptr;
|
||||||
};
|
};
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/core_timing.h"
|
||||||
|
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||||
|
#include "core/hle/service/hid/controllers/digitizer.h"
|
||||||
|
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||||
|
|
||||||
|
namespace Service::HID {
|
||||||
|
|
||||||
|
Digitizer::Digitizer(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {}
|
||||||
|
|
||||||
|
Digitizer::~Digitizer() = default;
|
||||||
|
|
||||||
|
void Digitizer::OnInit() {}
|
||||||
|
|
||||||
|
void Digitizer::OnRelease() {}
|
||||||
|
|
||||||
|
void Digitizer::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
|
if (!smart_update) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u64 aruid = applet_resource->GetActiveAruid();
|
||||||
|
auto* data = applet_resource->GetAruidData(aruid);
|
||||||
|
|
||||||
|
if (data == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& header = data->shared_memory_format->digitizer.header;
|
||||||
|
header.timestamp = core_timing.GetGlobalTimeNs().count();
|
||||||
|
header.total_entry_count = 17;
|
||||||
|
header.entry_count = 0;
|
||||||
|
header.last_entry_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Service::HID
|
|
@ -0,0 +1,27 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||||
|
|
||||||
|
namespace Service::HID {
|
||||||
|
|
||||||
|
class Digitizer final : public ControllerBase {
|
||||||
|
public:
|
||||||
|
explicit Digitizer(Core::HID::HIDCore& hid_core_);
|
||||||
|
~Digitizer() override;
|
||||||
|
|
||||||
|
// Called when the controller is initialized
|
||||||
|
void OnInit() override;
|
||||||
|
|
||||||
|
// When the controller is released
|
||||||
|
void OnRelease() override;
|
||||||
|
|
||||||
|
// When the controller is requesting an update for the shared memory
|
||||||
|
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool smart_update{};
|
||||||
|
};
|
||||||
|
} // namespace Service::HID
|
|
@ -6,8 +6,9 @@
|
||||||
#include "core/frontend/emu_window.h"
|
#include "core/frontend/emu_window.h"
|
||||||
#include "core/hid/emulated_console.h"
|
#include "core/hid/emulated_console.h"
|
||||||
#include "core/hid/hid_core.h"
|
#include "core/hid/hid_core.h"
|
||||||
|
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||||
#include "core/hle/service/hid/controllers/gesture.h"
|
#include "core/hle/service/hid/controllers/gesture.h"
|
||||||
#include "core/hle/service/hid/controllers/shared_memory_format.h"
|
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
// HW is around 700, value is set to 400 to make it easier to trigger with mouse
|
// HW is around 700, value is set to 400 to make it easier to trigger with mouse
|
||||||
|
@ -21,24 +22,40 @@ constexpr f32 Square(s32 num) {
|
||||||
return static_cast<f32>(num * num);
|
return static_cast<f32>(num * num);
|
||||||
}
|
}
|
||||||
|
|
||||||
Gesture::Gesture(Core::HID::HIDCore& hid_core_, GestureSharedMemoryFormat& gesture_shared_memory)
|
Gesture::Gesture(Core::HID::HIDCore& hid_core_) : ControllerBase(hid_core_) {
|
||||||
: ControllerBase(hid_core_), shared_memory{gesture_shared_memory} {
|
|
||||||
console = hid_core.GetEmulatedConsole();
|
console = hid_core.GetEmulatedConsole();
|
||||||
}
|
}
|
||||||
Gesture::~Gesture() = default;
|
Gesture::~Gesture() = default;
|
||||||
|
|
||||||
void Gesture::OnInit() {
|
void Gesture::OnInit() {
|
||||||
shared_memory.gesture_lifo.buffer_count = 0;
|
const u64 aruid = applet_resource->GetActiveAruid();
|
||||||
shared_memory.gesture_lifo.buffer_tail = 0;
|
auto* data = applet_resource->GetAruidData(aruid);
|
||||||
|
|
||||||
|
if (data == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_memory = &data->shared_memory_format->gesture;
|
||||||
|
shared_memory->gesture_lifo.buffer_count = 0;
|
||||||
|
shared_memory->gesture_lifo.buffer_tail = 0;
|
||||||
force_update = true;
|
force_update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gesture::OnRelease() {}
|
void Gesture::OnRelease() {}
|
||||||
|
|
||||||
void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
|
const u64 aruid = applet_resource->GetActiveAruid();
|
||||||
|
auto* data = applet_resource->GetAruidData(aruid);
|
||||||
|
|
||||||
|
if (data == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_memory = &data->shared_memory_format->gesture;
|
||||||
|
|
||||||
if (!IsControllerActivated()) {
|
if (!IsControllerActivated()) {
|
||||||
shared_memory.gesture_lifo.buffer_count = 0;
|
shared_memory->gesture_lifo.buffer_count = 0;
|
||||||
shared_memory.gesture_lifo.buffer_tail = 0;
|
shared_memory->gesture_lifo.buffer_tail = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +63,7 @@ void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
|
|
||||||
GestureProperties gesture = GetGestureProperties();
|
GestureProperties gesture = GetGestureProperties();
|
||||||
f32 time_difference =
|
f32 time_difference =
|
||||||
static_cast<f32>(shared_memory.gesture_lifo.timestamp - last_update_timestamp) /
|
static_cast<f32>(shared_memory->gesture_lifo.timestamp - last_update_timestamp) /
|
||||||
(1000 * 1000 * 1000);
|
(1000 * 1000 * 1000);
|
||||||
|
|
||||||
// Only update if necessary
|
// Only update if necessary
|
||||||
|
@ -54,7 +71,7 @@ void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_update_timestamp = shared_memory.gesture_lifo.timestamp;
|
last_update_timestamp = shared_memory->gesture_lifo.timestamp;
|
||||||
UpdateGestureSharedMemory(gesture, time_difference);
|
UpdateGestureSharedMemory(gesture, time_difference);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +114,7 @@ void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_dif
|
||||||
GestureType type = GestureType::Idle;
|
GestureType type = GestureType::Idle;
|
||||||
GestureAttribute attributes{};
|
GestureAttribute attributes{};
|
||||||
|
|
||||||
const auto& last_entry = shared_memory.gesture_lifo.ReadCurrentEntry().state;
|
const auto& last_entry = shared_memory->gesture_lifo.ReadCurrentEntry().state;
|
||||||
|
|
||||||
// Reset next state to default
|
// Reset next state to default
|
||||||
next_state.sampling_number = last_entry.sampling_number + 1;
|
next_state.sampling_number = last_entry.sampling_number + 1;
|
||||||
|
@ -127,7 +144,7 @@ void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_dif
|
||||||
next_state.points = gesture.points;
|
next_state.points = gesture.points;
|
||||||
last_gesture = gesture;
|
last_gesture = gesture;
|
||||||
|
|
||||||
shared_memory.gesture_lifo.WriteNextEntry(next_state);
|
shared_memory->gesture_lifo.WriteNextEntry(next_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gesture::NewGesture(GestureProperties& gesture, GestureType& type,
|
void Gesture::NewGesture(GestureProperties& gesture, GestureType& type,
|
||||||
|
@ -300,7 +317,7 @@ void Gesture::SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_
|
||||||
}
|
}
|
||||||
|
|
||||||
const GestureState& Gesture::GetLastGestureEntry() const {
|
const GestureState& Gesture::GetLastGestureEntry() const {
|
||||||
return shared_memory.gesture_lifo.ReadCurrentEntry().state;
|
return shared_memory->gesture_lifo.ReadCurrentEntry().state;
|
||||||
}
|
}
|
||||||
|
|
||||||
GestureProperties Gesture::GetGestureProperties() {
|
GestureProperties Gesture::GetGestureProperties() {
|
||||||
|
|
|
@ -18,8 +18,7 @@ struct GestureSharedMemoryFormat;
|
||||||
|
|
||||||
class Gesture final : public ControllerBase {
|
class Gesture final : public ControllerBase {
|
||||||
public:
|
public:
|
||||||
explicit Gesture(Core::HID::HIDCore& hid_core_,
|
explicit Gesture(Core::HID::HIDCore& hid_core_);
|
||||||
GestureSharedMemoryFormat& gesture_shared_memory);
|
|
||||||
~Gesture() override;
|
~Gesture() override;
|
||||||
|
|
||||||
// Called when the controller is initialized
|
// Called when the controller is initialized
|
||||||
|
@ -74,7 +73,7 @@ private:
|
||||||
GestureProperties GetGestureProperties();
|
GestureProperties GetGestureProperties();
|
||||||
|
|
||||||
GestureState next_state{};
|
GestureState next_state{};
|
||||||
GestureSharedMemoryFormat& shared_memory;
|
GestureSharedMemoryFormat* shared_memory;
|
||||||
Core::HID::EmulatedConsole* console = nullptr;
|
Core::HID::EmulatedConsole* console = nullptr;
|
||||||
|
|
||||||
std::array<Core::HID::TouchFinger, MAX_POINTS> fingers{};
|
std::array<Core::HID::TouchFinger, MAX_POINTS> fingers{};
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/core_timing.h"
|
||||||
|
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||||
|
#include "core/hle/service/hid/controllers/home_button.h"
|
||||||
|
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||||
|
|
||||||
|
namespace Service::HID {
|
||||||
|
|
||||||
|
HomeButton::HomeButton(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {}
|
||||||
|
|
||||||
|
HomeButton::~HomeButton() = default;
|
||||||
|
|
||||||
|
void HomeButton::OnInit() {}
|
||||||
|
|
||||||
|
void HomeButton::OnRelease() {}
|
||||||
|
|
||||||
|
void HomeButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
|
if (!smart_update) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u64 aruid = applet_resource->GetActiveAruid();
|
||||||
|
auto* data = applet_resource->GetAruidData(aruid);
|
||||||
|
|
||||||
|
if (data == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& header = data->shared_memory_format->home_button.header;
|
||||||
|
header.timestamp = core_timing.GetGlobalTimeNs().count();
|
||||||
|
header.total_entry_count = 17;
|
||||||
|
header.entry_count = 0;
|
||||||
|
header.last_entry_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Service::HID
|
|
@ -0,0 +1,27 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||||
|
|
||||||
|
namespace Service::HID {
|
||||||
|
|
||||||
|
class HomeButton final : public ControllerBase {
|
||||||
|
public:
|
||||||
|
explicit HomeButton(Core::HID::HIDCore& hid_core_);
|
||||||
|
~HomeButton() override;
|
||||||
|
|
||||||
|
// Called when the controller is initialized
|
||||||
|
void OnInit() override;
|
||||||
|
|
||||||
|
// When the controller is released
|
||||||
|
void OnRelease() override;
|
||||||
|
|
||||||
|
// When the controller is requesting an update for the shared memory
|
||||||
|
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool smart_update{};
|
||||||
|
};
|
||||||
|
} // namespace Service::HID
|
|
@ -5,14 +5,13 @@
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/hid/emulated_devices.h"
|
#include "core/hid/emulated_devices.h"
|
||||||
#include "core/hid/hid_core.h"
|
#include "core/hid/hid_core.h"
|
||||||
|
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||||
#include "core/hle/service/hid/controllers/keyboard.h"
|
#include "core/hle/service/hid/controllers/keyboard.h"
|
||||||
#include "core/hle/service/hid/controllers/shared_memory_format.h"
|
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
|
|
||||||
Keyboard::Keyboard(Core::HID::HIDCore& hid_core_,
|
Keyboard::Keyboard(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {
|
||||||
KeyboardSharedMemoryFormat& keyboard_shared_memory)
|
|
||||||
: ControllerBase{hid_core_}, shared_memory{keyboard_shared_memory} {
|
|
||||||
emulated_devices = hid_core.GetEmulatedDevices();
|
emulated_devices = hid_core.GetEmulatedDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +22,15 @@ void Keyboard::OnInit() {}
|
||||||
void Keyboard::OnRelease() {}
|
void Keyboard::OnRelease() {}
|
||||||
|
|
||||||
void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
|
const u64 aruid = applet_resource->GetActiveAruid();
|
||||||
|
auto* data = applet_resource->GetAruidData(aruid);
|
||||||
|
|
||||||
|
if (data == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardSharedMemoryFormat& shared_memory = data->shared_memory_format->keyboard;
|
||||||
|
|
||||||
if (!IsControllerActivated()) {
|
if (!IsControllerActivated()) {
|
||||||
shared_memory.keyboard_lifo.buffer_count = 0;
|
shared_memory.keyboard_lifo.buffer_count = 0;
|
||||||
shared_memory.keyboard_lifo.buffer_tail = 0;
|
shared_memory.keyboard_lifo.buffer_tail = 0;
|
||||||
|
|
|
@ -7,12 +7,9 @@
|
||||||
#include "core/hle/service/hid/controllers/types/keyboard_types.h"
|
#include "core/hle/service/hid/controllers/types/keyboard_types.h"
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
struct KeyboardSharedMemoryFormat;
|
|
||||||
|
|
||||||
class Keyboard final : public ControllerBase {
|
class Keyboard final : public ControllerBase {
|
||||||
public:
|
public:
|
||||||
explicit Keyboard(Core::HID::HIDCore& hid_core_,
|
explicit Keyboard(Core::HID::HIDCore& hid_core_);
|
||||||
KeyboardSharedMemoryFormat& keyboard_shared_memory);
|
|
||||||
~Keyboard() override;
|
~Keyboard() override;
|
||||||
|
|
||||||
// Called when the controller is initialized
|
// Called when the controller is initialized
|
||||||
|
@ -26,7 +23,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
KeyboardState next_state{};
|
KeyboardState next_state{};
|
||||||
KeyboardSharedMemoryFormat& shared_memory;
|
|
||||||
Core::HID::EmulatedDevices* emulated_devices = nullptr;
|
Core::HID::EmulatedDevices* emulated_devices = nullptr;
|
||||||
};
|
};
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
#include "core/frontend/emu_window.h"
|
#include "core/frontend/emu_window.h"
|
||||||
#include "core/hid/emulated_devices.h"
|
#include "core/hid/emulated_devices.h"
|
||||||
#include "core/hid/hid_core.h"
|
#include "core/hid/hid_core.h"
|
||||||
|
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||||
#include "core/hle/service/hid/controllers/mouse.h"
|
#include "core/hle/service/hid/controllers/mouse.h"
|
||||||
#include "core/hle/service/hid/controllers/shared_memory_format.h"
|
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
|
|
||||||
Mouse::Mouse(Core::HID::HIDCore& hid_core_, MouseSharedMemoryFormat& mouse_shared_memory)
|
Mouse::Mouse(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {
|
||||||
: ControllerBase{hid_core_}, shared_memory{mouse_shared_memory} {
|
|
||||||
emulated_devices = hid_core.GetEmulatedDevices();
|
emulated_devices = hid_core.GetEmulatedDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,15 @@ void Mouse::OnInit() {}
|
||||||
void Mouse::OnRelease() {}
|
void Mouse::OnRelease() {}
|
||||||
|
|
||||||
void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
|
const u64 aruid = applet_resource->GetActiveAruid();
|
||||||
|
auto* data = applet_resource->GetAruidData(aruid);
|
||||||
|
|
||||||
|
if (data == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseSharedMemoryFormat& shared_memory = data->shared_memory_format->mouse;
|
||||||
|
|
||||||
if (!IsControllerActivated()) {
|
if (!IsControllerActivated()) {
|
||||||
shared_memory.mouse_lifo.buffer_count = 0;
|
shared_memory.mouse_lifo.buffer_count = 0;
|
||||||
shared_memory.mouse_lifo.buffer_tail = 0;
|
shared_memory.mouse_lifo.buffer_tail = 0;
|
||||||
|
|
|
@ -12,11 +12,9 @@ struct AnalogStickState;
|
||||||
} // namespace Core::HID
|
} // namespace Core::HID
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
struct MouseSharedMemoryFormat;
|
|
||||||
|
|
||||||
class Mouse final : public ControllerBase {
|
class Mouse final : public ControllerBase {
|
||||||
public:
|
public:
|
||||||
explicit Mouse(Core::HID::HIDCore& hid_core_, MouseSharedMemoryFormat& mouse_shared_memory);
|
explicit Mouse(Core::HID::HIDCore& hid_core_);
|
||||||
~Mouse() override;
|
~Mouse() override;
|
||||||
|
|
||||||
// Called when the controller is initialized
|
// Called when the controller is initialized
|
||||||
|
@ -31,7 +29,6 @@ public:
|
||||||
private:
|
private:
|
||||||
Core::HID::MouseState next_state{};
|
Core::HID::MouseState next_state{};
|
||||||
Core::HID::AnalogStickState last_mouse_wheel_state{};
|
Core::HID::AnalogStickState last_mouse_wheel_state{};
|
||||||
MouseSharedMemoryFormat& shared_memory;
|
|
||||||
Core::HID::EmulatedDevices* emulated_devices = nullptr;
|
Core::HID::EmulatedDevices* emulated_devices = nullptr;
|
||||||
};
|
};
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
|
@ -16,8 +16,9 @@
|
||||||
#include "core/hid/hid_core.h"
|
#include "core/hid/hid_core.h"
|
||||||
#include "core/hle/kernel/k_event.h"
|
#include "core/hle/kernel/k_event.h"
|
||||||
#include "core/hle/kernel/k_readable_event.h"
|
#include "core/hle/kernel/k_readable_event.h"
|
||||||
|
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||||
#include "core/hle/service/hid/controllers/npad.h"
|
#include "core/hle/service/hid/controllers/npad.h"
|
||||||
#include "core/hle/service/hid/controllers/shared_memory_format.h"
|
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||||
#include "core/hle/service/hid/errors.h"
|
#include "core/hle/service/hid/errors.h"
|
||||||
#include "core/hle/service/hid/hid_util.h"
|
#include "core/hle/service/hid/hid_util.h"
|
||||||
#include "core/hle/service/kernel_helpers.h"
|
#include "core/hle/service/kernel_helpers.h"
|
||||||
|
@ -30,12 +31,10 @@ constexpr std::array<Core::HID::NpadIdType, 10> npad_id_list{
|
||||||
Core::HID::NpadIdType::Handheld,
|
Core::HID::NpadIdType::Handheld,
|
||||||
};
|
};
|
||||||
|
|
||||||
NPad::NPad(Core::HID::HIDCore& hid_core_, NpadSharedMemoryFormat& npad_shared_memory_format,
|
NPad::NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_)
|
||||||
KernelHelpers::ServiceContext& service_context_)
|
|
||||||
: ControllerBase{hid_core_}, service_context{service_context_} {
|
: ControllerBase{hid_core_}, service_context{service_context_} {
|
||||||
for (std::size_t i = 0; i < controller_data.size(); ++i) {
|
for (std::size_t i = 0; i < controller_data.size(); ++i) {
|
||||||
auto& controller = controller_data[i];
|
auto& controller = controller_data[i];
|
||||||
controller.shared_memory = &npad_shared_memory_format.npad_entry[i].internal_state;
|
|
||||||
controller.device = hid_core.GetEmulatedControllerByIndex(i);
|
controller.device = hid_core.GetEmulatedControllerByIndex(i);
|
||||||
controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value =
|
controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value =
|
||||||
Core::HID::DEFAULT_VIBRATION_VALUE;
|
Core::HID::DEFAULT_VIBRATION_VALUE;
|
||||||
|
@ -297,12 +296,20 @@ void NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPad::OnInit() {
|
void NPad::OnInit() {
|
||||||
|
const u64 aruid = applet_resource->GetActiveAruid();
|
||||||
|
auto* data = applet_resource->GetAruidData(aruid);
|
||||||
|
|
||||||
|
if (data == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!IsControllerActivated()) {
|
if (!IsControllerActivated()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::size_t i = 0; i < controller_data.size(); ++i) {
|
for (std::size_t i = 0; i < controller_data.size(); ++i) {
|
||||||
auto& controller = controller_data[i];
|
auto& controller = controller_data[i];
|
||||||
|
controller.shared_memory = &data->shared_memory_format->npad.npad_entry[i].internal_state;
|
||||||
controller.styleset_changed_event =
|
controller.styleset_changed_event =
|
||||||
service_context.CreateEvent(fmt::format("npad:NpadStyleSetChanged_{}", i));
|
service_context.CreateEvent(fmt::format("npad:NpadStyleSetChanged_{}", i));
|
||||||
}
|
}
|
||||||
|
@ -355,7 +362,9 @@ void NPad::OnRelease() {
|
||||||
is_controller_initialized = false;
|
is_controller_initialized = false;
|
||||||
for (std::size_t i = 0; i < controller_data.size(); ++i) {
|
for (std::size_t i = 0; i < controller_data.size(); ++i) {
|
||||||
auto& controller = controller_data[i];
|
auto& controller = controller_data[i];
|
||||||
service_context.CloseEvent(controller.styleset_changed_event);
|
if (controller.styleset_changed_event) {
|
||||||
|
service_context.CloseEvent(controller.styleset_changed_event);
|
||||||
|
}
|
||||||
for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) {
|
for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) {
|
||||||
VibrateControllerAtIndex(controller.device->GetNpadIdType(), device_idx, {});
|
VibrateControllerAtIndex(controller.device->GetNpadIdType(), device_idx, {});
|
||||||
}
|
}
|
||||||
|
@ -432,12 +441,20 @@ void NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
|
const u64 aruid = applet_resource->GetActiveAruid();
|
||||||
|
auto* data = applet_resource->GetAruidData(aruid);
|
||||||
|
|
||||||
|
if (data == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!IsControllerActivated()) {
|
if (!IsControllerActivated()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::size_t i = 0; i < controller_data.size(); ++i) {
|
for (std::size_t i = 0; i < controller_data.size(); ++i) {
|
||||||
auto& controller = controller_data[i];
|
auto& controller = controller_data[i];
|
||||||
|
controller.shared_memory = &data->shared_memory_format->npad.npad_entry[i].internal_state;
|
||||||
auto* npad = controller.shared_memory;
|
auto* npad = controller.shared_memory;
|
||||||
|
|
||||||
const auto& controller_type = controller.device->GetNpadStyleIndex();
|
const auto& controller_type = controller.device->GetNpadStyleIndex();
|
||||||
|
@ -976,30 +993,6 @@ Result NPad::ResetIsSixAxisSensorDeviceNewlyAssigned(
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
NpadSixAxisSensorLifo& NPad::GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id) {
|
|
||||||
return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_fullkey_lifo;
|
|
||||||
}
|
|
||||||
|
|
||||||
NpadSixAxisSensorLifo& NPad::GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id) {
|
|
||||||
return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_handheld_lifo;
|
|
||||||
}
|
|
||||||
|
|
||||||
NpadSixAxisSensorLifo& NPad::GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id) {
|
|
||||||
return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_left_lifo;
|
|
||||||
}
|
|
||||||
|
|
||||||
NpadSixAxisSensorLifo& NPad::GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id) {
|
|
||||||
return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_right_lifo;
|
|
||||||
}
|
|
||||||
|
|
||||||
NpadSixAxisSensorLifo& NPad::GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id) {
|
|
||||||
return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_left_lifo;
|
|
||||||
}
|
|
||||||
|
|
||||||
NpadSixAxisSensorLifo& NPad::GetSixAxisRightLifo(Core::HID::NpadIdType npad_id) {
|
|
||||||
return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_right_lifo;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
|
Result NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
|
||||||
Core::HID::NpadIdType npad_id_2) {
|
Core::HID::NpadIdType npad_id_2) {
|
||||||
if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
|
if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
|
||||||
|
|
|
@ -30,14 +30,14 @@ class ServiceContext;
|
||||||
union Result;
|
union Result;
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
|
class AppletResource;
|
||||||
struct NpadInternalState;
|
struct NpadInternalState;
|
||||||
struct NpadSixAxisSensorLifo;
|
struct NpadSixAxisSensorLifo;
|
||||||
struct NpadSharedMemoryFormat;
|
struct NpadSharedMemoryFormat;
|
||||||
|
|
||||||
class NPad final : public ControllerBase {
|
class NPad final : public ControllerBase {
|
||||||
public:
|
public:
|
||||||
explicit NPad(Core::HID::HIDCore& hid_core_, NpadSharedMemoryFormat& npad_shared_memory_format,
|
explicit NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_);
|
||||||
KernelHelpers::ServiceContext& service_context_);
|
|
||||||
~NPad() override;
|
~NPad() override;
|
||||||
|
|
||||||
// Called when the controller is initialized
|
// Called when the controller is initialized
|
||||||
|
@ -106,13 +106,6 @@ public:
|
||||||
Result ResetIsSixAxisSensorDeviceNewlyAssigned(
|
Result ResetIsSixAxisSensorDeviceNewlyAssigned(
|
||||||
const Core::HID::SixAxisSensorHandle& sixaxis_handle);
|
const Core::HID::SixAxisSensorHandle& sixaxis_handle);
|
||||||
|
|
||||||
NpadSixAxisSensorLifo& GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id);
|
|
||||||
NpadSixAxisSensorLifo& GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id);
|
|
||||||
NpadSixAxisSensorLifo& GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id);
|
|
||||||
NpadSixAxisSensorLifo& GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id);
|
|
||||||
NpadSixAxisSensorLifo& GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id);
|
|
||||||
NpadSixAxisSensorLifo& GetSixAxisRightLifo(Core::HID::NpadIdType npad_id);
|
|
||||||
|
|
||||||
Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const;
|
Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const;
|
||||||
Result IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id,
|
Result IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id,
|
||||||
bool& is_enabled) const;
|
bool& is_enabled) const;
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/kernel/k_shared_memory.h"
|
#include "core/hle/kernel/k_shared_memory.h"
|
||||||
#include "core/hle/service/hid/controllers/shared_memory_format.h"
|
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||||
#include "core/hle/service/hid/controllers/shared_memory_holder.h"
|
#include "core/hle/service/hid/controllers/shared_memory_holder.h"
|
||||||
|
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||||
#include "core/hle/service/hid/errors.h"
|
#include "core/hle/service/hid/errors.h"
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
#include "core/hid/emulated_controller.h"
|
#include "core/hid/emulated_controller.h"
|
||||||
#include "core/hid/hid_core.h"
|
#include "core/hid/hid_core.h"
|
||||||
#include "core/hle/service/hid/controllers/npad.h"
|
#include "core/hle/service/hid/controllers/npad.h"
|
||||||
#include "core/hle/service/hid/controllers/shared_memory_format.h"
|
|
||||||
#include "core/hle/service/hid/controllers/six_axis.h"
|
#include "core/hle/service/hid/controllers/six_axis.h"
|
||||||
|
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||||
#include "core/hle/service/hid/errors.h"
|
#include "core/hle/service/hid/errors.h"
|
||||||
#include "core/hle/service/hid/hid_util.h"
|
#include "core/hle/service/hid/hid_util.h"
|
||||||
|
|
||||||
|
@ -27,14 +27,20 @@ void SixAxis::OnInit() {}
|
||||||
void SixAxis::OnRelease() {}
|
void SixAxis::OnRelease() {}
|
||||||
|
|
||||||
void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
|
const u64 aruid = applet_resource->GetActiveAruid();
|
||||||
|
auto* data = applet_resource->GetAruidData(aruid);
|
||||||
|
|
||||||
|
if (data == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!IsControllerActivated()) {
|
if (!IsControllerActivated()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::size_t i = 0; i < controller_data.size(); ++i) {
|
for (std::size_t i = 0; i < controller_data.size(); ++i) {
|
||||||
|
NpadSharedMemoryEntry& shared_memory = data->shared_memory_format->npad.npad_entry[i];
|
||||||
auto& controller = controller_data[i];
|
auto& controller = controller_data[i];
|
||||||
|
|
||||||
const auto npad_id = IndexToNpadIdType(i);
|
|
||||||
const auto& controller_type = controller.device->GetNpadStyleIndex();
|
const auto& controller_type = controller.device->GetNpadStyleIndex();
|
||||||
|
|
||||||
if (controller_type == Core::HID::NpadStyleIndex::None ||
|
if (controller_type == Core::HID::NpadStyleIndex::None ||
|
||||||
|
@ -50,12 +56,12 @@ void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state;
|
auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state;
|
||||||
auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state;
|
auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state;
|
||||||
|
|
||||||
auto& sixaxis_fullkey_lifo = npad->GetSixAxisFullkeyLifo(npad_id);
|
auto& sixaxis_fullkey_lifo = shared_memory.internal_state.sixaxis_fullkey_lifo;
|
||||||
auto& sixaxis_handheld_lifo = npad->GetSixAxisHandheldLifo(npad_id);
|
auto& sixaxis_handheld_lifo = shared_memory.internal_state.sixaxis_handheld_lifo;
|
||||||
auto& sixaxis_dual_left_lifo = npad->GetSixAxisDualLeftLifo(npad_id);
|
auto& sixaxis_dual_left_lifo = shared_memory.internal_state.sixaxis_dual_left_lifo;
|
||||||
auto& sixaxis_dual_right_lifo = npad->GetSixAxisDualRightLifo(npad_id);
|
auto& sixaxis_dual_right_lifo = shared_memory.internal_state.sixaxis_dual_right_lifo;
|
||||||
auto& sixaxis_left_lifo = npad->GetSixAxisLeftLifo(npad_id);
|
auto& sixaxis_left_lifo = shared_memory.internal_state.sixaxis_left_lifo;
|
||||||
auto& sixaxis_right_lifo = npad->GetSixAxisRightLifo(npad_id);
|
auto& sixaxis_right_lifo = shared_memory.internal_state.sixaxis_right_lifo;
|
||||||
|
|
||||||
// Clear previous state
|
// Clear previous state
|
||||||
sixaxis_fullkey_state = {};
|
sixaxis_fullkey_state = {};
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/core_timing.h"
|
||||||
|
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||||
|
#include "core/hle/service/hid/controllers/sleep_button.h"
|
||||||
|
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||||
|
|
||||||
|
namespace Service::HID {
|
||||||
|
|
||||||
|
SleepButton::SleepButton(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {}
|
||||||
|
|
||||||
|
SleepButton::~SleepButton() = default;
|
||||||
|
|
||||||
|
void SleepButton::OnInit() {}
|
||||||
|
|
||||||
|
void SleepButton::OnRelease() {}
|
||||||
|
|
||||||
|
void SleepButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
|
if (!smart_update) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u64 aruid = applet_resource->GetActiveAruid();
|
||||||
|
auto* data = applet_resource->GetAruidData(aruid);
|
||||||
|
|
||||||
|
if (data == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& header = data->shared_memory_format->capture_button.header;
|
||||||
|
header.timestamp = core_timing.GetGlobalTimeNs().count();
|
||||||
|
header.total_entry_count = 17;
|
||||||
|
header.entry_count = 0;
|
||||||
|
header.last_entry_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Service::HID
|
|
@ -0,0 +1,27 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||||
|
|
||||||
|
namespace Service::HID {
|
||||||
|
|
||||||
|
class SleepButton final : public ControllerBase {
|
||||||
|
public:
|
||||||
|
explicit SleepButton(Core::HID::HIDCore& hid_core_);
|
||||||
|
~SleepButton() override;
|
||||||
|
|
||||||
|
// Called when the controller is initialized
|
||||||
|
void OnInit() override;
|
||||||
|
|
||||||
|
// When the controller is released
|
||||||
|
void OnRelease() override;
|
||||||
|
|
||||||
|
// When the controller is requesting an update for the shared memory
|
||||||
|
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool smart_update{};
|
||||||
|
};
|
||||||
|
} // namespace Service::HID
|
|
@ -8,15 +8,14 @@
|
||||||
#include "core/frontend/emu_window.h"
|
#include "core/frontend/emu_window.h"
|
||||||
#include "core/hid/emulated_console.h"
|
#include "core/hid/emulated_console.h"
|
||||||
#include "core/hid/hid_core.h"
|
#include "core/hid/hid_core.h"
|
||||||
#include "core/hle/service/hid/controllers/shared_memory_format.h"
|
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||||
#include "core/hle/service/hid/controllers/touchscreen.h"
|
#include "core/hle/service/hid/controllers/touchscreen.h"
|
||||||
|
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
|
|
||||||
TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_,
|
TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_)
|
||||||
TouchScreenSharedMemoryFormat& touch_shared_memory)
|
: ControllerBase{hid_core_}, touchscreen_width(Layout::ScreenUndocked::Width),
|
||||||
: ControllerBase{hid_core_}, shared_memory{touch_shared_memory},
|
|
||||||
touchscreen_width(Layout::ScreenUndocked::Width),
|
|
||||||
touchscreen_height(Layout::ScreenUndocked::Height) {
|
touchscreen_height(Layout::ScreenUndocked::Height) {
|
||||||
console = hid_core.GetEmulatedConsole();
|
console = hid_core.GetEmulatedConsole();
|
||||||
}
|
}
|
||||||
|
@ -28,6 +27,14 @@ void TouchScreen::OnInit() {}
|
||||||
void TouchScreen::OnRelease() {}
|
void TouchScreen::OnRelease() {}
|
||||||
|
|
||||||
void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
|
const u64 aruid = applet_resource->GetActiveAruid();
|
||||||
|
auto* data = applet_resource->GetAruidData(aruid);
|
||||||
|
|
||||||
|
if (data == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TouchScreenSharedMemoryFormat& shared_memory = data->shared_memory_format->touch_screen;
|
||||||
shared_memory.touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count();
|
shared_memory.touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count();
|
||||||
|
|
||||||
if (!IsControllerActivated()) {
|
if (!IsControllerActivated()) {
|
||||||
|
|
|
@ -18,8 +18,7 @@ struct TouchScreenSharedMemoryFormat;
|
||||||
|
|
||||||
class TouchScreen final : public ControllerBase {
|
class TouchScreen final : public ControllerBase {
|
||||||
public:
|
public:
|
||||||
explicit TouchScreen(Core::HID::HIDCore& hid_core_,
|
explicit TouchScreen(Core::HID::HIDCore& hid_core_);
|
||||||
TouchScreenSharedMemoryFormat& touch_shared_memory);
|
|
||||||
~TouchScreen() override;
|
~TouchScreen() override;
|
||||||
|
|
||||||
// Called when the controller is initialized
|
// Called when the controller is initialized
|
||||||
|
@ -35,7 +34,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TouchScreenState next_state{};
|
TouchScreenState next_state{};
|
||||||
TouchScreenSharedMemoryFormat& shared_memory;
|
|
||||||
Core::HID::EmulatedConsole* console = nullptr;
|
Core::HID::EmulatedConsole* console = nullptr;
|
||||||
|
|
||||||
std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers{};
|
std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers{};
|
||||||
|
|
|
@ -0,0 +1,240 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/common_funcs.h"
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "common/vector_math.h"
|
||||||
|
#include "core/hid/hid_types.h"
|
||||||
|
#include "core/hle/service/hid//controllers/types/debug_pad_types.h"
|
||||||
|
#include "core/hle/service/hid//controllers/types/keyboard_types.h"
|
||||||
|
#include "core/hle/service/hid//controllers/types/mouse_types.h"
|
||||||
|
#include "core/hle/service/hid//controllers/types/npad_types.h"
|
||||||
|
#include "core/hle/service/hid//controllers/types/touch_types.h"
|
||||||
|
#include "core/hle/service/hid/ring_lifo.h"
|
||||||
|
|
||||||
|
namespace Service::HID {
|
||||||
|
static const std::size_t HidEntryCount = 17;
|
||||||
|
|
||||||
|
struct CommonHeader {
|
||||||
|
s64 timestamp{};
|
||||||
|
s64 total_entry_count{};
|
||||||
|
s64 last_entry_index{};
|
||||||
|
s64 entry_count{};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
|
||||||
|
|
||||||
|
// This is nn::hid::detail::DebugPadSharedMemoryFormat
|
||||||
|
struct DebugPadSharedMemoryFormat {
|
||||||
|
// This is nn::hid::detail::DebugPadLifo
|
||||||
|
Lifo<DebugPadState, HidEntryCount> debug_pad_lifo{};
|
||||||
|
static_assert(sizeof(debug_pad_lifo) == 0x2C8, "debug_pad_lifo is an invalid size");
|
||||||
|
INSERT_PADDING_WORDS(0x4E);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(DebugPadSharedMemoryFormat) == 0x400,
|
||||||
|
"DebugPadSharedMemoryFormat is an invalid size");
|
||||||
|
|
||||||
|
// This is nn::hid::detail::TouchScreenSharedMemoryFormat
|
||||||
|
struct TouchScreenSharedMemoryFormat {
|
||||||
|
// This is nn::hid::detail::TouchScreenLifo
|
||||||
|
Lifo<TouchScreenState, HidEntryCount> touch_screen_lifo{};
|
||||||
|
static_assert(sizeof(touch_screen_lifo) == 0x2C38, "touch_screen_lifo is an invalid size");
|
||||||
|
INSERT_PADDING_WORDS(0xF2);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(TouchScreenSharedMemoryFormat) == 0x3000,
|
||||||
|
"TouchScreenSharedMemoryFormat is an invalid size");
|
||||||
|
|
||||||
|
// This is nn::hid::detail::MouseSharedMemoryFormat
|
||||||
|
struct MouseSharedMemoryFormat {
|
||||||
|
// This is nn::hid::detail::MouseLifo
|
||||||
|
Lifo<Core::HID::MouseState, HidEntryCount> mouse_lifo{};
|
||||||
|
static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size");
|
||||||
|
INSERT_PADDING_WORDS(0x2C);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(MouseSharedMemoryFormat) == 0x400,
|
||||||
|
"MouseSharedMemoryFormat is an invalid size");
|
||||||
|
|
||||||
|
// This is nn::hid::detail::KeyboardSharedMemoryFormat
|
||||||
|
struct KeyboardSharedMemoryFormat {
|
||||||
|
// This is nn::hid::detail::KeyboardLifo
|
||||||
|
Lifo<KeyboardState, HidEntryCount> keyboard_lifo{};
|
||||||
|
static_assert(sizeof(keyboard_lifo) == 0x3D8, "keyboard_lifo is an invalid size");
|
||||||
|
INSERT_PADDING_WORDS(0xA);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(KeyboardSharedMemoryFormat) == 0x400,
|
||||||
|
"KeyboardSharedMemoryFormat is an invalid size");
|
||||||
|
|
||||||
|
// This is nn::hid::detail::DigitizerSharedMemoryFormat
|
||||||
|
struct DigitizerSharedMemoryFormat {
|
||||||
|
CommonHeader header;
|
||||||
|
INSERT_PADDING_BYTES(0xFE0);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(DigitizerSharedMemoryFormat) == 0x1000,
|
||||||
|
"DigitizerSharedMemoryFormat is an invalid size");
|
||||||
|
|
||||||
|
// This is nn::hid::detail::HomeButtonSharedMemoryFormat
|
||||||
|
struct HomeButtonSharedMemoryFormat {
|
||||||
|
CommonHeader header;
|
||||||
|
INSERT_PADDING_BYTES(0x1E0);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(HomeButtonSharedMemoryFormat) == 0x200,
|
||||||
|
"HomeButtonSharedMemoryFormat is an invalid size");
|
||||||
|
|
||||||
|
// This is nn::hid::detail::SleepButtonSharedMemoryFormat
|
||||||
|
struct SleepButtonSharedMemoryFormat {
|
||||||
|
CommonHeader header;
|
||||||
|
INSERT_PADDING_BYTES(0x1E0);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SleepButtonSharedMemoryFormat) == 0x200,
|
||||||
|
"SleepButtonSharedMemoryFormat is an invalid size");
|
||||||
|
|
||||||
|
// This is nn::hid::detail::CaptureButtonSharedMemoryFormat
|
||||||
|
struct CaptureButtonSharedMemoryFormat {
|
||||||
|
CommonHeader header;
|
||||||
|
INSERT_PADDING_BYTES(0x1E0);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(CaptureButtonSharedMemoryFormat) == 0x200,
|
||||||
|
"CaptureButtonSharedMemoryFormat is an invalid size");
|
||||||
|
|
||||||
|
// This is nn::hid::detail::InputDetectorSharedMemoryFormat
|
||||||
|
struct InputDetectorSharedMemoryFormat {
|
||||||
|
CommonHeader header;
|
||||||
|
INSERT_PADDING_BYTES(0x7E0);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(InputDetectorSharedMemoryFormat) == 0x800,
|
||||||
|
"InputDetectorSharedMemoryFormat is an invalid size");
|
||||||
|
|
||||||
|
// This is nn::hid::detail::UniquePadSharedMemoryFormat
|
||||||
|
struct UniquePadSharedMemoryFormat {
|
||||||
|
CommonHeader header;
|
||||||
|
INSERT_PADDING_BYTES(0x3FE0);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(UniquePadSharedMemoryFormat) == 0x4000,
|
||||||
|
"UniquePadSharedMemoryFormat is an invalid size");
|
||||||
|
|
||||||
|
// This is nn::hid::detail::NpadSixAxisSensorLifo
|
||||||
|
struct NpadSixAxisSensorLifo {
|
||||||
|
Lifo<Core::HID::SixAxisSensorState, HidEntryCount> lifo;
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is nn::hid::detail::NpadInternalState
|
||||||
|
struct NpadInternalState {
|
||||||
|
Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None};
|
||||||
|
NpadJoyAssignmentMode assignment_mode{NpadJoyAssignmentMode::Dual};
|
||||||
|
NpadFullKeyColorState fullkey_color{};
|
||||||
|
NpadJoyColorState joycon_color{};
|
||||||
|
Lifo<NPadGenericState, HidEntryCount> fullkey_lifo{};
|
||||||
|
Lifo<NPadGenericState, HidEntryCount> handheld_lifo{};
|
||||||
|
Lifo<NPadGenericState, HidEntryCount> joy_dual_lifo{};
|
||||||
|
Lifo<NPadGenericState, HidEntryCount> joy_left_lifo{};
|
||||||
|
Lifo<NPadGenericState, HidEntryCount> joy_right_lifo{};
|
||||||
|
Lifo<NPadGenericState, HidEntryCount> palma_lifo{};
|
||||||
|
Lifo<NPadGenericState, HidEntryCount> system_ext_lifo{};
|
||||||
|
NpadSixAxisSensorLifo sixaxis_fullkey_lifo{};
|
||||||
|
NpadSixAxisSensorLifo sixaxis_handheld_lifo{};
|
||||||
|
NpadSixAxisSensorLifo sixaxis_dual_left_lifo{};
|
||||||
|
NpadSixAxisSensorLifo sixaxis_dual_right_lifo{};
|
||||||
|
NpadSixAxisSensorLifo sixaxis_left_lifo{};
|
||||||
|
NpadSixAxisSensorLifo sixaxis_right_lifo{};
|
||||||
|
DeviceType device_type{};
|
||||||
|
INSERT_PADDING_BYTES(0x4); // Reserved
|
||||||
|
NPadSystemProperties system_properties{};
|
||||||
|
NpadSystemButtonProperties button_properties{};
|
||||||
|
Core::HID::NpadBatteryLevel battery_level_dual{};
|
||||||
|
Core::HID::NpadBatteryLevel battery_level_left{};
|
||||||
|
Core::HID::NpadBatteryLevel battery_level_right{};
|
||||||
|
AppletFooterUiAttributes applet_footer_attributes{};
|
||||||
|
AppletFooterUiType applet_footer_type{AppletFooterUiType::None};
|
||||||
|
INSERT_PADDING_BYTES(0x5B); // Reserved
|
||||||
|
INSERT_PADDING_BYTES(0x20); // Unknown
|
||||||
|
Lifo<NpadGcTriggerState, HidEntryCount> gc_trigger_lifo{};
|
||||||
|
NpadLarkType lark_type_l_and_main{};
|
||||||
|
NpadLarkType lark_type_r{};
|
||||||
|
NpadLuciaType lucia_type{};
|
||||||
|
NpadLagerType lager_type{};
|
||||||
|
Core::HID::SixAxisSensorProperties sixaxis_fullkey_properties;
|
||||||
|
Core::HID::SixAxisSensorProperties sixaxis_handheld_properties;
|
||||||
|
Core::HID::SixAxisSensorProperties sixaxis_dual_left_properties;
|
||||||
|
Core::HID::SixAxisSensorProperties sixaxis_dual_right_properties;
|
||||||
|
Core::HID::SixAxisSensorProperties sixaxis_left_properties;
|
||||||
|
Core::HID::SixAxisSensorProperties sixaxis_right_properties;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(NpadInternalState) == 0x43F8, "NpadInternalState is an invalid size");
|
||||||
|
|
||||||
|
// This is nn::hid::detail::NpadSharedMemoryEntry
|
||||||
|
struct NpadSharedMemoryEntry {
|
||||||
|
NpadInternalState internal_state;
|
||||||
|
INSERT_PADDING_BYTES(0xC08);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(NpadSharedMemoryEntry) == 0x5000, "NpadSharedMemoryEntry is an invalid size");
|
||||||
|
|
||||||
|
// This is nn::hid::detail::NpadSharedMemoryFormat
|
||||||
|
struct NpadSharedMemoryFormat {
|
||||||
|
std::array<NpadSharedMemoryEntry, NpadCount> npad_entry;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(NpadSharedMemoryFormat) == 0x32000,
|
||||||
|
"NpadSharedMemoryFormat is an invalid size");
|
||||||
|
|
||||||
|
// This is nn::hid::detail::GestureSharedMemoryFormat
|
||||||
|
struct GestureSharedMemoryFormat {
|
||||||
|
// This is nn::hid::detail::GestureLifo
|
||||||
|
Lifo<GestureState, HidEntryCount> gesture_lifo{};
|
||||||
|
static_assert(sizeof(gesture_lifo) == 0x708, "gesture_lifo is an invalid size");
|
||||||
|
INSERT_PADDING_WORDS(0x3E);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(GestureSharedMemoryFormat) == 0x800,
|
||||||
|
"GestureSharedMemoryFormat is an invalid size");
|
||||||
|
|
||||||
|
// This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat
|
||||||
|
struct ConsoleSixAxisSensorSharedMemoryFormat {
|
||||||
|
u64 sampling_number{};
|
||||||
|
bool is_seven_six_axis_sensor_at_rest{};
|
||||||
|
INSERT_PADDING_BYTES(3); // padding
|
||||||
|
f32 verticalization_error{};
|
||||||
|
Common::Vec3f gyro_bias{};
|
||||||
|
INSERT_PADDING_BYTES(4); // padding
|
||||||
|
};
|
||||||
|
static_assert(sizeof(ConsoleSixAxisSensorSharedMemoryFormat) == 0x20,
|
||||||
|
"ConsoleSixAxisSensorSharedMemoryFormat is an invalid size");
|
||||||
|
|
||||||
|
// This is nn::hid::detail::SharedMemoryFormat
|
||||||
|
struct SharedMemoryFormat {
|
||||||
|
void Initialize() {}
|
||||||
|
|
||||||
|
DebugPadSharedMemoryFormat debug_pad;
|
||||||
|
TouchScreenSharedMemoryFormat touch_screen;
|
||||||
|
MouseSharedMemoryFormat mouse;
|
||||||
|
KeyboardSharedMemoryFormat keyboard;
|
||||||
|
DigitizerSharedMemoryFormat digitizer;
|
||||||
|
HomeButtonSharedMemoryFormat home_button;
|
||||||
|
SleepButtonSharedMemoryFormat sleep_button;
|
||||||
|
CaptureButtonSharedMemoryFormat capture_button;
|
||||||
|
InputDetectorSharedMemoryFormat input_detector;
|
||||||
|
UniquePadSharedMemoryFormat unique_pad;
|
||||||
|
NpadSharedMemoryFormat npad;
|
||||||
|
GestureSharedMemoryFormat gesture;
|
||||||
|
ConsoleSixAxisSensorSharedMemoryFormat console;
|
||||||
|
INSERT_PADDING_BYTES(0x19E0);
|
||||||
|
MouseSharedMemoryFormat debug_mouse;
|
||||||
|
INSERT_PADDING_BYTES(0x2000);
|
||||||
|
};
|
||||||
|
static_assert(offsetof(SharedMemoryFormat, debug_pad) == 0x0, "debug_pad has wrong offset");
|
||||||
|
static_assert(offsetof(SharedMemoryFormat, touch_screen) == 0x400, "touch_screen has wrong offset");
|
||||||
|
static_assert(offsetof(SharedMemoryFormat, mouse) == 0x3400, "mouse has wrong offset");
|
||||||
|
static_assert(offsetof(SharedMemoryFormat, keyboard) == 0x3800, "keyboard has wrong offset");
|
||||||
|
static_assert(offsetof(SharedMemoryFormat, digitizer) == 0x3C00, "digitizer has wrong offset");
|
||||||
|
static_assert(offsetof(SharedMemoryFormat, home_button) == 0x4C00, "home_button has wrong offset");
|
||||||
|
static_assert(offsetof(SharedMemoryFormat, sleep_button) == 0x4E00,
|
||||||
|
"sleep_button has wrong offset");
|
||||||
|
static_assert(offsetof(SharedMemoryFormat, capture_button) == 0x5000,
|
||||||
|
"capture_button has wrong offset");
|
||||||
|
static_assert(offsetof(SharedMemoryFormat, input_detector) == 0x5200,
|
||||||
|
"input_detector has wrong offset");
|
||||||
|
static_assert(offsetof(SharedMemoryFormat, npad) == 0x9A00, "npad has wrong offset");
|
||||||
|
static_assert(offsetof(SharedMemoryFormat, gesture) == 0x3BA00, "gesture has wrong offset");
|
||||||
|
static_assert(offsetof(SharedMemoryFormat, console) == 0x3C200, "console has wrong offset");
|
||||||
|
static_assert(offsetof(SharedMemoryFormat, debug_mouse) == 0x3DC00, "debug_mouse has wrong offset");
|
||||||
|
static_assert(sizeof(SharedMemoryFormat) == 0x40000, "SharedMemoryFormat is an invalid size");
|
||||||
|
|
||||||
|
} // namespace Service::HID
|
|
@ -0,0 +1,38 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/core_timing.h"
|
||||||
|
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||||
|
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||||
|
#include "core/hle/service/hid/controllers/unique_pad.h"
|
||||||
|
|
||||||
|
namespace Service::HID {
|
||||||
|
|
||||||
|
UniquePad::UniquePad(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {}
|
||||||
|
|
||||||
|
UniquePad::~UniquePad() = default;
|
||||||
|
|
||||||
|
void UniquePad::OnInit() {}
|
||||||
|
|
||||||
|
void UniquePad::OnRelease() {}
|
||||||
|
|
||||||
|
void UniquePad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||||
|
if (!smart_update) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u64 aruid = applet_resource->GetActiveAruid();
|
||||||
|
auto* data = applet_resource->GetAruidData(aruid);
|
||||||
|
|
||||||
|
if (data == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& header = data->shared_memory_format->capture_button.header;
|
||||||
|
header.timestamp = core_timing.GetGlobalTimeNs().count();
|
||||||
|
header.total_entry_count = 17;
|
||||||
|
header.entry_count = 0;
|
||||||
|
header.last_entry_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Service::HID
|
|
@ -0,0 +1,27 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||||
|
|
||||||
|
namespace Service::HID {
|
||||||
|
|
||||||
|
class UniquePad final : public ControllerBase {
|
||||||
|
public:
|
||||||
|
explicit UniquePad(Core::HID::HIDCore& hid_core_);
|
||||||
|
~UniquePad() override;
|
||||||
|
|
||||||
|
// Called when the controller is initialized
|
||||||
|
void OnInit() override;
|
||||||
|
|
||||||
|
// When the controller is released
|
||||||
|
void OnRelease() override;
|
||||||
|
|
||||||
|
// When the controller is requesting an update for the shared memory
|
||||||
|
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool smart_update{};
|
||||||
|
};
|
||||||
|
} // namespace Service::HID
|
|
@ -10,18 +10,23 @@
|
||||||
#include "core/hle/service/ipc_helpers.h"
|
#include "core/hle/service/ipc_helpers.h"
|
||||||
|
|
||||||
#include "core/hle/service/hid/controllers/applet_resource.h"
|
#include "core/hle/service/hid/controllers/applet_resource.h"
|
||||||
|
#include "core/hle/service/hid/controllers/capture_button.h"
|
||||||
#include "core/hle/service/hid/controllers/console_six_axis.h"
|
#include "core/hle/service/hid/controllers/console_six_axis.h"
|
||||||
|
#include "core/hle/service/hid/controllers/debug_mouse.h"
|
||||||
#include "core/hle/service/hid/controllers/debug_pad.h"
|
#include "core/hle/service/hid/controllers/debug_pad.h"
|
||||||
|
#include "core/hle/service/hid/controllers/digitizer.h"
|
||||||
#include "core/hle/service/hid/controllers/gesture.h"
|
#include "core/hle/service/hid/controllers/gesture.h"
|
||||||
|
#include "core/hle/service/hid/controllers/home_button.h"
|
||||||
#include "core/hle/service/hid/controllers/keyboard.h"
|
#include "core/hle/service/hid/controllers/keyboard.h"
|
||||||
#include "core/hle/service/hid/controllers/mouse.h"
|
#include "core/hle/service/hid/controllers/mouse.h"
|
||||||
#include "core/hle/service/hid/controllers/npad.h"
|
#include "core/hle/service/hid/controllers/npad.h"
|
||||||
#include "core/hle/service/hid/controllers/palma.h"
|
#include "core/hle/service/hid/controllers/palma.h"
|
||||||
#include "core/hle/service/hid/controllers/seven_six_axis.h"
|
#include "core/hle/service/hid/controllers/seven_six_axis.h"
|
||||||
#include "core/hle/service/hid/controllers/shared_memory_format.h"
|
|
||||||
#include "core/hle/service/hid/controllers/six_axis.h"
|
#include "core/hle/service/hid/controllers/six_axis.h"
|
||||||
#include "core/hle/service/hid/controllers/stubbed.h"
|
#include "core/hle/service/hid/controllers/sleep_button.h"
|
||||||
#include "core/hle/service/hid/controllers/touchscreen.h"
|
#include "core/hle/service/hid/controllers/touchscreen.h"
|
||||||
|
#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
|
||||||
|
#include "core/hle/service/hid/controllers/unique_pad.h"
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
|
|
||||||
|
@ -46,44 +51,15 @@ void ResourceManager::Initialize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
system.HIDCore().ReloadInputDevices();
|
system.HIDCore().ReloadInputDevices();
|
||||||
|
|
||||||
|
InitializeHidCommonSampler();
|
||||||
|
InitializeTouchScreenSampler();
|
||||||
|
InitializeConsoleSixAxisSampler();
|
||||||
|
InitializeAHidSampler();
|
||||||
|
|
||||||
is_initialized = true;
|
is_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceManager::InitializeController(u64 aruid) {
|
|
||||||
SharedMemoryFormat* shared_memory = nullptr;
|
|
||||||
const auto result = applet_resource->GetSharedMemoryFormat(&shared_memory, aruid);
|
|
||||||
if (result.IsError()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
debug_pad = std::make_shared<DebugPad>(system.HIDCore(), shared_memory->debug_pad);
|
|
||||||
mouse = std::make_shared<Mouse>(system.HIDCore(), shared_memory->mouse);
|
|
||||||
debug_mouse = std::make_shared<DebugMouse>(system.HIDCore(), shared_memory->debug_mouse);
|
|
||||||
keyboard = std::make_shared<Keyboard>(system.HIDCore(), shared_memory->keyboard);
|
|
||||||
unique_pad = std::make_shared<UniquePad>(system.HIDCore(), shared_memory->unique_pad.header);
|
|
||||||
npad = std::make_shared<NPad>(system.HIDCore(), shared_memory->npad, service_context);
|
|
||||||
gesture = std::make_shared<Gesture>(system.HIDCore(), shared_memory->gesture);
|
|
||||||
touch_screen = std::make_shared<TouchScreen>(system.HIDCore(), shared_memory->touch_screen);
|
|
||||||
|
|
||||||
palma = std::make_shared<Palma>(system.HIDCore(), service_context);
|
|
||||||
|
|
||||||
home_button = std::make_shared<HomeButton>(system.HIDCore(), shared_memory->home_button.header);
|
|
||||||
sleep_button =
|
|
||||||
std::make_shared<SleepButton>(system.HIDCore(), shared_memory->sleep_button.header);
|
|
||||||
capture_button =
|
|
||||||
std::make_shared<CaptureButton>(system.HIDCore(), shared_memory->capture_button.header);
|
|
||||||
digitizer = std::make_shared<Digitizer>(system.HIDCore(), shared_memory->digitizer.header);
|
|
||||||
|
|
||||||
six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad);
|
|
||||||
console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore(), shared_memory->console);
|
|
||||||
seven_six_axis = std::make_shared<SevenSixAxis>(system);
|
|
||||||
|
|
||||||
// Homebrew doesn't try to activate some controllers, so we activate them by default
|
|
||||||
npad->Activate();
|
|
||||||
six_axis->Activate();
|
|
||||||
touch_screen->Activate();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<AppletResource> ResourceManager::GetAppletResource() const {
|
std::shared_ptr<AppletResource> ResourceManager::GetAppletResource() const {
|
||||||
return applet_resource;
|
return applet_resource;
|
||||||
}
|
}
|
||||||
|
@ -165,16 +141,65 @@ Result ResourceManager::CreateAppletResource(u64 aruid) {
|
||||||
if (result.IsError()) {
|
if (result.IsError()) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Homebrew doesn't try to activate some controllers, so we activate them by default
|
||||||
|
npad->Activate();
|
||||||
|
six_axis->Activate();
|
||||||
|
touch_screen->Activate();
|
||||||
|
|
||||||
return GetNpad()->Activate(aruid);
|
return GetNpad()->Activate(aruid);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ResourceManager::CreateAppletResourceImpl(u64 aruid) {
|
Result ResourceManager::CreateAppletResourceImpl(u64 aruid) {
|
||||||
std::scoped_lock lock{shared_mutex};
|
std::scoped_lock lock{shared_mutex};
|
||||||
const auto result = applet_resource->CreateAppletResource(aruid);
|
return applet_resource->CreateAppletResource(aruid);
|
||||||
if (result.IsSuccess()) {
|
}
|
||||||
InitializeController(aruid);
|
|
||||||
}
|
void ResourceManager::InitializeHidCommonSampler() {
|
||||||
return result;
|
debug_pad = std::make_shared<DebugPad>(system.HIDCore());
|
||||||
|
mouse = std::make_shared<Mouse>(system.HIDCore());
|
||||||
|
debug_mouse = std::make_shared<DebugMouse>(system.HIDCore());
|
||||||
|
keyboard = std::make_shared<Keyboard>(system.HIDCore());
|
||||||
|
unique_pad = std::make_shared<UniquePad>(system.HIDCore());
|
||||||
|
npad = std::make_shared<NPad>(system.HIDCore(), service_context);
|
||||||
|
gesture = std::make_shared<Gesture>(system.HIDCore());
|
||||||
|
home_button = std::make_shared<HomeButton>(system.HIDCore());
|
||||||
|
sleep_button = std::make_shared<SleepButton>(system.HIDCore());
|
||||||
|
capture_button = std::make_shared<CaptureButton>(system.HIDCore());
|
||||||
|
digitizer = std::make_shared<Digitizer>(system.HIDCore());
|
||||||
|
|
||||||
|
palma = std::make_shared<Palma>(system.HIDCore(), service_context);
|
||||||
|
six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad);
|
||||||
|
|
||||||
|
debug_pad->SetAppletResource(applet_resource);
|
||||||
|
digitizer->SetAppletResource(applet_resource);
|
||||||
|
keyboard->SetAppletResource(applet_resource);
|
||||||
|
npad->SetAppletResource(applet_resource);
|
||||||
|
six_axis->SetAppletResource(applet_resource);
|
||||||
|
mouse->SetAppletResource(applet_resource);
|
||||||
|
debug_mouse->SetAppletResource(applet_resource);
|
||||||
|
home_button->SetAppletResource(applet_resource);
|
||||||
|
sleep_button->SetAppletResource(applet_resource);
|
||||||
|
capture_button->SetAppletResource(applet_resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceManager::InitializeTouchScreenSampler() {
|
||||||
|
gesture = std::make_shared<Gesture>(system.HIDCore());
|
||||||
|
touch_screen = std::make_shared<TouchScreen>(system.HIDCore());
|
||||||
|
|
||||||
|
touch_screen->SetAppletResource(applet_resource);
|
||||||
|
gesture->SetAppletResource(applet_resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceManager::InitializeConsoleSixAxisSampler() {
|
||||||
|
console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore());
|
||||||
|
seven_six_axis = std::make_shared<SevenSixAxis>(system);
|
||||||
|
|
||||||
|
console_six_axis->SetAppletResource(applet_resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceManager::InitializeAHidSampler() {
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ResourceManager::RegisterCoreAppletResource() {
|
Result ResourceManager::RegisterCoreAppletResource() {
|
||||||
|
|
|
@ -20,24 +20,23 @@ class KSharedMemory;
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
class AppletResource;
|
class AppletResource;
|
||||||
|
class CaptureButton;
|
||||||
class Controller_Stubbed;
|
class Controller_Stubbed;
|
||||||
class ConsoleSixAxis;
|
class ConsoleSixAxis;
|
||||||
|
class DebugMouse;
|
||||||
class DebugPad;
|
class DebugPad;
|
||||||
|
class Digitizer;
|
||||||
class Gesture;
|
class Gesture;
|
||||||
|
class HomeButton;
|
||||||
class Keyboard;
|
class Keyboard;
|
||||||
class Mouse;
|
class Mouse;
|
||||||
class NPad;
|
class NPad;
|
||||||
class Palma;
|
class Palma;
|
||||||
class SevenSixAxis;
|
class SevenSixAxis;
|
||||||
class SixAxis;
|
class SixAxis;
|
||||||
|
class SleepButton;
|
||||||
class TouchScreen;
|
class TouchScreen;
|
||||||
|
class UniquePad;
|
||||||
using CaptureButton = Controller_Stubbed;
|
|
||||||
using DebugMouse = Mouse;
|
|
||||||
using Digitizer = Controller_Stubbed;
|
|
||||||
using HomeButton = Controller_Stubbed;
|
|
||||||
using SleepButton = Controller_Stubbed;
|
|
||||||
using UniquePad = Controller_Stubbed;
|
|
||||||
|
|
||||||
class ResourceManager {
|
class ResourceManager {
|
||||||
|
|
||||||
|
@ -46,7 +45,6 @@ public:
|
||||||
~ResourceManager();
|
~ResourceManager();
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
void InitializeController(u64 aruid);
|
|
||||||
|
|
||||||
std::shared_ptr<AppletResource> GetAppletResource() const;
|
std::shared_ptr<AppletResource> GetAppletResource() const;
|
||||||
std::shared_ptr<CaptureButton> GetCaptureButton() const;
|
std::shared_ptr<CaptureButton> GetCaptureButton() const;
|
||||||
|
@ -88,6 +86,10 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Result CreateAppletResourceImpl(u64 aruid);
|
Result CreateAppletResourceImpl(u64 aruid);
|
||||||
|
void InitializeHidCommonSampler();
|
||||||
|
void InitializeTouchScreenSampler();
|
||||||
|
void InitializeConsoleSixAxisSampler();
|
||||||
|
void InitializeAHidSampler();
|
||||||
|
|
||||||
bool is_initialized{false};
|
bool is_initialized{false};
|
||||||
|
|
||||||
|
|
|
@ -686,7 +686,8 @@ public:
|
||||||
} else {
|
} else {
|
||||||
this->m_memory.WriteBlockUnsafe(this->m_addr, this->data(), this->size_bytes());
|
this->m_memory.WriteBlockUnsafe(this->m_addr, this->data(), this->size_bytes());
|
||||||
}
|
}
|
||||||
} else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
|
} else if constexpr ((FLAGS & GuestMemoryFlags::Safe) ||
|
||||||
|
(FLAGS & GuestMemoryFlags::Cached)) {
|
||||||
this->m_memory.InvalidateRegion(this->m_addr, this->size_bytes());
|
this->m_memory.InvalidateRegion(this->m_addr, this->size_bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -403,59 +403,63 @@ void Config::SavePlayerValues(const std::size_t player_index) {
|
||||||
// No custom profile selected
|
// No custom profile selected
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
WriteSetting(std::string(player_prefix).append("profile_name"), player.profile_name,
|
WriteStringSetting(std::string(player_prefix).append("profile_name"), player.profile_name,
|
||||||
std::make_optional(std::string("")));
|
std::make_optional(std::string("")));
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteSetting(std::string(player_prefix).append("type"), static_cast<u8>(player.controller_type),
|
WriteIntegerSetting(
|
||||||
std::make_optional(static_cast<u8>(Settings::ControllerType::ProController)));
|
std::string(player_prefix).append("type"), static_cast<u8>(player.controller_type),
|
||||||
|
std::make_optional(static_cast<u8>(Settings::ControllerType::ProController)));
|
||||||
|
|
||||||
if (!player_prefix.empty() || !Settings::IsConfiguringGlobal()) {
|
if (!player_prefix.empty() || !Settings::IsConfiguringGlobal()) {
|
||||||
WriteSetting(std::string(player_prefix).append("connected"), player.connected,
|
WriteBooleanSetting(std::string(player_prefix).append("connected"), player.connected,
|
||||||
std::make_optional(player_index == 0));
|
std::make_optional(player_index == 0));
|
||||||
WriteSetting(std::string(player_prefix).append("vibration_enabled"),
|
WriteIntegerSetting(std::string(player_prefix).append("vibration_enabled"),
|
||||||
player.vibration_enabled, std::make_optional(true));
|
player.vibration_enabled, std::make_optional(true));
|
||||||
WriteSetting(std::string(player_prefix).append("vibration_strength"),
|
WriteIntegerSetting(std::string(player_prefix).append("vibration_strength"),
|
||||||
player.vibration_strength, std::make_optional(100));
|
player.vibration_strength, std::make_optional(100));
|
||||||
WriteSetting(std::string(player_prefix).append("body_color_left"), player.body_color_left,
|
WriteIntegerSetting(std::string(player_prefix).append("body_color_left"),
|
||||||
std::make_optional(Settings::JOYCON_BODY_NEON_BLUE));
|
player.body_color_left,
|
||||||
WriteSetting(std::string(player_prefix).append("body_color_right"), player.body_color_right,
|
std::make_optional(Settings::JOYCON_BODY_NEON_BLUE));
|
||||||
std::make_optional(Settings::JOYCON_BODY_NEON_RED));
|
WriteIntegerSetting(std::string(player_prefix).append("body_color_right"),
|
||||||
WriteSetting(std::string(player_prefix).append("button_color_left"),
|
player.body_color_right,
|
||||||
player.button_color_left,
|
std::make_optional(Settings::JOYCON_BODY_NEON_RED));
|
||||||
std::make_optional(Settings::JOYCON_BUTTONS_NEON_BLUE));
|
WriteIntegerSetting(std::string(player_prefix).append("button_color_left"),
|
||||||
WriteSetting(std::string(player_prefix).append("button_color_right"),
|
player.button_color_left,
|
||||||
player.button_color_right,
|
std::make_optional(Settings::JOYCON_BUTTONS_NEON_BLUE));
|
||||||
std::make_optional(Settings::JOYCON_BUTTONS_NEON_RED));
|
WriteIntegerSetting(std::string(player_prefix).append("button_color_right"),
|
||||||
|
player.button_color_right,
|
||||||
|
std::make_optional(Settings::JOYCON_BUTTONS_NEON_RED));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::SaveTouchscreenValues() {
|
void Config::SaveTouchscreenValues() {
|
||||||
const auto& touchscreen = Settings::values.touchscreen;
|
const auto& touchscreen = Settings::values.touchscreen;
|
||||||
|
|
||||||
WriteSetting(std::string("touchscreen_enabled"), touchscreen.enabled, std::make_optional(true));
|
WriteBooleanSetting(std::string("touchscreen_enabled"), touchscreen.enabled,
|
||||||
|
std::make_optional(true));
|
||||||
|
|
||||||
WriteSetting(std::string("touchscreen_angle"), touchscreen.rotation_angle,
|
WriteIntegerSetting(std::string("touchscreen_angle"), touchscreen.rotation_angle,
|
||||||
std::make_optional(static_cast<u32>(0)));
|
std::make_optional(static_cast<u32>(0)));
|
||||||
WriteSetting(std::string("touchscreen_diameter_x"), touchscreen.diameter_x,
|
WriteIntegerSetting(std::string("touchscreen_diameter_x"), touchscreen.diameter_x,
|
||||||
std::make_optional(static_cast<u32>(15)));
|
std::make_optional(static_cast<u32>(15)));
|
||||||
WriteSetting(std::string("touchscreen_diameter_y"), touchscreen.diameter_y,
|
WriteIntegerSetting(std::string("touchscreen_diameter_y"), touchscreen.diameter_y,
|
||||||
std::make_optional(static_cast<u32>(15)));
|
std::make_optional(static_cast<u32>(15)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::SaveMotionTouchValues() {
|
void Config::SaveMotionTouchValues() {
|
||||||
BeginArray(std::string("touch_from_button_maps"));
|
BeginArray(std::string("touch_from_button_maps"));
|
||||||
for (std::size_t p = 0; p < Settings::values.touch_from_button_maps.size(); ++p) {
|
for (std::size_t p = 0; p < Settings::values.touch_from_button_maps.size(); ++p) {
|
||||||
SetArrayIndex(static_cast<int>(p));
|
SetArrayIndex(static_cast<int>(p));
|
||||||
WriteSetting(std::string("name"), Settings::values.touch_from_button_maps[p].name,
|
WriteStringSetting(std::string("name"), Settings::values.touch_from_button_maps[p].name,
|
||||||
std::make_optional(std::string("default")));
|
std::make_optional(std::string("default")));
|
||||||
|
|
||||||
BeginArray(std::string("entries"));
|
BeginArray(std::string("entries"));
|
||||||
for (std::size_t q = 0; q < Settings::values.touch_from_button_maps[p].buttons.size();
|
for (std::size_t q = 0; q < Settings::values.touch_from_button_maps[p].buttons.size();
|
||||||
++q) {
|
++q) {
|
||||||
SetArrayIndex(static_cast<int>(q));
|
SetArrayIndex(static_cast<int>(q));
|
||||||
WriteSetting(std::string("bind"),
|
WriteStringSetting(std::string("bind"),
|
||||||
Settings::values.touch_from_button_maps[p].buttons[q]);
|
Settings::values.touch_from_button_maps[p].buttons[q]);
|
||||||
}
|
}
|
||||||
EndArray(); // entries
|
EndArray(); // entries
|
||||||
}
|
}
|
||||||
|
@ -520,16 +524,16 @@ void Config::SaveCoreValues() {
|
||||||
void Config::SaveDataStorageValues() {
|
void Config::SaveDataStorageValues() {
|
||||||
BeginGroup(Settings::TranslateCategory(Settings::Category::DataStorage));
|
BeginGroup(Settings::TranslateCategory(Settings::Category::DataStorage));
|
||||||
|
|
||||||
WriteSetting(std::string("nand_directory"), FS::GetYuzuPathString(FS::YuzuPath::NANDDir),
|
WriteStringSetting(std::string("nand_directory"), FS::GetYuzuPathString(FS::YuzuPath::NANDDir),
|
||||||
std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::NANDDir)));
|
std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::NANDDir)));
|
||||||
WriteSetting(std::string("sdmc_directory"), FS::GetYuzuPathString(FS::YuzuPath::SDMCDir),
|
WriteStringSetting(std::string("sdmc_directory"), FS::GetYuzuPathString(FS::YuzuPath::SDMCDir),
|
||||||
std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::SDMCDir)));
|
std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::SDMCDir)));
|
||||||
WriteSetting(std::string("load_directory"), FS::GetYuzuPathString(FS::YuzuPath::LoadDir),
|
WriteStringSetting(std::string("load_directory"), FS::GetYuzuPathString(FS::YuzuPath::LoadDir),
|
||||||
std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::LoadDir)));
|
std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::LoadDir)));
|
||||||
WriteSetting(std::string("dump_directory"), FS::GetYuzuPathString(FS::YuzuPath::DumpDir),
|
WriteStringSetting(std::string("dump_directory"), FS::GetYuzuPathString(FS::YuzuPath::DumpDir),
|
||||||
std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::DumpDir)));
|
std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::DumpDir)));
|
||||||
WriteSetting(std::string("tas_directory"), FS::GetYuzuPathString(FS::YuzuPath::TASDir),
|
WriteStringSetting(std::string("tas_directory"), FS::GetYuzuPathString(FS::YuzuPath::TASDir),
|
||||||
std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::TASDir)));
|
std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::TASDir)));
|
||||||
|
|
||||||
WriteCategory(Settings::Category::DataStorage);
|
WriteCategory(Settings::Category::DataStorage);
|
||||||
|
|
||||||
|
@ -540,7 +544,7 @@ void Config::SaveDebuggingValues() {
|
||||||
BeginGroup(Settings::TranslateCategory(Settings::Category::Debugging));
|
BeginGroup(Settings::TranslateCategory(Settings::Category::Debugging));
|
||||||
|
|
||||||
// Intentionally not using the QT default setting as this is intended to be changed in the ini
|
// Intentionally not using the QT default setting as this is intended to be changed in the ini
|
||||||
WriteSetting(std::string("record_frame_times"), Settings::values.record_frame_times);
|
WriteBooleanSetting(std::string("record_frame_times"), Settings::values.record_frame_times);
|
||||||
|
|
||||||
WriteCategory(Settings::Category::Debugging);
|
WriteCategory(Settings::Category::Debugging);
|
||||||
WriteCategory(Settings::Category::DebuggingGraphics);
|
WriteCategory(Settings::Category::DebuggingGraphics);
|
||||||
|
@ -564,11 +568,13 @@ void Config::SaveDisabledAddOnValues() {
|
||||||
BeginArray(std::string(""));
|
BeginArray(std::string(""));
|
||||||
for (const auto& elem : Settings::values.disabled_addons) {
|
for (const auto& elem : Settings::values.disabled_addons) {
|
||||||
SetArrayIndex(i);
|
SetArrayIndex(i);
|
||||||
WriteSetting(std::string("title_id"), elem.first, std::make_optional(static_cast<u64>(0)));
|
WriteIntegerSetting(std::string("title_id"), elem.first,
|
||||||
|
std::make_optional(static_cast<u64>(0)));
|
||||||
BeginArray(std::string("disabled"));
|
BeginArray(std::string("disabled"));
|
||||||
for (std::size_t j = 0; j < elem.second.size(); ++j) {
|
for (std::size_t j = 0; j < elem.second.size(); ++j) {
|
||||||
SetArrayIndex(static_cast<int>(j));
|
SetArrayIndex(static_cast<int>(j));
|
||||||
WriteSetting(std::string("d"), elem.second[j], std::make_optional(std::string("")));
|
WriteStringSetting(std::string("d"), elem.second[j],
|
||||||
|
std::make_optional(std::string("")));
|
||||||
}
|
}
|
||||||
EndArray(); // disabled
|
EndArray(); // disabled
|
||||||
++i;
|
++i;
|
||||||
|
@ -609,8 +615,8 @@ void Config::SaveRendererValues() {
|
||||||
void Config::SaveScreenshotValues() {
|
void Config::SaveScreenshotValues() {
|
||||||
BeginGroup(Settings::TranslateCategory(Settings::Category::Screenshots));
|
BeginGroup(Settings::TranslateCategory(Settings::Category::Screenshots));
|
||||||
|
|
||||||
WriteSetting(std::string("screenshot_path"),
|
WriteStringSetting(std::string("screenshot_path"),
|
||||||
FS::GetYuzuPathString(FS::YuzuPath::ScreenshotsDir));
|
FS::GetYuzuPathString(FS::YuzuPath::ScreenshotsDir));
|
||||||
WriteCategory(Settings::Category::Screenshots);
|
WriteCategory(Settings::Category::Screenshots);
|
||||||
|
|
||||||
EndGroup();
|
EndGroup();
|
||||||
|
@ -746,46 +752,70 @@ bool Config::Exists(const std::string& section, const std::string& key) const {
|
||||||
return !value.empty();
|
return !value.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Type>
|
void Config::WriteBooleanSetting(const std::string& key, const bool& value,
|
||||||
void Config::WriteSetting(const std::string& key, const Type& value,
|
const std::optional<bool>& default_value,
|
||||||
const std::optional<Type>& default_value,
|
const std::optional<bool>& use_global) {
|
||||||
const std::optional<bool>& use_global) {
|
std::optional<std::string> string_default = std::nullopt;
|
||||||
std::string full_key = GetFullKey(key, false);
|
if (default_value.has_value()) {
|
||||||
|
string_default = std::make_optional(ToString(default_value.value()));
|
||||||
std::string saved_value;
|
|
||||||
std::string string_default;
|
|
||||||
if constexpr (std::is_same_v<Type, std::string>) {
|
|
||||||
saved_value.append(AdjustOutputString(value));
|
|
||||||
if (default_value.has_value()) {
|
|
||||||
string_default.append(AdjustOutputString(default_value.value()));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
saved_value.append(AdjustOutputString(ToString(value)));
|
|
||||||
if (default_value.has_value()) {
|
|
||||||
string_default.append(ToString(default_value.value()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
WritePreparedSetting(key, AdjustOutputString(ToString(value)), string_default, use_global);
|
||||||
|
}
|
||||||
|
|
||||||
if (default_value.has_value() && use_global.has_value()) {
|
template <typename T>
|
||||||
|
std::enable_if_t<std::is_integral_v<T>> Config::WriteIntegerSetting(
|
||||||
|
const std::string& key, const T& value, const std::optional<T>& default_value,
|
||||||
|
const std::optional<bool>& use_global) {
|
||||||
|
std::optional<std::string> string_default = std::nullopt;
|
||||||
|
if (default_value.has_value()) {
|
||||||
|
string_default = std::make_optional(ToString(default_value.value()));
|
||||||
|
}
|
||||||
|
WritePreparedSetting(key, AdjustOutputString(ToString(value)), string_default, use_global);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Config::WriteDoubleSetting(const std::string& key, const double& value,
|
||||||
|
const std::optional<double>& default_value,
|
||||||
|
const std::optional<bool>& use_global) {
|
||||||
|
std::optional<std::string> string_default = std::nullopt;
|
||||||
|
if (default_value.has_value()) {
|
||||||
|
string_default = std::make_optional(ToString(default_value.value()));
|
||||||
|
}
|
||||||
|
WritePreparedSetting(key, AdjustOutputString(ToString(value)), string_default, use_global);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Config::WriteStringSetting(const std::string& key, const std::string& value,
|
||||||
|
const std::optional<std::string>& default_value,
|
||||||
|
const std::optional<bool>& use_global) {
|
||||||
|
std::optional string_default = default_value;
|
||||||
|
if (default_value.has_value()) {
|
||||||
|
string_default.value().append(AdjustOutputString(default_value.value()));
|
||||||
|
}
|
||||||
|
WritePreparedSetting(key, AdjustOutputString(value), string_default, use_global);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Config::WritePreparedSetting(const std::string& key, const std::string& adjusted_value,
|
||||||
|
const std::optional<std::string>& adjusted_default_value,
|
||||||
|
const std::optional<bool>& use_global) {
|
||||||
|
std::string full_key = GetFullKey(key, false);
|
||||||
|
if (adjusted_default_value.has_value() && use_global.has_value()) {
|
||||||
if (!global) {
|
if (!global) {
|
||||||
WriteSettingInternal(std::string(full_key).append("\\global"),
|
WriteString(std::string(full_key).append("\\global"), ToString(use_global.value()));
|
||||||
ToString(use_global.value()));
|
|
||||||
}
|
}
|
||||||
if (global || use_global.value() == false) {
|
if (global || use_global.value() == false) {
|
||||||
WriteSettingInternal(std::string(full_key).append("\\default"),
|
WriteString(std::string(full_key).append("\\default"),
|
||||||
ToString(string_default == saved_value));
|
ToString(adjusted_default_value == adjusted_value));
|
||||||
WriteSettingInternal(full_key, saved_value);
|
WriteString(full_key, adjusted_value);
|
||||||
}
|
}
|
||||||
} else if (default_value.has_value() && !use_global.has_value()) {
|
} else if (adjusted_default_value.has_value() && !use_global.has_value()) {
|
||||||
WriteSettingInternal(std::string(full_key).append("\\default"),
|
WriteString(std::string(full_key).append("\\default"),
|
||||||
ToString(string_default == saved_value));
|
ToString(adjusted_default_value == adjusted_value));
|
||||||
WriteSettingInternal(full_key, saved_value);
|
WriteString(full_key, adjusted_value);
|
||||||
} else {
|
} else {
|
||||||
WriteSettingInternal(full_key, saved_value);
|
WriteString(full_key, adjusted_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::WriteSettingInternal(const std::string& key, const std::string& value) {
|
void Config::WriteString(const std::string& key, const std::string& value) {
|
||||||
config->SetValue(GetSection().c_str(), key.c_str(), value.c_str());
|
config->SetValue(GetSection().c_str(), key.c_str(), value.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -861,17 +891,17 @@ void Config::WriteSettingGeneric(const Settings::BasicSetting* const setting) {
|
||||||
std::string key = AdjustKey(setting->GetLabel());
|
std::string key = AdjustKey(setting->GetLabel());
|
||||||
if (setting->Switchable()) {
|
if (setting->Switchable()) {
|
||||||
if (!global) {
|
if (!global) {
|
||||||
WriteSetting(std::string(key).append("\\use_global"), setting->UsingGlobal());
|
WriteBooleanSetting(std::string(key).append("\\use_global"), setting->UsingGlobal());
|
||||||
}
|
}
|
||||||
if (global || !setting->UsingGlobal()) {
|
if (global || !setting->UsingGlobal()) {
|
||||||
WriteSetting(std::string(key).append("\\default"),
|
WriteBooleanSetting(std::string(key).append("\\default"),
|
||||||
setting->ToString() == setting->DefaultToString());
|
setting->ToString() == setting->DefaultToString());
|
||||||
WriteSetting(key, setting->ToString());
|
WriteStringSetting(key, setting->ToString());
|
||||||
}
|
}
|
||||||
} else if (global) {
|
} else if (global) {
|
||||||
WriteSetting(std::string(key).append("\\default"),
|
WriteBooleanSetting(std::string(key).append("\\default"),
|
||||||
setting->ToString() == setting->DefaultToString());
|
setting->ToString() == setting->DefaultToString());
|
||||||
WriteSetting(key, setting->ToString());
|
WriteStringSetting(key, setting->ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,11 +154,20 @@ protected:
|
||||||
* @param use_global Specifies if the custom or global config should be in use, for custom
|
* @param use_global Specifies if the custom or global config should be in use, for custom
|
||||||
* configs
|
* configs
|
||||||
*/
|
*/
|
||||||
template <typename Type = int>
|
void WriteBooleanSetting(const std::string& key, const bool& value,
|
||||||
void WriteSetting(const std::string& key, const Type& value,
|
const std::optional<bool>& default_value = std::nullopt,
|
||||||
const std::optional<Type>& default_value = std::nullopt,
|
const std::optional<bool>& use_global = std::nullopt);
|
||||||
const std::optional<bool>& use_global = std::nullopt);
|
template <typename T>
|
||||||
void WriteSettingInternal(const std::string& key, const std::string& value);
|
std::enable_if_t<std::is_integral_v<T>> WriteIntegerSetting(
|
||||||
|
const std::string& key, const T& value,
|
||||||
|
const std::optional<T>& default_value = std::nullopt,
|
||||||
|
const std::optional<bool>& use_global = std::nullopt);
|
||||||
|
void WriteDoubleSetting(const std::string& key, const double& value,
|
||||||
|
const std::optional<double>& default_value = std::nullopt,
|
||||||
|
const std::optional<bool>& use_global = std::nullopt);
|
||||||
|
void WriteStringSetting(const std::string& key, const std::string& value,
|
||||||
|
const std::optional<std::string>& default_value = std::nullopt,
|
||||||
|
const std::optional<bool>& use_global = std::nullopt);
|
||||||
|
|
||||||
void ReadCategory(Settings::Category category);
|
void ReadCategory(Settings::Category category);
|
||||||
void WriteCategory(Settings::Category category);
|
void WriteCategory(Settings::Category category);
|
||||||
|
@ -175,8 +184,10 @@ protected:
|
||||||
return value_ ? "true" : "false";
|
return value_ ? "true" : "false";
|
||||||
} else if constexpr (std::is_same_v<T, u64>) {
|
} else if constexpr (std::is_same_v<T, u64>) {
|
||||||
return std::to_string(static_cast<u64>(value_));
|
return std::to_string(static_cast<u64>(value_));
|
||||||
} else {
|
} else if constexpr (std::is_same_v<T, s64>) {
|
||||||
return std::to_string(static_cast<s64>(value_));
|
return std::to_string(static_cast<s64>(value_));
|
||||||
|
} else {
|
||||||
|
return std::to_string(value_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,9 +208,13 @@ protected:
|
||||||
const bool global;
|
const bool global;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline static std::array<char, 19> special_characters = {'!', '#', '$', '%', '^', '&', '*',
|
void WritePreparedSetting(const std::string& key, const std::string& adjusted_value,
|
||||||
'|', ';', '\'', '\"', ',', '<', '.',
|
const std::optional<std::string>& adjusted_default_value,
|
||||||
'>', '?', '`', '~', '='};
|
const std::optional<bool>& use_global);
|
||||||
|
void WriteString(const std::string& key, const std::string& value);
|
||||||
|
|
||||||
|
inline static std::array<char, 18> special_characters = {
|
||||||
|
'!', '#', '$', '%', '^', '&', '*', '|', ';', '\'', '\"', ',', '<', '>', '?', '`', '~', '='};
|
||||||
|
|
||||||
struct ConfigArray {
|
struct ConfigArray {
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
|
@ -228,7 +228,7 @@ void MaxwellDMA::CopyBlockLinearToPitch() {
|
||||||
|
|
||||||
Core::Memory::GpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead> tmp_read_buffer(
|
Core::Memory::GpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead> tmp_read_buffer(
|
||||||
memory_manager, src_operand.address, src_size, &read_buffer);
|
memory_manager, src_operand.address, src_size, &read_buffer);
|
||||||
Core::Memory::GpuGuestMemoryScoped<u8, Core::Memory::GuestMemoryFlags::SafeReadCachedWrite>
|
Core::Memory::GpuGuestMemoryScoped<u8, Core::Memory::GuestMemoryFlags::UnsafeReadCachedWrite>
|
||||||
tmp_write_buffer(memory_manager, dst_operand.address, dst_size, &write_buffer);
|
tmp_write_buffer(memory_manager, dst_operand.address, dst_size, &write_buffer);
|
||||||
|
|
||||||
UnswizzleSubrect(tmp_write_buffer, tmp_read_buffer, bytes_per_pixel, width, height, depth,
|
UnswizzleSubrect(tmp_write_buffer, tmp_read_buffer, bytes_per_pixel, width, height, depth,
|
||||||
|
@ -292,7 +292,7 @@ void MaxwellDMA::CopyPitchToBlockLinear() {
|
||||||
GPUVAddr dst_addr = regs.offset_out;
|
GPUVAddr dst_addr = regs.offset_out;
|
||||||
Core::Memory::GpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead> tmp_read_buffer(
|
Core::Memory::GpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead> tmp_read_buffer(
|
||||||
memory_manager, src_addr, src_size, &read_buffer);
|
memory_manager, src_addr, src_size, &read_buffer);
|
||||||
Core::Memory::GpuGuestMemoryScoped<u8, Core::Memory::GuestMemoryFlags::SafeReadCachedWrite>
|
Core::Memory::GpuGuestMemoryScoped<u8, Core::Memory::GuestMemoryFlags::UnsafeReadCachedWrite>
|
||||||
tmp_write_buffer(memory_manager, dst_addr, dst_size, &write_buffer);
|
tmp_write_buffer(memory_manager, dst_addr, dst_size, &write_buffer);
|
||||||
|
|
||||||
// If the input is linear and the output is tiled, swizzle the input and copy it over.
|
// If the input is linear and the output is tiled, swizzle the input and copy it over.
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue