فهرست منبع

Merge pull request #2584 from ogniK5377/cadence

Impl'd IsUserAccountSwitchLocked, SetAudioOutVolume, GetAudioOutVolume & Partial impl of GetAccumulatedSuspendedTickChangedEvent
Zach Hilman 7 سال پیش
والد
کامیت
5c665fcc5b

+ 7 - 3
src/audio_core/stream.cpp

@@ -51,6 +51,10 @@ void Stream::Stop() {
     UNIMPLEMENTED();
     UNIMPLEMENTED();
 }
 }
 
 
+void Stream::SetVolume(float volume) {
+    game_volume = volume;
+}
+
 Stream::State Stream::GetState() const {
 Stream::State Stream::GetState() const {
     return state;
     return state;
 }
 }
@@ -62,8 +66,8 @@ s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const {
     return Core::Timing::usToCycles(us);
     return Core::Timing::usToCycles(us);
 }
 }
 
 
-static void VolumeAdjustSamples(std::vector<s16>& samples) {
-    const float volume{std::clamp(Settings::values.volume, 0.0f, 1.0f)};
+static void VolumeAdjustSamples(std::vector<s16>& samples, float game_volume) {
+    const float volume{std::clamp(Settings::values.volume - (1.0f - game_volume), 0.0f, 1.0f)};
 
 
     if (volume == 1.0f) {
     if (volume == 1.0f) {
         return;
         return;
@@ -97,7 +101,7 @@ void Stream::PlayNextBuffer() {
     active_buffer = queued_buffers.front();
     active_buffer = queued_buffers.front();
     queued_buffers.pop();
     queued_buffers.pop();
 
 
-    VolumeAdjustSamples(active_buffer->GetSamples());
+    VolumeAdjustSamples(active_buffer->GetSamples(), game_volume);
 
 
     sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples());
     sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples());
 
 

+ 7 - 0
src/audio_core/stream.h

@@ -61,6 +61,12 @@ public:
     /// Returns a vector of recently released buffers specified by tag
     /// Returns a vector of recently released buffers specified by tag
     std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(std::size_t max_count);
     std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(std::size_t max_count);
 
 
+    void SetVolume(float volume);
+
+    float GetVolume() const {
+        return game_volume;
+    }
+
     /// Returns true if the stream is currently playing
     /// Returns true if the stream is currently playing
     bool IsPlaying() const {
     bool IsPlaying() const {
         return state == State::Playing;
         return state == State::Playing;
@@ -94,6 +100,7 @@ private:
 
 
     u32 sample_rate;                          ///< Sample rate of the stream
     u32 sample_rate;                          ///< Sample rate of the stream
     Format format;                            ///< Format of the stream
     Format format;                            ///< Format of the stream
+    float game_volume = 1.0f;                 ///< The volume the game currently has set
     ReleaseCallback release_callback;         ///< Buffer release callback for the stream
     ReleaseCallback release_callback;         ///< Buffer release callback for the stream
     State state{State::Stopped};              ///< Playback state of the stream
     State state{State::Stopped};              ///< Playback state of the stream
     Core::Timing::EventType* release_event{}; ///< Core timing release event for the stream
     Core::Timing::EventType* release_event{}; ///< Core timing release event for the stream

+ 4 - 0
src/core/file_sys/control_metadata.cpp

@@ -87,6 +87,10 @@ u64 NACP::GetDefaultJournalSaveSize() const {
     return raw.user_account_save_data_journal_size;
     return raw.user_account_save_data_journal_size;
 }
 }
 
 
+bool NACP::GetUserAccountSwitchLock() const {
+    return raw.user_account_switch_lock != 0;
+}
+
 u32 NACP::GetSupportedLanguages() const {
 u32 NACP::GetSupportedLanguages() const {
     return raw.supported_languages;
     return raw.supported_languages;
 }
 }

+ 3 - 1
src/core/file_sys/control_metadata.h

@@ -30,7 +30,8 @@ struct RawNACP {
     std::array<LanguageEntry, 16> language_entries;
     std::array<LanguageEntry, 16> language_entries;
     std::array<u8, 0x25> isbn;
     std::array<u8, 0x25> isbn;
     u8 startup_user_account;
     u8 startup_user_account;
-    INSERT_PADDING_BYTES(2);
+    u8 user_account_switch_lock;
+    u8 addon_content_registration_type;
     u32_le application_attribute;
     u32_le application_attribute;
     u32_le supported_languages;
     u32_le supported_languages;
     u32_le parental_control;
     u32_le parental_control;
@@ -111,6 +112,7 @@ public:
     u64 GetDefaultJournalSaveSize() const;
     u64 GetDefaultJournalSaveSize() const;
     u32 GetSupportedLanguages() const;
     u32 GetSupportedLanguages() const;
     std::vector<u8> GetRawBytes() const;
     std::vector<u8> GetRawBytes() const;
+    bool GetUserAccountSwitchLock() const;
 
 
 private:
 private:
     RawNACP raw{};
     RawNACP raw{};

+ 43 - 8
src/core/hle/service/acc/acc.cpp

@@ -12,13 +12,17 @@
 #include "common/swap.h"
 #include "common/swap.h"
 #include "core/constants.h"
 #include "core/constants.h"
 #include "core/core_timing.h"
 #include "core/core_timing.h"
+#include "core/file_sys/control_metadata.h"
+#include "core/file_sys/patch_manager.h"
 #include "core/hle/ipc_helpers.h"
 #include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/process.h"
 #include "core/hle/service/acc/acc.h"
 #include "core/hle/service/acc/acc.h"
 #include "core/hle/service/acc/acc_aa.h"
 #include "core/hle/service/acc/acc_aa.h"
 #include "core/hle/service/acc/acc_su.h"
 #include "core/hle/service/acc/acc_su.h"
 #include "core/hle/service/acc/acc_u0.h"
 #include "core/hle/service/acc/acc_u0.h"
 #include "core/hle/service/acc/acc_u1.h"
 #include "core/hle/service/acc/acc_u1.h"
 #include "core/hle/service/acc/profile_manager.h"
 #include "core/hle/service/acc/profile_manager.h"
+#include "core/loader/loader.h"
 
 
 namespace Service::Account {
 namespace Service::Account {
 
 
@@ -213,7 +217,7 @@ void Module::Interface::IsUserRegistrationRequestPermitted(Kernel::HLERequestCon
     rb.Push(profile_manager->CanSystemRegisterUser());
     rb.Push(profile_manager->CanSystemRegisterUser());
 }
 }
 
 
-void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) {
+void Module::Interface::InitializeApplicationInfoOld(Kernel::HLERequestContext& ctx) {
     LOG_WARNING(Service_ACC, "(STUBBED) called");
     LOG_WARNING(Service_ACC, "(STUBBED) called");
     IPC::ResponseBuilder rb{ctx, 2};
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(RESULT_SUCCESS);
     rb.Push(RESULT_SUCCESS);
@@ -226,6 +230,31 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo
     rb.PushIpcInterface<IManagerForApplication>();
     rb.PushIpcInterface<IManagerForApplication>();
 }
 }
 
 
+void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx) {
+    LOG_DEBUG(Service_ACC, "called");
+    FileSys::NACP nacp;
+    const auto res = system.GetAppLoader().ReadControlData(nacp);
+
+    bool is_locked = false;
+
+    if (res != Loader::ResultStatus::Success) {
+        FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()};
+        auto nacp_unique = pm.GetControlMetadata().first;
+
+        if (nacp_unique != nullptr) {
+            is_locked = nacp_unique->GetUserAccountSwitchLock();
+        } else {
+            LOG_ERROR(Service_ACC, "nacp_unique is null!");
+        }
+    } else {
+        is_locked = nacp.GetUserAccountSwitchLock();
+    }
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(RESULT_SUCCESS);
+    rb.Push(is_locked);
+}
+
 void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContext& ctx) {
 void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContext& ctx) {
     LOG_DEBUG(Service_ACC, "called");
     LOG_DEBUG(Service_ACC, "called");
     // A u8 is passed into this function which we can safely ignore. It's to determine if we have
     // A u8 is passed into this function which we can safely ignore. It's to determine if we have
@@ -251,19 +280,25 @@ void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContex
 }
 }
 
 
 Module::Interface::Interface(std::shared_ptr<Module> module,
 Module::Interface::Interface(std::shared_ptr<Module> module,
-                             std::shared_ptr<ProfileManager> profile_manager, const char* name)
+                             std::shared_ptr<ProfileManager> profile_manager, Core::System& system,
+                             const char* name)
     : ServiceFramework(name), module(std::move(module)),
     : ServiceFramework(name), module(std::move(module)),
-      profile_manager(std::move(profile_manager)) {}
+      profile_manager(std::move(profile_manager)), system(system) {}
 
 
 Module::Interface::~Interface() = default;
 Module::Interface::~Interface() = default;
 
 
-void InstallInterfaces(SM::ServiceManager& service_manager) {
+void InstallInterfaces(Core::System& system) {
     auto module = std::make_shared<Module>();
     auto module = std::make_shared<Module>();
     auto profile_manager = std::make_shared<ProfileManager>();
     auto profile_manager = std::make_shared<ProfileManager>();
-    std::make_shared<ACC_AA>(module, profile_manager)->InstallAsService(service_manager);
-    std::make_shared<ACC_SU>(module, profile_manager)->InstallAsService(service_manager);
-    std::make_shared<ACC_U0>(module, profile_manager)->InstallAsService(service_manager);
-    std::make_shared<ACC_U1>(module, profile_manager)->InstallAsService(service_manager);
+
+    std::make_shared<ACC_AA>(module, profile_manager, system)
+        ->InstallAsService(system.ServiceManager());
+    std::make_shared<ACC_SU>(module, profile_manager, system)
+        ->InstallAsService(system.ServiceManager());
+    std::make_shared<ACC_U0>(module, profile_manager, system)
+        ->InstallAsService(system.ServiceManager());
+    std::make_shared<ACC_U1>(module, profile_manager, system)
+        ->InstallAsService(system.ServiceManager());
 }
 }
 
 
 } // namespace Service::Account
 } // namespace Service::Account

+ 6 - 3
src/core/hle/service/acc/acc.h

@@ -15,7 +15,8 @@ public:
     class Interface : public ServiceFramework<Interface> {
     class Interface : public ServiceFramework<Interface> {
     public:
     public:
         explicit Interface(std::shared_ptr<Module> module,
         explicit Interface(std::shared_ptr<Module> module,
-                           std::shared_ptr<ProfileManager> profile_manager, const char* name);
+                           std::shared_ptr<ProfileManager> profile_manager, Core::System& system,
+                           const char* name);
         ~Interface() override;
         ~Interface() override;
 
 
         void GetUserCount(Kernel::HLERequestContext& ctx);
         void GetUserCount(Kernel::HLERequestContext& ctx);
@@ -24,18 +25,20 @@ public:
         void ListOpenUsers(Kernel::HLERequestContext& ctx);
         void ListOpenUsers(Kernel::HLERequestContext& ctx);
         void GetLastOpenedUser(Kernel::HLERequestContext& ctx);
         void GetLastOpenedUser(Kernel::HLERequestContext& ctx);
         void GetProfile(Kernel::HLERequestContext& ctx);
         void GetProfile(Kernel::HLERequestContext& ctx);
-        void InitializeApplicationInfo(Kernel::HLERequestContext& ctx);
+        void InitializeApplicationInfoOld(Kernel::HLERequestContext& ctx);
         void GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx);
         void GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx);
         void IsUserRegistrationRequestPermitted(Kernel::HLERequestContext& ctx);
         void IsUserRegistrationRequestPermitted(Kernel::HLERequestContext& ctx);
         void TrySelectUserWithoutInteraction(Kernel::HLERequestContext& ctx);
         void TrySelectUserWithoutInteraction(Kernel::HLERequestContext& ctx);
+        void IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx);
 
 
     protected:
     protected:
         std::shared_ptr<Module> module;
         std::shared_ptr<Module> module;
         std::shared_ptr<ProfileManager> profile_manager;
         std::shared_ptr<ProfileManager> profile_manager;
+        Core::System& system;
     };
     };
 };
 };
 
 
 /// Registers all ACC services with the specified service manager.
 /// Registers all ACC services with the specified service manager.
-void InstallInterfaces(SM::ServiceManager& service_manager);
+void InstallInterfaces(Core::System& system);
 
 
 } // namespace Service::Account
 } // namespace Service::Account

+ 3 - 2
src/core/hle/service/acc/acc_aa.cpp

@@ -6,8 +6,9 @@
 
 
 namespace Service::Account {
 namespace Service::Account {
 
 
-ACC_AA::ACC_AA(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager)
-    : Module::Interface(std::move(module), std::move(profile_manager), "acc:aa") {
+ACC_AA::ACC_AA(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager,
+               Core::System& system)
+    : Module::Interface(std::move(module), std::move(profile_manager), system, "acc:aa") {
     static const FunctionInfo functions[] = {
     static const FunctionInfo functions[] = {
         {0, nullptr, "EnsureCacheAsync"},
         {0, nullptr, "EnsureCacheAsync"},
         {1, nullptr, "LoadCache"},
         {1, nullptr, "LoadCache"},

+ 2 - 2
src/core/hle/service/acc/acc_aa.h

@@ -10,8 +10,8 @@ namespace Service::Account {
 
 
 class ACC_AA final : public Module::Interface {
 class ACC_AA final : public Module::Interface {
 public:
 public:
-    explicit ACC_AA(std::shared_ptr<Module> module,
-                    std::shared_ptr<ProfileManager> profile_manager);
+    explicit ACC_AA(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager,
+                    Core::System& system);
     ~ACC_AA() override;
     ~ACC_AA() override;
 };
 };
 
 

+ 3 - 2
src/core/hle/service/acc/acc_su.cpp

@@ -6,8 +6,9 @@
 
 
 namespace Service::Account {
 namespace Service::Account {
 
 
-ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager)
-    : Module::Interface(std::move(module), std::move(profile_manager), "acc:su") {
+ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager,
+               Core::System& system)
+    : Module::Interface(std::move(module), std::move(profile_manager), system, "acc:su") {
     // clang-format off
     // clang-format off
     static const FunctionInfo functions[] = {
     static const FunctionInfo functions[] = {
         {0, &ACC_SU::GetUserCount, "GetUserCount"},
         {0, &ACC_SU::GetUserCount, "GetUserCount"},

+ 2 - 2
src/core/hle/service/acc/acc_su.h

@@ -10,8 +10,8 @@ namespace Service::Account {
 
 
 class ACC_SU final : public Module::Interface {
 class ACC_SU final : public Module::Interface {
 public:
 public:
-    explicit ACC_SU(std::shared_ptr<Module> module,
-                    std::shared_ptr<ProfileManager> profile_manager);
+    explicit ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager,
+                    Core::System& system);
     ~ACC_SU() override;
     ~ACC_SU() override;
 };
 };
 
 

+ 5 - 4
src/core/hle/service/acc/acc_u0.cpp

@@ -6,8 +6,9 @@
 
 
 namespace Service::Account {
 namespace Service::Account {
 
 
-ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager)
-    : Module::Interface(std::move(module), std::move(profile_manager), "acc:u0") {
+ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager,
+               Core::System& system)
+    : Module::Interface(std::move(module), std::move(profile_manager), system, "acc:u0") {
     // clang-format off
     // clang-format off
     static const FunctionInfo functions[] = {
     static const FunctionInfo functions[] = {
         {0, &ACC_U0::GetUserCount, "GetUserCount"},
         {0, &ACC_U0::GetUserCount, "GetUserCount"},
@@ -21,7 +22,7 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
         {51, &ACC_U0::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"},
         {51, &ACC_U0::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"},
         {60, nullptr, "ListOpenContextStoredUsers"},
         {60, nullptr, "ListOpenContextStoredUsers"},
         {99, nullptr, "DebugActivateOpenContextRetention"},
         {99, nullptr, "DebugActivateOpenContextRetention"},
-        {100, &ACC_U0::InitializeApplicationInfo, "InitializeApplicationInfo"},
+        {100, &ACC_U0::InitializeApplicationInfoOld, "InitializeApplicationInfoOld"},
         {101, &ACC_U0::GetBaasAccountManagerForApplication, "GetBaasAccountManagerForApplication"},
         {101, &ACC_U0::GetBaasAccountManagerForApplication, "GetBaasAccountManagerForApplication"},
         {102, nullptr, "AuthenticateApplicationAsync"},
         {102, nullptr, "AuthenticateApplicationAsync"},
         {103, nullptr, "CheckNetworkServiceAvailabilityAsync"},
         {103, nullptr, "CheckNetworkServiceAvailabilityAsync"},
@@ -32,7 +33,7 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
         {131, nullptr, "ListOpenContextStoredUsers"},
         {131, nullptr, "ListOpenContextStoredUsers"},
         {140, nullptr, "InitializeApplicationInfo"},
         {140, nullptr, "InitializeApplicationInfo"},
         {141, nullptr, "ListQualifiedUsers"},
         {141, nullptr, "ListQualifiedUsers"},
-        {150, nullptr, "IsUserAccountSwitchLocked"},
+        {150, &ACC_U0::IsUserAccountSwitchLocked, "IsUserAccountSwitchLocked"},
     };
     };
     // clang-format on
     // clang-format on
 
 

+ 2 - 2
src/core/hle/service/acc/acc_u0.h

@@ -10,8 +10,8 @@ namespace Service::Account {
 
 
 class ACC_U0 final : public Module::Interface {
 class ACC_U0 final : public Module::Interface {
 public:
 public:
-    explicit ACC_U0(std::shared_ptr<Module> module,
-                    std::shared_ptr<ProfileManager> profile_manager);
+    explicit ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager,
+                    Core::System& system);
     ~ACC_U0() override;
     ~ACC_U0() override;
 };
 };
 
 

+ 3 - 2
src/core/hle/service/acc/acc_u1.cpp

@@ -6,8 +6,9 @@
 
 
 namespace Service::Account {
 namespace Service::Account {
 
 
-ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager)
-    : Module::Interface(std::move(module), std::move(profile_manager), "acc:u1") {
+ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager,
+               Core::System& system)
+    : Module::Interface(std::move(module), std::move(profile_manager), system, "acc:u1") {
     // clang-format off
     // clang-format off
     static const FunctionInfo functions[] = {
     static const FunctionInfo functions[] = {
         {0, &ACC_U1::GetUserCount, "GetUserCount"},
         {0, &ACC_U1::GetUserCount, "GetUserCount"},

+ 2 - 2
src/core/hle/service/acc/acc_u1.h

@@ -10,8 +10,8 @@ namespace Service::Account {
 
 
 class ACC_U1 final : public Module::Interface {
 class ACC_U1 final : public Module::Interface {
 public:
 public:
-    explicit ACC_U1(std::shared_ptr<Module> module,
-                    std::shared_ptr<ProfileManager> profile_manager);
+    explicit ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager,
+                    Core::System& system);
     ~ACC_U1() override;
     ~ACC_U1() override;
 };
 };
 
 

+ 17 - 1
src/core/hle/service/am/am.cpp

@@ -271,7 +271,7 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger
         {71, nullptr, "GetCurrentIlluminanceEx"},
         {71, nullptr, "GetCurrentIlluminanceEx"},
         {80, nullptr, "SetWirelessPriorityMode"},
         {80, nullptr, "SetWirelessPriorityMode"},
         {90, nullptr, "GetAccumulatedSuspendedTickValue"},
         {90, nullptr, "GetAccumulatedSuspendedTickValue"},
-        {91, nullptr, "GetAccumulatedSuspendedTickChangedEvent"},
+        {91, &ISelfController::GetAccumulatedSuspendedTickChangedEvent, "GetAccumulatedSuspendedTickChangedEvent"},
         {100, nullptr, "SetAlbumImageTakenNotificationEnabled"},
         {100, nullptr, "SetAlbumImageTakenNotificationEnabled"},
         {1000, nullptr, "GetDebugStorageChannel"},
         {1000, nullptr, "GetDebugStorageChannel"},
     };
     };
@@ -282,6 +282,11 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger
     auto& kernel = Core::System::GetInstance().Kernel();
     auto& kernel = Core::System::GetInstance().Kernel();
     launchable_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
     launchable_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
                                                               "ISelfController:LaunchableEvent");
                                                               "ISelfController:LaunchableEvent");
+
+    // TODO(ogniK): Figure out where, when and why this event gets signalled
+    accumulated_suspended_tick_changed_event = Kernel::WritableEvent::CreateEventPair(
+        kernel, Kernel::ResetType::Manual, "ISelfController:AccumulatedSuspendedTickChangedEvent");
+    accumulated_suspended_tick_changed_event.writable->Signal(); //	Is signalled on creation
 }
 }
 
 
 ISelfController::~ISelfController() = default;
 ISelfController::~ISelfController() = default;
@@ -444,6 +449,17 @@ void ISelfController::GetIdleTimeDetectionExtension(Kernel::HLERequestContext& c
     rb.Push<u32>(idle_time_detection_extension);
     rb.Push<u32>(idle_time_detection_extension);
 }
 }
 
 
+void ISelfController::GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequestContext& ctx) {
+    // The implementation of this function is fine as is, the reason we're labelling it as stubbed
+    // is because we're currently unsure when and where accumulated_suspended_tick_changed_event is
+    // actually signalled for the time being.
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    IPC::ResponseBuilder rb{ctx, 2, 1};
+    rb.Push(RESULT_SUCCESS);
+    rb.PushCopyObjects(accumulated_suspended_tick_changed_event.readable);
+}
+
 AppletMessageQueue::AppletMessageQueue() {
 AppletMessageQueue::AppletMessageQueue() {
     auto& kernel = Core::System::GetInstance().Kernel();
     auto& kernel = Core::System::GetInstance().Kernel();
     on_new_message = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
     on_new_message = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,

+ 3 - 0
src/core/hle/service/am/am.h

@@ -133,9 +133,12 @@ private:
     void SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx);
     void SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx);
     void SetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx);
     void SetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx);
     void GetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx);
     void GetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx);
+    void GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequestContext& ctx);
 
 
     std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
     std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
     Kernel::EventPair launchable_event;
     Kernel::EventPair launchable_event;
+    Kernel::EventPair accumulated_suspended_tick_changed_event;
+
     u32 idle_time_detection_extension = 0;
     u32 idle_time_detection_extension = 0;
     u64 num_fatal_sections_entered = 0;
     u64 num_fatal_sections_entered = 0;
 };
 };

+ 21 - 2
src/core/hle/service/audio/audout_u.cpp

@@ -58,8 +58,8 @@ public:
             {9, &IAudioOut::GetAudioOutBufferCount, "GetAudioOutBufferCount"},
             {9, &IAudioOut::GetAudioOutBufferCount, "GetAudioOutBufferCount"},
             {10, nullptr, "GetAudioOutPlayedSampleCount"},
             {10, nullptr, "GetAudioOutPlayedSampleCount"},
             {11, nullptr, "FlushAudioOutBuffers"},
             {11, nullptr, "FlushAudioOutBuffers"},
-            {12, nullptr, "SetAudioOutVolume"},
-            {13, nullptr, "GetAudioOutVolume"},
+            {12, &IAudioOut::SetAudioOutVolume, "SetAudioOutVolume"},
+            {13, &IAudioOut::GetAudioOutVolume, "GetAudioOutVolume"},
         };
         };
         // clang-format on
         // clang-format on
         RegisterHandlers(functions);
         RegisterHandlers(functions);
@@ -183,6 +183,25 @@ private:
         rb.Push(static_cast<u32>(stream->GetQueueSize()));
         rb.Push(static_cast<u32>(stream->GetQueueSize()));
     }
     }
 
 
+    void SetAudioOutVolume(Kernel::HLERequestContext& ctx) {
+        IPC::RequestParser rp{ctx};
+        const float volume = rp.Pop<float>();
+        LOG_DEBUG(Service_Audio, "called, volume={}", volume);
+
+        stream->SetVolume(volume);
+
+        IPC::ResponseBuilder rb{ctx, 2};
+        rb.Push(RESULT_SUCCESS);
+    }
+
+    void GetAudioOutVolume(Kernel::HLERequestContext& ctx) {
+        LOG_DEBUG(Service_Audio, "called");
+
+        IPC::ResponseBuilder rb{ctx, 3};
+        rb.Push(RESULT_SUCCESS);
+        rb.Push(stream->GetVolume());
+    }
+
     AudioCore::AudioOut& audio_core;
     AudioCore::AudioOut& audio_core;
     AudioCore::StreamPtr stream;
     AudioCore::StreamPtr stream;
     std::string device_name;
     std::string device_name;

+ 1 - 1
src/core/hle/service/service.cpp

@@ -200,7 +200,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system,
 
 
     SM::ServiceManager::InstallInterfaces(sm);
     SM::ServiceManager::InstallInterfaces(sm);
 
 
-    Account::InstallInterfaces(*sm);
+    Account::InstallInterfaces(system);
     AM::InstallInterfaces(*sm, nv_flinger);
     AM::InstallInterfaces(*sm, nv_flinger);
     AOC::InstallInterfaces(*sm);
     AOC::InstallInterfaces(*sm);
     APM::InstallInterfaces(*sm);
     APM::InstallInterfaces(*sm);