]> Shamusworld >> Repos - apple2/blob - apple2/src/timing.cpp
2bf07091173a20fcd3c391d02328e8f330d6a751
[apple2] / apple2 / src / timing.cpp
1 //
2 // System time handlers
3 //
4 // by James L. Hammons
5 // (C) 2005 Underground Software
6 //
7 // JLH = James L. 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
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 will go
28 // in with a time that is later than the ones already queued up. So we just use a simple
29 // list.
30
31 // Although if we used an insertion sort we could, but it wouldn't work for adjusting
32 // times...
33
34 struct Event
35 {
36     bool valid;
37     double eventTime;
38     void (* timerCallback)(void);
39 };
40
41 static Event eventList[EVENT_LIST_SIZE];
42 static uint32 nextEvent;
43
44 void InitializeEventList(void)
45 {
46     for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
47         eventList[i].valid = false;
48 }
49
50 //We just slap the next event into the list, no checking, no nada...
51 void SetCallbackTime(void (* callback)(void), double time)
52 {
53     for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
54     {
55         if (!eventList[i].valid)
56         {
57 //WriteLog("SCT: Found callback slot #%u...\n", i);
58             eventList[i].timerCallback = callback;
59             eventList[i].eventTime = time;
60             eventList[i].valid = true;
61
62             return;
63         }
64     }
65
66     WriteLog("SetCallbackTime() failed to find an empty slot in the list!\n");
67 }
68
69 void RemoveCallback(void (* callback)(void))
70 {
71     for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
72     {
73         if (eventList[i].valid && eventList[i].timerCallback == callback)
74         {
75             eventList[i].valid = false;
76
77             return;
78         }
79     }
80 }
81
82 void AdjustCallbackTime(void (* callback)(void), double time)
83 {
84     for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
85     {
86         if (eventList[i].valid && eventList[i].timerCallback == callback)
87         {
88             eventList[i].eventTime = time;
89
90             return;
91         }
92     }
93 }
94
95 double GetTimeToNextEvent(void)
96 {
97     double time = 0;
98     bool firstTime = true;
99
100     for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
101     {
102         if (eventList[i].valid)
103         {
104             if (firstTime)
105                 time = eventList[i].eventTime, nextEvent = i, firstTime = false;
106             else
107             {
108                 if (eventList[i].eventTime < time)
109                     time = eventList[i].eventTime, nextEvent = i;
110             }
111         }
112     }
113
114     return time;
115 }
116
117 void HandleNextEvent(void)
118 {
119     double elapsedTime = eventList[nextEvent].eventTime;
120     void (* event)(void) = eventList[nextEvent].timerCallback;
121
122     for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
123         if (eventList[i].valid)
124             eventList[i].eventTime -= elapsedTime;
125
126     eventList[nextEvent].valid = false;      // Remove event from list...
127
128     (*event)();
129 }