2007-06-28 10:47:08 -07:00
|
|
|
/*
|
|
|
|
* GTime.c
|
|
|
|
*
|
|
|
|
* Provide a game clock that runs only when the game runs.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2006-09-23 11:52:52 -07:00
|
|
|
#include "SDL/SDL_timer.h"
|
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
//#define DEBUG_GROUP1
|
2006-06-02 12:34:58 -07:00
|
|
|
#include "lib/framework/frame.h"
|
2007-06-28 10:47:08 -07:00
|
|
|
#include "gtime.h"
|
|
|
|
|
|
|
|
|
|
|
|
#define TIME_FIX
|
|
|
|
|
|
|
|
//#define RATE_LIMIT
|
|
|
|
|
2006-06-02 12:34:58 -07:00
|
|
|
#define GTIME_MINFRAME (GAME_TICKS_PER_SEC/80)
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
/* The current time in the game world */
|
|
|
|
UDWORD gameTime;
|
|
|
|
|
|
|
|
/* The time for the last frame */
|
|
|
|
UDWORD frameTime;
|
|
|
|
|
|
|
|
/* The current time in the game world ( never stops )*/
|
|
|
|
UDWORD gameTime2;
|
|
|
|
|
|
|
|
/* The time for the last frame (never stops)*/
|
|
|
|
UDWORD frameTime2;
|
|
|
|
|
|
|
|
|
|
|
|
// the current clock modifier
|
|
|
|
static FRACT modifier;
|
|
|
|
|
|
|
|
|
|
|
|
// the amount of game time before the last time clock speed was set
|
|
|
|
static UDWORD timeOffset;
|
|
|
|
static UDWORD timeOffset2;
|
|
|
|
|
|
|
|
// the tick count the last time the clock speed was set
|
|
|
|
static UDWORD baseTime;
|
|
|
|
static UDWORD baseTime2;
|
|
|
|
|
|
|
|
/* When the game paused so that gameTime can be adjusted when the game restarts */
|
|
|
|
static SDWORD pauseStart;
|
|
|
|
|
|
|
|
/* Count how many times gameTimeStop has been called without a game time start */
|
|
|
|
static UDWORD stopCount;
|
|
|
|
|
|
|
|
/* Initialise the game clock */
|
|
|
|
BOOL gameTimeInit(void)
|
|
|
|
{
|
|
|
|
//gameTime = 0;
|
2006-06-02 12:34:58 -07:00
|
|
|
/*start the timer off at 2 so that when the scripts strip the map of objects
|
2007-06-28 10:47:08 -07:00
|
|
|
for multiPlayer they will be processed as if they died*/
|
|
|
|
gameTime = 2;
|
|
|
|
timeOffset = 0;
|
2006-08-27 12:09:35 -07:00
|
|
|
baseTime = SDL_GetTicks();
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
gameTime2 = 0;
|
|
|
|
timeOffset2 = 0;
|
|
|
|
baseTime2 = baseTime;
|
|
|
|
|
|
|
|
|
|
|
|
modifier = FRACTCONST(1,1);
|
|
|
|
|
|
|
|
|
|
|
|
stopCount = 0;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
UDWORD getTimeValueRange(UDWORD tickFrequency, UDWORD requiredRange)
|
|
|
|
{
|
|
|
|
UDWORD div1,div2;
|
|
|
|
|
|
|
|
div1 = gameTime2%tickFrequency;
|
|
|
|
div2 = tickFrequency/requiredRange;
|
|
|
|
return(div1/div2);
|
|
|
|
}
|
|
|
|
|
|
|
|
UDWORD getStaticTimeValueRange(UDWORD tickFrequency, UDWORD requiredRange)
|
|
|
|
{
|
|
|
|
UDWORD div1,div2;
|
|
|
|
|
|
|
|
div1 = gameTime%tickFrequency;
|
|
|
|
div2 = tickFrequency/requiredRange;
|
|
|
|
return(div1/div2);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Call this each loop to update the game timer */
|
|
|
|
void gameTimeUpdate(void)
|
|
|
|
{
|
|
|
|
UDWORD currTime, fpMod;
|
|
|
|
#ifdef TIME_FIX
|
2006-09-08 13:05:38 -07:00
|
|
|
Uint64 newTime;
|
|
|
|
Uint64 extraTime;
|
2007-06-28 10:47:08 -07:00
|
|
|
#else
|
|
|
|
unsigned long long newTime;
|
|
|
|
#endif
|
|
|
|
|
2006-08-27 12:09:35 -07:00
|
|
|
currTime = SDL_GetTicks();
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
if (currTime < baseTime)
|
|
|
|
{
|
|
|
|
#ifdef RATE_LIMIT
|
|
|
|
// Limit the frame time
|
2006-06-02 12:34:58 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
// ooops the clock has wrapped round -
|
|
|
|
// someone actually managed to keep windows running for 50 days !!!!
|
|
|
|
// ........
|
|
|
|
}
|
|
|
|
|
|
|
|
//don't update the game time if gameTimeStop has been called
|
|
|
|
if (stopCount == 0)
|
|
|
|
{
|
|
|
|
|
|
|
|
// Calculate the new game time
|
|
|
|
newTime = currTime - baseTime;
|
|
|
|
|
|
|
|
// convert the modifier to fixed point cos we loose accuracy
|
|
|
|
fpMod = MAKEINT(FRACTmul(modifier, FRACTCONST(1000,1)));
|
|
|
|
|
|
|
|
newTime = newTime * fpMod / 1000;
|
|
|
|
|
|
|
|
newTime += timeOffset;
|
|
|
|
|
|
|
|
// Calculate the time for this frame
|
|
|
|
frameTime = (UDWORD)(newTime - gameTime);
|
|
|
|
|
|
|
|
// Limit the frame time
|
|
|
|
if (frameTime > GTIME_MAXFRAME)
|
|
|
|
{
|
|
|
|
#ifdef TIME_FIX
|
|
|
|
extraTime = frameTime - GTIME_MAXFRAME;
|
|
|
|
extraTime = extraTime * 1000 / fpMod;//adjust the addition to base time
|
|
|
|
baseTime += (UDWORD)extraTime;
|
|
|
|
#else
|
|
|
|
baseTime += frameTime - GTIME_MAXFRAME;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
newTime = gameTime + GTIME_MAXFRAME;
|
|
|
|
frameTime = GTIME_MAXFRAME;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Store the game time
|
|
|
|
gameTime = (UDWORD)newTime;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// now update gameTime2 which does not pause
|
|
|
|
newTime = currTime - baseTime2;
|
|
|
|
|
|
|
|
newTime += timeOffset;
|
|
|
|
|
|
|
|
// Calculate the time for this frame
|
|
|
|
frameTime2 = (UDWORD)newTime - gameTime2;
|
|
|
|
|
|
|
|
// Limit the frame time
|
|
|
|
if (frameTime2 > GTIME_MAXFRAME)
|
|
|
|
{
|
|
|
|
baseTime2 += frameTime2 - GTIME_MAXFRAME;
|
|
|
|
newTime = gameTime2 + GTIME_MAXFRAME;
|
|
|
|
frameTime2 = GTIME_MAXFRAME;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Store the game time
|
|
|
|
gameTime2 = (UDWORD)newTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// reset the game time modifiers
|
|
|
|
void gameTimeResetMod(void)
|
|
|
|
{
|
|
|
|
timeOffset = gameTime;
|
|
|
|
timeOffset2 = gameTime2;
|
|
|
|
|
2006-08-27 12:09:35 -07:00
|
|
|
baseTime = SDL_GetTicks();
|
|
|
|
baseTime2 = SDL_GetTicks();
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
modifier = FRACTCONST(1,1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// set the time modifier
|
|
|
|
void gameTimeSetMod(FRACT mod)
|
|
|
|
{
|
|
|
|
gameTimeResetMod();
|
|
|
|
modifier = mod;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get the current time modifier
|
|
|
|
void gameTimeGetMod(FRACT *pMod)
|
|
|
|
{
|
|
|
|
*pMod = modifier;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL gameTimeIsStopped(void)
|
|
|
|
{
|
|
|
|
return (stopCount != 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Call this to stop the game timer */
|
|
|
|
void gameTimeStop(void)
|
|
|
|
{
|
|
|
|
if (stopCount == 0)
|
|
|
|
{
|
2006-08-27 12:09:35 -07:00
|
|
|
pauseStart = SDL_GetTicks();
|
2006-12-01 14:22:29 -08:00
|
|
|
debug( LOG_NEVER, "Clock paused at %d\n", pauseStart);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
stopCount += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Call this to restart the game timer after a call to gameTimeStop */
|
|
|
|
void gameTimeStart(void)
|
|
|
|
{
|
|
|
|
if (stopCount == 1)
|
|
|
|
{
|
|
|
|
// shift the base time to now
|
|
|
|
timeOffset = gameTime;
|
2006-08-27 12:09:35 -07:00
|
|
|
baseTime = SDL_GetTicks();
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (stopCount > 0)
|
|
|
|
{
|
|
|
|
stopCount --;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*Call this to reset the game timer*/
|
|
|
|
void gameTimeReset(UDWORD time)
|
|
|
|
{
|
|
|
|
// reset the game timers
|
|
|
|
gameTime = time;
|
|
|
|
timeOffset = time;
|
|
|
|
|
|
|
|
gameTime2 = time;
|
|
|
|
timeOffset2 = time;
|
|
|
|
|
2006-08-27 12:09:35 -07:00
|
|
|
baseTime = SDL_GetTicks();//used from save game only so GetTickCount is as valid as anything
|
|
|
|
baseTime2 = SDL_GetTicks();
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
|
|
|
|
modifier = FRACTCONST(1,1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void getTimeComponents(UDWORD time, UDWORD *hours, UDWORD *minutes, UDWORD *seconds)
|
|
|
|
{
|
|
|
|
UDWORD h,m,s;
|
|
|
|
UDWORD tph,tpm;
|
|
|
|
|
|
|
|
/* Ticks in a minute */
|
|
|
|
tpm = GAME_TICKS_PER_SEC*60;
|
|
|
|
|
|
|
|
/* Ticks in an hour */
|
|
|
|
tph = tpm*60;
|
|
|
|
|
|
|
|
h = time/tph;
|
|
|
|
|
|
|
|
m = (time - (h*tph))/tpm;
|
|
|
|
|
|
|
|
s = (time - ((h*tph) + (m*tpm)))/GAME_TICKS_PER_SEC;
|
|
|
|
|
|
|
|
*hours = h;
|
|
|
|
*minutes = m;
|
|
|
|
*seconds = s;
|
|
|
|
}
|