diff options
Diffstat (limited to 'opl')
-rw-r--r-- | opl/opl.c | 8 | ||||
-rw-r--r-- | opl/opl.h | 5 | ||||
-rw-r--r-- | opl/opl_internal.h | 2 | ||||
-rw-r--r-- | opl/opl_linux.c | 3 | ||||
-rw-r--r-- | opl/opl_obsd.c | 3 | ||||
-rw-r--r-- | opl/opl_queue.c | 13 | ||||
-rw-r--r-- | opl/opl_queue.h | 2 | ||||
-rw-r--r-- | opl/opl_sdl.c | 10 | ||||
-rw-r--r-- | opl/opl_timer.c | 7 | ||||
-rw-r--r-- | opl/opl_timer.h | 1 | ||||
-rw-r--r-- | opl/opl_win32.c | 3 |
11 files changed, 53 insertions, 4 deletions
@@ -452,3 +452,11 @@ void OPL_SetPaused(int paused) } } +void OPL_AdjustCallbacks(float value) +{ + if (driver != NULL) + { + driver->adjust_callbacks_func(value); + } +} + @@ -104,6 +104,11 @@ void OPL_InitRegisters(void); void OPL_SetCallback(unsigned int ms, opl_callback_t callback, void *data); +// Adjust callback times by the specified factor. For example, a value of +// 0.5 will halve all remaining times. + +void OPL_AdjustCallbacks(float factor); + // Clear all OPL callbacks that have been set. void OPL_ClearCallbacks(void); diff --git a/opl/opl_internal.h b/opl/opl_internal.h index 91a275d5..24e79644 100644 --- a/opl/opl_internal.h +++ b/opl/opl_internal.h @@ -32,6 +32,7 @@ typedef void (*opl_clear_callbacks_func)(void); typedef void (*opl_lock_func)(void); typedef void (*opl_unlock_func)(void); typedef void (*opl_set_paused_func)(int paused); +typedef void (*opl_adjust_callbacks_func)(float value); typedef struct { @@ -46,6 +47,7 @@ typedef struct opl_lock_func lock_func; opl_unlock_func unlock_func; opl_set_paused_func set_paused_func; + opl_adjust_callbacks_func adjust_callbacks_func; } opl_driver_t; // Sample rate to use when doing software emulation. diff --git a/opl/opl_linux.c b/opl/opl_linux.c index 12d21075..5df5d468 100644 --- a/opl/opl_linux.c +++ b/opl/opl_linux.c @@ -95,7 +95,8 @@ opl_driver_t opl_linux_driver = OPL_Timer_ClearCallbacks, OPL_Timer_Lock, OPL_Timer_Unlock, - OPL_Timer_SetPaused + OPL_Timer_SetPaused, + OPL_Timer_AdjustCallbacks, }; #endif /* #ifdef HAVE_IOPERM */ diff --git a/opl/opl_obsd.c b/opl/opl_obsd.c index 3313c1b2..39e0c156 100644 --- a/opl/opl_obsd.c +++ b/opl/opl_obsd.c @@ -110,7 +110,8 @@ opl_driver_t opl_openbsd_driver = OPL_Timer_ClearCallbacks, OPL_Timer_Lock, OPL_Timer_Unlock, - OPL_Timer_SetPaused + OPL_Timer_SetPaused, + OPL_Timer_AdjustCallbacks, }; #endif /* #ifndef NO_OBSD_DRIVER */ diff --git a/opl/opl_queue.c b/opl/opl_queue.c index d05cc6a1..ee87a19b 100644 --- a/opl/opl_queue.c +++ b/opl/opl_queue.c @@ -201,6 +201,19 @@ unsigned int OPL_Queue_Peek(opl_callback_queue_t *queue) } } +void OPL_Queue_AdjustCallbacks(opl_callback_queue_t *queue, + unsigned int time, float factor) +{ + int offset; + int i; + + for (i = 0; i < queue->num_entries; ++i) + { + offset = queue->entries[i].time - time; + queue->entries[i].time = time + (int) (offset * factor); + } +} + #ifdef TEST #include <assert.h> diff --git a/opl/opl_queue.h b/opl/opl_queue.h index b0f479f4..20ddeda9 100644 --- a/opl/opl_queue.h +++ b/opl/opl_queue.h @@ -32,6 +32,8 @@ void OPL_Queue_Push(opl_callback_queue_t *queue, int OPL_Queue_Pop(opl_callback_queue_t *queue, opl_callback_t *callback, void **data); unsigned int OPL_Queue_Peek(opl_callback_queue_t *queue); +void OPL_Queue_AdjustCallbacks(opl_callback_queue_t *queue, + unsigned int time, float factor); #endif /* #ifndef OPL_QUEUE_H */ diff --git a/opl/opl_sdl.c b/opl/opl_sdl.c index 4cd3dc7b..3ed7f784 100644 --- a/opl/opl_sdl.c +++ b/opl/opl_sdl.c @@ -486,6 +486,13 @@ static void OPL_SDL_SetPaused(int paused) opl_sdl_paused = paused; } +static void OPL_SDL_AdjustCallbacks(float factor) +{ + SDL_LockMutex(callback_queue_mutex); + OPL_Queue_AdjustCallbacks(callback_queue, current_time, factor); + SDL_UnlockMutex(callback_queue_mutex); +} + opl_driver_t opl_sdl_driver = { "SDL", @@ -497,6 +504,7 @@ opl_driver_t opl_sdl_driver = OPL_SDL_ClearCallbacks, OPL_SDL_Lock, OPL_SDL_Unlock, - OPL_SDL_SetPaused + OPL_SDL_SetPaused, + OPL_SDL_AdjustCallbacks, }; diff --git a/opl/opl_timer.c b/opl/opl_timer.c index 97e5ea8b..bab15687 100644 --- a/opl/opl_timer.c +++ b/opl/opl_timer.c @@ -224,6 +224,13 @@ void OPL_Timer_ClearCallbacks(void) SDL_UnlockMutex(callback_queue_mutex); } +void OPL_Timer_AdjustCallbacks(float factor) +{ + SDL_LockMutex(callback_queue_mutex); + OPL_Queue_AdjustCallbacks(callback_queue, current_time, factor); + SDL_UnlockMutex(callback_queue_mutex); +} + void OPL_Timer_Lock(void) { SDL_LockMutex(timer_mutex); diff --git a/opl/opl_timer.h b/opl/opl_timer.h index 1febcac9..73544013 100644 --- a/opl/opl_timer.h +++ b/opl/opl_timer.h @@ -29,6 +29,7 @@ void OPL_Timer_ClearCallbacks(void); void OPL_Timer_Lock(void); void OPL_Timer_Unlock(void); void OPL_Timer_SetPaused(int paused); +void OPL_Timer_AdjustCallbacks(float factor); #endif /* #ifndef OPL_TIMER_H */ diff --git a/opl/opl_win32.c b/opl/opl_win32.c index c6c37803..ea7b9eeb 100644 --- a/opl/opl_win32.c +++ b/opl/opl_win32.c @@ -184,7 +184,8 @@ opl_driver_t opl_win32_driver = OPL_Timer_ClearCallbacks, OPL_Timer_Lock, OPL_Timer_Unlock, - OPL_Timer_SetPaused + OPL_Timer_SetPaused, + OPL_Timer_AdjustCallbacks, }; #endif /* #ifdef _WIN32 */ |