#include #include #include #include "Timer.h" #include "memory.h" #include "SaveGame.h" // // Created 1997/07/01 Darren Stone // // // support for named, low-resolution timers // (specified in seconds, based on universe time) // // the named referencing of these timers make using // them a little slower, but friendly for scripting, etc. // sdword timersAllocated = 0; sdword timersUsed = 0; Timer *timers = NULL; static Timer *timTimerFind(char *name) { sdword i; for (i = 0; i < timersUsed; ++i) if (!strncmp(timers[i].name, name, TIMER_NAME_MAX_LENGTH)) break; if (i >= timersUsed) return NULL; // doesn't exist else return timers+i; } void timTimerStart(char *name) { Timer *tp; tp = timTimerFind(name); if (!tp) return; if (tp->duration > 0) { tp->startTime = universe.totaltimeelapsed; tp->enabled = 1; tp->bPaused = FALSE; } else tp->enabled = 0; } void timTimerStop(char *name) { Timer *tp; tp = timTimerFind(name); if (!tp) return; tp->duration = (real32)timTimerRemaining(name); tp->enabled = 0; } sdword timTimerExpired(char *name) { if (!timTimerFind(name)) return 0; // non-existent timers haven't "expired" return !timTimerRemaining(name); } sdword timTimerExpiredDestroy(char *name) { if (!timTimerFind(name)) return 0; // non-existent timers haven't "expired" if (!timTimerRemaining(name)) { timTimerDestroy(name); return 1; } else return 0; } sdword timTimerRemaining(char *name) { Timer *tp; sdword rem; tp = timTimerFind(name); if (!tp) return 0; if (tp->bPaused) { return(SDWORD_Max); } if ((!tp->enabled)) return 0; rem = (sdword)(tp->duration - (universe.totaltimeelapsed - tp->startTime)); if (rem <= 0) { tp->enabled = 0; rem = 0; } return rem; } void timTimerSet(char *name, sdword duration) { Timer *tp; tp = timTimerFind(name); if (!tp) return; tp->duration = (real32)duration; } void timTimerDestroy(char *name) { sdword i; for (i = 0; i < timersUsed; ++i) if (!strncmp(timers[i].name, name, TIMER_NAME_MAX_LENGTH)) break; if (i >= timersUsed) return; // doesn't exist while (i < timersUsed-1) { memcpy(timers + i, timers + i+1, sizeof(Timer)); ++i; } --timersUsed; } void timTimerDestroyAll(void) { if (timers) { memFree(timers); timers = NULL; } timersAllocated = 0; timersUsed = 0; } void timTimerCreate(char *name) { if (timTimerFind(name)) return; // already exists // allocate more if necessary if (timersUsed >= timersAllocated) { timers = memRealloc(timers, sizeof(Timer) * (timersAllocated + TIMER_ALLOC_INCREMENT), "timers", 0); timersAllocated += TIMER_ALLOC_INCREMENT; } memStrncpy(timers[timersUsed].name, name, TIMER_NAME_MAX_LENGTH); if (strlen(name) < TIMER_NAME_MAX_LENGTH) timers[timersUsed].name[strlen(name)] = 0; else timers[timersUsed].name[TIMER_NAME_MAX_LENGTH] = 0; timers[timersUsed].duration = 0; timers[timersUsed].enabled = 0; timers[timersUsed].bPaused = 0; ++timersUsed; } // // saves having to do a create, then a set, then a start // with separate operations. // void timTimerCreateSetStart(char *name, sdword duration) { timTimerCreate(name); timTimerSet(name, duration); timTimerStart(name); } /*----------------------------------------------------------------------------- Name : timTimerPause Description : Pause a timer. Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void timTimerPause(Timer *tim) { dbgAssert(tim); tim->pauseTime = universe.totaltimeelapsed; tim->bPaused = TRUE; } /*----------------------------------------------------------------------------- Name : timTimerPauseAllNotScoped Description : Pauses all timers that do not have the specified scope name Inputs : scopeName - name of the FSM that called this function. Outputs : Return : ----------------------------------------------------------------------------*/ void timTimerPauseAllNotScoped(char *scopeName) { Timer *tim = timers; sdword index, stringLength = strlen(scopeName); for (index = 0; index < timersUsed; index++, tim++) { if (memcmp(scopeName, tim->name, stringLength)) { //if does not match scope name timTimerPause(tim); } } } /*----------------------------------------------------------------------------- Name : timTimerUnpause Description : Unpause a timer. Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void timTimerUnpause(Timer *tim) { tim->duration += universe.totaltimeelapsed - tim->pauseTime; tim->bPaused = FALSE; } /*----------------------------------------------------------------------------- Name : timTimerUnpauseAll Description : Resume all previously paused timers. Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void timTimerUnpauseAll(void) { Timer *tim = timers; sdword index; for (index = 0; index < timersUsed; index++, tim++) { if (tim->bPaused) { //if this timer is paused timTimerUnpause(tim); } } } /*============================================================================= Save Game Stuff below: =============================================================================*/ void timTimerSave(void) { SaveInfoNumber(timersAllocated); SaveInfoNumber(timersUsed); if (timersAllocated > 0) { dbgAssert(timers); // just number data, no pointers in Timer so we can just save this way SaveStructureOfSize(timers,timersAllocated * sizeof(Timer)); } } void timTimerLoad(void) { timersAllocated = LoadInfoNumber(); timersUsed = LoadInfoNumber(); if (timersAllocated > 0) { timers = LoadStructureOfSize(timersAllocated * sizeof(Timer)); } else { timers = NULL; } }