Compare commits

..

1 Commits

Author SHA1 Message Date
Chamatvha
7040964035 Yuzu emulator
Aot
2023-11-13 11:41:05 +07:00
170 changed files with 4775 additions and 6814 deletions

1
Yuzu emulator Normal file
View File

@@ -0,0 +1 @@

View File

@@ -373,10 +373,8 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
.getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val isEmulationActive = emulationViewModel.emulationStarted.value &&
!emulationViewModel.isEmulationStopping.value
pictureInPictureParamsBuilder.setAutoEnterEnabled(
BooleanSetting.PICTURE_IN_PICTURE.boolean && isEmulationActive
BooleanSetting.PICTURE_IN_PICTURE.boolean
)
}
setPictureInPictureParams(pictureInPictureParamsBuilder.build())

View File

@@ -22,16 +22,12 @@ import androidx.core.graphics.drawable.toBitmap
import androidx.core.graphics.drawable.toDrawable
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.navigation.findNavController
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.AsyncDifferConfig
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.yuzu.yuzu_emu.HomeNavigationDirections
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.YuzuApplication
@@ -96,34 +92,28 @@ class GameAdapter(private val activity: AppCompatActivity) :
data = Uri.parse(holder.game.path)
}
activity.lifecycleScope.launch {
withContext(Dispatchers.IO) {
val layerDrawable = ResourcesCompat.getDrawable(
YuzuApplication.appContext.resources,
R.drawable.shortcut,
null
) as LayerDrawable
layerDrawable.setDrawableByLayerId(
R.id.shortcut_foreground,
GameIconUtils.getGameIcon(activity, holder.game)
.toDrawable(YuzuApplication.appContext.resources)
val layerDrawable = ResourcesCompat.getDrawable(
YuzuApplication.appContext.resources,
R.drawable.shortcut,
null
) as LayerDrawable
layerDrawable.setDrawableByLayerId(
R.id.shortcut_foreground,
GameIconUtils.getGameIcon(holder.game).toDrawable(YuzuApplication.appContext.resources)
)
val inset = YuzuApplication.appContext.resources
.getDimensionPixelSize(R.dimen.icon_inset)
layerDrawable.setLayerInset(1, inset, inset, inset, inset)
val shortcut = ShortcutInfoCompat.Builder(YuzuApplication.appContext, holder.game.path)
.setShortLabel(holder.game.title)
.setIcon(
IconCompat.createWithAdaptiveBitmap(
layerDrawable.toBitmap(config = Bitmap.Config.ARGB_8888)
)
val inset = YuzuApplication.appContext.resources
.getDimensionPixelSize(R.dimen.icon_inset)
layerDrawable.setLayerInset(1, inset, inset, inset, inset)
val shortcut =
ShortcutInfoCompat.Builder(YuzuApplication.appContext, holder.game.path)
.setShortLabel(holder.game.title)
.setIcon(
IconCompat.createWithAdaptiveBitmap(
layerDrawable.toBitmap(config = Bitmap.Config.ARGB_8888)
)
)
.setIntent(openIntent)
.build()
ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut)
}
}
)
.setIntent(openIntent)
.build()
ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut)
val action = HomeNavigationDirections.actionGlobalEmulationActivity(holder.game)
view.findNavController().navigate(action)

View File

@@ -82,6 +82,7 @@ object Settings {
enum class MenuTag(val titleId: Int) {
SECTION_ROOT(R.string.advanced_settings),
SECTION_GENERAL(R.string.preferences_general),
SECTION_SYSTEM(R.string.preferences_system),
SECTION_RENDERER(R.string.preferences_graphics),
SECTION_AUDIO(R.string.preferences_audio),

View File

@@ -3,13 +3,10 @@
package org.yuzu.yuzu_emu.features.settings.model.view
import androidx.annotation.DrawableRes
class RunnableSetting(
titleId: Int,
descriptionId: Int,
val isRuntimeRunnable: Boolean,
@DrawableRes val iconId: Int = 0,
val runnable: () -> Unit
) : SettingsItem(emptySetting, titleId, descriptionId) {
override val type = TYPE_RUNNABLE

View File

@@ -73,7 +73,7 @@ abstract class SettingsItem(
R.string.frame_limit_slider,
R.string.frame_limit_slider_description,
1,
400,
200,
"%"
)
)

View File

@@ -3,14 +3,11 @@
package org.yuzu.yuzu_emu.features.settings.model.view
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import org.yuzu.yuzu_emu.features.settings.model.Settings
class SubmenuSetting(
@StringRes titleId: Int,
@StringRes descriptionId: Int,
@DrawableRes val iconId: Int,
titleId: Int,
descriptionId: Int,
val menuKey: Settings.MenuTag
) : SettingsItem(emptySetting, titleId, descriptionId) {
override val type = TYPE_SUBMENU

View File

@@ -20,6 +20,7 @@ import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.findNavController
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.divider.MaterialDividerItemDecoration
import com.google.android.material.transition.MaterialSharedAxis
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
@@ -67,9 +68,15 @@ class SettingsFragment : Fragment() {
)
binding.toolbarSettingsLayout.title = getString(args.menuTag.titleId)
val dividerDecoration = MaterialDividerItemDecoration(
requireContext(),
LinearLayoutManager.VERTICAL
)
dividerDecoration.isLastItemDecorated = false
binding.listSettings.apply {
adapter = settingsAdapter
layoutManager = LinearLayoutManager(requireContext())
addItemDecoration(dividerDecoration)
}
binding.toolbarSettings.setNavigationOnClickListener {
@@ -87,6 +94,17 @@ class SettingsFragment : Fragment() {
}
}
}
launch {
settingsViewModel.isUsingSearch.collectLatest {
if (it) {
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
} else {
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
}
}
}
}
if (args.menuTag == Settings.MenuTag.SECTION_ROOT) {
@@ -94,6 +112,8 @@ class SettingsFragment : Fragment() {
binding.toolbarSettings.setOnMenuItemClickListener {
when (it.itemId) {
R.id.action_search -> {
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
view.findNavController()
.navigate(R.id.action_settingsFragment_to_settingsSearchFragment)
true
@@ -109,6 +129,11 @@ class SettingsFragment : Fragment() {
setInsets()
}
override fun onResume() {
super.onResume()
settingsViewModel.setIsUsingSearch(false)
}
private fun setInsets() {
ViewCompat.setOnApplyWindowInsetsListener(
binding.root
@@ -119,9 +144,10 @@ class SettingsFragment : Fragment() {
val leftInsets = barInsets.left + cutoutInsets.left
val rightInsets = barInsets.right + cutoutInsets.right
val sideMargin = resources.getDimensionPixelSize(R.dimen.spacing_medlarge)
val mlpSettingsList = binding.listSettings.layoutParams as MarginLayoutParams
mlpSettingsList.leftMargin = leftInsets
mlpSettingsList.rightMargin = rightInsets
mlpSettingsList.leftMargin = sideMargin + leftInsets
mlpSettingsList.rightMargin = sideMargin + rightInsets
binding.listSettings.layoutParams = mlpSettingsList
binding.listSettings.updatePadding(
bottom = barInsets.bottom

View File

@@ -3,6 +3,7 @@
package org.yuzu.yuzu_emu.features.settings.ui
import android.content.Context
import android.content.SharedPreferences
import android.os.Build
import android.widget.Toast
@@ -31,6 +32,8 @@ class SettingsFragmentPresenter(
private val preferences: SharedPreferences
get() = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
private val context: Context get() = YuzuApplication.appContext
// Extension for populating settings list based on paired settings
fun ArrayList<SettingsItem>.add(key: String) {
val item = SettingsItem.settingsItems[key]!!
@@ -50,6 +53,7 @@ class SettingsFragmentPresenter(
val sl = ArrayList<SettingsItem>()
when (menuTag) {
Settings.MenuTag.SECTION_ROOT -> addConfigSettings(sl)
Settings.MenuTag.SECTION_GENERAL -> addGeneralSettings(sl)
Settings.MenuTag.SECTION_SYSTEM -> addSystemSettings(sl)
Settings.MenuTag.SECTION_RENDERER -> addGraphicsSettings(sl)
Settings.MenuTag.SECTION_AUDIO -> addAudioSettings(sl)
@@ -71,53 +75,30 @@ class SettingsFragmentPresenter(
private fun addConfigSettings(sl: ArrayList<SettingsItem>) {
sl.apply {
add(SubmenuSetting(R.string.preferences_general, 0, Settings.MenuTag.SECTION_GENERAL))
add(SubmenuSetting(R.string.preferences_system, 0, Settings.MenuTag.SECTION_SYSTEM))
add(SubmenuSetting(R.string.preferences_graphics, 0, Settings.MenuTag.SECTION_RENDERER))
add(SubmenuSetting(R.string.preferences_audio, 0, Settings.MenuTag.SECTION_AUDIO))
add(SubmenuSetting(R.string.preferences_debug, 0, Settings.MenuTag.SECTION_DEBUG))
add(
SubmenuSetting(
R.string.preferences_system,
R.string.preferences_system_description,
R.drawable.ic_system_settings,
Settings.MenuTag.SECTION_SYSTEM
)
)
add(
SubmenuSetting(
R.string.preferences_graphics,
R.string.preferences_graphics_description,
R.drawable.ic_graphics,
Settings.MenuTag.SECTION_RENDERER
)
)
add(
SubmenuSetting(
R.string.preferences_audio,
R.string.preferences_audio_description,
R.drawable.ic_audio,
Settings.MenuTag.SECTION_AUDIO
)
)
add(
SubmenuSetting(
R.string.preferences_debug,
R.string.preferences_debug_description,
R.drawable.ic_code,
Settings.MenuTag.SECTION_DEBUG
)
)
add(
RunnableSetting(
R.string.reset_to_default,
R.string.reset_to_default_description,
false,
R.drawable.ic_restore
) { settingsViewModel.setShouldShowResetSettingsDialog(true) }
RunnableSetting(R.string.reset_to_default, 0, false) {
settingsViewModel.setShouldShowResetSettingsDialog(true)
}
)
}
}
private fun addGeneralSettings(sl: ArrayList<SettingsItem>) {
sl.apply {
add(BooleanSetting.RENDERER_USE_SPEED_LIMIT.key)
add(ShortSetting.RENDERER_SPEED_LIMIT.key)
add(IntSetting.CPU_ACCURACY.key)
add(BooleanSetting.PICTURE_IN_PICTURE.key)
}
}
private fun addSystemSettings(sl: ArrayList<SettingsItem>) {
sl.apply {
add(BooleanSetting.RENDERER_USE_SPEED_LIMIT.key)
add(ShortSetting.RENDERER_SPEED_LIMIT.key)
add(BooleanSetting.USE_DOCKED_MODE.key)
add(IntSetting.REGION_INDEX.key)
add(IntSetting.LANGUAGE_INDEX.key)
@@ -135,7 +116,6 @@ class SettingsFragmentPresenter(
add(IntSetting.RENDERER_ANTI_ALIASING.key)
add(IntSetting.RENDERER_SCREEN_LAYOUT.key)
add(IntSetting.RENDERER_ASPECT_RATIO.key)
add(BooleanSetting.PICTURE_IN_PICTURE.key)
add(BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE.key)
add(BooleanSetting.RENDERER_FORCE_MAX_CLOCK.key)
add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key)
@@ -269,7 +249,6 @@ class SettingsFragmentPresenter(
add(BooleanSetting.RENDERER_DEBUG.key)
add(HeaderSetting(R.string.cpu))
add(IntSetting.CPU_ACCURACY.key)
add(BooleanSetting.CPU_DEBUG_MODE.key)
add(SettingsItem.FASTMEM_COMBINED)
}

View File

@@ -4,7 +4,6 @@
package org.yuzu.yuzu_emu.features.settings.ui.viewholder
import android.view.View
import androidx.core.content.res.ResourcesCompat
import org.yuzu.yuzu_emu.NativeLibrary
import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
import org.yuzu.yuzu_emu.features.settings.model.view.RunnableSetting
@@ -17,19 +16,6 @@ class RunnableViewHolder(val binding: ListItemSettingBinding, adapter: SettingsA
override fun bind(item: SettingsItem) {
setting = item as RunnableSetting
if (item.iconId != 0) {
binding.icon.visibility = View.VISIBLE
binding.icon.setImageDrawable(
ResourcesCompat.getDrawable(
binding.icon.resources,
item.iconId,
binding.icon.context.theme
)
)
} else {
binding.icon.visibility = View.GONE
}
binding.textSettingName.setText(item.nameId)
if (item.descriptionId != 0) {
binding.textSettingDescription.setText(item.descriptionId)

View File

@@ -4,7 +4,6 @@
package org.yuzu.yuzu_emu.features.settings.ui.viewholder
import android.view.View
import androidx.core.content.res.ResourcesCompat
import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
import org.yuzu.yuzu_emu.features.settings.model.view.SubmenuSetting
@@ -16,19 +15,6 @@ class SubmenuViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAd
override fun bind(item: SettingsItem) {
this.item = item as SubmenuSetting
if (item.iconId != 0) {
binding.icon.visibility = View.VISIBLE
binding.icon.setImageDrawable(
ResourcesCompat.getDrawable(
binding.icon.resources,
item.iconId,
binding.icon.context.theme
)
)
} else {
binding.icon.visibility = View.GONE
}
binding.textSettingName.setText(item.nameId)
if (item.descriptionId != 0) {
binding.textSettingDescription.setText(item.descriptionId)

View File

@@ -114,10 +114,10 @@ class AboutFragment : Fragment() {
val leftInsets = barInsets.left + cutoutInsets.left
val rightInsets = barInsets.right + cutoutInsets.right
val mlpToolbar = binding.toolbarAbout.layoutParams as MarginLayoutParams
mlpToolbar.leftMargin = leftInsets
mlpToolbar.rightMargin = rightInsets
binding.toolbarAbout.layoutParams = mlpToolbar
val mlpAppBar = binding.appbarAbout.layoutParams as MarginLayoutParams
mlpAppBar.leftMargin = leftInsets
mlpAppBar.rightMargin = rightInsets
binding.appbarAbout.layoutParams = mlpAppBar
val mlpScrollAbout = binding.scrollAbout.layoutParams as MarginLayoutParams
mlpScrollAbout.leftMargin = leftInsets

View File

@@ -21,8 +21,6 @@ import org.yuzu.yuzu_emu.databinding.FragmentInstallablesBinding
import org.yuzu.yuzu_emu.model.HomeViewModel
import org.yuzu.yuzu_emu.model.Installable
import org.yuzu.yuzu_emu.ui.main.MainActivity
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
class InstallableFragment : Fragment() {
private var _binding: FragmentInstallablesBinding? = null
@@ -80,15 +78,7 @@ class InstallableFragment : Fragment() {
R.string.manage_save_data,
R.string.import_export_saves_description,
install = { mainActivity.importSaves.launch(arrayOf("application/zip")) },
export = {
mainActivity.exportSaves.launch(
"yuzu saves - ${
LocalDateTime.now().format(
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
)
}.zip"
)
}
export = { mainActivity.exportSave() }
)
} else {
Installable(

View File

@@ -40,10 +40,8 @@ class SettingsSearchFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
}
override fun onCreateView(
@@ -57,6 +55,7 @@ class SettingsSearchFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
settingsViewModel.setIsUsingSearch(true)
if (savedInstanceState != null) {
binding.searchText.setText(savedInstanceState.getString(SEARCH_TEXT))

View File

@@ -18,8 +18,8 @@ class Game(
val version: String = "",
val isHomebrew: Boolean = false
) : Parcelable {
val keyAddedToLibraryTime get() = "${path}_AddedToLibraryTime"
val keyLastPlayedTime get() = "${path}_LastPlayed"
val keyAddedToLibraryTime get() = "${programId}_AddedToLibraryTime"
val keyLastPlayedTime get() = "${programId}_LastPlayed"
override fun equals(other: Any?): Boolean {
if (other !is Game) {

View File

@@ -29,6 +29,9 @@ class SettingsViewModel : ViewModel() {
val shouldReloadSettingsList: StateFlow<Boolean> get() = _shouldReloadSettingsList
private val _shouldReloadSettingsList = MutableStateFlow(false)
val isUsingSearch: StateFlow<Boolean> get() = _isUsingSearch
private val _isUsingSearch = MutableStateFlow(false)
val sliderProgress: StateFlow<Int> get() = _sliderProgress
private val _sliderProgress = MutableStateFlow(-1)
@@ -54,6 +57,10 @@ class SettingsViewModel : ViewModel() {
_shouldReloadSettingsList.value = value
}
fun setIsUsingSearch(value: Boolean) {
_isUsingSearch.value = value
}
fun setSliderTextValue(value: Float, units: String) {
_sliderProgress.value = value.toInt()
_sliderTextValue.value = String.format(

View File

@@ -6,6 +6,7 @@ package org.yuzu.yuzu_emu.ui.main
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.DocumentsContract
import android.view.View
import android.view.ViewGroup.MarginLayoutParams
import android.view.WindowManager
@@ -19,6 +20,7 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
@@ -39,6 +41,7 @@ import org.yuzu.yuzu_emu.NativeLibrary
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.activities.EmulationActivity
import org.yuzu.yuzu_emu.databinding.ActivityMainBinding
import org.yuzu.yuzu_emu.features.DocumentProvider
import org.yuzu.yuzu_emu.features.settings.model.Settings
import org.yuzu.yuzu_emu.fragments.IndeterminateProgressDialogFragment
import org.yuzu.yuzu_emu.fragments.MessageDialogFragment
@@ -50,6 +53,9 @@ import org.yuzu.yuzu_emu.model.TaskViewModel
import org.yuzu.yuzu_emu.utils.*
import java.io.BufferedInputStream
import java.io.BufferedOutputStream
import java.io.FileOutputStream
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
@@ -67,6 +73,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
// Get first subfolder in saves folder (should be the user folder)
val savesFolderRoot get() = File(savesFolder).listFiles()?.firstOrNull()?.canonicalPath ?: ""
private var lastZipCreated: File? = null
override fun onCreate(savedInstanceState: Bundle?) {
val splashScreen = installSplashScreen()
@@ -649,31 +656,75 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
}.show(supportFragmentManager, IndeterminateProgressDialogFragment.TAG)
}
/**
* Zips the save files located in the given folder path and creates a new zip file with the current date and time.
* @return true if the zip file is successfully created, false otherwise.
*/
private fun zipSave(): Boolean {
try {
val tempFolder = File(getPublicFilesDir().canonicalPath, "temp")
tempFolder.mkdirs()
val saveFolder = File(savesFolderRoot)
val outputZipFile = File(
tempFolder,
"yuzu saves - ${
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))
}.zip"
)
outputZipFile.createNewFile()
val result = FileUtil.zipFromInternalStorage(
saveFolder,
savesFolderRoot,
BufferedOutputStream(FileOutputStream(outputZipFile))
)
if (result == TaskState.Failed) {
return false
}
lastZipCreated = outputZipFile
} catch (e: Exception) {
return false
}
return true
}
/**
* Exports the save file located in the given folder path by creating a zip file and sharing it via intent.
*/
val exportSaves = registerForActivityResult(
ActivityResultContracts.CreateDocument("application/zip")
) { result ->
if (result == null) {
return@registerForActivityResult
}
IndeterminateProgressDialogFragment.newInstance(
this,
R.string.save_files_exporting,
false
) {
val zipResult = FileUtil.zipFromInternalStorage(
File(savesFolderRoot),
savesFolderRoot,
BufferedOutputStream(contentResolver.openOutputStream(result))
)
return@newInstance when (zipResult) {
TaskState.Completed -> getString(R.string.export_success)
TaskState.Cancelled, TaskState.Failed -> getString(R.string.export_failed)
fun exportSave() {
CoroutineScope(Dispatchers.IO).launch {
val wasZipCreated = zipSave()
val lastZipFile = lastZipCreated
if (!wasZipCreated || lastZipFile == null) {
withContext(Dispatchers.Main) {
Toast.makeText(
this@MainActivity,
getString(R.string.export_save_failed),
Toast.LENGTH_LONG
).show()
}
return@launch
}
}.show(supportFragmentManager, IndeterminateProgressDialogFragment.TAG)
withContext(Dispatchers.Main) {
val file = DocumentFile.fromSingleUri(
this@MainActivity,
DocumentsContract.buildDocumentUri(
DocumentProvider.AUTHORITY,
"${DocumentProvider.ROOT_ID}/temp/${lastZipFile.name}"
)
)!!
val intent = Intent(Intent.ACTION_SEND)
.setDataAndType(file.uri, "application/zip")
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
.putExtra(Intent.EXTRA_STREAM, file.uri)
startForResultExportSave.launch(
Intent.createChooser(
intent,
getString(R.string.share_save_file)
)
)
}
}
}
private val startForResultExportSave =

View File

@@ -8,9 +8,9 @@ import android.graphics.BitmapFactory
import android.widget.ImageView
import androidx.core.graphics.drawable.toBitmap
import androidx.core.graphics.drawable.toDrawable
import androidx.lifecycle.LifecycleOwner
import coil.ImageLoader
import coil.decode.DataSource
import coil.executeBlocking
import coil.fetch.DrawableResult
import coil.fetch.FetchResult
import coil.fetch.Fetcher
@@ -76,13 +76,12 @@ object GameIconUtils {
imageLoader.enqueue(request)
}
suspend fun getGameIcon(lifecycleOwner: LifecycleOwner, game: Game): Bitmap {
fun getGameIcon(game: Game): Bitmap {
val request = ImageRequest.Builder(YuzuApplication.appContext)
.data(game)
.lifecycle(lifecycleOwner)
.error(R.drawable.default_icon)
.build()
return imageLoader.execute(request)
return imageLoader.executeBlocking(request)
.drawable!!.toBitmap(config = Bitmap.Config.ARGB_8888)
}
}

View File

@@ -13,7 +13,7 @@ struct Values {
Settings::Linkage linkage;
// Android
Settings::Setting<bool> picture_in_picture{linkage, false, "picture_in_picture",
Settings::Setting<bool> picture_in_picture{linkage, true, "picture_in_picture",
Settings::Category::Android};
Settings::Setting<s32> screen_layout{linkage,
5,

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="?attr/colorControlNormal"
android:pathData="M3,9v6h4l5,5L12,4L7,9L3,9zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM14,3.23v2.06c2.89,0.86 5,3.54 5,6.71s-2.11,5.85 -5,6.71v2.06c4.01,-0.91 7,-4.49 7,-8.77s-2.99,-7.86 -7,-8.77z" />
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="?attr/colorControlNormal"
android:pathData="M320,720 L80,480l240,-240 57,57 -184,184 183,183 -56,56ZM640,720 L583,663 767,479 584,296 640,240 880,480 640,720Z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="?attr/colorControlNormal"
android:pathData="M160,840q-33,0 -56.5,-23.5T80,760v-560q0,-33 23.5,-56.5T160,120h560q33,0 56.5,23.5T800,200v80h80v80h-80v80h80v80h-80v80h80v80h-80v80q0,33 -23.5,56.5T720,840L160,840ZM160,760h560v-560L160,200v560ZM240,680h200v-160L240,520v160ZM480,400h160v-120L480,280v120ZM240,480h200v-200L240,280v200ZM480,680h160v-240L480,440v240ZM160,200v560,-560Z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="?attr/colorControlNormal"
android:pathData="M320,960q-17,0 -28.5,-11.5T280,920q0,-17 11.5,-28.5T320,880q17,0 28.5,11.5T360,920q0,17 -11.5,28.5T320,960ZM480,960q-17,0 -28.5,-11.5T440,920q0,-17 11.5,-28.5T480,880q17,0 28.5,11.5T520,920q0,17 -11.5,28.5T480,960ZM640,960q-17,0 -28.5,-11.5T600,920q0,-17 11.5,-28.5T640,880q17,0 28.5,11.5T680,920q0,17 -11.5,28.5T640,960ZM320,800q-33,0 -56.5,-23.5T240,720v-640q0,-33 23.5,-56.5T320,0h320q33,0 56.5,23.5T720,80v640q0,33 -23.5,56.5T640,800L320,800ZM320,720h320v-40L320,680v40ZM320,600h320v-400L320,200v400ZM320,120h320v-40L320,80v40ZM320,120v-40,40ZM320,720v-40,40Z"/>
</vector>

View File

@@ -1,233 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/coordinator_about"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_about"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar_about"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:navigationIcon="@drawable/ic_back"
app:title="@string/about" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/scroll_about"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fadeScrollbars="false"
android:scrollbars="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:id="@+id/content_about"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/image_logo"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center_horizontal"
android:padding="20dp"
android:src="@drawable/ic_yuzu_title" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp">
<com.google.android.material.textview.MaterialTextView
style="@style/TextAppearance.Material3.TitleMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:text="@string/about"
android:textAlignment="viewStart" />
<com.google.android.material.textview.MaterialTextView
style="@style/TextAppearance.Material3.BodyMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="6dp"
android:text="@string/about_app_description"
android:textAlignment="viewStart" />
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp" />
<LinearLayout
android:id="@+id/button_contributors"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:orientation="vertical"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp">
<com.google.android.material.textview.MaterialTextView
style="@style/TextAppearance.Material3.TitleMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:text="@string/contributors"
android:textAlignment="viewStart" />
<com.google.android.material.textview.MaterialTextView
style="@style/TextAppearance.Material3.BodyMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="6dp"
android:text="@string/contributors_description"
android:textAlignment="viewStart" />
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp" />
<LinearLayout
android:id="@+id/button_licenses"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:orientation="vertical"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp">
<com.google.android.material.textview.MaterialTextView
style="@style/TextAppearance.Material3.TitleMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:text="@string/licenses"
android:textAlignment="viewStart" />
<com.google.android.material.textview.MaterialTextView
style="@style/TextAppearance.Material3.BodyMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="6dp"
android:text="@string/licenses_description"
android:textAlignment="viewStart" />
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp" />
<LinearLayout
android:id="@+id/button_build_hash"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:orientation="vertical"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp">
<com.google.android.material.textview.MaterialTextView
style="@style/TextAppearance.Material3.TitleMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:text="@string/build"
android:textAlignment="viewStart" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text_build_hash"
style="@style/TextAppearance.Material3.BodyMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="6dp"
android:textAlignment="viewStart"
tools:text="abc123" />
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="40dp"
android:layout_marginTop="12dp"
android:layout_marginBottom="16dp"
android:gravity="center_horizontal"
android:orientation="horizontal">
<Button
android:id="@+id/button_discord"
style="?attr/materialIconButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
app:icon="@drawable/ic_discord"
app:iconGravity="textEnd"
app:iconSize="24dp"
app:iconTint="?attr/colorOnSurface" />
<Button
android:id="@+id/button_website"
style="?attr/materialIconButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
app:icon="@drawable/ic_website"
app:iconGravity="textEnd"
app:iconSize="24dp"
app:iconTint="?attr/colorOnSurface" />
<Button
android:id="@+id/button_github"
style="?attr/materialIconButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
app:icon="@drawable/ic_github"
app:iconGravity="textEnd"
app:iconSize="24dp"
app:iconTint="?attr/colorOnSurface" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -6,8 +6,8 @@
android:id="@+id/option_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:layout_marginHorizontal="12dp"
android:layout_marginVertical="12dp"
android:layout_marginHorizontal="16dp"
android:background="?attr/selectableItemBackground"
android:backgroundTint="?attr/colorSurfaceVariant"
android:clickable="true"

View File

@@ -38,17 +38,17 @@
<ImageView
android:id="@+id/image_logo"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_marginTop="24dp"
android:layout_marginBottom="28dp"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_marginTop="20dp"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_yuzu_title" />
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp" />
android:layout_marginHorizontal="20dp"
android:layout_marginTop="28dp" />
<LinearLayout
android:layout_width="match_parent"

View File

@@ -139,7 +139,7 @@
<com.google.android.material.textview.MaterialTextView
android:id="@+id/show_fps_text"
style="@style/TextAppearance.Material3.BodySmall"
style="@style/TextAppearance.Material3.BodyMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
@@ -147,8 +147,7 @@
android:focusable="false"
android:paddingHorizontal="20dp"
android:textColor="@android:color/white"
android:shadowColor="@android:color/black"
android:shadowRadius="3"
android:textSize="12sp"
tools:ignore="RtlHardcoded" />
</FrameLayout>

View File

@@ -14,14 +14,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="?attr/colorSurface"
android:paddingHorizontal="8dp">
android:background="?attr/colorSurface">
<ImageView
android:id="@+id/logo_image"
android:layout_width="96dp"
android:layout_height="96dp"
android:layout_marginVertical="32dp"
android:layout_width="128dp"
android:layout_height="128dp"
android:layout_margin="64dp"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_yuzu_full" />

View File

@@ -127,7 +127,6 @@
android:layout_height="wrap_content"
android:clipToPadding="false"
android:paddingVertical="4dp"
app:checkedChip="@id/chip_recently_played"
app:chipSpacingHorizontal="12dp"
app:singleLine="true"
app:singleSelection="true">

View File

@@ -10,59 +10,41 @@
android:focusable="true"
android:gravity="center_vertical"
android:minHeight="72dp"
android:padding="16dp">
android:padding="@dimen/spacing_large">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
android:orientation="vertical">
<ImageView
android:id="@+id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="24dp"
android:layout_gravity="center_vertical"
android:visibility="gone"
app:tint="?attr/colorOnSurface" />
<LinearLayout
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text_setting_name"
style="@style/TextAppearance.Material3.HeadlineMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:textAlignment="viewStart"
android:textSize="16sp"
app:lineHeight="22dp"
tools:text="Setting Name" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text_setting_name"
style="@style/TextAppearance.Material3.HeadlineMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="viewStart"
android:textSize="17sp"
app:lineHeight="22dp"
tools:text="Setting Name" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text_setting_description"
style="@style/TextAppearance.Material3.BodySmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/spacing_small"
android:textAlignment="viewStart"
tools:text="@string/app_disclaimer" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text_setting_description"
style="@style/TextAppearance.Material3.BodySmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/spacing_small"
android:textAlignment="viewStart"
tools:text="@string/app_disclaimer" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text_setting_value"
style="@style/TextAppearance.Material3.LabelMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/spacing_small"
android:textAlignment="viewStart"
android:textStyle="bold"
android:textSize="13sp"
tools:text="1x" />
</LinearLayout>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text_setting_value"
style="@style/TextAppearance.Material3.LabelMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/spacing_small"
android:textAlignment="viewStart"
android:textStyle="bold"
tools:text="1x" />
</LinearLayout>

View File

@@ -8,7 +8,9 @@
android:clickable="true"
android:focusable="true"
android:minHeight="72dp"
android:padding="16dp">
android:paddingVertical="@dimen/spacing_large"
android:paddingStart="@dimen/spacing_large"
android:paddingEnd="24dp">
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_widget"
@@ -22,7 +24,7 @@
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:layout_marginEnd="@dimen/spacing_large"
android:layout_toStartOf="@+id/switch_widget"
android:gravity="center_vertical"
android:orientation="vertical">
@@ -33,7 +35,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="viewStart"
android:textSize="17sp"
android:textSize="16sp"
app:lineHeight="28dp"
tools:text="@string/frame_limit_enable" />

View File

@@ -7,8 +7,7 @@
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:paddingHorizontal="@dimen/spacing_large"
android:paddingTop="16dp"
android:paddingBottom="8dp"
android:paddingVertical="16dp"
android:textAlignment="viewStart"
android:textColor="?attr/colorPrimary"
android:textStyle="bold"

View File

@@ -2,6 +2,7 @@
<resources>
<string-array name="regionNames">
<item>@string/auto</item>
<item>@string/region_australia</item>
<item>@string/region_china</item>
<item>@string/region_europe</item>
@@ -12,6 +13,7 @@
</string-array>
<integer-array name="regionValues">
<item>-1</item>
<item>3</item>
<item>4</item>
<item>2</item>

View File

@@ -91,7 +91,6 @@
<string name="manage_save_data">Manage save data</string>
<string name="manage_save_data_description">Save data found. Please select an option below.</string>
<string name="import_export_saves_description">Import or export save files</string>
<string name="save_files_exporting">Exporting save files…</string>
<string name="save_file_imported_success">Imported successfully</string>
<string name="save_file_invalid_zip_structure">Invalid save directory structure</string>
<string name="save_file_invalid_zip_structure_description">The first subfolder name must be the title ID of the game.</string>
@@ -241,7 +240,6 @@
<string name="shutting_down">Shutting down…</string>
<string name="reset_setting_confirmation">Do you want to reset this setting back to its default value?</string>
<string name="reset_to_default">Reset to default</string>
<string name="reset_to_default_description">Resets all advanced settings</string>
<string name="reset_all_settings">Reset all settings?</string>
<string name="reset_all_settings_description">All advanced settings will be reset to their default configuration. This can not be undone.</string>
<string name="settings_reset">Settings reset</string>
@@ -257,7 +255,6 @@
<string name="cancelling">Cancelling</string>
<string name="install">Install</string>
<string name="delete">Delete</string>
<string name="export_success">Exported successfully</string>
<!-- GPU driver installation -->
<string name="select_gpu_driver">Select GPU driver</string>
@@ -274,14 +271,10 @@
<string name="preferences_settings">Settings</string>
<string name="preferences_general">General</string>
<string name="preferences_system">System</string>
<string name="preferences_system_description">Docked mode, region, language</string>
<string name="preferences_graphics">Graphics</string>
<string name="preferences_graphics_description">Accuracy level, resolution, shader cache</string>
<string name="preferences_audio">Audio</string>
<string name="preferences_audio_description">Output engine, volume</string>
<string name="preferences_theme">Theme and color</string>
<string name="preferences_debug">Debug</string>
<string name="preferences_debug_description">CPU/GPU debugging, graphics API, fastmem</string>
<!-- ROM loading errors -->
<string name="loader_error_encrypted">Your ROM is encrypted</string>

View File

@@ -12,7 +12,7 @@ bool IsValidChannelCount(u32 channel_count) {
}
bool IsValidStreamCounts(u32 total_stream_count, u32 stereo_stream_count) {
return total_stream_count > 0 && static_cast<s32>(stereo_stream_count) >= 0 &&
return total_stream_count > 0 && stereo_stream_count > 0 &&
stereo_stream_count <= total_stream_count && IsValidChannelCount(total_stream_count);
}
} // namespace

View File

@@ -148,7 +148,7 @@ Result OpusDecoder::DecodeInterleavedForMultiStream(u32* out_data_size, u64* out
auto* header_p{reinterpret_cast<const OpusPacketHeader*>(input_data.data())};
OpusPacketHeader header{ReverseHeader(*header_p)};
LOG_TRACE(Service_Audio, "header size 0x{:X} input data size 0x{:X} in_data size 0x{:X}",
LOG_ERROR(Service_Audio, "header size 0x{:X} input data size 0x{:X} in_data size 0x{:X}",
header.size, input_data.size_bytes(), in_data.size_bytes());
R_UNLESS(in_data.size_bytes() >= header.size &&

View File

@@ -146,7 +146,7 @@ public:
return;
}
SignalPause();
paused = true;
if (cubeb_stream_stop(stream_backend) != CUBEB_OK) {
LOG_CRITICAL(Audio_Sink, "Error stopping cubeb stream");
}

View File

@@ -111,7 +111,7 @@ public:
if (device == 0 || paused) {
return;
}
SignalPause();
paused = true;
SDL_PauseAudioDevice(device, 1);
}

View File

@@ -282,19 +282,11 @@ u64 SinkStream::GetExpectedPlayedSampleCount() {
void SinkStream::WaitFreeSpace(std::stop_token stop_token) {
std::unique_lock lk{release_mutex};
release_cv.wait_for(lk, std::chrono::milliseconds(5),
[this]() { return paused || queued_buffers < max_queue_size; });
[this]() { return queued_buffers < max_queue_size; });
if (queued_buffers > max_queue_size + 3) {
Common::CondvarWait(release_cv, lk, stop_token,
[this] { return paused || queued_buffers < max_queue_size; });
[this] { return queued_buffers < max_queue_size; });
}
}
void SinkStream::SignalPause() {
{
std::scoped_lock lk{release_mutex};
paused = true;
}
release_cv.notify_one();
}
} // namespace AudioCore::Sink

View File

@@ -213,12 +213,6 @@ public:
*/
void WaitFreeSpace(std::stop_token stop_token);
protected:
/**
* Unblocks the ADSP if the stream is paused.
*/
void SignalPause();
protected:
/// Core system
Core::System& system;

View File

@@ -203,8 +203,6 @@ const char* TranslateCategory(Category category) {
case Category::Ui:
case Category::UiGeneral:
return "UI";
case Category::UiAudio:
return "UiAudio";
case Category::UiLayout:
return "UiLayout";
case Category::UiGameList:

View File

@@ -153,7 +153,7 @@ struct Values {
true,
true};
Setting<bool, false> audio_muted{
linkage, false, "audio_muted", Category::Audio, Specialization::Default, true, true};
linkage, false, "audio_muted", Category::Audio, Specialization::Default, false, true};
Setting<bool, false> dump_audio_commands{
linkage, false, "dump_audio_commands", Category::Audio, Specialization::Default, false};

View File

@@ -32,7 +32,6 @@ enum class Category : u32 {
AddOns,
Controls,
Ui,
UiAudio,
UiGeneral,
UiLayout,
UiGameList,

View File

@@ -6,11 +6,10 @@
namespace Settings {
namespace NativeButton {
const std::array<const char*, NumButtons> mapping = {{
"button_a", "button_b", "button_x", "button_y", "button_lstick",
"button_rstick", "button_l", "button_r", "button_zl", "button_zr",
"button_plus", "button_minus", "button_dleft", "button_dup", "button_dright",
"button_ddown", "button_slleft", "button_srleft", "button_home", "button_screenshot",
"button_slright", "button_srright",
"button_a", "button_b", "button_x", "button_y", "button_lstick",
"button_rstick", "button_l", "button_r", "button_zl", "button_zr",
"button_plus", "button_minus", "button_dleft", "button_dup", "button_dright",
"button_ddown", "button_sl", "button_sr", "button_home", "button_screenshot",
}};
}

View File

@@ -29,15 +29,12 @@ enum Values : int {
DRight,
DDown,
SLLeft,
SRLeft,
SL,
SR,
Home,
Screenshot,
SLRight,
SRRight,
NumButtons,
};

View File

@@ -521,28 +521,17 @@ add_library(core STATIC
hle/service/grc/grc.h
hle/service/hid/hid.cpp
hle/service/hid/hid.h
hle/service/hid/hid_debug_server.cpp
hle/service/hid/hid_debug_server.h
hle/service/hid/hid_firmware_settings.cpp
hle/service/hid/hid_firmware_settings.h
hle/service/hid/hid_server.cpp
hle/service/hid/hid_server.h
hle/service/hid/hid_system_server.cpp
hle/service/hid/hid_system_server.h
hle/service/hid/hid_util.h
hle/service/hid/hidbus.cpp
hle/service/hid/hidbus.h
hle/service/hid/irs.cpp
hle/service/hid/irs.h
hle/service/hid/irs_ring_lifo.h
hle/service/hid/resource_manager.cpp
hle/service/hid/resource_manager.h
hle/service/hid/ring_lifo.h
hle/service/hid/xcd.cpp
hle/service/hid/xcd.h
hle/service/hid/errors.h
hle/service/hid/controllers/console_six_axis.cpp
hle/service/hid/controllers/console_six_axis.h
hle/service/hid/controllers/console_sixaxis.cpp
hle/service/hid/controllers/console_sixaxis.h
hle/service/hid/controllers/controller_base.cpp
hle/service/hid/controllers/controller_base.h
hle/service/hid/controllers/debug_pad.cpp
@@ -557,10 +546,6 @@ add_library(core STATIC
hle/service/hid/controllers/npad.h
hle/service/hid/controllers/palma.cpp
hle/service/hid/controllers/palma.h
hle/service/hid/controllers/seven_six_axis.cpp
hle/service/hid/controllers/seven_six_axis.h
hle/service/hid/controllers/six_axis.cpp
hle/service/hid/controllers/six_axis.h
hle/service/hid/controllers/stubbed.cpp
hle/service/hid/controllers/stubbed.h
hle/service/hid/controllers/touchscreen.cpp
@@ -730,7 +715,6 @@ add_library(core STATIC
hle/service/nvnflinger/producer_listener.h
hle/service/nvnflinger/status.h
hle/service/nvnflinger/ui/fence.h
hle/service/nvnflinger/ui/graphic_buffer.cpp
hle/service/nvnflinger/ui/graphic_buffer.h
hle/service/nvnflinger/window.h
hle/service/olsc/olsc.cpp

View File

@@ -153,14 +153,6 @@ void ARM_Interface::Run() {
Kernel::KThread* current_thread{Kernel::GetCurrentThreadPointer(system.Kernel())};
HaltReason hr{};
// If the thread is scheduled for termination, exit the thread.
if (current_thread->HasDpc()) {
if (current_thread->IsTerminationRequested()) {
current_thread->Exit();
UNREACHABLE();
}
}
// Notify the debugger and go to sleep if a step was performed
// and this thread has been scheduled again.
if (current_thread->GetStepState() == StepState::StepPerformed) {
@@ -182,6 +174,14 @@ void ARM_Interface::Run() {
}
system.ExitCPUProfile();
// If the thread is scheduled for termination, exit the thread.
if (current_thread->HasDpc()) {
if (current_thread->IsTerminationRequested()) {
current_thread->Exit();
UNREACHABLE();
}
}
// Notify the debugger and go to sleep if a breakpoint was hit,
// or if the thread is unable to continue for any reason.
if (True(hr & HaltReason::InstructionBreakpoint) || True(hr & HaltReason::PrefetchAbort)) {

View File

@@ -76,7 +76,6 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
}
void CoreTiming::ClearPendingEvents() {
std::scoped_lock lock{basic_lock};
event_queue.clear();
}
@@ -114,7 +113,6 @@ bool CoreTiming::IsRunning() const {
}
bool CoreTiming::HasPendingEvents() const {
std::scoped_lock lock{basic_lock};
return !(wait_set && event_queue.empty());
}

View File

@@ -161,7 +161,7 @@ private:
std::shared_ptr<EventType> ev_lost;
Common::Event event{};
Common::Event pause_event{};
mutable std::mutex basic_lock;
std::mutex basic_lock;
std::mutex advance_lock;
std::unique_ptr<std::jthread> timer_thread;
std::atomic<bool> paused{};

View File

@@ -38,6 +38,14 @@ using TouchParams = std::array<Common::ParamPackage, MaxTouchDevices>;
using ConsoleMotionValues = ConsoleMotionInfo;
using TouchValues = std::array<Common::Input::TouchStatus, MaxTouchDevices>;
struct TouchFinger {
u64 last_touch{};
Common::Point<float> position{};
u32 id{};
TouchAttribute attribute{};
bool pressed{};
};
// Contains all motion related data that is used on the services
struct ConsoleMotion {
Common::Vec3f accel{};

View File

@@ -8,7 +8,6 @@
#include "common/thread.h"
#include "core/hid/emulated_controller.h"
#include "core/hid/input_converter.h"
#include "core/hle/service/hid/hid_util.h"
namespace Core::HID {
constexpr s32 HID_JOYSTICK_MAX = 0x7fff;
@@ -83,7 +82,7 @@ Settings::ControllerType EmulatedController::MapNPadToSettingsType(NpadStyleInde
}
void EmulatedController::ReloadFromSettings() {
const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
const auto player_index = NpadIdTypeToIndex(npad_id_type);
const auto& player = Settings::values.players.GetValue()[player_index];
for (std::size_t index = 0; index < player.buttons.size(); ++index) {
@@ -119,7 +118,7 @@ void EmulatedController::ReloadFromSettings() {
}
void EmulatedController::ReloadColorsFromSettings() {
const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
const auto player_index = NpadIdTypeToIndex(npad_id_type);
const auto& player = Settings::values.players.GetValue()[player_index];
// Avoid updating colors if overridden by physical controller
@@ -216,7 +215,7 @@ void EmulatedController::LoadDevices() {
}
void EmulatedController::LoadTASParams() {
const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
const auto player_index = NpadIdTypeToIndex(npad_id_type);
Common::ParamPackage common_params{};
common_params.Set("engine", "tas");
common_params.Set("port", static_cast<int>(player_index));
@@ -244,12 +243,10 @@ void EmulatedController::LoadTASParams() {
tas_button_params[Settings::NativeButton::DUp].Set("button", 13);
tas_button_params[Settings::NativeButton::DRight].Set("button", 14);
tas_button_params[Settings::NativeButton::DDown].Set("button", 15);
tas_button_params[Settings::NativeButton::SLLeft].Set("button", 16);
tas_button_params[Settings::NativeButton::SRLeft].Set("button", 17);
tas_button_params[Settings::NativeButton::SL].Set("button", 16);
tas_button_params[Settings::NativeButton::SR].Set("button", 17);
tas_button_params[Settings::NativeButton::Home].Set("button", 18);
tas_button_params[Settings::NativeButton::Screenshot].Set("button", 19);
tas_button_params[Settings::NativeButton::SLRight].Set("button", 20);
tas_button_params[Settings::NativeButton::SRRight].Set("button", 21);
tas_stick_params[Settings::NativeAnalog::LStick].Set("axis_x", 0);
tas_stick_params[Settings::NativeAnalog::LStick].Set("axis_y", 1);
@@ -265,7 +262,7 @@ void EmulatedController::LoadTASParams() {
}
void EmulatedController::LoadVirtualGamepadParams() {
const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
const auto player_index = NpadIdTypeToIndex(npad_id_type);
Common::ParamPackage common_params{};
common_params.Set("engine", "virtual_gamepad");
common_params.Set("port", static_cast<int>(player_index));
@@ -299,12 +296,10 @@ void EmulatedController::LoadVirtualGamepadParams() {
virtual_button_params[Settings::NativeButton::DUp].Set("button", 13);
virtual_button_params[Settings::NativeButton::DRight].Set("button", 14);
virtual_button_params[Settings::NativeButton::DDown].Set("button", 15);
virtual_button_params[Settings::NativeButton::SLLeft].Set("button", 16);
virtual_button_params[Settings::NativeButton::SRLeft].Set("button", 17);
virtual_button_params[Settings::NativeButton::SL].Set("button", 16);
virtual_button_params[Settings::NativeButton::SR].Set("button", 17);
virtual_button_params[Settings::NativeButton::Home].Set("button", 18);
virtual_button_params[Settings::NativeButton::Screenshot].Set("button", 19);
virtual_button_params[Settings::NativeButton::SLRight].Set("button", 20);
virtual_button_params[Settings::NativeButton::SRRight].Set("button", 21);
virtual_stick_params[Settings::NativeAnalog::LStick].Set("axis_x", 0);
virtual_stick_params[Settings::NativeAnalog::LStick].Set("axis_y", 1);
@@ -616,7 +611,7 @@ bool EmulatedController::IsConfiguring() const {
}
void EmulatedController::SaveCurrentConfig() {
const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
const auto player_index = NpadIdTypeToIndex(npad_id_type);
auto& player = Settings::values.players.GetValue()[player_index];
player.connected = is_connected;
player.controller_type = MapNPadToSettingsType(npad_type);
@@ -872,16 +867,12 @@ void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback
controller.npad_button_state.down.Assign(current_status.value);
controller.debug_pad_button_state.d_down.Assign(current_status.value);
break;
case Settings::NativeButton::SLLeft:
case Settings::NativeButton::SL:
controller.npad_button_state.left_sl.Assign(current_status.value);
break;
case Settings::NativeButton::SLRight:
controller.npad_button_state.right_sl.Assign(current_status.value);
break;
case Settings::NativeButton::SRLeft:
case Settings::NativeButton::SR:
controller.npad_button_state.left_sr.Assign(current_status.value);
break;
case Settings::NativeButton::SRRight:
controller.npad_button_state.right_sr.Assign(current_status.value);
break;
case Settings::NativeButton::Home:
@@ -1213,7 +1204,7 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
if (!output_devices[device_index]) {
return false;
}
const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
const auto player_index = NpadIdTypeToIndex(npad_id_type);
const auto& player = Settings::values.players.GetValue()[player_index];
const f32 strength = static_cast<f32>(player.vibration_strength) / 100.0f;
@@ -1239,7 +1230,7 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
}
bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
const auto player_index = NpadIdTypeToIndex(npad_id_type);
const auto& player = Settings::values.players.GetValue()[player_index];
if (!player.vibration_enabled) {
@@ -1649,7 +1640,7 @@ void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) {
}
if (is_connected) {
LOG_WARNING(Service_HID, "Controller {} type changed while it's connected",
Service::HID::NpadIdTypeToIndex(npad_id_type));
NpadIdTypeToIndex(npad_id_type));
}
npad_type = npad_type_;
}
@@ -1899,16 +1890,12 @@ NpadButton EmulatedController::GetTurboButtonMask() const {
case Settings::NativeButton::DDown:
button_mask.down.Assign(1);
break;
case Settings::NativeButton::SLLeft:
case Settings::NativeButton::SL:
button_mask.left_sl.Assign(1);
break;
case Settings::NativeButton::SLRight:
button_mask.right_sl.Assign(1);
break;
case Settings::NativeButton::SRLeft:
case Settings::NativeButton::SR:
button_mask.left_sr.Assign(1);
break;
case Settings::NativeButton::SRRight:
button_mask.right_sr.Assign(1);
break;
default:

View File

@@ -6,7 +6,6 @@
#include "core/hid/emulated_controller.h"
#include "core/hid/emulated_devices.h"
#include "core/hid/hid_core.h"
#include "core/hle/service/hid/hid_util.h"
namespace Core::HID {
@@ -99,11 +98,11 @@ const EmulatedDevices* HIDCore::GetEmulatedDevices() const {
}
EmulatedController* HIDCore::GetEmulatedControllerByIndex(std::size_t index) {
return GetEmulatedController(Service::HID::IndexToNpadIdType(index));
return GetEmulatedController(IndexToNpadIdType(index));
}
const EmulatedController* HIDCore::GetEmulatedControllerByIndex(std::size_t index) const {
return GetEmulatedController(Service::HID::IndexToNpadIdType(index));
return GetEmulatedController(IndexToNpadIdType(index));
}
void HIDCore::SetSupportedStyleTag(NpadStyleTag style_tag) {

View File

@@ -8,7 +8,6 @@
#include "common/common_types.h"
#include "common/point.h"
#include "common/uuid.h"
#include "common/vector_math.h"
namespace Core::HID {
@@ -219,13 +218,6 @@ enum class NpadIdType : u32 {
Invalid = 0xFFFFFFFF,
};
enum class NpadInterfaceType : u8 {
Bluetooth = 1,
Rail = 2,
Usb = 3,
Embedded = 4,
};
// This is nn::hid::NpadStyleIndex
enum class NpadStyleIndex : u8 {
None = 0,
@@ -364,14 +356,6 @@ struct TouchState {
};
static_assert(sizeof(TouchState) == 0x28, "Touchstate is an invalid size");
struct TouchFinger {
u64 last_touch{};
Common::Point<float> position{};
u32 id{};
TouchAttribute attribute{};
bool pressed{};
};
// This is nn::hid::TouchScreenConfigurationForNx
struct TouchScreenConfigurationForNx {
TouchScreenModeForNx mode{TouchScreenModeForNx::UseSystemSetting};
@@ -599,29 +583,6 @@ struct SixAxisSensorIcInformation {
static_assert(sizeof(SixAxisSensorIcInformation) == 0xC8,
"SixAxisSensorIcInformation is an invalid size");
// This is nn::hid::SixAxisSensorAttribute
struct SixAxisSensorAttribute {
union {
u32 raw{};
BitField<0, 1, u32> is_connected;
BitField<1, 1, u32> is_interpolated;
};
};
static_assert(sizeof(SixAxisSensorAttribute) == 4, "SixAxisSensorAttribute is an invalid size");
// This is nn::hid::SixAxisSensorState
struct SixAxisSensorState {
s64 delta_time{};
s64 sampling_number{};
Common::Vec3f accel{};
Common::Vec3f gyro{};
Common::Vec3f rotation{};
std::array<Common::Vec3f, 3> orientation{};
SixAxisSensorAttribute attribute{};
INSERT_PADDING_BYTES(4); // Reserved
};
static_assert(sizeof(SixAxisSensorState) == 0x60, "SixAxisSensorState is an invalid size");
// This is nn::hid::VibrationDeviceHandle
struct VibrationDeviceHandle {
NpadStyleIndex npad_type{NpadStyleIndex::None};
@@ -732,4 +693,60 @@ struct UniquePadId {
};
static_assert(sizeof(UniquePadId) == 0x8, "UniquePadId is an invalid size");
/// Converts a NpadIdType to an array index.
constexpr size_t NpadIdTypeToIndex(NpadIdType npad_id_type) {
switch (npad_id_type) {
case NpadIdType::Player1:
return 0;
case NpadIdType::Player2:
return 1;
case NpadIdType::Player3:
return 2;
case NpadIdType::Player4:
return 3;
case NpadIdType::Player5:
return 4;
case NpadIdType::Player6:
return 5;
case NpadIdType::Player7:
return 6;
case NpadIdType::Player8:
return 7;
case NpadIdType::Handheld:
return 8;
case NpadIdType::Other:
return 9;
default:
return 0;
}
}
/// Converts an array index to a NpadIdType
constexpr NpadIdType IndexToNpadIdType(size_t index) {
switch (index) {
case 0:
return NpadIdType::Player1;
case 1:
return NpadIdType::Player2;
case 2:
return NpadIdType::Player3;
case 3:
return NpadIdType::Player4;
case 4:
return NpadIdType::Player5;
case 5:
return NpadIdType::Player6;
case 6:
return NpadIdType::Player7;
case 7:
return NpadIdType::Player8;
case 8:
return NpadIdType::Handheld;
case 9:
return NpadIdType::Other;
default:
return NpadIdType::Invalid;
}
}
} // namespace Core::HID

View File

@@ -5,22 +5,21 @@
#include "core/hid/hid_types.h"
#include "core/hid/input_interpreter.h"
#include "core/hle/service/hid/controllers/npad.h"
#include "core/hle/service/hid/hid_server.h"
#include "core/hle/service/hid/resource_manager.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/sm/sm.h"
InputInterpreter::InputInterpreter(Core::System& system)
: npad{system.ServiceManager()
.GetService<Service::HID::IHidServer>("hid")
->GetResourceManager()
->GetNpad()} {
.GetService<Service::HID::Hid>("hid")
->GetAppletResource()
->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad)} {
ResetButtonStates();
}
InputInterpreter::~InputInterpreter() = default;
void InputInterpreter::PollInput() {
const auto button_state = npad->GetAndResetPressState();
const auto button_state = npad.GetAndResetPressState();
previous_index = current_index;
current_index = (current_index + 1) % button_states.size();

View File

@@ -16,7 +16,7 @@ enum class NpadButton : u64;
}
namespace Service::HID {
class NPad;
class Controller_NPad;
}
/**
@@ -101,7 +101,7 @@ public:
}
private:
std::shared_ptr<Service::HID::NPad> npad;
Service::HID::Controller_NPad& npad;
/// Stores 9 consecutive button states polled from HID.
std::array<Core::HID::NpadButton, 9> button_states{};

View File

@@ -1617,9 +1617,9 @@ void KPageTableBase::RemapPageGroup(PageLinkedList* page_list, KProcessAddress a
const KMemoryInfo info = it->GetMemoryInfo();
// Determine the range to map.
KProcessAddress map_address = std::max<u64>(info.GetAddress(), GetInteger(start_address));
KProcessAddress map_address = std::max(info.GetAddress(), GetInteger(start_address));
const KProcessAddress map_end_address =
std::min<u64>(info.GetEndAddress(), GetInteger(end_address));
std::min(info.GetEndAddress(), GetInteger(end_address));
ASSERT(map_end_address != map_address);
// Determine if we should disable head merge.

View File

@@ -13,7 +13,6 @@
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/registered_cache.h"
#include "core/file_sys/savedata_factory.h"
#include "core/hid/hid_types.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/result.h"
@@ -22,7 +21,6 @@
#include "core/hle/service/am/applet_ae.h"
#include "core/hle/service/am/applet_oe.h"
#include "core/hle/service/am/applets/applet_cabinet.h"
#include "core/hle/service/am/applets/applet_controller.h"
#include "core/hle/service/am/applets/applet_mii_edit_types.h"
#include "core/hle/service/am/applets/applet_profile_select.h"
#include "core/hle/service/am/applets/applet_software_keyboard_types.h"
@@ -37,7 +35,6 @@
#include "core/hle/service/caps/caps_su.h"
#include "core/hle/service/caps/caps_types.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/hid/controllers/npad.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/ns/ns.h"
#include "core/hle/service/nvnflinger/fb_share_buffer_manager.h"
@@ -76,7 +73,7 @@ IWindowController::IWindowController(Core::System& system_)
static const FunctionInfo functions[] = {
{0, nullptr, "CreateWindow"},
{1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"},
{2, &IWindowController::GetAppletResourceUserIdOfCallerApplet, "GetAppletResourceUserIdOfCallerApplet"},
{2, nullptr, "GetAppletResourceUserIdOfCallerApplet"},
{10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"},
{11, nullptr, "ReleaseForegroundRights"},
{12, nullptr, "RejectToChangeIntoBackground"},
@@ -100,16 +97,6 @@ void IWindowController::GetAppletResourceUserId(HLERequestContext& ctx) {
rb.Push<u64>(process_id);
}
void IWindowController::GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx) {
const u64 process_id = 0;
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.Push<u64>(process_id);
}
void IWindowController::AcquireForegroundRights(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
@@ -1578,7 +1565,7 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)
{6, nullptr, "GetPopInteractiveInDataEvent"},
{10, &ILibraryAppletSelfAccessor::ExitProcessAndReturn, "ExitProcessAndReturn"},
{11, &ILibraryAppletSelfAccessor::GetLibraryAppletInfo, "GetLibraryAppletInfo"},
{12, &ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo, "GetMainAppletIdentityInfo"},
{12, nullptr, "GetMainAppletIdentityInfo"},
{13, nullptr, "CanUseApplicationCore"},
{14, &ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo, "GetCallerAppletIdentityInfo"},
{15, nullptr, "GetMainAppletApplicationControlProperty"},
@@ -1622,9 +1609,6 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)
case Applets::AppletId::SoftwareKeyboard:
PushInShowSoftwareKeyboard();
break;
case Applets::AppletId::Controller:
PushInShowController();
break;
default:
break;
}
@@ -1682,33 +1666,13 @@ void ILibraryAppletSelfAccessor::GetLibraryAppletInfo(HLERequestContext& ctx) {
rb.PushRaw(applet_info);
}
void ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo(HLERequestContext& ctx) {
struct AppletIdentityInfo {
Applets::AppletId applet_id;
INSERT_PADDING_BYTES(0x4);
u64 application_id;
};
static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size.");
LOG_WARNING(Service_AM, "(STUBBED) called");
const AppletIdentityInfo applet_info{
.applet_id = Applets::AppletId::QLaunch,
.application_id = 0x0100000000001000ull,
};
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(ResultSuccess);
rb.PushRaw(applet_info);
}
void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext& ctx) {
struct AppletIdentityInfo {
Applets::AppletId applet_id;
INSERT_PADDING_BYTES(0x4);
u64 application_id;
};
static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size.");
LOG_WARNING(Service_AM, "(STUBBED) called");
const AppletIdentityInfo applet_info{
@@ -1773,55 +1737,6 @@ void ILibraryAppletSelfAccessor::PushInShowAlbum() {
queue_data.emplace_back(std::move(settings_data));
}
void ILibraryAppletSelfAccessor::PushInShowController() {
const Applets::CommonArguments common_args = {
.arguments_version = Applets::CommonArgumentVersion::Version3,
.size = Applets::CommonArgumentSize::Version3,
.library_version = static_cast<u32>(Applets::ControllerAppletVersion::Version8),
.theme_color = Applets::ThemeColor::BasicBlack,
.play_startup_sound = true,
.system_tick = system.CoreTiming().GetClockTicks(),
};
Applets::ControllerSupportArgNew user_args = {
.header = {.player_count_min = 1,
.player_count_max = 4,
.enable_take_over_connection = true,
.enable_left_justify = false,
.enable_permit_joy_dual = true,
.enable_single_mode = false,
.enable_identification_color = false},
.identification_colors = {},
.enable_explain_text = false,
.explain_text = {},
};
Applets::ControllerSupportArgPrivate private_args = {
.arg_private_size = sizeof(Applets::ControllerSupportArgPrivate),
.arg_size = sizeof(Applets::ControllerSupportArgNew),
.is_home_menu = true,
.flag_1 = true,
.mode = Applets::ControllerSupportMode::ShowControllerSupport,
.caller = Applets::ControllerSupportCaller::
Application, // switchbrew: Always zero except with
// ShowControllerFirmwareUpdateForSystem/ShowControllerKeyRemappingForSystem,
// which sets this to the input param
.style_set = Core::HID::NpadStyleSet::None,
.joy_hold_type = 0,
};
std::vector<u8> common_args_data(sizeof(common_args));
std::vector<u8> private_args_data(sizeof(private_args));
std::vector<u8> user_args_data(sizeof(user_args));
std::memcpy(common_args_data.data(), &common_args, sizeof(common_args));
std::memcpy(private_args_data.data(), &private_args, sizeof(private_args));
std::memcpy(user_args_data.data(), &user_args, sizeof(user_args));
queue_data.emplace_back(std::move(common_args_data));
queue_data.emplace_back(std::move(private_args_data));
queue_data.emplace_back(std::move(user_args_data));
}
void ILibraryAppletSelfAccessor::PushInShowCabinetData() {
const Applets::CommonArguments arguments{
.arguments_version = Applets::CommonArgumentVersion::Version3,

View File

@@ -87,7 +87,6 @@ public:
private:
void GetAppletResourceUserId(HLERequestContext& ctx);
void GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx);
void AcquireForegroundRights(HLERequestContext& ctx);
};
@@ -346,7 +345,6 @@ private:
void PopInData(HLERequestContext& ctx);
void PushOutData(HLERequestContext& ctx);
void GetLibraryAppletInfo(HLERequestContext& ctx);
void GetMainAppletIdentityInfo(HLERequestContext& ctx);
void ExitProcessAndReturn(HLERequestContext& ctx);
void GetCallerAppletIdentityInfo(HLERequestContext& ctx);
void GetDesirableKeyboardLayout(HLERequestContext& ctx);
@@ -357,7 +355,6 @@ private:
void PushInShowCabinetData();
void PushInShowMiiEditData();
void PushInShowSoftwareKeyboard();
void PushInShowController();
std::deque<std::vector<u8>> queue_data;
};

View File

@@ -56,7 +56,7 @@ enum class ControllerSupportResult : u32 {
struct ControllerSupportArgPrivate {
u32 arg_private_size{};
u32 arg_size{};
bool is_home_menu{};
bool flag_0{};
bool flag_1{};
ControllerSupportMode mode{};
ControllerSupportCaller caller{};

View File

@@ -127,7 +127,7 @@ public:
private:
void GetCore(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "called");
LOG_DEBUG(Service_BTM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
@@ -263,13 +263,13 @@ public:
explicit IBtmSystemCore(Core::System& system_) : ServiceFramework{system_, "IBtmSystemCore"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IBtmSystemCore::StartGamepadPairing, "StartGamepadPairing"},
{1, &IBtmSystemCore::CancelGamepadPairing, "CancelGamepadPairing"},
{0, nullptr, "StartGamepadPairing"},
{1, nullptr, "CancelGamepadPairing"},
{2, nullptr, "ClearGamepadPairingDatabase"},
{3, nullptr, "GetPairedGamepadCount"},
{4, nullptr, "EnableRadio"},
{5, nullptr, "DisableRadio"},
{6, &IBtmSystemCore::IsRadioEnabled, "IsRadioEnabled"},
{6, nullptr, "GetRadioOnOff"},
{7, nullptr, "AcquireRadioEvent"},
{8, nullptr, "AcquireGamepadPairingEvent"},
{9, nullptr, "IsGamepadPairingStarted"},
@@ -280,58 +280,18 @@ public:
{14, nullptr, "AcquireAudioDeviceConnectionEvent"},
{15, nullptr, "ConnectAudioDevice"},
{16, nullptr, "IsConnectingAudioDevice"},
{17, &IBtmSystemCore::GetConnectedAudioDevices, "GetConnectedAudioDevices"},
{17, nullptr, "GetConnectedAudioDevices"},
{18, nullptr, "DisconnectAudioDevice"},
{19, nullptr, "AcquirePairedAudioDeviceInfoChangedEvent"},
{20, nullptr, "GetPairedAudioDevices"},
{21, nullptr, "RemoveAudioDevicePairing"},
{22, &IBtmSystemCore::RequestAudioDeviceConnectionRejection, "RequestAudioDeviceConnectionRejection"},
{23, &IBtmSystemCore::CancelAudioDeviceConnectionRejection, "CancelAudioDeviceConnectionRejection"}
{22, nullptr, "RequestAudioDeviceConnectionRejection"},
{23, nullptr, "CancelAudioDeviceConnectionRejection"}
};
// clang-format on
RegisterHandlers(functions);
}
private:
void IsRadioEnabled(HLERequestContext& ctx) {
LOG_DEBUG(Service_BTM, "(STUBBED) called"); // Spams a lot when controller applet is running
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(true);
}
void StartGamepadPairing(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void CancelGamepadPairing(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void CancelAudioDeviceConnectionRejection(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void GetConnectedAudioDevices(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u32>(0);
}
void RequestAudioDeviceConnectionRejection(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
};
class BTM_SYS final : public ServiceFramework<BTM_SYS> {
@@ -348,7 +308,7 @@ public:
private:
void GetCore(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "called");
LOG_DEBUG(Service_BTM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);

View File

@@ -1,42 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hid/emulated_console.h"
#include "core/hid/hid_core.h"
#include "core/hle/service/hid/controllers/console_six_axis.h"
#include "core/memory.h"
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200;
ConsoleSixAxis::ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
: ControllerBase{hid_core_} {
console = hid_core.GetEmulatedConsole();
static_assert(SHARED_MEMORY_OFFSET + sizeof(ConsoleSharedMemory) < shared_memory_size,
"ConsoleSharedMemory is bigger than the shared memory");
shared_memory = std::construct_at(
reinterpret_cast<ConsoleSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
}
ConsoleSixAxis::~ConsoleSixAxis() = default;
void ConsoleSixAxis::OnInit() {}
void ConsoleSixAxis::OnRelease() {}
void ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
return;
}
const auto motion_status = console->GetMotion();
shared_memory->sampling_number++;
shared_memory->is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest;
shared_memory->verticalization_error = motion_status.verticalization_error;
shared_memory->gyro_bias = motion_status.gyro_bias;
}
} // namespace Service::HID

View File

@@ -1,43 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/vector_math.h"
#include "core/hle/service/hid/controllers/controller_base.h"
namespace Core::HID {
class EmulatedConsole;
} // namespace Core::HID
namespace Service::HID {
class ConsoleSixAxis final : public ControllerBase {
public:
explicit ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~ConsoleSixAxis() 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:
// This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat
struct ConsoleSharedMemory {
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(ConsoleSharedMemory) == 0x20, "ConsoleSharedMemory is an invalid size");
ConsoleSharedMemory* shared_memory = nullptr;
Core::HID::EmulatedConsole* console = nullptr;
};
} // namespace Service::HID

View File

@@ -1,29 +1,32 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <cstring>
#include "common/common_types.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/frontend/emu_window.h"
#include "core/hid/emulated_console.h"
#include "core/hid/emulated_devices.h"
#include "core/hid/hid_core.h"
#include "core/hle/service/hid/controllers/seven_six_axis.h"
#include "core/hle/service/hid/controllers/console_sixaxis.h"
#include "core/memory.h"
namespace Service::HID {
SevenSixAxis::SevenSixAxis(Core::System& system_)
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200;
Controller_ConsoleSixAxis::Controller_ConsoleSixAxis(Core::System& system_, u8* raw_shared_memory_)
: ControllerBase{system_.HIDCore()}, system{system_} {
console = hid_core.GetEmulatedConsole();
static_assert(SHARED_MEMORY_OFFSET + sizeof(ConsoleSharedMemory) < shared_memory_size,
"ConsoleSharedMemory is bigger than the shared memory");
shared_memory = std::construct_at(
reinterpret_cast<ConsoleSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
}
SevenSixAxis::~SevenSixAxis() = default;
Controller_ConsoleSixAxis::~Controller_ConsoleSixAxis() = default;
void SevenSixAxis::OnInit() {}
void SevenSixAxis::OnRelease() {}
void Controller_ConsoleSixAxis::OnInit() {}
void SevenSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
void Controller_ConsoleSixAxis::OnRelease() {}
void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated() || transfer_memory == 0) {
seven_sixaxis_lifo.buffer_count = 0;
seven_sixaxis_lifo.buffer_tail = 0;
@@ -50,17 +53,22 @@ void SevenSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
-motion_status.quaternion.xyz.z,
};
shared_memory->sampling_number++;
shared_memory->is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest;
shared_memory->verticalization_error = motion_status.verticalization_error;
shared_memory->gyro_bias = motion_status.gyro_bias;
// Update seven six axis transfer memory
seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state);
system.ApplicationMemory().WriteBlock(transfer_memory, &seven_sixaxis_lifo,
sizeof(seven_sixaxis_lifo));
}
void SevenSixAxis::SetTransferMemoryAddress(Common::ProcessAddress t_mem) {
void Controller_ConsoleSixAxis::SetTransferMemoryAddress(Common::ProcessAddress t_mem) {
transfer_memory = t_mem;
}
void SevenSixAxis::ResetTimestamp() {
void Controller_ConsoleSixAxis::ResetTimestamp() {
last_saved_timestamp = last_global_timestamp;
}
} // namespace Service::HID

View File

@@ -1,9 +1,10 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/common_types.h"
#include <array>
#include "common/quaternion.h"
#include "common/typed_address.h"
#include "core/hle/service/hid/controllers/controller_base.h"
@@ -18,10 +19,10 @@ class EmulatedConsole;
} // namespace Core::HID
namespace Service::HID {
class SevenSixAxis final : public ControllerBase {
class Controller_ConsoleSixAxis final : public ControllerBase {
public:
explicit SevenSixAxis(Core::System& system_);
~SevenSixAxis() override;
explicit Controller_ConsoleSixAxis(Core::System& system_, u8* raw_shared_memory_);
~Controller_ConsoleSixAxis() override;
// Called when the controller is initialized
void OnInit() override;
@@ -50,16 +51,28 @@ private:
};
static_assert(sizeof(SevenSixAxisState) == 0x48, "SevenSixAxisState is an invalid size");
// This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat
struct ConsoleSharedMemory {
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(ConsoleSharedMemory) == 0x20, "ConsoleSharedMemory is an invalid size");
Lifo<SevenSixAxisState, 0x21> seven_sixaxis_lifo{};
static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size");
SevenSixAxisState next_seven_sixaxis_state{};
Common::ProcessAddress transfer_memory{};
ConsoleSharedMemory* shared_memory = nullptr;
Core::HID::EmulatedConsole* console = nullptr;
u64 last_saved_timestamp{};
u64 last_global_timestamp{};
SevenSixAxisState next_seven_sixaxis_state{};
Common::ProcessAddress transfer_memory{};
Core::HID::EmulatedConsole* console = nullptr;
Core::System& system;
};
} // namespace Service::HID

View File

@@ -8,17 +8,12 @@ namespace Service::HID {
ControllerBase::ControllerBase(Core::HID::HIDCore& hid_core_) : hid_core(hid_core_) {}
ControllerBase::~ControllerBase() = default;
Result ControllerBase::Activate() {
void ControllerBase::ActivateController() {
if (is_activated) {
return ResultSuccess;
return;
}
is_activated = true;
OnInit();
return ResultSuccess;
}
Result ControllerBase::Activate(u64 aruid) {
return Activate();
}
void ControllerBase::DeactivateController() {

View File

@@ -4,7 +4,6 @@
#pragma once
#include "common/common_types.h"
#include "core/hle/result.h"
namespace Core::Timing {
class CoreTiming;
@@ -32,8 +31,7 @@ public:
// When the controller is requesting a motion update for the shared memory
virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) {}
Result Activate();
Result Activate(u64 aruid);
void ActivateController();
void DeactivateController();

View File

@@ -13,7 +13,7 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x00000;
DebugPad::DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
Controller_DebugPad::Controller_DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
: ControllerBase{hid_core_} {
static_assert(SHARED_MEMORY_OFFSET + sizeof(DebugPadSharedMemory) < shared_memory_size,
"DebugPadSharedMemory is bigger than the shared memory");
@@ -22,13 +22,13 @@ DebugPad::DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other);
}
DebugPad::~DebugPad() = default;
Controller_DebugPad::~Controller_DebugPad() = default;
void DebugPad::OnInit() {}
void Controller_DebugPad::OnInit() {}
void DebugPad::OnRelease() {}
void Controller_DebugPad::OnRelease() {}
void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
shared_memory->debug_pad_lifo.buffer_count = 0;
shared_memory->debug_pad_lifo.buffer_tail = 0;

View File

@@ -15,10 +15,10 @@ struct AnalogStickState;
} // namespace Core::HID
namespace Service::HID {
class DebugPad final : public ControllerBase {
class Controller_DebugPad final : public ControllerBase {
public:
explicit DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~DebugPad() override;
explicit Controller_DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~Controller_DebugPad() override;
// Called when the controller is initialized
void OnInit() override;

View File

@@ -23,7 +23,7 @@ constexpr f32 Square(s32 num) {
return static_cast<f32>(num * num);
}
Gesture::Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
Controller_Gesture::Controller_Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
: ControllerBase(hid_core_) {
static_assert(SHARED_MEMORY_OFFSET + sizeof(GestureSharedMemory) < shared_memory_size,
"GestureSharedMemory is bigger than the shared memory");
@@ -31,17 +31,17 @@ Gesture::Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
reinterpret_cast<GestureSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
console = hid_core.GetEmulatedConsole();
}
Gesture::~Gesture() = default;
Controller_Gesture::~Controller_Gesture() = default;
void Gesture::OnInit() {
void Controller_Gesture::OnInit() {
shared_memory->gesture_lifo.buffer_count = 0;
shared_memory->gesture_lifo.buffer_tail = 0;
force_update = true;
}
void Gesture::OnRelease() {}
void Controller_Gesture::OnRelease() {}
void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
shared_memory->gesture_lifo.buffer_count = 0;
shared_memory->gesture_lifo.buffer_tail = 0;
@@ -64,7 +64,7 @@ void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
UpdateGestureSharedMemory(gesture, time_difference);
}
void Gesture::ReadTouchInput() {
void Controller_Gesture::ReadTouchInput() {
if (!Settings::values.touchscreen.enabled) {
fingers = {};
return;
@@ -76,7 +76,8 @@ void Gesture::ReadTouchInput() {
}
}
bool Gesture::ShouldUpdateGesture(const GestureProperties& gesture, f32 time_difference) {
bool Controller_Gesture::ShouldUpdateGesture(const GestureProperties& gesture,
f32 time_difference) {
const auto& last_entry = GetLastGestureEntry();
if (force_update) {
force_update = false;
@@ -99,7 +100,8 @@ bool Gesture::ShouldUpdateGesture(const GestureProperties& gesture, f32 time_dif
return false;
}
void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_difference) {
void Controller_Gesture::UpdateGestureSharedMemory(GestureProperties& gesture,
f32 time_difference) {
GestureType type = GestureType::Idle;
GestureAttribute attributes{};
@@ -136,8 +138,8 @@ void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_dif
shared_memory->gesture_lifo.WriteNextEntry(next_state);
}
void Gesture::NewGesture(GestureProperties& gesture, GestureType& type,
GestureAttribute& attributes) {
void Controller_Gesture::NewGesture(GestureProperties& gesture, GestureType& type,
GestureAttribute& attributes) {
const auto& last_entry = GetLastGestureEntry();
gesture.detection_count++;
@@ -150,8 +152,8 @@ void Gesture::NewGesture(GestureProperties& gesture, GestureType& type,
}
}
void Gesture::UpdateExistingGesture(GestureProperties& gesture, GestureType& type,
f32 time_difference) {
void Controller_Gesture::UpdateExistingGesture(GestureProperties& gesture, GestureType& type,
f32 time_difference) {
const auto& last_entry = GetLastGestureEntry();
// Promote to pan type if touch moved
@@ -184,8 +186,9 @@ void Gesture::UpdateExistingGesture(GestureProperties& gesture, GestureType& typ
}
}
void Gesture::EndGesture(GestureProperties& gesture, GestureProperties& last_gesture_props,
GestureType& type, GestureAttribute& attributes, f32 time_difference) {
void Controller_Gesture::EndGesture(GestureProperties& gesture,
GestureProperties& last_gesture_props, GestureType& type,
GestureAttribute& attributes, f32 time_difference) {
const auto& last_entry = GetLastGestureEntry();
if (last_gesture_props.active_points != 0) {
@@ -219,8 +222,9 @@ void Gesture::EndGesture(GestureProperties& gesture, GestureProperties& last_ges
}
}
void Gesture::SetTapEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
GestureType& type, GestureAttribute& attributes) {
void Controller_Gesture::SetTapEvent(GestureProperties& gesture,
GestureProperties& last_gesture_props, GestureType& type,
GestureAttribute& attributes) {
type = GestureType::Tap;
gesture = last_gesture_props;
force_update = true;
@@ -232,8 +236,9 @@ void Gesture::SetTapEvent(GestureProperties& gesture, GestureProperties& last_ge
}
}
void Gesture::UpdatePanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
GestureType& type, f32 time_difference) {
void Controller_Gesture::UpdatePanEvent(GestureProperties& gesture,
GestureProperties& last_gesture_props, GestureType& type,
f32 time_difference) {
const auto& last_entry = GetLastGestureEntry();
next_state.delta = gesture.mid_point - last_entry.pos;
@@ -258,8 +263,9 @@ void Gesture::UpdatePanEvent(GestureProperties& gesture, GestureProperties& last
}
}
void Gesture::EndPanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
GestureType& type, f32 time_difference) {
void Controller_Gesture::EndPanEvent(GestureProperties& gesture,
GestureProperties& last_gesture_props, GestureType& type,
f32 time_difference) {
const auto& last_entry = GetLastGestureEntry();
next_state.vel_x =
static_cast<f32>(last_entry.delta.x) / (last_pan_time_difference + time_difference);
@@ -281,8 +287,8 @@ void Gesture::EndPanEvent(GestureProperties& gesture, GestureProperties& last_ge
force_update = true;
}
void Gesture::SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
GestureType& type) {
void Controller_Gesture::SetSwipeEvent(GestureProperties& gesture,
GestureProperties& last_gesture_props, GestureType& type) {
const auto& last_entry = GetLastGestureEntry();
type = GestureType::Swipe;
@@ -305,11 +311,11 @@ void Gesture::SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_
next_state.direction = GestureDirection::Up;
}
const Gesture::GestureState& Gesture::GetLastGestureEntry() const {
const Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() const {
return shared_memory->gesture_lifo.ReadCurrentEntry().state;
}
Gesture::GestureProperties Gesture::GetGestureProperties() {
Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties() {
GestureProperties gesture;
std::array<Core::HID::TouchFinger, MAX_POINTS> active_fingers;
const auto end_iter = std::copy_if(fingers.begin(), fingers.end(), active_fingers.begin(),

View File

@@ -12,10 +12,10 @@
#include "core/hle/service/hid/ring_lifo.h"
namespace Service::HID {
class Gesture final : public ControllerBase {
class Controller_Gesture final : public ControllerBase {
public:
explicit Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~Gesture() override;
explicit Controller_Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~Controller_Gesture() override;
// Called when the controller is initialized
void OnInit() override;

View File

@@ -12,7 +12,7 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800;
Keyboard::Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
Controller_Keyboard::Controller_Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
: ControllerBase{hid_core_} {
static_assert(SHARED_MEMORY_OFFSET + sizeof(KeyboardSharedMemory) < shared_memory_size,
"KeyboardSharedMemory is bigger than the shared memory");
@@ -21,13 +21,13 @@ Keyboard::Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
emulated_devices = hid_core.GetEmulatedDevices();
}
Keyboard::~Keyboard() = default;
Controller_Keyboard::~Controller_Keyboard() = default;
void Keyboard::OnInit() {}
void Controller_Keyboard::OnInit() {}
void Keyboard::OnRelease() {}
void Controller_Keyboard::OnRelease() {}
void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
shared_memory->keyboard_lifo.buffer_count = 0;
shared_memory->keyboard_lifo.buffer_tail = 0;

View File

@@ -14,10 +14,10 @@ struct KeyboardKey;
} // namespace Core::HID
namespace Service::HID {
class Keyboard final : public ControllerBase {
class Controller_Keyboard final : public ControllerBase {
public:
explicit Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~Keyboard() override;
explicit Controller_Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~Controller_Keyboard() override;
// Called when the controller is initialized
void OnInit() override;

View File

@@ -12,7 +12,8 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400;
Mouse::Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) : ControllerBase{hid_core_} {
Controller_Mouse::Controller_Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
: ControllerBase{hid_core_} {
static_assert(SHARED_MEMORY_OFFSET + sizeof(MouseSharedMemory) < shared_memory_size,
"MouseSharedMemory is bigger than the shared memory");
shared_memory = std::construct_at(
@@ -20,12 +21,12 @@ Mouse::Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) : Controller
emulated_devices = hid_core.GetEmulatedDevices();
}
Mouse::~Mouse() = default;
Controller_Mouse::~Controller_Mouse() = default;
void Mouse::OnInit() {}
void Mouse::OnRelease() {}
void Controller_Mouse::OnInit() {}
void Controller_Mouse::OnRelease() {}
void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
shared_memory->mouse_lifo.buffer_count = 0;
shared_memory->mouse_lifo.buffer_tail = 0;

View File

@@ -14,10 +14,10 @@ struct AnalogStickState;
} // namespace Core::HID
namespace Service::HID {
class Mouse final : public ControllerBase {
class Controller_Mouse final : public ControllerBase {
public:
explicit Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~Mouse() override;
explicit Controller_Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~Controller_Mouse() override;
// Called when the controller is initialized
void OnInit() override;

View File

@@ -18,7 +18,6 @@
#include "core/hle/kernel/k_readable_event.h"
#include "core/hle/service/hid/controllers/npad.h"
#include "core/hle/service/hid/errors.h"
#include "core/hle/service/hid/hid_util.h"
#include "core/hle/service/kernel_helpers.h"
namespace Service::HID {
@@ -30,8 +29,60 @@ constexpr std::array<Core::HID::NpadIdType, 10> npad_id_list{
Core::HID::NpadIdType::Handheld,
};
NPad::NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
KernelHelpers::ServiceContext& service_context_)
bool Controller_NPad::IsNpadIdValid(Core::HID::NpadIdType npad_id) {
switch (npad_id) {
case Core::HID::NpadIdType::Player1:
case Core::HID::NpadIdType::Player2:
case Core::HID::NpadIdType::Player3:
case Core::HID::NpadIdType::Player4:
case Core::HID::NpadIdType::Player5:
case Core::HID::NpadIdType::Player6:
case Core::HID::NpadIdType::Player7:
case Core::HID::NpadIdType::Player8:
case Core::HID::NpadIdType::Other:
case Core::HID::NpadIdType::Handheld:
return true;
default:
LOG_ERROR(Service_HID, "Invalid npad id {}", npad_id);
return false;
}
}
Result Controller_NPad::IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle) {
const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id));
const bool npad_type = device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType;
const bool device_index = device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
if (!npad_type) {
return VibrationInvalidStyleIndex;
}
if (!npad_id) {
return VibrationInvalidNpadId;
}
if (!device_index) {
return VibrationDeviceIndexOutOfRange;
}
return ResultSuccess;
}
Result Controller_NPad::VerifyValidSixAxisSensorHandle(
const Core::HID::SixAxisSensorHandle& device_handle) {
const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id));
const bool device_index = device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
if (!npad_id) {
return InvalidNpadId;
}
if (!device_index) {
return NpadDeviceIndexOutOfRange;
}
return ResultSuccess;
}
Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
KernelHelpers::ServiceContext& service_context_)
: ControllerBase{hid_core_}, service_context{service_context_} {
static_assert(NPAD_OFFSET + (NPAD_COUNT * sizeof(NpadInternalState)) < shared_memory_size);
for (std::size_t i = 0; i < controller_data.size(); ++i) {
@@ -52,7 +103,7 @@ NPad::NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
}
}
NPad::~NPad() {
Controller_NPad::~Controller_NPad() {
for (std::size_t i = 0; i < controller_data.size(); ++i) {
auto& controller = controller_data[i];
controller.device->DeleteCallback(controller.callback_key);
@@ -60,7 +111,8 @@ NPad::~NPad() {
OnRelease();
}
void NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx) {
void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
std::size_t controller_idx) {
if (type == Core::HID::ControllerTriggerType::All) {
ControllerUpdate(Core::HID::ControllerTriggerType::Connected, controller_idx);
ControllerUpdate(Core::HID::ControllerTriggerType::Battery, controller_idx);
@@ -98,7 +150,7 @@ void NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t c
}
}
void NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
auto& controller = GetControllerFromNpadIdType(npad_id);
if (!IsControllerSupported(controller.device->GetNpadStyleIndex())) {
return;
@@ -292,13 +344,12 @@ void NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::AllDevices,
Common::Input::PollingMode::Active);
}
SignalStyleSetChangedEvent(npad_id);
WriteEmptyEntry(controller.shared_memory);
hid_core.SetLastActiveController(npad_id);
}
void NPad::OnInit() {
void Controller_NPad::OnInit() {
if (!IsControllerActivated()) {
return;
}
@@ -332,7 +383,7 @@ void NPad::OnInit() {
}
}
void NPad::WriteEmptyEntry(NpadInternalState* npad) {
void Controller_NPad::WriteEmptyEntry(NpadInternalState* npad) {
NPadGenericState dummy_pad_state{};
NpadGcTriggerState dummy_gc_state{};
dummy_pad_state.sampling_number = npad->fullkey_lifo.ReadCurrentEntry().sampling_number + 1;
@@ -353,7 +404,7 @@ void NPad::WriteEmptyEntry(NpadInternalState* npad) {
npad->gc_trigger_lifo.WriteNextEntry(dummy_gc_state);
}
void NPad::OnRelease() {
void Controller_NPad::OnRelease() {
is_controller_initialized = false;
for (std::size_t i = 0; i < controller_data.size(); ++i) {
auto& controller = controller_data[i];
@@ -364,7 +415,7 @@ void NPad::OnRelease() {
}
}
void NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
void Controller_NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
std::scoped_lock lock{mutex};
auto& controller = GetControllerFromNpadIdType(npad_id);
const auto controller_type = controller.device->GetNpadStyleIndex();
@@ -406,14 +457,12 @@ void NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
pad_entry.l_stick = stick_state.left;
}
if (controller_type == Core::HID::NpadStyleIndex::JoyconLeft ||
controller_type == Core::HID::NpadStyleIndex::JoyconDual) {
if (controller_type == Core::HID::NpadStyleIndex::JoyconLeft) {
pad_entry.npad_buttons.left_sl.Assign(button_state.left_sl);
pad_entry.npad_buttons.left_sr.Assign(button_state.left_sr);
}
if (controller_type == Core::HID::NpadStyleIndex::JoyconRight ||
controller_type == Core::HID::NpadStyleIndex::JoyconDual) {
if (controller_type == Core::HID::NpadStyleIndex::JoyconRight) {
pad_entry.npad_buttons.right_sl.Assign(button_state.right_sl);
pad_entry.npad_buttons.right_sr.Assign(button_state.right_sr);
}
@@ -433,7 +482,7 @@ void NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
}
}
void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
return;
}
@@ -563,7 +612,134 @@ void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
}
}
void NPad::SetSupportedStyleSet(Core::HID::NpadStyleTag style_set) {
void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
return;
}
for (std::size_t i = 0; i < controller_data.size(); ++i) {
auto& controller = controller_data[i];
const auto& controller_type = controller.device->GetNpadStyleIndex();
if (controller_type == Core::HID::NpadStyleIndex::None ||
!controller.device->IsConnected()) {
continue;
}
auto* npad = controller.shared_memory;
const auto& motion_state = controller.device->GetMotions();
auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state;
auto& sixaxis_handheld_state = controller.sixaxis_handheld_state;
auto& sixaxis_dual_left_state = controller.sixaxis_dual_left_state;
auto& sixaxis_dual_right_state = controller.sixaxis_dual_right_state;
auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state;
auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state;
// Clear previous state
sixaxis_fullkey_state = {};
sixaxis_handheld_state = {};
sixaxis_dual_left_state = {};
sixaxis_dual_right_state = {};
sixaxis_left_lifo_state = {};
sixaxis_right_lifo_state = {};
if (controller.sixaxis_sensor_enabled && Settings::values.motion_enabled.GetValue()) {
controller.sixaxis_at_rest = true;
for (std::size_t e = 0; e < motion_state.size(); ++e) {
controller.sixaxis_at_rest =
controller.sixaxis_at_rest && motion_state[e].is_at_rest;
}
}
const auto set_motion_state = [&](SixAxisSensorState& state,
const Core::HID::ControllerMotion& hid_state) {
using namespace std::literals::chrono_literals;
static constexpr SixAxisSensorState default_motion_state = {
.delta_time = std::chrono::nanoseconds(5ms).count(),
.accel = {0, 0, -1.0f},
.orientation =
{
Common::Vec3f{1.0f, 0, 0},
Common::Vec3f{0, 1.0f, 0},
Common::Vec3f{0, 0, 1.0f},
},
.attribute = {1},
};
if (!controller.sixaxis_sensor_enabled) {
state = default_motion_state;
return;
}
if (!Settings::values.motion_enabled.GetValue()) {
state = default_motion_state;
return;
}
state.attribute.is_connected.Assign(1);
state.delta_time = std::chrono::nanoseconds(5ms).count();
state.accel = hid_state.accel;
state.gyro = hid_state.gyro;
state.rotation = hid_state.rotation;
state.orientation = hid_state.orientation;
};
switch (controller_type) {
case Core::HID::NpadStyleIndex::None:
ASSERT(false);
break;
case Core::HID::NpadStyleIndex::ProController:
set_motion_state(sixaxis_fullkey_state, motion_state[0]);
break;
case Core::HID::NpadStyleIndex::Handheld:
set_motion_state(sixaxis_handheld_state, motion_state[0]);
break;
case Core::HID::NpadStyleIndex::JoyconDual:
set_motion_state(sixaxis_dual_left_state, motion_state[0]);
set_motion_state(sixaxis_dual_right_state, motion_state[1]);
break;
case Core::HID::NpadStyleIndex::JoyconLeft:
set_motion_state(sixaxis_left_lifo_state, motion_state[0]);
break;
case Core::HID::NpadStyleIndex::JoyconRight:
set_motion_state(sixaxis_right_lifo_state, motion_state[1]);
break;
case Core::HID::NpadStyleIndex::Pokeball:
using namespace std::literals::chrono_literals;
set_motion_state(sixaxis_fullkey_state, motion_state[0]);
sixaxis_fullkey_state.delta_time = std::chrono::nanoseconds(15ms).count();
break;
default:
break;
}
sixaxis_fullkey_state.sampling_number =
npad->sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_handheld_state.sampling_number =
npad->sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_dual_left_state.sampling_number =
npad->sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_dual_right_state.sampling_number =
npad->sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_left_lifo_state.sampling_number =
npad->sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_right_lifo_state.sampling_number =
npad->sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
if (Core::HID::IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) {
// This buffer only is updated on handheld on HW
npad->sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state);
} else {
// Handheld doesn't update this buffer on HW
npad->sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state);
}
npad->sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state);
npad->sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state);
npad->sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state);
npad->sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state);
}
}
void Controller_NPad::SetSupportedStyleSet(Core::HID::NpadStyleTag style_set) {
hid_core.SetSupportedStyleTag(style_set);
if (is_controller_initialized) {
@@ -574,14 +750,14 @@ void NPad::SetSupportedStyleSet(Core::HID::NpadStyleTag style_set) {
is_controller_initialized = true;
}
Core::HID::NpadStyleTag NPad::GetSupportedStyleSet() const {
Core::HID::NpadStyleTag Controller_NPad::GetSupportedStyleSet() const {
if (!is_controller_initialized) {
return {Core::HID::NpadStyleSet::None};
}
return hid_core.GetSupportedStyleTag();
}
Result NPad::SetSupportedNpadIdTypes(std::span<const u8> data) {
Result Controller_NPad::SetSupportedNpadIdTypes(std::span<const u8> data) {
constexpr std::size_t max_number_npad_ids = 0xa;
const auto length = data.size();
ASSERT(length > 0 && (length % sizeof(u32)) == 0);
@@ -597,17 +773,17 @@ Result NPad::SetSupportedNpadIdTypes(std::span<const u8> data) {
return ResultSuccess;
}
void NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) {
void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) {
const auto copy_amount = supported_npad_id_types.size() * sizeof(u32);
ASSERT(max_length <= copy_amount);
std::memcpy(data, supported_npad_id_types.data(), copy_amount);
}
std::size_t NPad::GetSupportedNpadIdTypesSize() const {
std::size_t Controller_NPad::GetSupportedNpadIdTypesSize() const {
return supported_npad_id_types.size();
}
void NPad::SetHoldType(NpadJoyHoldType joy_hold_type) {
void Controller_NPad::SetHoldType(NpadJoyHoldType joy_hold_type) {
if (joy_hold_type != NpadJoyHoldType::Horizontal &&
joy_hold_type != NpadJoyHoldType::Vertical) {
LOG_ERROR(Service_HID, "Npad joy hold type needs to be valid, joy_hold_type={}",
@@ -617,11 +793,11 @@ void NPad::SetHoldType(NpadJoyHoldType joy_hold_type) {
hold_type = joy_hold_type;
}
NPad::NpadJoyHoldType NPad::GetHoldType() const {
Controller_NPad::NpadJoyHoldType Controller_NPad::GetHoldType() const {
return hold_type;
}
void NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode) {
void Controller_NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode) {
if (activation_mode >= NpadHandheldActivationMode::MaxActivationMode) {
ASSERT_MSG(false, "Activation mode should be always None, Single or Dual");
return;
@@ -630,20 +806,21 @@ void NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_m
handheld_activation_mode = activation_mode;
}
NPad::NpadHandheldActivationMode NPad::GetNpadHandheldActivationMode() const {
Controller_NPad::NpadHandheldActivationMode Controller_NPad::GetNpadHandheldActivationMode() const {
return handheld_activation_mode;
}
void NPad::SetNpadCommunicationMode(NpadCommunicationMode communication_mode_) {
void Controller_NPad::SetNpadCommunicationMode(NpadCommunicationMode communication_mode_) {
communication_mode = communication_mode_;
}
NPad::NpadCommunicationMode NPad::GetNpadCommunicationMode() const {
Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode() const {
return communication_mode;
}
bool NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode) {
bool Controller_NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
NpadJoyDeviceType npad_device_type,
NpadJoyAssignmentMode assignment_mode) {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
return false;
@@ -712,8 +889,9 @@ bool NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType
return true;
}
bool NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index,
const Core::HID::VibrationValue& vibration_value) {
bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id,
std::size_t device_index,
const Core::HID::VibrationValue& vibration_value) {
auto& controller = GetControllerFromNpadIdType(npad_id);
if (!controller.device->IsConnected()) {
return false;
@@ -757,9 +935,10 @@ bool NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t d
return controller.device->SetVibration(device_index, vibration);
}
void NPad::VibrateController(const Core::HID::VibrationDeviceHandle& vibration_device_handle,
const Core::HID::VibrationValue& vibration_value) {
if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
void Controller_NPad::VibrateController(
const Core::HID::VibrationDeviceHandle& vibration_device_handle,
const Core::HID::VibrationValue& vibration_value) {
if (IsDeviceHandleValid(vibration_device_handle).IsError()) {
return;
}
@@ -803,7 +982,7 @@ void NPad::VibrateController(const Core::HID::VibrationDeviceHandle& vibration_d
}
}
void NPad::VibrateControllers(
void Controller_NPad::VibrateControllers(
std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles,
std::span<const Core::HID::VibrationValue> vibration_values) {
if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) {
@@ -820,9 +999,9 @@ void NPad::VibrateControllers(
}
}
Core::HID::VibrationValue NPad::GetLastVibration(
Core::HID::VibrationValue Controller_NPad::GetLastVibration(
const Core::HID::VibrationDeviceHandle& vibration_device_handle) const {
if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
if (IsDeviceHandleValid(vibration_device_handle).IsError()) {
return {};
}
@@ -831,9 +1010,9 @@ Core::HID::VibrationValue NPad::GetLastVibration(
return controller.vibration[device_index].latest_vibration_value;
}
void NPad::InitializeVibrationDevice(
void Controller_NPad::InitializeVibrationDevice(
const Core::HID::VibrationDeviceHandle& vibration_device_handle) {
if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
if (IsDeviceHandleValid(vibration_device_handle).IsError()) {
return;
}
@@ -842,8 +1021,8 @@ void NPad::InitializeVibrationDevice(
InitializeVibrationDeviceAtIndex(npad_index, device_index);
}
void NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npad_id,
std::size_t device_index) {
void Controller_NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npad_id,
std::size_t device_index) {
auto& controller = GetControllerFromNpadIdType(npad_id);
if (!Settings::values.vibration_enabled.GetValue()) {
controller.vibration[device_index].device_mounted = false;
@@ -854,13 +1033,13 @@ void NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npad_id,
controller.device->IsVibrationEnabled(device_index);
}
void NPad::SetPermitVibrationSession(bool permit_vibration_session) {
void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) {
permit_vibration_session_enabled = permit_vibration_session;
}
bool NPad::IsVibrationDeviceMounted(
bool Controller_NPad::IsVibrationDeviceMounted(
const Core::HID::VibrationDeviceHandle& vibration_device_handle) const {
if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
if (IsDeviceHandleValid(vibration_device_handle).IsError()) {
return false;
}
@@ -869,7 +1048,7 @@ bool NPad::IsVibrationDeviceMounted(
return controller.vibration[device_index].device_mounted;
}
Kernel::KReadableEvent& NPad::GetStyleSetChangedEvent(Core::HID::NpadIdType npad_id) {
Kernel::KReadableEvent& Controller_NPad::GetStyleSetChangedEvent(Core::HID::NpadIdType npad_id) {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
// Fallback to player 1
@@ -881,17 +1060,18 @@ Kernel::KReadableEvent& NPad::GetStyleSetChangedEvent(Core::HID::NpadIdType npad
return controller.styleset_changed_event->GetReadableEvent();
}
void NPad::SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const {
void Controller_NPad::SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const {
const auto& controller = GetControllerFromNpadIdType(npad_id);
controller.styleset_changed_event->Signal();
}
void NPad::AddNewControllerAt(Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id) {
void Controller_NPad::AddNewControllerAt(Core::HID::NpadStyleIndex controller,
Core::HID::NpadIdType npad_id) {
UpdateControllerAt(controller, npad_id, true);
}
void NPad::UpdateControllerAt(Core::HID::NpadStyleIndex type, Core::HID::NpadIdType npad_id,
bool connected) {
void Controller_NPad::UpdateControllerAt(Core::HID::NpadStyleIndex type,
Core::HID::NpadIdType npad_id, bool connected) {
auto& controller = GetControllerFromNpadIdType(npad_id);
if (!connected) {
DisconnectNpad(npad_id);
@@ -902,7 +1082,7 @@ void NPad::UpdateControllerAt(Core::HID::NpadStyleIndex type, Core::HID::NpadIdT
InitNewlyAddedController(npad_id);
}
Result NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
Result Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
return InvalidNpadId;
@@ -951,9 +1131,54 @@ Result NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
return ResultSuccess;
}
Result NPad::IsFirmwareUpdateAvailableForSixAxisSensor(
Result Controller_NPad::SetGyroscopeZeroDriftMode(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::GyroscopeZeroDriftMode drift_mode) {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
auto& sixaxis = GetSixaxisState(sixaxis_handle);
auto& controller = GetControllerFromHandle(sixaxis_handle);
sixaxis.gyroscope_zero_drift_mode = drift_mode;
controller.device->SetGyroscopeZeroDriftMode(drift_mode);
return ResultSuccess;
}
Result Controller_NPad::GetGyroscopeZeroDriftMode(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::GyroscopeZeroDriftMode& drift_mode) const {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
const auto& sixaxis = GetSixaxisState(sixaxis_handle);
drift_mode = sixaxis.gyroscope_zero_drift_mode;
return ResultSuccess;
}
Result Controller_NPad::IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool& is_at_rest) const {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
const auto& controller = GetControllerFromHandle(sixaxis_handle);
is_at_rest = controller.sixaxis_at_rest;
return ResultSuccess;
}
Result Controller_NPad::IsFirmwareUpdateAvailableForSixAxisSensor(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const {
const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
@@ -964,9 +1189,65 @@ Result NPad::IsFirmwareUpdateAvailableForSixAxisSensor(
return ResultSuccess;
}
Result NPad::ResetIsSixAxisSensorDeviceNewlyAssigned(
Result Controller_NPad::EnableSixAxisSensorUnalteredPassthrough(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled) {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
auto& sixaxis = GetSixaxisState(sixaxis_handle);
sixaxis.unaltered_passtrough = is_enabled;
return ResultSuccess;
}
Result Controller_NPad::IsSixAxisSensorUnalteredPassthroughEnabled(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
const auto& sixaxis = GetSixaxisState(sixaxis_handle);
is_enabled = sixaxis.unaltered_passtrough;
return ResultSuccess;
}
Result Controller_NPad::LoadSixAxisSensorCalibrationParameter(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorCalibrationParameter& calibration) const {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
// TODO: Request this data to the controller. On error return 0xd8ca
const auto& sixaxis = GetSixaxisState(sixaxis_handle);
calibration = sixaxis.calibration;
return ResultSuccess;
}
Result Controller_NPad::GetSixAxisSensorIcInformation(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorIcInformation& ic_information) const {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
// TODO: Request this data to the controller. On error return 0xd8ca
const auto& sixaxis = GetSixaxisState(sixaxis_handle);
ic_information = sixaxis.ic_information;
return ResultSuccess;
}
Result Controller_NPad::ResetIsSixAxisSensorDeviceNewlyAssigned(
const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
@@ -978,32 +1259,83 @@ Result NPad::ResetIsSixAxisSensorDeviceNewlyAssigned(
return ResultSuccess;
}
NPad::SixAxisLifo& NPad::GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id) {
return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_fullkey_lifo;
Result Controller_NPad::SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool sixaxis_status) {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
auto& controller = GetControllerFromHandle(sixaxis_handle);
controller.sixaxis_sensor_enabled = sixaxis_status;
return ResultSuccess;
}
NPad::SixAxisLifo& NPad::GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id) {
return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_handheld_lifo;
Result Controller_NPad::IsSixAxisSensorFusionEnabled(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_fusion_enabled) const {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
const auto& sixaxis = GetSixaxisState(sixaxis_handle);
is_fusion_enabled = sixaxis.is_fusion_enabled;
return ResultSuccess;
}
Result Controller_NPad::SetSixAxisFusionEnabled(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_fusion_enabled) {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
auto& sixaxis = GetSixaxisState(sixaxis_handle);
sixaxis.is_fusion_enabled = is_fusion_enabled;
return ResultSuccess;
}
NPad::SixAxisLifo& NPad::GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id) {
return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_left_lifo;
Result Controller_NPad::SetSixAxisFusionParameters(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters) {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
const auto param1 = sixaxis_fusion_parameters.parameter1;
if (param1 < 0.0f || param1 > 1.0f) {
return InvalidSixAxisFusionRange;
}
auto& sixaxis = GetSixaxisState(sixaxis_handle);
sixaxis.fusion = sixaxis_fusion_parameters;
return ResultSuccess;
}
NPad::SixAxisLifo& NPad::GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id) {
return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_right_lifo;
Result Controller_NPad::GetSixAxisFusionParameters(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorFusionParameters& parameters) const {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
const auto& sixaxis = GetSixaxisState(sixaxis_handle);
parameters = sixaxis.fusion;
return ResultSuccess;
}
NPad::SixAxisLifo& NPad::GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id) {
return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_left_lifo;
}
NPad::SixAxisLifo& 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,
Core::HID::NpadIdType npad_id_2) {
Result Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
Core::HID::NpadIdType npad_id_2) {
if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1,
npad_id_2);
@@ -1065,17 +1397,18 @@ Result NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
return ResultSuccess;
}
void NPad::StartLRAssignmentMode() {
void Controller_NPad::StartLRAssignmentMode() {
// Nothing internally is used for lr assignment mode. Since we have the ability to set the
// controller types from boot, it doesn't really matter about showing a selection screen
is_in_lr_assignment_mode = true;
}
void NPad::StopLRAssignmentMode() {
void Controller_NPad::StopLRAssignmentMode() {
is_in_lr_assignment_mode = false;
}
Result NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2) {
Result Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1,
Core::HID::NpadIdType npad_id_2) {
if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1,
npad_id_2);
@@ -1106,7 +1439,8 @@ Result NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::Npad
return ResultSuccess;
}
Result NPad::GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const {
Result Controller_NPad::GetLedPattern(Core::HID::NpadIdType npad_id,
Core::HID::LedPattern& pattern) const {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
return InvalidNpadId;
@@ -1116,8 +1450,8 @@ Result NPad::GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern&
return ResultSuccess;
}
Result NPad::IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id,
bool& is_valid) const {
Result Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id,
bool& is_valid) const {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
return InvalidNpadId;
@@ -1127,8 +1461,8 @@ Result NPad::IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType
return ResultSuccess;
}
Result NPad::SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled,
Core::HID::NpadIdType npad_id) {
Result Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled(
bool is_protection_enabled, Core::HID::NpadIdType npad_id) {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
return InvalidNpadId;
@@ -1138,11 +1472,11 @@ Result NPad::SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_en
return ResultSuccess;
}
void NPad::SetAnalogStickUseCenterClamp(bool use_center_clamp) {
void Controller_NPad::SetAnalogStickUseCenterClamp(bool use_center_clamp) {
analog_stick_use_center_clamp = use_center_clamp;
}
void NPad::ClearAllConnectedControllers() {
void Controller_NPad::ClearAllConnectedControllers() {
for (auto& controller : controller_data) {
if (controller.device->IsConnected() &&
controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None) {
@@ -1152,13 +1486,13 @@ void NPad::ClearAllConnectedControllers() {
}
}
void NPad::DisconnectAllConnectedControllers() {
void Controller_NPad::DisconnectAllConnectedControllers() {
for (auto& controller : controller_data) {
controller.device->Disconnect();
}
}
void NPad::ConnectAllDisconnectedControllers() {
void Controller_NPad::ConnectAllDisconnectedControllers() {
for (auto& controller : controller_data) {
if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None &&
!controller.device->IsConnected()) {
@@ -1167,18 +1501,18 @@ void NPad::ConnectAllDisconnectedControllers() {
}
}
void NPad::ClearAllControllers() {
void Controller_NPad::ClearAllControllers() {
for (auto& controller : controller_data) {
controller.device->Disconnect();
controller.device->SetNpadStyleIndex(Core::HID::NpadStyleIndex::None);
}
}
Core::HID::NpadButton NPad::GetAndResetPressState() {
Core::HID::NpadButton Controller_NPad::GetAndResetPressState() {
return static_cast<Core::HID::NpadButton>(press_state.exchange(0));
}
void NPad::ApplyNpadSystemCommonPolicy() {
void Controller_NPad::ApplyNpadSystemCommonPolicy() {
Core::HID::NpadStyleTag styletag{};
styletag.fullkey.Assign(1);
styletag.handheld.Assign(1);
@@ -1203,7 +1537,7 @@ void NPad::ApplyNpadSystemCommonPolicy() {
supported_npad_id_types[9] = Core::HID::NpadIdType::Handheld;
}
bool NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller) const {
bool Controller_NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller) const {
if (controller == Core::HID::NpadStyleIndex::Handheld) {
const bool support_handheld =
std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(),
@@ -1254,50 +1588,51 @@ bool NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller) const {
return false;
}
NPad::NpadControllerData& NPad::GetControllerFromHandle(
const Core::HID::VibrationDeviceHandle& device_handle) {
const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
return GetControllerFromNpadIdType(npad_id);
}
const NPad::NpadControllerData& NPad::GetControllerFromHandle(
const Core::HID::VibrationDeviceHandle& device_handle) const {
const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
return GetControllerFromNpadIdType(npad_id);
}
NPad::NpadControllerData& NPad::GetControllerFromHandle(
Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle(
const Core::HID::SixAxisSensorHandle& device_handle) {
const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
return GetControllerFromNpadIdType(npad_id);
}
const NPad::NpadControllerData& NPad::GetControllerFromHandle(
const Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle(
const Core::HID::SixAxisSensorHandle& device_handle) const {
const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
return GetControllerFromNpadIdType(npad_id);
}
NPad::NpadControllerData& NPad::GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) {
Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle(
const Core::HID::VibrationDeviceHandle& device_handle) {
const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
return GetControllerFromNpadIdType(npad_id);
}
const Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle(
const Core::HID::VibrationDeviceHandle& device_handle) const {
const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
return GetControllerFromNpadIdType(npad_id);
}
Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromNpadIdType(
Core::HID::NpadIdType npad_id) {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
npad_id = Core::HID::NpadIdType::Player1;
}
const auto npad_index = NpadIdTypeToIndex(npad_id);
const auto npad_index = Core::HID::NpadIdTypeToIndex(npad_id);
return controller_data[npad_index];
}
const NPad::NpadControllerData& NPad::GetControllerFromNpadIdType(
const Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromNpadIdType(
Core::HID::NpadIdType npad_id) const {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
npad_id = Core::HID::NpadIdType::Player1;
}
const auto npad_index = NpadIdTypeToIndex(npad_id);
const auto npad_index = Core::HID::NpadIdTypeToIndex(npad_id);
return controller_data[npad_index];
}
Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties(
Core::HID::SixAxisSensorProperties& Controller_NPad::GetSixaxisProperties(
const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
auto& controller = GetControllerFromHandle(sixaxis_handle);
switch (sixaxis_handle.npad_type) {
@@ -1320,7 +1655,7 @@ Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties(
}
}
const Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties(
const Core::HID::SixAxisSensorProperties& Controller_NPad::GetSixaxisProperties(
const Core::HID::SixAxisSensorHandle& sixaxis_handle) const {
const auto& controller = GetControllerFromHandle(sixaxis_handle);
switch (sixaxis_handle.npad_type) {
@@ -1343,13 +1678,50 @@ const Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties(
}
}
NPad::AppletDetailedUiType NPad::GetAppletDetailedUiType(Core::HID::NpadIdType npad_id) {
const auto& shared_memory = GetControllerFromNpadIdType(npad_id).shared_memory;
Controller_NPad::SixaxisParameters& Controller_NPad::GetSixaxisState(
const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
auto& controller = GetControllerFromHandle(sixaxis_handle);
switch (sixaxis_handle.npad_type) {
case Core::HID::NpadStyleIndex::ProController:
case Core::HID::NpadStyleIndex::Pokeball:
return controller.sixaxis_fullkey;
case Core::HID::NpadStyleIndex::Handheld:
return controller.sixaxis_handheld;
case Core::HID::NpadStyleIndex::JoyconDual:
if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
return controller.sixaxis_dual_left;
}
return controller.sixaxis_dual_right;
case Core::HID::NpadStyleIndex::JoyconLeft:
return controller.sixaxis_left;
case Core::HID::NpadStyleIndex::JoyconRight:
return controller.sixaxis_right;
default:
return controller.sixaxis_unknown;
}
}
return {
.ui_variant = 0,
.footer = shared_memory->applet_footer_type,
};
const Controller_NPad::SixaxisParameters& Controller_NPad::GetSixaxisState(
const Core::HID::SixAxisSensorHandle& sixaxis_handle) const {
const auto& controller = GetControllerFromHandle(sixaxis_handle);
switch (sixaxis_handle.npad_type) {
case Core::HID::NpadStyleIndex::ProController:
case Core::HID::NpadStyleIndex::Pokeball:
return controller.sixaxis_fullkey;
case Core::HID::NpadStyleIndex::Handheld:
return controller.sixaxis_handheld;
case Core::HID::NpadStyleIndex::JoyconDual:
if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
return controller.sixaxis_dual_left;
}
return controller.sixaxis_dual_right;
case Core::HID::NpadStyleIndex::JoyconLeft:
return controller.sixaxis_left;
case Core::HID::NpadStyleIndex::JoyconRight:
return controller.sixaxis_right;
default:
return controller.sixaxis_unknown;
}
}
} // namespace Service::HID

View File

@@ -10,6 +10,7 @@
#include "common/bit_field.h"
#include "common/common_types.h"
#include "common/vector_math.h"
#include "core/hid/hid_types.h"
#include "core/hle/service/hid/controllers/controller_base.h"
@@ -33,11 +34,11 @@ union Result;
namespace Service::HID {
class NPad final : public ControllerBase {
class Controller_NPad final : public ControllerBase {
public:
explicit NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
KernelHelpers::ServiceContext& service_context_);
~NPad() override;
explicit Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
KernelHelpers::ServiceContext& service_context_);
~Controller_NPad() override;
// Called when the controller is initialized
void OnInit() override;
@@ -48,6 +49,9 @@ public:
// When the controller is requesting an update for the shared memory
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
// When the controller is requesting a motion update for the shared memory
void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) override;
// This is nn::hid::NpadJoyHoldType
enum class NpadJoyHoldType : u64 {
Vertical = 0,
@@ -74,46 +78,6 @@ public:
MaxActivationMode = 3,
};
// This is nn::hid::system::AppletFooterUiAttributesSet
struct AppletFooterUiAttributes {
INSERT_PADDING_BYTES(0x4);
};
// This is nn::hid::system::AppletFooterUiType
enum class AppletFooterUiType : u8 {
None = 0,
HandheldNone = 1,
HandheldJoyConLeftOnly = 2,
HandheldJoyConRightOnly = 3,
HandheldJoyConLeftJoyConRight = 4,
JoyDual = 5,
JoyDualLeftOnly = 6,
JoyDualRightOnly = 7,
JoyLeftHorizontal = 8,
JoyLeftVertical = 9,
JoyRightHorizontal = 10,
JoyRightVertical = 11,
SwitchProController = 12,
CompatibleProController = 13,
CompatibleJoyCon = 14,
LarkHvc1 = 15,
LarkHvc2 = 16,
LarkNesLeft = 17,
LarkNesRight = 18,
Lucia = 19,
Verification = 20,
Lagon = 21,
};
using AppletFooterUiVariant = u8;
// This is "nn::hid::system::AppletDetailedUiType".
struct AppletDetailedUiType {
AppletFooterUiVariant ui_variant;
INSERT_PADDING_BYTES(0x2);
AppletFooterUiType footer;
};
static_assert(sizeof(AppletDetailedUiType) == 0x4, "AppletDetailedUiType is an invalid size");
// This is nn::hid::NpadCommunicationMode
enum class NpadCommunicationMode : u64 {
Mode_5ms = 0,
@@ -122,15 +86,6 @@ public:
Default = 3,
};
enum class NpadRevision : u32 {
Revision0 = 0,
Revision1 = 1,
Revision2 = 2,
Revision3 = 3,
};
using SixAxisLifo = Lifo<Core::HID::SixAxisSensorState, hid_entry_count>;
void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set);
Core::HID::NpadStyleTag GetSupportedStyleSet() const;
@@ -183,18 +138,37 @@ public:
Result DisconnectNpad(Core::HID::NpadIdType npad_id);
Result SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::GyroscopeZeroDriftMode drift_mode);
Result GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::GyroscopeZeroDriftMode& drift_mode) const;
Result IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool& is_at_rest) const;
Result IsFirmwareUpdateAvailableForSixAxisSensor(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const;
Result EnableSixAxisSensorUnalteredPassthrough(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled);
Result IsSixAxisSensorUnalteredPassthroughEnabled(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const;
Result LoadSixAxisSensorCalibrationParameter(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorCalibrationParameter& calibration) const;
Result GetSixAxisSensorIcInformation(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorIcInformation& ic_information) const;
Result ResetIsSixAxisSensorDeviceNewlyAssigned(
const Core::HID::SixAxisSensorHandle& sixaxis_handle);
SixAxisLifo& GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id);
SixAxisLifo& GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id);
SixAxisLifo& GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id);
SixAxisLifo& GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id);
SixAxisLifo& GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id);
SixAxisLifo& GetSixAxisRightLifo(Core::HID::NpadIdType npad_id);
Result SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool sixaxis_status);
Result IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool& is_fusion_enabled) const;
Result SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool is_fusion_enabled);
Result SetSixAxisFusionParameters(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters);
Result GetSixAxisFusionParameters(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorFusionParameters& parameters) const;
Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const;
Result IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id,
bool& is_enabled) const;
@@ -218,7 +192,10 @@ public:
void ApplyNpadSystemCommonPolicy();
AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id);
static bool IsNpadIdValid(Core::HID::NpadIdType npad_id);
static Result IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle);
static Result VerifyValidSixAxisSensorHandle(
const Core::HID::SixAxisSensorHandle& device_handle);
private:
static constexpr std::size_t NPAD_COUNT = 10;
@@ -277,6 +254,29 @@ private:
};
static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size");
// This is nn::hid::SixAxisSensorAttribute
struct SixAxisSensorAttribute {
union {
u32 raw{};
BitField<0, 1, u32> is_connected;
BitField<1, 1, u32> is_interpolated;
};
};
static_assert(sizeof(SixAxisSensorAttribute) == 4, "SixAxisSensorAttribute is an invalid size");
// This is nn::hid::SixAxisSensorState
struct SixAxisSensorState {
s64 delta_time{};
s64 sampling_number{};
Common::Vec3f accel{};
Common::Vec3f gyro{};
Common::Vec3f rotation{};
std::array<Common::Vec3f, 3> orientation{};
SixAxisSensorAttribute attribute{};
INSERT_PADDING_BYTES(4); // Reserved
};
static_assert(sizeof(SixAxisSensorState) == 0x60, "SixAxisSensorState is an invalid size");
// This is nn::hid::server::NpadGcTriggerState
struct NpadGcTriggerState {
s64 sampling_number{};
@@ -353,6 +353,37 @@ private:
static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18,
"NfcXcdDeviceHandleStateImpl is an invalid size");
// This is nn::hid::system::AppletFooterUiAttributesSet
struct AppletFooterUiAttributes {
INSERT_PADDING_BYTES(0x4);
};
// This is nn::hid::system::AppletFooterUiType
enum class AppletFooterUiType : u8 {
None = 0,
HandheldNone = 1,
HandheldJoyConLeftOnly = 2,
HandheldJoyConRightOnly = 3,
HandheldJoyConLeftJoyConRight = 4,
JoyDual = 5,
JoyDualLeftOnly = 6,
JoyDualRightOnly = 7,
JoyLeftHorizontal = 8,
JoyLeftVertical = 9,
JoyRightHorizontal = 10,
JoyRightVertical = 11,
SwitchProController = 12,
CompatibleProController = 13,
CompatibleJoyCon = 14,
LarkHvc1 = 15,
LarkHvc2 = 16,
LarkNesLeft = 17,
LarkNesRight = 18,
Lucia = 19,
Verification = 20,
Lagon = 21,
};
// This is nn::hid::NpadLarkType
enum class NpadLarkType : u32 {
Invalid,
@@ -396,12 +427,12 @@ private:
Lifo<NPadGenericState, hid_entry_count> joy_right_lifo{};
Lifo<NPadGenericState, hid_entry_count> palma_lifo{};
Lifo<NPadGenericState, hid_entry_count> system_ext_lifo{};
Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_fullkey_lifo{};
Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_handheld_lifo{};
Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_dual_left_lifo{};
Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_dual_right_lifo{};
Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_left_lifo{};
Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_right_lifo{};
Lifo<SixAxisSensorState, hid_entry_count> sixaxis_fullkey_lifo{};
Lifo<SixAxisSensorState, hid_entry_count> sixaxis_handheld_lifo{};
Lifo<SixAxisSensorState, hid_entry_count> sixaxis_dual_left_lifo{};
Lifo<SixAxisSensorState, hid_entry_count> sixaxis_dual_right_lifo{};
Lifo<SixAxisSensorState, hid_entry_count> sixaxis_left_lifo{};
Lifo<SixAxisSensorState, hid_entry_count> sixaxis_right_lifo{};
DeviceType device_type{};
INSERT_PADDING_BYTES(0x4); // Reserved
NPadSystemProperties system_properties{};
@@ -435,6 +466,16 @@ private:
std::chrono::steady_clock::time_point last_vibration_timepoint{};
};
struct SixaxisParameters {
bool is_fusion_enabled{true};
bool unaltered_passtrough{false};
Core::HID::SixAxisSensorFusionParameters fusion{};
Core::HID::SixAxisSensorCalibrationParameter calibration{};
Core::HID::SixAxisSensorIcInformation ic_information{};
Core::HID::GyroscopeZeroDriftMode gyroscope_zero_drift_mode{
Core::HID::GyroscopeZeroDriftMode::Standard};
};
struct NpadControllerData {
Kernel::KEvent* styleset_changed_event{};
NpadInternalState* shared_memory = nullptr;
@@ -448,10 +489,27 @@ private:
bool is_dual_left_connected{true};
bool is_dual_right_connected{true};
// Motion parameters
bool sixaxis_at_rest{true};
bool sixaxis_sensor_enabled{true};
SixaxisParameters sixaxis_fullkey{};
SixaxisParameters sixaxis_handheld{};
SixaxisParameters sixaxis_dual_left{};
SixaxisParameters sixaxis_dual_right{};
SixaxisParameters sixaxis_left{};
SixaxisParameters sixaxis_right{};
SixaxisParameters sixaxis_unknown{};
// Current pad state
NPadGenericState npad_pad_state{};
NPadGenericState npad_libnx_state{};
NpadGcTriggerState npad_trigger_state{};
SixAxisSensorState sixaxis_fullkey_state{};
SixAxisSensorState sixaxis_handheld_state{};
SixAxisSensorState sixaxis_dual_left_state{};
SixAxisSensorState sixaxis_dual_right_state{};
SixAxisSensorState sixaxis_left_lifo_state{};
SixAxisSensorState sixaxis_right_lifo_state{};
int callback_key{};
};
@@ -461,14 +519,14 @@ private:
void RequestPadStateUpdate(Core::HID::NpadIdType npad_id);
void WriteEmptyEntry(NpadInternalState* npad);
NpadControllerData& GetControllerFromHandle(
const Core::HID::VibrationDeviceHandle& device_handle);
const NpadControllerData& GetControllerFromHandle(
const Core::HID::VibrationDeviceHandle& device_handle) const;
NpadControllerData& GetControllerFromHandle(
const Core::HID::SixAxisSensorHandle& device_handle);
const NpadControllerData& GetControllerFromHandle(
const Core::HID::SixAxisSensorHandle& device_handle) const;
NpadControllerData& GetControllerFromHandle(
const Core::HID::VibrationDeviceHandle& device_handle);
const NpadControllerData& GetControllerFromHandle(
const Core::HID::VibrationDeviceHandle& device_handle) const;
NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id);
const NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) const;
@@ -476,6 +534,9 @@ private:
const Core::HID::SixAxisSensorHandle& device_handle);
const Core::HID::SixAxisSensorProperties& GetSixaxisProperties(
const Core::HID::SixAxisSensorHandle& device_handle) const;
SixaxisParameters& GetSixaxisState(const Core::HID::SixAxisSensorHandle& device_handle);
const SixaxisParameters& GetSixaxisState(
const Core::HID::SixAxisSensorHandle& device_handle) const;
std::atomic<u64> press_state{};

View File

@@ -12,43 +12,43 @@
namespace Service::HID {
Palma::Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
KernelHelpers::ServiceContext& service_context_)
Controller_Palma::Controller_Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
KernelHelpers::ServiceContext& service_context_)
: ControllerBase{hid_core_}, service_context{service_context_} {
controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other);
operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent");
}
Palma::~Palma() {
Controller_Palma::~Controller_Palma() {
service_context.CloseEvent(operation_complete_event);
};
void Palma::OnInit() {}
void Controller_Palma::OnInit() {}
void Palma::OnRelease() {}
void Controller_Palma::OnRelease() {}
void Palma::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
void Controller_Palma::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
return;
}
}
Result Palma::GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id,
PalmaConnectionHandle& handle) {
Result Controller_Palma::GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id,
PalmaConnectionHandle& handle) {
active_handle.npad_id = npad_id;
handle = active_handle;
return ResultSuccess;
}
Result Palma::InitializePalma(const PalmaConnectionHandle& handle) {
Result Controller_Palma::InitializePalma(const PalmaConnectionHandle& handle) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
Activate();
ActivateController();
return ResultSuccess;
}
Kernel::KReadableEvent& Palma::AcquirePalmaOperationCompleteEvent(
Kernel::KReadableEvent& Controller_Palma::AcquirePalmaOperationCompleteEvent(
const PalmaConnectionHandle& handle) const {
if (handle.npad_id != active_handle.npad_id) {
LOG_ERROR(Service_HID, "Invalid npad id {}", handle.npad_id);
@@ -56,9 +56,9 @@ Kernel::KReadableEvent& Palma::AcquirePalmaOperationCompleteEvent(
return operation_complete_event->GetReadableEvent();
}
Result Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& handle,
PalmaOperationType& operation_type,
PalmaOperationData& data) const {
Result Controller_Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& handle,
PalmaOperationType& operation_type,
PalmaOperationData& data) const {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -67,7 +67,8 @@ Result Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& handle,
return ResultSuccess;
}
Result Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle, u64 palma_activity) {
Result Controller_Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle,
u64 palma_activity) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -78,7 +79,8 @@ Result Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle, u64 palma_a
return ResultSuccess;
}
Result Palma::SetPalmaFrModeType(const PalmaConnectionHandle& handle, PalmaFrModeType fr_mode_) {
Result Controller_Palma::SetPalmaFrModeType(const PalmaConnectionHandle& handle,
PalmaFrModeType fr_mode_) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -86,7 +88,7 @@ Result Palma::SetPalmaFrModeType(const PalmaConnectionHandle& handle, PalmaFrMod
return ResultSuccess;
}
Result Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) {
Result Controller_Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -97,25 +99,25 @@ Result Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) {
return ResultSuccess;
}
Result Palma::EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled) {
Result Controller_Palma::EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
return ResultSuccess;
}
Result Palma::ResetPalmaStep(const PalmaConnectionHandle& handle) {
Result Controller_Palma::ResetPalmaStep(const PalmaConnectionHandle& handle) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
return ResultSuccess;
}
void Palma::ReadPalmaApplicationSection() {}
void Controller_Palma::ReadPalmaApplicationSection() {}
void Palma::WritePalmaApplicationSection() {}
void Controller_Palma::WritePalmaApplicationSection() {}
Result Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle) {
Result Controller_Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -126,7 +128,7 @@ Result Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle) {
return ResultSuccess;
}
Result Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle) {
Result Controller_Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -137,9 +139,10 @@ Result Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle) {
return ResultSuccess;
}
void Palma::WritePalmaActivityEntry() {}
void Controller_Palma::WritePalmaActivityEntry() {}
Result Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, u64 unknown) {
Result Controller_Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle,
u64 unknown) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -150,8 +153,8 @@ Result Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle,
return ResultSuccess;
}
Result Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave,
Common::ProcessAddress t_mem, u64 size) {
Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave,
Common::ProcessAddress t_mem, u64 size) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -162,8 +165,8 @@ Result Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWave
return ResultSuccess;
}
Result Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle,
s32 database_id_version_) {
Result Controller_Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle,
s32 database_id_version_) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -175,7 +178,8 @@ Result Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle&
return ResultSuccess;
}
Result Palma::GetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle) {
Result Controller_Palma::GetPalmaDataBaseIdentificationVersion(
const PalmaConnectionHandle& handle) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -187,26 +191,26 @@ Result Palma::GetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle&
return ResultSuccess;
}
void Palma::SuspendPalmaFeature() {}
void Controller_Palma::SuspendPalmaFeature() {}
Result Palma::GetPalmaOperationResult(const PalmaConnectionHandle& handle) const {
Result Controller_Palma::GetPalmaOperationResult(const PalmaConnectionHandle& handle) const {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
return operation.result;
}
void Palma::ReadPalmaPlayLog() {}
void Controller_Palma::ReadPalmaPlayLog() {}
void Palma::ResetPalmaPlayLog() {}
void Controller_Palma::ResetPalmaPlayLog() {}
void Palma::SetIsPalmaAllConnectable(bool is_all_connectable) {
void Controller_Palma::SetIsPalmaAllConnectable(bool is_all_connectable) {
// If true controllers are able to be paired
is_connectable = is_all_connectable;
}
void Palma::SetIsPalmaPairedConnectable() {}
void Controller_Palma::SetIsPalmaPairedConnectable() {}
Result Palma::PairPalma(const PalmaConnectionHandle& handle) {
Result Controller_Palma::PairPalma(const PalmaConnectionHandle& handle) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -214,14 +218,14 @@ Result Palma::PairPalma(const PalmaConnectionHandle& handle) {
return ResultSuccess;
}
void Palma::SetPalmaBoostMode(bool boost_mode) {}
void Controller_Palma::SetPalmaBoostMode(bool boost_mode) {}
void Palma::CancelWritePalmaWaveEntry() {}
void Controller_Palma::CancelWritePalmaWaveEntry() {}
void Palma::EnablePalmaBoostMode() {}
void Controller_Palma::EnablePalmaBoostMode() {}
void Palma::GetPalmaBluetoothAddress() {}
void Controller_Palma::GetPalmaBluetoothAddress() {}
void Palma::SetDisallowedPalmaConnection() {}
void Controller_Palma::SetDisallowedPalmaConnection() {}
} // namespace Service::HID

View File

@@ -23,7 +23,7 @@ class EmulatedController;
} // namespace Core::HID
namespace Service::HID {
class Palma final : public ControllerBase {
class Controller_Palma final : public ControllerBase {
public:
using PalmaOperationData = std::array<u8, 0x140>;
@@ -97,9 +97,9 @@ public:
static_assert(sizeof(PalmaConnectionHandle) == 0x8,
"PalmaConnectionHandle has incorrect size.");
explicit Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
KernelHelpers::ServiceContext& service_context_);
~Palma() override;
explicit Controller_Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
KernelHelpers::ServiceContext& service_context_);
~Controller_Palma() override;
// Called when the controller is initialized
void OnInit() override;

View File

@@ -1,413 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "common/common_types.h"
#include "core/core_timing.h"
#include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h"
#include "core/hle/service/hid/controllers/npad.h"
#include "core/hle/service/hid/controllers/six_axis.h"
#include "core/hle/service/hid/errors.h"
#include "core/hle/service/hid/hid_util.h"
namespace Service::HID {
SixAxis::SixAxis(Core::HID::HIDCore& hid_core_, std::shared_ptr<NPad> npad_)
: ControllerBase{hid_core_}, npad{npad_} {
for (std::size_t i = 0; i < controller_data.size(); ++i) {
auto& controller = controller_data[i];
controller.device = hid_core.GetEmulatedControllerByIndex(i);
}
}
SixAxis::~SixAxis() = default;
void SixAxis::OnInit() {}
void SixAxis::OnRelease() {}
void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
return;
}
for (std::size_t i = 0; i < controller_data.size(); ++i) {
auto& controller = controller_data[i];
const auto npad_id = IndexToNpadIdType(i);
const auto& controller_type = controller.device->GetNpadStyleIndex();
if (controller_type == Core::HID::NpadStyleIndex::None ||
!controller.device->IsConnected()) {
continue;
}
const auto& motion_state = controller.device->GetMotions();
auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state;
auto& sixaxis_handheld_state = controller.sixaxis_handheld_state;
auto& sixaxis_dual_left_state = controller.sixaxis_dual_left_state;
auto& sixaxis_dual_right_state = controller.sixaxis_dual_right_state;
auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state;
auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state;
auto& sixaxis_fullkey_lifo = npad->GetSixAxisFullkeyLifo(npad_id);
auto& sixaxis_handheld_lifo = npad->GetSixAxisHandheldLifo(npad_id);
auto& sixaxis_dual_left_lifo = npad->GetSixAxisDualLeftLifo(npad_id);
auto& sixaxis_dual_right_lifo = npad->GetSixAxisDualRightLifo(npad_id);
auto& sixaxis_left_lifo = npad->GetSixAxisLeftLifo(npad_id);
auto& sixaxis_right_lifo = npad->GetSixAxisRightLifo(npad_id);
// Clear previous state
sixaxis_fullkey_state = {};
sixaxis_handheld_state = {};
sixaxis_dual_left_state = {};
sixaxis_dual_right_state = {};
sixaxis_left_lifo_state = {};
sixaxis_right_lifo_state = {};
if (controller.sixaxis_sensor_enabled && Settings::values.motion_enabled.GetValue()) {
controller.sixaxis_at_rest = true;
for (std::size_t e = 0; e < motion_state.size(); ++e) {
controller.sixaxis_at_rest =
controller.sixaxis_at_rest && motion_state[e].is_at_rest;
}
}
const auto set_motion_state = [&](Core::HID::SixAxisSensorState& state,
const Core::HID::ControllerMotion& hid_state) {
using namespace std::literals::chrono_literals;
static constexpr Core::HID::SixAxisSensorState default_motion_state = {
.delta_time = std::chrono::nanoseconds(5ms).count(),
.accel = {0, 0, -1.0f},
.orientation =
{
Common::Vec3f{1.0f, 0, 0},
Common::Vec3f{0, 1.0f, 0},
Common::Vec3f{0, 0, 1.0f},
},
.attribute = {1},
};
if (!controller.sixaxis_sensor_enabled) {
state = default_motion_state;
return;
}
if (!Settings::values.motion_enabled.GetValue()) {
state = default_motion_state;
return;
}
state.attribute.is_connected.Assign(1);
state.delta_time = std::chrono::nanoseconds(5ms).count();
state.accel = hid_state.accel;
state.gyro = hid_state.gyro;
state.rotation = hid_state.rotation;
state.orientation = hid_state.orientation;
};
switch (controller_type) {
case Core::HID::NpadStyleIndex::None:
ASSERT(false);
break;
case Core::HID::NpadStyleIndex::ProController:
set_motion_state(sixaxis_fullkey_state, motion_state[0]);
break;
case Core::HID::NpadStyleIndex::Handheld:
set_motion_state(sixaxis_handheld_state, motion_state[0]);
break;
case Core::HID::NpadStyleIndex::JoyconDual:
set_motion_state(sixaxis_dual_left_state, motion_state[0]);
set_motion_state(sixaxis_dual_right_state, motion_state[1]);
break;
case Core::HID::NpadStyleIndex::JoyconLeft:
set_motion_state(sixaxis_left_lifo_state, motion_state[0]);
break;
case Core::HID::NpadStyleIndex::JoyconRight:
set_motion_state(sixaxis_right_lifo_state, motion_state[1]);
break;
case Core::HID::NpadStyleIndex::Pokeball:
using namespace std::literals::chrono_literals;
set_motion_state(sixaxis_fullkey_state, motion_state[0]);
sixaxis_fullkey_state.delta_time = std::chrono::nanoseconds(15ms).count();
break;
default:
break;
}
sixaxis_fullkey_state.sampling_number =
sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_handheld_state.sampling_number =
sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_dual_left_state.sampling_number =
sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_dual_right_state.sampling_number =
sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_left_lifo_state.sampling_number =
sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_right_lifo_state.sampling_number =
sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
if (IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) {
// This buffer only is updated on handheld on HW
sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state);
} else {
// Handheld doesn't update this buffer on HW
sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state);
}
sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state);
sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state);
sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state);
sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state);
}
}
Result SixAxis::SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::GyroscopeZeroDriftMode drift_mode) {
const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
auto& sixaxis = GetSixaxisState(sixaxis_handle);
auto& controller = GetControllerFromHandle(sixaxis_handle);
sixaxis.gyroscope_zero_drift_mode = drift_mode;
controller.device->SetGyroscopeZeroDriftMode(drift_mode);
return ResultSuccess;
}
Result SixAxis::GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::GyroscopeZeroDriftMode& drift_mode) const {
const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
const auto& sixaxis = GetSixaxisState(sixaxis_handle);
drift_mode = sixaxis.gyroscope_zero_drift_mode;
return ResultSuccess;
}
Result SixAxis::IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool& is_at_rest) const {
const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
const auto& controller = GetControllerFromHandle(sixaxis_handle);
is_at_rest = controller.sixaxis_at_rest;
return ResultSuccess;
}
Result SixAxis::LoadSixAxisSensorCalibrationParameter(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorCalibrationParameter& calibration) const {
const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
// TODO: Request this data to the controller. On error return 0xd8ca
const auto& sixaxis = GetSixaxisState(sixaxis_handle);
calibration = sixaxis.calibration;
return ResultSuccess;
}
Result SixAxis::GetSixAxisSensorIcInformation(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorIcInformation& ic_information) const {
const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
// TODO: Request this data to the controller. On error return 0xd8ca
const auto& sixaxis = GetSixaxisState(sixaxis_handle);
ic_information = sixaxis.ic_information;
return ResultSuccess;
}
Result SixAxis::EnableSixAxisSensorUnalteredPassthrough(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled) {
const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
auto& sixaxis = GetSixaxisState(sixaxis_handle);
sixaxis.unaltered_passtrough = is_enabled;
return ResultSuccess;
}
Result SixAxis::IsSixAxisSensorUnalteredPassthroughEnabled(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const {
const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
const auto& sixaxis = GetSixaxisState(sixaxis_handle);
is_enabled = sixaxis.unaltered_passtrough;
return ResultSuccess;
}
Result SixAxis::SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool sixaxis_status) {
const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
auto& controller = GetControllerFromHandle(sixaxis_handle);
controller.sixaxis_sensor_enabled = sixaxis_status;
return ResultSuccess;
}
Result SixAxis::IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool& is_fusion_enabled) const {
const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
const auto& sixaxis = GetSixaxisState(sixaxis_handle);
is_fusion_enabled = sixaxis.is_fusion_enabled;
return ResultSuccess;
}
Result SixAxis::SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool is_fusion_enabled) {
const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
auto& sixaxis = GetSixaxisState(sixaxis_handle);
sixaxis.is_fusion_enabled = is_fusion_enabled;
return ResultSuccess;
}
Result SixAxis::SetSixAxisFusionParameters(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters) {
const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
const auto param1 = sixaxis_fusion_parameters.parameter1;
if (param1 < 0.0f || param1 > 1.0f) {
return InvalidSixAxisFusionRange;
}
auto& sixaxis = GetSixaxisState(sixaxis_handle);
sixaxis.fusion = sixaxis_fusion_parameters;
return ResultSuccess;
}
Result SixAxis::GetSixAxisFusionParameters(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorFusionParameters& parameters) const {
const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
const auto& sixaxis = GetSixaxisState(sixaxis_handle);
parameters = sixaxis.fusion;
return ResultSuccess;
}
SixAxis::SixaxisParameters& SixAxis::GetSixaxisState(
const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
auto& controller = GetControllerFromHandle(sixaxis_handle);
switch (sixaxis_handle.npad_type) {
case Core::HID::NpadStyleIndex::ProController:
case Core::HID::NpadStyleIndex::Pokeball:
return controller.sixaxis_fullkey;
case Core::HID::NpadStyleIndex::Handheld:
return controller.sixaxis_handheld;
case Core::HID::NpadStyleIndex::JoyconDual:
if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
return controller.sixaxis_dual_left;
}
return controller.sixaxis_dual_right;
case Core::HID::NpadStyleIndex::JoyconLeft:
return controller.sixaxis_left;
case Core::HID::NpadStyleIndex::JoyconRight:
return controller.sixaxis_right;
default:
return controller.sixaxis_unknown;
}
}
const SixAxis::SixaxisParameters& SixAxis::GetSixaxisState(
const Core::HID::SixAxisSensorHandle& sixaxis_handle) const {
const auto& controller = GetControllerFromHandle(sixaxis_handle);
switch (sixaxis_handle.npad_type) {
case Core::HID::NpadStyleIndex::ProController:
case Core::HID::NpadStyleIndex::Pokeball:
return controller.sixaxis_fullkey;
case Core::HID::NpadStyleIndex::Handheld:
return controller.sixaxis_handheld;
case Core::HID::NpadStyleIndex::JoyconDual:
if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
return controller.sixaxis_dual_left;
}
return controller.sixaxis_dual_right;
case Core::HID::NpadStyleIndex::JoyconLeft:
return controller.sixaxis_left;
case Core::HID::NpadStyleIndex::JoyconRight:
return controller.sixaxis_right;
default:
return controller.sixaxis_unknown;
}
}
SixAxis::NpadControllerData& SixAxis::GetControllerFromHandle(
const Core::HID::SixAxisSensorHandle& device_handle) {
const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
return GetControllerFromNpadIdType(npad_id);
}
const SixAxis::NpadControllerData& SixAxis::GetControllerFromHandle(
const Core::HID::SixAxisSensorHandle& device_handle) const {
const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
return GetControllerFromNpadIdType(npad_id);
}
SixAxis::NpadControllerData& SixAxis::GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
npad_id = Core::HID::NpadIdType::Player1;
}
const auto npad_index = NpadIdTypeToIndex(npad_id);
return controller_data[npad_index];
}
const SixAxis::NpadControllerData& SixAxis::GetControllerFromNpadIdType(
Core::HID::NpadIdType npad_id) const {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
npad_id = Core::HID::NpadIdType::Player1;
}
const auto npad_index = NpadIdTypeToIndex(npad_id);
return controller_data[npad_index];
}
} // namespace Service::HID

View File

@@ -1,111 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "common/common_types.h"
#include "core/hid/hid_types.h"
#include "core/hle/service/hid/controllers/controller_base.h"
#include "core/hle/service/hid/ring_lifo.h"
namespace Core::HID {
class EmulatedController;
} // namespace Core::HID
namespace Service::HID {
class NPad;
class SixAxis final : public ControllerBase {
public:
explicit SixAxis(Core::HID::HIDCore& hid_core_, std::shared_ptr<NPad> npad_);
~SixAxis() 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;
Result SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::GyroscopeZeroDriftMode drift_mode);
Result GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::GyroscopeZeroDriftMode& drift_mode) const;
Result IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool& is_at_rest) const;
Result EnableSixAxisSensorUnalteredPassthrough(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled);
Result IsSixAxisSensorUnalteredPassthroughEnabled(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const;
Result LoadSixAxisSensorCalibrationParameter(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorCalibrationParameter& calibration) const;
Result GetSixAxisSensorIcInformation(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorIcInformation& ic_information) const;
Result SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool sixaxis_status);
Result IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool& is_fusion_enabled) const;
Result SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool is_fusion_enabled);
Result SetSixAxisFusionParameters(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters);
Result GetSixAxisFusionParameters(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorFusionParameters& parameters) const;
private:
static constexpr std::size_t NPAD_COUNT = 10;
struct SixaxisParameters {
bool is_fusion_enabled{true};
bool unaltered_passtrough{false};
Core::HID::SixAxisSensorFusionParameters fusion{};
Core::HID::SixAxisSensorCalibrationParameter calibration{};
Core::HID::SixAxisSensorIcInformation ic_information{};
Core::HID::GyroscopeZeroDriftMode gyroscope_zero_drift_mode{
Core::HID::GyroscopeZeroDriftMode::Standard};
};
struct NpadControllerData {
Core::HID::EmulatedController* device = nullptr;
// Motion parameters
bool sixaxis_at_rest{true};
bool sixaxis_sensor_enabled{true};
SixaxisParameters sixaxis_fullkey{};
SixaxisParameters sixaxis_handheld{};
SixaxisParameters sixaxis_dual_left{};
SixaxisParameters sixaxis_dual_right{};
SixaxisParameters sixaxis_left{};
SixaxisParameters sixaxis_right{};
SixaxisParameters sixaxis_unknown{};
// Current pad state
Core::HID::SixAxisSensorState sixaxis_fullkey_state{};
Core::HID::SixAxisSensorState sixaxis_handheld_state{};
Core::HID::SixAxisSensorState sixaxis_dual_left_state{};
Core::HID::SixAxisSensorState sixaxis_dual_right_state{};
Core::HID::SixAxisSensorState sixaxis_left_lifo_state{};
Core::HID::SixAxisSensorState sixaxis_right_lifo_state{};
int callback_key{};
};
SixaxisParameters& GetSixaxisState(const Core::HID::SixAxisSensorHandle& device_handle);
const SixaxisParameters& GetSixaxisState(
const Core::HID::SixAxisSensorHandle& device_handle) const;
NpadControllerData& GetControllerFromHandle(
const Core::HID::SixAxisSensorHandle& device_handle);
const NpadControllerData& GetControllerFromHandle(
const Core::HID::SixAxisSensorHandle& device_handle) const;
NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id);
const NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) const;
std::shared_ptr<NPad> npad;
std::array<NpadControllerData, NPAD_COUNT> controller_data{};
};
} // namespace Service::HID

View File

@@ -15,7 +15,8 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400;
TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
Controller_Touchscreen::Controller_Touchscreen(Core::HID::HIDCore& hid_core_,
u8* raw_shared_memory_)
: ControllerBase{hid_core_} {
static_assert(SHARED_MEMORY_OFFSET + sizeof(TouchSharedMemory) < shared_memory_size,
"TouchSharedMemory is bigger than the shared memory");
@@ -24,13 +25,13 @@ TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
console = hid_core.GetEmulatedConsole();
}
TouchScreen::~TouchScreen() = default;
Controller_Touchscreen::~Controller_Touchscreen() = default;
void TouchScreen::OnInit() {}
void Controller_Touchscreen::OnInit() {}
void TouchScreen::OnRelease() {}
void Controller_Touchscreen::OnRelease() {}
void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
shared_memory->touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count();
if (!IsControllerActivated()) {

View File

@@ -14,10 +14,10 @@ class EmulatedConsole;
} // namespace Core::HID
namespace Service::HID {
class TouchScreen final : public ControllerBase {
class Controller_Touchscreen final : public ControllerBase {
public:
explicit TouchScreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~TouchScreen() override;
explicit Controller_Touchscreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~Controller_Touchscreen() override;
// Called when the controller is initialized
void OnInit() override;

View File

@@ -10,19 +10,20 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00;
XPad::XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) : ControllerBase{hid_core_} {
Controller_XPad::Controller_XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
: ControllerBase{hid_core_} {
static_assert(SHARED_MEMORY_OFFSET + sizeof(XpadSharedMemory) < shared_memory_size,
"XpadSharedMemory is bigger than the shared memory");
shared_memory = std::construct_at(
reinterpret_cast<XpadSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
}
XPad::~XPad() = default;
Controller_XPad::~Controller_XPad() = default;
void XPad::OnInit() {}
void Controller_XPad::OnInit() {}
void XPad::OnRelease() {}
void Controller_XPad::OnRelease() {}
void XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
void Controller_XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
shared_memory->basic_xpad_lifo.buffer_count = 0;
shared_memory->basic_xpad_lifo.buffer_tail = 0;

View File

@@ -10,10 +10,10 @@
#include "core/hle/service/hid/ring_lifo.h"
namespace Service::HID {
class XPad final : public ControllerBase {
class Controller_XPad final : public ControllerBase {
public:
explicit XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~XPad() override;
explicit Controller_XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
~Controller_XPad() override;
// Called when the controller is initialized
void OnInit() override;

File diff suppressed because it is too large Load Diff

View File

@@ -3,12 +3,220 @@
#pragma once
namespace Core {
class System;
#include <chrono>
#include "core/hle/service/hid/controllers/controller_base.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/service.h"
namespace Core::Timing {
struct EventType;
}
namespace Service::SM {
class ServiceManager;
}
namespace Service::HID {
enum class HidController : std::size_t {
DebugPad,
Touchscreen,
Mouse,
Keyboard,
XPad,
HomeButton,
SleepButton,
CaptureButton,
InputDetector,
UniquePad,
NPad,
Gesture,
ConsoleSixAxisSensor,
DebugMouse,
Palma,
MaxControllers,
};
class IAppletResource final : public ServiceFramework<IAppletResource> {
public:
explicit IAppletResource(Core::System& system_,
KernelHelpers::ServiceContext& service_context_);
~IAppletResource() override;
void ActivateController(HidController controller);
void DeactivateController(HidController controller);
template <typename T>
T& GetController(HidController controller) {
return static_cast<T&>(*controllers[static_cast<size_t>(controller)]);
}
template <typename T>
const T& GetController(HidController controller) const {
return static_cast<T&>(*controllers[static_cast<size_t>(controller)]);
}
private:
template <typename T>
void MakeController(HidController controller, u8* shared_memory) {
if constexpr (std::is_constructible_v<T, Core::System&, u8*>) {
controllers[static_cast<std::size_t>(controller)] =
std::make_unique<T>(system, shared_memory);
} else {
controllers[static_cast<std::size_t>(controller)] =
std::make_unique<T>(system.HIDCore(), shared_memory);
}
}
template <typename T>
void MakeControllerWithServiceContext(HidController controller, u8* shared_memory) {
controllers[static_cast<std::size_t>(controller)] =
std::make_unique<T>(system.HIDCore(), shared_memory, service_context);
}
void GetSharedMemoryHandle(HLERequestContext& ctx);
void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
KernelHelpers::ServiceContext& service_context;
std::shared_ptr<Core::Timing::EventType> npad_update_event;
std::shared_ptr<Core::Timing::EventType> default_update_event;
std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event;
std::shared_ptr<Core::Timing::EventType> motion_update_event;
std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
controllers{};
};
class Hid final : public ServiceFramework<Hid> {
public:
explicit Hid(Core::System& system_, std::shared_ptr<IAppletResource> applet_resource_);
~Hid() override;
std::shared_ptr<IAppletResource> GetAppletResource();
private:
void CreateAppletResource(HLERequestContext& ctx);
void ActivateDebugPad(HLERequestContext& ctx);
void ActivateTouchScreen(HLERequestContext& ctx);
void ActivateMouse(HLERequestContext& ctx);
void ActivateKeyboard(HLERequestContext& ctx);
void SendKeyboardLockKeyEvent(HLERequestContext& ctx);
void ActivateXpad(HLERequestContext& ctx);
void GetXpadIDs(HLERequestContext& ctx);
void ActivateSixAxisSensor(HLERequestContext& ctx);
void DeactivateSixAxisSensor(HLERequestContext& ctx);
void StartSixAxisSensor(HLERequestContext& ctx);
void StopSixAxisSensor(HLERequestContext& ctx);
void IsSixAxisSensorFusionEnabled(HLERequestContext& ctx);
void EnableSixAxisSensorFusion(HLERequestContext& ctx);
void SetSixAxisSensorFusionParameters(HLERequestContext& ctx);
void GetSixAxisSensorFusionParameters(HLERequestContext& ctx);
void ResetSixAxisSensorFusionParameters(HLERequestContext& ctx);
void SetGyroscopeZeroDriftMode(HLERequestContext& ctx);
void GetGyroscopeZeroDriftMode(HLERequestContext& ctx);
void ResetGyroscopeZeroDriftMode(HLERequestContext& ctx);
void IsSixAxisSensorAtRest(HLERequestContext& ctx);
void IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ctx);
void EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx);
void IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& ctx);
void LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx);
void GetSixAxisSensorIcInformation(HLERequestContext& ctx);
void ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx);
void ActivateGesture(HLERequestContext& ctx);
void SetSupportedNpadStyleSet(HLERequestContext& ctx);
void GetSupportedNpadStyleSet(HLERequestContext& ctx);
void SetSupportedNpadIdType(HLERequestContext& ctx);
void ActivateNpad(HLERequestContext& ctx);
void DeactivateNpad(HLERequestContext& ctx);
void AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx);
void DisconnectNpad(HLERequestContext& ctx);
void GetPlayerLedPattern(HLERequestContext& ctx);
void ActivateNpadWithRevision(HLERequestContext& ctx);
void SetNpadJoyHoldType(HLERequestContext& ctx);
void GetNpadJoyHoldType(HLERequestContext& ctx);
void SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx);
void SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx);
void SetNpadJoyAssignmentModeDual(HLERequestContext& ctx);
void MergeSingleJoyAsDualJoy(HLERequestContext& ctx);
void StartLrAssignmentMode(HLERequestContext& ctx);
void StopLrAssignmentMode(HLERequestContext& ctx);
void SetNpadHandheldActivationMode(HLERequestContext& ctx);
void GetNpadHandheldActivationMode(HLERequestContext& ctx);
void SwapNpadAssignment(HLERequestContext& ctx);
void IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx);
void EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx);
void SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx);
void SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx);
void SetNpadCaptureButtonAssignment(HLERequestContext& ctx);
void ClearNpadCaptureButtonAssignment(HLERequestContext& ctx);
void GetVibrationDeviceInfo(HLERequestContext& ctx);
void SendVibrationValue(HLERequestContext& ctx);
void GetActualVibrationValue(HLERequestContext& ctx);
void CreateActiveVibrationDeviceList(HLERequestContext& ctx);
void PermitVibration(HLERequestContext& ctx);
void IsVibrationPermitted(HLERequestContext& ctx);
void SendVibrationValues(HLERequestContext& ctx);
void SendVibrationGcErmCommand(HLERequestContext& ctx);
void GetActualVibrationGcErmCommand(HLERequestContext& ctx);
void BeginPermitVibrationSession(HLERequestContext& ctx);
void EndPermitVibrationSession(HLERequestContext& ctx);
void IsVibrationDeviceMounted(HLERequestContext& ctx);
void ActivateConsoleSixAxisSensor(HLERequestContext& ctx);
void StartConsoleSixAxisSensor(HLERequestContext& ctx);
void StopConsoleSixAxisSensor(HLERequestContext& ctx);
void ActivateSevenSixAxisSensor(HLERequestContext& ctx);
void StartSevenSixAxisSensor(HLERequestContext& ctx);
void StopSevenSixAxisSensor(HLERequestContext& ctx);
void InitializeSevenSixAxisSensor(HLERequestContext& ctx);
void FinalizeSevenSixAxisSensor(HLERequestContext& ctx);
void ResetSevenSixAxisSensorTimestamp(HLERequestContext& ctx);
void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx);
void GetPalmaConnectionHandle(HLERequestContext& ctx);
void InitializePalma(HLERequestContext& ctx);
void AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx);
void GetPalmaOperationInfo(HLERequestContext& ctx);
void PlayPalmaActivity(HLERequestContext& ctx);
void SetPalmaFrModeType(HLERequestContext& ctx);
void ReadPalmaStep(HLERequestContext& ctx);
void EnablePalmaStep(HLERequestContext& ctx);
void ResetPalmaStep(HLERequestContext& ctx);
void ReadPalmaApplicationSection(HLERequestContext& ctx);
void WritePalmaApplicationSection(HLERequestContext& ctx);
void ReadPalmaUniqueCode(HLERequestContext& ctx);
void SetPalmaUniqueCodeInvalid(HLERequestContext& ctx);
void WritePalmaActivityEntry(HLERequestContext& ctx);
void WritePalmaRgbLedPatternEntry(HLERequestContext& ctx);
void WritePalmaWaveEntry(HLERequestContext& ctx);
void SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx);
void GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx);
void SuspendPalmaFeature(HLERequestContext& ctx);
void GetPalmaOperationResult(HLERequestContext& ctx);
void ReadPalmaPlayLog(HLERequestContext& ctx);
void ResetPalmaPlayLog(HLERequestContext& ctx);
void SetIsPalmaAllConnectable(HLERequestContext& ctx);
void SetIsPalmaPairedConnectable(HLERequestContext& ctx);
void PairPalma(HLERequestContext& ctx);
void SetPalmaBoostMode(HLERequestContext& ctx);
void CancelWritePalmaWaveEntry(HLERequestContext& ctx);
void EnablePalmaBoostMode(HLERequestContext& ctx);
void GetPalmaBluetoothAddress(HLERequestContext& ctx);
void SetDisallowedPalmaConnection(HLERequestContext& ctx);
void SetNpadCommunicationMode(HLERequestContext& ctx);
void GetNpadCommunicationMode(HLERequestContext& ctx);
void SetTouchScreenConfiguration(HLERequestContext& ctx);
void IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx);
std::shared_ptr<IAppletResource> applet_resource;
KernelHelpers::ServiceContext service_context;
};
void LoopProcess(Core::System& system);
} // namespace Service::HID

View File

@@ -1,159 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hle/service/hid/hid_debug_server.h"
#include "core/hle/service/hid/resource_manager.h"
#include "core/hle/service/ipc_helpers.h"
namespace Service::HID {
IHidDebugServer::IHidDebugServer(Core::System& system_, std::shared_ptr<ResourceManager> resource)
: ServiceFramework{system_, "hid:dbg"}, resource_manager{resource} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "DeactivateDebugPad"},
{1, nullptr, "SetDebugPadAutoPilotState"},
{2, nullptr, "UnsetDebugPadAutoPilotState"},
{10, nullptr, "DeactivateTouchScreen"},
{11, nullptr, "SetTouchScreenAutoPilotState"},
{12, nullptr, "UnsetTouchScreenAutoPilotState"},
{13, nullptr, "GetTouchScreenConfiguration"},
{14, nullptr, "ProcessTouchScreenAutoTune"},
{15, nullptr, "ForceStopTouchScreenManagement"},
{16, nullptr, "ForceRestartTouchScreenManagement"},
{17, nullptr, "IsTouchScreenManaged"},
{20, nullptr, "DeactivateMouse"},
{21, nullptr, "SetMouseAutoPilotState"},
{22, nullptr, "UnsetMouseAutoPilotState"},
{25, nullptr, "SetDebugMouseAutoPilotState"},
{26, nullptr, "UnsetDebugMouseAutoPilotState"},
{30, nullptr, "DeactivateKeyboard"},
{31, nullptr, "SetKeyboardAutoPilotState"},
{32, nullptr, "UnsetKeyboardAutoPilotState"},
{50, nullptr, "DeactivateXpad"},
{51, nullptr, "SetXpadAutoPilotState"},
{52, nullptr, "UnsetXpadAutoPilotState"},
{53, nullptr, "DeactivateJoyXpad"},
{60, nullptr, "ClearNpadSystemCommonPolicy"},
{61, nullptr, "DeactivateNpad"},
{62, nullptr, "ForceDisconnectNpad"},
{91, nullptr, "DeactivateGesture"},
{110, nullptr, "DeactivateHomeButton"},
{111, nullptr, "SetHomeButtonAutoPilotState"},
{112, nullptr, "UnsetHomeButtonAutoPilotState"},
{120, nullptr, "DeactivateSleepButton"},
{121, nullptr, "SetSleepButtonAutoPilotState"},
{122, nullptr, "UnsetSleepButtonAutoPilotState"},
{123, nullptr, "DeactivateInputDetector"},
{130, nullptr, "DeactivateCaptureButton"},
{131, nullptr, "SetCaptureButtonAutoPilotState"},
{132, nullptr, "UnsetCaptureButtonAutoPilotState"},
{133, nullptr, "SetShiftAccelerometerCalibrationValue"},
{134, nullptr, "GetShiftAccelerometerCalibrationValue"},
{135, nullptr, "SetShiftGyroscopeCalibrationValue"},
{136, nullptr, "GetShiftGyroscopeCalibrationValue"},
{140, nullptr, "DeactivateConsoleSixAxisSensor"},
{141, nullptr, "GetConsoleSixAxisSensorSamplingFrequency"},
{142, nullptr, "DeactivateSevenSixAxisSensor"},
{143, nullptr, "GetConsoleSixAxisSensorCountStates"},
{144, nullptr, "GetAccelerometerFsr"},
{145, nullptr, "SetAccelerometerFsr"},
{146, nullptr, "GetAccelerometerOdr"},
{147, nullptr, "SetAccelerometerOdr"},
{148, nullptr, "GetGyroscopeFsr"},
{149, nullptr, "SetGyroscopeFsr"},
{150, nullptr, "GetGyroscopeOdr"},
{151, nullptr, "SetGyroscopeOdr"},
{152, nullptr, "GetWhoAmI"},
{201, nullptr, "ActivateFirmwareUpdate"},
{202, nullptr, "DeactivateFirmwareUpdate"},
{203, nullptr, "StartFirmwareUpdate"},
{204, nullptr, "GetFirmwareUpdateStage"},
{205, nullptr, "GetFirmwareVersion"},
{206, nullptr, "GetDestinationFirmwareVersion"},
{207, nullptr, "DiscardFirmwareInfoCacheForRevert"},
{208, nullptr, "StartFirmwareUpdateForRevert"},
{209, nullptr, "GetAvailableFirmwareVersionForRevert"},
{210, nullptr, "IsFirmwareUpdatingDevice"},
{211, nullptr, "StartFirmwareUpdateIndividual"},
{215, nullptr, "SetUsbFirmwareForceUpdateEnabled"},
{216, nullptr, "SetAllKuinaDevicesToFirmwareUpdateMode"},
{221, nullptr, "UpdateControllerColor"},
{222, nullptr, "ConnectUsbPadsAsync"},
{223, nullptr, "DisconnectUsbPadsAsync"},
{224, nullptr, "UpdateDesignInfo"},
{225, nullptr, "GetUniquePadDriverState"},
{226, nullptr, "GetSixAxisSensorDriverStates"},
{227, nullptr, "GetRxPacketHistory"},
{228, nullptr, "AcquireOperationEventHandle"},
{229, nullptr, "ReadSerialFlash"},
{230, nullptr, "WriteSerialFlash"},
{231, nullptr, "GetOperationResult"},
{232, nullptr, "EnableShipmentMode"},
{233, nullptr, "ClearPairingInfo"},
{234, nullptr, "GetUniquePadDeviceTypeSetInternal"},
{235, nullptr, "EnableAnalogStickPower"},
{236, nullptr, "RequestKuinaUartClockCal"},
{237, nullptr, "GetKuinaUartClockCal"},
{238, nullptr, "SetKuinaUartClockTrim"},
{239, nullptr, "KuinaLoopbackTest"},
{240, nullptr, "RequestBatteryVoltage"},
{241, nullptr, "GetBatteryVoltage"},
{242, nullptr, "GetUniquePadPowerInfo"},
{243, nullptr, "RebootUniquePad"},
{244, nullptr, "RequestKuinaFirmwareVersion"},
{245, nullptr, "GetKuinaFirmwareVersion"},
{246, nullptr, "GetVidPid"},
{247, nullptr, "GetAnalogStickCalibrationValue"},
{248, nullptr, "GetUniquePadIdsFull"},
{249, nullptr, "ConnectUniquePad"},
{250, nullptr, "IsVirtual"},
{251, nullptr, "GetAnalogStickModuleParam"},
{301, nullptr, "GetAbstractedPadHandles"},
{302, nullptr, "GetAbstractedPadState"},
{303, nullptr, "GetAbstractedPadsState"},
{321, nullptr, "SetAutoPilotVirtualPadState"},
{322, nullptr, "UnsetAutoPilotVirtualPadState"},
{323, nullptr, "UnsetAllAutoPilotVirtualPadState"},
{324, nullptr, "AttachHdlsWorkBuffer"},
{325, nullptr, "ReleaseHdlsWorkBuffer"},
{326, nullptr, "DumpHdlsNpadAssignmentState"},
{327, nullptr, "DumpHdlsStates"},
{328, nullptr, "ApplyHdlsNpadAssignmentState"},
{329, nullptr, "ApplyHdlsStateList"},
{330, nullptr, "AttachHdlsVirtualDevice"},
{331, nullptr, "DetachHdlsVirtualDevice"},
{332, nullptr, "SetHdlsState"},
{350, nullptr, "AddRegisteredDevice"},
{400, nullptr, "DisableExternalMcuOnNxDevice"},
{401, nullptr, "DisableRailDeviceFiltering"},
{402, nullptr, "EnableWiredPairing"},
{403, nullptr, "EnableShipmentModeAutoClear"},
{404, nullptr, "SetRailEnabled"},
{500, nullptr, "SetFactoryInt"},
{501, nullptr, "IsFactoryBootEnabled"},
{550, nullptr, "SetAnalogStickModelDataTemporarily"},
{551, nullptr, "GetAnalogStickModelData"},
{552, nullptr, "ResetAnalogStickModelData"},
{600, nullptr, "ConvertPadState"},
{650, nullptr, "AddButtonPlayData"},
{651, nullptr, "StartButtonPlayData"},
{652, nullptr, "StopButtonPlayData"},
{2000, nullptr, "DeactivateDigitizer"},
{2001, nullptr, "SetDigitizerAutoPilotState"},
{2002, nullptr, "UnsetDigitizerAutoPilotState"},
{2002, nullptr, "ReloadFirmwareDebugSettings"},
};
// clang-format on
RegisterHandlers(functions);
}
IHidDebugServer::~IHidDebugServer() = default;
std::shared_ptr<ResourceManager> IHidDebugServer::GetResourceManager() {
resource_manager->Initialize();
return resource_manager;
}
} // namespace Service::HID

View File

@@ -1,26 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/service.h"
namespace Core {
class System;
}
namespace Service::HID {
class ResourceManager;
class IHidDebugServer final : public ServiceFramework<IHidDebugServer> {
public:
explicit IHidDebugServer(Core::System& system_, std::shared_ptr<ResourceManager> resource);
~IHidDebugServer() override;
private:
std::shared_ptr<ResourceManager> GetResourceManager();
std::shared_ptr<ResourceManager> resource_manager;
};
} // namespace Service::HID

View File

@@ -1,99 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hle/service/hid/hid_firmware_settings.h"
namespace Service::HID {
HidFirmwareSettings::HidFirmwareSettings() {
LoadSettings(true);
}
void HidFirmwareSettings::Reload() {
LoadSettings(true);
}
void HidFirmwareSettings::LoadSettings(bool reload_config) {
if (is_initalized && !reload_config) {
return;
}
// TODO: Use nn::settings::fwdbg::GetSettingsItemValue to load config values
is_debug_pad_enabled = true;
is_device_managed = true;
is_touch_i2c_managed = is_device_managed;
is_future_devices_emulated = false;
is_mcu_hardware_error_emulated = false;
is_rail_enabled = true;
is_firmware_update_failure_emulated = false;
is_firmware_update_failure = {};
is_ble_disabled = false;
is_dscale_disabled = false;
is_handheld_forced = true;
features_per_id_disabled = {};
is_touch_firmware_auto_update_disabled = false;
is_initalized = true;
}
bool HidFirmwareSettings::IsDebugPadEnabled() {
LoadSettings(false);
return is_debug_pad_enabled;
}
bool HidFirmwareSettings::IsDeviceManaged() {
LoadSettings(false);
return is_device_managed;
}
bool HidFirmwareSettings::IsEmulateFutureDevice() {
LoadSettings(false);
return is_future_devices_emulated;
}
bool HidFirmwareSettings::IsTouchI2cManaged() {
LoadSettings(false);
return is_touch_i2c_managed;
}
bool HidFirmwareSettings::IsHandheldForced() {
LoadSettings(false);
return is_handheld_forced;
}
bool HidFirmwareSettings::IsRailEnabled() {
LoadSettings(false);
return is_rail_enabled;
}
bool HidFirmwareSettings::IsHardwareErrorEmulated() {
LoadSettings(false);
return is_mcu_hardware_error_emulated;
}
bool HidFirmwareSettings::IsBleDisabled() {
LoadSettings(false);
return is_ble_disabled;
}
bool HidFirmwareSettings::IsDscaleDisabled() {
LoadSettings(false);
return is_dscale_disabled;
}
bool HidFirmwareSettings::IsTouchAutoUpdateDisabled() {
LoadSettings(false);
return is_touch_firmware_auto_update_disabled;
}
HidFirmwareSettings::FirmwareSetting HidFirmwareSettings::GetFirmwareUpdateFailure() {
LoadSettings(false);
return is_firmware_update_failure;
}
HidFirmwareSettings::FeaturesPerId HidFirmwareSettings::FeaturesDisabledPerId() {
LoadSettings(false);
return features_per_id_disabled;
}
} // namespace Service::HID

View File

@@ -1,54 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "common/common_types.h"
namespace Service::HID {
/// Loads firmware config from nn::settings::fwdbg
class HidFirmwareSettings {
public:
using FirmwareSetting = std::array<u8, 4>;
using FeaturesPerId = std::array<bool, 0xA8>;
HidFirmwareSettings();
void Reload();
void LoadSettings(bool reload_config);
bool IsDebugPadEnabled();
bool IsDeviceManaged();
bool IsEmulateFutureDevice();
bool IsTouchI2cManaged();
bool IsHandheldForced();
bool IsRailEnabled();
bool IsHardwareErrorEmulated();
bool IsBleDisabled();
bool IsDscaleDisabled();
bool IsTouchAutoUpdateDisabled();
FirmwareSetting GetFirmwareUpdateFailure();
FeaturesPerId FeaturesDisabledPerId();
private:
bool is_initalized{};
// Debug settings
bool is_debug_pad_enabled{};
bool is_device_managed{};
bool is_touch_i2c_managed{};
bool is_future_devices_emulated{};
bool is_mcu_hardware_error_emulated{};
bool is_rail_enabled{};
bool is_firmware_update_failure_emulated{};
bool is_ble_disabled{};
bool is_dscale_disabled{};
bool is_handheld_forced{};
bool is_touch_firmware_auto_update_disabled{};
FirmwareSetting is_firmware_update_failure{};
FeaturesPerId features_per_id_disabled{};
};
} // namespace Service::HID

File diff suppressed because it is too large Load Diff

View File

@@ -1,149 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/service.h"
namespace Core {
class System;
}
namespace Service::HID {
class ResourceManager;
class HidFirmwareSettings;
class IHidServer final : public ServiceFramework<IHidServer> {
public:
explicit IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> resource,
std::shared_ptr<HidFirmwareSettings> settings);
~IHidServer() override;
std::shared_ptr<ResourceManager> GetResourceManager();
private:
void CreateAppletResource(HLERequestContext& ctx);
void ActivateDebugPad(HLERequestContext& ctx);
void ActivateTouchScreen(HLERequestContext& ctx);
void ActivateMouse(HLERequestContext& ctx);
void ActivateKeyboard(HLERequestContext& ctx);
void SendKeyboardLockKeyEvent(HLERequestContext& ctx);
void AcquireXpadIdEventHandle(HLERequestContext& ctx);
void ReleaseXpadIdEventHandle(HLERequestContext& ctx);
void ActivateXpad(HLERequestContext& ctx);
void GetXpadIds(HLERequestContext& ctx);
void ActivateJoyXpad(HLERequestContext& ctx);
void GetJoyXpadLifoHandle(HLERequestContext& ctx);
void GetJoyXpadIds(HLERequestContext& ctx);
void ActivateSixAxisSensor(HLERequestContext& ctx);
void DeactivateSixAxisSensor(HLERequestContext& ctx);
void GetSixAxisSensorLifoHandle(HLERequestContext& ctx);
void ActivateJoySixAxisSensor(HLERequestContext& ctx);
void DeactivateJoySixAxisSensor(HLERequestContext& ctx);
void GetJoySixAxisSensorLifoHandle(HLERequestContext& ctx);
void StartSixAxisSensor(HLERequestContext& ctx);
void StopSixAxisSensor(HLERequestContext& ctx);
void IsSixAxisSensorFusionEnabled(HLERequestContext& ctx);
void EnableSixAxisSensorFusion(HLERequestContext& ctx);
void SetSixAxisSensorFusionParameters(HLERequestContext& ctx);
void GetSixAxisSensorFusionParameters(HLERequestContext& ctx);
void ResetSixAxisSensorFusionParameters(HLERequestContext& ctx);
void SetGyroscopeZeroDriftMode(HLERequestContext& ctx);
void GetGyroscopeZeroDriftMode(HLERequestContext& ctx);
void ResetGyroscopeZeroDriftMode(HLERequestContext& ctx);
void IsSixAxisSensorAtRest(HLERequestContext& ctx);
void IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ctx);
void EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx);
void IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& ctx);
void LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx);
void GetSixAxisSensorIcInformation(HLERequestContext& ctx);
void ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx);
void ActivateGesture(HLERequestContext& ctx);
void SetSupportedNpadStyleSet(HLERequestContext& ctx);
void GetSupportedNpadStyleSet(HLERequestContext& ctx);
void SetSupportedNpadIdType(HLERequestContext& ctx);
void ActivateNpad(HLERequestContext& ctx);
void DeactivateNpad(HLERequestContext& ctx);
void AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx);
void DisconnectNpad(HLERequestContext& ctx);
void GetPlayerLedPattern(HLERequestContext& ctx);
void ActivateNpadWithRevision(HLERequestContext& ctx);
void SetNpadJoyHoldType(HLERequestContext& ctx);
void GetNpadJoyHoldType(HLERequestContext& ctx);
void SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx);
void SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx);
void SetNpadJoyAssignmentModeDual(HLERequestContext& ctx);
void MergeSingleJoyAsDualJoy(HLERequestContext& ctx);
void StartLrAssignmentMode(HLERequestContext& ctx);
void StopLrAssignmentMode(HLERequestContext& ctx);
void SetNpadHandheldActivationMode(HLERequestContext& ctx);
void GetNpadHandheldActivationMode(HLERequestContext& ctx);
void SwapNpadAssignment(HLERequestContext& ctx);
void IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx);
void EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx);
void SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx);
void SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx);
void SetNpadCaptureButtonAssignment(HLERequestContext& ctx);
void ClearNpadCaptureButtonAssignment(HLERequestContext& ctx);
void GetVibrationDeviceInfo(HLERequestContext& ctx);
void SendVibrationValue(HLERequestContext& ctx);
void GetActualVibrationValue(HLERequestContext& ctx);
void CreateActiveVibrationDeviceList(HLERequestContext& ctx);
void PermitVibration(HLERequestContext& ctx);
void IsVibrationPermitted(HLERequestContext& ctx);
void SendVibrationValues(HLERequestContext& ctx);
void SendVibrationGcErmCommand(HLERequestContext& ctx);
void GetActualVibrationGcErmCommand(HLERequestContext& ctx);
void BeginPermitVibrationSession(HLERequestContext& ctx);
void EndPermitVibrationSession(HLERequestContext& ctx);
void IsVibrationDeviceMounted(HLERequestContext& ctx);
void ActivateConsoleSixAxisSensor(HLERequestContext& ctx);
void StartConsoleSixAxisSensor(HLERequestContext& ctx);
void StopConsoleSixAxisSensor(HLERequestContext& ctx);
void ActivateSevenSixAxisSensor(HLERequestContext& ctx);
void StartSevenSixAxisSensor(HLERequestContext& ctx);
void StopSevenSixAxisSensor(HLERequestContext& ctx);
void InitializeSevenSixAxisSensor(HLERequestContext& ctx);
void FinalizeSevenSixAxisSensor(HLERequestContext& ctx);
void ResetSevenSixAxisSensorTimestamp(HLERequestContext& ctx);
void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx);
void GetPalmaConnectionHandle(HLERequestContext& ctx);
void InitializePalma(HLERequestContext& ctx);
void AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx);
void GetPalmaOperationInfo(HLERequestContext& ctx);
void PlayPalmaActivity(HLERequestContext& ctx);
void SetPalmaFrModeType(HLERequestContext& ctx);
void ReadPalmaStep(HLERequestContext& ctx);
void EnablePalmaStep(HLERequestContext& ctx);
void ResetPalmaStep(HLERequestContext& ctx);
void ReadPalmaApplicationSection(HLERequestContext& ctx);
void WritePalmaApplicationSection(HLERequestContext& ctx);
void ReadPalmaUniqueCode(HLERequestContext& ctx);
void SetPalmaUniqueCodeInvalid(HLERequestContext& ctx);
void WritePalmaActivityEntry(HLERequestContext& ctx);
void WritePalmaRgbLedPatternEntry(HLERequestContext& ctx);
void WritePalmaWaveEntry(HLERequestContext& ctx);
void SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx);
void GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx);
void SuspendPalmaFeature(HLERequestContext& ctx);
void GetPalmaOperationResult(HLERequestContext& ctx);
void ReadPalmaPlayLog(HLERequestContext& ctx);
void ResetPalmaPlayLog(HLERequestContext& ctx);
void SetIsPalmaAllConnectable(HLERequestContext& ctx);
void SetIsPalmaPairedConnectable(HLERequestContext& ctx);
void PairPalma(HLERequestContext& ctx);
void SetPalmaBoostMode(HLERequestContext& ctx);
void CancelWritePalmaWaveEntry(HLERequestContext& ctx);
void EnablePalmaBoostMode(HLERequestContext& ctx);
void GetPalmaBluetoothAddress(HLERequestContext& ctx);
void SetDisallowedPalmaConnection(HLERequestContext& ctx);
void SetNpadCommunicationMode(HLERequestContext& ctx);
void GetNpadCommunicationMode(HLERequestContext& ctx);
void SetTouchScreenConfiguration(HLERequestContext& ctx);
void IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx);
std::shared_ptr<ResourceManager> resource_manager;
std::shared_ptr<HidFirmwareSettings> firmware_settings;
};
} // namespace Service::HID

View File

@@ -1,539 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hid/hid_core.h"
#include "core/hle/service/hid/controllers/npad.h"
#include "core/hle/service/hid/controllers/touchscreen.h"
#include "core/hle/service/hid/errors.h"
#include "core/hle/service/hid/hid_system_server.h"
#include "core/hle/service/hid/resource_manager.h"
#include "core/hle/service/ipc_helpers.h"
namespace Service::HID {
IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<ResourceManager> resource)
: ServiceFramework{system_, "hid:sys"}, service_context{system_, service_name},
resource_manager{resource} {
// clang-format off
static const FunctionInfo functions[] = {
{31, nullptr, "SendKeyboardLockKeyEvent"},
{101, nullptr, "AcquireHomeButtonEventHandle"},
{111, nullptr, "ActivateHomeButton"},
{121, nullptr, "AcquireSleepButtonEventHandle"},
{131, nullptr, "ActivateSleepButton"},
{141, nullptr, "AcquireCaptureButtonEventHandle"},
{151, nullptr, "ActivateCaptureButton"},
{161, nullptr, "GetPlatformConfig"},
{210, nullptr, "AcquireNfcDeviceUpdateEventHandle"},
{211, nullptr, "GetNpadsWithNfc"},
{212, nullptr, "AcquireNfcActivateEventHandle"},
{213, nullptr, "ActivateNfc"},
{214, nullptr, "GetXcdHandleForNpadWithNfc"},
{215, nullptr, "IsNfcActivated"},
{230, nullptr, "AcquireIrSensorEventHandle"},
{231, nullptr, "ActivateIrSensor"},
{232, nullptr, "GetIrSensorState"},
{233, nullptr, "GetXcdHandleForNpadWithIrSensor"},
{301, nullptr, "ActivateNpadSystem"},
{303, &IHidSystemServer::ApplyNpadSystemCommonPolicy, "ApplyNpadSystemCommonPolicy"},
{304, &IHidSystemServer::EnableAssigningSingleOnSlSrPress, "EnableAssigningSingleOnSlSrPress"},
{305, &IHidSystemServer::DisableAssigningSingleOnSlSrPress, "DisableAssigningSingleOnSlSrPress"},
{306, &IHidSystemServer::GetLastActiveNpad, "GetLastActiveNpad"},
{307, nullptr, "GetNpadSystemExtStyle"},
{308, &IHidSystemServer::ApplyNpadSystemCommonPolicyFull, "ApplyNpadSystemCommonPolicyFull"},
{309, &IHidSystemServer::GetNpadFullKeyGripColor, "GetNpadFullKeyGripColor"},
{310, &IHidSystemServer::GetMaskedSupportedNpadStyleSet, "GetMaskedSupportedNpadStyleSet"},
{311, nullptr, "SetNpadPlayerLedBlinkingDevice"},
{312, &IHidSystemServer::SetSupportedNpadStyleSetAll, "SetSupportedNpadStyleSetAll"},
{313, nullptr, "GetNpadCaptureButtonAssignment"},
{314, nullptr, "GetAppletFooterUiType"},
{315, &IHidSystemServer::GetAppletDetailedUiType, "GetAppletDetailedUiType"},
{316, &IHidSystemServer::GetNpadInterfaceType, "GetNpadInterfaceType"},
{317, &IHidSystemServer::GetNpadLeftRightInterfaceType, "GetNpadLeftRightInterfaceType"},
{318, &IHidSystemServer::HasBattery, "HasBattery"},
{319, &IHidSystemServer::HasLeftRightBattery, "HasLeftRightBattery"},
{321, &IHidSystemServer::GetUniquePadsFromNpad, "GetUniquePadsFromNpad"},
{322, &IHidSystemServer::GetIrSensorState, "GetIrSensorState"},
{323, nullptr, "GetXcdHandleForNpadWithIrSensor"},
{324, nullptr, "GetUniquePadButtonSet"},
{325, nullptr, "GetUniquePadColor"},
{326, nullptr, "GetUniquePadAppletDetailedUiType"},
{327, nullptr, "GetAbstractedPadIdDataFromNpad"},
{328, nullptr, "AttachAbstractedPadToNpad"},
{329, nullptr, "DetachAbstractedPadAll"},
{330, nullptr, "CheckAbstractedPadConnection"},
{500, nullptr, "SetAppletResourceUserId"},
{501, nullptr, "RegisterAppletResourceUserId"},
{502, nullptr, "UnregisterAppletResourceUserId"},
{503, nullptr, "EnableAppletToGetInput"},
{504, nullptr, "SetAruidValidForVibration"},
{505, nullptr, "EnableAppletToGetSixAxisSensor"},
{506, nullptr, "EnableAppletToGetPadInput"},
{507, nullptr, "EnableAppletToGetTouchScreen"},
{510, nullptr, "SetVibrationMasterVolume"},
{511, nullptr, "GetVibrationMasterVolume"},
{512, nullptr, "BeginPermitVibrationSession"},
{513, nullptr, "EndPermitVibrationSession"},
{514, nullptr, "Unknown514"},
{520, nullptr, "EnableHandheldHids"},
{521, nullptr, "DisableHandheldHids"},
{522, nullptr, "SetJoyConRailEnabled"},
{523, nullptr, "IsJoyConRailEnabled"},
{524, nullptr, "IsHandheldHidsEnabled"},
{525, nullptr, "IsJoyConAttachedOnAllRail"},
{540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"},
{541, nullptr, "GetPlayReportControllerUsages"},
{542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"},
{543, nullptr, "GetRegisteredDevicesOld"},
{544, &IHidSystemServer::AcquireConnectionTriggerTimeoutEvent, "AcquireConnectionTriggerTimeoutEvent"},
{545, nullptr, "SendConnectionTrigger"},
{546, &IHidSystemServer::AcquireDeviceRegisteredEventForControllerSupport, "AcquireDeviceRegisteredEventForControllerSupport"},
{547, nullptr, "GetAllowedBluetoothLinksCount"},
{548, &IHidSystemServer::GetRegisteredDevices, "GetRegisteredDevices"},
{549, nullptr, "GetConnectableRegisteredDevices"},
{700, nullptr, "ActivateUniquePad"},
{702, &IHidSystemServer::AcquireUniquePadConnectionEventHandle, "AcquireUniquePadConnectionEventHandle"},
{703, &IHidSystemServer::GetUniquePadIds, "GetUniquePadIds"},
{751, &IHidSystemServer::AcquireJoyDetachOnBluetoothOffEventHandle, "AcquireJoyDetachOnBluetoothOffEventHandle"},
{800, nullptr, "ListSixAxisSensorHandles"},
{801, nullptr, "IsSixAxisSensorUserCalibrationSupported"},
{802, nullptr, "ResetSixAxisSensorCalibrationValues"},
{803, nullptr, "StartSixAxisSensorUserCalibration"},
{804, nullptr, "CancelSixAxisSensorUserCalibration"},
{805, nullptr, "GetUniquePadBluetoothAddress"},
{806, nullptr, "DisconnectUniquePad"},
{807, nullptr, "GetUniquePadType"},
{808, nullptr, "GetUniquePadInterface"},
{809, nullptr, "GetUniquePadSerialNumber"},
{810, nullptr, "GetUniquePadControllerNumber"},
{811, nullptr, "GetSixAxisSensorUserCalibrationStage"},
{812, nullptr, "GetConsoleUniqueSixAxisSensorHandle"},
{821, nullptr, "StartAnalogStickManualCalibration"},
{822, nullptr, "RetryCurrentAnalogStickManualCalibrationStage"},
{823, nullptr, "CancelAnalogStickManualCalibration"},
{824, nullptr, "ResetAnalogStickManualCalibration"},
{825, nullptr, "GetAnalogStickState"},
{826, nullptr, "GetAnalogStickManualCalibrationStage"},
{827, nullptr, "IsAnalogStickButtonPressed"},
{828, nullptr, "IsAnalogStickInReleasePosition"},
{829, nullptr, "IsAnalogStickInCircumference"},
{830, nullptr, "SetNotificationLedPattern"},
{831, nullptr, "SetNotificationLedPatternWithTimeout"},
{832, nullptr, "PrepareHidsForNotificationWake"},
{850, &IHidSystemServer::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"},
{851, nullptr, "EnableUsbFullKeyController"},
{852, nullptr, "IsUsbConnected"},
{870, &IHidSystemServer::IsHandheldButtonPressedOnConsoleMode, "IsHandheldButtonPressedOnConsoleMode"},
{900, nullptr, "ActivateInputDetector"},
{901, nullptr, "NotifyInputDetector"},
{1000, &IHidSystemServer::InitializeFirmwareUpdate, "InitializeFirmwareUpdate"},
{1001, nullptr, "GetFirmwareVersion"},
{1002, nullptr, "GetAvailableFirmwareVersion"},
{1003, nullptr, "IsFirmwareUpdateAvailable"},
{1004, nullptr, "CheckFirmwareUpdateRequired"},
{1005, nullptr, "StartFirmwareUpdate"},
{1006, nullptr, "AbortFirmwareUpdate"},
{1007, nullptr, "GetFirmwareUpdateState"},
{1008, nullptr, "ActivateAudioControl"},
{1009, nullptr, "AcquireAudioControlEventHandle"},
{1010, nullptr, "GetAudioControlStates"},
{1011, nullptr, "DeactivateAudioControl"},
{1050, nullptr, "IsSixAxisSensorAccurateUserCalibrationSupported"},
{1051, nullptr, "StartSixAxisSensorAccurateUserCalibration"},
{1052, nullptr, "CancelSixAxisSensorAccurateUserCalibration"},
{1053, nullptr, "GetSixAxisSensorAccurateUserCalibrationState"},
{1100, nullptr, "GetHidbusSystemServiceObject"},
{1120, nullptr, "SetFirmwareHotfixUpdateSkipEnabled"},
{1130, nullptr, "InitializeUsbFirmwareUpdate"},
{1131, nullptr, "FinalizeUsbFirmwareUpdate"},
{1132, nullptr, "CheckUsbFirmwareUpdateRequired"},
{1133, nullptr, "StartUsbFirmwareUpdate"},
{1134, nullptr, "GetUsbFirmwareUpdateState"},
{1135, &IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory, "InitializeUsbFirmwareUpdateWithoutMemory"},
{1150, nullptr, "SetTouchScreenMagnification"},
{1151, nullptr, "GetTouchScreenFirmwareVersion"},
{1152, nullptr, "SetTouchScreenDefaultConfiguration"},
{1153, &IHidSystemServer::GetTouchScreenDefaultConfiguration, "GetTouchScreenDefaultConfiguration"},
{1154, nullptr, "IsFirmwareAvailableForNotification"},
{1155, nullptr, "SetForceHandheldStyleVibration"},
{1156, nullptr, "SendConnectionTriggerWithoutTimeoutEvent"},
{1157, nullptr, "CancelConnectionTrigger"},
{1200, nullptr, "IsButtonConfigSupported"},
{1201, nullptr, "IsButtonConfigEmbeddedSupported"},
{1202, nullptr, "DeleteButtonConfig"},
{1203, nullptr, "DeleteButtonConfigEmbedded"},
{1204, nullptr, "SetButtonConfigEnabled"},
{1205, nullptr, "SetButtonConfigEmbeddedEnabled"},
{1206, nullptr, "IsButtonConfigEnabled"},
{1207, nullptr, "IsButtonConfigEmbeddedEnabled"},
{1208, nullptr, "SetButtonConfigEmbedded"},
{1209, nullptr, "SetButtonConfigFull"},
{1210, nullptr, "SetButtonConfigLeft"},
{1211, nullptr, "SetButtonConfigRight"},
{1212, nullptr, "GetButtonConfigEmbedded"},
{1213, nullptr, "GetButtonConfigFull"},
{1214, nullptr, "GetButtonConfigLeft"},
{1215, nullptr, "GetButtonConfigRight"},
{1250, nullptr, "IsCustomButtonConfigSupported"},
{1251, nullptr, "IsDefaultButtonConfigEmbedded"},
{1252, nullptr, "IsDefaultButtonConfigFull"},
{1253, nullptr, "IsDefaultButtonConfigLeft"},
{1254, nullptr, "IsDefaultButtonConfigRight"},
{1255, nullptr, "IsButtonConfigStorageEmbeddedEmpty"},
{1256, nullptr, "IsButtonConfigStorageFullEmpty"},
{1257, nullptr, "IsButtonConfigStorageLeftEmpty"},
{1258, nullptr, "IsButtonConfigStorageRightEmpty"},
{1259, nullptr, "GetButtonConfigStorageEmbeddedDeprecated"},
{1260, nullptr, "GetButtonConfigStorageFullDeprecated"},
{1261, nullptr, "GetButtonConfigStorageLeftDeprecated"},
{1262, nullptr, "GetButtonConfigStorageRightDeprecated"},
{1263, nullptr, "SetButtonConfigStorageEmbeddedDeprecated"},
{1264, nullptr, "SetButtonConfigStorageFullDeprecated"},
{1265, nullptr, "SetButtonConfigStorageLeftDeprecated"},
{1266, nullptr, "SetButtonConfigStorageRightDeprecated"},
{1267, nullptr, "DeleteButtonConfigStorageEmbedded"},
{1268, nullptr, "DeleteButtonConfigStorageFull"},
{1269, nullptr, "DeleteButtonConfigStorageLeft"},
{1270, nullptr, "DeleteButtonConfigStorageRight"},
{1271, nullptr, "IsUsingCustomButtonConfig"},
{1272, nullptr, "IsAnyCustomButtonConfigEnabled"},
{1273, nullptr, "SetAllCustomButtonConfigEnabled"},
{1274, nullptr, "SetDefaultButtonConfig"},
{1275, nullptr, "SetAllDefaultButtonConfig"},
{1276, nullptr, "SetHidButtonConfigEmbedded"},
{1277, nullptr, "SetHidButtonConfigFull"},
{1278, nullptr, "SetHidButtonConfigLeft"},
{1279, nullptr, "SetHidButtonConfigRight"},
{1280, nullptr, "GetHidButtonConfigEmbedded"},
{1281, nullptr, "GetHidButtonConfigFull"},
{1282, nullptr, "GetHidButtonConfigLeft"},
{1283, nullptr, "GetHidButtonConfigRight"},
{1284, nullptr, "GetButtonConfigStorageEmbedded"},
{1285, nullptr, "GetButtonConfigStorageFull"},
{1286, nullptr, "GetButtonConfigStorageLeft"},
{1287, nullptr, "GetButtonConfigStorageRight"},
{1288, nullptr, "SetButtonConfigStorageEmbedded"},
{1289, nullptr, "SetButtonConfigStorageFull"},
{1290, nullptr, "DeleteButtonConfigStorageRight"},
{1291, nullptr, "DeleteButtonConfigStorageRight"},
};
// clang-format on
RegisterHandlers(functions);
joy_detach_event = service_context.CreateEvent("IHidSystemServer::JoyDetachEvent");
acquire_device_registered_event =
service_context.CreateEvent("IHidSystemServer::AcquireDeviceRegisteredEvent");
acquire_connection_trigger_timeout_event =
service_context.CreateEvent("IHidSystemServer::AcquireConnectionTriggerTimeoutEvent");
unique_pad_connection_event =
service_context.CreateEvent("IHidSystemServer::AcquireUniquePadConnectionEventHandle");
}
IHidSystemServer::~IHidSystemServer() {
service_context.CloseEvent(joy_detach_event);
service_context.CloseEvent(acquire_device_registered_event);
service_context.CloseEvent(acquire_connection_trigger_timeout_event);
service_context.CloseEvent(unique_pad_connection_event);
};
void IHidSystemServer::ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) {
LOG_WARNING(Service_HID, "called");
GetResourceManager()->GetNpad()->ApplyNpadSystemCommonPolicy();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IHidSystemServer::EnableAssigningSingleOnSlSrPress(HLERequestContext& ctx) {
LOG_WARNING(Service_HID, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IHidSystemServer::DisableAssigningSingleOnSlSrPress(HLERequestContext& ctx) {
LOG_WARNING(Service_HID, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IHidSystemServer::GetLastActiveNpad(HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "(STUBBED) called"); // Spams a lot when controller applet is running
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(system.HIDCore().GetLastActiveController());
}
void IHidSystemServer::ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx) {
LOG_WARNING(Service_HID, "called");
GetResourceManager()->GetNpad()->ApplyNpadSystemCommonPolicy();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IHidSystemServer::GetNpadFullKeyGripColor(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
npad_id_type); // Spams a lot when controller applet is running
Core::HID::NpadColor left_color{};
Core::HID::NpadColor right_color{};
// TODO: Get colors from Npad
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.PushRaw(left_color);
rb.PushRaw(right_color);
}
void IHidSystemServer::GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
LOG_INFO(Service_HID, "(STUBBED) called");
Core::HID::NpadStyleSet supported_styleset =
GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw;
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(supported_styleset);
}
void IHidSystemServer::SetSupportedNpadStyleSetAll(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
LOG_INFO(Service_HID, "(STUBBED) called");
Core::HID::NpadStyleSet supported_styleset =
GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw;
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(supported_styleset);
}
void IHidSystemServer::GetAppletDetailedUiType(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
LOG_DEBUG(Service_HID, "called, npad_id_type={}",
npad_id_type); // Spams a lot when controller applet is running
const NPad::AppletDetailedUiType detailed_ui_type =
GetResourceManager()->GetNpad()->GetAppletDetailedUiType(npad_id_type);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushRaw(detailed_ui_type);
}
void IHidSystemServer::GetNpadInterfaceType(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
npad_id_type); // Spams a lot when controller applet is running
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(Core::HID::NpadInterfaceType::Bluetooth);
}
void IHidSystemServer::GetNpadLeftRightInterfaceType(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
npad_id_type); // Spams a lot when controller applet is running
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.PushEnum(Core::HID::NpadInterfaceType::Bluetooth);
rb.PushEnum(Core::HID::NpadInterfaceType::Bluetooth);
}
void IHidSystemServer::HasBattery(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
npad_id_type); // Spams a lot when controller applet is running
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(false);
}
void IHidSystemServer::HasLeftRightBattery(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
npad_id_type); // Spams a lot when controller applet is running
struct LeftRightBattery {
bool left;
bool right;
};
LeftRightBattery left_right_battery{
.left = false,
.right = false,
};
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushRaw(left_right_battery);
}
void IHidSystemServer::GetUniquePadsFromNpad(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
npad_id_type); // Spams a lot when controller applet is running
const std::vector<Core::HID::UniquePadId> unique_pads{};
if (!unique_pads.empty()) {
ctx.WriteBuffer(unique_pads);
}
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(static_cast<u32>(unique_pads.size()));
}
void IHidSystemServer::GetIrSensorState(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
LOG_WARNING(Service_HID, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IHidSystemServer::AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx) {
LOG_INFO(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(acquire_device_registered_event->GetReadableEvent());
}
void IHidSystemServer::AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx) {
LOG_INFO(Service_HID, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(acquire_device_registered_event->GetReadableEvent());
}
void IHidSystemServer::GetRegisteredDevices(HLERequestContext& ctx) {
LOG_WARNING(Service_HID, "(STUBBED) called");
struct RegisterData {
std::array<u8, 0x68> data;
};
static_assert(sizeof(RegisterData) == 0x68, "RegisterData is an invalid size");
std::vector<RegisterData> registered_devices{};
if (!registered_devices.empty()) {
ctx.WriteBuffer(registered_devices);
}
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.Push<u64>(registered_devices.size());
}
void IHidSystemServer::AcquireUniquePadConnectionEventHandle(HLERequestContext& ctx) {
LOG_WARNING(Service_HID, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.PushCopyObjects(unique_pad_connection_event->GetReadableEvent());
rb.Push(ResultSuccess);
}
void IHidSystemServer::GetUniquePadIds(HLERequestContext& ctx) {
LOG_WARNING(Service_HID, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.Push<u64>(0);
}
void IHidSystemServer::AcquireJoyDetachOnBluetoothOffEventHandle(HLERequestContext& ctx) {
LOG_INFO(Service_AM, "called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(joy_detach_event->GetReadableEvent());
}
void IHidSystemServer::IsUsbFullKeyControllerEnabled(HLERequestContext& ctx) {
const bool is_enabled = false;
LOG_WARNING(Service_HID, "(STUBBED) called, is_enabled={}", is_enabled);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(is_enabled);
}
void IHidSystemServer::IsHandheldButtonPressedOnConsoleMode(HLERequestContext& ctx) {
const bool button_pressed = false;
LOG_DEBUG(Service_HID, "(STUBBED) called, is_enabled={}",
button_pressed); // Spams a lot when controller applet is open
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(button_pressed);
}
void IHidSystemServer::InitializeFirmwareUpdate(HLERequestContext& ctx) {
LOG_WARNING(Service_HID, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx) {
LOG_WARNING(Service_HID, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IHidSystemServer::GetTouchScreenDefaultConfiguration(HLERequestContext& ctx) {
LOG_WARNING(Service_HID, "(STUBBED) called");
Core::HID::TouchScreenConfigurationForNx touchscreen_config{
.mode = Core::HID::TouchScreenModeForNx::Finger,
};
if (touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Heat2 &&
touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Finger) {
touchscreen_config.mode = Core::HID::TouchScreenModeForNx::UseSystemSetting;
}
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(ResultSuccess);
rb.PushRaw(touchscreen_config);
}
std::shared_ptr<ResourceManager> IHidSystemServer::GetResourceManager() {
resource_manager->Initialize();
return resource_manager;
}
} // namespace Service::HID

View File

@@ -1,63 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/service.h"
namespace Core {
class System;
}
namespace Kernel {
class KEvent;
}
namespace Service::HID {
class ResourceManager;
class IHidSystemServer final : public ServiceFramework<IHidSystemServer> {
public:
explicit IHidSystemServer(Core::System& system_, std::shared_ptr<ResourceManager> resource);
~IHidSystemServer() override;
private:
void ApplyNpadSystemCommonPolicy(HLERequestContext& ctx);
void EnableAssigningSingleOnSlSrPress(HLERequestContext& ctx);
void DisableAssigningSingleOnSlSrPress(HLERequestContext& ctx);
void GetLastActiveNpad(HLERequestContext& ctx);
void ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx);
void GetNpadFullKeyGripColor(HLERequestContext& ctx);
void GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx);
void SetSupportedNpadStyleSetAll(HLERequestContext& ctx);
void GetAppletDetailedUiType(HLERequestContext& ctx);
void GetNpadInterfaceType(HLERequestContext& ctx);
void GetNpadLeftRightInterfaceType(HLERequestContext& ctx);
void HasBattery(HLERequestContext& ctx);
void HasLeftRightBattery(HLERequestContext& ctx);
void GetUniquePadsFromNpad(HLERequestContext& ctx);
void GetIrSensorState(HLERequestContext& ctx);
void AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx);
void AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx);
void GetRegisteredDevices(HLERequestContext& ctx);
void AcquireUniquePadConnectionEventHandle(HLERequestContext& ctx);
void GetUniquePadIds(HLERequestContext& ctx);
void AcquireJoyDetachOnBluetoothOffEventHandle(HLERequestContext& ctx);
void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx);
void IsHandheldButtonPressedOnConsoleMode(HLERequestContext& ctx);
void InitializeFirmwareUpdate(HLERequestContext& ctx);
void InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx);
void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx);
std::shared_ptr<ResourceManager> GetResourceManager();
Kernel::KEvent* acquire_connection_trigger_timeout_event;
Kernel::KEvent* acquire_device_registered_event;
Kernel::KEvent* joy_detach_event;
Kernel::KEvent* unique_pad_connection_event;
KernelHelpers::ServiceContext service_context;
std::shared_ptr<ResourceManager> resource_manager;
};
} // namespace Service::HID

View File

@@ -1,146 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hid/hid_types.h"
#include "core/hle/service/hid/errors.h"
namespace Service::HID {
constexpr bool IsNpadIdValid(const Core::HID::NpadIdType npad_id) {
switch (npad_id) {
case Core::HID::NpadIdType::Player1:
case Core::HID::NpadIdType::Player2:
case Core::HID::NpadIdType::Player3:
case Core::HID::NpadIdType::Player4:
case Core::HID::NpadIdType::Player5:
case Core::HID::NpadIdType::Player6:
case Core::HID::NpadIdType::Player7:
case Core::HID::NpadIdType::Player8:
case Core::HID::NpadIdType::Other:
case Core::HID::NpadIdType::Handheld:
return true;
default:
return false;
}
}
constexpr Result IsSixaxisHandleValid(const Core::HID::SixAxisSensorHandle& handle) {
const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(handle.npad_id));
const bool device_index = handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
if (!npad_id) {
return InvalidNpadId;
}
if (!device_index) {
return NpadDeviceIndexOutOfRange;
}
return ResultSuccess;
}
constexpr Result IsVibrationHandleValid(const Core::HID::VibrationDeviceHandle& handle) {
switch (handle.npad_type) {
case Core::HID::NpadStyleIndex::ProController:
case Core::HID::NpadStyleIndex::Handheld:
case Core::HID::NpadStyleIndex::JoyconDual:
case Core::HID::NpadStyleIndex::JoyconLeft:
case Core::HID::NpadStyleIndex::JoyconRight:
case Core::HID::NpadStyleIndex::GameCube:
case Core::HID::NpadStyleIndex::N64:
case Core::HID::NpadStyleIndex::SystemExt:
case Core::HID::NpadStyleIndex::System:
// These support vibration
break;
default:
return VibrationInvalidStyleIndex;
}
if (!IsNpadIdValid(static_cast<Core::HID::NpadIdType>(handle.npad_id))) {
return VibrationInvalidNpadId;
}
if (handle.device_index >= Core::HID::DeviceIndex::MaxDeviceIndex) {
return VibrationDeviceIndexOutOfRange;
}
return ResultSuccess;
}
/// Converts a Core::HID::NpadIdType to an array index.
constexpr size_t NpadIdTypeToIndex(Core::HID::NpadIdType npad_id_type) {
switch (npad_id_type) {
case Core::HID::NpadIdType::Player1:
return 0;
case Core::HID::NpadIdType::Player2:
return 1;
case Core::HID::NpadIdType::Player3:
return 2;
case Core::HID::NpadIdType::Player4:
return 3;
case Core::HID::NpadIdType::Player5:
return 4;
case Core::HID::NpadIdType::Player6:
return 5;
case Core::HID::NpadIdType::Player7:
return 6;
case Core::HID::NpadIdType::Player8:
return 7;
case Core::HID::NpadIdType::Handheld:
return 8;
case Core::HID::NpadIdType::Other:
return 9;
default:
return 8;
}
}
/// Converts an array index to a Core::HID::NpadIdType
constexpr Core::HID::NpadIdType IndexToNpadIdType(size_t index) {
switch (index) {
case 0:
return Core::HID::NpadIdType::Player1;
case 1:
return Core::HID::NpadIdType::Player2;
case 2:
return Core::HID::NpadIdType::Player3;
case 3:
return Core::HID::NpadIdType::Player4;
case 4:
return Core::HID::NpadIdType::Player5;
case 5:
return Core::HID::NpadIdType::Player6;
case 6:
return Core::HID::NpadIdType::Player7;
case 7:
return Core::HID::NpadIdType::Player8;
case 8:
return Core::HID::NpadIdType::Handheld;
case 9:
return Core::HID::NpadIdType::Other;
default:
return Core::HID::NpadIdType::Invalid;
}
}
constexpr Core::HID::NpadStyleSet GetStylesetByIndex(std::size_t index) {
switch (index) {
case 0:
return Core::HID::NpadStyleSet::Fullkey;
case 1:
return Core::HID::NpadStyleSet::Handheld;
case 2:
return Core::HID::NpadStyleSet::JoyDual;
case 3:
return Core::HID::NpadStyleSet::JoyLeft;
case 4:
return Core::HID::NpadStyleSet::JoyRight;
case 5:
return Core::HID::NpadStyleSet::Palma;
default:
return Core::HID::NpadStyleSet::None;
}
}
} // namespace Service::HID

View File

@@ -12,7 +12,6 @@
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/service/hid/errors.h"
#include "core/hle/service/hid/hid_util.h"
#include "core/hle/service/hid/irs.h"
#include "core/hle/service/hid/irsensor/clustering_processor.h"
#include "core/hle/service/hid/irsensor/image_transfer_processor.h"
@@ -321,7 +320,7 @@ void IRS::GetNpadIrCameraHandle(HLERequestContext& ctx) {
}
Core::IrSensor::IrCameraHandle camera_handle{
.npad_id = static_cast<u8>(HID::NpadIdTypeToIndex(npad_id)),
.npad_id = static_cast<u8>(NpadIdTypeToIndex(npad_id)),
.npad_type = Core::HID::NpadStyleIndex::None,
};
@@ -546,7 +545,7 @@ void IRS::ActivateIrsensorWithFunctionLevel(HLERequestContext& ctx) {
Result IRS::IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const {
if (camera_handle.npad_id >
static_cast<u8>(HID::NpadIdTypeToIndex(Core::HID::NpadIdType::Handheld))) {
static_cast<u8>(NpadIdTypeToIndex(Core::HID::NpadIdType::Handheld))) {
return InvalidIrCameraHandle;
}
if (camera_handle.npad_type != Core::HID::NpadStyleIndex::None) {

View File

@@ -3,12 +3,15 @@
#pragma once
#include "core/core.h"
#include "core/hid/hid_types.h"
#include "core/hid/irs_types.h"
#include "core/hle/service/hid/irsensor/processor_base.h"
#include "core/hle/service/service.h"
namespace Core {
class System;
}
namespace Core::HID {
class EmulatedController;
} // namespace Core::HID

View File

@@ -1,241 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "common/logging/log.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hid/hid_core.h"
#include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/service/hid/resource_manager.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/hid/controllers/console_six_axis.h"
#include "core/hle/service/hid/controllers/debug_pad.h"
#include "core/hle/service/hid/controllers/gesture.h"
#include "core/hle/service/hid/controllers/keyboard.h"
#include "core/hle/service/hid/controllers/mouse.h"
#include "core/hle/service/hid/controllers/npad.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/six_axis.h"
#include "core/hle/service/hid/controllers/stubbed.h"
#include "core/hle/service/hid/controllers/touchscreen.h"
#include "core/hle/service/hid/controllers/xpad.h"
namespace Service::HID {
// Updating period for each HID device.
// Period time is obtained by measuring the number of samples in a second on HW using a homebrew
// Correct npad_update_ns is 4ms this is overclocked to lower input lag
constexpr auto npad_update_ns = std::chrono::nanoseconds{1 * 1000 * 1000}; // (1ms, 1000Hz)
constexpr auto default_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 1000Hz)
constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz)
constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz)
ResourceManager::ResourceManager(Core::System& system_)
: system{system_}, service_context{system_, "hid"} {}
ResourceManager::~ResourceManager() = default;
void ResourceManager::Initialize() {
if (is_initialized) {
return;
}
u8* shared_memory = system.Kernel().GetHidSharedMem().GetPointer();
debug_pad = std::make_shared<DebugPad>(system.HIDCore(), shared_memory);
mouse = std::make_shared<Mouse>(system.HIDCore(), shared_memory);
debug_mouse = std::make_shared<DebugMouse>(system.HIDCore(), shared_memory);
keyboard = std::make_shared<Keyboard>(system.HIDCore(), shared_memory);
unique_pad = std::make_shared<UniquePad>(system.HIDCore(), shared_memory);
npad = std::make_shared<NPad>(system.HIDCore(), shared_memory, service_context);
gesture = std::make_shared<Gesture>(system.HIDCore(), shared_memory);
touch_screen = std::make_shared<TouchScreen>(system.HIDCore(), shared_memory);
xpad = std::make_shared<XPad>(system.HIDCore(), shared_memory);
palma = std::make_shared<Palma>(system.HIDCore(), shared_memory, service_context);
home_button = std::make_shared<HomeButton>(system.HIDCore(), shared_memory);
sleep_button = std::make_shared<SleepButton>(system.HIDCore(), shared_memory);
capture_button = std::make_shared<CaptureButton>(system.HIDCore(), shared_memory);
six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad);
console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore(), shared_memory);
seven_six_axis = std::make_shared<SevenSixAxis>(system);
home_button->SetCommonHeaderOffset(0x4C00);
sleep_button->SetCommonHeaderOffset(0x4E00);
capture_button->SetCommonHeaderOffset(0x5000);
unique_pad->SetCommonHeaderOffset(0x5A00);
debug_mouse->SetCommonHeaderOffset(0x3DC00);
// Homebrew doesn't try to activate some controllers, so we activate them by default
npad->Activate();
six_axis->Activate();
touch_screen->Activate();
system.HIDCore().ReloadInputDevices();
is_initialized = true;
}
std::shared_ptr<CaptureButton> ResourceManager::GetCaptureButton() const {
return capture_button;
}
std::shared_ptr<ConsoleSixAxis> ResourceManager::GetConsoleSixAxis() const {
return console_six_axis;
}
std::shared_ptr<DebugMouse> ResourceManager::GetDebugMouse() const {
return debug_mouse;
}
std::shared_ptr<DebugPad> ResourceManager::GetDebugPad() const {
return debug_pad;
}
std::shared_ptr<Gesture> ResourceManager::GetGesture() const {
return gesture;
}
std::shared_ptr<HomeButton> ResourceManager::GetHomeButton() const {
return home_button;
}
std::shared_ptr<Keyboard> ResourceManager::GetKeyboard() const {
return keyboard;
}
std::shared_ptr<Mouse> ResourceManager::GetMouse() const {
return mouse;
}
std::shared_ptr<NPad> ResourceManager::GetNpad() const {
return npad;
}
std::shared_ptr<Palma> ResourceManager::GetPalma() const {
return palma;
}
std::shared_ptr<SevenSixAxis> ResourceManager::GetSevenSixAxis() const {
return seven_six_axis;
}
std::shared_ptr<SixAxis> ResourceManager::GetSixAxis() const {
return six_axis;
}
std::shared_ptr<SleepButton> ResourceManager::GetSleepButton() const {
return sleep_button;
}
std::shared_ptr<TouchScreen> ResourceManager::GetTouchScreen() const {
return touch_screen;
}
std::shared_ptr<UniquePad> ResourceManager::GetUniquePad() const {
return unique_pad;
}
void ResourceManager::UpdateControllers(std::uintptr_t user_data,
std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming();
debug_pad->OnUpdate(core_timing);
unique_pad->OnUpdate(core_timing);
gesture->OnUpdate(core_timing);
touch_screen->OnUpdate(core_timing);
palma->OnUpdate(core_timing);
home_button->OnUpdate(core_timing);
sleep_button->OnUpdate(core_timing);
capture_button->OnUpdate(core_timing);
xpad->OnUpdate(core_timing);
}
void ResourceManager::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming();
npad->OnUpdate(core_timing);
}
void ResourceManager::UpdateMouseKeyboard(std::uintptr_t user_data,
std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming();
mouse->OnUpdate(core_timing);
debug_mouse->OnUpdate(core_timing);
keyboard->OnUpdate(core_timing);
}
void ResourceManager::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming();
six_axis->OnUpdate(core_timing);
seven_six_axis->OnUpdate(core_timing);
console_six_axis->OnUpdate(core_timing);
}
IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource)
: ServiceFramework{system_, "IAppletResource"} {
static const FunctionInfo functions[] = {
{0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
};
RegisterHandlers(functions);
resource->Initialize();
// Register update callbacks
npad_update_event = Core::Timing::CreateEvent(
"HID::UpdatePadCallback",
[this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)
-> std::optional<std::chrono::nanoseconds> {
const auto guard = LockService();
resource->UpdateNpad(user_data, ns_late);
return std::nullopt;
});
default_update_event = Core::Timing::CreateEvent(
"HID::UpdateDefaultCallback",
[this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)
-> std::optional<std::chrono::nanoseconds> {
const auto guard = LockService();
resource->UpdateControllers(user_data, ns_late);
return std::nullopt;
});
mouse_keyboard_update_event = Core::Timing::CreateEvent(
"HID::UpdateMouseKeyboardCallback",
[this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)
-> std::optional<std::chrono::nanoseconds> {
const auto guard = LockService();
resource->UpdateMouseKeyboard(user_data, ns_late);
return std::nullopt;
});
motion_update_event = Core::Timing::CreateEvent(
"HID::UpdateMotionCallback",
[this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)
-> std::optional<std::chrono::nanoseconds> {
const auto guard = LockService();
resource->UpdateMotion(user_data, ns_late);
return std::nullopt;
});
system.CoreTiming().ScheduleLoopingEvent(npad_update_ns, npad_update_ns, npad_update_event);
system.CoreTiming().ScheduleLoopingEvent(default_update_ns, default_update_ns,
default_update_event);
system.CoreTiming().ScheduleLoopingEvent(mouse_keyboard_update_ns, mouse_keyboard_update_ns,
mouse_keyboard_update_event);
system.CoreTiming().ScheduleLoopingEvent(motion_update_ns, motion_update_ns,
motion_update_event);
}
IAppletResource::~IAppletResource() {
system.CoreTiming().UnscheduleEvent(npad_update_event, 0);
system.CoreTiming().UnscheduleEvent(default_update_event, 0);
system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0);
system.CoreTiming().UnscheduleEvent(motion_update_event, 0);
}
void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(&system.Kernel().GetHidSharedMem());
}
} // namespace Service::HID

View File

@@ -1,111 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/service.h"
namespace Core::Timing {
struct EventType;
}
namespace Service::HID {
class Controller_Stubbed;
class ConsoleSixAxis;
class DebugPad;
class Gesture;
class Keyboard;
class Mouse;
class NPad;
class Palma;
class SevenSixAxis;
class SixAxis;
class TouchScreen;
class XPad;
using CaptureButton = Controller_Stubbed;
using DebugMouse = Controller_Stubbed;
using HomeButton = Controller_Stubbed;
using SleepButton = Controller_Stubbed;
using UniquePad = Controller_Stubbed;
class ResourceManager {
public:
explicit ResourceManager(Core::System& system_);
~ResourceManager();
void Initialize();
std::shared_ptr<CaptureButton> GetCaptureButton() const;
std::shared_ptr<ConsoleSixAxis> GetConsoleSixAxis() const;
std::shared_ptr<DebugMouse> GetDebugMouse() const;
std::shared_ptr<DebugPad> GetDebugPad() const;
std::shared_ptr<Gesture> GetGesture() const;
std::shared_ptr<HomeButton> GetHomeButton() const;
std::shared_ptr<Keyboard> GetKeyboard() const;
std::shared_ptr<Mouse> GetMouse() const;
std::shared_ptr<NPad> GetNpad() const;
std::shared_ptr<Palma> GetPalma() const;
std::shared_ptr<SevenSixAxis> GetSevenSixAxis() const;
std::shared_ptr<SixAxis> GetSixAxis() const;
std::shared_ptr<SleepButton> GetSleepButton() const;
std::shared_ptr<TouchScreen> GetTouchScreen() const;
std::shared_ptr<UniquePad> GetUniquePad() const;
void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
private:
bool is_initialized{false};
std::shared_ptr<CaptureButton> capture_button = nullptr;
std::shared_ptr<ConsoleSixAxis> console_six_axis = nullptr;
std::shared_ptr<DebugMouse> debug_mouse = nullptr;
std::shared_ptr<DebugPad> debug_pad = nullptr;
std::shared_ptr<Gesture> gesture = nullptr;
std::shared_ptr<HomeButton> home_button = nullptr;
std::shared_ptr<Keyboard> keyboard = nullptr;
std::shared_ptr<Mouse> mouse = nullptr;
std::shared_ptr<NPad> npad = nullptr;
std::shared_ptr<Palma> palma = nullptr;
std::shared_ptr<SevenSixAxis> seven_six_axis = nullptr;
std::shared_ptr<SixAxis> six_axis = nullptr;
std::shared_ptr<SleepButton> sleep_button = nullptr;
std::shared_ptr<TouchScreen> touch_screen = nullptr;
std::shared_ptr<UniquePad> unique_pad = nullptr;
std::shared_ptr<XPad> xpad = nullptr;
// TODO: Create these resources
// std::shared_ptr<AudioControl> audio_control = nullptr;
// std::shared_ptr<ButtonConfig> button_config = nullptr;
// std::shared_ptr<Config> config = nullptr;
// std::shared_ptr<Connection> connection = nullptr;
// std::shared_ptr<CustomConfig> custom_config = nullptr;
// std::shared_ptr<Digitizer> digitizer = nullptr;
// std::shared_ptr<Hdls> hdls = nullptr;
// std::shared_ptr<PlayReport> play_report = nullptr;
// std::shared_ptr<Rail> rail = nullptr;
Core::System& system;
KernelHelpers::ServiceContext service_context;
};
class IAppletResource final : public ServiceFramework<IAppletResource> {
public:
explicit IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource);
~IAppletResource() override;
private:
void GetSharedMemoryHandle(HLERequestContext& ctx);
std::shared_ptr<Core::Timing::EventType> npad_update_event;
std::shared_ptr<Core::Timing::EventType> default_update_event;
std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event;
std::shared_ptr<Core::Timing::EventType> motion_update_event;
};
} // namespace Service::HID

View File

@@ -115,20 +115,12 @@ public:
{400, nullptr, "InitializeSystem"},
{401, nullptr, "FinalizeSystem"},
{402, nullptr, "SetOperationMode"},
{403, &ISystemLocalCommunicationService::InitializeSystem2, "InitializeSystem2"},
{403, nullptr, "InitializeSystem2"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void InitializeSystem2(HLERequestContext& ctx) {
LOG_WARNING(Service_LDN, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
};
class IUserLocalCommunicationService final

Some files were not shown because too many files have changed in this diff Show More