Hi list,
When playing a mod file using Mix_PlayMusic, the loops of the mod file
are ignored, resulting in the music being played incorrectly.
This has been discussed in this forum entry (there is a workaround provided):
http://forums.libsdl.org/viewtopic.php?t=7160
This is due to the ‘Jump to order’ command being ignored while the
file is being played.
http://www.milkytracker.org/docs/MilkyTracker.html#fxBxx
In my particular case, my game uses a mod file containing multiple music loops.
Music loops are switched dynamically by the game using
Mix_SetMusicPosition(position), which has the particular behaviour of
setting the pattern being played in the case of a mod file.
Having SDL_mixer ignoring the ‘Jump’ commands totally breaks the
playback of the music in my case.
The reason for mod playback not supporting loops is that this has been
explicitely disabled in the MOD_new_RW() function of the music_mod.c
file, with the line:
module->loop = 0; (see source code below)
Is there any reason for this? I cannot imagine why anyone would have
loop commands in mod files ignored by default.
(I didn’t notice this problem earlier, because before ubuntu 12.04,
the binary SDL packages provided with ubuntu didn’t exhibit this
behaviour… Maybe someone had patched it downstream?)
Thanks,
Florent
/* Load a MOD stream from an SDL_RWops object */
MODULE *MOD_new_RW(SDL_RWops *rw, int freerw)
{
MODULE *module;
/* Make sure the mikmod library is loaded */
if ( !Mix_Init(MIX_INIT_MOD) ) {
if ( freerw ) {
SDL_RWclose(rw);
}
return NULL;
}
module = MikMod_LoadSongRW(rw,64);
if (!module) {
Mix_SetError("%s", mikmod.MikMod_strerror(*mikmod.MikMod_errno));
if ( freerw ) {
SDL_RWclose(rw);
}
return NULL;
}
/* Stop implicit looping, fade out and other flags. */
module->extspd = 1;
module->panflag = 1;
module->wrap = 0;
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;
#endif
if ( freerw ) {
SDL_RWclose(rw);
}
return module;
}