From 60b9df5ba6592a2523b104386f0649124991fe7f Mon Sep 17 00:00:00 2001 From: avolkov Date: Sat, 7 Nov 2009 06:05:45 +0000 Subject: [PATCH] Game clock task retired; clock advances via a tick function and the game events are handled immediately git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3286 8092fc87-c524-0410-9efc-e669fe64eaf9 --- sc2/src/uqm/battle.c | 12 +- sc2/src/uqm/battle.h | 3 +- sc2/src/uqm/clock.c | 230 ++++++++++++++++----------------- sc2/src/uqm/clock.h | 25 ++-- sc2/src/uqm/confirm.c | 8 -- sc2/src/uqm/globdata.c | 6 - sc2/src/uqm/hyper.c | 8 -- sc2/src/uqm/load.c | 10 +- sc2/src/uqm/planets/genpet.c | 13 +- sc2/src/uqm/planets/pstarmap.c | 1 - sc2/src/uqm/planets/solarsys.c | 9 +- sc2/src/uqm/save.c | 2 +- sc2/src/uqm/ship.c | 5 - sc2/src/uqm/starbase.c | 13 +- sc2/src/uqm/starcon.c | 17 ++- sc2/src/uqm/uqmdebug.c | 33 ++--- sc2/src/uqm/util.c | 12 -- 17 files changed, 165 insertions(+), 242 deletions(-) diff --git a/sc2/src/uqm/battle.c b/sc2/src/uqm/battle.c index fae6e2aef..84b069049 100644 --- a/sc2/src/uqm/battle.c +++ b/sc2/src/uqm/battle.c @@ -313,9 +313,11 @@ DoBattle (BATTLE_STATE *bs) SetTransitionSource (&r); } BatchGraphics (); - if ((LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) && - !(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD))) - SeedUniverse (); + + // Call the callback function, if set + if (bs->frame_cb) + bs->frame_cb (); + RedrawQueue (TRUE); if (bs->first_time) @@ -331,10 +333,6 @@ DoBattle (BATTLE_STATE *bs) return FALSE; } - // Call the callback function, if set - if (bs->frame_cb) - bs->frame_cb (); - battle_speed = HIBYTE (nth_frame); if (battle_speed == (BYTE)~0) { // maximum speed, nothing rendered at all diff --git a/sc2/src/uqm/battle.h b/sc2/src/uqm/battle.h index de43242c4..3f0e1a65f 100644 --- a/sc2/src/uqm/battle.h +++ b/sc2/src/uqm/battle.h @@ -27,7 +27,8 @@ typedef DWORD BattleFrameCounter; // For NUM_SIDES // The callback function is called on every battle frame -// with GraphicsLock *not* held +// with GraphicsLock held, just before the display queue +// is drawn typedef void (BattleFrameCallback) (void); typedef struct battlestate_struct { diff --git a/sc2/src/uqm/clock.c b/sc2/src/uqm/clock.c index c8516d13b..0527b7edc 100644 --- a/sc2/src/uqm/clock.c +++ b/sc2/src/uqm/clock.c @@ -32,8 +32,11 @@ // and is hard-coded to the original 24 fps #define CLOCK_BASE_FRAMERATE 24 -static int clock_task_func(void* data); - +// WARNING: Most of clock functions are only meant to be called by the +// Starcon2Main thread! If you need access from other threads, examine +// the locking system! +// XXX: This mutex is only necessary because debugging functions +// may access the clock and event data from a different thread static Mutex clock_mutex; static BOOLEAN @@ -58,75 +61,51 @@ DaysInMonth (COUNT month, COUNT year) return days_in_month[month - 1]; } -static int -clock_task_func(void* data) +static void +nextClockDay (void) { - Task task = (Task) data; - - while (GLOBAL (GameClock).day_in_ticks == 0 && !Task_ReadState (task, TASK_EXIT)) - TaskSwitch (); - - while (!Task_ReadState (task, TASK_EXIT)) + ++GLOBAL (GameClock.day_index); + if (GLOBAL (GameClock.day_index) > DaysInMonth ( + GLOBAL (GameClock.month_index), + GLOBAL (GameClock.year_index))) { - DWORD TimeIn; - - /* use semaphore so that time passage - * can be halted. (e.g. during battle - * or communications) - */ - SetSemaphore (GLOBAL (GameClock.clock_sem)); - TimeIn = GetTimeCounter (); - - if (GLOBAL (GameClock).tick_count <= 0 - && (GLOBAL (GameClock).tick_count = GLOBAL (GameClock).day_in_ticks) > 0) - { - /* next day -- move the calendar */ - if (++GLOBAL (GameClock).day_index > DaysInMonth ( - GLOBAL (GameClock).month_index, - GLOBAL (GameClock).year_index)) - { - GLOBAL (GameClock).day_index = 1; - if (++GLOBAL (GameClock).month_index > 12) - { - GLOBAL (GameClock).month_index = 1; - ++GLOBAL (GameClock).year_index; - } - } - - LockMutex (GraphicsLock); - DrawStatusMessage (NULL); - { - HEVENT hEvent; - - while ((hEvent = GetHeadEvent ())) - { - EVENT *EventPtr; - - LockEvent (hEvent, &EventPtr); - - if (GLOBAL (GameClock).day_index != EventPtr->day_index - || GLOBAL (GameClock).month_index != EventPtr->month_index - || GLOBAL (GameClock).year_index != EventPtr->year_index) - { - UnlockEvent (hEvent); - break; - } - RemoveEvent (hEvent); - EventHandler (EventPtr->func_index); - - UnlockEvent (hEvent); - FreeEvent (hEvent); - } - } - UnlockMutex (GraphicsLock); + GLOBAL (GameClock.day_index) = 1; + ++GLOBAL (GameClock.month_index); + if (GLOBAL (GameClock.month_index) > 12) + { + GLOBAL (GameClock.month_index) = 1; + ++GLOBAL (GameClock.year_index); } - - - ClearSemaphore (GLOBAL (GameClock.clock_sem)); - SleepThreadUntil (TimeIn + ONE_SECOND / 120); } - FinishTask (task); - return(0); + + // update the date on screen + DrawStatusMessage (NULL); +} + +static void +processClockDayEvents (void) +{ + HEVENT hEvent; + + while ((hEvent = GetHeadEvent ())) + { + EVENT *EventPtr; + + LockEvent (hEvent, &EventPtr); + + if (GLOBAL (GameClock.day_index) != EventPtr->day_index + || GLOBAL (GameClock.month_index) != EventPtr->month_index + || GLOBAL (GameClock.year_index) != EventPtr->year_index) + { + UnlockEvent (hEvent); + break; + } + RemoveEvent (hEvent); + EventHandler (EventPtr->func_index); + + UnlockEvent (hEvent); + FreeEvent (hEvent); + } } BOOLEAN @@ -138,12 +117,8 @@ InitGameClock (void) GLOBAL (GameClock.month_index) = 2; GLOBAL (GameClock.day_index) = 17; GLOBAL (GameClock.year_index) = START_YEAR; /* Feb 17, START_YEAR */ - GLOBAL (GameClock).tick_count = GLOBAL (GameClock).day_in_ticks = 0; - SuspendGameClock (); - if ((GLOBAL (GameClock.clock_task) = - AssignTask (clock_task_func, 2048, - "game clock")) == 0) - return (FALSE); + GLOBAL (GameClock.tick_count) = 0; + GLOBAL (GameClock.day_in_ticks) = 0; return (TRUE); } @@ -151,14 +126,6 @@ InitGameClock (void) BOOLEAN UninitGameClock (void) { - if (GLOBAL (GameClock.clock_task)) - { - ResumeGameClock (); - - ConcludeTask (GLOBAL (GameClock.clock_task)); - - GLOBAL (GameClock.clock_task) = 0; - } DestroyMutex (clock_mutex); clock_mutex = NULL; @@ -167,52 +134,43 @@ UninitGameClock (void) return (TRUE); } +// For debugging use only void -SuspendGameClock (void) +LockGameClock (void) { - if (!clock_mutex) - { - log_add (log_Fatal, "BUG: " - "Attempted to suspend non-existent game clock"); -#ifdef DEBUG - explode (); -#endif - return; - } - LockMutex (clock_mutex); - if (GameClockRunning ()) - { - SetSemaphore (GLOBAL (GameClock.clock_sem)); - GLOBAL (GameClock.TimeCounter) = 0; - } - UnlockMutex (clock_mutex); + // Block the GameClockTick() for executing + if (clock_mutex) + LockMutex (clock_mutex); } +// For debugging use only void -ResumeGameClock (void) +UnlockGameClock (void) { - if (!clock_mutex) - { - log_add (log_Fatal, "BUG: " - "Attempted to resume non-existent game clock\n"); -#ifdef DEBUG - explode (); -#endif - return; - } - LockMutex (clock_mutex); - if (!GameClockRunning ()) - { - GLOBAL (GameClock.TimeCounter) = GetTimeCounter (); - ClearSemaphore (GLOBAL (GameClock.clock_sem)); - } - UnlockMutex (clock_mutex); + if (clock_mutex) + UnlockMutex (clock_mutex); } +// For debugging use only BOOLEAN GameClockRunning (void) { - return ((BOOLEAN)(GLOBAL (GameClock.TimeCounter) != 0)); + SIZE prev_tick, cur_tick; + + if (!clock_mutex) + return FALSE; + + LockMutex (clock_mutex); + prev_tick = GLOBAL (GameClock.tick_count); + UnlockMutex (clock_mutex); + + SleepThread (ONE_SECOND / 5); + + LockMutex (clock_mutex); + cur_tick = GLOBAL (GameClock.tick_count); + UnlockMutex (clock_mutex); + + return cur_tick != prev_tick; } void @@ -220,7 +178,6 @@ SetGameClockRate (COUNT seconds_per_day) { SIZE new_day_in_ticks, new_tick_count; - SetSemaphore (GLOBAL (GameClock.clock_sem)); new_day_in_ticks = (SIZE)(seconds_per_day * CLOCK_BASE_FRAMERATE); if (GLOBAL (GameClock.day_in_ticks) == 0) new_tick_count = new_day_in_ticks; @@ -231,7 +188,6 @@ SetGameClockRate (COUNT seconds_per_day) new_tick_count = 1; GLOBAL (GameClock.day_in_ticks) = new_day_in_ticks; GLOBAL (GameClock.tick_count) = new_tick_count; - ClearSemaphore (GLOBAL (GameClock.clock_sem)); } BOOLEAN @@ -324,9 +280,41 @@ AddEvent (EVENT_TYPE type, COUNT month_index, COUNT day_index, COUNT return (0); } -SIZE -ClockTick (void) +// This function must be called with GraphicsLock held. +void +GameClockTick (void) { - return (--GLOBAL (GameClock.tick_count)); + // XXX: This mutex is only necessary because debugging functions + // may access the clock and event data from a different thread + LockMutex (clock_mutex); + + --GLOBAL (GameClock.tick_count); + if (GLOBAL (GameClock.tick_count) <= 0) + { // next day -- move the calendar + GLOBAL (GameClock.tick_count) = GLOBAL (GameClock.day_in_ticks); + // Do not do anything until the clock is inited + if (GLOBAL (GameClock.day_in_ticks) > 0) + { + nextClockDay (); + processClockDayEvents (); + } + } + + UnlockMutex (clock_mutex); } +// This function must be called with GraphicsLock held. +void +MoveGameClockDays (COUNT days) +{ + // XXX: This should theoretically hold the clock_mutex, but if + // someone manages to hit the debug button while this function + // runs, it's their own fault :-P + + for ( ; days > 0; --days) + { + nextClockDay (); + processClockDayEvents (); + } + GLOBAL (GameClock.tick_count) = GLOBAL (GameClock.day_in_ticks); +} diff --git a/sc2/src/uqm/clock.h b/sc2/src/uqm/clock.h index 32ce3413b..41692709f 100644 --- a/sc2/src/uqm/clock.h +++ b/sc2/src/uqm/clock.h @@ -34,9 +34,6 @@ typedef struct BYTE day_index, month_index; COUNT year_index; SIZE tick_count, day_in_ticks; - Semaphore clock_sem; - Task clock_task; - DWORD TimeCounter; QUEUE event_q; /* Queue element is EVENT */ @@ -74,22 +71,34 @@ typedef enum #define ForAllEvents(callback, arg) ForAllLinks(&GLOBAL (GameClock.event_q), \ (void (*)(LINK *, void *)) (callback), (arg)) - /* rates are in seconds per game day */ +// Rates are in seconds per game day #define HYPERSPACE_CLOCK_RATE 5 +// XXX: the IP rate is based on 24 ticks/second (see SetGameClockRate), +// however, IP runs at 30 fps right now. So in reality, the IP clock +// rate is closer to 23 seconds per game day. The clock is faster, but +// the flagship also moves faster. #define INTERPLANETARY_CLOCK_RATE 30 extern BOOLEAN InitGameClock (void); extern BOOLEAN UninitGameClock (void); -extern void SuspendGameClock (void); -extern void ResumeGameClock (void); -extern BOOLEAN GameClockRunning (void); + extern void SetGameClockRate (COUNT seconds_per_day); extern BOOLEAN ValidateEvent (EVENT_TYPE type, COUNT *pmonth_index, COUNT *pday_index, COUNT *pyear_index); extern HEVENT AddEvent (EVENT_TYPE type, COUNT month_index, COUNT day_index, COUNT year_index, BYTE func_index); extern void EventHandler (BYTE selector); -extern SIZE ClockTick (void); +extern void GameClockTick (void); +extern void MoveGameClockDays (COUNT days); + +// The lock/unlock/running functions are for debugging use only +// Locking will block the GameClockTick() function and thus +// the thread moving the clock. +extern void LockGameClock (void); +extern void UnlockGameClock (void); +// A weak indicator of the clock moving. Suitable for debugging, +// but not much else +extern BOOLEAN GameClockRunning (void); #endif /* _CLOCK_H */ diff --git a/sc2/src/uqm/confirm.c b/sc2/src/uqm/confirm.c index 5e26663f2..c8df43e79 100644 --- a/sc2/src/uqm/confirm.c +++ b/sc2/src/uqm/confirm.c @@ -83,10 +83,6 @@ DoConfirmExit (void) { BOOLEAN result; - if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE && - LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE && - !(LastActivity & CHECK_RESTART)) - SuspendGameClock (); if (CommData.ConversationPhrases && PlayingTrack ()) PauseTrack (); @@ -174,10 +170,6 @@ DoConfirmExit (void) } UnlockMutex (GraphicsLock); - if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE && - LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE && - !(LastActivity & CHECK_RESTART)) - ResumeGameClock (); if (CommData.ConversationPhrases && PlayingTrack ()) ResumeTrack (); diff --git a/sc2/src/uqm/globdata.c b/sc2/src/uqm/globdata.c index b3d92f026..678b15656 100644 --- a/sc2/src/uqm/globdata.c +++ b/sc2/src/uqm/globdata.c @@ -418,12 +418,6 @@ InitGlobData (void) GLOBAL (glob_flags) = (BYTE)i; GLOBAL (DisplayArray) = DisplayArray; - // The clock semaphore was initially initialized as '1' - // but it is always cleared before set, so it toggled between - // 2 and 1, which doesn't actually do anything. - - GLOBAL (GameClock.clock_sem) = - CreateSemaphore(0, "Clock", SYNC_CLASS_TOPLEVEL); } diff --git a/sc2/src/uqm/hyper.c b/sc2/src/uqm/hyper.c index d699a498b..c5d32de60 100644 --- a/sc2/src/uqm/hyper.c +++ b/sc2/src/uqm/hyper.c @@ -357,10 +357,6 @@ LoadHyperspace (void) BOOLEAN FreeHyperspace (void) { - UnlockMutex (GraphicsLock); - SuspendGameClock (); - LockMutex (GraphicsLock); - { FRAME F; @@ -1337,8 +1333,6 @@ SeedUniverse (void) HELEMENT hHyperSpaceElement; ELEMENT *HyperSpaceElementPtr; - ClockTick (); - universe.x = LOGX_TO_UNIVERSE (GLOBAL_SIS (log_x)); universe.y = LOGY_TO_UNIVERSE (GLOBAL_SIS (log_y)); @@ -1613,7 +1607,6 @@ UnbatchGraphics (); OldColor = SetContextBackGroundColor (BLACK_COLOR); UnlockMutex (GraphicsLock); - SuspendGameClock (); memset (&MenuState, 0, sizeof (MenuState)); MenuState.InputFunc = DoFlagshipCommands; @@ -1638,7 +1631,6 @@ UnbatchGraphics (); ClearSISRect (CLEAR_SIS_RADAR); UnlockMutex (GraphicsLock); WaitForNoInput (ONE_SECOND / 2); - ResumeGameClock (); LockMutex (GraphicsLock); } diff --git a/sc2/src/uqm/load.c b/sc2/src/uqm/load.c index c40af6129..ccecdd187 100644 --- a/sc2/src/uqm/load.c +++ b/sc2/src/uqm/load.c @@ -371,7 +371,7 @@ LoadClockState (CLOCK_STATE *ClockPtr, DECODE_REF fh) cread_16 (fh, &ClockPtr->day_in_ticks); cread_ptr (fh); /* not loading ptr; Semaphore clock_sem */ cread_ptr (fh); /* not loading ptr; Task clock_task */ - cread_32 (fh, &ClockPtr->TimeCounter); /* theoretically useless */ + cread_32 (fh, NULL); /* not loading; DWORD TimeCounter */ DummyLoadQueue (&ClockPtr->event_q, fh); } @@ -566,14 +566,6 @@ LoadGame (COUNT which_game, SUMMARY_DESC *SummPtr) NextActivity = GLOBAL (CurrentActivity); GLOBAL (CurrentActivity) = Activity; - // It shouldn't be possible to ever save with TimeCounter != 0 - // But if it does happen, it needs to be reset to 0, since on load - // the clock semaphore is gauranteed to be 0 - if (GLOBAL (GameClock.TimeCounter) != 0) - log_add (log_Warning, "Warning: Game clock wasn't stopped during " - "save, Savegame may be corrupt!\n"); - GLOBAL (GameClock.TimeCounter) = 0; - LoadRaceQueue (fh, &GLOBAL (avail_race_q)); // START_INTERPLANETARY is only set when saving from Homeworld // encounter screen. When the game is loaded, GENERATE_ORBITAL will diff --git a/sc2/src/uqm/planets/genpet.c b/sc2/src/uqm/planets/genpet.c index aeed1d31b..f1a85659f 100644 --- a/sc2/src/uqm/planets/genpet.c +++ b/sc2/src/uqm/planets/genpet.c @@ -67,19 +67,12 @@ ZapToUrquanEncounter (void) { #define LOST_DAYS 15 - COUNT i; BYTE black_buf[] = {FadeAllToBlack}; SleepThreadUntil (XFormColorMap ((COLORMAPPTR)black_buf, ONE_SECOND * 2)); - for (i = 0; i < LOST_DAYS; ++i) - { - while (ClockTick () > 0) - ; - - ResumeGameClock (); - SleepThread (ONE_SECOND / 60); - SuspendGameClock (); - } + LockMutex (GraphicsLock); + MoveGameClockDays (LOST_DAYS); + UnlockMutex (GraphicsLock); } GLOBAL (CurrentActivity) = MAKE_WORD (IN_HYPERSPACE, 0) | START_ENCOUNTER; diff --git a/sc2/src/uqm/planets/pstarmap.c b/sc2/src/uqm/planets/pstarmap.c index 9c2a3f5d9..e005f6fc1 100644 --- a/sc2/src/uqm/planets/pstarmap.c +++ b/sc2/src/uqm/planets/pstarmap.c @@ -1805,7 +1805,6 @@ DoFlagshipCommands (MENU_STATE *pMS) if (pMS->Initialized <= 1) { pMS->Initialized = 1; - ResumeGameClock (); } else if (pMS->flash_task) { diff --git a/sc2/src/uqm/planets/solarsys.c b/sc2/src/uqm/planets/solarsys.c index c76563f82..3f51512e8 100644 --- a/sc2/src/uqm/planets/solarsys.c +++ b/sc2/src/uqm/planets/solarsys.c @@ -854,8 +854,6 @@ ProcessShipControls (void) COUNT index; SIZE delta_x, delta_y; - ClockTick (); - if (CurrentInputState.key[PlayerControls[0]][KEY_UP]) delta_y = -1; else @@ -1165,7 +1163,10 @@ IP_frame (void) } if (!(draw_sys_flags & DRAW_REFRESH)) + { + GameClockTick (); ProcessShipControls (); + } UndrawShip (); if (pSolarSysState->MenuState.Initialized != 1) { @@ -1270,8 +1271,6 @@ IP_frame (void) } else { - SuspendGameClock (); - LockMutex (GraphicsLock); DrawStatusMessage (NULL); if (LastActivity == CHECK_LOAD) @@ -1403,7 +1402,6 @@ StartGroups: } } - ResumeGameClock (); SetGameClockRate (INTERPLANETARY_CLOCK_RATE); } } @@ -1411,7 +1409,6 @@ StartGroups: { if (pSolarSysState->MenuState.flash_task) { - SuspendGameClock (); FreeSolarSys (); if (pSolarSysState->pOrbitalDesc->pPrevDesc != diff --git a/sc2/src/uqm/save.c b/sc2/src/uqm/save.c index 246c95c4f..9823b5b1a 100644 --- a/sc2/src/uqm/save.c +++ b/sc2/src/uqm/save.c @@ -341,7 +341,7 @@ SaveClockState (const CLOCK_STATE *ClockPtr, DECODE_REF fh) cwrite_16 (fh, ClockPtr->day_in_ticks); cwrite_ptr (fh); /* useless ptr; Semaphore clock_sem */ cwrite_ptr (fh); /* useless ptr; Task clock_task */ - cwrite_32 (fh, ClockPtr->TimeCounter); /* theoretically useless */ + cwrite_32 (fh, 0); /* useless value; DWORD TimeCounter */ DummySaveQueue (&ClockPtr->event_q, fh); } diff --git a/sc2/src/uqm/ship.c b/sc2/src/uqm/ship.c index af2a49ce3..a5f666263 100644 --- a/sc2/src/uqm/ship.c +++ b/sc2/src/uqm/ship.c @@ -213,11 +213,6 @@ ship_preprocess (ELEMENT *ElementPtr) InitIntersectStartPoint (ElementPtr); InitIntersectEndPoint (ElementPtr); - UnlockMutex (GraphicsLock); - ResumeGameClock (); - SetGameClockRate (HYPERSPACE_CLOCK_RATE); - LockMutex (GraphicsLock); - if (hyper_transition (ElementPtr)) return; } diff --git a/sc2/src/uqm/starbase.c b/sc2/src/uqm/starbase.c index 5e3eb388a..4a8d1388c 100644 --- a/sc2/src/uqm/starbase.c +++ b/sc2/src/uqm/starbase.c @@ -443,20 +443,13 @@ static void DoTimePassage (void) { #define LOST_DAYS 14 - COUNT i; BYTE clut_buf[1]; clut_buf[0] = FadeAllToBlack; SleepThreadUntil (XFormColorMap ((COLORMAPPTR)clut_buf, ONE_SECOND * 2)); - for (i = 0; i < LOST_DAYS; ++i) - { - while (ClockTick () > 0) - ; - - ResumeGameClock (); - SleepThread (ONE_SECOND / 60); - SuspendGameClock (); - } + LockMutex (GraphicsLock); + MoveGameClockDays (LOST_DAYS); + UnlockMutex (GraphicsLock); } void diff --git a/sc2/src/uqm/starcon.c b/sc2/src/uqm/starcon.c index 1d607ebba..5fea213a4 100644 --- a/sc2/src/uqm/starcon.c +++ b/sc2/src/uqm/starcon.c @@ -60,8 +60,7 @@ arilou_gate_task(void *data) counter = GET_GAME_STATE (ARILOU_SPACE_COUNTER); while (!Task_ReadState (task, TASK_EXIT)) { - SetSemaphore (GLOBAL (GameClock.clock_sem)); - + LockGameClock (); if (GET_GAME_STATE (ARILOU_SPACE) == OPENING) { if (++counter == 10) @@ -72,12 +71,12 @@ arilou_gate_task(void *data) if (counter-- == 0) counter = 0; } + UnlockGameClock (); LockMutex (GraphicsLock); SET_GAME_STATE (ARILOU_SPACE_COUNTER, counter); UnlockMutex (GraphicsLock); - ClearSemaphore (GLOBAL (GameClock.clock_sem)); SleepThreadUntil (TimeIn + BATTLE_FRAME_RATE); TimeIn = GetTimeCounter (); } @@ -86,12 +85,17 @@ arilou_gate_task(void *data) return 0; } +// Battle frame callback function. +// Called with GraphicsLock held static void on_battle_frame (void) { - LockMutex (GraphicsLock); + GameClockTick (); + + if (!(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD))) + SeedUniverse (); + DrawAutoPilotMessage (FALSE); - UnlockMutex (GraphicsLock); } static void @@ -212,8 +216,6 @@ while (--ac > 0) do { - SuspendGameClock (); - #ifdef DEBUG if (debugHook != NULL) { @@ -278,6 +280,7 @@ while (--ac > 0) TaskSwitch (); DrawAutoPilotMessage (TRUE); + SetGameClockRate (HYPERSPACE_CLOCK_RATE); Battle (&on_battle_frame); if (ArilouTask) Task_SetState (ArilouTask, TASK_EXIT); diff --git a/sc2/src/uqm/uqmdebug.c b/sc2/src/uqm/uqmdebug.c index ad9b0b34d..cc968d053 100644 --- a/sc2/src/uqm/uqmdebug.c +++ b/sc2/src/uqm/uqmdebug.c @@ -138,7 +138,10 @@ forwardToNextEvent (BOOLEAN skipHEE) if (!GameClockRunning ()) return; - SuspendGameClock (); + // Must hold GraphicsLock for MoveGameClockDays() + // Must acquire GraphicsLock *before* the game clock lock + LockMutex (GraphicsLock); + LockGameClock (); done = !skipHEE; do { @@ -161,16 +164,12 @@ forwardToNextEvent (BOOLEAN skipHEE) GLOBAL (GameClock.day_index) >= day)))) break; - while (ClockTick () > 0) - ; - - ResumeGameClock (); - SleepThread (ONE_SECOND / 60); - SuspendGameClock (); + MoveGameClockDays (1); } } while (!done); - ResumeGameClock (); + UnlockGameClock (); + UnlockMutex (GraphicsLock); } const char * @@ -239,15 +238,9 @@ dumpEvent (FILE *out, const EVENT *eventPtr) void dumpEvents (FILE *out) { - BOOLEAN restartClock = FALSE; - - if (GameClockRunning ()) { - SuspendGameClock (); - restartClock = TRUE; - } + LockGameClock (); ForAllEvents (dumpEventCallback, out); - if (restartClock) - ResumeGameClock (); + UnlockGameClock (); } //////////////////////////////////////////////////////////////////////////// @@ -592,7 +585,6 @@ forAllMoons (STAR_DESC *star, SOLARSYS_STATE *system, PLANET_DESC *planet, void UniverseRecurse (UniverseRecurseArg *universeRecurseArg) { - BOOLEAN clockRunning; ACTIVITY savedActivity; if (universeRecurseArg->systemFuncPre == NULL @@ -602,9 +594,7 @@ UniverseRecurse (UniverseRecurseArg *universeRecurseArg) && universeRecurseArg->moonFunc == NULL) return; - clockRunning = GameClockRunning (); - if (clockRunning) - SuspendGameClock (); + LockGameClock (); //TFB_DEBUG_HALT = 1; savedActivity = GLOBAL (CurrentActivity); disableInteractivity = TRUE; @@ -613,8 +603,7 @@ UniverseRecurse (UniverseRecurseArg *universeRecurseArg) disableInteractivity = FALSE; GLOBAL (CurrentActivity) = savedActivity; - if (clockRunning) - ResumeGameClock (); + UnlockGameClock (); } static void diff --git a/sc2/src/uqm/util.c b/sc2/src/uqm/util.c index fe221f60a..2374ad17c 100644 --- a/sc2/src/uqm/util.c +++ b/sc2/src/uqm/util.c @@ -161,9 +161,6 @@ PauseGame (void) GLOBAL (CurrentActivity) |= CHECK_PAUSE; - if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE && - LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE) - SuspendGameClock (); if (CommData.ConversationPhrases && PlayingTrack ()) PauseTrack (); @@ -221,9 +218,6 @@ PauseGame (void) WaitForNoInput (ONE_SECOND / 4); FlushInput (); - if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE && - LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE) - ResumeGameClock (); if (CommData.ConversationPhrases && PlayingTrack ()) ResumeTrack (); @@ -263,9 +257,6 @@ SleepGame (void) log_add (log_Debug, "Game is going to sleep"); - if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE && - LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE) - SuspendGameClock (); if (CommData.ConversationPhrases && PlayingTrack ()) PauseTrack (); PauseMusic (); @@ -282,9 +273,6 @@ SleepGame (void) ResumeMusic (); - if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE && - LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE) - ResumeGameClock (); if (CommData.ConversationPhrases && PlayingTrack ()) ResumeTrack ();