From d7671fa66e01fef1f6bd320d46874bc03cb9fac6 Mon Sep 17 00:00:00 2001 From: Alienjack Date: Wed, 10 Sep 2025 22:38:08 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dxmb=E9=94=AE=E4=BD=8D?= =?UTF-8?q?=E6=98=A0=E5=B0=84=E9=97=AE=E9=A2=98=EF=BC=8C=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=91=87=E6=9D=86=E7=B1=BB=E6=8E=A7=E5=88=B6=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E7=9A=84=E4=B8=8A=E4=B8=8B=E5=B7=A6=E5=8F=B3=E6=96=B9=E5=90=91?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E9=80=BB=E8=BE=91=EF=BC=8C=E5=B9=B6=E5=8A=A0?= =?UTF-8?q?=E5=85=A5=E6=AD=BB=E5=8C=BA=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../KeyMapperSetting/Model/EmuCoreBinder.cs | 20 ++- .../KeyMapperSetting/XMBKeyBinding.cs | 158 +++++++++++------- .../Devices/InputControls/Stick_C.cs | 71 +++++++- 3 files changed, 187 insertions(+), 62 deletions(-) diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/KeyMapperSetting/Model/EmuCoreBinder.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/KeyMapperSetting/Model/EmuCoreBinder.cs index 95b3ae58..669e2756 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/KeyMapperSetting/Model/EmuCoreBinder.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/KeyMapperSetting/Model/EmuCoreBinder.cs @@ -21,6 +21,13 @@ public abstract class EmuCoreBinder : InternalEmuCoreBinder, IDeviceBinder where T : Enum { + /// + /// 忽略输入设备的独占属性 + /// false:标记为独占的设备(Exclusive==true)只能绑定到一个控制器上 + /// true:设备可以被绑定到所有控制器上,无视设备的独占属性 + /// + protected virtual bool IgnoreInputDeviceExclusive => false; + //每一个实例代表一个对应模拟器平台的控制器索引 List m_controllerBinders = new List(); @@ -37,7 +44,7 @@ public abstract class EmuCoreBinder : InternalEmuCoreBinder, { foreach (var binding in m_controllerBinders) { - if (device.Exclusive && GetRegistedBinder(device) != null) continue; + if (!CheckDeviceCanBind(device)) break; binding.RegistInputDevice(device); } @@ -64,11 +71,20 @@ public abstract class EmuCoreBinder : InternalEmuCoreBinder, { foreach (var binding in m_controllerBinders) { - if (connectDevice.Exclusive && GetRegistedBinder(connectDevice) != null) continue; + if (!CheckDeviceCanBind(connectDevice)) return; 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) { foreach (var binding in m_controllerBinders) diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/KeyMapperSetting/XMBKeyBinding.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/KeyMapperSetting/XMBKeyBinding.cs index 636ac49b..bf83386b 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/KeyMapperSetting/XMBKeyBinding.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/KeyMapperSetting/XMBKeyBinding.cs @@ -1,10 +1,12 @@ using AxibugEmuOnline.Client.InputDevices; using AxibugProtobuf; +using static AxibugEmuOnline.Client.NesControllerMapper; namespace AxibugEmuOnline.Client { public class XMBKeyBinding : EmuCoreBinder { + protected override bool IgnoreInputDeviceExclusive => true; public override RomPlatformType Platform => RomPlatformType.Invalid; public override int ControllerCount => 2; @@ -39,78 +41,122 @@ namespace AxibugEmuOnline.Client } public override void Bind(DualShockController_D device, ControllerBinder controller) { - controller.SetBinding(EnumCommand.Back, device.Circle, 0); - controller.SetBinding(EnumCommand.Enter, device.Cross, 0); - controller.SetBinding(EnumCommand.OptionMenu, device.Options, 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); + switch (controller.ControllerIndex) + { + case 0: + controller.SetBinding(EnumCommand.Back, device.Circle, 0); + controller.SetBinding(EnumCommand.Enter, device.Cross, 0); + controller.SetBinding(EnumCommand.OptionMenu, device.Options, 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); + 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.TouchpadBtn, 0); + controller.SetBinding(EnumCommand.OptionMenu, device.R3, 1); + break; + } } public override void Bind(GamePad_D device, ControllerBinder controller) { - controller.SetBinding(EnumCommand.Back, device.East, 0); - controller.SetBinding(EnumCommand.Enter, device.South, 0); - controller.SetBinding(EnumCommand.OptionMenu, device.Start, 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); + switch (controller.ControllerIndex) + { + case 0: + controller.SetBinding(EnumCommand.Back, device.East, 0); + controller.SetBinding(EnumCommand.Enter, device.South, 0); + controller.SetBinding(EnumCommand.OptionMenu, device.Start, 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) { - controller.SetBinding(EnumCommand.Back, device.Circle, 0); - controller.SetBinding(EnumCommand.Enter, device.Cross, 0); - controller.SetBinding(EnumCommand.OptionMenu, device.Start, 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); + switch (controller.ControllerIndex) + { + case 0: + controller.SetBinding(EnumCommand.Back, device.Circle, 0); + controller.SetBinding(EnumCommand.Enter, device.Cross, 0); + controller.SetBinding(EnumCommand.OptionMenu, device.Start, 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) { - controller.SetBinding(EnumCommand.Back, device.B, 0); - controller.SetBinding(EnumCommand.Enter, device.A, 0); - controller.SetBinding(EnumCommand.OptionMenu, device.Menu, 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); + switch (controller.ControllerIndex) + { + case 0: + controller.SetBinding(EnumCommand.Back, device.B, 0); + controller.SetBinding(EnumCommand.Enter, device.A, 0); + controller.SetBinding(EnumCommand.OptionMenu, device.Menu, 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) { - controller.SetBinding(EnumCommand.Back, device.BTN_A, 0); - controller.SetBinding(EnumCommand.Enter, device.BTN_B, 0); - controller.SetBinding(EnumCommand.OptionMenu, device.OPTION_1, 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); + switch (controller.ControllerIndex) + { + case 0: + controller.SetBinding(EnumCommand.Back, device.BTN_A, 0); + controller.SetBinding(EnumCommand.Enter, device.BTN_B, 0); + controller.SetBinding(EnumCommand.OptionMenu, device.OPTION_1, 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.SelectItemLeft, device.JOYSTICK.Left, 1); - controller.SetBinding(EnumCommand.SelectItemRight, device.JOYSTICK.Right, 1); - controller.SetBinding(EnumCommand.SelectItemUp, device.JOYSTICK.Up, 1); + controller.SetBinding(EnumCommand.SelectItemDown, device.JOYSTICK.Down, 1); + controller.SetBinding(EnumCommand.SelectItemLeft, device.JOYSTICK.Left, 1); + controller.SetBinding(EnumCommand.SelectItemRight, device.JOYSTICK.Right, 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) { @@ -131,7 +177,7 @@ namespace AxibugEmuOnline.Client controller.SetBinding(EnumCommand.SelectItemUp, device.LeftStick.Up, 1); break; case 1://游戏中UI控制 - controller.SetBinding(EnumCommand.OptionMenu, device.Y, 0); + controller.SetBinding(EnumCommand.OptionMenu, device.RightStickPress, 0); break; } } diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/InputDevicesManager/Devices/InputControls/Stick_C.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/InputDevicesManager/Devices/InputControls/Stick_C.cs index 023b1146..72341190 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/InputDevicesManager/Devices/InputControls/Stick_C.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/InputDevicesManager/Devices/InputControls/Stick_C.cs @@ -18,19 +18,21 @@ namespace AxibugEmuOnline.Client.InputDevices { var axis = GetVector2(); - Up.m_performing = axis.y > 0f; + var dir = GetDirection(axis, 0.15f); + Up.m_performing = dir == Direction.Up; Up.Update(); - Down.m_performing = axis.y < 0f; + Down.m_performing = dir == Direction.Down; Down.Update(); - Left.m_performing = axis.x < 0f; + Left.m_performing = dir == Direction.Left; Left.Update(); - Right.m_performing = axis.x > 0f; + Right.m_performing = dir == Direction.Right; Right.Update(); } + public class VirtualButton : InputControl_C { @@ -53,5 +55,66 @@ namespace AxibugEmuOnline.Client.InputDevices 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; + } + } }