1 //Simplified BSD License (BSD-2-Clause)
2 //
3 //Copyright (c) 2020-2021, Marc Riera, The OpenBVE Project
4 //
5 //Redistribution and use in source and binary forms, with or without
6 //modification, are permitted provided that the following conditions are met:
7 //
8 //1. Redistributions of source code must retain the above copyright notice, this
9 //   list of conditions and the following disclaimer.
10 //2. Redistributions in binary form must reproduce the above copyright notice,
11 //   this list of conditions and the following disclaimer in the documentation
12 //   and/or other materials provided with the distribution.
13 //
14 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15 //ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 //DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18 //ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 //ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 //(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 
25 using System;
26 using System.Collections.Generic;
27 using System.Linq;
28 using System.Windows.Forms;
29 using System.Drawing;
30 using System.Timers;
31 using OpenTK.Input;
32 using OpenBveApi.Interface;
33 using Timer = System.Timers.Timer;
34 
35 namespace DenshaDeGoInput
36 {
37 	public partial class Config : Form
38 	{
39 		/// <summary>
40 		/// Internal list of connected controllers.
41 		/// </summary>
42 		private List<Guid> controllerList = new List<Guid>();
43 
44 		private Timer Timer1;
45 
Config()46 		public Config()
47 		{
48 			InitializeComponent();
49 
50 			// Load language files
51 			Translations.LoadLanguageFiles(OpenBveApi.Path.CombineDirectory(DenshaDeGoInput.FileSystem.DataFolder, "Languages"));
52 
53 			// Populate command boxes
54 			buttonselectBox.Items.Add(Translations.GetInterfaceString("denshadego_command_none"));
55 			buttonstartBox.Items.Add(Translations.GetInterfaceString("denshadego_command_none"));
56 			buttonaBox.Items.Add(Translations.GetInterfaceString("denshadego_command_none"));
57 			buttonbBox.Items.Add(Translations.GetInterfaceString("denshadego_command_none"));
58 			buttoncBox.Items.Add(Translations.GetInterfaceString("denshadego_command_none"));
59 			buttondBox.Items.Add(Translations.GetInterfaceString("denshadego_command_none"));
60 			buttonupBox.Items.Add(Translations.GetInterfaceString("denshadego_command_none"));
61 			buttondownBox.Items.Add(Translations.GetInterfaceString("denshadego_command_none"));
62 			buttonleftBox.Items.Add(Translations.GetInterfaceString("denshadego_command_none"));
63 			buttonrightBox.Items.Add(Translations.GetInterfaceString("denshadego_command_none"));
64 			buttonpedalBox.Items.Add(Translations.GetInterfaceString("denshadego_command_none"));
65 			buttonldoorBox.Items.Add(Translations.GetInterfaceString("denshadego_command_none"));
66 			buttonrdoorBox.Items.Add(Translations.GetInterfaceString("denshadego_command_none"));
67 			Translations.CommandInfo[] commands = Translations.CommandInfos.OrderBy(o => o.Command).ToArray();
68 			for (int i = 0; i < Translations.CommandInfos.Length; i++)
69 			{
70 				buttonselectBox.Items.Add(commands[i].Name);
71 				buttonstartBox.Items.Add(commands[i].Name);
72 				buttonaBox.Items.Add(commands[i].Name);
73 				buttonbBox.Items.Add(commands[i].Name);
74 				buttoncBox.Items.Add(commands[i].Name);
75 				buttondBox.Items.Add(commands[i].Name);
76 				buttonupBox.Items.Add(commands[i].Name);
77 				buttondownBox.Items.Add(commands[i].Name);
78 				buttonleftBox.Items.Add(commands[i].Name);
79 				buttonrightBox.Items.Add(commands[i].Name);
80 				buttonpedalBox.Items.Add(commands[i].Name);
81 				buttonldoorBox.Items.Add(commands[i].Name);
82 				buttonrdoorBox.Items.Add(commands[i].Name);
83 			}
84 
85 			Timer1 = new Timer {Interval = 100};
86 			Timer1.Elapsed += timer1_Tick;
87 		}
88 
89 		/// <summary>
90 		/// Adds the available controllers to the device dropdown list.
91 		/// </summary>
ListControllers()92 		private void ListControllers()
93 		{
94 			// Clear the internal and visible lists
95 			controllerList.Clear();
96 			deviceBox.Items.Clear();
97 
98 			foreach (KeyValuePair<Guid, Controller> controller in InputTranslator.Controllers)
99 			{
100 				if (controller.Value.IsConnected)
101 				{
102 					controllerList.Add(controller.Key);
103 					deviceBox.Items.Add(controller.Value.ControllerName);
104 				}
105 			}
106 
107 			// Adjust the width of the device dropdown to prevent truncation
108 			deviceBox.DropDownWidth = deviceBox.Width;
109 			foreach (var item in deviceBox.Items)
110 			{
111 				int currentItemWidth = (int)deviceBox.CreateGraphics().MeasureString(item.ToString(), deviceBox.Font).Width;
112 				if (currentItemWidth > deviceBox.DropDownWidth)
113 				{
114 					deviceBox.DropDownWidth = currentItemWidth;
115 				}
116 			}
117 		}
118 
119 		/// <summary>
120 		/// Updates the interface to reflect the input from the controller.
121 		/// </summary>
UpdateInterface()122 		private void UpdateInterface()
123 		{
124 			if (InputTranslator.IsControllerConnected)
125 			{
126 				switch (InputTranslator.BrakeNotch)
127 				{
128 					case InputTranslator.BrakeNotches.Released:
129 						label_brake.Text = Translations.GetInterfaceString("denshadego_label_brake").Replace("[notch]", Translations.QuickReferences.HandleBrakeNull);
130 						break;
131 					case InputTranslator.BrakeNotches.Emergency:
132 						label_brake.Text = Translations.GetInterfaceString("denshadego_label_brake").Replace("[notch]", Translations.QuickReferences.HandleEmergency);
133 						break;
134 					default:
135 						label_brake.Text = Translations.GetInterfaceString("denshadego_label_brake").Replace("[notch]", Translations.QuickReferences.HandleBrake + (int)InputTranslator.BrakeNotch);
136 						break;
137 				}
138 
139 				switch (InputTranslator.PowerNotch)
140 				{
141 					case InputTranslator.PowerNotches.N:
142 						label_power.Text = Translations.GetInterfaceString("denshadego_label_power").Replace("[notch]", Translations.QuickReferences.HandlePowerNull);
143 						break;
144 					default:
145 						label_power.Text = Translations.GetInterfaceString("denshadego_label_power").Replace("[notch]", Translations.QuickReferences.HandlePower + (int)InputTranslator.PowerNotch);
146 						break;
147 				}
148 
149 				label_select.ForeColor = InputTranslator.ControllerButtons[(int)InputTranslator.ControllerButton.Select] == OpenTK.Input.ButtonState.Pressed ? Color.White : Color.Black;
150 				label_start.ForeColor = InputTranslator.ControllerButtons[(int)InputTranslator.ControllerButton.Start] == OpenTK.Input.ButtonState.Pressed ? Color.White : Color.Black;
151 				label_a.ForeColor = InputTranslator.ControllerButtons[(int)InputTranslator.ControllerButton.A] == OpenTK.Input.ButtonState.Pressed ? Color.White : Color.Black;
152 				label_b.ForeColor = InputTranslator.ControllerButtons[(int)InputTranslator.ControllerButton.B] == OpenTK.Input.ButtonState.Pressed ? Color.White : Color.Black;
153 				label_c.ForeColor = InputTranslator.ControllerButtons[(int)InputTranslator.ControllerButton.C] == OpenTK.Input.ButtonState.Pressed ? Color.White : Color.Black;
154 				label_d.ForeColor = InputTranslator.ControllerButtons[(int)InputTranslator.ControllerButton.D] == OpenTK.Input.ButtonState.Pressed ? Color.White : Color.Black;
155 				label_up.ForeColor = InputTranslator.ControllerButtons[(int)InputTranslator.ControllerButton.Up] == OpenTK.Input.ButtonState.Pressed ? Color.White : Color.Black;
156 				label_down.ForeColor = InputTranslator.ControllerButtons[(int)InputTranslator.ControllerButton.Down] == OpenTK.Input.ButtonState.Pressed ? Color.White : Color.Black;
157 				label_left.ForeColor = InputTranslator.ControllerButtons[(int)InputTranslator.ControllerButton.Left] == OpenTK.Input.ButtonState.Pressed ? Color.White : Color.Black;
158 				label_right.ForeColor = InputTranslator.ControllerButtons[(int)InputTranslator.ControllerButton.Right] == OpenTK.Input.ButtonState.Pressed ? Color.White : Color.Black;
159 				label_pedal.ForeColor = InputTranslator.ControllerButtons[(int)InputTranslator.ControllerButton.Pedal] == OpenTK.Input.ButtonState.Pressed ? Color.White : Color.Black;
160 				label_ldoor.ForeColor = InputTranslator.ControllerButtons[(int)InputTranslator.ControllerButton.LDoor] == OpenTK.Input.ButtonState.Pressed ? Color.White : Color.Black;
161 				label_rdoor.ForeColor = InputTranslator.ControllerButtons[(int)InputTranslator.ControllerButton.RDoor] == OpenTK.Input.ButtonState.Pressed ? Color.White : Color.Black;
162 
163 				buttonCalibrate.Visible = InputTranslator.Controllers[InputTranslator.ActiveControllerGuid].RequiresCalibration;
164 				label_select.Visible = InputTranslator.Controllers[InputTranslator.ActiveControllerGuid].Buttons.HasFlag(Controller.ControllerButtons.Select);
165 				label_start.Visible = InputTranslator.Controllers[InputTranslator.ActiveControllerGuid].Buttons.HasFlag(Controller.ControllerButtons.Start);
166 				label_a.Visible = InputTranslator.Controllers[InputTranslator.ActiveControllerGuid].Buttons.HasFlag(Controller.ControllerButtons.A);
167 				label_b.Visible = InputTranslator.Controllers[InputTranslator.ActiveControllerGuid].Buttons.HasFlag(Controller.ControllerButtons.B);
168 				label_c.Visible = InputTranslator.Controllers[InputTranslator.ActiveControllerGuid].Buttons.HasFlag(Controller.ControllerButtons.C);
169 				label_d.Visible = InputTranslator.Controllers[InputTranslator.ActiveControllerGuid].Buttons.HasFlag(Controller.ControllerButtons.D);
170 				label_up.Visible = InputTranslator.Controllers[InputTranslator.ActiveControllerGuid].Buttons.HasFlag(Controller.ControllerButtons.DPad);
171 				label_down.Visible = InputTranslator.Controllers[InputTranslator.ActiveControllerGuid].Buttons.HasFlag(Controller.ControllerButtons.DPad);
172 				label_left.Visible = InputTranslator.Controllers[InputTranslator.ActiveControllerGuid].Buttons.HasFlag(Controller.ControllerButtons.DPad);
173 				label_right.Visible = InputTranslator.Controllers[InputTranslator.ActiveControllerGuid].Buttons.HasFlag(Controller.ControllerButtons.DPad);
174 				label_pedal.Visible = InputTranslator.Controllers[InputTranslator.ActiveControllerGuid].Buttons.HasFlag(Controller.ControllerButtons.Pedal);
175 				label_ldoor.Visible = InputTranslator.Controllers[InputTranslator.ActiveControllerGuid].Buttons.HasFlag(Controller.ControllerButtons.LDoor);
176 				label_rdoor.Visible = InputTranslator.Controllers[InputTranslator.ActiveControllerGuid].Buttons.HasFlag(Controller.ControllerButtons.RDoor);
177 			}
178 		}
179 
180 		/// <summary>
181 		/// Retranslates the configuration interface.
182 		/// </summary>
UpdateTranslation()183 		private void UpdateTranslation()
184 		{
185 			Text = Translations.GetInterfaceString("denshadego_config_title");
186 			deviceInputBox.Text = Translations.GetInterfaceString("denshadego_input_section");
187 			buttonCalibrate.Text = Translations.GetInterfaceString("denshadego_calibration_button");
188 			label_device.Text = Translations.GetInterfaceString("denshadego_device");
189 			buttonMappingBox.Text = Translations.GetInterfaceString("denshadego_button_section");
190 			handleMappingBox.Text = Translations.GetInterfaceString("denshadego_handle_section");
191 			convertnotchesCheck.Text = Translations.GetInterfaceString("denshadego_option_convert");
192 			minmaxCheck.Text = Translations.GetInterfaceString("denshadego_option_keep_minmax");
193 			holdbrakeCheck.Text = Translations.GetInterfaceString("denshadego_option_holdbrake");
194 			buttonSave.Text = Translations.GetInterfaceString("denshadego_save_button");
195 			buttonCancel.Text = Translations.GetInterfaceString("denshadego_cancel_button");
196 
197 			buttonselectBox.Items[0] = Translations.GetInterfaceString("denshadego_command_none");
198 			buttonstartBox.Items[0] = Translations.GetInterfaceString("denshadego_command_none");
199 			buttonaBox.Items[0] = Translations.GetInterfaceString("denshadego_command_none");
200 			buttonbBox.Items[0] = Translations.GetInterfaceString("denshadego_command_none");
201 			buttoncBox.Items[0] = Translations.GetInterfaceString("denshadego_command_none");
202 			buttondBox.Items[0] = Translations.GetInterfaceString("denshadego_command_none");
203 			buttonupBox.Items[0] = Translations.GetInterfaceString("denshadego_command_none");
204 			buttondownBox.Items[0] = Translations.GetInterfaceString("denshadego_command_none");
205 			buttonleftBox.Items[0] = Translations.GetInterfaceString("denshadego_command_none");
206 			buttonrightBox.Items[0] = Translations.GetInterfaceString("denshadego_command_none");
207 			buttonpedalBox.Items[0] = Translations.GetInterfaceString("denshadego_command_none");
208 			buttonldoorBox.Items[0] = Translations.GetInterfaceString("denshadego_command_none");
209 			buttonldoorBox.Items[0] = Translations.GetInterfaceString("denshadego_command_none");
210 
211 			label_up.Text = Translations.GetInterfaceString("denshadego_label_up");
212 			label_down.Text = Translations.GetInterfaceString("denshadego_label_down");
213 			label_left.Text = Translations.GetInterfaceString("denshadego_label_left");
214 			label_right.Text = Translations.GetInterfaceString("denshadego_label_right");
215 			label_pedal.Text = Translations.GetInterfaceString("denshadego_label_pedal");
216 			label_ldoor.Text = Translations.GetInterfaceString("denshadego_label_ldoor");
217 			label_rdoor.Text = Translations.GetInterfaceString("denshadego_label_rdoor");
218 			label_buttonup.Text = Translations.GetInterfaceString("denshadego_label_up");
219 			label_buttondown.Text = Translations.GetInterfaceString("denshadego_label_down");
220 			label_buttonleft.Text = Translations.GetInterfaceString("denshadego_label_left");
221 			label_buttonright.Text = Translations.GetInterfaceString("denshadego_label_right");
222 			label_buttonpedal.Text = Translations.GetInterfaceString("denshadego_label_pedal");
223 			label_buttonldoor.Text = Translations.GetInterfaceString("denshadego_label_ldoor");
224 			label_buttonrdoor.Text = Translations.GetInterfaceString("denshadego_label_rdoor");
225 
226 			linkLabel_driver.Text = Translations.GetInterfaceString("denshadego_linkLabel_driver");
227 		}
228 
Config_Shown(object sender, EventArgs e)229 		private void Config_Shown(object sender, EventArgs e)
230 		{
231 			// Add connected devices to device list
232 			InputTranslator.Update();
233 			ListControllers();
234 
235 			// Try to select the current device
236 			if (controllerList.Contains(InputTranslator.ActiveControllerGuid))
237 			{
238 				deviceBox.SelectedIndex = controllerList.IndexOf(InputTranslator.ActiveControllerGuid);
239 			}
240 
241 			// Set command boxes
242 			buttonselectBox.SelectedIndex = DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.Select];
243 			buttonstartBox.SelectedIndex = DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.Start];
244 			buttonaBox.SelectedIndex = DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.A];
245 			buttonbBox.SelectedIndex = DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.B];
246 			buttoncBox.SelectedIndex = DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.C];
247 			buttondBox.SelectedIndex = DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.D];
248 			buttonupBox.SelectedIndex = DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.Up];
249 			buttondownBox.SelectedIndex = DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.Down];
250 			buttonleftBox.SelectedIndex = DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.Left];
251 			buttonrightBox.SelectedIndex = DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.Right];
252 			buttonpedalBox.SelectedIndex = DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.Pedal];
253 			buttonldoorBox.SelectedIndex = DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.LDoor];
254 			buttonrdoorBox.SelectedIndex = DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.RDoor];
255 
256 
257 			// Set checkboxes
258 			convertnotchesCheck.Checked = DenshaDeGoInput.ConvertNotches;
259 			minmaxCheck.Checked = DenshaDeGoInput.KeepMaxMin;
260 			holdbrakeCheck.Checked = DenshaDeGoInput.MapHoldBrake;
261 			minmaxCheck.Enabled = DenshaDeGoInput.ConvertNotches;
262 			// Start timer
263 			Timer1.Enabled = true;
264 
265 			// Translate the interface to the current language
266 			UpdateTranslation();
267 		}
268 
Config_FormClosed(Object sender, FormClosedEventArgs e)269 		private void Config_FormClosed(Object sender, FormClosedEventArgs e)
270 		{
271 			// Reload the previous config and close the config dialog
272 			DenshaDeGoInput.LoadConfig();
273 			Timer1.Enabled = false;
274 		}
275 
deviceBox_SelectedIndexChanged(object sender, EventArgs e)276 		private void deviceBox_SelectedIndexChanged(object sender, EventArgs e)
277 		{
278 			InputTranslator.Update();
279 			InputTranslator.ActiveControllerGuid = controllerList[deviceBox.SelectedIndex];
280 		}
281 
buttonselectBox_SelectedIndexChanged(object sender, EventArgs e)282 		private void buttonselectBox_SelectedIndexChanged(object sender, EventArgs e)
283 		{
284 			DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.Select] = buttonselectBox.SelectedIndex;
285 		}
286 
buttonstartBox_SelectedIndexChanged(object sender, EventArgs e)287 		private void buttonstartBox_SelectedIndexChanged(object sender, EventArgs e)
288 		{
289 			DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.Start] = buttonstartBox.SelectedIndex;
290 		}
291 
buttonaBox_SelectedIndexChanged(object sender, EventArgs e)292 		private void buttonaBox_SelectedIndexChanged(object sender, EventArgs e)
293 		{
294 			DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.A] = buttonaBox.SelectedIndex;
295 		}
296 
buttonbBox_SelectedIndexChanged(object sender, EventArgs e)297 		private void buttonbBox_SelectedIndexChanged(object sender, EventArgs e)
298 		{
299 			DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.B] = buttonbBox.SelectedIndex;
300 		}
301 
buttoncBox_SelectedIndexChanged(object sender, EventArgs e)302 		private void buttoncBox_SelectedIndexChanged(object sender, EventArgs e)
303 		{
304 			DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.C] = buttoncBox.SelectedIndex;
305 		}
306 
buttondBox_SelectedIndexChanged(object sender, EventArgs e)307 		private void buttondBox_SelectedIndexChanged(object sender, EventArgs e)
308 		{
309 			DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.D] = buttondBox.SelectedIndex;
310 		}
311 
buttonupBox_SelectedIndexChanged(object sender, EventArgs e)312 		private void buttonupBox_SelectedIndexChanged(object sender, EventArgs e)
313 		{
314 			DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.Up] = buttonupBox.SelectedIndex;
315 		}
316 
buttondownBox_SelectedIndexChanged(object sender, EventArgs e)317 		private void buttondownBox_SelectedIndexChanged(object sender, EventArgs e)
318 		{
319 			DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.Down] = buttondownBox.SelectedIndex;
320 		}
321 
buttonleftBox_SelectedIndexChanged(object sender, EventArgs e)322 		private void buttonleftBox_SelectedIndexChanged(object sender, EventArgs e)
323 		{
324 			DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.Left] = buttonleftBox.SelectedIndex;
325 		}
326 
buttonrightBox_SelectedIndexChanged(object sender, EventArgs e)327 		private void buttonrightBox_SelectedIndexChanged(object sender, EventArgs e)
328 		{
329 			DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.Right] = buttonrightBox.SelectedIndex;
330 		}
331 
buttonpedalBox_SelectedIndexChanged(object sender, EventArgs e)332 		private void buttonpedalBox_SelectedIndexChanged(object sender, EventArgs e)
333 		{
334 			DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.Pedal] = buttonpedalBox.SelectedIndex;
335 		}
buttonldoorBox_SelectedIndexChanged(object sender, EventArgs e)336 		private void buttonldoorBox_SelectedIndexChanged(object sender, EventArgs e)
337 		{
338 			DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.LDoor] = buttonldoorBox.SelectedIndex;
339 		}
buttonrdoorBox_SelectedIndexChanged(object sender, EventArgs e)340 		private void buttonrdoorBox_SelectedIndexChanged(object sender, EventArgs e)
341 		{
342 			DenshaDeGoInput.ButtonCommands[(int)InputTranslator.ControllerButton.RDoor] = buttonrdoorBox.SelectedIndex;
343 		}
344 
convertnotchesCheck_CheckedChanged(object sender, EventArgs e)345 		private void convertnotchesCheck_CheckedChanged(object sender, EventArgs e)
346 		{
347 			DenshaDeGoInput.ConvertNotches = convertnotchesCheck.Checked;
348 			minmaxCheck.Enabled = DenshaDeGoInput.ConvertNotches;
349 		}
350 
minmaxCheck_CheckedChanged(object sender, EventArgs e)351 		private void minmaxCheck_CheckedChanged(object sender, EventArgs e)
352 		{
353 			DenshaDeGoInput.KeepMaxMin = minmaxCheck.Checked;
354 		}
355 
holdbrakeCheck_CheckedChanged(object sender, EventArgs e)356 		private void holdbrakeCheck_CheckedChanged(object sender, EventArgs e)
357 		{
358 			DenshaDeGoInput.MapHoldBrake = holdbrakeCheck.Checked;
359 		}
360 
buttonCalibrate_Click(object sender, EventArgs e)361 		private void buttonCalibrate_Click(object sender, EventArgs e)
362 		{
363 			if (controllerList.Count == 0)
364 			{
365 				return;
366 			}
367 			Timer1.Stop();
368 			ClassicController.Calibrate();
369 			Timer1.Start();
370 		}
371 
buttonSave_Click(object sender, EventArgs e)372 		private void buttonSave_Click(object sender, EventArgs e)
373 		{
374 			// Save the config and close the config dialog
375 			DenshaDeGoInput.SaveConfig();
376 			Close();
377 		}
378 
buttonCancel_Click(object sender, EventArgs e)379 		private void buttonCancel_Click(object sender, EventArgs e)
380 		{
381 			// Reload the previous config and close the config dialog
382 			DenshaDeGoInput.LoadConfig();
383 			Close();
384 		}
385 
linkLabel_LinkClicked(object sender, EventArgs e)386 		private void linkLabel_LinkClicked(object sender, EventArgs e)
387 		{
388 			Help helpForm = new Help();
389 			helpForm.ShowDialog(this);
390 		}
391 
timer1_Tick(object sender, EventArgs e)392 		private void timer1_Tick(object sender, EventArgs e)
393 		{
394 			InputTranslator.Update();
395 			//grab a random control, as we need something from the UI thread to check for invoke
396 			//WinForms is a pain
397 			if (buttonCalibrate.InvokeRequired)
398 			{
399 				buttonCalibrate.Invoke((MethodInvoker) UpdateInterface);
400 			}
401 			else
402 			{
403 				UpdateInterface();
404 			}
405 
406 		}
407 
408 	}
409 }
410