separate audio/network/imgui package

This commit is contained in:
Nomango 2019-07-30 10:46:01 +08:00
parent da7970bf34
commit cfebf15974
204 changed files with 2296 additions and 7563 deletions

3
.gitignore vendored
View File

@ -1,3 +1,6 @@
build/
output/
x64/
Debug/
Release/

View File

@ -4,7 +4,7 @@ VisualStudioVersion = 16.0.28729.10
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HelloWorld", "samples\HelloWorld\HelloWorld.vcxproj", "{3561A359-F9FD-48AB-A977-34E7E568BC8E}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Kiwano", "Kiwano\Kiwano.vcxproj", "{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kiwano", "kiwano\kiwano.vcxproj", "{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Samples", "samples\Samples\Samples.vcxproj", "{45F5738D-CDF2-4024-974D-25B64F9043DE}"
EndProject
@ -12,6 +12,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImGuiSample", "samples\ImGu
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Box2DSample", "samples\Box2DSample\Box2DSample.vcxproj", "{324CFF47-4EB2-499A-BE5F-53A82E3BA14B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kiwano-audio", "kiwano-audio\kiwano-audio.vcxproj", "{1B97937D-8184-426C-BE71-29A163DC76C9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kiwano-network", "kiwano-network\kiwano-network.vcxproj", "{69DFBE92-C06F-4CF8-9495-CA9BF2E3BAF2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kiwano-imgui", "kiwano-imgui\kiwano-imgui.vcxproj", "{A7062ED8-8910-48A5-A3BC-C1612672571F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -62,6 +68,30 @@ Global
{324CFF47-4EB2-499A-BE5F-53A82E3BA14B}.Release|Win32.Build.0 = Release|Win32
{324CFF47-4EB2-499A-BE5F-53A82E3BA14B}.Release|x64.ActiveCfg = Release|x64
{324CFF47-4EB2-499A-BE5F-53A82E3BA14B}.Release|x64.Build.0 = Release|x64
{1B97937D-8184-426C-BE71-29A163DC76C9}.Debug|Win32.ActiveCfg = Debug|Win32
{1B97937D-8184-426C-BE71-29A163DC76C9}.Debug|Win32.Build.0 = Debug|Win32
{1B97937D-8184-426C-BE71-29A163DC76C9}.Debug|x64.ActiveCfg = Debug|x64
{1B97937D-8184-426C-BE71-29A163DC76C9}.Debug|x64.Build.0 = Debug|x64
{1B97937D-8184-426C-BE71-29A163DC76C9}.Release|Win32.ActiveCfg = Release|Win32
{1B97937D-8184-426C-BE71-29A163DC76C9}.Release|Win32.Build.0 = Release|Win32
{1B97937D-8184-426C-BE71-29A163DC76C9}.Release|x64.ActiveCfg = Release|x64
{1B97937D-8184-426C-BE71-29A163DC76C9}.Release|x64.Build.0 = Release|x64
{69DFBE92-C06F-4CF8-9495-CA9BF2E3BAF2}.Debug|Win32.ActiveCfg = Debug|Win32
{69DFBE92-C06F-4CF8-9495-CA9BF2E3BAF2}.Debug|Win32.Build.0 = Debug|Win32
{69DFBE92-C06F-4CF8-9495-CA9BF2E3BAF2}.Debug|x64.ActiveCfg = Debug|x64
{69DFBE92-C06F-4CF8-9495-CA9BF2E3BAF2}.Debug|x64.Build.0 = Debug|x64
{69DFBE92-C06F-4CF8-9495-CA9BF2E3BAF2}.Release|Win32.ActiveCfg = Release|Win32
{69DFBE92-C06F-4CF8-9495-CA9BF2E3BAF2}.Release|Win32.Build.0 = Release|Win32
{69DFBE92-C06F-4CF8-9495-CA9BF2E3BAF2}.Release|x64.ActiveCfg = Release|x64
{69DFBE92-C06F-4CF8-9495-CA9BF2E3BAF2}.Release|x64.Build.0 = Release|x64
{A7062ED8-8910-48A5-A3BC-C1612672571F}.Debug|Win32.ActiveCfg = Debug|Win32
{A7062ED8-8910-48A5-A3BC-C1612672571F}.Debug|Win32.Build.0 = Debug|Win32
{A7062ED8-8910-48A5-A3BC-C1612672571F}.Debug|x64.ActiveCfg = Debug|x64
{A7062ED8-8910-48A5-A3BC-C1612672571F}.Debug|x64.Build.0 = Debug|x64
{A7062ED8-8910-48A5-A3BC-C1612672571F}.Release|Win32.ActiveCfg = Release|Win32
{A7062ED8-8910-48A5-A3BC-C1612672571F}.Release|Win32.Build.0 = Release|Win32
{A7062ED8-8910-48A5-A3BC-C1612672571F}.Release|x64.ActiveCfg = Release|x64
{A7062ED8-8910-48A5-A3BC-C1612672571F}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -1,137 +0,0 @@
// Copyright (c) 2016-2018 Kiwano - 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 "../kiwano-audio.h"
#include "Player.h"
namespace kiwano
{
Player::Player()
: volume_(1.f)
{
}
Player::~Player()
{
ClearCache();
}
bool Player::Load(Resource const& res)
{
size_t hash_code = res.GetHashCode();
if (sound_cache_.end() != sound_cache_.find(hash_code))
return true;
SoundPtr sound = new (std::nothrow) Sound();
if (sound)
{
if (sound->Load(res))
{
sound->SetVolume(volume_);
sound_cache_.insert(std::make_pair(hash_code, sound));
return true;
}
}
return false;
}
void Player::Play(Resource const& res, int loop_count)
{
if (Load(res))
{
size_t hash_code = res.GetHashCode();
if (sound_cache_.end() != sound_cache_.find(hash_code))
sound_cache_[hash_code]->Play(loop_count);
}
}
void Player::Pause(Resource const& res)
{
size_t hash_code = res.GetHashCode();
if (sound_cache_.end() != sound_cache_.find(hash_code))
sound_cache_[hash_code]->Pause();
}
void Player::Resume(Resource const& res)
{
size_t hash_code = res.GetHashCode();
if (sound_cache_.end() != sound_cache_.find(hash_code))
sound_cache_[hash_code]->Resume();
}
void Player::Stop(Resource const& res)
{
size_t hash_code = res.GetHashCode();
if (sound_cache_.end() != sound_cache_.find(hash_code))
sound_cache_[hash_code]->Stop();
}
bool Player::IsPlaying(Resource const& res)
{
size_t hash_code = res.GetHashCode();
if (sound_cache_.end() != sound_cache_.find(hash_code))
return sound_cache_[hash_code]->IsPlaying();
return false;
}
float Player::GetVolume() const
{
return volume_;
}
void Player::SetVolume(float volume)
{
volume_ = std::min(std::max(volume, -224.f), 224.f);
for (const auto& pair : sound_cache_)
{
pair.second->SetVolume(volume_);
}
}
void Player::PauseAll()
{
for (const auto& pair : sound_cache_)
{
pair.second->Pause();
}
}
void Player::ResumeAll()
{
for (const auto& pair : sound_cache_)
{
pair.second->Resume();
}
}
void Player::StopAll()
{
for (const auto& pair : sound_cache_)
{
pair.second->Stop();
}
}
void Player::ClearCache()
{
sound_cache_.clear();
}
}

View File

@ -1,219 +0,0 @@
// Copyright (c) 2016-2018 Kiwano - 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 "../kiwano-audio.h"
#include "Sound.h"
#include "Transcoder.h"
namespace kiwano
{
Sound::Sound()
: opened_(false)
, playing_(false)
, size_(0)
, wave_data_(nullptr)
, voice_(nullptr)
{
}
Sound::Sound(Resource const& res)
: Sound()
{
Load(res);
}
Sound::~Sound()
{
Close();
}
bool Sound::Load(Resource const& res)
{
if (opened_)
{
Close();
}
HRESULT hr = S_OK;
Transcoder transcoder;
if (res.IsFileType())
{
#if defined(KGE_DEBUG)
if (!FileUtil::ExistsFile(res.GetFileName()))
{
KGE_WARNING_LOG(L"Media file '%s' not found", res.GetFileName().c_str());
return false;
}
#endif
hr = transcoder.LoadMediaFile(res.GetFileName(), &wave_data_, &size_);
}
else
{
hr = transcoder.LoadMediaResource(res, &wave_data_, &size_);
}
if (FAILED(hr))
{
KGE_ERROR_LOG(L"Load media file failed with HRESULT of %08X", hr);
return false;
}
hr = Audio::Instance().CreateVoice(&voice_, transcoder.GetWaveFormatEx());
if (FAILED(hr))
{
if (wave_data_)
{
delete[] wave_data_;
wave_data_ = nullptr;
}
KGE_ERROR_LOG(L"Create source voice failed with HRESULT of %08X", hr);
return false;
}
opened_ = true;
return true;
}
void Sound::Play(int loop_count)
{
if (!opened_)
{
KGE_ERROR_LOG(L"Sound must be opened first!");
return;
}
KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL");
// if sound stream is not empty, stop() will clear it
XAUDIO2_VOICE_STATE state;
voice_->GetState(&state);
if (state.BuffersQueued)
Stop();
// clamp loop count
loop_count = (loop_count < 0) ? XAUDIO2_LOOP_INFINITE : std::min(loop_count, XAUDIO2_LOOP_INFINITE - 1);
XAUDIO2_BUFFER buffer = { 0 };
buffer.pAudioData = wave_data_;
buffer.Flags = XAUDIO2_END_OF_STREAM;
buffer.AudioBytes = size_;
buffer.LoopCount = static_cast<UINT32>(loop_count);
HRESULT hr = voice_->SubmitSourceBuffer(&buffer);
if (SUCCEEDED(hr))
{
hr = voice_->Start();
}
if (FAILED(hr))
{
KGE_ERROR_LOG(L"Submitting source buffer failed with HRESULT of %08X", hr);
}
playing_ = SUCCEEDED(hr);
}
void Sound::Pause()
{
KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL");
if (SUCCEEDED(voice_->Stop()))
playing_ = false;
}
void Sound::Resume()
{
KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL");
if (SUCCEEDED(voice_->Start()))
playing_ = true;
}
void Sound::Stop()
{
KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL");
HRESULT hr = voice_->Stop();
if (SUCCEEDED(hr))
hr = voice_->ExitLoop();
if (SUCCEEDED(hr))
hr = voice_->FlushSourceBuffers();
if (SUCCEEDED(hr))
playing_ = false;
}
void Sound::Close()
{
if (voice_)
{
voice_->Stop();
voice_->FlushSourceBuffers();
voice_->DestroyVoice();
voice_ = nullptr;
}
if (wave_data_)
{
delete[] wave_data_;
wave_data_ = nullptr;
}
opened_ = false;
playing_ = false;
}
bool Sound::IsPlaying() const
{
if (opened_)
{
if (!voice_)
return false;
XAUDIO2_VOICE_STATE state;
voice_->GetState(&state);
UINT32 buffers_queued = state.BuffersQueued;
if (buffers_queued && playing_)
return true;
}
return false;
}
float Sound::GetVolume() const
{
KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL");
float volume = 0.0f;
voice_->GetVolume(&volume);
return volume;
}
void Sound::SetVolume(float volume)
{
KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL");
volume = std::min(std::max(volume, -224.f), 224.f);
voice_->SetVolume(volume);
}
}

View File

@ -1,267 +0,0 @@
// Copyright (c) 2016-2018 Kiwano - 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.
#ifndef INITGUID
# define INITGUID // MFAudioFormat_PCM, MF_MT_MAJOR_TYPE, MF_MT_SUBTYPE, MFMediaType_Audio
#endif
#include "../kiwano-audio.h"
#include "Transcoder.h"
#include "audio-modules.h"
namespace kiwano
{
Transcoder::Transcoder()
: wave_format_(nullptr)
{
}
Transcoder::~Transcoder()
{
if (wave_format_)
{
::CoTaskMemFree(wave_format_);
wave_format_ = nullptr;
}
}
const WAVEFORMATEX* Transcoder::GetWaveFormatEx() const
{
return wave_format_;
}
HRESULT Transcoder::LoadMediaFile(String const& file_path, BYTE** wave_data, UINT32* wave_data_size)
{
HRESULT hr = S_OK;
ComPtr<IMFSourceReader> reader;
hr = modules::MediaFoundation::Get().MFCreateSourceReaderFromURL(
file_path.c_str(),
nullptr,
&reader
);
if (SUCCEEDED(hr))
{
hr = ReadSource(reader.Get(), wave_data, wave_data_size);
}
return hr;
}
HRESULT Transcoder::LoadMediaResource(Resource const& res, BYTE** wave_data, UINT32* wave_data_size)
{
HRESULT hr = S_OK;
ComPtr<IStream> stream;
ComPtr<IMFByteStream> byte_stream;
ComPtr<IMFSourceReader> reader;
LPVOID buffer;
DWORD buffer_size;
if (!res.Load(buffer, buffer_size)) { return false; }
stream = modules::Shlwapi::Get().SHCreateMemStream(
static_cast<const BYTE*>(buffer),
static_cast<UINT>(buffer_size)
);
if (stream == nullptr)
{
KGE_ERROR_LOG(L"SHCreateMemStream failed");
return E_OUTOFMEMORY;
}
if (SUCCEEDED(hr))
{
hr = modules::MediaFoundation::Get().MFCreateMFByteStreamOnStream(stream.Get(), &byte_stream);
}
if (SUCCEEDED(hr))
{
hr = modules::MediaFoundation::Get().MFCreateSourceReaderFromByteStream(
byte_stream.Get(),
nullptr,
&reader
);
}
if (SUCCEEDED(hr))
{
hr = ReadSource(reader.Get(), wave_data, wave_data_size);
}
return hr;
}
HRESULT Transcoder::ReadSource(IMFSourceReader* reader, BYTE** wave_data, UINT32* wave_data_size)
{
HRESULT hr = S_OK;
DWORD max_stream_size = 0;
ComPtr<IMFMediaType> partial_type;
ComPtr<IMFMediaType> uncompressed_type;
hr = modules::MediaFoundation::Get().MFCreateMediaType(&partial_type);
if (SUCCEEDED(hr))
{
hr = partial_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
}
if (SUCCEEDED(hr))
{
hr = partial_type->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM);
}
// 设置 source reader 的媒体类型,它将使用合适的解码器去解码这个音频
if (SUCCEEDED(hr))
{
hr = reader->SetCurrentMediaType(
(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,
0,
partial_type.Get()
);
}
// 从 IMFMediaType 中获取 WAVEFORMAT 结构
if (SUCCEEDED(hr))
{
hr = reader->GetCurrentMediaType(
(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,
&uncompressed_type
);
}
// 指定音频流
if (SUCCEEDED(hr))
{
hr = reader->SetStreamSelection(
(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,
true
);
}
// 获取 WAVEFORMAT 数据
if (SUCCEEDED(hr))
{
UINT32 size = 0;
hr = modules::MediaFoundation::Get().MFCreateWaveFormatExFromMFMediaType(
uncompressed_type.Get(),
&wave_format_,
&size,
(DWORD)MFWaveFormatExConvertFlag_Normal
);
}
// 估算音频流大小
if (SUCCEEDED(hr))
{
PROPVARIANT prop;
PropVariantInit(&prop);
hr = reader->GetPresentationAttribute(
(DWORD)MF_SOURCE_READER_MEDIASOURCE,
MF_PD_DURATION,
&prop
);
LONGLONG duration = prop.uhVal.QuadPart;
max_stream_size = static_cast<DWORD>(
(duration * wave_format_->nAvgBytesPerSec) / 10000000 + 1
);
PropVariantClear(&prop);
}
// 读取音频数据
if (SUCCEEDED(hr))
{
DWORD flags = 0;
DWORD position = 0;
BYTE* data = new (std::nothrow) BYTE[max_stream_size];
ComPtr<IMFSample> sample;
ComPtr<IMFMediaBuffer> buffer;
if (data == nullptr)
{
KGE_ERROR_LOG(L"Low memory");
hr = E_OUTOFMEMORY;
}
else
{
while (true)
{
hr = reader->ReadSample(
(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,
0,
nullptr,
&flags,
nullptr,
&sample
);
if (flags & MF_SOURCE_READERF_ENDOFSTREAM) { break; }
if (sample == nullptr) { continue; }
if (SUCCEEDED(hr))
{
hr = sample->ConvertToContiguousBuffer(&buffer);
if (SUCCEEDED(hr))
{
BYTE *audio_data = nullptr;
DWORD sample_buffer_length = 0;
hr = buffer->Lock(
&audio_data,
nullptr,
&sample_buffer_length
);
if (SUCCEEDED(hr))
{
for (DWORD i = 0; i < sample_buffer_length; i++)
{
data[position++] = audio_data[i];
}
hr = buffer->Unlock();
}
}
buffer = nullptr;
}
sample = nullptr;
if (FAILED(hr)) { break; }
}
if (SUCCEEDED(hr))
{
*wave_data = data;
*wave_data_size = position;
}
}
}
return hr;
}
}

View File

@ -1,97 +0,0 @@
// Copyright (c) 2016-2018 Kiwano - 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 "../kiwano-audio.h"
#include "audio-modules.h"
namespace kiwano
{
namespace modules
{
XAudio2::XAudio2()
{
const auto xaudio2_dll_names =
{
L"xaudio2_9.dll", // for Windows 10
L"xaudio2_8.dll", // for Windows 8
L"xaudio2_7.dll" // for DirectX SDK
};
for (const auto& name : xaudio2_dll_names)
{
xaudio2 = LoadLibraryW(name);
if (xaudio2)
{
XAudio2Create = (PFN_XAudio2Create)
GetProcAddress(xaudio2, "XAudio2Create");
break;
}
}
if (!xaudio2)
{
KGE_ERROR_LOG(L"Load xaudio2.dll failed");
throw std::runtime_error("Load xaudio2.dll failed");
}
}
MediaFoundation::MediaFoundation()
{
mfplat = LoadLibraryW(L"Mfplat.dll");
if (mfplat)
{
MFStartup = (PFN_MFStartup)
GetProcAddress(mfplat, "MFStartup");
MFShutdown = (PFN_MFShutdown)
GetProcAddress(mfplat, "MFShutdown");
MFCreateMediaType = (PFN_MFCreateMediaType)
GetProcAddress(mfplat, "MFCreateMediaType");
MFCreateWaveFormatExFromMFMediaType = (PFN_MFCreateWaveFormatExFromMFMediaType)
GetProcAddress(mfplat, "MFCreateWaveFormatExFromMFMediaType");
MFCreateMFByteStreamOnStream = (PFN_MFCreateMFByteStreamOnStream)
GetProcAddress(mfplat, "MFCreateMFByteStreamOnStream");
}
else
{
KGE_LOG(L"Load Mfplat.dll failed");
throw std::runtime_error("Load Mfplat.dll failed");
}
mfreadwrite = LoadLibraryW(L"Mfreadwrite.dll");
if (mfreadwrite)
{
MFCreateSourceReaderFromURL = (PFN_MFCreateSourceReaderFromURL)
GetProcAddress(mfreadwrite, "MFCreateSourceReaderFromURL");
MFCreateSourceReaderFromByteStream = (PFN_MFCreateSourceReaderFromByteStream)
GetProcAddress(mfreadwrite, "MFCreateSourceReaderFromByteStream");
}
else
{
KGE_LOG(L"Load Mfreadwrite.dll failed");
throw std::runtime_error("Load Mfreadwrite.dll failed");
}
}
}
}

View File

@ -1,83 +0,0 @@
// Copyright (c) 2016-2018 Kiwano - 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.
#pragma once
#include <xaudio2.h>
#include <mfapi.h>
#include <mfidl.h>
#include <mfreadwrite.h>
namespace kiwano
{
namespace modules
{
class KGE_API XAudio2
{
XAudio2();
HMODULE xaudio2;
// XAudio2 functions
typedef HRESULT(WINAPI *PFN_XAudio2Create)(IXAudio2**, UINT32, XAUDIO2_PROCESSOR);
public:
static inline XAudio2& Get()
{
static XAudio2 instance;
return instance;
}
PFN_XAudio2Create XAudio2Create;
};
class KGE_API MediaFoundation
{
MediaFoundation();
HMODULE mfplat;
HMODULE mfreadwrite;
// MediaFoundation functions
typedef HRESULT(WINAPI *PFN_MFStartup)(ULONG, DWORD);
typedef HRESULT(WINAPI *PFN_MFShutdown)();
typedef HRESULT(WINAPI *PFN_MFCreateMediaType)(IMFMediaType**);
typedef HRESULT(WINAPI *PFN_MFCreateWaveFormatExFromMFMediaType)(IMFMediaType*, WAVEFORMATEX**, UINT32*, UINT32);
typedef HRESULT(WINAPI *PFN_MFCreateSourceReaderFromURL)(LPCWSTR, IMFAttributes*, IMFSourceReader**);
typedef HRESULT(WINAPI *PFN_MFCreateSourceReaderFromByteStream)(IMFByteStream*, IMFAttributes*, IMFSourceReader**);
typedef HRESULT(WINAPI *PFN_MFCreateMFByteStreamOnStream)(IStream*, IMFByteStream**);
public:
static inline MediaFoundation& Get()
{
static MediaFoundation instance;
return instance;
}
PFN_MFStartup MFStartup;
PFN_MFShutdown MFShutdown;
PFN_MFCreateMediaType MFCreateMediaType;
PFN_MFCreateWaveFormatExFromMFMediaType MFCreateWaveFormatExFromMFMediaType;
PFN_MFCreateSourceReaderFromURL MFCreateSourceReaderFromURL;
PFN_MFCreateSourceReaderFromByteStream MFCreateSourceReaderFromByteStream;
PFN_MFCreateMFByteStreamOnStream MFCreateMFByteStreamOnStream;
};
}
}

View File

@ -1,185 +0,0 @@
// Copyright (c) 2016-2018 Kiwano - 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 "../kiwano-imgui.h"
namespace kiwano
{
namespace
{
Map<int, int> mouse_buttons =
{
{ MouseButton::Left, 0 },
{ MouseButton::Right, 1 },
{ MouseButton::Middle, 2 }
};
}
ImGuiLayer::ImGuiLayer()
{
target_window_ = Renderer::Instance().GetTargetWindow();
SetSwallowEvents(true);
}
ImGuiLayer::~ImGuiLayer()
{
ImGuiView::Instance().RemoveLayer(this);
}
void ImGuiLayer::OnMouseButtonDown(int btn, Point const & p)
{
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == nullptr)
::SetCapture(target_window_);
KGE_ASSERT(mouse_buttons.find(btn) != mouse_buttons.end());
ImGui::GetIO().MouseDown[mouse_buttons[btn]] = true;
}
void ImGuiLayer::OnMouseButtonUp(int btn, Point const & p)
{
KGE_ASSERT(mouse_buttons.find(btn) != mouse_buttons.end());
ImGui::GetIO().MouseDown[mouse_buttons[btn]] = false;
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == target_window_)
::ReleaseCapture();
}
void ImGuiLayer::OnMouseWheel(float wheel)
{
ImGui::GetIO().MouseWheel += wheel;
}
void ImGuiLayer::OnKeyDown(int key)
{
KGE_ASSERT(key < 256);
ImGui::GetIO().KeysDown[key] = 1;
}
void ImGuiLayer::OnKeyUp(int key)
{
KGE_ASSERT(key < 256);
ImGui::GetIO().KeysDown[key] = 0;
}
void ImGuiLayer::OnChar(char c)
{
ImGui::GetIO().AddInputCharacter(c);
}
void ImGuiLayer::OnUpdate(Duration dt)
{
ImGuiIO& io = ImGui::GetIO();
// Setup time step
io.DeltaTime = dt.Seconds();
// Read keyboard modifiers inputs
io.KeyCtrl = Input::Instance().IsDown(KeyCode::Ctrl);
io.KeyShift = Input::Instance().IsDown(KeyCode::Shift);
io.KeyAlt = Input::Instance().IsDown(KeyCode::Alt);
io.KeySuper = false;
// io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below.
// Update OS mouse position
UpdateMousePos();
// Update OS mouse cursor with the cursor requested by imgui
UpdateMouseCursor();
}
void ImGuiLayer::OnRender()
{
ImGuiView::Instance().NewFrame();
for (const auto& pipeline : pipelines_)
{
pipeline.second();
}
ImGuiView::Instance().Render();
}
void ImGuiLayer::UpdateMousePos()
{
ImGuiIO& io = ImGui::GetIO();
// Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
if (io.WantSetMousePos)
{
POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
HWND hwnd = target_window_;
::ClientToScreen(hwnd, &pos);
::SetCursorPos(pos.x, pos.y);
}
Point pos = Input::Instance().GetMousePos();
io.MousePos = ImVec2(pos.x, pos.y);
}
void ImGuiLayer::UpdateMouseCursor()
{
static ImGuiMouseCursor last_mouse_cursor = ImGuiMouseCursor_COUNT;
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
if (last_mouse_cursor != imgui_cursor)
{
last_mouse_cursor = imgui_cursor;
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
return;
MouseCursor cursor = MouseCursor::Arrow;
switch (imgui_cursor)
{
case ImGuiMouseCursor_Arrow: cursor = MouseCursor::Arrow; break;
case ImGuiMouseCursor_TextInput: cursor = MouseCursor::TextInput; break;
case ImGuiMouseCursor_ResizeAll: cursor = MouseCursor::SizeAll; break;
case ImGuiMouseCursor_ResizeEW: cursor = MouseCursor::SizeWE; break;
case ImGuiMouseCursor_ResizeNS: cursor = MouseCursor::SizeNS; break;
case ImGuiMouseCursor_ResizeNESW: cursor = MouseCursor::SizeNESW; break;
case ImGuiMouseCursor_ResizeNWSE: cursor = MouseCursor::SizeNWSE; break;
case ImGuiMouseCursor_Hand: cursor = MouseCursor::Hand; break;
}
GetScene()->SetMouseCursor(cursor);
}
}
void ImGuiLayer::AddItem(ImGuiPipeline const & item, String const & name)
{
pipelines_.insert(std::make_pair(name, item));
}
void ImGuiLayer::RemoveItem(String const & name)
{
auto iter = pipelines_.find(name);
if (iter != pipelines_.end())
{
pipelines_.erase(iter);
}
}
void ImGuiLayer::RemoveAllItems()
{
pipelines_.clear();
}
}

View File

@ -1,114 +0,0 @@
// Copyright (C) 2019 Nomango
#include "../kiwano-imgui.h"
#include "imgui_impl.hpp"
namespace kiwano
{
void ImGuiView::SetupComponent(Application* app)
{
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
Init(app->GetWindow()->GetHandle());
}
void ImGuiView::DestroyComponent()
{
ImGui_Impl_Shutdown();
ImGui::DestroyContext();
}
void ImGuiView::Init(HWND hwnd)
{
ImGuiIO& io = ImGui::GetIO();
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
io.BackendPlatformName = "imgui_impl_win32";
io.ImeWindowHandle = hwnd;
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime.
io.KeyMap[ImGuiKey_Tab] = KeyCode::Tab;
io.KeyMap[ImGuiKey_LeftArrow] = KeyCode::Left;
io.KeyMap[ImGuiKey_RightArrow] = KeyCode::Right;
io.KeyMap[ImGuiKey_UpArrow] = KeyCode::Up;
io.KeyMap[ImGuiKey_DownArrow] = KeyCode::Down;
io.KeyMap[ImGuiKey_Delete] = KeyCode::Delete;
io.KeyMap[ImGuiKey_Backspace] = KeyCode::Back;
io.KeyMap[ImGuiKey_Space] = KeyCode::Space;
io.KeyMap[ImGuiKey_Enter] = KeyCode::Enter;
io.KeyMap[ImGuiKey_Escape] = KeyCode::Esc;
io.KeyMap[ImGuiKey_A] = KeyCode::A;
io.KeyMap[ImGuiKey_C] = KeyCode::C;
io.KeyMap[ImGuiKey_V] = KeyCode::V;
io.KeyMap[ImGuiKey_X] = KeyCode::X;
io.KeyMap[ImGuiKey_Y] = KeyCode::Y;
io.KeyMap[ImGuiKey_Z] = KeyCode::Z;
ImGui_Impl_Init(
Renderer::Instance()
);
}
void ImGuiView::NewFrame()
{
ImGui_Impl_NewFrame();
ImGuiIO& io = ImGui::GetIO();
KGE_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built!");
// Setup display size (every frame to accommodate for window resizing)
Size display_size = Renderer::Instance().GetOutputSize();
io.DisplaySize = ImVec2(display_size.x, display_size.y);
ImGui::NewFrame();
}
void ImGuiView::Render()
{
ImGui::Render();
ImGui_Impl_RenderDrawData(ImGui::GetDrawData());
}
ImGuiLayerPtr ImGuiView::CreateLayer(Scene* scene)
{
auto iter = layers_.find(scene);
if (iter == layers_.end())
{
ImGuiLayerPtr layer = new (std::nothrow) ImGuiLayer;
if (layer)
{
layers_.insert(std::make_pair(scene, layer.Get()));
}
return layer;
}
else
{
return iter->second;
}
}
void ImGuiView::RemoveLayer(ImGuiLayer* layer)
{
using value_type = Map<Scene*, Layer*>::value_type;
auto iter = std::find_if(layers_.begin(), layers_.end(), [=](value_type const& value)
{
return value.second == layer;
});
if (iter != layers_.end())
{
layers_.erase(iter);
}
}
}

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -1,156 +0,0 @@
/* lws_config.h Generated from lws_config.h.in */
#ifndef NDEBUG
#ifndef _DEBUG
#define _DEBUG
#endif
#endif
#define LWS_INSTALL_DATADIR "C:/Program Files (x86)/libwebsockets/share"
/* Define to 1 to use wolfSSL/CyaSSL as a replacement for OpenSSL.
* LWS_OPENSSL_SUPPORT needs to be set also for this to work. */
/* #undef USE_WOLFSSL */
/* Also define to 1 (in addition to USE_WOLFSSL) when using the
(older) CyaSSL library */
/* #undef USE_OLD_CYASSL */
/* #undef LWS_WITH_BORINGSSL */
/* #undef LWS_WITH_MBEDTLS */
/* #undef LWS_WITH_POLARSSL */
/* #undef LWS_WITH_ESP8266 */
/* #undef LWS_WITH_ESP32 */
/* #undef LWS_WITH_PLUGINS */
/* #undef LWS_WITH_NO_LOGS */
/* The Libwebsocket version */
#define LWS_LIBRARY_VERSION "2.4.2"
#define LWS_LIBRARY_VERSION_MAJOR 2
#define LWS_LIBRARY_VERSION_MINOR 4
#define LWS_LIBRARY_VERSION_PATCH 2
/* LWS_LIBRARY_VERSION_NUMBER looks like 1005001 for e.g. version 1.5.1 */
#define LWS_LIBRARY_VERSION_NUMBER (LWS_LIBRARY_VERSION_MAJOR*1000000)+(LWS_LIBRARY_VERSION_MINOR*1000)+LWS_LIBRARY_VERSION_PATCH
/* The current git commit hash that we're building from */
#define LWS_BUILD_HASH "desktop-s54jiqa\\serveryjx@DESKTOP-S54JIQA-v2.0.0-640-g8964ce9d"
/* Build with OpenSSL support */
#define LWS_OPENSSL_SUPPORT
/* The client should load and trust CA root certs it finds in the OS */
#define LWS_SSL_CLIENT_USE_OS_CA_CERTS
/* Sets the path where the client certs should be installed. */
#define LWS_OPENSSL_CLIENT_CERTS "../share"
/* Turn off websocket extensions */
/* #undef LWS_NO_EXTENSIONS */
/* Enable libev io loop */
/* #undef LWS_WITH_LIBEV */
/* Enable libuv io loop */
#define LWS_WITH_LIBUV
/* Enable libevent io loop */
/* #undef LWS_WITH_LIBEVENT */
/* Build with support for ipv6 */
/* #undef LWS_WITH_IPV6 */
/* Build with support for UNIX domain socket */
/* #undef LWS_WITH_UNIX_SOCK */
/* Build with support for HTTP2 */
/* #undef LWS_WITH_HTTP2 */
/* Turn on latency measuring code */
/* #undef LWS_LATENCY */
/* Don't build the daemonizeation api */
#define LWS_NO_DAEMONIZE
/* Build without server support */
/* #undef LWS_NO_SERVER */
/* Build without client support */
/* #undef LWS_NO_CLIENT */
/* If we should compile with MinGW support */
/* #undef LWS_MINGW_SUPPORT */
/* Use the BSD getifaddrs that comes with libwebsocket, for uclibc support */
#define LWS_BUILTIN_GETIFADDRS
/* use SHA1() not internal libwebsockets_SHA1 */
/* #undef LWS_SHA1_USE_OPENSSL_NAME */
/* SSL server using ECDH certificate */
/* #undef LWS_SSL_SERVER_WITH_ECDH_CERT */
/* #undef LWS_HAVE_SSL_CTX_set1_param */
#define LWS_HAVE_X509_VERIFY_PARAM_set1_host
#define LWS_HAVE_RSA_SET0_KEY
/* #undef LWS_HAVE_UV_VERSION_H */
/* CGI apis */
/* #undef LWS_WITH_CGI */
/* whether the Openssl is recent enough, and / or built with, ecdh */
#define LWS_HAVE_OPENSSL_ECDH_H
/* HTTP Proxy support */
/* #undef LWS_WITH_HTTP_PROXY */
/* HTTP Ranges support */
#define LWS_WITH_RANGES
/* Http access log support */
/* #undef LWS_WITH_ACCESS_LOG */
/* #undef LWS_WITH_SERVER_STATUS */
/* #undef LWS_WITH_STATEFUL_URLDECODE */
/* #undef LWS_WITH_PEER_LIMITS */
/* Maximum supported service threads */
#define LWS_MAX_SMP 1
/* Lightweight JSON Parser */
/* #undef LWS_WITH_LEJP */
/* SMTP */
/* #undef LWS_WITH_SMTP */
/* OPTEE */
/* #undef LWS_PLAT_OPTEE */
/* ZIP FOPS */
#define LWS_WITH_ZIP_FOPS
#define LWS_HAVE_STDINT_H
/* #undef LWS_AVOID_SIGPIPE_IGN */
#define LWS_FALLBACK_GETHOSTBYNAME
/* #undef LWS_WITH_STATS */
/* #undef LWS_WITH_SOCKS5 */
/* #undef LWS_HAVE_SYS_CAPABILITY_H */
/* #undef LWS_HAVE_LIBCAP */
#define LWS_HAVE_ATOLL
#define LWS_HAVE__ATOI64
#define LWS_HAVE__STAT32I64
/* OpenSSL various APIs */
#define LWS_HAVE_TLS_CLIENT_METHOD
#define LWS_HAVE_TLSV1_2_CLIENT_METHOD
#define LWS_HAVE_SSL_SET_INFO_CALLBACK
#define LWS_HAS_INTPTR_T

View File

@ -19,8 +19,8 @@
// THE SOFTWARE.
#pragma once
#include "kiwano.h"
#include "kiwano/kiwano.h"
#include "audio/audio.h"
#include "audio/Sound.h"
#include "audio/Player.h"
#include "src/audio.h"
#include "src/Sound.h"
#include "src/Player.h"

View File

@ -0,0 +1,186 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClInclude Include="kiwano-audio.h" />
<ClInclude Include="src\audio-modules.h" />
<ClInclude Include="src\audio.h" />
<ClInclude Include="src\Player.h" />
<ClInclude Include="src\Sound.h" />
<ClInclude Include="src\Transcoder.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\audio-modules.cpp" />
<ClCompile Include="src\audio.cpp" />
<ClCompile Include="src\Player.cpp" />
<ClCompile Include="src\Sound.cpp" />
<ClCompile Include="src\Transcoder.cpp" />
</ItemGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{1B97937D-8184-426C-BE71-29A163DC76C9}</ProjectGuid>
<RootNamespace>kiwano-audio</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(ProjectDir)\output\$(Configuration).$(Platform)\</OutDir>
<IntDir>$(ProjectDir)\build\$(Configuration).$(Platform)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(ProjectDir)\output\$(Configuration).$(Platform)\</OutDir>
<IntDir>$(ProjectDir)\build\$(Configuration).$(Platform)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(ProjectDir)\output\$(Configuration).$(Platform)\</OutDir>
<IntDir>$(ProjectDir)\build\$(Configuration).$(Platform)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(ProjectDir)\output\$(Configuration).$(Platform)\</OutDir>
<IntDir>$(ProjectDir)\build\$(Configuration).$(Platform)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<TreatWarningAsError>true</TreatWarningAsError>
<AdditionalIncludeDirectories>../</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<TreatWarningAsError>true</TreatWarningAsError>
<AdditionalIncludeDirectories>../</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<BufferSecurityCheck>false</BufferSecurityCheck>
<TreatWarningAsError>true</TreatWarningAsError>
<AdditionalIncludeDirectories>../</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<BufferSecurityCheck>false</BufferSecurityCheck>
<TreatWarningAsError>true</TreatWarningAsError>
<AdditionalIncludeDirectories>../</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClInclude Include="kiwano-audio.h" />
<ClInclude Include="src\audio.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="src\audio-modules.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="src\Player.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="src\Sound.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="src\Transcoder.h">
<Filter>src</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\audio.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\audio-modules.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\Player.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\Sound.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\Transcoder.cpp">
<Filter>src</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="src">
<UniqueIdentifier>{331b453a-33de-4e2a-9c06-19a3fc9d43f3}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

140
kiwano-audio/src/Player.cpp Normal file
View File

@ -0,0 +1,140 @@
// Copyright (c) 2016-2018 Kiwano - 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 "../kiwano-audio.h"
#include "Player.h"
namespace kiwano
{
namespace audio
{
Player::Player()
: volume_(1.f)
{
}
Player::~Player()
{
ClearCache();
}
bool Player::Load(Resource const& res)
{
size_t hash_code = res.GetHashCode();
if (sound_cache_.end() != sound_cache_.find(hash_code))
return true;
SoundPtr sound = new (std::nothrow) Sound();
if (sound)
{
if (sound->Load(res))
{
sound->SetVolume(volume_);
sound_cache_.insert(std::make_pair(hash_code, sound));
return true;
}
}
return false;
}
void Player::Play(Resource const& res, int loop_count)
{
if (Load(res))
{
size_t hash_code = res.GetHashCode();
if (sound_cache_.end() != sound_cache_.find(hash_code))
sound_cache_[hash_code]->Play(loop_count);
}
}
void Player::Pause(Resource const& res)
{
size_t hash_code = res.GetHashCode();
if (sound_cache_.end() != sound_cache_.find(hash_code))
sound_cache_[hash_code]->Pause();
}
void Player::Resume(Resource const& res)
{
size_t hash_code = res.GetHashCode();
if (sound_cache_.end() != sound_cache_.find(hash_code))
sound_cache_[hash_code]->Resume();
}
void Player::Stop(Resource const& res)
{
size_t hash_code = res.GetHashCode();
if (sound_cache_.end() != sound_cache_.find(hash_code))
sound_cache_[hash_code]->Stop();
}
bool Player::IsPlaying(Resource const& res)
{
size_t hash_code = res.GetHashCode();
if (sound_cache_.end() != sound_cache_.find(hash_code))
return sound_cache_[hash_code]->IsPlaying();
return false;
}
float Player::GetVolume() const
{
return volume_;
}
void Player::SetVolume(float volume)
{
volume_ = std::min(std::max(volume, -224.f), 224.f);
for (const auto& pair : sound_cache_)
{
pair.second->SetVolume(volume_);
}
}
void Player::PauseAll()
{
for (const auto& pair : sound_cache_)
{
pair.second->Pause();
}
}
void Player::ResumeAll()
{
for (const auto& pair : sound_cache_)
{
pair.second->Resume();
}
}
void Player::StopAll()
{
for (const auto& pair : sound_cache_)
{
pair.second->Stop();
}
}
void Player::ClearCache()
{
sound_cache_.clear();
}
}
}

View File

@ -22,72 +22,75 @@
namespace kiwano
{
KGE_DECLARE_SMART_PTR(Player);
// 稜있꺄렴포
class KGE_API Player
: protected Object
namespace audio
{
using MusicMap = Map<size_t, SoundPtr>;
KGE_DECLARE_SMART_PTR(Player);
public:
Player();
// 稜있꺄렴포
class KGE_API Player
: protected Object
{
using MusicMap = Map<size_t, SoundPtr>;
~Player();
public:
Player();
// 渡속潼稜있栗都
bool Load(
Resource const& res /* 稜있栗都 */
);
~Player();
// 꺄렴稜있
void Play(
Resource const& res, /* 稜있栗都 */
int loop_count = 0 /* 꺄렴琦뻔늴鑒 (-1 槨琦뻔꺄렴) */
);
// 渡속潼稜있栗都
bool Load(
Resource const& res /* 稜있栗都 */
);
// 董界稜있
void Pause(
Resource const& res /* 稜있栗都 */
);
// 꺄렴稜있
void Play(
Resource const& res, /* 稜있栗都 */
int loop_count = 0 /* 꺄렴琦뻔늴鑒 (-1 槨琦뻔꺄렴) */
);
// 셨崎꺄렴稜있
void Resume(
Resource const& res /* 稜있栗都 */
);
// 董界稜있
void Pause(
Resource const& res /* 稜있栗都 */
);
// 界岺稜있
void Stop(
Resource const& res /* 稜있栗都 */
);
// 셨崎꺄렴稜있
void Resume(
Resource const& res /* 稜있栗都 */
);
// 삿혤稜있꺄렴榴檄
bool IsPlaying(
Resource const& res /* 稜있栗都 */
);
// 界岺稜있
void Stop(
Resource const& res /* 稜있栗都 */
);
// 삿혤稜좆
float GetVolume() const;
// 삿혤稜있꺄렴榴檄
bool IsPlaying(
Resource const& res /* 稜있栗都 */
);
// <20>零稜좆
void SetVolume(
float volume /* 1.0 槨覩迦稜좆 */
);
// 삿혤稜좆
float GetVolume() const;
// 董界杰唐稜있
void PauseAll();
// <20>零稜좆
void SetVolume(
float volume /* 1.0 槨覩迦稜좆 */
);
// 셨崎꺄렴杰唐稜있
void ResumeAll();
// 董界杰唐稜있
void PauseAll();
// 界岺杰唐稜있
void StopAll();
// 셨崎꺄렴杰唐稜있
void ResumeAll();
// 헌뇜뻠닸
void ClearCache();
// 界岺杰唐稜있
void StopAll();
protected:
float volume_;
MusicMap sound_cache_;
};
// 헌뇜뻠닸
void ClearCache();
protected:
float volume_;
MusicMap sound_cache_;
};
}
}

223
kiwano-audio/src/Sound.cpp Normal file
View File

@ -0,0 +1,223 @@
// Copyright (c) 2016-2018 Kiwano - 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 "../kiwano-audio.h"
#include "Sound.h"
#include "Transcoder.h"
namespace kiwano
{
namespace audio
{
Sound::Sound()
: opened_(false)
, playing_(false)
, size_(0)
, wave_data_(nullptr)
, voice_(nullptr)
{
}
Sound::Sound(Resource const& res)
: Sound()
{
Load(res);
}
Sound::~Sound()
{
Close();
}
bool Sound::Load(Resource const& res)
{
if (opened_)
{
Close();
}
HRESULT hr = S_OK;
Transcoder transcoder;
if (res.IsFileType())
{
#if defined(KGE_DEBUG)
if (!FileUtil::ExistsFile(res.GetFileName()))
{
KGE_WARNING_LOG(L"Media file '%s' not found", res.GetFileName().c_str());
return false;
}
#endif
hr = transcoder.LoadMediaFile(res.GetFileName(), &wave_data_, &size_);
}
else
{
hr = transcoder.LoadMediaResource(res, &wave_data_, &size_);
}
if (FAILED(hr))
{
KGE_ERROR_LOG(L"Load media file failed with HRESULT of %08X", hr);
return false;
}
hr = Audio::Instance().CreateVoice(&voice_, transcoder.GetWaveFormatEx());
if (FAILED(hr))
{
if (wave_data_)
{
delete[] wave_data_;
wave_data_ = nullptr;
}
KGE_ERROR_LOG(L"Create source voice failed with HRESULT of %08X", hr);
return false;
}
opened_ = true;
return true;
}
void Sound::Play(int loop_count)
{
if (!opened_)
{
KGE_ERROR_LOG(L"Sound must be opened first!");
return;
}
KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL");
// if sound stream is not empty, stop() will clear it
XAUDIO2_VOICE_STATE state;
voice_->GetState(&state);
if (state.BuffersQueued)
Stop();
// clamp loop count
loop_count = (loop_count < 0) ? XAUDIO2_LOOP_INFINITE : std::min(loop_count, XAUDIO2_LOOP_INFINITE - 1);
XAUDIO2_BUFFER buffer = { 0 };
buffer.pAudioData = wave_data_;
buffer.Flags = XAUDIO2_END_OF_STREAM;
buffer.AudioBytes = size_;
buffer.LoopCount = static_cast<UINT32>(loop_count);
HRESULT hr = voice_->SubmitSourceBuffer(&buffer);
if (SUCCEEDED(hr))
{
hr = voice_->Start();
}
if (FAILED(hr))
{
KGE_ERROR_LOG(L"Submitting source buffer failed with HRESULT of %08X", hr);
}
playing_ = SUCCEEDED(hr);
}
void Sound::Pause()
{
KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL");
if (SUCCEEDED(voice_->Stop()))
playing_ = false;
}
void Sound::Resume()
{
KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL");
if (SUCCEEDED(voice_->Start()))
playing_ = true;
}
void Sound::Stop()
{
KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL");
HRESULT hr = voice_->Stop();
if (SUCCEEDED(hr))
hr = voice_->ExitLoop();
if (SUCCEEDED(hr))
hr = voice_->FlushSourceBuffers();
if (SUCCEEDED(hr))
playing_ = false;
}
void Sound::Close()
{
if (voice_)
{
voice_->Stop();
voice_->FlushSourceBuffers();
voice_->DestroyVoice();
voice_ = nullptr;
}
if (wave_data_)
{
delete[] wave_data_;
wave_data_ = nullptr;
}
opened_ = false;
playing_ = false;
}
bool Sound::IsPlaying() const
{
if (opened_)
{
if (!voice_)
return false;
XAUDIO2_VOICE_STATE state;
voice_->GetState(&state);
UINT32 buffers_queued = state.BuffersQueued;
if (buffers_queued && playing_)
return true;
}
return false;
}
float Sound::GetVolume() const
{
KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL");
float volume = 0.0f;
voice_->GetVolume(&volume);
return volume;
}
void Sound::SetVolume(float volume)
{
KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL");
volume = std::min(std::max(volume, -224.f), 224.f);
voice_->SetVolume(volume);
}
}
}

View File

@ -23,59 +23,62 @@
namespace kiwano
{
KGE_DECLARE_SMART_PTR(Sound);
// 音乐对象
class KGE_API Sound
: public Object
namespace audio
{
public:
Sound();
KGE_DECLARE_SMART_PTR(Sound);
Sound(
Resource const& res /* 音乐资源 */
);
// 音乐对象
class KGE_API Sound
: public Object
{
public:
Sound();
virtual ~Sound();
Sound(
Resource const& res /* 音乐资源 */
);
// 打开音乐资源
bool Load(
Resource const& res /* 音乐资源 */
);
virtual ~Sound();
// 播放
void Play(
int loop_count = 0 /* 播放循环次数 (-1 为循环播放) */
);
// 打开音乐资源
bool Load(
Resource const& res /* 音乐资源 */
);
// 暂停
void Pause();
// 播放
void Play(
int loop_count = 0 /* 播放循环次数 (-1 为循环播放) */
);
// 继续
void Resume();
// 暂停
void Pause();
// 停止
void Stop();
// 继续
void Resume();
// 关闭并回收资源
void Close();
// 停止
void Stop();
// 是否正在播放
bool IsPlaying() const;
// 关闭并回收资源
void Close();
// 获取音量
float GetVolume() const;
// 是否正在播放
bool IsPlaying() const;
// 设置音量
void SetVolume(
float volume /* 1 为原始音量, 大于 1 为放大音量, 0 为最小音量 */
);
// 获取音量
float GetVolume() const;
protected:
bool opened_;
bool playing_;
UINT32 size_;
BYTE* wave_data_;
IXAudio2SourceVoice* voice_;
};
// 设置音量
void SetVolume(
float volume /* 1 为原始音量, 大于 1 为放大音量, 0 为最小音量 */
);
protected:
bool opened_;
bool playing_;
UINT32 size_;
BYTE* wave_data_;
IXAudio2SourceVoice* voice_;
};
}
}

View File

@ -0,0 +1,271 @@
// Copyright (c) 2016-2018 Kiwano - 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.
#ifndef INITGUID
# define INITGUID // MFAudioFormat_PCM, MF_MT_MAJOR_TYPE, MF_MT_SUBTYPE, MFMediaType_Audio
#endif
#include "../kiwano-audio.h"
#include "Transcoder.h"
#include "audio-modules.h"
namespace kiwano
{
namespace audio
{
Transcoder::Transcoder()
: wave_format_(nullptr)
{
}
Transcoder::~Transcoder()
{
if (wave_format_)
{
::CoTaskMemFree(wave_format_);
wave_format_ = nullptr;
}
}
const WAVEFORMATEX* Transcoder::GetWaveFormatEx() const
{
return wave_format_;
}
HRESULT Transcoder::LoadMediaFile(String const& file_path, BYTE** wave_data, UINT32* wave_data_size)
{
HRESULT hr = S_OK;
ComPtr<IMFSourceReader> reader;
hr = modules::MediaFoundation::Get().MFCreateSourceReaderFromURL(
file_path.c_str(),
nullptr,
&reader
);
if (SUCCEEDED(hr))
{
hr = ReadSource(reader.Get(), wave_data, wave_data_size);
}
return hr;
}
HRESULT Transcoder::LoadMediaResource(Resource const& res, BYTE** wave_data, UINT32* wave_data_size)
{
HRESULT hr = S_OK;
ComPtr<IStream> stream;
ComPtr<IMFByteStream> byte_stream;
ComPtr<IMFSourceReader> reader;
LPVOID buffer;
DWORD buffer_size;
if (!res.Load(buffer, buffer_size)) { return false; }
stream = kiwano::modules::Shlwapi::Get().SHCreateMemStream(
static_cast<const BYTE*>(buffer),
static_cast<UINT>(buffer_size)
);
if (stream == nullptr)
{
KGE_ERROR_LOG(L"SHCreateMemStream failed");
return E_OUTOFMEMORY;
}
if (SUCCEEDED(hr))
{
hr = modules::MediaFoundation::Get().MFCreateMFByteStreamOnStream(stream.Get(), &byte_stream);
}
if (SUCCEEDED(hr))
{
hr = modules::MediaFoundation::Get().MFCreateSourceReaderFromByteStream(
byte_stream.Get(),
nullptr,
&reader
);
}
if (SUCCEEDED(hr))
{
hr = ReadSource(reader.Get(), wave_data, wave_data_size);
}
return hr;
}
HRESULT Transcoder::ReadSource(IMFSourceReader* reader, BYTE** wave_data, UINT32* wave_data_size)
{
HRESULT hr = S_OK;
DWORD max_stream_size = 0;
ComPtr<IMFMediaType> partial_type;
ComPtr<IMFMediaType> uncompressed_type;
hr = modules::MediaFoundation::Get().MFCreateMediaType(&partial_type);
if (SUCCEEDED(hr))
{
hr = partial_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
}
if (SUCCEEDED(hr))
{
hr = partial_type->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM);
}
// 设置 source reader 的媒体类型,它将使用合适的解码器去解码这个音频
if (SUCCEEDED(hr))
{
hr = reader->SetCurrentMediaType(
(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,
0,
partial_type.Get()
);
}
// 从 IMFMediaType 中获取 WAVEFORMAT 结构
if (SUCCEEDED(hr))
{
hr = reader->GetCurrentMediaType(
(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,
&uncompressed_type
);
}
// 指定音频流
if (SUCCEEDED(hr))
{
hr = reader->SetStreamSelection(
(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,
true
);
}
// 获取 WAVEFORMAT 数据
if (SUCCEEDED(hr))
{
UINT32 size = 0;
hr = modules::MediaFoundation::Get().MFCreateWaveFormatExFromMFMediaType(
uncompressed_type.Get(),
&wave_format_,
&size,
(DWORD)MFWaveFormatExConvertFlag_Normal
);
}
// 估算音频流大小
if (SUCCEEDED(hr))
{
PROPVARIANT prop;
PropVariantInit(&prop);
hr = reader->GetPresentationAttribute(
(DWORD)MF_SOURCE_READER_MEDIASOURCE,
MF_PD_DURATION,
&prop
);
LONGLONG duration = prop.uhVal.QuadPart;
max_stream_size = static_cast<DWORD>(
(duration * wave_format_->nAvgBytesPerSec) / 10000000 + 1
);
PropVariantClear(&prop);
}
// 读取音频数据
if (SUCCEEDED(hr))
{
DWORD flags = 0;
DWORD position = 0;
BYTE* data = new (std::nothrow) BYTE[max_stream_size];
ComPtr<IMFSample> sample;
ComPtr<IMFMediaBuffer> buffer;
if (data == nullptr)
{
KGE_ERROR_LOG(L"Low memory");
hr = E_OUTOFMEMORY;
}
else
{
while (true)
{
hr = reader->ReadSample(
(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,
0,
nullptr,
&flags,
nullptr,
&sample
);
if (flags & MF_SOURCE_READERF_ENDOFSTREAM) { break; }
if (sample == nullptr) { continue; }
if (SUCCEEDED(hr))
{
hr = sample->ConvertToContiguousBuffer(&buffer);
if (SUCCEEDED(hr))
{
BYTE* audio_data = nullptr;
DWORD sample_buffer_length = 0;
hr = buffer->Lock(
&audio_data,
nullptr,
&sample_buffer_length
);
if (SUCCEEDED(hr))
{
for (DWORD i = 0; i < sample_buffer_length; i++)
{
data[position++] = audio_data[i];
}
hr = buffer->Unlock();
}
}
buffer = nullptr;
}
sample = nullptr;
if (FAILED(hr)) { break; }
}
if (SUCCEEDED(hr))
{
*wave_data = data;
*wave_data_size = position;
}
}
}
return hr;
}
}
}

View File

@ -25,33 +25,38 @@
namespace kiwano
{
class KGE_API Transcoder
namespace audio
{
WAVEFORMATEX* wave_format_;
public:
Transcoder();
class KGE_API Transcoder
{
public:
Transcoder();
~Transcoder();
~Transcoder();
const WAVEFORMATEX* GetWaveFormatEx() const;
const WAVEFORMATEX* GetWaveFormatEx() const;
HRESULT LoadMediaFile(
String const& file_path,
BYTE** wave_data,
UINT32* wave_data_size
);
HRESULT LoadMediaFile(
String const& file_path,
BYTE** wave_data,
UINT32* wave_data_size
);
HRESULT LoadMediaResource(
Resource const& res,
BYTE** wave_data,
UINT32* wave_data_size
);
HRESULT LoadMediaResource(
Resource const& res,
BYTE** wave_data,
UINT32* wave_data_size
);
HRESULT ReadSource(
IMFSourceReader* reader,
BYTE** wave_data,
UINT32* wave_data_size
);
};
HRESULT ReadSource(
IMFSourceReader* reader,
BYTE** wave_data,
UINT32* wave_data_size
);
private:
WAVEFORMATEX* wave_format_;
};
}
}

View File

@ -0,0 +1,100 @@
// Copyright (c) 2016-2018 Kiwano - 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 "../kiwano-audio.h"
#include "audio-modules.h"
namespace kiwano
{
namespace audio
{
namespace modules
{
XAudio2::XAudio2()
{
const auto xaudio2_dll_names =
{
L"xaudio2_9.dll", // for Windows 10
L"xaudio2_8.dll", // for Windows 8
L"xaudio2_7.dll" // for DirectX SDK
};
for (const auto& name : xaudio2_dll_names)
{
xaudio2 = LoadLibraryW(name);
if (xaudio2)
{
XAudio2Create = (PFN_XAudio2Create)
GetProcAddress(xaudio2, "XAudio2Create");
break;
}
}
if (!xaudio2)
{
KGE_ERROR_LOG(L"Load xaudio2.dll failed");
throw std::runtime_error("Load xaudio2.dll failed");
}
}
MediaFoundation::MediaFoundation()
{
mfplat = LoadLibraryW(L"Mfplat.dll");
if (mfplat)
{
MFStartup = (PFN_MFStartup)
GetProcAddress(mfplat, "MFStartup");
MFShutdown = (PFN_MFShutdown)
GetProcAddress(mfplat, "MFShutdown");
MFCreateMediaType = (PFN_MFCreateMediaType)
GetProcAddress(mfplat, "MFCreateMediaType");
MFCreateWaveFormatExFromMFMediaType = (PFN_MFCreateWaveFormatExFromMFMediaType)
GetProcAddress(mfplat, "MFCreateWaveFormatExFromMFMediaType");
MFCreateMFByteStreamOnStream = (PFN_MFCreateMFByteStreamOnStream)
GetProcAddress(mfplat, "MFCreateMFByteStreamOnStream");
}
else
{
KGE_LOG(L"Load Mfplat.dll failed");
throw std::runtime_error("Load Mfplat.dll failed");
}
mfreadwrite = LoadLibraryW(L"Mfreadwrite.dll");
if (mfreadwrite)
{
MFCreateSourceReaderFromURL = (PFN_MFCreateSourceReaderFromURL)
GetProcAddress(mfreadwrite, "MFCreateSourceReaderFromURL");
MFCreateSourceReaderFromByteStream = (PFN_MFCreateSourceReaderFromByteStream)
GetProcAddress(mfreadwrite, "MFCreateSourceReaderFromByteStream");
}
else
{
KGE_LOG(L"Load Mfreadwrite.dll failed");
throw std::runtime_error("Load Mfreadwrite.dll failed");
}
}
}
}
}

View File

@ -0,0 +1,86 @@
// Copyright (c) 2016-2018 Kiwano - 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.
#pragma once
#include <xaudio2.h>
#include <mfapi.h>
#include <mfidl.h>
#include <mfreadwrite.h>
namespace kiwano
{
namespace audio
{
namespace modules
{
class KGE_API XAudio2
{
XAudio2();
HMODULE xaudio2;
// XAudio2 functions
typedef HRESULT(WINAPI* PFN_XAudio2Create)(IXAudio2**, UINT32, XAUDIO2_PROCESSOR);
public:
static inline XAudio2& Get()
{
static XAudio2 instance;
return instance;
}
PFN_XAudio2Create XAudio2Create;
};
class KGE_API MediaFoundation
{
MediaFoundation();
HMODULE mfplat;
HMODULE mfreadwrite;
// MediaFoundation functions
typedef HRESULT(WINAPI* PFN_MFStartup)(ULONG, DWORD);
typedef HRESULT(WINAPI* PFN_MFShutdown)();
typedef HRESULT(WINAPI* PFN_MFCreateMediaType)(IMFMediaType**);
typedef HRESULT(WINAPI* PFN_MFCreateWaveFormatExFromMFMediaType)(IMFMediaType*, WAVEFORMATEX**, UINT32*, UINT32);
typedef HRESULT(WINAPI* PFN_MFCreateSourceReaderFromURL)(LPCWSTR, IMFAttributes*, IMFSourceReader**);
typedef HRESULT(WINAPI* PFN_MFCreateSourceReaderFromByteStream)(IMFByteStream*, IMFAttributes*, IMFSourceReader**);
typedef HRESULT(WINAPI* PFN_MFCreateMFByteStreamOnStream)(IStream*, IMFByteStream**);
public:
static inline MediaFoundation& Get()
{
static MediaFoundation instance;
return instance;
}
PFN_MFStartup MFStartup;
PFN_MFShutdown MFShutdown;
PFN_MFCreateMediaType MFCreateMediaType;
PFN_MFCreateWaveFormatExFromMFMediaType MFCreateWaveFormatExFromMFMediaType;
PFN_MFCreateSourceReaderFromURL MFCreateSourceReaderFromURL;
PFN_MFCreateSourceReaderFromByteStream MFCreateSourceReaderFromByteStream;
PFN_MFCreateMFByteStreamOnStream MFCreateMFByteStreamOnStream;
};
}
}
}

View File

@ -24,73 +24,75 @@
namespace kiwano
{
Audio::Audio()
: x_audio2_(nullptr)
, mastering_voice_(nullptr)
namespace audio
{
}
Audio::~Audio()
{
}
void Audio::SetupComponent(Application*)
{
KGE_LOG(L"Creating audio resources");
HRESULT hr = modules::MediaFoundation::Get().MFStartup(MF_VERSION, MFSTARTUP_FULL);
if (SUCCEEDED(hr))
Audio::Audio()
: x_audio2_(nullptr)
, mastering_voice_(nullptr)
{
hr = modules::XAudio2::Get().XAudio2Create(&x_audio2_, 0, XAUDIO2_DEFAULT_PROCESSOR);
}
if (SUCCEEDED(hr))
Audio::~Audio()
{
hr = x_audio2_->CreateMasteringVoice(&mastering_voice_);
}
ThrowIfFailed(hr);
}
void Audio::DestroyComponent()
{
KGE_LOG(L"Destroying audio resources");
if (mastering_voice_)
void Audio::SetupComponent(Application*)
{
mastering_voice_->DestroyVoice();
mastering_voice_ = nullptr;
KGE_LOG(L"Creating audio resources");
HRESULT hr = modules::MediaFoundation::Get().MFStartup(MF_VERSION, MFSTARTUP_FULL);
if (SUCCEEDED(hr))
{
hr = modules::XAudio2::Get().XAudio2Create(&x_audio2_, 0, XAUDIO2_DEFAULT_PROCESSOR);
}
if (SUCCEEDED(hr))
{
hr = x_audio2_->CreateMasteringVoice(&mastering_voice_);
}
ThrowIfFailed(hr);
}
if (x_audio2_)
void Audio::DestroyComponent()
{
x_audio2_->Release();
x_audio2_ = nullptr;
KGE_LOG(L"Destroying audio resources");
if (mastering_voice_)
{
mastering_voice_->DestroyVoice();
mastering_voice_ = nullptr;
}
if (x_audio2_)
{
x_audio2_->Release();
x_audio2_ = nullptr;
}
modules::MediaFoundation::Get().MFShutdown();
}
modules::MediaFoundation::Get().MFShutdown();
}
HRESULT Audio::CreateVoice(IXAudio2SourceVoice** voice, const WAVEFORMATEX* wfx)
{
if (voice == nullptr)
HRESULT Audio::CreateVoice(IXAudio2SourceVoice** voice, const WAVEFORMATEX* wfx)
{
return E_UNEXPECTED;
if (voice == nullptr)
{
return E_UNEXPECTED;
}
HRESULT hr = x_audio2_->CreateSourceVoice(voice, wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO);
return hr;
}
HRESULT hr = x_audio2_->CreateSourceVoice(voice, wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO);
return hr;
}
void Audio::Open()
{
x_audio2_->StartEngine();
}
void Audio::Open()
{
x_audio2_->StartEngine();
void Audio::Close()
{
x_audio2_->StopEngine();
}
}
void Audio::Close()
{
x_audio2_->StopEngine();
}
}

View File

@ -22,35 +22,38 @@
namespace kiwano
{
class KGE_API Audio
: public Singleton<Audio>
, public Component
namespace audio
{
KGE_DECLARE_SINGLETON(Audio);
class KGE_API Audio
: public Singleton<Audio>
, public Component
{
KGE_DECLARE_SINGLETON(Audio);
public:
void SetupComponent(Application*) override;
public:
void SetupComponent(Application*) override;
void DestroyComponent() override;
void DestroyComponent() override;
// 开启设备
void Open();
// 开启设备
void Open();
// 关闭设备
void Close();
// 关闭设备
void Close();
HRESULT CreateVoice(
IXAudio2SourceVoice** voice,
const WAVEFORMATEX* wfx
);
HRESULT CreateVoice(
IXAudio2SourceVoice** voice,
const WAVEFORMATEX* wfx
);
protected:
Audio();
protected:
Audio();
~Audio();
~Audio();
protected:
IXAudio2* x_audio2_;
IXAudio2MasteringVoice* mastering_voice_;
};
protected:
IXAudio2* x_audio2_;
IXAudio2MasteringVoice* mastering_voice_;
};
}
}

View File

@ -19,10 +19,10 @@
// THE SOFTWARE.
#pragma once
#include "kiwano.h"
#include "kiwano/kiwano.h"
#include "imgui/ImGuiLayer.h"
#include "imgui/ImGuiView.h"
#include "src/ImGuiLayer.h"
#include "src/ImGuiView.h"
// ImGui
#include "third-party/ImGui/imgui.h"

View File

@ -0,0 +1,195 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClInclude Include="kiwano-imgui.h" />
<ClInclude Include="src\ImGuiLayer.h" />
<ClInclude Include="src\ImGuiView.h" />
<ClInclude Include="src\imgui_impl.hpp" />
<ClInclude Include="src\imgui_impl_dx10.h" />
<ClInclude Include="src\imgui_impl_dx11.h" />
<ClInclude Include="third-party\ImGui\imconfig.h" />
<ClInclude Include="third-party\ImGui\imgui.h" />
<ClInclude Include="third-party\ImGui\imgui_internal.h" />
<ClInclude Include="third-party\ImGui\imstb_rectpack.h" />
<ClInclude Include="third-party\ImGui\imstb_textedit.h" />
<ClInclude Include="third-party\ImGui\imstb_truetype.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\ImGuiLayer.cpp" />
<ClCompile Include="src\ImGuiView.cpp" />
<ClCompile Include="src\imgui_impl_dx10.cpp" />
<ClCompile Include="src\imgui_impl_dx11.cpp" />
<ClCompile Include="third-party\ImGui\imgui.cpp" />
<ClCompile Include="third-party\ImGui\imgui_demo.cpp" />
<ClCompile Include="third-party\ImGui\imgui_draw.cpp" />
<ClCompile Include="third-party\ImGui\imgui_widgets.cpp" />
</ItemGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{A7062ED8-8910-48A5-A3BC-C1612672571F}</ProjectGuid>
<RootNamespace>kiwano-imgui</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(ProjectDir)\output\$(Configuration).$(Platform)\</OutDir>
<IntDir>$(ProjectDir)\build\$(Configuration).$(Platform)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(ProjectDir)\output\$(Configuration).$(Platform)\</OutDir>
<IntDir>$(ProjectDir)\build\$(Configuration).$(Platform)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(ProjectDir)\output\$(Configuration).$(Platform)\</OutDir>
<IntDir>$(ProjectDir)\build\$(Configuration).$(Platform)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(ProjectDir)\output\$(Configuration).$(Platform)\</OutDir>
<IntDir>$(ProjectDir)\build\$(Configuration).$(Platform)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<TreatWarningAsError>true</TreatWarningAsError>
<AdditionalIncludeDirectories>../</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<TreatWarningAsError>true</TreatWarningAsError>
<AdditionalIncludeDirectories>../</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<BufferSecurityCheck>false</BufferSecurityCheck>
<TreatWarningAsError>true</TreatWarningAsError>
<AdditionalIncludeDirectories>../</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<BufferSecurityCheck>false</BufferSecurityCheck>
<TreatWarningAsError>true</TreatWarningAsError>
<AdditionalIncludeDirectories>../</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="src">
<UniqueIdentifier>{ed21cd51-048d-4bbc-804a-d09a8afa1423}</UniqueIdentifier>
</Filter>
<Filter Include="third-party">
<UniqueIdentifier>{f737b6d4-4462-49c1-8e9d-5c834bed598f}</UniqueIdentifier>
</Filter>
<Filter Include="third-party\ImGui">
<UniqueIdentifier>{5b9d2eaa-0247-4ef5-8410-3221821b1221}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\imgui_impl.hpp">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="src\imgui_impl_dx10.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="src\imgui_impl_dx11.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="src\ImGuiLayer.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="src\ImGuiView.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="third-party\ImGui\imconfig.h">
<Filter>third-party\ImGui</Filter>
</ClInclude>
<ClInclude Include="third-party\ImGui\imgui.h">
<Filter>third-party\ImGui</Filter>
</ClInclude>
<ClInclude Include="third-party\ImGui\imgui_internal.h">
<Filter>third-party\ImGui</Filter>
</ClInclude>
<ClInclude Include="third-party\ImGui\imstb_rectpack.h">
<Filter>third-party\ImGui</Filter>
</ClInclude>
<ClInclude Include="third-party\ImGui\imstb_textedit.h">
<Filter>third-party\ImGui</Filter>
</ClInclude>
<ClInclude Include="third-party\ImGui\imstb_truetype.h">
<Filter>third-party\ImGui</Filter>
</ClInclude>
<ClInclude Include="kiwano-imgui.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\imgui_impl_dx10.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\imgui_impl_dx11.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\ImGuiLayer.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="src\ImGuiView.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="third-party\ImGui\imgui.cpp">
<Filter>third-party\ImGui</Filter>
</ClCompile>
<ClCompile Include="third-party\ImGui\imgui_demo.cpp">
<Filter>third-party\ImGui</Filter>
</ClCompile>
<ClCompile Include="third-party\ImGui\imgui_draw.cpp">
<Filter>third-party\ImGui</Filter>
</ClCompile>
<ClCompile Include="third-party\ImGui\imgui_widgets.cpp">
<Filter>third-party\ImGui</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,188 @@
// Copyright (c) 2016-2018 Kiwano - 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 "../kiwano-imgui.h"
namespace kiwano
{
namespace imgui
{
namespace
{
Map<int, int> mouse_buttons =
{
{ MouseButton::Left, 0 },
{ MouseButton::Right, 1 },
{ MouseButton::Middle, 2 }
};
}
ImGuiLayer::ImGuiLayer()
{
target_window_ = Renderer::Instance().GetTargetWindow();
SetSwallowEvents(true);
}
ImGuiLayer::~ImGuiLayer()
{
ImGuiView::Instance().RemoveLayer(this);
}
void ImGuiLayer::OnMouseButtonDown(int btn, Point const& p)
{
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == nullptr)
::SetCapture(target_window_);
KGE_ASSERT(mouse_buttons.find(btn) != mouse_buttons.end());
ImGui::GetIO().MouseDown[mouse_buttons[btn]] = true;
}
void ImGuiLayer::OnMouseButtonUp(int btn, Point const& p)
{
KGE_ASSERT(mouse_buttons.find(btn) != mouse_buttons.end());
ImGui::GetIO().MouseDown[mouse_buttons[btn]] = false;
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == target_window_)
::ReleaseCapture();
}
void ImGuiLayer::OnMouseWheel(float wheel)
{
ImGui::GetIO().MouseWheel += wheel;
}
void ImGuiLayer::OnKeyDown(int key)
{
KGE_ASSERT(key < 256);
ImGui::GetIO().KeysDown[key] = 1;
}
void ImGuiLayer::OnKeyUp(int key)
{
KGE_ASSERT(key < 256);
ImGui::GetIO().KeysDown[key] = 0;
}
void ImGuiLayer::OnChar(char c)
{
ImGui::GetIO().AddInputCharacter(c);
}
void ImGuiLayer::OnUpdate(Duration dt)
{
ImGuiIO& io = ImGui::GetIO();
// Setup time step
io.DeltaTime = dt.Seconds();
// Read keyboard modifiers inputs
io.KeyCtrl = Input::Instance().IsDown(KeyCode::Ctrl);
io.KeyShift = Input::Instance().IsDown(KeyCode::Shift);
io.KeyAlt = Input::Instance().IsDown(KeyCode::Alt);
io.KeySuper = false;
// io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below.
// Update OS mouse position
UpdateMousePos();
// Update OS mouse cursor with the cursor requested by imgui
UpdateMouseCursor();
}
void ImGuiLayer::OnRender()
{
ImGuiView::Instance().NewFrame();
for (const auto& pipeline : pipelines_)
{
pipeline.second();
}
ImGuiView::Instance().Render();
}
void ImGuiLayer::UpdateMousePos()
{
ImGuiIO& io = ImGui::GetIO();
// Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
if (io.WantSetMousePos)
{
POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
HWND hwnd = target_window_;
::ClientToScreen(hwnd, &pos);
::SetCursorPos(pos.x, pos.y);
}
Point pos = Input::Instance().GetMousePos();
io.MousePos = ImVec2(pos.x, pos.y);
}
void ImGuiLayer::UpdateMouseCursor()
{
static ImGuiMouseCursor last_mouse_cursor = ImGuiMouseCursor_COUNT;
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
if (last_mouse_cursor != imgui_cursor)
{
last_mouse_cursor = imgui_cursor;
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
return;
MouseCursor cursor = MouseCursor::Arrow;
switch (imgui_cursor)
{
case ImGuiMouseCursor_Arrow: cursor = MouseCursor::Arrow; break;
case ImGuiMouseCursor_TextInput: cursor = MouseCursor::TextInput; break;
case ImGuiMouseCursor_ResizeAll: cursor = MouseCursor::SizeAll; break;
case ImGuiMouseCursor_ResizeEW: cursor = MouseCursor::SizeWE; break;
case ImGuiMouseCursor_ResizeNS: cursor = MouseCursor::SizeNS; break;
case ImGuiMouseCursor_ResizeNESW: cursor = MouseCursor::SizeNESW; break;
case ImGuiMouseCursor_ResizeNWSE: cursor = MouseCursor::SizeNWSE; break;
case ImGuiMouseCursor_Hand: cursor = MouseCursor::Hand; break;
}
GetScene()->SetMouseCursor(cursor);
}
}
void ImGuiLayer::AddItem(ImGuiPipeline const& item, String const& name)
{
pipelines_.insert(std::make_pair(name, item));
}
void ImGuiLayer::RemoveItem(String const& name)
{
auto iter = pipelines_.find(name);
if (iter != pipelines_.end())
{
pipelines_.erase(iter);
}
}
void ImGuiLayer::RemoveAllItems()
{
pipelines_.clear();
}
}
}

View File

@ -22,55 +22,58 @@
namespace kiwano
{
class ImGuiView;
KGE_DECLARE_SMART_PTR(ImGuiLayer);
using ImGuiPipeline = Closure<void()>;
class ImGuiLayer
: public Layer
namespace imgui
{
friend class ImGuiView;
KGE_DECLARE_SMART_PTR(ImGuiLayer);
public:
virtual ~ImGuiLayer();
using ImGuiPipeline = Closure<void()>;
// 添加 ImGui 元素
void AddItem(
ImGuiPipeline const& item,
String const& name
);
class ImGuiView;
// 移除 ImGui 元素
void RemoveItem(
String const& name
);
class ImGuiLayer
: public Layer
{
friend class ImGuiView;
// 移除所有元素
void RemoveAllItems();
public:
virtual ~ImGuiLayer();
public:
void OnMouseButtonDown(int btn, Point const& p) override;
void OnMouseButtonUp(int btn, Point const& p) override;
void OnMouseWheel(float wheel) override;
// 添加 ImGui 元素
void AddItem(
ImGuiPipeline const& item,
String const& name
);
void OnKeyDown(int key) override;
void OnKeyUp(int key) override;
void OnChar(char c) override;
// 移除 ImGui 元素
void RemoveItem(
String const& name
);
public:
void OnUpdate(Duration dt) override;
void OnRender() override;
// 移除所有元素
void RemoveAllItems();
void UpdateMousePos();
void UpdateMouseCursor();
public:
void OnMouseButtonDown(int btn, Point const& p) override;
void OnMouseButtonUp(int btn, Point const& p) override;
void OnMouseWheel(float wheel) override;
protected:
ImGuiLayer();
void OnKeyDown(int key) override;
void OnKeyUp(int key) override;
void OnChar(char c) override;
protected:
HWND target_window_;
Map<String, ImGuiPipeline> pipelines_;
};
public:
void OnUpdate(Duration dt) override;
void OnRender() override;
void UpdateMousePos();
void UpdateMouseCursor();
protected:
ImGuiLayer();
protected:
HWND target_window_;
Map<String, ImGuiPipeline> pipelines_;
};
}
}

View File

@ -0,0 +1,117 @@
// Copyright (C) 2019 Nomango
#include "../kiwano-imgui.h"
#include "imgui_impl.hpp"
namespace kiwano
{
namespace imgui
{
void ImGuiView::SetupComponent(Application* app)
{
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
Init(app->GetWindow()->GetHandle());
}
void ImGuiView::DestroyComponent()
{
ImGui_Impl_Shutdown();
ImGui::DestroyContext();
}
void ImGuiView::Init(HWND hwnd)
{
ImGuiIO& io = ImGui::GetIO();
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
io.BackendPlatformName = "imgui_impl_win32";
io.ImeWindowHandle = hwnd;
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime.
io.KeyMap[ImGuiKey_Tab] = KeyCode::Tab;
io.KeyMap[ImGuiKey_LeftArrow] = KeyCode::Left;
io.KeyMap[ImGuiKey_RightArrow] = KeyCode::Right;
io.KeyMap[ImGuiKey_UpArrow] = KeyCode::Up;
io.KeyMap[ImGuiKey_DownArrow] = KeyCode::Down;
io.KeyMap[ImGuiKey_Delete] = KeyCode::Delete;
io.KeyMap[ImGuiKey_Backspace] = KeyCode::Back;
io.KeyMap[ImGuiKey_Space] = KeyCode::Space;
io.KeyMap[ImGuiKey_Enter] = KeyCode::Enter;
io.KeyMap[ImGuiKey_Escape] = KeyCode::Esc;
io.KeyMap[ImGuiKey_A] = KeyCode::A;
io.KeyMap[ImGuiKey_C] = KeyCode::C;
io.KeyMap[ImGuiKey_V] = KeyCode::V;
io.KeyMap[ImGuiKey_X] = KeyCode::X;
io.KeyMap[ImGuiKey_Y] = KeyCode::Y;
io.KeyMap[ImGuiKey_Z] = KeyCode::Z;
ImGui_Impl_Init(
Renderer::Instance()
);
}
void ImGuiView::NewFrame()
{
ImGui_Impl_NewFrame();
ImGuiIO& io = ImGui::GetIO();
KGE_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built!");
// Setup display size (every frame to accommodate for window resizing)
Size display_size = Renderer::Instance().GetOutputSize();
io.DisplaySize = ImVec2(display_size.x, display_size.y);
ImGui::NewFrame();
}
void ImGuiView::Render()
{
ImGui::Render();
ImGui_Impl_RenderDrawData(ImGui::GetDrawData());
}
ImGuiLayerPtr ImGuiView::CreateLayer(Scene* scene)
{
auto iter = layers_.find(scene);
if (iter == layers_.end())
{
ImGuiLayerPtr layer = new (std::nothrow) ImGuiLayer;
if (layer)
{
layers_.insert(std::make_pair(scene, layer.Get()));
}
return layer;
}
else
{
return iter->second;
}
}
void ImGuiView::RemoveLayer(ImGuiLayer* layer)
{
using value_type = Map<Scene*, Layer*>::value_type;
auto iter = std::find_if(layers_.begin(), layers_.end(), [=](value_type const& value)
{
return value.second == layer;
});
if (iter != layers_.end())
{
layers_.erase(iter);
}
}
}
}

View File

@ -22,38 +22,40 @@
namespace kiwano
{
class ImGuiLayer;
class ImGuiView
: public Singleton<ImGuiView>
, public Component
namespace imgui
{
KGE_DECLARE_SINGLETON(ImGuiView);
class ImGuiLayer;
friend class ImGuiLayer;
class ImGuiView
: public Singleton<ImGuiView>
, public Component
{
KGE_DECLARE_SINGLETON(ImGuiView);
public:
// ´´½¨ ImGui ͼ²ã
ImGuiLayerPtr CreateLayer(
Scene* scene /* Ö¸¶¨³¡¾° */
);
friend class ImGuiLayer;
private:
void Init(HWND hwnd);
public:
// ´´½¨ ImGui ͼ²ã
ImGuiLayerPtr CreateLayer(
Scene* scene /* Ö¸¶¨³¡¾° */
);
void NewFrame();
private:
void Init(HWND hwnd);
void Render();
void NewFrame();
void RemoveLayer(ImGuiLayer* layer);
void Render();
public:
void SetupComponent(Application* app) override;
void RemoveLayer(ImGuiLayer* layer);
void DestroyComponent() override;
public:
void SetupComponent(Application* app) override;
private:
Map<Scene*, ImGuiLayer*> layers_;
};
void DestroyComponent() override;
private:
Map<Scene*, ImGuiLayer*> layers_;
};
}
}

View File

@ -19,12 +19,12 @@
// THE SOFTWARE.
#pragma once
#include "kiwano.h"
#include "kiwano/kiwano.h"
#include "network/helper.h"
#include "network/HttpRequest.h"
#include "network/HttpResponse.h"
#include "network/HttpClient.h"
#include "src/helper.h"
#include "src/HttpRequest.h"
#include "src/HttpResponse.h"
#include "src/HttpClient.h"
// CURL
#include "third-party/curl/curl.h"

View File

@ -0,0 +1,184 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClInclude Include="kiwano-network.h" />
<ClInclude Include="src\helper.h" />
<ClInclude Include="src\HttpClient.h" />
<ClInclude Include="src\HttpRequest.h" />
<ClInclude Include="src\HttpResponse.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\HttpClient.cpp" />
</ItemGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<Library Include="third-party\libs\libcurl.lib" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{69DFBE92-C06F-4CF8-9495-CA9BF2E3BAF2}</ProjectGuid>
<RootNamespace>kiwano-network</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(ProjectDir)\output\$(Configuration).$(Platform)\</OutDir>
<IntDir>$(ProjectDir)\build\$(Configuration).$(Platform)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IntDir>$(ProjectDir)\build\$(Configuration).$(Platform)\</IntDir>
<OutDir>$(ProjectDir)\output\$(Configuration).$(Platform)\</OutDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(ProjectDir)\output\$(Configuration).$(Platform)\</OutDir>
<IntDir>$(ProjectDir)\build\$(Configuration).$(Platform)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IntDir>$(ProjectDir)\build\$(Configuration).$(Platform)\</IntDir>
<OutDir>$(ProjectDir)\output\$(Configuration).$(Platform)\</OutDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<TreatWarningAsError>true</TreatWarningAsError>
<AdditionalIncludeDirectories>../</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<TreatWarningAsError>true</TreatWarningAsError>
<AdditionalIncludeDirectories>../</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<BufferSecurityCheck>false</BufferSecurityCheck>
<TreatWarningAsError>true</TreatWarningAsError>
<AdditionalIncludeDirectories>../</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<BufferSecurityCheck>false</BufferSecurityCheck>
<TreatWarningAsError>true</TreatWarningAsError>
<AdditionalIncludeDirectories>../</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClInclude Include="kiwano-network.h" />
<ClInclude Include="src\helper.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="src\HttpClient.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="src\HttpRequest.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="src\HttpResponse.h">
<Filter>src</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="src">
<UniqueIdentifier>{702f4435-7612-4ce6-86c8-744d1868c19a}</UniqueIdentifier>
</Filter>
<Filter Include="libs">
<UniqueIdentifier>{4b536a1f-2907-4b85-baad-074d7274a5eb}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\HttpClient.cpp">
<Filter>src</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Library Include="third-party\libs\libcurl.lib">
<Filter>libs</Filter>
</Library>
</ItemGroup>
</Project>

View File

@ -25,8 +25,6 @@
// CURL
#include "../third-party/curl/curl.h"
#pragma comment(lib, "libcurl.lib")
namespace
{
using namespace kiwano;

Some files were not shown because too many files have changed in this diff Show More