]> 4ch.mooo.com Git - 16.git/blob - src/lib/16_sd.c
hmmm unstable code everywhere\!
[16.git] / src / lib / 16_sd.c
1 /* Project 16 Source Code~\r
2  * Copyright (C) 2012-2017 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
3  *\r
4  * This file is part of Project 16.\r
5  *\r
6  * Project 16 is free software; you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation; either version 3 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * Project 16 is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
18  * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
19  * Fifth Floor, Boston, MA 02110-1301 USA.\r
20  *\r
21  */\r
22 \r
23 //\r
24 //      ID Engine\r
25 //      ID_SD.c - Sound Manager for Wolfenstein 3D\r
26 //      v1.2w\r
27 //      By Jason Blochowiak\r
28 //      Open Watcom port by sparky4\r
29 //\r
30 \r
31 //\r
32 //      This module handles dealing with generating sound on the appropriate\r
33 //              hardware\r
34 //\r
35 //      Depends on: User Mgr (for parm checking)\r
36 //\r
37 //      Globals:\r
38 //              For User Mgr:\r
39 //                      SoundSourcePresent - Sound Source thingie present?\r
40 //                      SoundBlasterPresent - SoundBlaster card present?\r
41 //                      AdLibPresent - AdLib card present?\r
42 //                      SoundMode - What device is used for sound effects\r
43 //                              (Use SM_SetSoundMode() to set)\r
44 //                      MusicMode - What device is used for music\r
45 //                              (Use SM_SetMusicMode() to set)\r
46 //                      DigiMode - What device is used for digitized sound effects\r
47 //                              (Use SM_SetDigiDevice() to set)\r
48 //\r
49 //              For Cache Mgr:\r
50 //                      NeedsDigitized - load digitized sounds?\r
51 //                      NeedsMusic - load music?\r
52 //\r
53 \r
54 #pragma hdrstop         // Wierdo thing with MUSE\r
55 \r
56 #include <dos.h>\r
57 \r
58 #ifndef _MUSE_      // Will be defined in ID_Types.h\r
59 #include "src/lib/16_sd.h"\r
60 #else\r
61 #include "src/lib/16_head.h"\r
62 #endif\r
63 #pragma hdrstop\r
64 #pragma warn    -pia\r
65 \r
66 #define SDL_SoundFinished()     {SoundNumber = SoundPriority = 0;}\r
67 \r
68 // Macros for AdLib stuff\r
69 #define selreg(n)       outportb(alFMAddr,n)\r
70 #define writereg(n)     outportb(alFMData,n)\r
71 #define readstat()      inportb(alFMStatus)\r
72 \r
73 //#define SD_USECATA3DSETTIMERSPEED\r
74 \r
75 //      Imports from ID_SD_A.ASM\r
76 /*extern*/      void                    SDL_SetDS(void);\r
77 /*extern*/      void interrupt  SDL_t0ExtremeAsmService(void);//,\r
78 //                                      SDL_t0FastAsmService(void),\r
79 //                                      SDL_t0SlowAsmService(void);\r
80         void                    SDL_IndicatePC(boolean on),\r
81                                         SDL_DigitizedDoneInIRQ();\r
82 \r
83 //      Global variables\r
84         boolean         AdLibPresent,\r
85                                 NeedsDigitized,NeedsMusic,\r
86                                 SoundPositioned;\r
87         SDMode          SoundMode;\r
88         SMMode          MusicMode;\r
89         SDSMode         DigiMode;\r
90         dword   TimeCount;\r
91         word            HackCount;\r
92         word            *SoundTable;    // Really * _seg *SoundTable, but that don't work\r
93         boolean         ssIsTandy;\r
94         int                     DigiMap[LASTSOUND];\r
95 \r
96 //      Internal variables\r
97 static  boolean                 SD_Started;\r
98                 boolean                 nextsoundpos;\r
99                 word/*boolean_+*/                       TimerDone;\r
100                 word                    TimerVal,TimerDelay10,TimerDelay25,TimerDelay100;\r
101                 dword           TimerDivisor,TimerCount;\r
102 static  char                    *ParmStrings[] =\r
103                                                 {\r
104                                                         "noal",\r
105                                                         nil\r
106                                                 };\r
107 static  void                    (*SoundUserHook)(void);\r
108                 soundnames              SoundNumber,DigiNumber;\r
109                 word                    SoundPriority,DigiPriority;\r
110                 int                             LeftPosition,RightPosition;\r
111                 void interrupt  (*t0OldService)(void);\r
112                 long                    LocalTime;\r
113                 word                    TimerRate;\r
114 \r
115                 word                    NumDigi,DigiLeft,DigiPage;\r
116                 word                    _seg *DigiList;\r
117                 word                    DigiLastStart,DigiLastEnd;\r
118                 boolean                 DigiPlaying;\r
119 static  boolean                 DigiMissed,DigiLastSegment;\r
120 static  memptr                  DigiNextAddr;\r
121 static  word                    DigiNextLen;\r
122 \r
123 //      PC Sound variables\r
124                 volatile byte   pcLastSample,far *pcSound;\r
125                 dword           pcLengthLeft;\r
126                 word                    pcSoundLookup[255];\r
127 \r
128 //      AdLib variables\r
129                 boolean                 alNoCheck;\r
130                 byte                    far *alSound;\r
131                 word                    alBlock;\r
132                 dword           alLengthLeft;\r
133                 dword           alTimeCount;\r
134                 Instrument              alZeroInst;\r
135 \r
136 // This table maps channel numbers to carrier and modulator op cells\r
137 static  byte                    carriers[9] =  { 3, 4, 5,11,12,13,19,20,21},\r
138                                                 modifiers[9] = { 0, 1, 2, 8, 9,10,16,17,18},\r
139 // This table maps percussive voice numbers to op cells\r
140                                                 pcarriers[5] = {19,0xff,0xff,0xff,0xff},\r
141                                                 pmodifiers[5] = {16,17,18,20,21};\r
142 \r
143 //      Sequencer variables\r
144                 boolean                 sqActive;\r
145 static  word                    alFXReg;\r
146 static  ActiveTrack             *tracks[sqMaxTracks];//,\r
147 //--                                            mytracks[sqMaxTracks];\r
148 //--static      word                    sqMode,sqFadeStep;\r
149                 word                    far *sqHack,far *sqHackPtr,sqHackLen,sqHackSeqLen;\r
150                 long                    sqHackTime;\r
151 \r
152 //      Internal routines\r
153                 void                    SDL_DigitizedDone(void);\r
154 \r
155 //Assembly functions\r
156 boolean         alNoIRQ;\r
157 \r
158 int count_time=0;\r
159 int count_fx=0;\r
160 int extreme=0;\r
161 \r
162 void SDL_turnOnPCSpeaker(word timerval)\r
163 {\r
164         __asm {\r
165                 mov     bx,timerval\r
166                 mov     al,0b6h\r
167                 out     43h,al\r
168                 mov     al,bl\r
169                 out     42h,al\r
170                 mov     al,bh\r
171                 out     42h,al\r
172                 in      al,61h\r
173                 or      al,3\r
174                 out     61h,al\r
175         }\r
176 }\r
177 \r
178 void SDL_turnOffPCSpeaker()\r
179 {\r
180         __asm {\r
181                 in      al,61h\r
182                 and     al,0fch\r
183                 out     61h,al\r
184         }\r
185 }\r
186 \r
187 void SDL_setPCSpeaker(byte val)\r
188 {\r
189         __asm {\r
190                 mov     al,val\r
191                 in      al,61h\r
192                 and     al,0fch\r
193                 or      al,ah\r
194                 out     61h,al\r
195         }\r
196 }\r
197 \r
198 void SDL_DoFX()\r
199 {\r
200         if(pcSound)\r
201         {\r
202                 if(*pcSound!=pcLastSample)\r
203                 {\r
204                         pcLastSample=*pcSound;\r
205 \r
206                         if(pcLastSample)\r
207                                 SDL_turnOnPCSpeaker(pcLastSample*60);\r
208                         else\r
209                                 SDL_turnOffPCSpeaker();\r
210                 }\r
211                 pcSound++;\r
212                 pcLengthLeft--;\r
213                 if(!pcLengthLeft)\r
214                 {\r
215                         pcSound=0;\r
216                         SoundNumber=(soundnames)0;\r
217                         SoundPriority=0;\r
218                         SDL_turnOffPCSpeaker();\r
219                 }\r
220         }\r
221 \r
222         if(alSound && !alNoIRQ)\r
223         {\r
224                 if(*alSound)\r
225                 {\r
226                         alOut/*InIRQ*/(alFreqL,*alSound);\r
227                         alOut/*InIRQ*/(alFreqH,alBlock);\r
228                 }\r
229                 else alOut/*InIRQ*/(alFreqH,0);\r
230                 alSound++;\r
231                 alLengthLeft--;\r
232                 if(!alLengthLeft)\r
233                 {\r
234                         alSound=0;\r
235                         SoundNumber=(soundnames)0;\r
236                         SoundPriority=0;\r
237                         alOut/*InIRQ*/(alFreqH,0);\r
238                 }\r
239         }\r
240 \r
241 }\r
242 \r
243 void SDL_DoFast()\r
244 {\r
245         count_fx++;\r
246         if(count_fx>=5)\r
247         {\r
248                 count_fx=0;\r
249 \r
250                 SDL_DoFX();\r
251 \r
252                 count_time++;\r
253                 if(count_time>=2)\r
254                 {\r
255                         TimeCount++;\r
256                         count_time=0;\r
257                 }\r
258         }\r
259 \r
260         if(sqActive && !alNoIRQ)\r
261         {\r
262                 if(sqHackLen)\r
263                 {\r
264                         do\r
265                         {\r
266                                 if(sqHackTime>alTimeCount) break;\r
267                                 sqHackTime=alTimeCount+*(sqHackPtr+1);\r
268                                 alOut/*InIRQ*/(*(byte *)sqHackPtr,*(((byte *)sqHackPtr)+1));\r
269                                 sqHackPtr+=2;\r
270                                 sqHackLen-=4;\r
271                         }\r
272                         while(sqHackLen);\r
273                 }\r
274                 alTimeCount++;\r
275                 if(!sqHackLen)\r
276                 {\r
277                         sqHackPtr=sqHack;\r
278                         sqHackLen=sqHackSeqLen;\r
279                         alTimeCount=0;\r
280                         sqHackTime=0;\r
281                 }\r
282         }\r
283 \r
284 //SS    if(ssSample)\r
285 //SS    {\r
286 //SS            if(!(inp(ssStatus)&0x40))\r
287 //SS            {\r
288 //SS                    outp(ssData,*ssSample++);\r
289 //SS                    outp(ssControl,ssOff);\r
290 //SS                    __asm push ax\r
291 //SS                    __asm pop ax\r
292 //SS                    outp(ssControl,ssOn);\r
293 //SS                    __asm push ax\r
294 //SS                    __asm pop ax\r
295 //SS                    ssLengthLeft--;\r
296 //SS                    if(!ssLengthLeft)\r
297 //SS                    {\r
298 //SS                            ssSample=0;\r
299 //SS                            SDL_DigitizedDoneInIRQ();\r
300 //SS                    }\r
301 //SS            }\r
302 //SS    }\r
303 \r
304         TimerCount+=TimerDivisor;\r
305         if(*((word *)&TimerCount+1))\r
306         {\r
307                 *((word *)&TimerCount+1)=0;\r
308                 t0OldService();\r
309         }\r
310         else\r
311         {\r
312                 outp(0x20,0x20);\r
313         }\r
314 }\r
315 \r
316 // Timer 0 ISR for 700Hz interrupts\r
317 void interrupt SDL_t0FastAsmService(void)\r
318 {\r
319         SDL_DoFast();\r
320 }\r
321 \r
322 // Timer 0 ISR for 140Hz interrupts\r
323 void interrupt SDL_t0SlowAsmService(void)\r
324 {\r
325         count_time++;\r
326         if(count_time>=2)\r
327         {\r
328                 TimeCount++;\r
329                 count_time=0;\r
330         }\r
331 \r
332         SDL_DoFX();\r
333 \r
334         TimerCount+=TimerDivisor;\r
335         if(*((word *)&TimerCount+1))\r
336         {\r
337                 *((word *)&TimerCount+1)=0;\r
338                 t0OldService();\r
339         }\r
340         else\r
341                 outp(0x20,0x20);\r
342 }\r
343 \r
344 \r
345 ///////////////////////////////////////////////////////////////////////////\r
346 //\r
347 //      SDL_SetTimer0() - Sets system timer 0 to the specified speed\r
348 //\r
349 ///////////////////////////////////////////////////////////////////////////\r
350 #pragma argsused\r
351 static void\r
352 SDL_SetTimer0(word speed)\r
353 {\r
354 #ifndef TPROF   // If using Borland's profiling, don't screw with the timer\r
355 asm     pushf\r
356 asm     cli\r
357 \r
358         outportb(0x43,0x36);                            // Change timer 0\r
359         outportb(0x40,speed);\r
360         outportb(0x40,speed >> 8);\r
361         // Kludge to handle special case for digitized PC sounds\r
362         if (TimerDivisor == (1192030 / (TickBase * 100)))\r
363                 TimerDivisor = (1192030 / (TickBase * 10));\r
364         else\r
365                 TimerDivisor = speed;\r
366 \r
367 asm     popf\r
368 #else\r
369         TimerDivisor = 0x10000;\r
370 #endif\r
371 }\r
372 \r
373 ///////////////////////////////////////////////////////////////////////////\r
374 //\r
375 //      SDL_SetIntsPerSec() - Uses SDL_SetTimer0() to set the number of\r
376 //              interrupts generated by system timer 0 per second\r
377 //\r
378 ///////////////////////////////////////////////////////////////////////////\r
379 static void\r
380 SDL_SetIntsPerSec(word ints)\r
381 {\r
382         TimerRate = ints;\r
383         SDL_SetTimer0(1192030 / ints);\r
384 }\r
385 \r
386 #ifndef SD_USECATA3DSETTIMERSPEED\r
387 static void\r
388 SDL_SetTimerSpeed(void)\r
389 {\r
390         word    rate;\r
391         void interrupt  (*isr)(void);\r
392 \r
393         if ((DigiMode == sds_PC) && DigiPlaying)\r
394         {\r
395                 rate = TickBase * 100;\r
396                 isr = SDL_t0ExtremeAsmService;\r
397         }\r
398         else if\r
399         (\r
400                 (MusicMode == smm_AdLib)\r
401         ||      ((DigiMode == sds_SoundSource) && DigiPlaying)\r
402         )\r
403         {\r
404                 rate = TickBase * 10;\r
405                 isr = SDL_t0FastAsmService;\r
406         }\r
407         else\r
408         {\r
409                 rate = TickBase * 2;\r
410                 isr = SDL_t0SlowAsmService;\r
411         }\r
412 \r
413         if (rate != TimerRate)\r
414         {\r
415                 setvect(8,isr);\r
416                 SDL_SetIntsPerSec(rate);\r
417                 TimerRate = rate;\r
418         }\r
419 }\r
420 #else\r
421 static void\r
422 SDL_SetTimerSpeed(void)\r
423 {\r
424         word    rate;\r
425 \r
426         if (MusicMode == smm_AdLib)\r
427                 rate = TickBase * 8;\r
428         else\r
429                 rate = TickBase * 2;\r
430         SDL_SetIntsPerSec(rate);\r
431 }\r
432 #endif\r
433 \r
434 ///////////////////////////////////////////////////////////////////////////\r
435 //\r
436 //      SDL_TimingService() - Used by SDL_InitDelay() to determine a timing\r
437 //              value for the current system that we're running on\r
438 //\r
439 ///////////////////////////////////////////////////////////////////////////\r
440 //static void interrupt\r
441 void interrupt\r
442 SDL_TimingService(void)\r
443 {\r
444         //TimerVal = _CX;\r
445         __asm {\r
446                 mov TimerVal,cx\r
447         }\r
448         TimerDone = 1;\r
449 \r
450         outportb(0x20,0x20);                            // Ack interrupt\r
451 }\r
452 #ifdef SD_USECATA3DSETTIMERSPEED\r
453 ///////////////////////////////////////////////////////////////////////////\r
454 //\r
455 //      SDL_InitDelay() - Sets up TimerDelay's for SDL_Delay()\r
456 //\r
457 ///////////////////////////////////////////////////////////////////////////\r
458 static void\r
459 SDL_InitDelay(void)\r
460 {\r
461         int             i;\r
462         word    timer;\r
463 \r
464         setvect(8,SDL_TimingService);           // Set to my timer 0 ISR\r
465 \r
466         SDL_SetIntsPerSec(1000);                        // Time 1ms\r
467 \r
468         for (i = 0,timer = 0;i < 10;i++)        // Do timing test 10 times\r
469         {\r
470                 __asm {\r
471                         xor             dx,dx                                   // Zero DX\r
472                         mov             cx,0xffff                               // Put starting value in CX\r
473                         mov             [TimerDone],cx                  // TimerDone = false - 1\r
474 #ifdef __BORLANDC__\r
475                 }\r
476 #endif\r
477 startloop:\r
478 #ifdef __BORLANDC__\r
479                 __asm {\r
480 #endif\r
481                         or              [TimerDone],0\r
482                         jnz             startloop                               // Make sure we're at the start\r
483 #ifdef __BORLANDC__\r
484                 }\r
485 #endif\r
486 loop_:\r
487 #ifdef __BORLANDC__\r
488                 __asm {\r
489 #endif\r
490                         test    [TimerDone],1                   // See if TimerDone flag got hit\r
491                         jnz             done                                    // Yep - drop out of the loop\r
492                         loop    loop_\r
493 #ifdef __BORLANDC__\r
494                 }\r
495 #endif\r
496 done:\r
497 #ifdef __WATCOMC__\r
498         }\r
499 #endif\r
500 \r
501                 if (0xffff - TimerVal > timer)\r
502                         timer = 0xffff - TimerVal;\r
503         }\r
504         timer += timer / 2;                                     // Use some slop\r
505         TimerDelay10 =  timer / (1000 / 10);\r
506         TimerDelay25 =  timer / (1000 / 25);\r
507         TimerDelay100 = timer / (1000 / 100);\r
508 \r
509         SDL_SetTimer0(0);                                       // Reset timer 0\r
510 \r
511         setvect(8,t0OldService);                        // Set back to old ISR\r
512 }\r
513 #endif\r
514 ///////////////////////////////////////////////////////////////////////////\r
515 //\r
516 //      SDL_Delay() - Delays the specified amount of time\r
517 //\r
518 ///////////////////////////////////////////////////////////////////////////\r
519 static void\r
520 SDL_Delay(word delay)\r
521 {\r
522         if (!delay)\r
523                 return;\r
524 \r
525         __asm {\r
526                 mov             cx,[delay]\r
527 #ifdef __BORLANDC__\r
528         }\r
529 #endif\r
530 loop_:\r
531 #ifdef __BORLANDC__\r
532         __asm {\r
533 #endif\r
534                 test    [TimerDone],0   // Useless code - just for timing equivilency\r
535                 jnz             done\r
536                 loop    loop_\r
537 #ifdef __BORLANDC__\r
538         }\r
539 #endif\r
540 done:\r
541 #ifdef __WATCOMC__\r
542         }\r
543 #endif\r
544 }\r
545 \r
546 //\r
547 //      PC Sound code\r
548 //\r
549 \r
550 ///////////////////////////////////////////////////////////////////////////\r
551 //\r
552 //      SDL_PCPlaySample() - Plays the specified sample on the PC speaker\r
553 //\r
554 ///////////////////////////////////////////////////////////////////////////\r
555 #ifdef  _MUSE_\r
556 void\r
557 #else\r
558 static void\r
559 #endif\r
560 SDL_PCPlaySample(byte huge *data,dword len)\r
561 {\r
562 asm     pushf\r
563 asm     cli\r
564 \r
565         SDL_IndicatePC(true);\r
566 \r
567         pcLengthLeft = len;\r
568         pcSound = (volatile byte far *)data;\r
569 \r
570 asm     popf\r
571 }\r
572 \r
573 ///////////////////////////////////////////////////////////////////////////\r
574 //\r
575 //      SDL_PCStopSample() - Stops a sample playing on the PC speaker\r
576 //\r
577 ///////////////////////////////////////////////////////////////////////////\r
578 #ifdef  _MUSE_\r
579 void\r
580 #else\r
581 static void\r
582 #endif\r
583 SDL_PCStopSample(void)\r
584 {\r
585 asm     pushf\r
586 asm     cli\r
587 \r
588         /*(long)*/pcSound = 0;\r
589 \r
590         SDL_IndicatePC(false);\r
591 \r
592 asm     in      al,0x61                 // Turn the speaker off\r
593 asm     and     al,0xfd                 // ~2\r
594 asm     out     0x61,al\r
595 \r
596 asm     popf\r
597 }\r
598 \r
599 ///////////////////////////////////////////////////////////////////////////\r
600 //\r
601 //      SDL_PCPlaySound() - Plays the specified sound on the PC speaker\r
602 //\r
603 ///////////////////////////////////////////////////////////////////////////\r
604 #ifdef  _MUSE_\r
605 void\r
606 #else\r
607 static void\r
608 #endif\r
609 SDL_PCPlaySound(PCSound far *sound)\r
610 {\r
611 asm     pushf\r
612 asm     cli\r
613 \r
614         pcLastSample = -1;\r
615         pcLengthLeft = sound->common.length;\r
616         pcSound = sound->data;\r
617 \r
618 asm     popf\r
619 }\r
620 \r
621 ///////////////////////////////////////////////////////////////////////////\r
622 //\r
623 //      SDL_PCStopSound() - Stops the current sound playing on the PC Speaker\r
624 //\r
625 ///////////////////////////////////////////////////////////////////////////\r
626 #ifdef  _MUSE_\r
627 void\r
628 #else\r
629 static void\r
630 #endif\r
631 SDL_PCStopSound(void)\r
632 {\r
633 asm     pushf\r
634 asm     cli\r
635 \r
636         /*(long)*/pcSound = 0;\r
637 \r
638 asm     in      al,0x61                 // Turn the speaker off\r
639 asm     and     al,0xfd                 // ~2\r
640 asm     out     0x61,al\r
641 \r
642 asm     popf\r
643 }\r
644 \r
645 ///////////////////////////////////////////////////////////////////////////\r
646 //\r
647 //      SDL_PCService() - Handles playing the next sample in a PC sound\r
648 //\r
649 ///////////////////////////////////////////////////////////////////////////\r
650 static void\r
651 SDL_PCService(void)\r
652 {\r
653         byte    s;\r
654         word    t;\r
655 \r
656         if (pcSound)\r
657         {\r
658                 s = *pcSound++;\r
659                 if (s != pcLastSample)\r
660                 {\r
661                 asm     pushf\r
662                 asm     cli\r
663 \r
664                         pcLastSample = s;\r
665                         if (s)                                  // We have a frequency!\r
666                         {\r
667                                 t = pcSoundLookup[s];\r
668                         asm     mov     bx,[t]\r
669 \r
670                         asm     mov     al,0xb6                 // Write to channel 2 (speaker) timer\r
671                         asm     out     43h,al\r
672                         asm     mov     al,bl\r
673                         asm     out     42h,al                  // Low byte\r
674                         asm     mov     al,bh\r
675                         asm     out     42h,al                  // High byte\r
676 \r
677                         asm     in      al,0x61                 // Turn the speaker & gate on\r
678                         asm     or      al,3\r
679                         asm     out     0x61,al\r
680                         }\r
681                         else                                    // Time for some silence\r
682                         {\r
683                         asm     in      al,0x61                 // Turn the speaker & gate off\r
684                         asm     and     al,0xfc                 // ~3\r
685                         asm     out     0x61,al\r
686                         }\r
687 \r
688                 asm     popf\r
689                 }\r
690 \r
691                 if (!(--pcLengthLeft))\r
692                 {\r
693                         SDL_PCStopSound();\r
694                         SDL_SoundFinished();\r
695                 }\r
696         }\r
697 }\r
698 \r
699 ///////////////////////////////////////////////////////////////////////////\r
700 //\r
701 //      SDL_ShutPC() - Turns off the pc speaker\r
702 //\r
703 ///////////////////////////////////////////////////////////////////////////\r
704 static void\r
705 SDL_ShutPC(void)\r
706 {\r
707 asm     pushf\r
708 asm     cli\r
709 \r
710         pcSound = 0;\r
711 \r
712 asm     in      al,0x61                 // Turn the speaker & gate off\r
713 asm     and     al,0xfc                 // ~3\r
714 asm     out     0x61,al\r
715 \r
716 asm     popf\r
717 }\r
718 \r
719 //\r
720 //      Stuff for digitized sounds\r
721 //\r
722 memptr\r
723 SDL_LoadDigiSegment(word page, global_game_variables_t *gvar)\r
724 {\r
725         memptr  addr;\r
726 \r
727 #if 0   // for debugging\r
728 asm     mov     dx,STATUS_REGISTER_1\r
729 asm     in      al,dx\r
730 asm     mov     dx,ATR_INDEX\r
731 asm     mov     al,ATR_OVERSCAN\r
732 asm     out     dx,al\r
733 asm     mov     al,10   // bright green\r
734 asm     out     dx,al\r
735 #endif\r
736 \r
737         addr = PM_GetSoundPage(page);\r
738         PM_SetPageLock(gvar->pm.fi.PMSoundStart + page,pml_Locked, gvar);\r
739 \r
740 #if 0   // for debugging\r
741 asm     mov     dx,STATUS_REGISTER_1\r
742 asm     in      al,dx\r
743 asm     mov     dx,ATR_INDEX\r
744 asm     mov     al,ATR_OVERSCAN\r
745 asm     out     dx,al\r
746 asm     mov     al,3    // blue\r
747 asm     out     dx,al\r
748 asm     mov     al,0x20 // normal\r
749 asm     out     dx,al\r
750 #endif\r
751 \r
752         return(addr);\r
753 }\r
754 \r
755 void\r
756 SDL_PlayDigiSegment(memptr addr,word len)\r
757 {\r
758         switch (DigiMode)\r
759         {\r
760         case sds_PC:\r
761         SDL_PCPlaySample(addr,len);\r
762                 break;\r
763 //SS    case sds_SoundSource:\r
764 //SS            SDL_SSPlaySample(addr,len);\r
765 //SS            break;\r
766 //SB    case sds_SoundBlaster:\r
767 //SB            SDL_SBPlaySample(addr,len);\r
768 //SB            break;\r
769         }\r
770 }\r
771 \r
772 void\r
773 SD_StopDigitized(global_game_variables_t *gvar)\r
774 {\r
775         int     i;\r
776 \r
777 asm     pushf\r
778 asm     cli\r
779 \r
780         DigiLeft = 0;\r
781         DigiNextAddr = nil;\r
782         DigiNextLen = 0;\r
783         DigiMissed = false;\r
784         DigiPlaying = false;\r
785         DigiNumber = DigiPriority = 0;\r
786         SoundPositioned = false;\r
787         if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))\r
788                 SDL_SoundFinished();\r
789 \r
790         switch (DigiMode)\r
791         {\r
792         case sds_PC:\r
793                 SDL_PCStopSample();\r
794                 break;\r
795 //SS    case sds_SoundSource:\r
796 //SS            SDL_SSStopSample();\r
797 //SS            break;\r
798 //SB    case sds_SoundBlaster:\r
799 //SB            SDL_SBStopSample();\r
800 //SB            break;\r
801         }\r
802 \r
803 asm     popf\r
804 \r
805         for (i = DigiLastStart;i < DigiLastEnd;i++)\r
806                 PM_SetPageLock(i + gvar->pm.fi.PMSoundStart,pml_Unlocked, gvar);\r
807         DigiLastStart = 1;\r
808         DigiLastEnd = 0;\r
809 }\r
810 \r
811 void\r
812 SD_Poll(global_game_variables_t *gvar)\r
813 {\r
814         if (DigiLeft && !DigiNextAddr)\r
815         {\r
816                 DigiNextLen = (DigiLeft >= PMPageSize)? PMPageSize : (DigiLeft % PMPageSize);\r
817                 DigiLeft -= DigiNextLen;\r
818                 if (!DigiLeft)\r
819                         DigiLastSegment = true;\r
820                 DigiNextAddr = SDL_LoadDigiSegment(DigiPage++, gvar);\r
821         }\r
822         if (DigiMissed && DigiNextAddr)\r
823         {\r
824                 SDL_PlayDigiSegment(DigiNextAddr,DigiNextLen);\r
825                 DigiNextAddr = nil;\r
826                 DigiMissed = false;\r
827                 if (DigiLastSegment)\r
828                 {\r
829                         DigiPlaying = false;\r
830                         DigiLastSegment = false;\r
831                 }\r
832         }\r
833         SDL_SetTimerSpeed();\r
834 }\r
835 \r
836 void\r
837 SD_SetPosition(int leftpos,int rightpos, global_game_variables_t *gvar)\r
838 {\r
839         if\r
840         (\r
841                 (leftpos < 0)\r
842         ||      (leftpos > 15)\r
843         ||      (rightpos < 0)\r
844         ||      (rightpos > 15)\r
845         ||      ((leftpos == 15) && (rightpos == 15))\r
846         )\r
847                 Quit(gvar, "SD_SetPosition: Illegal position");\r
848 \r
849         switch (DigiMode)\r
850         {\r
851 //SB    case sds_SoundBlaster:\r
852 //SB            SDL_PositionSBP(leftpos,rightpos);\r
853 //SB            break;\r
854         }\r
855 }\r
856 \r
857 void\r
858 SD_PlayDigitized(word which,int leftpos,int rightpos, global_game_variables_t *gvar)\r
859 {\r
860         word    len;\r
861         memptr  addr;\r
862 \r
863         if (!DigiMode)\r
864                 return;\r
865 \r
866         SD_StopDigitized(gvar);\r
867         if (which >= NumDigi)\r
868                 Quit(gvar, "SD_PlayDigitized: bad sound number");\r
869 \r
870         SD_SetPosition(leftpos,rightpos, gvar);\r
871 \r
872         DigiPage = DigiList[(which * 2) + 0];\r
873         DigiLeft = DigiList[(which * 2) + 1];\r
874 \r
875         DigiLastStart = DigiPage;\r
876         DigiLastEnd = DigiPage + ((DigiLeft + (PMPageSize - 1)) / PMPageSize);\r
877 \r
878         len = (DigiLeft >= PMPageSize)? PMPageSize : (DigiLeft % PMPageSize);\r
879         addr = SDL_LoadDigiSegment(DigiPage++, gvar);\r
880 \r
881         DigiPlaying = true;\r
882         DigiLastSegment = false;\r
883 \r
884         SDL_PlayDigiSegment(addr,len);\r
885         DigiLeft -= len;\r
886         if (!DigiLeft)\r
887                 DigiLastSegment = true;\r
888 \r
889         SD_Poll(gvar);\r
890 }\r
891 \r
892 void\r
893 SDL_DigitizedDone(void)\r
894 {\r
895         if (DigiNextAddr)\r
896         {\r
897                 SDL_PlayDigiSegment(DigiNextAddr,DigiNextLen);\r
898                 DigiNextAddr = nil;\r
899                 DigiMissed = false;\r
900         }\r
901         else\r
902         {\r
903                 if (DigiLastSegment)\r
904                 {\r
905                         DigiPlaying = false;\r
906                         DigiLastSegment = false;\r
907                         if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))\r
908                         {\r
909                                 SDL_SoundFinished();\r
910                         }\r
911                         else\r
912                                 DigiNumber = DigiPriority = 0;\r
913                         SoundPositioned = false;\r
914                 }\r
915                 else\r
916                         DigiMissed = true;\r
917         }\r
918 }\r
919 \r
920 void\r
921 SD_SetDigiDevice(SDSMode mode, global_game_variables_t *gvar)\r
922 {\r
923         boolean devicenotpresent;\r
924 \r
925         if (mode == DigiMode)\r
926                 return;\r
927 \r
928         SD_StopDigitized(gvar);\r
929 \r
930         devicenotpresent = false;\r
931 //SBSS  switch (mode)\r
932 //SBSS  {\r
933 //SB    case sds_SoundBlaster:\r
934 //SB            if (!SoundBlasterPresent)\r
935 //SB            {\r
936 //SB                    if (SoundSourcePresent)\r
937 //SB                            mode = sds_SoundSource;\r
938 //SB                    else\r
939 //SB                            devicenotpresent = true;\r
940 //SB            }\r
941 //SB            break;\r
942 //SS    case sds_SoundSource:\r
943 //SS            if (!SoundSourcePresent)\r
944 //SS                    devicenotpresent = true;\r
945 //SS            break;\r
946 //SBSS  }\r
947 \r
948         if (!devicenotpresent)\r
949         {\r
950 //SS            if (DigiMode == sds_SoundSource)\r
951 //SS                    SDL_ShutSS();\r
952 \r
953                 DigiMode = mode;\r
954 \r
955 //SS            if (mode == sds_SoundSource)\r
956 //SS                    SDL_StartSS();\r
957 \r
958                 SDL_SetTimerSpeed();\r
959         }\r
960 }\r
961 \r
962 void\r
963 SDL_SetupDigi(global_game_variables_t *gvar)\r
964 {\r
965         memptr  list;\r
966         word    far *p,\r
967                         pg;\r
968         int             i;\r
969 \r
970         PM_UnlockMainMem(gvar);\r
971         MM_GetPtr(&list,PMPageSize, gvar);\r
972         PM_CheckMainMem(gvar);\r
973         p = (word far *)MK_FP(PM_GetPage(gvar->pm.fi.ChunksInFile - 1, gvar),0);\r
974         _fmemcpy((void far *)list,(void far *)p,PMPageSize);\r
975         pg = gvar->pm.fi.PMSoundStart;\r
976         for (i = 0;i < PMPageSize / (sizeof(word) * 2);i++,p += 2)\r
977         {\r
978                 if (pg >= gvar->pm.fi.ChunksInFile - 1)\r
979                         break;\r
980                 pg += (p[1] + (PMPageSize - 1)) / PMPageSize;\r
981         }\r
982         PM_UnlockMainMem(gvar);\r
983         MM_GetPtr(MEMPTRCONV DigiList,i * sizeof(word) * 2, gvar);\r
984         _fmemcpy((void far *)DigiList,(void far *)list,i * sizeof(word) * 2);\r
985         MM_FreePtr(&list, gvar);\r
986         NumDigi = i;\r
987 \r
988         for (i = 0;i < LASTSOUND;i++)\r
989                 DigiMap[i] = -1;\r
990 }\r
991 \r
992 //      AdLib Code\r
993 \r
994 ///////////////////////////////////////////////////////////////////////////\r
995 //\r
996 //      alOut(n,b) - Puts b in AdLib card register n\r
997 //\r
998 ///////////////////////////////////////////////////////////////////////////\r
999 void\r
1000 alOut(byte n,byte b)\r
1001 {\r
1002 asm     pushf\r
1003 asm     cli\r
1004 \r
1005 asm     mov             dx,0x388\r
1006 asm     mov             al,[n]\r
1007 asm     out             dx,al\r
1008 #if 0\r
1009         SDL_Delay(TimerDelay10);\r
1010 #else\r
1011 asm     in      al, dx\r
1012 asm     in      al, dx\r
1013 asm     in      al, dx\r
1014 asm     in      al, dx\r
1015 asm     in      al, dx\r
1016 asm     in      al, dx\r
1017 #endif\r
1018 \r
1019 asm     mov             dx,0x389\r
1020 asm     mov             al,[b]\r
1021 asm     out             dx,al\r
1022 \r
1023 asm     popf\r
1024 \r
1025 #if 0\r
1026         SDL_Delay(TimerDelay25);\r
1027 #else\r
1028 asm     mov     dx,0x388\r
1029 asm     in      al, dx\r
1030 asm     in      al, dx\r
1031 asm     in      al, dx\r
1032 asm     in      al, dx\r
1033 asm     in      al, dx\r
1034 asm     in      al, dx\r
1035 asm     in      al, dx\r
1036 asm     in      al, dx\r
1037 asm     in      al, dx\r
1038 asm     in      al, dx\r
1039 \r
1040 asm     in      al, dx\r
1041 asm     in      al, dx\r
1042 asm     in      al, dx\r
1043 asm     in      al, dx\r
1044 asm     in      al, dx\r
1045 asm     in      al, dx\r
1046 asm     in      al, dx\r
1047 asm     in      al, dx\r
1048 asm     in      al, dx\r
1049 asm     in      al, dx\r
1050 \r
1051 asm     in      al, dx\r
1052 asm     in      al, dx\r
1053 asm     in      al, dx\r
1054 asm     in      al, dx\r
1055 asm     in      al, dx\r
1056 asm     in      al, dx\r
1057 asm     in      al, dx\r
1058 asm     in      al, dx\r
1059 asm     in      al, dx\r
1060 asm     in      al, dx\r
1061 \r
1062 asm     in      al, dx\r
1063 asm     in      al, dx\r
1064 asm     in      al, dx\r
1065 asm     in      al, dx\r
1066 asm     in      al, dx\r
1067 #endif\r
1068 }\r
1069 \r
1070 //#if 0\r
1071 ///////////////////////////////////////////////////////////////////////////\r
1072 //\r
1073 //      SDL_SetInstrument() - Puts an instrument into a generator\r
1074 //\r
1075 ///////////////////////////////////////////////////////////////////////////\r
1076 //static void\r
1077 void\r
1078 SDL_SetInstrument(int track,int which,Instrument far *inst,boolean percussive)\r
1079 {\r
1080         byte            c,m;\r
1081 \r
1082         if (percussive)\r
1083         {\r
1084                 c = pcarriers[which];\r
1085                 m = pmodifiers[which];\r
1086         }\r
1087         else\r
1088         {\r
1089                 c = carriers[which];\r
1090                 m = modifiers[which];\r
1091         }\r
1092 \r
1093         tracks[track - 1]->inst = *inst;\r
1094         tracks[track - 1]->percussive = percussive;\r
1095 \r
1096         alOut(m + alChar,inst->mChar);\r
1097         alOut(m + alScale,inst->mScale);\r
1098         alOut(m + alAttack,inst->mAttack);\r
1099         alOut(m + alSus,inst->mSus);\r
1100         alOut(m + alWave,inst->mWave);\r
1101 \r
1102         // Most percussive instruments only use one cell\r
1103         if (c != 0xff)\r
1104         {\r
1105                 alOut(c + alChar,inst->cChar);\r
1106                 alOut(c + alScale,inst->cScale);\r
1107                 alOut(c + alAttack,inst->cAttack);\r
1108                 alOut(c + alSus,inst->cSus);\r
1109                 alOut(c + alWave,inst->cWave);\r
1110         }\r
1111 \r
1112         alOut(which + alFeedCon,inst->nConn);   // DEBUG - I think this is right\r
1113 }\r
1114 //#endif\r
1115 \r
1116 ///////////////////////////////////////////////////////////////////////////\r
1117 //\r
1118 //      SDL_ALStopSound() - Turns off any sound effects playing through the\r
1119 //              AdLib card\r
1120 //\r
1121 ///////////////////////////////////////////////////////////////////////////\r
1122 #ifdef  _MUSE_\r
1123 void\r
1124 #else\r
1125 static void\r
1126 #endif\r
1127 SDL_ALStopSound(void)\r
1128 {\r
1129 asm     pushf\r
1130 asm     cli\r
1131 \r
1132         /*(long)*/alSound = 0;\r
1133         alOut(alFreqH + 0,0);\r
1134 \r
1135 asm     popf\r
1136 }\r
1137 \r
1138 static void\r
1139 SDL_AlSetFXInst(Instrument far *inst)\r
1140 {\r
1141         byte            c,m;\r
1142 \r
1143         m = modifiers[0];\r
1144         c = carriers[0];\r
1145         alOut(m + alChar,inst->mChar);\r
1146         alOut(m + alScale,inst->mScale);\r
1147         alOut(m + alAttack,inst->mAttack);\r
1148         alOut(m + alSus,inst->mSus);\r
1149         alOut(m + alWave,inst->mWave);\r
1150         alOut(c + alChar,inst->cChar);\r
1151         alOut(c + alScale,inst->cScale);\r
1152         alOut(c + alAttack,inst->cAttack);\r
1153         alOut(c + alSus,inst->cSus);\r
1154         alOut(c + alWave,inst->cWave);\r
1155 \r
1156         // Note: Switch commenting on these lines for old MUSE compatibility\r
1157 //      alOut(alFeedCon,inst->nConn);\r
1158         alOut(alFeedCon,0);\r
1159 }\r
1160 \r
1161 ///////////////////////////////////////////////////////////////////////////\r
1162 //\r
1163 //      SDL_ALPlaySound() - Plays the specified sound on the AdLib card\r
1164 //\r
1165 ///////////////////////////////////////////////////////////////////////////\r
1166 #ifdef  _MUSE_\r
1167 void\r
1168 #else\r
1169 static void\r
1170 #endif\r
1171 SDL_ALPlaySound(AdLibSound far *sound, global_game_variables_t *gvar)\r
1172 {\r
1173         Instrument      __far *inst;\r
1174         byte            huge *data;\r
1175 \r
1176         SDL_ALStopSound();\r
1177 \r
1178 asm     pushf\r
1179 asm     cli\r
1180 \r
1181         alLengthLeft = sound->common.length;\r
1182         data = sound->data;\r
1183         data++;\r
1184         data--;\r
1185         alSound = (byte far *)data;\r
1186         alBlock = ((sound->block & 7) << 2) | 0x20;\r
1187         inst = &sound->inst;\r
1188 \r
1189         if (!(inst->mSus | inst->cSus))\r
1190         {\r
1191         asm     popf\r
1192                 Quit(gvar, "SDL_ALPlaySound() - Bad instrument");\r
1193         }\r
1194 \r
1195         SDL_AlSetFXInst(&alZeroInst);   // DEBUG\r
1196         SDL_AlSetFXInst(inst);\r
1197 \r
1198 asm     popf\r
1199 }\r
1200 \r
1201 //#if 0\r
1202 ///////////////////////////////////////////////////////////////////////////\r
1203 //\r
1204 //      SDL_ALSoundService() - Plays the next sample out through the AdLib card\r
1205 //\r
1206 ///////////////////////////////////////////////////////////////////////////\r
1207 //static void\r
1208 void\r
1209 SDL_ALSoundService(void)\r
1210 {\r
1211         byte    s;\r
1212 \r
1213         if (alSound)\r
1214         {\r
1215                 s = *alSound++;\r
1216                 if (!s)\r
1217                         alOut(alFreqH + 0,0);\r
1218                 else\r
1219                 {\r
1220                         alOut(alFreqL + 0,s);\r
1221                         alOut(alFreqH + 0,alBlock);\r
1222                 }\r
1223 \r
1224                 if (!(--alLengthLeft))\r
1225                 {\r
1226                         /*(long)*/alSound = 0;\r
1227                         alOut(alFreqH + 0,0);\r
1228                         SDL_SoundFinished();\r
1229                 }\r
1230         }\r
1231 }\r
1232 //#endif\r
1233 \r
1234 #if 0\r
1235 ///////////////////////////////////////////////////////////////////////////\r
1236 //\r
1237 //      SDL_SelectMeasure() - sets up sequencing variables for a given track\r
1238 //\r
1239 ///////////////////////////////////////////////////////////////////////////\r
1240 void\r
1241 SDL_SelectMeasure(ActiveTrack *track)\r
1242 {\r
1243         track->seq = track->moods[track->mood];\r
1244         track->nextevent = 0;\r
1245 }\r
1246 #endif\r
1247 \r
1248 //#if 0\r
1249 void\r
1250 SDL_ALService(void)\r
1251 {\r
1252         byte    a,v;\r
1253         word    w;\r
1254 \r
1255         a=v=0;\r
1256 \r
1257         if (!sqActive)\r
1258                 return;\r
1259 \r
1260         while (sqHackLen && (sqHackTime <= alTimeCount))\r
1261         {\r
1262                 w = *sqHackPtr++;\r
1263                 sqHackTime = alTimeCount + *sqHackPtr++;\r
1264         asm     mov     dx,[w]\r
1265         asm     mov     [a],dl\r
1266         asm     mov     [v],dh\r
1267                 alOut(a,v);\r
1268                 sqHackLen -= 4;\r
1269         }\r
1270         alTimeCount++;\r
1271         if (!sqHackLen)\r
1272         {\r
1273                 sqHackPtr = (word far *)sqHack;\r
1274                 sqHackLen = sqHackSeqLen;\r
1275                 alTimeCount = sqHackTime = 0;\r
1276         }\r
1277 }\r
1278 //#endif\r
1279 \r
1280 ///////////////////////////////////////////////////////////////////////////\r
1281 //\r
1282 //      SDL_ShutAL() - Shuts down the AdLib card for sound effects\r
1283 //\r
1284 ///////////////////////////////////////////////////////////////////////////\r
1285 static void\r
1286 SDL_ShutAL(void)\r
1287 {\r
1288 asm     pushf\r
1289 asm     cli\r
1290 \r
1291         alOut(alEffects,0);\r
1292         alOut(alFreqH + 0,0);\r
1293         SDL_AlSetFXInst(&alZeroInst);\r
1294         alSound = 0;\r
1295 \r
1296 asm     popf\r
1297 }\r
1298 \r
1299 ///////////////////////////////////////////////////////////////////////////\r
1300 //\r
1301 //      SDL_CleanAL() - Totally shuts down the AdLib card\r
1302 //\r
1303 ///////////////////////////////////////////////////////////////////////////\r
1304 static void\r
1305 SDL_CleanAL(void)\r
1306 {\r
1307         int     i;\r
1308 \r
1309 asm     pushf\r
1310 asm     cli\r
1311 \r
1312         alOut(alEffects,0);\r
1313         for (i = 1;i < 0xf5;i++)\r
1314                 alOut(i,0);\r
1315 \r
1316 asm     popf\r
1317 }\r
1318 \r
1319 ///////////////////////////////////////////////////////////////////////////\r
1320 //\r
1321 //      SDL_StartAL() - Starts up the AdLib card for sound effects\r
1322 //\r
1323 ///////////////////////////////////////////////////////////////////////////\r
1324 static void\r
1325 SDL_StartAL(void)\r
1326 {\r
1327         alFXReg = 0;\r
1328         alOut(alEffects,alFXReg);\r
1329         SDL_AlSetFXInst(&alZeroInst);\r
1330 }\r
1331 \r
1332 ///////////////////////////////////////////////////////////////////////////\r
1333 //\r
1334 //      SDL_DetectAdLib() - Determines if there's an AdLib (or SoundBlaster\r
1335 //              emulating an AdLib) present\r
1336 //\r
1337 ///////////////////////////////////////////////////////////////////////////\r
1338 static boolean\r
1339 SDL_DetectAdLib(void)\r
1340 {\r
1341         byte    status1,status2;\r
1342         int             i;\r
1343 \r
1344         alOut(4,0x60);  // Reset T1 & T2\r
1345         alOut(4,0x80);  // Reset IRQ\r
1346         status1 = readstat();\r
1347         alOut(2,0xff);  // Set timer 1\r
1348         alOut(4,0x21);  // Start timer 1\r
1349         SDL_Delay(TimerDelay100);\r
1350 \r
1351 #if 0\r
1352         __asm {\r
1353                 mov     dx,0x388\r
1354                 mov     cx,100\r
1355 #ifdef __BORLANDC__\r
1356         }\r
1357 #endif\r
1358 usecloop:\r
1359 #ifdef __BORLANDC__\r
1360         __asm {\r
1361 #endif\r
1362         in      al,dx\r
1363         loop usecloop\r
1364         }\r
1365 #endif\r
1366 \r
1367         status2 = readstat();\r
1368         alOut(4,0x60);\r
1369         alOut(4,0x80);\r
1370 \r
1371         if (((status1 & 0xe0) == 0x00) && ((status2 & 0xe0) == 0xc0))\r
1372         {\r
1373                 for (i = 1;i <= 0xf5;i++)       // Zero all the registers\r
1374                         alOut(i,0);\r
1375 \r
1376                 alOut(1,0x20);  // Set WSE=1\r
1377                 alOut(8,0);             // Set CSM=0 & SEL=0\r
1378 \r
1379                 return(true);\r
1380         }\r
1381         else\r
1382                 return(false);\r
1383 }\r
1384 \r
1385 ///////////////////////////////////////////////////////////////////////////\r
1386 //\r
1387 //      SDL_t0Service() - My timer 0 ISR which handles the different timings and\r
1388 //              dispatches to whatever other routines are appropriate\r
1389 //\r
1390 ///////////////////////////////////////////////////////////////////////////\r
1391 //static void interrupt\r
1392 void interrupt\r
1393 SDL_t0Service(void)\r
1394 {\r
1395 static  word    count = 1;\r
1396         boolean myackflag = 0;\r
1397 \r
1398 //00#if 0       // for debugging\r
1399 asm     mov     dx,STATUS_REGISTER_1\r
1400 asm     in      al,dx\r
1401 asm     mov     dx,ATR_INDEX\r
1402 asm     mov     al,ATR_OVERSCAN\r
1403 asm     out     dx,al\r
1404 asm     mov     al,4    // red\r
1405 asm     out     dx,al\r
1406 //00#endif\r
1407 \r
1408         HackCount++;\r
1409 \r
1410         if ((MusicMode == smm_AdLib) || (DigiMode == sds_SoundSource))\r
1411         {\r
1412                 SDL_ALService();\r
1413 //SS            SDL_SSService();\r
1414 //              if (!(++count & 7))\r
1415                 if (!(++count % 10))\r
1416                 {\r
1417                         LocalTime++;\r
1418                         TimeCount++;\r
1419                         if (SoundUserHook)\r
1420                                 SoundUserHook();\r
1421                 }\r
1422 //              if (!(count & 3))\r
1423                 if (!(count % 5))\r
1424                 {\r
1425                         switch (SoundMode)\r
1426                         {\r
1427                         case sdm_PC:\r
1428                                 SDL_PCService();\r
1429                                 break;\r
1430                         case sdm_AdLib:\r
1431                                 SDL_ALSoundService();\r
1432                                 break;\r
1433                         }\r
1434                 }\r
1435         }\r
1436         else\r
1437         {\r
1438                 if (!(++count & 1))\r
1439                 {\r
1440                         LocalTime++;\r
1441                         TimeCount++;\r
1442                         if (SoundUserHook)\r
1443                                 SoundUserHook();\r
1444                 }\r
1445                 switch (SoundMode)\r
1446                 {\r
1447                 case sdm_PC:\r
1448                         SDL_PCService();\r
1449                         break;\r
1450                 case sdm_AdLib:\r
1451                         SDL_ALSoundService();\r
1452                         break;\r
1453                 }\r
1454         }\r
1455 \r
1456         __asm {\r
1457                 mov     ax,[WORD PTR TimerCount]\r
1458                 add     ax,[WORD PTR TimerDivisor]\r
1459                 mov     [WORD PTR TimerCount],ax\r
1460                 jnc     myack\r
1461                 jmp end1\r
1462 #ifdef __BORLANDC__\r
1463         }\r
1464 #endif\r
1465 myack:\r
1466 #ifdef __BORLANDC__\r
1467         __asm {\r
1468 #endif\r
1469                 mov     myackflag,1\r
1470 #ifdef __BORLANDC__\r
1471         }\r
1472 #endif\r
1473 end1:\r
1474 #ifdef __WATCOMC__\r
1475         }\r
1476 #endif\r
1477         if(!myackflag)\r
1478                 t0OldService();                 // If we overflow a word, time to call old int handler\r
1479         else\r
1480                 outportb(0x20,0x20);    // Ack the interrupt\r
1481 \r
1482 //00#if 0       // for debugging\r
1483 asm     mov     dx,STATUS_REGISTER_1\r
1484 asm     in      al,dx\r
1485 asm     mov     dx,ATR_INDEX\r
1486 asm     mov     al,ATR_OVERSCAN\r
1487 asm     out     dx,al\r
1488 asm     mov     al,3    // blue\r
1489 asm     out     dx,al\r
1490 asm     mov     al,0x20 // normal\r
1491 asm     out     dx,al\r
1492 //00#endif\r
1493 }\r
1494 \r
1495 ////////////////////////////////////////////////////////////////////////////\r
1496 //\r
1497 //      SDL_ShutDevice() - turns off whatever device was being used for sound fx\r
1498 //\r
1499 ////////////////////////////////////////////////////////////////////////////\r
1500 static void\r
1501 SDL_ShutDevice(void)\r
1502 {\r
1503         switch (SoundMode)\r
1504         {\r
1505         case sdm_PC:\r
1506                 SDL_ShutPC();\r
1507                 break;\r
1508         case sdm_AdLib:\r
1509                 SDL_ShutAL();\r
1510                 break;\r
1511         }\r
1512         SoundMode = sdm_Off;\r
1513 }\r
1514 \r
1515 ///////////////////////////////////////////////////////////////////////////\r
1516 //\r
1517 //      SDL_CleanDevice() - totally shuts down all sound devices\r
1518 //\r
1519 ///////////////////////////////////////////////////////////////////////////\r
1520 static void\r
1521 SDL_CleanDevice(void)\r
1522 {\r
1523         if ((SoundMode == sdm_AdLib) || (MusicMode == smm_AdLib))\r
1524                 SDL_CleanAL();\r
1525 }\r
1526 \r
1527 ///////////////////////////////////////////////////////////////////////////\r
1528 //\r
1529 //      SDL_StartDevice() - turns on whatever device is to be used for sound fx\r
1530 //\r
1531 ///////////////////////////////////////////////////////////////////////////\r
1532 static void\r
1533 SDL_StartDevice(void)\r
1534 {\r
1535         switch (SoundMode)\r
1536         {\r
1537         case sdm_AdLib:\r
1538                 SDL_StartAL();\r
1539                 break;\r
1540         }\r
1541         SoundNumber = SoundPriority = 0;\r
1542 }\r
1543 #if 0\r
1544 static void\r
1545 SDL_SetTimerSpeed(void)\r
1546 {\r
1547         word    rate;\r
1548 \r
1549         if (MusicMode == smm_AdLib)\r
1550                 rate = TickBase * 8;\r
1551         else\r
1552                 rate = TickBase * 2;\r
1553         SDL_SetIntsPerSec(rate);\r
1554 }\r
1555 #endif\r
1556 //      Public routines\r
1557 \r
1558 ///////////////////////////////////////////////////////////////////////////\r
1559 //\r
1560 //      SD_SetSoundMode() - Sets which sound hardware to use for sound effects\r
1561 //\r
1562 ///////////////////////////////////////////////////////////////////////////\r
1563 boolean\r
1564 SD_SetSoundMode(SDMode mode, global_game_variables_t *gvar)\r
1565 {\r
1566         boolean result = false;\r
1567         word    tableoffset;\r
1568 \r
1569         SD_StopSound(gvar);\r
1570 \r
1571 #ifndef _MUSE_\r
1572         if ((mode == sdm_AdLib) && !AdLibPresent)\r
1573                 mode = sdm_PC;\r
1574 \r
1575         switch (mode)\r
1576         {\r
1577         case sdm_Off:\r
1578                 NeedsDigitized = false;\r
1579                 result = true;\r
1580                 break;\r
1581         case sdm_PC:\r
1582                 tableoffset = STARTPCSOUNDS;\r
1583                 NeedsDigitized = false;\r
1584                 result = true;\r
1585                 break;\r
1586         case sdm_AdLib:\r
1587                 if (AdLibPresent)\r
1588                 {\r
1589                         tableoffset = STARTADLIBSOUNDS;\r
1590                         NeedsDigitized = false;\r
1591                         result = true;\r
1592                 }\r
1593                 break;\r
1594         }\r
1595 #else\r
1596         result = true;\r
1597 #endif\r
1598 \r
1599         if (result && (mode != SoundMode))\r
1600         {\r
1601                 SDL_ShutDevice();\r
1602                 SoundMode = mode;\r
1603 #ifndef _MUSE_\r
1604                 SoundTable = (word *)(&gvar->ca.audiosegs[tableoffset]);\r
1605 #endif\r
1606                 SDL_StartDevice();\r
1607         }\r
1608 \r
1609         SDL_SetTimerSpeed();\r
1610 \r
1611         return(result);\r
1612 }\r
1613 \r
1614 ///////////////////////////////////////////////////////////////////////////\r
1615 //\r
1616 //      SD_SetMusicMode() - sets the device to use for background music\r
1617 //\r
1618 ///////////////////////////////////////////////////////////////////////////\r
1619 boolean\r
1620 SD_SetMusicMode(SMMode mode)\r
1621 {\r
1622         boolean result = false;\r
1623 \r
1624         SD_FadeOutMusic();\r
1625         while (SD_MusicPlaying())\r
1626                 ;\r
1627 \r
1628         switch (mode)\r
1629         {\r
1630         case smm_Off:\r
1631                 NeedsMusic = false;\r
1632                 result = true;\r
1633                 break;\r
1634         case smm_AdLib:\r
1635                 if (AdLibPresent)\r
1636                 {\r
1637                         NeedsMusic = true;\r
1638                         result = true;\r
1639                 }\r
1640                 break;\r
1641         }\r
1642 \r
1643         if (result)\r
1644                 MusicMode = mode;\r
1645 \r
1646         SDL_SetTimerSpeed();\r
1647 \r
1648         return(result);\r
1649 }\r
1650 \r
1651 ///////////////////////////////////////////////////////////////////////////\r
1652 //\r
1653 //      SD_Startup() - starts up the Sound Mgr\r
1654 //              Detects all additional sound hardware and installs my ISR\r
1655 //\r
1656 ///////////////////////////////////////////////////////////////////////////\r
1657 void\r
1658 SD_Startup(global_game_variables_t *gvar)\r
1659 {\r
1660         int     i;\r
1661 \r
1662         if (SD_Started)\r
1663                 return;\r
1664 #ifndef SD_USECATA3DSETTIMERSPEED\r
1665 //      SDL_SetDS();\r
1666 #endif\r
1667         ssIsTandy = false;\r
1668 //SS    ssNoCheck = false;\r
1669         alNoCheck = false;\r
1670 //SB    sbNoCheck = false;\r
1671 //SB    sbNoProCheck = false;\r
1672 #ifndef _MUSE_\r
1673         for (i = 1;i < _argc;i++)\r
1674         {\r
1675                 switch (US_CheckParm(_argv[i],ParmStrings))\r
1676                 {\r
1677                 case 0:                                         // No AdLib detection\r
1678                         alNoCheck = true;\r
1679                         break;\r
1680 //SB            case 1:                                         // No SoundBlaster detection\r
1681 //SB                    sbNoCheck = true;\r
1682 //SB                    break;\r
1683 //SB            case 2:                                         // No SoundBlaster Pro detection\r
1684 //SB                    sbNoProCheck = true;\r
1685 //SB                    break;\r
1686 //SS            case 3:\r
1687 //SS                    ssNoCheck = true;               // No Sound Source detection\r
1688 //SS                    break;\r
1689                 case 4:                                         // Tandy Sound Source handling\r
1690                         ssIsTandy = true;\r
1691                         break;\r
1692 //SS            case 5:                                         // Sound Source present at LPT1\r
1693 //SS                    ssPort = 1;\r
1694 //SS                    ssNoCheck = SoundSourcePresent = true;\r
1695 //SS                    break;\r
1696 //SS            case 6:                     // Sound Source present at LPT2\r
1697 //SS                    ssPort = 2;\r
1698 //SS                    ssNoCheck = SoundSourcePresent = true;\r
1699 //SS                    break;\r
1700 //SS            case 7:                     // Sound Source present at LPT3\r
1701 //SS                    ssPort = 3;\r
1702 //SS                    ssNoCheck = SoundSourcePresent = true;\r
1703 //SS                    break;\r
1704                 }\r
1705         }\r
1706 #endif\r
1707 \r
1708         SoundUserHook = 0;\r
1709 \r
1710         t0OldService = getvect(8);      // Get old timer 0 ISR\r
1711 #ifdef SD_USECATA3DSETTIMERSPEED\r
1712 //++++  SDL_InitDelay();                        // SDL_InitDelay() uses t0OldService\r
1713 \r
1714         setvect(8,SDL_t0Service);       // Set to my timer 0 ISR\r
1715 #endif\r
1716         LocalTime = TimeCount = alTimeCount = 0;\r
1717 \r
1718         SD_SetSoundMode(sdm_Off, gvar);\r
1719         SD_SetMusicMode(smm_Off);\r
1720 \r
1721 //SS    if (!ssNoCheck)\r
1722 //SS            SoundSourcePresent = SDL_DetectSoundSource();\r
1723 \r
1724         if (!alNoCheck)\r
1725         {\r
1726                 AdLibPresent = SDL_DetectAdLib();\r
1727 //SB            if (AdLibPresent) && !sbNoCheck)\r
1728 //SB            {\r
1729 //SB                    int port = -1;\r
1730 //SB                    char *env = getenv("BLASTER");\r
1731 //SB                    if (env)\r
1732 //SB                    {\r
1733 //SB                            long temp;\r
1734 //SB                            while (*env)\r
1735 //SB                            {\r
1736 //SB                                    while (isspace(*env))\r
1737 //SB                                            env++;\r
1738 //SB\r
1739 //SB                                    switch (toupper(*env))\r
1740 //SB                                    {\r
1741 //SB                                    case 'A':\r
1742 //SB                                            temp = strtol(env + 1,&env,16);\r
1743 //SB                                            if\r
1744 //SB                                            (\r
1745 //SB                                                    (temp >= 0x210)\r
1746 //SB                                            &&      (temp <= 0x260)\r
1747 //SB                                            &&      (!(temp & 0x00f))\r
1748 //SB                                            )\r
1749 //SB                                                    port = (temp - 0x200) >> 4;\r
1750 //SB                                            else\r
1751 //SB                                                    Quit(gvar, "SD_Startup: Unsupported address value in BLASTER");\r
1752 //SB                                            break;\r
1753 //SB                                    case 'I':\r
1754 //SB                                            temp = strtol(env + 1,&env,10);\r
1755 //SB                                            if\r
1756 //SB                                            (\r
1757 //SB                                                    (temp >= 0)\r
1758 //SB                                            &&      (temp <= 10)\r
1759 //SB                                            &&      (sbIntVectors[temp] != -1)\r
1760 //SB                                            )\r
1761 //SB                                            {\r
1762 //SB                                                    sbInterrupt = temp;\r
1763 //SB                                                    sbIntVec = sbIntVectors[sbInterrupt];\r
1764 //SB                                            }\r
1765 //SB                                            else\r
1766 //SB                                                    Quit(gvar, "SD_Startup: Unsupported interrupt value in BLASTER");\r
1767 //SB                                            break;\r
1768 //SB                                    case 'D':\r
1769 //SB                                            temp = strtol(env + 1,&env,10);\r
1770 //SB                                            if ((temp == 0) || (temp == 1) || (temp == 3))\r
1771 //SB                                                    SDL_SBSetDMA(temp);\r
1772 //SB                                            else\r
1773 //SB                                                    Quit(gvar, "SD_Startup: Unsupported DMA value in BLASTER");\r
1774 //SB                                            break;\r
1775 //SB                                    default:\r
1776 //SB                                            while (isspace(*env))\r
1777 //SB                                                    env++;\r
1778 //SB                                            while (*env && !isspace(*env))\r
1779 //SB                                                    env++;\r
1780 //SB                                            break;\r
1781 //SB                                    }\r
1782 //SB                            }\r
1783 //SB                    }\r
1784 //SB                    SoundBlasterPresent = SDL_DetectSoundBlaster(port);\r
1785 //SB            }\r
1786         }\r
1787 \r
1788         for (i = 0;i < 255;i++)\r
1789                 pcSoundLookup[i] = i * 60;\r
1790 \r
1791 //SB    if (SoundBlasterPresent)\r
1792 //SB            SDL_StartSB();\r
1793 \r
1794 //++++  SDL_SetupDigi(gvar);\r
1795 \r
1796         SD_Started = true;\r
1797 }\r
1798 \r
1799 ///////////////////////////////////////////////////////////////////////////\r
1800 //\r
1801 //      SD_Default() - Sets up the default behaviour for the Sound Mgr whether\r
1802 //              the config file was present or not.\r
1803 //\r
1804 ///////////////////////////////////////////////////////////////////////////\r
1805 void\r
1806 SD_Default(boolean gotit,SDMode sd,SMMode sm, global_game_variables_t *gvar)\r
1807 {\r
1808         boolean gotsd,gotsm;\r
1809 \r
1810         gotsd = gotsm = gotit;\r
1811 \r
1812         if (gotsd)      // Make sure requested sound hardware is available\r
1813         {\r
1814                 switch (sd)\r
1815                 {\r
1816                 case sdm_AdLib:\r
1817                         gotsd = AdLibPresent;\r
1818                         break;\r
1819                 }\r
1820         }\r
1821         if (!gotsd)\r
1822         {\r
1823                 if (AdLibPresent)\r
1824                         sd = sdm_AdLib;\r
1825                 else\r
1826                         sd = sdm_PC;\r
1827         }\r
1828         if (sd != SoundMode)\r
1829                 SD_SetSoundMode(sd, gvar);\r
1830 \r
1831 \r
1832         if (gotsm)      // Make sure requested music hardware is available\r
1833         {\r
1834                 switch (sm)\r
1835                 {\r
1836                 case sdm_AdLib:\r
1837                         gotsm = AdLibPresent;\r
1838                         break;\r
1839                 }\r
1840         }\r
1841         if (!gotsm)\r
1842         {\r
1843                 if (AdLibPresent)\r
1844                         sm = smm_AdLib;\r
1845         }\r
1846         if (sm != MusicMode)\r
1847                 SD_SetMusicMode(sm);\r
1848 }\r
1849 \r
1850 ///////////////////////////////////////////////////////////////////////////\r
1851 //\r
1852 //      SD_Shutdown() - shuts down the Sound Mgr\r
1853 //              Removes sound ISR and turns off whatever sound hardware was active\r
1854 //\r
1855 ///////////////////////////////////////////////////////////////////////////\r
1856 void\r
1857 SD_Shutdown(global_game_variables_t *gvar)\r
1858 {\r
1859         if (!SD_Started)\r
1860                 return;\r
1861 \r
1862         SD_MusicOff();\r
1863         SD_StopSound(gvar);\r
1864         SDL_ShutDevice();\r
1865         SDL_CleanDevice();\r
1866 \r
1867 //SB    if (SoundBlasterPresent)\r
1868 //SB            SDL_ShutSB();\r
1869 \r
1870 //SS    if (SoundSourcePresent)\r
1871 //SS            SDL_ShutSS();\r
1872 \r
1873         asm     pushf\r
1874         asm     cli\r
1875 \r
1876         SDL_SetTimer0(0);\r
1877 \r
1878         setvect(8,t0OldService);\r
1879 \r
1880         asm     popf\r
1881 \r
1882         SD_Started = false;\r
1883 }\r
1884 \r
1885 ///////////////////////////////////////////////////////////////////////////\r
1886 //\r
1887 //      SD_SetUserHook() - sets the routine that the Sound Mgr calls every 1/70th\r
1888 //              of a second from its timer 0 ISR\r
1889 //\r
1890 ///////////////////////////////////////////////////////////////////////////\r
1891 void\r
1892 SD_SetUserHook(void (* hook)(void))\r
1893 {\r
1894         SoundUserHook = hook;\r
1895 }\r
1896 \r
1897 ///////////////////////////////////////////////////////////////////////////\r
1898 //\r
1899 //      SD_PositionSound() - Sets up a stereo imaging location for the next\r
1900 //              sound to be played. Each channel ranges from 0 to 15.\r
1901 //\r
1902 ///////////////////////////////////////////////////////////////////////////\r
1903 void\r
1904 SD_PositionSound(int leftvol,int rightvol)\r
1905 {\r
1906         LeftPosition = leftvol;\r
1907         RightPosition = rightvol;\r
1908         nextsoundpos = true;\r
1909 }\r
1910 \r
1911 ///////////////////////////////////////////////////////////////////////////\r
1912 //\r
1913 //      SD_PlaySound() - plays the specified sound on the appropriate hardware\r
1914 //\r
1915 ///////////////////////////////////////////////////////////////////////////\r
1916 boolean\r
1917 SD_PlaySound(soundnames sound, global_game_variables_t *gvar)\r
1918 {\r
1919         boolean         ispos;\r
1920         SoundCommon     far *s;\r
1921         int     lp,rp;\r
1922 \r
1923         lp = LeftPosition;\r
1924         rp = RightPosition;\r
1925         LeftPosition = 0;\r
1926         RightPosition = 0;\r
1927 \r
1928         ispos = nextsoundpos;\r
1929         nextsoundpos = false;\r
1930 \r
1931         if (sound == -1)\r
1932                 return(false);\r
1933 \r
1934         s = MK_FP(SoundTable[sound],0);\r
1935         if ((SoundMode != sdm_Off) && !s)\r
1936                 Quit(gvar, "SD_PlaySound() - Uncached sound");\r
1937 \r
1938         if ((DigiMode != sds_Off) && (DigiMap[sound] != -1))\r
1939         {\r
1940                 if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))\r
1941                 {\r
1942                         if (s->priority < SoundPriority)\r
1943                                 return(false);\r
1944 \r
1945                         SDL_PCStopSound();\r
1946 \r
1947                         SD_PlayDigitized(DigiMap[sound],lp,rp, gvar);\r
1948                         SoundPositioned = ispos;\r
1949                         SoundNumber = sound;\r
1950                         SoundPriority = s->priority;\r
1951                 }\r
1952                 else\r
1953                 {\r
1954                 asm     pushf\r
1955                 asm     cli\r
1956                         if (DigiPriority && !DigiNumber)\r
1957                         {\r
1958                         asm     popf\r
1959                                 Quit(gvar, "SD_PlaySound: Priority without a sound");\r
1960                         }\r
1961                 asm     popf\r
1962 \r
1963                         if (s->priority < DigiPriority)\r
1964                                 return(false);\r
1965 \r
1966                         SD_PlayDigitized(DigiMap[sound],lp,rp, gvar);\r
1967                         SoundPositioned = ispos;\r
1968                         DigiNumber = sound;\r
1969                         DigiPriority = s->priority;\r
1970                 }\r
1971 \r
1972                 return(true);\r
1973         }\r
1974 \r
1975         if (SoundMode == sdm_Off)\r
1976                 return(false);\r
1977         if (!s->length)\r
1978                 Quit(gvar, "SD_PlaySound() - Zero length sound");\r
1979         if (s->priority < SoundPriority)\r
1980                 return(false);\r
1981 \r
1982         switch (SoundMode)\r
1983         {\r
1984         case sdm_PC:\r
1985                 SDL_PCPlaySound((void far *)s);\r
1986                 break;\r
1987         case sdm_AdLib:\r
1988                 SDL_ALPlaySound((void far *)s, gvar);\r
1989                 break;\r
1990         }\r
1991 \r
1992         SoundNumber = sound;\r
1993         SoundPriority = s->priority;\r
1994 \r
1995         return(false);\r
1996 }\r
1997 \r
1998 ///////////////////////////////////////////////////////////////////////////\r
1999 //\r
2000 //      SD_SoundPlaying() - returns the sound number that's playing, or 0 if\r
2001 //              no sound is playing\r
2002 //\r
2003 ///////////////////////////////////////////////////////////////////////////\r
2004 word\r
2005 SD_SoundPlaying(void)\r
2006 {\r
2007         boolean result = false;\r
2008 \r
2009         switch (SoundMode)\r
2010         {\r
2011         case sdm_PC:\r
2012                 result = pcSound? true : false;\r
2013                 break;\r
2014         case sdm_AdLib:\r
2015                 result = alSound? true : false;\r
2016                 break;\r
2017         }\r
2018 \r
2019         if (result)\r
2020                 return(SoundNumber);\r
2021         else\r
2022                 return(false);\r
2023 }\r
2024 \r
2025 ///////////////////////////////////////////////////////////////////////////\r
2026 //\r
2027 //      SD_StopSound() - if a sound is playing, stops it\r
2028 //\r
2029 ///////////////////////////////////////////////////////////////////////////\r
2030 void\r
2031 SD_StopSound(global_game_variables_t *gvar)\r
2032 {\r
2033         if (DigiPlaying)\r
2034                 SD_StopDigitized(gvar);\r
2035 \r
2036         switch (SoundMode)\r
2037         {\r
2038         case sdm_PC:\r
2039                 SDL_PCStopSound();\r
2040                 break;\r
2041         case sdm_AdLib:\r
2042                 SDL_ALStopSound();\r
2043                 break;\r
2044         }\r
2045 \r
2046         SoundPositioned = false;\r
2047 \r
2048         SDL_SoundFinished();\r
2049 }\r
2050 \r
2051 ///////////////////////////////////////////////////////////////////////////\r
2052 //\r
2053 //      SD_WaitSoundDone() - waits until the current sound is done playing\r
2054 //\r
2055 ///////////////////////////////////////////////////////////////////////////\r
2056 void\r
2057 SD_WaitSoundDone(void)\r
2058 {\r
2059         while (SD_SoundPlaying())\r
2060                 ;\r
2061 }\r
2062 \r
2063 ///////////////////////////////////////////////////////////////////////////\r
2064 //\r
2065 //      SD_MusicOn() - turns on the sequencer\r
2066 //\r
2067 ///////////////////////////////////////////////////////////////////////////\r
2068 void\r
2069 SD_MusicOn(void)\r
2070 {\r
2071         sqActive = true;\r
2072 }\r
2073 \r
2074 ///////////////////////////////////////////////////////////////////////////\r
2075 //\r
2076 //      SD_MusicOff() - turns off the sequencer and any playing notes\r
2077 //\r
2078 ///////////////////////////////////////////////////////////////////////////\r
2079 void\r
2080 SD_MusicOff(void)\r
2081 {\r
2082         word    i;\r
2083 \r
2084 \r
2085         switch (MusicMode)\r
2086         {\r
2087         case smm_AdLib:\r
2088                 alFXReg = 0;\r
2089                 alOut(alEffects,0);\r
2090                 for (i = 0;i < sqMaxTracks;i++)\r
2091                         alOut(alFreqH + i + 1,0);\r
2092                 break;\r
2093         }\r
2094         sqActive = false;\r
2095 }\r
2096 \r
2097 ///////////////////////////////////////////////////////////////////////////\r
2098 //\r
2099 //      SD_StartMusic() - starts playing the music pointed to\r
2100 //\r
2101 ///////////////////////////////////////////////////////////////////////////\r
2102 void\r
2103 SD_StartMusic(MusicGroup far *music)\r
2104 {\r
2105         SD_MusicOff();\r
2106 asm     pushf\r
2107 asm     cli\r
2108 \r
2109         if (MusicMode == smm_AdLib)\r
2110         {\r
2111                 sqHackPtr = sqHack = music->values;\r
2112                 sqHackSeqLen = sqHackLen = music->length;\r
2113                 sqHackTime = 0;\r
2114                 alTimeCount = 0;\r
2115                 SD_MusicOn();\r
2116         }\r
2117 \r
2118 asm     popf\r
2119 }\r
2120 \r
2121 ///////////////////////////////////////////////////////////////////////////\r
2122 //\r
2123 //      SD_FadeOutMusic() - starts fading out the music. Call SD_MusicPlaying()\r
2124 //              to see if the fadeout is complete\r
2125 //\r
2126 ///////////////////////////////////////////////////////////////////////////\r
2127 void\r
2128 SD_FadeOutMusic(void)\r
2129 {\r
2130         switch (MusicMode)\r
2131         {\r
2132         case smm_AdLib:\r
2133                 // DEBUG - quick hack to turn the music off\r
2134                 SD_MusicOff();\r
2135                 break;\r
2136         }\r
2137 }\r
2138 \r
2139 ///////////////////////////////////////////////////////////////////////////\r
2140 //\r
2141 //      SD_MusicPlaying() - returns true if music is currently playing, false if\r
2142 //              not\r
2143 //\r
2144 ///////////////////////////////////////////////////////////////////////////\r
2145 boolean\r
2146 SD_MusicPlaying(void)\r
2147 {\r
2148         boolean result;\r
2149 \r
2150         switch (MusicMode)\r
2151         {\r
2152         case smm_AdLib:\r
2153                 result = false;\r
2154                 // DEBUG - not written\r
2155                 break;\r
2156         default:\r
2157                 result = false;\r
2158         }\r
2159 \r
2160         return(result);\r
2161 }\r
2162 \r
2163 //#if 0\r
2164 //\r
2165 // SD ASS!\r
2166 //\r
2167 \r
2168 //variables for these assembly functions\r
2169 volatile boolean pcindicate;\r
2170 volatile unsigned/*boolean*/ MyDS;\r
2171 \r
2172 void SDL_SetDS()\r
2173 {\r
2174         __asm {\r
2175                 mov     ax,ds\r
2176                 mov     [cs:MyDS],ds\r
2177                 ret\r
2178         }\r
2179 }\r
2180 \r
2181 //\r
2182 \r
2183 // Timer 0 ISR for 7000Hz interrupts\r
2184 void interrupt SDL_t0ExtremeAsmService(void)\r
2185 {\r
2186         if(pcindicate)\r
2187         {\r
2188                 if(pcSound)\r
2189                 {\r
2190                         SDL_setPCSpeaker(((*pcSound++)&0x80)>>6);\r
2191                         pcLengthLeft--;\r
2192                         if(!pcLengthLeft)\r
2193                         {\r
2194                                 pcSound=0;\r
2195                                 SDL_turnOffPCSpeaker();\r
2196                                 SDL_DigitizedDoneInIRQ();\r
2197                         }\r
2198                 }\r
2199         }\r
2200         extreme++;\r
2201         if(extreme>=10)\r
2202         {\r
2203                 extreme=0;\r
2204                 SDL_DoFast();\r
2205         }\r
2206         else\r
2207                 outp(0x20,0x20);\r
2208 }\r
2209 \r
2210 //\r
2211 \r
2212 void SDL_IndicatePC(boolean ind)\r
2213 {\r
2214         pcindicate=ind;\r
2215 }\r
2216 \r
2217 void\r
2218 SDL_DigitizedDoneInIRQ(void)\r
2219 {\r
2220         if (DigiNextAddr)\r
2221         {\r
2222                 SDL_PlayDigiSegment(DigiNextAddr,DigiNextLen/*,true*/);\r
2223                 DigiNextAddr = nil;\r
2224                 DigiMissed = false;\r
2225         }\r
2226         else\r
2227         {\r
2228                 if (DigiLastSegment)\r
2229                 {\r
2230                         DigiPlaying = false;\r
2231                         DigiLastSegment = false;\r
2232                         if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))\r
2233                         {\r
2234                                 SDL_SoundFinished();\r
2235                         }\r
2236                         else\r
2237                         {\r
2238                                 DigiNumber = (soundnames) 0;\r
2239                                 DigiPriority = 0;\r
2240                         }\r
2241                         SoundPositioned = false;\r
2242                 }\r
2243                 else\r
2244                         DigiMissed = true;\r
2245         }\r
2246 }\r
2247 \r
2248 #if 0\r
2249 // Inside an interrupt handler interrupts should already be disabled\r
2250 // so don't disable them again and cause V86 exceptions which cost\r
2251 // aprox. 300 processor tics!\r
2252 \r
2253 //static\r
2254 void alOutInIRQ(byte n,byte b)\r
2255 {\r
2256         __asm {\r
2257                 mov     dx,0x388\r
2258                 mov     al,[n]\r
2259                 out     dx,al\r
2260                 in      al,dx\r
2261                 in      al,dx\r
2262                 in      al,dx\r
2263                 in      al,dx\r
2264                 in      al,dx\r
2265                 in      al,dx\r
2266                 inc     dx\r
2267                 mov     al,[b]\r
2268                 out     dx,al\r
2269 \r
2270                 dec     dx\r
2271                 in      al,dx\r
2272                 in      al,dx\r
2273                 in      al,dx\r
2274                 in      al,dx\r
2275                 in      al,dx\r
2276                 in      al,dx\r
2277                 in      al,dx\r
2278                 in      al,dx\r
2279                 in      al,dx\r
2280                 in      al,dx\r
2281 \r
2282                 in      al,dx\r
2283                 in      al,dx\r
2284                 in      al,dx\r
2285                 in      al,dx\r
2286                 in      al,dx\r
2287                 in      al,dx\r
2288                 in      al,dx\r
2289                 in      al,dx\r
2290                 in      al,dx\r
2291                 in      al,dx\r
2292 \r
2293                 in      al,dx\r
2294                 in      al,dx\r
2295                 in      al,dx\r
2296                 in      al,dx\r
2297                 in      al,dx\r
2298                 in      al,dx\r
2299                 in      al,dx\r
2300                 in      al,dx\r
2301                 in      al,dx\r
2302                 in      al,dx\r
2303 \r
2304                 in      al,dx\r
2305                 in      al,dx\r
2306                 in      al,dx\r
2307                 in      al,dx\r
2308                 in      al,dx\r
2309         }\r
2310 }\r
2311 #endif\r