First step towards configurable keyboard mappings (#464)

* Configurable keyboard mappings

* Cleanup

* Cleanup

* Biggest mistake of my career

* format

* Fix naming convention

---------

Co-authored-by: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
This commit is contained in:
Paris Oplopoios 2024-03-21 15:54:18 +02:00 committed by GitHub
parent 5488e9ca7c
commit 3270cfe602
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 162 additions and 126 deletions

View file

@ -8,8 +8,9 @@
#include <fstream>
#include "cheats.hpp"
#include "input_mappings.hpp"
MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent), screen(this) {
MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent), keyboardMappings(InputMappings::defaultKeyboardMappings()), screen(this) {
setWindowTitle("Alber");
// Enable drop events for loading ROMs
setAcceptDrops(true);
@ -298,29 +299,21 @@ void MainWindow::keyPressEvent(QKeyEvent* event) {
sendMessage(message);
};
switch (event->key()) {
case Qt::Key_L: pressKey(HID::Keys::A); break;
case Qt::Key_K: pressKey(HID::Keys::B); break;
case Qt::Key_O: pressKey(HID::Keys::X); break;
case Qt::Key_I: pressKey(HID::Keys::Y); break;
u32 key = keyboardMappings.getMapping(event->key());
if (key != HID::Keys::Null) {
switch (key) {
case HID::Keys::CirclePadUp: setCirclePad(MessageType::SetCirclePadY, 0x9C); break;
case HID::Keys::CirclePadDown: setCirclePad(MessageType::SetCirclePadY, -0x9C); break;
case HID::Keys::CirclePadLeft: setCirclePad(MessageType::SetCirclePadX, -0x9C); break;
case HID::Keys::CirclePadRight: setCirclePad(MessageType::SetCirclePadX, 0x9C); break;
case Qt::Key_Q: pressKey(HID::Keys::L); break;
case Qt::Key_P: pressKey(HID::Keys::R); break;
case Qt::Key_W: setCirclePad(MessageType::SetCirclePadY, 0x9C); break;
case Qt::Key_A: setCirclePad(MessageType::SetCirclePadX, -0x9C); break;
case Qt::Key_S: setCirclePad(MessageType::SetCirclePadY, -0x9C); break;
case Qt::Key_D: setCirclePad(MessageType::SetCirclePadX, 0x9C); break;
case Qt::Key_Right: pressKey(HID::Keys::Right); break;
case Qt::Key_Left: pressKey(HID::Keys::Left); break;
case Qt::Key_Up: pressKey(HID::Keys::Up); break;
case Qt::Key_Down: pressKey(HID::Keys::Down); break;
case Qt::Key_Return: pressKey(HID::Keys::Start); break;
case Qt::Key_Backspace: pressKey(HID::Keys::Select); break;
case Qt::Key_F4: sendMessage(EmulatorMessage{.type = MessageType::TogglePause}); break;
case Qt::Key_F5: sendMessage(EmulatorMessage{.type = MessageType::Reset}); break;
default: pressKey(key); break;
}
} else {
switch (event->key()) {
case Qt::Key_F4: sendMessage(EmulatorMessage{.type = MessageType::TogglePause}); break;
case Qt::Key_F5: sendMessage(EmulatorMessage{.type = MessageType::Reset}); break;
}
}
}
@ -337,28 +330,16 @@ void MainWindow::keyReleaseEvent(QKeyEvent* event) {
sendMessage(message);
};
switch (event->key()) {
case Qt::Key_L: releaseKey(HID::Keys::A); break;
case Qt::Key_K: releaseKey(HID::Keys::B); break;
case Qt::Key_O: releaseKey(HID::Keys::X); break;
case Qt::Key_I: releaseKey(HID::Keys::Y); break;
u32 key = keyboardMappings.getMapping(event->key());
if (key != HID::Keys::Null) {
switch (key) {
case HID::Keys::CirclePadUp: releaseCirclePad(MessageType::SetCirclePadY); break;
case HID::Keys::CirclePadDown: releaseCirclePad(MessageType::SetCirclePadY); break;
case HID::Keys::CirclePadLeft: releaseCirclePad(MessageType::SetCirclePadX); break;
case HID::Keys::CirclePadRight: releaseCirclePad(MessageType::SetCirclePadX); break;
case Qt::Key_Q: releaseKey(HID::Keys::L); break;
case Qt::Key_P: releaseKey(HID::Keys::R); break;
case Qt::Key_W:
case Qt::Key_S: releaseCirclePad(MessageType::SetCirclePadY); break;
case Qt::Key_A:
case Qt::Key_D: releaseCirclePad(MessageType::SetCirclePadX); break;
case Qt::Key_Right: releaseKey(HID::Keys::Right); break;
case Qt::Key_Left: releaseKey(HID::Keys::Left); break;
case Qt::Key_Up: releaseKey(HID::Keys::Up); break;
case Qt::Key_Down: releaseKey(HID::Keys::Down); break;
case Qt::Key_Return: releaseKey(HID::Keys::Start); break;
case Qt::Key_Backspace: releaseKey(HID::Keys::Select); break;
default: releaseKey(key); break;
}
}
}

25
src/panda_qt/mappings.cpp Normal file
View file

@ -0,0 +1,25 @@
#include "input_mappings.hpp"
#include <QKeyEvent>
InputMappings InputMappings::defaultKeyboardMappings() {
InputMappings mappings;
mappings.setMapping(Qt::Key_L, HID::Keys::A);
mappings.setMapping(Qt::Key_K, HID::Keys::B);
mappings.setMapping(Qt::Key_O, HID::Keys::X);
mappings.setMapping(Qt::Key_I, HID::Keys::Y);
mappings.setMapping(Qt::Key_Q, HID::Keys::L);
mappings.setMapping(Qt::Key_P, HID::Keys::R);
mappings.setMapping(Qt::Key_Up, HID::Keys::Up);
mappings.setMapping(Qt::Key_Down, HID::Keys::Down);
mappings.setMapping(Qt::Key_Right, HID::Keys::Right);
mappings.setMapping(Qt::Key_Left, HID::Keys::Left);
mappings.setMapping(Qt::Key_Return, HID::Keys::Start);
mappings.setMapping(Qt::Key_Backspace, HID::Keys::Select);
mappings.setMapping(Qt::Key_W, HID::Keys::CirclePadUp);
mappings.setMapping(Qt::Key_S, HID::Keys::CirclePadDown);
mappings.setMapping(Qt::Key_D, HID::Keys::CirclePadRight);
mappings.setMapping(Qt::Key_A, HID::Keys::CirclePadLeft);
return mappings;
}

View file

@ -2,7 +2,7 @@
#include <glad/gl.h>
FrontendSDL::FrontendSDL() {
FrontendSDL::FrontendSDL() : keyboardMappings(InputMappings::defaultKeyboardMappings()) {
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0) {
Helpers::panic("Failed to initialize SDL2");
}
@ -92,95 +92,71 @@ void FrontendSDL::run() {
programRunning = false;
return;
case SDL_KEYDOWN:
case SDL_KEYDOWN: {
if (emu.romType == ROMType::None) break;
switch (event.key.keysym.sym) {
case SDLK_l: hid.pressKey(Keys::A); break;
case SDLK_k: hid.pressKey(Keys::B); break;
case SDLK_o: hid.pressKey(Keys::X); break;
case SDLK_i: hid.pressKey(Keys::Y); break;
case SDLK_q: hid.pressKey(Keys::L); break;
case SDLK_p: hid.pressKey(Keys::R); break;
case SDLK_RIGHT: hid.pressKey(Keys::Right); break;
case SDLK_LEFT: hid.pressKey(Keys::Left); break;
case SDLK_UP: hid.pressKey(Keys::Up); break;
case SDLK_DOWN: hid.pressKey(Keys::Down); break;
case SDLK_w:
hid.setCirclepadY(0x9C);
keyboardAnalogY = true;
break;
case SDLK_a:
hid.setCirclepadX(-0x9C);
keyboardAnalogX = true;
break;
case SDLK_s:
hid.setCirclepadY(-0x9C);
keyboardAnalogY = true;
break;
case SDLK_d:
hid.setCirclepadX(0x9C);
keyboardAnalogX = true;
break;
case SDLK_RETURN: hid.pressKey(Keys::Start); break;
case SDLK_BACKSPACE: hid.pressKey(Keys::Select); break;
// Use the F4 button as a hot-key to pause or resume the emulator
// We can't use the audio play/pause buttons because it's annoying
case SDLK_F4: {
emu.togglePause();
break;
u32 key = getMapping(event.key.keysym.scancode);
if (key != HID::Keys::Null) {
switch (key) {
case HID::Keys::CirclePadRight:
hid.setCirclepadX(0x9C);
keyboardAnalogX = true;
break;
case HID::Keys::CirclePadLeft:
hid.setCirclepadX(-0x9C);
keyboardAnalogX = true;
break;
case HID::Keys::CirclePadUp:
hid.setCirclepadY(0x9C);
keyboardAnalogY = true;
break;
case HID::Keys::CirclePadDown:
hid.setCirclepadY(-0x9C);
keyboardAnalogY = true;
break;
default: hid.pressKey(key); break;
}
} else {
switch (event.key.keysym.sym) {
// Use the F4 button as a hot-key to pause or resume the emulator
// We can't use the audio play/pause buttons because it's annoying
case SDLK_F4: {
emu.togglePause();
break;
}
// Use F5 as a reset button
case SDLK_F5: {
emu.reset(Emulator::ReloadOption::Reload);
break;
// Use F5 as a reset button
case SDLK_F5: {
emu.reset(Emulator::ReloadOption::Reload);
break;
}
}
}
break;
}
case SDL_KEYUP:
case SDL_KEYUP: {
if (emu.romType == ROMType::None) break;
switch (event.key.keysym.sym) {
case SDLK_l: hid.releaseKey(Keys::A); break;
case SDLK_k: hid.releaseKey(Keys::B); break;
case SDLK_o: hid.releaseKey(Keys::X); break;
case SDLK_i: hid.releaseKey(Keys::Y); break;
case SDLK_q: hid.releaseKey(Keys::L); break;
case SDLK_p: hid.releaseKey(Keys::R); break;
case SDLK_RIGHT: hid.releaseKey(Keys::Right); break;
case SDLK_LEFT: hid.releaseKey(Keys::Left); break;
case SDLK_UP: hid.releaseKey(Keys::Up); break;
case SDLK_DOWN: hid.releaseKey(Keys::Down); break;
// Err this is probably not ideal
case SDLK_w:
case SDLK_s:
hid.setCirclepadY(0);
keyboardAnalogY = false;
break;
case SDLK_a:
case SDLK_d:
hid.setCirclepadX(0);
keyboardAnalogX = false;
break;
case SDLK_RETURN: hid.releaseKey(Keys::Start); break;
case SDLK_BACKSPACE: hid.releaseKey(Keys::Select); break;
u32 key = getMapping(event.key.keysym.scancode);
if (key != HID::Keys::Null) {
switch (key) {
// Err this is probably not ideal
case HID::Keys::CirclePadRight:
case HID::Keys::CirclePadLeft:
hid.setCirclepadX(0);
keyboardAnalogX = false;
break;
case HID::Keys::CirclePadUp:
case HID::Keys::CirclePadDown:
hid.setCirclepadY(0);
keyboardAnalogY = false;
break;
default: hid.releaseKey(key); break;
}
}
break;
}
case SDL_MOUSEBUTTONDOWN:
if (emu.romType == ROMType::None) break;

View file

@ -0,0 +1,25 @@
#include "input_mappings.hpp"
#include <SDL.h>
InputMappings InputMappings::defaultKeyboardMappings() {
InputMappings mappings;
mappings.setMapping(SDLK_l, HID::Keys::A);
mappings.setMapping(SDLK_k, HID::Keys::B);
mappings.setMapping(SDLK_o, HID::Keys::X);
mappings.setMapping(SDLK_i, HID::Keys::Y);
mappings.setMapping(SDLK_q, HID::Keys::L);
mappings.setMapping(SDLK_p, HID::Keys::R);
mappings.setMapping(SDLK_UP, HID::Keys::Up);
mappings.setMapping(SDLK_DOWN, HID::Keys::Down);
mappings.setMapping(SDLK_RIGHT, HID::Keys::Right);
mappings.setMapping(SDLK_LEFT, HID::Keys::Left);
mappings.setMapping(SDLK_RETURN, HID::Keys::Start);
mappings.setMapping(SDLK_BACKSPACE, HID::Keys::Select);
mappings.setMapping(SDLK_w, HID::Keys::CirclePadUp);
mappings.setMapping(SDLK_s, HID::Keys::CirclePadDown);
mappings.setMapping(SDLK_d, HID::Keys::CirclePadRight);
mappings.setMapping(SDLK_a, HID::Keys::CirclePadLeft);
return mappings;
}