mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Merge pull request #2946 from Subv/home_menu_apt
Implement PrepareToStartNewestHomeMenu and fixed an APT regression.
This commit is contained in:
		
						commit
						7056b9c46a
					
				
					 3 changed files with 45 additions and 8 deletions
				
			
		|  | @ -65,6 +65,7 @@ union AppletAttributes { | ||||||
|     u32 raw; |     u32 raw; | ||||||
| 
 | 
 | ||||||
|     BitField<0, 3, u32> applet_pos; |     BitField<0, 3, u32> applet_pos; | ||||||
|  |     BitField<29, 1, u32> is_home_menu; | ||||||
| 
 | 
 | ||||||
|     AppletAttributes() : raw(0) {} |     AppletAttributes() : raw(0) {} | ||||||
|     AppletAttributes(u32 attributes) : raw(attributes) {} |     AppletAttributes(u32 attributes) : raw(attributes) {} | ||||||
|  | @ -158,6 +159,11 @@ static AppletSlotData* GetAppletSlotData(AppletAttributes attributes) { | ||||||
|     if (slot == AppletSlot::Error) |     if (slot == AppletSlot::Error) | ||||||
|         return nullptr; |         return nullptr; | ||||||
| 
 | 
 | ||||||
|  |     // The Home Menu is a system applet, however, it has its own applet slot so that it can run
 | ||||||
|  |     // concurrently with other system applets.
 | ||||||
|  |     if (slot == AppletSlot::SystemApplet && attributes.is_home_menu) | ||||||
|  |         return &applet_slots[static_cast<size_t>(AppletSlot::HomeMenu)]; | ||||||
|  | 
 | ||||||
|     return &applet_slots[static_cast<size_t>(slot)]; |     return &applet_slots[static_cast<size_t>(slot)]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -197,6 +203,19 @@ void Initialize(Service::Interface* self) { | ||||||
|     rb.Push(RESULT_SUCCESS); |     rb.Push(RESULT_SUCCESS); | ||||||
|     rb.PushCopyHandles(Kernel::g_handle_table.Create(slot_data->notification_event).Unwrap(), |     rb.PushCopyHandles(Kernel::g_handle_table.Create(slot_data->notification_event).Unwrap(), | ||||||
|                        Kernel::g_handle_table.Create(slot_data->parameter_event).Unwrap()); |                        Kernel::g_handle_table.Create(slot_data->parameter_event).Unwrap()); | ||||||
|  | 
 | ||||||
|  |     if (slot_data->applet_id == AppletId::Application || | ||||||
|  |         slot_data->applet_id == AppletId::HomeMenu) { | ||||||
|  |         // Initialize the APT parameter to wake up the application.
 | ||||||
|  |         next_parameter.emplace(); | ||||||
|  |         next_parameter->signal = static_cast<u32>(SignalType::Wakeup); | ||||||
|  |         next_parameter->sender_id = static_cast<u32>(AppletId::None); | ||||||
|  |         next_parameter->destination_id = app_id; | ||||||
|  |         // Not signaling the parameter event will cause the application (or Home Menu) to hang
 | ||||||
|  |         // during startup. In the real console, it is usually the Kernel and Home Menu who cause NS
 | ||||||
|  |         // to signal the HomeMenu and Application parameter events, respectively.
 | ||||||
|  |         slot_data->parameter_event->Signal(); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static u32 DecompressLZ11(const u8* in, u8* out) { | static u32 DecompressLZ11(const u8* in, u8* out) { | ||||||
|  | @ -757,6 +776,20 @@ void PrepareToStartLibraryApplet(Service::Interface* self) { | ||||||
|     LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); |     LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void PrepareToStartNewestHomeMenu(Service::Interface* self) { | ||||||
|  |     IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1A, 0, 0); // 0x1A0000
 | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|  | 
 | ||||||
|  |     // TODO(Subv): This command can only be called by a System Applet (return 0xC8A0CC04 otherwise).
 | ||||||
|  | 
 | ||||||
|  |     // This command must return an error when called, otherwise the Home Menu will try to reboot the
 | ||||||
|  |     // system.
 | ||||||
|  |     rb.Push(ResultCode(ErrorDescription::AlreadyExists, ErrorModule::Applet, | ||||||
|  |                        ErrorSummary::InvalidState, ErrorLevel::Status)); | ||||||
|  | 
 | ||||||
|  |     LOG_DEBUG(Service_APT, "called"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void PreloadLibraryApplet(Service::Interface* self) { | void PreloadLibraryApplet(Service::Interface* self) { | ||||||
|     IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x16, 1, 0); // 0x160040
 |     IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x16, 1, 0); // 0x160040
 | ||||||
|     AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>()); |     AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>()); | ||||||
|  | @ -1041,12 +1074,6 @@ void Init() { | ||||||
|         slot_data.parameter_event = |         slot_data.parameter_event = | ||||||
|             Kernel::Event::Create(Kernel::ResetType::OneShot, "APT:Parameter"); |             Kernel::Event::Create(Kernel::ResetType::OneShot, "APT:Parameter"); | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     // Initialize the parameter to wake up the application.
 |  | ||||||
|     next_parameter.emplace(); |  | ||||||
|     next_parameter->signal = static_cast<u32>(SignalType::Wakeup); |  | ||||||
|     next_parameter->destination_id = static_cast<u32>(AppletId::Application); |  | ||||||
|     applet_slots[static_cast<size_t>(AppletSlot::Application)].parameter_event->Signal(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Shutdown() { | void Shutdown() { | ||||||
|  |  | ||||||
|  | @ -419,6 +419,16 @@ void GetAppCpuTimeLimit(Service::Interface* self); | ||||||
|  */ |  */ | ||||||
| void PrepareToStartLibraryApplet(Service::Interface* self); | void PrepareToStartLibraryApplet(Service::Interface* self); | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * APT::PrepareToStartNewestHomeMenu service function | ||||||
|  |  *  Inputs: | ||||||
|  |  *      0 : Command header [0x001A0000] | ||||||
|  |  *  Outputs: | ||||||
|  |  *      0 : Return header | ||||||
|  |  *      1 : Result of function | ||||||
|  |  */ | ||||||
|  | void PrepareToStartNewestHomeMenu(Service::Interface* self); | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * APT::PreloadLibraryApplet service function |  * APT::PreloadLibraryApplet service function | ||||||
|  *  Inputs: |  *  Inputs: | ||||||
|  |  | ||||||
|  | @ -17,7 +17,7 @@ const Interface::FunctionInfo FunctionTable[] = { | ||||||
|     {0x00060040, GetAppletInfo, "GetAppletInfo"}, |     {0x00060040, GetAppletInfo, "GetAppletInfo"}, | ||||||
|     {0x00070000, nullptr, "GetLastSignaledAppletId"}, |     {0x00070000, nullptr, "GetLastSignaledAppletId"}, | ||||||
|     {0x00080000, nullptr, "CountRegisteredApplet"}, |     {0x00080000, nullptr, "CountRegisteredApplet"}, | ||||||
|     {0x00090040, nullptr, "IsRegistered"}, |     {0x00090040, IsRegistered, "IsRegistered"}, | ||||||
|     {0x000A0040, nullptr, "GetAttribute"}, |     {0x000A0040, nullptr, "GetAttribute"}, | ||||||
|     {0x000B0040, InquireNotification, "InquireNotification"}, |     {0x000B0040, InquireNotification, "InquireNotification"}, | ||||||
|     {0x000C0104, nullptr, "SendParameter"}, |     {0x000C0104, nullptr, "SendParameter"}, | ||||||
|  | @ -34,7 +34,7 @@ const Interface::FunctionInfo FunctionTable[] = { | ||||||
|     {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, |     {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, | ||||||
|     {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, |     {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, | ||||||
|     {0x00190040, nullptr, "PrepareToStartSystemApplet"}, |     {0x00190040, nullptr, "PrepareToStartSystemApplet"}, | ||||||
|     {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"}, |     {0x001A0000, PrepareToStartNewestHomeMenu, "PrepareToStartNewestHomeMenu"}, | ||||||
|     {0x001B00C4, nullptr, "StartApplication"}, |     {0x001B00C4, nullptr, "StartApplication"}, | ||||||
|     {0x001C0000, nullptr, "WakeupApplication"}, |     {0x001C0000, nullptr, "WakeupApplication"}, | ||||||
|     {0x001D0000, nullptr, "CancelApplication"}, |     {0x001D0000, nullptr, "CancelApplication"}, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue