summaryrefslogtreecommitdiff
path: root/sid/sidplay-libs-2.1.0/libsidplay/src/event.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sid/sidplay-libs-2.1.0/libsidplay/src/event.cpp')
-rw-r--r--sid/sidplay-libs-2.1.0/libsidplay/src/event.cpp121
1 files changed, 121 insertions, 0 deletions
diff --git a/sid/sidplay-libs-2.1.0/libsidplay/src/event.cpp b/sid/sidplay-libs-2.1.0/libsidplay/src/event.cpp
new file mode 100644
index 00000000..ced11c38
--- /dev/null
+++ b/sid/sidplay-libs-2.1.0/libsidplay/src/event.cpp
@@ -0,0 +1,121 @@
+/***************************************************************************
+ event.cpp - Event schdeduler (based on alarm
+ from Vice)
+ -------------------
+ begin : Wed May 9 2001
+ copyright : (C) 2001 by Simon White
+ email : s_a_white@email.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/***************************************************************************
+ * $Log: event.cpp,v $
+ * Revision 1.7 2002/11/21 19:55:38 s_a_white
+ * We now jump to next event directly instead on clocking by a number of
+ * cycles.
+ *
+ * Revision 1.6 2002/07/17 19:20:03 s_a_white
+ * More efficient event handling code.
+ *
+ * Revision 1.5 2001/10/02 18:24:09 s_a_white
+ * Updated to support safe scheduler interface.
+ *
+ * Revision 1.4 2001/09/17 19:00:28 s_a_white
+ * Constructor moved out of line.
+ *
+ * Revision 1.3 2001/09/15 13:03:50 s_a_white
+ * timeWarp now zeros m_eventClk instead of m_pendingEventClk which
+ * fixes a inifinite loop problem when driving libsidplay1.
+ *
+ ***************************************************************************/
+
+#include <string.h>
+#include "event.h"
+
+#define EVENT_TIMEWARP_COUNT 0x0FFFFF
+
+
+EventScheduler::EventScheduler (const char * const name)
+:m_name(name),
+ m_pendingEventCount(0),
+ m_timeWarp(this)
+{
+ memset (&m_pendingEvents, 0, sizeof (Event));
+ m_pendingEvents.m_next = &m_pendingEvents;
+ m_pendingEvents.m_prev = &m_pendingEvents;
+ reset ();
+}
+
+// Usefull to prevent clock overflowing
+void EventScheduler::timeWarp ()
+{
+ Event *e = &m_pendingEvents;
+ uint count = m_pendingEventCount;
+ while (count--)
+ { // Reduce all event clocks and clip them
+ // so none go negative
+ event_clock_t clk;
+ e = e->m_next;
+ clk = e->m_clk;
+ e->m_clk = 0;
+ if (clk >= m_eventClk)
+ e->m_clk = clk - m_eventClk;
+ }
+ m_eventClk = 0;
+ // Re-schedule the next timeWarp
+ schedule (&m_timeWarp, EVENT_TIMEWARP_COUNT);
+}
+
+void EventScheduler::reset (void)
+{ // Remove all events
+ Event *e = &m_pendingEvents;
+ uint count = m_pendingEventCount;
+ while (count--)
+ {
+ e = e->m_next;
+ e->m_pending = false;
+ }
+ m_pendingEvents.m_next = &m_pendingEvents;
+ m_pendingEvents.m_prev = &m_pendingEvents;
+ m_pendingEventClk = m_eventClk = m_schedClk = 0;
+ m_pendingEventCount = 0;
+ timeWarp ();
+}
+
+// Add event to ordered pending queue
+void EventScheduler::schedule (Event *event, event_clock_t cycles)
+{
+ uint clk = m_eventClk + cycles;
+ if (event->m_pending)
+ cancelPending (*event);
+ event->m_pending = true;
+ event->m_clk = clk;
+
+ { // Now put in the correct place so we don't need to keep
+ // searching the list later.
+ Event *e = m_pendingEvents.m_next;
+ uint count = m_pendingEventCount;
+ while (count-- && (e->m_clk <= clk))
+ e = e->m_next;
+ event->m_next = e;
+ event->m_prev = e->m_prev;
+ e->m_prev->m_next = event;
+ e->m_prev = event;
+ m_pendingEventClk = m_pendingEvents.m_next->m_clk;
+ m_pendingEventCount++;
+ }
+}
+
+// Cancel a pending event
+void EventScheduler::cancel (Event *event)
+{
+ if (event->m_pending)
+ cancelPending (*event);
+}