CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/UWP/App.cpp
Views: 1401
#include "ppsspp_config.h"12#include "pch.h"3#include "App.h"45#include <ppltasks.h>6#include <mutex>78#include "Common/Net/HTTPClient.h"9#include "Common/Net/Resolve.h"1011#include "Common/File/VFS/VFS.h"12#include "Common/File/VFS/DirectoryReader.h"13#include "Common/Data/Encoding/Utf8.h"14#include "Common/Input/InputState.h"15#include "Common/System/NativeApp.h"16#include "Common/System/System.h"17#include "Common/Log/LogManager.h"18#include "Core/System.h"19#include "Core/Config.h"20#include "Core/Core.h"21#include "UWPHelpers/LaunchItem.h"22#include <UWPUtil.h>2324using namespace UWP;2526using namespace concurrency;27using namespace Windows::ApplicationModel;28using namespace Windows::ApplicationModel::Core;29using namespace Windows::ApplicationModel::Activation;30using namespace Windows::UI::Core;31using namespace Windows::UI::Input;32using namespace Windows::System;33using namespace Windows::Foundation;34using namespace Windows::Graphics::Display;3536// The main function is only used to initialize our IFrameworkView class.37[Platform::MTAThread]38int main(Platform::Array<Platform::String^>^) {39auto direct3DApplicationSource = ref new Direct3DApplicationSource();40CoreApplication::Run(direct3DApplicationSource);41return 0;42}4344IFrameworkView^ Direct3DApplicationSource::CreateView() {45return ref new App();46}4748App::App() :49m_windowClosed(false),50m_windowVisible(true)51{52}5354void App::InitialPPSSPP() {55// Initial net56net::Init();5758// Get install location59auto packageDirectory = Package::Current->InstalledPath;60const Path& exePath = Path(FromPlatformString(packageDirectory));61g_VFS.Register("", new DirectoryReader(exePath / "Content"));62g_VFS.Register("", new DirectoryReader(exePath));6364// Mount a filesystem65g_Config.flash0Directory = exePath / "assets/flash0";6667// Prepare for initialization68std::wstring internalDataFolderW = ApplicationData::Current->LocalFolder->Path->Data();69g_Config.internalDataDirectory = Path(internalDataFolderW);70g_Config.memStickDirectory = g_Config.internalDataDirectory;7172// On Win32 it makes more sense to initialize the system directories here73// because the next place it was called was in the EmuThread, and it's too late by then.74CreateSysDirectories();7576LogManager::Init(&g_Config.bEnableLogging);7778// Set the config path to local state by default79// it will be overrided by `NativeInit` if there is custom memStick80g_Config.SetSearchPath(GetSysDirectory(DIRECTORY_SYSTEM));81g_Config.Load();8283if (g_Config.bFirstRun) {84// Clear `memStickDirectory` to show memory stick screen on first start85g_Config.memStickDirectory.clear();86}8788// Since we don't have any async operation in `NativeInit`89// it's better to call it here90const char* argv[2] = { "fake", nullptr };91std::string cacheFolder = ConvertWStringToUTF8(ApplicationData::Current->TemporaryFolder->Path->Data());92// We will not be able to use `argv`93// since launch parameters usually handled by `OnActivated`94// and `OnActivated` will be invoked later, even after `PPSSPP_UWPMain(..)`95// so we are handling launch cases using `LaunchItem`96NativeInit(1, argv, "", "", cacheFolder.c_str());9798// Override backend, `DIRECT3D11` is the only way for UWP apps99g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D11;100101// Calling `NativeInit` before will help us to deal with custom configs102// such as custom adapter, so it's better to initial render device here103m_deviceResources = std::make_shared<DX::DeviceResources>();104m_deviceResources->CreateWindowSizeDependentResources();105}106107// The first method called when the IFrameworkView is being created.108void App::Initialize(CoreApplicationView^ applicationView) {109// Register event handlers for app lifecycle. This example includes Activated, so that we110// can make the CoreWindow active and start rendering on the window.111applicationView->Activated +=112ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &App::OnActivated);113114CoreApplication::Suspending +=115ref new EventHandler<SuspendingEventArgs^>(this, &App::OnSuspending);116117CoreApplication::Resuming +=118ref new EventHandler<Platform::Object^>(this, &App::OnResuming);119}120121// Called when the CoreWindow object is created (or re-created).122void App::SetWindow(CoreWindow^ window) {123window->SizeChanged +=124ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &App::OnWindowSizeChanged);125126window->VisibilityChanged +=127ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &App::OnVisibilityChanged);128129window->Closed +=130ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &App::OnWindowClosed);131132DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView();133134currentDisplayInformation->DpiChanged +=135ref new TypedEventHandler<DisplayInformation^, Object^>(this, &App::OnDpiChanged);136137currentDisplayInformation->OrientationChanged +=138ref new TypedEventHandler<DisplayInformation^, Object^>(this, &App::OnOrientationChanged);139140DisplayInformation::DisplayContentsInvalidated +=141ref new TypedEventHandler<DisplayInformation^, Object^>(this, &App::OnDisplayContentsInvalidated);142143window->KeyDown += ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &App::OnKeyDown);144window->KeyUp += ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &App::OnKeyUp);145window->CharacterReceived += ref new TypedEventHandler<CoreWindow^, CharacterReceivedEventArgs^>(this, &App::OnCharacterReceived);146147window->PointerMoved += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerMoved);148window->PointerEntered += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerEntered);149window->PointerExited += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerExited);150window->PointerPressed += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerPressed);151window->PointerReleased += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerReleased);152window->PointerCaptureLost += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerCaptureLost);153window->PointerWheelChanged += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerWheelChanged);154155if (Windows::Foundation::Metadata::ApiInformation::IsTypePresent("Windows.Phone.UI.Input.HardwareButtons")) {156m_hardwareButtons.insert(HardwareButton::BACK);157}158159if (Windows::System::Profile::AnalyticsInfo::VersionInfo->DeviceFamily == "Windows.Mobile") {160m_isPhone = true;161}162163Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->164BackRequested += ref new Windows::Foundation::EventHandler<165Windows::UI::Core::BackRequestedEventArgs^>(166this, &App::App_BackRequested);167168InitialPPSSPP();169}170171bool App::HasBackButton() {172if (m_hardwareButtons.count(HardwareButton::BACK) != 0)173return true;174else175return false;176}177178void App::App_BackRequested(Platform::Object^ sender, Windows::UI::Core::BackRequestedEventArgs^ e) {179if (m_isPhone) {180e->Handled = m_main->OnHardwareButton(HardwareButton::BACK);181} else {182e->Handled = true;183}184}185186void App::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) {187m_main->OnKeyDown(args->KeyStatus.ScanCode, args->VirtualKey, args->KeyStatus.RepeatCount);188}189190void App::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) {191m_main->OnKeyUp(args->KeyStatus.ScanCode, args->VirtualKey);192}193194void App::OnCharacterReceived(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CharacterReceivedEventArgs^ args) {195m_main->OnCharacterReceived(args->KeyStatus.ScanCode, args->KeyCode);196}197198void App::OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {199int pointerId = touchMap_.TouchId(args->CurrentPoint->PointerId);200if (pointerId < 0)201return;202float X = args->CurrentPoint->Position.X;203float Y = args->CurrentPoint->Position.Y;204int64_t timestamp = args->CurrentPoint->Timestamp;205m_main->OnTouchEvent(TOUCH_MOVE, pointerId, X, Y, (double)timestamp);206}207208void App::OnPointerEntered(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {209}210211void App::OnPointerExited(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {212}213214void App::OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {215int pointerId = touchMap_.TouchId(args->CurrentPoint->PointerId);216if (pointerId < 0)217pointerId = touchMap_.AddNewTouch(args->CurrentPoint->PointerId);218219float X = args->CurrentPoint->Position.X;220float Y = args->CurrentPoint->Position.Y;221int64_t timestamp = args->CurrentPoint->Timestamp;222m_main->OnTouchEvent(TOUCH_DOWN|TOUCH_MOVE, pointerId, X, Y, (double)timestamp);223if (!m_isPhone) {224sender->SetPointerCapture();225}226}227228void App::OnPointerReleased(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {229int pointerId = touchMap_.RemoveTouch(args->CurrentPoint->PointerId);230if (pointerId < 0)231return;232float X = args->CurrentPoint->Position.X;233float Y = args->CurrentPoint->Position.Y;234int64_t timestamp = args->CurrentPoint->Timestamp;235m_main->OnTouchEvent(TOUCH_UP|TOUCH_MOVE, pointerId, X, Y, (double)timestamp);236if (!m_isPhone) {237sender->ReleasePointerCapture();238}239}240241void App::OnPointerCaptureLost(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {242}243244void App::OnPointerWheelChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {245int pointerId = 0; // irrelevant246float delta = (float)args->CurrentPoint->GetCurrentPoint(args->CurrentPoint->PointerId)->Properties->MouseWheelDelta;247m_main->OnMouseWheel(delta);248}249250// Initializes scene resources, or loads a previously saved app state.251void App::Load(Platform::String^ entryPoint) {252if (m_main == nullptr) {253m_main = std::unique_ptr<PPSSPP_UWPMain>(new PPSSPP_UWPMain(this, m_deviceResources));254}255}256257// This method is called after the window becomes active.258void App::Run() {259while (!m_windowClosed) {260if (m_windowVisible) {261CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);262m_main->Render();263// TODO: Adopt some practices from m_deviceResources->Present();264} else {265CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);266}267}268}269270// Required for IFrameworkView.271// Terminate events do not cause Uninitialize to be called. It will be called if your IFrameworkView272// class is torn down while the app is in the foreground.273void App::Uninitialize() {274}275276// Application lifecycle event handlers.277void App::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args) {278// Run() won't start until the CoreWindow is activated.279CoreWindow::GetForCurrentThread()->Activate();280// On mobile, we force-enter fullscreen mode.281if (m_isPhone)282g_Config.iForceFullScreen = 1;283284if (g_Config.UseFullScreen())285Windows::UI::ViewManagement::ApplicationView::GetForCurrentView()->TryEnterFullScreenMode();286287//Detect if app started or activated by launch item (file, uri)288DetectLaunchItem(args);289}290291void App::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args) {292// Save app state asynchronously after requesting a deferral. Holding a deferral293// indicates that the application is busy performing suspending operations. Be294// aware that a deferral may not be held indefinitely. After about five seconds,295// the app will be forced to exit.296SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();297auto app = this;298299create_task([app, deferral]() {300g_Config.Save("App::OnSuspending");301app->m_deviceResources->Trim();302deferral->Complete();303});304}305306void App::OnResuming(Platform::Object^ sender, Platform::Object^ args) {307// Restore any data or state that was unloaded on suspend. By default, data308// and state are persisted when resuming from suspend. Note that this event309// does not occur if the app was previously terminated.310311// Insert your code here.312}313314// Window event handlers.315316void App::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args) {317auto view = Windows::UI::ViewManagement::ApplicationView::GetForCurrentView();318g_Config.bFullScreen = view->IsFullScreenMode;319g_Config.iForceFullScreen = -1;320321float width = sender->Bounds.Width;322float height = sender->Bounds.Height;323float scale = m_deviceResources->GetDpi() / 96.0f;324325m_deviceResources->SetLogicalSize(Size(width, height));326if (m_main) {327m_main->CreateWindowSizeDependentResources();328}329330PSP_CoreParameter().pixelWidth = (int)(width * scale);331PSP_CoreParameter().pixelHeight = (int)(height * scale);332if (UpdateScreenScale((int)width, (int)height)) {333System_PostUIMessage(UIMessage::GPU_DISPLAY_RESIZED);334}335}336337void App::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) {338m_windowVisible = args->Visible;339}340341void App::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) {342m_windowClosed = true;343}344345// DisplayInformation event handlers.346347void App::OnDpiChanged(DisplayInformation^ sender, Object^ args) {348// Note: The value for LogicalDpi retrieved here may not match the effective DPI of the app349// if it is being scaled for high resolution devices. Once the DPI is set on DeviceResources,350// you should always retrieve it using the GetDpi method.351// See DeviceResources.cpp for more details.352m_deviceResources->SetDpi(sender->LogicalDpi);353m_main->CreateWindowSizeDependentResources();354}355356void App::OnOrientationChanged(DisplayInformation^ sender, Object^ args) {357m_deviceResources->SetCurrentOrientation(sender->CurrentOrientation);358m_main->CreateWindowSizeDependentResources();359}360361void App::OnDisplayContentsInvalidated(DisplayInformation^ sender, Object^ args) {362m_deviceResources->ValidateDevice();363}364365366