/*****************************************************************
 * CodeName: SceneFactory.Net
 * Copyright: Virtual Media Systems, S.L. 2003
 * Assembly: Core
 * Type: Source Code (Class Library)
 * Version: 0.1
 * Description: Hi-Res Timer Library (Win32 Only)
 * 
 * Revisions
 * ------------------------------------------------
 * [F] 20/10/2003, Jcl - Shaping the thing up
 *   - Implemented Standard Timer using Kernel32 Performance Counters (Win32 Only)
 * [F] 7/11/2003, Jcl
 *   - Implemented SlideCounts, renamed CClass to .NET default
 *   - Fixed a bug with timing offset (presumably)
 *****************************************************************/
 
using System;
using System.Runtime.InteropServices;
 
using SceneFactory.Core;
using SceneFactory.Core.Utils;
 
namespace SceneFactory.Core.Utils
{
  public class Timer
  {
    [DllImport("kernel32", EntryPoint="QueryPerformanceCounter")]
    protected static extern uint QueryPerformanceCounter(ref long t);
 
    [DllImport("kernel32", EntryPoint="QueryPerformanceFrequency")]
    protected static extern uint QueryPerformanceFrequency(ref long t);
 
    public  const long TimerPrecision_Seconds = 1;
    public  const long TimerPrecision_TenthSeconds = 10;
    public  const long TimerPrecision_HundredthSeconds = 100;
    public  const long TimerPrecision_Millisecond = 1000;
    public  const long TimerPrecision_TenthMillisecond = 10000;
    public  const long TimerPrecision_HundredthMillisecond = 100000;
    public  const long TimerPrecision_MicroSecond = 1000000;
    public  const long TimerPrecision_NanoSecond = 1000000000;
 
    protected long m_StartValue;
    protected long m_ActualValue;
    protected long m_CounterFrequency;
    protected long m_Offset;
    protected long m_OffsetPrecision;
 
    protected bool m_Initialized;
 
    public long Milliseconds { get { return GetMs(); } }
 
    public Timer()
    {
      Initialize(0);
    }
 
    public Timer(long Offset)
    {
      Initialize(Offset);
    }
 
    protected void Initialize(long Offset) 
    {
      m_Initialized = false;
      m_StartValue = 0;
      m_ActualValue = 0;
      m_Offset = Offset;
      m_OffsetPrecision = TimerPrecision_Millisecond;
      try 
      {
        QueryPerformanceFrequency(ref m_CounterFrequency);
        m_Initialized = true;
      } 
      catch(System.EntryPointNotFoundException e) 
      {
        SFLog.ExceptionLog(Lang.GetString("CantLoadTimerRoutine"),e);                
      }
    }
 
    public void Start()
    {
      if(!m_Initialized)
        return;
 
      QueryPerformanceCounter(ref m_StartValue);
    }
 
    public void ResetOffset()
    {
      m_Offset = 0;
      m_OffsetPrecision = TimerPrecision_Millisecond;
    }
 
    public void TimerOffset(long Offset)
    {
      if(!m_Initialized)
        return;
 
      TimerOffset(Offset, m_OffsetPrecision);
    }
 
    public void TimerOffset(long Offset, long Precision)
    {
      if(!m_Initialized)
        return;
 
      if(Precision != m_OffsetPrecision) 
      {
        // Convert Offset to requested precision before adding
        m_Offset = m_Offset * Precision / m_OffsetPrecision;
      }
      m_OffsetPrecision = Precision;
      m_Offset += Offset;
    }
 
    public long GetPrecisionTimeCount(long Precision)
    {
      if(!m_Initialized)
        return 0;
 
      QueryPerformanceCounter(ref m_ActualValue);
      m_ActualValue -= m_StartValue;
      return (m_ActualValue * Precision / m_CounterFrequency) + ((m_Offset * m_OffsetPrecision)/ Precision);
    }
 
    public long GetSlidePosition(long StartValue, long EndValue, long StartMilliseconds, long EndMilliseconds) 
    {
      long Time = GetMs();
      if(EndMilliseconds-StartMilliseconds == 0)
        return StartValue;
      if(StartMilliseconds>EndMilliseconds) 
      {
        long vSwap = EndMilliseconds;
        EndMilliseconds = StartMilliseconds;
        StartMilliseconds = vSwap;
      }
      if(Time<=StartMilliseconds)
        return StartValue;
      if(Time>=EndMilliseconds)
        return EndValue;
 
      return StartValue + ((Time-StartMilliseconds)*(EndValue-StartValue)/(EndMilliseconds-StartMilliseconds));                                             
    }
 
    public long GetCurrentFrame(long TotalFrames, long TotalMilliseconds)
    {
      if(!m_Initialized)
        return 0;
 
      QueryPerformanceCounter(ref m_ActualValue);
      m_ActualValue -= m_StartValue;
      long t = (m_ActualValue * TimerPrecision_Millisecond / m_CounterFrequency) + ((m_Offset * m_OffsetPrecision)/ TimerPrecision_Millisecond);
      return (TotalFrames * t)/TotalMilliseconds;
    }
 
    public long GetMs()
    {
      if(!m_Initialized)
        return 0;
 
      return GetPrecisionTimeCount(TimerPrecision_Millisecond);
    }
 
    public long GetTimerTicks()
    {
      if(!m_Initialized)
        return 0;
 
      QueryPerformanceCounter(ref m_ActualValue);
      m_ActualValue -= m_StartValue;
      return m_ActualValue;
    }
 
    public long GetTicksPerSecond()
    {
      if(!m_Initialized)
        return 0;
 
      return m_CounterFrequency/1000;
    }
  }
}
 

Download timer.cs timer.cs - 5.2 KB