Use UTF-8 exclusively internally; update logvisor

This commit is contained in:
Luke Street 2021-06-22 17:21:21 -04:00
parent 542191fd70
commit 4265e9d801
28 changed files with 238 additions and 240 deletions

4
.gitignore vendored
View File

@ -1 +1,5 @@
.DS_Store .DS_Store
.idea/
cmake-build-*/
build/
out/

View File

@ -2,10 +2,72 @@ cmake_minimum_required(VERSION 3.10 FATAL_ERROR) # because of c++17
project(boo) project(boo)
cmake_policy(SET CMP0074 NEW) cmake_policy(SET CMP0074 NEW)
if (NOT MSVC) if (MSVC)
# Shaddup MSVC
add_compile_definitions(UNICODE=1 _UNICODE=1 __SSE__=1
_CRT_SECURE_NO_WARNINGS=1 D_SCL_SECURE_NO_WARNINGS=1
_SCL_SECURE_NO_DEPRECATE=1 _CRT_NONSTDC_NO_WARNINGS=1
_ENABLE_EXTENDED_ALIGNED_STORAGE=1 NOMINMAX=1)
add_compile_options(/IGNORE:4221
$<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/wd4018>
$<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/wd4800>
$<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/wd4005>
$<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/wd4311>
$<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/wd4068>
$<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/wd4267>
$<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/wd4244>
$<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/wd4200>
$<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/wd4305>
$<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/wd4067>
$<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/wd4146>
$<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/wd4309>
$<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/wd4805>
${VS_OPTIONS})
string(REPLACE "/GR " "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REPLACE " /EHsc" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
add_compile_options(
# Disable exceptions
$<$<COMPILE_LANGUAGE:CXX>:/EHsc->
# Disable RTTI
$<$<COMPILE_LANGUAGE:CXX>:/GR->
# Enforce various standards compliant behavior.
$<$<COMPILE_LANGUAGE:CXX>:/permissive->
# Enable standard volatile semantics.
$<$<COMPILE_LANGUAGE:CXX>:/volatile:iso>
# Reports the proper value for the __cplusplus preprocessor macro.
$<$<COMPILE_LANGUAGE:CXX>:/Zc:__cplusplus>
# Use latest C++ standard.
$<$<COMPILE_LANGUAGE:CXX>:/std:c++latest>
)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# Flags for MSVC (not clang-cl)
add_compile_options(
# Allow constexpr variables to have explicit external linkage.
$<$<COMPILE_LANGUAGE:CXX>:/Zc:externConstexpr>
# Assume that new throws exceptions, allowing better code generation.
$<$<COMPILE_LANGUAGE:CXX>:/Zc:throwingNew>
# Link-time Code Generation for Release builds
$<$<CONFIG:Release>:/GL>
)
# Link-time Code Generation for Release builds
set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "/LTCG")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO")
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/DEBUG /RELEASE /OPT:REF /OPT:ICF /INCREMENTAL:NO /DEBUGTYPE:cv,fixup")
endif ()
else ()
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif() endif ()
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}") set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}")

View File

@ -14,7 +14,7 @@ class IApplication;
struct IApplicationCallback { struct IApplicationCallback {
virtual int appMain(IApplication*) = 0; virtual int appMain(IApplication*) = 0;
virtual void appQuitting(IApplication*) = 0; virtual void appQuitting(IApplication*) = 0;
virtual void appFilesOpen(IApplication*, const std::vector<SystemString>&) {} virtual void appFilesOpen(IApplication*, const std::vector<std::string>&) {}
}; };
class IApplication { class IApplication {
@ -44,28 +44,28 @@ public:
virtual EPlatformType getPlatformType() const = 0; virtual EPlatformType getPlatformType() const = 0;
virtual int run() = 0; virtual int run() = 0;
virtual SystemStringView getUniqueName() const = 0; virtual std::string_view getUniqueName() const = 0;
virtual SystemStringView getFriendlyName() const = 0; virtual std::string_view getFriendlyName() const = 0;
virtual SystemStringView getProcessName() const = 0; virtual std::string_view getProcessName() const = 0;
virtual const std::vector<SystemString>& getArgs() const = 0; virtual const std::vector<std::string>& getArgs() const = 0;
/* Constructors/initializers for sub-objects */ /* Constructors/initializers for sub-objects */
virtual std::shared_ptr<IWindow> newWindow(SystemStringView title) = 0; virtual std::shared_ptr<IWindow> newWindow(std::string_view title) = 0;
}; };
int ApplicationRun(IApplication::EPlatformType platform, IApplicationCallback& cb, SystemStringView uniqueName, int ApplicationRun(IApplication::EPlatformType platform, IApplicationCallback& cb, std::string_view uniqueName,
SystemStringView friendlyName, SystemStringView pname, const std::vector<SystemString>& args, std::string_view friendlyName, std::string_view pname, const std::vector<std::string>& args,
std::string_view gfxApi = {}, uint32_t samples = 1, uint32_t anisotropy = 1, bool deepColor = false, std::string_view gfxApi = {}, uint32_t samples = 1, uint32_t anisotropy = 1, bool deepColor = false,
bool singleInstance = true); bool singleInstance = true);
extern IApplication* APP; extern IApplication* APP;
static inline int ApplicationRun(IApplication::EPlatformType platform, IApplicationCallback& cb, static inline int ApplicationRun(IApplication::EPlatformType platform, IApplicationCallback& cb,
SystemStringView uniqueName, SystemStringView friendlyName, int argc, std::string_view uniqueName, std::string_view friendlyName, int argc,
const SystemChar** argv, std::string_view gfxApi = {}, uint32_t samples = 1, char** argv, std::string_view gfxApi = {}, uint32_t samples = 1,
uint32_t anisotropy = 1, bool deepColor = false, bool singleInstance = true) { uint32_t anisotropy = 1, bool deepColor = false, bool singleInstance = true) {
if (APP) if (APP)
return 1; return 1;
std::vector<SystemString> args; std::vector<std::string> args;
for (int i = 1; i < argc; ++i) for (int i = 1; i < argc; ++i)
args.push_back(argv[i]); args.push_back(argv[i]);
return ApplicationRun(platform, cb, uniqueName, friendlyName, argv[0], args, gfxApi, samples, anisotropy, deepColor, return ApplicationRun(platform, cb, uniqueName, friendlyName, argv[0], args, gfxApi, samples, anisotropy, deepColor,

View File

@ -118,6 +118,7 @@ enum class ESpecialKey {
Up = 24, Up = 24,
Down = 25, Down = 25,
Tab = 26, Tab = 26,
MAX = 27,
}; };
enum class EModifierKey { enum class EModifierKey {
@ -216,8 +217,8 @@ public:
virtual void showWindow() = 0; virtual void showWindow() = 0;
virtual void hideWindow() = 0; virtual void hideWindow() = 0;
virtual SystemString getTitle() = 0; virtual std::string getTitle() = 0;
virtual void setTitle(SystemStringView title) = 0; virtual void setTitle(std::string_view title) = 0;
virtual void setCursor(EMouseCursor cursor) = 0; virtual void setCursor(EMouseCursor cursor) = 0;
virtual void setWaitCursor(bool wait) = 0; virtual void setWaitCursor(bool wait) = 0;

View File

@ -59,22 +59,6 @@ static inline ComPtr<T>* ReferenceComPtr(ComPtr<T>& ptr) {
namespace boo { namespace boo {
#ifdef _WIN32
using SystemString = std::wstring;
using SystemStringView = std::wstring_view;
using SystemChar = wchar_t;
#ifndef _SYS_STR
#define _SYS_STR(val) L##val
#endif
#else
using SystemString = std::string;
using SystemStringView = std::string_view;
using SystemChar = char;
#ifndef _SYS_STR
#define _SYS_STR(val) val
#endif
#endif
#ifndef NDEBUG #ifndef NDEBUG
#define __BooTraceArgs , const char *file, int line #define __BooTraceArgs , const char *file, int line
#define __BooTraceArgsUse , file, line #define __BooTraceArgsUse , file, line

View File

@ -8,14 +8,14 @@ namespace boo {
using namespace Windows::ApplicationModel::Core; using namespace Windows::ApplicationModel::Core;
ref struct ViewProvider sealed : IFrameworkViewSource { ref struct ViewProvider sealed : IFrameworkViewSource {
internal : ViewProvider(boo::IApplicationCallback& appCb, SystemStringView uniqueName, SystemStringView friendlyName, internal : ViewProvider(boo::IApplicationCallback& appCb, std::string_view uniqueName, std::string_view friendlyName,
SystemStringView pname, Platform::Array<Platform::String ^> ^ params, bool singleInstance) std::string_view pname, Platform::Array<Platform::String ^> ^ params, bool singleInstance)
: m_appCb(appCb) : m_appCb(appCb)
, m_uniqueName(uniqueName) , m_uniqueName(uniqueName)
, m_friendlyName(friendlyName) , m_friendlyName(friendlyName)
, m_pname(pname) , m_pname(pname)
, m_singleInstance(singleInstance) { , m_singleInstance(singleInstance) {
SystemChar selfPath[1024]; char selfPath[1024];
GetModuleFileNameW(nullptr, selfPath, 1024); GetModuleFileNameW(nullptr, selfPath, 1024);
m_args.reserve(params->Length + 1); m_args.reserve(params->Length + 1);
m_args.emplace_back(selfPath); m_args.emplace_back(selfPath);
@ -27,10 +27,10 @@ public:
virtual IFrameworkView ^ CreateView(); virtual IFrameworkView ^ CreateView();
internal : boo::IApplicationCallback& m_appCb; internal : boo::IApplicationCallback& m_appCb;
SystemString m_uniqueName; std::string m_uniqueName;
SystemString m_friendlyName; std::string m_friendlyName;
SystemString m_pname; std::string m_pname;
std::vector<SystemString> m_args; std::vector<std::string> m_args;
bool m_singleInstance; bool m_singleInstance;
}; };
#endif #endif

View File

@ -107,8 +107,5 @@ std::unique_ptr<IAudioVoiceEngine> NewAudioVoiceEngine();
/** Construct WAV-rendering voice engine */ /** Construct WAV-rendering voice engine */
std::unique_ptr<IAudioVoiceEngine> NewWAVAudioVoiceEngine(const char* path, double sampleRate, int numChans); std::unique_ptr<IAudioVoiceEngine> NewWAVAudioVoiceEngine(const char* path, double sampleRate, int numChans);
#if _WIN32
std::unique_ptr<IAudioVoiceEngine> NewWAVAudioVoiceEngine(const wchar_t* path, double sampleRate, int numChans);
#endif
} // namespace boo } // namespace boo

View File

@ -20,7 +20,7 @@ public:
~D3D11DataFactory() override = default; ~D3D11DataFactory() override = default;
Platform platform() const override { return Platform::D3D11; } Platform platform() const override { return Platform::D3D11; }
const SystemChar* platformName() const override { return _SYS_STR("D3D11"); } const char* platformName() const override { return "D3D11"; }
class Context final : public IGraphicsDataFactory::Context { class Context final : public IGraphicsDataFactory::Context {
friend class D3D11DataFactoryImpl; friend class D3D11DataFactoryImpl;
@ -31,7 +31,7 @@ public:
public: public:
Platform platform() const override { return Platform::D3D11; } Platform platform() const override { return Platform::D3D11; }
const SystemChar* platformName() const override { return _SYS_STR("D3D11"); } const char* platformName() const override { return "D3D11"; }
ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) override; ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) override;
ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count) override; ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count) override;

View File

@ -27,7 +27,7 @@ public:
public: public:
Platform platform() const override { return Platform::OpenGL; } Platform platform() const override { return Platform::OpenGL; }
const SystemChar* platformName() const override { return _SYS_STR("OpenGL"); } const char* platformName() const override { return "OpenGL"; }
ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) override; ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) override;
ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count) override; ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count) override;

View File

@ -15,7 +15,7 @@ struct IGraphicsCommandQueue {
using Platform = IGraphicsDataFactory::Platform; using Platform = IGraphicsDataFactory::Platform;
virtual Platform platform() const = 0; virtual Platform platform() const = 0;
virtual const SystemChar* platformName() const = 0; virtual const char* platformName() const = 0;
virtual void setShaderDataBinding(const ObjToken<IShaderDataBinding>& binding) = 0; virtual void setShaderDataBinding(const ObjToken<IShaderDataBinding>& binding) = 0;
virtual void setRenderTarget(const ObjToken<ITextureR>& target) = 0; virtual void setRenderTarget(const ObjToken<ITextureR>& target) = 0;

View File

@ -214,11 +214,11 @@ struct IGraphicsDataFactory {
enum class Platform { Null, OpenGL, D3D11, Metal, Vulkan, GX, NX }; enum class Platform { Null, OpenGL, D3D11, Metal, Vulkan, GX, NX };
virtual Platform platform() const = 0; virtual Platform platform() const = 0;
virtual const SystemChar* platformName() const = 0; virtual const char* platformName() const = 0;
struct Context { struct Context {
virtual Platform platform() const = 0; virtual Platform platform() const = 0;
virtual const SystemChar* platformName() const = 0; virtual const char* platformName() const = 0;
virtual ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, virtual ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride,
size_t count) = 0; size_t count) = 0;

View File

@ -22,7 +22,7 @@ public:
public: public:
Platform platform() const { return Platform::Metal; } Platform platform() const { return Platform::Metal; }
const SystemChar* platformName() const { return _SYS_STR("Metal"); } const char* platformName() const { return "Metal"; }
ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count); ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count);
ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count); ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count);

View File

@ -52,7 +52,7 @@ public:
public: public:
Platform platform() const { return Platform::NX; } Platform platform() const { return Platform::NX; }
const SystemChar* platformName() const { return _SYS_STR("NX"); } const char* platformName() const { return "NX"; }
boo::ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count); boo::ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count);
boo::ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count); boo::ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count);

View File

@ -135,7 +135,7 @@ public:
public: public:
Platform platform() const { return Platform::Vulkan; } Platform platform() const { return Platform::Vulkan; }
const SystemChar* platformName() const { return _SYS_STR("Vulkan"); } const char* platformName() const { return "Vulkan"; }
boo::ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count); boo::ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count);
boo::ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count); boo::ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count);

View File

@ -11,6 +11,7 @@
#include <Functiondiscoverykeys_devpkey.h> #include <Functiondiscoverykeys_devpkey.h>
#include <logvisor/logvisor.hpp> #include <logvisor/logvisor.hpp>
#include <nowide/convert.hpp>
#include <optick.h> #include <optick.h>
#ifdef TE_VIRTUAL_MIDI #ifdef TE_VIRTUAL_MIDI
@ -121,7 +122,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
void _buildAudioRenderClient() { void _buildAudioRenderClient() {
#if !WINDOWS_STORE #if !WINDOWS_STORE
if (!m_device) { if (!m_device) {
if (FAILED(m_enumerator->GetDevice(MBSTWCS(m_sinkName.c_str()).c_str(), &m_device))) { if (FAILED(m_enumerator->GetDevice(nowide::widen(m_sinkName).c_str(), &m_device))) {
Log.report(logvisor::Error, FMT_STRING("unable to obtain audio device {}"), m_sinkName); Log.report(logvisor::Error, FMT_STRING("unable to obtain audio device {}"), m_sinkName);
m_device.Reset(); m_device.Reset();
return; return;
@ -129,7 +130,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
} }
if (FAILED(m_device->Activate(IID_IAudioClient, CLSCTX_ALL, nullptr, &m_audClient))) { if (FAILED(m_device->Activate(IID_IAudioClient, CLSCTX_ALL, nullptr, &m_audClient))) {
Log.report(logvisor::Error, FMT_STRING(L"unable to create audio client from device")); Log.report(logvisor::Error, FMT_STRING("unable to create audio client from device"));
m_device.Reset(); m_device.Reset();
return; return;
} }
@ -137,7 +138,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
WAVEFORMATEXTENSIBLE* pwfx; WAVEFORMATEXTENSIBLE* pwfx;
if (FAILED(m_audClient->GetMixFormat((WAVEFORMATEX**)&pwfx))) { if (FAILED(m_audClient->GetMixFormat((WAVEFORMATEX**)&pwfx))) {
Log.report(logvisor::Error, FMT_STRING(L"unable to obtain audio mix format from device")); Log.report(logvisor::Error, FMT_STRING("unable to obtain audio mix format from device"));
#if !WINDOWS_STORE #if !WINDOWS_STORE
m_device.Reset(); m_device.Reset();
#endif #endif
@ -215,7 +216,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
/* Initialize audio client */ /* Initialize audio client */
if (FAILED(m_audClient->Initialize(AUDCLNT_SHAREMODE_SHARED, 0, 450000, /* 45ms */ if (FAILED(m_audClient->Initialize(AUDCLNT_SHAREMODE_SHARED, 0, 450000, /* 45ms */
0, (WAVEFORMATEX*)pwfx, nullptr))) { 0, (WAVEFORMATEX*)pwfx, nullptr))) {
Log.report(logvisor::Error, FMT_STRING(L"unable to initialize audio client")); Log.report(logvisor::Error, FMT_STRING("unable to initialize audio client"));
#if !WINDOWS_STORE #if !WINDOWS_STORE
m_device.Reset(); m_device.Reset();
#endif #endif
@ -236,7 +237,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
m_mixInfo.m_sampleFormat = SOXR_INT32_I; m_mixInfo.m_sampleFormat = SOXR_INT32_I;
m_mixInfo.m_bitsPerSample = 32; m_mixInfo.m_bitsPerSample = 32;
} else { } else {
Log.report(logvisor::Fatal, FMT_STRING(L"unsupported bits-per-sample {}"), pwfx->Format.wBitsPerSample); Log.report(logvisor::Fatal, FMT_STRING("unsupported bits-per-sample {}"), pwfx->Format.wBitsPerSample);
#if !WINDOWS_STORE #if !WINDOWS_STORE
m_device.Reset(); m_device.Reset();
#endif #endif
@ -249,7 +250,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
m_mixInfo.m_sampleFormat = SOXR_FLOAT32_I; m_mixInfo.m_sampleFormat = SOXR_FLOAT32_I;
m_mixInfo.m_bitsPerSample = 32; m_mixInfo.m_bitsPerSample = 32;
} else { } else {
Log.report(logvisor::Error, FMT_STRING(L"unsupported floating-point bits-per-sample {}"), pwfx->Format.wBitsPerSample); Log.report(logvisor::Error, FMT_STRING("unsupported floating-point bits-per-sample {}"), pwfx->Format.wBitsPerSample);
#if !WINDOWS_STORE #if !WINDOWS_STORE
m_device.Reset(); m_device.Reset();
#endif #endif
@ -261,7 +262,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
UINT32 bufferFrameCount; UINT32 bufferFrameCount;
if (FAILED(m_audClient->GetBufferSize(&bufferFrameCount))) { if (FAILED(m_audClient->GetBufferSize(&bufferFrameCount))) {
Log.report(logvisor::Error, FMT_STRING(L"unable to get audio buffer frame count")); Log.report(logvisor::Error, FMT_STRING("unable to get audio buffer frame count"));
#if !WINDOWS_STORE #if !WINDOWS_STORE
m_device.Reset(); m_device.Reset();
#endif #endif
@ -270,7 +271,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
m_mixInfo.m_periodFrames = bufferFrameCount; m_mixInfo.m_periodFrames = bufferFrameCount;
if (FAILED(m_audClient->GetService(IID_IAudioRenderClient, &m_renderClient))) { if (FAILED(m_audClient->GetService(IID_IAudioRenderClient, &m_renderClient))) {
Log.report(logvisor::Error, FMT_STRING(L"unable to create audio render client")); Log.report(logvisor::Error, FMT_STRING("unable to create audio render client"));
#if !WINDOWS_STORE #if !WINDOWS_STORE
m_device.Reset(); m_device.Reset();
#endif #endif
@ -347,24 +348,24 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
/* Enumerate default audio device */ /* Enumerate default audio device */
if (FAILED( if (FAILED(
CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_ALL, IID_IMMDeviceEnumerator, &m_enumerator))) { CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_ALL, IID_IMMDeviceEnumerator, &m_enumerator))) {
Log.report(logvisor::Error, FMT_STRING(L"unable to create MMDeviceEnumerator instance")); Log.report(logvisor::Error, FMT_STRING("unable to create MMDeviceEnumerator instance"));
return; return;
} }
if (FAILED(m_enumerator->RegisterEndpointNotificationCallback(&m_notificationClient))) { if (FAILED(m_enumerator->RegisterEndpointNotificationCallback(&m_notificationClient))) {
Log.report(logvisor::Error, FMT_STRING(L"unable to register multimedia event callback")); Log.report(logvisor::Error, FMT_STRING("unable to register multimedia event callback"));
m_device.Reset(); m_device.Reset();
return; return;
} }
if (FAILED(m_enumerator->GetDefaultAudioEndpoint(eRender, eConsole, &m_device))) { if (FAILED(m_enumerator->GetDefaultAudioEndpoint(eRender, eConsole, &m_device))) {
Log.report(logvisor::Error, FMT_STRING(L"unable to obtain default audio device")); Log.report(logvisor::Error, FMT_STRING("unable to obtain default audio device"));
m_device.Reset(); m_device.Reset();
return; return;
} }
LPWSTR sinkName = nullptr; LPWSTR sinkName = nullptr;
m_device->GetId(&sinkName); m_device->GetId(&sinkName);
m_sinkName = WCSTMBS(sinkName); m_sinkName = nowide::narrow(sinkName);
CoTaskMemFree(sinkName); CoTaskMemFree(sinkName);
_buildAudioRenderClient(); _buildAudioRenderClient();
@ -386,7 +387,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
m_started = false; m_started = false;
if (m_mixInfo.m_sampleFormat != oldFmt) if (m_mixInfo.m_sampleFormat != oldFmt)
Log.report(logvisor::Fatal, FMT_STRING(L"audio device sample format changed, boo doesn't support this!!")); Log.report(logvisor::Fatal, FMT_STRING("audio device sample format changed, boo doesn't support this!!"));
_resetSampleRate(); _resetSampleRate();
} }
@ -404,7 +405,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
int attempt = 0; int attempt = 0;
while (true) { while (true) {
if (attempt >= 10) if (attempt >= 10)
Log.report(logvisor::Fatal, FMT_STRING(L"unable to setup AudioRenderClient")); Log.report(logvisor::Fatal, FMT_STRING("unable to setup AudioRenderClient"));
if (m_rebuild) { if (m_rebuild) {
m_device.Reset(); m_device.Reset();
@ -473,7 +474,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
bool setCurrentAudioOutput(const char* name) override { bool setCurrentAudioOutput(const char* name) override {
ComPtr<IMMDevice> newDevice; ComPtr<IMMDevice> newDevice;
if (FAILED(m_enumerator->GetDevice(MBSTWCS(name).c_str(), &newDevice))) { if (FAILED(m_enumerator->GetDevice(nowide::widen(name).c_str(), &newDevice))) {
Log.report(logvisor::Error, FMT_STRING("unable to obtain audio device {}"), name); Log.report(logvisor::Error, FMT_STRING("unable to obtain audio device {}"), name);
return false; return false;
} }
@ -488,7 +489,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
ComPtr<IMMDeviceCollection> collection; ComPtr<IMMDeviceCollection> collection;
if (FAILED(m_enumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &collection))) { if (FAILED(m_enumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &collection))) {
Log.report(logvisor::Error, FMT_STRING(L"unable to enumerate audio outputs")); Log.report(logvisor::Error, FMT_STRING("unable to enumerate audio outputs"));
return ret; return ret;
} }
@ -505,8 +506,8 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
props->GetValue(PKEY_Device_FriendlyName, &val); props->GetValue(PKEY_Device_FriendlyName, &val);
std::string friendlyName; std::string friendlyName;
if (val.vt == VT_LPWSTR) if (val.vt == VT_LPWSTR)
friendlyName = WCSTMBS(val.pwszVal); friendlyName = nowide::narrow(val.pwszVal);
ret.emplace_back(WCSTMBS(devName), std::move(friendlyName)); ret.emplace_back(nowide::narrow(devName), std::move(friendlyName));
} }
return ret; return ret;
@ -527,29 +528,12 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
continue; continue;
#ifdef UNICODE #ifdef UNICODE
ret.push_back(std::make_pair(std::move(name), WCSTMBS(caps.szPname))); ret.emplace_back(std::move(name), nowide::narrow(caps.szPname));
#else #else
ret.push_back(std::make_pair(std::move(name), std::string(caps.szPname))); ret.emplace_back(std::move(name), std::string(caps.szPname));
#endif #endif
} }
#if 0
for (UINT i=0 ; i<numOutDevices ; ++i)
{
std::string name = fmt::format(FMT_STRING("out{}"), i);
MIDIOUTCAPS caps;
if (FAILED(midiOutGetDevCaps(i, &caps, sizeof(caps))))
continue;
#ifdef UNICODE
ret.push_back(std::make_pair(std::move(name), WCSTMBS(caps.szPname)));
#else
ret.push_back(std::make_pair(std::move(name), std::string(caps.szPname)));
#endif
}
#endif
return ret; return ret;
} }
@ -644,7 +628,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
return {}; return {};
#ifdef UNICODE #ifdef UNICODE
return WCSTMBS(caps.szPname); return nowide::narrow(caps.szPname);
#else #else
return caps.szPname; return caps.szPname;
#endif #endif
@ -684,7 +668,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
return {}; return {};
#ifdef UNICODE #ifdef UNICODE
return WCSTMBS(caps.szPname); return nowide::narrow(caps.szPname);
#else #else
return caps.szPname; return caps.szPname;
#endif #endif
@ -734,7 +718,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
return {}; return {};
#ifdef UNICODE #ifdef UNICODE
return WCSTMBS(caps.szPname); return nowide::narrow(caps.szPname);
#else #else
return caps.szPname; return caps.szPname;
#endif #endif
@ -757,7 +741,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
if (!ret) if (!ret)
return {}; return {};
SystemString name = SystemString(APP->getFriendlyName()) + _SYS_STR(" MIDI-In"); std::string name = std::string(APP->getFriendlyName()) + " MIDI-In";
auto port = virtualMIDICreatePortEx2PROC(name.c_str(), LPVM_MIDI_DATA_CB(VirtualMIDIReceiveProc), auto port = virtualMIDICreatePortEx2PROC(name.c_str(), LPVM_MIDI_DATA_CB(VirtualMIDIReceiveProc),
DWORD_PTR(static_cast<IMIDIReceiver*>(ret.get())), 512, DWORD_PTR(static_cast<IMIDIReceiver*>(ret.get())), 512,
TE_VM_FLAGS_PARSE_RX | TE_VM_FLAGS_INSTANTIATE_RX_ONLY); TE_VM_FLAGS_PARSE_RX | TE_VM_FLAGS_INSTANTIATE_RX_ONLY);
@ -779,7 +763,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
if (!ret) if (!ret)
return {}; return {};
SystemString name = SystemString(APP->getFriendlyName()) + _SYS_STR(" MIDI-Out"); std::string name = std::string(APP->getFriendlyName()) + " MIDI-Out";
auto port = virtualMIDICreatePortEx2PROC(name.c_str(), nullptr, 0, 512, auto port = virtualMIDICreatePortEx2PROC(name.c_str(), nullptr, 0, 512,
TE_VM_FLAGS_PARSE_TX | TE_VM_FLAGS_INSTANTIATE_TX_ONLY); TE_VM_FLAGS_PARSE_TX | TE_VM_FLAGS_INSTANTIATE_TX_ONLY);
if (!port) if (!port)
@ -800,7 +784,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine {
if (!ret) if (!ret)
return {}; return {};
SystemString name = SystemString(APP->getFriendlyName()) + _SYS_STR(" MIDI-In/Out"); std::string name = std::string(APP->getFriendlyName()) + " MIDI-In/Out";
auto port = auto port =
virtualMIDICreatePortEx2PROC(name.c_str(), LPVM_MIDI_DATA_CB(VirtualMIDIReceiveProc), virtualMIDICreatePortEx2PROC(name.c_str(), LPVM_MIDI_DATA_CB(VirtualMIDIReceiveProc),
DWORD_PTR(static_cast<IMIDIReceiver*>(ret.get())), 512, TE_VM_FLAGS_SUPPORTED); DWORD_PTR(static_cast<IMIDIReceiver*>(ret.get())), 512, TE_VM_FLAGS_SUPPORTED);

View File

@ -4,6 +4,7 @@
#include "boo/audiodev/IAudioVoiceEngine.hpp" #include "boo/audiodev/IAudioVoiceEngine.hpp"
#include <logvisor/logvisor.hpp> #include <logvisor/logvisor.hpp>
#include <nowide/stackstring.hpp>
#include <optick.h> #include <optick.h>
namespace boo { namespace boo {
@ -175,16 +176,17 @@ struct WAVOutVoiceEngine : BaseAudioVoiceEngine {
_buildAudioRenderClient(); _buildAudioRenderClient();
} }
#if _WIN32
WAVOutVoiceEngine(const char* path, double sampleRate, int numChans) { WAVOutVoiceEngine(const char* path, double sampleRate, int numChans) {
m_fp = fopen(path, "wb"); const nowide::wstackstring wpath(path);
m_fp = _wfopen(wpath.get(), L"wb");
if (!m_fp) if (!m_fp)
return; return;
prepareWAV(sampleRate, numChans); prepareWAV(sampleRate, numChans);
} }
#else
#if _WIN32 WAVOutVoiceEngine(const char* path, double sampleRate, int numChans) {
WAVOutVoiceEngine(const wchar_t* path, double sampleRate, int numChans) { m_fp = fopen(path, "wb");
m_fp = _wfopen(path, L"wb");
if (!m_fp) if (!m_fp)
return; return;
prepareWAV(sampleRate, numChans); prepareWAV(sampleRate, numChans);
@ -243,13 +245,4 @@ std::unique_ptr<IAudioVoiceEngine> NewWAVAudioVoiceEngine(const char* path, doub
return ret; return ret;
} }
#if _WIN32
std::unique_ptr<IAudioVoiceEngine> NewWAVAudioVoiceEngine(const wchar_t* path, double sampleRate, int numChans) {
std::unique_ptr<IAudioVoiceEngine> ret = std::make_unique<WAVOutVoiceEngine>(path, sampleRate, numChans);
if (!static_cast<WAVOutVoiceEngine&>(*ret).m_fp)
return {};
return ret;
}
#endif
} // namespace boo } // namespace boo

View File

@ -16,6 +16,7 @@
#include <comdef.h> #include <comdef.h>
#include <logvisor/logvisor.hpp> #include <logvisor/logvisor.hpp>
#include <nowide/convert.hpp>
#undef min #undef min
#undef max #undef max
@ -76,8 +77,8 @@ static inline void ThrowIfFailed(HRESULT hr) {
#else #else
_com_error err(hr, L"D3D11 fail"); _com_error err(hr, L"D3D11 fail");
#endif #endif
LPCTSTR errMsg = err.ErrorMessage(); std::string errMsg = nowide::narrow(err.ErrorMessage());
Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("{}")), errMsg); Log.report(logvisor::Fatal, FMT_STRING("{}"), errMsg);
} }
} }
@ -972,7 +973,7 @@ struct D3D11ShaderDataBinding : public GraphicsDataNode<IShaderDataBinding> {
struct D3D11CommandQueue final : IGraphicsCommandQueue { struct D3D11CommandQueue final : IGraphicsCommandQueue {
Platform platform() const override { return IGraphicsDataFactory::Platform::D3D11; } Platform platform() const override { return IGraphicsDataFactory::Platform::D3D11; }
const SystemChar* platformName() const override { return _SYS_STR("D3D11"); } const char* platformName() const override { return "D3D11"; }
D3D11Context* m_ctx; D3D11Context* m_ctx;
D3D11Context::Window* m_windowCtx; D3D11Context::Window* m_windowCtx;
IGraphicsContext* m_parent; IGraphicsContext* m_parent;
@ -1228,7 +1229,7 @@ struct D3D11CommandQueue final : IGraphicsCommandQueue {
#ifdef BOO_GRAPHICS_DEBUG_GROUPS #ifdef BOO_GRAPHICS_DEBUG_GROUPS
void pushDebugGroup(const char* name, const std::array<float, 4>& color) override { void pushDebugGroup(const char* name, const std::array<float, 4>& color) override {
if (m_deferredAnnot) if (m_deferredAnnot)
m_deferredAnnot->BeginEvent(MBSTWCS(name).c_str()); m_deferredAnnot->BeginEvent(nowide::widen(name).c_str());
} }
void popDebugGroup() override { void popDebugGroup() override {

View File

@ -130,7 +130,7 @@ public:
GLDataFactoryImpl(IGraphicsContext* parent, GLContext* glCtx) : m_parent(parent), m_glCtx(glCtx) {} GLDataFactoryImpl(IGraphicsContext* parent, GLContext* glCtx) : m_parent(parent), m_glCtx(glCtx) {}
Platform platform() const override { return Platform::OpenGL; } Platform platform() const override { return Platform::OpenGL; }
const SystemChar* platformName() const override { return _SYS_STR("OpenGL"); } const char* platformName() const override { return "OpenGL"; }
void commitTransaction(const FactoryCommitFunc& trans __BooTraceArgs) override; void commitTransaction(const FactoryCommitFunc& trans __BooTraceArgs) override;
ObjToken<IGraphicsBufferD> newPoolBuffer(BufferUse use, size_t stride, size_t count __BooTraceArgs) override; ObjToken<IGraphicsBufferD> newPoolBuffer(BufferUse use, size_t stride, size_t count __BooTraceArgs) override;
@ -1166,7 +1166,7 @@ constexpr std::array<GLenum, 11> SEMANTIC_TYPE_TABLE{
struct GLCommandQueue final : IGraphicsCommandQueue { struct GLCommandQueue final : IGraphicsCommandQueue {
Platform platform() const override { return IGraphicsDataFactory::Platform::OpenGL; } Platform platform() const override { return IGraphicsDataFactory::Platform::OpenGL; }
const SystemChar* platformName() const override { return _SYS_STR("OpenGL"); } const char* platformName() const override { return "OpenGL"; }
IGraphicsContext* m_parent = nullptr; IGraphicsContext* m_parent = nullptr;
GLContext* m_glCtx = nullptr; GLContext* m_glCtx = nullptr;
@ -1357,11 +1357,7 @@ struct GLCommandQueue final : IGraphicsCommandQueue {
static void RenderingWorker(GLCommandQueue* self) { static void RenderingWorker(GLCommandQueue* self) {
BOO_MSAN_NO_INTERCEPT BOO_MSAN_NO_INTERCEPT
#if _WIN32
std::string thrName = WCSTMBS(APP->getFriendlyName().data()) + " Render";
#else
std::string thrName = std::string(APP->getFriendlyName()) + " Render"; std::string thrName = std::string(APP->getFriendlyName()) + " Render";
#endif
logvisor::RegisterThreadName(thrName.c_str()); logvisor::RegisterThreadName(thrName.c_str());
GLDataFactoryImpl* dataFactory = static_cast<GLDataFactoryImpl*>(self->m_parent->getDataFactory()); GLDataFactoryImpl* dataFactory = static_cast<GLDataFactoryImpl*>(self->m_parent->getDataFactory());
{ {
@ -1497,7 +1493,7 @@ struct GLCommandQueue final : IGraphicsCommandQueue {
case Command::Op::DrawIndexed: case Command::Op::DrawIndexed:
if (cmd.baseVertex > 0) { if (cmd.baseVertex > 0) {
Log.report(logvisor::Fatal, Log.report(logvisor::Fatal,
FMT_STRING(_SYS_STR("Attempted to render with baseVertex > 0 (currently unsupported in GL)"))); FMT_STRING("Attempted to render with baseVertex > 0 (currently unsupported in GL)"));
} }
glDrawElements(currentPrim, cmd.count, GL_UNSIGNED_INT, reinterpret_cast<void*>(cmd.start * 4)); glDrawElements(currentPrim, cmd.count, GL_UNSIGNED_INT, reinterpret_cast<void*>(cmd.start * 4));
break; break;

View File

@ -127,7 +127,7 @@ public:
~VulkanDataFactoryImpl() { assert(m_descPoolHead == nullptr && "Dangling descriptor pools detected"); } ~VulkanDataFactoryImpl() { assert(m_descPoolHead == nullptr && "Dangling descriptor pools detected"); }
Platform platform() const { return Platform::Vulkan; } Platform platform() const { return Platform::Vulkan; }
const SystemChar* platformName() const { return _SYS_STR("Vulkan"); } const char* platformName() const { return "Vulkan"; }
boo::ObjToken<VulkanDescriptorPool> allocateDescriptorSets(VkDescriptorSet* out); boo::ObjToken<VulkanDescriptorPool> allocateDescriptorSets(VkDescriptorSet* out);
@ -2860,7 +2860,7 @@ struct VulkanShaderDataBinding : GraphicsDataNode<IShaderDataBinding> {
struct VulkanCommandQueue final : IGraphicsCommandQueue { struct VulkanCommandQueue final : IGraphicsCommandQueue {
Platform platform() const { return IGraphicsDataFactory::Platform::Vulkan; } Platform platform() const { return IGraphicsDataFactory::Platform::Vulkan; }
const SystemChar* platformName() const { return _SYS_STR("Vulkan"); } const char* platformName() const { return "Vulkan"; }
VulkanContext* m_ctx; VulkanContext* m_ctx;
VulkanContext::Window* m_windowCtx; VulkanContext::Window* m_windowCtx;
IGraphicsContext* m_parent; IGraphicsContext* m_parent;

View File

@ -30,17 +30,17 @@ namespace boo { class ApplicationCocoa; }
namespace boo { namespace boo {
static logvisor::Module Log("boo::ApplicationCocoa"); static logvisor::Module Log("boo::ApplicationCocoa");
std::shared_ptr<IWindow> _WindowCocoaNew(SystemStringView title, MetalContext* metalCtx); std::shared_ptr<IWindow> _WindowCocoaNew(std::string_view title, MetalContext* metalCtx);
class ApplicationCocoa : public IApplication { class ApplicationCocoa : public IApplication {
public: public:
IApplicationCallback& m_callback; IApplicationCallback& m_callback;
AppDelegate* m_appDelegate; AppDelegate* m_appDelegate;
private: private:
const SystemString m_uniqueName; const std::string m_uniqueName;
const SystemString m_friendlyName; const std::string m_friendlyName;
const SystemString m_pname; const std::string m_pname;
const std::vector<SystemString> m_args; const std::vector<std::string> m_args;
NSPanel* aboutPanel; NSPanel* aboutPanel;
@ -58,10 +58,10 @@ private:
public: public:
ApplicationCocoa(IApplicationCallback& callback, ApplicationCocoa(IApplicationCallback& callback,
SystemStringView uniqueName, std::string_view uniqueName,
SystemStringView friendlyName, std::string_view friendlyName,
SystemStringView pname, std::string_view pname,
const std::vector<SystemString>& args, const std::vector<std::string>& args,
std::string_view gfxApi, std::string_view gfxApi,
uint32_t samples, uint32_t samples,
uint32_t anisotropy, uint32_t anisotropy,
@ -164,19 +164,19 @@ public:
[NSApp terminate:nil]; [NSApp terminate:nil];
} }
SystemStringView getUniqueName() const override { std::string_view getUniqueName() const override {
return m_uniqueName; return m_uniqueName;
} }
SystemStringView getFriendlyName() const override { std::string_view getFriendlyName() const override {
return m_friendlyName; return m_friendlyName;
} }
SystemStringView getProcessName() const override { std::string_view getProcessName() const override {
return m_pname; return m_pname;
} }
const std::vector<SystemString>& getArgs() const override { const std::vector<std::string>& getArgs() const override {
return m_args; return m_args;
} }
@ -203,10 +203,10 @@ IApplication* APP = nullptr;
int ApplicationRun(IApplication::EPlatformType platform, int ApplicationRun(IApplication::EPlatformType platform,
IApplicationCallback& cb, IApplicationCallback& cb,
SystemStringView uniqueName, std::string_view uniqueName,
SystemStringView friendlyName, std::string_view friendlyName,
SystemStringView pname, std::string_view pname,
const std::vector<SystemString>& args, const std::vector<std::string>& args,
std::string_view gfxApi, std::string_view gfxApi,
uint32_t samples, uint32_t samples,
uint32_t anisotropy, uint32_t anisotropy,
@ -269,17 +269,17 @@ int ApplicationRun(IApplication::EPlatformType platform,
#endif #endif
- (BOOL)application:(NSApplication*)sender openFile:(NSString*)filename { - (BOOL)application:(NSApplication*)sender openFile:(NSString*)filename {
std::vector<boo::SystemString> strVec; std::vector<std::string> strVec;
strVec.push_back(boo::SystemString([filename UTF8String])); strVec.push_back(std::string([filename UTF8String]));
m_app->m_callback.appFilesOpen(boo::APP, strVec); m_app->m_callback.appFilesOpen(boo::APP, strVec);
return true; return true;
} }
- (void)application:(NSApplication*)sender openFiles:(NSArray*)filenames { - (void)application:(NSApplication*)sender openFiles:(NSArray*)filenames {
std::vector<boo::SystemString> strVec; std::vector<std::string> strVec;
strVec.reserve([filenames count]); strVec.reserve([filenames count]);
for (NSString* str in filenames) for (NSString* str in filenames)
strVec.push_back(boo::SystemString([str UTF8String])); strVec.push_back(std::string([str UTF8String]));
m_app->m_callback.appFilesOpen(boo::APP, strVec); m_app->m_callback.appFilesOpen(boo::APP, strVec);
} }

View File

@ -1524,7 +1524,7 @@ public:
}; };
std::shared_ptr<IWindow> _WindowCocoaNew(SystemStringView title, MetalContext* metalCtx) { std::shared_ptr<IWindow> _WindowCocoaNew(std::string_view title, MetalContext* metalCtx) {
auto ret = std::make_shared<WindowCocoa>(); auto ret = std::make_shared<WindowCocoa>();
ret->setup(title, metalCtx); ret->setup(title, metalCtx);
return ret; return ret;

View File

@ -37,15 +37,15 @@ static bool FindBestD3DCompile() {
namespace boo { namespace boo {
static logvisor::Module Log("boo::ApplicationUWP"); static logvisor::Module Log("boo::ApplicationUWP");
std::shared_ptr<IWindow> _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx); std::shared_ptr<IWindow> _WindowUWPNew(std::string_view title, Boo3DAppContextUWP& d3dCtx);
class ApplicationUWP final : public IApplication { class ApplicationUWP final : public IApplication {
friend ref class AppView; friend ref class AppView;
IApplicationCallback& m_callback; IApplicationCallback& m_callback;
const SystemString m_uniqueName; const std::string m_uniqueName;
const SystemString m_friendlyName; const std::string m_friendlyName;
const SystemString m_pname; const std::string m_pname;
const std::vector<SystemString> m_args; const std::vector<std::string> m_args;
std::shared_ptr<IWindow> m_window; std::shared_ptr<IWindow> m_window;
bool m_singleInstance; bool m_singleInstance;
bool m_issuedWindow = false; bool m_issuedWindow = false;
@ -55,8 +55,8 @@ class ApplicationUWP final : public IApplication {
void _deletedWindow(IWindow* window) override {} void _deletedWindow(IWindow* window) override {}
public: public:
ApplicationUWP(IApplicationCallback& callback, SystemStringView uniqueName, SystemStringView friendlyName, ApplicationUWP(IApplicationCallback& callback, std::string_view uniqueName, std::string_view friendlyName,
SystemStringView pname, const std::vector<SystemString>& args, bool singleInstance) std::string_view pname, const std::vector<std::string>& args, bool singleInstance)
: m_callback(callback) : m_callback(callback)
, m_uniqueName(uniqueName) , m_uniqueName(uniqueName)
, m_friendlyName(friendlyName) , m_friendlyName(friendlyName)
@ -67,7 +67,7 @@ public:
CreateDXGIFactory1PROC MyCreateDXGIFactory1 = CreateDXGIFactory1; CreateDXGIFactory1PROC MyCreateDXGIFactory1 = CreateDXGIFactory1;
bool no12 = true; bool no12 = true;
for (const SystemString& arg : args) for (const std::string& arg : args)
if (!arg.compare(L"--d3d12")) if (!arg.compare(L"--d3d12"))
no12 = false; no12 = false;
@ -190,7 +190,7 @@ public:
/* Spawn client thread */ /* Spawn client thread */
int clientReturn = 0; int clientReturn = 0;
m_clientThread = std::thread([&]() { m_clientThread = std::thread([&]() {
std::string thrName = WCSTMBS(getFriendlyName().data()) + " Client Thread"; std::string thrName = std::string(getFriendlyName()) + " Client Thread";
logvisor::RegisterThreadName(thrName.c_str()); logvisor::RegisterThreadName(thrName.c_str());
clientReturn = m_callback.appMain(this); clientReturn = m_callback.appMain(this);
}); });
@ -206,15 +206,15 @@ public:
m_clientThread.join(); m_clientThread.join();
} }
SystemStringView getUniqueName() const override { return m_uniqueName; } std::string_view getUniqueName() const override { return m_uniqueName; }
SystemStringView getFriendlyName() const override { return m_friendlyName; } std::string_view getFriendlyName() const override { return m_friendlyName; }
SystemStringView getProcessName() const override { return m_pname; } std::string_view getProcessName() const override { return m_pname; }
const std::vector<SystemString>& getArgs() const override { return m_args; } const std::vector<std::string>& getArgs() const override { return m_args; }
std::shared_ptr<IWindow> newWindow(SystemStringView title, uint32_t sampleCount) override { std::shared_ptr<IWindow> newWindow(std::string_view title, uint32_t sampleCount) override {
if (!m_issuedWindow) { if (!m_issuedWindow) {
m_issuedWindow = true; m_issuedWindow = true;
return m_window; return m_window;
@ -229,8 +229,8 @@ IApplication* APP = nullptr;
ref class AppView sealed : public IFrameworkView { ref class AppView sealed : public IFrameworkView {
ApplicationUWP m_app; ApplicationUWP m_app;
internal : AppView(IApplicationCallback& callback, SystemStringView uniqueName, SystemStringView friendlyName, internal : AppView(IApplicationCallback& callback, std::string_view uniqueName, std::string_view friendlyName,
SystemStringView pname, const std::vector<SystemString>& args, bool singleInstance) std::string_view pname, const std::vector<std::string>& args, bool singleInstance)
: m_app(callback, uniqueName, friendlyName, pname, args, singleInstance) { : m_app(callback, uniqueName, friendlyName, pname, args, singleInstance) {
APP = &m_app; APP = &m_app;
} }

View File

@ -77,14 +77,14 @@ namespace boo {
static logvisor::Module Log("boo::ApplicationWin32"); static logvisor::Module Log("boo::ApplicationWin32");
Win32Cursors WIN32_CURSORS; Win32Cursors WIN32_CURSORS;
std::shared_ptr<IWindow> _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx); std::shared_ptr<IWindow> _WindowWin32New(std::string_view title, Boo3DAppContextWin32& d3dCtx);
class ApplicationWin32 final : public IApplication { class ApplicationWin32 final : public IApplication {
IApplicationCallback& m_callback; IApplicationCallback& m_callback;
const SystemString m_uniqueName; const std::string m_uniqueName;
const SystemString m_friendlyName; const std::string m_friendlyName;
const SystemString m_pname; const std::string m_pname;
const std::vector<SystemString> m_args; const std::vector<std::string> m_args;
std::unordered_map<HWND, std::weak_ptr<IWindow>> m_allWindows; std::unordered_map<HWND, std::weak_ptr<IWindow>> m_allWindows;
Boo3DAppContextWin32 m_3dCtx; Boo3DAppContextWin32 m_3dCtx;
@ -95,8 +95,8 @@ class ApplicationWin32 final : public IApplication {
void _deletedWindow(IWindow* window) override { m_allWindows.erase(HWND(window->getPlatformHandle())); } void _deletedWindow(IWindow* window) override { m_allWindows.erase(HWND(window->getPlatformHandle())); }
public: public:
ApplicationWin32(IApplicationCallback& callback, SystemStringView uniqueName, SystemStringView friendlyName, ApplicationWin32(IApplicationCallback& callback, std::string_view uniqueName, std::string_view friendlyName,
SystemStringView pname, const std::vector<SystemString>& args, std::string_view gfxApi, std::string_view pname, const std::vector<std::string>& args, std::string_view gfxApi,
uint32_t samples, uint32_t anisotropy, bool deepColor, bool singleInstance) uint32_t samples, uint32_t anisotropy, bool deepColor, bool singleInstance)
: m_callback(callback), m_uniqueName(uniqueName), m_friendlyName(friendlyName), m_pname(pname), m_args(args) { : m_callback(callback), m_uniqueName(uniqueName), m_friendlyName(friendlyName), m_pname(pname), m_args(args) {
m_3dCtx.m_ctx11.m_sampleCount = samples; m_3dCtx.m_ctx11.m_sampleCount = samples;
@ -142,17 +142,17 @@ public:
noD3d = true; noD3d = true;
#endif #endif
} }
for (const SystemString& arg : args) { for (const std::string& arg : args) {
#if BOO_HAS_VULKAN #if BOO_HAS_VULKAN
if (!arg.compare(L"--d3d11")) { if (!arg.compare("--d3d11")) {
useVulkan = false; useVulkan = false;
noD3d = false; noD3d = false;
} }
if (!arg.compare(L"--vulkan")) { if (!arg.compare("--vulkan")) {
noD3d = true; noD3d = true;
useVulkan = true; useVulkan = true;
} }
if (!arg.compare(L"--gl")) { if (!arg.compare("--gl")) {
noD3d = true; noD3d = true;
useVulkan = false; useVulkan = false;
} }
@ -173,7 +173,7 @@ public:
/* Check device support for vulkan */ /* Check device support for vulkan */
if (g_VulkanContext.m_instance == VK_NULL_HANDLE) { if (g_VulkanContext.m_instance == VK_NULL_HANDLE) {
auto appName = getUniqueName(); auto appName = getUniqueName();
if (g_VulkanContext.initVulkan(WCSTMBS(appName.data()).c_str(), m_getVkProc)) { if (g_VulkanContext.initVulkan(appName.data(), m_getVkProc)) {
if (g_VulkanContext.enumerateDevices()) { if (g_VulkanContext.enumerateDevices()) {
/* Obtain DXGI Factory */ /* Obtain DXGI Factory */
HRESULT hr = MyCreateDXGIFactory1(__uuidof(IDXGIFactory1), &m_3dCtx.m_vulkanDxFactory); HRESULT hr = MyCreateDXGIFactory1(__uuidof(IDXGIFactory1), &m_3dCtx.m_vulkanDxFactory);
@ -375,7 +375,7 @@ public:
/* Spawn client thread */ /* Spawn client thread */
int clientReturn = 0; int clientReturn = 0;
std::thread clientThread([&]() { std::thread clientThread([&]() {
std::string thrName = WCSTMBS(getFriendlyName().data()) + " Client Thread"; std::string thrName = std::string(getFriendlyName()) + " Client Thread";
logvisor::RegisterThreadName(thrName.c_str()); logvisor::RegisterThreadName(thrName.c_str());
CoInitializeEx(nullptr, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE); CoInitializeEx(nullptr, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
clientReturn = m_callback.appMain(this); clientReturn = m_callback.appMain(this);
@ -391,7 +391,7 @@ public:
case WM_USER: { case WM_USER: {
/* New-window message (coalesced onto main thread) */ /* New-window message (coalesced onto main thread) */
std::lock_guard<std::mutex> lk(g_nwmt); std::lock_guard<std::mutex> lk(g_nwmt);
SystemStringView* title = reinterpret_cast<SystemStringView*>(msg.wParam); std::string_view* title = reinterpret_cast<std::string_view*>(msg.wParam);
m_mwret = newWindow(*title); m_mwret = newWindow(*title);
g_nwcv.notify_one(); g_nwcv.notify_one();
continue; continue;
@ -441,16 +441,16 @@ public:
w->_cleanup(); w->_cleanup();
} }
SystemStringView getUniqueName() const override { return m_uniqueName; } std::string_view getUniqueName() const override { return m_uniqueName; }
SystemStringView getFriendlyName() const override { return m_friendlyName; } std::string_view getFriendlyName() const override { return m_friendlyName; }
SystemStringView getProcessName() const override { return m_pname; } std::string_view getProcessName() const override { return m_pname; }
const std::vector<SystemString>& getArgs() const override { return m_args; } const std::vector<std::string>& getArgs() const override { return m_args; }
std::shared_ptr<IWindow> m_mwret; std::shared_ptr<IWindow> m_mwret;
std::shared_ptr<IWindow> newWindow(SystemStringView title) override { std::shared_ptr<IWindow> newWindow(std::string_view title) override {
if (GetCurrentThreadId() != g_mainThreadId) { if (GetCurrentThreadId() != g_mainThreadId) {
std::unique_lock<std::mutex> lk(g_nwmt); std::unique_lock<std::mutex> lk(g_nwmt);
if (!PostThreadMessageW(g_mainThreadId, WM_USER, WPARAM(&title), 0)) if (!PostThreadMessageW(g_mainThreadId, WM_USER, WPARAM(&title), 0))
@ -469,11 +469,11 @@ public:
}; };
IApplication* APP = nullptr; IApplication* APP = nullptr;
int ApplicationRun(IApplication::EPlatformType platform, IApplicationCallback& cb, SystemStringView uniqueName, int ApplicationRun(IApplication::EPlatformType platform, IApplicationCallback& cb, std::string_view uniqueName,
SystemStringView friendlyName, SystemStringView pname, const std::vector<SystemString>& args, std::string_view friendlyName, std::string_view pname, const std::vector<std::string>& args,
std::string_view gfxApi, uint32_t samples, uint32_t anisotropy, bool deepColor, std::string_view gfxApi, uint32_t samples, uint32_t anisotropy, bool deepColor,
bool singleInstance) { bool singleInstance) {
std::string thrName = WCSTMBS(friendlyName.data()) + " Main Thread"; std::string thrName = std::string(friendlyName) + " Main Thread";
logvisor::RegisterThreadName(thrName.c_str()); logvisor::RegisterThreadName(thrName.c_str());
if (APP) if (APP)
return 1; return 1;

View File

@ -9,7 +9,7 @@
namespace boo { namespace boo {
class IWindow; class IWindow;
} } // namespace boo
#if _WIN32_WINNT_WIN10 #if _WIN32_WINNT_WIN10
#include <dxgi1_4.h> #include <dxgi1_4.h>
@ -115,17 +115,3 @@ struct Boo3DAppContext {
win.m_needsResize = true; win.m_needsResize = true;
} }
}; };
inline std::string WCSTMBS(const wchar_t* wstr) {
int sizeNeeded = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, nullptr, 0, nullptr, nullptr) - 1;
std::string strTo(sizeNeeded, 0);
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, &strTo[0], sizeNeeded, nullptr, nullptr);
return strTo;
}
inline std::wstring MBSTWCS(const char* str) {
int sizeNeeded = MultiByteToWideChar(CP_UTF8, 0, str, -1, nullptr, 0) - 1;
std::wstring strTo(sizeNeeded, 0);
MultiByteToWideChar(CP_UTF8, 0, str, -1, &strTo[0], sizeNeeded);
return strTo;
}

View File

@ -279,7 +279,7 @@ public:
}; };
EventReceiver ^ m_eventReceiver; EventReceiver ^ m_eventReceiver;
WindowUWP(SystemStringView title, Boo3DAppContextUWP& b3dCtx) WindowUWP(std::string_view title, Boo3DAppContextUWP& b3dCtx)
: m_coreWindow(CoreWindow::GetForCurrentThread()), m_eventReceiver(ref new EventReceiver(*this)) { : m_coreWindow(CoreWindow::GetForCurrentThread()), m_eventReceiver(ref new EventReceiver(*this)) {
IGraphicsContext::EGraphicsAPI api = IGraphicsContext::EGraphicsAPI::D3D11; IGraphicsContext::EGraphicsAPI api = IGraphicsContext::EGraphicsAPI::D3D11;
#if _WIN32_WINNT_WIN10 #if _WIN32_WINNT_WIN10
@ -317,9 +317,9 @@ public:
void hideWindow() override {} void hideWindow() override {}
SystemString getTitle() override { return SystemString(m_appView->Title->Data()); } std::string getTitle() override { return std::string(m_appView->Title->Data()); }
void setTitle(SystemStringView title) override { m_appView->Title = ref new Platform::String(title.data()); } void setTitle(std::string_view title) override { m_appView->Title = ref new Platform::String(title.data()); }
void setCursor(EMouseCursor cursor) override {} void setCursor(EMouseCursor cursor) override {}
@ -493,7 +493,7 @@ public:
IGraphicsDataFactory* getLoadContextDataFactory() override { return m_gfxCtx->getLoadContextDataFactory(); } IGraphicsDataFactory* getLoadContextDataFactory() override { return m_gfxCtx->getLoadContextDataFactory(); }
}; };
std::shared_ptr<IWindow> _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx) { std::shared_ptr<IWindow> _WindowUWPNew(std::string_view title, Boo3DAppContextUWP& d3dCtx) {
return std::make_shared<WindowUWP>(title, d3dCtx); return std::make_shared<WindowUWP>(title, d3dCtx);
} }

View File

@ -24,6 +24,7 @@
#endif #endif
#include <logvisor/logvisor.hpp> #include <logvisor/logvisor.hpp>
#include <nowide/stackstring.hpp>
static const int ContextAttribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 3, static const int ContextAttribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 3,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
@ -863,7 +864,7 @@ class WindowWin32 : public IWindow {
} }
public: public:
WindowWin32(SystemStringView title, Boo3DAppContextWin32& b3dCtx) { WindowWin32(std::string_view title, Boo3DAppContextWin32& b3dCtx) {
const POINT ptZero = {0, 0}; const POINT ptZero = {0, 0};
HMONITOR monitor = MonitorFromPoint(ptZero, MONITOR_DEFAULTTOPRIMARY); HMONITOR monitor = MonitorFromPoint(ptZero, MONITOR_DEFAULTTOPRIMARY);
MONITORINFO monInfo = {}; MONITORINFO monInfo = {};
@ -874,7 +875,8 @@ public:
RECT r = {x, y, x + w, y + h}; RECT r = {x, y, x + w, y + h};
AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, FALSE); AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, FALSE);
m_hwnd = CreateWindowW(L"BooWindow", title.data(), WS_OVERLAPPEDWINDOW, r.left, r.top, r.right - r.left, const nowide::wstackstring wtitle(title);
m_hwnd = CreateWindowW(L"BooWindow", wtitle.get(), WS_OVERLAPPEDWINDOW, r.left, r.top, r.right - r.left,
r.bottom - r.top, nullptr, nullptr, nullptr, nullptr); r.bottom - r.top, nullptr, nullptr, nullptr, nullptr);
m_imc = ImmGetContext(m_hwnd); m_imc = ImmGetContext(m_hwnd);
@ -890,12 +892,12 @@ public:
IGraphicsContext::EGraphicsAPI api = IGraphicsContext::EGraphicsAPI::D3D11; IGraphicsContext::EGraphicsAPI api = IGraphicsContext::EGraphicsAPI::D3D11;
#if BOO_HAS_GL #if BOO_HAS_GL
if (b3dCtx.m_ctxOgl.m_dxFactory) { if (b3dCtx.m_ctxOgl.m_dxFactory) {
m_gfxCtx.reset(new GraphicsContextWin32GL(IGraphicsContext::EGraphicsAPI::OpenGL3_3, this, m_hwnd, b3dCtx)); m_gfxCtx = std::make_unique<GraphicsContextWin32GL>(IGraphicsContext::EGraphicsAPI::OpenGL3_3, this, m_hwnd, b3dCtx);
m_openGL = true; m_openGL = true;
return; return;
} }
#endif #endif
m_gfxCtx.reset(new GraphicsContextWin32D3D(api, this, m_hwnd, b3dCtx)); m_gfxCtx = std::make_unique<GraphicsContextWin32D3D>(api, this, m_hwnd, b3dCtx);
} }
void _cleanup() override { m_gfxCtx.reset(); } void _cleanup() override { m_gfxCtx.reset(); }
@ -911,13 +913,16 @@ public:
void hideWindow() override { ShowWindow(m_hwnd, SW_HIDE); } void hideWindow() override { ShowWindow(m_hwnd, SW_HIDE); }
SystemString getTitle() override { std::string getTitle() override {
wchar_t title[256]; wchar_t title[256];
int c = GetWindowTextW(m_hwnd, title, 256); int c = GetWindowTextW(m_hwnd, title, 256);
return SystemString(title, c); return nowide::narrow(title, c);
} }
void setTitle(SystemStringView title) override { SetWindowTextW(m_hwnd, title.data()); } void setTitle(std::string_view title) override {
const nowide::wstackstring wtitle(title);
SetWindowTextW(m_hwnd, wtitle.get());
}
static void _setCursor(HCURSOR cur) { PostThreadMessageW(g_mainThreadId, WM_USER + 2, WPARAM(cur), 0); } static void _setCursor(HCURSOR cur) { PostThreadMessageW(g_mainThreadId, WM_USER + 2, WPARAM(cur), 0); }
@ -989,13 +994,14 @@ public:
float getVirtualPixelFactor() const override { float getVirtualPixelFactor() const override {
#if _WIN32_WINNT_WINBLUE #if _WIN32_WINNT_WINBLUE
if (MyGetScaleFactorForMonitor) { if (MyGetScaleFactorForMonitor != nullptr) {
DEVICE_SCALE_FACTOR Factor; DEVICE_SCALE_FACTOR Factor = DEVICE_SCALE_FACTOR_INVALID;
HMONITOR mon = MonitorFromWindow(m_hwnd, MONITOR_DEFAULTTOPRIMARY); HMONITOR mon = MonitorFromWindow(m_hwnd, MONITOR_DEFAULTTOPRIMARY);
MyGetScaleFactorForMonitor(mon, &Factor); MyGetScaleFactorForMonitor(mon, &Factor);
if (Factor == 0) if (Factor == 0) {
return 1.f; return 1.f;
return Factor / 100.f; }
return static_cast<float>(Factor) / 100.f;
} }
#endif #endif
return 1.f; return 1.f;
@ -1368,7 +1374,7 @@ public:
IGraphicsDataFactory* getLoadContextDataFactory() override { return m_gfxCtx->getLoadContextDataFactory(); } IGraphicsDataFactory* getLoadContextDataFactory() override { return m_gfxCtx->getLoadContextDataFactory(); }
}; };
std::shared_ptr<IWindow> _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx) { std::shared_ptr<IWindow> _WindowWin32New(std::string_view title, Boo3DAppContextWin32& d3dCtx) {
return std::make_shared<WindowWin32>(title, d3dCtx); return std::make_shared<WindowWin32>(title, d3dCtx);
} }

@ -1 +1 @@
Subproject commit 274ad5ef07e0d658ee5281f11cc19bf168f7d4c6 Subproject commit 139281f6677bc3e08e39ebcc8b84a894cbc5fb6e

View File

@ -391,7 +391,7 @@ struct TestApplicationCallback : IApplicationCallback {
} }
int appMain(IApplication* app) override { int appMain(IApplication* app) override {
mainWindow = app->newWindow(_SYS_STR("YAY!")); mainWindow = app->newWindow("YAY!");
mainWindow->setCallback(&windowCallback); mainWindow->setCallback(&windowCallback);
mainWindow->showWindow(); mainWindow->showWindow();
windowCallback.m_lastRect = mainWindow->getWindowFrame(); windowCallback.m_lastRect = mainWindow->getWindowFrame();
@ -457,14 +457,10 @@ struct TestApplicationCallback : IApplicationCallback {
return 0; return 0;
} }
void appQuitting(IApplication*) override { running = false; } void appQuitting(IApplication*) override { running = false; }
void appFilesOpen(IApplication*, const std::vector<SystemString>& paths) override { void appFilesOpen(IApplication*, const std::vector<std::string>& paths) override {
fprintf(stderr, "OPENING: "); fprintf(stderr, "OPENING: ");
for (const SystemString& path : paths) { for (const std::string& path : paths) {
#if _WIN32
fwprintf(stderr, L"%s ", path.c_str());
#else
fprintf(stderr, "%s ", path.c_str()); fprintf(stderr, "%s ", path.c_str());
#endif
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
@ -473,18 +469,12 @@ struct TestApplicationCallback : IApplicationCallback {
} // namespace boo } // namespace boo
#if !WINDOWS_STORE #if !WINDOWS_STORE
#if _WIN32 int main(int argc, char** argv) {
int wmain(int argc, const boo::SystemChar** argv)
#else
int main(int argc, const boo::SystemChar** argv)
#endif
{
logvisor::RegisterStandardExceptions(); logvisor::RegisterStandardExceptions();
logvisor::RegisterConsoleLogger(); logvisor::RegisterConsoleLogger();
boo::TestApplicationCallback appCb; boo::TestApplicationCallback appCb;
int ret = ApplicationRun(boo::IApplication::EPlatformType::Auto, appCb, _SYS_STR("boo"), _SYS_STR("boo"), argc, argv, int ret = ApplicationRun(boo::IApplication::EPlatformType::Auto, appCb, "boo", "boo", argc, argv,
{}, 1, 1, true); {}, 1, 1, true);
printf("IM DYING!!\n");
return ret; return ret;
} }
@ -496,26 +486,20 @@ using namespace Windows::ApplicationModel::Core;
logvisor::RegisterConsoleLogger(); logvisor::RegisterConsoleLogger();
boo::TestApplicationCallback appCb; boo::TestApplicationCallback appCb;
boo::ViewProvider ^ viewProvider = boo::ViewProvider ^ viewProvider =
ref new boo::ViewProvider(appCb, _SYS_STR("boo"), _SYS_STR("boo"), _SYS_STR("boo"), params, false); ref new boo::ViewProvider(appCb, "boo", "boo", "boo", params, false);
CoreApplication::Run(viewProvider); CoreApplication::Run(viewProvider);
return 0; return 0;
} }
#endif #endif
#if _WIN32 && !WINDOWS_STORE #if _WIN32 && !WINDOWS_STORE
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int) { #include <nowide/args.hpp>
int argc = 0;
const boo::SystemChar** argv;
if (lpCmdLine[0])
argv = (const wchar_t**)(CommandLineToArgvW(lpCmdLine, &argc));
static boo::SystemChar selfPath[1024];
GetModuleFileNameW(nullptr, selfPath, 1024);
static const boo::SystemChar* booArgv[32] = {};
booArgv[0] = selfPath;
for (int i = 0; i < argc; ++i)
booArgv[i + 1] = argv[i];
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int) {
int argc = 0;
char** argv = nullptr;
nowide::args _(argc, argv);
logvisor::CreateWin32Console(); logvisor::CreateWin32Console();
return wmain(argc + 1, booArgv); return main(argc, argv);
} }
#endif #endif