增加音乐播放结束时执行回调函数的功能

This commit is contained in:
Nomango 2018-05-22 11:58:45 +08:00
parent afb8780a31
commit 7a99c03431
12 changed files with 178 additions and 33 deletions

View File

@ -197,6 +197,9 @@ void e2d::Game::quit()
void e2d::Game::destroy() void e2d::Game::destroy()
{ {
if (!s_bInitialized)
return;
// 删除所有场景 // 删除所有场景
SceneManager::__uninit(); SceneManager::__uninit();
// 删除输入监听器 // 删除输入监听器

View File

@ -11,7 +11,7 @@ static ID2D1HwndRenderTarget * s_pRenderTarget = nullptr;
static ID2D1SolidColorBrush * s_pSolidBrush = nullptr; static ID2D1SolidColorBrush * s_pSolidBrush = nullptr;
static IWICImagingFactory * s_pIWICFactory = nullptr; static IWICImagingFactory * s_pIWICFactory = nullptr;
static IDWriteFactory * s_pDWriteFactory = nullptr; static IDWriteFactory * s_pDWriteFactory = nullptr;
static e2d::CustomTextRenderer * s_pTextRenderer = nullptr; static e2d::TextRenderer * s_pTextRenderer = nullptr;
static D2D1_COLOR_F s_nClearColor = D2D1::ColorF(D2D1::ColorF::Black); static D2D1_COLOR_F s_nClearColor = D2D1::ColorF(D2D1::ColorF::Black);
@ -120,7 +120,7 @@ bool e2d::Renderer::__createDeviceResources()
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
// 创建自定义的文字渲染器 // 创建自定义的文字渲染器
s_pTextRenderer = new (std::nothrow) CustomTextRenderer( s_pTextRenderer = new (std::nothrow) TextRenderer(
s_pDirect2dFactory, s_pDirect2dFactory,
s_pRenderTarget, s_pRenderTarget,
s_pSolidBrush s_pSolidBrush
@ -279,7 +279,7 @@ IDWriteFactory * e2d::Renderer::getIDWriteFactory()
return s_pDWriteFactory; return s_pDWriteFactory;
} }
e2d::CustomTextRenderer * e2d::Renderer::getCustomTextRenderer() e2d::TextRenderer * e2d::Renderer::getTextRenderer()
{ {
return s_pTextRenderer; return s_pTextRenderer;
} }

View File

@ -3,7 +3,7 @@
using namespace e2d; using namespace e2d;
CustomTextRenderer::CustomTextRenderer( TextRenderer::TextRenderer(
ID2D1Factory* pD2DFactory, ID2D1Factory* pD2DFactory,
ID2D1HwndRenderTarget* pRT, ID2D1HwndRenderTarget* pRT,
ID2D1SolidColorBrush* pBrush ID2D1SolidColorBrush* pBrush
@ -23,14 +23,14 @@ CustomTextRenderer::CustomTextRenderer(
pBrush_->AddRef(); pBrush_->AddRef();
} }
CustomTextRenderer::~CustomTextRenderer() TextRenderer::~TextRenderer()
{ {
SafeReleaseInterface(pD2DFactory_); SafeReleaseInterface(pD2DFactory_);
SafeReleaseInterface(pRT_); SafeReleaseInterface(pRT_);
SafeReleaseInterface(pBrush_); SafeReleaseInterface(pBrush_);
} }
STDMETHODIMP_(void) CustomTextRenderer::SetTextStyle( STDMETHODIMP_(void) TextRenderer::SetTextStyle(
CONST D2D1_COLOR_F &fillColor, CONST D2D1_COLOR_F &fillColor,
BOOL hasOutline, BOOL hasOutline,
CONST D2D1_COLOR_F &outlineColor, CONST D2D1_COLOR_F &outlineColor,
@ -45,7 +45,7 @@ STDMETHODIMP_(void) CustomTextRenderer::SetTextStyle(
nOutlineJoin_ = outlineJoin; nOutlineJoin_ = outlineJoin;
} }
STDMETHODIMP CustomTextRenderer::DrawGlyphRun( STDMETHODIMP TextRenderer::DrawGlyphRun(
__maybenull void* clientDrawingContext, __maybenull void* clientDrawingContext,
FLOAT baselineOriginX, FLOAT baselineOriginX,
FLOAT baselineOriginY, FLOAT baselineOriginY,
@ -152,7 +152,7 @@ STDMETHODIMP CustomTextRenderer::DrawGlyphRun(
return hr; return hr;
} }
STDMETHODIMP CustomTextRenderer::DrawUnderline( STDMETHODIMP TextRenderer::DrawUnderline(
__maybenull void* clientDrawingContext, __maybenull void* clientDrawingContext,
FLOAT baselineOriginX, FLOAT baselineOriginX,
FLOAT baselineOriginY, FLOAT baselineOriginY,
@ -237,7 +237,7 @@ STDMETHODIMP CustomTextRenderer::DrawUnderline(
return S_OK; return S_OK;
} }
STDMETHODIMP CustomTextRenderer::DrawStrikethrough( STDMETHODIMP TextRenderer::DrawStrikethrough(
__maybenull void* clientDrawingContext, __maybenull void* clientDrawingContext,
FLOAT baselineOriginX, FLOAT baselineOriginX,
FLOAT baselineOriginY, FLOAT baselineOriginY,
@ -322,7 +322,7 @@ STDMETHODIMP CustomTextRenderer::DrawStrikethrough(
return S_OK; return S_OK;
} }
STDMETHODIMP CustomTextRenderer::DrawInlineObject( STDMETHODIMP TextRenderer::DrawInlineObject(
__maybenull void* clientDrawingContext, __maybenull void* clientDrawingContext,
FLOAT originX, FLOAT originX,
FLOAT originY, FLOAT originY,
@ -335,12 +335,12 @@ STDMETHODIMP CustomTextRenderer::DrawInlineObject(
return E_NOTIMPL; return E_NOTIMPL;
} }
STDMETHODIMP_(unsigned long) CustomTextRenderer::AddRef() STDMETHODIMP_(unsigned long) TextRenderer::AddRef()
{ {
return InterlockedIncrement(&cRefCount_); return InterlockedIncrement(&cRefCount_);
} }
STDMETHODIMP_(unsigned long) CustomTextRenderer::Release() STDMETHODIMP_(unsigned long) TextRenderer::Release()
{ {
unsigned long newCount = InterlockedDecrement(&cRefCount_); unsigned long newCount = InterlockedDecrement(&cRefCount_);
@ -353,7 +353,7 @@ STDMETHODIMP_(unsigned long) CustomTextRenderer::Release()
return newCount; return newCount;
} }
STDMETHODIMP CustomTextRenderer::IsPixelSnappingDisabled( STDMETHODIMP TextRenderer::IsPixelSnappingDisabled(
__maybenull void* clientDrawingContext, __maybenull void* clientDrawingContext,
__out BOOL* isDisabled __out BOOL* isDisabled
) )
@ -362,7 +362,7 @@ STDMETHODIMP CustomTextRenderer::IsPixelSnappingDisabled(
return S_OK; return S_OK;
} }
STDMETHODIMP CustomTextRenderer::GetCurrentTransform( STDMETHODIMP TextRenderer::GetCurrentTransform(
__maybenull void* clientDrawingContext, __maybenull void* clientDrawingContext,
__out DWRITE_MATRIX* transform __out DWRITE_MATRIX* transform
) )
@ -371,7 +371,7 @@ STDMETHODIMP CustomTextRenderer::GetCurrentTransform(
return S_OK; return S_OK;
} }
STDMETHODIMP CustomTextRenderer::GetPixelsPerDip( STDMETHODIMP TextRenderer::GetPixelsPerDip(
__maybenull void* clientDrawingContext, __maybenull void* clientDrawingContext,
__out FLOAT* pixelsPerDip __out FLOAT* pixelsPerDip
) )
@ -384,7 +384,7 @@ STDMETHODIMP CustomTextRenderer::GetPixelsPerDip(
return S_OK; return S_OK;
} }
STDMETHODIMP CustomTextRenderer::QueryInterface( STDMETHODIMP TextRenderer::QueryInterface(
IID const& riid, IID const& riid,
void** ppvObject void** ppvObject
) )

View File

@ -0,0 +1,64 @@
#include "..\e2dcustom.h"
#include "..\e2dbase.h"
#include "..\e2dtool.h"
e2d::VoiceCallback::VoiceCallback(Music * music)
: _music(music)
{
}
e2d::VoiceCallback::~VoiceCallback()
{
}
void e2d::VoiceCallback::OnLoopEnd(void * pBufferContext)
{
if (_loopEndFunc)
{
_loopEndFunc();
}
}
void e2d::VoiceCallback::OnStreamEnd()
{
if (_streamEndFunc)
{
_streamEndFunc();
}
}
void e2d::VoiceCallback::OnBufferEnd(void * pBufferContext)
{
if (_loopEndFunc)
{
_loopEndFunc();
}
e2d::GC::release(_music);
}
void e2d::VoiceCallback::OnBufferStart(void * pBufferContext)
{
e2d::GC::retain(_music);
}
void e2d::VoiceCallback::OnVoiceProcessingPassEnd()
{
}
void e2d::VoiceCallback::OnVoiceProcessingPassStart(UINT32 SamplesRequired)
{
}
void e2d::VoiceCallback::OnVoiceError(void * pBufferContext, HRESULT Error)
{
}
void e2d::VoiceCallback::SetFuncOnStreamEnd(const Function & func)
{
_streamEndFunc = func;
}
void e2d::VoiceCallback::SetFuncOnLoopEnd(const Function & func)
{
_loopEndFunc = func;
}

View File

@ -318,7 +318,7 @@ void e2d::Text::onRender()
// 设置画刷颜色和透明度 // 设置画刷颜色和透明度
Renderer::getSolidColorBrush()->SetOpacity(_displayOpacity); Renderer::getSolidColorBrush()->SetOpacity(_displayOpacity);
// 获取文本渲染器 // 获取文本渲染器
auto pTextRenderer = Renderer::getCustomTextRenderer(); auto pTextRenderer = Renderer::getTextRenderer();
pTextRenderer->SetTextStyle( pTextRenderer->SetTextStyle(
_style.color.toD2DColorF(), _style.color.toD2DColorF(),
_style.hasOutline, _style.hasOutline,

View File

@ -34,6 +34,7 @@ e2d::Music::Music()
, _waveData(nullptr) , _waveData(nullptr)
, _dwSize(0) , _dwSize(0)
, _voice(nullptr) , _voice(nullptr)
, _voiceCallback(this)
{ {
} }
@ -46,6 +47,7 @@ e2d::Music::Music(const e2d::String & filePath)
, _waveData(nullptr) , _waveData(nullptr)
, _dwSize(0) , _dwSize(0)
, _voice(nullptr) , _voice(nullptr)
, _voiceCallback(this)
{ {
this->open(filePath); this->open(filePath);
} }
@ -59,6 +61,7 @@ e2d::Music::Music(int resNameId, const String & resType)
, _waveData(nullptr) , _waveData(nullptr)
, _dwSize(0) , _dwSize(0)
, _voice(nullptr) , _voice(nullptr)
, _voiceCallback(this)
{ {
this->open(resNameId, resType); this->open(resNameId, resType);
} }
@ -128,7 +131,7 @@ bool e2d::Music::open(const e2d::String& filePath)
// ´´½¨ÒôÔ´ // ´´½¨ÒôÔ´
HRESULT hr; HRESULT hr;
if (FAILED(hr = s_pXAudio2->CreateSourceVoice(&_voice, _wfx))) if (FAILED(hr = s_pXAudio2->CreateSourceVoice(&_voice, _wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO, &this->_voiceCallback)))
{ {
TraceError(L"Create source voice error", hr); TraceError(L"Create source voice error", hr);
SAFE_DELETE_ARRAY(_waveData); SAFE_DELETE_ARRAY(_waveData);
@ -207,7 +210,7 @@ bool e2d::Music::open(int resNameId, const e2d::String& resType)
// ´´½¨ÒôÔ´ // ´´½¨ÒôÔ´
HRESULT hr; HRESULT hr;
if (FAILED(hr = s_pXAudio2->CreateSourceVoice(&_voice, _wfx))) if (FAILED(hr = s_pXAudio2->CreateSourceVoice(&_voice, _wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO, &this->_voiceCallback)))
{ {
TraceError(L"Create source voice error", hr); TraceError(L"Create source voice error", hr);
SAFE_DELETE_ARRAY(_waveData); SAFE_DELETE_ARRAY(_waveData);
@ -358,6 +361,16 @@ bool e2d::Music::setVolume(double volume)
return false; return false;
} }
void e2d::Music::setFuncOnEnd(const Function & func)
{
_voiceCallback.SetFuncOnStreamEnd(func);
}
void e2d::Music::setFuncOnLoopEnd(const Function & func)
{
_voiceCallback.SetFuncOnLoopEnd(func);
}
bool e2d::Music::_readMMIO() bool e2d::Music::_readMMIO()
{ {
MMCKINFO ckIn; MMCKINFO ckIn;

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "e2dmacros.h" #include "e2dmacros.h"
#include "e2dcommon.h" #include "e2dcommon.h"
#include "e2dcustom.h"
// Base Classes // Base Classes
@ -400,8 +401,8 @@ public:
// 获取 IDWriteFactory 对象 // 获取 IDWriteFactory 对象
static IDWriteFactory * getIDWriteFactory(); static IDWriteFactory * getIDWriteFactory();
// 获取自定义的文字渲染器 // 获取文字渲染器
static CustomTextRenderer * getCustomTextRenderer(); static TextRenderer * getTextRenderer();
private: private:
// 渲染游戏画面 // 渲染游戏画面

View File

@ -1,12 +1,10 @@
#pragma once #pragma once
#include "e2dmacros.h" #include "e2dmacros.h"
#include "e2dcustom.h"
namespace e2d namespace e2d
{ {
// 方向 // 方向
enum class Direction : int enum class Direction : int
{ {

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "e2dmacros.h" #include "e2dmacros.h"
#include "e2dcommon.h"
namespace e2d namespace e2d
{ {
@ -13,18 +14,68 @@ namespace e2d
} }
} }
// 自定义的文字渲染器 class Music;
class CustomTextRenderer
// ÒôÔ´»Øµ÷
class VoiceCallback
: public IXAudio2VoiceCallback
{
public:
VoiceCallback(Music * music);
~VoiceCallback();
void __stdcall OnStreamEnd();
void __stdcall OnBufferEnd(
void * pBufferContext
);
void __stdcall OnBufferStart(
void * pBufferContext
);
void __stdcall OnLoopEnd(
void * pBufferContext
);
void __stdcall OnVoiceProcessingPassEnd();
void __stdcall OnVoiceProcessingPassStart(
UINT32 SamplesRequired
);
void __stdcall OnVoiceError(
void * pBufferContext,
HRESULT Error
);
void SetFuncOnStreamEnd(
const Function& func
);
void SetFuncOnLoopEnd(
const Function& func
);
protected:
Music * _music;
Function _loopEndFunc;
Function _streamEndFunc;
};
// ÎÄ×ÖäÖȾÆ÷
class TextRenderer
: public IDWriteTextRenderer : public IDWriteTextRenderer
{ {
public: public:
CustomTextRenderer( TextRenderer(
ID2D1Factory* pD2DFactory, ID2D1Factory* pD2DFactory,
ID2D1HwndRenderTarget* pRT, ID2D1HwndRenderTarget* pRT,
ID2D1SolidColorBrush* pBrush ID2D1SolidColorBrush* pBrush
); );
~CustomTextRenderer(); ~TextRenderer();
STDMETHOD_(void, SetTextStyle)( STDMETHOD_(void, SetTextStyle)(
CONST D2D1_COLOR_F &fillColor, CONST D2D1_COLOR_F &fillColor,

View File

@ -96,13 +96,23 @@ public:
// 关闭并回收资源 // 关闭并回收资源
void close(); void close();
// 是否正在播放
bool isPlaying() const;
// 设置音量 // 设置音量
bool setVolume( bool setVolume(
double volume double volume
); );
// 是否正在播放 // 设置播放结束时的执行函数
bool isPlaying() const; void setFuncOnEnd(
const Function& func
);
// 设置循环播放中每一次播放结束时的执行函数
void setFuncOnLoopEnd(
const Function& func
);
// 获取 IXAudio2SourceVoice 对象 // 获取 IXAudio2SourceVoice 对象
IXAudio2SourceVoice * getIXAudio2SourceVoice() const; IXAudio2SourceVoice * getIXAudio2SourceVoice() const;
@ -144,6 +154,7 @@ protected:
MMCKINFO _ck; MMCKINFO _ck;
MMCKINFO _ckRiff; MMCKINFO _ckRiff;
WAVEFORMATEX* _wfx; WAVEFORMATEX* _wfx;
VoiceCallback _voiceCallback;
IXAudio2SourceVoice* _voice; IXAudio2SourceVoice* _voice;
}; };

View File

@ -235,7 +235,8 @@
<ClCompile Include="..\..\core\Common\Size.cpp" /> <ClCompile Include="..\..\core\Common\Size.cpp" />
<ClCompile Include="..\..\core\Common\String.cpp" /> <ClCompile Include="..\..\core\Common\String.cpp" />
<ClCompile Include="..\..\core\Common\Image.cpp" /> <ClCompile Include="..\..\core\Common\Image.cpp" />
<ClCompile Include="..\..\core\Custom\CustomTextRenderer.cpp" /> <ClCompile Include="..\..\core\Custom\TextRenderer.cpp" />
<ClCompile Include="..\..\core\Custom\VoiceCallback.cpp" />
<ClCompile Include="..\..\core\Manager\ActionManager.cpp" /> <ClCompile Include="..\..\core\Manager\ActionManager.cpp" />
<ClCompile Include="..\..\core\Manager\ColliderManager.cpp" /> <ClCompile Include="..\..\core\Manager\ColliderManager.cpp" />
<ClCompile Include="..\..\core\Manager\SceneManager.cpp" /> <ClCompile Include="..\..\core\Manager\SceneManager.cpp" />

View File

@ -144,9 +144,6 @@
<ClCompile Include="..\..\core\Node\Shape\Ellipse.cpp"> <ClCompile Include="..\..\core\Node\Shape\Ellipse.cpp">
<Filter>Node\Shape</Filter> <Filter>Node\Shape</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\core\Custom\CustomTextRenderer.cpp">
<Filter>Custom</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Common\Color.cpp"> <ClCompile Include="..\..\core\Common\Color.cpp">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClCompile> </ClCompile>
@ -225,6 +222,12 @@
<ClCompile Include="..\..\core\Common\Listener.cpp"> <ClCompile Include="..\..\core\Common\Listener.cpp">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\core\Custom\VoiceCallback.cpp">
<Filter>Custom</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Custom\TextRenderer.cpp">
<Filter>Custom</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\core\easy2d.h" /> <ClInclude Include="..\..\core\easy2d.h" />