aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpineappleEA <pineaea@gmail.com>2024-02-22 23:02:19 +0100
committerpineappleEA <pineaea@gmail.com>2024-02-22 23:02:19 +0100
commit89a3ee2eed96b975d2f96b73acf0eb4c69d378c7 (patch)
tree834c41a7e200298234ddd6c6a4f08b3dc8b14575
parentcb22e3fb4290a45f346f9ecfda429e57f015ea4c (diff)
early-access version 4160EA-4160
-rwxr-xr-xREADME.md2
-rwxr-xr-xsrc/CMakeLists.txt1
-rwxr-xr-xsrc/android/app/src/main/jni/native.cpp6
-rwxr-xr-xsrc/audio_core/audio_in_manager.cpp7
-rwxr-xr-xsrc/audio_core/audio_in_manager.h4
-rwxr-xr-xsrc/audio_core/device/audio_buffers.h4
-rwxr-xr-xsrc/audio_core/opus/decoder.cpp6
-rwxr-xr-xsrc/audio_core/opus/decoder.h6
-rwxr-xr-xsrc/audio_core/opus/decoder_manager.cpp18
-rwxr-xr-xsrc/audio_core/opus/decoder_manager.h16
-rwxr-xr-xsrc/audio_core/opus/hardware_opus.cpp13
-rwxr-xr-xsrc/audio_core/opus/hardware_opus.h6
-rwxr-xr-xsrc/audio_core/opus/parameters.h4
-rwxr-xr-xsrc/audio_core/renderer/audio_device.cpp14
-rwxr-xr-xsrc/audio_core/renderer/audio_device.h6
-rwxr-xr-xsrc/audio_core/renderer/audio_renderer.cpp7
-rwxr-xr-xsrc/audio_core/renderer/audio_renderer.h4
-rwxr-xr-xsrc/audio_core/renderer/behavior/info_updater.cpp2
-rwxr-xr-xsrc/audio_core/renderer/behavior/info_updater.h10
-rwxr-xr-xsrc/audio_core/renderer/memory/pool_mapper.cpp18
-rwxr-xr-xsrc/audio_core/renderer/memory/pool_mapper.h14
-rwxr-xr-xsrc/audio_core/renderer/system.cpp10
-rwxr-xr-xsrc/audio_core/renderer/system.h8
-rwxr-xr-xsrc/common/string_util.cpp4
-rwxr-xr-xsrc/common/string_util.h1
-rwxr-xr-xsrc/core/CMakeLists.txt80
-rwxr-xr-xsrc/core/file_sys/fs_save_data_types.h175
-rwxr-xr-xsrc/core/file_sys/savedata_factory.cpp90
-rwxr-xr-xsrc/core/file_sys/savedata_factory.h68
-rwxr-xr-xsrc/core/hle/service/am/service/application_functions.cpp6
-rwxr-xr-xsrc/core/hle/service/audio/audio.cpp28
-rwxr-xr-xsrc/core/hle/service/audio/audio_controller.cpp31
-rwxr-xr-xsrc/core/hle/service/audio/audio_controller.h1
-rwxr-xr-xsrc/core/hle/service/audio/audio_device.cpp163
-rwxr-xr-xsrc/core/hle/service/audio/audio_device.h58
-rwxr-xr-xsrc/core/hle/service/audio/audio_in.cpp146
-rwxr-xr-xsrc/core/hle/service/audio/audio_in.h53
-rwxr-xr-xsrc/core/hle/service/audio/audio_in_manager.cpp125
-rwxr-xr-xsrc/core/hle/service/audio/audio_in_manager.h57
-rwxr-xr-xsrc/core/hle/service/audio/audio_out.cpp146
-rwxr-xr-xsrc/core/hle/service/audio/audio_out.h58
-rwxr-xr-xsrc/core/hle/service/audio/audio_out_manager.cpp101
-rwxr-xr-xsrc/core/hle/service/audio/audio_out_manager.h44
-rwxr-xr-xsrc/core/hle/service/audio/audio_renderer.cpp139
-rwxr-xr-xsrc/core/hle/service/audio/audio_renderer.h54
-rwxr-xr-xsrc/core/hle/service/audio/audio_renderer_manager.cpp104
-rwxr-xr-xsrc/core/hle/service/audio/audio_renderer_manager.h37
-rwxr-xr-xsrc/core/hle/service/audio/final_output_recorder_manager.cpp43
-rwxr-xr-xsrc/core/hle/service/audio/final_output_recorder_manager.h20
-rwxr-xr-xsrc/core/hle/service/audio/final_output_recorder_manager_for_applet.cpp22
-rwxr-xr-xsrc/core/hle/service/audio/final_output_recorder_manager_for_applet.h21
-rwxr-xr-xsrc/core/hle/service/audio/hardware_opus_decoder.cpp145
-rwxr-xr-xsrc/core/hle/service/audio/hardware_opus_decoder.h63
-rwxr-xr-xsrc/core/hle/service/audio/hardware_opus_decoder_manager.cpp156
-rwxr-xr-xsrc/core/hle/service/audio/hardware_opus_decoder_manager.h53
-rwxr-xr-xsrc/core/hle/service/cmif_serialization.h2
-rwxr-xr-xsrc/core/hle/service/filesystem/fsp/fs_i_filesystem.h2
-rwxr-xr-xsrc/core/hle/service/filesystem/fsp/fs_i_multi_commit_manager.cpp33
-rwxr-xr-xsrc/core/hle/service/filesystem/fsp/fs_i_multi_commit_manager.h23
-rwxr-xr-xsrc/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp161
-rwxr-xr-xsrc/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.h50
-rwxr-xr-xsrc/core/hle/service/filesystem/fsp/fs_i_storage.cpp47
-rwxr-xr-xsrc/core/hle/service/filesystem/fsp/fs_i_storage.h7
-rwxr-xr-xsrc/core/hle/service/filesystem/fsp/fsp_srv.cpp589
-rwxr-xr-xsrc/core/hle/service/filesystem/fsp/fsp_srv.h72
-rwxr-xr-xsrc/core/hle/service/filesystem/fsp/fsp_types.h34
-rwxr-xr-xsrc/core/hle/service/olsc/daemon_controller.cpp40
-rwxr-xr-xsrc/core/hle/service/olsc/daemon_controller.h20
-rwxr-xr-xsrc/core/hle/service/olsc/native_handle_holder.cpp28
-rwxr-xr-xsrc/core/hle/service/olsc/native_handle_holder.h22
-rwxr-xr-xsrc/core/hle/service/olsc/olsc.cpp223
-rwxr-xr-xsrc/core/hle/service/olsc/olsc_service_for_application.cpp63
-rwxr-xr-xsrc/core/hle/service/olsc/olsc_service_for_application.h23
-rwxr-xr-xsrc/core/hle/service/olsc/olsc_service_for_system_service.cpp117
-rwxr-xr-xsrc/core/hle/service/olsc/olsc_service_for_system_service.h27
-rwxr-xr-xsrc/core/hle/service/olsc/remote_storage_controller.cpp54
-rwxr-xr-xsrc/core/hle/service/olsc/remote_storage_controller.h19
-rwxr-xr-xsrc/core/hle/service/olsc/transfer_task_list_controller.cpp55
-rwxr-xr-xsrc/core/hle/service/olsc/transfer_task_list_controller.h20
-rwxr-xr-xsrc/core/hle/service/pctl/parental_control_service.cpp434
-rwxr-xr-xsrc/core/hle/service/pctl/parental_control_service.h86
-rwxr-xr-xsrc/core/hle/service/pctl/parental_control_service_factory.cpp40
-rwxr-xr-xsrc/core/hle/service/pctl/parental_control_service_factory.h31
-rwxr-xr-xsrc/core/hle/service/pctl/pctl.cpp27
-rwxr-xr-xsrc/core/hle/service/pctl/pctl.h9
-rwxr-xr-xsrc/core/hle/service/pctl/pctl_results.h15
-rwxr-xr-xsrc/core/hle/service/pctl/pctl_types.h43
-rwxr-xr-xsrc/core/hle/service/psc/ovln/ovln_types.h21
-rwxr-xr-xsrc/core/hle/service/psc/ovln/receiver.cpp24
-rwxr-xr-xsrc/core/hle/service/psc/ovln/receiver.h16
-rwxr-xr-xsrc/core/hle/service/psc/ovln/receiver_service.cpp28
-rwxr-xr-xsrc/core/hle/service/psc/ovln/receiver_service.h22
-rwxr-xr-xsrc/core/hle/service/psc/ovln/sender.cpp32
-rwxr-xr-xsrc/core/hle/service/psc/ovln/sender.h21
-rwxr-xr-xsrc/core/hle/service/psc/ovln/sender_service.cpp30
-rwxr-xr-xsrc/core/hle/service/psc/ovln/sender_service.h23
-rwxr-xr-xsrc/core/hle/service/psc/pm_control.cpp28
-rwxr-xr-xsrc/core/hle/service/psc/pm_control.h16
-rwxr-xr-xsrc/core/hle/service/psc/pm_module.cpp24
-rwxr-xr-xsrc/core/hle/service/psc/pm_module.h16
-rwxr-xr-xsrc/core/hle/service/psc/pm_service.cpp28
-rwxr-xr-xsrc/core/hle/service/psc/pm_service.h22
-rwxr-xr-xsrc/core/hle/service/psc/psc.cpp71
-rwxr-xr-xsrc/core/hle/service/psc/psc.h4
-rwxr-xr-xsrc/core/hle/service/services.cpp2
-rwxr-xr-xsrc/yuzu/main.cpp10
106 files changed, 4261 insertions, 1071 deletions
diff --git a/README.md b/README.md
index 450176b9a..ee5fb89d9 100755
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
1yuzu emulator early access 1yuzu emulator early access
2============= 2=============
3 3
4This is the source code for early-access 4158. 4This is the source code for early-access 4160.
5 5
6## Legal Notice 6## Legal Notice
7 7
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 10aa8ad6e..4dec00709 100755
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -121,6 +121,7 @@ else()
121 -Wno-attributes 121 -Wno-attributes
122 -Wno-invalid-offsetof 122 -Wno-invalid-offsetof
123 -Wno-unused-parameter 123 -Wno-unused-parameter
124 -Wno-missing-field-initializers
124 ) 125 )
125 126
126 if (CMAKE_CXX_COMPILER_ID MATCHES Clang) # Clang or AppleClang 127 if (CMAKE_CXX_COMPILER_ID MATCHES Clang) # Clang or AppleClang
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index 1226219ad..5d484a85e 100755
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -668,7 +668,7 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeEmptyUserDirectory(JNIEnv*
668 ASSERT(user_id); 668 ASSERT(user_id);
669 669
670 const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath( 670 const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath(
671 {}, vfs_nand_dir, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData, 1, 671 {}, vfs_nand_dir, FileSys::SaveDataSpaceId::User, FileSys::SaveDataType::Account, 1,
672 user_id->AsU128(), 0); 672 user_id->AsU128(), 0);
673 673
674 const auto full_path = Common::FS::ConcatPathSafe(nand_dir, user_save_data_path); 674 const auto full_path = Common::FS::ConcatPathSafe(nand_dir, user_save_data_path);
@@ -836,8 +836,8 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject j
836 FileSys::OpenMode::Read); 836 FileSys::OpenMode::Read);
837 837
838 const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath( 838 const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath(
839 {}, vfsNandDir, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData, 839 {}, vfsNandDir, FileSys::SaveDataSpaceId::User, FileSys::SaveDataType::Account, program_id,
840 program_id, user_id->AsU128(), 0); 840 user_id->AsU128(), 0);
841 return Common::Android::ToJString(env, user_save_data_path); 841 return Common::Android::ToJString(env, user_save_data_path);
842} 842}
843 843
diff --git a/src/audio_core/audio_in_manager.cpp b/src/audio_core/audio_in_manager.cpp
index f3f29d327..c6aa60d7f 100755
--- a/src/audio_core/audio_in_manager.cpp
+++ b/src/audio_core/audio_in_manager.cpp
@@ -73,16 +73,15 @@ void Manager::BufferReleaseAndRegister() {
73 } 73 }
74} 74}
75 75
76u32 Manager::GetDeviceNames(std::vector<Renderer::AudioDevice::AudioDeviceName>& names, 76u32 Manager::GetDeviceNames(std::span<Renderer::AudioDevice::AudioDeviceName> names,
77 [[maybe_unused]] const u32 max_count,
78 [[maybe_unused]] const bool filter) { 77 [[maybe_unused]] const bool filter) {
79 std::scoped_lock l{mutex}; 78 std::scoped_lock l{mutex};
80 79
81 LinkToManager(); 80 LinkToManager();
82 81
83 auto input_devices{Sink::GetDeviceListForSink(Settings::values.sink_id.GetValue(), true)}; 82 auto input_devices{Sink::GetDeviceListForSink(Settings::values.sink_id.GetValue(), true)};
84 if (input_devices.size() > 1) { 83 if (!input_devices.empty() && !names.empty()) {
85 names.emplace_back("Uac"); 84 names[0] = Renderer::AudioDevice::AudioDeviceName("Uac");
86 return 1; 85 return 1;
87 } 86 }
88 return 0; 87 return 0;
diff --git a/src/audio_core/audio_in_manager.h b/src/audio_core/audio_in_manager.h
index 601fa570b..0f89d76b0 100755
--- a/src/audio_core/audio_in_manager.h
+++ b/src/audio_core/audio_in_manager.h
@@ -60,13 +60,11 @@ public:
60 * Get a list of audio in device names. 60 * Get a list of audio in device names.
61 * 61 *
62 * @param names - Output container to write names to. 62 * @param names - Output container to write names to.
63 * @param max_count - Maximum number of device names to write. Unused
64 * @param filter - Should the list be filtered? Unused. 63 * @param filter - Should the list be filtered? Unused.
65 * 64 *
66 * @return Number of names written. 65 * @return Number of names written.
67 */ 66 */
68 u32 GetDeviceNames(std::vector<Renderer::AudioDevice::AudioDeviceName>& names, u32 max_count, 67 u32 GetDeviceNames(std::span<Renderer::AudioDevice::AudioDeviceName> names, bool filter);
69 bool filter);
70 68
71 /// Core system 69 /// Core system
72 Core::System& system; 70 Core::System& system;
diff --git a/src/audio_core/device/audio_buffers.h b/src/audio_core/device/audio_buffers.h
index 940c8a2b6..25273652d 100755
--- a/src/audio_core/device/audio_buffers.h
+++ b/src/audio_core/device/audio_buffers.h
@@ -146,11 +146,11 @@ public:
146 break; 146 break;
147 } 147 }
148 148
149 tags[released++] = tag;
150
151 if (released >= tags.size()) { 149 if (released >= tags.size()) {
152 break; 150 break;
153 } 151 }
152
153 tags[released++] = tag;
154 } 154 }
155 155
156 return released; 156 return released;
diff --git a/src/audio_core/opus/decoder.cpp b/src/audio_core/opus/decoder.cpp
index b7fed5304..0c110cbeb 100755
--- a/src/audio_core/opus/decoder.cpp
+++ b/src/audio_core/opus/decoder.cpp
@@ -28,8 +28,8 @@ OpusDecoder::~OpusDecoder() {
28 } 28 }
29} 29}
30 30
31Result OpusDecoder::Initialize(OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory, 31Result OpusDecoder::Initialize(const OpusParametersEx& params,
32 u64 transfer_memory_size) { 32 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) {
33 auto frame_size{params.use_large_frame_size ? 5760 : 1920}; 33 auto frame_size{params.use_large_frame_size ? 5760 : 1920};
34 shared_buffer_size = transfer_memory_size; 34 shared_buffer_size = transfer_memory_size;
35 shared_buffer = std::make_unique<u8[]>(shared_buffer_size); 35 shared_buffer = std::make_unique<u8[]>(shared_buffer_size);
@@ -59,7 +59,7 @@ Result OpusDecoder::Initialize(OpusParametersEx& params, Kernel::KTransferMemory
59 R_SUCCEED(); 59 R_SUCCEED();
60} 60}
61 61
62Result OpusDecoder::Initialize(OpusMultiStreamParametersEx& params, 62Result OpusDecoder::Initialize(const OpusMultiStreamParametersEx& params,
63 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) { 63 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) {
64 auto frame_size{params.use_large_frame_size ? 5760 : 1920}; 64 auto frame_size{params.use_large_frame_size ? 5760 : 1920};
65 shared_buffer_size = transfer_memory_size; 65 shared_buffer_size = transfer_memory_size;
diff --git a/src/audio_core/opus/decoder.h b/src/audio_core/opus/decoder.h
index fd728958a..1b8c257d4 100755
--- a/src/audio_core/opus/decoder.h
+++ b/src/audio_core/opus/decoder.h
@@ -22,10 +22,10 @@ public:
22 explicit OpusDecoder(Core::System& system, HardwareOpus& hardware_opus_); 22 explicit OpusDecoder(Core::System& system, HardwareOpus& hardware_opus_);
23 ~OpusDecoder(); 23 ~OpusDecoder();
24 24
25 Result Initialize(OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory, 25 Result Initialize(const OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory,
26 u64 transfer_memory_size);
27 Result Initialize(OpusMultiStreamParametersEx& params, Kernel::KTransferMemory* transfer_memory,
28 u64 transfer_memory_size); 26 u64 transfer_memory_size);
27 Result Initialize(const OpusMultiStreamParametersEx& params,
28 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size);
29 Result DecodeInterleaved(u32* out_data_size, u64* out_time_taken, u32* out_sample_count, 29 Result DecodeInterleaved(u32* out_data_size, u64* out_time_taken, u32* out_sample_count,
30 std::span<const u8> input_data, std::span<u8> output_data, bool reset); 30 std::span<const u8> input_data, std::span<u8> output_data, bool reset);
31 Result SetContext([[maybe_unused]] std::span<const u8> context); 31 Result SetContext([[maybe_unused]] std::span<const u8> context);
diff --git a/src/audio_core/opus/decoder_manager.cpp b/src/audio_core/opus/decoder_manager.cpp
index 1464880a1..89eec1298 100755
--- a/src/audio_core/opus/decoder_manager.cpp
+++ b/src/audio_core/opus/decoder_manager.cpp
@@ -38,7 +38,7 @@ OpusDecoderManager::OpusDecoderManager(Core::System& system_)
38 } 38 }
39} 39}
40 40
41Result OpusDecoderManager::GetWorkBufferSize(OpusParameters& params, u64& out_size) { 41Result OpusDecoderManager::GetWorkBufferSize(const OpusParameters& params, u32& out_size) {
42 OpusParametersEx ex{ 42 OpusParametersEx ex{
43 .sample_rate = params.sample_rate, 43 .sample_rate = params.sample_rate,
44 .channel_count = params.channel_count, 44 .channel_count = params.channel_count,
@@ -47,11 +47,11 @@ Result OpusDecoderManager::GetWorkBufferSize(OpusParameters& params, u64& out_si
47 R_RETURN(GetWorkBufferSizeExEx(ex, out_size)); 47 R_RETURN(GetWorkBufferSizeExEx(ex, out_size));
48} 48}
49 49
50Result OpusDecoderManager::GetWorkBufferSizeEx(OpusParametersEx& params, u64& out_size) { 50Result OpusDecoderManager::GetWorkBufferSizeEx(const OpusParametersEx& params, u32& out_size) {
51 R_RETURN(GetWorkBufferSizeExEx(params, out_size)); 51 R_RETURN(GetWorkBufferSizeExEx(params, out_size));
52} 52}
53 53
54Result OpusDecoderManager::GetWorkBufferSizeExEx(OpusParametersEx& params, u64& out_size) { 54Result OpusDecoderManager::GetWorkBufferSizeExEx(const OpusParametersEx& params, u32& out_size) {
55 R_UNLESS(IsValidChannelCount(params.channel_count), ResultInvalidOpusChannelCount); 55 R_UNLESS(IsValidChannelCount(params.channel_count), ResultInvalidOpusChannelCount);
56 R_UNLESS(IsValidSampleRate(params.sample_rate), ResultInvalidOpusSampleRate); 56 R_UNLESS(IsValidSampleRate(params.sample_rate), ResultInvalidOpusSampleRate);
57 57
@@ -63,8 +63,8 @@ Result OpusDecoderManager::GetWorkBufferSizeExEx(OpusParametersEx& params, u64&
63 R_SUCCEED(); 63 R_SUCCEED();
64} 64}
65 65
66Result OpusDecoderManager::GetWorkBufferSizeForMultiStream(OpusMultiStreamParameters& params, 66Result OpusDecoderManager::GetWorkBufferSizeForMultiStream(const OpusMultiStreamParameters& params,
67 u64& out_size) { 67 u32& out_size) {
68 OpusMultiStreamParametersEx ex{ 68 OpusMultiStreamParametersEx ex{
69 .sample_rate = params.sample_rate, 69 .sample_rate = params.sample_rate,
70 .channel_count = params.channel_count, 70 .channel_count = params.channel_count,
@@ -76,13 +76,13 @@ Result OpusDecoderManager::GetWorkBufferSizeForMultiStream(OpusMultiStreamParame
76 R_RETURN(GetWorkBufferSizeForMultiStreamExEx(ex, out_size)); 76 R_RETURN(GetWorkBufferSizeForMultiStreamExEx(ex, out_size));
77} 77}
78 78
79Result OpusDecoderManager::GetWorkBufferSizeForMultiStreamEx(OpusMultiStreamParametersEx& params, 79Result OpusDecoderManager::GetWorkBufferSizeForMultiStreamEx(
80 u64& out_size) { 80 const OpusMultiStreamParametersEx& params, u32& out_size) {
81 R_RETURN(GetWorkBufferSizeForMultiStreamExEx(params, out_size)); 81 R_RETURN(GetWorkBufferSizeForMultiStreamExEx(params, out_size));
82} 82}
83 83
84Result OpusDecoderManager::GetWorkBufferSizeForMultiStreamExEx(OpusMultiStreamParametersEx& params, 84Result OpusDecoderManager::GetWorkBufferSizeForMultiStreamExEx(
85 u64& out_size) { 85 const OpusMultiStreamParametersEx& params, u32& out_size) {
86 R_UNLESS(IsValidMultiStreamChannelCount(params.channel_count), ResultInvalidOpusChannelCount); 86 R_UNLESS(IsValidMultiStreamChannelCount(params.channel_count), ResultInvalidOpusChannelCount);
87 R_UNLESS(IsValidSampleRate(params.sample_rate), ResultInvalidOpusSampleRate); 87 R_UNLESS(IsValidSampleRate(params.sample_rate), ResultInvalidOpusSampleRate);
88 R_UNLESS(IsValidStreamCount(params.channel_count, params.total_stream_count, 88 R_UNLESS(IsValidStreamCount(params.channel_count, params.total_stream_count,
diff --git a/src/audio_core/opus/decoder_manager.h b/src/audio_core/opus/decoder_manager.h
index 70ebc4bab..8f6876d5c 100755
--- a/src/audio_core/opus/decoder_manager.h
+++ b/src/audio_core/opus/decoder_manager.h
@@ -22,17 +22,19 @@ public:
22 return hardware_opus; 22 return hardware_opus;
23 } 23 }
24 24
25 Result GetWorkBufferSize(OpusParameters& params, u64& out_size); 25 Result GetWorkBufferSize(const OpusParameters& params, u32& out_size);
26 Result GetWorkBufferSizeEx(OpusParametersEx& params, u64& out_size); 26 Result GetWorkBufferSizeEx(const OpusParametersEx& params, u32& out_size);
27 Result GetWorkBufferSizeExEx(OpusParametersEx& params, u64& out_size); 27 Result GetWorkBufferSizeExEx(const OpusParametersEx& params, u32& out_size);
28 Result GetWorkBufferSizeForMultiStream(OpusMultiStreamParameters& params, u64& out_size); 28 Result GetWorkBufferSizeForMultiStream(const OpusMultiStreamParameters& params, u32& out_size);
29 Result GetWorkBufferSizeForMultiStreamEx(OpusMultiStreamParametersEx& params, u64& out_size); 29 Result GetWorkBufferSizeForMultiStreamEx(const OpusMultiStreamParametersEx& params,
30 Result GetWorkBufferSizeForMultiStreamExEx(OpusMultiStreamParametersEx& params, u64& out_size); 30 u32& out_size);
31 Result GetWorkBufferSizeForMultiStreamExEx(const OpusMultiStreamParametersEx& params,
32 u32& out_size);
31 33
32private: 34private:
33 Core::System& system; 35 Core::System& system;
34 HardwareOpus hardware_opus; 36 HardwareOpus hardware_opus;
35 std::array<u64, MaxChannels> required_workbuffer_sizes{}; 37 std::array<u32, MaxChannels> required_workbuffer_sizes{};
36}; 38};
37 39
38} // namespace AudioCore::OpusDecoder 40} // namespace AudioCore::OpusDecoder
diff --git a/src/audio_core/opus/hardware_opus.cpp b/src/audio_core/opus/hardware_opus.cpp
index 5ff71ab2d..30805f4a3 100755
--- a/src/audio_core/opus/hardware_opus.cpp
+++ b/src/audio_core/opus/hardware_opus.cpp
@@ -42,7 +42,7 @@ HardwareOpus::HardwareOpus(Core::System& system_)
42 opus_decoder.SetSharedMemory(shared_memory); 42 opus_decoder.SetSharedMemory(shared_memory);
43} 43}
44 44
45u64 HardwareOpus::GetWorkBufferSize(u32 channel) { 45u32 HardwareOpus::GetWorkBufferSize(u32 channel) {
46 if (!opus_decoder.IsRunning()) { 46 if (!opus_decoder.IsRunning()) {
47 return 0; 47 return 0;
48 } 48 }
@@ -55,10 +55,10 @@ u64 HardwareOpus::GetWorkBufferSize(u32 channel) {
55 ADSP::OpusDecoder::Message::GetWorkBufferSizeOK, msg); 55 ADSP::OpusDecoder::Message::GetWorkBufferSizeOK, msg);
56 return 0; 56 return 0;
57 } 57 }
58 return shared_memory.dsp_return_data[0]; 58 return static_cast<u32>(shared_memory.dsp_return_data[0]);
59} 59}
60 60
61u64 HardwareOpus::GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 stereo_stream_count) { 61u32 HardwareOpus::GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 stereo_stream_count) {
62 std::scoped_lock l{mutex}; 62 std::scoped_lock l{mutex};
63 shared_memory.host_send_data[0] = total_stream_count; 63 shared_memory.host_send_data[0] = total_stream_count;
64 shared_memory.host_send_data[1] = stereo_stream_count; 64 shared_memory.host_send_data[1] = stereo_stream_count;
@@ -70,7 +70,7 @@ u64 HardwareOpus::GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 st
70 ADSP::OpusDecoder::Message::GetWorkBufferSizeForMultiStreamOK, msg); 70 ADSP::OpusDecoder::Message::GetWorkBufferSizeForMultiStreamOK, msg);
71 return 0; 71 return 0;
72 } 72 }
73 return shared_memory.dsp_return_data[0]; 73 return static_cast<u32>(shared_memory.dsp_return_data[0]);
74} 74}
75 75
76Result HardwareOpus::InitializeDecodeObject(u32 sample_rate, u32 channel_count, void* buffer, 76Result HardwareOpus::InitializeDecodeObject(u32 sample_rate, u32 channel_count, void* buffer,
@@ -94,8 +94,9 @@ Result HardwareOpus::InitializeDecodeObject(u32 sample_rate, u32 channel_count,
94 94
95Result HardwareOpus::InitializeMultiStreamDecodeObject(u32 sample_rate, u32 channel_count, 95Result HardwareOpus::InitializeMultiStreamDecodeObject(u32 sample_rate, u32 channel_count,
96 u32 total_stream_count, 96 u32 total_stream_count,
97 u32 stereo_stream_count, void* mappings, 97 u32 stereo_stream_count,
98 void* buffer, u64 buffer_size) { 98 const void* mappings, void* buffer,
99 u64 buffer_size) {
99 std::scoped_lock l{mutex}; 100 std::scoped_lock l{mutex};
100 shared_memory.host_send_data[0] = (u64)buffer; 101 shared_memory.host_send_data[0] = (u64)buffer;
101 shared_memory.host_send_data[1] = buffer_size; 102 shared_memory.host_send_data[1] = buffer_size;
diff --git a/src/audio_core/opus/hardware_opus.h b/src/audio_core/opus/hardware_opus.h
index b10184baa..caa746840 100755
--- a/src/audio_core/opus/hardware_opus.h
+++ b/src/audio_core/opus/hardware_opus.h
@@ -16,14 +16,14 @@ class HardwareOpus {
16public: 16public:
17 HardwareOpus(Core::System& system); 17 HardwareOpus(Core::System& system);
18 18
19 u64 GetWorkBufferSize(u32 channel); 19 u32 GetWorkBufferSize(u32 channel);
20 u64 GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 stereo_stream_count); 20 u32 GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 stereo_stream_count);
21 21
22 Result InitializeDecodeObject(u32 sample_rate, u32 channel_count, void* buffer, 22 Result InitializeDecodeObject(u32 sample_rate, u32 channel_count, void* buffer,
23 u64 buffer_size); 23 u64 buffer_size);
24 Result InitializeMultiStreamDecodeObject(u32 sample_rate, u32 channel_count, 24 Result InitializeMultiStreamDecodeObject(u32 sample_rate, u32 channel_count,
25 u32 totaL_stream_count, u32 stereo_stream_count, 25 u32 totaL_stream_count, u32 stereo_stream_count,
26 void* mappings, void* buffer, u64 buffer_size); 26 const void* mappings, void* buffer, u64 buffer_size);
27 Result ShutdownDecodeObject(void* buffer, u64 buffer_size); 27 Result ShutdownDecodeObject(void* buffer, u64 buffer_size);
28 Result ShutdownMultiStreamDecodeObject(void* buffer, u64 buffer_size); 28 Result ShutdownMultiStreamDecodeObject(void* buffer, u64 buffer_size);
29 Result DecodeInterleaved(u32& out_sample_count, void* output_data, u64 output_data_size, 29 Result DecodeInterleaved(u32& out_sample_count, void* output_data, u64 output_data_size,
diff --git a/src/audio_core/opus/parameters.h b/src/audio_core/opus/parameters.h
index 4c54b2825..47c418b9f 100755
--- a/src/audio_core/opus/parameters.h
+++ b/src/audio_core/opus/parameters.h
@@ -20,7 +20,7 @@ struct OpusParametersEx {
20 /* 0x00 */ u32 sample_rate; 20 /* 0x00 */ u32 sample_rate;
21 /* 0x04 */ u32 channel_count; 21 /* 0x04 */ u32 channel_count;
22 /* 0x08 */ bool use_large_frame_size; 22 /* 0x08 */ bool use_large_frame_size;
23 /* 0x09 */ INSERT_PADDING_BYTES(7); 23 /* 0x09 */ INSERT_PADDING_BYTES_NOINIT(7);
24}; // size = 0x10 24}; // size = 0x10
25static_assert(sizeof(OpusParametersEx) == 0x10, "OpusParametersEx has the wrong size!"); 25static_assert(sizeof(OpusParametersEx) == 0x10, "OpusParametersEx has the wrong size!");
26 26
@@ -40,7 +40,7 @@ struct OpusMultiStreamParametersEx {
40 /* 0x08 */ u32 total_stream_count; 40 /* 0x08 */ u32 total_stream_count;
41 /* 0x0C */ u32 stereo_stream_count; 41 /* 0x0C */ u32 stereo_stream_count;
42 /* 0x10 */ bool use_large_frame_size; 42 /* 0x10 */ bool use_large_frame_size;
43 /* 0x11 */ INSERT_PADDING_BYTES(7); 43 /* 0x11 */ INSERT_PADDING_BYTES_NOINIT(7);
44 /* 0x18 */ std::array<u8, OpusStreamCountMax + 1> mappings; 44 /* 0x18 */ std::array<u8, OpusStreamCountMax + 1> mappings;
45}; // size = 0x118 45}; // size = 0x118
46static_assert(sizeof(OpusMultiStreamParametersEx) == 0x118, 46static_assert(sizeof(OpusMultiStreamParametersEx) == 0x118,
diff --git a/src/audio_core/renderer/audio_device.cpp b/src/audio_core/renderer/audio_device.cpp
index 7b329c880..27e311dbf 100755
--- a/src/audio_core/renderer/audio_device.cpp
+++ b/src/audio_core/renderer/audio_device.cpp
@@ -36,8 +36,7 @@ AudioDevice::AudioDevice(Core::System& system, const u64 applet_resource_user_id
36 : output_sink{system.AudioCore().GetOutputSink()}, 36 : output_sink{system.AudioCore().GetOutputSink()},
37 applet_resource_user_id{applet_resource_user_id_}, user_revision{revision} {} 37 applet_resource_user_id{applet_resource_user_id_}, user_revision{revision} {}
38 38
39u32 AudioDevice::ListAudioDeviceName(std::vector<AudioDeviceName>& out_buffer, 39u32 AudioDevice::ListAudioDeviceName(std::span<AudioDeviceName> out_buffer) const {
40 const size_t max_count) const {
41 std::span<const AudioDeviceName> names{}; 40 std::span<const AudioDeviceName> names{};
42 41
43 if (CheckFeatureSupported(SupportTags::AudioUsbDeviceOutput, user_revision)) { 42 if (CheckFeatureSupported(SupportTags::AudioUsbDeviceOutput, user_revision)) {
@@ -46,19 +45,18 @@ u32 AudioDevice::ListAudioDeviceName(std::vector<AudioDeviceName>& out_buffer,
46 names = device_names; 45 names = device_names;
47 } 46 }
48 47
49 const u32 out_count{static_cast<u32>(std::min(max_count, names.size()))}; 48 const u32 out_count{static_cast<u32>(std::min(out_buffer.size(), names.size()))};
50 for (u32 i = 0; i < out_count; i++) { 49 for (u32 i = 0; i < out_count; i++) {
51 out_buffer.push_back(names[i]); 50 out_buffer[i] = names[i];
52 } 51 }
53 return out_count; 52 return out_count;
54} 53}
55 54
56u32 AudioDevice::ListAudioOutputDeviceName(std::vector<AudioDeviceName>& out_buffer, 55u32 AudioDevice::ListAudioOutputDeviceName(std::span<AudioDeviceName> out_buffer) const {
57 const size_t max_count) const { 56 const u32 out_count{static_cast<u32>(std::min(out_buffer.size(), output_device_names.size()))};
58 const u32 out_count{static_cast<u32>(std::min(max_count, output_device_names.size()))};
59 57
60 for (u32 i = 0; i < out_count; i++) { 58 for (u32 i = 0; i < out_count; i++) {
61 out_buffer.push_back(output_device_names[i]); 59 out_buffer[i] = output_device_names[i];
62 } 60 }
63 return out_count; 61 return out_count;
64} 62}
diff --git a/src/audio_core/renderer/audio_device.h b/src/audio_core/renderer/audio_device.h
index 39f0ef591..6e219ca35 100755
--- a/src/audio_core/renderer/audio_device.h
+++ b/src/audio_core/renderer/audio_device.h
@@ -36,20 +36,18 @@ public:
36 * Get a list of the available output devices. 36 * Get a list of the available output devices.
37 * 37 *
38 * @param out_buffer - Output buffer to write the available device names. 38 * @param out_buffer - Output buffer to write the available device names.
39 * @param max_count - Maximum number of devices to write (count of out_buffer).
40 * @return Number of device names written. 39 * @return Number of device names written.
41 */ 40 */
42 u32 ListAudioDeviceName(std::vector<AudioDeviceName>& out_buffer, size_t max_count) const; 41 u32 ListAudioDeviceName(std::span<AudioDeviceName> out_buffer) const;
43 42
44 /** 43 /**
45 * Get a list of the available output devices. 44 * Get a list of the available output devices.
46 * Different to above somehow... 45 * Different to above somehow...
47 * 46 *
48 * @param out_buffer - Output buffer to write the available device names. 47 * @param out_buffer - Output buffer to write the available device names.
49 * @param max_count - Maximum number of devices to write (count of out_buffer).
50 * @return Number of device names written. 48 * @return Number of device names written.
51 */ 49 */
52 u32 ListAudioOutputDeviceName(std::vector<AudioDeviceName>& out_buffer, size_t max_count) const; 50 u32 ListAudioOutputDeviceName(std::span<AudioDeviceName> out_buffer) const;
53 51
54 /** 52 /**
55 * Set the volume of all streams in the backend sink. 53 * Set the volume of all streams in the backend sink.
diff --git a/src/audio_core/renderer/audio_renderer.cpp b/src/audio_core/renderer/audio_renderer.cpp
index bf265c83a..defb09919 100755
--- a/src/audio_core/renderer/audio_renderer.cpp
+++ b/src/audio_core/renderer/audio_renderer.cpp
@@ -17,9 +17,8 @@ Renderer::Renderer(Core::System& system_, Manager& manager_, Kernel::KEvent* ren
17 17
18Result Renderer::Initialize(const AudioRendererParameterInternal& params, 18Result Renderer::Initialize(const AudioRendererParameterInternal& params,
19 Kernel::KTransferMemory* transfer_memory, 19 Kernel::KTransferMemory* transfer_memory,
20 const u64 transfer_memory_size, const u32 process_handle, 20 const u64 transfer_memory_size, Kernel::KProcess* process_handle,
21 Kernel::KProcess& process, const u64 applet_resource_user_id, 21 const u64 applet_resource_user_id, const s32 session_id) {
22 const s32 session_id) {
23 if (params.execution_mode == ExecutionMode::Auto) { 22 if (params.execution_mode == ExecutionMode::Auto) {
24 if (!manager.AddSystem(system)) { 23 if (!manager.AddSystem(system)) {
25 LOG_ERROR(Service_Audio, 24 LOG_ERROR(Service_Audio,
@@ -30,7 +29,7 @@ Result Renderer::Initialize(const AudioRendererParameterInternal& params,
30 } 29 }
31 30
32 initialized = true; 31 initialized = true;
33 system.Initialize(params, transfer_memory, transfer_memory_size, process_handle, process, 32 system.Initialize(params, transfer_memory, transfer_memory_size, process_handle,
34 applet_resource_user_id, session_id); 33 applet_resource_user_id, session_id);
35 34
36 return ResultSuccess; 35 return ResultSuccess;
diff --git a/src/audio_core/renderer/audio_renderer.h b/src/audio_core/renderer/audio_renderer.h
index 390e39f1d..61c62532b 100755
--- a/src/audio_core/renderer/audio_renderer.h
+++ b/src/audio_core/renderer/audio_renderer.h
@@ -38,14 +38,14 @@ public:
38 * @param params - Input parameters to initialize the system with. 38 * @param params - Input parameters to initialize the system with.
39 * @param transfer_memory - Game-supplied memory for all workbuffers. Unused. 39 * @param transfer_memory - Game-supplied memory for all workbuffers. Unused.
40 * @param transfer_memory_size - Size of the transfer memory. Unused. 40 * @param transfer_memory_size - Size of the transfer memory. Unused.
41 * @param process_handle - Process handle, also used for memory. Unused. 41 * @param process_handle - Process handle, also used for memory.
42 * @param applet_resource_user_id - Applet id for this renderer. Unused. 42 * @param applet_resource_user_id - Applet id for this renderer. Unused.
43 * @param session_id - Session id of this renderer. 43 * @param session_id - Session id of this renderer.
44 * @return Result code. 44 * @return Result code.
45 */ 45 */
46 Result Initialize(const AudioRendererParameterInternal& params, 46 Result Initialize(const AudioRendererParameterInternal& params,
47 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, 47 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
48 u32 process_handle, Kernel::KProcess& process, u64 applet_resource_user_id, 48 Kernel::KProcess* process_handle, u64 applet_resource_user_id,
49 s32 session_id); 49 s32 session_id);
50 50
51 /** 51 /**
diff --git a/src/audio_core/renderer/behavior/info_updater.cpp b/src/audio_core/renderer/behavior/info_updater.cpp
index 77268f4a5..ba4e29fd9 100755
--- a/src/audio_core/renderer/behavior/info_updater.cpp
+++ b/src/audio_core/renderer/behavior/info_updater.cpp
@@ -18,7 +18,7 @@
18namespace AudioCore::Renderer { 18namespace AudioCore::Renderer {
19 19
20InfoUpdater::InfoUpdater(std::span<const u8> input_, std::span<u8> output_, 20InfoUpdater::InfoUpdater(std::span<const u8> input_, std::span<u8> output_,
21 const u32 process_handle_, BehaviorInfo& behaviour_) 21 Kernel::KProcess* process_handle_, BehaviorInfo& behaviour_)
22 : input{input_.data() + sizeof(UpdateDataHeader)}, 22 : input{input_.data() + sizeof(UpdateDataHeader)},
23 input_origin{input_}, output{output_.data() + sizeof(UpdateDataHeader)}, 23 input_origin{input_}, output{output_.data() + sizeof(UpdateDataHeader)},
24 output_origin{output_}, in_header{reinterpret_cast<const UpdateDataHeader*>( 24 output_origin{output_}, in_header{reinterpret_cast<const UpdateDataHeader*>(
diff --git a/src/audio_core/renderer/behavior/info_updater.h b/src/audio_core/renderer/behavior/info_updater.h
index 38eeb0777..d46e3a48b 100755
--- a/src/audio_core/renderer/behavior/info_updater.h
+++ b/src/audio_core/renderer/behavior/info_updater.h
@@ -8,6 +8,10 @@
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/hle/service/audio/errors.h" 9#include "core/hle/service/audio/errors.h"
10 10
11namespace Kernel {
12class KProcess;
13}
14
11namespace AudioCore::Renderer { 15namespace AudioCore::Renderer {
12class BehaviorInfo; 16class BehaviorInfo;
13class VoiceContext; 17class VoiceContext;
@@ -39,8 +43,8 @@ class InfoUpdater {
39 static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has the wrong size!"); 43 static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has the wrong size!");
40 44
41public: 45public:
42 explicit InfoUpdater(std::span<const u8> input, std::span<u8> output, u32 process_handle, 46 explicit InfoUpdater(std::span<const u8> input, std::span<u8> output,
43 BehaviorInfo& behaviour); 47 Kernel::KProcess* process_handle, BehaviorInfo& behaviour);
44 48
45 /** 49 /**
46 * Update the voice channel resources. 50 * Update the voice channel resources.
@@ -197,7 +201,7 @@ private:
197 /// Expected output size, see CheckConsumedSize 201 /// Expected output size, see CheckConsumedSize
198 u64 expected_output_size; 202 u64 expected_output_size;
199 /// Unused 203 /// Unused
200 u32 process_handle; 204 Kernel::KProcess* process_handle;
201 /// Behaviour 205 /// Behaviour
202 BehaviorInfo& behaviour; 206 BehaviorInfo& behaviour;
203}; 207};
diff --git a/src/audio_core/renderer/memory/pool_mapper.cpp b/src/audio_core/renderer/memory/pool_mapper.cpp
index 4016a1367..0c1e59bec 100755
--- a/src/audio_core/renderer/memory/pool_mapper.cpp
+++ b/src/audio_core/renderer/memory/pool_mapper.cpp
@@ -8,11 +8,11 @@
8 8
9namespace AudioCore::Renderer { 9namespace AudioCore::Renderer {
10 10
11PoolMapper::PoolMapper(u32 process_handle_, bool force_map_) 11PoolMapper::PoolMapper(Kernel::KProcess* process_handle_, bool force_map_)
12 : process_handle{process_handle_}, force_map{force_map_} {} 12 : process_handle{process_handle_}, force_map{force_map_} {}
13 13
14PoolMapper::PoolMapper(u32 process_handle_, std::span<MemoryPoolInfo> pool_infos_, u32 pool_count_, 14PoolMapper::PoolMapper(Kernel::KProcess* process_handle_, std::span<MemoryPoolInfo> pool_infos_,
15 bool force_map_) 15 u32 pool_count_, bool force_map_)
16 : process_handle{process_handle_}, pool_infos{pool_infos_.data()}, 16 : process_handle{process_handle_}, pool_infos{pool_infos_.data()},
17 pool_count{pool_count_}, force_map{force_map_} {} 17 pool_count{pool_count_}, force_map{force_map_} {}
18 18
@@ -106,15 +106,17 @@ bool PoolMapper::IsForceMapEnabled() const {
106 return force_map; 106 return force_map;
107} 107}
108 108
109u32 PoolMapper::GetProcessHandle(const MemoryPoolInfo* pool) const { 109Kernel::KProcess* PoolMapper::GetProcessHandle(const MemoryPoolInfo* pool) const {
110 switch (pool->GetLocation()) { 110 switch (pool->GetLocation()) {
111 case MemoryPoolInfo::Location::CPU: 111 case MemoryPoolInfo::Location::CPU:
112 return process_handle; 112 return process_handle;
113 case MemoryPoolInfo::Location::DSP: 113 case MemoryPoolInfo::Location::DSP:
114 return Kernel::Svc::CurrentProcess; 114 // return Kernel::Svc::CurrentProcess;
115 return nullptr;
115 } 116 }
116 LOG_WARNING(Service_Audio, "Invalid MemoryPoolInfo location!"); 117 LOG_WARNING(Service_Audio, "Invalid MemoryPoolInfo location!");
117 return Kernel::Svc::CurrentProcess; 118 // return Kernel::Svc::CurrentProcess;
119 return nullptr;
118} 120}
119 121
120bool PoolMapper::Map([[maybe_unused]] const u32 handle, [[maybe_unused]] const CpuAddr cpu_addr, 122bool PoolMapper::Map([[maybe_unused]] const u32 handle, [[maybe_unused]] const CpuAddr cpu_addr,
@@ -147,14 +149,14 @@ bool PoolMapper::Unmap([[maybe_unused]] const u32 handle, [[maybe_unused]] const
147} 149}
148 150
149bool PoolMapper::Unmap(MemoryPoolInfo& pool) const { 151bool PoolMapper::Unmap(MemoryPoolInfo& pool) const {
150 [[maybe_unused]] u32 handle{0}; 152 [[maybe_unused]] Kernel::KProcess* handle{};
151 153
152 switch (pool.GetLocation()) { 154 switch (pool.GetLocation()) {
153 case MemoryPoolInfo::Location::CPU: 155 case MemoryPoolInfo::Location::CPU:
154 handle = process_handle; 156 handle = process_handle;
155 break; 157 break;
156 case MemoryPoolInfo::Location::DSP: 158 case MemoryPoolInfo::Location::DSP:
157 handle = Kernel::Svc::CurrentProcess; 159 // handle = Kernel::Svc::CurrentProcess;
158 break; 160 break;
159 } 161 }
160 // nn::audio::dsp::UnmapUserPointer(handle, pool->cpu_address, pool->size); 162 // nn::audio::dsp::UnmapUserPointer(handle, pool->cpu_address, pool->size);
diff --git a/src/audio_core/renderer/memory/pool_mapper.h b/src/audio_core/renderer/memory/pool_mapper.h
index ce98f6da6..3f5903ad0 100755
--- a/src/audio_core/renderer/memory/pool_mapper.h
+++ b/src/audio_core/renderer/memory/pool_mapper.h
@@ -10,6 +10,10 @@
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "core/hle/service/audio/errors.h" 11#include "core/hle/service/audio/errors.h"
12 12
13namespace Kernel {
14class KProcess;
15}
16
13namespace AudioCore::Renderer { 17namespace AudioCore::Renderer {
14class AddressInfo; 18class AddressInfo;
15 19
@@ -18,9 +22,9 @@ class AddressInfo;
18 */ 22 */
19class PoolMapper { 23class PoolMapper {
20public: 24public:
21 explicit PoolMapper(u32 process_handle, bool force_map); 25 explicit PoolMapper(Kernel::KProcess* process_handle, bool force_map);
22 explicit PoolMapper(u32 process_handle, std::span<MemoryPoolInfo> pool_infos, u32 pool_count, 26 explicit PoolMapper(Kernel::KProcess* process_handle, std::span<MemoryPoolInfo> pool_infos,
23 bool force_map); 27 u32 pool_count, bool force_map);
24 28
25 /** 29 /**
26 * Clear the usage state for all given pools. 30 * Clear the usage state for all given pools.
@@ -98,7 +102,7 @@ public:
98 * @return CurrentProcessHandle if location == DSP, 102 * @return CurrentProcessHandle if location == DSP,
99 * the PoolMapper's process_handle if location == CPU 103 * the PoolMapper's process_handle if location == CPU
100 */ 104 */
101 u32 GetProcessHandle(const MemoryPoolInfo* pool) const; 105 Kernel::KProcess* GetProcessHandle(const MemoryPoolInfo* pool) const;
102 106
103 /** 107 /**
104 * Map the given region with the given handle. This is a no-op. 108 * Map the given region with the given handle. This is a no-op.
@@ -167,7 +171,7 @@ public:
167 171
168private: 172private:
169 /// Process handle for this mapper, used when location == CPU 173 /// Process handle for this mapper, used when location == CPU
170 u32 process_handle; 174 Kernel::KProcess* process_handle{};
171 /// List of memory pools assigned to this mapper 175 /// List of memory pools assigned to this mapper
172 MemoryPoolInfo* pool_infos{}; 176 MemoryPoolInfo* pool_infos{};
173 /// The number of pools 177 /// The number of pools
diff --git a/src/audio_core/renderer/system.cpp b/src/audio_core/renderer/system.cpp
index c00eea564..b118082d9 100755
--- a/src/audio_core/renderer/system.cpp
+++ b/src/audio_core/renderer/system.cpp
@@ -102,8 +102,8 @@ System::System(Core::System& core_, Kernel::KEvent* adsp_rendered_event_)
102 102
103Result System::Initialize(const AudioRendererParameterInternal& params, 103Result System::Initialize(const AudioRendererParameterInternal& params,
104 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, 104 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
105 u32 process_handle_, Kernel::KProcess& process_, 105 Kernel::KProcess* process_handle_, u64 applet_resource_user_id_,
106 u64 applet_resource_user_id_, s32 session_id_) { 106 s32 session_id_) {
107 if (!CheckValidRevision(params.revision)) { 107 if (!CheckValidRevision(params.revision)) {
108 return Service::Audio::ResultInvalidRevision; 108 return Service::Audio::ResultInvalidRevision;
109 } 109 }
@@ -119,7 +119,6 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
119 behavior.SetUserLibRevision(params.revision); 119 behavior.SetUserLibRevision(params.revision);
120 120
121 process_handle = process_handle_; 121 process_handle = process_handle_;
122 process = &process_;
123 applet_resource_user_id = applet_resource_user_id_; 122 applet_resource_user_id = applet_resource_user_id_;
124 session_id = session_id_; 123 session_id = session_id_;
125 124
@@ -132,7 +131,8 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
132 render_device = params.rendering_device; 131 render_device = params.rendering_device;
133 execution_mode = params.execution_mode; 132 execution_mode = params.execution_mode;
134 133
135 process->GetMemory().ZeroBlock(transfer_memory->GetSourceAddress(), transfer_memory_size); 134 process_handle->GetMemory().ZeroBlock(transfer_memory->GetSourceAddress(),
135 transfer_memory_size);
136 136
137 // Note: We're not actually using the transfer memory because it's a pain to code for. 137 // Note: We're not actually using the transfer memory because it's a pain to code for.
138 // Allocate the memory normally instead and hope the game doesn't try to read anything back 138 // Allocate the memory normally instead and hope the game doesn't try to read anything back
@@ -616,7 +616,7 @@ void System::SendCommandToDsp() {
616 static_cast<u64>((time_limit_percent / 100) * 2'880'000.0 * 616 static_cast<u64>((time_limit_percent / 100) * 2'880'000.0 *
617 (static_cast<f32>(render_time_limit_percent) / 100.0f))}; 617 (static_cast<f32>(render_time_limit_percent) / 100.0f))};
618 audio_renderer.SetCommandBuffer(session_id, translated_addr, command_size, time_limit, 618 audio_renderer.SetCommandBuffer(session_id, translated_addr, command_size, time_limit,
619 applet_resource_user_id, process, 619 applet_resource_user_id, process_handle,
620 reset_command_buffers); 620 reset_command_buffers);
621 reset_command_buffers = false; 621 reset_command_buffers = false;
622 command_buffer_size = command_size; 622 command_buffer_size = command_size;
diff --git a/src/audio_core/renderer/system.h b/src/audio_core/renderer/system.h
index c39086027..55d1340e6 100755
--- a/src/audio_core/renderer/system.h
+++ b/src/audio_core/renderer/system.h
@@ -74,14 +74,14 @@ public:
74 * @param params - Input parameters to initialize the system with. 74 * @param params - Input parameters to initialize the system with.
75 * @param transfer_memory - Game-supplied memory for all workbuffers. Unused. 75 * @param transfer_memory - Game-supplied memory for all workbuffers. Unused.
76 * @param transfer_memory_size - Size of the transfer memory. Unused. 76 * @param transfer_memory_size - Size of the transfer memory. Unused.
77 * @param process_handle - Process handle, also used for memory. Unused. 77 * @param process_handle - Process handle, also used for memory.
78 * @param applet_resource_user_id - Applet id for this renderer. Unused. 78 * @param applet_resource_user_id - Applet id for this renderer. Unused.
79 * @param session_id - Session id of this renderer. 79 * @param session_id - Session id of this renderer.
80 * @return Result code. 80 * @return Result code.
81 */ 81 */
82 Result Initialize(const AudioRendererParameterInternal& params, 82 Result Initialize(const AudioRendererParameterInternal& params,
83 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, 83 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
84 u32 process_handle, Kernel::KProcess& process, u64 applet_resource_user_id, 84 Kernel::KProcess* process_handle, u64 applet_resource_user_id,
85 s32 session_id); 85 s32 session_id);
86 86
87 /** 87 /**
@@ -278,9 +278,7 @@ private:
278 /// Does what locks do 278 /// Does what locks do
279 std::mutex lock{}; 279 std::mutex lock{};
280 /// Process this audio render is operating within, used for memory reads/writes. 280 /// Process this audio render is operating within, used for memory reads/writes.
281 Kernel::KProcess* process{}; 281 Kernel::KProcess* process_handle{};
282 /// Handle for the process for this system, unused
283 u32 process_handle{};
284 /// Applet resource id for this system, unused 282 /// Applet resource id for this system, unused
285 u64 applet_resource_user_id{}; 283 u64 applet_resource_user_id{};
286 /// Controls performance input and output 284 /// Controls performance input and output
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp
index ab6f36fd3..6b7862045 100755
--- a/src/common/string_util.cpp
+++ b/src/common/string_util.cpp
@@ -38,6 +38,10 @@ std::string StringFromBuffer(std::span<const u8> data) {
38 return std::string(data.begin(), std::find(data.begin(), data.end(), '\0')); 38 return std::string(data.begin(), std::find(data.begin(), data.end(), '\0'));
39} 39}
40 40
41std::string StringFromBuffer(std::span<const char> data) {
42 return std::string(data.begin(), std::find(data.begin(), data.end(), '\0'));
43}
44
41// Turns " hej " into "hej". Also handles tabs. 45// Turns " hej " into "hej". Also handles tabs.
42std::string StripSpaces(const std::string& str) { 46std::string StripSpaces(const std::string& str) {
43 const std::size_t s = str.find_first_not_of(" \t\r\n"); 47 const std::size_t s = str.find_first_not_of(" \t\r\n");
diff --git a/src/common/string_util.h b/src/common/string_util.h
index 068a6be2e..d28e47b09 100755
--- a/src/common/string_util.h
+++ b/src/common/string_util.h
@@ -19,6 +19,7 @@ namespace Common {
19[[nodiscard]] std::string ToUpper(std::string str); 19[[nodiscard]] std::string ToUpper(std::string str);
20 20
21[[nodiscard]] std::string StringFromBuffer(std::span<const u8> data); 21[[nodiscard]] std::string StringFromBuffer(std::span<const u8> data);
22[[nodiscard]] std::string StringFromBuffer(std::span<const char> data);
22 23
23[[nodiscard]] std::string StripSpaces(const std::string& s); 24[[nodiscard]] std::string StripSpaces(const std::string& s);
24[[nodiscard]] std::string StripQuotes(const std::string& s); 25[[nodiscard]] std::string StripQuotes(const std::string& s);
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 257e9080c..fc07115ed 100755
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -58,6 +58,7 @@ add_library(core STATIC
58 file_sys/fs_operate_range.h 58 file_sys/fs_operate_range.h
59 file_sys/fs_path.h 59 file_sys/fs_path.h
60 file_sys/fs_path_utility.h 60 file_sys/fs_path_utility.h
61 file_sys/fs_save_data_types.h
61 file_sys/fs_string_util.h 62 file_sys/fs_string_util.h
62 file_sys/fsa/fs_i_directory.h 63 file_sys/fsa/fs_i_directory.h
63 file_sys/fsa/fs_i_file.h 64 file_sys/fsa/fs_i_file.h
@@ -493,23 +494,33 @@ add_library(core STATIC
493 hle/service/apm/apm_controller.h 494 hle/service/apm/apm_controller.h
494 hle/service/apm/apm_interface.cpp 495 hle/service/apm/apm_interface.cpp
495 hle/service/apm/apm_interface.h 496 hle/service/apm/apm_interface.h
496 hle/service/audio/audin_u.cpp
497 hle/service/audio/audin_u.h
498 hle/service/audio/audio.cpp
499 hle/service/audio/audio.h
500 hle/service/audio/audio_controller.cpp 497 hle/service/audio/audio_controller.cpp
501 hle/service/audio/audio_controller.h 498 hle/service/audio/audio_controller.h
502 hle/service/audio/audout_u.cpp 499 hle/service/audio/audio_device.cpp
503 hle/service/audio/audout_u.h 500 hle/service/audio/audio_device.h
504 hle/service/audio/audrec_a.cpp 501 hle/service/audio/audio_in_manager.cpp
505 hle/service/audio/audrec_a.h 502 hle/service/audio/audio_in_manager.h
506 hle/service/audio/audrec_u.cpp 503 hle/service/audio/audio_in.cpp
507 hle/service/audio/audrec_u.h 504 hle/service/audio/audio_in.h
508 hle/service/audio/audren_u.cpp 505 hle/service/audio/audio_out_manager.cpp
509 hle/service/audio/audren_u.h 506 hle/service/audio/audio_out_manager.h
507 hle/service/audio/audio_out.cpp
508 hle/service/audio/audio_out.h
509 hle/service/audio/audio_renderer_manager.cpp
510 hle/service/audio/audio_renderer_manager.h
511 hle/service/audio/audio_renderer.cpp
512 hle/service/audio/audio_renderer.h
513 hle/service/audio/audio.cpp
514 hle/service/audio/audio.h
510 hle/service/audio/errors.h 515 hle/service/audio/errors.h
511 hle/service/audio/hwopus.cpp 516 hle/service/audio/final_output_recorder_manager_for_applet.cpp
512 hle/service/audio/hwopus.h 517 hle/service/audio/final_output_recorder_manager_for_applet.h
518 hle/service/audio/final_output_recorder_manager.cpp
519 hle/service/audio/final_output_recorder_manager.h
520 hle/service/audio/hardware_opus_decoder_manager.cpp
521 hle/service/audio/hardware_opus_decoder_manager.h
522 hle/service/audio/hardware_opus_decoder.cpp
523 hle/service/audio/hardware_opus_decoder.h
513 hle/service/bcat/backend/backend.cpp 524 hle/service/bcat/backend/backend.cpp
514 hle/service/bcat/backend/backend.h 525 hle/service/bcat/backend/backend.h
515 hle/service/bcat/bcat.cpp 526 hle/service/bcat/bcat.cpp
@@ -599,6 +610,10 @@ add_library(core STATIC
599 hle/service/filesystem/fsp/fs_i_file.h 610 hle/service/filesystem/fsp/fs_i_file.h
600 hle/service/filesystem/fsp/fs_i_filesystem.cpp 611 hle/service/filesystem/fsp/fs_i_filesystem.cpp
601 hle/service/filesystem/fsp/fs_i_filesystem.h 612 hle/service/filesystem/fsp/fs_i_filesystem.h
613 hle/service/filesystem/fsp/fs_i_multi_commit_manager.cpp
614 hle/service/filesystem/fsp/fs_i_multi_commit_manager.h
615 hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp
616 hle/service/filesystem/fsp/fs_i_save_data_info_reader.h
602 hle/service/filesystem/fsp/fs_i_storage.cpp 617 hle/service/filesystem/fsp/fs_i_storage.cpp
603 hle/service/filesystem/fsp/fs_i_storage.h 618 hle/service/filesystem/fsp/fs_i_storage.h
604 hle/service/filesystem/fsp/fsp_ldr.cpp 619 hle/service/filesystem/fsp/fsp_ldr.cpp
@@ -607,7 +622,7 @@ add_library(core STATIC
607 hle/service/filesystem/fsp/fsp_pr.h 622 hle/service/filesystem/fsp/fsp_pr.h
608 hle/service/filesystem/fsp/fsp_srv.cpp 623 hle/service/filesystem/fsp/fsp_srv.cpp
609 hle/service/filesystem/fsp/fsp_srv.h 624 hle/service/filesystem/fsp/fsp_srv.h
610 hle/service/filesystem/fsp/fsp_util.h 625 hle/service/filesystem/fsp/fsp_types.h
611 hle/service/filesystem/romfs_controller.cpp 626 hle/service/filesystem/romfs_controller.cpp
612 hle/service/filesystem/romfs_controller.h 627 hle/service/filesystem/romfs_controller.h
613 hle/service/filesystem/save_data_controller.cpp 628 hle/service/filesystem/save_data_controller.cpp
@@ -864,8 +879,20 @@ add_library(core STATIC
864 hle/service/nvnflinger/ui/graphic_buffer.cpp 879 hle/service/nvnflinger/ui/graphic_buffer.cpp
865 hle/service/nvnflinger/ui/graphic_buffer.h 880 hle/service/nvnflinger/ui/graphic_buffer.h
866 hle/service/nvnflinger/window.h 881 hle/service/nvnflinger/window.h
882 hle/service/olsc/daemon_controller.cpp
883 hle/service/olsc/daemon_controller.h
884 hle/service/olsc/native_handle_holder.cpp
885 hle/service/olsc/native_handle_holder.h
886 hle/service/olsc/olsc_service_for_application.cpp
887 hle/service/olsc/olsc_service_for_application.h
888 hle/service/olsc/olsc_service_for_system_service.cpp
889 hle/service/olsc/olsc_service_for_system_service.h
867 hle/service/olsc/olsc.cpp 890 hle/service/olsc/olsc.cpp
868 hle/service/olsc/olsc.h 891 hle/service/olsc/olsc.h
892 hle/service/olsc/remote_storage_controller.cpp
893 hle/service/olsc/remote_storage_controller.h
894 hle/service/olsc/transfer_task_list_controller.cpp
895 hle/service/olsc/transfer_task_list_controller.h
869 hle/service/omm/omm.cpp 896 hle/service/omm/omm.cpp
870 hle/service/omm/omm.h 897 hle/service/omm/omm.h
871 hle/service/omm/operation_mode_manager.cpp 898 hle/service/omm/operation_mode_manager.cpp
@@ -885,16 +912,35 @@ add_library(core STATIC
885 hle/service/os/mutex.h 912 hle/service/os/mutex.h
886 hle/service/pcie/pcie.cpp 913 hle/service/pcie/pcie.cpp
887 hle/service/pcie/pcie.h 914 hle/service/pcie/pcie.h
915 hle/service/pctl/parental_control_service_factory.cpp
916 hle/service/pctl/parental_control_service_factory.h
917 hle/service/pctl/parental_control_service.cpp
918 hle/service/pctl/parental_control_service.h
888 hle/service/pctl/pctl.cpp 919 hle/service/pctl/pctl.cpp
889 hle/service/pctl/pctl.h 920 hle/service/pctl/pctl.h
890 hle/service/pctl/pctl_module.cpp 921 hle/service/pctl/pctl_results.h
891 hle/service/pctl/pctl_module.h 922 hle/service/pctl/pctl_types.h
892 hle/service/pcv/pcv.cpp 923 hle/service/pcv/pcv.cpp
893 hle/service/pcv/pcv.h 924 hle/service/pcv/pcv.h
894 hle/service/pm/pm.cpp 925 hle/service/pm/pm.cpp
895 hle/service/pm/pm.h 926 hle/service/pm/pm.h
896 hle/service/prepo/prepo.cpp 927 hle/service/prepo/prepo.cpp
897 hle/service/prepo/prepo.h 928 hle/service/prepo/prepo.h
929 hle/service/psc/ovln/ovln_types.h
930 hle/service/psc/ovln/receiver_service.cpp
931 hle/service/psc/ovln/receiver_service.h
932 hle/service/psc/ovln/receiver.cpp
933 hle/service/psc/ovln/receiver.h
934 hle/service/psc/ovln/sender_service.cpp
935 hle/service/psc/ovln/sender_service.h
936 hle/service/psc/ovln/sender.cpp
937 hle/service/psc/ovln/sender.h
938 hle/service/psc/pm_control.cpp
939 hle/service/psc/pm_control.h
940 hle/service/psc/pm_module.cpp
941 hle/service/psc/pm_module.h
942 hle/service/psc/pm_service.cpp
943 hle/service/psc/pm_service.h
898 hle/service/psc/psc.cpp 944 hle/service/psc/psc.cpp
899 hle/service/psc/psc.h 945 hle/service/psc/psc.h
900 hle/service/psc/time/alarms.cpp 946 hle/service/psc/time/alarms.cpp
diff --git a/src/core/file_sys/fs_save_data_types.h b/src/core/file_sys/fs_save_data_types.h
new file mode 100755
index 000000000..86a83d217
--- /dev/null
+++ b/src/core/file_sys/fs_save_data_types.h
@@ -0,0 +1,175 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <array>
7#include <fmt/format.h>
8#include "common/common_funcs.h"
9#include "common/common_types.h"
10
11namespace FileSys {
12
13using SaveDataId = u64;
14using SystemSaveDataId = u64;
15using SystemBcatSaveDataId = SystemSaveDataId;
16using ProgramId = u64;
17
18enum class SaveDataSpaceId : u8 {
19 System = 0,
20 User = 1,
21 SdSystem = 2,
22 Temporary = 3,
23 SdUser = 4,
24
25 ProperSystem = 100,
26 SafeMode = 101,
27};
28
29enum class SaveDataType : u8 {
30 System = 0,
31 Account = 1,
32 Bcat = 2,
33 Device = 3,
34 Temporary = 4,
35 Cache = 5,
36 SystemBcat = 6,
37};
38
39enum class SaveDataRank : u8 {
40 Primary = 0,
41 Secondary = 1,
42};
43
44struct SaveDataSize {
45 u64 normal;
46 u64 journal;
47};
48static_assert(sizeof(SaveDataSize) == 0x10, "SaveDataSize has invalid size.");
49
50using UserId = u128;
51static_assert(std::is_trivially_copyable_v<UserId>, "Data type must be trivially copyable.");
52static_assert(sizeof(UserId) == 0x10, "UserId has invalid size.");
53
54constexpr inline SystemSaveDataId InvalidSystemSaveDataId = 0;
55constexpr inline UserId InvalidUserId = {};
56
57enum class SaveDataFlags : u32 {
58 None = (0 << 0),
59 KeepAfterResettingSystemSaveData = (1 << 0),
60 KeepAfterRefurbishment = (1 << 1),
61 KeepAfterResettingSystemSaveDataWithoutUserSaveData = (1 << 2),
62 NeedsSecureDelete = (1 << 3),
63};
64
65enum class SaveDataMetaType : u8 {
66 None = 0,
67 Thumbnail = 1,
68 ExtensionContext = 2,
69};
70
71struct SaveDataMetaInfo {
72 u32 size;
73 SaveDataMetaType type;
74 INSERT_PADDING_BYTES(0xB);
75};
76static_assert(std::is_trivially_copyable_v<SaveDataMetaInfo>,
77 "Data type must be trivially copyable.");
78static_assert(sizeof(SaveDataMetaInfo) == 0x10, "SaveDataMetaInfo has invalid size.");
79
80struct SaveDataCreationInfo {
81 s64 size;
82 s64 journal_size;
83 s64 block_size;
84 u64 owner_id;
85 u32 flags;
86 SaveDataSpaceId space_id;
87 bool pseudo;
88 INSERT_PADDING_BYTES(0x1A);
89};
90static_assert(std::is_trivially_copyable_v<SaveDataCreationInfo>,
91 "Data type must be trivially copyable.");
92static_assert(sizeof(SaveDataCreationInfo) == 0x40, "SaveDataCreationInfo has invalid size.");
93
94struct SaveDataAttribute {
95 ProgramId program_id;
96 UserId user_id;
97 SystemSaveDataId system_save_data_id;
98 SaveDataType type;
99 SaveDataRank rank;
100 u16 index;
101 INSERT_PADDING_BYTES(0x1C);
102
103 static constexpr SaveDataAttribute Make(ProgramId program_id, SaveDataType type, UserId user_id,
104 SystemSaveDataId system_save_data_id, u16 index,
105 SaveDataRank rank) {
106 return {
107 .program_id = program_id,
108 .user_id = user_id,
109 .system_save_data_id = system_save_data_id,
110 .type = type,
111 .rank = rank,
112 .index = index,
113 };
114 }
115
116 static constexpr SaveDataAttribute Make(ProgramId program_id, SaveDataType type, UserId user_id,
117 SystemSaveDataId system_save_data_id, u16 index) {
118 return Make(program_id, type, user_id, system_save_data_id, index, SaveDataRank::Primary);
119 }
120
121 static constexpr SaveDataAttribute Make(ProgramId program_id, SaveDataType type, UserId user_id,
122 SystemSaveDataId system_save_data_id) {
123 return Make(program_id, type, user_id, system_save_data_id, 0, SaveDataRank::Primary);
124 }
125
126 std::string DebugInfo() const {
127 return fmt::format(
128 "[title_id={:016X}, user_id={:016X}{:016X}, save_id={:016X}, type={:02X}, "
129 "rank={}, index={}]",
130 program_id, user_id[1], user_id[0], system_save_data_id, static_cast<u8>(type),
131 static_cast<u8>(rank), index);
132 }
133};
134static_assert(sizeof(SaveDataAttribute) == 0x40);
135static_assert(std::is_trivially_destructible<SaveDataAttribute>::value);
136
137constexpr inline bool operator<(const SaveDataAttribute& lhs, const SaveDataAttribute& rhs) {
138 return std::tie(lhs.program_id, lhs.user_id, lhs.system_save_data_id, lhs.index, lhs.rank) <
139 std::tie(rhs.program_id, rhs.user_id, rhs.system_save_data_id, rhs.index, rhs.rank);
140}
141
142constexpr inline bool operator==(const SaveDataAttribute& lhs, const SaveDataAttribute& rhs) {
143 return std::tie(lhs.program_id, lhs.user_id, lhs.system_save_data_id, lhs.type, lhs.rank,
144 lhs.index) == std::tie(rhs.program_id, rhs.user_id, rhs.system_save_data_id,
145 rhs.type, rhs.rank, rhs.index);
146}
147
148constexpr inline bool operator!=(const SaveDataAttribute& lhs, const SaveDataAttribute& rhs) {
149 return !(lhs == rhs);
150}
151
152struct SaveDataExtraData {
153 SaveDataAttribute attr;
154 u64 owner_id;
155 s64 timestamp;
156 u32 flags;
157 INSERT_PADDING_BYTES(4);
158 s64 available_size;
159 s64 journal_size;
160 s64 commit_id;
161 INSERT_PADDING_BYTES(0x190);
162};
163static_assert(sizeof(SaveDataExtraData) == 0x200, "SaveDataExtraData has invalid size.");
164static_assert(std::is_trivially_copyable_v<SaveDataExtraData>,
165 "Data type must be trivially copyable.");
166
167struct HashSalt {
168 static constexpr size_t Size = 32;
169
170 std::array<u8, Size> value;
171};
172static_assert(std::is_trivially_copyable_v<HashSalt>, "Data type must be trivially copyable.");
173static_assert(sizeof(HashSalt) == HashSalt::Size);
174
175} // namespace FileSys
diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp
index aa2f7e8f4..d13628cfe 100755
--- a/src/core/file_sys/savedata_factory.cpp
+++ b/src/core/file_sys/savedata_factory.cpp
@@ -14,48 +14,11 @@ namespace FileSys {
14 14
15namespace { 15namespace {
16 16
17void PrintSaveDataAttributeWarnings(SaveDataAttribute meta) {
18 if (meta.type == SaveDataType::SystemSaveData || meta.type == SaveDataType::SaveData) {
19 if (meta.zero_1 != 0) {
20 LOG_WARNING(Service_FS,
21 "Possibly incorrect SaveDataAttribute, type is "
22 "SystemSaveData||SaveData but offset 0x28 is non-zero ({:016X}).",
23 meta.zero_1);
24 }
25 if (meta.zero_2 != 0) {
26 LOG_WARNING(Service_FS,
27 "Possibly incorrect SaveDataAttribute, type is "
28 "SystemSaveData||SaveData but offset 0x30 is non-zero ({:016X}).",
29 meta.zero_2);
30 }
31 if (meta.zero_3 != 0) {
32 LOG_WARNING(Service_FS,
33 "Possibly incorrect SaveDataAttribute, type is "
34 "SystemSaveData||SaveData but offset 0x38 is non-zero ({:016X}).",
35 meta.zero_3);
36 }
37 }
38
39 if (meta.type == SaveDataType::SystemSaveData && meta.title_id != 0) {
40 LOG_WARNING(Service_FS,
41 "Possibly incorrect SaveDataAttribute, type is SystemSaveData but title_id is "
42 "non-zero ({:016X}).",
43 meta.title_id);
44 }
45
46 if (meta.type == SaveDataType::DeviceSaveData && meta.user_id != u128{0, 0}) {
47 LOG_WARNING(Service_FS,
48 "Possibly incorrect SaveDataAttribute, type is DeviceSaveData but user_id is "
49 "non-zero ({:016X}{:016X})",
50 meta.user_id[1], meta.user_id[0]);
51 }
52}
53
54bool ShouldSaveDataBeAutomaticallyCreated(SaveDataSpaceId space, const SaveDataAttribute& attr) { 17bool ShouldSaveDataBeAutomaticallyCreated(SaveDataSpaceId space, const SaveDataAttribute& attr) {
55 return attr.type == SaveDataType::CacheStorage || attr.type == SaveDataType::TemporaryStorage || 18 return attr.type == SaveDataType::Cache || attr.type == SaveDataType::Temporary ||
56 (space == SaveDataSpaceId::NandUser && ///< Normal Save Data -- Current Title & User 19 (space == SaveDataSpaceId::User && ///< Normal Save Data -- Current Title & User
57 (attr.type == SaveDataType::SaveData || attr.type == SaveDataType::DeviceSaveData) && 20 (attr.type == SaveDataType::Account || attr.type == SaveDataType::Device) &&
58 attr.title_id == 0 && attr.save_id == 0); 21 attr.program_id == 0 && attr.system_save_data_id == 0);
59} 22}
60 23
61std::string GetFutureSaveDataPath(SaveDataSpaceId space_id, SaveDataType type, u64 title_id, 24std::string GetFutureSaveDataPath(SaveDataSpaceId space_id, SaveDataType type, u64 title_id,
@@ -63,7 +26,7 @@ std::string GetFutureSaveDataPath(SaveDataSpaceId space_id, SaveDataType type, u
63 // Only detect nand user saves. 26 // Only detect nand user saves.
64 const auto space_id_path = [space_id]() -> std::string_view { 27 const auto space_id_path = [space_id]() -> std::string_view {
65 switch (space_id) { 28 switch (space_id) {
66 case SaveDataSpaceId::NandUser: 29 case SaveDataSpaceId::User:
67 return "/user/save"; 30 return "/user/save";
68 default: 31 default:
69 return ""; 32 return "";
@@ -79,9 +42,9 @@ std::string GetFutureSaveDataPath(SaveDataSpaceId space_id, SaveDataType type, u
79 42
80 // Only detect account/device saves from the future location. 43 // Only detect account/device saves from the future location.
81 switch (type) { 44 switch (type) {
82 case SaveDataType::SaveData: 45 case SaveDataType::Account:
83 return fmt::format("{}/account/{}/{:016X}/0", space_id_path, uuid.RawString(), title_id); 46 return fmt::format("{}/account/{}/{:016X}/0", space_id_path, uuid.RawString(), title_id);
84 case SaveDataType::DeviceSaveData: 47 case SaveDataType::Device:
85 return fmt::format("{}/device/{:016X}/0", space_id_path, title_id); 48 return fmt::format("{}/device/{:016X}/0", space_id_path, title_id);
86 default: 49 default:
87 return ""; 50 return "";
@@ -90,13 +53,6 @@ std::string GetFutureSaveDataPath(SaveDataSpaceId space_id, SaveDataType type, u
90 53
91} // Anonymous namespace 54} // Anonymous namespace
92 55
93std::string SaveDataAttribute::DebugInfo() const {
94 return fmt::format("[title_id={:016X}, user_id={:016X}{:016X}, save_id={:016X}, type={:02X}, "
95 "rank={}, index={}]",
96 title_id, user_id[1], user_id[0], save_id, static_cast<u8>(type),
97 static_cast<u8>(rank), index);
98}
99
100SaveDataFactory::SaveDataFactory(Core::System& system_, ProgramId program_id_, 56SaveDataFactory::SaveDataFactory(Core::System& system_, ProgramId program_id_,
101 VirtualDir save_directory_) 57 VirtualDir save_directory_)
102 : system{system_}, program_id{program_id_}, dir{std::move(save_directory_)} { 58 : system{system_}, program_id{program_id_}, dir{std::move(save_directory_)} {
@@ -108,18 +64,16 @@ SaveDataFactory::SaveDataFactory(Core::System& system_, ProgramId program_id_,
108SaveDataFactory::~SaveDataFactory() = default; 64SaveDataFactory::~SaveDataFactory() = default;
109 65
110VirtualDir SaveDataFactory::Create(SaveDataSpaceId space, const SaveDataAttribute& meta) const { 66VirtualDir SaveDataFactory::Create(SaveDataSpaceId space, const SaveDataAttribute& meta) const {
111 PrintSaveDataAttributeWarnings(meta); 67 const auto save_directory = GetFullPath(program_id, dir, space, meta.type, meta.program_id,
112 68 meta.user_id, meta.system_save_data_id);
113 const auto save_directory =
114 GetFullPath(program_id, dir, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
115 69
116 return dir->CreateDirectoryRelative(save_directory); 70 return dir->CreateDirectoryRelative(save_directory);
117} 71}
118 72
119VirtualDir SaveDataFactory::Open(SaveDataSpaceId space, const SaveDataAttribute& meta) const { 73VirtualDir SaveDataFactory::Open(SaveDataSpaceId space, const SaveDataAttribute& meta) const {
120 74
121 const auto save_directory = 75 const auto save_directory = GetFullPath(program_id, dir, space, meta.type, meta.program_id,
122 GetFullPath(program_id, dir, space, meta.type, meta.title_id, meta.user_id, meta.save_id); 76 meta.user_id, meta.system_save_data_id);
123 77
124 auto out = dir->GetDirectoryRelative(save_directory); 78 auto out = dir->GetDirectoryRelative(save_directory);
125 79
@@ -136,11 +90,11 @@ VirtualDir SaveDataFactory::GetSaveDataSpaceDirectory(SaveDataSpaceId space) con
136 90
137std::string SaveDataFactory::GetSaveDataSpaceIdPath(SaveDataSpaceId space) { 91std::string SaveDataFactory::GetSaveDataSpaceIdPath(SaveDataSpaceId space) {
138 switch (space) { 92 switch (space) {
139 case SaveDataSpaceId::NandSystem: 93 case SaveDataSpaceId::System:
140 return "/system/"; 94 return "/system/";
141 case SaveDataSpaceId::NandUser: 95 case SaveDataSpaceId::User:
142 return "/user/"; 96 return "/user/";
143 case SaveDataSpaceId::TemporaryStorage: 97 case SaveDataSpaceId::Temporary:
144 return "/temp/"; 98 return "/temp/";
145 default: 99 default:
146 ASSERT_MSG(false, "Unrecognized SaveDataSpaceId: {:02X}", static_cast<u8>(space)); 100 ASSERT_MSG(false, "Unrecognized SaveDataSpaceId: {:02X}", static_cast<u8>(space));
@@ -153,7 +107,7 @@ std::string SaveDataFactory::GetFullPath(ProgramId program_id, VirtualDir dir,
153 u128 user_id, u64 save_id) { 107 u128 user_id, u64 save_id) {
154 // According to switchbrew, if a save is of type SaveData and the title id field is 0, it should 108 // According to switchbrew, if a save is of type SaveData and the title id field is 0, it should
155 // be interpreted as the title id of the current process. 109 // be interpreted as the title id of the current process.
156 if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) { 110 if (type == SaveDataType::Account || type == SaveDataType::Device) {
157 if (title_id == 0) { 111 if (title_id == 0) {
158 title_id = program_id; 112 title_id = program_id;
159 } 113 }
@@ -173,16 +127,16 @@ std::string SaveDataFactory::GetFullPath(ProgramId program_id, VirtualDir dir,
173 std::string out = GetSaveDataSpaceIdPath(space); 127 std::string out = GetSaveDataSpaceIdPath(space);
174 128
175 switch (type) { 129 switch (type) {
176 case SaveDataType::SystemSaveData: 130 case SaveDataType::System:
177 return fmt::format("{}save/{:016X}/{:016X}{:016X}", out, save_id, user_id[1], user_id[0]); 131 return fmt::format("{}save/{:016X}/{:016X}{:016X}", out, save_id, user_id[1], user_id[0]);
178 case SaveDataType::SaveData: 132 case SaveDataType::Account:
179 case SaveDataType::DeviceSaveData: 133 case SaveDataType::Device:
180 return fmt::format("{}save/{:016X}/{:016X}{:016X}/{:016X}", out, 0, user_id[1], user_id[0], 134 return fmt::format("{}save/{:016X}/{:016X}{:016X}/{:016X}", out, 0, user_id[1], user_id[0],
181 title_id); 135 title_id);
182 case SaveDataType::TemporaryStorage: 136 case SaveDataType::Temporary:
183 return fmt::format("{}{:016X}/{:016X}{:016X}/{:016X}", out, 0, user_id[1], user_id[0], 137 return fmt::format("{}{:016X}/{:016X}{:016X}/{:016X}", out, 0, user_id[1], user_id[0],
184 title_id); 138 title_id);
185 case SaveDataType::CacheStorage: 139 case SaveDataType::Cache:
186 return fmt::format("{}save/cache/{:016X}", out, title_id); 140 return fmt::format("{}save/cache/{:016X}", out, title_id);
187 default: 141 default:
188 ASSERT_MSG(false, "Unrecognized SaveDataType: {:02X}", static_cast<u8>(type)); 142 ASSERT_MSG(false, "Unrecognized SaveDataType: {:02X}", static_cast<u8>(type));
@@ -202,7 +156,7 @@ std::string SaveDataFactory::GetUserGameSaveDataRoot(u128 user_id, bool future)
202SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id, 156SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
203 u128 user_id) const { 157 u128 user_id) const {
204 const auto path = 158 const auto path =
205 GetFullPath(program_id, dir, SaveDataSpaceId::NandUser, type, title_id, user_id, 0); 159 GetFullPath(program_id, dir, SaveDataSpaceId::User, type, title_id, user_id, 0);
206 const auto relative_dir = GetOrCreateDirectoryRelative(dir, path); 160 const auto relative_dir = GetOrCreateDirectoryRelative(dir, path);
207 161
208 const auto size_file = relative_dir->GetFile(GetSaveDataSizeFileName()); 162 const auto size_file = relative_dir->GetFile(GetSaveDataSizeFileName());
@@ -221,7 +175,7 @@ SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
221void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, 175void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
222 SaveDataSize new_value) const { 176 SaveDataSize new_value) const {
223 const auto path = 177 const auto path =
224 GetFullPath(program_id, dir, SaveDataSpaceId::NandUser, type, title_id, user_id, 0); 178 GetFullPath(program_id, dir, SaveDataSpaceId::User, type, title_id, user_id, 0);
225 const auto relative_dir = GetOrCreateDirectoryRelative(dir, path); 179 const auto relative_dir = GetOrCreateDirectoryRelative(dir, path);
226 180
227 const auto size_file = relative_dir->CreateFile(GetSaveDataSizeFileName()); 181 const auto size_file = relative_dir->CreateFile(GetSaveDataSizeFileName());
diff --git a/src/core/file_sys/savedata_factory.h b/src/core/file_sys/savedata_factory.h
index 2134eb405..b8076da65 100755
--- a/src/core/file_sys/savedata_factory.h
+++ b/src/core/file_sys/savedata_factory.h
@@ -7,6 +7,7 @@
7#include <string> 7#include <string>
8#include "common/common_funcs.h" 8#include "common/common_funcs.h"
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "core/file_sys/fs_save_data_types.h"
10#include "core/file_sys/vfs/vfs.h" 11#include "core/file_sys/vfs/vfs.h"
11#include "core/hle/result.h" 12#include "core/hle/result.h"
12 13
@@ -16,73 +17,6 @@ class System;
16 17
17namespace FileSys { 18namespace FileSys {
18 19
19enum class SaveDataSpaceId : u8 {
20 NandSystem = 0,
21 NandUser = 1,
22 SdCardSystem = 2,
23 TemporaryStorage = 3,
24 SdCardUser = 4,
25 ProperSystem = 100,
26 SafeMode = 101,
27};
28
29enum class SaveDataType : u8 {
30 SystemSaveData = 0,
31 SaveData = 1,
32 BcatDeliveryCacheStorage = 2,
33 DeviceSaveData = 3,
34 TemporaryStorage = 4,
35 CacheStorage = 5,
36 SystemBcat = 6,
37};
38
39enum class SaveDataRank : u8 {
40 Primary = 0,
41 Secondary = 1,
42};
43
44enum class SaveDataFlags : u32 {
45 None = (0 << 0),
46 KeepAfterResettingSystemSaveData = (1 << 0),
47 KeepAfterRefurbishment = (1 << 1),
48 KeepAfterResettingSystemSaveDataWithoutUserSaveData = (1 << 2),
49 NeedsSecureDelete = (1 << 3),
50};
51
52struct SaveDataAttribute {
53 u64 title_id;
54 u128 user_id;
55 u64 save_id;
56 SaveDataType type;
57 SaveDataRank rank;
58 u16 index;
59 INSERT_PADDING_BYTES_NOINIT(4);
60 u64 zero_1;
61 u64 zero_2;
62 u64 zero_3;
63
64 std::string DebugInfo() const;
65};
66static_assert(sizeof(SaveDataAttribute) == 0x40, "SaveDataAttribute has incorrect size.");
67
68struct SaveDataExtraData {
69 SaveDataAttribute attr;
70 u64 owner_id;
71 s64 timestamp;
72 SaveDataFlags flags;
73 INSERT_PADDING_BYTES_NOINIT(4);
74 s64 available_size;
75 s64 journal_size;
76 s64 commit_id;
77 std::array<u8, 0x190> unused;
78};
79static_assert(sizeof(SaveDataExtraData) == 0x200, "SaveDataExtraData has incorrect size.");
80
81struct SaveDataSize {
82 u64 normal;
83 u64 journal;
84};
85
86constexpr const char* GetSaveDataSizeFileName() { 20constexpr const char* GetSaveDataSizeFileName() {
87 return ".yuzu_save_size"; 21 return ".yuzu_save_size";
88} 22}
diff --git a/src/core/hle/service/am/service/application_functions.cpp b/src/core/hle/service/am/service/application_functions.cpp
index cb53b07e0..bfccb6b09 100755
--- a/src/core/hle/service/am/service/application_functions.cpp
+++ b/src/core/hle/service/am/service/application_functions.cpp
@@ -123,13 +123,13 @@ Result IApplicationFunctions::EnsureSaveData(Out<u64> out_size, Common::UUID use
123 LOG_INFO(Service_AM, "called, uid={}", user_id.FormattedString()); 123 LOG_INFO(Service_AM, "called, uid={}", user_id.FormattedString());
124 124
125 FileSys::SaveDataAttribute attribute{}; 125 FileSys::SaveDataAttribute attribute{};
126 attribute.title_id = m_applet->program_id; 126 attribute.program_id = m_applet->program_id;
127 attribute.user_id = user_id.AsU128(); 127 attribute.user_id = user_id.AsU128();
128 attribute.type = FileSys::SaveDataType::SaveData; 128 attribute.type = FileSys::SaveDataType::Account;
129 129
130 FileSys::VirtualDir save_data{}; 130 FileSys::VirtualDir save_data{};
131 R_TRY(system.GetFileSystemController().OpenSaveDataController()->CreateSaveData( 131 R_TRY(system.GetFileSystemController().OpenSaveDataController()->CreateSaveData(
132 &save_data, FileSys::SaveDataSpaceId::NandUser, attribute)); 132 &save_data, FileSys::SaveDataSpaceId::User, attribute));
133 133
134 *out_size = 0; 134 *out_size = 0;
135 R_SUCCEED(); 135 R_SUCCEED();
diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp
index 21314b516..1eb168d2c 100755
--- a/src/core/hle/service/audio/audio.cpp
+++ b/src/core/hle/service/audio/audio.cpp
@@ -2,14 +2,14 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core.h" 4#include "core/core.h"
5#include "core/hle/service/audio/audin_u.h"
6#include "core/hle/service/audio/audio.h" 5#include "core/hle/service/audio/audio.h"
7#include "core/hle/service/audio/audio_controller.h" 6#include "core/hle/service/audio/audio_controller.h"
8#include "core/hle/service/audio/audout_u.h" 7#include "core/hle/service/audio/audio_in_manager.h"
9#include "core/hle/service/audio/audrec_a.h" 8#include "core/hle/service/audio/audio_out_manager.h"
10#include "core/hle/service/audio/audrec_u.h" 9#include "core/hle/service/audio/audio_renderer_manager.h"
11#include "core/hle/service/audio/audren_u.h" 10#include "core/hle/service/audio/final_output_recorder_manager.h"
12#include "core/hle/service/audio/hwopus.h" 11#include "core/hle/service/audio/final_output_recorder_manager_for_applet.h"
12#include "core/hle/service/audio/hardware_opus_decoder_manager.h"
13#include "core/hle/service/server_manager.h" 13#include "core/hle/service/server_manager.h"
14#include "core/hle/service/service.h" 14#include "core/hle/service/service.h"
15 15
@@ -19,12 +19,16 @@ void LoopProcess(Core::System& system) {
19 auto server_manager = std::make_unique<ServerManager>(system); 19 auto server_manager = std::make_unique<ServerManager>(system);
20 20
21 server_manager->RegisterNamedService("audctl", std::make_shared<IAudioController>(system)); 21 server_manager->RegisterNamedService("audctl", std::make_shared<IAudioController>(system));
22 server_manager->RegisterNamedService("audout:u", std::make_shared<AudOutU>(system)); 22 server_manager->RegisterNamedService("audin:u", std::make_shared<IAudioInManager>(system));
23 server_manager->RegisterNamedService("audin:u", std::make_shared<AudInU>(system)); 23 server_manager->RegisterNamedService("audout:u", std::make_shared<IAudioOutManager>(system));
24 server_manager->RegisterNamedService("audrec:a", std::make_shared<AudRecA>(system)); 24 server_manager->RegisterNamedService(
25 server_manager->RegisterNamedService("audrec:u", std::make_shared<AudRecU>(system)); 25 "audrec:a", std::make_shared<IFinalOutputRecorderManagerForApplet>(system));
26 server_manager->RegisterNamedService("audren:u", std::make_shared<AudRenU>(system)); 26 server_manager->RegisterNamedService("audrec:u",
27 server_manager->RegisterNamedService("hwopus", std::make_shared<HwOpus>(system)); 27 std::make_shared<IFinalOutputRecorderManager>(system));
28 server_manager->RegisterNamedService("audren:u",
29 std::make_shared<IAudioRendererManager>(system));
30 server_manager->RegisterNamedService("hwopus",
31 std::make_shared<IHardwareOpusDecoderManager>(system));
28 ServerManager::RunServer(std::move(server_manager)); 32 ServerManager::RunServer(std::move(server_manager));
29} 33}
30 34
diff --git a/src/core/hle/service/audio/audio_controller.cpp b/src/core/hle/service/audio/audio_controller.cpp
index a6da66d0f..c9804cf9c 100755
--- a/src/core/hle/service/audio/audio_controller.cpp
+++ b/src/core/hle/service/audio/audio_controller.cpp
@@ -16,27 +16,27 @@ IAudioController::IAudioController(Core::System& system_)
16 static const FunctionInfo functions[] = { 16 static const FunctionInfo functions[] = {
17 {0, nullptr, "GetTargetVolume"}, 17 {0, nullptr, "GetTargetVolume"},
18 {1, nullptr, "SetTargetVolume"}, 18 {1, nullptr, "SetTargetVolume"},
19 {2, C<&IAudioController::GetTargetVolumeMin>, "GetTargetVolumeMin"}, 19 {2, D<&IAudioController::GetTargetVolumeMin>, "GetTargetVolumeMin"},
20 {3, C<&IAudioController::GetTargetVolumeMax>, "GetTargetVolumeMax"}, 20 {3, D<&IAudioController::GetTargetVolumeMax>, "GetTargetVolumeMax"},
21 {4, nullptr, "IsTargetMute"}, 21 {4, nullptr, "IsTargetMute"},
22 {5, nullptr, "SetTargetMute"}, 22 {5, nullptr, "SetTargetMute"},
23 {6, nullptr, "IsTargetConnected"}, 23 {6, nullptr, "IsTargetConnected"},
24 {7, nullptr, "SetDefaultTarget"}, 24 {7, nullptr, "SetDefaultTarget"},
25 {8, nullptr, "GetDefaultTarget"}, 25 {8, nullptr, "GetDefaultTarget"},
26 {9, C<&IAudioController::GetAudioOutputMode>, "GetAudioOutputMode"}, 26 {9, D<&IAudioController::GetAudioOutputMode>, "GetAudioOutputMode"},
27 {10, C<&IAudioController::SetAudioOutputMode>, "SetAudioOutputMode"}, 27 {10, D<&IAudioController::SetAudioOutputMode>, "SetAudioOutputMode"},
28 {11, nullptr, "SetForceMutePolicy"}, 28 {11, nullptr, "SetForceMutePolicy"},
29 {12, C<&IAudioController::GetForceMutePolicy>, "GetForceMutePolicy"}, 29 {12, D<&IAudioController::GetForceMutePolicy>, "GetForceMutePolicy"},
30 {13, C<&IAudioController::GetOutputModeSetting>, "GetOutputModeSetting"}, 30 {13, D<&IAudioController::GetOutputModeSetting>, "GetOutputModeSetting"},
31 {14, C<&IAudioController::SetOutputModeSetting>, "SetOutputModeSetting"}, 31 {14, D<&IAudioController::SetOutputModeSetting>, "SetOutputModeSetting"},
32 {15, nullptr, "SetOutputTarget"}, 32 {15, nullptr, "SetOutputTarget"},
33 {16, nullptr, "SetInputTargetForceEnabled"}, 33 {16, nullptr, "SetInputTargetForceEnabled"},
34 {17, C<&IAudioController::SetHeadphoneOutputLevelMode>, "SetHeadphoneOutputLevelMode"}, 34 {17, D<&IAudioController::SetHeadphoneOutputLevelMode>, "SetHeadphoneOutputLevelMode"},
35 {18, C<&IAudioController::GetHeadphoneOutputLevelMode>, "GetHeadphoneOutputLevelMode"}, 35 {18, D<&IAudioController::GetHeadphoneOutputLevelMode>, "GetHeadphoneOutputLevelMode"},
36 {19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"}, 36 {19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"},
37 {20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"}, 37 {20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"},
38 {21, nullptr, "GetAudioOutputTargetForPlayReport"}, 38 {21, nullptr, "GetAudioOutputTargetForPlayReport"},
39 {22, nullptr, "NotifyHeadphoneVolumeWarningDisplayedEvent"}, 39 {22, D<&IAudioController::NotifyHeadphoneVolumeWarningDisplayedEvent>, "NotifyHeadphoneVolumeWarningDisplayedEvent"},
40 {23, nullptr, "SetSystemOutputMasterVolume"}, 40 {23, nullptr, "SetSystemOutputMasterVolume"},
41 {24, nullptr, "GetSystemOutputMasterVolume"}, 41 {24, nullptr, "GetSystemOutputMasterVolume"},
42 {25, nullptr, "GetAudioVolumeDataForPlayReport"}, 42 {25, nullptr, "GetAudioVolumeDataForPlayReport"},
@@ -44,11 +44,11 @@ IAudioController::IAudioController(Core::System& system_)
44 {27, nullptr, "SetVolumeMappingTableForDev"}, 44 {27, nullptr, "SetVolumeMappingTableForDev"},
45 {28, nullptr, "GetAudioOutputChannelCountForPlayReport"}, 45 {28, nullptr, "GetAudioOutputChannelCountForPlayReport"},
46 {29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"}, 46 {29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"},
47 {30, C<&IAudioController::SetSpeakerAutoMuteEnabled>, "SetSpeakerAutoMuteEnabled"}, 47 {30, D<&IAudioController::SetSpeakerAutoMuteEnabled>, "SetSpeakerAutoMuteEnabled"},
48 {31, C<&IAudioController::IsSpeakerAutoMuteEnabled>, "IsSpeakerAutoMuteEnabled"}, 48 {31, D<&IAudioController::IsSpeakerAutoMuteEnabled>, "IsSpeakerAutoMuteEnabled"},
49 {32, nullptr, "GetActiveOutputTarget"}, 49 {32, nullptr, "GetActiveOutputTarget"},
50 {33, nullptr, "GetTargetDeviceInfo"}, 50 {33, nullptr, "GetTargetDeviceInfo"},
51 {34, C<&IAudioController::AcquireTargetNotification>, "AcquireTargetNotification"}, 51 {34, D<&IAudioController::AcquireTargetNotification>, "AcquireTargetNotification"},
52 {35, nullptr, "SetHearingProtectionSafeguardTimerRemainingTimeForDebug"}, 52 {35, nullptr, "SetHearingProtectionSafeguardTimerRemainingTimeForDebug"},
53 {36, nullptr, "GetHearingProtectionSafeguardTimerRemainingTimeForDebug"}, 53 {36, nullptr, "GetHearingProtectionSafeguardTimerRemainingTimeForDebug"},
54 {37, nullptr, "SetHearingProtectionSafeguardEnabled"}, 54 {37, nullptr, "SetHearingProtectionSafeguardEnabled"},
@@ -150,6 +150,11 @@ Result IAudioController::GetHeadphoneOutputLevelMode(
150 R_SUCCEED(); 150 R_SUCCEED();
151} 151}
152 152
153Result IAudioController::NotifyHeadphoneVolumeWarningDisplayedEvent() {
154 LOG_WARNING(Service_Audio, "(STUBBED) called");
155 R_SUCCEED();
156}
157
153Result IAudioController::SetSpeakerAutoMuteEnabled(bool is_speaker_auto_mute_enabled) { 158Result IAudioController::SetSpeakerAutoMuteEnabled(bool is_speaker_auto_mute_enabled) {
154 LOG_INFO(Audio, "called, is_speaker_auto_mute_enabled={}", is_speaker_auto_mute_enabled); 159 LOG_INFO(Audio, "called, is_speaker_auto_mute_enabled={}", is_speaker_auto_mute_enabled);
155 160
diff --git a/src/core/hle/service/audio/audio_controller.h b/src/core/hle/service/audio/audio_controller.h
index 9e8514373..d37c4843e 100755
--- a/src/core/hle/service/audio/audio_controller.h
+++ b/src/core/hle/service/audio/audio_controller.h
@@ -45,6 +45,7 @@ private:
45 Set::AudioOutputMode output_mode); 45 Set::AudioOutputMode output_mode);
46 Result SetHeadphoneOutputLevelMode(HeadphoneOutputLevelMode output_level_mode); 46 Result SetHeadphoneOutputLevelMode(HeadphoneOutputLevelMode output_level_mode);
47 Result GetHeadphoneOutputLevelMode(Out<HeadphoneOutputLevelMode> out_output_level_mode); 47 Result GetHeadphoneOutputLevelMode(Out<HeadphoneOutputLevelMode> out_output_level_mode);
48 Result NotifyHeadphoneVolumeWarningDisplayedEvent();
48 Result SetSpeakerAutoMuteEnabled(bool is_speaker_auto_mute_enabled); 49 Result SetSpeakerAutoMuteEnabled(bool is_speaker_auto_mute_enabled);
49 Result IsSpeakerAutoMuteEnabled(Out<bool> out_is_speaker_auto_mute_enabled); 50 Result IsSpeakerAutoMuteEnabled(Out<bool> out_is_speaker_auto_mute_enabled);
50 Result AcquireTargetNotification(OutCopyHandle<Kernel::KReadableEvent> out_notification_event); 51 Result AcquireTargetNotification(OutCopyHandle<Kernel::KReadableEvent> out_notification_event);
diff --git a/src/core/hle/service/audio/audio_device.cpp b/src/core/hle/service/audio/audio_device.cpp
new file mode 100755
index 000000000..438f3cccd
--- /dev/null
+++ b/src/core/hle/service/audio/audio_device.cpp
@@ -0,0 +1,163 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "audio_core/audio_core.h"
5#include "common/string_util.h"
6#include "core/hle/service/audio/audio_device.h"
7#include "core/hle/service/cmif_serialization.h"
8
9namespace Service::Audio {
10using namespace AudioCore::Renderer;
11
12IAudioDevice::IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u32 revision,
13 u32 device_num)
14 : ServiceFramework{system_, "IAudioDevice"}, service_context{system_, "IAudioDevice"},
15 impl{std::make_unique<AudioDevice>(system_, applet_resource_user_id, revision)},
16 event{service_context.CreateEvent(fmt::format("IAudioDeviceEvent-{}", device_num))} {
17 static const FunctionInfo functions[] = {
18 {0, D<&IAudioDevice::ListAudioDeviceName>, "ListAudioDeviceName"},
19 {1, D<&IAudioDevice::SetAudioDeviceOutputVolume>, "SetAudioDeviceOutputVolume"},
20 {2, D<&IAudioDevice::GetAudioDeviceOutputVolume>, "GetAudioDeviceOutputVolume"},
21 {3, D<&IAudioDevice::GetActiveAudioDeviceName>, "GetActiveAudioDeviceName"},
22 {4, D<&IAudioDevice::QueryAudioDeviceSystemEvent>, "QueryAudioDeviceSystemEvent"},
23 {5, D<&IAudioDevice::GetActiveChannelCount>, "GetActiveChannelCount"},
24 {6, D<&IAudioDevice::ListAudioDeviceNameAuto>, "ListAudioDeviceNameAuto"},
25 {7, D<&IAudioDevice::SetAudioDeviceOutputVolumeAuto>, "SetAudioDeviceOutputVolumeAuto"},
26 {8, D<&IAudioDevice::GetAudioDeviceOutputVolumeAuto>, "GetAudioDeviceOutputVolumeAuto"},
27 {10, D<&IAudioDevice::GetActiveAudioDeviceNameAuto>, "GetActiveAudioDeviceNameAuto"},
28 {11, D<&IAudioDevice::QueryAudioDeviceInputEvent>, "QueryAudioDeviceInputEvent"},
29 {12, D<&IAudioDevice::QueryAudioDeviceOutputEvent>, "QueryAudioDeviceOutputEvent"},
30 {13, D<&IAudioDevice::GetActiveAudioDeviceName>, "GetActiveAudioOutputDeviceName"},
31 {14, D<&IAudioDevice::ListAudioOutputDeviceName>, "ListAudioOutputDeviceName"},
32 };
33 RegisterHandlers(functions);
34
35 event->Signal();
36}
37
38IAudioDevice::~IAudioDevice() {
39 service_context.CloseEvent(event);
40}
41
42Result IAudioDevice::ListAudioDeviceName(
43 OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> out_names, Out<s32> out_count) {
44 R_RETURN(this->ListAudioDeviceNameAuto(out_names, out_count));
45}
46
47Result IAudioDevice::SetAudioDeviceOutputVolume(
48 InArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> name, f32 volume) {
49 R_RETURN(this->SetAudioDeviceOutputVolumeAuto(name, volume));
50}
51
52Result IAudioDevice::GetAudioDeviceOutputVolume(
53 Out<f32> out_volume, InArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> name) {
54 R_RETURN(this->GetAudioDeviceOutputVolumeAuto(out_volume, name));
55}
56
57Result IAudioDevice::GetActiveAudioDeviceName(
58 OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> out_name) {
59 R_RETURN(this->GetActiveAudioDeviceNameAuto(out_name));
60}
61
62Result IAudioDevice::ListAudioDeviceNameAuto(
63 OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcAutoSelect> out_names,
64 Out<s32> out_count) {
65 *out_count = impl->ListAudioDeviceName(out_names);
66
67 std::string out{};
68 for (s32 i = 0; i < *out_count; i++) {
69 std::string a{};
70 u32 j = 0;
71 while (out_names[i].name[j] != '\0') {
72 a += out_names[i].name[j];
73 j++;
74 }
75 out += "\n\t" + a;
76 }
77
78 LOG_DEBUG(Service_Audio, "called.\nNames={}", out);
79 R_SUCCEED();
80}
81
82Result IAudioDevice::SetAudioDeviceOutputVolumeAuto(
83 InArray<AudioDevice::AudioDeviceName, BufferAttr_HipcAutoSelect> name, f32 volume) {
84 R_UNLESS(!name.empty(), Audio::ResultInsufficientBuffer);
85
86 const std::string device_name = Common::StringFromBuffer(name[0].name);
87 LOG_DEBUG(Service_Audio, "called. name={}, volume={}", device_name, volume);
88
89 if (device_name == "AudioTvOutput") {
90 impl->SetDeviceVolumes(volume);
91 }
92
93 R_SUCCEED();
94}
95
96Result IAudioDevice::GetAudioDeviceOutputVolumeAuto(
97 Out<f32> out_volume, InArray<AudioDevice::AudioDeviceName, BufferAttr_HipcAutoSelect> name) {
98 R_UNLESS(!name.empty(), Audio::ResultInsufficientBuffer);
99
100 const std::string device_name = Common::StringFromBuffer(name[0].name);
101 LOG_DEBUG(Service_Audio, "called. Name={}", device_name);
102
103 *out_volume = 1.0f;
104 if (device_name == "AudioTvOutput") {
105 *out_volume = impl->GetDeviceVolume(device_name);
106 }
107
108 R_SUCCEED();
109}
110
111Result IAudioDevice::GetActiveAudioDeviceNameAuto(
112 OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcAutoSelect> out_name) {
113 R_UNLESS(!out_name.empty(), Audio::ResultInsufficientBuffer);
114 out_name[0] = AudioDevice::AudioDeviceName("AudioTvOutput");
115 LOG_DEBUG(Service_Audio, "(STUBBED) called");
116 R_SUCCEED();
117}
118
119Result IAudioDevice::QueryAudioDeviceSystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
120 LOG_DEBUG(Service_Audio, "(STUBBED) called");
121 event->Signal();
122 *out_event = &event->GetReadableEvent();
123 R_SUCCEED();
124}
125
126Result IAudioDevice::QueryAudioDeviceInputEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
127 LOG_DEBUG(Service_Audio, "(STUBBED) called");
128 *out_event = &event->GetReadableEvent();
129 R_SUCCEED();
130}
131
132Result IAudioDevice::QueryAudioDeviceOutputEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
133 LOG_DEBUG(Service_Audio, "called");
134 *out_event = &event->GetReadableEvent();
135 R_SUCCEED();
136}
137
138Result IAudioDevice::GetActiveChannelCount(Out<u32> out_active_channel_count) {
139 *out_active_channel_count = system.AudioCore().GetOutputSink().GetSystemChannels();
140 LOG_DEBUG(Service_Audio, "(STUBBED) called. Channels={}", *out_active_channel_count);
141 R_SUCCEED();
142}
143
144Result IAudioDevice::ListAudioOutputDeviceName(
145 OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> out_names, Out<s32> out_count) {
146 *out_count = impl->ListAudioOutputDeviceName(out_names);
147
148 std::string out{};
149 for (s32 i = 0; i < *out_count; i++) {
150 std::string a{};
151 u32 j = 0;
152 while (out_names[i].name[j] != '\0') {
153 a += out_names[i].name[j];
154 j++;
155 }
156 out += "\n\t" + a;
157 }
158
159 LOG_DEBUG(Service_Audio, "called.\nNames={}", out);
160 R_SUCCEED();
161}
162
163} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio_device.h b/src/core/hle/service/audio/audio_device.h
new file mode 100755
index 000000000..752157272
--- /dev/null
+++ b/src/core/hle/service/audio/audio_device.h
@@ -0,0 +1,58 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "audio_core/renderer/audio_device.h"
7#include "core/hle/service/cmif_types.h"
8#include "core/hle/service/kernel_helpers.h"
9#include "core/hle/service/service.h"
10
11namespace Kernel {
12class KReadableEvent;
13}
14
15namespace Service::Audio {
16
17using AudioCore::Renderer::AudioDevice;
18
19class IAudioDevice final : public ServiceFramework<IAudioDevice> {
20
21public:
22 explicit IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u32 revision,
23 u32 device_num);
24 ~IAudioDevice() override;
25
26private:
27 Result ListAudioDeviceName(
28 OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> out_names,
29 Out<s32> out_count);
30 Result SetAudioDeviceOutputVolume(
31 InArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> name, f32 volume);
32 Result GetAudioDeviceOutputVolume(
33 Out<f32> out_volume, InArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> name);
34 Result GetActiveAudioDeviceName(
35 OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> out_name);
36 Result ListAudioDeviceNameAuto(
37 OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcAutoSelect> out_names,
38 Out<s32> out_count);
39 Result SetAudioDeviceOutputVolumeAuto(
40 InArray<AudioDevice::AudioDeviceName, BufferAttr_HipcAutoSelect> name, f32 volume);
41 Result GetAudioDeviceOutputVolumeAuto(
42 Out<f32> out_volume, InArray<AudioDevice::AudioDeviceName, BufferAttr_HipcAutoSelect> name);
43 Result GetActiveAudioDeviceNameAuto(
44 OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcAutoSelect> out_name);
45 Result QueryAudioDeviceSystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
46 Result QueryAudioDeviceInputEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
47 Result QueryAudioDeviceOutputEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
48 Result GetActiveChannelCount(Out<u32> out_active_channel_count);
49 Result ListAudioOutputDeviceName(
50 OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> out_names,
51 Out<s32> out_count);
52
53 KernelHelpers::ServiceContext service_context;
54 std::unique_ptr<AudioCore::Renderer::AudioDevice> impl;
55 Kernel::KEvent* event;
56};
57
58} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio_in.cpp b/src/core/hle/service/audio/audio_in.cpp
new file mode 100755
index 000000000..416803acc
--- /dev/null
+++ b/src/core/hle/service/audio/audio_in.cpp
@@ -0,0 +1,146 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/audio/audio_in.h"
5#include "core/hle/service/cmif_serialization.h"
6#include "core/hle/service/ipc_helpers.h"
7
8namespace Service::Audio {
9using namespace AudioCore::AudioIn;
10
11IAudioIn::IAudioIn(Core::System& system_, Manager& manager, size_t session_id,
12 const std::string& device_name, const AudioInParameter& in_params,
13 Kernel::KProcess* handle, u64 applet_resource_user_id)
14 : ServiceFramework{system_, "IAudioIn"}, process{handle}, service_context{system_, "IAudioIn"},
15 event{service_context.CreateEvent("AudioInEvent")}, impl{std::make_shared<In>(system_,
16 manager, event,
17 session_id)} {
18 // clang-format off
19 static const FunctionInfo functions[] = {
20 {0, D<&IAudioIn::GetAudioInState>, "GetAudioInState"},
21 {1, D<&IAudioIn::Start>, "Start"},
22 {2, D<&IAudioIn::Stop>, "Stop"},
23 {3, D<&IAudioIn::AppendAudioInBuffer>, "AppendAudioInBuffer"},
24 {4, D<&IAudioIn::RegisterBufferEvent>, "RegisterBufferEvent"},
25 {5, D<&IAudioIn::GetReleasedAudioInBuffers>, "GetReleasedAudioInBuffers"},
26 {6, D<&IAudioIn::ContainsAudioInBuffer>, "ContainsAudioInBuffer"},
27 {7, D<&IAudioIn::AppendAudioInBuffer>, "AppendUacInBuffer"},
28 {8, D<&IAudioIn::AppendAudioInBufferAuto>, "AppendAudioInBufferAuto"},
29 {9, D<&IAudioIn::GetReleasedAudioInBuffersAuto>, "GetReleasedAudioInBuffersAuto"},
30 {10, D<&IAudioIn::AppendAudioInBufferAuto>, "AppendUacInBufferAuto"},
31 {11, D<&IAudioIn::GetAudioInBufferCount>, "GetAudioInBufferCount"},
32 {12, D<&IAudioIn::SetDeviceGain>, "SetDeviceGain"},
33 {13, D<&IAudioIn::GetDeviceGain>, "GetDeviceGain"},
34 {14, D<&IAudioIn::FlushAudioInBuffers>, "FlushAudioInBuffers"},
35 };
36 // clang-format on
37
38 RegisterHandlers(functions);
39
40 process->Open();
41
42 if (impl->GetSystem()
43 .Initialize(device_name, in_params, handle, applet_resource_user_id)
44 .IsError()) {
45 LOG_ERROR(Service_Audio, "Failed to initialize the AudioIn System!");
46 }
47}
48
49IAudioIn::~IAudioIn() {
50 impl->Free();
51 service_context.CloseEvent(event);
52 process->Close();
53}
54
55Result IAudioIn::GetAudioInState(Out<u32> out_state) {
56 *out_state = static_cast<u32>(impl->GetState());
57 LOG_DEBUG(Service_Audio, "called. state={}", *out_state);
58 R_SUCCEED();
59}
60
61Result IAudioIn::Start() {
62 LOG_DEBUG(Service_Audio, "called");
63 R_RETURN(impl->StartSystem());
64}
65
66Result IAudioIn::Stop() {
67 LOG_DEBUG(Service_Audio, "called");
68 R_RETURN(impl->StopSystem());
69}
70
71Result IAudioIn::AppendAudioInBuffer(InArray<AudioInBuffer, BufferAttr_HipcMapAlias> buffer,
72 u64 buffer_client_ptr) {
73 R_RETURN(this->AppendAudioInBufferAuto(buffer, buffer_client_ptr));
74}
75
76Result IAudioIn::AppendAudioInBufferAuto(InArray<AudioInBuffer, BufferAttr_HipcAutoSelect> buffer,
77 u64 buffer_client_ptr) {
78 if (buffer.empty()) {
79 LOG_ERROR(Service_Audio, "Input buffer is too small for an AudioInBuffer!");
80 R_THROW(Audio::ResultInsufficientBuffer);
81 }
82
83 [[maybe_unused]] const auto session_id{impl->GetSystem().GetSessionId()};
84 LOG_TRACE(Service_Audio, "called. Session {} Appending buffer {:08X}", session_id,
85 buffer_client_ptr);
86
87 R_RETURN(impl->AppendBuffer(buffer[0], buffer_client_ptr));
88}
89
90Result IAudioIn::RegisterBufferEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
91 LOG_DEBUG(Service_Audio, "called");
92 *out_event = &impl->GetBufferEvent();
93 R_SUCCEED();
94}
95
96Result IAudioIn::GetReleasedAudioInBuffers(OutArray<u64, BufferAttr_HipcMapAlias> out_audio_buffer,
97 Out<u32> out_count) {
98 R_RETURN(this->GetReleasedAudioInBuffersAuto(out_audio_buffer, out_count));
99}
100
101Result IAudioIn::GetReleasedAudioInBuffersAuto(
102 OutArray<u64, BufferAttr_HipcAutoSelect> out_audio_buffer, Out<u32> out_count) {
103
104 if (!out_audio_buffer.empty()) {
105 out_audio_buffer[0] = 0;
106 }
107 *out_count = impl->GetReleasedBuffers(out_audio_buffer);
108
109 LOG_TRACE(Service_Audio, "called. Session {} released {} buffers",
110 impl->GetSystem().GetSessionId(), *out_count);
111 R_SUCCEED();
112}
113
114Result IAudioIn::ContainsAudioInBuffer(Out<bool> out_contains_buffer, u64 buffer_client_ptr) {
115 *out_contains_buffer = impl->ContainsAudioBuffer(buffer_client_ptr);
116
117 LOG_DEBUG(Service_Audio, "called. Is buffer {:08X} registered? {}", buffer_client_ptr,
118 *out_contains_buffer);
119 R_SUCCEED();
120}
121
122Result IAudioIn::GetAudioInBufferCount(Out<u32> out_buffer_count) {
123 *out_buffer_count = impl->GetBufferCount();
124 LOG_DEBUG(Service_Audio, "called. Buffer count={}", *out_buffer_count);
125 R_SUCCEED();
126}
127
128Result IAudioIn::SetDeviceGain(f32 device_gain) {
129 impl->SetVolume(device_gain);
130 LOG_DEBUG(Service_Audio, "called. Gain {}", device_gain);
131 R_SUCCEED();
132}
133
134Result IAudioIn::GetDeviceGain(Out<f32> out_device_gain) {
135 *out_device_gain = impl->GetVolume();
136 LOG_DEBUG(Service_Audio, "called. Gain {}", *out_device_gain);
137 R_SUCCEED();
138}
139
140Result IAudioIn::FlushAudioInBuffers(Out<bool> out_flushed) {
141 *out_flushed = impl->FlushAudioInBuffers();
142 LOG_DEBUG(Service_Audio, "called. Were any buffers flushed? {}", *out_flushed);
143 R_SUCCEED();
144}
145
146} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio_in.h b/src/core/hle/service/audio/audio_in.h
new file mode 100755
index 000000000..3fe1e1e87
--- /dev/null
+++ b/src/core/hle/service/audio/audio_in.h
@@ -0,0 +1,53 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "audio_core/in/audio_in.h"
7#include "core/hle/service/cmif_types.h"
8#include "core/hle/service/kernel_helpers.h"
9#include "core/hle/service/service.h"
10
11namespace Service::Audio {
12
13class IAudioIn final : public ServiceFramework<IAudioIn> {
14public:
15 explicit IAudioIn(Core::System& system_, AudioCore::AudioIn::Manager& manager,
16 size_t session_id, const std::string& device_name,
17 const AudioCore::AudioIn::AudioInParameter& in_params,
18 Kernel::KProcess* handle, u64 applet_resource_user_id);
19 ~IAudioIn() override;
20
21 std::shared_ptr<AudioCore::AudioIn::In> GetImpl() {
22 return impl;
23 }
24
25 Result GetAudioInState(Out<u32> out_state);
26 Result Start();
27 Result Stop();
28 Result AppendAudioInBuffer(
29 InArray<AudioCore::AudioIn::AudioInBuffer, BufferAttr_HipcMapAlias> buffer,
30 u64 buffer_client_ptr);
31 Result AppendAudioInBufferAuto(
32 InArray<AudioCore::AudioIn::AudioInBuffer, BufferAttr_HipcAutoSelect> buffer,
33 u64 buffer_client_ptr);
34 Result RegisterBufferEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
35 Result GetReleasedAudioInBuffers(OutArray<u64, BufferAttr_HipcMapAlias> out_audio_buffer,
36 Out<u32> out_count);
37 Result GetReleasedAudioInBuffersAuto(OutArray<u64, BufferAttr_HipcAutoSelect> out_audio_buffer,
38 Out<u32> out_count);
39 Result ContainsAudioInBuffer(Out<bool> out_contains_buffer, u64 buffer_client_ptr);
40 Result GetAudioInBufferCount(Out<u32> out_buffer_count);
41 Result SetDeviceGain(f32 device_gain);
42 Result GetDeviceGain(Out<f32> out_device_gain);
43 Result FlushAudioInBuffers(Out<bool> out_flushed);
44
45private:
46 Kernel::KProcess* process;
47 KernelHelpers::ServiceContext service_context;
48 Kernel::KEvent* event;
49 std::shared_ptr<AudioCore::AudioIn::In> impl;
50 Common::ScratchBuffer<u64> released_buffer;
51};
52
53} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio_in_manager.cpp b/src/core/hle/service/audio/audio_in_manager.cpp
new file mode 100755
index 000000000..2675a5773
--- /dev/null
+++ b/src/core/hle/service/audio/audio_in_manager.cpp
@@ -0,0 +1,125 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/string_util.h"
5#include "core/hle/service/audio/audio_in.h"
6#include "core/hle/service/audio/audio_in_manager.h"
7#include "core/hle/service/cmif_serialization.h"
8
9namespace Service::Audio {
10using namespace AudioCore::AudioIn;
11
12IAudioInManager::IAudioInManager(Core::System& system_)
13 : ServiceFramework{system_, "audin:u"}, impl{std::make_unique<AudioCore::AudioIn::Manager>(
14 system_)} {
15 // clang-format off
16 static const FunctionInfo functions[] = {
17 {0, D<&IAudioInManager::ListAudioIns>, "ListAudioIns"},
18 {1, D<&IAudioInManager::OpenAudioIn>, "OpenAudioIn"},
19 {2, D<&IAudioInManager::ListAudioIns>, "ListAudioInsAuto"},
20 {3, D<&IAudioInManager::OpenAudioIn>, "OpenAudioInAuto"},
21 {4, D<&IAudioInManager::ListAudioInsAutoFiltered>, "ListAudioInsAutoFiltered"},
22 {5, D<&IAudioInManager::OpenAudioInProtocolSpecified>, "OpenAudioInProtocolSpecified"},
23 };
24 // clang-format on
25
26 RegisterHandlers(functions);
27}
28
29IAudioInManager::~IAudioInManager() = default;
30
31Result IAudioInManager::ListAudioIns(
32 OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_audio_ins, Out<u32> out_count) {
33 LOG_DEBUG(Service_Audio, "called");
34 R_RETURN(this->ListAudioInsAutoFiltered(out_audio_ins, out_count));
35}
36
37Result IAudioInManager::OpenAudioIn(Out<AudioInParameterInternal> out_parameter_internal,
38 Out<SharedPointer<IAudioIn>> out_audio_in,
39 OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_name,
40 InArray<AudioDeviceName, BufferAttr_HipcMapAlias> name,
41 AudioInParameter parameter,
42 InCopyHandle<Kernel::KProcess> process_handle,
43 ClientAppletResourceUserId aruid) {
44 LOG_DEBUG(Service_Audio, "called");
45 R_RETURN(this->OpenAudioInProtocolSpecified(out_parameter_internal, out_audio_in, out_name,
46 name, {}, parameter, process_handle, aruid));
47}
48
49Result IAudioInManager::ListAudioInsAuto(
50 OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_ins, Out<u32> out_count) {
51 LOG_DEBUG(Service_Audio, "called");
52 R_RETURN(this->ListAudioInsAutoFiltered(out_audio_ins, out_count));
53}
54
55Result IAudioInManager::OpenAudioInAuto(
56 Out<AudioInParameterInternal> out_parameter_internal, Out<SharedPointer<IAudioIn>> out_audio_in,
57 OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_name,
58 InArray<AudioDeviceName, BufferAttr_HipcAutoSelect> name, AudioInParameter parameter,
59 InCopyHandle<Kernel::KProcess> process_handle, ClientAppletResourceUserId aruid) {
60 LOG_DEBUG(Service_Audio, "called");
61 R_RETURN(this->OpenAudioInProtocolSpecified(out_parameter_internal, out_audio_in, out_name,
62 name, {}, parameter, process_handle, aruid));
63}
64
65Result IAudioInManager::ListAudioInsAutoFiltered(
66 OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_ins, Out<u32> out_count) {
67 LOG_DEBUG(Service_Audio, "called");
68 *out_count = impl->GetDeviceNames(out_audio_ins, true);
69 R_SUCCEED();
70}
71
72Result IAudioInManager::OpenAudioInProtocolSpecified(
73 Out<AudioInParameterInternal> out_parameter_internal, Out<SharedPointer<IAudioIn>> out_audio_in,
74 OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_name,
75 InArray<AudioDeviceName, BufferAttr_HipcAutoSelect> name, Protocol protocol,
76 AudioInParameter parameter, InCopyHandle<Kernel::KProcess> process_handle,
77 ClientAppletResourceUserId aruid) {
78 LOG_DEBUG(Service_Audio, "called");
79
80 if (!process_handle) {
81 LOG_ERROR(Service_Audio, "Failed to get process handle");
82 R_THROW(ResultUnknown);
83 }
84 if (name.empty() || out_name.empty()) {
85 LOG_ERROR(Service_Audio, "Invalid buffers");
86 R_THROW(ResultUnknown);
87 }
88
89 std::scoped_lock l{impl->mutex};
90
91 size_t new_session_id{};
92
93 R_TRY(impl->LinkToManager());
94 R_TRY(impl->AcquireSessionId(new_session_id));
95
96 LOG_DEBUG(Service_Audio, "Opening new AudioIn, session_id={}, free sessions={}", new_session_id,
97 impl->num_free_sessions);
98
99 const auto device_name = Common::StringFromBuffer(name[0].name);
100 *out_audio_in = std::make_shared<IAudioIn>(system, *impl, new_session_id, device_name,
101 parameter, process_handle.Get(), aruid.pid);
102 impl->sessions[new_session_id] = (*out_audio_in)->GetImpl();
103 impl->applet_resource_user_ids[new_session_id] = aruid.pid;
104
105 auto& out_system = impl->sessions[new_session_id]->GetSystem();
106 *out_parameter_internal =
107 AudioInParameterInternal{.sample_rate = out_system.GetSampleRate(),
108 .channel_count = out_system.GetChannelCount(),
109 .sample_format = static_cast<u32>(out_system.GetSampleFormat()),
110 .state = static_cast<u32>(out_system.GetState())};
111
112 out_name[0] = AudioDeviceName(out_system.GetName());
113
114 if (protocol == Protocol{}) {
115 if (out_system.IsUac()) {
116 out_name[0] = AudioDeviceName("UacIn");
117 } else {
118 out_name[0] = AudioDeviceName("DeviceIn");
119 }
120 }
121
122 R_SUCCEED();
123}
124
125} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio_in_manager.h b/src/core/hle/service/audio/audio_in_manager.h
new file mode 100755
index 000000000..2a983bc60
--- /dev/null
+++ b/src/core/hle/service/audio/audio_in_manager.h
@@ -0,0 +1,57 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "audio_core/audio_in_manager.h"
7#include "audio_core/in/audio_in_system.h"
8#include "core/hle/service/cmif_types.h"
9#include "core/hle/service/service.h"
10
11namespace Service::Audio {
12
13using AudioDeviceName = AudioCore::Renderer::AudioDevice::AudioDeviceName;
14using Protocol = std::array<u32, 2>;
15
16class IAudioIn;
17
18class IAudioInManager final : public ServiceFramework<IAudioInManager> {
19public:
20 explicit IAudioInManager(Core::System& system_);
21 ~IAudioInManager() override;
22
23private:
24 Result ListAudioIns(OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_audio_ins,
25 Out<u32> out_count);
26 Result OpenAudioIn(Out<AudioCore::AudioIn::AudioInParameterInternal> out_parameter_internal,
27 Out<SharedPointer<IAudioIn>> out_audio_in,
28 OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_name,
29 InArray<AudioDeviceName, BufferAttr_HipcMapAlias> name,
30 AudioCore::AudioIn::AudioInParameter parameter,
31 InCopyHandle<Kernel::KProcess> process_handle,
32 ClientAppletResourceUserId aruid);
33
34 Result ListAudioInsAuto(OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_ins,
35 Out<u32> out_count);
36 Result OpenAudioInAuto(Out<AudioCore::AudioIn::AudioInParameterInternal> out_parameter_internal,
37 Out<SharedPointer<IAudioIn>> out_audio_in,
38 OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_name,
39 InArray<AudioDeviceName, BufferAttr_HipcAutoSelect> name,
40 AudioCore::AudioIn::AudioInParameter parameter,
41 InCopyHandle<Kernel::KProcess> process_handle,
42 ClientAppletResourceUserId aruid);
43
44 Result ListAudioInsAutoFiltered(
45 OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_ins, Out<u32> out_count);
46 Result OpenAudioInProtocolSpecified(
47 Out<AudioCore::AudioIn::AudioInParameterInternal> out_parameter_internal,
48 Out<SharedPointer<IAudioIn>> out_audio_in,
49 OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_name,
50 InArray<AudioDeviceName, BufferAttr_HipcAutoSelect> name, Protocol protocol,
51 AudioCore::AudioIn::AudioInParameter parameter,
52 InCopyHandle<Kernel::KProcess> process_handle, ClientAppletResourceUserId aruid);
53
54 std::unique_ptr<AudioCore::AudioIn::Manager> impl;
55};
56
57} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio_out.cpp b/src/core/hle/service/audio/audio_out.cpp
new file mode 100755
index 000000000..53009d5d7
--- /dev/null
+++ b/src/core/hle/service/audio/audio_out.cpp
@@ -0,0 +1,146 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "audio_core/out/audio_out.h"
5#include "audio_core/out/audio_out_system.h"
6#include "core/hle/kernel/k_process.h"
7#include "core/hle/service/audio/audio_out.h"
8#include "core/hle/service/cmif_serialization.h"
9#include "core/hle/service/kernel_helpers.h"
10#include "core/hle/service/service.h"
11
12namespace Service::Audio {
13using namespace AudioCore::AudioOut;
14
15IAudioOut::IAudioOut(Core::System& system_, Manager& manager, size_t session_id,
16 const std::string& device_name, const AudioOutParameter& in_params,
17 Kernel::KProcess* handle, u64 applet_resource_user_id)
18 : ServiceFramework{system_, "IAudioOut"}, service_context{system_, "IAudioOut"},
19 event{service_context.CreateEvent("AudioOutEvent")}, process{handle},
20 impl{std::make_shared<AudioCore::AudioOut::Out>(system_, manager, event, session_id)} {
21
22 // clang-format off
23 static const FunctionInfo functions[] = {
24 {0, D<&IAudioOut::GetAudioOutState>, "GetAudioOutState"},
25 {1, D<&IAudioOut::Start>, "Start"},
26 {2, D<&IAudioOut::Stop>, "Stop"},
27 {3, D<&IAudioOut::AppendAudioOutBuffer>, "AppendAudioOutBuffer"},
28 {4, D<&IAudioOut::RegisterBufferEvent>, "RegisterBufferEvent"},
29 {5, D<&IAudioOut::GetReleasedAudioOutBuffers>, "GetReleasedAudioOutBuffers"},
30 {6, D<&IAudioOut::ContainsAudioOutBuffer>, "ContainsAudioOutBuffer"},
31 {7, D<&IAudioOut::AppendAudioOutBufferAuto>, "AppendAudioOutBufferAuto"},
32 {8, D<&IAudioOut::GetReleasedAudioOutBuffersAuto>, "GetReleasedAudioOutBuffersAuto"},
33 {9, D<&IAudioOut::GetAudioOutBufferCount>, "GetAudioOutBufferCount"},
34 {10, D<&IAudioOut::GetAudioOutPlayedSampleCount>, "GetAudioOutPlayedSampleCount"},
35 {11, D<&IAudioOut::FlushAudioOutBuffers>, "FlushAudioOutBuffers"},
36 {12, D<&IAudioOut::SetAudioOutVolume>, "SetAudioOutVolume"},
37 {13, D<&IAudioOut::GetAudioOutVolume>, "GetAudioOutVolume"},
38 };
39 // clang-format on
40 RegisterHandlers(functions);
41
42 process->Open();
43}
44
45IAudioOut::~IAudioOut() {
46 impl->Free();
47 service_context.CloseEvent(event);
48 process->Close();
49}
50
51Result IAudioOut::GetAudioOutState(Out<u32> out_state) {
52 *out_state = static_cast<u32>(impl->GetState());
53 LOG_DEBUG(Service_Audio, "called. state={}", *out_state);
54 R_SUCCEED();
55}
56
57Result IAudioOut::Start() {
58 LOG_DEBUG(Service_Audio, "called");
59 R_RETURN(impl->StartSystem());
60}
61
62Result IAudioOut::Stop() {
63 LOG_DEBUG(Service_Audio, "called");
64 R_RETURN(impl->StopSystem());
65}
66
67Result IAudioOut::AppendAudioOutBuffer(
68 InArray<AudioOutBuffer, BufferAttr_HipcMapAlias> audio_out_buffer, u64 buffer_client_ptr) {
69 R_RETURN(this->AppendAudioOutBufferAuto(audio_out_buffer, buffer_client_ptr));
70}
71
72Result IAudioOut::AppendAudioOutBufferAuto(
73 InArray<AudioOutBuffer, BufferAttr_HipcAutoSelect> audio_out_buffer, u64 buffer_client_ptr) {
74 if (audio_out_buffer.empty()) {
75 LOG_ERROR(Service_Audio, "Input buffer is too small for an AudioOutBuffer!");
76 R_THROW(Audio::ResultInsufficientBuffer);
77 }
78
79 LOG_TRACE(Service_Audio, "called. Session {} Appending buffer {:08X}",
80 impl->GetSystem().GetSessionId(), buffer_client_ptr);
81 R_RETURN(impl->AppendBuffer(audio_out_buffer[0], buffer_client_ptr));
82}
83
84Result IAudioOut::RegisterBufferEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
85 LOG_DEBUG(Service_Audio, "called");
86 *out_event = &impl->GetBufferEvent();
87 R_SUCCEED();
88}
89
90Result IAudioOut::GetReleasedAudioOutBuffers(
91 OutArray<u64, BufferAttr_HipcMapAlias> out_audio_buffer, Out<u32> out_count) {
92 R_RETURN(this->GetReleasedAudioOutBuffersAuto(out_audio_buffer, out_count));
93}
94
95Result IAudioOut::GetReleasedAudioOutBuffersAuto(
96 OutArray<u64, BufferAttr_HipcAutoSelect> out_audio_buffer, Out<u32> out_count) {
97
98 if (!out_audio_buffer.empty()) {
99 out_audio_buffer[0] = 0;
100 }
101 *out_count = impl->GetReleasedBuffers(out_audio_buffer);
102
103 LOG_TRACE(Service_Audio, "called. Session {} released {} buffers",
104 impl->GetSystem().GetSessionId(), *out_count);
105 R_SUCCEED();
106}
107
108Result IAudioOut::ContainsAudioOutBuffer(Out<bool> out_contains_buffer, u64 buffer_client_ptr) {
109 *out_contains_buffer = impl->ContainsAudioBuffer(buffer_client_ptr);
110
111 LOG_DEBUG(Service_Audio, "called. Is buffer {:08X} registered? {}", buffer_client_ptr,
112 *out_contains_buffer);
113 R_SUCCEED();
114}
115
116Result IAudioOut::GetAudioOutBufferCount(Out<u32> out_buffer_count) {
117 *out_buffer_count = impl->GetBufferCount();
118 LOG_DEBUG(Service_Audio, "called. Buffer count={}", *out_buffer_count);
119 R_SUCCEED();
120}
121
122Result IAudioOut::GetAudioOutPlayedSampleCount(Out<u64> out_played_sample_count) {
123 *out_played_sample_count = impl->GetPlayedSampleCount();
124 LOG_DEBUG(Service_Audio, "called. Played samples={}", *out_played_sample_count);
125 R_SUCCEED();
126}
127
128Result IAudioOut::FlushAudioOutBuffers(Out<bool> out_flushed) {
129 *out_flushed = impl->FlushAudioOutBuffers();
130 LOG_DEBUG(Service_Audio, "called. Were any buffers flushed? {}", *out_flushed);
131 R_SUCCEED();
132}
133
134Result IAudioOut::SetAudioOutVolume(f32 volume) {
135 LOG_DEBUG(Service_Audio, "called. Volume={}", volume);
136 impl->SetVolume(volume);
137 R_SUCCEED();
138}
139
140Result IAudioOut::GetAudioOutVolume(Out<f32> out_volume) {
141 *out_volume = impl->GetVolume();
142 LOG_DEBUG(Service_Audio, "called. Volume={}", *out_volume);
143 R_SUCCEED();
144}
145
146} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio_out.h b/src/core/hle/service/audio/audio_out.h
new file mode 100755
index 000000000..779b213e7
--- /dev/null
+++ b/src/core/hle/service/audio/audio_out.h
@@ -0,0 +1,58 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "audio_core/audio_out_manager.h"
7#include "audio_core/out/audio_out_system.h"
8#include "core/hle/service/cmif_types.h"
9#include "core/hle/service/kernel_helpers.h"
10#include "core/hle/service/service.h"
11
12namespace Kernel {
13class KReadableEvent;
14}
15
16namespace Service::Audio {
17
18class IAudioOut : public ServiceFramework<IAudioOut> {
19public:
20 explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager,
21 size_t session_id, const std::string& device_name,
22 const AudioCore::AudioOut::AudioOutParameter& in_params,
23 Kernel::KProcess* handle, u64 applet_resource_user_id);
24 ~IAudioOut() override;
25
26 std::shared_ptr<AudioCore::AudioOut::Out> GetImpl() {
27 return impl;
28 }
29
30 Result GetAudioOutState(Out<u32> out_state);
31 Result Start();
32 Result Stop();
33 Result AppendAudioOutBuffer(
34 InArray<AudioCore::AudioOut::AudioOutBuffer, BufferAttr_HipcMapAlias> audio_out_buffer,
35 u64 buffer_client_ptr);
36 Result AppendAudioOutBufferAuto(
37 InArray<AudioCore::AudioOut::AudioOutBuffer, BufferAttr_HipcAutoSelect> audio_out_buffer,
38 u64 buffer_client_ptr);
39 Result RegisterBufferEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
40 Result GetReleasedAudioOutBuffers(OutArray<u64, BufferAttr_HipcMapAlias> out_audio_buffer,
41 Out<u32> out_count);
42 Result GetReleasedAudioOutBuffersAuto(OutArray<u64, BufferAttr_HipcAutoSelect> out_audio_buffer,
43 Out<u32> out_count);
44 Result ContainsAudioOutBuffer(Out<bool> out_contains_buffer, u64 buffer_client_ptr);
45 Result GetAudioOutBufferCount(Out<u32> out_buffer_count);
46 Result GetAudioOutPlayedSampleCount(Out<u64> out_played_sample_count);
47 Result FlushAudioOutBuffers(Out<bool> out_flushed);
48 Result SetAudioOutVolume(f32 volume);
49 Result GetAudioOutVolume(Out<f32> out_volume);
50
51private:
52 KernelHelpers::ServiceContext service_context;
53 Kernel::KEvent* event;
54 Kernel::KProcess* process;
55 std::shared_ptr<AudioCore::AudioOut::Out> impl;
56};
57
58} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio_out_manager.cpp b/src/core/hle/service/audio/audio_out_manager.cpp
new file mode 100755
index 000000000..153445097
--- /dev/null
+++ b/src/core/hle/service/audio/audio_out_manager.cpp
@@ -0,0 +1,101 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/string_util.h"
5#include "core/hle/service/audio/audio_out.h"
6#include "core/hle/service/audio/audio_out_manager.h"
7#include "core/hle/service/cmif_serialization.h"
8#include "core/memory.h"
9
10namespace Service::Audio {
11using namespace AudioCore::AudioOut;
12
13IAudioOutManager::IAudioOutManager(Core::System& system_)
14 : ServiceFramework{system_, "audout:u"}, impl{std::make_unique<Manager>(system_)} {
15 // clang-format off
16 static const FunctionInfo functions[] = {
17 {0, D<&IAudioOutManager::ListAudioOuts>, "ListAudioOuts"},
18 {1, D<&IAudioOutManager::OpenAudioOut>, "OpenAudioOut"},
19 {2, D<&IAudioOutManager::ListAudioOutsAuto>, "ListAudioOutsAuto"},
20 {3, D<&IAudioOutManager::OpenAudioOutAuto>, "OpenAudioOutAuto"},
21 };
22 // clang-format on
23
24 RegisterHandlers(functions);
25}
26
27IAudioOutManager::~IAudioOutManager() = default;
28
29Result IAudioOutManager::ListAudioOuts(
30 OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_audio_outs, Out<u32> out_count) {
31 R_RETURN(this->ListAudioOutsAuto(out_audio_outs, out_count));
32}
33
34Result IAudioOutManager::OpenAudioOut(Out<AudioOutParameterInternal> out_parameter_internal,
35 Out<SharedPointer<IAudioOut>> out_audio_out,
36 OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_name,
37 InArray<AudioDeviceName, BufferAttr_HipcMapAlias> name,
38 AudioOutParameter parameter,
39 InCopyHandle<Kernel::KProcess> process_handle,
40 ClientAppletResourceUserId aruid) {
41 R_RETURN(this->OpenAudioOutAuto(out_parameter_internal, out_audio_out, out_name, name,
42 parameter, process_handle, aruid));
43}
44
45Result IAudioOutManager::ListAudioOutsAuto(
46 OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_outs, Out<u32> out_count) {
47 if (!out_audio_outs.empty()) {
48 out_audio_outs[0] = AudioDeviceName("DeviceOut");
49 *out_count = 1;
50 LOG_DEBUG(Service_Audio, "called. \nName=DeviceOut");
51 } else {
52 *out_count = 0;
53 LOG_DEBUG(Service_Audio, "called. Empty buffer passed in.");
54 }
55
56 R_SUCCEED();
57}
58
59Result IAudioOutManager::OpenAudioOutAuto(
60 Out<AudioOutParameterInternal> out_parameter_internal,
61 Out<SharedPointer<IAudioOut>> out_audio_out,
62 OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_name,
63 InArray<AudioDeviceName, BufferAttr_HipcAutoSelect> name, AudioOutParameter parameter,
64 InCopyHandle<Kernel::KProcess> process_handle, ClientAppletResourceUserId aruid) {
65 if (!process_handle) {
66 LOG_ERROR(Service_Audio, "Failed to get process handle");
67 R_THROW(ResultUnknown);
68 }
69 if (name.empty() || out_name.empty()) {
70 LOG_ERROR(Service_Audio, "Invalid buffers");
71 R_THROW(ResultUnknown);
72 }
73
74 size_t new_session_id{};
75 R_TRY(impl->LinkToManager());
76 R_TRY(impl->AcquireSessionId(new_session_id));
77
78 const auto device_name = Common::StringFromBuffer(name[0].name);
79 LOG_DEBUG(Service_Audio, "Opening new AudioOut, sessionid={}, free sessions={}", new_session_id,
80 impl->num_free_sessions);
81
82 auto audio_out = std::make_shared<IAudioOut>(system, *impl, new_session_id, device_name,
83 parameter, process_handle.Get(), aruid.pid);
84 R_TRY(audio_out->GetImpl()->GetSystem().Initialize(device_name, parameter, process_handle.Get(),
85 aruid.pid));
86
87 *out_audio_out = audio_out;
88 impl->sessions[new_session_id] = audio_out->GetImpl();
89 impl->applet_resource_user_ids[new_session_id] = aruid.pid;
90
91 auto& out_system = impl->sessions[new_session_id]->GetSystem();
92 *out_parameter_internal =
93 AudioOutParameterInternal{.sample_rate = out_system.GetSampleRate(),
94 .channel_count = out_system.GetChannelCount(),
95 .sample_format = static_cast<u32>(out_system.GetSampleFormat()),
96 .state = static_cast<u32>(out_system.GetState())};
97
98 R_SUCCEED();
99}
100
101} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio_out_manager.h b/src/core/hle/service/audio/audio_out_manager.h
new file mode 100755
index 000000000..eaa27bc79
--- /dev/null
+++ b/src/core/hle/service/audio/audio_out_manager.h
@@ -0,0 +1,44 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "audio_core/audio_out_manager.h"
7#include "audio_core/out/audio_out.h"
8#include "core/hle/service/cmif_types.h"
9#include "core/hle/service/service.h"
10
11namespace Service::Audio {
12
13using AudioDeviceName = AudioCore::Renderer::AudioDevice::AudioDeviceName;
14class IAudioOut;
15
16class IAudioOutManager final : public ServiceFramework<IAudioOutManager> {
17public:
18 explicit IAudioOutManager(Core::System& system_);
19 ~IAudioOutManager() override;
20
21private:
22 Result ListAudioOuts(OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_audio_outs,
23 Out<u32> out_count);
24 Result OpenAudioOut(Out<AudioCore::AudioOut::AudioOutParameterInternal> out_parameter_internal,
25 Out<SharedPointer<IAudioOut>> out_audio_out,
26 OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_name,
27 InArray<AudioDeviceName, BufferAttr_HipcMapAlias> name,
28 AudioCore::AudioOut::AudioOutParameter parameter,
29 InCopyHandle<Kernel::KProcess> process_handle,
30 ClientAppletResourceUserId aruid);
31 Result ListAudioOutsAuto(OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_outs,
32 Out<u32> out_count);
33 Result OpenAudioOutAuto(
34 Out<AudioCore::AudioOut::AudioOutParameterInternal> out_parameter_internal,
35 Out<SharedPointer<IAudioOut>> out_audio_out,
36 OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_name,
37 InArray<AudioDeviceName, BufferAttr_HipcAutoSelect> name,
38 AudioCore::AudioOut::AudioOutParameter parameter,
39 InCopyHandle<Kernel::KProcess> process_handle, ClientAppletResourceUserId aruid);
40
41 std::unique_ptr<AudioCore::AudioOut::Manager> impl;
42};
43
44} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio_renderer.cpp b/src/core/hle/service/audio/audio_renderer.cpp
new file mode 100755
index 000000000..fc4aad233
--- /dev/null
+++ b/src/core/hle/service/audio/audio_renderer.cpp
@@ -0,0 +1,139 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/audio/audio_renderer.h"
5#include "core/hle/service/cmif_serialization.h"
6
7namespace Service::Audio {
8using namespace AudioCore::Renderer;
9
10IAudioRenderer::IAudioRenderer(Core::System& system_, Manager& manager_,
11 AudioCore::AudioRendererParameterInternal& params,
12 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
13 Kernel::KProcess* process_handle_, u64 applet_resource_user_id,
14 s32 session_id)
15 : ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"},
16 rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_},
17 impl{std::make_unique<Renderer>(system_, manager, rendered_event)}, process_handle{
18 process_handle_} {
19 // clang-format off
20 static const FunctionInfo functions[] = {
21 {0, D<&IAudioRenderer::GetSampleRate>, "GetSampleRate"},
22 {1, D<&IAudioRenderer::GetSampleCount>, "GetSampleCount"},
23 {2, D<&IAudioRenderer::GetMixBufferCount>, "GetMixBufferCount"},
24 {3, D<&IAudioRenderer::GetState>, "GetState"},
25 {4, D<&IAudioRenderer::RequestUpdate>, "RequestUpdate"},
26 {5, D<&IAudioRenderer::Start>, "Start"},
27 {6, D<&IAudioRenderer::Stop>, "Stop"},
28 {7, D<&IAudioRenderer::QuerySystemEvent>, "QuerySystemEvent"},
29 {8, D<&IAudioRenderer::SetRenderingTimeLimit>, "SetRenderingTimeLimit"},
30 {9, D<&IAudioRenderer::GetRenderingTimeLimit>, "GetRenderingTimeLimit"},
31 {10, D<&IAudioRenderer::RequestUpdateAuto>, "RequestUpdateAuto"},
32 {11, nullptr, "ExecuteAudioRendererRendering"},
33 {12, D<&IAudioRenderer::SetVoiceDropParameter>, "SetVoiceDropParameter"},
34 {13, D<&IAudioRenderer::GetVoiceDropParameter>, "GetVoiceDropParameter"},
35 };
36 // clang-format on
37 RegisterHandlers(functions);
38
39 process_handle->Open();
40 impl->Initialize(params, transfer_memory, transfer_memory_size, process_handle,
41 applet_resource_user_id, session_id);
42}
43
44IAudioRenderer::~IAudioRenderer() {
45 impl->Finalize();
46 service_context.CloseEvent(rendered_event);
47 process_handle->Close();
48}
49
50Result IAudioRenderer::GetSampleRate(Out<u32> out_sample_rate) {
51 *out_sample_rate = impl->GetSystem().GetSampleRate();
52 LOG_DEBUG(Service_Audio, "called. Sample rate {}", *out_sample_rate);
53 R_SUCCEED();
54}
55
56Result IAudioRenderer::GetSampleCount(Out<u32> out_sample_count) {
57 *out_sample_count = impl->GetSystem().GetSampleCount();
58 LOG_DEBUG(Service_Audio, "called. Sample count {}", *out_sample_count);
59 R_SUCCEED();
60}
61
62Result IAudioRenderer::GetState(Out<u32> out_state) {
63 *out_state = !impl->GetSystem().IsActive();
64 LOG_DEBUG(Service_Audio, "called, state {}", *out_state);
65 R_SUCCEED();
66}
67
68Result IAudioRenderer::GetMixBufferCount(Out<u32> out_mix_buffer_count) {
69 LOG_DEBUG(Service_Audio, "called");
70 *out_mix_buffer_count = impl->GetSystem().GetMixBufferCount();
71 R_SUCCEED();
72}
73
74Result IAudioRenderer::RequestUpdate(OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
75 OutBuffer<BufferAttr_HipcMapAlias> out_performance_buffer,
76 InBuffer<BufferAttr_HipcMapAlias> input) {
77 R_RETURN(this->RequestUpdateAuto(out_buffer, out_performance_buffer, input));
78}
79
80Result IAudioRenderer::RequestUpdateAuto(
81 OutBuffer<BufferAttr_HipcAutoSelect> out_buffer,
82 OutBuffer<BufferAttr_HipcAutoSelect> out_performance_buffer,
83 InBuffer<BufferAttr_HipcAutoSelect> input) {
84 LOG_TRACE(Service_Audio, "called");
85
86 const auto result = impl->RequestUpdate(input, out_performance_buffer, out_buffer);
87 if (result.IsFailure()) {
88 LOG_ERROR(Service_Audio, "RequestUpdate failed error 0x{:02X}!", result.GetDescription());
89 }
90
91 R_RETURN(result);
92}
93
94Result IAudioRenderer::Start() {
95 LOG_DEBUG(Service_Audio, "called");
96 impl->Start();
97 R_SUCCEED();
98}
99
100Result IAudioRenderer::Stop() {
101 LOG_DEBUG(Service_Audio, "called");
102 impl->Stop();
103 R_SUCCEED();
104}
105
106Result IAudioRenderer::QuerySystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
107 LOG_DEBUG(Service_Audio, "called");
108 R_UNLESS(impl->GetSystem().GetExecutionMode() != AudioCore::ExecutionMode::Manual,
109 Audio::ResultNotSupported);
110 *out_event = &rendered_event->GetReadableEvent();
111 R_SUCCEED();
112}
113
114Result IAudioRenderer::SetRenderingTimeLimit(u32 rendering_time_limit) {
115 LOG_DEBUG(Service_Audio, "called");
116 impl->GetSystem().SetRenderingTimeLimit(rendering_time_limit);
117 ;
118 R_SUCCEED();
119}
120
121Result IAudioRenderer::GetRenderingTimeLimit(Out<u32> out_rendering_time_limit) {
122 LOG_DEBUG(Service_Audio, "called");
123 *out_rendering_time_limit = impl->GetSystem().GetRenderingTimeLimit();
124 R_SUCCEED();
125}
126
127Result IAudioRenderer::SetVoiceDropParameter(f32 voice_drop_parameter) {
128 LOG_DEBUG(Service_Audio, "called");
129 impl->GetSystem().SetVoiceDropParameter(voice_drop_parameter);
130 R_SUCCEED();
131}
132
133Result IAudioRenderer::GetVoiceDropParameter(Out<f32> out_voice_drop_parameter) {
134 LOG_DEBUG(Service_Audio, "called");
135 *out_voice_drop_parameter = impl->GetSystem().GetVoiceDropParameter();
136 R_SUCCEED();
137}
138
139} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio_renderer.h b/src/core/hle/service/audio/audio_renderer.h
new file mode 100755
index 000000000..f25c50ce8
--- /dev/null
+++ b/src/core/hle/service/audio/audio_renderer.h
@@ -0,0 +1,54 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "audio_core/renderer/audio_renderer.h"
7#include "core/hle/service/cmif_types.h"
8#include "core/hle/service/kernel_helpers.h"
9#include "core/hle/service/service.h"
10
11namespace Kernel {
12class KReadableEvent;
13}
14
15namespace Service::Audio {
16
17class IAudioRenderer final : public ServiceFramework<IAudioRenderer> {
18public:
19 explicit IAudioRenderer(Core::System& system_, AudioCore::Renderer::Manager& manager_,
20 AudioCore::AudioRendererParameterInternal& params,
21 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
22 Kernel::KProcess* process_handle_, u64 applet_resource_user_id,
23 s32 session_id);
24 ~IAudioRenderer() override;
25
26private:
27 Result GetSampleRate(Out<u32> out_sample_rate);
28 Result GetSampleCount(Out<u32> out_sample_count);
29 Result GetState(Out<u32> out_state);
30 Result GetMixBufferCount(Out<u32> out_mix_buffer_count);
31 Result RequestUpdate(OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
32 OutBuffer<BufferAttr_HipcMapAlias> out_performance_buffer,
33 InBuffer<BufferAttr_HipcMapAlias> input);
34 Result RequestUpdateAuto(OutBuffer<BufferAttr_HipcAutoSelect> out_buffer,
35 OutBuffer<BufferAttr_HipcAutoSelect> out_performance_buffer,
36 InBuffer<BufferAttr_HipcAutoSelect> input);
37 Result Start();
38 Result Stop();
39 Result QuerySystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
40 Result SetRenderingTimeLimit(u32 rendering_time_limit);
41 Result GetRenderingTimeLimit(Out<u32> out_rendering_time_limit);
42 Result SetVoiceDropParameter(f32 voice_drop_parameter);
43 Result GetVoiceDropParameter(Out<f32> out_voice_drop_parameter);
44
45 KernelHelpers::ServiceContext service_context;
46 Kernel::KEvent* rendered_event;
47 AudioCore::Renderer::Manager& manager;
48 std::unique_ptr<AudioCore::Renderer::Renderer> impl;
49 Kernel::KProcess* process_handle;
50 Common::ScratchBuffer<u8> output_buffer;
51 Common::ScratchBuffer<u8> performance_buffer;
52};
53
54} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio_renderer_manager.cpp b/src/core/hle/service/audio/audio_renderer_manager.cpp
new file mode 100755
index 000000000..6a1345c07
--- /dev/null
+++ b/src/core/hle/service/audio/audio_renderer_manager.cpp
@@ -0,0 +1,104 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "audio_core/audio_render_manager.h"
5#include "audio_core/common/feature_support.h"
6#include "core/hle/kernel/k_process.h"
7#include "core/hle/kernel/k_transfer_memory.h"
8#include "core/hle/service/audio/audio_device.h"
9#include "core/hle/service/audio/audio_renderer.h"
10#include "core/hle/service/audio/audio_renderer_manager.h"
11#include "core/hle/service/cmif_serialization.h"
12
13namespace Service::Audio {
14
15using namespace AudioCore::Renderer;
16
17IAudioRendererManager::IAudioRendererManager(Core::System& system_)
18 : ServiceFramework{system_, "audren:u"}, impl{std::make_unique<Manager>(system_)} {
19 // clang-format off
20 static const FunctionInfo functions[] = {
21 {0, D<&IAudioRendererManager::OpenAudioRenderer>, "OpenAudioRenderer"},
22 {1, D<&IAudioRendererManager::GetWorkBufferSize>, "GetWorkBufferSize"},
23 {2, D<&IAudioRendererManager::GetAudioDeviceService>, "GetAudioDeviceService"},
24 {3, nullptr, "OpenAudioRendererForManualExecution"},
25 {4, D<&IAudioRendererManager::GetAudioDeviceServiceWithRevisionInfo>, "GetAudioDeviceServiceWithRevisionInfo"},
26 };
27 // clang-format on
28
29 RegisterHandlers(functions);
30}
31
32IAudioRendererManager::~IAudioRendererManager() = default;
33
34Result IAudioRendererManager::OpenAudioRenderer(
35 Out<SharedPointer<IAudioRenderer>> out_audio_renderer,
36 AudioCore::AudioRendererParameterInternal parameter,
37 InCopyHandle<Kernel::KTransferMemory> tmem_handle, u64 tmem_size,
38 InCopyHandle<Kernel::KProcess> process_handle, ClientAppletResourceUserId aruid) {
39 LOG_DEBUG(Service_Audio, "called");
40
41 if (impl->GetSessionCount() + 1 > AudioCore::MaxRendererSessions) {
42 LOG_ERROR(Service_Audio, "Too many AudioRenderer sessions open!");
43 R_THROW(Audio::ResultOutOfSessions);
44 }
45
46 const auto session_id{impl->GetSessionId()};
47 if (session_id == -1) {
48 LOG_ERROR(Service_Audio, "Tried to open a session that's already in use!");
49 R_THROW(Audio::ResultOutOfSessions);
50 }
51
52 LOG_DEBUG(Service_Audio, "Opened new AudioRenderer session {} sessions open {}", session_id,
53 impl->GetSessionCount());
54
55 *out_audio_renderer =
56 std::make_shared<IAudioRenderer>(system, *impl, parameter, tmem_handle.Get(), tmem_size,
57 process_handle.Get(), aruid.pid, session_id);
58 R_SUCCEED();
59}
60
61Result IAudioRendererManager::GetWorkBufferSize(Out<u64> out_size,
62 AudioCore::AudioRendererParameterInternal params) {
63 LOG_DEBUG(Service_Audio, "called");
64
65 R_TRY(impl->GetWorkBufferSize(params, *out_size))
66
67 std::string output_info{};
68 output_info += fmt::format("\tRevision {}", AudioCore::GetRevisionNum(params.revision));
69 output_info +=
70 fmt::format("\n\tSample Rate {}, Sample Count {}", params.sample_rate, params.sample_count);
71 output_info += fmt::format("\n\tExecution Mode {}, Voice Drop Enabled {}",
72 static_cast<u32>(params.execution_mode), params.voice_drop_enabled);
73 output_info += fmt::format(
74 "\n\tSizes: Effects {:04X}, Mixes {:04X}, Sinks {:04X}, Submixes {:04X}, Splitter Infos "
75 "{:04X}, Splitter Destinations {:04X}, Voices {:04X}, Performance Frames {:04X} External "
76 "Context {:04X}",
77 params.effects, params.mixes, params.sinks, params.sub_mixes, params.splitter_infos,
78 params.splitter_destinations, params.voices, params.perf_frames,
79 params.external_context_size);
80
81 LOG_DEBUG(Service_Audio, "called.\nInput params:\n{}\nOutput params:\n\tWorkbuffer size {:08X}",
82 output_info, *out_size);
83 R_SUCCEED();
84}
85
86Result IAudioRendererManager::GetAudioDeviceService(
87 Out<SharedPointer<IAudioDevice>> out_audio_device, ClientAppletResourceUserId aruid) {
88 LOG_DEBUG(Service_Audio, "called, aruid={:#x}", aruid.pid);
89 *out_audio_device = std::make_shared<IAudioDevice>(
90 system, aruid.pid, Common::MakeMagic('R', 'E', 'V', '1'), num_audio_devices++);
91 R_SUCCEED();
92}
93
94Result IAudioRendererManager::GetAudioDeviceServiceWithRevisionInfo(
95 Out<SharedPointer<IAudioDevice>> out_audio_device, u32 revision,
96 ClientAppletResourceUserId aruid) {
97 LOG_DEBUG(Service_Audio, "called, revision={} aruid={:#x}", AudioCore::GetRevisionNum(revision),
98 aruid.pid);
99 *out_audio_device =
100 std::make_shared<IAudioDevice>(system, aruid.pid, revision, num_audio_devices++);
101 R_SUCCEED();
102}
103
104} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio_renderer_manager.h b/src/core/hle/service/audio/audio_renderer_manager.h
new file mode 100755
index 000000000..69eee664c
--- /dev/null
+++ b/src/core/hle/service/audio/audio_renderer_manager.h
@@ -0,0 +1,37 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "audio_core/audio_render_manager.h"
7#include "core/hle/service/cmif_types.h"
8#include "core/hle/service/service.h"
9
10namespace Service::Audio {
11
12class IAudioDevice;
13class IAudioRenderer;
14
15class IAudioRendererManager final : public ServiceFramework<IAudioRendererManager> {
16public:
17 explicit IAudioRendererManager(Core::System& system_);
18 ~IAudioRendererManager() override;
19
20private:
21 Result OpenAudioRenderer(Out<SharedPointer<IAudioRenderer>> out_audio_renderer,
22 AudioCore::AudioRendererParameterInternal parameter,
23 InCopyHandle<Kernel::KTransferMemory> tmem_handle, u64 tmem_size,
24 InCopyHandle<Kernel::KProcess> process_handle,
25 ClientAppletResourceUserId aruid);
26 Result GetWorkBufferSize(Out<u64> out_size,
27 AudioCore::AudioRendererParameterInternal parameter);
28 Result GetAudioDeviceService(Out<SharedPointer<IAudioDevice>> out_audio_device,
29 ClientAppletResourceUserId aruid);
30 Result GetAudioDeviceServiceWithRevisionInfo(Out<SharedPointer<IAudioDevice>> out_audio_device,
31 u32 revision, ClientAppletResourceUserId aruid);
32
33 std::unique_ptr<AudioCore::Renderer::Manager> impl;
34 u32 num_audio_devices{0};
35};
36
37} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/final_output_recorder_manager.cpp b/src/core/hle/service/audio/final_output_recorder_manager.cpp
new file mode 100755
index 000000000..f70a0e62d
--- /dev/null
+++ b/src/core/hle/service/audio/final_output_recorder_manager.cpp
@@ -0,0 +1,43 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/audio/final_output_recorder_manager.h"
5
6namespace Service::Audio {
7
8class IFinalOutputRecorder final : public ServiceFramework<IFinalOutputRecorder> {
9public:
10 explicit IFinalOutputRecorder(Core::System& system_)
11 : ServiceFramework{system_, "IFinalOutputRecorder"} {
12 // clang-format off
13 static const FunctionInfo functions[] = {
14 {0, nullptr, "GetFinalOutputRecorderState"},
15 {1, nullptr, "Start"},
16 {2, nullptr, "Stop"},
17 {3, nullptr, "AppendFinalOutputRecorderBuffer"},
18 {4, nullptr, "RegisterBufferEvent"},
19 {5, nullptr, "GetReleasedFinalOutputRecorderBuffers"},
20 {6, nullptr, "ContainsFinalOutputRecorderBuffer"},
21 {7, nullptr, "GetFinalOutputRecorderBufferEndTime"},
22 {8, nullptr, "AppendFinalOutputRecorderBufferAuto"},
23 {9, nullptr, "GetReleasedFinalOutputRecorderBufferAuto"},
24 {10, nullptr, "FlushFinalOutputRecorderBuffers"},
25 {11, nullptr, "AttachWorkBuffer"},
26 };
27 // clang-format on
28
29 RegisterHandlers(functions);
30 }
31};
32
33IFinalOutputRecorderManager::IFinalOutputRecorderManager(Core::System& system_)
34 : ServiceFramework{system_, "audrec:u"} {
35 static const FunctionInfo functions[] = {
36 {0, nullptr, "OpenFinalOutputRecorder"},
37 };
38 RegisterHandlers(functions);
39}
40
41IFinalOutputRecorderManager::~IFinalOutputRecorderManager() = default;
42
43} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/final_output_recorder_manager.h b/src/core/hle/service/audio/final_output_recorder_manager.h
new file mode 100755
index 000000000..0663b894e
--- /dev/null
+++ b/src/core/hle/service/audio/final_output_recorder_manager.h
@@ -0,0 +1,20 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/service.h"
7
8namespace Core {
9class System;
10}
11
12namespace Service::Audio {
13
14class IFinalOutputRecorderManager final : public ServiceFramework<IFinalOutputRecorderManager> {
15public:
16 explicit IFinalOutputRecorderManager(Core::System& system_);
17 ~IFinalOutputRecorderManager() override;
18};
19
20} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/final_output_recorder_manager_for_applet.cpp b/src/core/hle/service/audio/final_output_recorder_manager_for_applet.cpp
new file mode 100755
index 000000000..7e2e42bbe
--- /dev/null
+++ b/src/core/hle/service/audio/final_output_recorder_manager_for_applet.cpp
@@ -0,0 +1,22 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/audio/final_output_recorder_manager_for_applet.h"
5
6namespace Service::Audio {
7
8IFinalOutputRecorderManagerForApplet::IFinalOutputRecorderManagerForApplet(Core::System& system_)
9 : ServiceFramework{system_, "audrec:a"} {
10 // clang-format off
11 static const FunctionInfo functions[] = {
12 {0, nullptr, "RequestSuspend"},
13 {1, nullptr, "RequestResume"},
14 };
15 // clang-format on
16
17 RegisterHandlers(functions);
18}
19
20IFinalOutputRecorderManagerForApplet::~IFinalOutputRecorderManagerForApplet() = default;
21
22} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/final_output_recorder_manager_for_applet.h b/src/core/hle/service/audio/final_output_recorder_manager_for_applet.h
new file mode 100755
index 000000000..27940f7e0
--- /dev/null
+++ b/src/core/hle/service/audio/final_output_recorder_manager_for_applet.h
@@ -0,0 +1,21 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/service.h"
7
8namespace Core {
9class System;
10}
11
12namespace Service::Audio {
13
14class IFinalOutputRecorderManagerForApplet final
15 : public ServiceFramework<IFinalOutputRecorderManagerForApplet> {
16public:
17 explicit IFinalOutputRecorderManagerForApplet(Core::System& system_);
18 ~IFinalOutputRecorderManagerForApplet() override;
19};
20
21} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/hardware_opus_decoder.cpp b/src/core/hle/service/audio/hardware_opus_decoder.cpp
new file mode 100755
index 000000000..03d3374c1
--- /dev/null
+++ b/src/core/hle/service/audio/hardware_opus_decoder.cpp
@@ -0,0 +1,145 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/audio/hardware_opus_decoder.h"
5#include "core/hle/service/cmif_serialization.h"
6
7namespace Service::Audio {
8
9using namespace AudioCore::OpusDecoder;
10
11IHardwareOpusDecoder::IHardwareOpusDecoder(Core::System& system_, HardwareOpus& hardware_opus)
12 : ServiceFramework{system_, "IHardwareOpusDecoder"},
13 impl{std::make_unique<AudioCore::OpusDecoder::OpusDecoder>(system_, hardware_opus)} {
14 // clang-format off
15 static const FunctionInfo functions[] = {
16 {0, D<&IHardwareOpusDecoder::DecodeInterleavedOld>, "DecodeInterleavedOld"},
17 {1, D<&IHardwareOpusDecoder::SetContext>, "SetContext"},
18 {2, D<&IHardwareOpusDecoder::DecodeInterleavedForMultiStreamOld>, "DecodeInterleavedForMultiStreamOld"},
19 {3, D<&IHardwareOpusDecoder::SetContextForMultiStream>, "SetContextForMultiStream"},
20 {4, D<&IHardwareOpusDecoder::DecodeInterleavedWithPerfOld>, "DecodeInterleavedWithPerfOld"},
21 {5, D<&IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfOld>, "DecodeInterleavedForMultiStreamWithPerfOld"},
22 {6, D<&IHardwareOpusDecoder::DecodeInterleavedWithPerfAndResetOld>, "DecodeInterleavedWithPerfAndResetOld"},
23 {7, D<&IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfAndResetOld>, "DecodeInterleavedForMultiStreamWithPerfAndResetOld"},
24 {8, D<&IHardwareOpusDecoder::DecodeInterleaved>, "DecodeInterleaved"},
25 {9, D<&IHardwareOpusDecoder::DecodeInterleavedForMultiStream>, "DecodeInterleavedForMultiStream"},
26 };
27 // clang-format on
28
29 RegisterHandlers(functions);
30}
31
32IHardwareOpusDecoder::~IHardwareOpusDecoder() = default;
33
34Result IHardwareOpusDecoder::Initialize(const OpusParametersEx& params,
35 Kernel::KTransferMemory* transfer_memory,
36 u64 transfer_memory_size) {
37 return impl->Initialize(params, transfer_memory, transfer_memory_size);
38}
39
40Result IHardwareOpusDecoder::Initialize(const OpusMultiStreamParametersEx& params,
41 Kernel::KTransferMemory* transfer_memory,
42 u64 transfer_memory_size) {
43 return impl->Initialize(params, transfer_memory, transfer_memory_size);
44}
45
46Result IHardwareOpusDecoder::DecodeInterleavedOld(OutBuffer<BufferAttr_HipcMapAlias> out_pcm_data,
47 Out<u32> out_data_size, Out<u32> out_sample_count,
48 InBuffer<BufferAttr_HipcMapAlias> opus_data) {
49 R_TRY(impl->DecodeInterleaved(out_data_size, nullptr, out_sample_count, opus_data, out_pcm_data,
50 false));
51 LOG_DEBUG(Service_Audio, "bytes read {:#x} samples generated {}", *out_data_size,
52 *out_sample_count);
53 R_SUCCEED();
54}
55
56Result IHardwareOpusDecoder::SetContext(InBuffer<BufferAttr_HipcMapAlias> decoder_context) {
57 LOG_DEBUG(Service_Audio, "called");
58 R_RETURN(impl->SetContext(decoder_context));
59}
60
61Result IHardwareOpusDecoder::DecodeInterleavedForMultiStreamOld(
62 OutBuffer<BufferAttr_HipcMapAlias> out_pcm_data, Out<u32> out_data_size,
63 Out<u32> out_sample_count, InBuffer<BufferAttr_HipcMapAlias> opus_data) {
64 R_TRY(impl->DecodeInterleavedForMultiStream(out_data_size, nullptr, out_sample_count, opus_data,
65 out_pcm_data, false));
66 LOG_DEBUG(Service_Audio, "bytes read {:#x} samples generated {}", *out_data_size,
67 *out_sample_count);
68 R_SUCCEED();
69}
70
71Result IHardwareOpusDecoder::SetContextForMultiStream(
72 InBuffer<BufferAttr_HipcMapAlias> decoder_context) {
73 LOG_DEBUG(Service_Audio, "called");
74 R_RETURN(impl->SetContext(decoder_context));
75}
76
77Result IHardwareOpusDecoder::DecodeInterleavedWithPerfOld(
78 OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
79 Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
80 InBuffer<BufferAttr_HipcMapAlias> opus_data) {
81 R_TRY(impl->DecodeInterleaved(out_data_size, out_time_taken, out_sample_count, opus_data,
82 out_pcm_data, false));
83 LOG_DEBUG(Service_Audio, "bytes read {:#x} samples generated {} time taken {}", *out_data_size,
84 *out_sample_count, *out_time_taken);
85 R_SUCCEED();
86}
87
88Result IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfOld(
89 OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
90 Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
91 InBuffer<BufferAttr_HipcMapAlias> opus_data) {
92 R_TRY(impl->DecodeInterleavedForMultiStream(out_data_size, out_time_taken, out_sample_count,
93 opus_data, out_pcm_data, false));
94 LOG_DEBUG(Service_Audio, "bytes read {:#x} samples generated {} time taken {}", *out_data_size,
95 *out_sample_count, *out_time_taken);
96 R_SUCCEED();
97}
98
99Result IHardwareOpusDecoder::DecodeInterleavedWithPerfAndResetOld(
100 OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
101 Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
102 InBuffer<BufferAttr_HipcMapAlias> opus_data, bool reset) {
103 R_TRY(impl->DecodeInterleaved(out_data_size, out_time_taken, out_sample_count, opus_data,
104 out_pcm_data, reset));
105 LOG_DEBUG(Service_Audio, "reset {} bytes read {:#x} samples generated {} time taken {}", reset,
106 *out_data_size, *out_sample_count, *out_time_taken);
107 R_SUCCEED();
108}
109
110Result IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfAndResetOld(
111 OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
112 Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
113 InBuffer<BufferAttr_HipcMapAlias> opus_data, bool reset) {
114 R_TRY(impl->DecodeInterleavedForMultiStream(out_data_size, out_time_taken, out_sample_count,
115 opus_data, out_pcm_data, reset));
116 LOG_DEBUG(Service_Audio, "reset {} bytes read {:#x} samples generated {} time taken {}", reset,
117 *out_data_size, *out_sample_count, *out_time_taken);
118 R_SUCCEED();
119}
120
121Result IHardwareOpusDecoder::DecodeInterleaved(
122 OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
123 Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
124 InBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> opus_data,
125 bool reset) {
126 R_TRY(impl->DecodeInterleaved(out_data_size, out_time_taken, out_sample_count, opus_data,
127 out_pcm_data, reset));
128 LOG_DEBUG(Service_Audio, "reset {} bytes read {:#x} samples generated {} time taken {}", reset,
129 *out_data_size, *out_sample_count, *out_time_taken);
130 R_SUCCEED();
131}
132
133Result IHardwareOpusDecoder::DecodeInterleavedForMultiStream(
134 OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
135 Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
136 InBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> opus_data,
137 bool reset) {
138 R_TRY(impl->DecodeInterleavedForMultiStream(out_data_size, out_time_taken, out_sample_count,
139 opus_data, out_pcm_data, reset));
140 LOG_DEBUG(Service_Audio, "reset {} bytes read {:#x} samples generated {} time taken {}", reset,
141 *out_data_size, *out_sample_count, *out_time_taken);
142 R_SUCCEED();
143}
144
145} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/hardware_opus_decoder.h b/src/core/hle/service/audio/hardware_opus_decoder.h
new file mode 100755
index 000000000..511bf46bd
--- /dev/null
+++ b/src/core/hle/service/audio/hardware_opus_decoder.h
@@ -0,0 +1,63 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "audio_core/opus/decoder.h"
7#include "core/hle/service/cmif_types.h"
8#include "core/hle/service/service.h"
9
10namespace Service::Audio {
11
12class IHardwareOpusDecoder final : public ServiceFramework<IHardwareOpusDecoder> {
13public:
14 explicit IHardwareOpusDecoder(Core::System& system_,
15 AudioCore::OpusDecoder::HardwareOpus& hardware_opus);
16 ~IHardwareOpusDecoder() override;
17
18 Result Initialize(const AudioCore::OpusDecoder::OpusParametersEx& params,
19 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size);
20 Result Initialize(const AudioCore::OpusDecoder::OpusMultiStreamParametersEx& params,
21 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size);
22
23private:
24 Result DecodeInterleavedOld(OutBuffer<BufferAttr_HipcMapAlias> out_pcm_data,
25 Out<u32> out_data_size, Out<u32> out_sample_count,
26 InBuffer<BufferAttr_HipcMapAlias> opus_data);
27 Result SetContext(InBuffer<BufferAttr_HipcMapAlias> decoder_context);
28 Result DecodeInterleavedForMultiStreamOld(OutBuffer<BufferAttr_HipcMapAlias> out_pcm_data,
29 Out<u32> out_data_size, Out<u32> out_sample_count,
30 InBuffer<BufferAttr_HipcMapAlias> opus_data);
31 Result SetContextForMultiStream(InBuffer<BufferAttr_HipcMapAlias> decoder_context);
32 Result DecodeInterleavedWithPerfOld(
33 OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
34 Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
35 InBuffer<BufferAttr_HipcMapAlias> opus_data);
36 Result DecodeInterleavedForMultiStreamWithPerfOld(
37 OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
38 Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
39 InBuffer<BufferAttr_HipcMapAlias> opus_data);
40 Result DecodeInterleavedWithPerfAndResetOld(
41 OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
42 Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
43 InBuffer<BufferAttr_HipcMapAlias> opus_data, bool reset);
44 Result DecodeInterleavedForMultiStreamWithPerfAndResetOld(
45 OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
46 Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
47 InBuffer<BufferAttr_HipcMapAlias> opus_data, bool reset);
48 Result DecodeInterleaved(
49 OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
50 Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
51 InBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> opus_data,
52 bool reset);
53 Result DecodeInterleavedForMultiStream(
54 OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_pcm_data,
55 Out<u32> out_data_size, Out<u32> out_sample_count, Out<u64> out_time_taken,
56 InBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> opus_data,
57 bool reset);
58
59 std::unique_ptr<AudioCore::OpusDecoder::OpusDecoder> impl;
60 Common::ScratchBuffer<u8> output_data;
61};
62
63} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/hardware_opus_decoder_manager.cpp b/src/core/hle/service/audio/hardware_opus_decoder_manager.cpp
new file mode 100755
index 000000000..9de72e30f
--- /dev/null
+++ b/src/core/hle/service/audio/hardware_opus_decoder_manager.cpp
@@ -0,0 +1,156 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/audio/hardware_opus_decoder.h"
5#include "core/hle/service/audio/hardware_opus_decoder_manager.h"
6#include "core/hle/service/cmif_serialization.h"
7
8namespace Service::Audio {
9
10using namespace AudioCore::OpusDecoder;
11
12IHardwareOpusDecoderManager::IHardwareOpusDecoderManager(Core::System& system_)
13 : ServiceFramework{system_, "hwopus"}, system{system_}, impl{system} {
14 // clang-format off
15 static const FunctionInfo functions[] = {
16 {0, D<&IHardwareOpusDecoderManager::OpenHardwareOpusDecoder>, "OpenHardwareOpusDecoder"},
17 {1, D<&IHardwareOpusDecoderManager::GetWorkBufferSize>, "GetWorkBufferSize"},
18 {2, D<&IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStream>, "OpenOpusDecoderForMultiStream"},
19 {3, D<&IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStream>, "GetWorkBufferSizeForMultiStream"},
20 {4, D<&IHardwareOpusDecoderManager::OpenHardwareOpusDecoderEx>, "OpenHardwareOpusDecoderEx"},
21 {5, D<&IHardwareOpusDecoderManager::GetWorkBufferSizeEx>, "GetWorkBufferSizeEx"},
22 {6, D<&IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStreamEx>, "OpenHardwareOpusDecoderForMultiStreamEx"},
23 {7, D<&IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamEx>, "GetWorkBufferSizeForMultiStreamEx"},
24 {8, D<&IHardwareOpusDecoderManager::GetWorkBufferSizeExEx>, "GetWorkBufferSizeExEx"},
25 {9, D<&IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamExEx>, "GetWorkBufferSizeForMultiStreamExEx"},
26 };
27 // clang-format on
28 RegisterHandlers(functions);
29}
30
31IHardwareOpusDecoderManager::~IHardwareOpusDecoderManager() = default;
32
33Result IHardwareOpusDecoderManager::OpenHardwareOpusDecoder(
34 Out<SharedPointer<IHardwareOpusDecoder>> out_decoder, OpusParameters params, u32 tmem_size,
35 InCopyHandle<Kernel::KTransferMemory> tmem_handle) {
36 LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} transfer_memory_size {:#x}",
37 params.sample_rate, params.channel_count, tmem_size);
38
39 auto decoder{std::make_shared<IHardwareOpusDecoder>(system, impl.GetHardwareOpus())};
40 OpusParametersEx ex{
41 .sample_rate = params.sample_rate,
42 .channel_count = params.channel_count,
43 .use_large_frame_size = false,
44 };
45 R_TRY(decoder->Initialize(ex, tmem_handle.Get(), tmem_size));
46
47 *out_decoder = decoder;
48 R_SUCCEED();
49}
50
51Result IHardwareOpusDecoderManager::GetWorkBufferSize(Out<u32> out_size, OpusParameters params) {
52 R_TRY(impl.GetWorkBufferSize(params, *out_size));
53 LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} -- returned size {:#x}",
54 params.sample_rate, params.channel_count, *out_size);
55 R_SUCCEED();
56}
57
58Result IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStream(
59 Out<SharedPointer<IHardwareOpusDecoder>> out_decoder,
60 InLargeData<OpusMultiStreamParameters, BufferAttr_HipcPointer> params, u32 tmem_size,
61 InCopyHandle<Kernel::KTransferMemory> tmem_handle) {
62 LOG_DEBUG(Service_Audio,
63 "sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} "
64 "transfer_memory_size {:#x}",
65 params->sample_rate, params->channel_count, params->total_stream_count,
66 params->stereo_stream_count, tmem_size);
67
68 auto decoder{std::make_shared<IHardwareOpusDecoder>(system, impl.GetHardwareOpus())};
69
70 OpusMultiStreamParametersEx ex{
71 .sample_rate = params->sample_rate,
72 .channel_count = params->channel_count,
73 .total_stream_count = params->total_stream_count,
74 .stereo_stream_count = params->stereo_stream_count,
75 .use_large_frame_size = false,
76 .mappings{},
77 };
78 std::memcpy(ex.mappings.data(), params->mappings.data(), sizeof(params->mappings));
79 R_TRY(decoder->Initialize(ex, tmem_handle.Get(), tmem_size));
80
81 *out_decoder = decoder;
82 R_SUCCEED();
83}
84
85Result IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStream(
86 Out<u32> out_size, InLargeData<OpusMultiStreamParameters, BufferAttr_HipcPointer> params) {
87 R_TRY(impl.GetWorkBufferSizeForMultiStream(*params, *out_size));
88 LOG_DEBUG(Service_Audio, "size {:#x}", *out_size);
89 R_SUCCEED();
90}
91
92Result IHardwareOpusDecoderManager::OpenHardwareOpusDecoderEx(
93 Out<SharedPointer<IHardwareOpusDecoder>> out_decoder, OpusParametersEx params, u32 tmem_size,
94 InCopyHandle<Kernel::KTransferMemory> tmem_handle) {
95 LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} transfer_memory_size {:#x}",
96 params.sample_rate, params.channel_count, tmem_size);
97
98 auto decoder{std::make_shared<IHardwareOpusDecoder>(system, impl.GetHardwareOpus())};
99 R_TRY(decoder->Initialize(params, tmem_handle.Get(), tmem_size));
100
101 *out_decoder = decoder;
102 R_SUCCEED();
103}
104
105Result IHardwareOpusDecoderManager::GetWorkBufferSizeEx(Out<u32> out_size,
106 OpusParametersEx params) {
107 R_TRY(impl.GetWorkBufferSizeEx(params, *out_size));
108 LOG_DEBUG(Service_Audio, "size {:#x}", *out_size);
109 R_SUCCEED();
110}
111
112Result IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStreamEx(
113 Out<SharedPointer<IHardwareOpusDecoder>> out_decoder,
114 InLargeData<OpusMultiStreamParametersEx, BufferAttr_HipcPointer> params, u32 tmem_size,
115 InCopyHandle<Kernel::KTransferMemory> tmem_handle) {
116 LOG_DEBUG(Service_Audio,
117 "sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} "
118 "use_large_frame_size {}"
119 "transfer_memory_size {:#x}",
120 params->sample_rate, params->channel_count, params->total_stream_count,
121 params->stereo_stream_count, params->use_large_frame_size, tmem_size);
122
123 auto decoder{std::make_shared<IHardwareOpusDecoder>(system, impl.GetHardwareOpus())};
124
125 R_TRY(decoder->Initialize(*params, tmem_handle.Get(), tmem_size));
126
127 *out_decoder = decoder;
128 R_SUCCEED();
129}
130
131Result IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamEx(
132 Out<u32> out_size, InLargeData<OpusMultiStreamParametersEx, BufferAttr_HipcPointer> params) {
133 R_TRY(impl.GetWorkBufferSizeForMultiStreamEx(*params, *out_size));
134 LOG_DEBUG(Service_Audio,
135 "sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} "
136 "use_large_frame_size {} -- returned size {:#x}",
137 params->sample_rate, params->channel_count, params->total_stream_count,
138 params->stereo_stream_count, params->use_large_frame_size, *out_size);
139 R_SUCCEED();
140}
141
142Result IHardwareOpusDecoderManager::GetWorkBufferSizeExEx(Out<u32> out_size,
143 OpusParametersEx params) {
144 R_TRY(impl.GetWorkBufferSizeExEx(params, *out_size));
145 LOG_DEBUG(Service_Audio, "size {:#x}", *out_size);
146 R_SUCCEED();
147}
148
149Result IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamExEx(
150 Out<u32> out_size, InLargeData<OpusMultiStreamParametersEx, BufferAttr_HipcPointer> params) {
151 R_TRY(impl.GetWorkBufferSizeForMultiStreamExEx(*params, *out_size));
152 LOG_DEBUG(Service_Audio, "size {:#x}", *out_size);
153 R_SUCCEED();
154}
155
156} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/hardware_opus_decoder_manager.h b/src/core/hle/service/audio/hardware_opus_decoder_manager.h
new file mode 100755
index 000000000..4f869c517
--- /dev/null
+++ b/src/core/hle/service/audio/hardware_opus_decoder_manager.h
@@ -0,0 +1,53 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "audio_core/opus/decoder_manager.h"
7#include "core/hle/service/cmif_types.h"
8#include "core/hle/service/service.h"
9
10namespace Service::Audio {
11
12class IHardwareOpusDecoder;
13
14using AudioCore::OpusDecoder::OpusMultiStreamParameters;
15using AudioCore::OpusDecoder::OpusMultiStreamParametersEx;
16using AudioCore::OpusDecoder::OpusParameters;
17using AudioCore::OpusDecoder::OpusParametersEx;
18
19class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> {
20public:
21 explicit IHardwareOpusDecoderManager(Core::System& system_);
22 ~IHardwareOpusDecoderManager() override;
23
24private:
25 Result OpenHardwareOpusDecoder(Out<SharedPointer<IHardwareOpusDecoder>> out_decoder,
26 OpusParameters params, u32 tmem_size,
27 InCopyHandle<Kernel::KTransferMemory> tmem_handle);
28 Result GetWorkBufferSize(Out<u32> out_size, OpusParameters params);
29 Result OpenHardwareOpusDecoderForMultiStream(
30 Out<SharedPointer<IHardwareOpusDecoder>> out_decoder,
31 InLargeData<OpusMultiStreamParameters, BufferAttr_HipcPointer> params, u32 tmem_size,
32 InCopyHandle<Kernel::KTransferMemory> tmem_handle);
33 Result GetWorkBufferSizeForMultiStream(
34 Out<u32> out_size, InLargeData<OpusMultiStreamParameters, BufferAttr_HipcPointer> params);
35 Result OpenHardwareOpusDecoderEx(Out<SharedPointer<IHardwareOpusDecoder>> out_decoder,
36 OpusParametersEx params, u32 tmem_size,
37 InCopyHandle<Kernel::KTransferMemory> tmem_handle);
38 Result GetWorkBufferSizeEx(Out<u32> out_size, OpusParametersEx params);
39 Result OpenHardwareOpusDecoderForMultiStreamEx(
40 Out<SharedPointer<IHardwareOpusDecoder>> out_decoder,
41 InLargeData<OpusMultiStreamParametersEx, BufferAttr_HipcPointer> params, u32 tmem_size,
42 InCopyHandle<Kernel::KTransferMemory> tmem_handle);
43 Result GetWorkBufferSizeForMultiStreamEx(
44 Out<u32> out_size, InLargeData<OpusMultiStreamParametersEx, BufferAttr_HipcPointer> params);
45 Result GetWorkBufferSizeExEx(Out<u32> out_size, OpusParametersEx params);
46 Result GetWorkBufferSizeForMultiStreamExEx(
47 Out<u32> out_size, InLargeData<OpusMultiStreamParametersEx, BufferAttr_HipcPointer> params);
48
49 Core::System& system;
50 AudioCore::OpusDecoder::OpusDecoderManager impl;
51};
52
53} // namespace Service::Audio
diff --git a/src/core/hle/service/cmif_serialization.h b/src/core/hle/service/cmif_serialization.h
index f24682c34..5a5f610f3 100755
--- a/src/core/hle/service/cmif_serialization.h
+++ b/src/core/hle/service/cmif_serialization.h
@@ -415,7 +415,7 @@ void WriteOutArgument(bool is_domain, CallArguments& args, u8* raw_data, HLERequ
415 auto& buffer = temp[OutBufferIndex]; 415 auto& buffer = temp[OutBufferIndex];
416 const size_t size = buffer.size(); 416 const size_t size = buffer.size();
417 417
418 if (ctx.CanWriteBuffer(OutBufferIndex)) { 418 if (size > 0 && ctx.CanWriteBuffer(OutBufferIndex)) {
419 if constexpr (ArgType::Attr & BufferAttr_HipcAutoSelect) { 419 if constexpr (ArgType::Attr & BufferAttr_HipcAutoSelect) {
420 ctx.WriteBuffer(buffer.data(), size, OutBufferIndex); 420 ctx.WriteBuffer(buffer.data(), size, OutBufferIndex);
421 } else if constexpr (ArgType::Attr & BufferAttr_HipcMapAlias) { 421 } else if constexpr (ArgType::Attr & BufferAttr_HipcMapAlias) {
diff --git a/src/core/hle/service/filesystem/fsp/fs_i_filesystem.h b/src/core/hle/service/filesystem/fsp/fs_i_filesystem.h
index 113369203..dd069f36f 100755
--- a/src/core/hle/service/filesystem/fsp/fs_i_filesystem.h
+++ b/src/core/hle/service/filesystem/fsp/fs_i_filesystem.h
@@ -9,7 +9,7 @@
9#include "core/file_sys/vfs/vfs.h" 9#include "core/file_sys/vfs/vfs.h"
10#include "core/hle/service/cmif_types.h" 10#include "core/hle/service/cmif_types.h"
11#include "core/hle/service/filesystem/filesystem.h" 11#include "core/hle/service/filesystem/filesystem.h"
12#include "core/hle/service/filesystem/fsp/fsp_util.h" 12#include "core/hle/service/filesystem/fsp/fsp_types.h"
13#include "core/hle/service/service.h" 13#include "core/hle/service/service.h"
14 14
15namespace FileSys::Sf { 15namespace FileSys::Sf {
diff --git a/src/core/hle/service/filesystem/fsp/fs_i_multi_commit_manager.cpp b/src/core/hle/service/filesystem/fsp/fs_i_multi_commit_manager.cpp
new file mode 100755
index 000000000..626328234
--- /dev/null
+++ b/src/core/hle/service/filesystem/fsp/fs_i_multi_commit_manager.cpp
@@ -0,0 +1,33 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/filesystem/fsp/fs_i_filesystem.h"
6#include "core/hle/service/filesystem/fsp/fs_i_multi_commit_manager.h"
7
8namespace Service::FileSystem {
9
10IMultiCommitManager::IMultiCommitManager(Core::System& system_)
11 : ServiceFramework{system_, "IMultiCommitManager"} {
12 static const FunctionInfo functions[] = {
13 {1, D<&IMultiCommitManager::Add>, "Add"},
14 {2, D<&IMultiCommitManager::Commit>, "Commit"},
15 };
16 RegisterHandlers(functions);
17}
18
19IMultiCommitManager::~IMultiCommitManager() = default;
20
21Result IMultiCommitManager::Add(std::shared_ptr<IFileSystem> filesystem) {
22 LOG_WARNING(Service_FS, "(STUBBED) called");
23
24 R_SUCCEED();
25}
26
27Result IMultiCommitManager::Commit() {
28 LOG_WARNING(Service_FS, "(STUBBED) called");
29
30 R_SUCCEED();
31}
32
33} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/fsp/fs_i_multi_commit_manager.h b/src/core/hle/service/filesystem/fsp/fs_i_multi_commit_manager.h
new file mode 100755
index 000000000..8ebf7c7d9
--- /dev/null
+++ b/src/core/hle/service/filesystem/fsp/fs_i_multi_commit_manager.h
@@ -0,0 +1,23 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/file_sys/vfs/vfs.h"
7#include "core/hle/service/service.h"
8
9namespace Service::FileSystem {
10
11class IMultiCommitManager final : public ServiceFramework<IMultiCommitManager> {
12public:
13 explicit IMultiCommitManager(Core::System& system_);
14 ~IMultiCommitManager() override;
15
16private:
17 Result Add(std::shared_ptr<IFileSystem> filesystem);
18 Result Commit();
19
20 FileSys::VirtualFile backend;
21};
22
23} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp b/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp
new file mode 100755
index 000000000..ff823586b
--- /dev/null
+++ b/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp
@@ -0,0 +1,161 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/hex_util.h"
5#include "core/file_sys/savedata_factory.h"
6#include "core/hle/service/cmif_serialization.h"
7#include "core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.h"
8#include "core/hle/service/filesystem/save_data_controller.h"
9
10namespace Service::FileSystem {
11
12ISaveDataInfoReader::ISaveDataInfoReader(Core::System& system_,
13 std::shared_ptr<SaveDataController> save_data_controller_,
14 FileSys::SaveDataSpaceId space)
15 : ServiceFramework{system_, "ISaveDataInfoReader"}, save_data_controller{
16 save_data_controller_} {
17 static const FunctionInfo functions[] = {
18 {0, D<&ISaveDataInfoReader::ReadSaveDataInfo>, "ReadSaveDataInfo"},
19 };
20 RegisterHandlers(functions);
21
22 FindAllSaves(space);
23}
24
25ISaveDataInfoReader::~ISaveDataInfoReader() = default;
26
27static u64 stoull_be(std::string_view str) {
28 if (str.size() != 16) {
29 return 0;
30 }
31
32 const auto bytes = Common::HexStringToArray<0x8>(str);
33 u64 out{};
34 std::memcpy(&out, bytes.data(), sizeof(u64));
35
36 return Common::swap64(out);
37}
38
39Result ISaveDataInfoReader::ReadSaveDataInfo(
40 Out<u64> out_count, OutArray<SaveDataInfo, BufferAttr_HipcMapAlias> out_entries) {
41 LOG_DEBUG(Service_FS, "called");
42
43 // Calculate how many entries we can fit in the output buffer
44 const u64 count_entries = out_entries.size();
45
46 // Cap at total number of entries.
47 const u64 actual_entries = std::min(count_entries, info.size() - next_entry_index);
48
49 // Determine data start and end
50 const auto* begin = reinterpret_cast<u8*>(info.data() + next_entry_index);
51 const auto* end = reinterpret_cast<u8*>(info.data() + next_entry_index + actual_entries);
52 const auto range_size = static_cast<std::size_t>(std::distance(begin, end));
53
54 next_entry_index += actual_entries;
55
56 // Write the data to memory
57 std::memcpy(out_entries.data(), begin, range_size);
58 *out_count = actual_entries;
59
60 R_SUCCEED();
61}
62
63void ISaveDataInfoReader::FindAllSaves(FileSys::SaveDataSpaceId space) {
64 FileSys::VirtualDir save_root{};
65 const auto result = save_data_controller->OpenSaveDataSpace(&save_root, space);
66
67 if (result != ResultSuccess || save_root == nullptr) {
68 LOG_ERROR(Service_FS, "The save root for the space_id={:02X} was invalid!", space);
69 return;
70 }
71
72 for (const auto& type : save_root->GetSubdirectories()) {
73 if (type->GetName() == "save") {
74 FindNormalSaves(space, type);
75 } else if (space == FileSys::SaveDataSpaceId::Temporary) {
76 FindTemporaryStorageSaves(space, type);
77 }
78 }
79}
80
81void ISaveDataInfoReader::FindNormalSaves(FileSys::SaveDataSpaceId space,
82 const FileSys::VirtualDir& type) {
83 for (const auto& save_id : type->GetSubdirectories()) {
84 for (const auto& user_id : save_id->GetSubdirectories()) {
85 // Skip non user id subdirectories
86 if (user_id->GetName().size() != 0x20) {
87 continue;
88 }
89
90 const auto save_id_numeric = stoull_be(save_id->GetName());
91 auto user_id_numeric = Common::HexStringToArray<0x10>(user_id->GetName());
92 std::reverse(user_id_numeric.begin(), user_id_numeric.end());
93
94 if (save_id_numeric != 0) {
95 // System Save Data
96 info.emplace_back(SaveDataInfo{
97 0,
98 space,
99 FileSys::SaveDataType::System,
100 {},
101 user_id_numeric,
102 save_id_numeric,
103 0,
104 user_id->GetSize(),
105 {},
106 {},
107 });
108
109 continue;
110 }
111
112 for (const auto& title_id : user_id->GetSubdirectories()) {
113 const auto device = std::all_of(user_id_numeric.begin(), user_id_numeric.end(),
114 [](u8 val) { return val == 0; });
115 info.emplace_back(SaveDataInfo{
116 0,
117 space,
118 device ? FileSys::SaveDataType::Device : FileSys::SaveDataType::Account,
119 {},
120 user_id_numeric,
121 save_id_numeric,
122 stoull_be(title_id->GetName()),
123 title_id->GetSize(),
124 {},
125 {},
126 });
127 }
128 }
129 }
130}
131
132void ISaveDataInfoReader::FindTemporaryStorageSaves(FileSys::SaveDataSpaceId space,
133 const FileSys::VirtualDir& type) {
134 for (const auto& user_id : type->GetSubdirectories()) {
135 // Skip non user id subdirectories
136 if (user_id->GetName().size() != 0x20) {
137 continue;
138 }
139 for (const auto& title_id : user_id->GetSubdirectories()) {
140 if (!title_id->GetFiles().empty() || !title_id->GetSubdirectories().empty()) {
141 auto user_id_numeric = Common::HexStringToArray<0x10>(user_id->GetName());
142 std::reverse(user_id_numeric.begin(), user_id_numeric.end());
143
144 info.emplace_back(SaveDataInfo{
145 0,
146 space,
147 FileSys::SaveDataType::Temporary,
148 {},
149 user_id_numeric,
150 stoull_be(type->GetName()),
151 stoull_be(title_id->GetName()),
152 title_id->GetSize(),
153 {},
154 {},
155 });
156 }
157 }
158 }
159}
160
161} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.h b/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.h
new file mode 100755
index 000000000..e45ad852b
--- /dev/null
+++ b/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.h
@@ -0,0 +1,50 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <vector>
7#include "common/common_types.h"
8#include "core/hle/service/cmif_types.h"
9#include "core/hle/service/service.h"
10
11namespace Service::FileSystem {
12
13class SaveDataController;
14
15class ISaveDataInfoReader final : public ServiceFramework<ISaveDataInfoReader> {
16public:
17 explicit ISaveDataInfoReader(Core::System& system_,
18 std::shared_ptr<SaveDataController> save_data_controller_,
19 FileSys::SaveDataSpaceId space);
20 ~ISaveDataInfoReader() override;
21
22 struct SaveDataInfo {
23 u64_le save_id_unknown;
24 FileSys::SaveDataSpaceId space;
25 FileSys::SaveDataType type;
26 INSERT_PADDING_BYTES(0x6);
27 std::array<u8, 0x10> user_id;
28 u64_le save_id;
29 u64_le title_id;
30 u64_le save_image_size;
31 u16_le index;
32 FileSys::SaveDataRank rank;
33 INSERT_PADDING_BYTES(0x25);
34 };
35 static_assert(sizeof(SaveDataInfo) == 0x60, "SaveDataInfo has incorrect size.");
36
37 Result ReadSaveDataInfo(Out<u64> out_count,
38 OutArray<SaveDataInfo, BufferAttr_HipcMapAlias> out_entries);
39
40private:
41 void FindAllSaves(FileSys::SaveDataSpaceId space);
42 void FindNormalSaves(FileSys::SaveDataSpaceId space, const FileSys::VirtualDir& type);
43 void FindTemporaryStorageSaves(FileSys::SaveDataSpaceId space, const FileSys::VirtualDir& type);
44
45 std::shared_ptr<SaveDataController> save_data_controller;
46 std::vector<SaveDataInfo> info;
47 u64 next_entry_index = 0;
48};
49
50} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/fsp/fs_i_storage.cpp b/src/core/hle/service/filesystem/fsp/fs_i_storage.cpp
index 98223c1f9..213f19808 100755
--- a/src/core/hle/service/filesystem/fsp/fs_i_storage.cpp
+++ b/src/core/hle/service/filesystem/fsp/fs_i_storage.cpp
@@ -2,61 +2,44 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/file_sys/errors.h" 4#include "core/file_sys/errors.h"
5#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/filesystem/fsp/fs_i_storage.h" 6#include "core/hle/service/filesystem/fsp/fs_i_storage.h"
6#include "core/hle/service/ipc_helpers.h"
7 7
8namespace Service::FileSystem { 8namespace Service::FileSystem {
9 9
10IStorage::IStorage(Core::System& system_, FileSys::VirtualFile backend_) 10IStorage::IStorage(Core::System& system_, FileSys::VirtualFile backend_)
11 : ServiceFramework{system_, "IStorage"}, backend(std::move(backend_)) { 11 : ServiceFramework{system_, "IStorage"}, backend(std::move(backend_)) {
12 static const FunctionInfo functions[] = { 12 static const FunctionInfo functions[] = {
13 {0, &IStorage::Read, "Read"}, 13 {0, D<&IStorage::Read>, "Read"},
14 {1, nullptr, "Write"}, 14 {1, nullptr, "Write"},
15 {2, nullptr, "Flush"}, 15 {2, nullptr, "Flush"},
16 {3, nullptr, "SetSize"}, 16 {3, nullptr, "SetSize"},
17 {4, &IStorage::GetSize, "GetSize"}, 17 {4, D<&IStorage::GetSize>, "GetSize"},
18 {5, nullptr, "OperateRange"}, 18 {5, nullptr, "OperateRange"},
19 }; 19 };
20 RegisterHandlers(functions); 20 RegisterHandlers(functions);
21} 21}
22 22
23void IStorage::Read(HLERequestContext& ctx) { 23Result IStorage::Read(
24 IPC::RequestParser rp{ctx}; 24 OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_bytes,
25 const s64 offset = rp.Pop<s64>(); 25 s64 offset, s64 length) {
26 const s64 length = rp.Pop<s64>();
27
28 LOG_DEBUG(Service_FS, "called, offset=0x{:X}, length={}", offset, length); 26 LOG_DEBUG(Service_FS, "called, offset=0x{:X}, length={}", offset, length);
29 27
30 // Error checking 28 R_UNLESS(length >= 0, FileSys::ResultInvalidSize);
31 if (length < 0) { 29 R_UNLESS(offset >= 0, FileSys::ResultInvalidOffset);
32 LOG_ERROR(Service_FS, "Length is less than 0, length={}", length);
33 IPC::ResponseBuilder rb{ctx, 2};
34 rb.Push(FileSys::ResultInvalidSize);
35 return;
36 }
37 if (offset < 0) {
38 LOG_ERROR(Service_FS, "Offset is less than 0, offset={}", offset);
39 IPC::ResponseBuilder rb{ctx, 2};
40 rb.Push(FileSys::ResultInvalidOffset);
41 return;
42 }
43 30
44 // Read the data from the Storage backend 31 // Read the data from the Storage backend
45 std::vector<u8> output = backend->ReadBytes(length, offset); 32 backend->Read(out_bytes.data(), length, offset);
46 // Write the data to memory
47 ctx.WriteBuffer(output);
48 33
49 IPC::ResponseBuilder rb{ctx, 2}; 34 R_SUCCEED();
50 rb.Push(ResultSuccess);
51} 35}
52 36
53void IStorage::GetSize(HLERequestContext& ctx) { 37Result IStorage::GetSize(Out<u64> out_size) {
54 const u64 size = backend->GetSize(); 38 *out_size = backend->GetSize();
55 LOG_DEBUG(Service_FS, "called, size={}", size); 39
40 LOG_DEBUG(Service_FS, "called, size={}", *out_size);
56 41
57 IPC::ResponseBuilder rb{ctx, 4}; 42 R_SUCCEED();
58 rb.Push(ResultSuccess);
59 rb.Push<u64>(size);
60} 43}
61 44
62} // namespace Service::FileSystem 45} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/fsp/fs_i_storage.h b/src/core/hle/service/filesystem/fsp/fs_i_storage.h
index cb5bebcc9..74d879386 100755
--- a/src/core/hle/service/filesystem/fsp/fs_i_storage.h
+++ b/src/core/hle/service/filesystem/fsp/fs_i_storage.h
@@ -4,6 +4,7 @@
4#pragma once 4#pragma once
5 5
6#include "core/file_sys/vfs/vfs.h" 6#include "core/file_sys/vfs/vfs.h"
7#include "core/hle/service/cmif_types.h"
7#include "core/hle/service/filesystem/filesystem.h" 8#include "core/hle/service/filesystem/filesystem.h"
8#include "core/hle/service/service.h" 9#include "core/hle/service/service.h"
9 10
@@ -16,8 +17,10 @@ public:
16private: 17private:
17 FileSys::VirtualFile backend; 18 FileSys::VirtualFile backend;
18 19
19 void Read(HLERequestContext& ctx); 20 Result Read(
20 void GetSize(HLERequestContext& ctx); 21 OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_bytes,
22 s64 offset, s64 length);
23 Result GetSize(Out<u64> out_size);
21}; 24};
22 25
23} // namespace Service::FileSystem 26} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp
index 2d49f30c8..fc67a4713 100755
--- a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp
@@ -27,8 +27,11 @@
27#include "core/file_sys/system_archive/system_archive.h" 27#include "core/file_sys/system_archive/system_archive.h"
28#include "core/file_sys/vfs/vfs.h" 28#include "core/file_sys/vfs/vfs.h"
29#include "core/hle/result.h" 29#include "core/hle/result.h"
30#include "core/hle/service/cmif_serialization.h"
30#include "core/hle/service/filesystem/filesystem.h" 31#include "core/hle/service/filesystem/filesystem.h"
31#include "core/hle/service/filesystem/fsp/fs_i_filesystem.h" 32#include "core/hle/service/filesystem/fsp/fs_i_filesystem.h"
33#include "core/hle/service/filesystem/fsp/fs_i_multi_commit_manager.h"
34#include "core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.h"
32#include "core/hle/service/filesystem/fsp/fs_i_storage.h" 35#include "core/hle/service/filesystem/fsp/fs_i_storage.h"
33#include "core/hle/service/filesystem/fsp/fsp_srv.h" 36#include "core/hle/service/filesystem/fsp/fsp_srv.h"
34#include "core/hle/service/filesystem/romfs_controller.h" 37#include "core/hle/service/filesystem/romfs_controller.h"
@@ -39,182 +42,6 @@
39#include "core/reporter.h" 42#include "core/reporter.h"
40 43
41namespace Service::FileSystem { 44namespace Service::FileSystem {
42enum class FileSystemProxyType : u8 {
43 Code = 0,
44 Rom = 1,
45 Logo = 2,
46 Control = 3,
47 Manual = 4,
48 Meta = 5,
49 Data = 6,
50 Package = 7,
51 RegisteredUpdate = 8,
52};
53
54class ISaveDataInfoReader final : public ServiceFramework<ISaveDataInfoReader> {
55public:
56 explicit ISaveDataInfoReader(Core::System& system_,
57 std::shared_ptr<SaveDataController> save_data_controller_,
58 FileSys::SaveDataSpaceId space)
59 : ServiceFramework{system_, "ISaveDataInfoReader"}, save_data_controller{
60 save_data_controller_} {
61 static const FunctionInfo functions[] = {
62 {0, &ISaveDataInfoReader::ReadSaveDataInfo, "ReadSaveDataInfo"},
63 };
64 RegisterHandlers(functions);
65
66 FindAllSaves(space);
67 }
68
69 void ReadSaveDataInfo(HLERequestContext& ctx) {
70 LOG_DEBUG(Service_FS, "called");
71
72 // Calculate how many entries we can fit in the output buffer
73 const u64 count_entries = ctx.GetWriteBufferNumElements<SaveDataInfo>();
74
75 // Cap at total number of entries.
76 const u64 actual_entries = std::min(count_entries, info.size() - next_entry_index);
77
78 // Determine data start and end
79 const auto* begin = reinterpret_cast<u8*>(info.data() + next_entry_index);
80 const auto* end = reinterpret_cast<u8*>(info.data() + next_entry_index + actual_entries);
81 const auto range_size = static_cast<std::size_t>(std::distance(begin, end));
82
83 next_entry_index += actual_entries;
84
85 // Write the data to memory
86 ctx.WriteBuffer(begin, range_size);
87
88 IPC::ResponseBuilder rb{ctx, 4};
89 rb.Push(ResultSuccess);
90 rb.Push<u64>(actual_entries);
91 }
92
93private:
94 static u64 stoull_be(std::string_view str) {
95 if (str.size() != 16)
96 return 0;
97
98 const auto bytes = Common::HexStringToArray<0x8>(str);
99 u64 out{};
100 std::memcpy(&out, bytes.data(), sizeof(u64));
101
102 return Common::swap64(out);
103 }
104
105 void FindAllSaves(FileSys::SaveDataSpaceId space) {
106 FileSys::VirtualDir save_root{};
107 const auto result = save_data_controller->OpenSaveDataSpace(&save_root, space);
108
109 if (result != ResultSuccess || save_root == nullptr) {
110 LOG_ERROR(Service_FS, "The save root for the space_id={:02X} was invalid!", space);
111 return;
112 }
113
114 for (const auto& type : save_root->GetSubdirectories()) {
115 if (type->GetName() == "save") {
116 for (const auto& save_id : type->GetSubdirectories()) {
117 for (const auto& user_id : save_id->GetSubdirectories()) {
118 // Skip non user id subdirectories
119 if (user_id->GetName().size() != 0x20) {
120 continue;
121 }
122
123 const auto save_id_numeric = stoull_be(save_id->GetName());
124 auto user_id_numeric = Common::HexStringToArray<0x10>(user_id->GetName());
125 std::reverse(user_id_numeric.begin(), user_id_numeric.end());
126
127 if (save_id_numeric != 0) {
128 // System Save Data
129 info.emplace_back(SaveDataInfo{
130 0,
131 space,
132 FileSys::SaveDataType::SystemSaveData,
133 {},
134 user_id_numeric,
135 save_id_numeric,
136 0,
137 user_id->GetSize(),
138 {},
139 {},
140 });
141
142 continue;
143 }
144
145 for (const auto& title_id : user_id->GetSubdirectories()) {
146 const auto device =
147 std::all_of(user_id_numeric.begin(), user_id_numeric.end(),
148 [](u8 val) { return val == 0; });
149 info.emplace_back(SaveDataInfo{
150 0,
151 space,
152 device ? FileSys::SaveDataType::DeviceSaveData
153 : FileSys::SaveDataType::SaveData,
154 {},
155 user_id_numeric,
156 save_id_numeric,
157 stoull_be(title_id->GetName()),
158 title_id->GetSize(),
159 {},
160 {},
161 });
162 }
163 }
164 }
165 } else if (space == FileSys::SaveDataSpaceId::TemporaryStorage) {
166 // Temporary Storage
167 for (const auto& user_id : type->GetSubdirectories()) {
168 // Skip non user id subdirectories
169 if (user_id->GetName().size() != 0x20) {
170 continue;
171 }
172 for (const auto& title_id : user_id->GetSubdirectories()) {
173 if (!title_id->GetFiles().empty() ||
174 !title_id->GetSubdirectories().empty()) {
175 auto user_id_numeric =
176 Common::HexStringToArray<0x10>(user_id->GetName());
177 std::reverse(user_id_numeric.begin(), user_id_numeric.end());
178
179 info.emplace_back(SaveDataInfo{
180 0,
181 space,
182 FileSys::SaveDataType::TemporaryStorage,
183 {},
184 user_id_numeric,
185 stoull_be(type->GetName()),
186 stoull_be(title_id->GetName()),
187 title_id->GetSize(),
188 {},
189 {},
190 });
191 }
192 }
193 }
194 }
195 }
196 }
197
198 struct SaveDataInfo {
199 u64_le save_id_unknown;
200 FileSys::SaveDataSpaceId space;
201 FileSys::SaveDataType type;
202 INSERT_PADDING_BYTES(0x6);
203 std::array<u8, 0x10> user_id;
204 u64_le save_id;
205 u64_le title_id;
206 u64_le save_image_size;
207 u16_le index;
208 FileSys::SaveDataRank rank;
209 INSERT_PADDING_BYTES(0x25);
210 };
211 static_assert(sizeof(SaveDataInfo) == 0x60, "SaveDataInfo has incorrect size.");
212
213 ProcessId process_id = 0;
214 std::shared_ptr<SaveDataController> save_data_controller;
215 std::vector<SaveDataInfo> info;
216 u64 next_entry_index = 0;
217};
218 45
219FSP_SRV::FSP_SRV(Core::System& system_) 46FSP_SRV::FSP_SRV(Core::System& system_)
220 : ServiceFramework{system_, "fsp-srv"}, fsc{system.GetFileSystemController()}, 47 : ServiceFramework{system_, "fsp-srv"}, fsc{system.GetFileSystemController()},
@@ -222,20 +49,20 @@ FSP_SRV::FSP_SRV(Core::System& system_)
222 // clang-format off 49 // clang-format off
223 static const FunctionInfo functions[] = { 50 static const FunctionInfo functions[] = {
224 {0, nullptr, "OpenFileSystem"}, 51 {0, nullptr, "OpenFileSystem"},
225 {1, &FSP_SRV::SetCurrentProcess, "SetCurrentProcess"}, 52 {1, D<&FSP_SRV::SetCurrentProcess>, "SetCurrentProcess"},
226 {2, nullptr, "OpenDataFileSystemByCurrentProcess"}, 53 {2, nullptr, "OpenDataFileSystemByCurrentProcess"},
227 {7, &FSP_SRV::OpenFileSystemWithPatch, "OpenFileSystemWithPatch"}, 54 {7, D<&FSP_SRV::OpenFileSystemWithPatch>, "OpenFileSystemWithPatch"},
228 {8, nullptr, "OpenFileSystemWithId"}, 55 {8, nullptr, "OpenFileSystemWithId"},
229 {9, nullptr, "OpenDataFileSystemByApplicationId"}, 56 {9, nullptr, "OpenDataFileSystemByApplicationId"},
230 {11, nullptr, "OpenBisFileSystem"}, 57 {11, nullptr, "OpenBisFileSystem"},
231 {12, nullptr, "OpenBisStorage"}, 58 {12, nullptr, "OpenBisStorage"},
232 {13, nullptr, "InvalidateBisCache"}, 59 {13, nullptr, "InvalidateBisCache"},
233 {17, nullptr, "OpenHostFileSystem"}, 60 {17, nullptr, "OpenHostFileSystem"},
234 {18, &FSP_SRV::OpenSdCardFileSystem, "OpenSdCardFileSystem"}, 61 {18, D<&FSP_SRV::OpenSdCardFileSystem>, "OpenSdCardFileSystem"},
235 {19, nullptr, "FormatSdCardFileSystem"}, 62 {19, nullptr, "FormatSdCardFileSystem"},
236 {21, nullptr, "DeleteSaveDataFileSystem"}, 63 {21, nullptr, "DeleteSaveDataFileSystem"},
237 {22, &FSP_SRV::CreateSaveDataFileSystem, "CreateSaveDataFileSystem"}, 64 {22, D<&FSP_SRV::CreateSaveDataFileSystem>, "CreateSaveDataFileSystem"},
238 {23, &FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId, "CreateSaveDataFileSystemBySystemSaveDataId"}, 65 {23, D<&FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId>, "CreateSaveDataFileSystemBySystemSaveDataId"},
239 {24, nullptr, "RegisterSaveDataFileSystemAtomicDeletion"}, 66 {24, nullptr, "RegisterSaveDataFileSystemAtomicDeletion"},
240 {25, nullptr, "DeleteSaveDataFileSystemBySaveDataSpaceId"}, 67 {25, nullptr, "DeleteSaveDataFileSystemBySaveDataSpaceId"},
241 {26, nullptr, "FormatSdCardDryRun"}, 68 {26, nullptr, "FormatSdCardDryRun"},
@@ -245,26 +72,26 @@ FSP_SRV::FSP_SRV(Core::System& system_)
245 {31, nullptr, "OpenGameCardFileSystem"}, 72 {31, nullptr, "OpenGameCardFileSystem"},
246 {32, nullptr, "ExtendSaveDataFileSystem"}, 73 {32, nullptr, "ExtendSaveDataFileSystem"},
247 {33, nullptr, "DeleteCacheStorage"}, 74 {33, nullptr, "DeleteCacheStorage"},
248 {34, &FSP_SRV::GetCacheStorageSize, "GetCacheStorageSize"}, 75 {34, D<&FSP_SRV::GetCacheStorageSize>, "GetCacheStorageSize"},
249 {35, nullptr, "CreateSaveDataFileSystemByHashSalt"}, 76 {35, nullptr, "CreateSaveDataFileSystemByHashSalt"},
250 {36, nullptr, "OpenHostFileSystemWithOption"}, 77 {36, nullptr, "OpenHostFileSystemWithOption"},
251 {51, &FSP_SRV::OpenSaveDataFileSystem, "OpenSaveDataFileSystem"}, 78 {51, D<&FSP_SRV::OpenSaveDataFileSystem>, "OpenSaveDataFileSystem"},
252 {52, &FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId, "OpenSaveDataFileSystemBySystemSaveDataId"}, 79 {52, D<&FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId>, "OpenSaveDataFileSystemBySystemSaveDataId"},
253 {53, &FSP_SRV::OpenReadOnlySaveDataFileSystem, "OpenReadOnlySaveDataFileSystem"}, 80 {53, D<&FSP_SRV::OpenReadOnlySaveDataFileSystem>, "OpenReadOnlySaveDataFileSystem"},
254 {57, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"}, 81 {57, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"},
255 {58, nullptr, "ReadSaveDataFileSystemExtraData"}, 82 {58, nullptr, "ReadSaveDataFileSystemExtraData"},
256 {59, nullptr, "WriteSaveDataFileSystemExtraData"}, 83 {59, nullptr, "WriteSaveDataFileSystemExtraData"},
257 {60, nullptr, "OpenSaveDataInfoReader"}, 84 {60, nullptr, "OpenSaveDataInfoReader"},
258 {61, &FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId, "OpenSaveDataInfoReaderBySaveDataSpaceId"}, 85 {61, D<&FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId>, "OpenSaveDataInfoReaderBySaveDataSpaceId"},
259 {62, &FSP_SRV::OpenSaveDataInfoReaderOnlyCacheStorage, "OpenSaveDataInfoReaderOnlyCacheStorage"}, 86 {62, D<&FSP_SRV::OpenSaveDataInfoReaderOnlyCacheStorage>, "OpenSaveDataInfoReaderOnlyCacheStorage"},
260 {64, nullptr, "OpenSaveDataInternalStorageFileSystem"}, 87 {64, nullptr, "OpenSaveDataInternalStorageFileSystem"},
261 {65, nullptr, "UpdateSaveDataMacForDebug"}, 88 {65, nullptr, "UpdateSaveDataMacForDebug"},
262 {66, nullptr, "WriteSaveDataFileSystemExtraData2"}, 89 {66, nullptr, "WriteSaveDataFileSystemExtraData2"},
263 {67, nullptr, "FindSaveDataWithFilter"}, 90 {67, nullptr, "FindSaveDataWithFilter"},
264 {68, nullptr, "OpenSaveDataInfoReaderBySaveDataFilter"}, 91 {68, nullptr, "OpenSaveDataInfoReaderBySaveDataFilter"},
265 {69, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataAttribute"}, 92 {69, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataAttribute"},
266 {70, &FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute, "WriteSaveDataFileSystemExtraDataBySaveDataAttribute"}, 93 {70, D<&FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute>, "WriteSaveDataFileSystemExtraDataBySaveDataAttribute"},
267 {71, &FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute, "ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute"}, 94 {71, D<&FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute>, "ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute"},
268 {80, nullptr, "OpenSaveDataMetaFile"}, 95 {80, nullptr, "OpenSaveDataMetaFile"},
269 {81, nullptr, "OpenSaveDataTransferManager"}, 96 {81, nullptr, "OpenSaveDataTransferManager"},
270 {82, nullptr, "OpenSaveDataTransferManagerVersion2"}, 97 {82, nullptr, "OpenSaveDataTransferManagerVersion2"},
@@ -279,12 +106,12 @@ FSP_SRV::FSP_SRV(Core::System& system_)
279 {110, nullptr, "OpenContentStorageFileSystem"}, 106 {110, nullptr, "OpenContentStorageFileSystem"},
280 {120, nullptr, "OpenCloudBackupWorkStorageFileSystem"}, 107 {120, nullptr, "OpenCloudBackupWorkStorageFileSystem"},
281 {130, nullptr, "OpenCustomStorageFileSystem"}, 108 {130, nullptr, "OpenCustomStorageFileSystem"},
282 {200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"}, 109 {200, D<&FSP_SRV::OpenDataStorageByCurrentProcess>, "OpenDataStorageByCurrentProcess"},
283 {201, nullptr, "OpenDataStorageByProgramId"}, 110 {201, nullptr, "OpenDataStorageByProgramId"},
284 {202, &FSP_SRV::OpenDataStorageByDataId, "OpenDataStorageByDataId"}, 111 {202, D<&FSP_SRV::OpenDataStorageByDataId>, "OpenDataStorageByDataId"},
285 {203, &FSP_SRV::OpenPatchDataStorageByCurrentProcess, "OpenPatchDataStorageByCurrentProcess"}, 112 {203, D<&FSP_SRV::OpenPatchDataStorageByCurrentProcess>, "OpenPatchDataStorageByCurrentProcess"},
286 {204, nullptr, "OpenDataFileSystemByProgramIndex"}, 113 {204, nullptr, "OpenDataFileSystemByProgramIndex"},
287 {205, &FSP_SRV::OpenDataStorageWithProgramIndex, "OpenDataStorageWithProgramIndex"}, 114 {205, D<&FSP_SRV::OpenDataStorageWithProgramIndex>, "OpenDataStorageWithProgramIndex"},
288 {206, nullptr, "OpenDataStorageByPath"}, 115 {206, nullptr, "OpenDataStorageByPath"},
289 {400, nullptr, "OpenDeviceOperator"}, 116 {400, nullptr, "OpenDeviceOperator"},
290 {500, nullptr, "OpenSdCardDetectionEventNotifier"}, 117 {500, nullptr, "OpenSdCardDetectionEventNotifier"},
@@ -324,25 +151,25 @@ FSP_SRV::FSP_SRV(Core::System& system_)
324 {1000, nullptr, "SetBisRootForHost"}, 151 {1000, nullptr, "SetBisRootForHost"},
325 {1001, nullptr, "SetSaveDataSize"}, 152 {1001, nullptr, "SetSaveDataSize"},
326 {1002, nullptr, "SetSaveDataRootPath"}, 153 {1002, nullptr, "SetSaveDataRootPath"},
327 {1003, &FSP_SRV::DisableAutoSaveDataCreation, "DisableAutoSaveDataCreation"}, 154 {1003, D<&FSP_SRV::DisableAutoSaveDataCreation>, "DisableAutoSaveDataCreation"},
328 {1004, &FSP_SRV::SetGlobalAccessLogMode, "SetGlobalAccessLogMode"}, 155 {1004, D<&FSP_SRV::SetGlobalAccessLogMode>, "SetGlobalAccessLogMode"},
329 {1005, &FSP_SRV::GetGlobalAccessLogMode, "GetGlobalAccessLogMode"}, 156 {1005, D<&FSP_SRV::GetGlobalAccessLogMode>, "GetGlobalAccessLogMode"},
330 {1006, &FSP_SRV::OutputAccessLogToSdCard, "OutputAccessLogToSdCard"}, 157 {1006, D<&FSP_SRV::OutputAccessLogToSdCard>, "OutputAccessLogToSdCard"},
331 {1007, nullptr, "RegisterUpdatePartition"}, 158 {1007, nullptr, "RegisterUpdatePartition"},
332 {1008, nullptr, "OpenRegisteredUpdatePartition"}, 159 {1008, nullptr, "OpenRegisteredUpdatePartition"},
333 {1009, nullptr, "GetAndClearMemoryReportInfo"}, 160 {1009, nullptr, "GetAndClearMemoryReportInfo"},
334 {1010, nullptr, "SetDataStorageRedirectTarget"}, 161 {1010, nullptr, "SetDataStorageRedirectTarget"},
335 {1011, &FSP_SRV::GetProgramIndexForAccessLog, "GetProgramIndexForAccessLog"}, 162 {1011, D<&FSP_SRV::GetProgramIndexForAccessLog>, "GetProgramIndexForAccessLog"},
336 {1012, nullptr, "GetFsStackUsage"}, 163 {1012, nullptr, "GetFsStackUsage"},
337 {1013, nullptr, "UnsetSaveDataRootPath"}, 164 {1013, nullptr, "UnsetSaveDataRootPath"},
338 {1014, nullptr, "OutputMultiProgramTagAccessLog"}, 165 {1014, nullptr, "OutputMultiProgramTagAccessLog"},
339 {1016, &FSP_SRV::FlushAccessLogOnSdCard, "FlushAccessLogOnSdCard"}, 166 {1016, D<&FSP_SRV::FlushAccessLogOnSdCard>, "FlushAccessLogOnSdCard"},
340 {1017, nullptr, "OutputApplicationInfoAccessLog"}, 167 {1017, nullptr, "OutputApplicationInfoAccessLog"},
341 {1018, nullptr, "SetDebugOption"}, 168 {1018, nullptr, "SetDebugOption"},
342 {1019, nullptr, "UnsetDebugOption"}, 169 {1019, nullptr, "UnsetDebugOption"},
343 {1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"}, 170 {1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"},
344 {1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"}, 171 {1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"},
345 {1200, &FSP_SRV::OpenMultiCommitManager, "OpenMultiCommitManager"}, 172 {1200, D<&FSP_SRV::OpenMultiCommitManager>, "OpenMultiCommitManager"},
346 {1300, nullptr, "OpenBisWiper"}, 173 {1300, nullptr, "OpenBisWiper"},
347 }; 174 };
348 // clang-format on 175 // clang-format on
@@ -355,234 +182,177 @@ FSP_SRV::FSP_SRV(Core::System& system_)
355 182
356FSP_SRV::~FSP_SRV() = default; 183FSP_SRV::~FSP_SRV() = default;
357 184
358void FSP_SRV::SetCurrentProcess(HLERequestContext& ctx) { 185Result FSP_SRV::SetCurrentProcess(ClientProcessId pid) {
359 current_process_id = ctx.GetPID(); 186 current_process_id = *pid;
360 187
361 LOG_DEBUG(Service_FS, "called. current_process_id=0x{:016X}", current_process_id); 188 LOG_DEBUG(Service_FS, "called. current_process_id=0x{:016X}", current_process_id);
362 189
363 const auto res = 190 R_RETURN(
364 fsc.OpenProcess(&program_id, &save_data_controller, &romfs_controller, current_process_id); 191 fsc.OpenProcess(&program_id, &save_data_controller, &romfs_controller, current_process_id));
365
366 IPC::ResponseBuilder rb{ctx, 2};
367 rb.Push(res);
368} 192}
369 193
370void FSP_SRV::OpenFileSystemWithPatch(HLERequestContext& ctx) { 194Result FSP_SRV::OpenFileSystemWithPatch(OutInterface<IFileSystem> out_interface,
371 IPC::RequestParser rp{ctx}; 195 FileSystemProxyType type, u64 open_program_id) {
372 196 LOG_ERROR(Service_FS, "(STUBBED) called with type={}, program_id={:016X}", type,
373 struct InputParameters { 197 open_program_id);
374 FileSystemProxyType type;
375 u64 program_id;
376 };
377 static_assert(sizeof(InputParameters) == 0x10, "InputParameters has wrong size");
378
379 const auto params = rp.PopRaw<InputParameters>();
380 LOG_ERROR(Service_FS, "(STUBBED) called with type={}, program_id={:016X}", params.type,
381 params.program_id);
382 198
383 // FIXME: many issues with this 199 // FIXME: many issues with this
384 ASSERT(params.type == FileSystemProxyType::Manual); 200 ASSERT(type == FileSystemProxyType::Manual);
385 const auto manual_romfs = romfs_controller->OpenPatchedRomFS( 201 const auto manual_romfs = romfs_controller->OpenPatchedRomFS(
386 params.program_id, FileSys::ContentRecordType::HtmlDocument); 202 open_program_id, FileSys::ContentRecordType::HtmlDocument);
387 203
388 ASSERT(manual_romfs != nullptr); 204 ASSERT(manual_romfs != nullptr);
389 205
390 const auto extracted_romfs = FileSys::ExtractRomFS(manual_romfs); 206 const auto extracted_romfs = FileSys::ExtractRomFS(manual_romfs);
391 ASSERT(extracted_romfs != nullptr); 207 ASSERT(extracted_romfs != nullptr);
392 208
393 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 209 *out_interface = std::make_shared<IFileSystem>(
394 rb.Push(ResultSuccess); 210 system, extracted_romfs, SizeGetter::FromStorageId(fsc, FileSys::StorageId::NandUser));
395 rb.PushIpcInterface<IFileSystem>(system, extracted_romfs, 211
396 SizeGetter::FromStorageId(fsc, FileSys::StorageId::NandUser)); 212 R_SUCCEED();
397} 213}
398 214
399void FSP_SRV::OpenSdCardFileSystem(HLERequestContext& ctx) { 215Result FSP_SRV::OpenSdCardFileSystem(OutInterface<IFileSystem> out_interface) {
400 LOG_DEBUG(Service_FS, "called"); 216 LOG_DEBUG(Service_FS, "called");
401 217
402 FileSys::VirtualDir sdmc_dir{}; 218 FileSys::VirtualDir sdmc_dir{};
403 fsc.OpenSDMC(&sdmc_dir); 219 fsc.OpenSDMC(&sdmc_dir);
404 220
405 auto filesystem = std::make_shared<IFileSystem>( 221 *out_interface = std::make_shared<IFileSystem>(
406 system, sdmc_dir, SizeGetter::FromStorageId(fsc, FileSys::StorageId::SdCard)); 222 system, sdmc_dir, SizeGetter::FromStorageId(fsc, FileSys::StorageId::SdCard));
407 223
408 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 224 R_SUCCEED();
409 rb.Push(ResultSuccess);
410 rb.PushIpcInterface<IFileSystem>(std::move(filesystem));
411} 225}
412 226
413void FSP_SRV::CreateSaveDataFileSystem(HLERequestContext& ctx) { 227Result FSP_SRV::CreateSaveDataFileSystem(FileSys::SaveDataCreationInfo save_create_struct,
414 IPC::RequestParser rp{ctx}; 228 FileSys::SaveDataAttribute save_struct, u128 uid) {
415
416 auto save_struct = rp.PopRaw<FileSys::SaveDataAttribute>();
417 [[maybe_unused]] auto save_create_struct = rp.PopRaw<std::array<u8, 0x40>>();
418 u128 uid = rp.PopRaw<u128>();
419
420 LOG_DEBUG(Service_FS, "called save_struct = {}, uid = {:016X}{:016X}", save_struct.DebugInfo(), 229 LOG_DEBUG(Service_FS, "called save_struct = {}, uid = {:016X}{:016X}", save_struct.DebugInfo(),
421 uid[1], uid[0]); 230 uid[1], uid[0]);
422 231
423 FileSys::VirtualDir save_data_dir{}; 232 FileSys::VirtualDir save_data_dir{};
424 save_data_controller->CreateSaveData(&save_data_dir, FileSys::SaveDataSpaceId::NandUser, 233 R_RETURN(save_data_controller->CreateSaveData(&save_data_dir, FileSys::SaveDataSpaceId::User,
425 save_struct); 234 save_struct));
426
427 IPC::ResponseBuilder rb{ctx, 2};
428 rb.Push(ResultSuccess);
429} 235}
430 236
431void FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId(HLERequestContext& ctx) { 237Result FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId(
432 IPC::RequestParser rp{ctx}; 238 FileSys::SaveDataCreationInfo save_create_struct, FileSys::SaveDataAttribute save_struct) {
433
434 auto save_struct = rp.PopRaw<FileSys::SaveDataAttribute>();
435 [[maybe_unused]] auto save_create_struct = rp.PopRaw<std::array<u8, 0x40>>();
436
437 LOG_DEBUG(Service_FS, "called save_struct = {}", save_struct.DebugInfo()); 239 LOG_DEBUG(Service_FS, "called save_struct = {}", save_struct.DebugInfo());
438 240
439 FileSys::VirtualDir save_data_dir{}; 241 FileSys::VirtualDir save_data_dir{};
440 save_data_controller->CreateSaveData(&save_data_dir, FileSys::SaveDataSpaceId::NandSystem, 242 R_RETURN(save_data_controller->CreateSaveData(&save_data_dir, FileSys::SaveDataSpaceId::System,
441 save_struct); 243 save_struct));
442
443 IPC::ResponseBuilder rb{ctx, 2};
444 rb.Push(ResultSuccess);
445} 244}
446 245
447void FSP_SRV::OpenSaveDataFileSystem(HLERequestContext& ctx) { 246Result FSP_SRV::OpenSaveDataFileSystem(OutInterface<IFileSystem> out_interface,
448 IPC::RequestParser rp{ctx}; 247 FileSys::SaveDataSpaceId space_id,
449 248 FileSys::SaveDataAttribute attribute) {
450 struct Parameters {
451 FileSys::SaveDataSpaceId space_id;
452 FileSys::SaveDataAttribute attribute;
453 };
454
455 const auto parameters = rp.PopRaw<Parameters>();
456
457 LOG_INFO(Service_FS, "called."); 249 LOG_INFO(Service_FS, "called.");
458 250
459 FileSys::VirtualDir dir{}; 251 FileSys::VirtualDir dir{};
460 auto result = 252 R_TRY(save_data_controller->OpenSaveData(&dir, space_id, attribute));
461 save_data_controller->OpenSaveData(&dir, parameters.space_id, parameters.attribute);
462 if (result != ResultSuccess) {
463 IPC::ResponseBuilder rb{ctx, 2, 0, 0};
464 rb.Push(FileSys::ResultTargetNotFound);
465 return;
466 }
467 253
468 FileSys::StorageId id{}; 254 FileSys::StorageId id{};
469 switch (parameters.space_id) { 255 switch (space_id) {
470 case FileSys::SaveDataSpaceId::NandUser: 256 case FileSys::SaveDataSpaceId::User:
471 id = FileSys::StorageId::NandUser; 257 id = FileSys::StorageId::NandUser;
472 break; 258 break;
473 case FileSys::SaveDataSpaceId::SdCardSystem: 259 case FileSys::SaveDataSpaceId::SdSystem:
474 case FileSys::SaveDataSpaceId::SdCardUser: 260 case FileSys::SaveDataSpaceId::SdUser:
475 id = FileSys::StorageId::SdCard; 261 id = FileSys::StorageId::SdCard;
476 break; 262 break;
477 case FileSys::SaveDataSpaceId::NandSystem: 263 case FileSys::SaveDataSpaceId::System:
478 id = FileSys::StorageId::NandSystem; 264 id = FileSys::StorageId::NandSystem;
479 break; 265 break;
480 case FileSys::SaveDataSpaceId::TemporaryStorage: 266 case FileSys::SaveDataSpaceId::Temporary:
481 case FileSys::SaveDataSpaceId::ProperSystem: 267 case FileSys::SaveDataSpaceId::ProperSystem:
482 case FileSys::SaveDataSpaceId::SafeMode: 268 case FileSys::SaveDataSpaceId::SafeMode:
483 ASSERT(false); 269 ASSERT(false);
484 } 270 }
485 271
486 auto filesystem = 272 *out_interface =
487 std::make_shared<IFileSystem>(system, std::move(dir), SizeGetter::FromStorageId(fsc, id)); 273 std::make_shared<IFileSystem>(system, std::move(dir), SizeGetter::FromStorageId(fsc, id));
488 274
489 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 275 R_SUCCEED();
490 rb.Push(ResultSuccess);
491 rb.PushIpcInterface<IFileSystem>(std::move(filesystem));
492} 276}
493 277
494void FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId(HLERequestContext& ctx) { 278Result FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId(OutInterface<IFileSystem> out_interface,
279 FileSys::SaveDataSpaceId space_id,
280 FileSys::SaveDataAttribute attribute) {
495 LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem"); 281 LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem");
496 OpenSaveDataFileSystem(ctx); 282 R_RETURN(OpenSaveDataFileSystem(out_interface, space_id, attribute));
497} 283}
498 284
499void FSP_SRV::OpenReadOnlySaveDataFileSystem(HLERequestContext& ctx) { 285Result FSP_SRV::OpenReadOnlySaveDataFileSystem(OutInterface<IFileSystem> out_interface,
286 FileSys::SaveDataSpaceId space_id,
287 FileSys::SaveDataAttribute attribute) {
500 LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem"); 288 LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem");
501 OpenSaveDataFileSystem(ctx); 289 R_RETURN(OpenSaveDataFileSystem(out_interface, space_id, attribute));
502} 290}
503 291
504void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(HLERequestContext& ctx) { 292Result FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(
505 IPC::RequestParser rp{ctx}; 293 OutInterface<ISaveDataInfoReader> out_interface, FileSys::SaveDataSpaceId space) {
506 const auto space = rp.PopRaw<FileSys::SaveDataSpaceId>();
507 LOG_INFO(Service_FS, "called, space={}", space); 294 LOG_INFO(Service_FS, "called, space={}", space);
508 295
509 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 296 *out_interface = std::make_shared<ISaveDataInfoReader>(system, save_data_controller, space);
510 rb.Push(ResultSuccess); 297
511 rb.PushIpcInterface<ISaveDataInfoReader>( 298 R_SUCCEED();
512 std::make_shared<ISaveDataInfoReader>(system, save_data_controller, space));
513} 299}
514 300
515void FSP_SRV::OpenSaveDataInfoReaderOnlyCacheStorage(HLERequestContext& ctx) { 301Result FSP_SRV::OpenSaveDataInfoReaderOnlyCacheStorage(
302 OutInterface<ISaveDataInfoReader> out_interface) {
516 LOG_WARNING(Service_FS, "(STUBBED) called"); 303 LOG_WARNING(Service_FS, "(STUBBED) called");
517 304
518 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 305 *out_interface = std::make_shared<ISaveDataInfoReader>(system, save_data_controller,
519 rb.Push(ResultSuccess); 306 FileSys::SaveDataSpaceId::Temporary);
520 rb.PushIpcInterface<ISaveDataInfoReader>(system, save_data_controller, 307
521 FileSys::SaveDataSpaceId::TemporaryStorage); 308 R_SUCCEED();
522} 309}
523 310
524void FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute(HLERequestContext& ctx) { 311Result FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute() {
525 LOG_WARNING(Service_FS, "(STUBBED) called."); 312 LOG_WARNING(Service_FS, "(STUBBED) called.");
526 313
527 IPC::ResponseBuilder rb{ctx, 2}; 314 R_SUCCEED();
528 rb.Push(ResultSuccess);
529} 315}
530 316
531void FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(HLERequestContext& ctx) { 317Result FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(
532 IPC::RequestParser rp{ctx}; 318 FileSys::SaveDataSpaceId space_id, FileSys::SaveDataAttribute attribute,
533 319 InBuffer<BufferAttr_HipcMapAlias> mask_buffer, OutBuffer<BufferAttr_HipcMapAlias> out_buffer) {
534 struct Parameters {
535 FileSys::SaveDataSpaceId space_id;
536 FileSys::SaveDataAttribute attribute;
537 };
538
539 const auto parameters = rp.PopRaw<Parameters>();
540 // Stub this to None for now, backend needs an impl to read/write the SaveDataExtraData 320 // Stub this to None for now, backend needs an impl to read/write the SaveDataExtraData
541 constexpr auto flags = static_cast<u32>(FileSys::SaveDataFlags::None); 321 // In an earlier version of the code, this was returned as an out argument, but this is not
322 // correct
323 [[maybe_unused]] constexpr auto flags = static_cast<u32>(FileSys::SaveDataFlags::None);
542 324
543 LOG_WARNING(Service_FS, 325 LOG_WARNING(Service_FS,
544 "(STUBBED) called, flags={}, space_id={}, attribute.title_id={:016X}\n" 326 "(STUBBED) called, flags={}, space_id={}, attribute.program_id={:016X}\n"
545 "attribute.user_id={:016X}{:016X}, attribute.save_id={:016X}\n" 327 "attribute.user_id={:016X}{:016X}, attribute.save_id={:016X}\n"
546 "attribute.type={}, attribute.rank={}, attribute.index={}", 328 "attribute.type={}, attribute.rank={}, attribute.index={}",
547 flags, parameters.space_id, parameters.attribute.title_id, 329 flags, space_id, attribute.program_id, attribute.user_id[1], attribute.user_id[0],
548 parameters.attribute.user_id[1], parameters.attribute.user_id[0], 330 attribute.system_save_data_id, attribute.type, attribute.rank, attribute.index);
549 parameters.attribute.save_id, parameters.attribute.type, parameters.attribute.rank, 331
550 parameters.attribute.index); 332 R_SUCCEED();
551
552 IPC::ResponseBuilder rb{ctx, 3};
553 rb.Push(ResultSuccess);
554 rb.Push(flags);
555} 333}
556 334
557void FSP_SRV::OpenDataStorageByCurrentProcess(HLERequestContext& ctx) { 335Result FSP_SRV::OpenDataStorageByCurrentProcess(OutInterface<IStorage> out_interface) {
558 LOG_DEBUG(Service_FS, "called"); 336 LOG_DEBUG(Service_FS, "called");
559 337
560 if (!romfs) { 338 if (!romfs) {
561 auto current_romfs = romfs_controller->OpenRomFSCurrentProcess(); 339 auto current_romfs = romfs_controller->OpenRomFSCurrentProcess();
562 if (!current_romfs) { 340 if (!current_romfs) {
563 // TODO (bunnei): Find the right error code to use here 341 // TODO (bunnei): Find the right error code to use here
564 LOG_CRITICAL(Service_FS, "no file system interface available!"); 342 LOG_CRITICAL(Service_FS, "No file system interface available!");
565 IPC::ResponseBuilder rb{ctx, 2}; 343 R_RETURN(ResultUnknown);
566 rb.Push(ResultUnknown);
567 return;
568 } 344 }
569 345
570 romfs = current_romfs; 346 romfs = current_romfs;
571 } 347 }
572 348
573 auto storage = std::make_shared<IStorage>(system, romfs); 349 *out_interface = std::make_shared<IStorage>(system, romfs);
574 350
575 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 351 R_SUCCEED();
576 rb.Push(ResultSuccess);
577 rb.PushIpcInterface<IStorage>(std::move(storage));
578} 352}
579 353
580void FSP_SRV::OpenDataStorageByDataId(HLERequestContext& ctx) { 354Result FSP_SRV::OpenDataStorageByDataId(OutInterface<IStorage> out_interface,
581 IPC::RequestParser rp{ctx}; 355 FileSys::StorageId storage_id, u32 unknown, u64 title_id) {
582 const auto storage_id = rp.PopRaw<FileSys::StorageId>();
583 const auto unknown = rp.PopRaw<u32>();
584 const auto title_id = rp.PopRaw<u64>();
585
586 LOG_DEBUG(Service_FS, "called with storage_id={:02X}, unknown={:08X}, title_id={:016X}", 356 LOG_DEBUG(Service_FS, "called with storage_id={:02X}, unknown={:08X}, title_id={:016X}",
587 storage_id, unknown, title_id); 357 storage_id, unknown, title_id);
588 358
@@ -592,19 +362,15 @@ void FSP_SRV::OpenDataStorageByDataId(HLERequestContext& ctx) {
592 const auto archive = FileSys::SystemArchive::SynthesizeSystemArchive(title_id); 362 const auto archive = FileSys::SystemArchive::SynthesizeSystemArchive(title_id);
593 363
594 if (archive != nullptr) { 364 if (archive != nullptr) {
595 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 365 *out_interface = std::make_shared<IStorage>(system, archive);
596 rb.Push(ResultSuccess); 366 R_SUCCEED();
597 rb.PushIpcInterface(std::make_shared<IStorage>(system, archive));
598 return;
599 } 367 }
600 368
601 // TODO(DarkLordZach): Find the right error code to use here 369 // TODO(DarkLordZach): Find the right error code to use here
602 LOG_ERROR(Service_FS, 370 LOG_ERROR(Service_FS,
603 "could not open data storage with title_id={:016X}, storage_id={:02X}", title_id, 371 "Could not open data storage with title_id={:016X}, storage_id={:02X}", title_id,
604 storage_id); 372 storage_id);
605 IPC::ResponseBuilder rb{ctx, 2}; 373 R_RETURN(ResultUnknown);
606 rb.Push(ResultUnknown);
607 return;
608 } 374 }
609 375
610 const FileSys::PatchManager pm{title_id, fsc, content_provider}; 376 const FileSys::PatchManager pm{title_id, fsc, content_provider};
@@ -614,28 +380,20 @@ void FSP_SRV::OpenDataStorageByDataId(HLERequestContext& ctx) {
614 auto storage = std::make_shared<IStorage>( 380 auto storage = std::make_shared<IStorage>(
615 system, pm.PatchRomFS(base.get(), std::move(data), FileSys::ContentRecordType::Data)); 381 system, pm.PatchRomFS(base.get(), std::move(data), FileSys::ContentRecordType::Data));
616 382
617 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 383 *out_interface = std::move(storage);
618 rb.Push(ResultSuccess); 384 R_SUCCEED();
619 rb.PushIpcInterface<IStorage>(std::move(storage));
620} 385}
621 386
622void FSP_SRV::OpenPatchDataStorageByCurrentProcess(HLERequestContext& ctx) { 387Result FSP_SRV::OpenPatchDataStorageByCurrentProcess(OutInterface<IStorage> out_interface,
623 IPC::RequestParser rp{ctx}; 388 FileSys::StorageId storage_id, u64 title_id) {
624 389 LOG_WARNING(Service_FS, "(STUBBED) called with storage_id={:02X}, title_id={:016X}", storage_id,
625 const auto storage_id = rp.PopRaw<FileSys::StorageId>(); 390 title_id);
626 const auto title_id = rp.PopRaw<u64>();
627 391
628 LOG_DEBUG(Service_FS, "called with storage_id={:02X}, title_id={:016X}", storage_id, title_id); 392 R_RETURN(FileSys::ResultTargetNotFound);
629
630 IPC::ResponseBuilder rb{ctx, 2};
631 rb.Push(FileSys::ResultTargetNotFound);
632} 393}
633 394
634void FSP_SRV::OpenDataStorageWithProgramIndex(HLERequestContext& ctx) { 395Result FSP_SRV::OpenDataStorageWithProgramIndex(OutInterface<IStorage> out_interface,
635 IPC::RequestParser rp{ctx}; 396 u8 program_index) {
636
637 const auto program_index = rp.PopRaw<u8>();
638
639 LOG_DEBUG(Service_FS, "called, program_index={}", program_index); 397 LOG_DEBUG(Service_FS, "called, program_index={}", program_index);
640 398
641 auto patched_romfs = romfs_controller->OpenPatchedRomFSWithProgramIndex( 399 auto patched_romfs = romfs_controller->OpenPatchedRomFSWithProgramIndex(
@@ -643,123 +401,80 @@ void FSP_SRV::OpenDataStorageWithProgramIndex(HLERequestContext& ctx) {
643 401
644 if (!patched_romfs) { 402 if (!patched_romfs) {
645 // TODO: Find the right error code to use here 403 // TODO: Find the right error code to use here
646 LOG_ERROR(Service_FS, "could not open storage with program_index={}", program_index); 404 LOG_ERROR(Service_FS, "Could not open storage with program_index={}", program_index);
647 405 R_RETURN(ResultUnknown);
648 IPC::ResponseBuilder rb{ctx, 2};
649 rb.Push(ResultUnknown);
650 return;
651 } 406 }
652 407
653 auto storage = std::make_shared<IStorage>(system, std::move(patched_romfs)); 408 *out_interface = std::make_shared<IStorage>(system, std::move(patched_romfs));
654 409
655 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 410 R_SUCCEED();
656 rb.Push(ResultSuccess);
657 rb.PushIpcInterface<IStorage>(std::move(storage));
658} 411}
659 412
660void FSP_SRV::DisableAutoSaveDataCreation(HLERequestContext& ctx) { 413Result FSP_SRV::DisableAutoSaveDataCreation() {
661 LOG_DEBUG(Service_FS, "called"); 414 LOG_DEBUG(Service_FS, "called");
662 415
663 save_data_controller->SetAutoCreate(false); 416 save_data_controller->SetAutoCreate(false);
664 417
665 IPC::ResponseBuilder rb{ctx, 2}; 418 R_SUCCEED();
666 rb.Push(ResultSuccess);
667} 419}
668 420
669void FSP_SRV::SetGlobalAccessLogMode(HLERequestContext& ctx) { 421Result FSP_SRV::SetGlobalAccessLogMode(AccessLogMode access_log_mode_) {
670 IPC::RequestParser rp{ctx}; 422 LOG_DEBUG(Service_FS, "called, access_log_mode={}", access_log_mode_);
671 access_log_mode = rp.PopEnum<AccessLogMode>();
672 423
673 LOG_DEBUG(Service_FS, "called, access_log_mode={}", access_log_mode); 424 access_log_mode = access_log_mode_;
674 425
675 IPC::ResponseBuilder rb{ctx, 2}; 426 R_SUCCEED();
676 rb.Push(ResultSuccess);
677} 427}
678 428
679void FSP_SRV::GetGlobalAccessLogMode(HLERequestContext& ctx) { 429Result FSP_SRV::GetGlobalAccessLogMode(Out<AccessLogMode> out_access_log_mode) {
680 LOG_DEBUG(Service_FS, "called"); 430 LOG_DEBUG(Service_FS, "called");
681 431
682 IPC::ResponseBuilder rb{ctx, 3}; 432 *out_access_log_mode = access_log_mode;
683 rb.Push(ResultSuccess);
684 rb.PushEnum(access_log_mode);
685}
686 433
687void FSP_SRV::OutputAccessLogToSdCard(HLERequestContext& ctx) { 434 R_SUCCEED();
688 const auto raw = ctx.ReadBufferCopy(); 435}
689 auto log = Common::StringFromFixedZeroTerminatedBuffer(
690 reinterpret_cast<const char*>(raw.data()), raw.size());
691 436
437Result FSP_SRV::OutputAccessLogToSdCard(InBuffer<BufferAttr_HipcMapAlias> log_message_buffer) {
692 LOG_DEBUG(Service_FS, "called"); 438 LOG_DEBUG(Service_FS, "called");
693 439
440 auto log = Common::StringFromFixedZeroTerminatedBuffer(
441 reinterpret_cast<const char*>(log_message_buffer.data()), log_message_buffer.size());
694 reporter.SaveFSAccessLog(log); 442 reporter.SaveFSAccessLog(log);
695 443
696 IPC::ResponseBuilder rb{ctx, 2}; 444 R_SUCCEED();
697 rb.Push(ResultSuccess);
698} 445}
699 446
700void FSP_SRV::GetProgramIndexForAccessLog(HLERequestContext& ctx) { 447Result FSP_SRV::GetProgramIndexForAccessLog(Out<AccessLogVersion> out_access_log_version,
701 LOG_DEBUG(Service_FS, "called"); 448 Out<u32> out_access_log_program_index) {
449 LOG_DEBUG(Service_FS, "(STUBBED) called");
450
451 *out_access_log_version = AccessLogVersion::Latest;
452 *out_access_log_program_index = access_log_program_index;
702 453
703 IPC::ResponseBuilder rb{ctx, 4}; 454 R_SUCCEED();
704 rb.Push(ResultSuccess);
705 rb.PushEnum(AccessLogVersion::Latest);
706 rb.Push(access_log_program_index);
707} 455}
708 456
709void FSP_SRV::FlushAccessLogOnSdCard(HLERequestContext& ctx) { 457Result FSP_SRV::FlushAccessLogOnSdCard() {
710 LOG_DEBUG(Service_FS, "(STUBBED) called"); 458 LOG_DEBUG(Service_FS, "(STUBBED) called");
711 459
712 IPC::ResponseBuilder rb{ctx, 2}; 460 R_SUCCEED();
713 rb.Push(ResultSuccess);
714} 461}
715 462
716void FSP_SRV::GetCacheStorageSize(HLERequestContext& ctx) { 463Result FSP_SRV::GetCacheStorageSize(s32 index, Out<s64> out_data_size, Out<s64> out_journal_size) {
717 IPC::RequestParser rp{ctx};
718 const auto index{rp.Pop<s32>()};
719
720 LOG_WARNING(Service_FS, "(STUBBED) called with index={}", index); 464 LOG_WARNING(Service_FS, "(STUBBED) called with index={}", index);
721 465
722 IPC::ResponseBuilder rb{ctx, 6}; 466 *out_data_size = 0;
723 rb.Push(ResultSuccess); 467 *out_journal_size = 0;
724 rb.Push(s64{0});
725 rb.Push(s64{0});
726}
727
728class IMultiCommitManager final : public ServiceFramework<IMultiCommitManager> {
729public:
730 explicit IMultiCommitManager(Core::System& system_)
731 : ServiceFramework{system_, "IMultiCommitManager"} {
732 static const FunctionInfo functions[] = {
733 {1, &IMultiCommitManager::Add, "Add"},
734 {2, &IMultiCommitManager::Commit, "Commit"},
735 };
736 RegisterHandlers(functions);
737 }
738 468
739private: 469 R_SUCCEED();
740 FileSys::VirtualFile backend; 470}
741
742 void Add(HLERequestContext& ctx) {
743 LOG_WARNING(Service_FS, "(STUBBED) called");
744
745 IPC::ResponseBuilder rb{ctx, 2};
746 rb.Push(ResultSuccess);
747 }
748
749 void Commit(HLERequestContext& ctx) {
750 LOG_WARNING(Service_FS, "(STUBBED) called");
751
752 IPC::ResponseBuilder rb{ctx, 2};
753 rb.Push(ResultSuccess);
754 }
755};
756 471
757void FSP_SRV::OpenMultiCommitManager(HLERequestContext& ctx) { 472Result FSP_SRV::OpenMultiCommitManager(OutInterface<IMultiCommitManager> out_interface) {
758 LOG_DEBUG(Service_FS, "called"); 473 LOG_DEBUG(Service_FS, "called");
759 474
760 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 475 *out_interface = std::make_shared<IMultiCommitManager>(system);
761 rb.Push(ResultSuccess); 476
762 rb.PushIpcInterface<IMultiCommitManager>(std::make_shared<IMultiCommitManager>(system)); 477 R_SUCCEED();
763} 478}
764 479
765} // namespace Service::FileSystem 480} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.h b/src/core/hle/service/filesystem/fsp/fsp_srv.h
index 59406e6f9..ee67f6bc1 100755
--- a/src/core/hle/service/filesystem/fsp/fsp_srv.h
+++ b/src/core/hle/service/filesystem/fsp/fsp_srv.h
@@ -4,6 +4,9 @@
4#pragma once 4#pragma once
5 5
6#include <memory> 6#include <memory>
7#include "core/file_sys/fs_save_data_types.h"
8#include "core/hle/service/cmif_types.h"
9#include "core/hle/service/filesystem/fsp/fsp_types.h"
7#include "core/hle/service/service.h" 10#include "core/hle/service/service.h"
8 11
9namespace Core { 12namespace Core {
@@ -20,6 +23,11 @@ namespace Service::FileSystem {
20class RomFsController; 23class RomFsController;
21class SaveDataController; 24class SaveDataController;
22 25
26class IFileSystem;
27class ISaveDataInfoReader;
28class IStorage;
29class IMultiCommitManager;
30
23enum class AccessLogVersion : u32 { 31enum class AccessLogVersion : u32 {
24 V7_0_0 = 2, 32 V7_0_0 = 2,
25 33
@@ -38,30 +46,46 @@ public:
38 ~FSP_SRV() override; 46 ~FSP_SRV() override;
39 47
40private: 48private:
41 void SetCurrentProcess(HLERequestContext& ctx); 49 Result SetCurrentProcess(ClientProcessId pid);
42 void OpenFileSystemWithPatch(HLERequestContext& ctx); 50 Result OpenFileSystemWithPatch(OutInterface<IFileSystem> out_interface,
43 void OpenSdCardFileSystem(HLERequestContext& ctx); 51 FileSystemProxyType type, u64 open_program_id);
44 void CreateSaveDataFileSystem(HLERequestContext& ctx); 52 Result OpenSdCardFileSystem(OutInterface<IFileSystem> out_interface);
45 void CreateSaveDataFileSystemBySystemSaveDataId(HLERequestContext& ctx); 53 Result CreateSaveDataFileSystem(FileSys::SaveDataCreationInfo save_create_struct,
46 void OpenSaveDataFileSystem(HLERequestContext& ctx); 54 FileSys::SaveDataAttribute save_struct, u128 uid);
47 void OpenSaveDataFileSystemBySystemSaveDataId(HLERequestContext& ctx); 55 Result CreateSaveDataFileSystemBySystemSaveDataId(
48 void OpenReadOnlySaveDataFileSystem(HLERequestContext& ctx); 56 FileSys::SaveDataCreationInfo save_create_struct, FileSys::SaveDataAttribute save_struct);
49 void OpenSaveDataInfoReaderBySaveDataSpaceId(HLERequestContext& ctx); 57 Result OpenSaveDataFileSystem(OutInterface<IFileSystem> out_interface,
50 void OpenSaveDataInfoReaderOnlyCacheStorage(HLERequestContext& ctx); 58 FileSys::SaveDataSpaceId space_id,
51 void WriteSaveDataFileSystemExtraDataBySaveDataAttribute(HLERequestContext& ctx); 59 FileSys::SaveDataAttribute attribute);
52 void ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(HLERequestContext& ctx); 60 Result OpenSaveDataFileSystemBySystemSaveDataId(OutInterface<IFileSystem> out_interface,
53 void OpenDataStorageByCurrentProcess(HLERequestContext& ctx); 61 FileSys::SaveDataSpaceId space_id,
54 void OpenDataStorageByDataId(HLERequestContext& ctx); 62 FileSys::SaveDataAttribute attribute);
55 void OpenPatchDataStorageByCurrentProcess(HLERequestContext& ctx); 63 Result OpenReadOnlySaveDataFileSystem(OutInterface<IFileSystem> out_interface,
56 void OpenDataStorageWithProgramIndex(HLERequestContext& ctx); 64 FileSys::SaveDataSpaceId space_id,
57 void DisableAutoSaveDataCreation(HLERequestContext& ctx); 65 FileSys::SaveDataAttribute attribute);
58 void SetGlobalAccessLogMode(HLERequestContext& ctx); 66 Result OpenSaveDataInfoReaderBySaveDataSpaceId(OutInterface<ISaveDataInfoReader> out_interface,
59 void GetGlobalAccessLogMode(HLERequestContext& ctx); 67 FileSys::SaveDataSpaceId space);
60 void OutputAccessLogToSdCard(HLERequestContext& ctx); 68 Result OpenSaveDataInfoReaderOnlyCacheStorage(OutInterface<ISaveDataInfoReader> out_interface);
61 void FlushAccessLogOnSdCard(HLERequestContext& ctx); 69 Result WriteSaveDataFileSystemExtraDataBySaveDataAttribute();
62 void GetProgramIndexForAccessLog(HLERequestContext& ctx); 70 Result ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(
63 void OpenMultiCommitManager(HLERequestContext& ctx); 71 FileSys::SaveDataSpaceId space_id, FileSys::SaveDataAttribute attribute,
64 void GetCacheStorageSize(HLERequestContext& ctx); 72 InBuffer<BufferAttr_HipcMapAlias> mask_buffer,
73 OutBuffer<BufferAttr_HipcMapAlias> out_buffer);
74 Result OpenDataStorageByCurrentProcess(OutInterface<IStorage> out_interface);
75 Result OpenDataStorageByDataId(OutInterface<IStorage> out_interface,
76 FileSys::StorageId storage_id, u32 unknown, u64 title_id);
77 Result OpenPatchDataStorageByCurrentProcess(OutInterface<IStorage> out_interface,
78 FileSys::StorageId storage_id, u64 title_id);
79 Result OpenDataStorageWithProgramIndex(OutInterface<IStorage> out_interface, u8 program_index);
80 Result DisableAutoSaveDataCreation();
81 Result SetGlobalAccessLogMode(AccessLogMode access_log_mode_);
82 Result GetGlobalAccessLogMode(Out<AccessLogMode> out_access_log_mode);
83 Result OutputAccessLogToSdCard(InBuffer<BufferAttr_HipcMapAlias> log_message_buffer);
84 Result FlushAccessLogOnSdCard();
85 Result GetProgramIndexForAccessLog(Out<AccessLogVersion> out_access_log_version,
86 Out<u32> out_access_log_program_index);
87 Result OpenMultiCommitManager(OutInterface<IMultiCommitManager> out_interface);
88 Result GetCacheStorageSize(s32 index, Out<s64> out_data_size, Out<s64> out_journal_size);
65 89
66 FileSystemController& fsc; 90 FileSystemController& fsc;
67 const FileSys::ContentProvider& content_provider; 91 const FileSys::ContentProvider& content_provider;
diff --git a/src/core/hle/service/filesystem/fsp/fsp_types.h b/src/core/hle/service/filesystem/fsp/fsp_types.h
new file mode 100755
index 000000000..294da6a2d
--- /dev/null
+++ b/src/core/hle/service/filesystem/fsp/fsp_types.h
@@ -0,0 +1,34 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/filesystem/filesystem.h"
7
8namespace Service::FileSystem {
9
10enum class FileSystemProxyType : u8 {
11 Code = 0,
12 Rom = 1,
13 Logo = 2,
14 Control = 3,
15 Manual = 4,
16 Meta = 5,
17 Data = 6,
18 Package = 7,
19 RegisteredUpdate = 8,
20};
21
22struct SizeGetter {
23 std::function<u64()> get_free_size;
24 std::function<u64()> get_total_size;
25
26 static SizeGetter FromStorageId(const FileSystemController& fsc, FileSys::StorageId id) {
27 return {
28 [&fsc, id] { return fsc.GetFreeSpaceSize(id); },
29 [&fsc, id] { return fsc.GetTotalSpaceSize(id); },
30 };
31 }
32};
33
34} // namespace Service::FileSystem
diff --git a/src/core/hle/service/olsc/daemon_controller.cpp b/src/core/hle/service/olsc/daemon_controller.cpp
new file mode 100755
index 000000000..7823780a8
--- /dev/null
+++ b/src/core/hle/service/olsc/daemon_controller.cpp
@@ -0,0 +1,40 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/olsc/daemon_controller.h"
6
7namespace Service::OLSC {
8
9IDaemonController::IDaemonController(Core::System& system_)
10 : ServiceFramework{system_, "IDaemonController"} {
11 // clang-format off
12 static const FunctionInfo functions[] = {
13 {0, D<&IDaemonController::GetAutoTransferEnabledForAccountAndApplication>, "GetAutoTransferEnabledForAccountAndApplication"},
14 {1, nullptr, "SetAutoTransferEnabledForAccountAndApplication"},
15 {2, nullptr, "GetGlobalUploadEnabledForAccount"},
16 {3, nullptr, "SetGlobalUploadEnabledForAccount"},
17 {4, nullptr, "TouchAccount"},
18 {5, nullptr, "GetGlobalDownloadEnabledForAccount"},
19 {6, nullptr, "SetGlobalDownloadEnabledForAccount"},
20 {10, nullptr, "GetForbiddenSaveDataIndication"},
21 {11, nullptr, "GetStopperObject"},
22 {12, nullptr, "GetState"},
23 };
24 // clang-format on
25
26 RegisterHandlers(functions);
27}
28
29IDaemonController::~IDaemonController() = default;
30
31Result IDaemonController::GetAutoTransferEnabledForAccountAndApplication(Out<bool> out_is_enabled,
32 Common::UUID user_id,
33 u64 application_id) {
34 LOG_WARNING(Service_OLSC, "(STUBBED) called, user_id={} application_id={:016X}",
35 user_id.FormattedString(), application_id);
36 *out_is_enabled = false;
37 R_SUCCEED();
38}
39
40} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/daemon_controller.h b/src/core/hle/service/olsc/daemon_controller.h
new file mode 100755
index 000000000..dfad7f52a
--- /dev/null
+++ b/src/core/hle/service/olsc/daemon_controller.h
@@ -0,0 +1,20 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/uuid.h"
5#include "core/hle/service/cmif_types.h"
6#include "core/hle/service/service.h"
7
8namespace Service::OLSC {
9
10class IDaemonController final : public ServiceFramework<IDaemonController> {
11public:
12 explicit IDaemonController(Core::System& system_);
13 ~IDaemonController() override;
14
15private:
16 Result GetAutoTransferEnabledForAccountAndApplication(Out<bool> out_is_enabled,
17 Common::UUID user_id, u64 application_id);
18};
19
20} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/native_handle_holder.cpp b/src/core/hle/service/olsc/native_handle_holder.cpp
new file mode 100755
index 000000000..3cb5d7b11
--- /dev/null
+++ b/src/core/hle/service/olsc/native_handle_holder.cpp
@@ -0,0 +1,28 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/olsc/native_handle_holder.h"
6
7namespace Service::OLSC {
8
9INativeHandleHolder::INativeHandleHolder(Core::System& system_)
10 : ServiceFramework{system_, "INativeHandleHolder"} {
11 // clang-format off
12 static const FunctionInfo functions[] = {
13 {0, D<&INativeHandleHolder::GetNativeHandle>, "GetNativeHandle"},
14 };
15 // clang-format on
16
17 RegisterHandlers(functions);
18}
19
20INativeHandleHolder::~INativeHandleHolder() = default;
21
22Result INativeHandleHolder::GetNativeHandle(OutCopyHandle<Kernel::KReadableEvent> out_event) {
23 LOG_WARNING(Service_OLSC, "(STUBBED) called");
24 *out_event = nullptr;
25 R_SUCCEED();
26}
27
28} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/native_handle_holder.h b/src/core/hle/service/olsc/native_handle_holder.h
new file mode 100755
index 000000000..a44754c20
--- /dev/null
+++ b/src/core/hle/service/olsc/native_handle_holder.h
@@ -0,0 +1,22 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_types.h"
5#include "core/hle/service/service.h"
6
7namespace Kernel {
8class KReadableEvent;
9}
10
11namespace Service::OLSC {
12
13class INativeHandleHolder final : public ServiceFramework<INativeHandleHolder> {
14public:
15 explicit INativeHandleHolder(Core::System& system_);
16 ~INativeHandleHolder() override;
17
18private:
19 Result GetNativeHandle(OutCopyHandle<Kernel::KReadableEvent> out_event);
20};
21
22} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/olsc.cpp b/src/core/hle/service/olsc/olsc.cpp
index 010b406b2..d5acb719e 100755
--- a/src/core/hle/service/olsc/olsc.cpp
+++ b/src/core/hle/service/olsc/olsc.cpp
@@ -1,226 +1,27 @@
1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/ipc_helpers.h"
5#include "core/hle/service/olsc/olsc.h" 4#include "core/hle/service/olsc/olsc.h"
5#include "core/hle/service/olsc/olsc_service_for_application.h"
6#include "core/hle/service/olsc/olsc_service_for_system_service.h"
6#include "core/hle/service/server_manager.h" 7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8 9
9namespace Service::OLSC { 10namespace Service::OLSC {
10 11
11class IOlscServiceForApplication final : public ServiceFramework<IOlscServiceForApplication> {
12public:
13 explicit IOlscServiceForApplication(Core::System& system_)
14 : ServiceFramework{system_, "olsc:u"} {
15 // clang-format off
16 static const FunctionInfo functions[] = {
17 {0, &IOlscServiceForApplication::Initialize, "Initialize"},
18 {10, nullptr, "VerifySaveDataBackupLicenseAsync"},
19 {13, &IOlscServiceForApplication::GetSaveDataBackupSetting, "GetSaveDataBackupSetting"},
20 {14, &IOlscServiceForApplication::SetSaveDataBackupSettingEnabled, "SetSaveDataBackupSettingEnabled"},
21 {15, nullptr, "SetCustomData"},
22 {16, nullptr, "DeleteSaveDataBackupSetting"},
23 {18, nullptr, "GetSaveDataBackupInfoCache"},
24 {19, nullptr, "UpdateSaveDataBackupInfoCacheAsync"},
25 {22, nullptr, "DeleteSaveDataBackupAsync"},
26 {25, nullptr, "ListDownloadableSaveDataBackupInfoAsync"},
27 {26, nullptr, "DownloadSaveDataBackupAsync"},
28 {27, nullptr, "UploadSaveDataBackupAsync"},
29 {9010, nullptr, "VerifySaveDataBackupLicenseAsyncForDebug"},
30 {9013, nullptr, "GetSaveDataBackupSettingForDebug"},
31 {9014, nullptr, "SetSaveDataBackupSettingEnabledForDebug"},
32 {9015, nullptr, "SetCustomDataForDebug"},
33 {9016, nullptr, "DeleteSaveDataBackupSettingForDebug"},
34 {9018, nullptr, "GetSaveDataBackupInfoCacheForDebug"},
35 {9019, nullptr, "UpdateSaveDataBackupInfoCacheAsyncForDebug"},
36 {9022, nullptr, "DeleteSaveDataBackupAsyncForDebug"},
37 {9025, nullptr, "ListDownloadableSaveDataBackupInfoAsyncForDebug"},
38 {9026, nullptr, "DownloadSaveDataBackupAsyncForDebug"},
39 };
40 // clang-format on
41
42 RegisterHandlers(functions);
43 }
44
45private:
46 void Initialize(HLERequestContext& ctx) {
47 LOG_WARNING(Service_OLSC, "(STUBBED) called");
48
49 initialized = true;
50
51 IPC::ResponseBuilder rb{ctx, 2};
52 rb.Push(ResultSuccess);
53 }
54
55 void GetSaveDataBackupSetting(HLERequestContext& ctx) {
56 LOG_WARNING(Service_OLSC, "(STUBBED) called");
57
58 // backup_setting is set to 0 since real value is unknown
59 constexpr u64 backup_setting = 0;
60
61 IPC::ResponseBuilder rb{ctx, 4};
62 rb.Push(ResultSuccess);
63 rb.Push(backup_setting);
64 }
65
66 void SetSaveDataBackupSettingEnabled(HLERequestContext& ctx) {
67 LOG_WARNING(Service_OLSC, "(STUBBED) called");
68
69 IPC::ResponseBuilder rb{ctx, 2};
70 rb.Push(ResultSuccess);
71 }
72
73 bool initialized{};
74};
75
76class INativeHandleHolder final : public ServiceFramework<INativeHandleHolder> {
77public:
78 explicit INativeHandleHolder(Core::System& system_)
79 : ServiceFramework{system_, "INativeHandleHolder"} {
80 // clang-format off
81 static const FunctionInfo functions[] = {
82 {0, nullptr, "GetNativeHandle"},
83 };
84 // clang-format on
85
86 RegisterHandlers(functions);
87 }
88};
89
90class ITransferTaskListController final : public ServiceFramework<ITransferTaskListController> {
91public:
92 explicit ITransferTaskListController(Core::System& system_)
93 : ServiceFramework{system_, "ITransferTaskListController"} {
94 // clang-format off
95 static const FunctionInfo functions[] = {
96 {0, nullptr, "Unknown0"},
97 {1, nullptr, "Unknown1"},
98 {2, nullptr, "Unknown2"},
99 {3, nullptr, "Unknown3"},
100 {4, nullptr, "Unknown4"},
101 {5, &ITransferTaskListController::GetNativeHandleHolder , "GetNativeHandleHolder"},
102 {6, nullptr, "Unknown6"},
103 {7, nullptr, "Unknown7"},
104 {8, nullptr, "GetRemoteStorageController"},
105 {9, &ITransferTaskListController::GetNativeHandleHolder, "GetNativeHandleHolder2"},
106 {10, nullptr, "Unknown10"},
107 {11, nullptr, "Unknown11"},
108 {12, nullptr, "Unknown12"},
109 {13, nullptr, "Unknown13"},
110 {14, nullptr, "Unknown14"},
111 {15, nullptr, "Unknown15"},
112 {16, nullptr, "Unknown16"},
113 {17, nullptr, "Unknown17"},
114 {18, nullptr, "Unknown18"},
115 {19, nullptr, "Unknown19"},
116 {20, nullptr, "Unknown20"},
117 {21, nullptr, "Unknown21"},
118 {22, nullptr, "Unknown22"},
119 {23, nullptr, "Unknown23"},
120 {24, nullptr, "Unknown24"},
121 {25, nullptr, "Unknown25"},
122 };
123 // clang-format on
124
125 RegisterHandlers(functions);
126 }
127
128private:
129 void GetNativeHandleHolder(HLERequestContext& ctx) {
130 LOG_INFO(Service_OLSC, "called");
131
132 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
133 rb.Push(ResultSuccess);
134 rb.PushIpcInterface<INativeHandleHolder>(system);
135 }
136};
137
138class IOlscServiceForSystemService final : public ServiceFramework<IOlscServiceForSystemService> {
139public:
140 explicit IOlscServiceForSystemService(Core::System& system_)
141 : ServiceFramework{system_, "olsc:s"} {
142 // clang-format off
143 static const FunctionInfo functions[] = {
144 {0, &IOlscServiceForSystemService::OpenTransferTaskListController, "OpenTransferTaskListController"},
145 {1, nullptr, "OpenRemoteStorageController"},
146 {2, nullptr, "OpenDaemonController"},
147 {10, nullptr, "Unknown10"},
148 {11, nullptr, "Unknown11"},
149 {12, nullptr, "Unknown12"},
150 {13, nullptr, "Unknown13"},
151 {100, nullptr, "ListLastTransferTaskErrorInfo"},
152 {101, nullptr, "GetLastErrorInfoCount"},
153 {102, nullptr, "RemoveLastErrorInfoOld"},
154 {103, nullptr, "GetLastErrorInfo"},
155 {104, nullptr, "GetLastErrorEventHolder"},
156 {105, nullptr, "GetLastTransferTaskErrorInfo"},
157 {200, nullptr, "GetDataTransferPolicyInfo"},
158 {201, nullptr, "RemoveDataTransferPolicyInfo"},
159 {202, nullptr, "UpdateDataTransferPolicyOld"},
160 {203, nullptr, "UpdateDataTransferPolicy"},
161 {204, nullptr, "CleanupDataTransferPolicyInfo"},
162 {205, nullptr, "RequestDataTransferPolicy"},
163 {300, nullptr, "GetAutoTransferSeriesInfo"},
164 {301, nullptr, "UpdateAutoTransferSeriesInfo"},
165 {400, nullptr, "CleanupSaveDataArchiveInfoType1"},
166 {900, nullptr, "CleanupTransferTask"},
167 {902, nullptr, "CleanupSeriesInfoType0"},
168 {903, nullptr, "CleanupSaveDataArchiveInfoType0"},
169 {904, nullptr, "CleanupApplicationAutoTransferSetting"},
170 {905, nullptr, "CleanupErrorHistory"},
171 {906, nullptr, "SetLastError"},
172 {907, nullptr, "AddSaveDataArchiveInfoType0"},
173 {908, nullptr, "RemoveSeriesInfoType0"},
174 {909, nullptr, "GetSeriesInfoType0"},
175 {910, nullptr, "RemoveLastErrorInfo"},
176 {911, nullptr, "CleanupSeriesInfoType1"},
177 {912, nullptr, "RemoveSeriesInfoType1"},
178 {913, nullptr, "GetSeriesInfoType1"},
179 {1000, nullptr, "UpdateIssueOld"},
180 {1010, nullptr, "Unknown1010"},
181 {1011, nullptr, "ListIssueInfoOld"},
182 {1012, nullptr, "GetIssueOld"},
183 {1013, nullptr, "GetIssue2Old"},
184 {1014, nullptr, "GetIssue3Old"},
185 {1020, nullptr, "RepairIssueOld"},
186 {1021, nullptr, "RepairIssueWithUserIdOld"},
187 {1022, nullptr, "RepairIssue2Old"},
188 {1023, nullptr, "RepairIssue3Old"},
189 {1024, nullptr, "Unknown1024"},
190 {1100, nullptr, "UpdateIssue"},
191 {1110, nullptr, "Unknown1110"},
192 {1111, nullptr, "ListIssueInfo"},
193 {1112, nullptr, "GetIssue"},
194 {1113, nullptr, "GetIssue2"},
195 {1114, nullptr, "GetIssue3"},
196 {1120, nullptr, "RepairIssue"},
197 {1121, nullptr, "RepairIssueWithUserId"},
198 {1122, nullptr, "RepairIssue2"},
199 {1123, nullptr, "RepairIssue3"},
200 {1124, nullptr, "Unknown1124"},
201 };
202 // clang-format on
203
204 RegisterHandlers(functions);
205 }
206
207private:
208 void OpenTransferTaskListController(HLERequestContext& ctx) {
209 LOG_INFO(Service_OLSC, "called");
210
211 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
212 rb.Push(ResultSuccess);
213 rb.PushIpcInterface<ITransferTaskListController>(system);
214 }
215};
216
217void LoopProcess(Core::System& system) { 12void LoopProcess(Core::System& system) {
218 auto server_manager = std::make_unique<ServerManager>(system); 13 auto server_manager = std::make_unique<ServerManager>(system);
219 14
220 server_manager->RegisterNamedService("olsc:u", 15 const auto OlscFactoryForApplication = [&] {
221 std::make_shared<IOlscServiceForApplication>(system)); 16 return std::make_shared<IOlscServiceForApplication>(system);
222 server_manager->RegisterNamedService("olsc:s", 17 };
223 std::make_shared<IOlscServiceForSystemService>(system)); 18
19 const auto OlscFactoryForSystemService = [&] {
20 return std::make_shared<IOlscServiceForSystemService>(system);
21 };
22
23 server_manager->RegisterNamedService("olsc:u", OlscFactoryForApplication);
24 server_manager->RegisterNamedService("olsc:s", OlscFactoryForSystemService);
224 25
225 ServerManager::RunServer(std::move(server_manager)); 26 ServerManager::RunServer(std::move(server_manager));
226} 27}
diff --git a/src/core/hle/service/olsc/olsc_service_for_application.cpp b/src/core/hle/service/olsc/olsc_service_for_application.cpp
new file mode 100755
index 000000000..01360f5ef
--- /dev/null
+++ b/src/core/hle/service/olsc/olsc_service_for_application.cpp
@@ -0,0 +1,63 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/olsc/olsc_service_for_application.h"
6
7namespace Service::OLSC {
8
9IOlscServiceForApplication::IOlscServiceForApplication(Core::System& system_)
10 : ServiceFramework{system_, "olsc:u"} {
11 // clang-format off
12 static const FunctionInfo functions[] = {
13 {0, D<&IOlscServiceForApplication::Initialize>, "Initialize"},
14 {10, nullptr, "VerifySaveDataBackupLicenseAsync"},
15 {13, D<&IOlscServiceForApplication::GetSaveDataBackupSetting>, "GetSaveDataBackupSetting"},
16 {14, D<&IOlscServiceForApplication::SetSaveDataBackupSettingEnabled>, "SetSaveDataBackupSettingEnabled"},
17 {15, nullptr, "SetCustomData"},
18 {16, nullptr, "DeleteSaveDataBackupSetting"},
19 {18, nullptr, "GetSaveDataBackupInfoCache"},
20 {19, nullptr, "UpdateSaveDataBackupInfoCacheAsync"},
21 {22, nullptr, "DeleteSaveDataBackupAsync"},
22 {25, nullptr, "ListDownloadableSaveDataBackupInfoAsync"},
23 {26, nullptr, "DownloadSaveDataBackupAsync"},
24 {27, nullptr, "UploadSaveDataBackupAsync"},
25 {9010, nullptr, "VerifySaveDataBackupLicenseAsyncForDebug"},
26 {9013, nullptr, "GetSaveDataBackupSettingForDebug"},
27 {9014, nullptr, "SetSaveDataBackupSettingEnabledForDebug"},
28 {9015, nullptr, "SetCustomDataForDebug"},
29 {9016, nullptr, "DeleteSaveDataBackupSettingForDebug"},
30 {9018, nullptr, "GetSaveDataBackupInfoCacheForDebug"},
31 {9019, nullptr, "UpdateSaveDataBackupInfoCacheAsyncForDebug"},
32 {9022, nullptr, "DeleteSaveDataBackupAsyncForDebug"},
33 {9025, nullptr, "ListDownloadableSaveDataBackupInfoAsyncForDebug"},
34 {9026, nullptr, "DownloadSaveDataBackupAsyncForDebug"},
35 };
36 // clang-format on
37
38 RegisterHandlers(functions);
39}
40
41IOlscServiceForApplication::~IOlscServiceForApplication() = default;
42
43Result IOlscServiceForApplication::Initialize(ClientProcessId process_id) {
44 LOG_WARNING(Service_OLSC, "(STUBBED) called");
45 initialized = true;
46 R_SUCCEED();
47}
48
49Result IOlscServiceForApplication::GetSaveDataBackupSetting(Out<u8> out_save_data_backup_setting) {
50 LOG_WARNING(Service_OLSC, "(STUBBED) called");
51 // backup_setting is set to 0 since real value is unknown
52 *out_save_data_backup_setting = 0;
53 R_SUCCEED();
54}
55
56Result IOlscServiceForApplication::SetSaveDataBackupSettingEnabled(bool enabled,
57 NS::Uid account_id) {
58 LOG_WARNING(Service_OLSC, "(STUBBED) called, enabled={}, account_id={}", enabled,
59 account_id.uuid.FormattedString());
60 R_SUCCEED();
61}
62
63} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/olsc_service_for_application.h b/src/core/hle/service/olsc/olsc_service_for_application.h
new file mode 100755
index 000000000..3f9ac7536
--- /dev/null
+++ b/src/core/hle/service/olsc/olsc_service_for_application.h
@@ -0,0 +1,23 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_types.h"
5#include "core/hle/service/ns/ns_types.h"
6#include "core/hle/service/service.h"
7
8namespace Service::OLSC {
9
10class IOlscServiceForApplication final : public ServiceFramework<IOlscServiceForApplication> {
11public:
12 explicit IOlscServiceForApplication(Core::System& system_);
13 ~IOlscServiceForApplication() override;
14
15private:
16 Result Initialize(ClientProcessId process_id);
17 Result GetSaveDataBackupSetting(Out<u8> out_save_data_backup_setting);
18 Result SetSaveDataBackupSettingEnabled(bool enabled, NS::Uid account_id);
19
20 bool initialized{};
21};
22
23} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/olsc_service_for_system_service.cpp b/src/core/hle/service/olsc/olsc_service_for_system_service.cpp
new file mode 100755
index 000000000..f027933c9
--- /dev/null
+++ b/src/core/hle/service/olsc/olsc_service_for_system_service.cpp
@@ -0,0 +1,117 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/olsc/daemon_controller.h"
6#include "core/hle/service/olsc/olsc_service_for_system_service.h"
7#include "core/hle/service/olsc/remote_storage_controller.h"
8#include "core/hle/service/olsc/transfer_task_list_controller.h"
9
10namespace Service::OLSC {
11
12IOlscServiceForSystemService::IOlscServiceForSystemService(Core::System& system_)
13 : ServiceFramework{system_, "olsc:s"} {
14 // clang-format off
15 static const FunctionInfo functions[] = {
16 {0, D<&IOlscServiceForSystemService::OpenTransferTaskListController>, "OpenTransferTaskListController"},
17 {1, D<&IOlscServiceForSystemService::OpenRemoteStorageController>, "OpenRemoteStorageController"},
18 {2, D<&IOlscServiceForSystemService::OpenDaemonController>, "OpenDaemonController"},
19 {10, nullptr, "Unknown10"},
20 {11, nullptr, "Unknown11"},
21 {12, nullptr, "Unknown12"},
22 {13, nullptr, "Unknown13"},
23 {100, nullptr, "ListLastTransferTaskErrorInfo"},
24 {101, nullptr, "GetLastErrorInfoCount"},
25 {102, nullptr, "RemoveLastErrorInfoOld"},
26 {103, nullptr, "GetLastErrorInfo"},
27 {104, nullptr, "GetLastErrorEventHolder"},
28 {105, nullptr, "GetLastTransferTaskErrorInfo"},
29 {200, D<&IOlscServiceForSystemService::GetDataTransferPolicyInfo>, "GetDataTransferPolicyInfo"},
30 {201, nullptr, "RemoveDataTransferPolicyInfo"},
31 {202, nullptr, "UpdateDataTransferPolicyOld"},
32 {203, nullptr, "UpdateDataTransferPolicy"},
33 {204, nullptr, "CleanupDataTransferPolicyInfo"},
34 {205, nullptr, "RequestDataTransferPolicy"},
35 {300, nullptr, "GetAutoTransferSeriesInfo"},
36 {301, nullptr, "UpdateAutoTransferSeriesInfo"},
37 {400, nullptr, "CleanupSaveDataArchiveInfoType1"},
38 {900, nullptr, "CleanupTransferTask"},
39 {902, nullptr, "CleanupSeriesInfoType0"},
40 {903, nullptr, "CleanupSaveDataArchiveInfoType0"},
41 {904, nullptr, "CleanupApplicationAutoTransferSetting"},
42 {905, nullptr, "CleanupErrorHistory"},
43 {906, nullptr, "SetLastError"},
44 {907, nullptr, "AddSaveDataArchiveInfoType0"},
45 {908, nullptr, "RemoveSeriesInfoType0"},
46 {909, nullptr, "GetSeriesInfoType0"},
47 {910, nullptr, "RemoveLastErrorInfo"},
48 {911, nullptr, "CleanupSeriesInfoType1"},
49 {912, nullptr, "RemoveSeriesInfoType1"},
50 {913, nullptr, "GetSeriesInfoType1"},
51 {1000, nullptr, "UpdateIssueOld"},
52 {1010, nullptr, "Unknown1010"},
53 {1011, nullptr, "ListIssueInfoOld"},
54 {1012, nullptr, "GetIssueOld"},
55 {1013, nullptr, "GetIssue2Old"},
56 {1014, nullptr, "GetIssue3Old"},
57 {1020, nullptr, "RepairIssueOld"},
58 {1021, nullptr, "RepairIssueWithUserIdOld"},
59 {1022, nullptr, "RepairIssue2Old"},
60 {1023, nullptr, "RepairIssue3Old"},
61 {1024, nullptr, "Unknown1024"},
62 {1100, nullptr, "UpdateIssue"},
63 {1110, nullptr, "Unknown1110"},
64 {1111, nullptr, "ListIssueInfo"},
65 {1112, nullptr, "GetIssue"},
66 {1113, nullptr, "GetIssue2"},
67 {1114, nullptr, "GetIssue3"},
68 {1120, nullptr, "RepairIssue"},
69 {1121, nullptr, "RepairIssueWithUserId"},
70 {1122, nullptr, "RepairIssue2"},
71 {1123, nullptr, "RepairIssue3"},
72 {1124, nullptr, "Unknown1124"},
73 {10000, D<&IOlscServiceForSystemService::CloneService>, "CloneService"},
74 };
75 // clang-format on
76
77 RegisterHandlers(functions);
78}
79
80IOlscServiceForSystemService::~IOlscServiceForSystemService() = default;
81
82Result IOlscServiceForSystemService::OpenTransferTaskListController(
83 Out<SharedPointer<ITransferTaskListController>> out_interface) {
84 LOG_INFO(Service_OLSC, "called");
85 *out_interface = std::make_shared<ITransferTaskListController>(system);
86 R_SUCCEED();
87}
88
89Result IOlscServiceForSystemService::OpenRemoteStorageController(
90 Out<SharedPointer<IRemoteStorageController>> out_interface) {
91 LOG_INFO(Service_OLSC, "called");
92 *out_interface = std::make_shared<IRemoteStorageController>(system);
93 R_SUCCEED();
94}
95
96Result IOlscServiceForSystemService::OpenDaemonController(
97 Out<SharedPointer<IDaemonController>> out_interface) {
98 LOG_INFO(Service_OLSC, "called");
99 *out_interface = std::make_shared<IDaemonController>(system);
100 R_SUCCEED();
101}
102
103Result IOlscServiceForSystemService::GetDataTransferPolicyInfo(Out<u16> out_policy_info,
104 u64 application_id) {
105 LOG_WARNING(Service_OLSC, "(STUBBED) called");
106 *out_policy_info = 0;
107 R_SUCCEED();
108}
109
110Result IOlscServiceForSystemService::CloneService(
111 Out<SharedPointer<IOlscServiceForSystemService>> out_interface) {
112 LOG_INFO(Service_OLSC, "called");
113 *out_interface = std::static_pointer_cast<IOlscServiceForSystemService>(shared_from_this());
114 R_SUCCEED();
115}
116
117} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/olsc_service_for_system_service.h b/src/core/hle/service/olsc/olsc_service_for_system_service.h
new file mode 100755
index 000000000..13026272a
--- /dev/null
+++ b/src/core/hle/service/olsc/olsc_service_for_system_service.h
@@ -0,0 +1,27 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_types.h"
5#include "core/hle/service/service.h"
6
7namespace Service::OLSC {
8
9class IDaemonController;
10class IRemoteStorageController;
11class ITransferTaskListController;
12
13class IOlscServiceForSystemService final : public ServiceFramework<IOlscServiceForSystemService> {
14public:
15 explicit IOlscServiceForSystemService(Core::System& system_);
16 ~IOlscServiceForSystemService() override;
17
18private:
19 Result OpenTransferTaskListController(
20 Out<SharedPointer<ITransferTaskListController>> out_interface);
21 Result OpenRemoteStorageController(Out<SharedPointer<IRemoteStorageController>> out_interface);
22 Result OpenDaemonController(Out<SharedPointer<IDaemonController>> out_interface);
23 Result GetDataTransferPolicyInfo(Out<u16> out_policy_info, u64 application_id);
24 Result CloneService(Out<SharedPointer<IOlscServiceForSystemService>> out_interface);
25};
26
27} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/remote_storage_controller.cpp b/src/core/hle/service/olsc/remote_storage_controller.cpp
new file mode 100755
index 000000000..81d9c96ab
--- /dev/null
+++ b/src/core/hle/service/olsc/remote_storage_controller.cpp
@@ -0,0 +1,54 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/olsc/remote_storage_controller.h"
6
7namespace Service::OLSC {
8
9IRemoteStorageController::IRemoteStorageController(Core::System& system_)
10 : ServiceFramework{system_, "IRemoteStorageController"} {
11 // clang-format off
12 static const FunctionInfo functions[] = {
13 {0, nullptr, "GetSaveDataArchiveInfoBySaveDataId"},
14 {1, nullptr, "GetSaveDataArchiveInfoByApplicationId"},
15 {3, nullptr, "GetSaveDataArchiveCount"},
16 {6, nullptr, "CleanupSaveDataArchives"},
17 {7, nullptr, "CreateSaveDataArchiveCacheUpdationTask"},
18 {8, nullptr, "CreateSaveDataArchiveCacheUpdationForSpecifiedApplicationTask"},
19 {9, nullptr, "Delete"},
20 {10, nullptr, "GetSeriesInfo"},
21 {11, nullptr, "CreateDeleteDataTask"},
22 {12, nullptr, "DeleteSeriesInfo"},
23 {13, nullptr, "CreateRegisterNotificationTokenTask"},
24 {14, nullptr, "UpdateSeriesInfo"},
25 {15, nullptr, "RegisterUploadSaveDataTransferTaskForAutonomyRegistration"},
26 {16, nullptr, "CreateCleanupToDeleteSaveDataArchiveInfoTask"},
27 {17, nullptr, "ListDataInfo"},
28 {18, nullptr, "GetDataInfo"},
29 {19, nullptr, "Unknown19"},
30 {20, nullptr, "CreateSaveDataArchiveInfoCacheForSaveDataBackupUpdationTask"},
31 {21, nullptr, "ListSecondarySaves"},
32 {22, D<&IRemoteStorageController::GetSecondarySave>, "GetSecondarySave"},
33 {23, nullptr, "TouchSecondarySave"},
34 {24, nullptr, "GetSecondarySaveDataInfo"},
35 {25, nullptr, "RegisterDownloadSaveDataTransferTaskForAutonomyRegistration"},
36 {900, nullptr, "Unknown900"},
37 };
38 // clang-format on
39
40 RegisterHandlers(functions);
41}
42
43IRemoteStorageController::~IRemoteStorageController() = default;
44
45Result IRemoteStorageController::GetSecondarySave(Out<bool> out_has_secondary_save,
46 Out<std::array<u64, 3>> out_unknown,
47 u64 application_id) {
48 LOG_ERROR(Service_OLSC, "(STUBBED) called, application_id={:016X}", application_id);
49 *out_has_secondary_save = false;
50 *out_unknown = {};
51 R_SUCCEED();
52}
53
54} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/remote_storage_controller.h b/src/core/hle/service/olsc/remote_storage_controller.h
new file mode 100755
index 000000000..e7a0b5244
--- /dev/null
+++ b/src/core/hle/service/olsc/remote_storage_controller.h
@@ -0,0 +1,19 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_types.h"
5#include "core/hle/service/service.h"
6
7namespace Service::OLSC {
8
9class IRemoteStorageController final : public ServiceFramework<IRemoteStorageController> {
10public:
11 explicit IRemoteStorageController(Core::System& system_);
12 ~IRemoteStorageController() override;
13
14private:
15 Result GetSecondarySave(Out<bool> out_has_secondary_save, Out<std::array<u64, 3>> out_unknown,
16 u64 application_id);
17};
18
19} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/transfer_task_list_controller.cpp b/src/core/hle/service/olsc/transfer_task_list_controller.cpp
new file mode 100755
index 000000000..8ea9a0f1e
--- /dev/null
+++ b/src/core/hle/service/olsc/transfer_task_list_controller.cpp
@@ -0,0 +1,55 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/olsc/native_handle_holder.h"
6#include "core/hle/service/olsc/transfer_task_list_controller.h"
7
8namespace Service::OLSC {
9
10ITransferTaskListController::ITransferTaskListController(Core::System& system_)
11 : ServiceFramework{system_, "ITransferTaskListController"} {
12 // clang-format off
13 static const FunctionInfo functions[] = {
14 {0, nullptr, "Unknown0"},
15 {1, nullptr, "Unknown1"},
16 {2, nullptr, "Unknown2"},
17 {3, nullptr, "Unknown3"},
18 {4, nullptr, "Unknown4"},
19 {5, D<&ITransferTaskListController::GetNativeHandleHolder>, "GetNativeHandleHolder"},
20 {6, nullptr, "Unknown6"},
21 {7, nullptr, "Unknown7"},
22 {8, nullptr, "GetRemoteStorageController"},
23 {9, D<&ITransferTaskListController::GetNativeHandleHolder>, "GetNativeHandleHolder2"},
24 {10, nullptr, "Unknown10"},
25 {11, nullptr, "Unknown11"},
26 {12, nullptr, "Unknown12"},
27 {13, nullptr, "Unknown13"},
28 {14, nullptr, "Unknown14"},
29 {15, nullptr, "Unknown15"},
30 {16, nullptr, "Unknown16"},
31 {17, nullptr, "Unknown17"},
32 {18, nullptr, "Unknown18"},
33 {19, nullptr, "Unknown19"},
34 {20, nullptr, "Unknown20"},
35 {21, nullptr, "Unknown21"},
36 {22, nullptr, "Unknown22"},
37 {23, nullptr, "Unknown23"},
38 {24, nullptr, "Unknown24"},
39 {25, nullptr, "Unknown25"},
40 };
41 // clang-format on
42
43 RegisterHandlers(functions);
44}
45
46ITransferTaskListController::~ITransferTaskListController() = default;
47
48Result ITransferTaskListController::GetNativeHandleHolder(
49 Out<SharedPointer<INativeHandleHolder>> out_holder) {
50 LOG_WARNING(Service_OLSC, "(STUBBED) called");
51 *out_holder = std::make_shared<INativeHandleHolder>(system);
52 R_SUCCEED();
53}
54
55} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/transfer_task_list_controller.h b/src/core/hle/service/olsc/transfer_task_list_controller.h
new file mode 100755
index 000000000..f10a71375
--- /dev/null
+++ b/src/core/hle/service/olsc/transfer_task_list_controller.h
@@ -0,0 +1,20 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_types.h"
5#include "core/hle/service/service.h"
6
7namespace Service::OLSC {
8
9class INativeHandleHolder;
10
11class ITransferTaskListController final : public ServiceFramework<ITransferTaskListController> {
12public:
13 explicit ITransferTaskListController(Core::System& system_);
14 ~ITransferTaskListController() override;
15
16private:
17 Result GetNativeHandleHolder(Out<SharedPointer<INativeHandleHolder>> out_holder);
18};
19
20} // namespace Service::OLSC
diff --git a/src/core/hle/service/pctl/parental_control_service.cpp b/src/core/hle/service/pctl/parental_control_service.cpp
new file mode 100755
index 000000000..f57f2f157
--- /dev/null
+++ b/src/core/hle/service/pctl/parental_control_service.cpp
@@ -0,0 +1,434 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/core.h"
5#include "core/file_sys/control_metadata.h"
6#include "core/file_sys/patch_manager.h"
7#include "core/hle/service/cmif_serialization.h"
8#include "core/hle/service/pctl/parental_control_service.h"
9#include "core/hle/service/pctl/pctl_results.h"
10
11namespace Service::PCTL {
12
13IParentalControlService::IParentalControlService(Core::System& system_, Capability capability_)
14 : ServiceFramework{system_, "IParentalControlService"}, capability{capability_},
15 service_context{system_, "IParentalControlService"}, synchronization_event{service_context},
16 unlinked_event{service_context}, request_suspension_event{service_context} {
17 // clang-format off
18 static const FunctionInfo functions[] = {
19 {1, D<&IParentalControlService::Initialize>, "Initialize"},
20 {1001, D<&IParentalControlService::CheckFreeCommunicationPermission>, "CheckFreeCommunicationPermission"},
21 {1002, D<&IParentalControlService::ConfirmLaunchApplicationPermission>, "ConfirmLaunchApplicationPermission"},
22 {1003, D<&IParentalControlService::ConfirmResumeApplicationPermission>, "ConfirmResumeApplicationPermission"},
23 {1004, D<&IParentalControlService::ConfirmSnsPostPermission>, "ConfirmSnsPostPermission"},
24 {1005, nullptr, "ConfirmSystemSettingsPermission"},
25 {1006, D<&IParentalControlService::IsRestrictionTemporaryUnlocked>, "IsRestrictionTemporaryUnlocked"},
26 {1007, nullptr, "RevertRestrictionTemporaryUnlocked"},
27 {1008, nullptr, "EnterRestrictedSystemSettings"},
28 {1009, nullptr, "LeaveRestrictedSystemSettings"},
29 {1010, D<&IParentalControlService::IsRestrictedSystemSettingsEntered>, "IsRestrictedSystemSettingsEntered"},
30 {1011, nullptr, "RevertRestrictedSystemSettingsEntered"},
31 {1012, nullptr, "GetRestrictedFeatures"},
32 {1013, D<&IParentalControlService::ConfirmStereoVisionPermission>, "ConfirmStereoVisionPermission"},
33 {1014, nullptr, "ConfirmPlayableApplicationVideoOld"},
34 {1015, nullptr, "ConfirmPlayableApplicationVideo"},
35 {1016, nullptr, "ConfirmShowNewsPermission"},
36 {1017, D<&IParentalControlService::EndFreeCommunication>, "EndFreeCommunication"},
37 {1018, D<&IParentalControlService::IsFreeCommunicationAvailable>, "IsFreeCommunicationAvailable"},
38 {1031, D<&IParentalControlService::IsRestrictionEnabled>, "IsRestrictionEnabled"},
39 {1032, D<&IParentalControlService::GetSafetyLevel>, "GetSafetyLevel"},
40 {1033, nullptr, "SetSafetyLevel"},
41 {1034, nullptr, "GetSafetyLevelSettings"},
42 {1035, D<&IParentalControlService::GetCurrentSettings>, "GetCurrentSettings"},
43 {1036, nullptr, "SetCustomSafetyLevelSettings"},
44 {1037, nullptr, "GetDefaultRatingOrganization"},
45 {1038, nullptr, "SetDefaultRatingOrganization"},
46 {1039, D<&IParentalControlService::GetFreeCommunicationApplicationListCount>, "GetFreeCommunicationApplicationListCount"},
47 {1042, nullptr, "AddToFreeCommunicationApplicationList"},
48 {1043, nullptr, "DeleteSettings"},
49 {1044, nullptr, "GetFreeCommunicationApplicationList"},
50 {1045, nullptr, "UpdateFreeCommunicationApplicationList"},
51 {1046, nullptr, "DisableFeaturesForReset"},
52 {1047, nullptr, "NotifyApplicationDownloadStarted"},
53 {1048, nullptr, "NotifyNetworkProfileCreated"},
54 {1049, nullptr, "ResetFreeCommunicationApplicationList"},
55 {1061, D<&IParentalControlService::ConfirmStereoVisionRestrictionConfigurable>, "ConfirmStereoVisionRestrictionConfigurable"},
56 {1062, D<&IParentalControlService::GetStereoVisionRestriction>, "GetStereoVisionRestriction"},
57 {1063, D<&IParentalControlService::SetStereoVisionRestriction>, "SetStereoVisionRestriction"},
58 {1064, D<&IParentalControlService::ResetConfirmedStereoVisionPermission>, "ResetConfirmedStereoVisionPermission"},
59 {1065, D<&IParentalControlService::IsStereoVisionPermitted>, "IsStereoVisionPermitted"},
60 {1201, nullptr, "UnlockRestrictionTemporarily"},
61 {1202, nullptr, "UnlockSystemSettingsRestriction"},
62 {1203, nullptr, "SetPinCode"},
63 {1204, nullptr, "GenerateInquiryCode"},
64 {1205, nullptr, "CheckMasterKey"},
65 {1206, D<&IParentalControlService::GetPinCodeLength>, "GetPinCodeLength"},
66 {1207, nullptr, "GetPinCodeChangedEvent"},
67 {1208, nullptr, "GetPinCode"},
68 {1403, D<&IParentalControlService::IsPairingActive>, "IsPairingActive"},
69 {1406, nullptr, "GetSettingsLastUpdated"},
70 {1411, nullptr, "GetPairingAccountInfo"},
71 {1421, nullptr, "GetAccountNickname"},
72 {1424, nullptr, "GetAccountState"},
73 {1425, nullptr, "RequestPostEvents"},
74 {1426, nullptr, "GetPostEventInterval"},
75 {1427, nullptr, "SetPostEventInterval"},
76 {1432, D<&IParentalControlService::GetSynchronizationEvent>, "GetSynchronizationEvent"},
77 {1451, D<&IParentalControlService::StartPlayTimer>, "StartPlayTimer"},
78 {1452, D<&IParentalControlService::StopPlayTimer>, "StopPlayTimer"},
79 {1453, D<&IParentalControlService::IsPlayTimerEnabled>, "IsPlayTimerEnabled"},
80 {1454, nullptr, "GetPlayTimerRemainingTime"},
81 {1455, D<&IParentalControlService::IsRestrictedByPlayTimer>, "IsRestrictedByPlayTimer"},
82 {1456, D<&IParentalControlService::GetPlayTimerSettings>, "GetPlayTimerSettings"},
83 {1457, D<&IParentalControlService::GetPlayTimerEventToRequestSuspension>, "GetPlayTimerEventToRequestSuspension"},
84 {1458, D<&IParentalControlService::IsPlayTimerAlarmDisabled>, "IsPlayTimerAlarmDisabled"},
85 {1471, nullptr, "NotifyWrongPinCodeInputManyTimes"},
86 {1472, nullptr, "CancelNetworkRequest"},
87 {1473, D<&IParentalControlService::GetUnlinkedEvent>, "GetUnlinkedEvent"},
88 {1474, nullptr, "ClearUnlinkedEvent"},
89 {1601, nullptr, "DisableAllFeatures"},
90 {1602, nullptr, "PostEnableAllFeatures"},
91 {1603, nullptr, "IsAllFeaturesDisabled"},
92 {1901, nullptr, "DeleteFromFreeCommunicationApplicationListForDebug"},
93 {1902, nullptr, "ClearFreeCommunicationApplicationListForDebug"},
94 {1903, nullptr, "GetExemptApplicationListCountForDebug"},
95 {1904, nullptr, "GetExemptApplicationListForDebug"},
96 {1905, nullptr, "UpdateExemptApplicationListForDebug"},
97 {1906, nullptr, "AddToExemptApplicationListForDebug"},
98 {1907, nullptr, "DeleteFromExemptApplicationListForDebug"},
99 {1908, nullptr, "ClearExemptApplicationListForDebug"},
100 {1941, nullptr, "DeletePairing"},
101 {1951, nullptr, "SetPlayTimerSettingsForDebug"},
102 {1952, nullptr, "GetPlayTimerSpentTimeForTest"},
103 {1953, nullptr, "SetPlayTimerAlarmDisabledForDebug"},
104 {2001, nullptr, "RequestPairingAsync"},
105 {2002, nullptr, "FinishRequestPairing"},
106 {2003, nullptr, "AuthorizePairingAsync"},
107 {2004, nullptr, "FinishAuthorizePairing"},
108 {2005, nullptr, "RetrievePairingInfoAsync"},
109 {2006, nullptr, "FinishRetrievePairingInfo"},
110 {2007, nullptr, "UnlinkPairingAsync"},
111 {2008, nullptr, "FinishUnlinkPairing"},
112 {2009, nullptr, "GetAccountMiiImageAsync"},
113 {2010, nullptr, "FinishGetAccountMiiImage"},
114 {2011, nullptr, "GetAccountMiiImageContentTypeAsync"},
115 {2012, nullptr, "FinishGetAccountMiiImageContentType"},
116 {2013, nullptr, "SynchronizeParentalControlSettingsAsync"},
117 {2014, nullptr, "FinishSynchronizeParentalControlSettings"},
118 {2015, nullptr, "FinishSynchronizeParentalControlSettingsWithLastUpdated"},
119 {2016, nullptr, "RequestUpdateExemptionListAsync"},
120 };
121 // clang-format on
122 RegisterHandlers(functions);
123}
124
125IParentalControlService::~IParentalControlService() = default;
126
127bool IParentalControlService::CheckFreeCommunicationPermissionImpl() const {
128 if (states.temporary_unlocked) {
129 return true;
130 }
131 if ((states.application_info.parental_control_flag & 1) == 0) {
132 return true;
133 }
134 if (pin_code[0] == '\0') {
135 return true;
136 }
137 if (!settings.is_free_communication_default_on) {
138 return true;
139 }
140 // TODO(ogniK): Check for blacklisted/exempted applications. Return false can happen here
141 // but as we don't have multiproceses support yet, we can just assume our application is
142 // valid for the time being
143 return true;
144}
145
146bool IParentalControlService::ConfirmStereoVisionPermissionImpl() const {
147 if (states.temporary_unlocked) {
148 return true;
149 }
150 if (pin_code[0] == '\0') {
151 return true;
152 }
153 if (!settings.is_stero_vision_restricted) {
154 return false;
155 }
156 return true;
157}
158
159void IParentalControlService::SetStereoVisionRestrictionImpl(bool is_restricted) {
160 if (settings.disabled) {
161 return;
162 }
163
164 if (pin_code[0] == '\0') {
165 return;
166 }
167 settings.is_stero_vision_restricted = is_restricted;
168}
169
170Result IParentalControlService::Initialize() {
171 LOG_DEBUG(Service_PCTL, "called");
172
173 if (False(capability & (Capability::Application | Capability::System))) {
174 LOG_ERROR(Service_PCTL, "Invalid capability! capability={:X}", capability);
175 R_THROW(PCTL::ResultNoCapability);
176 }
177
178 // TODO(ogniK): Recovery flag initialization for pctl:r
179
180 const auto program_id = system.GetApplicationProcessProgramID();
181 if (program_id != 0) {
182 const FileSys::PatchManager pm{program_id, system.GetFileSystemController(),
183 system.GetContentProvider()};
184 const auto control = pm.GetControlMetadata();
185 if (control.first) {
186 states.tid_from_event = 0;
187 states.launch_time_valid = false;
188 states.is_suspended = false;
189 states.free_communication = false;
190 states.stereo_vision = false;
191 states.application_info = ApplicationInfo{
192 .application_id = program_id,
193 .age_rating = control.first->GetRatingAge(),
194 .parental_control_flag = control.first->GetParentalControlFlag(),
195 .capability = capability,
196 };
197
198 if (False(capability & (Capability::System | Capability::Recovery))) {
199 // TODO(ogniK): Signal application launch event
200 }
201 }
202 }
203
204 R_SUCCEED();
205}
206
207Result IParentalControlService::CheckFreeCommunicationPermission() {
208 LOG_DEBUG(Service_PCTL, "called");
209
210 if (!CheckFreeCommunicationPermissionImpl()) {
211 R_THROW(PCTL::ResultNoFreeCommunication);
212 } else {
213 states.free_communication = true;
214 R_SUCCEED();
215 }
216}
217
218Result IParentalControlService::ConfirmLaunchApplicationPermission(
219 InBuffer<BufferAttr_HipcPointer> restriction_bitset, u64 nacp_flag, u64 application_id) {
220 LOG_WARNING(Service_PCTL, "(STUBBED) called, nacp_flag={:#x} application_id={:016X}", nacp_flag,
221 application_id);
222 R_SUCCEED();
223}
224
225Result IParentalControlService::ConfirmResumeApplicationPermission(
226 InBuffer<BufferAttr_HipcPointer> restriction_bitset, u64 nacp_flag, u64 application_id) {
227 LOG_WARNING(Service_PCTL, "(STUBBED) called, nacp_flag={:#x} application_id={:016X}", nacp_flag,
228 application_id);
229 R_SUCCEED();
230}
231
232Result IParentalControlService::ConfirmSnsPostPermission() {
233 LOG_WARNING(Service_PCTL, "(STUBBED) called");
234 R_THROW(PCTL::ResultNoFreeCommunication);
235}
236
237Result IParentalControlService::IsRestrictionTemporaryUnlocked(
238 Out<bool> out_is_temporary_unlocked) {
239 *out_is_temporary_unlocked = false;
240 LOG_WARNING(Service_PCTL, "(STUBBED) called, is_temporary_unlocked={}",
241 *out_is_temporary_unlocked);
242 R_SUCCEED();
243}
244
245Result IParentalControlService::IsRestrictedSystemSettingsEntered(
246 Out<bool> out_is_restricted_system_settings_entered) {
247 *out_is_restricted_system_settings_entered = false;
248 LOG_WARNING(Service_PCTL, "(STUBBED) called, is_temporary_unlocked={}",
249 *out_is_restricted_system_settings_entered);
250 R_SUCCEED();
251}
252
253Result IParentalControlService::ConfirmStereoVisionPermission() {
254 LOG_DEBUG(Service_PCTL, "called");
255 states.stereo_vision = true;
256 R_SUCCEED();
257}
258
259Result IParentalControlService::EndFreeCommunication() {
260 LOG_WARNING(Service_PCTL, "(STUBBED) called");
261 R_SUCCEED();
262}
263
264Result IParentalControlService::IsFreeCommunicationAvailable() {
265 LOG_WARNING(Service_PCTL, "(STUBBED) called");
266
267 if (!CheckFreeCommunicationPermissionImpl()) {
268 R_THROW(PCTL::ResultNoFreeCommunication);
269 } else {
270 R_SUCCEED();
271 }
272}
273
274Result IParentalControlService::IsRestrictionEnabled(Out<bool> out_restriction_enabled) {
275 LOG_DEBUG(Service_PCTL, "called");
276
277 if (False(capability & (Capability::Status | Capability::Recovery))) {
278 LOG_ERROR(Service_PCTL, "Application does not have Status or Recovery capabilities!");
279 *out_restriction_enabled = false;
280 R_THROW(PCTL::ResultNoCapability);
281 }
282
283 *out_restriction_enabled = pin_code[0] != '\0';
284 R_SUCCEED();
285}
286
287Result IParentalControlService::GetSafetyLevel(Out<u32> out_safety_level) {
288 *out_safety_level = 0;
289 LOG_WARNING(Service_PCTL, "(STUBBED) called, safety_level={}", *out_safety_level);
290 R_SUCCEED();
291}
292
293Result IParentalControlService::GetCurrentSettings(Out<RestrictionSettings> out_settings) {
294 LOG_INFO(Service_PCTL, "called");
295 *out_settings = restriction_settings;
296 R_SUCCEED();
297}
298
299Result IParentalControlService::GetFreeCommunicationApplicationListCount(Out<s32> out_count) {
300 *out_count = 4;
301 LOG_WARNING(Service_PCTL, "(STUBBED) called, count={}", *out_count);
302 R_SUCCEED();
303}
304
305Result IParentalControlService::ConfirmStereoVisionRestrictionConfigurable() {
306 LOG_DEBUG(Service_PCTL, "called");
307
308 if (False(capability & Capability::StereoVision)) {
309 LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!");
310 R_THROW(PCTL::ResultNoCapability);
311 }
312
313 if (pin_code[0] == '\0') {
314 R_THROW(PCTL::ResultNoRestrictionEnabled);
315 }
316
317 R_SUCCEED();
318}
319
320Result IParentalControlService::IsStereoVisionPermitted(Out<bool> out_is_permitted) {
321 LOG_DEBUG(Service_PCTL, "called");
322
323 if (!ConfirmStereoVisionPermissionImpl()) {
324 *out_is_permitted = false;
325 R_THROW(PCTL::ResultStereoVisionRestricted);
326 } else {
327 *out_is_permitted = true;
328 R_SUCCEED();
329 }
330}
331
332Result IParentalControlService::GetPinCodeLength(Out<s32> out_length) {
333 *out_length = 0;
334 LOG_WARNING(Service_PCTL, "(STUBBED) called, length={}", *out_length);
335 R_SUCCEED();
336}
337
338Result IParentalControlService::IsPairingActive(Out<bool> out_is_pairing_active) {
339 *out_is_pairing_active = false;
340 LOG_WARNING(Service_PCTL, "(STUBBED) called, is_pairing_active={}", *out_is_pairing_active);
341 R_SUCCEED();
342}
343
344Result IParentalControlService::GetSynchronizationEvent(
345 OutCopyHandle<Kernel::KReadableEvent> out_event) {
346 LOG_INFO(Service_PCTL, "called");
347 *out_event = synchronization_event.GetHandle();
348 R_SUCCEED();
349}
350
351Result IParentalControlService::StartPlayTimer() {
352 LOG_WARNING(Service_PCTL, "(STUBBED) called");
353 R_SUCCEED();
354}
355
356Result IParentalControlService::StopPlayTimer() {
357 LOG_WARNING(Service_PCTL, "(STUBBED) called");
358 R_SUCCEED();
359}
360
361Result IParentalControlService::IsPlayTimerEnabled(Out<bool> out_is_play_timer_enabled) {
362 *out_is_play_timer_enabled = false;
363 LOG_WARNING(Service_PCTL, "(STUBBED) called, enabled={}", *out_is_play_timer_enabled);
364 R_SUCCEED();
365}
366
367Result IParentalControlService::IsRestrictedByPlayTimer(Out<bool> out_is_restricted_by_play_timer) {
368 *out_is_restricted_by_play_timer = false;
369 LOG_WARNING(Service_PCTL, "(STUBBED) called, restricted={}", *out_is_restricted_by_play_timer);
370 R_SUCCEED();
371}
372
373Result IParentalControlService::GetPlayTimerSettings(
374 Out<PlayTimerSettings> out_play_timer_settings) {
375 LOG_WARNING(Service_PCTL, "(STUBBED) called");
376 *out_play_timer_settings = {};
377 R_SUCCEED();
378}
379
380Result IParentalControlService::GetPlayTimerEventToRequestSuspension(
381 OutCopyHandle<Kernel::KReadableEvent> out_event) {
382 LOG_INFO(Service_PCTL, "called");
383 *out_event = request_suspension_event.GetHandle();
384 R_SUCCEED();
385}
386
387Result IParentalControlService::IsPlayTimerAlarmDisabled(Out<bool> out_play_timer_alarm_disabled) {
388 *out_play_timer_alarm_disabled = false;
389 LOG_INFO(Service_PCTL, "called, is_play_timer_alarm_disabled={}",
390 *out_play_timer_alarm_disabled);
391 R_SUCCEED();
392}
393
394Result IParentalControlService::GetUnlinkedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
395 LOG_INFO(Service_PCTL, "called");
396 *out_event = unlinked_event.GetHandle();
397 R_SUCCEED();
398}
399
400Result IParentalControlService::GetStereoVisionRestriction(
401 Out<bool> out_stereo_vision_restriction) {
402 LOG_DEBUG(Service_PCTL, "called");
403
404 if (False(capability & Capability::StereoVision)) {
405 LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!");
406 *out_stereo_vision_restriction = false;
407 R_THROW(PCTL::ResultNoCapability);
408 }
409
410 *out_stereo_vision_restriction = settings.is_stero_vision_restricted;
411 R_SUCCEED();
412}
413
414Result IParentalControlService::SetStereoVisionRestriction(bool stereo_vision_restriction) {
415 LOG_DEBUG(Service_PCTL, "called, can_use={}", stereo_vision_restriction);
416
417 if (False(capability & Capability::StereoVision)) {
418 LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!");
419 R_THROW(PCTL::ResultNoCapability);
420 }
421
422 SetStereoVisionRestrictionImpl(stereo_vision_restriction);
423 R_SUCCEED();
424}
425
426Result IParentalControlService::ResetConfirmedStereoVisionPermission() {
427 LOG_DEBUG(Service_PCTL, "called");
428
429 states.stereo_vision = false;
430
431 R_SUCCEED();
432}
433
434} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/parental_control_service.h b/src/core/hle/service/pctl/parental_control_service.h
new file mode 100755
index 000000000..03dbaa2e5
--- /dev/null
+++ b/src/core/hle/service/pctl/parental_control_service.h
@@ -0,0 +1,86 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/cmif_types.h"
7#include "core/hle/service/kernel_helpers.h"
8#include "core/hle/service/os/event.h"
9#include "core/hle/service/pctl/pctl_types.h"
10#include "core/hle/service/service.h"
11
12namespace Service::PCTL {
13
14class IParentalControlService final : public ServiceFramework<IParentalControlService> {
15public:
16 explicit IParentalControlService(Core::System& system_, Capability capability_);
17 ~IParentalControlService() override;
18
19private:
20 bool CheckFreeCommunicationPermissionImpl() const;
21 bool ConfirmStereoVisionPermissionImpl() const;
22 void SetStereoVisionRestrictionImpl(bool is_restricted);
23
24 Result Initialize();
25 Result CheckFreeCommunicationPermission();
26 Result ConfirmLaunchApplicationPermission(InBuffer<BufferAttr_HipcPointer> restriction_bitset,
27 u64 nacp_flag, u64 application_id);
28 Result ConfirmResumeApplicationPermission(InBuffer<BufferAttr_HipcPointer> restriction_bitset,
29 u64 nacp_flag, u64 application_id);
30 Result ConfirmSnsPostPermission();
31 Result IsRestrictionTemporaryUnlocked(Out<bool> out_is_temporary_unlocked);
32 Result IsRestrictedSystemSettingsEntered(Out<bool> out_is_restricted_system_settings_entered);
33 Result ConfirmStereoVisionPermission();
34 Result EndFreeCommunication();
35 Result IsFreeCommunicationAvailable();
36 Result IsRestrictionEnabled(Out<bool> out_restriction_enabled);
37 Result GetSafetyLevel(Out<u32> out_safety_level);
38 Result GetCurrentSettings(Out<RestrictionSettings> out_settings);
39 Result GetFreeCommunicationApplicationListCount(Out<s32> out_count);
40 Result ConfirmStereoVisionRestrictionConfigurable();
41 Result IsStereoVisionPermitted(Out<bool> out_is_permitted);
42 Result GetPinCodeLength(Out<s32> out_length);
43 Result IsPairingActive(Out<bool> out_is_pairing_active);
44 Result GetSynchronizationEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
45 Result StartPlayTimer();
46 Result StopPlayTimer();
47 Result IsPlayTimerEnabled(Out<bool> out_is_play_timer_enabled);
48 Result IsRestrictedByPlayTimer(Out<bool> out_is_restricted_by_play_timer);
49 Result GetPlayTimerSettings(Out<PlayTimerSettings> out_play_timer_settings);
50 Result GetPlayTimerEventToRequestSuspension(OutCopyHandle<Kernel::KReadableEvent> out_event);
51 Result IsPlayTimerAlarmDisabled(Out<bool> out_play_timer_alarm_disabled);
52 Result GetUnlinkedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
53 Result GetStereoVisionRestriction(Out<bool> out_stereo_vision_restriction);
54 Result SetStereoVisionRestriction(bool stereo_vision_restriction);
55 Result ResetConfirmedStereoVisionPermission();
56
57 struct States {
58 u64 current_tid{};
59 ApplicationInfo application_info{};
60 u64 tid_from_event{};
61 bool launch_time_valid{};
62 bool is_suspended{};
63 bool temporary_unlocked{};
64 bool free_communication{};
65 bool stereo_vision{};
66 };
67
68 struct ParentalControlSettings {
69 bool is_stero_vision_restricted{};
70 bool is_free_communication_default_on{};
71 bool disabled{};
72 };
73
74 States states{};
75 ParentalControlSettings settings{};
76 RestrictionSettings restriction_settings{};
77 std::array<char, 8> pin_code{};
78 Capability capability{};
79
80 KernelHelpers::ServiceContext service_context;
81 Event synchronization_event;
82 Event unlinked_event;
83 Event request_suspension_event;
84};
85
86} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/parental_control_service_factory.cpp b/src/core/hle/service/pctl/parental_control_service_factory.cpp
new file mode 100755
index 000000000..7d8f361e9
--- /dev/null
+++ b/src/core/hle/service/pctl/parental_control_service_factory.cpp
@@ -0,0 +1,40 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/pctl/parental_control_service.h"
6#include "core/hle/service/pctl/parental_control_service_factory.h"
7
8namespace Service::PCTL {
9
10IParentalControlServiceFactory::IParentalControlServiceFactory(Core::System& system_,
11 const char* name_,
12 Capability capability_)
13 : ServiceFramework{system_, name_}, capability{capability_} {
14 static const FunctionInfo functions[] = {
15 {0, D<&IParentalControlServiceFactory::CreateService>, "CreateService"},
16 {1, D<&IParentalControlServiceFactory::CreateServiceWithoutInitialize>,
17 "CreateServiceWithoutInitialize"},
18 };
19 RegisterHandlers(functions);
20}
21
22IParentalControlServiceFactory::~IParentalControlServiceFactory() = default;
23
24Result IParentalControlServiceFactory::CreateService(
25 Out<SharedPointer<IParentalControlService>> out_service, ClientProcessId process_id) {
26 LOG_DEBUG(Service_PCTL, "called");
27 // TODO(ogniK): Get application id from process
28 *out_service = std::make_shared<IParentalControlService>(system, capability);
29 R_SUCCEED();
30}
31
32Result IParentalControlServiceFactory::CreateServiceWithoutInitialize(
33 Out<SharedPointer<IParentalControlService>> out_service, ClientProcessId process_id) {
34 LOG_DEBUG(Service_PCTL, "called");
35 // TODO(ogniK): Get application id from process
36 *out_service = std::make_shared<IParentalControlService>(system, capability);
37 R_SUCCEED();
38}
39
40} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/parental_control_service_factory.h b/src/core/hle/service/pctl/parental_control_service_factory.h
new file mode 100755
index 000000000..362988add
--- /dev/null
+++ b/src/core/hle/service/pctl/parental_control_service_factory.h
@@ -0,0 +1,31 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/cmif_types.h"
7#include "core/hle/service/pctl/pctl_types.h"
8#include "core/hle/service/service.h"
9
10namespace Service::PCTL {
11
12class IParentalControlService;
13
14class IParentalControlServiceFactory : public ServiceFramework<IParentalControlServiceFactory> {
15public:
16 explicit IParentalControlServiceFactory(Core::System& system_, const char* name_,
17 Capability capability_);
18 ~IParentalControlServiceFactory() override;
19
20 Result CreateService(Out<SharedPointer<IParentalControlService>> out_service,
21 ClientProcessId process_id);
22 Result CreateServiceWithoutInitialize(Out<SharedPointer<IParentalControlService>> out_service,
23 ClientProcessId process_id);
24
25private:
26 Capability capability{};
27};
28
29void LoopProcess(Core::System& system);
30
31} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/pctl.cpp b/src/core/hle/service/pctl/pctl.cpp
index 635713796..0cb11cf0b 100755
--- a/src/core/hle/service/pctl/pctl.cpp
+++ b/src/core/hle/service/pctl/pctl.cpp
@@ -1,19 +1,28 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/pctl/parental_control_service_factory.h"
4#include "core/hle/service/pctl/pctl.h" 5#include "core/hle/service/pctl/pctl.h"
6#include "core/hle/service/server_manager.h"
5 7
6namespace Service::PCTL { 8namespace Service::PCTL {
7 9
8PCTL::PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name, 10void LoopProcess(Core::System& system) {
9 Capability capability_) 11 auto server_manager = std::make_unique<ServerManager>(system);
10 : Interface{system_, std::move(module_), name, capability_} { 12
11 static const FunctionInfo functions[] = { 13 server_manager->RegisterNamedService("pctl",
12 {0, &PCTL::CreateService, "CreateService"}, 14 std::make_shared<IParentalControlServiceFactory>(
13 {1, &PCTL::CreateServiceWithoutInitialize, "CreateServiceWithoutInitialize"}, 15 system, "pctl",
14 }; 16 Capability::Application | Capability::SnsPost |
15 RegisterHandlers(functions); 17 Capability::Status | Capability::StereoVision));
18 // TODO(ogniK): Implement remaining capabilities
19 server_manager->RegisterNamedService("pctl:a", std::make_shared<IParentalControlServiceFactory>(
20 system, "pctl:a", Capability::None));
21 server_manager->RegisterNamedService("pctl:r", std::make_shared<IParentalControlServiceFactory>(
22 system, "pctl:r", Capability::None));
23 server_manager->RegisterNamedService("pctl:s", std::make_shared<IParentalControlServiceFactory>(
24 system, "pctl:s", Capability::None));
25 ServerManager::RunServer(std::move(server_manager));
16} 26}
17 27
18PCTL::~PCTL() = default;
19} // namespace Service::PCTL 28} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/pctl.h b/src/core/hle/service/pctl/pctl.h
index 1ee9d0b6e..6a70db680 100755
--- a/src/core/hle/service/pctl/pctl.h
+++ b/src/core/hle/service/pctl/pctl.h
@@ -3,19 +3,12 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/pctl/pctl_module.h"
7
8namespace Core { 6namespace Core {
9class System; 7class System;
10} 8}
11 9
12namespace Service::PCTL { 10namespace Service::PCTL {
13 11
14class PCTL final : public Module::Interface { 12void LoopProcess(Core::System& system);
15public:
16 explicit PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name,
17 Capability capability_);
18 ~PCTL() override;
19};
20 13
21} // namespace Service::PCTL 14} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/pctl_results.h b/src/core/hle/service/pctl/pctl_results.h
new file mode 100755
index 000000000..1fc54727b
--- /dev/null
+++ b/src/core/hle/service/pctl/pctl_results.h
@@ -0,0 +1,15 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/result.h"
7
8namespace Service::PCTL {
9
10constexpr Result ResultNoFreeCommunication{ErrorModule::PCTL, 101};
11constexpr Result ResultStereoVisionRestricted{ErrorModule::PCTL, 104};
12constexpr Result ResultNoCapability{ErrorModule::PCTL, 131};
13constexpr Result ResultNoRestrictionEnabled{ErrorModule::PCTL, 181};
14
15} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/pctl_types.h b/src/core/hle/service/pctl/pctl_types.h
new file mode 100755
index 000000000..daaecdf48
--- /dev/null
+++ b/src/core/hle/service/pctl/pctl_types.h
@@ -0,0 +1,43 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "common/common_funcs.h"
7
8namespace Service::PCTL {
9
10enum class Capability : u32 {
11 None = 0,
12 Application = 1 << 0,
13 SnsPost = 1 << 1,
14 Recovery = 1 << 6,
15 Status = 1 << 8,
16 StereoVision = 1 << 9,
17 System = 1 << 15,
18};
19DECLARE_ENUM_FLAG_OPERATORS(Capability);
20
21struct ApplicationInfo {
22 u64 application_id{};
23 std::array<u8, 32> age_rating{};
24 u32 parental_control_flag{};
25 Capability capability{};
26};
27static_assert(sizeof(ApplicationInfo) == 0x30, "ApplicationInfo has incorrect size.");
28
29// This is nn::pctl::RestrictionSettings
30struct RestrictionSettings {
31 u8 rating_age;
32 bool sns_post_restriction;
33 bool free_communication_restriction;
34};
35static_assert(sizeof(RestrictionSettings) == 0x3, "RestrictionSettings has incorrect size.");
36
37// This is nn::pctl::PlayTimerSettings
38struct PlayTimerSettings {
39 std::array<u32, 13> settings;
40};
41static_assert(sizeof(PlayTimerSettings) == 0x34, "PlayTimerSettings has incorrect size.");
42
43} // namespace Service::PCTL
diff --git a/src/core/hle/service/psc/ovln/ovln_types.h b/src/core/hle/service/psc/ovln/ovln_types.h
new file mode 100755
index 000000000..343b05dcc
--- /dev/null
+++ b/src/core/hle/service/psc/ovln/ovln_types.h
@@ -0,0 +1,21 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "common/bit_field.h"
7#include "common/common_types.h"
8
9namespace Service::PSC {
10
11using OverlayNotification = std::array<u64, 0x10>;
12static_assert(sizeof(OverlayNotification) == 0x80, "OverlayNotification has incorrect size");
13
14union MessageFlags {
15 u64 raw;
16 BitField<0, 8, u64> message_type;
17 BitField<8, 8, u64> queue_type;
18};
19static_assert(sizeof(MessageFlags) == 0x8, "MessageFlags has incorrect size");
20
21} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/ovln/receiver.cpp b/src/core/hle/service/psc/ovln/receiver.cpp
new file mode 100755
index 000000000..85f62816d
--- /dev/null
+++ b/src/core/hle/service/psc/ovln/receiver.cpp
@@ -0,0 +1,24 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/psc/ovln/receiver.h"
5
6namespace Service::PSC {
7
8IReceiver::IReceiver(Core::System& system_) : ServiceFramework{system_, "IReceiver"} {
9 // clang-format off
10 static const FunctionInfo functions[] = {
11 {0, nullptr, "AddSource"},
12 {1, nullptr, "RemoveSource"},
13 {2, nullptr, "GetReceiveEventHandle"},
14 {3, nullptr, "Receive"},
15 {4, nullptr, "ReceiveWithTick"},
16 };
17 // clang-format on
18
19 RegisterHandlers(functions);
20}
21
22IReceiver::~IReceiver() = default;
23
24} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/ovln/receiver.h b/src/core/hle/service/psc/ovln/receiver.h
new file mode 100755
index 000000000..c47a4ff7e
--- /dev/null
+++ b/src/core/hle/service/psc/ovln/receiver.h
@@ -0,0 +1,16 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/service.h"
7
8namespace Service::PSC {
9
10class IReceiver final : public ServiceFramework<IReceiver> {
11public:
12 explicit IReceiver(Core::System& system_);
13 ~IReceiver() override;
14};
15
16} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/ovln/receiver_service.cpp b/src/core/hle/service/psc/ovln/receiver_service.cpp
new file mode 100755
index 000000000..bb988e905
--- /dev/null
+++ b/src/core/hle/service/psc/ovln/receiver_service.cpp
@@ -0,0 +1,28 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/psc/ovln/receiver.h"
6#include "core/hle/service/psc/ovln/receiver_service.h"
7
8namespace Service::PSC {
9
10IReceiverService::IReceiverService(Core::System& system_) : ServiceFramework{system_, "ovln:rcv"} {
11 // clang-format off
12 static const FunctionInfo functions[] = {
13 {0, D<&IReceiverService::OpenReceiver>, "OpenReceiver"},
14 };
15 // clang-format on
16
17 RegisterHandlers(functions);
18}
19
20IReceiverService::~IReceiverService() = default;
21
22Result IReceiverService::OpenReceiver(Out<SharedPointer<IReceiver>> out_receiver) {
23 LOG_DEBUG(Service_PSC, "called");
24 *out_receiver = std::make_shared<IReceiver>(system);
25 R_SUCCEED();
26}
27
28} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/ovln/receiver_service.h b/src/core/hle/service/psc/ovln/receiver_service.h
new file mode 100755
index 000000000..b3b31ba4a
--- /dev/null
+++ b/src/core/hle/service/psc/ovln/receiver_service.h
@@ -0,0 +1,22 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/cmif_types.h"
7#include "core/hle/service/service.h"
8
9namespace Service::PSC {
10
11class IReceiver;
12
13class IReceiverService final : public ServiceFramework<IReceiverService> {
14public:
15 explicit IReceiverService(Core::System& system_);
16 ~IReceiverService() override;
17
18private:
19 Result OpenReceiver(Out<SharedPointer<IReceiver>> out_receiver);
20};
21
22} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/ovln/sender.cpp b/src/core/hle/service/psc/ovln/sender.cpp
new file mode 100755
index 000000000..3227a56f2
--- /dev/null
+++ b/src/core/hle/service/psc/ovln/sender.cpp
@@ -0,0 +1,32 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/psc/ovln/sender.h"
6
7namespace Service::PSC {
8
9ISender::ISender(Core::System& system_) : ServiceFramework{system_, "ISender"} {
10 // clang-format off
11 static const FunctionInfo functions[] = {
12 {0, D<&ISender::Send>, "Send"},
13 {1, nullptr, "GetUnreceivedMessageCount"},
14 };
15 // clang-format on
16
17 RegisterHandlers(functions);
18}
19
20ISender::~ISender() = default;
21
22Result ISender::Send(const OverlayNotification& notification, MessageFlags flags) {
23 std::string data;
24 for (const auto m : notification) {
25 data += fmt::format("{:016X} ", m);
26 }
27
28 LOG_WARNING(Service_PSC, "(STUBBED) called, flags={} notification={}", flags.raw, data);
29 R_SUCCEED();
30}
31
32} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/ovln/sender.h b/src/core/hle/service/psc/ovln/sender.h
new file mode 100755
index 000000000..c1575428e
--- /dev/null
+++ b/src/core/hle/service/psc/ovln/sender.h
@@ -0,0 +1,21 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/cmif_types.h"
7#include "core/hle/service/psc/ovln/ovln_types.h"
8#include "core/hle/service/service.h"
9
10namespace Service::PSC {
11
12class ISender final : public ServiceFramework<ISender> {
13public:
14 explicit ISender(Core::System& system_);
15 ~ISender() override;
16
17private:
18 Result Send(const OverlayNotification& notification, MessageFlags flags);
19};
20
21} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/ovln/sender_service.cpp b/src/core/hle/service/psc/ovln/sender_service.cpp
new file mode 100755
index 000000000..18d2c83a3
--- /dev/null
+++ b/src/core/hle/service/psc/ovln/sender_service.cpp
@@ -0,0 +1,30 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/psc/ovln/sender.h"
6#include "core/hle/service/psc/ovln/sender_service.h"
7
8namespace Service::PSC {
9
10ISenderService::ISenderService(Core::System& system_) : ServiceFramework{system_, "ovln:snd"} {
11 // clang-format off
12 static const FunctionInfo functions[] = {
13 {0, D<&ISenderService::OpenSender>, "OpenSender"},
14 };
15 // clang-format on
16
17 RegisterHandlers(functions);
18}
19
20ISenderService::~ISenderService() = default;
21
22Result ISenderService::OpenSender(Out<SharedPointer<ISender>> out_sender, u32 sender_id,
23 std::array<u64, 2> data) {
24 LOG_WARNING(Service_PSC, "(STUBBED) called, sender_id={}, data={:016X} {:016X}", sender_id,
25 data[0], data[1]);
26 *out_sender = std::make_shared<ISender>(system);
27 R_SUCCEED();
28}
29
30} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/ovln/sender_service.h b/src/core/hle/service/psc/ovln/sender_service.h
new file mode 100755
index 000000000..10027701f
--- /dev/null
+++ b/src/core/hle/service/psc/ovln/sender_service.h
@@ -0,0 +1,23 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/cmif_types.h"
7#include "core/hle/service/service.h"
8
9namespace Service::PSC {
10
11class ISender;
12
13class ISenderService final : public ServiceFramework<ISenderService> {
14public:
15 explicit ISenderService(Core::System& system_);
16 ~ISenderService() override;
17
18private:
19 Result OpenSender(Out<SharedPointer<ISender>> out_sender, u32 sender_id,
20 std::array<u64, 2> data);
21};
22
23} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/pm_control.cpp b/src/core/hle/service/psc/pm_control.cpp
new file mode 100755
index 000000000..7dedb7662
--- /dev/null
+++ b/src/core/hle/service/psc/pm_control.cpp
@@ -0,0 +1,28 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/psc/pm_control.h"
5
6namespace Service::PSC {
7
8IPmControl::IPmControl(Core::System& system_) : ServiceFramework{system_, "psc:c"} {
9 // clang-format off
10 static const FunctionInfo functions[] = {
11 {0, nullptr, "Initialize"},
12 {1, nullptr, "DispatchRequest"},
13 {2, nullptr, "GetResult"},
14 {3, nullptr, "GetState"},
15 {4, nullptr, "Cancel"},
16 {5, nullptr, "PrintModuleInformation"},
17 {6, nullptr, "GetModuleInformation"},
18 {10, nullptr, "AcquireStateLock"},
19 {11, nullptr, "HasStateLock"},
20 };
21 // clang-format on
22
23 RegisterHandlers(functions);
24}
25
26IPmControl::~IPmControl() = default;
27
28} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/pm_control.h b/src/core/hle/service/psc/pm_control.h
new file mode 100755
index 000000000..e0ae2f39c
--- /dev/null
+++ b/src/core/hle/service/psc/pm_control.h
@@ -0,0 +1,16 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/service.h"
7
8namespace Service::PSC {
9
10class IPmControl final : public ServiceFramework<IPmControl> {
11public:
12 explicit IPmControl(Core::System& system_);
13 ~IPmControl() override;
14};
15
16} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/pm_module.cpp b/src/core/hle/service/psc/pm_module.cpp
new file mode 100755
index 000000000..74dc7ed4e
--- /dev/null
+++ b/src/core/hle/service/psc/pm_module.cpp
@@ -0,0 +1,24 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/psc/pm_module.h"
5
6namespace Service::PSC {
7
8IPmModule::IPmModule(Core::System& system_) : ServiceFramework{system_, "IPmModule"} {
9 // clang-format off
10 static const FunctionInfo functions[] = {
11 {0, nullptr, "Initialize"},
12 {1, nullptr, "GetRequest"},
13 {2, nullptr, "Acknowledge"},
14 {3, nullptr, "Finalize"},
15 {4, nullptr, "AcknowledgeEx"},
16 };
17 // clang-format on
18
19 RegisterHandlers(functions);
20}
21
22IPmModule::~IPmModule() = default;
23
24} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/pm_module.h b/src/core/hle/service/psc/pm_module.h
new file mode 100755
index 000000000..b3a2d2584
--- /dev/null
+++ b/src/core/hle/service/psc/pm_module.h
@@ -0,0 +1,16 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/service.h"
7
8namespace Service::PSC {
9
10class IPmModule final : public ServiceFramework<IPmModule> {
11public:
12 explicit IPmModule(Core::System& system_);
13 ~IPmModule() override;
14};
15
16} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/pm_service.cpp b/src/core/hle/service/psc/pm_service.cpp
new file mode 100755
index 000000000..c4e0ad228
--- /dev/null
+++ b/src/core/hle/service/psc/pm_service.cpp
@@ -0,0 +1,28 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/cmif_serialization.h"
5#include "core/hle/service/psc/pm_module.h"
6#include "core/hle/service/psc/pm_service.h"
7
8namespace Service::PSC {
9
10IPmService::IPmService(Core::System& system_) : ServiceFramework{system_, "psc:m"} {
11 // clang-format off
12 static const FunctionInfo functions[] = {
13 {0, D<&IPmService::GetPmModule>, "GetPmModule"},
14 };
15 // clang-format on
16
17 RegisterHandlers(functions);
18}
19
20IPmService::~IPmService() = default;
21
22Result IPmService::GetPmModule(Out<SharedPointer<IPmModule>> out_module) {
23 LOG_DEBUG(Service_PSC, "called");
24 *out_module = std::make_shared<IPmModule>(system);
25 R_SUCCEED();
26}
27
28} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/pm_service.h b/src/core/hle/service/psc/pm_service.h
new file mode 100755
index 000000000..08e14c6f8
--- /dev/null
+++ b/src/core/hle/service/psc/pm_service.h
@@ -0,0 +1,22 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/cmif_types.h"
7#include "core/hle/service/service.h"
8
9namespace Service::PSC {
10
11class IPmModule;
12
13class IPmService final : public ServiceFramework<IPmService> {
14public:
15 explicit IPmService(Core::System& system_);
16 ~IPmService() override;
17
18private:
19 Result GetPmModule(Out<SharedPointer<IPmModule>> out_module);
20};
21
22} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/psc.cpp b/src/core/hle/service/psc/psc.cpp
index 94eaa566a..e7c902ad6 100755
--- a/src/core/hle/service/psc/psc.cpp
+++ b/src/core/hle/service/psc/psc.cpp
@@ -1,11 +1,10 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include <memory> 4#include "core/hle/service/psc/ovln/receiver_service.h"
5 5#include "core/hle/service/psc/ovln/sender_service.h"
6#include "common/logging/log.h" 6#include "core/hle/service/psc/pm_control.h"
7#include "core/core.h" 7#include "core/hle/service/psc/pm_service.h"
8#include "core/hle/service/ipc_helpers.h"
9#include "core/hle/service/psc/psc.h" 8#include "core/hle/service/psc/psc.h"
10#include "core/hle/service/psc/time/manager.h" 9#include "core/hle/service/psc/time/manager.h"
11#include "core/hle/service/psc/time/power_state_service.h" 10#include "core/hle/service/psc/time/power_state_service.h"
@@ -15,71 +14,13 @@
15 14
16namespace Service::PSC { 15namespace Service::PSC {
17 16
18class IPmControl final : public ServiceFramework<IPmControl> {
19public:
20 explicit IPmControl(Core::System& system_) : ServiceFramework{system_, "psc:c"} {
21 // clang-format off
22 static const FunctionInfo functions[] = {
23 {0, nullptr, "Initialize"},
24 {1, nullptr, "DispatchRequest"},
25 {2, nullptr, "GetResult"},
26 {3, nullptr, "GetState"},
27 {4, nullptr, "Cancel"},
28 {5, nullptr, "PrintModuleInformation"},
29 {6, nullptr, "GetModuleInformation"},
30 {10, nullptr, "AcquireStateLock"},
31 {11, nullptr, "HasStateLock"},
32 };
33 // clang-format on
34
35 RegisterHandlers(functions);
36 }
37};
38
39class IPmModule final : public ServiceFramework<IPmModule> {
40public:
41 explicit IPmModule(Core::System& system_) : ServiceFramework{system_, "IPmModule"} {
42 // clang-format off
43 static const FunctionInfo functions[] = {
44 {0, nullptr, "Initialize"},
45 {1, nullptr, "GetRequest"},
46 {2, nullptr, "Acknowledge"},
47 {3, nullptr, "Finalize"},
48 {4, nullptr, "AcknowledgeEx"},
49 };
50 // clang-format on
51
52 RegisterHandlers(functions);
53 }
54};
55
56class IPmService final : public ServiceFramework<IPmService> {
57public:
58 explicit IPmService(Core::System& system_) : ServiceFramework{system_, "psc:m"} {
59 // clang-format off
60 static const FunctionInfo functions[] = {
61 {0, &IPmService::GetPmModule, "GetPmModule"},
62 };
63 // clang-format on
64
65 RegisterHandlers(functions);
66 }
67
68private:
69 void GetPmModule(HLERequestContext& ctx) {
70 LOG_DEBUG(Service_PSC, "called");
71
72 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
73 rb.Push(ResultSuccess);
74 rb.PushIpcInterface<IPmModule>(system);
75 }
76};
77
78void LoopProcess(Core::System& system) { 17void LoopProcess(Core::System& system) {
79 auto server_manager = std::make_unique<ServerManager>(system); 18 auto server_manager = std::make_unique<ServerManager>(system);
80 19
81 server_manager->RegisterNamedService("psc:c", std::make_shared<IPmControl>(system)); 20 server_manager->RegisterNamedService("psc:c", std::make_shared<IPmControl>(system));
82 server_manager->RegisterNamedService("psc:m", std::make_shared<IPmService>(system)); 21 server_manager->RegisterNamedService("psc:m", std::make_shared<IPmService>(system));
22 server_manager->RegisterNamedService("ovln:rcv", std::make_shared<IReceiverService>(system));
23 server_manager->RegisterNamedService("ovln:snd", std::make_shared<ISenderService>(system));
83 24
84 auto time = std::make_shared<Time::TimeManager>(system); 25 auto time = std::make_shared<Time::TimeManager>(system);
85 26
diff --git a/src/core/hle/service/psc/psc.h b/src/core/hle/service/psc/psc.h
index 1af33262e..24a12850a 100755
--- a/src/core/hle/service/psc/psc.h
+++ b/src/core/hle/service/psc/psc.h
@@ -7,10 +7,6 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::PSC { 10namespace Service::PSC {
15 11
16void LoopProcess(Core::System& system); 12void LoopProcess(Core::System& system);
diff --git a/src/core/hle/service/services.cpp b/src/core/hle/service/services.cpp
index d6c6eff50..1aa85ea54 100755
--- a/src/core/hle/service/services.cpp
+++ b/src/core/hle/service/services.cpp
@@ -46,7 +46,7 @@
46#include "core/hle/service/olsc/olsc.h" 46#include "core/hle/service/olsc/olsc.h"
47#include "core/hle/service/omm/omm.h" 47#include "core/hle/service/omm/omm.h"
48#include "core/hle/service/pcie/pcie.h" 48#include "core/hle/service/pcie/pcie.h"
49#include "core/hle/service/pctl/pctl_module.h" 49#include "core/hle/service/pctl/pctl.h"
50#include "core/hle/service/pcv/pcv.h" 50#include "core/hle/service/pcv/pcv.h"
51#include "core/hle/service/pm/pm.h" 51#include "core/hle/service/pm/pm.h"
52#include "core/hle/service/prepo/prepo.h" 52#include "core/hle/service/prepo/prepo.h"
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 62ce5beac..ed820399b 100755
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -2325,15 +2325,15 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
2325 ASSERT(user_id); 2325 ASSERT(user_id);
2326 2326
2327 const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath( 2327 const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath(
2328 {}, vfs_nand_dir, FileSys::SaveDataSpaceId::NandUser, 2328 {}, vfs_nand_dir, FileSys::SaveDataSpaceId::User, FileSys::SaveDataType::Account,
2329 FileSys::SaveDataType::SaveData, program_id, user_id->AsU128(), 0); 2329 program_id, user_id->AsU128(), 0);
2330 2330
2331 path = Common::FS::ConcatPathSafe(nand_dir, user_save_data_path); 2331 path = Common::FS::ConcatPathSafe(nand_dir, user_save_data_path);
2332 } else { 2332 } else {
2333 // Device save data 2333 // Device save data
2334 const auto device_save_data_path = FileSys::SaveDataFactory::GetFullPath( 2334 const auto device_save_data_path = FileSys::SaveDataFactory::GetFullPath(
2335 {}, vfs_nand_dir, FileSys::SaveDataSpaceId::NandUser, 2335 {}, vfs_nand_dir, FileSys::SaveDataSpaceId::User, FileSys::SaveDataType::Account,
2336 FileSys::SaveDataType::SaveData, program_id, {}, 0); 2336 program_id, {}, 0);
2337 2337
2338 path = Common::FS::ConcatPathSafe(nand_dir, device_save_data_path); 2338 path = Common::FS::ConcatPathSafe(nand_dir, device_save_data_path);
2339 } 2339 }
@@ -2674,7 +2674,7 @@ void GMainWindow::RemoveCacheStorage(u64 program_id) {
2674 vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir), FileSys::OpenMode::Read); 2674 vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir), FileSys::OpenMode::Read);
2675 2675
2676 const auto cache_storage_path = FileSys::SaveDataFactory::GetFullPath( 2676 const auto cache_storage_path = FileSys::SaveDataFactory::GetFullPath(
2677 {}, vfs_nand_dir, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::CacheStorage, 2677 {}, vfs_nand_dir, FileSys::SaveDataSpaceId::User, FileSys::SaveDataType::Cache,
2678 0 /* program_id */, {}, 0); 2678 0 /* program_id */, {}, 0);
2679 2679
2680 const auto path = Common::FS::ConcatPathSafe(nand_dir, cache_storage_path); 2680 const auto path = Common::FS::ConcatPathSafe(nand_dir, cache_storage_path);