Merge pull request 'master' (#109) from Alienjack/AxibugEmuOnline:master into master

Reviewed-on: #109
This commit is contained in:
sin365 2025-09-10 22:44:51 +08:00
commit b2525bb68f
4 changed files with 189 additions and 63 deletions

View File

@ -736,6 +736,7 @@ public class AxiNSIO
#endif
}
#if UNITY_SWITCH
bool CreateLoopDir(string path)
{
// 检查路径是否存在及其类型
@ -783,7 +784,7 @@ public class AxiNSIO
return false;
return true;
}
#endif
/// <summary>
/// 解析路径并获取其所有父级目录(从直接父目录到根目录),并排除存储设备挂载根节点(如"save:"或"sd:")。

View File

@ -21,6 +21,13 @@ public abstract class EmuCoreBinder<T> : InternalEmuCoreBinder,
IDeviceBinder<T, SwitchJoyCon_D>
where T : Enum
{
/// <summary>
/// 忽略输入设备的独占属性
/// false:标记为独占的设备Exclusive==true只能绑定到一个控制器上
/// true:设备可以被绑定到所有控制器上,无视设备的独占属性
/// </summary>
protected virtual bool IgnoreInputDeviceExclusive => false;
//每一个实例代表一个对应模拟器平台的控制器索引
List<ControllerBinder> m_controllerBinders = new List<ControllerBinder>();
@ -37,7 +44,7 @@ public abstract class EmuCoreBinder<T> : 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<T> : 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)

View File

@ -1,10 +1,12 @@
using AxibugEmuOnline.Client.InputDevices;
using AxibugProtobuf;
using static AxibugEmuOnline.Client.NesControllerMapper;
namespace AxibugEmuOnline.Client
{
public class XMBKeyBinding : EmuCoreBinder<EnumCommand>
{
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;
}
}

View File

@ -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;
}
}
}