add: decode media resources with Media Foundation and playback with XAudio2.
This commit is contained in:
parent
80d1a87955
commit
a924eed280
|
|
@ -57,12 +57,11 @@
|
|||
#include <d2d1.h>
|
||||
#include <dwrite.h>
|
||||
#include <dinput.h>
|
||||
#include <shlwapi.h>
|
||||
#include <xaudio2.h>
|
||||
#include <mfapi.h>
|
||||
#include <mfidl.h>
|
||||
#include <mferror.h>
|
||||
#include <evr.h>
|
||||
#include <mmdeviceapi.h>
|
||||
#include <mfreadwrite.h>
|
||||
#include <shlwapi.h>
|
||||
|
||||
// C++ RunTime Header Files
|
||||
#include <map>
|
||||
|
|
@ -83,11 +82,10 @@
|
|||
#pragma comment(lib, "windowscodecs.lib")
|
||||
#pragma comment(lib, "winmm.lib")
|
||||
#pragma comment(lib, "dinput8.lib")
|
||||
#pragma comment(lib, "shlwapi")
|
||||
#pragma comment(lib, "mfplay.lib")
|
||||
#pragma comment(lib, "mf.lib")
|
||||
#pragma comment(lib, "xaudio2.lib")
|
||||
#pragma comment(lib, "mfplat.lib")
|
||||
#pragma comment(lib, "mfuuid.lib")
|
||||
#pragma comment(lib, "mfreadwrite.lib")
|
||||
#pragma comment(lib, "shlwapi.lib")
|
||||
|
||||
|
||||
#ifndef HINST_THISCOMPONENT
|
||||
|
|
|
|||
|
|
@ -149,30 +149,21 @@ namespace e2d
|
|||
|
||||
~Audio();
|
||||
|
||||
// 获取音量
|
||||
float GetVolume();
|
||||
// 开启设备
|
||||
void Open();
|
||||
|
||||
// 设置音量
|
||||
void SetVolume(
|
||||
float volume
|
||||
);
|
||||
// 关闭设备
|
||||
void Close();
|
||||
|
||||
// 是否静音
|
||||
bool GetMute();
|
||||
|
||||
// 设置静音
|
||||
void SetMute(
|
||||
bool mute
|
||||
// 创建音源
|
||||
HRESULT CreateVoice(
|
||||
IXAudio2SourceVoice ** voice,
|
||||
WAVEFORMATEX * wfx
|
||||
);
|
||||
|
||||
protected:
|
||||
LPWSTR device_id; // Device ID.
|
||||
IMMDeviceEnumerator *enum_; // Audio device enumerator.
|
||||
IMMDeviceCollection *devices_; // Audio device collection.
|
||||
IMMDevice *device_; // An audio device.
|
||||
IMFAttributes *attributes_; // Attribute store.
|
||||
IMFMediaSink *sink_; // Streaming audio renderer (SAR)
|
||||
IMFSimpleAudioVolume *audio_volume;
|
||||
IXAudio2 * x_audio2_;
|
||||
IXAudio2MasteringVoice* mastering_voice_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
111
core/e2dtool.h
111
core/e2dtool.h
|
|
@ -71,19 +71,10 @@ namespace e2d
|
|||
|
||||
// 音乐
|
||||
class Music
|
||||
: public IMFAsyncCallback
|
||||
{
|
||||
public:
|
||||
Music();
|
||||
|
||||
explicit Music(
|
||||
const e2d::String& file_path /* 音乐文件路径 */
|
||||
);
|
||||
|
||||
explicit Music(
|
||||
const Resource& res /* 音乐资源 */
|
||||
);
|
||||
|
||||
virtual ~Music();
|
||||
|
||||
// 打开音乐文件
|
||||
|
|
@ -104,6 +95,9 @@ namespace e2d
|
|||
// 暂停
|
||||
void Pause();
|
||||
|
||||
// 继续
|
||||
void Resume();
|
||||
|
||||
// 停止
|
||||
void Stop();
|
||||
|
||||
|
|
@ -113,99 +107,26 @@ namespace e2d
|
|||
// 是否正在播放
|
||||
bool IsPlaying() const;
|
||||
|
||||
// 设置音量
|
||||
bool SetVolume(
|
||||
float volume /* 范围: 0.0 ~ 1.0 */
|
||||
);
|
||||
|
||||
// 获取音量
|
||||
float GetVolume() const;
|
||||
|
||||
// IUnknown methods
|
||||
STDMETHODIMP QueryInterface(REFIID iid, void** ppv) override;
|
||||
STDMETHODIMP_(ULONG) AddRef() override;
|
||||
STDMETHODIMP_(ULONG) Release() override;
|
||||
// 设置音量
|
||||
bool SetVolume(
|
||||
float volume /* 1.0 为原始音量 */
|
||||
);
|
||||
|
||||
// IMFAsyncCallback methods
|
||||
STDMETHODIMP GetParameters(DWORD*, DWORD*) override;
|
||||
STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult) override;
|
||||
// 获取 IXAudio2SourceVoice 对象
|
||||
IXAudio2SourceVoice * GetSourceVoice() const;
|
||||
|
||||
protected:
|
||||
enum class State : int
|
||||
{
|
||||
Closed = 0,
|
||||
Loaded,
|
||||
Started,
|
||||
Paused,
|
||||
Stopped,
|
||||
Closing
|
||||
};
|
||||
|
||||
E2D_DISABLE_COPY(Music);
|
||||
|
||||
// Media event handlers
|
||||
HRESULT OnNewPresentation(IMFMediaEvent *pEvent);
|
||||
|
||||
HRESULT StartPlayback();
|
||||
HRESULT CreateMediaSource(PCWSTR sURL, IMFMediaSource **ppSource);
|
||||
HRESULT HandleEvent(UINT_PTR pUnkPtr);
|
||||
|
||||
// Add a source node to a topology.
|
||||
HRESULT AddSourceNode(
|
||||
IMFTopology *pTopology, // Topology.
|
||||
IMFMediaSource *pSource, // Media source.
|
||||
IMFPresentationDescriptor *pPD, // Presentation descriptor.
|
||||
IMFStreamDescriptor *pSD, // Stream descriptor.
|
||||
IMFTopologyNode **ppNode // Receives the node pointer.
|
||||
);
|
||||
|
||||
// Add an output node to a topology.
|
||||
HRESULT AddOutputNode(
|
||||
IMFTopology *pTopology, // Topology.
|
||||
IMFActivate *pActivate, // Media sink activation object.
|
||||
DWORD dwId, // Identifier of the stream sink.
|
||||
IMFTopologyNode **ppNode // Receives the node pointer.
|
||||
);
|
||||
|
||||
HRESULT AddBranchToPartialTopology(
|
||||
IMFTopology *pTopology, // Topology.
|
||||
IMFMediaSource *pSource, // Media source.
|
||||
IMFPresentationDescriptor *pPD, // Presentation descriptor.
|
||||
DWORD iStream // Stream index.
|
||||
);
|
||||
|
||||
// Create a playback topology from a media source.
|
||||
HRESULT CreatePlaybackTopology(
|
||||
IMFMediaSource *pSource, // Media source.
|
||||
IMFPresentationDescriptor *pPD, // Presentation descriptor.
|
||||
IMFTopology **ppTopology // Receives a pointer to the topology.
|
||||
);
|
||||
|
||||
// Create an activation object for a renderer, based on the stream media type.
|
||||
HRESULT CreateMediaSinkActivate(
|
||||
IMFStreamDescriptor *pSourceSD, // Pointer to the stream descriptor.
|
||||
IMFActivate **ppActivate
|
||||
);
|
||||
|
||||
HRESULT GetSimpleAudioVolume(
|
||||
IMFSimpleAudioVolume** ppAudioVolume
|
||||
) const;
|
||||
|
||||
static LRESULT CALLBACK MediaProc(
|
||||
HWND hWnd,
|
||||
UINT Msg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
);
|
||||
|
||||
protected:
|
||||
long m_nRefCount;
|
||||
int m_nTimes;
|
||||
IMFMediaSession * m_pSession;
|
||||
IMFMediaSource *m_pSource;
|
||||
HWND m_hwndEvent;
|
||||
State m_state;
|
||||
HANDLE m_hCloseEvent;
|
||||
bool opened_;
|
||||
bool playing_;
|
||||
UINT32 size_;
|
||||
BYTE* wave_data_;
|
||||
IXAudio2SourceVoice* voice_;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -280,11 +201,11 @@ namespace e2d
|
|||
);
|
||||
|
||||
// 获取音量
|
||||
float GetVolume();
|
||||
float GetVolume() const;
|
||||
|
||||
// 设置音量
|
||||
void SetVolume(
|
||||
float volume /* 范围: 0.0 ~ 1.0 */
|
||||
float volume /* 1.0 为原始音量 */
|
||||
);
|
||||
|
||||
// 暂停所有音乐
|
||||
|
|
|
|||
|
|
@ -1,116 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "..\e2dimpl.h"
|
||||
|
||||
e2d::MediaAsyncCallback::MediaAsyncCallback(HWND hwnd, IMFMediaSession * pSession, HANDLE hCloseEvent)
|
||||
: m_pSession(pSession)
|
||||
, m_hCloseEvent(hCloseEvent)
|
||||
, m_hwnd(hwnd)
|
||||
{
|
||||
}
|
||||
|
||||
HRESULT e2d::MediaAsyncCallback::QueryInterface(REFIID riid, void** ppv)
|
||||
{
|
||||
static const QITAB qit[] =
|
||||
{
|
||||
QITABENT(MediaAsyncCallback, IMFAsyncCallback),
|
||||
{ 0 }
|
||||
};
|
||||
return QISearch(this, qit, riid, ppv);
|
||||
}
|
||||
|
||||
ULONG e2d::MediaAsyncCallback::AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_nRefCount);
|
||||
}
|
||||
|
||||
ULONG e2d::MediaAsyncCallback::Release()
|
||||
{
|
||||
ULONG uCount = InterlockedDecrement(&m_nRefCount);
|
||||
if (uCount == 0)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
return uCount;
|
||||
}
|
||||
|
||||
HRESULT e2d::MediaAsyncCallback::GetParameters(DWORD *, DWORD *)
|
||||
{
|
||||
// Implementation of this method is optional.
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT e2d::MediaAsyncCallback::Invoke(IMFAsyncResult *pResult)
|
||||
{
|
||||
MediaEventType meType = MEUnknown; // Event type
|
||||
|
||||
IMFMediaEvent *pEvent = NULL;
|
||||
|
||||
// Get the event from the event queue.
|
||||
HRESULT hr = m_pSession->EndGetEvent(pResult, &pEvent);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
|
||||
// Get the event type.
|
||||
hr = pEvent->GetType(&meType);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (meType == MESessionClosed)
|
||||
{
|
||||
// The session was closed.
|
||||
// The application is waiting on the m_hCloseEvent event handle.
|
||||
SetEvent(m_hCloseEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
// For all other events, get the next event in the queue.
|
||||
hr = m_pSession->BeginGetEvent(this, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the application state.
|
||||
|
||||
// If a call to IMFMediaSession::Close is pending, it means the
|
||||
// application is waiting on the m_hCloseEvent event and
|
||||
// the application's message loop is blocked.
|
||||
|
||||
// Otherwise, post a private window message to the application.
|
||||
|
||||
//if (m_state != Closing)
|
||||
{
|
||||
// Leave a reference count on the event.
|
||||
pEvent->AddRef();
|
||||
|
||||
::PostMessage(m_hwnd, WM_APP + 1, (WPARAM)pEvent, (LPARAM)meType);
|
||||
}
|
||||
|
||||
done:
|
||||
SafeRelease(pEvent);
|
||||
return S_OK;
|
||||
}
|
||||
|
|
@ -22,128 +22,46 @@
|
|||
|
||||
|
||||
e2d::Audio::Audio()
|
||||
: enum_(nullptr)
|
||||
, devices_(nullptr)
|
||||
, device_(nullptr)
|
||||
, attributes_(nullptr)
|
||||
, sink_(nullptr)
|
||||
, device_id(nullptr)
|
||||
, audio_volume(nullptr)
|
||||
: x_audio2_(nullptr)
|
||||
, mastering_voice_(nullptr)
|
||||
{
|
||||
ThrowIfFailed(
|
||||
MFStartup(MF_VERSION)
|
||||
);
|
||||
|
||||
// Create the device enumerator.
|
||||
ThrowIfFailed(
|
||||
CoCreateInstance(
|
||||
__uuidof(MMDeviceEnumerator),
|
||||
NULL,
|
||||
CLSCTX_ALL,
|
||||
__uuidof(IMMDeviceEnumerator),
|
||||
(void**)&enum_
|
||||
)
|
||||
);
|
||||
|
||||
// Enumerate the rendering devices.
|
||||
ThrowIfFailed(
|
||||
enum_->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &devices_)
|
||||
);
|
||||
|
||||
// Get ID of the first device in the list.
|
||||
ThrowIfFailed(
|
||||
devices_->Item(0, &device_)
|
||||
XAudio2Create(&x_audio2_)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
device_->GetId(&device_id)
|
||||
x_audio2_->CreateMasteringVoice(&mastering_voice_)
|
||||
);
|
||||
|
||||
// Create an attribute store and set the device ID attribute.
|
||||
ThrowIfFailed(
|
||||
MFCreateAttributes(&attributes_, 2)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
attributes_->SetString(
|
||||
MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID,
|
||||
device_id
|
||||
)
|
||||
);
|
||||
|
||||
// Create the audio renderer.
|
||||
ThrowIfFailed(
|
||||
MFCreateAudioRenderer(attributes_, &sink_)
|
||||
);
|
||||
|
||||
IMFGetService* service = NULL;
|
||||
|
||||
ThrowIfFailed(
|
||||
sink_->QueryInterface(IID_IMFGetService, (void **)&service)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
service->GetService(MR_POLICY_VOLUME_SERVICE, IID_PPV_ARGS(&audio_volume))
|
||||
);
|
||||
|
||||
SafeRelease(service);
|
||||
}
|
||||
|
||||
e2d::Audio::~Audio()
|
||||
{
|
||||
SafeRelease(enum_);
|
||||
SafeRelease(devices_);
|
||||
SafeRelease(device_);
|
||||
SafeRelease(attributes_);
|
||||
SafeRelease(audio_volume);
|
||||
SafeRelease(sink_);
|
||||
CoTaskMemFree(device_id);
|
||||
if (mastering_voice_)
|
||||
{
|
||||
mastering_voice_->DestroyVoice();
|
||||
mastering_voice_ = nullptr;
|
||||
}
|
||||
|
||||
SafeRelease(x_audio2_);
|
||||
|
||||
MFShutdown();
|
||||
}
|
||||
|
||||
float e2d::Audio::GetVolume()
|
||||
HRESULT e2d::Audio::CreateVoice(IXAudio2SourceVoice ** voice, WAVEFORMATEX * wfx)
|
||||
{
|
||||
float volume = 0.f;
|
||||
if (audio_volume)
|
||||
{
|
||||
HRESULT hr = audio_volume->GetMasterVolume(&volume);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
return volume;
|
||||
}
|
||||
}
|
||||
return 0.f;
|
||||
return x_audio2_->CreateSourceVoice(voice, wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO);
|
||||
}
|
||||
|
||||
void e2d::Audio::SetVolume(float volume)
|
||||
void e2d::Audio::Open()
|
||||
{
|
||||
if (audio_volume)
|
||||
{
|
||||
volume = std::min(std::max(volume, 0.f), 1.f);
|
||||
HRESULT hr = audio_volume->SetMasterVolume(volume);
|
||||
printf("ºÇºÇ%#X\n", hr);
|
||||
}
|
||||
x_audio2_->StartEngine();
|
||||
}
|
||||
|
||||
bool e2d::Audio::GetMute()
|
||||
void e2d::Audio::Close()
|
||||
{
|
||||
BOOL mute = FALSE;
|
||||
if (audio_volume)
|
||||
{
|
||||
HRESULT hr = audio_volume->GetMute(&mute);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
return mute ? true : false;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void e2d::Audio::SetMute(bool mute)
|
||||
{
|
||||
if (audio_volume)
|
||||
{
|
||||
audio_volume->SetMute(mute ? TRUE : FALSE);
|
||||
}
|
||||
x_audio2_->StopEngine();
|
||||
}
|
||||
|
|
|
|||
1214
core/tools/Music.cpp
1214
core/tools/Music.cpp
File diff suppressed because it is too large
Load Diff
|
|
@ -68,7 +68,7 @@ void e2d::Player::Resume(const String & file_path)
|
|||
|
||||
size_t hash = file_path.GetHash();
|
||||
if (musics_.end() != musics_.find(hash))
|
||||
musics_[hash]->Play();
|
||||
musics_[hash]->Resume();
|
||||
}
|
||||
|
||||
void e2d::Player::Stop(const String & file_path)
|
||||
|
|
@ -137,7 +137,7 @@ void e2d::Player::Pause(const Resource& res)
|
|||
void e2d::Player::Resume(const Resource& res)
|
||||
{
|
||||
if (musics_.end() != musics_.find(res.id))
|
||||
musics_[res.id]->Play();
|
||||
musics_[res.id]->Resume();
|
||||
}
|
||||
|
||||
void e2d::Player::Stop(const Resource& res)
|
||||
|
|
@ -153,14 +153,14 @@ bool e2d::Player::IsPlaying(const Resource& res)
|
|||
return false;
|
||||
}
|
||||
|
||||
float e2d::Player::GetVolume()
|
||||
float e2d::Player::GetVolume() const
|
||||
{
|
||||
return volume_;
|
||||
}
|
||||
|
||||
void e2d::Player::SetVolume(float volume)
|
||||
{
|
||||
volume_ = std::min(std::max(volume, 0.f), 1.f);
|
||||
volume_ = std::min(std::max(volume, -224.f), 224.f);
|
||||
for (const auto& pair : musics_)
|
||||
{
|
||||
pair.second->SetVolume(volume_);
|
||||
|
|
@ -179,7 +179,7 @@ void e2d::Player::ResumeAll()
|
|||
{
|
||||
for (const auto& pair : musics_)
|
||||
{
|
||||
pair.second->Play();
|
||||
pair.second->Resume();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@
|
|||
<ClCompile Include="..\..\core\events\KeyEvent.cpp" />
|
||||
<ClCompile Include="..\..\core\events\MouseEvent.cpp" />
|
||||
<ClCompile Include="..\..\core\impl\TextRenderer.cpp" />
|
||||
<ClCompile Include="..\..\core\impl\VoiceCallback.cpp" />
|
||||
<ClCompile Include="..\..\core\modules\Audio.cpp" />
|
||||
<ClCompile Include="..\..\core\modules\Device.cpp" />
|
||||
<ClCompile Include="..\..\core\modules\Game.cpp" />
|
||||
|
|
|
|||
|
|
@ -141,9 +141,6 @@
|
|||
<ClCompile Include="..\..\core\impl\TextRenderer.cpp">
|
||||
<Filter>impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\impl\VoiceCallback.cpp">
|
||||
<Filter>impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\events\KeyEvent.cpp">
|
||||
<Filter>events</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -189,7 +189,6 @@
|
|||
<ClCompile Include="..\..\core\events\KeyEvent.cpp" />
|
||||
<ClCompile Include="..\..\core\events\MouseEvent.cpp" />
|
||||
<ClCompile Include="..\..\core\impl\TextRenderer.cpp" />
|
||||
<ClCompile Include="..\..\core\impl\VoiceCallback.cpp" />
|
||||
<ClCompile Include="..\..\core\modules\Audio.cpp" />
|
||||
<ClCompile Include="..\..\core\modules\Device.cpp" />
|
||||
<ClCompile Include="..\..\core\modules\Game.cpp" />
|
||||
|
|
|
|||
|
|
@ -141,9 +141,6 @@
|
|||
<ClCompile Include="..\..\core\impl\TextRenderer.cpp">
|
||||
<Filter>impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\impl\VoiceCallback.cpp">
|
||||
<Filter>impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\events\KeyEvent.cpp">
|
||||
<Filter>events</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@
|
|||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
|
|
@ -222,7 +222,6 @@
|
|||
<ClCompile Include="..\..\core\events\KeyEvent.cpp" />
|
||||
<ClCompile Include="..\..\core\events\MouseEvent.cpp" />
|
||||
<ClCompile Include="..\..\core\impl\TextRenderer.cpp" />
|
||||
<ClCompile Include="..\..\core\impl\MediaAsyncCallback.cpp" />
|
||||
<ClCompile Include="..\..\core\modules\Audio.cpp" />
|
||||
<ClCompile Include="..\..\core\modules\Device.cpp" />
|
||||
<ClCompile Include="..\..\core\modules\Game.cpp" />
|
||||
|
|
|
|||
|
|
@ -216,9 +216,6 @@
|
|||
<ClCompile Include="..\..\core\modules\Device.cpp">
|
||||
<Filter>modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\impl\MediaAsyncCallback.cpp">
|
||||
<Filter>impl</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\core\easy2d.h" />
|
||||
|
|
|
|||
Loading…
Reference in New Issue