Files
PCK-Studio/MinecraftUSkinEditor/Classes/StoneVOX/client/SyncWindow.cs
PhoenixARC 10f1c8daa0 update
2021-08-09 19:05:20 -04:00

227 lines
8.0 KiB
C#

using OpenTK;
using OpenTK.Graphics;
using OpenTK.Platform;
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
namespace stonevox
{
public class SyncWindow : GameWindow, IGameWindow, INativeWindow, IDisposable
{
[DllImport("kernel32.dll", ExactSpelling = true)]
public static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
public int targetFps;
public SyncWindow(int width, int height, GraphicsMode mode)
: base(width, height, mode)
{
}
public void Run_WithErrorCatching(int targetFps)
{
this.targetFps = targetFps;
base.Visible = true;
try
{
TargetUpdateFrequency = this.targetFps;
TargetRenderFrequency = this.targetFps;
FrameEventArgs updateArgs = new FrameEventArgs();
FrameEventArgs renderArgs = new FrameEventArgs();
OnLoad(EventArgs.Empty);
OnResize(EventArgs.Empty);
Stopwatch stopWatch = Stopwatch.StartNew();
int[] sleepTimes = new int[15];
for (int i = 0; i < sleepTimes.Length; i++) sleepTimes[i] = 1000 / this.targetFps;
int frameSleepTime = 0;
int frames = 0;
double previousElapsedSeconds = 0;
while (true)
{
frames++;
double totalElapsedSeconds = stopWatch.Elapsed.TotalSeconds;
double frameElapsedSeconds = totalElapsedSeconds - previousElapsedSeconds;
previousElapsedSeconds = totalElapsedSeconds;
if (totalElapsedSeconds >= 0.25)
{
double fps = frames / totalElapsedSeconds;
if (fps < this.targetFps)
{
int max = 0;
for (int i = 1; i < sleepTimes.Length; i++)
{
if (sleepTimes[i] > sleepTimes[max]) max = i;
}
sleepTimes[max] = System.Math.Max(0, sleepTimes[max] - 1);
}
else
{
int min = 0;
for (int i = 1; i < sleepTimes.Length; i++)
{
if (sleepTimes[i] < sleepTimes[min]) min = i;
}
sleepTimes[min] += 1;
}
stopWatch.Reset();
stopWatch.Start();
frames = 0;
previousElapsedSeconds = 0;
}
ProcessEvents();
updateArgs = new FrameEventArgs(frameElapsedSeconds);
this.OnUpdateFrame(updateArgs);
renderArgs = new FrameEventArgs(frameElapsedSeconds);
this.OnRenderFrame(renderArgs);
System.Threading.Thread.Sleep(sleepTimes[frameSleepTime]);
frameSleepTime = (frameSleepTime + 1) % sleepTimes.Length;
}
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("");
Console.WriteLine("Exception Caught - exiting main loop.");
string stacktrace = ex.ToString().ToLower();
stacktrace = stacktrace.Replace("c:\\users\\daniel\\documents\\github\\stonevox3d\\", "");
Console.WriteLine(stacktrace);
Console.WriteLine("");
SetForegroundWindow(GetConsoleWindow());
var result = MessageBox.Show("Would you like to copy crash info to the clipboard?", "StoneVox Encountered An Error", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
Clipboard.SetText(stacktrace);
}
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("");
Console.WriteLine("Crash info copied to clipboard.");
Console.WriteLine("");
Console.ForegroundColor = ConsoleColor.White;
}
finally
{
Debug.Print("Restoring priority.");
Thread.CurrentThread.Priority = ThreadPriority.Normal;
OnUnload(EventArgs.Empty);
if (Exists)
{
Context.Dispose();
}
while (this.Exists)
this.ProcessEvents();
}
}
public void Run_NoErrorCatching(int targetFps)
{
this.targetFps = targetFps;
base.Visible = true;
while (!IsExiting)
{
TargetUpdateFrequency = this.targetFps;
TargetRenderFrequency = this.targetFps;
FrameEventArgs updateArgs = new FrameEventArgs();
FrameEventArgs renderArgs = new FrameEventArgs();
OnLoad(EventArgs.Empty);
OnResize(EventArgs.Empty);
Stopwatch stopWatch = Stopwatch.StartNew();
int[] sleepTimes = new int[15];
for (int i = 0; i < sleepTimes.Length; i++) sleepTimes[i] = 1000 / this.targetFps;
int frameSleepTime = 0;
int frames = 0;
double previousElapsedSeconds = 0;
while (true)
{
frames++;
double totalElapsedSeconds = stopWatch.Elapsed.TotalSeconds;
double frameElapsedSeconds = totalElapsedSeconds - previousElapsedSeconds;
previousElapsedSeconds = totalElapsedSeconds;
if (totalElapsedSeconds >= 0.25)
{
double fps = frames / totalElapsedSeconds;
if (fps < this.targetFps)
{
int max = 0;
for (int i = 1; i < sleepTimes.Length; i++)
{
if (sleepTimes[i] > sleepTimes[max]) max = i;
}
sleepTimes[max] = System.Math.Max(0, sleepTimes[max] - 1);
}
else
{
int min = 0;
for (int i = 1; i < sleepTimes.Length; i++)
{
if (sleepTimes[i] < sleepTimes[min]) min = i;
}
sleepTimes[min] += 1;
}
stopWatch.Reset();
stopWatch.Start();
frames = 0;
previousElapsedSeconds = 0;
}
ProcessEvents();
updateArgs = new FrameEventArgs(frameElapsedSeconds);
this.OnUpdateFrame(updateArgs);
renderArgs = new FrameEventArgs(frameElapsedSeconds);
this.OnRenderFrame(renderArgs);
System.Threading.Thread.Sleep(sleepTimes[frameSleepTime]);
frameSleepTime = (frameSleepTime + 1) % sleepTimes.Length;
}
}
Thread.CurrentThread.Priority = ThreadPriority.Normal;
OnUnload(EventArgs.Empty);
if (Exists)
{
Context.Dispose();
}
while (this.Exists)
this.ProcessEvents();
}
}
}