Skip to content

Commit

Permalink
Refactor VirtualController and keyboard mappings. At UI for editing k…
Browse files Browse the repository at this point in the history
…eyboard mapping table.
  • Loading branch information
Mysticial committed Jan 28, 2025
1 parent 51f18f0 commit 8165f57
Show file tree
Hide file tree
Showing 15 changed files with 538 additions and 104 deletions.
31 changes: 25 additions & 6 deletions Common/Qt/Options/EditableTableWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <QScrollBar>
#include <QLabel>
#include <QPushButton>
#include <QMessageBox>
#include "Common/Cpp/Json/JsonValue.h"
#include "Common/Qt/AutoHeightTable.h"
#include "EditableTableWidget.h"
Expand Down Expand Up @@ -94,10 +95,10 @@ EditableTableWidget::EditableTableWidget(QWidget& parent, EditableTableOption& v
QHBoxLayout* buttons = new QHBoxLayout();
layout->addLayout(buttons);
{
QPushButton* load_button = new QPushButton("Load Table", this);
buttons->addWidget(load_button, 1);
QPushButton* button = new QPushButton("Load Table", this);
buttons->addWidget(button, 1);
connect(
load_button, &QPushButton::clicked,
button, &QPushButton::clicked,
this, [this, &value](bool){
std::string path = QFileDialog::getOpenFileName(
this,
Expand All @@ -111,10 +112,10 @@ EditableTableWidget::EditableTableWidget(QWidget& parent, EditableTableOption& v
);
}
{
QPushButton* save_button = new QPushButton("Save Table", this);
buttons->addWidget(save_button, 1);
QPushButton* button = new QPushButton("Save Table", this);
buttons->addWidget(button, 1);
connect(
save_button, &QPushButton::clicked,
button, &QPushButton::clicked,
this, [this, &value](bool){
std::string path = QFileDialog::getSaveFileName(
this,
Expand All @@ -128,6 +129,24 @@ EditableTableWidget::EditableTableWidget(QWidget& parent, EditableTableOption& v
}
);
}
{
QPushButton* button = new QPushButton("Restore Defaults", this);
buttons->addWidget(button, 1);
connect(
button, &QPushButton::clicked,
this, [&value](bool){
QMessageBox::StandardButton button = QMessageBox::question(
nullptr,
"Restore Defaults",
"Are you sure you wish to this table back to defaults? This will wipe the current table.",
QMessageBox::Ok | QMessageBox::Cancel
);
if (button == QMessageBox::Ok){
value.restore_defaults();
}
}
);
}
buttons->addStretch(2);
}

Expand Down
8 changes: 6 additions & 2 deletions SerialPrograms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ file(GLOB MAIN_SOURCES
../Common/Cpp/Options/GroupOption.h
../Common/Cpp/Options/IntegerRangeOption.cpp
../Common/Cpp/Options/IntegerRangeOption.h
../Common/Cpp/Options/KeyBindingOption.cpp
../Common/Cpp/Options/KeyBindingOption.h
../Common/Cpp/Options/RandomCodeOption.cpp
../Common/Cpp/Options/RandomCodeOption.h
../Common/Cpp/Options/SimpleIntegerOption.cpp
Expand Down Expand Up @@ -214,6 +216,8 @@ file(GLOB MAIN_SOURCES
../Common/Qt/Options/GroupWidget.h
../Common/Qt/Options/IntegerRangeWidget.cpp
../Common/Qt/Options/IntegerRangeWidget.h
../Common/Qt/Options/KeyBindingWidget.cpp
../Common/Qt/Options/KeyBindingWidget.h
../Common/Qt/Options/RandomCodeWidget.cpp
../Common/Qt/Options/RandomCodeWidget.h
../Common/Qt/Options/SimpleIntegerWidget.cpp
Expand Down Expand Up @@ -832,8 +836,6 @@ file(GLOB MAIN_SOURCES
Source/NintendoSwitch/Framework/NintendoSwitch_SwitchSystemSession.h
Source/NintendoSwitch/Framework/NintendoSwitch_VirtualController.cpp
Source/NintendoSwitch/Framework/NintendoSwitch_VirtualController.h
Source/NintendoSwitch/Framework/NintendoSwitch_VirtualControllerMapping.cpp
Source/NintendoSwitch/Framework/NintendoSwitch_VirtualControllerMapping.h
Source/NintendoSwitch/Framework/NintendoSwitch_VirtualControllerState.cpp
Source/NintendoSwitch/Framework/NintendoSwitch_VirtualControllerState.h
Source/NintendoSwitch/Framework/UI/NintendoSwitch_CommandRow.cpp
Expand All @@ -852,6 +854,8 @@ file(GLOB MAIN_SOURCES
Source/NintendoSwitch/Inference/NintendoSwitch_DetectHome.h
Source/NintendoSwitch/NintendoSwitch_ConsoleHandle.cpp
Source/NintendoSwitch/NintendoSwitch_ConsoleHandle.h
Source/NintendoSwitch/NintendoSwitch_KeyboardMapping.cpp
Source/NintendoSwitch/NintendoSwitch_KeyboardMapping.h
Source/NintendoSwitch/NintendoSwitch_MultiSwitchProgram.cpp
Source/NintendoSwitch/NintendoSwitch_MultiSwitchProgram.h
Source/NintendoSwitch/NintendoSwitch_Panels.cpp
Expand Down
12 changes: 10 additions & 2 deletions SerialPrograms/SerialPrograms.pro
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ SOURCES += \
../Common/Cpp/Options/FloatingPointOption.cpp \
../Common/Cpp/Options/GroupOption.cpp \
../Common/Cpp/Options/IntegerRangeOption.cpp \
../Common/Cpp/Options/KeyBindingOption.cpp \
../Common/Cpp/Options/RandomCodeOption.cpp \
../Common/Cpp/Options/SimpleIntegerOption.cpp \
../Common/Cpp/Options/StaticTableOption.cpp \
Expand Down Expand Up @@ -141,6 +142,7 @@ SOURCES += \
../Common/Qt/Options/FloatingPointWidget.cpp \
../Common/Qt/Options/GroupWidget.cpp \
../Common/Qt/Options/IntegerRangeWidget.cpp \
../Common/Qt/Options/KeyBindingWidget.cpp \
../Common/Qt/Options/RandomCodeWidget.cpp \
../Common/Qt/Options/SimpleIntegerWidget.cpp \
../Common/Qt/Options/StaticTableWidget.cpp \
Expand Down Expand Up @@ -413,7 +415,6 @@ SOURCES += \
Source/NintendoSwitch/Framework/NintendoSwitch_SwitchSystemOption.cpp \
Source/NintendoSwitch/Framework/NintendoSwitch_SwitchSystemSession.cpp \
Source/NintendoSwitch/Framework/NintendoSwitch_VirtualController.cpp \
Source/NintendoSwitch/Framework/NintendoSwitch_VirtualControllerMapping.cpp \
Source/NintendoSwitch/Framework/NintendoSwitch_VirtualControllerState.cpp \
Source/NintendoSwitch/Framework/UI/NintendoSwitch_CommandRow.cpp \
Source/NintendoSwitch/Framework/UI/NintendoSwitch_MultiSwitchProgramWidget.cpp \
Expand All @@ -423,6 +424,7 @@ SOURCES += \
Source/NintendoSwitch/Inference/NintendoSwitch_DateReader.cpp \
Source/NintendoSwitch/Inference/NintendoSwitch_DetectHome.cpp \
Source/NintendoSwitch/NintendoSwitch_ConsoleHandle.cpp \
Source/NintendoSwitch/NintendoSwitch_KeyboardMapping.cpp \
Source/NintendoSwitch/NintendoSwitch_MultiSwitchProgram.cpp \
Source/NintendoSwitch/NintendoSwitch_Panels.cpp \
Source/NintendoSwitch/NintendoSwitch_Settings.cpp \
Expand Down Expand Up @@ -646,6 +648,8 @@ SOURCES += \
Source/PokemonLA/Resources/PokemonLA_NameDatabase.cpp \
Source/PokemonLA/Resources/PokemonLA_PokemonSprites.cpp \
Source/PokemonLA/Resources/PokemonLA_WeatherAndTimeIcons.cpp \
Source/PokemonRSE/PokemonRSE_Panels.cpp \
Source/PokemonRSE/PokemonRSE_Settings.cpp \
Source/PokemonSV/Inference/Battles/PokemonSV_BattleBallReader.cpp \
Source/PokemonSV/Inference/Battles/PokemonSV_EncounterWatcher.cpp \
Source/PokemonSV/Inference/Battles/PokemonSV_NormalBattleMenus.cpp \
Expand Down Expand Up @@ -1166,6 +1170,7 @@ HEADERS += \
../Common/Cpp/Options/FloatingPointOption.h \
../Common/Cpp/Options/GroupOption.h \
../Common/Cpp/Options/IntegerRangeOption.h \
../Common/Cpp/Options/KeyBindingOption.h \
../Common/Cpp/Options/RandomCodeOption.h \
../Common/Cpp/Options/SimpleIntegerOption.h \
../Common/Cpp/Options/StaticTableOption.h \
Expand Down Expand Up @@ -1210,6 +1215,7 @@ HEADERS += \
../Common/Qt/Options/FloatingPointWidget.h \
../Common/Qt/Options/GroupWidget.h \
../Common/Qt/Options/IntegerRangeWidget.h \
../Common/Qt/Options/KeyBindingWidget.h \
../Common/Qt/Options/RandomCodeWidget.h \
../Common/Qt/Options/SimpleIntegerWidget.h \
../Common/Qt/Options/StaticTableWidget.h \
Expand Down Expand Up @@ -1547,7 +1553,6 @@ HEADERS += \
Source/NintendoSwitch/Framework/NintendoSwitch_SwitchSystemOption.h \
Source/NintendoSwitch/Framework/NintendoSwitch_SwitchSystemSession.h \
Source/NintendoSwitch/Framework/NintendoSwitch_VirtualController.h \
Source/NintendoSwitch/Framework/NintendoSwitch_VirtualControllerMapping.h \
Source/NintendoSwitch/Framework/NintendoSwitch_VirtualControllerState.h \
Source/NintendoSwitch/Framework/UI/NintendoSwitch_CommandRow.h \
Source/NintendoSwitch/Framework/UI/NintendoSwitch_MultiSwitchProgramWidget.h \
Expand All @@ -1556,6 +1561,7 @@ HEADERS += \
Source/NintendoSwitch/Framework/UI/NintendoSwitch_SwitchSystemWidget.h \
Source/NintendoSwitch/Inference/NintendoSwitch_DateReader.h \
Source/NintendoSwitch/Inference/NintendoSwitch_DetectHome.h \
Source/NintendoSwitch/NintendoSwitch_KeyboardMapping.h \
Source/NintendoSwitch/NintendoSwitch_MultiSwitchProgram.h \
Source/NintendoSwitch/NintendoSwitch_Panels.h \
Source/NintendoSwitch/NintendoSwitch_Settings.h \
Expand Down Expand Up @@ -1784,6 +1790,8 @@ HEADERS += \
Source/PokemonLA/Resources/PokemonLA_NameDatabase.h \
Source/PokemonLA/Resources/PokemonLA_PokemonSprites.h \
Source/PokemonLA/Resources/PokemonLA_WeatherAndTimeIcons.h \
Source/PokemonRSE/PokemonRSE_Panels.h \
Source/PokemonRSE/PokemonRSE_Settings.h \
Source/PokemonSV/Inference/Battles/PokemonSV_BattleBallReader.h \
Source/PokemonSV/Inference/Battles/PokemonSV_EncounterWatcher.h \
Source/PokemonSV/Inference/Battles/PokemonSV_NormalBattleMenus.h \
Expand Down
5 changes: 3 additions & 2 deletions SerialPrograms/Source/CommonFramework/PersistentSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include "CommonFramework/Globals.h"
#include "CommonFramework/GlobalSettingsPanel.h"
#include "CommonFramework/Options/Environment/PerformanceOptions.h"
#include "NintendoSwitch/Framework/NintendoSwitch_VirtualControllerMapping.h"
#include "PersistentSettings.h"

// #include <iostream>
Expand All @@ -37,7 +36,7 @@ void PersistentSettings::write() const{
JsonObject root;

root["20-GlobalSettings"] = GlobalSettings::instance().to_json();
root["50-SwitchKeyboardMapping"] = NintendoSwitch::read_keyboard_mapping();
// root["50-SwitchKeyboardMapping"] = NintendoSwitch::read_keyboard_mapping();

root["99-Panels"] = panels.clone();

Expand Down Expand Up @@ -67,12 +66,14 @@ void PersistentSettings::read(){
// GlobalSettings::instance().PROCESS_PRIORITY0.update_priority_to_option();
GlobalSettings::instance().PERFORMANCE->REALTIME_THREAD_PRIORITY.set_on_this_thread();

#if 0
{
const JsonArray* array = obj->get_array("50-SwitchKeyboardMapping");
if (array){
NintendoSwitch::set_keyboard_mapping(*array);
}
}
#endif
{
JsonObject* value = obj->get_object("99-Panels");
if (value){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
#include "CommonFramework/Exceptions/ProgramFinishedException.h"
#include "CommonFramework/Options/Environment/PerformanceOptions.h"
#include "Controllers/GlobalQtKeyMap.h"
#include "NintendoSwitch/NintendoSwitch_Settings.h"
#include "NintendoSwitch/Controllers/NintendoSwitch_Controller.h"
#include "NintendoSwitch_VirtualControllerMapping.h"
#include "NintendoSwitch_VirtualController.h"

//#include <iostream>
Expand All @@ -38,8 +38,15 @@ VirtualController::VirtualController(
, m_allow_commands_while_running(allow_commands_while_running)
, m_last_known_state(ProgramState::STOPPED)
, m_stop(false)
, m_thread(run_with_catch, "VirtualController::thread_loop()", [this]{ thread_loop(); })
{}
{
std::vector<std::shared_ptr<EditableTableRow>> mapping = ConsoleSettings::instance().KEYBOARD_MAPPINGS.current_refs();
for (const auto& deltas : mapping){
const KeyMapTableRow& row = static_cast<const KeyMapTableRow&>(*deltas);
m_mapping[(Qt::Key)(uint32_t)row.key] += row.snapshot();
}

m_thread = std::thread(run_with_catch, "VirtualController::thread_loop()", [this]{ thread_loop(); });
}
VirtualController::~VirtualController(){
m_stop.store(true, std::memory_order_release);
{
Expand All @@ -60,6 +67,10 @@ void VirtualController::clear_state(){

bool VirtualController::on_key_press(const QKeyEvent& key){
// cout << "press: " << key.key() << ", native = " << key.nativeVirtualKey() << endl;

// QKeySequence seq((Qt::Key)key.key());
// cout << "button: " << seq.toString().toStdString() << endl;

QtKeyMap::instance().record(key);
{
WriteSpinLock lg(m_state_lock);
Expand Down Expand Up @@ -101,7 +112,7 @@ bool VirtualController::try_next_interrupt(){
void VirtualController::thread_loop(){
GlobalSettings::instance().PERFORMANCE->REALTIME_THREAD_PRIORITY.set_on_this_thread();

VirtualControllerState last;
ControllerState last;
bool last_neutral = true;
WallClock last_press = current_time();
while (true){
Expand All @@ -113,7 +124,7 @@ void VirtualController::thread_loop(){
if (!m_allow_commands_while_running &&
m_last_known_state.load(std::memory_order_acquire) != ProgramState::STOPPED
){
last = VirtualControllerState();
last = ControllerState();
std::unique_lock<std::mutex> lg(m_sleep_lock);
if (m_stop.load(std::memory_order_acquire)){
return;
Expand All @@ -131,33 +142,24 @@ void VirtualController::thread_loop(){
next_wake = m_state_tracker.next_state_change();
}

#if 0
// REMOVE
std::string str = "state: ";
for (uint32_t native_key : pressed_native_keys){
str += std::to_string(native_key);
str += " ";
}
cout << str << endl; // REMOVE
#endif

// Convert the raw keyboard state to controller state.
VirtualControllerState current;
bool neutral;
ControllerState current;
{
ControllerDeltas deltas;
const QtKeyMap& qkey_map = QtKeyMap::instance();
for (uint32_t native_key : pressed_native_keys){
const std::set<Qt::Key>& qkeys = qkey_map.get_QtKeys(native_key);
for (Qt::Key qkey : qkeys){
const ControllerButton* button = button_lookup(qkey);
if (button != nullptr){
button->press(current);
auto iter = m_mapping.find(qkey);
if (iter != m_mapping.end()){
deltas += iter->second;
break;
}
}
}
neutral = deltas.to_state(current);
}
ControllerState state;
bool neutral = current.to_state(state);
// cout << "neutral = " << neutral << endl;


// Send the command.
Expand All @@ -175,7 +177,7 @@ void VirtualController::thread_loop(){
// If state is neutral, just issue a stop.
if (neutral){
if (try_stop_commands()){
last = VirtualControllerState();
last = ControllerState();
last_neutral = true;
last_press = now;
}else{
Expand All @@ -193,22 +195,22 @@ void VirtualController::thread_loop(){

// Send the command.
m_logger.log(
"VirtualController: (" + button_to_string(state.buttons) +
"), dpad(" + dpad_to_string(state.dpad) +
"), LJ(" + std::to_string(state.left_x) + "," + std::to_string(state.left_y) +
"), RJ(" + std::to_string(state.right_x) + "," + std::to_string(state.right_y) +
"VirtualController: (" + button_to_string(current.buttons) +
"), dpad(" + dpad_to_string(current.dpad) +
"), LJ(" + std::to_string(current.left_x) + "," + std::to_string(current.left_y) +
"), RJ(" + std::to_string(current.right_x) + "," + std::to_string(current.right_y) +
")",
COLOR_DARKGREEN
);
std::string error = m_session.try_run<SwitchController>([=](SwitchController& controller){
controller.issue_controller_state(
nullptr,
state.buttons,
state.dpad,
state.left_x,
state.left_y,
state.right_x,
state.right_y,
current.buttons,
current.dpad,
current.left_x,
current.left_y,
current.right_x,
current.right_y,
255*8ms
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "CommonFramework/Globals.h"
#include "Controllers/ControllerSession.h"
#include "Controllers/KeyboardStateTracker.h"
#include "NintendoSwitch_VirtualControllerState.h"

namespace PokemonAutomation{
namespace NintendoSwitch{
Expand Down Expand Up @@ -54,6 +55,8 @@ class VirtualController{
ControllerSession& m_session;
const bool m_allow_commands_while_running;

std::map<Qt::Key, ControllerDeltas> m_mapping;

// Controller State
SpinLock m_state_lock;
KeyboardStateTracker m_state_tracker;
Expand Down
Loading

0 comments on commit 8165f57

Please sign in to comment.