// Copyright 1994 Brad Pitzel
//
// Feel free to use/distribute/modify as long as credit/copyrights for myself 
// are included.

// File   : $__self$
// Name   : $__alias$
// Status : $__status$
// Changed: $__mtime$

#include "Timer.h"


timeval Timer::VlastClk;
timeval Timer::VnewClk;
long	Timer::VfTime=0;
long	Timer::Vlast=0;
long	Timer::Vnew=0;
long	Timer::VendSleep=0;
int	Timer::VframeRate=0;


// set frame rate to 'f' frames per second
void Timer::setFrameRate( int f ) 
	{ 
	VframeRate = f;
	VfTime = 1000000/f; 
	}
    	
// call once before entering animation loops
void Timer::init() 
	{ 
	gettimeofday(&VlastClk,NULL); 
	gettimeofday(&VnewClk,NULL); 
	VendSleep = VlastClk.tv_usec;
	}
    
// pause required amount of time to get proper frame rate
long Timer::sync()
    	{
    	long delta=0,wait=0;
    	
    	gettimeofday(&VnewClk, NULL);	// get current time
	

    	
	if (VnewClk.tv_usec<VendSleep) VendSleep-=1000000;

	// figure out how long to wait. Min is 0 usec, max is ftime.
    	wait  = ((VfTime - VnewClk.tv_usec + VendSleep) >? 0) <? VfTime;
    	usleep( wait );
    	
    	// This should approx. be the current time, but if usleep took
    	// alot longer than it should have, the next 'wait' value will
    	// be shorter. This will SOMEWHAT even out the peformance under
    	// varying CPU loads.  Needs improvement tho (need real-time linux :-)
    	VendSleep = VnewClk.tv_usec + wait;

	// calc the time between sleeps (not including sleeping time)
	// This give you the time between calls to sync(), therefore the
	// time to create one frame of animation.
   	delta = VnewClk.tv_usec - VlastClk.tv_usec;
   
	gettimeofday(&VlastClk, NULL);
	
	return delta;
	}
