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)
42 song_info Songs[MAX_NUM_SONGS];
43 int Songs_initialized = 0;
47 extern void digi_stop_current_song();
49 cvar_t Redbook_enabled = { "RedbookEnabled", "1", 1 };
51 //0 if redbook is no playing, else the track number
52 int Redbook_playing = 0;
54 #define NumLevelSongs (Num_songs - SONG_FIRST_LEVEL_SONG)
56 extern int CD_blast_mixer();
58 #define REDBOOK_VOLUME_SCALE (255/3) // 255 is MAX
61 //takes volume in range 0..8
62 void set_redbook_volume(int volume)
65 RBASetVolume(volume * REDBOOK_VOLUME_SCALE / 8);
75 if ( Songs_initialized ) return;
78 if (!FindArg("-nomixer"))
79 CD_blast_mixer(); // Crank it!
82 if (cfexist("descent.sng")) { // mac (demo?) datafiles don't have the .sng file
83 fp = cfopen( "descent.sng", "rb" );
85 Error( "Couldn't open descent.sng" );
87 while (cfgets(inputline, 80, fp ))
89 if ( strlen( inputline ) )
91 Assert( i < MAX_NUM_SONGS );
92 sscanf( inputline, "%s %s %s",
94 Songs[i].melodic_bank_file,
95 Songs[i].drum_bank_file );
96 //printf( "%d. '%s' '%s' '%s'\n",i,Songs[i].filename,Songs[i].melodic_bank_file,Songs[i].drum_bank_file );
101 if (Num_songs <= SONG_FIRST_LEVEL_SONG)
102 Error("Must have at least %d songs",SONG_FIRST_LEVEL_SONG+1);
106 Songs_initialized = 1;
109 if (FindArg("-noredbook"))
110 cvar_setint( &Redbook_enabled, 0 );
111 else { // use redbook
115 set_redbook_volume(Config_redbook_volume.intval);
119 atexit(RBAStop); // stop song on exit
123 #define FADE_TIME (f1_0/2)
125 // stop the redbook, so we can read off the CD
126 void songs_stop_redbook(void)
128 int old_volume = Config_redbook_volume.intval * REDBOOK_VOLUME_SCALE / 8;
129 fix old_time = timer_get_fixed_seconds();
131 if (Redbook_playing) { // fade out volume
134 fix t = timer_get_fixed_seconds();
136 new_volume = fixmuldiv(old_volume, (FADE_TIME - (t-old_time)), FADE_TIME);
141 RBASetVolume(new_volume);
143 } while (new_volume > 0);
146 RBAStop(); // Stop CD, if playing
148 RBASetVolume(old_volume); // restore volume
155 // stop any songs - midi or redbook - that are currently playing
156 void songs_stop_all(void)
158 digi_stop_current_song(); // Stop midi song, if playing
160 songs_stop_redbook(); // Stop CD, if playing
164 int force_rb_register = 0;
166 void reinit_redbook()
171 set_redbook_volume(Config_redbook_volume.intval);
173 force_rb_register = 0;
178 // returns 1 if track started sucessfully
179 // start at tracknum. if keep_playing set, play to end of disc. else
180 // play only specified track
181 int play_redbook_track(int tracknum,int keep_playing)
185 if (!RBAEnabled() && Redbook_enabled.intval && !FindArg("-noredbook"))
188 if (force_rb_register) {
189 RBARegisterCD(); // get new track list for new CD
190 force_rb_register = 0;
193 if (Redbook_enabled.intval && RBAEnabled()) {
194 int num_tracks = RBAGetNumberOfTracks();
195 if (tracknum <= num_tracks)
196 if (RBAPlayTracks(tracknum, keep_playing?num_tracks:tracknum)) {
197 Redbook_playing = tracknum;
201 return (Redbook_playing != 0);
205 /* Redbook versions of 13 songs from Descent 1 as found on the Macintosh version.
206 All the same tracklist, but some versions have tracks mixed to different lengths
210 4: The Escape (aka Close Call)
211 5: Ether in the Air (aka The Darkness of Space)
212 6: Robotic Menace (aka Get It On)
213 7: Virtual Tension (aka Fight)
214 8: Time for the Big Guns (aka Death Lurks Beneath)
215 9: Mystery Metal (aka C-4 Home Recipe)
216 10: Hydraulic Pressure (aka Escape)
217 11: Not That Button! (aka Backwards Time)
218 12: Industrial Accident (aka Crazyfactory)
219 13: Overdrive (aka Machine Gun)
220 14: A Big Problem (aka Insanity)
222 #define D1_DISCID_1 0xb60d990e
223 #define D1_DISCID_2 0xde0feb0e
224 #define D1_DISCID_3 0xb70ee40e
226 #define D1_RB_TITLE 2
227 #define D1_RB_BRIEFING 3
228 #define D1_RB_ENDLEVEL 4
229 #define D1_RB_ENDGAME 3
230 #define D1_RB_CREDITS 5
231 #define D1_RB_FIRST_LEVEL_SONG 6
243 10: Haunted (Instrumental Remix)
248 #define D2_DISCID_1 0x22115710 // Mac version, has some extended versions and 3 bonus tracks
249 #define D2_DISCID_2 0xac0bc30d
250 #define D2_DISCID_3 0xc40c0a0d
251 #define D2_DISCID_4 0xc610080d
252 #define D2_DISCID_5 0xcc101b0d
253 #define D2_DISCID_6 0xd00bf30d
254 #define D2_DISCID_7 0xd2101d0d
255 #define D2_DISCID_8 0xd410070d
256 #define D2_DISCID_9 0xda10370d
258 #define D2_RB_TITLE 2
259 #define D2_RB_CREDITS 3
260 #define D2_RB_FIRST_LEVEL_SONG 4
262 /* Same as above, but all tracks shifted by one
273 11: Haunted (Instrumental Remix)
278 #define D2_2_DISCID_1 0xe010a30e
280 #define D2_2_RB_TITLE 3
281 #define D2_2_RB_CREDITS 4
282 #define D2_2_RB_FIRST_LEVEL_SONG 5
284 /* Descent II: The Infinite Abyss
287 3: Cold Reality - Extended Remix
288 4: Crawl - Extended Remix
289 5: Gunner Down - Extended Remix
290 6: Ratzez - Extended Remix
291 7: Techno Industry - Extended Remix
292 8: Are You Descent? - Extended Remix
293 9: Robot Jungle - Extended Remix
295 #define D2_IA_DISCID_1 0x7d0ff809
296 #define D2_IA_DISCID_2 0x8110ec09
297 #define D2_IA_DISCID_3 0x82104909
298 #define D2_IA_DISCID_4 0x85101d09
299 #define D2_IA_DISCID_5 0x87102209
301 #define D2_IA_RB_TITLE 2
302 #define D2_IA_RB_CREDITS 3
303 #define D2_IA_RB_FIRST_LEVEL_SONG 4
305 /* Descent II: Vertigo Series
307 2: Crush - Extended Remix
308 3: Glut - Extended Remix
309 4: Haunted - Instrumental Re-Remix
311 6: Untitled - Extended Remix
315 #define D2_X_DISCID_1 0x53078208
316 #define D2_X_DISCID_2 0x64071408
318 #define D2_X_RB_FIRST_LEVEL_SONG 2
321 int songs_redbook_track(int songnum)
325 if (!Redbook_enabled.intval)
328 discid = RBAGetDiscID();
335 case SONG_TITLE: return D1_RB_TITLE;
336 case SONG_BRIEFING: return D1_RB_BRIEFING;
337 case SONG_ENDLEVEL: return D1_RB_ENDLEVEL;
338 case SONG_ENDGAME: return D1_RB_ENDGAME;
339 case SONG_CREDITS: return D1_RB_CREDITS;
340 case SONG_FIRST_LEVEL_SONG: return D1_RB_FIRST_LEVEL_SONG;
341 default: Int3(); break;
353 case SONG_TITLE: return D2_RB_TITLE;
354 case SONG_CREDITS: return D2_RB_CREDITS;
355 case SONG_FIRST_LEVEL_SONG: return D2_RB_FIRST_LEVEL_SONG;
356 default: Int3(); break;
360 case SONG_TITLE: return D2_2_RB_TITLE;
361 case SONG_CREDITS: return D2_2_RB_CREDITS;
362 case SONG_FIRST_LEVEL_SONG: return D2_2_RB_FIRST_LEVEL_SONG;
363 default: Int3(); break;
371 case SONG_TITLE: return D2_IA_RB_TITLE;
372 case SONG_CREDITS: return D2_IA_RB_CREDITS;
373 case SONG_FIRST_LEVEL_SONG: return D2_IA_RB_FIRST_LEVEL_SONG;
374 default: Int3(); break;
378 return D2_X_RB_FIRST_LEVEL_SONG;
381 con_printf(CON_DEBUG, "Unknown CD. discid: %x\n", discid);
388 #define REDBOOK_TITLE_TRACK (songs_redbook_track(SONG_TITLE))
389 #define REDBOOK_CREDITS_TRACK (songs_redbook_track(SONG_CREDITS))
390 #define REDBOOK_FIRST_LEVEL_TRACK (songs_redbook_track(SONG_FIRST_LEVEL_SONG))
393 void songs_play_song( int songnum, int repeat )
396 //Assert(songnum != SONG_ENDLEVEL && songnum != SONG_ENDGAME);// not in full version
399 if ( !Songs_initialized )
402 // stop any music already playing
405 // do we want any of these to be redbook songs?
406 if (force_rb_register) {
407 RBARegisterCD(); // get new track list for new CD
408 force_rb_register = 0;
411 if (songnum == SONG_TITLE)
412 play_redbook_track(REDBOOK_TITLE_TRACK, 0);
413 else if (songnum == SONG_CREDITS)
414 play_redbook_track(REDBOOK_CREDITS_TRACK, 0);
416 if (!Redbook_playing) // not playing redbook, so play midi
417 digi_play_midi_song( Songs[songnum].filename, Songs[songnum].melodic_bank_file, Songs[songnum].drum_bank_file, repeat );
421 int current_song_level;
423 void songs_play_level_song( int levelnum )
428 Assert( levelnum != 0 );
430 if ( !Songs_initialized )
435 current_song_level = levelnum;
437 songnum = (levelnum > 0)?(levelnum - 1):(-levelnum);
439 if (!RBAEnabled() && Redbook_enabled.intval && !FindArg("-noredbook"))
442 if (force_rb_register) {
443 RBARegisterCD(); // get new track list for new CD
444 force_rb_register = 0;
447 if (Redbook_enabled.intval && RBAEnabled() && (n_tracks = RBAGetNumberOfTracks()) > 1) {
449 // try to play redbook
451 mprintf((0,"n_tracks = %d\n",n_tracks));
453 play_redbook_track(REDBOOK_FIRST_LEVEL_TRACK + (songnum % (n_tracks-REDBOOK_FIRST_LEVEL_TRACK+1)), 1);
456 if (! Redbook_playing) { // not playing redbook, so play midi
458 songnum = SONG_FIRST_LEVEL_SONG + (songnum % NumLevelSongs);
460 digi_play_midi_song( Songs[songnum].filename, Songs[songnum].melodic_bank_file, Songs[songnum].drum_bank_file, 1 );
466 // this should be called regularly to check for redbook restart
467 void songs_check_redbook_repeat()
469 static fix last_check_time;
472 if (!Redbook_playing || Config_redbook_volume.intval==0) return;
474 current_time = timer_get_fixed_seconds();
475 if (current_time < last_check_time || (current_time - last_check_time) >= F2_0) {
476 if (!RBAPeekPlayStatus()) {
478 // if title ends, start credit music
479 // if credits music ends, restart it
480 if (Redbook_playing == REDBOOK_TITLE_TRACK || Redbook_playing == REDBOOK_CREDITS_TRACK)
481 play_redbook_track(REDBOOK_CREDITS_TRACK,0);
483 //songs_goto_next_song();
485 // new code plays all tracks to end of disk, so if disk has
486 // stopped we must be at end. So start again with level 1 song.
488 songs_play_level_song(1);
492 last_check_time = current_time;
497 // goto the next level song
498 void songs_goto_next_song()
500 if (Redbook_playing) // get correct track
501 current_song_level = RBAGetTrackNum() - REDBOOK_FIRST_LEVEL_TRACK + 1;
503 songs_play_level_song(current_song_level + 1);
507 // goto the previous level song
508 void songs_goto_prev_song()
510 if (Redbook_playing) // get correct track
511 current_song_level = RBAGetTrackNum() - REDBOOK_FIRST_LEVEL_TRACK + 1;
513 if (current_song_level > 1)
514 songs_play_level_song(current_song_level - 1);