home *** CD-ROM | disk | FTP | other *** search
/ C++ Games Programming / CPPGAMES.ISO / thx / source / theatrix / vocal.cpp < prev    next >
C/C++ Source or Header  |  1995-05-30  |  6KB  |  323 lines

  1. #include <fstream.h>
  2. #include <iomanip.h>
  3. #include <values.h>    // MAXINT
  4. #include <io.h>
  5. #include <dir.h>
  6. #include <dos.h>
  7. #include <ctype.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include "theatrix.h"
  11. #include "vocal.h"
  12. #include "xms.h"
  13.  
  14. SoundMedia VocalHand::sfxlib;
  15.  
  16. VocalHand::Driver VocalHand::driver;
  17. static char far *realptr;
  18. static char far *driverptr;
  19. static char far *initptr;
  20. static char far *deinitptr;
  21. unsigned *VocalHand::isplaying;
  22. unsigned VocalHand::playing;
  23. unsigned VocalHand::port;
  24. unsigned VocalHand::irq;
  25.  
  26. void VocalHand::startup()
  27. {
  28.     cout << "looking for sound card...\n";
  29.     if ((driver=load_digpak_driver()) == nodriver)
  30.         driver = load_ct_voice_driver();
  31.     if (driver != nodriver)    {
  32.         if (driver == ctvoicedriver)    {
  33.             get_soundcard_settings();
  34.             set_port(port);
  35.             set_irq(irq);
  36.             init_driver();
  37.             if (driver != nodriver)    {
  38.                 cout << "CT-VOICE driver initialized...\n";
  39.                 set_status_flag((char*)&playing);
  40.                 return;
  41.             }
  42.         }
  43.         else if (driver == digpakdriver)    {
  44.             init_driver();
  45.             cout << "DIGPAK driver initialized...\n";
  46.             return;
  47.         }
  48.     }
  49.     cout << "sound driver not initialized...\n";
  50. }
  51.  
  52. void VocalHand::shutdown()
  53. {
  54.     if (driver != nodriver)    {
  55.         terminate_driver();
  56.         cout << "sound driver terminated...\n";
  57.     }
  58. }
  59.  
  60. void VocalHand::load_sfxlib(char* fname)
  61. {
  62.     sfxlib.load_library(fname);
  63.     set_sfxlib(fname);
  64. }
  65.  
  66. void VocalHand::set_sfxlib(char* fname)
  67. {
  68.     curlib=sfxlib.library_number(fname);
  69. }
  70.  
  71. void VocalHand::thxplay_sound_clip(int index)
  72. {
  73.     if (driver == nodriver)
  74.         return;
  75.  
  76.     MediaClip& mc = sfxlib.getclip(curlib,index-1);
  77.  
  78.     if (sound_clip_is_playing())
  79.         stop_sound_clip();
  80.  
  81.     if (driver == digpakdriver)    {
  82.         struct    {
  83.             char *clip;                // address of sample.
  84.             unsigned length;         // length of sample.
  85.             unsigned *isplaying;    // Address of play status flag.
  86.             unsigned samplrate;        // sampling rate
  87.         } snd;
  88.  
  89.         snd.clip = mc.buf+32;
  90.         snd.length = *(unsigned*)(mc.buf+27) - 2;
  91.         snd.isplaying = 0;
  92.         int sr = *(mc.buf+30) & 255;
  93.         snd.samplrate = (unsigned) (-1000000L / (sr - 256));
  94.  
  95.         unsigned segm = FP_SEG(&snd);
  96.         unsigned off = FP_OFF(&snd);
  97.  
  98.         asm {
  99.             push ds
  100.             push si
  101.             mov si,off
  102.             mov ax,segm
  103.             mov ds,ax
  104.             mov ax,0x68b
  105.             int 0x66
  106.             pop si
  107.             pop ds
  108.         }
  109.         isplaying = snd.isplaying;
  110.     }
  111.     else    {
  112.         char* data=mc.buf;
  113.         unsigned segm = FP_SEG(data);
  114.         unsigned offm = FP_OFF(data)+data[20];
  115.         asm {
  116.             mov bx,6
  117.             mov ax,segm
  118.             push es
  119.             push di
  120.             mov es,ax
  121.             mov di,offm
  122.             call driverptr
  123.             pop di
  124.             pop es
  125.         }
  126.         isplaying = &playing;
  127.     }
  128. }
  129.  
  130. void VocalHand::stop_sound_clip()
  131. {
  132.     if (driver == digpakdriver)    {
  133.         _AX = 0x68f;
  134.         geninterrupt(0x66);
  135.     }
  136.     else if (driver == ctvoicedriver)    {
  137.         asm    {
  138.             mov bx,8
  139.             call driverptr
  140.         }
  141.     }
  142.     isplaying = 0;
  143. }
  144.  
  145. int VocalHand::sound_clip_is_playing()
  146. {
  147.     return isplaying ? *isplaying : 0;
  148. }
  149.  
  150. int VocalHand::get_num_clips()
  151. {
  152.     return sfxlib.clipcount(curlib);
  153. }
  154.  
  155. VocalHand::Driver VocalHand::load_digpak_driver()
  156. {
  157.     long size;
  158.     struct ffblk ffblk;
  159.  
  160.     if (findfirst("soundrv.com",&ffblk,0) == -1)
  161.         return nodriver;
  162.     size=ffblk.ff_fsize;
  163.     realptr=new char[(int)size+16];
  164.  
  165.     driverptr=(char*)MK_FP(FP_SEG(realptr)+1,0);
  166.  
  167.     ifstream dfile("soundrv.com",ios::binary);
  168.     dfile.read(driverptr,(int)size);
  169.  
  170.     if (strncmp(driverptr+3, "DIGPAK", 6))    {
  171.         delete realptr;
  172.         realptr = 0;
  173.         return nodriver;
  174.     }
  175.  
  176.     initptr = (char*)MK_FP(FP_SEG(driverptr)-0x10, 0x200);
  177.     deinitptr = (char*)MK_FP(FP_SEG(driverptr)-0x10, 0x203);
  178.  
  179.     return digpakdriver;
  180. }
  181.  
  182. void VocalHand::get_soundcard_settings()
  183. {
  184.     char* t = getenv("BLASTER");
  185.     if (!t)    {
  186.         cout << "  BLASTER environment variable not set\n";
  187.         return;
  188.     }
  189.     cout << t << '\n';
  190.     t = strtok(t," \t");
  191.     while (t)
  192.     {
  193.         switch (toupper(t[0]))    {
  194.             case 'A':
  195.                 port=(int)strtol(t+1,0,16);
  196.                 break;
  197.             case 'I':
  198.                 irq=atoi(t+1);
  199.                 break;
  200.         }
  201.         t=strtok(0," \t");
  202.     }
  203. }
  204.  
  205. VocalHand::Driver VocalHand::load_ct_voice_driver()
  206. {
  207.     char driver[MAXPATH];
  208.     char cwd[MAXPATH];
  209.     int curdisk;
  210.     char* t;
  211.  
  212.     long size;
  213.     struct ffblk ffblk;
  214.  
  215.     t=getenv("SOUND");
  216.     if (!t)    {
  217.         cout << "  SOUND environment variable not set\n";
  218.         return nodriver;
  219.     }
  220.  
  221.     curdisk = getdisk();
  222.     getcwd(cwd, MAXPATH);
  223.  
  224.     if (*(t+1) == ':')
  225.         setdisk(tolower(*t) - 'a');
  226.  
  227.     strcpy(driver, t);
  228.     strcat(driver, "\\drv");
  229.     chdir(driver);
  230.  
  231.     if (findfirst("ct-voice.drv",&ffblk,0) == -1)    {
  232.         cout << "  can't find ct-voice.drv\n";
  233.         return nodriver;
  234.     }
  235.     size=ffblk.ff_fsize;
  236.     realptr=new char[(int)size+16];
  237.  
  238.     // force driveptr to point to a paragraph boundary
  239.     driverptr=(char*)MK_FP(FP_SEG(realptr)+1,0);
  240.  
  241.     ifstream dfile("ct-voice.drv",ios::binary);
  242.     dfile.read(driverptr,(int)size);
  243.  
  244.     setdisk(curdisk);
  245.     chdir(cwd);
  246.     return ctvoicedriver;
  247. }
  248.  
  249. void VocalHand::init_driver()
  250. {
  251.     unsigned drv = 1;
  252.     if (driver == digpakdriver)    {
  253.         asm    {
  254.             call initptr
  255.             mov drv,ax
  256.         }
  257.     }
  258.     else if (driver == ctvoicedriver)    {
  259.           asm {
  260.             mov bx,3
  261.             call driverptr
  262.             mov drv,ax
  263.            }
  264.  
  265.     }
  266.     if (drv)    {
  267.         driver = nodriver;
  268.         delete realptr;
  269.         realptr = 0;
  270.     }
  271. }
  272.  
  273. void VocalHand::terminate_driver()
  274. {
  275.     if (driver == digpakdriver)    {
  276.         asm {
  277.             call deinitptr
  278.         }
  279.     }
  280.     else if (driver == ctvoicedriver)    {
  281.         asm    {
  282.             mov bx,9
  283.             call driverptr
  284.         }
  285.     }
  286.     driver = nodriver;
  287.     delete realptr;
  288.     realptr = 0;
  289. }
  290.  
  291. void VocalHand::set_port(unsigned port)
  292. {
  293.     asm {
  294.         mov bx,1
  295.         mov ax,port
  296.         call driverptr
  297.     }
  298.     cout << "  using port " << setbase(16) << port
  299.                             << setbase(10) << '\n';
  300. }
  301.  
  302. void VocalHand::set_irq(unsigned irq)
  303. {
  304.     asm {
  305.         mov bx,2
  306.         mov ax,irq
  307.         call driverptr
  308.     }
  309.     cout << "  using irq " << irq << '\n';
  310. }
  311.  
  312. void VocalHand::set_status_flag(char* ptr)
  313. {
  314.     unsigned segm = FP_SEG(ptr);
  315.     unsigned offm = FP_OFF(ptr);
  316.     asm {
  317.         mov bx,5
  318.         mov es,segm
  319.         mov di,offm
  320.         call driverptr
  321.     }
  322. }
  323.