/// <summary> /// Retrieves the configuration file location for the individual controller. /// If using an XInput controller, pass null. /// </summary> private void GetConfigLocation(DInputController dInputController) { // Get Configuration Details LoaderConfigParser.Config config = LoaderConfigParser.ParseConfig(); // Set the device type ConfigType = config.DirectInputConfigType; // If XInput/DInput if (DeviceType == InputDeviceType.DirectInput) { // If InstanceGUID or ProductGUID. if (ConfigType == DirectInputConfigType.InstanceGUID) { ConfigurationFileLocation = LoaderPaths.GetModLoaderConfigDirectory() + "/Controllers/Instances/" + dInputController.Information.InstanceGuid + ".json"; } else if (ConfigType == DirectInputConfigType.ProductGUID) { ConfigurationFileLocation = LoaderPaths.GetModLoaderConfigDirectory() + "/Controllers/" + PathSanitizer.ForceValidFilePath(dInputController.Information.ProductName) + ".json"; } } else if (DeviceType == InputDeviceType.XInput) { ConfigurationFileLocation = LoaderPaths.GetModLoaderConfigDirectory() + "/Controllers/XInput/" + "Controller_" + XInputPort + ".json"; } }
/// <summary> /// This is the constructor for DirectInput devices. See class description for information /// about this class. /// </summary> /// <param name="deviceType">The type of the device (DirectInput)</param> /// <param name="dInputController">The directInput controller instance.</param> public Remapper(InputDeviceType deviceType, DInputController dInputController) { DeviceType = deviceType; Controller = dInputController; // Retrieve the configuration location. GetConfigLocation(dInputController); }
/// <summary> /// Remaps a DirectInput button to the controller button map struct. /// </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="buttonToMap">Specififies the button variable where the index of the pressed button will be written to. Either a member of Controller_Button_Mapping or Emulation_Button_Mapping</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 button has successfully been assigned by the user.</returns> private bool DInputRemapButton(int timeoutSeconds, out float currentTimeout, ref byte buttonToMap, ref bool cancellationToken) { // Cast Controller to DInput Controller DInputController dInputController = (DInputController)Controller; // Retrieve Joystick State JoystickState joystickState = dInputController.GetCurrentState(); // Initialize Timeout int pollAttempts = timeoutSeconds * MillisecondsInSecond / SleepTimePolling; int pollCounter = 0; // Poll the controller properties. while (pollCounter < pollAttempts) { // Get new JoystickState JoystickState joystickStateNew = dInputController.GetCurrentState(); // Iterate over all buttons. for (int x = 0; x < joystickState.Buttons.Length; x++) { if (joystickState.Buttons[x] != joystickStateNew.Buttons[x]) { // Retrieve the button mapping. ControllerCommon.ButtonMapping buttonMapping = Controller.InputMappings.ButtonMapping; // Assign requested button. buttonToMap = (byte)x; // Reassign button mapping. Controller.InputMappings.ButtonMapping = buttonMapping; // Set timeout to 0 currentTimeout = 0; // Return 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); } // Assign the current timeout. 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); }