using AxibugEmuOnline.Client.ClientCore; using AxibugEmuOnline.Client.Common; using AxibugEmuOnline.Client.Event; using NUnit.Framework.Internal; using System.Collections.Generic; using System.Linq; using UnityEngine; using VirtualNes.Core; namespace AxibugEmuOnline.Client { public class NesControllerMapper : IControllerSetuper { public Controller Controller0 { get; } = new Controller(0); public Controller Controller1 { get; } = new Controller(1); public Controller Controller2 { get; } = new Controller(2); public Controller Controller3 { get; } = new Controller(3); private readonly EnumButtonType[] m_states = new EnumButtonType[4]; public ControllerState CreateState() { m_states[0] = m_states[1] = m_states[2] = m_states[3] = 0; if (Controller0.ConnectSlot.HasValue) m_states[Controller0.ConnectSlot.Value] = Controller0.GetButtons(); else if (Controller0.AnyButtonDown()) Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 0); if (Controller1.ConnectSlot.HasValue) m_states[Controller1.ConnectSlot.Value] = Controller1.GetButtons(); else if (Controller1.AnyButtonDown()) Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 1); if (Controller2.ConnectSlot.HasValue) m_states[Controller2.ConnectSlot.Value] = Controller2.GetButtons(); else if (Controller2.AnyButtonDown()) Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 2); if (Controller3.ConnectSlot.HasValue) m_states[Controller3.ConnectSlot.Value] = Controller3.GetButtons(); else if (Controller3.AnyButtonDown()) Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 3); var result = new ControllerState(m_states); return result; } public void SetConnect(uint? con0ToSlot = null, uint? con1ToSlot = null, uint? con2ToSlot = null, uint? con3ToSlot = null) { Controller0.ConnectSlot = con0ToSlot; Controller1.ConnectSlot = con1ToSlot; Controller2.ConnectSlot = con2ToSlot; Controller3.ConnectSlot = con3ToSlot; } public int? GetSlotConnectingControllerIndex(int slotIndex) { if (Controller0.ConnectSlot.HasValue && Controller0.ConnectSlot.Value == slotIndex) return 0; else if (Controller1.ConnectSlot.HasValue && Controller1.ConnectSlot.Value == slotIndex) return 1; else if (Controller2.ConnectSlot.HasValue && Controller2.ConnectSlot.Value == slotIndex) return 2; else if (Controller3.ConnectSlot.HasValue && Controller3.ConnectSlot.Value == slotIndex) return 3; else return null; } public IController GetSlotConnectingController(int slotIndex) { if (Controller0.ConnectSlot.HasValue && Controller0.ConnectSlot.Value == slotIndex) return Controller0; else if (Controller1.ConnectSlot.HasValue && Controller1.ConnectSlot.Value == slotIndex) return Controller1; else if (Controller2.ConnectSlot.HasValue && Controller2.ConnectSlot.Value == slotIndex) return Controller2; else if (Controller3.ConnectSlot.HasValue && Controller3.ConnectSlot.Value == slotIndex) return Controller3; else return null; } //static HashSet s_temp = new HashSet(4); //低版本不能这样初始化 static HashSet s_temp = new HashSet(); public uint? GetFreeSlotIndex() { s_temp.Clear(); s_temp.Add(0); s_temp.Add(1); s_temp.Add(2); s_temp.Add(3); if (Controller0.ConnectSlot.HasValue) s_temp.Remove(Controller0.ConnectSlot.Value); if (Controller1.ConnectSlot.HasValue) s_temp.Remove(Controller1.ConnectSlot.Value); if (Controller2.ConnectSlot.HasValue) s_temp.Remove(Controller2.ConnectSlot.Value); if (Controller3.ConnectSlot.HasValue) s_temp.Remove(Controller3.ConnectSlot.Value); if (s_temp.Count > 0) return s_temp.First(); else return null; } public void LetControllerConnect(int conIndex, uint slotIndex) { Controller targetController; switch (conIndex) { case 0: targetController = Controller0; break; case 1: targetController = Controller1; break; case 2: targetController = Controller2; break; 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; targetController.ConnectSlot = slotIndex; Eventer.Instance.PostEvent(EEvent.OnControllerConnectChanged); } /// /// Nes控制器 /// public class Controller : IController { /// /// 控制器编号 /// 此编号并非对应游戏中的player1,player2,player3,player4,仅仅作为本地4个手柄的实例 /// [0,3] /// public int ControllerIndex { get; } /// /// 指示该手柄连接的手柄插槽 /// 这个值代表了该手柄在实际游戏中控制的Player /// [0,3] 例外:为空代表未连接 /// 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(); 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; } //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; // } //} } ///// ///// NES控制器按键类 ///// //public class Button //{ // /// 所属控制器 // readonly Controller m_hostController; // /// 按键 // readonly EnumButtonType m_buttonType; // /// 按键监听器 // KeyListener m_keyListener; // /// 指示按钮是否正在按下状态 // public bool IsPressing => m_keyListener.IsPressing(); // /// 指示按钮是否被按下 // public bool IsDown => m_keyListener.IsDown(); // public Button(Controller controller, EnumButtonType buttonType) // { // m_hostController = controller; // m_buttonType = buttonType; // CreateListener(); // } // /// // /// 采集按钮按下状态 // /// // /// // 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; // } // /// 从配置字符串构建 // 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); // //} //} } }