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);
}