home *** CD-ROM | disk | FTP | other *** search
/ C++ Games Programming / CPPGAMES.ISO / thx / source / utils / sfxplay.cpp < prev    next >
C/C++ Source or Header  |  1995-05-12  |  8KB  |  396 lines

  1. #include <fstream.h>
  2. #include <iomanip.h>
  3. #include <stdlib.h>
  4. #include <conio.h>
  5. #include <ctype.h>
  6. #include <dos.h>
  7. #include <dir.h>
  8. #include <alloc.h>
  9. #include <string.h>
  10. #include <io.h>
  11. #include <values.h>
  12. #include <fcntl.h>
  13.  
  14. const int TRUE  = 1;
  15. const int FALSE = 0;
  16. const int MAX = 100;
  17.  
  18. struct clip_info
  19.   {
  20.   long size;
  21.   char huge * data;
  22.   };
  23.  
  24. static clip_info clip[MAX];
  25.  
  26. void list_entries(char* libname,int count);
  27. int find_and_load_driver();
  28. int load_driver();
  29. void init_driver();
  30. void set_port(unsigned port);
  31. void set_status_flag(char* ptr);
  32. void terminate_driver();
  33. void play_clip(char huge *data);
  34. void print_version();
  35. void stop_clip();
  36.  
  37. unsigned port;
  38. unsigned hdma,ldma;
  39. int playing;
  40. char* realptr;
  41. char* driverptr;
  42.  
  43. int main(int argc,char** argv)
  44.   {
  45.   int i;
  46.   unsigned long mem_used;
  47.   //-----------------------------------------------------
  48.   // check for two arguments
  49.  
  50.   if (argc<2)
  51.     {
  52.     cout << "\nUSAGE : SFXPLAY <sfxlib>\n";
  53.     cout << "  SFXPLAY is a utility which loads an SFX (sound effects)\n";
  54.     cout << "  library, and allows the user to sample the entries.\n";
  55.     cout << "  The SFX file should have first been created with SFXMAKE.\n";
  56.     return -1;
  57.     }
  58.  
  59.   //--------------------------------------------------------
  60.   // make sure library exists
  61.  
  62.   if (access(argv[1],0)!=0)
  63.     {
  64.     cout << "can't find sfx file '" << argv[1] << "'\n";
  65.     return -1;
  66.     }
  67.  
  68.   //--------------------------------------------------------
  69.   // set up the sound card
  70.  
  71.   cout << "looking for sound card...\n";
  72.   int sound_supported=find_and_load_driver();
  73.   if (sound_supported)
  74.     {
  75.     init_driver();
  76.     set_port(port);
  77.     set_status_flag((char*)&playing);
  78.     cout << "sound card detected...\n";
  79.     }
  80.   else
  81.     {
  82.     cout << "sound card NOT detected...\n";
  83.     return -1;
  84.     }
  85.  
  86.   //---------------------------------------------------------
  87.   // read the sfx library
  88.  
  89.   int handle;
  90.   if (_dos_open(argv[1],O_RDONLY,&handle) != 0)
  91.     {
  92.     cerr << "No file named " << argv[1];
  93.     exit(1);
  94.     }
  95.   
  96.   
  97.   int count;
  98.   long size;
  99.   char far *buf;
  100.   unsigned chread;
  101.  
  102.   _dos_read(handle,(char*)&count,sizeof(count),&chread);
  103.   mem_used=0L;
  104.   for (i=0;i<count;i++)
  105.     {
  106.     _dos_read(handle,(char*)&size,sizeof(size),&chread);
  107.     clip[i].size=size;
  108.  
  109.     unsigned int paras = (unsigned) ((size+15) / 16);
  110.     unsigned int segment;
  111.     if (_dos_allocmem(paras, &segment) != 0)    {
  112.         cerr << "insufficient memory";
  113.         exit(1);
  114.     }
  115.     FP_SEG(buf) = segment;
  116.     FP_OFF(buf) = 0;
  117.  
  118.     char huge *fptr = (char huge *) buf;
  119.  
  120.     clip[i].data=buf;
  121.     mem_used+=size;
  122.  
  123.     do
  124.       {
  125.       int chs = MAXINT;
  126.       if (size < chs)
  127.         chs = (int)size;
  128.       _dos_read(handle,fptr,chs,&chread);
  129.       fptr += chread;
  130.       size -= chread;
  131.       } while (size > 0);
  132.  
  133.  
  134.     }
  135.  
  136.   _dos_close(handle);
  137.   //-----------------------------------------------------
  138.   // print out statistics
  139.  
  140.   list_entries(argv[1],count);
  141.  
  142.   //------------------------------------------------------
  143.   // play the requested clips in a loop
  144.  
  145.   char str[40];
  146.   char* p;
  147.   int num;
  148.   do{
  149.     query:;
  150.     cout << "> ";
  151.     cin >> str;
  152.     p=strchr(str,'\n');
  153.     if (p)  *p='\0';
  154.     p=strchr(str,' ');
  155.     if (p)  *p='\0';
  156.     if (stricmp(str,"exit")==0 || stricmp(str,"quit")==0)  break;
  157.     if (stricmp(str,"mem")==0 || stricmp(str,"memory")==0)
  158.       {
  159.       cout << "Memory in use: " << mem_used << '\n';
  160.       cout << "Memory left  : " << coreleft() << '\n';
  161.       goto query;
  162.       }
  163.     if (stricmp(str,"list")==0)
  164.       {
  165.       list_entries(argv[1],count);
  166.       goto query;
  167.       }
  168.     if (strlen(str)==0)
  169.       {
  170.       cout << "type \"list[ENTER]\" for help\n";
  171.       goto query;
  172.       }
  173.     p=str;
  174.     while (*p)
  175.       {
  176.       if (!((*p>='0' && *p<='9') || !*p))
  177.         {
  178.         cout << "type \"list[ENTER]\" for help\n";
  179.         goto query;
  180.         }
  181.       p++;
  182.       }
  183.     num=atoi(str);
  184.     if (num<1 || num>count)
  185.       cout << "request " << num << " out of range\n";
  186.     else
  187.       {
  188.       cout << "playing entry " << num
  189.            << " (" << clip[num-1].size << ") bytes\n";
  190.       play_clip(clip[num-1].data);
  191.       }
  192.     } while (1);     // tag
  193.  
  194.  
  195.   for (i=0;i<count;i++)
  196.     _dos_freemem(FP_SEG(clip[num-1].data));
  197.  
  198.   //------------------------------------------------
  199.   // shut down sound card
  200.  
  201.   terminate_driver();
  202.   delete realptr;
  203.   cout << "sound driver terminated...\n";
  204.   return 0;
  205.   }  // main
  206.  
  207.  
  208. //--------------------------------------------------
  209. // 'list_entries' simply reports the entry sizes
  210. //--------------------------------------------------
  211. void list_entries(char* libname,int count)
  212.   {
  213.   int i;
  214.  
  215.   cout << strupr(libname) << " contains " << count << " entries\n";
  216.   cout << "--------------------\n";
  217.   for (i=0;i<count;i++)
  218.     {
  219.     cout << (i+1) << ": " << clip[i].size << " bytes\n";
  220.     }
  221.   cout << "--------------------\n";
  222.   cout << "Type in a number, \"mem\", \"list\", or \"exit\", then press [ENTER]\n\n";
  223.   }
  224.  
  225. int find_and_load_driver()
  226.   {
  227.   char* t;
  228.   char* blaster;
  229.  
  230.   t=getenv("BLASTER");
  231.   if (!t)
  232.     {
  233.     cout << "  BLASTER environment variable not set\n";
  234.     return FALSE;
  235.     }
  236.  
  237.   blaster=strdup(t);
  238.   cout << blaster << '\n';
  239.   t=strtok(blaster," \t");
  240.   while (t)
  241.     {
  242.     switch (toupper(t[0]))
  243.       {
  244.       case 'A':
  245.         port=(int)strtol(t+1,0,16);
  246.         break;
  247.       case 'I':
  248.         //irq=atoi(t+1);
  249.         break;
  250.       case 'D':
  251.         ldma=atoi(t+1);
  252.         break;
  253.       case 'H':
  254.         hdma=atoi(t+1);
  255.         break;
  256.       case 'P':
  257.         //midiport=(int)strtol(t+1,0,16);
  258.         break;
  259.       case 'T':
  260.         //type=atoi(t+1);
  261.         break;
  262.       }
  263.     t=strtok(0," \t");
  264.     }
  265.   free(blaster);
  266.  
  267.   if (!load_driver())
  268.     return FALSE;
  269.  
  270.   return TRUE;
  271.   }
  272.  
  273. int load_driver()
  274.   {
  275.   static char driver[MAXPATH];
  276.   char* t;
  277.  
  278.   long size;
  279.   struct ffblk ffblk;
  280.  
  281.   t=getenv("SOUND");
  282.   if (!t)
  283.     {
  284.     cout << "  SOUND environment variable not set\n";
  285.     return FALSE;
  286.     }
  287.   strcpy(driver,t);
  288.   strcat(driver,"\\drv\\ct-voice.drv");
  289.   if (access(driver,0)!=0)
  290.     {
  291.     cout << "  can't find file [" << driver << "]\n";
  292.     return FALSE;
  293.     }
  294.  
  295.   findfirst(driver,&ffblk,0);
  296.   size=ffblk.ff_fsize;
  297.   realptr=new char[(int)size+16];
  298.   if (!realptr)  return FALSE;
  299.  
  300.   driverptr=(char*)MK_FP(FP_SEG(realptr)+1,0);
  301.     // force driveptr to point to a paragraph boundary
  302.  
  303.   ifstream dfile(driver,ios::binary);
  304.   dfile.read(driverptr,(int)size);
  305.   dfile.close();
  306.  
  307.   print_version();
  308.   return TRUE;
  309.   }
  310.  
  311. void set_port(unsigned port)
  312.   {
  313.   asm {
  314.     mov bx,1
  315.     mov ax,port
  316.     call driverptr
  317.     }
  318.   cout << "  using port " << setbase(16) << port
  319.                           << setbase(10) << '\n';
  320.   }
  321.  
  322. void set_status_flag(char* ptr)
  323.   {
  324.   unsigned segm = FP_SEG(ptr);
  325.   unsigned offm = FP_OFF(ptr);
  326.   asm {
  327.     mov bx,5
  328.     mov es,segm
  329.     mov di,offm
  330.     call driverptr
  331.     }
  332.   }
  333.  
  334. void init_driver()
  335.   {
  336.   int initstatus;
  337.   asm {
  338.     mov bx,3
  339.     call driverptr
  340.     mov initstatus,ax
  341.     }
  342.   }
  343.  
  344. void play_clip(char huge *data)
  345.   {
  346.   if (playing)
  347.     {
  348.     stop_clip();
  349.     cout << "current clip interrupted / starting new clip...\n";
  350.     }
  351.   if (data[0]!='C')  // 'C' for "Creative"
  352.     {
  353.     cout << "only VOC files are supported at this time!\n";
  354.     return;
  355.     }
  356.  
  357.   unsigned segm = FP_SEG(data);
  358.   unsigned offm = FP_OFF(data)+data[20];
  359.   asm {
  360.     mov bx,6
  361.     mov ax,segm
  362.     mov es,ax
  363.     mov di,offm
  364.     call driverptr
  365.     }
  366.   }
  367.  
  368. void terminate_driver()
  369.   {
  370.   asm {
  371.     mov bx,9
  372.     call driverptr
  373.     }
  374.   }
  375.  
  376. void print_version()
  377.   {
  378.   unsigned version;
  379.   asm {
  380.     mov bx,0
  381.     call driverptr
  382.     mov version,ax
  383.   }
  384.   unsigned major=((version>>8) & 0x0ff);
  385.   unsigned minor=(version&0x00ff);
  386.   cout << "  driver version: " << major << "." << minor << "\n";
  387.   }
  388.  
  389. void stop_clip()
  390.   {
  391.   asm {
  392.     mov bx,8
  393.     call driverptr
  394.     }
  395.   }
  396.