input_common: Revert deleted TAS functions
This commit is contained in:
parent
5f69fdbfcc
commit
61d9eb9f69
7 changed files with 122 additions and 48 deletions
|
@ -127,7 +127,7 @@ void EmulatedController::LoadDevices() {
|
||||||
// Initialize TAS devices
|
// Initialize TAS devices
|
||||||
std::transform(tas_button_params.begin(), tas_button_params.end(), tas_button_devices.begin(),
|
std::transform(tas_button_params.begin(), tas_button_params.end(), tas_button_devices.begin(),
|
||||||
Input::CreateDevice<Input::InputDevice>);
|
Input::CreateDevice<Input::InputDevice>);
|
||||||
std::transform(tas_stick_params.begin(), tas_stick_params.begin(), tas_stick_devices.begin(),
|
std::transform(tas_stick_params.begin(), tas_stick_params.end(), tas_stick_devices.begin(),
|
||||||
Input::CreateDevice<Input::InputDevice>);
|
Input::CreateDevice<Input::InputDevice>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ void EmulatedController::LoadTASParams() {
|
||||||
const auto player_index = NpadIdTypeToIndex(npad_id_type);
|
const auto player_index = NpadIdTypeToIndex(npad_id_type);
|
||||||
Common::ParamPackage common_params{};
|
Common::ParamPackage common_params{};
|
||||||
common_params.Set("engine", "tas");
|
common_params.Set("engine", "tas");
|
||||||
common_params.Set("pad", static_cast<int>(player_index));
|
common_params.Set("port", static_cast<int>(player_index));
|
||||||
for (auto& param : tas_button_params) {
|
for (auto& param : tas_button_params) {
|
||||||
param = common_params;
|
param = common_params;
|
||||||
}
|
}
|
||||||
|
@ -144,26 +144,26 @@ void EmulatedController::LoadTASParams() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(german77): Replace this with an input profile or something better
|
// TODO(german77): Replace this with an input profile or something better
|
||||||
tas_button_params[Settings::NativeButton::A].Set("button", 1 << 0);
|
tas_button_params[Settings::NativeButton::A].Set("button", 0);
|
||||||
tas_button_params[Settings::NativeButton::B].Set("button", 1 << 1);
|
tas_button_params[Settings::NativeButton::B].Set("button", 1);
|
||||||
tas_button_params[Settings::NativeButton::X].Set("button", 1 << 2);
|
tas_button_params[Settings::NativeButton::X].Set("button", 2);
|
||||||
tas_button_params[Settings::NativeButton::Y].Set("button", 1 << 3);
|
tas_button_params[Settings::NativeButton::Y].Set("button", 3);
|
||||||
tas_button_params[Settings::NativeButton::LStick].Set("button", 1 << 4);
|
tas_button_params[Settings::NativeButton::LStick].Set("button", 4);
|
||||||
tas_button_params[Settings::NativeButton::RStick].Set("button", 1 << 5);
|
tas_button_params[Settings::NativeButton::RStick].Set("button", 5);
|
||||||
tas_button_params[Settings::NativeButton::L].Set("button", 1 << 6);
|
tas_button_params[Settings::NativeButton::L].Set("button", 6);
|
||||||
tas_button_params[Settings::NativeButton::R].Set("button", 1 << 7);
|
tas_button_params[Settings::NativeButton::R].Set("button", 7);
|
||||||
tas_button_params[Settings::NativeButton::ZL].Set("button", 1 << 8);
|
tas_button_params[Settings::NativeButton::ZL].Set("button", 8);
|
||||||
tas_button_params[Settings::NativeButton::ZR].Set("button", 1 << 9);
|
tas_button_params[Settings::NativeButton::ZR].Set("button", 9);
|
||||||
tas_button_params[Settings::NativeButton::Plus].Set("button", 1 << 10);
|
tas_button_params[Settings::NativeButton::Plus].Set("button", 10);
|
||||||
tas_button_params[Settings::NativeButton::Minus].Set("button", 1 << 11);
|
tas_button_params[Settings::NativeButton::Minus].Set("button", 11);
|
||||||
tas_button_params[Settings::NativeButton::DLeft].Set("button", 1 << 12);
|
tas_button_params[Settings::NativeButton::DLeft].Set("button", 12);
|
||||||
tas_button_params[Settings::NativeButton::DUp].Set("button", 1 << 13);
|
tas_button_params[Settings::NativeButton::DUp].Set("button", 13);
|
||||||
tas_button_params[Settings::NativeButton::DRight].Set("button", 1 << 14);
|
tas_button_params[Settings::NativeButton::DRight].Set("button", 14);
|
||||||
tas_button_params[Settings::NativeButton::DDown].Set("button", 1 << 15);
|
tas_button_params[Settings::NativeButton::DDown].Set("button", 15);
|
||||||
tas_button_params[Settings::NativeButton::SL].Set("button", 1 << 16);
|
tas_button_params[Settings::NativeButton::SL].Set("button", 16);
|
||||||
tas_button_params[Settings::NativeButton::SR].Set("button", 1 << 17);
|
tas_button_params[Settings::NativeButton::SR].Set("button", 17);
|
||||||
tas_button_params[Settings::NativeButton::Home].Set("button", 1 << 18);
|
tas_button_params[Settings::NativeButton::Home].Set("button", 18);
|
||||||
tas_button_params[Settings::NativeButton::Screenshot].Set("button", 1 << 19);
|
tas_button_params[Settings::NativeButton::Screenshot].Set("button", 19);
|
||||||
|
|
||||||
tas_stick_params[Settings::NativeAnalog::LStick].Set("axis_x", 0);
|
tas_stick_params[Settings::NativeAnalog::LStick].Set("axis_x", 0);
|
||||||
tas_stick_params[Settings::NativeAnalog::LStick].Set("axis_y", 1);
|
tas_stick_params[Settings::NativeAnalog::LStick].Set("axis_y", 1);
|
||||||
|
|
|
@ -141,7 +141,7 @@ void Tas::WriteTasFile(std::u8string file_name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tas::RecordInput(u32 buttons, TasAnalog left_axis, TasAnalog right_axis) {
|
void Tas::RecordInput(u64 buttons, TasAnalog left_axis, TasAnalog right_axis) {
|
||||||
last_input = {
|
last_input = {
|
||||||
.buttons = buttons,
|
.buttons = buttons,
|
||||||
.l_axis = FlipAxisY(left_axis),
|
.l_axis = FlipAxisY(left_axis),
|
||||||
|
@ -195,7 +195,7 @@ void Tas::UpdateThread() {
|
||||||
}
|
}
|
||||||
if (current_command < script_length) {
|
if (current_command < script_length) {
|
||||||
LOG_DEBUG(Input, "Playing TAS {}/{}", current_command, script_length);
|
LOG_DEBUG(Input, "Playing TAS {}/{}", current_command, script_length);
|
||||||
size_t frame = current_command++;
|
const size_t frame = current_command++;
|
||||||
for (size_t player_index = 0; player_index < commands.size(); player_index++) {
|
for (size_t player_index = 0; player_index < commands.size(); player_index++) {
|
||||||
TASCommand command{};
|
TASCommand command{};
|
||||||
if (frame < commands[player_index].size()) {
|
if (frame < commands[player_index].size()) {
|
||||||
|
@ -207,8 +207,8 @@ void Tas::UpdateThread() {
|
||||||
.port = player_index,
|
.port = player_index,
|
||||||
.pad = 0,
|
.pad = 0,
|
||||||
};
|
};
|
||||||
for (std::size_t i = 0; i < sizeof(command.buttons); ++i) {
|
for (std::size_t i = 0; i < sizeof(command.buttons) * 8; ++i) {
|
||||||
const bool button_status = (command.buttons & (1U << i)) != 0;
|
const bool button_status = (command.buttons & (1LLU << i)) != 0;
|
||||||
const int button = static_cast<int>(i);
|
const int button = static_cast<int>(i);
|
||||||
SetButton(identifier, button, button_status);
|
SetButton(identifier, button, button_status);
|
||||||
}
|
}
|
||||||
|
@ -244,14 +244,14 @@ TasAnalog Tas::ReadCommandAxis(const std::string& line) const {
|
||||||
return {x, y};
|
return {x, y};
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Tas::ReadCommandButtons(const std::string& data) const {
|
u64 Tas::ReadCommandButtons(const std::string& data) const {
|
||||||
std::stringstream button_text(data);
|
std::stringstream button_text(data);
|
||||||
std::string line;
|
std::string line;
|
||||||
u32 buttons = 0;
|
u64 buttons = 0;
|
||||||
while (std::getline(button_text, line, ';')) {
|
while (std::getline(button_text, line, ';')) {
|
||||||
for (auto [text, tas_button] : text_to_tas_button) {
|
for (auto [text, tas_button] : text_to_tas_button) {
|
||||||
if (text == line) {
|
if (text == line) {
|
||||||
buttons |= static_cast<u32>(tas_button);
|
buttons |= static_cast<u64>(tas_button);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,13 +259,14 @@ u32 Tas::ReadCommandButtons(const std::string& data) const {
|
||||||
return buttons;
|
return buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Tas::WriteCommandButtons(u32 buttons) const {
|
std::string Tas::WriteCommandButtons(u64 buttons) const {
|
||||||
std::string returns = "";
|
std::string returns = "";
|
||||||
for (auto [text_button, tas_button] : text_to_tas_button) {
|
for (auto [text_button, tas_button] : text_to_tas_button) {
|
||||||
if ((buttons & static_cast<u32>(tas_button)) != 0)
|
if ((buttons & static_cast<u64>(tas_button)) != 0) {
|
||||||
returns += fmt::format("{};", text_button.substr(4));
|
returns += fmt::format("{};", text_button);
|
||||||
}
|
}
|
||||||
return returns.empty() ? "NONE" : returns.substr(2);
|
}
|
||||||
|
return returns.empty() ? "NONE" : returns;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Tas::WriteCommandAxis(TasAnalog analog) const {
|
std::string Tas::WriteCommandAxis(TasAnalog analog) const {
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace InputCommon::TasInput {
|
||||||
|
|
||||||
constexpr size_t PLAYER_NUMBER = 10;
|
constexpr size_t PLAYER_NUMBER = 10;
|
||||||
|
|
||||||
enum class TasButton : u32 {
|
enum class TasButton : u64 {
|
||||||
BUTTON_A = 1U << 0,
|
BUTTON_A = 1U << 0,
|
||||||
BUTTON_B = 1U << 1,
|
BUTTON_B = 1U << 1,
|
||||||
BUTTON_X = 1U << 2,
|
BUTTON_X = 1U << 2,
|
||||||
|
@ -92,7 +92,7 @@ public:
|
||||||
* @param left_axis: value of the left axis
|
* @param left_axis: value of the left axis
|
||||||
* @param right_axis: value of the right axis
|
* @param right_axis: value of the right axis
|
||||||
*/
|
*/
|
||||||
void RecordInput(u32 buttons, TasAnalog left_axis, TasAnalog right_axis);
|
void RecordInput(u64 buttons, TasAnalog left_axis, TasAnalog right_axis);
|
||||||
|
|
||||||
// Main loop that records or executes input
|
// Main loop that records or executes input
|
||||||
void UpdateThread();
|
void UpdateThread();
|
||||||
|
@ -129,7 +129,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct TASCommand {
|
struct TASCommand {
|
||||||
u32 buttons{};
|
u64 buttons{};
|
||||||
TasAnalog l_axis{};
|
TasAnalog l_axis{};
|
||||||
TasAnalog r_axis{};
|
TasAnalog r_axis{};
|
||||||
};
|
};
|
||||||
|
@ -164,9 +164,9 @@ private:
|
||||||
* Parses a string containing the button values. Each button is represented by it's text format
|
* Parses a string containing the button values. Each button is represented by it's text format
|
||||||
* specified in text_to_tas_button array
|
* specified in text_to_tas_button array
|
||||||
* @param line: string containing button name with the following format "a;b;c;d..."
|
* @param line: string containing button name with the following format "a;b;c;d..."
|
||||||
* @return Returns a u32 with each bit representing the status of a button
|
* @return Returns a u64 with each bit representing the status of a button
|
||||||
*/
|
*/
|
||||||
u32 ReadCommandButtons(const std::string& line) const;
|
u64 ReadCommandButtons(const std::string& line) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset state of all players
|
* Reset state of all players
|
||||||
|
@ -174,11 +174,11 @@ private:
|
||||||
void ClearInput();
|
void ClearInput();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts an u32 containing the button status into the text equivalent
|
* Converts an u64 containing the button status into the text equivalent
|
||||||
* @param buttons: bitfield with the status of the buttons
|
* @param buttons: bitfield with the status of the buttons
|
||||||
* @return Returns a string with the name of the buttons to be written to the file
|
* @return Returns a string with the name of the buttons to be written to the file
|
||||||
*/
|
*/
|
||||||
std::string WriteCommandButtons(u32 buttons) const;
|
std::string WriteCommandButtons(u64 buttons) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts an TAS analog object containing the axis status into the text equivalent
|
* Converts an TAS analog object containing the axis status into the text equivalent
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "core/frontend/framebuffer_layout.h"
|
#include "core/frontend/framebuffer_layout.h"
|
||||||
#include "input_common/drivers/keyboard.h"
|
#include "input_common/drivers/keyboard.h"
|
||||||
#include "input_common/drivers/mouse.h"
|
#include "input_common/drivers/mouse.h"
|
||||||
|
#include "input_common/drivers/tas_input.h"
|
||||||
#include "input_common/drivers/touch_screen.h"
|
#include "input_common/drivers/touch_screen.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
|
|
|
@ -7,11 +7,16 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/hid/emulated_controller.h"
|
||||||
|
#include "input_common/drivers/tas_input.h"
|
||||||
|
#include "input_common/main.h"
|
||||||
#include "yuzu/configuration/configure_input_player_widget.h"
|
#include "yuzu/configuration/configure_input_player_widget.h"
|
||||||
#include "yuzu/debugger/controller.h"
|
#include "yuzu/debugger/controller.h"
|
||||||
|
|
||||||
ControllerDialog::ControllerDialog(Core::System& system, QWidget* parent)
|
ControllerDialog::ControllerDialog(Core::System& system_,
|
||||||
: QWidget(parent, Qt::Dialog) {
|
std::shared_ptr<InputCommon::InputSubsystem> input_subsystem_,
|
||||||
|
QWidget* parent)
|
||||||
|
: QWidget(parent, Qt::Dialog), system{system_}, input_subsystem{input_subsystem_} {
|
||||||
setObjectName(QStringLiteral("Controller"));
|
setObjectName(QStringLiteral("Controller"));
|
||||||
setWindowTitle(tr("Controller P1"));
|
setWindowTitle(tr("Controller P1"));
|
||||||
resize(500, 350);
|
resize(500, 350);
|
||||||
|
@ -21,7 +26,7 @@ ControllerDialog::ControllerDialog(Core::System& system, QWidget* parent)
|
||||||
Qt::WindowMaximizeButtonHint);
|
Qt::WindowMaximizeButtonHint);
|
||||||
|
|
||||||
widget = new PlayerControlPreview(this);
|
widget = new PlayerControlPreview(this);
|
||||||
widget->SetController(system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1));
|
refreshConfiguration();
|
||||||
QLayout* layout = new QVBoxLayout(this);
|
QLayout* layout = new QVBoxLayout(this);
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
layout->addWidget(widget);
|
layout->addWidget(widget);
|
||||||
|
@ -34,6 +39,22 @@ ControllerDialog::ControllerDialog(Core::System& system, QWidget* parent)
|
||||||
widget->setFocus();
|
widget->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ControllerDialog::refreshConfiguration() {
|
||||||
|
UnloadController();
|
||||||
|
auto* player_1 = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
|
||||||
|
auto* handheld = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
||||||
|
// Display the correct controller
|
||||||
|
controller = handheld->IsConnected() ? handheld : player_1;
|
||||||
|
|
||||||
|
Core::HID::ControllerUpdateCallback engine_callback{
|
||||||
|
.on_change = [this](Core::HID::ControllerTriggerType type) { ControllerUpdate(type); },
|
||||||
|
.is_npad_service = true,
|
||||||
|
};
|
||||||
|
callback_key = controller->SetCallback(engine_callback);
|
||||||
|
widget->SetController(controller);
|
||||||
|
is_controller_set = true;
|
||||||
|
}
|
||||||
|
|
||||||
QAction* ControllerDialog::toggleViewAction() {
|
QAction* ControllerDialog::toggleViewAction() {
|
||||||
if (toggle_view_action == nullptr) {
|
if (toggle_view_action == nullptr) {
|
||||||
toggle_view_action = new QAction(tr("&Controller P1"), this);
|
toggle_view_action = new QAction(tr("&Controller P1"), this);
|
||||||
|
@ -47,6 +68,10 @@ QAction* ControllerDialog::toggleViewAction() {
|
||||||
|
|
||||||
void ControllerDialog::UnloadController() {
|
void ControllerDialog::UnloadController() {
|
||||||
widget->UnloadController();
|
widget->UnloadController();
|
||||||
|
if (is_controller_set) {
|
||||||
|
controller->DeleteCallback(callback_key);
|
||||||
|
is_controller_set = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerDialog::showEvent(QShowEvent* ev) {
|
void ControllerDialog::showEvent(QShowEvent* ev) {
|
||||||
|
@ -62,3 +87,32 @@ void ControllerDialog::hideEvent(QHideEvent* ev) {
|
||||||
}
|
}
|
||||||
QWidget::hideEvent(ev);
|
QWidget::hideEvent(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ControllerDialog::ControllerUpdate(Core::HID::ControllerTriggerType type) {
|
||||||
|
// TODO(german77): Remove TAS from here
|
||||||
|
switch (type) {
|
||||||
|
case Core::HID::ControllerTriggerType::Button:
|
||||||
|
case Core::HID::ControllerTriggerType::Stick: {
|
||||||
|
const auto buttons_values = controller->GetButtonsValues();
|
||||||
|
const auto stick_values = controller->GetSticksValues();
|
||||||
|
u64 buttons = 0;
|
||||||
|
std::size_t index = 0;
|
||||||
|
for (const auto& button : buttons_values) {
|
||||||
|
buttons |= button.value ? 1LLU << index : 0;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
const InputCommon::TasInput::TasAnalog left_axis = {
|
||||||
|
.x = stick_values[Settings::NativeAnalog::LStick].x.value,
|
||||||
|
.y = stick_values[Settings::NativeAnalog::LStick].y.value,
|
||||||
|
};
|
||||||
|
const InputCommon::TasInput::TasAnalog right_axis = {
|
||||||
|
.x = stick_values[Settings::NativeAnalog::RStick].x.value,
|
||||||
|
.y = stick_values[Settings::NativeAnalog::RStick].y.value,
|
||||||
|
};
|
||||||
|
input_subsystem->GetTas()->RecordInput(buttons, left_axis, right_axis);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -11,24 +11,33 @@ class QHideEvent;
|
||||||
class QShowEvent;
|
class QShowEvent;
|
||||||
class PlayerControlPreview;
|
class PlayerControlPreview;
|
||||||
|
|
||||||
|
namespace InputCommon {
|
||||||
|
class InputSubsystem;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class System;
|
class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace InputCommon {
|
namespace Core::HID {
|
||||||
class InputSubsystem;
|
class EmulatedController;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ControllerDialog : public QWidget {
|
class ControllerDialog : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ControllerDialog(Core::System& system, QWidget* parent = nullptr);
|
explicit ControllerDialog(Core::System& system_,
|
||||||
|
std::shared_ptr<InputCommon::InputSubsystem> input_subsystem_,
|
||||||
|
QWidget* parent = nullptr);
|
||||||
|
|
||||||
/// Returns a QAction that can be used to toggle visibility of this dialog.
|
/// Returns a QAction that can be used to toggle visibility of this dialog.
|
||||||
QAction* toggleViewAction();
|
QAction* toggleViewAction();
|
||||||
|
|
||||||
// Disables events from the emulated controller
|
/// Reloads the widget to apply any changes in the configuration
|
||||||
|
void refreshConfiguration();
|
||||||
|
|
||||||
|
/// Disables events from the emulated controller
|
||||||
void UnloadController();
|
void UnloadController();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -36,6 +45,15 @@ protected:
|
||||||
void hideEvent(QHideEvent* ev) override;
|
void hideEvent(QHideEvent* ev) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// Redirects input from the widget to the TAS driver
|
||||||
|
void ControllerUpdate(Core::HID::ControllerTriggerType type);
|
||||||
|
|
||||||
|
int callback_key;
|
||||||
|
bool is_controller_set{};
|
||||||
|
Core::HID::EmulatedController* controller;
|
||||||
|
|
||||||
QAction* toggle_view_action = nullptr;
|
QAction* toggle_view_action = nullptr;
|
||||||
PlayerControlPreview* widget;
|
PlayerControlPreview* widget;
|
||||||
|
Core::System& system;
|
||||||
|
std::shared_ptr<InputCommon::InputSubsystem> input_subsystem;
|
||||||
};
|
};
|
||||||
|
|
|
@ -925,7 +925,7 @@ void GMainWindow::InitializeDebugWidgets() {
|
||||||
waitTreeWidget->hide();
|
waitTreeWidget->hide();
|
||||||
debug_menu->addAction(waitTreeWidget->toggleViewAction());
|
debug_menu->addAction(waitTreeWidget->toggleViewAction());
|
||||||
|
|
||||||
controller_dialog = new ControllerDialog(*system, this);
|
controller_dialog = new ControllerDialog(*system, input_subsystem, this);
|
||||||
controller_dialog->hide();
|
controller_dialog->hide();
|
||||||
debug_menu->addAction(controller_dialog->toggleViewAction());
|
debug_menu->addAction(controller_dialog->toggleViewAction());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue