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 98cf9b90ca
commit f0edc54479
7 changed files with 94 additions and 139 deletions

View file

@ -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

View file

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

View file

@ -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

View file

@ -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
}

View file

@ -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<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-1998 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,95 +85,79 @@ 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++;
}
}
// 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;
}

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-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 );