mirror of
https://github.com/PabloMK7/citra
synced 2024-11-15 05:08:23 +00:00
Merge pull request #4306 from Subv/apt_jump
Services/APT: Better implementation of PrepareToDoApplicationJump and DoApplicationJump.
This commit is contained in:
commit
f405134913
7 changed files with 193 additions and 51 deletions
|
@ -3,6 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "common/common_paths.h"
|
#include "common/common_paths.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/hle/applets/applet.h"
|
#include "core/hle/applets/applet.h"
|
||||||
#include "core/hle/service/apt/applet_manager.h"
|
#include "core/hle/service/apt/applet_manager.h"
|
||||||
#include "core/hle/service/apt/errors.h"
|
#include "core/hle/service/apt/errors.h"
|
||||||
|
@ -255,6 +256,9 @@ ResultVal<AppletManager::InitializeResult> AppletManager::Initialize(AppletId ap
|
||||||
}
|
}
|
||||||
|
|
||||||
slot_data->applet_id = static_cast<AppletId>(app_id);
|
slot_data->applet_id = static_cast<AppletId>(app_id);
|
||||||
|
// Note: In the real console the title id of a given applet slot is set by the APT module when
|
||||||
|
// calling StartApplication.
|
||||||
|
slot_data->title_id = Kernel::g_current_process->codeset->program_id;
|
||||||
slot_data->attributes.raw = attributes.raw;
|
slot_data->attributes.raw = attributes.raw;
|
||||||
|
|
||||||
if (slot_data->applet_id == AppletId::Application ||
|
if (slot_data->applet_id == AppletId::Application ||
|
||||||
|
@ -465,7 +469,94 @@ ResultVal<AppletManager::AppletInfo> AppletManager::GetAppletInfo(AppletId app_i
|
||||||
slot->registered, slot->loaded, slot->attributes.raw});
|
slot->registered, slot->loaded, slot->attributes.raw});
|
||||||
}
|
}
|
||||||
|
|
||||||
AppletManager::AppletManager() {
|
ResultCode AppletManager::PrepareToDoApplicationJump(u64 title_id, FS::MediaType media_type,
|
||||||
|
ApplicationJumpFlags flags) {
|
||||||
|
// A running application can not launch another application directly because the applet state
|
||||||
|
// for the Application slot is already in use. The way this is implemented in hardware is to
|
||||||
|
// launch the Home Menu and tell it to launch our desired application.
|
||||||
|
|
||||||
|
// Save the title data to send it to the Home Menu when DoApplicationJump is called.
|
||||||
|
const auto& application_slot = applet_slots[static_cast<size_t>(AppletSlot::Application)];
|
||||||
|
|
||||||
|
ASSERT_MSG(flags != ApplicationJumpFlags::UseStoredParameters,
|
||||||
|
"Unimplemented application jump flags 1");
|
||||||
|
|
||||||
|
if (flags == ApplicationJumpFlags::UseCurrentParameters) {
|
||||||
|
title_id = application_slot.title_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
app_jump_parameters.current_title_id = application_slot.title_id;
|
||||||
|
// TODO(Subv): Retrieve the correct media type of the currently-running application. For now
|
||||||
|
// just assume NAND.
|
||||||
|
app_jump_parameters.current_media_type = FS::MediaType::NAND;
|
||||||
|
app_jump_parameters.next_title_id = title_id;
|
||||||
|
app_jump_parameters.next_media_type = media_type;
|
||||||
|
|
||||||
|
// Note: The real console uses the Home Menu to perform the application jump, therefore the menu
|
||||||
|
// needs to be running. The real APT module starts the Home Menu here if it's not already
|
||||||
|
// running, we don't have to do this. See `EnsureHomeMenuLoaded` for launching the Home Menu.
|
||||||
|
return RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultCode AppletManager::DoApplicationJump() {
|
||||||
|
// Note: The real console uses the Home Menu to perform the application jump, it goes
|
||||||
|
// OldApplication->Home Menu->NewApplication. We do not need to use the Home Menu to do this so
|
||||||
|
// we launch the new application directly. In the real APT service, the Home Menu must be
|
||||||
|
// running to do this, otherwise error 0xC8A0CFF0 is returned.
|
||||||
|
|
||||||
|
auto& application_slot = applet_slots[static_cast<size_t>(AppletSlot::Application)];
|
||||||
|
application_slot.Reset();
|
||||||
|
|
||||||
|
// TODO(Subv): Set the delivery parameters.
|
||||||
|
|
||||||
|
// TODO(Subv): Terminate the current Application.
|
||||||
|
|
||||||
|
// Note: The real console sends signal 17 (WakeupToLaunchApplication) to the Home Menu, this
|
||||||
|
// prompts it to call GetProgramIdOnApplicationJump and
|
||||||
|
// PrepareToStartApplication/StartApplication on the title to launch.
|
||||||
|
|
||||||
|
if (app_jump_parameters.next_title_id == app_jump_parameters.current_title_id) {
|
||||||
|
// Perform a soft-reset if we're trying to relaunch the same title.
|
||||||
|
// TODO(Subv): Note that this reboots the entire emulated system, a better way would be to
|
||||||
|
// simply re-launch the title without closing all services, but this would only work for
|
||||||
|
// installed titles since we have no way of getting the file path of an arbitrary game dump
|
||||||
|
// based only on the title id.
|
||||||
|
system.RequestReset();
|
||||||
|
return RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Launch the title directly.
|
||||||
|
auto process =
|
||||||
|
NS::LaunchTitle(app_jump_parameters.next_media_type, app_jump_parameters.next_title_id);
|
||||||
|
if (!process) {
|
||||||
|
LOG_CRITICAL(Service_APT, "Failed to launch title during application jump, exiting.");
|
||||||
|
system.RequestShutdown();
|
||||||
|
}
|
||||||
|
return RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppletManager::EnsureHomeMenuLoaded() {
|
||||||
|
const auto& system_slot = applet_slots[static_cast<size_t>(AppletSlot::SystemApplet)];
|
||||||
|
// TODO(Subv): The real APT service sends signal 12 (WakeupByCancel) to the currently running
|
||||||
|
// System applet, waits for it to finish, and then launches the Home Menu.
|
||||||
|
ASSERT_MSG(!system_slot.registered, "A system applet is already running");
|
||||||
|
|
||||||
|
const auto& menu_slot = applet_slots[static_cast<size_t>(AppletSlot::HomeMenu)];
|
||||||
|
|
||||||
|
if (menu_slot.registered) {
|
||||||
|
// The Home Menu is already running.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 menu_title_id = GetTitleIdForApplet(AppletId::HomeMenu);
|
||||||
|
auto process = NS::LaunchTitle(FS::MediaType::NAND, menu_title_id);
|
||||||
|
if (!process) {
|
||||||
|
LOG_WARNING(Service_APT,
|
||||||
|
"The Home Menu failed to launch, application jumping will not work.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AppletManager::AppletManager(Core::System& system) : system(system) {
|
||||||
for (std::size_t slot = 0; slot < applet_slots.size(); ++slot) {
|
for (std::size_t slot = 0; slot < applet_slots.size(); ++slot) {
|
||||||
auto& slot_data = applet_slots[slot];
|
auto& slot_data = applet_slots[slot];
|
||||||
slot_data.slot = static_cast<AppletSlot>(slot);
|
slot_data.slot = static_cast<AppletSlot>(slot);
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
#include "core/hle/service/fs/archive.h"
|
#include "core/hle/service/fs/archive.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Service::APT {
|
namespace Service::APT {
|
||||||
|
|
||||||
/// Signals used by APT functions
|
/// Signals used by APT functions
|
||||||
|
@ -97,9 +101,15 @@ union AppletAttributes {
|
||||||
AppletAttributes(u32 attributes) : raw(attributes) {}
|
AppletAttributes(u32 attributes) : raw(attributes) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ApplicationJumpFlags : u8 {
|
||||||
|
UseInputParameters = 0,
|
||||||
|
UseStoredParameters = 1,
|
||||||
|
UseCurrentParameters = 2
|
||||||
|
};
|
||||||
|
|
||||||
class AppletManager : public std::enable_shared_from_this<AppletManager> {
|
class AppletManager : public std::enable_shared_from_this<AppletManager> {
|
||||||
public:
|
public:
|
||||||
AppletManager();
|
explicit AppletManager(Core::System& system);
|
||||||
~AppletManager();
|
~AppletManager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -130,6 +140,10 @@ public:
|
||||||
ResultCode PrepareToCloseLibraryApplet(bool not_pause, bool exiting, bool jump_home);
|
ResultCode PrepareToCloseLibraryApplet(bool not_pause, bool exiting, bool jump_home);
|
||||||
ResultCode CloseLibraryApplet(Kernel::SharedPtr<Kernel::Object> object, std::vector<u8> buffer);
|
ResultCode CloseLibraryApplet(Kernel::SharedPtr<Kernel::Object> object, std::vector<u8> buffer);
|
||||||
|
|
||||||
|
ResultCode PrepareToDoApplicationJump(u64 title_id, FS::MediaType media_type,
|
||||||
|
ApplicationJumpFlags flags);
|
||||||
|
ResultCode DoApplicationJump();
|
||||||
|
|
||||||
struct AppletInfo {
|
struct AppletInfo {
|
||||||
u64 title_id;
|
u64 title_id;
|
||||||
Service::FS::MediaType media_type;
|
Service::FS::MediaType media_type;
|
||||||
|
@ -140,6 +154,18 @@ public:
|
||||||
|
|
||||||
ResultVal<AppletInfo> GetAppletInfo(AppletId app_id);
|
ResultVal<AppletInfo> GetAppletInfo(AppletId app_id);
|
||||||
|
|
||||||
|
struct ApplicationJumpParameters {
|
||||||
|
u64 next_title_id;
|
||||||
|
FS::MediaType next_media_type;
|
||||||
|
|
||||||
|
u64 current_title_id;
|
||||||
|
FS::MediaType current_media_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
ApplicationJumpParameters GetApplicationJumpParameters() const {
|
||||||
|
return app_jump_parameters;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Parameter data to be returned in the next call to Glance/ReceiveParameter.
|
/// Parameter data to be returned in the next call to Glance/ReceiveParameter.
|
||||||
/// TODO(Subv): Use std::optional once we migrate to C++17.
|
/// TODO(Subv): Use std::optional once we migrate to C++17.
|
||||||
|
@ -160,6 +186,7 @@ private:
|
||||||
struct AppletSlotData {
|
struct AppletSlotData {
|
||||||
AppletId applet_id;
|
AppletId applet_id;
|
||||||
AppletSlot slot;
|
AppletSlot slot;
|
||||||
|
u64 title_id;
|
||||||
bool registered;
|
bool registered;
|
||||||
bool loaded;
|
bool loaded;
|
||||||
AppletAttributes attributes;
|
AppletAttributes attributes;
|
||||||
|
@ -169,10 +196,13 @@ private:
|
||||||
void Reset() {
|
void Reset() {
|
||||||
applet_id = AppletId::None;
|
applet_id = AppletId::None;
|
||||||
registered = false;
|
registered = false;
|
||||||
|
title_id = 0;
|
||||||
attributes.raw = 0;
|
attributes.raw = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ApplicationJumpParameters app_jump_parameters{};
|
||||||
|
|
||||||
// Holds data about the concurrently running applets in the system.
|
// Holds data about the concurrently running applets in the system.
|
||||||
std::array<AppletSlotData, NumAppletSlot> applet_slots = {};
|
std::array<AppletSlotData, NumAppletSlot> applet_slots = {};
|
||||||
|
|
||||||
|
@ -180,8 +210,12 @@ private:
|
||||||
AppletSlotData* GetAppletSlotData(AppletId id);
|
AppletSlotData* GetAppletSlotData(AppletId id);
|
||||||
AppletSlotData* GetAppletSlotData(AppletAttributes attributes);
|
AppletSlotData* GetAppletSlotData(AppletAttributes attributes);
|
||||||
|
|
||||||
|
void EnsureHomeMenuLoaded();
|
||||||
|
|
||||||
// Command that will be sent to the application when a library applet calls CloseLibraryApplet.
|
// Command that will be sent to the application when a library applet calls CloseLibraryApplet.
|
||||||
SignalType library_applet_closing_command;
|
SignalType library_applet_closing_command;
|
||||||
|
|
||||||
|
Core::System& system;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::APT
|
} // namespace Service::APT
|
||||||
|
|
|
@ -394,6 +394,54 @@ void Module::Interface::CancelParameter(Kernel::HLERequestContext& ctx) {
|
||||||
static_cast<u32>(receiver_appid));
|
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) {
|
void Module::Interface::PrepareToStartApplication(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp(ctx, 0x15, 5, 0); // 0x00150140
|
IPC::RequestParser rp(ctx, 0x15, 5, 0); // 0x00150140
|
||||||
u32 title_info1 = rp.Pop<u32>();
|
u32 title_info1 = rp.Pop<u32>();
|
||||||
|
@ -550,51 +598,6 @@ void Module::Interface::CloseApplication(Kernel::HLERequestContext& ctx) {
|
||||||
rb.Push(RESULT_SUCCESS);
|
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) {
|
void Module::Interface::CancelLibraryApplet(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp(ctx, 0x3B, 1, 0); // 0x003B0040
|
IPC::RequestParser rp(ctx, 0x3B, 1, 0); // 0x003B0040
|
||||||
bool exiting = rp.Pop<bool>();
|
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::Interface::~Interface() = default;
|
||||||
|
|
||||||
Module::Module(Core::System& system) : system(system) {
|
Module::Module(Core::System& system) : system(system) {
|
||||||
applet_manager = std::make_shared<AppletManager>();
|
applet_manager = std::make_shared<AppletManager>(system);
|
||||||
|
|
||||||
using Kernel::MemoryPermission;
|
using Kernel::MemoryPermission;
|
||||||
shared_font_mem =
|
shared_font_mem =
|
||||||
|
|
|
@ -455,6 +455,20 @@ public:
|
||||||
*/
|
*/
|
||||||
void DoApplicationJump(Kernel::HLERequestContext& ctx);
|
void DoApplicationJump(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::GetProgramIdOnApplicationJump service function
|
||||||
|
* Inputs:
|
||||||
|
* 0 : Command header [0x00330000]
|
||||||
|
* Outputs:
|
||||||
|
* 0 : Return header
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
* 2-3 : Current Application title id
|
||||||
|
* 4 : Current Application media type
|
||||||
|
* 5-6 : Next Application title id to jump to
|
||||||
|
* 7 : Next Application media type
|
||||||
|
*/
|
||||||
|
void GetProgramIdOnApplicationJump(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APT::CancelLibraryApplet service function
|
* APT::CancelLibraryApplet service function
|
||||||
* Inputs:
|
* Inputs:
|
||||||
|
|
|
@ -59,7 +59,7 @@ APT_A::APT_A(std::shared_ptr<Module> apt)
|
||||||
{0x00300044, nullptr, "LeaveResidentApplet"},
|
{0x00300044, nullptr, "LeaveResidentApplet"},
|
||||||
{0x00310100, &APT_A::PrepareToDoApplicationJump, "PrepareToDoApplicationJump"},
|
{0x00310100, &APT_A::PrepareToDoApplicationJump, "PrepareToDoApplicationJump"},
|
||||||
{0x00320084, &APT_A::DoApplicationJump, "DoApplicationJump"},
|
{0x00320084, &APT_A::DoApplicationJump, "DoApplicationJump"},
|
||||||
{0x00330000, nullptr, "GetProgramIdOnApplicationJump"},
|
{0x00330000, &APT_A::GetProgramIdOnApplicationJump, "GetProgramIdOnApplicationJump"},
|
||||||
{0x00340084, nullptr, "SendDeliverArg"},
|
{0x00340084, nullptr, "SendDeliverArg"},
|
||||||
{0x00350080, nullptr, "ReceiveDeliverArg"},
|
{0x00350080, nullptr, "ReceiveDeliverArg"},
|
||||||
{0x00360040, nullptr, "LoadSysMenuArg"},
|
{0x00360040, nullptr, "LoadSysMenuArg"},
|
||||||
|
|
|
@ -59,7 +59,7 @@ APT_S::APT_S(std::shared_ptr<Module> apt)
|
||||||
{0x00300044, nullptr, "LeaveResidentApplet"},
|
{0x00300044, nullptr, "LeaveResidentApplet"},
|
||||||
{0x00310100, &APT_S::PrepareToDoApplicationJump, "PrepareToDoApplicationJump"},
|
{0x00310100, &APT_S::PrepareToDoApplicationJump, "PrepareToDoApplicationJump"},
|
||||||
{0x00320084, &APT_S::DoApplicationJump, "DoApplicationJump"},
|
{0x00320084, &APT_S::DoApplicationJump, "DoApplicationJump"},
|
||||||
{0x00330000, nullptr, "GetProgramIdOnApplicationJump"},
|
{0x00330000, &APT_S::GetProgramIdOnApplicationJump, "GetProgramIdOnApplicationJump"},
|
||||||
{0x00340084, nullptr, "SendDeliverArg"},
|
{0x00340084, nullptr, "SendDeliverArg"},
|
||||||
{0x00350080, nullptr, "ReceiveDeliverArg"},
|
{0x00350080, nullptr, "ReceiveDeliverArg"},
|
||||||
{0x00360040, nullptr, "LoadSysMenuArg"},
|
{0x00360040, nullptr, "LoadSysMenuArg"},
|
||||||
|
|
|
@ -59,7 +59,7 @@ APT_U::APT_U(std::shared_ptr<Module> apt)
|
||||||
{0x00300044, nullptr, "LeaveResidentApplet"},
|
{0x00300044, nullptr, "LeaveResidentApplet"},
|
||||||
{0x00310100, &APT_U::PrepareToDoApplicationJump, "PrepareToDoApplicationJump"},
|
{0x00310100, &APT_U::PrepareToDoApplicationJump, "PrepareToDoApplicationJump"},
|
||||||
{0x00320084, &APT_U::DoApplicationJump, "DoApplicationJump"},
|
{0x00320084, &APT_U::DoApplicationJump, "DoApplicationJump"},
|
||||||
{0x00330000, nullptr, "GetProgramIdOnApplicationJump"},
|
{0x00330000, &APT_U::GetProgramIdOnApplicationJump, "GetProgramIdOnApplicationJump"},
|
||||||
{0x00340084, nullptr, "SendDeliverArg"},
|
{0x00340084, nullptr, "SendDeliverArg"},
|
||||||
{0x00350080, nullptr, "ReceiveDeliverArg"},
|
{0x00350080, nullptr, "ReceiveDeliverArg"},
|
||||||
{0x00360040, nullptr, "LoadSysMenuArg"},
|
{0x00360040, nullptr, "LoadSysMenuArg"},
|
||||||
|
|
Loading…
Reference in a new issue