]> Shamusworld >> Repos - apple2/blob - src/timing.cpp
Graphical fixes for DHIRES and added CASIN emulation.
[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
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
34 struct Event
35 {
36     bool valid;
37     double eventTime;
38     void (* timerCallback)(void);
39 };
40
41 //let's try +1... nope.
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("TIMING: 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         // Find the next event. Since the events are not necessarily in order of
99         // increasing time, we have to search through the list for the lowest one.
100
101 //ALSO: There's a bug here--nextEvent is getting a bogus value/getting clobbered...
102 //      Seems like it's getting clobbered somewhere other than here...
103     double time = 0;
104     bool firstTime = true;
105
106     for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
107     {
108         if (eventList[i].valid)
109         {
110             if (firstTime)
111                         {
112                 time = eventList[i].eventTime;
113                                 nextEvent = i;
114                                 firstTime = false;
115                         }
116             else
117             {
118                 if (eventList[i].eventTime < time)
119                                 {
120                     time = eventList[i].eventTime;
121                                         nextEvent = i;
122                                 }
123             }
124         }
125     }
126
127         if (time == 0)
128                 WriteLog("TIMING: GetTimeToNextEvent() failed to find next event!\n");
129
130         if (nextEvent >= EVENT_LIST_SIZE)
131                 WriteLog("TIMING: GetTimeToNextEvent() has bad nextEvent (=%u)!\n", nextEvent);
132
133     return time;
134 }
135
136 void HandleNextEvent(void)
137 {
138     double elapsedTime = eventList[nextEvent].eventTime;
139     void (* event)(void) = eventList[nextEvent].timerCallback;
140
141     for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
142         if (eventList[i].valid)
143             eventList[i].eventTime -= elapsedTime;
144
145     eventList[nextEvent].valid = false;      // Remove event from list...
146
147     (*event)();
148 }