/// <summary> /// Remaps a XInput button mapped to a buton struct 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 XInputRemapButton(int timeoutSeconds, out float currentTimeout, ref byte buttonToMap, ref bool cancellationToken) { // Cast Controller to DInput Controller XInputController xInputController = (XInputController)Controller; // Retrieve Joystick State bool[] buttonState = xInputController.GetButtons(); // Initialize Timeout int pollAttempts = timeoutSeconds * MillisecondsInSecond / SleepTimePolling; int pollCounter = 0; // Poll the controller properties. while (pollCounter < pollAttempts) { // Get new JoystickState bool[] buttonStateNew = xInputController.GetButtons(); // Iterate over all buttons. for (int x = 0; x < buttonStateNew.Length; x++) { if (buttonState[x] != buttonStateNew[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> /// Parses a Mod Loader Controller Configuration. /// </summary> /// <param name="configLocation">States the location of the controller configuration.</param> /// <param name="controller">A DirectInput or XInput controller instance.</param> public ControllerCommon.IController ParseConfig(string configLocation, ControllerCommon.IController controller) { // Instantiate the individual mapping structs. ControllerCommon.AxisMapping axisMapping = new ControllerCommon.AxisMapping(); ControllerCommon.EmulationButtonMapping emulationMapping = new ControllerCommon.EmulationButtonMapping(); ControllerCommon.ButtonMapping buttonMapping = new ControllerCommon.ButtonMapping(); // Check if the config exists, if it doesn't, first write an empty config. if (!File.Exists(configLocation)) { // Check if directory exists first. // Unpack sample themes if (!Directory.Exists(Path.GetDirectoryName(configLocation))) { Directory.CreateDirectory(Path.GetDirectoryName(configLocation)); } // Write Sample Config File.WriteAllText(configLocation, SampleConfig.Sample); } // Read the controller configuration. _iniData = _iniParser.ReadFile(configLocation); // Read the controller port ID. controller.ControllerId = Convert.ToInt32(_iniData["Main Settings"]["Controller_Port"]); // Read the controller button mappings. #region Button Mappings buttonMapping.ButtonA = byte.Parse(_iniData["Button Mappings"]["Button_A"]); buttonMapping.ButtonB = byte.Parse(_iniData["Button Mappings"]["Button_B"]); buttonMapping.ButtonX = byte.Parse(_iniData["Button Mappings"]["Button_X"]); buttonMapping.ButtonY = byte.Parse(_iniData["Button Mappings"]["Button_Y"]); buttonMapping.ButtonLb = byte.Parse(_iniData["Button Mappings"]["Button_LB"]); buttonMapping.ButtonRb = byte.Parse(_iniData["Button Mappings"]["Button_RB"]); buttonMapping.ButtonLs = byte.Parse(_iniData["Button Mappings"]["Button_LS"]); buttonMapping.ButtonRs = byte.Parse(_iniData["Button Mappings"]["Button_RS"]); buttonMapping.ButtonBack = byte.Parse(_iniData["Button Mappings"]["Button_Back"]); buttonMapping.ButtonGuide = byte.Parse(_iniData["Button Mappings"]["Button_Guide"]); buttonMapping.ButtonStart = byte.Parse(_iniData["Button Mappings"]["Button_Start"]); #endregion // Read the controller axis emulation mappings. #region Emulation Mappings emulationMapping.DpadUp = byte.Parse(_iniData["Emulation Mapping"]["DPAD_UP"]); emulationMapping.DpadLeft = byte.Parse(_iniData["Emulation Mapping"]["DPAD_LEFT"]); emulationMapping.DpadRight = byte.Parse(_iniData["Emulation Mapping"]["DPAD_RIGHT"]); emulationMapping.DpadDown = byte.Parse(_iniData["Emulation Mapping"]["DPAD_DOWN"]); emulationMapping.RightTrigger = byte.Parse(_iniData["Emulation Mapping"]["Right_Trigger"]); emulationMapping.LeftTrigger = byte.Parse(_iniData["Emulation Mapping"]["Left_Trigger"]); emulationMapping.LeftStickUp = byte.Parse(_iniData["Emulation Mapping"]["Left_Stick_Up"]); emulationMapping.LeftStickLeft = byte.Parse(_iniData["Emulation Mapping"]["Left_Stick_Left"]); emulationMapping.LeftStickDown = byte.Parse(_iniData["Emulation Mapping"]["Left_Stick_Down"]); emulationMapping.LeftStickRight = byte.Parse(_iniData["Emulation Mapping"]["Left_Stick_Right"]); emulationMapping.RightStickUp = byte.Parse(_iniData["Emulation Mapping"]["Right_Stick_Up"]); emulationMapping.RightStickLeft = byte.Parse(_iniData["Emulation Mapping"]["Right_Stick_Left"]); emulationMapping.RightStickDown = byte.Parse(_iniData["Emulation Mapping"]["Right_Stick_Down"]); emulationMapping.RightStickRight = byte.Parse(_iniData["Emulation Mapping"]["Right_Stick_Right"]); #endregion // Read the controller axis mappings. #region Axis Mappings axisMapping.LeftStickX.SourceAxis = _iniData["Axis"]["Left_Stick_X"]; axisMapping.LeftStickX.DestinationAxis = ParseAxisName(_iniData["Axis Type"]["Left_Stick_X"]); axisMapping.LeftStickX.DeadZone = float.Parse(_iniData["Axis Deadzone"]["Left_Stick_X"]); axisMapping.LeftStickX.IsReversed = bool.Parse(_iniData["Axis Inverse"]["Left_Stick_X"]); axisMapping.LeftStickX.RadiusScale = float.Parse(_iniData["Radius Scale"]["Left_Stick_X"]); axisMapping.RightStickX.SourceAxis = _iniData["Axis"]["Right_Stick_X"]; axisMapping.RightStickX.DestinationAxis = ParseAxisName(_iniData["Axis Type"]["Right_Stick_X"]); axisMapping.RightStickX.DeadZone = float.Parse(_iniData["Axis Deadzone"]["Right_Stick_X"]); axisMapping.RightStickX.IsReversed = bool.Parse(_iniData["Axis Inverse"]["Right_Stick_X"]); axisMapping.RightStickX.RadiusScale = float.Parse(_iniData["Radius Scale"]["Right_Stick_X"]); axisMapping.LeftStickY.SourceAxis = _iniData["Axis"]["Left_Stick_Y"]; axisMapping.LeftStickY.DestinationAxis = ParseAxisName(_iniData["Axis Type"]["Left_Stick_Y"]); axisMapping.LeftStickY.DeadZone = float.Parse(_iniData["Axis Deadzone"]["Left_Stick_Y"]); axisMapping.LeftStickY.IsReversed = bool.Parse(_iniData["Axis Inverse"]["Left_Stick_Y"]); axisMapping.LeftStickY.RadiusScale = float.Parse(_iniData["Radius Scale"]["Left_Stick_Y"]); axisMapping.RightStickY.SourceAxis = _iniData["Axis"]["Right_Stick_Y"]; axisMapping.RightStickY.DestinationAxis = ParseAxisName(_iniData["Axis Type"]["Right_Stick_Y"]); axisMapping.RightStickY.DeadZone = float.Parse(_iniData["Axis Deadzone"]["Right_Stick_Y"]); axisMapping.RightStickY.IsReversed = bool.Parse(_iniData["Axis Inverse"]["Right_Stick_Y"]); axisMapping.RightStickY.RadiusScale = float.Parse(_iniData["Radius Scale"]["Right_Stick_Y"]); axisMapping.LeftTrigger.SourceAxis = _iniData["Axis"]["Left_Trigger"]; axisMapping.LeftTrigger.DestinationAxis = ParseAxisName(_iniData["Axis Type"]["Left_Trigger"]); axisMapping.LeftTrigger.DeadZone = float.Parse(_iniData["Axis Deadzone"]["Left_Trigger"]); axisMapping.LeftTrigger.IsReversed = bool.Parse(_iniData["Axis Inverse"]["Left_Trigger"]); axisMapping.LeftTrigger.RadiusScale = float.Parse(_iniData["Radius Scale"]["Left_Trigger"]); axisMapping.RightTrigger.SourceAxis = _iniData["Axis"]["Right_Trigger"]; axisMapping.RightTrigger.DestinationAxis = ParseAxisName(_iniData["Axis Type"]["Right_Trigger"]); axisMapping.RightTrigger.DeadZone = float.Parse(_iniData["Axis Deadzone"]["Right_Trigger"]); axisMapping.RightTrigger.IsReversed = bool.Parse(_iniData["Axis Inverse"]["Right_Trigger"]); axisMapping.RightTrigger.RadiusScale = float.Parse(_iniData["Radius Scale"]["Right_Trigger"]); #endregion // Assign Mappings back to Controller controller.AxisMapping = axisMapping; controller.ButtonMapping = buttonMapping; controller.EmulationMapping = emulationMapping; // Return controller. return(controller); }