diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7ae69104f3..9f46f7f4c3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -128,6 +128,10 @@ jobs: - name: Add MSBuild to PATH uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # v2.0.0 + - name: Restore NuGet packages + working-directory: ${{ github.workspace }}/UWP + run: nuget restore PPSSPP_UWP.sln + - name: Build UWP working-directory: ${{ env.GITHUB_WORKSPACE }} run: msbuild /m /p:TrackFileAccess=false /p:Configuration=${{ env.BUILD_CONFIGURATION }} /p:Platform=x64 /p:AppxPackageSigningEnabled=false UWP/PPSSPP_UWP.sln diff --git a/.github/workflows/manual_generate_uwp.yml b/.github/workflows/manual_generate_uwp.yml index 9142d026cb..66e7da6c4d 100644 --- a/.github/workflows/manual_generate_uwp.yml +++ b/.github/workflows/manual_generate_uwp.yml @@ -80,6 +80,11 @@ jobs: echo "single ${ github.event.inputs.buildConfiguration }" echo $env:GITHUB_WORKSPACE + - name: Restore NuGet packages + working-directory: ${{ github.workspace }}/UWP + run: | + nuget restore PPSSPP_UWP.sln + - name: Execute MSIX build working-directory: ${{ github.workspace }} env: diff --git a/UWP/.gitignore b/UWP/.gitignore index dae79e7cea..d89ce275a1 100644 --- a/UWP/.gitignore +++ b/UWP/.gitignore @@ -2,6 +2,8 @@ Assets AppPackages +Generated Files +packages x64 ARM ARM64 diff --git a/UWP/App.cpp b/UWP/App.cpp index bc5909207d..48bfc60048 100644 --- a/UWP/App.cpp +++ b/UWP/App.cpp @@ -3,7 +3,6 @@ #include "pch.h" #include "App.h" -#include #include #include "Common/Net/HTTPClient.h" @@ -23,27 +22,26 @@ #include using namespace UWP; - -using namespace concurrency; -using namespace Windows::ApplicationModel; -using namespace Windows::ApplicationModel::Core; -using namespace Windows::ApplicationModel::Activation; -using namespace Windows::UI::Core; -using namespace Windows::UI::Input; -using namespace Windows::System; -using namespace Windows::Foundation; -using namespace Windows::Graphics::Display; + +using namespace winrt; +using namespace winrt::Windows::ApplicationModel; +using namespace winrt::Windows::ApplicationModel::Core; +using namespace winrt::Windows::ApplicationModel::Activation; +using namespace winrt::Windows::UI::Core; +using namespace winrt::Windows::UI::Input; +using namespace winrt::Windows::System; +using namespace winrt::Windows::Foundation; +using namespace winrt::Windows::Graphics::Display; // The main function is only used to initialize our IFrameworkView class. -[Platform::MTAThread] -int main(Platform::Array^) { - auto direct3DApplicationSource = ref new Direct3DApplicationSource(); - CoreApplication::Run(direct3DApplicationSource); +int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int) { + winrt::init_apartment(); + CoreApplication::Run(winrt::make()); return 0; } -IFrameworkView^ Direct3DApplicationSource::CreateView() { - return ref new App(); +IFrameworkView Direct3DApplicationSource::CreateView() { + return winrt::make(); } App::App() : @@ -57,8 +55,8 @@ void App::InitialPPSSPP() { net::Init(); // Get install location - auto packageDirectory = Package::Current->InstalledPath; - const Path& exePath = Path(FromPlatformString(packageDirectory)); + auto packageDirectory = Package::Current().InstalledPath(); + const Path& exePath = Path(FromHString(packageDirectory)); g_VFS.Register("", new DirectoryReader(exePath / "Content")); g_VFS.Register("", new DirectoryReader(exePath)); @@ -66,7 +64,7 @@ void App::InitialPPSSPP() { g_Config.flash0Directory = exePath / "assets/flash0"; // Prepare for initialization - std::wstring internalDataFolderW = ApplicationData::Current->LocalFolder->Path->Data(); + std::wstring internalDataFolderW = std::wstring(winrt::Windows::Storage::ApplicationData::Current().LocalFolder().Path()); g_Config.internalDataDirectory = Path(internalDataFolderW); g_Config.memStickDirectory = g_Config.internalDataDirectory; @@ -89,7 +87,9 @@ void App::InitialPPSSPP() { // Since we don't have any async operation in `NativeInit` // it's better to call it here const char* argv[2] = { "fake", nullptr }; - std::string cacheFolder = ConvertWStringToUTF8(ApplicationData::Current->TemporaryFolder->Path->Data()); + std::string cacheFolder = ConvertWStringToUTF8( + std::wstring(winrt::Windows::Storage::ApplicationData::Current().TemporaryFolder().Path()) + ); // We will not be able to use `argv` // since launch parameters usually handled by `OnActivated` // and `OnActivated` will be invoked later, even after `PPSSPP_UWPMain(..)` @@ -106,65 +106,49 @@ void App::InitialPPSSPP() { } // The first method called when the IFrameworkView is being created. -void App::Initialize(CoreApplicationView^ applicationView) { +void App::Initialize(const CoreApplicationView& applicationView) { // Register event handlers for app lifecycle. This example includes Activated, so that we // can make the CoreWindow active and start rendering on the window. - applicationView->Activated += - ref new TypedEventHandler(this, &App::OnActivated); - - CoreApplication::Suspending += - ref new EventHandler(this, &App::OnSuspending); - - CoreApplication::Resuming += - ref new EventHandler(this, &App::OnResuming); + applicationView.Activated({ this, &App::OnActivated }); + CoreApplication::Suspending({ this, &App::OnSuspending }); + CoreApplication::Resuming({ this, &App::OnResuming }); } // Called when the CoreWindow object is created (or re-created). -void App::SetWindow(CoreWindow^ window) { - window->SizeChanged += - ref new TypedEventHandler(this, &App::OnWindowSizeChanged); +void App::SetWindow(const CoreWindow& window) { + window.SizeChanged({ this, &App::OnWindowSizeChanged }); + window.VisibilityChanged({ this, &App::OnVisibilityChanged }); + window.Closed({ this, &App::OnWindowClosed }); - window->VisibilityChanged += - ref new TypedEventHandler(this, &App::OnVisibilityChanged); + DisplayInformation currentDisplayInformation = DisplayInformation::GetForCurrentView(); - window->Closed += - ref new TypedEventHandler(this, &App::OnWindowClosed); + currentDisplayInformation.DpiChanged({ this, &App::OnDpiChanged }); + currentDisplayInformation.OrientationChanged({ this, &App::OnOrientationChanged }); + DisplayInformation::DisplayContentsInvalidated({ this, &App::OnDisplayContentsInvalidated }); - DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView(); + window.KeyDown({ this, &App::OnKeyDown }); + window.KeyUp({ this, &App::OnKeyUp }); + window.CharacterReceived({ this, &App::OnCharacterReceived }); - currentDisplayInformation->DpiChanged += - ref new TypedEventHandler(this, &App::OnDpiChanged); + window.PointerMoved({ this, &App::OnPointerMoved }); + window.PointerEntered({ this, &App::OnPointerEntered }); + window.PointerExited({ this, &App::OnPointerExited }); + window.PointerPressed({ this, &App::OnPointerPressed }); + window.PointerReleased({ this, &App::OnPointerReleased }); + window.PointerCaptureLost({ this, &App::OnPointerCaptureLost }); + window.PointerWheelChanged({ this, &App::OnPointerWheelChanged }); - currentDisplayInformation->OrientationChanged += - ref new TypedEventHandler(this, &App::OnOrientationChanged); - - DisplayInformation::DisplayContentsInvalidated += - ref new TypedEventHandler(this, &App::OnDisplayContentsInvalidated); - - window->KeyDown += ref new TypedEventHandler(this, &App::OnKeyDown); - window->KeyUp += ref new TypedEventHandler(this, &App::OnKeyUp); - window->CharacterReceived += ref new TypedEventHandler(this, &App::OnCharacterReceived); - - window->PointerMoved += ref new TypedEventHandler(this, &App::OnPointerMoved); - window->PointerEntered += ref new TypedEventHandler(this, &App::OnPointerEntered); - window->PointerExited += ref new TypedEventHandler(this, &App::OnPointerExited); - window->PointerPressed += ref new TypedEventHandler(this, &App::OnPointerPressed); - window->PointerReleased += ref new TypedEventHandler(this, &App::OnPointerReleased); - window->PointerCaptureLost += ref new TypedEventHandler(this, &App::OnPointerCaptureLost); - window->PointerWheelChanged += ref new TypedEventHandler(this, &App::OnPointerWheelChanged); - - if (Windows::Foundation::Metadata::ApiInformation::IsTypePresent("Windows.Phone.UI.Input.HardwareButtons")) { + if (winrt::Windows::Foundation::Metadata::ApiInformation::IsTypePresent(L"Windows.Phone.UI.Input.HardwareButtons")) { m_hardwareButtons.insert(HardwareButton::BACK); } - if (Windows::System::Profile::AnalyticsInfo::VersionInfo->DeviceFamily == "Windows.Mobile") { + if (winrt::Windows::System::Profile::AnalyticsInfo::VersionInfo().DeviceFamily() == L"Windows.Mobile") { m_isPhone = true; } - Windows::UI::Core::SystemNavigationManager::GetForCurrentView()-> - BackRequested += ref new Windows::Foundation::EventHandler< - Windows::UI::Core::BackRequestedEventArgs^>( - this, &App::App_BackRequested); + winrt::Windows::UI::Core::SystemNavigationManager::GetForCurrentView().BackRequested( + { this, &App::App_BackRequested } + ); InitialPPSSPP(); } @@ -176,80 +160,80 @@ bool App::HasBackButton() { return false; } -void App::App_BackRequested(Platform::Object^ sender, Windows::UI::Core::BackRequestedEventArgs^ e) { +void App::App_BackRequested(const IInspectable& sender, const BackRequestedEventArgs& e) { if (m_isPhone) { - e->Handled = m_main->OnHardwareButton(HardwareButton::BACK); + e.Handled(m_main->OnHardwareButton(HardwareButton::BACK)); } else { - e->Handled = true; + e.Handled(true); } } -void App::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) { - m_main->OnKeyDown(args->KeyStatus.ScanCode, args->VirtualKey, args->KeyStatus.RepeatCount); +void App::OnKeyDown(const CoreWindow& sender, const KeyEventArgs& args) { + m_main->OnKeyDown(args.KeyStatus().ScanCode, args.VirtualKey(), args.KeyStatus().RepeatCount); } -void App::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) { - m_main->OnKeyUp(args->KeyStatus.ScanCode, args->VirtualKey); +void App::OnKeyUp(const CoreWindow& sender, const KeyEventArgs& args) { + m_main->OnKeyUp(args.KeyStatus().ScanCode, args.VirtualKey()); } -void App::OnCharacterReceived(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CharacterReceivedEventArgs^ args) { - m_main->OnCharacterReceived(args->KeyStatus.ScanCode, args->KeyCode); +void App::OnCharacterReceived(const CoreWindow& sender, const CharacterReceivedEventArgs& args) { + m_main->OnCharacterReceived(args.KeyStatus().ScanCode, args.KeyCode()); } -void App::OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) { - int pointerId = touchMap_.TouchId(args->CurrentPoint->PointerId); +void App::OnPointerMoved(const CoreWindow& sender, const PointerEventArgs& args) { + int pointerId = touchMap_.TouchId(args.CurrentPoint().PointerId()); if (pointerId < 0) return; - float X = args->CurrentPoint->Position.X; - float Y = args->CurrentPoint->Position.Y; - int64_t timestamp = args->CurrentPoint->Timestamp; + float X = args.CurrentPoint().Position().X; + float Y = args.CurrentPoint().Position().Y; + int64_t timestamp = args.CurrentPoint().Timestamp(); m_main->OnTouchEvent(TouchInputFlags::MOVE, pointerId, X, Y, (double)timestamp); } -void App::OnPointerEntered(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) { +void App::OnPointerEntered(const CoreWindow& sender, const PointerEventArgs& args) { } -void App::OnPointerExited(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) { +void App::OnPointerExited(const CoreWindow& sender, const PointerEventArgs& args) { } -void App::OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) { - int pointerId = touchMap_.TouchId(args->CurrentPoint->PointerId); +void App::OnPointerPressed(const CoreWindow& sender, const PointerEventArgs& args) { + int pointerId = touchMap_.TouchId(args.CurrentPoint().PointerId()); if (pointerId < 0) - pointerId = touchMap_.AddNewTouch(args->CurrentPoint->PointerId); + pointerId = touchMap_.AddNewTouch(args.CurrentPoint().PointerId()); - float X = args->CurrentPoint->Position.X; - float Y = args->CurrentPoint->Position.Y; - int64_t timestamp = args->CurrentPoint->Timestamp; + float X = args.CurrentPoint().Position().X; + float Y = args.CurrentPoint().Position().Y; + int64_t timestamp = args.CurrentPoint().Timestamp(); m_main->OnTouchEvent(TouchInputFlags::DOWN | TouchInputFlags::MOVE, pointerId, X, Y, (double)timestamp); if (!m_isPhone) { - sender->SetPointerCapture(); + sender.SetPointerCapture(); } } -void App::OnPointerReleased(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) { - int pointerId = touchMap_.RemoveTouch(args->CurrentPoint->PointerId); +void App::OnPointerReleased(const CoreWindow& sender, const PointerEventArgs& args) { + int pointerId = touchMap_.RemoveTouch(args.CurrentPoint().PointerId()); if (pointerId < 0) return; - float X = args->CurrentPoint->Position.X; - float Y = args->CurrentPoint->Position.Y; - int64_t timestamp = args->CurrentPoint->Timestamp; + float X = args.CurrentPoint().Position().X; + float Y = args.CurrentPoint().Position().Y; + int64_t timestamp = args.CurrentPoint().Timestamp(); m_main->OnTouchEvent(TouchInputFlags::UP | TouchInputFlags::MOVE, pointerId, X, Y, (double)timestamp); if (!m_isPhone) { - sender->ReleasePointerCapture(); + sender.ReleasePointerCapture(); } } -void App::OnPointerCaptureLost(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) { +void App::OnPointerCaptureLost(const CoreWindow& sender, const PointerEventArgs& args) { } -void App::OnPointerWheelChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) { +void App::OnPointerWheelChanged(const CoreWindow& sender, const PointerEventArgs& args) { int pointerId = 0; // irrelevant - float delta = (float)args->CurrentPoint->GetCurrentPoint(args->CurrentPoint->PointerId)->Properties->MouseWheelDelta; + float delta = (float)args.CurrentPoint().Properties().MouseWheelDelta(); m_main->OnMouseWheel(delta); } // Initializes scene resources, or loads a previously saved app state. -void App::Load(Platform::String^ entryPoint) { +void App::Load(const hstring& entryPoint) { if (m_main == nullptr) { m_main = std::unique_ptr(new PPSSPP_UWPMain(this, m_deviceResources)); } @@ -259,11 +243,11 @@ void App::Load(Platform::String^ entryPoint) { void App::Run() { while (!m_windowClosed) { if (m_windowVisible) { - CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent); + CoreWindow::GetForCurrentThread().Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent); m_main->Render(); // TODO: Adopt some practices from m_deviceResources->Present(); } else { - CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending); + CoreWindow::GetForCurrentThread().Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending); } } } @@ -275,36 +259,36 @@ void App::Uninitialize() { } // Application lifecycle event handlers. -void App::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args) { +void App::OnActivated(const CoreApplicationView& applicationView, const IActivatedEventArgs& args) { // Run() won't start until the CoreWindow is activated. - CoreWindow::GetForCurrentThread()->Activate(); + CoreWindow::GetForCurrentThread().Activate(); // On mobile, we force-enter fullscreen mode. if (m_isPhone) g_Config.iForceFullScreen = 1; if (g_Config.UseFullScreen()) - Windows::UI::ViewManagement::ApplicationView::GetForCurrentView()->TryEnterFullScreenMode(); + winrt::Windows::UI::ViewManagement::ApplicationView::GetForCurrentView().TryEnterFullScreenMode(); //Detect if app started or activated by launch item (file, uri) DetectLaunchItem(args); } -void App::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args) { +void App::OnSuspending(const IInspectable& sender, const SuspendingEventArgs& args) { // Save app state asynchronously after requesting a deferral. Holding a deferral // indicates that the application is busy performing suspending operations. Be // aware that a deferral may not be held indefinitely. After about five seconds, // the app will be forced to exit. - SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral(); + SuspendingDeferral deferral = args.SuspendingOperation().GetDeferral(); auto app = this; - create_task([app, deferral]() { + std::thread([app, deferral]() { g_Config.Save("App::OnSuspending"); app->m_deviceResources->Trim(); - deferral->Complete(); - }); + deferral.Complete(); + }).detach(); } -void App::OnResuming(Platform::Object^ sender, Platform::Object^ args) { +void App::OnResuming(const IInspectable& sender, const IInspectable& args) { // Restore any data or state that was unloaded on suspend. By default, data // and state are persisted when resuming from suspend. Note that this event // does not occur if the app was previously terminated. @@ -313,17 +297,16 @@ void App::OnResuming(Platform::Object^ sender, Platform::Object^ args) { } // Window event handlers. - -void App::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args) { - auto view = Windows::UI::ViewManagement::ApplicationView::GetForCurrentView(); - g_Config.bFullScreen = view->IsFullScreenMode; +void App::OnWindowSizeChanged(const CoreWindow& sender, const WindowSizeChangedEventArgs& args) { + auto view = winrt::Windows::UI::ViewManagement::ApplicationView::GetForCurrentView(); + g_Config.bFullScreen = view.IsFullScreenMode(); g_Config.iForceFullScreen = -1; - float width = sender->Bounds.Width; - float height = sender->Bounds.Height; + float width = sender.Bounds().Width; + float height = sender.Bounds().Height; float scale = m_deviceResources->GetDpi() / 96.0f; - m_deviceResources->SetLogicalSize(Size(width, height)); + m_deviceResources->SetLogicalSize(winrt::Windows::Foundation::Size(width, height)); if (m_main) { m_main->CreateWindowSizeDependentResources(); } @@ -335,30 +318,29 @@ void App::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ ar } } -void App::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) { - m_windowVisible = args->Visible; +void App::OnVisibilityChanged(const CoreWindow& sender, const VisibilityChangedEventArgs& args) { + m_windowVisible = args.Visible(); } -void App::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) { +void App::OnWindowClosed(const CoreWindow& sender, const CoreWindowEventArgs& args) { m_windowClosed = true; } // DisplayInformation event handlers. - -void App::OnDpiChanged(DisplayInformation^ sender, Object^ args) { +void App::OnDpiChanged(const DisplayInformation& sender, const IInspectable& args) { // Note: The value for LogicalDpi retrieved here may not match the effective DPI of the app // if it is being scaled for high resolution devices. Once the DPI is set on DeviceResources, // you should always retrieve it using the GetDpi method. // See DeviceResources.cpp for more details. - m_deviceResources->SetDpi(sender->LogicalDpi); + m_deviceResources->SetDpi(sender.LogicalDpi()); m_main->CreateWindowSizeDependentResources(); } -void App::OnOrientationChanged(DisplayInformation^ sender, Object^ args) { - m_deviceResources->SetCurrentOrientation(sender->CurrentOrientation); +void App::OnOrientationChanged(const DisplayInformation& sender, const IInspectable& args) { + m_deviceResources->SetCurrentOrientation(sender.CurrentOrientation()); m_main->CreateWindowSizeDependentResources(); } -void App::OnDisplayContentsInvalidated(DisplayInformation^ sender, Object^ args) { +void App::OnDisplayContentsInvalidated(const DisplayInformation& sender, const IInspectable& args) { m_deviceResources->ValidateDevice(); } diff --git a/UWP/App.h b/UWP/App.h index 595b618fc4..6db53db1cf 100644 --- a/UWP/App.h +++ b/UWP/App.h @@ -52,52 +52,51 @@ namespace UWP { }; // Main entry point for our app. Connects the app with the Windows shell and handles application lifecycle events. - ref class App sealed : public Windows::ApplicationModel::Core::IFrameworkView { + struct App : winrt::implements { public: App(); // IFrameworkView Methods. - virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView); - virtual void SetWindow(Windows::UI::Core::CoreWindow^ window); - virtual void Load(Platform::String^ entryPoint); - virtual void Run(); - virtual void Uninitialize(); + void Initialize(const winrt::Windows::ApplicationModel::Core::CoreApplicationView& applicationView); + void SetWindow(const winrt::Windows::UI::Core::CoreWindow& window); + void Load(const winrt::hstring& entryPoint); + void Run(); + void Uninitialize(); bool HasBackButton(); - protected: + private: // Application lifecycle event handlers. - void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args); - void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ args); - void OnResuming(Platform::Object^ sender, Platform::Object^ args); + void OnActivated(const winrt::Windows::ApplicationModel::Core::CoreApplicationView& applicationView, const winrt::Windows::ApplicationModel::Activation::IActivatedEventArgs& args); + void OnSuspending(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::ApplicationModel::SuspendingEventArgs& args); + void OnResuming(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args); // Window event handlers. - void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args); - void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args); - void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args); + void OnWindowSizeChanged(const winrt::Windows::UI::Core::CoreWindow& sender, const winrt::Windows::UI::Core::WindowSizeChangedEventArgs& args); + void OnVisibilityChanged(const winrt::Windows::UI::Core::CoreWindow& sender, const winrt::Windows::UI::Core::VisibilityChangedEventArgs& args); + void OnWindowClosed(const winrt::Windows::UI::Core::CoreWindow& sender, const winrt::Windows::UI::Core::CoreWindowEventArgs& args); // DisplayInformation event handlers. - void OnDpiChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args); - void OnOrientationChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args); - void OnDisplayContentsInvalidated(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args); + void OnDpiChanged(const winrt::Windows::Graphics::Display::DisplayInformation& sender, const winrt::Windows::Foundation::IInspectable& args); + void OnOrientationChanged(const winrt::Windows::Graphics::Display::DisplayInformation& sender, const winrt::Windows::Foundation::IInspectable& args); + void OnDisplayContentsInvalidated(const winrt::Windows::Graphics::Display::DisplayInformation& sender, const winrt::Windows::Foundation::IInspectable& args); // Input - void OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args); - void OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args); - void OnCharacterReceived(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CharacterReceivedEventArgs^ args); + void OnKeyDown(const winrt::Windows::UI::Core::CoreWindow& sender, const winrt::Windows::UI::Core::KeyEventArgs& args); + void OnKeyUp(const winrt::Windows::UI::Core::CoreWindow& sender, const winrt::Windows::UI::Core::KeyEventArgs& args); + void OnCharacterReceived(const winrt::Windows::UI::Core::CoreWindow& sender, const winrt::Windows::UI::Core::CharacterReceivedEventArgs& args); - void OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args); - void OnPointerEntered(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args); - void OnPointerExited(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args); - void OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args); - void OnPointerReleased(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args); - void OnPointerCaptureLost(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args); - void OnPointerWheelChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args); + void OnPointerMoved(const winrt::Windows::UI::Core::CoreWindow& sender, const winrt::Windows::UI::Core::PointerEventArgs& args); + void OnPointerEntered(const winrt::Windows::UI::Core::CoreWindow& sender, const winrt::Windows::UI::Core::PointerEventArgs& args); + void OnPointerExited(const winrt::Windows::UI::Core::CoreWindow& sender, const winrt::Windows::UI::Core::PointerEventArgs& args); + void OnPointerPressed(const winrt::Windows::UI::Core::CoreWindow& sender, const winrt::Windows::UI::Core::PointerEventArgs& args); + void OnPointerReleased(const winrt::Windows::UI::Core::CoreWindow& sender, const winrt::Windows::UI::Core::PointerEventArgs& args); + void OnPointerCaptureLost(const winrt::Windows::UI::Core::CoreWindow& sender, const winrt::Windows::UI::Core::PointerEventArgs& args); + void OnPointerWheelChanged(const winrt::Windows::UI::Core::CoreWindow& sender, const winrt::Windows::UI::Core::PointerEventArgs& args); - void App_BackRequested(Platform::Object^ sender, Windows::UI::Core::BackRequestedEventArgs^ e); + void App_BackRequested(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Core::BackRequestedEventArgs& e); void InitialPPSSPP(); - private: std::shared_ptr m_deviceResources; std::set m_hardwareButtons; std::unique_ptr m_main; @@ -109,8 +108,6 @@ namespace UWP { }; } -ref class Direct3DApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource -{ -public: - virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView(); +struct Direct3DApplicationSource : winrt::implements { + winrt::Windows::ApplicationModel::Core::IFrameworkView CreateView(); }; diff --git a/UWP/Common/DeviceResources.cpp b/UWP/Common/DeviceResources.cpp index 6a2edb7d3f..2d38c28df0 100644 --- a/UWP/Common/DeviceResources.cpp +++ b/UWP/Common/DeviceResources.cpp @@ -9,12 +9,9 @@ using namespace D2D1; using namespace DirectX; -using namespace Microsoft::WRL; -using namespace Windows::Foundation; -using namespace Windows::Graphics::Display; -using namespace Windows::UI::Core; -using namespace Windows::UI::Xaml::Controls; -using namespace Platform; +using namespace winrt::Windows::Foundation; +using namespace winrt::Windows::Graphics::Display; +using namespace winrt::Windows::UI::Core; namespace DisplayMetrics { @@ -104,7 +101,7 @@ void DX::DeviceResources::CreateDeviceIndependentResources() D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory3), &options, - &m_d2dFactory + m_d2dFactory.put_void() ) ); @@ -113,7 +110,7 @@ void DX::DeviceResources::CreateDeviceIndependentResources() DWriteCreateFactory( DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory3), - &m_dwriteFactory + reinterpret_cast<::IUnknown**>(m_dwriteFactory.put()) ) ); @@ -123,7 +120,7 @@ void DX::DeviceResources::CreateDeviceIndependentResources() CLSID_WICImagingFactory2, nullptr, CLSCTX_INPROC_SERVER, - IID_PPV_ARGS(&m_wicFactory) + IID_PPV_ARGS(m_wicFactory.put()) ) ); } @@ -161,8 +158,8 @@ void DX::DeviceResources::CreateDeviceResources(IDXGIAdapter* vAdapter) }; // Create the Direct3D 11 API device object and a corresponding context. - ComPtr device; - ComPtr context; + winrt::com_ptr device; + winrt::com_ptr context; auto hardwareType = (vAdapter != nullptr ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE); HRESULT hr = D3D11CreateDevice( vAdapter, // Specify nullptr to use the default adapter. @@ -172,9 +169,9 @@ void DX::DeviceResources::CreateDeviceResources(IDXGIAdapter* vAdapter) featureLevels, // List of feature levels this app can support. ARRAYSIZE(featureLevels), // Size of the list above. D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps. - &device, // Returns the Direct3D device created. + device.put(), // Returns the Direct3D device created. &m_d3dFeatureLevel, // Returns feature level of device created. - &context // Returns the device immediate context. + context.put() // Returns the device immediate context. ); if (FAILED(hr)) @@ -191,9 +188,9 @@ void DX::DeviceResources::CreateDeviceResources(IDXGIAdapter* vAdapter) featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, - &device, + device.put(), &m_d3dFeatureLevel, - &context + context.put() ) ); } @@ -207,54 +204,42 @@ void DX::DeviceResources::CreateDeviceResources(IDXGIAdapter* vAdapter) } // Store pointers to the Direct3D 11.3 API device and immediate context. - DX::ThrowIfFailed( - device.As(&m_d3dDevice) - ); + m_d3dDevice = device.as(); + m_d3dContext = context.as(); + m_dxgiDevice = m_d3dDevice.as(); DX::ThrowIfFailed( - context.As(&m_d3dContext) - ); - - DX::ThrowIfFailed( - m_d3dDevice.As(&m_dxgiDevice) + m_dxgiDevice->GetAdapter(m_dxgiAdapter.put()) ); + winrt::com_ptr adapterParent; DX::ThrowIfFailed( - m_dxgiDevice->GetAdapter(&m_dxgiAdapter) - ); - - DX::ThrowIfFailed( - m_dxgiAdapter->GetParent(IID_PPV_ARGS(&m_dxgiFactory)) + m_dxgiAdapter->GetParent(IID_PPV_ARGS(adapterParent.put())) ); + m_dxgiFactory = adapterParent.as(); // Create the Direct2D device object and a corresponding context. DX::ThrowIfFailed( - m_d3dDevice.As(&m_dxgiDevice) - ); - - DX::ThrowIfFailed( - m_d2dFactory->CreateDevice(m_dxgiDevice.Get(), &m_d2dDevice) + m_d2dFactory->CreateDevice(m_dxgiDevice.get(), m_d2dDevice.put()) ); DX::ThrowIfFailed( m_d2dDevice->CreateDeviceContext( D2D1_DEVICE_CONTEXT_OPTIONS_NONE, - &m_d2dContext + m_d2dContext.put() ) ); } -bool DX::DeviceResources::CreateAdaptersList(ComPtr device) { - ComPtr dxgi_device; - DX::ThrowIfFailed( - device.As(&dxgi_device) - ); +bool DX::DeviceResources::CreateAdaptersList(winrt::com_ptr device) { + auto dxgi_device = device.as(); - Microsoft::WRL::ComPtr deviceAdapter; - dxgi_device->GetAdapter(&deviceAdapter); + winrt::com_ptr deviceAdapter; + dxgi_device->GetAdapter(deviceAdapter.put()); - Microsoft::WRL::ComPtr deviceFactory; - deviceAdapter->GetParent(IID_PPV_ARGS(&deviceFactory)); + winrt::com_ptr adapterParent; + deviceAdapter->GetParent(IID_PPV_ARGS(adapterParent.put())); + auto deviceFactory = adapterParent.as(); // Current adapter (Get current adapter name) DXGI_ADAPTER_DESC currentDefaultAdapterDesc; @@ -264,8 +249,8 @@ bool DX::DeviceResources::CreateAdaptersList(ComPtr device) { UINT i = 0; IDXGIAdapter* pAdapter; IDXGIAdapter* customAdapter = nullptr; - auto deviceInfo = Windows::System::Profile::AnalyticsInfo::VersionInfo; - bool isXbox = deviceInfo->DeviceFamily == "Windows.Xbox"; + auto deviceInfo = winrt::Windows::System::Profile::AnalyticsInfo::VersionInfo(); + bool isXbox = deviceInfo.DeviceFamily() == L"Windows.Xbox"; while (deviceFactory->EnumAdapters(i, &pAdapter) != DXGI_ERROR_NOT_FOUND) { ++i; @@ -284,7 +269,6 @@ bool DX::DeviceResources::CreateAdaptersList(ComPtr device) { } } } - deviceFactory->Release(); if (m_vAdapters.size() == 1) { // Only one (default) adapter, clear the list to hide device option from settings @@ -308,7 +292,7 @@ void DX::DeviceResources::CreateWindowSizeDependentResources() // we don't have to do that since we can easily get the current window auto coreWindow = CoreWindow::GetForCurrentThread(); - SetWindow(coreWindow); + SetWindow(); // Clear the previous window size specific context. ID3D11RenderTargetView* nullViews[] = {nullptr}; @@ -373,19 +357,17 @@ void DX::DeviceResources::CreateWindowSizeDependentResources() swapChainDesc.Scaling = scaling; swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; - ComPtr swapChain; + winrt::com_ptr swapChain; DX::ThrowIfFailed( m_dxgiFactory->CreateSwapChainForCoreWindow( - m_d3dDevice.Get(), - reinterpret_cast(coreWindow), + m_d3dDevice.get(), + winrt::get_unknown(coreWindow), &swapChainDesc, nullptr, - &swapChain + swapChain.put() ) ); - DX::ThrowIfFailed( - swapChain.As(&m_swapChain) - ); + m_swapChain = swapChain.as(); // Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and // ensures that the application will only render after each VSync, minimizing power consumption. @@ -429,7 +411,7 @@ void DX::DeviceResources::CreateWindowSizeDependentResources() break; default: - throw ref new FailureException(); + winrt::throw_hresult(E_FAIL); } DX::ThrowIfFailed( @@ -437,16 +419,16 @@ void DX::DeviceResources::CreateWindowSizeDependentResources() ); // Create a render target view of the swap chain back buffer. - ComPtr backBuffer; + winrt::com_ptr backBuffer; DX::ThrowIfFailed( - m_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer)) + m_swapChain->GetBuffer(0, IID_PPV_ARGS(backBuffer.put())) ); DX::ThrowIfFailed( m_d3dDevice->CreateRenderTargetView1( - backBuffer.Get(), + backBuffer.get(), nullptr, - &m_d3dRenderTargetView + m_d3dRenderTargetView.put() ) ); @@ -470,20 +452,20 @@ void DX::DeviceResources::CreateWindowSizeDependentResources() m_dpi ); - ComPtr dxgiBackBuffer; + winrt::com_ptr dxgiBackBuffer; DX::ThrowIfFailed( - m_swapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer)) + m_swapChain->GetBuffer(0, IID_PPV_ARGS(dxgiBackBuffer.put())) ); DX::ThrowIfFailed( m_d2dContext->CreateBitmapFromDxgiSurface( - dxgiBackBuffer.Get(), + dxgiBackBuffer.get(), &bitmapProperties, - &m_d2dTargetBitmap + m_d2dTargetBitmap.put() ) ); - m_d2dContext->SetTarget(m_d2dTargetBitmap.Get()); + m_d2dContext->SetTarget(m_d2dTargetBitmap.get()); m_d2dContext->SetDpi(m_effectiveDpi, m_effectiveDpi); // Grayscale text anti-aliasing is recommended for all Windows Store apps. @@ -494,7 +476,7 @@ void DX::DeviceResources::CreateWindowSizeDependentResources() void DX::DeviceResources::UpdateRenderTargetSize() { m_effectiveDpi = m_dpi; - if (Windows::System::Profile::AnalyticsInfo::VersionInfo->DeviceFamily == L"Windows.Xbox") + if (winrt::Windows::System::Profile::AnalyticsInfo::VersionInfo().DeviceFamily() == L"Windows.Xbox") { m_effectiveDpi = 96.0f / static_cast(m_logicalSize.Height) * 1080.0f; } @@ -527,46 +509,47 @@ void DX::DeviceResources::UpdateRenderTargetSize() } // This method is called when the CoreWindow is created (or re-created). -void DX::DeviceResources::SetWindow(CoreWindow^ window) +void DX::DeviceResources::SetWindow() { - DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView(); + auto window = CoreWindow::GetForCurrentThread(); + DisplayInformation currentDisplayInformation = DisplayInformation::GetForCurrentView(); - if (Windows::System::Profile::AnalyticsInfo::VersionInfo->DeviceFamily == L"Windows.Xbox") + if (winrt::Windows::System::Profile::AnalyticsInfo::VersionInfo().DeviceFamily() == L"Windows.Xbox") { - const auto hdi = Windows::Graphics::Display::Core::HdmiDisplayInformation::GetForCurrentView(); + auto hdi = winrt::Windows::Graphics::Display::Core::HdmiDisplayInformation::GetForCurrentView(); if (hdi) { try { - const auto dm = hdi->GetCurrentDisplayMode(); - const float hdmi_width = (float)dm->ResolutionWidthInRawPixels; - const float hdmi_height = (float)dm->ResolutionHeightInRawPixels; + auto dm = hdi.GetCurrentDisplayMode(); + float hdmi_width = static_cast(dm.ResolutionWidthInRawPixels()); + float hdmi_height = static_cast(dm.ResolutionHeightInRawPixels()); // If we're running on Xbox, use the HDMI mode instead of the CoreWindow size. // In UWP, the CoreWindow is always 1920x1080, even when running at 4K. - m_logicalSize = Windows::Foundation::Size(hdmi_width, hdmi_height); - m_dpi = currentDisplayInformation->LogicalDpi * 1.5f; + m_logicalSize = winrt::Windows::Foundation::Size(hdmi_width, hdmi_height); + m_dpi = currentDisplayInformation.LogicalDpi() * 1.5f; } - catch (const Platform::Exception^) + catch (const winrt::hresult_error&) { - m_logicalSize = Windows::Foundation::Size(window->Bounds.Width, window->Bounds.Height); - m_dpi = currentDisplayInformation->LogicalDpi; + m_logicalSize = winrt::Windows::Foundation::Size(window.Bounds().Width, window.Bounds().Height); + m_dpi = currentDisplayInformation.LogicalDpi(); } } } else { - m_logicalSize = Windows::Foundation::Size(window->Bounds.Width, window->Bounds.Height); - m_dpi = currentDisplayInformation->LogicalDpi; + m_logicalSize = winrt::Windows::Foundation::Size(window.Bounds().Width, window.Bounds().Height); + m_dpi = currentDisplayInformation.LogicalDpi(); } - m_nativeOrientation = currentDisplayInformation->NativeOrientation; - m_currentOrientation = currentDisplayInformation->CurrentOrientation; + m_nativeOrientation = currentDisplayInformation.NativeOrientation(); + m_currentOrientation = currentDisplayInformation.CurrentOrientation(); m_d2dContext->SetDpi(m_dpi, m_dpi); } // This method is called in the event handler for the SizeChanged event. -void DX::DeviceResources::SetLogicalSize(Windows::Foundation::Size logicalSize) +void DX::DeviceResources::SetLogicalSize(winrt::Windows::Foundation::Size logicalSize) { if (m_logicalSize != logicalSize) { @@ -605,19 +588,19 @@ void DX::DeviceResources::ValidateDevice() // was created or if the device has been removed. // First, get the information for the default adapter from when the device was created. - ComPtr previousDefaultAdapter; - DX::ThrowIfFailed(m_dxgiFactory->EnumAdapters1(0, &previousDefaultAdapter)); + winrt::com_ptr previousDefaultAdapter; + DX::ThrowIfFailed(m_dxgiFactory->EnumAdapters1(0, previousDefaultAdapter.put())); DXGI_ADAPTER_DESC1 previousDesc; DX::ThrowIfFailed(previousDefaultAdapter->GetDesc1(&previousDesc)); // Next, get the information for the current default adapter. - ComPtr currentFactory; - DX::ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(¤tFactory))); + winrt::com_ptr currentFactory; + DX::ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(currentFactory.put()))); - ComPtr currentDefaultAdapter; - DX::ThrowIfFailed(currentFactory->EnumAdapters1(0, ¤tDefaultAdapter)); + winrt::com_ptr currentDefaultAdapter; + DX::ThrowIfFailed(currentFactory->EnumAdapters1(0, currentDefaultAdapter.put())); DXGI_ADAPTER_DESC1 currentDesc; DX::ThrowIfFailed(currentDefaultAdapter->GetDesc1(¤tDesc)); @@ -667,10 +650,7 @@ void DX::DeviceResources::RegisterDeviceNotify(DX::IDeviceNotify* deviceNotify) // is entering an idle state and that temporary buffers can be reclaimed for use by other apps. void DX::DeviceResources::Trim() { - ComPtr dxgiDevice; - m_d3dDevice.As(&dxgiDevice); - - dxgiDevice->Trim(); + m_dxgiDevice->Trim(); } // Present the contents of the swap chain to the screen. @@ -685,7 +665,7 @@ void DX::DeviceResources::Present() // Discard the contents of the render target. // This is a valid operation only when the existing contents will be entirely // overwritten. If dirty or scroll rects are used, this call should be removed. - m_d3dContext->DiscardView1(m_d3dRenderTargetView.Get(), nullptr, 0); + m_d3dContext->DiscardView1(m_d3dRenderTargetView.get(), nullptr, 0); // If the device was removed either by a disconnection or a driver upgrade, we // must recreate all device resources. @@ -752,4 +732,4 @@ DXGI_MODE_ROTATION DX::DeviceResources::ComputeDisplayRotation() break; } return rotation; -} +} \ No newline at end of file diff --git a/UWP/Common/DeviceResources.h b/UWP/Common/DeviceResources.h index 8d2723cf10..f85cb37280 100644 --- a/UWP/Common/DeviceResources.h +++ b/UWP/Common/DeviceResources.h @@ -2,6 +2,9 @@ #include #include +#include +#include +#include namespace DX { @@ -18,9 +21,9 @@ namespace DX public: DeviceResources(); void CreateWindowSizeDependentResources(); - void SetWindow(Windows::UI::Core::CoreWindow^ window); - void SetLogicalSize(Windows::Foundation::Size logicalSize); - void SetCurrentOrientation(Windows::Graphics::Display::DisplayOrientations currentOrientation); + void SetWindow(); + void SetLogicalSize(winrt::Windows::Foundation::Size logicalSize); + void SetCurrentOrientation(winrt::Windows::Graphics::Display::DisplayOrientations currentOrientation); void SetDpi(float dpi); void ValidateDevice(); void HandleDeviceLost(); @@ -29,29 +32,29 @@ namespace DX void Present(); // The size of the render target, in pixels. - Windows::Foundation::Size GetOutputSize() const { return m_outputSize; } + winrt::Windows::Foundation::Size GetOutputSize() const { return m_outputSize; } // The size of the render target, in dips. - Windows::Foundation::Size GetLogicalSize() const { return m_logicalSize; } + winrt::Windows::Foundation::Size GetLogicalSize() const { return m_logicalSize; } float GetDpi() const { return m_effectiveDpi; } float GetActualDpi() const { return m_dpi; } // D3D Accessors. - ID3D11Device3* GetD3DDevice() const { return m_d3dDevice.Get(); } - ID3D11DeviceContext3* GetD3DDeviceContext() const { return m_d3dContext.Get(); } - IDXGISwapChain3* GetSwapChain() const { return m_swapChain.Get(); } + ID3D11Device3* GetD3DDevice() const { return m_d3dDevice.get(); } + ID3D11DeviceContext3* GetD3DDeviceContext() const { return m_d3dContext.get(); } + IDXGISwapChain3* GetSwapChain() const { return m_swapChain.get(); } D3D_FEATURE_LEVEL GetDeviceFeatureLevel() const { return m_d3dFeatureLevel; } - ID3D11RenderTargetView1* GetBackBufferRenderTargetView() const { return m_d3dRenderTargetView.Get(); } + ID3D11RenderTargetView1* GetBackBufferRenderTargetView() const { return m_d3dRenderTargetView.get(); } D3D11_VIEWPORT GetScreenViewport() const { return m_screenViewport; } DirectX::XMFLOAT4X4 GetOrientationTransform3D() const { return m_orientationTransform3D; } // D2D Accessors. - ID2D1Factory3* GetD2DFactory() const { return m_d2dFactory.Get(); } - ID2D1Device2* GetD2DDevice() const { return m_d2dDevice.Get(); } - ID2D1DeviceContext2* GetD2DDeviceContext() const { return m_d2dContext.Get(); } - ID2D1Bitmap1* GetD2DTargetBitmap() const { return m_d2dTargetBitmap.Get(); } - IDWriteFactory3* GetDWriteFactory() const { return m_dwriteFactory.Get(); } - IWICImagingFactory2* GetWicImagingFactory() const { return m_wicFactory.Get(); } + ID2D1Factory3* GetD2DFactory() const { return m_d2dFactory.get(); } + ID2D1Device2* GetD2DDevice() const { return m_d2dDevice.get(); } + ID2D1DeviceContext2* GetD2DDeviceContext() const { return m_d2dContext.get(); } + ID2D1Bitmap1* GetD2DTargetBitmap() const { return m_d2dTargetBitmap.get(); } + IDWriteFactory3* GetDWriteFactory() const { return m_dwriteFactory.get(); } + IWICImagingFactory2* GetWicImagingFactory() const { return m_wicFactory.get(); } D2D1::Matrix3x2F GetOrientationTransform2D() const { return m_orientationTransform2D; } DXGI_MODE_ROTATION ComputeDisplayRotation(); @@ -62,40 +65,40 @@ namespace DX void CreateDeviceIndependentResources(); void CreateDeviceResources(IDXGIAdapter* vAdapter = nullptr); void UpdateRenderTargetSize(); - bool CreateAdaptersList(Microsoft::WRL::ComPtr device); + bool CreateAdaptersList(winrt::com_ptr device); // Direct3D objects. - Microsoft::WRL::ComPtr m_d3dDevice; - Microsoft::WRL::ComPtr m_d3dContext; - Microsoft::WRL::ComPtr m_swapChain; - Microsoft::WRL::ComPtr m_dxgiDevice; - Microsoft::WRL::ComPtr m_dxgiFactory; - Microsoft::WRL::ComPtr m_dxgiAdapter; + winrt::com_ptr m_d3dDevice; + winrt::com_ptr m_d3dContext; + winrt::com_ptr m_swapChain; + winrt::com_ptr m_dxgiDevice; + winrt::com_ptr m_dxgiFactory; + winrt::com_ptr m_dxgiAdapter; // Direct3D adapters std::vector m_vAdapters; // Direct3D rendering objects. Required for 3D. - Microsoft::WRL::ComPtr m_d3dRenderTargetView; - D3D11_VIEWPORT m_screenViewport; + winrt::com_ptr m_d3dRenderTargetView; + D3D11_VIEWPORT m_screenViewport; // Direct2D drawing components. - Microsoft::WRL::ComPtr m_d2dFactory; - Microsoft::WRL::ComPtr m_d2dDevice; - Microsoft::WRL::ComPtr m_d2dContext; - Microsoft::WRL::ComPtr m_d2dTargetBitmap; + winrt::com_ptr m_d2dFactory; + winrt::com_ptr m_d2dDevice; + winrt::com_ptr m_d2dContext; + winrt::com_ptr m_d2dTargetBitmap; // DirectWrite drawing components. - Microsoft::WRL::ComPtr m_dwriteFactory; - Microsoft::WRL::ComPtr m_wicFactory; + winrt::com_ptr m_dwriteFactory; + winrt::com_ptr m_wicFactory; // Cached device properties. - D3D_FEATURE_LEVEL m_d3dFeatureLevel; - Windows::Foundation::Size m_d3dRenderTargetSize; - Windows::Foundation::Size m_outputSize; - Windows::Foundation::Size m_logicalSize; - Windows::Graphics::Display::DisplayOrientations m_nativeOrientation; - Windows::Graphics::Display::DisplayOrientations m_currentOrientation; + D3D_FEATURE_LEVEL m_d3dFeatureLevel; + winrt::Windows::Foundation::Size m_d3dRenderTargetSize; + winrt::Windows::Foundation::Size m_outputSize; + winrt::Windows::Foundation::Size m_logicalSize; + winrt::Windows::Graphics::Display::DisplayOrientations m_nativeOrientation; + winrt::Windows::Graphics::Display::DisplayOrientations m_currentOrientation; float m_dpi; // This is the DPI that will be reported back to the app. It takes into account whether the app supports high resolution screens or not. @@ -108,4 +111,4 @@ namespace DX // The IDeviceNotify can be held directly as it owns the DeviceResources. IDeviceNotify* m_deviceNotify; }; -} +} \ No newline at end of file diff --git a/UWP/Common/DirectXHelper.h b/UWP/Common/DirectXHelper.h index 1137361a9a..9a46bbbd3a 100644 --- a/UWP/Common/DirectXHelper.h +++ b/UWP/Common/DirectXHelper.h @@ -9,26 +9,25 @@ namespace DX if (FAILED(hr)) { // Set a breakpoint on this line to catch Win32 API errors. - throw Platform::Exception::CreateException(hr); + winrt::throw_hresult(hr); } } // Function that reads from a binary file asynchronously. - inline Concurrency::task> ReadDataAsync(const std::wstring& filename) + inline Concurrency::task> ReadDataAsync(const std::wstring& filename) { - using namespace Windows::Storage; using namespace Concurrency; - auto folder = Windows::ApplicationModel::Package::Current->InstalledLocation; + auto folder = winrt::Windows::ApplicationModel::Package::Current().InstalledLocation(); - return create_task(folder->GetFileAsync(Platform::StringReference(filename.c_str()))).then([] (StorageFile^ file) - { - return FileIO::ReadBufferAsync(file); - }).then([] (Streams::IBuffer^ fileBuffer) -> std::vector - { - std::vector returnBuffer; - returnBuffer.resize(fileBuffer->Length); - Streams::DataReader::FromBuffer(fileBuffer)->ReadBytes(Platform::ArrayReference(returnBuffer.data(), fileBuffer->Length)); + return create_task([folder, filename]() -> std::vector { + auto file = folder.GetFileAsync(winrt::hstring(filename)).get(); + auto buffer = winrt::Windows::Storage::FileIO::ReadBufferAsync(file).get(); + + + std::vector returnBuffer(buffer.Length()); + auto reader = winrt::Windows::Storage::Streams::DataReader::FromBuffer(buffer); + reader.ReadBytes(returnBuffer); return returnBuffer; }); } diff --git a/UWP/NKCodeFromWindowsSystem.cpp b/UWP/NKCodeFromWindowsSystem.cpp index fe109d62d1..4b83805882 100644 --- a/UWP/NKCodeFromWindowsSystem.cpp +++ b/UWP/NKCodeFromWindowsSystem.cpp @@ -1,9 +1,9 @@ #include "pch.h" #include "NKCodeFromWindowsSystem.h" -using namespace Windows::System; +using namespace winrt::Windows::System; -std::map virtualKeyCodeToNKCode{ +std::map virtualKeyCodeToNKCode{ { VirtualKey::A, NKCODE_A }, { VirtualKey::B, NKCODE_B }, { VirtualKey::C, NKCODE_C }, diff --git a/UWP/NKCodeFromWindowsSystem.h b/UWP/NKCodeFromWindowsSystem.h index 230b5a986f..b05633ba05 100644 --- a/UWP/NKCodeFromWindowsSystem.h +++ b/UWP/NKCodeFromWindowsSystem.h @@ -4,4 +4,4 @@ #include "Common/Input/KeyCodes.h" -extern std::map virtualKeyCodeToNKCode; +extern std::map virtualKeyCodeToNKCode; diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index edcf1433ad..a565e8494a 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "Common/File/FileUtil.h" #include "Common/Net/HTTPClient.h" @@ -44,20 +45,20 @@ #include "Windows/InputDevice.h" using namespace UWP; -using namespace Windows::Foundation; -using namespace Windows::Storage; -using namespace Windows::Storage::Streams; -using namespace Windows::System::Threading; -using namespace Windows::ApplicationModel::DataTransfer; -using namespace Windows::Devices::Enumeration; -using namespace Concurrency; +using namespace winrt; +using namespace winrt::Windows::Foundation; +using namespace winrt::Windows::Storage; +using namespace winrt::Windows::Storage::Streams; +using namespace winrt::Windows::System::Threading; +using namespace winrt::Windows::ApplicationModel::DataTransfer; +using namespace winrt::Windows::Devices::Enumeration; // TODO: Use Microsoft::WRL::ComPtr<> for D3D11 objects? // TODO: See https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/WindowsAudioSession for WASAPI with UWP // TODO: Low latency input: https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/LowLatencyInput/cpp // Loads and initializes application assets when the application is loaded. -PPSSPP_UWPMain::PPSSPP_UWPMain(App ^app, const std::shared_ptr& deviceResources) : +PPSSPP_UWPMain::PPSSPP_UWPMain(App *app, const std::shared_ptr& deviceResources) : app_(app), m_deviceResources(deviceResources) { @@ -131,7 +132,8 @@ void PPSSPP_UWPMain::UpdateScreenState() { case DXGI_MODE_ROTATION_ROTATE270: g_display.rotation = DisplayRotation::ROTATE_270; break; } // Not super elegant but hey. - memcpy(&g_display.rot_matrix, &m_deviceResources->GetOrientationTransform3D(), sizeof(float) * 16); + auto orientMatrix = m_deviceResources->GetOrientationTransform3D(); + memcpy(&g_display.rot_matrix, &orientMatrix, sizeof(float) * 16); // Reset the viewport to target the whole screen. auto viewport = m_deviceResources->GetScreenViewport(); @@ -194,7 +196,7 @@ void PPSSPP_UWPMain::OnDeviceRestored() { ctx_->GetDrawContext()->HandleEvent(Draw::Event::GOT_DEVICE, 0, 0, nullptr); } -void PPSSPP_UWPMain::OnKeyDown(int scanCode, Windows::System::VirtualKey virtualKey, int repeatCount) { +void PPSSPP_UWPMain::OnKeyDown(int scanCode, winrt::Windows::System::VirtualKey virtualKey, int repeatCount) { // TODO: Look like (Ctrl, Alt, Shift) don't trigger this event bool isDPad = (int)virtualKey >= 195 && (int)virtualKey <= 218; // DPad buttons range DPadInputState(isDPad); @@ -211,7 +213,7 @@ void PPSSPP_UWPMain::OnKeyDown(int scanCode, Windows::System::VirtualKey virtual } } -void PPSSPP_UWPMain::OnKeyUp(int scanCode, Windows::System::VirtualKey virtualKey) { +void PPSSPP_UWPMain::OnKeyUp(int scanCode, winrt::Windows::System::VirtualKey virtualKey) { auto iter = virtualKeyCodeToNKCode.find(virtualKey); if (iter != virtualKeyCodeToNKCode.end()) { KeyInput key{}; @@ -325,9 +327,9 @@ std::string System_GetProperty(SystemProperty prop) { return GetLangRegion(); case SYSPROP_CLIPBOARD_TEXT: /* TODO: Need to either change this API or do this on a thread in an ugly fashion. - DataPackageView ^view = Clipboard::GetContent(); + auto view = winrt::Windows::ApplicationModel::DataTransfer::Clipboard::GetContent(); if (view) { - string text = await view->GetTextAsync(); + winrt::hstring text = co_await view.GetTextAsync(); } */ return ""; @@ -381,16 +383,16 @@ int64_t System_GetPropertyInt(SystemProperty prop) { } case SYSPROP_DISPLAY_XRES: { - CoreWindow^ corewindow = CoreWindow::GetForCurrentThread(); + winrt::Windows::UI::Core::CoreWindow corewindow = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread(); if (corewindow) { - return (int)corewindow->Bounds.Width; + return (int)corewindow.Bounds().Width; } } case SYSPROP_DISPLAY_YRES: { - CoreWindow^ corewindow = CoreWindow::GetForCurrentThread(); + winrt::Windows::UI::Core::CoreWindow corewindow = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread(); if (corewindow) { - return (int)corewindow->Bounds.Height; + return (int)corewindow.Bounds().Height; } } default: @@ -463,7 +465,7 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string case SystemRequestType::EXIT_APP: { bool state = false; - ExecuteTask(state, Windows::UI::ViewManagement::ApplicationView::GetForCurrentView()->TryConsolidateAsync()); + ExecuteTask(state, winrt::Windows::UI::ViewManagement::ApplicationView::GetForCurrentView().TryConsolidateAsync()); if (!state) { // Notify the user? } @@ -471,9 +473,9 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string } case SystemRequestType::RESTART_APP: { - Windows::ApplicationModel::Core::AppRestartFailureReason error; - ExecuteTask(error, Windows::ApplicationModel::Core::CoreApplication::RequestRestartAsync(nullptr)); - if (error != Windows::ApplicationModel::Core::AppRestartFailureReason::RestartPending) { + winrt::Windows::ApplicationModel::Core::AppRestartFailureReason error; + ExecuteTask(error, winrt::Windows::ApplicationModel::Core::CoreApplication::RequestRestartAsync(L"")); + if (error != winrt::Windows::ApplicationModel::Core::AppRestartFailureReason::RestartPending) { // Shutdown System_MakeRequest(SystemRequestType::EXIT_APP, requestId, param1, param2, param3, param4); } @@ -484,14 +486,13 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string std::vector supportedExtensions = { ".jpg", ".png" }; //Call file picker - ChooseFile(supportedExtensions).then([requestId](std::string filePath) { - if (filePath.size() > 1) { - g_requestManager.PostSystemSuccess(requestId, filePath.c_str()); - } - else { - g_requestManager.PostSystemFailure(requestId); - } - }); + std::string filePath = ChooseFile(supportedExtensions); + if (filePath.size() > 1) { + g_requestManager.PostSystemSuccess(requestId, filePath.c_str()); + } + else { + g_requestManager.PostSystemFailure(requestId); + } return true; } case SystemRequestType::BROWSE_FOR_FILE: @@ -531,27 +532,25 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string } //Call file picker - ChooseFile(supportedExtensions).then([requestId](std::string filePath) { - if (filePath.size() > 1) { - g_requestManager.PostSystemSuccess(requestId, filePath.c_str()); - } - else { - g_requestManager.PostSystemFailure(requestId); - } - }); + std::string filePath = ChooseFile(supportedExtensions); + if (filePath.size() > 1) { + g_requestManager.PostSystemSuccess(requestId, filePath.c_str()); + } + else { + g_requestManager.PostSystemFailure(requestId); + } return true; } case SystemRequestType::BROWSE_FOR_FOLDER: { - ChooseFolder().then([requestId](std::string folderPath) { - if (folderPath.size() > 1) { - g_requestManager.PostSystemSuccess(requestId, folderPath.c_str()); - } - else { - g_requestManager.PostSystemFailure(requestId); - } - }); + std::string folderPath = ChooseFolder(); + if (folderPath.size() > 1) { + g_requestManager.PostSystemSuccess(requestId, folderPath.c_str()); + } + else { + g_requestManager.PostSystemFailure(requestId); + } return true; } case SystemRequestType::NOTIFY_UI_EVENT: @@ -576,25 +575,25 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string } case SystemRequestType::COPY_TO_CLIPBOARD: { - auto dataPackage = ref new DataPackage(); - dataPackage->RequestedOperation = DataPackageOperation::Copy; - dataPackage->SetText(ToPlatformString(param1)); - Clipboard::SetContent(dataPackage); + winrt::Windows::ApplicationModel::DataTransfer::DataPackage dataPackage; + dataPackage.RequestedOperation(winrt::Windows::ApplicationModel::DataTransfer::DataPackageOperation::Copy); + dataPackage.SetText(ToHString(param1)); + winrt::Windows::ApplicationModel::DataTransfer::Clipboard::SetContent(dataPackage); return true; } case SystemRequestType::TOGGLE_FULLSCREEN_STATE: { - auto view = Windows::UI::ViewManagement::ApplicationView::GetForCurrentView(); - bool flag = !view->IsFullScreenMode; + auto view = winrt::Windows::UI::ViewManagement::ApplicationView::GetForCurrentView(); + bool flag = !view.IsFullScreenMode(); if (param1 == "0") { flag = false; } else if (param1 == "1"){ flag = true; } if (flag) { - view->TryEnterFullScreenMode(); + view.TryEnterFullScreenMode(); } else { - view->ExitFullScreenMode(); + view.ExitFullScreenMode(); } return true; } @@ -607,9 +606,8 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string } void System_LaunchUrl(LaunchUrlType urlType, std::string_view url) { - auto uri = ref new Windows::Foundation::Uri(ToPlatformString(url)); - - create_task(Windows::System::Launcher::LaunchUriAsync(uri)).then([](bool b) {}); + auto uri = winrt::Windows::Foundation::Uri(ToHString(url)); + winrt::Windows::System::Launcher::LaunchUriAsync(uri); } void System_Vibrate(int length_ms) { @@ -621,15 +619,14 @@ void System_Vibrate(int length_ms) { else return; - auto timeSpan = Windows::Foundation::TimeSpan(); - timeSpan.Duration = length_ms * 10000; + winrt::Windows::Foundation::TimeSpan timeSpan; + timeSpan.count = length_ms * 10000; // TODO: Can't use this? - // Windows::Phone::Devices::Notification::VibrationDevice::GetDefault()->Vibrate(timeSpan); + // winrt::Windows::Phone::Devices::Notification::VibrationDevice::GetDefault().Vibrate(timeSpan); #endif } void System_AskForPermission(SystemPermission permission) { - // Do nothing } PermissionStatus System_GetPermissionStatus(SystemPermission permission) { @@ -637,55 +634,45 @@ PermissionStatus System_GetPermissionStatus(SystemPermission permission) { } std::string GetCPUBrandString() { - Platform::String^ cpu_id = nullptr; - Platform::String^ cpu_name = nullptr; + winrt::hstring cpu_id; + winrt::hstring cpu_name; // GUID_DEVICE_PROCESSOR: {97FADB10-4E33-40AE-359C-8BEF029DBDD0} - Platform::String^ if_filter = L"System.Devices.InterfaceClassGuid:=\"{97FADB10-4E33-40AE-359C-8BEF029DBDD0}\""; + winrt::hstring if_filter = L"System.Devices.InterfaceClassGuid:=\"{97FADB10-4E33-40AE-359C-8BEF029DBDD0}\""; // Enumerate all CPU DeviceInterfaces, and get DeviceInstanceID of the first one. - auto if_task = create_task( - DeviceInformation::FindAllAsync(if_filter)).then([&](DeviceInformationCollection ^ collection) { - if (collection->Size > 0) { - auto cpu = collection->GetAt(0); - auto id = cpu->Properties->Lookup(L"System.Devices.DeviceInstanceID"); - cpu_id = dynamic_cast(id); - } - }); - try { - if_task.wait(); + auto collection = winrt::Windows::Devices::Enumeration::DeviceInformation::FindAllAsync(if_filter).get(); + if (collection.Size() > 0) { + auto cpu = collection.GetAt(0); + auto id = cpu.Properties().Lookup(L"System.Devices.DeviceInstanceID"); + cpu_id = winrt::unbox_value(id); + } } - catch (const std::exception & e) { - const char* what = e.what(); - INFO_LOG(Log::System, "%s", what); + catch (const winrt::hresult_error& e) { + INFO_LOG(Log::System, "%s", winrt::to_string(e.message()).c_str()); } - if (cpu_id != nullptr) { + if (!cpu_id.empty()) { // Get the Device with the same ID as the DeviceInterface // Then get the name (description) of that Device // We have to do this because the DeviceInterface we get doesn't have a proper description. - Platform::String^ dev_filter = L"System.Devices.DeviceInstanceID:=\"" + cpu_id + L"\""; - - auto dev_task = create_task( - DeviceInformation::FindAllAsync(dev_filter, {}, DeviceInformationKind::Device)).then( - [&](DeviceInformationCollection ^ collection) { - if (collection->Size > 0) { - cpu_name = collection->GetAt(0)->Name; - } - }); + winrt::hstring dev_filter = L"System.Devices.DeviceInstanceID:=\"" + cpu_id + L"\""; try { - dev_task.wait(); + auto collection = winrt::Windows::Devices::Enumeration::DeviceInformation::FindAllAsync(dev_filter, {}, + winrt::Windows::Devices::Enumeration::DeviceInformationKind::Device).get(); + if (collection.Size() > 0) { + cpu_name = collection.GetAt(0).Name(); + } } - catch (const std::exception & e) { - const char* what = e.what(); - INFO_LOG(Log::System, "%s", what); + catch (const winrt::hresult_error& e) { + INFO_LOG(Log::System, "%s", winrt::to_string(e.message()).c_str()); } } - if (cpu_name != nullptr) { - return FromPlatformString(cpu_name); + if (!cpu_name.empty()) { + return FromHString(cpu_name); } else { return "Unknown"; } diff --git a/UWP/PPSSPP_UWPMain.h b/UWP/PPSSPP_UWPMain.h index 3a6d832b36..a7c176474e 100644 --- a/UWP/PPSSPP_UWPMain.h +++ b/UWP/PPSSPP_UWPMain.h @@ -12,7 +12,7 @@ // Renders Direct2D and 3D content on the screen. namespace UWP { -ref class App; +struct App; enum class HardwareButton; class UWPGraphicsContext : public GraphicsContext { @@ -32,7 +32,7 @@ private: class PPSSPP_UWPMain : public DX::IDeviceNotify { public: - PPSSPP_UWPMain(App ^app, const std::shared_ptr& deviceResources); + PPSSPP_UWPMain(App *app, const std::shared_ptr& deviceResources); ~PPSSPP_UWPMain(); void CreateWindowSizeDependentResources(); void UpdateScreenState(); @@ -44,8 +44,8 @@ public: // Various forwards from App, in simplified format. // Not sure whether this abstraction is worth it. - void OnKeyDown(int scanCode, Windows::System::VirtualKey virtualKey, int repeatCount); - void OnKeyUp(int scanCode, Windows::System::VirtualKey virtualKey); + void OnKeyDown(int scanCode, winrt::Windows::System::VirtualKey virtualKey, int repeatCount); + void OnKeyUp(int scanCode, winrt::Windows::System::VirtualKey virtualKey); void OnCharacterReceived(int scanCode,unsigned int keyCode); void OnTouchEvent(TouchInputFlags flags, int touchId, float x, float y, double timestamp); @@ -61,7 +61,7 @@ public: void Close(); private: - App ^app_; + App *app_; // Cached pointer to device resources. std::shared_ptr m_deviceResources; diff --git a/UWP/Package.appxmanifest b/UWP/Package.appxmanifest index e18687e75f..bf49532ba8 100644 --- a/UWP/Package.appxmanifest +++ b/UWP/Package.appxmanifest @@ -1,4 +1,4 @@ - + diff --git a/UWP/UWP.vcxproj b/UWP/UWP.vcxproj index eb7bc46259..c7a2fb16e8 100644 --- a/UWP/UWP.vcxproj +++ b/UWP/UWP.vcxproj @@ -1,5 +1,6 @@ + Debug @@ -78,6 +79,7 @@ xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib; %(AdditionalDependencies) ../ffmpeg/Windows10/ARM64/lib;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm + false pch.h @@ -87,7 +89,8 @@ 4453;28204 _DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) pch.h - stdcpp17 + stdcpp20 + /bigobj /await %(AdditionalOptions) @@ -101,6 +104,7 @@ xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib; %(AdditionalDependencies) ../ffmpeg/Windows10/ARM64/lib;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm + false pch.h @@ -110,7 +114,8 @@ 4453;28204 NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) pch.h - stdcpp17 + stdcpp20 + /bigobj /await %(AdditionalOptions) @@ -124,6 +129,7 @@ xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib; %(AdditionalDependencies) ../ffmpeg/Windows10/ARM64/lib;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm + false pch.h @@ -133,7 +139,8 @@ 4453;28204 GOLD;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) pch.h - stdcpp17 + stdcpp20 + /bigobj /await %(AdditionalOptions) @@ -148,6 +155,7 @@ xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib; %(AdditionalDependencies) ../ffmpeg/Windows10/x64/lib;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\amd64; $(VCInstallDir)\lib\amd64 + false pch.h @@ -157,7 +165,8 @@ 4453;28204 _DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) pch.h - stdcpp17 + stdcpp20 + /bigobj /await %(AdditionalOptions) @@ -171,6 +180,7 @@ xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib; %(AdditionalDependencies) ../ffmpeg/Windows10/x64/lib;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\amd64; $(VCInstallDir)\lib\amd64 + false pch.h @@ -180,7 +190,8 @@ 4453;28204 NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) pch.h - stdcpp17 + stdcpp20 + /bigobj /await %(AdditionalOptions) @@ -194,6 +205,7 @@ xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib; %(AdditionalDependencies) ../ffmpeg/Windows10/x64/lib;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\amd64; $(VCInstallDir)\lib\amd64 + false pch.h @@ -203,7 +215,8 @@ 4453;28204 GOLD;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) pch.h - stdcpp17 + stdcpp20 + /bigobj /await %(AdditionalOptions) @@ -403,6 +416,7 @@ true Content\shaders\%(Filename)%(Extension) + @@ -472,5 +486,13 @@ + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + diff --git a/UWP/UWPHelpers/InputHelpers.cpp b/UWP/UWPHelpers/InputHelpers.cpp index 441b731094..c512a4d688 100644 --- a/UWP/UWPHelpers/InputHelpers.cpp +++ b/UWP/UWPHelpers/InputHelpers.cpp @@ -15,7 +15,9 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "pch.h" #include +#include #include "InputHelpers.h" #include "UWPUtil.h" @@ -26,14 +28,14 @@ #include #include -using namespace Windows::System; -using namespace Windows::Foundation; -using namespace Windows::UI::Core; -using namespace Windows::UI::ViewManagement; -using namespace Windows::ApplicationModel::Core; -using namespace Windows::Data::Xml::Dom; -using namespace Windows::UI::Notifications; -using namespace Windows::UI::ViewManagement; +using namespace winrt; +using namespace winrt::Windows::System; +using namespace winrt::Windows::Foundation; +using namespace winrt::Windows::UI::Core; +using namespace winrt::Windows::UI::ViewManagement; +using namespace winrt::Windows::ApplicationModel::Core; +using namespace winrt::Windows::Data::Xml::Dom; +using namespace winrt::Windows::UI::Notifications; #pragma region Extenstions template @@ -44,14 +46,14 @@ bool findInList(std::list& inputList, T& str) { #pragma region Input Devices bool isKeyboardAvailable() { - Windows::Devices::Input::KeyboardCapabilities^ keyboardCapabilities = ref new Windows::Devices::Input::KeyboardCapabilities(); - bool hasKeyboard = keyboardCapabilities->KeyboardPresent != 0; + winrt::Windows::Devices::Input::KeyboardCapabilities keyboardCapabilities; + bool hasKeyboard = keyboardCapabilities.KeyboardPresent() != 0; return hasKeyboard; } bool isTouchAvailable() { - Windows::Devices::Input::TouchCapabilities^ touchCapabilities = ref new Windows::Devices::Input::TouchCapabilities(); - bool hasTouch = touchCapabilities->TouchPresent != 0; + winrt::Windows::Devices::Input::TouchCapabilities touchCapabilities; + bool hasTouch = touchCapabilities.TouchPresent() != 0; return hasTouch; } #pragma endregion @@ -61,28 +63,35 @@ bool isTouchAvailable() { bool dPadInputActive = false; bool textEditActive = false; bool inputPaneVisible = false; -Platform::Agile inputPane = nullptr; +winrt::agile_ref inputPane = nullptr; -void OnShowing(InputPane^ pane, InputPaneVisibilityEventArgs^ args) { +void OnShowing(const InputPane& pane, const InputPaneVisibilityEventArgs& args) { inputPaneVisible = true; } -void OnHiding(InputPane^ pane, InputPaneVisibilityEventArgs^ args) { +void OnHiding(const InputPane& pane, const InputPaneVisibilityEventArgs& args) { inputPaneVisible = false; } void PrepareInputPane() { - inputPane = InputPane::GetForCurrentView(); - inputPane->Showing += ref new Windows::Foundation::TypedEventHandler(&OnShowing); - inputPane->Hiding += ref new Windows::Foundation::TypedEventHandler(&OnHiding); + auto pane = InputPane::GetForCurrentView(); + pane.Showing(OnShowing); + pane.Hiding(OnHiding); + inputPane = pane; } // Show input pane (OSK) bool ShowInputPane() { - return !isInputPaneVisible() ? inputPane->TryShow() : true; + if (inputPane) { + return !isInputPaneVisible() ? inputPane.get().TryShow() : true; + } + return false; } // Hide input pane (OSK) bool HideInputPane() { - return isInputPaneVisible() ? inputPane->TryHide() : true; + if (inputPane) { + return isInputPaneVisible() ? inputPane.get().TryHide() : true; + } + return false; } // Check if input pane (OSK) visible @@ -107,9 +116,9 @@ bool isDPadActive() { void ActivateTextEditInput(bool byFocus) { // Must be performed from UI thread - Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync( + CoreApplication::MainView().CoreWindow().Dispatcher().RunAsync( CoreDispatcherPriority::Normal, - ref new Windows::UI::Core::DispatchedHandler([=]() + [byFocus]() { if (byFocus) { // Why we should delay? (Mostly happen on XBox) @@ -130,14 +139,14 @@ void ActivateTextEditInput(bool byFocus) { } DEBUG_LOG(Log::Common, "Text edit active"); textEditActive = true; - })); + }); } void DeactivateTextEditInput(bool byFocus) { // Must be performed from UI thread - Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync( + CoreApplication::MainView().CoreWindow().Dispatcher().RunAsync( CoreDispatcherPriority::Normal, - ref new Windows::UI::Core::DispatchedHandler([=]() + [byFocus]() { if (isInputPaneVisible()) { if (HideInputPane()) { @@ -151,7 +160,7 @@ void DeactivateTextEditInput(bool byFocus) { DEBUG_LOG(Log::Common, "Text edit inactive"); textEditActive = false; } - })); + }); } bool IgnoreInput(int keyCode) { @@ -200,17 +209,17 @@ bool IgnoreInput(int keyCode) { #pragma region Keys Status bool IsCapsLockOn() { // TODO: Perform this on UI thread, delayed as currently `KeyDown` don't detect those anyway - auto capsLockState = CoreApplication::MainView->CoreWindow->GetKeyState(VirtualKey::CapitalLock); + auto capsLockState = CoreApplication::MainView().CoreWindow().GetKeyState(VirtualKey::CapitalLock); return (capsLockState == CoreVirtualKeyStates::Locked); } bool IsShiftOnHold() { // TODO: Perform this on UI thread, delayed as currently `KeyDown` don't detect those anyway - auto shiftState = CoreApplication::MainView->CoreWindow->GetKeyState(VirtualKey::Shift); + auto shiftState = CoreApplication::MainView().CoreWindow().GetKeyState(VirtualKey::Shift); return (shiftState == CoreVirtualKeyStates::Down); } bool IsCtrlOnHold() { // TODO: Perform this on UI thread, delayed as currently `KeyDown` don't detect those anyway - auto ctrlState = CoreApplication::MainView->CoreWindow->GetKeyState(VirtualKey::Control); + auto ctrlState = CoreApplication::MainView().CoreWindow().GetKeyState(VirtualKey::Control); return (ctrlState == CoreVirtualKeyStates::Down); } #pragma endregion @@ -231,18 +240,18 @@ std::string GetLangRegion() { } bool IsXBox() { - auto deviceInfo = Windows::System::Profile::AnalyticsInfo::VersionInfo; - return deviceInfo->DeviceFamily == "Windows.Xbox"; + auto deviceInfo = winrt::Windows::System::Profile::AnalyticsInfo::VersionInfo(); + return deviceInfo.DeviceFamily() == L"Windows.Xbox"; } bool IsMobile() { - auto deviceInfo = Windows::System::Profile::AnalyticsInfo::VersionInfo; - return deviceInfo->DeviceFamily == "Windows.Mobile"; + auto deviceInfo = winrt::Windows::System::Profile::AnalyticsInfo::VersionInfo(); + return deviceInfo.DeviceFamily() == L"Windows.Mobile"; } void GetVersionInfo(uint32_t& major, uint32_t& minor, uint32_t& build, uint32_t& revision) { - Platform::String^ deviceFamilyVersion = Windows::System::Profile::AnalyticsInfo::VersionInfo->DeviceFamilyVersion; - uint64_t version = std::stoull(deviceFamilyVersion->Data()); + winrt::hstring deviceFamilyVersion = winrt::Windows::System::Profile::AnalyticsInfo::VersionInfo().DeviceFamilyVersion(); + uint64_t version = std::stoull(std::wstring(deviceFamilyVersion)); major = static_cast((version & 0xFFFF000000000000L) >> 48); minor = static_cast((version & 0x0000FFFF00000000L) >> 32); diff --git a/UWP/UWPHelpers/LaunchItem.cpp b/UWP/UWPHelpers/LaunchItem.cpp index e46bb5e219..5402d103d8 100644 --- a/UWP/UWPHelpers/LaunchItem.cpp +++ b/UWP/UWPHelpers/LaunchItem.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include "LaunchItem.h" #include "StorageAccess.h" @@ -31,6 +32,11 @@ #include #include +using namespace winrt; +using namespace winrt::Windows::Storage; +using namespace winrt::Windows::Foundation; +using namespace winrt::Windows::ApplicationModel::Activation; + #pragma region LaunchItemClass class LaunchItem { public: @@ -38,31 +44,30 @@ public: } ~LaunchItem() { - delete storageFile; } - void Activate(IStorageFile^ file) { + void Activate(const IStorageFile& file) { storageFile = file; AddItemToFutureList(storageFile); launchPath = std::string(); launchOnExit = std::string(); } - void Activate(ProtocolActivatedEventArgs^ args) { + void Activate(const ProtocolActivatedEventArgs& args) { try { unsigned i; - Windows::Foundation::WwwFormUrlDecoder^ query = args->Uri->QueryParsed; + auto query = args.Uri().QueryParsed(); - for (i = 0; i < query->Size; i++) + for (i = 0; i < query.Size(); i++) { - IWwwFormUrlDecoderEntry^ arg = query->GetAt(i); + auto arg = query.GetAt(i); - if (arg->Name == "cmd") + if (arg.Name() == L"cmd") { - auto command = FromPlatformString(arg->Value); + auto command = FromHString(arg.Value()); DEBUG_LOG(Log::FileSystem, "Launch command %s", command.c_str()); - std::regex rgx("\"(.+[^\\/]+)\""); + std::regex rgx("\"(.+[^\\\\/]+)\""); std::smatch match; if (std::regex_search(command, match, rgx)) { @@ -76,8 +81,8 @@ public: DEBUG_LOG(Log::FileSystem, "Launch target %s", launchPath.c_str()); } } - else if (arg->Name == "launchOnExit") { - launchOnExit = FromPlatformString(arg->Value); + else if (arg.Name() == L"launchOnExit") { + launchOnExit = FromHString(arg.Value()); DEBUG_LOG(Log::FileSystem, "On exit URI %s", launchOnExit.c_str()); } } @@ -90,13 +95,13 @@ public: void Start() { if (IsValid()) { - concurrency::create_task([&] { + std::thread([this] { SetState(true); std::string path = GetFilePath(); // Delay to be able to launch on startup too std::this_thread::sleep_for(std::chrono::milliseconds(100)); System_PostUIMessage(UIMessage::REQUEST_GAME_BOOT, path); - }); + }).detach(); } } @@ -114,7 +119,7 @@ public: std::string GetFilePath() { std::string path = launchPath; if (storageFile != nullptr) { - path = FromPlatformString(storageFile->Path); + path = FromHString(storageFile.Path()); } return path; } @@ -127,8 +132,8 @@ public: if (!launchOnExit.empty()) { if (callLaunchOnExit) { DEBUG_LOG(Log::FileSystem, "Calling back %s", launchOnExit.c_str()); - auto uri = ref new Windows::Foundation::Uri(ToPlatformString(launchOnExit)); - Windows::System::Launcher::LaunchUriAsync(uri); + auto uri = winrt::Windows::Foundation::Uri(ToHString(launchOnExit)); + winrt::Windows::System::Launcher::LaunchUriAsync(uri); } else { DEBUG_LOG(Log::FileSystem, "Ignoring callback %s, due to callLaunchOnExit is false", launchOnExit.c_str()); @@ -138,7 +143,7 @@ public: } private: - IStorageFile^ storageFile; + IStorageFile storageFile = nullptr; std::string launchPath; std::string launchOnExit; bool handled = false; @@ -146,17 +151,24 @@ private: #pragma endregion LaunchItem launchItemHandler; -void DetectLaunchItem(IActivatedEventArgs^ activateArgs, bool onlyActivate) { +void DetectLaunchItem(const IActivatedEventArgs& activateArgs, bool onlyActivate) { if (activateArgs != nullptr) { if (!launchItemHandler.IsHandled()) { - if (activateArgs->Kind == ActivationKind::File) { - FileActivatedEventArgs^ fileArgs = dynamic_cast(activateArgs); - launchItemHandler.Activate((StorageFile^)fileArgs->Files->GetAt(0)); + if (activateArgs.Kind() == ActivationKind::File) { + auto fileArgs = activateArgs.try_as(); + if (fileArgs) { + auto file = fileArgs.Files().GetAt(0).try_as(); + if (file) { + launchItemHandler.Activate(file); + } + } } - else if (activateArgs->Kind == ActivationKind::Protocol) + else if (activateArgs.Kind() == ActivationKind::Protocol) { - ProtocolActivatedEventArgs^ protocolArgs = dynamic_cast(activateArgs); - launchItemHandler.Activate(protocolArgs); + auto protocolArgs = activateArgs.try_as(); + if (protocolArgs) { + launchItemHandler.Activate(protocolArgs); + } } if (!onlyActivate) { launchItemHandler.Start(); @@ -165,7 +177,7 @@ void DetectLaunchItem(IActivatedEventArgs^ activateArgs, bool onlyActivate) { } } -std::string GetLaunchItemPath(IActivatedEventArgs^ activateArgs) { +std::string GetLaunchItemPath(const IActivatedEventArgs& activateArgs) { DetectLaunchItem(activateArgs, true); // Just activate if (launchItemHandler.IsValid()) { // Expected that 'GetLaunchItemPath' called to handle startup item diff --git a/UWP/UWPHelpers/LaunchItem.h b/UWP/UWPHelpers/LaunchItem.h index 36979728c2..f988bd5f90 100644 --- a/UWP/UWPHelpers/LaunchItem.h +++ b/UWP/UWPHelpers/LaunchItem.h @@ -15,12 +15,9 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -using namespace Platform; -using namespace Windows::Storage; -using namespace Windows::Foundation; -using namespace Windows::UI::Core; -using namespace Windows::ApplicationModel; -using namespace Windows::ApplicationModel::Activation; +#pragma once + +#include "pch.h" // LaunchItem can detect launch items in two cases // 1- StorageFile @@ -28,13 +25,13 @@ using namespace Windows::ApplicationModel::Activation; // Detect if activate args has launch item // it will auto start the item unless 'onlyActivate' set to 'true' -void DetectLaunchItem(IActivatedEventArgs^ activateArgs, bool onlyActivate = false); +void DetectLaunchItem(const winrt::Windows::ApplicationModel::Activation::IActivatedEventArgs& activateArgs, bool onlyActivate = false); // Get current launch item path (same as 'DetectLaunchItem' but it doesn't start) // this function made to handle item on startup // it will mark the item as 'Handled' by default // consider to close it if you want to use it for other purposes -std::string GetLaunchItemPath(IActivatedEventArgs^ activateArgs); +std::string GetLaunchItemPath(const winrt::Windows::ApplicationModel::Activation::IActivatedEventArgs& activateArgs); // Close current launch item // it will launch back 'launchOnExit' if passed with URI 'cmd' diff --git a/UWP/UWPHelpers/StorageAccess.cpp b/UWP/UWPHelpers/StorageAccess.cpp index d3075345a3..87320f8540 100644 --- a/UWP/UWPHelpers/StorageAccess.cpp +++ b/UWP/UWPHelpers/StorageAccess.cpp @@ -15,55 +15,57 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "pch.h" #include "StorageAsync.h" #include "StorageAccess.h" #include "UWPUtil.h" #include "Common/File/Path.h" -using namespace Platform; -using namespace Windows::Foundation; -using namespace Windows::Foundation::Collections; -using namespace Windows::Storage::AccessCache; -using namespace Windows::ApplicationModel; +using namespace winrt; +using namespace winrt::Windows::Foundation; +using namespace winrt::Windows::Foundation::Collections; +using namespace winrt::Windows::Storage::AccessCache; +using namespace winrt::Windows::Storage; +using namespace winrt::Windows::ApplicationModel; std::list alist; -void AppendToAccessList(Platform::String^ path) +void AppendToAccessList(winrt::hstring path) { - Path p(FromPlatformString(path)); + Path p(FromHString(path)); alist.push_back(p.ToString()); } // Get value from app local settings -Platform::String^ GetDataFromLocalSettings(Platform::String^ key) { - ApplicationDataContainer^ localSettings{ ApplicationData::Current->LocalSettings }; - IPropertySet^ values{ localSettings->Values }; - if (key != nullptr) { - Platform::Object^ tokenRetrive = values->Lookup(key); - if (tokenRetrive != nullptr) { - Platform::String^ ConvertedToken = (Platform::String^)tokenRetrive; +winrt::hstring GetDataFromLocalSettings(winrt::hstring key) { + ApplicationDataContainer localSettings = ApplicationData::Current().LocalSettings(); + IPropertySet values = localSettings.Values(); + if (!key.empty()) { + auto tokenRetrive = values.TryLookup(key); + if (tokenRetrive) { + winrt::hstring ConvertedToken = winrt::unbox_value(tokenRetrive); return ConvertedToken; } } - return nullptr; + return L""; } std::string GetDataFromLocalSettings(std::string key) { - return FromPlatformString(GetDataFromLocalSettings(ToPlatformString(key))); + return FromHString(GetDataFromLocalSettings(ToHString(key))); } // Add or replace value in app local settings -bool AddDataToLocalSettings(Platform::String^ key, Platform::String^ data, bool replace) { - ApplicationDataContainer^ localSettings{ ApplicationData::Current->LocalSettings }; - IPropertySet^ values{ localSettings->Values }; +bool AddDataToLocalSettings(winrt::hstring key, winrt::hstring data, bool replace) { + ApplicationDataContainer localSettings = ApplicationData::Current().LocalSettings(); + IPropertySet values = localSettings.Values(); - Platform::String^ testResult = GetDataFromLocalSettings(key); - if (testResult == nullptr) { - values->Insert(key, PropertyValue::CreateString(data)); + winrt::hstring testResult = GetDataFromLocalSettings(key); + if (testResult.empty()) { + values.Insert(key, winrt::box_value(data)); return true; } else if (replace) { - values->Remove(key); - values->Insert(key, PropertyValue::CreateString(data)); + values.Remove(key); + values.Insert(key, winrt::box_value(data)); return true; } @@ -71,28 +73,28 @@ bool AddDataToLocalSettings(Platform::String^ key, Platform::String^ data, bool } bool AddDataToLocalSettings(std::string key, std::string data, bool replace) { - return AddDataToLocalSettings(ToPlatformString(key), ToPlatformString(data),replace); + return AddDataToLocalSettings(ToHString(key), ToHString(data), replace); } // Add folder to future list (to avoid request picker again) -void AddItemToFutureList(IStorageItem^ item) { +void AddItemToFutureList(const winrt::Windows::Storage::IStorageItem& item) { try { if (item != nullptr) { - Platform::String^ folderToken = AccessCache::StorageApplicationPermissions::FutureAccessList->Add(item); - AppendToAccessList(item->Path); + winrt::hstring folderToken = StorageApplicationPermissions::FutureAccessList().Add(item); + AppendToAccessList(item.Path()); } } - catch (Platform::COMException^ e) { + catch (const winrt::hresult_error&) { } } // Get item by key // This function can be used when you store token in LocalSettings as custom key -IStorageItem^ GetItemByKey(Platform::String^ key) { - IStorageItem^ item; - Platform::String^ itemToken = GetDataFromLocalSettings(key); - if (itemToken != nullptr && AccessCache::StorageApplicationPermissions::FutureAccessList->ContainsItem(itemToken)) { - ExecuteTask(item, AccessCache::StorageApplicationPermissions::FutureAccessList->GetItemAsync(itemToken)); +winrt::Windows::Storage::IStorageItem GetItemByKey(winrt::hstring key) { + winrt::Windows::Storage::IStorageItem item = nullptr; + winrt::hstring itemToken = GetDataFromLocalSettings(key); + if (!itemToken.empty() && StorageApplicationPermissions::FutureAccessList().ContainsItem(itemToken)) { + ExecuteTask(item, StorageApplicationPermissions::FutureAccessList().GetItemAsync(itemToken)); } return item; @@ -100,28 +102,28 @@ IStorageItem^ GetItemByKey(Platform::String^ key) { std::list GetFutureAccessList() { if (alist.empty()) { - auto AccessList = AccessCache::StorageApplicationPermissions::FutureAccessList->Entries; - for (auto it = 0; it != AccessList->Size; ++it){ - auto item = AccessList->GetAt(it); + auto AccessList = StorageApplicationPermissions::FutureAccessList().Entries(); + for (uint32_t it = 0; it != AccessList.Size(); ++it){ + auto item = AccessList.GetAt(it); try { auto token = item.Token; - if (token != nullptr && AccessCache::StorageApplicationPermissions::FutureAccessList->ContainsItem(token)) { - IStorageItem^ storageItem; - ExecuteTask(storageItem, AccessCache::StorageApplicationPermissions::FutureAccessList->GetItemAsync(token)); + if (!token.empty() && StorageApplicationPermissions::FutureAccessList().ContainsItem(token)) { + winrt::Windows::Storage::IStorageItem storageItem = nullptr; + ExecuteTask(storageItem, StorageApplicationPermissions::FutureAccessList().GetItemAsync(token)); if (storageItem != nullptr) { - AppendToAccessList(storageItem->Path); + AppendToAccessList(storageItem.Path()); } else { - AccessCache::StorageApplicationPermissions::FutureAccessList->Remove(token); + StorageApplicationPermissions::FutureAccessList().Remove(token); } } } - catch (Platform::COMException^ e) { + catch (const winrt::hresult_error&) { } } - AppendToAccessList(ApplicationData::Current->LocalFolder->Path); - AppendToAccessList(ApplicationData::Current->TemporaryFolder->Path); + AppendToAccessList(ApplicationData::Current().LocalFolder().Path()); + AppendToAccessList(ApplicationData::Current().TemporaryFolder().Path()); } return alist; } diff --git a/UWP/UWPHelpers/StorageAccess.h b/UWP/UWPHelpers/StorageAccess.h index e7b967b4fb..a741e77458 100644 --- a/UWP/UWPHelpers/StorageAccess.h +++ b/UWP/UWPHelpers/StorageAccess.h @@ -23,10 +23,14 @@ #include #include -using namespace Windows::Storage; +winrt::hstring GetDataFromLocalSettings(winrt::hstring key); // Local settings std::string GetDataFromLocalSettings(std::string key); +bool AddDataToLocalSettings(winrt::hstring key, winrt::hstring data, bool replace); bool AddDataToLocalSettings(std::string key, std::string data, bool replace); -void AddItemToFutureList(IStorageItem^ item); + +void AddItemToFutureList(const winrt::Windows::Storage::IStorageItem& item); +winrt::Windows::Storage::IStorageItem GetItemByKey(winrt::hstring key); + std::list GetFutureAccessList(); diff --git a/UWP/UWPHelpers/StorageAsync.cpp b/UWP/UWPHelpers/StorageAsync.cpp index e79152fe9c..68240e2377 100644 --- a/UWP/UWPHelpers/StorageAsync.cpp +++ b/UWP/UWPHelpers/StorageAsync.cpp @@ -1,26 +1,49 @@ // Thanks to RetroArch/Libretro team for this idea // This is improved version of the original idea +#include "pch.h" #include "StorageAsync.h" -bool ActionPass(Windows::Foundation::IAsyncAction^ action) -{ - try { - return TaskHandler([&]() { - return concurrency::create_task(action).then([]() { - return true; - }); - }, false); - } - catch (...) { - return false; +bool ActionPass(winrt::Windows::Foundation::IAsyncAction action) { + bool result = false; + bool done = false; + + action.Completed([&](auto&& sender, winrt::Windows::Foundation::AsyncStatus status) { + if (status == winrt::Windows::Foundation::AsyncStatus::Completed) { + result = true; + } + else { + ERROR_LOG(Log::FileSystem, "Async action failed with status %d", (int)status); + result = false; + } + done = true; + }); + + winrt::Windows::UI::Core::CoreWindow corewindow = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread(); + while (!done) { + try { + if (corewindow) { + corewindow.Dispatcher().ProcessEvents(winrt::Windows::UI::Core::CoreProcessEventsOption::ProcessAllIfPresent); + } + else { + corewindow = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread(); + } + } + catch (...) { + } } + + return result; } // Async action such as 'Delete' file // @action: async action // return false when action failed -bool ExecuteTask(Windows::Foundation::IAsyncAction^ action) -{ - return ActionPass(action); -}; +bool ExecuteTask(winrt::Windows::Foundation::IAsyncAction action) { + try { + return ActionPass(action); + } + catch (...) { + return false; + } +} diff --git a/UWP/UWPHelpers/StorageAsync.h b/UWP/UWPHelpers/StorageAsync.h index b55066d303..11fb19a33f 100644 --- a/UWP/UWPHelpers/StorageAsync.h +++ b/UWP/UWPHelpers/StorageAsync.h @@ -6,45 +6,43 @@ #include "pch.h" #include #include -#include -#include +#include #include "Common/Log.h" #include "UWPUtil.h" -using namespace Windows::UI::Core; - -// Don't add 'using' 'Windows::Foundation' -// it might cause confilct with some types like 'Point' - -#pragma region Async Handlers - +// Helper to detect if a type is a WinRT runtime class (nullable) template -T TaskHandler(std::function()> wtask, T def) +struct is_winrt_class : std::bool_constant> {}; + +// Execute a WinRT async operation synchronously by spinning the message pump (for WinRT classes) +template +T ExecuteAsyncWithPump(winrt::Windows::Foundation::IAsyncOperation asyncOp) { - T result = def; + T result{ nullptr }; bool done = false; - wtask().then([&](concurrency::task t) { - try - { - result = t.get(); - } - catch (Platform::Exception^ exception_) - { - ERROR_LOG(Log::FileSystem, FromPlatformString(exception_->Message).c_str()); - } + + asyncOp.Completed([&](auto&& sender, winrt::Windows::Foundation::AsyncStatus status) { + if (status == winrt::Windows::Foundation::AsyncStatus::Completed) { + try { + result = sender.GetResults(); + } + catch (const winrt::hresult_error& e) { + ERROR_LOG(Log::FileSystem, "%s", winrt::to_string(e.message()).c_str()); + } + } done = true; }); - CoreWindow^ corewindow = CoreWindow::GetForCurrentThread(); + winrt::Windows::UI::Core::CoreWindow corewindow = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread(); while (!done) { try { if (corewindow) { - corewindow->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent); + corewindow.Dispatcher().ProcessEvents(winrt::Windows::UI::Core::CoreProcessEventsOption::ProcessAllIfPresent); } else { - corewindow = CoreWindow::GetForCurrentThread(); + corewindow = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread(); } } catch (...) { @@ -53,53 +51,85 @@ T TaskHandler(std::function()> wtask, T def) } return result; -}; - -template -T TaskPass(Windows::Foundation::IAsyncOperation^ task, T def) -{ - return TaskHandler([&]() { - return concurrency::create_task(task).then([](T res) { - return res; - }); - }, def); } -bool ActionPass(Windows::Foundation::IAsyncAction^ action); - -#pragma endregion - -// Now it's more simple to execute async task -// @out: output variable -// @task: async task +// Execute for value types with default value template -void ExecuteTask(T& out, Windows::Foundation::IAsyncOperation^ task) +T ExecuteAsyncWithPumpValue(winrt::Windows::Foundation::IAsyncOperation asyncOp, T def) +{ + T result = def; + bool done = false; + + asyncOp.Completed([&](auto&& sender, winrt::Windows::Foundation::AsyncStatus status) { + if (status == winrt::Windows::Foundation::AsyncStatus::Completed) { + try { + result = sender.GetResults(); + } + catch (const winrt::hresult_error& e) { + ERROR_LOG(Log::FileSystem, "%s", winrt::to_string(e.message()).c_str()); + } + } + done = true; + }); + + winrt::Windows::UI::Core::CoreWindow corewindow = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread(); + while (!done) + { + try { + if (corewindow) { + corewindow.Dispatcher().ProcessEvents(winrt::Windows::UI::Core::CoreProcessEventsOption::ProcessAllIfPresent); + } + else { + corewindow = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread(); + } + } + catch (...) { + + } + } + + return result; +} + +bool ActionPass(winrt::Windows::Foundation::IAsyncAction action); + +// ExecuteTask for WinRT runtime class types (StorageFile, StorageFolder, etc) +template::value, int> = 0> +void ExecuteTask(T& out, winrt::Windows::Foundation::IAsyncOperation task) { try { - out = TaskPass(task, T()); + out = ExecuteAsyncWithPump(task); } catch (...) { - out = T(); + out = nullptr; } -}; +} -// For specific return default value -// @out: output variable -// @task: async task -// @def: default value when fail -template -void ExecuteTask(T& out, Windows::Foundation::IAsyncOperation^ task, T def) +// ExecuteTask for value types (bool, int, enums, etc) +template::value, int> = 0> +void ExecuteTask(T& out, winrt::Windows::Foundation::IAsyncOperation task) { - try{ - out = TaskPass(task, def); + try { + out = ExecuteAsyncWithPumpValue(task, T{}); + } + catch (...) { + out = T{}; + } +} + +// ExecuteTask for value types with default value +template +void ExecuteTask(T& out, winrt::Windows::Foundation::IAsyncOperation task, T def) +{ + try { + out = ExecuteAsyncWithPumpValue(task, def); } catch (...) { out = def; } -}; - +} // Async action such as 'Delete' file // @action: async action // return false when action failed -bool ExecuteTask(Windows::Foundation::IAsyncAction^ action); +bool ExecuteTask(winrt::Windows::Foundation::IAsyncAction action); diff --git a/UWP/UWPHelpers/StorageManager.cpp b/UWP/UWPHelpers/StorageManager.cpp index c54fdd59ae..5961672899 100644 --- a/UWP/UWPHelpers/StorageManager.cpp +++ b/UWP/UWPHelpers/StorageManager.cpp @@ -18,7 +18,6 @@ #include "pch.h" #include #include -#include #include "Common/Log.h" #include "Core/Config.h" @@ -30,11 +29,10 @@ #include "StorageAsync.h" #include "StorageAccess.h" - -using namespace Platform; -using namespace Windows::Storage; -using namespace Windows::Foundation; -using namespace Windows::ApplicationModel; +using namespace winrt; +using namespace winrt::Windows::Storage; +using namespace winrt::Windows::Foundation; +using namespace winrt::Windows::ApplicationModel; #pragma region Locations @@ -47,22 +45,22 @@ std::string GetPSPFolder() { } } std::string GetInstallationFolder() { - return FromPlatformString(Package::Current->InstalledLocation->Path); + return FromHString(Package::Current().InstalledLocation().Path()); } -StorageFolder^ GetLocalStorageFolder() { - return ApplicationData::Current->LocalFolder; +winrt::Windows::Storage::StorageFolder GetLocalStorageFolder() { + return ApplicationData::Current().LocalFolder(); } std::string GetLocalFolder() { - return FromPlatformString(GetLocalStorageFolder()->Path); + return FromHString(GetLocalStorageFolder().Path()); } std::string GetTempFolder() { - return FromPlatformString(ApplicationData::Current->TemporaryFolder->Path); + return FromHString(ApplicationData::Current().TemporaryFolder().Path()); } std::string GetTempFile(std::string name) { - StorageFile^ tmpFile; - ExecuteTask(tmpFile, ApplicationData::Current->TemporaryFolder->CreateFileAsync(ToPlatformString(name), CreationCollisionOption::GenerateUniqueName)); + StorageFile tmpFile = nullptr; + ExecuteTask(tmpFile, ApplicationData::Current().TemporaryFolder().CreateFileAsync(ToHString(name), CreationCollisionOption::GenerateUniqueName)); if (tmpFile != nullptr) { - return FromPlatformString(tmpFile->Path); + return FromHString(tmpFile.Path()); } else { return ""; @@ -70,19 +68,19 @@ std::string GetTempFile(std::string name) { } std::string GetPicturesFolder() { // Requires 'picturesLibrary' capability - return FromPlatformString(KnownFolders::PicturesLibrary->Path); + return FromHString(KnownFolders::PicturesLibrary().Path()); } std::string GetVideosFolder() { // Requires 'videosLibrary' capability - return FromPlatformString(KnownFolders::VideosLibrary->Path); + return FromHString(KnownFolders::VideosLibrary().Path()); } std::string GetDocumentsFolder() { // Requires 'documentsLibrary' capability - return FromPlatformString(KnownFolders::DocumentsLibrary->Path); + return FromHString(KnownFolders::DocumentsLibrary().Path()); } std::string GetMusicFolder() { // Requires 'musicLibrary' capability - return FromPlatformString(KnownFolders::MusicLibrary->Path); + return FromHString(KnownFolders::MusicLibrary().Path()); } std::string GetPreviewPath(std::string path) { std::string pathView = path; @@ -258,7 +256,7 @@ bool IsRootForAccessibleItems(Path path, std::list& subRoot, bool b // This check can be better, but that's how I can do it in C++ if (!endsWith(sub, ":")) { bool alreadyAdded = false; - for each (auto sItem in subRoot) { + for (const auto& sItem : subRoot) { if (sItem == sub) { alreadyAdded = true; break; @@ -283,7 +281,7 @@ bool GetFakeFolders(Path path, std::vector* files, const char* f std::list subRoot; if (IsRootForAccessibleItems(path, subRoot)) { if (!subRoot.empty()) { - for each (auto sItem in subRoot) { + for (const auto& sItem : subRoot) { auto folderPath = Path(sItem); File::FileInfo info; info.name = folderPath.GetFilename(); @@ -310,16 +308,16 @@ bool GetFakeFolders(Path path, std::vector* files, const char* f #pragma region Helpers bool OpenFile(std::string path) { bool state = false; - Platform::String^ wString = ref new Platform::String(Path(path).ToWString().c_str()); + winrt::hstring wString = winrt::hstring(Path(path).ToWString()); - StorageFile^ storageItem; + StorageFile storageItem = nullptr; ExecuteTask(storageItem, StorageFile::GetFileFromPathAsync(wString)); if (storageItem != nullptr) { - ExecuteTask(state, Windows::System::Launcher::LaunchFileAsync(storageItem), false); + ExecuteTask(state, winrt::Windows::System::Launcher::LaunchFileAsync(storageItem), false); } else { - auto uri = ref new Windows::Foundation::Uri(wString); - ExecuteTask(state, Windows::System::Launcher::LaunchUriAsync(uri), false); + auto uri = winrt::Windows::Foundation::Uri(wString); + ExecuteTask(state, winrt::Windows::System::Launcher::LaunchUriAsync(uri), false); } return state; } @@ -327,20 +325,20 @@ bool OpenFile(std::string path) { bool OpenFolder(std::string path) { bool state = false; Path itemPath(path); - Platform::String^ wString = ref new Platform::String(itemPath.ToWString().c_str()); - StorageFolder^ storageItem; + winrt::hstring wString = winrt::hstring(itemPath.ToWString()); + StorageFolder storageItem = nullptr; ExecuteTask(storageItem, StorageFolder::GetFolderFromPathAsync(wString)); if (storageItem != nullptr) { - ExecuteTask(state, Windows::System::Launcher::LaunchFolderAsync(storageItem), false); + ExecuteTask(state, winrt::Windows::System::Launcher::LaunchFolderAsync(storageItem), false); } else { // Try as it's file Path parent = Path(itemPath.GetDirectory()); - Platform::String^ wParentString = ref new Platform::String(parent.ToWString().c_str()); + winrt::hstring wParentString = winrt::hstring(parent.ToWString()); ExecuteTask(storageItem, StorageFolder::GetFolderFromPathAsync(wParentString)); if (storageItem != nullptr) { - ExecuteTask(state, Windows::System::Launcher::LaunchFolderAsync(storageItem), false); + ExecuteTask(state, winrt::Windows::System::Launcher::LaunchFolderAsync(storageItem), false); } } return state; @@ -356,24 +354,21 @@ bool GetDriveFreeSpace(Path path, int64_t& space) { g_Config.memStickDirectory = path; } } - Platform::String^ wString = ref new Platform::String(path.ToWString().c_str()); - StorageFolder^ storageItem; + winrt::hstring wString = winrt::hstring(path.ToWString()); + StorageFolder storageItem = nullptr; ExecuteTask(storageItem, StorageFolder::GetFolderFromPathAsync(wString)); if (storageItem != nullptr) { - Platform::String^ freeSpaceKey = ref new Platform::String(L"System.FreeSpace"); - Platform::Collections::Vector^ propertiesToRetrieve = ref new Platform::Collections::Vector(); - propertiesToRetrieve->Append(freeSpaceKey); - Windows::Foundation::Collections::IMap^ result; - ExecuteTask(result, storageItem->Properties->RetrievePropertiesAsync(propertiesToRetrieve)); - if (result != nullptr && result->Size > 0) { - try { - auto value = result->Lookup(L"System.FreeSpace"); - space = (uint64_t)value; + try { + auto props = winrt::single_threaded_vector({ L"System.FreeSpace" }); + auto result = storageItem.Properties().RetrievePropertiesAsync(props).get(); + if (result.Size() > 0) { + auto value = result.Lookup(L"System.FreeSpace"); + space = winrt::unbox_value(value); state = true; } - catch (...) { + } + catch (...) { - } } } diff --git a/UWP/UWPHelpers/StoragePickers.cpp b/UWP/UWPHelpers/StoragePickers.cpp index db725834f7..4cb9802355 100644 --- a/UWP/UWPHelpers/StoragePickers.cpp +++ b/UWP/UWPHelpers/StoragePickers.cpp @@ -20,67 +20,60 @@ #include "StorageAsync.h" #include "StorageAccess.h" -using namespace Platform; -using namespace Windows::Storage; -using namespace Windows::Foundation; - -extern void AddItemToFutureList(IStorageItem^ folder); +using namespace winrt; +using namespace winrt::Windows::Storage; +using namespace winrt::Windows::Storage::Pickers; +using namespace winrt::Windows::Foundation; // Call folder picker (the selected folder will be added to future list) -concurrency::task PickSingleFolder() +std::string PickSingleFolder() { - auto folderPicker = ref new Windows::Storage::Pickers::FolderPicker(); - folderPicker->SuggestedStartLocation = Windows::Storage::Pickers::PickerLocationId::Desktop; - folderPicker->FileTypeFilter->Append("*"); + FolderPicker folderPicker; + folderPicker.SuggestedStartLocation(PickerLocationId::Desktop); + folderPicker.FileTypeFilter().Append(L"*"); - return concurrency::create_task(folderPicker->PickSingleFolderAsync()).then([](StorageFolder^ folder) { - auto path = ref new Platform::String(); - if (folder != nullptr) - { - AddItemToFutureList(folder); - path = folder->Path; - } - return path; - }); + StorageFolder folder{ nullptr }; + ExecuteTask(folder, folderPicker.PickSingleFolderAsync()); + + std::string path; + if (folder) { + AddItemToFutureList(folder); + path = winrt::to_string(folder.Path()); + } + return path; } // Call file picker (the selected file will be added to future list) -concurrency::task PickSingleFile(std::vector exts) +std::string PickSingleFile(std::vector exts) { - auto filePicker = ref new Windows::Storage::Pickers::FileOpenPicker(); - filePicker->SuggestedStartLocation = Windows::Storage::Pickers::PickerLocationId::Desktop; - filePicker->ViewMode = Pickers::PickerViewMode::List; + FileOpenPicker filePicker; + filePicker.SuggestedStartLocation(PickerLocationId::Desktop); + filePicker.ViewMode(PickerViewMode::List); - if (exts.size() > 0) { - for each (auto ext in exts) { - filePicker->FileTypeFilter->Append(ToPlatformString(ext)); + if (!exts.empty()) { + for (const auto& ext : exts) { + filePicker.FileTypeFilter().Append(winrt::to_hstring(ext)); } } - else - { - filePicker->FileTypeFilter->Append("*"); + else { + filePicker.FileTypeFilter().Append(L"*"); } - return concurrency::create_task(filePicker->PickSingleFileAsync()).then([](StorageFile^ file) { - auto path = ref new Platform::String(); - if (file != nullptr) - { - AddItemToFutureList(file); - path = file->Path; - } - return path; - }); + + StorageFile file{ nullptr }; + ExecuteTask(file, filePicker.PickSingleFileAsync()); + + std::string path; + if (file) { + AddItemToFutureList(file); + path = winrt::to_string(file.Path()); + } + return path; } - -concurrency::task ChooseFile(std::vector exts) { - return PickSingleFile(exts).then([](Platform::String^ filePath) { - return FromPlatformString(filePath); - }); +std::string ChooseFile(std::vector exts) { + return PickSingleFile(exts); } -concurrency::task ChooseFolder() { - return PickSingleFolder().then([](Platform::String^ folderPath) { - return FromPlatformString(folderPath); - }); - +std::string ChooseFolder() { + return PickSingleFolder(); } diff --git a/UWP/UWPHelpers/StoragePickers.h b/UWP/UWPHelpers/StoragePickers.h index 8d845e6798..afcbdcad08 100644 --- a/UWP/UWPHelpers/StoragePickers.h +++ b/UWP/UWPHelpers/StoragePickers.h @@ -17,10 +17,8 @@ #pragma once -#include -#include #include #include -concurrency::task ChooseFolder(); -concurrency::task ChooseFile(std::vector exts); +std::string ChooseFolder(); +std::string ChooseFile(std::vector exts); diff --git a/UWP/UWPUtil.h b/UWP/UWPUtil.h index 683b17b166..602901a8c8 100644 --- a/UWP/UWPUtil.h +++ b/UWP/UWPUtil.h @@ -1,12 +1,12 @@ #pragma once +#include "pch.h" #include "Common/Data/Encoding/Utf8.h" -inline Platform::String ^ToPlatformString(std::string_view str) { - return ref new Platform::String(ConvertUTF8ToWString(str).c_str()); +inline winrt::hstring ToHString(std::string_view str) { + return winrt::hstring(ConvertUTF8ToWString(str)); } -inline std::string FromPlatformString(Platform::String ^str) { - std::wstring wstr(str->Data()); - return ConvertWStringToUTF8(wstr); +inline std::string FromHString(const winrt::hstring& str) { + return ConvertWStringToUTF8(std::wstring(str)); } diff --git a/UWP/packages.config b/UWP/packages.config new file mode 100644 index 0000000000..f229371b33 --- /dev/null +++ b/UWP/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/UWP/pch.h b/UWP/pch.h index 95b1c658cf..0fbfbd2129 100644 --- a/UWP/pch.h +++ b/UWP/pch.h @@ -2,8 +2,34 @@ #define NOMINMAX -#include -#include +// C++/WinRT headers +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// DirectX headers #include #include #include @@ -13,5 +39,4 @@ #include #include #include -#include -#include \ No newline at end of file +#include