@ -1,10 +1,8 @@
using DotSDL.Events ;
using DotSDL.Input ;
using DotSDL.Interop.Core ;
using DotSDL.Platform ;
using System ;
using System.Collections.Generic ;
using System.Diagnostics ;
using System.Linq ;
namespace DotSDL.Graphics {
@ -21,26 +19,15 @@ namespace DotSDL.Graphics {
private IntPtr _ texture ;
private bool _ hasTexture ;
private float _ videoUpdateRate , _ gameUpdateRate ;
private float _ videoUpdateMs , _ gameUpdateMs ;
private bool _ videoUpdateUncapped , _ gameUpdateUncapped ;
private bool _ running ;
private float _ nextVideoUpdate ;
private float _ nextGameUpdate ;
private float _ updateDelta ;
private uint _ nextVideoUpdate ;
private uint _ nextGameUpdate ;
private List < Canvas > _d rawList = new List < Canvas > ( ) ;
private ScalingQuality _ scalingQuality = ScalingQuality . Nearest ;
/// <summary>
/// An <see cref="IPlatform"/> that contains native functions appropriate to
/// the platform that this application is running on.
/// </summary>
protected IPlatform Platform { get ; } = PlatformFactory . GetPlatform ( ) ;
/// <summary>Gets the background layer of this window. This is equivalent to accessing Layers[0].</summary>
public Canvas Background = > Layers [ 0 ] ;
@ -81,35 +68,11 @@ namespace DotSDL.Graphics {
public int RenderHeight { get ; }
/// <summary>The amount of time, in milliseconds, from when the application was started.</summary>
public float MillisecondsElapsed { get ; private set ; } = 0.0f ;
/// <summary>Gets or sets the rate, in hertz, between video updates.</summary>
public float VideoUpdateRate {
get = > _ videoUpdateUncapped ? 0 : _ videoUpdateRate ;
set {
_ videoUpdateRate = value ;
if ( System . Math . Abs ( _ videoUpdateRate ) < 1.0f ) {
_ videoUpdateUncapped = true ;
} else {
_ videoUpdateUncapped = false ;
_ videoUpdateMs = 1 0 0 0 / _ videoUpdateRate ;
}
}
}
/// <summary>Gets or sets the rate, in hertz, between game (logic) updates.</summary>
public float GameUpdateRate {
get = > _ gameUpdateUncapped ? 0 : _ gameUpdateRate ;
set {
_ gameUpdateRate = value ;
if ( System . Math . Abs ( _ gameUpdateRate ) < 1.0f ) {
_ gameUpdateUncapped = true ;
} else {
_ gameUpdateUncapped = false ;
_ gameUpdateMs = 1 0 0 0 / _ gameUpdateRate ;
}
}
}
public uint TicksElapsed = > Timer . GetTicks ( ) ;
/// <summary>Gets or sets the amount of time, in milliseconds, between video updates.</summary>
public uint VideoUpdateTicks { get ; set ; }
/// <summary>Gets or sets the amount of time, in milliseconds, between game (logic) updates.</summary>
public uint GameUpdateTicks { get ; set ; }
/// <summary>Gets a <see cref="Rectangle"/> that can be manipulated to modify how much of the scene is displayed.</summary>
public Rectangle CameraView { get ; }
@ -319,11 +282,11 @@ namespace DotSDL.Graphics {
/// <summary>
/// Handles updating the application logic for the <see cref="SdlWindow"/>.
/// </summary>
private void BaseUpdate ( float delta ) {
private void BaseUpdate ( ) {
if ( IsDestroyed ) return ;
Events . EventHandler . ProcessEvents ( ) ;
OnUpdate ( delta ) ; // Call the overridden Update function.
OnUpdate ( ) ; // Call the overridden Update function.
}
/// <summary>
@ -455,40 +418,26 @@ namespace DotSDL.Graphics {
/// A game loop that calls the <see cref="SdlWindow"/> update and draw functions.
/// </summary>
private void Loop ( ) {
long MsToNs ( float ms ) = > ( long ) ( ms * 1 0 0 0 0 0 0 ) ;
var sw = new Stopwatch ( ) ;
_ running = true ;
while ( _ running ) {
sw . Restart ( ) ;
var ticks = TicksElapsed ;
if ( _ nextGameUpdate < = 0 | | _ gameUpdateUncapped ) {
BaseUpdate ( _ updateDelta ) ;
_ updateDelta = 0 ;
_ nextGameUpdate + = _ gameUpdateMs ;
if ( ticks > _ nextGameUpdate | | GameUpdateTicks = = 0 ) {
_ nextGameUpdate = ticks + GameUpdateTicks ;
BaseUpdate ( ) ;
}
if ( _ nextVideoUpdate < = 0 | | _ videoUpdateUncapped ) {
if ( ticks > _ nextVideoUpdate | | VideoUpdateTicks = = 0 ) {
_ nextVideoUpdate = ticks + VideoUpdateTicks ;
BaseDraw ( ) ;
_ nextVideoUpdate + = _ videoUpdateMs ;
}
var cycleElapsed = ( float ) sw . Elapsed . TotalMilliseconds ;
MillisecondsElapsed + = cycleElapsed ;
_ nextGameUpdate - = cycleElapsed ;
_ nextVideoUpdate - = cycleElapsed ;
_ updateDelta + = cycleElapsed ;
if ( VideoUpdateTicks < = 0 & & GameUpdateTicks < = 0 ) continue ; // Cook the CPU!
if ( ! _ videoUpdateUncapped & & ! _ gameUpdateUncapped ) {
var waitMs = _ nextGameUpdate > _ nextVideoUpdate ? _ nextVideoUpdate : _ nextGameUpdate ;
if ( waitMs > 0 )
Platform . Nanosleep ( MsToNs ( waitMs ) ) ;
_ updateDelta + = waitMs ;
_ nextGameUpdate - = waitMs ;
_ nextVideoUpdate - = waitMs ;
}
var updateTicks = ( long ) ( _ nextGameUpdate > _ nextVideoUpdate ? _ nextVideoUpdate : _ nextGameUpdate ) - TicksElapsed ;
if ( updateTicks > 0 )
Timer . Delay ( ( uint ) updateTicks ) ;
}
}
@ -529,7 +478,7 @@ namespace DotSDL.Graphics {
/// <summary>
/// Called every time the application logic update runs.
/// </summary>
protected virtual void OnUpdate ( float delta ) { }
protected virtual void OnUpdate ( ) { }
/// <summary>
/// Removes a layer from the layer stack.
@ -551,17 +500,17 @@ namespace DotSDL.Graphics {
/// <summary>
/// Displays the window and begins executing code that's associated with it.
/// </summary>
/// <param name="updateRate">The desired number of video and game logic updates per second. 0 causes the display and game to be updated as quickly as possible .</param>
public void Start ( floa t updateRate ) = > Start ( updateRate , updateRate ) ;
/// <param name="updateRate">The desired number of milliseconds between frames and game logic updates. 0 causes the display and game to be continuously updated .</param>
public void Start ( uin t updateRate ) = > Start ( updateRate , updateRate ) ;
/// <summary>
/// Displays the window and begins executing code that's associated with it.
/// </summary>
/// <param name="drawRate">The desired number of draw calls per second. 0 causes the display to be updated as quickly as possible .</param>
/// <param name="updateRate">The desired number of game logic updates per second. 0 causes the game to be updated as quickly as possible .</param>
public void Start ( float drawRate , floa t updateRate ) {
VideoUpdateRate = drawRate ;
GameUpdateRate = updateRate ;
/// <param name="drawRate">The desired number of milliseconds between draw calls. 0 causes the display to be continuously updated .</param>
/// <param name="updateRate">The desired number of milliseconds between game logic updates. 0 causes the game to be continuously updated .</param>
public void Start ( uint drawRate , uin t updateRate ) {
VideoUpdateTicks = drawRate ;
GameUpdateTicks = updateRate ;
BaseLoad ( ) ;
Video . ShowWindow ( _ window ) ;