diff --git a/gui/App.xaml b/gui/App.xaml index d0c3c3d..68601ec 100644 --- a/gui/App.xaml +++ b/gui/App.xaml @@ -150,6 +150,9 @@ + + + diff --git a/gui/App.xaml.cs b/gui/App.xaml.cs index d2a748b..43a6f0a 100644 --- a/gui/App.xaml.cs +++ b/gui/App.xaml.cs @@ -1,8 +1,38 @@ +using System.Runtime.InteropServices; using System.Windows; +using System.Windows.Media.Animation; namespace CapyLauncher { public partial class App : Application { + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + struct DisplayMode + { + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string DeviceName; + public short SpecVersion, DriverVersion, Size, DriverExtra; + public int Fields, PositionX, PositionY, Orientation, FixedOutput; + public short Color, Duplex, YResolution, TTOption, Collate; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string FormName; + public short LogPixels; + public int BitsPerPel, PelsWidth, PelsHeight, DisplayFlags, DisplayFrequency; + public int IcmMethod, IcmIntent, MediaType, DitherType, Reserved1, Reserved2, PanningWidth, PanningHeight; + } + + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + static extern bool EnumDisplaySettings(string device, int mode, ref DisplayMode devMode); + + static int RefreshRate() + { + var mode = new DisplayMode { Size = (short)Marshal.SizeOf(typeof(DisplayMode)) }; + if (!EnumDisplaySettings(null, -1, ref mode) || mode.DisplayFrequency <= 1) + return 60; + return mode.DisplayFrequency; + } + + public App() + { + Timeline.DesiredFrameRateProperty.OverrideMetadata(typeof(Timeline), new FrameworkPropertyMetadata { DefaultValue = RefreshRate() }); + } } } diff --git a/gui/MainWindow.xaml b/gui/MainWindow.xaml index d03261c..bef4b3b 100644 --- a/gui/MainWindow.xaml +++ b/gui/MainWindow.xaml @@ -14,23 +14,23 @@ - - + + - + - + - + - + - + @@ -40,24 +40,39 @@ - - - - - + + + + + + + + + - - + + + + + + + + + - - + + + + + + + + + - - - diff --git a/gui/MainWindow.xaml.cs b/gui/MainWindow.xaml.cs index 7bf0437..495b372 100644 --- a/gui/MainWindow.xaml.cs +++ b/gui/MainWindow.xaml.cs @@ -66,7 +66,6 @@ namespace CapyLauncher string dispatch, gamePort, lastError; bool closing; int frame; - double bob; public MainWindow() { @@ -403,6 +402,24 @@ namespace CapyLauncher EmptyCapy.Source = swim[0]; } + void Bob(bool on) + { + var move = (TranslateTransform)Capy.RenderTransform; + if (!on) + { + move.BeginAnimation(TranslateTransform.YProperty, new DoubleAnimation(0, TimeSpan.FromMilliseconds(300))); + return; + } + if (move.HasAnimatedProperties && move.Y != 0) + return; + move.BeginAnimation(TranslateTransform.YProperty, new DoubleAnimation(-1.6, 1.6, TimeSpan.FromMilliseconds(900)) + { + AutoReverse = true, + RepeatBehavior = RepeatBehavior.Forever, + EasingFunction = new SineEase { EasingMode = EasingMode.EaseInOut }, + }); + } + void Swim() { bool awake = state == State.Online || state == State.Starting; @@ -411,8 +428,6 @@ namespace CapyLauncher if (awake) { Capy.Source = swim[frame]; - bob += 0.35; - ((TranslateTransform)Capy.RenderTransform).Y = Math.Sin(bob) * 1.5; } if (EmptyState.Visibility == Visibility.Visible) EmptyCapy.Source = swim[frame]; @@ -463,10 +478,10 @@ namespace CapyLauncher Animate(Capy, OpacityProperty, awake, 400); Animate(Water, OpacityProperty, up ? 0.55 : 0.2, 600); } + Bob(up); if (!up) { Capy.Source = swim[0]; - ((TranslateTransform)Capy.RenderTransform).Y = 0; UptimeText.Text = "—"; PlayerText.Text = "—"; PlayerText.Foreground = (Brush)FindResource("Text"); @@ -910,7 +925,9 @@ namespace CapyLauncher Animate(Overlay, OpacityProperty, 1, 200); Animate(scale, ScaleTransform.ScaleXProperty, 1, 260, 0, 0.94); Animate(scale, ScaleTransform.ScaleYProperty, 1, 260, 0, 0.94); - Animate(ShellBlur, BlurEffect.RadiusProperty, 10, 260); + var blur = new BlurEffect { Radius = 0 }; + Shell.Effect = blur; + Animate(blur, BlurEffect.RadiusProperty, 10, 260); } void HideDialog(bool result) @@ -918,7 +935,12 @@ namespace CapyLauncher var fade = new DoubleAnimation(0, TimeSpan.FromMilliseconds(160)); fade.Completed += (s, e) => Overlay.Visibility = Visibility.Collapsed; Overlay.BeginAnimation(OpacityProperty, fade); - Animate(ShellBlur, BlurEffect.RadiusProperty, 0, 200); + if (Shell.Effect is BlurEffect blur) + { + var clear = new DoubleAnimation(0, TimeSpan.FromMilliseconds(200)); + clear.Completed += (s, e) => { if (Overlay.Visibility != Visibility.Visible) Shell.Effect = null; }; + blur.BeginAnimation(BlurEffect.RadiusProperty, clear); + } answer?.TrySetResult(result); }