summaryrefslogtreecommitdiffstats
path: root/src/core/hle
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/ipc_helpers.h8
-rw-r--r--src/core/hle/service/aoc/aoc_u.cpp10
-rw-r--r--src/core/hle/service/aoc/aoc_u.h1
-rw-r--r--src/core/hle/service/audio/audren_u.cpp14
-rw-r--r--src/core/hle/service/audio/hwopus.cpp45
-rw-r--r--src/core/hle/service/audio/hwopus.h4
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp24
-rw-r--r--src/core/hle/service/filesystem/filesystem.h1
-rw-r--r--src/core/hle/service/mii/manager.cpp5
9 files changed, 91 insertions, 21 deletions
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h
index 61bda3786..ceff2532d 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/ipc_helpers.h
@@ -345,8 +345,12 @@ public:
explicit RequestParser(u32* command_buffer) : RequestHelperBase(command_buffer) {}
explicit RequestParser(Kernel::HLERequestContext& ctx) : RequestHelperBase(ctx) {
- ASSERT_MSG(ctx.GetDataPayloadOffset(), "context is incomplete");
- Skip(ctx.GetDataPayloadOffset(), false);
+ // TIPC does not have data payload offset
+ if (!ctx.IsTipc()) {
+ ASSERT_MSG(ctx.GetDataPayloadOffset(), "context is incomplete");
+ Skip(ctx.GetDataPayloadOffset(), false);
+ }
+
// Skip the u64 command id, it's already stored in the context
static constexpr u32 CommandIdSize = 2;
Skip(CommandIdSize, false);
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp
index fec704c65..dd945e058 100644
--- a/src/core/hle/service/aoc/aoc_u.cpp
+++ b/src/core/hle/service/aoc/aoc_u.cpp
@@ -117,7 +117,7 @@ AOC_U::AOC_U(Core::System& system_)
{7, &AOC_U::PrepareAddOnContent, "PrepareAddOnContent"},
{8, &AOC_U::GetAddOnContentListChangedEvent, "GetAddOnContentListChangedEvent"},
{9, nullptr, "GetAddOnContentLostErrorCode"},
- {10, nullptr, "GetAddOnContentListChangedEventWithProcessId"},
+ {10, &AOC_U::GetAddOnContentListChangedEventWithProcessId, "GetAddOnContentListChangedEventWithProcessId"},
{100, &AOC_U::CreateEcPurchasedEventManager, "CreateEcPurchasedEventManager"},
{101, &AOC_U::CreatePermanentEcPurchasedEventManager, "CreatePermanentEcPurchasedEventManager"},
{110, nullptr, "CreateContentsServiceManager"},
@@ -257,6 +257,14 @@ void AOC_U::GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx) {
rb.PushCopyObjects(aoc_change_event.GetReadableEvent());
}
+void AOC_U::GetAddOnContentListChangedEventWithProcessId(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_AOC, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ rb.PushCopyObjects(aoc_change_event.GetReadableEvent());
+}
+
void AOC_U::CreateEcPurchasedEventManager(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AOC, "(STUBBED) called");
diff --git a/src/core/hle/service/aoc/aoc_u.h b/src/core/hle/service/aoc/aoc_u.h
index 65095baa2..bb6ffb8eb 100644
--- a/src/core/hle/service/aoc/aoc_u.h
+++ b/src/core/hle/service/aoc/aoc_u.h
@@ -28,6 +28,7 @@ private:
void GetAddOnContentBaseId(Kernel::HLERequestContext& ctx);
void PrepareAddOnContent(Kernel::HLERequestContext& ctx);
void GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx);
+ void GetAddOnContentListChangedEventWithProcessId(Kernel::HLERequestContext& ctx);
void CreateEcPurchasedEventManager(Kernel::HLERequestContext& ctx);
void CreatePermanentEcPurchasedEventManager(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 800feba6e..b769fe959 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -96,7 +96,7 @@ private:
void RequestUpdateImpl(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Audio, "(STUBBED) called");
- std::vector<u8> output_params(ctx.GetWriteBufferSize());
+ std::vector<u8> output_params(ctx.GetWriteBufferSize(), 0);
auto result = renderer->UpdateAudioRenderer(ctx.ReadBuffer(), output_params);
if (result.IsSuccess()) {
@@ -110,17 +110,19 @@ private:
void Start(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_Audio, "(STUBBED) called");
- IPC::ResponseBuilder rb{ctx, 2};
+ const auto result = renderer->Start();
- rb.Push(ResultSuccess);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
}
void Stop(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_Audio, "(STUBBED) called");
- IPC::ResponseBuilder rb{ctx, 2};
+ const auto result = renderer->Stop();
- rb.Push(ResultSuccess);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
}
void QuerySystemEvent(Kernel::HLERequestContext& ctx) {
@@ -288,7 +290,7 @@ private:
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
- rb.Push<u32>(1);
+ rb.Push<u32>(2);
}
// Should be similar to QueryAudioDeviceOutputEvent
diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp
index 10e6f7a64..33a6dbbb6 100644
--- a/src/core/hle/service/audio/hwopus.cpp
+++ b/src/core/hle/service/audio/hwopus.cpp
@@ -253,7 +253,11 @@ void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) {
rb.Push<u32>(worker_buffer_sz);
}
-void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) {
+void HwOpus::GetWorkBufferSizeEx(Kernel::HLERequestContext& ctx) {
+ GetWorkBufferSize(ctx);
+}
+
+void HwOpus::OpenHardwareOpusDecoder(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto sample_rate = rp.Pop<u32>();
const auto channel_count = rp.Pop<u32>();
@@ -291,14 +295,47 @@ void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) {
system, OpusDecoderState{std::move(decoder), sample_rate, channel_count});
}
+void HwOpus::OpenHardwareOpusDecoderEx(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto sample_rate = rp.Pop<u32>();
+ const auto channel_count = rp.Pop<u32>();
+
+ LOG_CRITICAL(Audio, "called sample_rate={}, channel_count={}", sample_rate, channel_count);
+
+ ASSERT_MSG(sample_rate == 48000 || sample_rate == 24000 || sample_rate == 16000 ||
+ sample_rate == 12000 || sample_rate == 8000,
+ "Invalid sample rate");
+ ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count");
+
+ const int num_stereo_streams = channel_count == 2 ? 1 : 0;
+ const auto mapping_table = CreateMappingTable(channel_count);
+
+ int error = 0;
+ OpusDecoderPtr decoder{
+ opus_multistream_decoder_create(sample_rate, static_cast<int>(channel_count), 1,
+ num_stereo_streams, mapping_table.data(), &error)};
+ if (error != OPUS_OK || decoder == nullptr) {
+ LOG_ERROR(Audio, "Failed to create Opus decoder (error={}).", error);
+ IPC::ResponseBuilder rb{ctx, 2};
+ // TODO(ogniK): Use correct error code
+ rb.Push(ResultUnknown);
+ return;
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(ResultSuccess);
+ rb.PushIpcInterface<IHardwareOpusDecoderManager>(
+ system, OpusDecoderState{std::move(decoder), sample_rate, channel_count});
+}
+
HwOpus::HwOpus(Core::System& system_) : ServiceFramework{system_, "hwopus"} {
static const FunctionInfo functions[] = {
- {0, &HwOpus::OpenOpusDecoder, "OpenOpusDecoder"},
+ {0, &HwOpus::OpenHardwareOpusDecoder, "OpenHardwareOpusDecoder"},
{1, &HwOpus::GetWorkBufferSize, "GetWorkBufferSize"},
{2, nullptr, "OpenOpusDecoderForMultiStream"},
{3, nullptr, "GetWorkBufferSizeForMultiStream"},
- {4, nullptr, "OpenHardwareOpusDecoderEx"},
- {5, nullptr, "GetWorkBufferSizeEx"},
+ {4, &HwOpus::OpenHardwareOpusDecoderEx, "OpenHardwareOpusDecoderEx"},
+ {5, &HwOpus::GetWorkBufferSizeEx, "GetWorkBufferSizeEx"},
{6, nullptr, "OpenHardwareOpusDecoderForMultiStreamEx"},
{7, nullptr, "GetWorkBufferSizeForMultiStreamEx"},
};
diff --git a/src/core/hle/service/audio/hwopus.h b/src/core/hle/service/audio/hwopus.h
index 4f921f18e..b74824ff3 100644
--- a/src/core/hle/service/audio/hwopus.h
+++ b/src/core/hle/service/audio/hwopus.h
@@ -18,8 +18,10 @@ public:
~HwOpus() override;
private:
- void OpenOpusDecoder(Kernel::HLERequestContext& ctx);
+ void OpenHardwareOpusDecoder(Kernel::HLERequestContext& ctx);
+ void OpenHardwareOpusDecoderEx(Kernel::HLERequestContext& ctx);
void GetWorkBufferSize(Kernel::HLERequestContext& ctx);
+ void GetWorkBufferSizeEx(Kernel::HLERequestContext& ctx);
};
} // namespace Service::Audio
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index 3c16fe6c7..4a9b13e45 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -703,6 +703,16 @@ FileSys::VirtualDir FileSystemController::GetModificationLoadRoot(u64 title_id)
return bis_factory->GetModificationLoadRoot(title_id);
}
+FileSys::VirtualDir FileSystemController::GetSDMCModificationLoadRoot(u64 title_id) const {
+ LOG_TRACE(Service_FS, "Opening SDMC mod load root for tid={:016X}", title_id);
+
+ if (sdmc_factory == nullptr) {
+ return nullptr;
+ }
+
+ return sdmc_factory->GetSDMCModificationLoadRoot(title_id);
+}
+
FileSys::VirtualDir FileSystemController::GetModificationDumpRoot(u64 title_id) const {
LOG_TRACE(Service_FS, "Opening mod dump root for tid={:016X}", title_id);
@@ -733,20 +743,23 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove
}
using YuzuPath = Common::FS::YuzuPath;
+ const auto sdmc_dir_path = Common::FS::GetYuzuPath(YuzuPath::SDMCDir);
+ const auto sdmc_load_dir_path = sdmc_dir_path / "atmosphere/contents";
const auto rw_mode = FileSys::Mode::ReadWrite;
auto nand_directory =
vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::NANDDir), rw_mode);
- auto sd_directory =
- vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::SDMCDir), rw_mode);
+ auto sd_directory = vfs.OpenDirectory(Common::FS::PathToUTF8String(sdmc_dir_path), rw_mode);
auto load_directory =
vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::LoadDir), FileSys::Mode::Read);
+ auto sd_load_directory =
+ vfs.OpenDirectory(Common::FS::PathToUTF8String(sdmc_load_dir_path), FileSys::Mode::Read);
auto dump_directory =
vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::DumpDir), rw_mode);
if (bis_factory == nullptr) {
- bis_factory =
- std::make_unique<FileSys::BISFactory>(nand_directory, load_directory, dump_directory);
+ bis_factory = std::make_unique<FileSys::BISFactory>(
+ nand_directory, std::move(load_directory), std::move(dump_directory));
system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::SysNAND,
bis_factory->GetSystemNANDContents());
system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::UserNAND,
@@ -759,7 +772,8 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove
}
if (sdmc_factory == nullptr) {
- sdmc_factory = std::make_unique<FileSys::SDMCFactory>(std::move(sd_directory));
+ sdmc_factory = std::make_unique<FileSys::SDMCFactory>(std::move(sd_directory),
+ std::move(sd_load_directory));
system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::SDMC,
sdmc_factory->GetSDMCContents());
}
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h
index b6b1b9220..d387af3cb 100644
--- a/src/core/hle/service/filesystem/filesystem.h
+++ b/src/core/hle/service/filesystem/filesystem.h
@@ -115,6 +115,7 @@ public:
FileSys::VirtualDir GetContentDirectory(ContentStorageId id) const;
FileSys::VirtualDir GetImageDirectory(ImageDirectoryId id) const;
+ FileSys::VirtualDir GetSDMCModificationLoadRoot(u64 title_id) const;
FileSys::VirtualDir GetModificationLoadRoot(u64 title_id) const;
FileSys::VirtualDir GetModificationDumpRoot(u64 title_id) const;
diff --git a/src/core/hle/service/mii/manager.cpp b/src/core/hle/service/mii/manager.cpp
index 114aff31c..869d2763f 100644
--- a/src/core/hle/service/mii/manager.cpp
+++ b/src/core/hle/service/mii/manager.cpp
@@ -20,6 +20,7 @@ namespace {
constexpr ResultCode ERROR_CANNOT_FIND_ENTRY{ErrorModule::Mii, 4};
+constexpr std::size_t BaseMiiCount{2};
constexpr std::size_t DefaultMiiCount{RawData::DefaultMii.size()};
constexpr MiiStoreData::Name DefaultMiiName{u'y', u'u', u'z', u'u'};
@@ -415,7 +416,7 @@ u32 MiiManager::GetCount(SourceFlag source_flag) const {
count += 0;
}
if ((source_flag & SourceFlag::Default) != SourceFlag::None) {
- count += DefaultMiiCount;
+ count += (DefaultMiiCount - BaseMiiCount);
}
return static_cast<u32>(count);
}
@@ -445,7 +446,7 @@ ResultVal<std::vector<MiiInfoElement>> MiiManager::GetDefault(SourceFlag source_
return MakeResult(std::move(result));
}
- for (std::size_t index = 0; index < DefaultMiiCount; index++) {
+ for (std::size_t index = BaseMiiCount; index < DefaultMiiCount; index++) {
result.emplace_back(BuildDefault(index), Source::Default);
}