I_GetMusicLoopPoint and I_SetMusicLoopPoint implementation
* Stub pause for MIDI * Fix MP3 tag wide char search * Reset songpaused bool where appropriate
This commit is contained in:
parent
137291d50b
commit
fdd1af62a8
|
@ -237,6 +237,10 @@ boolean I_SetSongSpeed(float speed);
|
||||||
|
|
||||||
UINT32 I_GetMusicLength(void);
|
UINT32 I_GetMusicLength(void);
|
||||||
|
|
||||||
|
boolean I_SetMusicLoopPoint(UINT32 looppoint);
|
||||||
|
|
||||||
|
UINT32 I_GetMusicLoopPoint(void);
|
||||||
|
|
||||||
boolean I_SetMusicPosition(UINT32 position);
|
boolean I_SetMusicPosition(UINT32 position);
|
||||||
|
|
||||||
UINT32 I_GetMusicPosition(void);
|
UINT32 I_GetMusicPosition(void);
|
||||||
|
|
|
@ -1427,6 +1427,16 @@ UINT32 S_GetMusicLength(void)
|
||||||
return I_GetMusicLength();
|
return I_GetMusicLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean S_SetMusicLoopPoint(UINT32 looppoint)
|
||||||
|
{
|
||||||
|
return I_SetMusicPosition(looppoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 S_GetMusicLoopPoint(void)
|
||||||
|
{
|
||||||
|
return I_GetMusicLoopPoint();
|
||||||
|
}
|
||||||
|
|
||||||
boolean S_SetMusicPosition(UINT32 position)
|
boolean S_SetMusicPosition(UINT32 position)
|
||||||
{
|
{
|
||||||
return I_SetMusicPosition(position);
|
return I_SetMusicPosition(position);
|
||||||
|
|
|
@ -142,6 +142,12 @@ boolean S_SpeedMusic(float speed);
|
||||||
// Get Length of Music
|
// Get Length of Music
|
||||||
UINT32 S_GetMusicLength(void);
|
UINT32 S_GetMusicLength(void);
|
||||||
|
|
||||||
|
// Set LoopPoint of Music
|
||||||
|
boolean S_SetMusicLoopPoint(UINT32 looppoint);
|
||||||
|
|
||||||
|
// Get LoopPoint of Music
|
||||||
|
UINT32 S_GetMusicLoopPoint(void);
|
||||||
|
|
||||||
// Set Position of Music
|
// Set Position of Music
|
||||||
boolean S_SetMusicPosition(UINT32 position);
|
boolean S_SetMusicPosition(UINT32 position);
|
||||||
|
|
||||||
|
|
|
@ -477,6 +477,7 @@ static void music_loop(void)
|
||||||
{
|
{
|
||||||
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
|
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
|
||||||
music_bytes = 0;
|
music_bytes = 0;
|
||||||
|
songpaused = false;
|
||||||
// be consistent with FMOD, otherwise I'd prefer to freeze music_bytes
|
// be consistent with FMOD, otherwise I'd prefer to freeze music_bytes
|
||||||
// since the other flags indicate music is still playing.
|
// since the other flags indicate music is still playing.
|
||||||
}
|
}
|
||||||
|
@ -516,8 +517,13 @@ void I_ShutdownMusic(void)
|
||||||
void I_PauseSong(INT32 handle)
|
void I_PauseSong(INT32 handle)
|
||||||
{
|
{
|
||||||
(void)handle;
|
(void)handle;
|
||||||
if(!midimode)
|
|
||||||
|
if(midimode) // really, SDL Mixer? why can't you pause MIDI???
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!gme && I_MusicType() != MU_MOD)
|
||||||
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
|
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
|
||||||
|
|
||||||
Mix_PauseMusic();
|
Mix_PauseMusic();
|
||||||
songpaused = true;
|
songpaused = true;
|
||||||
}
|
}
|
||||||
|
@ -525,14 +531,19 @@ void I_PauseSong(INT32 handle)
|
||||||
void I_ResumeSong(INT32 handle)
|
void I_ResumeSong(INT32 handle)
|
||||||
{
|
{
|
||||||
(void)handle;
|
(void)handle;
|
||||||
if(!midimode)
|
|
||||||
|
if (midimode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!gme && I_MusicType() != MU_MOD)
|
||||||
{
|
{
|
||||||
while(Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes) != 0) { }
|
while(Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes) != 0) { }
|
||||||
// HACK: fixes issue of multiple effect callbacks being registered
|
// HACK: fixes issue of multiple effect callbacks being registered
|
||||||
|
|
||||||
if(music && !Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL))
|
if(music && !Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL))
|
||||||
// midimode and music must be checked in case nothing is actually playing
|
|
||||||
CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError());
|
CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
Mix_ResumeMusic();
|
Mix_ResumeMusic();
|
||||||
songpaused = false;
|
songpaused = false;
|
||||||
}
|
}
|
||||||
|
@ -544,7 +555,7 @@ boolean I_MusicPlaying(void)
|
||||||
|
|
||||||
boolean I_MusicPaused(void)
|
boolean I_MusicPaused(void)
|
||||||
{
|
{
|
||||||
return Mix_PausedMusic();
|
return songpaused;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -574,6 +585,7 @@ void I_ShutdownDigMusic(void)
|
||||||
if (!music)
|
if (!music)
|
||||||
return;
|
return;
|
||||||
is_looping = false;
|
is_looping = false;
|
||||||
|
songpaused = false;
|
||||||
music_bytes = 0;
|
music_bytes = 0;
|
||||||
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
|
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
|
||||||
Mix_HookMusicFinished(NULL);
|
Mix_HookMusicFinished(NULL);
|
||||||
|
@ -714,16 +726,19 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
|
||||||
const char *key2 = "POINT=";
|
const char *key2 = "POINT=";
|
||||||
const char *key3 = "MS=";
|
const char *key3 = "MS=";
|
||||||
const char *key4 = "LENGTHMS=";
|
const char *key4 = "LENGTHMS=";
|
||||||
const char *key1w = "L\0O\0O\0P\0";
|
|
||||||
const char *key2w = "P\0O\0I\0N\0T\0=\0";
|
|
||||||
const char *key3w = "M\0S\0=\0";
|
|
||||||
const char *key4w = "L\0E\0N\0G\0T\0H\0M\0S\0=\0";
|
|
||||||
const char *wterm = "\0\0";
|
|
||||||
const size_t key1len = strlen(key1);
|
const size_t key1len = strlen(key1);
|
||||||
const size_t key2len = strlen(key2);
|
const size_t key2len = strlen(key2);
|
||||||
const size_t key3len = strlen(key3);
|
const size_t key3len = strlen(key3);
|
||||||
const size_t key4len = strlen(key4);
|
const size_t key4len = strlen(key4);
|
||||||
char wval[10]; // millisecond range up to 30 hours!
|
|
||||||
|
// for mp3 wide chars
|
||||||
|
const char *key1w = "L\0O\0O\0P\0";
|
||||||
|
const char *key2w = "P\0O\0I\0N\0T\0\0\0\xFF\xFE";
|
||||||
|
const char *key3w = "M\0S\0\0\0\xFF\xFE";
|
||||||
|
const char *key4w = "L\0E\0N\0G\0T\0H\0M\0S\0\0\0\xFF\xFE";
|
||||||
|
const char *wterm = "\0\0";
|
||||||
|
char wval[10];
|
||||||
|
|
||||||
size_t wstart, wp;
|
size_t wstart, wp;
|
||||||
char *p = data;
|
char *p = data;
|
||||||
while ((UINT32)(p - data) < len)
|
while ((UINT32)(p - data) < len)
|
||||||
|
@ -753,15 +768,15 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
|
||||||
music_length = (float)(atoi(p) / 1000.0L);
|
music_length = (float)(atoi(p) / 1000.0L);
|
||||||
}
|
}
|
||||||
// below: search MP3 or other tags that use wide char encoding
|
// below: search MP3 or other tags that use wide char encoding
|
||||||
else if (!loop_point && !strncmp(p, key1w, key1len*2)) // LOOP wide char
|
else if (!loop_point && !memcmp(p, key1w, key1len*2)) // LOOP wide char
|
||||||
{
|
{
|
||||||
p += key1len*2;
|
p += key1len*2;
|
||||||
if (!strncmp(p, key2w, key2len*2)) // POINT= wide char
|
if (!memcmp(p, key2w, (key2len+1)*2)) // POINT= wide char
|
||||||
{
|
{
|
||||||
p += key2len*2+2;
|
p += (key2len+1)*2;
|
||||||
wstart = (size_t)p;
|
wstart = (size_t)p;
|
||||||
wp = 0;
|
wp = 0;
|
||||||
while (wp < 9 && strncmp(p, wterm, 2))
|
while (wp < 9 && memcmp(p, wterm, 2))
|
||||||
{
|
{
|
||||||
wval[wp] = *p;
|
wval[wp] = *p;
|
||||||
p += 2;
|
p += 2;
|
||||||
|
@ -770,12 +785,12 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
|
||||||
wval[min(wp, 9)] = 0;
|
wval[min(wp, 9)] = 0;
|
||||||
loop_point = (float)((44.1L+atoi(wval) / 44100.0L));
|
loop_point = (float)((44.1L+atoi(wval) / 44100.0L));
|
||||||
}
|
}
|
||||||
else if (!strncmp(p, key3w, key3len*2)) // MS= wide char
|
else if (!memcmp(p, key3w, (key3len+1)*2)) // MS= wide char
|
||||||
{
|
{
|
||||||
p += key3len*2+2;
|
p += (key3len+1)*2;
|
||||||
wstart = (size_t)p;
|
wstart = (size_t)p;
|
||||||
wp = 0;
|
wp = 0;
|
||||||
while (wp < 9 && strncmp(p, wterm, 2))
|
while (wp < 9 && memcmp(p, wterm, 2))
|
||||||
{
|
{
|
||||||
wval[wp] = *p;
|
wval[wp] = *p;
|
||||||
p += 2;
|
p += 2;
|
||||||
|
@ -785,12 +800,12 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
|
||||||
loop_point = (float)(atoi(wval) / 1000.0L);
|
loop_point = (float)(atoi(wval) / 1000.0L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!music_length && !strncmp(p, key4w, key4len*2)) // LENGTHMS= wide char
|
else if (!music_length && !memcmp(p, key4w, (key4len+1)*2)) // LENGTHMS= wide char
|
||||||
{
|
{
|
||||||
p += key4len*2+2;
|
p += (key4len+1)*2;
|
||||||
wstart = (size_t)p;
|
wstart = (size_t)p;
|
||||||
wp = 0;
|
wp = 0;
|
||||||
while (wp < 9 && strncmp(p, wterm, 2))
|
while (wp < 9 && memcmp(p, wterm, 2))
|
||||||
{
|
{
|
||||||
wval[wp] = *p;
|
wval[wp] = *p;
|
||||||
p += 2;
|
p += 2;
|
||||||
|
@ -824,6 +839,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
|
||||||
if (I_MusicType() != MU_MOD)
|
if (I_MusicType() != MU_MOD)
|
||||||
Mix_HookMusicFinished(music_loop); // don't bother counting if MOD
|
Mix_HookMusicFinished(music_loop); // don't bother counting if MOD
|
||||||
|
|
||||||
|
songpaused = false;
|
||||||
music_bytes = 0;
|
music_bytes = 0;
|
||||||
if(I_MusicType() != MU_MOD && !Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL))
|
if(I_MusicType() != MU_MOD && !Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL))
|
||||||
CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError());
|
CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError());
|
||||||
|
@ -848,6 +864,7 @@ void I_StopDigSong(void)
|
||||||
if (!music)
|
if (!music)
|
||||||
return;
|
return;
|
||||||
is_looping = false;
|
is_looping = false;
|
||||||
|
songpaused = false;
|
||||||
music_bytes = 0;
|
music_bytes = 0;
|
||||||
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
|
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
|
||||||
Mix_HookMusicFinished(NULL);
|
Mix_HookMusicFinished(NULL);
|
||||||
|
@ -924,6 +941,42 @@ UINT32 I_GetMusicLength(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean I_SetMusicLoopPoint(UINT32 looppoint)
|
||||||
|
{
|
||||||
|
if (midimode || gme || !music || I_MusicType() == MU_MOD)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
loop_point = max((float)(looppoint / 1000.0L), 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 I_GetMusicLoopPoint(void)
|
||||||
|
{
|
||||||
|
if (gme)
|
||||||
|
{
|
||||||
|
INT32 looppoint;
|
||||||
|
gme_info_t *info;
|
||||||
|
gme_err_t gme_e = gme_track_info(gme, &info, current_track);
|
||||||
|
|
||||||
|
if (gme_e != NULL)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
|
||||||
|
looppoint = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
looppoint = info->intro_length > 0 ? info->intro_length : 0;
|
||||||
|
|
||||||
|
gme_free_info(info);
|
||||||
|
return max(looppoint, 0);
|
||||||
|
}
|
||||||
|
else if (midimode || !music || I_MusicType() == MU_MOD)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return (UINT32)(loop_point * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
boolean I_SetMusicPosition(UINT32 position)
|
boolean I_SetMusicPosition(UINT32 position)
|
||||||
{
|
{
|
||||||
UINT32 length;
|
UINT32 length;
|
||||||
|
@ -1056,6 +1109,7 @@ void I_ShutdownMIDIMusic(void)
|
||||||
if (!midimode || !music)
|
if (!midimode || !music)
|
||||||
return;
|
return;
|
||||||
is_looping = false;
|
is_looping = false;
|
||||||
|
songpaused = false;
|
||||||
//MIDI does count correctly, but dummy out because unsupported
|
//MIDI does count correctly, but dummy out because unsupported
|
||||||
//music_bytes = 0;
|
//music_bytes = 0;
|
||||||
//Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
|
//Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
|
||||||
|
@ -1100,7 +1154,7 @@ boolean I_PlaySong(INT32 handle, boolean looping)
|
||||||
}
|
}
|
||||||
|
|
||||||
is_looping = looping;
|
is_looping = looping;
|
||||||
|
songpaused = false;
|
||||||
//MIDI does count correctly, but dummy out because unsupported
|
//MIDI does count correctly, but dummy out because unsupported
|
||||||
//If this is enabled, you need to edit Mix_PlayMusic above to never loop (0)
|
//If this is enabled, you need to edit Mix_PlayMusic above to never loop (0)
|
||||||
//and register the music_loop callback
|
//and register the music_loop callback
|
||||||
|
@ -1118,7 +1172,7 @@ void I_StopSong(INT32 handle)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
is_looping = false;
|
is_looping = false;
|
||||||
|
songpaused = false;
|
||||||
//MIDI does count correctly, but dummy out because unsupported
|
//MIDI does count correctly, but dummy out because unsupported
|
||||||
//music_bytes = 0;
|
//music_bytes = 0;
|
||||||
//Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
|
//Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
|
||||||
|
@ -1132,7 +1186,7 @@ void I_UnRegisterSong(INT32 handle)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
is_looping = false;
|
is_looping = false;
|
||||||
|
songpaused = false;
|
||||||
//MIDI does count correctly, but dummy out because unsupported
|
//MIDI does count correctly, but dummy out because unsupported
|
||||||
//music_bytes = 0;
|
//music_bytes = 0;
|
||||||
//Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
|
//Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
|
||||||
|
|
Loading…
Reference in New Issue