Merge branch 'master' into vulkan

This commit is contained in:
Triang3l
2021-07-03 20:59:25 +03:00
73 changed files with 1611 additions and 873 deletions

View File

@@ -12,6 +12,7 @@
#include "third_party/imgui/imgui.h"
#include "xenia/base/assert.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/ui/window.h"
namespace xe {
@@ -107,23 +108,23 @@ void ImGuiDrawer::Initialize() {
style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 1.00f, 0.00f, 0.21f);
style.Colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f);
io.KeyMap[ImGuiKey_Tab] = 0x09; // VK_TAB;
io.KeyMap[ImGuiKey_LeftArrow] = 0x25;
io.KeyMap[ImGuiKey_RightArrow] = 0x27;
io.KeyMap[ImGuiKey_UpArrow] = 0x26;
io.KeyMap[ImGuiKey_DownArrow] = 0x28;
io.KeyMap[ImGuiKey_Home] = 0x24;
io.KeyMap[ImGuiKey_End] = 0x23;
io.KeyMap[ImGuiKey_Delete] = 0x2E;
io.KeyMap[ImGuiKey_Backspace] = 0x08;
io.KeyMap[ImGuiKey_Enter] = 0x0D;
io.KeyMap[ImGuiKey_Escape] = 0x1B;
io.KeyMap[ImGuiKey_A] = 'A';
io.KeyMap[ImGuiKey_C] = 'C';
io.KeyMap[ImGuiKey_V] = 'V';
io.KeyMap[ImGuiKey_X] = 'X';
io.KeyMap[ImGuiKey_Y] = 'Y';
io.KeyMap[ImGuiKey_Z] = 'Z';
io.KeyMap[ImGuiKey_Tab] = int(ui::VirtualKey::kTab);
io.KeyMap[ImGuiKey_LeftArrow] = int(ui::VirtualKey::kLeft);
io.KeyMap[ImGuiKey_RightArrow] = int(ui::VirtualKey::kRight);
io.KeyMap[ImGuiKey_UpArrow] = int(ui::VirtualKey::kUp);
io.KeyMap[ImGuiKey_DownArrow] = int(ui::VirtualKey::kDown);
io.KeyMap[ImGuiKey_Home] = int(ui::VirtualKey::kHome);
io.KeyMap[ImGuiKey_End] = int(ui::VirtualKey::kEnd);
io.KeyMap[ImGuiKey_Delete] = int(ui::VirtualKey::kDelete);
io.KeyMap[ImGuiKey_Backspace] = int(ui::VirtualKey::kBack);
io.KeyMap[ImGuiKey_Enter] = int(ui::VirtualKey::kReturn);
io.KeyMap[ImGuiKey_Escape] = int(ui::VirtualKey::kEscape);
io.KeyMap[ImGuiKey_A] = int(ui::VirtualKey::kA);
io.KeyMap[ImGuiKey_C] = int(ui::VirtualKey::kC);
io.KeyMap[ImGuiKey_V] = int(ui::VirtualKey::kV);
io.KeyMap[ImGuiKey_X] = int(ui::VirtualKey::kX);
io.KeyMap[ImGuiKey_Y] = int(ui::VirtualKey::kY);
io.KeyMap[ImGuiKey_Z] = int(ui::VirtualKey::kZ);
}
void ImGuiDrawer::SetupFont() {
@@ -228,36 +229,16 @@ void ImGuiDrawer::RenderDrawLists() {
}
}
void ImGuiDrawer::OnKeyDown(KeyEvent* e) {
auto& io = GetIO();
io.KeysDown[e->key_code()] = true;
switch (e->key_code()) {
case 16: {
io.KeyShift = true;
} break;
case 17: {
io.KeyCtrl = true;
} break;
}
}
void ImGuiDrawer::OnKeyDown(KeyEvent* e) { OnKey(e, true); }
void ImGuiDrawer::OnKeyUp(KeyEvent* e) {
auto& io = GetIO();
io.KeysDown[e->key_code()] = false;
switch (e->key_code()) {
case 16: {
io.KeyShift = false;
} break;
case 17: {
io.KeyCtrl = false;
} break;
}
}
void ImGuiDrawer::OnKeyUp(KeyEvent* e) { OnKey(e, false); }
void ImGuiDrawer::OnKeyChar(KeyEvent* e) {
auto& io = GetIO();
if (e->key_code() > 0 && e->key_code() < 0x10000) {
io.AddInputCharacter(e->key_code());
// TODO(Triang3l): Accept the Unicode character.
unsigned int character = static_cast<unsigned int>(e->virtual_key());
if (character > 0 && character < 0x10000) {
io.AddInputCharacter(character);
e->set_handled(true);
}
}
@@ -327,5 +308,30 @@ void ImGuiDrawer::OnMouseWheel(MouseEvent* e) {
io.MouseWheel += float(e->dy() / 120.0f);
}
void ImGuiDrawer::OnKey(KeyEvent* e, bool is_down) {
auto& io = GetIO();
VirtualKey virtual_key = e->virtual_key();
if (size_t(virtual_key) < xe::countof(io.KeysDown)) {
io.KeysDown[size_t(virtual_key)] = is_down;
}
switch (virtual_key) {
case VirtualKey::kShift:
io.KeyShift = is_down;
break;
case VirtualKey::kControl:
io.KeyCtrl = is_down;
break;
case VirtualKey::kMenu:
// FIXME(Triang3l): Doesn't work in xenia-ui-window-demo.
io.KeyAlt = is_down;
break;
case VirtualKey::kLWin:
io.KeySuper = is_down;
break;
default:
break;
}
}
} // namespace ui
} // namespace xe

View File

@@ -57,6 +57,9 @@ class ImGuiDrawer : public WindowListener {
ImGuiContext* internal_state_ = nullptr;
std::unique_ptr<ImmediateTexture> font_texture_;
private:
void OnKey(KeyEvent* e, bool is_down);
};
} // namespace ui

View File

@@ -12,6 +12,8 @@
#include <filesystem>
#include "xenia/ui/virtual_key.h"
namespace xe {
namespace ui {
@@ -42,11 +44,12 @@ class FileDropEvent : public UIEvent {
class KeyEvent : public UIEvent {
public:
KeyEvent(Window* target, int key_code, int repeat_count, bool prev_state,
bool modifier_shift_pressed, bool modifier_ctrl_pressed,
bool modifier_alt_pressed, bool modifier_super_pressed)
KeyEvent(Window* target, VirtualKey virtual_key, int repeat_count,
bool prev_state, bool modifier_shift_pressed,
bool modifier_ctrl_pressed, bool modifier_alt_pressed,
bool modifier_super_pressed)
: UIEvent(target),
key_code_(key_code),
virtual_key_(virtual_key),
repeat_count_(repeat_count),
prev_state_(prev_state),
modifier_shift_pressed_(modifier_shift_pressed),
@@ -58,7 +61,7 @@ class KeyEvent : public UIEvent {
bool is_handled() const { return handled_; }
void set_handled(bool value) { handled_ = value; }
int key_code() const { return key_code_; }
VirtualKey virtual_key() const { return virtual_key_; }
int repeat_count() const { return repeat_count_; }
bool prev_state() const { return prev_state_; }
@@ -70,7 +73,7 @@ class KeyEvent : public UIEvent {
private:
bool handled_ = false;
int key_code_ = 0;
VirtualKey virtual_key_ = VirtualKey::kNone;
int repeat_count_ = 0;
bool prev_state_ = false; // Key previously down(true) or up(false)

362
src/xenia/ui/virtual_key.h Normal file
View File

@@ -0,0 +1,362 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2021 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_UI_VIRTUAL_KEY_H_
#define XENIA_UI_VIRTUAL_KEY_H_
#include <cstdint>
namespace xe {
namespace ui {
// Windows and Xbox 360 / XInput virtual key enumeration.
// This is what platform-specific keys should be translated to, for both HID
// keystroke emulation and Xenia-internal UI events. On Windows, the translation
// is a simple cast.
// This is uint16_t as it's WPARAM (which was 16-bit back in Win16 days, where
// virtual key codes were added), and XINPUT_KEYSTROKE stores the virtual key as
// a WORD. In some cases (see kPacket), bits above 16 may be used as well, but
// VK_ on Windows are defined up to 0xFF (0xFE not counting the reserved 0xFF)
// as of Windows SDK 10.0.19041.0, and XInput virtual key codes are 16-bit.
// Base virtual key codes as of _WIN32_WINNT 0x0500 (Windows 2000, which the
// Xbox 360's kernel is based on), virtual key codes added later are marked
// explicitly as such.
enum class VirtualKey : uint16_t {
// Not a valid key - MapVirtualKey returns zero when there is no translation.
kNone,
kLButton = 0x01,
kRButton = 0x02,
kCancel = 0x03, // Control-break.
kMButton = 0x04, // Not contiguous with kLButton and kRButton.
kXButton1 = 0x05, // Not contiguous with kLButton and kRButton.
kXButton2 = 0x06, // Not contiguous with kLButton and kRButton.
kBack = 0x08, // Backspace.
kTab = 0x09,
kClear = 0x0C,
kReturn = 0x0D, // Enter.
kShift = 0x10,
kControl = 0x11, // Ctrl.
kMenu = 0x12, // Alt.
kPause = 0x13,
kCapital = 0x14, // Caps Lock.
kKana = 0x15,
kHangeul = 0x15, // Old name.
kHangul = 0x15,
kImeOn = 0x16,
kJunja = 0x17,
kFinal = 0x18,
kHanja = 0x19,
kKanji = 0x19,
kImeOff = 0x1A,
kEscape = 0x1B,
kConvert = 0x1C,
kNonConvert = 0x1D,
kAccept = 0x1E,
kModeChange = 0x1F,
kSpace = 0x20,
kPrior = 0x21, // Page Up.
kNext = 0x22, // Page Down.
kEnd = 0x23,
kHome = 0x24,
kLeft = 0x25,
kUp = 0x26,
kRight = 0x27,
kDown = 0x28,
kSelect = 0x29,
kPrint = 0x2A,
kExecute = 0x2B,
kSnapshot = 0x2C,
kInsert = 0x2D,
kDelete = 0x2E,
kHelp = 0x2F,
// Same as ASCII '0' - '9'.
k0 = 0x30,
k1 = 0x31,
k2 = 0x32,
k3 = 0x33,
k4 = 0x34,
k5 = 0x35,
k6 = 0x36,
k7 = 0x37,
k8 = 0x38,
k9 = 0x39,
// Same as ASCII 'A' - 'Z'.
kA = 0x41,
kB = 0x42,
kC = 0x43,
kD = 0x44,
kE = 0x45,
kF = 0x46,
kG = 0x47,
kH = 0x48,
kI = 0x49,
kJ = 0x4A,
kK = 0x4B,
kL = 0x4C,
kM = 0x4D,
kN = 0x4E,
kO = 0x4F,
kP = 0x50,
kQ = 0x51,
kR = 0x52,
kS = 0x53,
kT = 0x54,
kU = 0x55,
kV = 0x56,
kW = 0x57,
kX = 0x58,
kY = 0x59,
kZ = 0x5A,
kLWin = 0x5B,
kRWin = 0x5C,
kApps = 0x5D,
kSleep = 0x5F,
kNumpad0 = 0x60,
kNumpad1 = 0x61,
kNumpad2 = 0x62,
kNumpad3 = 0x63,
kNumpad4 = 0x64,
kNumpad5 = 0x65,
kNumpad6 = 0x66,
kNumpad7 = 0x67,
kNumpad8 = 0x68,
kNumpad9 = 0x69,
kMultiply = 0x6A,
kAdd = 0x6B,
kSeparator = 0x6C,
kSubtract = 0x6D,
kDecimal = 0x6E,
kDivide = 0x6F,
kF1 = 0x70,
kF2 = 0x71,
kF3 = 0x72,
kF4 = 0x73,
kF5 = 0x74,
kF6 = 0x75,
kF7 = 0x76,
kF8 = 0x77,
kF9 = 0x78,
kF10 = 0x79,
kF11 = 0x7A,
kF12 = 0x7B,
kF13 = 0x7C,
kF14 = 0x7D,
kF15 = 0x7E,
kF16 = 0x7F,
kF17 = 0x80,
kF18 = 0x81,
kF19 = 0x82,
kF20 = 0x83,
kF21 = 0x84,
kF22 = 0x85,
kF23 = 0x86,
kF24 = 0x87,
// VK_NAVIGATION_* added in _WIN32_WINNT 0x0604, but marked as reserved in
// WinUser.h and not documented on MSDN.
kNavigationView = 0x88,
kNavigationMenu = 0x89,
kNavigationUp = 0x8A,
kNavigationDown = 0x8B,
kNavigationLeft = 0x8C,
kNavigationRight = 0x8D,
kNavigationAccept = 0x8E,
kNavigationCancel = 0x8F,
kNumLock = 0x90,
kScroll = 0x91,
// NEC PC-9800 keyboard.
kOemNecEqual = 0x92, // '=' key on the numpad.
// Fujitsu/OASYS keyboard.
kOemFjJisho = 0x92, // 'Dictionary' key.
kOemFjMasshou = 0x93, // 'Unregister word' key.
kOemFjTouroku = 0x94, // 'Register word' key.
kOemFjLOya = 0x95, // 'Left OYAYUBI' key.
kOemFjROya = 0x96, // 'Right OYAYUBI' key.
// Left and right Alt, Ctrl and Shift virtual keys.
// On Windows (from WinUser.h):
// "Used only as parameters to GetAsyncKeyState() and GetKeyState().
// No other API or message will distinguish left and right keys in this way."
kLShift = 0xA0,
kRShift = 0xA1,
kLControl = 0xA2,
kRControl = 0xA3,
kLMenu = 0xA4,
kRMenu = 0xA5,
kBrowserBack = 0xA6,
kBrowserForward = 0xA7,
kBrowserRefresh = 0xA8,
kBrowserStop = 0xA9,
kBrowserSearch = 0xAA,
kBrowserFavorites = 0xAB,
kBrowserHome = 0xAC,
kVolumeMute = 0xAD,
kVolumeDown = 0xAE,
kVolumeUp = 0xAF,
kMediaNextTrack = 0xB0,
kMediaPrevTrack = 0xB1,
kMediaStop = 0xB2,
kMediaPlayPause = 0xB3,
kLaunchMail = 0xB4,
kLaunchMediaSelect = 0xB5,
kLaunchApp1 = 0xB6,
kLaunchApp2 = 0xB7,
kOem1 = 0xBA, // ';:' for the US.
kOemPlus = 0xBB, // '+' for any country.
kOemComma = 0xBC, // ',' for any country.
kOemMinus = 0xBD, // '-' for any country.
kOemPeriod = 0xBE, // '.' for any country.
kOem2 = 0xBF, // '/?' for the US.
kOem3 = 0xC0, // '`~' for the US.
// VK_GAMEPAD_* (since _WIN32_WINNT 0x0604) virtual key codes are marked as
// reserved in WinUser.h and are mostly not documented on MSDN (with the
// exception of the Xbox Device Portal Remote Input REST API in the "UWP on
// Xbox One" section).
// Xenia uses VK_PAD_* (kXInputPad*) for HID emulation internally instead
// because XInput is the API used for the Xbox 360 controller.
// To avoid confusion between VK_GAMEPAD_* and VK_PAD_*, here they are
// prefixed with kXboxOne and kXInput respectively.
kXboxOneGamepadA = 0xC3,
kXboxOneGamepadB = 0xC4,
kXboxOneGamepadX = 0xC5,
kXboxOneGamepadY = 0xC6,
kXboxOneGamepadRightShoulder = 0xC7,
kXboxOneGamepadLeftShoulder = 0xC8,
kXboxOneGamepadLeftTrigger = 0xC9,
kXboxOneGamepadRightTrigger = 0xCA,
kXboxOneGamepadDpadUp = 0xCB,
kXboxOneGamepadDpadDown = 0xCC,
kXboxOneGamepadDpadLeft = 0xCD,
kXboxOneGamepadDpadRight = 0xCE,
kXboxOneGamepadMenu = 0xCF,
kXboxOneGamepadView = 0xD0,
kXboxOneGamepadLeftThumbstickButton = 0xD1,
kXboxOneGamepadRightThumbstickButton = 0xD2,
kXboxOneGamepadLeftThumbstickUp = 0xD3,
kXboxOneGamepadLeftThumbstickDown = 0xD4,
kXboxOneGamepadLeftThumbstickRight = 0xD5,
kXboxOneGamepadLeftThumbstickLeft = 0xD6,
kXboxOneGamepadRightThumbstickUp = 0xD7,
kXboxOneGamepadRightThumbstickDown = 0xD8,
kXboxOneGamepadRightThumbstickRight = 0xD9,
kXboxOneGamepadRightThumbstickLeft = 0xDA,
kOem4 = 0xDB, // '[{' for the US.
kOem5 = 0xDC, // '\|' for the US.
kOem6 = 0xDD, // ']}' for the US.
kOem7 = 0xDE, // ''"' for the US.
kOem8 = 0xDF,
kOemAx = 0xE1, // 'AX' key on the Japanese AX keyboard.
kOem102 = 0xE2, // "<>" or "\|" on the RT 102-key keyboard.
kIcoHelp = 0xE3, // Help key on the Olivetti keyboard (ICO).
kIco00 = 0xE4, // 00 key on the ICO.
kProcessKey = 0xE5,
kIcoClear = 0xE6,
// From MSDN:
// "Used to pass Unicode characters as if they were keystrokes. The VK_PACKET
// key is the low word of a 32-bit Virtual Key value used for non-keyboard
// input methods."
kPacket = 0xE7,
// Nokia/Ericsson.
kOemReset = 0xE9,
kOemJump = 0xEA,
kOemPa1 = 0xEB,
kOemPa2 = 0xEC,
kOemPa3 = 0xED,
kOemWsCtrl = 0xEE,
kOemCuSel = 0xEF,
kOemAttn = 0xF0,
kOemFinish = 0xF1,
kOemCopy = 0xF2,
kOemAuto = 0xF3,
kOemEnlW = 0xF4,
kOemBackTab = 0xF5,
kAttn = 0xF6,
kCrSel = 0xF7,
kExSel = 0xF8,
kErEof = 0xF9,
kPlay = 0xFA,
kZoom = 0xFB,
kNoName = 0xFC,
kPa1 = 0xFD,
kOemClear = 0xFE,
// VK_PAD_* from XInput.h for XInputGetKeystroke. kXInput prefix added to
// distinguish from VK_GAMEPAD_*, added much later for the Xbox One
// controller.
kXInputPadA = 0x5800,
kXInputPadB = 0x5801,
kXInputPadX = 0x5802,
kXInputPadY = 0x5803,
// RShoulder before LShoulder, not a typo.
kXInputPadRShoulder = 0x5804,
kXInputPadLShoulder = 0x5805,
kXInputPadLTrigger = 0x5806,
kXInputPadRTrigger = 0x5807,
kXInputPadDpadUp = 0x5810,
kXInputPadDpadDown = 0x5811,
kXInputPadDpadLeft = 0x5812,
kXInputPadDpadRight = 0x5813,
kXInputPadStart = 0x5814,
kXInputPadBack = 0x5815,
kXInputPadLThumbPress = 0x5816,
kXInputPadRThumbPress = 0x5817,
kXInputPadLThumbUp = 0x5820,
kXInputPadLThumbDown = 0x5821,
kXInputPadLThumbRight = 0x5822,
kXInputPadLThumbLeft = 0x5823,
kXInputPadLThumbUpLeft = 0x5824,
kXInputPadLThumbUpRight = 0x5825,
kXInputPadLThumbDownRight = 0x5826,
kXInputPadLThumbDownLeft = 0x5827,
kXInputPadRThumbUp = 0x5830,
kXInputPadRThumbDown = 0x5831,
kXInputPadRThumbRight = 0x5832,
kXInputPadRThumbLeft = 0x5833,
kXInputPadRThumbUpLeft = 0x5834,
kXInputPadRThumbUpRight = 0x5835,
kXInputPadRThumbDownRight = 0x5836,
kXInputPadRThumbDownLeft = 0x5837,
};
} // namespace ui
} // namespace xe
#endif // XENIA_UI_VIRTUAL_KEY_H_

View File

@@ -259,20 +259,21 @@ void Window::OnLostFocus(UIEvent* e) {
void Window::OnKeyPress(KeyEvent* e, bool is_down, bool is_char) {
if (!is_char) {
switch (e->key_code()) {
case 16:
switch (e->virtual_key()) {
case VirtualKey::kShift:
modifier_shift_pressed_ = is_down;
break;
case 17:
case VirtualKey::kControl:
modifier_cntrl_pressed_ = is_down;
break;
// case xx:
// // alt ??
// modifier_alt_pressed_ = is_down;
// break;
case 91:
case VirtualKey::kMenu:
modifier_alt_pressed_ = is_down;
break;
case VirtualKey::kLWin:
modifier_super_pressed_ = is_down;
break;
default:
break;
}
}
}

View File

@@ -18,6 +18,7 @@
#include "xenia/ui/graphics_provider.h"
#include "xenia/ui/imgui_dialog.h"
#include "xenia/ui/imgui_drawer.h"
#include "xenia/ui/virtual_key.h"
#include "xenia/ui/window.h"
namespace xe {
@@ -92,10 +93,12 @@ int window_demo_main(const std::vector<std::string>& args) {
loop->on_quit.AddListener([&window](xe::ui::UIEvent* e) { window.reset(); });
window->on_key_down.AddListener([](xe::ui::KeyEvent* e) {
switch (e->key_code()) {
case 0x72: { // F3
switch (e->virtual_key()) {
case VirtualKey::kF3:
Profiler::ToggleDisplay();
} break;
break;
default:
break;
}
});

View File

@@ -12,6 +12,7 @@
#include "xenia/base/assert.h"
#include "xenia/base/logging.h"
#include "xenia/base/platform_linux.h"
#include "xenia/ui/virtual_key.h"
#include "xenia/ui/window_gtk.h"
namespace xe {
@@ -350,9 +351,10 @@ bool GTKWindow::HandleKeyboard(GdkEventKey* event) {
bool ctrl_pressed = modifiers & GDK_CONTROL_MASK;
bool alt_pressed = modifiers & GDK_META_MASK;
bool super_pressed = modifiers & GDK_SUPER_MASK;
auto e =
KeyEvent(this, event->hardware_keycode, 1, event->type == GDK_KEY_RELEASE,
shift_pressed, ctrl_pressed, alt_pressed, super_pressed);
// TODO(Triang3l): event->hardware_keycode to VirtualKey translation.
auto e = KeyEvent(this, VirtualKey(event->hardware_keycode), 1,
event->type == GDK_KEY_RELEASE, shift_pressed, ctrl_pressed,
alt_pressed, super_pressed);
switch (event->type) {
case GDK_KEY_PRESS:
OnKeyDown(&e);

View File

@@ -17,6 +17,7 @@
#include "xenia/base/filesystem.h"
#include "xenia/base/logging.h"
#include "xenia/base/platform_win.h"
#include "xenia/ui/virtual_key.h"
namespace xe {
namespace ui {
@@ -706,7 +707,7 @@ bool Win32Window::HandleMouse(UINT message, WPARAM wParam, LPARAM lParam) {
bool Win32Window::HandleKeyboard(UINT message, WPARAM wParam, LPARAM lParam) {
auto e = KeyEvent(
this, static_cast<int>(wParam), lParam & 0xFFFF0000, !!(lParam & 0x2),
this, VirtualKey(wParam), lParam & 0xFFFF0000, !!(lParam & 0x2),
!!(GetKeyState(VK_SHIFT) & 0x80), !!(GetKeyState(VK_CONTROL) & 0x80),
!!(GetKeyState(VK_MENU) & 0x80), !!(GetKeyState(VK_LWIN) & 0x80));
switch (message) {