diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 7f95559e6..af3679fd3 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,9 @@ D2X-Rebirth Changelog +20110418 +-------- +arch/sdl/digi_mixer_music.c, arch/sdl/jukebox.c, main/config.c, main/menu.c, main/songs.c, main/songs.h, main/titles.c: Fix broken m3u playlist support (in jukebox_play() path resolving); point to default descent.m3u playlist for Mac OS X (will be included in bundle); better error reporting in mix_play_file(); only make relative Jukebox path in the menu absolute after browsing it - relative paths are more flexible; allow select_file_recursive() to figure out PhysicsFS relative paths passed to it; stop the music if Jukebox is chosen and unavailable (used to just keep playing the last song) + 20110414 -------- main/kmatrix.c: Fixing km struct being used after it's being freed by closing the window in EVENT_WINDOW_DRAW diff --git a/arch/sdl/digi_mixer_music.c b/arch/sdl/digi_mixer_music.c index 1bd007ef2..84d989b72 100644 --- a/arch/sdl/digi_mixer_music.c +++ b/arch/sdl/digi_mixer_music.c @@ -63,6 +63,19 @@ int mix_play_file(char *filename, int loop, void (*hook_finished_track)()) if (!current_music) current_music = Mix_LoadMUS(filename); + // allow the shell convention tilde character to mean the user's home folder + // chiefly used for default jukebox level song music referenced in 'descent.m3u' for Mac OS X + if (!current_music && *filename == '~') + { + snprintf(full_path, PATH_MAX, "%s%s", PHYSFS_getUserDir(), + &filename[1 + (!strncmp(&filename[1], PHYSFS_getDirSeparator(), strlen(PHYSFS_getDirSeparator())) ? + strlen(PHYSFS_getDirSeparator()) : 0)]); + current_music = Mix_LoadMUS(full_path); + if (current_music) + filename = full_path; // used later for possible error reporting + } + + // no luck. so it might be in Searchpath. So try to build absolute path if (!current_music) { @@ -94,7 +107,7 @@ int mix_play_file(char *filename, int loop, void (*hook_finished_track)()) } else { - con_printf(CON_CRITICAL,"Music %s could not be loaded\n", filename); + con_printf(CON_CRITICAL,"Music %s could not be loaded: %s\n", filename, Mix_GetError()); mix_stop_music(); } diff --git a/arch/sdl/jukebox.c b/arch/sdl/jukebox.c index 32c14abba..84796e0c0 100644 --- a/arch/sdl/jukebox.c +++ b/arch/sdl/jukebox.c @@ -59,15 +59,29 @@ void jukebox_unload() char *jukebox_exts[] = { ".mp3", ".ogg", ".wav", ".aif", ".mid", NULL }; -void read_m3u(void) +int read_m3u(void) { FILE *fp; int length; char *buf; + char *abspath; - fp = fopen(GameCfg.CMLevelMusicPath, "rb"); + MALLOC(abspath, char, PATH_MAX); + if (!abspath) + return 0; + + if (PHYSFS_exists(GameCfg.CMLevelMusicPath)) // it's a child of Sharepath, build full path + PHYSFSX_getRealPath(GameCfg.CMLevelMusicPath, abspath); + else + { + strncpy(abspath, GameCfg.CMLevelMusicPath, PATH_MAX - 1); + abspath[PATH_MAX - 1] = '\0'; + } + + fp = fopen(abspath, "rb"); + d_free(abspath); if (!fp) - return; + return 0; fseek( fp, -1, SEEK_END ); length = ftell(fp) + 1; @@ -75,7 +89,7 @@ void read_m3u(void) if (!JukeboxSongs.list_buf) { fclose(fp); - return; + return 0; } fseek(fp, 0, SEEK_SET); @@ -83,7 +97,7 @@ void read_m3u(void) { d_free(JukeboxSongs.list_buf); fclose(fp); - return; + return 0; } fclose(fp); // Finished with it @@ -93,7 +107,7 @@ void read_m3u(void) if (!JukeboxSongs.list) { d_free(JukeboxSongs.list_buf); - return; + return 0; } JukeboxSongs.max_songs = 1024; @@ -125,15 +139,14 @@ void read_m3u(void) *buf = 0; } + + return 1; } /* Loads music file names from a given directory or M3U playlist */ void jukebox_load() { static int jukebox_init = 1; - int new_path = 0; - char *p; - const char *sep = PHYSFS_getDirSeparator(); // initialize JukeboxSongs structure once per runtime if (jukebox_init) @@ -145,41 +158,36 @@ void jukebox_load() jukebox_unload(); - // build path properly. - if (strlen(GameCfg.CMLevelMusicPath) >= strlen(sep)) - { - char *abspath; - - MALLOC(abspath, char, PATH_MAX); - - p = GameCfg.CMLevelMusicPath + strlen(GameCfg.CMLevelMusicPath) - strlen(sep); - if (strcmp(p, sep) && stricmp(&GameCfg.CMLevelMusicPath[strlen(GameCfg.CMLevelMusicPath) - 4], ".m3u")) - strncat(GameCfg.CMLevelMusicPath, sep, PATH_MAX - 1 - strlen(GameCfg.CMLevelMusicPath)); - - if (PHYSFS_isDirectory(GameCfg.CMLevelMusicPath)) // it's a child of Sharepath, build full path - { - PHYSFSX_getRealPath(GameCfg.CMLevelMusicPath,abspath); - snprintf(GameCfg.CMLevelMusicPath,sizeof(char)*PATH_MAX,"%s",abspath); - } - d_free(abspath); - } - - new_path = PHYSFSX_isNewPath(GameCfg.CMLevelMusicPath); - // Check if it's an M3U file - if (!PHYSFS_addToSearchPath(GameCfg.CMLevelMusicPath, 0)) - { - if (!stricmp(&GameCfg.CMLevelMusicPath[strlen(GameCfg.CMLevelMusicPath) - 4], ".m3u")) - read_m3u(); - } - else + if (!stricmp(&GameCfg.CMLevelMusicPath[strlen(GameCfg.CMLevelMusicPath) - 4], ".m3u")) + read_m3u(); + else // a directory { + int new_path = 0; + char *p; + const char *sep = PHYSFS_getDirSeparator(); int i; - // Read directory using PhysicsFS + // stick a separator on the end if necessary. + if (strlen(GameCfg.CMLevelMusicPath) >= strlen(sep)) + { + p = GameCfg.CMLevelMusicPath + strlen(GameCfg.CMLevelMusicPath) - strlen(sep); + if (strcmp(p, sep)) + strncat(GameCfg.CMLevelMusicPath, sep, PATH_MAX - 1 - strlen(GameCfg.CMLevelMusicPath)); + } + + // Read directory using PhysicsFS + if (PHYSFS_isDirectory(GameCfg.CMLevelMusicPath)) // find files in relative directory + JukeboxSongs.list = PHYSFSX_findFiles(GameCfg.CMLevelMusicPath, jukebox_exts); + else + { + new_path = PHYSFSX_isNewPath(GameCfg.CMLevelMusicPath); + PHYSFS_addToSearchPath(GameCfg.CMLevelMusicPath, 0); + + // as mountpoints are no option (yet), make sure only files originating from GameCfg.CMLevelMusicPath are aded to the list. + JukeboxSongs.list = PHYSFSX_findabsoluteFiles("", GameCfg.CMLevelMusicPath, jukebox_exts); + } - // as mountpoints are no option (yet), make sure only files originating from GameCfg.CMLevelMusicPath are aded to the list. - JukeboxSongs.list = PHYSFSX_findabsoluteFiles("", GameCfg.CMLevelMusicPath, jukebox_exts); if (!JukeboxSongs.list) { if (new_path) @@ -243,7 +251,10 @@ int jukebox_play() MALLOC(full_filename, char, strlen(GameCfg.CMLevelMusicPath)+strlen(music_filename)+1); memset(full_filename, '\0', strlen(GameCfg.CMLevelMusicPath)+strlen(music_filename)+1); - snprintf(full_filename, strlen(GameCfg.CMLevelMusicPath)+strlen(music_filename)+1, "%s%s", GameCfg.CMLevelMusicPath, music_filename); + if (!stricmp(&GameCfg.CMLevelMusicPath[strlen(GameCfg.CMLevelMusicPath) - 4], ".m3u")) // if it's from an M3U playlist + strcpy(full_filename, music_filename); + else // if it's from a specified path + snprintf(full_filename, strlen(GameCfg.CMLevelMusicPath)+strlen(music_filename)+1, "%s%s", GameCfg.CMLevelMusicPath, music_filename); if (!mix_play_file(full_filename, ((GameCfg.CMLevelMusicPlayOrder == MUSIC_CM_PLAYORDER_LEVEL)?1:0), ((GameCfg.CMLevelMusicPlayOrder == MUSIC_CM_PLAYORDER_LEVEL)?NULL:jukebox_hook_next))) { diff --git a/main/config.c b/main/config.c index a5f22c836..8b5313d8b 100644 --- a/main/config.c +++ b/main/config.c @@ -92,12 +92,12 @@ int ReadConfigFile() memset(GameCfg.CMMiscMusic[SONG_CREDITS],0,PATH_MAX+1); #if defined(__APPLE__) && defined(__MACH__) GameCfg.OrigTrackOrder = 1; - snprintf(GameCfg.CMLevelMusicPath, PATH_MAX, "%s/%s", PHYSFS_getUserDir(), "Music/iTunes/iTunes Music/Redbook Soundtrack/Descent II, Macintosh CD-ROM/"); - snprintf(GameCfg.CMMiscMusic[SONG_TITLE], PATH_MAX, "%s/%s", PHYSFS_getUserDir(), "Music/iTunes/iTunes Music/Redbook Soundtrack/Descent II, Macintosh CD-ROM/02 Title.mp3"); - snprintf(GameCfg.CMMiscMusic[SONG_BRIEFING], PATH_MAX, "%s/%s", PHYSFS_getUserDir(), "Music/iTunes/iTunes Music/Insanity/Descent/03 Outerlimits.mp3"); - snprintf(GameCfg.CMMiscMusic[SONG_ENDLEVEL], PATH_MAX, "%s/%s", PHYSFS_getUserDir(), "Music/iTunes/iTunes Music/Insanity/Descent/04 Close Call.mp3"); - snprintf(GameCfg.CMMiscMusic[SONG_ENDGAME], PATH_MAX, "%s/%s", PHYSFS_getUserDir(), "Music/iTunes/iTunes Music/Insanity/Descent/14 Insanity.mp3"); - snprintf(GameCfg.CMMiscMusic[SONG_CREDITS], PATH_MAX, "%s/%s", PHYSFS_getUserDir(), "Music/iTunes/iTunes Music/Redbook Soundtrack/Descent II, Macintosh CD-ROM/03 Crawl.mp3"); + snprintf(GameCfg.CMLevelMusicPath, PATH_MAX, "%s", "descent2.m3u"); + snprintf(GameCfg.CMMiscMusic[SONG_TITLE], PATH_MAX, "%s%s", PHYSFS_getUserDir(), "Music/iTunes/iTunes Music/Redbook Soundtrack/Descent II, Macintosh CD-ROM/02 Title.mp3"); + snprintf(GameCfg.CMMiscMusic[SONG_BRIEFING], PATH_MAX, "%s%s", PHYSFS_getUserDir(), "Music/iTunes/iTunes Music/Insanity/Descent/03 Outerlimits.mp3"); + snprintf(GameCfg.CMMiscMusic[SONG_ENDLEVEL], PATH_MAX, "%s%s", PHYSFS_getUserDir(), "Music/iTunes/iTunes Music/Insanity/Descent/04 Close Call.mp3"); + snprintf(GameCfg.CMMiscMusic[SONG_ENDGAME], PATH_MAX, "%s%s", PHYSFS_getUserDir(), "Music/iTunes/iTunes Music/Insanity/Descent/14 Insanity.mp3"); + snprintf(GameCfg.CMMiscMusic[SONG_CREDITS], PATH_MAX, "%s%s", PHYSFS_getUserDir(), "Music/iTunes/iTunes Music/Redbook Soundtrack/Descent II, Macintosh CD-ROM/03 Crawl.mp3"); #endif GameCfg.GammaLevel = 0; memset(GameCfg.LastPlayer,0,CALLSIGN_LEN+1); diff --git a/main/menu.c b/main/menu.c index 7dcdd9e47..61a6f615a 100644 --- a/main/menu.c +++ b/main/menu.c @@ -1539,6 +1539,7 @@ int select_file_recursive(char *title, const char *orig_path, char **ext_list, i browser *b; const char *sep = PHYSFS_getDirSeparator(); char *p; + char new_path[PATH_MAX]; MALLOC(b, browser, 1); if (!b) @@ -1553,6 +1554,13 @@ int select_file_recursive(char *title, const char *orig_path, char **ext_list, i b->view_path[0] = '\0'; b->new_path = 1; + // Check for a PhysicsFS path first, saves complication! + if (orig_path && strncmp(orig_path, sep, strlen(sep)) && PHYSFS_exists(orig_path)) + { + PHYSFSX_getRealPath(orig_path, new_path); + orig_path = new_path; + } + // Set the viewing directory to orig_path, or some parent of it if (orig_path) { diff --git a/main/songs.c b/main/songs.c index 4de376ca5..54acaf194 100644 --- a/main/songs.c +++ b/main/songs.c @@ -36,7 +36,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "timer.h" int Songs_initialized = 0; -static int Song_playing = 0; // 0 if no song playing, else the Descent song number +static int Song_playing = -1; // -1 if no song playing, else the Descent song number static int Redbook_playing = 0; // Redbook track num differs from Song_playing. We need this for Redbook repeat hooks. bim_song_info *BIMSongs = NULL; @@ -180,7 +180,7 @@ void songs_uninit() if (BIMSongs != NULL) d_free(BIMSongs); - Song_playing = 0; + Song_playing = -1; Songs_initialized = 0; } @@ -195,7 +195,7 @@ void songs_stop_all(void) mix_stop_music(); #endif - Song_playing = 0; + Song_playing = -1; } void songs_pause(void) @@ -300,7 +300,7 @@ int songs_play_song( int songnum, int repeat ) { case MUSIC_TYPE_BUILTIN: { - Song_playing = 0; + Song_playing = -1; #ifdef _WIN32 if (GameArg.SndDisableSdlMixer) { @@ -325,7 +325,7 @@ int songs_play_song( int songnum, int repeat ) { int num_tracks = RBAGetNumberOfTracks(); - //Song_playing = 0; // keep playing current music if chosen song is unavailable (e.g. SONG_ENDLEVEL) + //Song_playing = -1; // keep playing current music if chosen song is unavailable (e.g. SONG_ENDLEVEL) if ((songnum == SONG_TITLE) && (REDBOOK_TITLE_TRACK <= num_tracks)) { if (RBAPlayTracks(REDBOOK_TITLE_TRACK, REDBOOK_TITLE_TRACK, repeat ? play_credits_track : NULL)) @@ -351,7 +351,7 @@ int songs_play_song( int songnum, int repeat ) if (Song_playing >= SONG_FIRST_LEVEL_SONG && songnum == SONG_ENDLEVEL && !strlen(GameCfg.CMMiscMusic[songnum])) return Song_playing; - Song_playing = 0; + Song_playing = -1; if (mix_play_file(GameCfg.CMMiscMusic[songnum], // Play the credits track after the title track and loop the credits track if original CD track order was chosen (songnum == SONG_TITLE && GameCfg.OrigTrackOrder) ? 0 : repeat, @@ -361,10 +361,14 @@ int songs_play_song( int songnum, int repeat ) } #endif default: - Song_playing = 0; + Song_playing = -1; break; } + // If we couldn't play the song, most likely because it wasn't specified, play no music. + if (Song_playing == -1) + songs_stop_all(); + return Song_playing; } @@ -385,7 +389,7 @@ int songs_play_level_song( int levelnum, int offset ) songs_init(); if (!Songs_initialized) return 0; - + songnum = (levelnum>0)?(levelnum-1):(-levelnum); switch (GameCfg.MusicType) @@ -395,7 +399,7 @@ int songs_play_level_song( int levelnum, int offset ) if (offset) return Song_playing; - Song_playing = 0; + Song_playing = -1; if ((Num_bim_songs - SONG_FIRST_LEVEL_SONG) > 0) { songnum = SONG_FIRST_LEVEL_SONG + (songnum % (Num_bim_songs - SONG_FIRST_LEVEL_SONG)); @@ -443,7 +447,7 @@ int songs_play_level_song( int levelnum, int offset ) tracknum = REDBOOK_FIRST_LEVEL_TRACK + (tracknum - n_tracks) - 1; } - Song_playing = 0; + Song_playing = -1; if (RBAEnabled() && (tracknum <= n_tracks)) { if (RBAPlayTracks(tracknum, n_tracks, redbook_first_song_func)) @@ -464,7 +468,7 @@ int songs_play_level_song( int levelnum, int offset ) if (GameCfg.CMLevelMusicPlayOrder == MUSIC_CM_PLAYORDER_CONT) { static int last_songnum = -1; - + if (Song_playing >= SONG_FIRST_LEVEL_SONG) return Song_playing; @@ -485,7 +489,7 @@ int songs_play_level_song( int levelnum, int offset ) GameCfg.CMLevelMusicTrack[0] = GameCfg.CMLevelMusicTrack[0] - GameCfg.CMLevelMusicTrack[1]; } - Song_playing = 0; + Song_playing = -1; if (jukebox_play()) Song_playing = songnum + SONG_FIRST_LEVEL_SONG; @@ -493,14 +497,18 @@ int songs_play_level_song( int levelnum, int offset ) } #endif default: - Song_playing = 0; + Song_playing = -1; break; } + // If we couldn't play the song, most likely because it wasn't specified, play no music. + if (Song_playing == -1) + songs_stop_all(); + return Song_playing; } -// check which song is playing +// check which song is playing, or -1 if not playing anything int songs_is_playing() { return Song_playing; diff --git a/main/songs.h b/main/songs.h index 738b3f6cb..99f09f6f4 100644 --- a/main/songs.h +++ b/main/songs.h @@ -24,7 +24,7 @@ int songs_play_level_song( int levelnum, int offset ); //stop any songs - midi, redbook or jukebox - that are currently playing void songs_stop_all(void); -// check which song is playing +// check which song is playing, or -1 if not playing anything int songs_is_playing(); void songs_pause(void); diff --git a/main/titles.c b/main/titles.c index 7625d3edc..8c9dff1b7 100644 --- a/main/titles.c +++ b/main/titles.c @@ -1250,7 +1250,7 @@ int new_briefing_screen(briefing *br, int first) br->guy_bitmap_show = 0; br->prev_ch = -1; - if (!songs_is_playing() && (br->hum_channel == -1)) + if ((songs_is_playing() == -1) && (br->hum_channel == -1)) br->hum_channel = digi_start_sound( digi_xlat_sound(SOUND_BRIEFING_HUM), F1_0/2, 0xFFFF/2, 1, -1, -1, -1 ); return 1;