summaryrefslogtreecommitdiff
path: root/src/input_common/tas/tas_input.h
diff options
context:
space:
mode:
authorGravatar MonsterDruide12021-06-18 16:32:46 +0200
committerGravatar MonsterDruide12021-09-18 23:22:20 +0200
commit4297d2fea2228ff4afe2a7c244fb8b3f1a97491a (patch)
tree25a1ce3a2d41bf9e066c7a57a441be65e282f16f /src/input_common/tas/tas_input.h
parentmain: TAS Playback state label (diff)
downloadyuzu-4297d2fea2228ff4afe2a7c244fb8b3f1a97491a.tar.gz
yuzu-4297d2fea2228ff4afe2a7c244fb8b3f1a97491a.tar.xz
yuzu-4297d2fea2228ff4afe2a7c244fb8b3f1a97491a.zip
core: Hacky TAS syncing & load pausing
To keep the TAS inputs synced to the game speed even through lag spikes and loading zones, deeper access is required. First, the `TAS::UpdateThread` has to be executed exactly once per frame. This is done by connecting it to the service method the game calls to pass parameters to the GPU: `Service::VI::QueueBuffer`. Second, the loading time of new subareas and/or kingdoms (SMO) can vary. To counteract that, the `CPU_BOOST_MODE` can be detected: In the `APM`-interface, the call to enabling/disabling the boost mode can be caught and forwarded to the TASing system, which can pause the script execution if neccessary and enabled in the settings.
Diffstat (limited to 'src/input_common/tas/tas_input.h')
-rw-r--r--src/input_common/tas/tas_input.h58
1 files changed, 20 insertions, 38 deletions
diff --git a/src/input_common/tas/tas_input.h b/src/input_common/tas/tas_input.h
index 0a152a04f..8ee70bcaf 100644
--- a/src/input_common/tas/tas_input.h
+++ b/src/input_common/tas/tas_input.h
@@ -12,11 +12,17 @@
12#include "core/frontend/input.h" 12#include "core/frontend/input.h"
13#include "input_common/main.h" 13#include "input_common/main.h"
14 14
15#define PLAYER_NUMBER 8
16
17namespace TasInput { 15namespace TasInput {
18 16
19using TasAnalog = std::tuple<float, float>; 17constexpr int PLAYER_NUMBER = 8;
18
19using TasAnalog = std::pair<float, float>;
20
21enum class TasState {
22 RUNNING,
23 RECORDING,
24 STOPPED,
25};
20 26
21enum class TasButton : u32 { 27enum class TasButton : u32 {
22 BUTTON_A = 0x000001, 28 BUTTON_A = 0x000001,
@@ -41,29 +47,6 @@ enum class TasButton : u32 {
41 BUTTON_CAPTURE = 0x080000, 47 BUTTON_CAPTURE = 0x080000,
42}; 48};
43 49
44static const std::array<std::pair<std::string, TasButton>, 20> text_to_tas_button = {
45 std::pair{"KEY_A", TasButton::BUTTON_A},
46 {"KEY_B", TasButton::BUTTON_B},
47 {"KEY_X", TasButton::BUTTON_X},
48 {"KEY_Y", TasButton::BUTTON_Y},
49 {"KEY_LSTICK", TasButton::STICK_L},
50 {"KEY_RSTICK", TasButton::STICK_R},
51 {"KEY_L", TasButton::TRIGGER_L},
52 {"KEY_R", TasButton::TRIGGER_R},
53 {"KEY_PLUS", TasButton::BUTTON_PLUS},
54 {"KEY_MINUS", TasButton::BUTTON_MINUS},
55 {"KEY_DLEFT", TasButton::BUTTON_LEFT},
56 {"KEY_DUP", TasButton::BUTTON_UP},
57 {"KEY_DRIGHT", TasButton::BUTTON_RIGHT},
58 {"KEY_DDOWN", TasButton::BUTTON_DOWN},
59 {"KEY_SL", TasButton::BUTTON_SL},
60 {"KEY_SR", TasButton::BUTTON_SR},
61 {"KEY_CAPTURE", TasButton::BUTTON_CAPTURE},
62 {"KEY_HOME", TasButton::BUTTON_HOME},
63 {"KEY_ZL", TasButton::TRIGGER_ZL},
64 {"KEY_ZR", TasButton::TRIGGER_ZR},
65};
66
67enum class TasAxes : u8 { 50enum class TasAxes : u8 {
68 StickX, 51 StickX,
69 StickY, 52 StickY,
@@ -82,7 +65,7 @@ public:
82 Tas(); 65 Tas();
83 ~Tas(); 66 ~Tas();
84 67
85 static std::string buttonsToString(u32 button) { 68 static std::string ButtonsToString(u32 button) {
86 std::string returns; 69 std::string returns;
87 if ((button & static_cast<u32>(TasInput::TasButton::BUTTON_A)) != 0) 70 if ((button & static_cast<u32>(TasInput::TasButton::BUTTON_A)) != 0)
88 returns += ", A"; 71 returns += ", A";
@@ -124,14 +107,14 @@ public:
124 returns += ", HOME"; 107 returns += ", HOME";
125 if ((button & static_cast<u32>(TasInput::TasButton::BUTTON_CAPTURE)) != 0) 108 if ((button & static_cast<u32>(TasInput::TasButton::BUTTON_CAPTURE)) != 0)
126 returns += ", CAPTURE"; 109 returns += ", CAPTURE";
127 return returns.length() != 0 ? returns.substr(2) : ""; 110 return returns.empty() ? "" : returns.substr(2);
128 } 111 }
129 112
130 void RefreshTasFile(); 113 void RefreshTasFile();
131 void LoadTasFiles(); 114 void LoadTasFiles();
132 void RecordInput(u32 buttons, std::array<std::pair<float, float>, 2> axes); 115 void RecordInput(u32 buttons, const std::array<std::pair<float, float>, 2>& axes);
133 void UpdateThread(); 116 void UpdateThread();
134 std::string GetStatusDescription(); 117 std::tuple<TasState, size_t, size_t> GetStatus();
135 118
136 InputCommon::ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) const; 119 InputCommon::ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) const;
137 InputCommon::AnalogMapping GetAnalogMappingForDevice(const Common::ParamPackage& params) const; 120 InputCommon::AnalogMapping GetAnalogMappingForDevice(const Common::ParamPackage& params) const;
@@ -143,21 +126,20 @@ private:
143 TasAnalog l_axis{}; 126 TasAnalog l_axis{};
144 TasAnalog r_axis{}; 127 TasAnalog r_axis{};
145 }; 128 };
146 void LoadTasFile(int playerIndex); 129 void LoadTasFile(size_t player_index);
147 void WriteTasFile(); 130 void WriteTasFile();
148 TasAnalog ReadCommandAxis(const std::string line) const; 131 TasAnalog ReadCommandAxis(const std::string& line) const;
149 u32 ReadCommandButtons(const std::string line) const; 132 u32 ReadCommandButtons(const std::string& line) const;
150 std::string WriteCommandButtons(u32 data) const; 133 std::string WriteCommandButtons(u32 data) const;
151 std::string WriteCommandAxis(TasAnalog data) const; 134 std::string WriteCommandAxis(TasAnalog data) const;
152 std::pair<float, float> flipY(std::pair<float, float> old) const;
153 135
154 size_t scriptLength{0}; 136 size_t script_length{0};
155 std::array<TasData, PLAYER_NUMBER> tas_data; 137 std::array<TasData, PLAYER_NUMBER> tas_data;
156 bool update_thread_running{true}; 138 bool update_thread_running{true};
157 bool refresh_tas_fle{false}; 139 bool refresh_tas_fle{false};
158 std::array<std::vector<TASCommand>, PLAYER_NUMBER> newCommands{}; 140 std::array<std::vector<TASCommand>, PLAYER_NUMBER> commands{};
159 std::vector<TASCommand> recordCommands{}; 141 std::vector<TASCommand> record_commands{};
160 std::size_t current_command{0}; 142 std::size_t current_command{0};
161 TASCommand lastInput{}; // only used for recording 143 TASCommand last_input{}; // only used for recording
162}; 144};
163} // namespace TasInput 145} // namespace TasInput