From 395e9a449d338e56ade9ea88ffeed297a7d86b10 Mon Sep 17 00:00:00 2001 From: german77 Date: Mon, 20 Sep 2021 17:22:07 -0500 Subject: input_common: Rewrite gc_adapter --- src/input_common/drivers/tas_input.h | 200 +++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 src/input_common/drivers/tas_input.h (limited to 'src/input_common/drivers/tas_input.h') diff --git a/src/input_common/drivers/tas_input.h b/src/input_common/drivers/tas_input.h new file mode 100644 index 000000000..9fadc118b --- /dev/null +++ b/src/input_common/drivers/tas_input.h @@ -0,0 +1,200 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include + +#include "common/common_types.h" +#include "common/settings_input.h" +#include "input_common/input_engine.h" +#include "input_common/main.h" + +/* +To play back TAS scripts on Yuzu, select the folder with scripts in the configuration menu below +Tools -> Configure TAS. The file itself has normal text format and has to be called script0-1.txt +for controller 1, script0-2.txt for controller 2 and so forth (with max. 8 players). + +A script file has the same format as TAS-nx uses, so final files will look like this: + +1 KEY_B 0;0 0;0 +6 KEY_ZL 0;0 0;0 +41 KEY_ZL;KEY_Y 0;0 0;0 +43 KEY_X;KEY_A 32767;0 0;0 +44 KEY_A 32767;0 0;0 +45 KEY_A 32767;0 0;0 +46 KEY_A 32767;0 0;0 +47 KEY_A 32767;0 0;0 + +After placing the file at the correct location, it can be read into Yuzu with the (default) hotkey +CTRL+F6 (refresh). In the bottom left corner, it will display the amount of frames the script file +has. Playback can be started or stopped using CTRL+F5. + +However, for playback to actually work, the correct input device has to be selected: In the Controls +menu, select TAS from the device list for the controller that the script should be played on. + +Recording a new script file is really simple: Just make sure that the proper device (not TAS) is +connected on P1, and press CTRL+F7 to start recording. When done, just press the same keystroke +again (CTRL+F7). The new script will be saved at the location previously selected, as the filename +record.txt. + +For debugging purposes, the common controller debugger can be used (View -> Debugging -> Controller +P1). +*/ + +namespace InputCommon::TasInput { + +constexpr size_t PLAYER_NUMBER = 10; + +enum class TasButton : u32 { + BUTTON_A = 1U << 0, + BUTTON_B = 1U << 1, + BUTTON_X = 1U << 2, + BUTTON_Y = 1U << 3, + STICK_L = 1U << 4, + STICK_R = 1U << 5, + TRIGGER_L = 1U << 6, + TRIGGER_R = 1U << 7, + TRIGGER_ZL = 1U << 8, + TRIGGER_ZR = 1U << 9, + BUTTON_PLUS = 1U << 10, + BUTTON_MINUS = 1U << 11, + BUTTON_LEFT = 1U << 12, + BUTTON_UP = 1U << 13, + BUTTON_RIGHT = 1U << 14, + BUTTON_DOWN = 1U << 15, + BUTTON_SL = 1U << 16, + BUTTON_SR = 1U << 17, + BUTTON_HOME = 1U << 18, + BUTTON_CAPTURE = 1U << 19, +}; + +struct TasAnalog { + float x{}; + float y{}; +}; + +enum class TasState { + Running, + Recording, + Stopped, +}; + +class Tas final : public InputCommon::InputEngine { +public: + explicit Tas(const std::string input_engine_); + ~Tas(); + + /** + * Changes the input status that will be stored in each frame + * @param buttons: bitfield with the status of the buttons + * @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); + + // Main loop that records or executes input + void UpdateThread(); + + // Sets the flag to start or stop the TAS command excecution and swaps controllers profiles + void StartStop(); + + // Stop the TAS and reverts any controller profile + void Stop(); + + // Sets the flag to reload the file and start from the begining in the next update + void Reset(); + + /** + * Sets the flag to enable or disable recording of inputs + * @return Returns true if the current recording status is enabled + */ + bool Record(); + + /** + * Saves contents of record_commands on a file + * @param overwrite_file: Indicates if player 1 should be overwritten + */ + void SaveRecording(bool overwrite_file); + + /** + * Returns the current status values of TAS playback/recording + * @return Tuple of + * TasState indicating the current state out of Running ; + * Current playback progress ; + * Total length of script file currently loaded or being recorded + */ + std::tuple GetStatus() const; + +private: + struct TASCommand { + u32 buttons{}; + TasAnalog l_axis{}; + TasAnalog r_axis{}; + }; + + /// Loads TAS files from all players + void LoadTasFiles(); + + /** Loads TAS file from the specified player + * @param player_index: player number where data is going to be stored + */ + void LoadTasFile(size_t player_index); + + /** Writes a TAS file from the recorded commands + * @param file_name: name of the file to be written + */ + void WriteTasFile(std::u8string file_name); + + /** Inverts the Y axis polarity + * @param old: value of the axis + * @return new value of the axis + */ + TasAnalog FlipAxisY(TasAnalog old); + + /** + * Parses a string containing the axis values. X and Y have a range from -32767 to 32767 + * @param line: string containing axis values with the following format "x;y" + * @return Returns a TAS analog object with axis values with range from -1.0 to 1.0 + */ + TasAnalog ReadCommandAxis(const std::string& line) const; + + /** + * 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 + */ + u32 ReadCommandButtons(const std::string& line) const; + + /** + * Reset state of all players + */ + void ClearInput(); + + /** + * Converts an u32 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; + + /** + * Converts an TAS analog object containing the axis status into the text equivalent + * @param data: value of the axis + * @return A string with the value of the axis to be written to the file + */ + std::string WriteCommandAxis(TasAnalog data) const; + + size_t script_length{0}; + bool is_old_input_saved{false}; + bool is_recording{false}; + bool is_running{false}; + bool needs_reset{false}; + std::array, PLAYER_NUMBER> commands{}; + std::vector record_commands{}; + size_t current_command{0}; + TASCommand last_input{}; // only used for recording +}; +} // namespace InputCommon::TasInput -- cgit v1.2.3 From 61d9eb9f690d6afe141f24ba75c99b54e122dfa3 Mon Sep 17 00:00:00 2001 From: german77 Date: Sat, 30 Oct 2021 20:16:10 -0500 Subject: input_common: Revert deleted TAS functions --- src/input_common/drivers/tas_input.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/input_common/drivers/tas_input.h') diff --git a/src/input_common/drivers/tas_input.h b/src/input_common/drivers/tas_input.h index 9fadc118b..5f5c3267c 100644 --- a/src/input_common/drivers/tas_input.h +++ b/src/input_common/drivers/tas_input.h @@ -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 -- cgit v1.2.3 From 730f07830247cfcdc551c253d30c6717fc16316c Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 31 Oct 2021 10:41:44 -0500 Subject: settings: Fix Debug controller type options --- src/input_common/drivers/tas_input.h | 1 - 1 file changed, 1 deletion(-) (limited to 'src/input_common/drivers/tas_input.h') diff --git a/src/input_common/drivers/tas_input.h b/src/input_common/drivers/tas_input.h index 5f5c3267c..82dc9d616 100644 --- a/src/input_common/drivers/tas_input.h +++ b/src/input_common/drivers/tas_input.h @@ -188,7 +188,6 @@ private: std::string WriteCommandAxis(TasAnalog data) const; size_t script_length{0}; - bool is_old_input_saved{false}; bool is_recording{false}; bool is_running{false}; bool needs_reset{false}; -- cgit v1.2.3 From 157e0b85fdd805e02d234dccf1ce578e3159adee Mon Sep 17 00:00:00 2001 From: german77 Date: Tue, 2 Nov 2021 22:50:30 -0600 Subject: core/hid: Prevent Emulated controller from flapping with multiple inputs devices --- src/input_common/drivers/tas_input.h | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'src/input_common/drivers/tas_input.h') diff --git a/src/input_common/drivers/tas_input.h b/src/input_common/drivers/tas_input.h index 82dc9d616..bfb37a638 100644 --- a/src/input_common/drivers/tas_input.h +++ b/src/input_common/drivers/tas_input.h @@ -138,21 +138,16 @@ private: void LoadTasFiles(); /** Loads TAS file from the specified player - * @param player_index: player number where data is going to be stored + * @param player_index: player number to save the script + * @param file_index: script number of the file */ - void LoadTasFile(size_t player_index); + void LoadTasFile(size_t player_index, size_t file_index); /** Writes a TAS file from the recorded commands * @param file_name: name of the file to be written */ void WriteTasFile(std::u8string file_name); - /** Inverts the Y axis polarity - * @param old: value of the axis - * @return new value of the axis - */ - TasAnalog FlipAxisY(TasAnalog old); - /** * Parses a string containing the axis values. X and Y have a range from -32767 to 32767 * @param line: string containing axis values with the following format "x;y" -- cgit v1.2.3 From 42949738f2c01a4125a9a385c9100240181153ec Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 14 Nov 2021 21:56:54 -0600 Subject: kraken: Address comments from review Fix compiler bug --- src/input_common/drivers/tas_input.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/input_common/drivers/tas_input.h') diff --git a/src/input_common/drivers/tas_input.h b/src/input_common/drivers/tas_input.h index bfb37a638..c95a130fc 100644 --- a/src/input_common/drivers/tas_input.h +++ b/src/input_common/drivers/tas_input.h @@ -83,7 +83,7 @@ enum class TasState { class Tas final : public InputCommon::InputEngine { public: - explicit Tas(const std::string input_engine_); + explicit Tas(const std::string& input_engine_); ~Tas(); /** -- cgit v1.2.3 From 2b92d22bda767c7c723935c357bea474f8e2d2f8 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 13 Dec 2021 09:05:23 -0500 Subject: input_engine: std::move engine name where applicable We can allow the name to be moved into, allowing allocations to be avoided. --- src/input_common/drivers/tas_input.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/input_common/drivers/tas_input.h') diff --git a/src/input_common/drivers/tas_input.h b/src/input_common/drivers/tas_input.h index c95a130fc..9a7f98727 100644 --- a/src/input_common/drivers/tas_input.h +++ b/src/input_common/drivers/tas_input.h @@ -81,10 +81,10 @@ enum class TasState { Stopped, }; -class Tas final : public InputCommon::InputEngine { +class Tas final : public InputEngine { public: - explicit Tas(const std::string& input_engine_); - ~Tas(); + explicit Tas(std::string input_engine_); + ~Tas() override; /** * Changes the input status that will be stored in each frame -- cgit v1.2.3 From c126b0718ca4ffff463c4462ca38f61019df4acf Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 13 Dec 2021 10:41:30 -0500 Subject: tas_input: Make TasAxes enum an enum class Prevents these values from potentially clashing with anything in other headers. --- src/input_common/drivers/tas_input.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/input_common/drivers/tas_input.h') diff --git a/src/input_common/drivers/tas_input.h b/src/input_common/drivers/tas_input.h index c95a130fc..c44c39da9 100644 --- a/src/input_common/drivers/tas_input.h +++ b/src/input_common/drivers/tas_input.h @@ -128,6 +128,8 @@ public: std::tuple GetStatus() const; private: + enum class TasAxis : u8; + struct TASCommand { u64 buttons{}; TasAnalog l_axis{}; @@ -182,6 +184,9 @@ private: */ std::string WriteCommandAxis(TasAnalog data) const; + /// Sets an axis for a particular pad to the given value. + void SetTasAxis(const PadIdentifier& identifier, TasAxis axis, f32 value); + size_t script_length{0}; bool is_recording{false}; bool is_running{false}; -- cgit v1.2.3 From d52ad96ce348656b2ea7de8b8a85badfa86d2860 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 13 Dec 2021 10:49:06 -0500 Subject: tas_input: Amend -Wdocumentation warnings Parameters shouldn't have the colon by their name. --- src/input_common/drivers/tas_input.h | 48 +++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 23 deletions(-) (limited to 'src/input_common/drivers/tas_input.h') diff --git a/src/input_common/drivers/tas_input.h b/src/input_common/drivers/tas_input.h index c44c39da9..7c2c4a21b 100644 --- a/src/input_common/drivers/tas_input.h +++ b/src/input_common/drivers/tas_input.h @@ -88,39 +88,39 @@ public: /** * Changes the input status that will be stored in each frame - * @param buttons: bitfield with the status of the buttons - * @param left_axis: value of the left axis - * @param right_axis: value of the right axis + * @param buttons Bitfield with the status of the buttons + * @param left_axis Value of the left axis + * @param right_axis Value of the right axis */ void RecordInput(u64 buttons, TasAnalog left_axis, TasAnalog right_axis); // Main loop that records or executes input void UpdateThread(); - // Sets the flag to start or stop the TAS command excecution and swaps controllers profiles + // Sets the flag to start or stop the TAS command execution and swaps controllers profiles void StartStop(); - // Stop the TAS and reverts any controller profile + // Stop the TAS and reverts any controller profile void Stop(); - // Sets the flag to reload the file and start from the begining in the next update + // Sets the flag to reload the file and start from the beginning in the next update void Reset(); /** * Sets the flag to enable or disable recording of inputs - * @return Returns true if the current recording status is enabled + * @returns true if the current recording status is enabled */ bool Record(); /** * Saves contents of record_commands on a file - * @param overwrite_file: Indicates if player 1 should be overwritten + * @param overwrite_file Indicates if player 1 should be overwritten */ void SaveRecording(bool overwrite_file); /** * Returns the current status values of TAS playback/recording - * @return Tuple of + * @returns A Tuple of * TasState indicating the current state out of Running ; * Current playback progress ; * Total length of script file currently loaded or being recorded @@ -139,29 +139,31 @@ private: /// Loads TAS files from all players void LoadTasFiles(); - /** Loads TAS file from the specified player - * @param player_index: player number to save the script - * @param file_index: script number of the file + /** + * Loads TAS file from the specified player + * @param player_index Player number to save the script + * @param file_index Script number of the file */ void LoadTasFile(size_t player_index, size_t file_index); - /** Writes a TAS file from the recorded commands - * @param file_name: name of the file to be written + /** + * Writes a TAS file from the recorded commands + * @param file_name Name of the file to be written */ void WriteTasFile(std::u8string file_name); /** * Parses a string containing the axis values. X and Y have a range from -32767 to 32767 - * @param line: string containing axis values with the following format "x;y" - * @return Returns a TAS analog object with axis values with range from -1.0 to 1.0 + * @param line String containing axis values with the following format "x;y" + * @returns A TAS analog object with axis values with range from -1.0 to 1.0 */ TasAnalog ReadCommandAxis(const std::string& line) const; /** * 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 u64 with each bit representing the status of a button + * @param line string containing button name with the following format "a;b;c;d..." + * @returns A u64 with each bit representing the status of a button */ u64 ReadCommandButtons(const std::string& line) const; @@ -172,17 +174,17 @@ private: /** * 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 + * @param buttons Bitfield with the status of the buttons + * @returns A string with the name of the buttons to be written to the file */ std::string WriteCommandButtons(u64 buttons) const; /** * Converts an TAS analog object containing the axis status into the text equivalent - * @param data: value of the axis - * @return A string with the value of the axis to be written to the file + * @param analog Value of the axis + * @returns A string with the value of the axis to be written to the file */ - std::string WriteCommandAxis(TasAnalog data) const; + std::string WriteCommandAxis(TasAnalog analog) const; /// Sets an axis for a particular pad to the given value. void SetTasAxis(const PadIdentifier& identifier, TasAxis axis, f32 value); -- cgit v1.2.3 From 6be730bdcdf875655973b1a39576e6933fd93eab Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 13 Dec 2021 10:54:05 -0500 Subject: tas_input: Use u8string_view instead of u8string Same behavior, but without the potential for extra allocations. --- src/input_common/drivers/tas_input.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/input_common/drivers/tas_input.h') diff --git a/src/input_common/drivers/tas_input.h b/src/input_common/drivers/tas_input.h index 7c2c4a21b..68970dcec 100644 --- a/src/input_common/drivers/tas_input.h +++ b/src/input_common/drivers/tas_input.h @@ -150,7 +150,7 @@ private: * Writes a TAS file from the recorded commands * @param file_name Name of the file to be written */ - void WriteTasFile(std::u8string file_name); + void WriteTasFile(std::u8string_view file_name); /** * Parses a string containing the axis values. X and Y have a range from -32767 to 32767 -- cgit v1.2.3 From db9320e7541430dc487e85f40912725bd5b66c8a Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 13 Dec 2021 11:10:56 -0500 Subject: tas_input: Remove unnecessary includes Gets rid of indirect includes and includes only what the interface needs. --- src/input_common/drivers/tas_input.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/input_common/drivers/tas_input.h') diff --git a/src/input_common/drivers/tas_input.h b/src/input_common/drivers/tas_input.h index 68970dcec..3996fe3a8 100644 --- a/src/input_common/drivers/tas_input.h +++ b/src/input_common/drivers/tas_input.h @@ -5,11 +5,11 @@ #pragma once #include +#include +#include #include "common/common_types.h" -#include "common/settings_input.h" #include "input_common/input_engine.h" -#include "input_common/main.h" /* To play back TAS scripts on Yuzu, select the folder with scripts in the configuration menu below -- cgit v1.2.3