mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-17 04:39:34 +00:00
UWP: Hook up basic touch/mouse input. Start work on loading from a StorageFile. Getting closer to starting to boot a game
This commit is contained in:
parent
86f4559748
commit
4ced81b1df
@ -280,7 +280,7 @@ void FreeAlignedMemory(void* ptr) {
|
||||
bool PlatformIsWXExclusive() {
|
||||
// Only iOS really needs this mode currently. Even without block linking, still should be much faster than IR JIT.
|
||||
// This might also come in useful for UWP (Universal Windows Platform) if I'm understanding things correctly.
|
||||
#ifdef IOS
|
||||
#if defined(IOS) || PPSSPP_PLATFORM(UWP)
|
||||
return true;
|
||||
#else
|
||||
// Returning true here lets you test the W^X path on Windows and other non-W^X platforms.
|
||||
|
@ -35,9 +35,22 @@
|
||||
#include "Core/ELF/PBPReader.h"
|
||||
#include "Core/ELF/ParamSFO.h"
|
||||
|
||||
// Gross, gross hack! But necessary for UWP, fitting it in neatly would be a major refactor
|
||||
FileLoader *g_OverriddenLoader;
|
||||
IdentifiedFileType g_OverriddenFiletype;
|
||||
|
||||
void OverrideNextLoader(FileLoader *fileLoader, IdentifiedFileType fileType) {
|
||||
g_OverriddenLoader = fileLoader;
|
||||
g_OverriddenFiletype = fileType;
|
||||
}
|
||||
|
||||
FileLoader *ConstructFileLoader(const std::string &filename) {
|
||||
if (filename.find("http://") == 0 || filename.find("https://") == 0)
|
||||
return new CachingFileLoader(new DiskCachingFileLoader(new RetryingFileLoader(new HTTPFileLoader(filename))));
|
||||
if (filename == "override://") {
|
||||
g_OverriddenLoader = nullptr;
|
||||
return g_OverriddenLoader;
|
||||
}
|
||||
return new LocalFileLoader(filename);
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
enum class IdentifiedFileType {
|
||||
ERROR_IDENTIFYING,
|
||||
@ -100,5 +101,7 @@ std::string ResolvePBPFile(const std::string &filename);
|
||||
|
||||
IdentifiedFileType Identify_File(FileLoader *fileLoader);
|
||||
|
||||
void OverrideNextLoader(FileLoader *fileLoader, IdentifiedFileType fileType);
|
||||
|
||||
// Can modify the string filename, as it calls IdentifyFile above.
|
||||
bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string);
|
||||
|
@ -228,7 +228,7 @@ bool GameInfo::LoadFromPath(const std::string &gamePath) {
|
||||
title = File::GetFilename(filePath_);
|
||||
}
|
||||
|
||||
return GetFileLoader()->Exists();
|
||||
return fileLoader ? fileLoader->Exists() : true;
|
||||
}
|
||||
|
||||
FileLoader *GameInfo::GetFileLoader() {
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
#include "ppsspp_config.h"
|
||||
#include "base/colorutil.h"
|
||||
#include "base/display.h"
|
||||
#include "base/timeutil.h"
|
||||
@ -857,8 +858,12 @@ void MainScreen::CreateViews() {
|
||||
gold->OnClick.Handle(this, &MainScreen::OnSupport);
|
||||
gold->SetIcon(I_ICONGOLD);
|
||||
#endif
|
||||
|
||||
#if !PPSSPP_PLATFORM(UWP)
|
||||
// Having an exit button is against UWP guidelines.
|
||||
rightColumnItems->Add(new Spacer(25.0));
|
||||
rightColumnItems->Add(new Choice(mm->T("Exit")))->OnClick.Handle(this, &MainScreen::OnExit);
|
||||
#endif
|
||||
|
||||
if (vertical) {
|
||||
root_ = new LinearLayout(ORIENT_VERTICAL);
|
||||
@ -972,6 +977,8 @@ UI::EventReturn MainScreen::OnLoadFile(UI::EventParams &e) {
|
||||
g_Config.Save();
|
||||
screenManager()->switchScreen(new EmuScreen(fileName.toStdString()));
|
||||
}
|
||||
#elif PPSSPP_PLATFORM(UWP)
|
||||
System_SendMessage("browse_file", "");
|
||||
#elif defined(USING_WIN_UI)
|
||||
MainWindow::BrowseAndBoot("");
|
||||
#endif
|
||||
|
64
UWP/App.cpp
64
UWP/App.cpp
@ -1,6 +1,10 @@
|
||||
#include "pch.h"
|
||||
#include "App.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "input/input_state.h"
|
||||
|
||||
#include <ppltasks.h>
|
||||
|
||||
using namespace UWP;
|
||||
@ -76,6 +80,14 @@ void App::SetWindow(CoreWindow^ window) {
|
||||
window->KeyDown += ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &App::OnKeyDown);
|
||||
window->KeyUp += ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &App::OnKeyUp);
|
||||
|
||||
window->PointerMoved += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerMoved);
|
||||
window->PointerEntered += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerEntered);
|
||||
window->PointerExited += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerExited);
|
||||
window->PointerPressed += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerPressed);
|
||||
window->PointerReleased += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerReleased);
|
||||
window->PointerCaptureLost += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerCaptureLost);
|
||||
window->PointerWheelChanged += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerWheelChanged);
|
||||
|
||||
m_deviceResources->SetWindow(window);
|
||||
}
|
||||
|
||||
@ -87,11 +99,53 @@ void App::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyE
|
||||
m_main->OnKeyUp(args->KeyStatus.ScanCode, args->VirtualKey);
|
||||
}
|
||||
|
||||
void App::OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {
|
||||
int pointerId = args->CurrentPoint->PointerId;
|
||||
float X = args->CurrentPoint->Position.X;
|
||||
float Y = args->CurrentPoint->Position.Y;
|
||||
int64_t timestamp = args->CurrentPoint->Timestamp;
|
||||
m_main->OnTouchEvent(TOUCH_MOVE, pointerId, X, Y, timestamp);
|
||||
}
|
||||
|
||||
void App::OnPointerEntered(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {
|
||||
}
|
||||
|
||||
void App::OnPointerExited(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {
|
||||
}
|
||||
|
||||
void App::OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {
|
||||
int pointerId = args->CurrentPoint->PointerId;
|
||||
float X = args->CurrentPoint->Position.X;
|
||||
float Y = args->CurrentPoint->Position.Y;
|
||||
int64_t timestamp = args->CurrentPoint->Timestamp;
|
||||
m_main->OnTouchEvent(TOUCH_DOWN|TOUCH_MOVE, pointerId, X, Y, timestamp);
|
||||
sender->SetPointerCapture();
|
||||
}
|
||||
|
||||
void App::OnPointerReleased(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {
|
||||
int pointerId = args->CurrentPoint->PointerId;
|
||||
float X = args->CurrentPoint->Position.X;
|
||||
float Y = args->CurrentPoint->Position.Y;
|
||||
int64_t timestamp = args->CurrentPoint->Timestamp;
|
||||
m_main->OnTouchEvent(TOUCH_UP|TOUCH_MOVE, pointerId, X, Y, timestamp);
|
||||
sender->ReleasePointerCapture();
|
||||
}
|
||||
|
||||
void App::OnPointerCaptureLost(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {
|
||||
}
|
||||
|
||||
void App::OnPointerWheelChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {
|
||||
int pointerId = args->CurrentPoint->PointerId;
|
||||
float X = args->CurrentPoint->Position.X;
|
||||
float Y = args->CurrentPoint->Position.Y;
|
||||
int64_t timestamp = args->CurrentPoint->Timestamp;
|
||||
m_main->OnTouchEvent(TOUCH_WHEEL, pointerId, X, Y, timestamp);
|
||||
}
|
||||
|
||||
// Initializes scene resources, or loads a previously saved app state.
|
||||
void App::Load(Platform::String^ entryPoint) {
|
||||
if (m_main == nullptr) {
|
||||
m_main = std::unique_ptr<PPSSPP_UWPMain>(new PPSSPP_UWPMain(m_deviceResources));
|
||||
m_main = std::unique_ptr<PPSSPP_UWPMain>(new PPSSPP_UWPMain(this, m_deviceResources));
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,10 +184,7 @@ void App::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args) {
|
||||
SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
|
||||
|
||||
create_task([this, deferral]() {
|
||||
m_deviceResources->Trim();
|
||||
|
||||
// Insert your code here.
|
||||
|
||||
m_deviceResources->Trim();
|
||||
deferral->Complete();
|
||||
});
|
||||
}
|
||||
@ -148,8 +199,7 @@ void App::OnResuming(Platform::Object^ sender, Platform::Object^ args) {
|
||||
|
||||
// Window event handlers.
|
||||
|
||||
void App::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
|
||||
{
|
||||
void App::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args) {
|
||||
m_deviceResources->SetLogicalSize(Size(sender->Bounds.Width, sender->Bounds.Height));
|
||||
m_main->CreateWindowSizeDependentResources();
|
||||
}
|
||||
|
11
UWP/App.h
11
UWP/App.h
@ -7,8 +7,7 @@
|
||||
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
|
||||
{
|
||||
ref class App sealed : public Windows::ApplicationModel::Core::IFrameworkView {
|
||||
public:
|
||||
App();
|
||||
|
||||
@ -39,6 +38,14 @@ namespace UWP
|
||||
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 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);
|
||||
|
||||
private:
|
||||
std::shared_ptr<DX::DeviceResources> m_deviceResources;
|
||||
std::unique_ptr<PPSSPP_UWPMain> m_main;
|
||||
|
@ -288,7 +288,6 @@
|
||||
<ClInclude Include="..\..\ext\native\ui\ui_screen.h" />
|
||||
<ClInclude Include="..\..\ext\native\ui\view.h" />
|
||||
<ClInclude Include="..\..\ext\native\ui\viewgroup.h" />
|
||||
<ClInclude Include="..\..\ext\native\ui\virtual_input.h" />
|
||||
<ClInclude Include="..\..\ext\native\util\const_map.h" />
|
||||
<ClInclude Include="..\..\ext\native\util\hash\hash.h" />
|
||||
<ClInclude Include="..\..\ext\native\util\random\rng.h" />
|
||||
@ -969,7 +968,6 @@
|
||||
<ClCompile Include="..\..\ext\native\ui\ui_screen.cpp" />
|
||||
<ClCompile Include="..\..\ext\native\ui\view.cpp" />
|
||||
<ClCompile Include="..\..\ext\native\ui\viewgroup.cpp" />
|
||||
<ClCompile Include="..\..\ext\native\ui\virtual_input.cpp" />
|
||||
<ClCompile Include="..\..\ext\native\util\hash\hash.cpp" />
|
||||
<ClCompile Include="..\..\ext\native\util\text\parsers.cpp" />
|
||||
<ClCompile Include="..\..\ext\native\util\text\utf8.cpp" />
|
||||
|
@ -163,9 +163,6 @@
|
||||
<ClCompile Include="..\..\ext\native\ui\viewgroup.cpp">
|
||||
<Filter>ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\ext\native\ui\virtual_input.cpp">
|
||||
<Filter>ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\ext\native\math\lin\matrix4x4.cpp">
|
||||
<Filter>math</Filter>
|
||||
</ClCompile>
|
||||
@ -608,9 +605,6 @@
|
||||
<ClInclude Include="..\..\ext\native\ui\viewgroup.h">
|
||||
<Filter>ui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\ext\native\ui\virtual_input.h">
|
||||
<Filter>ui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\ext\native\math\lin\matrix4x4.h">
|
||||
<Filter>math</Filter>
|
||||
</ClInclude>
|
||||
|
@ -3,10 +3,12 @@
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Common/LogManager.h"
|
||||
#include "Core/System.h"
|
||||
#include "Core/Loaders.h"
|
||||
#include "base/NativeApp.h"
|
||||
#include "base/timeutil.h"
|
||||
#include "input/input_state.h"
|
||||
@ -18,22 +20,32 @@
|
||||
#include "Common/DirectXHelper.h"
|
||||
#include "NKCodeFromWindowsSystem.h"
|
||||
#include "XAudioSoundStream.h"
|
||||
#include "UWPHost.h"
|
||||
#include "StorageFileLoader.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 Concurrency;
|
||||
|
||||
namespace UWP {
|
||||
// UGLY!
|
||||
PPSSPP_UWPMain *g_main;
|
||||
|
||||
// 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(const std::shared_ptr<DX::DeviceResources>& deviceResources) :
|
||||
PPSSPP_UWPMain::PPSSPP_UWPMain(App ^app, const std::shared_ptr<DX::DeviceResources>& deviceResources) :
|
||||
app_(app),
|
||||
m_deviceResources(deviceResources)
|
||||
{
|
||||
g_main = this;
|
||||
|
||||
host = new UWPHost();
|
||||
// Register to be notified if the Device is lost or recreated
|
||||
m_deviceResources->RegisterDeviceNotify(this);
|
||||
|
||||
@ -65,7 +77,6 @@ PPSSPP_UWPMain::PPSSPP_UWPMain(const std::shared_ptr<DX::DeviceResources>& devic
|
||||
langRegion = "en_US";
|
||||
}
|
||||
|
||||
|
||||
char configFilename[MAX_PATH] = { 0 };
|
||||
char controlsConfigFilename[MAX_PATH] = { 0 };
|
||||
|
||||
@ -83,6 +94,7 @@ PPSSPP_UWPMain::PPSSPP_UWPMain(const std::shared_ptr<DX::DeviceResources>& devic
|
||||
bool debugLogLevel = false;
|
||||
|
||||
g_Config.iGPUBackend = GPU_BACKEND_DIRECT3D11;
|
||||
g_Config.bSeparateCPUThread = false;
|
||||
|
||||
#ifdef _DEBUG
|
||||
g_Config.bEnableLogging = true;
|
||||
@ -124,8 +136,7 @@ void PPSSPP_UWPMain::CreateWindowSizeDependentResources() {
|
||||
// Renders the current frame according to the current application state.
|
||||
// Returns true if the frame was rendered and is ready to be displayed.
|
||||
bool PPSSPP_UWPMain::Render() {
|
||||
InputState input{};
|
||||
NativeUpdate(input);
|
||||
NativeUpdate();
|
||||
|
||||
time_update();
|
||||
auto context = m_deviceResources->GetD3DDeviceContext();
|
||||
@ -186,6 +197,40 @@ void PPSSPP_UWPMain::OnKeyUp(int scanCode, Windows::System::VirtualKey virtualKe
|
||||
}
|
||||
}
|
||||
|
||||
void PPSSPP_UWPMain::OnTouchEvent(int touchEvent, int touchId, float x, float y, double timestamp) {
|
||||
// It appears that Windows' touchIds start from 1. Let's fix that.
|
||||
touchId--;
|
||||
|
||||
TouchInput input{};
|
||||
input.id = touchId;
|
||||
input.x = x;
|
||||
input.y = y;
|
||||
input.flags = touchEvent;
|
||||
input.timestamp = timestamp;
|
||||
NativeTouch(input);
|
||||
|
||||
KeyInput key{};
|
||||
key.deviceId = DEVICE_ID_MOUSE;
|
||||
if (touchEvent & TOUCH_DOWN) {
|
||||
key.keyCode = NKCODE_EXT_MOUSEBUTTON_1;
|
||||
key.flags = KEY_DOWN;
|
||||
NativeKey(key);
|
||||
}
|
||||
if (touchEvent & TOUCH_UP) {
|
||||
key.keyCode = NKCODE_EXT_MOUSEBUTTON_1;
|
||||
key.flags = KEY_UP;
|
||||
NativeKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
void PPSSPP_UWPMain::OnSuspend() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void PPSSPP_UWPMain::LoadStorageFile(StorageFile ^file) {
|
||||
OverrideNextLoader(new StorageFileLoader(file), FILETYPE_PSP_ISO);
|
||||
NativeMessageReceived("boot", "override://");
|
||||
}
|
||||
|
||||
UWPGraphicsContext::UWPGraphicsContext(std::shared_ptr<DX::DeviceResources> resources) {
|
||||
draw_ = Draw::T3DCreateD3D11Context(resources->GetD3DDevice(), resources->GetD3DDeviceContext(), resources->GetD3DDevice(), resources->GetD3DDeviceContext(), 0);
|
||||
@ -199,16 +244,20 @@ void UWPGraphicsContext::SwapInterval(int interval) {
|
||||
|
||||
}
|
||||
|
||||
} // namespace UWP
|
||||
|
||||
std::string System_GetProperty(SystemProperty prop) {
|
||||
static bool hasCheckedGPUDriverVersion = false;
|
||||
switch (prop) {
|
||||
case SYSPROP_NAME:
|
||||
return "Windows 10";
|
||||
return "Windows 10 Universal";
|
||||
case SYSPROP_LANGREGION:
|
||||
return "en_US"; // TODO UWP
|
||||
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();
|
||||
if (view) {
|
||||
string text = await view->GetTextAsync();
|
||||
}
|
||||
*/
|
||||
return "";
|
||||
case SYSPROP_GPUDRIVER_VERSION:
|
||||
return "";
|
||||
@ -225,24 +274,55 @@ int System_GetPropertyInt(SystemProperty prop) {
|
||||
return 60000;
|
||||
case SYSPROP_DEVICE_TYPE:
|
||||
return DEVICE_TYPE_DESKTOP;
|
||||
case SYSPROP_HAS_FILE_BROWSER:
|
||||
return true;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void System_SendMessage(const char *command, const char *parameter) {
|
||||
// TODO UWP
|
||||
using namespace concurrency;
|
||||
|
||||
if (!strcmp(command, "finish")) {
|
||||
// Not really supposed to support this under UWP.
|
||||
} else if (!strcmp(command, "browse_file")) {
|
||||
auto picker = ref new Windows::Storage::Pickers::FileOpenPicker();
|
||||
picker->ViewMode = Pickers::PickerViewMode::List;
|
||||
picker->FileTypeFilter->Append(".cso");
|
||||
picker->FileTypeFilter->Append(".iso");
|
||||
picker->FileTypeFilter->Append(".bin");
|
||||
|
||||
create_task(picker->PickSingleFileAsync()).then([](StorageFile ^file){
|
||||
g_main->LoadStorageFile(file);
|
||||
/*
|
||||
std::thread([file] {
|
||||
create_task(file->OpenReadAsync()).then([](IRandomAccessStreamWithContentType^ imgStream) {
|
||||
imgStream->Seek(0);
|
||||
IBuffer ^buffer = ref new Streams::Buffer(2048);
|
||||
auto readTask = create_task(imgStream->ReadAsync(buffer, 2048, InputStreamOptions::None));
|
||||
readTask.wait();
|
||||
});
|
||||
}).detach();
|
||||
*/
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void LaunchBrowser(const char *url) {
|
||||
// TODO UWP
|
||||
Platform::String ^pstr = ref new Platform::String(ConvertUTF8ToWString(url).c_str());
|
||||
auto uri = ref new Windows::Foundation::Uri(pstr);
|
||||
|
||||
create_task(Windows::System::Launcher::LaunchUriAsync(uri)).then([](bool b) {});
|
||||
}
|
||||
|
||||
void Vibrate(int length_ms) {
|
||||
// Ignore on PC
|
||||
// TODO: Use Windows::Phone::Devices::Notification where available
|
||||
}
|
||||
|
||||
void System_AskForPermission(SystemPermission permission) {}
|
||||
void System_AskForPermission(SystemPermission permission) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
PermissionStatus System_GetPermissionStatus(SystemPermission permission) {
|
||||
return PERMISSION_STATUS_GRANTED;
|
||||
|
@ -1,13 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "thin3d/thin3d.h"
|
||||
#include "input/input_state.h"
|
||||
|
||||
#include "Common/GraphicsContext.h"
|
||||
#include "Common/DeviceResources.h"
|
||||
|
||||
// Renders Direct2D and 3D content on the screen.
|
||||
namespace UWP {
|
||||
|
||||
|
||||
ref class App;
|
||||
|
||||
class UWPGraphicsContext : public GraphicsContext {
|
||||
public:
|
||||
UWPGraphicsContext(std::shared_ptr<DX::DeviceResources> resources);
|
||||
@ -28,7 +33,7 @@ private:
|
||||
class PPSSPP_UWPMain : public DX::IDeviceNotify
|
||||
{
|
||||
public:
|
||||
PPSSPP_UWPMain(const std::shared_ptr<DX::DeviceResources>& deviceResources);
|
||||
PPSSPP_UWPMain(App ^app, const std::shared_ptr<DX::DeviceResources>& deviceResources);
|
||||
~PPSSPP_UWPMain();
|
||||
void CreateWindowSizeDependentResources();
|
||||
bool Render();
|
||||
@ -42,7 +47,17 @@ public:
|
||||
void OnKeyDown(int scanCode, Windows::System::VirtualKey virtualKey, int repeatCount);
|
||||
void OnKeyUp(int scanCode, Windows::System::VirtualKey virtualKey);
|
||||
|
||||
void OnTouchEvent(int touchEvent, int touchId, float x, float y, double timestamp);
|
||||
|
||||
// Save state fast if we can!
|
||||
void OnSuspend();
|
||||
void Close();
|
||||
|
||||
void LoadStorageFile(Windows::Storage::StorageFile ^file);
|
||||
|
||||
private:
|
||||
App ^app_;
|
||||
|
||||
// Cached pointer to device resources.
|
||||
std::shared_ptr<DX::DeviceResources> m_deviceResources;
|
||||
|
||||
|
91
UWP/StorageFileLoader.cpp
Normal file
91
UWP/StorageFileLoader.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
#include "pch.h"
|
||||
#include "ppltasks.h"
|
||||
#include "StorageFileLoader.h"
|
||||
|
||||
|
||||
using namespace Concurrency;
|
||||
using namespace Windows::Storage;
|
||||
using namespace Windows::Storage::Streams;
|
||||
|
||||
StorageFileLoader::StorageFileLoader(Windows::Storage::StorageFile ^file) {
|
||||
create_task(file->OpenReadAsync()).then([this](IRandomAccessStreamWithContentType ^stream) {
|
||||
stream_ = stream;
|
||||
active_ = true;
|
||||
thread_ = std::thread([this]() { this->threadfunc(); });
|
||||
});
|
||||
}
|
||||
|
||||
StorageFileLoader::~StorageFileLoader() {
|
||||
active_ = false;
|
||||
thread_.join();
|
||||
}
|
||||
|
||||
void StorageFileLoader::threadfunc() {
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
while (active_) {
|
||||
cond_.wait(lock);
|
||||
std::unique_lock<std::mutex> lock(mutexResponse_);
|
||||
while (operations_.size()) {
|
||||
Operation op = operations_.front();
|
||||
operations_.pop();
|
||||
|
||||
switch (op.type) {
|
||||
case OpType::READ: {
|
||||
op.buffer = ref new Streams::Buffer(op.size);
|
||||
auto task = create_task(stream_->ReadAsync(op.buffer, op.size, Streams::InputStreamOptions::None));
|
||||
task.wait();
|
||||
break;
|
||||
responses_.push(op);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// OK, done with all operations.
|
||||
condResponse_.notify_one();
|
||||
}
|
||||
}
|
||||
|
||||
bool StorageFileLoader::Exists() {
|
||||
return true;
|
||||
}
|
||||
bool StorageFileLoader::ExistsFast() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StorageFileLoader::IsDirectory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
s64 StorageFileLoader::FileSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string StorageFileLoader::Path() const { return ""; }
|
||||
|
||||
std::string StorageFileLoader::Extension() { return ""; }
|
||||
|
||||
void StorageFileLoader::Seek(s64 absolutePos) {
|
||||
seekPos_ = absolutePos;
|
||||
}
|
||||
|
||||
size_t StorageFileLoader::Read(size_t bytes, size_t count, void *data, Flags flags) {
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
operations_.push(Operation{ OpType::READ, seekPos_, (int64_t)(bytes * count) });
|
||||
cond_.notify_one();
|
||||
}
|
||||
// OK, now wait for response...
|
||||
{
|
||||
std::unique_lock<std::mutex> responseLock(mutexResponse_);
|
||||
condResponse_.wait(responseLock);
|
||||
Operation resp = responses_.front();
|
||||
responses_.pop();
|
||||
// memcpy(data, bytes * count, )
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t StorageFileLoader::ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags) {
|
||||
return 0;
|
||||
}
|
56
UWP/StorageFileLoader.h
Normal file
56
UWP/StorageFileLoader.h
Normal file
@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <queue>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/Loaders.h"
|
||||
|
||||
class StorageFileLoader : public FileLoader {
|
||||
public:
|
||||
StorageFileLoader(Windows::Storage::StorageFile ^file);
|
||||
~StorageFileLoader();
|
||||
|
||||
bool Exists() override;
|
||||
bool ExistsFast() override;
|
||||
|
||||
bool IsDirectory() override;
|
||||
s64 FileSize() override;
|
||||
std::string Path() const override;
|
||||
std::string Extension() override;
|
||||
void Seek(s64 absolutePos) override;
|
||||
size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE);
|
||||
size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE);
|
||||
|
||||
private:
|
||||
void threadfunc();
|
||||
|
||||
enum class OpType {
|
||||
READ,
|
||||
};
|
||||
|
||||
struct Operation {
|
||||
OpType type;
|
||||
int64_t offset;
|
||||
int64_t size;
|
||||
Windows::Storage::Streams::Buffer ^buffer;
|
||||
};
|
||||
|
||||
bool active_ = false;
|
||||
std::thread thread_;
|
||||
Windows::Storage::Streams::IRandomAccessStreamWithContentType ^stream_;
|
||||
std::condition_variable cond_;
|
||||
std::mutex mutex_;
|
||||
|
||||
std::condition_variable condResponse_;
|
||||
std::mutex mutexResponse_;
|
||||
|
||||
std::queue<Operation> operations_;
|
||||
int64_t seekPos_ = 0;
|
||||
|
||||
std::queue<Operation> responses_;
|
||||
};
|
@ -116,6 +116,7 @@
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
@ -130,6 +131,7 @@
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
@ -144,6 +146,7 @@
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
@ -158,6 +161,7 @@
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
@ -172,6 +176,7 @@
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
@ -186,6 +191,7 @@
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
@ -222,12 +228,15 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\ppsspp_config.h" />
|
||||
<ClInclude Include="..\Windows\XinputDevice.h" />
|
||||
<ClInclude Include="App.h" />
|
||||
<ClInclude Include="Common\DeviceResources.h" />
|
||||
<ClInclude Include="NKCodeFromWindowsSystem.h" />
|
||||
<ClInclude Include="PPSSPP_UWPMain.h" />
|
||||
<ClInclude Include="Common\DirectXHelper.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="StorageFileLoader.h" />
|
||||
<ClInclude Include="UWPHost.h" />
|
||||
<ClInclude Include="XAudioSoundStream.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -239,6 +248,7 @@
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Windows\XinputDevice.cpp" />
|
||||
<ClCompile Include="App.cpp" />
|
||||
<ClCompile Include="Common\DeviceResources.cpp" />
|
||||
<ClCompile Include="NKCodeFromWindowsSystem.cpp" />
|
||||
@ -251,6 +261,8 @@
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="StorageFileLoader.cpp" />
|
||||
<ClCompile Include="UWPHost.cpp" />
|
||||
<ClCompile Include="XAudioSoundStream.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -46,6 +46,9 @@
|
||||
<ClCompile Include="XAudioSoundStream.cpp" />
|
||||
<ClCompile Include="PPSSPP_UWPMain.cpp" />
|
||||
<ClCompile Include="NKCodeFromWindowsSystem.cpp" />
|
||||
<ClCompile Include="StorageFileLoader.cpp" />
|
||||
<ClCompile Include="UWPHost.cpp" />
|
||||
<ClCompile Include="..\Windows\XinputDevice.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="App.h" />
|
||||
@ -54,6 +57,9 @@
|
||||
<ClInclude Include="XAudioSoundStream.h" />
|
||||
<ClInclude Include="PPSSPP_UWPMain.h" />
|
||||
<ClInclude Include="NKCodeFromWindowsSystem.h" />
|
||||
<ClInclude Include="StorageFileLoader.h" />
|
||||
<ClInclude Include="UWPHost.h" />
|
||||
<ClInclude Include="..\Windows\XinputDevice.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="Assets\StoreLogo.png">
|
||||
|
189
UWP/UWPHost.cpp
Normal file
189
UWP/UWPHost.cpp
Normal file
@ -0,0 +1,189 @@
|
||||
// Copyright (c) 2012- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "ppsspp_config.h"
|
||||
|
||||
#include "file/file_util.h"
|
||||
#include "base/NativeApp.h"
|
||||
#include "input/input_state.h"
|
||||
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/CoreParameter.h"
|
||||
#include "Core/System.h"
|
||||
#include "Core/Debugger/SymbolMap.h"
|
||||
|
||||
#include "UI/OnScreenDisplay.h"
|
||||
|
||||
#include "Windows/XinputDevice.h"
|
||||
#include "Windows/DSoundStream.h"
|
||||
|
||||
#include "UWP/XAudioSoundStream.h"
|
||||
#include "UWP/UWPHost.h"
|
||||
|
||||
UWPHost::UWPHost() {
|
||||
|
||||
// add first XInput device to respond
|
||||
input.push_back(std::shared_ptr<InputDevice>(new XinputDevice()));
|
||||
}
|
||||
|
||||
UWPHost::~UWPHost() {
|
||||
|
||||
}
|
||||
|
||||
void UWPHost::SetConsolePosition() {
|
||||
}
|
||||
|
||||
void UWPHost::UpdateConsolePosition() {
|
||||
}
|
||||
|
||||
bool UWPHost::InitGraphics(std::string *error_message, GraphicsContext **ctx) {
|
||||
// Done elsewhere
|
||||
return true;
|
||||
}
|
||||
|
||||
void UWPHost::ShutdownGraphics() {
|
||||
// Done elsewhere
|
||||
}
|
||||
|
||||
void UWPHost::SetWindowTitle(const char *message) {
|
||||
// Should really be done differently
|
||||
}
|
||||
|
||||
void UWPHost::InitSound() {
|
||||
}
|
||||
|
||||
void UWPHost::UpdateSound() {
|
||||
}
|
||||
|
||||
void UWPHost::ShutdownSound() {
|
||||
}
|
||||
|
||||
void UWPHost::UpdateUI() {
|
||||
}
|
||||
|
||||
void UWPHost::UpdateMemView() {
|
||||
}
|
||||
|
||||
void UWPHost::UpdateDisassembly() {
|
||||
}
|
||||
|
||||
void UWPHost::SetDebugMode(bool mode) {
|
||||
}
|
||||
|
||||
void UWPHost::PollControllers() {
|
||||
bool doPad = true;
|
||||
for (auto iter = this->input.begin(); iter != this->input.end(); iter++)
|
||||
{
|
||||
auto device = *iter;
|
||||
if (!doPad && device->IsPad())
|
||||
continue;
|
||||
if (device->UpdateState() == InputDevice::UPDATESTATE_SKIP_PAD)
|
||||
doPad = false;
|
||||
}
|
||||
|
||||
/*
|
||||
g_mouseDeltaX *= 0.9f;
|
||||
g_mouseDeltaY *= 0.9f;
|
||||
|
||||
// TODO: Tweak!
|
||||
float scaleFactor = g_dpi_scale * 0.01f;
|
||||
|
||||
float mx = std::max(-1.0f, std::min(1.0f, g_mouseDeltaX * scaleFactor));
|
||||
float my = std::max(-1.0f, std::min(1.0f, g_mouseDeltaY * scaleFactor));
|
||||
AxisInput axisX, axisY;
|
||||
axisX.axisId = JOYSTICK_AXIS_MOUSE_REL_X;
|
||||
axisX.deviceId = DEVICE_ID_MOUSE;
|
||||
axisX.value = mx;
|
||||
axisY.axisId = JOYSTICK_AXIS_MOUSE_REL_Y;
|
||||
axisY.deviceId = DEVICE_ID_MOUSE;
|
||||
axisY.value = my;
|
||||
*/
|
||||
}
|
||||
|
||||
void UWPHost::BootDone() {
|
||||
g_symbolMap->SortSymbols();
|
||||
|
||||
SetDebugMode(false);
|
||||
Core_EnableStepping(false);
|
||||
}
|
||||
|
||||
static std::string SymbolMapFilename(const char *currentFilename, char* ext) {
|
||||
FileInfo info;
|
||||
|
||||
std::string result = currentFilename;
|
||||
|
||||
// can't fail, definitely exists if it gets this far
|
||||
getFileInfo(currentFilename, &info);
|
||||
if (info.isDirectory) {
|
||||
#ifdef _WIN32
|
||||
char* slash = "\\";
|
||||
#else
|
||||
char* slash = "/";
|
||||
#endif
|
||||
if (!endsWith(result, slash))
|
||||
result += slash;
|
||||
|
||||
return result + ".ppsspp-symbols" + ext;
|
||||
} else {
|
||||
size_t dot = result.rfind('.');
|
||||
if (dot == result.npos)
|
||||
return result + ext;
|
||||
|
||||
result.replace(dot, result.npos, ext);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
bool UWPHost::AttemptLoadSymbolMap() {
|
||||
bool result1 = g_symbolMap->LoadSymbolMap(SymbolMapFilename(PSP_CoreParameter().fileToStart.c_str(), ".ppmap").c_str());
|
||||
// Load the old-style map file.
|
||||
if (!result1)
|
||||
result1 = g_symbolMap->LoadSymbolMap(SymbolMapFilename(PSP_CoreParameter().fileToStart.c_str(), ".map").c_str());
|
||||
bool result2 = g_symbolMap->LoadNocashSym(SymbolMapFilename(PSP_CoreParameter().fileToStart.c_str(), ".sym").c_str());
|
||||
return result1 || result2;
|
||||
}
|
||||
|
||||
void UWPHost::SaveSymbolMap() {
|
||||
g_symbolMap->SaveSymbolMap(SymbolMapFilename(PSP_CoreParameter().fileToStart.c_str(), ".ppmap").c_str());
|
||||
}
|
||||
|
||||
bool UWPHost::IsDebuggingEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UWPHost::CanCreateShortcut() {
|
||||
return false; // Turn on when below function fixed
|
||||
}
|
||||
|
||||
bool UWPHost::CreateDesktopShortcut(std::string argumentPath, std::string gameTitle) {
|
||||
// TODO: not working correctly
|
||||
return false;
|
||||
}
|
||||
|
||||
void UWPHost::GoFullscreen(bool viewFullscreen) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void UWPHost::ToggleDebugConsoleVisibility() {
|
||||
// N/A
|
||||
}
|
||||
|
||||
void UWPHost::NotifyUserMessage(const std::string &message, float duration, u32 color, const char *id) {
|
||||
osm.Show(message, duration, color, -1, true, id);
|
||||
}
|
56
UWP/UWPHost.h
Normal file
56
UWP/UWPHost.h
Normal file
@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core/Host.h"
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
#include "Windows/InputDevice.h"
|
||||
|
||||
class UWPHost : public Host {
|
||||
public:
|
||||
UWPHost();
|
||||
~UWPHost();
|
||||
|
||||
void UpdateMemView() override;
|
||||
void UpdateDisassembly() override;
|
||||
void UpdateUI() override;
|
||||
void SetDebugMode(bool mode) override;
|
||||
|
||||
// If returns false, will return a null context
|
||||
bool InitGraphics(std::string *error_message, GraphicsContext **ctx) override;
|
||||
void PollControllers() override;
|
||||
void ShutdownGraphics() override;
|
||||
|
||||
void InitSound() override;
|
||||
void UpdateSound() override;
|
||||
void ShutdownSound() override;
|
||||
|
||||
bool IsDebuggingEnabled() override;
|
||||
void BootDone() override;
|
||||
bool AttemptLoadSymbolMap() override;
|
||||
void SaveSymbolMap() override;
|
||||
void SetWindowTitle(const char *message) override;
|
||||
|
||||
bool GPUDebuggingActive() override { return false; }
|
||||
void GPUNotifyCommand(u32 pc) override {}
|
||||
void GPUNotifyDisplay(u32 framebuf, u32 stride, int format) override {}
|
||||
void GPUNotifyDraw() override {}
|
||||
void GPUNotifyTextureAttachment(u32 addr) override {}
|
||||
void ToggleDebugConsoleVisibility() override;
|
||||
|
||||
bool CanCreateShortcut() override;
|
||||
bool CreateDesktopShortcut(std::string argumentPath, std::string title) override;
|
||||
|
||||
void NotifyUserMessage(const std::string &message, float duration = 1.0f, u32 color = 0x00FFFFFF, const char *id = nullptr) override;
|
||||
|
||||
void GoFullscreen(bool) override;
|
||||
|
||||
GraphicsContext *GetGraphicsContext() { return nullptr; }
|
||||
|
||||
private:
|
||||
void SetConsolePosition();
|
||||
void UpdateConsolePosition();
|
||||
|
||||
std::list<std::shared_ptr<InputDevice>> input;
|
||||
};
|
@ -1,5 +1,3 @@
|
||||
// NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003.
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "base/timeutil.h"
|
||||
@ -26,6 +24,7 @@
|
||||
#include <tchar.h>
|
||||
#include <process.h>
|
||||
#include <intrin.h>
|
||||
|
||||
#pragma intrinsic(_InterlockedExchange)
|
||||
|
||||
static std::mutex emuThreadLock;
|
||||
|
@ -1,4 +1,6 @@
|
||||
#include <limits.h>
|
||||
#include "ppsspp_config.h"
|
||||
|
||||
#include <climits>
|
||||
#include <algorithm>
|
||||
|
||||
#include "base/NativeApp.h"
|
||||
@ -11,6 +13,8 @@
|
||||
|
||||
// Utilities to dynamically load XInput. Adapted from SDL.
|
||||
|
||||
#if !PPSSPP_PLATFORM(UWP)
|
||||
|
||||
typedef DWORD (WINAPI *XInputGetState_t) (DWORD dwUserIndex, XINPUT_STATE* pState);
|
||||
typedef DWORD (WINAPI *XInputSetState_t) (DWORD dwUserIndex, XINPUT_VIBRATION* pVibration);
|
||||
typedef DWORD (WINAPI *XInputGetCapabilities_t) (DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPABILITIES* pCapabilities);
|
||||
@ -66,6 +70,14 @@ static void UnloadXInputDLL() {
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
static int LoadXInputDLL() { return 0; }
|
||||
static void UnloadXInputDLL() {}
|
||||
#define PPSSPP_XInputGetState XInputGetState
|
||||
#define PPSSPP_XInputSetState XInputSetState
|
||||
#define PPSSPP_XInputGetCapabilities XInputGetCapabilities
|
||||
#endif
|
||||
|
||||
#ifndef XUSER_MAX_COUNT
|
||||
#define XUSER_MAX_COUNT 4
|
||||
#endif
|
||||
@ -201,8 +213,10 @@ bool NormalizedDeadzoneDiffers(u8 x1, u8 x2, const u8 thresh) {
|
||||
}
|
||||
|
||||
int XinputDevice::UpdateState() {
|
||||
#if !PPSSPP_PLATFORM(UWP)
|
||||
if (!s_pXInputDLL)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
bool anySuccess = false;
|
||||
for (int i = 0; i < XUSER_MAX_COUNT; i++) {
|
||||
|
@ -212,6 +212,8 @@ int System_GetPropertyInt(SystemProperty prop) {
|
||||
return DEVICE_TYPE_DESKTOP;
|
||||
case SYSPROP_DISPLAY_DPI:
|
||||
return ScreenDPI();
|
||||
case SYSPROP_HAS_FILE_BROWSER:
|
||||
return true;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
@ -152,6 +152,8 @@ enum SystemProperty {
|
||||
SYSPROP_CLIPBOARD_TEXT,
|
||||
SYSPROP_GPUDRIVER_VERSION,
|
||||
|
||||
SYSPROP_HAS_FILE_BROWSER,
|
||||
|
||||
// Available as Int:
|
||||
SYSPROP_SYSTEMVERSION,
|
||||
SYSPROP_DISPLAY_XRES,
|
||||
|
@ -111,9 +111,7 @@ int time_now_ms() {
|
||||
|
||||
void sleep_ms(int ms) {
|
||||
#ifdef _WIN32
|
||||
#ifndef METRO
|
||||
Sleep(ms);
|
||||
#endif
|
||||
#else
|
||||
usleep(ms * 1000);
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user