public override void OnApplyTemplate() { base.OnApplyTemplate(); slider = GetTemplateChild("Slider") as DoubleSlider; LowerLabel = GetTemplateChild("LowerValue") as Label; UpperLabel = GetTemplateChild("UpperValue") as Label; ThresholdWarning = GetTemplateChild("ThresholdWarning") as Image; SensorDisplay = GetTemplateChild("PlatformSensorDisplay") as PlatformSensorDisplay; slider.ValueChanged += delegate(DoubleSlider slider) { SaveToConfig(); }; // Show the edit button for the custom-sensors slider. Button EditCustomSensorsButton = GetTemplateChild("EditCustomSensorsButton") as Button; EditCustomSensorsButton.Visibility = Type == "custom-sensors"? Visibility.Visible:Visibility.Hidden; EditCustomSensorsButton.Click += delegate(object sender, RoutedEventArgs e) { SetCustomSensors dialog = new SetCustomSensors(); dialog.Owner = Window.GetWindow(this); dialog.ShowDialog(); }; onConfigChange = new OnConfigChange(this, delegate(LoadFromConfigDelegateArgs args) { LoadUIFromConfig(ActivePad.GetFirstActivePadConfig(args)); }); }
public override void OnApplyTemplate() { base.OnApplyTemplate(); int[] PanelToIndex = new int[] { 7, 8, 9, 4, 5, 6, 1, 2, 3, }; EnabledPanelButtons = new PanelButton[9]; for (int i = 0; i < 9; ++i) { EnabledPanelButtons[i] = GetTemplateChild("EnablePanel" + PanelToIndex[i]) as PanelButton; } foreach (PanelButton button in EnabledPanelButtons) { button.Click += EnabledPanelButtonClicked; } onConfigChange = new OnConfigChange(this, delegate(LoadFromConfigDelegateArgs args) { LoadUIFromConfig(ActivePad.GetFirstActivePadConfig(args)); }); }
protected override void OnClick() { if (AdvancedModeEnabled) { // Stop forcing advanced mode on, and sync the thresholds so we exit advanced mode. ForcedOn = false; foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { int pad = activePad.Item1; SMX.SMXConfig config = activePad.Item2; ConfigPresets.SyncUnifiedThresholds(ref config); SMX.SMX.SetConfig(pad, config); } CurrentSMXDevice.singleton.FireConfigurationChanged(this); } else { // Enable advanced mode. ForcedOn = true; } // Refresh the UI. LoadUIFromConfig(ActivePad.GetFirstActivePadConfig()); }
private void ImportSettings(object sender, RoutedEventArgs e) { // Prompt for a file to read. Microsoft.Win32.OpenFileDialog dialog = new Microsoft.Win32.OpenFileDialog(); dialog.FileName = "StepManiaX settings"; dialog.DefaultExt = ".smxcfg"; dialog.Filter = "StepManiaX settings (.smxcfg)|*.smxcfg"; bool?result = dialog.ShowDialog(); if (result == null || !(bool)result) { return; } string json = Helpers.ReadFile(dialog.FileName); // Apply settings from the file to all active pads. foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { int pad = activePad.Item1; SMX.SMXConfig config = activePad.Item2; SMXHelpers.ImportSettingsFromJSON(json, ref config); SMX.SMX.SetConfig(pad, config); } CurrentSMXDevice.singleton.FireConfigurationChanged(null); }
public override void OnApplyTemplate() { base.OnApplyTemplate(); onConfigChange = new OnConfigChange(this, delegate(LoadFromConfigDelegateArgs args) { LoadUIFromConfig(ActivePad.GetFirstActivePadConfig(args)); }); }
private void FactoryReset_Click(object sender, RoutedEventArgs e) { foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { int pad = activePad.Item1; SMX.SMX.FactoryReset(pad); } CurrentSMXDevice.singleton.FireConfigurationChanged(null); }
// Update which of the "Leave this application running", etc. blocks to display. private void RefreshUploadPadText(LoadFromConfigDelegateArgs args) { foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { SMX.SMXConfig config = activePad.Item2; bool uploadsSupported = config.masterVersion >= 4; LeaveRunning.Visibility = uploadsSupported ? Visibility.Collapsed : Visibility.Visible; break; } }
public static void SyncSliderThresholds() { foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { SMX.SMXConfig config = activePad.Item2; SyncSliderThresholdsForConfig(ref config); SMX.SMX.SetConfig(activePad.Item1, config); } CurrentSMXDevice.singleton.FireConfigurationChanged(null); }
private void Select() { foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { int pad = activePad.Item1; SMX.SMXConfig config = activePad.Item2; ConfigPresets.SetPreset(Type, ref config); SMX.SMX.SetConfig(pad, config); } CurrentSMXDevice.singleton.FireConfigurationChanged(this); }
protected override void OnClick() { Properties.Settings.Default.AdvancedMode = !Properties.Settings.Default.AdvancedMode; if (!Properties.Settings.Default.AdvancedMode) { // Sync thresholds when we exit advanced mode. XXX: not needed since MainWindow is recreating // sliders anyway ThresholdSettings.SyncSliderThresholds(); } // Refresh the UI. LoadUIFromConfig(ActivePad.GetFirstActivePadConfig()); }
public override void OnApplyTemplate() { base.OnApplyTemplate(); slider = GetTemplateChild("Slider") as DoubleSlider; LowerLabel = GetTemplateChild("LowerValue") as Label; UpperLabel = GetTemplateChild("UpperValue") as Label; slider.ValueChanged += delegate(DoubleSlider slider) { SaveToConfig(); }; onConfigChange = new OnConfigChange(this, delegate(LoadFromConfigDelegateArgs args) { LoadUIFromConfig(ActivePad.GetFirstActivePadConfig(args)); }); }
private void Select() { foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { int pad = activePad.Item1; SMX.SMXConfig config = activePad.Item2; ConfigPresets.SetPreset(Type, ref config); Console.WriteLine("PresetButton::Select (" + Type + "): " + config.panelThreshold1Low + ", " + config.panelThreshold4Low + ", " + config.panelThreshold7Low + ", " + config.panelThreshold2Low); SMX.SMX.SetConfig(pad, config); } CurrentSMXDevice.singleton.FireConfigurationChanged(this); }
private void EnabledPanelButtonClicked(object sender, EventArgs e) { // One of the panel buttons on the panel toggle UI was clicked. Toggle the // panel. int button = GetIndexFromButton(sender); Console.WriteLine("Clicked " + button); // Set the enabled sensor mask on both pads to the state of the UI. foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { int pad = activePad.Item1; SMX.SMXConfig config = activePad.Item2; // This could be done algorithmically, but this is clearer. int[] PanelButtonToSensorIndex = { 0, 0, 1, 1, 2, 2, 3, 3, 4 }; byte[] PanelButtonToSensorMask = { 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, }; for (int i = 0; i < 5; ++i) { config.enabledSensors[i] = 0; } for (int Panel = 0; Panel < 9; ++Panel) { int index = PanelButtonToSensorIndex[Panel]; byte mask = PanelButtonToSensorMask[Panel]; if (EnabledPanelButtons[Panel].IsChecked == true) { config.enabledSensors[index] |= (byte)mask; } } // If we're not in "light all panels" mode, sync up autoLightPanelMask // with the new enabledSensors. config.refreshAutoLightPanelMask(); SMX.SMX.SetConfig(pad, config); } }
protected override void OnClick() { //SMX.SMXConfig firstConfig = ActivePad.GetFirstActivePadConfig(); foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { int pad = activePad.Item1; SMX.SMXConfig config = activePad.Item2; config.setLightAllPanelsMode(!LightAllPanels); SMX.SMX.SetConfig(pad, config); } CurrentSMXDevice.singleton.FireConfigurationChanged(this); // Refresh the UI. //LoadUIFromConfig(firstConfig); }
private void SaveToConfig() { if (UpdatingUI) { return; } // Apply the change and save it to the devices. foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { int pad = activePad.Item1; SMX.SMXConfig config = activePad.Item2; SetValueToConfig(ref config); SMX.SMX.SetConfig(pad, config); CurrentSMXDevice.singleton.FireConfigurationChanged(this); } }
public override void OnApplyTemplate() { base.OnApplyTemplate(); Button button = GetTemplateChild("PART_Button") as Button; button.Click += delegate(object sender, RoutedEventArgs e) { Select(); }; onConfigChange = new OnConfigChange(this, delegate(LoadFromConfigDelegateArgs args) { foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { SMX.SMXConfig config = activePad.Item2; string CurrentPreset = ConfigPresets.GetPreset(config); Selected = CurrentPreset == Type; break; } }); }
private void UploadLatestGIF() { // Create a progress window. Center it on top of the main window. ProgressWindow dialog = new ProgressWindow(); dialog.Left = (Left + Width / 2) - (dialog.Width / 2); dialog.Top = (Top + Height / 2) - (dialog.Height / 2); dialog.Title = "Storing animations on pad..."; int[] CurrentProgress = new int[] { 0, 0 }; // Upload graphics for all connected pads. If two pads are connected // we can start both of these simultaneously, and they'll be sent in // parallel. int total = 0; foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { int pad = activePad.Item1; SMX.SMX.LightsUpload_BeginUpload(pad, delegate(int progress) { // This is called from a thread, so dispatch back to the main thread. Dispatcher.Invoke(delegate() { // Store progress, so we can sum both pads. CurrentProgress[pad] = progress; dialog.SetProgress(CurrentProgress[0] + CurrentProgress[1]); if (progress == 100) { dialog.Close(); } }); }); // Each pad that we start uploading to is 100 units of progress. total += 100; dialog.SetTotal(total); } // Show the progress window as a modal dialog. This function won't return // until we call dialog.Close above. dialog.ShowDialog(); }
protected override void OnClick() { foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { int pad = activePad.Item1; SMX.SMXConfig config = activePad.Item2; // Disable the sensor by setting its high threshold to 255, and enable it by syncing it up // with the other thresholds. if (!EnableSensor) { config.panelSettings[4].fsrHighThreshold[2] = config.panelSettings[4].fsrHighThreshold[0]; } else { config.panelSettings[4].fsrHighThreshold[2] = 255; } SMX.SMX.SetConfig(pad, config); } CurrentSMXDevice.singleton.FireConfigurationChanged(this); }
public override void OnApplyTemplate() { base.OnApplyTemplate(); OnConfigChange onConfigChange; onConfigChange = new OnConfigChange(this, delegate(LoadFromConfigDelegateArgs args) { int SelectedPad = Panel < 9? 0:1; int PanelIndex = Panel % 9; Pressed = args.controller[SelectedPad].inputs[PanelIndex]; Warning = !args.controller[SelectedPad].test_data.bHaveDataFromPanel[PanelIndex] || args.controller[SelectedPad].test_data.AnySensorsOnPanelNotResponding(PanelIndex) || args.controller[SelectedPad].test_data.AnyBadJumpersOnPanel(PanelIndex); // Only show this panel button if the panel's input is enabled. SMX.SMXConfig config = ActivePad.GetFirstActivePadConfig(args); Visibility = ShouldBeDisplayed(config)? Visibility.Visible:Visibility.Collapsed; }); onConfigChange.RefreshOnInputChange = true; onConfigChange.RefreshOnTestDataChange = true; }
private void ExportSettings(object sender, RoutedEventArgs e) { // Save the current thresholds on the first available pad as a preset. foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { int pad = activePad.Item1; SMX.SMXConfig config = activePad.Item2; string json = SMXHelpers.ExportSettingsToJSON(config); Microsoft.Win32.SaveFileDialog dialog = new Microsoft.Win32.SaveFileDialog(); dialog.FileName = "StepManiaX settings"; dialog.DefaultExt = ".smxcfg"; dialog.Filter = "StepManiaX settings (.smxcfg)|*.smxcfg"; bool?result = dialog.ShowDialog(); if (result == null || !(bool)result) { return; } System.IO.File.WriteAllText(dialog.FileName, json); return; } }
// We have two main modes: color mode and GIF animation mode. These behave differently // on gen1-3 pads and gen4 pads. // // On gen4 pads, this determines whether we show animations on press, or show a solid color. // This makes it easy to pick a solid color if that's all you want to change, instead of having // to make a GIF with the color. We always show animations on release in both modes. // // On gen1-3 pads, panels are black in color mode, so they behave the same as they did originally. // Animations are only shown in GIF animation mode. These animations are enabled with // LightsAnimation_SetAuto. // // The gen1-3 firmware ignores the AutoLightingUsePressedAnimations flag, but we still use it to // store which mode the user has selected. private void PressedColorModeButton(object sender, RoutedEventArgs e) { // The user pressed either the "panel colors" or "GIF animations" button. bool pressedPanelColors = sender == PanelColorsButton; foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { SMX.SMXConfig config = activePad.Item2; // If we're in panel colors mode, clear the AutoLightingUsePressedAnimations flag. // Otherwise, set it. if (pressedPanelColors) { config.configFlags &= ~SMX.SMXConfigFlags.AutoLightingUsePressedAnimations; } else { config.configFlags |= SMX.SMXConfigFlags.AutoLightingUsePressedAnimations; } SMX.SMX.SetConfig(activePad.Item1, config); } CurrentSMXDevice.singleton.FireConfigurationChanged(null); }
private void LoadUIFromConfig(LoadFromConfigDelegateArgs args) { // Refresh whether LightsAnimation_SetAuto should be enabled. SMX.SMXConfig firstConfig = ActivePad.GetFirstActivePadConfig(); bool usePressedAnimationsEnabled = (firstConfig.configFlags & SMX.SMXConfigFlags.AutoLightingUsePressedAnimations) != 0; SMX.SMX.LightsAnimation_SetAuto(usePressedAnimationsEnabled); bool EitherControllerConnected = args.controller[0].info.connected || args.controller[1].info.connected; Main.Visibility = EitherControllerConnected ? Visibility.Visible : Visibility.Hidden; Searching.Visibility = EitherControllerConnected ? Visibility.Hidden : Visibility.Visible; ConnectedPads.Visibility = EitherControllerConnected ? Visibility.Visible : Visibility.Hidden; PanelColorP1.Visibility = args.controller[0].info.connected ? Visibility.Visible : Visibility.Collapsed; PanelColorP2.Visibility = args.controller[1].info.connected ? Visibility.Visible : Visibility.Collapsed; EnableCenterTopSensorCheckbox.Visibility = P1_Floor.Visibility = P2_Floor.Visibility = args.firmwareVersion() >= 5 ? Visibility.Visible : Visibility.Collapsed; // Show the color slider or GIF UI depending on which one is set in flags. // If both pads are turned on, just use the first one. foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { SMX.SMXConfig config = activePad.Item2; // If SMXConfigFlags_AutoLightingUsePressedAnimations is set, show the GIF UI. // If it's not set, show the color slider UI. SMX.SMXConfigFlags flags = config.configFlags; bool usePressedAnimations = (flags & SMX.SMXConfigFlags.AutoLightingUsePressedAnimations) != 0; ColorPickerGroup.Visibility = usePressedAnimations ? Visibility.Collapsed : Visibility.Visible; GIFGroup.Visibility = usePressedAnimations ? Visibility.Visible : Visibility.Collapsed; // Tell the color mode buttons which one is selected, to set the button highlight. PanelColorsButton.Selected = !usePressedAnimations; GIFAnimationsButton.Selected = usePressedAnimations; break; } RefreshConnectedPadList(args); RefreshUploadPadText(args); RefreshSelectedColorPicker(); // If a device has connected or disconnected, refresh the displayed threshold // sliders. Don't do this otherwise, or we'll do this when the sliders are // dragged. if (args.ConnectionsChanged) { CreateThresholdSliders(); } // Show the threshold warning explanation if any panels are showing the threshold warning icon. bool ShowThresholdWarningText = false; foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { SMX.SMXConfig config = activePad.Item2; for (int panelIdx = 0; panelIdx < 9; ++panelIdx) { for (int sensor = 0; sensor < 4; ++sensor) { if (config.ShowThresholdWarning(panelIdx, sensor)) { ShowThresholdWarningText = true; } } } } ThresholdWarningText.Visibility = ShowThresholdWarningText ? Visibility.Visible : Visibility.Hidden; // If a second controller has connected and we're on Both, see if we need to prompt // to sync configs. We only actually need to do this if a controller just connected. if (args.ConfigurationChanged) { CheckConfiguringBothPads(args); } }
private void LoadGIF(object sender, RoutedEventArgs e) { // If the "load idle GIF" button was pressed, load the released animation. // Otherwise, load the pressed animation. bool pressed = sender == this.LoadPressed; // Prompt for a file to read. Microsoft.Win32.OpenFileDialog dialog = new Microsoft.Win32.OpenFileDialog(); dialog.FileName = "Select an animated GIF"; dialog.DefaultExt = ".gif"; dialog.Filter = "Animated GIF (.gif)|*.gif"; bool?result = dialog.ShowDialog(); if (result == null || !(bool)result) { return; } byte[] buf = Helpers.ReadBinaryFile(dialog.FileName); SMX.SMX.LightsType type = pressed ? SMX.SMX.LightsType.LightsType_Pressed : SMX.SMX.LightsType.LightsType_Released; foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { int pad = activePad.Item1; // Load the animation. string error; if (!SMX.SMX.LightsAnimation_Load(buf, pad, type, out error)) { // Any errors here are problems with the GIF, so there's no point trying // to load it for the second pad if the first returns an error. Just show the // error and stop. MessageBox.Show(error, "Error", MessageBoxButton.OK, MessageBoxImage.Warning); // Return without saving to settings on error. return; } // Save the GIF to disk so we can load it quickly later. Helpers.SaveAnimationToDisk(pad, type, buf); // Refresh after loading a GIF to update the "Leave this application running" text. CurrentSMXDevice.singleton.FireConfigurationChanged(null); } // For firmwares that support it, upload the animation to the pad now. Otherwise, // we'll run the animation directly. foreach (Tuple <int, SMX.SMXConfig> activePad in ActivePad.ActivePads()) { int pad = activePad.Item1; SMX.SMXConfig config; if (!SMX.SMX.GetConfig(pad, out config)) { continue; } if (config.masterVersion >= 4) { UploadLatestGIF(); } break; } }
void RefreshVisibility() { SMX.SMXConfig config = ActivePad.GetFirstActivePadConfig(); this.Visibility = ShouldBeDisplayed(config)? Visibility.Visible:Visibility.Collapsed; }
bool IsThresholdSliderShown(string type) { bool AdvancedModeEnabled = Properties.Settings.Default.AdvancedMode; SMX.SMXConfig config = ActivePad.GetFirstActivePadConfig(); bool[] enabledPanels = config.GetEnabledPanels(); // Check the list of sensors this slider controls. If the list is empty, don't show it. // For example, if the user adds all four sensors on the up panel to custom-sensors, the // up button has nothing left to control, so we'll hide it. // // Don't do this for custom, inner-sensors or outer-sensors. Those are always shown in // advanced mode. List <ThresholdSettings.PanelAndSensor> panelAndSensors = ThresholdSettings.GetControlledSensorsForSliderType(type, AdvancedModeEnabled, false); if (type == "custom-sensors" || type == "inner-sensors" || type == "outer-sensors") { if (!AdvancedModeEnabled || !config.fsr()) { return(false); } } else { if (panelAndSensors.Count == 0) { return(false); } } // Hide thresholds that only affect panels that are disabled, so we don't show // corner panel sliders in advanced mode if the corner panels are disabled. We // don't handle this in GetControlledSensorsForSliderType, since we do want cardinal // and corner to write thresholds to disabled panels, so they're in sync if they're // turned back on. switch (type) { case "up-left": return(enabledPanels[0]); case "up": return(enabledPanels[1]); case "up-right": return(enabledPanels[2]); case "left": return(enabledPanels[3]); case "center": return(enabledPanels[4]); case "right": return(enabledPanels[5]); case "down-left": return(enabledPanels[6]); case "down": return(enabledPanels[7]); case "down-right": return(enabledPanels[8]); // Show cardinal and corner if at least one panel they affect is enabled. case "cardinal": return(enabledPanels[3] || enabledPanels[5] || enabledPanels[8]); case "corner": return(enabledPanels[0] || enabledPanels[2] || enabledPanels[6] || enabledPanels[8]); default: return(true); } }
private void Refresh(LoadFromConfigDelegateArgs args) { // First, make sure a valid panel is selected. SMX.SMXConfig config = ActivePad.GetFirstActivePadConfig(args); SelectValidPanel(config); RefreshSelectedPanel(); // Make sure SetShowAllLights is disabled if the controller is disconnected, since // we can miss mouse up events. bool EitherControllerConnected = args.controller[0].info.connected || args.controller[1].info.connected; if (!EitherControllerConnected) { SetShowAllLights?.Invoke(false); } P1Diagnostics.Visibility = args.controller[0].info.connected? Visibility.Visible:Visibility.Collapsed; P2Diagnostics.Visibility = args.controller[1].info.connected? Visibility.Visible:Visibility.Collapsed; // Update the displayed DIP switch icons. int SelectedPad = SelectedPanel < 9? 0:1; int PanelIndex = SelectedPanel % 9; int dip = args.controller[SelectedPad].test_data.iDIPSwitchPerPanel[PanelIndex]; CurrentDIP.Frame = dip; ExpectedDIP.Frame = PanelIndex; // Show or hide the sensor error text. bool AnySensorsNotResponding = false, HaveIncorrectSensorDIP = false; if (args.controller[SelectedPad].test_data.bHaveDataFromPanel[PanelIndex]) { AnySensorsNotResponding = args.controller[SelectedPad].test_data.AnySensorsOnPanelNotResponding(PanelIndex); // Don't show both warnings. HaveIncorrectSensorDIP = !AnySensorsNotResponding && args.controller[SelectedPad].test_data.AnyBadJumpersOnPanel(PanelIndex); } NoResponseFromSensors.Visibility = AnySensorsNotResponding? Visibility.Visible:Visibility.Collapsed; BadSensorDIPSwitches.Visibility = HaveIncorrectSensorDIP? Visibility.Visible:Visibility.Collapsed; // Adjust the DIP labels to match the PCB. bool DIPLabelsOnLeft = config.masterVersion < 4; DIPLabelRight.Visibility = DIPLabelsOnLeft? Visibility.Collapsed:Visibility.Visible; DIPLabelLeft.Visibility = DIPLabelsOnLeft? Visibility.Visible:Visibility.Collapsed; // Update the level bar from the test mode data for the selected panel. for (int sensor = 0; sensor < 4; ++sensor) { var controllerData = args.controller[SelectedPad]; Int16 value = controllerData.test_data.sensorLevel[PanelIndex * 4 + sensor]; if (GetTestMode() == SMX.SMX.SensorTestMode.Noise) { // In noise mode, we receive standard deviation values squared. Display the square // root, since the panels don't do this for us. This makes the numbers different // than the configured value (square it to convert back), but without this we display // a bunch of 4 and 5-digit numbers that are too hard to read. value = (Int16)Math.Sqrt(value); } LevelBarText[sensor].Visibility = Visibility.Visible; if (!args.controller[SelectedPad].test_data.bHaveDataFromPanel[PanelIndex]) { LevelBars[sensor].Value = 0; LevelBarText[sensor].Visibility = Visibility.Hidden; LevelBarText[sensor].Content = "-"; LevelBars[sensor].Error = false; } else if (args.controller[SelectedPad].test_data.bBadSensorInput[PanelIndex * 4 + sensor]) { LevelBars[sensor].Value = 0; LevelBarText[sensor].Content = "!"; LevelBars[sensor].Error = true; } else { // Very slightly negative values happen due to noise. They don't indicate a // problem, but they're confusing in the UI, so clamp them away. if (value < 0 && value >= -10) { value = 0; } // Scale differently depending on if this is an FSR panel or a load cell panel. bool isFSR = controllerData.config.masterVersion >= 4 && (controllerData.config.configFlags & SMX.SMXConfigFlags.PlatformFlags_FSR) != 0; if (isFSR) { value >>= 2; } float maxValue = isFSR? 250:500; LevelBars[sensor].Value = value / maxValue; LevelBarText[sensor].Content = value; LevelBars[sensor].Error = false; } } NoResponseFromPanel.Visibility = Visibility.Collapsed; CurrentDIPGroup.Visibility = Visibility.Visible; if (!args.controller[SelectedPad].test_data.bHaveDataFromPanel[PanelIndex]) { NoResponseFromPanel.Visibility = Visibility.Visible; NoResponseFromSensors.Visibility = Visibility.Collapsed; CurrentDIPGroup.Visibility = Visibility.Hidden; return; } }