Services/APT: Better implementation of PrepareToDoApplicationJump and DoApplicationJump.

The real console can't launch an Application directly from within another Application so it has to go through the Home Menu. We do not have such limitation and can directly launch the requested title.
This commit is contained in:
Subv
2018-10-05 12:03:27 -05:00
parent b163502744
commit 8ec2a9817c
7 changed files with 193 additions and 51 deletions

View File

@ -394,6 +394,54 @@ void Module::Interface::CancelParameter(Kernel::HLERequestContext& ctx) {
static_cast<u32>(receiver_appid));
}
void Module::Interface::PrepareToDoApplicationJump(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x31, 4, 0); // 0x00310100
auto flags = rp.PopEnum<ApplicationJumpFlags>();
u64 title_id = rp.Pop<u64>();
u8 media_type = rp.Pop<u8>();
LOG_WARNING(Service_APT, "(STUBBED) called title_id={:016X}, media_type={:#01X}, flags={:#08X}",
title_id, media_type, static_cast<u8>(flags));
ResultCode result = apt->applet_manager->PrepareToDoApplicationJump(
title_id, static_cast<FS::MediaType>(media_type), flags);
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(result);
}
void Module::Interface::DoApplicationJump(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x32, 2, 4); // 0x00320084
u32 param_size = rp.Pop<u32>();
u32 hmac_size = rp.Pop<u32>();
auto param = rp.PopStaticBuffer();
auto hmac = rp.PopStaticBuffer();
LOG_WARNING(Service_APT, "(STUBBED) called param_size={:08X}, hmac_size={:08X}", param_size,
hmac_size);
// TODO(Subv): Set the delivery parameters before starting the new application.
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(apt->applet_manager->DoApplicationJump());
}
void Module::Interface::GetProgramIdOnApplicationJump(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x33, 0, 0); // 0x00330000
LOG_DEBUG(Service_APT, "called");
auto parameters = apt->applet_manager->GetApplicationJumpParameters();
IPC::RequestBuilder rb = rp.MakeBuilder(7, 0);
rb.Push(RESULT_SUCCESS);
rb.Push<u64>(parameters.current_title_id);
rb.Push(static_cast<u8>(parameters.current_media_type));
rb.Push<u64>(parameters.next_title_id);
rb.Push(static_cast<u8>(parameters.next_media_type));
}
void Module::Interface::PrepareToStartApplication(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x15, 5, 0); // 0x00150140
u32 title_info1 = rp.Pop<u32>();
@ -550,51 +598,6 @@ void Module::Interface::CloseApplication(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
}
void Module::Interface::PrepareToDoApplicationJump(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x31, 4, 0);
u32 flags = rp.Pop<u8>();
u32 program_id_low = rp.Pop<u32>();
u32 program_id_high = rp.Pop<u32>();
Service::FS::MediaType media_type = static_cast<Service::FS::MediaType>(rp.Pop<u8>());
LOG_WARNING(Service_APT,
"(STUBBED) called, flags={:08X}, program_id_low={:08X}, program_id_high={:08X}, "
"media_type={:08X}",
flags, program_id_low, program_id_high, static_cast<u8>(media_type));
if (flags == 0x2) {
// It seems that flags 0x2 means jumping to the same application,
// and ignore the parameters. This is used in Pokemon main series
// to soft reset.
application_reset_prepared = true;
}
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
}
void Module::Interface::DoApplicationJump(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x32, 2, 4);
u32 parameter_size = rp.Pop<u32>();
u32 hmac_size = rp.Pop<u32>();
std::vector<u8> parameter = rp.PopStaticBuffer();
std::vector<u8> hmac = rp.PopStaticBuffer();
LOG_WARNING(Service_APT, "(STUBBED) called");
if (application_reset_prepared) {
// Reset system
apt->system.RequestReset();
} else {
// After the jump, the application should shutdown
// TODO: Actually implement the jump
apt->system.RequestShutdown();
}
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
}
void Module::Interface::CancelLibraryApplet(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x3B, 1, 0); // 0x003B0040
bool exiting = rp.Pop<bool>();
@ -844,7 +847,7 @@ Module::Interface::Interface(std::shared_ptr<Module> apt, const char* name, u32
Module::Interface::~Interface() = default;
Module::Module(Core::System& system) : system(system) {
applet_manager = std::make_shared<AppletManager>();
applet_manager = std::make_shared<AppletManager>(system);
using Kernel::MemoryPermission;
shared_font_mem =