home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / SLOWRUNS.ZIP / SLOWSRC.ZIP / MAGIC6.C < prev    next >
C/C++ Source or Header  |  1997-02-11  |  11KB  |  464 lines

  1. // I N C L U D E S ///////////////////////////////////////////////////////////
  2.  
  3. #include <io.h>
  4. #include <conio.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <dos.h>
  8. #include <bios.h>
  9. #include <fcntl.h>
  10. #include <memory.h>
  11. #include <malloc.h>
  12. #include <math.h>
  13. #include <string.h>
  14.  
  15. #include "magic6.h"
  16.  
  17. // The variables declared and the routines Load_Sound_Driver_Files and those
  18. // that load and initialize MIDPAK and DIGPAK are hi-jacked from Dave Robert's
  19. // book, "PC Game Programming Explorer" - a Coriolis Book...
  20. //          ----------------------------
  21.  
  22. int    DigPakLoaded = 0;
  23. int  DigPakInit     = 0;
  24. unsigned char far *DigPakAddr;
  25. unsigned int DigPakParaSeg;
  26. int MidPakLoaded  = 0;
  27. int MidPakInit     = 0;
  28. unsigned char far *MidPakAddr;
  29. unsigned int MidPakParaSeg;
  30. unsigned char far *AdvAddr;
  31. unsigned int AdvParaSeg;
  32. unsigned char far *AdAddr;
  33.  
  34. int Load_Sound_Driver_File(char *Filename, unsigned char far *(*Addr), unsigned int *Para, long *Len)
  35. {
  36.     unsigned char far *temp_ptr;    // temporary pointer used to load sound
  37.  
  38.     unsigned char far *sound_ptr;    // pointer sound data
  39.  
  40.     unsigned int segment,            // segment of sound data memory
  41.                  paragraphs,        // number of 16 byte paragraphs sound takes up
  42.                  bytes_read,        // used to track number of bytes read by DOS
  43.                  size_of_file,        // the total size of the VOC file in bytes
  44.                  header_length;        // the length of the header portion of VOC file
  45.  
  46.     int sound_handle;                // DOS file handle
  47.  
  48.     // open the sound file, use DOS file and memory allocation to make sure
  49.     // memory is on a 16 byte or paragraph boundary
  50.  
  51.     if (_dos_open(Filename, _O_RDONLY | _O_BINARY, &sound_handle)!=0)
  52.     {
  53.         printf("\nSound System - Couldn't open %s",Filename);
  54.         return(0);
  55.     } // end if file not found
  56.  
  57.     // compute number of paragraphs that sound file needs
  58.  
  59.     size_of_file = _filelength(sound_handle);
  60.  
  61.     paragraphs = 1 + (size_of_file)/16;
  62.  
  63.     // allocate the memory on a paragraph boundary
  64.  
  65.     _dos_allocmem(paragraphs,&segment);
  66.  
  67.     // point data pointer to allocated data area
  68.  
  69.     _FP_SEG(sound_ptr) = segment;
  70.     _FP_OFF(sound_ptr) = 0;
  71.  
  72.     // alias pointer to memory storage area
  73.  
  74.     temp_ptr = sound_ptr;
  75.  
  76.     // read in blocks of 16k until file is loaded
  77.  
  78.     do
  79.     {
  80.         // load next block
  81.  
  82.         _dos_read(sound_handle, temp_ptr, 0x4000, &bytes_read);
  83.  
  84.         // adjust pointer
  85.  
  86.         temp_ptr += bytes_read;
  87.  
  88.     } while (bytes_read==0x4000);
  89.  
  90.     // close the file
  91.  
  92.     _dos_close(sound_handle);
  93.  
  94.     return(1);
  95. } // end Load_Sound_Driver_File
  96.  
  97. ///////////////////////////////////////////////////////////////////////////
  98.  
  99. //            Routines From the great Andre' Lamothe
  100.  
  101. ///////////////////////////////////////////////////////////////////////////
  102.  
  103. int Sound_Load(char *filename, sound_ptr the_sound, int translate)
  104. {
  105.     unsigned char far *temp_ptr;    // temporary pointer used to load sound
  106.  
  107.     unsigned char far *sound_ptr;    // pointer sound data
  108.  
  109.     unsigned int segment,            // segment of sound data memory
  110.                  paragraphs,        // number of 16 byte paragraphs sound takes up
  111.                  bytes_read,        // used to track number of bytes read by DOS
  112.                  size_of_file,        // the total size of the VOC file in bytes
  113.                  header_length;        // the length of the header portion of VOC file
  114.  
  115.     int sound_handle;                // DOS file handle
  116.  
  117.     // open the sound file, use DOS file and memory allocation to make sure
  118.     // memory is on a 16 byte or paragraph boundary
  119.  
  120.     if (_dos_open(filename, _O_RDONLY, &sound_handle)!=0)
  121.     {
  122.         printf("\nSound System - Couldn't open %s",filename);
  123.         return(0);
  124.     } // end if file not found
  125.  
  126.     // compute number of paragraphs that sound file needs
  127.  
  128.     size_of_file = _filelength(sound_handle);
  129.  
  130.     paragraphs = 1 + (size_of_file)/16;
  131.  
  132.     // allocate the memory on a paragraph boundary
  133.  
  134.     _dos_allocmem(paragraphs,&segment);
  135.  
  136.     // point data pointer to allocated data area
  137.  
  138.     _FP_SEG(sound_ptr) = segment;
  139.     _FP_OFF(sound_ptr) = 0;
  140.  
  141.     // alias pointer to memory storage area
  142.  
  143.     temp_ptr = sound_ptr;
  144.  
  145.     // read in blocks of 16k until file is loaded
  146.  
  147.     do
  148.     {
  149.         // load next block
  150.  
  151.         _dos_read(sound_handle, temp_ptr, 0x4000, &bytes_read);
  152.  
  153.         // adjust pointer
  154.  
  155.         temp_ptr += bytes_read;
  156.  
  157.     } while (bytes_read==0x4000);
  158.  
  159.     // close the file
  160.  
  161.     _dos_close(sound_handle);
  162.  
  163.     // make sure it's a voc file, test for "Creative"
  164.  
  165.     if ((sound_ptr[0] != 'C') || (sound_ptr[1] != 'r'))
  166.     {
  167.         printf("\n%s is not a VOC file!",filename);
  168.  
  169.         // de-allocate the memory
  170.  
  171.         _dos_freemem(_FP_SEG(sound_ptr));
  172.  
  173.         // return failure
  174.  
  175.         return(0);
  176.     } // end if voc file
  177.  
  178.     // compute start of sound data;
  179.  
  180.     header_length = (unsigned int)sound_ptr[20];
  181.  
  182.     // point buffer pointer to start of VOC file in memory
  183.  
  184.     the_sound->buffer            = sound_ptr;
  185.  
  186.     // set up the SNDSTRUC for DIGPAK
  187.  
  188.     the_sound->SS.sound            = (unsigned char far*)(sound_ptr+header_length+4);
  189.     the_sound->SS.sndlen        = (unsigned short)(size_of_file - header_length);
  190.     the_sound->SS.IsPlaying        = (short far *)&the_sound->status;
  191.     the_sound->SS.frequency        = (short)((long)(-1000000) / ((int)sound_ptr[header_length+4]-256));
  192.  
  193.     // now format data for sound card if requested
  194.  
  195.     if (translate)
  196.         Sound_Translate(the_sound);
  197.  
  198.     // return success
  199.  
  200.     return(1);
  201. } // end Sound_Load
  202.  
  203. void Sound_Translate(sound_ptr the_sound)
  204. {
  205.     // this function calls the DIGPAK function massage audio to translate
  206.     // the raw audio data into the proper format for the sound card that
  207.     // the sound system is running on.
  208.  
  209.     unsigned char far *buffer;
  210.  
  211.     buffer = (unsigned char far*)&the_sound->SS;
  212.  
  213.     _asm
  214.     {
  215.         push ds            ; save DS and SI on stack
  216.         push si
  217.         mov ax, 068Ah    ; function 3: MassageAudio
  218.         lds si, buffer    ; move address of sound in DS:SI
  219.         int 66h            ; call DIGPAK
  220.         pop si            ; restore DS and SI from stack
  221.         pop ds
  222.                         ; have a nice day :)
  223.     } // end inline asm
  224. } // end Sound_Translate
  225.  
  226. void Sound_Unload(sound_ptr the_sound)
  227. {
  228.     // this function deletes the sound from memory
  229.  
  230.     _dos_freemem(_FP_SEG(the_sound->buffer));
  231.     the_sound->buffer = NULL;
  232. } // end Sound_Unload
  233.  
  234. void Sound_Play(sound_ptr the_sound)
  235. {
  236.     // this function plays the sound pointed to by the sound structure
  237.  
  238.     unsigned char far *buffer;
  239.  
  240.     // alias sound structure
  241.  
  242.     buffer = (unsigned char far*)&the_sound->SS;
  243.  
  244.     _asm
  245.     {
  246.         push ds                ; save DS and SI on stack
  247.         push si
  248.         mov ax, 068Bh        ; function 4: DigPlay2
  249.         lds si, buffer        ; move address of sound in DS:SI
  250.         int 66h                ; call DIGPAK
  251.         pop si                ; restore DS and SI from stack
  252.         pop ds
  253.     } // end inline asm
  254. } // end Sound_Play
  255.  
  256. int Sound_Status(void)
  257. {
  258.     // this function will return the status of DIGPAK i.e. is a sound playing
  259.     // or not
  260.  
  261.     _asm
  262.     {
  263.         mov ax,0689h        ; function 2: SoundStatus
  264.         int 66h                ; call DIGPAK
  265.     } // end inline asm
  266.  
  267.     // on exit AX will be used as the return value, if 1 then a sound is playing
  268.     // 0 if a sound is not playing
  269. } // end Sound_Status
  270.  
  271. void Sound_Stop(void)
  272. {
  273.     // this function will stop a currently playing sound
  274.  
  275.     _asm
  276.     {
  277.         mov ax, 068Fh        ; function 8: StopSound
  278.         int 66h                ; call DIGPAK
  279.     } // end inline asm
  280. }
  281.  
  282. int Music_Load(char *filename, music_ptr the_music)
  283. {
  284.     // this function will load a xmidi file from disk into memory and register it
  285.  
  286.     unsigned char far *temp_ptr;    // temporary pointer used to load music
  287.     unsigned char far *xmidi_ptr;    // pointer to xmidi data
  288.  
  289.     unsigned int segment,            // segment of music data memory
  290.                  paragraphs,        // number of 16 byte paragraphs music takes up
  291.                  bytes_read;        // used to track number of bytes read by DOS
  292.  
  293.     long size_of_file;                // the total size of the xmidi file in bytes
  294.  
  295.     int xmidi_handle;                // DOS file handle
  296.  
  297.     // open the extended xmidi file, use DOS file and memory allocation to make sure
  298.     // memory is on a 16 byte or paragraph boundary
  299.  
  300.     if (_dos_open(filename, _O_RDONLY, &xmidi_handle)!=0)
  301.     {
  302.         printf("\nMusic System - Couldn't open %s", filename);
  303.         return(0);
  304.     } // end if file not found
  305.  
  306.     // compute number of paragraphs that sound file needs
  307.  
  308.     size_of_file = _filelength(xmidi_handle);
  309.     paragraphs = 1 + (size_of_file)/16;
  310.  
  311.     // allocate the memory on a paragraph boundary
  312.  
  313.     _dos_allocmem(paragraphs, &segment);
  314.  
  315.     // point data pointer to allocated data area
  316.  
  317.     _FP_SEG(xmidi_ptr) = segment;
  318.     _FP_OFF(xmidi_ptr) = 0;
  319.  
  320.     // alias pointer to memory storage area
  321.  
  322.     temp_ptr = xmidi_ptr;
  323.  
  324.     // read in blocks of 16k until file is loaded
  325.  
  326.     do
  327.     {
  328.         // load next block
  329.  
  330.         _dos_read(xmidi_handle, temp_ptr, 0x4000, &bytes_read);
  331.  
  332.         // adjust pointer
  333.  
  334.         temp_ptr += bytes_read;
  335.  
  336.     } while(bytes_read==0x4000);
  337.  
  338.     // close the file
  339.  
  340.     _dos_close(xmidi_handle);
  341.  
  342.     // set up the music structure
  343.  
  344.     the_music->buffer    = xmidi_ptr;
  345.     the_music->size        = size_of_file;
  346.     the_music->status    = 0;
  347.  
  348.     // now register the xmidi file with MIDPAK
  349.  
  350.     if ((the_music->register_info = Music_Register(the_music))==XMIDI_UNREGISTERED)
  351.     {
  352.         // delete the memory
  353.  
  354.         Music_Unload(the_music);
  355.  
  356.         // return an error
  357.  
  358.         return(0);
  359.     } // end if couldn't register xmidi file
  360.  
  361.     // else return success
  362.  
  363.     return(1);
  364. } // end Music_Load
  365.  
  366. int Music_Register(music_ptr the_music)
  367. {
  368.     // this function registers the xmidi music with MIDPAK, so that it can be
  369.     // played
  370.  
  371.     unsigned int xmid_off,        // offset and segment of midi file
  372.                  xmid_seg,
  373.                  length_low,    // length of midi file in bytes
  374.                  length_hi;
  375.  
  376.     // extract segment and offset of music buffer
  377.  
  378.     xmid_off = _FP_OFF((the_music->buffer));
  379.     xmid_seg = _FP_SEG((the_music->buffer));
  380.  
  381.     // extract the low word and high word of xmidi file length
  382.  
  383.     length_low = the_music->size;
  384.     length_hi  = (the_music->size) >> 16;
  385.  
  386.     // call MIDPAK
  387.  
  388.     _asm
  389.     {
  390.         push si                        ; save si and di
  391.         push di
  392.         mov ax,704h                    ; function #5: RegisterXmidi
  393.         mov bx,xmid_off                ; offset of xmidi data
  394.  
  395.         mov cx,xmid_seg                ; segment of xmidi data
  396.  
  397.         mov si,length_low            ; low word of xmidi length
  398.         mov di,length_hi            ; hi word of xmidi length
  399.  
  400.         int 66h                        ; call MIDPAK
  401.         pop di                        ; restore si and di
  402.         pop si
  403.     } // end inline asm
  404.  
  405.     // return value will be in AX
  406. } // end Music_Register
  407.  
  408. void Music_Unload(music_ptr the_music)
  409. {
  410.     // this function deletes the xmidi file data from memory
  411.  
  412.     _dos_freemem(_FP_SEG(the_music->buffer));
  413.     the_music->buffer=NULL;
  414. } // end Music_Unload
  415.  
  416. int Music_Play(music_ptr the_music, int sequence)
  417. {
  418.     // this function plays an xmidi file from memory
  419.  
  420.     _asm
  421.     {
  422.         mov ax,702h                ; function #3: PlaySequence
  423.         mov bx,sequence            ; which sequence to play 0,1,2....
  424.         int 66h                    ; call MIDPAK
  425.     } // end inline assembly
  426.  
  427.     // return value is in AX, 1 success, 0 sequence not available
  428. } // end Music_Play
  429.  
  430. void Music_Stop(void)
  431. {
  432.     // this function will stop the song currently playing
  433.  
  434.     _asm
  435.     {
  436.         mov ax,705h                ; function #6: MidiStop
  437.         int 66h                    ; call MIDPAK
  438.     } // end inline asm
  439. } // end Music_Stop
  440.  
  441. void Music_Resume(void)
  442. {
  443.     // this function resumes a previously stopped xmidi sequence
  444.  
  445.     _asm
  446.     {
  447.         mov ax,70Bh                ; function #12: ResumePlaying
  448.         int 66h                    ; call MIDPAK
  449.     } // end inline assembly
  450. } // end Music_Resume
  451.  
  452. int Music_Status(void)
  453. {
  454.     // this function returns the status of a playing sequence
  455.  
  456.     _asm
  457.     {
  458.         mov ax,70Ch                ; function #13: SequenceStatus
  459.         int 66h                    ; call MIDPAK
  460.     } // end inline assembly
  461.  
  462.     // return value is in AX
  463. // end Music_Status
  464. }