diff --git a/core/Base/Game.cpp b/core/Base/Game.cpp index ee61edad..343811eb 100644 --- a/core/Base/Game.cpp +++ b/core/Base/Game.cpp @@ -203,6 +203,8 @@ void e2d::Game::destroy() ColliderManager::__uninit(); // 删除动作 ActionManager::__uninit(); + // 回收音乐播放器资源 + Player::__uninit(); // 删除所有对象 ObjectManager::__clear(); // 清空图片缓存 @@ -213,9 +215,7 @@ void e2d::Game::destroy() Timer::__uninit(); // 关闭输入 Input::__uninit(); - // 恢复计时操作 - Time::__uninit(); - // 删除渲染相关资源 + // 回收渲染相关资源 Renderer::__discardResources(); // 销毁窗口 Window::__uninit(); diff --git a/core/Base/Input.cpp b/core/Base/Input.cpp index c455ae75..a3d25bb6 100644 --- a/core/Base/Input.cpp +++ b/core/Base/Input.cpp @@ -10,8 +10,8 @@ using namespace e2d; static IDirectInput8* s_pDirectInput = nullptr; // DirectInput 接口对象 static IDirectInputDevice8* s_KeyboardDevice = nullptr; // 键盘设备接口 -static char s_KeyBuffer[BUFFER_SIZE] = { 0 }; // 用于保存键盘按键信息缓冲区 -static char s_KeyRecordBuffer[BUFFER_SIZE] = { 0 }; // 键盘消息二级缓冲区 +static char s_KeyBuffer[BUFFER_SIZE] = { 0 }; // 用于保存键盘按键信息缓冲区 +static char s_KeyRecordBuffer[BUFFER_SIZE] = { 0 }; // 键盘消息二级缓冲区 static IDirectInputDevice8* s_MouseDevice = nullptr; // 鼠标设备接口 static DIMOUSESTATE s_MouseState; // 鼠标信息存储结构体 diff --git a/core/Base/Time.cpp b/core/Base/Time.cpp index 2948456e..1652494b 100644 --- a/core/Base/Time.cpp +++ b/core/Base/Time.cpp @@ -48,10 +48,6 @@ bool e2d::Time::__init() return true; } -void e2d::Time::__uninit() -{ -} - bool e2d::Time::__isReady() { return s_tExceptedInvertal < duration_cast(s_tNow - s_tFixedUpdate); diff --git a/core/Tool/Music.cpp b/core/Tool/Music.cpp index f88041bd..7ae1f737 100644 --- a/core/Tool/Music.cpp +++ b/core/Tool/Music.cpp @@ -1,6 +1,4 @@ #include "..\e2dtool.h" -#include "..\e2dmanager.h" -#include #ifndef SAFE_DELETE @@ -22,109 +20,72 @@ inline bool TraceError(wchar_t* sPrompt, HRESULT hr) return false; } + static IXAudio2 * s_pXAudio2 = nullptr; static IXAudio2MasteringVoice * s_pMasteringVoice = nullptr; -static float s_fMusicVolume = 1.0; -// 音乐播放器 -class MusicPlayer -{ -public: - MusicPlayer(); - - virtual ~MusicPlayer(); - - bool open( - const e2d::String& filePath - ); - - bool MusicPlayer::open( - int resNameId, - const e2d::String& resType - ); - - bool play( - int nLoopCount = 0 - ); - - void pause(); - - void resume(); - - void stop(); - - void close(); - - bool setVolume( - float fVolume - ); - - bool isPlaying() const; - -protected: - bool _readMMIO(); - - bool _resetFile(); - - bool _read( - BYTE* pBuffer, - DWORD dwSizeToRead - ); - - bool _findMediaFileCch( - wchar_t* strDestPath, - int cchDest, - const wchar_t * strFilename - ); - -protected: - bool _bOpened; - mutable bool _bPlaying; - DWORD _dwSize; - CHAR* _pResourceBuffer; - BYTE* _pbWaveData; - HMMIO _hmmio; - MMCKINFO _ck; - MMCKINFO _ckRiff; - WAVEFORMATEX* _pwfx; - IXAudio2SourceVoice* _pSourceVoice; -}; - -typedef std::map MusicMap; - -static MusicMap& GetMusicFileList() -{ - static MusicMap s_MusicFileList; - return s_MusicFileList; -} - -static MusicMap& GetMusicResList() -{ - static MusicMap s_MusicResList; - return s_MusicResList; -} - -MusicPlayer::MusicPlayer() - : _bOpened(false) - , _bPlaying(false) - , _pwfx(nullptr) +e2d::Music::Music() + : _opened(false) + , _playing(false) + , _wfx(nullptr) , _hmmio(nullptr) - , _pResourceBuffer(nullptr) - , _pbWaveData(nullptr) + , _resBuffer(nullptr) + , _waveData(nullptr) , _dwSize(0) - , _pSourceVoice(nullptr) + , _voice(nullptr) { } -MusicPlayer::~MusicPlayer() +e2d::Music::Music(const e2d::String & filePath) + : _opened(false) + , _playing(false) + , _wfx(nullptr) + , _hmmio(nullptr) + , _resBuffer(nullptr) + , _waveData(nullptr) + , _dwSize(0) + , _voice(nullptr) +{ + this->open(filePath); +} + +e2d::Music::Music(int resNameId, const String & resType) + : _opened(false) + , _playing(false) + , _wfx(nullptr) + , _hmmio(nullptr) + , _resBuffer(nullptr) + , _waveData(nullptr) + , _dwSize(0) + , _voice(nullptr) +{ + this->open(resNameId, resType); +} + +e2d::Music::~Music() { close(); } -bool MusicPlayer::open(const e2d::String& filePath) +e2d::Music * e2d::Music::create() { - if (_bOpened) + return Create(); +} + +e2d::Music * e2d::Music::create(const e2d::String & filePath) +{ + return Create(filePath); +} + +e2d::Music * e2d::Music::create(int resNameId, const String & resType) +{ + return Create(resNameId, resType); +} + +bool e2d::Music::open(const e2d::String& filePath) +{ + if (_opened) { WARN_IF(true, "MusicInfo can be opened only once!"); return false; @@ -171,37 +132,37 @@ bool MusicPlayer::open(const e2d::String& filePath) _dwSize = _ck.cksize; // 将样本数据读取到内存中 - _pbWaveData = new (std::nothrow) BYTE[_dwSize]; + _waveData = new (std::nothrow) BYTE[_dwSize]; - if (!_read(_pbWaveData, _dwSize)) + if (!_read(_waveData, _dwSize)) { TraceError(L"Failed to read WAV data"); - SAFE_DELETE_ARRAY(_pbWaveData); + SAFE_DELETE_ARRAY(_waveData); return false; } // 创建音源 HRESULT hr; - if (FAILED(hr = s_pXAudio2->CreateSourceVoice(&_pSourceVoice, _pwfx))) + if (FAILED(hr = s_pXAudio2->CreateSourceVoice(&_voice, _wfx))) { TraceError(L"Create source voice error", hr); - SAFE_DELETE_ARRAY(_pbWaveData); + SAFE_DELETE_ARRAY(_waveData); return false; } - _bOpened = true; - _bPlaying = false; + _opened = true; + _playing = false; return true; } -bool MusicPlayer::open(int resNameId, const e2d::String& resType) +bool e2d::Music::open(int resNameId, const e2d::String& resType) { HRSRC hResInfo; HGLOBAL hResData; DWORD dwSize; void* pvRes; - if (_bOpened) + if (_opened) { WARN_IF(true, "MusicInfo can be opened only once!"); return false; @@ -213,7 +174,6 @@ bool MusicPlayer::open(int resNameId, const e2d::String& resType) return false; } - // Loading it as a file failed, so try it as a resource if (nullptr == (hResInfo = FindResourceW(HINST_THISCOMPONENT, MAKEINTRESOURCE(resNameId), resType))) return TraceError(L"FindResource"); @@ -226,20 +186,20 @@ bool MusicPlayer::open(int resNameId, const e2d::String& resType) if (nullptr == (pvRes = LockResource(hResData))) return TraceError(L"LockResource"); - _pResourceBuffer = new (std::nothrow) CHAR[dwSize]; - memcpy(_pResourceBuffer, pvRes, dwSize); + _resBuffer = new (std::nothrow) CHAR[dwSize]; + memcpy(_resBuffer, pvRes, dwSize); MMIOINFO mmioInfo; ZeroMemory(&mmioInfo, sizeof(mmioInfo)); mmioInfo.fccIOProc = FOURCC_MEM; mmioInfo.cchBuffer = dwSize; - mmioInfo.pchBuffer = (CHAR*)_pResourceBuffer; + mmioInfo.pchBuffer = (CHAR*)_resBuffer; _hmmio = mmioOpen(nullptr, &mmioInfo, MMIO_ALLOCBUF | MMIO_READ); if (!_readMMIO()) { - // ReadMMIO will fail if its an not a wave file + // 读取非 wave 文件时 ReadMMIO 调用失败 mmioClose(_hmmio, 0); return TraceError(L"ReadMMIO"); } @@ -247,48 +207,48 @@ bool MusicPlayer::open(int resNameId, const e2d::String& resType) if (!_resetFile()) return TraceError(L"ResetFile"); - // After the reset, the size of the wav file is _ck.cksize so store it now + // 重置文件后,wave 文件的大小是 _ck.cksize _dwSize = _ck.cksize; - // Read the sample data into memory - _pbWaveData = new (std::nothrow) BYTE[_dwSize]; + // 将样本数据读取到内存中 + _waveData = new (std::nothrow) BYTE[_dwSize]; - if (!_read(_pbWaveData, _dwSize)) + if (!_read(_waveData, _dwSize)) { TraceError(L"Failed to read WAV data"); - SAFE_DELETE_ARRAY(_pbWaveData); + SAFE_DELETE_ARRAY(_waveData); return false; } // 创建音源 HRESULT hr; - if (FAILED(hr = s_pXAudio2->CreateSourceVoice(&_pSourceVoice, _pwfx))) + if (FAILED(hr = s_pXAudio2->CreateSourceVoice(&_voice, _wfx))) { TraceError(L"Create source voice error", hr); - SAFE_DELETE_ARRAY(_pbWaveData); + SAFE_DELETE_ARRAY(_waveData); return false; } - _bOpened = true; - _bPlaying = false; + _opened = true; + _playing = false; return true; } -bool MusicPlayer::play(int nLoopCount) +bool e2d::Music::play(int nLoopCount) { - if (!_bOpened) + if (!_opened) { WARN_IF(true, "MusicInfo::play Failed: MusicInfo must be opened first!"); return false; } - if (_pSourceVoice == nullptr) + if (_voice == nullptr) { WARN_IF(true, "MusicInfo::play Failed: IXAudio2SourceVoice Null pointer exception!"); return false; } - if (_bPlaying) + if (_playing) { stop(); } @@ -298,71 +258,72 @@ bool MusicPlayer::play(int nLoopCount) // 提交 wave 样本数据 XAUDIO2_BUFFER buffer = { 0 }; - buffer.pAudioData = _pbWaveData; + buffer.pAudioData = _waveData; buffer.Flags = XAUDIO2_END_OF_STREAM; buffer.AudioBytes = _dwSize; buffer.LoopCount = nLoopCount; HRESULT hr; - if (FAILED(hr = _pSourceVoice->SubmitSourceBuffer(&buffer))) + if (FAILED(hr = _voice->SubmitSourceBuffer(&buffer))) { TraceError(L"Submitting source buffer error", hr); - _pSourceVoice->DestroyVoice(); - SAFE_DELETE_ARRAY(_pbWaveData); + _voice->DestroyVoice(); + SAFE_DELETE_ARRAY(_waveData); return false; } - if (SUCCEEDED(hr = _pSourceVoice->Start(0))) + if (SUCCEEDED(hr = _voice->Start(0))) { - _bPlaying = true; + // 播放成功,保留这个对象 + _playing = true; } - + return SUCCEEDED(hr); } -void MusicPlayer::pause() +void e2d::Music::pause() { - if (_pSourceVoice) + if (_voice) { - if (SUCCEEDED(_pSourceVoice->Stop())) + if (SUCCEEDED(_voice->Stop())) { - _bPlaying = false; + _playing = false; } } } -void MusicPlayer::resume() +void e2d::Music::resume() { - if (_pSourceVoice) + if (_voice) { - if (SUCCEEDED(_pSourceVoice->Start())) + if (SUCCEEDED(_voice->Start())) { - _bPlaying = true; + _playing = true; } } } -void MusicPlayer::stop() +void e2d::Music::stop() { - if (_pSourceVoice) + if (_voice) { - if (SUCCEEDED(_pSourceVoice->Stop())) + if (SUCCEEDED(_voice->Stop())) { - _pSourceVoice->ExitLoop(); - _pSourceVoice->FlushSourceBuffers(); - _bPlaying = false; + _voice->ExitLoop(); + _voice->FlushSourceBuffers(); + _playing = false; } } } -void MusicPlayer::close() +void e2d::Music::close() { - if (_pSourceVoice) + if (_voice) { - _pSourceVoice->Stop(); - _pSourceVoice->FlushSourceBuffers(); - _pSourceVoice->DestroyVoice(); - _pSourceVoice = nullptr; + _voice->Stop(); + _voice->FlushSourceBuffers(); + _voice->DestroyVoice(); + _voice = nullptr; } if (_hmmio != nullptr) @@ -371,26 +332,26 @@ void MusicPlayer::close() _hmmio = nullptr; } - SAFE_DELETE_ARRAY(_pResourceBuffer); - SAFE_DELETE_ARRAY(_pbWaveData); - SAFE_DELETE_ARRAY(_pwfx); + SAFE_DELETE_ARRAY(_resBuffer); + SAFE_DELETE_ARRAY(_waveData); + SAFE_DELETE_ARRAY(_wfx); - _bOpened = false; - _bPlaying = false; + _opened = false; + _playing = false; } -bool MusicPlayer::isPlaying() const +bool e2d::Music::isPlaying() const { - if (_bOpened && _pSourceVoice) + if (_opened && _voice) { XAUDIO2_VOICE_STATE state; - _pSourceVoice->GetState(&state); + _voice->GetState(&state); if (state.BuffersQueued == 0) { - _bPlaying = false; + _playing = false; } - return _bPlaying; + return _playing; } else { @@ -398,23 +359,28 @@ bool MusicPlayer::isPlaying() const } } -bool MusicPlayer::setVolume(float fVolume) +IXAudio2SourceVoice * e2d::Music::getIXAudio2SourceVoice() const { - if (_pSourceVoice) + return _voice; +} + +bool e2d::Music::setVolume(double volume) +{ + if (_voice) { - return SUCCEEDED(_pSourceVoice->SetVolume(fVolume)); + return SUCCEEDED(_voice->SetVolume(float(volume))); } return false; } -bool MusicPlayer::_readMMIO() +bool e2d::Music::_readMMIO() { MMCKINFO ckIn; PCMWAVEFORMAT pcmWaveFormat; memset(&ckIn, 0, sizeof(ckIn)); - _pwfx = nullptr; + _wfx = nullptr; if ((0 != mmioDescend(_hmmio, &_ckRiff, nullptr, 0))) return TraceError(L"mmioDescend"); @@ -442,11 +408,11 @@ bool MusicPlayer::_readMMIO() // 的数据,这个数据就是额外分配的大小 if (pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM) { - _pwfx = (WAVEFORMATEX*) new (std::nothrow) CHAR[sizeof(WAVEFORMATEX)]; + _wfx = (WAVEFORMATEX*) new (std::nothrow) CHAR[sizeof(WAVEFORMATEX)]; // 拷贝数据 - memcpy(_pwfx, &pcmWaveFormat, sizeof(pcmWaveFormat)); - _pwfx->cbSize = 0; + memcpy(_wfx, &pcmWaveFormat, sizeof(pcmWaveFormat)); + _wfx->cbSize = 0; } else { @@ -455,31 +421,31 @@ bool MusicPlayer::_readMMIO() if (mmioRead(_hmmio, (CHAR*)&cbExtraBytes, sizeof(WORD)) != sizeof(WORD)) return TraceError(L"mmioRead"); - _pwfx = (WAVEFORMATEX*) new (std::nothrow) CHAR[sizeof(WAVEFORMATEX) + cbExtraBytes]; + _wfx = (WAVEFORMATEX*) new (std::nothrow) CHAR[sizeof(WAVEFORMATEX) + cbExtraBytes]; // 拷贝数据 - memcpy(_pwfx, &pcmWaveFormat, sizeof(pcmWaveFormat)); - _pwfx->cbSize = cbExtraBytes; + memcpy(_wfx, &pcmWaveFormat, sizeof(pcmWaveFormat)); + _wfx->cbSize = cbExtraBytes; // 读取额外数据 - if (mmioRead(_hmmio, (CHAR*)(((BYTE*)&(_pwfx->cbSize)) + sizeof(WORD)), + if (mmioRead(_hmmio, (CHAR*)(((BYTE*)&(_wfx->cbSize)) + sizeof(WORD)), cbExtraBytes) != cbExtraBytes) { - SAFE_DELETE(_pwfx); + SAFE_DELETE(_wfx); return TraceError(L"mmioRead"); } } if (0 != mmioAscend(_hmmio, &ckIn, 0)) { - SAFE_DELETE(_pwfx); + SAFE_DELETE(_wfx); return TraceError(L"mmioAscend"); } return true; } -bool MusicPlayer::_resetFile() +bool e2d::Music::_resetFile() { // Seek to the data if (-1 == mmioSeek(_hmmio, _ckRiff.dwDataOffset + sizeof(FOURCC), @@ -494,7 +460,7 @@ bool MusicPlayer::_resetFile() return true; } -bool MusicPlayer::_read(BYTE* pBuffer, DWORD dwSizeToRead) +bool e2d::Music::_read(BYTE* pBuffer, DWORD dwSizeToRead) { MMIOINFO mmioinfoIn; // current status of _hmmio @@ -530,7 +496,7 @@ bool MusicPlayer::_read(BYTE* pBuffer, DWORD dwSizeToRead) return true; } -bool MusicPlayer::_findMediaFileCch(wchar_t* strDestPath, int cchDest, const wchar_t * strFilename) +bool e2d::Music::_findMediaFileCch(wchar_t* strDestPath, int cchDest, const wchar_t * strFilename) { bool bFound = false; @@ -604,195 +570,6 @@ bool MusicPlayer::_findMediaFileCch(wchar_t* strDestPath, int cchDest, const wch return false; } - -bool e2d::Music::preload(const String& filePath) -{ - UINT nRet = filePath.getHashCode(); - - if (GetMusicFileList().end() != GetMusicFileList().find(nRet)) - { - return true; - } - else - { - MusicPlayer * pPlayer = new (std::nothrow) MusicPlayer(); - - if (pPlayer->open(filePath)) - { - pPlayer->setVolume(s_fMusicVolume); - GetMusicFileList().insert(std::pair(nRet, pPlayer)); - return true; - } - else - { - delete pPlayer; - pPlayer = nullptr; - } - } - return false; -} - -bool e2d::Music::preload(int resNameId, const String& resType) -{ - if (GetMusicResList().end() != GetMusicResList().find(resNameId)) - { - return true; - } - else - { - MusicPlayer * pPlayer = new (std::nothrow) MusicPlayer(); - - if (pPlayer->open(resNameId, resType)) - { - pPlayer->setVolume(s_fMusicVolume); - GetMusicResList().insert(std::pair(resNameId, pPlayer)); - return true; - } - else - { - delete pPlayer; - pPlayer = nullptr; - } - } - return false; -} - -bool e2d::Music::play(const String& filePath, int nLoopCount) -{ - if (Music::preload(filePath)) - { - UINT nRet = filePath.getHashCode(); - auto pMusic = GetMusicFileList()[nRet]; - if (pMusic->play(nLoopCount)) - { - return true; - } - } - return false; -} - -bool e2d::Music::play(int resNameId, const String& resType, int nLoopCount) -{ - if (Music::preload(resNameId, resType)) - { - auto pMusic = GetMusicResList()[resNameId]; - if (pMusic->play(nLoopCount)) - { - return true; - } - } - return false; -} - -void e2d::Music::pause(const String& filePath) -{ - if (filePath.isEmpty()) - return; - - UINT nRet = filePath.getHashCode(); - - if (GetMusicFileList().end() != GetMusicFileList().find(nRet)) - GetMusicFileList()[nRet]->pause(); -} - -void e2d::Music::pause(int resNameId, const String& resType) -{ - if (GetMusicResList().end() != GetMusicResList().find(resNameId)) - GetMusicResList()[resNameId]->pause(); -} - -void e2d::Music::resume(const String& filePath) -{ - if (filePath.isEmpty()) - return; - - UINT nRet = filePath.getHashCode(); - - if (GetMusicFileList().end() != GetMusicFileList().find(nRet)) - GetMusicFileList()[nRet]->resume(); -} - -void e2d::Music::resume(int resNameId, const String& resType) -{ - if (GetMusicResList().end() != GetMusicResList().find(resNameId)) - GetMusicResList()[resNameId]->pause(); -} - -void e2d::Music::stop(const String& filePath) -{ - if (filePath.isEmpty()) - return; - - UINT nRet = filePath.getHashCode(); - - if (GetMusicFileList().end() != GetMusicFileList().find(nRet)) - GetMusicFileList()[nRet]->stop(); -} - -void e2d::Music::stop(int resNameId, const String& resType) -{ - if (GetMusicResList().end() != GetMusicResList().find(resNameId)) - GetMusicResList()[resNameId]->stop(); -} - -bool e2d::Music::isPlaying(const String& filePath) -{ - if (filePath.isEmpty()) - return false; - - UINT nRet = filePath.getHashCode(); - - if (GetMusicFileList().end() != GetMusicFileList().find(nRet)) - return GetMusicFileList()[nRet]->isPlaying(); - - return false; -} - -bool e2d::Music::isPlaying(int resNameId, const String& resType) -{ - if (GetMusicResList().end() != GetMusicResList().find(resNameId)) - return GetMusicResList()[resNameId]->isPlaying(); - return false; -} - -double e2d::Music::getVolume() -{ - return s_fMusicVolume; -} - -void e2d::Music::setVolume(double fVolume) -{ - s_fMusicVolume = min(max(float(fVolume), -224), 224); - for (auto pair : GetMusicFileList()) - { - pair.second->setVolume(s_fMusicVolume); - } -} - -void e2d::Music::pauseAll() -{ - for (auto pair : GetMusicFileList()) - { - pair.second->pause(); - } -} - -void e2d::Music::resumeAll() -{ - for (auto pair : GetMusicFileList()) - { - pair.second->resume(); - } -} - -void e2d::Music::stopAll() -{ - for (auto pair : GetMusicFileList()) - { - pair.second->stop(); - } -} - IXAudio2 * e2d::Music::getIXAudio2() { return s_pXAudio2; @@ -825,18 +602,10 @@ bool e2d::Music::__init() void e2d::Music::__uninit() { - for (auto pair : GetMusicFileList()) - { - pair.second->close(); - delete pair.second; - } - - GetMusicFileList().clear(); - if (s_pMasteringVoice) { s_pMasteringVoice->DestroyVoice(); } e2d::SafeReleaseInterface(s_pXAudio2); -} +} \ No newline at end of file diff --git a/core/Tool/Player.cpp b/core/Tool/Player.cpp new file mode 100644 index 00000000..7d35567f --- /dev/null +++ b/core/Tool/Player.cpp @@ -0,0 +1,218 @@ +#include "..\e2dtool.h" +#include + +typedef std::map MusicMap; + +static MusicMap& GetMusicFileList() +{ + static MusicMap s_MusicFileList; + return s_MusicFileList; +} + +static MusicMap& GetMusicResList() +{ + static MusicMap s_MusicResList; + return s_MusicResList; +} + +static float s_fMusicVolume = 1.0; + + +bool e2d::Player::preload(const String& filePath) +{ + UINT hash = filePath.getHashCode(); + + if (GetMusicFileList().end() != GetMusicFileList().find(hash)) + { + return true; + } + else + { + Music * music = new (std::nothrow) Music(); + + if (music->open(filePath)) + { + music->setVolume(s_fMusicVolume); + GetMusicFileList().insert(std::pair(hash, music)); + return true; + } + else + { + delete music; + music = nullptr; + } + } + return false; +} + +bool e2d::Player::preload(int resNameId, const String& resType) +{ + if (GetMusicResList().end() != GetMusicResList().find(resNameId)) + { + return true; + } + else + { + Music * music = new (std::nothrow) Music(); + + if (music->open(resNameId, resType)) + { + music->setVolume(s_fMusicVolume); + GetMusicResList().insert(std::pair(resNameId, music)); + return true; + } + else + { + delete music; + music = nullptr; + } + } + return false; +} + +bool e2d::Player::play(const String& filePath, int nLoopCount) +{ + if (Player::preload(filePath)) + { + UINT hash = filePath.getHashCode(); + auto music = GetMusicFileList()[hash]; + if (music->play(nLoopCount)) + { + return true; + } + } + return false; +} + +bool e2d::Player::play(int resNameId, const String& resType, int nLoopCount) +{ + if (Player::preload(resNameId, resType)) + { + auto music = GetMusicResList()[resNameId]; + if (music->play(nLoopCount)) + { + return true; + } + } + return false; +} + +void e2d::Player::pause(const String& filePath) +{ + if (filePath.isEmpty()) + return; + + UINT hash = filePath.getHashCode(); + + if (GetMusicFileList().end() != GetMusicFileList().find(hash)) + GetMusicFileList()[hash]->pause(); +} + +void e2d::Player::pause(int resNameId, const String& resType) +{ + if (GetMusicResList().end() != GetMusicResList().find(resNameId)) + GetMusicResList()[resNameId]->pause(); +} + +void e2d::Player::resume(const String& filePath) +{ + if (filePath.isEmpty()) + return; + + UINT hash = filePath.getHashCode(); + + if (GetMusicFileList().end() != GetMusicFileList().find(hash)) + GetMusicFileList()[hash]->resume(); +} + +void e2d::Player::resume(int resNameId, const String& resType) +{ + if (GetMusicResList().end() != GetMusicResList().find(resNameId)) + GetMusicResList()[resNameId]->pause(); +} + +void e2d::Player::stop(const String& filePath) +{ + if (filePath.isEmpty()) + return; + + UINT hash = filePath.getHashCode(); + + if (GetMusicFileList().end() != GetMusicFileList().find(hash)) + GetMusicFileList()[hash]->stop(); +} + +void e2d::Player::stop(int resNameId, const String& resType) +{ + if (GetMusicResList().end() != GetMusicResList().find(resNameId)) + GetMusicResList()[resNameId]->stop(); +} + +bool e2d::Player::isPlaying(const String& filePath) +{ + if (filePath.isEmpty()) + return false; + + UINT hash = filePath.getHashCode(); + + if (GetMusicFileList().end() != GetMusicFileList().find(hash)) + return GetMusicFileList()[hash]->isPlaying(); + + return false; +} + +bool e2d::Player::isPlaying(int resNameId, const String& resType) +{ + if (GetMusicResList().end() != GetMusicResList().find(resNameId)) + return GetMusicResList()[resNameId]->isPlaying(); + return false; +} + +double e2d::Player::getVolume() +{ + return s_fMusicVolume; +} + +void e2d::Player::setVolume(double volume) +{ + s_fMusicVolume = min(max(float(volume), -224), 224); + for (auto pair : GetMusicFileList()) + { + pair.second->setVolume(s_fMusicVolume); + } +} + +void e2d::Player::pauseAll() +{ + for (auto pair : GetMusicFileList()) + { + pair.second->pause(); + } +} + +void e2d::Player::resumeAll() +{ + for (auto pair : GetMusicFileList()) + { + pair.second->resume(); + } +} + +void e2d::Player::stopAll() +{ + for (auto pair : GetMusicFileList()) + { + pair.second->stop(); + } +} + +void e2d::Player::__uninit() +{ + for (auto pair : GetMusicFileList()) + { + pair.second->close(); + delete pair.second; + } + + GetMusicFileList().clear(); +} \ No newline at end of file diff --git a/core/e2dbase.h b/core/e2dbase.h index 313384e8..b7e6263e 100644 --- a/core/e2dbase.h +++ b/core/e2dbase.h @@ -164,9 +164,6 @@ private: // 初始化计时操作 static bool __init(); - // 重置计时操作 - static void __uninit(); - // 是否达到更新时间 static bool __isReady(); diff --git a/core/e2dmanager.h b/core/e2dmanager.h index 679e8c7b..33108f3d 100644 --- a/core/e2dmanager.h +++ b/core/e2dmanager.h @@ -11,7 +11,7 @@ class Renderer; class Node; class Timer; class Action; -class Music; +class Player; class Collider; class Transition; diff --git a/core/e2dtool.h b/core/e2dtool.h index 99ea6746..9bef9b63 100644 --- a/core/e2dtool.h +++ b/core/e2dtool.h @@ -50,8 +50,122 @@ private: }; +// 音乐 +class Music : + public Object +{ + friend Game; + +public: + Music(); + + Music( + const e2d::String& filePath /* 音乐文件路径 */ + ); + + Music( + int resNameId, /* 音乐资源名称 */ + const String& resType /* 音乐资源类型 */ + ); + + virtual ~Music(); + + // 创建音乐对象 + static Music * create(); + + // 创建音乐对象 + static Music * create( + const e2d::String& filePath /* 音乐文件路径 */ + ); + + // 创建音乐对象 + static Music * create( + int resNameId, /* 音乐资源名称 */ + const String& resType /* 音乐资源类型 */ + ); + + // 打开音乐文件 + bool open( + const e2d::String& filePath /* 音乐文件路径 */ + ); + + // 打开音乐资源 + bool open( + int resNameId, /* 音乐资源名称 */ + const String& resType /* 音乐资源类型 */ + ); + + // 播放 + bool play( + int nLoopCount = 0 + ); + + // 暂停 + void pause(); + + // 继续 + void resume(); + + // 停止 + void stop(); + + // 关闭并回收资源 + void close(); + + // 设置音量 + bool setVolume( + double volume + ); + + // 是否正在播放 + bool isPlaying() const; + + // 获取 IXAudio2SourceVoice 对象 + IXAudio2SourceVoice * getIXAudio2SourceVoice() const; + + // 获取 IXAudio2 对象 + static IXAudio2 * getIXAudio2(); + + // 获取 IXAudio2MasteringVoice 对象 + static IXAudio2MasteringVoice * getIXAudio2MasteringVoice(); + +protected: + bool _readMMIO(); + + bool _resetFile(); + + bool _read( + BYTE* pBuffer, + DWORD dwSizeToRead + ); + + bool _findMediaFileCch( + wchar_t* strDestPath, + int cchDest, + const wchar_t * strFilename + ); + +private: + static bool __init(); + + static void __uninit(); + +protected: + bool _opened; + mutable bool _playing; + DWORD _dwSize; + CHAR* _resBuffer; + BYTE* _waveData; + HMMIO _hmmio; + MMCKINFO _ck; + MMCKINFO _ckRiff; + WAVEFORMATEX* _wfx; + IXAudio2SourceVoice* _voice; +}; + + // 音乐播放器 -class Music +class Player { friend Game; @@ -61,18 +175,38 @@ public: const String& filePath /* 音乐文件路径 */ ); - // 预加载音乐资源 - static bool preload( - int resNameId, /* 音乐资源名称 */ - const String& resType /* 音乐资源类型 */ - ); - // 播放音乐 static bool play( const String& filePath, /* 音乐文件路径 */ int nLoopCount = 0 /* 重复播放次数,设置 -1 为循环播放 */ ); + // 暂停音乐 + static void pause( + const String& filePath /* 音乐文件路径 */ + ); + + // 继续播放音乐 + static void resume( + const String& filePath /* 音乐文件路径 */ + ); + + // 停止音乐 + static void stop( + const String& filePath /* 音乐文件路径 */ + ); + + // 获取音乐播放状态 + static bool isPlaying( + const String& filePath /* 音乐文件路径 */ + ); + + // 预加载音乐资源 + static bool preload( + int resNameId, /* 音乐资源名称 */ + const String& resType /* 音乐资源类型 */ + ); + // 播放音乐 static bool play( int resNameId, /* 音乐资源名称 */ @@ -80,44 +214,24 @@ public: int nLoopCount = 0 /* 重复播放次数,设置 -1 为循环播放 */ ); - // 暂停音乐 - static void pause( - const String& filePath /* 音乐文件路径 */ - ); - // 暂停音乐 static void pause( int resNameId, /* 音乐资源名称 */ const String& resType /* 音乐资源类型 */ ); - // 继续播放音乐 - static void resume( - const String& filePath /* 音乐文件路径 */ - ); - // 继续播放音乐 static void resume( int resNameId, /* 音乐资源名称 */ const String& resType /* 音乐资源类型 */ ); - // 停止音乐 - static void stop( - const String& filePath /* 音乐文件路径 */ - ); - // 停止音乐 static void stop( int resNameId, /* 音乐资源名称 */ const String& resType /* 音乐资源类型 */ ); - // 获取音乐播放状态 - static bool isPlaying( - const String& filePath /* 音乐文件路径 */ - ); - // 获取音乐播放状态 static bool isPlaying( int resNameId, /* 音乐资源名称 */ @@ -129,7 +243,7 @@ public: // 设置音量 static void setVolume( - double fVolume /* 音量范围为 -224 ~ 224,0 是静音,1 是正常音量 */ + double volume /* 音量范围为 -224 ~ 224,0 是静音,1 是正常音量 */ ); // 暂停所有音乐 @@ -141,15 +255,7 @@ public: // 停止所有音乐 static void stopAll(); - // 获取 IXAudio2 对象 - static IXAudio2 * getIXAudio2(); - - // 获取 IXAudio2MasteringVoice 对象 - static IXAudio2MasteringVoice * getIXAudio2MasteringVoice(); - private: - static bool __init(); - static void __uninit(); }; diff --git a/project/vs2017/Easy2D.vcxproj b/project/vs2017/Easy2D.vcxproj index 1b6e9e5c..f9fdaf49 100644 --- a/project/vs2017/Easy2D.vcxproj +++ b/project/vs2017/Easy2D.vcxproj @@ -250,8 +250,9 @@ - + + diff --git a/project/vs2017/Easy2D.vcxproj.filters b/project/vs2017/Easy2D.vcxproj.filters index 852a8df6..2c355783 100644 --- a/project/vs2017/Easy2D.vcxproj.filters +++ b/project/vs2017/Easy2D.vcxproj.filters @@ -96,9 +96,6 @@ Base - - Tool - Common @@ -219,6 +216,12 @@ Action + + Tool + + + Tool +