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(void);
49 cvar_t Redbook_enabled = { "RedbookEnabled", "1", CVAR_ARCHIVE };
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(void);
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);
69 void songs_close(void)
71 Songs_initialized = 0;
81 if ( Songs_initialized ) return;
84 if (!FindArg("-nomixer"))
85 CD_blast_mixer(); // Crank it!
88 if (cfexist("descent.sng")) { // mac (demo?) datafiles don't have the .sng file
89 fp = cfopen( "descent.sng", "rb" );
91 Error( "Couldn't open descent.sng" );
93 while (cfgets(inputline, 80, fp ))
95 if ( strlen( inputline ) )
97 Assert( i < MAX_NUM_SONGS );
98 sscanf( inputline, "%s %s %s",
100 Songs[i].melodic_bank_file,
101 Songs[i].drum_bank_file );
102 //printf( "%d. '%s' '%s' '%s'\n",i,Songs[i].filename,Songs[i].melodic_bank_file,Songs[i].drum_bank_file );
107 if (Num_songs <= SONG_FIRST_LEVEL_SONG)
108 Error("Must have at least %d songs",SONG_FIRST_LEVEL_SONG+1);
112 Songs_initialized = 1;
115 if (FindArg("-noredbook"))
116 cvar_setint( &Redbook_enabled, 0 );
117 else { // use redbook
121 set_redbook_volume(Config_redbook_volume.intval);
125 atexit(RBAStop); // stop song on exit
129 #define FADE_TIME (f1_0/2)
131 // stop the redbook, so we can read off the CD
132 void songs_stop_redbook(void)
134 int old_volume = Config_redbook_volume.intval * REDBOOK_VOLUME_SCALE / 8;
135 fix old_time = timer_get_fixed_seconds();
137 if (Redbook_playing) { // fade out volume
140 fix t = timer_get_fixed_seconds();
142 new_volume = fixmuldiv(old_volume, (FADE_TIME - (t-old_time)), FADE_TIME);
147 RBASetVolume(new_volume);
149 } while (new_volume > 0);
152 RBAStop(); // Stop CD, if playing
154 RBASetVolume(old_volume); // restore volume
161 // stop any songs - midi or redbook - that are currently playing
162 void songs_stop_all(void)
164 digi_stop_current_song(); // Stop midi song, if playing
166 songs_stop_redbook(); // Stop CD, if playing
170 int force_rb_register = 0;
172 void reinit_redbook()
177 set_redbook_volume(Config_redbook_volume.intval);
179 force_rb_register = 0;
184 // returns 1 if track started sucessfully
185 // start at tracknum. if keep_playing set, play to end of disc. else
186 // play only specified track
187 int play_redbook_track(int tracknum,int keep_playing)
191 if (!RBAEnabled() && Redbook_enabled.intval && !FindArg("-noredbook"))
194 if (force_rb_register) {
195 RBARegisterCD(); // get new track list for new CD
196 force_rb_register = 0;
199 if (Redbook_enabled.intval && RBAEnabled()) {
200 int num_tracks = RBAGetNumberOfTracks();
201 if (tracknum <= num_tracks)
202 if (RBAPlayTracks(tracknum, keep_playing?num_tracks:tracknum)) {
203 Redbook_playing = tracknum;
207 return (Redbook_playing != 0);
211 /* Redbook versions of 13 songs from Descent 1 as found on the Macintosh version.
212 All the same tracklist, but some versions have tracks mixed to different lengths
216 4: The Escape (aka Close Call)
217 5: Ether in the Air (aka The Darkness of Space)
218 6: Robotic Menace (aka Get It On)
219 7: Virtual Tension (aka Fight)
220 8: Time for the Big Guns (aka Death Lurks Beneath)
221 9: Mystery Metal (aka C-4 Home Recipe)
222 10: Hydraulic Pressure (aka Escape)
223 11: Not That Button! (aka Backwards Time)
224 12: Industrial Accident (aka Crazyfactory)
225 13: Overdrive (aka Machine Gun)
226 14: A Big Problem (aka Insanity)
228 #define D1_DISCID_1 0xb60d990e
229 #define D1_DISCID_2 0xde0feb0e
230 #define D1_DISCID_3 0xb70ee40e
232 #define D1_RB_TITLE 2
233 #define D1_RB_BRIEFING 3
234 #define D1_RB_ENDLEVEL 4
235 #define D1_RB_ENDGAME 3
236 #define D1_RB_CREDITS 5
237 #define D1_RB_FIRST_LEVEL_SONG 6
249 10: Haunted (Instrumental Remix)
254 #define D2_DISCID_1 0x22115710 // Mac version, has some extended versions and 3 bonus tracks
255 #define D2_DISCID_2 0xac0bc30d
256 #define D2_DISCID_3 0xc40c0a0d
257 #define D2_DISCID_4 0xc610080d
258 #define D2_DISCID_5 0xcc101b0d
259 #define D2_DISCID_6 0xd00bf30d
260 #define D2_DISCID_7 0xd2101d0d
261 #define D2_DISCID_8 0xd410070d
262 #define D2_DISCID_9 0xda10370d
264 #define D2_RB_TITLE 2
265 #define D2_RB_CREDITS 3
266 #define D2_RB_FIRST_LEVEL_SONG 4
268 /* Same as above, but all tracks shifted by one
279 11: Haunted (Instrumental Remix)
284 #define D2_2_DISCID_1 0xe010a30e
286 #define D2_2_RB_TITLE 3
287 #define D2_2_RB_CREDITS 4
288 #define D2_2_RB_FIRST_LEVEL_SONG 5
290 /* Descent II: The Infinite Abyss
293 3: Cold Reality - Extended Remix
294 4: Crawl - Extended Remix
295 5: Gunner Down - Extended Remix
296 6: Ratzez - Extended Remix
297 7: Techno Industry - Extended Remix
298 8: Are You Descent? - Extended Remix
299 9: Robot Jungle - Extended Remix
301 #define D2_IA_DISCID_1 0x7d0ff809
302 #define D2_IA_DISCID_2 0x8110ec09
303 #define D2_IA_DISCID_3 0x82104909
304 #define D2_IA_DISCID_4 0x85101d09
305 #define D2_IA_DISCID_5 0x87102209
307 #define D2_IA_RB_TITLE 2
308 #define D2_IA_RB_CREDITS 3
309 #define D2_IA_RB_FIRST_LEVEL_SONG 4
311 /* Descent II: Vertigo Series
313 2: Crush - Extended Remix
314 3: Glut - Extended Remix
315 4: Haunted - Instrumental Re-Remix
317 6: Untitled - Extended Remix
321 #define D2_X_DISCID_1 0x53078208
322 #define D2_X_DISCID_2 0x64071408
324 #define D2_X_RB_FIRST_LEVEL_SONG 2
327 static inline int REDBOOK(int songnum)
331 if (!Redbook_enabled.intval)
334 discid = RBAGetDiscID();
341 case SONG_TITLE: return D1_RB_TITLE;
342 case SONG_BRIEFING: return D1_RB_BRIEFING;
343 case SONG_ENDLEVEL: return D1_RB_ENDLEVEL;
344 case SONG_ENDGAME: return D1_RB_ENDGAME;
345 case SONG_CREDITS: return D1_RB_CREDITS;
346 case SONG_FIRST_LEVEL_SONG: return D1_RB_FIRST_LEVEL_SONG;
347 default: Int3(); break;
359 case SONG_TITLE: return D2_RB_TITLE;
360 case SONG_CREDITS: return D2_RB_CREDITS;
361 case SONG_FIRST_LEVEL_SONG: return D2_RB_FIRST_LEVEL_SONG;
362 default: Int3(); break;
366 case SONG_TITLE: return D2_2_RB_TITLE;
367 case SONG_CREDITS: return D2_2_RB_CREDITS;
368 case SONG_FIRST_LEVEL_SONG: return D2_2_RB_FIRST_LEVEL_SONG;
369 default: Int3(); break;
377 case SONG_TITLE: return D2_IA_RB_TITLE;
378 case SONG_CREDITS: return D2_IA_RB_CREDITS;
379 case SONG_FIRST_LEVEL_SONG: return D2_IA_RB_FIRST_LEVEL_SONG;
380 default: Int3(); break;
384 return D2_X_RB_FIRST_LEVEL_SONG;
387 con_printf(CON_DEBUG, "Unknown CD. discid: %x\n", discid);
394 void songs_play_song( int songnum, int repeat )
396 if ( !Songs_initialized )
399 // stop any music already playing
402 // do we want any of these to be redbook songs?
403 if (force_rb_register) {
404 RBARegisterCD(); // get new track list for new CD
405 force_rb_register = 0;
408 play_redbook_track(REDBOOK(songnum), 0);
410 if (!Redbook_playing) // not playing redbook, so play midi
411 digi_play_midi_song( Songs[songnum].filename, Songs[songnum].melodic_bank_file, Songs[songnum].drum_bank_file, repeat );
415 int current_song_level;
417 void songs_play_level_song( int levelnum )
422 Assert( levelnum != 0 );
424 if ( !Songs_initialized )
429 current_song_level = levelnum;
431 songnum = (levelnum > 0)?(levelnum - 1):(-levelnum);
433 if (!RBAEnabled() && Redbook_enabled.intval && !FindArg("-noredbook"))
436 if (force_rb_register) {
437 RBARegisterCD(); // get new track list for new CD
438 force_rb_register = 0;
441 if (Redbook_enabled.intval && RBAEnabled() && (n_tracks = RBAGetNumberOfTracks()) > 1) {
443 // try to play redbook
445 mprintf((0,"n_tracks = %d\n",n_tracks));
447 play_redbook_track(REDBOOK(SONG_FIRST_LEVEL_SONG) + (songnum % (n_tracks - REDBOOK(SONG_FIRST_LEVEL_SONG) + 1)), 1);
450 if (! Redbook_playing) { // not playing redbook, so play midi
452 songnum = SONG_FIRST_LEVEL_SONG + (songnum % NumLevelSongs);
454 digi_play_midi_song( Songs[songnum].filename, Songs[songnum].melodic_bank_file, Songs[songnum].drum_bank_file, 1 );
460 // this should be called regularly to check for redbook restart
461 void songs_check_redbook_repeat()
463 static fix last_check_time;
466 if (!Redbook_playing || Config_redbook_volume.intval==0) return;
468 current_time = timer_get_fixed_seconds();
469 if (current_time < last_check_time || (current_time - last_check_time) >= F2_0) {
470 if (!RBAPeekPlayStatus()) {
472 // if title ends, start credit music
473 // if credits music ends, restart it
474 if (Redbook_playing == REDBOOK(SONG_TITLE) || Redbook_playing == REDBOOK(SONG_CREDITS))
475 play_redbook_track(REDBOOK(SONG_CREDITS), 0);
477 //songs_goto_next_song();
479 // new code plays all tracks to end of disk, so if disk has
480 // stopped we must be at end. So start again with level 1 song.
482 songs_play_level_song(1);
486 last_check_time = current_time;
491 // goto the next level song
492 void songs_goto_next_song()
494 if (Redbook_playing) // get correct track
495 current_song_level = RBAGetTrackNum() - REDBOOK(SONG_FIRST_LEVEL_SONG) + 1;
497 songs_play_level_song(current_song_level + 1);
501 // goto the previous level song
502 void songs_goto_prev_song()
504 if (Redbook_playing) // get correct track
505 current_song_level = RBAGetTrackNum() - REDBOOK(SONG_FIRST_LEVEL_SONG) + 1;
507 if (current_song_level > 1)
508 songs_play_level_song(current_song_level - 1);