增加File类和Resource类;图片和音乐资源统一为Resource map
This commit is contained in:
parent
0423b49bb9
commit
b7c4c409cb
|
|
@ -3,9 +3,7 @@
|
||||||
#include "..\e2dtool.h"
|
#include "..\e2dtool.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
static std::map<size_t, ID2D1Bitmap*> s_mBitmapsFromFile;
|
static std::map<e2d::Resource, ID2D1Bitmap*> s_mBitmapsFromResource;
|
||||||
static std::map<int, ID2D1Bitmap*> s_mBitmapsFromResource;
|
|
||||||
static std::set<ID2D1Bitmap*> s_vBitmaps;
|
|
||||||
|
|
||||||
|
|
||||||
e2d::Image::Image()
|
e2d::Image::Image()
|
||||||
|
|
@ -14,33 +12,33 @@ e2d::Image::Image()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::Image::Image(const String& filePath)
|
e2d::Image::Image(const Resource& res)
|
||||||
: _bitmap(nullptr)
|
: _bitmap(nullptr)
|
||||||
, _cropRect()
|
, _cropRect()
|
||||||
{
|
{
|
||||||
this->open(filePath);
|
this->open(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::Image::Image(int resNameId, const String& resType)
|
e2d::Image::Image(const Resource& res, const Rect& cropRect)
|
||||||
: _bitmap(nullptr)
|
: _bitmap(nullptr)
|
||||||
, _cropRect()
|
, _cropRect()
|
||||||
{
|
{
|
||||||
this->open(resNameId, resType);
|
this->open(res);
|
||||||
}
|
|
||||||
|
|
||||||
e2d::Image::Image(const String& filePath, const Rect& cropRect)
|
|
||||||
: _bitmap(nullptr)
|
|
||||||
, _cropRect()
|
|
||||||
{
|
|
||||||
this->open(filePath);
|
|
||||||
this->crop(cropRect);
|
this->crop(cropRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::Image::Image(int resNameId, const String& resType, const Rect& cropRect)
|
e2d::Image::Image(const String & fileName)
|
||||||
: _bitmap(nullptr)
|
: _bitmap(nullptr)
|
||||||
, _cropRect()
|
, _cropRect()
|
||||||
{
|
{
|
||||||
this->open(resNameId, resType);
|
this->open(Resource(fileName));
|
||||||
|
}
|
||||||
|
|
||||||
|
e2d::Image::Image(const String & fileName, const Rect & cropRect)
|
||||||
|
: _bitmap(nullptr)
|
||||||
|
, _cropRect()
|
||||||
|
{
|
||||||
|
this->open(Resource(fileName));
|
||||||
this->crop(cropRect);
|
this->crop(cropRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,33 +46,29 @@ e2d::Image::~Image()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool e2d::Image::open(const String& filePath)
|
bool e2d::Image::open(const Resource& res)
|
||||||
{
|
{
|
||||||
WARN_IF(filePath.isEmpty(), "Image open failed! Invalid file name.");
|
if (!res.isResource())
|
||||||
|
{
|
||||||
|
WARN_IF(res.getFileName().isEmpty(), "Image open failed! Invalid file name.");
|
||||||
|
|
||||||
if (filePath.isEmpty())
|
if (res.getFileName().isEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!Image::preload(filePath))
|
if (!Image::preload(res))
|
||||||
{
|
{
|
||||||
WARN("Load Image from file failed!");
|
WARN("Load Image from file failed!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->_setBitmap(s_mBitmapsFromFile.at(filePath.getHashCode()));
|
this->_setBitmap(s_mBitmapsFromResource.at(res));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool e2d::Image::open(int resNameId, const String& resType)
|
bool e2d::Image::open(const String & fileName)
|
||||||
{
|
{
|
||||||
if (!Image::preload(resNameId, resType))
|
return open(Resource(fileName));
|
||||||
{
|
|
||||||
WARN("Load Image from file failed!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->_setBitmap(s_mBitmapsFromResource.at(resNameId));
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Image::crop(const Rect& cropRect)
|
void e2d::Image::crop(const Rect& cropRect)
|
||||||
|
|
@ -154,94 +148,9 @@ e2d::Point e2d::Image::getCropPos() const
|
||||||
return _cropRect.origin;
|
return _cropRect.origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool e2d::Image::preload(const String& filePath)
|
bool e2d::Image::preload(const Resource& res)
|
||||||
{
|
{
|
||||||
if (s_mBitmapsFromFile.find(filePath.getHashCode()) != s_mBitmapsFromFile.end())
|
if (s_mBitmapsFromResource.find(res) != s_mBitmapsFromResource.end())
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
String actualFilePath = Path::findFile(filePath);
|
|
||||||
if (actualFilePath.isEmpty())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
|
|
||||||
IWICBitmapDecoder *pDecoder = nullptr;
|
|
||||||
IWICBitmapFrameDecode *pSource = nullptr;
|
|
||||||
IWICStream *pStream = nullptr;
|
|
||||||
IWICFormatConverter *pConverter = nullptr;
|
|
||||||
ID2D1Bitmap *pBitmap = nullptr;
|
|
||||||
|
|
||||||
// 创建解码器
|
|
||||||
hr = Renderer::getImagingFactory()->CreateDecoderFromFilename(
|
|
||||||
(LPCWSTR)actualFilePath,
|
|
||||||
nullptr,
|
|
||||||
GENERIC_READ,
|
|
||||||
WICDecodeMetadataCacheOnLoad,
|
|
||||||
&pDecoder
|
|
||||||
);
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
// 创建初始化框架
|
|
||||||
hr = pDecoder->GetFrame(0, &pSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
// 创建图片格式转换器
|
|
||||||
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
|
|
||||||
hr = Renderer::getImagingFactory()->CreateFormatConverter(&pConverter);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
// 图片格式转换成 32bbpPBGRA
|
|
||||||
hr = pConverter->Initialize(
|
|
||||||
pSource,
|
|
||||||
GUID_WICPixelFormat32bppPBGRA,
|
|
||||||
WICBitmapDitherTypeNone,
|
|
||||||
nullptr,
|
|
||||||
0.f,
|
|
||||||
WICBitmapPaletteTypeMedianCut
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
// 从 WIC 位图创建一个 Direct2D 位图
|
|
||||||
hr = Renderer::getInstance()->getRenderTarget()->CreateBitmapFromWicBitmap(
|
|
||||||
pConverter,
|
|
||||||
nullptr,
|
|
||||||
&pBitmap
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
// 保存图片指针和图片的 Hash 名
|
|
||||||
s_mBitmapsFromFile.insert(
|
|
||||||
std::map<size_t, ID2D1Bitmap*>::value_type(
|
|
||||||
filePath.getHashCode(),
|
|
||||||
pBitmap)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 释放相关资源
|
|
||||||
SafeRelease(pDecoder);
|
|
||||||
SafeRelease(pSource);
|
|
||||||
SafeRelease(pStream);
|
|
||||||
SafeRelease(pConverter);
|
|
||||||
|
|
||||||
return SUCCEEDED(hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool e2d::Image::preload(int resNameId, const String& resType)
|
|
||||||
{
|
|
||||||
if (s_mBitmapsFromResource.find(resNameId) != s_mBitmapsFromResource.end())
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -252,63 +161,87 @@ bool e2d::Image::preload(int resNameId, const String& resType)
|
||||||
IWICBitmapFrameDecode *pSource = nullptr;
|
IWICBitmapFrameDecode *pSource = nullptr;
|
||||||
IWICStream *pStream = nullptr;
|
IWICStream *pStream = nullptr;
|
||||||
IWICFormatConverter *pConverter = nullptr;
|
IWICFormatConverter *pConverter = nullptr;
|
||||||
IWICBitmapScaler *pScaler = nullptr;
|
|
||||||
ID2D1Bitmap *pBitmap = nullptr;
|
ID2D1Bitmap *pBitmap = nullptr;
|
||||||
|
IWICImagingFactory *pImagingFactory = Renderer::getImagingFactory();
|
||||||
|
|
||||||
HRSRC imageResHandle = nullptr;
|
if (res.isResource())
|
||||||
HGLOBAL imageResDataHandle = nullptr;
|
|
||||||
void *pImageFile = nullptr;
|
|
||||||
DWORD imageFileSize = 0;
|
|
||||||
|
|
||||||
// 定位资源
|
|
||||||
imageResHandle = ::FindResourceW(HINST_THISCOMPONENT, MAKEINTRESOURCE(resNameId), (LPCWSTR)resType);
|
|
||||||
|
|
||||||
hr = imageResHandle ? S_OK : E_FAIL;
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
{
|
||||||
// 加载资源
|
HRSRC imageResHandle = nullptr;
|
||||||
imageResDataHandle = ::LoadResource(HINST_THISCOMPONENT, imageResHandle);
|
HGLOBAL imageResDataHandle = nullptr;
|
||||||
|
void *pImageFile = nullptr;
|
||||||
|
DWORD imageFileSize = 0;
|
||||||
|
|
||||||
hr = imageResDataHandle ? S_OK : E_FAIL;
|
// 定位资源
|
||||||
}
|
imageResHandle = ::FindResourceW(
|
||||||
|
HINST_THISCOMPONENT,
|
||||||
if (SUCCEEDED(hr))
|
MAKEINTRESOURCE(res.getResNameId()),
|
||||||
{
|
(LPCWSTR)res.getResType()
|
||||||
// 获取文件指针,并锁定资源
|
|
||||||
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 = Renderer::getImagingFactory()->CreateStream(&pStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
// 初始化流
|
|
||||||
hr = pStream->InitializeFromMemory(
|
|
||||||
reinterpret_cast<BYTE*>(pImageFile),
|
|
||||||
imageFileSize
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// 创建流的解码器
|
String actualFilePath = File(res.getFileName()).getFilePath();
|
||||||
hr = Renderer::getImagingFactory()->CreateDecoderFromStream(
|
if (actualFilePath.isEmpty())
|
||||||
pStream,
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建解码器
|
||||||
|
hr = pImagingFactory->CreateDecoderFromFilename(
|
||||||
|
(LPCWSTR)actualFilePath,
|
||||||
nullptr,
|
nullptr,
|
||||||
|
GENERIC_READ,
|
||||||
WICDecodeMetadataCacheOnLoad,
|
WICDecodeMetadataCacheOnLoad,
|
||||||
&pDecoder
|
&pDecoder
|
||||||
);
|
);
|
||||||
|
|
@ -323,8 +256,7 @@ bool e2d::Image::preload(int resNameId, const String& resType)
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
// 创建图片格式转换器
|
// 创建图片格式转换器
|
||||||
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
|
hr = pImagingFactory->CreateFormatConverter(&pConverter);
|
||||||
hr = Renderer::getImagingFactory()->CreateFormatConverter(&pConverter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
|
|
@ -352,7 +284,7 @@ bool e2d::Image::preload(int resNameId, const String& resType)
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
s_mBitmapsFromResource.insert(std::pair<int, ID2D1Bitmap*>(resNameId, pBitmap));
|
s_mBitmapsFromResource.insert(std::make_pair(res, pBitmap));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 释放相关资源
|
// 释放相关资源
|
||||||
|
|
@ -360,31 +292,17 @@ bool e2d::Image::preload(int resNameId, const String& resType)
|
||||||
SafeRelease(pSource);
|
SafeRelease(pSource);
|
||||||
SafeRelease(pStream);
|
SafeRelease(pStream);
|
||||||
SafeRelease(pConverter);
|
SafeRelease(pConverter);
|
||||||
SafeRelease(pScaler);
|
|
||||||
|
|
||||||
return SUCCEEDED(hr);
|
return SUCCEEDED(hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void e2d::Image::clearCache()
|
void e2d::Image::clearCache()
|
||||||
{
|
{
|
||||||
for (auto bitmap : s_mBitmapsFromFile)
|
|
||||||
{
|
|
||||||
SafeRelease(bitmap.second);
|
|
||||||
}
|
|
||||||
s_mBitmapsFromFile.clear();
|
|
||||||
|
|
||||||
for (auto bitmap : s_mBitmapsFromResource)
|
for (auto bitmap : s_mBitmapsFromResource)
|
||||||
{
|
{
|
||||||
SafeRelease(bitmap.second);
|
SafeRelease(bitmap.second);
|
||||||
}
|
}
|
||||||
s_mBitmapsFromResource.clear();
|
s_mBitmapsFromResource.clear();
|
||||||
|
|
||||||
for (auto bitmap : s_vBitmaps)
|
|
||||||
{
|
|
||||||
SafeRelease(bitmap);
|
|
||||||
}
|
|
||||||
s_vBitmaps.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Image::_setBitmap(ID2D1Bitmap * bitmap)
|
void e2d::Image::_setBitmap(ID2D1Bitmap * bitmap)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
#include "..\e2dtool.h"
|
||||||
|
|
||||||
|
e2d::Resource::Resource(const String & fileName)
|
||||||
|
: _isResource(false)
|
||||||
|
, _fileName(fileName)
|
||||||
|
, _resNameId(0)
|
||||||
|
, _resType()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
e2d::Resource::Resource(int resNameId, const String & resType)
|
||||||
|
: _isResource(true)
|
||||||
|
, _fileName()
|
||||||
|
, _resNameId(resNameId)
|
||||||
|
, _resType(resType)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool e2d::Resource::isResource() const
|
||||||
|
{
|
||||||
|
return _isResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
const e2d::String & e2d::Resource::getFileName() const
|
||||||
|
{
|
||||||
|
return _fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
int e2d::Resource::getResNameId() const
|
||||||
|
{
|
||||||
|
return _resNameId;
|
||||||
|
}
|
||||||
|
|
||||||
|
const e2d::String & e2d::Resource::getResType() const
|
||||||
|
{
|
||||||
|
return _resType;
|
||||||
|
}
|
||||||
|
|
||||||
|
int e2d::Resource::getKey() const
|
||||||
|
{
|
||||||
|
if (_isResource)
|
||||||
|
{
|
||||||
|
return _resNameId;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return _fileName.getHashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
@ -12,29 +12,29 @@ e2d::Sprite::Sprite(Image * image)
|
||||||
open(image);
|
open(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::Sprite::Sprite(const String& filePath)
|
e2d::Sprite::Sprite(const Resource& res)
|
||||||
: _image(nullptr)
|
: _image(nullptr)
|
||||||
{
|
{
|
||||||
open(filePath);
|
open(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::Sprite::Sprite(int resNameId, const String& resType)
|
e2d::Sprite::Sprite(const Resource& res, const Rect& cropRect)
|
||||||
: _image(nullptr)
|
: _image(nullptr)
|
||||||
{
|
{
|
||||||
open(resNameId, resType);
|
open(res);
|
||||||
}
|
|
||||||
|
|
||||||
e2d::Sprite::Sprite(const String& filePath, const Rect& cropRect)
|
|
||||||
: _image(nullptr)
|
|
||||||
{
|
|
||||||
open(filePath);
|
|
||||||
crop(cropRect);
|
crop(cropRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::Sprite::Sprite(int resNameId, const String& resType, const Rect& cropRect)
|
e2d::Sprite::Sprite(const String & fileName)
|
||||||
: _image(nullptr)
|
: _image(nullptr)
|
||||||
{
|
{
|
||||||
open(resNameId, resType);
|
open(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
e2d::Sprite::Sprite(const String & fileName, const Rect & cropRect)
|
||||||
|
: _image(nullptr)
|
||||||
|
{
|
||||||
|
open(fileName);
|
||||||
crop(cropRect);
|
crop(cropRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,7 +57,7 @@ bool e2d::Sprite::open(Image * image)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool e2d::Sprite::open(const String& filePath)
|
bool e2d::Sprite::open(const Resource& res)
|
||||||
{
|
{
|
||||||
if (!_image)
|
if (!_image)
|
||||||
{
|
{
|
||||||
|
|
@ -65,7 +65,7 @@ bool e2d::Sprite::open(const String& filePath)
|
||||||
GC::retain(_image);
|
GC::retain(_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_image->open(filePath))
|
if (_image->open(res))
|
||||||
{
|
{
|
||||||
Node::setSize(_image->getWidth(), _image->getHeight());
|
Node::setSize(_image->getWidth(), _image->getHeight());
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -73,20 +73,9 @@ bool e2d::Sprite::open(const String& filePath)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool e2d::Sprite::open(int resNameId, const String& resType)
|
bool e2d::Sprite::open(const String & fileName)
|
||||||
{
|
{
|
||||||
if (!_image)
|
return open(Resource(fileName));
|
||||||
{
|
|
||||||
_image = new (e2d::autorelease) Image();
|
|
||||||
GC::retain(_image);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_image->open(resNameId, resType))
|
|
||||||
{
|
|
||||||
Node::setSize(_image->getWidth(), _image->getHeight());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Sprite::crop(const Rect& cropRect)
|
void e2d::Sprite::crop(const Rect& cropRect)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,182 @@
|
||||||
|
#include "..\e2dtool.h"
|
||||||
|
#include <commdlg.h>
|
||||||
|
|
||||||
|
std::list<e2d::String> e2d::File::_searchPaths;
|
||||||
|
|
||||||
|
e2d::File::File()
|
||||||
|
: _fileName()
|
||||||
|
, _attributes(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
e2d::File::File(const String & fileName)
|
||||||
|
: _fileName(fileName)
|
||||||
|
, _attributes(0)
|
||||||
|
{
|
||||||
|
this->open(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
e2d::File::~File()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool e2d::File::open(const String & fileName)
|
||||||
|
{
|
||||||
|
auto FindFile = [=](const String & path) -> bool
|
||||||
|
{
|
||||||
|
if (::_waccess((const wchar_t*)path, 0) == 0)
|
||||||
|
{
|
||||||
|
_attributes = ::GetFileAttributes((LPCTSTR)path);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (FindFile(fileName))
|
||||||
|
{
|
||||||
|
_fileName = fileName;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto& resPath : _searchPaths)
|
||||||
|
{
|
||||||
|
if (FindFile(resPath + fileName))
|
||||||
|
{
|
||||||
|
_fileName = resPath + fileName;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool e2d::File::exists() const
|
||||||
|
{
|
||||||
|
return ::_waccess((const wchar_t*)_fileName, 0) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool e2d::File::isFolder() const
|
||||||
|
{
|
||||||
|
return _attributes & FILE_ATTRIBUTE_DIRECTORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
e2d::String e2d::File::getFilePath() const
|
||||||
|
{
|
||||||
|
return _fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
e2d::String e2d::File::getExtension() const
|
||||||
|
{
|
||||||
|
String fileExtension;
|
||||||
|
// 找到文件名中的最后一个 '.' 的位置
|
||||||
|
size_t pos = _fileName.getWString().find_last_of(L'.');
|
||||||
|
// 判断 pos 是否是有效位置
|
||||||
|
if (pos != std::wstring::npos)
|
||||||
|
{
|
||||||
|
// 截取扩展名
|
||||||
|
fileExtension = _fileName.subtract(static_cast<int>(pos));
|
||||||
|
// 转换为小写字母
|
||||||
|
fileExtension = fileExtension.toLower();
|
||||||
|
}
|
||||||
|
return fileExtension;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool e2d::File::deleteFile()
|
||||||
|
{
|
||||||
|
if (::DeleteFile((LPCWSTR)_fileName))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
e2d::File e2d::File::extract(int resNameId, const String & resType, const String& destFileName)
|
||||||
|
{
|
||||||
|
String destFilePath = Path::getTempPath() + destFileName;
|
||||||
|
// 创建文件
|
||||||
|
HANDLE hFile = ::CreateFile((LPCWSTR)destFilePath, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
|
||||||
|
if (hFile == INVALID_HANDLE_VALUE)
|
||||||
|
return std::move(File());
|
||||||
|
|
||||||
|
// 查找资源文件中、加载资源到内存、得到资源大小
|
||||||
|
HRSRC hRes = ::FindResource(NULL, MAKEINTRESOURCE(resNameId), (LPCWSTR)resType);
|
||||||
|
HGLOBAL hMem = ::LoadResource(NULL, hRes);
|
||||||
|
DWORD dwSize = ::SizeofResource(NULL, hRes);
|
||||||
|
|
||||||
|
if (hRes && hMem && dwSize)
|
||||||
|
{
|
||||||
|
// 写入文件
|
||||||
|
DWORD dwWrite = 0;
|
||||||
|
::WriteFile(hFile, hMem, dwSize, &dwWrite, NULL);
|
||||||
|
::CloseHandle(hFile);
|
||||||
|
return File(destFilePath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
::CloseHandle(hFile);
|
||||||
|
::DeleteFile((LPCWSTR)destFilePath);
|
||||||
|
return std::move(File());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::File::addSearchPath(const String & path)
|
||||||
|
{
|
||||||
|
String tmp = path;
|
||||||
|
tmp.replace(L"/", L"\\");
|
||||||
|
if (tmp[tmp.getLength() - 1] != L'\\')
|
||||||
|
{
|
||||||
|
tmp << L"\\";
|
||||||
|
}
|
||||||
|
auto iter = std::find(_searchPaths.cbegin(), _searchPaths.cend(), tmp);
|
||||||
|
if (iter == _searchPaths.cend())
|
||||||
|
{
|
||||||
|
_searchPaths.push_front(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool e2d::File::createFolder(const String & dirPath)
|
||||||
|
{
|
||||||
|
if (dirPath.isEmpty() || dirPath.getLength() >= MAX_PATH)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wchar_t tmpDirPath[_MAX_PATH] = { 0 };
|
||||||
|
int length = dirPath.getLength();
|
||||||
|
|
||||||
|
for (int i = 0; i < length; ++i)
|
||||||
|
{
|
||||||
|
tmpDirPath[i] = dirPath.at(i);
|
||||||
|
if (tmpDirPath[i] == L'\\' || tmpDirPath[i] == L'/' || i == (length - 1))
|
||||||
|
{
|
||||||
|
if (::_waccess(tmpDirPath, 0) != 0)
|
||||||
|
{
|
||||||
|
if (::_wmkdir(tmpDirPath) != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
e2d::String e2d::File::getSaveFilePath(const String& title, const String& defExt)
|
||||||
|
{
|
||||||
|
// 弹出保存对话框
|
||||||
|
OPENFILENAME ofn = { 0 };
|
||||||
|
wchar_t strFilename[MAX_PATH] = { 0 }; // 用于接收文件名
|
||||||
|
ofn.lStructSize = sizeof(OPENFILENAME); // 结构体大小
|
||||||
|
ofn.hwndOwner = Window::getInstance()->getHWnd(); // 窗口句柄
|
||||||
|
ofn.lpstrFilter = L"所有文件\0*.*\0\0"; // 设置过滤
|
||||||
|
ofn.nFilterIndex = 1; // 过滤器索引
|
||||||
|
ofn.lpstrFile = strFilename; // 接收返回的文件路径和文件名
|
||||||
|
ofn.nMaxFile = sizeof(strFilename); // 缓冲区长度
|
||||||
|
ofn.lpstrInitialDir = nullptr; // 初始目录为默认
|
||||||
|
ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
|
||||||
|
ofn.lpstrTitle = (LPCWSTR)title; // 标题
|
||||||
|
ofn.lpstrDefExt = (LPCWSTR)defExt; // 默认追加的扩展名
|
||||||
|
|
||||||
|
if (GetSaveFileName(&ofn))
|
||||||
|
{
|
||||||
|
return strFilename;
|
||||||
|
}
|
||||||
|
return std::move(String());
|
||||||
|
}
|
||||||
|
|
@ -49,7 +49,7 @@ e2d::Music::Music(const e2d::String & filePath)
|
||||||
this->open(filePath);
|
this->open(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::Music::Music(int resNameId, const String & resType)
|
e2d::Music::Music(const Resource& res)
|
||||||
: _opened(false)
|
: _opened(false)
|
||||||
, _playing(false)
|
, _playing(false)
|
||||||
, _wfx(nullptr)
|
, _wfx(nullptr)
|
||||||
|
|
@ -60,7 +60,7 @@ e2d::Music::Music(int resNameId, const String & resType)
|
||||||
, _voice(nullptr)
|
, _voice(nullptr)
|
||||||
, _voiceCallback(this)
|
, _voiceCallback(this)
|
||||||
{
|
{
|
||||||
this->open(resNameId, resType);
|
this->open(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::Music::~Music()
|
e2d::Music::~Music()
|
||||||
|
|
@ -69,6 +69,11 @@ e2d::Music::~Music()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool e2d::Music::open(const e2d::String& filePath)
|
bool e2d::Music::open(const e2d::String& filePath)
|
||||||
|
{
|
||||||
|
return open(Resource(filePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool e2d::Music::open(const Resource& res)
|
||||||
{
|
{
|
||||||
if (_opened)
|
if (_opened)
|
||||||
{
|
{
|
||||||
|
|
@ -76,114 +81,68 @@ bool e2d::Music::open(const e2d::String& filePath)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filePath.isEmpty())
|
if (res.isResource())
|
||||||
{
|
{
|
||||||
WARN("MusicInfo::open Invalid file name.");
|
HRSRC hResInfo;
|
||||||
return false;
|
HGLOBAL hResData;
|
||||||
}
|
DWORD dwSize;
|
||||||
|
void* pvRes;
|
||||||
|
|
||||||
String actualFilePath = Path::findFile(filePath);
|
if (nullptr == (hResInfo = FindResourceW(HINST_THISCOMPONENT, MAKEINTRESOURCE(res.getResNameId()), (LPCWSTR)res.getResType())))
|
||||||
if (actualFilePath.isEmpty())
|
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);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
WARN("MusicInfo::open File not found.");
|
String filePath = res.getFileName();
|
||||||
return false;
|
if (filePath.isEmpty())
|
||||||
}
|
{
|
||||||
|
WARN("MusicInfo::open Invalid file name.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// 定位 wave 文件
|
String actualFilePath = File(filePath).getFilePath();
|
||||||
wchar_t pFilePath[MAX_PATH];
|
if (actualFilePath.isEmpty())
|
||||||
if (!_findMediaFileCch(pFilePath, MAX_PATH, (const wchar_t *)actualFilePath))
|
{
|
||||||
{
|
WARN("MusicInfo::open File not found.");
|
||||||
WARN("Failed to find media file: %s", pFilePath);
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
_hmmio = mmioOpen(pFilePath, nullptr, MMIO_ALLOCBUF | MMIO_READ);
|
// ¶¨Î» 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);
|
||||||
|
}
|
||||||
|
|
||||||
if (nullptr == _hmmio)
|
if (nullptr == _hmmio)
|
||||||
{
|
{
|
||||||
return TraceError(L"mmioOpen");
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建音源
|
|
||||||
HRESULT hr = Player::getInstance()->getXAudio2()->CreateSourceVoice(
|
|
||||||
&_voice,
|
|
||||||
_wfx,
|
|
||||||
0,
|
|
||||||
XAUDIO2_DEFAULT_FREQ_RATIO,
|
|
||||||
&this->_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(int resNameId, const e2d::String& resType)
|
|
||||||
{
|
|
||||||
HRSRC hResInfo;
|
|
||||||
HGLOBAL hResData;
|
|
||||||
DWORD dwSize;
|
|
||||||
void* pvRes;
|
|
||||||
|
|
||||||
if (_opened)
|
|
||||||
{
|
|
||||||
WARN("MusicInfo can be opened only once!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nullptr == (hResInfo = FindResourceW(HINST_THISCOMPONENT, MAKEINTRESOURCE(resNameId), (LPCWSTR)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 (!_readMMIO())
|
if (!_readMMIO())
|
||||||
{
|
{
|
||||||
// 读取非 wave 文件时 ReadMMIO 调用失败
|
// 读取非 wave 文件时 ReadMMIO 调用失败
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
#include "..\e2dtool.h"
|
#include "..\e2dtool.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <commdlg.h>
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" const GUID DECLSPEC_SELECTANY FOLDERID_LocalAppData = {
|
extern "C" const GUID DECLSPEC_SELECTANY FOLDERID_LocalAppData = {
|
||||||
|
|
@ -8,49 +7,33 @@ extern "C" const GUID DECLSPEC_SELECTANY FOLDERID_LocalAppData = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
e2d::String e2d::Path::_tempPath;
|
|
||||||
e2d::String e2d::Path::_dataPath;
|
|
||||||
std::list<e2d::String> e2d::Path::_paths;
|
|
||||||
|
|
||||||
|
|
||||||
void e2d::Path::addSearchPath(String path)
|
|
||||||
{
|
|
||||||
path.replace(L"/", L"\\");
|
|
||||||
if (path[path.getLength() - 1] != L'\\')
|
|
||||||
{
|
|
||||||
path << L"\\";
|
|
||||||
}
|
|
||||||
auto iter = std::find(_paths.cbegin(), _paths.cend(), path);
|
|
||||||
if (iter == _paths.cend())
|
|
||||||
{
|
|
||||||
_paths.push_front(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
e2d::String e2d::Path::getDataPath()
|
e2d::String e2d::Path::getDataPath()
|
||||||
{
|
{
|
||||||
if (_dataPath.isEmpty())
|
static String dataPath;
|
||||||
|
if (dataPath.isEmpty())
|
||||||
{
|
{
|
||||||
// 设置数据的保存路径
|
// 设置数据的保存路径
|
||||||
String localAppDataPath = Path::getLocalAppDataPath();
|
String localAppDataPath = Path::getLocalAppDataPath();
|
||||||
String gameName = Game::getInstance()->getConfig()->getGameName();
|
String gameName = Game::getInstance()->getConfig()->getGameName();
|
||||||
if (!localAppDataPath.isEmpty() && !gameName.isEmpty())
|
if (!localAppDataPath.isEmpty() && !gameName.isEmpty())
|
||||||
{
|
{
|
||||||
_dataPath = localAppDataPath + L"\\Easy2DGameData\\" << gameName << L"\\";
|
dataPath = localAppDataPath + L"\\Easy2DGameData\\" << gameName << L"\\";
|
||||||
|
|
||||||
if (!Path::exists(_dataPath) && !Path::createFolder(_dataPath))
|
File file(dataPath);
|
||||||
|
if (!file.exists() && !File::createFolder(dataPath))
|
||||||
{
|
{
|
||||||
_dataPath = L"";
|
dataPath = L"";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_dataPath << L"Data.ini";
|
dataPath << L"Data.ini";
|
||||||
}
|
}
|
||||||
return _dataPath;
|
return dataPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::String e2d::Path::getTempPath()
|
e2d::String e2d::Path::getTempPath()
|
||||||
{
|
{
|
||||||
if (_tempPath.isEmpty())
|
static String tempPath;
|
||||||
|
if (tempPath.isEmpty())
|
||||||
{
|
{
|
||||||
// 设置临时文件保存路径
|
// 设置临时文件保存路径
|
||||||
wchar_t path[_MAX_PATH];
|
wchar_t path[_MAX_PATH];
|
||||||
|
|
@ -58,15 +41,16 @@ e2d::String e2d::Path::getTempPath()
|
||||||
|
|
||||||
if (0 != ::GetTempPath(_MAX_PATH, path) && !gameName.isEmpty())
|
if (0 != ::GetTempPath(_MAX_PATH, path) && !gameName.isEmpty())
|
||||||
{
|
{
|
||||||
_tempPath << path << L"\\Easy2DGameTemp\\" << gameName << L"\\";
|
tempPath << path << L"\\Easy2DGameTemp\\" << gameName << L"\\";
|
||||||
|
|
||||||
if (!Path::exists(_tempPath) && !Path::createFolder(_tempPath))
|
File file(tempPath);
|
||||||
|
if (!file.exists() && !File::createFolder(tempPath))
|
||||||
{
|
{
|
||||||
_tempPath = L"";
|
tempPath = L"";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return _tempPath;
|
return tempPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::String e2d::Path::getLocalAppDataPath()
|
e2d::String e2d::Path::getLocalAppDataPath()
|
||||||
|
|
@ -94,134 +78,14 @@ e2d::String e2d::Path::getLocalAppDataPath()
|
||||||
|
|
||||||
e2d::String e2d::Path::getCurrentFilePath()
|
e2d::String e2d::Path::getCurrentFilePath()
|
||||||
{
|
{
|
||||||
TCHAR szPath[_MAX_PATH] = { 0 };
|
static String currFilePath;
|
||||||
if (::GetModuleFileName(nullptr, szPath, _MAX_PATH) != 0)
|
if (currFilePath.isEmpty())
|
||||||
{
|
{
|
||||||
return std::move(String(szPath));
|
TCHAR szPath[_MAX_PATH] = { 0 };
|
||||||
}
|
if (::GetModuleFileName(nullptr, szPath, _MAX_PATH) != 0)
|
||||||
return std::move(String());
|
|
||||||
}
|
|
||||||
|
|
||||||
e2d::String e2d::Path::findFile(const String& path)
|
|
||||||
{
|
|
||||||
if (Path::exists(path))
|
|
||||||
{
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (auto& resPath : _paths)
|
|
||||||
{
|
{
|
||||||
if (Path::exists(resPath + path))
|
currFilePath = szPath;
|
||||||
{
|
|
||||||
return resPath + path;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return std::move(String());
|
return currFilePath;
|
||||||
}
|
|
||||||
|
|
||||||
e2d::String e2d::Path::extractResource(int resNameId, const String & resType, const String & destFileName)
|
|
||||||
{
|
|
||||||
String destFilePath = _tempPath + destFileName;
|
|
||||||
// 创建文件
|
|
||||||
HANDLE hFile = ::CreateFile((LPCWSTR)destFilePath, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
|
|
||||||
if (hFile == INVALID_HANDLE_VALUE)
|
|
||||||
return std::move(String());
|
|
||||||
|
|
||||||
// 查找资源文件中、加载资源到内存、得到资源大小
|
|
||||||
HRSRC hRes = ::FindResource(NULL, MAKEINTRESOURCE(resNameId), (LPCWSTR)resType);
|
|
||||||
HGLOBAL hMem = ::LoadResource(NULL, hRes);
|
|
||||||
DWORD dwSize = ::SizeofResource(NULL, hRes);
|
|
||||||
|
|
||||||
if (hRes && hMem && dwSize)
|
|
||||||
{
|
|
||||||
// 写入文件
|
|
||||||
DWORD dwWrite = 0;
|
|
||||||
::WriteFile(hFile, hMem, dwSize, &dwWrite, NULL);
|
|
||||||
::CloseHandle(hFile);
|
|
||||||
return destFilePath;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
::CloseHandle(hFile);
|
|
||||||
::DeleteFile((LPCWSTR)destFilePath);
|
|
||||||
return std::move(String());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
e2d::String e2d::Path::getFileExtension(const String& filePath)
|
|
||||||
{
|
|
||||||
String fileExtension;
|
|
||||||
// 找到文件名中的最后一个 '.' 的位置
|
|
||||||
size_t pos = filePath.getWString().find_last_of(L'.');
|
|
||||||
// 判断 pos 是否是有效位置
|
|
||||||
if (pos != std::wstring::npos)
|
|
||||||
{
|
|
||||||
// 截取扩展名
|
|
||||||
fileExtension = filePath.subtract(static_cast<int>(pos));
|
|
||||||
// 转换为小写字母
|
|
||||||
fileExtension = fileExtension.toLower();
|
|
||||||
}
|
|
||||||
|
|
||||||
return fileExtension;
|
|
||||||
}
|
|
||||||
|
|
||||||
e2d::String e2d::Path::getSaveFilePath(const String& title, const String& defExt)
|
|
||||||
{
|
|
||||||
// 弹出保存对话框
|
|
||||||
OPENFILENAME ofn = { 0 };
|
|
||||||
wchar_t strFilename[MAX_PATH] = { 0 }; // 用于接收文件名
|
|
||||||
ofn.lStructSize = sizeof(OPENFILENAME); // 结构体大小
|
|
||||||
ofn.hwndOwner = Window::getInstance()->getHWnd(); // 窗口句柄
|
|
||||||
ofn.lpstrFilter = L"所有文件\0*.*\0\0"; // 设置过滤
|
|
||||||
ofn.nFilterIndex = 1; // 过滤器索引
|
|
||||||
ofn.lpstrFile = strFilename; // 接收返回的文件路径和文件名
|
|
||||||
ofn.nMaxFile = sizeof(strFilename); // 缓冲区长度
|
|
||||||
ofn.lpstrInitialDir = nullptr; // 初始目录为默认
|
|
||||||
ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
|
|
||||||
ofn.lpstrTitle = (LPCWSTR)title; // 标题
|
|
||||||
ofn.lpstrDefExt = (LPCWSTR)defExt; // 默认追加的扩展名
|
|
||||||
|
|
||||||
if (GetSaveFileName(&ofn))
|
|
||||||
{
|
|
||||||
return strFilename;
|
|
||||||
}
|
|
||||||
return std::move(String());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool e2d::Path::createFolder(const String& dirPath)
|
|
||||||
{
|
|
||||||
if (dirPath.isEmpty() || dirPath.getLength() >= MAX_PATH)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
wchar_t tmpDirPath[_MAX_PATH] = { 0 };
|
|
||||||
int length = dirPath.getLength();
|
|
||||||
|
|
||||||
for (int i = 0; i < length; ++i)
|
|
||||||
{
|
|
||||||
tmpDirPath[i] = dirPath.at(i);
|
|
||||||
if (tmpDirPath[i] == L'\\' || tmpDirPath[i] == L'/' || i == (length - 1))
|
|
||||||
{
|
|
||||||
if (::_waccess(tmpDirPath, 0) != 0)
|
|
||||||
{
|
|
||||||
if (::_wmkdir(tmpDirPath) != 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool e2d::Path::exists(const String & path)
|
|
||||||
{
|
|
||||||
if (path.isEmpty() || path.getLength() >= MAX_PATH)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return ::_waccess((const wchar_t *)path, 0) == 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,6 @@ e2d::Player::Player()
|
||||||
|
|
||||||
e2d::Player::~Player()
|
e2d::Player::~Player()
|
||||||
{
|
{
|
||||||
for (auto pair : _fileList)
|
|
||||||
GC::release(pair.second);
|
|
||||||
_fileList.clear();
|
|
||||||
|
|
||||||
for (auto pair : _resList)
|
for (auto pair : _resList)
|
||||||
GC::release(pair.second);
|
GC::release(pair.second);
|
||||||
_resList.clear();
|
_resList.clear();
|
||||||
|
|
@ -61,67 +57,42 @@ IXAudio2 * e2d::Player::getXAudio2()
|
||||||
|
|
||||||
bool e2d::Player::preload(const String& filePath)
|
bool e2d::Player::preload(const String& filePath)
|
||||||
{
|
{
|
||||||
UINT hash = filePath.getHashCode();
|
if (filePath.isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
if (_fileList.end() != _fileList.find(hash))
|
return preload(Resource(filePath));
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Music * music = new (e2d::autorelease) Music();
|
|
||||||
|
|
||||||
if (music->open(filePath))
|
|
||||||
{
|
|
||||||
GC::retain(music);
|
|
||||||
music->setVolume(_volume);
|
|
||||||
_fileList.insert(std::pair<UINT, Music *>(hash, music));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool e2d::Player::preload(int resNameId, const String& resType)
|
bool e2d::Player::preload(const Resource& res)
|
||||||
{
|
{
|
||||||
if (_resList.end() != _resList.find(resNameId))
|
if (_resList.end() != _resList.find(res))
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Music * music = new (e2d::autorelease) Music();
|
|
||||||
|
|
||||||
if (music->open(resNameId, resType))
|
Music * music = new (e2d::autorelease) Music();
|
||||||
{
|
|
||||||
GC::retain(music);
|
if (music->open(res))
|
||||||
music->setVolume(_volume);
|
{
|
||||||
_resList.insert(std::pair<UINT, Music *>(resNameId, music));
|
GC::retain(music);
|
||||||
return true;
|
music->setVolume(_volume);
|
||||||
}
|
_resList.insert(std::make_pair(res, music));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool e2d::Player::play(const String& filePath, int nLoopCount)
|
bool e2d::Player::play(const String& filePath, int nLoopCount)
|
||||||
{
|
{
|
||||||
if (Player::preload(filePath))
|
if (filePath.isEmpty())
|
||||||
{
|
return false;
|
||||||
UINT hash = filePath.getHashCode();
|
|
||||||
auto music = _fileList[hash];
|
return play(Resource(filePath), nLoopCount);
|
||||||
if (music->play(nLoopCount))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool e2d::Player::play(int resNameId, const String& resType, int nLoopCount)
|
bool e2d::Player::play(const Resource& res, int nLoopCount)
|
||||||
{
|
{
|
||||||
if (Player::preload(resNameId, resType))
|
if (Player::preload(res))
|
||||||
{
|
{
|
||||||
auto music = _resList[resNameId];
|
auto music = _resList[res];
|
||||||
if (music->play(nLoopCount))
|
if (music->play(nLoopCount))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -135,16 +106,13 @@ void e2d::Player::pause(const String& filePath)
|
||||||
if (filePath.isEmpty())
|
if (filePath.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
UINT hash = filePath.getHashCode();
|
pause(Resource(filePath));
|
||||||
|
|
||||||
if (_fileList.end() != _fileList.find(hash))
|
|
||||||
_fileList[hash]->pause();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Player::pause(int resNameId, const String& resType)
|
void e2d::Player::pause(const Resource& res)
|
||||||
{
|
{
|
||||||
if (_resList.end() != _resList.find(resNameId))
|
if (_resList.end() != _resList.find(res))
|
||||||
_resList[resNameId]->pause();
|
_resList[res]->pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Player::resume(const String& filePath)
|
void e2d::Player::resume(const String& filePath)
|
||||||
|
|
@ -152,16 +120,13 @@ void e2d::Player::resume(const String& filePath)
|
||||||
if (filePath.isEmpty())
|
if (filePath.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
UINT hash = filePath.getHashCode();
|
resume(Resource(filePath));
|
||||||
|
|
||||||
if (_fileList.end() != _fileList.find(hash))
|
|
||||||
_fileList[hash]->resume();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Player::resume(int resNameId, const String& resType)
|
void e2d::Player::resume(const Resource& res)
|
||||||
{
|
{
|
||||||
if (_resList.end() != _resList.find(resNameId))
|
if (_resList.end() != _resList.find(res))
|
||||||
_resList[resNameId]->pause();
|
_resList[res]->pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Player::stop(const String& filePath)
|
void e2d::Player::stop(const String& filePath)
|
||||||
|
|
@ -169,16 +134,17 @@ void e2d::Player::stop(const String& filePath)
|
||||||
if (filePath.isEmpty())
|
if (filePath.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
UINT hash = filePath.getHashCode();
|
stop(Resource(filePath));
|
||||||
|
|
||||||
if (_fileList.end() != _fileList.find(hash))
|
|
||||||
_fileList[hash]->stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Player::stop(int resNameId, const String& resType)
|
void e2d::Player::stop(const Resource& res)
|
||||||
{
|
{
|
||||||
if (_resList.end() != _resList.find(resNameId))
|
if (res.isResource())
|
||||||
_resList[resNameId]->stop();
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
if (_resList.end() != _resList.find(res))
|
||||||
|
_resList[res]->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool e2d::Player::isPlaying(const String& filePath)
|
bool e2d::Player::isPlaying(const String& filePath)
|
||||||
|
|
@ -186,18 +152,13 @@ bool e2d::Player::isPlaying(const String& filePath)
|
||||||
if (filePath.isEmpty())
|
if (filePath.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
UINT hash = filePath.getHashCode();
|
return isPlaying(Resource(filePath));
|
||||||
|
|
||||||
if (_fileList.end() != _fileList.find(hash))
|
|
||||||
return _fileList[hash]->isPlaying();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool e2d::Player::isPlaying(int resNameId, const String& resType)
|
bool e2d::Player::isPlaying(const Resource& res)
|
||||||
{
|
{
|
||||||
if (_resList.end() != _resList.find(resNameId))
|
if (_resList.end() != _resList.find(res))
|
||||||
return _resList[resNameId]->isPlaying();
|
return _resList[res]->isPlaying();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -209,11 +170,6 @@ double e2d::Player::getVolume()
|
||||||
void e2d::Player::setVolume(double volume)
|
void e2d::Player::setVolume(double volume)
|
||||||
{
|
{
|
||||||
_volume = std::min(std::max(float(volume), -224.f), 224.f);
|
_volume = std::min(std::max(float(volume), -224.f), 224.f);
|
||||||
for (auto pair : _fileList)
|
|
||||||
{
|
|
||||||
pair.second->setVolume(_volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto pair : _resList)
|
for (auto pair : _resList)
|
||||||
{
|
{
|
||||||
pair.second->setVolume(_volume);
|
pair.second->setVolume(_volume);
|
||||||
|
|
@ -222,11 +178,6 @@ void e2d::Player::setVolume(double volume)
|
||||||
|
|
||||||
void e2d::Player::pauseAll()
|
void e2d::Player::pauseAll()
|
||||||
{
|
{
|
||||||
for (auto pair : _fileList)
|
|
||||||
{
|
|
||||||
pair.second->pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto pair : _resList)
|
for (auto pair : _resList)
|
||||||
{
|
{
|
||||||
pair.second->pause();
|
pair.second->pause();
|
||||||
|
|
@ -235,11 +186,6 @@ void e2d::Player::pauseAll()
|
||||||
|
|
||||||
void e2d::Player::resumeAll()
|
void e2d::Player::resumeAll()
|
||||||
{
|
{
|
||||||
for (auto pair : _fileList)
|
|
||||||
{
|
|
||||||
pair.second->resume();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto pair : _resList)
|
for (auto pair : _resList)
|
||||||
{
|
{
|
||||||
pair.second->resume();
|
pair.second->resume();
|
||||||
|
|
@ -248,11 +194,6 @@ void e2d::Player::resumeAll()
|
||||||
|
|
||||||
void e2d::Player::stopAll()
|
void e2d::Player::stopAll()
|
||||||
{
|
{
|
||||||
for (auto pair : _fileList)
|
|
||||||
{
|
|
||||||
pair.second->stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto pair : _resList)
|
for (auto pair : _resList)
|
||||||
{
|
{
|
||||||
pair.second->stop();
|
pair.second->stop();
|
||||||
|
|
@ -261,12 +202,6 @@ void e2d::Player::stopAll()
|
||||||
|
|
||||||
void e2d::Player::clearCache()
|
void e2d::Player::clearCache()
|
||||||
{
|
{
|
||||||
for (auto pair : _fileList)
|
|
||||||
{
|
|
||||||
GC::release(pair.second);
|
|
||||||
}
|
|
||||||
_fileList.clear();
|
|
||||||
|
|
||||||
for (auto pair : _resList)
|
for (auto pair : _resList)
|
||||||
{
|
{
|
||||||
GC::release(pair.second);
|
GC::release(pair.second);
|
||||||
|
|
|
||||||
|
|
@ -521,6 +521,44 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 资源
|
||||||
|
class Resource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Resource(
|
||||||
|
const String& fileName /* 文件路径 */
|
||||||
|
);
|
||||||
|
|
||||||
|
Resource(
|
||||||
|
int resNameId, /* 资源名称 */
|
||||||
|
const String& resType /* 资源类型 */
|
||||||
|
);
|
||||||
|
|
||||||
|
// 是否是资源类型
|
||||||
|
bool isResource() const;
|
||||||
|
|
||||||
|
const String& getFileName() const;
|
||||||
|
|
||||||
|
int getResNameId() const;
|
||||||
|
|
||||||
|
const String& getResType() const;
|
||||||
|
|
||||||
|
int getKey() const;
|
||||||
|
|
||||||
|
// 比较运算符
|
||||||
|
bool operator> (const Resource &) const;
|
||||||
|
bool operator>= (const Resource &) const;
|
||||||
|
bool operator< (const Resource &) const;
|
||||||
|
bool operator<= (const Resource &) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool _isResource;
|
||||||
|
String _fileName;
|
||||||
|
int _resNameId;
|
||||||
|
String _resType;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// 引用计数对象
|
// 引用计数对象
|
||||||
class Ref
|
class Ref
|
||||||
{
|
{
|
||||||
|
|
@ -554,36 +592,33 @@ public:
|
||||||
Image();
|
Image();
|
||||||
|
|
||||||
explicit Image(
|
explicit Image(
|
||||||
const String& filePath /* 图片文件路径 */
|
const Resource& res
|
||||||
);
|
);
|
||||||
|
|
||||||
explicit Image(
|
explicit Image(
|
||||||
int resNameId, /* 图片资源名称 */
|
const Resource& res,
|
||||||
const String& resType /* 图片资源类型 */
|
|
||||||
);
|
|
||||||
|
|
||||||
explicit Image(
|
|
||||||
const String& filePath, /* 图片文件路径 */
|
|
||||||
const Rect& cropRect /* 裁剪矩形 */
|
const Rect& cropRect /* 裁剪矩形 */
|
||||||
);
|
);
|
||||||
|
|
||||||
explicit Image(
|
explicit Image(
|
||||||
int resNameId, /* 图片资源名称 */
|
const String& fileName
|
||||||
const String& resType, /* 图片资源类型 */
|
);
|
||||||
|
|
||||||
|
explicit Image(
|
||||||
|
const String& fileName,
|
||||||
const Rect& cropRect /* 裁剪矩形 */
|
const Rect& cropRect /* 裁剪矩形 */
|
||||||
);
|
);
|
||||||
|
|
||||||
virtual ~Image();
|
virtual ~Image();
|
||||||
|
|
||||||
// 加载图片文件
|
// 加载图片资源
|
||||||
bool open(
|
bool open(
|
||||||
const String& filePath /* 图片文件路径 */
|
const Resource& res
|
||||||
);
|
);
|
||||||
|
|
||||||
// 加载图片资源
|
// 加载图片资源
|
||||||
bool open(
|
bool open(
|
||||||
int resNameId, /* 图片资源名称 */
|
const String& fileName
|
||||||
const String& resType /* 图片资源类型 */
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// 将图片裁剪为矩形
|
// 将图片裁剪为矩形
|
||||||
|
|
@ -621,15 +656,9 @@ public:
|
||||||
// 获取 ID2D1Bitmap 对象
|
// 获取 ID2D1Bitmap 对象
|
||||||
ID2D1Bitmap * getBitmap();
|
ID2D1Bitmap * getBitmap();
|
||||||
|
|
||||||
// 预加载图片文件
|
|
||||||
static bool preload(
|
|
||||||
const String& filePath /* 图片文件路径 */
|
|
||||||
);
|
|
||||||
|
|
||||||
// 预加载图片资源
|
// 预加载图片资源
|
||||||
static bool preload(
|
static bool preload(
|
||||||
int resNameId, /* 图片资源名称 */
|
const Resource& res
|
||||||
const String& resType /* 图片资源类型 */
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// 清空缓存
|
// 清空缓存
|
||||||
|
|
|
||||||
|
|
@ -452,22 +452,20 @@ public:
|
||||||
);
|
);
|
||||||
|
|
||||||
explicit Sprite(
|
explicit Sprite(
|
||||||
const String& filePath /* 图片文件路径 */
|
const Resource& res
|
||||||
);
|
);
|
||||||
|
|
||||||
explicit Sprite(
|
explicit Sprite(
|
||||||
int resNameId, /* 图片资源名称 */
|
const Resource& res,
|
||||||
const String& resType /* 图片资源类型 */
|
|
||||||
);
|
|
||||||
|
|
||||||
explicit Sprite(
|
|
||||||
const String& filePath, /* 图片文件路径 */
|
|
||||||
const Rect& cropRect /* 裁剪矩形 */
|
const Rect& cropRect /* 裁剪矩形 */
|
||||||
);
|
);
|
||||||
|
|
||||||
explicit Sprite(
|
explicit Sprite(
|
||||||
int resNameId, /* 图片资源名称 */
|
const String& fileName
|
||||||
const String& resType, /* 图片资源类型 */
|
);
|
||||||
|
|
||||||
|
explicit Sprite(
|
||||||
|
const String& fileName,
|
||||||
const Rect& cropRect /* 裁剪矩形 */
|
const Rect& cropRect /* 裁剪矩形 */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -475,13 +473,12 @@ public:
|
||||||
|
|
||||||
// 加载图片文件
|
// 加载图片文件
|
||||||
bool open(
|
bool open(
|
||||||
const String& filePath
|
const Resource& res
|
||||||
);
|
);
|
||||||
|
|
||||||
// 加载图片资源
|
// 加载图片文件
|
||||||
bool open(
|
bool open(
|
||||||
int resNameId, /* 图片资源名称 */
|
const String& fileName
|
||||||
const String& resType /* 图片资源类型 */
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// 加载图片
|
// 加载图片
|
||||||
|
|
|
||||||
123
core/e2dtool.h
123
core/e2dtool.h
|
|
@ -62,8 +62,7 @@ public:
|
||||||
);
|
);
|
||||||
|
|
||||||
explicit Music(
|
explicit Music(
|
||||||
int resNameId, /* 音乐资源名称 */
|
const Resource& res
|
||||||
const String& resType /* 音乐资源类型 */
|
|
||||||
);
|
);
|
||||||
|
|
||||||
virtual ~Music();
|
virtual ~Music();
|
||||||
|
|
@ -75,8 +74,7 @@ public:
|
||||||
|
|
||||||
// 打开音乐资源
|
// 打开音乐资源
|
||||||
bool open(
|
bool open(
|
||||||
int resNameId, /* 音乐资源名称 */
|
const Resource& res
|
||||||
const String& resType /* 音乐资源类型 */
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// 播放
|
// 播放
|
||||||
|
|
@ -152,7 +150,7 @@ protected:
|
||||||
class Player
|
class Player
|
||||||
{
|
{
|
||||||
friend class Game;
|
friend class Game;
|
||||||
typedef std::map<UINT, Music*> MusicMap;
|
typedef std::map<Resource, Music*> MusicMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// 获取播放器实例
|
// 获取播放器实例
|
||||||
|
|
@ -194,39 +192,33 @@ public:
|
||||||
|
|
||||||
// 预加载音乐资源
|
// 预加载音乐资源
|
||||||
bool preload(
|
bool preload(
|
||||||
int resNameId, /* 音乐资源名称 */
|
const Resource& res /* 音乐资源 */
|
||||||
const String& resType /* 音乐资源类型 */
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// 播放音乐
|
// 播放音乐
|
||||||
bool play(
|
bool play(
|
||||||
int resNameId, /* 音乐资源名称 */
|
const Resource& res, /* 音乐资源 */
|
||||||
const String& resType, /* 音乐资源类型 */
|
|
||||||
int nLoopCount = 0 /* 重复播放次数,设置 -1 为循环播放 */
|
int nLoopCount = 0 /* 重复播放次数,设置 -1 为循环播放 */
|
||||||
);
|
);
|
||||||
|
|
||||||
// 暂停音乐
|
// 暂停音乐
|
||||||
void pause(
|
void pause(
|
||||||
int resNameId, /* 音乐资源名称 */
|
const Resource& res /* 音乐资源 */
|
||||||
const String& resType /* 音乐资源类型 */
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// 继续播放音乐
|
// 继续播放音乐
|
||||||
void resume(
|
void resume(
|
||||||
int resNameId, /* 音乐资源名称 */
|
const Resource& res /* 音乐资源 */
|
||||||
const String& resType /* 音乐资源类型 */
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// 停止音乐
|
// 停止音乐
|
||||||
void stop(
|
void stop(
|
||||||
int resNameId, /* 音乐资源名称 */
|
const Resource& res /* 音乐资源 */
|
||||||
const String& resType /* 音乐资源类型 */
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// 获取音乐播放状态
|
// 获取音乐播放状态
|
||||||
bool isPlaying(
|
bool isPlaying(
|
||||||
int resNameId, /* 音乐资源名称 */
|
const Resource& res /* 音乐资源 */
|
||||||
const String& resType /* 音乐资源类型 */
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// 获取音量
|
// 获取音量
|
||||||
|
|
@ -261,7 +253,6 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float _volume;
|
float _volume;
|
||||||
MusicMap _fileList;
|
|
||||||
MusicMap _resList;
|
MusicMap _resList;
|
||||||
IXAudio2* _xAudio2;
|
IXAudio2* _xAudio2;
|
||||||
IXAudio2MasteringVoice* _masteringVoice;
|
IXAudio2MasteringVoice* _masteringVoice;
|
||||||
|
|
@ -504,29 +495,75 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 路径工具
|
// 文件
|
||||||
class Path
|
class File
|
||||||
{
|
{
|
||||||
friend class Game;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// 添加资源搜索路径
|
File();
|
||||||
static void addSearchPath(
|
|
||||||
String path
|
File(
|
||||||
|
const String& fileName
|
||||||
);
|
);
|
||||||
|
|
||||||
// 检索文件路径
|
virtual ~File();
|
||||||
static String findFile(
|
|
||||||
const String& path
|
// 打开文件
|
||||||
|
bool open(
|
||||||
|
const String& fileName
|
||||||
);
|
);
|
||||||
|
|
||||||
// 提取资源文件,返回提取后的文件路径
|
// 文件或文件夹是否存在
|
||||||
static String extractResource(
|
bool exists() const;
|
||||||
|
|
||||||
|
// 是否是文件夹
|
||||||
|
bool isFolder() const;
|
||||||
|
|
||||||
|
// 删除文件
|
||||||
|
bool deleteFile();
|
||||||
|
|
||||||
|
// 获取文件路径
|
||||||
|
String getFilePath() const;
|
||||||
|
|
||||||
|
// 获取文件扩展名
|
||||||
|
String getExtension() const;
|
||||||
|
|
||||||
|
// 释放资源到临时文件目录
|
||||||
|
static File extract(
|
||||||
int resNameId, /* 资源名称 */
|
int resNameId, /* 资源名称 */
|
||||||
const String& resType, /* 资源类型 */
|
const String& resType, /* 资源类型 */
|
||||||
const String& destFileName /* 目标文件名 */
|
const String& destFileName /* 目标文件名 */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 添加文件搜索路径
|
||||||
|
static void addSearchPath(
|
||||||
|
const String& path
|
||||||
|
);
|
||||||
|
|
||||||
|
// 创建文件夹
|
||||||
|
static bool createFolder(
|
||||||
|
const String& dirPath /* 文件夹路径 */
|
||||||
|
);
|
||||||
|
|
||||||
|
// 打开保存文件对话框
|
||||||
|
static String getSaveFilePath(
|
||||||
|
const String& title = L"保存到", /* 对话框标题 */
|
||||||
|
const String& defExt = L"" /* 默认扩展名 */
|
||||||
|
);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DWORD _attributes;
|
||||||
|
String _fileName;
|
||||||
|
|
||||||
|
static std::list<String> _searchPaths;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 路径
|
||||||
|
class Path
|
||||||
|
{
|
||||||
|
friend class Game;
|
||||||
|
|
||||||
|
public:
|
||||||
// 获取数据的默认保存路径
|
// 获取数据的默认保存路径
|
||||||
static String getDataPath();
|
static String getDataPath();
|
||||||
|
|
||||||
|
|
@ -538,32 +575,6 @@ public:
|
||||||
|
|
||||||
// 获取当前程序的运行路径
|
// 获取当前程序的运行路径
|
||||||
static String getCurrentFilePath();
|
static String getCurrentFilePath();
|
||||||
|
|
||||||
// 获取文件扩展名
|
|
||||||
static String getFileExtension(
|
|
||||||
const String& filePath
|
|
||||||
);
|
|
||||||
|
|
||||||
// 打开保存文件对话框
|
|
||||||
static String getSaveFilePath(
|
|
||||||
const String& title = L"保存到", /* 对话框标题 */
|
|
||||||
const String& defExt = L"" /* 默认扩展名 */
|
|
||||||
);
|
|
||||||
|
|
||||||
// 创建文件夹
|
|
||||||
static bool createFolder(
|
|
||||||
const String& dirPath /* 文件夹路径 */
|
|
||||||
);
|
|
||||||
|
|
||||||
// 判断文件或文件夹是否存在
|
|
||||||
static bool exists(
|
|
||||||
const String& dirPath /* 文件夹路径 */
|
|
||||||
);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static String _tempPath;
|
|
||||||
static String _dataPath;
|
|
||||||
static std::list<String> _paths;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -230,6 +230,7 @@
|
||||||
<ClCompile Include="..\..\core\Common\Point.cpp" />
|
<ClCompile Include="..\..\core\Common\Point.cpp" />
|
||||||
<ClCompile Include="..\..\core\Common\Rect.cpp" />
|
<ClCompile Include="..\..\core\Common\Rect.cpp" />
|
||||||
<ClCompile Include="..\..\core\Common\Ref.cpp" />
|
<ClCompile Include="..\..\core\Common\Ref.cpp" />
|
||||||
|
<ClCompile Include="..\..\core\Common\Resource.cpp" />
|
||||||
<ClCompile Include="..\..\core\Common\Scene.cpp" />
|
<ClCompile Include="..\..\core\Common\Scene.cpp" />
|
||||||
<ClCompile Include="..\..\core\Common\Size.cpp" />
|
<ClCompile Include="..\..\core\Common\Size.cpp" />
|
||||||
<ClCompile Include="..\..\core\Common\String.cpp" />
|
<ClCompile Include="..\..\core\Common\String.cpp" />
|
||||||
|
|
@ -253,6 +254,7 @@
|
||||||
<ClCompile Include="..\..\core\Node\Sprite.cpp" />
|
<ClCompile Include="..\..\core\Node\Sprite.cpp" />
|
||||||
<ClCompile Include="..\..\core\Node\Text.cpp" />
|
<ClCompile Include="..\..\core\Node\Text.cpp" />
|
||||||
<ClCompile Include="..\..\core\Tool\Data.cpp" />
|
<ClCompile Include="..\..\core\Tool\Data.cpp" />
|
||||||
|
<ClCompile Include="..\..\core\Tool\File.cpp" />
|
||||||
<ClCompile Include="..\..\core\Tool\Listener.cpp" />
|
<ClCompile Include="..\..\core\Tool\Listener.cpp" />
|
||||||
<ClCompile Include="..\..\core\Tool\Music.cpp" />
|
<ClCompile Include="..\..\core\Tool\Music.cpp" />
|
||||||
<ClCompile Include="..\..\core\Tool\Path.cpp" />
|
<ClCompile Include="..\..\core\Tool\Path.cpp" />
|
||||||
|
|
|
||||||
|
|
@ -240,6 +240,12 @@
|
||||||
<ClCompile Include="..\..\core\Common\Ref.cpp">
|
<ClCompile Include="..\..\core\Common\Ref.cpp">
|
||||||
<Filter>Common</Filter>
|
<Filter>Common</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\core\Tool\File.cpp">
|
||||||
|
<Filter>Tool</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\core\Common\Resource.cpp">
|
||||||
|
<Filter>Common</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\core\easy2d.h" />
|
<ClInclude Include="..\..\core\easy2d.h" />
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue