From e3c7240c5263a18e17ac770315998096d0ffb155 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 21 Oct 2017 00:53:21 -0700 Subject: [PATCH] Simplified music interface library loading Also implemented SDL_AudioStream functionality for mikmod music loader --- configure | 2 +- configure.in | 2 +- music_flac.c | 148 +++--------- music_fluidsynth.c | 1 - music_mikmod.c | 551 +++++++++++++++------------------------------ music_modplug.c | 81 ++----- music_mpg123.c | 1 - music_ogg.c | 137 +++-------- music_smpeg.c | 148 ++---------- 9 files changed, 285 insertions(+), 786 deletions(-) diff --git a/configure b/configure index 34b1db01..8337426a 100755 --- a/configure +++ b/configure @@ -12074,7 +12074,7 @@ fi EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MOD_MIKMOD `$LIBMIKMOD_CONFIG --cflags`" if test x$enable_music_mod_mikmod_shared = xyes && test x$mikmod_lib != x; then echo "-- dynamic libmikmod -> $mikmod_lib" - EXTRA_CFLAGS="$EXTRA_CFLAGS -DMOD_DYNAMIC=\\\"$mikmod_lib\\\"" + EXTRA_CFLAGS="$EXTRA_CFLAGS -DMIKMOD_DYNAMIC=\\\"$mikmod_lib\\\"" else EXTRA_LDFLAGS="$EXTRA_LDFLAGS `$LIBMIKMOD_CONFIG --libs`" fi diff --git a/configure.in b/configure.in index af85b38c..969db72b 100644 --- a/configure.in +++ b/configure.in @@ -337,7 +337,7 @@ return 1; EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MOD_MIKMOD `$LIBMIKMOD_CONFIG --cflags`" if test x$enable_music_mod_mikmod_shared = xyes && test x$mikmod_lib != x; then echo "-- dynamic libmikmod -> $mikmod_lib" - EXTRA_CFLAGS="$EXTRA_CFLAGS -DMOD_DYNAMIC=\\\"$mikmod_lib\\\"" + EXTRA_CFLAGS="$EXTRA_CFLAGS -DMIKMOD_DYNAMIC=\\\"$mikmod_lib\\\"" else EXTRA_LDFLAGS="$EXTRA_LDFLAGS `$LIBMIKMOD_CONFIG --libs`" fi diff --git a/music_flac.c b/music_flac.c index 9d270656..94461335 100644 --- a/music_flac.c +++ b/music_flac.c @@ -68,30 +68,35 @@ static flac_loader flac = { }; #ifdef FLAC_DYNAMIC +#define FUNCTION_LOADER(FUNC, SIG) \ + flac.FUNC = (SIG) SDL_LoadFunction(flac.handle, #FUNC); \ + if (flac.FUNC == NULL) { SDL_UnloadObject(flac.handle); return -1; } +#else +#define FUNCTION_LOADER(FUNC, SIG) \ + flac.FUNC = FUNC; +#endif static int FLAC_Load(void) { if (flac.loaded == 0) { +#ifdef FLAC_DYNAMIC flac.handle = SDL_LoadObject(FLAC_DYNAMIC); if (flac.handle == NULL) { return -1; } - flac.FLAC__stream_decoder_new = - (FLAC__StreamDecoder *(*)(void)) - SDL_LoadFunction(flac.handle, "FLAC__stream_decoder_new"); - if (flac.FLAC__stream_decoder_new == NULL) { - SDL_UnloadObject(flac.handle); - return -1; - } - flac.FLAC__stream_decoder_delete = - (void (*)(FLAC__StreamDecoder *)) - SDL_LoadFunction(flac.handle, "FLAC__stream_decoder_delete"); - if (flac.FLAC__stream_decoder_delete == NULL) { - SDL_UnloadObject(flac.handle); +#elif defined(__MACOSX__) + extern FLAC__StreamDecoder *FLAC__stream_decoder_new(void) __attribute__((weak_import)); + if (FLAC__stream_decoder_new == NULL) + { + /* Missing weakly linked framework */ + Mix_SetError("Missing FLAC.framework"); return -1; } - flac.FLAC__stream_decoder_init_stream = - (FLAC__StreamDecoderInitStatus (*)( +#endif + + FUNCTION_LOADER(FLAC__stream_decoder_new, FLAC__StreamDecoder *(*)(void)) + FUNCTION_LOADER(FLAC__stream_decoder_delete, void (*)(FLAC__StreamDecoder *)) + FUNCTION_LOADER(FLAC__stream_decoder_init_stream, FLAC__StreamDecoderInitStatus (*)( FLAC__StreamDecoder *, FLAC__StreamDecoderReadCallback, FLAC__StreamDecoderSeekCallback, @@ -102,63 +107,13 @@ static int FLAC_Load(void) FLAC__StreamDecoderMetadataCallback, FLAC__StreamDecoderErrorCallback, void *)) - SDL_LoadFunction(flac.handle, "FLAC__stream_decoder_init_stream"); - if (flac.FLAC__stream_decoder_init_stream == NULL) { - SDL_UnloadObject(flac.handle); - return -1; - } - flac.FLAC__stream_decoder_finish = - (FLAC__bool (*)(FLAC__StreamDecoder *)) - SDL_LoadFunction(flac.handle, "FLAC__stream_decoder_finish"); - if (flac.FLAC__stream_decoder_finish == NULL) { - SDL_UnloadObject(flac.handle); - return -1; - } - flac.FLAC__stream_decoder_flush = - (FLAC__bool (*)(FLAC__StreamDecoder *)) - SDL_LoadFunction(flac.handle, "FLAC__stream_decoder_flush"); - if (flac.FLAC__stream_decoder_flush == NULL) { - SDL_UnloadObject(flac.handle); - return -1; - } - flac.FLAC__stream_decoder_process_single = - (FLAC__bool (*)(FLAC__StreamDecoder *)) - SDL_LoadFunction(flac.handle, - "FLAC__stream_decoder_process_single"); - if (flac.FLAC__stream_decoder_process_single == NULL) { - SDL_UnloadObject(flac.handle); - return -1; - } - flac.FLAC__stream_decoder_process_until_end_of_metadata = - (FLAC__bool (*)(FLAC__StreamDecoder *)) - SDL_LoadFunction(flac.handle, - "FLAC__stream_decoder_process_until_end_of_metadata"); - if (flac.FLAC__stream_decoder_process_until_end_of_metadata == NULL) { - SDL_UnloadObject(flac.handle); - return -1; - } - flac.FLAC__stream_decoder_process_until_end_of_stream = - (FLAC__bool (*)(FLAC__StreamDecoder *)) - SDL_LoadFunction(flac.handle, - "FLAC__stream_decoder_process_until_end_of_stream"); - if (flac.FLAC__stream_decoder_process_until_end_of_stream == NULL) { - SDL_UnloadObject(flac.handle); - return -1; - } - flac.FLAC__stream_decoder_seek_absolute = - (FLAC__bool (*)(FLAC__StreamDecoder *, FLAC__uint64)) - SDL_LoadFunction(flac.handle, "FLAC__stream_decoder_seek_absolute"); - if (flac.FLAC__stream_decoder_seek_absolute == NULL) { - SDL_UnloadObject(flac.handle); - return -1; - } - flac.FLAC__stream_decoder_get_state = - (FLAC__StreamDecoderState (*)(const FLAC__StreamDecoder *decoder)) - SDL_LoadFunction(flac.handle, "FLAC__stream_decoder_get_state"); - if (flac.FLAC__stream_decoder_get_state == NULL) { - SDL_UnloadObject(flac.handle); - return -1; - } + FUNCTION_LOADER(FLAC__stream_decoder_finish, FLAC__bool (*)(FLAC__StreamDecoder *)) + FUNCTION_LOADER(FLAC__stream_decoder_flush, FLAC__bool (*)(FLAC__StreamDecoder *)) + FUNCTION_LOADER(FLAC__stream_decoder_process_single, FLAC__bool (*)(FLAC__StreamDecoder *)) + FUNCTION_LOADER(FLAC__stream_decoder_process_until_end_of_metadata, FLAC__bool (*)(FLAC__StreamDecoder *)) + FUNCTION_LOADER(FLAC__stream_decoder_process_until_end_of_stream, FLAC__bool (*)(FLAC__StreamDecoder *)) + FUNCTION_LOADER(FLAC__stream_decoder_seek_absolute, FLAC__bool (*)(FLAC__StreamDecoder *, FLAC__uint64)) + FUNCTION_LOADER(FLAC__stream_decoder_get_state, FLAC__StreamDecoderState (*)(const FLAC__StreamDecoder *decoder)) } ++flac.loaded; @@ -171,60 +126,13 @@ static void FLAC_Unload(void) return; } if (flac.loaded == 1) { +#ifdef FLAC_DYNAMIC SDL_UnloadObject(flac.handle); +#endif } --flac.loaded; } -#else /* !FLAC_DYNAMIC */ - -static int FLAC_Load(void) -{ - if (flac.loaded == 0) { -#ifdef __MACOSX__ - extern FLAC__StreamDecoder *FLAC__stream_decoder_new(void) __attribute__((weak_import)); - if (FLAC__stream_decoder_new == NULL) - { - /* Missing weakly linked framework */ - Mix_SetError("Missing FLAC.framework"); - return -1; - } -#endif /* __MACOSX__ */ - - flac.FLAC__stream_decoder_new = FLAC__stream_decoder_new; - flac.FLAC__stream_decoder_delete = FLAC__stream_decoder_delete; - flac.FLAC__stream_decoder_init_stream = - FLAC__stream_decoder_init_stream; - flac.FLAC__stream_decoder_finish = FLAC__stream_decoder_finish; - flac.FLAC__stream_decoder_flush = FLAC__stream_decoder_flush; - flac.FLAC__stream_decoder_process_single = - FLAC__stream_decoder_process_single; - flac.FLAC__stream_decoder_process_until_end_of_metadata = - FLAC__stream_decoder_process_until_end_of_metadata; - flac.FLAC__stream_decoder_process_until_end_of_stream = - FLAC__stream_decoder_process_until_end_of_stream; - flac.FLAC__stream_decoder_seek_absolute = - FLAC__stream_decoder_seek_absolute; - flac.FLAC__stream_decoder_get_state = - FLAC__stream_decoder_get_state; - } - ++flac.loaded; - - return 0; -} - -static void FLAC_Unload(void) -{ - if (flac.loaded == 0) { - return; - } - if (flac.loaded == 1) { - } - --flac.loaded; -} - -#endif /* FLAC_DYNAMIC */ - typedef struct { int volume; diff --git a/music_fluidsynth.c b/music_fluidsynth.c index 808391ce..f87272ea 100644 --- a/music_fluidsynth.c +++ b/music_fluidsynth.c @@ -78,7 +78,6 @@ static int FLUIDSYNTH_Load() return -1; } #endif - FUNCTION_LOADER(delete_fluid_player, int (*)(fluid_player_t*)) FUNCTION_LOADER(delete_fluid_settings, void (*)(fluid_settings_t*)) FUNCTION_LOADER(delete_fluid_synth, int (*)(fluid_synth_t*)) diff --git a/music_mikmod.c b/music_mikmod.c index f820a83d..b847dc5d 100644 --- a/music_mikmod.c +++ b/music_mikmod.c @@ -20,7 +20,6 @@ */ #ifdef MUSIC_MOD_MIKMOD -#error Implement play_count and audio stream conversion /* This file supports MOD tracker music streams */ @@ -31,8 +30,6 @@ #include "mikmod.h" -#define MAX_OUTPUT_CHANNELS 6 - /* libmikmod >= 3.3.2 constified several funcs */ #if (LIBMIKMOD_VERSION < 0x030302) #define MIKMOD3_CONST @@ -76,220 +73,29 @@ static mikmod_loader mikmod = { 0, NULL }; -#ifdef MOD_DYNAMIC +#ifdef MIKMOD_DYNAMIC +#define FUNCTION_LOADER(FUNC, SIG) \ + mikmod.FUNC = (SIG) SDL_LoadFunction(mikmod.handle, #FUNC); \ + if (mikmod.FUNC == NULL) { SDL_UnloadObject(mikmod.handle); return -1; } +#define VARIABLE_LOADER(NAME, SIG) \ + mikmod.NAME = (SIG) SDL_LoadFunction(mikmod.handle, #NAME); \ + if (mikmod.NAME == NULL) { SDL_UnloadObject(mikmod.handle); return -1; } +#else +#define FUNCTION_LOADER(FUNC, SIG) \ + mikmod.FUNC = FUNC; +#define VARIABLE_LOADER(NAME, SIG) \ + mikmod.NAME = &NAME; +#endif static int MIKMOD_Load() { if (mikmod.loaded == 0) { - mikmod.handle = SDL_LoadObject(MOD_DYNAMIC); +#ifdef MIKMOD_DYNAMIC + mikmod.handle = SDL_LoadObject(MIKMOD_DYNAMIC); if (mikmod.handle == NULL) { return -1; } - mikmod.MikMod_Exit = - (void (*)(void)) - SDL_LoadFunction(mikmod.handle, "MikMod_Exit"); - if (mikmod.MikMod_Exit == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.MikMod_InfoDriver = - (CHAR* (*)(void)) - SDL_LoadFunction(mikmod.handle, "MikMod_InfoDriver"); - if (mikmod.MikMod_InfoDriver == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.MikMod_InfoLoader = - (CHAR* (*)(void)) - SDL_LoadFunction(mikmod.handle, "MikMod_InfoLoader"); - if (mikmod.MikMod_InfoLoader == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.MikMod_Init = - (int (*)(MIKMOD3_CONST CHAR*)) - SDL_LoadFunction(mikmod.handle, "MikMod_Init"); - if (mikmod.MikMod_Init == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.MikMod_RegisterAllLoaders = - (void (*)(void)) - SDL_LoadFunction(mikmod.handle, "MikMod_RegisterAllLoaders"); - if (mikmod.MikMod_RegisterAllLoaders == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.MikMod_RegisterDriver = - (void (*)(struct MDRIVER*)) - SDL_LoadFunction(mikmod.handle, "MikMod_RegisterDriver"); - if (mikmod.MikMod_RegisterDriver == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.MikMod_errno = - (int*) - SDL_LoadFunction(mikmod.handle, "MikMod_errno"); - if (mikmod.MikMod_errno == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.MikMod_strerror = - (MIKMOD3_CONST char* (*)(int)) - SDL_LoadFunction(mikmod.handle, "MikMod_strerror"); - if (mikmod.MikMod_strerror == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.MikMod_free = - (void (*)(void*)) - SDL_LoadFunction(mikmod.handle, "MikMod_free"); - if (mikmod.MikMod_free == NULL) { - /* libmikmod 3.1 and earlier doesn't have it */ - mikmod.MikMod_free = free; - } - mikmod.Player_Active = - (BOOL (*)(void)) - SDL_LoadFunction(mikmod.handle, "Player_Active"); - if (mikmod.Player_Active == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.Player_Free = - (void (*)(MODULE*)) - SDL_LoadFunction(mikmod.handle, "Player_Free"); - if (mikmod.Player_Free == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.Player_LoadGeneric = - (MODULE* (*)(MREADER*,int,BOOL)) - SDL_LoadFunction(mikmod.handle, "Player_LoadGeneric"); - if (mikmod.Player_LoadGeneric == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.Player_SetPosition = - (void (*)(UWORD)) - SDL_LoadFunction(mikmod.handle, "Player_SetPosition"); - if (mikmod.Player_SetPosition == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.Player_SetVolume = - (void (*)(SWORD)) - SDL_LoadFunction(mikmod.handle, "Player_SetVolume"); - if (mikmod.Player_SetVolume == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.Player_Start = - (void (*)(MODULE*)) - SDL_LoadFunction(mikmod.handle, "Player_Start"); - if (mikmod.Player_Start == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.Player_Stop = - (void (*)(void)) - SDL_LoadFunction(mikmod.handle, "Player_Stop"); - if (mikmod.Player_Stop == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.VC_WriteBytes = - (ULONG (*)(SBYTE*,ULONG)) - SDL_LoadFunction(mikmod.handle, "VC_WriteBytes"); - if (mikmod.VC_WriteBytes == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.drv_nos = - (MDRIVER*) - SDL_LoadFunction(mikmod.handle, "drv_nos"); - if (mikmod.drv_nos == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.md_device = - (UWORD*) - SDL_LoadFunction(mikmod.handle, "md_device"); - if (mikmod.md_device == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.md_mixfreq = - (UWORD*) - SDL_LoadFunction(mikmod.handle, "md_mixfreq"); - if (mikmod.md_mixfreq == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.md_mode = - (UWORD*) - SDL_LoadFunction(mikmod.handle, "md_mode"); - if (mikmod.md_mode == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.md_musicvolume = - (UBYTE*) - SDL_LoadFunction(mikmod.handle, "md_musicvolume"); - if (mikmod.md_musicvolume == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.md_pansep = - (UBYTE*) - SDL_LoadFunction(mikmod.handle, "md_pansep"); - if (mikmod.md_pansep == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.md_reverb = - (UBYTE*) - SDL_LoadFunction(mikmod.handle, "md_reverb"); - if (mikmod.md_reverb == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.md_sndfxvolume = - (UBYTE*) - SDL_LoadFunction(mikmod.handle, "md_sndfxvolume"); - if (mikmod.md_sndfxvolume == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - mikmod.md_volume = - (UBYTE*) - SDL_LoadFunction(mikmod.handle, "md_volume"); - if (mikmod.md_volume == NULL) { - SDL_UnloadObject(mikmod.handle); - return -1; - } - } - ++mikmod.loaded; - - return 0; -} - -static void MIKMOD_Unload() -{ - if (mikmod.loaded == 0) { - return; - } - if (mikmod.loaded == 1) { - SDL_UnloadObject(mikmod.handle); - } - --mikmod.loaded; -} - -#else /* !MOD_DYNAMIC */ - -static int MIKMOD_Load() -{ - if (mikmod.loaded == 0) { -#ifdef __MACOSX__ +#elif defined(__MACOSX__) extern void Player_Start(MODULE*) __attribute__((weak_import)); if (Player_Start == NULL) { @@ -297,38 +103,45 @@ static int MIKMOD_Load() Mix_SetError("Missing mikmod.framework"); return -1; } -#endif // __MACOSX__ - - mikmod.MikMod_Exit = MikMod_Exit; - mikmod.MikMod_InfoDriver = MikMod_InfoDriver; - mikmod.MikMod_InfoLoader = MikMod_InfoLoader; - mikmod.MikMod_Init = MikMod_Init; - mikmod.MikMod_RegisterAllLoaders = MikMod_RegisterAllLoaders; - mikmod.MikMod_RegisterDriver = MikMod_RegisterDriver; - mikmod.MikMod_errno = &MikMod_errno; - mikmod.MikMod_strerror = MikMod_strerror; +#endif + FUNCTION_LOADER(MikMod_Exit, void (*)(void)) + FUNCTION_LOADER(MikMod_InfoDriver, CHAR* (*)(void)) + FUNCTION_LOADER(MikMod_InfoLoader, CHAR* (*)(void)) + FUNCTION_LOADER(MikMod_Init, int (*)(MIKMOD3_CONST CHAR*)) + FUNCTION_LOADER(MikMod_RegisterAllLoaders, void (*)(void)) + FUNCTION_LOADER(MikMod_RegisterDriver, void (*)(struct MDRIVER*)) + VARIABLE_LOADER(MikMod_errno, int*) + FUNCTION_LOADER(MikMod_strerror, MIKMOD3_CONST char* (*)(int)) +#ifdef MIKMOD_DYNAMIC + mikmod.MikMod_free = (void (*)(void*)) SDL_LoadFunction(mikmod.handle, "MikMod_free"); + if (!mikmod.MikMod_free) { + /* libmikmod 3.1 and earlier doesn't have it */ + mikmod.MikMod_free = free; + } +#else #if LIBMIKMOD_VERSION < ((3<<16)|(2<<8)) mikmod.MikMod_free = free; #else mikmod.MikMod_free = MikMod_free; #endif - mikmod.Player_Active = Player_Active; - mikmod.Player_Free = Player_Free; - mikmod.Player_LoadGeneric = Player_LoadGeneric; - mikmod.Player_SetPosition = Player_SetPosition; - mikmod.Player_SetVolume = Player_SetVolume; - mikmod.Player_Start = Player_Start; - mikmod.Player_Stop = Player_Stop; - mikmod.VC_WriteBytes = VC_WriteBytes; - mikmod.drv_nos = &drv_nos; - mikmod.md_device = &md_device; - mikmod.md_mixfreq = &md_mixfreq; - mikmod.md_mode = &md_mode; - mikmod.md_musicvolume = &md_musicvolume; - mikmod.md_pansep = &md_pansep; - mikmod.md_reverb = &md_reverb; - mikmod.md_sndfxvolume = &md_sndfxvolume; - mikmod.md_volume = &md_volume; +#endif /* MIKMOD_DYNAMIC */ + FUNCTION_LOADER(Player_Active, BOOL (*)(void)) + FUNCTION_LOADER(Player_Free, void (*)(MODULE*)) + FUNCTION_LOADER(Player_LoadGeneric, MODULE* (*)(MREADER*,int,BOOL)) + FUNCTION_LOADER(Player_SetPosition, void (*)(UWORD)) + FUNCTION_LOADER(Player_SetVolume, void (*)(SWORD)) + FUNCTION_LOADER(Player_Start, void (*)(MODULE*)) + FUNCTION_LOADER(Player_Stop, void (*)(void)) + FUNCTION_LOADER(VC_WriteBytes, ULONG (*)(SBYTE*,ULONG)) + VARIABLE_LOADER(drv_nos, MDRIVER*) + VARIABLE_LOADER(md_device, UWORD*) + VARIABLE_LOADER(md_mixfreq, UWORD*) + VARIABLE_LOADER(md_mode, UWORD*) + VARIABLE_LOADER(md_musicvolume, UBYTE*) + VARIABLE_LOADER(md_pansep, UBYTE*) + VARIABLE_LOADER(md_reverb, UBYTE*) + VARIABLE_LOADER(md_sndfxvolume, UBYTE*) + VARIABLE_LOADER(md_volume, UBYTE*) } ++mikmod.loaded; @@ -341,19 +154,27 @@ static void MIKMOD_Unload() return; } if (mikmod.loaded == 1) { +#ifdef MIKMOD_DYNAMIC + SDL_UnloadObject(mikmod.handle); +#endif } --mikmod.loaded; } -#endif /* MOD_DYNAMIC */ +typedef struct +{ + int play_count; + int volume; + MODULE *module; + SDL_AudioStream *stream; + SBYTE *buffer; + ULONG buffer_size; +} MIKMOD_Music; -/* Reference for converting mikmod output to 4/6 channels */ -static int current_output_channels; -static Uint16 current_output_format; -static int music_swap8; -static int music_swap16; +static int MIKMOD_Seek(void *context, double position); +static void MIKMOD_Delete(void *context); /* Initialize the MOD player, with the given mixer settings This function returns 0, or -1 if there was an error. @@ -363,45 +184,14 @@ static int MIKMOD_Open(const SDL_AudioSpec *spec) CHAR *list; /* Set the MikMod music format */ - music_swap8 = 0; - music_swap16 = 0; - switch (spec->format) { - - case AUDIO_U8: - case AUDIO_S8: { - if (spec->format == AUDIO_S8) { - music_swap8 = 1; - } - *mikmod.md_mode = 0; - } - break; - - case AUDIO_S16LSB: - case AUDIO_S16MSB: { - /* See if we need to correct MikMod mixing */ -#if SDL_BYTEORDER == SDL_LIL_ENDIAN - if (spec->format == AUDIO_S16MSB) { -#else - if (spec->format == AUDIO_S16LSB) { -#endif - music_swap16 = 1; - } - *mikmod.md_mode = DMODE_16BITS; - } - break; - - default: { - Mix_SetError("Unknown hardware audio format"); - return -1; - } + if (spec->format == AUDIO_S8 || spec->format == AUDIO_U8) { + /* MIKMOD audio format is AUDIO_U8 */ + *mikmod.md_mode = 0; + } else { + /* MIKMOD audio format is AUDIO_S16SYS */ + *mikmod.md_mode = DMODE_16BITS; } - current_output_channels = spec->channels; - current_output_format = spec->format; if (spec->channels > 1) { - if (spec->channels > MAX_OUTPUT_CHANNELS) { - Mix_SetError("Hardware uses more channels than supported"); - return -1; - } *mikmod.md_mode |= DMODE_STEREO; } *mikmod.md_mixfreq = spec->freq; @@ -414,22 +204,23 @@ static int MIKMOD_Open(const SDL_AudioSpec *spec) *mikmod.md_mode |= DMODE_HQMIXER|DMODE_SOFT_MUSIC|DMODE_SURROUND; list = mikmod.MikMod_InfoDriver(); - if (list) + if (list) { mikmod.MikMod_free(list); - else + } else { mikmod.MikMod_RegisterDriver(mikmod.drv_nos); + } list = mikmod.MikMod_InfoLoader(); - if (list) + if (list) { mikmod.MikMod_free(list); - else + } else { mikmod.MikMod_RegisterAllLoaders(); + } if (mikmod.MikMod_Init(NULL)) { Mix_SetError("%s", mikmod.MikMod_strerror(*mikmod.MikMod_errno)); return -1; } - return 0; } @@ -510,43 +301,81 @@ MODULE *MikMod_LoadSongRW(SDL_RWops *src, int maxchan) /* Load a MOD stream from an SDL_RWops object */ void *MIKMOD_CreateFromRW(SDL_RWops *src, int freesrc) { - MODULE *module; + MIKMOD_Music *music; + SDL_AudioFormat format; + Uint8 channels; - module = MikMod_LoadSongRW(src, 64); - if (!module) { + music = (MIKMOD_Music *)SDL_calloc(1, sizeof(*music)); + if (!music) { + SDL_OutOfMemory(); + return NULL; + } + music->volume = MIX_MAX_VOLUME; + + music->module = MikMod_LoadSongRW(src, 64); + if (!music->module) { Mix_SetError("%s", mikmod.MikMod_strerror(*mikmod.MikMod_errno)); + MIKMOD_Delete(music); return NULL; } /* Stop implicit looping, fade out and other flags. */ - module->extspd = 1; - module->panflag = 1; - module->wrap = 0; - module->loop = 0; + music->module->extspd = 1; + music->module->panflag = 1; + music->module->wrap = 0; + music->module->loop = 0; #if 0 /* Don't set fade out by default - unfortunately there's no real way to query the status of the song or set trigger actions. Hum. */ - module->fadeout = 1; + music->module->fadeout = 1; #endif + if ((*mikmod.md_mode & DMODE_16BITS) == DMODE_16BITS) { + format = AUDIO_S16SYS; + } else { + format = AUDIO_U8; + } + if ((*mikmod.md_mode & DMODE_STEREO) == DMODE_STEREO) { + channels = 2; + } else { + channels = 1; + } + music->stream = SDL_NewAudioStream(format, channels, *mikmod.md_mixfreq, + music_spec.format, music_spec.channels, music_spec.freq); + if (!music->stream) { + MIKMOD_Delete(music); + return NULL; + } + + music->buffer_size = music_spec.samples * (SDL_AUDIO_BITSIZE(format) / 8) * channels; + music->buffer = (SBYTE *)SDL_malloc(music->buffer_size); + if (!music->buffer) { + SDL_OutOfMemory(); + MIKMOD_Delete(music); + return NULL; + } + if (freesrc) { SDL_RWclose(src); } - return module; + return music; } /* Set the volume for a MOD stream */ static void MIKMOD_SetVolume(void *context, int volume) { + MIKMOD_Music *music = (MIKMOD_Music *)context; + music->volume = volume; mikmod.Player_SetVolume((SWORD)volume); } /* Start playback of a given MOD stream */ -static int MIKMOD_Play(void *context) +static int MIKMOD_Play(void *context, int play_count) { - MODULE *music = (MODULE *)context; - mikmod.Player_Start(music); - mikmod.Player_SetVolume((SWORD)music_volume); - return 0; + MIKMOD_Music *music = (MIKMOD_Music *)context; + music->play_count = play_count; + mikmod.Player_Start(music->module); + mikmod.Player_SetVolume((SWORD)music->volume); + return MIKMOD_Seek(music, 0.0); } /* Return non-zero if a stream is currently playing */ @@ -556,84 +385,50 @@ static SDL_bool MIKMOD_IsPlaying(void *context) } /* Play some of a stream previously started with MOD_play() */ -static int MIKMOD_GetAudio(void *context, void *data, int bytes) +static int MIKMOD_GetSome(void *context, void *data, int bytes, SDL_bool *done) { - MODULE *music = (MODULE *)context; - Uint8 *stream = (Uint8 *)data; - int len = bytes; - - if (current_output_channels > 2) { - int small_len = 2 * len / current_output_channels; - int i; - Uint8 *src, *dst; - - mikmod.VC_WriteBytes((SBYTE *)stream, small_len); - /* and extend to len by copying channels */ - src = stream + small_len; - dst = stream + len; - - switch (current_output_format & 0xFF) { - case 8: - for (i=small_len/2; i; --i) { - src -= 2; - dst -= current_output_channels; - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[0]; - dst[3] = src[1]; - if (current_output_channels == 6) { - dst[4] = src[0]; - dst[5] = src[1]; - } - } - break; - case 16: - for (i=small_len/4; i; --i) { - src -= 4; - dst -= 2 * current_output_channels; - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - dst[3] = src[3]; - dst[4] = src[0]; - dst[5] = src[1]; - dst[6] = src[2]; - dst[7] = src[3]; - if (current_output_channels == 6) { - dst[8] = src[0]; - dst[9] = src[1]; - dst[10] = src[2]; - dst[11] = src[3]; - } - } - break; - } - } else { - mikmod.VC_WriteBytes((SBYTE *)stream, len); + MIKMOD_Music *music = (MIKMOD_Music *)context; + int filled; + + filled = SDL_AudioStreamGet(music->stream, data, bytes); + if (filled != 0) { + return filled; } - if (music_swap8) { - Uint8 *dst; - int i; - dst = stream; - for (i=len; i; --i) { - *dst++ ^= 0x80; - } - } else - if (music_swap16) { - Uint8 *dst, tmp; - int i; - - dst = stream; - for (i=(len/2); i; --i) { - tmp = dst[0]; - dst[0] = dst[1]; - dst[1] = tmp; - dst += 2; + if (!music->play_count) { + /* All done */ + *done = SDL_TRUE; + return 0; + } + + /* This never fails, and always writes a full buffer */ + mikmod.VC_WriteBytes(music->buffer, music->buffer_size); + + if (SDL_AudioStreamPut(music->stream, music->buffer, music->buffer_size) < 0) { + return -1; + } + + /* Check to see if we're done now */ + if (!mikmod.Player_Active()) { + if (music->play_count == 1) { + music->play_count = 0; + SDL_AudioStreamFlush(music->stream); + } else { + int play_count = -1; + if (music->play_count > 0) { + play_count = (music->play_count - 1); + } + if (MIKMOD_Play(music, play_count) < 0) { + return -1; + } } } return 0; } +static int MIKMOD_GetAudio(void *context, void *data, int bytes) +{ + return music_pcm_getaudio(context, data, bytes, MIX_MAX_VOLUME, MIKMOD_GetSome); +} /* Jump (seek) to a given position (time is in seconds) */ static int MIKMOD_Seek(void *context, double position) @@ -651,8 +446,18 @@ static void MIKMOD_Stop(void *context) /* Close the given MOD stream */ static void MIKMOD_Delete(void *context) { - MODULE *music = (MODULE *)context; - mikmod.Player_Free(music); + MIKMOD_Music *music = (MIKMOD_Music *)context; + + if (music->module) { + mikmod.Player_Free(music->module); + } + if (music->stream) { + SDL_FreeAudioStream(music->stream); + } + if (music->buffer) { + SDL_free(music->buffer); + } + SDL_free(music); } Mix_MusicInterface Mix_MusicInterface_MIKMOD = @@ -674,7 +479,7 @@ Mix_MusicInterface Mix_MusicInterface_MIKMOD = MIKMOD_Seek, NULL, /* Pause */ NULL, /* Resume */ - NULL, /* Stop */ + MIKMOD_Stop, MIKMOD_Delete, MIKMOD_Close, MIKMOD_Unload, diff --git a/music_modplug.c b/music_modplug.c index e73bc6cf..7e40039c 100644 --- a/music_modplug.c +++ b/music_modplug.c @@ -52,65 +52,23 @@ static modplug_loader modplug = { static ModPlug_Settings settings; #ifdef MODPLUG_DYNAMIC +#define FUNCTION_LOADER(FUNC, SIG) \ + modplug.FUNC = (SIG) SDL_LoadFunction(modplug.handle, #FUNC); \ + if (modplug.FUNC == NULL) { SDL_UnloadObject(modplug.handle); return -1; } +#else +#define FUNCTION_LOADER(FUNC, SIG) \ + modplug.FUNC = FUNC; +#endif static int MODPLUG_Load(void) { if (modplug.loaded == 0) { +#ifdef MODPLUG_DYNAMIC modplug.handle = SDL_LoadObject(MODPLUG_DYNAMIC); if (modplug.handle == NULL) { return -1; } - - modplug.ModPlug_Load = - (ModPlugFile* (*)(const void* data, int size)) - SDL_LoadFunction(modplug.handle, "ModPlug_Load"); - - modplug.ModPlug_Unload = - (void (*)(ModPlugFile* file)) - SDL_LoadFunction(modplug.handle, "ModPlug_Unload"); - - modplug.ModPlug_Read = - (int (*)(ModPlugFile* file, void* buffer, int size)) - SDL_LoadFunction(modplug.handle, "ModPlug_Read"); - - modplug.ModPlug_Seek = - (void (*)(ModPlugFile* file, int millisecond)) - SDL_LoadFunction(modplug.handle, "ModPlug_Seek"); - - modplug.ModPlug_GetSettings = - (void (*)(ModPlug_Settings* settings)) - SDL_LoadFunction(modplug.handle, "ModPlug_GetSettings"); - - modplug.ModPlug_SetSettings = - (void (*)(const ModPlug_Settings* settings)) - SDL_LoadFunction(modplug.handle, "ModPlug_SetSettings"); - - modplug.ModPlug_SetMasterVolume = - (void (*)(ModPlugFile* file,unsigned int cvol)) - SDL_LoadFunction(modplug.handle, "ModPlug_SetMasterVolume"); - } - ++modplug.loaded; - - return 0; -} - -static void MODPLUG_Unload(void) -{ - if (modplug.loaded == 0) { - return; - } - if (modplug.loaded == 1) { - SDL_UnloadObject(modplug.handle); - } - --modplug.loaded; -} - -#else /* !MODPLUG_DYNAMIC */ - -int MODPLUG_Load(void) -{ - if (modplug.loaded == 0) { -#ifdef __MACOSX__ +#elif defined(__MACOSX__) extern ModPlugFile* ModPlug_Load(const void* data, int size) __attribute__((weak_import)); if (ModPlug_Load == NULL) { @@ -118,15 +76,14 @@ int MODPLUG_Load(void) Mix_SetError("Missing modplug.framework"); return -1; } -#endif // __MACOSX__ - - modplug.ModPlug_Load = ModPlug_Load; - modplug.ModPlug_Unload = ModPlug_Unload; - modplug.ModPlug_Read = ModPlug_Read; - modplug.ModPlug_Seek = ModPlug_Seek; - modplug.ModPlug_GetSettings = ModPlug_GetSettings; - modplug.ModPlug_SetSettings = ModPlug_SetSettings; - modplug.ModPlug_SetMasterVolume = ModPlug_SetMasterVolume; +#endif + FUNCTION_LOADER(ModPlug_Load, ModPlugFile* (*)(const void* data, int size)) + FUNCTION_LOADER(ModPlug_Unload, void (*)(ModPlugFile* file)) + FUNCTION_LOADER(ModPlug_Read, int (*)(ModPlugFile* file, void* buffer, int size)) + FUNCTION_LOADER(ModPlug_Seek, void (*)(ModPlugFile* file, int millisecond)) + FUNCTION_LOADER(ModPlug_GetSettings, void (*)(ModPlug_Settings* settings)) + FUNCTION_LOADER(ModPlug_SetSettings, void (*)(const ModPlug_Settings* settings)) + FUNCTION_LOADER(ModPlug_SetMasterVolume, void (*)(ModPlugFile* file,unsigned int cvol)) } ++modplug.loaded; @@ -139,11 +96,13 @@ static void MODPLUG_Unload(void) return; } if (modplug.loaded == 1) { +#ifdef MODPLUG_DYNAMIC + SDL_UnloadObject(modplug.handle); +#endif } --modplug.loaded; } -#endif /* MODPLUG_DYNAMIC */ typedef struct { diff --git a/music_mpg123.c b/music_mpg123.c index 5415a4b1..f75e9ced 100644 --- a/music_mpg123.c +++ b/music_mpg123.c @@ -84,7 +84,6 @@ static int MPG123_Load(void) return -1; } #endif - FUNCTION_LOADER(mpg123_close, int (*)(mpg123_handle *mh)) FUNCTION_LOADER(mpg123_delete, void (*)(mpg123_handle *mh)) FUNCTION_LOADER(mpg123_exit, void (*)(void)) diff --git a/music_ogg.c b/music_ogg.c index 1b22a505..a6e2e735 100644 --- a/music_ogg.c +++ b/music_ogg.c @@ -62,85 +62,52 @@ static vorbis_loader vorbis = { }; #ifdef OGG_DYNAMIC +#define FUNCTION_LOADER(FUNC, SIG) \ + vorbis.FUNC = (SIG) SDL_LoadFunction(vorbis.handle, #FUNC); \ + if (vorbis.FUNC == NULL) { SDL_UnloadObject(vorbis.handle); return -1; } +#else +#define FUNCTION_LOADER(FUNC, SIG) \ + vorbis.FUNC = FUNC; +#endif static int OGG_Load(void) { if (vorbis.loaded == 0) { +#ifdef OGG_DYNAMIC vorbis.handle = SDL_LoadObject(OGG_DYNAMIC); if (vorbis.handle == NULL) { return -1; } - vorbis.ov_clear = - (int (*)(OggVorbis_File *)) - SDL_LoadFunction(vorbis.handle, "ov_clear"); - if (vorbis.ov_clear == NULL) { - SDL_UnloadObject(vorbis.handle); - return -1; - } - vorbis.ov_info = - (vorbis_info *(*)(OggVorbis_File *,int)) - SDL_LoadFunction(vorbis.handle, "ov_info"); - if (vorbis.ov_info == NULL) { - SDL_UnloadObject(vorbis.handle); - return -1; - } - vorbis.ov_comment = - (vorbis_comment *(*)(OggVorbis_File *,int)) - SDL_LoadFunction(vorbis.handle, "ov_comment"); - if (vorbis.ov_comment == NULL) { - SDL_UnloadObject(vorbis.handle); - return -1; - } - vorbis.ov_open_callbacks = - (int (*)(void *, OggVorbis_File *, const char *, long, ov_callbacks)) - SDL_LoadFunction(vorbis.handle, "ov_open_callbacks"); - if (vorbis.ov_open_callbacks == NULL) { - SDL_UnloadObject(vorbis.handle); - return -1; - } - vorbis.ov_pcm_total = - (ogg_int64_t (*)(OggVorbis_File *,int)) - SDL_LoadFunction(vorbis.handle, "ov_pcm_total"); - if (vorbis.ov_pcm_total == NULL) { - SDL_UnloadObject(vorbis.handle); +#elif defined(__MACOSX__) + extern int ov_open_callbacks(void*, OggVorbis_File*, const char*, long, ov_callbacks) __attribute__((weak_import)); + if (ov_open_callbacks == NULL) + { + /* Missing weakly linked framework */ + Mix_SetError("Missing Vorbis.framework"); return -1; } - vorbis.ov_read = +#endif + FUNCTION_LOADER(ov_clear, int (*)(OggVorbis_File *)) + FUNCTION_LOADER(ov_info, vorbis_info *(*)(OggVorbis_File *,int)) + FUNCTION_LOADER(ov_comment, vorbis_comment *(*)(OggVorbis_File *,int)) + FUNCTION_LOADER(ov_open_callbacks, int (*)(void *, OggVorbis_File *, const char *, long, ov_callbacks)) + FUNCTION_LOADER(ov_pcm_total, ogg_int64_t (*)(OggVorbis_File *,int)) + FUNCTION_LOADER(ov_read, #ifdef OGG_USE_TREMOR - (long (*)(OggVorbis_File *,char *,int,int *)) + long (*)(OggVorbis_File *,char *,int,int *) #else - (long (*)(OggVorbis_File *,char *,int,int,int,int,int *)) + long (*)(OggVorbis_File *,char *,int,int,int,int,int *) #endif - SDL_LoadFunction(vorbis.handle, "ov_read"); - if (vorbis.ov_read == NULL) { - SDL_UnloadObject(vorbis.handle); - return -1; - } - vorbis.ov_time_seek = + ) + FUNCTION_LOADER(ov_time_seek, #ifdef OGG_USE_TREMOR - (long (*)(OggVorbis_File *,ogg_int64_t)) + long (*)(OggVorbis_File *,ogg_int64_t) #else - (int (*)(OggVorbis_File *,double)) + int (*)(OggVorbis_File *,double) #endif - SDL_LoadFunction(vorbis.handle, "ov_time_seek"); - if (vorbis.ov_time_seek == NULL) { - SDL_UnloadObject(vorbis.handle); - return -1; - } - vorbis.ov_pcm_seek = - (int (*)(OggVorbis_File *,ogg_int64_t)) - SDL_LoadFunction(vorbis.handle, "ov_pcm_seek"); - if (vorbis.ov_pcm_seek == NULL) { - SDL_UnloadObject(vorbis.handle); - return -1; - } - vorbis.ov_pcm_tell = - (ogg_int64_t (*)(OggVorbis_File *)) - SDL_LoadFunction(vorbis.handle, "ov_pcm_tell"); - if (vorbis.ov_pcm_tell == NULL) { - SDL_UnloadObject(vorbis.handle); - return -1; - } + ) + FUNCTION_LOADER(ov_pcm_seek, int (*)(OggVorbis_File *,ogg_int64_t)) + FUNCTION_LOADER(ov_pcm_tell, ogg_int64_t (*)(OggVorbis_File *)) } ++vorbis.loaded; @@ -153,53 +120,13 @@ static void OGG_Unload(void) return; } if (vorbis.loaded == 1) { +#ifdef OGG_DYNAMIC SDL_UnloadObject(vorbis.handle); +#endif } --vorbis.loaded; } -#else /* !OGG_DYNAMIC */ - -static int OGG_Load(void) -{ - if (vorbis.loaded == 0) { -#ifdef __MACOSX__ - extern int ov_open_callbacks(void*, OggVorbis_File*, const char*, long, ov_callbacks) __attribute__((weak_import)); - if (ov_open_callbacks == NULL) - { - /* Missing weakly linked framework */ - Mix_SetError("Missing Vorbis.framework"); - return -1; - } -#endif // __MACOSX__ - - vorbis.ov_clear = ov_clear; - vorbis.ov_info = ov_info; - vorbis.ov_comment = ov_comment; - vorbis.ov_open_callbacks = ov_open_callbacks; - vorbis.ov_pcm_total = ov_pcm_total; - vorbis.ov_read = ov_read; - vorbis.ov_time_seek = ov_time_seek; - vorbis.ov_pcm_seek = ov_pcm_seek; - vorbis.ov_pcm_tell = ov_pcm_tell; - } - ++vorbis.loaded; - - return 0; -} - -static void OGG_Unload(void) -{ - if (vorbis.loaded == 0) { - return; - } - if (vorbis.loaded == 1) { - } - --vorbis.loaded; -} - -#endif /* OGG_DYNAMIC */ - typedef struct { SDL_RWops *src; diff --git a/music_smpeg.c b/music_smpeg.c index b5651171..b333bcb5 100644 --- a/music_smpeg.c +++ b/music_smpeg.c @@ -55,121 +55,23 @@ static smpeg_loader smpeg = { }; #ifdef SMPEG_DYNAMIC +#define FUNCTION_LOADER(FUNC, SIG) \ + smpeg.FUNC = (SIG) SDL_LoadFunction(smpeg.handle, #FUNC); \ + if (smpeg.FUNC == NULL) { SDL_UnloadObject(smpeg.handle); return -1; } +#else +#define FUNCTION_LOADER(FUNC, SIG) \ + smpeg.FUNC = FUNC; +#endif static int SMPEG_Load(void) { if (smpeg.loaded == 0) { +#ifdef SMPEG_DYNAMIC smpeg.handle = SDL_LoadObject(SMPEG_DYNAMIC); if (smpeg.handle == NULL) { return -1; } - smpeg.SMPEG_actualSpec = - (void (*)(SMPEG *, SDL_AudioSpec *)) - SDL_LoadFunction(smpeg.handle, "SMPEG_actualSpec"); - if (smpeg.SMPEG_actualSpec == NULL) { - SDL_UnloadObject(smpeg.handle); - return -1; - } - smpeg.SMPEG_delete = - (void (*)(SMPEG*)) - SDL_LoadFunction(smpeg.handle, "SMPEG_delete"); - if (smpeg.SMPEG_delete == NULL) { - SDL_UnloadObject(smpeg.handle); - return -1; - } - smpeg.SMPEG_enableaudio = - (void (*)(SMPEG*, int)) - SDL_LoadFunction(smpeg.handle, "SMPEG_enableaudio"); - if (smpeg.SMPEG_enableaudio == NULL) { - SDL_UnloadObject(smpeg.handle); - return -1; - } - smpeg.SMPEG_enablevideo = - (void (*)(SMPEG*, int)) - SDL_LoadFunction(smpeg.handle, "SMPEG_enablevideo"); - if (smpeg.SMPEG_enablevideo == NULL) { - SDL_UnloadObject(smpeg.handle); - return -1; - } - smpeg.SMPEG_new_rwops = - (SMPEG* (*)(SDL_RWops *, SMPEG_Info*, int, int)) - SDL_LoadFunction(smpeg.handle, "SMPEG_new_rwops"); - if (smpeg.SMPEG_new_rwops == NULL) { - SDL_UnloadObject(smpeg.handle); - return -1; - } - smpeg.SMPEG_play = - (void (*)(SMPEG*)) - SDL_LoadFunction(smpeg.handle, "SMPEG_play"); - if (smpeg.SMPEG_play == NULL) { - SDL_UnloadObject(smpeg.handle); - return -1; - } - smpeg.SMPEG_playAudio = - (int (*)(SMPEG *, Uint8 *, int)) - SDL_LoadFunction(smpeg.handle, "SMPEG_playAudio"); - if (smpeg.SMPEG_playAudio == NULL) { - SDL_UnloadObject(smpeg.handle); - return -1; - } - smpeg.SMPEG_rewind = - (void (*)(SMPEG*)) - SDL_LoadFunction(smpeg.handle, "SMPEG_rewind"); - if (smpeg.SMPEG_rewind == NULL) { - SDL_UnloadObject(smpeg.handle); - return -1; - } - smpeg.SMPEG_setvolume = - (void (*)(SMPEG*, int)) - SDL_LoadFunction(smpeg.handle, "SMPEG_setvolume"); - if (smpeg.SMPEG_setvolume == NULL) { - SDL_UnloadObject(smpeg.handle); - return -1; - } - smpeg.SMPEG_skip = - (void (*)(SMPEG*, float)) - SDL_LoadFunction(smpeg.handle, "SMPEG_skip"); - if (smpeg.SMPEG_skip == NULL) { - SDL_UnloadObject(smpeg.handle); - return -1; - } - smpeg.SMPEG_status = - (SMPEGstatus (*)(SMPEG*)) - SDL_LoadFunction(smpeg.handle, "SMPEG_status"); - if (smpeg.SMPEG_status == NULL) { - SDL_UnloadObject(smpeg.handle); - return -1; - } - smpeg.SMPEG_stop = - (void (*)(SMPEG*)) - SDL_LoadFunction(smpeg.handle, "SMPEG_stop"); - if (smpeg.SMPEG_stop == NULL) { - SDL_UnloadObject(smpeg.handle); - return -1; - } - } - ++smpeg.loaded; - - return 0; -} - -static void SMPEG_Unload(void) -{ - if (smpeg.loaded == 0) { - return; - } - if (smpeg.loaded == 1) { - SDL_UnloadObject(smpeg.handle); - } - --smpeg.loaded; -} - -#else /* !SMPEG_DYNAMIC */ - -static int SMPEG_Load(void) -{ - if (smpeg.loaded == 0) { -#ifdef __MACOSX__ +#elif defined(__MACOSX__) extern SMPEG* SMPEG_new_rwops(SDL_RWops*, SMPEG_Info*, int, int) __attribute__((weak_import)); if (SMPEG_new_rwops == NULL) { @@ -177,20 +79,19 @@ static int SMPEG_Load(void) Mix_SetError("Missing smpeg2.framework"); return -1; } -#endif // __MACOSX__ - - smpeg.SMPEG_actualSpec = SMPEG_actualSpec; - smpeg.SMPEG_delete = SMPEG_delete; - smpeg.SMPEG_enableaudio = SMPEG_enableaudio; - smpeg.SMPEG_enablevideo = SMPEG_enablevideo; - smpeg.SMPEG_new_rwops = SMPEG_new_rwops; - smpeg.SMPEG_play = SMPEG_play; - smpeg.SMPEG_playAudio = SMPEG_playAudio; - smpeg.SMPEG_rewind = SMPEG_rewind; - smpeg.SMPEG_setvolume = SMPEG_setvolume; - smpeg.SMPEG_skip = SMPEG_skip; - smpeg.SMPEG_status = SMPEG_status; - smpeg.SMPEG_stop = SMPEG_stop; +#endif + FUNCTION_LOADER(SMPEG_actualSpec, void (*)(SMPEG *, SDL_AudioSpec *)) + FUNCTION_LOADER(SMPEG_delete, void (*)(SMPEG*)) + FUNCTION_LOADER(SMPEG_enableaudio, void (*)(SMPEG*, int)) + FUNCTION_LOADER(SMPEG_enablevideo, void (*)(SMPEG*, int)) + FUNCTION_LOADER(SMPEG_new_rwops, SMPEG* (*)(SDL_RWops *, SMPEG_Info*, int, int)) + FUNCTION_LOADER(SMPEG_play, void (*)(SMPEG*)) + FUNCTION_LOADER(SMPEG_playAudio, int (*)(SMPEG *, Uint8 *, int)) + FUNCTION_LOADER(SMPEG_rewind, void (*)(SMPEG*)) + FUNCTION_LOADER(SMPEG_setvolume, void (*)(SMPEG*, int)) + FUNCTION_LOADER(SMPEG_skip, void (*)(SMPEG*, float)) + FUNCTION_LOADER(SMPEG_status, SMPEGstatus (*)(SMPEG*)) + FUNCTION_LOADER(SMPEG_stop, void (*)(SMPEG*)) } ++smpeg.loaded; @@ -203,12 +104,13 @@ static void SMPEG_Unload(void) return; } if (smpeg.loaded == 1) { +#ifdef SMPEG_DYNAMIC + SDL_UnloadObject(smpeg.handle); +#endif } --smpeg.loaded; } -#endif /* SMPEG_DYNAMIC */ - typedef struct {