MoonWorks/src/Game.cs

95 lines
2.8 KiB
C#

using System;
using SDL2;
using Campari;
using System.Collections.Generic;
namespace MoonWorks
{
public abstract class Game
{
private bool quit = false;
private double timestep;
ulong currentTime = SDL.SDL_GetPerformanceCounter();
double accumulator = 0;
public IntPtr WindowHandle { get; }
public GraphicsDevice GraphicsDevice { get; }
public Input Input { get; }
private Dictionary<PresentMode, RefreshCS.Refresh.PresentMode> moonWorksToRefreshPresentMode = new Dictionary<PresentMode, RefreshCS.Refresh.PresentMode>
{
{ PresentMode.Immediate, RefreshCS.Refresh.PresentMode.Immediate },
{ PresentMode.Mailbox, RefreshCS.Refresh.PresentMode.Mailbox },
{ PresentMode.FIFO, RefreshCS.Refresh.PresentMode.FIFO },
{ PresentMode.FIFORelaxed, RefreshCS.Refresh.PresentMode.FIFORelaxed }
};
public Game(uint windowWidth, uint windowHeight, PresentMode presentMode, int targetTimestep = 60, bool debugMode = false)
{
timestep = 1.0 / targetTimestep;
if (SDL.SDL_Init(SDL.SDL_INIT_VIDEO | SDL.SDL_INIT_TIMER | SDL.SDL_INIT_GAMECONTROLLER) < 0)
{
System.Console.WriteLine("Failed to initialize SDL!");
return;
}
WindowHandle = SDL.SDL_CreateWindow(
"CampariTest",
SDL.SDL_WINDOWPOS_UNDEFINED,
SDL.SDL_WINDOWPOS_UNDEFINED,
(int)windowWidth,
(int)windowHeight,
SDL.SDL_WindowFlags.SDL_WINDOW_VULKAN
);
GraphicsDevice = new GraphicsDevice(WindowHandle, moonWorksToRefreshPresentMode[presentMode], debugMode);
Input = new Input();
}
public void Run()
{
while (!quit)
{
var newTime = SDL.SDL_GetPerformanceCounter();
double frameTime = (newTime - currentTime) / (double)SDL.SDL_GetPerformanceFrequency();
if (frameTime > 0.25)
{
frameTime = 0.25;
}
currentTime = newTime;
accumulator += frameTime;
bool updateThisLoop = (accumulator >= timestep);
if (!quit)
{
while (accumulator >= timestep)
{
SDL.SDL_PumpEvents();
Input.Update();
Update(timestep);
accumulator -= timestep;
}
if (updateThisLoop)
{
Draw();
}
}
}
}
protected abstract void Update(double dt);
protected abstract void Draw();
}
}