private void ratioListView_MouseDoubleClick(object sender, MouseEventArgs e) { ListViewItem item = ratioListView.HitTest(e.Location).Item; if (item != null) { int index = (int)item.Tag; TorqueRatio ratio = Ratios[index]; using (TorqueCurveForm frm = new TorqueCurveForm((int)torqueBox.Value, ratio)) { // Show form var result = frm.ShowDialog(); if (result == DialogResult.Yes) { Ratios[index] = frm.GetRatio(); // Flag change RatiosChanged = true; // Force Points Redraw PopulateTorqueRatios(); // Force a chart redraw torqueBox_ValueChanged(this, EventArgs.Empty); } } } }
private void ratioListView_KeyDown(object sender, KeyEventArgs e) { if (ratioListView.SelectedItems.Count == 0) { return; } ListViewItem item = ratioListView.SelectedItems[0]; int index = (int)item.Tag; if (e.KeyCode == Keys.Delete) { // Remove torque ratio Ratios.RemoveAt(index); // Flag change RatiosChanged = true; // Force Points Redraw PopulateTorqueRatios(); // Force a chart redraw torqueBox_ValueChanged(this, EventArgs.Empty); e.Handled = true; } else if (e.KeyCode == Keys.Enter) { TorqueRatio ratio = Ratios[index]; using (TorqueCurveForm frm = new TorqueCurveForm((int)torqueBox.Value, ratio)) { // Show form var result = frm.ShowDialog(); if (result == DialogResult.Yes) { // Grab Ratio TorqueRatio values = frm.GetRatio(); // Create the new Ratio ratio.RpmLevel = values.RpmLevel; ratio.Ratio = values.Ratio; // Flag change RatiosChanged = true; // Force Points Redraw PopulateTorqueRatios(); // Force a chart redraw torqueBox_ValueChanged(this, EventArgs.Empty); } } e.Handled = true; } }
/// <summary> /// Creates a new instance of <see cref="TorqueCurveForm"/> /// </summary> /// <param name="maxTorque">The maximum torque rating as defined by the engine</param> /// <param name="ratio">If editing a torque ratio, specify it here.</param> public TorqueCurveForm(double maxTorque, TorqueRatio ratio = null) { // Create form controls and set default dialog result InitializeComponent(); DialogResult = DialogResult.No; // Set the max power in newton meters MaxNewtonMeters = (Program.Config.UnitSystem == UnitSystem.Imperial) ? Metrics.TorqueToNewtonMeters(maxTorque, 2) : maxTorque; // If this is an existing ratio, set form values if (ratio != null) { CurrentNewtonMeters = MaxNewtonMeters * ratio.Ratio; rpmLevelBox.Value = ratio.RpmLevel; } // Fire the checked event to get things rolling radioButton1.Checked = true; }
private void addPointButton_Click(object sender, EventArgs e) { using (TorqueCurveForm frm = new TorqueCurveForm((int)torqueBox.Value)) { var result = frm.ShowDialog(); if (result == DialogResult.Yes) { // Create the new Ratio TorqueRatio ratio = frm.GetRatio(); Ratios.Add(ratio); // Flag change RatiosChanged = true; // Force Points Redraw PopulateTorqueRatios(); // Force a chart redraw torqueBox_ValueChanged(this, EventArgs.Empty); } } }
private void importButton_Click(object sender, EventArgs e) { // Request the user supply the steam library path var dialog = new OpenFileDialog(); dialog.Title = "Engine SII File Import"; dialog.Filter = "SiiNunit|*.sii"; if (dialog.ShowDialog() == DialogResult.OK) { try { var document = new SiiDocument(typeof(AccessoryEngineData)); using (FileStream stream = File.OpenRead(dialog.FileName)) using (StreamReader reader = new StreamReader(stream)) { // Read the file contents string contents = reader.ReadToEnd().Trim(); document.Load(contents); // Grab the engine object List <string> objects = new List <string>(document.Definitions.Keys); if (objects.Count == 0) { MessageBox.Show("Unable to find any engine data in this sii document!", "Failed", MessageBoxButtons.OK, MessageBoxIcon.Warning ); return; } // Grab the engine var engine = document.GetDefinition <AccessoryEngineData>(objects[0]); // === Set form values int len = objects[0].IndexOf('.'); unitNameBox.Text = objects[0].Substring(0, len); engineNameBox.Text = engine.Name; filenameTextBox.Text = Path.GetFileName(dialog.FileName); unlockBox.SetValueInRange(engine.UnlockLevel); priceBox.SetValueInRange(engine.Price); neutralRpmBox.SetValueInRange(engine?.RpmLimitNeutral ?? 2200); rpmLimitBox.SetValueInRange((decimal)engine.RpmLimit); idleRpmBox.SetValueInRange(engine?.IdleRpm ?? 650); brakeStrengthBox.SetValueInRange((decimal)engine.BrakeStrength); brakePositionsBox.SetValueInRange(engine.BrakePositions); automaticDSCheckBox.Checked = engine.BrakeDownshift == 1; // Misc if (engine.RpmRangeEngineBrake.X > 0f) { engineBrakeLow.SetValueInRange((int)engine.RpmRangeEngineBrake.X); engineBrakeHigh.SetValueInRange((int)engine.RpmRangeEngineBrake.Y); } consumptionBox.SetValueInRange((decimal)engine.FuelConsumption * 100); adBlueConsumption.SetValueInRange((decimal)engine.AdblueConsumption); adBlueNoPowerLimit.SetValueInRange((decimal)engine.NoAdbluePowerLimit); conflictsTextBox.Lines = engine?.Conflicts ?? new string[] { }; // Tab 3 if (engine.RpmRange_LowGear.X > 0f) { rpmRangeBox1.SetValueInRange((int)engine.RpmRange_LowGear.X); rpmRangeBox2.SetValueInRange((int)engine.RpmRange_LowGear.Y); } if (engine.RpmRange_HighGear.X > 0f) { rpmRangeBox3.SetValueInRange((int)engine.RpmRange_HighGear.X); rpmRangeBox4.SetValueInRange((int)engine.RpmRange_HighGear.Y); } if (engine.RpmRange_PowerBoost.X > 0f) { rpmRangeBox5.SetValueInRange((int)engine.RpmRange_PowerBoost.X); rpmRangeBox6.SetValueInRange((int)engine.RpmRange_PowerBoost.Y); } // Parse Horsepower Regex reg = new Regex("^(?<hp>[0-9]+)", RegexOptions.Multiline); if (reg.IsMatch(engine.Info[0])) { horsepowerBox.SetValueInRange(Int32.Parse(reg.Match(engine.Info[0]).Groups["hp"].Value)); } if (engine.TorqueCurves?.Length > 0) { // Clear torque curves chart1.Series[0].Points.Clear(); ratioListView.Items.Clear(); Ratios.Clear(); // Set new torque curves foreach (Vector2 vector in engine.TorqueCurves) { TorqueRatio ratio = new TorqueRatio(); ratio.RpmLevel = (int)vector.X; ratio.Ratio = Math.Round(vector.Y, 4); Ratios.Add(ratio); } // Fill ratio view PopulateTorqueRatios(); } // Set torque value torqueBox.SetValueInRange((Program.Config.UnitSystem == UnitSystem.Imperial) ? Metrics.NewtonMetersToTorque((decimal)engine.Torque, torqueBox.DecimalPlaces) : Math.Round((decimal)engine.Torque, torqueBox.DecimalPlaces) ); // Defaults (skip sounds) if (engine.Defaults != null) { fileDefaultsTextBox.Lines = (from x in engine.Defaults where !x.Contains("/sound/") select x).ToArray(); } // Overrides (skip sounds) if (engine.Overrides != null) { fileOverridesTextBox.Lines = (from x in engine.Overrides where !x.Contains("/sound/") select x).ToArray(); } // Alert the user MessageBox.Show( $"Successfully imported the engine \"{engine.Name}\"! You must now select an engine series for this engine.", "Import Successful", MessageBoxButtons.OK, MessageBoxIcon.Information ); } } catch (SiiSyntaxException ex) { StringBuilder builder = new StringBuilder("A Syntax error occured while parsing the sii file!"); builder.AppendLine(); builder.AppendLine(); builder.AppendLine($"Message: {ex.Message.Replace("\0", "\\0")}"); builder.AppendLine(); builder.AppendLine($"Line: {ex.Span.Start.Line}"); builder.AppendLine($"Column: {ex.Span.Start.Column}"); MessageBox.Show(builder.ToString(), "Sii Syntax Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (SiiException ex) { StringBuilder builder = new StringBuilder("Failed to parse the sii file."); builder.AppendLine(); builder.AppendLine($"Message: {ex.Message}"); MessageBox.Show(builder.ToString(), "Sii Exception", MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (Exception ex) { MessageBox.Show(ex.Message, "An Error Occured", MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
private void torqueBox_ValueChanged(object sender, EventArgs e) { // Update label labelNM.Text = (Program.Config.UnitSystem == UnitSystem.Imperial) ? String.Concat(Metrics.TorqueToNewtonMeters(torqueBox.Value), " (Nm)") : String.Concat(Metrics.NewtonMetersToTorque(torqueBox.Value), " (Trq)"); // disable buttons addPointButton.Enabled = false; removePointButton.Enabled = false; // Clear old chart points chart1.Series[0].Points.Clear(); chart1.Series[1].Points.Clear(); DataPoint lastPoint = null; TorqueRatio highest = null; double torque = 0; double horsepower = 0; // Fill torque ratios foreach (TorqueRatio ratio in Ratios.OrderBy(x => x.RpmLevel)) { // Plot the torque point torque = Math.Round((double)torqueBox.Value * ratio.Ratio, 2); int index = chart1.Series[0].Points.AddXY(ratio.RpmLevel, torque); DataPoint point = chart1.Series[0].Points[index]; // Set tool tip and covert chart value for later if (Program.Config.UnitSystem == UnitSystem.Imperial) { point.ToolTip = $"{torque} lb-ft @ {ratio.RpmLevel} RPM"; } else { point.ToolTip = $"{torque} Nm @ {ratio.RpmLevel} RPM"; torque = Metrics.NewtonMetersToTorque(torque, 2); } // Set the highest and earliest ratio if (highest == null || ratio.Ratio > highest.Ratio) { highest = ratio; } // === Plot Horsepower if (lastPoint != null) { // Calculate the last plots starting Torque value double torqueAtPoint = lastPoint.YValues[0]; // Get torque difference from last point double deltaY = point.YValues[0] - lastPoint.YValues[0]; // Get RPM difference from last point double deltaX = point.XValue - lastPoint.XValue; // Convert Nm to Torque if using the Metric System if (Program.Config.UnitSystem == UnitSystem.Metric) { deltaY = Metrics.NewtonMetersToTorque(deltaY, 2); torqueAtPoint = Metrics.NewtonMetersToTorque(torqueAtPoint, 2); } // Calculate torque rise (rpm distance * (torque rise per rpm)), // Then walk from the last point, to right before the current one double torqueRise = HP_POINT_DIST * (deltaY / deltaX); double rpm = lastPoint.XValue + HP_POINT_DIST; double stop = point.XValue; // Now we plot the horsepower points, up until we hit the next torque point for (; rpm < stop; rpm += HP_POINT_DIST) { // increment torque rating by our dermined curve rise torqueAtPoint += torqueRise; // Plot the horsepower point horsepower = Metrics.TorqueToHorsepower(torqueAtPoint, rpm, 0); index = chart1.Series[1].Points.AddXY(rpm, horsepower); chart1.Series[1].Points[index].ToolTip = $"#VALY HP @ {rpm} RPM"; } } // Plot the Horsepower plots horsepower = Metrics.TorqueToHorsepower(torque, ratio.RpmLevel, 0); index = chart1.Series[1].Points.AddXY(ratio.RpmLevel, horsepower); chart1.Series[1].Points[index].ToolTip = $"#VALY HP @ {ratio.RpmLevel} RPM"; chart1.Series[1].Points[index].MarkerStyle = MarkerStyle.Circle; chart1.Series[1].Points[index].MarkerColor = Color.Black; // Set the last point lastPoint = point; } // Update labels if (chart1.Series[1].Points.Count > 0) { DataPoint pnt = chart1.Series[1].Points.FindMaxByValue("Y"); maxHpLabel.Text = $"{pnt.YValues[0]} @ {pnt.XValue} RPM"; torque = Math.Round((double)torqueBox.Value * highest.Ratio, 0); maxTrqLabel.Text = $"{torque} @ {highest.RpmLevel} RPM"; peakRPMBox.Value = highest?.RpmLevel ?? 1200; peakRPMBox.Enabled = false; // no user edit } else { peakRPMBox.Enabled = true; maxHpLabel.Text = ""; maxTrqLabel.Text = ""; } // Enable buttons addPointButton.Enabled = true; removePointButton.Enabled = true; }