summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service')
-rw-r--r--src/core/hle/service/acc/acc.cpp59
-rw-r--r--src/core/hle/service/acc/acc.h3
-rw-r--r--src/core/hle/service/acc/acc_su.cpp2
-rw-r--r--src/core/hle/service/acc/acc_u0.cpp2
-rw-r--r--src/core/hle/service/acc/acc_u1.cpp2
-rw-r--r--src/core/hle/service/am/am.cpp17
-rw-r--r--src/core/hle/service/audio/audin_u.cpp70
-rw-r--r--src/core/hle/service/audio/audin_u.h29
-rw-r--r--src/core/hle/service/caps/caps_su.cpp11
-rw-r--r--src/core/hle/service/caps/caps_su.h3
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h5
11 files changed, 162 insertions, 41 deletions
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index cfac8ca9a..630a8b048 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -228,7 +228,8 @@ public:
class IManagerForApplication final : public ServiceFramework<IManagerForApplication> {
public:
- IManagerForApplication() : ServiceFramework("IManagerForApplication") {
+ explicit IManagerForApplication(Common::UUID user_id)
+ : ServiceFramework("IManagerForApplication"), user_id(user_id) {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IManagerForApplication::CheckAvailability, "CheckAvailability"},
@@ -254,12 +255,14 @@ private:
}
void GetAccountId(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_ACC, "(STUBBED) called");
- // Should return a nintendo account ID
+ LOG_DEBUG(Service_ACC, "called");
+
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
- rb.PushRaw<u64>(1);
+ rb.PushRaw<u64>(user_id.GetNintendoID());
}
+
+ Common::UUID user_id;
};
void Module::Interface::GetUserCount(Kernel::HLERequestContext& ctx) {
@@ -319,46 +322,37 @@ void Module::Interface::IsUserRegistrationRequestPermitted(Kernel::HLERequestCon
void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- auto pid = rp.Pop<u64>();
- LOG_DEBUG(Service_ACC, "called, process_id={}", pid);
+ LOG_DEBUG(Service_ACC, "called");
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(InitializeApplicationInfoBase(pid));
+ rb.Push(InitializeApplicationInfoBase());
}
void Module::Interface::InitializeApplicationInfoRestricted(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- auto pid = rp.Pop<u64>();
- LOG_WARNING(Service_ACC, "(Partial implementation) called, process_id={}", pid);
+ LOG_WARNING(Service_ACC, "(Partial implementation) called");
// TODO(ogniK): We require checking if the user actually owns the title and what not. As of
// currently, we assume the user owns the title. InitializeApplicationInfoBase SHOULD be called
// first then we do extra checks if the game is a digital copy.
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(InitializeApplicationInfoBase(pid));
+ rb.Push(InitializeApplicationInfoBase());
}
-ResultCode Module::Interface::InitializeApplicationInfoBase(u64 process_id) {
+ResultCode Module::Interface::InitializeApplicationInfoBase() {
if (application_info) {
LOG_ERROR(Service_ACC, "Application already initialized");
return ERR_ACCOUNTINFO_ALREADY_INITIALIZED;
}
- const auto& list = system.Kernel().GetProcessList();
- const auto iter = std::find_if(list.begin(), list.end(), [&process_id](const auto& process) {
- return process->GetProcessID() == process_id;
- });
-
- if (iter == list.end()) {
- LOG_ERROR(Service_ACC, "Failed to find process ID");
- application_info.application_type = ApplicationType::Unknown;
-
- return ERR_ACCOUNTINFO_BAD_APPLICATION;
- }
-
- const auto launch_property = system.GetARPManager().GetLaunchProperty((*iter)->GetTitleID());
+ // TODO(ogniK): This should be changed to reflect the target process for when we have multiple
+ // processes emulated. As we don't actually have pid support we should assume we're just using
+ // our own process
+ const auto& current_process = system.Kernel().CurrentProcess();
+ const auto launch_property =
+ system.GetARPManager().GetLaunchProperty(current_process->GetTitleID());
if (launch_property.Failed()) {
LOG_ERROR(Service_ACC, "Failed to get launch property");
@@ -372,10 +366,12 @@ ResultCode Module::Interface::InitializeApplicationInfoBase(u64 process_id) {
case FileSys::StorageId::Host:
case FileSys::StorageId::NandUser:
case FileSys::StorageId::SdCard:
+ case FileSys::StorageId::None: // Yuzu specific, differs from hardware
application_info.application_type = ApplicationType::Digital;
break;
default:
- LOG_ERROR(Service_ACC, "Invalid game storage ID");
+ LOG_ERROR(Service_ACC, "Invalid game storage ID! storage_id={}",
+ launch_property->base_game_storage_id);
return ERR_ACCOUNTINFO_BAD_APPLICATION;
}
@@ -389,7 +385,7 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo
LOG_DEBUG(Service_ACC, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<IManagerForApplication>();
+ rb.PushIpcInterface<IManagerForApplication>(profile_manager->GetLastOpenedUser());
}
void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx) {
@@ -428,6 +424,17 @@ void Module::Interface::GetProfileEditor(Kernel::HLERequestContext& ctx) {
rb.PushIpcInterface<IProfileEditor>(user_id, *profile_manager);
}
+void Module::Interface::ListQualifiedUsers(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_ACC, "called");
+
+ // All users should be qualified. We don't actually have parental control or anything to do with
+ // nintendo online currently. We're just going to assume the user running the game has access to
+ // the game regardless of parental control settings.
+ ctx.WriteBuffer(profile_manager->GetAllUsers());
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_ACC, "called");
// A u8 is passed into this function which we can safely ignore. It's to determine if we have
diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h
index 7a7dc9ec6..74ca39d6e 100644
--- a/src/core/hle/service/acc/acc.h
+++ b/src/core/hle/service/acc/acc.h
@@ -33,9 +33,10 @@ public:
void TrySelectUserWithoutInteraction(Kernel::HLERequestContext& ctx);
void IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx);
void GetProfileEditor(Kernel::HLERequestContext& ctx);
+ void ListQualifiedUsers(Kernel::HLERequestContext& ctx);
private:
- ResultCode InitializeApplicationInfoBase(u64 process_id);
+ ResultCode InitializeApplicationInfoBase();
enum class ApplicationType : u32_le {
GameCard = 0,
diff --git a/src/core/hle/service/acc/acc_su.cpp b/src/core/hle/service/acc/acc_su.cpp
index ae88deda5..2eefc6df5 100644
--- a/src/core/hle/service/acc/acc_su.cpp
+++ b/src/core/hle/service/acc/acc_su.cpp
@@ -35,7 +35,7 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{113, nullptr, "GetSaveDataThumbnailExistence"},
{120, nullptr, "ListOpenUsersInApplication"},
{130, nullptr, "ActivateOpenContextRetention"},
- {140, nullptr, "ListQualifiedUsers"},
+ {140, &ACC_SU::ListQualifiedUsers, "ListQualifiedUsers"},
{150, nullptr, "AuthenticateApplicationAsync"},
{190, nullptr, "GetUserLastOpenedApplication"},
{191, nullptr, "ActivateOpenContextHolder"},
diff --git a/src/core/hle/service/acc/acc_u0.cpp b/src/core/hle/service/acc/acc_u0.cpp
index 0ac19f4ff..fb4e7e772 100644
--- a/src/core/hle/service/acc/acc_u0.cpp
+++ b/src/core/hle/service/acc/acc_u0.cpp
@@ -32,7 +32,7 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{130, nullptr, "LoadOpenContext"},
{131, nullptr, "ListOpenContextStoredUsers"},
{140, &ACC_U0::InitializeApplicationInfoRestricted, "InitializeApplicationInfoRestricted"},
- {141, nullptr, "ListQualifiedUsers"},
+ {141, &ACC_U0::ListQualifiedUsers, "ListQualifiedUsers"},
{150, &ACC_U0::IsUserAccountSwitchLocked, "IsUserAccountSwitchLocked"},
};
// clang-format on
diff --git a/src/core/hle/service/acc/acc_u1.cpp b/src/core/hle/service/acc/acc_u1.cpp
index 2b9c11928..9f29cdc82 100644
--- a/src/core/hle/service/acc/acc_u1.cpp
+++ b/src/core/hle/service/acc/acc_u1.cpp
@@ -34,7 +34,7 @@ ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{112, nullptr, "LoadSaveDataThumbnail"},
{113, nullptr, "GetSaveDataThumbnailExistence"},
{130, nullptr, "ActivateOpenContextRetention"},
- {140, nullptr, "ListQualifiedUsers"},
+ {140, &ACC_U1::ListQualifiedUsers, "ListQualifiedUsers"},
{150, nullptr, "AuthenticateApplicationAsync"},
{190, nullptr, "GetUserLastOpenedApplication"},
{191, nullptr, "ActivateOpenContextHolder"},
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 30cd73252..4df74c4f9 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -1335,12 +1335,23 @@ void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) {
}
void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_AM, "(STUBBED) called");
+ LOG_DEBUG(Service_AM, "called");
+
+ std::array<u8, 0x10> version_string{};
+
+ FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()};
+ const auto res = pm.GetControlMetadata();
+ if (res.first != nullptr) {
+ const auto& version = res.first->GetVersionString();
+ std::copy(version.begin(), version.end(), version_string.begin());
+ } else {
+ constexpr u128 default_version = {1, 0};
+ std::memcpy(version_string.data(), default_version.data(), sizeof(u128));
+ }
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(RESULT_SUCCESS);
- rb.Push<u64>(1);
- rb.Push<u64>(0);
+ rb.PushRaw(version_string);
}
void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp
index d7f1d348d..3e2299426 100644
--- a/src/core/hle/service/audio/audin_u.cpp
+++ b/src/core/hle/service/audio/audin_u.cpp
@@ -2,6 +2,9 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/logging/log.h"
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/audio/audin_u.h"
namespace Service::Audio {
@@ -36,11 +39,12 @@ public:
AudInU::AudInU() : ServiceFramework("audin:u") {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "ListAudioIns"},
- {1, nullptr, "OpenAudioIn"},
- {2, nullptr, "Unknown"},
- {3, nullptr, "OpenAudioInAuto"},
- {4, nullptr, "ListAudioInsAuto"},
+ {0, &AudInU::ListAudioIns, "ListAudioIns"},
+ {1, &AudInU::OpenAudioIn, "OpenAudioIn"},
+ {2, &AudInU::ListAudioIns, "ListAudioInsAuto"},
+ {3, &AudInU::OpenAudioIn, "OpenAudioInAuto"},
+ {4, &AudInU::ListAudioInsAutoFiltered, "ListAudioInsAutoFiltered"},
+ {5, &AudInU::OpenAudioInProtocolSpecified, "OpenAudioInProtocolSpecified"},
};
// clang-format on
@@ -49,4 +53,60 @@ AudInU::AudInU() : ServiceFramework("audin:u") {
AudInU::~AudInU() = default;
+void AudInU::ListAudioIns(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_Audio, "called");
+ const std::size_t count = ctx.GetWriteBufferSize() / sizeof(AudioInDeviceName);
+
+ const std::size_t device_count = std::min(count, audio_device_names.size());
+ std::vector<AudioInDeviceName> device_names;
+ device_names.reserve(device_count);
+
+ for (std::size_t i = 0; i < device_count; i++) {
+ const auto& device_name = audio_device_names[i];
+ auto& entry = device_names.emplace_back();
+ device_name.copy(entry.data(), device_name.size());
+ }
+
+ ctx.WriteBuffer(device_names);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(static_cast<u32>(device_names.size()));
+}
+
+void AudInU::ListAudioInsAutoFiltered(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_Audio, "called");
+ constexpr u32 device_count = 0;
+
+ // Since we don't actually use any other audio input devices, we return 0 devices. Filtered
+ // device listing just omits the default input device
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(static_cast<u32>(device_count));
+}
+
+void AudInU::OpenInOutImpl(Kernel::HLERequestContext& ctx) {
+ AudInOutParams params{};
+ params.channel_count = 2;
+ params.sample_format = SampleFormat::PCM16;
+ params.sample_rate = 48000;
+ params.state = State::Started;
+
+ IPC::ResponseBuilder rb{ctx, 6, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushRaw<AudInOutParams>(params);
+ rb.PushIpcInterface<IAudioIn>();
+}
+
+void AudInU::OpenAudioIn(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_Audio, "(STUBBED) called");
+ OpenInOutImpl(ctx);
+}
+
+void AudInU::OpenAudioInProtocolSpecified(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_Audio, "(STUBBED) called");
+ OpenInOutImpl(ctx);
+}
+
} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audin_u.h b/src/core/hle/service/audio/audin_u.h
index 0538b9560..a599f4a64 100644
--- a/src/core/hle/service/audio/audin_u.h
+++ b/src/core/hle/service/audio/audin_u.h
@@ -16,6 +16,35 @@ class AudInU final : public ServiceFramework<AudInU> {
public:
explicit AudInU();
~AudInU() override;
+
+private:
+ enum class SampleFormat : u32_le {
+ PCM16 = 2,
+ };
+
+ enum class State : u32_le {
+ Started = 0,
+ Stopped = 1,
+ };
+
+ struct AudInOutParams {
+ u32_le sample_rate{};
+ u32_le channel_count{};
+ SampleFormat sample_format{};
+ State state{};
+ };
+ static_assert(sizeof(AudInOutParams) == 0x10, "AudInOutParams is an invalid size");
+
+ using AudioInDeviceName = std::array<char, 256>;
+ static constexpr std::array<std::string_view, 1> audio_device_names{{
+ "BuiltInHeadset",
+ }};
+
+ void ListAudioIns(Kernel::HLERequestContext& ctx);
+ void ListAudioInsAutoFiltered(Kernel::HLERequestContext& ctx);
+ void OpenInOutImpl(Kernel::HLERequestContext& ctx);
+ void OpenAudioIn(Kernel::HLERequestContext& ctx);
+ void OpenAudioInProtocolSpecified(Kernel::HLERequestContext& ctx);
};
} // namespace Service::Audio
diff --git a/src/core/hle/service/caps/caps_su.cpp b/src/core/hle/service/caps/caps_su.cpp
index b4d9355ef..e8b0698e8 100644
--- a/src/core/hle/service/caps/caps_su.cpp
+++ b/src/core/hle/service/caps/caps_su.cpp
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/logging/log.h"
+#include "core/hle/ipc_helpers.h"
#include "core/hle/service/caps/caps_su.h"
namespace Service::Capture {
@@ -9,7 +11,7 @@ namespace Service::Capture {
CAPS_SU::CAPS_SU() : ServiceFramework("caps:su") {
// clang-format off
static const FunctionInfo functions[] = {
- {32, nullptr, "SetShimLibraryVersion"},
+ {32, &CAPS_SU::SetShimLibraryVersion, "SetShimLibraryVersion"},
{201, nullptr, "SaveScreenShot"},
{203, nullptr, "SaveScreenShotEx0"},
{205, nullptr, "SaveScreenShotEx1"},
@@ -22,4 +24,11 @@ CAPS_SU::CAPS_SU() : ServiceFramework("caps:su") {
CAPS_SU::~CAPS_SU() = default;
+void CAPS_SU::SetShimLibraryVersion(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_Capture, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
} // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps_su.h b/src/core/hle/service/caps/caps_su.h
index cb11f7c9a..c494d7c84 100644
--- a/src/core/hle/service/caps/caps_su.h
+++ b/src/core/hle/service/caps/caps_su.h
@@ -16,6 +16,9 @@ class CAPS_SU final : public ServiceFramework<CAPS_SU> {
public:
explicit CAPS_SU();
~CAPS_SU() override;
+
+private:
+ void SetShimLibraryVersion(Kernel::HLERequestContext& ctx);
};
} // namespace Service::Capture
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
index 642b0a2cb..07b644ec5 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
@@ -159,9 +159,10 @@ private:
static_assert(sizeof(IoctlFlushL2) == 8, "IoctlFlushL2 is incorrect size");
struct IoctlGetGpuTime {
- u64_le gpu_time;
+ u64_le gpu_time{};
+ INSERT_PADDING_WORDS(2);
};
- static_assert(sizeof(IoctlGetGpuTime) == 8, "IoctlGetGpuTime is incorrect size");
+ static_assert(sizeof(IoctlGetGpuTime) == 0x10, "IoctlGetGpuTime is incorrect size");
u32 GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& output2, IoctlVersion version);