forked from sin365/AxibugEmuOnline
修复xmb键位映射问题,优化摇杆类控制设备的上下左右方向判断逻辑,并加入死区机制
This commit is contained in:
parent
592d76a302
commit
d7671fa66e
@ -21,6 +21,13 @@ public abstract class EmuCoreBinder<T> : InternalEmuCoreBinder,
|
|||||||
IDeviceBinder<T, SwitchJoyCon_D>
|
IDeviceBinder<T, SwitchJoyCon_D>
|
||||||
where T : Enum
|
where T : Enum
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 忽略输入设备的独占属性
|
||||||
|
/// false:标记为独占的设备(Exclusive==true)只能绑定到一个控制器上
|
||||||
|
/// true:设备可以被绑定到所有控制器上,无视设备的独占属性
|
||||||
|
/// </summary>
|
||||||
|
protected virtual bool IgnoreInputDeviceExclusive => false;
|
||||||
|
|
||||||
//每一个实例代表一个对应模拟器平台的控制器索引
|
//每一个实例代表一个对应模拟器平台的控制器索引
|
||||||
List<ControllerBinder> m_controllerBinders = new List<ControllerBinder>();
|
List<ControllerBinder> m_controllerBinders = new List<ControllerBinder>();
|
||||||
|
|
||||||
@ -37,7 +44,7 @@ public abstract class EmuCoreBinder<T> : InternalEmuCoreBinder,
|
|||||||
{
|
{
|
||||||
foreach (var binding in m_controllerBinders)
|
foreach (var binding in m_controllerBinders)
|
||||||
{
|
{
|
||||||
if (device.Exclusive && GetRegistedBinder(device) != null) continue;
|
if (!CheckDeviceCanBind(device)) break;
|
||||||
|
|
||||||
binding.RegistInputDevice(device);
|
binding.RegistInputDevice(device);
|
||||||
}
|
}
|
||||||
@ -64,11 +71,20 @@ public abstract class EmuCoreBinder<T> : InternalEmuCoreBinder,
|
|||||||
{
|
{
|
||||||
foreach (var binding in m_controllerBinders)
|
foreach (var binding in m_controllerBinders)
|
||||||
{
|
{
|
||||||
if (connectDevice.Exclusive && GetRegistedBinder(connectDevice) != null) continue;
|
if (!CheckDeviceCanBind(connectDevice)) return;
|
||||||
binding.RegistInputDevice(connectDevice);
|
binding.RegistInputDevice(connectDevice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool CheckDeviceCanBind(InputDevice_D device)
|
||||||
|
{
|
||||||
|
if (IgnoreInputDeviceExclusive) return true;
|
||||||
|
if (!device.Exclusive) return true;
|
||||||
|
|
||||||
|
//当一个输入设备的Exclusive为true时,只能绑定到一个控制器
|
||||||
|
return GetRegistedBinder(device) == null;
|
||||||
|
}
|
||||||
|
|
||||||
private void InputDevicesMgr_OnDeviceLost(InputDevice_D lostDevice)
|
private void InputDevicesMgr_OnDeviceLost(InputDevice_D lostDevice)
|
||||||
{
|
{
|
||||||
foreach (var binding in m_controllerBinders)
|
foreach (var binding in m_controllerBinders)
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
using AxibugEmuOnline.Client.InputDevices;
|
using AxibugEmuOnline.Client.InputDevices;
|
||||||
using AxibugProtobuf;
|
using AxibugProtobuf;
|
||||||
|
using static AxibugEmuOnline.Client.NesControllerMapper;
|
||||||
|
|
||||||
namespace AxibugEmuOnline.Client
|
namespace AxibugEmuOnline.Client
|
||||||
{
|
{
|
||||||
public class XMBKeyBinding : EmuCoreBinder<EnumCommand>
|
public class XMBKeyBinding : EmuCoreBinder<EnumCommand>
|
||||||
{
|
{
|
||||||
|
protected override bool IgnoreInputDeviceExclusive => true;
|
||||||
public override RomPlatformType Platform => RomPlatformType.Invalid;
|
public override RomPlatformType Platform => RomPlatformType.Invalid;
|
||||||
public override int ControllerCount => 2;
|
public override int ControllerCount => 2;
|
||||||
|
|
||||||
@ -39,78 +41,122 @@ namespace AxibugEmuOnline.Client
|
|||||||
}
|
}
|
||||||
public override void Bind(DualShockController_D device, ControllerBinder controller)
|
public override void Bind(DualShockController_D device, ControllerBinder controller)
|
||||||
{
|
{
|
||||||
controller.SetBinding(EnumCommand.Back, device.Circle, 0);
|
switch (controller.ControllerIndex)
|
||||||
controller.SetBinding(EnumCommand.Enter, device.Cross, 0);
|
{
|
||||||
controller.SetBinding(EnumCommand.OptionMenu, device.Options, 0);
|
case 0:
|
||||||
controller.SetBinding(EnumCommand.SelectItemDown, device.Down, 0);
|
controller.SetBinding(EnumCommand.Back, device.Circle, 0);
|
||||||
controller.SetBinding(EnumCommand.SelectItemLeft, device.Left, 0);
|
controller.SetBinding(EnumCommand.Enter, device.Cross, 0);
|
||||||
controller.SetBinding(EnumCommand.SelectItemRight, device.Right, 0);
|
controller.SetBinding(EnumCommand.OptionMenu, device.Options, 0);
|
||||||
controller.SetBinding(EnumCommand.SelectItemUp, device.Up, 0);
|
controller.SetBinding(EnumCommand.SelectItemDown, device.Down, 0);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemLeft, device.Left, 0);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemRight, device.Right, 0);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemUp, device.Up, 0);
|
||||||
|
|
||||||
controller.SetBinding(EnumCommand.SelectItemDown, device.LeftStick.Down, 1);
|
controller.SetBinding(EnumCommand.SelectItemDown, device.LeftStick.Down, 1);
|
||||||
controller.SetBinding(EnumCommand.SelectItemLeft, device.LeftStick.Left, 1);
|
controller.SetBinding(EnumCommand.SelectItemLeft, device.LeftStick.Left, 1);
|
||||||
controller.SetBinding(EnumCommand.SelectItemRight, device.LeftStick.Right, 1);
|
controller.SetBinding(EnumCommand.SelectItemRight, device.LeftStick.Right, 1);
|
||||||
controller.SetBinding(EnumCommand.SelectItemUp, device.LeftStick.Up, 1);
|
controller.SetBinding(EnumCommand.SelectItemUp, device.LeftStick.Up, 1);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
controller.SetBinding(EnumCommand.OptionMenu, device.TouchpadBtn, 0);
|
||||||
|
controller.SetBinding(EnumCommand.OptionMenu, device.R3, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public override void Bind(GamePad_D device, ControllerBinder controller)
|
public override void Bind(GamePad_D device, ControllerBinder controller)
|
||||||
{
|
{
|
||||||
controller.SetBinding(EnumCommand.Back, device.East, 0);
|
switch (controller.ControllerIndex)
|
||||||
controller.SetBinding(EnumCommand.Enter, device.South, 0);
|
{
|
||||||
controller.SetBinding(EnumCommand.OptionMenu, device.Start, 0);
|
case 0:
|
||||||
controller.SetBinding(EnumCommand.SelectItemDown, device.Down, 0);
|
controller.SetBinding(EnumCommand.Back, device.East, 0);
|
||||||
controller.SetBinding(EnumCommand.SelectItemLeft, device.Left, 0);
|
controller.SetBinding(EnumCommand.Enter, device.South, 0);
|
||||||
controller.SetBinding(EnumCommand.SelectItemRight, device.Right, 0);
|
controller.SetBinding(EnumCommand.OptionMenu, device.Start, 0);
|
||||||
controller.SetBinding(EnumCommand.SelectItemUp, device.Up, 0);
|
controller.SetBinding(EnumCommand.SelectItemDown, device.Down, 0);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemLeft, device.Left, 0);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemRight, device.Right, 0);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemUp, device.Up, 0);
|
||||||
|
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemDown, device.LeftStick.Down, 1);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemLeft, device.LeftStick.Left, 1);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemRight, device.LeftStick.Right, 1);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemUp, device.LeftStick.Up, 1);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
controller.SetBinding(EnumCommand.OptionMenu, device.RightStickPress, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
controller.SetBinding(EnumCommand.SelectItemDown, device.LeftStick.Down, 1);
|
|
||||||
controller.SetBinding(EnumCommand.SelectItemLeft, device.LeftStick.Left, 1);
|
|
||||||
controller.SetBinding(EnumCommand.SelectItemRight, device.LeftStick.Right, 1);
|
|
||||||
controller.SetBinding(EnumCommand.SelectItemUp, device.LeftStick.Up, 1);
|
|
||||||
}
|
}
|
||||||
public override void Bind(PSVController_D device, ControllerBinder controller)
|
public override void Bind(PSVController_D device, ControllerBinder controller)
|
||||||
{
|
{
|
||||||
controller.SetBinding(EnumCommand.Back, device.Circle, 0);
|
switch (controller.ControllerIndex)
|
||||||
controller.SetBinding(EnumCommand.Enter, device.Cross, 0);
|
{
|
||||||
controller.SetBinding(EnumCommand.OptionMenu, device.Start, 0);
|
case 0:
|
||||||
controller.SetBinding(EnumCommand.SelectItemDown, device.Down, 0);
|
controller.SetBinding(EnumCommand.Back, device.Circle, 0);
|
||||||
controller.SetBinding(EnumCommand.SelectItemLeft, device.Left, 0);
|
controller.SetBinding(EnumCommand.Enter, device.Cross, 0);
|
||||||
controller.SetBinding(EnumCommand.SelectItemRight, device.Right, 0);
|
controller.SetBinding(EnumCommand.OptionMenu, device.Start, 0);
|
||||||
controller.SetBinding(EnumCommand.SelectItemUp, device.Up, 0);
|
controller.SetBinding(EnumCommand.SelectItemDown, device.Down, 0);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemLeft, device.Left, 0);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemRight, device.Right, 0);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemUp, device.Up, 0);
|
||||||
|
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemDown, device.LeftStick.Down, 1);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemLeft, device.LeftStick.Left, 1);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemRight, device.LeftStick.Right, 1);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemUp, device.LeftStick.Up, 1);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
controller.SetBinding(EnumCommand.OptionMenu, device.Triangle, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
controller.SetBinding(EnumCommand.SelectItemDown, device.LeftStick.Down, 1);
|
|
||||||
controller.SetBinding(EnumCommand.SelectItemLeft, device.LeftStick.Left, 1);
|
|
||||||
controller.SetBinding(EnumCommand.SelectItemRight, device.LeftStick.Right, 1);
|
|
||||||
controller.SetBinding(EnumCommand.SelectItemUp, device.LeftStick.Up, 1);
|
|
||||||
}
|
}
|
||||||
public override void Bind(XboxController_D device, ControllerBinder controller)
|
public override void Bind(XboxController_D device, ControllerBinder controller)
|
||||||
{
|
{
|
||||||
controller.SetBinding(EnumCommand.Back, device.B, 0);
|
switch (controller.ControllerIndex)
|
||||||
controller.SetBinding(EnumCommand.Enter, device.A, 0);
|
{
|
||||||
controller.SetBinding(EnumCommand.OptionMenu, device.Menu, 0);
|
case 0:
|
||||||
controller.SetBinding(EnumCommand.SelectItemDown, device.Down, 0);
|
controller.SetBinding(EnumCommand.Back, device.B, 0);
|
||||||
controller.SetBinding(EnumCommand.SelectItemLeft, device.Left, 0);
|
controller.SetBinding(EnumCommand.Enter, device.A, 0);
|
||||||
controller.SetBinding(EnumCommand.SelectItemRight, device.Right, 0);
|
controller.SetBinding(EnumCommand.OptionMenu, device.Menu, 0);
|
||||||
controller.SetBinding(EnumCommand.SelectItemUp, device.Up, 0);
|
controller.SetBinding(EnumCommand.SelectItemDown, device.Down, 0);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemLeft, device.Left, 0);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemRight, device.Right, 0);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemUp, device.Up, 0);
|
||||||
|
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemDown, device.LeftStick.Down, 1);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemLeft, device.LeftStick.Left, 1);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemRight, device.LeftStick.Right, 1);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemUp, device.LeftStick.Up, 1);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
controller.SetBinding(EnumCommand.OptionMenu, device.RightStickPress, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
controller.SetBinding(EnumCommand.SelectItemDown, device.LeftStick.Down, 1);
|
|
||||||
controller.SetBinding(EnumCommand.SelectItemLeft, device.LeftStick.Left, 1);
|
|
||||||
controller.SetBinding(EnumCommand.SelectItemRight, device.LeftStick.Right, 1);
|
|
||||||
controller.SetBinding(EnumCommand.SelectItemUp, device.LeftStick.Up, 1);
|
|
||||||
}
|
}
|
||||||
public override void Bind(ScreenGamepad_D device, ControllerBinder controller)
|
public override void Bind(ScreenGamepad_D device, ControllerBinder controller)
|
||||||
{
|
{
|
||||||
controller.SetBinding(EnumCommand.Back, device.BTN_A, 0);
|
switch (controller.ControllerIndex)
|
||||||
controller.SetBinding(EnumCommand.Enter, device.BTN_B, 0);
|
{
|
||||||
controller.SetBinding(EnumCommand.OptionMenu, device.OPTION_1, 0);
|
case 0:
|
||||||
controller.SetBinding(EnumCommand.SelectItemDown, device.DOWN, 0);
|
controller.SetBinding(EnumCommand.Back, device.BTN_A, 0);
|
||||||
controller.SetBinding(EnumCommand.SelectItemLeft, device.LEFT, 0);
|
controller.SetBinding(EnumCommand.Enter, device.BTN_B, 0);
|
||||||
controller.SetBinding(EnumCommand.SelectItemRight, device.RIGHT, 0);
|
controller.SetBinding(EnumCommand.OptionMenu, device.OPTION_1, 0);
|
||||||
controller.SetBinding(EnumCommand.SelectItemUp, device.UP, 0);
|
controller.SetBinding(EnumCommand.SelectItemDown, device.DOWN, 0);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemLeft, device.LEFT, 0);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemRight, device.RIGHT, 0);
|
||||||
|
controller.SetBinding(EnumCommand.SelectItemUp, device.UP, 0);
|
||||||
|
|
||||||
controller.SetBinding(EnumCommand.SelectItemDown, device.JOYSTICK.Down, 1);
|
controller.SetBinding(EnumCommand.SelectItemDown, device.JOYSTICK.Down, 1);
|
||||||
controller.SetBinding(EnumCommand.SelectItemLeft, device.JOYSTICK.Left, 1);
|
controller.SetBinding(EnumCommand.SelectItemLeft, device.JOYSTICK.Left, 1);
|
||||||
controller.SetBinding(EnumCommand.SelectItemRight, device.JOYSTICK.Right, 1);
|
controller.SetBinding(EnumCommand.SelectItemRight, device.JOYSTICK.Right, 1);
|
||||||
controller.SetBinding(EnumCommand.SelectItemUp, device.JOYSTICK.Up, 1);
|
controller.SetBinding(EnumCommand.SelectItemUp, device.JOYSTICK.Up, 1);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
controller.SetBinding(EnumCommand.OptionMenu, device.HOME, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public override void Bind(SwitchJoyCon_D device, ControllerBinder controller)
|
public override void Bind(SwitchJoyCon_D device, ControllerBinder controller)
|
||||||
{
|
{
|
||||||
@ -131,7 +177,7 @@ namespace AxibugEmuOnline.Client
|
|||||||
controller.SetBinding(EnumCommand.SelectItemUp, device.LeftStick.Up, 1);
|
controller.SetBinding(EnumCommand.SelectItemUp, device.LeftStick.Up, 1);
|
||||||
break;
|
break;
|
||||||
case 1://游戏中UI控制
|
case 1://游戏中UI控制
|
||||||
controller.SetBinding(EnumCommand.OptionMenu, device.Y, 0);
|
controller.SetBinding(EnumCommand.OptionMenu, device.RightStickPress, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,19 +18,21 @@ namespace AxibugEmuOnline.Client.InputDevices
|
|||||||
{
|
{
|
||||||
var axis = GetVector2();
|
var axis = GetVector2();
|
||||||
|
|
||||||
Up.m_performing = axis.y > 0f;
|
var dir = GetDirection(axis, 0.15f);
|
||||||
|
Up.m_performing = dir == Direction.Up;
|
||||||
Up.Update();
|
Up.Update();
|
||||||
|
|
||||||
Down.m_performing = axis.y < 0f;
|
Down.m_performing = dir == Direction.Down;
|
||||||
Down.Update();
|
Down.Update();
|
||||||
|
|
||||||
Left.m_performing = axis.x < 0f;
|
Left.m_performing = dir == Direction.Left;
|
||||||
Left.Update();
|
Left.Update();
|
||||||
|
|
||||||
Right.m_performing = axis.x > 0f;
|
Right.m_performing = dir == Direction.Right;
|
||||||
Right.Update();
|
Right.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class VirtualButton : InputControl_C
|
public class VirtualButton : InputControl_C
|
||||||
{
|
{
|
||||||
@ -53,5 +55,66 @@ namespace AxibugEmuOnline.Client.InputDevices
|
|||||||
return Performing ? 1 : 0;
|
return Performing ? 1 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Direction
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Up,
|
||||||
|
Down,
|
||||||
|
Left,
|
||||||
|
Right
|
||||||
|
}
|
||||||
|
|
||||||
|
static Direction GetDirection(Vector2 input, float deadzone)
|
||||||
|
{
|
||||||
|
// 检查死区:如果点在死区半径内,返回无
|
||||||
|
if (input.magnitude <= deadzone)
|
||||||
|
{
|
||||||
|
return Direction.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标准化向量(确保在单位圆上)
|
||||||
|
Vector2 normalized = input.normalized;
|
||||||
|
|
||||||
|
// 计算点与四个方向基准向量的点积
|
||||||
|
float dotUp = Vector2.Dot(normalized, Vector2.up); // (0, 1)
|
||||||
|
float dotDown = Vector2.Dot(normalized, Vector2.down); // (0, -1)
|
||||||
|
float dotRight = Vector2.Dot(normalized, Vector2.right); // (1, 0)
|
||||||
|
float dotLeft = Vector2.Dot(normalized, Vector2.left); // (-1, 0)
|
||||||
|
|
||||||
|
// 找出最大点积对应的方向
|
||||||
|
Direction bestDirection = Direction.None;
|
||||||
|
float maxDot = -1f; // 初始化为最小值
|
||||||
|
|
||||||
|
// 检查上方向
|
||||||
|
if (dotUp > maxDot)
|
||||||
|
{
|
||||||
|
maxDot = dotUp;
|
||||||
|
bestDirection = Direction.Up;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查下方向
|
||||||
|
if (dotDown > maxDot)
|
||||||
|
{
|
||||||
|
maxDot = dotDown;
|
||||||
|
bestDirection = Direction.Down;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查右方向
|
||||||
|
if (dotRight > maxDot)
|
||||||
|
{
|
||||||
|
maxDot = dotRight;
|
||||||
|
bestDirection = Direction.Right;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查左方向
|
||||||
|
if (dotLeft > maxDot)
|
||||||
|
{
|
||||||
|
bestDirection = Direction.Left;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bestDirection;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user