2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
16 * Routines to manage the songs in Descent.
29 #if !defined(_MSC_VER) && !defined(macintosh)
45 song_info Songs[MAX_NUM_SONGS];
46 int Songs_initialized = 0;
52 extern void digi_stop_current_song();
54 cvar_t Redbook_enabled = { "RedbookEnabled", "1", 1 };
56 //0 if redbook is no playing, else the track number
57 int Redbook_playing = 0;
59 #define NumLevelSongs (Num_songs - SONG_FIRST_LEVEL_SONG)
61 extern int CD_blast_mixer();
64 #define REDBOOK_VOLUME_SCALE (255/3) //255 is MAX
66 #define REDBOOK_VOLUME_SCALE (255)
69 //takes volume in range 0..8
70 void set_redbook_volume(int volume)
73 RBASetVolume(0); // makes the macs sound really funny
75 RBASetVolume(volume*REDBOOK_VOLUME_SCALE/8);
78 extern char CDROM_dir[];
86 if ( Songs_initialized ) return;
89 #if !defined(MACINTOSH) && !defined(WINDOWS) // don't crank it if on a macintosh!!!!!
90 if (!FindArg("-nomixer"))
91 CD_blast_mixer(); // Crank it!
95 if (cfexist("descent.sng")) { // mac (demo?) datafiles don't have the .sng file
96 fp = cfopen( "descent.sng", "rb" );
99 Error( "Couldn't open descent.sng" );
102 while (cfgets(inputline, 80, fp ))
104 if ( strlen( inputline ) )
106 Assert( i < MAX_NUM_SONGS );
107 sscanf( inputline, "%s %s %s",
109 Songs[i].melodic_bank_file,
110 Songs[i].drum_bank_file );
111 //printf( "%d. '%s' '%s' '%s'\n",i,Songs[i].filename,Songs[i].melodic_bank_file,Songs[i].drum_bank_file );
116 if (Num_songs <= SONG_FIRST_LEVEL_SONG)
117 Error("Must have at least %d songs",SONG_FIRST_LEVEL_SONG+1);
121 Songs_initialized = 1;
124 if (FindArg("-noredbook"))
126 cvar_setint( &Redbook_enabled, 0 );
130 #ifndef __MSDOS__ // defined(WINDOWS) || defined(MACINTOSH)
133 RBAInit(toupper(CDROM_dir[0]) - 'A');
138 set_redbook_volume(Config_redbook_volume.intval);
142 atexit(RBAStop); // stop song on exit
145 #define FADE_TIME (f1_0/2)
147 //stop the redbook, so we can read off the CD
148 void songs_stop_redbook(void)
150 int old_volume = Config_redbook_volume.intval * REDBOOK_VOLUME_SCALE / 8;
151 fix old_time = timer_get_fixed_seconds();
153 if (Redbook_playing) { //fade out volume
156 fix t = timer_get_fixed_seconds();
158 new_volume = fixmuldiv(old_volume,(FADE_TIME - (t-old_time)),FADE_TIME);
163 RBASetVolume(new_volume);
165 } while (new_volume > 0);
168 RBAStop(); // Stop CD, if playing
170 RBASetVolume(old_volume); //restore volume
176 //stop any songs - midi or redbook - that are currently playing
177 void songs_stop_all(void)
179 digi_stop_current_song(); // Stop midi song, if playing
181 songs_stop_redbook(); // Stop CD, if playing
184 int force_rb_register=0;
186 void reinit_redbook()
188 #ifndef __MSDOS__ // defined(WINDOWS) || defined(MACINTOSH)
191 RBAInit(toupper(CDROM_dir[0]) - 'A');
196 set_redbook_volume(Config_redbook_volume.intval);
203 //returns 1 if track started sucessfully
204 //start at tracknum. if keep_playing set, play to end of disc. else
205 //play only specified track
206 int play_redbook_track(int tracknum,int keep_playing)
210 if (!RBAEnabled() && Redbook_enabled.intval && !FindArg("-noredbook"))
213 if (force_rb_register) {
214 RBARegisterCD(); //get new track list for new CD
215 force_rb_register = 0;
218 if (Redbook_enabled.intval && RBAEnabled()) {
219 int num_tracks = RBAGetNumberOfTracks();
220 if (tracknum <= num_tracks)
221 if (RBAPlayTracks(tracknum,keep_playing?num_tracks:tracknum)) {
222 Redbook_playing = tracknum;
226 return (Redbook_playing != 0);
232 #define REDBOOK_TITLE_TRACK 2
233 #define REDBOOK_CREDITS_TRACK 3
234 #define REDBOOK_FIRST_LEVEL_TRACK (songs_haved2_cd()?4:1)
236 // songs_haved2_cd returns 1 if the descent 2 CD is in the drive and
238 int songs_haved2_cd()
240 char temp[128],cwd[128];
244 strcpy(temp,CDROM_dir);
246 #ifndef MACINTOSH //for PC, strip of trailing slash
247 if (temp[strlen(temp)-1] == '\\')
248 temp[strlen(temp)-1] = 0;
251 if ( !chdir(temp) ) {
262 /* Redbook versions of 13 songs from Descent 1 as found on the Macintosh version.
263 All the same tracklist, but some versions have tracks mixed to different lengths
267 4: The Escape (aka Close Call)
268 5: Ether in the Air (aka The Darkness of Space)
269 6: Robotic Menace (aka Get It On)
270 7: Virtual Tension (aka Fight)
271 8: Time for the Big Guns (aka Death Lurks Beneath)
272 9: Mystery Metal (aka C-4 Home Recipe)
273 10: Hydraulic Pressure (aka Escape)
274 11: Not That Button! (aka Backwards Time)
275 12: Industrial Accident (aka Crazyfactory)
276 13: Overdrive (aka Machine Gun)
277 14: A Big Problem (aka Insanity)
279 #define D1_DISCID_1 0xb60d990e
280 #define D1_DISCID_2 0xde0feb0e
281 #define D1_DISCID_3 0xb70ee40e
283 #define D1_RB_TITLE 2
284 #define D1_RB_BRIEFING 3
285 #define D1_RB_ENDLEVEL 4
286 #define D1_RB_ENDGAME 3
287 #define D1_RB_CREDITS 5
288 #define D1_RB_FIRST_LEVEL_SONG 6
300 10: Haunted (Instrumental Remix)
305 #define D2_DISCID_1 0x22115710 // Mac version, has some extended versions and 3 bonus tracks
306 #define D2_DISCID_2 0xac0bc30d
307 #define D2_DISCID_3 0xc40c0a0d
308 #define D2_DISCID_4 0xc610080d
309 #define D2_DISCID_5 0xcc101b0d
310 #define D2_DISCID_6 0xd00bf30d
311 #define D2_DISCID_7 0xd2101d0d
312 #define D2_DISCID_8 0xd410070d
313 #define D2_DISCID_9 0xda10370d
315 #define D2_RB_TITLE 2
316 #define D2_RB_CREDITS 3
317 #define D2_RB_FIRST_LEVEL_SONG 4
319 /* Same as above, but all tracks shifted by one
330 11: Haunted (Instrumental Remix)
335 #define D2_2_DISCID_1 0xe010a30e
337 #define D2_2_RB_TITLE 3
338 #define D2_2_RB_CREDITS 4
339 #define D2_2_RB_FIRST_LEVEL_SONG 5
341 /* Descent II: The Infinite Abyss
344 3: Cold Reality - Extended Remix
345 4: Crawl - Extended Remix
346 5: Gunner Down - Extended Remix
347 6: Ratzez - Extended Remix
348 7: Techno Industry - Extended Remix
349 8: Are You Descent? - Extended Remix
350 9: Robot Jungle - Extended Remix
352 #define D2_IA_DISCID_1 0x7d0ff809
353 #define D2_IA_DISCID_2 0x8110ec09
354 #define D2_IA_DISCID_3 0x82104909
355 #define D2_IA_DISCID_4 0x85101d09
356 #define D2_IA_DISCID_5 0x87102209
358 #define D2_IA_RB_TITLE 2
359 #define D2_IA_RB_CREDITS 3
360 #define D2_IA_RB_FIRST_LEVEL_SONG 4
362 /* Descent II: Vertigo Series
364 2: Crush - Extended Remix
365 3: Glut - Extended Remix
366 4: Haunted - Instrumental Re-Remix
368 6: Untitled - Extended Remix
372 #define D2_X_DISCID_1 0x53078208
373 #define D2_X_DISCID_2 0x64071408
375 #define D2_X_RB_FIRST_LEVEL_SONG 2
378 int songs_redbook_track(int songnum)
382 if (!Redbook_enabled.intval)
385 discid = RBAGetDiscID();
392 case SONG_TITLE: return D1_RB_TITLE;
393 case SONG_BRIEFING: return D1_RB_BRIEFING;
394 case SONG_ENDLEVEL: return D1_RB_ENDLEVEL;
395 case SONG_ENDGAME: return D1_RB_ENDGAME;
396 case SONG_CREDITS: return D1_RB_CREDITS;
397 case SONG_FIRST_LEVEL_SONG: return D1_RB_FIRST_LEVEL_SONG;
398 default: Int3(); break;
410 case SONG_TITLE: return D2_RB_TITLE;
411 case SONG_CREDITS: return D2_RB_CREDITS;
412 case SONG_FIRST_LEVEL_SONG: return D2_RB_FIRST_LEVEL_SONG;
413 default: Int3(); break;
417 case SONG_TITLE: return D2_2_RB_TITLE;
418 case SONG_CREDITS: return D2_2_RB_CREDITS;
419 case SONG_FIRST_LEVEL_SONG: return D2_2_RB_FIRST_LEVEL_SONG;
420 default: Int3(); break;
428 case SONG_TITLE: return D2_IA_RB_TITLE;
429 case SONG_CREDITS: return D2_IA_RB_CREDITS;
430 case SONG_FIRST_LEVEL_SONG: return D2_IA_RB_FIRST_LEVEL_SONG;
431 default: Int3(); break;
435 return D2_X_RB_FIRST_LEVEL_SONG;
438 con_printf(CON_DEBUG, "Unknown CD. discid: %x\n", discid);
444 #define REDBOOK_TITLE_TRACK (songs_redbook_track(SONG_TITLE))
445 #define REDBOOK_CREDITS_TRACK (songs_redbook_track(SONG_CREDITS))
446 #define REDBOOK_FIRST_LEVEL_TRACK (songs_redbook_track(SONG_FIRST_LEVEL_SONG))
451 void songs_play_song( int songnum, int repeat )
454 //Assert(songnum != SONG_ENDLEVEL && songnum != SONG_ENDGAME); //not in full version
457 if ( !Songs_initialized )
460 //stop any music already playing
464 //do we want any of these to be redbook songs?
466 if (force_rb_register) {
467 RBARegisterCD(); //get new track list for new CD
468 force_rb_register = 0;
471 if (songnum == SONG_TITLE)
472 play_redbook_track(REDBOOK_TITLE_TRACK,0);
473 else if (songnum == SONG_CREDITS)
474 play_redbook_track(REDBOOK_CREDITS_TRACK,0);
476 if (!Redbook_playing) { //not playing redbook, so play midi
479 digi_play_midi_song( Songs[songnum].filename, Songs[songnum].melodic_bank_file, Songs[songnum].drum_bank_file, repeat );
481 digi_play_midi_song(songnum, repeat);
486 int current_song_level;
488 void songs_play_level_song( int levelnum )
493 Assert( levelnum != 0 );
495 if ( !Songs_initialized )
500 current_song_level = levelnum;
502 songnum = (levelnum>0)?(levelnum-1):(-levelnum);
504 if (!RBAEnabled() && Redbook_enabled.intval && !FindArg("-noredbook"))
507 if (force_rb_register) {
508 RBARegisterCD(); //get new track list for new CD
509 force_rb_register = 0;
512 if (Redbook_enabled.intval && RBAEnabled() && (n_tracks = RBAGetNumberOfTracks()) > 1) {
514 //try to play redbook
516 mprintf((0,"n_tracks = %d\n",n_tracks));
518 play_redbook_track(REDBOOK_FIRST_LEVEL_TRACK + (songnum % (n_tracks-REDBOOK_FIRST_LEVEL_TRACK+1)),1);
521 if (! Redbook_playing) { //not playing redbook, so play midi
523 songnum = SONG_FIRST_LEVEL_SONG + (songnum % NumLevelSongs);
526 digi_play_midi_song( Songs[songnum].filename, Songs[songnum].melodic_bank_file, Songs[songnum].drum_bank_file, 1 );
528 digi_play_midi_song( songnum, 1 );
534 //this should be called regularly to check for redbook restart
535 void songs_check_redbook_repeat()
537 static fix last_check_time;
540 if (!Redbook_playing || Config_redbook_volume.intval==0) return;
542 current_time = timer_get_fixed_seconds();
543 if (current_time < last_check_time || (current_time - last_check_time) >= F2_0) {
544 if (!RBAPeekPlayStatus()) {
546 // if title ends, start credit music
547 // if credits music ends, restart it
548 if (Redbook_playing == REDBOOK_TITLE_TRACK || Redbook_playing == REDBOOK_CREDITS_TRACK)
549 play_redbook_track(REDBOOK_CREDITS_TRACK,0);
551 //songs_goto_next_song();
553 //new code plays all tracks to end of disk, so if disk has
554 //stopped we must be at end. So start again with level 1 song.
556 songs_play_level_song(1);
560 last_check_time = current_time;
564 //goto the next level song
565 void songs_goto_next_song()
567 if (Redbook_playing) //get correct track
568 current_song_level = RBAGetTrackNum() - REDBOOK_FIRST_LEVEL_TRACK + 1;
570 songs_play_level_song(current_song_level+1);
574 //goto the previous level song
575 void songs_goto_prev_song()
577 if (Redbook_playing) //get correct track
578 current_song_level = RBAGetTrackNum() - REDBOOK_FIRST_LEVEL_TRACK + 1;
580 if (current_song_level > 1)
581 songs_play_level_song(current_song_level-1);