home *** CD-ROM | disk | FTP | other *** search
/ C++ Games Programming / CPPGAMES.ISO / thx / source / theatrix / music.cpp < prev    next >
C/C++ Source or Header  |  1995-04-26  |  4KB  |  199 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.  
  12. int MusicHand::music_supported;
  13. char *MusicHand::drivers[3];
  14. char *MusicHand::realptr[3];
  15. char *MusicHand::driverptr[3];
  16. static char far *initptr;
  17. static char far *deinitptr;
  18.  
  19. MusicHand::MusicHand(char *sc) : Hand(0)
  20. {
  21.     scorefilename = sc;
  22.     score = 0;
  23. }
  24.  
  25. MusicHand::~MusicHand()
  26. {
  27.     delete score;
  28. }
  29.  
  30. void MusicHand::startup()
  31. {
  32.     cout << "looking for music driver...\n";
  33.     if ((music_supported = load_sound_drivers()) != 0)    {
  34.         cout << "MIDPAK drivers loaded...\n";
  35.         if ((music_supported = init_driver()) != 0)    {
  36.             cout << "MIDPAK driver initialized...\n";
  37.             return;
  38.         }
  39.     }
  40.     cout << "music driver not initialized...\n";
  41. }
  42.  
  43. void MusicHand::initialize()
  44. {
  45.     if (music_supported && scorefilename)
  46.         load_score(scorefilename);
  47. }
  48.  
  49. void MusicHand::shutdown()
  50. {
  51.     if (music_supported)    {
  52.         terminate_driver();
  53.         cout << "music driver terminated...\n";
  54.     }
  55. }
  56.  
  57. void MusicHand::load_score(char *fname)
  58. {
  59.     if (!music_supported)
  60.         return;
  61.     delete score;
  62.     score = 0;
  63.     scorefilename = 0;
  64.     struct ffblk ffblk;
  65.     if (findfirst(fname, &ffblk, 0) == -1)
  66.         return;
  67.     scorefilename = fname;
  68.     score = new char[(int)ffblk.ff_fsize];
  69.     ifstream sfile(fname, ios::binary);
  70.     sfile.read(score, (int)ffblk.ff_fsize);
  71.  
  72.     // ----- register XMI file with DIGPAK
  73.     unsigned segm = FP_SEG(score);
  74.     unsigned offs = FP_OFF(score);
  75.  
  76.     _DI = 0;
  77.     _SI = (int)ffblk.ff_fsize;
  78.     _BX = offs;
  79.     _CX = segm;
  80.     _AX = 0x704;
  81.     geninterrupt(0x66);
  82.     if (_AX != 2)    {
  83.         delete score;
  84.         score = 0;
  85.     }
  86. }
  87.  
  88. void MusicHand::play_music_clip(int index)
  89. {
  90.     if (!music_supported || scorefilename == 0)
  91.         return;
  92.     stop_music_clip();
  93.     _BX = index-1;
  94.     _AX = 0x0702;
  95.     geninterrupt(0x66);
  96. }
  97.  
  98. void MusicHand::stop_music_clip()
  99. {
  100.     if (!music_supported || scorefilename == 0)
  101.         return;
  102.     _AX = 0x0705;
  103.     geninterrupt(0x66);
  104. }
  105.  
  106. int MusicHand::music_clip_is_playing()
  107. {
  108.     if (!music_supported || scorefilename == 0)
  109.         return 0;
  110.     _AX = 0x070c;
  111.     geninterrupt(0x66);
  112.     return _AX == 1;
  113. }
  114.  
  115. void MusicHand::delete_drivers(int i)
  116. {
  117.     while (i > 0)    {
  118.         delete realptr[--i];
  119.         realptr[i] = 0;
  120.         delete driverptr[i];
  121.         driverptr[i] = 0;
  122.     }
  123. }
  124.  
  125. int MusicHand::load_sound_drivers()
  126. {
  127.     static char *dnames[] = {
  128.         "midpak.com",
  129.         "midpak.adv",
  130.         "midpak.ad"
  131.     };
  132.     for (int i = 0; i < 3; i++)    {
  133.         struct ffblk ffblk;
  134.         if (findfirst(dnames[i],&ffblk,0) == -1)
  135.             break;
  136.         long siz = ffblk.ff_fsize;
  137.         realptr[i] = new char[(int)siz+16];
  138.         driverptr[i] = (char*)MK_FP(FP_SEG(realptr[i])+1,0);
  139.  
  140.         ifstream dfile(dnames[i],ios::binary);
  141.         dfile.read(driverptr[i],(int)siz);
  142.     }
  143.     if (i < 3 || strncmp(driverptr[0]+3, "MIDPAK", 6))    {
  144.         delete_drivers(i);
  145.         return 0;
  146.     }
  147.     initptr = (char*)MK_FP(FP_SEG(driverptr[0])-0x10, 0x200);
  148.     deinitptr = (char*)MK_FP(FP_SEG(driverptr[0])-0x10, 0x203);
  149.     return 1;
  150. }
  151.  
  152. int MusicHand::init_driver()
  153. {
  154.     unsigned drv;
  155.  
  156.     asm    {
  157.         call initptr
  158.            mov drv,ax
  159.     }
  160.     if (drv)    {
  161.         delete_drivers(3);
  162.         return 0;
  163.     }
  164.  
  165.     unsigned segadv = FP_SEG(driverptr[1]);
  166.     unsigned offadv = FP_OFF(driverptr[1]);
  167.     unsigned segad  = FP_SEG(driverptr[2]);
  168.     unsigned offad  = FP_OFF(driverptr[2]);
  169.  
  170.     asm    {
  171.         push si
  172.         push dx
  173.         push cx
  174.         push bx
  175.         mov  si,offad
  176.         mov  dx,segad
  177.         mov  cx,offadv
  178.         mov  bx,segadv
  179.         mov  ax,710h
  180.         int  66h
  181.         pop  bx
  182.         pop  cx
  183.         pop  dx
  184.         pop  si
  185.     }
  186.     return 1;
  187. }
  188.  
  189. void MusicHand::terminate_driver()
  190. {
  191.     if (!music_supported)
  192.         return;
  193.     asm {
  194.         call deinitptr
  195.     }
  196.     delete_drivers(3);
  197. }
  198.  
  199.