summaryrefslogtreecommitdiff
path: root/opl/opl_sdl.c
diff options
context:
space:
mode:
Diffstat (limited to 'opl/opl_sdl.c')
-rw-r--r--opl/opl_sdl.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/opl/opl_sdl.c b/opl/opl_sdl.c
index ffbe6820..e38f9f6e 100644
--- a/opl/opl_sdl.c
+++ b/opl/opl_sdl.c
@@ -60,6 +60,15 @@ static SDL_mutex *callback_queue_mutex = NULL;
static int current_time;
+// If non-zero, playback is currently paused.
+
+static int opl_sdl_paused;
+
+// Time offset (in samples) due to the fact that callbacks
+// were previously paused.
+
+static unsigned int pause_offset;
+
// OPL software emulator structure.
static FM_OPL *opl_emulator = NULL;
@@ -96,11 +105,16 @@ static void AdvanceTime(unsigned int nsamples)
current_time += nsamples;
+ if (opl_sdl_paused)
+ {
+ pause_offset += nsamples;
+ }
+
// Are there callbacks to invoke now? Keep invoking them
// until there are none more left.
while (!OPL_Queue_IsEmpty(callback_queue)
- && current_time >= OPL_Queue_Peek(callback_queue))
+ && current_time >= OPL_Queue_Peek(callback_queue) + pause_offset)
{
// Pop the callback from the queue to invoke it.
@@ -180,13 +194,13 @@ static void OPL_Mix_Callback(void *udata,
// the callback queue must be invoked. We can then fill the
// buffer with this many samples.
- if (OPL_Queue_IsEmpty(callback_queue))
+ if (opl_sdl_paused || OPL_Queue_IsEmpty(callback_queue))
{
nsamples = buffer_len - filled;
}
else
{
- next_callback_time = OPL_Queue_Peek(callback_queue);
+ next_callback_time = OPL_Queue_Peek(callback_queue) + pause_offset;
nsamples = next_callback_time - current_time;
@@ -260,7 +274,7 @@ static void TimerHandler(int channel, double interval_seconds)
SDL_LockMutex(callback_queue_mutex);
OPL_Queue_Push(callback_queue, TimerOver, (void *) channel,
- current_time + interval_samples);
+ current_time - pause_offset + interval_samples);
SDL_UnlockMutex(callback_queue_mutex);
}
@@ -297,6 +311,9 @@ static int OPL_SDL_Init(unsigned int port_base)
sdl_was_initialised = 0;
}
+ opl_sdl_paused = 0;
+ pause_offset = 0;
+
// Queue structure of callbacks to invoke.
callback_queue = OPL_Queue_Create();
@@ -370,7 +387,7 @@ static void OPL_SDL_SetCallback(unsigned int ms,
{
SDL_LockMutex(callback_queue_mutex);
OPL_Queue_Push(callback_queue, callback, data,
- current_time + (ms * mixing_freq) / 1000);
+ current_time - pause_offset + (ms * mixing_freq) / 1000);
SDL_UnlockMutex(callback_queue_mutex);
}
@@ -391,6 +408,11 @@ static void OPL_SDL_Unlock(void)
SDL_UnlockMutex(callback_mutex);
}
+static void OPL_SDL_SetPaused(int paused)
+{
+ opl_sdl_paused = paused;
+}
+
opl_driver_t opl_sdl_driver =
{
"SDL",
@@ -401,6 +423,7 @@ opl_driver_t opl_sdl_driver =
OPL_SDL_SetCallback,
OPL_SDL_ClearCallbacks,
OPL_SDL_Lock,
- OPL_SDL_Unlock
+ OPL_SDL_Unlock,
+ OPL_SDL_SetPaused
};