Compare commits

...

16 Commits

Author SHA1 Message Date
3797bba442 完善GamePad支持 2025-03-27 20:13:00 +08:00
4e87cfe9ee Input代码迭代 2025-03-27 20:08:31 +08:00
e463c23c4c Input逻辑结构调整 2025-03-27 19:19:05 +08:00
50e3a30f31 将所有抽象层Input的类加上后缀,D代表设备,C代表控件,避免和InputSystem中的设备重名 2025-03-27 15:02:41 +08:00
8007af0bc5 InputControl的实现类挪入基本类型,不再每个设备单独实现 2025-03-27 11:54:10 +08:00
924727eb7c Input系统代码迭代 2025-03-26 19:07:46 +08:00
cf8127c553 修复GetBinding返回的InputControl对象并不完整的问题 2025-03-18 11:23:08 +08:00
49c893fdab GetBinding方法修改,在没有绑定设备时返回空迭代器而不是null 2025-03-18 10:56:24 +08:00
667089891a KeyMapper根据每种设备单独配置 2025-03-17 20:32:34 +08:00
811b0b2a48 InputManager迭代 2025-03-17 19:50:41 +08:00
a93f6449c8 键盘设备键值字段接口调整 2025-03-17 10:50:17 +08:00
3257e15dda 键盘映射配置加载机制修改,现在在初始化以及任何键盘设备断开和连接时,会检查可用键盘设备并且调用配置加载方法 2025-03-17 10:33:23 +08:00
1c20707751 输入系统迭代 2025-03-14 15:27:26 +08:00
4e1f8fd045 InputDevice中的keybase基类改为inputcontrol,突出基础类型作为一个输入控件的概念,以免和按钮类控件混淆 2025-03-14 11:02:38 +08:00
955a35659a 引入InputSystem,输入设备管理系统迭代中 2025-03-13 17:38:12 +08:00
3c10873180 输入设备管理器,以及按键映射设置基本框架搭建 2025-03-12 20:09:11 +08:00
90 changed files with 2029 additions and 906 deletions

View File

@ -34,7 +34,7 @@ namespace AxibugEmuOnline.Editors
}
EditorGUILayout.EndVertical();
EditorGUILayout.LabelField(dispacather.Current.Name);
EditorGUILayout.LabelField(dispacather.Mode.ToString());
Repaint();
}

View File

@ -10,7 +10,7 @@ GameObject:
m_Component:
- component: {fileID: 3186794564434009199}
- component: {fileID: 1464475178787633862}
- component: {fileID: 2053226018124086955}
- component: {fileID: 3126747713153700628}
m_Layer: 0
m_Name: EventSystem
m_TagString: Untagged
@ -48,7 +48,7 @@ MonoBehaviour:
m_FirstSelected: {fileID: 0}
m_sendNavigationEvents: 0
m_DragThreshold: 10
--- !u!114 &2053226018124086955
--- !u!114 &3126747713153700628
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
@ -57,17 +57,28 @@ MonoBehaviour:
m_GameObject: {fileID: 173080370084988713}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3}
m_Script: {fileID: 11500000, guid: 01614664b831546d2ae94a42149d80ac, type: 3}
m_Name:
m_EditorClassIdentifier:
m_SendPointerHoverToParent: 1
m_HorizontalAxis: Horizontal
m_VerticalAxis: Vertical
m_SubmitButton: Submit
m_CancelButton: Cancel
m_InputActionsPerSecond: 10
m_RepeatDelay: 0.5
m_ForceModuleActive: 0
m_MoveRepeatDelay: 0.5
m_MoveRepeatRate: 0.1
m_XRTrackingOrigin: {fileID: 0}
m_ActionsAsset: {fileID: -944628639613478452, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
m_PointAction: {fileID: -1654692200621890270, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
m_MoveAction: {fileID: -8784545083839296357, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
m_SubmitAction: {fileID: 392368643174621059, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
m_CancelAction: {fileID: 7727032971491509709, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
m_LeftClickAction: {fileID: 3001919216989983466, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
m_MiddleClickAction: {fileID: -2185481485913320682, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
m_RightClickAction: {fileID: -4090225696740746782, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
m_ScrollWheelAction: {fileID: 6240969308177333660, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
m_TrackedDevicePositionAction: {fileID: 6564999863303420839, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
m_TrackedDeviceOrientationAction: {fileID: 7970375526676320489, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
m_DeselectOnBackgroundClick: 1
m_PointerBehavior: 0
m_CursorLockBehavior: 0
m_ScrollDeltaPerTick: 6
--- !u!1 &261166211120060501
GameObject:
m_ObjectHideFlags: 0

View File

@ -1,4 +1,5 @@
using AxibugEmuOnline.Client.Manager;
using AxibugEmuOnline.Client.InputDevices;
using AxibugEmuOnline.Client.Manager;
using AxibugEmuOnline.Client.Network;
using AxibugProtobuf;
using System;
@ -22,14 +23,13 @@ namespace AxibugEmuOnline.Client.ClientCore
public static AppLogin login;
public static AppChat chat;
public static UserDataManager user;
public static AppInput input;
public static InputDevicesManager input;
public static AppEmu emu;
public static HttpAPI httpAPI;
public static CacheManager CacheMgr;
public static AppRoom roomMgr;
public static AppSettings settings;
public static AppShare share;
public static GamePadManager gamePadMgr;
public static SaveSlotManager SavMgr;
public static FileDownloader FileDownloader;
static bool bTest;
@ -70,15 +70,14 @@ namespace AxibugEmuOnline.Client.ClientCore
return s_romLibs[platform];
}
public static void Init(bool isTest = false,bool isUseGUIButton = false, string testSrvIP = "", bool bUseLocalWebApi = false, string mLocalWebApi = "")
public static void Init(bool isTest = false, bool isUseGUIButton = false, string testSrvIP = "", bool bUseLocalWebApi = false, string mLocalWebApi = "")
{
log = new LogManager(OnLogOut);
//其他平台必要的初始化
if (UnityEngine.Application.platform == RuntimePlatform.PSP2)
{
PSP2Init();
}
input = new AppInput();
if (UnityEngine.Application.platform == RuntimePlatform.PSP2) PSP2Init();
input = new InputDevicesManager();
FileDownloader = new FileDownloader();
settings = new AppSettings();
network = new NetworkHelper();
@ -102,7 +101,6 @@ namespace AxibugEmuOnline.Client.ClientCore
roomMgr = new AppRoom();
share = new AppShare();
SavMgr = new SaveSlotManager();
gamePadMgr = new GamePadManager();
bTest = isTest;
@ -232,8 +230,7 @@ namespace AxibugEmuOnline.Client.ClientCore
foreach (var romLib in s_romLibs.Values) romLib.ExecuteFetchRomInfo();
starRomLib.ExecuteFetchRomInfo();
FileDownloader.Update();
gamePadMgr.Update();
input.Update();
}
public static Coroutine StartCoroutine(IEnumerator itor)

View File

@ -1,4 +1,5 @@
using AxibugEmuOnline.Client.Manager;
using AxibugEmuOnline.Client.Settings;
using UnityEngine;
namespace AxiInputSP.Setting

View File

@ -1,4 +1,5 @@
using AxibugEmuOnline.Client.Manager;
using AxibugEmuOnline.Client.Settings;
using UnityEngine;
namespace AxiInputSP.Setting

View File

@ -1,4 +1,5 @@
using AxibugEmuOnline.Client.Manager;
using AxibugEmuOnline.Client.Settings;
using UnityEngine;
namespace AxiInputSP.Setting

View File

@ -1,4 +1,5 @@
using AxibugEmuOnline.Client.Manager;
using AxibugEmuOnline.Client.Settings;
using UnityEngine;
namespace AxiInputSP.Setting

View File

@ -1,24 +1,10 @@
using AxibugEmuOnline.Client.Manager;
using AxibugEmuOnline.Client.Settings;
using System;
using UnityEngine;
namespace AxiInputSP.Setting
{
[Flags]
public enum EssgeeSingleKey : ushort
{
NONE = 0,
UP = 1,
DOWN = 1 << 1,
LEFT = 1 << 2,
RIGHT = 1 << 3,
BTN_1 = 1 << 4,
BTN_2 = 1 << 5,
BTN_3 = 1 << 6,
BTN_4 = 1 << 7,
OPTION_1 = 1 << 8,
OPTION_2 = 1 << 9,
}
public class MasterSystemMultiKeysSetting : MultiKeysSettingBase
{

View File

@ -1,4 +1,5 @@
using AxibugEmuOnline.Client.Manager;
using AxibugEmuOnline.Client.Settings;
using UnityEngine;
namespace AxiInputSP.Setting

View File

@ -1,4 +1,5 @@
using AxibugEmuOnline.Client.Manager;
using AxibugEmuOnline.Client.Settings;
using UnityEngine;
namespace AxiInputSP.Setting

View File

@ -1,23 +1,9 @@
using AxibugEmuOnline.Client.Manager;
using AxibugEmuOnline.Client.Settings;
using UnityEngine;
namespace AxiInputSP.Setting
{
public enum UMAMEKSingleKey
{
INSERT_COIN,
GAMESTART,
UP,
DOWN,
LEFT,
RIGHT,
BTN_A,
BTN_B,
BTN_C,
BTN_D,
BTN_E,
BTN_F
}
public class UMAMEMultiKeysSetting : MultiKeysSettingBase
{
public UMAMEMultiKeysSetting()

View File

@ -6,7 +6,8 @@
"VirtualNes.Core",
"UIEffect2018",
"Mame.Core",
"Essgee.Unity"
"Essgee.Unity",
"Unity.InputSystem"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@ -1,7 +1,8 @@
using AxibugEmuOnline.Client;
using AxibugEmuOnline.Client;
using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.Event;
using AxibugEmuOnline.Client.Manager;
using AxibugEmuOnline.Client.Settings;
using AxiInputSP.Setting;
using AxiReplay;
using System;
@ -318,7 +319,7 @@ public class UEGKeyboard : MonoBehaviour
public bool SampleInput()
{
//Net模式
//Net模式
if (InGameUI.Instance.IsNetPlay)
{
bool bHadNetData = false;
@ -334,18 +335,18 @@ public class UEGKeyboard : MonoBehaviour
SetCurrKeyArr(CurrRemoteInpuAllData);
bHadNetData = true;
}
else//无输入
else//无输入
{
CurrRemoteInpuAllData = 0;
}
//发送本地操作
//发送本地操作
App.roomMgr.SendRoomSingelPlayerInput(UEssgee.instance.Frame,
DoLocalPressedKeys());
return bHadNetData;
}
//单机模式
//单机模式
else
{
ulong inputData = DoLocalPressedKeys();
@ -550,9 +551,9 @@ public class EssgssSingleController : IController
uint? mConnectSlot;
/// <summary>
/// 指示该手柄连接的手柄插槽
/// <para><c>这个值代表了该手柄在实际游戏中控制的Player</c></para>
/// <value>[0,3] 例外:为空代表未连接</value>
/// 指示该手柄连接的手柄插槽
/// <para><c>这个值代表了该手柄在实际游戏中控制的Player</c></para>
/// <value>[0,3] 例外:为空代表未连接</value>
/// </summary>
public uint? ConnectSlot
{
@ -561,8 +562,8 @@ public class EssgssSingleController : IController
}
/// <summary>
/// 控制器编号
/// <para><c>此编号并非对应游戏中的player1,player2,player3,player4,仅仅作为本地4个手柄的实例</c></para>
/// 控制器编号
/// <para><c>此编号并非对应游戏中的player1,player2,player3,player4,仅仅作为本地4个手柄的实例</c></para>
/// <value>[0,3]</value>
/// </summary>
public int ControllerIndex
@ -578,34 +579,12 @@ public class EssgssSingleController : IController
public bool AnyButtonDown()
{
//if (Input.GetKeyDown(UP)) return true;
//if (Input.GetKeyDown(DOWN)) return true;
//if (Input.GetKeyDown(LEFT)) return true;
//if (Input.GetKeyDown(RIGHT)) return true;
//if (Input.GetKeyDown(BTN_1)) return true;
//if (Input.GetKeyDown(BTN_2)) return true;
//if (Input.GetKeyDown(BTN_3)) return true;
//if (Input.GetKeyDown(BTN_4)) return true;
//if (Input.GetKeyDown(OPTION_1)) return true;
//if (Input.GetKeyDown(OPTION_2)) return true;
//return false;
return GetSingleKeys().HadAnyKeyDown();
return GetKeyMapper().AnyKeyDown(mControllerIndex);
}
public SingleKeySettingBase GetSingleKeys()
public EssgeeKeyBinding GetKeyMapper()
{
switch (UEssgee.instance.Platform)
{
case AxibugProtobuf.RomPlatformType.MasterSystem: return App.input.sms.controllers[mControllerIndex];
case AxibugProtobuf.RomPlatformType.GameBoy: return App.input.gb.controllers[mControllerIndex];
case AxibugProtobuf.RomPlatformType.GameBoyColor: return App.input.gbc.controllers[mControllerIndex];
case AxibugProtobuf.RomPlatformType.ColecoVision: return App.input.cv.controllers[mControllerIndex];
case AxibugProtobuf.RomPlatformType.GameGear: return App.input.gg.controllers[mControllerIndex];
case AxibugProtobuf.RomPlatformType.Sc3000: return App.input.sc3000.controllers[mControllerIndex];
case AxibugProtobuf.RomPlatformType.Sg1000: return App.input.sg1000.controllers[mControllerIndex];
default: throw new NotImplementedException("err essgee platform");
}
return App.settings.KeyMapper.GetBinder<EssgeeKeyBinding>(UEssgee.instance.Platform);
}
public ulong GetSingleAllInput()
@ -614,29 +593,19 @@ public class EssgssSingleController : IController
return 0;
CurrLocalSingleAllInput = 0;
SingleKeySettingBase essgeeKeys = GetSingleKeys();
EssgeeKeyBinding essgeeKeys = GetKeyMapper();
if (essgeeKeys.GetKey((ulong)EssgeeSingleKey.UP)) CurrLocalSingleAllInput |= (ulong)tg_UP;
if (essgeeKeys.GetKey((ulong)EssgeeSingleKey.DOWN)) CurrLocalSingleAllInput |= (ulong)tg_DOWN;
if (essgeeKeys.GetKey((ulong)EssgeeSingleKey.LEFT)) CurrLocalSingleAllInput |= (ulong)tg_LEFT;
if (essgeeKeys.GetKey((ulong)EssgeeSingleKey.RIGHT)) CurrLocalSingleAllInput |= (ulong)tg_RIGHT;
if (essgeeKeys.GetKey((ulong)EssgeeSingleKey.BTN_1)) CurrLocalSingleAllInput |= (ulong)tg_BTN_1;
if (essgeeKeys.GetKey((ulong)EssgeeSingleKey.BTN_2)) CurrLocalSingleAllInput |= (ulong)tg_BTN_2;
if (essgeeKeys.GetKey((ulong)EssgeeSingleKey.BTN_3)) CurrLocalSingleAllInput |= (ulong)tg_BTN_3;
if (essgeeKeys.GetKey((ulong)EssgeeSingleKey.BTN_4)) CurrLocalSingleAllInput |= (ulong)tg_BTN_4;
if (essgeeKeys.GetKey((ulong)EssgeeSingleKey.OPTION_1)) CurrLocalSingleAllInput |= (ulong)tg_OPTION_1;
if (essgeeKeys.GetKey((ulong)EssgeeSingleKey.OPTION_2)) CurrLocalSingleAllInput |= (ulong)tg_OPTION_2;
if (essgeeKeys.GetKey(EssgeeSingleKey.UP, mControllerIndex)) CurrLocalSingleAllInput |= tg_UP;
if (essgeeKeys.GetKey(EssgeeSingleKey.DOWN, mControllerIndex)) CurrLocalSingleAllInput |= tg_DOWN;
if (essgeeKeys.GetKey(EssgeeSingleKey.LEFT, mControllerIndex)) CurrLocalSingleAllInput |= tg_LEFT;
if (essgeeKeys.GetKey(EssgeeSingleKey.RIGHT, mControllerIndex)) CurrLocalSingleAllInput |= tg_RIGHT;
if (essgeeKeys.GetKey(EssgeeSingleKey.BTN_1, mControllerIndex)) CurrLocalSingleAllInput |= tg_BTN_1;
if (essgeeKeys.GetKey(EssgeeSingleKey.BTN_2, mControllerIndex)) CurrLocalSingleAllInput |= tg_BTN_2;
if (essgeeKeys.GetKey(EssgeeSingleKey.BTN_3, mControllerIndex)) CurrLocalSingleAllInput |= tg_BTN_3;
if (essgeeKeys.GetKey(EssgeeSingleKey.BTN_4, mControllerIndex)) CurrLocalSingleAllInput |= tg_BTN_4;
if (essgeeKeys.GetKey(EssgeeSingleKey.OPTION_1, mControllerIndex)) CurrLocalSingleAllInput |= tg_OPTION_1;
if (essgeeKeys.GetKey(EssgeeSingleKey.OPTION_2, mControllerIndex)) CurrLocalSingleAllInput |= tg_OPTION_2;
//if (Input.GetKey(UP)) CurrLocalSingleAllInput |= (ulong)tg_UP;
//if (Input.GetKey(DOWN)) CurrLocalSingleAllInput |= (ulong)tg_DOWN;
//if (Input.GetKey(LEFT)) CurrLocalSingleAllInput |= (ulong)tg_LEFT;
//if (Input.GetKey(RIGHT)) CurrLocalSingleAllInput |= (ulong)tg_RIGHT;
//if (Input.GetKey(BTN_1)) CurrLocalSingleAllInput |= (ulong)tg_BTN_1;
//if (Input.GetKey(BTN_2)) CurrLocalSingleAllInput |= (ulong)tg_BTN_2;
//if (Input.GetKey(BTN_3)) CurrLocalSingleAllInput |= (ulong)tg_BTN_3;
//if (Input.GetKey(BTN_4)) CurrLocalSingleAllInput |= (ulong)tg_BTN_4;
//if (Input.GetKey(OPTION_1)) CurrLocalSingleAllInput |= (ulong)tg_OPTION_1;
//if (Input.GetKey(OPTION_2)) CurrLocalSingleAllInput |= (ulong)tg_OPTION_1;
return CurrLocalSingleAllInput;
}
}
@ -646,7 +615,7 @@ public static class EssgssSingleControllerSetter
{
//public static void LoadControlKeyForConfig(this EssgssSingleController singlecontrol)
//{
// //TODO 等待支持配置,或统一
// //TODO 等待支持配置,或统一
// switch (singlecontrol.ControllerIndex)
// {
// case 0:

View File

@ -1,6 +1,7 @@
using AxibugEmuOnline.Client;
using AxibugEmuOnline.Client;
using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.Event;
using AxibugEmuOnline.Client.Settings;
using AxiInputSP.Setting;
using AxiReplay;
using MAME.Core;
@ -25,9 +26,9 @@ public class UniKeyboard : MonoBehaviour, IKeyboard
public ulong GetPressedKeys()
{
ulong InputData;
if (!bReplayMode)//游玩模式(单机或联机)
if (!bReplayMode)//游玩模式(单机或联机)
return mPlayMode.GetPressedKeys();
else//Replay模式
else//Replay模式
return mReplayMode.GetPressedKeys();
}
@ -82,7 +83,7 @@ public class UniKeyboard : MonoBehaviour, IKeyboard
public bool SampleInput()
{
//Net模式
//Net模式
if (InGameUI.Instance.IsNetPlay)
{
bool bHadNetData = false;
@ -98,15 +99,15 @@ public class UniKeyboard : MonoBehaviour, IKeyboard
bHadNetData = true;
}
else//无输入
else//无输入
{
CurrRemoteInpuAllData = 0;
}
//发送本地操作
//发送本地操作
App.roomMgr.SendRoomSingelPlayerInput(UMAME.instance.Frame, DoLocalPressedKeys());
return bHadNetData;
}
//单人模式
//单人模式
else
{
DoLocalPressedKeys();
@ -135,7 +136,7 @@ public class UniKeyboard : MonoBehaviour, IKeyboard
#endif
CurrLocalInpuAllData = tempLocalInputAllData;
//写入replay
//写入replay
UMAME.instance.mReplayWriter.NextFramebyFrameIdx((int)UMAME.instance.mUniVideoPlayer.mFrame, CurrLocalInpuAllData);
CheckPlayerSlotChanged();
@ -146,16 +147,16 @@ public class UniKeyboard : MonoBehaviour, IKeyboard
void CheckPlayerSlotChanged()
{
if (!mUniKeyboard.ControllerMapper.Controller0.ConnectSlot.HasValue && mUniKeyboard.ControllerMapper.Controller0.AnyButtonDown())
if (!mUniKeyboard.ControllerMapper.Controller0.ConnectSlot.HasValue && mUniKeyboard.ControllerMapper.Controller0.AnyButtonDown())
Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 0);
if (!mUniKeyboard.ControllerMapper.Controller1.ConnectSlot.HasValue && mUniKeyboard.ControllerMapper.Controller1.AnyButtonDown())
Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 1);
if (!mUniKeyboard.ControllerMapper.Controller2.ConnectSlot.HasValue && mUniKeyboard.ControllerMapper.Controller2.AnyButtonDown())
Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 2);
if (!mUniKeyboard.ControllerMapper.Controller3.ConnectSlot.HasValue && mUniKeyboard.ControllerMapper.Controller3.AnyButtonDown())
if (!mUniKeyboard.ControllerMapper.Controller1.ConnectSlot.HasValue && mUniKeyboard.ControllerMapper.Controller1.AnyButtonDown())
Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 1);
if (!mUniKeyboard.ControllerMapper.Controller2.ConnectSlot.HasValue && mUniKeyboard.ControllerMapper.Controller2.AnyButtonDown())
Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 2);
if (!mUniKeyboard.ControllerMapper.Controller3.ConnectSlot.HasValue && mUniKeyboard.ControllerMapper.Controller3.AnyButtonDown())
Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 3);
}
@ -172,7 +173,7 @@ public class UniKeyboard : MonoBehaviour, IKeyboard
{
int targetFrame = (int)UMAME.instance.mUniVideoPlayer.mFrame;
AxiReplay.ReplayStep stepData;
//有变化
//有变化
if (UMAME.instance.mReplayReader.NextFramebyFrameIdx(targetFrame, out stepData))
{
#if UNITY_EDITOR
@ -265,7 +266,7 @@ public class MameControllerMapper : IControllerSetuper
}
/// <summary>
/// MAME控制器
/// MAME控制器
/// </summary>
public class MameSingleConoller : IController
{
@ -277,15 +278,16 @@ public class MameSingleConoller : IController
tg_UP, tg_DOWN, tg_LEFT, tg_RIGHT,
tg_BTN_A, tg_BTN_B, tg_BTN_C, tg_BTN_D, tg_BTN_E, tg_BTN_F;
public ulong CurrLocalSingleAllInput { get; private set; }
public ulong CurrLocalSingleAllInput { get; private set; }
private MAMEKeyBinding m_keyMapper;
int mControllerIndex;
uint? mConnectSlot;
/// <summary>
/// 指示该手柄连接的手柄插槽
/// <para><c>这个值代表了该手柄在实际游戏中控制的Player</c></para>
/// <value>[0,3] 例外:为空代表未连接</value>
/// 指示该手柄连接的手柄插槽
/// <para><c>这个值代表了该手柄在实际游戏中控制的Player</c></para>
/// <value>[0,3] 例外:为空代表未连接</value>
/// </summary>
public uint? ConnectSlot
{
@ -294,26 +296,29 @@ public class MameSingleConoller : IController
}
/// <summary>
/// 控制器编号
/// <para><c>此编号并非对应游戏中的player1,player2,player3,player4,仅仅作为本地4个手柄的实例</c></para>
/// 控制器编号
/// <para><c>此编号并非对应游戏中的player1,player2,player3,player4,仅仅作为本地4个手柄的实例</c></para>
/// <value>[0,3]</value>
/// </summary>
public int ControllerIndex
{
get { return mControllerIndex; }
set { mControllerIndex = value;
//this.LoadControlKeyForConfig();
//走统一配置
set
{
mControllerIndex = value;
//this.LoadControlKeyForConfig();
//走统一配置
}
}
public MameSingleConoller(int controllerIndex)
{
ControllerIndex = controllerIndex;
m_keyMapper = App.settings.KeyMapper.GetBinder<MAMEKeyBinding>(UMAME.instance.Platform);
}
public bool AnyButtonDown()
{
return App.input.mame.HadAnyKeyDown(ControllerIndex);
return m_keyMapper.AnyKeyDown(ControllerIndex);
//if (Input.GetKeyDown(INSERT_COIN)) return true;
//if (Input.GetKeyDown(GAMESTART)) return true;
//if (Input.GetKeyDown(UP)) return true;
@ -334,19 +339,19 @@ public class MameSingleConoller : IController
return 0;
CurrLocalSingleAllInput = 0;
var keys = App.input.mame.controllers[ControllerIndex];
if (keys.GetKey((ulong)UMAMEKSingleKey.INSERT_COIN)) CurrLocalSingleAllInput |= (ulong)tg_INSERT_COIN;
if (keys.GetKey((ulong)UMAMEKSingleKey.GAMESTART)) CurrLocalSingleAllInput |= (ulong)tg_GAMESTART;
if (keys.GetKey((ulong)UMAMEKSingleKey.UP)) CurrLocalSingleAllInput |= (ulong)tg_UP;
if (keys.GetKey((ulong)UMAMEKSingleKey.DOWN)) CurrLocalSingleAllInput |= (ulong)tg_DOWN;
if (keys.GetKey((ulong)UMAMEKSingleKey.LEFT)) CurrLocalSingleAllInput |= (ulong)tg_LEFT;
if (keys.GetKey((ulong)UMAMEKSingleKey.RIGHT)) CurrLocalSingleAllInput |= (ulong)tg_RIGHT;
if (keys.GetKey((ulong)UMAMEKSingleKey.BTN_A)) CurrLocalSingleAllInput |= (ulong)tg_BTN_A;
if (keys.GetKey((ulong)UMAMEKSingleKey.BTN_B)) CurrLocalSingleAllInput |= (ulong)tg_BTN_B;
if (keys.GetKey((ulong)UMAMEKSingleKey.BTN_C)) CurrLocalSingleAllInput |= (ulong)tg_BTN_C;
if (keys.GetKey((ulong)UMAMEKSingleKey.BTN_D)) CurrLocalSingleAllInput |= (ulong)tg_BTN_D;
if (keys.GetKey((ulong)UMAMEKSingleKey.BTN_E)) CurrLocalSingleAllInput |= (ulong)tg_BTN_E;
if (keys.GetKey((ulong)UMAMEKSingleKey.BTN_F)) CurrLocalSingleAllInput |= (ulong)tg_BTN_F;
if (m_keyMapper.GetKey(UMAMEKSingleKey.INSERT_COIN, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_INSERT_COIN;
if (m_keyMapper.GetKey(UMAMEKSingleKey.GAMESTART, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_GAMESTART;
if (m_keyMapper.GetKey(UMAMEKSingleKey.UP, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_UP;
if (m_keyMapper.GetKey(UMAMEKSingleKey.DOWN, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_DOWN;
if (m_keyMapper.GetKey(UMAMEKSingleKey.LEFT, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_LEFT;
if (m_keyMapper.GetKey(UMAMEKSingleKey.RIGHT, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_RIGHT;
if (m_keyMapper.GetKey(UMAMEKSingleKey.BTN_A, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_BTN_A;
if (m_keyMapper.GetKey(UMAMEKSingleKey.BTN_B, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_BTN_B;
if (m_keyMapper.GetKey(UMAMEKSingleKey.BTN_C, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_BTN_C;
if (m_keyMapper.GetKey(UMAMEKSingleKey.BTN_D, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_BTN_D;
if (m_keyMapper.GetKey(UMAMEKSingleKey.BTN_E, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_BTN_E;
if (m_keyMapper.GetKey(UMAMEKSingleKey.BTN_F, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_BTN_F;
//if (Input.GetKey(INSERT_COIN)) CurrLocalSingleAllInput |= (ulong)tg_INSERT_COIN;
//if (Input.GetKey(GAMESTART)) CurrLocalSingleAllInput |= (ulong)tg_GAMESTART;
@ -367,10 +372,10 @@ public class MameSingleConoller : IController
}
public static class MameSingleControllSetter
{
//不再需要
//不再需要
//public static void LoadControlKeyForConfig(this MameSingleConoller singlecontrol)
//{
// //TODO 等待支持配置,或统一
// //TODO 等待支持配置,或统一
// switch (singlecontrol.ControllerIndex)
// {
// case 0:
@ -456,7 +461,7 @@ public static class MameSingleControllSetter
singlecontrol.tg_BTN_E = MotionKey.P2_BTN_5;
singlecontrol.tg_BTN_F = MotionKey.P2_BTN_6;
break;
//后续修改后 支持P3 P4
//后续修改后 支持P3 P4
case 2:
singlecontrol.tg_INSERT_COIN = MotionKey.FinalKey;
singlecontrol.tg_GAMESTART = MotionKey.FinalKey;

View File

@ -1,7 +1,9 @@
using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.Common;
using AxibugEmuOnline.Client.Event;
using AxibugEmuOnline.Client.Settings;
using NUnit.Framework.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
@ -98,16 +100,7 @@ namespace AxibugEmuOnline.Client
case 3: targetController = Controller3; break;
default:
throw new System.Exception($"Not Allowed conIndex Range: {conIndex}");
break;
}
//var targetController = conIndex switch
//{
// 0 => Controller0,
// 1 => Controller1,
// 2 => Controller2,
// 3 => Controller3,
// _ => throw new System.Exception($"Not Allowed conIndex Range: {conIndex}")
//};
if (targetController.ConnectSlot.HasValue) return;
@ -121,6 +114,7 @@ namespace AxibugEmuOnline.Client
/// </summary>
public class Controller : IController
{
static Lazy<NesKeyBinding> s_keyBinder = new Lazy<NesKeyBinding>(() => App.settings.KeyMapper.GetBinder<NesKeyBinding>());
/// <summary>
/// 控制器编号
/// <para><c>此编号并非对应游戏中的player1,player2,player3,player4,仅仅作为本地4个手柄的实例</c></para>
@ -135,260 +129,32 @@ namespace AxibugEmuOnline.Client
/// </summary>
public uint? ConnectSlot { get; set; }
//public Button UP { get; }
//public Button DOWN { get; }
//public Button LEFT { get; }
//public Button RIGHT { get; }
//public Button A { get; }
//public Button B { get; }
//public Button SELECT { get; }
//public Button START { get; }
//public Button MIC { get; }
public Controller(int controllerIndex)
{
ControllerIndex = controllerIndex;
//UP = new Button(this, EnumButtonType.UP);
//DOWN = new Button(this, EnumButtonType.DOWN);
//LEFT = new Button(this, EnumButtonType.LEFT);
//RIGHT = new Button(this, EnumButtonType.RIGHT);
//A = new Button(this, EnumButtonType.A);
//B = new Button(this, EnumButtonType.B);
//SELECT = new Button(this, EnumButtonType.SELECT);
//START = new Button(this, EnumButtonType.START);
//MIC = new Button(this, EnumButtonType.MIC);
}
public EnumButtonType GetButtons()
{
EnumButtonType res = 0;
if(App.input.nes.controllers[ControllerIndex].GetKey((ulong)EnumButtonType.UP)) res |= EnumButtonType.UP;
if(App.input.nes.controllers[ControllerIndex].GetKey((ulong)EnumButtonType.DOWN)) res |= EnumButtonType.DOWN;
if(App.input.nes.controllers[ControllerIndex].GetKey((ulong)EnumButtonType.LEFT)) res |= EnumButtonType.LEFT;
if(App.input.nes.controllers[ControllerIndex].GetKey((ulong)EnumButtonType.RIGHT)) res |= EnumButtonType.RIGHT;
if(App.input.nes.controllers[ControllerIndex].GetKey((ulong)EnumButtonType.A)) res |= EnumButtonType.A;
if(App.input.nes.controllers[ControllerIndex].GetKey((ulong)EnumButtonType.B)) res |= EnumButtonType.B;
if(App.input.nes.controllers[ControllerIndex].GetKey((ulong)EnumButtonType.SELECT)) res |= EnumButtonType.SELECT;
if(App.input.nes.controllers[ControllerIndex].GetKey((ulong)EnumButtonType.START)) res |= EnumButtonType.START;
if(App.input.nes.controllers[ControllerIndex].GetKey((ulong)EnumButtonType.MIC)) res |= EnumButtonType.MIC;
//res |= UP.SampleKey();
//res |= DOWN.SampleKey();
//res |= LEFT.SampleKey();
//res |= RIGHT.SampleKey();
//res |= A.SampleKey();
//res |= B.SampleKey();
//res |= SELECT.SampleKey();
//res |= START.SampleKey();
//res |= MIC.SampleKey();
if (s_keyBinder.Value.GetKey(EnumButtonType.UP, ControllerIndex)) res |= EnumButtonType.UP;
if (s_keyBinder.Value.GetKey(EnumButtonType.DOWN, ControllerIndex)) res |= EnumButtonType.DOWN;
if (s_keyBinder.Value.GetKey(EnumButtonType.LEFT, ControllerIndex)) res |= EnumButtonType.LEFT;
if (s_keyBinder.Value.GetKey(EnumButtonType.RIGHT, ControllerIndex)) res |= EnumButtonType.RIGHT;
if (s_keyBinder.Value.GetKey(EnumButtonType.A, ControllerIndex)) res |= EnumButtonType.A;
if (s_keyBinder.Value.GetKey(EnumButtonType.B, ControllerIndex)) res |= EnumButtonType.B;
if (s_keyBinder.Value.GetKey(EnumButtonType.SELECT, ControllerIndex)) res |= EnumButtonType.SELECT;
if (s_keyBinder.Value.GetKey(EnumButtonType.START, ControllerIndex)) res |= EnumButtonType.START;
if (s_keyBinder.Value.GetKey(EnumButtonType.MIC, ControllerIndex)) res |= EnumButtonType.MIC;
return res;
}
public bool AnyButtonDown()
{
return App.input.nes.controllers[ControllerIndex].HadAnyKeyDown();
//return
// UP.IsDown ||
// DOWN.IsDown ||
// LEFT.IsDown ||
// RIGHT.IsDown ||
// A.IsDown ||
// B.IsDown ||
// SELECT.IsDown ||
// START.IsDown ||
// MIC.IsDown;
return s_keyBinder.Value.AnyKeyDown(ControllerIndex);
}
//public static KeyListener GetKey(int controllerInput, EnumButtonType nesConBtnType)
//{
// string configKey = $"NES_{controllerInput}_{nesConBtnType}";
// //PSV平台固定键值
// if (UnityEngine.Application.platform == RuntimePlatform.PSP2)
// {
// return KeyListener.GetPSVitaKey(controllerInput, nesConBtnType);
// }
// if (PlayerPrefs.HasKey(configKey))
// {
// return new KeyListener(PlayerPrefs.GetString(configKey));
// }
// else
// {
// var defaultKeyCode = KeyListener.GetDefaultKey(controllerInput, nesConBtnType);
// PlayerPrefs.SetString(configKey, defaultKeyCode.ToString());
// return defaultKeyCode;
// }
//}
}
///// <summary>
///// NES控制器按键类
///// </summary>
//public class Button
//{
// /// <summary> 所属控制器 </summary>
// readonly Controller m_hostController;
// /// <summary> 按键 </summary>
// readonly EnumButtonType m_buttonType;
// /// <summary> 按键监听器 </summary>
// KeyListener m_keyListener;
// /// <summary> 指示按钮是否正在按下状态 </summary>
// public bool IsPressing => m_keyListener.IsPressing();
// /// <summary> 指示按钮是否被按下 </summary>
// public bool IsDown => m_keyListener.IsDown();
// public Button(Controller controller, EnumButtonType buttonType)
// {
// m_hostController = controller;
// m_buttonType = buttonType;
// CreateListener();
// }
// /// <summary>
// /// 采集按钮按下状态
// /// </summary>
// /// <returns></returns>
// public EnumButtonType SampleKey()
// {
// return IsPressing ? m_buttonType : 0;
// }
// private void CreateListener()
// {
// m_keyListener = Controller.GetKey(m_hostController.ControllerIndex, m_buttonType);
// }
//}
//low C# readonly
//public readonly struct KeyListener
//public struct KeyListener
//{
// private readonly KeyCode m_key;
// public KeyListener(KeyCode key)
// {
// m_key = key;
// }
// /// <summary> 从配置字符串构建 </summary>
// public KeyListener(string confStr)
// {
// m_key = KeyCode.None;
// int result;
// if (int.TryParse(confStr, out result))
// m_key = (KeyCode)result;
// }
// public bool IsPressing()
// {
// return Input.GetKey(m_key);
// }
// public bool IsDown()
// {
// return Input.GetKeyDown(m_key);
// }
// public override string ToString()
// {
// return ((int)(m_key)).ToString();
// }
// public static KeyListener GetDefaultKey(int controllerIndex, EnumButtonType nesConBtnType)
// {
// switch (controllerIndex)
// {
// case 0:
// switch (nesConBtnType)
// {
// case EnumButtonType.LEFT:
// return new KeyListener(KeyCode.A);
// case EnumButtonType.RIGHT:
// return new KeyListener(KeyCode.D);
// case EnumButtonType.UP:
// return new KeyListener(KeyCode.W);
// case EnumButtonType.DOWN:
// return new KeyListener(KeyCode.S);
// case EnumButtonType.START:
// return new KeyListener(KeyCode.B);
// case EnumButtonType.SELECT:
// return new KeyListener(KeyCode.V);
// case EnumButtonType.A:
// return new KeyListener(KeyCode.K);
// case EnumButtonType.B:
// return new KeyListener(KeyCode.J);
// case EnumButtonType.MIC:
// return new KeyListener(KeyCode.M);
// }
// break;
// case 1:
// switch (nesConBtnType)
// {
// case EnumButtonType.LEFT:
// return new KeyListener(KeyCode.Delete);
// case EnumButtonType.RIGHT:
// return new KeyListener(KeyCode.PageDown);
// case EnumButtonType.UP:
// return new KeyListener(KeyCode.Home);
// case EnumButtonType.DOWN:
// return new KeyListener(KeyCode.End);
// case EnumButtonType.START:
// return new KeyListener(KeyCode.PageUp);
// case EnumButtonType.SELECT:
// return new KeyListener(KeyCode.Insert);
// case EnumButtonType.A:
// return new KeyListener(KeyCode.Keypad5);
// case EnumButtonType.B:
// return new KeyListener(KeyCode.Keypad4);
// case EnumButtonType.MIC:
// return new KeyListener(KeyCode.KeypadPeriod);
// }
// break;
// }
// return default(KeyListener);
// }
// //public static KeyListener GetPSVitaKey(int controllerIndex, EnumButtonType nesConBtnType)
// //{
// // switch (controllerIndex)
// // {
// // case 0:
// // switch (nesConBtnType)
// // {
// // case EnumButtonType.LEFT:
// // return new KeyListener(PSVitaKey.Left);
// // case EnumButtonType.RIGHT:
// // return new KeyListener(PSVitaKey.Right);
// // case EnumButtonType.UP:
// // return new KeyListener(PSVitaKey.Up);
// // case EnumButtonType.DOWN:
// // return new KeyListener(PSVitaKey.Down);
// // case EnumButtonType.START:
// // return new KeyListener(PSVitaKey.Start);
// // case EnumButtonType.SELECT:
// // return new KeyListener(PSVitaKey.Select);
// // case EnumButtonType.A:
// // return new KeyListener(PSVitaKey.Circle);
// // case EnumButtonType.B:
// // return new KeyListener(PSVitaKey.Cross);
// // case EnumButtonType.MIC:
// // return new KeyListener(PSVitaKey.Block);
// // }
// // break;
// // }
// // return default(KeyListener);
// //}
//}
}
}

View File

@ -1,3 +1,5 @@
using AxibugEmuOnline.Client.Settings;
namespace AxibugEmuOnline.Client
{
public static class EventInvoker

View File

@ -1,13 +0,0 @@
using AxibugEmuOnline.Client.Manager;
using System.Collections.Generic;
namespace AxibugEmuOnline.Client
{
public abstract class CommandChanger : IKeyMapperChanger
{
public string Name => GetType().Name;
public abstract EnumCommand[] GetConfig();
public abstract SingleKeysSetting GetKeySetting();
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: c29cb72b155d20a48a3a47a7a05160bd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,35 +0,0 @@
using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.Manager;
namespace AxibugEmuOnline.Client
{
public class GamingChanger : CommandChanger
{
public override EnumCommand[] GetConfig()
{
return App.input.gaming.controllers[0].GetAllCmd<EnumCommand>();
}
public override SingleKeysSetting GetKeySetting()
{
return App.input.gaming.controllers[0];
}
//Dictionary<KeyCode, EnumCommand> m_uiKeyMapper = new Dictionary<KeyCode, EnumCommand>();
//public GamingChanger()
//{
// m_uiKeyMapper[KeyCode.Escape] = EnumCommand.OptionMenu;
// if (Application.platform == RuntimePlatform.PSP2)
// {
// m_uiKeyMapper[Common.PSVitaKey.L] = EnumCommand.OptionMenu;
// m_uiKeyMapper[Common.PSVitaKey.R] = EnumCommand.OptionMenu;
// }
// //PC XBOX
// m_uiKeyMapper[Common.PC_XBOXKEY.Y] = EnumCommand.OptionMenu;
//}
//public override object GetConfig() => m_uiKeyMapper;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: c8339ffab20bfea4cbc7d3aa440c3fdb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,64 +0,0 @@
using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.Manager;
namespace AxibugEmuOnline.Client
{
public class NormalChanger : CommandChanger
{
public override EnumCommand[] GetConfig()
{
return App.input.xmb.controllers[0].GetAllCmd<EnumCommand>();
}
public override SingleKeysSetting GetKeySetting()
{
return App.input.xmb.controllers[0];
}
//Dictionary<KeyCode, EnumCommand> m_uiKeyMapper = new Dictionary<KeyCode, EnumCommand>();
//public NormalChanger()
//{
// m_uiKeyMapper[KeyCode.A] = EnumCommand.SelectItemLeft;
// m_uiKeyMapper[KeyCode.D] = EnumCommand.SelectItemRight;
// m_uiKeyMapper[KeyCode.W] = EnumCommand.SelectItemUp;
// m_uiKeyMapper[KeyCode.S] = EnumCommand.SelectItemDown;
// m_uiKeyMapper[KeyCode.K] = EnumCommand.Enter;
// m_uiKeyMapper[KeyCode.L] = EnumCommand.Back;
// m_uiKeyMapper[KeyCode.I] = EnumCommand.OptionMenu;
// m_uiKeyMapper[KeyCode.LeftArrow] = EnumCommand.SelectItemLeft;
// m_uiKeyMapper[KeyCode.RightArrow] = EnumCommand.SelectItemRight;
// m_uiKeyMapper[KeyCode.UpArrow] = EnumCommand.SelectItemUp;
// m_uiKeyMapper[KeyCode.DownArrow] = EnumCommand.SelectItemDown;
// m_uiKeyMapper[KeyCode.Return] = EnumCommand.Enter;
// m_uiKeyMapper[KeyCode.Escape] = EnumCommand.Back;
// m_uiKeyMapper[KeyCode.RightShift] = EnumCommand.OptionMenu;
// m_uiKeyMapper[KeyCode.LeftShift] = EnumCommand.OptionMenu;
// if (Application.platform == RuntimePlatform.PSP2)
// {
// m_uiKeyMapper[Common.PSVitaKey.Left] = EnumCommand.SelectItemLeft;
// m_uiKeyMapper[Common.PSVitaKey.Right] = EnumCommand.SelectItemRight;
// m_uiKeyMapper[Common.PSVitaKey.Up] = EnumCommand.SelectItemUp;
// m_uiKeyMapper[Common.PSVitaKey.Down] = EnumCommand.SelectItemDown;
// m_uiKeyMapper[Common.PSVitaKey.Circle] = EnumCommand.Enter;
// m_uiKeyMapper[Common.PSVitaKey.Cross] = EnumCommand.Back;
// m_uiKeyMapper[Common.PSVitaKey.Triangle] = EnumCommand.OptionMenu;
// }
// //PC XBOX
// //m_uiKeyMapper[Common.PC_XBOXKEY.Left] = EnumCommand.SelectItemLeft;
// //m_uiKeyMapper[Common.PSVitaKey.Right] = EnumCommand.SelectItemRight;
// //m_uiKeyMapper[Common.PSVitaKey.Up] = EnumCommand.SelectItemUp;
// //m_uiKeyMapper[Common.PSVitaKey.Down] = EnumCommand.SelectItemDown;
// m_uiKeyMapper[Common.PC_XBOXKEY.MenuBtn] = EnumCommand.Enter;
// m_uiKeyMapper[Common.PC_XBOXKEY.ViewBtn] = EnumCommand.Back;
// m_uiKeyMapper[Common.PC_XBOXKEY.Y] = EnumCommand.OptionMenu;
//}
//public override object GetConfig() => m_uiKeyMapper;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: b8790f215d873d044aa8d00bacdee237
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -78,7 +78,7 @@ namespace AxibugEmuOnline.Client.Manager
LaunchUI.Instance.HideMainMenu();
InGameUI.Instance.Show(romFile, m_emuCore);
CommandDispatcher.Instance.Current = CommandDispatcher.Instance.Gaming;
CommandDispatcher.Instance.Mode = CommandListener.ScheduleType.Gaming;
m_controllerSetuper = m_emuCore.GetControllerSetuper();

View File

@ -1,4 +1,6 @@
namespace AxibugEmuOnline.Client
using AxibugEmuOnline.Client.Settings;
namespace AxibugEmuOnline.Client
{
public class AppSettings
{
@ -7,13 +9,16 @@
/// <summary> 滤镜设置 </summary>
public FilterManager Filter { get; private set; }
/// <summary> 画面比例设置 </summary>
public ScreenScaler ScreenScaler { get; private set; }
public ScreenScaler ScreenScaler { get; private set; }
/// <summary> 键位设置 </summary>
public KeyMapperSetting KeyMapper { get; private set; }
public AppSettings()
{
BgColor = new BgColorSettings();
Filter = new FilterManager();
ScreenScaler = new ScreenScaler();
KeyMapper = new KeyMapperSetting();
}
}
}

View File

@ -1,7 +1,7 @@
using System.Collections.Generic;
using UnityEngine;
namespace AxibugEmuOnline.Client
namespace AxibugEmuOnline.Client.Settings
{
/// <summary> 颜色设置 </summary>
public class BgColorSettings

View File

@ -8,7 +8,7 @@ using UnityEngine;
using UnityEngine.UI;
using static AxibugEmuOnline.Client.FilterEffect;
namespace AxibugEmuOnline.Client
namespace AxibugEmuOnline.Client.Settings
{
public class FilterManager
{

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 04e926e140ae5bc4fa46bd64067261cf
guid: 7c4a24e114240814a8587e2f90a2f6f0
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@ -0,0 +1,162 @@
using AxibugEmuOnline.Client.InputDevices;
using AxibugProtobuf;
using System;
namespace AxibugEmuOnline.Client.Settings
{
[Flags]
public enum EssgeeSingleKey : ushort
{
NONE = 0,
UP = 1,
DOWN = 1 << 1,
LEFT = 1 << 2,
RIGHT = 1 << 3,
BTN_1 = 1 << 4,
BTN_2 = 1 << 5,
BTN_3 = 1 << 6,
BTN_4 = 1 << 7,
OPTION_1 = 1 << 8,
OPTION_2 = 1 << 9,
}
public abstract class EssgeeKeyBinding : EmuCoreControllerKeyBinding<EssgeeSingleKey>
{
protected override void OnRegistDevices(InputDevice_D device, BindingPage binding)
{
if (device is Keyboard_D keyboard)
{
switch (binding.ControllerIndex)
{
case 0:
binding.SetBinding(EssgeeSingleKey.OPTION_1, keyboard.Return, 0);
binding.SetBinding(EssgeeSingleKey.OPTION_2, keyboard.RightShift, 0);
binding.SetBinding(EssgeeSingleKey.UP, keyboard.W, 0);
binding.SetBinding(EssgeeSingleKey.DOWN, keyboard.S, 0);
binding.SetBinding(EssgeeSingleKey.LEFT, keyboard.A, 0);
binding.SetBinding(EssgeeSingleKey.RIGHT, keyboard.D, 0);
binding.SetBinding(EssgeeSingleKey.BTN_1, keyboard.J, 0);
binding.SetBinding(EssgeeSingleKey.BTN_2, keyboard.K, 0);
binding.SetBinding(EssgeeSingleKey.BTN_3, keyboard.U, 0);
binding.SetBinding(EssgeeSingleKey.BTN_4, keyboard.I, 0);
break;
case 1:
binding.SetBinding(EssgeeSingleKey.OPTION_1, keyboard.Keypad0, 0);
binding.SetBinding(EssgeeSingleKey.OPTION_2, keyboard.Delete, 0);
binding.SetBinding(EssgeeSingleKey.UP, keyboard.UpArrow, 0);
binding.SetBinding(EssgeeSingleKey.DOWN, keyboard.DownArrow, 0);
binding.SetBinding(EssgeeSingleKey.LEFT, keyboard.LeftArrow, 0);
binding.SetBinding(EssgeeSingleKey.RIGHT, keyboard.RightArrow, 0);
binding.SetBinding(EssgeeSingleKey.BTN_1, keyboard.Keypad1, 0);
binding.SetBinding(EssgeeSingleKey.BTN_2, keyboard.Keypad2, 0);
binding.SetBinding(EssgeeSingleKey.BTN_3, keyboard.Keypad3, 0);
binding.SetBinding(EssgeeSingleKey.BTN_4, keyboard.Keypad4, 0);
break;
}
}
else if (device is PSVController_D psvCon && binding.ControllerIndex == 0)
{
binding.SetBinding(EssgeeSingleKey.OPTION_1, psvCon.Start, 0);
binding.SetBinding(EssgeeSingleKey.OPTION_2, psvCon.Select, 0);
binding.SetBinding(EssgeeSingleKey.UP, psvCon.Up, 0);
binding.SetBinding(EssgeeSingleKey.DOWN, psvCon.Down, 0);
binding.SetBinding(EssgeeSingleKey.LEFT, psvCon.Left, 0);
binding.SetBinding(EssgeeSingleKey.RIGHT, psvCon.Right, 0);
binding.SetBinding(EssgeeSingleKey.BTN_1, psvCon.Cross, 0);
binding.SetBinding(EssgeeSingleKey.BTN_2, psvCon.Circle, 0);
binding.SetBinding(EssgeeSingleKey.BTN_3, psvCon.Square, 0);
binding.SetBinding(EssgeeSingleKey.BTN_4, psvCon.Triangle, 0);
//PSV 摇杆
binding.SetBinding(EssgeeSingleKey.UP, psvCon.LeftStick.UP, 1);
binding.SetBinding(EssgeeSingleKey.DOWN, psvCon.LeftStick.Down, 1);
binding.SetBinding(EssgeeSingleKey.LEFT, psvCon.LeftStick.Left, 1);
binding.SetBinding(EssgeeSingleKey.RIGHT, psvCon.LeftStick.Right, 1);
}
}
}
public class MasterSystemKeyBinding : EssgeeKeyBinding
{
public override RomPlatformType Platform => RomPlatformType.MasterSystem;
public override int ControllerCount => 2;
}
public class SG1000KeyBinding : EssgeeKeyBinding
{
public override RomPlatformType Platform => RomPlatformType.Sg1000;
public override int ControllerCount => 2;
}
public class ColecoVisionKeyBinding : EssgeeKeyBinding
{
public override RomPlatformType Platform => RomPlatformType.ColecoVision;
public override int ControllerCount => 2;
}
public class GameBoyColorKeyBinding : EssgeeKeyBinding
{
public override RomPlatformType Platform => RomPlatformType.GameBoyColor;
public override int ControllerCount => 1;
protected override void OnRegistDevices(InputDevice_D device, BindingPage binding)
{
if (device is Keyboard_D keyboard)
{
switch (binding.ControllerIndex)
{
case 0:
binding.SetBinding(EssgeeSingleKey.OPTION_1, keyboard.Return, 0);
binding.SetBinding(EssgeeSingleKey.OPTION_2, keyboard.RightShift, 0);
binding.SetBinding(EssgeeSingleKey.UP, keyboard.W, 0);
binding.SetBinding(EssgeeSingleKey.DOWN, keyboard.S, 0);
binding.SetBinding(EssgeeSingleKey.LEFT, keyboard.A, 0);
binding.SetBinding(EssgeeSingleKey.RIGHT, keyboard.D, 0);
binding.SetBinding(EssgeeSingleKey.BTN_1, keyboard.J, 0);
binding.SetBinding(EssgeeSingleKey.BTN_2, keyboard.K, 0);
binding.SetBinding(EssgeeSingleKey.BTN_3, keyboard.U, 0);
binding.SetBinding(EssgeeSingleKey.BTN_4, keyboard.I, 0);
break;
}
}
}
}
public class GameBoyKeyBinding : EssgeeKeyBinding
{
public override RomPlatformType Platform => RomPlatformType.GameBoy;
public override int ControllerCount => 1;
protected override void OnRegistDevices(InputDevice_D device, BindingPage binding)
{
if (device is Keyboard_D keyboard)
{
switch (binding.ControllerIndex)
{
case 0:
binding.SetBinding(EssgeeSingleKey.OPTION_1, keyboard.Return, 0);
binding.SetBinding(EssgeeSingleKey.OPTION_2, keyboard.RightShift, 0);
binding.SetBinding(EssgeeSingleKey.UP, keyboard.W, 0);
binding.SetBinding(EssgeeSingleKey.DOWN, keyboard.S, 0);
binding.SetBinding(EssgeeSingleKey.LEFT, keyboard.A, 0);
binding.SetBinding(EssgeeSingleKey.RIGHT, keyboard.D, 0);
binding.SetBinding(EssgeeSingleKey.BTN_1, keyboard.J, 0);
binding.SetBinding(EssgeeSingleKey.BTN_2, keyboard.K, 0);
binding.SetBinding(EssgeeSingleKey.BTN_3, keyboard.U, 0);
binding.SetBinding(EssgeeSingleKey.BTN_4, keyboard.I, 0);
break;
}
}
}
}
public class GameGearKeyBinding : EssgeeKeyBinding
{
public override RomPlatformType Platform => RomPlatformType.GameGear;
public override int ControllerCount => 2;
}
public class SC3000KeyBinding : EssgeeKeyBinding
{
public override RomPlatformType Platform => RomPlatformType.Sc3000;
public override int ControllerCount => 2;
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: f55743cde04853247be4bd9f7681edf4

View File

@ -0,0 +1,346 @@
using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.InputDevices;
using AxibugProtobuf;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace AxibugEmuOnline.Client.Settings
{
/// <summary>
/// 管理键位映射设置
/// </summary>
public class KeyMapperSetting
{
Dictionary<RomPlatformType, EmuCoreControllerKeyBinding> m_binders = new Dictionary<RomPlatformType, EmuCoreControllerKeyBinding>();
Dictionary<Type, EmuCoreControllerKeyBinding> m_bindersByType = new Dictionary<Type, EmuCoreControllerKeyBinding>();
public KeyMapperSetting()
{
var baseType = typeof(EmuCoreControllerKeyBinding);
foreach (var t in baseType.Assembly.ExportedTypes)
{
if (t.IsAbstract) continue;
if (!baseType.IsAssignableFrom(t)) continue;
var binderIns = Activator.CreateInstance(t) as EmuCoreControllerKeyBinding;
m_binders.Add(binderIns.Platform, binderIns);
m_bindersByType.Add(binderIns.GetType(), binderIns);
}
}
public T GetBinder<T>() where T : EmuCoreControllerKeyBinding
{
m_bindersByType.TryGetValue(typeof(T), out var binder);
return binder as T;
}
public T GetBinder<T>(RomPlatformType romType) where T : EmuCoreControllerKeyBinding
{
m_binders.TryGetValue(romType, out var binder);
return binder as T;
}
}
/// <summary>
/// 此类为内部继承, 请勿继承此类
/// </summary>
public abstract class EmuCoreControllerKeyBinding
{
/// <summary> 所属核心 </summary>
public abstract RomPlatformType Platform { get; }
/// <summary> 控制器数量 </summary>
public abstract int ControllerCount { get; }
}
/// <summary>
/// 模拟器核心控制器键位绑定器
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class EmuCoreControllerKeyBinding<T> : EmuCoreControllerKeyBinding
where T : Enum
{
List<BindingPage> m_bindingPages = new List<BindingPage>();
public EmuCoreControllerKeyBinding()
{
for (int i = 0; i < ControllerCount; i++)
{
m_bindingPages.Add(new BindingPage(i, this));
}
var keyboard = App.input.GetDevice<Keyboard_D>();
if (keyboard != null)
{
foreach (var binding in m_bindingPages)
{
binding.RegistInputDevice(keyboard);
}
}
var psvController = App.input.GetDevice<PSVController_D>();
if (psvController != null)
{
foreach (var binding in m_bindingPages)
{
binding.RegistInputDevice(psvController);
}
}
App.input.OnDeviceLost += InputDevicesMgr_OnDeviceLost;
App.input.OnDeviceConnected += InputDevicesMgr_OnDeviceConnected;
}
private void InputDevicesMgr_OnDeviceConnected(InputDevice_D connectDevice)
{
if (connectDevice is Keyboard_D)
{
foreach (var binding in m_bindingPages)
{
binding.RegistInputDevice(connectDevice);
}
}
}
private void InputDevicesMgr_OnDeviceLost(InputDevice_D lostDevice)
{
foreach (var binding in m_bindingPages)
{
binding.UnregistInputDevice(lostDevice);
}
if (lostDevice is Keyboard_D) //键盘丢失,立即查找还存在的键盘并建立连接
{
var anotherKeyboard = App.input.GetDevice<Keyboard_D>();
if (anotherKeyboard != null)
{
foreach (var binding in m_bindingPages)
{
binding.UnregistInputDevice(lostDevice);
}
}
}
}
IEnumerable<T> DefineKeys()
{
return Enum.GetValues(typeof(T)).Cast<T>();
}
internal void RaiseDeviceRegist(InputDevice_D device, BindingPage binding)
{
OnRegistDevices(device, binding);
}
protected abstract void OnRegistDevices(InputDevice_D device, BindingPage binding);
public bool Start(T emuControl, int controllerIndex)
{
var binding = m_bindingPages[controllerIndex];
foreach (var key in binding.GetBinding(emuControl))
{
if (key.Start) return true;
}
return false;
}
public bool Release(T emuControl, int controllerIndex)
{
var binding = m_bindingPages[controllerIndex];
foreach (var key in binding.GetBinding(emuControl))
{
if (key.Release) return true;
}
return false;
}
/// <summary>
/// 获取指定控件是否处于按下状态
/// <para>如果绑定了多个物理按键,则只有这多个物理按键全部不处于按下状态时,才会返回false</para>
/// </summary>
/// <param name="emuControl"></param>
/// <param name="controllerIndex"></param>
/// <returns></returns>
public bool GetKey(T emuControl, int controllerIndex)
{
var binding = m_bindingPages[controllerIndex];
foreach (var key in binding.GetBinding(emuControl))
{
if (key.Performing) return true;
}
return false;
}
/// <summary>
/// 获取调用帧是否有任意按键触发了按下操作
/// </summary>
/// <param name="controllerIndex"></param>
/// <returns></returns>
public bool AnyKeyDown(int controllerIndex)
{
var binding = m_bindingPages[controllerIndex];
return binding.AnyKeyDown();
}
/// <summary>
/// 获取指定控件的向量值
/// <para>通常用于摇杆类型的控件</para>
/// <para>如果同时绑定了多个物理输入设备,只会返回其中一个物理设备的向量值</para>
/// </summary>
/// <param name="emuControl">模拟器平台的具体键枚举</param>
/// <param name="controllerIndex">模拟器平台的控制器序号</param>
/// <returns></returns>
public Vector2 GetVector2(T emuControl, int controllerIndex)
{
var binding = m_bindingPages[controllerIndex];
foreach (var control in binding.GetBinding(emuControl))
{
if (!control.Performing) continue;
return control.GetVector2();
}
return default(Vector2);
}
/// <summary>
/// 获取指定控件的浮点值,取值范围为[0f,1f]
/// <para>通常用于线性类按键,例如PS手柄的扳机键</para>
/// <para>普通的按键也能读取这个值,但返回值只会有0f和1f两种值</para>
/// <para>如果同时绑定了多个物理控件,则会从所有处于按下状态的物理控件中取平均值</para>
/// </summary>
/// <param name="emuControl">模拟器平台的具体键枚举</param>
/// <param name="controllerIndex">模拟器平台的控制器序号</param>
/// <returns></returns>
public float GetFloat(T emuControl, int controllerIndex)
{
var totalFloat = 0f;
var totalControl = 0;
var binding = m_bindingPages[controllerIndex];
foreach (var key in binding.GetBinding(emuControl))
{
if (!key.Performing) continue;
totalControl++;
totalFloat += key.GetFlaot();
}
if (totalControl == 0) return default(float);
else return totalFloat / totalControl;
}
public class MapSetting : Dictionary<T, List<InputControl_C>> { }
public class BindingPage
{
Dictionary<Type, InputDevice_D> m_registedDevices = new Dictionary<Type, InputDevice_D>();
Dictionary<InputDevice_D, MapSetting> m_mapSetting = new Dictionary<InputDevice_D, MapSetting>();
public int ControllerIndex { get; }
public EmuCoreControllerKeyBinding<T> Host { get; }
internal BindingPage(int controllerIndex, EmuCoreControllerKeyBinding<T> host)
{
ControllerIndex = controllerIndex;
Host = host;
}
internal bool IsRegisted<DEVICE>() where DEVICE : InputDevice_D
{
var type = typeof(T);
return IsRegisted(type);
}
internal bool IsRegisted(Type deviceType)
{
return m_registedDevices.ContainsKey(deviceType);
}
internal void RegistInputDevice(InputDevice_D device)
{
var type = device.GetType();
if (IsRegisted(type)) return;
m_registedDevices.Add(type, device);
m_mapSetting[device] = new MapSetting();
Host.RaiseDeviceRegist(device, this);
}
internal void UnregistInputDevice(InputDevice_D device)
{
var type = device.GetType();
if (!IsRegisted(type)) return;
m_registedDevices.Remove(type);
m_mapSetting.Remove(device);
}
public void SetBinding(T emuBtn, InputControl_C key, int settingSlot)
{
var device = key.Device;
m_registedDevices.TryGetValue(device.GetType(), out var inputDevice);
Debug.Assert(inputDevice == device);
var setting = m_mapSetting[inputDevice];
if (!setting.TryGetValue(emuBtn, out var settingList))
{
settingList = new List<InputControl_C>();
setting[emuBtn] = settingList;
}
int needFixCount = settingSlot - settingList.Count + 1;
if (needFixCount > 0) for (int i = 0; i < needFixCount; i++) settingList.Add(null);
settingList[settingSlot] = key;
}
public InputControl_C GetBinding(T emuBtn, InputDevice_D device, int settingSlot)
{
m_mapSetting.TryGetValue(device, out var mapSetting);
if (mapSetting == null) return null;
mapSetting.TryGetValue(emuBtn, out var settingList);
if (settingList == null || settingSlot >= settingList.Count) return null;
return settingList[settingSlot];
}
private List<InputControl_C> m_caches = new List<InputControl_C>();
public IEnumerable<InputControl_C> GetBinding(T emuBtn)
{
m_caches.Clear();
foreach (var mapSettings in m_mapSetting.Values)
{
mapSettings.TryGetValue(emuBtn, out var bindControls);
if (bindControls != null)
{
m_caches.AddRange(bindControls);
}
}
return m_caches;
}
public bool AnyKeyDown()
{
foreach (var mapSettings in m_mapSetting.Values)
{
foreach (var keys in mapSettings.Values)
{
foreach (var key in keys)
{
if (key.Start) return true;
}
}
}
return false;
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 59504da02f065ec4e8e6905ab357badc

View File

@ -0,0 +1,89 @@
using AxibugEmuOnline.Client.InputDevices;
using AxibugProtobuf;
namespace AxibugEmuOnline.Client.Settings
{
public enum UMAMEKSingleKey
{
INSERT_COIN,
GAMESTART,
UP,
DOWN,
LEFT,
RIGHT,
BTN_A,
BTN_B,
BTN_C,
BTN_D,
BTN_E,
BTN_F
}
public abstract class MAMEKeyBinding : EmuCoreControllerKeyBinding<UMAMEKSingleKey>
{
public override int ControllerCount => 4;
protected override void OnRegistDevices(InputDevice_D device, BindingPage binding)
{
if (device is Keyboard_D keyboard)
{
switch (binding.ControllerIndex)
{
case 0:
binding.SetBinding(UMAMEKSingleKey.INSERT_COIN, keyboard.Q, 0);
binding.SetBinding(UMAMEKSingleKey.GAMESTART, keyboard.E, 0);
binding.SetBinding(UMAMEKSingleKey.UP, keyboard.W, 0);
binding.SetBinding(UMAMEKSingleKey.DOWN, keyboard.S, 0);
binding.SetBinding(UMAMEKSingleKey.LEFT, keyboard.A, 0);
binding.SetBinding(UMAMEKSingleKey.RIGHT, keyboard.D, 0);
binding.SetBinding(UMAMEKSingleKey.BTN_A, keyboard.J, 0);
binding.SetBinding(UMAMEKSingleKey.BTN_B, keyboard.K, 0);
binding.SetBinding(UMAMEKSingleKey.BTN_C, keyboard.L, 0);
binding.SetBinding(UMAMEKSingleKey.BTN_D, keyboard.U, 0);
binding.SetBinding(UMAMEKSingleKey.BTN_E, keyboard.I, 0);
binding.SetBinding(UMAMEKSingleKey.BTN_F, keyboard.O, 0);
break;
case 1:
binding.SetBinding(UMAMEKSingleKey.INSERT_COIN, keyboard.Delete, 0);
binding.SetBinding(UMAMEKSingleKey.GAMESTART, keyboard.PageDown, 0);
binding.SetBinding(UMAMEKSingleKey.UP, keyboard.UpArrow, 0);
binding.SetBinding(UMAMEKSingleKey.DOWN, keyboard.DownArrow, 0);
binding.SetBinding(UMAMEKSingleKey.LEFT, keyboard.LeftArrow, 0);
binding.SetBinding(UMAMEKSingleKey.RIGHT, keyboard.RightArrow, 0);
binding.SetBinding(UMAMEKSingleKey.BTN_A, keyboard.Keypad1, 0);
binding.SetBinding(UMAMEKSingleKey.BTN_B, keyboard.Keypad2, 0);
binding.SetBinding(UMAMEKSingleKey.BTN_C, keyboard.Keypad3, 0);
binding.SetBinding(UMAMEKSingleKey.BTN_D, keyboard.Keypad4, 0);
binding.SetBinding(UMAMEKSingleKey.BTN_E, keyboard.Keypad5, 0);
binding.SetBinding(UMAMEKSingleKey.BTN_F, keyboard.Keypad6, 0);
break;
}
}
}
}
public class NEOGEOKeyBinding : MAMEKeyBinding
{
public override RomPlatformType Platform => RomPlatformType.Neogeo;
}
public class CPS1KeyBinding : MAMEKeyBinding
{
public override RomPlatformType Platform => RomPlatformType.Cps1;
}
public class CPS2KeyBinding : MAMEKeyBinding
{
public override RomPlatformType Platform => RomPlatformType.Cps2;
}
public class IGSKeyBinding : MAMEKeyBinding
{
public override RomPlatformType Platform => RomPlatformType.Igs;
}
public class OldArcadeKeyBinding : MAMEKeyBinding
{
public override RomPlatformType Platform => RomPlatformType.ArcadeOld;
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ef759672134881f4ca7df82e984a8c87

View File

@ -0,0 +1,43 @@
using AxibugEmuOnline.Client.InputDevices;
using AxibugProtobuf;
using VirtualNes.Core;
namespace AxibugEmuOnline.Client.Settings
{
public class NesKeyBinding : EmuCoreControllerKeyBinding<EnumButtonType>
{
public override RomPlatformType Platform => RomPlatformType.Nes;
public override int ControllerCount => 4;
protected override void OnRegistDevices(InputDevice_D device, BindingPage binding)
{
if (device is Keyboard_D keyboard)
{
switch (binding.ControllerIndex)
{
case 0:
binding.SetBinding(EnumButtonType.LEFT, keyboard.A, 0);
binding.SetBinding(EnumButtonType.RIGHT, keyboard.D, 0);
binding.SetBinding(EnumButtonType.UP, keyboard.W, 0);
binding.SetBinding(EnumButtonType.DOWN, keyboard.S, 0);
binding.SetBinding(EnumButtonType.A, keyboard.K, 0);
binding.SetBinding(EnumButtonType.B, keyboard.J, 0);
binding.SetBinding(EnumButtonType.SELECT, keyboard.V, 0);
binding.SetBinding(EnumButtonType.START, keyboard.B, 0);
binding.SetBinding(EnumButtonType.MIC, keyboard.M, 0);
break;
case 1:
binding.SetBinding(EnumButtonType.UP, keyboard.UpArrow, 0);
binding.SetBinding(EnumButtonType.DOWN, keyboard.DownArrow, 0);
binding.SetBinding(EnumButtonType.LEFT, keyboard.LeftArrow, 0);
binding.SetBinding(EnumButtonType.RIGHT, keyboard.RightArrow, 0);
binding.SetBinding(EnumButtonType.A, keyboard.Keypad2, 0);
binding.SetBinding(EnumButtonType.B, keyboard.Keypad1, 0);
binding.SetBinding(EnumButtonType.SELECT, keyboard.Keypad0, 0);
binding.SetBinding(EnumButtonType.START, keyboard.KeypadPeriod, 0);
break;
}
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 65743da1d10d08d4d8a6485eb7fd7188

View File

@ -0,0 +1,46 @@
using AxibugEmuOnline.Client.InputDevices;
using AxibugEmuOnline.Client.Settings;
using AxibugProtobuf;
namespace AxibugEmuOnline.Client
{
public class XMBKeyBinding : EmuCoreControllerKeyBinding<EnumCommand>
{
public override RomPlatformType Platform => RomPlatformType.Invalid;
public override int ControllerCount => 2;
protected override void OnRegistDevices(InputDevice_D device, BindingPage binding)
{
if (device is Keyboard_D keyboard)
{
switch (binding.ControllerIndex)
{
case 0://设置标准UI控制
//第一套控制布局 WSAD+JKLI
binding.SetBinding(EnumCommand.Back, keyboard.L, 0);
binding.SetBinding(EnumCommand.Enter, keyboard.K, 0);
binding.SetBinding(EnumCommand.OptionMenu, keyboard.I, 0);
binding.SetBinding(EnumCommand.SelectItemDown, keyboard.S, 0);
binding.SetBinding(EnumCommand.SelectItemLeft, keyboard.A, 0);
binding.SetBinding(EnumCommand.SelectItemRight, keyboard.D, 0);
binding.SetBinding(EnumCommand.SelectItemUp, keyboard.W, 0);
//第二套控制布局 LOWB用
binding.SetBinding(EnumCommand.Back, keyboard.Escape, 1);
binding.SetBinding(EnumCommand.Back, keyboard.Backspace, 2);
binding.SetBinding(EnumCommand.Enter, keyboard.Return, 1);
binding.SetBinding(EnumCommand.OptionMenu, keyboard.LeftShift, 1);
binding.SetBinding(EnumCommand.OptionMenu, keyboard.RightShift, 2);
binding.SetBinding(EnumCommand.SelectItemDown, keyboard.DownArrow, 1);
binding.SetBinding(EnumCommand.SelectItemLeft, keyboard.LeftArrow, 1);
binding.SetBinding(EnumCommand.SelectItemRight, keyboard.RightArrow, 1);
binding.SetBinding(EnumCommand.SelectItemUp, keyboard.UpArrow, 1);
break;
case 1://游戏中UI控制
binding.SetBinding(EnumCommand.OptionMenu, keyboard.Escape, 0);
break;
}
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 8605f13d4a077324b83a12938ee03721

View File

@ -2,7 +2,7 @@
using UnityEngine;
using UnityEngine.UI;
namespace AxibugEmuOnline.Client
namespace AxibugEmuOnline.Client.Settings
{
/// <summary>
/// 实现模拟器输出画面的比例调整类

View File

@ -1,26 +0,0 @@
namespace AxibugEmuOnline.Client.Manager
{
public partial class GamePadManager
{
/// <summary>
/// 被Unity所识别的通用GamePad类
/// </summary>
public class GamePad
{
internal GamePadInfo m_info;
public int Index => m_info.Index;
public string Name => m_info.Name;
public bool Offline { get; internal set; }
internal GamePad(GamePadInfo info)
{
m_info = info;
}
public override string ToString()
{
return $"{Index}:{Name}{(Offline ? "(Offline)" : string.Empty)}";
}
}
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: c2c0a06020f65a747af5490a6112361b

View File

@ -1,121 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace AxibugEmuOnline.Client.Manager
{
public partial class GamePadManager
{
#region Events
public delegate void GamePadConnectedHandle(GamePad newConnectGamePad);
/// <summary> 当一个手柄连接时触发 </summary>
public event GamePadConnectedHandle OnGamePadConnected;
public delegate void GamePadDisConnectedHandle(GamePad disConnectGamePad);
/// <summary> 当一个手柄断开时触发 </summary>
public event GamePadDisConnectedHandle OnGamePadDisConnected;
#endregion
Dictionary<GamePadInfo, GamePad> m_gamePads = new Dictionary<GamePadInfo, GamePad>();
HashSet<GamePadInfo> m_temp = new HashSet<GamePadInfo>();
public void Update()
{
m_temp.Clear();
foreach (var info in m_gamePads.Keys)
m_temp.Add(info); //记录需要被移除的手柄
var devices = Input.GetJoystickNames();
for (int i = 0; i < devices.Length; i++)
{
var info = new GamePadInfo { Index = i, Name = devices[i] };
m_temp.Remove(info);
if (!m_gamePads.ContainsKey(info))
{
m_gamePads[info] = new GamePad(info);
OnGamePadConnected?.Invoke(m_gamePads[info]);
};
}
foreach (var info in m_temp)
{
if (m_gamePads.TryGetValue(info, out GamePad gp))
{
m_gamePads.Remove(info);
gp.Offline = true;
OnGamePadDisConnected?.Invoke(gp);
}
}
}
/// <summary>
/// 获取所有已连接的手柄,返回的结果顺序与手柄序号无关
/// </summary>
/// <returns></returns>
public GamePad[] GetGamePads()
{
return m_gamePads.Values.ToArray();
}
internal struct GamePadInfo : IEquatable<GamePadInfo>, IComparable<GamePadInfo>
{
internal int Index;
internal string Name;
public override bool Equals(object obj)
{
if (obj is GamePadInfo)
{
return Equals((GamePadInfo)obj);
}
return false;
}
public bool Equals(GamePadInfo other)
{
return Index == other.Index && Name == other.Name;
}
public override int GetHashCode()
{
// Custom hash code implementation without HashCombine
int hash = 17;
hash = hash * 31 + Index.GetHashCode();
hash = hash * 31 + (Name != null ? Name.GetHashCode() : 0);
return hash;
}
public int CompareTo(GamePadInfo other)
{
int indexComparison = Index.CompareTo(other.Index);
if (indexComparison != 0)
{
return indexComparison;
}
return string.Compare(Name, other.Name, StringComparison.Ordinal);
}
public static bool operator ==(GamePadInfo left, GamePadInfo right)
{
return left.Equals(right);
}
public static bool operator !=(GamePadInfo left, GamePadInfo right)
{
return !(left == right);
}
public static bool operator <(GamePadInfo left, GamePadInfo right)
{
return left.CompareTo(right) < 0;
}
public static bool operator >(GamePadInfo left, GamePadInfo right)
{
return left.CompareTo(right) > 0;
}
}
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: ce4d215abea527e4a8cf1103cbfecf6b

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 5fe26f58ab822c44888b86305c5326e0
guid: 7c141dadb47c8624c80c092e415ab621
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c72c157b8f11c634991ba09272065d1e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,29 @@
namespace AxibugEmuOnline.Client.InputDevices
{
/// <summary>
/// 通用游戏控制器
/// </summary>
public class GamePad_D : InputDevice_D
{
public Button_C Up;
public Button_C Down;
public Button_C Left;
public Button_C Right;
public Button_C Select;
public Button_C Start;
public Button_C North;
public Button_C South;
public Button_C West;
public Button_C East;
public Button_C LeftShoulder;
public Button_C RightShoulder;
public Button_C LeftTrigger;
public Button_C RightTrigger;
public Button_C LeftStickPress;
public Button_C RightStickPress;
public Stick_C LeftStick;
public Stick_C RightStick;
public GamePad_D(InputResolver resolver) : base(resolver) { }
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: adda9a9ea56de5742bc1b00ce85ce9e5

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e098c1dc313c2d746b3a0c6a7f1a69f0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,12 @@
namespace AxibugEmuOnline.Client.InputDevices
{
/// <summary>
/// 按键类型的输入控件
/// </summary>
public class Button_C : InputControl_C
{
public Button_C(InputDevice_D device, string controlName) : base(device, controlName)
{
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 2106c0f7afa9b7647978373d7c6d5aae

View File

@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
namespace AxibugEmuOnline.Client.InputDevices
{
/// <summary>
/// 输入设备的抽象控件接口
/// </summary>
public abstract class InputControl_C
{
/// <summary> 控件所属设备 </summary>
public InputDevice_D Device { get; internal set; }
/// <summary> 获取该控件是否在当前调用帧被激发 </summary>
public bool Start { get; private set; }
/// <summary> 获取该控件是否在当前调用帧被释放 </summary>
public bool Release { get; private set; }
bool m_performingLastFrame;
/// <summary> 获取该控件是否在当前调用帧是否处于活动状态 </summary>
public virtual bool Performing => Device.Resolver.CheckPerforming(this);
/// <summary> 获得该控件的以二维向量表达的值 </summary>
/// <returns></returns>
public virtual Vector2 GetVector2() => Device.Resolver.GetVector2(this);
/// <summary> 获得该控件的以浮点数表达的值 </summary>
public virtual float GetFlaot() => Device.Resolver.GetFloat(this);
internal void Update()
{
UpdateReleaseStartState();
OnUpdate();
}
private void UpdateReleaseStartState()
{
var oldPerforming = m_performingLastFrame;
var newPerforming = Performing;
Start = false;
Release = false;
if (oldPerforming != newPerforming)
{
if (oldPerforming == false) Start = true;
else Release = true;
}
m_performingLastFrame = Performing;
}
protected virtual void OnUpdate() { }
public InputControl_C Parent { get; private set; }
/// <summary> 控件名,这个控件名称必须是唯一的 </summary>
public string ControlName { get; private set; }
protected Dictionary<string, InputControl_C> m_controlMapper = new Dictionary<string, InputControl_C>();
internal InputControl_C(InputDevice_D device, string controlName)
{
Device = device;
ControlName = controlName;
DefineControls();
}
private void DefineControls()
{
foreach (var field in GetType().GetFields(BindingFlags.Instance | BindingFlags.Public))
{
if (!typeof(InputControl_C).IsAssignableFrom(field.FieldType)) continue;
var controlIns = Activator.CreateInstance(field.FieldType, this, field.Name) as InputControl_C;
controlIns.Parent = this;
field.SetValue(this, controlIns);
m_controlMapper[field.Name] = controlIns;
}
}
public override string ToString()
{
if (Parent != null)
{
return $"{Parent}/{ControlName}";
}
else
{
return $"{Device}/{ControlName}";
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0d3d88a49545f614184e3d5a59d2958e

View File

@ -0,0 +1,59 @@
using UnityEngine;
namespace AxibugEmuOnline.Client.InputDevices
{
/// <summary>
/// 摇杆类型的输入控件,支持的返回值为Vector2
/// </summary>
public class Stick_C : InputControl_C
{
public VirtualButton UP;
public VirtualButton Down;
public VirtualButton Left;
public VirtualButton Right;
public Stick_C(InputDevice_D device, string controlName) : base(device, controlName)
{
}
protected override void OnUpdate()
{
var axis = GetVector2();
UP.m_performing = axis.y > 0f;
UP.Update();
Down.m_performing = axis.y < 0f;
Down.Update();
Left.m_performing = axis.x < 0f;
Left.Update();
Right.m_performing = axis.x > 0f;
Right.Update();
}
public class VirtualButton : InputControl_C
{
internal bool m_performing;
public VirtualButton(InputDevice_D device, string controlName) : base(device, controlName) { }
public override bool Performing
{
get => m_performing;
}
public override Vector2 GetVector2()
{
return default;
}
public override float GetFlaot()
{
return Performing ? 1 : 0;
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 9091f3794f770294488695cd2cbbf7af

View File

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Reflection;
namespace AxibugEmuOnline.Client.InputDevices
{
public abstract class InputDevice_D
{
public string UniqueName => m_resolver.GetDeviceName(this);
/// <summary> 指示该设备是否在线 </summary>
public bool Online => m_resolver.CheckOnline(this);
/// <summary> 指示该设备当前帧是否有任意控件被激发 </summary>
public bool AnyKeyDown { get; private set; }
/// <summary> 获得输入解决器 </summary>
internal InputResolver Resolver => m_resolver;
protected Dictionary<string, InputControl_C> m_controlMapper = new Dictionary<string, InputControl_C>();
protected InputResolver m_resolver;
public InputDevice_D(InputResolver resolver)
{
m_resolver = resolver;
DefineControls();
}
private void DefineControls()
{
foreach (var field in GetType().GetFields(BindingFlags.Instance | BindingFlags.Public))
{
if (!typeof(InputControl_C).IsAssignableFrom(field.FieldType)) continue;
var controlIns = Activator.CreateInstance(field.FieldType, this, field.Name) as InputControl_C;
field.SetValue(this, controlIns);
m_controlMapper[field.Name] = controlIns;
}
}
public void Update()
{
AnyKeyDown = false;
foreach (var control in m_controlMapper.Values)
{
control.Update();
if (control.Start)
{
AnyKeyDown = true;
}
}
}
public override string ToString()
{
return Resolver.GetDeviceName(this);
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: eab247826950d024b8a5c7ade4142391

View File

@ -0,0 +1,116 @@
using System.Collections.Generic;
namespace AxibugEmuOnline.Client.InputDevices
{
/// <summary>
/// 通用键盘设备
/// </summary>
public class Keyboard_D : InputDevice_D
{
public Button_C A;
public Button_C B;
public Button_C C;
public Button_C D;
public Button_C E;
public Button_C F;
public Button_C G;
public Button_C H;
public Button_C I;
public Button_C J;
public Button_C K;
public Button_C L;
public Button_C M;
public Button_C N;
public Button_C O;
public Button_C P;
public Button_C Q;
public Button_C R;
public Button_C S;
public Button_C T;
public Button_C U;
public Button_C V;
public Button_C W;
public Button_C X;
public Button_C Y;
public Button_C Z;
public Button_C Alpha0;
public Button_C Alpha1;
public Button_C Alpha2;
public Button_C Alpha3;
public Button_C Alpha4;
public Button_C Alpha5;
public Button_C Alpha6;
public Button_C Alpha7;
public Button_C Alpha8;
public Button_C Alpha9;
public Button_C F1;
public Button_C F2;
public Button_C F3;
public Button_C F4;
public Button_C F5;
public Button_C F6;
public Button_C F7;
public Button_C F8;
public Button_C F9;
public Button_C F10;
public Button_C F11;
public Button_C F12;
public Button_C UpArrow;
public Button_C DownArrow;
public Button_C LeftArrow;
public Button_C RightArrow;
public Button_C Space;
public Button_C Return;
public Button_C Escape;
public Button_C Tab;
public Button_C Backspace;
public Button_C CapsLock;
public Button_C LeftShift;
public Button_C RightShift;
public Button_C LeftControl;
public Button_C RightControl;
public Button_C LeftAlt;
public Button_C RightAlt;
public Button_C LeftCommand;
public Button_C RightCommand;
public Button_C Comma;
public Button_C Period;
public Button_C Slash;
public Button_C BackQuote;
public Button_C Quote;
public Button_C Semicolon;
public Button_C LeftBracket;
public Button_C RightBracket;
public Button_C Backslash;
public Button_C Minus;
public Button_C Equals_k;
public Button_C Keypad0;
public Button_C Keypad1;
public Button_C Keypad2;
public Button_C Keypad3;
public Button_C Keypad4;
public Button_C Keypad5;
public Button_C Keypad6;
public Button_C Keypad7;
public Button_C Keypad8;
public Button_C Keypad9;
public Button_C KeypadPeriod;
public Button_C KeypadDivide;
public Button_C KeypadMultiply;
public Button_C KeypadMinus;
public Button_C KeypadPlus;
public Button_C KeypadEnter;
public Button_C Numlock;
public Button_C Print;
public Button_C Insert;
public Button_C Delete;
public Button_C Home;
public Button_C End;
public Button_C PageUp;
public Button_C PageDown;
public Button_C Pause;
public Button_C ScrollLock;
public Keyboard_D(InputResolver resolver) : base(resolver) { }
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e75cd67769afcad4890be3acf0ac1330

View File

@ -0,0 +1,22 @@
namespace AxibugEmuOnline.Client.InputDevices
{
public class PSVController_D : InputDevice_D
{
public Button_C Cross;
public Button_C Circle;
public Button_C Square;
public Button_C Triangle;
public Button_C L;
public Button_C R;
public Button_C Select;
public Button_C Start;
public Button_C Up;
public Button_C Right;
public Button_C Down;
public Button_C Left;
public Stick_C LeftStick;
public Stick_C RightStick;
public PSVController_D(InputResolver resolver) : base(resolver) { }
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5f5d8205d647a4741a9c4e8d7894f040

View File

@ -0,0 +1,133 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace AxibugEmuOnline.Client.InputDevices
{
/// <summary>
/// 双向字典
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
public class DualWayDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary
where TKey : notnull
where TValue : notnull
{
private readonly Dictionary<TKey, TValue> _forward = new();
private readonly Dictionary<TValue, TKey> _reverse = new();
// 显式实现非泛型接口
bool IDictionary.IsFixedSize => false;
bool IDictionary.IsReadOnly => false;
bool ICollection.IsSynchronized => false;
object ICollection.SyncRoot => ((ICollection)_forward).SyncRoot;
// 泛型接口实现
public TValue this[TKey key]
{
get => _forward[key];
set
{
if (_forward.TryGetValue(key, out var oldValue))
_reverse.Remove(oldValue);
_forward[key] = value;
_reverse[value] = key;
}
}
object? IDictionary.this[object key]
{
get => key is TKey k ? _forward[k] : null;
set
{
if (key is TKey tk && value is TValue tv)
this[tk] = tv;
}
}
public ICollection<TKey> Keys => _forward.Keys;
public ICollection<TValue> Values => _forward.Values;
ICollection IDictionary.Keys => _forward.Keys;
ICollection IDictionary.Values => _forward.Values;
public int Count => _forward.Count;
public bool IsReadOnly => false;
// 双向查询扩展
public bool TryGetKey(TValue value, out TKey key) => _reverse.TryGetValue(value, out key);
public bool TryGetValue(TKey key, out TValue value) => _forward.TryGetValue(key, out value);
// 接口方法实现
public void Add(TKey key, TValue value)
{
if (_forward.ContainsKey(key) || _reverse.ContainsKey(value))
throw new ArgumentException("键或值已存在");
_forward.Add(key, value);
_reverse.Add(value, key);
}
public void Add(KeyValuePair<TKey, TValue> item) => Add(item.Key, item.Value);
void IDictionary.Add(object key, object value)
{
if (key is TKey k && value is TValue v)
Add(k, v);
else
throw new ArgumentException("类型不匹配");
}
public bool Contains(object key) => key is TKey k && _forward.ContainsKey(k);
public bool Contains(KeyValuePair<TKey, TValue> item) => _forward.TryGetValue(item.Key, out var v) && v.Equals(item.Value);
public bool ContainsKey(TKey key) => _forward.ContainsKey(key);
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
((ICollection<KeyValuePair<TKey, TValue>>)_forward).CopyTo(array, arrayIndex);
}
public void CopyTo(Array array, int index)
{
((ICollection)_forward).CopyTo(array, index);
}
public bool Remove(TKey key)
{
if (!_forward.Remove(key, out var value)) return false;
_reverse.Remove(value);
return true;
}
public bool Remove(KeyValuePair<TKey, TValue> item) => Remove(item.Key);
void IDictionary.Remove(object key)
{
if (key is TKey k) Remove(k);
}
public void Clear()
{
_forward.Clear();
_reverse.Clear();
}
// 枚举器实现
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() => _forward.GetEnumerator();
IDictionaryEnumerator IDictionary.GetEnumerator() => new DictionaryEnumerator(_forward.GetEnumerator());
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
// 非泛型枚举器适配器
private class DictionaryEnumerator : IDictionaryEnumerator
{
private readonly IEnumerator<KeyValuePair<TKey, TValue>> _enumerator;
public DictionaryEnumerator(IEnumerator<KeyValuePair<TKey, TValue>> enumerator) => _enumerator = enumerator;
public DictionaryEntry Entry => new(_enumerator.Current.Key, _enumerator.Current.Value);
public object Key => _enumerator.Current.Key;
public object? Value => _enumerator.Current.Value;
public object Current => Entry;
public bool MoveNext() => _enumerator.MoveNext();
public void Reset() => _enumerator.Reset();
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: c1c60fee919bdf34983705af53c629f6

View File

@ -0,0 +1,65 @@
using System.Collections.Generic;
using UnityEngine;
namespace AxibugEmuOnline.Client.InputDevices
{
public class InputDevicesManager
{
InputResolver m_inputResolver = InputResolver.Create();
Dictionary<string, InputDevice_D> m_devices = new Dictionary<string, InputDevice_D>();
public delegate void OnDeviceConnectedHandle(InputDevice_D connectDevice);
public event OnDeviceConnectedHandle OnDeviceConnected;
public delegate void OnDeviceLostHandle(InputDevice_D lostDevice);
public event OnDeviceLostHandle OnDeviceLost;
public InputDevicesManager()
{
m_inputResolver.OnDeviceConnected += Resolver_OnDeviceConnected;
m_inputResolver.OnDeviceLost += Resolver_OnDeviceLost;
foreach (var device in m_inputResolver.GetDevices())
AddDevice(device);
}
private void Resolver_OnDeviceLost(InputDevice_D lostDevice)
{
RemoveDevice(lostDevice);
}
private void Resolver_OnDeviceConnected(InputDevice_D connectDevice)
{
AddDevice(connectDevice);
}
void AddDevice(InputDevice_D device)
{
m_devices[device.UniqueName] = device;
OnDeviceConnected?.Invoke(device);
}
void RemoveDevice(InputDevice_D device)
{
m_devices.Remove(device.UniqueName);
OnDeviceLost?.Invoke(device);
}
/// <summary>
/// 获得一个指定类型的设备
/// </summary>
public T GetDevice<T>() where T : InputDevice_D
{
foreach (var d in m_devices.Values)
{
if (d is T) return d as T;
}
return null;
}
/// <summary> 由外部驱动的逻辑更新入口 </summary>
public void Update()
{
foreach (var device in m_devices.Values) device.Update();
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 81cfc80679d76514d801eed124ffc356

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8fec275f55ad33a4fbe0ce724bc7274f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,69 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
namespace AxibugEmuOnline.Client.InputDevices
{
public abstract class InputResolver
{
public static InputResolver Create()
{
#if ENABLE_INPUT_SYSTEM //InputSystem
return new ForInputSystem.InputSystemResolver();
#elif UNITY_PSP2 //特化实现
return new ForPSV.PSVResolver();
#elif UNITY_PS3 //SDK
throw new System.NotImplementedException();
#else
throw new System.NotImplementedException();
#endif
}
/// <summary> 禁止外部构造 </summary>
protected InputResolver()
{
OnInit();
}
protected abstract void OnInit();
/// <summary>
/// 获得所有当前已连入的输入设备
/// </summary>
/// <returns></returns>
public abstract IEnumerable<InputDevice_D> GetDevices();
/// <summary>
/// 检查指定输入设备是否还保持着连接
/// </summary>
/// <returns></returns>
public abstract bool CheckOnline(InputDevice_D device);
/// <param name="lostDevice">丢失的设备</param>
public delegate void OnDeviceLostHandle(InputDevice_D lostDevice);
/// <summary> 当设备丢失时触发 </summary>
public event OnDeviceLostHandle OnDeviceLost;
protected void RaiseDeviceLost(InputDevice_D lostDevice)
{
OnDeviceLost?.Invoke(lostDevice);
}
/// <param name="connectDevice">建立连接的设备</param>
public delegate void OnDeviceConnectedHandle(InputDevice_D connectDevice);
/// <summary> 当设备连接时触发 </summary>
public event OnDeviceConnectedHandle OnDeviceConnected;
protected void RaiseDeviceConnected(InputDevice_D connectDevice)
{
OnDeviceConnected?.Invoke(connectDevice);
}
public abstract bool CheckPerforming<CONTROLLER>(CONTROLLER control) where CONTROLLER : InputControl_C;
public abstract Vector2 GetVector2<CONTROLLER>(CONTROLLER control) where CONTROLLER : InputControl_C;
public abstract float GetFloat<CONTROLLER>(CONTROLLER control) where CONTROLLER : InputControl_C;
/// <summary>
/// 获得输入设备的唯一名称
/// </summary>
/// <param name="inputDevice">这个设备必须是由resolver提供,并且保持着连接</param>
/// <returns></returns>
public abstract string GetDeviceName(InputDevice_D inputDevice);
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 120c0ed2a5e098a4d84325be244aa9f3

View File

@ -0,0 +1,255 @@
#if ENABLE_INPUT_SYSTEM
using Google.Protobuf.WellKnownTypes;
using NUnit.Framework.Internal;
using System.Collections.Generic;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
using UnityEngine.InputSystem;
namespace AxibugEmuOnline.Client.InputDevices.ForInputSystem
{
/// <summary> 基于UnityInputSystem实现的输入解决器 </summary>
public class InputSystemResolver : InputResolver
{
DualWayDictionary<InputDevice, InputDevice_D> m_devices = new DualWayDictionary<InputDevice, InputDevice_D>();
protected override void OnInit()
{
foreach (var device in InputSystem.devices) AddDevice(device);
InputSystem.onDeviceChange += IP_onDeviceChange;
}
private void AddDevice(InputDevice ipdev)
{
InputDevice_D newDevice = null;
if (ipdev is Keyboard) newDevice = new Keyboard_D(this);
else if (ipdev is Gamepad) newDevice = new GamePad_D(this);
if (newDevice != null)
{
m_devices.Add(ipdev, newDevice);
AddDeviceMapper(newDevice, ipdev);
RaiseDeviceConnected(newDevice);
}
}
private void RemoveDevice(InputDevice ipdev)
{
if (m_devices.TryGetValue(ipdev, out var device))
{
m_devices.Remove(ipdev);
RemoveDeviceMapper(device);
RaiseDeviceLost(device);
}
}
private T GetInputSystemDevice<T>(InputDevice_D device) where T : InputDevice
{
m_devices.TryGetKey(device, out var ipDev);
return ipDev as T;
}
public override string GetDeviceName(InputDevice_D inputDevice)
{
var ipdev = GetInputSystemDevice<InputDevice>(inputDevice);
Debug.Assert(ipdev != null, "不能对已离线的设备获取名称");
return $"{ipdev.description.deviceClass}_{ipdev.description.interfaceName}_{ipdev.deviceId}";
}
public override bool CheckOnline(InputDevice_D device)
{
return m_devices.TryGetKey(device, out var _);
}
private void IP_onDeviceChange(InputDevice device, InputDeviceChange changeType)
{
switch (changeType)
{
case InputDeviceChange.Added: AddDevice(device); break;
case InputDeviceChange.Removed: RemoveDevice(device); break;
}
}
public override IEnumerable<InputDevice_D> GetDevices()
{
return m_devices.Values;
}
public override bool CheckPerforming<CONTROLLER>(CONTROLLER control)
{
var ipControl = GetInputSystemControl(control);
return ipControl.IsPressed();
}
public override Vector2 GetVector2<CONTROLLER>(CONTROLLER control)
{
var ipControl = GetInputSystemControl(control);
return (ipControl as InputControl<Vector2>).value;
}
public override float GetFloat<CONTROLLER>(CONTROLLER control)
{
var ipControl = GetInputSystemControl(control);
return (ipControl as InputControl<float>).value;
}
InputControl GetInputSystemControl(InputControl_C key)
{
var device_d = key.Device;
var mapper = m_deviceMapper[device_d];
mapper.TryGetValue(key, out InputControl inputBtn);
if (inputBtn != null)
return inputBtn;
else
{
throw new System.Exception($"not found mapper setting : {key}");
}
}
Dictionary<InputDevice_D, Dictionary<InputControl_C, InputControl>> m_deviceMapper = new Dictionary<InputDevice_D, Dictionary<InputControl_C, InputControl>>();
void AddDeviceMapper(InputDevice_D device_d, InputDevice ipdevice)
{
m_deviceMapper.Add(device_d, new Dictionary<InputControl_C, InputControl>());
var mapper = m_deviceMapper[device_d];
if (device_d is Keyboard_D keyboard_d)
{
var ipKeyboard = ipdevice as Keyboard;
mapper[keyboard_d.A] = ipKeyboard.aKey;
mapper[keyboard_d.B] = ipKeyboard.bKey;
mapper[keyboard_d.C] = ipKeyboard.cKey;
mapper[keyboard_d.D] = ipKeyboard.dKey;
mapper[keyboard_d.E] = ipKeyboard.eKey;
mapper[keyboard_d.F] = ipKeyboard.fKey;
mapper[keyboard_d.G] = ipKeyboard.gKey;
mapper[keyboard_d.H] = ipKeyboard.hKey;
mapper[keyboard_d.I] = ipKeyboard.iKey;
mapper[keyboard_d.J] = ipKeyboard.jKey;
mapper[keyboard_d.K] = ipKeyboard.kKey;
mapper[keyboard_d.L] = ipKeyboard.lKey;
mapper[keyboard_d.M] = ipKeyboard.mKey;
mapper[keyboard_d.N] = ipKeyboard.nKey;
mapper[keyboard_d.O] = ipKeyboard.oKey;
mapper[keyboard_d.P] = ipKeyboard.pKey;
mapper[keyboard_d.Q] = ipKeyboard.qKey;
mapper[keyboard_d.R] = ipKeyboard.rKey;
mapper[keyboard_d.S] = ipKeyboard.sKey;
mapper[keyboard_d.T] = ipKeyboard.tKey;
mapper[keyboard_d.U] = ipKeyboard.uKey;
mapper[keyboard_d.V] = ipKeyboard.vKey;
mapper[keyboard_d.W] = ipKeyboard.wKey;
mapper[keyboard_d.X] = ipKeyboard.xKey;
mapper[keyboard_d.Y] = ipKeyboard.yKey;
mapper[keyboard_d.Z] = ipKeyboard.zKey;
mapper[keyboard_d.Alpha0] = ipKeyboard.digit0Key;
mapper[keyboard_d.Alpha1] = ipKeyboard.digit1Key;
mapper[keyboard_d.Alpha2] = ipKeyboard.digit2Key;
mapper[keyboard_d.Alpha3] = ipKeyboard.digit3Key;
mapper[keyboard_d.Alpha4] = ipKeyboard.digit4Key;
mapper[keyboard_d.Alpha5] = ipKeyboard.digit5Key;
mapper[keyboard_d.Alpha6] = ipKeyboard.digit6Key;
mapper[keyboard_d.Alpha7] = ipKeyboard.digit7Key;
mapper[keyboard_d.Alpha8] = ipKeyboard.digit8Key;
mapper[keyboard_d.Alpha9] = ipKeyboard.digit9Key;
mapper[keyboard_d.Keypad0] = ipKeyboard.numpad0Key;
mapper[keyboard_d.Keypad1] = ipKeyboard.numpad1Key;
mapper[keyboard_d.Keypad2] = ipKeyboard.numpad2Key;
mapper[keyboard_d.Keypad3] = ipKeyboard.numpad3Key;
mapper[keyboard_d.Keypad4] = ipKeyboard.numpad4Key;
mapper[keyboard_d.Keypad5] = ipKeyboard.numpad5Key;
mapper[keyboard_d.Keypad6] = ipKeyboard.numpad6Key;
mapper[keyboard_d.Keypad7] = ipKeyboard.numpad7Key;
mapper[keyboard_d.Keypad8] = ipKeyboard.numpad8Key;
mapper[keyboard_d.Keypad9] = ipKeyboard.numpad9Key;
mapper[keyboard_d.KeypadPeriod] = ipKeyboard.numpadPeriodKey;
mapper[keyboard_d.KeypadDivide] = ipKeyboard.numpadDivideKey;
mapper[keyboard_d.KeypadMultiply] = ipKeyboard.numpadMultiplyKey;
mapper[keyboard_d.KeypadMinus] = ipKeyboard.numpadMinusKey;
mapper[keyboard_d.KeypadPlus] = ipKeyboard.numpadPlusKey;
mapper[keyboard_d.KeypadEnter] = ipKeyboard.numpadEnterKey;
mapper[keyboard_d.F1] = ipKeyboard.f1Key;
mapper[keyboard_d.F2] = ipKeyboard.f2Key;
mapper[keyboard_d.F3] = ipKeyboard.f3Key;
mapper[keyboard_d.F4] = ipKeyboard.f4Key;
mapper[keyboard_d.F5] = ipKeyboard.f5Key;
mapper[keyboard_d.F6] = ipKeyboard.f6Key;
mapper[keyboard_d.F7] = ipKeyboard.f7Key;
mapper[keyboard_d.F8] = ipKeyboard.f8Key;
mapper[keyboard_d.F9] = ipKeyboard.f9Key;
mapper[keyboard_d.F10] = ipKeyboard.f10Key;
mapper[keyboard_d.F11] = ipKeyboard.f11Key;
mapper[keyboard_d.F12] = ipKeyboard.f12Key;
mapper[keyboard_d.UpArrow] = ipKeyboard.upArrowKey;
mapper[keyboard_d.DownArrow] = ipKeyboard.downArrowKey;
mapper[keyboard_d.LeftArrow] = ipKeyboard.leftArrowKey;
mapper[keyboard_d.RightArrow] = ipKeyboard.rightArrowKey;
mapper[keyboard_d.Space] = ipKeyboard.spaceKey;
mapper[keyboard_d.Backspace] = ipKeyboard.backspaceKey;
mapper[keyboard_d.Tab] = ipKeyboard.tabKey;
mapper[keyboard_d.Return] = ipKeyboard.enterKey;
mapper[keyboard_d.Escape] = ipKeyboard.escapeKey;
mapper[keyboard_d.LeftShift] = ipKeyboard.leftShiftKey;
mapper[keyboard_d.RightShift] = ipKeyboard.rightShiftKey;
mapper[keyboard_d.LeftControl] = ipKeyboard.leftCtrlKey;
mapper[keyboard_d.RightControl] = ipKeyboard.rightCtrlKey;
mapper[keyboard_d.LeftAlt] = ipKeyboard.leftAltKey;
mapper[keyboard_d.RightAlt] = ipKeyboard.rightAltKey;
mapper[keyboard_d.LeftCommand] = ipKeyboard.leftCommandKey;
mapper[keyboard_d.RightCommand] = ipKeyboard.rightCommandKey;
mapper[keyboard_d.CapsLock] = ipKeyboard.capsLockKey;
mapper[keyboard_d.Numlock] = ipKeyboard.numLockKey;
mapper[keyboard_d.ScrollLock] = ipKeyboard.scrollLockKey;
mapper[keyboard_d.Print] = ipKeyboard.printScreenKey;
mapper[keyboard_d.Pause] = ipKeyboard.pauseKey;
mapper[keyboard_d.Insert] = ipKeyboard.insertKey;
mapper[keyboard_d.Home] = ipKeyboard.homeKey;
mapper[keyboard_d.End] = ipKeyboard.endKey;
mapper[keyboard_d.PageUp] = ipKeyboard.pageUpKey;
mapper[keyboard_d.PageDown] = ipKeyboard.pageDownKey;
mapper[keyboard_d.Delete] = ipKeyboard.deleteKey;
mapper[keyboard_d.Comma] = ipKeyboard.commaKey;
mapper[keyboard_d.Period] = ipKeyboard.periodKey;
mapper[keyboard_d.Slash] = ipKeyboard.slashKey;
mapper[keyboard_d.BackQuote] = ipKeyboard.backquoteKey;
mapper[keyboard_d.Minus] = ipKeyboard.minusKey;
mapper[keyboard_d.Equals_k] = ipKeyboard.equalsKey;
mapper[keyboard_d.LeftBracket] = ipKeyboard.leftBracketKey;
mapper[keyboard_d.RightBracket] = ipKeyboard.rightBracketKey;
mapper[keyboard_d.Backslash] = ipKeyboard.backslashKey;
mapper[keyboard_d.Semicolon] = ipKeyboard.semicolonKey;
mapper[keyboard_d.Quote] = ipKeyboard.quoteKey;
}
else if (device_d is GamePad_D gamepad_d)
{
var ipGamepad = ipdevice as Gamepad;
mapper[gamepad_d.Up] = ipGamepad.dpad.up;
mapper[gamepad_d.Down] = ipGamepad.dpad.down;
mapper[gamepad_d.Left] = ipGamepad.dpad.left;
mapper[gamepad_d.Right] = ipGamepad.dpad.right;
mapper[gamepad_d.Select] = ipGamepad.selectButton;
mapper[gamepad_d.Start] = ipGamepad.startButton;
mapper[gamepad_d.North] = ipGamepad.buttonNorth;
mapper[gamepad_d.South] = ipGamepad.buttonSouth;
mapper[gamepad_d.West] = ipGamepad.buttonWest;
mapper[gamepad_d.East] = ipGamepad.buttonEast;
mapper[gamepad_d.LeftShoulder] = ipGamepad.leftShoulder;
mapper[gamepad_d.RightShoulder] = ipGamepad.rightShoulder;
mapper[gamepad_d.LeftTrigger] = ipGamepad.leftTrigger;
mapper[gamepad_d.RightTrigger] = ipGamepad.rightTrigger;
mapper[gamepad_d.LeftStickPress] = ipGamepad.leftStickButton;
mapper[gamepad_d.RightStickPress] = ipGamepad.rightStickButton;
mapper[gamepad_d.LeftStick] = ipGamepad.leftStick;
mapper[gamepad_d.RightStick] = ipGamepad.rightStick;
}
else throw new System.NotImplementedException($"初始化设备失败,未实现的物理按键映射 for {device_d.GetType()}");
}
void RemoveDeviceMapper(InputDevice_D keyboard_d)
{
m_deviceMapper.Remove(keyboard_d);
}
}
}
#endif

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e56617975c158684eb627cfb4a1c3ebd

View File

@ -0,0 +1,83 @@
using System.Collections.Generic;
using UnityEngine;
namespace AxibugEmuOnline.Client.InputDevices.ForPSV
{
/// <summary> PSV特化输入解决器,只能用于PSV平台,并且只支持PSV控制器 </summary>
public class PSVResolver : InputResolver
{
List<InputDevice_D> m_devices = new List<InputDevice_D>();
PSVController_D m_psvController;
protected override void OnInit()
{
m_psvController = new PSVController_D(this);
m_devices.Add(m_psvController);
}
public override IEnumerable<InputDevice_D> GetDevices()
{
return m_devices;
}
public override bool CheckOnline(InputDevice_D device)
{
return device == m_psvController;
}
public override string GetDeviceName(InputDevice_D inputDevice)
{
Debug.Assert(inputDevice == m_psvController, "只支持psv控制器");
return nameof(PSVController_D);
}
public override bool CheckPerforming<CONTROLLER>(CONTROLLER control)
{
if (control.Device is PSVController_D psvCon)
{
if (control == psvCon.Cross) return Input.GetKey(KeyCode.Joystick1Button0);
else if (control == psvCon.Circle) return Input.GetKey(KeyCode.Joystick1Button1);
else if (control == psvCon.Square) return Input.GetKey(KeyCode.Joystick1Button2);
else if (control == psvCon.Triangle) return Input.GetKey(KeyCode.Joystick1Button3);
else if (control == psvCon.L) return Input.GetKey(KeyCode.Joystick1Button4);
else if (control == psvCon.R) return Input.GetKey(KeyCode.Joystick1Button5);
else if (control == psvCon.Select) return Input.GetKey(KeyCode.Joystick1Button6);
else if (control == psvCon.Start) return Input.GetKey(KeyCode.Joystick1Button7);
else if (control == psvCon.Up) return Input.GetKey(KeyCode.Joystick1Button8);
else if (control == psvCon.Right) return Input.GetKey(KeyCode.Joystick1Button9);
else if (control == psvCon.Down) return Input.GetKey(KeyCode.Joystick1Button10);
else if (control == psvCon.Left) return Input.GetKey(KeyCode.Joystick1Button11);
else if (control == psvCon.LeftStick || control == psvCon.RightStick)
{
var vec2 = control.GetVector2();
return vec2.x != 0 || vec2.y != 0;
}
}
throw new System.NotImplementedException();
}
public override Vector2 GetVector2<CONTROLLER>(CONTROLLER control)
{
if (control.Device is PSVController_D psvCon)
{
if (control == psvCon.LeftStick)
{
return new Vector2(Input.GetAxis("Joy1 Axis X"), Input.GetAxis("Joy1 Axis Y"));
}
else if (control == psvCon.RightStick)
{
return new Vector2(Input.GetAxis("Joy1 Axis 4"), Input.GetAxis("Joy1 Axis 5"));
}
}
throw new System.NotImplementedException();
}
public override float GetFloat<CONTROLLER>(CONTROLLER control)
{
throw new System.NotImplementedException();
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 4347b81ba3ae8e148813290b685e8df0

View File

@ -1,4 +1,5 @@
using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.Settings;
using System;
using System.Collections.Generic;

View File

@ -1,3 +1,4 @@
using AxibugEmuOnline.Client.Settings;
using UnityEngine;
namespace AxibugEmuOnline.Client

View File

@ -1,4 +1,5 @@
using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.Settings;
using AxibugEmuOnline.Client.UI;
using DG.Tweening;
using DG.Tweening.Core;

View File

@ -4,7 +4,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using static AxibugEmuOnline.Client.FilterManager;
using static AxibugEmuOnline.Client.Settings.FilterManager;
namespace AxibugEmuOnline.Client
{

View File

@ -1,4 +1,5 @@
using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.Settings;
using AxibugEmuOnline.Client.UI;
namespace AxibugEmuOnline.Client

View File

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
namespace AxibugEmuOnline.Client
@ -7,39 +7,26 @@ namespace AxibugEmuOnline.Client
{
public static CommandDispatcher Instance { get; private set; }
/// <summary> 平级注册对象,都会响应指令 </summary>
/// <summary> 平级注册对象,都会响应指令 </summary>
List<CommandExecuter> m_register = new List<CommandExecuter>();
/// <summary> 独占注册对象,指令会被列表中最后一个对象独占 </summary>
/// <summary> 独占注册对象,指令会被列表中最后一个对象独占 </summary>
List<CommandExecuter> m_registerHigh = new List<CommandExecuter>();
ICommandListener m_listener;
/// <summary> 标准UI操作 </summary>
public IKeyMapperChanger Normal { get; private set; }
/// <summary> 游戏中UI操作 </summary>
public IKeyMapperChanger Gaming { get; private set; }
CommandListener m_listener;
private IKeyMapperChanger m_current;
public IKeyMapperChanger Current
{
get => m_current;
set
{
m_current = value;
SetKeyMapper(m_current);
}
CommandListener.ScheduleType? m_waitMapperSetting = null;
public CommandListener.ScheduleType Mode
{
get => m_listener.Schedule;
set => m_waitMapperSetting = value;
}
private void Awake()
{
Instance = this;
//初始化command监视器
//初始化command监视器
m_listener = new CommandListener();
//初始化键位修改器
Normal = new NormalChanger();
Gaming = new GamingChanger();
}
private void OnDestroy()
@ -85,20 +72,14 @@ namespace AxibugEmuOnline.Client
m_listener.Update(oneFrameRegister);
}
//键位映射在按键响应的堆栈结束后处理,防止迭代器修改问题
//键位映射在按键响应的堆栈结束后处理,防止迭代器修改问题
if (m_waitMapperSetting != null)
{
m_listener.ApplyKeyMapper(m_waitMapperSetting);
m_listener.Schedule = m_waitMapperSetting.Value;
m_waitMapperSetting = null;
}
}
IKeyMapperChanger m_waitMapperSetting = null;
void SetKeyMapper(IKeyMapperChanger keyMapChanger)
{
m_waitMapperSetting = keyMapChanger;
}
private List<CommandExecuter> peekRegister(List<CommandExecuter> results)
{
results.Clear();

View File

@ -1,89 +1,43 @@
using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.Manager;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace AxibugEmuOnline.Client
{
public class CommandListener : ICommandListener
public class CommandListener
{
//Dictionary<KeyCode, EnumCommand> m_keyMapper = new Dictionary<KeyCode, EnumCommand>();
SingleKeysSetting singleKeysSetting;
Dictionary<EnumCommand, bool> m_dictLastState = new Dictionary<EnumCommand, bool>();
EnumCommand[] m_checkCmds;
List<CommandState> m_commands = new List<CommandState>();
long CheckFrame = -1;
long CheckFrame = -1;
XMBKeyBinding m_keyBinder;
public ScheduleType Schedule { get; set; }
public CommandListener()
{
m_keyBinder = App.settings.KeyMapper.GetBinder<XMBKeyBinding>();
m_checkCmds = Enum.GetValues(typeof(EnumCommand)) as EnumCommand[];
}
IEnumerable<CommandState> GetCommand()
{
//foreach (var item in m_keyMapper)
//{
// if (Input.GetKeyDown(item.Key)) m_commands.Add(new CommandState { Cmd = item.Value, Cancel = false });
// if (Input.GetKeyUp(item.Key)) m_commands.Add(new CommandState { Cmd = item.Value, Cancel = true });
//}
if (CheckFrame == Time.frameCount)
return m_commands;
CheckFrame = Time.frameCount;
m_commands.Clear();
//不再依赖KeyDown KeyUp的做法兼容UGUI或者Axis
if (m_checkCmds != null)
{
foreach (var cmd in m_checkCmds)
{
if (singleKeysSetting.GetKeyDown((ulong)cmd)) m_commands.Add(new CommandState { Cmd = cmd, Cancel = false });
if (singleKeysSetting.GetKeyUp((ulong)cmd)) m_commands.Add(new CommandState { Cmd = cmd, Cancel = true });
//if (m_dictLastState[cmd] && !singleKeysSetting.GetKey((ulong)cmd))
//{
// m_commands.Add(new CommandState { Cmd = cmd, Cancel = true });
// m_dictLastState[cmd] = false;
//}
//else if (!m_dictLastState[cmd] && singleKeysSetting.GetKey((ulong)cmd))
//{
// m_commands.Add(new CommandState { Cmd = cmd, Cancel = false });
// m_dictLastState[cmd] = true;
//}
//bool oldstate = m_dictLastState[cmd];
//bool newstate = singleKeysSetting.GetKey((ulong)cmd);
//m_dictLastState[cmd] = newstate;
//if (oldstate != newstate)
//{
// m_commands.Add(new CommandState { Cmd = cmd, Cancel = !newstate });
//}
}
}
//foreach (var item in m_keyMapper)
//{
// if (Input.GetKeyDown(item.Key)) m_commands.Add(new CommandState { Cmd = item.Value, Cancel = false });
// if (Input.GetKeyUp(item.Key)) m_commands.Add(new CommandState { Cmd = item.Value, Cancel = true });
//}
int controllerIndex = (int)Schedule;
foreach (var cmd in m_checkCmds)
{
if (m_keyBinder.Start(cmd, controllerIndex)) m_commands.Add(new CommandState { Cmd = cmd, Cancel = false });
if (m_keyBinder.Release(cmd, controllerIndex)) m_commands.Add(new CommandState { Cmd = cmd, Cancel = true });
}
return m_commands;
}
public void ApplyKeyMapper(IKeyMapperChanger changer)
{
//var cfg = (Dictionary<KeyCode, EnumCommand>)changer.GetConfig();
singleKeysSetting = changer.GetKeySetting();
App.log.Debug($"CommandListener ApplyKeyMapper | {Time.frameCount} {changer.Name}");
EnumCommand[] arr = changer.GetConfig();
//不要直接清m_dictLastState.Clear()同样的Key维持状态避免造成多余CommandState
EnumCommand[] temp = m_dictLastState.Keys.ToArray();
//仅添加新增
foreach (var cmd in arr)
{
if(!m_dictLastState.ContainsKey(cmd))
m_dictLastState[cmd] = true;
}
m_checkCmds = arr;
}
public void Update(IEnumerable<CommandExecuter> executers)
{
@ -96,5 +50,11 @@ namespace AxibugEmuOnline.Client
}
}
}
public enum ScheduleType
{
Normal,
Gaming
}
}
}

View File

@ -3,22 +3,6 @@ using System.Collections.Generic;
namespace AxibugEmuOnline.Client
{
public interface IKeyMapperChanger
{
string Name { get; }
EnumCommand[] GetConfig();
SingleKeysSetting GetKeySetting();
}
public interface ICommandListener
{
/// <summary>
/// 应用键位设置
/// </summary>
/// <param name="changer"></param>
void ApplyKeyMapper(IKeyMapperChanger changer);
void Update(IEnumerable<CommandExecuter> commands);
}
public struct CommandState
{
public EnumCommand Cmd;

View File

@ -1,7 +1,7 @@
using AxibugEmuOnline.Client.ClientCore;
using System.Collections.Generic;
using System.Linq;
using static AxibugEmuOnline.Client.FilterManager;
using static AxibugEmuOnline.Client.Settings.FilterManager;
namespace AxibugEmuOnline.Client
{

View File

@ -1,7 +1,7 @@
using AxibugEmuOnline.Client.ClientCore;
using System;
using System.Collections.Generic;
using static AxibugEmuOnline.Client.ScreenScaler;
using static AxibugEmuOnline.Client.Settings.ScreenScaler;
namespace AxibugEmuOnline.Client
{

View File

@ -44,13 +44,13 @@ namespace AxibugEmuOnline.Client
private void Start()
{
CommandDispatcher.Instance.Current = CommandDispatcher.Instance.Normal;
CommandDispatcher.Instance.Mode = CommandListener.ScheduleType.Normal;
}
private void Update()
{
if (CommandDispatcher.Instance.Current == CommandDispatcher.Instance.Gaming && App.emu.Core.IsNull())
CommandDispatcher.Instance.Current = CommandDispatcher.Instance.Normal;
if (CommandDispatcher.Instance.Mode == CommandListener.ScheduleType.Gaming && App.emu.Core.IsNull())
CommandDispatcher.Instance.Mode = CommandListener.ScheduleType.Normal;
}
public void HideMainMenu()

View File

@ -147,7 +147,7 @@ namespace AxibugEmuOnline.Client
return dirty;
}
IKeyMapperChanger m_lastCS;
CommandListener.ScheduleType? m_lastCS;
private Action m_onClose;
/// <summary>
@ -214,8 +214,8 @@ namespace AxibugEmuOnline.Client
0.3f
).SetEase(Ease.OutCubic);
m_lastCS = CommandDispatcher.Instance.Current;
CommandDispatcher.Instance.Current = CommandDispatcher.Instance.Normal;
m_lastCS = CommandDispatcher.Instance.Mode;
CommandDispatcher.Instance.Mode = CommandListener.ScheduleType.Normal;
}
}
@ -263,7 +263,7 @@ namespace AxibugEmuOnline.Client
m_bPoped = false;
CommandDispatcher.Instance.Current = m_lastCS;
CommandDispatcher.Instance.Mode = m_lastCS.Value;
m_onClose?.Invoke();
m_onClose = null;

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
@ -14,8 +14,6 @@ namespace AxibugEmuOnline.Client
public static bool IsInputing { get; private set; }
protected override void OnShow(object param)
{
ValueTuple<Action<string>, string, string> t = (ValueTuple<Action<string>, string, string>)param;
@ -30,7 +28,7 @@ namespace AxibugEmuOnline.Client
base.Update();
IsInputing = m_input.isFocused;
if (IsInputing && Input.GetButtonDown("Submit"))
{
OnCmdEnter();

View File

@ -1,4 +1,5 @@
using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.Settings;
using UnityEngine;
using UnityEngine.UI;

View File

@ -1,4 +1,5 @@
using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.Settings;
using Coffee.UIExtensions;
using UnityEngine;

View File

@ -2,25 +2,20 @@
"dependencies": {
"com.unity.2d.sprite": "1.0.0",
"com.unity.ide.visualstudio": "2.0.22",
"com.unity.inputsystem": "1.11.2",
"com.unity.test-framework": "1.4.5",
"com.unity.ugui": "2.0.0",
"com.unity.modules.accessibility": "1.0.0",
"com.unity.modules.ai": "1.0.0",
"com.unity.modules.androidjni": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.cloth": "1.0.0",
"com.unity.modules.director": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.physics2d": "1.0.0",
"com.unity.modules.screencapture": "1.0.0",
"com.unity.modules.terrain": "1.0.0",
"com.unity.modules.terrainphysics": "1.0.0",
"com.unity.modules.tilemap": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.uielements": "1.0.0",
"com.unity.modules.umbra": "1.0.0",

View File

@ -8,10 +8,10 @@
},
"com.unity.ext.nunit": {
"version": "2.0.5",
"depth": 2,
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.cn"
"url": "https://packages.unity.com"
},
"com.unity.ide.visualstudio": {
"version": "2.0.22",
@ -20,18 +20,27 @@
"dependencies": {
"com.unity.test-framework": "1.1.9"
},
"url": "https://packages.unity.cn"
"url": "https://packages.unity.com"
},
"com.unity.inputsystem": {
"version": "1.11.2",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.modules.uielements": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.test-framework": {
"version": "1.4.5",
"depth": 1,
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ext.nunit": "2.0.3",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
},
"url": "https://packages.unity.cn"
"url": "https://packages.unity.com"
},
"com.unity.ugui": {
"version": "2.0.0",
@ -48,12 +57,6 @@
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.ai": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.androidjni": {
"version": "1.0.0",
"depth": 0,
@ -78,23 +81,6 @@
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.cloth": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.director": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.animation": "1.0.0"
}
},
"com.unity.modules.hierarchycore": {
"version": "1.0.0",
"depth": 1,
@ -119,12 +105,6 @@
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.particlesystem": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.physics": {
"version": "1.0.0",
"depth": 0,
@ -153,29 +133,6 @@
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.terrain": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.terrainphysics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.terrain": "1.0.0"
}
},
"com.unity.modules.tilemap": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics2d": "1.0.0"
}
},
"com.unity.modules.ui": {
"version": "1.0.0",
"depth": 0,

View File

@ -8,4 +8,6 @@ EditorBuildSettings:
- enabled: 1
path: Assets/Scene/AxibugEmuOnline.Client.unity
guid: eb0c18a619175384d95147898a43054b
m_configObjects: {}
m_configObjects:
com.unity.input.settings.actions: {fileID: -944628639613478452, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
m_UseUCBPForAssetBundles: 0

View File

@ -37,6 +37,38 @@ InputManager:
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Horizontal
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 1
- serializedVersion: 3
m_Name: Vertical
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 1
- serializedVersion: 3
m_Name: Horizontal
descriptiveName:
@ -69,3 +101,36 @@ InputManager:
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: HorizontalR
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 3
joyNum: 0
- serializedVersion: 3
m_Name: VerticalR
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: 0
snap: 0
invert: 0
type: 0
axis: 4
joyNum: 0
m_UsePhysicalKeys: 1

View File

@ -18,10 +18,11 @@ MonoBehaviour:
m_SeeAllPackageVersions: 0
m_DismissPreviewPackagesInUse: 0
oneTimeWarningShown: 0
oneTimeDeprecatedPopUpShown: 0
m_Registries:
- m_Id: main
m_Name:
m_Url: https://packages.unity.cn
m_Url: https://packages.unity.com
m_Scopes: []
m_IsDefault: 1
m_Capabilities: 7
@ -31,6 +32,6 @@ MonoBehaviour:
m_RegistryInfoDraft:
m_Modified: 0
m_ErrorMessage:
m_UserModificationsInstanceId: -892
m_OriginalInstanceId: -894
m_UserModificationsInstanceId: -882
m_OriginalInstanceId: -884
m_LoadAssets: 0