mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-25 13:30:15 +00:00
Update the code of APT service(part2)
This commit is contained in:
parent
04a2cb01cf
commit
5cfd37225a
@ -17,6 +17,7 @@
|
|||||||
/// Detailed description of the error. This listing is likely incomplete.
|
/// Detailed description of the error. This listing is likely incomplete.
|
||||||
enum class ErrorDescription : u32 {
|
enum class ErrorDescription : u32 {
|
||||||
Success = 0,
|
Success = 0,
|
||||||
|
InvalidMemoryPermissions = 2,
|
||||||
WrongPermission = 46,
|
WrongPermission = 46,
|
||||||
OS_InvalidBufferDescriptor = 48,
|
OS_InvalidBufferDescriptor = 48,
|
||||||
WrongAddress = 53,
|
WrongAddress = 53,
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
|
||||||
#include "core/hle/applets/applet.h"
|
#include "core/hle/applets/applet.h"
|
||||||
|
#include "core/hle/config_mem.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
#include "core/hle/service/apt/apt.h"
|
#include "core/hle/service/apt/apt.h"
|
||||||
#include "core/hle/service/apt/apt_a.h"
|
#include "core/hle/service/apt/apt_a.h"
|
||||||
@ -14,6 +15,7 @@
|
|||||||
#include "core/hle/service/apt/apt_u.h"
|
#include "core/hle/service/apt/apt_u.h"
|
||||||
#include "core/hle/service/apt/bcfnt/bcfnt.h"
|
#include "core/hle/service/apt/bcfnt/bcfnt.h"
|
||||||
#include "core/hle/service/fs/archive.h"
|
#include "core/hle/service/fs/archive.h"
|
||||||
|
#include "core/hle/service/gsp_gpu.h"
|
||||||
#include "core/hle/service/ptm/ptm.h"
|
#include "core/hle/service/ptm/ptm.h"
|
||||||
|
|
||||||
#include "core/hle/kernel/event.h"
|
#include "core/hle/kernel/event.h"
|
||||||
@ -21,6 +23,9 @@
|
|||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
#include "core/hle/kernel/shared_memory.h"
|
#include "core/hle/kernel/shared_memory.h"
|
||||||
|
|
||||||
|
#include "core/hw/gpu.h"
|
||||||
|
#include "core/settings.h"
|
||||||
|
|
||||||
namespace Service {
|
namespace Service {
|
||||||
namespace APT {
|
namespace APT {
|
||||||
|
|
||||||
@ -33,6 +38,13 @@ static Kernel::SharedPtr<Kernel::Event> notification_event; ///< APT notificatio
|
|||||||
static Kernel::SharedPtr<Kernel::Event> parameter_event; ///< APT parameter event
|
static Kernel::SharedPtr<Kernel::Event> parameter_event; ///< APT parameter event
|
||||||
|
|
||||||
static u32 cpu_percent; ///< CPU time available to the running application
|
static u32 cpu_percent; ///< CPU time available to the running application
|
||||||
|
static u32 homemenu_input_buffer;
|
||||||
|
static bool is_capture_buffer_info_set = false;
|
||||||
|
static bool is_homemenu_input_buffer_set = false;
|
||||||
|
|
||||||
|
static AppletPreparationState applet_preparation_state = AppletPreparationState::NoPreparation;
|
||||||
|
static CaptureBufferInfo capture_buffer_info;
|
||||||
|
static WirelessRebootInfo wireless_reboot_info;
|
||||||
|
|
||||||
// APT::CheckNew3DSApp will check this unknown_ns_state_field to determine processing mode
|
// APT::CheckNew3DSApp will check this unknown_ns_state_field to determine processing mode
|
||||||
static u8 unknown_ns_state_field;
|
static u8 unknown_ns_state_field;
|
||||||
@ -41,6 +53,46 @@ static ScreencapPostPermission screen_capture_post_permission;
|
|||||||
|
|
||||||
/// Parameter data to be returned in the next call to Glance/ReceiveParameter
|
/// Parameter data to be returned in the next call to Glance/ReceiveParameter
|
||||||
static MessageParameter next_parameter;
|
static MessageParameter next_parameter;
|
||||||
|
static std::array<MessageParameter, 0x4> MessageParameters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetMessageParametersIndex(sub_10F564)
|
||||||
|
* Index 0 :
|
||||||
|
* 0x300 : Application
|
||||||
|
* Index 1 :
|
||||||
|
* 0x11X : System Applet
|
||||||
|
* Index 2 :
|
||||||
|
* 0x10X : Home Menu
|
||||||
|
* Index 3 :
|
||||||
|
* 0x2XX : Library Applet
|
||||||
|
* 0x4XX : Library Applet
|
||||||
|
*/
|
||||||
|
static u32 GetMessageParametersIndex(const u32& app_id) {
|
||||||
|
u32 result = 0;
|
||||||
|
if (!(app_id & 0xFF)) {
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
} else {
|
||||||
|
if (app_id == 0x101 || app_id == 0x103) {
|
||||||
|
if (app_id & 0x100) {
|
||||||
|
return 0x2;
|
||||||
|
}
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
if ((app_id & 0x300) != app_id) {
|
||||||
|
if ((app_id & 0x110) != app_id) {
|
||||||
|
if ((app_id & 0x100) != app_id) {
|
||||||
|
if ((app_id & 0x200) != app_id && (app_id & 0x400) != app_id) {
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SendParameter(const MessageParameter& parameter) {
|
void SendParameter(const MessageParameter& parameter) {
|
||||||
next_parameter = parameter;
|
next_parameter = parameter;
|
||||||
@ -48,6 +100,16 @@ void SendParameter(const MessageParameter& parameter) {
|
|||||||
parameter_event->Signal();
|
parameter_event->Signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SendParameter(const u32& dst_app_id, const MessageParameter& parameter) {
|
||||||
|
u32 index = GetMessageParametersIndex(dst_app_id);
|
||||||
|
if(index != 0xFFFFFFFF){
|
||||||
|
memcpy(&MessageParameters[index], ¶meter, sizeof(MessageParameter));
|
||||||
|
}
|
||||||
|
// Signal the event to let the application know that a new parameter is ready to be read
|
||||||
|
parameter_event->Signal();
|
||||||
|
}
|
||||||
|
|
||||||
void Initialize(Service::Interface* self) {
|
void Initialize(Service::Interface* self) {
|
||||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
u32 app_id = cmd_buff[1];
|
u32 app_id = cmd_buff[1];
|
||||||
@ -100,11 +162,213 @@ void GetSharedFont(Service::Interface* self) {
|
|||||||
cmd_buff[4] = Kernel::g_handle_table.Create(shared_font_mem).MoveFrom();
|
cmd_buff[4] = Kernel::g_handle_table.Create(shared_font_mem).MoveFrom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GetWirelessRebootInfo(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
u32 buffer_size = cmd_buff[1];
|
||||||
|
VAddr buffer_addr = cmd_buff[0x41];
|
||||||
|
|
||||||
|
if (buffer_size > sizeof(WirelessRebootInfo)) {
|
||||||
|
buffer_size = sizeof(WirelessRebootInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&wireless_reboot_info, Memory::GetPointer(buffer_addr), sizeof(buffer_size));
|
||||||
|
|
||||||
|
cmd_buff[0] = IPC::MakeHeader(0x45, 0x1, 0x2);
|
||||||
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
|
cmd_buff[2] = (buffer_size << 14) | 2;
|
||||||
|
cmd_buff[3] = buffer_size;
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) called");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrepareToLeaveResidentApplet(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
u32 caller_exiting = cmd_buff[1] & 0xFF;
|
||||||
|
|
||||||
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) caller_exiting=0x%08X", caller_exiting);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LeaveResidentApplet(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
u32 parameters_size = cmd_buff[1];
|
||||||
|
u32 parameter_handle = cmd_buff[3];
|
||||||
|
u32 parameters_addr = cmd_buff[5];
|
||||||
|
|
||||||
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) parameter_size=0x%08X, parameter_handle=0x%08X, parameter_addr=0x%08X",
|
||||||
|
parameters_size, parameter_handle, parameters_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreloadResidentApplet(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
u32 app_id = cmd_buff[1];
|
||||||
|
|
||||||
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) app_id=0x%08X", app_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrepareToStartResidentApplet(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
u32 app_id = cmd_buff[1];
|
||||||
|
|
||||||
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) app_id=0x%08X", app_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartResidentApplet(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
u32 parameters_size = cmd_buff[1];
|
||||||
|
u32 parameter_handle = cmd_buff[3];
|
||||||
|
u32 parameters_addr = cmd_buff[5];
|
||||||
|
|
||||||
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) parameter_size=0x%08X, parameter_handle=0x%08X, parameter_addr=0x%08X",
|
||||||
|
parameters_size, parameter_handle, parameters_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CancelLibraryApplet(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
u32 application_exiting = cmd_buff[1] & 0xf;
|
||||||
|
|
||||||
|
cmd_buff[0] = IPC::MakeHeader(0x3B, 0x1, 0);
|
||||||
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) application_exiting=%u", application_exiting);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReplySleepQuery(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
u32 app_id = cmd_buff[1];
|
||||||
|
QueryReply query_reply = static_cast<QueryReply>(cmd_buff[2] & 0xFF);
|
||||||
|
|
||||||
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
|
if (query_reply == QueryReply::Reject) {
|
||||||
|
LOG_ERROR(Service_APT, "(STUBBED) app_id=0x%08X, query_reply=REJECT", app_id);
|
||||||
|
} else {
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) app_id=0x%08X, query_reply=%u", app_id, query_reply);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReplySleepNotificationComplete(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
u32 app_id = cmd_buff[1];
|
||||||
|
|
||||||
|
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) app_id=0x%08X", app_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void InitCaptureBufferInfo() {
|
||||||
|
u32 thread_id = 0;
|
||||||
|
u32 top_screen_color_per_pixel;
|
||||||
|
u32 bottom_screen_color_per_pixel;
|
||||||
|
|
||||||
|
GSP_GPU::FrameBufferUpdate* top_screen = GSP_GPU::GetFrameBufferInfo(thread_id, 0);
|
||||||
|
GSP_GPU::FrameBufferUpdate* bottom_screen = GSP_GPU::GetFrameBufferInfo(thread_id, 1);
|
||||||
|
// not 3D
|
||||||
|
capture_buffer_info.is_3d = 0;
|
||||||
|
// main screen config
|
||||||
|
capture_buffer_info.top_screen_left_offset = top_screen->framebuffer_info[top_screen->index].address_left;
|
||||||
|
capture_buffer_info.top_screen_right_offset = top_screen->framebuffer_info[top_screen->index].address_right;
|
||||||
|
capture_buffer_info.top_screen_format = top_screen->framebuffer_info[top_screen->index].format & 0x7;
|
||||||
|
// sub screen config
|
||||||
|
capture_buffer_info.bottom_screen_left_offset = bottom_screen->framebuffer_info[bottom_screen->index].address_left;
|
||||||
|
capture_buffer_info.bottom_screen_right_offset = bottom_screen->framebuffer_info[bottom_screen->index].address_right;
|
||||||
|
capture_buffer_info.bottom_screen_format = bottom_screen->framebuffer_info[bottom_screen->index].format & 0x7;
|
||||||
|
|
||||||
|
top_screen_color_per_pixel = GPU::Regs::BytesPerPixel(static_cast<GPU::Regs::PixelFormat>(capture_buffer_info.top_screen_format));
|
||||||
|
bottom_screen_color_per_pixel = GPU::Regs::BytesPerPixel(static_cast<GPU::Regs::PixelFormat>(capture_buffer_info.bottom_screen_format));
|
||||||
|
capture_buffer_info.size = 240 * (top_screen_color_per_pixel * 400 + bottom_screen_color_per_pixel * 320);
|
||||||
|
|
||||||
|
is_capture_buffer_info_set = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultCode SendCaptureBufferInfo(u32& buffer_addr, u32& buffer_size) {
|
||||||
|
if (buffer_addr) {
|
||||||
|
if (buffer_size > sizeof(CaptureBufferInfo)) {
|
||||||
|
buffer_size = sizeof(CaptureBufferInfo);
|
||||||
|
}
|
||||||
|
is_capture_buffer_info_set = true;
|
||||||
|
} else {
|
||||||
|
buffer_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&capture_buffer_info, Memory::GetPointer(buffer_addr), buffer_size);
|
||||||
|
return RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendCaptureBufferInfo(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
u32 buffer_size = cmd_buff[1];
|
||||||
|
u32 buffer_transition = cmd_buff[2];
|
||||||
|
u32 buffer_addr = cmd_buff[3];
|
||||||
|
|
||||||
|
if ((buffer_transition & 0x3C0F) != 0x2) {
|
||||||
|
cmd_buff[0] = IPC::MakeHeader(0, 0x1, 0);
|
||||||
|
cmd_buff[1] = ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS,
|
||||||
|
ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw; //0xD9001830
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_buff[0] = IPC::MakeHeader(0x40, 0x1, 0); //0x00400040
|
||||||
|
cmd_buff[1] = SendCaptureBufferInfo(buffer_addr, buffer_size).raw;
|
||||||
|
LOG_WARNING(Service_APT, "buffer_addr=0x%08X, buffer_size=0x%08X", buffer_addr, buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultCode ReceiveCaptureBufferInfo(u32& buffer_addr, u32 buffer_size) {
|
||||||
|
if (buffer_addr) {
|
||||||
|
if (buffer_size > sizeof(CaptureBufferInfo)) {
|
||||||
|
buffer_size = sizeof(CaptureBufferInfo);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buffer_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_capture_buffer_info_set) {
|
||||||
|
memcpy(Memory::GetPointer(buffer_addr), &capture_buffer_info, buffer_size);
|
||||||
|
} else {
|
||||||
|
InitCaptureBufferInfo();
|
||||||
|
memcpy(Memory::GetPointer(buffer_addr), &capture_buffer_info, buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReceiveCaptureBufferInfo(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
u32 buffer_size = cmd_buff[1];
|
||||||
|
VAddr buffer_addr = cmd_buff[0x41];
|
||||||
|
|
||||||
|
if (buffer_size > 0x1000) {
|
||||||
|
buffer_size = 0x1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_buff[0] = IPC::MakeHeader(0x41, 0x2, 0x2); //0x00410082
|
||||||
|
cmd_buff[1] = ReceiveCaptureBufferInfo(buffer_addr, buffer_size).raw;
|
||||||
|
cmd_buff[2] = buffer_size;
|
||||||
|
cmd_buff[3] = (buffer_size << 14) | 2;
|
||||||
|
LOG_WARNING(Service_APT, "buffer_size=0x%08X", buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetCaptureInfo(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
u32 buffer_size = cmd_buff[1];
|
||||||
|
VAddr buffer_addr = cmd_buff[0x41];
|
||||||
|
|
||||||
|
if (buffer_size > 0x1000) {
|
||||||
|
buffer_size = 0x1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_buff[0] = IPC::MakeHeader(0x4A, 0x1, 0x2);
|
||||||
|
cmd_buff[1] = ReceiveCaptureBufferInfo(buffer_addr, buffer_size).raw;
|
||||||
|
cmd_buff[2] = (buffer_size << 14) | 2;
|
||||||
|
LOG_WARNING(Service_APT, "buffer_size=0x%08X", buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
void NotifyToWait(Service::Interface* self) {
|
void NotifyToWait(Service::Interface* self) {
|
||||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
u32 app_id = cmd_buff[1];
|
u32 app_id = cmd_buff[1];
|
||||||
|
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
||||||
LOG_WARNING(Service_APT, "(STUBBED) app_id=%u", app_id);
|
LOG_WARNING(Service_APT, "(STUBBED) app_id=0x%08X", app_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetLockHandle(Service::Interface* self) {
|
void GetLockHandle(Service::Interface* self) {
|
||||||
@ -127,6 +391,7 @@ void GetLockHandle(Service::Interface* self) {
|
|||||||
void Enable(Service::Interface* self) {
|
void Enable(Service::Interface* self) {
|
||||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
u32 attributes = cmd_buff[1];
|
u32 attributes = cmd_buff[1];
|
||||||
|
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
||||||
parameter_event->Signal(); // Let the application know that it has been started
|
parameter_event->Signal(); // Let the application know that it has been started
|
||||||
LOG_WARNING(Service_APT, "(STUBBED) called attributes=0x%08X", attributes);
|
LOG_WARNING(Service_APT, "(STUBBED) called attributes=0x%08X", attributes);
|
||||||
@ -134,14 +399,22 @@ void Enable(Service::Interface* self) {
|
|||||||
|
|
||||||
void GetAppletManInfo(Service::Interface* self) {
|
void GetAppletManInfo(Service::Interface* self) {
|
||||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
u32 unk = cmd_buff[1];
|
AppletPos applet_pos = static_cast<AppletPos>(cmd_buff[1]);
|
||||||
|
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
||||||
cmd_buff[2] = 0;
|
cmd_buff[2] = static_cast<u32>(applet_pos);
|
||||||
cmd_buff[3] = 0;
|
cmd_buff[3] = 0;
|
||||||
cmd_buff[4] = static_cast<u32>(AppletId::HomeMenu); // Home menu AppID
|
cmd_buff[4] = static_cast<u32>(AppletId::HomeMenu); // Home menu AppID
|
||||||
cmd_buff[5] = static_cast<u32>(AppletId::Application); // TODO(purpasmart96): Do this correctly
|
cmd_buff[5] = static_cast<u32>(AppletId::Application); // TODO(purpasmart96): Do this correctly
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) called applet_pos=0x%08X", applet_pos);
|
||||||
|
}
|
||||||
|
|
||||||
LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk);
|
void CountRegisteredApplet(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
|
||||||
|
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
||||||
|
cmd_buff[2] = HLE::Applets::GetRegisteredAppletCount();
|
||||||
|
LOG_WARNING(Service_APT, "registered_applet_count=0x%08X", cmd_buff[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IsRegistered(Service::Interface* self) {
|
void IsRegistered(Service::Interface* self) {
|
||||||
@ -164,6 +437,7 @@ void IsRegistered(Service::Interface* self) {
|
|||||||
void InquireNotification(Service::Interface* self) {
|
void InquireNotification(Service::Interface* self) {
|
||||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
u32 app_id = cmd_buff[1];
|
u32 app_id = cmd_buff[1];
|
||||||
|
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
||||||
cmd_buff[2] = static_cast<u32>(SignalType::None); // Signal type
|
cmd_buff[2] = static_cast<u32>(SignalType::None); // Signal type
|
||||||
LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X", app_id);
|
LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X", app_id);
|
||||||
@ -207,7 +481,7 @@ void ReceiveParameter(Service::Interface* self) {
|
|||||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
u32 app_id = cmd_buff[1];
|
u32 app_id = cmd_buff[1];
|
||||||
u32 buffer_size = cmd_buff[2];
|
u32 buffer_size = cmd_buff[2];
|
||||||
VAddr buffer = cmd_buff[0x104 >> 2];
|
VAddr buffer = cmd_buff[0x41];
|
||||||
|
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
||||||
cmd_buff[2] = next_parameter.sender_id;
|
cmd_buff[2] = next_parameter.sender_id;
|
||||||
@ -229,7 +503,7 @@ void GlanceParameter(Service::Interface* self) {
|
|||||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
u32 app_id = cmd_buff[1];
|
u32 app_id = cmd_buff[1];
|
||||||
u32 buffer_size = cmd_buff[2];
|
u32 buffer_size = cmd_buff[2];
|
||||||
VAddr buffer = cmd_buff[0x104 >> 2];
|
VAddr buffer = cmd_buff[0x41];
|
||||||
|
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
||||||
cmd_buff[2] = next_parameter.sender_id;
|
cmd_buff[2] = next_parameter.sender_id;
|
||||||
@ -249,16 +523,32 @@ void GlanceParameter(Service::Interface* self) {
|
|||||||
|
|
||||||
void CancelParameter(Service::Interface* self) {
|
void CancelParameter(Service::Interface* self) {
|
||||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
u32 flag1 = cmd_buff[1];
|
u32 check_sender = cmd_buff[1] & 0xFF;
|
||||||
u32 unk = cmd_buff[2];
|
u32 sender_id = cmd_buff[2];
|
||||||
u32 flag2 = cmd_buff[3];
|
u32 check_receiver = cmd_buff[3] & 0xFF;
|
||||||
u32 app_id = cmd_buff[4];
|
u32 receiver_id = cmd_buff[4];
|
||||||
|
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
||||||
cmd_buff[2] = 1; // Set to Success
|
cmd_buff[2] = 1; // Set to Success
|
||||||
|
|
||||||
LOG_WARNING(Service_APT, "(STUBBED) called flag1=0x%08X, unk=0x%08X, flag2=0x%08X, app_id=0x%08X",
|
LOG_WARNING(Service_APT, "(STUBBED) check_sender=0x%08X, sender_id=0x%08X, check_receiver=0x%08X, receiver_id=0x%08X",
|
||||||
flag1, unk, flag2, app_id);
|
check_sender, sender_id, check_receiver, receiver_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetPreparationState(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
|
||||||
|
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
||||||
|
cmd_buff[2] = static_cast<u32>(applet_preparation_state);
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) called");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetPreparationState(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
applet_preparation_state = static_cast<AppletPreparationState>(cmd_buff[1]);
|
||||||
|
|
||||||
|
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) applet_preparation_state=0x%08X", applet_preparation_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrepareToStartApplication(Service::Interface* self) {
|
void PrepareToStartApplication(Service::Interface* self) {
|
||||||
@ -281,36 +571,119 @@ void PrepareToStartApplication(Service::Interface* self) {
|
|||||||
|
|
||||||
void StartApplication(Service::Interface* self) {
|
void StartApplication(Service::Interface* self) {
|
||||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
u32 buffer1_size = cmd_buff[1];
|
u32 parameter_size = cmd_buff[1];
|
||||||
u32 buffer2_size = cmd_buff[2];
|
u32 hmac_size = cmd_buff[2];
|
||||||
u32 flag = cmd_buff[3];
|
u32 is_paused = cmd_buff[3] & 0xFF;
|
||||||
u32 size1 = cmd_buff[4];
|
u32 parameter_transition = cmd_buff[4];
|
||||||
u32 buffer1_ptr = cmd_buff[5];
|
u32 parameter_buffer = cmd_buff[5];
|
||||||
u32 size2 = cmd_buff[6];
|
u32 hmac_transtion = cmd_buff[6];
|
||||||
u32 buffer2_ptr = cmd_buff[7];
|
u32 hmac_buffer = cmd_buff[7];
|
||||||
|
|
||||||
|
if ((parameter_transition & 0x3C0F) != 2 || (hmac_transtion & 0x3C0F) != 0x802) {
|
||||||
|
cmd_buff[0] = IPC::MakeHeader(0, 0x1, 0); // 0x40
|
||||||
|
cmd_buff[1] = ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS,
|
||||||
|
ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw; //0xD9001830
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_buff[0] = IPC::MakeHeader(0x1B, 0x1, 0);
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) parameter_size=0x%08X, hmac_size=0x%08X, is_paused=0x%08X, parameter_buffer=0x%08X, hmac_buffer=0x%08X",
|
||||||
|
parameter_size, hmac_size, is_paused, parameter_buffer, hmac_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
LOG_WARNING(Service_APT, "(STUBBED) called buffer1_size=0x%08X, buffer2_size=0x%08X, flag=0x%08X,"
|
ResultCode AppletUtility(u32& utility_id, u32& input_buffer, u32& input_size, u32& output_buffer,u32& output_size, bool applet_result) {
|
||||||
"size1=0x%08X, buffer1_ptr=0x%08X, size2=0x%08X, buffer2_ptr=0x%08X",
|
u32 sender_id = 0;
|
||||||
buffer1_size, buffer2_size, flag, size1, buffer1_ptr, size2, buffer2_ptr);
|
u32 transition = 0;
|
||||||
|
bool shell_open = true;
|
||||||
|
|
||||||
|
switch (static_cast<UtilityID>(utility_id)) {
|
||||||
|
case UtilityID::ClearPowerButtonState: // not useful
|
||||||
|
case UtilityID::ClearExclusiveControl:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UtilityID::SleepIfShellClosed:
|
||||||
|
shell_open = PTM::GetShellState();
|
||||||
|
if (!shell_open) {
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) SleepIfShellClosed, The 3DS system should sleep now.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) SleepIfShellClosed shell_open=%u", shell_open);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UtilityID::LockTransition:
|
||||||
|
transition = Memory::Read32(input_buffer);
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) LockTransition, transition=0x%08X", transition);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UtilityID::TryLockTransition:
|
||||||
|
applet_result = false;
|
||||||
|
if (output_buffer) {
|
||||||
|
if (output_size != 0) {
|
||||||
|
transition = Memory::Read32(input_buffer);
|
||||||
|
Memory::Write32(output_buffer, 0);
|
||||||
|
applet_result = true;
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) TryLockTransition, transition=0x%08X", transition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_ERROR(Service_APT, "(STUBBED) Utility TryLockTransition Operation Failed");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UtilityID::UnlockTransition:
|
||||||
|
transition = Memory::Read32(input_buffer);
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) UnlockTransition, transition=0x%08X", transition);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UtilityID::StartExitTask: // not useful
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UtilityID::SetInitialSenderId:
|
||||||
|
sender_id = Memory::Read32(input_buffer);
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) SetInitialSenderId, sender_id=0x%08X", sender_id);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UtilityID::SetPowerButtonClick: // not useful
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UtilityID::SetHomeMenuBuffer:
|
||||||
|
// This input_buffer content(may be a src_appid or a dst_appid)
|
||||||
|
// will be used by homemenu operation(like APT::LeaveHomeMenu) which try to do SendParameter()
|
||||||
|
is_homemenu_input_buffer_set = true;
|
||||||
|
homemenu_input_buffer = Memory::Read32(input_buffer);
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) SetLeaveHomeMenuBuffer, input_buffer=0x%08X", input_buffer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOG_ERROR(Service_APT, "(STUBBED) unknown utility_id=0x%08X", utility_id);
|
||||||
|
UNIMPLEMENTED();
|
||||||
|
}
|
||||||
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppletUtility(Service::Interface* self) {
|
void AppletUtility(Service::Interface* self) {
|
||||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
|
||||||
// These are from 3dbrew - I'm not really sure what they're used for.
|
u32 utility_id = cmd_buff[1];
|
||||||
u32 command = cmd_buff[1];
|
u32 input_size = cmd_buff[2];
|
||||||
u32 buffer1_size = cmd_buff[2];
|
u32 output_size = (cmd_buff[3] > 0x1000) ? 0x1000 : cmd_buff[3];
|
||||||
u32 buffer2_size = cmd_buff[3];
|
u32 input_traslation = cmd_buff[4];
|
||||||
u32 buffer1_addr = cmd_buff[5];
|
u32 input_buffer = cmd_buff[5];
|
||||||
u32 buffer2_addr = cmd_buff[65];
|
u32 output_traslation = cmd_buff[0x40];
|
||||||
|
u32 output_buffer = cmd_buff[0x41];
|
||||||
|
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
bool applet_result = false; // Only use for utility_id = 6 (bool TryLockTransition)
|
||||||
|
|
||||||
LOG_WARNING(Service_APT, "(STUBBED) called command=0x%08X, buffer1_size=0x%08X, buffer2_size=0x%08X, "
|
if (input_size > 0x1000) {
|
||||||
"buffer1_addr=0x%08X, buffer2_addr=0x%08X", command, buffer1_size, buffer2_size,
|
cmd_buff[0] = IPC::MakeHeader(0, 0x1, 0); // 0x40
|
||||||
buffer1_addr, buffer2_addr);
|
cmd_buff[1] = ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS,
|
||||||
|
ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw;;// 0xD9001830
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_buff[0] = IPC::MakeHeader(0x4B, 0x2, 0x2);// 0x004B0082
|
||||||
|
cmd_buff[1] = AppletUtility(utility_id, input_buffer, input_size, output_buffer, output_size, applet_result).raw;
|
||||||
|
cmd_buff[2] = static_cast<u32>(applet_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetAppCpuTimeLimit(Service::Interface* self) {
|
void SetAppCpuTimeLimit(Service::Interface* self) {
|
||||||
@ -410,6 +783,45 @@ void GetScreenCapPostPermission(Service::Interface* self) {
|
|||||||
LOG_WARNING(Service_APT, "(STUBBED) screen_capture_post_permission=%u", screen_capture_post_permission);
|
LOG_WARNING(Service_APT, "(STUBBED) screen_capture_post_permission=%u", screen_capture_post_permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrepareToCloseApplication(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
u32 cancel_preload = cmd_buff[1] & 0xFF;
|
||||||
|
|
||||||
|
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) cancel_preload=%u", cancel_preload);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CloseApplication(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
u32 parameter_size = cmd_buff[1];
|
||||||
|
u32 handle_parameter = cmd_buff[3];
|
||||||
|
u32 parameter_buffer = cmd_buff[5];
|
||||||
|
|
||||||
|
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) parameter_size=0x%08X, handle_parameter=0x%08X, parameter_buffer=0x%08X",
|
||||||
|
parameter_size, handle_parameter, parameter_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LeaveHomeMenu(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
u32 parameter_size = cmd_buff[1];
|
||||||
|
u32 handle_parameter = cmd_buff[3];
|
||||||
|
u32 parameter_buffer_transition = cmd_buff[4];
|
||||||
|
u32 parameter_buffer = cmd_buff[5];
|
||||||
|
|
||||||
|
if (cmd_buff[2] != 0 || (parameter_buffer_transition & 0x3C0F) != 2) {
|
||||||
|
cmd_buff[0] = IPC::MakeHeader(0, 0x1, 0);// 0x40
|
||||||
|
cmd_buff[1] = ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS,
|
||||||
|
ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw; //0xD9001830
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_buff[0] = IPC::MakeHeader(0x2E, 0x1, 0); //0x2E0040
|
||||||
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) parameter_size=0x%08X, handle_parameter=0x%08X, parameter_buffer=0x%08X",
|
||||||
|
parameter_size, handle_parameter, parameter_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
void GetAppletInfo(Service::Interface* self) {
|
void GetAppletInfo(Service::Interface* self) {
|
||||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
auto app_id = static_cast<AppletId>(cmd_buff[1]);
|
auto app_id = static_cast<AppletId>(cmd_buff[1]);
|
||||||
@ -431,18 +843,20 @@ void GetAppletInfo(Service::Interface* self) {
|
|||||||
void GetStartupArgument(Service::Interface* self) {
|
void GetStartupArgument(Service::Interface* self) {
|
||||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
u32 parameter_size = cmd_buff[1];
|
u32 parameter_size = cmd_buff[1];
|
||||||
|
u32 parameter_buffer = cmd_buff[0x41];
|
||||||
|
|
||||||
StartupArgumentType startup_argument_type = static_cast<StartupArgumentType>(cmd_buff[2]);
|
StartupArgumentType startup_argument_type = static_cast<StartupArgumentType>(cmd_buff[2]);
|
||||||
|
|
||||||
if (parameter_size >= 0x300) {
|
if (parameter_size > 0x1000) {
|
||||||
LOG_ERROR(Service_APT, "Parameter size is outside the valid range (capped to 0x300): parameter_size=0x%08x", parameter_size);
|
parameter_size = 0x1000;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_WARNING(Service_APT,"(stubbed) called startup_argument_type=%u , parameter_size=0x%08x , parameter_value=0x%08x",
|
LOG_WARNING(Service_APT,"(STUBBED) called startup_argument_type=%u , parameter_size=0x%08x , parameter_buffer=0x%08x",
|
||||||
startup_argument_type, parameter_size, Memory::Read32(cmd_buff[41]));
|
startup_argument_type, parameter_size, parameter_buffer);
|
||||||
|
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw;
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
cmd_buff[2] = (parameter_size > 0) ? 1 : 0;
|
cmd_buff[2] = (parameter_size > 0) ? 1 : 0;
|
||||||
|
cmd_buff[3] = (parameter_size << 14) | 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckNew3DSApp(Service::Interface* self) {
|
void CheckNew3DSApp(Service::Interface* self) {
|
||||||
@ -468,6 +882,31 @@ void CheckNew3DS(Service::Interface* self) {
|
|||||||
LOG_WARNING(Service_APT, "(STUBBED) called");
|
LOG_WARNING(Service_APT, "(STUBBED) called");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IsStandardMemoryLayout(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
|
||||||
|
const bool is_new_3ds = Settings::values.is_new_3ds;
|
||||||
|
|
||||||
|
u32 is_standard_memory_layout = 0;
|
||||||
|
|
||||||
|
using ConfigMem::config_mem;
|
||||||
|
|
||||||
|
if (is_new_3ds) {
|
||||||
|
if (config_mem.app_mem_type != 7) { // 7 for 178MB mode.
|
||||||
|
is_standard_memory_layout = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (config_mem.app_mem_type == 0) { // 0 for 64MB mode
|
||||||
|
is_standard_memory_layout = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_buff[0] = IPC::MakeHeader(0x104, 0x2, 0);
|
||||||
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
|
cmd_buff[2] = is_standard_memory_layout;
|
||||||
|
LOG_WARNING(Service_APT, "(STUBBED) is_standard_memory_layout=%u", is_standard_memory_layout);
|
||||||
|
}
|
||||||
|
|
||||||
void Init() {
|
void Init() {
|
||||||
AddService(new APT_A_Interface);
|
AddService(new APT_A_Interface);
|
||||||
AddService(new APT_S_Interface);
|
AddService(new APT_S_Interface);
|
||||||
@ -501,7 +940,7 @@ void Init() {
|
|||||||
lock = Kernel::Mutex::Create(false, "APT_U:Lock");
|
lock = Kernel::Mutex::Create(false, "APT_U:Lock");
|
||||||
|
|
||||||
cpu_percent = 0;
|
cpu_percent = 0;
|
||||||
unknown_ns_state_field = 0;
|
homemenu_input_buffer = 0;
|
||||||
screen_capture_post_permission = ScreencapPostPermission::CleanThePermission; // TODO(JamePeng): verify the initial value
|
screen_capture_post_permission = ScreencapPostPermission::CleanThePermission; // TODO(JamePeng): verify the initial value
|
||||||
|
|
||||||
// TODO(bunnei): Check if these are created in Initialize or on APT process startup.
|
// TODO(bunnei): Check if these are created in Initialize or on APT process startup.
|
||||||
@ -513,6 +952,8 @@ void Init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown() {
|
void Shutdown() {
|
||||||
|
is_capture_buffer_info_set = false;
|
||||||
|
is_homemenu_input_buffer_set = false;
|
||||||
shared_font_mem = nullptr;
|
shared_font_mem = nullptr;
|
||||||
shared_font_relocated = false;
|
shared_font_relocated = false;
|
||||||
lock = nullptr;
|
lock = nullptr;
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
|
|
||||||
@ -44,6 +46,13 @@ struct CaptureBufferInfo {
|
|||||||
};
|
};
|
||||||
static_assert(sizeof(CaptureBufferInfo) == 0x20, "CaptureBufferInfo struct has incorrect size");
|
static_assert(sizeof(CaptureBufferInfo) == 0x20, "CaptureBufferInfo struct has incorrect size");
|
||||||
|
|
||||||
|
struct WirelessRebootInfo {
|
||||||
|
std::array<u8, 6> mac_address{};
|
||||||
|
std::array<u8, 9> wireless_reboot_passphrase{};
|
||||||
|
INSERT_PADDING_BYTES(1);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(WirelessRebootInfo) == 0x10, "WirelessRebootInfo struct has incorrect size");
|
||||||
|
|
||||||
/// Signals used by APT functions
|
/// Signals used by APT functions
|
||||||
enum class SignalType : u32 {
|
enum class SignalType : u32 {
|
||||||
None = 0x0,
|
None = 0x0,
|
||||||
@ -70,12 +79,12 @@ enum class AppletId : u32 {
|
|||||||
AmiiboSettings = 0x119,
|
AmiiboSettings = 0x119,
|
||||||
SoftwareKeyboard1 = 0x201,
|
SoftwareKeyboard1 = 0x201,
|
||||||
Ed1 = 0x202,
|
Ed1 = 0x202,
|
||||||
PnoteApp = 0x204,
|
PnoteApp1 = 0x204,
|
||||||
SnoteApp = 0x205,
|
SnoteApp1 = 0x205,
|
||||||
Error = 0x206,
|
Error = 0x206,
|
||||||
Mint = 0x207,
|
Mint1 = 0x207,
|
||||||
Extrapad = 0x208,
|
Extrapad1 = 0x208,
|
||||||
Memolib = 0x209,
|
Memolib1 = 0x209,
|
||||||
Application = 0x300,
|
Application = 0x300,
|
||||||
AnyLibraryApplet = 0x400,
|
AnyLibraryApplet = 0x400,
|
||||||
SoftwareKeyboard2 = 0x401,
|
SoftwareKeyboard2 = 0x401,
|
||||||
@ -88,6 +97,15 @@ enum class AppletId : u32 {
|
|||||||
Memolib2 = 0x409,
|
Memolib2 = 0x409,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class AppletPos {
|
||||||
|
None = -1,
|
||||||
|
App = 0,
|
||||||
|
AppLib = 1,
|
||||||
|
Sys = 2,
|
||||||
|
SysLib = 3,
|
||||||
|
Resident = 4
|
||||||
|
};
|
||||||
|
|
||||||
enum class StartupArgumentType : u32 {
|
enum class StartupArgumentType : u32 {
|
||||||
OtherApp = 0,
|
OtherApp = 0,
|
||||||
Restart = 1,
|
Restart = 1,
|
||||||
@ -101,6 +119,49 @@ enum class ScreencapPostPermission : u32 {
|
|||||||
DisableScreenshotPostingToMiiverse = 3
|
DisableScreenshotPostingToMiiverse = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class QueryReply : u32 {
|
||||||
|
Reject = 0,
|
||||||
|
Accept = 1,
|
||||||
|
Later = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class AppletPreparationState : u32 {
|
||||||
|
NoPreparation = 0,
|
||||||
|
PreparedToLaunchApp = 1,
|
||||||
|
PreparedToCloseApp = 2,
|
||||||
|
PreparedToForceToCloseApp = 3,
|
||||||
|
PreparedToPreloadApplib = 4,
|
||||||
|
PreparedToLaunchApplib = 5,
|
||||||
|
PreparedToCloseApplib = 6,
|
||||||
|
PreparedToLaunchSys = 7,
|
||||||
|
PreparedToCloseSys = 8,
|
||||||
|
PreparedToPreloadSyslib = 9,
|
||||||
|
PreparedToLaunchSyslib = 10,
|
||||||
|
PreparedToCloseSyslib = 11,
|
||||||
|
PreparedToLaunchResident = 12,
|
||||||
|
PreparedToLeaveResident = 13,
|
||||||
|
PreparedToDoHomemenu = 14,
|
||||||
|
PreparedToLeaveHomemenu = 15,
|
||||||
|
PreparedToStartResident = 16,
|
||||||
|
PreparedToDoAppJump = 17,
|
||||||
|
PreparedToForceToCloseSys = 18,
|
||||||
|
PreparedToLaunchOtherSys = 19,
|
||||||
|
PreparedToJumpToApp = 20,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class UtilityID : u32 {
|
||||||
|
ClearPowerButtonState = 0,
|
||||||
|
ClearExclusiveControl = 3,
|
||||||
|
SleepIfShellClosed = 4,
|
||||||
|
LockTransition = 5,
|
||||||
|
TryLockTransition = 6,
|
||||||
|
UnlockTransition = 7,
|
||||||
|
StartExitTask = 10,
|
||||||
|
SetInitialSenderId = 11,
|
||||||
|
SetPowerButtonClick = 12,
|
||||||
|
SetHomeMenuBuffer = 17
|
||||||
|
};
|
||||||
|
|
||||||
/// Send a parameter to the currently-running application, which will read it via ReceiveParameter
|
/// Send a parameter to the currently-running application, which will read it via ReceiveParameter
|
||||||
void SendParameter(const MessageParameter& parameter);
|
void SendParameter(const MessageParameter& parameter);
|
||||||
|
|
||||||
@ -123,6 +184,149 @@ void Initialize(Service::Interface* self);
|
|||||||
*/
|
*/
|
||||||
void GetSharedFont(Service::Interface* self);
|
void GetSharedFont(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::GetWirelessRebootInfo service function
|
||||||
|
* Inputs:
|
||||||
|
* 1 : buffer_size
|
||||||
|
* Outputs:
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
* Note:
|
||||||
|
* Same as NSS:SetWirelessRebootInfo except this loads the data instead.
|
||||||
|
* The state flag set by NSS:SetWirelessRebootInfo must have bit0 set,
|
||||||
|
* Otherwise the output buffer is just cleared without copying any data.
|
||||||
|
* This is used by DLP-child titles.
|
||||||
|
*/
|
||||||
|
void GetWirelessRebootInfo(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::PrepareToLeaveResidentApplet service function
|
||||||
|
* Inputs:
|
||||||
|
* 1 : u8, Caller Exiting (0 = not exiting, 1 = exiting)
|
||||||
|
* Outputs:
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
*/
|
||||||
|
void PrepareToLeaveResidentApplet(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::LeaveResidentApplet service function
|
||||||
|
* Inputs:
|
||||||
|
* 1 : Parameters Size
|
||||||
|
* 2 : 0x0
|
||||||
|
* 3 : Handle Parameter
|
||||||
|
* 5 : void*, Parameters
|
||||||
|
* Outputs:
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
*/
|
||||||
|
void LeaveResidentApplet(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::PreloadResidentApplet service function
|
||||||
|
* Inputs:
|
||||||
|
* 1 : AppID
|
||||||
|
* Outputs:
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
*/
|
||||||
|
void PreloadResidentApplet(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::PrepareToStartResidentApplet service function
|
||||||
|
* Inputs:
|
||||||
|
* 1 : AppID
|
||||||
|
* Outputs:
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
*/
|
||||||
|
void PrepareToStartResidentApplet(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::StartResidentApplet service function
|
||||||
|
* Inputs:
|
||||||
|
* 1 : Parameters Size
|
||||||
|
* 2 : 0x0
|
||||||
|
* 3 : Handle Parameter
|
||||||
|
* 5 : void*, Parameters
|
||||||
|
* Outputs:
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
*/
|
||||||
|
void StartResidentApplet(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::CancelLibraryApplet service function
|
||||||
|
* Inputs:
|
||||||
|
* 0 : Header code [0x003B0040]
|
||||||
|
* 1 : u8, Application Exiting (0 = not exiting, 1 = exiting)
|
||||||
|
* Outputs:
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
*/
|
||||||
|
void CancelLibraryApplet(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::ReplySleepQuery service function
|
||||||
|
* Inputs:
|
||||||
|
* 1 : AppID
|
||||||
|
* 2: QueryReply
|
||||||
|
* Outputs:
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
* Note: If the specific unimplemented function or applet was called by application,
|
||||||
|
* It would return a value QueryReply::Reject to cmd_buff[2]
|
||||||
|
* For example, "Could not create applet XXXX" will cause the command QueryReply::Reject to this function
|
||||||
|
*/
|
||||||
|
void ReplySleepQuery(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::ReplySleepNotificationComplete service function
|
||||||
|
* Inputs:
|
||||||
|
* 1 : AppId
|
||||||
|
* Outputs:
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
*/
|
||||||
|
void ReplySleepNotificationComplete(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::SendCaptureBufferInfo service function
|
||||||
|
* Inputs:
|
||||||
|
* 1 : Size
|
||||||
|
* 2 : (Size << 14) | 2
|
||||||
|
* 3: void* CaptureBufferInfo
|
||||||
|
* Outputs:
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
* Note:
|
||||||
|
* The input size is clamped to 0x20-bytes by NS.
|
||||||
|
* The input buffer with the clamped size is then copied to a NS state buffer.
|
||||||
|
* The size field for this state buffer is also set to this clamped size.
|
||||||
|
*/
|
||||||
|
void SendCaptureBufferInfo(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::ReceiveCaptureBufferInfo service function
|
||||||
|
* Inputs:
|
||||||
|
* 1 : Size
|
||||||
|
* 0x40 : (Size << 14) | 2
|
||||||
|
* 0x41 : void*, CaptureBufferInfo
|
||||||
|
* Outputs:
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
* 2 : Actual Size
|
||||||
|
* Note:
|
||||||
|
* This command loads the data set by APT:SendCaptureBufferInfo.
|
||||||
|
* The input size is clamped to 0x20-bytes by NS, then this size is clamped to the size for the NS state buffer.
|
||||||
|
* The NS state buffer data is copied to the output buffer, (when the clamped size is not zero) then the size field for the state buffer is set 0.
|
||||||
|
*/
|
||||||
|
void ReceiveCaptureBufferInfo(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::GetCaptureInfo service function
|
||||||
|
* Inputs:
|
||||||
|
* 1 : Size
|
||||||
|
* 0x40 : (Size << 14) | 2
|
||||||
|
* 0x41 : void*, CaptureBufferInfo
|
||||||
|
* Outputs:
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
* Notes:
|
||||||
|
* This command loads the data set by APT:SendCaptureBufferInfo, this command is similar to APT:ReceiveCaptureBufferInfo.
|
||||||
|
* The input size is clamped to 0x20-bytes by NS.
|
||||||
|
* The NS state buffer data is then copied to the output buffer.
|
||||||
|
*/
|
||||||
|
void GetCaptureInfo(Service::Interface* self);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APT::NotifyToWait service function
|
* APT::NotifyToWait service function
|
||||||
* Inputs:
|
* Inputs:
|
||||||
@ -157,11 +361,11 @@ void Enable(Service::Interface* self);
|
|||||||
/**
|
/**
|
||||||
* APT::GetAppletManInfo service function.
|
* APT::GetAppletManInfo service function.
|
||||||
* Inputs:
|
* Inputs:
|
||||||
* 1 : Unknown
|
* 1 : AppletPos
|
||||||
* Outputs:
|
* Outputs:
|
||||||
* 1 : Result of function, 0 on success, otherwise error code
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
* 2 : Unknown u32 value
|
* 2 : AppletPos
|
||||||
* 3 : Unknown u8 value
|
* 3 : Requested AppId
|
||||||
* 4 : Home Menu AppId
|
* 4 : Home Menu AppId
|
||||||
* 5 : AppID of currently active app
|
* 5 : AppID of currently active app
|
||||||
*/
|
*/
|
||||||
@ -182,19 +386,37 @@ void GetAppletManInfo(Service::Interface* self);
|
|||||||
void GetAppletInfo(Service::Interface* self);
|
void GetAppletInfo(Service::Interface* self);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APT::IsRegistered service function. This returns whether the specified AppID is registered with NS yet.
|
* APT::CountRegisteredApplet service function.
|
||||||
* An AppID is "registered" once the process associated with the AppID uses APT:Enable. Home Menu uses this
|
* Outputs:
|
||||||
* command to determine when the launched process is running and to determine when to stop using GSP etc,
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
* while displaying the "Nintendo 3DS" loading screen.
|
* 2 : Registered Applet Count
|
||||||
|
*/
|
||||||
|
void CountRegisteredApplet(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::IsRegistered service function
|
||||||
* Inputs:
|
* Inputs:
|
||||||
* 1 : AppID
|
* 1 : AppID
|
||||||
* Outputs:
|
* Outputs:
|
||||||
* 0 : Return header
|
* 0 : Return header
|
||||||
* 1 : Result of function, 0 on success, otherwise error code
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
* 2 : Output, 0 = not registered, 1 = registered.
|
* 2 : Output, 0 = not registered, 1 = registered.
|
||||||
|
* Note:
|
||||||
|
* This returns whether the specified AppID is registered with NS yet.
|
||||||
|
* An AppID is "registered" once the process associated with the AppID uses APT:Enable. Home Menu uses this
|
||||||
|
* command to determine when the launched process is running and to determine when to stop using GSP etc,
|
||||||
|
* while displaying the "Nintendo 3DS" loading screen.
|
||||||
*/
|
*/
|
||||||
void IsRegistered(Service::Interface* self);
|
void IsRegistered(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::InquireNotification service function.
|
||||||
|
* Inputs:
|
||||||
|
* 1 : AppId
|
||||||
|
* Outputs:
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
* 2 : Notification
|
||||||
|
*/
|
||||||
void InquireNotification(Service::Interface* self);
|
void InquireNotification(Service::Interface* self);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -215,11 +437,7 @@ void InquireNotification(Service::Interface* self);
|
|||||||
void SendParameter(Service::Interface* self);
|
void SendParameter(Service::Interface* self);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APT::ReceiveParameter service function. This returns the current parameter data from NS state,
|
* APT::ReceiveParameter service function
|
||||||
* from the source process which set the parameters. Once finished, NS will clear a flag in the NS
|
|
||||||
* state so that this command will return an error if this command is used again if parameters were
|
|
||||||
* not set again. This is called when the second Initialize event is triggered. It returns a signal
|
|
||||||
* type indicating why it was triggered.
|
|
||||||
* Inputs:
|
* Inputs:
|
||||||
* 1 : AppID
|
* 1 : AppID
|
||||||
* 2 : Parameter buffer size, max size is 0x1000
|
* 2 : Parameter buffer size, max size is 0x1000
|
||||||
@ -232,90 +450,123 @@ void SendParameter(Service::Interface* self);
|
|||||||
* 6 : Handle from the source process which set the parameters, likely used for shared memory
|
* 6 : Handle from the source process which set the parameters, likely used for shared memory
|
||||||
* 7 : Size
|
* 7 : Size
|
||||||
* 8 : Output parameter buffer ptr
|
* 8 : Output parameter buffer ptr
|
||||||
|
* Note:
|
||||||
|
* This returns the current parameter data from NS state,
|
||||||
|
* from the source process which set the parameters. Once finished, NS will clear a flag in the NS
|
||||||
|
* state so that this command will return an error if this command is used again if parameters were
|
||||||
|
* not set again. This is called when the second Initialize event is triggered. It returns a signal
|
||||||
|
* type indicating why it was triggered.
|
||||||
*/
|
*/
|
||||||
void ReceiveParameter(Service::Interface* self);
|
void ReceiveParameter(Service::Interface* self);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APT::GlanceParameter service function. This is exactly the same as APT_U::ReceiveParameter
|
* APT::GlanceParameter service function
|
||||||
* (except for the word value prior to the output handle), except this will not clear the flag
|
|
||||||
* (except when responseword[3]==8 || responseword[3]==9) in NS state.
|
|
||||||
* Inputs:
|
* Inputs:
|
||||||
* 1 : AppID
|
* 1 : AppID
|
||||||
* 2 : Parameter buffer size, max size is 0x1000
|
* 2 : Parameter buffer size, max size is 0x1000
|
||||||
* Outputs:
|
* Outputs:
|
||||||
* 1 : Result of function, 0 on success, otherwise error code
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
* 2 : Unknown, for now assume AppID of the process which sent these parameters
|
* 2 : Sender AppID, for now assume AppID of the process which sent these parameters
|
||||||
* 3 : Unknown, for now assume Signal type
|
* 3 : Command, for now assume Signal type
|
||||||
* 4 : Actual parameter buffer size, this is <= to the the input size
|
* 4 : Actual parameter buffer size, this is <= to the the input size
|
||||||
* 5 : Value
|
* 5 : Value
|
||||||
* 6 : Handle from the source process which set the parameters, likely used for shared memory
|
* 6 : Handle from the source process which set the parameters, likely used for shared memory
|
||||||
* 7 : Size
|
* 7 : Size
|
||||||
* 8 : Output parameter buffer ptr
|
* 8 : Output parameter buffer ptr
|
||||||
|
* Note:
|
||||||
|
* This is exactly the same as APT_U::ReceiveParameter
|
||||||
|
* (except for the word value prior to the output handle), except this will not clear the flag
|
||||||
|
* (except when responseword[3]==8 || responseword[3]==9) in NS state.
|
||||||
*/
|
*/
|
||||||
void GlanceParameter(Service::Interface* self);
|
void GlanceParameter(Service::Interface* self);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APT::CancelParameter service function. When the parameter data is available, and when the above
|
* APT::CancelParameter service function.
|
||||||
* specified fields match the ones in NS state(for the ones where the checks are enabled), this
|
|
||||||
* clears the flag which indicates that parameter data is available
|
|
||||||
* (same flag cleared by APT:ReceiveParameter).
|
|
||||||
* Inputs:
|
* Inputs:
|
||||||
* 1 : Flag, when non-zero NS will compare the word after this one with a field in the NS state.
|
* 1 : u8, Check Sender (0 = don't check, 1 = check)
|
||||||
* 2 : Unknown, this is the same as the first unknown field returned by APT:ReceiveParameter.
|
* 2 : Sender AppID
|
||||||
* 3 : Flag, when non-zero NS will compare the word after this one with a field in the NS state.
|
* 3 : u8, Check Receiver (0 = don't check, 1 = check)
|
||||||
* 4 : AppID
|
* 4 : Receiver AppID
|
||||||
* Outputs:
|
* Outputs:
|
||||||
* 0 : Return header
|
|
||||||
* 1 : Result of function, 0 on success, otherwise error code
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
* 2 : Status flag, 0 = failure due to no parameter data being available, or the above enabled
|
* 2 : Status flag, 0 = failure due to no parameter data being available, or the above enabled
|
||||||
* fields don't match the fields in NS state. 1 = success.
|
* fields don't match the fields in NS state. 1 = success.
|
||||||
|
* Note:
|
||||||
|
* When the parameter data is available, and when the above specified fields match the ones in NS state(for the ones where the checks are enabled),
|
||||||
|
* This clears the flag which indicates that parameter data is available(same flag cleared by APT:ReceiveParameter).
|
||||||
*/
|
*/
|
||||||
void CancelParameter(Service::Interface* self);
|
void CancelParameter(Service::Interface* self);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APT::PrepareToStartApplication service function. When the input title-info programID is zero,
|
* APT::GetPreparationState service function
|
||||||
|
* Outputs:
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
* 2: AppletPreparationState
|
||||||
|
*/
|
||||||
|
void GetPreparationState(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::SetPreparationState service function
|
||||||
|
* Inputs:
|
||||||
|
* 1 : AppletPreparationState
|
||||||
|
* Outputs:
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
*/
|
||||||
|
void SetPreparationState(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::PrepareToStartApplication service function
|
||||||
|
* Inputs:
|
||||||
|
* 1-4 : ProgramInfo
|
||||||
|
* 5 : Flags (usually zero, when zero, NS writes a title-info struct with Program ID = ~0
|
||||||
|
* and MediaType = NAND to the FIRM parameters structure)
|
||||||
|
* Outputs:
|
||||||
|
* 0 : Return header
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
* Note:
|
||||||
|
* When the input title-info programID is zero,
|
||||||
* NS will load the actual program ID via AMNet:GetTitleIDList. After doing some checks with the
|
* NS will load the actual program ID via AMNet:GetTitleIDList. After doing some checks with the
|
||||||
* programID, NS will then set a NS state flag to value 1, then set the programID for AppID
|
* programID, NS will then set a NS state flag to value 1, then set the programID for AppID
|
||||||
* 0x300(application) to the input program ID(or the one from GetTitleIDList). A media-type field
|
* 0x300(application) to the input program ID(or the one from GetTitleIDList). A media-type field
|
||||||
* in the NS state is also set to the input media-type value
|
* in the NS state is also set to the input media-type value
|
||||||
* (other state fields are set at this point as well). With 8.0.0-18, NS will set an u8 NS state
|
* (other state fields are set at this point as well). With 8.0.0-18, NS will set an u8 NS state
|
||||||
* field to value 1 when input flags bit8 is set
|
* field to value 1 when input flags bit8 is set
|
||||||
* Inputs:
|
|
||||||
* 1-4 : 0x10-byte title-info struct
|
|
||||||
* 4 : Flags
|
|
||||||
* Outputs:
|
|
||||||
* 0 : Return header
|
|
||||||
* 1 : Result of function, 0 on success, otherwise error code
|
|
||||||
*/
|
*/
|
||||||
void PrepareToStartApplication(Service::Interface* self);
|
void PrepareToStartApplication(Service::Interface* self);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APT::StartApplication service function. Buf0 is copied to NS FIRMparams+0x0, then Buf1 is copied
|
* APT::StartApplication service function.
|
||||||
* to the NS FIRMparams+0x480. Then the application is launched.
|
|
||||||
* Inputs:
|
* Inputs:
|
||||||
* 1 : Buffer 0 size, max size is 0x300
|
* 1 : Parameter Size (capped to 0x300)
|
||||||
* 2 : Buffer 1 size, max size is 0x20 (this can be zero)
|
* 2 : HMAC Size (capped to 0x20)
|
||||||
* 3 : u8 flag
|
* 3 : u8 Paused (0 = not paused, 1 = paused)
|
||||||
* 4 : (Size0<<14) | 2
|
* 4 : (Parameter Size << 14) | 2
|
||||||
* 5 : Buffer 0 pointer
|
* 5 : void*, Parameter
|
||||||
* 6 : (Size1<<14) | 0x802
|
* 6 : (HMAC Size << 14) | 0x802
|
||||||
* 7 : Buffer 1 pointer
|
* 7 : void*, HMAC
|
||||||
* Outputs:
|
* Outputs:
|
||||||
* 0 : Return Header
|
* 0 : Return Header
|
||||||
* 1 : Result of function, 0 on success, otherwise error code
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
*/
|
* Note:
|
||||||
|
* The parameter buffer is copied to NS FIRMparams+0x0, then the HMAC buffer is copied to NS FIRMparams+0x480.
|
||||||
|
* Then the application is launched.
|
||||||
|
*/
|
||||||
void StartApplication(Service::Interface* self);
|
void StartApplication(Service::Interface* self);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APT::AppletUtility service function
|
* APT::AppletUtility service function
|
||||||
* Inputs:
|
* Inputs:
|
||||||
* 1 : Unknown, but clearly used for something
|
* 1 : UtilityID
|
||||||
* 2 : Buffer 1 size (purpose is unknown)
|
* 2 : Input Size
|
||||||
* 3 : Buffer 2 size (purpose is unknown)
|
* 3 : Output Size
|
||||||
* 5 : Buffer 1 address (purpose is unknown)
|
* 4 : (Input Size << 14) | 0x402
|
||||||
* 65 : Buffer 2 address (purpose is unknown)
|
* 5 : void*, Input
|
||||||
|
* 0x41 : void*, Output
|
||||||
* Outputs:
|
* Outputs:
|
||||||
* 1 : Result of function, 0 on success, otherwise error code
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
* 2 : Applet Result
|
||||||
|
* Note:
|
||||||
|
* This function may affect specific srv:Notifications operation by using Utility
|
||||||
*/
|
*/
|
||||||
void AppletUtility(Service::Interface* self);
|
void AppletUtility(Service::Interface* self);
|
||||||
|
|
||||||
@ -378,14 +629,50 @@ void PreloadLibraryApplet(Service::Interface* self);
|
|||||||
*/
|
*/
|
||||||
void StartLibraryApplet(Service::Interface* self);
|
void StartLibraryApplet(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::PrepareToCloseApplication service function
|
||||||
|
* Inputs:
|
||||||
|
* 1 : u8, Cancel Preload (0 = don't cancel, 1 = cancel)
|
||||||
|
* Outputs:
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
*/
|
||||||
|
void PrepareToCloseApplication(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::CloseApplication service function
|
||||||
|
* Inputs:
|
||||||
|
* 1 : Parameters Size
|
||||||
|
* 2 : 0x0
|
||||||
|
* 3 : Handle Parameter
|
||||||
|
* 4 : (Parameters Size << 14) | 2
|
||||||
|
* 5 : void*, Parameters
|
||||||
|
* Outputs:
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
*/
|
||||||
|
void CloseApplication(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::LeaveHomeMenu service function
|
||||||
|
* Inputs:
|
||||||
|
* 0 : Header code [0x002E0044]
|
||||||
|
* 1 : Parameters Size
|
||||||
|
* 2 : 0x0
|
||||||
|
* 3 : Handle Parameter
|
||||||
|
* 4 : (Parameters Size << 14) | 2
|
||||||
|
* 5 : void*, Parameters
|
||||||
|
* Outputs:
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
*/
|
||||||
|
void LeaveHomeMenu(Service::Interface* self);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APT::GetStartupArgument service function
|
* APT::GetStartupArgument service function
|
||||||
* Inputs:
|
* Inputs:
|
||||||
* 1 : Parameter Size (capped to 0x300)
|
* 1 : Parameter Size (capped to 0x300)
|
||||||
* 2 : StartupArgumentType
|
* 2 : StartupArgumentType
|
||||||
* Outputs:
|
* Outputs:
|
||||||
* 0 : Return header
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
* 1 : u8, Exists (0 = does not exist, 1 = exists)
|
* 2 : u8, Exists (0 = does not exist, 1 = exists)
|
||||||
*/
|
*/
|
||||||
void GetStartupArgument(Service::Interface* self);
|
void GetStartupArgument(Service::Interface* self);
|
||||||
|
|
||||||
@ -432,6 +719,17 @@ void CheckNew3DSApp(Service::Interface* self);
|
|||||||
*/
|
*/
|
||||||
void CheckNew3DS(Service::Interface* self);
|
void CheckNew3DS(Service::Interface* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APT::IsStandardMemoryLayout service function
|
||||||
|
* Inputs:
|
||||||
|
* 0 : Header code [0x01040000]
|
||||||
|
* Outputs:
|
||||||
|
* 0 : Header code
|
||||||
|
* 1 : Result code
|
||||||
|
* 2 : u8, Standard Memory Layout (0 = non-standard, 1 = standard)
|
||||||
|
*/
|
||||||
|
void IsStandardMemoryLayout(Service::Interface* self);
|
||||||
|
|
||||||
/// Initialize the APT service
|
/// Initialize the APT service
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
|
@ -15,20 +15,37 @@ const Interface::FunctionInfo FunctionTable[] = {
|
|||||||
{0x00040040, nullptr, "Finalize?"},
|
{0x00040040, nullptr, "Finalize?"},
|
||||||
{0x00050040, GetAppletManInfo, "GetAppletManInfo"},
|
{0x00050040, GetAppletManInfo, "GetAppletManInfo"},
|
||||||
{0x00060040, GetAppletInfo, "GetAppletInfo"},
|
{0x00060040, GetAppletInfo, "GetAppletInfo"},
|
||||||
|
{0x00080000, CountRegisteredApplet, "CountRegisteredApplet"},
|
||||||
{0x00090040, IsRegistered, "IsRegistered"},
|
{0x00090040, IsRegistered, "IsRegistered"},
|
||||||
{0x000B0040, InquireNotification, "InquireNotification"},
|
{0x000B0040, InquireNotification, "InquireNotification"},
|
||||||
{0x000C0104, SendParameter, "SendParameter"},
|
{0x000C0104, SendParameter, "SendParameter"},
|
||||||
{0x000D0080, ReceiveParameter, "ReceiveParameter"},
|
{0x000D0080, ReceiveParameter, "ReceiveParameter"},
|
||||||
{0x000E0080, GlanceParameter, "GlanceParameter"},
|
{0x000E0080, GlanceParameter, "GlanceParameter"},
|
||||||
{0x000F0100, CancelParameter, "CancelParameter"},
|
{0x000F0100, CancelParameter, "CancelParameter"},
|
||||||
|
{0x00130000, GetPreparationState, "GetPreparationState"},
|
||||||
|
{0x00140040, SetPreparationState, "SetPreparationState"},
|
||||||
{0x00150140, PrepareToStartApplication, "PrepareToStartApplication"},
|
{0x00150140, PrepareToStartApplication, "PrepareToStartApplication"},
|
||||||
{0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"},
|
{0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"},
|
||||||
{0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"},
|
{0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"},
|
||||||
|
{0x001B00C4, StartApplication, "StartApplication"},
|
||||||
{0x001E0084, StartLibraryApplet, "StartLibraryApplet"},
|
{0x001E0084, StartLibraryApplet, "StartLibraryApplet"},
|
||||||
{0x003B0040, nullptr, "CancelLibraryApplet?"},
|
{0x00220040, PrepareToCloseApplication, "PrepareToCloseApplication"},
|
||||||
{0x003E0080, nullptr, "ReplySleepQuery"},
|
{0x00270044, CloseApplication, "CloseApplication"},
|
||||||
|
{0x002E0044, LeaveHomeMenu, "LeaveHomeMenu"},
|
||||||
|
{0x002F0040, PrepareToLeaveResidentApplet, "PrepareToLeaveResidentApplet"},
|
||||||
|
{0x00300044, LeaveResidentApplet, "LeaveResidentApplet"},
|
||||||
|
{0x00380040, PreloadResidentApplet, "PreloadResidentApplet"},
|
||||||
|
{0x00390040, PrepareToStartResidentApplet, "PrepareToStartResidentApplet"},
|
||||||
|
{0x003A0044, StartResidentApplet, "StartResidentApplet"},
|
||||||
|
{0x003B0040, CancelLibraryApplet, "CancelLibraryApplet?"},
|
||||||
|
{0x003E0080, ReplySleepQuery, "ReplySleepQuery"},
|
||||||
|
{0x003F0040, ReplySleepNotificationComplete,"ReplySleepNotificationComplete"},
|
||||||
|
{0x00400042, SendCaptureBufferInfo, "SendCaptureBufferInfo"},
|
||||||
|
{0x00410040, ReceiveCaptureBufferInfo, "ReceiveCaptureBufferInfo"},
|
||||||
{0x00430040, NotifyToWait, "NotifyToWait?"},
|
{0x00430040, NotifyToWait, "NotifyToWait?"},
|
||||||
{0x00440000, GetSharedFont, "GetSharedFont?"},
|
{0x00440000, GetSharedFont, "GetSharedFont?"},
|
||||||
|
{0x00450040, GetWirelessRebootInfo, "GetWirelessRebootInfo"},
|
||||||
|
{0x004A0040, GetCaptureInfo, "GetCaptureInfo"},
|
||||||
{0x004B00C2, AppletUtility, "AppletUtility?"},
|
{0x004B00C2, AppletUtility, "AppletUtility?"},
|
||||||
{0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"},
|
{0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"},
|
||||||
{0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"},
|
{0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"},
|
||||||
@ -36,7 +53,9 @@ const Interface::FunctionInfo FunctionTable[] = {
|
|||||||
{0x00550040, SetScreenCapPostPermission, "SetScreenCapPostPermission"},
|
{0x00550040, SetScreenCapPostPermission, "SetScreenCapPostPermission"},
|
||||||
{0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"},
|
{0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"},
|
||||||
{0x01010000, CheckNew3DSApp, "CheckNew3DSApp"},
|
{0x01010000, CheckNew3DSApp, "CheckNew3DSApp"},
|
||||||
{0x01020000, CheckNew3DS, "CheckNew3DS"}
|
{0x01020000, CheckNew3DS, "CheckNew3DS"},
|
||||||
|
{0x01040000, IsStandardMemoryLayout, "IsStandardMemoryLayout" },
|
||||||
|
{0x01050100, nullptr, "IsTitleAllowed" }
|
||||||
};
|
};
|
||||||
|
|
||||||
APT_A_Interface::APT_A_Interface() {
|
APT_A_Interface::APT_A_Interface() {
|
||||||
|
@ -16,7 +16,7 @@ const Interface::FunctionInfo FunctionTable[] = {
|
|||||||
{0x00050040, GetAppletManInfo, "GetAppletManInfo"},
|
{0x00050040, GetAppletManInfo, "GetAppletManInfo"},
|
||||||
{0x00060040, GetAppletInfo, "GetAppletInfo"},
|
{0x00060040, GetAppletInfo, "GetAppletInfo"},
|
||||||
{0x00070000, nullptr, "GetLastSignaledAppletId"},
|
{0x00070000, nullptr, "GetLastSignaledAppletId"},
|
||||||
{0x00080000, nullptr, "CountRegisteredApplet"},
|
{0x00080000, CountRegisteredApplet, "CountRegisteredApplet"},
|
||||||
{0x00090040, IsRegistered, "IsRegistered"},
|
{0x00090040, IsRegistered, "IsRegistered"},
|
||||||
{0x000A0040, nullptr, "GetAttribute"},
|
{0x000A0040, nullptr, "GetAttribute"},
|
||||||
{0x000B0040, InquireNotification, "InquireNotification"},
|
{0x000B0040, InquireNotification, "InquireNotification"},
|
||||||
@ -27,36 +27,36 @@ const Interface::FunctionInfo FunctionTable[] = {
|
|||||||
{0x001000C2, nullptr, "DebugFunc"},
|
{0x001000C2, nullptr, "DebugFunc"},
|
||||||
{0x001100C0, nullptr, "MapProgramIdForDebug"},
|
{0x001100C0, nullptr, "MapProgramIdForDebug"},
|
||||||
{0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"},
|
{0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"},
|
||||||
{0x00130000, nullptr, "GetPreparationState"},
|
{0x00130000, GetPreparationState, "GetPreparationState"},
|
||||||
{0x00140040, nullptr, "SetPreparationState"},
|
{0x00140040, SetPreparationState, "SetPreparationState"},
|
||||||
{0x00150140, PrepareToStartApplication, "PrepareToStartApplication"},
|
{0x00150140, PrepareToStartApplication, "PrepareToStartApplication"},
|
||||||
{0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"},
|
{0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"},
|
||||||
{0x00170040, nullptr, "FinishPreloadingLibraryApplet"},
|
{0x00170040, nullptr, "FinishPreloadingLibraryApplet"},
|
||||||
{0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"},
|
{0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"},
|
||||||
{0x00190040, nullptr, "PrepareToStartSystemApplet"},
|
{0x00190040, nullptr, "PrepareToStartSystemApplet"},
|
||||||
{0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"},
|
{0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"},
|
||||||
{0x001B00C4, nullptr, "StartApplication"},
|
{0x001B00C4, StartApplication, "StartApplication"},
|
||||||
{0x001C0000, nullptr, "WakeupApplication"},
|
{0x001C0000, nullptr, "WakeupApplication"},
|
||||||
{0x001D0000, nullptr, "CancelApplication"},
|
{0x001D0000, nullptr, "CancelApplication"},
|
||||||
{0x001E0084, StartLibraryApplet, "StartLibraryApplet"},
|
{0x001E0084, StartLibraryApplet, "StartLibraryApplet"},
|
||||||
{0x001F0084, nullptr, "StartSystemApplet"},
|
{0x001F0084, nullptr, "StartSystemApplet"},
|
||||||
{0x00200044, nullptr, "StartNewestHomeMenu"},
|
{0x00200044, nullptr, "StartNewestHomeMenu"},
|
||||||
{0x00210000, nullptr, "OrderToCloseApplication"},
|
{0x00210000, nullptr, "OrderToCloseApplication"},
|
||||||
{0x00220040, nullptr, "PrepareToCloseApplication"},
|
{0x00220040, PrepareToCloseApplication, "PrepareToCloseApplication"},
|
||||||
{0x00230040, nullptr, "PrepareToJumpToApplication"},
|
{0x00230040, nullptr, "PrepareToJumpToApplication"},
|
||||||
{0x00240044, nullptr, "JumpToApplication"},
|
{0x00240044, nullptr, "JumpToApplication"},
|
||||||
{0x002500C0, nullptr, "PrepareToCloseLibraryApplet"},
|
{0x002500C0, nullptr, "PrepareToCloseLibraryApplet"},
|
||||||
{0x00260000, nullptr, "PrepareToCloseSystemApplet"},
|
{0x00260000, nullptr, "PrepareToCloseSystemApplet"},
|
||||||
{0x00270044, nullptr, "CloseApplication"},
|
{0x00270044, CloseApplication, "CloseApplication"},
|
||||||
{0x00280044, nullptr, "CloseLibraryApplet"},
|
{0x00280044, nullptr, "CloseLibraryApplet"},
|
||||||
{0x00290044, nullptr, "CloseSystemApplet"},
|
{0x00290044, nullptr, "CloseSystemApplet"},
|
||||||
{0x002A0000, nullptr, "OrderToCloseSystemApplet"},
|
{0x002A0000, nullptr, "OrderToCloseSystemApplet"},
|
||||||
{0x002B0000, nullptr, "PrepareToJumpToHomeMenu"},
|
{0x002B0000, nullptr, "PrepareToJumpToHomeMenu"},
|
||||||
{0x002C0044, nullptr, "JumpToHomeMenu"},
|
{0x002C0044, nullptr, "JumpToHomeMenu"},
|
||||||
{0x002D0000, nullptr, "PrepareToLeaveHomeMenu"},
|
{0x002D0000, nullptr, "PrepareToLeaveHomeMenu"},
|
||||||
{0x002E0044, nullptr, "LeaveHomeMenu"},
|
{0x002E0044, LeaveHomeMenu, "LeaveHomeMenu"},
|
||||||
{0x002F0040, nullptr, "PrepareToLeaveResidentApplet"},
|
{0x002F0040, PrepareToLeaveResidentApplet, "PrepareToLeaveResidentApplet"},
|
||||||
{0x00300044, nullptr, "LeaveResidentApplet"},
|
{0x00300044, LeaveResidentApplet, "LeaveResidentApplet"},
|
||||||
{0x00310100, nullptr, "PrepareToDoApplicationJump"},
|
{0x00310100, nullptr, "PrepareToDoApplicationJump"},
|
||||||
{0x00320084, nullptr, "DoApplicationJump"},
|
{0x00320084, nullptr, "DoApplicationJump"},
|
||||||
{0x00330000, nullptr, "GetProgramIdOnApplicationJump"},
|
{0x00330000, nullptr, "GetProgramIdOnApplicationJump"},
|
||||||
@ -64,25 +64,25 @@ const Interface::FunctionInfo FunctionTable[] = {
|
|||||||
{0x00350080, nullptr, "ReceiveDeliverArg"},
|
{0x00350080, nullptr, "ReceiveDeliverArg"},
|
||||||
{0x00360040, nullptr, "LoadSysMenuArg"},
|
{0x00360040, nullptr, "LoadSysMenuArg"},
|
||||||
{0x00370042, nullptr, "StoreSysMenuArg"},
|
{0x00370042, nullptr, "StoreSysMenuArg"},
|
||||||
{0x00380040, nullptr, "PreloadResidentApplet"},
|
{0x00380040, PreloadResidentApplet, "PreloadResidentApplet"},
|
||||||
{0x00390040, nullptr, "PrepareToStartResidentApplet"},
|
{0x00390040, PrepareToStartResidentApplet, "PrepareToStartResidentApplet"},
|
||||||
{0x003A0044, nullptr, "StartResidentApplet"},
|
{0x003A0044, StartResidentApplet, "StartResidentApplet"},
|
||||||
{0x003B0040, nullptr, "CancelLibraryApplet"},
|
{0x003B0040, CancelLibraryApplet, "CancelLibraryApplet"},
|
||||||
{0x003C0042, nullptr, "SendDspSleep"},
|
{0x003C0042, nullptr, "SendDspSleep"},
|
||||||
{0x003D0042, nullptr, "SendDspWakeUp"},
|
{0x003D0042, nullptr, "SendDspWakeUp"},
|
||||||
{0x003E0080, nullptr, "ReplySleepQuery"},
|
{0x003E0080, ReplySleepQuery, "ReplySleepQuery"},
|
||||||
{0x003F0040, nullptr, "ReplySleepNotificationComplete"},
|
{0x003F0040, ReplySleepNotificationComplete, "ReplySleepNotificationComplete"},
|
||||||
{0x00400042, nullptr, "SendCaptureBufferInfo"},
|
{0x00400042, SendCaptureBufferInfo, "SendCaptureBufferInfo"},
|
||||||
{0x00410040, nullptr, "ReceiveCaptureBufferInfo"},
|
{0x00410040, ReceiveCaptureBufferInfo, "ReceiveCaptureBufferInfo"},
|
||||||
{0x00420080, nullptr, "SleepSystem"},
|
{0x00420080, nullptr, "SleepSystem"},
|
||||||
{0x00430040, NotifyToWait, "NotifyToWait"},
|
{0x00430040, NotifyToWait, "NotifyToWait"},
|
||||||
{0x00440000, GetSharedFont, "GetSharedFont"},
|
{0x00440000, GetSharedFont, "GetSharedFont"},
|
||||||
{0x00450040, nullptr, "GetWirelessRebootInfo"},
|
{0x00450040, GetWirelessRebootInfo, "GetWirelessRebootInfo"},
|
||||||
{0x00460104, nullptr, "Wrap"},
|
{0x00460104, nullptr, "Wrap"},
|
||||||
{0x00470104, nullptr, "Unwrap"},
|
{0x00470104, nullptr, "Unwrap"},
|
||||||
{0x00480100, nullptr, "GetProgramInfo"},
|
{0x00480100, nullptr, "GetProgramInfo"},
|
||||||
{0x00490180, nullptr, "Reboot"},
|
{0x00490180, nullptr, "Reboot"},
|
||||||
{0x004A0040, nullptr, "GetCaptureInfo"},
|
{0x004A0040, GetCaptureInfo, "GetCaptureInfo"},
|
||||||
{0x004B00C2, AppletUtility, "AppletUtility"},
|
{0x004B00C2, AppletUtility, "AppletUtility"},
|
||||||
{0x004C0000, nullptr, "SetFatalErrDispMode"},
|
{0x004C0000, nullptr, "SetFatalErrDispMode"},
|
||||||
{0x004D0080, nullptr, "GetAppletProgramInfo"},
|
{0x004D0080, nullptr, "GetAppletProgramInfo"},
|
||||||
@ -96,7 +96,9 @@ const Interface::FunctionInfo FunctionTable[] = {
|
|||||||
{0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"},
|
{0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"},
|
||||||
{0x00580002, nullptr, "GetProgramID"},
|
{0x00580002, nullptr, "GetProgramID"},
|
||||||
{0x01010000, CheckNew3DSApp, "CheckNew3DSApp"},
|
{0x01010000, CheckNew3DSApp, "CheckNew3DSApp"},
|
||||||
{0x01020000, CheckNew3DS, "CheckNew3DS"}
|
{0x01020000, CheckNew3DS, "CheckNew3DS"},
|
||||||
|
{0x01040000, IsStandardMemoryLayout, "IsStandardMemoryLayout"},
|
||||||
|
{0x01050100, nullptr, "IsTitleAllowed"}
|
||||||
};
|
};
|
||||||
|
|
||||||
APT_U_Interface::APT_U_Interface() {
|
APT_U_Interface::APT_U_Interface() {
|
||||||
|
@ -611,6 +611,7 @@ static void TriggerCmdReqQueue(Service::Interface* self) {
|
|||||||
* Inputs:
|
* Inputs:
|
||||||
* 0: Header 0x00180000
|
* 0: Header 0x00180000
|
||||||
* Outputs:
|
* Outputs:
|
||||||
|
* 0: Header Code[0x00180240]
|
||||||
* 1: Result code
|
* 1: Result code
|
||||||
* 2: Left framebuffer virtual address for the main screen
|
* 2: Left framebuffer virtual address for the main screen
|
||||||
* 3: Right framebuffer virtual address for the main screen
|
* 3: Right framebuffer virtual address for the main screen
|
||||||
@ -633,18 +634,19 @@ static void ImportDisplayCaptureInfo(Service::Interface* self) {
|
|||||||
FrameBufferUpdate* top_screen = GetFrameBufferInfo(thread_id, 0);
|
FrameBufferUpdate* top_screen = GetFrameBufferInfo(thread_id, 0);
|
||||||
FrameBufferUpdate* bottom_screen = GetFrameBufferInfo(thread_id, 1);
|
FrameBufferUpdate* bottom_screen = GetFrameBufferInfo(thread_id, 1);
|
||||||
|
|
||||||
|
cmd_buff[0] = IPC::MakeHeader(0x18, 0x9, 0);
|
||||||
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
|
//Top Screen
|
||||||
cmd_buff[2] = top_screen->framebuffer_info[top_screen->index].address_left;
|
cmd_buff[2] = top_screen->framebuffer_info[top_screen->index].address_left;
|
||||||
cmd_buff[3] = top_screen->framebuffer_info[top_screen->index].address_right;
|
cmd_buff[3] = top_screen->framebuffer_info[top_screen->index].address_right;
|
||||||
cmd_buff[4] = top_screen->framebuffer_info[top_screen->index].format;
|
cmd_buff[4] = top_screen->framebuffer_info[top_screen->index].format;
|
||||||
cmd_buff[5] = top_screen->framebuffer_info[top_screen->index].stride;
|
cmd_buff[5] = top_screen->framebuffer_info[top_screen->index].stride;
|
||||||
|
//Bottom Screen
|
||||||
cmd_buff[6] = bottom_screen->framebuffer_info[bottom_screen->index].address_left;
|
cmd_buff[6] = bottom_screen->framebuffer_info[bottom_screen->index].address_left;
|
||||||
cmd_buff[7] = bottom_screen->framebuffer_info[bottom_screen->index].address_right;
|
cmd_buff[7] = bottom_screen->framebuffer_info[bottom_screen->index].address_right;
|
||||||
cmd_buff[8] = bottom_screen->framebuffer_info[bottom_screen->index].format;
|
cmd_buff[8] = bottom_screen->framebuffer_info[bottom_screen->index].format;
|
||||||
cmd_buff[9] = bottom_screen->framebuffer_info[bottom_screen->index].stride;
|
cmd_buff[9] = bottom_screen->framebuffer_info[bottom_screen->index].stride;
|
||||||
|
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw;
|
|
||||||
|
|
||||||
LOG_WARNING(Service_GSP, "called");
|
LOG_WARNING(Service_GSP, "called");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user