diff options
66 files changed, 1052 insertions, 697 deletions
diff --git a/.gitmodules b/.gitmodules index e65997afc..52256d86f 100644 --- a/.gitmodules +++ b/.gitmodules | |||
| @@ -64,3 +64,6 @@ | |||
| 64 | [submodule "oaknut"] | 64 | [submodule "oaknut"] |
| 65 | path = externals/oaknut | 65 | path = externals/oaknut |
| 66 | url = https://github.com/merryhime/oaknut | 66 | url = https://github.com/merryhime/oaknut |
| 67 | [submodule "Vulkan-Utility-Libraries"] | ||
| 68 | path = externals/Vulkan-Utility-Libraries | ||
| 69 | url = https://github.com/KhronosGroup/Vulkan-Utility-Libraries.git | ||
diff --git a/CMakeLists.txt b/CMakeLists.txt index 7cd6b2108..eb26fbfd8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
| @@ -36,6 +36,8 @@ option(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" "${WIN32}") | |||
| 36 | 36 | ||
| 37 | option(YUZU_USE_EXTERNAL_VULKAN_HEADERS "Use Vulkan-Headers from externals" ON) | 37 | option(YUZU_USE_EXTERNAL_VULKAN_HEADERS "Use Vulkan-Headers from externals" ON) |
| 38 | 38 | ||
| 39 | option(YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES "Use Vulkan-Utility-Libraries from externals" ON) | ||
| 40 | |||
| 39 | option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF) | 41 | option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF) |
| 40 | 42 | ||
| 41 | option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF) | 43 | option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF) |
| @@ -308,6 +310,10 @@ if (NOT YUZU_USE_EXTERNAL_VULKAN_HEADERS) | |||
| 308 | find_package(Vulkan 1.3.274 REQUIRED) | 310 | find_package(Vulkan 1.3.274 REQUIRED) |
| 309 | endif() | 311 | endif() |
| 310 | 312 | ||
| 313 | if (NOT YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES) | ||
| 314 | find_package(VulkanUtilityLibraries REQUIRED) | ||
| 315 | endif() | ||
| 316 | |||
| 311 | if (ENABLE_LIBUSB) | 317 | if (ENABLE_LIBUSB) |
| 312 | find_package(libusb 1.0.24 MODULE) | 318 | find_package(libusb 1.0.24 MODULE) |
| 313 | endif() | 319 | endif() |
diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 15b444338..42355716c 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt | |||
| @@ -154,6 +154,11 @@ if (YUZU_USE_EXTERNAL_VULKAN_HEADERS) | |||
| 154 | add_subdirectory(Vulkan-Headers) | 154 | add_subdirectory(Vulkan-Headers) |
| 155 | endif() | 155 | endif() |
| 156 | 156 | ||
| 157 | # Vulkan-Utility-Libraries | ||
| 158 | if (YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES) | ||
| 159 | add_subdirectory(Vulkan-Utility-Libraries) | ||
| 160 | endif() | ||
| 161 | |||
| 157 | # TZDB (Time Zone Database) | 162 | # TZDB (Time Zone Database) |
| 158 | add_subdirectory(nx_tzdb) | 163 | add_subdirectory(nx_tzdb) |
| 159 | 164 | ||
diff --git a/externals/Vulkan-Utility-Libraries b/externals/Vulkan-Utility-Libraries new file mode 160000 | |||
| Subproject 524f8910d0e4a5f2ec5961996b23e5b74b95cb1 | |||
diff --git a/externals/nx_tzdb/CMakeLists.txt b/externals/nx_tzdb/CMakeLists.txt index 0fad24642..13723f175 100644 --- a/externals/nx_tzdb/CMakeLists.txt +++ b/externals/nx_tzdb/CMakeLists.txt | |||
| @@ -32,7 +32,7 @@ set(NX_TZDB_ARCHIVE "${CMAKE_CURRENT_BINARY_DIR}/${NX_TZDB_VERSION}.zip") | |||
| 32 | 32 | ||
| 33 | set(NX_TZDB_ROMFS_DIR "${CMAKE_CURRENT_BINARY_DIR}/nx_tzdb") | 33 | set(NX_TZDB_ROMFS_DIR "${CMAKE_CURRENT_BINARY_DIR}/nx_tzdb") |
| 34 | 34 | ||
| 35 | if ((NOT CAN_BUILD_NX_TZDB OR YUZU_DOWNLOAD_TIME_ZONE_DATA) AND NOT EXISTS ${NX_TZDB_ARCHIVE}) | 35 | if ((NOT CAN_BUILD_NX_TZDB OR YUZU_DOWNLOAD_TIME_ZONE_DATA) AND NOT EXISTS ${NX_TZDB_ROMFS_DIR}) |
| 36 | set(NX_TZDB_DOWNLOAD_URL "https://github.com/lat9nq/tzdb_to_nx/releases/download/${NX_TZDB_VERSION}/${NX_TZDB_VERSION}.zip") | 36 | set(NX_TZDB_DOWNLOAD_URL "https://github.com/lat9nq/tzdb_to_nx/releases/download/${NX_TZDB_VERSION}/${NX_TZDB_VERSION}.zip") |
| 37 | 37 | ||
| 38 | message(STATUS "Downloading time zone data from ${NX_TZDB_DOWNLOAD_URL}...") | 38 | message(STATUS "Downloading time zone data from ${NX_TZDB_DOWNLOAD_URL}...") |
diff --git a/externals/nx_tzdb/NxTzdbCreateHeader.cmake b/externals/nx_tzdb/NxTzdbCreateHeader.cmake index 8c29e1167..95606d862 100644 --- a/externals/nx_tzdb/NxTzdbCreateHeader.cmake +++ b/externals/nx_tzdb/NxTzdbCreateHeader.cmake | |||
| @@ -11,6 +11,10 @@ execute_process( | |||
| 11 | WORKING_DIRECTORY ${ZONE_PATH} | 11 | WORKING_DIRECTORY ${ZONE_PATH} |
| 12 | OUTPUT_VARIABLE FILE_LIST) | 12 | OUTPUT_VARIABLE FILE_LIST) |
| 13 | 13 | ||
| 14 | if (NOT FILE_LIST) | ||
| 15 | message(FATAL_ERROR "No timezone files found in directory ${ZONE_PATH}, did the download fail?") | ||
| 16 | endif() | ||
| 17 | |||
| 14 | set(DIRECTORY_NAME ${HEADER_NAME}) | 18 | set(DIRECTORY_NAME ${HEADER_NAME}) |
| 15 | 19 | ||
| 16 | set(FILE_DATA "") | 20 | set(FILE_DATA "") |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt index 55abba093..53137b2e2 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt | |||
| @@ -261,7 +261,7 @@ object NativeLibrary { | |||
| 261 | /** | 261 | /** |
| 262 | * Begins emulation. | 262 | * Begins emulation. |
| 263 | */ | 263 | */ |
| 264 | external fun run(path: String?) | 264 | external fun run(path: String?, programIndex: Int = 0) |
| 265 | 265 | ||
| 266 | // Surface Handling | 266 | // Surface Handling |
| 267 | external fun surfaceChanged(surf: Surface?) | 267 | external fun surfaceChanged(surf: Surface?) |
| @@ -489,6 +489,12 @@ object NativeLibrary { | |||
| 489 | sEmulationActivity.get()!!.onEmulationStopped(status) | 489 | sEmulationActivity.get()!!.onEmulationStopped(status) |
| 490 | } | 490 | } |
| 491 | 491 | ||
| 492 | @Keep | ||
| 493 | @JvmStatic | ||
| 494 | fun onProgramChanged(programIndex: Int) { | ||
| 495 | sEmulationActivity.get()!!.onProgramChanged(programIndex) | ||
| 496 | } | ||
| 497 | |||
| 492 | /** | 498 | /** |
| 493 | * Logs the Yuzu version, Android version and, CPU. | 499 | * Logs the Yuzu version, Android version and, CPU. |
| 494 | */ | 500 | */ |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt index 26cddecf4..564aaf305 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt | |||
| @@ -76,7 +76,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener { | |||
| 76 | 76 | ||
| 77 | override fun onDestroy() { | 77 | override fun onDestroy() { |
| 78 | stopForegroundService(this) | 78 | stopForegroundService(this) |
| 79 | emulationViewModel.clear() | ||
| 80 | super.onDestroy() | 79 | super.onDestroy() |
| 81 | } | 80 | } |
| 82 | 81 | ||
| @@ -446,9 +445,14 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener { | |||
| 446 | } | 445 | } |
| 447 | 446 | ||
| 448 | fun onEmulationStopped(status: Int) { | 447 | fun onEmulationStopped(status: Int) { |
| 449 | if (status == 0) { | 448 | if (status == 0 && emulationViewModel.programChanged.value == -1) { |
| 450 | finish() | 449 | finish() |
| 451 | } | 450 | } |
| 451 | emulationViewModel.setEmulationStopped(true) | ||
| 452 | } | ||
| 453 | |||
| 454 | fun onProgramChanged(programIndex: Int) { | ||
| 455 | emulationViewModel.setProgramChanged(programIndex) | ||
| 452 | } | 456 | } |
| 453 | 457 | ||
| 454 | private fun startMotionSensorListener() { | 458 | private fun startMotionSensorListener() { |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt index 22da1d0e5..1f591ced1 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt | |||
| @@ -301,6 +301,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 301 | 301 | ||
| 302 | R.id.menu_exit -> { | 302 | R.id.menu_exit -> { |
| 303 | emulationState.stop() | 303 | emulationState.stop() |
| 304 | NativeConfig.reloadGlobalConfig() | ||
| 304 | emulationViewModel.setIsEmulationStopping(true) | 305 | emulationViewModel.setIsEmulationStopping(true) |
| 305 | binding.drawerLayout.close() | 306 | binding.drawerLayout.close() |
| 306 | binding.inGameMenu.requestFocus() | 307 | binding.inGameMenu.requestFocus() |
| @@ -423,10 +424,38 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 423 | } | 424 | } |
| 424 | } | 425 | } |
| 425 | } | 426 | } |
| 427 | launch { | ||
| 428 | repeatOnLifecycle(Lifecycle.State.CREATED) { | ||
| 429 | emulationViewModel.programChanged.collect { | ||
| 430 | if (it != 0) { | ||
| 431 | emulationViewModel.setEmulationStarted(false) | ||
| 432 | binding.drawerLayout.close() | ||
| 433 | binding.drawerLayout | ||
| 434 | .setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) | ||
| 435 | ViewUtils.hideView(binding.surfaceInputOverlay) | ||
| 436 | ViewUtils.showView(binding.loadingIndicator) | ||
| 437 | } | ||
| 438 | } | ||
| 439 | } | ||
| 440 | } | ||
| 441 | launch { | ||
| 442 | repeatOnLifecycle(Lifecycle.State.CREATED) { | ||
| 443 | emulationViewModel.emulationStopped.collect { | ||
| 444 | if (it && emulationViewModel.programChanged.value != -1) { | ||
| 445 | if (perfStatsUpdater != null) { | ||
| 446 | perfStatsUpdateHandler.removeCallbacks(perfStatsUpdater!!) | ||
| 447 | } | ||
| 448 | emulationState.changeProgram(emulationViewModel.programChanged.value) | ||
| 449 | emulationViewModel.setProgramChanged(-1) | ||
| 450 | emulationViewModel.setEmulationStopped(false) | ||
| 451 | } | ||
| 452 | } | ||
| 453 | } | ||
| 454 | } | ||
| 426 | } | 455 | } |
| 427 | } | 456 | } |
| 428 | 457 | ||
| 429 | private fun startEmulation() { | 458 | private fun startEmulation(programIndex: Int = 0) { |
| 430 | if (!NativeLibrary.isRunning() && !NativeLibrary.isPaused()) { | 459 | if (!NativeLibrary.isRunning() && !NativeLibrary.isPaused()) { |
| 431 | if (!DirectoryInitialization.areDirectoriesReady) { | 460 | if (!DirectoryInitialization.areDirectoriesReady) { |
| 432 | DirectoryInitialization.start() | 461 | DirectoryInitialization.start() |
| @@ -434,7 +463,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 434 | 463 | ||
| 435 | updateScreenLayout() | 464 | updateScreenLayout() |
| 436 | 465 | ||
| 437 | emulationState.run(emulationActivity!!.isActivityRecreated) | 466 | emulationState.run(emulationActivity!!.isActivityRecreated, programIndex) |
| 438 | } | 467 | } |
| 439 | } | 468 | } |
| 440 | 469 | ||
| @@ -832,6 +861,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 832 | ) { | 861 | ) { |
| 833 | private var state: State | 862 | private var state: State |
| 834 | private var surface: Surface? = null | 863 | private var surface: Surface? = null |
| 864 | lateinit var emulationThread: Thread | ||
| 835 | 865 | ||
| 836 | init { | 866 | init { |
| 837 | // Starting state is stopped. | 867 | // Starting state is stopped. |
| @@ -877,7 +907,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 877 | } | 907 | } |
| 878 | 908 | ||
| 879 | @Synchronized | 909 | @Synchronized |
| 880 | fun run(isActivityRecreated: Boolean) { | 910 | fun run(isActivityRecreated: Boolean, programIndex: Int = 0) { |
| 881 | if (isActivityRecreated) { | 911 | if (isActivityRecreated) { |
| 882 | if (NativeLibrary.isRunning()) { | 912 | if (NativeLibrary.isRunning()) { |
| 883 | state = State.PAUSED | 913 | state = State.PAUSED |
| @@ -888,10 +918,20 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 888 | 918 | ||
| 889 | // If the surface is set, run now. Otherwise, wait for it to get set. | 919 | // If the surface is set, run now. Otherwise, wait for it to get set. |
| 890 | if (surface != null) { | 920 | if (surface != null) { |
| 891 | runWithValidSurface() | 921 | runWithValidSurface(programIndex) |
| 892 | } | 922 | } |
| 893 | } | 923 | } |
| 894 | 924 | ||
| 925 | @Synchronized | ||
| 926 | fun changeProgram(programIndex: Int) { | ||
| 927 | emulationThread.join() | ||
| 928 | emulationThread = Thread({ | ||
| 929 | Log.debug("[EmulationFragment] Starting emulation thread.") | ||
| 930 | NativeLibrary.run(gamePath, programIndex) | ||
| 931 | }, "NativeEmulation") | ||
| 932 | emulationThread.start() | ||
| 933 | } | ||
| 934 | |||
| 895 | // Surface callbacks | 935 | // Surface callbacks |
| 896 | @Synchronized | 936 | @Synchronized |
| 897 | fun newSurface(surface: Surface?) { | 937 | fun newSurface(surface: Surface?) { |
| @@ -931,7 +971,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 931 | } | 971 | } |
| 932 | } | 972 | } |
| 933 | 973 | ||
| 934 | private fun runWithValidSurface() { | 974 | private fun runWithValidSurface(programIndex: Int = 0) { |
| 935 | NativeLibrary.surfaceChanged(surface) | 975 | NativeLibrary.surfaceChanged(surface) |
| 936 | if (!emulationCanStart.invoke()) { | 976 | if (!emulationCanStart.invoke()) { |
| 937 | return | 977 | return |
| @@ -939,9 +979,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 939 | 979 | ||
| 940 | when (state) { | 980 | when (state) { |
| 941 | State.STOPPED -> { | 981 | State.STOPPED -> { |
| 942 | val emulationThread = Thread({ | 982 | emulationThread = Thread({ |
| 943 | Log.debug("[EmulationFragment] Starting emulation thread.") | 983 | Log.debug("[EmulationFragment] Starting emulation thread.") |
| 944 | NativeLibrary.run(gamePath) | 984 | NativeLibrary.run(gamePath, programIndex) |
| 945 | }, "NativeEmulation") | 985 | }, "NativeEmulation") |
| 946 | emulationThread.start() | 986 | emulationThread.start() |
| 947 | } | 987 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt index 5ed754c96..a49c887a1 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt | |||
| @@ -66,10 +66,13 @@ class DriverViewModel : ViewModel() { | |||
| 66 | 66 | ||
| 67 | fun updateDriverList() { | 67 | fun updateDriverList() { |
| 68 | val selectedDriver = GpuDriverHelper.customDriverSettingData | 68 | val selectedDriver = GpuDriverHelper.customDriverSettingData |
| 69 | val systemDriverData = GpuDriverHelper.getSystemDriverInfo() | ||
| 69 | val newDriverList = mutableListOf( | 70 | val newDriverList = mutableListOf( |
| 70 | Driver( | 71 | Driver( |
| 71 | selectedDriver == GpuDriverMetadata(), | 72 | selectedDriver == GpuDriverMetadata(), |
| 72 | YuzuApplication.appContext.getString(R.string.system_gpu_driver) | 73 | YuzuApplication.appContext.getString(R.string.system_gpu_driver), |
| 74 | systemDriverData?.get(0) ?: "", | ||
| 75 | systemDriverData?.get(1) ?: "" | ||
| 73 | ) | 76 | ) |
| 74 | ) | 77 | ) |
| 75 | driverData.forEach { | 78 | driverData.forEach { |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/EmulationViewModel.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/EmulationViewModel.kt index b66f47fe7..d024493cd 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/EmulationViewModel.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/EmulationViewModel.kt | |||
| @@ -15,6 +15,12 @@ class EmulationViewModel : ViewModel() { | |||
| 15 | val isEmulationStopping: StateFlow<Boolean> get() = _isEmulationStopping | 15 | val isEmulationStopping: StateFlow<Boolean> get() = _isEmulationStopping |
| 16 | private val _isEmulationStopping = MutableStateFlow(false) | 16 | private val _isEmulationStopping = MutableStateFlow(false) |
| 17 | 17 | ||
| 18 | private val _emulationStopped = MutableStateFlow(false) | ||
| 19 | val emulationStopped = _emulationStopped.asStateFlow() | ||
| 20 | |||
| 21 | private val _programChanged = MutableStateFlow(-1) | ||
| 22 | val programChanged = _programChanged.asStateFlow() | ||
| 23 | |||
| 18 | val shaderProgress: StateFlow<Int> get() = _shaderProgress | 24 | val shaderProgress: StateFlow<Int> get() = _shaderProgress |
| 19 | private val _shaderProgress = MutableStateFlow(0) | 25 | private val _shaderProgress = MutableStateFlow(0) |
| 20 | 26 | ||
| @@ -35,6 +41,17 @@ class EmulationViewModel : ViewModel() { | |||
| 35 | _isEmulationStopping.value = value | 41 | _isEmulationStopping.value = value |
| 36 | } | 42 | } |
| 37 | 43 | ||
| 44 | fun setEmulationStopped(value: Boolean) { | ||
| 45 | if (value) { | ||
| 46 | _emulationStarted.value = false | ||
| 47 | } | ||
| 48 | _emulationStopped.value = value | ||
| 49 | } | ||
| 50 | |||
| 51 | fun setProgramChanged(programIndex: Int) { | ||
| 52 | _programChanged.value = programIndex | ||
| 53 | } | ||
| 54 | |||
| 38 | fun setShaderProgress(progress: Int) { | 55 | fun setShaderProgress(progress: Int) { |
| 39 | _shaderProgress.value = progress | 56 | _shaderProgress.value = progress |
| 40 | } | 57 | } |
| @@ -56,20 +73,4 @@ class EmulationViewModel : ViewModel() { | |||
| 56 | fun setDrawerOpen(value: Boolean) { | 73 | fun setDrawerOpen(value: Boolean) { |
| 57 | _drawerOpen.value = value | 74 | _drawerOpen.value = value |
| 58 | } | 75 | } |
| 59 | |||
| 60 | fun clear() { | ||
| 61 | setEmulationStarted(false) | ||
| 62 | setIsEmulationStopping(false) | ||
| 63 | setShaderProgress(0) | ||
| 64 | setTotalShaders(0) | ||
| 65 | setShaderMessage("") | ||
| 66 | } | ||
| 67 | |||
| 68 | companion object { | ||
| 69 | const val KEY_EMULATION_STARTED = "EmulationStarted" | ||
| 70 | const val KEY_IS_EMULATION_STOPPING = "IsEmulationStarting" | ||
| 71 | const val KEY_SHADER_PROGRESS = "ShaderProgress" | ||
| 72 | const val KEY_TOTAL_SHADERS = "TotalShaders" | ||
| 73 | const val KEY_SHADER_MESSAGE = "ShaderMessage" | ||
| 74 | } | ||
| 75 | } | 76 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt index 81212cbee..a72dea8f1 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt | |||
| @@ -3,8 +3,10 @@ | |||
| 3 | 3 | ||
| 4 | package org.yuzu.yuzu_emu.utils | 4 | package org.yuzu.yuzu_emu.utils |
| 5 | 5 | ||
| 6 | import android.graphics.SurfaceTexture | ||
| 6 | import android.net.Uri | 7 | import android.net.Uri |
| 7 | import android.os.Build | 8 | import android.os.Build |
| 9 | import android.view.Surface | ||
| 8 | import java.io.File | 10 | import java.io.File |
| 9 | import java.io.IOException | 11 | import java.io.IOException |
| 10 | import org.yuzu.yuzu_emu.NativeLibrary | 12 | import org.yuzu.yuzu_emu.NativeLibrary |
| @@ -195,6 +197,11 @@ object GpuDriverHelper { | |||
| 195 | 197 | ||
| 196 | external fun supportsCustomDriverLoading(): Boolean | 198 | external fun supportsCustomDriverLoading(): Boolean |
| 197 | 199 | ||
| 200 | external fun getSystemDriverInfo( | ||
| 201 | surface: Surface = Surface(SurfaceTexture(true)), | ||
| 202 | hookLibPath: String = GpuDriverHelper.hookLibPath!! | ||
| 203 | ): Array<String>? | ||
| 204 | |||
| 198 | // Parse the custom driver metadata to retrieve the name. | 205 | // Parse the custom driver metadata to retrieve the name. |
| 199 | val installedCustomDriverData: GpuDriverMetadata | 206 | val installedCustomDriverData: GpuDriverMetadata |
| 200 | get() = GpuDriverMetadata(File(driverInstallationPath + META_JSON_FILENAME)) | 207 | get() = GpuDriverMetadata(File(driverInstallationPath + META_JSON_FILENAME)) |
diff --git a/src/android/app/src/main/jni/CMakeLists.txt b/src/android/app/src/main/jni/CMakeLists.txt index 2acc93da8..abc6055ab 100644 --- a/src/android/app/src/main/jni/CMakeLists.txt +++ b/src/android/app/src/main/jni/CMakeLists.txt | |||
| @@ -22,7 +22,7 @@ add_library(yuzu-android SHARED | |||
| 22 | 22 | ||
| 23 | set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR}) | 23 | set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR}) |
| 24 | 24 | ||
| 25 | target_link_libraries(yuzu-android PRIVATE audio_core common core input_common frontend_common) | 25 | target_link_libraries(yuzu-android PRIVATE audio_core common core input_common frontend_common Vulkan::Headers) |
| 26 | target_link_libraries(yuzu-android PRIVATE android camera2ndk EGL glad jnigraphics log) | 26 | target_link_libraries(yuzu-android PRIVATE android camera2ndk EGL glad jnigraphics log) |
| 27 | if (ARCHITECTURE_arm64) | 27 | if (ARCHITECTURE_arm64) |
| 28 | target_link_libraries(yuzu-android PRIVATE adrenotools) | 28 | target_link_libraries(yuzu-android PRIVATE adrenotools) |
diff --git a/src/android/app/src/main/jni/id_cache.cpp b/src/android/app/src/main/jni/id_cache.cpp index 96f2ad3d4..f30100bd8 100644 --- a/src/android/app/src/main/jni/id_cache.cpp +++ b/src/android/app/src/main/jni/id_cache.cpp | |||
| @@ -19,6 +19,7 @@ static jmethodID s_exit_emulation_activity; | |||
| 19 | static jmethodID s_disk_cache_load_progress; | 19 | static jmethodID s_disk_cache_load_progress; |
| 20 | static jmethodID s_on_emulation_started; | 20 | static jmethodID s_on_emulation_started; |
| 21 | static jmethodID s_on_emulation_stopped; | 21 | static jmethodID s_on_emulation_stopped; |
| 22 | static jmethodID s_on_program_changed; | ||
| 22 | 23 | ||
| 23 | static jclass s_game_class; | 24 | static jclass s_game_class; |
| 24 | static jmethodID s_game_constructor; | 25 | static jmethodID s_game_constructor; |
| @@ -123,6 +124,10 @@ jmethodID GetOnEmulationStopped() { | |||
| 123 | return s_on_emulation_stopped; | 124 | return s_on_emulation_stopped; |
| 124 | } | 125 | } |
| 125 | 126 | ||
| 127 | jmethodID GetOnProgramChanged() { | ||
| 128 | return s_on_program_changed; | ||
| 129 | } | ||
| 130 | |||
| 126 | jclass GetGameClass() { | 131 | jclass GetGameClass() { |
| 127 | return s_game_class; | 132 | return s_game_class; |
| 128 | } | 133 | } |
| @@ -306,6 +311,8 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) { | |||
| 306 | env->GetStaticMethodID(s_native_library_class, "onEmulationStarted", "()V"); | 311 | env->GetStaticMethodID(s_native_library_class, "onEmulationStarted", "()V"); |
| 307 | s_on_emulation_stopped = | 312 | s_on_emulation_stopped = |
| 308 | env->GetStaticMethodID(s_native_library_class, "onEmulationStopped", "(I)V"); | 313 | env->GetStaticMethodID(s_native_library_class, "onEmulationStopped", "(I)V"); |
| 314 | s_on_program_changed = | ||
| 315 | env->GetStaticMethodID(s_native_library_class, "onProgramChanged", "(I)V"); | ||
| 309 | 316 | ||
| 310 | const jclass game_class = env->FindClass("org/yuzu/yuzu_emu/model/Game"); | 317 | const jclass game_class = env->FindClass("org/yuzu/yuzu_emu/model/Game"); |
| 311 | s_game_class = reinterpret_cast<jclass>(env->NewGlobalRef(game_class)); | 318 | s_game_class = reinterpret_cast<jclass>(env->NewGlobalRef(game_class)); |
diff --git a/src/android/app/src/main/jni/id_cache.h b/src/android/app/src/main/jni/id_cache.h index a002e705d..00e48afc0 100644 --- a/src/android/app/src/main/jni/id_cache.h +++ b/src/android/app/src/main/jni/id_cache.h | |||
| @@ -19,6 +19,7 @@ jmethodID GetExitEmulationActivity(); | |||
| 19 | jmethodID GetDiskCacheLoadProgress(); | 19 | jmethodID GetDiskCacheLoadProgress(); |
| 20 | jmethodID GetOnEmulationStarted(); | 20 | jmethodID GetOnEmulationStarted(); |
| 21 | jmethodID GetOnEmulationStopped(); | 21 | jmethodID GetOnEmulationStopped(); |
| 22 | jmethodID GetOnProgramChanged(); | ||
| 22 | 23 | ||
| 23 | jclass GetGameClass(); | 24 | jclass GetGameClass(); |
| 24 | jmethodID GetGameConstructor(); | 25 | jmethodID GetGameConstructor(); |
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 3fd9a500c..64627db88 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp | |||
| @@ -60,6 +60,9 @@ | |||
| 60 | #include "jni/id_cache.h" | 60 | #include "jni/id_cache.h" |
| 61 | #include "jni/native.h" | 61 | #include "jni/native.h" |
| 62 | #include "video_core/renderer_base.h" | 62 | #include "video_core/renderer_base.h" |
| 63 | #include "video_core/renderer_vulkan/renderer_vulkan.h" | ||
| 64 | #include "video_core/vulkan_common/vulkan_instance.h" | ||
| 65 | #include "video_core/vulkan_common/vulkan_surface.h" | ||
| 63 | 66 | ||
| 64 | #define jconst [[maybe_unused]] const auto | 67 | #define jconst [[maybe_unused]] const auto |
| 65 | #define jauto [[maybe_unused]] auto | 68 | #define jauto [[maybe_unused]] auto |
| @@ -208,7 +211,8 @@ void EmulationSession::InitializeSystem(bool reload) { | |||
| 208 | m_system.GetFileSystemController().CreateFactories(*m_vfs); | 211 | m_system.GetFileSystemController().CreateFactories(*m_vfs); |
| 209 | } | 212 | } |
| 210 | 213 | ||
| 211 | Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string& filepath) { | 214 | Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string& filepath, |
| 215 | const std::size_t program_index) { | ||
| 212 | std::scoped_lock lock(m_mutex); | 216 | std::scoped_lock lock(m_mutex); |
| 213 | 217 | ||
| 214 | // Create the render window. | 218 | // Create the render window. |
| @@ -238,7 +242,8 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string | |||
| 238 | ConfigureFilesystemProvider(filepath); | 242 | ConfigureFilesystemProvider(filepath); |
| 239 | 243 | ||
| 240 | // Load the ROM. | 244 | // Load the ROM. |
| 241 | m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filepath); | 245 | m_load_result = |
| 246 | m_system.Load(EmulationSession::GetInstance().Window(), filepath, 0, program_index); | ||
| 242 | if (m_load_result != Core::SystemResultStatus::Success) { | 247 | if (m_load_result != Core::SystemResultStatus::Success) { |
| 243 | return m_load_result; | 248 | return m_load_result; |
| 244 | } | 249 | } |
| @@ -248,6 +253,12 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string | |||
| 248 | m_system.GetCpuManager().OnGpuReady(); | 253 | m_system.GetCpuManager().OnGpuReady(); |
| 249 | m_system.RegisterExitCallback([&] { HaltEmulation(); }); | 254 | m_system.RegisterExitCallback([&] { HaltEmulation(); }); |
| 250 | 255 | ||
| 256 | // Register an ExecuteProgram callback such that Core can execute a sub-program | ||
| 257 | m_system.RegisterExecuteProgramCallback([&](std::size_t program_index_) { | ||
| 258 | m_next_program_index = program_index_; | ||
| 259 | EmulationSession::GetInstance().HaltEmulation(); | ||
| 260 | }); | ||
| 261 | |||
| 251 | OnEmulationStarted(); | 262 | OnEmulationStarted(); |
| 252 | return Core::SystemResultStatus::Success; | 263 | return Core::SystemResultStatus::Success; |
| 253 | } | 264 | } |
| @@ -255,6 +266,11 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string | |||
| 255 | void EmulationSession::ShutdownEmulation() { | 266 | void EmulationSession::ShutdownEmulation() { |
| 256 | std::scoped_lock lock(m_mutex); | 267 | std::scoped_lock lock(m_mutex); |
| 257 | 268 | ||
| 269 | if (m_next_program_index != -1) { | ||
| 270 | ChangeProgram(m_next_program_index); | ||
| 271 | m_next_program_index = -1; | ||
| 272 | } | ||
| 273 | |||
| 258 | m_is_running = false; | 274 | m_is_running = false; |
| 259 | 275 | ||
| 260 | // Unload user input. | 276 | // Unload user input. |
| @@ -402,6 +418,12 @@ void EmulationSession::OnEmulationStopped(Core::SystemResultStatus result) { | |||
| 402 | static_cast<jint>(result)); | 418 | static_cast<jint>(result)); |
| 403 | } | 419 | } |
| 404 | 420 | ||
| 421 | void EmulationSession::ChangeProgram(std::size_t program_index) { | ||
| 422 | JNIEnv* env = IDCache::GetEnvForThread(); | ||
| 423 | env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetOnProgramChanged(), | ||
| 424 | static_cast<jint>(program_index)); | ||
| 425 | } | ||
| 426 | |||
| 405 | u64 EmulationSession::GetProgramId(JNIEnv* env, jstring jprogramId) { | 427 | u64 EmulationSession::GetProgramId(JNIEnv* env, jstring jprogramId) { |
| 406 | auto program_id_string = GetJString(env, jprogramId); | 428 | auto program_id_string = GetJString(env, jprogramId); |
| 407 | try { | 429 | try { |
| @@ -411,7 +433,8 @@ u64 EmulationSession::GetProgramId(JNIEnv* env, jstring jprogramId) { | |||
| 411 | } | 433 | } |
| 412 | } | 434 | } |
| 413 | 435 | ||
| 414 | static Core::SystemResultStatus RunEmulation(const std::string& filepath) { | 436 | static Core::SystemResultStatus RunEmulation(const std::string& filepath, |
| 437 | const size_t program_index = 0) { | ||
| 415 | MicroProfileOnThreadCreate("EmuThread"); | 438 | MicroProfileOnThreadCreate("EmuThread"); |
| 416 | SCOPE_EXIT({ MicroProfileShutdown(); }); | 439 | SCOPE_EXIT({ MicroProfileShutdown(); }); |
| 417 | 440 | ||
| @@ -424,7 +447,7 @@ static Core::SystemResultStatus RunEmulation(const std::string& filepath) { | |||
| 424 | 447 | ||
| 425 | SCOPE_EXIT({ EmulationSession::GetInstance().ShutdownEmulation(); }); | 448 | SCOPE_EXIT({ EmulationSession::GetInstance().ShutdownEmulation(); }); |
| 426 | 449 | ||
| 427 | jconst result = EmulationSession::GetInstance().InitializeEmulation(filepath); | 450 | jconst result = EmulationSession::GetInstance().InitializeEmulation(filepath, program_index); |
| 428 | if (result != Core::SystemResultStatus::Success) { | 451 | if (result != Core::SystemResultStatus::Success) { |
| 429 | return result; | 452 | return result; |
| 430 | } | 453 | } |
| @@ -521,6 +544,37 @@ jboolean JNICALL Java_org_yuzu_yuzu_1emu_utils_GpuDriverHelper_supportsCustomDri | |||
| 521 | #endif | 544 | #endif |
| 522 | } | 545 | } |
| 523 | 546 | ||
| 547 | jobjectArray Java_org_yuzu_yuzu_1emu_utils_GpuDriverHelper_getSystemDriverInfo( | ||
| 548 | JNIEnv* env, jobject j_obj, jobject j_surf, jstring j_hook_lib_dir) { | ||
| 549 | const char* file_redirect_dir_{}; | ||
| 550 | int featureFlags{}; | ||
| 551 | std::string hook_lib_dir = GetJString(env, j_hook_lib_dir); | ||
| 552 | auto handle = adrenotools_open_libvulkan(RTLD_NOW, featureFlags, nullptr, hook_lib_dir.c_str(), | ||
| 553 | nullptr, nullptr, file_redirect_dir_, nullptr); | ||
| 554 | auto driver_library = std::make_shared<Common::DynamicLibrary>(handle); | ||
| 555 | InputCommon::InputSubsystem input_subsystem; | ||
| 556 | auto m_window = std::make_unique<EmuWindow_Android>( | ||
| 557 | &input_subsystem, ANativeWindow_fromSurface(env, j_surf), driver_library); | ||
| 558 | |||
| 559 | Vulkan::vk::InstanceDispatch dld; | ||
| 560 | Vulkan::vk::Instance vk_instance = Vulkan::CreateInstance( | ||
| 561 | *driver_library, dld, VK_API_VERSION_1_1, Core::Frontend::WindowSystemType::Android); | ||
| 562 | |||
| 563 | auto surface = Vulkan::CreateSurface(vk_instance, m_window->GetWindowInfo()); | ||
| 564 | |||
| 565 | auto device = Vulkan::CreateDevice(vk_instance, dld, *surface); | ||
| 566 | |||
| 567 | auto driver_version = device.GetDriverVersion(); | ||
| 568 | auto version_string = | ||
| 569 | fmt::format("{}.{}.{}", VK_API_VERSION_MAJOR(driver_version), | ||
| 570 | VK_API_VERSION_MINOR(driver_version), VK_API_VERSION_PATCH(driver_version)); | ||
| 571 | |||
| 572 | jobjectArray j_driver_info = | ||
| 573 | env->NewObjectArray(2, IDCache::GetStringClass(), ToJString(env, version_string)); | ||
| 574 | env->SetObjectArrayElement(j_driver_info, 1, ToJString(env, device.GetDriverName())); | ||
| 575 | return j_driver_info; | ||
| 576 | } | ||
| 577 | |||
| 524 | jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_reloadKeys(JNIEnv* env, jclass clazz) { | 578 | jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_reloadKeys(JNIEnv* env, jclass clazz) { |
| 525 | Core::Crypto::KeyManager::Instance().ReloadKeys(); | 579 | Core::Crypto::KeyManager::Instance().ReloadKeys(); |
| 526 | return static_cast<jboolean>(Core::Crypto::KeyManager::Instance().AreKeysLoaded()); | 580 | return static_cast<jboolean>(Core::Crypto::KeyManager::Instance().AreKeysLoaded()); |
| @@ -689,11 +743,11 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_logSettings(JNIEnv* env, jobject jobj | |||
| 689 | Settings::LogSettings(); | 743 | Settings::LogSettings(); |
| 690 | } | 744 | } |
| 691 | 745 | ||
| 692 | void Java_org_yuzu_yuzu_1emu_NativeLibrary_run__Ljava_lang_String_2(JNIEnv* env, jclass clazz, | 746 | void Java_org_yuzu_yuzu_1emu_NativeLibrary_run(JNIEnv* env, jobject jobj, jstring j_path, |
| 693 | jstring j_path) { | 747 | jint j_program_index) { |
| 694 | const std::string path = GetJString(env, j_path); | 748 | const std::string path = GetJString(env, j_path); |
| 695 | 749 | ||
| 696 | const Core::SystemResultStatus result{RunEmulation(path)}; | 750 | const Core::SystemResultStatus result{RunEmulation(path, j_program_index)}; |
| 697 | if (result != Core::SystemResultStatus::Success) { | 751 | if (result != Core::SystemResultStatus::Success) { |
| 698 | env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), | 752 | env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), |
| 699 | IDCache::GetExitEmulationActivity(), static_cast<int>(result)); | 753 | IDCache::GetExitEmulationActivity(), static_cast<int>(result)); |
diff --git a/src/android/app/src/main/jni/native.h b/src/android/app/src/main/jni/native.h index dadb138ad..bfe3fccca 100644 --- a/src/android/app/src/main/jni/native.h +++ b/src/android/app/src/main/jni/native.h | |||
| @@ -45,7 +45,8 @@ public: | |||
| 45 | const Core::PerfStatsResults& PerfStats(); | 45 | const Core::PerfStatsResults& PerfStats(); |
| 46 | void ConfigureFilesystemProvider(const std::string& filepath); | 46 | void ConfigureFilesystemProvider(const std::string& filepath); |
| 47 | void InitializeSystem(bool reload); | 47 | void InitializeSystem(bool reload); |
| 48 | Core::SystemResultStatus InitializeEmulation(const std::string& filepath); | 48 | Core::SystemResultStatus InitializeEmulation(const std::string& filepath, |
| 49 | const std::size_t program_index = 0); | ||
| 49 | 50 | ||
| 50 | bool IsHandheldOnly(); | 51 | bool IsHandheldOnly(); |
| 51 | void SetDeviceType([[maybe_unused]] int index, int type); | 52 | void SetDeviceType([[maybe_unused]] int index, int type); |
| @@ -60,6 +61,7 @@ public: | |||
| 60 | private: | 61 | private: |
| 61 | static void LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress, int max); | 62 | static void LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress, int max); |
| 62 | static void OnEmulationStopped(Core::SystemResultStatus result); | 63 | static void OnEmulationStopped(Core::SystemResultStatus result); |
| 64 | static void ChangeProgram(std::size_t program_index); | ||
| 63 | 65 | ||
| 64 | private: | 66 | private: |
| 65 | // Window management | 67 | // Window management |
| @@ -84,4 +86,7 @@ private: | |||
| 84 | // Synchronization | 86 | // Synchronization |
| 85 | std::condition_variable_any m_cv; | 87 | std::condition_variable_any m_cv; |
| 86 | mutable std::mutex m_mutex; | 88 | mutable std::mutex m_mutex; |
| 89 | |||
| 90 | // Program index for next boot | ||
| 91 | std::atomic<s32> m_next_program_index = -1; | ||
| 87 | }; | 92 | }; |
diff --git a/src/android/app/src/main/res/layout/fragment_emulation.xml b/src/android/app/src/main/res/layout/fragment_emulation.xml index c01117d14..0d2bfe8d6 100644 --- a/src/android/app/src/main/res/layout/fragment_emulation.xml +++ b/src/android/app/src/main/res/layout/fragment_emulation.xml | |||
| @@ -34,8 +34,10 @@ | |||
| 34 | android:layout_width="wrap_content" | 34 | android:layout_width="wrap_content" |
| 35 | android:layout_height="wrap_content" | 35 | android:layout_height="wrap_content" |
| 36 | android:layout_gravity="center" | 36 | android:layout_gravity="center" |
| 37 | android:focusable="false" | ||
| 37 | android:defaultFocusHighlightEnabled="false" | 38 | android:defaultFocusHighlightEnabled="false" |
| 38 | android:clickable="false"> | 39 | android:clickable="false" |
| 40 | app:rippleColor="@android:color/transparent"> | ||
| 39 | 41 | ||
| 40 | <androidx.constraintlayout.widget.ConstraintLayout | 42 | <androidx.constraintlayout.widget.ConstraintLayout |
| 41 | android:id="@+id/loading_layout" | 43 | android:id="@+id/loading_layout" |
diff --git a/src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp b/src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp index ef301d8b4..7a76c3d0b 100644 --- a/src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp +++ b/src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp | |||
| @@ -89,11 +89,13 @@ u32 AudioRenderer::Receive(Direction dir) { | |||
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | void AudioRenderer::SetCommandBuffer(s32 session_id, CpuAddr buffer, u64 size, u64 time_limit, | 91 | void AudioRenderer::SetCommandBuffer(s32 session_id, CpuAddr buffer, u64 size, u64 time_limit, |
| 92 | u64 applet_resource_user_id, bool reset) noexcept { | 92 | u64 applet_resource_user_id, Kernel::KProcess* process, |
| 93 | bool reset) noexcept { | ||
| 93 | command_buffers[session_id].buffer = buffer; | 94 | command_buffers[session_id].buffer = buffer; |
| 94 | command_buffers[session_id].size = size; | 95 | command_buffers[session_id].size = size; |
| 95 | command_buffers[session_id].time_limit = time_limit; | 96 | command_buffers[session_id].time_limit = time_limit; |
| 96 | command_buffers[session_id].applet_resource_user_id = applet_resource_user_id; | 97 | command_buffers[session_id].applet_resource_user_id = applet_resource_user_id; |
| 98 | command_buffers[session_id].process = process; | ||
| 97 | command_buffers[session_id].reset_buffer = reset; | 99 | command_buffers[session_id].reset_buffer = reset; |
| 98 | } | 100 | } |
| 99 | 101 | ||
| @@ -173,7 +175,8 @@ void AudioRenderer::Main(std::stop_token stop_token) { | |||
| 173 | // If there are no remaining commands (from the previous list), | 175 | // If there are no remaining commands (from the previous list), |
| 174 | // this is a new command list, initialize it. | 176 | // this is a new command list, initialize it. |
| 175 | if (command_buffer.remaining_command_count == 0) { | 177 | if (command_buffer.remaining_command_count == 0) { |
| 176 | command_list_processor.Initialize(system, command_buffer.buffer, | 178 | command_list_processor.Initialize(system, *command_buffer.process, |
| 179 | command_buffer.buffer, | ||
| 177 | command_buffer.size, streams[index]); | 180 | command_buffer.size, streams[index]); |
| 178 | } | 181 | } |
| 179 | 182 | ||
diff --git a/src/audio_core/adsp/apps/audio_renderer/audio_renderer.h b/src/audio_core/adsp/apps/audio_renderer/audio_renderer.h index 57b89d9fe..875266f27 100644 --- a/src/audio_core/adsp/apps/audio_renderer/audio_renderer.h +++ b/src/audio_core/adsp/apps/audio_renderer/audio_renderer.h | |||
| @@ -19,6 +19,10 @@ namespace Core { | |||
| 19 | class System; | 19 | class System; |
| 20 | } // namespace Core | 20 | } // namespace Core |
| 21 | 21 | ||
| 22 | namespace Kernel { | ||
| 23 | class KProcess; | ||
| 24 | } | ||
| 25 | |||
| 22 | namespace AudioCore { | 26 | namespace AudioCore { |
| 23 | namespace Sink { | 27 | namespace Sink { |
| 24 | class Sink; | 28 | class Sink; |
| @@ -69,7 +73,8 @@ public: | |||
| 69 | u32 Receive(Direction dir); | 73 | u32 Receive(Direction dir); |
| 70 | 74 | ||
| 71 | void SetCommandBuffer(s32 session_id, CpuAddr buffer, u64 size, u64 time_limit, | 75 | void SetCommandBuffer(s32 session_id, CpuAddr buffer, u64 size, u64 time_limit, |
| 72 | u64 applet_resource_user_id, bool reset) noexcept; | 76 | u64 applet_resource_user_id, Kernel::KProcess* process, |
| 77 | bool reset) noexcept; | ||
| 73 | u32 GetRemainCommandCount(s32 session_id) const noexcept; | 78 | u32 GetRemainCommandCount(s32 session_id) const noexcept; |
| 74 | void ClearRemainCommandCount(s32 session_id) noexcept; | 79 | void ClearRemainCommandCount(s32 session_id) noexcept; |
| 75 | u64 GetRenderingStartTick(s32 session_id) const noexcept; | 80 | u64 GetRenderingStartTick(s32 session_id) const noexcept; |
diff --git a/src/audio_core/adsp/apps/audio_renderer/command_buffer.h b/src/audio_core/adsp/apps/audio_renderer/command_buffer.h index 3fd1b09dc..d6a721f34 100644 --- a/src/audio_core/adsp/apps/audio_renderer/command_buffer.h +++ b/src/audio_core/adsp/apps/audio_renderer/command_buffer.h | |||
| @@ -6,6 +6,10 @@ | |||
| 6 | #include "audio_core/common/common.h" | 6 | #include "audio_core/common/common.h" |
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | 8 | ||
| 9 | namespace Kernel { | ||
| 10 | class KProcess; | ||
| 11 | } | ||
| 12 | |||
| 9 | namespace AudioCore::ADSP::AudioRenderer { | 13 | namespace AudioCore::ADSP::AudioRenderer { |
| 10 | 14 | ||
| 11 | struct CommandBuffer { | 15 | struct CommandBuffer { |
| @@ -14,6 +18,7 @@ struct CommandBuffer { | |||
| 14 | u64 size{}; | 18 | u64 size{}; |
| 15 | u64 time_limit{}; | 19 | u64 time_limit{}; |
| 16 | u64 applet_resource_user_id{}; | 20 | u64 applet_resource_user_id{}; |
| 21 | Kernel::KProcess* process{}; | ||
| 17 | bool reset_buffer{}; | 22 | bool reset_buffer{}; |
| 18 | // Set by the DSP | 23 | // Set by the DSP |
| 19 | u32 remaining_command_count{}; | 24 | u32 remaining_command_count{}; |
diff --git a/src/audio_core/adsp/apps/audio_renderer/command_list_processor.cpp b/src/audio_core/adsp/apps/audio_renderer/command_list_processor.cpp index 24e4d0496..eef2c0b89 100644 --- a/src/audio_core/adsp/apps/audio_renderer/command_list_processor.cpp +++ b/src/audio_core/adsp/apps/audio_renderer/command_list_processor.cpp | |||
| @@ -9,14 +9,15 @@ | |||
| 9 | #include "common/settings.h" | 9 | #include "common/settings.h" |
| 10 | #include "core/core.h" | 10 | #include "core/core.h" |
| 11 | #include "core/core_timing.h" | 11 | #include "core/core_timing.h" |
| 12 | #include "core/hle/kernel/k_process.h" | ||
| 12 | #include "core/memory.h" | 13 | #include "core/memory.h" |
| 13 | 14 | ||
| 14 | namespace AudioCore::ADSP::AudioRenderer { | 15 | namespace AudioCore::ADSP::AudioRenderer { |
| 15 | 16 | ||
| 16 | void CommandListProcessor::Initialize(Core::System& system_, CpuAddr buffer, u64 size, | 17 | void CommandListProcessor::Initialize(Core::System& system_, Kernel::KProcess& process, |
| 17 | Sink::SinkStream* stream_) { | 18 | CpuAddr buffer, u64 size, Sink::SinkStream* stream_) { |
| 18 | system = &system_; | 19 | system = &system_; |
| 19 | memory = &system->ApplicationMemory(); | 20 | memory = &process.GetMemory(); |
| 20 | stream = stream_; | 21 | stream = stream_; |
| 21 | header = reinterpret_cast<Renderer::CommandListHeader*>(buffer); | 22 | header = reinterpret_cast<Renderer::CommandListHeader*>(buffer); |
| 22 | commands = reinterpret_cast<u8*>(buffer + sizeof(Renderer::CommandListHeader)); | 23 | commands = reinterpret_cast<u8*>(buffer + sizeof(Renderer::CommandListHeader)); |
diff --git a/src/audio_core/adsp/apps/audio_renderer/command_list_processor.h b/src/audio_core/adsp/apps/audio_renderer/command_list_processor.h index 4e5fb793e..944e82505 100644 --- a/src/audio_core/adsp/apps/audio_renderer/command_list_processor.h +++ b/src/audio_core/adsp/apps/audio_renderer/command_list_processor.h | |||
| @@ -16,6 +16,10 @@ class Memory; | |||
| 16 | class System; | 16 | class System; |
| 17 | } // namespace Core | 17 | } // namespace Core |
| 18 | 18 | ||
| 19 | namespace Kernel { | ||
| 20 | class KProcess; | ||
| 21 | } | ||
| 22 | |||
| 19 | namespace AudioCore { | 23 | namespace AudioCore { |
| 20 | namespace Sink { | 24 | namespace Sink { |
| 21 | class SinkStream; | 25 | class SinkStream; |
| @@ -40,7 +44,8 @@ public: | |||
| 40 | * @param size - The size of the buffer. | 44 | * @param size - The size of the buffer. |
| 41 | * @param stream - The stream to be used for sending the samples. | 45 | * @param stream - The stream to be used for sending the samples. |
| 42 | */ | 46 | */ |
| 43 | void Initialize(Core::System& system, CpuAddr buffer, u64 size, Sink::SinkStream* stream); | 47 | void Initialize(Core::System& system, Kernel::KProcess& process, CpuAddr buffer, u64 size, |
| 48 | Sink::SinkStream* stream); | ||
| 44 | 49 | ||
| 45 | /** | 50 | /** |
| 46 | * Set the maximum processing time for this command list. | 51 | * Set the maximum processing time for this command list. |
diff --git a/src/audio_core/renderer/audio_renderer.cpp b/src/audio_core/renderer/audio_renderer.cpp index 09efe9be9..df03d03aa 100644 --- a/src/audio_core/renderer/audio_renderer.cpp +++ b/src/audio_core/renderer/audio_renderer.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include "audio_core/renderer/audio_renderer.h" | 6 | #include "audio_core/renderer/audio_renderer.h" |
| 7 | #include "audio_core/renderer/system_manager.h" | 7 | #include "audio_core/renderer/system_manager.h" |
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/hle/kernel/k_process.h" | ||
| 9 | #include "core/hle/kernel/k_transfer_memory.h" | 10 | #include "core/hle/kernel/k_transfer_memory.h" |
| 10 | #include "core/hle/service/audio/errors.h" | 11 | #include "core/hle/service/audio/errors.h" |
| 11 | 12 | ||
| @@ -17,7 +18,8 @@ Renderer::Renderer(Core::System& system_, Manager& manager_, Kernel::KEvent* ren | |||
| 17 | Result Renderer::Initialize(const AudioRendererParameterInternal& params, | 18 | Result Renderer::Initialize(const AudioRendererParameterInternal& params, |
| 18 | Kernel::KTransferMemory* transfer_memory, | 19 | Kernel::KTransferMemory* transfer_memory, |
| 19 | const u64 transfer_memory_size, const u32 process_handle, | 20 | const u64 transfer_memory_size, const u32 process_handle, |
| 20 | const u64 applet_resource_user_id, const s32 session_id) { | 21 | Kernel::KProcess& process, const u64 applet_resource_user_id, |
| 22 | const s32 session_id) { | ||
| 21 | if (params.execution_mode == ExecutionMode::Auto) { | 23 | if (params.execution_mode == ExecutionMode::Auto) { |
| 22 | if (!manager.AddSystem(system)) { | 24 | if (!manager.AddSystem(system)) { |
| 23 | LOG_ERROR(Service_Audio, | 25 | LOG_ERROR(Service_Audio, |
| @@ -28,7 +30,7 @@ Result Renderer::Initialize(const AudioRendererParameterInternal& params, | |||
| 28 | } | 30 | } |
| 29 | 31 | ||
| 30 | initialized = true; | 32 | initialized = true; |
| 31 | system.Initialize(params, transfer_memory, transfer_memory_size, process_handle, | 33 | system.Initialize(params, transfer_memory, transfer_memory_size, process_handle, process, |
| 32 | applet_resource_user_id, session_id); | 34 | applet_resource_user_id, session_id); |
| 33 | 35 | ||
| 34 | return ResultSuccess; | 36 | return ResultSuccess; |
diff --git a/src/audio_core/renderer/audio_renderer.h b/src/audio_core/renderer/audio_renderer.h index 24650278b..1219f74ca 100644 --- a/src/audio_core/renderer/audio_renderer.h +++ b/src/audio_core/renderer/audio_renderer.h | |||
| @@ -14,7 +14,8 @@ class System; | |||
| 14 | 14 | ||
| 15 | namespace Kernel { | 15 | namespace Kernel { |
| 16 | class KTransferMemory; | 16 | class KTransferMemory; |
| 17 | } | 17 | class KProcess; |
| 18 | } // namespace Kernel | ||
| 18 | 19 | ||
| 19 | namespace AudioCore { | 20 | namespace AudioCore { |
| 20 | struct AudioRendererParameterInternal; | 21 | struct AudioRendererParameterInternal; |
| @@ -44,7 +45,8 @@ public: | |||
| 44 | */ | 45 | */ |
| 45 | Result Initialize(const AudioRendererParameterInternal& params, | 46 | Result Initialize(const AudioRendererParameterInternal& params, |
| 46 | Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, | 47 | Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, |
| 47 | u32 process_handle, u64 applet_resource_user_id, s32 session_id); | 48 | u32 process_handle, Kernel::KProcess& process, u64 applet_resource_user_id, |
| 49 | s32 session_id); | ||
| 48 | 50 | ||
| 49 | /** | 51 | /** |
| 50 | * Finalize the renderer for shutdown. | 52 | * Finalize the renderer for shutdown. |
diff --git a/src/audio_core/renderer/system.cpp b/src/audio_core/renderer/system.cpp index 31f92087c..ca656edae 100644 --- a/src/audio_core/renderer/system.cpp +++ b/src/audio_core/renderer/system.cpp | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include "core/core.h" | 32 | #include "core/core.h" |
| 33 | #include "core/core_timing.h" | 33 | #include "core/core_timing.h" |
| 34 | #include "core/hle/kernel/k_event.h" | 34 | #include "core/hle/kernel/k_event.h" |
| 35 | #include "core/hle/kernel/k_process.h" | ||
| 35 | #include "core/hle/kernel/k_transfer_memory.h" | 36 | #include "core/hle/kernel/k_transfer_memory.h" |
| 36 | #include "core/memory.h" | 37 | #include "core/memory.h" |
| 37 | 38 | ||
| @@ -101,7 +102,8 @@ System::System(Core::System& core_, Kernel::KEvent* adsp_rendered_event_) | |||
| 101 | 102 | ||
| 102 | Result System::Initialize(const AudioRendererParameterInternal& params, | 103 | Result System::Initialize(const AudioRendererParameterInternal& params, |
| 103 | Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, | 104 | Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, |
| 104 | u32 process_handle_, u64 applet_resource_user_id_, s32 session_id_) { | 105 | u32 process_handle_, Kernel::KProcess& process_, |
| 106 | u64 applet_resource_user_id_, s32 session_id_) { | ||
| 105 | if (!CheckValidRevision(params.revision)) { | 107 | if (!CheckValidRevision(params.revision)) { |
| 106 | return Service::Audio::ResultInvalidRevision; | 108 | return Service::Audio::ResultInvalidRevision; |
| 107 | } | 109 | } |
| @@ -117,6 +119,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 117 | behavior.SetUserLibRevision(params.revision); | 119 | behavior.SetUserLibRevision(params.revision); |
| 118 | 120 | ||
| 119 | process_handle = process_handle_; | 121 | process_handle = process_handle_; |
| 122 | process = &process_; | ||
| 120 | applet_resource_user_id = applet_resource_user_id_; | 123 | applet_resource_user_id = applet_resource_user_id_; |
| 121 | session_id = session_id_; | 124 | session_id = session_id_; |
| 122 | 125 | ||
| @@ -129,7 +132,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params, | |||
| 129 | render_device = params.rendering_device; | 132 | render_device = params.rendering_device; |
| 130 | execution_mode = params.execution_mode; | 133 | execution_mode = params.execution_mode; |
| 131 | 134 | ||
| 132 | core.ApplicationMemory().ZeroBlock(transfer_memory->GetSourceAddress(), transfer_memory_size); | 135 | process->GetMemory().ZeroBlock(transfer_memory->GetSourceAddress(), transfer_memory_size); |
| 133 | 136 | ||
| 134 | // Note: We're not actually using the transfer memory because it's a pain to code for. | 137 | // Note: We're not actually using the transfer memory because it's a pain to code for. |
| 135 | // Allocate the memory normally instead and hope the game doesn't try to read anything back | 138 | // Allocate the memory normally instead and hope the game doesn't try to read anything back |
| @@ -613,7 +616,8 @@ void System::SendCommandToDsp() { | |||
| 613 | static_cast<u64>((time_limit_percent / 100) * 2'880'000.0 * | 616 | static_cast<u64>((time_limit_percent / 100) * 2'880'000.0 * |
| 614 | (static_cast<f32>(render_time_limit_percent) / 100.0f))}; | 617 | (static_cast<f32>(render_time_limit_percent) / 100.0f))}; |
| 615 | audio_renderer.SetCommandBuffer(session_id, translated_addr, command_size, time_limit, | 618 | audio_renderer.SetCommandBuffer(session_id, translated_addr, command_size, time_limit, |
| 616 | applet_resource_user_id, reset_command_buffers); | 619 | applet_resource_user_id, process, |
| 620 | reset_command_buffers); | ||
| 617 | reset_command_buffers = false; | 621 | reset_command_buffers = false; |
| 618 | command_buffer_size = command_size; | 622 | command_buffer_size = command_size; |
| 619 | if (remaining_command_count == 0) { | 623 | if (remaining_command_count == 0) { |
diff --git a/src/audio_core/renderer/system.h b/src/audio_core/renderer/system.h index 8a8341710..753a0b796 100644 --- a/src/audio_core/renderer/system.h +++ b/src/audio_core/renderer/system.h | |||
| @@ -29,6 +29,7 @@ class System; | |||
| 29 | 29 | ||
| 30 | namespace Kernel { | 30 | namespace Kernel { |
| 31 | class KEvent; | 31 | class KEvent; |
| 32 | class KProcess; | ||
| 32 | class KTransferMemory; | 33 | class KTransferMemory; |
| 33 | } // namespace Kernel | 34 | } // namespace Kernel |
| 34 | 35 | ||
| @@ -80,7 +81,8 @@ public: | |||
| 80 | */ | 81 | */ |
| 81 | Result Initialize(const AudioRendererParameterInternal& params, | 82 | Result Initialize(const AudioRendererParameterInternal& params, |
| 82 | Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, | 83 | Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, |
| 83 | u32 process_handle, u64 applet_resource_user_id, s32 session_id); | 84 | u32 process_handle, Kernel::KProcess& process, u64 applet_resource_user_id, |
| 85 | s32 session_id); | ||
| 84 | 86 | ||
| 85 | /** | 87 | /** |
| 86 | * Finalize the system. | 88 | * Finalize the system. |
| @@ -275,6 +277,8 @@ private: | |||
| 275 | Common::Event terminate_event{}; | 277 | Common::Event terminate_event{}; |
| 276 | /// Does what locks do | 278 | /// Does what locks do |
| 277 | std::mutex lock{}; | 279 | std::mutex lock{}; |
| 280 | /// Process this audio render is operating within, used for memory reads/writes. | ||
| 281 | Kernel::KProcess* process{}; | ||
| 278 | /// Handle for the process for this system, unused | 282 | /// Handle for the process for this system, unused |
| 279 | u32 process_handle{}; | 283 | u32 process_handle{}; |
| 280 | /// Applet resource id for this system, unused | 284 | /// Applet resource id for this system, unused |
diff --git a/src/common/atomic_ops.h b/src/common/atomic_ops.h index c18bb33c4..9bf6f2f81 100644 --- a/src/common/atomic_ops.h +++ b/src/common/atomic_ops.h | |||
| @@ -15,25 +15,34 @@ namespace Common { | |||
| 15 | 15 | ||
| 16 | #if _MSC_VER | 16 | #if _MSC_VER |
| 17 | 17 | ||
| 18 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected) { | 18 | template <typename T> |
| 19 | [[nodiscard]] inline bool AtomicCompareAndSwap(T* pointer, T value, T expected); | ||
| 20 | template <typename T> | ||
| 21 | [[nodiscard]] inline bool AtomicCompareAndSwap(T* pointer, T value, T expected, T& actual); | ||
| 22 | |||
| 23 | template <> | ||
| 24 | [[nodiscard]] inline bool AtomicCompareAndSwap<u8>(u8* pointer, u8 value, u8 expected) { | ||
| 19 | const u8 result = | 25 | const u8 result = |
| 20 | _InterlockedCompareExchange8(reinterpret_cast<volatile char*>(pointer), value, expected); | 26 | _InterlockedCompareExchange8(reinterpret_cast<volatile char*>(pointer), value, expected); |
| 21 | return result == expected; | 27 | return result == expected; |
| 22 | } | 28 | } |
| 23 | 29 | ||
| 24 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected) { | 30 | template <> |
| 31 | [[nodiscard]] inline bool AtomicCompareAndSwap<u16>(u16* pointer, u16 value, u16 expected) { | ||
| 25 | const u16 result = | 32 | const u16 result = |
| 26 | _InterlockedCompareExchange16(reinterpret_cast<volatile short*>(pointer), value, expected); | 33 | _InterlockedCompareExchange16(reinterpret_cast<volatile short*>(pointer), value, expected); |
| 27 | return result == expected; | 34 | return result == expected; |
| 28 | } | 35 | } |
| 29 | 36 | ||
| 30 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected) { | 37 | template <> |
| 38 | [[nodiscard]] inline bool AtomicCompareAndSwap<u32>(u32* pointer, u32 value, u32 expected) { | ||
| 31 | const u32 result = | 39 | const u32 result = |
| 32 | _InterlockedCompareExchange(reinterpret_cast<volatile long*>(pointer), value, expected); | 40 | _InterlockedCompareExchange(reinterpret_cast<volatile long*>(pointer), value, expected); |
| 33 | return result == expected; | 41 | return result == expected; |
| 34 | } | 42 | } |
| 35 | 43 | ||
| 36 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected) { | 44 | template <> |
| 45 | [[nodiscard]] inline bool AtomicCompareAndSwap<u64>(u64* pointer, u64 value, u64 expected) { | ||
| 37 | const u64 result = _InterlockedCompareExchange64(reinterpret_cast<volatile __int64*>(pointer), | 46 | const u64 result = _InterlockedCompareExchange64(reinterpret_cast<volatile __int64*>(pointer), |
| 38 | value, expected); | 47 | value, expected); |
| 39 | return result == expected; | 48 | return result == expected; |
| @@ -45,29 +54,32 @@ namespace Common { | |||
| 45 | reinterpret_cast<__int64*>(expected.data())) != 0; | 54 | reinterpret_cast<__int64*>(expected.data())) != 0; |
| 46 | } | 55 | } |
| 47 | 56 | ||
| 48 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected, | 57 | template <> |
| 49 | u8& actual) { | 58 | [[nodiscard]] inline bool AtomicCompareAndSwap<u8>(u8* pointer, u8 value, u8 expected, u8& actual) { |
| 50 | actual = | 59 | actual = |
| 51 | _InterlockedCompareExchange8(reinterpret_cast<volatile char*>(pointer), value, expected); | 60 | _InterlockedCompareExchange8(reinterpret_cast<volatile char*>(pointer), value, expected); |
| 52 | return actual == expected; | 61 | return actual == expected; |
| 53 | } | 62 | } |
| 54 | 63 | ||
| 55 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected, | 64 | template <> |
| 56 | u16& actual) { | 65 | [[nodiscard]] inline bool AtomicCompareAndSwap<u16>(u16* pointer, u16 value, u16 expected, |
| 66 | u16& actual) { | ||
| 57 | actual = | 67 | actual = |
| 58 | _InterlockedCompareExchange16(reinterpret_cast<volatile short*>(pointer), value, expected); | 68 | _InterlockedCompareExchange16(reinterpret_cast<volatile short*>(pointer), value, expected); |
| 59 | return actual == expected; | 69 | return actual == expected; |
| 60 | } | 70 | } |
| 61 | 71 | ||
| 62 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected, | 72 | template <> |
| 63 | u32& actual) { | 73 | [[nodiscard]] inline bool AtomicCompareAndSwap<u32>(u32* pointer, u32 value, u32 expected, |
| 74 | u32& actual) { | ||
| 64 | actual = | 75 | actual = |
| 65 | _InterlockedCompareExchange(reinterpret_cast<volatile long*>(pointer), value, expected); | 76 | _InterlockedCompareExchange(reinterpret_cast<volatile long*>(pointer), value, expected); |
| 66 | return actual == expected; | 77 | return actual == expected; |
| 67 | } | 78 | } |
| 68 | 79 | ||
| 69 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected, | 80 | template <> |
| 70 | u64& actual) { | 81 | [[nodiscard]] inline bool AtomicCompareAndSwap<u64>(u64* pointer, u64 value, u64 expected, |
| 82 | u64& actual) { | ||
| 71 | actual = _InterlockedCompareExchange64(reinterpret_cast<volatile __int64*>(pointer), value, | 83 | actual = _InterlockedCompareExchange64(reinterpret_cast<volatile __int64*>(pointer), value, |
| 72 | expected); | 84 | expected); |
| 73 | return actual == expected; | 85 | return actual == expected; |
| @@ -91,23 +103,12 @@ namespace Common { | |||
| 91 | 103 | ||
| 92 | #else | 104 | #else |
| 93 | 105 | ||
| 94 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected) { | 106 | template <typename T> |
| 95 | return __sync_bool_compare_and_swap(pointer, expected, value); | 107 | [[nodiscard]] inline bool AtomicCompareAndSwap(T* pointer, T value, T expected) { |
| 96 | } | ||
| 97 | |||
| 98 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected) { | ||
| 99 | return __sync_bool_compare_and_swap(pointer, expected, value); | ||
| 100 | } | ||
| 101 | |||
| 102 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected) { | ||
| 103 | return __sync_bool_compare_and_swap(pointer, expected, value); | 108 | return __sync_bool_compare_and_swap(pointer, expected, value); |
| 104 | } | 109 | } |
| 105 | 110 | ||
| 106 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected) { | 111 | [[nodiscard]] inline bool AtomicCompareAndSwap(u64* pointer, u128 value, u128 expected) { |
| 107 | return __sync_bool_compare_and_swap(pointer, expected, value); | ||
| 108 | } | ||
| 109 | |||
| 110 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u128 value, u128 expected) { | ||
| 111 | unsigned __int128 value_a; | 112 | unsigned __int128 value_a; |
| 112 | unsigned __int128 expected_a; | 113 | unsigned __int128 expected_a; |
| 113 | std::memcpy(&value_a, value.data(), sizeof(u128)); | 114 | std::memcpy(&value_a, value.data(), sizeof(u128)); |
| @@ -115,31 +116,13 @@ namespace Common { | |||
| 115 | return __sync_bool_compare_and_swap((unsigned __int128*)pointer, expected_a, value_a); | 116 | return __sync_bool_compare_and_swap((unsigned __int128*)pointer, expected_a, value_a); |
| 116 | } | 117 | } |
| 117 | 118 | ||
| 118 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected, | 119 | template <typename T> |
| 119 | u8& actual) { | 120 | [[nodiscard]] inline bool AtomicCompareAndSwap(T* pointer, T value, T expected, T& actual) { |
| 120 | actual = __sync_val_compare_and_swap(pointer, expected, value); | 121 | actual = __sync_val_compare_and_swap(pointer, expected, value); |
| 121 | return actual == expected; | 122 | return actual == expected; |
| 122 | } | 123 | } |
| 123 | 124 | ||
| 124 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected, | 125 | [[nodiscard]] inline bool AtomicCompareAndSwap(u64* pointer, u128 value, u128 expected, |
| 125 | u16& actual) { | ||
| 126 | actual = __sync_val_compare_and_swap(pointer, expected, value); | ||
| 127 | return actual == expected; | ||
| 128 | } | ||
| 129 | |||
| 130 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected, | ||
| 131 | u32& actual) { | ||
| 132 | actual = __sync_val_compare_and_swap(pointer, expected, value); | ||
| 133 | return actual == expected; | ||
| 134 | } | ||
| 135 | |||
| 136 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected, | ||
| 137 | u64& actual) { | ||
| 138 | actual = __sync_val_compare_and_swap(pointer, expected, value); | ||
| 139 | return actual == expected; | ||
| 140 | } | ||
| 141 | |||
| 142 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u128 value, u128 expected, | ||
| 143 | u128& actual) { | 126 | u128& actual) { |
| 144 | unsigned __int128 value_a; | 127 | unsigned __int128 value_a; |
| 145 | unsigned __int128 expected_a; | 128 | unsigned __int128 expected_a; |
| @@ -151,7 +134,7 @@ namespace Common { | |||
| 151 | return actual_a == expected_a; | 134 | return actual_a == expected_a; |
| 152 | } | 135 | } |
| 153 | 136 | ||
| 154 | [[nodiscard]] inline u128 AtomicLoad128(volatile u64* pointer) { | 137 | [[nodiscard]] inline u128 AtomicLoad128(u64* pointer) { |
| 155 | unsigned __int128 zeros_a = 0; | 138 | unsigned __int128 zeros_a = 0; |
| 156 | unsigned __int128 result_a = | 139 | unsigned __int128 result_a = |
| 157 | __sync_val_compare_and_swap((unsigned __int128*)pointer, zeros_a, zeros_a); | 140 | __sync_val_compare_and_swap((unsigned __int128*)pointer, zeros_a, zeros_a); |
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 7d3421929..8a360a839 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp | |||
| @@ -543,7 +543,8 @@ void KThread::Unpin() { | |||
| 543 | ASSERT(m_parent != nullptr); | 543 | ASSERT(m_parent != nullptr); |
| 544 | 544 | ||
| 545 | // Resume any threads that began waiting on us while we were pinned. | 545 | // Resume any threads that began waiting on us while we were pinned. |
| 546 | for (auto it = m_pinned_waiter_list.begin(); it != m_pinned_waiter_list.end(); ++it) { | 546 | for (auto it = m_pinned_waiter_list.begin(); it != m_pinned_waiter_list.end(); |
| 547 | it = m_pinned_waiter_list.erase(it)) { | ||
| 547 | it->EndWait(ResultSuccess); | 548 | it->EndWait(ResultSuccess); |
| 548 | } | 549 | } |
| 549 | } | 550 | } |
diff --git a/src/core/hle/service/am/applets/applet_mii_edit.cpp b/src/core/hle/service/am/applets/applet_mii_edit.cpp index 50adc7c02..e83e931c5 100644 --- a/src/core/hle/service/am/applets/applet_mii_edit.cpp +++ b/src/core/hle/service/am/applets/applet_mii_edit.cpp | |||
| @@ -59,7 +59,7 @@ void MiiEdit::Initialize() { | |||
| 59 | break; | 59 | break; |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | manager = system.ServiceManager().GetService<Mii::MiiDBModule>("mii:e")->GetMiiManager(); | 62 | manager = system.ServiceManager().GetService<Mii::IStaticService>("mii:e")->GetMiiManager(); |
| 63 | if (manager == nullptr) { | 63 | if (manager == nullptr) { |
| 64 | manager = std::make_shared<Mii::MiiManager>(); | 64 | manager = std::make_shared<Mii::MiiManager>(); |
| 65 | } | 65 | } |
diff --git a/src/core/hle/service/audio/audctl.cpp b/src/core/hle/service/audio/audctl.cpp index 66dd64fd1..3101cf447 100644 --- a/src/core/hle/service/audio/audctl.cpp +++ b/src/core/hle/service/audio/audctl.cpp | |||
| @@ -4,6 +4,8 @@ | |||
| 4 | #include "common/logging/log.h" | 4 | #include "common/logging/log.h" |
| 5 | #include "core/hle/service/audio/audctl.h" | 5 | #include "core/hle/service/audio/audctl.h" |
| 6 | #include "core/hle/service/ipc_helpers.h" | 6 | #include "core/hle/service/ipc_helpers.h" |
| 7 | #include "core/hle/service/set/system_settings_server.h" | ||
| 8 | #include "core/hle/service/sm/sm.h" | ||
| 7 | 9 | ||
| 8 | namespace Service::Audio { | 10 | namespace Service::Audio { |
| 9 | 11 | ||
| @@ -19,15 +21,15 @@ AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} { | |||
| 19 | {6, nullptr, "IsTargetConnected"}, | 21 | {6, nullptr, "IsTargetConnected"}, |
| 20 | {7, nullptr, "SetDefaultTarget"}, | 22 | {7, nullptr, "SetDefaultTarget"}, |
| 21 | {8, nullptr, "GetDefaultTarget"}, | 23 | {8, nullptr, "GetDefaultTarget"}, |
| 22 | {9, nullptr, "GetAudioOutputMode"}, | 24 | {9, &AudCtl::GetAudioOutputMode, "GetAudioOutputMode"}, |
| 23 | {10, nullptr, "SetAudioOutputMode"}, | 25 | {10, &AudCtl::SetAudioOutputMode, "SetAudioOutputMode"}, |
| 24 | {11, nullptr, "SetForceMutePolicy"}, | 26 | {11, nullptr, "SetForceMutePolicy"}, |
| 25 | {12, &AudCtl::GetForceMutePolicy, "GetForceMutePolicy"}, | 27 | {12, &AudCtl::GetForceMutePolicy, "GetForceMutePolicy"}, |
| 26 | {13, &AudCtl::GetOutputModeSetting, "GetOutputModeSetting"}, | 28 | {13, &AudCtl::GetOutputModeSetting, "GetOutputModeSetting"}, |
| 27 | {14, nullptr, "SetOutputModeSetting"}, | 29 | {14, &AudCtl::SetOutputModeSetting, "SetOutputModeSetting"}, |
| 28 | {15, nullptr, "SetOutputTarget"}, | 30 | {15, nullptr, "SetOutputTarget"}, |
| 29 | {16, nullptr, "SetInputTargetForceEnabled"}, | 31 | {16, nullptr, "SetInputTargetForceEnabled"}, |
| 30 | {17, nullptr, "SetHeadphoneOutputLevelMode"}, | 32 | {17, &AudCtl::SetHeadphoneOutputLevelMode, "SetHeadphoneOutputLevelMode"}, |
| 31 | {18, &AudCtl::GetHeadphoneOutputLevelMode, "GetHeadphoneOutputLevelMode"}, | 33 | {18, &AudCtl::GetHeadphoneOutputLevelMode, "GetHeadphoneOutputLevelMode"}, |
| 32 | {19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"}, | 34 | {19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"}, |
| 33 | {20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"}, | 35 | {20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"}, |
| @@ -40,7 +42,7 @@ AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} { | |||
| 40 | {27, nullptr, "SetVolumeMappingTableForDev"}, | 42 | {27, nullptr, "SetVolumeMappingTableForDev"}, |
| 41 | {28, nullptr, "GetAudioOutputChannelCountForPlayReport"}, | 43 | {28, nullptr, "GetAudioOutputChannelCountForPlayReport"}, |
| 42 | {29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"}, | 44 | {29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"}, |
| 43 | {30, nullptr, "SetSpeakerAutoMuteEnabled"}, | 45 | {30, &AudCtl::SetSpeakerAutoMuteEnabled, "SetSpeakerAutoMuteEnabled"}, |
| 44 | {31, &AudCtl::IsSpeakerAutoMuteEnabled, "IsSpeakerAutoMuteEnabled"}, | 46 | {31, &AudCtl::IsSpeakerAutoMuteEnabled, "IsSpeakerAutoMuteEnabled"}, |
| 45 | {32, nullptr, "GetActiveOutputTarget"}, | 47 | {32, nullptr, "GetActiveOutputTarget"}, |
| 46 | {33, nullptr, "GetTargetDeviceInfo"}, | 48 | {33, nullptr, "GetTargetDeviceInfo"}, |
| @@ -68,6 +70,9 @@ AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} { | |||
| 68 | // clang-format on | 70 | // clang-format on |
| 69 | 71 | ||
| 70 | RegisterHandlers(functions); | 72 | RegisterHandlers(functions); |
| 73 | |||
| 74 | m_set_sys = | ||
| 75 | system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); | ||
| 71 | } | 76 | } |
| 72 | 77 | ||
| 73 | AudCtl::~AudCtl() = default; | 78 | AudCtl::~AudCtl() = default; |
| @@ -96,6 +101,33 @@ void AudCtl::GetTargetVolumeMax(HLERequestContext& ctx) { | |||
| 96 | rb.Push(target_max_volume); | 101 | rb.Push(target_max_volume); |
| 97 | } | 102 | } |
| 98 | 103 | ||
| 104 | void AudCtl::GetAudioOutputMode(HLERequestContext& ctx) { | ||
| 105 | IPC::RequestParser rp{ctx}; | ||
| 106 | const auto target{rp.PopEnum<Set::AudioOutputModeTarget>()}; | ||
| 107 | |||
| 108 | Set::AudioOutputMode output_mode{}; | ||
| 109 | const auto result = m_set_sys->GetAudioOutputMode(output_mode, target); | ||
| 110 | |||
| 111 | LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode); | ||
| 112 | |||
| 113 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 114 | rb.Push(result); | ||
| 115 | rb.PushEnum(output_mode); | ||
| 116 | } | ||
| 117 | |||
| 118 | void AudCtl::SetAudioOutputMode(HLERequestContext& ctx) { | ||
| 119 | IPC::RequestParser rp{ctx}; | ||
| 120 | const auto target{rp.PopEnum<Set::AudioOutputModeTarget>()}; | ||
| 121 | const auto output_mode{rp.PopEnum<Set::AudioOutputMode>()}; | ||
| 122 | |||
| 123 | const auto result = m_set_sys->SetAudioOutputMode(target, output_mode); | ||
| 124 | |||
| 125 | LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode); | ||
| 126 | |||
| 127 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 128 | rb.Push(result); | ||
| 129 | } | ||
| 130 | |||
| 99 | void AudCtl::GetForceMutePolicy(HLERequestContext& ctx) { | 131 | void AudCtl::GetForceMutePolicy(HLERequestContext& ctx) { |
| 100 | LOG_WARNING(Audio, "(STUBBED) called"); | 132 | LOG_WARNING(Audio, "(STUBBED) called"); |
| 101 | 133 | ||
| @@ -106,13 +138,31 @@ void AudCtl::GetForceMutePolicy(HLERequestContext& ctx) { | |||
| 106 | 138 | ||
| 107 | void AudCtl::GetOutputModeSetting(HLERequestContext& ctx) { | 139 | void AudCtl::GetOutputModeSetting(HLERequestContext& ctx) { |
| 108 | IPC::RequestParser rp{ctx}; | 140 | IPC::RequestParser rp{ctx}; |
| 109 | const auto value = rp.Pop<u32>(); | 141 | const auto target{rp.PopEnum<Set::AudioOutputModeTarget>()}; |
| 110 | 142 | ||
| 111 | LOG_WARNING(Audio, "(STUBBED) called, value={}", value); | 143 | LOG_WARNING(Audio, "(STUBBED) called, target={}", target); |
| 112 | 144 | ||
| 113 | IPC::ResponseBuilder rb{ctx, 3}; | 145 | IPC::ResponseBuilder rb{ctx, 3}; |
| 114 | rb.Push(ResultSuccess); | 146 | rb.Push(ResultSuccess); |
| 115 | rb.PushEnum(AudioOutputMode::PcmAuto); | 147 | rb.PushEnum(Set::AudioOutputMode::ch_7_1); |
| 148 | } | ||
| 149 | |||
| 150 | void AudCtl::SetOutputModeSetting(HLERequestContext& ctx) { | ||
| 151 | IPC::RequestParser rp{ctx}; | ||
| 152 | const auto target{rp.PopEnum<Set::AudioOutputModeTarget>()}; | ||
| 153 | const auto output_mode{rp.PopEnum<Set::AudioOutputMode>()}; | ||
| 154 | |||
| 155 | LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode); | ||
| 156 | |||
| 157 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 158 | rb.Push(ResultSuccess); | ||
| 159 | } | ||
| 160 | |||
| 161 | void AudCtl::SetHeadphoneOutputLevelMode(HLERequestContext& ctx) { | ||
| 162 | LOG_WARNING(Audio, "(STUBBED) called"); | ||
| 163 | |||
| 164 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 165 | rb.Push(ResultSuccess); | ||
| 116 | } | 166 | } |
| 117 | 167 | ||
| 118 | void AudCtl::GetHeadphoneOutputLevelMode(HLERequestContext& ctx) { | 168 | void AudCtl::GetHeadphoneOutputLevelMode(HLERequestContext& ctx) { |
| @@ -123,14 +173,28 @@ void AudCtl::GetHeadphoneOutputLevelMode(HLERequestContext& ctx) { | |||
| 123 | rb.PushEnum(HeadphoneOutputLevelMode::Normal); | 173 | rb.PushEnum(HeadphoneOutputLevelMode::Normal); |
| 124 | } | 174 | } |
| 125 | 175 | ||
| 176 | void AudCtl::SetSpeakerAutoMuteEnabled(HLERequestContext& ctx) { | ||
| 177 | IPC::RequestParser rp{ctx}; | ||
| 178 | const auto is_speaker_auto_mute_enabled{rp.Pop<bool>()}; | ||
| 179 | |||
| 180 | LOG_WARNING(Audio, "(STUBBED) called, is_speaker_auto_mute_enabled={}", | ||
| 181 | is_speaker_auto_mute_enabled); | ||
| 182 | |||
| 183 | const auto result = m_set_sys->SetSpeakerAutoMuteFlag(is_speaker_auto_mute_enabled); | ||
| 184 | |||
| 185 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 186 | rb.Push(result); | ||
| 187 | } | ||
| 188 | |||
| 126 | void AudCtl::IsSpeakerAutoMuteEnabled(HLERequestContext& ctx) { | 189 | void AudCtl::IsSpeakerAutoMuteEnabled(HLERequestContext& ctx) { |
| 127 | const bool is_speaker_auto_mute_enabled = false; | 190 | bool is_speaker_auto_mute_enabled{}; |
| 191 | const auto result = m_set_sys->GetSpeakerAutoMuteFlag(is_speaker_auto_mute_enabled); | ||
| 128 | 192 | ||
| 129 | LOG_WARNING(Audio, "(STUBBED) called, is_speaker_auto_mute_enabled={}", | 193 | LOG_WARNING(Audio, "(STUBBED) called, is_speaker_auto_mute_enabled={}", |
| 130 | is_speaker_auto_mute_enabled); | 194 | is_speaker_auto_mute_enabled); |
| 131 | 195 | ||
| 132 | IPC::ResponseBuilder rb{ctx, 3}; | 196 | IPC::ResponseBuilder rb{ctx, 3}; |
| 133 | rb.Push(ResultSuccess); | 197 | rb.Push(result); |
| 134 | rb.Push<u8>(is_speaker_auto_mute_enabled); | 198 | rb.Push<u8>(is_speaker_auto_mute_enabled); |
| 135 | } | 199 | } |
| 136 | 200 | ||
diff --git a/src/core/hle/service/audio/audctl.h b/src/core/hle/service/audio/audctl.h index d57abb383..4c90ead70 100644 --- a/src/core/hle/service/audio/audctl.h +++ b/src/core/hle/service/audio/audctl.h | |||
| @@ -9,6 +9,10 @@ namespace Core { | |||
| 9 | class System; | 9 | class System; |
| 10 | } | 10 | } |
| 11 | 11 | ||
| 12 | namespace Service::Set { | ||
| 13 | class ISystemSettingsServer; | ||
| 14 | } | ||
| 15 | |||
| 12 | namespace Service::Audio { | 16 | namespace Service::Audio { |
| 13 | 17 | ||
| 14 | class AudCtl final : public ServiceFramework<AudCtl> { | 18 | class AudCtl final : public ServiceFramework<AudCtl> { |
| @@ -17,14 +21,6 @@ public: | |||
| 17 | ~AudCtl() override; | 21 | ~AudCtl() override; |
| 18 | 22 | ||
| 19 | private: | 23 | private: |
| 20 | enum class AudioOutputMode { | ||
| 21 | Invalid, | ||
| 22 | Pcm1ch, | ||
| 23 | Pcm2ch, | ||
| 24 | Pcm6ch, | ||
| 25 | PcmAuto, | ||
| 26 | }; | ||
| 27 | |||
| 28 | enum class ForceMutePolicy { | 24 | enum class ForceMutePolicy { |
| 29 | Disable, | 25 | Disable, |
| 30 | SpeakerMuteOnHeadphoneUnplugged, | 26 | SpeakerMuteOnHeadphoneUnplugged, |
| @@ -37,10 +33,18 @@ private: | |||
| 37 | 33 | ||
| 38 | void GetTargetVolumeMin(HLERequestContext& ctx); | 34 | void GetTargetVolumeMin(HLERequestContext& ctx); |
| 39 | void GetTargetVolumeMax(HLERequestContext& ctx); | 35 | void GetTargetVolumeMax(HLERequestContext& ctx); |
| 36 | void GetAudioOutputMode(HLERequestContext& ctx); | ||
| 37 | void SetAudioOutputMode(HLERequestContext& ctx); | ||
| 40 | void GetForceMutePolicy(HLERequestContext& ctx); | 38 | void GetForceMutePolicy(HLERequestContext& ctx); |
| 41 | void GetOutputModeSetting(HLERequestContext& ctx); | 39 | void GetOutputModeSetting(HLERequestContext& ctx); |
| 40 | void SetOutputModeSetting(HLERequestContext& ctx); | ||
| 41 | void SetHeadphoneOutputLevelMode(HLERequestContext& ctx); | ||
| 42 | void GetHeadphoneOutputLevelMode(HLERequestContext& ctx); | 42 | void GetHeadphoneOutputLevelMode(HLERequestContext& ctx); |
| 43 | void SetSpeakerAutoMuteEnabled(HLERequestContext& ctx); | ||
| 43 | void IsSpeakerAutoMuteEnabled(HLERequestContext& ctx); | 44 | void IsSpeakerAutoMuteEnabled(HLERequestContext& ctx); |
| 45 | void AcquireTargetNotification(HLERequestContext& ctx); | ||
| 46 | |||
| 47 | std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; | ||
| 44 | }; | 48 | }; |
| 45 | 49 | ||
| 46 | } // namespace Service::Audio | 50 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 05581e6e0..10108abc0 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp | |||
| @@ -35,10 +35,11 @@ public: | |||
| 35 | explicit IAudioRenderer(Core::System& system_, Manager& manager_, | 35 | explicit IAudioRenderer(Core::System& system_, Manager& manager_, |
| 36 | AudioCore::AudioRendererParameterInternal& params, | 36 | AudioCore::AudioRendererParameterInternal& params, |
| 37 | Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, | 37 | Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, |
| 38 | u32 process_handle, u64 applet_resource_user_id, s32 session_id) | 38 | u32 process_handle, Kernel::KProcess& process_, |
| 39 | u64 applet_resource_user_id, s32 session_id) | ||
| 39 | : ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"}, | 40 | : ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"}, |
| 40 | rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_}, | 41 | rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_}, |
| 41 | impl{std::make_unique<Renderer>(system_, manager, rendered_event)} { | 42 | impl{std::make_unique<Renderer>(system_, manager, rendered_event)}, process{process_} { |
| 42 | // clang-format off | 43 | // clang-format off |
| 43 | static const FunctionInfo functions[] = { | 44 | static const FunctionInfo functions[] = { |
| 44 | {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"}, | 45 | {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"}, |
| @@ -59,13 +60,15 @@ public: | |||
| 59 | // clang-format on | 60 | // clang-format on |
| 60 | RegisterHandlers(functions); | 61 | RegisterHandlers(functions); |
| 61 | 62 | ||
| 62 | impl->Initialize(params, transfer_memory, transfer_memory_size, process_handle, | 63 | process.Open(); |
| 64 | impl->Initialize(params, transfer_memory, transfer_memory_size, process_handle, process, | ||
| 63 | applet_resource_user_id, session_id); | 65 | applet_resource_user_id, session_id); |
| 64 | } | 66 | } |
| 65 | 67 | ||
| 66 | ~IAudioRenderer() override { | 68 | ~IAudioRenderer() override { |
| 67 | impl->Finalize(); | 69 | impl->Finalize(); |
| 68 | service_context.CloseEvent(rendered_event); | 70 | service_context.CloseEvent(rendered_event); |
| 71 | process.Close(); | ||
| 69 | } | 72 | } |
| 70 | 73 | ||
| 71 | private: | 74 | private: |
| @@ -235,6 +238,7 @@ private: | |||
| 235 | Kernel::KEvent* rendered_event; | 238 | Kernel::KEvent* rendered_event; |
| 236 | Manager& manager; | 239 | Manager& manager; |
| 237 | std::unique_ptr<Renderer> impl; | 240 | std::unique_ptr<Renderer> impl; |
| 241 | Kernel::KProcess& process; | ||
| 238 | Common::ScratchBuffer<u8> output_buffer; | 242 | Common::ScratchBuffer<u8> output_buffer; |
| 239 | Common::ScratchBuffer<u8> performance_buffer; | 243 | Common::ScratchBuffer<u8> performance_buffer; |
| 240 | }; | 244 | }; |
| @@ -455,7 +459,7 @@ void AudRenU::OpenAudioRenderer(HLERequestContext& ctx) { | |||
| 455 | return; | 459 | return; |
| 456 | } | 460 | } |
| 457 | 461 | ||
| 458 | auto process{ctx.GetObjectFromHandle<Kernel::KProcess>(process_handle)}; | 462 | auto process{ctx.GetObjectFromHandle<Kernel::KProcess>(process_handle).GetPointerUnsafe()}; |
| 459 | auto transfer_memory{ctx.GetObjectFromHandle<Kernel::KTransferMemory>(transfer_memory_handle)}; | 463 | auto transfer_memory{ctx.GetObjectFromHandle<Kernel::KTransferMemory>(transfer_memory_handle)}; |
| 460 | 464 | ||
| 461 | const auto session_id{impl->GetSessionId()}; | 465 | const auto session_id{impl->GetSessionId()}; |
| @@ -472,7 +476,7 @@ void AudRenU::OpenAudioRenderer(HLERequestContext& ctx) { | |||
| 472 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 476 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 473 | rb.Push(ResultSuccess); | 477 | rb.Push(ResultSuccess); |
| 474 | rb.PushIpcInterface<IAudioRenderer>(system, *impl, params, transfer_memory.GetPointerUnsafe(), | 478 | rb.PushIpcInterface<IAudioRenderer>(system, *impl, params, transfer_memory.GetPointerUnsafe(), |
| 475 | transfer_memory_size, process_handle, | 479 | transfer_memory_size, process_handle, *process, |
| 476 | applet_resource_user_id, session_id); | 480 | applet_resource_user_id, session_id); |
| 477 | } | 481 | } |
| 478 | 482 | ||
| @@ -522,7 +526,7 @@ void AudRenU::GetAudioDeviceService(HLERequestContext& ctx) { | |||
| 522 | } | 526 | } |
| 523 | 527 | ||
| 524 | void AudRenU::OpenAudioRendererForManualExecution(HLERequestContext& ctx) { | 528 | void AudRenU::OpenAudioRendererForManualExecution(HLERequestContext& ctx) { |
| 525 | LOG_DEBUG(Service_Audio, "called"); | 529 | LOG_ERROR(Service_Audio, "called. Implement me!"); |
| 526 | } | 530 | } |
| 527 | 531 | ||
| 528 | void AudRenU::GetAudioDeviceServiceWithRevisionInfo(HLERequestContext& ctx) { | 532 | void AudRenU::GetAudioDeviceServiceWithRevisionInfo(HLERequestContext& ctx) { |
diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp index c28eed926..b4d16fed5 100644 --- a/src/core/hle/service/mii/mii.cpp +++ b/src/core/hle/service/mii/mii.cpp | |||
| @@ -4,15 +4,18 @@ | |||
| 4 | #include <memory> | 4 | #include <memory> |
| 5 | 5 | ||
| 6 | #include "common/logging/log.h" | 6 | #include "common/logging/log.h" |
| 7 | #include "core/hle/service/cmif_serialization.h" | ||
| 7 | #include "core/hle/service/ipc_helpers.h" | 8 | #include "core/hle/service/ipc_helpers.h" |
| 8 | #include "core/hle/service/mii/mii.h" | 9 | #include "core/hle/service/mii/mii.h" |
| 9 | #include "core/hle/service/mii/mii_manager.h" | 10 | #include "core/hle/service/mii/mii_manager.h" |
| 10 | #include "core/hle/service/mii/mii_result.h" | 11 | #include "core/hle/service/mii/mii_result.h" |
| 11 | #include "core/hle/service/mii/types/char_info.h" | 12 | #include "core/hle/service/mii/types/char_info.h" |
| 13 | #include "core/hle/service/mii/types/raw_data.h" | ||
| 12 | #include "core/hle/service/mii/types/store_data.h" | 14 | #include "core/hle/service/mii/types/store_data.h" |
| 13 | #include "core/hle/service/mii/types/ver3_store_data.h" | 15 | #include "core/hle/service/mii/types/ver3_store_data.h" |
| 14 | #include "core/hle/service/server_manager.h" | 16 | #include "core/hle/service/server_manager.h" |
| 15 | #include "core/hle/service/service.h" | 17 | #include "core/hle/service/set/system_settings_server.h" |
| 18 | #include "core/hle/service/sm/sm.h" | ||
| 16 | 19 | ||
| 17 | namespace Service::Mii { | 20 | namespace Service::Mii { |
| 18 | 21 | ||
| @@ -24,549 +27,302 @@ public: | |||
| 24 | is_system_} { | 27 | is_system_} { |
| 25 | // clang-format off | 28 | // clang-format off |
| 26 | static const FunctionInfo functions[] = { | 29 | static const FunctionInfo functions[] = { |
| 27 | {0, &IDatabaseService::IsUpdated, "IsUpdated"}, | 30 | {0, D<&IDatabaseService::IsUpdated>, "IsUpdated"}, |
| 28 | {1, &IDatabaseService::IsFullDatabase, "IsFullDatabase"}, | 31 | {1, D<&IDatabaseService::IsFullDatabase>, "IsFullDatabase"}, |
| 29 | {2, &IDatabaseService::GetCount, "GetCount"}, | 32 | {2, D<&IDatabaseService::GetCount>, "GetCount"}, |
| 30 | {3, &IDatabaseService::Get, "Get"}, | 33 | {3, D<&IDatabaseService::Get>, "Get"}, |
| 31 | {4, &IDatabaseService::Get1, "Get1"}, | 34 | {4, D<&IDatabaseService::Get1>, "Get1"}, |
| 32 | {5, &IDatabaseService::UpdateLatest, "UpdateLatest"}, | 35 | {5, D<&IDatabaseService::UpdateLatest>, "UpdateLatest"}, |
| 33 | {6, &IDatabaseService::BuildRandom, "BuildRandom"}, | 36 | {6, D<&IDatabaseService::BuildRandom>, "BuildRandom"}, |
| 34 | {7, &IDatabaseService::BuildDefault, "BuildDefault"}, | 37 | {7, D<&IDatabaseService::BuildDefault>, "BuildDefault"}, |
| 35 | {8, &IDatabaseService::Get2, "Get2"}, | 38 | {8, D<&IDatabaseService::Get2>, "Get2"}, |
| 36 | {9, &IDatabaseService::Get3, "Get3"}, | 39 | {9, D<&IDatabaseService::Get3>, "Get3"}, |
| 37 | {10, &IDatabaseService::UpdateLatest1, "UpdateLatest1"}, | 40 | {10, D<&IDatabaseService::UpdateLatest1>, "UpdateLatest1"}, |
| 38 | {11, &IDatabaseService::FindIndex, "FindIndex"}, | 41 | {11, D<&IDatabaseService::FindIndex>, "FindIndex"}, |
| 39 | {12, &IDatabaseService::Move, "Move"}, | 42 | {12, D<&IDatabaseService::Move>, "Move"}, |
| 40 | {13, &IDatabaseService::AddOrReplace, "AddOrReplace"}, | 43 | {13, D<&IDatabaseService::AddOrReplace>, "AddOrReplace"}, |
| 41 | {14, &IDatabaseService::Delete, "Delete"}, | 44 | {14, D<&IDatabaseService::Delete>, "Delete"}, |
| 42 | {15, &IDatabaseService::DestroyFile, "DestroyFile"}, | 45 | {15, D<&IDatabaseService::DestroyFile>, "DestroyFile"}, |
| 43 | {16, &IDatabaseService::DeleteFile, "DeleteFile"}, | 46 | {16, D<&IDatabaseService::DeleteFile>, "DeleteFile"}, |
| 44 | {17, &IDatabaseService::Format, "Format"}, | 47 | {17, D<&IDatabaseService::Format>, "Format"}, |
| 45 | {18, nullptr, "Import"}, | 48 | {18, nullptr, "Import"}, |
| 46 | {19, nullptr, "Export"}, | 49 | {19, nullptr, "Export"}, |
| 47 | {20, &IDatabaseService::IsBrokenDatabaseWithClearFlag, "IsBrokenDatabaseWithClearFlag"}, | 50 | {20, D<&IDatabaseService::IsBrokenDatabaseWithClearFlag>, "IsBrokenDatabaseWithClearFlag"}, |
| 48 | {21, &IDatabaseService::GetIndex, "GetIndex"}, | 51 | {21, D<&IDatabaseService::GetIndex>, "GetIndex"}, |
| 49 | {22, &IDatabaseService::SetInterfaceVersion, "SetInterfaceVersion"}, | 52 | {22, D<&IDatabaseService::SetInterfaceVersion>, "SetInterfaceVersion"}, |
| 50 | {23, &IDatabaseService::Convert, "Convert"}, | 53 | {23, D<&IDatabaseService::Convert>, "Convert"}, |
| 51 | {24, &IDatabaseService::ConvertCoreDataToCharInfo, "ConvertCoreDataToCharInfo"}, | 54 | {24, D<&IDatabaseService::ConvertCoreDataToCharInfo>, "ConvertCoreDataToCharInfo"}, |
| 52 | {25, &IDatabaseService::ConvertCharInfoToCoreData, "ConvertCharInfoToCoreData"}, | 55 | {25, D<&IDatabaseService::ConvertCharInfoToCoreData>, "ConvertCharInfoToCoreData"}, |
| 53 | {26, &IDatabaseService::Append, "Append"}, | 56 | {26, D<&IDatabaseService::Append>, "Append"}, |
| 54 | }; | 57 | }; |
| 55 | // clang-format on | 58 | // clang-format on |
| 56 | 59 | ||
| 57 | RegisterHandlers(functions); | 60 | RegisterHandlers(functions); |
| 58 | 61 | ||
| 62 | m_set_sys = system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>( | ||
| 63 | "set:sys", true); | ||
| 59 | manager->Initialize(metadata); | 64 | manager->Initialize(metadata); |
| 60 | } | 65 | } |
| 61 | 66 | ||
| 62 | private: | 67 | private: |
| 63 | void IsUpdated(HLERequestContext& ctx) { | 68 | Result IsUpdated(Out<bool> out_is_updated, SourceFlag source_flag) { |
| 64 | IPC::RequestParser rp{ctx}; | ||
| 65 | const auto source_flag{rp.PopRaw<SourceFlag>()}; | ||
| 66 | |||
| 67 | LOG_DEBUG(Service_Mii, "called with source_flag={}", source_flag); | 69 | LOG_DEBUG(Service_Mii, "called with source_flag={}", source_flag); |
| 68 | 70 | ||
| 69 | const bool is_updated = manager->IsUpdated(metadata, source_flag); | 71 | *out_is_updated = manager->IsUpdated(metadata, source_flag); |
| 70 | 72 | ||
| 71 | IPC::ResponseBuilder rb{ctx, 3}; | 73 | R_SUCCEED(); |
| 72 | rb.Push(ResultSuccess); | ||
| 73 | rb.Push<u8>(is_updated); | ||
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | void IsFullDatabase(HLERequestContext& ctx) { | 76 | Result IsFullDatabase(Out<bool> out_is_full_database) { |
| 77 | LOG_DEBUG(Service_Mii, "called"); | 77 | LOG_DEBUG(Service_Mii, "called"); |
| 78 | 78 | ||
| 79 | const bool is_full_database = manager->IsFullDatabase(); | 79 | *out_is_full_database = manager->IsFullDatabase(); |
| 80 | 80 | ||
| 81 | IPC::ResponseBuilder rb{ctx, 3}; | 81 | R_SUCCEED(); |
| 82 | rb.Push(ResultSuccess); | ||
| 83 | rb.Push<u8>(is_full_database); | ||
| 84 | } | 82 | } |
| 85 | 83 | ||
| 86 | void GetCount(HLERequestContext& ctx) { | 84 | Result GetCount(Out<u32> out_mii_count, SourceFlag source_flag) { |
| 87 | IPC::RequestParser rp{ctx}; | 85 | *out_mii_count = manager->GetCount(metadata, source_flag); |
| 88 | const auto source_flag{rp.PopRaw<SourceFlag>()}; | ||
| 89 | |||
| 90 | const u32 mii_count = manager->GetCount(metadata, source_flag); | ||
| 91 | 86 | ||
| 92 | LOG_DEBUG(Service_Mii, "called with source_flag={}, mii_count={}", source_flag, mii_count); | 87 | LOG_DEBUG(Service_Mii, "called with source_flag={}, mii_count={}", source_flag, |
| 88 | *out_mii_count); | ||
| 93 | 89 | ||
| 94 | IPC::ResponseBuilder rb{ctx, 3}; | 90 | R_SUCCEED(); |
| 95 | rb.Push(ResultSuccess); | ||
| 96 | rb.Push(mii_count); | ||
| 97 | } | 91 | } |
| 98 | 92 | ||
| 99 | void Get(HLERequestContext& ctx) { | 93 | Result Get(Out<u32> out_mii_count, SourceFlag source_flag, |
| 100 | IPC::RequestParser rp{ctx}; | 94 | OutArray<CharInfoElement, BufferAttr_HipcMapAlias> char_info_element_buffer) { |
| 101 | const auto source_flag{rp.PopRaw<SourceFlag>()}; | 95 | const auto result = |
| 102 | const auto output_size{ctx.GetWriteBufferNumElements<CharInfoElement>()}; | 96 | manager->Get(metadata, char_info_element_buffer, *out_mii_count, source_flag); |
| 103 | |||
| 104 | u32 mii_count{}; | ||
| 105 | std::vector<CharInfoElement> char_info_elements(output_size); | ||
| 106 | const auto result = manager->Get(metadata, char_info_elements, mii_count, source_flag); | ||
| 107 | |||
| 108 | if (mii_count != 0) { | ||
| 109 | ctx.WriteBuffer(char_info_elements); | ||
| 110 | } | ||
| 111 | 97 | ||
| 112 | LOG_INFO(Service_Mii, "called with source_flag={}, out_size={}, mii_count={}", source_flag, | 98 | LOG_INFO(Service_Mii, "called with source_flag={}, mii_count={}", source_flag, |
| 113 | output_size, mii_count); | 99 | *out_mii_count); |
| 114 | 100 | ||
| 115 | IPC::ResponseBuilder rb{ctx, 3}; | 101 | R_RETURN(result); |
| 116 | rb.Push(result); | ||
| 117 | rb.Push(mii_count); | ||
| 118 | } | 102 | } |
| 119 | 103 | ||
| 120 | void Get1(HLERequestContext& ctx) { | 104 | Result Get1(Out<u32> out_mii_count, SourceFlag source_flag, |
| 121 | IPC::RequestParser rp{ctx}; | 105 | OutArray<CharInfo, BufferAttr_HipcMapAlias> char_info_buffer) { |
| 122 | const auto source_flag{rp.PopRaw<SourceFlag>()}; | 106 | const auto result = manager->Get(metadata, char_info_buffer, *out_mii_count, source_flag); |
| 123 | const auto output_size{ctx.GetWriteBufferNumElements<CharInfo>()}; | ||
| 124 | 107 | ||
| 125 | u32 mii_count{}; | 108 | LOG_INFO(Service_Mii, "called with source_flag={}, mii_count={}", source_flag, |
| 126 | std::vector<CharInfo> char_info(output_size); | 109 | *out_mii_count); |
| 127 | const auto result = manager->Get(metadata, char_info, mii_count, source_flag); | ||
| 128 | 110 | ||
| 129 | if (mii_count != 0) { | 111 | R_RETURN(result); |
| 130 | ctx.WriteBuffer(char_info); | ||
| 131 | } | ||
| 132 | |||
| 133 | LOG_INFO(Service_Mii, "called with source_flag={}, out_size={}, mii_count={}", source_flag, | ||
| 134 | output_size, mii_count); | ||
| 135 | |||
| 136 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 137 | rb.Push(result); | ||
| 138 | rb.Push(mii_count); | ||
| 139 | } | 112 | } |
| 140 | 113 | ||
| 141 | void UpdateLatest(HLERequestContext& ctx) { | 114 | Result UpdateLatest(Out<CharInfo> out_char_info, CharInfo& char_info, SourceFlag source_flag) { |
| 142 | IPC::RequestParser rp{ctx}; | ||
| 143 | const auto char_info{rp.PopRaw<CharInfo>()}; | ||
| 144 | const auto source_flag{rp.PopRaw<SourceFlag>()}; | ||
| 145 | |||
| 146 | LOG_INFO(Service_Mii, "called with source_flag={}", source_flag); | 115 | LOG_INFO(Service_Mii, "called with source_flag={}", source_flag); |
| 147 | 116 | ||
| 148 | CharInfo new_char_info{}; | 117 | R_RETURN(manager->UpdateLatest(metadata, *out_char_info, char_info, source_flag)); |
| 149 | const auto result = manager->UpdateLatest(metadata, new_char_info, char_info, source_flag); | ||
| 150 | if (result.IsFailure()) { | ||
| 151 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 152 | rb.Push(result); | ||
| 153 | return; | ||
| 154 | } | ||
| 155 | |||
| 156 | IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)}; | ||
| 157 | rb.Push(ResultSuccess); | ||
| 158 | rb.PushRaw(new_char_info); | ||
| 159 | } | 118 | } |
| 160 | 119 | ||
| 161 | void BuildRandom(HLERequestContext& ctx) { | 120 | Result BuildRandom(Out<CharInfo> out_char_info, Age age, Gender gender, Race race) { |
| 162 | IPC::RequestParser rp{ctx}; | ||
| 163 | const auto age{rp.PopRaw<Age>()}; | ||
| 164 | const auto gender{rp.PopRaw<Gender>()}; | ||
| 165 | const auto race{rp.PopRaw<Race>()}; | ||
| 166 | |||
| 167 | LOG_DEBUG(Service_Mii, "called with age={}, gender={}, race={}", age, gender, race); | 121 | LOG_DEBUG(Service_Mii, "called with age={}, gender={}, race={}", age, gender, race); |
| 168 | 122 | ||
| 169 | if (age > Age::All) { | 123 | R_UNLESS(age <= Age::All, ResultInvalidArgument); |
| 170 | IPC::ResponseBuilder rb{ctx, 2}; | 124 | R_UNLESS(gender <= Gender::All, ResultInvalidArgument); |
| 171 | rb.Push(ResultInvalidArgument); | 125 | R_UNLESS(race <= Race::All, ResultInvalidArgument); |
| 172 | return; | ||
| 173 | } | ||
| 174 | |||
| 175 | if (gender > Gender::All) { | ||
| 176 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 177 | rb.Push(ResultInvalidArgument); | ||
| 178 | return; | ||
| 179 | } | ||
| 180 | |||
| 181 | if (race > Race::All) { | ||
| 182 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 183 | rb.Push(ResultInvalidArgument); | ||
| 184 | return; | ||
| 185 | } | ||
| 186 | |||
| 187 | CharInfo char_info{}; | ||
| 188 | manager->BuildRandom(char_info, age, gender, race); | ||
| 189 | |||
| 190 | IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)}; | ||
| 191 | rb.Push(ResultSuccess); | ||
| 192 | rb.PushRaw(char_info); | ||
| 193 | } | ||
| 194 | 126 | ||
| 195 | void BuildDefault(HLERequestContext& ctx) { | 127 | manager->BuildRandom(*out_char_info, age, gender, race); |
| 196 | IPC::RequestParser rp{ctx}; | ||
| 197 | const auto index{rp.Pop<u32>()}; | ||
| 198 | 128 | ||
| 199 | LOG_DEBUG(Service_Mii, "called with index={}", index); | 129 | R_SUCCEED(); |
| 130 | } | ||
| 200 | 131 | ||
| 201 | if (index > 5) { | 132 | Result BuildDefault(Out<CharInfo> out_char_info, s32 index) { |
| 202 | IPC::ResponseBuilder rb{ctx, 2}; | 133 | LOG_DEBUG(Service_Mii, "called with index={}", index); |
| 203 | rb.Push(ResultInvalidArgument); | 134 | R_UNLESS(index < static_cast<s32>(RawData::DefaultMii.size()), ResultInvalidArgument); |
| 204 | return; | ||
| 205 | } | ||
| 206 | 135 | ||
| 207 | CharInfo char_info{}; | 136 | manager->BuildDefault(*out_char_info, index); |
| 208 | manager->BuildDefault(char_info, index); | ||
| 209 | 137 | ||
| 210 | IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)}; | 138 | R_SUCCEED(); |
| 211 | rb.Push(ResultSuccess); | ||
| 212 | rb.PushRaw(char_info); | ||
| 213 | } | 139 | } |
| 214 | 140 | ||
| 215 | void Get2(HLERequestContext& ctx) { | 141 | Result Get2(Out<u32> out_mii_count, SourceFlag source_flag, |
| 216 | IPC::RequestParser rp{ctx}; | 142 | OutArray<StoreDataElement, BufferAttr_HipcMapAlias> store_data_element_buffer) { |
| 217 | const auto source_flag{rp.PopRaw<SourceFlag>()}; | 143 | const auto result = |
| 218 | const auto output_size{ctx.GetWriteBufferNumElements<StoreDataElement>()}; | 144 | manager->Get(metadata, store_data_element_buffer, *out_mii_count, source_flag); |
| 219 | 145 | ||
| 220 | u32 mii_count{}; | 146 | LOG_INFO(Service_Mii, "called with source_flag={}, mii_count={}", source_flag, |
| 221 | std::vector<StoreDataElement> store_data_elements(output_size); | 147 | *out_mii_count); |
| 222 | const auto result = manager->Get(metadata, store_data_elements, mii_count, source_flag); | ||
| 223 | 148 | ||
| 224 | if (mii_count != 0) { | 149 | R_RETURN(result); |
| 225 | ctx.WriteBuffer(store_data_elements); | ||
| 226 | } | ||
| 227 | |||
| 228 | LOG_INFO(Service_Mii, "called with source_flag={}, out_size={}, mii_count={}", source_flag, | ||
| 229 | output_size, mii_count); | ||
| 230 | |||
| 231 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 232 | rb.Push(result); | ||
| 233 | rb.Push(mii_count); | ||
| 234 | } | 150 | } |
| 235 | 151 | ||
| 236 | void Get3(HLERequestContext& ctx) { | 152 | Result Get3(Out<u32> out_mii_count, SourceFlag source_flag, |
| 237 | IPC::RequestParser rp{ctx}; | 153 | OutArray<StoreData, BufferAttr_HipcMapAlias> store_data_buffer) { |
| 238 | const auto source_flag{rp.PopRaw<SourceFlag>()}; | 154 | const auto result = manager->Get(metadata, store_data_buffer, *out_mii_count, source_flag); |
| 239 | const auto output_size{ctx.GetWriteBufferNumElements<StoreData>()}; | ||
| 240 | |||
| 241 | u32 mii_count{}; | ||
| 242 | std::vector<StoreData> store_data(output_size); | ||
| 243 | const auto result = manager->Get(metadata, store_data, mii_count, source_flag); | ||
| 244 | 155 | ||
| 245 | if (mii_count != 0) { | 156 | LOG_INFO(Service_Mii, "called with source_flag={}, mii_count={}", source_flag, |
| 246 | ctx.WriteBuffer(store_data); | 157 | *out_mii_count); |
| 247 | } | ||
| 248 | 158 | ||
| 249 | LOG_INFO(Service_Mii, "called with source_flag={}, out_size={}, mii_count={}", source_flag, | 159 | R_RETURN(result); |
| 250 | output_size, mii_count); | ||
| 251 | |||
| 252 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 253 | rb.Push(result); | ||
| 254 | rb.Push(mii_count); | ||
| 255 | } | 160 | } |
| 256 | 161 | ||
| 257 | void UpdateLatest1(HLERequestContext& ctx) { | 162 | Result UpdateLatest1(Out<StoreData> out_store_data, StoreData& store_data, |
| 258 | IPC::RequestParser rp{ctx}; | 163 | SourceFlag source_flag) { |
| 259 | const auto store_data{rp.PopRaw<StoreData>()}; | ||
| 260 | const auto source_flag{rp.PopRaw<SourceFlag>()}; | ||
| 261 | |||
| 262 | LOG_INFO(Service_Mii, "called with source_flag={}", source_flag); | 164 | LOG_INFO(Service_Mii, "called with source_flag={}", source_flag); |
| 165 | R_UNLESS(is_system, ResultPermissionDenied); | ||
| 263 | 166 | ||
| 264 | Result result = ResultSuccess; | 167 | R_RETURN(manager->UpdateLatest(metadata, *out_store_data, store_data, source_flag)); |
| 265 | if (!is_system) { | ||
| 266 | result = ResultPermissionDenied; | ||
| 267 | } | ||
| 268 | |||
| 269 | StoreData new_store_data{}; | ||
| 270 | if (result.IsSuccess()) { | ||
| 271 | result = manager->UpdateLatest(metadata, new_store_data, store_data, source_flag); | ||
| 272 | } | ||
| 273 | |||
| 274 | if (result.IsFailure()) { | ||
| 275 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 276 | rb.Push(result); | ||
| 277 | return; | ||
| 278 | } | ||
| 279 | |||
| 280 | IPC::ResponseBuilder rb{ctx, 2 + sizeof(StoreData) / sizeof(u32)}; | ||
| 281 | rb.Push(ResultSuccess); | ||
| 282 | rb.PushRaw<StoreData>(new_store_data); | ||
| 283 | } | 168 | } |
| 284 | 169 | ||
| 285 | void FindIndex(HLERequestContext& ctx) { | 170 | Result FindIndex(Out<s32> out_index, Common::UUID create_id, bool is_special) { |
| 286 | IPC::RequestParser rp{ctx}; | ||
| 287 | const auto create_id{rp.PopRaw<Common::UUID>()}; | ||
| 288 | const auto is_special{rp.PopRaw<bool>()}; | ||
| 289 | |||
| 290 | LOG_INFO(Service_Mii, "called with create_id={}, is_special={}", | 171 | LOG_INFO(Service_Mii, "called with create_id={}, is_special={}", |
| 291 | create_id.FormattedString(), is_special); | 172 | create_id.FormattedString(), is_special); |
| 292 | 173 | ||
| 293 | const s32 index = manager->FindIndex(create_id, is_special); | 174 | *out_index = manager->FindIndex(create_id, is_special); |
| 294 | 175 | ||
| 295 | IPC::ResponseBuilder rb{ctx, 3}; | 176 | R_SUCCEED(); |
| 296 | rb.Push(ResultSuccess); | ||
| 297 | rb.Push(index); | ||
| 298 | } | 177 | } |
| 299 | 178 | ||
| 300 | void Move(HLERequestContext& ctx) { | 179 | Result Move(Common::UUID create_id, s32 new_index) { |
| 301 | IPC::RequestParser rp{ctx}; | ||
| 302 | const auto create_id{rp.PopRaw<Common::UUID>()}; | ||
| 303 | const auto new_index{rp.PopRaw<s32>()}; | ||
| 304 | |||
| 305 | LOG_INFO(Service_Mii, "called with create_id={}, new_index={}", create_id.FormattedString(), | 180 | LOG_INFO(Service_Mii, "called with create_id={}, new_index={}", create_id.FormattedString(), |
| 306 | new_index); | 181 | new_index); |
| 182 | R_UNLESS(is_system, ResultPermissionDenied); | ||
| 307 | 183 | ||
| 308 | Result result = ResultSuccess; | 184 | const u32 count = manager->GetCount(metadata, SourceFlag::Database); |
| 309 | if (!is_system) { | ||
| 310 | result = ResultPermissionDenied; | ||
| 311 | } | ||
| 312 | 185 | ||
| 313 | if (result.IsSuccess()) { | 186 | R_UNLESS(new_index >= 0 && new_index < static_cast<s32>(count), ResultInvalidArgument); |
| 314 | const u32 count = manager->GetCount(metadata, SourceFlag::Database); | ||
| 315 | if (new_index < 0 || new_index >= static_cast<s32>(count)) { | ||
| 316 | result = ResultInvalidArgument; | ||
| 317 | } | ||
| 318 | } | ||
| 319 | 187 | ||
| 320 | if (result.IsSuccess()) { | 188 | R_RETURN(manager->Move(metadata, new_index, create_id)); |
| 321 | result = manager->Move(metadata, new_index, create_id); | ||
| 322 | } | ||
| 323 | |||
| 324 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 325 | rb.Push(result); | ||
| 326 | } | 189 | } |
| 327 | 190 | ||
| 328 | void AddOrReplace(HLERequestContext& ctx) { | 191 | Result AddOrReplace(StoreData& store_data) { |
| 329 | IPC::RequestParser rp{ctx}; | ||
| 330 | const auto store_data{rp.PopRaw<StoreData>()}; | ||
| 331 | |||
| 332 | LOG_INFO(Service_Mii, "called"); | 192 | LOG_INFO(Service_Mii, "called"); |
| 193 | R_UNLESS(is_system, ResultPermissionDenied); | ||
| 333 | 194 | ||
| 334 | Result result = ResultSuccess; | 195 | const auto result = manager->AddOrReplace(metadata, store_data); |
| 335 | |||
| 336 | if (!is_system) { | ||
| 337 | result = ResultPermissionDenied; | ||
| 338 | } | ||
| 339 | 196 | ||
| 340 | if (result.IsSuccess()) { | 197 | R_RETURN(result); |
| 341 | result = manager->AddOrReplace(metadata, store_data); | ||
| 342 | } | ||
| 343 | |||
| 344 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 345 | rb.Push(result); | ||
| 346 | } | 198 | } |
| 347 | 199 | ||
| 348 | void Delete(HLERequestContext& ctx) { | 200 | Result Delete(Common::UUID create_id) { |
| 349 | IPC::RequestParser rp{ctx}; | ||
| 350 | const auto create_id{rp.PopRaw<Common::UUID>()}; | ||
| 351 | |||
| 352 | LOG_INFO(Service_Mii, "called, create_id={}", create_id.FormattedString()); | 201 | LOG_INFO(Service_Mii, "called, create_id={}", create_id.FormattedString()); |
| 202 | R_UNLESS(is_system, ResultPermissionDenied); | ||
| 353 | 203 | ||
| 354 | Result result = ResultSuccess; | 204 | R_RETURN(manager->Delete(metadata, create_id)); |
| 355 | |||
| 356 | if (!is_system) { | ||
| 357 | result = ResultPermissionDenied; | ||
| 358 | } | ||
| 359 | |||
| 360 | if (result.IsSuccess()) { | ||
| 361 | result = manager->Delete(metadata, create_id); | ||
| 362 | } | ||
| 363 | |||
| 364 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 365 | rb.Push(result); | ||
| 366 | } | 205 | } |
| 367 | 206 | ||
| 368 | void DestroyFile(HLERequestContext& ctx) { | 207 | Result DestroyFile() { |
| 369 | // This calls nn::settings::fwdbg::GetSettingsItemValue("is_db_test_mode_enabled"); | 208 | bool is_db_test_mode_enabled{}; |
| 370 | const bool is_db_test_mode_enabled = false; | 209 | m_set_sys->GetSettingsItemValue(is_db_test_mode_enabled, "mii", "is_db_test_mode_enabled"); |
| 371 | 210 | ||
| 372 | LOG_INFO(Service_Mii, "called is_db_test_mode_enabled={}", is_db_test_mode_enabled); | 211 | LOG_INFO(Service_Mii, "called is_db_test_mode_enabled={}", is_db_test_mode_enabled); |
| 212 | R_UNLESS(is_db_test_mode_enabled, ResultTestModeOnly); | ||
| 373 | 213 | ||
| 374 | Result result = ResultSuccess; | 214 | R_RETURN(manager->DestroyFile(metadata)); |
| 375 | |||
| 376 | if (!is_db_test_mode_enabled) { | ||
| 377 | result = ResultTestModeOnly; | ||
| 378 | } | ||
| 379 | |||
| 380 | if (result.IsSuccess()) { | ||
| 381 | result = manager->DestroyFile(metadata); | ||
| 382 | } | ||
| 383 | |||
| 384 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 385 | rb.Push(result); | ||
| 386 | } | 215 | } |
| 387 | 216 | ||
| 388 | void DeleteFile(HLERequestContext& ctx) { | 217 | Result DeleteFile() { |
| 389 | // This calls nn::settings::fwdbg::GetSettingsItemValue("is_db_test_mode_enabled"); | 218 | bool is_db_test_mode_enabled{}; |
| 390 | const bool is_db_test_mode_enabled = false; | 219 | m_set_sys->GetSettingsItemValue(is_db_test_mode_enabled, "mii", "is_db_test_mode_enabled"); |
| 391 | 220 | ||
| 392 | LOG_INFO(Service_Mii, "called is_db_test_mode_enabled={}", is_db_test_mode_enabled); | 221 | LOG_INFO(Service_Mii, "called is_db_test_mode_enabled={}", is_db_test_mode_enabled); |
| 222 | R_UNLESS(is_db_test_mode_enabled, ResultTestModeOnly); | ||
| 393 | 223 | ||
| 394 | Result result = ResultSuccess; | 224 | R_RETURN(manager->DeleteFile()); |
| 395 | |||
| 396 | if (!is_db_test_mode_enabled) { | ||
| 397 | result = ResultTestModeOnly; | ||
| 398 | } | ||
| 399 | |||
| 400 | if (result.IsSuccess()) { | ||
| 401 | result = manager->DeleteFile(); | ||
| 402 | } | ||
| 403 | |||
| 404 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 405 | rb.Push(result); | ||
| 406 | } | 225 | } |
| 407 | 226 | ||
| 408 | void Format(HLERequestContext& ctx) { | 227 | Result Format() { |
| 409 | // This calls nn::settings::fwdbg::GetSettingsItemValue("is_db_test_mode_enabled"); | 228 | bool is_db_test_mode_enabled{}; |
| 410 | const bool is_db_test_mode_enabled = false; | 229 | m_set_sys->GetSettingsItemValue(is_db_test_mode_enabled, "mii", "is_db_test_mode_enabled"); |
| 411 | 230 | ||
| 412 | LOG_INFO(Service_Mii, "called is_db_test_mode_enabled={}", is_db_test_mode_enabled); | 231 | LOG_INFO(Service_Mii, "called is_db_test_mode_enabled={}", is_db_test_mode_enabled); |
| 232 | R_UNLESS(is_db_test_mode_enabled, ResultTestModeOnly); | ||
| 413 | 233 | ||
| 414 | Result result = ResultSuccess; | 234 | R_RETURN(manager->Format(metadata)); |
| 415 | |||
| 416 | if (!is_db_test_mode_enabled) { | ||
| 417 | result = ResultTestModeOnly; | ||
| 418 | } | ||
| 419 | |||
| 420 | if (result.IsSuccess()) { | ||
| 421 | result = manager->Format(metadata); | ||
| 422 | } | ||
| 423 | |||
| 424 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 425 | rb.Push(result); | ||
| 426 | } | 235 | } |
| 427 | 236 | ||
| 428 | void IsBrokenDatabaseWithClearFlag(HLERequestContext& ctx) { | 237 | Result IsBrokenDatabaseWithClearFlag(Out<bool> out_is_broken_with_clear_flag) { |
| 429 | LOG_DEBUG(Service_Mii, "called"); | 238 | LOG_DEBUG(Service_Mii, "called"); |
| 239 | R_UNLESS(is_system, ResultPermissionDenied); | ||
| 430 | 240 | ||
| 431 | bool is_broken_with_clear_flag = false; | 241 | *out_is_broken_with_clear_flag = manager->IsBrokenWithClearFlag(metadata); |
| 432 | Result result = ResultSuccess; | ||
| 433 | 242 | ||
| 434 | if (!is_system) { | 243 | R_SUCCEED(); |
| 435 | result = ResultPermissionDenied; | ||
| 436 | } | ||
| 437 | |||
| 438 | if (result.IsSuccess()) { | ||
| 439 | is_broken_with_clear_flag = manager->IsBrokenWithClearFlag(metadata); | ||
| 440 | } | ||
| 441 | |||
| 442 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 443 | rb.Push(result); | ||
| 444 | rb.Push<u8>(is_broken_with_clear_flag); | ||
| 445 | } | 244 | } |
| 446 | 245 | ||
| 447 | void GetIndex(HLERequestContext& ctx) { | 246 | Result GetIndex(Out<s32> out_index, CharInfo& char_info) { |
| 448 | IPC::RequestParser rp{ctx}; | ||
| 449 | const auto info{rp.PopRaw<CharInfo>()}; | ||
| 450 | |||
| 451 | LOG_DEBUG(Service_Mii, "called"); | 247 | LOG_DEBUG(Service_Mii, "called"); |
| 452 | 248 | ||
| 453 | s32 index{}; | 249 | R_RETURN(manager->GetIndex(metadata, char_info, *out_index)); |
| 454 | const auto result = manager->GetIndex(metadata, info, index); | ||
| 455 | |||
| 456 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 457 | rb.Push(result); | ||
| 458 | rb.Push(index); | ||
| 459 | } | 250 | } |
| 460 | 251 | ||
| 461 | void SetInterfaceVersion(HLERequestContext& ctx) { | 252 | Result SetInterfaceVersion(u32 interface_version) { |
| 462 | IPC::RequestParser rp{ctx}; | ||
| 463 | const auto interface_version{rp.PopRaw<u32>()}; | ||
| 464 | |||
| 465 | LOG_INFO(Service_Mii, "called, interface_version={:08X}", interface_version); | 253 | LOG_INFO(Service_Mii, "called, interface_version={:08X}", interface_version); |
| 466 | 254 | ||
| 467 | manager->SetInterfaceVersion(metadata, interface_version); | 255 | manager->SetInterfaceVersion(metadata, interface_version); |
| 468 | 256 | ||
| 469 | IPC::ResponseBuilder rb{ctx, 2}; | 257 | R_SUCCEED(); |
| 470 | rb.Push(ResultSuccess); | ||
| 471 | } | 258 | } |
| 472 | 259 | ||
| 473 | void Convert(HLERequestContext& ctx) { | 260 | Result Convert(Out<CharInfo> out_char_info, Ver3StoreData& mii_v3) { |
| 474 | IPC::RequestParser rp{ctx}; | ||
| 475 | const auto mii_v3{rp.PopRaw<Ver3StoreData>()}; | ||
| 476 | |||
| 477 | LOG_INFO(Service_Mii, "called"); | 261 | LOG_INFO(Service_Mii, "called"); |
| 478 | 262 | ||
| 479 | CharInfo char_info{}; | 263 | R_RETURN(manager->ConvertV3ToCharInfo(*out_char_info, mii_v3)); |
| 480 | const auto result = manager->ConvertV3ToCharInfo(char_info, mii_v3); | ||
| 481 | |||
| 482 | IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)}; | ||
| 483 | rb.Push(result); | ||
| 484 | rb.PushRaw<CharInfo>(char_info); | ||
| 485 | } | 264 | } |
| 486 | 265 | ||
| 487 | void ConvertCoreDataToCharInfo(HLERequestContext& ctx) { | 266 | Result ConvertCoreDataToCharInfo(Out<CharInfo> out_char_info, CoreData& core_data) { |
| 488 | IPC::RequestParser rp{ctx}; | ||
| 489 | const auto core_data{rp.PopRaw<CoreData>()}; | ||
| 490 | |||
| 491 | LOG_INFO(Service_Mii, "called"); | 267 | LOG_INFO(Service_Mii, "called"); |
| 492 | 268 | ||
| 493 | CharInfo char_info{}; | 269 | R_RETURN(manager->ConvertCoreDataToCharInfo(*out_char_info, core_data)); |
| 494 | const auto result = manager->ConvertCoreDataToCharInfo(char_info, core_data); | ||
| 495 | |||
| 496 | IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)}; | ||
| 497 | rb.Push(result); | ||
| 498 | rb.PushRaw<CharInfo>(char_info); | ||
| 499 | } | 270 | } |
| 500 | 271 | ||
| 501 | void ConvertCharInfoToCoreData(HLERequestContext& ctx) { | 272 | Result ConvertCharInfoToCoreData(Out<CoreData> out_core_data, CharInfo& char_info) { |
| 502 | IPC::RequestParser rp{ctx}; | ||
| 503 | const auto char_info{rp.PopRaw<CharInfo>()}; | ||
| 504 | |||
| 505 | LOG_INFO(Service_Mii, "called"); | 273 | LOG_INFO(Service_Mii, "called"); |
| 506 | 274 | ||
| 507 | CoreData core_data{}; | 275 | R_RETURN(manager->ConvertCharInfoToCoreData(*out_core_data, char_info)); |
| 508 | const auto result = manager->ConvertCharInfoToCoreData(core_data, char_info); | ||
| 509 | |||
| 510 | IPC::ResponseBuilder rb{ctx, 2 + sizeof(CoreData) / sizeof(u32)}; | ||
| 511 | rb.Push(result); | ||
| 512 | rb.PushRaw<CoreData>(core_data); | ||
| 513 | } | 276 | } |
| 514 | 277 | ||
| 515 | void Append(HLERequestContext& ctx) { | 278 | Result Append(CharInfo& char_info) { |
| 516 | IPC::RequestParser rp{ctx}; | ||
| 517 | const auto char_info{rp.PopRaw<CharInfo>()}; | ||
| 518 | |||
| 519 | LOG_INFO(Service_Mii, "called"); | 279 | LOG_INFO(Service_Mii, "called"); |
| 520 | 280 | ||
| 521 | const auto result = manager->Append(metadata, char_info); | 281 | R_RETURN(manager->Append(metadata, char_info)); |
| 522 | |||
| 523 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 524 | rb.Push(result); | ||
| 525 | } | 282 | } |
| 526 | 283 | ||
| 527 | std::shared_ptr<MiiManager> manager = nullptr; | 284 | std::shared_ptr<MiiManager> manager = nullptr; |
| 528 | DatabaseSessionMetadata metadata{}; | 285 | DatabaseSessionMetadata metadata{}; |
| 529 | bool is_system{}; | 286 | bool is_system{}; |
| 287 | |||
| 288 | std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; | ||
| 530 | }; | 289 | }; |
| 531 | 290 | ||
| 532 | MiiDBModule::MiiDBModule(Core::System& system_, const char* name_, | 291 | IStaticService::IStaticService(Core::System& system_, const char* name_, |
| 533 | std::shared_ptr<MiiManager> mii_manager, bool is_system_) | 292 | std::shared_ptr<MiiManager> mii_manager, bool is_system_) |
| 534 | : ServiceFramework{system_, name_}, manager{mii_manager}, is_system{is_system_} { | 293 | : ServiceFramework{system_, name_}, manager{mii_manager}, is_system{is_system_} { |
| 535 | // clang-format off | 294 | // clang-format off |
| 536 | static const FunctionInfo functions[] = { | 295 | static const FunctionInfo functions[] = { |
| 537 | {0, &MiiDBModule::GetDatabaseService, "GetDatabaseService"}, | 296 | {0, D<&IStaticService::GetDatabaseService>, "GetDatabaseService"}, |
| 538 | }; | 297 | }; |
| 539 | // clang-format on | 298 | // clang-format on |
| 540 | 299 | ||
| 541 | RegisterHandlers(functions); | 300 | RegisterHandlers(functions); |
| 542 | |||
| 543 | if (manager == nullptr) { | ||
| 544 | manager = std::make_shared<MiiManager>(); | ||
| 545 | } | ||
| 546 | } | 301 | } |
| 547 | 302 | ||
| 548 | MiiDBModule::~MiiDBModule() = default; | 303 | IStaticService::~IStaticService() = default; |
| 549 | |||
| 550 | void MiiDBModule::GetDatabaseService(HLERequestContext& ctx) { | ||
| 551 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 552 | rb.Push(ResultSuccess); | ||
| 553 | rb.PushIpcInterface<IDatabaseService>(system, manager, is_system); | ||
| 554 | 304 | ||
| 305 | Result IStaticService::GetDatabaseService( | ||
| 306 | Out<SharedPointer<IDatabaseService>> out_database_service) { | ||
| 555 | LOG_DEBUG(Service_Mii, "called"); | 307 | LOG_DEBUG(Service_Mii, "called"); |
| 308 | |||
| 309 | *out_database_service = std::make_shared<IDatabaseService>(system, manager, is_system); | ||
| 310 | |||
| 311 | R_SUCCEED(); | ||
| 556 | } | 312 | } |
| 557 | 313 | ||
| 558 | std::shared_ptr<MiiManager> MiiDBModule::GetMiiManager() { | 314 | std::shared_ptr<MiiManager> IStaticService::GetMiiManager() { |
| 559 | return manager; | 315 | return manager; |
| 560 | } | 316 | } |
| 561 | 317 | ||
| 562 | class MiiImg final : public ServiceFramework<MiiImg> { | 318 | class IImageDatabaseService final : public ServiceFramework<IImageDatabaseService> { |
| 563 | public: | 319 | public: |
| 564 | explicit MiiImg(Core::System& system_) : ServiceFramework{system_, "miiimg"} { | 320 | explicit IImageDatabaseService(Core::System& system_) : ServiceFramework{system_, "miiimg"} { |
| 565 | // clang-format off | 321 | // clang-format off |
| 566 | static const FunctionInfo functions[] = { | 322 | static const FunctionInfo functions[] = { |
| 567 | {0, &MiiImg::Initialize, "Initialize"}, | 323 | {0, D<&IImageDatabaseService::Initialize>, "Initialize"}, |
| 568 | {10, nullptr, "Reload"}, | 324 | {10, nullptr, "Reload"}, |
| 569 | {11, &MiiImg::GetCount, "GetCount"}, | 325 | {11, D<&IImageDatabaseService::GetCount>, "GetCount"}, |
| 570 | {12, nullptr, "IsEmpty"}, | 326 | {12, nullptr, "IsEmpty"}, |
| 571 | {13, nullptr, "IsFull"}, | 327 | {13, nullptr, "IsFull"}, |
| 572 | {14, nullptr, "GetAttribute"}, | 328 | {14, nullptr, "GetAttribute"}, |
| @@ -585,31 +341,30 @@ public: | |||
| 585 | } | 341 | } |
| 586 | 342 | ||
| 587 | private: | 343 | private: |
| 588 | void Initialize(HLERequestContext& ctx) { | 344 | Result Initialize() { |
| 589 | LOG_INFO(Service_Mii, "called"); | 345 | LOG_INFO(Service_Mii, "called"); |
| 590 | 346 | ||
| 591 | IPC::ResponseBuilder rb{ctx, 2}; | 347 | R_SUCCEED(); |
| 592 | rb.Push(ResultSuccess); | ||
| 593 | } | 348 | } |
| 594 | 349 | ||
| 595 | void GetCount(HLERequestContext& ctx) { | 350 | Result GetCount(Out<u32> out_count) { |
| 596 | LOG_DEBUG(Service_Mii, "called"); | 351 | LOG_DEBUG(Service_Mii, "called"); |
| 597 | 352 | ||
| 598 | IPC::ResponseBuilder rb{ctx, 3}; | 353 | *out_count = 0; |
| 599 | rb.Push(ResultSuccess); | 354 | |
| 600 | rb.Push(0); | 355 | R_SUCCEED(); |
| 601 | } | 356 | } |
| 602 | }; | 357 | }; |
| 603 | 358 | ||
| 604 | void LoopProcess(Core::System& system) { | 359 | void LoopProcess(Core::System& system) { |
| 605 | auto server_manager = std::make_unique<ServerManager>(system); | 360 | auto server_manager = std::make_unique<ServerManager>(system); |
| 606 | std::shared_ptr<MiiManager> manager = nullptr; | 361 | std::shared_ptr<MiiManager> manager = std::make_shared<MiiManager>(); |
| 607 | 362 | ||
| 608 | server_manager->RegisterNamedService( | 363 | server_manager->RegisterNamedService( |
| 609 | "mii:e", std::make_shared<MiiDBModule>(system, "mii:e", manager, true)); | 364 | "mii:e", std::make_shared<IStaticService>(system, "mii:e", manager, true)); |
| 610 | server_manager->RegisterNamedService( | 365 | server_manager->RegisterNamedService( |
| 611 | "mii:u", std::make_shared<MiiDBModule>(system, "mii:u", manager, false)); | 366 | "mii:u", std::make_shared<IStaticService>(system, "mii:u", manager, false)); |
| 612 | server_manager->RegisterNamedService("miiimg", std::make_shared<MiiImg>(system)); | 367 | server_manager->RegisterNamedService("miiimg", std::make_shared<IImageDatabaseService>(system)); |
| 613 | ServerManager::RunServer(std::move(server_manager)); | 368 | ServerManager::RunServer(std::move(server_manager)); |
| 614 | } | 369 | } |
| 615 | 370 | ||
diff --git a/src/core/hle/service/mii/mii.h b/src/core/hle/service/mii/mii.h index 9aa4426f6..8683ac1a5 100644 --- a/src/core/hle/service/mii/mii.h +++ b/src/core/hle/service/mii/mii.h | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "core/hle/service/service.h" | 6 | #include "core/hle/service/cmif_types.h" |
| 7 | 7 | ||
| 8 | namespace Core { | 8 | namespace Core { |
| 9 | class System; | 9 | class System; |
| @@ -11,19 +11,20 @@ class System; | |||
| 11 | 11 | ||
| 12 | namespace Service::Mii { | 12 | namespace Service::Mii { |
| 13 | class MiiManager; | 13 | class MiiManager; |
| 14 | class IDatabaseService; | ||
| 14 | 15 | ||
| 15 | class MiiDBModule final : public ServiceFramework<MiiDBModule> { | 16 | class IStaticService final : public ServiceFramework<IStaticService> { |
| 16 | public: | 17 | public: |
| 17 | explicit MiiDBModule(Core::System& system_, const char* name_, | 18 | explicit IStaticService(Core::System& system_, const char* name_, |
| 18 | std::shared_ptr<MiiManager> mii_manager, bool is_system_); | 19 | std::shared_ptr<MiiManager> mii_manager, bool is_system_); |
| 19 | ~MiiDBModule() override; | 20 | ~IStaticService() override; |
| 20 | 21 | ||
| 21 | std::shared_ptr<MiiManager> GetMiiManager(); | 22 | std::shared_ptr<MiiManager> GetMiiManager(); |
| 22 | 23 | ||
| 23 | private: | 24 | private: |
| 24 | void GetDatabaseService(HLERequestContext& ctx); | 25 | Result GetDatabaseService(Out<SharedPointer<IDatabaseService>> out_database_service); |
| 25 | 26 | ||
| 26 | std::shared_ptr<MiiManager> manager = nullptr; | 27 | std::shared_ptr<MiiManager> manager{nullptr}; |
| 27 | bool is_system{}; | 28 | bool is_system{}; |
| 28 | }; | 29 | }; |
| 29 | 30 | ||
diff --git a/src/core/hle/service/set/setting_formats/system_settings.cpp b/src/core/hle/service/set/setting_formats/system_settings.cpp index 88a305f03..7231ff78e 100644 --- a/src/core/hle/service/set/setting_formats/system_settings.cpp +++ b/src/core/hle/service/set/setting_formats/system_settings.cpp | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "common/settings.h" | ||
| 4 | #include "core/hle/service/set/setting_formats/system_settings.h" | 5 | #include "core/hle/service/set/setting_formats/system_settings.h" |
| 5 | 6 | ||
| 6 | namespace Service::Set { | 7 | namespace Service::Set { |
| @@ -44,7 +45,7 @@ SystemSettings DefaultSystemSettings() { | |||
| 44 | .console_sleep_plan = ConsoleSleepPlan::Sleep1Hour, | 45 | .console_sleep_plan = ConsoleSleepPlan::Sleep1Hour, |
| 45 | }; | 46 | }; |
| 46 | 47 | ||
| 47 | settings.device_time_zone_location_name = {"UTC"}; | 48 | settings.device_time_zone_location_name = Service::PSC::Time::LocationName{"UTC"}; |
| 48 | settings.user_system_clock_automatic_correction_enabled = true; | 49 | settings.user_system_clock_automatic_correction_enabled = true; |
| 49 | 50 | ||
| 50 | settings.primary_album_storage = PrimaryAlbumStorage::SdCard; | 51 | settings.primary_album_storage = PrimaryAlbumStorage::SdCard; |
| @@ -52,6 +53,17 @@ SystemSettings DefaultSystemSettings() { | |||
| 52 | settings.chinese_traditional_input_method = ChineseTraditionalInputMethod::Unknown0; | 53 | settings.chinese_traditional_input_method = ChineseTraditionalInputMethod::Unknown0; |
| 53 | settings.vibration_master_volume = 1.0f; | 54 | settings.vibration_master_volume = 1.0f; |
| 54 | 55 | ||
| 56 | const auto language_code = | ||
| 57 | available_language_codes[static_cast<s32>(::Settings::values.language_index.GetValue())]; | ||
| 58 | const auto key_code = | ||
| 59 | std::find_if(language_to_layout.cbegin(), language_to_layout.cend(), | ||
| 60 | [=](const auto& element) { return element.first == language_code; }); | ||
| 61 | |||
| 62 | settings.keyboard_layout = KeyboardLayout::EnglishUs; | ||
| 63 | if (key_code != language_to_layout.end()) { | ||
| 64 | settings.keyboard_layout = key_code->second; | ||
| 65 | } | ||
| 66 | |||
| 55 | return settings; | 67 | return settings; |
| 56 | } | 68 | } |
| 57 | 69 | ||
diff --git a/src/core/hle/service/set/setting_formats/system_settings.h b/src/core/hle/service/set/setting_formats/system_settings.h index af5929fa9..ebc373da5 100644 --- a/src/core/hle/service/set/setting_formats/system_settings.h +++ b/src/core/hle/service/set/setting_formats/system_settings.h | |||
| @@ -213,10 +213,9 @@ struct SystemSettings { | |||
| 213 | // nn::settings::system::AudioVolume | 213 | // nn::settings::system::AudioVolume |
| 214 | std::array<u8, 0x8> audio_volume_type0; | 214 | std::array<u8, 0x8> audio_volume_type0; |
| 215 | std::array<u8, 0x8> audio_volume_type1; | 215 | std::array<u8, 0x8> audio_volume_type1; |
| 216 | // nn::settings::system::AudioOutputMode | 216 | AudioOutputMode audio_output_mode_hdmi; |
| 217 | s32 audio_output_mode_type0; | 217 | AudioOutputMode audio_output_mode_speaker; |
| 218 | s32 audio_output_mode_type1; | 218 | AudioOutputMode audio_output_mode_headphone; |
| 219 | s32 audio_output_mode_type2; | ||
| 220 | bool force_mute_on_headphone_removed; | 219 | bool force_mute_on_headphone_removed; |
| 221 | INSERT_PADDING_BYTES(0x3); | 220 | INSERT_PADDING_BYTES(0x3); |
| 222 | s32 headphone_volume_warning_count; | 221 | s32 headphone_volume_warning_count; |
| @@ -224,9 +223,8 @@ struct SystemSettings { | |||
| 224 | INSERT_PADDING_BYTES(0x3); | 223 | INSERT_PADDING_BYTES(0x3); |
| 225 | // nn::settings::system::AudioVolume | 224 | // nn::settings::system::AudioVolume |
| 226 | std::array<u8, 0x8> audio_volume_type2; | 225 | std::array<u8, 0x8> audio_volume_type2; |
| 227 | // nn::settings::system::AudioOutputMode | 226 | AudioOutputMode audio_output_mode_type3; |
| 228 | s32 audio_output_mode_type3; | 227 | AudioOutputMode audio_output_mode_type4; |
| 229 | s32 audio_output_mode_type4; | ||
| 230 | bool hearing_protection_safeguard_flag; | 228 | bool hearing_protection_safeguard_flag; |
| 231 | INSERT_PADDING_BYTES(0x3); | 229 | INSERT_PADDING_BYTES(0x3); |
| 232 | INSERT_PADDING_BYTES(0x4); // Reserved | 230 | INSERT_PADDING_BYTES(0x4); // Reserved |
diff --git a/src/core/hle/service/set/settings_types.h b/src/core/hle/service/set/settings_types.h index 968425319..ceb85b82a 100644 --- a/src/core/hle/service/set/settings_types.h +++ b/src/core/hle/service/set/settings_types.h | |||
| @@ -23,9 +23,12 @@ enum class AudioOutputMode : u32 { | |||
| 23 | 23 | ||
| 24 | /// This is nn::settings::system::AudioOutputModeTarget | 24 | /// This is nn::settings::system::AudioOutputModeTarget |
| 25 | enum class AudioOutputModeTarget : u32 { | 25 | enum class AudioOutputModeTarget : u32 { |
| 26 | None, | ||
| 26 | Hdmi, | 27 | Hdmi, |
| 27 | Speaker, | 28 | Speaker, |
| 28 | Headphone, | 29 | Headphone, |
| 30 | Type3, | ||
| 31 | Type4, | ||
| 29 | }; | 32 | }; |
| 30 | 33 | ||
| 31 | /// This is nn::settings::system::AudioVolumeTarget | 34 | /// This is nn::settings::system::AudioVolumeTarget |
| @@ -367,6 +370,12 @@ struct AccountNotificationSettings { | |||
| 367 | static_assert(sizeof(AccountNotificationSettings) == 0x18, | 370 | static_assert(sizeof(AccountNotificationSettings) == 0x18, |
| 368 | "AccountNotificationSettings is an invalid size"); | 371 | "AccountNotificationSettings is an invalid size"); |
| 369 | 372 | ||
| 373 | /// This is nn::settings::factory::BatteryLot | ||
| 374 | struct BatteryLot { | ||
| 375 | std::array<char, 0x18> lot_number; | ||
| 376 | }; | ||
| 377 | static_assert(sizeof(BatteryLot) == 0x18, "BatteryLot is an invalid size"); | ||
| 378 | |||
| 370 | /// This is nn::settings::system::EulaVersion | 379 | /// This is nn::settings::system::EulaVersion |
| 371 | struct EulaVersion { | 380 | struct EulaVersion { |
| 372 | u32 version; | 381 | u32 version; |
| @@ -436,6 +445,12 @@ struct NotificationSettings { | |||
| 436 | }; | 445 | }; |
| 437 | static_assert(sizeof(NotificationSettings) == 0x18, "NotificationSettings is an invalid size"); | 446 | static_assert(sizeof(NotificationSettings) == 0x18, "NotificationSettings is an invalid size"); |
| 438 | 447 | ||
| 448 | /// This is nn::settings::factory::SerialNumber | ||
| 449 | struct SerialNumber { | ||
| 450 | std::array<char, 0x18> serial_number; | ||
| 451 | }; | ||
| 452 | static_assert(sizeof(SerialNumber) == 0x18, "SerialNumber is an invalid size"); | ||
| 453 | |||
| 439 | /// This is nn::settings::system::SleepSettings | 454 | /// This is nn::settings::system::SleepSettings |
| 440 | struct SleepSettings { | 455 | struct SleepSettings { |
| 441 | SleepFlag flags; | 456 | SleepFlag flags; |
diff --git a/src/core/hle/service/set/system_settings_server.cpp b/src/core/hle/service/set/system_settings_server.cpp index e907b57b6..100cb2db4 100644 --- a/src/core/hle/service/set/system_settings_server.cpp +++ b/src/core/hle/service/set/system_settings_server.cpp | |||
| @@ -25,7 +25,7 @@ | |||
| 25 | namespace Service::Set { | 25 | namespace Service::Set { |
| 26 | 26 | ||
| 27 | namespace { | 27 | namespace { |
| 28 | constexpr u32 SETTINGS_VERSION{1u}; | 28 | constexpr u32 SETTINGS_VERSION{2u}; |
| 29 | constexpr auto SETTINGS_MAGIC = Common::MakeMagic('y', 'u', 'z', 'u', '_', 's', 'e', 't'); | 29 | constexpr auto SETTINGS_MAGIC = Common::MakeMagic('y', 'u', 'z', 'u', '_', 's', 'e', 't'); |
| 30 | struct SettingsHeader { | 30 | struct SettingsHeader { |
| 31 | u64 magic; | 31 | u64 magic; |
| @@ -131,10 +131,10 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) | |||
| 131 | {40, &ISystemSettingsServer::SetTvSettings, "SetTvSettings"}, | 131 | {40, &ISystemSettingsServer::SetTvSettings, "SetTvSettings"}, |
| 132 | {41, nullptr, "GetEdid"}, | 132 | {41, nullptr, "GetEdid"}, |
| 133 | {42, nullptr, "SetEdid"}, | 133 | {42, nullptr, "SetEdid"}, |
| 134 | {43, nullptr, "GetAudioOutputMode"}, | 134 | {43, &ISystemSettingsServer::GetAudioOutputMode, "GetAudioOutputMode"}, |
| 135 | {44, nullptr, "SetAudioOutputMode"}, | 135 | {44, &ISystemSettingsServer::SetAudioOutputMode, "SetAudioOutputMode"}, |
| 136 | {45, &ISystemSettingsServer::IsForceMuteOnHeadphoneRemoved, "IsForceMuteOnHeadphoneRemoved"}, | 136 | {45, &ISystemSettingsServer::GetSpeakerAutoMuteFlag , "GetSpeakerAutoMuteFlag"}, |
| 137 | {46, &ISystemSettingsServer::SetForceMuteOnHeadphoneRemoved, "SetForceMuteOnHeadphoneRemoved"}, | 137 | {46, &ISystemSettingsServer::SetSpeakerAutoMuteFlag , "SetSpeakerAutoMuteFlag"}, |
| 138 | {47, &ISystemSettingsServer::GetQuestFlag, "GetQuestFlag"}, | 138 | {47, &ISystemSettingsServer::GetQuestFlag, "GetQuestFlag"}, |
| 139 | {48, &ISystemSettingsServer::SetQuestFlag, "SetQuestFlag"}, | 139 | {48, &ISystemSettingsServer::SetQuestFlag, "SetQuestFlag"}, |
| 140 | {49, nullptr, "GetDataDeletionSettings"}, | 140 | {49, nullptr, "GetDataDeletionSettings"}, |
| @@ -155,8 +155,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) | |||
| 155 | {64, &ISystemSettingsServer::SetPrimaryAlbumStorage, "SetPrimaryAlbumStorage"}, | 155 | {64, &ISystemSettingsServer::SetPrimaryAlbumStorage, "SetPrimaryAlbumStorage"}, |
| 156 | {65, nullptr, "GetUsb30EnableFlag"}, | 156 | {65, nullptr, "GetUsb30EnableFlag"}, |
| 157 | {66, nullptr, "SetUsb30EnableFlag"}, | 157 | {66, nullptr, "SetUsb30EnableFlag"}, |
| 158 | {67, nullptr, "GetBatteryLot"}, | 158 | {67, &ISystemSettingsServer::GetBatteryLot, "GetBatteryLot"}, |
| 159 | {68, nullptr, "GetSerialNumber"}, | 159 | {68, &ISystemSettingsServer::GetSerialNumber, "GetSerialNumber"}, |
| 160 | {69, &ISystemSettingsServer::GetNfcEnableFlag, "GetNfcEnableFlag"}, | 160 | {69, &ISystemSettingsServer::GetNfcEnableFlag, "GetNfcEnableFlag"}, |
| 161 | {70, &ISystemSettingsServer::SetNfcEnableFlag, "SetNfcEnableFlag"}, | 161 | {70, &ISystemSettingsServer::SetNfcEnableFlag, "SetNfcEnableFlag"}, |
| 162 | {71, &ISystemSettingsServer::GetSleepSettings, "GetSleepSettings"}, | 162 | {71, &ISystemSettingsServer::GetSleepSettings, "GetSleepSettings"}, |
| @@ -184,11 +184,11 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) | |||
| 184 | {93, nullptr, "AcquireFatalDirtyFlagEventHandle"}, | 184 | {93, nullptr, "AcquireFatalDirtyFlagEventHandle"}, |
| 185 | {94, nullptr, "GetFatalDirtyFlags"}, | 185 | {94, nullptr, "GetFatalDirtyFlags"}, |
| 186 | {95, &ISystemSettingsServer::GetAutoUpdateEnableFlag, "GetAutoUpdateEnableFlag"}, | 186 | {95, &ISystemSettingsServer::GetAutoUpdateEnableFlag, "GetAutoUpdateEnableFlag"}, |
| 187 | {96, nullptr, "SetAutoUpdateEnableFlag"}, | 187 | {96, &ISystemSettingsServer::SetAutoUpdateEnableFlag, "SetAutoUpdateEnableFlag"}, |
| 188 | {97, nullptr, "GetNxControllerSettings"}, | 188 | {97, nullptr, "GetNxControllerSettings"}, |
| 189 | {98, nullptr, "SetNxControllerSettings"}, | 189 | {98, nullptr, "SetNxControllerSettings"}, |
| 190 | {99, &ISystemSettingsServer::GetBatteryPercentageFlag, "GetBatteryPercentageFlag"}, | 190 | {99, &ISystemSettingsServer::GetBatteryPercentageFlag, "GetBatteryPercentageFlag"}, |
| 191 | {100, nullptr, "SetBatteryPercentageFlag"}, | 191 | {100, &ISystemSettingsServer::SetBatteryPercentageFlag, "SetBatteryPercentageFlag"}, |
| 192 | {101, nullptr, "GetExternalRtcResetFlag"}, | 192 | {101, nullptr, "GetExternalRtcResetFlag"}, |
| 193 | {102, nullptr, "SetExternalRtcResetFlag"}, | 193 | {102, nullptr, "SetExternalRtcResetFlag"}, |
| 194 | {103, nullptr, "GetUsbFullKeyEnableFlag"}, | 194 | {103, nullptr, "GetUsbFullKeyEnableFlag"}, |
| @@ -208,12 +208,12 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) | |||
| 208 | {117, nullptr, "GetHeadphoneVolumeUpdateFlag"}, | 208 | {117, nullptr, "GetHeadphoneVolumeUpdateFlag"}, |
| 209 | {118, nullptr, "SetHeadphoneVolumeUpdateFlag"}, | 209 | {118, nullptr, "SetHeadphoneVolumeUpdateFlag"}, |
| 210 | {119, nullptr, "NeedsToUpdateHeadphoneVolume"}, | 210 | {119, nullptr, "NeedsToUpdateHeadphoneVolume"}, |
| 211 | {120, nullptr, "GetPushNotificationActivityModeOnSleep"}, | 211 | {120, &ISystemSettingsServer::GetPushNotificationActivityModeOnSleep, "GetPushNotificationActivityModeOnSleep"}, |
| 212 | {121, nullptr, "SetPushNotificationActivityModeOnSleep"}, | 212 | {121, &ISystemSettingsServer::SetPushNotificationActivityModeOnSleep, "SetPushNotificationActivityModeOnSleep"}, |
| 213 | {122, nullptr, "GetServiceDiscoveryControlSettings"}, | 213 | {122, nullptr, "GetServiceDiscoveryControlSettings"}, |
| 214 | {123, nullptr, "SetServiceDiscoveryControlSettings"}, | 214 | {123, nullptr, "SetServiceDiscoveryControlSettings"}, |
| 215 | {124, &ISystemSettingsServer::GetErrorReportSharePermission, "GetErrorReportSharePermission"}, | 215 | {124, &ISystemSettingsServer::GetErrorReportSharePermission, "GetErrorReportSharePermission"}, |
| 216 | {125, nullptr, "SetErrorReportSharePermission"}, | 216 | {125, &ISystemSettingsServer::SetErrorReportSharePermission, "SetErrorReportSharePermission"}, |
| 217 | {126, &ISystemSettingsServer::GetAppletLaunchFlags, "GetAppletLaunchFlags"}, | 217 | {126, &ISystemSettingsServer::GetAppletLaunchFlags, "GetAppletLaunchFlags"}, |
| 218 | {127, &ISystemSettingsServer::SetAppletLaunchFlags, "SetAppletLaunchFlags"}, | 218 | {127, &ISystemSettingsServer::SetAppletLaunchFlags, "SetAppletLaunchFlags"}, |
| 219 | {128, nullptr, "GetConsoleSixAxisSensorAccelerationBias"}, | 219 | {128, nullptr, "GetConsoleSixAxisSensorAccelerationBias"}, |
| @@ -225,7 +225,7 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) | |||
| 225 | {134, nullptr, "GetConsoleSixAxisSensorAngularVelocityGain"}, | 225 | {134, nullptr, "GetConsoleSixAxisSensorAngularVelocityGain"}, |
| 226 | {135, nullptr, "SetConsoleSixAxisSensorAngularVelocityGain"}, | 226 | {135, nullptr, "SetConsoleSixAxisSensorAngularVelocityGain"}, |
| 227 | {136, &ISystemSettingsServer::GetKeyboardLayout, "GetKeyboardLayout"}, | 227 | {136, &ISystemSettingsServer::GetKeyboardLayout, "GetKeyboardLayout"}, |
| 228 | {137, nullptr, "SetKeyboardLayout"}, | 228 | {137, &ISystemSettingsServer::SetKeyboardLayout, "SetKeyboardLayout"}, |
| 229 | {138, nullptr, "GetWebInspectorFlag"}, | 229 | {138, nullptr, "GetWebInspectorFlag"}, |
| 230 | {139, nullptr, "GetAllowedSslHosts"}, | 230 | {139, nullptr, "GetAllowedSslHosts"}, |
| 231 | {140, nullptr, "GetHostFsMountPoint"}, | 231 | {140, nullptr, "GetHostFsMountPoint"}, |
| @@ -291,8 +291,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) | |||
| 291 | {200, nullptr, "SetButtonConfigRegisteredSettings"}, | 291 | {200, nullptr, "SetButtonConfigRegisteredSettings"}, |
| 292 | {201, &ISystemSettingsServer::GetFieldTestingFlag, "GetFieldTestingFlag"}, | 292 | {201, &ISystemSettingsServer::GetFieldTestingFlag, "GetFieldTestingFlag"}, |
| 293 | {202, nullptr, "SetFieldTestingFlag"}, | 293 | {202, nullptr, "SetFieldTestingFlag"}, |
| 294 | {203, nullptr, "GetPanelCrcMode"}, | 294 | {203, &ISystemSettingsServer::GetPanelCrcMode, "GetPanelCrcMode"}, |
| 295 | {204, nullptr, "SetPanelCrcMode"}, | 295 | {204, &ISystemSettingsServer::SetPanelCrcMode, "SetPanelCrcMode"}, |
| 296 | {205, nullptr, "GetNxControllerSettingsEx"}, | 296 | {205, nullptr, "GetNxControllerSettingsEx"}, |
| 297 | {206, nullptr, "SetNxControllerSettingsEx"}, | 297 | {206, nullptr, "SetNxControllerSettingsEx"}, |
| 298 | {207, nullptr, "GetHearingProtectionSafeguardFlag"}, | 298 | {207, nullptr, "GetHearingProtectionSafeguardFlag"}, |
| @@ -349,7 +349,7 @@ bool ISystemSettingsServer::LoadSettingsFile(std::filesystem::path& path, auto&& | |||
| 349 | } | 349 | } |
| 350 | SettingsHeader hdr{}; | 350 | SettingsHeader hdr{}; |
| 351 | file.read(reinterpret_cast<char*>(&hdr), sizeof(hdr)); | 351 | file.read(reinterpret_cast<char*>(&hdr), sizeof(hdr)); |
| 352 | return hdr.magic == SETTINGS_MAGIC && hdr.version == SETTINGS_VERSION; | 352 | return hdr.magic == SETTINGS_MAGIC && hdr.version >= SETTINGS_VERSION; |
| 353 | }; | 353 | }; |
| 354 | 354 | ||
| 355 | if (!exists || !file_size_ok) { | 355 | if (!exists || !file_size_ok) { |
| @@ -390,7 +390,7 @@ bool ISystemSettingsServer::StoreSettingsFile(std::filesystem::path& path, auto& | |||
| 390 | } | 390 | } |
| 391 | 391 | ||
| 392 | auto settings_base = path / "settings"; | 392 | auto settings_base = path / "settings"; |
| 393 | auto settings_tmp_file = settings_base; | 393 | std::filesystem::path settings_tmp_file = settings_base; |
| 394 | settings_tmp_file = settings_tmp_file.replace_extension("tmp"); | 394 | settings_tmp_file = settings_tmp_file.replace_extension("tmp"); |
| 395 | std::ofstream file(settings_tmp_file, std::ios::binary | std::ios::out); | 395 | std::ofstream file(settings_tmp_file, std::ios::binary | std::ios::out); |
| 396 | if (!file.is_open()) { | 396 | if (!file.is_open()) { |
| @@ -722,6 +722,9 @@ static Settings GetSettings() { | |||
| 722 | ret["hid_debug"]["disabled_features_per_id"] = std::vector<u8>(0xa8); | 722 | ret["hid_debug"]["disabled_features_per_id"] = std::vector<u8>(0xa8); |
| 723 | ret["hid_debug"]["touch_firmware_auto_update_disabled"] = ToBytes(bool{false}); | 723 | ret["hid_debug"]["touch_firmware_auto_update_disabled"] = ToBytes(bool{false}); |
| 724 | 724 | ||
| 725 | // Mii | ||
| 726 | ret["mii"]["is_db_test_mode_enabled"] = ToBytes(bool{false}); | ||
| 727 | |||
| 725 | // Settings | 728 | // Settings |
| 726 | ret["settings_debug"]["is_debug_mode_enabled"] = ToBytes(bool{false}); | 729 | ret["settings_debug"]["is_debug_mode_enabled"] = ToBytes(bool{false}); |
| 727 | 730 | ||
| @@ -814,7 +817,34 @@ void ISystemSettingsServer::SetTvSettings(HLERequestContext& ctx) { | |||
| 814 | rb.Push(ResultSuccess); | 817 | rb.Push(ResultSuccess); |
| 815 | } | 818 | } |
| 816 | 819 | ||
| 817 | void ISystemSettingsServer::IsForceMuteOnHeadphoneRemoved(HLERequestContext& ctx) { | 820 | void ISystemSettingsServer::GetAudioOutputMode(HLERequestContext& ctx) { |
| 821 | IPC::RequestParser rp{ctx}; | ||
| 822 | const auto target{rp.PopEnum<AudioOutputModeTarget>()}; | ||
| 823 | |||
| 824 | AudioOutputMode output_mode{}; | ||
| 825 | const auto result = GetAudioOutputMode(output_mode, target); | ||
| 826 | |||
| 827 | LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode); | ||
| 828 | |||
| 829 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 830 | rb.Push(result); | ||
| 831 | rb.PushEnum(output_mode); | ||
| 832 | } | ||
| 833 | |||
| 834 | void ISystemSettingsServer::SetAudioOutputMode(HLERequestContext& ctx) { | ||
| 835 | IPC::RequestParser rp{ctx}; | ||
| 836 | const auto target{rp.PopEnum<AudioOutputModeTarget>()}; | ||
| 837 | const auto output_mode{rp.PopEnum<AudioOutputMode>()}; | ||
| 838 | |||
| 839 | const auto result = SetAudioOutputMode(target, output_mode); | ||
| 840 | |||
| 841 | LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode); | ||
| 842 | |||
| 843 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 844 | rb.Push(result); | ||
| 845 | } | ||
| 846 | |||
| 847 | void ISystemSettingsServer::GetSpeakerAutoMuteFlag(HLERequestContext& ctx) { | ||
| 818 | LOG_INFO(Service_SET, "called, force_mute_on_headphone_removed={}", | 848 | LOG_INFO(Service_SET, "called, force_mute_on_headphone_removed={}", |
| 819 | m_system_settings.force_mute_on_headphone_removed); | 849 | m_system_settings.force_mute_on_headphone_removed); |
| 820 | 850 | ||
| @@ -823,7 +853,7 @@ void ISystemSettingsServer::IsForceMuteOnHeadphoneRemoved(HLERequestContext& ctx | |||
| 823 | rb.PushRaw(m_system_settings.force_mute_on_headphone_removed); | 853 | rb.PushRaw(m_system_settings.force_mute_on_headphone_removed); |
| 824 | } | 854 | } |
| 825 | 855 | ||
| 826 | void ISystemSettingsServer::SetForceMuteOnHeadphoneRemoved(HLERequestContext& ctx) { | 856 | void ISystemSettingsServer::SetSpeakerAutoMuteFlag(HLERequestContext& ctx) { |
| 827 | IPC::RequestParser rp{ctx}; | 857 | IPC::RequestParser rp{ctx}; |
| 828 | m_system_settings.force_mute_on_headphone_removed = rp.PopRaw<bool>(); | 858 | m_system_settings.force_mute_on_headphone_removed = rp.PopRaw<bool>(); |
| 829 | SetSaveNeeded(); | 859 | SetSaveNeeded(); |
| @@ -966,6 +996,26 @@ void ISystemSettingsServer::SetPrimaryAlbumStorage(HLERequestContext& ctx) { | |||
| 966 | rb.Push(ResultSuccess); | 996 | rb.Push(ResultSuccess); |
| 967 | } | 997 | } |
| 968 | 998 | ||
| 999 | void ISystemSettingsServer::GetBatteryLot(HLERequestContext& ctx) { | ||
| 1000 | BatteryLot battery_lot = {"YUZUEMULATOR123456789"}; | ||
| 1001 | |||
| 1002 | LOG_INFO(Service_SET, "called"); | ||
| 1003 | |||
| 1004 | IPC::ResponseBuilder rb{ctx, 8}; | ||
| 1005 | rb.Push(ResultSuccess); | ||
| 1006 | rb.PushRaw(battery_lot); | ||
| 1007 | } | ||
| 1008 | |||
| 1009 | void ISystemSettingsServer::GetSerialNumber(HLERequestContext& ctx) { | ||
| 1010 | SerialNumber console_serial = {"YUZ10012345678"}; | ||
| 1011 | |||
| 1012 | LOG_INFO(Service_SET, "called"); | ||
| 1013 | |||
| 1014 | IPC::ResponseBuilder rb{ctx, 8}; | ||
| 1015 | rb.Push(ResultSuccess); | ||
| 1016 | rb.PushRaw(console_serial); | ||
| 1017 | } | ||
| 1018 | |||
| 969 | void ISystemSettingsServer::GetNfcEnableFlag(HLERequestContext& ctx) { | 1019 | void ISystemSettingsServer::GetNfcEnableFlag(HLERequestContext& ctx) { |
| 970 | LOG_INFO(Service_SET, "called, nfc_enable_flag={}", m_system_settings.nfc_enable_flag); | 1020 | LOG_INFO(Service_SET, "called, nfc_enable_flag={}", m_system_settings.nfc_enable_flag); |
| 971 | 1021 | ||
| @@ -1129,6 +1179,17 @@ void ISystemSettingsServer::GetAutoUpdateEnableFlag(HLERequestContext& ctx) { | |||
| 1129 | rb.Push(m_system_settings.auto_update_enable_flag); | 1179 | rb.Push(m_system_settings.auto_update_enable_flag); |
| 1130 | } | 1180 | } |
| 1131 | 1181 | ||
| 1182 | void ISystemSettingsServer::SetAutoUpdateEnableFlag(HLERequestContext& ctx) { | ||
| 1183 | IPC::RequestParser rp{ctx}; | ||
| 1184 | m_system_settings.auto_update_enable_flag = rp.Pop<bool>(); | ||
| 1185 | SetSaveNeeded(); | ||
| 1186 | |||
| 1187 | LOG_INFO(Service_SET, "called, auto_update_flag={}", m_system_settings.auto_update_enable_flag); | ||
| 1188 | |||
| 1189 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1190 | rb.Push(ResultSuccess); | ||
| 1191 | } | ||
| 1192 | |||
| 1132 | void ISystemSettingsServer::GetBatteryPercentageFlag(HLERequestContext& ctx) { | 1193 | void ISystemSettingsServer::GetBatteryPercentageFlag(HLERequestContext& ctx) { |
| 1133 | LOG_DEBUG(Service_SET, "called, battery_percentage_flag={}", | 1194 | LOG_DEBUG(Service_SET, "called, battery_percentage_flag={}", |
| 1134 | m_system_settings.battery_percentage_flag); | 1195 | m_system_settings.battery_percentage_flag); |
| @@ -1138,6 +1199,18 @@ void ISystemSettingsServer::GetBatteryPercentageFlag(HLERequestContext& ctx) { | |||
| 1138 | rb.Push(m_system_settings.battery_percentage_flag); | 1199 | rb.Push(m_system_settings.battery_percentage_flag); |
| 1139 | } | 1200 | } |
| 1140 | 1201 | ||
| 1202 | void ISystemSettingsServer::SetBatteryPercentageFlag(HLERequestContext& ctx) { | ||
| 1203 | IPC::RequestParser rp{ctx}; | ||
| 1204 | m_system_settings.battery_percentage_flag = rp.Pop<bool>(); | ||
| 1205 | SetSaveNeeded(); | ||
| 1206 | |||
| 1207 | LOG_INFO(Service_SET, "called, battery_percentage_flag={}", | ||
| 1208 | m_system_settings.battery_percentage_flag); | ||
| 1209 | |||
| 1210 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1211 | rb.Push(ResultSuccess); | ||
| 1212 | } | ||
| 1213 | |||
| 1141 | void ISystemSettingsServer::SetExternalSteadyClockInternalOffset(HLERequestContext& ctx) { | 1214 | void ISystemSettingsServer::SetExternalSteadyClockInternalOffset(HLERequestContext& ctx) { |
| 1142 | LOG_DEBUG(Service_SET, "called."); | 1215 | LOG_DEBUG(Service_SET, "called."); |
| 1143 | 1216 | ||
| @@ -1161,6 +1234,27 @@ void ISystemSettingsServer::GetExternalSteadyClockInternalOffset(HLERequestConte | |||
| 1161 | rb.Push(offset); | 1234 | rb.Push(offset); |
| 1162 | } | 1235 | } |
| 1163 | 1236 | ||
| 1237 | void ISystemSettingsServer::GetPushNotificationActivityModeOnSleep(HLERequestContext& ctx) { | ||
| 1238 | LOG_INFO(Service_SET, "called, push_notification_activity_mode_on_sleep={}", | ||
| 1239 | m_system_settings.push_notification_activity_mode_on_sleep); | ||
| 1240 | |||
| 1241 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 1242 | rb.Push(ResultSuccess); | ||
| 1243 | rb.Push(m_system_settings.push_notification_activity_mode_on_sleep); | ||
| 1244 | } | ||
| 1245 | |||
| 1246 | void ISystemSettingsServer::SetPushNotificationActivityModeOnSleep(HLERequestContext& ctx) { | ||
| 1247 | IPC::RequestParser rp{ctx}; | ||
| 1248 | m_system_settings.push_notification_activity_mode_on_sleep = rp.Pop<s32>(); | ||
| 1249 | SetSaveNeeded(); | ||
| 1250 | |||
| 1251 | LOG_INFO(Service_SET, "called, push_notification_activity_mode_on_sleep={}", | ||
| 1252 | m_system_settings.push_notification_activity_mode_on_sleep); | ||
| 1253 | |||
| 1254 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1255 | rb.Push(ResultSuccess); | ||
| 1256 | } | ||
| 1257 | |||
| 1164 | void ISystemSettingsServer::GetErrorReportSharePermission(HLERequestContext& ctx) { | 1258 | void ISystemSettingsServer::GetErrorReportSharePermission(HLERequestContext& ctx) { |
| 1165 | LOG_INFO(Service_SET, "called, error_report_share_permission={}", | 1259 | LOG_INFO(Service_SET, "called, error_report_share_permission={}", |
| 1166 | m_system_settings.error_report_share_permission); | 1260 | m_system_settings.error_report_share_permission); |
| @@ -1170,6 +1264,18 @@ void ISystemSettingsServer::GetErrorReportSharePermission(HLERequestContext& ctx | |||
| 1170 | rb.PushEnum(m_system_settings.error_report_share_permission); | 1264 | rb.PushEnum(m_system_settings.error_report_share_permission); |
| 1171 | } | 1265 | } |
| 1172 | 1266 | ||
| 1267 | void ISystemSettingsServer::SetErrorReportSharePermission(HLERequestContext& ctx) { | ||
| 1268 | IPC::RequestParser rp{ctx}; | ||
| 1269 | m_system_settings.error_report_share_permission = rp.PopEnum<ErrorReportSharePermission>(); | ||
| 1270 | SetSaveNeeded(); | ||
| 1271 | |||
| 1272 | LOG_INFO(Service_SET, "called, error_report_share_permission={}", | ||
| 1273 | m_system_settings.error_report_share_permission); | ||
| 1274 | |||
| 1275 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1276 | rb.Push(ResultSuccess); | ||
| 1277 | } | ||
| 1278 | |||
| 1173 | void ISystemSettingsServer::GetAppletLaunchFlags(HLERequestContext& ctx) { | 1279 | void ISystemSettingsServer::GetAppletLaunchFlags(HLERequestContext& ctx) { |
| 1174 | LOG_INFO(Service_SET, "called, applet_launch_flag={}", m_system_settings.applet_launch_flag); | 1280 | LOG_INFO(Service_SET, "called, applet_launch_flag={}", m_system_settings.applet_launch_flag); |
| 1175 | 1281 | ||
| @@ -1190,22 +1296,22 @@ void ISystemSettingsServer::SetAppletLaunchFlags(HLERequestContext& ctx) { | |||
| 1190 | } | 1296 | } |
| 1191 | 1297 | ||
| 1192 | void ISystemSettingsServer::GetKeyboardLayout(HLERequestContext& ctx) { | 1298 | void ISystemSettingsServer::GetKeyboardLayout(HLERequestContext& ctx) { |
| 1193 | const auto language_code = | 1299 | LOG_INFO(Service_SET, "called, keyboard_layout={}", m_system_settings.keyboard_layout); |
| 1194 | available_language_codes[static_cast<s32>(::Settings::values.language_index.GetValue())]; | ||
| 1195 | const auto key_code = | ||
| 1196 | std::find_if(language_to_layout.cbegin(), language_to_layout.cend(), | ||
| 1197 | [=](const auto& element) { return element.first == language_code; }); | ||
| 1198 | |||
| 1199 | KeyboardLayout selected_keyboard_layout = KeyboardLayout::EnglishUs; | ||
| 1200 | if (key_code != language_to_layout.end()) { | ||
| 1201 | selected_keyboard_layout = key_code->second; | ||
| 1202 | } | ||
| 1203 | |||
| 1204 | LOG_INFO(Service_SET, "called, selected_keyboard_layout={}", selected_keyboard_layout); | ||
| 1205 | 1300 | ||
| 1206 | IPC::ResponseBuilder rb{ctx, 3}; | 1301 | IPC::ResponseBuilder rb{ctx, 3}; |
| 1207 | rb.Push(ResultSuccess); | 1302 | rb.Push(ResultSuccess); |
| 1208 | rb.Push(static_cast<u32>(selected_keyboard_layout)); | 1303 | rb.Push(static_cast<u32>(m_system_settings.keyboard_layout)); |
| 1304 | } | ||
| 1305 | |||
| 1306 | void ISystemSettingsServer::SetKeyboardLayout(HLERequestContext& ctx) { | ||
| 1307 | IPC::RequestParser rp{ctx}; | ||
| 1308 | m_system_settings.keyboard_layout = rp.PopRaw<KeyboardLayout>(); | ||
| 1309 | SetSaveNeeded(); | ||
| 1310 | |||
| 1311 | LOG_INFO(Service_SET, "called, keyboard_layout={}", m_system_settings.keyboard_layout); | ||
| 1312 | |||
| 1313 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1314 | rb.Push(ResultSuccess); | ||
| 1209 | } | 1315 | } |
| 1210 | 1316 | ||
| 1211 | void ISystemSettingsServer::GetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx) { | 1317 | void ISystemSettingsServer::GetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx) { |
| @@ -1297,6 +1403,25 @@ void ISystemSettingsServer::GetFieldTestingFlag(HLERequestContext& ctx) { | |||
| 1297 | rb.Push(m_system_settings.field_testing_flag); | 1403 | rb.Push(m_system_settings.field_testing_flag); |
| 1298 | } | 1404 | } |
| 1299 | 1405 | ||
| 1406 | void ISystemSettingsServer::GetPanelCrcMode(HLERequestContext& ctx) { | ||
| 1407 | LOG_INFO(Service_SET, "called, panel_crc_mode={}", m_system_settings.panel_crc_mode); | ||
| 1408 | |||
| 1409 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 1410 | rb.Push(ResultSuccess); | ||
| 1411 | rb.Push(m_system_settings.panel_crc_mode); | ||
| 1412 | } | ||
| 1413 | |||
| 1414 | void ISystemSettingsServer::SetPanelCrcMode(HLERequestContext& ctx) { | ||
| 1415 | IPC::RequestParser rp{ctx}; | ||
| 1416 | m_system_settings.panel_crc_mode = rp.PopRaw<s32>(); | ||
| 1417 | SetSaveNeeded(); | ||
| 1418 | |||
| 1419 | LOG_INFO(Service_SET, "called, panel_crc_mode={}", m_system_settings.panel_crc_mode); | ||
| 1420 | |||
| 1421 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1422 | rb.Push(ResultSuccess); | ||
| 1423 | } | ||
| 1424 | |||
| 1300 | void ISystemSettingsServer::SetupSettings() { | 1425 | void ISystemSettingsServer::SetupSettings() { |
| 1301 | auto system_dir = | 1426 | auto system_dir = |
| 1302 | Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000050"; | 1427 | Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000050"; |
| @@ -1387,6 +1512,66 @@ Result ISystemSettingsServer::SetVibrationMasterVolume(f32 volume) { | |||
| 1387 | R_SUCCEED(); | 1512 | R_SUCCEED(); |
| 1388 | } | 1513 | } |
| 1389 | 1514 | ||
| 1515 | Result ISystemSettingsServer::GetAudioOutputMode(AudioOutputMode& out_output_mode, | ||
| 1516 | AudioOutputModeTarget target) const { | ||
| 1517 | switch (target) { | ||
| 1518 | case AudioOutputModeTarget::Hdmi: | ||
| 1519 | out_output_mode = m_system_settings.audio_output_mode_hdmi; | ||
| 1520 | break; | ||
| 1521 | case AudioOutputModeTarget::Speaker: | ||
| 1522 | out_output_mode = m_system_settings.audio_output_mode_speaker; | ||
| 1523 | break; | ||
| 1524 | case AudioOutputModeTarget::Headphone: | ||
| 1525 | out_output_mode = m_system_settings.audio_output_mode_headphone; | ||
| 1526 | break; | ||
| 1527 | case AudioOutputModeTarget::Type3: | ||
| 1528 | out_output_mode = m_system_settings.audio_output_mode_type3; | ||
| 1529 | break; | ||
| 1530 | case AudioOutputModeTarget::Type4: | ||
| 1531 | out_output_mode = m_system_settings.audio_output_mode_type4; | ||
| 1532 | break; | ||
| 1533 | default: | ||
| 1534 | LOG_ERROR(Service_SET, "Invalid audio output mode target {}", target); | ||
| 1535 | } | ||
| 1536 | R_SUCCEED(); | ||
| 1537 | } | ||
| 1538 | |||
| 1539 | Result ISystemSettingsServer::SetAudioOutputMode(AudioOutputModeTarget target, | ||
| 1540 | AudioOutputMode output_mode) { | ||
| 1541 | switch (target) { | ||
| 1542 | case AudioOutputModeTarget::Hdmi: | ||
| 1543 | m_system_settings.audio_output_mode_hdmi = output_mode; | ||
| 1544 | break; | ||
| 1545 | case AudioOutputModeTarget::Speaker: | ||
| 1546 | m_system_settings.audio_output_mode_speaker = output_mode; | ||
| 1547 | break; | ||
| 1548 | case AudioOutputModeTarget::Headphone: | ||
| 1549 | m_system_settings.audio_output_mode_headphone = output_mode; | ||
| 1550 | break; | ||
| 1551 | case AudioOutputModeTarget::Type3: | ||
| 1552 | m_system_settings.audio_output_mode_type3 = output_mode; | ||
| 1553 | break; | ||
| 1554 | case AudioOutputModeTarget::Type4: | ||
| 1555 | m_system_settings.audio_output_mode_type4 = output_mode; | ||
| 1556 | break; | ||
| 1557 | default: | ||
| 1558 | LOG_ERROR(Service_SET, "Invalid audio output mode target {}", target); | ||
| 1559 | } | ||
| 1560 | SetSaveNeeded(); | ||
| 1561 | R_SUCCEED(); | ||
| 1562 | } | ||
| 1563 | |||
| 1564 | Result ISystemSettingsServer::GetSpeakerAutoMuteFlag(bool& is_auto_mute) const { | ||
| 1565 | is_auto_mute = m_system_settings.force_mute_on_headphone_removed; | ||
| 1566 | R_SUCCEED(); | ||
| 1567 | } | ||
| 1568 | |||
| 1569 | Result ISystemSettingsServer::SetSpeakerAutoMuteFlag(bool is_auto_mute) { | ||
| 1570 | m_system_settings.force_mute_on_headphone_removed = is_auto_mute; | ||
| 1571 | SetSaveNeeded(); | ||
| 1572 | R_SUCCEED(); | ||
| 1573 | } | ||
| 1574 | |||
| 1390 | Result ISystemSettingsServer::GetExternalSteadyClockSourceId(Common::UUID& out_id) const { | 1575 | Result ISystemSettingsServer::GetExternalSteadyClockSourceId(Common::UUID& out_id) const { |
| 1391 | out_id = m_private_settings.external_clock_source_id; | 1576 | out_id = m_private_settings.external_clock_source_id; |
| 1392 | R_SUCCEED(); | 1577 | R_SUCCEED(); |
diff --git a/src/core/hle/service/set/system_settings_server.h b/src/core/hle/service/set/system_settings_server.h index acbda8b8c..1982b9723 100644 --- a/src/core/hle/service/set/system_settings_server.h +++ b/src/core/hle/service/set/system_settings_server.h | |||
| @@ -50,6 +50,10 @@ public: | |||
| 50 | 50 | ||
| 51 | Result GetVibrationMasterVolume(f32& out_volume) const; | 51 | Result GetVibrationMasterVolume(f32& out_volume) const; |
| 52 | Result SetVibrationMasterVolume(f32 volume); | 52 | Result SetVibrationMasterVolume(f32 volume); |
| 53 | Result GetAudioOutputMode(AudioOutputMode& out_output_mode, AudioOutputModeTarget target) const; | ||
| 54 | Result SetAudioOutputMode(AudioOutputModeTarget target, AudioOutputMode output_mode); | ||
| 55 | Result GetSpeakerAutoMuteFlag(bool& is_auto_mute) const; | ||
| 56 | Result SetSpeakerAutoMuteFlag(bool auto_mute); | ||
| 53 | Result GetExternalSteadyClockSourceId(Common::UUID& out_id) const; | 57 | Result GetExternalSteadyClockSourceId(Common::UUID& out_id) const; |
| 54 | Result SetExternalSteadyClockSourceId(const Common::UUID& id); | 58 | Result SetExternalSteadyClockSourceId(const Common::UUID& id); |
| 55 | Result GetUserSystemClockContext(Service::PSC::Time::SystemClockContext& out_context) const; | 59 | Result GetUserSystemClockContext(Service::PSC::Time::SystemClockContext& out_context) const; |
| @@ -97,8 +101,10 @@ private: | |||
| 97 | void GetSettingsItemValue(HLERequestContext& ctx); | 101 | void GetSettingsItemValue(HLERequestContext& ctx); |
| 98 | void GetTvSettings(HLERequestContext& ctx); | 102 | void GetTvSettings(HLERequestContext& ctx); |
| 99 | void SetTvSettings(HLERequestContext& ctx); | 103 | void SetTvSettings(HLERequestContext& ctx); |
| 100 | void IsForceMuteOnHeadphoneRemoved(HLERequestContext& ctx); | 104 | void GetAudioOutputMode(HLERequestContext& ctx); |
| 101 | void SetForceMuteOnHeadphoneRemoved(HLERequestContext& ctx); | 105 | void SetAudioOutputMode(HLERequestContext& ctx); |
| 106 | void GetSpeakerAutoMuteFlag(HLERequestContext& ctx); | ||
| 107 | void SetSpeakerAutoMuteFlag(HLERequestContext& ctx); | ||
| 102 | void GetDebugModeFlag(HLERequestContext& ctx); | 108 | void GetDebugModeFlag(HLERequestContext& ctx); |
| 103 | void GetQuestFlag(HLERequestContext& ctx); | 109 | void GetQuestFlag(HLERequestContext& ctx); |
| 104 | void SetQuestFlag(HLERequestContext& ctx); | 110 | void SetQuestFlag(HLERequestContext& ctx); |
| @@ -111,6 +117,8 @@ private: | |||
| 111 | void SetUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx); | 117 | void SetUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx); |
| 112 | void GetPrimaryAlbumStorage(HLERequestContext& ctx); | 118 | void GetPrimaryAlbumStorage(HLERequestContext& ctx); |
| 113 | void SetPrimaryAlbumStorage(HLERequestContext& ctx); | 119 | void SetPrimaryAlbumStorage(HLERequestContext& ctx); |
| 120 | void GetBatteryLot(HLERequestContext& ctx); | ||
| 121 | void GetSerialNumber(HLERequestContext& ctx); | ||
| 114 | void GetNfcEnableFlag(HLERequestContext& ctx); | 122 | void GetNfcEnableFlag(HLERequestContext& ctx); |
| 115 | void SetNfcEnableFlag(HLERequestContext& ctx); | 123 | void SetNfcEnableFlag(HLERequestContext& ctx); |
| 116 | void GetSleepSettings(HLERequestContext& ctx); | 124 | void GetSleepSettings(HLERequestContext& ctx); |
| @@ -126,13 +134,19 @@ private: | |||
| 126 | void SetBluetoothEnableFlag(HLERequestContext& ctx); | 134 | void SetBluetoothEnableFlag(HLERequestContext& ctx); |
| 127 | void GetMiiAuthorId(HLERequestContext& ctx); | 135 | void GetMiiAuthorId(HLERequestContext& ctx); |
| 128 | void GetAutoUpdateEnableFlag(HLERequestContext& ctx); | 136 | void GetAutoUpdateEnableFlag(HLERequestContext& ctx); |
| 137 | void SetAutoUpdateEnableFlag(HLERequestContext& ctx); | ||
| 129 | void GetBatteryPercentageFlag(HLERequestContext& ctx); | 138 | void GetBatteryPercentageFlag(HLERequestContext& ctx); |
| 139 | void SetBatteryPercentageFlag(HLERequestContext& ctx); | ||
| 130 | void SetExternalSteadyClockInternalOffset(HLERequestContext& ctx); | 140 | void SetExternalSteadyClockInternalOffset(HLERequestContext& ctx); |
| 131 | void GetExternalSteadyClockInternalOffset(HLERequestContext& ctx); | 141 | void GetExternalSteadyClockInternalOffset(HLERequestContext& ctx); |
| 142 | void GetPushNotificationActivityModeOnSleep(HLERequestContext& ctx); | ||
| 143 | void SetPushNotificationActivityModeOnSleep(HLERequestContext& ctx); | ||
| 132 | void GetErrorReportSharePermission(HLERequestContext& ctx); | 144 | void GetErrorReportSharePermission(HLERequestContext& ctx); |
| 145 | void SetErrorReportSharePermission(HLERequestContext& ctx); | ||
| 133 | void GetAppletLaunchFlags(HLERequestContext& ctx); | 146 | void GetAppletLaunchFlags(HLERequestContext& ctx); |
| 134 | void SetAppletLaunchFlags(HLERequestContext& ctx); | 147 | void SetAppletLaunchFlags(HLERequestContext& ctx); |
| 135 | void GetKeyboardLayout(HLERequestContext& ctx); | 148 | void GetKeyboardLayout(HLERequestContext& ctx); |
| 149 | void SetKeyboardLayout(HLERequestContext& ctx); | ||
| 136 | void GetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx); | 150 | void GetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx); |
| 137 | void SetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx); | 151 | void SetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx); |
| 138 | void GetUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext& ctx); | 152 | void GetUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext& ctx); |
| @@ -141,6 +155,8 @@ private: | |||
| 141 | void GetHomeMenuScheme(HLERequestContext& ctx); | 155 | void GetHomeMenuScheme(HLERequestContext& ctx); |
| 142 | void GetHomeMenuSchemeModel(HLERequestContext& ctx); | 156 | void GetHomeMenuSchemeModel(HLERequestContext& ctx); |
| 143 | void GetFieldTestingFlag(HLERequestContext& ctx); | 157 | void GetFieldTestingFlag(HLERequestContext& ctx); |
| 158 | void GetPanelCrcMode(HLERequestContext& ctx); | ||
| 159 | void SetPanelCrcMode(HLERequestContext& ctx); | ||
| 144 | 160 | ||
| 145 | bool LoadSettingsFile(std::filesystem::path& path, auto&& default_func); | 161 | bool LoadSettingsFile(std::filesystem::path& path, auto&& default_func); |
| 146 | bool StoreSettingsFile(std::filesystem::path& path, auto& settings); | 162 | bool StoreSettingsFile(std::filesystem::path& path, auto& settings); |
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 1c218566f..e10a4601e 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -781,8 +781,7 @@ struct Memory::Impl { | |||
| 781 | }, | 781 | }, |
| 782 | [&]() { HandleRasterizerWrite(GetInteger(vaddr), sizeof(T)); }); | 782 | [&]() { HandleRasterizerWrite(GetInteger(vaddr), sizeof(T)); }); |
| 783 | if (ptr) { | 783 | if (ptr) { |
| 784 | const auto volatile_pointer = reinterpret_cast<volatile T*>(ptr); | 784 | return Common::AtomicCompareAndSwap(reinterpret_cast<T*>(ptr), data, expected); |
| 785 | return Common::AtomicCompareAndSwap(volatile_pointer, data, expected); | ||
| 786 | } | 785 | } |
| 787 | return true; | 786 | return true; |
| 788 | } | 787 | } |
| @@ -796,8 +795,7 @@ struct Memory::Impl { | |||
| 796 | }, | 795 | }, |
| 797 | [&]() { HandleRasterizerWrite(GetInteger(vaddr), sizeof(u128)); }); | 796 | [&]() { HandleRasterizerWrite(GetInteger(vaddr), sizeof(u128)); }); |
| 798 | if (ptr) { | 797 | if (ptr) { |
| 799 | const auto volatile_pointer = reinterpret_cast<volatile u64*>(ptr); | 798 | return Common::AtomicCompareAndSwap(reinterpret_cast<u64*>(ptr), data, expected); |
| 800 | return Common::AtomicCompareAndSwap(volatile_pointer, data, expected); | ||
| 801 | } | 799 | } |
| 802 | return true; | 800 | return true; |
| 803 | } | 801 | } |
diff --git a/src/frontend_common/config.cpp b/src/frontend_common/config.cpp index 46277e288..905f35118 100644 --- a/src/frontend_common/config.cpp +++ b/src/frontend_common/config.cpp | |||
| @@ -298,6 +298,16 @@ void Config::ReadDebuggingValues() { | |||
| 298 | EndGroup(); | 298 | EndGroup(); |
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | #ifdef __unix__ | ||
| 302 | void Config::ReadLinuxValues() { | ||
| 303 | BeginGroup(Settings::TranslateCategory(Settings::Category::Linux)); | ||
| 304 | |||
| 305 | ReadCategory(Settings::Category::Linux); | ||
| 306 | |||
| 307 | EndGroup(); | ||
| 308 | } | ||
| 309 | #endif | ||
| 310 | |||
| 301 | void Config::ReadServiceValues() { | 311 | void Config::ReadServiceValues() { |
| 302 | BeginGroup(Settings::TranslateCategory(Settings::Category::Services)); | 312 | BeginGroup(Settings::TranslateCategory(Settings::Category::Services)); |
| 303 | 313 | ||
| @@ -404,6 +414,9 @@ void Config::ReadValues() { | |||
| 404 | ReadControlValues(); | 414 | ReadControlValues(); |
| 405 | ReadCoreValues(); | 415 | ReadCoreValues(); |
| 406 | ReadCpuValues(); | 416 | ReadCpuValues(); |
| 417 | #ifdef __unix__ | ||
| 418 | ReadLinuxValues(); | ||
| 419 | #endif | ||
| 407 | ReadRendererValues(); | 420 | ReadRendererValues(); |
| 408 | ReadAudioValues(); | 421 | ReadAudioValues(); |
| 409 | ReadSystemValues(); | 422 | ReadSystemValues(); |
| @@ -504,6 +517,9 @@ void Config::SaveValues() { | |||
| 504 | SaveControlValues(); | 517 | SaveControlValues(); |
| 505 | SaveCoreValues(); | 518 | SaveCoreValues(); |
| 506 | SaveCpuValues(); | 519 | SaveCpuValues(); |
| 520 | #ifdef __unix__ | ||
| 521 | SaveLinuxValues(); | ||
| 522 | #endif | ||
| 507 | SaveRendererValues(); | 523 | SaveRendererValues(); |
| 508 | SaveAudioValues(); | 524 | SaveAudioValues(); |
| 509 | SaveSystemValues(); | 525 | SaveSystemValues(); |
| @@ -578,6 +594,16 @@ void Config::SaveDebuggingValues() { | |||
| 578 | EndGroup(); | 594 | EndGroup(); |
| 579 | } | 595 | } |
| 580 | 596 | ||
| 597 | #ifdef __unix__ | ||
| 598 | void Config::SaveLinuxValues() { | ||
| 599 | BeginGroup(Settings::TranslateCategory(Settings::Category::Linux)); | ||
| 600 | |||
| 601 | WriteCategory(Settings::Category::Linux); | ||
| 602 | |||
| 603 | EndGroup(); | ||
| 604 | } | ||
| 605 | #endif | ||
| 606 | |||
| 581 | void Config::SaveNetworkValues() { | 607 | void Config::SaveNetworkValues() { |
| 582 | BeginGroup(Settings::TranslateCategory(Settings::Category::Services)); | 608 | BeginGroup(Settings::TranslateCategory(Settings::Category::Services)); |
| 583 | 609 | ||
diff --git a/src/frontend_common/config.h b/src/frontend_common/config.h index 4798d6432..4ecb97044 100644 --- a/src/frontend_common/config.h +++ b/src/frontend_common/config.h | |||
| @@ -76,6 +76,9 @@ protected: | |||
| 76 | void ReadCoreValues(); | 76 | void ReadCoreValues(); |
| 77 | void ReadDataStorageValues(); | 77 | void ReadDataStorageValues(); |
| 78 | void ReadDebuggingValues(); | 78 | void ReadDebuggingValues(); |
| 79 | #ifdef __unix__ | ||
| 80 | void ReadLinuxValues(); | ||
| 81 | #endif | ||
| 79 | void ReadServiceValues(); | 82 | void ReadServiceValues(); |
| 80 | void ReadDisabledAddOnValues(); | 83 | void ReadDisabledAddOnValues(); |
| 81 | void ReadMiscellaneousValues(); | 84 | void ReadMiscellaneousValues(); |
| @@ -107,6 +110,9 @@ protected: | |||
| 107 | void SaveCoreValues(); | 110 | void SaveCoreValues(); |
| 108 | void SaveDataStorageValues(); | 111 | void SaveDataStorageValues(); |
| 109 | void SaveDebuggingValues(); | 112 | void SaveDebuggingValues(); |
| 113 | #ifdef __unix__ | ||
| 114 | void SaveLinuxValues(); | ||
| 115 | #endif | ||
| 110 | void SaveNetworkValues(); | 116 | void SaveNetworkValues(); |
| 111 | void SaveDisabledAddOnValues(); | 117 | void SaveDisabledAddOnValues(); |
| 112 | void SaveMiscellaneousValues(); | 118 | void SaveMiscellaneousValues(); |
diff --git a/src/hid_core/resource_manager.cpp b/src/hid_core/resource_manager.cpp index a2295219a..e78665d31 100644 --- a/src/hid_core/resource_manager.cpp +++ b/src/hid_core/resource_manager.cpp | |||
| @@ -184,7 +184,7 @@ void ResourceManager::InitializeHidCommonSampler() { | |||
| 184 | keyboard->SetAppletResource(applet_resource, &shared_mutex); | 184 | keyboard->SetAppletResource(applet_resource, &shared_mutex); |
| 185 | 185 | ||
| 186 | const auto settings = | 186 | const auto settings = |
| 187 | system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys"); | 187 | system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); |
| 188 | npad->SetNpadExternals(applet_resource, &shared_mutex, handheld_config, settings); | 188 | npad->SetNpadExternals(applet_resource, &shared_mutex, handheld_config, settings); |
| 189 | 189 | ||
| 190 | six_axis->SetAppletResource(applet_resource, &shared_mutex); | 190 | six_axis->SetAppletResource(applet_resource, &shared_mutex); |
diff --git a/src/hid_core/resources/abstracted_pad/abstract_properties_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_properties_handler.cpp index 4897a2784..36b630c7f 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_properties_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_properties_handler.cpp | |||
| @@ -137,7 +137,7 @@ void NpadAbstractPropertiesHandler::UpdateAllDeviceProperties() { | |||
| 137 | const auto npad_index = NpadIdTypeToIndex(npad_id_type); | 137 | const auto npad_index = NpadIdTypeToIndex(npad_id_type); |
| 138 | for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) { | 138 | for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) { |
| 139 | auto* data = applet_resource_holder->applet_resource->GetAruidData(aruid_index); | 139 | auto* data = applet_resource_holder->applet_resource->GetAruidData(aruid_index); |
| 140 | if (!data->flag.is_assigned) { | 140 | if (data == nullptr || !data->flag.is_assigned) { |
| 141 | continue; | 141 | continue; |
| 142 | } | 142 | } |
| 143 | auto& npad_entry = data->shared_memory_format->npad.npad_entry[npad_index]; | 143 | auto& npad_entry = data->shared_memory_format->npad.npad_entry[npad_index]; |
diff --git a/src/hid_core/resources/hid_firmware_settings.cpp b/src/hid_core/resources/hid_firmware_settings.cpp index 9c9019e8f..b32c0660a 100644 --- a/src/hid_core/resources/hid_firmware_settings.cpp +++ b/src/hid_core/resources/hid_firmware_settings.cpp | |||
| @@ -8,7 +8,8 @@ | |||
| 8 | namespace Service::HID { | 8 | namespace Service::HID { |
| 9 | 9 | ||
| 10 | HidFirmwareSettings::HidFirmwareSettings(Core::System& system) { | 10 | HidFirmwareSettings::HidFirmwareSettings(Core::System& system) { |
| 11 | m_set_sys = system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys"); | 11 | m_set_sys = |
| 12 | system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); | ||
| 12 | LoadSettings(true); | 13 | LoadSettings(true); |
| 13 | } | 14 | } |
| 14 | 15 | ||
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 521a0e253..0755ba772 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt | |||
| @@ -302,7 +302,7 @@ target_link_options(video_core PRIVATE ${FFmpeg_LDFLAGS}) | |||
| 302 | 302 | ||
| 303 | add_dependencies(video_core host_shaders) | 303 | add_dependencies(video_core host_shaders) |
| 304 | target_include_directories(video_core PRIVATE ${HOST_SHADERS_INCLUDE}) | 304 | target_include_directories(video_core PRIVATE ${HOST_SHADERS_INCLUDE}) |
| 305 | target_link_libraries(video_core PRIVATE sirit Vulkan::Headers GPUOpen::VulkanMemoryAllocator) | 305 | target_link_libraries(video_core PRIVATE sirit Vulkan::Headers Vulkan::UtilityHeaders GPUOpen::VulkanMemoryAllocator) |
| 306 | 306 | ||
| 307 | if (ENABLE_NSIGHT_AFTERMATH) | 307 | if (ENABLE_NSIGHT_AFTERMATH) |
| 308 | if (NOT DEFINED ENV{NSIGHT_AFTERMATH_SDK}) | 308 | if (NOT DEFINED ENV{NSIGHT_AFTERMATH_SDK}) |
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index 86a30dcd1..4f1d3b4e3 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include "core/core.h" | 12 | #include "core/core.h" |
| 13 | #include "video_core/renderer_vulkan/vk_scheduler.h" | 13 | #include "video_core/renderer_vulkan/vk_scheduler.h" |
| 14 | #include "video_core/renderer_vulkan/vk_swapchain.h" | 14 | #include "video_core/renderer_vulkan/vk_swapchain.h" |
| 15 | #include "video_core/vulkan_common/vk_enum_string_helper.h" | ||
| 15 | #include "video_core/vulkan_common/vulkan_device.h" | 16 | #include "video_core/vulkan_common/vulkan_device.h" |
| 16 | #include "video_core/vulkan_common/vulkan_wrapper.h" | 17 | #include "video_core/vulkan_common/vulkan_wrapper.h" |
| 17 | #include "vulkan/vulkan_core.h" | 18 | #include "vulkan/vulkan_core.h" |
| @@ -151,7 +152,7 @@ bool Swapchain::AcquireNextImage() { | |||
| 151 | vk::Check(result); | 152 | vk::Check(result); |
| 152 | break; | 153 | break; |
| 153 | default: | 154 | default: |
| 154 | LOG_ERROR(Render_Vulkan, "vkAcquireNextImageKHR returned {}", vk::ToString(result)); | 155 | LOG_ERROR(Render_Vulkan, "vkAcquireNextImageKHR returned {}", string_VkResult(result)); |
| 155 | break; | 156 | break; |
| 156 | } | 157 | } |
| 157 | 158 | ||
| @@ -187,7 +188,7 @@ void Swapchain::Present(VkSemaphore render_semaphore) { | |||
| 187 | vk::Check(result); | 188 | vk::Check(result); |
| 188 | break; | 189 | break; |
| 189 | default: | 190 | default: |
| 190 | LOG_CRITICAL(Render_Vulkan, "Failed to present with error {}", vk::ToString(result)); | 191 | LOG_CRITICAL(Render_Vulkan, "Failed to present with error {}", string_VkResult(result)); |
| 191 | break; | 192 | break; |
| 192 | } | 193 | } |
| 193 | ++frame_index; | 194 | ++frame_index; |
diff --git a/src/video_core/vulkan_common/vk_enum_string_helper.h b/src/video_core/vulkan_common/vk_enum_string_helper.h new file mode 100644 index 000000000..a1515814c --- /dev/null +++ b/src/video_core/vulkan_common/vk_enum_string_helper.h | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "video_core/vulkan_common/vulkan.h" | ||
| 7 | |||
| 8 | #include <vulkan/vk_enum_string_helper.h> | ||
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index 3966bd61e..f1aa45551 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | 9 | ||
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "common/logging/log.h" | 11 | #include "common/logging/log.h" |
| 12 | #include "video_core/vulkan_common/vk_enum_string_helper.h" | ||
| 12 | #include "video_core/vulkan_common/vma.h" | 13 | #include "video_core/vulkan_common/vma.h" |
| 13 | #include "video_core/vulkan_common/vulkan_wrapper.h" | 14 | #include "video_core/vulkan_common/vulkan_wrapper.h" |
| 14 | 15 | ||
| @@ -298,109 +299,7 @@ bool Load(VkInstance instance, InstanceDispatch& dld) noexcept { | |||
| 298 | } | 299 | } |
| 299 | 300 | ||
| 300 | const char* Exception::what() const noexcept { | 301 | const char* Exception::what() const noexcept { |
| 301 | return ToString(result); | 302 | return string_VkResult(result); |
| 302 | } | ||
| 303 | |||
| 304 | const char* ToString(VkResult result) noexcept { | ||
| 305 | switch (result) { | ||
| 306 | case VkResult::VK_SUCCESS: | ||
| 307 | return "VK_SUCCESS"; | ||
| 308 | case VkResult::VK_NOT_READY: | ||
| 309 | return "VK_NOT_READY"; | ||
| 310 | case VkResult::VK_TIMEOUT: | ||
| 311 | return "VK_TIMEOUT"; | ||
| 312 | case VkResult::VK_EVENT_SET: | ||
| 313 | return "VK_EVENT_SET"; | ||
| 314 | case VkResult::VK_EVENT_RESET: | ||
| 315 | return "VK_EVENT_RESET"; | ||
| 316 | case VkResult::VK_INCOMPLETE: | ||
| 317 | return "VK_INCOMPLETE"; | ||
| 318 | case VkResult::VK_ERROR_OUT_OF_HOST_MEMORY: | ||
| 319 | return "VK_ERROR_OUT_OF_HOST_MEMORY"; | ||
| 320 | case VkResult::VK_ERROR_OUT_OF_DEVICE_MEMORY: | ||
| 321 | return "VK_ERROR_OUT_OF_DEVICE_MEMORY"; | ||
| 322 | case VkResult::VK_ERROR_INITIALIZATION_FAILED: | ||
| 323 | return "VK_ERROR_INITIALIZATION_FAILED"; | ||
| 324 | case VkResult::VK_ERROR_DEVICE_LOST: | ||
| 325 | return "VK_ERROR_DEVICE_LOST"; | ||
| 326 | case VkResult::VK_ERROR_MEMORY_MAP_FAILED: | ||
| 327 | return "VK_ERROR_MEMORY_MAP_FAILED"; | ||
| 328 | case VkResult::VK_ERROR_LAYER_NOT_PRESENT: | ||
| 329 | return "VK_ERROR_LAYER_NOT_PRESENT"; | ||
| 330 | case VkResult::VK_ERROR_EXTENSION_NOT_PRESENT: | ||
| 331 | return "VK_ERROR_EXTENSION_NOT_PRESENT"; | ||
| 332 | case VkResult::VK_ERROR_FEATURE_NOT_PRESENT: | ||
| 333 | return "VK_ERROR_FEATURE_NOT_PRESENT"; | ||
| 334 | case VkResult::VK_ERROR_INCOMPATIBLE_DRIVER: | ||
| 335 | return "VK_ERROR_INCOMPATIBLE_DRIVER"; | ||
| 336 | case VkResult::VK_ERROR_TOO_MANY_OBJECTS: | ||
| 337 | return "VK_ERROR_TOO_MANY_OBJECTS"; | ||
| 338 | case VkResult::VK_ERROR_FORMAT_NOT_SUPPORTED: | ||
| 339 | return "VK_ERROR_FORMAT_NOT_SUPPORTED"; | ||
| 340 | case VkResult::VK_ERROR_FRAGMENTED_POOL: | ||
| 341 | return "VK_ERROR_FRAGMENTED_POOL"; | ||
| 342 | case VkResult::VK_ERROR_OUT_OF_POOL_MEMORY: | ||
| 343 | return "VK_ERROR_OUT_OF_POOL_MEMORY"; | ||
| 344 | case VkResult::VK_ERROR_INVALID_EXTERNAL_HANDLE: | ||
| 345 | return "VK_ERROR_INVALID_EXTERNAL_HANDLE"; | ||
| 346 | case VkResult::VK_ERROR_SURFACE_LOST_KHR: | ||
| 347 | return "VK_ERROR_SURFACE_LOST_KHR"; | ||
| 348 | case VkResult::VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: | ||
| 349 | return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR"; | ||
| 350 | case VkResult::VK_SUBOPTIMAL_KHR: | ||
| 351 | return "VK_SUBOPTIMAL_KHR"; | ||
| 352 | case VkResult::VK_ERROR_OUT_OF_DATE_KHR: | ||
| 353 | return "VK_ERROR_OUT_OF_DATE_KHR"; | ||
| 354 | case VkResult::VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: | ||
| 355 | return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR"; | ||
| 356 | case VkResult::VK_ERROR_VALIDATION_FAILED_EXT: | ||
| 357 | return "VK_ERROR_VALIDATION_FAILED_EXT"; | ||
| 358 | case VkResult::VK_ERROR_INVALID_SHADER_NV: | ||
| 359 | return "VK_ERROR_INVALID_SHADER_NV"; | ||
| 360 | case VkResult::VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR: | ||
| 361 | return "VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR"; | ||
| 362 | case VkResult::VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR: | ||
| 363 | return "VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR"; | ||
| 364 | case VkResult::VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR: | ||
| 365 | return "VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR"; | ||
| 366 | case VkResult::VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR: | ||
| 367 | return "VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR"; | ||
| 368 | case VkResult::VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR: | ||
| 369 | return "VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR"; | ||
| 370 | case VkResult::VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR: | ||
| 371 | return "VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR"; | ||
| 372 | case VkResult::VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT: | ||
| 373 | return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT"; | ||
| 374 | case VkResult::VK_ERROR_FRAGMENTATION_EXT: | ||
| 375 | return "VK_ERROR_FRAGMENTATION_EXT"; | ||
| 376 | case VkResult::VK_ERROR_NOT_PERMITTED_EXT: | ||
| 377 | return "VK_ERROR_NOT_PERMITTED_EXT"; | ||
| 378 | case VkResult::VK_ERROR_INVALID_DEVICE_ADDRESS_EXT: | ||
| 379 | return "VK_ERROR_INVALID_DEVICE_ADDRESS_EXT"; | ||
| 380 | case VkResult::VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT: | ||
| 381 | return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT"; | ||
| 382 | case VkResult::VK_ERROR_UNKNOWN: | ||
| 383 | return "VK_ERROR_UNKNOWN"; | ||
| 384 | case VkResult::VK_THREAD_IDLE_KHR: | ||
| 385 | return "VK_THREAD_IDLE_KHR"; | ||
| 386 | case VkResult::VK_THREAD_DONE_KHR: | ||
| 387 | return "VK_THREAD_DONE_KHR"; | ||
| 388 | case VkResult::VK_OPERATION_DEFERRED_KHR: | ||
| 389 | return "VK_OPERATION_DEFERRED_KHR"; | ||
| 390 | case VkResult::VK_OPERATION_NOT_DEFERRED_KHR: | ||
| 391 | return "VK_OPERATION_NOT_DEFERRED_KHR"; | ||
| 392 | case VkResult::VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR: | ||
| 393 | return "VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR"; | ||
| 394 | case VkResult::VK_PIPELINE_COMPILE_REQUIRED_EXT: | ||
| 395 | return "VK_PIPELINE_COMPILE_REQUIRED_EXT"; | ||
| 396 | case VkResult::VK_RESULT_MAX_ENUM: | ||
| 397 | return "VK_RESULT_MAX_ENUM"; | ||
| 398 | case VkResult::VK_ERROR_COMPRESSION_EXHAUSTED_EXT: | ||
| 399 | return "VK_ERROR_COMPRESSION_EXHAUSTED_EXT"; | ||
| 400 | case VkResult::VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT: | ||
| 401 | return "VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT"; | ||
| 402 | } | ||
| 403 | return "Unknown"; | ||
| 404 | } | 303 | } |
| 405 | 304 | ||
| 406 | void Destroy(VkInstance instance, const InstanceDispatch& dld) noexcept { | 305 | void Destroy(VkInstance instance, const InstanceDispatch& dld) noexcept { |
| @@ -1067,7 +966,7 @@ u32 AvailableVersion(const InstanceDispatch& dld) noexcept { | |||
| 1067 | u32 version; | 966 | u32 version; |
| 1068 | if (const VkResult result = vkEnumerateInstanceVersion(&version); result != VK_SUCCESS) { | 967 | if (const VkResult result = vkEnumerateInstanceVersion(&version); result != VK_SUCCESS) { |
| 1069 | LOG_ERROR(Render_Vulkan, "vkEnumerateInstanceVersion returned {}, assuming Vulkan 1.1", | 968 | LOG_ERROR(Render_Vulkan, "vkEnumerateInstanceVersion returned {}, assuming Vulkan 1.1", |
| 1070 | ToString(result)); | 969 | string_VkResult(result)); |
| 1071 | return VK_API_VERSION_1_1; | 970 | return VK_API_VERSION_1_1; |
| 1072 | } | 971 | } |
| 1073 | return version; | 972 | return version; |
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index a0c70797f..757f3c8af 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h | |||
| @@ -125,9 +125,6 @@ private: | |||
| 125 | VkResult result; | 125 | VkResult result; |
| 126 | }; | 126 | }; |
| 127 | 127 | ||
| 128 | /// Converts a VkResult enum into a rodata string | ||
| 129 | const char* ToString(VkResult) noexcept; | ||
| 130 | |||
| 131 | /// Throws a Vulkan exception if result is not success. | 128 | /// Throws a Vulkan exception if result is not success. |
| 132 | inline void Check(VkResult result) { | 129 | inline void Check(VkResult result) { |
| 133 | if (result != VK_SUCCESS) { | 130 | if (result != VK_SUCCESS) { |
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index b058dba17..76f06da12 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt | |||
| @@ -96,6 +96,9 @@ add_executable(yuzu | |||
| 96 | configuration/configure_input_profile_dialog.cpp | 96 | configuration/configure_input_profile_dialog.cpp |
| 97 | configuration/configure_input_profile_dialog.h | 97 | configuration/configure_input_profile_dialog.h |
| 98 | configuration/configure_input_profile_dialog.ui | 98 | configuration/configure_input_profile_dialog.ui |
| 99 | configuration/configure_linux_tab.cpp | ||
| 100 | configuration/configure_linux_tab.h | ||
| 101 | configuration/configure_linux_tab.ui | ||
| 99 | configuration/configure_mouse_panning.cpp | 102 | configuration/configure_mouse_panning.cpp |
| 100 | configuration/configure_mouse_panning.h | 103 | configuration/configure_mouse_panning.h |
| 101 | configuration/configure_mouse_panning.ui | 104 | configuration/configure_mouse_panning.ui |
diff --git a/src/yuzu/configuration/configure_audio.h b/src/yuzu/configuration/configure_audio.h index 79538e81c..82d7f6524 100644 --- a/src/yuzu/configuration/configure_audio.h +++ b/src/yuzu/configuration/configure_audio.h | |||
| @@ -24,6 +24,8 @@ class Builder; | |||
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | class ConfigureAudio : public ConfigurationShared::Tab { | 26 | class ConfigureAudio : public ConfigurationShared::Tab { |
| 27 | Q_OBJECT | ||
| 28 | |||
| 27 | public: | 29 | public: |
| 28 | explicit ConfigureAudio(const Core::System& system_, | 30 | explicit ConfigureAudio(const Core::System& system_, |
| 29 | std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group, | 31 | std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group, |
diff --git a/src/yuzu/configuration/configure_cpu.h b/src/yuzu/configuration/configure_cpu.h index a102b4c1f..7bbeac496 100644 --- a/src/yuzu/configuration/configure_cpu.h +++ b/src/yuzu/configuration/configure_cpu.h | |||
| @@ -24,6 +24,8 @@ class Builder; | |||
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | class ConfigureCpu : public ConfigurationShared::Tab { | 26 | class ConfigureCpu : public ConfigurationShared::Tab { |
| 27 | Q_OBJECT | ||
| 28 | |||
| 27 | public: | 29 | public: |
| 28 | explicit ConfigureCpu(const Core::System& system_, | 30 | explicit ConfigureCpu(const Core::System& system_, |
| 29 | std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group, | 31 | std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group, |
diff --git a/src/yuzu/configuration/configure_general.h b/src/yuzu/configuration/configure_general.h index 2d953f679..ada6526a6 100644 --- a/src/yuzu/configuration/configure_general.h +++ b/src/yuzu/configuration/configure_general.h | |||
| @@ -25,6 +25,8 @@ class Builder; | |||
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | class ConfigureGeneral : public ConfigurationShared::Tab { | 27 | class ConfigureGeneral : public ConfigurationShared::Tab { |
| 28 | Q_OBJECT | ||
| 29 | |||
| 28 | public: | 30 | public: |
| 29 | explicit ConfigureGeneral(const Core::System& system_, | 31 | explicit ConfigureGeneral(const Core::System& system_, |
| 30 | std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group, | 32 | std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group, |
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 0836bcb7e..54c931e56 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp | |||
| @@ -224,6 +224,11 @@ void ConfigureGraphics::PopulateVSyncModeSelection(bool use_setting) { | |||
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | void ConfigureGraphics::UpdateVsyncSetting() const { | 226 | void ConfigureGraphics::UpdateVsyncSetting() const { |
| 227 | const Settings::RendererBackend backend{GetCurrentGraphicsBackend()}; | ||
| 228 | if (backend == Settings::RendererBackend::Null) { | ||
| 229 | return; | ||
| 230 | } | ||
| 231 | |||
| 227 | const auto mode = vsync_mode_combobox_enum_map[vsync_mode_combobox->currentIndex()]; | 232 | const auto mode = vsync_mode_combobox_enum_map[vsync_mode_combobox->currentIndex()]; |
| 228 | const auto vsync_mode = PresentModeToSetting(mode); | 233 | const auto vsync_mode = PresentModeToSetting(mode); |
| 229 | Settings::values.vsync_mode.SetValue(vsync_mode); | 234 | Settings::values.vsync_mode.SetValue(vsync_mode); |
diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h index 5c8286836..b92b4496b 100644 --- a/src/yuzu/configuration/configure_graphics.h +++ b/src/yuzu/configuration/configure_graphics.h | |||
| @@ -43,6 +43,8 @@ class Builder; | |||
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | class ConfigureGraphics : public ConfigurationShared::Tab { | 45 | class ConfigureGraphics : public ConfigurationShared::Tab { |
| 46 | Q_OBJECT | ||
| 47 | |||
| 46 | public: | 48 | public: |
| 47 | explicit ConfigureGraphics( | 49 | explicit ConfigureGraphics( |
| 48 | const Core::System& system_, std::vector<VkDeviceInfo::Record>& records, | 50 | const Core::System& system_, std::vector<VkDeviceInfo::Record>& records, |
diff --git a/src/yuzu/configuration/configure_graphics_advanced.h b/src/yuzu/configuration/configure_graphics_advanced.h index 78b5389c3..82431987e 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.h +++ b/src/yuzu/configuration/configure_graphics_advanced.h | |||
| @@ -21,6 +21,8 @@ class Builder; | |||
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | class ConfigureGraphicsAdvanced : public ConfigurationShared::Tab { | 23 | class ConfigureGraphicsAdvanced : public ConfigurationShared::Tab { |
| 24 | Q_OBJECT | ||
| 25 | |||
| 24 | public: | 26 | public: |
| 25 | explicit ConfigureGraphicsAdvanced( | 27 | explicit ConfigureGraphicsAdvanced( |
| 26 | const Core::System& system_, std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group, | 28 | const Core::System& system_, std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group, |
diff --git a/src/yuzu/configuration/configure_linux_tab.cpp b/src/yuzu/configuration/configure_linux_tab.cpp new file mode 100644 index 000000000..ab3d18816 --- /dev/null +++ b/src/yuzu/configuration/configure_linux_tab.cpp | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/settings.h" | ||
| 5 | #include "core/core.h" | ||
| 6 | #include "ui_configure_linux_tab.h" | ||
| 7 | #include "yuzu/configuration/configuration_shared.h" | ||
| 8 | #include "yuzu/configuration/configure_linux_tab.h" | ||
| 9 | #include "yuzu/configuration/shared_widget.h" | ||
| 10 | |||
| 11 | ConfigureLinuxTab::ConfigureLinuxTab(const Core::System& system_, | ||
| 12 | std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_, | ||
| 13 | const ConfigurationShared::Builder& builder, QWidget* parent) | ||
| 14 | : Tab(group_, parent), ui(std::make_unique<Ui::ConfigureLinuxTab>()), system{system_} { | ||
| 15 | ui->setupUi(this); | ||
| 16 | |||
| 17 | Setup(builder); | ||
| 18 | |||
| 19 | SetConfiguration(); | ||
| 20 | } | ||
| 21 | |||
| 22 | ConfigureLinuxTab::~ConfigureLinuxTab() = default; | ||
| 23 | |||
| 24 | void ConfigureLinuxTab::SetConfiguration() {} | ||
| 25 | void ConfigureLinuxTab::Setup(const ConfigurationShared::Builder& builder) { | ||
| 26 | QLayout& linux_layout = *ui->linux_widget->layout(); | ||
| 27 | |||
| 28 | std::map<u32, QWidget*> linux_hold{}; | ||
| 29 | |||
| 30 | std::vector<Settings::BasicSetting*> settings; | ||
| 31 | const auto push = [&](Settings::Category category) { | ||
| 32 | for (const auto setting : Settings::values.linkage.by_category[category]) { | ||
| 33 | settings.push_back(setting); | ||
| 34 | } | ||
| 35 | }; | ||
| 36 | |||
| 37 | push(Settings::Category::Linux); | ||
| 38 | |||
| 39 | for (auto* setting : settings) { | ||
| 40 | auto* widget = builder.BuildWidget(setting, apply_funcs); | ||
| 41 | |||
| 42 | if (widget == nullptr) { | ||
| 43 | continue; | ||
| 44 | } | ||
| 45 | if (!widget->Valid()) { | ||
| 46 | widget->deleteLater(); | ||
| 47 | continue; | ||
| 48 | } | ||
| 49 | |||
| 50 | linux_hold.insert({setting->Id(), widget}); | ||
| 51 | } | ||
| 52 | |||
| 53 | for (const auto& [id, widget] : linux_hold) { | ||
| 54 | linux_layout.addWidget(widget); | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | void ConfigureLinuxTab::ApplyConfiguration() { | ||
| 59 | const bool is_powered_on = system.IsPoweredOn(); | ||
| 60 | for (const auto& apply_func : apply_funcs) { | ||
| 61 | apply_func(is_powered_on); | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | void ConfigureLinuxTab::changeEvent(QEvent* event) { | ||
| 66 | if (event->type() == QEvent::LanguageChange) { | ||
| 67 | RetranslateUI(); | ||
| 68 | } | ||
| 69 | |||
| 70 | QWidget::changeEvent(event); | ||
| 71 | } | ||
| 72 | |||
| 73 | void ConfigureLinuxTab::RetranslateUI() { | ||
| 74 | ui->retranslateUi(this); | ||
| 75 | } | ||
diff --git a/src/yuzu/configuration/configure_linux_tab.h b/src/yuzu/configuration/configure_linux_tab.h new file mode 100644 index 000000000..2f402079c --- /dev/null +++ b/src/yuzu/configuration/configure_linux_tab.h | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <QWidget> | ||
| 7 | |||
| 8 | namespace Core { | ||
| 9 | class System; | ||
| 10 | } | ||
| 11 | |||
| 12 | namespace Ui { | ||
| 13 | class ConfigureLinuxTab; | ||
| 14 | } | ||
| 15 | |||
| 16 | namespace ConfigurationShared { | ||
| 17 | class Builder; | ||
| 18 | } | ||
| 19 | |||
| 20 | class ConfigureLinuxTab : public ConfigurationShared::Tab { | ||
| 21 | Q_OBJECT | ||
| 22 | |||
| 23 | public: | ||
| 24 | explicit ConfigureLinuxTab(const Core::System& system_, | ||
| 25 | std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group, | ||
| 26 | const ConfigurationShared::Builder& builder, | ||
| 27 | QWidget* parent = nullptr); | ||
| 28 | ~ConfigureLinuxTab() override; | ||
| 29 | |||
| 30 | void ApplyConfiguration() override; | ||
| 31 | void SetConfiguration() override; | ||
| 32 | |||
| 33 | private: | ||
| 34 | void changeEvent(QEvent* event) override; | ||
| 35 | void RetranslateUI(); | ||
| 36 | |||
| 37 | void Setup(const ConfigurationShared::Builder& builder); | ||
| 38 | |||
| 39 | std::unique_ptr<Ui::ConfigureLinuxTab> ui; | ||
| 40 | |||
| 41 | const Core::System& system; | ||
| 42 | |||
| 43 | std::vector<std::function<void(bool)>> apply_funcs{}; | ||
| 44 | }; | ||
diff --git a/src/yuzu/configuration/configure_linux_tab.ui b/src/yuzu/configuration/configure_linux_tab.ui new file mode 100644 index 000000000..f8e07f581 --- /dev/null +++ b/src/yuzu/configuration/configure_linux_tab.ui | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <ui version="4.0"> | ||
| 3 | <class>ConfigureLinuxTab</class> | ||
| 4 | <widget class="QWidget" name="ConfigureLinuxTab"> | ||
| 5 | <property name="accessibleName"> | ||
| 6 | <string>Linux</string> | ||
| 7 | </property> | ||
| 8 | <layout class="QVBoxLayout"> | ||
| 9 | <item> | ||
| 10 | <widget class="QGroupBox" name="LinuxGroupBox"> | ||
| 11 | <property name="title"> | ||
| 12 | <string>Linux</string> | ||
| 13 | </property> | ||
| 14 | <layout class="QVBoxLayout" name="LinuxVerticalLayout_1"> | ||
| 15 | <item> | ||
| 16 | <widget class="QWidget" name="linux_widget" native="true"> | ||
| 17 | <layout class="QVBoxLayout" name="LinuxVerticalLayout_2"> | ||
| 18 | <property name="leftMargin"> | ||
| 19 | <number>0</number> | ||
| 20 | </property> | ||
| 21 | <property name="topMargin"> | ||
| 22 | <number>0</number> | ||
| 23 | </property> | ||
| 24 | <property name="rightMargin"> | ||
| 25 | <number>0</number> | ||
| 26 | </property> | ||
| 27 | <property name="bottomMargin"> | ||
| 28 | <number>0</number> | ||
| 29 | </property> | ||
| 30 | </layout> | ||
| 31 | </widget> | ||
| 32 | </item> | ||
| 33 | </layout> | ||
| 34 | </widget> | ||
| 35 | </item> | ||
| 36 | <item> | ||
| 37 | <spacer name="verticalSpacer"> | ||
| 38 | <property name="orientation"> | ||
| 39 | <enum>Qt::Vertical</enum> | ||
| 40 | </property> | ||
| 41 | <property name="sizeHint" stdset="0"> | ||
| 42 | <size> | ||
| 43 | <width>20</width> | ||
| 44 | <height>40</height> | ||
| 45 | </size> | ||
| 46 | </property> | ||
| 47 | </spacer> | ||
| 48 | </item> | ||
| 49 | </layout> | ||
| 50 | </widget> | ||
| 51 | <resources/> | ||
| 52 | <connections/> | ||
| 53 | </ui> | ||
diff --git a/src/yuzu/configuration/configure_motion_touch.h b/src/yuzu/configuration/configure_motion_touch.h index 7dcc9318e..a5db0de51 100644 --- a/src/yuzu/configuration/configure_motion_touch.h +++ b/src/yuzu/configuration/configure_motion_touch.h | |||
| @@ -26,6 +26,7 @@ class ConfigureMotionTouch; | |||
| 26 | /// A dialog for touchpad calibration configuration. | 26 | /// A dialog for touchpad calibration configuration. |
| 27 | class CalibrationConfigurationDialog : public QDialog { | 27 | class CalibrationConfigurationDialog : public QDialog { |
| 28 | Q_OBJECT | 28 | Q_OBJECT |
| 29 | |||
| 29 | public: | 30 | public: |
| 30 | explicit CalibrationConfigurationDialog(QWidget* parent, const std::string& host, u16 port); | 31 | explicit CalibrationConfigurationDialog(QWidget* parent, const std::string& host, u16 port); |
| 31 | ~CalibrationConfigurationDialog() override; | 32 | ~CalibrationConfigurationDialog() override; |
diff --git a/src/yuzu/configuration/configure_mouse_panning.h b/src/yuzu/configuration/configure_mouse_panning.h index 08c6e1f62..f5e62ee13 100644 --- a/src/yuzu/configuration/configure_mouse_panning.h +++ b/src/yuzu/configuration/configure_mouse_panning.h | |||
| @@ -16,6 +16,7 @@ class ConfigureMousePanning; | |||
| 16 | 16 | ||
| 17 | class ConfigureMousePanning : public QDialog { | 17 | class ConfigureMousePanning : public QDialog { |
| 18 | Q_OBJECT | 18 | Q_OBJECT |
| 19 | |||
| 19 | public: | 20 | public: |
| 20 | explicit ConfigureMousePanning(QWidget* parent, InputCommon::InputSubsystem* input_subsystem_, | 21 | explicit ConfigureMousePanning(QWidget* parent, InputCommon::InputSubsystem* input_subsystem_, |
| 21 | float right_stick_deadzone, float right_stick_range); | 22 | float right_stick_deadzone, float right_stick_range); |
diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index b274a3321..9d38ab812 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include "yuzu/configuration/configure_graphics.h" | 33 | #include "yuzu/configuration/configure_graphics.h" |
| 34 | #include "yuzu/configuration/configure_graphics_advanced.h" | 34 | #include "yuzu/configuration/configure_graphics_advanced.h" |
| 35 | #include "yuzu/configuration/configure_input_per_game.h" | 35 | #include "yuzu/configuration/configure_input_per_game.h" |
| 36 | #include "yuzu/configuration/configure_linux_tab.h" | ||
| 36 | #include "yuzu/configuration/configure_per_game.h" | 37 | #include "yuzu/configuration/configure_per_game.h" |
| 37 | #include "yuzu/configuration/configure_per_game_addons.h" | 38 | #include "yuzu/configuration/configure_per_game_addons.h" |
| 38 | #include "yuzu/configuration/configure_system.h" | 39 | #include "yuzu/configuration/configure_system.h" |
| @@ -60,6 +61,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st | |||
| 60 | system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, | 61 | system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, |
| 61 | [](Settings::AspectRatio, Settings::ResolutionSetup) {}, tab_group, *builder, this); | 62 | [](Settings::AspectRatio, Settings::ResolutionSetup) {}, tab_group, *builder, this); |
| 62 | input_tab = std::make_unique<ConfigureInputPerGame>(system_, game_config.get(), this); | 63 | input_tab = std::make_unique<ConfigureInputPerGame>(system_, game_config.get(), this); |
| 64 | linux_tab = std::make_unique<ConfigureLinuxTab>(system_, tab_group, *builder, this); | ||
| 63 | system_tab = std::make_unique<ConfigureSystem>(system_, tab_group, *builder, this); | 65 | system_tab = std::make_unique<ConfigureSystem>(system_, tab_group, *builder, this); |
| 64 | 66 | ||
| 65 | ui->setupUi(this); | 67 | ui->setupUi(this); |
| @@ -71,6 +73,10 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st | |||
| 71 | ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("Adv. Graphics")); | 73 | ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("Adv. Graphics")); |
| 72 | ui->tabWidget->addTab(audio_tab.get(), tr("Audio")); | 74 | ui->tabWidget->addTab(audio_tab.get(), tr("Audio")); |
| 73 | ui->tabWidget->addTab(input_tab.get(), tr("Input Profiles")); | 75 | ui->tabWidget->addTab(input_tab.get(), tr("Input Profiles")); |
| 76 | // Only show Linux tab on Unix | ||
| 77 | #ifdef __unix__ | ||
| 78 | ui->tabWidget->addTab(linux_tab.get(), tr("Linux")); | ||
| 79 | #endif | ||
| 74 | 80 | ||
| 75 | setFocusPolicy(Qt::ClickFocus); | 81 | setFocusPolicy(Qt::ClickFocus); |
| 76 | setWindowTitle(tr("Properties")); | 82 | setWindowTitle(tr("Properties")); |
diff --git a/src/yuzu/configuration/configure_per_game.h b/src/yuzu/configuration/configure_per_game.h index 9daae772c..196cb32e6 100644 --- a/src/yuzu/configuration/configure_per_game.h +++ b/src/yuzu/configuration/configure_per_game.h | |||
| @@ -32,6 +32,7 @@ class ConfigureCpu; | |||
| 32 | class ConfigureGraphics; | 32 | class ConfigureGraphics; |
| 33 | class ConfigureGraphicsAdvanced; | 33 | class ConfigureGraphicsAdvanced; |
| 34 | class ConfigureInputPerGame; | 34 | class ConfigureInputPerGame; |
| 35 | class ConfigureLinuxTab; | ||
| 35 | class ConfigureSystem; | 36 | class ConfigureSystem; |
| 36 | 37 | ||
| 37 | class QGraphicsScene; | 38 | class QGraphicsScene; |
| @@ -85,5 +86,6 @@ private: | |||
| 85 | std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab; | 86 | std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab; |
| 86 | std::unique_ptr<ConfigureGraphics> graphics_tab; | 87 | std::unique_ptr<ConfigureGraphics> graphics_tab; |
| 87 | std::unique_ptr<ConfigureInputPerGame> input_tab; | 88 | std::unique_ptr<ConfigureInputPerGame> input_tab; |
| 89 | std::unique_ptr<ConfigureLinuxTab> linux_tab; | ||
| 88 | std::unique_ptr<ConfigureSystem> system_tab; | 90 | std::unique_ptr<ConfigureSystem> system_tab; |
| 89 | }; | 91 | }; |
diff --git a/src/yuzu/configuration/configure_system.h b/src/yuzu/configuration/configure_system.h index 4334211f9..a01c29dcf 100644 --- a/src/yuzu/configuration/configure_system.h +++ b/src/yuzu/configuration/configure_system.h | |||
| @@ -27,6 +27,8 @@ class Builder; | |||
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | class ConfigureSystem : public ConfigurationShared::Tab { | 29 | class ConfigureSystem : public ConfigurationShared::Tab { |
| 30 | Q_OBJECT | ||
| 31 | |||
| 30 | public: | 32 | public: |
| 31 | explicit ConfigureSystem(Core::System& system_, | 33 | explicit ConfigureSystem(Core::System& system_, |
| 32 | std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group, | 34 | std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group, |