mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-11-04 12:45:03 +01:00 
			
		
		
		
	Merge pull request #12011 from Macj0rdan/controller-applet
Implemented qlaunch version of the controller applet
This commit is contained in:
		
						commit
						8da5bd27e9
					
				@ -218,6 +218,13 @@ enum class NpadIdType : u32 {
 | 
			
		||||
    Invalid = 0xFFFFFFFF,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum class NpadInterfaceType : u8 {
 | 
			
		||||
    Bluetooth = 1,
 | 
			
		||||
    Rail = 2,
 | 
			
		||||
    Usb = 3,
 | 
			
		||||
    Embedded = 4,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// This is nn::hid::NpadStyleIndex
 | 
			
		||||
enum class NpadStyleIndex : u8 {
 | 
			
		||||
    None = 0,
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,7 @@
 | 
			
		||||
#include "core/file_sys/patch_manager.h"
 | 
			
		||||
#include "core/file_sys/registered_cache.h"
 | 
			
		||||
#include "core/file_sys/savedata_factory.h"
 | 
			
		||||
#include "core/hid/hid_types.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_transfer_memory.h"
 | 
			
		||||
#include "core/hle/result.h"
 | 
			
		||||
@ -21,6 +22,7 @@
 | 
			
		||||
#include "core/hle/service/am/applet_ae.h"
 | 
			
		||||
#include "core/hle/service/am/applet_oe.h"
 | 
			
		||||
#include "core/hle/service/am/applets/applet_cabinet.h"
 | 
			
		||||
#include "core/hle/service/am/applets/applet_controller.h"
 | 
			
		||||
#include "core/hle/service/am/applets/applet_mii_edit_types.h"
 | 
			
		||||
#include "core/hle/service/am/applets/applet_profile_select.h"
 | 
			
		||||
#include "core/hle/service/am/applets/applet_software_keyboard_types.h"
 | 
			
		||||
@ -35,6 +37,7 @@
 | 
			
		||||
#include "core/hle/service/caps/caps_su.h"
 | 
			
		||||
#include "core/hle/service/caps/caps_types.h"
 | 
			
		||||
#include "core/hle/service/filesystem/filesystem.h"
 | 
			
		||||
#include "core/hle/service/hid/controllers/npad.h"
 | 
			
		||||
#include "core/hle/service/ipc_helpers.h"
 | 
			
		||||
#include "core/hle/service/ns/ns.h"
 | 
			
		||||
#include "core/hle/service/nvnflinger/fb_share_buffer_manager.h"
 | 
			
		||||
@ -73,7 +76,7 @@ IWindowController::IWindowController(Core::System& system_)
 | 
			
		||||
    static const FunctionInfo functions[] = {
 | 
			
		||||
        {0, nullptr, "CreateWindow"},
 | 
			
		||||
        {1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"},
 | 
			
		||||
        {2, nullptr, "GetAppletResourceUserIdOfCallerApplet"},
 | 
			
		||||
        {2, &IWindowController::GetAppletResourceUserIdOfCallerApplet, "GetAppletResourceUserIdOfCallerApplet"},
 | 
			
		||||
        {10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"},
 | 
			
		||||
        {11, nullptr, "ReleaseForegroundRights"},
 | 
			
		||||
        {12, nullptr, "RejectToChangeIntoBackground"},
 | 
			
		||||
@ -97,6 +100,16 @@ void IWindowController::GetAppletResourceUserId(HLERequestContext& ctx) {
 | 
			
		||||
    rb.Push<u64>(process_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IWindowController::GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx) {
 | 
			
		||||
    const u64 process_id = 0;
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_AM, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 4};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.Push<u64>(process_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IWindowController::AcquireForegroundRights(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_WARNING(Service_AM, "(STUBBED) called");
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
@ -1565,7 +1578,7 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)
 | 
			
		||||
        {6, nullptr, "GetPopInteractiveInDataEvent"},
 | 
			
		||||
        {10, &ILibraryAppletSelfAccessor::ExitProcessAndReturn, "ExitProcessAndReturn"},
 | 
			
		||||
        {11, &ILibraryAppletSelfAccessor::GetLibraryAppletInfo, "GetLibraryAppletInfo"},
 | 
			
		||||
        {12, nullptr, "GetMainAppletIdentityInfo"},
 | 
			
		||||
        {12, &ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo, "GetMainAppletIdentityInfo"},
 | 
			
		||||
        {13, nullptr, "CanUseApplicationCore"},
 | 
			
		||||
        {14, &ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo, "GetCallerAppletIdentityInfo"},
 | 
			
		||||
        {15, nullptr, "GetMainAppletApplicationControlProperty"},
 | 
			
		||||
@ -1609,6 +1622,9 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)
 | 
			
		||||
    case Applets::AppletId::SoftwareKeyboard:
 | 
			
		||||
        PushInShowSoftwareKeyboard();
 | 
			
		||||
        break;
 | 
			
		||||
    case Applets::AppletId::Controller:
 | 
			
		||||
        PushInShowController();
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
@ -1666,13 +1682,33 @@ void ILibraryAppletSelfAccessor::GetLibraryAppletInfo(HLERequestContext& ctx) {
 | 
			
		||||
    rb.PushRaw(applet_info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo(HLERequestContext& ctx) {
 | 
			
		||||
    struct AppletIdentityInfo {
 | 
			
		||||
        Applets::AppletId applet_id;
 | 
			
		||||
        INSERT_PADDING_BYTES(0x4);
 | 
			
		||||
        u64 application_id;
 | 
			
		||||
    };
 | 
			
		||||
    static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size.");
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_AM, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
    const AppletIdentityInfo applet_info{
 | 
			
		||||
        .applet_id = Applets::AppletId::QLaunch,
 | 
			
		||||
        .application_id = 0x0100000000001000ull,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 6};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.PushRaw(applet_info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext& ctx) {
 | 
			
		||||
    struct AppletIdentityInfo {
 | 
			
		||||
        Applets::AppletId applet_id;
 | 
			
		||||
        INSERT_PADDING_BYTES(0x4);
 | 
			
		||||
        u64 application_id;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size.");
 | 
			
		||||
    LOG_WARNING(Service_AM, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
    const AppletIdentityInfo applet_info{
 | 
			
		||||
@ -1737,6 +1773,55 @@ void ILibraryAppletSelfAccessor::PushInShowAlbum() {
 | 
			
		||||
    queue_data.emplace_back(std::move(settings_data));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ILibraryAppletSelfAccessor::PushInShowController() {
 | 
			
		||||
    const Applets::CommonArguments common_args = {
 | 
			
		||||
        .arguments_version = Applets::CommonArgumentVersion::Version3,
 | 
			
		||||
        .size = Applets::CommonArgumentSize::Version3,
 | 
			
		||||
        .library_version = static_cast<u32>(Applets::ControllerAppletVersion::Version8),
 | 
			
		||||
        .theme_color = Applets::ThemeColor::BasicBlack,
 | 
			
		||||
        .play_startup_sound = true,
 | 
			
		||||
        .system_tick = system.CoreTiming().GetClockTicks(),
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Applets::ControllerSupportArgNew user_args = {
 | 
			
		||||
        .header = {.player_count_min = 1,
 | 
			
		||||
                   .player_count_max = 4,
 | 
			
		||||
                   .enable_take_over_connection = true,
 | 
			
		||||
                   .enable_left_justify = false,
 | 
			
		||||
                   .enable_permit_joy_dual = true,
 | 
			
		||||
                   .enable_single_mode = false,
 | 
			
		||||
                   .enable_identification_color = false},
 | 
			
		||||
        .identification_colors = {},
 | 
			
		||||
        .enable_explain_text = false,
 | 
			
		||||
        .explain_text = {},
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Applets::ControllerSupportArgPrivate private_args = {
 | 
			
		||||
        .arg_private_size = sizeof(Applets::ControllerSupportArgPrivate),
 | 
			
		||||
        .arg_size = sizeof(Applets::ControllerSupportArgNew),
 | 
			
		||||
        .is_home_menu = true,
 | 
			
		||||
        .flag_1 = true,
 | 
			
		||||
        .mode = Applets::ControllerSupportMode::ShowControllerSupport,
 | 
			
		||||
        .caller = Applets::ControllerSupportCaller::
 | 
			
		||||
            Application, // switchbrew: Always zero except with
 | 
			
		||||
                         // ShowControllerFirmwareUpdateForSystem/ShowControllerKeyRemappingForSystem,
 | 
			
		||||
                         // which sets this to the input param
 | 
			
		||||
        .style_set = Core::HID::NpadStyleSet::None,
 | 
			
		||||
        .joy_hold_type = 0,
 | 
			
		||||
    };
 | 
			
		||||
    std::vector<u8> common_args_data(sizeof(common_args));
 | 
			
		||||
    std::vector<u8> private_args_data(sizeof(private_args));
 | 
			
		||||
    std::vector<u8> user_args_data(sizeof(user_args));
 | 
			
		||||
 | 
			
		||||
    std::memcpy(common_args_data.data(), &common_args, sizeof(common_args));
 | 
			
		||||
    std::memcpy(private_args_data.data(), &private_args, sizeof(private_args));
 | 
			
		||||
    std::memcpy(user_args_data.data(), &user_args, sizeof(user_args));
 | 
			
		||||
 | 
			
		||||
    queue_data.emplace_back(std::move(common_args_data));
 | 
			
		||||
    queue_data.emplace_back(std::move(private_args_data));
 | 
			
		||||
    queue_data.emplace_back(std::move(user_args_data));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ILibraryAppletSelfAccessor::PushInShowCabinetData() {
 | 
			
		||||
    const Applets::CommonArguments arguments{
 | 
			
		||||
        .arguments_version = Applets::CommonArgumentVersion::Version3,
 | 
			
		||||
 | 
			
		||||
@ -87,6 +87,7 @@ public:
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void GetAppletResourceUserId(HLERequestContext& ctx);
 | 
			
		||||
    void GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx);
 | 
			
		||||
    void AcquireForegroundRights(HLERequestContext& ctx);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -345,6 +346,7 @@ private:
 | 
			
		||||
    void PopInData(HLERequestContext& ctx);
 | 
			
		||||
    void PushOutData(HLERequestContext& ctx);
 | 
			
		||||
    void GetLibraryAppletInfo(HLERequestContext& ctx);
 | 
			
		||||
    void GetMainAppletIdentityInfo(HLERequestContext& ctx);
 | 
			
		||||
    void ExitProcessAndReturn(HLERequestContext& ctx);
 | 
			
		||||
    void GetCallerAppletIdentityInfo(HLERequestContext& ctx);
 | 
			
		||||
    void GetDesirableKeyboardLayout(HLERequestContext& ctx);
 | 
			
		||||
@ -355,6 +357,7 @@ private:
 | 
			
		||||
    void PushInShowCabinetData();
 | 
			
		||||
    void PushInShowMiiEditData();
 | 
			
		||||
    void PushInShowSoftwareKeyboard();
 | 
			
		||||
    void PushInShowController();
 | 
			
		||||
 | 
			
		||||
    std::deque<std::vector<u8>> queue_data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -56,7 +56,7 @@ enum class ControllerSupportResult : u32 {
 | 
			
		||||
struct ControllerSupportArgPrivate {
 | 
			
		||||
    u32 arg_private_size{};
 | 
			
		||||
    u32 arg_size{};
 | 
			
		||||
    bool flag_0{};
 | 
			
		||||
    bool is_home_menu{};
 | 
			
		||||
    bool flag_1{};
 | 
			
		||||
    ControllerSupportMode mode{};
 | 
			
		||||
    ControllerSupportCaller caller{};
 | 
			
		||||
 | 
			
		||||
@ -127,7 +127,7 @@ public:
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void GetCore(HLERequestContext& ctx) {
 | 
			
		||||
        LOG_DEBUG(Service_BTM, "called");
 | 
			
		||||
        LOG_WARNING(Service_BTM, "called");
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 0, 1};
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
@ -263,13 +263,13 @@ public:
 | 
			
		||||
    explicit IBtmSystemCore(Core::System& system_) : ServiceFramework{system_, "IBtmSystemCore"} {
 | 
			
		||||
        // clang-format off
 | 
			
		||||
        static const FunctionInfo functions[] = {
 | 
			
		||||
            {0, nullptr, "StartGamepadPairing"},
 | 
			
		||||
            {1, nullptr, "CancelGamepadPairing"},
 | 
			
		||||
            {0, &IBtmSystemCore::StartGamepadPairing, "StartGamepadPairing"},
 | 
			
		||||
            {1, &IBtmSystemCore::CancelGamepadPairing, "CancelGamepadPairing"},
 | 
			
		||||
            {2, nullptr, "ClearGamepadPairingDatabase"},
 | 
			
		||||
            {3, nullptr, "GetPairedGamepadCount"},
 | 
			
		||||
            {4, nullptr, "EnableRadio"},
 | 
			
		||||
            {5, nullptr, "DisableRadio"},
 | 
			
		||||
            {6, nullptr, "GetRadioOnOff"},
 | 
			
		||||
            {6, &IBtmSystemCore::IsRadioEnabled, "IsRadioEnabled"},
 | 
			
		||||
            {7, nullptr, "AcquireRadioEvent"},
 | 
			
		||||
            {8, nullptr, "AcquireGamepadPairingEvent"},
 | 
			
		||||
            {9, nullptr, "IsGamepadPairingStarted"},
 | 
			
		||||
@ -280,18 +280,58 @@ public:
 | 
			
		||||
            {14, nullptr, "AcquireAudioDeviceConnectionEvent"},
 | 
			
		||||
            {15, nullptr, "ConnectAudioDevice"},
 | 
			
		||||
            {16, nullptr, "IsConnectingAudioDevice"},
 | 
			
		||||
            {17, nullptr, "GetConnectedAudioDevices"},
 | 
			
		||||
            {17, &IBtmSystemCore::GetConnectedAudioDevices, "GetConnectedAudioDevices"},
 | 
			
		||||
            {18, nullptr, "DisconnectAudioDevice"},
 | 
			
		||||
            {19, nullptr, "AcquirePairedAudioDeviceInfoChangedEvent"},
 | 
			
		||||
            {20, nullptr, "GetPairedAudioDevices"},
 | 
			
		||||
            {21, nullptr, "RemoveAudioDevicePairing"},
 | 
			
		||||
            {22, nullptr, "RequestAudioDeviceConnectionRejection"},
 | 
			
		||||
            {23, nullptr, "CancelAudioDeviceConnectionRejection"}
 | 
			
		||||
            {22, &IBtmSystemCore::RequestAudioDeviceConnectionRejection, "RequestAudioDeviceConnectionRejection"},
 | 
			
		||||
            {23, &IBtmSystemCore::CancelAudioDeviceConnectionRejection, "CancelAudioDeviceConnectionRejection"}
 | 
			
		||||
        };
 | 
			
		||||
        // clang-format on
 | 
			
		||||
 | 
			
		||||
        RegisterHandlers(functions);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void IsRadioEnabled(HLERequestContext& ctx) {
 | 
			
		||||
        LOG_DEBUG(Service_BTM, "(STUBBED) called"); // Spams a lot when controller applet is running
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 3};
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
        rb.Push(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void StartGamepadPairing(HLERequestContext& ctx) {
 | 
			
		||||
        LOG_WARNING(Service_BTM, "(STUBBED) called");
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void CancelGamepadPairing(HLERequestContext& ctx) {
 | 
			
		||||
        LOG_WARNING(Service_BTM, "(STUBBED) called");
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void CancelAudioDeviceConnectionRejection(HLERequestContext& ctx) {
 | 
			
		||||
        LOG_WARNING(Service_BTM, "(STUBBED) called");
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void GetConnectedAudioDevices(HLERequestContext& ctx) {
 | 
			
		||||
        LOG_WARNING(Service_BTM, "(STUBBED) called");
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 3};
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
        rb.Push<u32>(0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void RequestAudioDeviceConnectionRejection(HLERequestContext& ctx) {
 | 
			
		||||
        LOG_WARNING(Service_BTM, "(STUBBED) called");
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class BTM_SYS final : public ServiceFramework<BTM_SYS> {
 | 
			
		||||
@ -308,7 +348,7 @@ public:
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void GetCore(HLERequestContext& ctx) {
 | 
			
		||||
        LOG_DEBUG(Service_BTM, "called");
 | 
			
		||||
        LOG_WARNING(Service_BTM, "called");
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 0, 1};
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
 | 
			
		||||
@ -344,6 +344,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
 | 
			
		||||
        controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::AllDevices,
 | 
			
		||||
                                          Common::Input::PollingMode::Active);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SignalStyleSetChangedEvent(npad_id);
 | 
			
		||||
    WriteEmptyEntry(controller.shared_memory);
 | 
			
		||||
    hid_core.SetLastActiveController(npad_id);
 | 
			
		||||
@ -1726,4 +1727,19 @@ const Controller_NPad::SixaxisParameters& Controller_NPad::GetSixaxisState(
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Controller_NPad::AppletDetailedUiType Controller_NPad::GetAppletDetailedUiType(
 | 
			
		||||
    Core::HID::NpadIdType npad_id) {
 | 
			
		||||
 | 
			
		||||
    auto controller = GetControllerFromNpadIdType(npad_id);
 | 
			
		||||
    auto shared_memory = controller.shared_memory;
 | 
			
		||||
    Service::HID::Controller_NPad::AppletFooterUiType applet_footer_type =
 | 
			
		||||
        shared_memory->applet_footer_type;
 | 
			
		||||
 | 
			
		||||
    Controller_NPad::AppletDetailedUiType detailed_ui_type{
 | 
			
		||||
        .ui_variant = 0,
 | 
			
		||||
        .footer = applet_footer_type,
 | 
			
		||||
    };
 | 
			
		||||
    return detailed_ui_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Service::HID
 | 
			
		||||
 | 
			
		||||
@ -78,6 +78,46 @@ public:
 | 
			
		||||
        MaxActivationMode = 3,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // This is nn::hid::system::AppletFooterUiAttributesSet
 | 
			
		||||
    struct AppletFooterUiAttributes {
 | 
			
		||||
        INSERT_PADDING_BYTES(0x4);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // This is nn::hid::system::AppletFooterUiType
 | 
			
		||||
    enum class AppletFooterUiType : u8 {
 | 
			
		||||
        None = 0,
 | 
			
		||||
        HandheldNone = 1,
 | 
			
		||||
        HandheldJoyConLeftOnly = 2,
 | 
			
		||||
        HandheldJoyConRightOnly = 3,
 | 
			
		||||
        HandheldJoyConLeftJoyConRight = 4,
 | 
			
		||||
        JoyDual = 5,
 | 
			
		||||
        JoyDualLeftOnly = 6,
 | 
			
		||||
        JoyDualRightOnly = 7,
 | 
			
		||||
        JoyLeftHorizontal = 8,
 | 
			
		||||
        JoyLeftVertical = 9,
 | 
			
		||||
        JoyRightHorizontal = 10,
 | 
			
		||||
        JoyRightVertical = 11,
 | 
			
		||||
        SwitchProController = 12,
 | 
			
		||||
        CompatibleProController = 13,
 | 
			
		||||
        CompatibleJoyCon = 14,
 | 
			
		||||
        LarkHvc1 = 15,
 | 
			
		||||
        LarkHvc2 = 16,
 | 
			
		||||
        LarkNesLeft = 17,
 | 
			
		||||
        LarkNesRight = 18,
 | 
			
		||||
        Lucia = 19,
 | 
			
		||||
        Verification = 20,
 | 
			
		||||
        Lagon = 21,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    using AppletFooterUiVariant = u8;
 | 
			
		||||
 | 
			
		||||
    // This is "nn::hid::system::AppletDetailedUiType".
 | 
			
		||||
    struct AppletDetailedUiType {
 | 
			
		||||
        AppletFooterUiVariant ui_variant;
 | 
			
		||||
        INSERT_PADDING_BYTES(0x2);
 | 
			
		||||
        AppletFooterUiType footer;
 | 
			
		||||
    };
 | 
			
		||||
    static_assert(sizeof(AppletDetailedUiType) == 0x4, "AppletDetailedUiType is an invalid size");
 | 
			
		||||
    // This is nn::hid::NpadCommunicationMode
 | 
			
		||||
    enum class NpadCommunicationMode : u64 {
 | 
			
		||||
        Mode_5ms = 0,
 | 
			
		||||
@ -203,6 +243,7 @@ public:
 | 
			
		||||
    static Result IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle);
 | 
			
		||||
    static Result VerifyValidSixAxisSensorHandle(
 | 
			
		||||
        const Core::HID::SixAxisSensorHandle& device_handle);
 | 
			
		||||
    AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    static constexpr std::size_t NPAD_COUNT = 10;
 | 
			
		||||
@ -360,37 +401,6 @@ private:
 | 
			
		||||
    static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18,
 | 
			
		||||
                  "NfcXcdDeviceHandleStateImpl is an invalid size");
 | 
			
		||||
 | 
			
		||||
    // This is nn::hid::system::AppletFooterUiAttributesSet
 | 
			
		||||
    struct AppletFooterUiAttributes {
 | 
			
		||||
        INSERT_PADDING_BYTES(0x4);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // This is nn::hid::system::AppletFooterUiType
 | 
			
		||||
    enum class AppletFooterUiType : u8 {
 | 
			
		||||
        None = 0,
 | 
			
		||||
        HandheldNone = 1,
 | 
			
		||||
        HandheldJoyConLeftOnly = 2,
 | 
			
		||||
        HandheldJoyConRightOnly = 3,
 | 
			
		||||
        HandheldJoyConLeftJoyConRight = 4,
 | 
			
		||||
        JoyDual = 5,
 | 
			
		||||
        JoyDualLeftOnly = 6,
 | 
			
		||||
        JoyDualRightOnly = 7,
 | 
			
		||||
        JoyLeftHorizontal = 8,
 | 
			
		||||
        JoyLeftVertical = 9,
 | 
			
		||||
        JoyRightHorizontal = 10,
 | 
			
		||||
        JoyRightVertical = 11,
 | 
			
		||||
        SwitchProController = 12,
 | 
			
		||||
        CompatibleProController = 13,
 | 
			
		||||
        CompatibleJoyCon = 14,
 | 
			
		||||
        LarkHvc1 = 15,
 | 
			
		||||
        LarkHvc2 = 16,
 | 
			
		||||
        LarkNesLeft = 17,
 | 
			
		||||
        LarkNesRight = 18,
 | 
			
		||||
        Lucia = 19,
 | 
			
		||||
        Verification = 20,
 | 
			
		||||
        Lagon = 21,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // This is nn::hid::NpadLarkType
 | 
			
		||||
    enum class NpadLarkType : u32 {
 | 
			
		||||
        Invalid,
 | 
			
		||||
 | 
			
		||||
@ -1222,8 +1222,8 @@ void IHidServer::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) {
 | 
			
		||||
    controller.SetNpadMode(new_npad_id, parameters.npad_id, {},
 | 
			
		||||
                           Controller_NPad::NpadJoyAssignmentMode::Dual);
 | 
			
		||||
 | 
			
		||||
    LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
 | 
			
		||||
             parameters.applet_resource_user_id);
 | 
			
		||||
    LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
 | 
			
		||||
              parameters.applet_resource_user_id); // Spams a lot when controller applet is open
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
 | 
			
		||||
@ -36,24 +36,24 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
 | 
			
		||||
            {233, nullptr, "GetXcdHandleForNpadWithIrSensor"},
 | 
			
		||||
            {301, nullptr, "ActivateNpadSystem"},
 | 
			
		||||
            {303, &IHidSystemServer::ApplyNpadSystemCommonPolicy, "ApplyNpadSystemCommonPolicy"},
 | 
			
		||||
            {304, nullptr, "EnableAssigningSingleOnSlSrPress"},
 | 
			
		||||
            {305, nullptr, "DisableAssigningSingleOnSlSrPress"},
 | 
			
		||||
            {304, &IHidSystemServer::EnableAssigningSingleOnSlSrPress, "EnableAssigningSingleOnSlSrPress"},
 | 
			
		||||
            {305, &IHidSystemServer::DisableAssigningSingleOnSlSrPress, "DisableAssigningSingleOnSlSrPress"},
 | 
			
		||||
            {306, &IHidSystemServer::GetLastActiveNpad, "GetLastActiveNpad"},
 | 
			
		||||
            {307, nullptr, "GetNpadSystemExtStyle"},
 | 
			
		||||
            {308, nullptr, "ApplyNpadSystemCommonPolicyFull"},
 | 
			
		||||
            {309, nullptr, "GetNpadFullKeyGripColor"},
 | 
			
		||||
            {310, nullptr, "GetMaskedSupportedNpadStyleSet"},
 | 
			
		||||
            {308, &IHidSystemServer::ApplyNpadSystemCommonPolicyFull, "ApplyNpadSystemCommonPolicyFull"},
 | 
			
		||||
            {309, &IHidSystemServer::GetNpadFullKeyGripColor, "GetNpadFullKeyGripColor"},
 | 
			
		||||
            {310, &IHidSystemServer::GetMaskedSupportedNpadStyleSet, "GetMaskedSupportedNpadStyleSet"},
 | 
			
		||||
            {311, nullptr, "SetNpadPlayerLedBlinkingDevice"},
 | 
			
		||||
            {312, nullptr, "SetSupportedNpadStyleSetAll"},
 | 
			
		||||
            {312, &IHidSystemServer::SetSupportedNpadStyleSetAll, "SetSupportedNpadStyleSetAll"},
 | 
			
		||||
            {313, nullptr, "GetNpadCaptureButtonAssignment"},
 | 
			
		||||
            {314, nullptr, "GetAppletFooterUiType"},
 | 
			
		||||
            {315, nullptr, "GetAppletDetailedUiType"},
 | 
			
		||||
            {316, nullptr, "GetNpadInterfaceType"},
 | 
			
		||||
            {317, nullptr, "GetNpadLeftRightInterfaceType"},
 | 
			
		||||
            {318, nullptr, "HasBattery"},
 | 
			
		||||
            {319, nullptr, "HasLeftRightBattery"},
 | 
			
		||||
            {315, &IHidSystemServer::GetAppletDetailedUiType, "GetAppletDetailedUiType"},
 | 
			
		||||
            {316, &IHidSystemServer::GetNpadInterfaceType, "GetNpadInterfaceType"},
 | 
			
		||||
            {317, &IHidSystemServer::GetNpadLeftRightInterfaceType, "GetNpadLeftRightInterfaceType"},
 | 
			
		||||
            {318, &IHidSystemServer::HasBattery, "HasBattery"},
 | 
			
		||||
            {319, &IHidSystemServer::HasLeftRightBattery, "HasLeftRightBattery"},
 | 
			
		||||
            {321, &IHidSystemServer::GetUniquePadsFromNpad, "GetUniquePadsFromNpad"},
 | 
			
		||||
            {322, nullptr, "GetIrSensorState"},
 | 
			
		||||
            {322, &IHidSystemServer::GetIrSensorState, "GetIrSensorState"},
 | 
			
		||||
            {323, nullptr, "GetXcdHandleForNpadWithIrSensor"},
 | 
			
		||||
            {324, nullptr, "GetUniquePadButtonSet"},
 | 
			
		||||
            {325, nullptr, "GetUniquePadColor"},
 | 
			
		||||
@ -85,15 +85,15 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
 | 
			
		||||
            {541, nullptr, "GetPlayReportControllerUsages"},
 | 
			
		||||
            {542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"},
 | 
			
		||||
            {543, nullptr, "GetRegisteredDevicesOld"},
 | 
			
		||||
            {544, nullptr, "AcquireConnectionTriggerTimeoutEvent"},
 | 
			
		||||
            {544, &IHidSystemServer::AcquireConnectionTriggerTimeoutEvent, "AcquireConnectionTriggerTimeoutEvent"},
 | 
			
		||||
            {545, nullptr, "SendConnectionTrigger"},
 | 
			
		||||
            {546, nullptr, "AcquireDeviceRegisteredEventForControllerSupport"},
 | 
			
		||||
            {546, &IHidSystemServer::AcquireDeviceRegisteredEventForControllerSupport, "AcquireDeviceRegisteredEventForControllerSupport"},
 | 
			
		||||
            {547, nullptr, "GetAllowedBluetoothLinksCount"},
 | 
			
		||||
            {548, nullptr, "GetRegisteredDevices"},
 | 
			
		||||
            {548, &IHidSystemServer::GetRegisteredDevices, "GetRegisteredDevices"},
 | 
			
		||||
            {549, nullptr, "GetConnectableRegisteredDevices"},
 | 
			
		||||
            {700, nullptr, "ActivateUniquePad"},
 | 
			
		||||
            {702, nullptr, "AcquireUniquePadConnectionEventHandle"},
 | 
			
		||||
            {703, nullptr, "GetUniquePadIds"},
 | 
			
		||||
            {702, &IHidSystemServer::AcquireUniquePadConnectionEventHandle, "AcquireUniquePadConnectionEventHandle"},
 | 
			
		||||
            {703, &IHidSystemServer::GetUniquePadIds, "GetUniquePadIds"},
 | 
			
		||||
            {751, &IHidSystemServer::AcquireJoyDetachOnBluetoothOffEventHandle, "AcquireJoyDetachOnBluetoothOffEventHandle"},
 | 
			
		||||
            {800, nullptr, "ListSixAxisSensorHandles"},
 | 
			
		||||
            {801, nullptr, "IsSixAxisSensorUserCalibrationSupported"},
 | 
			
		||||
@ -123,10 +123,10 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
 | 
			
		||||
            {850, &IHidSystemServer::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"},
 | 
			
		||||
            {851, nullptr, "EnableUsbFullKeyController"},
 | 
			
		||||
            {852, nullptr, "IsUsbConnected"},
 | 
			
		||||
            {870, nullptr, "IsHandheldButtonPressedOnConsoleMode"},
 | 
			
		||||
            {870, &IHidSystemServer::IsHandheldButtonPressedOnConsoleMode, "IsHandheldButtonPressedOnConsoleMode"},
 | 
			
		||||
            {900, nullptr, "ActivateInputDetector"},
 | 
			
		||||
            {901, nullptr, "NotifyInputDetector"},
 | 
			
		||||
            {1000, nullptr, "InitializeFirmwareUpdate"},
 | 
			
		||||
            {1000, &IHidSystemServer::InitializeFirmwareUpdate, "InitializeFirmwareUpdate"},
 | 
			
		||||
            {1001, nullptr, "GetFirmwareVersion"},
 | 
			
		||||
            {1002, nullptr, "GetAvailableFirmwareVersion"},
 | 
			
		||||
            {1003, nullptr, "IsFirmwareUpdateAvailable"},
 | 
			
		||||
@ -149,6 +149,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
 | 
			
		||||
            {1132, nullptr, "CheckUsbFirmwareUpdateRequired"},
 | 
			
		||||
            {1133, nullptr, "StartUsbFirmwareUpdate"},
 | 
			
		||||
            {1134, nullptr, "GetUsbFirmwareUpdateState"},
 | 
			
		||||
            {1135, &IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory, "InitializeUsbFirmwareUpdateWithoutMemory"},
 | 
			
		||||
            {1150, nullptr, "SetTouchScreenMagnification"},
 | 
			
		||||
            {1151, nullptr, "GetTouchScreenFirmwareVersion"},
 | 
			
		||||
            {1152, nullptr, "SetTouchScreenDefaultConfiguration"},
 | 
			
		||||
@ -220,11 +221,20 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
 | 
			
		||||
 | 
			
		||||
    RegisterHandlers(functions);
 | 
			
		||||
 | 
			
		||||
    joy_detach_event = service_context.CreateEvent("HidSys::JoyDetachEvent");
 | 
			
		||||
    joy_detach_event = service_context.CreateEvent("IHidSystemServer::JoyDetachEvent");
 | 
			
		||||
    acquire_device_registered_event =
 | 
			
		||||
        service_context.CreateEvent("IHidSystemServer::AcquireDeviceRegisteredEvent");
 | 
			
		||||
    acquire_connection_trigger_timeout_event =
 | 
			
		||||
        service_context.CreateEvent("IHidSystemServer::AcquireConnectionTriggerTimeoutEvent");
 | 
			
		||||
    unique_pad_connection_event =
 | 
			
		||||
        service_context.CreateEvent("IHidSystemServer::AcquireUniquePadConnectionEventHandle");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
IHidSystemServer::~IHidSystemServer() {
 | 
			
		||||
    service_context.CloseEvent(joy_detach_event);
 | 
			
		||||
    service_context.CloseEvent(acquire_device_registered_event);
 | 
			
		||||
    service_context.CloseEvent(acquire_connection_trigger_timeout_event);
 | 
			
		||||
    service_context.CloseEvent(unique_pad_connection_event);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) {
 | 
			
		||||
@ -238,29 +248,241 @@ void IHidSystemServer::ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) {
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::EnableAssigningSingleOnSlSrPress(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_WARNING(Service_HID, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::DisableAssigningSingleOnSlSrPress(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_WARNING(Service_HID, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::GetLastActiveNpad(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_DEBUG(Service_HID, "(STUBBED) called");
 | 
			
		||||
    LOG_DEBUG(Service_HID, "(STUBBED) called"); // Spams a lot when controller applet is running
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 3};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.PushEnum(system.HIDCore().GetLastActiveController());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_WARNING(Service_HID, "called");
 | 
			
		||||
 | 
			
		||||
    GetResourceManager()
 | 
			
		||||
        ->GetController<Controller_NPad>(HidController::NPad)
 | 
			
		||||
        .ApplyNpadSystemCommonPolicy();
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::GetNpadFullKeyGripColor(HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp{ctx};
 | 
			
		||||
    const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
 | 
			
		||||
              npad_id_type); // Spams a lot when controller applet is running
 | 
			
		||||
 | 
			
		||||
    Core::HID::NpadColor left_color{};
 | 
			
		||||
    Core::HID::NpadColor right_color{};
 | 
			
		||||
    // TODO: Get colors from Npad
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 4};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.PushRaw(left_color);
 | 
			
		||||
    rb.PushRaw(right_color);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp{ctx};
 | 
			
		||||
 | 
			
		||||
    LOG_INFO(Service_HID, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
    Core::HID::NpadStyleSet supported_styleset =
 | 
			
		||||
        GetResourceManager()
 | 
			
		||||
            ->GetController<Controller_NPad>(HidController::NPad)
 | 
			
		||||
            .GetSupportedStyleSet()
 | 
			
		||||
            .raw;
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 3};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.PushEnum(supported_styleset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::SetSupportedNpadStyleSetAll(HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp{ctx};
 | 
			
		||||
 | 
			
		||||
    LOG_INFO(Service_HID, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
    Core::HID::NpadStyleSet supported_styleset =
 | 
			
		||||
        GetResourceManager()
 | 
			
		||||
            ->GetController<Controller_NPad>(HidController::NPad)
 | 
			
		||||
            .GetSupportedStyleSet()
 | 
			
		||||
            .raw;
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 3};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.PushEnum(supported_styleset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::GetAppletDetailedUiType(HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp{ctx};
 | 
			
		||||
    const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_HID, "called, npad_id_type={}",
 | 
			
		||||
              npad_id_type); // Spams a lot when controller applet is running
 | 
			
		||||
 | 
			
		||||
    const Service::HID::Controller_NPad::AppletDetailedUiType detailed_ui_type =
 | 
			
		||||
        GetResourceManager()
 | 
			
		||||
            ->GetController<Controller_NPad>(HidController::NPad)
 | 
			
		||||
            .GetAppletDetailedUiType(npad_id_type);
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 3};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.PushRaw(detailed_ui_type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::GetNpadInterfaceType(HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp{ctx};
 | 
			
		||||
    const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
 | 
			
		||||
              npad_id_type); // Spams a lot when controller applet is running
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 3};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.PushEnum(Core::HID::NpadInterfaceType::Bluetooth);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::GetNpadLeftRightInterfaceType(HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp{ctx};
 | 
			
		||||
    const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
 | 
			
		||||
              npad_id_type); // Spams a lot when controller applet is running
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 4};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.PushEnum(Core::HID::NpadInterfaceType::Bluetooth);
 | 
			
		||||
    rb.PushEnum(Core::HID::NpadInterfaceType::Bluetooth);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::HasBattery(HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp{ctx};
 | 
			
		||||
    const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
 | 
			
		||||
              npad_id_type); // Spams a lot when controller applet is running
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 3};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.Push(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::HasLeftRightBattery(HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp{ctx};
 | 
			
		||||
    const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
 | 
			
		||||
              npad_id_type); // Spams a lot when controller applet is running
 | 
			
		||||
 | 
			
		||||
    struct LeftRightBattery {
 | 
			
		||||
        bool left;
 | 
			
		||||
        bool right;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    LeftRightBattery left_right_battery{
 | 
			
		||||
        .left = false,
 | 
			
		||||
        .right = false,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 3};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.PushRaw(left_right_battery);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::GetUniquePadsFromNpad(HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp{ctx};
 | 
			
		||||
    const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_HID, "(STUBBED) called, npad_id_type={}", npad_id_type);
 | 
			
		||||
    LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
 | 
			
		||||
              npad_id_type); // Spams a lot when controller applet is running
 | 
			
		||||
 | 
			
		||||
    const std::vector<Core::HID::UniquePadId> unique_pads{};
 | 
			
		||||
 | 
			
		||||
    ctx.WriteBuffer(unique_pads);
 | 
			
		||||
    if (!unique_pads.empty()) {
 | 
			
		||||
        ctx.WriteBuffer(unique_pads);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 3};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.Push(static_cast<u32>(unique_pads.size()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::GetIrSensorState(HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp{ctx};
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_HID, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_INFO(Service_AM, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.PushCopyObjects(acquire_device_registered_event->GetReadableEvent());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_INFO(Service_HID, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.PushCopyObjects(acquire_device_registered_event->GetReadableEvent());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::GetRegisteredDevices(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_WARNING(Service_HID, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
    struct RegisterData {
 | 
			
		||||
        std::array<u8, 0x68> data;
 | 
			
		||||
    };
 | 
			
		||||
    static_assert(sizeof(RegisterData) == 0x68, "RegisterData is an invalid size");
 | 
			
		||||
    std::vector<RegisterData> registered_devices{};
 | 
			
		||||
 | 
			
		||||
    if (!registered_devices.empty()) {
 | 
			
		||||
        ctx.WriteBuffer(registered_devices);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 4};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.Push<u64>(registered_devices.size());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::AcquireUniquePadConnectionEventHandle(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_WARNING(Service_HID, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
    rb.PushCopyObjects(unique_pad_connection_event->GetReadableEvent());
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::GetUniquePadIds(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_WARNING(Service_HID, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 4};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.Push<u64>(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::AcquireJoyDetachOnBluetoothOffEventHandle(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_INFO(Service_AM, "called");
 | 
			
		||||
 | 
			
		||||
@ -279,6 +501,31 @@ void IHidSystemServer::IsUsbFullKeyControllerEnabled(HLERequestContext& ctx) {
 | 
			
		||||
    rb.Push(is_enabled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::IsHandheldButtonPressedOnConsoleMode(HLERequestContext& ctx) {
 | 
			
		||||
    const bool button_pressed = false;
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_HID, "(STUBBED) called, is_enabled={}",
 | 
			
		||||
              button_pressed); // Spams a lot when controller applet is open
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 3};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.Push(button_pressed);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::InitializeFirmwareUpdate(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_WARNING(Service_HID, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_WARNING(Service_HID, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IHidSystemServer::GetTouchScreenDefaultConfiguration(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_WARNING(Service_HID, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -24,15 +24,38 @@ public:
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void ApplyNpadSystemCommonPolicy(HLERequestContext& ctx);
 | 
			
		||||
    void EnableAssigningSingleOnSlSrPress(HLERequestContext& ctx);
 | 
			
		||||
    void DisableAssigningSingleOnSlSrPress(HLERequestContext& ctx);
 | 
			
		||||
    void GetLastActiveNpad(HLERequestContext& ctx);
 | 
			
		||||
    void ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx);
 | 
			
		||||
    void GetNpadFullKeyGripColor(HLERequestContext& ctx);
 | 
			
		||||
    void GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx);
 | 
			
		||||
    void SetSupportedNpadStyleSetAll(HLERequestContext& ctx);
 | 
			
		||||
    void GetAppletDetailedUiType(HLERequestContext& ctx);
 | 
			
		||||
    void GetNpadInterfaceType(HLERequestContext& ctx);
 | 
			
		||||
    void GetNpadLeftRightInterfaceType(HLERequestContext& ctx);
 | 
			
		||||
    void HasBattery(HLERequestContext& ctx);
 | 
			
		||||
    void HasLeftRightBattery(HLERequestContext& ctx);
 | 
			
		||||
    void GetUniquePadsFromNpad(HLERequestContext& ctx);
 | 
			
		||||
    void GetIrSensorState(HLERequestContext& ctx);
 | 
			
		||||
    void AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx);
 | 
			
		||||
    void AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx);
 | 
			
		||||
    void GetRegisteredDevices(HLERequestContext& ctx);
 | 
			
		||||
    void AcquireUniquePadConnectionEventHandle(HLERequestContext& ctx);
 | 
			
		||||
    void GetUniquePadIds(HLERequestContext& ctx);
 | 
			
		||||
    void AcquireJoyDetachOnBluetoothOffEventHandle(HLERequestContext& ctx);
 | 
			
		||||
    void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx);
 | 
			
		||||
    void IsHandheldButtonPressedOnConsoleMode(HLERequestContext& ctx);
 | 
			
		||||
    void InitializeFirmwareUpdate(HLERequestContext& ctx);
 | 
			
		||||
    void InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx);
 | 
			
		||||
    void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx);
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr<ResourceManager> GetResourceManager();
 | 
			
		||||
 | 
			
		||||
    Kernel::KEvent* acquire_connection_trigger_timeout_event;
 | 
			
		||||
    Kernel::KEvent* acquire_device_registered_event;
 | 
			
		||||
    Kernel::KEvent* joy_detach_event;
 | 
			
		||||
    Kernel::KEvent* unique_pad_connection_event;
 | 
			
		||||
    KernelHelpers::ServiceContext service_context;
 | 
			
		||||
    std::shared_ptr<ResourceManager> resource_manager;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -115,12 +115,20 @@ public:
 | 
			
		||||
            {400, nullptr, "InitializeSystem"},
 | 
			
		||||
            {401, nullptr, "FinalizeSystem"},
 | 
			
		||||
            {402, nullptr, "SetOperationMode"},
 | 
			
		||||
            {403, nullptr, "InitializeSystem2"},
 | 
			
		||||
            {403, &ISystemLocalCommunicationService::InitializeSystem2, "InitializeSystem2"},
 | 
			
		||||
        };
 | 
			
		||||
        // clang-format on
 | 
			
		||||
 | 
			
		||||
        RegisterHandlers(functions);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void InitializeSystem2(HLERequestContext& ctx) {
 | 
			
		||||
        LOG_WARNING(Service_LDN, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class IUserLocalCommunicationService final
 | 
			
		||||
 | 
			
		||||
@ -431,8 +431,7 @@ void SET_SYS::GetAutoUpdateEnableFlag(HLERequestContext& ctx) {
 | 
			
		||||
void SET_SYS::GetBatteryPercentageFlag(HLERequestContext& ctx) {
 | 
			
		||||
    u8 battery_percentage_flag{1};
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_SET, "(STUBBED) called, battery_percentage_flag={}",
 | 
			
		||||
                battery_percentage_flag);
 | 
			
		||||
    LOG_DEBUG(Service_SET, "(STUBBED) called, battery_percentage_flag={}", battery_percentage_flag);
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 3};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
@ -492,6 +491,29 @@ void SET_SYS::GetChineseTraditionalInputMethod(HLERequestContext& ctx) {
 | 
			
		||||
    rb.PushEnum(ChineseTraditionalInputMethod::Unknown0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SET_SYS::GetHomeMenuScheme(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_DEBUG(Service_SET, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
    const HomeMenuScheme default_color = {
 | 
			
		||||
        .main = 0xFF323232,
 | 
			
		||||
        .back = 0xFF323232,
 | 
			
		||||
        .sub = 0xFFFFFFFF,
 | 
			
		||||
        .bezel = 0xFFFFFFFF,
 | 
			
		||||
        .extra = 0xFF000000,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 7};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.PushRaw(default_color);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SET_SYS::GetHomeMenuSchemeModel(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_WARNING(Service_SET, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 3};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
    rb.Push(0);
 | 
			
		||||
}
 | 
			
		||||
void SET_SYS::GetFieldTestingFlag(HLERequestContext& ctx) {
 | 
			
		||||
    LOG_WARNING(Service_SET, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
@ -674,7 +696,7 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
 | 
			
		||||
        {171, nullptr, "SetChineseTraditionalInputMethod"},
 | 
			
		||||
        {172, nullptr, "GetPtmCycleCountReliability"},
 | 
			
		||||
        {173, nullptr, "SetPtmCycleCountReliability"},
 | 
			
		||||
        {174, nullptr, "GetHomeMenuScheme"},
 | 
			
		||||
        {174, &SET_SYS::GetHomeMenuScheme, "GetHomeMenuScheme"},
 | 
			
		||||
        {175, nullptr, "GetThemeSettings"},
 | 
			
		||||
        {176, nullptr, "SetThemeSettings"},
 | 
			
		||||
        {177, nullptr, "GetThemeKey"},
 | 
			
		||||
@ -685,7 +707,7 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
 | 
			
		||||
        {182, nullptr, "SetT"},
 | 
			
		||||
        {183, nullptr, "GetPlatformRegion"},
 | 
			
		||||
        {184, nullptr, "SetPlatformRegion"},
 | 
			
		||||
        {185, nullptr, "GetHomeMenuSchemeModel"},
 | 
			
		||||
        {185, &SET_SYS::GetHomeMenuSchemeModel, "GetHomeMenuSchemeModel"},
 | 
			
		||||
        {186, nullptr, "GetMemoryUsageRateFlag"},
 | 
			
		||||
        {187, nullptr, "GetTouchScreenMode"},
 | 
			
		||||
        {188, nullptr, "SetTouchScreenMode"},
 | 
			
		||||
 | 
			
		||||
@ -269,6 +269,16 @@ private:
 | 
			
		||||
    };
 | 
			
		||||
    static_assert(sizeof(EulaVersion) == 0x30, "EulaVersion is incorrect size");
 | 
			
		||||
 | 
			
		||||
    /// This is nn::settings::system::HomeMenuScheme
 | 
			
		||||
    struct HomeMenuScheme {
 | 
			
		||||
        u32 main;
 | 
			
		||||
        u32 back;
 | 
			
		||||
        u32 sub;
 | 
			
		||||
        u32 bezel;
 | 
			
		||||
        u32 extra;
 | 
			
		||||
    };
 | 
			
		||||
    static_assert(sizeof(HomeMenuScheme) == 0x14, "HomeMenuScheme is incorrect size");
 | 
			
		||||
 | 
			
		||||
    void SetLanguageCode(HLERequestContext& ctx);
 | 
			
		||||
    void GetFirmwareVersion(HLERequestContext& ctx);
 | 
			
		||||
    void GetFirmwareVersion2(HLERequestContext& ctx);
 | 
			
		||||
@ -305,6 +315,8 @@ private:
 | 
			
		||||
    void GetKeyboardLayout(HLERequestContext& ctx);
 | 
			
		||||
    void GetChineseTraditionalInputMethod(HLERequestContext& ctx);
 | 
			
		||||
    void GetFieldTestingFlag(HLERequestContext& ctx);
 | 
			
		||||
    void GetHomeMenuScheme(HLERequestContext& ctx);
 | 
			
		||||
    void GetHomeMenuSchemeModel(HLERequestContext& ctx);
 | 
			
		||||
 | 
			
		||||
    AccountSettings account_settings{
 | 
			
		||||
        .flags = {},
 | 
			
		||||
 | 
			
		||||
@ -1575,6 +1575,7 @@ void GMainWindow::ConnectMenuEvents() {
 | 
			
		||||
    connect_menu(ui->action_Load_Cabinet_Formatter,
 | 
			
		||||
                 [this]() { OnCabinet(Service::NFP::CabinetMode::StartFormatter); });
 | 
			
		||||
    connect_menu(ui->action_Load_Mii_Edit, &GMainWindow::OnMiiEdit);
 | 
			
		||||
    connect_menu(ui->action_Open_Controller_Menu, &GMainWindow::OnOpenControllerMenu);
 | 
			
		||||
    connect_menu(ui->action_Capture_Screenshot, &GMainWindow::OnCaptureScreenshot);
 | 
			
		||||
 | 
			
		||||
    // TAS
 | 
			
		||||
@ -1602,14 +1603,13 @@ void GMainWindow::UpdateMenuState() {
 | 
			
		||||
        ui->action_Pause,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const std::array applet_actions{
 | 
			
		||||
        ui->action_Load_Album,
 | 
			
		||||
        ui->action_Load_Cabinet_Nickname_Owner,
 | 
			
		||||
        ui->action_Load_Cabinet_Eraser,
 | 
			
		||||
        ui->action_Load_Cabinet_Restorer,
 | 
			
		||||
        ui->action_Load_Cabinet_Formatter,
 | 
			
		||||
        ui->action_Load_Mii_Edit,
 | 
			
		||||
    };
 | 
			
		||||
    const std::array applet_actions{ui->action_Load_Album,
 | 
			
		||||
                                    ui->action_Load_Cabinet_Nickname_Owner,
 | 
			
		||||
                                    ui->action_Load_Cabinet_Eraser,
 | 
			
		||||
                                    ui->action_Load_Cabinet_Restorer,
 | 
			
		||||
                                    ui->action_Load_Cabinet_Formatter,
 | 
			
		||||
                                    ui->action_Load_Mii_Edit,
 | 
			
		||||
                                    ui->action_Open_Controller_Menu};
 | 
			
		||||
 | 
			
		||||
    for (QAction* action : running_actions) {
 | 
			
		||||
        action->setEnabled(emulation_running);
 | 
			
		||||
@ -4375,6 +4375,31 @@ void GMainWindow::OnMiiEdit() {
 | 
			
		||||
    BootGame(filename, MiiEditId);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GMainWindow::OnOpenControllerMenu() {
 | 
			
		||||
    constexpr u64 ControllerAppletId =
 | 
			
		||||
        static_cast<u64>(Service::AM::Applets::AppletProgramId::Controller);
 | 
			
		||||
    auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
 | 
			
		||||
    if (!bis_system) {
 | 
			
		||||
        QMessageBox::warning(this, tr("No firmware available"),
 | 
			
		||||
                             tr("Please install the firmware to use the Controller Menu."));
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto controller_applet_nca =
 | 
			
		||||
        bis_system->GetEntry(ControllerAppletId, FileSys::ContentRecordType::Program);
 | 
			
		||||
    if (!controller_applet_nca) {
 | 
			
		||||
        QMessageBox::warning(this, tr("Controller Applet"),
 | 
			
		||||
                             tr("Controller Menu is not available. Please reinstall firmware."));
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    system->GetAppletManager().SetCurrentAppletId(Service::AM::Applets::AppletId::Controller);
 | 
			
		||||
 | 
			
		||||
    const auto filename = QString::fromStdString((controller_applet_nca->GetFullPath()));
 | 
			
		||||
    UISettings::values.roms_path = QFileInfo(filename).path();
 | 
			
		||||
    BootGame(filename, ControllerAppletId);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GMainWindow::OnCaptureScreenshot() {
 | 
			
		||||
    if (emu_thread == nullptr || !emu_thread->IsRunning()) {
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
@ -410,6 +410,7 @@ private slots:
 | 
			
		||||
    void OnAlbum();
 | 
			
		||||
    void OnCabinet(Service::NFP::CabinetMode mode);
 | 
			
		||||
    void OnMiiEdit();
 | 
			
		||||
    void OnOpenControllerMenu();
 | 
			
		||||
    void OnCaptureScreenshot();
 | 
			
		||||
    void OnReinitializeKeys(ReinitializeKeyBehavior behavior);
 | 
			
		||||
    void OnLanguageChanged(const QString& locale);
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,7 @@
 | 
			
		||||
  </property>
 | 
			
		||||
  <widget class="QWidget" name="centralwidget">
 | 
			
		||||
   <layout class="QHBoxLayout" name="horizontalLayout">
 | 
			
		||||
    <property name="margin">
 | 
			
		||||
    <property name="margin" stdset="0">
 | 
			
		||||
     <number>0</number>
 | 
			
		||||
    </property>
 | 
			
		||||
   </layout>
 | 
			
		||||
@ -36,7 +36,7 @@
 | 
			
		||||
     <x>0</x>
 | 
			
		||||
     <y>0</y>
 | 
			
		||||
     <width>1280</width>
 | 
			
		||||
     <height>26</height>
 | 
			
		||||
     <height>21</height>
 | 
			
		||||
    </rect>
 | 
			
		||||
   </property>
 | 
			
		||||
   <widget class="QMenu" name="menu_File">
 | 
			
		||||
@ -162,6 +162,7 @@
 | 
			
		||||
    <addaction name="menu_cabinet_applet"/>
 | 
			
		||||
    <addaction name="action_Load_Album"/>
 | 
			
		||||
    <addaction name="action_Load_Mii_Edit"/>
 | 
			
		||||
    <addaction name="action_Open_Controller_Menu"/>
 | 
			
		||||
    <addaction name="separator"/>
 | 
			
		||||
    <addaction name="action_Capture_Screenshot"/>
 | 
			
		||||
    <addaction name="menuTAS"/>
 | 
			
		||||
@ -382,9 +383,9 @@
 | 
			
		||||
   </property>
 | 
			
		||||
  </action>
 | 
			
		||||
  <action name="action_Load_Album">
 | 
			
		||||
    <property name="text">
 | 
			
		||||
      <string>Open &Album</string>
 | 
			
		||||
    </property>
 | 
			
		||||
   <property name="text">
 | 
			
		||||
    <string>Open &Album</string>
 | 
			
		||||
   </property>
 | 
			
		||||
  </action>
 | 
			
		||||
  <action name="action_Load_Cabinet_Nickname_Owner">
 | 
			
		||||
   <property name="text">
 | 
			
		||||
@ -407,9 +408,9 @@
 | 
			
		||||
   </property>
 | 
			
		||||
  </action>
 | 
			
		||||
  <action name="action_Load_Mii_Edit">
 | 
			
		||||
    <property name="text">
 | 
			
		||||
      <string>Open &Mii Editor</string>
 | 
			
		||||
    </property>
 | 
			
		||||
   <property name="text">
 | 
			
		||||
    <string>Open &Mii Editor</string>
 | 
			
		||||
   </property>
 | 
			
		||||
  </action>
 | 
			
		||||
  <action name="action_Configure_Tas">
 | 
			
		||||
   <property name="text">
 | 
			
		||||
@ -454,6 +455,11 @@
 | 
			
		||||
    <string>R&ecord</string>
 | 
			
		||||
   </property>
 | 
			
		||||
  </action>
 | 
			
		||||
  <action name="action_Open_Controller_Menu">
 | 
			
		||||
   <property name="text">
 | 
			
		||||
    <string>Open &Controller Menu</string>
 | 
			
		||||
   </property>
 | 
			
		||||
  </action>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <resources>
 | 
			
		||||
  <include location="yuzu.qrc"/>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user