UWP: Hook up basic keyboard support

This commit is contained in:
Henrik Rydgard 2017-02-27 11:00:57 +01:00 committed by Henrik Rydgård
parent 52cd3164ee
commit 86f4559748
10 changed files with 173 additions and 59 deletions

View File

@ -73,11 +73,21 @@ void App::SetWindow(CoreWindow^ window) {
DisplayInformation::DisplayContentsInvalidated +=
ref new TypedEventHandler<DisplayInformation^, Object^>(this, &App::OnDisplayContentsInvalidated);
// window->KeyDown += ref new TypedEventHandler<DisplayInformation, Object^>(this, &App::OnKeyDown);
window->KeyDown += ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &App::OnKeyDown);
window->KeyUp += ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &App::OnKeyUp);
m_deviceResources->SetWindow(window);
}
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::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) {
m_main->OnKeyUp(args->KeyStatus.ScanCode, args->VirtualKey);
}
// Initializes scene resources, or loads a previously saved app state.
void App::Load(Platform::String^ entryPoint) {
if (m_main == nullptr) {
@ -90,7 +100,6 @@ void App::Run() {
while (!m_windowClosed) {
if (m_windowVisible) {
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
m_main->Update();
if (m_main->Render()) {
m_deviceResources->Present();
}
@ -153,10 +162,6 @@ void App::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) {
m_windowClosed = true;
}
void App::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args) {
}
// DisplayInformation event handlers.
void App::OnDpiChanged(DisplayInformation^ sender, Object^ args) {

View File

@ -36,7 +36,8 @@ namespace UWP
void OnDisplayContentsInvalidated(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
// Input
void OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args);
void OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
void OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
private:
std::shared_ptr<DX::DeviceResources> m_deviceResources;

View File

@ -230,7 +230,6 @@ void DX::DeviceResources::CreateWindowSizeDependentResources()
m_d3dRenderTargetView = nullptr;
m_d2dContext->SetTarget(nullptr);
m_d2dTargetBitmap = nullptr;
m_d3dDepthStencilView = nullptr;
m_d3dContext->Flush1(D3D11_CONTEXT_TYPE_ALL, nullptr);
UpdateRenderTargetSize();
@ -381,34 +380,6 @@ void DX::DeviceResources::CreateWindowSizeDependentResources()
)
);
// Create a depth stencil view for use with 3D rendering if needed.
CD3D11_TEXTURE2D_DESC1 depthStencilDesc(
DXGI_FORMAT_D24_UNORM_S8_UINT,
lround(m_d3dRenderTargetSize.Width),
lround(m_d3dRenderTargetSize.Height),
1, // This depth stencil view has only one texture.
1, // Use a single mipmap level.
D3D11_BIND_DEPTH_STENCIL
);
ComPtr<ID3D11Texture2D1> depthStencil;
DX::ThrowIfFailed(
m_d3dDevice->CreateTexture2D1(
&depthStencilDesc,
nullptr,
&depthStencil
)
);
CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D);
DX::ThrowIfFailed(
m_d3dDevice->CreateDepthStencilView(
depthStencil.Get(),
&depthStencilViewDesc,
&m_d3dDepthStencilView
)
);
// Set the 3D rendering viewport to target the entire window.
m_screenViewport = CD3D11_VIEWPORT(
0.0f,
@ -632,9 +603,6 @@ void DX::DeviceResources::Present()
// overwritten. If dirty or scroll rects are used, this call should be removed.
m_d3dContext->DiscardView1(m_d3dRenderTargetView.Get(), nullptr, 0);
// Discard the contents of the depth stencil.
m_d3dContext->DiscardView1(m_d3dDepthStencilView.Get(), nullptr, 0);
// If the device was removed either by a disconnection or a driver upgrade, we
// must recreate all device resources.
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)

View File

@ -37,7 +37,6 @@ namespace DX
IDXGISwapChain3* GetSwapChain() const { return m_swapChain.Get(); }
D3D_FEATURE_LEVEL GetDeviceFeatureLevel() const { return m_d3dFeatureLevel; }
ID3D11RenderTargetView1* GetBackBufferRenderTargetView() const { return m_d3dRenderTargetView.Get(); }
ID3D11DepthStencilView* GetDepthStencilView() const { return m_d3dDepthStencilView.Get(); }
D3D11_VIEWPORT GetScreenViewport() const { return m_screenViewport; }
DirectX::XMFLOAT4X4 GetOrientationTransform3D() const { return m_orientationTransform3D; }
@ -64,7 +63,6 @@ namespace DX
// Direct3D rendering objects. Required for 3D.
Microsoft::WRL::ComPtr<ID3D11RenderTargetView1> m_d3dRenderTargetView;
Microsoft::WRL::ComPtr<ID3D11DepthStencilView> m_d3dDepthStencilView;
D3D11_VIEWPORT m_screenViewport;
// Direct2D drawing components.

View File

@ -0,0 +1,110 @@
#include "pch.h"
#include "NKCodeFromWindowsSystem.h"
using namespace Windows::System;
std::map<Windows::System::VirtualKey, int> virtualKeyCodeToNKCode{
{ VirtualKey::A, NKCODE_A },
{ VirtualKey::B, NKCODE_B },
{ VirtualKey::C, NKCODE_C },
{ VirtualKey::D, NKCODE_D },
{ VirtualKey::E, NKCODE_E },
{ VirtualKey::F, NKCODE_F },
{ VirtualKey::G, NKCODE_G },
{ VirtualKey::H, NKCODE_H },
{ VirtualKey::I, NKCODE_I },
{ VirtualKey::J, NKCODE_J },
{ VirtualKey::K, NKCODE_K },
{ VirtualKey::L, NKCODE_L },
{ VirtualKey::M, NKCODE_M },
{ VirtualKey::N, NKCODE_N },
{ VirtualKey::O, NKCODE_O },
{ VirtualKey::P, NKCODE_P },
{ VirtualKey::Q, NKCODE_Q },
{ VirtualKey::R, NKCODE_R },
{ VirtualKey::S, NKCODE_S },
{ VirtualKey::T, NKCODE_T },
{ VirtualKey::U, NKCODE_U },
{ VirtualKey::V, NKCODE_V },
{ VirtualKey::W, NKCODE_W },
{ VirtualKey::X, NKCODE_X },
{ VirtualKey::Y, NKCODE_Y },
{ VirtualKey::Z, NKCODE_Z },
{ VirtualKey::Number0, NKCODE_0 },
{ VirtualKey::Number1, NKCODE_1 },
{ VirtualKey::Number2, NKCODE_2 },
{ VirtualKey::Number3, NKCODE_3 },
{ VirtualKey::Number4, NKCODE_4 },
{ VirtualKey::Number5, NKCODE_5 },
{ VirtualKey::Number6, NKCODE_6 },
{ VirtualKey::Number7, NKCODE_7 },
{ VirtualKey::Number8, NKCODE_8 },
{ VirtualKey::Number9, NKCODE_9 },
{ VirtualKey::Decimal, NKCODE_PERIOD },
// { VirtualKey::Comma, NKCODE_COMMA },
{ VirtualKey::NumberPad0, NKCODE_NUMPAD_0 },
{ VirtualKey::NumberPad1, NKCODE_NUMPAD_1 },
{ VirtualKey::NumberPad2, NKCODE_NUMPAD_2 },
{ VirtualKey::NumberPad3, NKCODE_NUMPAD_3 },
{ VirtualKey::NumberPad4, NKCODE_NUMPAD_4 },
{ VirtualKey::NumberPad5, NKCODE_NUMPAD_5 },
{ VirtualKey::NumberPad6, NKCODE_NUMPAD_6 },
{ VirtualKey::NumberPad7, NKCODE_NUMPAD_7 },
{ VirtualKey::NumberPad8, NKCODE_NUMPAD_8 },
{ VirtualKey::NumberPad9, NKCODE_NUMPAD_9 },
{ VirtualKey::Decimal, NKCODE_NUMPAD_DOT },
{ VirtualKey::Divide, NKCODE_NUMPAD_DIVIDE },
{ VirtualKey::Multiply, NKCODE_NUMPAD_MULTIPLY },
{ VirtualKey::Subtract, NKCODE_NUMPAD_SUBTRACT },
{ VirtualKey::Add, NKCODE_NUMPAD_ADD },
{ VirtualKey::Separator, NKCODE_NUMPAD_COMMA },
{ VirtualKey::LeftControl, NKCODE_CTRL_LEFT },
{ VirtualKey::RightControl, NKCODE_CTRL_RIGHT },
{ VirtualKey::LeftShift, NKCODE_SHIFT_LEFT },
{ VirtualKey::RightShift, NKCODE_SHIFT_RIGHT },
//{ VK_LMENU, NKCODE_ALT_LEFT },
//{ VK_RMENU, NKCODE_ALT_RIGHT },
{ VirtualKey::GoBack, NKCODE_BACK },
{ VirtualKey::Space, NKCODE_SPACE },
{ VirtualKey::Escape, NKCODE_ESCAPE },
{ VirtualKey::Up, NKCODE_DPAD_UP },
{ VirtualKey::Insert, NKCODE_INSERT },
{ VirtualKey::Home, NKCODE_MOVE_HOME },
{ VirtualKey::PageUp, NKCODE_PAGE_UP },
{ VirtualKey::PageDown, NKCODE_PAGE_DOWN },
{ VirtualKey::Delete, NKCODE_FORWARD_DEL },
{ VirtualKey::End, NKCODE_MOVE_END },
{ VirtualKey::Tab, NKCODE_TAB },
{ VirtualKey::Down, NKCODE_DPAD_DOWN },
{ VirtualKey::Left, NKCODE_DPAD_LEFT },
{ VirtualKey::Right, NKCODE_DPAD_RIGHT },
{ VirtualKey::CapitalLock, NKCODE_CAPS_LOCK },
{ VirtualKey::Clear, NKCODE_CLEAR },
// { VirtualKey::, NKCODE_SYSRQ },
{ VirtualKey::Scroll, NKCODE_SCROLL_LOCK },
// { , NKCODE_SEMICOLON },
// { VK_OEM_2, NKCODE_SLASH },
// { VK_OEM_3, NKCODE_GRAVE },
// { VK_OEM_4, NKCODE_LEFT_BRACKET },
// { VK_OEM_5, NKCODE_BACKSLASH },
// { VK_OEM_6, NKCODE_RIGHT_BRACKET },
// { VK_OEM_7, NKCODE_APOSTROPHE },
{ VirtualKey::Enter, NKCODE_ENTER },
// { VK_APPS, NKCODE_MENU }, // Context menu key, let's call this "menu".
{ VirtualKey::Pause, NKCODE_BREAK },
{ VirtualKey::F1, NKCODE_F1 },
{ VirtualKey::F2, NKCODE_F2 },
{ VirtualKey::F3, NKCODE_F3 },
{ VirtualKey::F4, NKCODE_F4 },
{ VirtualKey::F5, NKCODE_F5 },
{ VirtualKey::F6, NKCODE_F6 },
{ VirtualKey::F7, NKCODE_F7 },
{ VirtualKey::F8, NKCODE_F8 },
{ VirtualKey::F9, NKCODE_F9 },
{ VirtualKey::F10, NKCODE_F10 },
{ VirtualKey::F11, NKCODE_F11 },
{ VirtualKey::F12, NKCODE_F12 },
//{ VK_OEM_102, NKCODE_EXT_PIPE },
//{ VK_LBUTTON, NKCODE_EXT_MOUSEBUTTON_1 },
//{ VK_RBUTTON, NKCODE_EXT_MOUSEBUTTON_2 },;
};

View File

@ -0,0 +1,7 @@
#pragma once
#include <map>
#include "input/keycodes.h"
extern std::map<Windows::System::VirtualKey, int> virtualKeyCodeToNKCode;

View File

@ -8,6 +8,7 @@
#include "Common/LogManager.h"
#include "Core/System.h"
#include "base/NativeApp.h"
#include "base/timeutil.h"
#include "input/input_state.h"
#include "file/vfs.h"
#include "file/zip_read.h"
@ -15,6 +16,7 @@
#include "base/display.h"
#include "util/text/utf8.h"
#include "Common/DirectXHelper.h"
#include "NKCodeFromWindowsSystem.h"
#include "XAudioSoundStream.h"
using namespace UWP;
@ -119,21 +121,18 @@ void PPSSPP_UWPMain::CreateWindowSizeDependentResources() {
NativeResized();
}
// Updates the application state once per frame.
void PPSSPP_UWPMain::Update() {
InputState input{};
NativeUpdate(input);
}
// 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);
time_update();
auto context = m_deviceResources->GetD3DDeviceContext();
// Reset the viewport to target the whole screen.
auto viewport = m_deviceResources->GetScreenViewport();
m_deviceResources->GetBackBufferRenderTargetView();
pixel_xres = viewport.Width;
pixel_yres = viewport.Height;
@ -147,13 +146,8 @@ bool PPSSPP_UWPMain::Render() {
context->RSSetViewports(1, &viewport);
// Reset render targets to the screen.
ID3D11RenderTargetView *const targets[1] = { m_deviceResources->GetBackBufferRenderTargetView() };
context->OMSetRenderTargets(1, targets, m_deviceResources->GetDepthStencilView());
ctx_->GetDrawContext()->BindBackbufferAsRenderTarget();
// Clear the back buffer and depth stencil view.
context->ClearRenderTargetView(m_deviceResources->GetBackBufferRenderTargetView(), DirectX::Colors::CornflowerBlue);
context->ClearDepthStencilView(m_deviceResources->GetDepthStencilView(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
NativeRender(ctx_.get());
return true;
}
@ -170,6 +164,29 @@ 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) {
auto iter = virtualKeyCodeToNKCode.find(virtualKey);
if (iter != virtualKeyCodeToNKCode.end()) {
KeyInput key{};
key.deviceId = DEVICE_ID_KEYBOARD;
key.keyCode = iter->second;
key.flags = KEY_DOWN | (repeatCount > 1 ? KEY_IS_REPEAT : 0);
NativeKey(key);
}
}
void PPSSPP_UWPMain::OnKeyUp(int scanCode, Windows::System::VirtualKey virtualKey) {
auto iter = virtualKeyCodeToNKCode.find(virtualKey);
if (iter != virtualKeyCodeToNKCode.end()) {
KeyInput key{};
key.deviceId = DEVICE_ID_KEYBOARD;
key.keyCode = iter->second;
key.flags = KEY_UP;
NativeKey(key);
}
}
UWPGraphicsContext::UWPGraphicsContext(std::shared_ptr<DX::DeviceResources> resources) {
draw_ = Draw::T3DCreateD3D11Context(resources->GetD3DDevice(), resources->GetD3DDeviceContext(), resources->GetD3DDevice(), resources->GetD3DDeviceContext(), 0);
}

View File

@ -31,13 +31,17 @@ public:
PPSSPP_UWPMain(const std::shared_ptr<DX::DeviceResources>& deviceResources);
~PPSSPP_UWPMain();
void CreateWindowSizeDependentResources();
void Update();
bool Render();
// IDeviceNotify
virtual void OnDeviceLost();
virtual void OnDeviceRestored();
// 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);
private:
// Cached pointer to device resources.
std::shared_ptr<DX::DeviceResources> m_deviceResources;

View File

@ -224,6 +224,7 @@
<ClInclude Include="..\ppsspp_config.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" />
@ -240,6 +241,7 @@
</ClCompile>
<ClCompile Include="App.cpp" />
<ClCompile Include="Common\DeviceResources.cpp" />
<ClCompile Include="NKCodeFromWindowsSystem.cpp" />
<ClCompile Include="PPSSPP_UWPMain.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>

View File

@ -45,6 +45,7 @@
<ClCompile Include="..\git-version.cpp" />
<ClCompile Include="XAudioSoundStream.cpp" />
<ClCompile Include="PPSSPP_UWPMain.cpp" />
<ClCompile Include="NKCodeFromWindowsSystem.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="App.h" />
@ -52,6 +53,7 @@
<ClInclude Include="..\ppsspp_config.h" />
<ClInclude Include="XAudioSoundStream.h" />
<ClInclude Include="PPSSPP_UWPMain.h" />
<ClInclude Include="NKCodeFromWindowsSystem.h" />
</ItemGroup>
<ItemGroup>
<Image Include="Assets\StoreLogo.png">
@ -69,15 +71,15 @@
<Image Include="Content\zip.png">
<Filter>Content</Filter>
</Image>
<Image Include="Content\ui_atlas.zim">
<Filter>Content</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest" />
</ItemGroup>
<ItemGroup>
<None Include="UWP_TemporaryKey.pfx" />
<None Include="Content\ui_atlas.zim">
<Filter>Content</Filter>
</None>
<None Include="Content\compat.ini">
<Filter>Content</Filter>
</None>