From b11ca16d3aeb16c846bc210a2f683bb68dd48f7c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 19 Dec 2001 17:11:40 +0000 Subject: [PATCH] Guillaume Cottenceau - Wed Dec 19 08:59:05 PST 2001 * Added an API for seeking in music files (implemented for MOD files) Mix_FadeInMusicPos(), Mix_SetMusicPosition() * Exposed the mikmod synchro value for music synchronization Mix_SetSynchroValue(), Mix_GetSynchroValue() --- CHANGES | 7 ++++ SDL_mixer.h | 13 ++++++- configure.in | 6 ++-- mikmod/load_xm.c | 3 ++ mikmod/mikmod.h | 2 ++ mikmod/mikmod_internals.h | 1 + mikmod/mplayer.c | 15 ++++++++ mikmod/munitrk.c | 3 +- music.c | 75 ++++++++++++++++++++++++++++++++++++++- 9 files changed, 119 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index c26aae94..47fbc0d8 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,11 @@ +1.2.2: +Guillaume Cottenceau - Wed Dec 19 08:59:05 PST 2001 + * Added an API for seeking in music files (implemented for MOD files) + Mix_FadeInMusicPos(), Mix_SetMusicPosition() + * Exposed the mikmod synchro value for music synchronization + Mix_SetSynchroValue(), Mix_GetSynchroValue() + 1.2.1: Yi-Huang Han - Wed Oct 24 21:55:47 PDT 2001 * Fixed MOD music volume when looping diff --git a/SDL_mixer.h b/SDL_mixer.h index 9be94d74..e6551941 100644 --- a/SDL_mixer.h +++ b/SDL_mixer.h @@ -41,7 +41,7 @@ extern "C" { */ #define MIX_MAJOR_VERSION 1 #define MIX_MINOR_VERSION 2 -#define MIX_PATCHLEVEL 1 +#define MIX_PATCHLEVEL 2 /* This macro can be used to fill a version structure with the compile-time * version of the SDL_mixer library. @@ -460,6 +460,7 @@ extern DECLSPEC int Mix_PlayMusic(Mix_Music *music, int loops); /* Fade in music or a channel over "ms" milliseconds, same semantics as the "Play" functions */ extern DECLSPEC int Mix_FadeInMusic(Mix_Music *music, int loops, int ms); +extern DECLSPEC int Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, int position); #define Mix_FadeInChannel(channel,chunk,loops,ms) Mix_FadeInChannelTimed(channel,chunk,loops,ms,-1) extern DECLSPEC int Mix_FadeInChannelTimed(int channel, Mix_Chunk *chunk, int loops, int ms, int ticks); @@ -506,6 +507,12 @@ extern DECLSPEC void Mix_ResumeMusic(void); extern DECLSPEC void Mix_RewindMusic(void); extern DECLSPEC int Mix_PausedMusic(void); +/* Set the current position in the music stream. + This returns 0 if successful, or -1 if it failed or isn't implemented. + This function is only implemented for MOD music formats at the moment. +*/ +extern DECLSPEC int Mix_SetMusicPosition(int position); + /* Check the status of a specific channel. If the specified channel is -1, check all channels. */ @@ -515,6 +522,10 @@ extern DECLSPEC int Mix_PlayingMusic(void); /* Stop music and set external music playback command */ extern DECLSPEC int Mix_SetMusicCMD(const char *command); +/* Synchro value is set by MikMod from modules while playing */ +extern DECLSPEC int Mix_SetSynchroValue(int value); +extern DECLSPEC int Mix_GetSynchroValue(void); + /* Get the Mix_Chunk currently associated with a mixer channel Returns NULL if it's an invalid channel, or there's no chunk associated. */ diff --git a/configure.in b/configure.in index 4cbc6208..d08a8184 100644 --- a/configure.in +++ b/configure.in @@ -13,9 +13,9 @@ dnl Set various version strings - taken gratefully from the GTk sources MAJOR_VERSION=1 MINOR_VERSION=2 -MICRO_VERSION=1 -INTERFACE_AGE=1 -BINARY_AGE=1 +MICRO_VERSION=2 +INTERFACE_AGE=0 +BINARY_AGE=2 VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION AC_SUBST(MAJOR_VERSION) diff --git a/mikmod/load_xm.c b/mikmod/load_xm.c index 47147a09..5d70c97d 100644 --- a/mikmod/load_xm.c +++ b/mikmod/load_xm.c @@ -286,6 +286,9 @@ static UBYTE* XM_Convert(XMNOTE* xmtrack,UWORD rows) break; } break; + case 'Z'-55: /* Z - synchro */ + UniEffect(UNI_XMEFFECTZ,dat); + break; default: if(eff<=0xf) { /* the pattern jump destination is written in decimal, diff --git a/mikmod/mikmod.h b/mikmod/mikmod.h index 10fed5a3..a9d4e6b0 100644 --- a/mikmod/mikmod.h +++ b/mikmod/mikmod.h @@ -550,6 +550,8 @@ MIKMODAPI extern void Player_Mute(SLONG,...); MIKMODAPI extern void Player_ToggleMute(SLONG,...); MIKMODAPI extern int Player_GetChannelVoice(UBYTE); MIKMODAPI extern UWORD Player_GetChannelPeriod(UBYTE); +MIKMODAPI extern void Player_SetSynchroValue(int); +MIKMODAPI extern int Player_GetSynchroValue(void); typedef void (MikMod_player)(void); typedef MikMod_player *MikMod_player_t; diff --git a/mikmod/mikmod_internals.h b/mikmod/mikmod_internals.h index 5837a698..c5f804c5 100644 --- a/mikmod/mikmod_internals.h +++ b/mikmod/mikmod_internals.h @@ -336,6 +336,7 @@ enum { UNI_MEDEFFECTF1, /* play note twice */ UNI_MEDEFFECTF2, /* delay note */ UNI_MEDEFFECTF3, /* play note three times */ + UNI_XMEFFECTZ, /* XM Z synchro */ UNI_LAST }; diff --git a/mikmod/mplayer.c b/mikmod/mplayer.c index 08ab7f69..1f239012 100644 --- a/mikmod/mplayer.c +++ b/mikmod/mplayer.c @@ -1806,6 +1806,9 @@ static void pt_playeffects(void) case UNI_MEDEFFECTF3: DoEEffects(0x90|(pf->sngspd/3)); break; + case UNI_XMEFFECTZ: + Player_SetSynchroValue(UniGetByte()); + break; default: a->sliding=oldsliding; UniSkipOpcode(c); @@ -2897,4 +2900,16 @@ void Player_SetTempo(UWORD tempo) MUTEX_UNLOCK(vars); } +static int _pl_synchro_value; +void Player_SetSynchroValue(int i) +{ + _pl_synchro_value = i; +} + +int Player_GetSynchroValue(void) +{ + return _pl_synchro_value; +} + + /* ex:set ts=4: */ diff --git a/mikmod/munitrk.c b/mikmod/munitrk.c index 20ed7075..f136f645 100644 --- a/mikmod/munitrk.c +++ b/mikmod/munitrk.c @@ -98,7 +98,8 @@ UWORD unioperands[UNI_LAST]={ 2, /* UNI_MEDSPEED */ 0, /* UNI_MEDEFFECTF1 */ 0, /* UNI_MEDEFFECTF2 */ - 0 /* UNI_MEDEFFECTF3 */ + 0, /* UNI_MEDEFFECTF3 */ + 1 /* UNI_XMEFFECTZ */ }; /* Sparse description of the internal module format diff --git a/music.c b/music.c index 559002ab..875a36b3 100644 --- a/music.c +++ b/music.c @@ -679,8 +679,26 @@ int Mix_PlayMusic(Mix_Music *music, int loops) return(0); } +int Mix_SetMusicPosition(int position) +{ + if ( music_playing && !music_stopped ) { + switch ( music_playing->type ) { +#ifdef MOD_MUSIC + case MUS_MOD: + Player_SetPosition(position); + return(0); + break; +#endif + default: + /* TODO: Implement this for other music backends */ + return(-1); + break; + } + } +} + /* Fade in a music over "ms" milliseconds */ -int Mix_FadeInMusic(Mix_Music *music, int loops, int ms) +int Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, int position) { if ( music && music_volume > 0 ) { /* No need to fade if we can't hear it */ music->fade_volume = music_volume; @@ -688,6 +706,12 @@ int Mix_FadeInMusic(Mix_Music *music, int loops, int ms) if ( Mix_PlayMusic(music, loops) < 0 ) { return(-1); } + if ( position ) { + if ( Mix_SetMusicPosition(position) < 0 ) { + Mix_HaltMusic(); + return(-1); + } + } music_playing->fade_step = 0; music_playing->fade_steps = ms/ms_per_step; music_playing->fading = MIX_FADING_IN; @@ -695,6 +719,11 @@ int Mix_FadeInMusic(Mix_Music *music, int loops, int ms) return(0); } +int Mix_FadeInMusic(Mix_Music *music, int loops, int ms) +{ + return Mix_FadeInMusicPos(music, loops, ms, 0); +} + /* Set the music volume */ int Mix_VolumeMusic(int volume) { @@ -980,6 +1009,50 @@ int Mix_SetMusicCMD(const char *command) return(0); } +int Mix_SetSynchroValue(int i) +{ + if ( music_playing && ! music_stopped ) { + switch (music_playing->type) { +#ifdef MOD_MUSIC + case MUS_MOD: + if ( ! Player_Active() ) { + return(-1); + } + Player_SetSynchroValue(i); + return 0; + break; +#endif + default: + return(-1); + break; + } + return(-1); + } + return(-1); +} + +int Mix_GetSynchroValue(void) +{ + if ( music_playing && ! music_stopped ) { + switch (music_playing->type) { +#ifdef MOD_MUSIC + case MUS_MOD: + if ( ! Player_Active() ) { + return(-1); + } + return Player_GetSynchroValue(); + break; +#endif + default: + return(-1); + break; + } + return(-1); + } + return(-1); +} + + /* Uninitialize the music players */ void close_music(void) {