/// <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);
        }
Exemple #2
0
        /// <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);
        }