summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--CMakeLists.txt6
-rw-r--r--externals/CMakeLists.txt5
m---------externals/Vulkan-Utility-Libraries0
-rw-r--r--externals/tz/tz/tz.cpp4
-rw-r--r--externals/tz/tz/tz.h4
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt8
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt8
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/DriverAdapter.kt7
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt53
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt5
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/model/EmulationViewModel.kt33
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt7
-rw-r--r--src/android/app/src/main/jni/CMakeLists.txt2
-rw-r--r--src/android/app/src/main/jni/id_cache.cpp7
-rw-r--r--src/android/app/src/main/jni/id_cache.h1
-rw-r--r--src/android/app/src/main/jni/native.cpp68
-rw-r--r--src/android/app/src/main/jni/native.h7
-rw-r--r--src/android/app/src/main/res/layout/fragment_emulation.xml4
-rw-r--r--src/audio_core/CMakeLists.txt4
-rw-r--r--src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp7
-rw-r--r--src/audio_core/adsp/apps/audio_renderer/audio_renderer.h7
-rw-r--r--src/audio_core/adsp/apps/audio_renderer/command_buffer.h5
-rw-r--r--src/audio_core/adsp/apps/audio_renderer/command_list_processor.cpp7
-rw-r--r--src/audio_core/adsp/apps/audio_renderer/command_list_processor.h7
-rw-r--r--src/audio_core/renderer/audio_renderer.cpp6
-rw-r--r--src/audio_core/renderer/audio_renderer.h6
-rw-r--r--src/audio_core/renderer/system.cpp10
-rw-r--r--src/audio_core/renderer/system.h6
-rw-r--r--src/common/CMakeLists.txt4
-rw-r--r--src/common/atomic_ops.h79
-rw-r--r--src/core/CMakeLists.txt4
-rw-r--r--src/core/core.cpp14
-rw-r--r--src/core/hle/kernel/k_thread.cpp3
-rw-r--r--src/core/hle/service/am/am.cpp2
-rw-r--r--src/core/hle/service/am/applets/applet_mii_edit.cpp2
-rw-r--r--src/core/hle/service/audio/audctl.cpp84
-rw-r--r--src/core/hle/service/audio/audctl.h20
-rw-r--r--src/core/hle/service/audio/audren_u.cpp16
-rw-r--r--src/core/hle/service/caps/caps_manager.cpp12
-rw-r--r--src/core/hle/service/cmif_serialization.h123
-rw-r--r--src/core/hle/service/cmif_types.h197
-rw-r--r--src/core/hle/service/glue/time/alarm_worker.cpp3
-rw-r--r--src/core/hle/service/glue/time/alarm_worker.h4
-rw-r--r--src/core/hle/service/glue/time/file_timestamp_worker.cpp4
-rw-r--r--src/core/hle/service/glue/time/manager.cpp40
-rw-r--r--src/core/hle/service/glue/time/static.cpp394
-rw-r--r--src/core/hle/service/glue/time/static.h76
-rw-r--r--src/core/hle/service/glue/time/time_zone.cpp347
-rw-r--r--src/core/hle/service/glue/time/time_zone.h67
-rw-r--r--src/core/hle/service/glue/time/time_zone_binary.cpp11
-rw-r--r--src/core/hle/service/glue/time/time_zone_binary.h2
-rw-r--r--src/core/hle/service/glue/time/worker.cpp42
-rw-r--r--src/core/hle/service/glue/time/worker.h8
-rw-r--r--src/core/hle/service/mii/mii.cpp563
-rw-r--r--src/core/hle/service/mii/mii.h15
-rw-r--r--src/core/hle/service/nfc/common/device.cpp8
-rw-r--r--src/core/hle/service/nfc/common/device_manager.cpp8
-rw-r--r--src/core/hle/service/psc/time/common.h135
-rw-r--r--src/core/hle/service/psc/time/power_state_service.cpp28
-rw-r--r--src/core/hle/service/psc/time/power_state_service.h7
-rw-r--r--src/core/hle/service/psc/time/service_manager.cpp438
-rw-r--r--src/core/hle/service/psc/time/service_manager.h60
-rw-r--r--src/core/hle/service/psc/time/static.cpp493
-rw-r--r--src/core/hle/service/psc/time/static.h65
-rw-r--r--src/core/hle/service/psc/time/steady_clock.cpp133
-rw-r--r--src/core/hle/service/psc/time/steady_clock.h21
-rw-r--r--src/core/hle/service/psc/time/system_clock.cpp92
-rw-r--r--src/core/hle/service/psc/time/system_clock.h13
-rw-r--r--src/core/hle/service/psc/time/time_zone.cpp18
-rw-r--r--src/core/hle/service/psc/time/time_zone.h15
-rw-r--r--src/core/hle/service/psc/time/time_zone_service.cpp322
-rw-r--r--src/core/hle/service/psc/time/time_zone_service.h57
-rw-r--r--src/core/hle/service/set/setting_formats/system_settings.cpp14
-rw-r--r--src/core/hle/service/set/setting_formats/system_settings.h12
-rw-r--r--src/core/hle/service/set/settings_types.h15
-rw-r--r--src/core/hle/service/set/system_settings_server.cpp249
-rw-r--r--src/core/hle/service/set/system_settings_server.h20
-rw-r--r--src/core/memory.cpp6
-rw-r--r--src/dedicated_room/CMakeLists.txt4
-rw-r--r--src/frontend_common/config.cpp26
-rw-r--r--src/frontend_common/config.h6
-rw-r--r--src/hid_core/CMakeLists.txt1
-rw-r--r--src/hid_core/hid_types.h10
-rw-r--r--src/hid_core/resource_manager.cpp2
-rw-r--r--src/hid_core/resources/hid_firmware_settings.cpp3
-rw-r--r--src/hid_core/resources/shared_memory_format.h13
-rw-r--r--src/hid_core/resources/system_buttons/capture_button.cpp26
-rw-r--r--src/hid_core/resources/system_buttons/capture_button.h3
-rw-r--r--src/hid_core/resources/system_buttons/home_button.cpp26
-rw-r--r--src/hid_core/resources/system_buttons/home_button.h3
-rw-r--r--src/hid_core/resources/system_buttons/sleep_button.cpp23
-rw-r--r--src/hid_core/resources/system_buttons/sleep_button.h3
-rw-r--r--src/hid_core/resources/system_buttons/system_button_types.h31
-rw-r--r--src/hid_core/resources/unique_pad/unique_pad.cpp2
-rw-r--r--src/video_core/CMakeLists.txt6
-rw-r--r--src/video_core/renderer_vulkan/vk_swapchain.cpp5
-rw-r--r--src/video_core/vulkan_common/vk_enum_string_helper.h8
-rw-r--r--src/video_core/vulkan_common/vulkan_wrapper.cpp107
-rw-r--r--src/video_core/vulkan_common/vulkan_wrapper.h3
-rw-r--r--src/yuzu/CMakeLists.txt7
-rw-r--r--src/yuzu/configuration/configure_audio.h2
-rw-r--r--src/yuzu/configuration/configure_cpu.h2
-rw-r--r--src/yuzu/configuration/configure_general.h2
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp5
-rw-r--r--src/yuzu/configuration/configure_graphics.h2
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.h2
-rw-r--r--src/yuzu/configuration/configure_linux_tab.cpp75
-rw-r--r--src/yuzu/configuration/configure_linux_tab.h44
-rw-r--r--src/yuzu/configuration/configure_linux_tab.ui53
-rw-r--r--src/yuzu/configuration/configure_motion_touch.h1
-rw-r--r--src/yuzu/configuration/configure_mouse_panning.h1
-rw-r--r--src/yuzu/configuration/configure_per_game.cpp6
-rw-r--r--src/yuzu/configuration/configure_per_game.h2
-rw-r--r--src/yuzu/configuration/configure_system.h2
-rw-r--r--src/yuzu_cmd/CMakeLists.txt4
116 files changed, 2381 insertions, 2802 deletions
diff --git a/.gitmodules b/.gitmodules
index e65997afc..52256d86f 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -64,3 +64,6 @@
[submodule "oaknut"]
path = externals/oaknut
url = https://github.com/merryhime/oaknut
+[submodule "Vulkan-Utility-Libraries"]
+ path = externals/Vulkan-Utility-Libraries
+ 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}")
option(YUZU_USE_EXTERNAL_VULKAN_HEADERS "Use Vulkan-Headers from externals" ON)
+option(YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES "Use Vulkan-Utility-Libraries from externals" ON)
+
option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF)
option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF)
@@ -308,6 +310,10 @@ if (NOT YUZU_USE_EXTERNAL_VULKAN_HEADERS)
find_package(Vulkan 1.3.274 REQUIRED)
endif()
+if (NOT YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES)
+ find_package(VulkanUtilityLibraries REQUIRED)
+endif()
+
if (ENABLE_LIBUSB)
find_package(libusb 1.0.24 MODULE)
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)
add_subdirectory(Vulkan-Headers)
endif()
+# Vulkan-Utility-Libraries
+if (YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES)
+ add_subdirectory(Vulkan-Utility-Libraries)
+endif()
+
# TZDB (Time Zone Database)
add_subdirectory(nx_tzdb)
diff --git a/externals/Vulkan-Utility-Libraries b/externals/Vulkan-Utility-Libraries
new file mode 160000
+Subproject 524f8910d0e4a5f2ec5961996b23e5b74b95cb1
diff --git a/externals/tz/tz/tz.cpp b/externals/tz/tz/tz.cpp
index 0c8b68217..04fa6cc8a 100644
--- a/externals/tz/tz/tz.cpp
+++ b/externals/tz/tz/tz.cpp
@@ -1625,11 +1625,11 @@ s32 ParseTimeZoneBinary(Rule& out_rule, std::span<const u8> binary) {
return 0;
}
-bool localtime_rz(CalendarTimeInternal* tmp, Rule* sp, time_t* timep) {
+bool localtime_rz(CalendarTimeInternal* tmp, Rule const* sp, time_t* timep) {
return localsub(sp, timep, 0, tmp) == nullptr;
}
-u32 mktime_tzname(time_t* out_time, Rule* sp, CalendarTimeInternal* tmp) {
+u32 mktime_tzname(time_t* out_time, Rule const* sp, CalendarTimeInternal* tmp) {
return time1(out_time, tmp, localsub, sp, 0);
}
diff --git a/externals/tz/tz/tz.h b/externals/tz/tz/tz.h
index 38605cfb1..dae4459bc 100644
--- a/externals/tz/tz/tz.h
+++ b/externals/tz/tz/tz.h
@@ -75,7 +75,7 @@ static_assert(sizeof(CalendarTimeInternal) == 0x3C, "CalendarTimeInternal has th
s32 ParseTimeZoneBinary(Rule& out_rule, std::span<const u8> binary);
-bool localtime_rz(CalendarTimeInternal* tmp, Rule* sp, time_t* timep);
-u32 mktime_tzname(time_t* out_time, Rule* sp, CalendarTimeInternal* tmp);
+bool localtime_rz(CalendarTimeInternal* tmp, Rule const* sp, time_t* timep);
+u32 mktime_tzname(time_t* out_time, Rule const* sp, CalendarTimeInternal* tmp);
} // namespace Tz
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 {
/**
* Begins emulation.
*/
- external fun run(path: String?)
+ external fun run(path: String?, programIndex: Int = 0)
// Surface Handling
external fun surfaceChanged(surf: Surface?)
@@ -489,6 +489,12 @@ object NativeLibrary {
sEmulationActivity.get()!!.onEmulationStopped(status)
}
+ @Keep
+ @JvmStatic
+ fun onProgramChanged(programIndex: Int) {
+ sEmulationActivity.get()!!.onProgramChanged(programIndex)
+ }
+
/**
* Logs the Yuzu version, Android version and, CPU.
*/
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 {
override fun onDestroy() {
stopForegroundService(this)
- emulationViewModel.clear()
super.onDestroy()
}
@@ -446,9 +445,14 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
}
fun onEmulationStopped(status: Int) {
- if (status == 0) {
+ if (status == 0 && emulationViewModel.programChanged.value == -1) {
finish()
}
+ emulationViewModel.setEmulationStopped(true)
+ }
+
+ fun onProgramChanged(programIndex: Int) {
+ emulationViewModel.setProgramChanged(programIndex)
}
private fun startMotionSensorListener() {
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/DriverAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/DriverAdapter.kt
index d6f17cf29..f218c76ef 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/DriverAdapter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/DriverAdapter.kt
@@ -7,6 +7,7 @@ import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.databinding.CardDriverOptionBinding
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
import org.yuzu.yuzu_emu.model.Driver
@@ -57,13 +58,9 @@ class DriverAdapter(private val driverViewModel: DriverViewModel) :
title.text = model.title
version.text = model.version
description.text = model.description
- if (model.description.isNotEmpty()) {
- version.visibility = View.VISIBLE
- description.visibility = View.VISIBLE
+ if (model.title != binding.root.context.getString(R.string.system_gpu_driver)) {
buttonDelete.visibility = View.VISIBLE
} else {
- version.visibility = View.GONE
- description.visibility = View.GONE
buttonDelete.visibility = View.GONE
}
}
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 ef393c4be..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
@@ -424,10 +424,38 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
}
}
+ launch {
+ repeatOnLifecycle(Lifecycle.State.CREATED) {
+ emulationViewModel.programChanged.collect {
+ if (it != 0) {
+ emulationViewModel.setEmulationStarted(false)
+ binding.drawerLayout.close()
+ binding.drawerLayout
+ .setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
+ ViewUtils.hideView(binding.surfaceInputOverlay)
+ ViewUtils.showView(binding.loadingIndicator)
+ }
+ }
+ }
+ }
+ launch {
+ repeatOnLifecycle(Lifecycle.State.CREATED) {
+ emulationViewModel.emulationStopped.collect {
+ if (it && emulationViewModel.programChanged.value != -1) {
+ if (perfStatsUpdater != null) {
+ perfStatsUpdateHandler.removeCallbacks(perfStatsUpdater!!)
+ }
+ emulationState.changeProgram(emulationViewModel.programChanged.value)
+ emulationViewModel.setProgramChanged(-1)
+ emulationViewModel.setEmulationStopped(false)
+ }
+ }
+ }
+ }
}
}
- private fun startEmulation() {
+ private fun startEmulation(programIndex: Int = 0) {
if (!NativeLibrary.isRunning() && !NativeLibrary.isPaused()) {
if (!DirectoryInitialization.areDirectoriesReady) {
DirectoryInitialization.start()
@@ -435,7 +463,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
updateScreenLayout()
- emulationState.run(emulationActivity!!.isActivityRecreated)
+ emulationState.run(emulationActivity!!.isActivityRecreated, programIndex)
}
}
@@ -833,6 +861,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
) {
private var state: State
private var surface: Surface? = null
+ lateinit var emulationThread: Thread
init {
// Starting state is stopped.
@@ -878,7 +907,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
@Synchronized
- fun run(isActivityRecreated: Boolean) {
+ fun run(isActivityRecreated: Boolean, programIndex: Int = 0) {
if (isActivityRecreated) {
if (NativeLibrary.isRunning()) {
state = State.PAUSED
@@ -889,10 +918,20 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
// If the surface is set, run now. Otherwise, wait for it to get set.
if (surface != null) {
- runWithValidSurface()
+ runWithValidSurface(programIndex)
}
}
+ @Synchronized
+ fun changeProgram(programIndex: Int) {
+ emulationThread.join()
+ emulationThread = Thread({
+ Log.debug("[EmulationFragment] Starting emulation thread.")
+ NativeLibrary.run(gamePath, programIndex)
+ }, "NativeEmulation")
+ emulationThread.start()
+ }
+
// Surface callbacks
@Synchronized
fun newSurface(surface: Surface?) {
@@ -932,7 +971,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
}
- private fun runWithValidSurface() {
+ private fun runWithValidSurface(programIndex: Int = 0) {
NativeLibrary.surfaceChanged(surface)
if (!emulationCanStart.invoke()) {
return
@@ -940,9 +979,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
when (state) {
State.STOPPED -> {
- val emulationThread = Thread({
+ emulationThread = Thread({
Log.debug("[EmulationFragment] Starting emulation thread.")
- NativeLibrary.run(gamePath)
+ NativeLibrary.run(gamePath, programIndex)
}, "NativeEmulation")
emulationThread.start()
}
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() {
fun updateDriverList() {
val selectedDriver = GpuDriverHelper.customDriverSettingData
+ val systemDriverData = GpuDriverHelper.getSystemDriverInfo()
val newDriverList = mutableListOf(
Driver(
selectedDriver == GpuDriverMetadata(),
- YuzuApplication.appContext.getString(R.string.system_gpu_driver)
+ YuzuApplication.appContext.getString(R.string.system_gpu_driver),
+ systemDriverData?.get(0) ?: "",
+ systemDriverData?.get(1) ?: ""
)
)
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() {
val isEmulationStopping: StateFlow<Boolean> get() = _isEmulationStopping
private val _isEmulationStopping = MutableStateFlow(false)
+ private val _emulationStopped = MutableStateFlow(false)
+ val emulationStopped = _emulationStopped.asStateFlow()
+
+ private val _programChanged = MutableStateFlow(-1)
+ val programChanged = _programChanged.asStateFlow()
+
val shaderProgress: StateFlow<Int> get() = _shaderProgress
private val _shaderProgress = MutableStateFlow(0)
@@ -35,6 +41,17 @@ class EmulationViewModel : ViewModel() {
_isEmulationStopping.value = value
}
+ fun setEmulationStopped(value: Boolean) {
+ if (value) {
+ _emulationStarted.value = false
+ }
+ _emulationStopped.value = value
+ }
+
+ fun setProgramChanged(programIndex: Int) {
+ _programChanged.value = programIndex
+ }
+
fun setShaderProgress(progress: Int) {
_shaderProgress.value = progress
}
@@ -56,20 +73,4 @@ class EmulationViewModel : ViewModel() {
fun setDrawerOpen(value: Boolean) {
_drawerOpen.value = value
}
-
- fun clear() {
- setEmulationStarted(false)
- setIsEmulationStopping(false)
- setShaderProgress(0)
- setTotalShaders(0)
- setShaderMessage("")
- }
-
- companion object {
- const val KEY_EMULATION_STARTED = "EmulationStarted"
- const val KEY_IS_EMULATION_STOPPING = "IsEmulationStarting"
- const val KEY_SHADER_PROGRESS = "ShaderProgress"
- const val KEY_TOTAL_SHADERS = "TotalShaders"
- const val KEY_SHADER_MESSAGE = "ShaderMessage"
- }
}
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 @@
package org.yuzu.yuzu_emu.utils
+import android.graphics.SurfaceTexture
import android.net.Uri
import android.os.Build
+import android.view.Surface
import java.io.File
import java.io.IOException
import org.yuzu.yuzu_emu.NativeLibrary
@@ -195,6 +197,11 @@ object GpuDriverHelper {
external fun supportsCustomDriverLoading(): Boolean
+ external fun getSystemDriverInfo(
+ surface: Surface = Surface(SurfaceTexture(true)),
+ hookLibPath: String = GpuDriverHelper.hookLibPath!!
+ ): Array<String>?
+
// Parse the custom driver metadata to retrieve the name.
val installedCustomDriverData: GpuDriverMetadata
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
set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR})
-target_link_libraries(yuzu-android PRIVATE audio_core common core input_common frontend_common)
+target_link_libraries(yuzu-android PRIVATE audio_core common core input_common frontend_common Vulkan::Headers)
target_link_libraries(yuzu-android PRIVATE android camera2ndk EGL glad jnigraphics log)
if (ARCHITECTURE_arm64)
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;
static jmethodID s_disk_cache_load_progress;
static jmethodID s_on_emulation_started;
static jmethodID s_on_emulation_stopped;
+static jmethodID s_on_program_changed;
static jclass s_game_class;
static jmethodID s_game_constructor;
@@ -123,6 +124,10 @@ jmethodID GetOnEmulationStopped() {
return s_on_emulation_stopped;
}
+jmethodID GetOnProgramChanged() {
+ return s_on_program_changed;
+}
+
jclass GetGameClass() {
return s_game_class;
}
@@ -306,6 +311,8 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
env->GetStaticMethodID(s_native_library_class, "onEmulationStarted", "()V");
s_on_emulation_stopped =
env->GetStaticMethodID(s_native_library_class, "onEmulationStopped", "(I)V");
+ s_on_program_changed =
+ env->GetStaticMethodID(s_native_library_class, "onProgramChanged", "(I)V");
const jclass game_class = env->FindClass("org/yuzu/yuzu_emu/model/Game");
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();
jmethodID GetDiskCacheLoadProgress();
jmethodID GetOnEmulationStarted();
jmethodID GetOnEmulationStopped();
+jmethodID GetOnProgramChanged();
jclass GetGameClass();
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 @@
#include "jni/id_cache.h"
#include "jni/native.h"
#include "video_core/renderer_base.h"
+#include "video_core/renderer_vulkan/renderer_vulkan.h"
+#include "video_core/vulkan_common/vulkan_instance.h"
+#include "video_core/vulkan_common/vulkan_surface.h"
#define jconst [[maybe_unused]] const auto
#define jauto [[maybe_unused]] auto
@@ -208,7 +211,8 @@ void EmulationSession::InitializeSystem(bool reload) {
m_system.GetFileSystemController().CreateFactories(*m_vfs);
}
-Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string& filepath) {
+Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string& filepath,
+ const std::size_t program_index) {
std::scoped_lock lock(m_mutex);
// Create the render window.
@@ -238,7 +242,8 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string
ConfigureFilesystemProvider(filepath);
// Load the ROM.
- m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filepath);
+ m_load_result =
+ m_system.Load(EmulationSession::GetInstance().Window(), filepath, 0, program_index);
if (m_load_result != Core::SystemResultStatus::Success) {
return m_load_result;
}
@@ -248,6 +253,12 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string
m_system.GetCpuManager().OnGpuReady();
m_system.RegisterExitCallback([&] { HaltEmulation(); });
+ // Register an ExecuteProgram callback such that Core can execute a sub-program
+ m_system.RegisterExecuteProgramCallback([&](std::size_t program_index_) {
+ m_next_program_index = program_index_;
+ EmulationSession::GetInstance().HaltEmulation();
+ });
+
OnEmulationStarted();
return Core::SystemResultStatus::Success;
}
@@ -255,6 +266,11 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string
void EmulationSession::ShutdownEmulation() {
std::scoped_lock lock(m_mutex);
+ if (m_next_program_index != -1) {
+ ChangeProgram(m_next_program_index);
+ m_next_program_index = -1;
+ }
+
m_is_running = false;
// Unload user input.
@@ -402,6 +418,12 @@ void EmulationSession::OnEmulationStopped(Core::SystemResultStatus result) {
static_cast<jint>(result));
}
+void EmulationSession::ChangeProgram(std::size_t program_index) {
+ JNIEnv* env = IDCache::GetEnvForThread();
+ env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetOnProgramChanged(),
+ static_cast<jint>(program_index));
+}
+
u64 EmulationSession::GetProgramId(JNIEnv* env, jstring jprogramId) {
auto program_id_string = GetJString(env, jprogramId);
try {
@@ -411,7 +433,8 @@ u64 EmulationSession::GetProgramId(JNIEnv* env, jstring jprogramId) {
}
}
-static Core::SystemResultStatus RunEmulation(const std::string& filepath) {
+static Core::SystemResultStatus RunEmulation(const std::string& filepath,
+ const size_t program_index = 0) {
MicroProfileOnThreadCreate("EmuThread");
SCOPE_EXIT({ MicroProfileShutdown(); });
@@ -424,7 +447,7 @@ static Core::SystemResultStatus RunEmulation(const std::string& filepath) {
SCOPE_EXIT({ EmulationSession::GetInstance().ShutdownEmulation(); });
- jconst result = EmulationSession::GetInstance().InitializeEmulation(filepath);
+ jconst result = EmulationSession::GetInstance().InitializeEmulation(filepath, program_index);
if (result != Core::SystemResultStatus::Success) {
return result;
}
@@ -521,6 +544,37 @@ jboolean JNICALL Java_org_yuzu_yuzu_1emu_utils_GpuDriverHelper_supportsCustomDri
#endif
}
+jobjectArray Java_org_yuzu_yuzu_1emu_utils_GpuDriverHelper_getSystemDriverInfo(
+ JNIEnv* env, jobject j_obj, jobject j_surf, jstring j_hook_lib_dir) {
+ const char* file_redirect_dir_{};
+ int featureFlags{};
+ std::string hook_lib_dir = GetJString(env, j_hook_lib_dir);
+ auto handle = adrenotools_open_libvulkan(RTLD_NOW, featureFlags, nullptr, hook_lib_dir.c_str(),
+ nullptr, nullptr, file_redirect_dir_, nullptr);
+ auto driver_library = std::make_shared<Common::DynamicLibrary>(handle);
+ InputCommon::InputSubsystem input_subsystem;
+ auto m_window = std::make_unique<EmuWindow_Android>(
+ &input_subsystem, ANativeWindow_fromSurface(env, j_surf), driver_library);
+
+ Vulkan::vk::InstanceDispatch dld;
+ Vulkan::vk::Instance vk_instance = Vulkan::CreateInstance(
+ *driver_library, dld, VK_API_VERSION_1_1, Core::Frontend::WindowSystemType::Android);
+
+ auto surface = Vulkan::CreateSurface(vk_instance, m_window->GetWindowInfo());
+
+ auto device = Vulkan::CreateDevice(vk_instance, dld, *surface);
+
+ auto driver_version = device.GetDriverVersion();
+ auto version_string =
+ fmt::format("{}.{}.{}", VK_API_VERSION_MAJOR(driver_version),
+ VK_API_VERSION_MINOR(driver_version), VK_API_VERSION_PATCH(driver_version));
+
+ jobjectArray j_driver_info =
+ env->NewObjectArray(2, IDCache::GetStringClass(), ToJString(env, version_string));
+ env->SetObjectArrayElement(j_driver_info, 1, ToJString(env, device.GetDriverName()));
+ return j_driver_info;
+}
+
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_reloadKeys(JNIEnv* env, jclass clazz) {
Core::Crypto::KeyManager::Instance().ReloadKeys();
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
Settings::LogSettings();
}
-void Java_org_yuzu_yuzu_1emu_NativeLibrary_run__Ljava_lang_String_2(JNIEnv* env, jclass clazz,
- jstring j_path) {
+void Java_org_yuzu_yuzu_1emu_NativeLibrary_run(JNIEnv* env, jobject jobj, jstring j_path,
+ jint j_program_index) {
const std::string path = GetJString(env, j_path);
- const Core::SystemResultStatus result{RunEmulation(path)};
+ const Core::SystemResultStatus result{RunEmulation(path, j_program_index)};
if (result != Core::SystemResultStatus::Success) {
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(),
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:
const Core::PerfStatsResults& PerfStats();
void ConfigureFilesystemProvider(const std::string& filepath);
void InitializeSystem(bool reload);
- Core::SystemResultStatus InitializeEmulation(const std::string& filepath);
+ Core::SystemResultStatus InitializeEmulation(const std::string& filepath,
+ const std::size_t program_index = 0);
bool IsHandheldOnly();
void SetDeviceType([[maybe_unused]] int index, int type);
@@ -60,6 +61,7 @@ public:
private:
static void LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress, int max);
static void OnEmulationStopped(Core::SystemResultStatus result);
+ static void ChangeProgram(std::size_t program_index);
private:
// Window management
@@ -84,4 +86,7 @@ private:
// Synchronization
std::condition_variable_any m_cv;
mutable std::mutex m_mutex;
+
+ // Program index for next boot
+ std::atomic<s32> m_next_program_index = -1;
};
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 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
+ android:focusable="false"
android:defaultFocusHighlightEnabled="false"
- android:clickable="false">
+ android:clickable="false"
+ app:rippleColor="@android:color/transparent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/loading_layout"
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt
index e982d03be..4e4ed1789 100644
--- a/src/audio_core/CMakeLists.txt
+++ b/src/audio_core/CMakeLists.txt
@@ -210,8 +210,6 @@ add_library(audio_core STATIC
sink/sink_stream.h
)
-create_target_directory_groups(audio_core)
-
if (MSVC)
target_compile_options(audio_core PRIVATE
/we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data
@@ -267,3 +265,5 @@ endif()
if (YUZU_USE_PRECOMPILED_HEADERS)
target_precompile_headers(audio_core PRIVATE precompiled_headers.h)
endif()
+
+create_target_directory_groups(audio_core)
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) {
}
void AudioRenderer::SetCommandBuffer(s32 session_id, CpuAddr buffer, u64 size, u64 time_limit,
- u64 applet_resource_user_id, bool reset) noexcept {
+ u64 applet_resource_user_id, Kernel::KProcess* process,
+ bool reset) noexcept {
command_buffers[session_id].buffer = buffer;
command_buffers[session_id].size = size;
command_buffers[session_id].time_limit = time_limit;
command_buffers[session_id].applet_resource_user_id = applet_resource_user_id;
+ command_buffers[session_id].process = process;
command_buffers[session_id].reset_buffer = reset;
}
@@ -173,7 +175,8 @@ void AudioRenderer::Main(std::stop_token stop_token) {
// If there are no remaining commands (from the previous list),
// this is a new command list, initialize it.
if (command_buffer.remaining_command_count == 0) {
- command_list_processor.Initialize(system, command_buffer.buffer,
+ command_list_processor.Initialize(system, *command_buffer.process,
+ command_buffer.buffer,
command_buffer.size, streams[index]);
}
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 {
class System;
} // namespace Core
+namespace Kernel {
+class KProcess;
+}
+
namespace AudioCore {
namespace Sink {
class Sink;
@@ -69,7 +73,8 @@ public:
u32 Receive(Direction dir);
void SetCommandBuffer(s32 session_id, CpuAddr buffer, u64 size, u64 time_limit,
- u64 applet_resource_user_id, bool reset) noexcept;
+ u64 applet_resource_user_id, Kernel::KProcess* process,
+ bool reset) noexcept;
u32 GetRemainCommandCount(s32 session_id) const noexcept;
void ClearRemainCommandCount(s32 session_id) noexcept;
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 @@
#include "audio_core/common/common.h"
#include "common/common_types.h"
+namespace Kernel {
+class KProcess;
+}
+
namespace AudioCore::ADSP::AudioRenderer {
struct CommandBuffer {
@@ -14,6 +18,7 @@ struct CommandBuffer {
u64 size{};
u64 time_limit{};
u64 applet_resource_user_id{};
+ Kernel::KProcess* process{};
bool reset_buffer{};
// Set by the DSP
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 @@
#include "common/settings.h"
#include "core/core.h"
#include "core/core_timing.h"
+#include "core/hle/kernel/k_process.h"
#include "core/memory.h"
namespace AudioCore::ADSP::AudioRenderer {
-void CommandListProcessor::Initialize(Core::System& system_, CpuAddr buffer, u64 size,
- Sink::SinkStream* stream_) {
+void CommandListProcessor::Initialize(Core::System& system_, Kernel::KProcess& process,
+ CpuAddr buffer, u64 size, Sink::SinkStream* stream_) {
system = &system_;
- memory = &system->ApplicationMemory();
+ memory = &process.GetMemory();
stream = stream_;
header = reinterpret_cast<Renderer::CommandListHeader*>(buffer);
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;
class System;
} // namespace Core
+namespace Kernel {
+class KProcess;
+}
+
namespace AudioCore {
namespace Sink {
class SinkStream;
@@ -40,7 +44,8 @@ public:
* @param size - The size of the buffer.
* @param stream - The stream to be used for sending the samples.
*/
- void Initialize(Core::System& system, CpuAddr buffer, u64 size, Sink::SinkStream* stream);
+ void Initialize(Core::System& system, Kernel::KProcess& process, CpuAddr buffer, u64 size,
+ Sink::SinkStream* stream);
/**
* 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 @@
#include "audio_core/renderer/audio_renderer.h"
#include "audio_core/renderer/system_manager.h"
#include "core/core.h"
+#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/service/audio/errors.h"
@@ -17,7 +18,8 @@ Renderer::Renderer(Core::System& system_, Manager& manager_, Kernel::KEvent* ren
Result Renderer::Initialize(const AudioRendererParameterInternal& params,
Kernel::KTransferMemory* transfer_memory,
const u64 transfer_memory_size, const u32 process_handle,
- const u64 applet_resource_user_id, const s32 session_id) {
+ Kernel::KProcess& process, const u64 applet_resource_user_id,
+ const s32 session_id) {
if (params.execution_mode == ExecutionMode::Auto) {
if (!manager.AddSystem(system)) {
LOG_ERROR(Service_Audio,
@@ -28,7 +30,7 @@ Result Renderer::Initialize(const AudioRendererParameterInternal& params,
}
initialized = true;
- system.Initialize(params, transfer_memory, transfer_memory_size, process_handle,
+ system.Initialize(params, transfer_memory, transfer_memory_size, process_handle, process,
applet_resource_user_id, session_id);
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;
namespace Kernel {
class KTransferMemory;
-}
+class KProcess;
+} // namespace Kernel
namespace AudioCore {
struct AudioRendererParameterInternal;
@@ -44,7 +45,8 @@ public:
*/
Result Initialize(const AudioRendererParameterInternal& params,
Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
- u32 process_handle, u64 applet_resource_user_id, s32 session_id);
+ u32 process_handle, Kernel::KProcess& process, u64 applet_resource_user_id,
+ s32 session_id);
/**
* 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 @@
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/k_event.h"
+#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/memory.h"
@@ -101,7 +102,8 @@ System::System(Core::System& core_, Kernel::KEvent* adsp_rendered_event_)
Result System::Initialize(const AudioRendererParameterInternal& params,
Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
- u32 process_handle_, u64 applet_resource_user_id_, s32 session_id_) {
+ u32 process_handle_, Kernel::KProcess& process_,
+ u64 applet_resource_user_id_, s32 session_id_) {
if (!CheckValidRevision(params.revision)) {
return Service::Audio::ResultInvalidRevision;
}
@@ -117,6 +119,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
behavior.SetUserLibRevision(params.revision);
process_handle = process_handle_;
+ process = &process_;
applet_resource_user_id = applet_resource_user_id_;
session_id = session_id_;
@@ -129,7 +132,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
render_device = params.rendering_device;
execution_mode = params.execution_mode;
- core.ApplicationMemory().ZeroBlock(transfer_memory->GetSourceAddress(), transfer_memory_size);
+ process->GetMemory().ZeroBlock(transfer_memory->GetSourceAddress(), transfer_memory_size);
// Note: We're not actually using the transfer memory because it's a pain to code for.
// Allocate the memory normally instead and hope the game doesn't try to read anything back
@@ -613,7 +616,8 @@ void System::SendCommandToDsp() {
static_cast<u64>((time_limit_percent / 100) * 2'880'000.0 *
(static_cast<f32>(render_time_limit_percent) / 100.0f))};
audio_renderer.SetCommandBuffer(session_id, translated_addr, command_size, time_limit,
- applet_resource_user_id, reset_command_buffers);
+ applet_resource_user_id, process,
+ reset_command_buffers);
reset_command_buffers = false;
command_buffer_size = command_size;
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;
namespace Kernel {
class KEvent;
+class KProcess;
class KTransferMemory;
} // namespace Kernel
@@ -80,7 +81,8 @@ public:
*/
Result Initialize(const AudioRendererParameterInternal& params,
Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
- u32 process_handle, u64 applet_resource_user_id, s32 session_id);
+ u32 process_handle, Kernel::KProcess& process, u64 applet_resource_user_id,
+ s32 session_id);
/**
* Finalize the system.
@@ -275,6 +277,8 @@ private:
Common::Event terminate_event{};
/// Does what locks do
std::mutex lock{};
+ /// Process this audio render is operating within, used for memory reads/writes.
+ Kernel::KProcess* process{};
/// Handle for the process for this system, unused
u32 process_handle{};
/// Applet resource id for this system, unused
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 8c57d47c6..e30fea268 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -244,8 +244,6 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
)
endif()
-create_target_directory_groups(common)
-
target_link_libraries(common PUBLIC Boost::context Boost::headers fmt::fmt microprofile stb::headers Threads::Threads)
target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd LLVM::Demangle)
@@ -257,3 +255,5 @@ endif()
if (YUZU_USE_PRECOMPILED_HEADERS)
target_precompile_headers(common PRIVATE precompiled_headers.h)
endif()
+
+create_target_directory_groups(common)
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 {
#if _MSC_VER
-[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected) {
+template <typename T>
+[[nodiscard]] inline bool AtomicCompareAndSwap(T* pointer, T value, T expected);
+template <typename T>
+[[nodiscard]] inline bool AtomicCompareAndSwap(T* pointer, T value, T expected, T& actual);
+
+template <>
+[[nodiscard]] inline bool AtomicCompareAndSwap<u8>(u8* pointer, u8 value, u8 expected) {
const u8 result =
_InterlockedCompareExchange8(reinterpret_cast<volatile char*>(pointer), value, expected);
return result == expected;
}
-[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected) {
+template <>
+[[nodiscard]] inline bool AtomicCompareAndSwap<u16>(u16* pointer, u16 value, u16 expected) {
const u16 result =
_InterlockedCompareExchange16(reinterpret_cast<volatile short*>(pointer), value, expected);
return result == expected;
}
-[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected) {
+template <>
+[[nodiscard]] inline bool AtomicCompareAndSwap<u32>(u32* pointer, u32 value, u32 expected) {
const u32 result =
_InterlockedCompareExchange(reinterpret_cast<volatile long*>(pointer), value, expected);
return result == expected;
}
-[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected) {
+template <>
+[[nodiscard]] inline bool AtomicCompareAndSwap<u64>(u64* pointer, u64 value, u64 expected) {
const u64 result = _InterlockedCompareExchange64(reinterpret_cast<volatile __int64*>(pointer),
value, expected);
return result == expected;
@@ -45,29 +54,32 @@ namespace Common {
reinterpret_cast<__int64*>(expected.data())) != 0;
}
-[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected,
- u8& actual) {
+template <>
+[[nodiscard]] inline bool AtomicCompareAndSwap<u8>(u8* pointer, u8 value, u8 expected, u8& actual) {
actual =
_InterlockedCompareExchange8(reinterpret_cast<volatile char*>(pointer), value, expected);
return actual == expected;
}
-[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected,
- u16& actual) {
+template <>
+[[nodiscard]] inline bool AtomicCompareAndSwap<u16>(u16* pointer, u16 value, u16 expected,
+ u16& actual) {
actual =
_InterlockedCompareExchange16(reinterpret_cast<volatile short*>(pointer), value, expected);
return actual == expected;
}
-[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected,
- u32& actual) {
+template <>
+[[nodiscard]] inline bool AtomicCompareAndSwap<u32>(u32* pointer, u32 value, u32 expected,
+ u32& actual) {
actual =
_InterlockedCompareExchange(reinterpret_cast<volatile long*>(pointer), value, expected);
return actual == expected;
}
-[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected,
- u64& actual) {
+template <>
+[[nodiscard]] inline bool AtomicCompareAndSwap<u64>(u64* pointer, u64 value, u64 expected,
+ u64& actual) {
actual = _InterlockedCompareExchange64(reinterpret_cast<volatile __int64*>(pointer), value,
expected);
return actual == expected;
@@ -91,23 +103,12 @@ namespace Common {
#else
-[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected) {
- return __sync_bool_compare_and_swap(pointer, expected, value);
-}
-
-[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected) {
- return __sync_bool_compare_and_swap(pointer, expected, value);
-}
-
-[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected) {
+template <typename T>
+[[nodiscard]] inline bool AtomicCompareAndSwap(T* pointer, T value, T expected) {
return __sync_bool_compare_and_swap(pointer, expected, value);
}
-[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected) {
- return __sync_bool_compare_and_swap(pointer, expected, value);
-}
-
-[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u128 value, u128 expected) {
+[[nodiscard]] inline bool AtomicCompareAndSwap(u64* pointer, u128 value, u128 expected) {
unsigned __int128 value_a;
unsigned __int128 expected_a;
std::memcpy(&value_a, value.data(), sizeof(u128));
@@ -115,31 +116,13 @@ namespace Common {
return __sync_bool_compare_and_swap((unsigned __int128*)pointer, expected_a, value_a);
}
-[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected,
- u8& actual) {
+template <typename T>
+[[nodiscard]] inline bool AtomicCompareAndSwap(T* pointer, T value, T expected, T& actual) {
actual = __sync_val_compare_and_swap(pointer, expected, value);
return actual == expected;
}
-[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected,
- u16& actual) {
- actual = __sync_val_compare_and_swap(pointer, expected, value);
- return actual == expected;
-}
-
-[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected,
- u32& actual) {
- actual = __sync_val_compare_and_swap(pointer, expected, value);
- return actual == expected;
-}
-
-[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected,
- u64& actual) {
- actual = __sync_val_compare_and_swap(pointer, expected, value);
- return actual == expected;
-}
-
-[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u128 value, u128 expected,
+[[nodiscard]] inline bool AtomicCompareAndSwap(u64* pointer, u128 value, u128 expected,
u128& actual) {
unsigned __int128 value_a;
unsigned __int128 expected_a;
@@ -151,7 +134,7 @@ namespace Common {
return actual_a == expected_a;
}
-[[nodiscard]] inline u128 AtomicLoad128(volatile u64* pointer) {
+[[nodiscard]] inline u128 AtomicLoad128(u64* pointer) {
unsigned __int128 zeros_a = 0;
unsigned __int128 result_a =
__sync_val_compare_and_swap((unsigned __int128*)pointer, zeros_a, zeros_a);
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 347bbf2d0..ea6b2c285 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -915,8 +915,6 @@ else()
)
endif()
-create_target_directory_groups(core)
-
target_link_libraries(core PUBLIC common PRIVATE audio_core hid_core network video_core nx_tzdb tz)
target_link_libraries(core PUBLIC Boost::headers PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls RenderDoc::API)
if (MINGW)
@@ -994,3 +992,5 @@ endif()
if (YUZU_ENABLE_LTO)
set_property(TARGET core PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
+
+create_target_directory_groups(core)
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 1b412ac98..11bf8d2f6 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -200,22 +200,22 @@ struct System::Impl {
system.ServiceManager().GetService<Service::PSC::Time::StaticService>("time:s", true);
std::shared_ptr<Service::PSC::Time::SystemClock> user_clock;
- static_service_a->GetStandardUserSystemClock(user_clock);
+ static_service_a->GetStandardUserSystemClock(&user_clock);
std::shared_ptr<Service::PSC::Time::SystemClock> local_clock;
- static_service_a->GetStandardLocalSystemClock(local_clock);
+ static_service_a->GetStandardLocalSystemClock(&local_clock);
std::shared_ptr<Service::PSC::Time::SystemClock> network_clock;
- static_service_s->GetStandardNetworkSystemClock(network_clock);
+ static_service_s->GetStandardNetworkSystemClock(&network_clock);
std::shared_ptr<Service::Glue::Time::TimeZoneService> timezone_service;
- static_service_a->GetTimeZoneService(timezone_service);
+ static_service_a->GetTimeZoneService(&timezone_service);
Service::PSC::Time::LocationName name{};
auto new_name = Settings::GetTimeZoneString(Settings::values.time_zone_index.GetValue());
- std::memcpy(name.name.data(), new_name.data(), std::min(name.name.size(), new_name.size()));
+ std::memcpy(name.data(), new_name.data(), std::min(name.size(), new_name.size()));
- timezone_service->SetDeviceLocation(name);
+ timezone_service->SetDeviceLocationName(name);
u64 time_offset = 0;
if (Settings::values.custom_rtc_enabled) {
@@ -233,7 +233,7 @@ struct System::Impl {
local_clock->SetCurrentTime(new_time);
- network_clock->GetSystemClockContext(context);
+ network_clock->GetSystemClockContext(&context);
settings_service->SetNetworkSystemClockContext(context);
network_clock->SetCurrentTime(new_time);
}
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() {
ASSERT(m_parent != nullptr);
// Resume any threads that began waiting on us while we were pinned.
- for (auto it = m_pinned_waiter_list.begin(); it != m_pinned_waiter_list.end(); ++it) {
+ for (auto it = m_pinned_waiter_list.begin(); it != m_pinned_waiter_list.end();
+ it = m_pinned_waiter_list.erase(it)) {
it->EndWait(ResultSuccess);
}
}
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index a768bdc54..38f67adcd 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -931,8 +931,8 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
sleep_lock_event = service_context.CreateEvent("ICommonStateGetter::SleepLockEvent");
// Configure applets to be in foreground state
- msg_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
msg_queue->PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground);
+ msg_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
}
ICommonStateGetter::~ICommonStateGetter() {
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() {
break;
}
- manager = system.ServiceManager().GetService<Mii::MiiDBModule>("mii:e")->GetMiiManager();
+ manager = system.ServiceManager().GetService<Mii::IStaticService>("mii:e")->GetMiiManager();
if (manager == nullptr) {
manager = std::make_shared<Mii::MiiManager>();
}
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 @@
#include "common/logging/log.h"
#include "core/hle/service/audio/audctl.h"
#include "core/hle/service/ipc_helpers.h"
+#include "core/hle/service/set/system_settings_server.h"
+#include "core/hle/service/sm/sm.h"
namespace Service::Audio {
@@ -19,15 +21,15 @@ AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} {
{6, nullptr, "IsTargetConnected"},
{7, nullptr, "SetDefaultTarget"},
{8, nullptr, "GetDefaultTarget"},
- {9, nullptr, "GetAudioOutputMode"},
- {10, nullptr, "SetAudioOutputMode"},
+ {9, &AudCtl::GetAudioOutputMode, "GetAudioOutputMode"},
+ {10, &AudCtl::SetAudioOutputMode, "SetAudioOutputMode"},
{11, nullptr, "SetForceMutePolicy"},
{12, &AudCtl::GetForceMutePolicy, "GetForceMutePolicy"},
{13, &AudCtl::GetOutputModeSetting, "GetOutputModeSetting"},
- {14, nullptr, "SetOutputModeSetting"},
+ {14, &AudCtl::SetOutputModeSetting, "SetOutputModeSetting"},
{15, nullptr, "SetOutputTarget"},
{16, nullptr, "SetInputTargetForceEnabled"},
- {17, nullptr, "SetHeadphoneOutputLevelMode"},
+ {17, &AudCtl::SetHeadphoneOutputLevelMode, "SetHeadphoneOutputLevelMode"},
{18, &AudCtl::GetHeadphoneOutputLevelMode, "GetHeadphoneOutputLevelMode"},
{19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"},
{20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"},
@@ -40,7 +42,7 @@ AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} {
{27, nullptr, "SetVolumeMappingTableForDev"},
{28, nullptr, "GetAudioOutputChannelCountForPlayReport"},
{29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"},
- {30, nullptr, "SetSpeakerAutoMuteEnabled"},
+ {30, &AudCtl::SetSpeakerAutoMuteEnabled, "SetSpeakerAutoMuteEnabled"},
{31, &AudCtl::IsSpeakerAutoMuteEnabled, "IsSpeakerAutoMuteEnabled"},
{32, nullptr, "GetActiveOutputTarget"},
{33, nullptr, "GetTargetDeviceInfo"},
@@ -68,6 +70,9 @@ AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} {
// clang-format on
RegisterHandlers(functions);
+
+ m_set_sys =
+ system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
}
AudCtl::~AudCtl() = default;
@@ -96,6 +101,33 @@ void AudCtl::GetTargetVolumeMax(HLERequestContext& ctx) {
rb.Push(target_max_volume);
}
+void AudCtl::GetAudioOutputMode(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto target{rp.PopEnum<Set::AudioOutputModeTarget>()};
+
+ Set::AudioOutputMode output_mode{};
+ const auto result = m_set_sys->GetAudioOutputMode(output_mode, target);
+
+ LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(result);
+ rb.PushEnum(output_mode);
+}
+
+void AudCtl::SetAudioOutputMode(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto target{rp.PopEnum<Set::AudioOutputModeTarget>()};
+ const auto output_mode{rp.PopEnum<Set::AudioOutputMode>()};
+
+ const auto result = m_set_sys->SetAudioOutputMode(target, output_mode);
+
+ LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
void AudCtl::GetForceMutePolicy(HLERequestContext& ctx) {
LOG_WARNING(Audio, "(STUBBED) called");
@@ -106,13 +138,31 @@ void AudCtl::GetForceMutePolicy(HLERequestContext& ctx) {
void AudCtl::GetOutputModeSetting(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto value = rp.Pop<u32>();
+ const auto target{rp.PopEnum<Set::AudioOutputModeTarget>()};
- LOG_WARNING(Audio, "(STUBBED) called, value={}", value);
+ LOG_WARNING(Audio, "(STUBBED) called, target={}", target);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
- rb.PushEnum(AudioOutputMode::PcmAuto);
+ rb.PushEnum(Set::AudioOutputMode::ch_7_1);
+}
+
+void AudCtl::SetOutputModeSetting(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto target{rp.PopEnum<Set::AudioOutputModeTarget>()};
+ const auto output_mode{rp.PopEnum<Set::AudioOutputMode>()};
+
+ LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void AudCtl::SetHeadphoneOutputLevelMode(HLERequestContext& ctx) {
+ LOG_WARNING(Audio, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
}
void AudCtl::GetHeadphoneOutputLevelMode(HLERequestContext& ctx) {
@@ -123,14 +173,28 @@ void AudCtl::GetHeadphoneOutputLevelMode(HLERequestContext& ctx) {
rb.PushEnum(HeadphoneOutputLevelMode::Normal);
}
+void AudCtl::SetSpeakerAutoMuteEnabled(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto is_speaker_auto_mute_enabled{rp.Pop<bool>()};
+
+ LOG_WARNING(Audio, "(STUBBED) called, is_speaker_auto_mute_enabled={}",
+ is_speaker_auto_mute_enabled);
+
+ const auto result = m_set_sys->SetSpeakerAutoMuteFlag(is_speaker_auto_mute_enabled);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
void AudCtl::IsSpeakerAutoMuteEnabled(HLERequestContext& ctx) {
- const bool is_speaker_auto_mute_enabled = false;
+ bool is_speaker_auto_mute_enabled{};
+ const auto result = m_set_sys->GetSpeakerAutoMuteFlag(is_speaker_auto_mute_enabled);
LOG_WARNING(Audio, "(STUBBED) called, is_speaker_auto_mute_enabled={}",
is_speaker_auto_mute_enabled);
IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
+ rb.Push(result);
rb.Push<u8>(is_speaker_auto_mute_enabled);
}
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 {
class System;
}
+namespace Service::Set {
+class ISystemSettingsServer;
+}
+
namespace Service::Audio {
class AudCtl final : public ServiceFramework<AudCtl> {
@@ -17,14 +21,6 @@ public:
~AudCtl() override;
private:
- enum class AudioOutputMode {
- Invalid,
- Pcm1ch,
- Pcm2ch,
- Pcm6ch,
- PcmAuto,
- };
-
enum class ForceMutePolicy {
Disable,
SpeakerMuteOnHeadphoneUnplugged,
@@ -37,10 +33,18 @@ private:
void GetTargetVolumeMin(HLERequestContext& ctx);
void GetTargetVolumeMax(HLERequestContext& ctx);
+ void GetAudioOutputMode(HLERequestContext& ctx);
+ void SetAudioOutputMode(HLERequestContext& ctx);
void GetForceMutePolicy(HLERequestContext& ctx);
void GetOutputModeSetting(HLERequestContext& ctx);
+ void SetOutputModeSetting(HLERequestContext& ctx);
+ void SetHeadphoneOutputLevelMode(HLERequestContext& ctx);
void GetHeadphoneOutputLevelMode(HLERequestContext& ctx);
+ void SetSpeakerAutoMuteEnabled(HLERequestContext& ctx);
void IsSpeakerAutoMuteEnabled(HLERequestContext& ctx);
+ void AcquireTargetNotification(HLERequestContext& ctx);
+
+ std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys;
};
} // 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:
explicit IAudioRenderer(Core::System& system_, Manager& manager_,
AudioCore::AudioRendererParameterInternal& params,
Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
- u32 process_handle, u64 applet_resource_user_id, s32 session_id)
+ u32 process_handle, Kernel::KProcess& process_,
+ u64 applet_resource_user_id, s32 session_id)
: ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"},
rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_},
- impl{std::make_unique<Renderer>(system_, manager, rendered_event)} {
+ impl{std::make_unique<Renderer>(system_, manager, rendered_event)}, process{process_} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IAudioRenderer::GetSampleRate, "GetSampleRate"},
@@ -59,13 +60,15 @@ public:
// clang-format on
RegisterHandlers(functions);
- impl->Initialize(params, transfer_memory, transfer_memory_size, process_handle,
+ process.Open();
+ impl->Initialize(params, transfer_memory, transfer_memory_size, process_handle, process,
applet_resource_user_id, session_id);
}
~IAudioRenderer() override {
impl->Finalize();
service_context.CloseEvent(rendered_event);
+ process.Close();
}
private:
@@ -235,6 +238,7 @@ private:
Kernel::KEvent* rendered_event;
Manager& manager;
std::unique_ptr<Renderer> impl;
+ Kernel::KProcess& process;
Common::ScratchBuffer<u8> output_buffer;
Common::ScratchBuffer<u8> performance_buffer;
};
@@ -455,7 +459,7 @@ void AudRenU::OpenAudioRenderer(HLERequestContext& ctx) {
return;
}
- auto process{ctx.GetObjectFromHandle<Kernel::KProcess>(process_handle)};
+ auto process{ctx.GetObjectFromHandle<Kernel::KProcess>(process_handle).GetPointerUnsafe()};
auto transfer_memory{ctx.GetObjectFromHandle<Kernel::KTransferMemory>(transfer_memory_handle)};
const auto session_id{impl->GetSessionId()};
@@ -472,7 +476,7 @@ void AudRenU::OpenAudioRenderer(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IAudioRenderer>(system, *impl, params, transfer_memory.GetPointerUnsafe(),
- transfer_memory_size, process_handle,
+ transfer_memory_size, process_handle, *process,
applet_resource_user_id, session_id);
}
@@ -522,7 +526,7 @@ void AudRenU::GetAudioDeviceService(HLERequestContext& ctx) {
}
void AudRenU::OpenAudioRendererForManualExecution(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Audio, "called");
+ LOG_ERROR(Service_Audio, "called. Implement me!");
}
void AudRenU::GetAudioDeviceServiceWithRevisionInfo(HLERequestContext& ctx) {
diff --git a/src/core/hle/service/caps/caps_manager.cpp b/src/core/hle/service/caps/caps_manager.cpp
index e3b8ecf3e..3a22b135f 100644
--- a/src/core/hle/service/caps/caps_manager.cpp
+++ b/src/core/hle/service/caps/caps_manager.cpp
@@ -246,10 +246,10 @@ Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry,
system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true);
std::shared_ptr<Service::PSC::Time::SystemClock> user_clock{};
- static_service->GetStandardUserSystemClock(user_clock);
+ static_service->GetStandardUserSystemClock(&user_clock);
s64 posix_time{};
- auto result = user_clock->GetCurrentTime(posix_time);
+ auto result = user_clock->GetCurrentTime(&posix_time);
if (result.IsError()) {
return result;
@@ -268,10 +268,10 @@ Result AlbumManager::SaveEditedScreenShot(ApplicationAlbumEntry& out_entry,
system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true);
std::shared_ptr<Service::PSC::Time::SystemClock> user_clock{};
- static_service->GetStandardUserSystemClock(user_clock);
+ static_service->GetStandardUserSystemClock(&user_clock);
s64 posix_time{};
- auto result = user_clock->GetCurrentTime(posix_time);
+ auto result = user_clock->GetCurrentTime(&posix_time);
if (result.IsError()) {
return result;
@@ -470,11 +470,11 @@ AlbumFileDateTime AlbumManager::ConvertToAlbumDateTime(u64 posix_time) const {
system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true);
std::shared_ptr<Service::Glue::Time::TimeZoneService> timezone_service{};
- static_service->GetTimeZoneService(timezone_service);
+ static_service->GetTimeZoneService(&timezone_service);
Service::PSC::Time::CalendarTime calendar_time{};
Service::PSC::Time::CalendarAdditionalInfo additional_info{};
- timezone_service->ToCalendarTimeWithMyRule(calendar_time, additional_info, posix_time);
+ timezone_service->ToCalendarTimeWithMyRule(&calendar_time, &additional_info, posix_time);
return {
.year = calendar_time.year,
diff --git a/src/core/hle/service/cmif_serialization.h b/src/core/hle/service/cmif_serialization.h
index 9eb10e816..9ee26400d 100644
--- a/src/core/hle/service/cmif_serialization.h
+++ b/src/core/hle/service/cmif_serialization.h
@@ -12,6 +12,109 @@
namespace Service {
// clang-format off
+template <typename T>
+struct UnwrapArg {
+ using Type = std::remove_cvref_t<T>;
+};
+
+template <typename T, int A>
+struct UnwrapArg<InLargeData<T, A>> {
+ using Type = std::remove_cv_t<typename InLargeData<T, A>::Type>;
+};
+
+template <typename T>
+struct UnwrapArg<Out<T>> {
+ using Type = AutoOut<typename Out<T>::Type>;
+};
+
+template <typename T>
+struct UnwrapArg<OutCopyHandle<T>> {
+ using Type = AutoOut<typename OutCopyHandle<T>::Type>;
+};
+
+template <typename T>
+struct UnwrapArg<OutMoveHandle<T>> {
+ using Type = AutoOut<typename OutMoveHandle<T>::Type>;
+};
+
+template <typename T, int A>
+struct UnwrapArg<OutLargeData<T, A>> {
+ using Type = AutoOut<typename OutLargeData<T, A>::Type>;
+};
+
+enum class ArgumentType {
+ InProcessId,
+ InData,
+ InInterface,
+ InCopyHandle,
+ OutData,
+ OutInterface,
+ OutCopyHandle,
+ OutMoveHandle,
+ InBuffer,
+ InLargeData,
+ OutBuffer,
+ OutLargeData,
+};
+
+template <typename T>
+struct ArgumentTraits;
+
+template <>
+struct ArgumentTraits<ClientProcessId> {
+ static constexpr ArgumentType Type = ArgumentType::InProcessId;
+};
+
+template <typename T>
+struct ArgumentTraits<SharedPointer<T>> {
+ static constexpr ArgumentType Type = ArgumentType::InInterface;
+};
+
+template <typename T>
+struct ArgumentTraits<InCopyHandle<T>> {
+ static constexpr ArgumentType Type = ArgumentType::InCopyHandle;
+};
+
+template <typename T>
+struct ArgumentTraits<Out<SharedPointer<T>>> {
+ static constexpr ArgumentType Type = ArgumentType::OutInterface;
+};
+
+template <typename T>
+struct ArgumentTraits<Out<T>> {
+ static constexpr ArgumentType Type = ArgumentType::OutData;
+};
+
+template <typename T>
+struct ArgumentTraits<OutCopyHandle<T>> {
+ static constexpr ArgumentType Type = ArgumentType::OutCopyHandle;
+};
+
+template <typename T>
+struct ArgumentTraits<OutMoveHandle<T>> {
+ static constexpr ArgumentType Type = ArgumentType::OutMoveHandle;
+};
+
+template <typename T, int A>
+struct ArgumentTraits<Buffer<T, A>> {
+ static constexpr ArgumentType Type = (A & BufferAttr_In) == 0 ? ArgumentType::OutBuffer : ArgumentType::InBuffer;
+};
+
+template <typename T, int A>
+struct ArgumentTraits<InLargeData<T, A>> {
+ static constexpr ArgumentType Type = ArgumentType::InLargeData;
+};
+
+template <typename T, int A>
+struct ArgumentTraits<OutLargeData<T, A>> {
+ static constexpr ArgumentType Type = ArgumentType::OutLargeData;
+};
+
+template <typename T>
+struct ArgumentTraits {
+ static constexpr ArgumentType Type = ArgumentType::InData;
+};
+
struct RequestLayout {
u32 copy_handle_count;
u32 move_handle_count;
@@ -122,6 +225,8 @@ void ReadInArgument(bool is_domain, CallArguments& args, const u8* raw_data, HLE
static_assert(PrevAlign <= ArgAlign, "Input argument is not ordered by alignment");
static_assert(!RawDataFinished, "All input interface arguments must appear after raw data");
+ static_assert(!std::is_pointer_v<ArgType>, "Input raw data must not be a pointer");
+ static_assert(std::is_trivially_copyable_v<ArgType>, "Input raw data must be trivially copyable");
constexpr size_t ArgOffset = Common::AlignUp(DataOffset, ArgAlign);
constexpr size_t ArgEnd = ArgOffset + ArgSize;
@@ -198,7 +303,7 @@ void ReadInArgument(bool is_domain, CallArguments& args, const u8* raw_data, HLE
constexpr size_t BufferSize = sizeof(ArgType);
// Clear the existing data.
- std::memset(&std::get<ArgIndex>(args), 0, BufferSize);
+ std::memset(&std::get<ArgIndex>(args).raw, 0, BufferSize);
return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex, OutBufferIndex + 1, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutBuffer) {
@@ -237,27 +342,29 @@ void WriteOutArgument(bool is_domain, CallArguments& args, u8* raw_data, HLERequ
static_assert(PrevAlign <= ArgAlign, "Output argument is not ordered by alignment");
static_assert(!RawDataFinished, "All output interface arguments must appear after raw data");
+ static_assert(!std::is_pointer_v<ArgType>, "Output raw data must not be a pointer");
+ static_assert(std::is_trivially_copyable_v<decltype(std::get<ArgIndex>(args).raw)>, "Output raw data must be trivially copyable");
constexpr size_t ArgOffset = Common::AlignUp(DataOffset, ArgAlign);
constexpr size_t ArgEnd = ArgOffset + ArgSize;
- std::memcpy(raw_data + ArgOffset, &std::get<ArgIndex>(args), ArgSize);
+ std::memcpy(raw_data + ArgOffset, &std::get<ArgIndex>(args).raw, ArgSize);
return WriteOutArgument<MethodArguments, CallArguments, ArgAlign, ArgEnd, OutBufferIndex, false, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutInterface) {
if (is_domain) {
- ctx.AddDomainObject(std::get<ArgIndex>(args));
+ ctx.AddDomainObject(std::get<ArgIndex>(args).raw);
} else {
- ctx.AddMoveInterface(std::get<ArgIndex>(args));
+ ctx.AddMoveInterface(std::get<ArgIndex>(args).raw);
}
return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, true, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutCopyHandle) {
- ctx.AddCopyObject(std::get<ArgIndex>(args));
+ ctx.AddCopyObject(std::get<ArgIndex>(args).raw);
return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutMoveHandle) {
- ctx.AddMoveObject(std::get<ArgIndex>(args));
+ ctx.AddMoveObject(std::get<ArgIndex>(args).raw);
return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutLargeData) {
@@ -302,10 +409,10 @@ void CmifReplyWrapImpl(HLERequestContext& ctx, T& t, Result (T::*f)(A...)) {
}
const bool is_domain = Domain ? ctx.GetManager()->IsDomain() : false;
- using MethodArguments = std::tuple<std::remove_reference_t<A>...>;
+ using MethodArguments = std::tuple<std::remove_cvref_t<A>...>;
OutTemporaryBuffers buffers{};
- auto call_arguments = std::tuple<typename RemoveOut<A>::Type...>();
+ auto call_arguments = std::tuple<typename UnwrapArg<A>::Type...>();
// Read inputs.
const size_t offset_plus_command_id = ctx.GetDataPayloadOffset() + 2;
diff --git a/src/core/hle/service/cmif_types.h b/src/core/hle/service/cmif_types.h
index 2610c49f3..dc06169f4 100644
--- a/src/core/hle/service/cmif_types.h
+++ b/src/core/hle/service/cmif_types.h
@@ -13,21 +13,30 @@ namespace Service {
// clang-format off
template <typename T>
+struct AutoOut {
+ T raw;
+};
+
+template <typename T>
class Out {
public:
using Type = T;
- /* implicit */ Out(Type& t) : raw(&t) {}
- ~Out() = default;
+ /* implicit */ Out(AutoOut<Type>& t) : raw(&t.raw) {}
+ /* implicit */ Out(Type* t) : raw(t) {}
Type* Get() const {
return raw;
}
- Type& operator*() {
+ Type& operator*() const {
return *raw;
}
+ Type* operator->() const {
+ return raw;
+ }
+
private:
Type* raw;
};
@@ -35,6 +44,9 @@ private:
template <typename T>
using SharedPointer = std::shared_ptr<T>;
+template <typename T>
+using OutInterface = Out<SharedPointer<T>>;
+
struct ClientProcessId {
explicit operator bool() const {
return pid != 0;
@@ -101,17 +113,21 @@ class OutCopyHandle {
public:
using Type = T*;
- /* implicit */ OutCopyHandle(Type& t) : raw(&t) {}
- ~OutCopyHandle() = default;
+ /* implicit */ OutCopyHandle(AutoOut<Type>& t) : raw(&t.raw) {}
+ /* implicit */ OutCopyHandle(Type* t) : raw(t) {}
Type* Get() const {
return raw;
}
- Type& operator*() {
+ Type& operator*() const {
return *raw;
}
+ Type* operator->() const {
+ return raw;
+ }
+
private:
Type* raw;
};
@@ -121,30 +137,34 @@ class OutMoveHandle {
public:
using Type = T*;
- /* implicit */ OutMoveHandle(Type& t) : raw(&t) {}
- ~OutMoveHandle() = default;
+ /* implicit */ OutMoveHandle(AutoOut<Type>& t) : raw(&t.raw) {}
+ /* implicit */ OutMoveHandle(Type* t) : raw(t) {}
Type* Get() const {
return raw;
}
- Type& operator*() {
+ Type& operator*() const {
return *raw;
}
+ Type* operator->() const {
+ return raw;
+ }
+
private:
Type* raw;
};
enum BufferAttr : int {
- BufferAttr_In = (1U << 0),
- BufferAttr_Out = (1U << 1),
- BufferAttr_HipcMapAlias = (1U << 2),
- BufferAttr_HipcPointer = (1U << 3),
- BufferAttr_FixedSize = (1U << 4),
- BufferAttr_HipcAutoSelect = (1U << 5),
- BufferAttr_HipcMapTransferAllowsNonSecure = (1U << 6),
- BufferAttr_HipcMapTransferAllowsNonDevice = (1U << 7),
+ /* 0x01 */ BufferAttr_In = (1U << 0),
+ /* 0x02 */ BufferAttr_Out = (1U << 1),
+ /* 0x04 */ BufferAttr_HipcMapAlias = (1U << 2),
+ /* 0x08 */ BufferAttr_HipcPointer = (1U << 3),
+ /* 0x10 */ BufferAttr_FixedSize = (1U << 4),
+ /* 0x20 */ BufferAttr_HipcAutoSelect = (1U << 5),
+ /* 0x40 */ BufferAttr_HipcMapTransferAllowsNonSecure = (1U << 6),
+ /* 0x80 */ BufferAttr_HipcMapTransferAllowsNonDevice = (1U << 7),
};
template <typename T, int A>
@@ -172,123 +192,80 @@ struct Buffer : public std::span<T> {
}
};
-template <BufferAttr A>
+template <int A>
using InBuffer = Buffer<const u8, BufferAttr_In | A>;
-template <typename T, BufferAttr A>
+template <typename T, int A>
using InArray = Buffer<T, BufferAttr_In | A>;
-template <BufferAttr A>
+template <int A>
using OutBuffer = Buffer<u8, BufferAttr_Out | A>;
-template <typename T, BufferAttr A>
+template <typename T, int A>
using OutArray = Buffer<T, BufferAttr_Out | A>;
template <typename T, int A>
-struct LargeData : public T {
+class InLargeData {
+public:
static_assert(std::is_trivially_copyable_v<T>, "LargeData type must be trivially copyable");
- static_assert((A & BufferAttr_FixedSize) != 0, "LargeData attr must contain FixedSize");
- static_assert(((A & BufferAttr_In) == 0) ^ ((A & BufferAttr_Out) == 0), "LargeData attr must be In or Out");
- static constexpr BufferAttr Attr = static_cast<BufferAttr>(A);
- using Type = T;
-
- /* implicit */ LargeData(const T& rhs) : T(rhs) {}
- /* implicit */ LargeData() = default;
-};
-
-template <typename T, BufferAttr A>
-using InLargeData = LargeData<T, BufferAttr_FixedSize | BufferAttr_In | A>;
-
-template <typename T, BufferAttr A>
-using OutLargeData = LargeData<T, BufferAttr_FixedSize | BufferAttr_Out | A>;
+ static_assert((A & BufferAttr_Out) == 0, "InLargeData attr must not be Out");
+ static constexpr BufferAttr Attr = static_cast<BufferAttr>(A | BufferAttr_In | BufferAttr_FixedSize);
+ using Type = const T;
-template <typename T>
-struct RemoveOut {
- using Type = std::remove_reference_t<T>;
-};
-
-template <typename T>
-struct RemoveOut<Out<T>> {
- using Type = typename Out<T>::Type;
-};
+ /* implicit */ InLargeData(Type& t) : raw(&t) {}
+ ~InLargeData() = default;
-template <typename T>
-struct RemoveOut<OutCopyHandle<T>> {
- using Type = typename OutCopyHandle<T>::Type;
-};
-
-template <typename T>
-struct RemoveOut<OutMoveHandle<T>> {
- using Type = typename OutMoveHandle<T>::Type;
-};
-
-enum class ArgumentType {
- InProcessId,
- InData,
- InInterface,
- InCopyHandle,
- OutData,
- OutInterface,
- OutCopyHandle,
- OutMoveHandle,
- InBuffer,
- InLargeData,
- OutBuffer,
- OutLargeData,
-};
+ InLargeData& operator=(Type* rhs) {
+ raw = rhs;
+ return *this;
+ }
-template <typename T>
-struct ArgumentTraits;
+ Type* Get() const {
+ return raw;
+ }
-template <>
-struct ArgumentTraits<ClientProcessId> {
- static constexpr ArgumentType Type = ArgumentType::InProcessId;
-};
+ Type& operator*() const {
+ return *raw;
+ }
-template <typename T>
-struct ArgumentTraits<SharedPointer<T>> {
- static constexpr ArgumentType Type = ArgumentType::InInterface;
-};
+ Type* operator->() const {
+ return raw;
+ }
-template <typename T>
-struct ArgumentTraits<InCopyHandle<T>> {
- static constexpr ArgumentType Type = ArgumentType::InCopyHandle;
-};
+ explicit operator bool() const {
+ return raw != nullptr;
+ }
-template <typename T>
-struct ArgumentTraits<Out<SharedPointer<T>>> {
- static constexpr ArgumentType Type = ArgumentType::OutInterface;
+private:
+ Type* raw;
};
-template <typename T>
-struct ArgumentTraits<Out<T>> {
- static constexpr ArgumentType Type = ArgumentType::OutData;
-};
+template <typename T, int A>
+class OutLargeData {
+public:
+ static_assert(std::is_trivially_copyable_v<T>, "LargeData type must be trivially copyable");
+ static_assert((A & BufferAttr_In) == 0, "OutLargeData attr must not be In");
+ static constexpr BufferAttr Attr = static_cast<BufferAttr>(A | BufferAttr_In | BufferAttr_FixedSize);
+ using Type = T;
-template <typename T>
-struct ArgumentTraits<OutCopyHandle<T>> {
- static constexpr ArgumentType Type = ArgumentType::OutCopyHandle;
-};
+ /* implicit */ OutLargeData(Type* t) : raw(t) {}
+ /* implicit */ OutLargeData(AutoOut<T>& t) : raw(&t.raw) {}
-template <typename T>
-struct ArgumentTraits<OutMoveHandle<T>> {
- static constexpr ArgumentType Type = ArgumentType::OutMoveHandle;
-};
+ Type* Get() const {
+ return raw;
+ }
-template <typename T, int A>
-struct ArgumentTraits<Buffer<T, A>> {
- static constexpr ArgumentType Type = (A & BufferAttr_In) == 0 ? ArgumentType::OutBuffer : ArgumentType::InBuffer;
-};
+ Type& operator*() const {
+ return *raw;
+ }
-template <typename T, int A>
-struct ArgumentTraits<LargeData<T, A>> {
- static constexpr ArgumentType Type = (A & BufferAttr_In) == 0 ? ArgumentType::OutLargeData : ArgumentType::InLargeData;
-};
+ Type* operator->() const {
+ return raw;
+ }
-template <typename T>
-struct ArgumentTraits {
- static constexpr ArgumentType Type = ArgumentType::InData;
+private:
+ Type* raw;
};
// clang-format on
-} // namespace Service
+} // namespace Service \ No newline at end of file
diff --git a/src/core/hle/service/glue/time/alarm_worker.cpp b/src/core/hle/service/glue/time/alarm_worker.cpp
index f549ed00a..3ff071f4a 100644
--- a/src/core/hle/service/glue/time/alarm_worker.cpp
+++ b/src/core/hle/service/glue/time/alarm_worker.cpp
@@ -41,7 +41,7 @@ bool AlarmWorker::GetClosestAlarmInfo(Service::PSC::Time::AlarmInfo& out_alarm_i
Service::PSC::Time::AlarmInfo alarm_info{};
s64 closest_time{};
- auto res = m_time_m->GetClosestAlarmInfo(is_valid, alarm_info, closest_time);
+ auto res = m_time_m->GetClosestAlarmInfo(&is_valid, &alarm_info, &closest_time);
ASSERT(res == ResultSuccess);
if (is_valid) {
@@ -76,6 +76,7 @@ void AlarmWorker::OnPowerStateChanged() {
Result AlarmWorker::AttachToClosestAlarmEvent() {
m_time_m->GetClosestAlarmUpdatedEvent(&m_event);
+
R_SUCCEED();
}
diff --git a/src/core/hle/service/glue/time/alarm_worker.h b/src/core/hle/service/glue/time/alarm_worker.h
index f269cffdb..131d012a6 100644
--- a/src/core/hle/service/glue/time/alarm_worker.h
+++ b/src/core/hle/service/glue/time/alarm_worker.h
@@ -26,7 +26,7 @@ public:
void Initialize(std::shared_ptr<Service::PSC::Time::ServiceManager> time_m);
- Kernel::KEvent& GetEvent() {
+ Kernel::KReadableEvent& GetEvent() {
return *m_event;
}
@@ -44,7 +44,7 @@ private:
KernelHelpers::ServiceContext m_ctx;
std::shared_ptr<Service::PSC::Time::ServiceManager> m_time_m;
- Kernel::KEvent* m_event{};
+ Kernel::KReadableEvent* m_event{};
Kernel::KEvent* m_timer_event{};
std::shared_ptr<Core::Timing::EventType> m_timer_timing_event;
StandardSteadyClockResource& m_steady_clock_resource;
diff --git a/src/core/hle/service/glue/time/file_timestamp_worker.cpp b/src/core/hle/service/glue/time/file_timestamp_worker.cpp
index 5a6309549..048ff174c 100644
--- a/src/core/hle/service/glue/time/file_timestamp_worker.cpp
+++ b/src/core/hle/service/glue/time/file_timestamp_worker.cpp
@@ -13,8 +13,8 @@ void FileTimestampWorker::SetFilesystemPosixTime() {
Service::PSC::Time::CalendarTime calendar_time{};
Service::PSC::Time::CalendarAdditionalInfo additional_info{};
- if (m_initialized && m_system_clock->GetCurrentTime(time) == ResultSuccess &&
- m_time_zone->ToCalendarTimeWithMyRule(calendar_time, additional_info, time) ==
+ if (m_initialized && m_system_clock->GetCurrentTime(&time) == ResultSuccess &&
+ m_time_zone->ToCalendarTimeWithMyRule(&calendar_time, &additional_info, time) ==
ResultSuccess) {
// TODO IFileSystemProxy::SetCurrentPosixTime
}
diff --git a/src/core/hle/service/glue/time/manager.cpp b/src/core/hle/service/glue/time/manager.cpp
index b56762941..0c27e8029 100644
--- a/src/core/hle/service/glue/time/manager.cpp
+++ b/src/core/hle/service/glue/time/manager.cpp
@@ -79,18 +79,18 @@ Service::PSC::Time::LocationName GetTimeZoneString(Service::PSC::Time::LocationN
auto configured_zone = Settings::GetTimeZoneString(Settings::values.time_zone_index.GetValue());
Service::PSC::Time::LocationName configured_name{};
- std::memcpy(configured_name.name.data(), configured_zone.data(),
- std::min(configured_name.name.size(), configured_zone.size()));
+ std::memcpy(configured_name.data(), configured_zone.data(),
+ std::min(configured_name.size(), configured_zone.size()));
if (!IsTimeZoneBinaryValid(configured_name)) {
configured_zone = Common::TimeZone::FindSystemTimeZone();
configured_name = {};
- std::memcpy(configured_name.name.data(), configured_zone.data(),
- std::min(configured_name.name.size(), configured_zone.size()));
+ std::memcpy(configured_name.data(), configured_zone.data(),
+ std::min(configured_name.size(), configured_zone.size()));
}
ASSERT_MSG(IsTimeZoneBinaryValid(configured_name), "Invalid time zone {}!",
- configured_name.name.data());
+ configured_name.data());
return configured_name;
}
@@ -103,7 +103,7 @@ TimeManager::TimeManager(Core::System& system)
m_time_m =
system.ServiceManager().GetService<Service::PSC::Time::ServiceManager>("time:m", true);
- auto res = m_time_m->GetStaticServiceAsServiceManager(m_time_sm);
+ auto res = m_time_m->GetStaticServiceAsServiceManager(&m_time_sm);
ASSERT(res == ResultSuccess);
m_set_sys =
@@ -114,10 +114,10 @@ TimeManager::TimeManager(Core::System& system)
m_worker.Initialize(m_time_sm, m_set_sys);
- res = m_time_sm->GetStandardUserSystemClock(m_file_timestamp_worker.m_system_clock);
+ res = m_time_sm->GetStandardUserSystemClock(&m_file_timestamp_worker.m_system_clock);
ASSERT(res == ResultSuccess);
- res = m_time_sm->GetTimeZoneService(m_file_timestamp_worker.m_time_zone);
+ res = m_time_sm->GetTimeZoneService(&m_file_timestamp_worker.m_time_zone);
ASSERT(res == ResultSuccess);
res = SetupStandardSteadyClockCore();
@@ -161,8 +161,8 @@ TimeManager::TimeManager(Core::System& system)
automatic_correction_time_point);
ASSERT(res == ResultSuccess);
- res = m_time_m->SetupStandardUserSystemClockCore(automatic_correction_time_point,
- is_automatic_correction_enabled);
+ res = m_time_m->SetupStandardUserSystemClockCore(is_automatic_correction_enabled,
+ automatic_correction_time_point);
ASSERT(res == ResultSuccess);
res = m_time_m->SetupEphemeralNetworkSystemClockCore();
@@ -184,12 +184,12 @@ TimeManager::TimeManager(Core::System& system)
m_file_timestamp_worker.m_initialized = true;
s64 system_clock_time{};
- if (m_file_timestamp_worker.m_system_clock->GetCurrentTime(system_clock_time) ==
+ if (m_file_timestamp_worker.m_system_clock->GetCurrentTime(&system_clock_time) ==
ResultSuccess) {
Service::PSC::Time::CalendarTime calendar_time{};
Service::PSC::Time::CalendarAdditionalInfo calendar_additional{};
if (m_file_timestamp_worker.m_time_zone->ToCalendarTimeWithMyRule(
- calendar_time, calendar_additional, system_clock_time) == ResultSuccess) {
+ &calendar_time, &calendar_additional, system_clock_time) == ResultSuccess) {
// TODO IFileSystemProxy::SetCurrentPosixTime(system_clock_time,
// calendar_additional.ut_offset)
}
@@ -228,10 +228,9 @@ Result TimeManager::SetupStandardSteadyClockCore() {
m_set_sys->SetExternalSteadyClockSourceId(clock_source_id);
}
- res = m_time_m->SetupStandardSteadyClockCore(clock_source_id, m_steady_clock_resource.GetTime(),
- external_steady_clock_internal_offset_ns,
- standard_steady_clock_test_offset_ns,
- reset_detected);
+ res = m_time_m->SetupStandardSteadyClockCore(
+ reset_detected, clock_source_id, m_steady_clock_resource.GetTime(),
+ external_steady_clock_internal_offset_ns, standard_steady_clock_test_offset_ns);
ASSERT(res == ResultSuccess);
R_SUCCEED();
}
@@ -243,14 +242,15 @@ Result TimeManager::SetupTimeZoneServiceCore() {
auto configured_zone = GetTimeZoneString(name);
- if (configured_zone.name != name.name) {
+ if (configured_zone != name) {
m_set_sys->SetDeviceTimeZoneLocationName(configured_zone);
name = configured_zone;
std::shared_ptr<Service::PSC::Time::SystemClock> local_clock;
- m_time_sm->GetStandardLocalSystemClock(local_clock);
+ m_time_sm->GetStandardLocalSystemClock(&local_clock);
+
Service::PSC::Time::SystemClockContext context{};
- local_clock->GetSystemClockContext(context);
+ local_clock->GetSystemClockContext(&context);
m_set_sys->SetDeviceTimeZoneLocationUpdatedTime(context.steady_time_point);
}
@@ -267,7 +267,7 @@ Result TimeManager::SetupTimeZoneServiceCore() {
res = GetTimeZoneRule(rule_buffer, rule_size, name);
ASSERT(res == ResultSuccess);
- res = m_time_m->SetupTimeZoneServiceCore(name, time_point, rule_version, location_count,
+ res = m_time_m->SetupTimeZoneServiceCore(name, rule_version, location_count, time_point,
rule_buffer);
ASSERT(res == ResultSuccess);
diff --git a/src/core/hle/service/glue/time/static.cpp b/src/core/hle/service/glue/time/static.cpp
index 63b7d91da..f56db76e1 100644
--- a/src/core/hle/service/glue/time/static.cpp
+++ b/src/core/hle/service/glue/time/static.cpp
@@ -3,9 +3,11 @@
#include <chrono>
+#include "common/scope_exit.h"
#include "core/core.h"
#include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/kernel/svc.h"
+#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/glue/time/file_timestamp_worker.h"
#include "core/hle/service/glue/time/static.h"
#include "core/hle/service/psc/time/errors.h"
@@ -41,25 +43,25 @@ StaticService::StaticService(Core::System& system_,
time->m_steady_clock_resource} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, &StaticService::Handle_GetStandardUserSystemClock, "GetStandardUserSystemClock"},
- {1, &StaticService::Handle_GetStandardNetworkSystemClock, "GetStandardNetworkSystemClock"},
- {2, &StaticService::Handle_GetStandardSteadyClock, "GetStandardSteadyClock"},
- {3, &StaticService::Handle_GetTimeZoneService, "GetTimeZoneService"},
- {4, &StaticService::Handle_GetStandardLocalSystemClock, "GetStandardLocalSystemClock"},
- {5, &StaticService::Handle_GetEphemeralNetworkSystemClock, "GetEphemeralNetworkSystemClock"},
- {20, &StaticService::Handle_GetSharedMemoryNativeHandle, "GetSharedMemoryNativeHandle"},
- {50, &StaticService::Handle_SetStandardSteadyClockInternalOffset, "SetStandardSteadyClockInternalOffset"},
- {51, &StaticService::Handle_GetStandardSteadyClockRtcValue, "GetStandardSteadyClockRtcValue"},
- {100, &StaticService::Handle_IsStandardUserSystemClockAutomaticCorrectionEnabled, "IsStandardUserSystemClockAutomaticCorrectionEnabled"},
- {101, &StaticService::Handle_SetStandardUserSystemClockAutomaticCorrectionEnabled, "SetStandardUserSystemClockAutomaticCorrectionEnabled"},
- {102, &StaticService::Handle_GetStandardUserSystemClockInitialYear, "GetStandardUserSystemClockInitialYear"},
- {200, &StaticService::Handle_IsStandardNetworkSystemClockAccuracySufficient, "IsStandardNetworkSystemClockAccuracySufficient"},
- {201, &StaticService::Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedTime, "GetStandardUserSystemClockAutomaticCorrectionUpdatedTime"},
- {300, &StaticService::Handle_CalculateMonotonicSystemClockBaseTimePoint, "CalculateMonotonicSystemClockBaseTimePoint"},
- {400, &StaticService::Handle_GetClockSnapshot, "GetClockSnapshot"},
- {401, &StaticService::Handle_GetClockSnapshotFromSystemClockContext, "GetClockSnapshotFromSystemClockContext"},
- {500, &StaticService::Handle_CalculateStandardUserSystemClockDifferenceByUser, "CalculateStandardUserSystemClockDifferenceByUser"},
- {501, &StaticService::Handle_CalculateSpanBetween, "CalculateSpanBetween"},
+ {0, D<&StaticService::GetStandardUserSystemClock>, "GetStandardUserSystemClock"},
+ {1, D<&StaticService::GetStandardNetworkSystemClock>, "GetStandardNetworkSystemClock"},
+ {2, D<&StaticService::GetStandardSteadyClock>, "GetStandardSteadyClock"},
+ {3, D<&StaticService::GetTimeZoneService>, "GetTimeZoneService"},
+ {4, D<&StaticService::GetStandardLocalSystemClock>, "GetStandardLocalSystemClock"},
+ {5, D<&StaticService::GetEphemeralNetworkSystemClock>, "GetEphemeralNetworkSystemClock"},
+ {20, D<&StaticService::GetSharedMemoryNativeHandle>, "GetSharedMemoryNativeHandle"},
+ {50, D<&StaticService::SetStandardSteadyClockInternalOffset>, "SetStandardSteadyClockInternalOffset"},
+ {51, D<&StaticService::GetStandardSteadyClockRtcValue>, "GetStandardSteadyClockRtcValue"},
+ {100, D<&StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled>, "IsStandardUserSystemClockAutomaticCorrectionEnabled"},
+ {101, D<&StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled>, "SetStandardUserSystemClockAutomaticCorrectionEnabled"},
+ {102, D<&StaticService::GetStandardUserSystemClockInitialYear>, "GetStandardUserSystemClockInitialYear"},
+ {200, D<&StaticService::IsStandardNetworkSystemClockAccuracySufficient>, "IsStandardNetworkSystemClockAccuracySufficient"},
+ {201, D<&StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime>, "GetStandardUserSystemClockAutomaticCorrectionUpdatedTime"},
+ {300, D<&StaticService::CalculateMonotonicSystemClockBaseTimePoint>, "CalculateMonotonicSystemClockBaseTimePoint"},
+ {400, D<&StaticService::GetClockSnapshot>, "GetClockSnapshot"},
+ {401, D<&StaticService::GetClockSnapshotFromSystemClockContext>, "GetClockSnapshotFromSystemClockContext"},
+ {500, D<&StaticService::CalculateStandardUserSystemClockDifferenceByUser>, "CalculateStandardUserSystemClockDifferenceByUser"},
+ {501, D<&StaticService::CalculateSpanBetween>, "CalculateSpanBetween"},
};
// clang-format on
@@ -71,314 +73,80 @@ StaticService::StaticService(Core::System& system_,
if (m_setup_info.can_write_local_clock && m_setup_info.can_write_user_clock &&
!m_setup_info.can_write_network_clock && m_setup_info.can_write_timezone_device_location &&
!m_setup_info.can_write_steady_clock && !m_setup_info.can_write_uninitialized_clock) {
- m_time_m->GetStaticServiceAsAdmin(m_wrapped_service);
+ m_time_m->GetStaticServiceAsAdmin(&m_wrapped_service);
} else if (!m_setup_info.can_write_local_clock && !m_setup_info.can_write_user_clock &&
!m_setup_info.can_write_network_clock &&
!m_setup_info.can_write_timezone_device_location &&
!m_setup_info.can_write_steady_clock &&
!m_setup_info.can_write_uninitialized_clock) {
- m_time_m->GetStaticServiceAsUser(m_wrapped_service);
+ m_time_m->GetStaticServiceAsUser(&m_wrapped_service);
} else if (!m_setup_info.can_write_local_clock && !m_setup_info.can_write_user_clock &&
!m_setup_info.can_write_network_clock &&
!m_setup_info.can_write_timezone_device_location &&
m_setup_info.can_write_steady_clock && !m_setup_info.can_write_uninitialized_clock) {
- m_time_m->GetStaticServiceAsRepair(m_wrapped_service);
+ m_time_m->GetStaticServiceAsRepair(&m_wrapped_service);
} else {
UNREACHABLE();
}
- auto res = m_wrapped_service->GetTimeZoneService(m_time_zone);
+ auto res = m_wrapped_service->GetTimeZoneService(&m_time_zone);
ASSERT(res == ResultSuccess);
}
-void StaticService::Handle_GetStandardUserSystemClock(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- std::shared_ptr<Service::PSC::Time::SystemClock> service{};
- auto res = GetStandardUserSystemClock(service);
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(res);
- rb.PushIpcInterface<Service::PSC::Time::SystemClock>(std::move(service));
-}
-
-void StaticService::Handle_GetStandardNetworkSystemClock(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- std::shared_ptr<Service::PSC::Time::SystemClock> service{};
- auto res = GetStandardNetworkSystemClock(service);
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(res);
- rb.PushIpcInterface<Service::PSC::Time::SystemClock>(std::move(service));
-}
-
-void StaticService::Handle_GetStandardSteadyClock(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- std::shared_ptr<Service::PSC::Time::SteadyClock> service{};
- auto res = GetStandardSteadyClock(service);
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(res);
- rb.PushIpcInterface(std::move(service));
-}
-
-void StaticService::Handle_GetTimeZoneService(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- std::shared_ptr<TimeZoneService> service{};
- auto res = GetTimeZoneService(service);
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(res);
- rb.PushIpcInterface(std::move(service));
-}
-
-void StaticService::Handle_GetStandardLocalSystemClock(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- std::shared_ptr<Service::PSC::Time::SystemClock> service{};
- auto res = GetStandardLocalSystemClock(service);
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(res);
- rb.PushIpcInterface<Service::PSC::Time::SystemClock>(std::move(service));
-}
-
-void StaticService::Handle_GetEphemeralNetworkSystemClock(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- std::shared_ptr<Service::PSC::Time::SystemClock> service{};
- auto res = GetEphemeralNetworkSystemClock(service);
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(res);
- rb.PushIpcInterface<Service::PSC::Time::SystemClock>(std::move(service));
-}
-
-void StaticService::Handle_GetSharedMemoryNativeHandle(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- Kernel::KSharedMemory* shared_memory{};
- auto res = GetSharedMemoryNativeHandle(&shared_memory);
-
- IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(res);
- rb.PushCopyObjects(shared_memory);
-}
-
-void StaticService::Handle_SetStandardSteadyClockInternalOffset(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::RequestParser rp{ctx};
- auto offset_ns{rp.Pop<s64>()};
-
- auto res = SetStandardSteadyClockInternalOffset(offset_ns);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
-}
-
-void StaticService::Handle_GetStandardSteadyClockRtcValue(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- s64 rtc_value{};
- auto res = GetStandardSteadyClockRtcValue(rtc_value);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(res);
- rb.Push(rtc_value);
-}
-
-void StaticService::Handle_IsStandardUserSystemClockAutomaticCorrectionEnabled(
- HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- bool is_enabled{};
- auto res = IsStandardUserSystemClockAutomaticCorrectionEnabled(is_enabled);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(res);
- rb.Push<bool>(is_enabled);
-}
-
-void StaticService::Handle_SetStandardUserSystemClockAutomaticCorrectionEnabled(
- HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::RequestParser rp{ctx};
- auto automatic_correction{rp.Pop<bool>()};
-
- auto res = SetStandardUserSystemClockAutomaticCorrectionEnabled(automatic_correction);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
-}
-
-void StaticService::Handle_GetStandardUserSystemClockInitialYear(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- s32 initial_year{};
- auto res = GetStandardUserSystemClockInitialYear(initial_year);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(res);
- rb.Push(initial_year);
-}
-
-void StaticService::Handle_IsStandardNetworkSystemClockAccuracySufficient(HLERequestContext& ctx) {
+Result StaticService::GetStandardUserSystemClock(
+ OutInterface<Service::PSC::Time::SystemClock> out_service) {
LOG_DEBUG(Service_Time, "called.");
- bool is_sufficient{};
- auto res = IsStandardNetworkSystemClockAccuracySufficient(is_sufficient);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(res);
- rb.Push<bool>(is_sufficient);
+ R_RETURN(m_wrapped_service->GetStandardUserSystemClock(out_service));
}
-void StaticService::Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(
- HLERequestContext& ctx) {
+Result StaticService::GetStandardNetworkSystemClock(
+ OutInterface<Service::PSC::Time::SystemClock> out_service) {
LOG_DEBUG(Service_Time, "called.");
- Service::PSC::Time::SteadyClockTimePoint time_point{};
- auto res = GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(time_point);
-
- IPC::ResponseBuilder rb{ctx,
- 2 + sizeof(Service::PSC::Time::SteadyClockTimePoint) / sizeof(u32)};
- rb.Push(res);
- rb.PushRaw<Service::PSC::Time::SteadyClockTimePoint>(time_point);
+ R_RETURN(m_wrapped_service->GetStandardNetworkSystemClock(out_service));
}
-void StaticService::Handle_CalculateMonotonicSystemClockBaseTimePoint(HLERequestContext& ctx) {
+Result StaticService::GetStandardSteadyClock(
+ OutInterface<Service::PSC::Time::SteadyClock> out_service) {
LOG_DEBUG(Service_Time, "called.");
- IPC::RequestParser rp{ctx};
- auto context{rp.PopRaw<Service::PSC::Time::SystemClockContext>()};
-
- s64 time{};
- auto res = CalculateMonotonicSystemClockBaseTimePoint(time, context);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(res);
- rb.Push<s64>(time);
+ R_RETURN(m_wrapped_service->GetStandardSteadyClock(out_service));
}
-void StaticService::Handle_GetClockSnapshot(HLERequestContext& ctx) {
+Result StaticService::GetTimeZoneService(OutInterface<TimeZoneService> out_service) {
LOG_DEBUG(Service_Time, "called.");
- IPC::RequestParser rp{ctx};
- auto type{rp.PopEnum<Service::PSC::Time::TimeType>()};
-
- Service::PSC::Time::ClockSnapshot snapshot{};
- auto res = GetClockSnapshot(snapshot, type);
-
- ctx.WriteBuffer(snapshot);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
+ *out_service = std::make_shared<TimeZoneService>(
+ m_system, m_file_timestamp_worker, m_setup_info.can_write_timezone_device_location,
+ m_time_zone);
+ R_SUCCEED();
}
-void StaticService::Handle_GetClockSnapshotFromSystemClockContext(HLERequestContext& ctx) {
+Result StaticService::GetStandardLocalSystemClock(
+ OutInterface<Service::PSC::Time::SystemClock> out_service) {
LOG_DEBUG(Service_Time, "called.");
- IPC::RequestParser rp{ctx};
- auto clock_type{rp.PopEnum<Service::PSC::Time::TimeType>()};
- [[maybe_unused]] auto alignment{rp.Pop<u32>()};
- auto user_context{rp.PopRaw<Service::PSC::Time::SystemClockContext>()};
- auto network_context{rp.PopRaw<Service::PSC::Time::SystemClockContext>()};
-
- Service::PSC::Time::ClockSnapshot snapshot{};
- auto res =
- GetClockSnapshotFromSystemClockContext(snapshot, user_context, network_context, clock_type);
-
- ctx.WriteBuffer(snapshot);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
+ R_RETURN(m_wrapped_service->GetStandardLocalSystemClock(out_service));
}
-void StaticService::Handle_CalculateStandardUserSystemClockDifferenceByUser(
- HLERequestContext& ctx) {
+Result StaticService::GetEphemeralNetworkSystemClock(
+ OutInterface<Service::PSC::Time::SystemClock> out_service) {
LOG_DEBUG(Service_Time, "called.");
- Service::PSC::Time::ClockSnapshot a{};
- Service::PSC::Time::ClockSnapshot b{};
-
- auto a_buffer{ctx.ReadBuffer(0)};
- auto b_buffer{ctx.ReadBuffer(1)};
-
- std::memcpy(&a, a_buffer.data(), sizeof(Service::PSC::Time::ClockSnapshot));
- std::memcpy(&b, b_buffer.data(), sizeof(Service::PSC::Time::ClockSnapshot));
-
- s64 difference{};
- auto res = CalculateStandardUserSystemClockDifferenceByUser(difference, a, b);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(res);
- rb.Push(difference);
+ R_RETURN(m_wrapped_service->GetEphemeralNetworkSystemClock(out_service));
}
-void StaticService::Handle_CalculateSpanBetween(HLERequestContext& ctx) {
+Result StaticService::GetSharedMemoryNativeHandle(
+ OutCopyHandle<Kernel::KSharedMemory> out_shared_memory) {
LOG_DEBUG(Service_Time, "called.");
- Service::PSC::Time::ClockSnapshot a{};
- Service::PSC::Time::ClockSnapshot b{};
-
- auto a_buffer{ctx.ReadBuffer(0)};
- auto b_buffer{ctx.ReadBuffer(1)};
-
- std::memcpy(&a, a_buffer.data(), sizeof(Service::PSC::Time::ClockSnapshot));
- std::memcpy(&b, b_buffer.data(), sizeof(Service::PSC::Time::ClockSnapshot));
-
- s64 time{};
- auto res = CalculateSpanBetween(time, a, b);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(res);
- rb.Push(time);
-}
-
-// =============================== Implementations ===========================
-
-Result StaticService::GetStandardUserSystemClock(
- std::shared_ptr<Service::PSC::Time::SystemClock>& out_service) {
- R_RETURN(m_wrapped_service->GetStandardUserSystemClock(out_service));
-}
-
-Result StaticService::GetStandardNetworkSystemClock(
- std::shared_ptr<Service::PSC::Time::SystemClock>& out_service) {
- R_RETURN(m_wrapped_service->GetStandardNetworkSystemClock(out_service));
-}
-
-Result StaticService::GetStandardSteadyClock(
- std::shared_ptr<Service::PSC::Time::SteadyClock>& out_service) {
- R_RETURN(m_wrapped_service->GetStandardSteadyClock(out_service));
-}
-
-Result StaticService::GetTimeZoneService(std::shared_ptr<TimeZoneService>& out_service) {
- out_service = std::make_shared<TimeZoneService>(m_system, m_file_timestamp_worker,
- m_setup_info.can_write_timezone_device_location,
- m_time_zone);
- R_SUCCEED();
-}
-
-Result StaticService::GetStandardLocalSystemClock(
- std::shared_ptr<Service::PSC::Time::SystemClock>& out_service) {
- R_RETURN(m_wrapped_service->GetStandardLocalSystemClock(out_service));
-}
-
-Result StaticService::GetEphemeralNetworkSystemClock(
- std::shared_ptr<Service::PSC::Time::SystemClock>& out_service) {
- R_RETURN(m_wrapped_service->GetEphemeralNetworkSystemClock(out_service));
-}
-
-Result StaticService::GetSharedMemoryNativeHandle(Kernel::KSharedMemory** out_shared_memory) {
R_RETURN(m_wrapped_service->GetSharedMemoryNativeHandle(out_shared_memory));
}
Result StaticService::SetStandardSteadyClockInternalOffset(s64 offset_ns) {
+ LOG_DEBUG(Service_Time, "called. offset_ns={}", offset_ns);
+
R_UNLESS(m_setup_info.can_write_steady_clock, Service::PSC::Time::ResultPermissionDenied);
R_RETURN(m_set_sys->SetExternalSteadyClockInternalOffset(
@@ -386,62 +154,92 @@ Result StaticService::SetStandardSteadyClockInternalOffset(s64 offset_ns) {
std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::seconds(1)).count()));
}
-Result StaticService::GetStandardSteadyClockRtcValue(s64& out_rtc_value) {
- R_RETURN(m_standard_steady_clock_resource.GetRtcTimeInSeconds(out_rtc_value));
+Result StaticService::GetStandardSteadyClockRtcValue(Out<s64> out_rtc_value) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_rtc_value={}", *out_rtc_value); });
+
+ R_RETURN(m_standard_steady_clock_resource.GetRtcTimeInSeconds(*out_rtc_value));
}
Result StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled(
- bool& out_automatic_correction) {
+ Out<bool> out_automatic_correction) {
+ SCOPE_EXIT({
+ LOG_DEBUG(Service_Time, "called. out_automatic_correction={}", *out_automatic_correction);
+ });
+
R_RETURN(m_wrapped_service->IsStandardUserSystemClockAutomaticCorrectionEnabled(
out_automatic_correction));
}
Result StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled(
bool automatic_correction) {
+ LOG_DEBUG(Service_Time, "called. automatic_correction={}", automatic_correction);
+
R_RETURN(m_wrapped_service->SetStandardUserSystemClockAutomaticCorrectionEnabled(
automatic_correction));
}
-Result StaticService::GetStandardUserSystemClockInitialYear(s32& out_year) {
- out_year = GetSettingsItemValue<s32>(m_set_sys, "time", "standard_user_clock_initial_year");
+Result StaticService::GetStandardUserSystemClockInitialYear(Out<s32> out_year) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_year={}", *out_year); });
+
+ *out_year = GetSettingsItemValue<s32>(m_set_sys, "time", "standard_user_clock_initial_year");
R_SUCCEED();
}
-Result StaticService::IsStandardNetworkSystemClockAccuracySufficient(bool& out_is_sufficient) {
+Result StaticService::IsStandardNetworkSystemClockAccuracySufficient(Out<bool> out_is_sufficient) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_is_sufficient={}", *out_is_sufficient); });
+
R_RETURN(m_wrapped_service->IsStandardNetworkSystemClockAccuracySufficient(out_is_sufficient));
}
Result StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(
- Service::PSC::Time::SteadyClockTimePoint& out_time_point) {
+ Out<Service::PSC::Time::SteadyClockTimePoint> out_time_point) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_time_point={}", *out_time_point); });
+
R_RETURN(m_wrapped_service->GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(
out_time_point));
}
Result StaticService::CalculateMonotonicSystemClockBaseTimePoint(
- s64& out_time, Service::PSC::Time::SystemClockContext& context) {
+ Out<s64> out_time, Service::PSC::Time::SystemClockContext& context) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. context={} out_time={}", context, *out_time); });
+
R_RETURN(m_wrapped_service->CalculateMonotonicSystemClockBaseTimePoint(out_time, context));
}
-Result StaticService::GetClockSnapshot(Service::PSC::Time::ClockSnapshot& out_snapshot,
+Result StaticService::GetClockSnapshot(OutClockSnapshot out_snapshot,
Service::PSC::Time::TimeType type) {
+ SCOPE_EXIT(
+ { LOG_DEBUG(Service_Time, "called. type={} out_snapshot={}", type, *out_snapshot); });
+
R_RETURN(m_wrapped_service->GetClockSnapshot(out_snapshot, type));
}
Result StaticService::GetClockSnapshotFromSystemClockContext(
- Service::PSC::Time::ClockSnapshot& out_snapshot,
+ Service::PSC::Time::TimeType type, OutClockSnapshot out_snapshot,
Service::PSC::Time::SystemClockContext& user_context,
- Service::PSC::Time::SystemClockContext& network_context, Service::PSC::Time::TimeType type) {
- R_RETURN(m_wrapped_service->GetClockSnapshotFromSystemClockContext(out_snapshot, user_context,
- network_context, type));
+ Service::PSC::Time::SystemClockContext& network_context) {
+ SCOPE_EXIT({
+ LOG_DEBUG(Service_Time,
+ "called. type={} out_snapshot={} user_context={} network_context={}", type,
+ *out_snapshot, user_context, network_context);
+ });
+
+ R_RETURN(m_wrapped_service->GetClockSnapshotFromSystemClockContext(
+ type, out_snapshot, user_context, network_context));
}
-Result StaticService::CalculateStandardUserSystemClockDifferenceByUser(
- s64& out_time, Service::PSC::Time::ClockSnapshot& a, Service::PSC::Time::ClockSnapshot& b) {
+Result StaticService::CalculateStandardUserSystemClockDifferenceByUser(Out<s64> out_time,
+ InClockSnapshot a,
+ InClockSnapshot b) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. a={} b={} out_time={}", *a, *b, *out_time); });
+
R_RETURN(m_wrapped_service->CalculateStandardUserSystemClockDifferenceByUser(out_time, a, b));
}
-Result StaticService::CalculateSpanBetween(s64& out_time, Service::PSC::Time::ClockSnapshot& a,
- Service::PSC::Time::ClockSnapshot& b) {
+Result StaticService::CalculateSpanBetween(Out<s64> out_time, InClockSnapshot a,
+ InClockSnapshot b) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. a={} b={} out_time={}", *a, *b, *out_time); });
+
R_RETURN(m_wrapped_service->CalculateSpanBetween(out_time, a, b));
}
diff --git a/src/core/hle/service/glue/time/static.h b/src/core/hle/service/glue/time/static.h
index 75fe4e2cd..d3cc0fdd6 100644
--- a/src/core/hle/service/glue/time/static.h
+++ b/src/core/hle/service/glue/time/static.h
@@ -4,6 +4,7 @@
#pragma once
#include "common/common_types.h"
+#include "core/hle/service/cmif_types.h"
#include "core/hle/service/glue/time/manager.h"
#include "core/hle/service/glue/time/time_zone.h"
#include "core/hle/service/psc/time/common.h"
@@ -29,6 +30,10 @@ class FileTimestampWorker;
class StandardSteadyClockResource;
class StaticService final : public ServiceFramework<StaticService> {
+ using InClockSnapshot = InLargeData<Service::PSC::Time::ClockSnapshot, BufferAttr_HipcPointer>;
+ using OutClockSnapshot =
+ OutLargeData<Service::PSC::Time::ClockSnapshot, BufferAttr_HipcPointer>;
+
public:
explicit StaticService(Core::System& system,
Service::PSC::Time::StaticServiceSetupInfo setup_info,
@@ -36,65 +41,34 @@ public:
~StaticService() override = default;
- Result GetStandardUserSystemClock(
- std::shared_ptr<Service::PSC::Time::SystemClock>& out_service);
- Result GetStandardNetworkSystemClock(
- std::shared_ptr<Service::PSC::Time::SystemClock>& out_service);
- Result GetStandardSteadyClock(std::shared_ptr<Service::PSC::Time::SteadyClock>& out_service);
- Result GetTimeZoneService(std::shared_ptr<TimeZoneService>& out_service);
- Result GetStandardLocalSystemClock(
- std::shared_ptr<Service::PSC::Time::SystemClock>& out_service);
+ Result GetStandardUserSystemClock(OutInterface<Service::PSC::Time::SystemClock> out_service);
+ Result GetStandardNetworkSystemClock(OutInterface<Service::PSC::Time::SystemClock> out_service);
+ Result GetStandardSteadyClock(OutInterface<Service::PSC::Time::SteadyClock> out_service);
+ Result GetTimeZoneService(OutInterface<TimeZoneService> out_service);
+ Result GetStandardLocalSystemClock(OutInterface<Service::PSC::Time::SystemClock> out_service);
Result GetEphemeralNetworkSystemClock(
- std::shared_ptr<Service::PSC::Time::SystemClock>& out_service);
- Result GetSharedMemoryNativeHandle(Kernel::KSharedMemory** out_shared_memory);
- Result SetStandardSteadyClockInternalOffset(s64 offset);
- Result GetStandardSteadyClockRtcValue(s64& out_rtc_value);
- Result IsStandardUserSystemClockAutomaticCorrectionEnabled(bool& out_automatic_correction);
+ OutInterface<Service::PSC::Time::SystemClock> out_service);
+ Result GetSharedMemoryNativeHandle(OutCopyHandle<Kernel::KSharedMemory> out_shared_memory);
+ Result SetStandardSteadyClockInternalOffset(s64 offset_ns);
+ Result GetStandardSteadyClockRtcValue(Out<s64> out_rtc_value);
+ Result IsStandardUserSystemClockAutomaticCorrectionEnabled(Out<bool> out_is_enabled);
Result SetStandardUserSystemClockAutomaticCorrectionEnabled(bool automatic_correction);
- Result GetStandardUserSystemClockInitialYear(s32& out_year);
- Result IsStandardNetworkSystemClockAccuracySufficient(bool& out_is_sufficient);
+ Result GetStandardUserSystemClockInitialYear(Out<s32> out_year);
+ Result IsStandardNetworkSystemClockAccuracySufficient(Out<bool> out_is_sufficient);
Result GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(
- Service::PSC::Time::SteadyClockTimePoint& out_time_point);
+ Out<Service::PSC::Time::SteadyClockTimePoint> out_time_point);
Result CalculateMonotonicSystemClockBaseTimePoint(
- s64& out_time, Service::PSC::Time::SystemClockContext& context);
- Result GetClockSnapshot(Service::PSC::Time::ClockSnapshot& out_snapshot,
- Service::PSC::Time::TimeType type);
+ Out<s64> out_time, Service::PSC::Time::SystemClockContext& context);
+ Result GetClockSnapshot(OutClockSnapshot out_snapshot, Service::PSC::Time::TimeType type);
Result GetClockSnapshotFromSystemClockContext(
- Service::PSC::Time::ClockSnapshot& out_snapshot,
+ Service::PSC::Time::TimeType type, OutClockSnapshot out_snapshot,
Service::PSC::Time::SystemClockContext& user_context,
- Service::PSC::Time::SystemClockContext& network_context, Service::PSC::Time::TimeType type);
- Result CalculateStandardUserSystemClockDifferenceByUser(s64& out_time,
- Service::PSC::Time::ClockSnapshot& a,
- Service::PSC::Time::ClockSnapshot& b);
- Result CalculateSpanBetween(s64& out_time, Service::PSC::Time::ClockSnapshot& a,
- Service::PSC::Time::ClockSnapshot& b);
+ Service::PSC::Time::SystemClockContext& network_context);
+ Result CalculateStandardUserSystemClockDifferenceByUser(Out<s64> out_difference,
+ InClockSnapshot a, InClockSnapshot b);
+ Result CalculateSpanBetween(Out<s64> out_time, InClockSnapshot a, InClockSnapshot b);
private:
- Result GetClockSnapshotImpl(Service::PSC::Time::ClockSnapshot& out_snapshot,
- Service::PSC::Time::SystemClockContext& user_context,
- Service::PSC::Time::SystemClockContext& network_context,
- Service::PSC::Time::TimeType type);
-
- void Handle_GetStandardUserSystemClock(HLERequestContext& ctx);
- void Handle_GetStandardNetworkSystemClock(HLERequestContext& ctx);
- void Handle_GetStandardSteadyClock(HLERequestContext& ctx);
- void Handle_GetTimeZoneService(HLERequestContext& ctx);
- void Handle_GetStandardLocalSystemClock(HLERequestContext& ctx);
- void Handle_GetEphemeralNetworkSystemClock(HLERequestContext& ctx);
- void Handle_GetSharedMemoryNativeHandle(HLERequestContext& ctx);
- void Handle_SetStandardSteadyClockInternalOffset(HLERequestContext& ctx);
- void Handle_GetStandardSteadyClockRtcValue(HLERequestContext& ctx);
- void Handle_IsStandardUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx);
- void Handle_SetStandardUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx);
- void Handle_GetStandardUserSystemClockInitialYear(HLERequestContext& ctx);
- void Handle_IsStandardNetworkSystemClockAccuracySufficient(HLERequestContext& ctx);
- void Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext& ctx);
- void Handle_CalculateMonotonicSystemClockBaseTimePoint(HLERequestContext& ctx);
- void Handle_GetClockSnapshot(HLERequestContext& ctx);
- void Handle_GetClockSnapshotFromSystemClockContext(HLERequestContext& ctx);
- void Handle_CalculateStandardUserSystemClockDifferenceByUser(HLERequestContext& ctx);
- void Handle_CalculateSpanBetween(HLERequestContext& ctx);
-
Core::System& m_system;
std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys;
diff --git a/src/core/hle/service/glue/time/time_zone.cpp b/src/core/hle/service/glue/time/time_zone.cpp
index 503c327dd..5dc1187cb 100644
--- a/src/core/hle/service/glue/time/time_zone.cpp
+++ b/src/core/hle/service/glue/time/time_zone.cpp
@@ -3,8 +3,10 @@
#include <chrono>
+#include "common/scope_exit.h"
#include "core/core.h"
#include "core/hle/kernel/svc.h"
+#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/glue/time/file_timestamp_worker.h"
#include "core/hle/service/glue/time/time_zone.h"
#include "core/hle/service/glue/time/time_zone_binary.h"
@@ -28,20 +30,20 @@ TimeZoneService::TimeZoneService(
m_wrapped_service{std::move(time_zone_service)}, m_operation_event{m_system} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, &TimeZoneService::Handle_GetDeviceLocationName, "GetDeviceLocationName"},
- {1, &TimeZoneService::Handle_SetDeviceLocationName, "SetDeviceLocationName"},
- {2, &TimeZoneService::Handle_GetTotalLocationNameCount, "GetTotalLocationNameCount"},
- {3, &TimeZoneService::Handle_LoadLocationNameList, "LoadLocationNameList"},
- {4, &TimeZoneService::Handle_LoadTimeZoneRule, "LoadTimeZoneRule"},
- {5, &TimeZoneService::Handle_GetTimeZoneRuleVersion, "GetTimeZoneRuleVersion"},
- {6, &TimeZoneService::Handle_GetDeviceLocationNameAndUpdatedTime, "GetDeviceLocationNameAndUpdatedTime"},
- {7, &TimeZoneService::Handle_SetDeviceLocationNameWithTimeZoneRule, "SetDeviceLocationNameWithTimeZoneRule"},
- {8, &TimeZoneService::Handle_ParseTimeZoneBinary, "ParseTimeZoneBinary"},
- {20, &TimeZoneService::Handle_GetDeviceLocationNameOperationEventReadableHandle, "GetDeviceLocationNameOperationEventReadableHandle"},
- {100, &TimeZoneService::Handle_ToCalendarTime, "ToCalendarTime"},
- {101, &TimeZoneService::Handle_ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"},
- {201, &TimeZoneService::Handle_ToPosixTime, "ToPosixTime"},
- {202, &TimeZoneService::Handle_ToPosixTimeWithMyRule, "ToPosixTimeWithMyRule"},
+ {0, D<&TimeZoneService::GetDeviceLocationName>, "GetDeviceLocationName"},
+ {1, D<&TimeZoneService::SetDeviceLocationName>, "SetDeviceLocationName"},
+ {2, D<&TimeZoneService::GetTotalLocationNameCount>, "GetTotalLocationNameCount"},
+ {3, D<&TimeZoneService::LoadLocationNameList>, "LoadLocationNameList"},
+ {4, D<&TimeZoneService::LoadTimeZoneRule>, "LoadTimeZoneRule"},
+ {5, D<&TimeZoneService::GetTimeZoneRuleVersion>, "GetTimeZoneRuleVersion"},
+ {6, D<&TimeZoneService::GetDeviceLocationNameAndUpdatedTime>, "GetDeviceLocationNameAndUpdatedTime"},
+ {7, D<&TimeZoneService::SetDeviceLocationNameWithTimeZoneRule>, "SetDeviceLocationNameWithTimeZoneRule"},
+ {8, D<&TimeZoneService::ParseTimeZoneBinary>, "ParseTimeZoneBinary"},
+ {20, D<&TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle>, "GetDeviceLocationNameOperationEventReadableHandle"},
+ {100, D<&TimeZoneService::ToCalendarTime>, "ToCalendarTime"},
+ {101, D<&TimeZoneService::ToCalendarTimeWithMyRule>, "ToCalendarTimeWithMyRule"},
+ {201, D<&TimeZoneService::ToPosixTime>, "ToPosixTime"},
+ {202, D<&TimeZoneService::ToPosixTimeWithMyRule>, "ToPosixTimeWithMyRule"},
};
// clang-format on
RegisterHandlers(functions);
@@ -53,220 +55,16 @@ TimeZoneService::TimeZoneService(
TimeZoneService::~TimeZoneService() = default;
-void TimeZoneService::Handle_GetDeviceLocationName(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- Service::PSC::Time::LocationName name{};
- auto res = GetDeviceLocationName(name);
-
- IPC::ResponseBuilder rb{ctx, 2 + sizeof(Service::PSC::Time::LocationName) / sizeof(u32)};
- rb.Push(res);
- rb.PushRaw<Service::PSC::Time::LocationName>(name);
-}
-
-void TimeZoneService::Handle_SetDeviceLocationName(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::RequestParser rp{ctx};
- auto name{rp.PopRaw<Service::PSC::Time::LocationName>()};
-
- auto res = SetDeviceLocation(name);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
-}
-
-void TimeZoneService::Handle_GetTotalLocationNameCount(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- u32 count{};
- auto res = GetTotalLocationNameCount(count);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(res);
- rb.Push(count);
-}
-
-void TimeZoneService::Handle_LoadLocationNameList(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::RequestParser rp{ctx};
- auto index{rp.Pop<u32>()};
-
- auto max_names{ctx.GetWriteBufferSize() / sizeof(Service::PSC::Time::LocationName)};
-
- std::vector<Service::PSC::Time::LocationName> names{};
- u32 count{};
- auto res = LoadLocationNameList(count, names, max_names, index);
-
- ctx.WriteBuffer(names);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(res);
- rb.Push(count);
-}
-
-void TimeZoneService::Handle_LoadTimeZoneRule(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::RequestParser rp{ctx};
- auto name{rp.PopRaw<Service::PSC::Time::LocationName>()};
-
- Tz::Rule rule{};
- auto res = LoadTimeZoneRule(rule, name);
-
- ctx.WriteBuffer(rule);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
-}
-
-void TimeZoneService::Handle_GetTimeZoneRuleVersion(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- Service::PSC::Time::RuleVersion rule_version{};
- auto res = GetTimeZoneRuleVersion(rule_version);
-
- IPC::ResponseBuilder rb{ctx, 2 + sizeof(Service::PSC::Time::RuleVersion) / sizeof(u32)};
- rb.Push(res);
- rb.PushRaw<Service::PSC::Time::RuleVersion>(rule_version);
-}
-
-void TimeZoneService::Handle_GetDeviceLocationNameAndUpdatedTime(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- Service::PSC::Time::LocationName name{};
- Service::PSC::Time::SteadyClockTimePoint time_point{};
- auto res = GetDeviceLocationNameAndUpdatedTime(time_point, name);
-
- IPC::ResponseBuilder rb{ctx,
- 2 + (sizeof(Service::PSC::Time::LocationName) / sizeof(u32)) +
- (sizeof(Service::PSC::Time::SteadyClockTimePoint) / sizeof(u32))};
- rb.Push(res);
- rb.PushRaw<Service::PSC::Time::LocationName>(name);
- rb.PushRaw<Service::PSC::Time::SteadyClockTimePoint>(time_point);
-}
-
-void TimeZoneService::Handle_SetDeviceLocationNameWithTimeZoneRule(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- auto res = SetDeviceLocationNameWithTimeZoneRule();
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
-}
-
-void TimeZoneService::Handle_ParseTimeZoneBinary(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(Service::PSC::Time::ResultNotImplemented);
-}
-
-void TimeZoneService::Handle_GetDeviceLocationNameOperationEventReadableHandle(
- HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- Kernel::KEvent* event{};
- auto res = GetDeviceLocationNameOperationEventReadableHandle(&event);
-
- IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(res);
- rb.PushCopyObjects(event->GetReadableEvent());
-}
-
-void TimeZoneService::Handle_ToCalendarTime(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::RequestParser rp{ctx};
- auto time{rp.Pop<s64>()};
-
- auto rule_buffer{ctx.ReadBuffer()};
- Tz::Rule rule{};
- std::memcpy(&rule, rule_buffer.data(), sizeof(Tz::Rule));
-
- Service::PSC::Time::CalendarTime calendar_time{};
- Service::PSC::Time::CalendarAdditionalInfo additional_info{};
- auto res = ToCalendarTime(calendar_time, additional_info, time, rule);
-
- IPC::ResponseBuilder rb{ctx,
- 2 + (sizeof(Service::PSC::Time::CalendarTime) / sizeof(u32)) +
- (sizeof(Service::PSC::Time::CalendarAdditionalInfo) / sizeof(u32))};
- rb.Push(res);
- rb.PushRaw<Service::PSC::Time::CalendarTime>(calendar_time);
- rb.PushRaw<Service::PSC::Time::CalendarAdditionalInfo>(additional_info);
-}
-
-void TimeZoneService::Handle_ToCalendarTimeWithMyRule(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- auto time{rp.Pop<s64>()};
-
- LOG_DEBUG(Service_Time, "called. time={}", time);
-
- Service::PSC::Time::CalendarTime calendar_time{};
- Service::PSC::Time::CalendarAdditionalInfo additional_info{};
- auto res = ToCalendarTimeWithMyRule(calendar_time, additional_info, time);
-
- IPC::ResponseBuilder rb{ctx,
- 2 + (sizeof(Service::PSC::Time::CalendarTime) / sizeof(u32)) +
- (sizeof(Service::PSC::Time::CalendarAdditionalInfo) / sizeof(u32))};
- rb.Push(res);
- rb.PushRaw<Service::PSC::Time::CalendarTime>(calendar_time);
- rb.PushRaw<Service::PSC::Time::CalendarAdditionalInfo>(additional_info);
-}
-
-void TimeZoneService::Handle_ToPosixTime(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- auto calendar{rp.PopRaw<Service::PSC::Time::CalendarTime>()};
-
- LOG_DEBUG(Service_Time, "called. calendar year {} month {} day {} hour {} minute {} second {}",
- calendar.year, calendar.month, calendar.day, calendar.hour, calendar.minute,
- calendar.second);
-
- auto binary{ctx.ReadBuffer()};
-
- Tz::Rule rule{};
- std::memcpy(&rule, binary.data(), sizeof(Tz::Rule));
-
- u32 count{};
- std::array<s64, 2> times{};
- u32 times_count{static_cast<u32>(ctx.GetWriteBufferSize() / sizeof(s64))};
-
- auto res = ToPosixTime(count, times, times_count, calendar, rule);
-
- ctx.WriteBuffer(times);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(res);
- rb.Push(count);
-}
-
-void TimeZoneService::Handle_ToPosixTimeWithMyRule(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::RequestParser rp{ctx};
- auto calendar{rp.PopRaw<Service::PSC::Time::CalendarTime>()};
-
- u32 count{};
- std::array<s64, 2> times{};
- u32 times_count{static_cast<u32>(ctx.GetWriteBufferSize() / sizeof(s64))};
-
- auto res = ToPosixTimeWithMyRule(count, times, times_count, calendar);
-
- ctx.WriteBuffer(times);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(res);
- rb.Push(count);
-}
+Result TimeZoneService::GetDeviceLocationName(
+ Out<Service::PSC::Time::LocationName> out_location_name) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_location_name={}", *out_location_name); });
-// =============================== Implementations ===========================
-
-Result TimeZoneService::GetDeviceLocationName(Service::PSC::Time::LocationName& out_location_name) {
R_RETURN(m_wrapped_service->GetDeviceLocationName(out_location_name));
}
-Result TimeZoneService::SetDeviceLocation(Service::PSC::Time::LocationName& location_name) {
+Result TimeZoneService::SetDeviceLocationName(Service::PSC::Time::LocationName& location_name) {
+ LOG_DEBUG(Service_Time, "called. location_name={}", location_name);
+
R_UNLESS(m_can_write_timezone_device_location, Service::PSC::Time::ResultPermissionDenied);
R_UNLESS(IsTimeZoneBinaryValid(location_name), Service::PSC::Time::ResultTimeZoneNotFound);
@@ -282,7 +80,7 @@ Result TimeZoneService::SetDeviceLocation(Service::PSC::Time::LocationName& loca
Service::PSC::Time::SteadyClockTimePoint time_point{};
Service::PSC::Time::LocationName name{};
- R_TRY(m_wrapped_service->GetDeviceLocationNameAndUpdatedTime(time_point, name));
+ R_TRY(m_wrapped_service->GetDeviceLocationNameAndUpdatedTime(&name, &time_point));
m_set_sys->SetDeviceTimeZoneLocationName(name);
m_set_sys->SetDeviceTimeZoneLocationUpdatedTime(time_point);
@@ -294,19 +92,27 @@ Result TimeZoneService::SetDeviceLocation(Service::PSC::Time::LocationName& loca
R_SUCCEED();
}
-Result TimeZoneService::GetTotalLocationNameCount(u32& out_count) {
+Result TimeZoneService::GetTotalLocationNameCount(Out<u32> out_count) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_count={}", *out_count); });
+
R_RETURN(m_wrapped_service->GetTotalLocationNameCount(out_count));
}
Result TimeZoneService::LoadLocationNameList(
- u32& out_count, std::vector<Service::PSC::Time::LocationName>& out_names, size_t max_names,
- u32 index) {
+ Out<u32> out_count,
+ OutArray<Service::PSC::Time::LocationName, BufferAttr_HipcMapAlias> out_names, u32 index) {
+ SCOPE_EXIT({
+ LOG_DEBUG(Service_Time, "called. index={} out_count={} out_names[0]={} out_names[1]={}",
+ index, *out_count, out_names[0], out_names[1]);
+ });
+
std::scoped_lock l{m_mutex};
- R_RETURN(GetTimeZoneLocationList(out_count, out_names, max_names, index));
+ R_RETURN(GetTimeZoneLocationList(*out_count, out_names, out_names.size(), index));
}
-Result TimeZoneService::LoadTimeZoneRule(Tz::Rule& out_rule,
- Service::PSC::Time::LocationName& name) {
+Result TimeZoneService::LoadTimeZoneRule(OutRule out_rule, Service::PSC::Time::LocationName& name) {
+ LOG_DEBUG(Service_Time, "called. name={}", name);
+
std::scoped_lock l{m_mutex};
std::span<const u8> binary{};
size_t binary_size{};
@@ -314,23 +120,43 @@ Result TimeZoneService::LoadTimeZoneRule(Tz::Rule& out_rule,
R_RETURN(m_wrapped_service->ParseTimeZoneBinary(out_rule, binary));
}
-Result TimeZoneService::GetTimeZoneRuleVersion(Service::PSC::Time::RuleVersion& out_rule_version) {
+Result TimeZoneService::GetTimeZoneRuleVersion(
+ Out<Service::PSC::Time::RuleVersion> out_rule_version) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_rule_version={}", *out_rule_version); });
+
R_RETURN(m_wrapped_service->GetTimeZoneRuleVersion(out_rule_version));
}
Result TimeZoneService::GetDeviceLocationNameAndUpdatedTime(
- Service::PSC::Time::SteadyClockTimePoint& out_time_point,
- Service::PSC::Time::LocationName& location_name) {
- R_RETURN(m_wrapped_service->GetDeviceLocationNameAndUpdatedTime(out_time_point, location_name));
+ Out<Service::PSC::Time::LocationName> location_name,
+ Out<Service::PSC::Time::SteadyClockTimePoint> out_time_point) {
+ SCOPE_EXIT({
+ LOG_DEBUG(Service_Time, "called. location_name={} out_time_point={}", *location_name,
+ *out_time_point);
+ });
+
+ R_RETURN(m_wrapped_service->GetDeviceLocationNameAndUpdatedTime(location_name, out_time_point));
}
-Result TimeZoneService::SetDeviceLocationNameWithTimeZoneRule() {
+Result TimeZoneService::SetDeviceLocationNameWithTimeZoneRule(
+ Service::PSC::Time::LocationName& location_name, InBuffer<BufferAttr_HipcAutoSelect> binary) {
+ LOG_DEBUG(Service_Time, "called. location_name={}", location_name);
+
R_UNLESS(m_can_write_timezone_device_location, Service::PSC::Time::ResultPermissionDenied);
R_RETURN(Service::PSC::Time::ResultNotImplemented);
}
+Result TimeZoneService::ParseTimeZoneBinary(OutRule out_rule,
+ InBuffer<BufferAttr_HipcAutoSelect> binary) {
+ LOG_DEBUG(Service_Time, "called.");
+
+ R_RETURN(Service::PSC::Time::ResultNotImplemented);
+}
+
Result TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle(
- Kernel::KEvent** out_event) {
+ OutCopyHandle<Kernel::KReadableEvent> out_event) {
+ LOG_DEBUG(Service_Time, "called.");
+
if (!operation_event_initialized) {
operation_event_initialized = false;
@@ -342,34 +168,59 @@ Result TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle(
g_list_nodes.push_back(m_operation_event);
}
- *out_event = m_operation_event.m_event;
+ *out_event = &m_operation_event.m_event->GetReadableEvent();
R_SUCCEED();
}
Result TimeZoneService::ToCalendarTime(
- Service::PSC::Time::CalendarTime& out_calendar_time,
- Service::PSC::Time::CalendarAdditionalInfo& out_additional_info, s64 time, Tz::Rule& rule) {
+ Out<Service::PSC::Time::CalendarTime> out_calendar_time,
+ Out<Service::PSC::Time::CalendarAdditionalInfo> out_additional_info, s64 time, InRule rule) {
+ SCOPE_EXIT({
+ LOG_DEBUG(Service_Time, "called. time={} out_calendar_time={} out_additional_info={}", time,
+ *out_calendar_time, *out_additional_info);
+ });
+
R_RETURN(m_wrapped_service->ToCalendarTime(out_calendar_time, out_additional_info, time, rule));
}
Result TimeZoneService::ToCalendarTimeWithMyRule(
- Service::PSC::Time::CalendarTime& out_calendar_time,
- Service::PSC::Time::CalendarAdditionalInfo& out_additional_info, s64 time) {
+ Out<Service::PSC::Time::CalendarTime> out_calendar_time,
+ Out<Service::PSC::Time::CalendarAdditionalInfo> out_additional_info, s64 time) {
+ SCOPE_EXIT({
+ LOG_DEBUG(Service_Time, "called. time={} out_calendar_time={} out_additional_info={}", time,
+ *out_calendar_time, *out_additional_info);
+ });
+
R_RETURN(
m_wrapped_service->ToCalendarTimeWithMyRule(out_calendar_time, out_additional_info, time));
}
-Result TimeZoneService::ToPosixTime(u32& out_count, std::span<s64, 2> out_times,
- u32 out_times_count,
- Service::PSC::Time::CalendarTime& calendar_time,
- Tz::Rule& rule) {
+Result TimeZoneService::ToPosixTime(Out<u32> out_count,
+ OutArray<s64, BufferAttr_HipcPointer> out_times,
+ Out<u32> out_times_count,
+ Service::PSC::Time::CalendarTime& calendar_time, InRule rule) {
+ SCOPE_EXIT({
+ LOG_DEBUG(Service_Time,
+ "called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} "
+ "out_times_count={}",
+ calendar_time, *out_count, out_times[0], out_times[1], *out_times_count);
+ });
+
R_RETURN(
m_wrapped_service->ToPosixTime(out_count, out_times, out_times_count, calendar_time, rule));
}
-Result TimeZoneService::ToPosixTimeWithMyRule(u32& out_count, std::span<s64, 2> out_times,
- u32 out_times_count,
+Result TimeZoneService::ToPosixTimeWithMyRule(Out<u32> out_count,
+ OutArray<s64, BufferAttr_HipcPointer> out_times,
+ Out<u32> out_times_count,
Service::PSC::Time::CalendarTime& calendar_time) {
+ SCOPE_EXIT({
+ LOG_DEBUG(Service_Time,
+ "called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} "
+ "out_times_count={}",
+ calendar_time, *out_count, out_times[0], out_times[1], *out_times_count);
+ });
+
R_RETURN(m_wrapped_service->ToPosixTimeWithMyRule(out_count, out_times, out_times_count,
calendar_time));
}
diff --git a/src/core/hle/service/glue/time/time_zone.h b/src/core/hle/service/glue/time/time_zone.h
index 3c8ae4bf8..bf12adbdc 100644
--- a/src/core/hle/service/glue/time/time_zone.h
+++ b/src/core/hle/service/glue/time/time_zone.h
@@ -8,6 +8,7 @@
#include <span>
#include <vector>
+#include "core/hle/service/cmif_types.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/psc/time/common.h"
#include "core/hle/service/server_manager.h"
@@ -33,6 +34,9 @@ namespace Service::Glue::Time {
class FileTimestampWorker;
class TimeZoneService final : public ServiceFramework<TimeZoneService> {
+ using InRule = InLargeData<Tz::Rule, BufferAttr_HipcMapAlias>;
+ using OutRule = OutLargeData<Tz::Rule, BufferAttr_HipcMapAlias>;
+
public:
explicit TimeZoneService(
Core::System& system, FileTimestampWorker& file_timestamp_worker,
@@ -41,46 +45,37 @@ public:
~TimeZoneService() override;
- Result GetDeviceLocationName(Service::PSC::Time::LocationName& out_location_name);
- Result SetDeviceLocation(Service::PSC::Time::LocationName& location_name);
- Result GetTotalLocationNameCount(u32& out_count);
- Result LoadLocationNameList(u32& out_count,
- std::vector<Service::PSC::Time::LocationName>& out_names,
- size_t max_names, u32 index);
- Result LoadTimeZoneRule(Tz::Rule& out_rule, Service::PSC::Time::LocationName& name);
- Result GetTimeZoneRuleVersion(Service::PSC::Time::RuleVersion& out_rule_version);
+ Result GetDeviceLocationName(Out<Service::PSC::Time::LocationName> out_location_name);
+ Result SetDeviceLocationName(Service::PSC::Time::LocationName& location_name);
+ Result GetTotalLocationNameCount(Out<u32> out_count);
+ Result LoadLocationNameList(
+ Out<u32> out_count,
+ OutArray<Service::PSC::Time::LocationName, BufferAttr_HipcMapAlias> out_names, u32 index);
+ Result LoadTimeZoneRule(OutRule out_rule, Service::PSC::Time::LocationName& location_name);
+ Result GetTimeZoneRuleVersion(Out<Service::PSC::Time::RuleVersion> out_rule_version);
Result GetDeviceLocationNameAndUpdatedTime(
- Service::PSC::Time::SteadyClockTimePoint& out_time_point,
- Service::PSC::Time::LocationName& location_name);
- Result SetDeviceLocationNameWithTimeZoneRule();
- Result GetDeviceLocationNameOperationEventReadableHandle(Kernel::KEvent** out_event);
- Result ToCalendarTime(Service::PSC::Time::CalendarTime& out_calendar_time,
- Service::PSC::Time::CalendarAdditionalInfo& out_additional_info, s64 time,
- Tz::Rule& rule);
- Result ToCalendarTimeWithMyRule(Service::PSC::Time::CalendarTime& out_calendar_time,
- Service::PSC::Time::CalendarAdditionalInfo& out_additional_info,
- s64 time);
- Result ToPosixTime(u32& out_count, std::span<s64, 2> out_times, u32 out_times_count,
- Service::PSC::Time::CalendarTime& calendar_time, Tz::Rule& rule);
- Result ToPosixTimeWithMyRule(u32& out_count, std::span<s64, 2> out_times, u32 out_times_count,
+ Out<Service::PSC::Time::LocationName> location_name,
+ Out<Service::PSC::Time::SteadyClockTimePoint> out_time_point);
+ Result SetDeviceLocationNameWithTimeZoneRule(Service::PSC::Time::LocationName& location_name,
+ InBuffer<BufferAttr_HipcAutoSelect> binary);
+ Result ParseTimeZoneBinary(OutRule out_rule, InBuffer<BufferAttr_HipcAutoSelect> binary);
+ Result GetDeviceLocationNameOperationEventReadableHandle(
+ OutCopyHandle<Kernel::KReadableEvent> out_event);
+ Result ToCalendarTime(Out<Service::PSC::Time::CalendarTime> out_calendar_time,
+ Out<Service::PSC::Time::CalendarAdditionalInfo> out_additional_info,
+ s64 time, InRule rule);
+ Result ToCalendarTimeWithMyRule(
+ Out<Service::PSC::Time::CalendarTime> out_calendar_time,
+ Out<Service::PSC::Time::CalendarAdditionalInfo> out_additional_info, s64 time);
+ Result ToPosixTime(Out<u32> out_count, OutArray<s64, BufferAttr_HipcPointer> out_times,
+ Out<u32> out_times_count, Service::PSC::Time::CalendarTime& calendar_time,
+ InRule rule);
+ Result ToPosixTimeWithMyRule(Out<u32> out_count,
+ OutArray<s64, BufferAttr_HipcPointer> out_times,
+ Out<u32> out_times_count,
Service::PSC::Time::CalendarTime& calendar_time);
private:
- void Handle_GetDeviceLocationName(HLERequestContext& ctx);
- void Handle_SetDeviceLocationName(HLERequestContext& ctx);
- void Handle_GetTotalLocationNameCount(HLERequestContext& ctx);
- void Handle_LoadLocationNameList(HLERequestContext& ctx);
- void Handle_LoadTimeZoneRule(HLERequestContext& ctx);
- void Handle_GetTimeZoneRuleVersion(HLERequestContext& ctx);
- void Handle_GetDeviceLocationNameAndUpdatedTime(HLERequestContext& ctx);
- void Handle_SetDeviceLocationNameWithTimeZoneRule(HLERequestContext& ctx);
- void Handle_ParseTimeZoneBinary(HLERequestContext& ctx);
- void Handle_GetDeviceLocationNameOperationEventReadableHandle(HLERequestContext& ctx);
- void Handle_ToCalendarTime(HLERequestContext& ctx);
- void Handle_ToCalendarTimeWithMyRule(HLERequestContext& ctx);
- void Handle_ToPosixTime(HLERequestContext& ctx);
- void Handle_ToPosixTimeWithMyRule(HLERequestContext& ctx);
-
Core::System& m_system;
std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys;
diff --git a/src/core/hle/service/glue/time/time_zone_binary.cpp b/src/core/hle/service/glue/time/time_zone_binary.cpp
index d33f784c0..cc50b6b7b 100644
--- a/src/core/hle/service/glue/time/time_zone_binary.cpp
+++ b/src/core/hle/service/glue/time/time_zone_binary.cpp
@@ -103,7 +103,7 @@ void GetTimeZoneZonePath(std::string& out_path, Service::PSC::Time::LocationName
return;
}
// out_path = fmt::format("{}:/zoneinfo/{}", "TimeZoneBinary", name);
- out_path = fmt::format("/zoneinfo/{}", name.name.data());
+ out_path = fmt::format("/zoneinfo/{}", name.data());
}
bool IsTimeZoneBinaryValid(Service::PSC::Time::LocationName& name) {
@@ -169,7 +169,7 @@ Result GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size,
}
Result GetTimeZoneLocationList(u32& out_count,
- std::vector<Service::PSC::Time::LocationName>& out_names,
+ std::span<Service::PSC::Time::LocationName> out_names,
size_t max_names, u32 index) {
std::string path{};
GetTimeZoneBinaryListPath(path);
@@ -193,7 +193,7 @@ Result GetTimeZoneLocationList(u32& out_count,
if (chr == '\n') {
if (name_count >= index) {
- out_names.push_back(current_name);
+ out_names[out_count] = current_name;
out_count++;
if (out_count >= max_names) {
break;
@@ -209,10 +209,9 @@ Result GetTimeZoneLocationList(u32& out_count,
break;
}
- R_UNLESS(current_name_len <= current_name.name.size() - 2,
- Service::PSC::Time::ResultFailed);
+ R_UNLESS(current_name_len <= current_name.size() - 2, Service::PSC::Time::ResultFailed);
- current_name.name[current_name_len++] = chr;
+ current_name[current_name_len++] = chr;
}
R_SUCCEED();
diff --git a/src/core/hle/service/glue/time/time_zone_binary.h b/src/core/hle/service/glue/time/time_zone_binary.h
index 2cad6b458..461f4577e 100644
--- a/src/core/hle/service/glue/time/time_zone_binary.h
+++ b/src/core/hle/service/glue/time/time_zone_binary.h
@@ -26,7 +26,7 @@ Result GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version);
Result GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size,
Service::PSC::Time::LocationName& name);
Result GetTimeZoneLocationList(u32& out_count,
- std::vector<Service::PSC::Time::LocationName>& out_names,
+ std::span<Service::PSC::Time::LocationName> out_names,
size_t max_names, u32 index);
} // namespace Service::Glue::Time
diff --git a/src/core/hle/service/glue/time/worker.cpp b/src/core/hle/service/glue/time/worker.cpp
index ea0e49b90..f44f3077e 100644
--- a/src/core/hle/service/glue/time/worker.cpp
+++ b/src/core/hle/service/glue/time/worker.cpp
@@ -38,11 +38,12 @@ T GetSettingsItemValue(std::shared_ptr<Service::Set::ISystemSettingsServer>& set
TimeWorker::TimeWorker(Core::System& system, StandardSteadyClockResource& steady_clock_resource,
FileTimestampWorker& file_timestamp_worker)
- : m_system{system}, m_ctx{m_system, "Glue:58"}, m_event{m_ctx.CreateEvent("Glue:58:Event")},
+ : m_system{system}, m_ctx{m_system, "Glue:TimeWorker"}, m_event{m_ctx.CreateEvent(
+ "Glue:TimeWorker:Event")},
m_steady_clock_resource{steady_clock_resource},
m_file_timestamp_worker{file_timestamp_worker}, m_timer_steady_clock{m_ctx.CreateEvent(
- "Glue:58:SteadyClockTimerEvent")},
- m_timer_file_system{m_ctx.CreateEvent("Glue:58:FileTimeTimerEvent")},
+ "Glue:TimeWorker:SteadyClockTimerEvent")},
+ m_timer_file_system{m_ctx.CreateEvent("Glue:TimeWorker:FileTimeTimerEvent")},
m_alarm_worker{m_system, m_steady_clock_resource}, m_pm_state_change_handler{m_alarm_worker} {
g_ig_report_network_clock_context_set = false;
g_report_network_clock_context = {};
@@ -113,17 +114,17 @@ void TimeWorker::Initialize(std::shared_ptr<Service::PSC::Time::StaticService> t
std::chrono::nanoseconds(fs_notify_time_ns),
m_timer_file_system_timing_event);
- auto res = m_time_sm->GetStandardLocalSystemClock(m_local_clock);
+ auto res = m_time_sm->GetStandardLocalSystemClock(&m_local_clock);
ASSERT(res == ResultSuccess);
res = m_time_m->GetStandardLocalClockOperationEvent(&m_local_clock_event);
ASSERT(res == ResultSuccess);
- res = m_time_sm->GetStandardNetworkSystemClock(m_network_clock);
+ res = m_time_sm->GetStandardNetworkSystemClock(&m_network_clock);
ASSERT(res == ResultSuccess);
res = m_time_m->GetStandardNetworkClockOperationEventForServiceManager(&m_network_clock_event);
ASSERT(res == ResultSuccess);
- res = m_time_sm->GetEphemeralNetworkSystemClock(m_ephemeral_clock);
+ res = m_time_sm->GetEphemeralNetworkSystemClock(&m_ephemeral_clock);
ASSERT(res == ResultSuccess);
res =
m_time_m->GetEphemeralNetworkClockOperationEventForServiceManager(&m_ephemeral_clock_event);
@@ -183,22 +184,19 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) {
AddWaiter(&m_event->GetReadableEvent(), EventType::Exit);
// TODO
// AddWaiter(gIPmModuleService::GetEvent(), 1);
- AddWaiter(&m_alarm_worker.GetEvent().GetReadableEvent(), EventType::PowerStateChange);
+ AddWaiter(&m_alarm_worker.GetEvent(), EventType::PowerStateChange);
} else {
AddWaiter(&m_event->GetReadableEvent(), EventType::Exit);
// TODO
// AddWaiter(gIPmModuleService::GetEvent(), 1);
- AddWaiter(&m_alarm_worker.GetEvent().GetReadableEvent(), EventType::PowerStateChange);
+ AddWaiter(&m_alarm_worker.GetEvent(), EventType::PowerStateChange);
AddWaiter(&m_alarm_worker.GetTimerEvent().GetReadableEvent(), EventType::SignalAlarms);
- AddWaiter(&m_local_clock_event->GetReadableEvent(), EventType::UpdateLocalSystemClock);
- AddWaiter(&m_network_clock_event->GetReadableEvent(),
- EventType::UpdateNetworkSystemClock);
- AddWaiter(&m_ephemeral_clock_event->GetReadableEvent(),
- EventType::UpdateEphemeralSystemClock);
+ AddWaiter(m_local_clock_event, EventType::UpdateLocalSystemClock);
+ AddWaiter(m_network_clock_event, EventType::UpdateNetworkSystemClock);
+ AddWaiter(m_ephemeral_clock_event, EventType::UpdateEphemeralSystemClock);
AddWaiter(&m_timer_steady_clock->GetReadableEvent(), EventType::UpdateSteadyClock);
AddWaiter(&m_timer_file_system->GetReadableEvent(), EventType::UpdateFileTimestamp);
- AddWaiter(&m_standard_user_auto_correct_clock_event->GetReadableEvent(),
- EventType::AutoCorrect);
+ AddWaiter(m_standard_user_auto_correct_clock_event, EventType::AutoCorrect);
}
s32 out_index{-1};
@@ -237,7 +235,7 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) {
m_local_clock_event->Clear();
Service::PSC::Time::SystemClockContext context{};
- auto res = m_local_clock->GetSystemClockContext(context);
+ auto res = m_local_clock->GetSystemClockContext(&context);
ASSERT(res == ResultSuccess);
m_set_sys->SetUserSystemClockContext(context);
@@ -248,12 +246,12 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) {
case EventType::UpdateNetworkSystemClock: {
m_network_clock_event->Clear();
Service::PSC::Time::SystemClockContext context{};
- auto res = m_network_clock->GetSystemClockContext(context);
+ auto res = m_network_clock->GetSystemClockContext(&context);
ASSERT(res == ResultSuccess);
m_set_sys->SetNetworkSystemClockContext(context);
s64 time{};
- if (m_network_clock->GetCurrentTime(time) != ResultSuccess) {
+ if (m_network_clock->GetCurrentTime(&time) != ResultSuccess) {
break;
}
@@ -275,13 +273,13 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) {
m_ephemeral_clock_event->Clear();
Service::PSC::Time::SystemClockContext context{};
- auto res = m_ephemeral_clock->GetSystemClockContext(context);
+ auto res = m_ephemeral_clock->GetSystemClockContext(&context);
if (res != ResultSuccess) {
break;
}
s64 time{};
- res = m_ephemeral_clock->GetCurrentTime(time);
+ res = m_ephemeral_clock->GetCurrentTime(&time);
if (res != ResultSuccess) {
break;
}
@@ -317,11 +315,11 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) {
bool automatic_correction{};
auto res = m_time_sm->IsStandardUserSystemClockAutomaticCorrectionEnabled(
- automatic_correction);
+ &automatic_correction);
ASSERT(res == ResultSuccess);
Service::PSC::Time::SteadyClockTimePoint time_point{};
- res = m_time_sm->GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(time_point);
+ res = m_time_sm->GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(&time_point);
ASSERT(res == ResultSuccess);
m_set_sys->SetUserSystemClockAutomaticCorrectionEnabled(automatic_correction);
diff --git a/src/core/hle/service/glue/time/worker.h b/src/core/hle/service/glue/time/worker.h
index adbbe6b6d..75e5c4d0f 100644
--- a/src/core/hle/service/glue/time/worker.h
+++ b/src/core/hle/service/glue/time/worker.h
@@ -49,10 +49,10 @@ private:
std::shared_ptr<Service::PSC::Time::SystemClock> m_ephemeral_clock;
StandardSteadyClockResource& m_steady_clock_resource;
FileTimestampWorker& m_file_timestamp_worker;
- Kernel::KEvent* m_local_clock_event{};
- Kernel::KEvent* m_network_clock_event{};
- Kernel::KEvent* m_ephemeral_clock_event{};
- Kernel::KEvent* m_standard_user_auto_correct_clock_event{};
+ Kernel::KReadableEvent* m_local_clock_event{};
+ Kernel::KReadableEvent* m_network_clock_event{};
+ Kernel::KReadableEvent* m_ephemeral_clock_event{};
+ Kernel::KReadableEvent* m_standard_user_auto_correct_clock_event{};
Kernel::KEvent* m_timer_steady_clock{};
std::shared_ptr<Core::Timing::EventType> m_timer_steady_clock_timing_event;
Kernel::KEvent* m_timer_file_system{};
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 @@
#include <memory>
#include "common/logging/log.h"
+#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/mii/mii.h"
#include "core/hle/service/mii/mii_manager.h"
#include "core/hle/service/mii/mii_result.h"
#include "core/hle/service/mii/types/char_info.h"
+#include "core/hle/service/mii/types/raw_data.h"
#include "core/hle/service/mii/types/store_data.h"
#include "core/hle/service/mii/types/ver3_store_data.h"
#include "core/hle/service/server_manager.h"
-#include "core/hle/service/service.h"
+#include "core/hle/service/set/system_settings_server.h"
+#include "core/hle/service/sm/sm.h"
namespace Service::Mii {
@@ -24,549 +27,302 @@ public:
is_system_} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, &IDatabaseService::IsUpdated, "IsUpdated"},
- {1, &IDatabaseService::IsFullDatabase, "IsFullDatabase"},
- {2, &IDatabaseService::GetCount, "GetCount"},
- {3, &IDatabaseService::Get, "Get"},
- {4, &IDatabaseService::Get1, "Get1"},
- {5, &IDatabaseService::UpdateLatest, "UpdateLatest"},
- {6, &IDatabaseService::BuildRandom, "BuildRandom"},
- {7, &IDatabaseService::BuildDefault, "BuildDefault"},
- {8, &IDatabaseService::Get2, "Get2"},
- {9, &IDatabaseService::Get3, "Get3"},
- {10, &IDatabaseService::UpdateLatest1, "UpdateLatest1"},
- {11, &IDatabaseService::FindIndex, "FindIndex"},
- {12, &IDatabaseService::Move, "Move"},
- {13, &IDatabaseService::AddOrReplace, "AddOrReplace"},
- {14, &IDatabaseService::Delete, "Delete"},
- {15, &IDatabaseService::DestroyFile, "DestroyFile"},
- {16, &IDatabaseService::DeleteFile, "DeleteFile"},
- {17, &IDatabaseService::Format, "Format"},
+ {0, D<&IDatabaseService::IsUpdated>, "IsUpdated"},
+ {1, D<&IDatabaseService::IsFullDatabase>, "IsFullDatabase"},
+ {2, D<&IDatabaseService::GetCount>, "GetCount"},
+ {3, D<&IDatabaseService::Get>, "Get"},
+ {4, D<&IDatabaseService::Get1>, "Get1"},
+ {5, D<&IDatabaseService::UpdateLatest>, "UpdateLatest"},
+ {6, D<&IDatabaseService::BuildRandom>, "BuildRandom"},
+ {7, D<&IDatabaseService::BuildDefault>, "BuildDefault"},
+ {8, D<&IDatabaseService::Get2>, "Get2"},
+ {9, D<&IDatabaseService::Get3>, "Get3"},
+ {10, D<&IDatabaseService::UpdateLatest1>, "UpdateLatest1"},
+ {11, D<&IDatabaseService::FindIndex>, "FindIndex"},
+ {12, D<&IDatabaseService::Move>, "Move"},
+ {13, D<&IDatabaseService::AddOrReplace>, "AddOrReplace"},
+ {14, D<&IDatabaseService::Delete>, "Delete"},
+ {15, D<&IDatabaseService::DestroyFile>, "DestroyFile"},
+ {16, D<&IDatabaseService::DeleteFile>, "DeleteFile"},
+ {17, D<&IDatabaseService::Format>, "Format"},
{18, nullptr, "Import"},
{19, nullptr, "Export"},
- {20, &IDatabaseService::IsBrokenDatabaseWithClearFlag, "IsBrokenDatabaseWithClearFlag"},
- {21, &IDatabaseService::GetIndex, "GetIndex"},
- {22, &IDatabaseService::SetInterfaceVersion, "SetInterfaceVersion"},
- {23, &IDatabaseService::Convert, "Convert"},
- {24, &IDatabaseService::ConvertCoreDataToCharInfo, "ConvertCoreDataToCharInfo"},
- {25, &IDatabaseService::ConvertCharInfoToCoreData, "ConvertCharInfoToCoreData"},
- {26, &IDatabaseService::Append, "Append"},
+ {20, D<&IDatabaseService::IsBrokenDatabaseWithClearFlag>, "IsBrokenDatabaseWithClearFlag"},
+ {21, D<&IDatabaseService::GetIndex>, "GetIndex"},
+ {22, D<&IDatabaseService::SetInterfaceVersion>, "SetInterfaceVersion"},
+ {23, D<&IDatabaseService::Convert>, "Convert"},
+ {24, D<&IDatabaseService::ConvertCoreDataToCharInfo>, "ConvertCoreDataToCharInfo"},
+ {25, D<&IDatabaseService::ConvertCharInfoToCoreData>, "ConvertCharInfoToCoreData"},
+ {26, D<&IDatabaseService::Append>, "Append"},
};
// clang-format on
RegisterHandlers(functions);
+ m_set_sys = system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>(
+ "set:sys", true);
manager->Initialize(metadata);
}
private:
- void IsUpdated(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto source_flag{rp.PopRaw<SourceFlag>()};
-
+ Result IsUpdated(Out<bool> out_is_updated, SourceFlag source_flag) {
LOG_DEBUG(Service_Mii, "called with source_flag={}", source_flag);
- const bool is_updated = manager->IsUpdated(metadata, source_flag);
+ *out_is_updated = manager->IsUpdated(metadata, source_flag);
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push<u8>(is_updated);
+ R_SUCCEED();
}
- void IsFullDatabase(HLERequestContext& ctx) {
+ Result IsFullDatabase(Out<bool> out_is_full_database) {
LOG_DEBUG(Service_Mii, "called");
- const bool is_full_database = manager->IsFullDatabase();
+ *out_is_full_database = manager->IsFullDatabase();
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push<u8>(is_full_database);
+ R_SUCCEED();
}
- void GetCount(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto source_flag{rp.PopRaw<SourceFlag>()};
-
- const u32 mii_count = manager->GetCount(metadata, source_flag);
+ Result GetCount(Out<u32> out_mii_count, SourceFlag source_flag) {
+ *out_mii_count = manager->GetCount(metadata, source_flag);
- LOG_DEBUG(Service_Mii, "called with source_flag={}, mii_count={}", source_flag, mii_count);
+ LOG_DEBUG(Service_Mii, "called with source_flag={}, mii_count={}", source_flag,
+ *out_mii_count);
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(mii_count);
+ R_SUCCEED();
}
- void Get(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto source_flag{rp.PopRaw<SourceFlag>()};
- const auto output_size{ctx.GetWriteBufferNumElements<CharInfoElement>()};
-
- u32 mii_count{};
- std::vector<CharInfoElement> char_info_elements(output_size);
- const auto result = manager->Get(metadata, char_info_elements, mii_count, source_flag);
-
- if (mii_count != 0) {
- ctx.WriteBuffer(char_info_elements);
- }
+ Result Get(Out<u32> out_mii_count, SourceFlag source_flag,
+ OutArray<CharInfoElement, BufferAttr_HipcMapAlias> char_info_element_buffer) {
+ const auto result =
+ manager->Get(metadata, char_info_element_buffer, *out_mii_count, source_flag);
- LOG_INFO(Service_Mii, "called with source_flag={}, out_size={}, mii_count={}", source_flag,
- output_size, mii_count);
+ LOG_INFO(Service_Mii, "called with source_flag={}, mii_count={}", source_flag,
+ *out_mii_count);
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(result);
- rb.Push(mii_count);
+ R_RETURN(result);
}
- void Get1(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto source_flag{rp.PopRaw<SourceFlag>()};
- const auto output_size{ctx.GetWriteBufferNumElements<CharInfo>()};
+ Result Get1(Out<u32> out_mii_count, SourceFlag source_flag,
+ OutArray<CharInfo, BufferAttr_HipcMapAlias> char_info_buffer) {
+ const auto result = manager->Get(metadata, char_info_buffer, *out_mii_count, source_flag);
- u32 mii_count{};
- std::vector<CharInfo> char_info(output_size);
- const auto result = manager->Get(metadata, char_info, mii_count, source_flag);
+ LOG_INFO(Service_Mii, "called with source_flag={}, mii_count={}", source_flag,
+ *out_mii_count);
- if (mii_count != 0) {
- ctx.WriteBuffer(char_info);
- }
-
- LOG_INFO(Service_Mii, "called with source_flag={}, out_size={}, mii_count={}", source_flag,
- output_size, mii_count);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(result);
- rb.Push(mii_count);
+ R_RETURN(result);
}
- void UpdateLatest(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto char_info{rp.PopRaw<CharInfo>()};
- const auto source_flag{rp.PopRaw<SourceFlag>()};
-
+ Result UpdateLatest(Out<CharInfo> out_char_info, CharInfo& char_info, SourceFlag source_flag) {
LOG_INFO(Service_Mii, "called with source_flag={}", source_flag);
- CharInfo new_char_info{};
- const auto result = manager->UpdateLatest(metadata, new_char_info, char_info, source_flag);
- if (result.IsFailure()) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
-
- IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)};
- rb.Push(ResultSuccess);
- rb.PushRaw(new_char_info);
+ R_RETURN(manager->UpdateLatest(metadata, *out_char_info, char_info, source_flag));
}
- void BuildRandom(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto age{rp.PopRaw<Age>()};
- const auto gender{rp.PopRaw<Gender>()};
- const auto race{rp.PopRaw<Race>()};
-
+ Result BuildRandom(Out<CharInfo> out_char_info, Age age, Gender gender, Race race) {
LOG_DEBUG(Service_Mii, "called with age={}, gender={}, race={}", age, gender, race);
- if (age > Age::All) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultInvalidArgument);
- return;
- }
-
- if (gender > Gender::All) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultInvalidArgument);
- return;
- }
-
- if (race > Race::All) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultInvalidArgument);
- return;
- }
-
- CharInfo char_info{};
- manager->BuildRandom(char_info, age, gender, race);
-
- IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)};
- rb.Push(ResultSuccess);
- rb.PushRaw(char_info);
- }
+ R_UNLESS(age <= Age::All, ResultInvalidArgument);
+ R_UNLESS(gender <= Gender::All, ResultInvalidArgument);
+ R_UNLESS(race <= Race::All, ResultInvalidArgument);
- void BuildDefault(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto index{rp.Pop<u32>()};
+ manager->BuildRandom(*out_char_info, age, gender, race);
- LOG_DEBUG(Service_Mii, "called with index={}", index);
+ R_SUCCEED();
+ }
- if (index > 5) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultInvalidArgument);
- return;
- }
+ Result BuildDefault(Out<CharInfo> out_char_info, s32 index) {
+ LOG_DEBUG(Service_Mii, "called with index={}", index);
+ R_UNLESS(index < static_cast<s32>(RawData::DefaultMii.size()), ResultInvalidArgument);
- CharInfo char_info{};
- manager->BuildDefault(char_info, index);
+ manager->BuildDefault(*out_char_info, index);
- IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)};
- rb.Push(ResultSuccess);
- rb.PushRaw(char_info);
+ R_SUCCEED();
}
- void Get2(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto source_flag{rp.PopRaw<SourceFlag>()};
- const auto output_size{ctx.GetWriteBufferNumElements<StoreDataElement>()};
+ Result Get2(Out<u32> out_mii_count, SourceFlag source_flag,
+ OutArray<StoreDataElement, BufferAttr_HipcMapAlias> store_data_element_buffer) {
+ const auto result =
+ manager->Get(metadata, store_data_element_buffer, *out_mii_count, source_flag);
- u32 mii_count{};
- std::vector<StoreDataElement> store_data_elements(output_size);
- const auto result = manager->Get(metadata, store_data_elements, mii_count, source_flag);
+ LOG_INFO(Service_Mii, "called with source_flag={}, mii_count={}", source_flag,
+ *out_mii_count);
- if (mii_count != 0) {
- ctx.WriteBuffer(store_data_elements);
- }
-
- LOG_INFO(Service_Mii, "called with source_flag={}, out_size={}, mii_count={}", source_flag,
- output_size, mii_count);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(result);
- rb.Push(mii_count);
+ R_RETURN(result);
}
- void Get3(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto source_flag{rp.PopRaw<SourceFlag>()};
- const auto output_size{ctx.GetWriteBufferNumElements<StoreData>()};
-
- u32 mii_count{};
- std::vector<StoreData> store_data(output_size);
- const auto result = manager->Get(metadata, store_data, mii_count, source_flag);
+ Result Get3(Out<u32> out_mii_count, SourceFlag source_flag,
+ OutArray<StoreData, BufferAttr_HipcMapAlias> store_data_buffer) {
+ const auto result = manager->Get(metadata, store_data_buffer, *out_mii_count, source_flag);
- if (mii_count != 0) {
- ctx.WriteBuffer(store_data);
- }
+ LOG_INFO(Service_Mii, "called with source_flag={}, mii_count={}", source_flag,
+ *out_mii_count);
- LOG_INFO(Service_Mii, "called with source_flag={}, out_size={}, mii_count={}", source_flag,
- output_size, mii_count);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(result);
- rb.Push(mii_count);
+ R_RETURN(result);
}
- void UpdateLatest1(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto store_data{rp.PopRaw<StoreData>()};
- const auto source_flag{rp.PopRaw<SourceFlag>()};
-
+ Result UpdateLatest1(Out<StoreData> out_store_data, StoreData& store_data,
+ SourceFlag source_flag) {
LOG_INFO(Service_Mii, "called with source_flag={}", source_flag);
+ R_UNLESS(is_system, ResultPermissionDenied);
- Result result = ResultSuccess;
- if (!is_system) {
- result = ResultPermissionDenied;
- }
-
- StoreData new_store_data{};
- if (result.IsSuccess()) {
- result = manager->UpdateLatest(metadata, new_store_data, store_data, source_flag);
- }
-
- if (result.IsFailure()) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
-
- IPC::ResponseBuilder rb{ctx, 2 + sizeof(StoreData) / sizeof(u32)};
- rb.Push(ResultSuccess);
- rb.PushRaw<StoreData>(new_store_data);
+ R_RETURN(manager->UpdateLatest(metadata, *out_store_data, store_data, source_flag));
}
- void FindIndex(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto create_id{rp.PopRaw<Common::UUID>()};
- const auto is_special{rp.PopRaw<bool>()};
-
+ Result FindIndex(Out<s32> out_index, Common::UUID create_id, bool is_special) {
LOG_INFO(Service_Mii, "called with create_id={}, is_special={}",
create_id.FormattedString(), is_special);
- const s32 index = manager->FindIndex(create_id, is_special);
+ *out_index = manager->FindIndex(create_id, is_special);
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(index);
+ R_SUCCEED();
}
- void Move(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto create_id{rp.PopRaw<Common::UUID>()};
- const auto new_index{rp.PopRaw<s32>()};
-
+ Result Move(Common::UUID create_id, s32 new_index) {
LOG_INFO(Service_Mii, "called with create_id={}, new_index={}", create_id.FormattedString(),
new_index);
+ R_UNLESS(is_system, ResultPermissionDenied);
- Result result = ResultSuccess;
- if (!is_system) {
- result = ResultPermissionDenied;
- }
+ const u32 count = manager->GetCount(metadata, SourceFlag::Database);
- if (result.IsSuccess()) {
- const u32 count = manager->GetCount(metadata, SourceFlag::Database);
- if (new_index < 0 || new_index >= static_cast<s32>(count)) {
- result = ResultInvalidArgument;
- }
- }
+ R_UNLESS(new_index >= 0 && new_index < static_cast<s32>(count), ResultInvalidArgument);
- if (result.IsSuccess()) {
- result = manager->Move(metadata, new_index, create_id);
- }
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
+ R_RETURN(manager->Move(metadata, new_index, create_id));
}
- void AddOrReplace(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto store_data{rp.PopRaw<StoreData>()};
-
+ Result AddOrReplace(StoreData& store_data) {
LOG_INFO(Service_Mii, "called");
+ R_UNLESS(is_system, ResultPermissionDenied);
- Result result = ResultSuccess;
-
- if (!is_system) {
- result = ResultPermissionDenied;
- }
+ const auto result = manager->AddOrReplace(metadata, store_data);
- if (result.IsSuccess()) {
- result = manager->AddOrReplace(metadata, store_data);
- }
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
+ R_RETURN(result);
}
- void Delete(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto create_id{rp.PopRaw<Common::UUID>()};
-
+ Result Delete(Common::UUID create_id) {
LOG_INFO(Service_Mii, "called, create_id={}", create_id.FormattedString());
+ R_UNLESS(is_system, ResultPermissionDenied);
- Result result = ResultSuccess;
-
- if (!is_system) {
- result = ResultPermissionDenied;
- }
-
- if (result.IsSuccess()) {
- result = manager->Delete(metadata, create_id);
- }
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
+ R_RETURN(manager->Delete(metadata, create_id));
}
- void DestroyFile(HLERequestContext& ctx) {
- // This calls nn::settings::fwdbg::GetSettingsItemValue("is_db_test_mode_enabled");
- const bool is_db_test_mode_enabled = false;
+ Result DestroyFile() {
+ bool is_db_test_mode_enabled{};
+ m_set_sys->GetSettingsItemValue(is_db_test_mode_enabled, "mii", "is_db_test_mode_enabled");
LOG_INFO(Service_Mii, "called is_db_test_mode_enabled={}", is_db_test_mode_enabled);
+ R_UNLESS(is_db_test_mode_enabled, ResultTestModeOnly);
- Result result = ResultSuccess;
-
- if (!is_db_test_mode_enabled) {
- result = ResultTestModeOnly;
- }
-
- if (result.IsSuccess()) {
- result = manager->DestroyFile(metadata);
- }
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
+ R_RETURN(manager->DestroyFile(metadata));
}
- void DeleteFile(HLERequestContext& ctx) {
- // This calls nn::settings::fwdbg::GetSettingsItemValue("is_db_test_mode_enabled");
- const bool is_db_test_mode_enabled = false;
+ Result DeleteFile() {
+ bool is_db_test_mode_enabled{};
+ m_set_sys->GetSettingsItemValue(is_db_test_mode_enabled, "mii", "is_db_test_mode_enabled");
LOG_INFO(Service_Mii, "called is_db_test_mode_enabled={}", is_db_test_mode_enabled);
+ R_UNLESS(is_db_test_mode_enabled, ResultTestModeOnly);
- Result result = ResultSuccess;
-
- if (!is_db_test_mode_enabled) {
- result = ResultTestModeOnly;
- }
-
- if (result.IsSuccess()) {
- result = manager->DeleteFile();
- }
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
+ R_RETURN(manager->DeleteFile());
}
- void Format(HLERequestContext& ctx) {
- // This calls nn::settings::fwdbg::GetSettingsItemValue("is_db_test_mode_enabled");
- const bool is_db_test_mode_enabled = false;
+ Result Format() {
+ bool is_db_test_mode_enabled{};
+ m_set_sys->GetSettingsItemValue(is_db_test_mode_enabled, "mii", "is_db_test_mode_enabled");
LOG_INFO(Service_Mii, "called is_db_test_mode_enabled={}", is_db_test_mode_enabled);
+ R_UNLESS(is_db_test_mode_enabled, ResultTestModeOnly);
- Result result = ResultSuccess;
-
- if (!is_db_test_mode_enabled) {
- result = ResultTestModeOnly;
- }
-
- if (result.IsSuccess()) {
- result = manager->Format(metadata);
- }
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
+ R_RETURN(manager->Format(metadata));
}
- void IsBrokenDatabaseWithClearFlag(HLERequestContext& ctx) {
+ Result IsBrokenDatabaseWithClearFlag(Out<bool> out_is_broken_with_clear_flag) {
LOG_DEBUG(Service_Mii, "called");
+ R_UNLESS(is_system, ResultPermissionDenied);
- bool is_broken_with_clear_flag = false;
- Result result = ResultSuccess;
+ *out_is_broken_with_clear_flag = manager->IsBrokenWithClearFlag(metadata);
- if (!is_system) {
- result = ResultPermissionDenied;
- }
-
- if (result.IsSuccess()) {
- is_broken_with_clear_flag = manager->IsBrokenWithClearFlag(metadata);
- }
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(result);
- rb.Push<u8>(is_broken_with_clear_flag);
+ R_SUCCEED();
}
- void GetIndex(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto info{rp.PopRaw<CharInfo>()};
-
+ Result GetIndex(Out<s32> out_index, CharInfo& char_info) {
LOG_DEBUG(Service_Mii, "called");
- s32 index{};
- const auto result = manager->GetIndex(metadata, info, index);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(result);
- rb.Push(index);
+ R_RETURN(manager->GetIndex(metadata, char_info, *out_index));
}
- void SetInterfaceVersion(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto interface_version{rp.PopRaw<u32>()};
-
+ Result SetInterfaceVersion(u32 interface_version) {
LOG_INFO(Service_Mii, "called, interface_version={:08X}", interface_version);
manager->SetInterfaceVersion(metadata, interface_version);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ R_SUCCEED();
}
- void Convert(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto mii_v3{rp.PopRaw<Ver3StoreData>()};
-
+ Result Convert(Out<CharInfo> out_char_info, Ver3StoreData& mii_v3) {
LOG_INFO(Service_Mii, "called");
- CharInfo char_info{};
- const auto result = manager->ConvertV3ToCharInfo(char_info, mii_v3);
-
- IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)};
- rb.Push(result);
- rb.PushRaw<CharInfo>(char_info);
+ R_RETURN(manager->ConvertV3ToCharInfo(*out_char_info, mii_v3));
}
- void ConvertCoreDataToCharInfo(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto core_data{rp.PopRaw<CoreData>()};
-
+ Result ConvertCoreDataToCharInfo(Out<CharInfo> out_char_info, CoreData& core_data) {
LOG_INFO(Service_Mii, "called");
- CharInfo char_info{};
- const auto result = manager->ConvertCoreDataToCharInfo(char_info, core_data);
-
- IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)};
- rb.Push(result);
- rb.PushRaw<CharInfo>(char_info);
+ R_RETURN(manager->ConvertCoreDataToCharInfo(*out_char_info, core_data));
}
- void ConvertCharInfoToCoreData(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto char_info{rp.PopRaw<CharInfo>()};
-
+ Result ConvertCharInfoToCoreData(Out<CoreData> out_core_data, CharInfo& char_info) {
LOG_INFO(Service_Mii, "called");
- CoreData core_data{};
- const auto result = manager->ConvertCharInfoToCoreData(core_data, char_info);
-
- IPC::ResponseBuilder rb{ctx, 2 + sizeof(CoreData) / sizeof(u32)};
- rb.Push(result);
- rb.PushRaw<CoreData>(core_data);
+ R_RETURN(manager->ConvertCharInfoToCoreData(*out_core_data, char_info));
}
- void Append(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto char_info{rp.PopRaw<CharInfo>()};
-
+ Result Append(CharInfo& char_info) {
LOG_INFO(Service_Mii, "called");
- const auto result = manager->Append(metadata, char_info);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
+ R_RETURN(manager->Append(metadata, char_info));
}
std::shared_ptr<MiiManager> manager = nullptr;
DatabaseSessionMetadata metadata{};
bool is_system{};
+
+ std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys;
};
-MiiDBModule::MiiDBModule(Core::System& system_, const char* name_,
- std::shared_ptr<MiiManager> mii_manager, bool is_system_)
+IStaticService::IStaticService(Core::System& system_, const char* name_,
+ std::shared_ptr<MiiManager> mii_manager, bool is_system_)
: ServiceFramework{system_, name_}, manager{mii_manager}, is_system{is_system_} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, &MiiDBModule::GetDatabaseService, "GetDatabaseService"},
+ {0, D<&IStaticService::GetDatabaseService>, "GetDatabaseService"},
};
// clang-format on
RegisterHandlers(functions);
-
- if (manager == nullptr) {
- manager = std::make_shared<MiiManager>();
- }
}
-MiiDBModule::~MiiDBModule() = default;
-
-void MiiDBModule::GetDatabaseService(HLERequestContext& ctx) {
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(ResultSuccess);
- rb.PushIpcInterface<IDatabaseService>(system, manager, is_system);
+IStaticService::~IStaticService() = default;
+Result IStaticService::GetDatabaseService(
+ Out<SharedPointer<IDatabaseService>> out_database_service) {
LOG_DEBUG(Service_Mii, "called");
+
+ *out_database_service = std::make_shared<IDatabaseService>(system, manager, is_system);
+
+ R_SUCCEED();
}
-std::shared_ptr<MiiManager> MiiDBModule::GetMiiManager() {
+std::shared_ptr<MiiManager> IStaticService::GetMiiManager() {
return manager;
}
-class MiiImg final : public ServiceFramework<MiiImg> {
+class IImageDatabaseService final : public ServiceFramework<IImageDatabaseService> {
public:
- explicit MiiImg(Core::System& system_) : ServiceFramework{system_, "miiimg"} {
+ explicit IImageDatabaseService(Core::System& system_) : ServiceFramework{system_, "miiimg"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, &MiiImg::Initialize, "Initialize"},
+ {0, D<&IImageDatabaseService::Initialize>, "Initialize"},
{10, nullptr, "Reload"},
- {11, &MiiImg::GetCount, "GetCount"},
+ {11, D<&IImageDatabaseService::GetCount>, "GetCount"},
{12, nullptr, "IsEmpty"},
{13, nullptr, "IsFull"},
{14, nullptr, "GetAttribute"},
@@ -585,31 +341,30 @@ public:
}
private:
- void Initialize(HLERequestContext& ctx) {
+ Result Initialize() {
LOG_INFO(Service_Mii, "called");
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ R_SUCCEED();
}
- void GetCount(HLERequestContext& ctx) {
+ Result GetCount(Out<u32> out_count) {
LOG_DEBUG(Service_Mii, "called");
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(0);
+ *out_count = 0;
+
+ R_SUCCEED();
}
};
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
- std::shared_ptr<MiiManager> manager = nullptr;
+ std::shared_ptr<MiiManager> manager = std::make_shared<MiiManager>();
server_manager->RegisterNamedService(
- "mii:e", std::make_shared<MiiDBModule>(system, "mii:e", manager, true));
+ "mii:e", std::make_shared<IStaticService>(system, "mii:e", manager, true));
server_manager->RegisterNamedService(
- "mii:u", std::make_shared<MiiDBModule>(system, "mii:u", manager, false));
- server_manager->RegisterNamedService("miiimg", std::make_shared<MiiImg>(system));
+ "mii:u", std::make_shared<IStaticService>(system, "mii:u", manager, false));
+ server_manager->RegisterNamedService("miiimg", std::make_shared<IImageDatabaseService>(system));
ServerManager::RunServer(std::move(server_manager));
}
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 @@
#pragma once
-#include "core/hle/service/service.h"
+#include "core/hle/service/cmif_types.h"
namespace Core {
class System;
@@ -11,19 +11,20 @@ class System;
namespace Service::Mii {
class MiiManager;
+class IDatabaseService;
-class MiiDBModule final : public ServiceFramework<MiiDBModule> {
+class IStaticService final : public ServiceFramework<IStaticService> {
public:
- explicit MiiDBModule(Core::System& system_, const char* name_,
- std::shared_ptr<MiiManager> mii_manager, bool is_system_);
- ~MiiDBModule() override;
+ explicit IStaticService(Core::System& system_, const char* name_,
+ std::shared_ptr<MiiManager> mii_manager, bool is_system_);
+ ~IStaticService() override;
std::shared_ptr<MiiManager> GetMiiManager();
private:
- void GetDatabaseService(HLERequestContext& ctx);
+ Result GetDatabaseService(Out<SharedPointer<IDatabaseService>> out_database_service);
- std::shared_ptr<MiiManager> manager = nullptr;
+ std::shared_ptr<MiiManager> manager{nullptr};
bool is_system{};
};
diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp
index 1e2d2d212..28e3000bd 100644
--- a/src/core/hle/service/nfc/common/device.cpp
+++ b/src/core/hle/service/nfc/common/device.cpp
@@ -1405,7 +1405,7 @@ NFP::AmiiboDate NfcDevice::GetAmiiboDate(s64 posix_time) const {
system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true);
std::shared_ptr<Service::Glue::Time::TimeZoneService> timezone_service{};
- static_service->GetTimeZoneService(timezone_service);
+ static_service->GetTimeZoneService(&timezone_service);
Service::PSC::Time::CalendarTime calendar_time{};
Service::PSC::Time::CalendarAdditionalInfo additional_info{};
@@ -1416,7 +1416,7 @@ NFP::AmiiboDate NfcDevice::GetAmiiboDate(s64 posix_time) const {
amiibo_date.SetMonth(1);
amiibo_date.SetDay(1);
- if (timezone_service->ToCalendarTimeWithMyRule(calendar_time, additional_info, posix_time) ==
+ if (timezone_service->ToCalendarTimeWithMyRule(&calendar_time, &additional_info, posix_time) ==
ResultSuccess) {
amiibo_date.SetYear(calendar_time.year);
amiibo_date.SetMonth(calendar_time.month);
@@ -1431,10 +1431,10 @@ s64 NfcDevice::GetCurrentPosixTime() const {
system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true);
std::shared_ptr<Service::PSC::Time::SteadyClock> steady_clock{};
- static_service->GetStandardSteadyClock(steady_clock);
+ static_service->GetStandardSteadyClock(&steady_clock);
Service::PSC::Time::SteadyClockTimePoint time_point{};
- R_ASSERT(steady_clock->GetCurrentTimePoint(time_point));
+ R_ASSERT(steady_clock->GetCurrentTimePoint(&time_point));
return time_point.time_point;
}
diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp
index b60699c45..94a8243b5 100644
--- a/src/core/hle/service/nfc/common/device_manager.cpp
+++ b/src/core/hle/service/nfc/common/device_manager.cpp
@@ -91,10 +91,10 @@ Result DeviceManager::ListDevices(std::vector<u64>& nfp_devices, std::size_t max
true);
std::shared_ptr<Service::PSC::Time::SteadyClock> steady_clock{};
- static_service->GetStandardSteadyClock(steady_clock);
+ static_service->GetStandardSteadyClock(&steady_clock);
Service::PSC::Time::SteadyClockTimePoint time_point{};
- R_ASSERT(steady_clock->GetCurrentTimePoint(time_point));
+ R_ASSERT(steady_clock->GetCurrentTimePoint(&time_point));
const s64 elapsed_time = time_point.time_point - time_since_last_error;
if (time_since_last_error != 0 && elapsed_time < MinimumRecoveryTime) {
@@ -754,10 +754,10 @@ Result DeviceManager::VerifyDeviceResult(std::shared_ptr<NfcDevice> device,
system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true);
std::shared_ptr<Service::PSC::Time::SteadyClock> steady_clock{};
- static_service->GetStandardSteadyClock(steady_clock);
+ static_service->GetStandardSteadyClock(&steady_clock);
Service::PSC::Time::SteadyClockTimePoint time_point{};
- R_ASSERT(steady_clock->GetCurrentTimePoint(time_point));
+ R_ASSERT(steady_clock->GetCurrentTimePoint(&time_point));
time_since_last_error = time_point.time_point;
}
diff --git a/src/core/hle/service/psc/time/common.h b/src/core/hle/service/psc/time/common.h
index d17b31143..596828b8b 100644
--- a/src/core/hle/service/psc/time/common.h
+++ b/src/core/hle/service/psc/time/common.h
@@ -5,6 +5,7 @@
#include <array>
#include <chrono>
+#include <fmt/format.h>
#include "common/common_types.h"
#include "common/intrusive_list.h"
@@ -21,8 +22,14 @@ class System;
namespace Service::PSC::Time {
using ClockSourceId = Common::UUID;
+enum class TimeType : u8 {
+ UserSystemClock = 0,
+ NetworkSystemClock = 1,
+ LocalSystemClock = 2,
+};
+
struct SteadyClockTimePoint {
- constexpr bool IdMatches(SteadyClockTimePoint& other) {
+ constexpr bool IdMatches(const SteadyClockTimePoint& other) const {
return clock_source_id == other.clock_source_id;
}
bool operator==(const SteadyClockTimePoint& other) const = default;
@@ -42,12 +49,6 @@ struct SystemClockContext {
static_assert(sizeof(SystemClockContext) == 0x20, "SystemClockContext has the wrong size!");
static_assert(std::is_trivial_v<SystemClockContext>);
-enum class TimeType : u8 {
- UserSystemClock,
- NetworkSystemClock,
- LocalSystemClock,
-};
-
struct CalendarTime {
s16 year;
s8 month;
@@ -67,14 +68,10 @@ struct CalendarAdditionalInfo {
};
static_assert(sizeof(CalendarAdditionalInfo) == 0x18, "CalendarAdditionalInfo has the wrong size!");
-struct LocationName {
- std::array<char, 36> name;
-};
+using LocationName = std::array<char, 0x24>;
static_assert(sizeof(LocationName) == 0x24, "LocationName has the wrong size!");
-struct RuleVersion {
- std::array<char, 16> version;
-};
+using RuleVersion = std::array<char, 0x10>;
static_assert(sizeof(RuleVersion) == 0x10, "RuleVersion has the wrong size!");
struct ClockSnapshot {
@@ -152,8 +149,8 @@ constexpr inline std::chrono::nanoseconds ConvertToTimeSpan(s64 ticks) {
return std::chrono::nanoseconds(a + b);
}
-constexpr inline Result GetSpanBetweenTimePoints(s64* out_seconds, SteadyClockTimePoint& a,
- SteadyClockTimePoint& b) {
+constexpr inline Result GetSpanBetweenTimePoints(s64* out_seconds, const SteadyClockTimePoint& a,
+ const SteadyClockTimePoint& b) {
R_UNLESS(out_seconds, ResultInvalidArgument);
R_UNLESS(a.IdMatches(b), ResultInvalidArgument);
R_UNLESS(a.time_point >= 0 || b.time_point <= a.time_point + std::numeric_limits<s64>::max(),
@@ -166,3 +163,111 @@ constexpr inline Result GetSpanBetweenTimePoints(s64* out_seconds, SteadyClockTi
}
} // namespace Service::PSC::Time
+
+template <>
+struct fmt::formatter<Service::PSC::Time::TimeType> : fmt::formatter<fmt::string_view> {
+ template <typename FormatContext>
+ auto format(Service::PSC::Time::TimeType type, FormatContext& ctx) {
+ const string_view name = [type] {
+ using Service::PSC::Time::TimeType;
+ switch (type) {
+ case TimeType::UserSystemClock:
+ return "UserSystemClock";
+ case TimeType::NetworkSystemClock:
+ return "NetworkSystemClock";
+ case TimeType::LocalSystemClock:
+ return "LocalSystemClock";
+ }
+ return "Invalid";
+ }();
+ return formatter<string_view>::format(name, ctx);
+ }
+};
+
+template <>
+struct fmt::formatter<Service::PSC::Time::SteadyClockTimePoint> : fmt::formatter<fmt::string_view> {
+ template <typename FormatContext>
+ auto format(const Service::PSC::Time::SteadyClockTimePoint& time_point,
+ FormatContext& ctx) const {
+ return fmt::format_to(ctx.out(), "time_point={}", time_point.time_point);
+ }
+};
+
+template <>
+struct fmt::formatter<Service::PSC::Time::SystemClockContext> : fmt::formatter<fmt::string_view> {
+ template <typename FormatContext>
+ auto format(const Service::PSC::Time::SystemClockContext& context, FormatContext& ctx) const {
+ return fmt::format_to(ctx.out(), "offset={} steady_time_point={}", context.offset,
+ context.steady_time_point.time_point);
+ }
+};
+
+template <>
+struct fmt::formatter<Service::PSC::Time::CalendarTime> : fmt::formatter<fmt::string_view> {
+ template <typename FormatContext>
+ auto format(const Service::PSC::Time::CalendarTime& calendar, FormatContext& ctx) const {
+ return fmt::format_to(ctx.out(), "{}/{}/{} {}:{}:{}", calendar.day, calendar.month,
+ calendar.year, calendar.hour, calendar.minute, calendar.second);
+ }
+};
+
+template <>
+struct fmt::formatter<Service::PSC::Time::CalendarAdditionalInfo>
+ : fmt::formatter<fmt::string_view> {
+ template <typename FormatContext>
+ auto format(const Service::PSC::Time::CalendarAdditionalInfo& additional,
+ FormatContext& ctx) const {
+ return fmt::format_to(ctx.out(), "weekday={} yearday={} name={} is_dst={} ut_offset={}",
+ additional.day_of_week, additional.day_of_year,
+ additional.name.data(), additional.is_dst, additional.ut_offset);
+ }
+};
+
+template <>
+struct fmt::formatter<Service::PSC::Time::LocationName> : fmt::formatter<fmt::string_view> {
+ template <typename FormatContext>
+ auto format(const Service::PSC::Time::LocationName& name, FormatContext& ctx) const {
+ std::string_view n{name.data(), name.size()};
+ return formatter<string_view>::format(n, ctx);
+ }
+};
+
+template <>
+struct fmt::formatter<Service::PSC::Time::RuleVersion> : fmt::formatter<fmt::string_view> {
+ template <typename FormatContext>
+ auto format(const Service::PSC::Time::RuleVersion& version, FormatContext& ctx) const {
+ std::string_view v{version.data(), version.size()};
+ return formatter<string_view>::format(v, ctx);
+ }
+};
+
+template <>
+struct fmt::formatter<Service::PSC::Time::ClockSnapshot> : fmt::formatter<fmt::string_view> {
+ template <typename FormatContext>
+ auto format(const Service::PSC::Time::ClockSnapshot& snapshot, FormatContext& ctx) const {
+ return fmt::format_to(
+ ctx.out(),
+ "user_context={} network_context={} user_time={} network_time={} user_calendar_time={} "
+ "network_calendar_time={} user_calendar_additional_time={} "
+ "network_calendar_additional_time={} steady_clock_time_point={} location={} "
+ "is_automatic_correction_enabled={} type={}",
+ snapshot.user_context, snapshot.network_context, snapshot.user_time,
+ snapshot.network_time, snapshot.user_calendar_time, snapshot.network_calendar_time,
+ snapshot.user_calendar_additional_time, snapshot.network_calendar_additional_time,
+ snapshot.steady_clock_time_point, snapshot.location_name,
+ snapshot.is_automatic_correction_enabled, snapshot.type);
+ }
+};
+
+template <>
+struct fmt::formatter<Service::PSC::Time::ContinuousAdjustmentTimePoint>
+ : fmt::formatter<fmt::string_view> {
+ template <typename FormatContext>
+ auto format(const Service::PSC::Time::ContinuousAdjustmentTimePoint& time_point,
+ FormatContext& ctx) const {
+ return fmt::format_to(ctx.out(),
+ "rtc_offset={} diff_scale={} shift_amount={} lower={} upper={}",
+ time_point.rtc_offset, time_point.diff_scale, time_point.shift_amount,
+ time_point.lower, time_point.upper);
+ }
+}; \ No newline at end of file
diff --git a/src/core/hle/service/psc/time/power_state_service.cpp b/src/core/hle/service/psc/time/power_state_service.cpp
index b0ae71bf9..ab1d32c70 100644
--- a/src/core/hle/service/psc/time/power_state_service.cpp
+++ b/src/core/hle/service/psc/time/power_state_service.cpp
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/psc/time/power_state_service.h"
namespace Service::PSC::Time {
@@ -11,39 +12,34 @@ IPowerStateRequestHandler::IPowerStateRequestHandler(
power_state_request_manager} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, &IPowerStateRequestHandler::GetPowerStateRequestEventReadableHandle, "GetPowerStateRequestEventReadableHandle"},
- {1, &IPowerStateRequestHandler::GetAndClearPowerStateRequest, "GetAndClearPowerStateRequest"},
+ {0, D<&IPowerStateRequestHandler::GetPowerStateRequestEventReadableHandle>, "GetPowerStateRequestEventReadableHandle"},
+ {1, D<&IPowerStateRequestHandler::GetAndClearPowerStateRequest>, "GetAndClearPowerStateRequest"},
};
// clang-format on
RegisterHandlers(functions);
}
-void IPowerStateRequestHandler::GetPowerStateRequestEventReadableHandle(HLERequestContext& ctx) {
+Result IPowerStateRequestHandler::GetPowerStateRequestEventReadableHandle(
+ OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_DEBUG(Service_Time, "called.");
- IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(ResultSuccess);
- rb.PushCopyObjects(m_power_state_request_manager.GetReadableEvent());
+ *out_event = &m_power_state_request_manager.GetReadableEvent();
+ R_SUCCEED();
}
-void IPowerStateRequestHandler::GetAndClearPowerStateRequest(HLERequestContext& ctx) {
+Result IPowerStateRequestHandler::GetAndClearPowerStateRequest(Out<bool> out_cleared,
+ Out<u32> out_priority) {
LOG_DEBUG(Service_Time, "called.");
u32 priority{};
auto cleared = m_power_state_request_manager.GetAndClearPowerStateRequest(priority);
+ *out_cleared = cleared;
if (cleared) {
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(ResultSuccess);
- rb.Push(priority);
- rb.Push(cleared);
- return;
+ *out_priority = priority;
}
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(cleared);
+ R_SUCCEED();
}
} // namespace Service::PSC::Time
diff --git a/src/core/hle/service/psc/time/power_state_service.h b/src/core/hle/service/psc/time/power_state_service.h
index 3ebfddb79..56e2c4b87 100644
--- a/src/core/hle/service/psc/time/power_state_service.h
+++ b/src/core/hle/service/psc/time/power_state_service.h
@@ -3,6 +3,7 @@
#pragma once
+#include "core/hle/service/cmif_types.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/psc/time/power_state_request_manager.h"
#include "core/hle/service/server_manager.h"
@@ -21,10 +22,10 @@ public:
~IPowerStateRequestHandler() override = default;
-private:
- void GetPowerStateRequestEventReadableHandle(HLERequestContext& ctx);
- void GetAndClearPowerStateRequest(HLERequestContext& ctx);
+ Result GetPowerStateRequestEventReadableHandle(OutCopyHandle<Kernel::KReadableEvent> out_event);
+ Result GetAndClearPowerStateRequest(Out<bool> out_cleared, Out<u32> out_priority);
+private:
Core::System& m_system;
PowerStateRequestManager& m_power_state_request_manager;
};
diff --git a/src/core/hle/service/psc/time/service_manager.cpp b/src/core/hle/service/psc/time/service_manager.cpp
index 60820aa9b..ec906b723 100644
--- a/src/core/hle/service/psc/time/service_manager.cpp
+++ b/src/core/hle/service/psc/time/service_manager.cpp
@@ -3,6 +3,7 @@
#include "core/core.h"
#include "core/core_timing.h"
+#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/psc/time/power_state_service.h"
#include "core/hle/service/psc/time/service_manager.h"
#include "core/hle/service/psc/time/static.h"
@@ -25,24 +26,24 @@ ServiceManager::ServiceManager(Core::System& system_, std::shared_ptr<TimeManage
m_local_operation{m_system}, m_network_operation{m_system}, m_ephemeral_operation{m_system} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, &ServiceManager::Handle_GetStaticServiceAsUser, "GetStaticServiceAsUser"},
- {5, &ServiceManager::Handle_GetStaticServiceAsAdmin, "GetStaticServiceAsAdmin"},
- {6, &ServiceManager::Handle_GetStaticServiceAsRepair, "GetStaticServiceAsRepair"},
- {9, &ServiceManager::Handle_GetStaticServiceAsServiceManager, "GetStaticServiceAsServiceManager"},
- {10, &ServiceManager::Handle_SetupStandardSteadyClockCore, "SetupStandardSteadyClockCore"},
- {11, &ServiceManager::Handle_SetupStandardLocalSystemClockCore, "SetupStandardLocalSystemClockCore"},
- {12, &ServiceManager::Handle_SetupStandardNetworkSystemClockCore, "SetupStandardNetworkSystemClockCore"},
- {13, &ServiceManager::Handle_SetupStandardUserSystemClockCore, "SetupStandardUserSystemClockCore"},
- {14, &ServiceManager::Handle_SetupTimeZoneServiceCore, "SetupTimeZoneServiceCore"},
- {15, &ServiceManager::Handle_SetupEphemeralNetworkSystemClockCore, "SetupEphemeralNetworkSystemClockCore"},
- {50, &ServiceManager::Handle_GetStandardLocalClockOperationEvent, "GetStandardLocalClockOperationEvent"},
- {51, &ServiceManager::Handle_GetStandardNetworkClockOperationEventForServiceManager, "GetStandardNetworkClockOperationEventForServiceManager"},
- {52, &ServiceManager::Handle_GetEphemeralNetworkClockOperationEventForServiceManager, "GetEphemeralNetworkClockOperationEventForServiceManager"},
- {60, &ServiceManager::Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent, "GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent"},
- {100, &ServiceManager::Handle_SetStandardSteadyClockBaseTime, "SetStandardSteadyClockBaseTime"},
- {200, &ServiceManager::Handle_GetClosestAlarmUpdatedEvent, "GetClosestAlarmUpdatedEvent"},
- {201, &ServiceManager::Handle_CheckAndSignalAlarms, "CheckAndSignalAlarms"},
- {202, &ServiceManager::Handle_GetClosestAlarmInfo, "GetClosestAlarmInfo "},
+ {0, D<&ServiceManager::GetStaticServiceAsUser>, "GetStaticServiceAsUser"},
+ {5, D<&ServiceManager::GetStaticServiceAsAdmin>, "GetStaticServiceAsAdmin"},
+ {6, D<&ServiceManager::GetStaticServiceAsRepair>, "GetStaticServiceAsRepair"},
+ {9, D<&ServiceManager::GetStaticServiceAsServiceManager>, "GetStaticServiceAsServiceManager"},
+ {10, D<&ServiceManager::SetupStandardSteadyClockCore>, "SetupStandardSteadyClockCore"},
+ {11, D<&ServiceManager::SetupStandardLocalSystemClockCore>, "SetupStandardLocalSystemClockCore"},
+ {12, D<&ServiceManager::SetupStandardNetworkSystemClockCore>, "SetupStandardNetworkSystemClockCore"},
+ {13, D<&ServiceManager::SetupStandardUserSystemClockCore>, "SetupStandardUserSystemClockCore"},
+ {14, D<&ServiceManager::SetupTimeZoneServiceCore>, "SetupTimeZoneServiceCore"},
+ {15, D<&ServiceManager::SetupEphemeralNetworkSystemClockCore>, "SetupEphemeralNetworkSystemClockCore"},
+ {50, D<&ServiceManager::GetStandardLocalClockOperationEvent>, "GetStandardLocalClockOperationEvent"},
+ {51, D<&ServiceManager::GetStandardNetworkClockOperationEventForServiceManager>, "GetStandardNetworkClockOperationEventForServiceManager"},
+ {52, D<&ServiceManager::GetEphemeralNetworkClockOperationEventForServiceManager>, "GetEphemeralNetworkClockOperationEventForServiceManager"},
+ {60, D<&ServiceManager::GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent>, "GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent"},
+ {100, D<&ServiceManager::SetStandardSteadyClockBaseTime>, "SetStandardSteadyClockBaseTime"},
+ {200, D<&ServiceManager::GetClosestAlarmUpdatedEvent>, "GetClosestAlarmUpdatedEvent"},
+ {201, D<&ServiceManager::CheckAndSignalAlarms>, "CheckAndSignalAlarms"},
+ {202, D<&ServiceManager::GetClosestAlarmInfo>, "GetClosestAlarmInfo "},
};
// clang-format on
RegisterHandlers(functions);
@@ -52,302 +53,39 @@ ServiceManager::ServiceManager(Core::System& system_, std::shared_ptr<TimeManage
m_ephemeral_system_context_writer.Link(m_ephemeral_operation);
}
-void ServiceManager::SetupSAndP() {
- if (!m_is_s_and_p_setup) {
- m_is_s_and_p_setup = true;
- m_server_manager.RegisterNamedService(
- "time:s", std::make_shared<StaticService>(
- m_system, StaticServiceSetupInfo{0, 0, 1, 0, 0, 0}, m_time, "time:s"));
- m_server_manager.RegisterNamedService("time:p",
- std::make_shared<IPowerStateRequestHandler>(
- m_system, m_time->m_power_state_request_manager));
- }
-}
-
-void ServiceManager::CheckAndSetupServicesSAndP() {
- if (m_local_system_clock.IsInitialized() && m_user_system_clock.IsInitialized() &&
- m_network_system_clock.IsInitialized() && m_steady_clock.IsInitialized() &&
- m_time_zone.IsInitialized() && m_ephemeral_network_clock.IsInitialized()) {
- SetupSAndP();
- }
-}
-
-void ServiceManager::Handle_GetStaticServiceAsUser(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- std::shared_ptr<StaticService> service{};
- auto res = GetStaticServiceAsUser(service);
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(res);
- rb.PushIpcInterface<StaticService>(std::move(service));
-}
-
-void ServiceManager::Handle_GetStaticServiceAsAdmin(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- std::shared_ptr<StaticService> service{};
- auto res = GetStaticServiceAsAdmin(service);
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(res);
- rb.PushIpcInterface<StaticService>(std::move(service));
-}
-
-void ServiceManager::Handle_GetStaticServiceAsRepair(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- std::shared_ptr<StaticService> service{};
- auto res = GetStaticServiceAsRepair(service);
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(res);
- rb.PushIpcInterface<StaticService>(std::move(service));
-}
-
-void ServiceManager::Handle_GetStaticServiceAsServiceManager(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- std::shared_ptr<StaticService> service{};
- auto res = GetStaticServiceAsServiceManager(service);
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(res);
- rb.PushIpcInterface<StaticService>(std::move(service));
-}
-
-void ServiceManager::Handle_SetupStandardSteadyClockCore(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- struct Parameters {
- bool reset_detected;
- Common::UUID clock_source_id;
- s64 rtc_offset;
- s64 internal_offset;
- s64 test_offset;
- };
- static_assert(sizeof(Parameters) == 0x30);
-
- IPC::RequestParser rp{ctx};
- auto params{rp.PopRaw<Parameters>()};
-
- auto res = SetupStandardSteadyClockCore(params.clock_source_id, params.rtc_offset,
- params.internal_offset, params.test_offset,
- params.reset_detected);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
-}
-
-void ServiceManager::Handle_SetupStandardLocalSystemClockCore(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::RequestParser rp{ctx};
- auto context{rp.PopRaw<SystemClockContext>()};
- auto time{rp.Pop<s64>()};
-
- auto res = SetupStandardLocalSystemClockCore(context, time);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
-}
-
-void ServiceManager::Handle_SetupStandardNetworkSystemClockCore(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::RequestParser rp{ctx};
- auto context{rp.PopRaw<SystemClockContext>()};
- auto accuracy{rp.Pop<s64>()};
-
- auto res = SetupStandardNetworkSystemClockCore(context, accuracy);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
-}
-
-void ServiceManager::Handle_SetupStandardUserSystemClockCore(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- struct Parameters {
- bool automatic_correction;
- SteadyClockTimePoint time_point;
- };
- static_assert(sizeof(Parameters) == 0x20);
-
- IPC::RequestParser rp{ctx};
- auto params{rp.PopRaw<Parameters>()};
-
- auto res = SetupStandardUserSystemClockCore(params.time_point, params.automatic_correction);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
-}
-
-void ServiceManager::Handle_SetupTimeZoneServiceCore(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- struct Parameters {
- u32 location_count;
- LocationName name;
- SteadyClockTimePoint time_point;
- RuleVersion rule_version;
- };
- static_assert(sizeof(Parameters) == 0x50);
-
- IPC::RequestParser rp{ctx};
- auto params{rp.PopRaw<Parameters>()};
-
- auto rule_buffer{ctx.ReadBuffer()};
-
- auto res = SetupTimeZoneServiceCore(params.name, params.time_point, params.rule_version,
- params.location_count, rule_buffer);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
-}
-
-void ServiceManager::Handle_SetupEphemeralNetworkSystemClockCore(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- auto res = SetupEphemeralNetworkSystemClockCore();
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
-}
-
-void ServiceManager::Handle_GetStandardLocalClockOperationEvent(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- Kernel::KEvent* event{};
- auto res = GetStandardLocalClockOperationEvent(&event);
-
- IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(res);
- rb.PushCopyObjects(event->GetReadableEvent());
-}
-
-void ServiceManager::Handle_GetStandardNetworkClockOperationEventForServiceManager(
- HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- Kernel::KEvent* event{};
- auto res = GetStandardNetworkClockOperationEventForServiceManager(&event);
-
- IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(res);
- rb.PushCopyObjects(event);
-}
-
-void ServiceManager::Handle_GetEphemeralNetworkClockOperationEventForServiceManager(
- HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- Kernel::KEvent* event{};
- auto res = GetEphemeralNetworkClockOperationEventForServiceManager(&event);
-
- IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(res);
- rb.PushCopyObjects(event);
-}
-
-void ServiceManager::Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent(
- HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- Kernel::KEvent* event{};
- auto res = GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent(&event);
-
- IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(res);
- rb.PushCopyObjects(event);
-}
-
-void ServiceManager::Handle_SetStandardSteadyClockBaseTime(HLERequestContext& ctx) {
+Result ServiceManager::GetStaticServiceAsUser(OutInterface<StaticService> out_service) {
LOG_DEBUG(Service_Time, "called.");
- IPC::RequestParser rp{ctx};
- auto base_time{rp.Pop<s64>()};
-
- auto res = SetStandardSteadyClockBaseTime(base_time);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
+ R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{0, 0, 0, 0, 0, 0}, "time:u"));
}
-void ServiceManager::Handle_GetClosestAlarmUpdatedEvent(HLERequestContext& ctx) {
+Result ServiceManager::GetStaticServiceAsAdmin(OutInterface<StaticService> out_service) {
LOG_DEBUG(Service_Time, "called.");
- Kernel::KEvent* event{};
- auto res = GetClosestAlarmUpdatedEvent(&event);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(res);
- rb.PushCopyObjects(event->GetReadableEvent());
+ R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{1, 1, 0, 1, 0, 0}, "time:a"));
}
-void ServiceManager::Handle_CheckAndSignalAlarms(HLERequestContext& ctx) {
+Result ServiceManager::GetStaticServiceAsRepair(OutInterface<StaticService> out_service) {
LOG_DEBUG(Service_Time, "called.");
- auto res = CheckAndSignalAlarms();
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
+ R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{0, 0, 0, 0, 1, 0}, "time:r"));
}
-void ServiceManager::Handle_GetClosestAlarmInfo(HLERequestContext& ctx) {
+Result ServiceManager::GetStaticServiceAsServiceManager(OutInterface<StaticService> out_service) {
LOG_DEBUG(Service_Time, "called.");
- AlarmInfo alarm_info{};
- bool is_valid{};
- s64 time{};
- auto res = GetClosestAlarmInfo(is_valid, alarm_info, time);
-
- struct OutParameters {
- bool is_valid;
- AlarmInfo alarm_info;
- s64 time;
- };
- static_assert(sizeof(OutParameters) == 0x20);
-
- OutParameters out_params{
- .is_valid = is_valid,
- .alarm_info = alarm_info,
- .time = time,
- };
-
- IPC::ResponseBuilder rb{ctx, 2 + sizeof(OutParameters) / sizeof(u32)};
- rb.Push(res);
- rb.PushRaw<OutParameters>(out_params);
-}
-
-// =============================== Implementations ===========================
-
-Result ServiceManager::GetStaticService(std::shared_ptr<StaticService>& out_service,
- StaticServiceSetupInfo setup_info, const char* name) {
- out_service = std::make_shared<StaticService>(m_system, setup_info, m_time, name);
- R_SUCCEED();
-}
-
-Result ServiceManager::GetStaticServiceAsUser(std::shared_ptr<StaticService>& out_service) {
- R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{0, 0, 0, 0, 0, 0}, "time:u"));
-}
-
-Result ServiceManager::GetStaticServiceAsAdmin(std::shared_ptr<StaticService>& out_service) {
- R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{1, 1, 0, 1, 0, 0}, "time:a"));
-}
-
-Result ServiceManager::GetStaticServiceAsRepair(std::shared_ptr<StaticService>& out_service) {
- R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{0, 0, 0, 0, 1, 0}, "time:r"));
-}
-
-Result ServiceManager::GetStaticServiceAsServiceManager(
- std::shared_ptr<StaticService>& out_service) {
R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{1, 1, 1, 1, 1, 0}, "time:sm"));
}
-Result ServiceManager::SetupStandardSteadyClockCore(Common::UUID& clock_source_id, s64 rtc_offset,
- s64 internal_offset, s64 test_offset,
- bool is_rtc_reset_detected) {
+Result ServiceManager::SetupStandardSteadyClockCore(bool is_rtc_reset_detected,
+ Common::UUID& clock_source_id, s64 rtc_offset,
+ s64 internal_offset, s64 test_offset) {
+ LOG_DEBUG(Service_Time,
+ "called. is_rtc_reset_detected={} clock_source_id={} rtc_offset={} "
+ "internal_offset={} test_offset={}",
+ is_rtc_reset_detected, clock_source_id.RawString(), rtc_offset, internal_offset,
+ test_offset);
+
m_steady_clock.Initialize(clock_source_id, rtc_offset, internal_offset, test_offset,
is_rtc_reset_detected);
auto time = m_steady_clock.GetRawTime();
@@ -365,6 +103,10 @@ Result ServiceManager::SetupStandardSteadyClockCore(Common::UUID& clock_source_i
}
Result ServiceManager::SetupStandardLocalSystemClockCore(SystemClockContext& context, s64 time) {
+ LOG_DEBUG(Service_Time,
+ "called. context={} context.steady_time_point.clock_source_id={} time={}", context,
+ context.steady_time_point.clock_source_id.RawString(), time);
+
m_local_system_clock.SetContextWriter(m_local_system_context_writer);
m_local_system_clock.Initialize(context, time);
@@ -374,6 +116,9 @@ Result ServiceManager::SetupStandardLocalSystemClockCore(SystemClockContext& con
Result ServiceManager::SetupStandardNetworkSystemClockCore(SystemClockContext& context,
s64 accuracy) {
+ LOG_DEBUG(Service_Time, "called. context={} steady_time_point.clock_source_id={} accuracy={}",
+ context, context.steady_time_point.clock_source_id.RawString(), accuracy);
+
// TODO this is a hack! The network clock should be updated independently, from the ntc service
// and maybe elsewhere. We do not do that, so fix the clock to the local clock on first boot
// to avoid it being stuck at 0.
@@ -388,8 +133,11 @@ Result ServiceManager::SetupStandardNetworkSystemClockCore(SystemClockContext& c
R_SUCCEED();
}
-Result ServiceManager::SetupStandardUserSystemClockCore(SteadyClockTimePoint& time_point,
- bool automatic_correction) {
+Result ServiceManager::SetupStandardUserSystemClockCore(bool automatic_correction,
+ SteadyClockTimePoint& time_point) {
+ LOG_DEBUG(Service_Time, "called. automatic_correction={} time_point={} clock_source_id={}",
+ automatic_correction, time_point, time_point.clock_source_id.RawString());
+
// TODO this is a hack! The user clock should be updated independently, from the ntc service
// and maybe elsewhere. We do not do that, so fix the clock to the local clock on first boot
// to avoid it being stuck at 0.
@@ -406,10 +154,16 @@ Result ServiceManager::SetupStandardUserSystemClockCore(SteadyClockTimePoint& ti
R_SUCCEED();
}
-Result ServiceManager::SetupTimeZoneServiceCore(LocationName& name,
+Result ServiceManager::SetupTimeZoneServiceCore(LocationName& name, RuleVersion& rule_version,
+ u32 location_count,
SteadyClockTimePoint& time_point,
- RuleVersion& rule_version, u32 location_count,
- std::span<const u8> rule_buffer) {
+ InBuffer<BufferAttr_HipcAutoSelect> rule_buffer) {
+ LOG_DEBUG(Service_Time,
+ "called. name={} rule_version={} location_count={} time_point={} "
+ "clock_source_id={}",
+ name, rule_version, location_count, time_point,
+ time_point.clock_source_id.RawString());
+
if (m_time_zone.ParseBinary(name, rule_buffer) != ResultSuccess) {
LOG_ERROR(Service_Time, "Failed to parse time zone binary!");
}
@@ -424,6 +178,8 @@ Result ServiceManager::SetupTimeZoneServiceCore(LocationName& name,
}
Result ServiceManager::SetupEphemeralNetworkSystemClockCore() {
+ LOG_DEBUG(Service_Time, "called.");
+
m_ephemeral_network_clock.SetContextWriter(m_ephemeral_system_context_writer);
m_ephemeral_network_clock.SetInitialized();
@@ -431,30 +187,41 @@ Result ServiceManager::SetupEphemeralNetworkSystemClockCore() {
R_SUCCEED();
}
-Result ServiceManager::GetStandardLocalClockOperationEvent(Kernel::KEvent** out_event) {
- *out_event = m_local_operation.m_event;
+Result ServiceManager::GetStandardLocalClockOperationEvent(
+ OutCopyHandle<Kernel::KReadableEvent> out_event) {
+ LOG_DEBUG(Service_Time, "called.");
+
+ *out_event = &m_local_operation.m_event->GetReadableEvent();
R_SUCCEED();
}
Result ServiceManager::GetStandardNetworkClockOperationEventForServiceManager(
- Kernel::KEvent** out_event) {
- *out_event = m_network_operation.m_event;
+ OutCopyHandle<Kernel::KReadableEvent> out_event) {
+ LOG_DEBUG(Service_Time, "called.");
+
+ *out_event = &m_network_operation.m_event->GetReadableEvent();
R_SUCCEED();
}
Result ServiceManager::GetEphemeralNetworkClockOperationEventForServiceManager(
- Kernel::KEvent** out_event) {
- *out_event = m_ephemeral_operation.m_event;
+ OutCopyHandle<Kernel::KReadableEvent> out_event) {
+ LOG_DEBUG(Service_Time, "called.");
+
+ *out_event = &m_ephemeral_operation.m_event->GetReadableEvent();
R_SUCCEED();
}
Result ServiceManager::GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent(
- Kernel::KEvent** out_event) {
- *out_event = &m_user_system_clock.GetEvent();
+ OutCopyHandle<Kernel::KReadableEvent> out_event) {
+ LOG_DEBUG(Service_Time, "called.");
+
+ *out_event = &m_user_system_clock.GetEvent().GetReadableEvent();
R_SUCCEED();
}
Result ServiceManager::SetStandardSteadyClockBaseTime(s64 base_time) {
+ LOG_DEBUG(Service_Time, "called. base_time={}", base_time);
+
m_steady_clock.SetRtcOffset(base_time);
auto time = m_steady_clock.GetRawTime();
auto ticks = m_system.CoreTiming().GetClockTicks();
@@ -468,26 +235,63 @@ Result ServiceManager::SetStandardSteadyClockBaseTime(s64 base_time) {
R_SUCCEED();
}
-Result ServiceManager::GetClosestAlarmUpdatedEvent(Kernel::KEvent** out_event) {
- *out_event = &m_alarms.GetEvent();
+Result ServiceManager::GetClosestAlarmUpdatedEvent(
+ OutCopyHandle<Kernel::KReadableEvent> out_event) {
+ LOG_DEBUG(Service_Time, "called.");
+
+ *out_event = &m_alarms.GetEvent().GetReadableEvent();
R_SUCCEED();
}
Result ServiceManager::CheckAndSignalAlarms() {
+ LOG_DEBUG(Service_Time, "called.");
+
m_alarms.CheckAndSignal();
R_SUCCEED();
}
-Result ServiceManager::GetClosestAlarmInfo(bool& out_is_valid, AlarmInfo& out_info, s64& out_time) {
+Result ServiceManager::GetClosestAlarmInfo(Out<bool> out_is_valid, Out<AlarmInfo> out_info,
+ Out<s64> out_time) {
Alarm* alarm{nullptr};
- out_is_valid = m_alarms.GetClosestAlarm(&alarm);
- if (out_is_valid) {
- out_info = {
+ *out_is_valid = m_alarms.GetClosestAlarm(&alarm);
+ if (*out_is_valid) {
+ *out_info = {
.alert_time = alarm->GetAlertTime(),
.priority = alarm->GetPriority(),
};
- out_time = m_alarms.GetRawTime();
+ *out_time = m_alarms.GetRawTime();
+ }
+
+ LOG_DEBUG(Service_Time,
+ "called. out_is_valid={} out_info.alert_time={} out_info.priority={}, out_time={}",
+ *out_is_valid, out_info->alert_time, out_info->priority, *out_time);
+
+ R_SUCCEED();
+}
+
+void ServiceManager::CheckAndSetupServicesSAndP() {
+ if (m_local_system_clock.IsInitialized() && m_user_system_clock.IsInitialized() &&
+ m_network_system_clock.IsInitialized() && m_steady_clock.IsInitialized() &&
+ m_time_zone.IsInitialized() && m_ephemeral_network_clock.IsInitialized()) {
+ SetupSAndP();
+ }
+}
+
+void ServiceManager::SetupSAndP() {
+ if (!m_is_s_and_p_setup) {
+ m_is_s_and_p_setup = true;
+ m_server_manager.RegisterNamedService(
+ "time:s", std::make_shared<StaticService>(
+ m_system, StaticServiceSetupInfo{0, 0, 1, 0, 0, 0}, m_time, "time:s"));
+ m_server_manager.RegisterNamedService("time:p",
+ std::make_shared<IPowerStateRequestHandler>(
+ m_system, m_time->m_power_state_request_manager));
}
+}
+
+Result ServiceManager::GetStaticService(OutInterface<StaticService> out_service,
+ StaticServiceSetupInfo setup_info, const char* name) {
+ *out_service = std::make_shared<StaticService>(m_system, setup_info, m_time, name);
R_SUCCEED();
}
diff --git a/src/core/hle/service/psc/time/service_manager.h b/src/core/hle/service/psc/time/service_manager.h
index 1d9952317..25d361d4f 100644
--- a/src/core/hle/service/psc/time/service_manager.h
+++ b/src/core/hle/service/psc/time/service_manager.h
@@ -6,6 +6,7 @@
#include <list>
#include <memory>
+#include "core/hle/service/cmif_types.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/psc/time/common.h"
#include "core/hle/service/psc/time/manager.h"
@@ -29,55 +30,38 @@ public:
ServerManager* server_manager);
~ServiceManager() override = default;
- Result GetStaticServiceAsUser(std::shared_ptr<StaticService>& out_service);
- Result GetStaticServiceAsAdmin(std::shared_ptr<StaticService>& out_service);
- Result GetStaticServiceAsRepair(std::shared_ptr<StaticService>& out_service);
- Result GetStaticServiceAsServiceManager(std::shared_ptr<StaticService>& out_service);
- Result SetupStandardSteadyClockCore(Common::UUID& clock_source_id, s64 rtc_offset,
- s64 internal_offset, s64 test_offset,
- bool is_rtc_reset_detected);
+ Result GetStaticServiceAsUser(OutInterface<StaticService> out_service);
+ Result GetStaticServiceAsAdmin(OutInterface<StaticService> out_service);
+ Result GetStaticServiceAsRepair(OutInterface<StaticService> out_service);
+ Result GetStaticServiceAsServiceManager(OutInterface<StaticService> out_service);
+ Result SetupStandardSteadyClockCore(bool is_rtc_reset_detected, Common::UUID& clock_source_id,
+ s64 rtc_offset, s64 internal_offset, s64 test_offset);
Result SetupStandardLocalSystemClockCore(SystemClockContext& context, s64 time);
Result SetupStandardNetworkSystemClockCore(SystemClockContext& context, s64 accuracy);
- Result SetupStandardUserSystemClockCore(SteadyClockTimePoint& time_point,
- bool automatic_correction);
- Result SetupTimeZoneServiceCore(LocationName& name, SteadyClockTimePoint& time_point,
- RuleVersion& rule_version, u32 location_count,
- std::span<const u8> rule_buffer);
+ Result SetupStandardUserSystemClockCore(bool automatic_correction,
+ SteadyClockTimePoint& time_point);
+ Result SetupTimeZoneServiceCore(LocationName& name, RuleVersion& rule_version,
+ u32 location_count, SteadyClockTimePoint& time_point,
+ InBuffer<BufferAttr_HipcAutoSelect> rule_buffer);
Result SetupEphemeralNetworkSystemClockCore();
- Result GetStandardLocalClockOperationEvent(Kernel::KEvent** out_event);
- Result GetStandardNetworkClockOperationEventForServiceManager(Kernel::KEvent** out_event);
- Result GetEphemeralNetworkClockOperationEventForServiceManager(Kernel::KEvent** out_event);
- Result GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent(Kernel::KEvent** out_event);
+ Result GetStandardLocalClockOperationEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+ Result GetStandardNetworkClockOperationEventForServiceManager(
+ OutCopyHandle<Kernel::KReadableEvent> out_event);
+ Result GetEphemeralNetworkClockOperationEventForServiceManager(
+ OutCopyHandle<Kernel::KReadableEvent> out_event);
+ Result GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent(
+ OutCopyHandle<Kernel::KReadableEvent> out_event);
Result SetStandardSteadyClockBaseTime(s64 base_time);
- Result GetClosestAlarmUpdatedEvent(Kernel::KEvent** out_event);
+ Result GetClosestAlarmUpdatedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result CheckAndSignalAlarms();
- Result GetClosestAlarmInfo(bool& out_is_valid, AlarmInfo& out_info, s64& out_time);
+ Result GetClosestAlarmInfo(Out<bool> out_is_valid, Out<AlarmInfo> out_info, Out<s64> out_time);
private:
void CheckAndSetupServicesSAndP();
void SetupSAndP();
- Result GetStaticService(std::shared_ptr<StaticService>& out_service,
+ Result GetStaticService(OutInterface<StaticService> out_service,
StaticServiceSetupInfo setup_info, const char* name);
- void Handle_GetStaticServiceAsUser(HLERequestContext& ctx);
- void Handle_GetStaticServiceAsAdmin(HLERequestContext& ctx);
- void Handle_GetStaticServiceAsRepair(HLERequestContext& ctx);
- void Handle_GetStaticServiceAsServiceManager(HLERequestContext& ctx);
- void Handle_SetupStandardSteadyClockCore(HLERequestContext& ctx);
- void Handle_SetupStandardLocalSystemClockCore(HLERequestContext& ctx);
- void Handle_SetupStandardNetworkSystemClockCore(HLERequestContext& ctx);
- void Handle_SetupStandardUserSystemClockCore(HLERequestContext& ctx);
- void Handle_SetupTimeZoneServiceCore(HLERequestContext& ctx);
- void Handle_SetupEphemeralNetworkSystemClockCore(HLERequestContext& ctx);
- void Handle_GetStandardLocalClockOperationEvent(HLERequestContext& ctx);
- void Handle_GetStandardNetworkClockOperationEventForServiceManager(HLERequestContext& ctx);
- void Handle_GetEphemeralNetworkClockOperationEventForServiceManager(HLERequestContext& ctx);
- void Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent(HLERequestContext& ctx);
- void Handle_SetStandardSteadyClockBaseTime(HLERequestContext& ctx);
- void Handle_GetClosestAlarmUpdatedEvent(HLERequestContext& ctx);
- void Handle_CheckAndSignalAlarms(HLERequestContext& ctx);
- void Handle_GetClosestAlarmInfo(HLERequestContext& ctx);
-
Core::System& m_system;
std::shared_ptr<TimeManager> m_time;
ServerManager& m_server_manager;
diff --git a/src/core/hle/service/psc/time/static.cpp b/src/core/hle/service/psc/time/static.cpp
index 6f8cf3f88..3ca3311af 100644
--- a/src/core/hle/service/psc/time/static.cpp
+++ b/src/core/hle/service/psc/time/static.cpp
@@ -1,9 +1,11 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include "common/scope_exit.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/k_shared_memory.h"
+#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/psc/time/clocks/ephemeral_network_system_clock_core.h"
#include "core/hle/service/psc/time/clocks/standard_local_system_clock_core.h"
#include "core/hle/service/psc/time/clocks/standard_network_system_clock_core.h"
@@ -39,358 +41,122 @@ StaticService::StaticService(Core::System& system_, StaticServiceSetupInfo setup
m_time->m_shared_memory} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, &StaticService::Handle_GetStandardUserSystemClock, "GetStandardUserSystemClock"},
- {1, &StaticService::Handle_GetStandardNetworkSystemClock, "GetStandardNetworkSystemClock"},
- {2, &StaticService::Handle_GetStandardSteadyClock, "GetStandardSteadyClock"},
- {3, &StaticService::Handle_GetTimeZoneService, "GetTimeZoneService"},
- {4, &StaticService::Handle_GetStandardLocalSystemClock, "GetStandardLocalSystemClock"},
- {5, &StaticService::Handle_GetEphemeralNetworkSystemClock, "GetEphemeralNetworkSystemClock"},
- {20, &StaticService::Handle_GetSharedMemoryNativeHandle, "GetSharedMemoryNativeHandle"},
- {50, &StaticService::Handle_SetStandardSteadyClockInternalOffset, "SetStandardSteadyClockInternalOffset"},
- {51, &StaticService::Handle_GetStandardSteadyClockRtcValue, "GetStandardSteadyClockRtcValue"},
- {100, &StaticService::Handle_IsStandardUserSystemClockAutomaticCorrectionEnabled, "IsStandardUserSystemClockAutomaticCorrectionEnabled"},
- {101, &StaticService::Handle_SetStandardUserSystemClockAutomaticCorrectionEnabled, "SetStandardUserSystemClockAutomaticCorrectionEnabled"},
- {102, &StaticService::Handle_GetStandardUserSystemClockInitialYear, "GetStandardUserSystemClockInitialYear"},
- {200, &StaticService::Handle_IsStandardNetworkSystemClockAccuracySufficient, "IsStandardNetworkSystemClockAccuracySufficient"},
- {201, &StaticService::Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedTime, "GetStandardUserSystemClockAutomaticCorrectionUpdatedTime"},
- {300, &StaticService::Handle_CalculateMonotonicSystemClockBaseTimePoint, "CalculateMonotonicSystemClockBaseTimePoint"},
- {400, &StaticService::Handle_GetClockSnapshot, "GetClockSnapshot"},
- {401, &StaticService::Handle_GetClockSnapshotFromSystemClockContext, "GetClockSnapshotFromSystemClockContext"},
- {500, &StaticService::Handle_CalculateStandardUserSystemClockDifferenceByUser, "CalculateStandardUserSystemClockDifferenceByUser"},
- {501, &StaticService::Handle_CalculateSpanBetween, "CalculateSpanBetween"},
+ {0, D<&StaticService::GetStandardUserSystemClock>, "GetStandardUserSystemClock"},
+ {1, D<&StaticService::GetStandardNetworkSystemClock>, "GetStandardNetworkSystemClock"},
+ {2, D<&StaticService::GetStandardSteadyClock>, "GetStandardSteadyClock"},
+ {3, D<&StaticService::GetTimeZoneService>, "GetTimeZoneService"},
+ {4, D<&StaticService::GetStandardLocalSystemClock>, "GetStandardLocalSystemClock"},
+ {5, D<&StaticService::GetEphemeralNetworkSystemClock>, "GetEphemeralNetworkSystemClock"},
+ {20, D<&StaticService::GetSharedMemoryNativeHandle>, "GetSharedMemoryNativeHandle"},
+ {50, D<&StaticService::SetStandardSteadyClockInternalOffset>, "SetStandardSteadyClockInternalOffset"},
+ {51, D<&StaticService::GetStandardSteadyClockRtcValue>, "GetStandardSteadyClockRtcValue"},
+ {100, D<&StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled>, "IsStandardUserSystemClockAutomaticCorrectionEnabled"},
+ {101, D<&StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled>, "SetStandardUserSystemClockAutomaticCorrectionEnabled"},
+ {102, D<&StaticService::GetStandardUserSystemClockInitialYear>, "GetStandardUserSystemClockInitialYear"},
+ {200, D<&StaticService::IsStandardNetworkSystemClockAccuracySufficient>, "IsStandardNetworkSystemClockAccuracySufficient"},
+ {201, D<&StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime>, "GetStandardUserSystemClockAutomaticCorrectionUpdatedTime"},
+ {300, D<&StaticService::CalculateMonotonicSystemClockBaseTimePoint>, "CalculateMonotonicSystemClockBaseTimePoint"},
+ {400, D<&StaticService::GetClockSnapshot>, "GetClockSnapshot"},
+ {401, D<&StaticService::GetClockSnapshotFromSystemClockContext>, "GetClockSnapshotFromSystemClockContext"},
+ {500, D<&StaticService::CalculateStandardUserSystemClockDifferenceByUser>, "CalculateStandardUserSystemClockDifferenceByUser"},
+ {501, D<&StaticService::CalculateSpanBetween>, "CalculateSpanBetween"},
};
// clang-format on
RegisterHandlers(functions);
}
-Result StaticService::GetClockSnapshotImpl(ClockSnapshot& out_snapshot,
- SystemClockContext& user_context,
- SystemClockContext& network_context, TimeType type) {
- out_snapshot.user_context = user_context;
- out_snapshot.network_context = network_context;
-
- R_TRY(
- m_time->m_standard_steady_clock.GetCurrentTimePoint(out_snapshot.steady_clock_time_point));
-
- out_snapshot.is_automatic_correction_enabled = m_user_system_clock.GetAutomaticCorrection();
-
- R_TRY(m_time_zone.GetLocationName(out_snapshot.location_name));
-
- R_TRY(GetTimeFromTimePointAndContext(
- &out_snapshot.user_time, out_snapshot.steady_clock_time_point, out_snapshot.user_context));
-
- R_TRY(m_time_zone.ToCalendarTimeWithMyRule(out_snapshot.user_calendar_time,
- out_snapshot.user_calendar_additional_time,
- out_snapshot.user_time));
-
- if (GetTimeFromTimePointAndContext(&out_snapshot.network_time,
- out_snapshot.steady_clock_time_point,
- out_snapshot.network_context) != ResultSuccess) {
- out_snapshot.network_time = 0;
- }
-
- R_TRY(m_time_zone.ToCalendarTimeWithMyRule(out_snapshot.network_calendar_time,
- out_snapshot.network_calendar_additional_time,
- out_snapshot.network_time));
- out_snapshot.type = type;
- out_snapshot.unk_CE = 0;
- R_SUCCEED();
-}
-
-void StaticService::Handle_GetStandardUserSystemClock(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- std::shared_ptr<SystemClock> service{};
- auto res = GetStandardUserSystemClock(service);
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(res);
- rb.PushIpcInterface<SystemClock>(std::move(service));
-}
-
-void StaticService::Handle_GetStandardNetworkSystemClock(HLERequestContext& ctx) {
+Result StaticService::GetStandardUserSystemClock(OutInterface<SystemClock> out_service) {
LOG_DEBUG(Service_Time, "called.");
- std::shared_ptr<SystemClock> service{};
- auto res = GetStandardNetworkSystemClock(service);
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(res);
- rb.PushIpcInterface<SystemClock>(std::move(service));
-}
-
-void StaticService::Handle_GetStandardSteadyClock(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- std::shared_ptr<SteadyClock> service{};
- auto res = GetStandardSteadyClock(service);
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(res);
- rb.PushIpcInterface(std::move(service));
-}
-
-void StaticService::Handle_GetTimeZoneService(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- std::shared_ptr<TimeZoneService> service{};
- auto res = GetTimeZoneService(service);
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(res);
- rb.PushIpcInterface(std::move(service));
-}
-
-void StaticService::Handle_GetStandardLocalSystemClock(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- std::shared_ptr<SystemClock> service{};
- auto res = GetStandardLocalSystemClock(service);
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(res);
- rb.PushIpcInterface<SystemClock>(std::move(service));
-}
-
-void StaticService::Handle_GetEphemeralNetworkSystemClock(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- std::shared_ptr<SystemClock> service{};
- auto res = GetEphemeralNetworkSystemClock(service);
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(res);
- rb.PushIpcInterface<SystemClock>(std::move(service));
-}
-
-void StaticService::Handle_GetSharedMemoryNativeHandle(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- Kernel::KSharedMemory* shared_memory{};
- auto res = GetSharedMemoryNativeHandle(&shared_memory);
-
- IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(res);
- rb.PushCopyObjects(shared_memory);
-}
-
-void StaticService::Handle_SetStandardSteadyClockInternalOffset(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(m_setup_info.can_write_steady_clock ? ResultNotImplemented : ResultPermissionDenied);
-}
-
-void StaticService::Handle_GetStandardSteadyClockRtcValue(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultNotImplemented);
-}
-
-void StaticService::Handle_IsStandardUserSystemClockAutomaticCorrectionEnabled(
- HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- bool is_enabled{};
- auto res = IsStandardUserSystemClockAutomaticCorrectionEnabled(is_enabled);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(res);
- rb.Push<bool>(is_enabled);
-}
-
-void StaticService::Handle_SetStandardUserSystemClockAutomaticCorrectionEnabled(
- HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::RequestParser rp{ctx};
- auto automatic_correction{rp.Pop<bool>()};
-
- auto res = SetStandardUserSystemClockAutomaticCorrectionEnabled(automatic_correction);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
-}
-
-void StaticService::Handle_GetStandardUserSystemClockInitialYear(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultNotImplemented);
-}
-
-void StaticService::Handle_IsStandardNetworkSystemClockAccuracySufficient(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- bool is_sufficient{};
- auto res = IsStandardNetworkSystemClockAccuracySufficient(is_sufficient);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(res);
- rb.Push<bool>(is_sufficient);
+ *out_service = std::make_shared<SystemClock>(m_system, m_user_system_clock,
+ m_setup_info.can_write_user_clock,
+ m_setup_info.can_write_uninitialized_clock);
+ R_SUCCEED();
}
-void StaticService::Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(
- HLERequestContext& ctx) {
+Result StaticService::GetStandardNetworkSystemClock(OutInterface<SystemClock> out_service) {
LOG_DEBUG(Service_Time, "called.");
- SteadyClockTimePoint time_point{};
- auto res = GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(time_point);
-
- IPC::ResponseBuilder rb{ctx, 2 + sizeof(SteadyClockTimePoint) / sizeof(u32)};
- rb.Push(res);
- rb.PushRaw<SteadyClockTimePoint>(time_point);
+ *out_service = std::make_shared<SystemClock>(m_system, m_network_system_clock,
+ m_setup_info.can_write_network_clock,
+ m_setup_info.can_write_uninitialized_clock);
+ R_SUCCEED();
}
-void StaticService::Handle_CalculateMonotonicSystemClockBaseTimePoint(HLERequestContext& ctx) {
+Result StaticService::GetStandardSteadyClock(OutInterface<SteadyClock> out_service) {
LOG_DEBUG(Service_Time, "called.");
- IPC::RequestParser rp{ctx};
- auto context{rp.PopRaw<SystemClockContext>()};
-
- s64 time{};
- auto res = CalculateMonotonicSystemClockBaseTimePoint(time, context);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(res);
- rb.Push<s64>(time);
+ *out_service =
+ std::make_shared<SteadyClock>(m_system, m_time, m_setup_info.can_write_steady_clock,
+ m_setup_info.can_write_uninitialized_clock);
+ R_SUCCEED();
}
-void StaticService::Handle_GetClockSnapshot(HLERequestContext& ctx) {
+Result StaticService::GetTimeZoneService(OutInterface<TimeZoneService> out_service) {
LOG_DEBUG(Service_Time, "called.");
- IPC::RequestParser rp{ctx};
- auto type{rp.PopEnum<TimeType>()};
-
- ClockSnapshot snapshot{};
- auto res = GetClockSnapshot(snapshot, type);
-
- ctx.WriteBuffer(snapshot);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
+ *out_service =
+ std::make_shared<TimeZoneService>(m_system, m_time->m_standard_steady_clock, m_time_zone,
+ m_setup_info.can_write_timezone_device_location);
+ R_SUCCEED();
}
-void StaticService::Handle_GetClockSnapshotFromSystemClockContext(HLERequestContext& ctx) {
+Result StaticService::GetStandardLocalSystemClock(OutInterface<SystemClock> out_service) {
LOG_DEBUG(Service_Time, "called.");
- IPC::RequestParser rp{ctx};
- auto clock_type{rp.PopEnum<TimeType>()};
- [[maybe_unused]] auto alignment{rp.Pop<u32>()};
- auto user_context{rp.PopRaw<SystemClockContext>()};
- auto network_context{rp.PopRaw<SystemClockContext>()};
-
- ClockSnapshot snapshot{};
- auto res =
- GetClockSnapshotFromSystemClockContext(snapshot, user_context, network_context, clock_type);
-
- ctx.WriteBuffer(snapshot);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
+ *out_service = std::make_shared<SystemClock>(m_system, m_local_system_clock,
+ m_setup_info.can_write_local_clock,
+ m_setup_info.can_write_uninitialized_clock);
+ R_SUCCEED();
}
-void StaticService::Handle_CalculateStandardUserSystemClockDifferenceByUser(
- HLERequestContext& ctx) {
+Result StaticService::GetEphemeralNetworkSystemClock(OutInterface<SystemClock> out_service) {
LOG_DEBUG(Service_Time, "called.");
- ClockSnapshot a{};
- ClockSnapshot b{};
-
- auto a_buffer{ctx.ReadBuffer(0)};
- auto b_buffer{ctx.ReadBuffer(1)};
-
- std::memcpy(&a, a_buffer.data(), sizeof(ClockSnapshot));
- std::memcpy(&b, b_buffer.data(), sizeof(ClockSnapshot));
-
- s64 difference{};
- auto res = CalculateStandardUserSystemClockDifferenceByUser(difference, a, b);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(res);
- rb.Push(difference);
+ *out_service = std::make_shared<SystemClock>(m_system, m_ephemeral_network_clock,
+ m_setup_info.can_write_network_clock,
+ m_setup_info.can_write_uninitialized_clock);
+ R_SUCCEED();
}
-void StaticService::Handle_CalculateSpanBetween(HLERequestContext& ctx) {
+Result StaticService::GetSharedMemoryNativeHandle(
+ OutCopyHandle<Kernel::KSharedMemory> out_shared_memory) {
LOG_DEBUG(Service_Time, "called.");
- ClockSnapshot a{};
- ClockSnapshot b{};
-
- auto a_buffer{ctx.ReadBuffer(0)};
- auto b_buffer{ctx.ReadBuffer(1)};
-
- std::memcpy(&a, a_buffer.data(), sizeof(ClockSnapshot));
- std::memcpy(&b, b_buffer.data(), sizeof(ClockSnapshot));
-
- s64 time{};
- auto res = CalculateSpanBetween(time, a, b);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(res);
- rb.Push(time);
-}
-
-// =============================== Implementations ===========================
-
-Result StaticService::GetStandardUserSystemClock(std::shared_ptr<SystemClock>& out_service) {
- out_service = std::make_shared<SystemClock>(m_system, m_user_system_clock,
- m_setup_info.can_write_user_clock,
- m_setup_info.can_write_uninitialized_clock);
+ *out_shared_memory = &m_shared_memory.GetKSharedMemory();
R_SUCCEED();
}
-Result StaticService::GetStandardNetworkSystemClock(std::shared_ptr<SystemClock>& out_service) {
- out_service = std::make_shared<SystemClock>(m_system, m_network_system_clock,
- m_setup_info.can_write_network_clock,
- m_setup_info.can_write_uninitialized_clock);
- R_SUCCEED();
-}
+Result StaticService::SetStandardSteadyClockInternalOffset(s64 offset_ns) {
+ LOG_DEBUG(Service_Time, "called. This function is not implemented!");
-Result StaticService::GetStandardSteadyClock(std::shared_ptr<SteadyClock>& out_service) {
- out_service =
- std::make_shared<SteadyClock>(m_system, m_time, m_setup_info.can_write_steady_clock,
- m_setup_info.can_write_uninitialized_clock);
- R_SUCCEED();
-}
+ R_UNLESS(m_setup_info.can_write_steady_clock, ResultPermissionDenied);
-Result StaticService::GetTimeZoneService(std::shared_ptr<TimeZoneService>& out_service) {
- out_service =
- std::make_shared<TimeZoneService>(m_system, m_time->m_standard_steady_clock, m_time_zone,
- m_setup_info.can_write_timezone_device_location);
- R_SUCCEED();
+ R_RETURN(ResultNotImplemented);
}
-Result StaticService::GetStandardLocalSystemClock(std::shared_ptr<SystemClock>& out_service) {
- out_service = std::make_shared<SystemClock>(m_system, m_local_system_clock,
- m_setup_info.can_write_local_clock,
- m_setup_info.can_write_uninitialized_clock);
- R_SUCCEED();
-}
+Result StaticService::GetStandardSteadyClockRtcValue(Out<s64> out_rtc_value) {
+ LOG_DEBUG(Service_Time, "called. This function is not implemented!");
-Result StaticService::GetEphemeralNetworkSystemClock(std::shared_ptr<SystemClock>& out_service) {
- out_service = std::make_shared<SystemClock>(m_system, m_ephemeral_network_clock,
- m_setup_info.can_write_network_clock,
- m_setup_info.can_write_uninitialized_clock);
- R_SUCCEED();
+ R_RETURN(ResultNotImplemented);
}
-Result StaticService::GetSharedMemoryNativeHandle(Kernel::KSharedMemory** out_shared_memory) {
- *out_shared_memory = &m_shared_memory.GetKSharedMemory();
- R_SUCCEED();
-}
+Result StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled(
+ Out<bool> out_is_enabled) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_is_enabled={}", *out_is_enabled); });
-Result StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled(bool& out_is_enabled) {
R_UNLESS(m_user_system_clock.IsInitialized(), ResultClockUninitialized);
- out_is_enabled = m_user_system_clock.GetAutomaticCorrection();
+ *out_is_enabled = m_user_system_clock.GetAutomaticCorrection();
+
R_SUCCEED();
}
Result StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled(
bool automatic_correction) {
+ LOG_DEBUG(Service_Time, "called. automatic_correction={}", automatic_correction);
+
R_UNLESS(m_user_system_clock.IsInitialized() && m_time->m_standard_steady_clock.IsInitialized(),
ResultClockUninitialized);
R_UNLESS(m_setup_info.can_write_user_clock, ResultPermissionDenied);
@@ -407,22 +173,35 @@ Result StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled(
R_SUCCEED();
}
-Result StaticService::IsStandardNetworkSystemClockAccuracySufficient(bool& out_is_sufficient) {
- out_is_sufficient = m_network_system_clock.IsAccuracySufficient();
+Result StaticService::GetStandardUserSystemClockInitialYear(Out<s32> out_year) {
+ LOG_DEBUG(Service_Time, "called. This function is not implemented!");
+
+ R_RETURN(ResultNotImplemented);
+}
+
+Result StaticService::IsStandardNetworkSystemClockAccuracySufficient(Out<bool> out_is_sufficient) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_is_sufficient={}", *out_is_sufficient); });
+
+ *out_is_sufficient = m_network_system_clock.IsAccuracySufficient();
+
R_SUCCEED();
}
Result StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(
- SteadyClockTimePoint& out_time_point) {
+ Out<SteadyClockTimePoint> out_time_point) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_time_point={}", *out_time_point); });
+
R_UNLESS(m_user_system_clock.IsInitialized(), ResultClockUninitialized);
- m_user_system_clock.GetTimePoint(out_time_point);
+ m_user_system_clock.GetTimePoint(*out_time_point);
R_SUCCEED();
}
-Result StaticService::CalculateMonotonicSystemClockBaseTimePoint(s64& out_time,
+Result StaticService::CalculateMonotonicSystemClockBaseTimePoint(Out<s64> out_time,
SystemClockContext& context) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. context={} out_time={}", context, *out_time); });
+
R_UNLESS(m_time->m_standard_steady_clock.IsInitialized(), ResultClockUninitialized);
SteadyClockTimePoint time_point{};
@@ -433,12 +212,16 @@ Result StaticService::CalculateMonotonicSystemClockBaseTimePoint(s64& out_time,
auto one_second_ns{
std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::seconds(1)).count()};
auto ticks{m_system.CoreTiming().GetClockTicks()};
- auto current_time{ConvertToTimeSpan(ticks).count()};
- out_time = ((context.offset + time_point.time_point) - (current_time / one_second_ns));
+ auto current_time_ns{ConvertToTimeSpan(ticks).count()};
+ *out_time = ((context.offset + time_point.time_point) - (current_time_ns / one_second_ns));
+
R_SUCCEED();
}
-Result StaticService::GetClockSnapshot(ClockSnapshot& out_snapshot, TimeType type) {
+Result StaticService::GetClockSnapshot(OutClockSnapshot out_snapshot, TimeType type) {
+ SCOPE_EXIT(
+ { LOG_DEBUG(Service_Time, "called. type={} out_snapshot={}", type, *out_snapshot); });
+
SystemClockContext user_context{};
R_TRY(m_user_system_clock.GetContext(user_context));
@@ -448,53 +231,101 @@ Result StaticService::GetClockSnapshot(ClockSnapshot& out_snapshot, TimeType typ
R_RETURN(GetClockSnapshotImpl(out_snapshot, user_context, network_context, type));
}
-Result StaticService::GetClockSnapshotFromSystemClockContext(ClockSnapshot& out_snapshot,
+Result StaticService::GetClockSnapshotFromSystemClockContext(TimeType type,
+ OutClockSnapshot out_snapshot,
SystemClockContext& user_context,
- SystemClockContext& network_context,
- TimeType type) {
+ SystemClockContext& network_context) {
+ SCOPE_EXIT({
+ LOG_DEBUG(Service_Time,
+ "called. type={} user_context={} network_context={} out_snapshot={}", type,
+ user_context, network_context, *out_snapshot);
+ });
+
R_RETURN(GetClockSnapshotImpl(out_snapshot, user_context, network_context, type));
}
-Result StaticService::CalculateStandardUserSystemClockDifferenceByUser(s64& out_time,
- ClockSnapshot& a,
- ClockSnapshot& b) {
+Result StaticService::CalculateStandardUserSystemClockDifferenceByUser(Out<s64> out_difference,
+ InClockSnapshot a,
+ InClockSnapshot b) {
+ SCOPE_EXIT({
+ LOG_DEBUG(Service_Time, "called. a={} b={} out_difference={}", *a, *b, *out_difference);
+ });
+
auto diff_s =
- std::chrono::seconds(b.user_context.offset) - std::chrono::seconds(a.user_context.offset);
+ std::chrono::seconds(b->user_context.offset) - std::chrono::seconds(a->user_context.offset);
- if (a.user_context == b.user_context ||
- !a.user_context.steady_time_point.IdMatches(b.user_context.steady_time_point)) {
- out_time = 0;
+ if (a->user_context == b->user_context ||
+ !a->user_context.steady_time_point.IdMatches(b->user_context.steady_time_point)) {
+ *out_difference = 0;
R_SUCCEED();
}
- if (!a.is_automatic_correction_enabled || !b.is_automatic_correction_enabled) {
- out_time = std::chrono::duration_cast<std::chrono::nanoseconds>(diff_s).count();
+ if (!a->is_automatic_correction_enabled || !b->is_automatic_correction_enabled) {
+ *out_difference = std::chrono::duration_cast<std::chrono::nanoseconds>(diff_s).count();
R_SUCCEED();
}
- if (a.network_context.steady_time_point.IdMatches(a.steady_clock_time_point) ||
- b.network_context.steady_time_point.IdMatches(b.steady_clock_time_point)) {
- out_time = 0;
+ if (a->network_context.steady_time_point.IdMatches(a->steady_clock_time_point) ||
+ b->network_context.steady_time_point.IdMatches(b->steady_clock_time_point)) {
+ *out_difference = 0;
R_SUCCEED();
}
- out_time = std::chrono::duration_cast<std::chrono::nanoseconds>(diff_s).count();
+ *out_difference = std::chrono::duration_cast<std::chrono::nanoseconds>(diff_s).count();
R_SUCCEED();
}
-Result StaticService::CalculateSpanBetween(s64& out_time, ClockSnapshot& a, ClockSnapshot& b) {
+Result StaticService::CalculateSpanBetween(Out<s64> out_time, InClockSnapshot a,
+ InClockSnapshot b) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. a={} b={} out_time={}", *a, *b, *out_time); });
+
s64 time_s{};
auto res =
- GetSpanBetweenTimePoints(&time_s, a.steady_clock_time_point, b.steady_clock_time_point);
+ GetSpanBetweenTimePoints(&time_s, a->steady_clock_time_point, b->steady_clock_time_point);
if (res != ResultSuccess) {
- R_UNLESS(a.network_time != 0 && b.network_time != 0, ResultTimeNotFound);
- time_s = b.network_time - a.network_time;
+ R_UNLESS(a->network_time != 0 && b->network_time != 0, ResultTimeNotFound);
+ time_s = b->network_time - a->network_time;
}
- out_time =
+ *out_time =
std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::seconds(time_s)).count();
R_SUCCEED();
}
+Result StaticService::GetClockSnapshotImpl(OutClockSnapshot out_snapshot,
+ SystemClockContext& user_context,
+ SystemClockContext& network_context, TimeType type) {
+ out_snapshot->user_context = user_context;
+ out_snapshot->network_context = network_context;
+
+ R_TRY(
+ m_time->m_standard_steady_clock.GetCurrentTimePoint(out_snapshot->steady_clock_time_point));
+
+ out_snapshot->is_automatic_correction_enabled = m_user_system_clock.GetAutomaticCorrection();
+
+ R_TRY(m_time_zone.GetLocationName(out_snapshot->location_name));
+
+ R_TRY(GetTimeFromTimePointAndContext(&out_snapshot->user_time,
+ out_snapshot->steady_clock_time_point,
+ out_snapshot->user_context));
+
+ R_TRY(m_time_zone.ToCalendarTimeWithMyRule(out_snapshot->user_calendar_time,
+ out_snapshot->user_calendar_additional_time,
+ out_snapshot->user_time));
+
+ if (GetTimeFromTimePointAndContext(&out_snapshot->network_time,
+ out_snapshot->steady_clock_time_point,
+ out_snapshot->network_context) != ResultSuccess) {
+ out_snapshot->network_time = 0;
+ }
+
+ R_TRY(m_time_zone.ToCalendarTimeWithMyRule(out_snapshot->network_calendar_time,
+ out_snapshot->network_calendar_additional_time,
+ out_snapshot->network_time));
+ out_snapshot->type = type;
+ out_snapshot->unk_CE = 0;
+ R_SUCCEED();
+}
+
} // namespace Service::PSC::Time
diff --git a/src/core/hle/service/psc/time/static.h b/src/core/hle/service/psc/time/static.h
index 498cd5ab5..120bab259 100644
--- a/src/core/hle/service/psc/time/static.h
+++ b/src/core/hle/service/psc/time/static.h
@@ -3,6 +3,7 @@
#pragma once
+#include "core/hle/service/cmif_types.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/psc/time/common.h"
#include "core/hle/service/server_manager.h"
@@ -29,58 +30,44 @@ class EphemeralNetworkSystemClockCore;
class SharedMemory;
class StaticService final : public ServiceFramework<StaticService> {
+ using InClockSnapshot = InLargeData<ClockSnapshot, BufferAttr_HipcPointer>;
+ using OutClockSnapshot = OutLargeData<ClockSnapshot, BufferAttr_HipcPointer>;
+
public:
explicit StaticService(Core::System& system, StaticServiceSetupInfo setup_info,
std::shared_ptr<TimeManager> time, const char* name);
~StaticService() override = default;
- Result GetStandardUserSystemClock(std::shared_ptr<SystemClock>& out_service);
- Result GetStandardNetworkSystemClock(std::shared_ptr<SystemClock>& out_service);
- Result GetStandardSteadyClock(std::shared_ptr<SteadyClock>& out_service);
- Result GetTimeZoneService(std::shared_ptr<TimeZoneService>& out_service);
- Result GetStandardLocalSystemClock(std::shared_ptr<SystemClock>& out_service);
- Result GetEphemeralNetworkSystemClock(std::shared_ptr<SystemClock>& out_service);
- Result GetSharedMemoryNativeHandle(Kernel::KSharedMemory** out_shared_memory);
- Result IsStandardUserSystemClockAutomaticCorrectionEnabled(bool& out_is_enabled);
+ Result GetStandardUserSystemClock(OutInterface<SystemClock> out_service);
+ Result GetStandardNetworkSystemClock(OutInterface<SystemClock> out_service);
+ Result GetStandardSteadyClock(OutInterface<SteadyClock> out_service);
+ Result GetTimeZoneService(OutInterface<TimeZoneService> out_service);
+ Result GetStandardLocalSystemClock(OutInterface<SystemClock> out_service);
+ Result GetEphemeralNetworkSystemClock(OutInterface<SystemClock> out_service);
+ Result GetSharedMemoryNativeHandle(OutCopyHandle<Kernel::KSharedMemory> out_shared_memory);
+ Result SetStandardSteadyClockInternalOffset(s64 offset_ns);
+ Result GetStandardSteadyClockRtcValue(Out<s64> out_rtc_value);
+ Result IsStandardUserSystemClockAutomaticCorrectionEnabled(Out<bool> out_is_enabled);
Result SetStandardUserSystemClockAutomaticCorrectionEnabled(bool automatic_correction);
- Result IsStandardNetworkSystemClockAccuracySufficient(bool& out_is_sufficient);
+ Result GetStandardUserSystemClockInitialYear(Out<s32> out_year);
+ Result IsStandardNetworkSystemClockAccuracySufficient(Out<bool> out_is_sufficient);
Result GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(
- SteadyClockTimePoint& out_time_point);
- Result CalculateMonotonicSystemClockBaseTimePoint(s64& out_time, SystemClockContext& context);
- Result GetClockSnapshot(ClockSnapshot& out_snapshot, TimeType type);
- Result GetClockSnapshotFromSystemClockContext(ClockSnapshot& out_snapshot,
+ Out<SteadyClockTimePoint> out_time_point);
+ Result CalculateMonotonicSystemClockBaseTimePoint(Out<s64> out_time,
+ SystemClockContext& context);
+ Result GetClockSnapshot(OutClockSnapshot out_snapshot, TimeType type);
+ Result GetClockSnapshotFromSystemClockContext(TimeType type, OutClockSnapshot out_snapshot,
SystemClockContext& user_context,
- SystemClockContext& network_context,
- TimeType type);
- Result CalculateStandardUserSystemClockDifferenceByUser(s64& out_time, ClockSnapshot& a,
- ClockSnapshot& b);
- Result CalculateSpanBetween(s64& out_time, ClockSnapshot& a, ClockSnapshot& b);
+ SystemClockContext& network_context);
+ Result CalculateStandardUserSystemClockDifferenceByUser(Out<s64> out_difference,
+ InClockSnapshot a, InClockSnapshot b);
+ Result CalculateSpanBetween(Out<s64> out_time, InClockSnapshot a, InClockSnapshot b);
private:
- Result GetClockSnapshotImpl(ClockSnapshot& out_snapshot, SystemClockContext& user_context,
+ Result GetClockSnapshotImpl(OutClockSnapshot out_snapshot, SystemClockContext& user_context,
SystemClockContext& network_context, TimeType type);
- void Handle_GetStandardUserSystemClock(HLERequestContext& ctx);
- void Handle_GetStandardNetworkSystemClock(HLERequestContext& ctx);
- void Handle_GetStandardSteadyClock(HLERequestContext& ctx);
- void Handle_GetTimeZoneService(HLERequestContext& ctx);
- void Handle_GetStandardLocalSystemClock(HLERequestContext& ctx);
- void Handle_GetEphemeralNetworkSystemClock(HLERequestContext& ctx);
- void Handle_GetSharedMemoryNativeHandle(HLERequestContext& ctx);
- void Handle_SetStandardSteadyClockInternalOffset(HLERequestContext& ctx);
- void Handle_GetStandardSteadyClockRtcValue(HLERequestContext& ctx);
- void Handle_IsStandardUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx);
- void Handle_SetStandardUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx);
- void Handle_GetStandardUserSystemClockInitialYear(HLERequestContext& ctx);
- void Handle_IsStandardNetworkSystemClockAccuracySufficient(HLERequestContext& ctx);
- void Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext& ctx);
- void Handle_CalculateMonotonicSystemClockBaseTimePoint(HLERequestContext& ctx);
- void Handle_GetClockSnapshot(HLERequestContext& ctx);
- void Handle_GetClockSnapshotFromSystemClockContext(HLERequestContext& ctx);
- void Handle_CalculateStandardUserSystemClockDifferenceByUser(HLERequestContext& ctx);
- void Handle_CalculateSpanBetween(HLERequestContext& ctx);
-
Core::System& m_system;
StaticServiceSetupInfo m_setup_info;
std::shared_ptr<TimeManager> m_time;
diff --git a/src/core/hle/service/psc/time/steady_clock.cpp b/src/core/hle/service/psc/time/steady_clock.cpp
index 1ed5c7679..948610a2b 100644
--- a/src/core/hle/service/psc/time/steady_clock.cpp
+++ b/src/core/hle/service/psc/time/steady_clock.cpp
@@ -1,7 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include "common/scope_exit.h"
#include "core/core.h"
+#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/psc/time/steady_clock.h"
namespace Service::PSC::Time {
@@ -14,114 +16,40 @@ SteadyClock::SteadyClock(Core::System& system_, std::shared_ptr<TimeManager> man
can_write_uninitialized_clock} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, &SteadyClock::Handle_GetCurrentTimePoint, "GetCurrentTimePoint"},
- {2, &SteadyClock::Handle_GetTestOffset, "GetTestOffset"},
- {3, &SteadyClock::Handle_SetTestOffset, "SetTestOffset"},
- {100, &SteadyClock::Handle_GetRtcValue, "GetRtcValue"},
- {101, &SteadyClock::Handle_IsRtcResetDetected, "IsRtcResetDetected"},
- {102, &SteadyClock::Handle_GetSetupResultValue, "GetSetupResultValue"},
- {200, &SteadyClock::Handle_GetInternalOffset, "GetInternalOffset"},
+ {0, D<&SteadyClock::GetCurrentTimePoint>, "GetCurrentTimePoint"},
+ {2, D<&SteadyClock::GetTestOffset>, "GetTestOffset"},
+ {3, D<&SteadyClock::SetTestOffset>, "SetTestOffset"},
+ {100, D<&SteadyClock::GetRtcValue>, "GetRtcValue"},
+ {101, D<&SteadyClock::IsRtcResetDetected>, "IsRtcResetDetected"},
+ {102, D<&SteadyClock::GetSetupResultValue>, "GetSetupResultValue"},
+ {200, D<&SteadyClock::GetInternalOffset>, "GetInternalOffset"},
};
// clang-format on
RegisterHandlers(functions);
}
-void SteadyClock::Handle_GetCurrentTimePoint(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
+Result SteadyClock::GetCurrentTimePoint(Out<SteadyClockTimePoint> out_time_point) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_time_point={}", *out_time_point); });
- SteadyClockTimePoint time_point{};
- auto res = GetCurrentTimePoint(time_point);
-
- IPC::ResponseBuilder rb{ctx, 2 + sizeof(SteadyClockTimePoint) / sizeof(u32)};
- rb.Push(res);
- rb.PushRaw<SteadyClockTimePoint>(time_point);
-}
-
-void SteadyClock::Handle_GetTestOffset(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- s64 test_offset{};
- auto res = GetTestOffset(test_offset);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(res);
- rb.Push(test_offset);
-}
-
-void SteadyClock::Handle_SetTestOffset(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::RequestParser rp{ctx};
- auto test_offset{rp.Pop<s64>()};
-
- auto res = SetTestOffset(test_offset);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
-}
-
-void SteadyClock::Handle_GetRtcValue(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- s64 rtc_value{};
- auto res = GetRtcValue(rtc_value);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(res);
- rb.Push(rtc_value);
-}
-
-void SteadyClock::Handle_IsRtcResetDetected(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- bool reset_detected{false};
- auto res = IsRtcResetDetected(reset_detected);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(res);
- rb.Push(reset_detected);
-}
-
-void SteadyClock::Handle_GetSetupResultValue(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- Result result_value{ResultSuccess};
- auto res = GetSetupResultValue(result_value);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(res);
- rb.Push(result_value);
-}
-
-void SteadyClock::Handle_GetInternalOffset(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- s64 internal_offset{};
- auto res = GetInternalOffset(internal_offset);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(res);
- rb.Push(internal_offset);
-}
-
-// =============================== Implementations ===========================
-
-Result SteadyClock::GetCurrentTimePoint(SteadyClockTimePoint& out_time_point) {
R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(),
ResultClockUninitialized);
- R_RETURN(m_clock_core.GetCurrentTimePoint(out_time_point));
+ R_RETURN(m_clock_core.GetCurrentTimePoint(*out_time_point));
}
-Result SteadyClock::GetTestOffset(s64& out_test_offset) {
+Result SteadyClock::GetTestOffset(Out<s64> out_test_offset) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_test_offset={}", *out_test_offset); });
+
R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(),
ResultClockUninitialized);
- out_test_offset = m_clock_core.GetTestOffset();
+ *out_test_offset = m_clock_core.GetTestOffset();
R_SUCCEED();
}
Result SteadyClock::SetTestOffset(s64 test_offset) {
+ LOG_DEBUG(Service_Time, "called. test_offset={}", test_offset);
+
R_UNLESS(m_can_write_steady_clock, ResultPermissionDenied);
R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(),
ResultClockUninitialized);
@@ -130,34 +58,43 @@ Result SteadyClock::SetTestOffset(s64 test_offset) {
R_SUCCEED();
}
-Result SteadyClock::GetRtcValue(s64& out_rtc_value) {
+Result SteadyClock::GetRtcValue(Out<s64> out_rtc_value) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_rtc_value={}", *out_rtc_value); });
+
R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(),
ResultClockUninitialized);
- R_RETURN(m_clock_core.GetRtcValue(out_rtc_value));
+ R_RETURN(m_clock_core.GetRtcValue(*out_rtc_value));
}
-Result SteadyClock::IsRtcResetDetected(bool& out_is_detected) {
+Result SteadyClock::IsRtcResetDetected(Out<bool> out_is_detected) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_is_detected={}", *out_is_detected); });
+
R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(),
ResultClockUninitialized);
- out_is_detected = m_clock_core.IsResetDetected();
+ *out_is_detected = m_clock_core.IsResetDetected();
R_SUCCEED();
}
-Result SteadyClock::GetSetupResultValue(Result& out_result) {
+Result SteadyClock::GetSetupResultValue(Out<Result> out_result) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_result=0x{:X}", out_result->raw); });
+
R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(),
ResultClockUninitialized);
- out_result = m_clock_core.GetSetupResultValue();
+ *out_result = m_clock_core.GetSetupResultValue();
R_SUCCEED();
}
-Result SteadyClock::GetInternalOffset(s64& out_internal_offset) {
+Result SteadyClock::GetInternalOffset(Out<s64> out_internal_offset) {
+ SCOPE_EXIT(
+ { LOG_DEBUG(Service_Time, "called. out_internal_offset={}", *out_internal_offset); });
+
R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(),
ResultClockUninitialized);
- out_internal_offset = m_clock_core.GetInternalOffset();
+ *out_internal_offset = m_clock_core.GetInternalOffset();
R_SUCCEED();
}
diff --git a/src/core/hle/service/psc/time/steady_clock.h b/src/core/hle/service/psc/time/steady_clock.h
index 115e9b138..025d758a6 100644
--- a/src/core/hle/service/psc/time/steady_clock.h
+++ b/src/core/hle/service/psc/time/steady_clock.h
@@ -3,6 +3,7 @@
#pragma once
+#include "core/hle/service/cmif_types.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/psc/time/common.h"
#include "core/hle/service/psc/time/manager.h"
@@ -22,23 +23,15 @@ public:
~SteadyClock() override = default;
- Result GetCurrentTimePoint(SteadyClockTimePoint& out_time_point);
- Result GetTestOffset(s64& out_test_offset);
+ Result GetCurrentTimePoint(Out<SteadyClockTimePoint> out_time_point);
+ Result GetTestOffset(Out<s64> out_test_offset);
Result SetTestOffset(s64 test_offset);
- Result GetRtcValue(s64& out_rtc_value);
- Result IsRtcResetDetected(bool& out_is_detected);
- Result GetSetupResultValue(Result& out_result);
- Result GetInternalOffset(s64& out_internal_offset);
+ Result GetRtcValue(Out<s64> out_rtc_value);
+ Result IsRtcResetDetected(Out<bool> out_is_detected);
+ Result GetSetupResultValue(Out<Result> out_result);
+ Result GetInternalOffset(Out<s64> out_internal_offset);
private:
- void Handle_GetCurrentTimePoint(HLERequestContext& ctx);
- void Handle_GetTestOffset(HLERequestContext& ctx);
- void Handle_SetTestOffset(HLERequestContext& ctx);
- void Handle_GetRtcValue(HLERequestContext& ctx);
- void Handle_IsRtcResetDetected(HLERequestContext& ctx);
- void Handle_GetSetupResultValue(HLERequestContext& ctx);
- void Handle_GetInternalOffset(HLERequestContext& ctx);
-
Core::System& m_system;
StandardSteadyClockCore& m_clock_core;
diff --git a/src/core/hle/service/psc/time/system_clock.cpp b/src/core/hle/service/psc/time/system_clock.cpp
index 13d2f1d11..0695502d5 100644
--- a/src/core/hle/service/psc/time/system_clock.cpp
+++ b/src/core/hle/service/psc/time/system_clock.cpp
@@ -1,7 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include "common/scope_exit.h"
#include "core/core.h"
+#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/psc/time/system_clock.h"
namespace Service::PSC::Time {
@@ -13,83 +15,28 @@ SystemClock::SystemClock(Core::System& system_, SystemClockCore& clock_core, boo
can_write_uninitialized_clock} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, &SystemClock::Handle_GetCurrentTime, "GetCurrentTime"},
- {1, &SystemClock::Handle_SetCurrentTime, "SetCurrentTime"},
- {2, &SystemClock::Handle_GetSystemClockContext, "GetSystemClockContext"},
- {3, &SystemClock::Handle_SetSystemClockContext, "SetSystemClockContext"},
- {4, &SystemClock::Handle_GetOperationEventReadableHandle, "GetOperationEventReadableHandle"},
+ {0, D<&SystemClock::GetCurrentTime>, "GetCurrentTime"},
+ {1, D<&SystemClock::SetCurrentTime>, "SetCurrentTime"},
+ {2, D<&SystemClock::GetSystemClockContext>, "GetSystemClockContext"},
+ {3, D<&SystemClock::SetSystemClockContext>, "SetSystemClockContext"},
+ {4, D<&SystemClock::GetOperationEventReadableHandle>, "GetOperationEventReadableHandle"},
};
// clang-format on
RegisterHandlers(functions);
}
-void SystemClock::Handle_GetCurrentTime(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- s64 time{};
- auto res = GetCurrentTime(time);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(res);
- rb.Push<s64>(time);
-}
-
-void SystemClock::Handle_SetCurrentTime(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::RequestParser rp{ctx};
- auto time{rp.Pop<s64>()};
-
- auto res = SetCurrentTime(time);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
-}
-
-void SystemClock::Handle_GetSystemClockContext(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- SystemClockContext context{};
- auto res = GetSystemClockContext(context);
-
- IPC::ResponseBuilder rb{ctx, 2 + sizeof(SystemClockContext) / sizeof(u32)};
- rb.Push(res);
- rb.PushRaw<SystemClockContext>(context);
-}
-
-void SystemClock::Handle_SetSystemClockContext(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::RequestParser rp{ctx};
- auto context{rp.PopRaw<SystemClockContext>()};
-
- auto res = SetSystemClockContext(context);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
-}
-
-void SystemClock::Handle_GetOperationEventReadableHandle(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- Kernel::KEvent* event{};
- auto res = GetOperationEventReadableHandle(&event);
+Result SystemClock::GetCurrentTime(Out<s64> out_time) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_time={}", *out_time); });
- IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(res);
- rb.PushCopyObjects(event->GetReadableEvent());
-}
-
-// =============================== Implementations ===========================
-
-Result SystemClock::GetCurrentTime(s64& out_time) {
R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(),
ResultClockUninitialized);
- R_RETURN(m_clock_core.GetCurrentTime(&out_time));
+ R_RETURN(m_clock_core.GetCurrentTime(out_time.Get()));
}
Result SystemClock::SetCurrentTime(s64 time) {
+ LOG_DEBUG(Service_Time, "called. time={}", time);
+
R_UNLESS(m_can_write_clock, ResultPermissionDenied);
R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(),
ResultClockUninitialized);
@@ -97,14 +44,18 @@ Result SystemClock::SetCurrentTime(s64 time) {
R_RETURN(m_clock_core.SetCurrentTime(time));
}
-Result SystemClock::GetSystemClockContext(SystemClockContext& out_context) {
+Result SystemClock::GetSystemClockContext(Out<SystemClockContext> out_context) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_context={}", *out_context); });
+
R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(),
ResultClockUninitialized);
- R_RETURN(m_clock_core.GetContext(out_context));
+ R_RETURN(m_clock_core.GetContext(*out_context));
}
Result SystemClock::SetSystemClockContext(SystemClockContext& context) {
+ LOG_DEBUG(Service_Time, "called. context={}", context);
+
R_UNLESS(m_can_write_clock, ResultPermissionDenied);
R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(),
ResultClockUninitialized);
@@ -112,7 +63,10 @@ Result SystemClock::SetSystemClockContext(SystemClockContext& context) {
R_RETURN(m_clock_core.SetContextAndWrite(context));
}
-Result SystemClock::GetOperationEventReadableHandle(Kernel::KEvent** out_event) {
+Result SystemClock::GetOperationEventReadableHandle(
+ OutCopyHandle<Kernel::KReadableEvent> out_event) {
+ LOG_DEBUG(Service_Time, "called.");
+
if (!m_operation_event) {
m_operation_event = std::make_unique<OperationEvent>(m_system);
R_UNLESS(m_operation_event != nullptr, ResultFailed);
@@ -120,7 +74,7 @@ Result SystemClock::GetOperationEventReadableHandle(Kernel::KEvent** out_event)
m_clock_core.LinkOperationEvent(*m_operation_event);
}
- *out_event = m_operation_event->m_event;
+ *out_event = &m_operation_event->m_event->GetReadableEvent();
R_SUCCEED();
}
diff --git a/src/core/hle/service/psc/time/system_clock.h b/src/core/hle/service/psc/time/system_clock.h
index f30027e7b..b40d73595 100644
--- a/src/core/hle/service/psc/time/system_clock.h
+++ b/src/core/hle/service/psc/time/system_clock.h
@@ -3,6 +3,7 @@
#pragma once
+#include "core/hle/service/cmif_types.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/psc/time/common.h"
#include "core/hle/service/psc/time/manager.h"
@@ -22,19 +23,13 @@ public:
~SystemClock() override = default;
- Result GetCurrentTime(s64& out_time);
+ Result GetCurrentTime(Out<s64> out_time);
Result SetCurrentTime(s64 time);
- Result GetSystemClockContext(SystemClockContext& out_context);
+ Result GetSystemClockContext(Out<SystemClockContext> out_context);
Result SetSystemClockContext(SystemClockContext& context);
- Result GetOperationEventReadableHandle(Kernel::KEvent** out_event);
+ Result GetOperationEventReadableHandle(OutCopyHandle<Kernel::KReadableEvent> out_event);
private:
- void Handle_GetCurrentTime(HLERequestContext& ctx);
- void Handle_SetCurrentTime(HLERequestContext& ctx);
- void Handle_GetSystemClockContext(HLERequestContext& ctx);
- void Handle_SetSystemClockContext(HLERequestContext& ctx);
- void Handle_GetOperationEventReadableHandle(HLERequestContext& ctx);
-
Core::System& m_system;
SystemClockCore& m_clock_core;
diff --git a/src/core/hle/service/psc/time/time_zone.cpp b/src/core/hle/service/psc/time/time_zone.cpp
index cfee8f866..82ddba42f 100644
--- a/src/core/hle/service/psc/time/time_zone.cpp
+++ b/src/core/hle/service/psc/time/time_zone.cpp
@@ -5,7 +5,7 @@
namespace Service::PSC::Time {
namespace {
-constexpr Result ValidateRule(Tz::Rule& rule) {
+constexpr Result ValidateRule(const Tz::Rule& rule) {
if (rule.typecnt > static_cast<s32>(Tz::TZ_MAX_TYPES) ||
rule.timecnt > static_cast<s32>(Tz::TZ_MAX_TIMES) ||
rule.charcnt > static_cast<s32>(Tz::TZ_MAX_CHARS)) {
@@ -26,7 +26,7 @@ constexpr Result ValidateRule(Tz::Rule& rule) {
R_SUCCEED();
}
-constexpr bool GetTimeZoneTime(s64& out_time, Tz::Rule& rule, s64 time, s32 index,
+constexpr bool GetTimeZoneTime(s64& out_time, const Tz::Rule& rule, s64 time, s32 index,
s32 index_offset) {
s32 found_idx{};
s32 expected_index{index + index_offset};
@@ -107,7 +107,7 @@ Result TimeZone::GetTimePoint(SteadyClockTimePoint& out_time_point) {
Result TimeZone::ToCalendarTime(CalendarTime& out_calendar_time,
CalendarAdditionalInfo& out_additional_info, s64 time,
- Tz::Rule& rule) {
+ const Tz::Rule& rule) {
std::scoped_lock l{m_mutex};
R_RETURN(ToCalendarTimeImpl(out_calendar_time, out_additional_info, time, rule));
}
@@ -140,8 +140,8 @@ Result TimeZone::ParseBinaryInto(Tz::Rule& out_rule, std::span<const u8> binary)
R_RETURN(ParseBinaryImpl(out_rule, binary));
}
-Result TimeZone::ToPosixTime(u32& out_count, std::span<s64, 2> out_times, u32 out_times_count,
- CalendarTime& calendar, Tz::Rule& rule) {
+Result TimeZone::ToPosixTime(u32& out_count, std::span<s64> out_times, u32 out_times_count,
+ CalendarTime& calendar, const Tz::Rule& rule) {
std::scoped_lock l{m_mutex};
auto res = ToPosixTimeImpl(out_count, out_times, out_times_count, calendar, rule, -1);
@@ -157,7 +157,7 @@ Result TimeZone::ToPosixTime(u32& out_count, std::span<s64, 2> out_times, u32 ou
R_RETURN(res);
}
-Result TimeZone::ToPosixTimeWithMyRule(u32& out_count, std::span<s64, 2> out_times,
+Result TimeZone::ToPosixTimeWithMyRule(u32& out_count, std::span<s64> out_times,
u32 out_times_count, CalendarTime& calendar) {
std::scoped_lock l{m_mutex};
@@ -183,7 +183,7 @@ Result TimeZone::ParseBinaryImpl(Tz::Rule& out_rule, std::span<const u8> binary)
Result TimeZone::ToCalendarTimeImpl(CalendarTime& out_calendar_time,
CalendarAdditionalInfo& out_additional_info, s64 time,
- Tz::Rule& rule) {
+ const Tz::Rule& rule) {
R_TRY(ValidateRule(rule));
Tz::CalendarTimeInternal calendar_internal{};
@@ -212,8 +212,8 @@ Result TimeZone::ToCalendarTimeImpl(CalendarTime& out_calendar_time,
R_SUCCEED();
}
-Result TimeZone::ToPosixTimeImpl(u32& out_count, std::span<s64, 2> out_times, u32 out_times_count,
- CalendarTime& calendar, Tz::Rule& rule, s32 is_dst) {
+Result TimeZone::ToPosixTimeImpl(u32& out_count, std::span<s64> out_times, u32 out_times_count,
+ CalendarTime& calendar, const Tz::Rule& rule, s32 is_dst) {
R_TRY(ValidateRule(rule));
calendar.month -= 1;
diff --git a/src/core/hle/service/psc/time/time_zone.h b/src/core/hle/service/psc/time/time_zone.h
index ce2acca17..6bd8f2fda 100644
--- a/src/core/hle/service/psc/time/time_zone.h
+++ b/src/core/hle/service/psc/time/time_zone.h
@@ -32,23 +32,24 @@ public:
Result GetTimePoint(SteadyClockTimePoint& out_time_point);
Result ToCalendarTime(CalendarTime& out_calendar_time,
- CalendarAdditionalInfo& out_additional_info, s64 time, Tz::Rule& rule);
+ CalendarAdditionalInfo& out_additional_info, s64 time,
+ const Tz::Rule& rule);
Result ToCalendarTimeWithMyRule(CalendarTime& calendar_time,
CalendarAdditionalInfo& calendar_additional, s64 time);
Result ParseBinary(LocationName& name, std::span<const u8> binary);
Result ParseBinaryInto(Tz::Rule& out_rule, std::span<const u8> binary);
- Result ToPosixTime(u32& out_count, std::span<s64, 2> out_times, u32 out_times_count,
- CalendarTime& calendar, Tz::Rule& rule);
- Result ToPosixTimeWithMyRule(u32& out_count, std::span<s64, 2> out_times, u32 out_times_count,
+ Result ToPosixTime(u32& out_count, std::span<s64> out_times, u32 out_times_count,
+ CalendarTime& calendar, const Tz::Rule& rule);
+ Result ToPosixTimeWithMyRule(u32& out_count, std::span<s64> out_times, u32 out_times_count,
CalendarTime& calendar);
private:
Result ParseBinaryImpl(Tz::Rule& out_rule, std::span<const u8> binary);
Result ToCalendarTimeImpl(CalendarTime& out_calendar_time,
CalendarAdditionalInfo& out_additional_info, s64 time,
- Tz::Rule& rule);
- Result ToPosixTimeImpl(u32& out_count, std::span<s64, 2> out_times, u32 out_times_count,
- CalendarTime& calendar, Tz::Rule& rule, s32 is_dst);
+ const Tz::Rule& rule);
+ Result ToPosixTimeImpl(u32& out_count, std::span<s64> out_times, u32 out_times_count,
+ CalendarTime& calendar, const Tz::Rule& rule, s32 is_dst);
bool m_initialized{};
std::recursive_mutex m_mutex;
diff --git a/src/core/hle/service/psc/time/time_zone_service.cpp b/src/core/hle/service/psc/time/time_zone_service.cpp
index e304c8387..9376a0324 100644
--- a/src/core/hle/service/psc/time/time_zone_service.cpp
+++ b/src/core/hle/service/psc/time/time_zone_service.cpp
@@ -2,7 +2,10 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <tz/tz.h>
+
+#include "common/scope_exit.h"
#include "core/core.h"
+#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/psc/time/time_zone_service.h"
namespace Service::PSC::Time {
@@ -14,276 +17,153 @@ TimeZoneService::TimeZoneService(Core::System& system_, StandardSteadyClockCore&
can_write_timezone_device_location} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, &TimeZoneService::Handle_GetDeviceLocationName, "GetDeviceLocationName"},
- {1, &TimeZoneService::Handle_SetDeviceLocationName, "SetDeviceLocationName"},
- {2, &TimeZoneService::Handle_GetTotalLocationNameCount, "GetTotalLocationNameCount"},
- {3, &TimeZoneService::Handle_LoadLocationNameList, "LoadLocationNameList"},
- {4, &TimeZoneService::Handle_LoadTimeZoneRule, "LoadTimeZoneRule"},
- {5, &TimeZoneService::Handle_GetTimeZoneRuleVersion, "GetTimeZoneRuleVersion"},
- {6, &TimeZoneService::Handle_GetDeviceLocationNameAndUpdatedTime, "GetDeviceLocationNameAndUpdatedTime"},
- {7, &TimeZoneService::Handle_SetDeviceLocationNameWithTimeZoneRule, "SetDeviceLocationNameWithTimeZoneRule"},
- {8, &TimeZoneService::Handle_ParseTimeZoneBinary, "ParseTimeZoneBinary"},
- {20, &TimeZoneService::Handle_GetDeviceLocationNameOperationEventReadableHandle, "GetDeviceLocationNameOperationEventReadableHandle"},
- {100, &TimeZoneService::Handle_ToCalendarTime, "ToCalendarTime"},
- {101, &TimeZoneService::Handle_ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"},
- {201, &TimeZoneService::Handle_ToPosixTime, "ToPosixTime"},
- {202, &TimeZoneService::Handle_ToPosixTimeWithMyRule, "ToPosixTimeWithMyRule"},
+ {0, D<&TimeZoneService::GetDeviceLocationName>, "GetDeviceLocationName"},
+ {1, D<&TimeZoneService::SetDeviceLocationName>, "SetDeviceLocationName"},
+ {2, D<&TimeZoneService::GetTotalLocationNameCount>, "GetTotalLocationNameCount"},
+ {3, D<&TimeZoneService::LoadLocationNameList>, "LoadLocationNameList"},
+ {4, D<&TimeZoneService::LoadTimeZoneRule>, "LoadTimeZoneRule"},
+ {5, D<&TimeZoneService::GetTimeZoneRuleVersion>, "GetTimeZoneRuleVersion"},
+ {6, D<&TimeZoneService::GetDeviceLocationNameAndUpdatedTime>, "GetDeviceLocationNameAndUpdatedTime"},
+ {7, D<&TimeZoneService::SetDeviceLocationNameWithTimeZoneRule>, "SetDeviceLocationNameWithTimeZoneRule"},
+ {8, D<&TimeZoneService::ParseTimeZoneBinary>, "ParseTimeZoneBinary"},
+ {20, D<&TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle>, "GetDeviceLocationNameOperationEventReadableHandle"},
+ {100, D<&TimeZoneService::ToCalendarTime>, "ToCalendarTime"},
+ {101, D<&TimeZoneService::ToCalendarTimeWithMyRule>, "ToCalendarTimeWithMyRule"},
+ {201, D<&TimeZoneService::ToPosixTime>, "ToPosixTime"},
+ {202, D<&TimeZoneService::ToPosixTimeWithMyRule>, "ToPosixTimeWithMyRule"},
};
// clang-format on
RegisterHandlers(functions);
}
-void TimeZoneService::Handle_GetDeviceLocationName(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- LocationName name{};
- auto res = GetDeviceLocationName(name);
-
- IPC::ResponseBuilder rb{ctx, 2 + sizeof(LocationName) / sizeof(u32)};
- rb.Push(res);
- rb.PushRaw<LocationName>(name);
-}
-
-void TimeZoneService::Handle_SetDeviceLocationName(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::RequestParser rp{ctx};
- [[maybe_unused]] auto name{rp.PopRaw<LocationName>()};
-
- if (!m_can_write_timezone_device_location) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultPermissionDenied);
- return;
- }
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultNotImplemented);
-}
-
-void TimeZoneService::Handle_GetTotalLocationNameCount(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- u32 count{};
- auto res = GetTotalLocationNameCount(count);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(res);
- rb.Push(count);
-}
-
-void TimeZoneService::Handle_LoadLocationNameList(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
+Result TimeZoneService::GetDeviceLocationName(Out<LocationName> out_location_name) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_location_name={}", *out_location_name); });
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultNotImplemented);
+ R_RETURN(m_time_zone.GetLocationName(*out_location_name));
}
-void TimeZoneService::Handle_LoadTimeZoneRule(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
+Result TimeZoneService::SetDeviceLocationName(LocationName& location_name) {
+ LOG_DEBUG(Service_Time, "called. This function is not implemented!");
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultNotImplemented);
+ R_UNLESS(m_can_write_timezone_device_location, ResultPermissionDenied);
+ R_RETURN(ResultNotImplemented);
}
-void TimeZoneService::Handle_GetTimeZoneRuleVersion(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- RuleVersion rule_version{};
- auto res = GetTimeZoneRuleVersion(rule_version);
+Result TimeZoneService::GetTotalLocationNameCount(Out<u32> out_count) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_count={}", *out_count); });
- IPC::ResponseBuilder rb{ctx, 2 + sizeof(RuleVersion) / sizeof(u32)};
- rb.Push(res);
- rb.PushRaw<RuleVersion>(rule_version);
+ R_RETURN(m_time_zone.GetTotalLocationCount(*out_count));
}
-void TimeZoneService::Handle_GetDeviceLocationNameAndUpdatedTime(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- LocationName name{};
- SteadyClockTimePoint time_point{};
- auto res = GetDeviceLocationNameAndUpdatedTime(time_point, name);
+Result TimeZoneService::LoadLocationNameList(
+ Out<u32> out_count, OutArray<LocationName, BufferAttr_HipcMapAlias> out_names, u32 index) {
+ LOG_DEBUG(Service_Time, "called. This function is not implemented!");
- IPC::ResponseBuilder rb{ctx, 2 + (sizeof(LocationName) / sizeof(u32)) +
- (sizeof(SteadyClockTimePoint) / sizeof(u32))};
- rb.Push(res);
- rb.PushRaw<LocationName>(name);
- rb.PushRaw<SteadyClockTimePoint>(time_point);
+ R_RETURN(ResultNotImplemented);
}
-void TimeZoneService::Handle_SetDeviceLocationNameWithTimeZoneRule(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::RequestParser rp{ctx};
- auto name{rp.PopRaw<LocationName>()};
-
- auto binary{ctx.ReadBuffer()};
- auto res = SetDeviceLocationNameWithTimeZoneRule(name, binary);
+Result TimeZoneService::LoadTimeZoneRule(OutRule out_rule, LocationName& location_name) {
+ LOG_DEBUG(Service_Time, "called. This function is not implemented!");
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
+ R_RETURN(ResultNotImplemented);
}
-void TimeZoneService::Handle_ParseTimeZoneBinary(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- auto binary{ctx.ReadBuffer()};
+Result TimeZoneService::GetTimeZoneRuleVersion(Out<RuleVersion> out_rule_version) {
+ SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_rule_version={}", *out_rule_version); });
- Tz::Rule rule{};
- auto res = ParseTimeZoneBinary(rule, binary);
-
- ctx.WriteBuffer(rule);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(res);
+ R_RETURN(m_time_zone.GetRuleVersion(*out_rule_version));
}
-void TimeZoneService::Handle_GetDeviceLocationNameOperationEventReadableHandle(
- HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
+Result TimeZoneService::GetDeviceLocationNameAndUpdatedTime(
+ Out<LocationName> out_location_name, Out<SteadyClockTimePoint> out_time_point) {
+ SCOPE_EXIT({
+ LOG_DEBUG(Service_Time, "called. out_location_name={} out_time_point={}",
+ *out_location_name, *out_time_point);
+ });
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultNotImplemented);
+ R_TRY(m_time_zone.GetLocationName(*out_location_name));
+ R_RETURN(m_time_zone.GetTimePoint(*out_time_point));
}
-void TimeZoneService::Handle_ToCalendarTime(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::RequestParser rp{ctx};
- auto time{rp.Pop<s64>()};
+Result TimeZoneService::SetDeviceLocationNameWithTimeZoneRule(
+ LocationName& location_name, InBuffer<BufferAttr_HipcAutoSelect> binary) {
+ LOG_DEBUG(Service_Time, "called. location_name={}", location_name);
- auto rule_buffer{ctx.ReadBuffer()};
- Tz::Rule rule{};
- std::memcpy(&rule, rule_buffer.data(), sizeof(Tz::Rule));
-
- CalendarTime calendar_time{};
- CalendarAdditionalInfo additional_info{};
- auto res = ToCalendarTime(calendar_time, additional_info, time, rule);
-
- IPC::ResponseBuilder rb{ctx, 2 + (sizeof(CalendarTime) / sizeof(u32)) +
- (sizeof(CalendarAdditionalInfo) / sizeof(u32))};
- rb.Push(res);
- rb.PushRaw<CalendarTime>(calendar_time);
- rb.PushRaw<CalendarAdditionalInfo>(additional_info);
-}
-
-void TimeZoneService::Handle_ToCalendarTimeWithMyRule(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::RequestParser rp{ctx};
- auto time{rp.Pop<s64>()};
+ R_UNLESS(m_can_write_timezone_device_location, ResultPermissionDenied);
+ R_TRY(m_time_zone.ParseBinary(location_name, binary));
- CalendarTime calendar_time{};
- CalendarAdditionalInfo additional_info{};
- auto res = ToCalendarTimeWithMyRule(calendar_time, additional_info, time);
+ SteadyClockTimePoint time_point{};
+ R_TRY(m_clock_core.GetCurrentTimePoint(time_point));
- IPC::ResponseBuilder rb{ctx, 2 + (sizeof(CalendarTime) / sizeof(u32)) +
- (sizeof(CalendarAdditionalInfo) / sizeof(u32))};
- rb.Push(res);
- rb.PushRaw<CalendarTime>(calendar_time);
- rb.PushRaw<CalendarAdditionalInfo>(additional_info);
+ m_time_zone.SetTimePoint(time_point);
+ R_SUCCEED();
}
-void TimeZoneService::Handle_ToPosixTime(HLERequestContext& ctx) {
+Result TimeZoneService::ParseTimeZoneBinary(OutRule out_rule,
+ InBuffer<BufferAttr_HipcAutoSelect> binary) {
LOG_DEBUG(Service_Time, "called.");
- IPC::RequestParser rp{ctx};
- auto calendar{rp.PopRaw<CalendarTime>()};
-
- auto binary{ctx.ReadBuffer()};
-
- Tz::Rule rule{};
- std::memcpy(&rule, binary.data(), sizeof(Tz::Rule));
-
- u32 count{};
- std::array<s64, 2> times{};
- u32 times_count{static_cast<u32>(ctx.GetWriteBufferSize() / sizeof(s64))};
-
- auto res = ToPosixTime(count, times, times_count, calendar, rule);
-
- ctx.WriteBuffer(times);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(res);
- rb.Push(count);
+ R_RETURN(m_time_zone.ParseBinaryInto(*out_rule, binary));
}
-void TimeZoneService::Handle_ToPosixTimeWithMyRule(HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called.");
-
- IPC::RequestParser rp{ctx};
- auto calendar{rp.PopRaw<CalendarTime>()};
+Result TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle(
+ OutCopyHandle<Kernel::KReadableEvent> out_event) {
+ LOG_DEBUG(Service_Time, "called. This function is not implemented!");
- u32 count{};
- std::array<s64, 2> times{};
- u32 times_count{static_cast<u32>(ctx.GetWriteBufferSize() / sizeof(s64))};
-
- auto res = ToPosixTimeWithMyRule(count, times, times_count, calendar);
-
- ctx.WriteBuffer(times);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(res);
- rb.Push(count);
+ R_RETURN(ResultNotImplemented);
}
-// =============================== Implementations ===========================
-
-Result TimeZoneService::GetDeviceLocationName(LocationName& out_location_name) {
- R_RETURN(m_time_zone.GetLocationName(out_location_name));
-}
+Result TimeZoneService::ToCalendarTime(Out<CalendarTime> out_calendar_time,
+ Out<CalendarAdditionalInfo> out_additional_info, s64 time,
+ InRule rule) {
+ SCOPE_EXIT({
+ LOG_DEBUG(Service_Time, "called. time={} out_calendar_time={} out_additional_info={}", time,
+ *out_calendar_time, *out_additional_info);
+ });
-Result TimeZoneService::GetTotalLocationNameCount(u32& out_count) {
- R_RETURN(m_time_zone.GetTotalLocationCount(out_count));
-}
-
-Result TimeZoneService::GetTimeZoneRuleVersion(RuleVersion& out_rule_version) {
- R_RETURN(m_time_zone.GetRuleVersion(out_rule_version));
-}
-
-Result TimeZoneService::GetDeviceLocationNameAndUpdatedTime(SteadyClockTimePoint& out_time_point,
- LocationName& location_name) {
- R_TRY(m_time_zone.GetLocationName(location_name));
- R_RETURN(m_time_zone.GetTimePoint(out_time_point));
+ R_RETURN(
+ m_time_zone.ToCalendarTime(*out_calendar_time, *out_additional_info, time, *rule.Get()));
}
-Result TimeZoneService::SetDeviceLocationNameWithTimeZoneRule(LocationName& location_name,
- std::span<const u8> binary) {
- R_UNLESS(m_can_write_timezone_device_location, ResultPermissionDenied);
- R_TRY(m_time_zone.ParseBinary(location_name, binary));
-
- SteadyClockTimePoint time_point{};
- R_TRY(m_clock_core.GetCurrentTimePoint(time_point));
+Result TimeZoneService::ToCalendarTimeWithMyRule(Out<CalendarTime> out_calendar_time,
+ Out<CalendarAdditionalInfo> out_additional_info,
+ s64 time) {
+ SCOPE_EXIT({
+ LOG_DEBUG(Service_Time, "called. time={} out_calendar_time={} out_additional_info={}", time,
+ *out_calendar_time, *out_additional_info);
+ });
- m_time_zone.SetTimePoint(time_point);
- R_SUCCEED();
+ R_RETURN(m_time_zone.ToCalendarTimeWithMyRule(*out_calendar_time, *out_additional_info, time));
}
-Result TimeZoneService::ParseTimeZoneBinary(Tz::Rule& out_rule, std::span<const u8> binary) {
- R_RETURN(m_time_zone.ParseBinaryInto(out_rule, binary));
-}
+Result TimeZoneService::ToPosixTime(Out<u32> out_count,
+ OutArray<s64, BufferAttr_HipcPointer> out_times,
+ Out<u32> out_times_count, CalendarTime& calendar_time,
+ InRule rule) {
+ SCOPE_EXIT({
+ LOG_DEBUG(Service_Time,
+ "called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} "
+ "out_times_count={}",
+ calendar_time, *out_count, out_times[0], out_times[1], *out_times_count);
+ });
-Result TimeZoneService::ToCalendarTime(CalendarTime& out_calendar_time,
- CalendarAdditionalInfo& out_additional_info, s64 time,
- Tz::Rule& rule) {
- R_RETURN(m_time_zone.ToCalendarTime(out_calendar_time, out_additional_info, time, rule));
-}
-
-Result TimeZoneService::ToCalendarTimeWithMyRule(CalendarTime& out_calendar_time,
- CalendarAdditionalInfo& out_additional_info,
- s64 time) {
- R_RETURN(m_time_zone.ToCalendarTimeWithMyRule(out_calendar_time, out_additional_info, time));
+ R_RETURN(
+ m_time_zone.ToPosixTime(*out_count, out_times, *out_times_count, calendar_time, *rule));
}
-Result TimeZoneService::ToPosixTime(u32& out_count, std::span<s64, 2> out_times,
- u32 out_times_count, CalendarTime& calendar_time,
- Tz::Rule& rule) {
- R_RETURN(m_time_zone.ToPosixTime(out_count, out_times, out_times_count, calendar_time, rule));
-}
+Result TimeZoneService::ToPosixTimeWithMyRule(Out<u32> out_count,
+ OutArray<s64, BufferAttr_HipcPointer> out_times,
+ Out<u32> out_times_count,
+ CalendarTime& calendar_time) {
+ SCOPE_EXIT({
+ LOG_DEBUG(Service_Time,
+ "called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} "
+ "out_times_count={}",
+ calendar_time, *out_count, out_times[0], out_times[1], *out_times_count);
+ });
-Result TimeZoneService::ToPosixTimeWithMyRule(u32& out_count, std::span<s64, 2> out_times,
- u32 out_times_count, CalendarTime& calendar_time) {
R_RETURN(
- m_time_zone.ToPosixTimeWithMyRule(out_count, out_times, out_times_count, calendar_time));
+ m_time_zone.ToPosixTimeWithMyRule(*out_count, out_times, *out_times_count, calendar_time));
}
} // namespace Service::PSC::Time
diff --git a/src/core/hle/service/psc/time/time_zone_service.h b/src/core/hle/service/psc/time/time_zone_service.h
index 074c1d4ae..084e3f907 100644
--- a/src/core/hle/service/psc/time/time_zone_service.h
+++ b/src/core/hle/service/psc/time/time_zone_service.h
@@ -3,6 +3,7 @@
#pragma once
+#include "core/hle/service/cmif_types.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/psc/time/common.h"
#include "core/hle/service/psc/time/manager.h"
@@ -20,45 +21,41 @@ struct Rule;
namespace Service::PSC::Time {
class TimeZoneService final : public ServiceFramework<TimeZoneService> {
+ using InRule = InLargeData<Tz::Rule, BufferAttr_HipcMapAlias>;
+ using OutRule = OutLargeData<Tz::Rule, BufferAttr_HipcMapAlias>;
+
public:
explicit TimeZoneService(Core::System& system, StandardSteadyClockCore& clock_core,
TimeZone& time_zone, bool can_write_timezone_device_location);
~TimeZoneService() override = default;
- Result GetDeviceLocationName(LocationName& out_location_name);
- Result GetTotalLocationNameCount(u32& out_count);
- Result GetTimeZoneRuleVersion(RuleVersion& out_rule_version);
- Result GetDeviceLocationNameAndUpdatedTime(SteadyClockTimePoint& out_time_point,
- LocationName& location_name);
+ Result GetDeviceLocationName(Out<LocationName> out_location_name);
+ Result SetDeviceLocationName(LocationName& location_name);
+ Result GetTotalLocationNameCount(Out<u32> out_count);
+ Result LoadLocationNameList(Out<u32> out_count,
+ OutArray<LocationName, BufferAttr_HipcMapAlias> out_names,
+ u32 index);
+ Result LoadTimeZoneRule(OutRule out_rule, LocationName& location_name);
+ Result GetTimeZoneRuleVersion(Out<RuleVersion> out_rule_version);
+ Result GetDeviceLocationNameAndUpdatedTime(Out<LocationName> location_name,
+ Out<SteadyClockTimePoint> out_time_point);
Result SetDeviceLocationNameWithTimeZoneRule(LocationName& location_name,
- std::span<const u8> binary);
- Result ParseTimeZoneBinary(Tz::Rule& out_rule, std::span<const u8> binary);
- Result ToCalendarTime(CalendarTime& out_calendar_time,
- CalendarAdditionalInfo& out_additional_info, s64 time, Tz::Rule& rule);
- Result ToCalendarTimeWithMyRule(CalendarTime& out_calendar_time,
- CalendarAdditionalInfo& out_additional_info, s64 time);
- Result ToPosixTime(u32& out_count, std::span<s64, 2> out_times, u32 out_times_count,
- CalendarTime& calendar_time, Tz::Rule& rule);
- Result ToPosixTimeWithMyRule(u32& out_count, std::span<s64, 2> out_times, u32 out_times_count,
- CalendarTime& calendar_time);
+ InBuffer<BufferAttr_HipcAutoSelect> binary);
+ Result ParseTimeZoneBinary(OutRule out_rule, InBuffer<BufferAttr_HipcAutoSelect> binary);
+ Result GetDeviceLocationNameOperationEventReadableHandle(
+ OutCopyHandle<Kernel::KReadableEvent> out_event);
+ Result ToCalendarTime(Out<CalendarTime> out_calendar_time,
+ Out<CalendarAdditionalInfo> out_additional_info, s64 time, InRule rule);
+ Result ToCalendarTimeWithMyRule(Out<CalendarTime> out_calendar_time,
+ Out<CalendarAdditionalInfo> out_additional_info, s64 time);
+ Result ToPosixTime(Out<u32> out_count, OutArray<s64, BufferAttr_HipcPointer> out_times,
+ Out<u32> out_times_count, CalendarTime& calendar_time, InRule rule);
+ Result ToPosixTimeWithMyRule(Out<u32> out_count,
+ OutArray<s64, BufferAttr_HipcPointer> out_times,
+ Out<u32> out_times_count, CalendarTime& calendar_time);
private:
- void Handle_GetDeviceLocationName(HLERequestContext& ctx);
- void Handle_SetDeviceLocationName(HLERequestContext& ctx);
- void Handle_GetTotalLocationNameCount(HLERequestContext& ctx);
- void Handle_LoadLocationNameList(HLERequestContext& ctx);
- void Handle_LoadTimeZoneRule(HLERequestContext& ctx);
- void Handle_GetTimeZoneRuleVersion(HLERequestContext& ctx);
- void Handle_GetDeviceLocationNameAndUpdatedTime(HLERequestContext& ctx);
- void Handle_SetDeviceLocationNameWithTimeZoneRule(HLERequestContext& ctx);
- void Handle_ParseTimeZoneBinary(HLERequestContext& ctx);
- void Handle_GetDeviceLocationNameOperationEventReadableHandle(HLERequestContext& ctx);
- void Handle_ToCalendarTime(HLERequestContext& ctx);
- void Handle_ToCalendarTimeWithMyRule(HLERequestContext& ctx);
- void Handle_ToPosixTime(HLERequestContext& ctx);
- void Handle_ToPosixTimeWithMyRule(HLERequestContext& ctx);
-
Core::System& m_system;
StandardSteadyClockCore& m_clock_core;
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 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include "common/settings.h"
#include "core/hle/service/set/setting_formats/system_settings.h"
namespace Service::Set {
@@ -44,7 +45,7 @@ SystemSettings DefaultSystemSettings() {
.console_sleep_plan = ConsoleSleepPlan::Sleep1Hour,
};
- settings.device_time_zone_location_name = {"UTC"};
+ settings.device_time_zone_location_name = Service::PSC::Time::LocationName{"UTC"};
settings.user_system_clock_automatic_correction_enabled = true;
settings.primary_album_storage = PrimaryAlbumStorage::SdCard;
@@ -52,6 +53,17 @@ SystemSettings DefaultSystemSettings() {
settings.chinese_traditional_input_method = ChineseTraditionalInputMethod::Unknown0;
settings.vibration_master_volume = 1.0f;
+ const auto language_code =
+ available_language_codes[static_cast<s32>(::Settings::values.language_index.GetValue())];
+ const auto key_code =
+ std::find_if(language_to_layout.cbegin(), language_to_layout.cend(),
+ [=](const auto& element) { return element.first == language_code; });
+
+ settings.keyboard_layout = KeyboardLayout::EnglishUs;
+ if (key_code != language_to_layout.end()) {
+ settings.keyboard_layout = key_code->second;
+ }
+
return settings;
}
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 {
// nn::settings::system::AudioVolume
std::array<u8, 0x8> audio_volume_type0;
std::array<u8, 0x8> audio_volume_type1;
- // nn::settings::system::AudioOutputMode
- s32 audio_output_mode_type0;
- s32 audio_output_mode_type1;
- s32 audio_output_mode_type2;
+ AudioOutputMode audio_output_mode_hdmi;
+ AudioOutputMode audio_output_mode_speaker;
+ AudioOutputMode audio_output_mode_headphone;
bool force_mute_on_headphone_removed;
INSERT_PADDING_BYTES(0x3);
s32 headphone_volume_warning_count;
@@ -224,9 +223,8 @@ struct SystemSettings {
INSERT_PADDING_BYTES(0x3);
// nn::settings::system::AudioVolume
std::array<u8, 0x8> audio_volume_type2;
- // nn::settings::system::AudioOutputMode
- s32 audio_output_mode_type3;
- s32 audio_output_mode_type4;
+ AudioOutputMode audio_output_mode_type3;
+ AudioOutputMode audio_output_mode_type4;
bool hearing_protection_safeguard_flag;
INSERT_PADDING_BYTES(0x3);
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 {
/// This is nn::settings::system::AudioOutputModeTarget
enum class AudioOutputModeTarget : u32 {
+ None,
Hdmi,
Speaker,
Headphone,
+ Type3,
+ Type4,
};
/// This is nn::settings::system::AudioVolumeTarget
@@ -367,6 +370,12 @@ struct AccountNotificationSettings {
static_assert(sizeof(AccountNotificationSettings) == 0x18,
"AccountNotificationSettings is an invalid size");
+/// This is nn::settings::factory::BatteryLot
+struct BatteryLot {
+ std::array<char, 0x18> lot_number;
+};
+static_assert(sizeof(BatteryLot) == 0x18, "BatteryLot is an invalid size");
+
/// This is nn::settings::system::EulaVersion
struct EulaVersion {
u32 version;
@@ -436,6 +445,12 @@ struct NotificationSettings {
};
static_assert(sizeof(NotificationSettings) == 0x18, "NotificationSettings is an invalid size");
+/// This is nn::settings::factory::SerialNumber
+struct SerialNumber {
+ std::array<char, 0x18> serial_number;
+};
+static_assert(sizeof(SerialNumber) == 0x18, "SerialNumber is an invalid size");
+
/// This is nn::settings::system::SleepSettings
struct SleepSettings {
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 @@
namespace Service::Set {
namespace {
-constexpr u32 SETTINGS_VERSION{1u};
+constexpr u32 SETTINGS_VERSION{2u};
constexpr auto SETTINGS_MAGIC = Common::MakeMagic('y', 'u', 'z', 'u', '_', 's', 'e', 't');
struct SettingsHeader {
u64 magic;
@@ -131,10 +131,10 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
{40, &ISystemSettingsServer::SetTvSettings, "SetTvSettings"},
{41, nullptr, "GetEdid"},
{42, nullptr, "SetEdid"},
- {43, nullptr, "GetAudioOutputMode"},
- {44, nullptr, "SetAudioOutputMode"},
- {45, &ISystemSettingsServer::IsForceMuteOnHeadphoneRemoved, "IsForceMuteOnHeadphoneRemoved"},
- {46, &ISystemSettingsServer::SetForceMuteOnHeadphoneRemoved, "SetForceMuteOnHeadphoneRemoved"},
+ {43, &ISystemSettingsServer::GetAudioOutputMode, "GetAudioOutputMode"},
+ {44, &ISystemSettingsServer::SetAudioOutputMode, "SetAudioOutputMode"},
+ {45, &ISystemSettingsServer::GetSpeakerAutoMuteFlag , "GetSpeakerAutoMuteFlag"},
+ {46, &ISystemSettingsServer::SetSpeakerAutoMuteFlag , "SetSpeakerAutoMuteFlag"},
{47, &ISystemSettingsServer::GetQuestFlag, "GetQuestFlag"},
{48, &ISystemSettingsServer::SetQuestFlag, "SetQuestFlag"},
{49, nullptr, "GetDataDeletionSettings"},
@@ -155,8 +155,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
{64, &ISystemSettingsServer::SetPrimaryAlbumStorage, "SetPrimaryAlbumStorage"},
{65, nullptr, "GetUsb30EnableFlag"},
{66, nullptr, "SetUsb30EnableFlag"},
- {67, nullptr, "GetBatteryLot"},
- {68, nullptr, "GetSerialNumber"},
+ {67, &ISystemSettingsServer::GetBatteryLot, "GetBatteryLot"},
+ {68, &ISystemSettingsServer::GetSerialNumber, "GetSerialNumber"},
{69, &ISystemSettingsServer::GetNfcEnableFlag, "GetNfcEnableFlag"},
{70, &ISystemSettingsServer::SetNfcEnableFlag, "SetNfcEnableFlag"},
{71, &ISystemSettingsServer::GetSleepSettings, "GetSleepSettings"},
@@ -184,11 +184,11 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
{93, nullptr, "AcquireFatalDirtyFlagEventHandle"},
{94, nullptr, "GetFatalDirtyFlags"},
{95, &ISystemSettingsServer::GetAutoUpdateEnableFlag, "GetAutoUpdateEnableFlag"},
- {96, nullptr, "SetAutoUpdateEnableFlag"},
+ {96, &ISystemSettingsServer::SetAutoUpdateEnableFlag, "SetAutoUpdateEnableFlag"},
{97, nullptr, "GetNxControllerSettings"},
{98, nullptr, "SetNxControllerSettings"},
{99, &ISystemSettingsServer::GetBatteryPercentageFlag, "GetBatteryPercentageFlag"},
- {100, nullptr, "SetBatteryPercentageFlag"},
+ {100, &ISystemSettingsServer::SetBatteryPercentageFlag, "SetBatteryPercentageFlag"},
{101, nullptr, "GetExternalRtcResetFlag"},
{102, nullptr, "SetExternalRtcResetFlag"},
{103, nullptr, "GetUsbFullKeyEnableFlag"},
@@ -208,12 +208,12 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
{117, nullptr, "GetHeadphoneVolumeUpdateFlag"},
{118, nullptr, "SetHeadphoneVolumeUpdateFlag"},
{119, nullptr, "NeedsToUpdateHeadphoneVolume"},
- {120, nullptr, "GetPushNotificationActivityModeOnSleep"},
- {121, nullptr, "SetPushNotificationActivityModeOnSleep"},
+ {120, &ISystemSettingsServer::GetPushNotificationActivityModeOnSleep, "GetPushNotificationActivityModeOnSleep"},
+ {121, &ISystemSettingsServer::SetPushNotificationActivityModeOnSleep, "SetPushNotificationActivityModeOnSleep"},
{122, nullptr, "GetServiceDiscoveryControlSettings"},
{123, nullptr, "SetServiceDiscoveryControlSettings"},
{124, &ISystemSettingsServer::GetErrorReportSharePermission, "GetErrorReportSharePermission"},
- {125, nullptr, "SetErrorReportSharePermission"},
+ {125, &ISystemSettingsServer::SetErrorReportSharePermission, "SetErrorReportSharePermission"},
{126, &ISystemSettingsServer::GetAppletLaunchFlags, "GetAppletLaunchFlags"},
{127, &ISystemSettingsServer::SetAppletLaunchFlags, "SetAppletLaunchFlags"},
{128, nullptr, "GetConsoleSixAxisSensorAccelerationBias"},
@@ -225,7 +225,7 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
{134, nullptr, "GetConsoleSixAxisSensorAngularVelocityGain"},
{135, nullptr, "SetConsoleSixAxisSensorAngularVelocityGain"},
{136, &ISystemSettingsServer::GetKeyboardLayout, "GetKeyboardLayout"},
- {137, nullptr, "SetKeyboardLayout"},
+ {137, &ISystemSettingsServer::SetKeyboardLayout, "SetKeyboardLayout"},
{138, nullptr, "GetWebInspectorFlag"},
{139, nullptr, "GetAllowedSslHosts"},
{140, nullptr, "GetHostFsMountPoint"},
@@ -291,8 +291,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
{200, nullptr, "SetButtonConfigRegisteredSettings"},
{201, &ISystemSettingsServer::GetFieldTestingFlag, "GetFieldTestingFlag"},
{202, nullptr, "SetFieldTestingFlag"},
- {203, nullptr, "GetPanelCrcMode"},
- {204, nullptr, "SetPanelCrcMode"},
+ {203, &ISystemSettingsServer::GetPanelCrcMode, "GetPanelCrcMode"},
+ {204, &ISystemSettingsServer::SetPanelCrcMode, "SetPanelCrcMode"},
{205, nullptr, "GetNxControllerSettingsEx"},
{206, nullptr, "SetNxControllerSettingsEx"},
{207, nullptr, "GetHearingProtectionSafeguardFlag"},
@@ -349,7 +349,7 @@ bool ISystemSettingsServer::LoadSettingsFile(std::filesystem::path& path, auto&&
}
SettingsHeader hdr{};
file.read(reinterpret_cast<char*>(&hdr), sizeof(hdr));
- return hdr.magic == SETTINGS_MAGIC && hdr.version == SETTINGS_VERSION;
+ return hdr.magic == SETTINGS_MAGIC && hdr.version >= SETTINGS_VERSION;
};
if (!exists || !file_size_ok) {
@@ -390,7 +390,7 @@ bool ISystemSettingsServer::StoreSettingsFile(std::filesystem::path& path, auto&
}
auto settings_base = path / "settings";
- auto settings_tmp_file = settings_base;
+ std::filesystem::path settings_tmp_file = settings_base;
settings_tmp_file = settings_tmp_file.replace_extension("tmp");
std::ofstream file(settings_tmp_file, std::ios::binary | std::ios::out);
if (!file.is_open()) {
@@ -722,6 +722,9 @@ static Settings GetSettings() {
ret["hid_debug"]["disabled_features_per_id"] = std::vector<u8>(0xa8);
ret["hid_debug"]["touch_firmware_auto_update_disabled"] = ToBytes(bool{false});
+ // Mii
+ ret["mii"]["is_db_test_mode_enabled"] = ToBytes(bool{false});
+
// Settings
ret["settings_debug"]["is_debug_mode_enabled"] = ToBytes(bool{false});
@@ -814,7 +817,34 @@ void ISystemSettingsServer::SetTvSettings(HLERequestContext& ctx) {
rb.Push(ResultSuccess);
}
-void ISystemSettingsServer::IsForceMuteOnHeadphoneRemoved(HLERequestContext& ctx) {
+void ISystemSettingsServer::GetAudioOutputMode(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto target{rp.PopEnum<AudioOutputModeTarget>()};
+
+ AudioOutputMode output_mode{};
+ const auto result = GetAudioOutputMode(output_mode, target);
+
+ LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(result);
+ rb.PushEnum(output_mode);
+}
+
+void ISystemSettingsServer::SetAudioOutputMode(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto target{rp.PopEnum<AudioOutputModeTarget>()};
+ const auto output_mode{rp.PopEnum<AudioOutputMode>()};
+
+ const auto result = SetAudioOutputMode(target, output_mode);
+
+ LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void ISystemSettingsServer::GetSpeakerAutoMuteFlag(HLERequestContext& ctx) {
LOG_INFO(Service_SET, "called, force_mute_on_headphone_removed={}",
m_system_settings.force_mute_on_headphone_removed);
@@ -823,7 +853,7 @@ void ISystemSettingsServer::IsForceMuteOnHeadphoneRemoved(HLERequestContext& ctx
rb.PushRaw(m_system_settings.force_mute_on_headphone_removed);
}
-void ISystemSettingsServer::SetForceMuteOnHeadphoneRemoved(HLERequestContext& ctx) {
+void ISystemSettingsServer::SetSpeakerAutoMuteFlag(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
m_system_settings.force_mute_on_headphone_removed = rp.PopRaw<bool>();
SetSaveNeeded();
@@ -966,6 +996,26 @@ void ISystemSettingsServer::SetPrimaryAlbumStorage(HLERequestContext& ctx) {
rb.Push(ResultSuccess);
}
+void ISystemSettingsServer::GetBatteryLot(HLERequestContext& ctx) {
+ BatteryLot battery_lot = {"YUZUEMULATOR123456789"};
+
+ LOG_INFO(Service_SET, "called");
+
+ IPC::ResponseBuilder rb{ctx, 8};
+ rb.Push(ResultSuccess);
+ rb.PushRaw(battery_lot);
+}
+
+void ISystemSettingsServer::GetSerialNumber(HLERequestContext& ctx) {
+ SerialNumber console_serial = {"YUZ10012345678"};
+
+ LOG_INFO(Service_SET, "called");
+
+ IPC::ResponseBuilder rb{ctx, 8};
+ rb.Push(ResultSuccess);
+ rb.PushRaw(console_serial);
+}
+
void ISystemSettingsServer::GetNfcEnableFlag(HLERequestContext& ctx) {
LOG_INFO(Service_SET, "called, nfc_enable_flag={}", m_system_settings.nfc_enable_flag);
@@ -1129,6 +1179,17 @@ void ISystemSettingsServer::GetAutoUpdateEnableFlag(HLERequestContext& ctx) {
rb.Push(m_system_settings.auto_update_enable_flag);
}
+void ISystemSettingsServer::SetAutoUpdateEnableFlag(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ m_system_settings.auto_update_enable_flag = rp.Pop<bool>();
+ SetSaveNeeded();
+
+ LOG_INFO(Service_SET, "called, auto_update_flag={}", m_system_settings.auto_update_enable_flag);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
void ISystemSettingsServer::GetBatteryPercentageFlag(HLERequestContext& ctx) {
LOG_DEBUG(Service_SET, "called, battery_percentage_flag={}",
m_system_settings.battery_percentage_flag);
@@ -1138,6 +1199,18 @@ void ISystemSettingsServer::GetBatteryPercentageFlag(HLERequestContext& ctx) {
rb.Push(m_system_settings.battery_percentage_flag);
}
+void ISystemSettingsServer::SetBatteryPercentageFlag(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ m_system_settings.battery_percentage_flag = rp.Pop<bool>();
+ SetSaveNeeded();
+
+ LOG_INFO(Service_SET, "called, battery_percentage_flag={}",
+ m_system_settings.battery_percentage_flag);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
void ISystemSettingsServer::SetExternalSteadyClockInternalOffset(HLERequestContext& ctx) {
LOG_DEBUG(Service_SET, "called.");
@@ -1161,6 +1234,27 @@ void ISystemSettingsServer::GetExternalSteadyClockInternalOffset(HLERequestConte
rb.Push(offset);
}
+void ISystemSettingsServer::GetPushNotificationActivityModeOnSleep(HLERequestContext& ctx) {
+ LOG_INFO(Service_SET, "called, push_notification_activity_mode_on_sleep={}",
+ m_system_settings.push_notification_activity_mode_on_sleep);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(m_system_settings.push_notification_activity_mode_on_sleep);
+}
+
+void ISystemSettingsServer::SetPushNotificationActivityModeOnSleep(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ m_system_settings.push_notification_activity_mode_on_sleep = rp.Pop<s32>();
+ SetSaveNeeded();
+
+ LOG_INFO(Service_SET, "called, push_notification_activity_mode_on_sleep={}",
+ m_system_settings.push_notification_activity_mode_on_sleep);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
void ISystemSettingsServer::GetErrorReportSharePermission(HLERequestContext& ctx) {
LOG_INFO(Service_SET, "called, error_report_share_permission={}",
m_system_settings.error_report_share_permission);
@@ -1170,6 +1264,18 @@ void ISystemSettingsServer::GetErrorReportSharePermission(HLERequestContext& ctx
rb.PushEnum(m_system_settings.error_report_share_permission);
}
+void ISystemSettingsServer::SetErrorReportSharePermission(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ m_system_settings.error_report_share_permission = rp.PopEnum<ErrorReportSharePermission>();
+ SetSaveNeeded();
+
+ LOG_INFO(Service_SET, "called, error_report_share_permission={}",
+ m_system_settings.error_report_share_permission);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
void ISystemSettingsServer::GetAppletLaunchFlags(HLERequestContext& ctx) {
LOG_INFO(Service_SET, "called, applet_launch_flag={}", m_system_settings.applet_launch_flag);
@@ -1190,22 +1296,22 @@ void ISystemSettingsServer::SetAppletLaunchFlags(HLERequestContext& ctx) {
}
void ISystemSettingsServer::GetKeyboardLayout(HLERequestContext& ctx) {
- const auto language_code =
- available_language_codes[static_cast<s32>(::Settings::values.language_index.GetValue())];
- const auto key_code =
- std::find_if(language_to_layout.cbegin(), language_to_layout.cend(),
- [=](const auto& element) { return element.first == language_code; });
-
- KeyboardLayout selected_keyboard_layout = KeyboardLayout::EnglishUs;
- if (key_code != language_to_layout.end()) {
- selected_keyboard_layout = key_code->second;
- }
-
- LOG_INFO(Service_SET, "called, selected_keyboard_layout={}", selected_keyboard_layout);
+ LOG_INFO(Service_SET, "called, keyboard_layout={}", m_system_settings.keyboard_layout);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
- rb.Push(static_cast<u32>(selected_keyboard_layout));
+ rb.Push(static_cast<u32>(m_system_settings.keyboard_layout));
+}
+
+void ISystemSettingsServer::SetKeyboardLayout(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ m_system_settings.keyboard_layout = rp.PopRaw<KeyboardLayout>();
+ SetSaveNeeded();
+
+ LOG_INFO(Service_SET, "called, keyboard_layout={}", m_system_settings.keyboard_layout);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
}
void ISystemSettingsServer::GetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx) {
@@ -1297,6 +1403,25 @@ void ISystemSettingsServer::GetFieldTestingFlag(HLERequestContext& ctx) {
rb.Push(m_system_settings.field_testing_flag);
}
+void ISystemSettingsServer::GetPanelCrcMode(HLERequestContext& ctx) {
+ LOG_INFO(Service_SET, "called, panel_crc_mode={}", m_system_settings.panel_crc_mode);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(m_system_settings.panel_crc_mode);
+}
+
+void ISystemSettingsServer::SetPanelCrcMode(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ m_system_settings.panel_crc_mode = rp.PopRaw<s32>();
+ SetSaveNeeded();
+
+ LOG_INFO(Service_SET, "called, panel_crc_mode={}", m_system_settings.panel_crc_mode);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
void ISystemSettingsServer::SetupSettings() {
auto system_dir =
Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000050";
@@ -1387,6 +1512,66 @@ Result ISystemSettingsServer::SetVibrationMasterVolume(f32 volume) {
R_SUCCEED();
}
+Result ISystemSettingsServer::GetAudioOutputMode(AudioOutputMode& out_output_mode,
+ AudioOutputModeTarget target) const {
+ switch (target) {
+ case AudioOutputModeTarget::Hdmi:
+ out_output_mode = m_system_settings.audio_output_mode_hdmi;
+ break;
+ case AudioOutputModeTarget::Speaker:
+ out_output_mode = m_system_settings.audio_output_mode_speaker;
+ break;
+ case AudioOutputModeTarget::Headphone:
+ out_output_mode = m_system_settings.audio_output_mode_headphone;
+ break;
+ case AudioOutputModeTarget::Type3:
+ out_output_mode = m_system_settings.audio_output_mode_type3;
+ break;
+ case AudioOutputModeTarget::Type4:
+ out_output_mode = m_system_settings.audio_output_mode_type4;
+ break;
+ default:
+ LOG_ERROR(Service_SET, "Invalid audio output mode target {}", target);
+ }
+ R_SUCCEED();
+}
+
+Result ISystemSettingsServer::SetAudioOutputMode(AudioOutputModeTarget target,
+ AudioOutputMode output_mode) {
+ switch (target) {
+ case AudioOutputModeTarget::Hdmi:
+ m_system_settings.audio_output_mode_hdmi = output_mode;
+ break;
+ case AudioOutputModeTarget::Speaker:
+ m_system_settings.audio_output_mode_speaker = output_mode;
+ break;
+ case AudioOutputModeTarget::Headphone:
+ m_system_settings.audio_output_mode_headphone = output_mode;
+ break;
+ case AudioOutputModeTarget::Type3:
+ m_system_settings.audio_output_mode_type3 = output_mode;
+ break;
+ case AudioOutputModeTarget::Type4:
+ m_system_settings.audio_output_mode_type4 = output_mode;
+ break;
+ default:
+ LOG_ERROR(Service_SET, "Invalid audio output mode target {}", target);
+ }
+ SetSaveNeeded();
+ R_SUCCEED();
+}
+
+Result ISystemSettingsServer::GetSpeakerAutoMuteFlag(bool& is_auto_mute) const {
+ is_auto_mute = m_system_settings.force_mute_on_headphone_removed;
+ R_SUCCEED();
+}
+
+Result ISystemSettingsServer::SetSpeakerAutoMuteFlag(bool is_auto_mute) {
+ m_system_settings.force_mute_on_headphone_removed = is_auto_mute;
+ SetSaveNeeded();
+ R_SUCCEED();
+}
+
Result ISystemSettingsServer::GetExternalSteadyClockSourceId(Common::UUID& out_id) const {
out_id = m_private_settings.external_clock_source_id;
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:
Result GetVibrationMasterVolume(f32& out_volume) const;
Result SetVibrationMasterVolume(f32 volume);
+ Result GetAudioOutputMode(AudioOutputMode& out_output_mode, AudioOutputModeTarget target) const;
+ Result SetAudioOutputMode(AudioOutputModeTarget target, AudioOutputMode output_mode);
+ Result GetSpeakerAutoMuteFlag(bool& is_auto_mute) const;
+ Result SetSpeakerAutoMuteFlag(bool auto_mute);
Result GetExternalSteadyClockSourceId(Common::UUID& out_id) const;
Result SetExternalSteadyClockSourceId(const Common::UUID& id);
Result GetUserSystemClockContext(Service::PSC::Time::SystemClockContext& out_context) const;
@@ -97,8 +101,10 @@ private:
void GetSettingsItemValue(HLERequestContext& ctx);
void GetTvSettings(HLERequestContext& ctx);
void SetTvSettings(HLERequestContext& ctx);
- void IsForceMuteOnHeadphoneRemoved(HLERequestContext& ctx);
- void SetForceMuteOnHeadphoneRemoved(HLERequestContext& ctx);
+ void GetAudioOutputMode(HLERequestContext& ctx);
+ void SetAudioOutputMode(HLERequestContext& ctx);
+ void GetSpeakerAutoMuteFlag(HLERequestContext& ctx);
+ void SetSpeakerAutoMuteFlag(HLERequestContext& ctx);
void GetDebugModeFlag(HLERequestContext& ctx);
void GetQuestFlag(HLERequestContext& ctx);
void SetQuestFlag(HLERequestContext& ctx);
@@ -111,6 +117,8 @@ private:
void SetUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx);
void GetPrimaryAlbumStorage(HLERequestContext& ctx);
void SetPrimaryAlbumStorage(HLERequestContext& ctx);
+ void GetBatteryLot(HLERequestContext& ctx);
+ void GetSerialNumber(HLERequestContext& ctx);
void GetNfcEnableFlag(HLERequestContext& ctx);
void SetNfcEnableFlag(HLERequestContext& ctx);
void GetSleepSettings(HLERequestContext& ctx);
@@ -126,13 +134,19 @@ private:
void SetBluetoothEnableFlag(HLERequestContext& ctx);
void GetMiiAuthorId(HLERequestContext& ctx);
void GetAutoUpdateEnableFlag(HLERequestContext& ctx);
+ void SetAutoUpdateEnableFlag(HLERequestContext& ctx);
void GetBatteryPercentageFlag(HLERequestContext& ctx);
+ void SetBatteryPercentageFlag(HLERequestContext& ctx);
void SetExternalSteadyClockInternalOffset(HLERequestContext& ctx);
void GetExternalSteadyClockInternalOffset(HLERequestContext& ctx);
+ void GetPushNotificationActivityModeOnSleep(HLERequestContext& ctx);
+ void SetPushNotificationActivityModeOnSleep(HLERequestContext& ctx);
void GetErrorReportSharePermission(HLERequestContext& ctx);
+ void SetErrorReportSharePermission(HLERequestContext& ctx);
void GetAppletLaunchFlags(HLERequestContext& ctx);
void SetAppletLaunchFlags(HLERequestContext& ctx);
void GetKeyboardLayout(HLERequestContext& ctx);
+ void SetKeyboardLayout(HLERequestContext& ctx);
void GetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx);
void SetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx);
void GetUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext& ctx);
@@ -141,6 +155,8 @@ private:
void GetHomeMenuScheme(HLERequestContext& ctx);
void GetHomeMenuSchemeModel(HLERequestContext& ctx);
void GetFieldTestingFlag(HLERequestContext& ctx);
+ void GetPanelCrcMode(HLERequestContext& ctx);
+ void SetPanelCrcMode(HLERequestContext& ctx);
bool LoadSettingsFile(std::filesystem::path& path, auto&& default_func);
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 {
},
[&]() { HandleRasterizerWrite(GetInteger(vaddr), sizeof(T)); });
if (ptr) {
- const auto volatile_pointer = reinterpret_cast<volatile T*>(ptr);
- return Common::AtomicCompareAndSwap(volatile_pointer, data, expected);
+ return Common::AtomicCompareAndSwap(reinterpret_cast<T*>(ptr), data, expected);
}
return true;
}
@@ -796,8 +795,7 @@ struct Memory::Impl {
},
[&]() { HandleRasterizerWrite(GetInteger(vaddr), sizeof(u128)); });
if (ptr) {
- const auto volatile_pointer = reinterpret_cast<volatile u64*>(ptr);
- return Common::AtomicCompareAndSwap(volatile_pointer, data, expected);
+ return Common::AtomicCompareAndSwap(reinterpret_cast<u64*>(ptr), data, expected);
}
return true;
}
diff --git a/src/dedicated_room/CMakeLists.txt b/src/dedicated_room/CMakeLists.txt
index 136109a0c..c0dcc0241 100644
--- a/src/dedicated_room/CMakeLists.txt
+++ b/src/dedicated_room/CMakeLists.txt
@@ -7,8 +7,6 @@ add_executable(yuzu-room
yuzu_room.rc
)
-create_target_directory_groups(yuzu-room)
-
target_link_libraries(yuzu-room PRIVATE common network)
if (ENABLE_WEB_SERVICE)
target_compile_definitions(yuzu-room PRIVATE -DENABLE_WEB_SERVICE)
@@ -28,3 +26,5 @@ endif()
if (YUZU_USE_PRECOMPILED_HEADERS)
target_precompile_headers(yuzu-room PRIVATE precompiled_headers.h)
endif()
+
+create_target_directory_groups(yuzu-room)
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() {
EndGroup();
}
+#ifdef __unix__
+void Config::ReadLinuxValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Linux));
+
+ ReadCategory(Settings::Category::Linux);
+
+ EndGroup();
+}
+#endif
+
void Config::ReadServiceValues() {
BeginGroup(Settings::TranslateCategory(Settings::Category::Services));
@@ -404,6 +414,9 @@ void Config::ReadValues() {
ReadControlValues();
ReadCoreValues();
ReadCpuValues();
+#ifdef __unix__
+ ReadLinuxValues();
+#endif
ReadRendererValues();
ReadAudioValues();
ReadSystemValues();
@@ -504,6 +517,9 @@ void Config::SaveValues() {
SaveControlValues();
SaveCoreValues();
SaveCpuValues();
+#ifdef __unix__
+ SaveLinuxValues();
+#endif
SaveRendererValues();
SaveAudioValues();
SaveSystemValues();
@@ -578,6 +594,16 @@ void Config::SaveDebuggingValues() {
EndGroup();
}
+#ifdef __unix__
+void Config::SaveLinuxValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Linux));
+
+ WriteCategory(Settings::Category::Linux);
+
+ EndGroup();
+}
+#endif
+
void Config::SaveNetworkValues() {
BeginGroup(Settings::TranslateCategory(Settings::Category::Services));
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:
void ReadCoreValues();
void ReadDataStorageValues();
void ReadDebuggingValues();
+#ifdef __unix__
+ void ReadLinuxValues();
+#endif
void ReadServiceValues();
void ReadDisabledAddOnValues();
void ReadMiscellaneousValues();
@@ -107,6 +110,9 @@ protected:
void SaveCoreValues();
void SaveDataStorageValues();
void SaveDebuggingValues();
+#ifdef __unix__
+ void SaveLinuxValues();
+#endif
void SaveNetworkValues();
void SaveDisabledAddOnValues();
void SaveMiscellaneousValues();
diff --git a/src/hid_core/CMakeLists.txt b/src/hid_core/CMakeLists.txt
index aa85502b5..64cd6e726 100644
--- a/src/hid_core/CMakeLists.txt
+++ b/src/hid_core/CMakeLists.txt
@@ -96,6 +96,7 @@ add_library(hid_core STATIC
resources/system_buttons/home_button.h
resources/system_buttons/sleep_button.cpp
resources/system_buttons/sleep_button.h
+ resources/system_buttons/system_button_types.h
resources/touch_screen/gesture.cpp
resources/touch_screen/gesture.h
resources/touch_screen/gesture_types.h
diff --git a/src/hid_core/hid_types.h b/src/hid_core/hid_types.h
index a01292a70..b310ab72d 100644
--- a/src/hid_core/hid_types.h
+++ b/src/hid_core/hid_types.h
@@ -437,6 +437,16 @@ struct LedPattern {
};
};
+struct SleepButtonState {
+ union {
+ u64 raw{};
+
+ // Buttons
+ BitField<0, 1, u64> sleep;
+ };
+};
+static_assert(sizeof(SleepButtonState) == 0x8, "SleepButtonState has incorrect size.");
+
struct HomeButtonState {
union {
u64 raw{};
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() {
keyboard->SetAppletResource(applet_resource, &shared_mutex);
const auto settings =
- system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys");
+ system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
npad->SetNpadExternals(applet_resource, &shared_mutex, handheld_config, settings);
six_axis->SetAppletResource(applet_resource, &shared_mutex);
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 @@
namespace Service::HID {
HidFirmwareSettings::HidFirmwareSettings(Core::System& system) {
- m_set_sys = system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys");
+ m_set_sys =
+ system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
LoadSettings(true);
}
diff --git a/src/hid_core/resources/shared_memory_format.h b/src/hid_core/resources/shared_memory_format.h
index 2ae0004ba..49755c8dc 100644
--- a/src/hid_core/resources/shared_memory_format.h
+++ b/src/hid_core/resources/shared_memory_format.h
@@ -12,6 +12,7 @@
#include "hid_core/resources/mouse/mouse_types.h"
#include "hid_core/resources/npad/npad_types.h"
#include "hid_core/resources/ring_lifo.h"
+#include "hid_core/resources/system_buttons/system_button_types.h"
#include "hid_core/resources/touch_screen/touch_types.h"
namespace Service::HID {
@@ -75,24 +76,24 @@ static_assert(sizeof(DigitizerSharedMemoryFormat) == 0x1000,
// This is nn::hid::detail::HomeButtonSharedMemoryFormat
struct HomeButtonSharedMemoryFormat {
- CommonHeader header;
- INSERT_PADDING_BYTES(0x1E0);
+ Lifo<HomeButtonState, HidEntryCount> home_lifo{};
+ INSERT_PADDING_BYTES(0x48);
};
static_assert(sizeof(HomeButtonSharedMemoryFormat) == 0x200,
"HomeButtonSharedMemoryFormat is an invalid size");
// This is nn::hid::detail::SleepButtonSharedMemoryFormat
struct SleepButtonSharedMemoryFormat {
- CommonHeader header;
- INSERT_PADDING_BYTES(0x1E0);
+ Lifo<SleepButtonState, HidEntryCount> sleep_lifo{};
+ INSERT_PADDING_BYTES(0x48);
};
static_assert(sizeof(SleepButtonSharedMemoryFormat) == 0x200,
"SleepButtonSharedMemoryFormat is an invalid size");
// This is nn::hid::detail::CaptureButtonSharedMemoryFormat
struct CaptureButtonSharedMemoryFormat {
- CommonHeader header;
- INSERT_PADDING_BYTES(0x1E0);
+ Lifo<CaptureButtonState, HidEntryCount> capture_lifo{};
+ INSERT_PADDING_BYTES(0x48);
};
static_assert(sizeof(CaptureButtonSharedMemoryFormat) == 0x200,
"CaptureButtonSharedMemoryFormat is an invalid size");
diff --git a/src/hid_core/resources/system_buttons/capture_button.cpp b/src/hid_core/resources/system_buttons/capture_button.cpp
index 70973ae25..95eb60424 100644
--- a/src/hid_core/resources/system_buttons/capture_button.cpp
+++ b/src/hid_core/resources/system_buttons/capture_button.cpp
@@ -2,6 +2,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core_timing.h"
+#include "hid_core/frontend/emulated_controller.h"
+#include "hid_core/hid_core.h"
#include "hid_core/resources/applet_resource.h"
#include "hid_core/resources/shared_memory_format.h"
#include "hid_core/resources/system_buttons/capture_button.h"
@@ -17,10 +19,6 @@ void CaptureButton::OnInit() {}
void CaptureButton::OnRelease() {}
void CaptureButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- if (!smart_update) {
- return;
- }
-
std::scoped_lock shared_lock{*shared_mutex};
const u64 aruid = applet_resource->GetActiveAruid();
auto* data = applet_resource->GetAruidData(aruid);
@@ -29,11 +27,21 @@ void CaptureButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
return;
}
- auto& header = data->shared_memory_format->capture_button.header;
- header.timestamp = core_timing.GetGlobalTimeNs().count();
- header.total_entry_count = 17;
- header.entry_count = 0;
- header.last_entry_index = 0;
+ auto& shared_memory = data->shared_memory_format->capture_button;
+
+ if (!IsControllerActivated()) {
+ shared_memory.capture_lifo.buffer_count = 0;
+ shared_memory.capture_lifo.buffer_tail = 0;
+ return;
+ }
+
+ const auto& last_entry = shared_memory.capture_lifo.ReadCurrentEntry().state;
+ next_state.sampling_number = last_entry.sampling_number + 1;
+
+ auto* controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1);
+ next_state.buttons.raw = controller->GetHomeButtons().raw;
+
+ shared_memory.capture_lifo.WriteNextEntry(next_state);
}
} // namespace Service::HID
diff --git a/src/hid_core/resources/system_buttons/capture_button.h b/src/hid_core/resources/system_buttons/capture_button.h
index ad95d7cad..f362ef90b 100644
--- a/src/hid_core/resources/system_buttons/capture_button.h
+++ b/src/hid_core/resources/system_buttons/capture_button.h
@@ -4,6 +4,7 @@
#pragma once
#include "hid_core/resources/controller_base.h"
+#include "hid_core/resources/system_buttons/system_button_types.h"
namespace Service::HID {
@@ -22,6 +23,6 @@ public:
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
private:
- bool smart_update{};
+ CaptureButtonState next_state{};
};
} // namespace Service::HID
diff --git a/src/hid_core/resources/system_buttons/home_button.cpp b/src/hid_core/resources/system_buttons/home_button.cpp
index f9c1f44b5..f665338f3 100644
--- a/src/hid_core/resources/system_buttons/home_button.cpp
+++ b/src/hid_core/resources/system_buttons/home_button.cpp
@@ -2,6 +2,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core_timing.h"
+#include "hid_core/frontend/emulated_controller.h"
+#include "hid_core/hid_core.h"
#include "hid_core/resources/applet_resource.h"
#include "hid_core/resources/shared_memory_format.h"
#include "hid_core/resources/system_buttons/home_button.h"
@@ -17,10 +19,6 @@ void HomeButton::OnInit() {}
void HomeButton::OnRelease() {}
void HomeButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- if (!smart_update) {
- return;
- }
-
std::scoped_lock shared_lock{*shared_mutex};
const u64 aruid = applet_resource->GetActiveAruid();
auto* data = applet_resource->GetAruidData(aruid);
@@ -29,11 +27,21 @@ void HomeButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
return;
}
- auto& header = data->shared_memory_format->home_button.header;
- header.timestamp = core_timing.GetGlobalTimeNs().count();
- header.total_entry_count = 17;
- header.entry_count = 0;
- header.last_entry_index = 0;
+ auto& shared_memory = data->shared_memory_format->home_button;
+
+ if (!IsControllerActivated()) {
+ shared_memory.home_lifo.buffer_count = 0;
+ shared_memory.home_lifo.buffer_tail = 0;
+ return;
+ }
+
+ const auto& last_entry = shared_memory.home_lifo.ReadCurrentEntry().state;
+ next_state.sampling_number = last_entry.sampling_number + 1;
+
+ auto* controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1);
+ next_state.buttons.raw = controller->GetHomeButtons().raw;
+
+ shared_memory.home_lifo.WriteNextEntry(next_state);
}
} // namespace Service::HID
diff --git a/src/hid_core/resources/system_buttons/home_button.h b/src/hid_core/resources/system_buttons/home_button.h
index ecf8327f4..a9374828d 100644
--- a/src/hid_core/resources/system_buttons/home_button.h
+++ b/src/hid_core/resources/system_buttons/home_button.h
@@ -4,6 +4,7 @@
#pragma once
#include "hid_core/resources/controller_base.h"
+#include "hid_core/resources/system_buttons/system_button_types.h"
namespace Service::HID {
@@ -22,6 +23,6 @@ public:
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
private:
- bool smart_update{};
+ HomeButtonState next_state{};
};
} // namespace Service::HID
diff --git a/src/hid_core/resources/system_buttons/sleep_button.cpp b/src/hid_core/resources/system_buttons/sleep_button.cpp
index 22adf501f..159663246 100644
--- a/src/hid_core/resources/system_buttons/sleep_button.cpp
+++ b/src/hid_core/resources/system_buttons/sleep_button.cpp
@@ -17,10 +17,6 @@ void SleepButton::OnInit() {}
void SleepButton::OnRelease() {}
void SleepButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- if (!smart_update) {
- return;
- }
-
std::scoped_lock shared_lock{*shared_mutex};
const u64 aruid = applet_resource->GetActiveAruid();
auto* data = applet_resource->GetAruidData(aruid);
@@ -29,11 +25,20 @@ void SleepButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
return;
}
- auto& header = data->shared_memory_format->capture_button.header;
- header.timestamp = core_timing.GetGlobalTimeNs().count();
- header.total_entry_count = 17;
- header.entry_count = 0;
- header.last_entry_index = 0;
+ auto& shared_memory = data->shared_memory_format->sleep_button;
+
+ if (!IsControllerActivated()) {
+ shared_memory.sleep_lifo.buffer_count = 0;
+ shared_memory.sleep_lifo.buffer_tail = 0;
+ return;
+ }
+
+ const auto& last_entry = shared_memory.sleep_lifo.ReadCurrentEntry().state;
+ next_state.sampling_number = last_entry.sampling_number + 1;
+
+ next_state.buttons.raw = 0;
+
+ shared_memory.sleep_lifo.WriteNextEntry(next_state);
}
} // namespace Service::HID
diff --git a/src/hid_core/resources/system_buttons/sleep_button.h b/src/hid_core/resources/system_buttons/sleep_button.h
index f9ed38c33..f8ac5031b 100644
--- a/src/hid_core/resources/system_buttons/sleep_button.h
+++ b/src/hid_core/resources/system_buttons/sleep_button.h
@@ -4,6 +4,7 @@
#pragma once
#include "hid_core/resources/controller_base.h"
+#include "hid_core/resources/system_buttons/system_button_types.h"
namespace Service::HID {
@@ -22,6 +23,6 @@ public:
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
private:
- bool smart_update{};
+ SleepButtonState next_state{};
};
} // namespace Service::HID
diff --git a/src/hid_core/resources/system_buttons/system_button_types.h b/src/hid_core/resources/system_buttons/system_button_types.h
new file mode 100644
index 000000000..929e1dc4c
--- /dev/null
+++ b/src/hid_core/resources/system_buttons/system_button_types.h
@@ -0,0 +1,31 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "hid_core/hid_types.h"
+
+namespace Service::HID {
+
+// This is nn::hid::system::SleepButtonState
+struct SleepButtonState {
+ s64 sampling_number{};
+ Core::HID::SleepButtonState buttons;
+};
+static_assert(sizeof(SleepButtonState) == 0x10, "SleepButtonState is an invalid size");
+
+// This is nn::hid::system::HomeButtonState
+struct HomeButtonState {
+ s64 sampling_number{};
+ Core::HID::HomeButtonState buttons;
+};
+static_assert(sizeof(HomeButtonState) == 0x10, "HomeButtonState is an invalid size");
+
+// This is nn::hid::system::SleepButtonState
+struct CaptureButtonState {
+ s64 sampling_number{};
+ Core::HID::CaptureButtonState buttons;
+};
+static_assert(sizeof(CaptureButtonState) == 0x10, "CaptureButtonState is an invalid size");
+
+} // namespace Service::HID
diff --git a/src/hid_core/resources/unique_pad/unique_pad.cpp b/src/hid_core/resources/unique_pad/unique_pad.cpp
index 892bbe3c9..89fc57269 100644
--- a/src/hid_core/resources/unique_pad/unique_pad.cpp
+++ b/src/hid_core/resources/unique_pad/unique_pad.cpp
@@ -28,7 +28,7 @@ void UniquePad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
return;
}
- auto& header = data->shared_memory_format->capture_button.header;
+ auto& header = data->shared_memory_format->unique_pad.header;
header.timestamp = core_timing.GetGlobalTimeNs().count();
header.total_entry_count = 17;
header.entry_count = 0;
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 5ed0ad0ed..0755ba772 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -289,8 +289,6 @@ add_library(video_core STATIC
vulkan_common/vulkan.h
)
-create_target_directory_groups(video_core)
-
target_link_libraries(video_core PUBLIC common core)
target_link_libraries(video_core PUBLIC glad shader_recompiler stb bc_decoder)
@@ -304,7 +302,7 @@ target_link_options(video_core PRIVATE ${FFmpeg_LDFLAGS})
add_dependencies(video_core host_shaders)
target_include_directories(video_core PRIVATE ${HOST_SHADERS_INCLUDE})
-target_link_libraries(video_core PRIVATE sirit Vulkan::Headers GPUOpen::VulkanMemoryAllocator)
+target_link_libraries(video_core PRIVATE sirit Vulkan::Headers Vulkan::UtilityHeaders GPUOpen::VulkanMemoryAllocator)
if (ENABLE_NSIGHT_AFTERMATH)
if (NOT DEFINED ENV{NSIGHT_AFTERMATH_SDK})
@@ -365,3 +363,5 @@ endif()
if (ANDROID AND ARCHITECTURE_arm64)
target_link_libraries(video_core PRIVATE adrenotools)
endif()
+
+create_target_directory_groups(video_core)
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 @@
#include "core/core.h"
#include "video_core/renderer_vulkan/vk_scheduler.h"
#include "video_core/renderer_vulkan/vk_swapchain.h"
+#include "video_core/vulkan_common/vk_enum_string_helper.h"
#include "video_core/vulkan_common/vulkan_device.h"
#include "video_core/vulkan_common/vulkan_wrapper.h"
#include "vulkan/vulkan_core.h"
@@ -151,7 +152,7 @@ bool Swapchain::AcquireNextImage() {
vk::Check(result);
break;
default:
- LOG_ERROR(Render_Vulkan, "vkAcquireNextImageKHR returned {}", vk::ToString(result));
+ LOG_ERROR(Render_Vulkan, "vkAcquireNextImageKHR returned {}", string_VkResult(result));
break;
}
@@ -187,7 +188,7 @@ void Swapchain::Present(VkSemaphore render_semaphore) {
vk::Check(result);
break;
default:
- LOG_CRITICAL(Render_Vulkan, "Failed to present with error {}", vk::ToString(result));
+ LOG_CRITICAL(Render_Vulkan, "Failed to present with error {}", string_VkResult(result));
break;
}
++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 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "video_core/vulkan_common/vulkan.h"
+
+#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 @@
#include "common/common_types.h"
#include "common/logging/log.h"
+#include "video_core/vulkan_common/vk_enum_string_helper.h"
#include "video_core/vulkan_common/vma.h"
#include "video_core/vulkan_common/vulkan_wrapper.h"
@@ -298,109 +299,7 @@ bool Load(VkInstance instance, InstanceDispatch& dld) noexcept {
}
const char* Exception::what() const noexcept {
- return ToString(result);
-}
-
-const char* ToString(VkResult result) noexcept {
- switch (result) {
- case VkResult::VK_SUCCESS:
- return "VK_SUCCESS";
- case VkResult::VK_NOT_READY:
- return "VK_NOT_READY";
- case VkResult::VK_TIMEOUT:
- return "VK_TIMEOUT";
- case VkResult::VK_EVENT_SET:
- return "VK_EVENT_SET";
- case VkResult::VK_EVENT_RESET:
- return "VK_EVENT_RESET";
- case VkResult::VK_INCOMPLETE:
- return "VK_INCOMPLETE";
- case VkResult::VK_ERROR_OUT_OF_HOST_MEMORY:
- return "VK_ERROR_OUT_OF_HOST_MEMORY";
- case VkResult::VK_ERROR_OUT_OF_DEVICE_MEMORY:
- return "VK_ERROR_OUT_OF_DEVICE_MEMORY";
- case VkResult::VK_ERROR_INITIALIZATION_FAILED:
- return "VK_ERROR_INITIALIZATION_FAILED";
- case VkResult::VK_ERROR_DEVICE_LOST:
- return "VK_ERROR_DEVICE_LOST";
- case VkResult::VK_ERROR_MEMORY_MAP_FAILED:
- return "VK_ERROR_MEMORY_MAP_FAILED";
- case VkResult::VK_ERROR_LAYER_NOT_PRESENT:
- return "VK_ERROR_LAYER_NOT_PRESENT";
- case VkResult::VK_ERROR_EXTENSION_NOT_PRESENT:
- return "VK_ERROR_EXTENSION_NOT_PRESENT";
- case VkResult::VK_ERROR_FEATURE_NOT_PRESENT:
- return "VK_ERROR_FEATURE_NOT_PRESENT";
- case VkResult::VK_ERROR_INCOMPATIBLE_DRIVER:
- return "VK_ERROR_INCOMPATIBLE_DRIVER";
- case VkResult::VK_ERROR_TOO_MANY_OBJECTS:
- return "VK_ERROR_TOO_MANY_OBJECTS";
- case VkResult::VK_ERROR_FORMAT_NOT_SUPPORTED:
- return "VK_ERROR_FORMAT_NOT_SUPPORTED";
- case VkResult::VK_ERROR_FRAGMENTED_POOL:
- return "VK_ERROR_FRAGMENTED_POOL";
- case VkResult::VK_ERROR_OUT_OF_POOL_MEMORY:
- return "VK_ERROR_OUT_OF_POOL_MEMORY";
- case VkResult::VK_ERROR_INVALID_EXTERNAL_HANDLE:
- return "VK_ERROR_INVALID_EXTERNAL_HANDLE";
- case VkResult::VK_ERROR_SURFACE_LOST_KHR:
- return "VK_ERROR_SURFACE_LOST_KHR";
- case VkResult::VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
- return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
- case VkResult::VK_SUBOPTIMAL_KHR:
- return "VK_SUBOPTIMAL_KHR";
- case VkResult::VK_ERROR_OUT_OF_DATE_KHR:
- return "VK_ERROR_OUT_OF_DATE_KHR";
- case VkResult::VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
- return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR";
- case VkResult::VK_ERROR_VALIDATION_FAILED_EXT:
- return "VK_ERROR_VALIDATION_FAILED_EXT";
- case VkResult::VK_ERROR_INVALID_SHADER_NV:
- return "VK_ERROR_INVALID_SHADER_NV";
- case VkResult::VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR:
- return "VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR";
- case VkResult::VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR:
- return "VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR";
- case VkResult::VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR:
- return "VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR";
- case VkResult::VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR:
- return "VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR";
- case VkResult::VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR:
- return "VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR";
- case VkResult::VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR:
- return "VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR";
- case VkResult::VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT:
- return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT";
- case VkResult::VK_ERROR_FRAGMENTATION_EXT:
- return "VK_ERROR_FRAGMENTATION_EXT";
- case VkResult::VK_ERROR_NOT_PERMITTED_EXT:
- return "VK_ERROR_NOT_PERMITTED_EXT";
- case VkResult::VK_ERROR_INVALID_DEVICE_ADDRESS_EXT:
- return "VK_ERROR_INVALID_DEVICE_ADDRESS_EXT";
- case VkResult::VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT:
- return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT";
- case VkResult::VK_ERROR_UNKNOWN:
- return "VK_ERROR_UNKNOWN";
- case VkResult::VK_THREAD_IDLE_KHR:
- return "VK_THREAD_IDLE_KHR";
- case VkResult::VK_THREAD_DONE_KHR:
- return "VK_THREAD_DONE_KHR";
- case VkResult::VK_OPERATION_DEFERRED_KHR:
- return "VK_OPERATION_DEFERRED_KHR";
- case VkResult::VK_OPERATION_NOT_DEFERRED_KHR:
- return "VK_OPERATION_NOT_DEFERRED_KHR";
- case VkResult::VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR:
- return "VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR";
- case VkResult::VK_PIPELINE_COMPILE_REQUIRED_EXT:
- return "VK_PIPELINE_COMPILE_REQUIRED_EXT";
- case VkResult::VK_RESULT_MAX_ENUM:
- return "VK_RESULT_MAX_ENUM";
- case VkResult::VK_ERROR_COMPRESSION_EXHAUSTED_EXT:
- return "VK_ERROR_COMPRESSION_EXHAUSTED_EXT";
- case VkResult::VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT:
- return "VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT";
- }
- return "Unknown";
+ return string_VkResult(result);
}
void Destroy(VkInstance instance, const InstanceDispatch& dld) noexcept {
@@ -1067,7 +966,7 @@ u32 AvailableVersion(const InstanceDispatch& dld) noexcept {
u32 version;
if (const VkResult result = vkEnumerateInstanceVersion(&version); result != VK_SUCCESS) {
LOG_ERROR(Render_Vulkan, "vkEnumerateInstanceVersion returned {}, assuming Vulkan 1.1",
- ToString(result));
+ string_VkResult(result));
return VK_API_VERSION_1_1;
}
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:
VkResult result;
};
-/// Converts a VkResult enum into a rodata string
-const char* ToString(VkResult) noexcept;
-
/// Throws a Vulkan exception if result is not success.
inline void Check(VkResult result) {
if (result != VK_SUCCESS) {
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 93b03b917..76f06da12 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -96,6 +96,9 @@ add_executable(yuzu
configuration/configure_input_profile_dialog.cpp
configuration/configure_input_profile_dialog.h
configuration/configure_input_profile_dialog.ui
+ configuration/configure_linux_tab.cpp
+ configuration/configure_linux_tab.h
+ configuration/configure_linux_tab.ui
configuration/configure_mouse_panning.cpp
configuration/configure_mouse_panning.h
configuration/configure_mouse_panning.ui
@@ -375,8 +378,6 @@ elseif(WIN32)
endif()
endif()
-create_target_directory_groups(yuzu)
-
target_link_libraries(yuzu PRIVATE common core input_common frontend_common network video_core)
target_link_libraries(yuzu PRIVATE Boost::headers glad Qt${QT_MAJOR_VERSION}::Widgets)
target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
@@ -472,3 +473,5 @@ endif()
if (YUZU_USE_PRECOMPILED_HEADERS)
target_precompile_headers(yuzu PRIVATE precompiled_headers.h)
endif()
+
+create_target_directory_groups(yuzu)
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;
}
class ConfigureAudio : public ConfigurationShared::Tab {
+ Q_OBJECT
+
public:
explicit ConfigureAudio(const Core::System& system_,
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;
}
class ConfigureCpu : public ConfigurationShared::Tab {
+ Q_OBJECT
+
public:
explicit ConfigureCpu(const Core::System& system_,
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;
}
class ConfigureGeneral : public ConfigurationShared::Tab {
+ Q_OBJECT
+
public:
explicit ConfigureGeneral(const Core::System& system_,
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) {
}
void ConfigureGraphics::UpdateVsyncSetting() const {
+ const Settings::RendererBackend backend{GetCurrentGraphicsBackend()};
+ if (backend == Settings::RendererBackend::Null) {
+ return;
+ }
+
const auto mode = vsync_mode_combobox_enum_map[vsync_mode_combobox->currentIndex()];
const auto vsync_mode = PresentModeToSetting(mode);
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;
}
class ConfigureGraphics : public ConfigurationShared::Tab {
+ Q_OBJECT
+
public:
explicit ConfigureGraphics(
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;
}
class ConfigureGraphicsAdvanced : public ConfigurationShared::Tab {
+ Q_OBJECT
+
public:
explicit ConfigureGraphicsAdvanced(
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 @@
+// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "common/settings.h"
+#include "core/core.h"
+#include "ui_configure_linux_tab.h"
+#include "yuzu/configuration/configuration_shared.h"
+#include "yuzu/configuration/configure_linux_tab.h"
+#include "yuzu/configuration/shared_widget.h"
+
+ConfigureLinuxTab::ConfigureLinuxTab(const Core::System& system_,
+ std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_,
+ const ConfigurationShared::Builder& builder, QWidget* parent)
+ : Tab(group_, parent), ui(std::make_unique<Ui::ConfigureLinuxTab>()), system{system_} {
+ ui->setupUi(this);
+
+ Setup(builder);
+
+ SetConfiguration();
+}
+
+ConfigureLinuxTab::~ConfigureLinuxTab() = default;
+
+void ConfigureLinuxTab::SetConfiguration() {}
+void ConfigureLinuxTab::Setup(const ConfigurationShared::Builder& builder) {
+ QLayout& linux_layout = *ui->linux_widget->layout();
+
+ std::map<u32, QWidget*> linux_hold{};
+
+ std::vector<Settings::BasicSetting*> settings;
+ const auto push = [&](Settings::Category category) {
+ for (const auto setting : Settings::values.linkage.by_category[category]) {
+ settings.push_back(setting);
+ }
+ };
+
+ push(Settings::Category::Linux);
+
+ for (auto* setting : settings) {
+ auto* widget = builder.BuildWidget(setting, apply_funcs);
+
+ if (widget == nullptr) {
+ continue;
+ }
+ if (!widget->Valid()) {
+ widget->deleteLater();
+ continue;
+ }
+
+ linux_hold.insert({setting->Id(), widget});
+ }
+
+ for (const auto& [id, widget] : linux_hold) {
+ linux_layout.addWidget(widget);
+ }
+}
+
+void ConfigureLinuxTab::ApplyConfiguration() {
+ const bool is_powered_on = system.IsPoweredOn();
+ for (const auto& apply_func : apply_funcs) {
+ apply_func(is_powered_on);
+ }
+}
+
+void ConfigureLinuxTab::changeEvent(QEvent* event) {
+ if (event->type() == QEvent::LanguageChange) {
+ RetranslateUI();
+ }
+
+ QWidget::changeEvent(event);
+}
+
+void ConfigureLinuxTab::RetranslateUI() {
+ ui->retranslateUi(this);
+}
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 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <QWidget>
+
+namespace Core {
+class System;
+}
+
+namespace Ui {
+class ConfigureLinuxTab;
+}
+
+namespace ConfigurationShared {
+class Builder;
+}
+
+class ConfigureLinuxTab : public ConfigurationShared::Tab {
+ Q_OBJECT
+
+public:
+ explicit ConfigureLinuxTab(const Core::System& system_,
+ std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group,
+ const ConfigurationShared::Builder& builder,
+ QWidget* parent = nullptr);
+ ~ConfigureLinuxTab() override;
+
+ void ApplyConfiguration() override;
+ void SetConfiguration() override;
+
+private:
+ void changeEvent(QEvent* event) override;
+ void RetranslateUI();
+
+ void Setup(const ConfigurationShared::Builder& builder);
+
+ std::unique_ptr<Ui::ConfigureLinuxTab> ui;
+
+ const Core::System& system;
+
+ std::vector<std::function<void(bool)>> apply_funcs{};
+};
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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ConfigureLinuxTab</class>
+ <widget class="QWidget" name="ConfigureLinuxTab">
+ <property name="accessibleName">
+ <string>Linux</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QGroupBox" name="LinuxGroupBox">
+ <property name="title">
+ <string>Linux</string>
+ </property>
+ <layout class="QVBoxLayout" name="LinuxVerticalLayout_1">
+ <item>
+ <widget class="QWidget" name="linux_widget" native="true">
+ <layout class="QVBoxLayout" name="LinuxVerticalLayout_2">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</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;
/// A dialog for touchpad calibration configuration.
class CalibrationConfigurationDialog : public QDialog {
Q_OBJECT
+
public:
explicit CalibrationConfigurationDialog(QWidget* parent, const std::string& host, u16 port);
~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;
class ConfigureMousePanning : public QDialog {
Q_OBJECT
+
public:
explicit ConfigureMousePanning(QWidget* parent, InputCommon::InputSubsystem* input_subsystem_,
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 @@
#include "yuzu/configuration/configure_graphics.h"
#include "yuzu/configuration/configure_graphics_advanced.h"
#include "yuzu/configuration/configure_input_per_game.h"
+#include "yuzu/configuration/configure_linux_tab.h"
#include "yuzu/configuration/configure_per_game.h"
#include "yuzu/configuration/configure_per_game_addons.h"
#include "yuzu/configuration/configure_system.h"
@@ -60,6 +61,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st
system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); },
[](Settings::AspectRatio, Settings::ResolutionSetup) {}, tab_group, *builder, this);
input_tab = std::make_unique<ConfigureInputPerGame>(system_, game_config.get(), this);
+ linux_tab = std::make_unique<ConfigureLinuxTab>(system_, tab_group, *builder, this);
system_tab = std::make_unique<ConfigureSystem>(system_, tab_group, *builder, this);
ui->setupUi(this);
@@ -71,6 +73,10 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st
ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("Adv. Graphics"));
ui->tabWidget->addTab(audio_tab.get(), tr("Audio"));
ui->tabWidget->addTab(input_tab.get(), tr("Input Profiles"));
+ // Only show Linux tab on Unix
+#ifdef __unix__
+ ui->tabWidget->addTab(linux_tab.get(), tr("Linux"));
+#endif
setFocusPolicy(Qt::ClickFocus);
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;
class ConfigureGraphics;
class ConfigureGraphicsAdvanced;
class ConfigureInputPerGame;
+class ConfigureLinuxTab;
class ConfigureSystem;
class QGraphicsScene;
@@ -85,5 +86,6 @@ private:
std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab;
std::unique_ptr<ConfigureGraphics> graphics_tab;
std::unique_ptr<ConfigureInputPerGame> input_tab;
+ std::unique_ptr<ConfigureLinuxTab> linux_tab;
std::unique_ptr<ConfigureSystem> system_tab;
};
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;
}
class ConfigureSystem : public ConfigurationShared::Tab {
+ Q_OBJECT
+
public:
explicit ConfigureSystem(Core::System& system_,
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group,
diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt
index fbeba8813..ebd8fd738 100644
--- a/src/yuzu_cmd/CMakeLists.txt
+++ b/src/yuzu_cmd/CMakeLists.txt
@@ -28,8 +28,6 @@ add_executable(yuzu-cmd
yuzu.rc
)
-create_target_directory_groups(yuzu-cmd)
-
target_link_libraries(yuzu-cmd PRIVATE common core input_common frontend_common)
target_link_libraries(yuzu-cmd PRIVATE glad)
if (MSVC)
@@ -63,3 +61,5 @@ endif()
if (YUZU_USE_PRECOMPILED_HEADERS)
target_precompile_headers(yuzu-cmd PRIVATE precompiled_headers.h)
endif()
+
+create_target_directory_groups(yuzu-cmd)