Update the code of APT service(part2)
This commit is contained in:
		@@ -17,6 +17,7 @@
 | 
			
		||||
/// Detailed description of the error. This listing is likely incomplete.
 | 
			
		||||
enum class ErrorDescription : u32 {
 | 
			
		||||
    Success = 0,
 | 
			
		||||
    InvalidMemoryPermissions = 2,
 | 
			
		||||
    WrongPermission = 46,
 | 
			
		||||
    OS_InvalidBufferDescriptor = 48,
 | 
			
		||||
    WrongAddress = 53,
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
 | 
			
		||||
#include "core/hle/applets/applet.h"
 | 
			
		||||
#include "core/hle/config_mem.h"
 | 
			
		||||
#include "core/hle/service/service.h"
 | 
			
		||||
#include "core/hle/service/apt/apt.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/bcfnt/bcfnt.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/kernel/event.h"
 | 
			
		||||
@@ -21,6 +23,9 @@
 | 
			
		||||
#include "core/hle/kernel/process.h"
 | 
			
		||||
#include "core/hle/kernel/shared_memory.h"
 | 
			
		||||
 | 
			
		||||
#include "core/hw/gpu.h"
 | 
			
		||||
#include "core/settings.h"
 | 
			
		||||
 | 
			
		||||
namespace Service {
 | 
			
		||||
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 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
 | 
			
		||||
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
 | 
			
		||||
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) {
 | 
			
		||||
    next_parameter = parameter;
 | 
			
		||||
@@ -48,6 +100,16 @@ void SendParameter(const MessageParameter& parameter) {
 | 
			
		||||
    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) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
    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();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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) {
 | 
			
		||||
    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=%u", app_id);
 | 
			
		||||
    LOG_WARNING(Service_APT, "(STUBBED) app_id=0x%08X", app_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GetLockHandle(Service::Interface* self) {
 | 
			
		||||
@@ -127,6 +391,7 @@ void GetLockHandle(Service::Interface* self) {
 | 
			
		||||
void Enable(Service::Interface* self) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
    u32 attributes = cmd_buff[1];
 | 
			
		||||
 | 
			
		||||
    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
			
		||||
    parameter_event->Signal(); // Let the application know that it has been started
 | 
			
		||||
    LOG_WARNING(Service_APT, "(STUBBED) called attributes=0x%08X", attributes);
 | 
			
		||||
@@ -134,14 +399,22 @@ void Enable(Service::Interface* self) {
 | 
			
		||||
 | 
			
		||||
void GetAppletManInfo(Service::Interface* self) {
 | 
			
		||||
    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[2] = 0;
 | 
			
		||||
    cmd_buff[2] = static_cast<u32>(applet_pos);
 | 
			
		||||
    cmd_buff[3] = 0;
 | 
			
		||||
    cmd_buff[4] = static_cast<u32>(AppletId::HomeMenu); // Home menu AppID
 | 
			
		||||
    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) {
 | 
			
		||||
@@ -164,6 +437,7 @@ void IsRegistered(Service::Interface* self) {
 | 
			
		||||
void InquireNotification(Service::Interface* self) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
    u32 app_id = cmd_buff[1];
 | 
			
		||||
 | 
			
		||||
    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
			
		||||
    cmd_buff[2] = static_cast<u32>(SignalType::None); // Signal type
 | 
			
		||||
    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 app_id = cmd_buff[1];
 | 
			
		||||
    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[2] = next_parameter.sender_id;
 | 
			
		||||
@@ -229,7 +503,7 @@ void GlanceParameter(Service::Interface* self) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
    u32 app_id = cmd_buff[1];
 | 
			
		||||
    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[2] = next_parameter.sender_id;
 | 
			
		||||
@@ -249,16 +523,32 @@ void GlanceParameter(Service::Interface* self) {
 | 
			
		||||
 | 
			
		||||
void CancelParameter(Service::Interface* self) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
    u32 flag1  = cmd_buff[1];
 | 
			
		||||
    u32 unk    = cmd_buff[2];
 | 
			
		||||
    u32 flag2  = cmd_buff[3];
 | 
			
		||||
    u32 app_id = cmd_buff[4];
 | 
			
		||||
    u32 check_sender   = cmd_buff[1] & 0xFF;
 | 
			
		||||
    u32 sender_id      = cmd_buff[2];
 | 
			
		||||
    u32 check_receiver = cmd_buff[3] & 0xFF;
 | 
			
		||||
    u32 receiver_id    = cmd_buff[4];
 | 
			
		||||
 | 
			
		||||
    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
			
		||||
    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",
 | 
			
		||||
                flag1, unk, flag2, app_id);
 | 
			
		||||
    LOG_WARNING(Service_APT, "(STUBBED) check_sender=0x%08X, sender_id=0x%08X, check_receiver=0x%08X, receiver_id=0x%08X",
 | 
			
		||||
                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) {
 | 
			
		||||
@@ -281,36 +571,119 @@ void PrepareToStartApplication(Service::Interface* self) {
 | 
			
		||||
 | 
			
		||||
void StartApplication(Service::Interface* self) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
    u32 buffer1_size = cmd_buff[1];
 | 
			
		||||
    u32 buffer2_size = cmd_buff[2];
 | 
			
		||||
    u32 flag         = cmd_buff[3];
 | 
			
		||||
    u32 size1        = cmd_buff[4];
 | 
			
		||||
    u32 buffer1_ptr  = cmd_buff[5];
 | 
			
		||||
    u32 size2        = cmd_buff[6];
 | 
			
		||||
    u32 buffer2_ptr  = cmd_buff[7];
 | 
			
		||||
    u32 parameter_size   = cmd_buff[1];
 | 
			
		||||
    u32 hmac_size        = cmd_buff[2];
 | 
			
		||||
    u32 is_paused        = cmd_buff[3] & 0xFF;
 | 
			
		||||
    u32 parameter_transition = cmd_buff[4];
 | 
			
		||||
    u32 parameter_buffer = cmd_buff[5];
 | 
			
		||||
    u32 hmac_transtion   = cmd_buff[6];
 | 
			
		||||
    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
 | 
			
		||||
    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,"
 | 
			
		||||
               "size1=0x%08X, buffer1_ptr=0x%08X, size2=0x%08X, buffer2_ptr=0x%08X",
 | 
			
		||||
               buffer1_size, buffer2_size, flag, size1, buffer1_ptr, size2, buffer2_ptr);
 | 
			
		||||
ResultCode AppletUtility(u32& utility_id, u32& input_buffer, u32& input_size, u32& output_buffer,u32& output_size, bool applet_result) {
 | 
			
		||||
    u32 sender_id = 0;
 | 
			
		||||
    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) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
 | 
			
		||||
    // These are from 3dbrew - I'm not really sure what they're used for.
 | 
			
		||||
    u32 command = cmd_buff[1];
 | 
			
		||||
    u32 buffer1_size = cmd_buff[2];
 | 
			
		||||
    u32 buffer2_size = cmd_buff[3];
 | 
			
		||||
    u32 buffer1_addr = cmd_buff[5];
 | 
			
		||||
    u32 buffer2_addr = cmd_buff[65];
 | 
			
		||||
    u32 utility_id        = cmd_buff[1];
 | 
			
		||||
    u32 input_size        = cmd_buff[2];
 | 
			
		||||
    u32 output_size       = (cmd_buff[3] > 0x1000) ? 0x1000 : cmd_buff[3];
 | 
			
		||||
    u32 input_traslation  = cmd_buff[4];
 | 
			
		||||
    u32 input_buffer      = cmd_buff[5];
 | 
			
		||||
    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, "
 | 
			
		||||
             "buffer1_addr=0x%08X, buffer2_addr=0x%08X", command, buffer1_size, buffer2_size,
 | 
			
		||||
             buffer1_addr, buffer2_addr);
 | 
			
		||||
    if (input_size > 0x1000) {
 | 
			
		||||
        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(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) {
 | 
			
		||||
@@ -410,6 +783,45 @@ void GetScreenCapPostPermission(Service::Interface* self) {
 | 
			
		||||
    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) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
    auto app_id = static_cast<AppletId>(cmd_buff[1]);
 | 
			
		||||
@@ -431,18 +843,20 @@ void GetAppletInfo(Service::Interface* self) {
 | 
			
		||||
void GetStartupArgument(Service::Interface* self) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
    u32 parameter_size = cmd_buff[1];
 | 
			
		||||
    u32 parameter_buffer = cmd_buff[0x41];
 | 
			
		||||
 | 
			
		||||
    StartupArgumentType startup_argument_type = static_cast<StartupArgumentType>(cmd_buff[2]);
 | 
			
		||||
 | 
			
		||||
    if (parameter_size >= 0x300) {
 | 
			
		||||
        LOG_ERROR(Service_APT, "Parameter size is outside the valid range (capped to 0x300): parameter_size=0x%08x", parameter_size);
 | 
			
		||||
        return;
 | 
			
		||||
    if (parameter_size > 0x1000) {
 | 
			
		||||
        parameter_size = 0x1000;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_APT,"(stubbed) called startup_argument_type=%u , parameter_size=0x%08x , parameter_value=0x%08x",
 | 
			
		||||
                startup_argument_type, parameter_size, Memory::Read32(cmd_buff[41]));
 | 
			
		||||
    LOG_WARNING(Service_APT,"(STUBBED) called startup_argument_type=%u , parameter_size=0x%08x , parameter_buffer=0x%08x",
 | 
			
		||||
                startup_argument_type, parameter_size, parameter_buffer);
 | 
			
		||||
 | 
			
		||||
    cmd_buff[1] = RESULT_SUCCESS.raw;
 | 
			
		||||
    cmd_buff[2] = (parameter_size > 0) ? 1 : 0;
 | 
			
		||||
    cmd_buff[3] = (parameter_size << 14) | 2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CheckNew3DSApp(Service::Interface* self) {
 | 
			
		||||
@@ -468,6 +882,31 @@ void CheckNew3DS(Service::Interface* self) {
 | 
			
		||||
    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() {
 | 
			
		||||
    AddService(new APT_A_Interface);
 | 
			
		||||
    AddService(new APT_S_Interface);
 | 
			
		||||
@@ -501,7 +940,7 @@ void Init() {
 | 
			
		||||
    lock = Kernel::Mutex::Create(false, "APT_U:Lock");
 | 
			
		||||
 | 
			
		||||
    cpu_percent = 0;
 | 
			
		||||
    unknown_ns_state_field = 0;
 | 
			
		||||
    homemenu_input_buffer = 0;
 | 
			
		||||
    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.
 | 
			
		||||
@@ -513,6 +952,8 @@ void Init() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Shutdown() {
 | 
			
		||||
    is_capture_buffer_info_set = false;
 | 
			
		||||
    is_homemenu_input_buffer_set = false;
 | 
			
		||||
    shared_font_mem = nullptr;
 | 
			
		||||
    shared_font_relocated = false;
 | 
			
		||||
    lock = nullptr;
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,8 @@
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <array>
 | 
			
		||||
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "common/swap.h"
 | 
			
		||||
 | 
			
		||||
@@ -44,6 +46,13 @@ struct CaptureBufferInfo {
 | 
			
		||||
};
 | 
			
		||||
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
 | 
			
		||||
enum class SignalType : u32 {
 | 
			
		||||
    None              = 0x0,
 | 
			
		||||
@@ -70,12 +79,12 @@ enum class AppletId : u32 {
 | 
			
		||||
    AmiiboSettings     = 0x119,
 | 
			
		||||
    SoftwareKeyboard1  = 0x201,
 | 
			
		||||
    Ed1                = 0x202,
 | 
			
		||||
    PnoteApp           = 0x204,
 | 
			
		||||
    SnoteApp           = 0x205,
 | 
			
		||||
    PnoteApp1          = 0x204,
 | 
			
		||||
    SnoteApp1          = 0x205,
 | 
			
		||||
    Error              = 0x206,
 | 
			
		||||
    Mint               = 0x207,
 | 
			
		||||
    Extrapad           = 0x208,
 | 
			
		||||
    Memolib            = 0x209,
 | 
			
		||||
    Mint1              = 0x207,
 | 
			
		||||
    Extrapad1          = 0x208,
 | 
			
		||||
    Memolib1           = 0x209,
 | 
			
		||||
    Application        = 0x300,
 | 
			
		||||
    AnyLibraryApplet   = 0x400,
 | 
			
		||||
    SoftwareKeyboard2  = 0x401,
 | 
			
		||||
@@ -88,6 +97,15 @@ enum class AppletId : u32 {
 | 
			
		||||
    Memolib2           = 0x409,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum class AppletPos {
 | 
			
		||||
    None     = -1,
 | 
			
		||||
    App      = 0,
 | 
			
		||||
    AppLib   = 1,
 | 
			
		||||
    Sys      = 2,
 | 
			
		||||
    SysLib   = 3,
 | 
			
		||||
    Resident = 4
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum class StartupArgumentType : u32 {
 | 
			
		||||
    OtherApp   = 0,
 | 
			
		||||
    Restart    = 1,
 | 
			
		||||
@@ -101,6 +119,49 @@ enum class ScreencapPostPermission : u32 {
 | 
			
		||||
    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
 | 
			
		||||
void SendParameter(const MessageParameter& parameter);
 | 
			
		||||
 | 
			
		||||
@@ -123,6 +184,149 @@ void Initialize(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
 | 
			
		||||
 *  Inputs:
 | 
			
		||||
@@ -157,11 +361,11 @@ void Enable(Service::Interface* self);
 | 
			
		||||
/**
 | 
			
		||||
 * APT::GetAppletManInfo service function.
 | 
			
		||||
 *  Inputs:
 | 
			
		||||
 *      1 : Unknown
 | 
			
		||||
 *      1 : AppletPos
 | 
			
		||||
 *  Outputs:
 | 
			
		||||
 *      1 : Result of function, 0 on success, otherwise error code
 | 
			
		||||
 *      2 : Unknown u32 value
 | 
			
		||||
 *      3 : Unknown u8 value
 | 
			
		||||
 *      2 : AppletPos
 | 
			
		||||
 *      3 : Requested AppId
 | 
			
		||||
 *      4 : Home Menu AppId
 | 
			
		||||
 *      5 : AppID of currently active app
 | 
			
		||||
 */
 | 
			
		||||
@@ -182,19 +386,37 @@ void GetAppletManInfo(Service::Interface* self);
 | 
			
		||||
void GetAppletInfo(Service::Interface* self);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * APT::IsRegistered service function. 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.
 | 
			
		||||
 * APT::CountRegisteredApplet service function.
 | 
			
		||||
 *  Outputs:
 | 
			
		||||
 *      1 : Result of function, 0 on success, otherwise error code
 | 
			
		||||
 *      2 : Registered Applet Count
 | 
			
		||||
 */
 | 
			
		||||
void CountRegisteredApplet(Service::Interface* self);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * APT::IsRegistered service function
 | 
			
		||||
 *  Inputs:
 | 
			
		||||
 *      1 : AppID
 | 
			
		||||
 *  Outputs:
 | 
			
		||||
 *      0 : Return header
 | 
			
		||||
 *      1 : Result of function, 0 on success, otherwise error code
 | 
			
		||||
 *      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);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -215,11 +437,7 @@ void InquireNotification(Service::Interface* self);
 | 
			
		||||
void SendParameter(Service::Interface* self);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * APT::ReceiveParameter service function. 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.
 | 
			
		||||
 * APT::ReceiveParameter service function
 | 
			
		||||
 *  Inputs:
 | 
			
		||||
 *      1 : AppID
 | 
			
		||||
 *      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
 | 
			
		||||
 *      7 : Size
 | 
			
		||||
 *      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);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * APT::GlanceParameter service function. 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.
 | 
			
		||||
 * APT::GlanceParameter service function
 | 
			
		||||
 *  Inputs:
 | 
			
		||||
 *      1 : AppID
 | 
			
		||||
 *      2 : Parameter buffer size, max size is 0x1000
 | 
			
		||||
 *  Outputs:
 | 
			
		||||
 *      1 : Result of function, 0 on success, otherwise error code
 | 
			
		||||
 *      2 : Unknown, for now assume AppID of the process which sent these parameters
 | 
			
		||||
 *      3 : Unknown, for now assume Signal type
 | 
			
		||||
 *      2 : Sender AppID, for now assume AppID of the process which sent these parameters
 | 
			
		||||
 *      3 : Command, for now assume Signal type
 | 
			
		||||
 *      4 : Actual parameter buffer size, this is <= to the the input size
 | 
			
		||||
 *      5 : Value
 | 
			
		||||
 *      6 : Handle from the source process which set the parameters, likely used for shared memory
 | 
			
		||||
 *      7 : Size
 | 
			
		||||
 *      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);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * APT::CancelParameter service function. 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).
 | 
			
		||||
 * APT::CancelParameter service function.
 | 
			
		||||
 *  Inputs:
 | 
			
		||||
 *      1 : Flag, when non-zero NS will compare the word after this one with a field in the NS state.
 | 
			
		||||
 *      2 : Unknown, this is the same as the first unknown field returned by APT:ReceiveParameter.
 | 
			
		||||
 *      3 : Flag, when non-zero NS will compare the word after this one with a field in the NS state.
 | 
			
		||||
 *      4 : AppID
 | 
			
		||||
 *      1 : u8, Check Sender (0 = don't check, 1 = check)
 | 
			
		||||
 *      2 : Sender AppID
 | 
			
		||||
 *      3 : u8, Check Receiver (0 = don't check, 1 = check)
 | 
			
		||||
 *      4 : Receiver AppID
 | 
			
		||||
 *  Outputs:
 | 
			
		||||
 *      0 : Return header
 | 
			
		||||
 *      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
 | 
			
		||||
 *          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);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * APT::PrepareToStartApplication service function. When the input title-info programID is zero,
 | 
			
		||||
 * 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
 | 
			
		||||
 * 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
 | 
			
		||||
 * (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
 | 
			
		||||
 * 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-4 : 0x10-byte title-info struct
 | 
			
		||||
 *      4 : Flags
 | 
			
		||||
 *      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
 | 
			
		||||
 *      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
 | 
			
		||||
 *      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
 | 
			
		||||
 *      field to value 1 when input flags bit8 is set
 | 
			
		||||
 */
 | 
			
		||||
void PrepareToStartApplication(Service::Interface* self);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * APT::StartApplication service function. Buf0 is copied to NS FIRMparams+0x0, then Buf1 is copied
 | 
			
		||||
 * to the NS FIRMparams+0x480. Then the application is launched.
 | 
			
		||||
 * APT::StartApplication service function.
 | 
			
		||||
 * Inputs:
 | 
			
		||||
 *     1 : Buffer 0 size, max size is 0x300
 | 
			
		||||
 *     2 : Buffer 1 size, max size is 0x20 (this can be zero)
 | 
			
		||||
 *     3 : u8 flag
 | 
			
		||||
 *     4 : (Size0<<14) | 2
 | 
			
		||||
 *     5 : Buffer 0 pointer
 | 
			
		||||
 *     6 : (Size1<<14) | 0x802
 | 
			
		||||
 *     7 : Buffer 1 pointer
 | 
			
		||||
 *     1 : Parameter Size (capped to 0x300)
 | 
			
		||||
 *     2 : HMAC Size (capped to 0x20)
 | 
			
		||||
 *     3 : u8 Paused (0 = not paused, 1 = paused)
 | 
			
		||||
 *     4 : (Parameter Size << 14) | 2
 | 
			
		||||
 *     5 : void*, Parameter
 | 
			
		||||
 *     6 : (HMAC Size << 14) | 0x802
 | 
			
		||||
 *     7 : void*, HMAC
 | 
			
		||||
 * Outputs:
 | 
			
		||||
 *     0 : Return Header
 | 
			
		||||
 *     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);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * APT::AppletUtility service function
 | 
			
		||||
 *  Inputs:
 | 
			
		||||
 *      1 : Unknown, but clearly used for something
 | 
			
		||||
 *      2 : Buffer 1 size (purpose is unknown)
 | 
			
		||||
 *      3 : Buffer 2 size (purpose is unknown)
 | 
			
		||||
 *      5 : Buffer 1 address (purpose is unknown)
 | 
			
		||||
 *      65 : Buffer 2 address (purpose is unknown)
 | 
			
		||||
 *      1 : UtilityID
 | 
			
		||||
 *      2 : Input Size
 | 
			
		||||
 *      3 : Output Size
 | 
			
		||||
 *      4 : (Input Size << 14) | 0x402
 | 
			
		||||
 *      5 : void*, Input
 | 
			
		||||
 *   0x41 : void*, Output
 | 
			
		||||
 *  Outputs:
 | 
			
		||||
 *      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);
 | 
			
		||||
 | 
			
		||||
@@ -378,14 +629,50 @@ void PreloadLibraryApplet(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
 | 
			
		||||
 *  Inputs:
 | 
			
		||||
 *      1 : Parameter Size (capped to 0x300)
 | 
			
		||||
 *      2 : StartupArgumentType
 | 
			
		||||
 *  Outputs:
 | 
			
		||||
 *      0 : Return header
 | 
			
		||||
 *      1 : u8, Exists (0 = does not exist, 1 = exists)
 | 
			
		||||
 *      1 : Result of function, 0 on success, otherwise error code
 | 
			
		||||
 *      2 : u8, Exists (0 = does not exist, 1 = exists)
 | 
			
		||||
 */
 | 
			
		||||
void GetStartupArgument(Service::Interface* self);
 | 
			
		||||
 | 
			
		||||
@@ -432,6 +719,17 @@ void CheckNew3DSApp(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
 | 
			
		||||
void Init();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,20 +15,37 @@ const Interface::FunctionInfo FunctionTable[] = {
 | 
			
		||||
    {0x00040040, nullptr,                      "Finalize?"},
 | 
			
		||||
    {0x00050040, GetAppletManInfo,             "GetAppletManInfo"},
 | 
			
		||||
    {0x00060040, GetAppletInfo,                "GetAppletInfo"},
 | 
			
		||||
    {0x00080000, CountRegisteredApplet,        "CountRegisteredApplet"},
 | 
			
		||||
    {0x00090040, IsRegistered,                 "IsRegistered"},
 | 
			
		||||
    {0x000B0040, InquireNotification,          "InquireNotification"},
 | 
			
		||||
    {0x000C0104, SendParameter,                "SendParameter"},
 | 
			
		||||
    {0x000D0080, ReceiveParameter,             "ReceiveParameter"},
 | 
			
		||||
    {0x000E0080, GlanceParameter,              "GlanceParameter"},
 | 
			
		||||
    {0x000F0100, CancelParameter,              "CancelParameter"},
 | 
			
		||||
    {0x00130000, GetPreparationState,          "GetPreparationState"},
 | 
			
		||||
    {0x00140040, SetPreparationState,          "SetPreparationState"},
 | 
			
		||||
    {0x00150140, PrepareToStartApplication,    "PrepareToStartApplication"},
 | 
			
		||||
    {0x00160040, PreloadLibraryApplet,         "PreloadLibraryApplet"},
 | 
			
		||||
    {0x00180040, PrepareToStartLibraryApplet,  "PrepareToStartLibraryApplet"},
 | 
			
		||||
    {0x001B00C4, StartApplication,             "StartApplication"},
 | 
			
		||||
    {0x001E0084, StartLibraryApplet,           "StartLibraryApplet"},
 | 
			
		||||
    {0x003B0040, nullptr,                      "CancelLibraryApplet?"},
 | 
			
		||||
    {0x003E0080, nullptr,                      "ReplySleepQuery"},
 | 
			
		||||
    {0x00220040, PrepareToCloseApplication,    "PrepareToCloseApplication"},
 | 
			
		||||
    {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?"},
 | 
			
		||||
    {0x00440000, GetSharedFont,                "GetSharedFont?"},
 | 
			
		||||
    {0x00450040, GetWirelessRebootInfo,        "GetWirelessRebootInfo"},
 | 
			
		||||
    {0x004A0040, GetCaptureInfo,               "GetCaptureInfo"},
 | 
			
		||||
    {0x004B00C2, AppletUtility,                "AppletUtility?"},
 | 
			
		||||
    {0x004F0080, SetAppCpuTimeLimit,           "SetAppCpuTimeLimit"},
 | 
			
		||||
    {0x00500040, GetAppCpuTimeLimit,           "GetAppCpuTimeLimit"},
 | 
			
		||||
@@ -36,7 +53,9 @@ const Interface::FunctionInfo FunctionTable[] = {
 | 
			
		||||
    {0x00550040, SetScreenCapPostPermission,   "SetScreenCapPostPermission"},
 | 
			
		||||
    {0x00560000, GetScreenCapPostPermission,   "GetScreenCapPostPermission"},
 | 
			
		||||
    {0x01010000, CheckNew3DSApp,               "CheckNew3DSApp"},
 | 
			
		||||
    {0x01020000, CheckNew3DS,                  "CheckNew3DS"}
 | 
			
		||||
    {0x01020000, CheckNew3DS,                  "CheckNew3DS"},
 | 
			
		||||
    {0x01040000, IsStandardMemoryLayout,       "IsStandardMemoryLayout" },
 | 
			
		||||
    {0x01050100, nullptr,                      "IsTitleAllowed" }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
APT_A_Interface::APT_A_Interface() {
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ const Interface::FunctionInfo FunctionTable[] = {
 | 
			
		||||
    {0x00050040, GetAppletManInfo,                "GetAppletManInfo"},
 | 
			
		||||
    {0x00060040, GetAppletInfo,                   "GetAppletInfo"},
 | 
			
		||||
    {0x00070000, nullptr,                         "GetLastSignaledAppletId"},
 | 
			
		||||
    {0x00080000, nullptr,                         "CountRegisteredApplet"},
 | 
			
		||||
    {0x00080000, CountRegisteredApplet,           "CountRegisteredApplet"},
 | 
			
		||||
    {0x00090040, IsRegistered,                    "IsRegistered"},
 | 
			
		||||
    {0x000A0040, nullptr,                         "GetAttribute"},
 | 
			
		||||
    {0x000B0040, InquireNotification,             "InquireNotification"},
 | 
			
		||||
@@ -27,36 +27,36 @@ const Interface::FunctionInfo FunctionTable[] = {
 | 
			
		||||
    {0x001000C2, nullptr,                         "DebugFunc"},
 | 
			
		||||
    {0x001100C0, nullptr,                         "MapProgramIdForDebug"},
 | 
			
		||||
    {0x00120040, nullptr,                         "SetHomeMenuAppletIdForDebug"},
 | 
			
		||||
    {0x00130000, nullptr,                         "GetPreparationState"},
 | 
			
		||||
    {0x00140040, nullptr,                         "SetPreparationState"},
 | 
			
		||||
    {0x00130000, GetPreparationState,             "GetPreparationState"},
 | 
			
		||||
    {0x00140040, SetPreparationState,             "SetPreparationState"},
 | 
			
		||||
    {0x00150140, PrepareToStartApplication,       "PrepareToStartApplication"},
 | 
			
		||||
    {0x00160040, PreloadLibraryApplet,            "PreloadLibraryApplet"},
 | 
			
		||||
    {0x00170040, nullptr,                         "FinishPreloadingLibraryApplet"},
 | 
			
		||||
    {0x00180040, PrepareToStartLibraryApplet,     "PrepareToStartLibraryApplet"},
 | 
			
		||||
    {0x00190040, nullptr,                         "PrepareToStartSystemApplet"},
 | 
			
		||||
    {0x001A0000, nullptr,                         "PrepareToStartNewestHomeMenu"},
 | 
			
		||||
    {0x001B00C4, nullptr,                         "StartApplication"},
 | 
			
		||||
    {0x001B00C4, StartApplication,                "StartApplication"},
 | 
			
		||||
    {0x001C0000, nullptr,                         "WakeupApplication"},
 | 
			
		||||
    {0x001D0000, nullptr,                         "CancelApplication"},
 | 
			
		||||
    {0x001E0084, StartLibraryApplet,              "StartLibraryApplet"},
 | 
			
		||||
    {0x001F0084, nullptr,                         "StartSystemApplet"},
 | 
			
		||||
    {0x00200044, nullptr,                         "StartNewestHomeMenu"},
 | 
			
		||||
    {0x00210000, nullptr,                         "OrderToCloseApplication"},
 | 
			
		||||
    {0x00220040, nullptr,                         "PrepareToCloseApplication"},
 | 
			
		||||
    {0x00220040, PrepareToCloseApplication,       "PrepareToCloseApplication"},
 | 
			
		||||
    {0x00230040, nullptr,                         "PrepareToJumpToApplication"},
 | 
			
		||||
    {0x00240044, nullptr,                         "JumpToApplication"},
 | 
			
		||||
    {0x002500C0, nullptr,                         "PrepareToCloseLibraryApplet"},
 | 
			
		||||
    {0x00260000, nullptr,                         "PrepareToCloseSystemApplet"},
 | 
			
		||||
    {0x00270044, nullptr,                         "CloseApplication"},
 | 
			
		||||
    {0x00270044, CloseApplication,                "CloseApplication"},
 | 
			
		||||
    {0x00280044, nullptr,                         "CloseLibraryApplet"},
 | 
			
		||||
    {0x00290044, nullptr,                         "CloseSystemApplet"},
 | 
			
		||||
    {0x002A0000, nullptr,                         "OrderToCloseSystemApplet"},
 | 
			
		||||
    {0x002B0000, nullptr,                         "PrepareToJumpToHomeMenu"},
 | 
			
		||||
    {0x002C0044, nullptr,                         "JumpToHomeMenu"},
 | 
			
		||||
    {0x002D0000, nullptr,                         "PrepareToLeaveHomeMenu"},
 | 
			
		||||
    {0x002E0044, nullptr,                         "LeaveHomeMenu"},
 | 
			
		||||
    {0x002F0040, nullptr,                         "PrepareToLeaveResidentApplet"},
 | 
			
		||||
    {0x00300044, nullptr,                         "LeaveResidentApplet"},
 | 
			
		||||
    {0x002E0044, LeaveHomeMenu,                   "LeaveHomeMenu"},
 | 
			
		||||
    {0x002F0040, PrepareToLeaveResidentApplet,    "PrepareToLeaveResidentApplet"},
 | 
			
		||||
    {0x00300044, LeaveResidentApplet,             "LeaveResidentApplet"},
 | 
			
		||||
    {0x00310100, nullptr,                         "PrepareToDoApplicationJump"},
 | 
			
		||||
    {0x00320084, nullptr,                         "DoApplicationJump"},
 | 
			
		||||
    {0x00330000, nullptr,                         "GetProgramIdOnApplicationJump"},
 | 
			
		||||
@@ -64,25 +64,25 @@ const Interface::FunctionInfo FunctionTable[] = {
 | 
			
		||||
    {0x00350080, nullptr,                         "ReceiveDeliverArg"},
 | 
			
		||||
    {0x00360040, nullptr,                         "LoadSysMenuArg"},
 | 
			
		||||
    {0x00370042, nullptr,                         "StoreSysMenuArg"},
 | 
			
		||||
    {0x00380040, nullptr,                         "PreloadResidentApplet"},
 | 
			
		||||
    {0x00390040, nullptr,                         "PrepareToStartResidentApplet"},
 | 
			
		||||
    {0x003A0044, nullptr,                         "StartResidentApplet"},
 | 
			
		||||
    {0x003B0040, nullptr,                         "CancelLibraryApplet"},
 | 
			
		||||
    {0x00380040, PreloadResidentApplet,           "PreloadResidentApplet"},
 | 
			
		||||
    {0x00390040, PrepareToStartResidentApplet,    "PrepareToStartResidentApplet"},
 | 
			
		||||
    {0x003A0044, StartResidentApplet,             "StartResidentApplet"},
 | 
			
		||||
    {0x003B0040, CancelLibraryApplet,             "CancelLibraryApplet"},
 | 
			
		||||
    {0x003C0042, nullptr,                         "SendDspSleep"},
 | 
			
		||||
    {0x003D0042, nullptr,                         "SendDspWakeUp"},
 | 
			
		||||
    {0x003E0080, nullptr,                         "ReplySleepQuery"},
 | 
			
		||||
    {0x003F0040, nullptr,                         "ReplySleepNotificationComplete"},
 | 
			
		||||
    {0x00400042, nullptr,                         "SendCaptureBufferInfo"},
 | 
			
		||||
    {0x00410040, nullptr,                         "ReceiveCaptureBufferInfo"},
 | 
			
		||||
    {0x003E0080, ReplySleepQuery,                 "ReplySleepQuery"},
 | 
			
		||||
    {0x003F0040, ReplySleepNotificationComplete,  "ReplySleepNotificationComplete"},
 | 
			
		||||
    {0x00400042, SendCaptureBufferInfo,           "SendCaptureBufferInfo"},
 | 
			
		||||
    {0x00410040, ReceiveCaptureBufferInfo,        "ReceiveCaptureBufferInfo"},
 | 
			
		||||
    {0x00420080, nullptr,                         "SleepSystem"},
 | 
			
		||||
    {0x00430040, NotifyToWait,                    "NotifyToWait"},
 | 
			
		||||
    {0x00440000, GetSharedFont,                   "GetSharedFont"},
 | 
			
		||||
    {0x00450040, nullptr,                         "GetWirelessRebootInfo"},
 | 
			
		||||
    {0x00450040, GetWirelessRebootInfo,           "GetWirelessRebootInfo"},
 | 
			
		||||
    {0x00460104, nullptr,                         "Wrap"},
 | 
			
		||||
    {0x00470104, nullptr,                         "Unwrap"},
 | 
			
		||||
    {0x00480100, nullptr,                         "GetProgramInfo"},
 | 
			
		||||
    {0x00490180, nullptr,                         "Reboot"},
 | 
			
		||||
    {0x004A0040, nullptr,                         "GetCaptureInfo"},
 | 
			
		||||
    {0x004A0040, GetCaptureInfo,                  "GetCaptureInfo"},
 | 
			
		||||
    {0x004B00C2, AppletUtility,                   "AppletUtility"},
 | 
			
		||||
    {0x004C0000, nullptr,                         "SetFatalErrDispMode"},
 | 
			
		||||
    {0x004D0080, nullptr,                         "GetAppletProgramInfo"},
 | 
			
		||||
@@ -96,7 +96,9 @@ const Interface::FunctionInfo FunctionTable[] = {
 | 
			
		||||
    {0x00560000, GetScreenCapPostPermission,      "GetScreenCapPostPermission"},
 | 
			
		||||
    {0x00580002, nullptr,                         "GetProgramID"},
 | 
			
		||||
    {0x01010000, CheckNew3DSApp,                  "CheckNew3DSApp"},
 | 
			
		||||
    {0x01020000, CheckNew3DS,                     "CheckNew3DS"}
 | 
			
		||||
    {0x01020000, CheckNew3DS,                     "CheckNew3DS"},
 | 
			
		||||
    {0x01040000, IsStandardMemoryLayout,          "IsStandardMemoryLayout"},
 | 
			
		||||
    {0x01050100, nullptr,                         "IsTitleAllowed"}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
APT_U_Interface::APT_U_Interface() {
 | 
			
		||||
 
 | 
			
		||||
@@ -611,6 +611,7 @@ static void TriggerCmdReqQueue(Service::Interface* self) {
 | 
			
		||||
 *  Inputs:
 | 
			
		||||
 *      0: Header 0x00180000
 | 
			
		||||
 *  Outputs:
 | 
			
		||||
 *      0: Header Code[0x00180240]
 | 
			
		||||
 *      1: Result code
 | 
			
		||||
 *      2: Left 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* 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[3] = top_screen->framebuffer_info[top_screen->index].address_right;
 | 
			
		||||
    cmd_buff[4] = top_screen->framebuffer_info[top_screen->index].format;
 | 
			
		||||
    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[7] = bottom_screen->framebuffer_info[bottom_screen->index].address_right;
 | 
			
		||||
    cmd_buff[8] = bottom_screen->framebuffer_info[bottom_screen->index].format;
 | 
			
		||||
    cmd_buff[9] = bottom_screen->framebuffer_info[bottom_screen->index].stride;
 | 
			
		||||
 | 
			
		||||
    cmd_buff[1] = RESULT_SUCCESS.raw;
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_GSP, "called");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user