From f0edc54479049bbf5d9b916b3731c7752ab74d7c Mon Sep 17 00:00:00 2001 From: zicodxx <> Date: Sun, 1 Aug 2010 17:42:38 +0000 Subject: [PATCH] Builtin music list now dynamically allocated and not limited to 30 songs; Instead of never loading new level when loading savestate ingame, only do this for Redbook and Custom Music playing order 'continously'; if no endlevel song is specified in Custom Music continue with level music --- CHANGELOG.txt | 4 ++ arch/sdl/digi.c | 2 +- main/digi.h | 2 +- main/gameseq.c | 3 +- main/menu.c | 28 -------- main/songs.c | 170 ++++++++++++++++++++++++------------------------ main/songs.h | 24 +------ 7 files changed, 94 insertions(+), 139 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 9fd545d3d..877a83ab9 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,9 @@ D1X-Rebirth Changelog +20100801 +-------- +main/menu.c, main/songs.c, main/songs.h, main/gameseq.c, main/digi.h, arch/sdl/digi.c: Builtin music list now dynamically allocated and not limited to 30 songs; Instead of never loading new level when loading savestate ingame, only do this for Redbook and Custom Music playing order 'continously'; if no endlevel song is specified in Custom Music continue with level music + 20100731 -------- main/inferno.c, main/kmatrix.c, main/menu.c, main/newmenu.c, main/newmenu.h, main/scores.c: For polling newmenus, set rval using a pointer and don't delay closing the window, hopefully fixing bad memory access when clicking in level scores screen; change newmenu_close to newmenu_free_background to avoid confusion diff --git a/arch/sdl/digi.c b/arch/sdl/digi.c index abc8f4e31..08a13ddda 100644 --- a/arch/sdl/digi.c +++ b/arch/sdl/digi.c @@ -168,7 +168,7 @@ void digi_win32_set_midi_volume( int mvolume ) midiOutSetVolume((HMIDIOUT)cur_hmp->hmidi, mm_volume | mm_volume << 16); } -int digi_win32_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop ) +int digi_win32_play_midi_song( char * filename, int loop ) { digi_win32_stop_current_song(); diff --git a/main/digi.h b/main/digi.h index 081088355..a3e99b6a3 100644 --- a/main/digi.h +++ b/main/digi.h @@ -122,7 +122,7 @@ void digi_select_system(int); #ifdef _WIN32 // Windows native-MIDI stuff. void digi_win32_set_midi_volume( int mvolume ); -int digi_win32_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop ); +int digi_win32_play_midi_song( char * filename, int loop ); void digi_win32_stop_current_song(); #endif diff --git a/main/gameseq.c b/main/gameseq.c index 4d339fe18..1b266834a 100644 --- a/main/gameseq.c +++ b/main/gameseq.c @@ -704,8 +704,7 @@ void LoadLevel(int level_num) set_sound_sources(); - if (songs_is_playing() < SONG_FIRST_LEVEL_SONG) - songs_play_level_song( Current_level_num, 0 ); + songs_play_level_song( Current_level_num, 0 ); gr_palette_load(gr_palette); //actually load the palette } diff --git a/main/menu.c b/main/menu.c index 44928642d..35c3aa7d9 100644 --- a/main/menu.c +++ b/main/menu.c @@ -95,7 +95,6 @@ enum MENUS MENU_SHOW_CREDITS, MENU_ORDER_INFO, - MENU_PLAY_SONG, #ifdef USE_UDP MENU_START_UDP_NETGAME, @@ -478,8 +477,6 @@ void create_main_menu(newmenu_item *m, int *menu_choice, int *callers_num_option ADD_ITEM(" Editor", MENU_EDITOR, KEY_E); #endif } - - ADD_ITEM( " Play song", MENU_PLAY_SONG, -1 ); #endif *callers_num_options = num_options; @@ -514,20 +511,6 @@ int DoMenu() extern void show_order_form(void); // John didn't want this in inferno.h so I just externed it. -int select_song_callback(listbox *lb, d_event *event, void *userdata) -{ - int citem = listbox_get_citem(lb); - - userdata = userdata; - if (event->type != EVENT_NEWMENU_SELECTED) - return 0; - - if (citem > -1) - songs_play_song( citem, 0 ); - - return 1; // stay in menu until user escapes -} - //returns flag, true means quit menu int do_option ( int select) { @@ -581,17 +564,6 @@ int do_option ( int select) break; #ifndef RELEASE - - case MENU_PLAY_SONG: - { - char * m[MAX_NUM_SONGS]; - int i; - - for (i=0;i= SONG_FIRST_LEVEL_SONG) + int predef=30; // define 30 songs - period + + MALLOC(BIMSongs, bim_song_info, predef); + if (!BIMSongs) + return; + + strncpy(BIMSongs[SONG_TITLE].filename, "descent.hmp",sizeof(BIMSongs[SONG_TITLE].filename)); + strncpy(BIMSongs[SONG_BRIEFING].filename, "briefing.hmp",sizeof(BIMSongs[SONG_BRIEFING].filename)); + strncpy(BIMSongs[SONG_CREDITS].filename, "credits.hmp",sizeof(BIMSongs[SONG_CREDITS].filename)); + strncpy(BIMSongs[SONG_ENDLEVEL].filename, "endlevel.hmp",sizeof(BIMSongs[SONG_ENDLEVEL].filename)); // can't find it? give a warning + strncpy(BIMSongs[SONG_ENDGAME].filename, "endgame.hmp",sizeof(BIMSongs[SONG_ENDGAME].filename)); // ditto + + for (i = SONG_FIRST_LEVEL_SONG; i < predef; i++) { + snprintf(BIMSongs[i].filename, sizeof(BIMSongs[i].filename), "game%02d.hmp", i - SONG_FIRST_LEVEL_SONG + 1); + if (!cfexist(BIMSongs[i].filename)) + snprintf(BIMSongs[i].filename, sizeof(BIMSongs[i].filename), "game%d.hmp", i - SONG_FIRST_LEVEL_SONG); + if (!cfexist(BIMSongs[i].filename)) { - sprintf(Songs[i].filename, "game%02d.hmp", i - SONG_FIRST_LEVEL_SONG + 1); - if (!cfexist(Songs[i].filename)) - sprintf(Songs[i].filename, "game%d.hmp", i - SONG_FIRST_LEVEL_SONG); - if (!cfexist(Songs[i].filename)) - { - Songs[i].filename[0] = '\0'; // music not available - break; - } + memset(BIMSongs[i].filename, '\0', sizeof(BIMSongs[i].filename)); // music not available + break; } } - strcpy(Songs[SONG_TITLE].filename, "descent.hmp"); - strcpy(Songs[SONG_BRIEFING].filename, "briefing.hmp"); - strcpy(Songs[SONG_CREDITS].filename, "credits.hmp"); - strcpy(Songs[SONG_ENDLEVEL].filename, "endlevel.hmp"); // can't find it? give a warning - strcpy(Songs[SONG_ENDGAME].filename, "endgame.hmp"); // ditto } else { while (!PHYSFS_eof(fp)) { - if (i == MAX_NUM_SONGS) - break; - cfgets(inputline, 80, fp ); if ( strlen( inputline ) ) { - memset(Songs[i].filename, '\0', sizeof(char)*16); - memset(Songs[i].melodic_bank_file, '\0', sizeof(char)*16); - memset(Songs[i].drum_bank_file, '\0', sizeof(char)*16); - sscanf( inputline, "%15s %15s %15s", - Songs[i].filename, - Songs[i].melodic_bank_file, - Songs[i].drum_bank_file ); + BIMSongs = d_realloc(BIMSongs, sizeof(bim_song_info)*(i+1)); + memset(BIMSongs[i].filename, '\0', sizeof(BIMSongs[i].filename)); + sscanf( inputline, "%15s", BIMSongs[i].filename ); - if (strrchr(Songs[i].filename, '.')) - if (!stricmp(strrchr(Songs[i].filename, '.'), ".hmp") || - !stricmp(strrchr(Songs[i].filename, '.'), ".mp3") || - !stricmp(strrchr(Songs[i].filename, '.'), ".ogg") || - !stricmp(strrchr(Songs[i].filename, '.'), ".aif") || - !stricmp(strrchr(Songs[i].filename, '.'), ".mid") + if (strrchr(BIMSongs[i].filename, '.')) + if (!stricmp(strrchr(BIMSongs[i].filename, '.'), ".hmp") || + !stricmp(strrchr(BIMSongs[i].filename, '.'), ".mp3") || + !stricmp(strrchr(BIMSongs[i].filename, '.'), ".ogg") || + !stricmp(strrchr(BIMSongs[i].filename, '.'), ".aif") || + !stricmp(strrchr(BIMSongs[i].filename, '.'), ".mid") ) i++; } } - // HACK: If Descent.hog is patched from 1.0 to 1.5, descent.sng is broken and will not exceed 12 songs. So let's HACK it here. + // HACK: If Descent.hog is patched from 1.0 to 1.5, descent.sng is turncated. So let's patch it up here if (i==12 && cfile_size("descent.sng")==422) { - sprintf(Songs[i].filename,"game08.hmp"); sprintf(Songs[i].melodic_bank_file,"rickmelo.bnk"); sprintf(Songs[i].drum_bank_file,"rickdrum.bnk"); i++; - sprintf(Songs[i].filename,"game09.hmp"); sprintf(Songs[i].melodic_bank_file,"melodic.bnk"); sprintf(Songs[i].drum_bank_file,"drum.bnk"); i++; - sprintf(Songs[i].filename,"game10.hmp"); sprintf(Songs[i].melodic_bank_file,"melodic.bnk"); sprintf(Songs[i].drum_bank_file,"drum.bnk"); i++; - sprintf(Songs[i].filename,"game11.hmp"); sprintf(Songs[i].melodic_bank_file,"intmelo.bnk"); sprintf(Songs[i].drum_bank_file,"intdrum.bnk"); i++; - sprintf(Songs[i].filename,"game12.hmp"); sprintf(Songs[i].melodic_bank_file,"melodic.bnk"); sprintf(Songs[i].drum_bank_file,"drum.bnk"); i++; - sprintf(Songs[i].filename,"game13.hmp"); sprintf(Songs[i].melodic_bank_file,"intmelo.bnk"); sprintf(Songs[i].drum_bank_file,"intdrum.bnk"); i++; - sprintf(Songs[i].filename,"game14.hmp"); sprintf(Songs[i].melodic_bank_file,"intmelo.bnk"); sprintf(Songs[i].drum_bank_file,"intdrum.bnk"); i++; - sprintf(Songs[i].filename,"game15.hmp"); sprintf(Songs[i].melodic_bank_file,"melodic.bnk"); sprintf(Songs[i].drum_bank_file,"drum.bnk"); i++; - sprintf(Songs[i].filename,"game16.hmp"); sprintf(Songs[i].melodic_bank_file,"melodic.bnk"); sprintf(Songs[i].drum_bank_file,"drum.bnk"); i++; - sprintf(Songs[i].filename,"game17.hmp"); sprintf(Songs[i].melodic_bank_file,"melodic.bnk"); sprintf(Songs[i].drum_bank_file,"drum.bnk"); i++; - sprintf(Songs[i].filename,"game18.hmp"); sprintf(Songs[i].melodic_bank_file,"intmelo.bnk"); sprintf(Songs[i].drum_bank_file,"intdrum.bnk"); i++; - sprintf(Songs[i].filename,"game19.hmp"); sprintf(Songs[i].melodic_bank_file,"melodic.bnk"); sprintf(Songs[i].drum_bank_file,"drum.bnk"); i++; - sprintf(Songs[i].filename,"game20.hmp"); sprintf(Songs[i].melodic_bank_file,"melodic.bnk"); sprintf(Songs[i].drum_bank_file,"drum.bnk"); i++; - sprintf(Songs[i].filename,"game21.hmp"); sprintf(Songs[i].melodic_bank_file,"intmelo.bnk"); sprintf(Songs[i].drum_bank_file,"intdrum.bnk"); i++; - sprintf(Songs[i].filename,"game22.hmp"); sprintf(Songs[i].melodic_bank_file,"hammelo.bnk"); sprintf(Songs[i].drum_bank_file,"hamdrum.bnk"); i++; + BIMSongs = d_realloc(BIMSongs, sizeof(bim_song_info)*(i+15)); + for (i = 12; i <= 26; i++) + snprintf(BIMSongs[i].filename, sizeof(BIMSongs[i].filename), "game%02d.hmp", i-4); } } - Num_songs = i; + Num_bim_songs = i; Songs_initialized = 1; - if (fp != NULL) cfclose(fp); + if (fp != NULL) + cfclose(fp); // Now each song will get it's own number which will serve custom music (and maybe others) as track number - if (Num_songs > 0) + if (Num_bim_songs > 0) { int i = 0, j = 0, c = 0; - for (i = 0; i < Num_songs; i++) + for (i = 0; i < Num_bim_songs; i++) { - Songs[i].id = -1; + BIMSongs[i].id = -1; for (j = 0; j < i; j++) - if (stricmp(Songs[i].filename, Songs[j].filename) == 0) - Songs[i].id = Songs[j].id; + if (stricmp(BIMSongs[i].filename, BIMSongs[j].filename) == 0) + BIMSongs[i].id = BIMSongs[j].id; - if (Songs[i].id == -1) - Songs[i].id = c++; + if (BIMSongs[i].id == -1) + BIMSongs[i].id = c++; } } @@ -219,6 +202,8 @@ void songs_uninit() jukebox_unload(); #endif + if (BIMSongs != NULL) + d_free(BIMSongs); Song_playing = 0; Songs_initialized = 0; } @@ -306,19 +291,18 @@ void redbook_repeat_func() int songs_play_song( int songnum, int repeat ) { songs_init(); - - //stop any music already playing - - songs_stop_all(); + if (!Songs_initialized) + return 0; switch (GameCfg.MusicType) { case MUSIC_TYPE_BUILTIN: { + Song_playing = 0; #ifdef _WIN32 if (GameArg.SndDisableSdlMixer) { - if (digi_win32_play_midi_song( Songs[songnum].filename, Songs[songnum].melodic_bank_file, Songs[songnum].drum_bank_file, repeat )) + if (digi_win32_play_midi_song( BIMSongs[songnum].filename, repeat )) { Song_playing = songnum; } @@ -327,7 +311,7 @@ int songs_play_song( int songnum, int repeat ) #endif #ifdef USE_SDLMIXER { - if (mix_play_file(Songs[songnum].filename, repeat, NULL)) + if (mix_play_file(BIMSongs[songnum].filename, repeat, NULL)) { Song_playing = songnum; } @@ -339,6 +323,7 @@ int songs_play_song( int songnum, int repeat ) { int num_tracks = RBAGetNumberOfTracks(); + Song_playing = 0; if ((songnum < SONG_ENDGAME) && (songnum + 2 <= num_tracks)) { if (RBAPlayTracks(songnum + 2, 0, repeat ? redbook_repeat_func : NULL)) @@ -368,6 +353,11 @@ int songs_play_song( int songnum, int repeat ) #ifdef USE_SDLMIXER case MUSIC_TYPE_CUSTOM: { + // EXCEPTION: If SONG_ENDLEVEL is undefined, continue playing level song. + if (Song_playing >= SONG_FIRST_LEVEL_SONG && songnum == SONG_ENDLEVEL && !strlen(GameCfg.CMMiscMusic[songnum])) + return Song_playing; + + Song_playing = 0; if (mix_play_file(GameCfg.CMMiscMusic[songnum], repeat, NULL)) Song_playing = songnum; break; @@ -395,13 +385,9 @@ int songs_play_level_song( int levelnum, int offset ) Assert( levelnum != 0 ); - // Track changing not allowed for builtin music - if (offset && GameCfg.MusicType == MUSIC_TYPE_BUILTIN) - return Song_playing; - songs_init(); - - songs_stop_all(); + if (!Songs_initialized) + return 0; songnum = (levelnum>0)?(levelnum-1):(-levelnum); @@ -409,13 +395,17 @@ int songs_play_level_song( int levelnum, int offset ) { case MUSIC_TYPE_BUILTIN: { - if (NumLevelSongs > 0) + if (offset) + return Song_playing; + + Song_playing = 0; + if ((Num_bim_songs - SONG_FIRST_LEVEL_SONG) > 0) { - songnum = SONG_FIRST_LEVEL_SONG + (songnum % NumLevelSongs); + songnum = SONG_FIRST_LEVEL_SONG + (songnum % (Num_bim_songs - SONG_FIRST_LEVEL_SONG)); #ifdef _WIN32 if (GameArg.SndDisableSdlMixer) { - if (digi_win32_play_midi_song( Songs[songnum].filename, Songs[songnum].melodic_bank_file, Songs[songnum].drum_bank_file, 1 )) + if (digi_win32_play_midi_song( BIMSongs[songnum].filename, 1 )) { Song_playing = songnum; } @@ -426,7 +416,7 @@ int songs_play_level_song( int levelnum, int offset ) #endif #ifdef USE_SDLMIXER { - if (mix_play_file(Songs[songnum].filename, 1, NULL)) + if (mix_play_file(BIMSongs[songnum].filename, 1, NULL)) { Song_playing = songnum; } @@ -441,7 +431,12 @@ int songs_play_level_song( int levelnum, int offset ) int tracknum; if (!offset) + { + if (Song_playing >= SONG_FIRST_LEVEL_SONG) + return Song_playing; + tracknum = REDBOOK_FIRST_LEVEL_TRACK + ((n_tracks<=REDBOOK_FIRST_LEVEL_TRACK) ? 0 : (songnum % (n_tracks-REDBOOK_FIRST_LEVEL_TRACK))); + } else { tracknum = Redbook_playing+offset; @@ -451,11 +446,12 @@ int songs_play_level_song( int levelnum, int offset ) tracknum = REDBOOK_FIRST_LEVEL_TRACK + (tracknum - n_tracks) - 1; } + Song_playing = 0; if (RBAEnabled() && (tracknum <= n_tracks)) { if (RBAPlayTracks(tracknum, !songs_haved1_cd()?n_tracks:tracknum, songs_haved1_cd() ? redbook_repeat_func : redbook_first_song_func)) { - Song_playing = songnum; + Song_playing = songnum + SONG_FIRST_LEVEL_SONG; Redbook_playing = tracknum; } } @@ -470,13 +466,16 @@ int songs_play_level_song( int levelnum, int offset ) { static int last_songnum = -1; + if (Song_playing >= SONG_FIRST_LEVEL_SONG) + return Song_playing; + // As soon as we start a new level, go to next track if (last_songnum != -1 && songnum != last_songnum) ((GameCfg.CMLevelMusicTrack[0]+1>=GameCfg.CMLevelMusicTrack[1])?GameCfg.CMLevelMusicTrack[0]=0:GameCfg.CMLevelMusicTrack[0]++); last_songnum = songnum; } else if (GameCfg.CMLevelMusicPlayOrder == MUSIC_CM_PLAYORDER_LEVELDEP) - GameCfg.CMLevelMusicTrack[0] = ((Songs[songnum+SONG_FIRST_LEVEL_SONG].id - SONG_FIRST_LEVEL_SONG) % (GameCfg.CMLevelMusicTrack[1])); + GameCfg.CMLevelMusicTrack[0] = ((BIMSongs[songnum+SONG_FIRST_LEVEL_SONG].id - SONG_FIRST_LEVEL_SONG) % (GameCfg.CMLevelMusicTrack[1])); else if (GameCfg.CMLevelMusicPlayOrder == MUSIC_CM_PLAYORDER_LEVELALPHA) GameCfg.CMLevelMusicTrack[0] = (songnum % GameCfg.CMLevelMusicTrack[1]); } @@ -489,8 +488,9 @@ int songs_play_level_song( int levelnum, int offset ) GameCfg.CMLevelMusicTrack[0] = GameCfg.CMLevelMusicTrack[0] - GameCfg.CMLevelMusicTrack[1]; } + Song_playing = 0; if (jukebox_play()) - Song_playing = songnum; + Song_playing = songnum + SONG_FIRST_LEVEL_SONG; break; } diff --git a/main/songs.h b/main/songs.h index 5daa1a305..0106ba5de 100644 --- a/main/songs.h +++ b/main/songs.h @@ -1,17 +1,3 @@ -/* $Id: songs.h,v 1.1.1.1 2006/03/17 19:55:35 zicodxx Exp $ */ -/* -THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX -SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO -END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A -ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS -IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS -SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE -FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE -CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. -COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. -*/ - /* * * Header for songs.c @@ -21,15 +7,10 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #ifndef _SONGS_H #define _SONGS_H -typedef struct song_info { +typedef struct bim_song_info { char filename[16]; - char melodic_bank_file[16]; - char drum_bank_file[16]; int id; // representative number for each song -} song_info; - -extern int Num_songs; //how many songs -extern song_info Songs[]; +} bim_song_info; #define SONG_TITLE 0 #define SONG_BRIEFING 1 @@ -37,7 +18,6 @@ extern song_info Songs[]; #define SONG_ENDGAME 3 #define SONG_CREDITS 4 #define SONG_FIRST_LEVEL_SONG 5 -#define MAX_NUM_SONGS (5+MAX_LEVELS_PER_MISSION+MAX_SECRET_LEVELS_PER_MISSION) int songs_play_song( int songnum, int repeat ); int songs_play_level_song( int levelnum, int offset );