We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 4107

Summary: SDL_mixer 2.0.3 music_mikmod.c unable to load XM modules using MikMod
Product: SDL_mixer Reporter: Roberto Prieto <dm2>
Component: miscAssignee: Ryan C. Gordon <icculus>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: sezeroz
Version: 2.0.2   
Hardware: All   
OS: All   
Attachments: Patch music_mikmod.c for allowing XM modules to be loaded again

Description Roberto Prieto 2018-03-10 00:16:35 UTC
Created attachment 3191 [details]
Patch music_mikmod.c for allowing XM modules to be loaded again

Since the music.c was rewritten (4 months ago according to Mercurial repo), a new music_mikmod.c was on charge of loading modules using MikMod library.

Unfortunately, a change on the return type of on LMM_Seek() function avoided to load XM modules anymore. It just affect to XM as the rest of MikMod loaders (I checked it) are not using the return value of this function.

In music.c, it was defined as:

BOOL LMM_Seek(...)

and in music_mikmod.c:

int LMM_Seek(...)

I know BOOL is just a typedef int but the way the function returned the value makes the difference: previous one returned 0 with all OK and 1 when failed. New function returns the value of the offset performed which will be evaluated by MikMod in load_xm.c, static BOOL XM_Load(...):

if(_mm_fseek(modreader, mh->headersize+60, SEEK_SET) || _mm_eof(modreader))
		goto bad_hdr;

to false so effectively, avoiding to load XM modules indicating a bad header which is not the case.

The proposed and attached patch is working fine and does not affect the others modules consists in modify LMM_Seek() for returning again 0 and 1.

Regards,
Roberto
Comment 1 Ozkan Sezer 2018-03-10 06:10:01 UTC
I seem to have screwed it up in http://hg.libsdl.org/SDL_mixer/rev/9453f8515493

Looks like SDL_RWseek() behaves like ftell() and not fseek(), so the following
should do the trick without changing return types again.

diff --git a/music_mikmod.c b/music_mikmod.c
--- a/music_mikmod.c
+++ b/music_mikmod.c
@@ -254,7 +254,7 @@ int LMM_Seek(struct MREADER *mr,long to,
         if (offset < lmmmr->offset)
             return -1;
     }
-    return (int)(SDL_RWseek(lmmmr->src, offset, dir));
+    return (SDL_RWseek(lmmmr->src, offset, dir) < lmmmr->offset)? -1 : 0;
 }
 long LMM_Tell(struct MREADER *mr)
 {
Comment 2 Roberto Prieto 2018-03-11 15:32:52 UTC
That's right, for avoiding to break ABI compatibility, we could keep the return type and just modify the returned value. 

Longing for seeing the patch applied to SDL_mixer :).

Regards,
Roberto
Comment 3 Sam Lantinga 2018-03-12 00:12:58 UTC
This should fix it, explicitly checking for errors on the seek:
https://hg.libsdl.org/SDL_mixer/rev/f34c3cb2ed70

Please let me know if this doesn't work!
Comment 4 Ozkan Sezer 2018-03-12 05:55:17 UTC
Consider a case with lmmmr->offset==1 and that SEEK_CUR,-1 is requested:
Seek with succeed but the result will go beyond lmmmr->offset. My patch
in #c1 handles that, yours in hg does not: You won't ever have a negative
offset, therefore the retcode from seek will always be >= lmmmr->offset,
otherwise error.
Comment 5 Ozkan Sezer 2018-05-11 07:52:31 UTC
This should be fixed as of https://hg.libsdl.org/SDL_mixer/rev/703fd1401434