1 /* $Id: songs.c,v 1.10 2003-11-26 12:26:33 btb Exp $ */
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
17 * Routines to manage the songs in Descent.
20 * Revision 1.5 1995/11/03 12:52:59 allender
23 * Revision 1.4 1995/10/18 01:51:33 allender
24 * fixed up stuff for redbook
26 * Revision 1.3 1995/10/17 13:13:44 allender
27 * dont' add resource value to songs to play -- now done in digi
30 * Revision 1.2 1995/07/17 08:50:35 allender
31 * make work with new music system
33 * Revision 1.1 1995/05/16 15:31:05 allender
36 * Revision 2.1 1995/05/02 16:15:21 john
39 * Revision 2.0 1995/02/27 11:27:13 john
40 * New version 2.0, which has no anonymous unions, builds with
41 * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
43 * Revision 1.2 1995/02/11 12:42:12 john
44 * Added new song method, with FM bank switching..
46 * Revision 1.1 1995/02/11 10:20:33 john
77 song_info Songs[MAX_NUM_SONGS];
78 int Songs_initialized = 0;
84 extern void digi_stop_current_song();
86 int Redbook_enabled = 1;
88 //0 if redbook is no playing, else the track number
89 int Redbook_playing = 0;
91 #define NumLevelSongs (Num_songs - SONG_FIRST_LEVEL_SONG)
93 extern int CD_blast_mixer();
96 #define REDBOOK_VOLUME_SCALE (255/3) //255 is MAX
98 #define REDBOOK_VOLUME_SCALE (255)
101 //takes volume in range 0..8
102 void set_redbook_volume(int volume)
105 RBASetVolume(0); // makes the macs sound really funny
107 RBASetVolume(volume*REDBOOK_VOLUME_SCALE/8);
110 extern char CDROM_dir[];
115 char inputline[80+1];
118 if ( Songs_initialized ) return;
121 #if !defined(MACINTOSH) && !defined(WINDOWS) // don't crank it if on a macintosh!!!!!
122 if (!FindArg("-nomixer"))
123 CD_blast_mixer(); // Crank it!
127 if (cfexist("descent.sng")) { // mac (demo?) datafiles don't have the .sng file
128 fp = cfopen( "descent.sng", "rb" );
131 Error( "Couldn't open descent.sng" );
134 while (cfgets(inputline, 80, fp ))
136 char *p = strchr(inputline,'\n');
138 if ( strlen( inputline ) )
140 Assert( i < MAX_NUM_SONGS );
141 sscanf( inputline, "%s %s %s",
143 Songs[i].melodic_bank_file,
144 Songs[i].drum_bank_file );
145 //printf( "%d. '%s' '%s' '%s'\n",i,Songs[i].filename,Songs[i].melodic_bank_file,Songs[i].drum_bank_file );
150 if (Num_songs <= SONG_FIRST_LEVEL_SONG)
151 Error("Must have at least %d songs",SONG_FIRST_LEVEL_SONG+1);
155 Songs_initialized = 1;
158 #if !defined(SHAREWARE) || ( defined(SHAREWARE) && defined(APPLE_DEMO) )
159 if (FindArg("-noredbook"))
165 #ifndef __MSDOS__ // defined(WINDOWS) || defined(MACINTOSH)
168 RBAInit(toupper(CDROM_dir[0]) - 'A');
173 set_redbook_volume(Config_redbook_volume);
177 //atexit(RBAStop); // stop song on exit
178 #endif // endof ifndef SHAREWARE, ie ifdef SHAREWARE
181 #define FADE_TIME (f1_0/2)
183 //stop the redbook, so we can read off the CD
184 void songs_stop_redbook(void)
186 int old_volume = Config_redbook_volume*REDBOOK_VOLUME_SCALE/8;
187 fix old_time = timer_get_fixed_seconds();
189 if (Redbook_playing) { //fade out volume
192 fix t = timer_get_fixed_seconds();
194 new_volume = fixmuldiv(old_volume,(FADE_TIME - (t-old_time)),FADE_TIME);
199 RBASetVolume(new_volume);
201 } while (new_volume > 0);
204 //RBAStop(); // Stop CD, if playing
206 RBASetVolume(old_volume); //restore volume
212 //stop any songs - midi or redbook - that are currently playing
213 void songs_stop_all(void)
215 digi_stop_current_song(); // Stop midi song, if playing
217 songs_stop_redbook(); // Stop CD, if playing
220 int force_rb_register=0;
222 void reinit_redbook()
224 #ifndef __MSDOS__ // defined(WINDOWS) || defined(MACINTOSH)
227 RBAInit(toupper(CDROM_dir[0]) - 'A');
232 set_redbook_volume(Config_redbook_volume);
239 //returns 1 if track started sucessfully
240 //start at tracknum. if keep_playing set, play to end of disc. else
241 //play only specified track
242 int play_redbook_track(int tracknum,int keep_playing)
246 if (!RBAEnabled() && Redbook_enabled && !FindArg("-noredbook"))
249 if (force_rb_register) {
250 RBARegisterCD(); //get new track list for new CD
251 force_rb_register = 0;
254 if (Redbook_enabled && RBAEnabled()) {
255 int num_tracks = RBAGetNumberOfTracks();
256 if (tracknum <= num_tracks)
257 if (RBAPlayTracks(tracknum,keep_playing?num_tracks:tracknum)) {
258 Redbook_playing = tracknum;
262 return (Redbook_playing != 0);
266 * Some of these have different Track listings!
267 * Which one is the "correct" order?
269 #define D2_1_DISCID 0x7d0ff809 // Descent II
270 #define D2_2_DISCID 0xe010a30e // Descent II
271 #define D2_3_DISCID 0xd410070d // Descent II
272 #define D2_4_DISCID 0xc610080d // Descent II
273 #define D2_DEF_DISCID 0x87102209 // Definitive collection Disc 2
274 #define D2_OEM_DISCID 0xac0bc30d // Destination: Quartzon
275 #define D2_OEM2_DISCID 0xc40c0a0d // Destination: Quartzon
276 #define D2_VERTIGO_DISCID 0x53078208 // Vertigo
277 #define D2_VERTIGO2_DISCID 0x64071408 // Vertigo + DMB
278 #define D2_MAC_DISCID 0xb70ee40e // Macintosh
279 #define D2_IPLAY_DISCID 0x22115710 // iPlay for Macintosh
281 #define REDBOOK_TITLE_TRACK 2
282 #define REDBOOK_CREDITS_TRACK 3
283 #define REDBOOK_FIRST_LEVEL_TRACK (songs_haved2_cd()?4:1)
285 // songs_haved2_cd returns 1 if the descent 2 CD is in the drive and
289 int songs_haved2_cd()
293 if (!Redbook_enabled)
296 discid = RBAGetDiscID();
306 case D2_VERTIGO_DISCID:
307 case D2_VERTIGO2_DISCID:
309 case D2_IPLAY_DISCID:
310 printf("Found D2 CD! discid: %x\n", discid);
313 printf("Unknown CD! discid: %x\n", discid);
318 int songs_haved2_cd()
320 char temp[128],cwd[128];
324 strcpy(temp,CDROM_dir);
326 #ifndef MACINTOSH //for PC, strip of trailing slash
327 if (temp[strlen(temp)-1] == '\\')
328 temp[strlen(temp)-1] = 0;
331 if ( !chdir(temp) ) {
341 void songs_play_song( int songnum, int repeat )
344 //Assert(songnum != SONG_ENDLEVEL && songnum != SONG_ENDGAME); //not in full version
347 if ( !Songs_initialized )
350 //stop any music already playing
354 //do we want any of these to be redbook songs?
356 if (force_rb_register) {
357 RBARegisterCD(); //get new track list for new CD
358 force_rb_register = 0;
361 if (songnum == SONG_TITLE)
362 play_redbook_track(REDBOOK_TITLE_TRACK,0);
363 else if (songnum == SONG_CREDITS)
364 play_redbook_track(REDBOOK_CREDITS_TRACK,0);
366 if (!Redbook_playing) { //not playing redbook, so play midi
369 digi_play_midi_song( Songs[songnum].filename, Songs[songnum].melodic_bank_file, Songs[songnum].drum_bank_file, repeat );
371 digi_play_midi_song(songnum, repeat);
376 int current_song_level;
378 void songs_play_level_song( int levelnum )
383 Assert( levelnum != 0 );
385 if ( !Songs_initialized )
390 current_song_level = levelnum;
392 songnum = (levelnum>0)?(levelnum-1):(-levelnum);
394 if (!RBAEnabled() && Redbook_enabled && !FindArg("-noredbook"))
397 if (force_rb_register) {
398 RBARegisterCD(); //get new track list for new CD
399 force_rb_register = 0;
402 if (Redbook_enabled && RBAEnabled() && (n_tracks = RBAGetNumberOfTracks()) > 1) {
404 //try to play redbook
406 mprintf((0,"n_tracks = %d\n",n_tracks));
408 play_redbook_track(REDBOOK_FIRST_LEVEL_TRACK + (songnum % (n_tracks-REDBOOK_FIRST_LEVEL_TRACK+1)),1);
411 if (! Redbook_playing) { //not playing redbook, so play midi
413 songnum = SONG_FIRST_LEVEL_SONG + (songnum % NumLevelSongs);
416 digi_play_midi_song( Songs[songnum].filename, Songs[songnum].melodic_bank_file, Songs[songnum].drum_bank_file, 1 );
418 digi_play_midi_song( songnum, 1 );
424 //this should be called regularly to check for redbook restart
425 void songs_check_redbook_repeat()
427 static fix last_check_time;
430 if (!Redbook_playing || Config_redbook_volume==0) return;
432 current_time = timer_get_fixed_seconds();
433 if (current_time < last_check_time || (current_time - last_check_time) >= F2_0) {
434 if (!RBAPeekPlayStatus()) {
436 // if title ends, start credit music
437 // if credits music ends, restart it
438 if (Redbook_playing == REDBOOK_TITLE_TRACK || Redbook_playing == REDBOOK_CREDITS_TRACK)
439 play_redbook_track(REDBOOK_CREDITS_TRACK,0);
441 //songs_goto_next_song();
443 //new code plays all tracks to end of disk, so if disk has
444 //stopped we must be at end. So start again with level 1 song.
446 songs_play_level_song(1);
450 last_check_time = current_time;
454 //goto the next level song
455 void songs_goto_next_song()
457 if (Redbook_playing) //get correct track
458 current_song_level = RBAGetTrackNum() - REDBOOK_FIRST_LEVEL_TRACK + 1;
460 songs_play_level_song(current_song_level+1);
464 //goto the previous level song
465 void songs_goto_prev_song()
467 if (Redbook_playing) //get correct track
468 current_song_level = RBAGetTrackNum() - REDBOOK_FIRST_LEVEL_TRACK + 1;
470 if (current_song_level > 1)
471 songs_play_level_song(current_song_level-1);