1 #include "compat.h"
2 #include "baselayer.h"
3 #include "fx_man.h"
4 #include "hmpplay.h"
5 #include "keyboard.h"
6 #include "control.h"
7 #include "tekwar.h"
8 #include "config.h"
9 
10 #if 0
11 
12 /***************************************************************************
13  *   TEKSND.C  - HMI library replaces Kens sound stuff                     *
14  *               Also timer routine and keytimerstuff is here              *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #define  AMBUPDATEDIST  4000L
19 
20 //defines for looping sound variables
21 extern    int       loopinsound;
22 extern    int       baydoorloop;
23 extern    int       ambsubloop;
24 
25 
26 // a 1-1 map from sounds in sound file to this array
27 struct    soundbuffertype {
28      int       users;
29      long      offset;
30      long      cache_ptr;
31      long      cache_length;
32      char      cache_lock;
33 };
34 struct    soundbuffertype    sbuf[TOTALSOUNDS];
35 struct    soundbuffertype    *sbufptr[TOTALSOUNDS];
36 struct    soundbuffertype    loopbuf[MAXLOOPS];
37 struct    soundbuffertype    *loopbufptr[MAXLOOPS];
38 
39 struct    soundtype {
40      int       handle;
41      int       sndnum;
42      int       plevel;
43      long      x,y;
44      short     type;
45 };
46 struct    soundtype     dsound[MAXSOUNDS];
47 struct    soundtype     *dsoundptr[MAXSOUNDS];
48 struct    soundtype     lsound[MAXLOOPS];
49 struct    soundtype     *lsoundptr[MAXLOOPS];
50 DWORD    *LoopList;
51 
52 #define   BASESONG            0
53 #define   MAXBASESONGLENGTH   44136
54 #define   AVAILMODES          3
55 #define   SONGSPERLEVEL       3
56 #define   NUMLEVELS       7
57 
58 int       totalsongsperlevel;
59 char      basesongdata[MAXBASESONGLENGTH];
60 char      secondsongdata[MAXBASESONGLENGTH];
61 char      thirdsongdata[MAXBASESONGLENGTH];
62 
63 struct    songtype  {
64      int       handle;
65      int       offset;
66      int       playing;
67      int       pending;
68      char     *buffer;
69      long      length;
70 };
71 struct    songtype  song[SONGSPERLEVEL];
72 struct    songtype  *songptr[SONGSPERLEVEL];
73 
74 int       songlist[4096];
75 
76 
77 initaudioptrs()
78 {
79      int         i;
80 
81      for( i=0; i<TOTALSOUNDS; i++ ) {
82           sbufptr[i]=&sbuf[i];
83           sbufptr[i]->users=0;
84           sbufptr[i]->offset=0;
85           sbufptr[i]->cache_ptr=0L;
86           sbufptr[i]->cache_length=0;
87           sbufptr[i]->cache_lock=0x00;
88      }
89      for( i=0; i<MAXSOUNDS; i++ ) {
90           dsoundptr[i]=&dsound[i];
91           dsoundptr[i]->handle=NULL_HANDLE;
92           dsoundptr[i]->sndnum=0;
93           dsoundptr[i]->plevel=0;
94           dsoundptr[i]->x=0L;
95           dsoundptr[i]->y=0L;
96           dsoundptr[i]->type=ST_UPDATE;
97           dsoundptr[i]->sndnum=-1;
98           sampleptr[i]=(_SOS_START_SAMPLE   _far *)&sample[i];
99           sampleptr[i]->wSamplePitchFraction=0;
100           sampleptr[i]->wSamplePanDirection=0;
101           sampleptr[i]->wSamplePanStart=0;
102           sampleptr[i]->wSamplePanEnd=0;
103           sampleptr[i]->wSampleDelayBytes=0;
104           sampleptr[i]->wSampleDelayRepeat=0;
105           sampleptr[i]->dwSampleADPCMPredicted=0;
106           sampleptr[i]->wSampleADPCMIndex=0;
107           sampleptr[i]->wSampleRootNoteMIDI=0;
108           sampleptr[i]->dwSampleTemp1=0;
109           sampleptr[i]->dwSampleTemp2=0;
110           sampleptr[i]->dwSampleTemp3=0;
111      }
112 //jsa venom
113      for( i=0; i<SONGSPERLEVEL; i++ ) {
114           songptr[i]=&song[i];
115           songptr[i]->handle=NULL_HANDLE;
116           songptr[i]->offset=0;
117           songptr[i]->playing= 0;
118           songptr[i]->pending=0;
119           songptr[i]->length=0L;
120      }
121      songptr[0]->buffer=&basesongdata;
122      songptr[1]->buffer=&secondsongdata;
123      songptr[2]->buffer=&thirdsongdata;
124 
125 
126      for( i=0; i<MAXLOOPS; i++ ) {
127           loopbufptr[i]=&loopbuf[i];
128           loopbufptr[i]->users=0;
129           loopbufptr[i]->offset=0;
130           loopbufptr[i]->cache_ptr=0L;
131           loopbufptr[i]->cache_length=0;
132           loopbufptr[i]->cache_lock=0x00;
133           lsoundptr[i]=&lsound[i];
134           lsoundptr[i]->handle=NULL_HANDLE;
135           lsoundptr[i]->sndnum=0;
136           lsoundptr[i]->plevel=0;
137           lsoundptr[i]->x=0L;
138           lsoundptr[i]->y=0L;
139           lsoundptr[i]->type=ST_UPDATE;
140           lsoundptr[i]->sndnum=-1;
141           loopsampleptr[i]=(_SOS_START_SAMPLE   _far *)&loopsampledata[i];
142      }
143 }
144 
145 setupdigi()
146 {
147      int       i;
148      DWORD     *digilist;
149 
150      if( soundmode == SM_NOHARDWARE ) {
151           return;
152      }
153 
154      digilist=( DWORD *)malloc(( size_t)4096);
155      if( digilist == ( DWORD *)NULL ) {
156           crash("setupdigi: digilist malloc failed");
157      }
158 
159      fhsounds=open("sounds",O_RDONLY|O_BINARY);
160      if( fhsounds == -1 ) {
161           crash("setupdigi: cant open sounds");
162      }
163      memset(digilist,0, 4096);
164      lseek(fhsounds,-4096L,SEEK_END);
165      i=read(fhsounds,( void *)digilist, 4096);
166      if( i != 4096 ) {
167           crash("setupdigi: bad read of digilist");
168      }
169 
170      for( i=0; i<TOTALSOUNDS; i++ ) {
171           sbufptr[i]=&sbuf[i];
172           sbufptr[i]->users=0;
173           sbufptr[i]->offset=(digilist[i*3]*4096L);
174           sbufptr[i]->cache_ptr=0L;
175           sbufptr[i]->cache_length=( WORD)(digilist[i*3+1]);
176           sbufptr[i]->cache_lock=0x00;
177      }
178      for( i=0; i<MAXSOUNDS; i++ ) {
179           dsoundptr[i]=&dsound[i];
180           dsoundptr[i]->handle=NULL_HANDLE;
181           dsoundptr[i]->sndnum=0;
182           dsoundptr[i]->plevel=0;
183           dsoundptr[i]->x=0L;
184           dsoundptr[i]->y=0L;
185           dsoundptr[i]->type=ST_UPDATE;
186           dsoundptr[i]->sndnum=-1;
187           sampleptr[i]=(_SOS_START_SAMPLE   _far *)&sample[i];
188           sampleptr[i]->wSamplePitchFraction=0;
189           sampleptr[i]->wSamplePanDirection=0;
190           sampleptr[i]->wSamplePanStart=0;
191           sampleptr[i]->wSamplePanEnd=0;
192           sampleptr[i]->wSampleDelayBytes=0;
193           sampleptr[i]->wSampleDelayRepeat=0;
194           sampleptr[i]->dwSampleADPCMPredicted=0;
195           sampleptr[i]->wSampleADPCMIndex=0;
196           sampleptr[i]->wSampleRootNoteMIDI=0;
197           sampleptr[i]->dwSampleTemp1=0;
198           sampleptr[i]->dwSampleTemp2=0;
199           sampleptr[i]->dwSampleTemp3=0;
200      }
201 
202      free(digilist);
203 }
204 
205 setupmidi()
206 {
207      int       fh,dl,rv,i;
208 
209      if( musicmode == MM_NOHARDWARE ) {
210           return;
211      }
212 
213      melodicbankptr=( LPSTR)0;
214      drumbankptr=( LPSTR)0;
215      digitalbankptr=( LPSTR)0;
216 
217      if( (musicmode != MM_MIDIFM) && (musicmode != MM_MIDIDIGI) )
218           goto nobanks;
219 
220      melodicbankptr=( LPSTR)malloc(( size_t)MELODICBANKLENGTH);
221      drumbankptr=( LPSTR)malloc(( size_t)DRUMBANKLENGTH);
222      if( (melodicbankptr == ( LPSTR)NULL) || (drumbankptr == ( LPSTR)NULL) ) {
223           crash("setupmidi: failed malloc");
224      }
225      if( (fh=open("melodic.bnk",O_RDONLY)) == -1 ) {
226           crash("setupmidi: cant open melodic.bnk");
227      }
228      read(fh, ( void * )melodicbankptr, MELODICBANKLENGTH);
229      close(fh);
230      rv=sosMIDISetInsData(*fhmididriverptr, melodicbankptr, 1);
231      if( rv != _ERR_NO_ERROR ) {
232           crash("setupmidi: bad SetInsData");
233      }
234      if( (fh=open("drum.bnk",O_RDONLY)) == -1 ) {
235           crash("setupmidi: cant open drum.bnk");
236      }
237      read(fh, ( void * )drumbankptr, DRUMBANKLENGTH);
238      close(fh);
239      rv=sosMIDISetInsData(*fhmididriverptr, drumbankptr, 1);
240      if( rv != _ERR_NO_ERROR ) {
241           crash("setupmidi: bad SetInsData");
242      }
243 
244      if( (musicmode == MM_MIDIDIGI) && (midihardwareptr->wPort == 0x388) ) {
245           if( (fh=open("test.dig",O_BINARY|O_RDWR)) == -1 ) {
246                crash("setupmidi: cant open test.dig");
247           }
248           dl=lseek(fh, 0L, SEEK_END);
249           lseek(fh, 0L, SEEK_SET);
250           digitalbankptr=( LPSTR)malloc(( size_t)dl);
251           if( digitalbankptr == ( LPSTR)NULL ) {
252                crash("setupmidi: failed malloc digbnkptr");
253           }
254           rv=read(fh, ( void * )digitalbankptr, dl);
255           if( rv != dl ) {
256                crash("setupmidi: bad .dig read");
257           }
258           close(fh);
259           rv=sosMIDISetInsData(*fhmididigidriverptr, digitalbankptr, 1);
260           if( rv != _ERR_NO_ERROR ) {
261                crash("setupmidi: bad SetInsData");
262           }
263      }
264 
265 nobanks:
266 
267      if( musicmode != MM_NOHARDWARE ) {
268           if( (fhsongs=open("SONGS",O_RDONLY | O_BINARY)) == -1 ) {
269                crash("setupmidi: cant open songs");
270           }
271           lseek(fhsongs, 0, SEEK_SET);
272           lseek(fhsongs, -4096, SEEK_END);
273           read(fhsongs, ( void *)songlist, 4096);
274      }
275 
276 //jsa venom
277      for( i=0; i<SONGSPERLEVEL; i++ ) {
278           songptr[i]=&song[i];
279           songptr[i]->handle=NULL_HANDLE;
280           songptr[i]->offset=0;
281           songptr[i]->playing= 0;
282           songptr[i]->pending=0;
283           songptr[i]->length=0L;
284      }
285      songptr[0]->buffer=&basesongdata;
286      songptr[1]->buffer=&secondsongdata;
287      songptr[2]->buffer=&thirdsongdata;
288 
289       totalsongsperlevel=SONGSPERLEVEL*AVAILMODES;
290 
291 
292 }
293 
294 
295 VOID _far cdecl
296 soundcallback(WORD fhdriver, WORD action, WORD fhsample)
297 {
298      int  i;
299 
300      switch( action ) {
301      case _SAMPLE_PROCESSED:
302           return;
303      case _SAMPLE_LOOPING:
304           return;
305      case _SAMPLE_DONE:
306           for( i=0; i<MAXSOUNDS; i++ ) {
307                if( dsoundptr[i]->handle == fhsample ) {
308                     sbufptr[dsoundptr[i]->sndnum]->users--;
309                     if( sbufptr[dsoundptr[i]->sndnum]->users == 0 ) {
310                          sbufptr[dsoundptr[i]->sndnum]->cache_lock=0x00;
311                     }
312                     dsoundptr[i]->handle=NULL_HANDLE;
313                     dsoundptr[i]->plevel=0;
314                     dsoundptr[i]->sndnum=-1;
315                     break;
316                }
317           }
318           break;
319      }
320      return;
321 }
322 
323 VOID _far cdecl
324 digiloopcallback(WORD fhdriver, WORD action, WORD fhsample)
325 {
326      if ( action == _SAMPLE_LOOPING ) {
327                if(LoopPending) {
328                     SND_SwapLoops();
329                     LoopPending = 0;
330                }
331      }
332 }
333 
334 int
335 playsound(int sn, long sndx,long sndy, int loop, short type)
336 {
337      int       i,nr=0;
338      long      dist=0L,vol=0L,pan=0L;
339 
340      if( (toggles[TOGGLE_SOUND] == 0) || (soundmode == SM_NOHARDWARE) || (sn < 0) || (sn >= TOTALSOUNDS) )
341           return(-1);
342 
343      if( type&(ST_UNIQUE|ST_AMBUPDATE|ST_TOGGLE) ) {
344           for( i=0; i<MAXSOUNDS; i++ ) {
345                if( dsoundptr[i]->handle == NULL_HANDLE ) {
346                     continue;
347                }
348                else if( dsoundptr[i]->sndnum == sn ) {
349                     if( (type&ST_TOGGLE) != 0 ) {
350                          stopsound(i);
351                     }
352                     return(-1);
353                }
354           }
355      }
356 
357      for( i=0; i<MAXSOUNDS; i++ ) {
358           if( dsoundptr[i]->handle == NULL_HANDLE )
359                break;
360      }
361      if( i == MAXSOUNDS ) {
362           // add plevel and multiple occurrence replacement
363           return(-1);
364      }
365 
366      dsoundptr[i]->type=type;
367      dsoundptr[i]->x=sndx; dsoundptr[i]->y=sndy;
368 
369      sbufptr[sn]->cache_lock=1;
370 
371      if( sbufptr[sn]->cache_ptr == 0L ) {   // no longer in cache
372           allocache(&(sbufptr[sn]->cache_ptr), sbufptr[sn]->cache_length, &(sbufptr[sn]->cache_lock));
373           if( sbufptr[sn]->cache_ptr == 0L ) {
374                sbufptr[sn]->cache_lock=0x00;
375                return(-1);
376           }
377           lseek(fhsounds, sbufptr[sn]->offset, SEEK_SET);
378           nr=read(fhsounds,( void *)(sbufptr[sn]->cache_ptr),sbufptr[sn]->cache_length);
379           if( nr != sbufptr[sn]->cache_length ) {
380                sbufptr[sn]->cache_ptr=0L;
381                sbufptr[sn]->cache_lock=0x00;
382                return(-1);
383           }
384      }
385      else {
386      }
387 
388      if( (type&ST_IMMEDIATE) ) {
389           vol=0x7fff;
390           pan=13;
391      }
392      else {
393           dist=labs(posx[screenpeek]-sndx)+labs(posy[screenpeek]-sndy);
394            if( (type&ST_AMBUPDATE) || (type&ST_VEHUPDATE) ) {
395                if( dist < AMBUPDATEDIST ) {
396                    vol = (AMBUPDATEDIST<<3)-(dist<<3);
397                }
398                else {
399                    vol=0;
400                }
401            }
402            else {
403                if(dist < 1500L)
404                     vol = 0x7fff;
405                else if(dist > 8500L) {
406                     if(sn >= S_MALE_COMEONYOU)
407                          vol = 0x0000;
408                     else
409                          vol = 0x1f00;
410                }
411                else
412                     vol = 39000L-(dist<<2);
413            }
414            pan=((getangle(posx[screenpeek]-dsoundptr[i]->x,posy[screenpeek]-dsoundptr[i]->y)+(2047-ang[screenpeek]))&2047) >> 6;
415            if( (pan < 0) || (pan > 35) )
416                pan=13;
417      }
418      if( (vol < 0) )
419          vol=0;
420      if( (vol > 0x7fff) )
421          vol=0x7fff;
422 
423      sampleptr[i]->lpSamplePtr=( LPSTR)sbufptr[sn]->cache_ptr;
424      sampleptr[i]->dwSampleSize=sbufptr[sn]->cache_length;
425      sampleptr[i]->wLoopCount=loop;
426      sampleptr[i]->wChannel=_CENTER_CHANNEL;
427      sampleptr[i]->wVolume=vol;
428      sampleptr[i]->wSampleID=sn;
429      sampleptr[i]->lpCallback=soundcallback;
430      sampleptr[i]->wSamplePort=0;
431      sampleptr[i]->wSampleFlags=_LOOPING|_VOLUME|_PANNING;
432      sampleptr[i]->dwSampleLoopPoint=0;
433      sampleptr[i]->dwSampleLoopLength=0;
434      sampleptr[i]->dwSamplePitchAdd=0;
435      sampleptr[i]->dwSampleByteLength=sbufptr[sn]->cache_length;
436      sampleptr[i]->wSamplePanLocation=PanArray[pan];
437      if( sampleptr[i]->wSamplePanLocation > 0xffff )
438           sampleptr[i]->wSamplePanLocation=0x8000;
439      sampleptr[i]->wSamplePanSpeed=0;
440 
441      dsoundptr[i]->handle=sosDIGIStartSample(*fhdigidriverptr,sampleptr[i]);
442      if( dsoundptr[i]->handle == _ERR_NO_SLOTS ) {
443           dsoundptr[i]->handle=NULL_HANDLE;
444           dsoundptr[i]->plevel=0;
445           dsoundptr[i]->sndnum=-1;
446           if( sbufptr[sn]->users == 0 ) {
447                sbufptr[sn]->cache_lock=0;
448           }
449           return(-1);
450      }
451      else {
452           sbufptr[sn]->users++;
453          #ifdef SNDDEBUG
454           showmessage("SND %03d ADDR %08ld USRS %02d", sn, sbufptr[sn]->cache_ptr, sbufptr[sn]->users);
455          #endif
456          dsoundptr[i]->sndnum=sn;
457      }
458 
459      return(i);
460 }
461 
462 stopsound(int i)
463 {
464      if( soundmode == SM_NOHARDWARE )
465           return;
466      if( (i < 0) || (i >= MAXSOUNDS) ) {
467           return;
468      }
469      if( dsoundptr[i]->handle == NULL_HANDLE )
470           return;
471 
472      sosDIGIStopSample(*fhdigidriverptr, dsoundptr[i]->handle);
473      sbufptr[dsoundptr[i]->sndnum]->users--;
474      if( sbufptr[dsoundptr[i]->sndnum]->users < 0 )
475               sbufptr[dsoundptr[i]->sndnum]->users=0;
476      if( sbufptr[dsoundptr[i]->sndnum]->users == 0 ) {
477          sbufptr[dsoundptr[i]->sndnum]->cache_lock=0x00;
478      }
479      dsoundptr[i]->handle=NULL_HANDLE;
480      dsoundptr[i]->plevel=0;
481      dsoundptr[i]->sndnum=-1;
482 }
483 
484 void
485 updatesounds(int    snum)
486 {
487      long      dist=0L,vol=0L,pan=0L;
488      int       i,bufnum,panindx;
489 
490      if( (toggles[TOGGLE_SOUND] == 0) || (soundmode == SM_NOHARDWARE) )
491           return;
492 
493      for( i=0; i<MAXSOUNDS; i++ ) {
494           if( dsoundptr[i]->handle == NULL_HANDLE ) {
495                continue;
496           }
497           if( (dsoundptr[i]->type&(ST_IMMEDIATE|ST_NOUPDATE|ST_VEHUPDATE)) != 0 ) {
498                continue;
499           }
500           dist=labs(posx[snum]-dsoundptr[i]->x)+labs(posy[snum]-dsoundptr[i]->y);
501 
502           if(dsoundptr[i]->type==ST_AMBUPDATE) {
503                if( dist < AMBUPDATEDIST ) {
504                     vol = (AMBUPDATEDIST<<3)-(dist<<3);
505                }
506                else {
507                     vol=0;
508                }
509           }
510           else {
511                if(dist < 1500L)
512                     vol = 0x7fff;
513                else if(dist > 8500L)
514                     vol = 0x1f00;
515                else
516                     vol = 39000L-(dist<<2);
517           }
518 
519           if( (vol < 0) )
520               vol=0;
521           if( (vol > 0x7fff) )
522               vol=0x7fff;
523 
524           if( dsoundptr[i]->handle != NULL_HANDLE ) {   // safeguard on int level
525                sosDIGISetSampleVolume(*fhdigidriverptr, dsoundptr[i]->handle, vol);
526           }
527          #ifdef DYNAMICPANPERFECT
528           panindx=((getangle(posx[snum]-dsoundptr[i]->x,posy[snum]-dsoundptr[i]->y)+(2047-ang[snum]))&2047) >> 6;
529           if( (panindx < 0) || (panindx > 35) )
530                panindx=13;
531           pan=PanArray[panindx];
532           if( pan > 0xffff )
533                pan=0xffff;
534           if( dsoundptr[i]->handle != NULL_HANDLE ) {   // safeguard on int level
535                sosDIGISetPanLocation(*fhdigidriverptr, dsoundptr[i]->handle, pan);
536           }
537          #endif
538      }
539 }
540 
541 void
542 updatevehiclesnds(int i, long sndx, long sndy)
543 {
544      long      dist=0L,vol=0L,pan=0L;
545 
546      if( soundmode == SM_NOHARDWARE ) {
547           return;
548      }
549      if( (i < 0) || (i > MAXSOUNDS) ) {
550           return;
551      }
552 
553      dsoundptr[i]->x=sndx;
554      dsoundptr[i]->y=sndy;
555 
556      dist=labs(posx[screenpeek]-sndx)+labs(posy[screenpeek]-sndy);
557 
558 
559      if( dist < 1000L ) {
560           vol = 0x7fff;
561      }
562      else if( dist > 9000L ) {
563           vol = 0x0000;
564      }
565      else {
566           vol = 36000L-(dist<<2);
567      }
568      if( (vol < 0) || (vol > 0x7FFF) ) {
569           vol=0x7fff;
570      }
571 
572      if( dsoundptr[i]->handle != NULL_HANDLE )
573           sosDIGISetSampleVolume(*fhdigidriverptr, dsoundptr[i]->handle, vol);
574 
575      pan=((getangle(posx[screenpeek]-dsoundptr[i]->x,posy[screenpeek]-dsoundptr[i]->y)+(2047-ang[screenpeek]))&2047) >> 6;
576      if( (pan < 0) || (pan > 35) )
577           pan=13;
578 
579      if( dsoundptr[i]->handle != NULL_HANDLE )
580           sosDIGISetPanLocation(*fhdigidriverptr, dsoundptr[i]->handle, PanArray[pan]);
581 }
582 
583 
584 VOID _far cdecl
585 songcallback(WORD shandle)
586 {
587 }
588 
589 VOID _far cdecl
590 triggercallback(WORD shandle, BYTE track, BYTE id)
591 {
592 }
593 
594 stopsong(int sn)
595 {
596      if( musicmode == MM_NOHARDWARE )
597           return;
598 
599      if( songptr[sn]->playing == 0 ) {
600           return;
601      }
602      if( songptr[sn]->pending != 0 ) {    // cant stop a pending song
603           return;                         // since may be interrupted
604      }                                    // by trigger function
605 
606      sosMIDIStopSong(songptr[sn]->handle);
607      songptr[sn]->playing=0;
608 }
609 
610 removesong(int sn)
611 {
612      if( musicmode == MM_NOHARDWARE )
613           return;
614 
615      if( songptr[sn]->handle != NULL_HANDLE ) {
616           songptr[sn]->pending=0;
617           sosMIDIStopSong(songptr[sn]->handle);
618           sosMIDIUnInitSong(songptr[sn]->handle);
619           songptr[sn]->handle=NULL_HANDLE;
620           songptr[sn]->playing=0;
621      }
622 }
623 
624 int
625 playsong(int sn)
626 {
627      int       rv;
628      int       fpos;
629 
630      if( (musicmode == MM_NOHARDWARE) || (toggles[TOGGLE_MUSIC] == 0) ) {
631           return(0);
632      }
633      if( (sn < 0) || (sn >= SONGSPERLEVEL) || (songptr[sn]->playing != 0) || (songptr[sn]->pending != 0) ) {
634           return(0);
635      }
636 
637      if( songptr[sn]->handle != NULL_HANDLE ) {
638           removesong(sn);
639      }
640      if( songptr[sn]->length == 0 )
641          return(0);
642 
643      songdataptr->lpSongData=( LPSTR)songptr[sn]->buffer;
644      songdataptr->lpSongCallback=( VOID _far *)NULL; //songcallback;
645 
646      fpos=flushall();
647      if( songptr[sn]->handle == NULL_HANDLE ) {
648           lseek(fhsongs,0,SEEK_SET);
649           fpos=filelength(fhsongs);
650           lseek(fhsongs, songptr[sn]->offset, SEEK_SET);
651           fpos=tell(fhsongs);
652           rv=read(fhsongs, ( void *)songptr[sn]->buffer, songptr[sn]->length);
653           if( rv != songptr[sn]->length ) {
654               crash("playsong: bad read");
655           }
656           rv=sosMIDIInitSong(songdataptr, trackmapptr, ( WORD _far *)&(songptr[sn]->handle));
657           if( rv != _ERR_NO_ERROR ) {
658                songptr[sn]->handle=NULL_HANDLE;
659                return(0);
660           }
661      }
662      else {
663           rv=sosMIDIResetSong(songptr[sn]->handle, songdataptr);
664           if( rv != _ERR_NO_ERROR ) {
665                songptr[sn]->handle=NULL_HANDLE;
666               #ifdef MUSICDEBUG
667                showmessage("CANT RESET SONG %2d", sn);
668               #endif
669           }
670      }
671 
672      rv=sosMIDIStartSong(songptr[sn]->handle);
673      if( rv != _ERR_NO_ERROR ) {
674           songptr[sn]->handle=NULL_HANDLE;
675           return(0);
676      }
677 
678      if( (musicv<<3) > 0 ) {
679           sosMIDIFadeSong(songptr[sn]->handle,_SOS_MIDI_FADE_IN,250,
680                           0,(musicv<<3), 50);
681      }
682 
683     #ifdef MUSICDEBUG
684      showmessage("PLAYING SONG %2d", sn);
685     #endif
686      songptr[sn]->playing=1;
687      songptr[sn]->pending=0;
688 
689      return(1);
690 }
691 
692 
693 void menusong(int insubway)
694 {
695 int i,index;
696 
697      if( musicmode == MM_NOHARDWARE )
698      return;
699 
700     for( i=0; i<SONGSPERLEVEL; i++ ) {
701          removesong(i);
702     }
703 
704      if(insubway)
705           index=(NUMLEVELS*(AVAILMODES*SONGSPERLEVEL)+3);
706 
707      else
708           index=NUMLEVELS*(AVAILMODES*SONGSPERLEVEL);
709 
710      switch( musicmode ) {
711      case MM_MIDIFM:
712           break;
713      case MM_MIDIAWE32:
714            index++;
715           break;
716      case MM_MIDIGEN:
717            index+=2;
718           break;
719      }
720 
721      for( i=0; i<SONGSPERLEVEL; i++ ) {
722           songptr[0]->handle=NULL_HANDLE;
723           songptr[0]->offset=songlist[index*3]*4096;
724           songptr[0]->playing=0;
725           songptr[0]->pending=0;
726           songptr[0]->length=( WORD)songlist[(index*3)+1];
727           if( songptr[0]->length >= MAXBASESONGLENGTH ) {
728                crash("prepsongs: basesong exceeded max length");
729           }
730      }
731      songptr[0]->buffer=&basesongdata;
732 
733      playsong(BASESONG);
734 
735 
736 }
737 
738 startmusic(int level)
739 {
740      int       i,index;
741 
742      if( musicmode == MM_NOHARDWARE ) {
743           return;
744      }
745 
746      if( level > 6 ) {
747           return;
748      }
749 
750      for( i=0; i<SONGSPERLEVEL; i++ ) {
751           removesong(i);
752      }
753 
754      index=totalsongsperlevel*(level);
755 
756      switch( musicmode ) {
757      case MM_MIDIFM:
758           break;
759      case MM_MIDIAWE32:
760            index+=SONGSPERLEVEL;
761           break;
762      case MM_MIDIGEN:
763            index+=SONGSPERLEVEL*2;
764           break;
765      }
766 
767      for( i=0; i<SONGSPERLEVEL; i++ ) {
768           songptr[i]->handle=NULL_HANDLE;
769           songptr[i]->offset=songlist[(index*3)+(i*3)]*4096;
770           songptr[i]->playing=0;
771           songptr[i]->pending=0;
772           songptr[i]->length=( WORD)songlist[((index*3)+(i*3))+1];
773           if( songptr[i]->length >= MAXBASESONGLENGTH ) {
774                crash("prepsongs: basesong exceeded max length");
775           }
776      }
777      songptr[0]->buffer=&basesongdata;
778      songptr[1]->buffer=&secondsongdata;
779      songptr[2]->buffer=&thirdsongdata;
780 
781      playsong(BASESONG);
782 }
783 
784 songmastervolume(int vol)
785 {
786      if( musicmode == MM_NOHARDWARE )
787           return;
788 
789      if( (vol < 0) || (vol > 127) )
790           vol=127;
791      sosMIDISetMasterVolume(vol);
792 }
793 
794 soundmastervolume(int vol)
795 {
796      if( soundmode == SM_NOHARDWARE )
797           return;
798 
799      if( (vol < 0) || (vol > 0x7FFF) )
800           vol=0x7fff;
801      sosDIGISetMasterVolume(*fhdigidriverptr, vol);
802 }
803 
804 musicfade(int  dir)
805 {
806      int i;
807 
808      if( musicmode == MM_NOHARDWARE ) {
809           return;
810      }
811      for( i=0; i<SONGSPERLEVEL; i++ ) {
812           if( (songptr[i]->handle != NULL_HANDLE) ) {
813                if( ((musicv<<3) > 0) && (sosMIDISongDone(songptr[i]->handle) == _FALSE) ) {
814                     sosMIDIFadeSong(songptr[i]->handle,_SOS_MIDI_FADE_OUT_STOP, 700,
815                                     (musicv<<3),0,50);
816                     while( (sosMIDISongDone(songptr[i]->handle)==_FALSE) ) {
817                     }
818                }
819                removesong(i);
820           }
821      }
822 }
823 
824 musicoff(void)
825 {
826      int  i;
827 
828      if( musicmode != MM_NOHARDWARE )  {
829           for( i=0; i<SONGSPERLEVEL; i++ ) {
830                if( songptr[i]->handle == NULL_HANDLE )
831                     continue;
832                sosMIDIStopSong(songptr[i]->handle);
833                sosMIDIUnInitSong(songptr[i]->handle);
834           }
835     }
836 }
837 
838 stopallsounds()
839 {
840      int       i;
841 
842      if( soundmode == SM_NOHARDWARE )
843           return;
844 
845      for( i=0; i< MAXSOUNDS; i++ ) {
846           if( dsoundptr[i]->handle == NULL_HANDLE )
847                continue;
848           sosDIGIStopSample(*fhdigidriverptr, dsoundptr[i]->handle);
849           sbufptr[dsoundptr[i]->sndnum]->users--;
850           if( sbufptr[dsoundptr[i]->sndnum]->users < 0 )
851               sbufptr[dsoundptr[i]->sndnum]->users=0;
852           if( sbufptr[dsoundptr[i]->sndnum]->users == 0 ) {
853                sbufptr[dsoundptr[i]->sndnum]->cache_lock=0x00;
854           }
855           dsoundptr[i]->handle=NULL_HANDLE;
856           dsoundptr[i]->plevel=0;
857           dsoundptr[i]->sndnum=-1;
858      }
859 
860 //clear variables that track looping sounds
861      loopinsound=-1;
862      baydoorloop=-1;
863      ambsubloop=-1;
864 
865 }
866 
867 uninitsb(void)
868 {
869      int       i;
870 
871      if( musicmode != MM_NOHARDWARE )  {
872           for( i=0; i<SONGSPERLEVEL; i++ ) {
873                if( songptr[i]->handle == NULL_HANDLE )
874                     continue;
875                sosMIDIStopSong(songptr[i]->handle);
876                sosMIDIUnInitSong(songptr[i]->handle);
877           }
878           sosMIDIUnInitDriver(*fhmididriverptr, _TRUE );
879          sosMIDIUnInitSystem();
880     }
881 
882     if( digiloopflag != 0 ) {
883           for( i=0; i<MAXLOOPS; i++ ) {
884                if( lsoundptr[i]->handle == NULL_HANDLE )
885                     continue;
886                sosDIGIStopSample(*fhdigidriverptr, lsoundptr[i]->handle);
887           }
888     }
889 
890      if( soundmode != SM_NOHARDWARE ) {
891           for( i=0; i<MAXSOUNDS; i++ ) {
892                if( dsoundptr[i]->handle == NULL_HANDLE )
893                     continue;
894                sosDIGIStopSample(*fhdigidriverptr, dsoundptr[i]->handle);
895           }
896           if( soundmode != SM_NOHARDWARE ) {
897                sosTIMERRemoveEvent(*fhdigifillptr);
898                sosDIGIUnInitDriver(*fhdigidriverptr, _TRUE,_TRUE);
899                sosDIGIUnInitSystem();
900           }
901      }
902 
903      if( fhsounds >= 0 )
904           close(fhsounds);
905      if( fhsongs >= 0 )
906           close(fhsongs);
907 
908      if( hLoopFile != -1 )
909            close( hLoopFile );
910      if( LoopList != ( DWORD *)NULL )
911            free( LoopList );
912 
913      if( melodicbankptr )
914           free( ( void *)melodicbankptr);
915      if( drumbankptr )
916           free( ( void *)drumbankptr);
917      if( digitalbankptr )
918           free( ( void *)digitalbankptr);
919 
920      smkuninit(*fhdigidriverptr);
921 }
922 
923 void
924 initlooptable(void)
925 {
926      if(!digiloopflag)
927           return;
928 
929      hLoopFile = open("LOOPS",O_RDONLY | O_BINARY);
930      if( hLoopFile == -1 ) {
931           crash("initlooptable: cant open loops");
932      }
933      LoopList = ( DWORD    *)malloc(0x1000);
934     if( LoopList == ( DWORD *)NULL )
935          crash("initlooptable: cant get mem for LoopList");
936      lseek(hLoopFile,-4096L,SEEK_END);
937      read(hLoopFile,(void *)FP_OFF(LoopList),4096);
938 }
939 
940 void
941 tekprepdigiloops(void)
942 {
943      if( !digiloopflag )
944           return;
945 
946      loopbufptr[0]->cache_lock=1;
947      allocache(&(loopbufptr[0]->cache_ptr), MAX_LOOP_LENGTH, &(loopbufptr[0]->cache_lock));
948      if( loopbufptr[0]->cache_ptr == 0L ) {
949           loopbufptr[0]->cache_lock=0x00;
950           digiloopflag=0;
951      }
952 
953      loopbufptr[1]->cache_lock=1;
954      allocache(&(loopbufptr[1]->cache_ptr), MAX_LOOP_LENGTH, &(loopbufptr[1]->cache_lock));
955      if( loopbufptr[1]->cache_ptr == 0L ) {
956           loopbufptr[1]->cache_lock=0x00;
957           digiloopflag=0;
958      }
959 }
960 
961 void
962 SND_LoadLoop(int load_start)
963 {
964      int  nr=0;
965      SeekIndex = ( LoopList[(LoopIndex * 3)+0] * 4096 );
966      SampleSize= (WORD)LoopList[(LoopIndex * 3) + 1];
967      lseek(hLoopFile, SeekIndex, SEEK_SET);
968 
969      if(!load_start) {
970           nr=read(hLoopFile,( void *)(loopbufptr[looptoggle]->cache_ptr),SampleSize);
971           if( nr != SampleSize ) {
972                loopbufptr[looptoggle]->cache_ptr=0L;
973                loopbufptr[looptoggle]->cache_lock=0x00;
974                crash("read problem with loops");
975           }
976           loopsampleptr[looptoggle]->lpSamplePtr=( LPSTR)loopbufptr[looptoggle]->cache_ptr;
977           loopsampleptr[looptoggle]->dwSampleSize= SampleSize;
978           loopsampleptr[looptoggle]->dwSampleByteLength= SampleSize;
979      }
980      else {
981           nr=read(hLoopFile,( void *)(loopbufptr[looptoggle]->cache_ptr),SampleSize);
982           if( nr != SampleSize ) {
983                loopbufptr[looptoggle]->cache_ptr=0L;
984                loopbufptr[looptoggle]->cache_lock=0x00;
985                crash("read problem with loops");
986           }
987          loopsampleptr[looptoggle]->lpSamplePtr=( LPSTR)loopbufptr[looptoggle]->cache_ptr;
988           loopsampleptr[looptoggle]->dwSampleSize= SampleSize;
989           loopsampleptr[looptoggle]->dwSampleByteLength= SampleSize;
990           lsoundptr[looptoggle]->handle=sosDIGIStartSample(*fhdigidriverptr,loopsampleptr[looptoggle]);
991           looptoggle^=1;
992      }
993 
994      LoopIndex++;
995      if(LoopIndex>MAX_SND_LOOPS-1)
996           LoopIndex=0;
997 }
998 
999 VOID
1000 SND_SwapLoops(VOID)
1001 {
1002      int temp,i;
1003 
1004      temp=looptoggle^1;
1005 
1006      if( !sosDIGISampleDone(*fhdigidriverptr,lsoundptr[temp]->handle) )
1007      {
1008           sosDIGIStopSample(*fhdigidriverptr,lsoundptr[temp]->handle);
1009           lsoundptr[looptoggle]->handle = sosDIGIStartSample(*fhdigidriverptr,loopsampleptr[looptoggle] );
1010      }
1011 
1012      looptoggle^=1;
1013 
1014 }
1015 
1016 #endif
1017 
1018 #define NULL_HANDLE        -1
1019 
1020 
1021 buildvfs_kfd fhsongs = buildvfs_kfd_invalid;
1022 
1023 #define BASESONG            0
1024 #define MAXBASESONGLENGTH   44136
1025 #define AVAILMODES          3
1026 #define SONGSPERLEVEL       3
1027 #define	NUMLEVELS           7
1028 
1029 int       totalsongsperlevel;
1030 char      basesongdata[MAXBASESONGLENGTH];
1031 char      secondsongdata[MAXBASESONGLENGTH]; // TODO: Unused ?
1032 char      thirdsongdata[MAXBASESONGLENGTH];
1033 
1034 struct songtype {
1035     int32_t   handle;
1036     int32_t   offset;
1037     int32_t   playing;
1038     int32_t   pending;
1039     char     *buffer;
1040     int32_t   length;
1041 };
1042 
1043 InitSong songdataptr;
1044 
1045 songtype song[SONGSPERLEVEL];
1046 songtype *songptr[SONGSPERLEVEL];
1047 int       songlist[4096];
1048 
1049 #define MM_NOHARDWARE       0
1050 #define MM_MIDIFM           1
1051 #define MM_MIDIDIGI         2
1052 #define MM_MIDIGEN          3
1053 #define MM_MIDIAWE32        4
1054 
1055 char      musicmode = MM_NOHARDWARE;
1056 
1057 TrackDevice songtrackmap = {
1058     0xff, 0xff, 0xff, 0xff,
1059     0xff, 0xff, 0xff, 0xff,
1060     0xff, 0xff, 0xff, 0xff,
1061     0xff, 0xff, 0xff, 0xff
1062 };
1063 
1064 int       digiloopflag=0;
1065 extern int MV_MixRate;
1066 extern int musicv;
1067 
1068 #define MELODICBANKLENGTH   0x152C
1069 #define DRUMBANKLENGTH      0x152C
1070 char *melodicbankptr;
1071 char *drumbankptr;
1072 
1073 void
setupmidi()1074 setupmidi()
1075 {
1076     buildvfs_kfd fh;
1077     int       rv, i;
1078 
1079     if (musicmode == MM_NOHARDWARE)
1080         return;
1081 
1082     melodicbankptr = NULL;
1083     drumbankptr = NULL;
1084 
1085     if ((musicmode != MM_MIDIFM) && (musicmode != MM_MIDIDIGI))
1086         goto nobanks;
1087 
1088     melodicbankptr = (char*)malloc(MELODICBANKLENGTH);
1089     drumbankptr = (char*)malloc(DRUMBANKLENGTH);
1090     if ((melodicbankptr == NULL) || (drumbankptr == NULL)) {
1091         crash("setupmidi: failed malloc");
1092     }
1093     if ((fh = kopen4load("melodic.bnk", 0)) == buildvfs_kfd_invalid) {
1094         crash("setupmidi: cant open melodic.bnk");
1095     }
1096     kread(fh, (void*)melodicbankptr, MELODICBANKLENGTH);
1097     kclose(fh);
1098     rv = FMSetBank(melodicbankptr);
1099     if (rv != 0) {
1100         crash("setupmidi: bad SetInsData");
1101     }
1102     if ((fh = kopen4load("drum.bnk", O_RDONLY)) == buildvfs_kfd_invalid) {
1103         crash("setupmidi: cant open drum.bnk");
1104     }
1105     kread(fh, (void*)drumbankptr, DRUMBANKLENGTH);
1106     kclose(fh);
1107     rv = FMSetBank(drumbankptr);
1108     if (rv != 0) {
1109         crash("setupmidi: bad SetInsData");
1110     }
1111 
1112 #if 0
1113     if ((musicmode == MM_MIDIDIGI) && (midihardwareptr->wPort == 0x388)) {
1114         if ((fh = open("test.dig", O_BINARY | O_RDWR)) == -1) {
1115             crash("setupmidi: cant open test.dig");
1116         }
1117         dl = lseek(fh, 0L, SEEK_END);
1118         lseek(fh, 0L, SEEK_SET);
1119         digitalbankptr = (LPSTR)malloc((size_t)dl);
1120         if (digitalbankptr == (LPSTR)NULL) {
1121             crash("setupmidi: failed malloc digbnkptr");
1122         }
1123         rv = read(fh, (void*)digitalbankptr, dl);
1124         if (rv != dl) {
1125             crash("setupmidi: bad .dig read");
1126         }
1127         close(fh);
1128         rv = sosMIDISetInsData(*fhmididigidriverptr, digitalbankptr, 1);
1129         if (rv != _ERR_NO_ERROR) {
1130             crash("setupmidi: bad SetInsData");
1131         }
1132     }
1133 #endif
1134 
1135 nobanks:
1136 
1137     if (musicmode != MM_NOHARDWARE) {
1138         if ((fhsongs = kopen4load("SONGS", 0)) == buildvfs_kfd_invalid) {
1139             crash("setupmidi: cant open songs");
1140         }
1141         klseek(fhsongs, 0, SEEK_SET);
1142         klseek(fhsongs, -4096, SEEK_END);
1143         kread(fhsongs, (void*)songlist, 4096);
1144     }
1145 
1146     //jsa venom
1147     for (i = 0; i < SONGSPERLEVEL; i++) {
1148         songptr[i] = &song[i];
1149         songptr[i]->handle = NULL_HANDLE;
1150         songptr[i]->offset = 0;
1151         songptr[i]->playing = 0;
1152         songptr[i]->pending = 0;
1153         songptr[i]->length = 0L;
1154     }
1155     songptr[0]->buffer = basesongdata;
1156     songptr[1]->buffer = secondsongdata;
1157     songptr[2]->buffer = thirdsongdata;
1158 
1159     totalsongsperlevel = SONGSPERLEVEL * AVAILMODES;
1160 }
1161 
1162 void
initsb(char UNUSED (option1),char UNUSED (option2),int UNUSED (digihz),char UNUSED (option7a),char UNUSED (option7b),int UNUSED (val),char UNUSED (option7c))1163 initsb(char UNUSED(option1),char UNUSED(option2),int UNUSED(digihz),
1164     char UNUSED(option7a),char UNUSED(option7b),int UNUSED(val),char UNUSED(option7c))
1165 {
1166     #ifdef MIXERTYPEWIN
1167     void* initdata = (void*)win_gethwnd(); // used for DirectSound
1168     #else
1169     void* initdata = NULL;
1170     #endif
1171 
1172     if (FX_Init(NumVoices, NumChannels, MixRate, initdata) != FX_Ok)
1173     {
1174         initprintf("Error initializing sound card!\n");
1175         return;
1176     }
1177 
1178     musicmode = MM_MIDIFM;
1179 
1180     HMIInit(MV_MixRate);
1181     setupmidi();
1182 }
1183 
1184 void
uninitsb(void)1185 uninitsb(void)
1186 {
1187     int i;
1188     if (musicmode != MM_NOHARDWARE)
1189     {
1190         for (i = 0; i < SONGSPERLEVEL; i++)
1191         {
1192             if (songptr[i]->handle == NULL_HANDLE)
1193                 continue;
1194             HMIStopSong(songptr[i]->handle);
1195             HMIUnInitSong(songptr[i]->handle);
1196         }
1197         HMIUnInit();
1198     }
1199     if (fhsongs != buildvfs_kfd_invalid)
1200         kclose(fhsongs);
1201     if (melodicbankptr)
1202         free(melodicbankptr);
1203     if (drumbankptr)
1204         free(drumbankptr);
1205 
1206     FX_Shutdown();
1207 }
1208 
1209 void
musicoff(void)1210 musicoff(void)
1211 {
1212     int i;
1213 
1214     if (musicmode != MM_NOHARDWARE)
1215     {
1216         for (i = 0; i < SONGSPERLEVEL; i++) {
1217             if (songptr[i]->handle == NULL_HANDLE)
1218                 continue;
1219             HMIStopSong(songptr[i]->handle);
1220             HMIUnInitSong(songptr[i]->handle);
1221         }
1222     }
1223 }
1224 
1225 int
playsound(int UNUSED (sn),int UNUSED (sndx),int UNUSED (sndy),int UNUSED (loop),short UNUSED (type))1226 playsound(int UNUSED(sn), int UNUSED(sndx), int UNUSED(sndy), int UNUSED(loop), short UNUSED(type))
1227 {
1228     return -1;
1229 }
1230 
1231 void
updatevehiclesnds(int UNUSED (i),int UNUSED (sndx),int UNUSED (sndy))1232 updatevehiclesnds(int UNUSED(i), int UNUSED(sndx), int UNUSED(sndy))
1233 {
1234 }
1235 
1236 void
stopsound(int UNUSED (i))1237 stopsound(int UNUSED(i))
1238 {
1239 }
1240 
1241 void
songmastervolume(int vol)1242 songmastervolume(int vol)
1243 {
1244     if (musicmode == MM_NOHARDWARE)
1245         return;
1246 
1247     if ((vol < 0) || (vol > 127))
1248         vol = 127;
1249     HMISetMasterVolume(vol);
1250 }
1251 
1252 void
soundmastervolume(int UNUSED (vol))1253 soundmastervolume(int UNUSED(vol))
1254 {
1255 }
1256 
1257 void
updatesounds(int UNUSED (snum))1258 updatesounds(int UNUSED(snum))
1259 {
1260 }
1261 
1262 void
stopallsounds()1263 stopallsounds()
1264 {
1265 }
1266 
1267 void
removesong(int sn)1268 removesong(int sn)
1269 {
1270      if( musicmode == MM_NOHARDWARE )
1271           return;
1272 
1273      if( songptr[sn]->handle != NULL_HANDLE )
1274      {
1275           songptr[sn]->pending=0;
1276           HMIStopSong(songptr[sn]->handle);
1277           HMIUnInitSong(songptr[sn]->handle);
1278           songptr[sn]->handle=NULL_HANDLE;
1279           songptr[sn]->playing=0;
1280      }
1281 }
1282 
1283 int
playsong(int sn)1284 playsong(int sn)
1285 {
1286     int       rv;
1287     int       fpos;
1288 
1289     if ((musicmode == MM_NOHARDWARE) || (toggles[TOGGLE_MUSIC] == 0))
1290         return(0);
1291 
1292     if ((sn < 0) || (sn >= SONGSPERLEVEL) || (songptr[sn]->playing != 0) || (songptr[sn]->pending != 0))
1293         return(0);
1294 
1295 
1296     if (songptr[sn]->handle != NULL_HANDLE)
1297         removesong(sn);
1298 
1299     if (songptr[sn]->length == 0)
1300         return(0);
1301 
1302     songdataptr.songptr = (uint8_t*)songptr[sn]->buffer;
1303     songdataptr.callback = NULL; //songcallback;
1304 
1305     if (songptr[sn]->handle == NULL_HANDLE) {
1306         klseek(fhsongs, 0, SEEK_SET);
1307         fpos = kfilelength(fhsongs);
1308         klseek(fhsongs, songptr[sn]->offset, SEEK_SET);
1309         fpos = ktell(fhsongs);
1310         rv = kread(fhsongs, (void*)songptr[sn]->buffer, songptr[sn]->length);
1311         if (rv != songptr[sn]->length) {
1312             crash("playsong: bad read");
1313         }
1314         rv = HMIInitSong(&songdataptr, &songtrackmap, (uint32_t*)&songptr[sn]->handle);
1315         if (rv != 0) {
1316             songptr[sn]->handle = NULL_HANDLE;
1317             return(0);
1318         }
1319     }
1320     else {
1321         rv = HMIResetSong(songptr[sn]->handle, &songdataptr);
1322         if (rv != 0) {
1323             songptr[sn]->handle = NULL_HANDLE;
1324 #ifdef MUSICDEBUG
1325             showmessage("CANT RESET SONG %2d", sn);
1326 #endif
1327         }
1328     }
1329 
1330     rv = HMIStartSong(songptr[sn]->handle);
1331     if (rv != 0) {
1332         songptr[sn]->handle = NULL_HANDLE;
1333         return(0);
1334     }
1335 
1336     if ((musicv << 3) > 0) {
1337         HMIFadeSong(songptr[sn]->handle, SONG_FADE_IN, 250,
1338             0, (musicv << 3), 50);
1339     }
1340 
1341 #ifdef MUSICDEBUG
1342     showmessage("PLAYING SONG %2d", sn);
1343 #endif
1344     songptr[sn]->playing = 1;
1345     songptr[sn]->pending = 0;
1346 
1347     return(1);
1348 }
1349 
1350 void
musicfade()1351 musicfade()
1352 {
1353     int i;
1354 
1355     if (musicmode == MM_NOHARDWARE)
1356         return;
1357 
1358     for (i = 0; i < SONGSPERLEVEL; i++)
1359     {
1360         if ((songptr[i]->handle != NULL_HANDLE)) {
1361             if (((musicv << 3) > 0) && !HMISongDone(songptr[i]->handle)) {
1362                 HMIFadeSong(songptr[i]->handle, SONG_FADE_OUT_STOP, 700,
1363                     (musicv << 3), 0, 50);
1364                 while (!HMISongDone(songptr[i]->handle)) {
1365                 }
1366             }
1367             removesong(i);
1368         }
1369     }
1370 }
1371 
1372 void
menusong(int insubway)1373 menusong(int insubway)
1374 {
1375     int i, index;
1376 
1377     if (musicmode == MM_NOHARDWARE)
1378         return;
1379 
1380     for (i = 0; i < SONGSPERLEVEL; i++)
1381         removesong(i);
1382 
1383     if (insubway)
1384         index = (NUMLEVELS * (AVAILMODES * SONGSPERLEVEL) + 3);
1385 
1386     else
1387         index = NUMLEVELS * (AVAILMODES * SONGSPERLEVEL);
1388 
1389     switch (musicmode) {
1390     case MM_MIDIFM:
1391         break;
1392     case MM_MIDIAWE32:
1393         index++;
1394         break;
1395     case MM_MIDIGEN:
1396         index += 2;
1397         break;
1398     }
1399 
1400     for (i = 0; i < SONGSPERLEVEL; i++) {
1401         songptr[0]->handle = NULL_HANDLE;
1402         songptr[0]->offset = songlist[index * 3] * 4096;
1403         songptr[0]->playing = 0;
1404         songptr[0]->pending = 0;
1405         songptr[0]->length = (uint16_t)songlist[(index * 3) + 1];
1406         if (songptr[0]->length >= MAXBASESONGLENGTH) {
1407             crash("prepsongs: basesong exceeded max length");
1408         }
1409     }
1410     songptr[0]->buffer = basesongdata;
1411 
1412     playsong(BASESONG);
1413 }
1414 
1415 void
startmusic(int level)1416 startmusic(int level)
1417 {
1418     int i, index;
1419 
1420     if (musicmode == MM_NOHARDWARE)
1421         return;
1422 
1423     if (level > 6)
1424         return;
1425 
1426     for (i = 0; i < SONGSPERLEVEL; i++)
1427         removesong(i);
1428 
1429     index = totalsongsperlevel * (level);
1430 
1431     switch (musicmode) {
1432     case MM_MIDIFM:
1433         break;
1434     case MM_MIDIAWE32:
1435         index += SONGSPERLEVEL;
1436         break;
1437     case MM_MIDIGEN:
1438         index += SONGSPERLEVEL * 2;
1439         break;
1440     }
1441 
1442     for (i = 0; i < SONGSPERLEVEL; i++)
1443     {
1444         songptr[i]->handle = NULL_HANDLE;
1445         songptr[i]->offset = songlist[(index * 3) + (i * 3)] * 4096;
1446         songptr[i]->playing = 0;
1447         songptr[i]->pending = 0;
1448         songptr[i]->length = (uint16_t)songlist[((index * 3) + (i * 3)) + 1];
1449         if (songptr[i]->length >= MAXBASESONGLENGTH) {
1450             crash("prepsongs: basesong exceeded max length");
1451         }
1452     }
1453     songptr[0]->buffer = basesongdata;
1454     songptr[1]->buffer = secondsongdata;
1455     songptr[2]->buffer = thirdsongdata;
1456 
1457     playsong(BASESONG);
1458 }
1459