FrontendCommon: Support UWP in helper classes

This commit is contained in:
Connor McLaughlin 2021-07-04 19:14:28 +10:00
parent b35a1308c4
commit 99018b51b4
6 changed files with 92 additions and 17 deletions

View File

@ -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 <cstring>
#include <ctime>
#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 <KnownFolders.h>
#include <ShlObj.h>
#include <mmsystem.h>
@ -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<AudioStream> 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

View File

@ -111,6 +111,8 @@ static constexpr std::array<const char*, static_cast<u32>(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> ControllerInterface::Create(Backend type)
#ifdef _WIN32
if (type == Backend::XInput)
return std::make_unique<XInputControllerInterface>();
#endif
#ifdef WITH_DINPUT
if (type == Backend::DInput)
return std::make_unique<DInputControllerInterface>();
#endif

View File

@ -23,6 +23,8 @@ public:
#endif
#ifdef _WIN32
XInput,
#endif
#ifdef WITH_DINPUT
DInput,
#endif
#ifdef ANDROID

View File

@ -251,7 +251,11 @@ bool D3D11HostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view
create_flags |= D3D11_CREATE_DEVICE_DEBUG;
ComPtr<IDXGIFactory> 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<IDXGIFactory2> 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<IDXGISwapChain1> swap_chain1;
hr = factory2->CreateSwapChainForCoreWindow(m_device.Get(), static_cast<IUnknown*>(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<float>(desc.BufferDesc.RefreshRate.Numerator) /
static_cast<float>(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<float>(desc.BufferDesc.RefreshRate.Numerator) /
static_cast<float>(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<IDXGIFactory> 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 {};

View File

@ -4,7 +4,7 @@
#include <cinttypes>
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

View File

@ -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<decltype(m_xinput_get_state)>(GetProcAddress(m_xinput_module, "XInputGetState"));
m_xinput_set_state =
reinterpret_cast<decltype(m_xinput_set_state)>(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.");