From 00a2b9ebacbd67663263ce84a92cac4a477321bf Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Sun, 19 Aug 2018 20:40:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=98=8E=E7=A1=AEResource=E7=9A=84=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=EF=BC=8C=E4=B8=8D=E5=85=81=E8=AE=B8=E4=BB=8E=E6=9C=AC?= =?UTF-8?q?=E5=9C=B0=E6=96=87=E4=BB=B6=E5=88=9B=E5=BB=BAResource?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/Common/Image.cpp | 244 ++++++++++++++++++++++-------------- core/Common/Resource.cpp | 58 +-------- core/Node/Sprite.cpp | 13 +- core/Tool/Music.cpp | 260 ++++++++++++++++++++++++--------------- core/Tool/Player.cpp | 124 ++++++++++++------- core/e2dcommon.h | 36 ++---- core/e2dtool.h | 79 +++++++++--- 7 files changed, 471 insertions(+), 343 deletions(-) diff --git a/core/Common/Image.cpp b/core/Common/Image.cpp index a4ca3260..df9d2cae 100644 --- a/core/Common/Image.cpp +++ b/core/Common/Image.cpp @@ -2,7 +2,7 @@ #include "..\e2dbase.h" #include "..\e2dtool.h" -std::map e2d::Image::_bitmapCache; +std::map e2d::Image::_bitmapCache; e2d::Image::Image() : _bitmap(nullptr) @@ -29,14 +29,14 @@ e2d::Image::Image(const String & fileName) : _bitmap(nullptr) , _cropRect() { - this->open(Resource(fileName)); + this->open(fileName); } e2d::Image::Image(const String & fileName, const Rect & cropRect) : _bitmap(nullptr) , _cropRect() { - this->open(Resource(fileName)); + this->open(fileName); this->crop(cropRect); } @@ -46,27 +46,31 @@ e2d::Image::~Image() bool e2d::Image::open(const Resource& res) { - if (res.isFile()) - { - WARN_IF(res.getFileName().isEmpty(), "Image open failed! Invalid file name."); - - if (res.getFileName().isEmpty()) - return false; - } - if (!Image::preload(res)) { WARN("Load Image from file failed!"); return false; } - this->_setBitmap(_bitmapCache.at(res)); + this->_setBitmap(_bitmapCache.at(res.resNameId)); return true; } bool e2d::Image::open(const String & fileName) { - return open(Resource(fileName)); + WARN_IF(fileName.isEmpty(), "Image open failed! Invalid file name."); + + if (fileName.isEmpty()) + return false; + + if (!Image::preload(fileName)) + { + WARN("Load Image from file failed!"); + return false; + } + + this->_setBitmap(_bitmapCache.at(fileName.hash())); + return true; } void e2d::Image::crop(const Rect& cropRect) @@ -148,98 +152,77 @@ e2d::Point e2d::Image::getCropPos() const bool e2d::Image::preload(const Resource& res) { - if (_bitmapCache.find(res) != _bitmapCache.end()) + if (_bitmapCache.find(res.resNameId) != _bitmapCache.end()) { return true; } - HRESULT hr = S_OK; - + Renderer* renderer = Game::getInstance()->getRenderer(); + ID2D1HwndRenderTarget* pRenderTarget = renderer->getRenderTarget(); + IWICImagingFactory *pImagingFactory = renderer->getImagingFactory(); IWICBitmapDecoder *pDecoder = nullptr; IWICBitmapFrameDecode *pSource = nullptr; IWICStream *pStream = nullptr; IWICFormatConverter *pConverter = nullptr; ID2D1Bitmap *pBitmap = nullptr; - IWICImagingFactory *pImagingFactory = Game::getInstance()->getRenderer()->getImagingFactory(); + HRSRC imageResHandle = nullptr; + HGLOBAL imageResDataHandle = nullptr; + void *pImageFile = nullptr; + DWORD imageFileSize = 0; - if (!res.isFile()) + // 定位资源 + imageResHandle = ::FindResourceW( + HINST_THISCOMPONENT, + MAKEINTRESOURCE(res.resNameId), + (LPCWSTR)res.resType + ); + + HRESULT hr = imageResHandle ? S_OK : E_FAIL; + if (SUCCEEDED(hr)) { - HRSRC imageResHandle = nullptr; - HGLOBAL imageResDataHandle = nullptr; - void *pImageFile = nullptr; - DWORD imageFileSize = 0; + // 加载资源 + imageResDataHandle = ::LoadResource(HINST_THISCOMPONENT, imageResHandle); - // 定位资源 - imageResHandle = ::FindResourceW( - HINST_THISCOMPONENT, - MAKEINTRESOURCE(res.getResNameId()), - (LPCWSTR)res.getResType() - ); - - hr = imageResHandle ? S_OK : E_FAIL; - if (SUCCEEDED(hr)) - { - // 加载资源 - imageResDataHandle = ::LoadResource(HINST_THISCOMPONENT, imageResHandle); - - hr = imageResDataHandle ? S_OK : E_FAIL; - } - - if (SUCCEEDED(hr)) - { - // 获取文件指针,并锁定资源 - pImageFile = ::LockResource(imageResDataHandle); - - hr = pImageFile ? S_OK : E_FAIL; - } - - if (SUCCEEDED(hr)) - { - // 计算大小 - imageFileSize = ::SizeofResource(HINST_THISCOMPONENT, imageResHandle); - - hr = imageFileSize ? S_OK : E_FAIL; - } - - if (SUCCEEDED(hr)) - { - // 创建 WIC 流 - hr = pImagingFactory->CreateStream(&pStream); - } - - if (SUCCEEDED(hr)) - { - // 初始化流 - hr = pStream->InitializeFromMemory( - reinterpret_cast(pImageFile), - imageFileSize - ); - } - - if (SUCCEEDED(hr)) - { - // 创建流的解码器 - hr = pImagingFactory->CreateDecoderFromStream( - pStream, - nullptr, - WICDecodeMetadataCacheOnLoad, - &pDecoder - ); - } + hr = imageResDataHandle ? S_OK : E_FAIL; } - else - { - String actualFilePath = File(res.getFileName()).getFilePath(); - if (actualFilePath.isEmpty()) - { - return false; - } - // 创建解码器 - hr = pImagingFactory->CreateDecoderFromFilename( - (LPCWSTR)actualFilePath, + if (SUCCEEDED(hr)) + { + // 获取文件指针,并锁定资源 + pImageFile = ::LockResource(imageResDataHandle); + + hr = pImageFile ? S_OK : E_FAIL; + } + + if (SUCCEEDED(hr)) + { + // 计算大小 + imageFileSize = ::SizeofResource(HINST_THISCOMPONENT, imageResHandle); + + hr = imageFileSize ? S_OK : E_FAIL; + } + + if (SUCCEEDED(hr)) + { + // 创建 WIC 流 + hr = pImagingFactory->CreateStream(&pStream); + } + + if (SUCCEEDED(hr)) + { + // 初始化流 + hr = pStream->InitializeFromMemory( + reinterpret_cast(pImageFile), + imageFileSize + ); + } + + if (SUCCEEDED(hr)) + { + // 创建流的解码器 + hr = pImagingFactory->CreateDecoderFromStream( + pStream, nullptr, - GENERIC_READ, WICDecodeMetadataCacheOnLoad, &pDecoder ); @@ -273,7 +256,7 @@ bool e2d::Image::preload(const Resource& res) if (SUCCEEDED(hr)) { // 从 WIC 位图创建一个 Direct2D 位图 - hr = Game::getInstance()->getRenderer()->getRenderTarget()->CreateBitmapFromWicBitmap( + hr = pRenderTarget->CreateBitmapFromWicBitmap( pConverter, nullptr, &pBitmap @@ -282,7 +265,84 @@ bool e2d::Image::preload(const Resource& res) if (SUCCEEDED(hr)) { - _bitmapCache.insert(std::make_pair(res, pBitmap)); + _bitmapCache.insert(std::make_pair(res.resNameId, pBitmap)); + } + + // 释放相关资源 + SafeRelease(pDecoder); + SafeRelease(pSource); + SafeRelease(pStream); + SafeRelease(pConverter); + + return SUCCEEDED(hr); +} + +bool e2d::Image::preload(const String & fileName) +{ + String actualFilePath = File(fileName).getFilePath(); + if (actualFilePath.isEmpty()) + return false; + + size_t hash = actualFilePath.hash(); + if (_bitmapCache.find(hash) != _bitmapCache.end()) + return true; + + Renderer* renderer = Game::getInstance()->getRenderer(); + ID2D1HwndRenderTarget* pRenderTarget = renderer->getRenderTarget(); + IWICImagingFactory *pImagingFactory = renderer->getImagingFactory(); + IWICBitmapDecoder *pDecoder = nullptr; + IWICBitmapFrameDecode *pSource = nullptr; + IWICStream *pStream = nullptr; + IWICFormatConverter *pConverter = nullptr; + ID2D1Bitmap *pBitmap = nullptr; + + // 创建解码器 + HRESULT hr = pImagingFactory->CreateDecoderFromFilename( + (LPCWSTR)actualFilePath, + nullptr, + GENERIC_READ, + WICDecodeMetadataCacheOnLoad, + &pDecoder + ); + + if (SUCCEEDED(hr)) + { + // 创建初始化框架 + hr = pDecoder->GetFrame(0, &pSource); + } + + if (SUCCEEDED(hr)) + { + // 创建图片格式转换器 + hr = pImagingFactory->CreateFormatConverter(&pConverter); + } + + if (SUCCEEDED(hr)) + { + // 图片格式转换成 32bppPBGRA + hr = pConverter->Initialize( + pSource, + GUID_WICPixelFormat32bppPBGRA, + WICBitmapDitherTypeNone, + nullptr, + 0.f, + WICBitmapPaletteTypeMedianCut + ); + } + + if (SUCCEEDED(hr)) + { + // 从 WIC 位图创建一个 Direct2D 位图 + hr = pRenderTarget->CreateBitmapFromWicBitmap( + pConverter, + nullptr, + &pBitmap + ); + } + + if (SUCCEEDED(hr)) + { + _bitmapCache.insert(std::make_pair(hash, pBitmap)); } // 释放相关资源 diff --git a/core/Common/Resource.cpp b/core/Common/Resource.cpp index ec34b1cc..3a4018db 100644 --- a/core/Common/Resource.cpp +++ b/core/Common/Resource.cpp @@ -1,62 +1,8 @@ #include "..\e2dtool.h" -e2d::Resource::Resource(const String & fileName) - : _isFile(true) - , _fileName(fileName) - , _resNameId(0) - , _resType() -{ -} e2d::Resource::Resource(size_t resNameId, const String & resType) - : _isFile(false) - , _fileName() - , _resNameId(resNameId) - , _resType(resType) + : resNameId(resNameId) + , resType(resType) { } - -bool e2d::Resource::isFile() const -{ - return _isFile; -} - -const e2d::String & e2d::Resource::getFileName() const -{ - return _fileName; -} - -size_t e2d::Resource::getResNameId() const -{ - return _resNameId; -} - -const e2d::String & e2d::Resource::getResType() const -{ - return _resType; -} - -size_t e2d::Resource::getKey() const -{ - return _isFile ? _fileName.hash() : _resNameId; -} - -bool e2d::Resource::operator>(const Resource &res) const -{ - return this->getKey() > res.getKey(); -} - -bool e2d::Resource::operator>=(const Resource &res) const -{ - return this->getKey() >= res.getKey(); -} - -bool e2d::Resource::operator<(const Resource &res) const -{ - return this->getKey() < res.getKey(); -} - -bool e2d::Resource::operator<=(const Resource &res) const -{ - return this->getKey() <= res.getKey(); -} diff --git a/core/Node/Sprite.cpp b/core/Node/Sprite.cpp index 442d66f7..f4c2cc09 100644 --- a/core/Node/Sprite.cpp +++ b/core/Node/Sprite.cpp @@ -75,7 +75,18 @@ bool e2d::Sprite::open(const Resource& res) bool e2d::Sprite::open(const String & fileName) { - return open(Resource(fileName)); + if (!_image) + { + _image = new (e2d::autorelease) Image(); + _image->retain(); + } + + if (_image->open(fileName)) + { + Node::setSize(_image->getWidth(), _image->getHeight()); + return true; + } + return false; } void e2d::Sprite::crop(const Rect& cropRect) diff --git a/core/Tool/Music.cpp b/core/Tool/Music.cpp index 2f6e73af..b29ff1cd 100644 --- a/core/Tool/Music.cpp +++ b/core/Tool/Music.cpp @@ -22,6 +22,44 @@ inline bool TraceError(wchar_t* sPrompt, HRESULT hr) } +e2d::Music::XAudio2Tool::XAudio2Tool() +{ + CoInitialize(nullptr); + + ThrowIfFailed( + XAudio2Create(&_xAudio2, 0) + ); + + ThrowIfFailed( + _xAudio2->CreateMasteringVoice(&_masteringVoice) + ); +} + +e2d::Music::XAudio2Tool::~XAudio2Tool() +{ + _masteringVoice->DestroyVoice(); + _xAudio2->Release(); + + CoUninitialize(); +} + +e2d::Music::XAudio2Tool* e2d::Music::XAudio2Tool::getInstance() +{ + static XAudio2Tool instance; + return &instance; +} + +IXAudio2 * e2d::Music::XAudio2Tool::getXAudio2() +{ + return _xAudio2; +} + +IXAudio2MasteringVoice * e2d::Music::XAudio2Tool::getMasteringVoice() +{ + return _masteringVoice; +} + + e2d::Music::Music() : _opened(false) , _playing(false) @@ -32,10 +70,26 @@ e2d::Music::Music() , _dwSize(0) , _voice(nullptr) , _voiceCallback(this) - , _xAudio2(nullptr) - , _masteringVoice(nullptr) { - CoInitialize(nullptr); + auto xAudio2 = XAudio2Tool::getInstance()->getXAudio2(); + xAudio2->AddRef(); +} + +e2d::Music::Music(const e2d::String & filePath) + : _opened(false) + , _playing(false) + , _wfx(nullptr) + , _hmmio(nullptr) + , _resBuffer(nullptr) + , _waveData(nullptr) + , _dwSize(0) + , _voice(nullptr) + , _voiceCallback(this) +{ + auto xAudio2 = XAudio2Tool::getInstance()->getXAudio2(); + xAudio2->AddRef(); + + this->open(filePath); } e2d::Music::Music(const Resource& res) @@ -48,129 +102,51 @@ e2d::Music::Music(const Resource& res) , _dwSize(0) , _voice(nullptr) , _voiceCallback(this) - , _xAudio2(nullptr) - , _masteringVoice(nullptr) { - CoInitialize(nullptr); + auto xAudio2 = XAudio2Tool::getInstance()->getXAudio2(); + xAudio2->AddRef(); this->open(res); } -e2d::Music::Music(IXAudio2 * xAudio2) - : _opened(false) - , _playing(false) - , _wfx(nullptr) - , _hmmio(nullptr) - , _resBuffer(nullptr) - , _waveData(nullptr) - , _dwSize(0) - , _voice(nullptr) - , _voiceCallback(this) - , _xAudio2(xAudio2) - , _masteringVoice(nullptr) -{ - CoInitialize(nullptr); - - if (_xAudio2) - { - _xAudio2->AddRef(); - } -} - e2d::Music::~Music() { close(); - if (_masteringVoice) - { - _masteringVoice->DestroyVoice(); - _masteringVoice = nullptr; - } - - SafeRelease(_xAudio2); - - CoUninitialize(); + auto xAudio2 = XAudio2Tool::getInstance()->getXAudio2(); + xAudio2->Release(); } -bool e2d::Music::open(const Resource& res) +bool e2d::Music::open(const e2d::String & filePath) { if (_opened) { close(); } - if (!_xAudio2) + if (filePath.isEmpty()) { - if (FAILED(XAudio2Create(&_xAudio2, 0))) - { - TraceError(L"Create IXAudio2 error"); - return false; - } - - if (FAILED(_xAudio2->CreateMasteringVoice(&_masteringVoice))) - { - TraceError(L"Create IXAudio2MasteringVoice error"); - return false; - } + WARN("MusicInfo::open Invalid file name."); + return false; } - if (!res.isFile()) + String actualFilePath = File(filePath).getFilePath(); + if (actualFilePath.isEmpty()) { - HRSRC hResInfo; - HGLOBAL hResData; - DWORD dwSize; - void* pvRes; - - if (nullptr == (hResInfo = FindResourceW(HINST_THISCOMPONENT, MAKEINTRESOURCE(res.getResNameId()), (LPCWSTR)res.getResType()))) - return TraceError(L"FindResource"); - - if (nullptr == (hResData = LoadResource(HINST_THISCOMPONENT, hResInfo))) - return TraceError(L"LoadResource"); - - if (0 == (dwSize = SizeofResource(HINST_THISCOMPONENT, hResInfo))) - return TraceError(L"SizeofResource"); - - if (nullptr == (pvRes = LockResource(hResData))) - return TraceError(L"LockResource"); - - _resBuffer = new CHAR[dwSize]; - memcpy(_resBuffer, pvRes, dwSize); - - MMIOINFO mmioInfo; - ZeroMemory(&mmioInfo, sizeof(mmioInfo)); - mmioInfo.fccIOProc = FOURCC_MEM; - mmioInfo.cchBuffer = dwSize; - mmioInfo.pchBuffer = (CHAR*)_resBuffer; - - _hmmio = mmioOpen(nullptr, &mmioInfo, MMIO_ALLOCBUF | MMIO_READ); + WARN("MusicInfo::open File not found."); + return false; } - else + + // 定位 wave 文件 + wchar_t pFilePath[MAX_PATH]; + if (!_findMediaFileCch(pFilePath, MAX_PATH, (const wchar_t *)actualFilePath)) { - String filePath = res.getFileName(); - if (filePath.isEmpty()) - { - WARN("MusicInfo::open Invalid file name."); - return false; - } - - String actualFilePath = File(filePath).getFilePath(); - if (actualFilePath.isEmpty()) - { - WARN("MusicInfo::open File not found."); - return false; - } - - // 定位 wave 文件 - wchar_t pFilePath[MAX_PATH]; - if (!_findMediaFileCch(pFilePath, MAX_PATH, (const wchar_t *)actualFilePath)) - { - WARN("Failed to find media file: %s", pFilePath); - return false; - } - - _hmmio = mmioOpen(pFilePath, nullptr, MMIO_ALLOCBUF | MMIO_READ); + WARN("Failed to find media file: %s", pFilePath); + return false; } + _hmmio = mmioOpen(pFilePath, nullptr, MMIO_ALLOCBUF | MMIO_READ); + if (nullptr == _hmmio) { return TraceError(L"mmioOpen"); @@ -200,7 +176,87 @@ bool e2d::Music::open(const Resource& res) } // 创建音源 - HRESULT hr = _xAudio2->CreateSourceVoice(&_voice, _wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO, &_voiceCallback); + auto xAudio2 = XAudio2Tool::getInstance()->getXAudio2(); + HRESULT hr = xAudio2->CreateSourceVoice(&_voice, _wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO, &_voiceCallback); + + if (FAILED(hr)) + { + TraceError(L"Create source voice error", hr); + SAFE_DELETE_ARRAY(_waveData); + return false; + } + + _opened = true; + _playing = false; + return true; +} + +bool e2d::Music::open(const Resource& res) +{ + if (_opened) + { + close(); + } + + HRSRC hResInfo; + HGLOBAL hResData; + DWORD dwSize; + void* pvRes; + + if (nullptr == (hResInfo = FindResourceW(HINST_THISCOMPONENT, MAKEINTRESOURCE(res.resNameId), (LPCWSTR)res.resType))) + return TraceError(L"FindResource"); + + if (nullptr == (hResData = LoadResource(HINST_THISCOMPONENT, hResInfo))) + return TraceError(L"LoadResource"); + + if (0 == (dwSize = SizeofResource(HINST_THISCOMPONENT, hResInfo))) + return TraceError(L"SizeofResource"); + + if (nullptr == (pvRes = LockResource(hResData))) + return TraceError(L"LockResource"); + + _resBuffer = new CHAR[dwSize]; + memcpy(_resBuffer, pvRes, dwSize); + + MMIOINFO mmioInfo; + ZeroMemory(&mmioInfo, sizeof(mmioInfo)); + mmioInfo.fccIOProc = FOURCC_MEM; + mmioInfo.cchBuffer = dwSize; + mmioInfo.pchBuffer = (CHAR*)_resBuffer; + + _hmmio = mmioOpen(nullptr, &mmioInfo, MMIO_ALLOCBUF | MMIO_READ); + + if (nullptr == _hmmio) + { + return TraceError(L"mmioOpen"); + } + + if (!_readMMIO()) + { + // 读取非 wave 文件时 ReadMMIO 调用失败 + mmioClose(_hmmio, 0); + return TraceError(L"ReadMMIO"); + } + + if (!_resetFile()) + return TraceError(L"ResetFile"); + + // 重置文件后,wave 文件的大小是 _ck.cksize + _dwSize = _ck.cksize; + + // 将样本数据读取到内存中 + _waveData = new BYTE[_dwSize]; + + if (!_read(_waveData, _dwSize)) + { + TraceError(L"Failed to read WAV data"); + SAFE_DELETE_ARRAY(_waveData); + return false; + } + + // 创建音源 + auto xAudio2 = XAudio2Tool::getInstance()->getXAudio2(); + HRESULT hr = xAudio2->CreateSourceVoice(&_voice, _wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO, &_voiceCallback); if (FAILED(hr)) { diff --git a/core/Tool/Player.cpp b/core/Tool/Player.cpp index 294d0e94..bcd89b40 100644 --- a/core/Tool/Player.cpp +++ b/core/Tool/Player.cpp @@ -3,21 +3,7 @@ e2d::Player::Player() : _volume(1.f) - , _enabled(true) - , _xAudio2(nullptr) - , _masteringVoice(nullptr) { - CoInitialize(nullptr); - - if (FAILED(XAudio2Create(&_xAudio2, 0))) - { - WARN("初始化 XAudio2 组件失败"); - } - - if (FAILED(_xAudio2->CreateMasteringVoice(&_masteringVoice))) - { - WARN("初始化 MasteringVoice 组件失败"); - } } e2d::Player::~Player() @@ -30,30 +16,85 @@ e2d::Player::~Player() } } - if (_masteringVoice) - { - _masteringVoice->DestroyVoice(); - _masteringVoice = nullptr; - } - - SafeRelease(_xAudio2); - CoUninitialize(); } -IXAudio2 * e2d::Player::getXAudio2() +bool e2d::Player::preload(const String & filePath) { - return _xAudio2; + if (filePath.isEmpty()) + return false; + + Music * music = new (std::nothrow) Music(); + + if (music && music->open(filePath)) + { + music->setVolume(_volume); + _musicList.insert(std::make_pair(filePath.hash(), music)); + return true; + } + return false; } -IXAudio2MasteringVoice * e2d::Player::getMasteringVoice() +bool e2d::Player::play(const String & filePath, int nLoopCount) { - return _masteringVoice; + if (filePath.isEmpty()) + return false; + + if (Player::preload(filePath)) + { + auto music = _musicList[filePath.hash()]; + if (music->play(nLoopCount)) + { + return true; + } + } + return false; +} + +void e2d::Player::pause(const String & filePath) +{ + if (filePath.isEmpty()) + return; + + size_t hash = filePath.hash(); + if (_musicList.end() != _musicList.find(hash)) + _musicList[hash]->pause(); +} + +void e2d::Player::resume(const String & filePath) +{ + if (filePath.isEmpty()) + return; + + size_t hash = filePath.hash(); + if (_musicList.end() != _musicList.find(hash)) + _musicList[hash]->resume(); +} + +void e2d::Player::stop(const String & filePath) +{ + if (filePath.isEmpty()) + return; + + size_t hash = filePath.hash(); + if (_musicList.end() != _musicList.find(hash)) + _musicList[hash]->stop(); +} + +bool e2d::Player::isPlaying(const String & filePath) +{ + if (filePath.isEmpty()) + return false; + + size_t hash = filePath.hash(); + if (_musicList.end() != _musicList.find(hash)) + return _musicList[hash]->isPlaying(); + return false; } bool e2d::Player::preload(const Resource& res) { - if (_musicList.end() != _musicList.find(res)) + if (_musicList.end() != _musicList.find(res.resNameId)) return true; Music * music = new (std::nothrow) Music(); @@ -61,7 +102,7 @@ bool e2d::Player::preload(const Resource& res) if (music && music->open(res)) { music->setVolume(_volume); - _musicList.insert(std::make_pair(res, music)); + _musicList.insert(std::make_pair(res.resNameId, music)); return true; } return false; @@ -71,7 +112,7 @@ bool e2d::Player::play(const Resource& res, int nLoopCount) { if (Player::preload(res)) { - auto music = _musicList[res]; + auto music = _musicList[res.resNameId]; if (music->play(nLoopCount)) { return true; @@ -82,26 +123,26 @@ bool e2d::Player::play(const Resource& res, int nLoopCount) void e2d::Player::pause(const Resource& res) { - if (_musicList.end() != _musicList.find(res)) - _musicList[res]->pause(); + if (_musicList.end() != _musicList.find(res.resNameId)) + _musicList[res.resNameId]->pause(); } void e2d::Player::resume(const Resource& res) { - if (_musicList.end() != _musicList.find(res)) - _musicList[res]->pause(); + if (_musicList.end() != _musicList.find(res.resNameId)) + _musicList[res.resNameId]->resume(); } void e2d::Player::stop(const Resource& res) { - if (_musicList.end() != _musicList.find(res)) - _musicList[res]->stop(); + if (_musicList.end() != _musicList.find(res.resNameId)) + _musicList[res.resNameId]->stop(); } bool e2d::Player::isPlaying(const Resource& res) { - if (_musicList.end() != _musicList.find(res)) - return _musicList[res]->isPlaying(); + if (_musicList.end() != _musicList.find(res.resNameId)) + return _musicList[res.resNameId]->isPlaying(); return false; } @@ -143,15 +184,6 @@ void e2d::Player::stopAll() } } -void e2d::Player::setEnabled(bool enabled) -{ - if (_enabled == enabled) - return; - - _enabled = enabled; - _enabled ? _xAudio2->StartEngine() : _xAudio2->StopEngine(); -} - void e2d::Player::clearCache() { for (const auto& pair : _musicList) diff --git a/core/e2dcommon.h b/core/e2dcommon.h index ddfde679..1e5cd5a8 100644 --- a/core/e2dcommon.h +++ b/core/e2dcommon.h @@ -679,37 +679,14 @@ protected: class Resource { public: - Resource( - const String& fileName /* 文件路径 */ - ); - Resource( size_t resNameId, /* 资源名称 */ const String& resType /* 资源类型 */ ); - // 是否是本地文件 - bool isFile() const; - - const String& getFileName() const; - - size_t getResNameId() const; - - const String& getResType() const; - - size_t getKey() const; - - // 比较运算符 - bool operator> (const Resource &) const; - bool operator>= (const Resource &) const; - bool operator< (const Resource &) const; - bool operator<= (const Resource &) const; - -protected: - bool _isFile; - size_t _resNameId; - String _resType; - String _fileName; +public: + size_t resNameId; + String resType; }; @@ -810,6 +787,11 @@ public: // 获取 ID2D1Bitmap 对象 ID2D1Bitmap * getBitmap(); + // 预加载图片资源 + static bool preload( + const String& fileName + ); + // 预加载图片资源 static bool preload( const Resource& res @@ -830,7 +812,7 @@ protected: Rect _cropRect; ID2D1Bitmap * _bitmap; - static std::map _bitmapCache; + static std::map _bitmapCache; }; diff --git a/core/e2dtool.h b/core/e2dtool.h index 6708e351..3666c99c 100644 --- a/core/e2dtool.h +++ b/core/e2dtool.h @@ -58,15 +58,20 @@ public: Music(); explicit Music( - const Resource& res /* 音乐资源 */ + const e2d::String& filePath /* 音乐文件路径 */ ); explicit Music( - IXAudio2* xAudio2 + const Resource& res /* 音乐资源 */ ); virtual ~Music(); + // 打开音乐文件 + bool open( + const e2d::String& filePath /* 音乐文件路径 */ + ); + // 打开音乐资源 bool open( const Resource& res @@ -110,6 +115,27 @@ public: // 获取 IXAudio2SourceVoice 对象 IXAudio2SourceVoice * getIXAudio2SourceVoice() const; +public: + class XAudio2Tool + { + public: + XAudio2Tool(); + + ~XAudio2Tool(); + + static XAudio2Tool* getInstance(); + + // 获取 XAudio2 实例对象 + IXAudio2 * getXAudio2(); + + // 获取 MasteringVoice 实例对象 + IXAudio2MasteringVoice* getMasteringVoice(); + + protected: + IXAudio2 * _xAudio2; + IXAudio2MasteringVoice* _masteringVoice; + }; + protected: bool _readMMIO(); @@ -137,9 +163,7 @@ protected: MMCKINFO _ckRiff; WAVEFORMATEX* _wfx; VoiceCallback _voiceCallback; - IXAudio2* _xAudio2; IXAudio2SourceVoice* _voice; - IXAudio2MasteringVoice* _masteringVoice; }; @@ -153,6 +177,37 @@ public: ~Player(); + // 预加载音乐资源 + bool preload( + const String& filePath /* 音乐文件路径 */ + ); + + // 播放音乐 + bool play( + const String& filePath, /* 音乐文件路径 */ + int nLoopCount = 0 /* 重复播放次数,设置 -1 为循环播放 */ + ); + + // 暂停音乐 + void pause( + const String& filePath /* 音乐文件路径 */ + ); + + // 继续播放音乐 + void resume( + const String& filePath /* 音乐文件路径 */ + ); + + // 停止音乐 + void stop( + const String& filePath /* 音乐文件路径 */ + ); + + // 获取音乐播放状态 + bool isPlaying( + const String& filePath /* 音乐文件路径 */ + ); + // 预加载音乐资源 bool preload( const Resource& res /* 音乐资源 */ @@ -201,26 +256,12 @@ public: // 停止所有音乐 void stopAll(); - // 打开或关闭播放器 - void setEnabled( - bool enabled - ); - // 清空音乐缓存 void clearCache(); - // 获取 XAudio2 实例对象 - IXAudio2 * getXAudio2(); - - // 获取 MasteringVoice 实例对象 - IXAudio2MasteringVoice* getMasteringVoice(); - private: - bool _enabled; float _volume; - IXAudio2* _xAudio2; - IXAudio2MasteringVoice* _masteringVoice; - std::map _musicList; + std::map _musicList; };