From 99018b51b4b135513fc98c6dcf1447729a81ab79 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sun, 4 Jul 2021 19:14:28 +1000 Subject: [PATCH] FrontendCommon: Support UWP in helper classes --- src/frontend-common/common_host_interface.cpp | 17 ++++- src/frontend-common/controller_interface.cpp | 8 +- src/frontend-common/controller_interface.h | 2 + src/frontend-common/d3d11_host_display.cpp | 73 ++++++++++++++++--- src/frontend-common/inhibit_screensaver.cpp | 4 +- .../xinput_controller_interface.cpp | 5 ++ 6 files changed, 92 insertions(+), 17 deletions(-) diff --git a/src/frontend-common/common_host_interface.cpp b/src/frontend-common/common_host_interface.cpp index d0e40914d..ff7c02d1f 100644 --- a/src/frontend-common/common_host_interface.cpp +++ b/src/frontend-common/common_host_interface.cpp @@ -22,7 +22,6 @@ #include "core/system.h" #include "core/texture_replacements.h" #include "core/timers.h" -#include "cubeb_audio_stream.h" #include "fullscreen_ui.h" #include "game_list.h" #include "icon.h" @@ -39,6 +38,10 @@ #include #include +#ifndef _UWP +#include "cubeb_audio_stream.h" +#endif + #ifdef WITH_SDL2 #include "sdl_audio_stream.h" #endif @@ -53,6 +56,7 @@ #ifdef _WIN32 #include "common/windows_headers.h" +#include "xaudio2_audio_stream.h" #include #include #include @@ -173,6 +177,11 @@ void CommonHostInterface::InitializeUserDirectory() result &= FileSystem::CreateDirectory(GetUserDirectoryRelativePath("shaders").c_str(), false); result &= FileSystem::CreateDirectory(GetUserDirectoryRelativePath("textures").c_str(), false); + // Games directory for UWP because it's a pain to create them manually. +#ifdef _UWP + result &= FileSystem::CreateDirectory(GetUserDirectoryRelativePath("games").c_str(), false); +#endif + if (!result) ReportError("Failed to create one or more user directories. This may cause issues at runtime."); } @@ -636,8 +645,10 @@ std::unique_ptr CommonHostInterface::CreateAudioStream(AudioBackend case AudioBackend::Null: return AudioStream::CreateNullAudioStream(); +#ifndef _UWP case AudioBackend::Cubeb: return CubebAudioStream::Create(); +#endif #ifdef _WIN32 case AudioBackend::XAudio2: @@ -997,7 +1008,7 @@ void CommonHostInterface::SetUserDirectory() } else { -#if defined(_WIN32) +#if defined(_WIN32) && !defined(_UWP) // On Windows, use My Documents\DuckStation. PWSTR documents_directory; if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Documents, 0, NULL, &documents_directory))) @@ -3221,7 +3232,7 @@ void CommonHostInterface::SetTimerResolutionIncreased(bool enabled) m_timer_resolution_increased = enabled; -#ifdef _WIN32 +#if defined(_WIN32) && !defined(_UWP) if (enabled) timeBeginPeriod(1); else diff --git a/src/frontend-common/controller_interface.cpp b/src/frontend-common/controller_interface.cpp index a7fda44c8..47e78ccd7 100644 --- a/src/frontend-common/controller_interface.cpp +++ b/src/frontend-common/controller_interface.cpp @@ -111,6 +111,8 @@ static constexpr std::array(ControllerInterface::B #endif #ifdef _WIN32 TRANSLATABLE("ControllerInterface", "XInput"), +#endif +#ifdef WITH_DINPUT TRANSLATABLE("ControllerInterface", "DInput"), #endif #ifdef ANDROID @@ -155,9 +157,11 @@ ControllerInterface::Backend ControllerInterface::GetDefaultBackend() #include "sdl_controller_interface.h" #endif #ifdef _WIN32 -#include "dinput_controller_interface.h" #include "xinput_controller_interface.h" #endif +#ifdef WITH_DINPUT +#include "dinput_controller_interface.h" +#endif #ifdef WITH_EVDEV #include "evdev_controller_interface.h" #endif @@ -171,6 +175,8 @@ std::unique_ptr ControllerInterface::Create(Backend type) #ifdef _WIN32 if (type == Backend::XInput) return std::make_unique(); +#endif +#ifdef WITH_DINPUT if (type == Backend::DInput) return std::make_unique(); #endif diff --git a/src/frontend-common/controller_interface.h b/src/frontend-common/controller_interface.h index 717a97361..cd6930a02 100644 --- a/src/frontend-common/controller_interface.h +++ b/src/frontend-common/controller_interface.h @@ -23,6 +23,8 @@ public: #endif #ifdef _WIN32 XInput, +#endif +#ifdef WITH_DINPUT DInput, #endif #ifdef ANDROID diff --git a/src/frontend-common/d3d11_host_display.cpp b/src/frontend-common/d3d11_host_display.cpp index 72a5754b2..6674d4c77 100644 --- a/src/frontend-common/d3d11_host_display.cpp +++ b/src/frontend-common/d3d11_host_display.cpp @@ -251,7 +251,11 @@ bool D3D11HostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view create_flags |= D3D11_CREATE_DEVICE_DEBUG; ComPtr temp_dxgi_factory; +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) HRESULT hr = CreateDXGIFactory(IID_PPV_ARGS(temp_dxgi_factory.GetAddressOf())); +#else + HRESULT hr = CreateDXGIFactory2(0, IID_PPV_ARGS(temp_dxgi_factory.GetAddressOf())); +#endif if (FAILED(hr)) { Log_ErrorPrintf("Failed to create DXGI factory: 0x%08X", hr); @@ -385,6 +389,9 @@ bool D3D11HostDisplay::DoneRenderContextCurrent() bool D3D11HostDisplay::CreateSwapChain(const DXGI_MODE_DESC* fullscreen_mode) { + HRESULT hr; + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) if (m_window_info.type != WindowInfo::Type::Win32) return false; @@ -423,7 +430,7 @@ bool D3D11HostDisplay::CreateSwapChain(const DXGI_MODE_DESC* fullscreen_mode) swap_chain_desc.BufferDesc.Height, m_using_flip_model_swap_chain ? "flip-discard" : "discard", swap_chain_desc.Windowed ? "windowed" : "full-screen"); - HRESULT hr = m_dxgi_factory->CreateSwapChain(m_device.Get(), &swap_chain_desc, m_swap_chain.GetAddressOf()); + hr = m_dxgi_factory->CreateSwapChain(m_device.Get(), &swap_chain_desc, m_swap_chain.GetAddressOf()); if (FAILED(hr) && m_using_flip_model_swap_chain) { Log_WarningPrintf("Failed to create a flip-discard swap chain, trying discard."); @@ -448,6 +455,42 @@ bool D3D11HostDisplay::CreateSwapChain(const DXGI_MODE_DESC* fullscreen_mode) if (FAILED(hr)) Log_WarningPrintf("MakeWindowAssociation() to disable ALT+ENTER failed"); } +#else + if (m_window_info.type != WindowInfo::Type::WinRT) + return false; + + ComPtr factory2; + hr = m_dxgi_factory.As(&factory2); + if (FAILED(hr)) + { + Log_ErrorPrintf("Failed to get DXGI factory: %08X", hr); + return false; + } + + DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {}; + swap_chain_desc.Width = m_window_info.surface_width; + swap_chain_desc.Height = m_window_info.surface_height; + swap_chain_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + swap_chain_desc.SampleDesc.Count = 1; + swap_chain_desc.BufferCount = 3; + swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swap_chain_desc.SwapEffect = m_using_flip_model_swap_chain ? DXGI_SWAP_EFFECT_FLIP_DISCARD : DXGI_SWAP_EFFECT_DISCARD; + + m_using_allow_tearing = (m_allow_tearing_supported && m_using_flip_model_swap_chain && !fullscreen_mode); + if (m_using_allow_tearing) + swap_chain_desc.Flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING; + + ComPtr swap_chain1; + hr = factory2->CreateSwapChainForCoreWindow(m_device.Get(), static_cast(m_window_info.window_handle), + &swap_chain_desc, nullptr, swap_chain1.GetAddressOf()); + if (FAILED(hr)) + { + Log_ErrorPrintf("CreateSwapChainForCoreWindow failed: 0x%08X", hr); + return false; + } + + m_swap_chain = swap_chain1; +#endif return CreateSwapChainRTV(); } @@ -476,18 +519,22 @@ bool D3D11HostDisplay::CreateSwapChainRTV() m_window_info.surface_width = backbuffer_desc.Width; m_window_info.surface_height = backbuffer_desc.Height; + Log_InfoPrintf("Swap chain buffer size: %ux%u", m_window_info.surface_width, m_window_info.surface_height); - BOOL fullscreen = FALSE; - DXGI_SWAP_CHAIN_DESC desc; - if (SUCCEEDED(m_swap_chain->GetFullscreenState(&fullscreen, nullptr)) && fullscreen && - SUCCEEDED(m_swap_chain->GetDesc(&desc))) + if (m_window_info.type == WindowInfo::Type::Win32) { - m_window_info.surface_refresh_rate = static_cast(desc.BufferDesc.RefreshRate.Numerator) / - static_cast(desc.BufferDesc.RefreshRate.Denominator); - } - else - { - m_window_info.surface_refresh_rate = 0.0f; + BOOL fullscreen = FALSE; + DXGI_SWAP_CHAIN_DESC desc; + if (SUCCEEDED(m_swap_chain->GetFullscreenState(&fullscreen, nullptr)) && fullscreen && + SUCCEEDED(m_swap_chain->GetDesc(&desc))) + { + m_window_info.surface_refresh_rate = static_cast(desc.BufferDesc.RefreshRate.Numerator) / + static_cast(desc.BufferDesc.RefreshRate.Denominator); + } + else + { + m_window_info.surface_refresh_rate = 0.0f; + } } return true; @@ -870,7 +917,11 @@ void D3D11HostDisplay::RenderSoftwareCursor(s32 left, s32 top, s32 width, s32 he HostDisplay::AdapterAndModeList D3D11HostDisplay::StaticGetAdapterAndModeList() { ComPtr dxgi_factory; +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) HRESULT hr = CreateDXGIFactory(IID_PPV_ARGS(dxgi_factory.GetAddressOf())); +#else + HRESULT hr = CreateDXGIFactory2(0, IID_PPV_ARGS(dxgi_factory.GetAddressOf())); +#endif if (FAILED(hr)) return {}; diff --git a/src/frontend-common/inhibit_screensaver.cpp b/src/frontend-common/inhibit_screensaver.cpp index e0650d53d..16e681298 100644 --- a/src/frontend-common/inhibit_screensaver.cpp +++ b/src/frontend-common/inhibit_screensaver.cpp @@ -4,7 +4,7 @@ #include Log_SetChannel(FrontendCommon); -#ifdef _WIN32 +#if defined(_WIN32) && !defined(_UWP) #include "common/windows_headers.h" static bool SetScreensaverInhibitWin32(bool inhibit, const WindowInfo& wi) @@ -93,7 +93,7 @@ static bool SetScreensaverInhibit(bool inhibit, const WindowInfo& wi) { switch (wi.type) { -#ifdef _WIN32 +#if defined(_WIN32) && !defined(_UWP) case WindowInfo::Type::Win32: return SetScreensaverInhibitWin32(inhibit, wi); #endif diff --git a/src/frontend-common/xinput_controller_interface.cpp b/src/frontend-common/xinput_controller_interface.cpp index aa4059246..13d139f91 100644 --- a/src/frontend-common/xinput_controller_interface.cpp +++ b/src/frontend-common/xinput_controller_interface.cpp @@ -23,6 +23,7 @@ ControllerInterface::Backend XInputControllerInterface::GetBackend() const bool XInputControllerInterface::Initialize(CommonHostInterface* host_interface) { +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) m_xinput_module = LoadLibraryW(L"xinput1_4"); if (!m_xinput_module) { @@ -45,6 +46,10 @@ bool XInputControllerInterface::Initialize(CommonHostInterface* host_interface) reinterpret_cast(GetProcAddress(m_xinput_module, "XInputGetState")); m_xinput_set_state = reinterpret_cast(GetProcAddress(m_xinput_module, "XInputSetState")); +#else + m_xinput_get_state = XInputGetState; + m_xinput_set_state = XInputSetState; +#endif if (!m_xinput_get_state || !m_xinput_set_state) { Log_ErrorPrintf("Failed to get XInput function pointers.");