1 /*
2
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 */
19 /*
20 * $Source: r:/prj/cit/src/RCS/musicai.c $
21 * $Revision: 1.124 $
22 * $Author: unknown $
23 * $Date: 1994/11/26 03:16:18 $
24 */
25
26 #define __MUSICAI_SRC
27
28 #include <string.h>
29 #include <stdlib.h>
30
31 #include "Shock.h"
32 #include "Prefs.h"
33
34 #include "musicai.h"
35 #include "MacTune.h"
36
37 #include "ai.h"
38 #include "faketime.h"
39 #include "map.h"
40 #include "mapflags.h"
41 #include "player.h"
42 #include "sfxlist.h"
43 #include "tickcount.h"
44 #include "tools.h"
45
46 #include "adlmidi.h"
47 #include "Xmi.h"
48
49 /*
50 #include <mainloop.h>
51 #include <_audio.h>
52 #include <_testing.h>
53 #include <objects.h>
54 #include <objcrit.h>
55 #include <texttool.h>
56 #include <otrip.h>
57 #include <diginode.h>
58 */
59 #ifdef AUDIOLOGS
60 #include "audiolog.h"
61 #endif
62
63 //#include <ail.h>
64
65 extern void grind_music_ai();
66
67 uchar music_card = TRUE, music_on = FALSE;
68
69 uchar track_table[NUM_SCORES][SUPERCHUNKS_PER_SCORE];
70 uchar transition_table[NUM_TRANSITIONS];
71 uchar layering_table[NUM_LAYERS][MAX_KEYS];
72 uchar key_table[NUM_LAYERABLE_SUPERCHUNKS][KEY_BAR_RESOLUTION];
73
74 char peril_bars = 0;
75
76 int new_theme = 0;
77 int new_x, new_y;
78 int old_bore;
79 short mai_override = 0;
80 uchar cyber_play = 255;
81
82 int layer_danger = 0;
83 int layer_success = 0;
84 int layer_transition = 0;
85 int transition_count = 0;
86 char tmode_time = 0;
87 int actual_score = 0;
88 uchar decon_count = 0;
89 uchar decon_time = 8;
90 uchar in_deconst = FALSE, old_deconst = FALSE;
91 uchar in_peril = FALSE;
92 uchar just_started = TRUE;
93 int score_playing = 0;
94 short curr_ramp_time, curr_ramp;
95 char curr_prioritize, curr_crossfade;
96
97 void musicai_clear();
98 errtype mai_transition(int new_trans);
99
100 extern errtype make_request(int chunk_num, int piece_ID);
101 extern int digifx_volume_shift(short x, short y, short z, short phi, short theta, short basevol);
102 extern int digifx_pan_shift(short x, short y, short z, short phi, short theta);
103 extern uchar mai_semaphor;
104
105 uchar park_random = 75;
106 uchar park_playing = 0;
107 uchar access_random = 45;
108
109 ulong last_damage_sum = 0;
110 ulong last_vel_time = 0;
111
112 // Damage taken decay & quantity of decay
113 int danger_hp_level = 10;
114 int danger_damage_level = 40;
115 int damage_decay_time = 300;
116 int damage_decay_amount = 6;
117 int mai_damage_sum = 0;
118
119 // How long an attack keeps us in combat music mode
120 int mai_combat_length = 1000;
121
122 uchar bad_digifx = FALSE;
123
124 // KLC - no longer need this Datapath music_dpath;
125
126 #define SMALL_ROBOT_LAYER 3
127
128 char mlimbs_machine = 0;
129
130 //------------------
131 // INTERNAL PROTOTYPES
132 //------------------
133 errtype musicai_shutdown();
134 errtype musicai_reset(uchar runai);
135 int gen_monster(int monster_num);
136
musicai_shutdown()137 errtype musicai_shutdown() {
138 int i;
139 for (i = 0; i < MLIMBS_MAX_SEQUENCES - 1; i++)
140 current_request[i].pieceID = 255;
141 MacTuneKillCurrentTheme();
142 return (OK);
143 }
144
145 extern uchar run_asynch_music_ai;
146
musicai_reset(uchar runai)147 errtype musicai_reset(uchar runai) {
148 if (runai) // Figure out if there is a theme to start with.
149 grind_music_ai();
150 mlimbs_counter = 0;
151 return (OK);
152 }
153
musicai_clear()154 void musicai_clear() {
155 mai_damage_sum = 0;
156 last_damage_sum = 0;
157 mlimbs_combat = 0;
158 }
159
mlimbs_do_ai()160 void mlimbs_do_ai() {
161 // extern uchar mlimbs_semaphore;
162 extern errtype check_asynch_ai(uchar new_score_ok);
163 extern ObjID damage_sound_id;
164 extern char damage_sound_fx;
165
166 if (!IsPlaying(0)) gReadyToQueue = 1;
167
168
169 //repeat shorter tracks while thread 0 is still playing
170 if (!gReadyToQueue)
171 {
172 for (int i = 1; i < MLIMBS_MAX_CHANNELS - 1; i++)
173 if (current_request[i].pieceID != 255)
174 if (!IsPlaying(i))
175 {
176 make_request(i, current_request[i].pieceID);
177 current_request[i].pieceID = 255; //make sure it only plays this time
178 }
179 }
180
181
182 /* Is this really necessary? It's already called twice in fr_rend().
183 #ifdef AUDIOLOGS
184 audiolog_loop_callback();
185 #endif
186 */
187 // Play any queued sound effects, or damage SFX that have yet to get flushed
188 if (damage_sound_fx != -1) {
189 play_digi_fx_obj(damage_sound_fx, 1, damage_sound_id);
190 damage_sound_fx = -1;
191 }
192
193 if (music_on) {
194 if (mlimbs_combat != 0) {
195 if (mlimbs_combat < player_struct.game_time)
196 mlimbs_combat = 0;
197 }
198
199 // Set danger layer
200 layer_danger = 0;
201 if (mai_damage_sum > danger_damage_level)
202 layer_danger = 2;
203 else if (player_struct.hit_points < danger_hp_level)
204 layer_danger = 1;
205
206 // Decay damage
207 if ((last_damage_sum + damage_decay_time) < player_struct.game_time) {
208 mai_damage_sum -= damage_decay_amount;
209 if (mai_damage_sum < 0)
210 mai_damage_sum = 0;
211 last_damage_sum = player_struct.game_time;
212 }
213
214 if ((score_playing == BRIDGE_ZONE) && in_peril) {
215 mlimbs_peril = DEFAULT_PERIL_MIN;
216 mlimbs_combat = 0;
217 } else {
218 if ((mlimbs_combat > 0) || in_peril) {
219 mlimbs_peril = DEFAULT_PERIL_MAX;
220 }
221 }
222
223 // KLC - moved here from grind_music_ai, so it can do this check at all times.
224 if (global_fullmap->cyber) {
225 MapElem *pme;
226 int play_me;
227
228 pme = MAP_GET_XY(PLAYER_BIN_X, PLAYER_BIN_Y); // Determine music for this
229 if (!me_bits_peril(pme)) // location in cyberspace.
230 play_me = NUM_NODE_THEMES + me_bits_music(pme);
231 else
232 play_me = me_bits_music(pme);
233 if (play_me != cyber_play) // If music needs to be changed, then
234 {
235 musicai_shutdown(); // stop playing current tune
236 make_request(0, play_me); // setup new tune
237 musicai_reset(FALSE); // reset MLIMBS and
238 MacTuneStartCurrentTheme(); // start playing the new tune.
239 } else
240 make_request(0, play_me); // otherwise just queue up next tune.
241 cyber_play = play_me;
242 }
243
244 // This is all pretty temporary right now, but here's what's happening.
245 // If the gReadyToQueue flag is set, that means the 6-second timer has
246 // fired. So we call check_asynch_ai() to determine the next tune to play
247 // then queue it up.
248 // Does not handle layering. Just one music track!
249 if (gReadyToQueue) {
250 extern bool mlimbs_update_requests;
251 mlimbs_update_requests = TRUE;
252
253 if (!global_fullmap->cyber)
254 check_asynch_ai(TRUE);
255 int pid = current_request[0].pieceID;
256 if (pid != 255) // If there is a theme to play,
257 {
258 MacTuneQueueTune(pid); // Queue it up.
259 mlimbs_counter++; // Tell mlimbs we've queued another tune.
260 gReadyToQueue = FALSE;
261 }
262 }
263
264 // If a tune has finished playing, then another has just started, so prime the
265 // timer to do the next tune calc.
266 // if (gTuneDone) {
267 // MacTunePrimeTimer();
268 // gTuneDone = FALSE;
269 // }
270 }
271 }
272
273 #ifdef NOT_YET //
274
mlimbs_do_credits_ai()275 void mlimbs_do_credits_ai() {
276 extern uchar mlimbs_semaphore;
277 if (ai_cycle) {
278 ai_cycle = 0;
279 grind_credits_music_ai();
280 mlimbs_preload_requested_timbres();
281 mlimbs_semaphore = FALSE;
282 }
283 }
284
285 #endif // NOT_YET
286
mai_attack()287 errtype mai_attack() {
288 if (music_on) {
289 mlimbs_combat = player_struct.game_time + mai_combat_length;
290 }
291 return (OK);
292 }
293
mai_intro()294 errtype mai_intro() {
295 if (music_on) {
296 if (transition_table[TRANS_INTRO] != 255)
297 mai_transition(TRANS_INTRO);
298 mlimbs_peril = DEFAULT_PERIL_MIN;
299 mlimbs_combat = 0;
300 }
301 return (OK);
302 }
303
mai_monster_nearby(int monster_type)304 errtype mai_monster_nearby(int monster_type) {
305 if (music_on) {
306 mlimbs_monster = monster_type;
307 if (monster_type == NO_MONSTER) {
308 mlimbs_combat = 0;
309 mlimbs_peril = DEFAULT_PERIL_MIN;
310 }
311 }
312 return (OK);
313 }
314
mai_monster_defeated()315 errtype mai_monster_defeated() {
316 if (music_on) {
317 mlimbs_combat = 0;
318 }
319 return (OK);
320 }
321
mai_player_death()322 errtype mai_player_death() {
323 if (music_on) {
324 mai_transition(TRANS_DEATH);
325 mlimbs_peril = DEFAULT_PERIL_MIN;
326 peril_bars = 0;
327 layer_danger = 0;
328 mai_damage_sum = 0;
329 layer_success = 0;
330 mlimbs_machine = 0;
331 mlimbs_monster = 0;
332 mlimbs_combat = 0;
333 musicai_shutdown();
334 make_request(0, transition_table[TRANS_DEATH]);
335 musicai_reset(FALSE);
336 MacTuneStartCurrentTheme();
337 }
338 return (OK);
339 }
340
mlimbs_AI_init(void)341 errtype mlimbs_AI_init(void) {
342 mlimbs_boredom = 0;
343 old_bore = 0;
344 mlimbs_monster = NO_MONSTER;
345 wait_flag = FALSE;
346 random_flag = 0;
347 boring_count = 0;
348 ai_cycle = 0;
349 mlimbs_peril = DEFAULT_PERIL_MAX;
350 current_transition = TRANS_INTRO;
351 current_mode = TRANSITION_MODE;
352 tmode_time = 1; // KLC - was 4
353 current_score = actual_score = last_score = WALKING_SCORE;
354 current_zone = HOSPITAL_ZONE;
355 // mlimbs_AI = &music_ai;
356 cyber_play = 255;
357
358 return (OK);
359 }
360
mai_transition(int new_trans)361 errtype mai_transition(int new_trans) {
362 if ((next_mode == TRANSITION_MODE) || (current_mode == TRANSITION_MODE))
363 return (ERR_NOEFFECT);
364
365 if (transition_table[new_trans] < LAYER_BASE) {
366 current_transition = new_trans;
367 next_mode = TRANSITION_MODE;
368 tmode_time = 1; // KLC - was 4
369 } else if ((transition_count == 0) && (layering_table[TRANSITION_LAYER_BASE + new_trans][0] != 255)) {
370 current_transition = new_trans;
371 // For now, let's not do any layered transitions.
372 // transition_count = 1; //KLC - was 2
373 }
374 // temp
375 /*
376 char msg[30];
377 lg_sprintf(msg, "Transitioning:%d, mode:%d, count:%d", new_trans, next_mode, transition_count);
378 message_info(msg);
379 */
380 return (OK);
381 }
382
gen_monster(int monster_num)383 int gen_monster(int monster_num) {
384 if (monster_num < 3)
385 return (0);
386 if (monster_num < 6)
387 return (1);
388 return (2);
389 }
390
391 int ext_rp = -1;
392
393 extern struct mlimbs_request_info default_request;
394
make_request(int chunk_num,int piece_ID)395 errtype make_request(int chunk_num, int piece_ID) {
396 current_request[chunk_num] = default_request;
397 current_request[chunk_num].pieceID = piece_ID;
398
399 // These get set all around differently and stuff
400 current_request[chunk_num].crossfade = curr_crossfade;
401 current_request[chunk_num].ramp_time = curr_ramp_time;
402 current_request[chunk_num].ramp = curr_ramp;
403
404 DEBUG("make_request %i %i", chunk_num, piece_ID);
405
406 extern int WonGame_ShowStats;
407
408 int i = chunk_num;
409 int track = 1+piece_ID;
410 if (i >= 0 && i < NUM_THREADS && track >= 0 && track < NumTracks && !WonGame_ShowStats && !IsPlaying(i))
411 {
412 // extern uchar curr_vol_lev;
413 // int volume = (int)curr_vol_lev * 127 / 100; //convert from 0-100 to 0-127
414 StartTrack(i, track);
415 }
416
417 return (OK);
418 }
419
420 /*
421 errtype load_score_from_cfg(FSSpec *specPtr)
422 {
423 short filenum;
424 Handle binHdl;
425 Ptr p;
426
427 filenum = FSpOpenResFile(specPtr, fsRdPerm);
428 if (filenum == -1)
429 return (ERR_FOPEN);
430 binHdl = GetResource('tbin', 128);
431 if (binHdl == NULL)
432 return (ERR_FOPEN);
433
434 HLock(binHdl);
435 p = *binHdl;
436 BlockMoveData(p, track_table, NUM_SCORES * SUPERCHUNKS_PER_SCORE);
437 p += NUM_SCORES * SUPERCHUNKS_PER_SCORE;
438 BlockMoveData(p, transition_table, NUM_TRANSITIONS);
439 p += NUM_TRANSITIONS;
440 BlockMoveData(p, layering_table, NUM_LAYERS * MAX_KEYS);
441 p += NUM_LAYERS * MAX_KEYS;
442 BlockMoveData(p, key_table, NUM_LAYERABLE_SUPERCHUNKS * KEY_BAR_RESOLUTION);
443 HUnlock(binHdl);
444
445 CloseResFile(filenum);
446 return(OK);
447 }
448 */
449
450 int old_score;
451
fade_into_location(int x,int y)452 errtype fade_into_location(int x, int y) {
453 MapElem *pme;
454
455 new_x = x;
456 new_y = y;
457 new_theme = 2;
458 pme = MAP_GET_XY(new_x, new_y);
459 score_playing = me_bits_music(pme);
460
461 // For going into/outof elevator and cyberspace, don't do any crossfading.
462 if ((score_playing == ELEVATOR_ZONE) || (score_playing > CYBERSPACE_SCORE_BASE) || (old_score == ELEVATOR_ZONE) ||
463 (old_score > CYBERSPACE_SCORE_BASE)) {
464 if (old_score != score_playing) // Don't restart music if going from elevator
465 { // to elevator (eg, when changing levels).
466 load_score_for_location(new_x, new_y);
467 MacTuneStartCurrentTheme();
468 new_theme = 0;
469 }
470 } else // for now, we're not going to do any cross-fading. Just load the new score.
471 {
472 // message_info("Sould be fading into new location.");
473 load_score_for_location(new_x, new_y);
474 MacTuneStartCurrentTheme();
475 new_theme = 0;
476 }
477 return (OK);
478 }
479
480 /*KLC - don't need
481 errtype blank_theme_data()
482 {
483 LG_memset(track_table, 255, NUM_SCORES * SUPERCHUNKS_PER_SCORE * sizeof(uchar));
484 LG_memset(transition_table, 255, NUM_TRANSITIONS * sizeof(uchar));
485 LG_memset(layering_table, 255, NUM_LAYERS * MAX_KEYS * sizeof(uchar));
486 LG_memset(key_table, 255, NUM_LAYERABLE_SUPERCHUNKS * KEY_BAR_RESOLUTION * sizeof(uchar));
487 return(OK);
488 }
489 */
490
491 // don't need? uchar voices_4op = FALSE;
492 // don't need? uchar digi_gain = FALSE;
load_score_guts(uint8_t score_play)493 void load_score_guts(uint8_t score_play) {
494 int rv;
495 char base[20];
496
497 // Get the theme file name.
498 sprintf(base, "thm%d", score_play);
499 musicai_shutdown();
500
501 // rv = MacTuneLoadTheme(&themeSpec, score_playing);
502 rv = MacTuneLoadTheme(base, score_play);
503
504 if (rv == 0) {
505 musicai_reset(false);
506 }
507 else {
508 DEBUG("%s: load theme failed!", __FUNCTION__); // handle this a better way.
509 }
510 }
511
load_score_for_location(int x,int y)512 errtype load_score_for_location(int x, int y) {
513 MapElem *pme;
514 char sc;
515 extern char old_bits;
516
517 pme = MAP_GET_XY(x, y);
518 sc = me_bits_music(pme);
519 // KLC if ((global_fullmap->cyber) && (sc != 0))
520 if (global_fullmap->cyber)
521 sc = CYBERSPACE_SCORE_BASE;
522 old_bits = old_score = score_playing = sc;
523 if (sc == 7) // Randomize boredom for the elevator
524 mlimbs_boredom = TickCount() % 8;
525 else
526 mlimbs_boredom = 0;
527 load_score_guts(sc);
528 return (OK);
529 }
530
531 #ifdef NOT_YET //
532
533 // 16384
534 // 8192
535 //#define SFX_BUFFER_SIZE 8192
536 #define MIDI_TYPE 0
537 #define DIGI_TYPE 1
538 // #define SPCH_TYPE 2 // perhaps someday, for special CD speech and separate SB digital effects, eh?
539 #define DEV_TYPES 2
540
541 #define DEV_CARD 0
542 #define DEV_IRQ 1
543 #define DEV_DMA 2
544 #define DEV_IO 3
545 #define DEV_DRQ 4
546 #define DEV_PARMS 5
547
548 // doug gets sneaky, film at 11
549 #define MIDI_CARD MIDI_TYPE][DEV_CARD
550 #define MIDI_IRQ MIDI_TYPE][DEV_IRQ
551 #define MIDI_DMA MIDI_TYPE][DEV_DMA
552 #define MIDI_IO MIDI_TYPE][DEV_IO
553 #define MIDI_DRQ MIDI_TYPE][DEV_DRQ
554 #define DIGI_CARD DIGI_TYPE][DEV_CARD
555 #define DIGI_IRQ DIGI_TYPE][DEV_IRQ
556 #define DIGI_DMA DIGI_TYPE][DEV_DMA
557 #define DIGI_IO DIGI_TYPE][DEV_IO
558 #define DIGI_DRQ DIGI_TYPE][DEV_DRQ
559
560 #define SFX_BUFFER_SIZE 8192
561 //#define SFX_BUFFER_SIZE 4096
562
563 static char *dev_suffix[] = {"card", "irq", "dma", "io", "drq"};
564 static char *dev_prefix[] = {"midi_", "digi_"};
565
music_get_config(char * pre,char * suf)566 short music_get_config(char *pre, char *suf) {
567 int tmp_in, dummy_count = 1;
568 char buf[20];
569 strcpy(buf, pre);
570 strcat(buf, suf);
571 if (!config_get_value(buf, CONFIG_INT_TYPE, &tmp_in, &dummy_count))
572 return -1;
573 else
574 return (short)tmp_in;
575 }
576
fill_audio_card(audio_card * cinf,short * dinf)577 audio_card *fill_audio_card(audio_card *cinf, short *dinf) {
578 cinf->type = dinf[DEV_CARD];
579 cinf->dname = NULL;
580 cinf->io = dinf[DEV_IO];
581 cinf->irq = dinf[DEV_IRQ];
582 cinf->dma_8bit = dinf[DEV_DMA];
583 cinf->dma_16bit = -1; // who knows, eh?
584 return cinf;
585 }
586
587 #ifdef PLAYTEST
588 static char def_sound_path[] = "r:\\prj\\cit\\src\\sound";
589 #else
590 static char def_sound_path[] = "sound";
591 #endif
592
593 #ifdef SECRET_SUPPORT
594 FILE *secret_fp = NULL;
595 char secret_dc_buf[10000];
596 volatile char secret_update = FALSE;
secret_closedown(void)597 void secret_closedown(void) {
598 if (secret_fp != NULL)
599 fclose(secret_fp);
600 }
601 #endif
602
603 #endif // NOT_YET
604
605 //----------------------------------------------------------------------
606 // For Mac version, the vast majority of the config mess just goes away. But we do check for
607 // the presence of QuickTime Musical Instruments.
608 //----------------------------------------------------------------------
music_init()609 errtype music_init() {
610 /* put in later
611 int i,j;
612 uchar gm=FALSE;
613 short dev_info[DEV_TYPES][DEV_PARMS];
614 char s[64],path[64];
615 audio_card card_info;
616 extern uchar curr_sfx_vol;
617 extern char curr_vol_lev;
618
619 #ifdef SECRET_SUPPORT
620 if ((secret_fp=fopen("secret.ddb","wt"))!=NULL)
621 {
622 secret_dc_buf[0]='\0';
623 mono_clear();
624 mono_split(MONO_AXIS_Y,4);
625 mono_setwin(2);
626 }
627 atexit(secret_closedown);
628 #endif
629
630 strcpy(s,def_sound_path);
631
632 dev_info[MIDI_CARD]=music_get_config(dev_prefix[0],dev_suffix[0]);
633 dev_info[DIGI_CARD]=music_get_config(dev_prefix[1],dev_suffix[0]);
634
635 DatapathClear(&music_dpath);
636
637 // can we make this actually know what is going on?
638 switch (dev_info[MIDI_CARD])
639 { // probably should be in the library, not here...
640 case GRAVISULTRASTUPID: case MT32: case GENMIDI: case AWE32: case SOUNDSCAPE: case RAP_10: gm=TRUE; break;
641 }
642
643 // add contents of CFG_SOUNDVAR
644 if (config_get_raw(CFG_SOUNDVAR,path,64))
645 {
646 // mprintf("hey, path = %s\n",path);
647 DatapathAdd(&music_dpath, path);
648 if (gm)
649 { strcat(path,"\\genmidi"); }
650 else
651 { strcat(path,"\\sblaster"); }
652 // mprintf("now, path = %s\n",path);
653 DatapathAdd(&music_dpath,path);
654 }
655
656 // add contents of CFG_CD_SOUNDVAR
657 if (config_get_raw(CFG_CD_SOUNDVAR,path,64))
658 {
659 // mprintf("hey, path = %s\n",path);
660 DatapathAdd(&music_dpath, path);
661 if (gm)
662 { strcat(path,"\\genmidi"); }
663 else
664 { strcat(path,"\\sblaster"); }
665 // mprintf("now, path = %s\n",path);
666 DatapathAdd(&music_dpath,path);
667 }
668
669 #ifdef PLAYTEST
670 DatapathAdd(&music_dpath,s+15); // and go back and add net/sound if necessary
671 #else
672 DatapathAdd(&music_dpath,s);
673 #endif
674
675 if (gm)
676 { strcat(s,"\\genmidi"); }
677 else
678 { strcat(s,"\\sblaster"); }
679
680 #ifdef PLAYTEST
681 DatapathAdd(&music_dpath,s+15); // add just sound/devtype
682 DatapathAdd(&music_dpath,s);
683 s[21] = '\0';
684 DatapathAdd(&music_dpath,s);
685 #else
686 DatapathAdd(&music_dpath,s); // add just sound/devtype
687 #endif
688
689 snd_setup(&music_dpath,"sound/cit"); // really it should go find cit.ad on the datapath, then use its path
690
691 music_card=(dev_info[MIDI_CARD]>0);
692 sfx_card =(dev_info[DIGI_CARD]>0);
693 if (!(music_card||sfx_card))
694 {
695 curr_sfx_vol = 0;
696 curr_vol_lev = 0;
697 return(ERR_NODEV);
698 }
699
700 for (i=0; i<DEV_TYPES; i++)
701 if (dev_info[i][DEV_CARD]!=-1)
702 for (j=1; j<DEV_PARMS; j++)
703 dev_info[i][j]=music_get_config(dev_prefix[i],dev_suffix[j]);
704
705 #define ULTRA_GROSS_JOHN_MILES_HACK
706 #ifdef ULTRA_GROSS_JOHN_MILES_HACK
707 {
708 #include <conio.h>
709 if ((dev_info[MIDI_CARD]==GENMIDI)&&(dev_info[DIGI_CARD]==SOUNDBLASTERPRO2)) {
710 int mod_loc=dev_info[DIGI_IO]; // loc, the io port to send too
711 if (mod_loc==-1) mod_loc=0x220; // i know much secretness of destruction
712 outp(mod_loc+4,0x83); // such that def io is 220, which AIL wont
713 outp(mod_loc+5,0xb); // tell me till later, when we init it
714 } // which we are not allowed to do yet
715 }
716 #endif
717
718 if (music_card)
719 {
720 if (snd_start_midi(fill_audio_card(&card_info,dev_info[MIDI_TYPE]))!=SND_OK)
721 {
722 Warning(("Device %d not loaded for Midi at %x %x %x
723 %x\n",dev_info[MIDI_CARD],dev_info[MIDI_IO],dev_info[MIDI_IRQ],dev_info[MIDI_DMA],dev_info[MIDI_DRQ])); music_card =
724 FALSE; curr_vol_lev = 0;
725 }
726 else
727 {
728 mlimbs_init();
729 }
730 }
731 else
732 curr_vol_lev = 0;
733
734 if (sfx_card)
735 {
736 if (snd_start_digital(fill_audio_card(&card_info,dev_info[DIGI_TYPE]))!=SND_OK)
737 {
738 Warning(("Device %d not loaded for DigiFx at %x %x %x
739 %x\n",dev_info[DIGI_CARD],dev_info[DIGI_IO],dev_info[DIGI_IRQ],dev_info[DIGI_DMA],dev_info[DIGI_DRQ])); sfx_card =
740 FALSE; curr_sfx_vol = 0;
741 }
742 else // note this use to allocate double buffer space here
743 {
744 snd_set_digital_channels(cur_digi_channels);
745 // digi_gain = TRUE; // ie look at detail and stuff
746 }
747 }
748 else
749 curr_sfx_vol = 0;
750
751 if (sfx_card)
752 {
753 sfx_on=TRUE;
754 #ifdef AUDIOLOGS
755 audiolog_init();
756 #endif
757 }
758 */
759 if (gShockPrefs.soBackMusic) {
760 // if (music_card)
761 // {
762 if (MacTuneInit() == 0) // If no error, go ahead and start up.
763 {
764 music_on = mlimbs_on = TRUE;
765 mlimbs_AI_init();
766 } else // else turn off the music globals and prefs
767 {
768 gShockPrefs.soBackMusic = FALSE;
769 SavePrefs();
770 music_on = mlimbs_on = FALSE;
771 }
772 // }
773 } else {
774 music_on = mlimbs_on = FALSE;
775 }
776 return (OK);
777 }
778
779 /* KLC - doesn't do anything
780 void music_free(void)
781 {
782 DatapathFree(&music_dpath);
783 }
784 */
785