mirror of
				https://git.h3cjp.net/H3cJP/citra.git
				synced 2025-10-29 22:07:38 +00:00 
			
		
		
		
	input_common: Revert deleted TAS functions
This commit is contained in:
		
							parent
							
								
									5f69fdbfcc
								
							
						
					
					
						commit
						61d9eb9f69
					
				|  | @ -127,7 +127,7 @@ void EmulatedController::LoadDevices() { | |||
|     // Initialize TAS devices
 | ||||
|     std::transform(tas_button_params.begin(), tas_button_params.end(), tas_button_devices.begin(), | ||||
|                    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>); | ||||
| } | ||||
| 
 | ||||
|  | @ -135,7 +135,7 @@ void EmulatedController::LoadTASParams() { | |||
|     const auto player_index = NpadIdTypeToIndex(npad_id_type); | ||||
|     Common::ParamPackage common_params{}; | ||||
|     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) { | ||||
|         param = common_params; | ||||
|     } | ||||
|  | @ -144,26 +144,26 @@ void EmulatedController::LoadTASParams() { | |||
|     } | ||||
| 
 | ||||
|     // 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::B].Set("button", 1 << 1); | ||||
|     tas_button_params[Settings::NativeButton::X].Set("button", 1 << 2); | ||||
|     tas_button_params[Settings::NativeButton::Y].Set("button", 1 << 3); | ||||
|     tas_button_params[Settings::NativeButton::LStick].Set("button", 1 << 4); | ||||
|     tas_button_params[Settings::NativeButton::RStick].Set("button", 1 << 5); | ||||
|     tas_button_params[Settings::NativeButton::L].Set("button", 1 << 6); | ||||
|     tas_button_params[Settings::NativeButton::R].Set("button", 1 << 7); | ||||
|     tas_button_params[Settings::NativeButton::ZL].Set("button", 1 << 8); | ||||
|     tas_button_params[Settings::NativeButton::ZR].Set("button", 1 << 9); | ||||
|     tas_button_params[Settings::NativeButton::Plus].Set("button", 1 << 10); | ||||
|     tas_button_params[Settings::NativeButton::Minus].Set("button", 1 << 11); | ||||
|     tas_button_params[Settings::NativeButton::DLeft].Set("button", 1 << 12); | ||||
|     tas_button_params[Settings::NativeButton::DUp].Set("button", 1 << 13); | ||||
|     tas_button_params[Settings::NativeButton::DRight].Set("button", 1 << 14); | ||||
|     tas_button_params[Settings::NativeButton::DDown].Set("button", 1 << 15); | ||||
|     tas_button_params[Settings::NativeButton::SL].Set("button", 1 << 16); | ||||
|     tas_button_params[Settings::NativeButton::SR].Set("button", 1 << 17); | ||||
|     tas_button_params[Settings::NativeButton::Home].Set("button", 1 << 18); | ||||
|     tas_button_params[Settings::NativeButton::Screenshot].Set("button", 1 << 19); | ||||
|     tas_button_params[Settings::NativeButton::A].Set("button", 0); | ||||
|     tas_button_params[Settings::NativeButton::B].Set("button", 1); | ||||
|     tas_button_params[Settings::NativeButton::X].Set("button", 2); | ||||
|     tas_button_params[Settings::NativeButton::Y].Set("button", 3); | ||||
|     tas_button_params[Settings::NativeButton::LStick].Set("button", 4); | ||||
|     tas_button_params[Settings::NativeButton::RStick].Set("button", 5); | ||||
|     tas_button_params[Settings::NativeButton::L].Set("button", 6); | ||||
|     tas_button_params[Settings::NativeButton::R].Set("button", 7); | ||||
|     tas_button_params[Settings::NativeButton::ZL].Set("button", 8); | ||||
|     tas_button_params[Settings::NativeButton::ZR].Set("button", 9); | ||||
|     tas_button_params[Settings::NativeButton::Plus].Set("button", 10); | ||||
|     tas_button_params[Settings::NativeButton::Minus].Set("button", 11); | ||||
|     tas_button_params[Settings::NativeButton::DLeft].Set("button", 12); | ||||
|     tas_button_params[Settings::NativeButton::DUp].Set("button", 13); | ||||
|     tas_button_params[Settings::NativeButton::DRight].Set("button", 14); | ||||
|     tas_button_params[Settings::NativeButton::DDown].Set("button", 15); | ||||
|     tas_button_params[Settings::NativeButton::SL].Set("button", 16); | ||||
|     tas_button_params[Settings::NativeButton::SR].Set("button", 17); | ||||
|     tas_button_params[Settings::NativeButton::Home].Set("button", 18); | ||||
|     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_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 = { | ||||
|         .buttons = buttons, | ||||
|         .l_axis = FlipAxisY(left_axis), | ||||
|  | @ -195,7 +195,7 @@ void Tas::UpdateThread() { | |||
|     } | ||||
|     if (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++) { | ||||
|             TASCommand command{}; | ||||
|             if (frame < commands[player_index].size()) { | ||||
|  | @ -207,8 +207,8 @@ void Tas::UpdateThread() { | |||
|                 .port = player_index, | ||||
|                 .pad = 0, | ||||
|             }; | ||||
|             for (std::size_t i = 0; i < sizeof(command.buttons); ++i) { | ||||
|                 const bool button_status = (command.buttons & (1U << i)) != 0; | ||||
|             for (std::size_t i = 0; i < sizeof(command.buttons) * 8; ++i) { | ||||
|                 const bool button_status = (command.buttons & (1LLU << i)) != 0; | ||||
|                 const int button = static_cast<int>(i); | ||||
|                 SetButton(identifier, button, button_status); | ||||
|             } | ||||
|  | @ -244,14 +244,14 @@ TasAnalog Tas::ReadCommandAxis(const std::string& line) const { | |||
|     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::string line; | ||||
|     u32 buttons = 0; | ||||
|     u64 buttons = 0; | ||||
|     while (std::getline(button_text, line, ';')) { | ||||
|         for (auto [text, tas_button] : text_to_tas_button) { | ||||
|             if (text == line) { | ||||
|                 buttons |= static_cast<u32>(tas_button); | ||||
|                 buttons |= static_cast<u64>(tas_button); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|  | @ -259,13 +259,14 @@ u32 Tas::ReadCommandButtons(const std::string& data) const { | |||
|     return buttons; | ||||
| } | ||||
| 
 | ||||
| std::string Tas::WriteCommandButtons(u32 buttons) const { | ||||
| std::string Tas::WriteCommandButtons(u64 buttons) const { | ||||
|     std::string returns = ""; | ||||
|     for (auto [text_button, tas_button] : text_to_tas_button) { | ||||
|         if ((buttons & static_cast<u32>(tas_button)) != 0) | ||||
|             returns += fmt::format("{};", text_button.substr(4)); | ||||
|         if ((buttons & static_cast<u64>(tas_button)) != 0) { | ||||
|             returns += fmt::format("{};", text_button); | ||||
|         } | ||||
|     } | ||||
|     return returns.empty() ? "NONE" : returns.substr(2); | ||||
|     return returns.empty() ? "NONE" : returns; | ||||
| } | ||||
| 
 | ||||
| std::string Tas::WriteCommandAxis(TasAnalog analog) const { | ||||
|  |  | |||
|  | @ -47,7 +47,7 @@ namespace InputCommon::TasInput { | |||
| 
 | ||||
| constexpr size_t PLAYER_NUMBER = 10; | ||||
| 
 | ||||
| enum class TasButton : u32 { | ||||
| enum class TasButton : u64 { | ||||
|     BUTTON_A = 1U << 0, | ||||
|     BUTTON_B = 1U << 1, | ||||
|     BUTTON_X = 1U << 2, | ||||
|  | @ -92,7 +92,7 @@ public: | |||
|      * @param left_axis: value of the left 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
 | ||||
|     void UpdateThread(); | ||||
|  | @ -129,7 +129,7 @@ public: | |||
| 
 | ||||
| private: | ||||
|     struct TASCommand { | ||||
|         u32 buttons{}; | ||||
|         u64 buttons{}; | ||||
|         TasAnalog l_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 | ||||
|      * specified in text_to_tas_button array | ||||
|      * @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 | ||||
|  | @ -174,11 +174,11 @@ private: | |||
|     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 | ||||
|      * @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 | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ | |||
| #include "core/frontend/framebuffer_layout.h" | ||||
| #include "input_common/drivers/keyboard.h" | ||||
| #include "input_common/drivers/mouse.h" | ||||
| #include "input_common/drivers/tas_input.h" | ||||
| #include "input_common/drivers/touch_screen.h" | ||||
| #include "input_common/main.h" | ||||
| #include "video_core/renderer_base.h" | ||||
|  |  | |||
|  | @ -7,11 +7,16 @@ | |||
| #include <QString> | ||||
| #include "common/settings.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/debugger/controller.h" | ||||
| 
 | ||||
| ControllerDialog::ControllerDialog(Core::System& system, QWidget* parent) | ||||
|     : QWidget(parent, Qt::Dialog) { | ||||
| ControllerDialog::ControllerDialog(Core::System& system_, | ||||
|                                    std::shared_ptr<InputCommon::InputSubsystem> input_subsystem_, | ||||
|                                    QWidget* parent) | ||||
|     : QWidget(parent, Qt::Dialog), system{system_}, input_subsystem{input_subsystem_} { | ||||
|     setObjectName(QStringLiteral("Controller")); | ||||
|     setWindowTitle(tr("Controller P1")); | ||||
|     resize(500, 350); | ||||
|  | @ -21,7 +26,7 @@ ControllerDialog::ControllerDialog(Core::System& system, QWidget* parent) | |||
|                    Qt::WindowMaximizeButtonHint); | ||||
| 
 | ||||
|     widget = new PlayerControlPreview(this); | ||||
|     widget->SetController(system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1)); | ||||
|     refreshConfiguration(); | ||||
|     QLayout* layout = new QVBoxLayout(this); | ||||
|     layout->setContentsMargins(0, 0, 0, 0); | ||||
|     layout->addWidget(widget); | ||||
|  | @ -34,6 +39,22 @@ ControllerDialog::ControllerDialog(Core::System& system, QWidget* parent) | |||
|     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() { | ||||
|     if (toggle_view_action == nullptr) { | ||||
|         toggle_view_action = new QAction(tr("&Controller P1"), this); | ||||
|  | @ -47,6 +68,10 @@ QAction* ControllerDialog::toggleViewAction() { | |||
| 
 | ||||
| void ControllerDialog::UnloadController() { | ||||
|     widget->UnloadController(); | ||||
|     if (is_controller_set) { | ||||
|         controller->DeleteCallback(callback_key); | ||||
|         is_controller_set = false; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ControllerDialog::showEvent(QShowEvent* ev) { | ||||
|  | @ -62,3 +87,32 @@ void ControllerDialog::hideEvent(QHideEvent* 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 PlayerControlPreview; | ||||
| 
 | ||||
| namespace InputCommon { | ||||
| class InputSubsystem; | ||||
| } | ||||
| 
 | ||||
| namespace Core { | ||||
| class System; | ||||
| } | ||||
| 
 | ||||
| namespace InputCommon { | ||||
| class InputSubsystem; | ||||
| namespace Core::HID { | ||||
| class EmulatedController; | ||||
| } | ||||
| 
 | ||||
| class ControllerDialog : public QWidget { | ||||
|     Q_OBJECT | ||||
| 
 | ||||
| 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.
 | ||||
|     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(); | ||||
| 
 | ||||
| protected: | ||||
|  | @ -36,6 +45,15 @@ protected: | |||
|     void hideEvent(QHideEvent* ev) override; | ||||
| 
 | ||||
| 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; | ||||
|     PlayerControlPreview* widget; | ||||
|     Core::System& system; | ||||
|     std::shared_ptr<InputCommon::InputSubsystem> input_subsystem; | ||||
| }; | ||||
|  |  | |||
|  | @ -925,7 +925,7 @@ void GMainWindow::InitializeDebugWidgets() { | |||
|     waitTreeWidget->hide(); | ||||
|     debug_menu->addAction(waitTreeWidget->toggleViewAction()); | ||||
| 
 | ||||
|     controller_dialog = new ControllerDialog(*system, this); | ||||
|     controller_dialog = new ControllerDialog(*system, input_subsystem, this); | ||||
|     controller_dialog->hide(); | ||||
|     debug_menu->addAction(controller_dialog->toggleViewAction()); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue