Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
354
GameTools/SoundLib/Sound.cpp
Normal file
354
GameTools/SoundLib/Sound.cpp
Normal file
@@ -0,0 +1,354 @@
|
||||
// Sound.cpp: implementation of the CSound class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "WaveLoader.h"
|
||||
#include "Sound.h"
|
||||
#include "SoundMgr.h"
|
||||
|
||||
|
||||
CSound::CSound() : m_ppDSBuffer( NULL ),
|
||||
m_pWaveFile( NULL ),
|
||||
m_dwNumBuffers( 0 ),
|
||||
m_dwDSBufferSize( 0 ),
|
||||
m_bSound3D( false ),
|
||||
m_bLoop( false ),
|
||||
m_fVolume( VOLUME_MAX ),
|
||||
m_dwLastPlayTime( 0 ),
|
||||
m_dwLatestPlayIndex( 0 ),
|
||||
m_iPreserveScore( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CSound::~CSound()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
|
||||
HRESULT CSound::RestoreBuffer( LPDIRECTSOUNDBUFFER pDSB, bool* pbWasRestored )
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if( pDSB == NULL )
|
||||
return CO_E_NOTINITIALIZED;
|
||||
if( pbWasRestored )
|
||||
*pbWasRestored = FALSE;
|
||||
|
||||
DWORD dwStatus;
|
||||
if( FAILED( hr = pDSB->GetStatus( &dwStatus ) ) )
|
||||
return E_FAIL;
|
||||
|
||||
if( dwStatus & DSBSTATUS_BUFFERLOST )
|
||||
{
|
||||
do
|
||||
{
|
||||
hr = pDSB->Restore();
|
||||
if( hr == DSERR_BUFFERLOST )
|
||||
Sleep( 10 );
|
||||
}
|
||||
while( ( hr = pDSB->Restore() ) == DSERR_BUFFERLOST );
|
||||
|
||||
if( pbWasRestored != NULL )
|
||||
*pbWasRestored = TRUE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LPDIRECTSOUNDBUFFER CSound::GetFreeBuffer()
|
||||
{
|
||||
if( m_ppDSBuffer == NULL )
|
||||
return FALSE;
|
||||
|
||||
for( DWORD i=0; i<m_dwNumBuffers; i++ )
|
||||
{
|
||||
if( m_ppDSBuffer[i] )
|
||||
{
|
||||
DWORD dwStatus = 0;
|
||||
m_ppDSBuffer[i]->GetStatus( &dwStatus );
|
||||
if ( ( dwStatus & DSBSTATUS_PLAYING ) == 0 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( i != m_dwNumBuffers )
|
||||
{
|
||||
m_dwLatestPlayIndex = i;
|
||||
return m_ppDSBuffer[ i ];
|
||||
}
|
||||
else
|
||||
return m_ppDSBuffer[ rand() % m_dwNumBuffers ];
|
||||
}
|
||||
|
||||
|
||||
LPDIRECTSOUNDBUFFER CSound::GetBuffer( DWORD dwIndex )
|
||||
{
|
||||
if( m_ppDSBuffer == NULL )
|
||||
return NULL;
|
||||
if( dwIndex >= m_dwNumBuffers )
|
||||
return NULL;
|
||||
|
||||
return m_ppDSBuffer[dwIndex];
|
||||
}
|
||||
|
||||
|
||||
void CSound::Stop()
|
||||
{
|
||||
HRESULT hr = 0;
|
||||
|
||||
for( DWORD i=0; i<m_dwNumBuffers; i++ )
|
||||
hr |= m_ppDSBuffer[i]->Stop();
|
||||
|
||||
if( FAILED(hr) )
|
||||
MessageBox( NULL, "hr |= m_ppDSBuffer[i]->Stop()", "CSound::Stop", MB_OK );
|
||||
}
|
||||
|
||||
|
||||
void CSound::Reset()
|
||||
{
|
||||
HRESULT hr = 0;
|
||||
|
||||
for( DWORD i=0; i<m_dwNumBuffers; i++ )
|
||||
hr |= m_ppDSBuffer[i]->SetCurrentPosition( 0 );
|
||||
|
||||
if( FAILED(hr) )
|
||||
MessageBox( NULL, "hr |= m_ppDSBuffer[i]->SetCurrentPosition",
|
||||
"CSound::Stop", MB_OK );
|
||||
}
|
||||
|
||||
|
||||
bool CSound::IsPlaying()
|
||||
{
|
||||
bool bIsPlaying = false;
|
||||
|
||||
if( m_ppDSBuffer == NULL )
|
||||
return false;
|
||||
|
||||
for( DWORD i=0; i<m_dwNumBuffers; i++ )
|
||||
{
|
||||
if( m_ppDSBuffer[i] )
|
||||
{
|
||||
DWORD dwStatus = 0;
|
||||
m_ppDSBuffer[i]->GetStatus( &dwStatus );
|
||||
bIsPlaying |= ( ( dwStatus & DSBSTATUS_PLAYING ) != 0 );
|
||||
}
|
||||
}
|
||||
|
||||
return bIsPlaying;
|
||||
}
|
||||
|
||||
|
||||
bool CSound::Create( const char* strFileName, DWORD dwNumBuffers )
|
||||
{
|
||||
DWORD i;
|
||||
DWORD dwDSBufferSize = NULL;
|
||||
m_dwNumBuffers = dwNumBuffers;
|
||||
|
||||
LPDIRECTSOUND8 pDS = CSoundManager::_GetInstance()->GetDirectSound();
|
||||
m_ppDSBuffer = new LPDIRECTSOUNDBUFFER8[dwNumBuffers];
|
||||
for( i = 0; i < dwNumBuffers; ++i )
|
||||
{
|
||||
m_ppDSBuffer[i] = 0;
|
||||
}
|
||||
m_pWaveFile = new CWaveLoader;
|
||||
|
||||
if( FAILED(m_pWaveFile->Open((LPSTR)strFileName, NULL, WAVEFILE_READ)) )
|
||||
{
|
||||
char buf[MAX_PATH] = {0};
|
||||
sprintf( buf, "<EFBFBD>ش<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>. : %s \n CSound::Create", strFileName );
|
||||
MessageBox( NULL, buf, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>忡<EFBFBD><EFBFBD>", MB_OK );
|
||||
SAFE_DELETE(m_pWaveFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_dwDSBufferSize = m_pWaveFile->GetSize();
|
||||
|
||||
WAVEFORMATEX wfx;
|
||||
ZeroMemory( &wfx, sizeof(WAVEFORMATEX) );
|
||||
wfx.nChannels = m_pWaveFile->m_pwfx->nChannels;
|
||||
wfx.nSamplesPerSec = m_pWaveFile->m_pwfx->nSamplesPerSec;
|
||||
wfx.wBitsPerSample = m_pWaveFile->m_pwfx->wBitsPerSample;
|
||||
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels;
|
||||
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
|
||||
|
||||
if( m_bSound3D && wfx.nChannels != 1 )
|
||||
{
|
||||
MessageBox( NULL, "3DSound Only Acquire One Channel", "Sound::Create", MB_OK );
|
||||
wfx.nChannels = 1;
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
//Create Buffer
|
||||
DSBUFFERDESC dsbd;
|
||||
ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
|
||||
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbd.dwFlags = DSBCAPS_CTRLVOLUME;
|
||||
if( m_bSound3D ) dsbd.dwFlags |= DSBCAPS_CTRL3D|DSBCAPS_MUTE3DATMAXDISTANCE;
|
||||
dsbd.dwBufferBytes = m_dwDSBufferSize;
|
||||
dsbd.guid3DAlgorithm = m_bSound3D ? CSoundManager::_GetInstance()->GetInitProp()->m_guidSound3DAlgorithm : GUID_NULL;
|
||||
dsbd.lpwfxFormat = &wfx;
|
||||
|
||||
|
||||
//========================================
|
||||
LPDIRECTSOUNDBUFFER tempBuffer;
|
||||
if( FAILED(pDS->CreateSoundBuffer( &dsbd, &tempBuffer, NULL )) )
|
||||
{
|
||||
//MessageBox( NULL, "pDS->CreateSoundBuffer( &dsbd, &tempBuffer, NULL )", "CSound::Create", MB_OK );
|
||||
SAFE_RELEASE( tempBuffer );
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
if( FAILED(tempBuffer->QueryInterface( IID_IDirectSoundBuffer8, (LPVOID*)m_ppDSBuffer )) )
|
||||
{
|
||||
//MessageBox( NULL, "pDS->CreateSoundBuffer( &dsbd, &tempBuffer, NULL )", "CSound::Create", MB_OK );
|
||||
SAFE_RELEASE( tempBuffer );
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
SAFE_RELEASE(tempBuffer)
|
||||
|
||||
for( i = 1; i < dwNumBuffers; i++ )
|
||||
{
|
||||
if( FAILED(pDS->DuplicateSoundBuffer( m_ppDSBuffer[0], (LPDIRECTSOUNDBUFFER*)&m_ppDSBuffer[i])) )
|
||||
{
|
||||
//MessageBox( NULL, "pDS->DuplicateSoundBuffer( m_ppDSBuffer[0], &m_ppDSBuffer[i])",
|
||||
// "CSound::Create", MB_OK );
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
FillBuffer( m_ppDSBuffer[0] );
|
||||
//===============================================
|
||||
|
||||
|
||||
/*
|
||||
if( FAILED(pDS->CreateSoundBuffer( &dsbd, &m_ppDSBuffer[0], NULL )) )
|
||||
{
|
||||
//MessageBox( NULL, "pDS->CreateSoundBuffer( &dsbd, &m_ppDSBuffer[0], NULL )",
|
||||
// "CSound::Create", MB_OK );
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
for( i = 1; i < dwNumBuffers; i++ )
|
||||
{
|
||||
if( FAILED(pDS->DuplicateSoundBuffer( m_ppDSBuffer[0], &m_ppDSBuffer[i])) )
|
||||
{
|
||||
//MessageBox( NULL, "pDS->DuplicateSoundBuffer( m_ppDSBuffer[0], &m_ppDSBuffer[i])",
|
||||
// "CSound::Create", MB_OK );
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
FillBuffer( m_ppDSBuffer[0] );
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CSound::Destroy()
|
||||
{
|
||||
for( DWORD i = 0; i < m_dwNumBuffers; i++ )
|
||||
{
|
||||
SAFE_RELEASE( m_ppDSBuffer[i] );
|
||||
}
|
||||
|
||||
SAFE_DELETE_ARRAY( m_ppDSBuffer );
|
||||
SAFE_DELETE( m_pWaveFile );
|
||||
}
|
||||
|
||||
|
||||
void CSound::Play()
|
||||
{
|
||||
if( 0 == this )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_dwLastPlayTime = timeGetTime();
|
||||
|
||||
bool bRestored;
|
||||
LPDIRECTSOUNDBUFFER pDSB = GetFreeBuffer();
|
||||
|
||||
if( FAILED(RestoreBuffer(pDSB, &bRestored)) )
|
||||
{
|
||||
MessageBox(NULL, "FAILED(RestoreBuffer(pDSB, &bRestored))",
|
||||
"CSound::Play", MB_OK );
|
||||
return;
|
||||
}
|
||||
|
||||
if( bRestored )
|
||||
{
|
||||
FillBuffer( pDSB );
|
||||
}
|
||||
|
||||
pDSB->Play(0,0, m_bLoop ? DSBPLAY_LOOPING:0 );
|
||||
}
|
||||
|
||||
|
||||
void CSound::FillBuffer( LPDIRECTSOUNDBUFFER pDSBuffer )
|
||||
{
|
||||
VOID* pDSLockedBuffer = NULL;
|
||||
DWORD dwDSLockedBufferSize = 0;
|
||||
DWORD dwWavDataRead = 0;
|
||||
|
||||
if( FAILED(RestoreBuffer( pDSBuffer, NULL)) )
|
||||
{
|
||||
MessageBox( NULL, "FAILED(RestoreBuffer( pDSBuffer, NULL))",
|
||||
"CSound::FillBuffer", MB_OK );
|
||||
return;
|
||||
}
|
||||
|
||||
if( FAILED(pDSBuffer->Lock(0, 0, &pDSLockedBuffer, &dwDSLockedBufferSize,
|
||||
NULL, NULL, DSBLOCK_ENTIREBUFFER ) ) )
|
||||
{
|
||||
MessageBox( NULL, "FAILED(pDSBuffer->Lock", "CSound::FillBuffer", MB_OK );
|
||||
return;
|
||||
}
|
||||
|
||||
m_pWaveFile->ResetFile();
|
||||
|
||||
if( FAILED(m_pWaveFile->Read((BYTE*)pDSLockedBuffer, dwDSLockedBufferSize, &dwWavDataRead)) )
|
||||
{
|
||||
MessageBox( NULL, "FAILED(m_pWaveFile->Read", "CSound::FillBuffer", MB_OK );
|
||||
return;
|
||||
}
|
||||
|
||||
if( dwWavDataRead == 0 )
|
||||
{
|
||||
MessageBox( NULL, "dwWavDataRead == 0", "CSound::FillBuffer", MB_OK );
|
||||
return;
|
||||
}
|
||||
|
||||
pDSBuffer->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 );
|
||||
}
|
||||
|
||||
|
||||
void CSound::SetVolume( float fVol )
|
||||
{
|
||||
if( !m_ppDSBuffer ) return;
|
||||
|
||||
m_fVolume = Clamp( fVol, VOLUME_MIN, VOLUME_MAX );
|
||||
float fMasterVol = CSoundManager::_GetInstance()->GetVolume();
|
||||
int iVol = LinearToLogVol(m_fVolume * fMasterVol);
|
||||
|
||||
if( FAILED(m_ppDSBuffer[0]->SetVolume(iVol)) )
|
||||
{
|
||||
MessageBox( NULL, "FAILED(m_ppDSBuffer[0]->SetVolume(iVol))",
|
||||
"CSound::SetVolume", MB_OK );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user