summaryrefslogtreecommitdiffstats
path: root/src/input_common/tas
diff options
context:
space:
mode:
Diffstat (limited to 'src/input_common/tas')
-rw-r--r--src/input_common/tas/tas_input.cpp3
-rw-r--r--src/input_common/tas/tas_input.h108
-rw-r--r--src/input_common/tas/tas_poller.h4
3 files changed, 112 insertions, 3 deletions
diff --git a/src/input_common/tas/tas_input.cpp b/src/input_common/tas/tas_input.cpp
index aceb13adc..877d35088 100644
--- a/src/input_common/tas/tas_input.cpp
+++ b/src/input_common/tas/tas_input.cpp
@@ -14,6 +14,7 @@
namespace TasInput {
+// Supported keywords and buttons from a TAS file
constexpr std::array<std::pair<std::string_view, TasButton>, 20> text_to_tas_button = {
std::pair{"KEY_A", TasButton::BUTTON_A},
{"KEY_B", TasButton::BUTTON_B},
@@ -214,7 +215,7 @@ void Tas::UpdateThread() {
}
}
} else {
- is_running = Settings::values.tas_loop;
+ is_running = Settings::values.tas_loop.GetValue();
current_command = 0;
tas_data.fill({});
if (!is_running) {
diff --git a/src/input_common/tas/tas_input.h b/src/input_common/tas/tas_input.h
index e1f351251..52d000db4 100644
--- a/src/input_common/tas/tas_input.h
+++ b/src/input_common/tas/tas_input.h
@@ -11,6 +11,38 @@
#include "core/frontend/input.h"
#include "input_common/main.h"
+/*
+To play back TAS scripts on Yuzu, select the folder with scripts in the configuration menu below
+Emulation -> 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 TasInput {
constexpr size_t PLAYER_NUMBER = 8;
@@ -64,12 +96,26 @@ public:
Tas();
~Tas();
+ // Changes the input status that will be stored in each frame
void RecordInput(u32 buttons, const std::array<std::pair<float, float>, 2>& axes);
+
+ // 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();
+
+ // 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 if overwrite is enabled player 1 will be
+ // overwritten with the recorded commands
void SaveRecording(bool overwrite_file);
/**
@@ -80,7 +126,11 @@ public:
* Total length of script file currently loaded or amount of frames (so far) for Recording
*/
std::tuple<TasState, size_t, size_t> GetStatus() const;
+
+ // Retuns an array of the default button mappings
InputCommon::ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) const;
+
+ // Retuns an array of the default analog mappings
InputCommon::AnalogMapping GetAnalogMappingForDevice(const Common::ParamPackage& params) const;
[[nodiscard]] const TasData& GetTasState(std::size_t pad) const;
@@ -90,23 +140,81 @@ private:
TasAnalog l_axis{};
TasAnalog r_axis{};
};
+
+ // Loads TAS files from all players
void LoadTasFiles();
+
+ // Loads TAS file from the specified player
void LoadTasFile(size_t player_index);
+
+ // Writes a TAS file from the recorded commands
void WriteTasFile(std::u8string file_name);
+
+ /**
+ * Parses a string containing the axis values with the following format "x;y"
+ * X and Y have a range from -32767 to 32767
+ * @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 with the following format "a;b;c;d..."
+ * Each button is represented by it's text format specified in text_to_tas_button array
+ * @return Returns a u32 with each bit representing the status of a button
+ */
u32 ReadCommandButtons(const std::string& line) const;
+
+ /**
+ * Converts an u32 containing the button status into the text equivalent
+ * @return Returns a string with the name of the buttons to be written to the file
+ */
std::string WriteCommandButtons(u32 data) const;
+
+ /**
+ * Converts an TAS analog object containing the axis status into the text equivalent
+ * @return Returns a string with the value of the axis to be written to the file
+ */
std::string WriteCommandAxis(TasAnalog data) const;
+ // Inverts the Y axis polarity
std::pair<float, float> FlipAxisY(std::pair<float, float> old);
+ /**
+ * Converts an u32 containing the button status into the text equivalent
+ * @return Returns a string with the name of the buttons to be printed on console
+ */
std::string DebugButtons(u32 buttons) const;
+
+ /**
+ * Converts an TAS analog object containing the axis status into the text equivalent
+ * @return Returns a string with the value of the axis to be printed on console
+ */
std::string DebugJoystick(float x, float y) const;
+
+ /**
+ * Converts the given TAS status into the text equivalent
+ * @return Returns a string with the value of the TAS status to be printed on console
+ */
std::string DebugInput(const TasData& data) const;
+
+ /**
+ * Converts the given TAS status of multiple players into the text equivalent
+ * @return Returns a string with the value of the status of all TAS players to be printed on
+ * console
+ */
std::string DebugInputs(const std::array<TasData, PLAYER_NUMBER>& arr) const;
+
+ /**
+ * Converts an u32 containing the button status into the text equivalent
+ * @return Returns a string with the name of the buttons
+ */
std::string ButtonsToString(u32 button) const;
+ // Stores current controller configuration and sets a TAS controller for every active controller
+ // to the current config
void SwapToTasController();
+
+ // Sets the stored controller configuration to the current config
void SwapToStoredController();
size_t script_length{0};
diff --git a/src/input_common/tas/tas_poller.h b/src/input_common/tas/tas_poller.h
index 1bc0d173b..09e426cef 100644
--- a/src/input_common/tas/tas_poller.h
+++ b/src/input_common/tas/tas_poller.h
@@ -11,7 +11,7 @@
namespace InputCommon {
/**
- * A button device factory representing a mouse. It receives mouse events and forward them
+ * A button device factory representing a tas bot. It receives tas events and forward them
* to all button devices it created.
*/
class TasButtonFactory final : public Input::Factory<Input::ButtonDevice> {
@@ -29,7 +29,7 @@ private:
std::shared_ptr<TasInput::Tas> tas_input;
};
-/// An analog device factory that creates analog devices from mouse
+/// An analog device factory that creates analog devices from tas
class TasAnalogFactory final : public Input::Factory<Input::AnalogDevice> {
public:
explicit TasAnalogFactory(std::shared_ptr<TasInput::Tas> tas_input_);