/// <summary> /// Waits for the user to move an axis and retrieves the last pressed axis. /// Accepts any axis as input. Returns the read-in axis. /// </summary> /// <param name="timeoutSeconds">The timeout in seconds for the controller assignment.</param> /// <param name="currentTimeout">The current amount of time left in seconds, use this to update the GUI.</param> /// <param name="mappingEntry">Specififies the mapping entry containing the axis to be remapped.</param> /// <param name="cancellationToken">The method polls on this boolean such that if it is set to true, the method will exit.</param> /// <returns>True if a new axis has been assigned to the current mapping entry.</returns> public bool RemapAxis(int timeoutSeconds, out float currentTimeout, ControllerCommon.AxisMappingEntry mappingEntry, ref bool cancellationToken) { // Retrieve the object type of the controller. Type controllerType = Controller.GetType(); // If it's a DirectInput controller. if (controllerType == typeof(DInputController)) { return(DInputRemapAxis(timeoutSeconds, out currentTimeout, mappingEntry, ref cancellationToken)); } if (controllerType == typeof(XInputController)) { return(XInputRemapAxis(timeoutSeconds, out currentTimeout, mappingEntry, ref cancellationToken)); } currentTimeout = 0; return(false); }
/// <summary> /// Remaps the axis of an XInput controller. /// </summary> private bool XInputRemapAxis(int timeoutSeconds, out float currentTimeout, ControllerCommon.AxisMappingEntry mappingEntry, ref bool cancellationToken) { // Cast Controller to DInput Controller XInputController xInputController = (XInputController)Controller; // Retrieve Joystick State State joystickState = xInputController.Controller.GetState(); // Initialize Timeout // MillisecondsInSecond / SleepTimePolling = Amount of polls/ticks per second. int pollAttempts = timeoutSeconds * MillisecondsInSecond / SleepTimePolling; int pollCounter = 0; // Get % Change for recognition of input. int percentDelta = (int)(XInputController.MaxAnalogStickRangeXinput / 100.0F * PercentageAxisDelta); int percentDeltaTrigger = (int)(XInputController.MaxTriggerRangeXinput / 100.0F * PercentageAxisDelta); // Poll the controller properties. while (pollCounter < pollAttempts) { // Get new JoystickState State joystickStateNew = xInputController.Controller.GetState(); // Get Deltas (Differences) int leftStickX = joystickState.Gamepad.LeftThumbX - joystickStateNew.Gamepad.LeftThumbX; int leftStickY = joystickState.Gamepad.LeftThumbY - joystickStateNew.Gamepad.LeftThumbY; int rightStickX = joystickState.Gamepad.RightThumbX - joystickStateNew.Gamepad.RightThumbX; int rightStickY = joystickState.Gamepad.RightTrigger - joystickStateNew.Gamepad.RightThumbY; int leftTrigger = joystickState.Gamepad.LeftTrigger - joystickStateNew.Gamepad.LeftTrigger; int rightTrigger = joystickState.Gamepad.RightTrigger - joystickStateNew.Gamepad.RightTrigger; // Iterate over all axis. if (leftStickX < -1 * percentDelta) { mappingEntry.IsReversed = true; mappingEntry.DestinationAxis = ControllerCommon.ControllerAxis.LeftStickX; currentTimeout = 0; return(true); } if (leftStickX > percentDelta) { mappingEntry.IsReversed = false; mappingEntry.DestinationAxis = ControllerCommon.ControllerAxis.LeftStickX; currentTimeout = 0; return(true); } if (rightStickX < -1 * percentDelta) { mappingEntry.IsReversed = true; mappingEntry.DestinationAxis = ControllerCommon.ControllerAxis.RightStickX; currentTimeout = 0; return(true); } if (rightStickX > percentDelta) { mappingEntry.IsReversed = false; mappingEntry.DestinationAxis = ControllerCommon.ControllerAxis.RightStickX; currentTimeout = 0; return(true); } if (leftStickY < -1 * percentDelta) { mappingEntry.IsReversed = true; mappingEntry.DestinationAxis = ControllerCommon.ControllerAxis.LeftStickY; currentTimeout = 0; return(true); } if (leftStickY > percentDelta) { mappingEntry.IsReversed = false; mappingEntry.DestinationAxis = ControllerCommon.ControllerAxis.LeftStickY; currentTimeout = 0; return(true); } if (rightStickY < -1 * percentDelta) { mappingEntry.IsReversed = true; mappingEntry.DestinationAxis = ControllerCommon.ControllerAxis.RightStickY; currentTimeout = 0; return(true); } if (rightStickY > percentDelta) { mappingEntry.IsReversed = false; mappingEntry.DestinationAxis = ControllerCommon.ControllerAxis.RightStickY; currentTimeout = 0; return(true); } if (leftTrigger < -1 * percentDeltaTrigger) { mappingEntry.IsReversed = true; mappingEntry.DestinationAxis = ControllerCommon.ControllerAxis.LeftTrigger; currentTimeout = 0; return(true); } if (leftTrigger > percentDeltaTrigger) { mappingEntry.IsReversed = false; mappingEntry.DestinationAxis = ControllerCommon.ControllerAxis.LeftTrigger; currentTimeout = 0; return(true); } if (rightTrigger < -1 * percentDeltaTrigger) { mappingEntry.IsReversed = true; mappingEntry.DestinationAxis = ControllerCommon.ControllerAxis.RightTrigger; currentTimeout = 0; return(true); } if (rightTrigger > percentDeltaTrigger) { mappingEntry.IsReversed = false; mappingEntry.DestinationAxis = ControllerCommon.ControllerAxis.RightTrigger; currentTimeout = 0; return(true); } // Increase counter, calculate new time left. // SleepTimePolling / MillisecondsInSecond = Amount of time per 1 tick (pollCounter) // pollCOunter = current amount of ticks done. pollCounter += 1; currentTimeout = (float)timeoutSeconds - (pollCounter * (SleepTimePolling / MillisecondsInSecond)); // Check exit condition if (cancellationToken) { return(false); } // Sleep Thread.Sleep(SleepTimePolling); } // Set current timeout (suppress compiler) currentTimeout = 0; return(false); }
/// <summary> /// Remaps the axis of a DirectInput controller. /// </summary> /// <returns>True if a new axis has been assigned to the current mapping entry.</returns> private bool DInputRemapAxis(int timeoutSeconds, out float currentTimeout, ControllerCommon.AxisMappingEntry mappingEntry, ref bool cancellationToken) { // Cast Controller to DInput Controller DInputController dInputController = (DInputController)Controller; // Get type of JoystickState Type stateType = typeof(JoystickState); // Retrieve Joystick State JoystickState joystickState = dInputController.GetCurrentState(); // Initialize Timeout int pollAttempts = timeoutSeconds * MillisecondsInSecond / SleepTimePolling; int pollCounter = 0; // Get % Change for recognition of input. int percentDelta = (int)(DInputManager.AxisMaxValue / 100.0F * PercentageAxisDelta); // If the axis is relative, instead set the delta very low, as relative acceleration based inputs cannot be scaled to a range. if (dInputController.Properties.AxisMode == DeviceAxisMode.Relative) { // Set low delta percentDelta = 50; // Additionally reset every property. foreach (PropertyInfo propertyInfo in stateType.GetProperties()) { if (propertyInfo.PropertyType == typeof(int)) { propertyInfo.SetValue(joystickState, 0); } } } // Poll the controller properties. while (pollCounter < pollAttempts) { // Get new JoystickState JoystickState joystickStateNew = dInputController.GetCurrentState(); // Iterate over all properties. foreach (PropertyInfo propertyInfo in stateType.GetProperties()) { // If the property type is an integer. (This covers, nearly all possible axis readings and all in common controllers.) if (propertyInfo.PropertyType == typeof(int)) { // Calculate the change of value from last time. int valueDelta = (int)propertyInfo.GetValue(joystickState) - (int)propertyInfo.GetValue(joystickStateNew); // If the value has changed over X amount if (valueDelta < -1 * percentDelta) { //mappingEntry.isReversed = true; mappingEntry.SourceAxis = propertyInfo.Name; currentTimeout = 0; return(true); } if (valueDelta > percentDelta) { //mappingEntry.isReversed = false; mappingEntry.SourceAxis = propertyInfo.Name; currentTimeout = 0; return(true); } } } // Increase counter, calculate new time left. pollCounter += 1; currentTimeout = timeoutSeconds - pollCounter * SleepTimePolling / (float)MillisecondsInSecond; // Check exit condition if (cancellationToken) { return(false); } // Sleep Thread.Sleep(SleepTimePolling); } // Set current timeout (suppress compiler) currentTimeout = 0; mappingEntry.SourceAxis = "Null"; return(false); }