home *** CD-ROM | disk | FTP | other *** search
/ Launch & Play / spustahrej2.iso / Egoboo / code / sound.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-12-03  |  29.4 KB  |  1,150 lines

  1. // sound.c
  2.  
  3. // Egoboo, Copyright (C) 2000 Aaron Bishop
  4.  
  5. #include "egoboo.h"
  6. #include "sound.h"
  7.  
  8. #define MAX_SDL_SOUND 512 // Max of 512 loaded sound
  9. #define MAX_SDL_MIXING_SOUND 16 // Max of simultaneous playing sounds
  10.  
  11. BOOL    gSoundOn = FALSE;
  12. SDL_AudioSpec    *gHardwareSpec = NULL;
  13. SDLSound        *gSDLSoundList = NULL;
  14. SDLActiveSound    *gSDLSoundChannelList = NULL;
  15. BOOL            gSoundMixingPaused = TRUE;
  16. Uint32            gNumChannelToMix = 0;
  17.  
  18.  
  19. Uint32    gSoundOutputSPS; // sample per second
  20. Uint32    gSoundOutputMixBufferSize;
  21. Uint32    gSoundMaxSoundChannel;
  22.  
  23.  
  24.  
  25. //------------------------------------------------------------------------------
  26. //Sound Routines----------------------------------------------------------------
  27. //------------------------------------------------------------------------------
  28.  
  29. /*----------------
  30.  
  31.  Returns the nunber of sample for the specified sound buffer
  32.  Don't work on compressed sounds ( ADPCM )
  33.  
  34. prog:
  35.     Germain SauvΘ
  36.  
  37. ----------------*/
  38. Sint32    GetNumSamples( Uint16 format, Uint8 channels, Uint32 size )
  39. {
  40.     Uint8    lBytePerChan = 0;
  41.     Sint32    lNumSample;
  42.  
  43.     switch( format )
  44.     {
  45.         case AUDIO_U8:
  46.         case AUDIO_S8:
  47.             lBytePerChan = 1;
  48.             break;
  49.         case AUDIO_U16LSB:
  50.         case AUDIO_S16LSB:
  51.         case AUDIO_U16MSB:
  52.         case AUDIO_S16MSB:
  53.             lBytePerChan = 2;
  54.             break;
  55.         default:
  56.             return -1; // format undefined
  57.             break;
  58.     }
  59.     lNumSample = size / (lBytePerChan * channels);
  60.     return lNumSample;
  61.     
  62. }
  63.  
  64. /*----------------
  65.  
  66.  Returns the index of a free SDL_sound or -1 if any are available
  67.  
  68. prog:
  69.     Germain SauvΘ
  70.  
  71. ----------------*/
  72. Sint32    GetFreeSoundIdx()
  73. {
  74.     Sint32 lCheckIdx; 
  75.     
  76.     if ( gSDLSoundList == NULL )
  77.     {
  78.         return -1;
  79.     }
  80.     lCheckIdx = 0;
  81.     while ( lCheckIdx < MAX_SDL_SOUND )
  82.         {
  83.         if ( gSDLSoundList[lCheckIdx].m_Free )
  84.             {
  85.             return lCheckIdx;
  86.             }
  87.         lCheckIdx++;
  88.         }
  89.  
  90.     return -1;
  91. }
  92.  
  93.  
  94. /*----------------
  95.  
  96.  Returns the index of a free SDL_sound or -1 if any are available
  97.  
  98. prog:
  99.     Germain SauvΘ
  100.  
  101. ----------------*/
  102. Sint32    GetFreePlayingIdx()
  103. {
  104.     Sint32 lCheckIdx; 
  105.     
  106.     if ( gSDLSoundChannelList == NULL )
  107.     {
  108.         return -1;
  109.     }
  110.     lCheckIdx = 0;
  111.     while ( lCheckIdx < (Sint32)gNumChannelToMix )
  112.         {
  113.         if ( !gSDLSoundChannelList[lCheckIdx].m_Active )
  114.             {
  115.             return lCheckIdx;
  116.             }
  117.         lCheckIdx++;
  118.         }
  119.  
  120.     return -1;
  121. }
  122.  
  123. /*----------------
  124.  
  125.  Main mixing callback function
  126.  
  127.  Doesn't support looping sounds.
  128.  
  129. prog:
  130.     Germain SauvΘ
  131.  
  132. ----------------*/
  133. void EgobooSoundMixCallback( void *userdata, Uint8 *stream, int len)
  134. {
  135.     Uint32    lCompt;
  136.     Uint32    lSizeToMix;
  137.  
  138.     if ( gSDLSoundChannelList == NULL )
  139.         {
  140.         return;
  141.         }
  142.     lCompt = 0;
  143.     while (lCompt < gNumChannelToMix )
  144.     {
  145.         if ( gSDLSoundChannelList[lCompt].m_Active )
  146.         {
  147.             // check if the sound buffer still exist
  148.             if ( gSDLSoundList[gSDLSoundChannelList[lCompt].m_SoundBufferIdx].m_Free == FALSE )
  149.             {
  150.                 // mix the sound in the stream
  151.                 if ( (gSDLSoundChannelList[lCompt].m_CurPlayPos + len) < gSDLSoundList[gSDLSoundChannelList[lCompt].m_SoundBufferIdx].m_AudioLen )
  152.                     {
  153.                     SDL_MixAudio( stream, &gSDLSoundList[gSDLSoundChannelList[lCompt].m_SoundBufferIdx].m_AudioBuffer[gSDLSoundChannelList[lCompt].m_CurPlayPos], len, gSDLSoundChannelList[lCompt].m_Volume );
  154.                     gSDLSoundChannelList[lCompt].m_CurPlayPos += len;
  155.                     }
  156.                 else
  157.                     {
  158.                     lSizeToMix = gSDLSoundList[gSDLSoundChannelList[lCompt].m_SoundBufferIdx].m_AudioLen - gSDLSoundChannelList[lCompt].m_CurPlayPos;
  159.                     SDL_MixAudio( stream, &gSDLSoundList[gSDLSoundChannelList[lCompt].m_SoundBufferIdx].m_AudioBuffer[gSDLSoundChannelList[lCompt].m_CurPlayPos], lSizeToMix, gSDLSoundChannelList[lCompt].m_Volume );
  160.                     // no looping for now
  161.                     gSDLSoundChannelList[lCompt].m_Active = FALSE;
  162.                     }
  163.                 // update the sound channel
  164.             }
  165.             else
  166.             {
  167.                 // stop this sound channel since it points to an unused sound
  168.                 gSDLSoundChannelList[lCompt].m_Active = FALSE;
  169.             }
  170.         }
  171.         lCompt++;
  172.     }
  173. }
  174.  
  175. /*----------------
  176.  
  177.  Initialize SDL sound system
  178.  
  179. prog:
  180.     Germain SauvΘ
  181.  
  182. ----------------*/
  183. BOOL InitSound( Uint32 pBufferSize, Uint32 pFreq, Uint32 pMaxSoundChannel )
  184. {
  185.     int OpenErr;
  186.     Sint32    lCompt;
  187.  
  188.     if ( pMaxSoundChannel > MAX_SDL_MIXING_SOUND)
  189.     {
  190.         pMaxSoundChannel = MAX_SDL_MIXING_SOUND;
  191.     }
  192.     gNumChannelToMix = pMaxSoundChannel;
  193.     
  194.     gHardwareSpec = (SDL_AudioSpec *)malloc( sizeof( SDL_AudioSpec ) );
  195.     gHardwareSpec->freq = pFreq;
  196.     gHardwareSpec->format = AUDIO_S16SYS;    // 16 bit 
  197.     gHardwareSpec->channels = 1; // MONO for the beta
  198.     gHardwareSpec->samples = pBufferSize; // in samples
  199.     gHardwareSpec->size = 0; // will be set by samples
  200.     gHardwareSpec->callback = EgobooSoundMixCallback;
  201.     gHardwareSpec->userdata = NULL;
  202.  
  203.     OpenErr = SDL_OpenAudio(gHardwareSpec, NULL);
  204.     if ( OpenErr < 0)
  205.         {
  206.         // error
  207.         return FALSE;
  208.         }
  209.  
  210.     // initialize the sound list and the sound channels
  211.     gSDLSoundList = (SDLSound *)malloc( sizeof(SDLSound) * MAX_SDL_SOUND );
  212.     gSDLSoundChannelList = (SDLActiveSound *)malloc( sizeof( SDLActiveSound ) * pMaxSoundChannel);
  213.     if ( gSDLSoundList != NULL && gSDLSoundChannelList != NULL )
  214.     {
  215.         for ( lCompt = 0; lCompt < MAX_SDL_SOUND; lCompt++ )
  216.         {
  217.             gSDLSoundList[lCompt].m_Free = TRUE;
  218.             gSDLSoundList[lCompt].m_AudioBuffer = NULL;
  219.         }
  220.         for ( lCompt = 0; lCompt < (Sint32)pMaxSoundChannel; lCompt++ )
  221.         {
  222.             gSDLSoundChannelList[lCompt].m_Active = FALSE;
  223.         }
  224.         gSoundOn = TRUE;
  225.         SDL_PauseAudio( 0 ); // start mixing sounds
  226.         gSoundMixingPaused = FALSE;
  227.     }
  228.     return TRUE;
  229.  
  230. }
  231.  
  232.  
  233. /*----------------
  234.  
  235.  Shutdown SDL sound system
  236.  
  237. prog:
  238.     Germain SauvΘ
  239.  
  240. ----------------*/
  241. BOOL ShutdownSound( void )
  242. {
  243.     if ( gSoundOn == TRUE )
  244.     {
  245.         SDL_PauseAudio( 1 );
  246.         gSoundMixingPaused = TRUE;
  247.         SDL_CloseAudio();
  248.         if ( gHardwareSpec != NULL )
  249.         {
  250.             free( gHardwareSpec );
  251.         }
  252.         gSoundOn = FALSE;
  253.     }
  254.     return TRUE;
  255. }
  256.  
  257. /*----------------
  258.  
  259.  Looks for an inactive sound channel and plays the sound "index" with volume.
  260.  Doesn't use pan and frequency
  261.  
  262. prog:
  263.     Germain SauvΘ
  264.     prog X
  265.  
  266. ----------------*/
  267. void play_sound_pvf(int index, int pan, int volume, int frequency)
  268. {
  269.     // ZZ> This function starts playing a sound
  270.     Sint32    lFreeChannel;
  271.     float    lCalcVolume;
  272. /* 
  273. pan goes from -10000 to 10000 and volume goes from 0 to -10000.
  274. for now, only volume count and panning is simulated
  275. */
  276.     if ( gSoundOn == FALSE || index < 0 || index >= MAX_SDL_SOUND )
  277.         {
  278.         return;
  279.         }
  280.  
  281.     if ( gSDLSoundList[index].m_Free == TRUE)
  282.         {
  283.         // no sound at index
  284.         return;
  285.         }
  286.     SDL_LockAudio();
  287.     lFreeChannel = GetFreePlayingIdx();
  288.     if ( lFreeChannel != -1 )
  289.     {
  290.         gSDLSoundChannelList[lFreeChannel].m_Active = TRUE;
  291.         gSDLSoundChannelList[lFreeChannel].m_SoundBufferIdx = (Uint32)index;
  292.         gSDLSoundChannelList[lFreeChannel].m_IsLooped = FALSE;
  293.         gSDLSoundChannelList[lFreeChannel].m_CurPlayPos = 0;
  294.         lCalcVolume = 128.0f + ((float)volume / 78.25 );
  295.         if ( lCalcVolume <= 0.0f)
  296.         {
  297.             lCalcVolume = 0.0f;
  298.         }
  299.         else
  300.         {
  301.             // simulate panning
  302.             if ( pan != 0 )
  303.             {
  304.                 lCalcVolume -= (lCalcVolume / 2.0f) * (abs( pan ) / 10000.0f);
  305.             }
  306.         }
  307.         gSDLSoundChannelList[lFreeChannel].m_Volume = (Uint32)lCalcVolume; // cheap for the moment
  308.         //printf("Ask to play sound index %i\n", index);
  309.     }
  310.     SDL_UnlockAudio();
  311.     
  312. /*PORT
  313.     if(index < numsound && index >= 0 && soundon)
  314.     {
  315.         lpDSBuffer[index]->Stop();
  316.         lpDSBuffer[index]->SetCurrentPosition(0);
  317.         lpDSBuffer[index]->SetPan(pan);
  318.         lpDSBuffer[index]->SetVolume(volume);
  319.         lpDSBuffer[index]->SetFrequency(frequency);
  320.         lpDSBuffer[index]->Play(0, 0, 0);
  321.     }
  322. */
  323. }
  324.  
  325. //------------------------------------------------------------------------------
  326. void play_sound_skip(int index, int skip)
  327. {
  328.     // ZZ> This function starts playing a sound with padding
  329. /*PORT
  330.     if(index < numsound && index >= 0 && soundon)
  331.     {
  332.         lpDSBuffer[index]->Stop();
  333.         lpDSBuffer[index]->SetCurrentPosition(skip);
  334.         lpDSBuffer[index]->SetPan(PANMID);
  335.         lpDSBuffer[index]->SetVolume(VOLMAX);
  336.         lpDSBuffer[index]->SetFrequency(11025);
  337.         lpDSBuffer[index]->Play(0, 0, 0);
  338.     }
  339. */
  340. }
  341.  
  342. //------------------------------------------------------------------------------
  343. void play_sound_pvf_looped(int index, int pan, int volume, int frequency)
  344. {
  345.     // ZZ> This function starts playing a looped sound
  346. /* PORT
  347.     if(index < numsound && index >= 0 && soundon)
  348.     {
  349.         lpDSBuffer[index]->SetPan(pan);
  350.         lpDSBuffer[index]->SetVolume(volume);
  351.         lpDSBuffer[index]->SetFrequency(frequency);
  352.         lpDSBuffer[index]->Play(0, 0, DSBPLAY_LOOPING);
  353.     }
  354. */
  355. }
  356.  
  357. /*----------------
  358.  
  359.  Stop all sound channels playing sound "index"
  360.  
  361. prog:
  362.     Germain SauvΘ
  363.     prog X
  364.  
  365. ----------------*/
  366. void stop_sound(int index)
  367. {
  368. // since there isn't any concept of sound channel on DiretcX ( weird )
  369. // stop_sound looks for any sound channel currently playing "index" and stops it
  370.     Uint32    lCheckChan;
  371.     if ( gSoundOn == FALSE || index < 0 || index >= MAX_SDL_SOUND )
  372.     {
  373.         return;
  374.     }
  375.     SDL_LockAudio(); 
  376.     for ( lCheckChan = 0; lCheckChan < MAX_SDL_MIXING_SOUND; lCheckChan++ )
  377.     {
  378.         if ( gSDLSoundChannelList[lCheckChan].m_Active )
  379.         {
  380.             if ( gSDLSoundChannelList[lCheckChan].m_SoundBufferIdx == (Uint32)index )
  381.             {
  382.                 gSDLSoundChannelList[lCheckChan].m_Active = FALSE;
  383.             }
  384.         }
  385.     }
  386.     SDL_UnlockAudio();
  387. }
  388.  
  389. /*----------------
  390.  
  391.  Stop a specific sound channel
  392.  
  393. prog:
  394.     Germain SauvΘ
  395.  
  396. ----------------*/
  397. void StopSoundChannel( Uint32 pChannel )
  398. {
  399.     
  400.     if ( gSoundOn == FALSE || pChannel >= MAX_SDL_MIXING_SOUND )
  401.     {
  402.         return;
  403.     }
  404.     SDL_LockAudio(); 
  405.     gSDLSoundChannelList[pChannel].m_Active = FALSE;
  406.     SDL_UnlockAudio();
  407. }
  408.  
  409. /*----------------
  410.  
  411.  Stop all sound channel
  412.  
  413. prog:
  414.     Germain SauvΘ
  415.  
  416. ----------------*/
  417. void StopAllSoundChannel( void )
  418. {
  419.     Uint32 lCompt;
  420.  
  421.     if ( gSoundOn == FALSE )
  422.     {
  423.         return;
  424.     }
  425.     SDL_LockAudio(); 
  426.     for ( lCompt = 0; lCompt < MAX_SDL_MIXING_SOUND; lCompt++ )
  427.     {
  428.         gSDLSoundChannelList[lCompt].m_Active = FALSE;
  429.     }
  430.     SDL_UnlockAudio();
  431. }
  432.  
  433. /*----------------
  434.  
  435.  
  436. prog:
  437.     Germain SauvΘ
  438.  
  439. ----------------*/
  440. void PauseMixingSound( void )
  441. {
  442.     if (!gSoundMixingPaused && gSoundOn)
  443.     {
  444.         SDL_PauseAudio( 1 );
  445.         gSoundMixingPaused = TRUE;
  446.     }
  447. }
  448.  
  449. /*----------------
  450.  
  451.  
  452. prog:
  453.     Germain SauvΘ
  454.  
  455. ----------------*/
  456. void ResumeMixingSound( void )
  457. {
  458.     if (gSoundMixingPaused && gSoundOn)
  459.     {
  460.         SDL_PauseAudio( 1 );
  461.         gSoundMixingPaused = FALSE;
  462.     }
  463. }
  464.  
  465. /*----------------
  466.  
  467.  
  468. prog:
  469.     Germain SauvΘ
  470.  
  471. ----------------*/
  472. BOOL IsMixingPaused( void )
  473. {
  474.     return gSoundMixingPaused;
  475. }
  476.  
  477.  
  478. /*----------------
  479.  
  480.  Remove the sound "index" from the list and from memory
  481.  
  482. prog:
  483.     Germain SauvΘ
  484.  
  485. ----------------*/
  486. void RemoveSound( Uint32 index )
  487. {
  488.     if ( gSoundOn == FALSE || index < 0 || index >= MAX_SDL_SOUND )
  489.     {
  490.         return;
  491.     }
  492.     if ( gSDLSoundList[index].m_Free )
  493.     {
  494.         return;
  495.     }
  496.     SDL_LockAudio(); 
  497.     if ( gSDLSoundList[index].m_AudioBuffer != NULL )
  498.     {
  499.         free( gSDLSoundList[index].m_AudioBuffer );
  500.         gSDLSoundList[index].m_AudioBuffer = NULL;
  501.     }
  502.     gSDLSoundList[index].m_Free = TRUE;
  503.     SDL_UnlockAudio();
  504. }
  505.  
  506. /*----------------
  507.  
  508.  Remove all sounds from the list
  509.  
  510. prog:
  511.     Germain SauvΘ
  512.     prog X
  513.  
  514. ----------------*/
  515. void reset_sounds()
  516. {
  517.     Uint32 lCompt;
  518.  
  519.     if ( gSoundOn == FALSE )
  520.     {
  521.         return;
  522.     }
  523.     StopAllSoundChannel();
  524.     for ( lCompt = 0; lCompt < MAX_SDL_SOUND; lCompt++ )
  525.     {
  526.         RemoveSound( lCompt );
  527.     }
  528. /*PORT
  529.     int cnt = 0;
  530.     if(numsound == 0)
  531.     {
  532.         // Set 'em all to unused
  533.         while(cnt < MAXSOUND)
  534.         {
  535.             lpDSBuffer[cnt] = NULL;
  536.             cnt++;
  537.         }
  538.     }
  539.     else
  540.     {
  541.         // Free 'em up
  542.         while(cnt < numsound)
  543.         {
  544.             lpDSBuffer[cnt]->Stop();
  545.             RELEASE(lpDSBuffer[cnt]);
  546.             cnt++;
  547.         }
  548.     }
  549.     numsound = 0;
  550. */
  551. }
  552.  
  553. /*----------------
  554.  
  555.  Loads one .wav file and returns its index number or -1 if it failed
  556.  
  557. prog:
  558.     Germain SauvΘ
  559.     prog X
  560.  
  561. ----------------*/
  562. int load_one_wave(char *szFileName)
  563. {
  564.     SDL_AudioCVT  wav_cvt;
  565.     SDL_AudioSpec wav_spec;
  566.     Uint32    wav_length;
  567.     Uint32    wav_cvt_len;
  568.     Uint8    *wav_buffer;
  569.     Sint32    lSDLSoundIdx;
  570.     int        ret;
  571.     Sint32 lNumSample;
  572.  
  573.     if ( gSoundOn == FALSE ) { return -1; }
  574.     
  575.     lSDLSoundIdx = GetFreeSoundIdx();
  576.     if ( lSDLSoundIdx == -1 ) { return -1; }
  577.  
  578.     /* Load the WAV */
  579.     if( SDL_LoadWAV(szFileName, &wav_spec, &wav_buffer, &wav_length) == NULL ) { return -1; }
  580.  
  581.     //printf("loading sound %s at index %i\n", szFileName, lSDLSoundIdx);
  582.     // convert the wav to 16 bit mono at hardware SPS
  583.     ret = SDL_BuildAudioCVT( &wav_cvt, wav_spec.format, wav_spec.channels, wav_spec.freq,
  584.             AUDIO_S16SYS, 1, gHardwareSpec->freq );
  585.     if ( ret == -1 ) { SDL_FreeWAV(wav_buffer); return -1; }
  586.  
  587.     if ( gSDLSoundList[lSDLSoundIdx].m_AudioBuffer != NULL )
  588.     {
  589.       free( gSDLSoundList[lSDLSoundIdx].m_AudioBuffer );
  590.       gSDLSoundList[lSDLSoundIdx].m_AudioBuffer = NULL;
  591.     }
  592.  
  593.     lNumSample = GetNumSamples(wav_spec.format,wav_spec.channels,wav_length);
  594.     if ( lNumSample == -1 ) { SDL_FreeWAV(wav_buffer); return -1; }
  595.  
  596.     wav_cvt_len = (Uint32)((float)(lNumSample * 2) * ( (float)gHardwareSpec->freq / (float)wav_spec.freq )); // 16 bit mono
  597.     if ( wav_cvt_len < wav_length )
  598.     {
  599.         gSDLSoundList[lSDLSoundIdx].m_AudioBuffer = (Uint8 *)malloc( wav_length );
  600.     }
  601.     else
  602.     {
  603.         gSDLSoundList[lSDLSoundIdx].m_AudioBuffer = (Uint8 *)malloc( wav_cvt_len );
  604.     }
  605.     gSDLSoundList[lSDLSoundIdx].m_AudioLen = wav_cvt_len;
  606.     wav_cvt.buf = gSDLSoundList[lSDLSoundIdx].m_AudioBuffer;
  607.     wav_cvt.len = wav_length;
  608.  
  609.     memcpy( gSDLSoundList[lSDLSoundIdx].m_AudioBuffer, wav_buffer, wav_length );
  610.     // Free memory used by WAV file
  611.     SDL_FreeWAV(wav_buffer);
  612.     
  613.     ret = SDL_ConvertAudio(&wav_cvt);
  614.  
  615.     if ( ret == -1 ) { free( gSDLSoundList[lSDLSoundIdx].m_AudioBuffer ); gSDLSoundList[lSDLSoundIdx].m_AudioBuffer=NULL; return -1; }
  616.  
  617.     // weird bug!!! probably ADPCM
  618.     if (wav_cvt_len != wav_cvt.len*wav_cvt.len_ratio)
  619.     {
  620.         if ( wav_cvt_len > wav_cvt.len*wav_cvt.len_ratio )
  621.         {
  622.             gSDLSoundList[lSDLSoundIdx].m_AudioLen = wav_cvt.len*wav_cvt.len_ratio;
  623.         }
  624.         else
  625.         {
  626.             // Major error
  627.             // will probably crash anyway
  628.             free( gSDLSoundList[lSDLSoundIdx].m_AudioBuffer );
  629.                         gSDLSoundList[lSDLSoundIdx].m_AudioBuffer = NULL;
  630.             return -1;
  631.         }
  632.     }
  633.     gSDLSoundList[lSDLSoundIdx].m_Free = FALSE;
  634.     return lSDLSoundIdx;
  635.  
  636. /* PORT
  637.     DSBUFFERDESC    dsbd;
  638.     LPVOID          pbData = NULL;
  639.     LPVOID          pbData2 = NULL;
  640.     DWORD           dwLength;
  641.     DWORD           dwLength2;
  642.  
  643.     UINT            Size;
  644.     DWORD           Samples;
  645.     WAVEFORMATEX    *WaveFormat;
  646.     BYTE            *Data;
  647.     HRESULT         hr;
  648.  
  649.  
  650.     // Only bother if sound is available
  651.     if(soundon)
  652.     {
  653.         // Load the data from the file into memory ( at Data )
  654.         hr = WaveLoadFile(szFileName, &Size, &Samples, &WaveFormat, &Data);
  655.         if(hr || Size == 0)
  656.         {
  657.             // File not loaded, so just quit
  658.             return -1;
  659.         }
  660.  
  661.  
  662.         // Set up the direct sound buffer. 
  663.         memset(&dsbd, 0, sizeof(DSBUFFERDESC));
  664.         dsbd.dwSize = sizeof(DSBUFFERDESC);
  665.         dsbd.dwFlags = DSBCAPS_STATIC | DSBCAPS_CTRLDEFAULT | DSBCAPS_GETCURRENTPOSITION2;
  666.         dsbd.dwBufferBytes = Size;
  667.         dsbd.lpwfxFormat = WaveFormat;
  668.         hr = lpDirectSound->CreateSoundBuffer(&dsbd, &lpDSBuffer[numsound], NULL);
  669.         if(hr)
  670.         {
  671.             // Free the loadfile memory...
  672.             if(WaveFormat!=NULL)  GlobalFreePtr(WaveFormat);
  673.             if(Data!=NULL)  GlobalFreePtr(Data);
  674.             return -1;
  675.         }
  676.  
  677.  
  678.         // Get ready to copy data
  679.         hr = lpDSBuffer[numsound]->Lock(0, Size, &pbData, &dwLength, &pbData2, &dwLength2, 0L);
  680.         if(hr)
  681.         {
  682.             // The buffer didn't get locked...  That's bad
  683.             RELEASE(lpDSBuffer[numsound]);
  684.             if(WaveFormat!=NULL)  GlobalFreePtr(WaveFormat);
  685.             if(Data!=NULL)  GlobalFreePtr(Data);
  686.             return -1;
  687.         }
  688.  
  689.  
  690.         // Copy the data to the sound buffer
  691.         memcpy(pbData, Data, Size);
  692.  
  693.  
  694.         // Set the buffer back to its unlocked state.
  695.         hr = lpDSBuffer[numsound]->Unlock(pbData, Size, NULL, 0);
  696.         if(hr)
  697.         {
  698.             // The buffer didn't get unlocked...  That's bad
  699.             RELEASE(lpDSBuffer[numsound]);
  700.             if(WaveFormat!=NULL)  GlobalFreePtr(WaveFormat);
  701.             if(Data!=NULL)  GlobalFreePtr(Data);
  702.             return -1;
  703.         }
  704.  
  705.  
  706.         // Set the pan, volume, and frequency
  707.         lpDSBuffer[numsound]->SetPan(PANMID);
  708.         lpDSBuffer[numsound]->SetVolume(VOLMAX);
  709.         lpDSBuffer[numsound]->SetFrequency(FRQDEFAULT);
  710.         if(Data!=NULL)  GlobalFreePtr(Data);
  711.         numsound++;
  712.         return numsound-1;
  713.     }
  714.     return -1;
  715. */
  716. }
  717.  
  718. //------------------------------------------------------------------------------
  719. //Music Stuff-------------------------------------------------------------------
  720. // Everything under this can go away!!!!
  721. //------------------------------------------------------------------------------
  722. void load_all_music_sounds(char *modname)
  723. {
  724.     // ZZ> This function loads all of the music sounds
  725.     char loadname[128];
  726.     int cnt;
  727.  
  728.     // Reset instruments
  729.     instrumentsloaded = FALSE;
  730.     musicon = FALSE;
  731.     cnt = 0;
  732.     while(cnt < MAXINSTRUMENT)
  733.     {
  734.         instrumenttosound[cnt] = -1;
  735.         cnt++;
  736.     }
  737.     // Load the data
  738.     if(musicvalid)
  739.     {
  740.         cnt = 0;
  741.         while(cnt < MAXINSTRUMENT)
  742.         {
  743.             sprintf(loadname, FILENAME("%s/music%02d.wav"), modname, cnt);
  744.             instrumenttosound[cnt] = load_one_wave(loadname);
  745.             if(instrumenttosound[cnt] != -1)  instrumentsloaded = TRUE;
  746.             cnt++;
  747.         }
  748.     }
  749. }
  750.  
  751. //------------------------------------------------------------------------------
  752. void create_ig_trackmaster()
  753. {
  754.     // ZZ> This function creates a look-up table.  The table tells the
  755.     //     interactive music code which music??.wav file to play next, based on
  756.     //     what we want to play, and what we're are playing currently
  757.  
  758.     // Want to play a normal track...
  759.     igtrackmaster[IGNORMAL][IGNM01] = IGNM01;
  760.     igtrackmaster[IGNORMAL][IGNM02] = IGNM01;
  761.     igtrackmaster[IGNORMAL][IGNM03] = IGNM01;
  762.     igtrackmaster[IGNORMAL][IGSM01] = IGSM03;
  763.     igtrackmaster[IGNORMAL][IGSM02] = IGSM03;
  764.     igtrackmaster[IGNORMAL][IGSM03] = IGNM01;
  765.     igtrackmaster[IGNORMAL][IGCM01] = IGCM03;
  766.     igtrackmaster[IGNORMAL][IGCM02] = IGCM03;
  767.     igtrackmaster[IGNORMAL][IGCM03] = IGNM01;
  768.  
  769.     // Want to play a secret track...
  770.     igtrackmaster[IGSECRET][IGNM01] = IGSM01;
  771.     igtrackmaster[IGSECRET][IGNM02] = IGSM01;
  772.     igtrackmaster[IGSECRET][IGNM03] = IGSM01;
  773.     igtrackmaster[IGSECRET][IGSM01] = IGSM02;
  774.     igtrackmaster[IGSECRET][IGSM02] = IGSM02;
  775.     igtrackmaster[IGSECRET][IGSM03] = IGSM01;
  776.     igtrackmaster[IGSECRET][IGCM01] = IGCM03;
  777.     igtrackmaster[IGSECRET][IGCM02] = IGCM03;
  778.     igtrackmaster[IGSECRET][IGCM03] = IGSM01;
  779.  
  780.     // Want to play a combat track...
  781.     igtrackmaster[IGCOMBAT][IGNM01] = IGCM01;
  782.     igtrackmaster[IGCOMBAT][IGNM02] = IGCM01;
  783.     igtrackmaster[IGCOMBAT][IGNM03] = IGCM01;
  784.     igtrackmaster[IGCOMBAT][IGSM01] = IGSM03;
  785.     igtrackmaster[IGCOMBAT][IGSM02] = IGSM03;
  786.     igtrackmaster[IGCOMBAT][IGSM03] = IGCM01;
  787.     igtrackmaster[IGCOMBAT][IGCM01] = IGCM02;
  788.     igtrackmaster[IGCOMBAT][IGCM02] = IGCM02;
  789.     igtrackmaster[IGCOMBAT][IGCM03] = IGCM01;
  790. }
  791.  
  792. //------------------------------------------------------------------------------
  793. void load_ig_length(char *filename)
  794. {
  795.     // ZZ> This function sets up interactive music...
  796.     FILE* fileread;
  797.     int iTmp;
  798.  
  799.     ignowplaying = IGNM01;
  800.     igpasstime = 0;
  801.     igfilesize = 87142;
  802.     igstopped = TRUE;
  803.     ignexttrack = IGNORMAL;
  804.     igtrackcount = 1;
  805.     fileread = fopen(FILENAME(filename), "r");
  806.     if(fileread)
  807.     {
  808.         globalname = filename;
  809.         fscanf(fileread, "%d", &iTmp);
  810.         igfilesize = iTmp;
  811.         fclose(fileread);
  812.     }
  813.     play_sound_skip(instrumenttosound[ignowplaying], 0);
  814. }
  815.  
  816.  
  817. //------------------------------------------------------------------------------
  818. void check_ig_passage()
  819. {
  820.     // ZZ> This function checks the passages every .20 seconds to see if the track
  821.     //     needs to be changed
  822.     int cnt, x, y;
  823.  
  824.  
  825.     if(igloaded)
  826.     {
  827.         if(igpasstime >= 10)
  828.         {
  829.             // Check the passages
  830.             x = camtrackx;  x = x>>7;
  831.             y = camtracky;  y = y>>7;
  832.             cnt = 0;
  833.             while(cnt < numpassage)
  834.             {
  835.                 // Has the passage been setup for music?
  836.                 if(passtracktype[cnt] != IGNOTRACK)
  837.                 {
  838.                     // Is the camera looking at the passage?
  839.                     if(x >= passtlx[cnt] && x <= passbrx[cnt])
  840.                     {
  841.                         if(y >= passtly[cnt] && y <= passbry[cnt])
  842.                         {
  843.                             // Do the sound...
  844.                             ignexttrack = passtracktype[cnt];
  845.                             igtrackcount = passtrackcount[cnt];
  846.  
  847.                             // Reset the passage to normal
  848.                             passtracktype[cnt] = IGNOTRACK;
  849.                             cnt = numpassage;
  850.                         }
  851.                     }
  852.                 }
  853.                 cnt++;
  854.             }
  855.             igpasstime = 0;
  856.         }
  857.         else
  858.         {
  859.             // Don't need to yet
  860.             igpasstime++;
  861.         }
  862.     }
  863. }
  864.  
  865. //------------------------------------------------------------------------------
  866. void check_ig_music()
  867. {
  868.     // ZZ> This function updates the igmusic counter, and plays the next sound
  869. /* PORT
  870.     int cnt;
  871.     int skip;
  872.     int stopped;
  873.     int oldplaying;
  874.     DWORD dTmp;
  875.  
  876.  
  877.     if(igloaded)
  878.     {
  879.         //  See if we're ready...
  880.         stopped = igstopped;
  881.         lpDSBuffer[instrumenttosound[ignowplaying]]->GetCurrentPosition(&dTmp, NULL);
  882.         cnt = dTmp;  if(cnt == 0)  cnt = igfilesize;
  883.         skip = igfilesize-cnt;  // Bytes left to play
  884.         if(skip < 0)  skip = 0;
  885.         if(skip < 2205)  // 2205 bytes = 100 msec
  886.         {
  887.             // Pick a new track...
  888.             oldplaying = ignowplaying;
  889.             ignowplaying = igtrackmaster[ignexttrack][ignowplaying];
  890.             if(ignowplaying == IGNM01)  ignowplaying = allclock%3;  // A random normal track
  891.             if(oldplaying == ignowplaying && skip > 100)  return;  // Try in vain to fix problems...
  892.  
  893.  
  894.             // Start it playing
  895.             play_sound_skip(instrumenttosound[ignowplaying], 2205-skip);
  896.             stopped = FALSE;
  897.  
  898.  
  899.             // Down the counters
  900.             if(ignowplaying == IGSM02 || ignowplaying == IGCM02)
  901.             {
  902.                 igtrackcount--;
  903.             }
  904.             if(igtrackcount <= 0)  ignexttrack = IGNORMAL;
  905.             skip = igfilesize;
  906.         }
  907.         if(skip < (igfilesize-4000) && igstopped==FALSE)
  908.         {
  909.             // Stop all old sounds before they start playing again
  910.             cnt = 0;
  911.             while(cnt < IGINSTRUMENTS)
  912.             {
  913.                 if(cnt != ignowplaying)
  914.                 {
  915.                     stop_sound(instrumenttosound[cnt]);
  916.                 }
  917.                 cnt++;
  918.             }
  919.             stopped = TRUE;
  920.         }
  921.         igstopped = stopped;
  922.     }
  923. */
  924. }
  925.  
  926.  
  927. //------------------------------------------------------------------------------
  928. void load_all_music_tracks(char *modname)
  929. {
  930.     // ZZ> This function loads the music track file
  931. /*PORT
  932.     char loadname[128];
  933.     FILE* fileread;
  934.     float fTmp;
  935.     float playtime;
  936.     unsigned int writehead;
  937.     int reading;
  938.     unsigned int iTmp;
  939.  
  940.  
  941.     musicon = FALSE;
  942.     numtrack = 0;
  943.     writehead = 0;
  944.     sprintf(loadname, "modules\\%s\\music\\tracks.txt", modname);
  945.     fileread = fopen(loadname, "r");
  946.     if(fileread != NULL)
  947.     {
  948.         while(goto_colon_yesno(fileread))
  949.         {
  950.             fscanf(fileread, "%f", &playtime);
  951.             trackheadstart[numtrack] = writehead;
  952.             trackmaxtime[numtrack] = playtime*ONESECOND;
  953.             reading = TRUE;
  954.             while(reading)
  955.             {
  956.                 goto_colon(fileread);
  957.                 fscanf(fileread, "%f", &fTmp);
  958.                 if(fTmp >= playtime)
  959.                 {
  960.                     reading = FALSE;
  961.                     trackheadend[numtrack] = writehead;
  962.                 }
  963.                 else
  964.                 {
  965.                     trackplaytime[writehead] = fTmp*ONESECOND;
  966.                     fscanf(fileread, "%d", &iTmp);  trackplaypan[writehead] = iTmp;
  967.                     fscanf(fileread, "%d", &iTmp);  trackplayvol[writehead] = iTmp;
  968.                     fscanf(fileread, "%d", &iTmp);  trackplayfrq[writehead] = iTmp;
  969.                     fscanf(fileread, "%d", &iTmp);  trackplayinstrument[writehead] = iTmp;
  970.                     writehead++;
  971.                 }
  972.             }
  973.             numtrack++;
  974.         }
  975.         fclose(fileread);
  976.     }
  977. */
  978. }
  979.  
  980. //------------------------------------------------------------------------------
  981. void load_music_sequence(char *modname)
  982. {
  983.     // ZZ> This function loads the music sequence file
  984. /*PORT
  985.     char loadname[128];
  986.     FILE* fileread;
  987.     unsigned int iTmp;
  988.  
  989.  
  990.     numsequence = 0;
  991.     sequence[0] = 0;
  992.     nextsequence = 0;
  993.  
  994.  
  995.     sprintf(loadname, "modules\\%s\\music\\sequence.txt", modname);
  996.     fileread = fopen(loadname, "r");
  997.     if(fileread)
  998.     {
  999.         while(goto_colon_yesno(fileread))
  1000.         {
  1001.             fscanf(fileread, "%d", &iTmp);
  1002.             sequence[numsequence] = iTmp;
  1003.             numsequence++;
  1004.         }
  1005.         fclose(fileread);
  1006.     }
  1007. */
  1008. }
  1009.  
  1010. //------------------------------------------------------------------------------
  1011. void load_all_music_loops(char *modname)
  1012. {
  1013.     // ZZ> This function loads the music loop file and begins playing
  1014. /*PORT
  1015.     char loadname[128];
  1016.     FILE* fileread;
  1017.     int pan, vol, frq, sound;
  1018.  
  1019.  
  1020.     if(musicvalid)
  1021.     {
  1022.         sprintf(loadname, "modules\\%s\\music\\loops.txt", modname);
  1023.         fileread = fopen(FILENAME(loadname), "r");
  1024.         if(fileread)
  1025.         {
  1026.             while(goto_colon_yesno(fileread))
  1027.             {
  1028.                 fscanf(fileread, "%d", &pan);
  1029.                 fscanf(fileread, "%d", &vol);
  1030.                 fscanf(fileread, "%d", &frq);
  1031.                 fscanf(fileread, "%d", &sound);
  1032.                 sound = instrumenttosound[sound];
  1033.                 pan = (PANRIGHT*pan/100) + (PANLEFT*(100-pan)/100);
  1034.                 vol = (VOLMAX*vol/100) + (VOLMIN*(100-vol)/100);
  1035.                 play_sound_pvf_looped(sound, pan, vol, frq);
  1036.             }
  1037.             fclose(fileread);
  1038.         }
  1039.     }
  1040. */
  1041. }
  1042.  
  1043. //---------------------------------------------------------------------------------------------
  1044. void start_music_track(int track)
  1045. {
  1046.     // ZZ> This function starts playing a new track
  1047. /*PORT
  1048.     if(track < numtrack && musicvalid)
  1049.     {
  1050.         trackhead = trackheadstart[track];
  1051.         tracktime = 0;
  1052.         playingtrack = track;
  1053.         musicon = TRUE;
  1054.     }
  1055. */
  1056. }
  1057.  
  1058. //---------------------------------------------------------------------------------------------
  1059. void play_next_track()
  1060. {
  1061. /*PORT
  1062.     // ZZ> This function begins playing the next track in the sequence
  1063.     start_music_track(sequence[nextsequence]);
  1064.     nextsequence++;
  1065.     if(nextsequence >= numsequence)
  1066.     {
  1067.         nextsequence = 0;
  1068.     }
  1069. */
  1070. }
  1071.  
  1072. //---------------------------------------------------------------------------------------------
  1073. void stop_music()
  1074. {
  1075.     // ZZ> This function stops the music
  1076. /*PORT
  1077.     musicon = FALSE;
  1078. */
  1079. }
  1080.  
  1081. //---------------------------------------------------------------------------------------------
  1082. void change_music_track(int track)
  1083. {
  1084.     // ZZ> This function starts a new track, but at the same time as the old one
  1085.     //     so we don't miss a beat
  1086. /*PORT
  1087.     int cnt;
  1088.  
  1089.     if(track < numtrack)
  1090.     {
  1091.         trackhead = trackheadstart[track];
  1092.         cnt = trackplaytime[trackhead];
  1093.         while(cnt < tracktime)
  1094.         {
  1095.             trackhead++;
  1096.             cnt = trackplaytime[trackhead];
  1097.         }
  1098.         tracktime = 0;
  1099.         playingtrack = track;
  1100.         musicon = TRUE;
  1101.     }
  1102. */
  1103. }
  1104.  
  1105. //---------------------------------------------------------------------------------------------
  1106. void play_next_music_sound()
  1107. {
  1108.     // ZZ> This function plays the next sound if its time has come and advances the
  1109.     //     track head
  1110. /* PORT
  1111.     int     sound;
  1112.     int     pan;
  1113.     int     vol;
  1114.     int     frq;
  1115.     int     fallout;
  1116.  
  1117.  
  1118.     if(musicon)
  1119.     {
  1120.         // Play all the current sounds
  1121.         fallout = FALSE;
  1122.         while(trackplaytime[trackhead] == tracktime && fallout == FALSE)
  1123.         {
  1124.             if(trackhead < trackheadend[playingtrack])
  1125.             {
  1126.                 sound = instrumenttosound[trackplayinstrument[trackhead]];
  1127.                 pan = trackplaypan[trackhead];
  1128.                 pan = (PANRIGHT*pan/100) + (PANLEFT*(100-pan)/100);
  1129.                 vol = trackplayvol[trackhead];
  1130.                 vol = (VOLMAX*vol/100) + (VOLMIN*(100-vol)/100);
  1131.                 frq = trackplayfrq[trackhead];
  1132.                 play_sound_pvf(sound, pan, vol, frq);
  1133.             }
  1134.             else
  1135.             {
  1136.                 fallout = TRUE;
  1137.             }
  1138.             trackhead++;
  1139.         }
  1140.         // Start new track if finished
  1141.         tracktime++;
  1142.         if(tracktime >= trackmaxtime[playingtrack])
  1143.         {
  1144.             play_next_track();
  1145.         }
  1146.     }
  1147. */
  1148. }
  1149.  
  1150.