]> Shamusworld >> Repos - stargem2/blob - src/timing.cpp
Finally fixed problems with demo mode.
[stargem2] / src / timing.cpp
1 //
2 // System time handlers
3 //
4 // by James Hammons
5 // (C) 2005 Underground Software
6 //
7 // JLH = James Hammons <jlhamm@acm.org>
8 //
9 // WHO  WHEN        WHAT
10 // ---  ----------  ------------------------------------------------------------
11 // JLH  01/04/2006  Cosmetic changes (like this one ;-)
12 //
13
14 // STILL TO DO:
15 //
16 // - Handling for an event that occurs NOW
17 //
18
19 #include "timing.h"
20 #include <stdint.h>
21 #include "log.h"
22
23 #define EVENT_LIST_SIZE         512
24
25 // NOTE ABOUT TIMING SYSTEM DATA STRUCTURES:
26 //
27 // A queue won't work for this system because we can't guarantee that an event
28 // will go in with a time that is later than the ones already queued up. So we
29 // just use a simple list.
30 //
31 // Although if we used an insertion sort we could, but it wouldn't work for
32 // adjusting times...
33 // [In that case, we could pull the event out, close the gap, then do insertion sort]
34
35 struct Event
36 {
37         bool valid;
38         double eventTime;
39         void (* timerCallback)(void);
40 };
41
42 static Event eventList[EVENT_LIST_SIZE];
43 static uint32_t nextEvent;
44
45 void InitializeEventList(void)
46 {
47         for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
48                 eventList[i].valid = false;
49 }
50
51 //We just slap the next event into the list, no checking, no nada...
52 void SetCallbackTime(void (* callback)(void), double time)
53 {
54         for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
55         {
56                 if (!eventList[i].valid)
57                 {
58 //WriteLog("SCT: Found callback slot #%u...\n", i);
59                         eventList[i].timerCallback = callback;
60                         eventList[i].eventTime = time;
61                         eventList[i].valid = true;
62
63                         return;
64                 }
65         }
66
67         WriteLog("SetCallbackTime() failed to find an empty slot in the list!\n");
68 }
69
70 void RemoveCallback(void (* callback)(void))
71 {
72         for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
73         {
74                 if (eventList[i].valid && eventList[i].timerCallback == callback)
75                 {
76                         eventList[i].valid = false;
77
78                         return;
79                 }
80         }
81 }
82
83 void AdjustCallbackTime(void (* callback)(void), double time)
84 {
85         for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
86         {
87                 if (eventList[i].valid && eventList[i].timerCallback == callback)
88                 {
89                         eventList[i].eventTime = time;
90
91                         return;
92                 }
93         }
94 }
95
96 double GetTimeToNextEvent(void)
97 {
98         double time = 0;
99         bool firstTime = true;
100
101         for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
102         {
103                 if (eventList[i].valid)
104                 {
105                         if (firstTime)
106                                 time = eventList[i].eventTime, nextEvent = i, firstTime = false;
107                         else
108                         {
109                                 if (eventList[i].eventTime < time)
110                                         time = eventList[i].eventTime, nextEvent = i;
111                         }
112                 }
113         }
114
115         return time;
116 }
117
118 void HandleNextEvent(void)
119 {
120         double elapsedTime = eventList[nextEvent].eventTime;
121         void (* event)(void) = eventList[nextEvent].timerCallback;
122
123         for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
124                 if (eventList[i].valid)
125                         eventList[i].eventTime -= elapsedTime;
126
127         eventList[nextEvent].valid = false;      // Remove event from list...
128
129         (*event)();
130 }