diff --git a/DS4Windows/DS4Control/ControlSerivce.cs b/DS4Windows/DS4Control/ControlSerivce.cs index 0808aa7..c4fb59a 100644 --- a/DS4Windows/DS4Control/ControlSerivce.cs +++ b/DS4Windows/DS4Control/ControlSerivce.cs @@ -13,21 +13,22 @@ namespace DS4Windows public class ControlService { public X360Device x360Bus; - public DS4Device[] DS4Controllers = new DS4Device[4]; - public Mouse[] touchPad = new Mouse[4]; + public const int DS4_CONTROLLER_COUNT = 4; + public DS4Device[] DS4Controllers = new DS4Device[DS4_CONTROLLER_COUNT]; + public Mouse[] touchPad = new Mouse[DS4_CONTROLLER_COUNT]; private bool running = false; - private DS4State[] MappedState = new DS4State[4]; - private DS4State[] CurrentState = new DS4State[4]; - private DS4State[] PreviousState = new DS4State[4]; - public DS4StateExposed[] ExposedState = new DS4StateExposed[4]; + private DS4State[] MappedState = new DS4State[DS4_CONTROLLER_COUNT]; + private DS4State[] CurrentState = new DS4State[DS4_CONTROLLER_COUNT]; + private DS4State[] PreviousState = new DS4State[DS4_CONTROLLER_COUNT]; + public DS4StateExposed[] ExposedState = new DS4StateExposed[DS4_CONTROLLER_COUNT]; public bool recordingMacro = false; public event EventHandler Debug = null; public bool eastertime = false; private int eCode = 0; bool[] buttonsdown = { false, false, false, false }; List dcs = new List(); - bool[] held = new bool[4]; - int[] oldmouse = new int[4] { -1, -1, -1, -1 }; + bool[] held = new bool[DS4_CONTROLLER_COUNT]; + int[] oldmouse = new int[DS4_CONTROLLER_COUNT] { -1, -1, -1, -1 }; SoundPlayer sp = new SoundPlayer(); private class X360Data @@ -460,7 +461,7 @@ namespace DS4Windows DS4Device device = (DS4Device)sender; int ind = -1; - for (int i = 0, arlength = DS4Controllers.Length; ind == -1 && i < arlength; i++) + for (int i = 0, arlength = DS4_CONTROLLER_COUNT; ind == -1 && i < arlength; i++) if (device == DS4Controllers[i]) ind = i; @@ -504,7 +505,7 @@ namespace DS4Windows */ cState = Mapping.SetCurveAndDeadzone(ind, cState); if (!recordingMacro && (!string.IsNullOrEmpty(tempprofilename[ind]) || - containsCustomAction(ind) || containsCustomExtras(ind) || getProfileActions(ind).Count > 0)) + containsCustomAction(ind) || containsCustomExtras(ind) || getProfileActionCount(ind) > 0)) { Mapping.MapCustom(ind, cState, MappedState[ind], ExposedState[ind], touchPad[ind], this); cState = MappedState[ind]; diff --git a/DS4Windows/DS4Control/Mapping.cs b/DS4Windows/DS4Control/Mapping.cs index 86ff54b..b71b79d 100644 --- a/DS4Windows/DS4Control/Mapping.cs +++ b/DS4Windows/DS4Control/Mapping.cs @@ -785,7 +785,7 @@ namespace DS4Windows int MouseDeltaY = 0; SyntheticState deviceState = Mapping.deviceState[device]; - if (containsCustomAction(device) && (getProfileActions(device).Count > 0 || !string.IsNullOrEmpty(tempprofilename[device]))) + if (getProfileActionCount(device) > 0 || !string.IsNullOrEmpty(tempprofilename[device])) MapCustomAction(device, cState, MappedState, eState, tp, ctrl); if (ctrl.DS4Controllers[device] == null) return; @@ -1193,7 +1193,7 @@ namespace DS4Windows private static bool IfAxisIsNotModified(int device, bool shift, DS4Controls dc) { - return shift ? false : GetDS4Action(device, dc.ToString(), false) == null; + return shift ? false : GetDS4Action(device, dc, false) == null; } public static async void MapCustomAction(int device, DS4State cState, DS4State MappedState, DS4StateExposed eState, Mouse tp, ControlService ctrl) { @@ -1204,8 +1204,10 @@ namespace DS4Windows foreach (string actionname in profileActions) { //DS4KeyType keyType = getShiftCustomKeyType(device, customKey.Key); - SpecialAction action = GetAction(actionname); - int index = GetActionIndexOf(actionname); + //SpecialAction action = GetAction(actionname); + //int index = GetActionIndexOf(actionname); + SpecialAction action = GetProfileAction(device, actionname); + int index = GetProfileActionIndexOf(device, actionname); int actionDoneCount = actionDone.Count; if (actionDoneCount < index + 1) actionDone.Add(new ActionState()); @@ -1214,7 +1216,7 @@ namespace DS4Windows double time = 0.0; //If a key or button is assigned to the trigger, a key special action is used like //a quick tap to use and hold to use the regular custom button/key - bool triggerToBeTapped = action.type == "Key" && action.trigger.Count == 1 && + bool triggerToBeTapped = action.typeID == SpecialAction.ActionTypeId.None && action.trigger.Count == 1 && GetDS4Action(device, action.trigger[0], false) == null; if (!(action.name == "null" || index < 0)) { @@ -1292,7 +1294,7 @@ namespace DS4Windows bool utriggeractivated = true; int uTriggerCount = action.uTrigger.Count; - if (action.type == "Key" && uTriggerCount > 0) + if (action.typeID == SpecialAction.ActionTypeId.Key && uTriggerCount > 0) { foreach (DS4Controls dc in action.uTrigger) { @@ -1305,7 +1307,7 @@ namespace DS4Windows if (action.pressRelease) utriggeractivated = !utriggeractivated; } - if (triggeractivated && action.type == "Program") + if (triggeractivated && action.typeID == SpecialAction.ActionTypeId.Program) { if (!actionDone[index].dev[device]) { @@ -1316,7 +1318,7 @@ namespace DS4Windows Process.Start(action.details); } } - else if (triggeractivated && action.type == "Profile") + else if (triggeractivated && action.typeID == SpecialAction.ActionTypeId.Profile) { if (!actionDone[index].dev[device] && string.IsNullOrEmpty(tempprofilename[device])) { @@ -1342,7 +1344,7 @@ namespace DS4Windows return; } } - else if (triggeractivated && action.type == "Macro") + else if (triggeractivated && action.typeID == SpecialAction.ActionTypeId.Macro) { if (!actionDone[index].dev[device]) { @@ -1355,7 +1357,7 @@ namespace DS4Windows else EndMacro(device, macroControl, String.Join("/", action.macro), DS4Controls.None); } - else if (triggeractivated && action.type == "Key") + else if (triggeractivated && action.typeID == SpecialAction.ActionTypeId.Key) { if (uTriggerCount == 0 || (uTriggerCount > 0 && untriggerindex[device] == -1 && !actionDone[index].dev[device])) { @@ -1380,7 +1382,7 @@ namespace DS4Windows InputMethods.performKeyPress(key); } } - else if (uTriggerCount > 0 && utriggeractivated && action.type == "Key") + else if (uTriggerCount > 0 && utriggeractivated && action.typeID == SpecialAction.ActionTypeId.Key) { if (untriggerindex[device] > -1 && !actionDone[index].dev[device]) { @@ -1394,7 +1396,7 @@ namespace DS4Windows InputMethods.performKeyRelease(key); } } - else if (triggeractivated && action.type == "DisconnectBT") + else if (triggeractivated && action.typeID == SpecialAction.ActionTypeId.DisconnectBT) { DS4Device d = ctrl.DS4Controllers[device]; if (!d.Charging) @@ -1418,7 +1420,7 @@ namespace DS4Windows return; } } - else if (triggeractivated && action.type == "BatteryCheck") + else if (triggeractivated && action.typeID == SpecialAction.ActionTypeId.BatteryCheck) { string[] dets = action.details.Split('|'); if (dets.Length == 1) @@ -1444,7 +1446,7 @@ namespace DS4Windows } actionDone[index].dev[device] = true; } - else if (!triggeractivated && action.type == "BatteryCheck") + else if (!triggeractivated && action.typeID == SpecialAction.ActionTypeId.BatteryCheck) { if (actionDone[index].dev[device]) { @@ -1460,7 +1462,7 @@ namespace DS4Windows actionDone[index].dev[device] = false; } } - else if (action.type == "XboxGameDVR" || action.type == "MultiAction") + else if (action.typeID == SpecialAction.ActionTypeId.XboxGameDVR || action.typeID == SpecialAction.ActionTypeId.MultiAction) { /*if (getCustomButton(device, action.trigger[0]) != X360Controls.Unbound) getCustomButtons(device)[action.trigger[0]] = X360Controls.Unbound; @@ -1505,7 +1507,7 @@ namespace DS4Windows string macro = ""; if (tappedOnce) //single tap { - if (action.type == "MultiAction") + if (action.typeID == SpecialAction.ActionTypeId.MultiAction) { macro = dets[0]; } @@ -1530,7 +1532,7 @@ namespace DS4Windows } else if (firstTouch && (DateTime.UtcNow - pastTime) > TimeSpan.FromMilliseconds(1000)) //helddown { - if (action.type == "MultiAction") + if (action.typeID == SpecialAction.ActionTypeId.MultiAction) { macro = dets[1]; } @@ -1551,7 +1553,7 @@ namespace DS4Windows } else if (secondtouchbegin) //if double tap { - if (action.type == "MultiAction") + if (action.typeID == SpecialAction.ActionTypeId.MultiAction) { macro = dets[2]; } @@ -1592,7 +1594,7 @@ namespace DS4Windows } } - if (utriggeractivated && action.type == "Profile") + if (utriggeractivated && action.typeID == SpecialAction.ActionTypeId.Profile) { if ((action.controls == action.ucontrols && !actionDone[index].dev[device]) || //if trigger and end trigger are the same action.controls != action.ucontrols) diff --git a/DS4Windows/DS4Control/ScpUtil.cs b/DS4Windows/DS4Control/ScpUtil.cs index 7a633cc..49aa040 100644 --- a/DS4Windows/DS4Control/ScpUtil.cs +++ b/DS4Windows/DS4Control/ScpUtil.cs @@ -429,6 +429,14 @@ namespace DS4Windows public static string[] ProfilePath => m_Config.profilePath; public static bool[] DistanceProfiles = m_Config.distanceProfiles; public static List[] ProfileActions => m_Config.profileActions; + public static int getProfileActionCount(int index) + { + return m_Config.profileActionCount[index]; + } + public static void calculateProfileActionCount(int index) + { + m_Config.profileActionCount[index] = m_Config.profileActions[index].Count; + } public static List getProfileActions(int index) { return m_Config.profileActions[index]; @@ -490,6 +498,13 @@ namespace DS4Windows return -1; } + public static int GetProfileActionIndexOf(int device, string name) + { + int index = -1; + m_Config.profileActionIndexDict[device].TryGetValue(name, out index); + return index; + } + public static SpecialAction GetAction(string name) { foreach (SpecialAction sA in m_Config.actions) @@ -498,6 +513,24 @@ namespace DS4Windows return new SpecialAction("null", "null", "null", "null"); } + public static SpecialAction GetProfileAction(int device, string name) + { + SpecialAction sA = new SpecialAction("null", "null", "null", "null"); + m_Config.profileActionDict[device].TryGetValue(name, out sA); + return sA; + } + + public static void calculateProfileActionDicts(int device) + { + m_Config.profileActionDict[device].Clear(); + m_Config.profileActionIndexDict[device].Clear(); + + foreach (string actionname in m_Config.profileActions[device]) + { + m_Config.profileActionDict[device].Add(actionname, Global.GetAction(actionname)); + m_Config.profileActionIndexDict[device].Add(actionname, Global.GetActionIndexOf(actionname)); + } + } /*public static X360Controls getCustomButton(int device, DS4Controls controlName) => m_Config.GetCustomButton(device, controlName); @@ -736,6 +769,9 @@ namespace DS4Windows public Dictionary[] shiftCustomMapButtons = { null, null, null, null, null }; public Dictionary[] shiftCustomMapExtras = { null, null, null, null, null };*/ public List[] profileActions = { null, null, null, null, null }; + public int[] profileActionCount = { 0, 0, 0, 0, 0 }; + public Dictionary[] profileActionDict = { new Dictionary(), new Dictionary(), new Dictionary(), new Dictionary(), new Dictionary() }; + public Dictionary[] profileActionIndexDict = { new Dictionary(), new Dictionary(), new Dictionary(), new Dictionary(), new Dictionary() }; public bool downloadLang = true; public bool useWhiteIcon; public bool flashWhenLate = true; @@ -767,6 +803,7 @@ namespace DS4Windows shiftCustomMapExtras[i] = new Dictionary();*/ profileActions[i] = new List(); profileActions[i].Add("Disconnect Controller"); + profileActionCount[i] = profileActions[i].Count; } } @@ -1627,6 +1664,14 @@ namespace DS4Windows containsCustomAction[device] = false; containsCustomExtras[device] = false; + profileActionCount[device] = profileActions[device].Count; + profileActionDict[device].Clear(); + profileActionIndexDict[device].Clear(); + foreach (string actionname in profileActions[device]) + { + profileActionDict[device].Add(actionname, Global.GetAction(actionname)); + profileActionIndexDict[device].Add(actionname, Global.GetActionIndexOf(actionname)); + } DS4KeyType keyType; ushort wvk; @@ -2478,9 +2523,12 @@ namespace DS4Windows public class SpecialAction { + public enum ActionTypeId { None, Key, Program, Profile, Macro, DisconnectBT, BatteryCheck, MultiAction, XboxGameDVR } + public string name; public List trigger = new List(); public string type; + public ActionTypeId typeID; public string controls; public List macro = new List(); public string details; @@ -2494,25 +2542,16 @@ namespace DS4Windows { this.name = name; this.type = type; + this.typeID = ActionTypeId.None; this.controls = controls; delayTime = delay; string[] ctrls = controls.Split('/'); foreach (string s in ctrls) trigger.Add(getDS4ControlsByName(s)); - if (type == "Macro") - { - string[] macs = details.Split('/'); - foreach (string s in macs) - { - int v; - if (int.TryParse(s, out v)) - macro.Add(v); - } - if (extras.Contains("Scan Code")) - keyType |= DS4KeyType.ScanCode; - } - else if (type == "Key") + + if (type == "Key") { + typeID = ActionTypeId.Key; this.details = details.Split(' ')[0]; if (!string.IsNullOrEmpty(extras)) { @@ -2528,12 +2567,43 @@ namespace DS4Windows } else if (type == "Program") { + typeID = ActionTypeId.Program; this.details = details; if (extras != string.Empty) extra = extras; } + else if (type == "Profile") + { + typeID = ActionTypeId.Profile; + } + else if (type == "Macro") + { + typeID = ActionTypeId.Macro; + string[] macs = details.Split('/'); + foreach (string s in macs) + { + int v; + if (int.TryParse(s, out v)) + macro.Add(v); + } + if (extras.Contains("Scan Code")) + keyType |= DS4KeyType.ScanCode; + } + else if (type == "DisconnectBT") + { + typeID = ActionTypeId.DisconnectBT; + } + else if (type == "BatteryCheck") + { + typeID = ActionTypeId.BatteryCheck; + } + else if (type == "MultiAction") + { + typeID = ActionTypeId.MultiAction; + } else if (type == "XboxGameDVR") { + this.typeID = ActionTypeId.XboxGameDVR; string[] dets = details.Split(','); List macros = new List(); //string dets = ""; diff --git a/DS4Windows/DS4Forms/Options.cs b/DS4Windows/DS4Forms/Options.cs index 493d99d..c7a3cd1 100644 --- a/DS4Windows/DS4Forms/Options.cs +++ b/DS4Windows/DS4Forms/Options.cs @@ -1080,6 +1080,8 @@ namespace DS4Windows if (lvi.Checked) pactions.Add(lvi.Text); ProfileActions[device] = pactions; + calculateProfileActionCount(device); + calculateProfileActionDicts(device); pnlTPMouse.Visible = rBTPMouse.Checked; pnlSAMouse.Visible = rBSAMouse.Checked; fLPTiltControls.Visible = rBSAControls.Checked; @@ -2010,6 +2012,8 @@ namespace DS4Windows if (lvi != null && lvi.Checked) pactions.Add(lvi.Text); ProfileActions[device] = pactions; + calculateProfileActionCount(device); + calculateProfileActionDicts(device); /*if (lVActions.Items.Count >= 50) { btnNewAction.Enabled = false;