明确Resource的定义,不允许从本地文件创建Resource

This commit is contained in:
Nomango 2018-08-19 20:40:44 +08:00
parent a394eb0595
commit 00a2b9ebac
7 changed files with 471 additions and 343 deletions

View File

@ -2,7 +2,7 @@
#include "..\e2dbase.h"
#include "..\e2dtool.h"
std::map<e2d::Resource, ID2D1Bitmap*> e2d::Image::_bitmapCache;
std::map<size_t, ID2D1Bitmap*> 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<BYTE*>(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<BYTE*>(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));
}
// 释放相关资源

View File

@ -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();
}

View File

@ -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)

View File

@ -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))
{

View File

@ -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)

View File

@ -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<Resource, ID2D1Bitmap*> _bitmapCache;
static std::map<size_t, ID2D1Bitmap*> _bitmapCache;
};

View File

@ -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<Resource, Music*> _musicList;
std::map<size_t, Music*> _musicList;
};