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

This commit is contained in:
zicodxx 2010-08-01 17:42:38 +00:00
parent 7f93792249
commit fd32ea98c4
7 changed files with 90 additions and 123 deletions

View file

@ -1,5 +1,9 @@
D2X-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/gamepal.c, main/gamerend.c, 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

View file

@ -167,7 +167,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();

View file

@ -124,7 +124,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

View file

@ -810,8 +810,7 @@ void LoadLevel(int level_num,int page_in_textures)
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

View file

@ -96,7 +96,6 @@ enum MENUS
MENU_SHOW_CREDITS,
MENU_ORDER_INFO,
MENU_PLAY_SONG,
#ifdef USE_UDP
MENU_START_UDP_NETGAME,
@ -518,7 +517,6 @@ void create_main_menu(newmenu_item *m, int *menu_choice, int *callers_num_option
#endif
}
//ADD_ITEM( " Play song", MENU_PLAY_SONG, -1 );
#endif
*callers_num_options = num_options;
@ -553,20 +551,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)
{
@ -621,17 +605,6 @@ int do_option ( int select)
break;
#ifndef RELEASE
case MENU_PLAY_SONG:
{
char * m[MAX_NUM_SONGS];
int i;
for (i=0;i<Num_songs;i++)
m[i] = Songs[i].filename;
newmenu_listbox( "Select Song", Num_songs, m, 1, select_song_callback, NULL );
break;
}
case MENU_LOAD_LEVEL:
select_mission(0, "Load Level\n\nSelect mission", do_load_level_menu);
break;

View file

@ -35,16 +35,12 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
#include "config.h"
#include "timer.h"
song_info Songs[MAX_NUM_SONGS];
int Songs_initialized = 0;
int Num_songs;
static int Song_playing = 0; // 0 if no song playing, else the Descent song number
static int Redbook_playing = 0; // Redbook track num differs from Song num. Store here so we know with which track we deal with.
// NOTE: Custom music song number is stored in GameCfg.CMLevelMusicTrack[0]
static int Redbook_playing = 0; // Redbook track num differs from Song_playing. We need this for Redbook repeat hooks.
#define NumLevelSongs (Num_songs - SONG_FIRST_LEVEL_SONG)
bim_song_info *BIMSongs = NULL;
int Num_bim_songs;
#define EXTMUSIC_VOLUME_SCALE (255)
@ -72,7 +68,10 @@ void songs_init()
CFILE * fp = NULL;
char sng_file[PATH_MAX];
memset(Songs, '\0', sizeof(Songs));
Songs_initialized = 0;
if (BIMSongs != NULL)
d_free(BIMSongs);
memset(sng_file, '\0', sizeof(sng_file));
if (Current_mission != NULL)
@ -86,75 +85,71 @@ void songs_init()
if ( fp == NULL ) // No descent.sng available. Define a default song-set
{
for (i = 0; i < MAX_NUM_SONGS; i++) {
strcpy(Songs[i].melodic_bank_file, "melodic.bnk");
strcpy(Songs[i].drum_bank_file, "drum.bnk");
if (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++;
}
}
}
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++;
}
}
@ -199,6 +194,8 @@ void songs_uninit()
jukebox_unload();
#endif
if (BIMSongs != NULL)
d_free(BIMSongs);
Song_playing = 0;
Songs_initialized = 0;
}
@ -307,19 +304,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;
}
@ -328,7 +324,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;
}
@ -340,6 +336,7 @@ int songs_play_song( int songnum, int repeat )
{
int num_tracks = RBAGetNumberOfTracks();
Song_playing = 0;
if ((songnum == SONG_TITLE) && (REDBOOK_TITLE_TRACK <= num_tracks))
{
if (RBAPlayTracks(REDBOOK_TITLE_TRACK, 0, repeat ? redbook_repeat_func : NULL))
@ -361,6 +358,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;
@ -388,13 +390,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);
@ -402,13 +400,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;
}
@ -419,7 +421,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;
}
@ -434,7 +436,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+1<=REDBOOK_FIRST_LEVEL_TRACK) ? 0 : (songnum % (n_tracks-REDBOOK_FIRST_LEVEL_TRACK+1)));
}
else
{
tracknum = Redbook_playing+offset;
@ -444,12 +451,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, n_tracks, redbook_first_song_func))
{
Song_playing = songnum;
Song_playing = songnum + SONG_FIRST_LEVEL_SONG;
Redbook_playing = tracknum;
}
}
@ -463,6 +470,9 @@ 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;
// As soon as we start a new level, go to next track
if (last_songnum != -1 && songnum != last_songnum)
@ -470,7 +480,7 @@ int songs_play_level_song( int levelnum, int offset )
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]);
}
@ -483,8 +493,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;
}

View file

@ -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-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
*/
/*
*
* Header for songs.c
@ -21,15 +7,10 @@ COPYRIGHT 1993-1999 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 );