early-access version 4041
This commit is contained in:
parent
05d9419e78
commit
d950efa077
105 changed files with 10268 additions and 8920 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
580
dist/languages/ar.ts
vendored
580
dist/languages/ar.ts
vendored
File diff suppressed because it is too large
Load diff
564
dist/languages/ca.ts
vendored
564
dist/languages/ca.ts
vendored
File diff suppressed because it is too large
Load diff
841
dist/languages/cs.ts
vendored
841
dist/languages/cs.ts
vendored
File diff suppressed because it is too large
Load diff
564
dist/languages/da.ts
vendored
564
dist/languages/da.ts
vendored
File diff suppressed because it is too large
Load diff
610
dist/languages/de.ts
vendored
610
dist/languages/de.ts
vendored
File diff suppressed because it is too large
Load diff
564
dist/languages/el.ts
vendored
564
dist/languages/el.ts
vendored
File diff suppressed because it is too large
Load diff
692
dist/languages/es.ts
vendored
692
dist/languages/es.ts
vendored
File diff suppressed because it is too large
Load diff
592
dist/languages/fr.ts
vendored
592
dist/languages/fr.ts
vendored
File diff suppressed because it is too large
Load diff
657
dist/languages/hu.ts
vendored
657
dist/languages/hu.ts
vendored
File diff suppressed because it is too large
Load diff
564
dist/languages/id.ts
vendored
564
dist/languages/id.ts
vendored
File diff suppressed because it is too large
Load diff
564
dist/languages/it.ts
vendored
564
dist/languages/it.ts
vendored
File diff suppressed because it is too large
Load diff
564
dist/languages/ja_JP.ts
vendored
564
dist/languages/ja_JP.ts
vendored
File diff suppressed because it is too large
Load diff
564
dist/languages/ko_KR.ts
vendored
564
dist/languages/ko_KR.ts
vendored
File diff suppressed because it is too large
Load diff
564
dist/languages/nb.ts
vendored
564
dist/languages/nb.ts
vendored
File diff suppressed because it is too large
Load diff
564
dist/languages/nl.ts
vendored
564
dist/languages/nl.ts
vendored
File diff suppressed because it is too large
Load diff
566
dist/languages/pl.ts
vendored
566
dist/languages/pl.ts
vendored
File diff suppressed because it is too large
Load diff
657
dist/languages/pt_BR.ts
vendored
657
dist/languages/pt_BR.ts
vendored
File diff suppressed because it is too large
Load diff
657
dist/languages/pt_PT.ts
vendored
657
dist/languages/pt_PT.ts
vendored
File diff suppressed because it is too large
Load diff
564
dist/languages/ru_RU.ts
vendored
564
dist/languages/ru_RU.ts
vendored
File diff suppressed because it is too large
Load diff
564
dist/languages/sv.ts
vendored
564
dist/languages/sv.ts
vendored
File diff suppressed because it is too large
Load diff
564
dist/languages/tr_TR.ts
vendored
564
dist/languages/tr_TR.ts
vendored
File diff suppressed because it is too large
Load diff
564
dist/languages/uk.ts
vendored
564
dist/languages/uk.ts
vendored
File diff suppressed because it is too large
Load diff
564
dist/languages/vi.ts
vendored
564
dist/languages/vi.ts
vendored
File diff suppressed because it is too large
Load diff
564
dist/languages/vi_VN.ts
vendored
564
dist/languages/vi_VN.ts
vendored
File diff suppressed because it is too large
Load diff
564
dist/languages/zh_CN.ts
vendored
564
dist/languages/zh_CN.ts
vendored
File diff suppressed because it is too large
Load diff
566
dist/languages/zh_TW.ts
vendored
566
dist/languages/zh_TW.ts
vendored
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()
|
||||||
|
|
188
src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/model/OverlayControl.kt
Executable file
188
src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/model/OverlayControl.kt
Executable file
|
@ -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>)
|
||||||
}
|
}
|
||||||
|
|
37
src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/PreferenceUtil.kt
Executable file
37
src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/PreferenceUtil.kt
Executable file
|
@ -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,41 +21,12 @@ class KSharedMemory;
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
struct SharedMemoryFormat;
|
struct SharedMemoryFormat;
|
||||||
|
class AppletResource;
|
||||||
|
class NPadResource;
|
||||||
|
|
||||||
class AppletResource {
|
|
||||||
public:
|
|
||||||
explicit AppletResource(Core::System& system_);
|
|
||||||
~AppletResource();
|
|
||||||
|
|
||||||
Result CreateAppletResource(u64 aruid);
|
|
||||||
|
|
||||||
Result RegisterAppletResourceUserId(u64 aruid, bool enable_input);
|
|
||||||
void UnregisterAppletResourceUserId(u64 aruid);
|
|
||||||
|
|
||||||
void FreeAppletResourceId(u64 aruid);
|
|
||||||
|
|
||||||
u64 GetActiveAruid();
|
|
||||||
Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid);
|
|
||||||
Result GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format, u64 aruid);
|
|
||||||
|
|
||||||
u64 GetIndexFromAruid(u64 aruid);
|
|
||||||
|
|
||||||
Result DestroySevenSixAxisTransferMemory();
|
|
||||||
|
|
||||||
void EnableInput(u64 aruid, bool is_enabled);
|
|
||||||
void EnableSixAxisSensor(u64 aruid, bool is_enabled);
|
|
||||||
void EnablePadInput(u64 aruid, bool is_enabled);
|
|
||||||
void EnableTouchScreen(u64 aruid, bool is_enabled);
|
|
||||||
void SetIsPalmaConnectable(u64 aruid, bool is_connectable);
|
|
||||||
void EnablePalmaBoostMode(u64 aruid, bool is_enabled);
|
|
||||||
|
|
||||||
Result RegisterCoreAppletResource();
|
|
||||||
Result UnregisterCoreAppletResource();
|
|
||||||
|
|
||||||
private:
|
|
||||||
static constexpr std::size_t AruidIndexMax = 0x20;
|
static constexpr std::size_t AruidIndexMax = 0x20;
|
||||||
|
|
||||||
enum RegistrationStatus : u32 {
|
enum class RegistrationStatus : u32 {
|
||||||
None,
|
None,
|
||||||
Initialized,
|
Initialized,
|
||||||
PendingDelete,
|
PendingDelete,
|
||||||
|
@ -87,11 +59,63 @@ private:
|
||||||
SharedMemoryFormat* shared_memory_format{nullptr};
|
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 {
|
||||||
|
public:
|
||||||
|
explicit AppletResource(Core::System& system_);
|
||||||
|
~AppletResource();
|
||||||
|
|
||||||
|
Result CreateAppletResource(u64 aruid);
|
||||||
|
|
||||||
|
Result RegisterAppletResourceUserId(u64 aruid, bool enable_input);
|
||||||
|
void UnregisterAppletResourceUserId(u64 aruid);
|
||||||
|
|
||||||
|
void FreeAppletResourceId(u64 aruid);
|
||||||
|
|
||||||
|
u64 GetActiveAruid();
|
||||||
|
Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, 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);
|
||||||
|
|
||||||
|
Result DestroySevenSixAxisTransferMemory();
|
||||||
|
|
||||||
|
void EnableInput(u64 aruid, bool is_enabled);
|
||||||
|
void EnableSixAxisSensor(u64 aruid, bool is_enabled);
|
||||||
|
void EnablePadInput(u64 aruid, bool is_enabled);
|
||||||
|
void EnableTouchScreen(u64 aruid, bool is_enabled);
|
||||||
|
void SetIsPalmaConnectable(u64 aruid, bool is_connectable);
|
||||||
|
void EnablePalmaBoostMode(u64 aruid, bool is_enabled);
|
||||||
|
|
||||||
|
Result RegisterCoreAppletResource();
|
||||||
|
Result UnregisterCoreAppletResource();
|
||||||
|
|
||||||
|
private:
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
38
src/core/hle/service/hid/controllers/capture_button.cpp
Executable file
38
src/core/hle/service/hid/controllers/capture_button.cpp
Executable file
|
@ -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
|
27
src/core/hle/service/hid/controllers/capture_button.h
Executable file
27
src/core/hle/service/hid/controllers/capture_button.h
Executable file
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
63
src/core/hle/service/hid/controllers/debug_mouse.cpp
Executable file
63
src/core/hle/service/hid/controllers/debug_mouse.cpp
Executable file
|
@ -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
|
34
src/core/hle/service/hid/controllers/debug_mouse.h
Executable file
34
src/core/hle/service/hid/controllers/debug_mouse.h
Executable file
|
@ -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
|
||||||
|
|
38
src/core/hle/service/hid/controllers/digitizer.cpp
Executable file
38
src/core/hle/service/hid/controllers/digitizer.cpp
Executable file
|
@ -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
|
27
src/core/hle/service/hid/controllers/digitizer.h
Executable file
27
src/core/hle/service/hid/controllers/digitizer.h
Executable file
|
@ -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{};
|
||||||
|
|
38
src/core/hle/service/hid/controllers/home_button.cpp
Executable file
38
src/core/hle/service/hid/controllers/home_button.cpp
Executable file
|
@ -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
|
27
src/core/hle/service/hid/controllers/home_button.h
Executable file
27
src/core/hle/service/hid/controllers/home_button.h
Executable file
|
@ -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];
|
||||||
|
if (controller.styleset_changed_event) {
|
||||||
service_context.CloseEvent(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 = {};
|
||||||
|
|
38
src/core/hle/service/hid/controllers/sleep_button.cpp
Executable file
38
src/core/hle/service/hid/controllers/sleep_button.cpp
Executable file
|
@ -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
|
27
src/core/hle/service/hid/controllers/sleep_button.h
Executable file
27
src/core/hle/service/hid/controllers/sleep_button.h
Executable file
|
@ -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{};
|
||||||
|
|
240
src/core/hle/service/hid/controllers/types/shared_memory_format.h
Executable file
240
src/core/hle/service/hid/controllers/types/shared_memory_format.h
Executable file
|
@ -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
|
38
src/core/hle/service/hid/controllers/unique_pad.cpp
Executable file
38
src/core/hle/service/hid/controllers/unique_pad.cpp
Executable file
|
@ -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
|
27
src/core/hle/service/hid/controllers/unique_pad.h
Executable file
27
src/core/hle/service/hid/controllers/unique_pad.h
Executable file
|
@ -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);
|
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
|
void ResourceManager::InitializeHidCommonSampler() {
|
||||||
|
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,28 +403,31 @@ 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::string(player_prefix).append("type"), static_cast<u8>(player.controller_type),
|
||||||
std::make_optional(static_cast<u8>(Settings::ControllerType::ProController)));
|
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"),
|
||||||
|
player.body_color_left,
|
||||||
std::make_optional(Settings::JOYCON_BODY_NEON_BLUE));
|
std::make_optional(Settings::JOYCON_BODY_NEON_BLUE));
|
||||||
WriteSetting(std::string(player_prefix).append("body_color_right"), player.body_color_right,
|
WriteIntegerSetting(std::string(player_prefix).append("body_color_right"),
|
||||||
|
player.body_color_right,
|
||||||
std::make_optional(Settings::JOYCON_BODY_NEON_RED));
|
std::make_optional(Settings::JOYCON_BODY_NEON_RED));
|
||||||
WriteSetting(std::string(player_prefix).append("button_color_left"),
|
WriteIntegerSetting(std::string(player_prefix).append("button_color_left"),
|
||||||
player.button_color_left,
|
player.button_color_left,
|
||||||
std::make_optional(Settings::JOYCON_BUTTONS_NEON_BLUE));
|
std::make_optional(Settings::JOYCON_BUTTONS_NEON_BLUE));
|
||||||
WriteSetting(std::string(player_prefix).append("button_color_right"),
|
WriteIntegerSetting(std::string(player_prefix).append("button_color_right"),
|
||||||
player.button_color_right,
|
player.button_color_right,
|
||||||
std::make_optional(Settings::JOYCON_BUTTONS_NEON_RED));
|
std::make_optional(Settings::JOYCON_BUTTONS_NEON_RED));
|
||||||
}
|
}
|
||||||
|
@ -433,13 +436,14 @@ void Config::SavePlayerValues(const std::size_t player_index) {
|
||||||
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)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,14 +451,14 @@ 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,15 +524,15 @@ 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,7 +615,7 @@ 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);
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
const std::optional<bool>& use_global) {
|
||||||
std::string full_key = GetFullKey(key, false);
|
std::string full_key = GetFullKey(key, false);
|
||||||
|
if (adjusted_default_value.has_value() && use_global.has_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()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (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);
|
||||||
|
template <typename T>
|
||||||
|
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);
|
const std::optional<bool>& use_global = std::nullopt);
|
||||||
void WriteSettingInternal(const std::string& key, const std::string& value);
|
|
||||||
|
|
||||||
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 a new issue