diff --git a/OpenSpaceToolbox/GameManager/Games/Donald/DonaldGameManager.cs b/OpenSpaceToolbox/GameManager/Games/Donald/DonaldGameManager.cs index 3ea264f..4ad532c 100644 --- a/OpenSpaceToolbox/GameManager/Games/Donald/DonaldGameManager.cs +++ b/OpenSpaceToolbox/GameManager/Games/Donald/DonaldGameManager.cs @@ -29,6 +29,7 @@ public DonaldGameManager() //Extras ExtraActions = new ObservableCollection() { + new GenericSpeedMonitorExtra(this), new DonaldLivesExtra(this), }; diff --git a/OpenSpaceToolbox/GameManager/Games/Generic/GenericSpeedMonitorExtra.cs b/OpenSpaceToolbox/GameManager/Games/Generic/GenericSpeedMonitorExtra.cs new file mode 100644 index 0000000..8653535 --- /dev/null +++ b/OpenSpaceToolbox/GameManager/Games/Generic/GenericSpeedMonitorExtra.cs @@ -0,0 +1,37 @@ +using System.Numerics; +using System.Windows; + +namespace OpenSpaceToolbox +{ + public class GenericSpeedMonitorExtra : OpenspaceExtraAction + { + public GenericSpeedMonitorExtra(OpenspaceGameManager gameManager) : base(gameManager) + { + Name = "Speed Monitor"; + ShortName = "Speed Monitor"; + } + + public Vector3 PlayerCoordinates + { + get + { + var playerCoords = GameManager.PlayerCoordinates; + + return new Vector3( + playerCoords.Item1, + playerCoords.Item2, + playerCoords.Item3 + ); + } + } + + public override void Action() + { + SpeedMonitorWindow speedWindow = new SpeedMonitorWindow(new SpeedMonitorWindowViewModel(this)) + { + Owner = Application.Current.MainWindow + }; + speedWindow.Show(); + } + } +} diff --git a/OpenSpaceToolbox/GameManager/Games/Rayman2/Rayman2GameManager.cs b/OpenSpaceToolbox/GameManager/Games/Rayman2/Rayman2GameManager.cs index 2266e46..6c363d2 100644 --- a/OpenSpaceToolbox/GameManager/Games/Rayman2/Rayman2GameManager.cs +++ b/OpenSpaceToolbox/GameManager/Games/Rayman2/Rayman2GameManager.cs @@ -27,6 +27,7 @@ public Rayman2GameManager() //Extras ExtraActions = new ObservableCollection() { + new GenericSpeedMonitorExtra(this), new Rayman2VoidExtra(this), new Rayman2NoHpExtra(this), new Rayman2MaxHpExtra(this), diff --git a/OpenSpaceToolbox/GameManager/Games/Rayman3/Rayman3GameManager.cs b/OpenSpaceToolbox/GameManager/Games/Rayman3/Rayman3GameManager.cs index 74bab7c..b342234 100644 --- a/OpenSpaceToolbox/GameManager/Games/Rayman3/Rayman3GameManager.cs +++ b/OpenSpaceToolbox/GameManager/Games/Rayman3/Rayman3GameManager.cs @@ -27,6 +27,7 @@ public Rayman3GameManager() //Extras ExtraActions = new ObservableCollection() { + new GenericSpeedMonitorExtra(this), }; //Levels diff --git a/OpenSpaceToolbox/OpenSpaceToolbox.csproj b/OpenSpaceToolbox/OpenSpaceToolbox.csproj index 1c289b6..5b230cf 100644 --- a/OpenSpaceToolbox/OpenSpaceToolbox.csproj +++ b/OpenSpaceToolbox/OpenSpaceToolbox.csproj @@ -69,6 +69,9 @@ + + ..\packages\System.Numerics.Vectors.4.5.0\lib\portable-net45+win8+wp8+wpa81\System.Numerics.Vectors.dll + ..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll @@ -92,10 +95,12 @@ + + GameChooser.xaml @@ -135,6 +140,9 @@ GameManagerMinimizedView.xaml + + SpeedMonitorWindow.xaml + ProgressArrayWindow.xaml @@ -156,6 +164,10 @@ Designer MSBuild:Compile + + MSBuild:Compile + Designer + MSBuild:Compile Designer @@ -211,6 +223,7 @@ + diff --git a/OpenSpaceToolbox/ViewModels/SpeedMonitorWindowViewModel.cs b/OpenSpaceToolbox/ViewModels/SpeedMonitorWindowViewModel.cs new file mode 100644 index 0000000..f4e216e --- /dev/null +++ b/OpenSpaceToolbox/ViewModels/SpeedMonitorWindowViewModel.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Input; +using System.Windows.Threading; + +namespace OpenSpaceToolbox +{ + /// + /// View model for the Speed Monitor + /// + public class SpeedMonitorWindowViewModel : BaseViewModel + { + #region Constructor + + public SpeedMonitorWindowViewModel(GenericSpeedMonitorExtra extra) + { + Extra = extra; + + Task.Run(UpdateSpeedTask); + } + + #endregion + + #region Public Properties + + public float PositionX => _lastPosition.X; + public float PositionY => _lastPosition.Y; + public float PositionZ => _lastPosition.Z; + + public float SpeedX => _speed.X; + public float SpeedY => _speed.Y; + public float SpeedZ => _speed.Z; + public float SpeedXY => new Vector2(_speed.X, _speed.Y).Length(); + public float SpeedXYZ => _speed.Length(); + + public float AverageSpeedX => _averageSpeed.X; + public float AverageSpeedY => _averageSpeed.Y; + public float AverageSpeedZ => _averageSpeed.Z; + public float AverageSpeedXY => new Vector2(_averageSpeed.X, _averageSpeed.Y).Length(); + public float AverageSpeedXYZ => _averageSpeed.Length(); + + public float AverageSpeedDuration { get; set; } = 5.0f; + + public bool Active { get; set; } = true; + + #endregion + + #region Private Properties + + private GenericSpeedMonitorExtra Extra { get; } + + #endregion + + #region Fields + + private Vector3 _speed; + private Vector3 _averageSpeed; + + private Vector3 _lastPosition; + private long _lastTime; + + private Dictionary _speedHistory; + + #endregion + + #region Public Methods + + public async Task UpdateSpeedTask() + { + _speedHistory = new Dictionary(); + + await Task.Run(async () => + { + while (Active) { + try { + int processHandle = Extra.GameManager.GetProcessHandle(false); + + if (processHandle >= 0) { + + var position = Extra.PlayerCoordinates; + var newTime = DateTime.Now.Ticks; + float timeDelta = (newTime - _lastTime) / (float)TimeSpan.TicksPerSecond; + + if (timeDelta > 0) { + _speed = (position - _lastPosition) / timeDelta; + _speedHistory.Add(newTime, _speed); + } + + // Remove old speeds from the history + long cutoffTime = newTime - (long)(AverageSpeedDuration * TimeSpan.TicksPerSecond); + _speedHistory = _speedHistory. + Where(kv => kv.Key > cutoffTime). + ToDictionary(kv=>kv.Key, kv=>kv.Value); + + _averageSpeed = _speedHistory.Aggregate(Vector3.Zero, + (s, v) => s + v.Value) / _speedHistory.Count; + + _lastPosition = position; + _lastTime = DateTime.Now.Ticks; + + OnPropertyChanged(nameof(PositionX)); + OnPropertyChanged(nameof(PositionY)); + OnPropertyChanged(nameof(PositionZ)); + + OnPropertyChanged(nameof(SpeedX)); + OnPropertyChanged(nameof(SpeedY)); + OnPropertyChanged(nameof(SpeedZ)); + OnPropertyChanged(nameof(SpeedXY)); + OnPropertyChanged(nameof(SpeedXYZ)); + + OnPropertyChanged(nameof(AverageSpeedX)); + OnPropertyChanged(nameof(AverageSpeedY)); + OnPropertyChanged(nameof(AverageSpeedZ)); + OnPropertyChanged(nameof(AverageSpeedXY)); + OnPropertyChanged(nameof(AverageSpeedXYZ)); + } + + await Task.Delay(100); + } catch (Exception ex) { + MessageBox.Show(ex.Message); + } + } + }); + } + + #endregion + } +} \ No newline at end of file diff --git a/OpenSpaceToolbox/Windows/SpeedMonitorWindow.xaml b/OpenSpaceToolbox/Windows/SpeedMonitorWindow.xaml new file mode 100644 index 0000000..9cb5cab --- /dev/null +++ b/OpenSpaceToolbox/Windows/SpeedMonitorWindow.xaml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenSpaceToolbox/Windows/SpeedMonitorWindow.xaml.cs b/OpenSpaceToolbox/Windows/SpeedMonitorWindow.xaml.cs new file mode 100644 index 0000000..bbd581f --- /dev/null +++ b/OpenSpaceToolbox/Windows/SpeedMonitorWindow.xaml.cs @@ -0,0 +1,26 @@ +using System.Threading.Tasks; +using System.Windows; + +namespace OpenSpaceToolbox +{ + /// + /// Interaction logic for GlmWindow.xaml + /// + public partial class SpeedMonitorWindow : Window + { + public SpeedMonitorWindow(SpeedMonitorWindowViewModel viewModel) + { + InitializeComponent(); + + DataContext = ViewModel = viewModel; + //Task.Run(viewModel.UpdateSpeed); + } + + private SpeedMonitorWindowViewModel ViewModel { get; } + + private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) + { + ViewModel.Active = false; + } + } +} diff --git a/OpenSpaceToolbox/packages.config b/OpenSpaceToolbox/packages.config index a7c03f8..f9d35eb 100644 --- a/OpenSpaceToolbox/packages.config +++ b/OpenSpaceToolbox/packages.config @@ -4,5 +4,6 @@ + \ No newline at end of file