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>
313 lines
7.6 KiB
C++
313 lines
7.6 KiB
C++
|
|
#include "DirectMusic.h"
|
|
|
|
#include <dmusicc.h>
|
|
#include <dmusici.h>
|
|
#include <set>
|
|
|
|
#include "MusicBuffer.h"
|
|
#include "DMusic_OggLoader.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
|
|
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
|
|
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
CDirectMusic & CDirectMusic::GetInstance()
|
|
{
|
|
static CDirectMusic dmusic;
|
|
return dmusic;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
CDirectMusic::CDirectMusic()
|
|
: m_pWavLoader( NULL )
|
|
, m_pOggLoader( NULL )
|
|
, m_pPerformance( NULL )
|
|
, m_bCOMInitialized( false )
|
|
|
|
, m_pDSListener( NULL )
|
|
|
|
, m_pMusicBuffers( new MUSICBUFFERS )
|
|
{
|
|
if( !m_bCOMInitialized )
|
|
{
|
|
CoInitialize( NULL );
|
|
m_bCOMInitialized = true;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
CDirectMusic::~CDirectMusic()
|
|
{
|
|
Destroy();
|
|
|
|
if( m_bCOMInitialized )
|
|
{
|
|
CoUninitialize();
|
|
m_bCOMInitialized = false;
|
|
}
|
|
|
|
delete m_pMusicBuffers;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CDirectMusic::Create( HWND hWnd, DWORD dwPChannels )
|
|
{
|
|
if( m_pWavLoader || m_pOggLoader || m_pPerformance )
|
|
return;
|
|
|
|
//Wav 로더 생성
|
|
HRESULT hr = CoCreateInstance( CLSID_DirectMusicLoader,
|
|
NULL,
|
|
CLSCTX_INPROC,
|
|
IID_IDirectMusicLoader8,
|
|
(void**)&m_pWavLoader );
|
|
|
|
if( FAILED( hr ) )
|
|
SNDError( "DirectMusic WavLoader Creation Error!! ErrorCode : 0x%x", hr );
|
|
|
|
//Ogg 로더 생성
|
|
CDMusic_OggLoader * pOggLoader = new CDMusic_OggLoader;
|
|
m_pOggLoader = pOggLoader;
|
|
|
|
hr = pOggLoader->Init();
|
|
if( FAILED( hr ) )
|
|
SNDError( "DirectMusic OggLoader Creation Error!! ErrorCode : 0x%x", hr );
|
|
|
|
|
|
//퍼포먼스 생성
|
|
hr = CoCreateInstance( CLSID_DirectMusicPerformance,
|
|
NULL,
|
|
CLSCTX_INPROC,
|
|
IID_IDirectMusicPerformance8,
|
|
(void**)&m_pPerformance );
|
|
if( FAILED( hr ) )
|
|
SNDError( "DirectMusic Performance Creation Error!! ErrorCode : 0x%x", hr );
|
|
|
|
hr = m_pPerformance->InitAudio( NULL,
|
|
NULL,
|
|
hWnd,
|
|
DMUS_APATH_DYNAMIC_STEREO,
|
|
dwPChannels,
|
|
DMUS_AUDIOF_ALL,
|
|
NULL );
|
|
if( FAILED( hr ) )
|
|
SNDError( "InitAudio Failed!! ErrorCode : 0x%x", hr );
|
|
|
|
Get3DListener();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CDirectMusic::Get3DListener()
|
|
{
|
|
//3D Listener 얻어옴.
|
|
IDirectMusicAudioPath * p3DAudioPath;
|
|
HRESULT hr = m_pPerformance->CreateStandardAudioPath( DMUS_APATH_DYNAMIC_3D, 64, TRUE, &p3DAudioPath );
|
|
if( FAILED( hr ) )
|
|
SNDError( "DirectMusic CreateStandardAudioPath(3D AudioPath) Failed!! ErrorCode : 0x%x", hr );
|
|
|
|
hr = p3DAudioPath->GetObjectInPath( 0, DMUS_PATH_PRIMARY_BUFFER, 0, GUID_NULL, 0, IID_IDirectSound3DListener,
|
|
(void**)&m_pDSListener );
|
|
if( FAILED( hr ) )
|
|
SNDError( "DirectMusic GetObjectInPath(Primary Buffer) Failed!! ErrorCode : 0x%x", hr );
|
|
|
|
p3DAudioPath->Release();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CDirectMusic::Destroy()
|
|
{
|
|
ClearMusicBuffers();
|
|
|
|
SAFE_RELEASE( m_pWavLoader );
|
|
CDMusic_OggLoader * pOggLoader = (CDMusic_OggLoader*)m_pOggLoader;
|
|
pOggLoader->UnInit();
|
|
SAFE_RELEASE( m_pOggLoader );
|
|
|
|
SAFE_RELEASE( m_pDSListener );
|
|
|
|
if( m_pPerformance )
|
|
{
|
|
m_pPerformance->Stop( NULL, NULL, 0, 0 ); //플레이 되고 있는 음악이 있으면 멈춤.
|
|
m_pPerformance->CloseDown();
|
|
|
|
SAFE_RELEASE( m_pPerformance );
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CDirectMusic::SetSearchDirectory( const char * szPath )
|
|
{
|
|
if( m_pWavLoader == NULL )
|
|
return;
|
|
|
|
//DirectMusic은 WideString만 받음.
|
|
WCHAR wstrPath[256];
|
|
int len = strlen( szPath );
|
|
MultiByteToWideChar( CP_ACP, 0, szPath, -1, wstrPath, len );
|
|
|
|
HRESULT hr = m_pWavLoader->SetSearchDirectory( GUID_DirectMusicAllTypes, wstrPath, FALSE );
|
|
if( FAILED( hr ) )
|
|
SNDError( "DirectMusic WavLoader SetSearchDirectory Failed!! ErrorCode : 0x%x", hr );
|
|
|
|
hr = m_pOggLoader->SetSearchDirectory( GUID_DirectMusicAllTypes, wstrPath, FALSE );
|
|
if( FAILED( hr ) )
|
|
SNDError( "DirectMusic OggLoader SetSearchDirectory Failed!! ErrorCode : 0x%x", hr );
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CDirectMusic::CollectGarbage()
|
|
{
|
|
if( m_pWavLoader )
|
|
m_pWavLoader->CollectGarbage();
|
|
|
|
if( m_pOggLoader )
|
|
m_pOggLoader->CollectGarbage();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CDirectMusic::SetDoppler( D3DVALUE distance, D3DVALUE doppler )
|
|
{
|
|
if( m_pDSListener )
|
|
{
|
|
m_pDSListener->SetDistanceFactor( distance, DS3D_IMMEDIATE );
|
|
m_pDSListener->SetDopplerFactor( doppler, DS3D_IMMEDIATE );
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CDirectMusic::SetRolloff( D3DVALUE rolloff )
|
|
{
|
|
if( m_pDSListener )
|
|
{
|
|
m_pDSListener->SetRolloffFactor( rolloff, DS3D_IMMEDIATE );
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CDirectMusic::Set3DOrientation( D3DVALUE xFront, D3DVALUE yFront, D3DVALUE zFront
|
|
, D3DVALUE xTop, D3DVALUE yTop, D3DVALUE zTop )
|
|
{
|
|
if( m_pDSListener )
|
|
{
|
|
m_pDSListener->SetOrientation( xFront, yFront, zFront, xTop, yTop, zTop, DS3D_IMMEDIATE );
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CDirectMusic::SetVelocity( D3DVALUE x, D3DVALUE y, D3DVALUE z )
|
|
{
|
|
if( m_pDSListener )
|
|
{
|
|
m_pDSListener->SetVelocity( x, y, z, DS3D_IMMEDIATE );
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CDirectMusic::SetPosition( D3DVALUE x, D3DVALUE y, D3DVALUE z )
|
|
{
|
|
if( m_pDSListener )
|
|
{
|
|
m_pDSListener->SetPosition( x, y, z, DS3D_IMMEDIATE );
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
inline CMusicBuffer * NewMusicBuffer()
|
|
{
|
|
return new CMusicBuffer;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
inline void DeleteMusicBuffer( CMusicBuffer * pBuf )
|
|
{
|
|
delete pBuf;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CDirectMusic::ClearMusicBuffers()
|
|
{
|
|
MUSICBUFFERS::iterator it, it_end;
|
|
|
|
it = m_pMusicBuffers->begin();
|
|
it_end = m_pMusicBuffers->end();
|
|
|
|
for( ; it != it_end; it++ )
|
|
{
|
|
::DeleteMusicBuffer( *it );
|
|
}
|
|
|
|
m_pMusicBuffers->clear();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
CMusicBuffer & CDirectMusic::NewMusicBuffer()
|
|
{
|
|
typedef MUSICBUFFERS::iterator iterator;
|
|
|
|
CMusicBuffer * pNewBuf = ::NewMusicBuffer();
|
|
pair <iterator, bool> r = m_pMusicBuffers->insert( pNewBuf );
|
|
if( r.second == false )
|
|
{
|
|
SNDError_Debug( "NewMusicBuffer Failed!!" );
|
|
}
|
|
|
|
return *pNewBuf;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
void CDirectMusic::DeleteMusicBuffer( CMusicBuffer & musicBuffer )
|
|
{
|
|
size_t nErased = m_pMusicBuffers->erase( &musicBuffer );
|
|
if( nErased == 0 )
|
|
{
|
|
SNDError_Debug( "DeleteMusicBuffer Failed!! 지정된 버퍼를 컨테이너에서 찾을 수 없습니다." );
|
|
}
|
|
else
|
|
{
|
|
::DeleteMusicBuffer( &musicBuffer );
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|