From 039b8b551ecbde0052aa089e28af3c994b20f85e Mon Sep 17 00:00:00 2001 From: zicodxx <> Date: Thu, 1 May 2008 21:40:34 +0000 Subject: [PATCH] Extended Jukebox capabilities for looping and continous playing and added jukebox_free() which allows calling jukebox_load() being able to load a new directory; Added Jukebox options to sound options menu; Removed loop hack for Windows MIDI playback; SDL_mixer implementation can now be used for Windows build as well --- CHANGELOG.txt | 4 ++ SConstruct | 3 +- arch/include/jukebox.h | 9 ++-- arch/ogl/gr.c | 6 +-- arch/sdl/digi_mixer.c | 7 ++- arch/sdl/digi_mixer_music.c | 9 ++-- arch/sdl/jukebox.c | 91 +++++++++++++++++++++++-------------- arch/win32/hmpfile.c | 4 +- d1x.ini | 2 + include/args.h | 3 +- main/config.c | 14 ++++++ main/config.h | 2 + main/game.c | 2 +- main/inferno.c | 8 +--- main/menu.c | 16 +++++-- main/songs.c | 4 -- misc/args.c | 3 +- 17 files changed, 114 insertions(+), 73 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 5fdc7e8d5..2523714da 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,9 @@ D1X-Rebirth Changelog +20080502 +-------- +include/args.h, main/inferno.c, main/menu.c, main/songs.c, main/config.c, main/config.h, main/game.c, misc/args.c, SConstruct, d1x.ini, arch/ogl/gr.c, arch/sdl/digi_mixer.c, arch/sdl/digi_mixer_music.c, arch/sdl/jukebox.c, arch/win32/hmpfile.c, arch/include/jukebox.h: Extended Jukebox capabilities for looping and continous playing and added jukebox_free() which allows calling jukebox_load() being able to load a new directory; Added Jukebox options to sound options menu; Removed loop hack for Windows MIDI playback; SDL_mixer implementation can now be used for Windows build as well + 20080427 -------- main/console.c: make sure it doesn't try to write to gamelog.txt after it's closed diff --git a/SConstruct b/SConstruct index 4398f065c..7e8a4f1a7 100644 --- a/SConstruct +++ b/SConstruct @@ -283,8 +283,7 @@ arch_sdlmixer = [ ] if (sdlmixer == 1): - arch_linux_sources += arch_sdlmixer - arch_macosx_sources += arch_sdlmixer + common_sources += arch_sdlmixer # flags and stuff for all platforms diff --git a/arch/include/jukebox.h b/arch/include/jukebox.h index d8604a625..d89c4a2b0 100644 --- a/arch/include/jukebox.h +++ b/arch/include/jukebox.h @@ -1,12 +1,13 @@ #ifndef __JUKEBOX_H__ #define __JUKEBOX_H__ +void jukebox_free(); void jukebox_load(); -void jukebox_play(); +void jukebox_play(int loop); void jukebox_stop(); -void jukebox_hook_stop(); -void jukebox_hook_next(); -void jukebox_next(); +void jukebox_hook_stop(); +void jukebox_hook_next(); +void jukebox_next(); void jukebox_prev(); char *jukebox_current(); int jukebox_is_loaded(); diff --git a/arch/ogl/gr.c b/arch/ogl/gr.c index dacd1921b..9fdaf6902 100644 --- a/arch/ogl/gr.c +++ b/arch/ogl/gr.c @@ -66,7 +66,7 @@ int ogl_init_window(int x, int y) #endif ogl_smash_texture_list_internal();//if we are or were fullscreen, changing vid mode will invalidate current textures } - SDL_WM_SetCaption(DESCENT_VERSION, "Descent II"); + SDL_WM_SetCaption(DESCENT_VERSION, "Descent"); if (!SDL_SetVideoMode(x, y, GameArg.DbgGlBpp, SDL_OPENGL | (ogl_fullscreen ? SDL_FULLSCREEN : 0))) { @@ -156,9 +156,7 @@ void ogl_get_verinfo(void) gl_version=(const char *)glGetString(GL_VERSION); gl_extensions=(const char *)glGetString(GL_EXTENSIONS); -#ifndef NDEBUG - con_printf(CON_VERBOSE,"gl vendor:%s renderer:%s version:%s extensions:%s\n",gl_vendor,gl_renderer,gl_version,gl_extensions); -#endif + con_printf(CON_VERBOSE, "OpenGL: vendor: %s\nOpenGL: renderer: %s\nOpenGL: version: %s\n",gl_vendor,gl_renderer,gl_version); #ifdef _WIN32 dglMultiTexCoord2fARB = (glMultiTexCoord2fARB_fp)wglGetProcAddress("glMultiTexCoord2fARB"); diff --git a/arch/sdl/digi_mixer.c b/arch/sdl/digi_mixer.c index 3ef7126d9..8dc2ed3eb 100644 --- a/arch/sdl/digi_mixer.c +++ b/arch/sdl/digi_mixer.c @@ -80,6 +80,7 @@ int digi_mixer_init() { jukebox_load(); //jukebox_list(); + atexit(jukebox_free); atexit(digi_close); digi_initialised = 1; @@ -203,15 +204,14 @@ int digi_mixer_get_max_channels() { return digi_max_channels; } // MIDI stuff follows. -#ifndef _WIN32 - void digi_mixer_play_midi_song(char * filename, char * melodic_bank, char * drum_bank, int loop ) { mix_set_music_volume(midi_volume); + jukebox_load(); // update jukebox state // quick hack to check if filename begins with "game" -- MD2211 if (jukebox_is_loaded() && strstr(filename, "game") == filename) { // use jukebox - jukebox_play(); + jukebox_play(loop); } else { // standard song playback @@ -227,7 +227,6 @@ int digi_mixer_music_exists(const char *filename) void digi_mixer_stop_current_song() { jukebox_stop(); //stops jukebox as well as standard music } -#endif void digi_mixer_pause_midi() {} void digi_mixer_resume_midi() {} diff --git a/arch/sdl/digi_mixer_music.c b/arch/sdl/digi_mixer_music.c index 10f568766..a0a5dddfd 100644 --- a/arch/sdl/digi_mixer_music.c +++ b/arch/sdl/digi_mixer_music.c @@ -76,8 +76,6 @@ void mix_play_music(char *filename, int loop) { char music_title[16]; char *basedir = "Music"; - loop *= -1; - // Quick hack to filter out the .hmp extension for (i=0; !got_end; i++) { switch (filename[i]) { @@ -116,6 +114,10 @@ void mix_play_file(char *filename, int loop) { PHYSFSX_getRealPath(filename, real_filename); // build absolute path + // If loop, builtin music (MIDI) should loop (-1) while in jukebox it should only play once and proceed to next track (1) or stop after track (0) + if (!jukebox_is_loaded() && loop) + loop = -1; + if ((current_music = Mix_LoadMUS(real_filename))) { if (Mix_PlayingMusic()) { // Fade-in effect sounds cleaner if we're already playing something @@ -124,7 +126,8 @@ void mix_play_file(char *filename, int loop) { else { Mix_PlayMusic(current_music, loop); } - Mix_HookMusicFinished(loop == -1 ? music_hook_next : music_hook_stop); + + Mix_HookMusicFinished(loop == 1 ? music_hook_next : music_hook_stop); } else { con_printf(CON_CRITICAL,"Music %s could not be loaded\n", real_filename); diff --git a/arch/sdl/jukebox.c b/arch/sdl/jukebox.c index ccfdd6214..3424d20dc 100644 --- a/arch/sdl/jukebox.c +++ b/arch/sdl/jukebox.c @@ -13,8 +13,8 @@ #include "jukebox.h" #include "error.h" #include "console.h" +#include "config.h" -#define JUKEBOX_ARG "-jukebox" #define MUSIC_HUDMSG_MAXLEN 40 #define JUKEBOX_HUDMSG_PLAYING "Now playing:" #define JUKEBOX_HUDMSG_STOPPED "Jukebox stopped" @@ -59,52 +59,73 @@ char *select_next_song(dl_list *list) { return ret; } +void jukebox_free() +{ + if (JukeboxSongs == NULL) + return; + + while (JukeboxSongs->first!=NULL) + { + dl_remove(JukeboxSongs,JukeboxSongs->first); + } + d_free(JukeboxSongs); + jukebox_loaded = 0; +} + /* Loads music file names from a given directory */ void jukebox_load() { int count = 0; char **files; char *music_exts[] = { ".mp3", ".ogg", ".wav", ".aif", NULL }; + static char curpath[PATH_MAX+1]; - if (!jukebox_loaded) { - if (GameArg.SndJukebox) { - // Adding as a mount point is an option, but wouldn't work for older versions of PhysicsFS - PHYSFS_addToSearchPath(GameArg.SndJukebox, 1); - - JukeboxSongs = dl_init(); - files = PHYSFSX_findFiles("", music_exts); - - if (files != NULL && *files != NULL) { - char **i; - - for (i=files; *i!=NULL; i++) - { - dl_add(JukeboxSongs, *i); - count++; - } - if (count) - { - con_printf(CON_DEBUG,"Jukebox: %d music file(s) found in %s\n", count, GameArg.SndJukebox); - jukebox_loaded = 1; - } - else { con_printf(CON_DEBUG,"Jukebox music could not be found!\n"); } - } - else - { Int3(); } // should at least find a directory in some search path, otherwise how did D2X load? - - if (files != NULL) - free(files); - } + if (memcmp(curpath,GameCfg.JukeboxPath,PATH_MAX) || !GameCfg.JukeboxOn) + { + PHYSFS_removeFromSearchPath(curpath); + jukebox_free(); + } + + if (jukebox_loaded) + return; + + if (GameCfg.JukeboxOn) { + // Adding as a mount point is an option, but wouldn't work for older versions of PhysicsFS + PHYSFS_addToSearchPath(GameCfg.JukeboxPath, 1); + + JukeboxSongs = dl_init(); + files = PHYSFSX_findFiles("", music_exts); + + if (files != NULL && *files != NULL) { + char **i; + + for (i=files; *i!=NULL; i++) + { + dl_add(JukeboxSongs, *i); + count++; + } + if (count) + { + con_printf(CON_DEBUG,"Jukebox: %d music file(s) found in %s\n", count, GameCfg.JukeboxPath); + memcpy(curpath,GameCfg.JukeboxPath,PATH_MAX); + jukebox_loaded = 1; + } + else { con_printf(CON_DEBUG,"Jukebox music could not be found!\n"); } + } + else + { Int3(); } // should at least find a directory in some search path, otherwise how did D2X load? + + if (files != NULL) + free(files); } - else { con_printf(CON_DEBUG,"Jukebox already loaded\n"); } } -void jukebox_play() { +void jukebox_play(int loop) { char *music_filename; if (!jukebox_loaded) return; music_filename = (char *) JukeboxSongs->current->data; - mix_play_file(music_filename, 0); + mix_play_file(music_filename, loop); // Formatting a pretty message if (strlen(music_filename) >= MUSIC_HUDMSG_MAXLEN) { @@ -138,13 +159,13 @@ void jukebox_hook_next() { void jukebox_next() { if (!jukebox_loaded) return; select_next_song(JukeboxSongs); - if (jukebox_playing) jukebox_play(); + if (jukebox_playing) jukebox_play(1); } void jukebox_prev() { if (!jukebox_loaded) return; select_prev_song(JukeboxSongs); - if (jukebox_playing) jukebox_play(); + if (jukebox_playing) jukebox_play(1); } char *jukebox_current() { diff --git a/arch/win32/hmpfile.c b/arch/win32/hmpfile.c index 021506265..ac8b3dfad 100644 --- a/arch/win32/hmpfile.c +++ b/arch/win32/hmpfile.c @@ -297,8 +297,6 @@ static void reset_tracks(struct hmp_file *hmp) hmp->cur_time=0; } -extern int loop; - static void _stdcall midi_callback(HMIDISTRM hms, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) { MIDIHDR *mhdr; hmp_file *hmp; @@ -316,7 +314,7 @@ static void _stdcall midi_callback(HMIDISTRM hms, UINT uMsg, DWORD dwUser, DWORD if (!hmp->stop) { while (fill_buffer(hmp) == HMP_EOF) { - if (loop) + if (hmp->bLoop) hmp->stop = 0; else hmp->stop = 1; diff --git a/d1x.ini b/d1x.ini index c26d7c407..c294f557c 100644 --- a/d1x.ini +++ b/d1x.ini @@ -24,6 +24,8 @@ ;-nosound Disables sound output ;-nomusic Disables music output +;-nosdlmixer Disable Sound output via SDL_mixer +;-music_ext Play music files with extension (i.e. mp3, ogg) Graphics: diff --git a/include/args.h b/include/args.h index 8b4f39886..2550808c1 100644 --- a/include/args.h +++ b/include/args.h @@ -58,9 +58,8 @@ typedef struct Arg int CtlGrabMouse; int SndNoSound; int SndNoMusic; - int SndSdlMixer; + int SndDisableSdlMixer; char *SndExternalMusic; - char *SndJukebox; int GfxHiresFNTAvailable; #ifdef OGL int OglFixedFont; diff --git a/main/config.c b/main/config.c index 8cffb3ba0..31b587da2 100644 --- a/main/config.c +++ b/main/config.c @@ -54,6 +54,8 @@ static char *WindowModeStr="WindowMode"; static char *TexFiltStr="TexFilt"; static char *VSyncStr="VSync"; static char *MultisampleStr="Multisample"; +static char *JukeboxOnStr="JukeboxOn"; +static char *JukeboxPathStr="JukeboxPath"; int ReadConfigFile() { @@ -75,6 +77,8 @@ int ReadConfigFile() GameCfg.TexFilt = 0; GameCfg.VSync = 0; GameCfg.Multisample = 0; + GameCfg.JukeboxOn = 0; + memset(GameCfg.JukeboxPath,0,PATH_MAX+1); infile = PHYSFSX_openReadBuffered("descent.cfg"); @@ -132,6 +136,14 @@ int ReadConfigFile() GameCfg.VSync = strtol(value, NULL, 10); else if (!strcmp(token, MultisampleStr)) GameCfg.Multisample = strtol(value, NULL, 10); + else if (!strcmp(token, JukeboxOnStr)) + GameCfg.JukeboxOn = strtol(value, NULL, 10); + else if (!strcmp(token, JukeboxPathStr)) { + char * p; + strncpy( GameCfg.JukeboxPath, value, PATH_MAX ); + p = strchr( GameCfg.JukeboxPath, '\n'); + if ( p ) *p = 0; + } } } @@ -174,6 +186,8 @@ int WriteConfigFile() PHYSFSX_printf(infile, "%s=%i\n", TexFiltStr, GameCfg.TexFilt); PHYSFSX_printf(infile, "%s=%i\n", VSyncStr, GameCfg.VSync); PHYSFSX_printf(infile, "%s=%i\n", MultisampleStr, GameCfg.Multisample); + PHYSFSX_printf(infile, "%s=%i\n", JukeboxOnStr, GameCfg.JukeboxOn); + PHYSFSX_printf(infile, "%s=%s\n", JukeboxPathStr, GameCfg.JukeboxPath ); PHYSFS_close(infile); diff --git a/main/config.h b/main/config.h index 99a487ef3..bf38f64d0 100644 --- a/main/config.h +++ b/main/config.h @@ -40,6 +40,8 @@ typedef struct Cfg int TexFilt; int VSync; int Multisample; + int JukeboxOn; + char JukeboxPath[PATH_MAX+1]; } __pack__ Cfg; extern struct Cfg GameCfg; diff --git a/main/game.c b/main/game.c index 86ba9ef6d..3e6af21b5 100644 --- a/main/game.c +++ b/main/game.c @@ -2180,7 +2180,7 @@ void HandleGameKey(int key) * ============================================== */ case KEY_ALTED + KEY_SHIFTED + KEY_F9: - jukebox_play(); + jukebox_play(1); break; case KEY_ALTED + KEY_SHIFTED + KEY_F10: jukebox_stop(); diff --git a/main/inferno.c b/main/inferno.c index 43fac8161..561d5c7b4 100644 --- a/main/inferno.c +++ b/main/inferno.c @@ -159,9 +159,8 @@ void show_commandline_help() printf( " -nosound %s\n", "Disables sound output"); printf( " -nomusic %s\n", "Disables music output"); #ifdef USE_SDLMIXER - printf( " -sdlmixer %s\n", "Sound output via SDL_mixer"); + printf( " -nosdlmixer %s\n", "Disable Sound output via SDL_mixer"); printf( " -music_ext %s\n", "Play music files with extension (i.e. mp3, ogg)"); - printf( " -jukebox %s\n", "Play music files out of path "); #endif // USE SDLMIXER printf( "\n Graphics:\n\n"); @@ -314,10 +313,7 @@ int main(int argc,char *argv[]) key_init(); - digi_select_system( - GameArg.SndSdlMixer || GameArg.SndExternalMusic || GameArg.SndJukebox ? - SDLMIXER_SYSTEM : SDLAUDIO_SYSTEM - ); + digi_select_system( GameArg.SndDisableSdlMixer ? SDLAUDIO_SYSTEM : SDLMIXER_SYSTEM ); if (!GameArg.SndNoSound) digi_init(); diff --git a/main/menu.c b/main/menu.c index 476e0d902..4741cd596 100644 --- a/main/menu.c +++ b/main/menu.c @@ -665,18 +665,28 @@ void sound_menuset(int nitems, newmenu_item * items, int *last_key, int citem ) void do_sound_menu() { - newmenu_item m[4]; + newmenu_item m[7]; int i = 0; do { m[0].type = NM_TYPE_SLIDER; m[0].text=TXT_FX_VOLUME; m[0].value=GameCfg.DigiVolume; m[0].min_value=0; m[0].max_value=8; - m[1].type =NM_TYPE_SLIDER; m[1].text=TXT_MUSIC_VOLUME; m[1].value=GameCfg.MidiVolume; m[1].min_value=0; m[1].max_value=8; + m[1].type = NM_TYPE_SLIDER; m[1].text="music volume"; m[1].value=GameCfg.MidiVolume; m[1].min_value=0; m[1].max_value=8; m[2].type = NM_TYPE_TEXT; m[2].text=""; - m[3].type = NM_TYPE_CHECK; m[3].text=TXT_REVERSE_STEREO; m[3].value=GameCfg.ReverseStereo; + m[3].type = NM_TYPE_CHECK; m[3].text=TXT_REVERSE_STEREO; m[3].value=GameCfg.ReverseStereo; +#ifdef USE_SDLMIXER + m[4].type = NM_TYPE_CHECK; m[4].text="use jukebox in game"; m[4].value=GameCfg.JukeboxOn; + m[5].type = NM_TYPE_TEXT; m[5].text="path to music for jukebox:"; + m[6].type = NM_TYPE_INPUT; m[6].text = GameCfg.JukeboxPath; m[6].text_len = PATH_MAX; +#endif i = newmenu_do1( NULL, "Sound Effects & Music", sizeof(m)/sizeof(*m), m, sound_menuset, i ); GameCfg.ReverseStereo = m[3].value; +#ifdef USE_SDLMIXER + GameCfg.JukeboxOn = m[4].value; + if (Function_mode == FMODE_GAME) + songs_play_level_song( Current_level_num ); +#endif } while( i>-1 ); } diff --git a/main/songs.c b/main/songs.c index 1f843b9a9..025f30301 100644 --- a/main/songs.c +++ b/main/songs.c @@ -119,14 +119,10 @@ void songs_init() cfclose(fp); } -int loop; - void songs_play_song( int songnum, int repeat ) { if ( !Songs_initialized ) songs_init(); - loop=repeat; - digi_play_midi_song( Songs[songnum].filename, Songs[songnum].melodic_bank_file, Songs[songnum].drum_bank_file, repeat ); } diff --git a/misc/args.c b/misc/args.c index 88c34d5db..aaf93a2cf 100644 --- a/misc/args.c +++ b/misc/args.c @@ -156,8 +156,7 @@ void ReadCmdArgs(void) GameArg.SndNoMusic = FindArg("-nomusic"); #ifdef USE_SDLMIXER - GameArg.SndSdlMixer = FindArg("-sdlmixer"); - GameArg.SndJukebox = get_str_arg("-jukebox", NULL); + GameArg.SndDisableSdlMixer = FindArg("-nosdlmixer"); GameArg.SndExternalMusic = get_str_arg("-music_ext", NULL); #endif