diff options
author | Zephyron <zephyron@citron-emu.orgq> | 2025-02-17 17:33:10 +1000 |
---|---|---|
committer | Zephyron <zephyron@citron-emu.orgq> | 2025-02-17 17:33:10 +1000 |
commit | c5e480e55ddc3183c48148daaa14c00ada855fee (patch) | |
tree | 36613554e13c7526fc106b59b80c49bb1c893392 /src | |
parent | 1c9e17496b6f9f4b083c62aa25548617dd179a8b (diff) |
feat: Add Home Menu launch support and system improvements
This commit adds support for launching the system Home Menu and implements
several system-level improvements:
- Add Home Menu launch functionality through new UI action
- Implement shutdown/reboot sequence handlers in GlobalStateController
- Add support for reserved region extra size in page tables
- Enhance audio controller with output management
- Expand parental control service capabilities
- Add profile service improvements for user management
Technical changes:
- Add OnHomeMenu() handler to launch QLaunch system applet
- Implement m_alias_region_extra_size tracking in page tables
- Add new CreateProcessFlag for reserved region extra size
- Expand audio controller interface with output management
- Add self-controller methods to various services
- Implement play timer and profile service improvements
The changes primarily focus on system menu integration and core service
improvements to better support system functionality.
Diffstat (limited to 'src')
-rw-r--r-- | src/citron/main.cpp | 41 | ||||
-rw-r--r-- | src/citron/main.h | 1 | ||||
-rw-r--r-- | src/citron/main.ui | 111 | ||||
-rw-r--r-- | src/core/hle/kernel/k_page_table_base.cpp | 1 | ||||
-rw-r--r-- | src/core/hle/kernel/k_page_table_base.h | 5 | ||||
-rw-r--r-- | src/core/hle/kernel/k_process_page_table.h | 4 | ||||
-rw-r--r-- | src/core/hle/kernel/svc_types.h | 7 | ||||
-rw-r--r-- | src/core/hle/service/acc/acc.cpp | 27 | ||||
-rw-r--r-- | src/core/hle/service/am/service/all_system_applet_proxies_service.cpp | 9 | ||||
-rw-r--r-- | src/core/hle/service/am/service/all_system_applet_proxies_service.h | 5 | ||||
-rw-r--r-- | src/core/hle/service/am/service/global_state_controller.cpp | 16 | ||||
-rw-r--r-- | src/core/hle/service/am/service/global_state_controller.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/audio/audio_controller.cpp | 57 | ||||
-rw-r--r-- | src/core/hle/service/audio/audio_controller.h | 12 | ||||
-rw-r--r-- | src/core/hle/service/pctl/parental_control_service.cpp | 21 | ||||
-rw-r--r-- | src/core/hle/service/pctl/parental_control_service.h | 2 |
16 files changed, 206 insertions, 115 deletions
diff --git a/src/citron/main.cpp b/src/citron/main.cpp index c30395310..cb6cedd19 100644 --- a/src/citron/main.cpp +++ b/src/citron/main.cpp @@ -1584,6 +1584,7 @@ void GMainWindow::ConnectMenuEvents() { [this]() { OnCabinet(Service::NFP::CabinetMode::StartFormatter); }); connect_menu(ui->action_Load_Mii_Edit, &GMainWindow::OnMiiEdit); connect_menu(ui->action_Open_Controller_Menu, &GMainWindow::OnOpenControllerMenu); + connect_menu(ui->action_Load_Home_Menu, &GMainWindow::OnHomeMenu); connect_menu(ui->action_Capture_Screenshot, &GMainWindow::OnCaptureScreenshot); // TAS @@ -1619,7 +1620,8 @@ void GMainWindow::UpdateMenuState() { ui->action_Load_Cabinet_Restorer, ui->action_Load_Cabinet_Formatter, ui->action_Load_Mii_Edit, - ui->action_Open_Controller_Menu}; + ui->action_Open_Controller_Menu, + ui->action_Load_Home_Menu}; for (QAction* action : running_actions) { action->setEnabled(emulation_running); @@ -5324,3 +5326,40 @@ int main(int argc, char* argv[]) { detached_tasks.WaitForAllTasks(); return result; } + +void GMainWindow::OnHomeMenu() { + constexpr u64 QLaunchId = static_cast<u64>(Service::AM::AppletProgramId::QLaunch); + + // Check if system NAND contents are available + auto bis_system = system->GetFileSystemController().GetSystemNANDContents(); + if (!bis_system) { + QMessageBox::warning(this, tr("System Error"), + tr("System NAND contents not found. Please verify your firmware installation.")); + return; + } + + // Try to get the QLaunch NCA + auto qlaunch_nca = bis_system->GetEntry(QLaunchId, FileSys::ContentRecordType::Program); + if (!qlaunch_nca) { + QMessageBox::warning(this, tr("System Error"), + tr("Home Menu applet not found. Please verify your firmware installation.")); + return; + } + + // Set up applet parameters + Service::AM::FrontendAppletParameters params{ + .program_id = QLaunchId, + .applet_id = Service::AM::AppletId::QLaunch, + .applet_type = Service::AM::AppletType::SystemApplet + }; + + // Configure system for QLaunch + system->GetFrontendAppletHolder().SetCurrentAppletId(Service::AM::AppletId::QLaunch); + + // Get path and launch + const auto nca_path = QString::fromStdString(qlaunch_nca->GetFullPath()); + UISettings::values.roms_path = QFileInfo(nca_path).path().toStdString(); + + // Launch QLaunch with proper parameters + BootGame(nca_path, params); +} diff --git a/src/citron/main.h b/src/citron/main.h index 4822a8981..8a2771760 100644 --- a/src/citron/main.h +++ b/src/citron/main.h @@ -407,6 +407,7 @@ private slots: void OnShutdownBeginDialog(); void OnEmulationStopped(); void OnEmulationStopTimeExpired(); + void OnHomeMenu(); private: QString GetGameListErrorRemoving(InstalledEntryType type) const; diff --git a/src/citron/main.ui b/src/citron/main.ui index 56f1a358b..c68e0180a 100644 --- a/src/citron/main.ui +++ b/src/citron/main.ui @@ -17,91 +17,6 @@ <iconset resource="citron.qrc"> <normaloff>:/img/citron.ico</normaloff>:/img/citron.ico</iconset> </property> - <property name="styleSheet"> - <string notr="true">QMainWindow { - background-color: #2D2D2D; -} - -QMenuBar { - background-color: #333333; - color: #E0E0E0; - border-bottom: 1px solid #404040; - padding: 2px; -} - -QMenuBar::item { - padding: 4px 8px; - background: transparent; - border-radius: 4px; -} - -QMenuBar::item:selected { - background: #404040; -} - -QMenuBar::item:pressed { - background: #505050; -} - -QMenu { - background-color: #333333; - border: 1px solid #404040; - padding: 4px; -} - -QMenu::item { - padding: 6px 24px 6px 12px; - color: #E0E0E0; - border-radius: 4px; -} - -QMenu::item:selected { - background-color: #404040; -} - -QMenu::separator { - height: 1px; - background: #404040; - margin: 4px 0px; -} - -QStatusBar { - background-color: #333333; - color: #E0E0E0; - border-top: 1px solid #404040; -} - -QDockWidget { - border: 1px solid #404040; - titlebar-close-icon: url(close.png); -} - -QDockWidget::title { - background: #333333; - padding: 6px; - color: #E0E0E0; -} - -QToolBar { - background: #333333; - border: none; - spacing: 3px; - padding: 3px; -} - -QToolButton { - border-radius: 4px; - padding: 4px; -} - -QToolButton:hover { - background-color: #404040; -} - -QToolButton:pressed { - background-color: #505050; -}</string> - </property> <property name="tabShape"> <enum>QTabWidget::Rounded</enum> </property> @@ -130,7 +45,7 @@ QToolButton:pressed { <x>0</x> <y>0</y> <width>1280</width> - <height>29</height> + <height>21</height> </rect> </property> <widget class="QMenu" name="menu_File"> @@ -254,6 +169,7 @@ QToolButton:pressed { <addaction name="action_Install_Firmware"/> <addaction name="action_Verify_installed_contents"/> <addaction name="separator"/> + <addaction name="action_Load_Home_Menu"/> <addaction name="menu_cabinet_applet"/> <addaction name="action_Load_Album"/> <addaction name="action_Load_Mii_Edit"/> @@ -266,7 +182,6 @@ QToolButton:pressed { <property name="title"> <string>&Help</string> </property> - <addaction name="action_Report_Compatibility"/> <addaction name="action_About"/> </widget> <addaction name="menu_File"/> @@ -322,7 +237,7 @@ QToolButton:pressed { </action> <action name="action_About"> <property name="text"> - <string>&About citron</string> + <string>&About Citron</string> </property> </action> <action name="action_Single_Window_Mode"> @@ -457,7 +372,15 @@ QToolButton:pressed { </action> <action name="action_Open_citron_Folder"> <property name="text"> - <string>Open &citron Folder</string> + <string>Open &Citron Folder</string> + </property> + </action> + <action name="action_Load_Home_Menu"> + <property name="text"> + <string>Launch System Menu</string> + </property> + <property name="toolTip"> + <string>Launch the system Home Menu</string> </property> </action> <action name="action_Capture_Screenshot"> @@ -556,16 +479,6 @@ QToolButton:pressed { <string>Install Decryption Keys</string> </property> </action> - <action name="actionSave"> - <property name="text"> - <string>&Save</string> - </property> - </action> - <action name="actionLoad"> - <property name="text"> - <string>&Load</string> - </property> - </action> </widget> <resources> <include location="citron.qrc"/> diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp index 5e00f0c81..5d5e3d002 100644 --- a/src/core/hle/kernel/k_page_table_base.cpp +++ b/src/core/hle/kernel/k_page_table_base.cpp @@ -172,6 +172,7 @@ Result KPageTableBase::InitializeForKernel(bool is_64_bit, KVirtualAddress start m_mapped_unsafe_physical_memory = 0; m_mapped_insecure_memory = 0; m_mapped_ipc_server_memory = 0; + m_alias_region_extra_size = 0; m_memory_block_slab_manager = m_kernel.GetSystemSystemResource().GetMemoryBlockSlabManagerPointer(); diff --git a/src/core/hle/kernel/k_page_table_base.h b/src/core/hle/kernel/k_page_table_base.h index 939b8a7ae..1a6f90ec2 100644 --- a/src/core/hle/kernel/k_page_table_base.h +++ b/src/core/hle/kernel/k_page_table_base.h @@ -208,6 +208,7 @@ private: size_t m_mapped_unsafe_physical_memory{}; size_t m_mapped_insecure_memory{}; size_t m_mapped_ipc_server_memory{}; + size_t m_alias_region_extra_size{}; mutable KLightLock m_general_lock; mutable KLightLock m_map_physical_memory_lock; KLightLock m_device_map_lock; @@ -715,6 +716,10 @@ public: return m_address_space_width; } + size_t GetReservedRegionExtraSize() const { + return m_alias_region_extra_size; + } + public: // Linear mapped static u8* GetLinearMappedVirtualPointer(KernelCore& kernel, KPhysicalAddress addr) { diff --git a/src/core/hle/kernel/k_process_page_table.h b/src/core/hle/kernel/k_process_page_table.h index 346d7ca08..4b9942d50 100644 --- a/src/core/hle/kernel/k_process_page_table.h +++ b/src/core/hle/kernel/k_process_page_table.h @@ -472,6 +472,10 @@ public: const KPageTable& GetBasePageTable() const { return m_page_table; } + + size_t GetReservedRegionExtraSize() const { + return m_page_table.GetReservedRegionExtraSize(); + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/svc_types.h b/src/core/hle/kernel/svc_types.h index e301f67c5..e4f60d953 100644 --- a/src/core/hle/kernel/svc_types.h +++ b/src/core/hle/kernel/svc_types.h @@ -153,6 +153,7 @@ enum class InfoType : u32 { ThreadTickCount = 25, IsSvcPermitted = 26, IoRegionHint = 27, + ReservedRegionExtraSize = 28, MesosphereMeta = 65000, MesosphereCurrentProcess = 65001, @@ -643,9 +644,13 @@ enum class CreateProcessFlag : u32 { // 11.x+ DisableDeviceAddressSpaceMerge. DisableDeviceAddressSpaceMerge = (1 << 12), + // 13.x+ EnableReservedRegionExtraSize. + EnableReservedRegionExtraSize = (1 << 13), + // Mask of all flags. All = Is64Bit | AddressSpaceMask | EnableDebug | EnableAslr | IsApplication | - PoolPartitionMask | OptimizeMemoryAllocation | DisableDeviceAddressSpaceMerge, + PoolPartitionMask | OptimizeMemoryAllocation | DisableDeviceAddressSpaceMerge | + EnableReservedRegionExtraSize, }; DECLARE_ENUM_FLAG_OPERATORS(CreateProcessFlag); diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 9f40c5425..e628c025c 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -317,6 +317,10 @@ public: {1, &IProfileCommon::GetBase, "GetBase"}, {10, &IProfileCommon::GetImageSize, "GetImageSize"}, {11, &IProfileCommon::LoadImage, "LoadImage"}, + {20, &IProfileCommon::GetImageSize, "GetLargeImageSize"}, + {21, &IProfileCommon::LoadImage, "LoadLargeImage"}, + {30, &IProfileCommon::Unknown, "GetImageId"}, + {40, &IProfileCommon::GetStableUserId, "GetStableUserId"}, }; RegisterHandlers(functions); @@ -486,6 +490,20 @@ protected: rb.Push(ResultSuccess); } + void Unknown(HLERequestContext& ctx) { + LOG_WARNING(Service_ACC, "(STUBBED) called"); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(0); + } + + void GetStableUserId(HLERequestContext& ctx) { + LOG_DEBUG(Service_ACC, "called"); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(user_id.Hash()); + } + ProfileManager& profile_manager; Common::UUID user_id{}; ///< The user id this profile refers to. }; @@ -500,8 +518,13 @@ public: class IProfileEditor final : public IProfileCommon { public: explicit IProfileEditor(Core::System& system_, Common::UUID user_id_, - ProfileManager& profile_manager_) - : IProfileCommon{system_, "IProfileEditor", true, user_id_, profile_manager_} {} + ProfileManager& profile_manager_) + : IProfileCommon{system_, "IProfileEditor", true, user_id_, profile_manager_} { + static const FunctionInfo functions[] = { + {30, &IProfileEditor::Unknown, "Unknown"}, + }; + RegisterHandlers(functions); + } }; class ISessionObject final : public ServiceFramework<ISessionObject> { diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp index bc9c86c55..e44037d30 100644 --- a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp +++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp @@ -4,6 +4,7 @@ #include "core/core.h" #include "core/hle/service/am/applet_manager.h" #include "core/hle/service/am/service/all_system_applet_proxies_service.h" +#include "core/hle/service/am/service/global_state_controller.h" #include "core/hle/service/am/service/library_applet_proxy.h" #include "core/hle/service/am/service/system_applet_proxy.h" #include "core/hle/service/am/window_system.h" @@ -23,6 +24,7 @@ IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& sys {350, nullptr, "OpenSystemApplicationProxy"}, {400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"}, {410, nullptr, "GetSystemAppletControllerForDebug"}, + {450, D<&IAllSystemAppletProxiesService::GetGlobalStateController>, "GetGlobalStateController"}, {1000, nullptr, "GetDebugFunctions"}, }; // clang-format on @@ -73,6 +75,13 @@ Result IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld( this->OpenLibraryAppletProxy(out_library_applet_proxy, pid, process_handle, attribute)); } +Result IAllSystemAppletProxiesService::GetGlobalStateController( + Out<SharedPointer<IGlobalStateController>> out_controller) { + LOG_DEBUG(Service_AM, "called"); + *out_controller = std::make_shared<IGlobalStateController>(this->system); + R_SUCCEED(); +} + std::shared_ptr<Applet> IAllSystemAppletProxiesService::GetAppletFromProcessId( ProcessId process_id) { return m_window_system.GetByAppletResourceUserId(process_id.pid); diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.h b/src/core/hle/service/am/service/all_system_applet_proxies_service.h index e3e79dc4f..344d93b13 100644 --- a/src/core/hle/service/am/service/all_system_applet_proxies_service.h +++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.h @@ -5,6 +5,7 @@ #include "core/hle/service/cmif_types.h" #include "core/hle/service/service.h" +#include "core/hle/service/am/service/global_state_controller.h" namespace Service { @@ -14,6 +15,7 @@ struct Applet; struct AppletAttribute; class ILibraryAppletProxy; class ISystemAppletProxy; +class IGlobalStateController; class WindowSystem; class IAllSystemAppletProxiesService final @@ -34,7 +36,8 @@ private: Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, ClientProcessId pid, InCopyHandle<Kernel::KProcess> process_handle); -private: + Result GetGlobalStateController(Out<SharedPointer<IGlobalStateController>> out_controller); + std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid); WindowSystem& m_window_system; diff --git a/src/core/hle/service/am/service/global_state_controller.cpp b/src/core/hle/service/am/service/global_state_controller.cpp index dba5d3613..e1ffff919 100644 --- a/src/core/hle/service/am/service/global_state_controller.cpp +++ b/src/core/hle/service/am/service/global_state_controller.cpp @@ -15,8 +15,8 @@ IGlobalStateController::IGlobalStateController(Core::System& system_) {0, nullptr, "RequestToEnterSleep"}, {1, nullptr, "EnterSleep"}, {2, nullptr, "StartSleepSequence"}, - {3, nullptr, "StartShutdownSequence"}, - {4, nullptr, "StartRebootSequence"}, + {3, D<&IGlobalStateController::StartShutdownSequence>, "StartShutdownSequence"}, + {4, D<&IGlobalStateController::StartRebootSequence>, "StartRebootSequence"}, {9, nullptr, "IsAutoPowerDownRequested"}, {10, D<&IGlobalStateController::LoadAndApplyIdlePolicySettings>, "LoadAndApplyIdlePolicySettings"}, {11, nullptr, "NotifyCecSettingsChanged"}, @@ -58,4 +58,16 @@ Result IGlobalStateController::OpenCradleFirmwareUpdater( R_SUCCEED(); } +Result IGlobalStateController::StartShutdownSequence() { + LOG_INFO(Service_AM, "called"); + system.Exit(); + R_SUCCEED(); +} + +Result IGlobalStateController::StartRebootSequence() { + LOG_INFO(Service_AM, "called"); + system.Exit(); + R_SUCCEED(); +} + } // namespace Service::AM diff --git a/src/core/hle/service/am/service/global_state_controller.h b/src/core/hle/service/am/service/global_state_controller.h index 67c753513..83efb57df 100644 --- a/src/core/hle/service/am/service/global_state_controller.h +++ b/src/core/hle/service/am/service/global_state_controller.h @@ -18,6 +18,8 @@ public: ~IGlobalStateController() override; private: + Result StartShutdownSequence(); + Result StartRebootSequence(); Result LoadAndApplyIdlePolicySettings(); Result ShouldSleepOnBoot(Out<bool> out_should_sleep_on_boot); Result GetHdcpAuthenticationFailedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); diff --git a/src/core/hle/service/audio/audio_controller.cpp b/src/core/hle/service/audio/audio_controller.cpp index 300764ad6..c725e05fc 100644 --- a/src/core/hle/service/audio/audio_controller.cpp +++ b/src/core/hle/service/audio/audio_controller.cpp @@ -11,8 +11,19 @@ namespace Service::Audio { IAudioController::IAudioController(Core::System& system_) - : ServiceFramework{system_, "audctl"}, service_context{system, "audctl"} { - // clang-format off + : ServiceFramework{system_, "audctl"} + , service_context{system, "audctl"} + , m_current_output_target{1} // Initialize with default values + , m_current_parameter{0x1388} + , m_current_volume{100} { + + // Create notification event first + notification_event = service_context.CreateEvent("IAudioController:NotificationEvent"); + + // Get system settings service + m_set_sys = system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); + + // Register handlers static const FunctionInfo functions[] = { {0, nullptr, "GetTargetVolume"}, {1, nullptr, "SetTargetVolume"}, @@ -67,15 +78,15 @@ IAudioController::IAudioController(Core::System& system_) {10104, nullptr, "GetAudioOutputChannelCountForPlayReport"}, {10105, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"}, {10106, nullptr, "GetDefaultAudioOutputTargetForPlayReport"}, - {50000, nullptr, "SetAnalogInputBoostGainForPrototyping"}, + {5000, D<&IAudioController::GetSelfController>, "GetSelfController"}, + {50001, D<&IAudioController::SetAudioControllerOutput>, "SetAudioControllerOutput"}, }; - // clang-format on - RegisterHandlers(functions); - m_set_sys = - system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); - notification_event = service_context.CreateEvent("IAudioController:NotificationEvent"); + // Signal initial state + if (notification_event) { + notification_event->Signal(); + } } IAudioController::~IAudioController() { @@ -176,4 +187,34 @@ Result IAudioController::AcquireTargetNotification( R_SUCCEED(); } +Result IAudioController::SetAudioControllerOutput(u32 output_target, u32 parameter, u32 volume) { + LOG_DEBUG(Audio, "called. output_target={}, parameter={}, volume={}", output_target, parameter, volume); + + if (!notification_event) { + LOG_ERROR(Audio, "Notification event not initialized"); + R_THROW(ResultCode::ResultInvalidState); + } + + m_current_output_target = output_target; + m_current_parameter = parameter; + m_current_volume = volume; + + notification_event->Signal(); + R_SUCCEED(); +} + +Result IAudioController::GetSelfController(Out<SharedPointer<IAudioController>> out_controller) { + LOG_DEBUG(Audio, "called"); + + // Use ServiceFramework's built-in method to get a shared pointer + *out_controller = SharedPointer<IAudioController>(this); + + // Signal notification event since we're returning a new interface + if (notification_event) { + notification_event->Signal(); + } + + R_SUCCEED(); +} + } // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio_controller.h b/src/core/hle/service/audio/audio_controller.h index d37c4843e..98d7ecf89 100644 --- a/src/core/hle/service/audio/audio_controller.h +++ b/src/core/hle/service/audio/audio_controller.h @@ -6,6 +6,7 @@ #include "core/hle/service/cmif_types.h" #include "core/hle/service/service.h" #include "core/hle/service/set/settings_types.h" +#include "core/hle/result.h" namespace Core { class System; @@ -17,6 +18,10 @@ class ISystemSettingsServer; namespace Service::Audio { +namespace ResultCode { + constexpr Result ResultInvalidState{ErrorModule::Audio, 1}; +} // namespace ResultCode + class IAudioController final : public ServiceFramework<IAudioController> { public: explicit IAudioController(Core::System& system_); @@ -49,11 +54,18 @@ private: Result SetSpeakerAutoMuteEnabled(bool is_speaker_auto_mute_enabled); Result IsSpeakerAutoMuteEnabled(Out<bool> out_is_speaker_auto_mute_enabled); Result AcquireTargetNotification(OutCopyHandle<Kernel::KReadableEvent> out_notification_event); + Result SetAudioControllerOutput(u32 output_target, u32 parameter, u32 volume); + Result GetSelfController(Out<SharedPointer<IAudioController>> out_controller); KernelHelpers::ServiceContext service_context; Kernel::KEvent* notification_event; std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; + + // Add state tracking + u32 m_current_output_target{0}; + u32 m_current_parameter{0}; + u32 m_current_volume{0}; }; } // namespace Service::Audio diff --git a/src/core/hle/service/pctl/parental_control_service.cpp b/src/core/hle/service/pctl/parental_control_service.cpp index f57f2f157..3d156e87a 100644 --- a/src/core/hle/service/pctl/parental_control_service.cpp +++ b/src/core/hle/service/pctl/parental_control_service.cpp @@ -77,7 +77,7 @@ IParentalControlService::IParentalControlService(Core::System& system_, Capabili {1451, D<&IParentalControlService::StartPlayTimer>, "StartPlayTimer"}, {1452, D<&IParentalControlService::StopPlayTimer>, "StopPlayTimer"}, {1453, D<&IParentalControlService::IsPlayTimerEnabled>, "IsPlayTimerEnabled"}, - {1454, nullptr, "GetPlayTimerRemainingTime"}, + {1454, D<&IParentalControlService::GetPlayTimerRemainingTime>, "GetPlayTimerRemainingTime"}, {1455, D<&IParentalControlService::IsRestrictedByPlayTimer>, "IsRestrictedByPlayTimer"}, {1456, D<&IParentalControlService::GetPlayTimerSettings>, "GetPlayTimerSettings"}, {1457, D<&IParentalControlService::GetPlayTimerEventToRequestSuspension>, "GetPlayTimerEventToRequestSuspension"}, @@ -117,6 +117,7 @@ IParentalControlService::IParentalControlService(Core::System& system_, Capabili {2014, nullptr, "FinishSynchronizeParentalControlSettings"}, {2015, nullptr, "FinishSynchronizeParentalControlSettingsWithLastUpdated"}, {2016, nullptr, "RequestUpdateExemptionListAsync"}, + {145601, D<&IParentalControlService::GetSelfController>, "GetSelfController"}, }; // clang-format on RegisterHandlers(functions); @@ -431,4 +432,22 @@ Result IParentalControlService::ResetConfirmedStereoVisionPermission() { R_SUCCEED(); } +Result IParentalControlService::GetSelfController(Out<SharedPointer<IParentalControlService>> out_controller) { + LOG_DEBUG(Service_PCTL, "called"); + + // Return a shared pointer to this service instance + *out_controller = SharedPointer<IParentalControlService>(this); + + R_SUCCEED(); +} + +Result IParentalControlService::GetPlayTimerRemainingTime(Out<s32> out_remaining_time) { + LOG_DEBUG(Service_PCTL, "called"); + + // For now, return maximum time remaining since play timer is stubbed + *out_remaining_time = std::numeric_limits<s32>::max(); + + R_SUCCEED(); +} + } // 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 index 03dbaa2e5..121e67664 100644 --- a/src/core/hle/service/pctl/parental_control_service.h +++ b/src/core/hle/service/pctl/parental_control_service.h @@ -53,6 +53,8 @@ private: Result GetStereoVisionRestriction(Out<bool> out_stereo_vision_restriction); Result SetStereoVisionRestriction(bool stereo_vision_restriction); Result ResetConfirmedStereoVisionPermission(); + Result GetSelfController(Out<SharedPointer<IParentalControlService>> out_controller); + Result GetPlayTimerRemainingTime(Out<s32> out_remaining_time); struct States { u64 current_tid{}; |