@@ -373,7 +373,10 @@ ResultVal<AppletManager::InitializeResult> AppletManager::Initialize(AppletId ap
373
373
if (active_slot == AppletSlot::Error) {
374
374
active_slot = slot;
375
375
376
- // Wake up the application.
376
+ // APT automatically calls enable on the first registered applet.
377
+ Enable (attributes);
378
+
379
+ // Wake up the applet.
377
380
SendParameter ({
378
381
.sender_id = AppletId::None,
379
382
.destination_id = app_id,
@@ -398,7 +401,8 @@ Result AppletManager::Enable(AppletAttributes attributes) {
398
401
auto slot_data = GetAppletSlot (slot);
399
402
slot_data->registered = true ;
400
403
401
- if (slot_data->attributes .applet_pos == AppletPos::System &&
404
+ if (slot_data->applet_id != AppletId::None &&
405
+ slot_data->attributes .applet_pos == AppletPos::System &&
402
406
slot_data->attributes .is_home_menu ) {
403
407
slot_data->attributes .raw |= attributes.raw ;
404
408
LOG_DEBUG (Service_APT, " Updated home menu attributes to {:08X}." ,
@@ -786,16 +790,23 @@ Result AppletManager::PrepareToStartSystemApplet(AppletId applet_id) {
786
790
787
791
Result AppletManager::StartSystemApplet (AppletId applet_id, std::shared_ptr<Kernel::Object> object,
788
792
const std::vector<u8>& buffer) {
789
- auto source_applet_id = AppletId::None ;
793
+ auto source_applet_id = AppletId::Application ;
790
794
if (last_system_launcher_slot != AppletSlot::Error) {
791
- const auto slot_data = GetAppletSlot (last_system_launcher_slot);
792
- source_applet_id = slot_data->applet_id ;
793
-
794
- // If a system applet is launching another system applet, reset the slot to avoid conflicts.
795
- // This is needed because system applets won't necessarily call CloseSystemApplet before
796
- // exiting.
797
- if (last_system_launcher_slot == AppletSlot::SystemApplet) {
798
- slot_data->Reset ();
795
+ const auto launcher_slot_data = GetAppletSlot (last_system_launcher_slot);
796
+ source_applet_id = launcher_slot_data->applet_id ;
797
+
798
+ // APT generally clears and terminates the caller of StartSystemApplet. This helps in
799
+ // situations such as a system applet launching another system applet, which would
800
+ // otherwise deadlock.
801
+ // TODO: In real APT, the check for AppletSlot::Application does not exist; there is
802
+ // TODO: something wrong with our implementation somewhere that makes this necessary.
803
+ // TODO: Otherwise, games that attempt to launch system applets will be cleared and
804
+ // TODO: emulation will crash.
805
+ if (!launcher_slot_data->registered ||
806
+ (last_system_launcher_slot != AppletSlot::Application &&
807
+ !launcher_slot_data->attributes .no_exit_on_system_applet )) {
808
+ launcher_slot_data->Reset ();
809
+ // TODO: Implement launcher process termination.
799
810
}
800
811
}
801
812
0 commit comments