/// <summary> /// A function called on each frame. /// </summary> public void OnUpdateFrame() { // Brake handle if (brakeHandleMoved) { KeyUp(this, new InputEventArgs(Controls[brakeCommands[(int)InputTranslator.BrakeNotch]])); brakeHandleMoved = false; } // Power handle if (powerHandleMoved) { KeyUp(this, new InputEventArgs(Controls[50 + powerCommands[(int)InputTranslator.PowerNotch]])); powerHandleMoved = false; } // Buttons for (int i = 0; i < ButtonProperties.Length; i++) { KeyUp(this, new InputEventArgs(Controls[100 + ButtonProperties[i].Command])); } InputTranslator.Update(); if (InputTranslator.IsControllerConnected) { // Brake handle if (InputTranslator.BrakeNotch != InputTranslator.PreviousBrakeNotch || loading) { KeyDown(this, new InputEventArgs(Controls[brakeCommands[(int)InputTranslator.BrakeNotch]])); brakeHandleMoved = true; } // Power handle if (InputTranslator.PowerNotch != InputTranslator.PreviousPowerNotch || loading) { KeyDown(this, new InputEventArgs(Controls[50 + powerCommands[(int)InputTranslator.PowerNotch]])); powerHandleMoved = true; } // Buttons for (int i = 0; i < ButtonProperties.Length; i++) { if (InputTranslator.ControllerButtons[i] == OpenTK.Input.ButtonState.Pressed && ButtonProperties[i].Timer <= 0) { KeyDown(this, new InputEventArgs(Controls[100 + ButtonProperties[i].Command])); if (ButtonProperties[i].Repeats) { ButtonProperties[i].Timer = repeatInterval; } else { ButtonProperties[i].Timer = repeatDelay; ButtonProperties[i].Repeats = true; } } } } loading = false; }
/// <summary> /// A function called when the plugin is loaded. /// </summary> /// <param name="fileSystem">The instance of FileSytem class</param> /// <returns>Whether the plugin has been loaded successfully.</returns> public bool Load(FileSystem fileSystem) { FileSystem = fileSystem; //HACK: In order to avoid meddling with a shipped interface (or making this field public and increasing the mess), let's grab it via reflection CurrentHost = (HostInterface)typeof(FileSystem).GetField("currentHost", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(fileSystem); if (loading) { InputTranslator.Load(); } // Start thread for LibUsb-based controllers LibUsb.LibUsbThread = new Thread(LibUsb.LibUsbLoop); LibUsb.LibUsbThread.Start(); // Initialize the array of button properties for (int i = 0; i < ButtonProperties.Length; i++) { ButtonProperties[i] = new ButtonProp(); } // Load settings from the config file LoadConfig(); // Create the config form configForm = new Config(); // Define the list of commands // We allocate 50 slots per handle plus one slot per command int commandCount = Translations.CommandInfos.Length; Controls = new InputControl[100 + commandCount]; // Brake notches for (int i = 0; i < 50; i++) { Controls[i].Command = Translations.Command.BrakeAnyNotch; Controls[i].Option = i; } // Power notches for (int i = 50; i < 100; i++) { Controls[i].Command = Translations.Command.PowerAnyNotch; Controls[i].Option = i - 50; } // Other commands for (int i = 0; i < commandCount; i++) { Controls[i + 100].Command = (Translations.Command)i; } // Configure the mappings for the buttons and notches ConfigureMappings(); return(true); }
private void timer1_Tick(object sender, EventArgs e) { InputTranslator.Update(); //grab a random control, as we need something from the UI thread to check for invoke //WinForms is a pain if (buttonCalibrate.InvokeRequired) { buttonCalibrate.Invoke((MethodInvoker)UpdateInterface); } else { UpdateInterface(); } }
private void Config_Shown(object sender, EventArgs e) { // Add connected devices to device list InputTranslator.Update(); ListControllers(); // Try to select the current device if (controllerList.Contains(InputTranslator.ActiveControllerGuid)) { deviceBox.SelectedIndex = controllerList.IndexOf(InputTranslator.ActiveControllerGuid); } // Set command boxes buttonselectBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[(int)InputTranslator.ControllerButton.Select].Command; buttonstartBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[(int)InputTranslator.ControllerButton.Start].Command; buttonaBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[(int)InputTranslator.ControllerButton.A].Command; buttonbBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[(int)InputTranslator.ControllerButton.B].Command; buttoncBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[(int)InputTranslator.ControllerButton.C].Command; buttondBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[(int)InputTranslator.ControllerButton.D].Command; buttonupBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[(int)InputTranslator.ControllerButton.Up].Command; buttondownBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[(int)InputTranslator.ControllerButton.Down].Command; buttonleftBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[(int)InputTranslator.ControllerButton.Left].Command; buttonrightBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[(int)InputTranslator.ControllerButton.Right].Command; buttonpedalBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[(int)InputTranslator.ControllerButton.Pedal].Command; buttonldoorBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[(int)InputTranslator.ControllerButton.LDoor].Command; buttonrdoorBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[(int)InputTranslator.ControllerButton.RDoor].Command; // Set checkboxes convertnotchesCheck.Checked = DenshaDeGoInput.ConvertNotches; minmaxCheck.Checked = DenshaDeGoInput.KeepMaxMin; holdbrakeCheck.Checked = DenshaDeGoInput.MapHoldBrake; minmaxCheck.Enabled = DenshaDeGoInput.ConvertNotches; // Start timer Timer1.Enabled = true; // Translate the interface to the current language UpdateTranslation(); }
private void Config_Shown(object sender, EventArgs e) { // Add connected devices to device list InputTranslator.Update(); ListControllers(); // Try to select the current device if (ControllerList.Contains(InputTranslator.activeControllerGuid)) { deviceBox.SelectedIndex = ControllerList.IndexOf(InputTranslator.activeControllerGuid); } // Set command boxes buttonselectBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[0].Command; buttonstartBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[1].Command; buttonaBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[2].Command; buttonbBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[3].Command; buttoncBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[4].Command; buttondBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[5].Command; buttonupBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[6].Command; buttondownBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[7].Command; buttonleftBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[8].Command; buttonrightBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[9].Command; buttonpedalBox.SelectedIndex = DenshaDeGoInput.ButtonProperties[10].Command; // Set checkboxes convertnotchesCheck.Checked = DenshaDeGoInput.convertNotches; minmaxCheck.Checked = DenshaDeGoInput.keepMaxMin; holdbrakeCheck.Checked = DenshaDeGoInput.mapHoldBrake; minmaxCheck.Enabled = DenshaDeGoInput.convertNotches; // Start timer timer1.Enabled = true; // Translate the interface to the current language UpdateTranslation(); }
/// <summary> /// Configures the correct mappings for the buttons and notches according to the user settings. /// </summary> internal void ConfigureMappings() { int controllerBrakeNotches = InputTranslator.GetControllerBrakeNotches(); int controllerPowerNotches = InputTranslator.GetControllerPowerNotches(); if (!ConvertNotches) { // The notches are not supposed to be converted // Brake notches if (MapHoldBrake && TrainSpecs.HasHoldBrake) { brakeCommands[0] = 0; brakeCommands[1] = 100 + (int)Translations.Command.HoldBrake; for (int i = 2; i < controllerBrakeNotches + 2; i++) { brakeCommands[i] = i - 1; } } else { for (int i = 0; i < controllerBrakeNotches + 2; i++) { brakeCommands[i] = i; } } // Emergency brake, only if the train has the same or less notches than the controller if (TrainSpecs.BrakeNotches <= controllerBrakeNotches) { brakeCommands[(int)InputTranslator.BrakeNotches.Emergency] = 100 + (int)Translations.Command.BrakeEmergency; } // Power notches for (int i = 0; i < controllerPowerNotches; i++) { powerCommands[i] = i; } } else { // The notches are supposed to be converted // Brake notches if (MapHoldBrake && TrainSpecs.HasHoldBrake) { double brakeStep = (TrainSpecs.BrakeNotches - 1) / (double)(controllerBrakeNotches - 1); brakeCommands[0] = 0; brakeCommands[1] = 100 + (int)Translations.Command.HoldBrake; for (int i = 2; i < controllerBrakeNotches + 1; i++) { brakeCommands[i] = (int)Math.Round(brakeStep * (i - 1), MidpointRounding.AwayFromZero); if (i > 0 && brakeCommands[i] == 0) { brakeCommands[i] = 1; } if (KeepMaxMin && i == 2) { brakeCommands[i] = 1; } if (KeepMaxMin && i == controllerBrakeNotches) { brakeCommands[i] = TrainSpecs.BrakeNotches - 1; } } } else { double brakeStep = TrainSpecs.BrakeNotches / (double)controllerBrakeNotches; for (int i = 0; i < controllerBrakeNotches + 1; i++) { brakeCommands[i] = (int)Math.Round(brakeStep * i, MidpointRounding.AwayFromZero); if (i > 0 && brakeCommands[i] == 0) { brakeCommands[i] = 1; } if (KeepMaxMin && i == 1) { brakeCommands[i] = 1; } if (KeepMaxMin && i == controllerBrakeNotches) { brakeCommands[i] = TrainSpecs.BrakeNotches; } } } // Emergency brake brakeCommands[(int)InputTranslator.BrakeNotches.Emergency] = 100 + (int)Translations.Command.BrakeEmergency; // Power notches double powerStep = TrainSpecs.PowerNotches / (double)controllerPowerNotches; for (int i = 0; i < controllerPowerNotches + 1; i++) { powerCommands[i] = (int)Math.Round(powerStep * i, MidpointRounding.AwayFromZero); if (i > 0 && powerCommands[i] == 0) { powerCommands[i] = 1; } if (KeepMaxMin && i == 1) { powerCommands[i] = 1; } if (KeepMaxMin && i == controllerPowerNotches) { powerCommands[i] = TrainSpecs.PowerNotches; } } } }
private void deviceBox_SelectedIndexChanged(object sender, EventArgs e) { InputTranslator.Update(); InputTranslator.ActiveControllerGuid = controllerList[deviceBox.SelectedIndex]; }
private void timer1_Tick(object sender, EventArgs e) { InputTranslator.Update(); UpdateInterface(); }
/// <summary> /// A function called on each frame. /// </summary> public void OnUpdateFrame() { // Store previous state of the buttons OpenTK.Input.ButtonState[] previousButtonState = (OpenTK.Input.ButtonState[])InputTranslator.ControllerButtons.Clone(); // Brake handle (release) if (brakeHandleMoved) { KeyUp(this, new InputEventArgs(Controls[brakeCommands[(int)InputTranslator.BrakeNotch]])); brakeHandleMoved = false; } // Power handle (release) if (powerHandleMoved) { KeyUp(this, new InputEventArgs(Controls[50 + powerCommands[(int)InputTranslator.PowerNotch]])); powerHandleMoved = false; } // Update input from controller InputTranslator.Update(); // Configure the mappings on the first frame to fit the controller's features if (loading) { ConfigureMappings(); } // Buttons (release) for (int i = 0; i < ButtonCommands.Length; i++) { if (InputTranslator.ControllerButtons[i] == OpenTK.Input.ButtonState.Released && previousButtonState[i] == OpenTK.Input.ButtonState.Pressed) { KeyUp(this, new InputEventArgs(Controls[100 + ButtonCommands[i]])); } } if (InputTranslator.IsControllerConnected) { // Brake handle (apply) if (InputTranslator.BrakeNotch != InputTranslator.PreviousBrakeNotch || loading) { KeyDown(this, new InputEventArgs(Controls[brakeCommands[(int)InputTranslator.BrakeNotch]])); brakeHandleMoved = true; } // Power handle (apply) if (InputTranslator.PowerNotch != InputTranslator.PreviousPowerNotch || loading) { KeyDown(this, new InputEventArgs(Controls[50 + powerCommands[(int)InputTranslator.PowerNotch]])); powerHandleMoved = true; } // Buttons (apply) for (int i = 0; i < ButtonCommands.Length; i++) { if (InputTranslator.ControllerButtons[i] == OpenTK.Input.ButtonState.Pressed && previousButtonState[i] == OpenTK.Input.ButtonState.Released) { KeyDown(this, new InputEventArgs(Controls[100 + ButtonCommands[i]])); } } } loading = false; }
/// <summary> /// Launches the calibration wizard to guess the button indices used by the adapter. /// </summary> internal static void Calibrate() { string[] input = { "SELECT", "START", "A", "B", "C", Translations.QuickReferences.HandleEmergency, Translations.QuickReferences.HandleBrake + "6", Translations.QuickReferences.HandleBrake + "5", Translations.QuickReferences.HandleBrake + "4", Translations.QuickReferences.HandleBrake + "8", Translations.QuickReferences.HandlePower + "5", Translations.QuickReferences.HandlePowerNull, Translations.QuickReferences.HandlePower + "2", Translations.QuickReferences.HandlePower + "1", Translations.QuickReferences.HandlePower + "5", }; List <OpenTK.Input.ButtonState> ButtonState = InputTranslator.GetButtonsState(); List <OpenTK.Input.ButtonState> PreviousButtonState; List <HatPosition> HatPositions = InputTranslator.GetHatPositions(); List <HatPosition> PreviousHatPositions; List <int> ignored = new List <int>(); // Button calibration for (int i = 0; i < 5; i++) { MessageBox.Show(Translations.GetInterfaceString("denshadego_calibrate_button").Replace("[button]", input[i])); PreviousButtonState = ButtonState; ButtonState = InputTranslator.GetButtonsState(); int index = InputTranslator.GetDifferentPressedIndex(PreviousButtonState, ButtonState, ignored); ignored.Add(index); switch (i) { case 0: ButtonIndex.Select = index; break; case 1: ButtonIndex.Start = index; break; case 2: ButtonIndex.A = index; break; case 3: ButtonIndex.B = index; break; case 4: ButtonIndex.C = index; break; } } // The brake handle needs to be moved to EMG to initialise properly MessageBox.Show(Translations.GetInterfaceString("denshadego_calibrate_brake").Replace("[notch]", input[5])); // Brake handle calibration for (int i = 6; i < 10; i++) { MessageBox.Show(Translations.GetInterfaceString("denshadego_calibrate_brake").Replace("[notch]", input[i])); PreviousButtonState = ButtonState; ButtonState = InputTranslator.GetButtonsState(); int index = InputTranslator.GetDifferentPressedIndex(PreviousButtonState, ButtonState, ignored); ignored.Add(index); switch (i) { case 6: ButtonIndex.Brake4 = index; break; case 7: ButtonIndex.Brake1 = index; break; case 8: ButtonIndex.Brake2 = index; break; case 9: ButtonIndex.Brake3 = index; break; } } // The power handle needs to be moved to P5 and N to initialise properly MessageBox.Show(Translations.GetInterfaceString("denshadego_calibrate_power").Replace("[notch]", input[10])); MessageBox.Show(Translations.GetInterfaceString("denshadego_calibrate_power").Replace("[notch]", input[11])); // Clear previous data before calibrating the power handle ignored.Clear(); ButtonState = InputTranslator.GetButtonsState(); HatPositions = InputTranslator.GetHatPositions(); // Power handle calibration for (int i = 12; i < 15; i++) { MessageBox.Show(Translations.GetInterfaceString("denshadego_calibrate_power").Replace("[notch]", input[i])); PreviousButtonState = ButtonState; PreviousHatPositions = HatPositions; ButtonState = InputTranslator.GetButtonsState(); HatPositions = InputTranslator.GetHatPositions(); int index = InputTranslator.GetDifferentPressedIndex(PreviousButtonState, ButtonState, ignored); ignored.Add(index); int hat = InputTranslator.GetChangedHat(PreviousHatPositions, HatPositions); if (hat != -1 && i != 13) { // If a hat has changed, it means the converter is mapping the direction buttons usesHat = true; hatIndex = hat; } else { usesHat = false; } switch (i) { case 12: ButtonIndex.Power2 = index; break; case 13: ButtonIndex.Power1 = index; break; case 14: ButtonIndex.Power3 = index; break; } } }