woaidaima2016 发表于 2017-6-13 11:17:26

水果+控制+机器人【源码】

http://img.woaidaima.com//upload/image/20170523/1495499417035006098.pnghttp://img.woaidaima.com//upload/image/20170523/1495499418708054168.png/////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1998 by J鰎g K鰊ig
// All rights reserved
//
// This file is part of the completely free tetris clone "CGTetris".
//
// This is free software.
// You may redistribute it by any means providing it is not sold for profit
// without the authors written consent.
//
// No warrantee of any kind, expressed or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
//
// Send bug reports, bug fixes, enhancements, requests, flames, etc., and
// I'll try to keep a version up to date.I can be reached as follows:
//    J.Koenig@adg.de               (company site)
//    Joerg.Koenig@rhein-neckar.de    (private site)
/////////////////////////////////////////////////////////////////////////////


// DirectSound.cpp: implementation of the CDirectSound class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DirectSound.h"

// The following macro is defined since DirectX 5, but will work with
// older versions too.
#ifndef DSBLOCK_ENTIREBUFFER
    #define DSBLOCK_ENTIREBUFFER      0x00000002
#endif

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

static void DSError( HRESULT hRes ) {
    switch(hRes) {
      case DS_OK: TRACE0("NO ERROR\n"); break;
      case DSERR_ALLOCATED: TRACE0("ALLOCATED\n"); break;
      case DSERR_INVALIDPARAM: TRACE0("INVALIDPARAM\n"); break;
      case DSERR_OUTOFMEMORY: TRACE0("OUTOFMEMORY\n"); break;
      case DSERR_UNSUPPORTED: TRACE0("UNSUPPORTED\n"); break;
      case DSERR_NOAGGREGATION: TRACE0("NOAGGREGATION\n"); break;
      case DSERR_UNINITIALIZED: TRACE0("UNINITIALIZED\n"); break;
      case DSERR_BADFORMAT: TRACE0("BADFORMAT\n"); break;
      case DSERR_ALREADYINITIALIZED: TRACE0("ALREADYINITIALIZED\n"); break;
      case DSERR_BUFFERLOST: TRACE0("BUFFERLOST\n"); break;
      case DSERR_CONTROLUNAVAIL: TRACE0("CONTROLUNAVAIL\n"); break;
      case DSERR_GENERIC: TRACE0("GENERIC\n"); break;
      case DSERR_INVALIDCALL: TRACE0("INVALIDCALL\n"); break;
      case DSERR_OTHERAPPHASPRIO: TRACE0("OTHERAPPHASPRIO\n"); break;
      case DSERR_PRIOLEVELNEEDED: TRACE0("PRIOLEVELNEEDED\n"); break;
      default: TRACE1("%lu\n",hRes);break;
    }
}

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

LPDIRECTSOUND CDirectSound::m_lpDirectSound;
DWORD CDirectSound::m_dwInstances;


CDirectSound::CDirectSound()
{
    m_lpDirectSound = 0;
    m_pDsb = 0;
    m_pTheSound = 0;
    m_dwTheSound = 0;
    m_bEnabled = TRUE;

    ++m_dwInstances;
}

CDirectSound::~CDirectSound()
{
    if( m_pDsb )
      m_pDsb->Release();

    if( !--m_dwInstances && m_lpDirectSound ) {
      m_lpDirectSound->Release();
      m_lpDirectSound = 0;
    }
}

BOOL CDirectSound::Create(LPCTSTR pszResource, CWnd * pWnd)
{
    //////////////////////////////////////////////////////////////////
    // load resource
    HINSTANCE hApp = ::GetModuleHandle(0);
    ASSERT(hApp);

    HRSRC hResInfo = ::FindResource(hApp, pszResource, TEXT("WAVE"));
    if(hResInfo == 0)
      return FALSE;

    HGLOBAL hRes = ::LoadResource(hApp, hResInfo);
    if(hRes == 0)
      return FALSE;

    LPVOID pTheSound = ::LockResource(hRes);
    if(pTheSound == 0)
      return FALSE;

    return Create(pTheSound, pWnd);
}


BOOL CDirectSound :: Create(LPVOID pSoundData, CWnd * pWnd) {
    if(pWnd == 0)
      pWnd = AfxGetApp()->GetMainWnd();

    ASSERT(pWnd != 0);
    ASSERT(::IsWindow(pWnd->GetSafeHwnd()));

    ASSERT(pSoundData != 0);

    //////////////////////////////////////////////////////////////////
    // create direct sound object
   
    if( m_lpDirectSound == 0 ) {
      // Someone might use sounds for starting apps. This may cause
      // DirectSoundCreate() to fail because the driver is used by
      // anyone else. So wait a little before starting with the work ...
      HRESULT hRes = DS_OK;
      short nRes = 0;

      do {
            if( nRes )
                ::Sleep(500);
            hRes = ::DirectSoundCreate(0, &m_lpDirectSound, 0);
            ++nRes;
      } while( nRes < 10 && (hRes == DSERR_ALLOCATED || hRes == DSERR_NODRIVER) );

      if( hRes != DS_OK )
            return FALSE;
   
      m_lpDirectSound->SetCooperativeLevel(pWnd->GetSafeHwnd(), DSSCL_NORMAL);
    }

    ASSERT(m_lpDirectSound != 0);

    WAVEFORMATEX * pcmwf;
    if( ! GetWaveData(pSoundData, pcmwf, m_pTheSound, m_dwTheSound) ||
      ! CreateSoundBuffer(pcmwf) ||
      ! SetSoundData(m_pTheSound, m_dwTheSound) )
      return FALSE;

    return TRUE;
}


BOOL CDirectSound :: GetWaveData(void * pRes, WAVEFORMATEX * & pWaveHeader, void * & pbWaveData, DWORD & cbWaveSize) {
    pWaveHeader = 0;
    pbWaveData = 0;
    cbWaveSize = 0;

    DWORD * pdw = (DWORD *)pRes;
    DWORD dwRiff = *pdw++;
    DWORD dwLength = *pdw++;
    DWORD dwType = *pdw++;

    if( dwRiff != mmioFOURCC('R', 'I', 'F', 'F') )
      return FALSE;      // not even RIFF

    if( dwType != mmioFOURCC('W', 'A', 'V', 'E') )
      return FALSE;      // not a WAV

    DWORD * pdwEnd = (DWORD *)((BYTE *)pdw + dwLength-4);

    while( pdw < pdwEnd ) {
      dwType = *pdw++;
      dwLength = *pdw++;

      switch( dwType ) {
            case mmioFOURCC('f', 'm', 't', ' '):
                if( !pWaveHeader ) {
                  if( dwLength < sizeof(WAVEFORMAT) )
                        return FALSE;      // not a WAV

                  pWaveHeader = (WAVEFORMATEX *)pdw;

                  if( pbWaveData && cbWaveSize )
                        return TRUE;
                }
                break;

            case mmioFOURCC('d', 'a', 't', 'a'):
                pbWaveData = LPVOID(pdw);
                cbWaveSize = dwLength;

                if( pWaveHeader )
                  return TRUE;
                break;
      }
      pdw = (DWORD *)((BYTE *)pdw + ((dwLength+1)&~1));
    }

    return FALSE;
}


BOOL CDirectSound::CreateSoundBuffer(WAVEFORMATEX * pcmwf)
{
    DSBUFFERDESC dsbdesc;

    // Set up DSBUFFERDESC structure.
    memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); // Zero it out.
    dsbdesc.dwSize = sizeof(DSBUFFERDESC);
    // Need no controls (pan, volume, frequency).
    dsbdesc.dwFlags = DSBCAPS_STATIC;      // assumes that the sound is played often
    dsbdesc.dwBufferBytes = m_dwTheSound;
    dsbdesc.lpwfxFormat = pcmwf;    // Create buffer.
    HRESULT hRes;
    if( DS_OK != (hRes = m_lpDirectSound->CreateSoundBuffer(&dsbdesc, &m_pDsb, 0)) ) {
      // Failed.
      DSError(hRes);
      m_pDsb = 0;
      return FALSE;
    }

    return TRUE;
}


BOOL CDirectSound::SetSoundData(void * pSoundData, DWORD dwSoundSize) {
    LPVOID lpvPtr1;
    DWORD dwBytes1;
    // Obtain write pointer.
    HRESULT hr = m_pDsb->Lock(0, 0, &lpvPtr1, &dwBytes1, 0, 0, DSBLOCK_ENTIREBUFFER);   
    // If DSERR_BUFFERLOST is returned, restore and retry lock.
    if(DSERR_BUFFERLOST == hr) {
      m_pDsb->Restore();
      hr = m_pDsb->Lock(0, 0, &lpvPtr1, &dwBytes1, 0, 0, DSBLOCK_ENTIREBUFFER);
    }
    if(DS_OK == hr) {
      // Write to pointers.
      ::CopyMemory(lpvPtr1, pSoundData, dwBytes1);
      // Release the data back to DirectSound.
      hr = m_pDsb->Unlock(lpvPtr1, dwBytes1, 0, 0);
      if(DS_OK == hr)
            return TRUE;
    }
    // Lock, Unlock, or Restore failed.
    return FALSE;
}

void CDirectSound::Play(DWORD dwStartPosition, BOOL bLoop)
{
    if( ! IsValid() || ! IsEnabled() )
      return;      // no chance to play the sound ...

    if( dwStartPosition > m_dwTheSound )
      dwStartPosition = m_dwTheSound;
    m_pDsb->SetCurrentPosition(dwStartPosition);
    if( DSERR_BUFFERLOST == m_pDsb->Play(0, 0, bLoop ? DSBPLAY_LOOPING : 0) ) {
      // another application had stolen our buffer
      // Note that a "Restore()" is not enough, because
      // the sound data is invalid after Restore().
      SetSoundData(m_pTheSound, m_dwTheSound);

      // Try playing again
      m_pDsb->Play(0, 0, bLoop ? DSBPLAY_LOOPING : 0);
    }
}

void CDirectSound::Stop()
{
    if( IsValid() )
      m_pDsb->Stop();
}

void CDirectSound::Pause()
{
    Stop();
}

void CDirectSound::Continue()
{
    if( IsValid() ) {
      DWORD dwPlayCursor, dwWriteCursor;
      m_pDsb->GetCurrentPosition(&dwPlayCursor, &dwWriteCursor);
      Play(dwPlayCursor);
    }
}

BOOL CDirectSound::IsValid() const
{
    return (m_lpDirectSound && m_pDsb && m_pTheSound && m_dwTheSound) ? TRUE : FALSE;
}

页: [1]
查看完整版本: 水果+控制+机器人【源码】