mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	Merge pull request #2657 from ogniK5377/npad-assignments
hid:StartLrAssignmentMode, hid:StopLrAssignmentMode, hid:SwapNpadAssignment
This commit is contained in:
		@@ -548,6 +548,37 @@ void Controller_NPad::DisconnectNPad(u32 npad_id) {
 | 
			
		||||
    connected_controllers[NPadIdToIndex(npad_id)].is_connected = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Controller_NPad::StartLRAssignmentMode() {
 | 
			
		||||
    // Nothing internally is used for lr assignment mode. Since we have the ability to set the
 | 
			
		||||
    // controller types from boot, it doesn't really matter about showing a selection screen
 | 
			
		||||
    is_in_lr_assignment_mode = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Controller_NPad::StopLRAssignmentMode() {
 | 
			
		||||
    is_in_lr_assignment_mode = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Controller_NPad::SwapNpadAssignment(u32 npad_id_1, u32 npad_id_2) {
 | 
			
		||||
    if (npad_id_1 == NPAD_HANDHELD || npad_id_2 == NPAD_HANDHELD || npad_id_1 == NPAD_UNKNOWN ||
 | 
			
		||||
        npad_id_2 == NPAD_UNKNOWN) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    const auto npad_index_1 = NPadIdToIndex(npad_id_1);
 | 
			
		||||
    const auto npad_index_2 = NPadIdToIndex(npad_id_2);
 | 
			
		||||
 | 
			
		||||
    if (!IsControllerSupported(connected_controllers[npad_index_1].type) ||
 | 
			
		||||
        !IsControllerSupported(connected_controllers[npad_index_2].type)) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::swap(connected_controllers[npad_index_1].type, connected_controllers[npad_index_2].type);
 | 
			
		||||
 | 
			
		||||
    InitNewlyAddedControler(npad_index_1);
 | 
			
		||||
    InitNewlyAddedControler(npad_index_2);
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Controller_NPad::IsControllerSupported(NPadControllerType controller) {
 | 
			
		||||
    if (controller == NPadControllerType::Handheld) {
 | 
			
		||||
        // Handheld is not even a supported type, lets stop here
 | 
			
		||||
 
 | 
			
		||||
@@ -124,6 +124,10 @@ public:
 | 
			
		||||
    void ConnectAllDisconnectedControllers();
 | 
			
		||||
    void ClearAllControllers();
 | 
			
		||||
 | 
			
		||||
    void StartLRAssignmentMode();
 | 
			
		||||
    void StopLRAssignmentMode();
 | 
			
		||||
    bool SwapNpadAssignment(u32 npad_id_1, u32 npad_id_2);
 | 
			
		||||
 | 
			
		||||
    // Logical OR for all buttons presses on all controllers
 | 
			
		||||
    // Specifically for cheat engine and other features.
 | 
			
		||||
    u32 GetAndResetPressState();
 | 
			
		||||
@@ -321,5 +325,6 @@ private:
 | 
			
		||||
    void RequestPadStateUpdate(u32 npad_id);
 | 
			
		||||
    std::array<ControllerPad, 10> npad_pad_states{};
 | 
			
		||||
    bool IsControllerSupported(NPadControllerType controller);
 | 
			
		||||
    bool is_in_lr_assignment_mode{false};
 | 
			
		||||
};
 | 
			
		||||
} // namespace Service::HID
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								src/core/hle/service/hid/errors.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/core/hle/service/hid/errors.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
// Copyright 2019 yuzu emulator team
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "core/hle/result.h"
 | 
			
		||||
 | 
			
		||||
namespace Service::HID {
 | 
			
		||||
 | 
			
		||||
constexpr ResultCode ERR_NPAD_NOT_CONNECTED{ErrorModule::HID, 710};
 | 
			
		||||
 | 
			
		||||
} // namespace Service::HID
 | 
			
		||||
@@ -16,6 +16,7 @@
 | 
			
		||||
#include "core/hle/kernel/readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/shared_memory.h"
 | 
			
		||||
#include "core/hle/kernel/writable_event.h"
 | 
			
		||||
#include "core/hle/service/hid/errors.h"
 | 
			
		||||
#include "core/hle/service/hid/hid.h"
 | 
			
		||||
#include "core/hle/service/hid/irs.h"
 | 
			
		||||
#include "core/hle/service/hid/xcd.h"
 | 
			
		||||
@@ -202,11 +203,11 @@ Hid::Hid() : ServiceFramework("hid") {
 | 
			
		||||
        {123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"},
 | 
			
		||||
        {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"},
 | 
			
		||||
        {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"},
 | 
			
		||||
        {126, nullptr, "StartLrAssignmentMode"},
 | 
			
		||||
        {127, nullptr, "StopLrAssignmentMode"},
 | 
			
		||||
        {126, &Hid::StartLrAssignmentMode, "StartLrAssignmentMode"},
 | 
			
		||||
        {127, &Hid::StopLrAssignmentMode, "StopLrAssignmentMode"},
 | 
			
		||||
        {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
 | 
			
		||||
        {129, nullptr, "GetNpadHandheldActivationMode"},
 | 
			
		||||
        {130, nullptr, "SwapNpadAssignment"},
 | 
			
		||||
        {130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"},
 | 
			
		||||
        {131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"},
 | 
			
		||||
        {132, nullptr, "EnableUnintendedHomeButtonInputProtection"},
 | 
			
		||||
        {133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"},
 | 
			
		||||
@@ -733,6 +734,49 @@ void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    rb.Push(RESULT_SUCCESS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp{ctx};
 | 
			
		||||
    const auto applet_resource_user_id{rp.Pop<u64>()};
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
 | 
			
		||||
    auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
 | 
			
		||||
    controller.StartLRAssignmentMode();
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
    rb.Push(RESULT_SUCCESS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp{ctx};
 | 
			
		||||
    const auto applet_resource_user_id{rp.Pop<u64>()};
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
 | 
			
		||||
    auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
 | 
			
		||||
    controller.StopLRAssignmentMode();
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
    rb.Push(RESULT_SUCCESS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp{ctx};
 | 
			
		||||
    const auto npad_1{rp.Pop<u32>()};
 | 
			
		||||
    const auto npad_2{rp.Pop<u32>()};
 | 
			
		||||
    const auto applet_resource_user_id{rp.Pop<u64>()};
 | 
			
		||||
 | 
			
		||||
    LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, npad_1={}, npad_2={}",
 | 
			
		||||
              applet_resource_user_id, npad_1, npad_2);
 | 
			
		||||
 | 
			
		||||
    auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
    if (controller.SwapNpadAssignment(npad_1, npad_2)) {
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_ERROR(Service_HID, "Npads are not connected!");
 | 
			
		||||
        rb.Push(ERR_NPAD_NOT_CONNECTED);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class HidDbg final : public ServiceFramework<HidDbg> {
 | 
			
		||||
public:
 | 
			
		||||
    explicit HidDbg() : ServiceFramework{"hid:dbg"} {
 | 
			
		||||
 
 | 
			
		||||
@@ -119,6 +119,9 @@ private:
 | 
			
		||||
    void StopSixAxisSensor(Kernel::HLERequestContext& ctx);
 | 
			
		||||
    void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx);
 | 
			
		||||
    void SetPalmaBoostMode(Kernel::HLERequestContext& ctx);
 | 
			
		||||
    void StartLrAssignmentMode(Kernel::HLERequestContext& ctx);
 | 
			
		||||
    void StopLrAssignmentMode(Kernel::HLERequestContext& ctx);
 | 
			
		||||
    void SwapNpadAssignment(Kernel::HLERequestContext& ctx);
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr<IAppletResource> applet_resource;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user