/// <summary> /// Main input forwarding function/loop (input thread). /// </summary> public void ThreadFunc() { try { this.BeginInvoke((Action)(() => { SetInfoText("Running feeder.", Color.Green); })); XInputManager.InputState stateData; vJoyManager.AxisExtents XLimit = vJoyObj.GetAxisExtents(HID_USAGES.HID_USAGE_X); vJoyManager.AxisExtents YLimit = vJoyObj.GetAxisExtents(HID_USAGES.HID_USAGE_Y); vJoyManager.AxisExtents RXLimit = vJoyObj.GetAxisExtents(HID_USAGES.HID_USAGE_RX); vJoyManager.AxisExtents RYLimit = vJoyObj.GetAxisExtents(HID_USAGES.HID_USAGE_RY); vJoyManager.AxisExtents SL0Limit = vJoyObj.GetAxisExtents(HID_USAGES.HID_USAGE_SL0); vJoyManager.AxisExtents SL1Limit = vJoyObj.GetAxisExtents(HID_USAGES.HID_USAGE_SL1); List <bool> finalButtonStates = new List <bool>(); int ButtonCount = vJoyObj.GetButtonCount(vJoyObj.ActiveVJoyID); while (finalButtonStates.Count < ButtonCount) { finalButtonStates.Add(false); } Dictionary <HID_USAGES, int> finalHidValues = new Dictionary <HID_USAGES, int>(); Dictionary <HID_USAGES, vJoyManager.AxisExtents> HidExtents = new Dictionary <HID_USAGES, vJoyManager.AxisExtents>(); List <HID_USAGES> AvailableHidValues = vJoyObj.GetExistingAxes(vJoyObj.ActiveVJoyID); foreach (HID_USAGES axis in AvailableHidValues) { finalHidValues.Add(axis, 0); HidExtents.Add(axis, vJoyObj.GetAxisExtents(axis)); } List <int> xInputMinRanges = new List <int>(); List <int> xInputMaxRanges = new List <int>(); for (int i = 0; i < XInputManager.InputCount; i++) { int[] inputRange = XInputManager.GetAxisLimitsForInput((XInputManager.Inputs)i); xInputMinRanges.Add(inputRange[0]); xInputMaxRanges.Add(inputRange[1]); } int tempHidValue = 0; while (bIsActive) { // Thread body stateData = XInputObj.GetState(); for (int i = 0; i < finalButtonStates.Count; i++) { finalButtonStates[i] = false; } for (int i = 0; i < AvailableHidValues.Count; i++) { finalHidValues[AvailableHidValues[i]] = 0; } foreach (InputMapping inputMap in InputMappings) { switch (inputMap.Type) { case InputMapping.MappingType.Button: finalButtonStates[(int)inputMap.ButtonIndex - 1] |= XInputManager.GetInputStateButtonValueFromInputType(ref stateData, inputMap.XInput); break; case InputMapping.MappingType.Axis: tempHidValue = XInputManager.GetInputStateAxisValueFromInputType(ref stateData, inputMap.XInput); tempHidValue = RemapValueToVJoy(tempHidValue, xInputMinRanges[(int)inputMap.XInput], xInputMaxRanges[(int)inputMap.XInput], HidExtents[inputMap.vJoyAxis]); finalHidValues[inputMap.vJoyAxis] = Math.Max(finalHidValues[inputMap.vJoyAxis], tempHidValue); break; default: break; } } for (uint i = 0; i < finalButtonStates.Count; i++) { vJoyObj.SetButton(i + 1, finalButtonStates[(int)i]); } for (int i = 0; i < AvailableHidValues.Count; i++) { HID_USAGES Axis = AvailableHidValues[i]; vJoyObj.SetAxis(Axis, finalHidValues[Axis]); } Thread.Sleep(16); // The delay between updates in ms (16 = ~60fps) } // Thread done/canceled } catch (ThreadAbortException) { // Thread aborted } }
/// <summary> /// Remaps a value from XInput range to VJoy range. This is necessary because differences in axis values (e.g. negative short values, 0-255 ranges etc.). /// </summary> /// <param name="Value">The value to convert.</param> /// <param name="XMin">The minimum value of Value.</param> /// <param name="XMax">The maximum value of Value.</param> /// <param name="vJoyLimit">Struct defining the vJoy target limits.</param> /// <returns></returns> private int RemapValueToVJoy(int Value, int XMin, int XMax, vJoyManager.AxisExtents vJoyLimit) { float value = (float)vJoyLimit.Min + ((float)Value - ((float)XMin)) / (((float)XMax) - ((float)XMin)) * ((float)vJoyLimit.Max - (float)vJoyLimit.Min); return((int)Math.Round(value)); }