⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 win_snd.c

📁 经典的老游戏digger的源代码.提起digger相信很多人会回忆起曾经为了它挑灯夜战的时光
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Digger Remastered
   Copyright (c) Andrew Jenner 1998-2004 */

#include "def.h"
#include <stdlib.h>
#include "newsnd.h"
#include "win_dig.h"
#include "win_snd.h"
#include "sound.h"

#define WAVE_OUT_DEVICE 2
#define DIRECT_SOUND_DEVICE 1

LPDIRECTSOUND lpds;                   /* the DirectSound object */
LPDIRECTSOUNDBUFFER lpdsb;            /* the DirectSoundBuffer that all sound is written to */
int sound_output_device=0;            /* 0=sound disabled;1=directsound;2=standard windows waveOut*/

samp* sound_buffer=(samp*) NULL;

extern bool sndflag;
int sound_card_capture_flag=0;
BOOL sound_buffer_playing=FALSE;      /* DirectSound only: has playback been started */
LONG dx_sound_volume;                 /* current volume (percentage from 0 to 100)   */
bool wave_device_available;           /* is there a DirectSound device or any other wave device that can be used? */
HWAVEOUT wave_output_device = (HWAVEOUT) NULL;   /* handle to wave output device (when not using DirectSound) */

#define NUM_SOUND_BUFFERS 2

samp far*  waveout_buffer[NUM_SOUND_BUFFERS] = {NULL, NULL}; /* Non DirectSound only */
WAVEHDR waveheader[NUM_SOUND_BUFFERS]; /* Non DirectSound only */
bool fill_sound_buffer=FALSE;
Uint4 waveout_sample_rate;             /* Non DirectSound only: just stores the waveout_sample_rate that was in the INI file */

/* DIRECTSOUND                                                                                */
/* If using DirectSound, a circular buffer is used similar to the DOS/Soundblaster version.   */
/* s1fillbuffer() operates more or less the same as the DOS version.                          */



/* NON-DIRECTSOUND                                                                            */
/* If using the standard Windows waveOut functions, things are a little strange...            */
/* There are two WAVEHDR structures, each with an asoociated sound buffer.  When the playback */
/* is first started, both of these buffers are 'prepared' (locked) and written out.  When the */
/* first buffer is finished playing, the second starts playing automatically, and the         */
/* waveOutProc function is called to notify the program that the first buffer is finished     */
/* playing.  In the waveOutProc function, the first header/buffer is 'unprepared', then       */
/* filled with new sound data (this is obtained from 'buffer' which is filled in              */
/* 's1fillbuffer'), 'prepared', and finally written out with 'waveOutWrite'. Then, when the   */
/* second buffer is finished being played, waveOutProc is again called, and the second buffer */
/* is unprepared, filled, prepared, and written out also.  Playback continues to alternate    */
/* between these two headers/buffers for the entire game.                                     */

/* Currently, s1fillbuffer() fills the 'buffer' variable, similar to the Soundblaster version,*/
/* except that it doesn't automatically wrap around to the beginning of 'buffer'.             */
/* Also, this function must call 'waveOutGetPosition' to try to control the rate at which     */
/* 'buffer' is filled (otherwise the sound is really messed up, especially the music at the   */
/* end of a level).                                                                           */

/* waveOut_fillbuffer() copies the sound data from 'buffer' to one of the waveheader/buffers  */
/* and resets the 'last' variable to indicate that s1fillbuffer should start filling 'buffer' */
/* up again with new sound data.                                                              */


void destroy_sound_buffers()
{
  MMRESULT mmresult;
  int i;
  for (i=0;i<NUM_SOUND_BUFFERS;i++)
    if (waveout_buffer[i])
    {
      farfree (waveout_buffer[i]);
      waveout_buffer[i]=NULL;
    }
  if (sound_buffer)
  {
    farfree (sound_buffer);
    sound_buffer=NULL;
  }
}


void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
  switch (uMsg)
  {
  case MM_WOM_DONE:
    unprepare_sound_data((WAVEHDR*) dwParam1);  /* unlock the sound buffer, so we can fill it with new data */
    if (!shutting_down)
    {
      play_sound_data((WAVEHDR*) dwParam1);
    }
    break;
  }
}

bool setsounddevice(int base,int irq,int dma,Uint4 samprate,Uint4 bufsize)
{
  HRESULT hr;
  samp* lpvAudioPtr1;
  DWORD dwAudioBytes1;
  samp* lpvAudioPtr2;
  DWORD dwAudioBytes2;

  bufsize<<=1;
  size=bufsize;

  if (sound_output_device==DIRECT_SOUND_DEVICE && !lpDirectSoundCreate)
  {
    sound_output_device=WAVE_OUT_DEVICE;
  }

  switch (sound_output_device)
  {
  case DIRECT_SOUND_DEVICE:
    hr = DirectSoundCreate(NULL, &lpds, NULL);
    if (!hr == DS_OK)
    {
      wave_device_available=FALSE;
      return FALSE;
    }
    wave_device_available=TRUE;
//    hr = IDirectSound_SetCooperativeLevel(lpds, hWnd, DSSCL_PRIORITY);
    if (!hr == DS_OK)
      fatal_error(hr, "DirectSound_SetCooperativeLevel: FAILED");

    if (!create_windows_sound_buffer(samprate, bufsize))
      fatal_error(0, "create_windows_sound_buffer FAILED");

//    hr=IDirectSoundBuffer_Lock(lpdsb,0,bufsize,(void **)&lpvAudioPtr1,
//                               &dwAudioBytes1,(void **)&lpvAudioPtr2,
//                               &dwAudioBytes2,(DWORD)NULL);
    switch (hr)
    {
    case DSERR_BUFFERLOST:
      fatal_error(hr, "DirectSoundBuffer: lock FAILED  (BufferLost)");
    case DSERR_INVALIDCALL:
      fatal_error(hr, "DirectSoundBuffer: lock FAILED  (InvalidCall)");
    case DSERR_INVALIDPARAM:
      fatal_error(hr, "DirectSoundBuffer: lock FAILED  (InvalidParam)");
    case DSERR_PRIOLEVELNEEDED:
      fatal_error(hr, "DirectSoundBuffer: lock FAILED  (PrioLevelNeeded)");
    }

    if (hr==DS_OK) {
      memset(lpvAudioPtr1, (MIN_SAMP+MAX_SAMP)>>1, dwAudioBytes1);
      IDirectSoundBuffer_Unlock(lpdsb,lpvAudioPtr1,dwAudioBytes1,lpvAudioPtr2,
                                dwAudioBytes2);
    }
    s1fillbuffer();
    sound_buffer_playing=TRUE;
//    hr = IDirectSoundBuffer_Play(lpdsb, 0, 0, DSBPLAY_LOOPING);
    if (hr!=DS_OK)
      fatal_error(hr, "DirectSoundBuffer_Play FAILED");
    return TRUE;

  case WAVE_OUT_DEVICE:
    wave_device_available=waveOutGetNumDevs();
    if (wave_device_available)
       create_windows_sound_buffer(samprate, bufsize);
    waveout_sample_rate=samprate;
    return TRUE;
  case 0:  // disabled
    wave_device_available=FALSE;
    return TRUE;
  }
  return FALSE;
}

bool initsounddevice(void)
{
  return TRUE;
}

void killsounddevice(void)
{
}

BOOL create_windows_sound_buffer(Uint4 samprate, Uint4 bufsize)
{
  PCMWAVEFORMAT pcmwf;
  int i;
  HRESULT hr;
  DSBUFFERDESC dsbdesc;
  MMRESULT mmresult;

  if (!wave_device_available)
    return FALSE;
  memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT));
  pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM;
  pcmwf.wf.nChannels = 1;
  pcmwf.wf.nSamplesPerSec = samprate;
  pcmwf.wf.nBlockAlign = 1;
  pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
  pcmwf.wBitsPerSample = 8;
  /* Using Directsound */
  if (sound_output_device==DIRECT_SOUND_DEVICE)
  {
    memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); // Zero it out.
    dsbdesc.dwSize = sizeof(DSBUFFERDESC);
    dsbdesc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;
    dsbdesc.dwBufferBytes = bufsize;
    dsbdesc.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf;
//    hr = IDirectSound_CreateSoundBuffer(lpds, &dsbdesc, &lpdsb, NULL);
    if SUCCEEDED(hr)
    {
      return TRUE;
    }
    else
    {
      lpdsb = NULL;
      return FALSE;
    }
  }
  if (sound_output_device==WAVE_OUT_DEVICE)
  {
    /* Not using DirectSound */
    mmresult=waveOutOpen(&wave_output_device, WAVE_MAPPER, (LPWAVEFORMATEX) &pcmwf, (DWORD) waveOutProc, 0, CALLBACK_FUNCTION);
    if (mmresult!=MMSYSERR_NOERROR)
    {
      wave_device_available=FALSE;
      return FALSE;
    }
    else
    {
      sound_buffer=(samp*) malloc(bufsize*sizeof(samp));
      if (!sound_buffer)
        fatal_error(0, "create_windows_sound_buffer: FAILED to allocate memory for 'sound_buffer'");
      for (i=0;i<NUM_SOUND_BUFFERS;i++)
      {
        /* create sound buffers and WAVEHEADERs */
        waveout_buffer[i]=(samp*) malloc(bufsize*sizeof(samp));
        if (waveout_buffer[i]==NULL)
        {
          wave_device_available=FALSE;
          return FALSE;
        }
        farmemset(waveout_buffer[i], (MIN_SAMP+MAX_SAMP)>>1, bufsize*sizeof(samp));
        waveheader[i].lpData=waveout_buffer[i];
        waveheader[i].dwBufferLength=bufsize*sizeof(samp);
        waveheader[i].dwBytesRecorded=0;
        waveheader[i].dwUser=0;
        waveheader[i].dwFlags=0;
        waveheader[i].dwLoops=0;
        waveheader[i].lpNext=0;
        waveheader[i].reserved=0;
      }
      for (i=0;i<NUM_SOUND_BUFFERS;i++)
      {
        /* start playing the wavedata */
        play_sound_data(&waveheader[i]);
      }
      return TRUE;
    }
  }
  return FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -