1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
// Copyright 2020 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <array>
#include "common/common_types.h"
#include "common/settings_input.h"
#include "core/frontend/input.h"
#include "input_common/main.h"
namespace TasInput {
constexpr size_t PLAYER_NUMBER = 8;
using TasAnalog = std::pair<float, float>;
enum class TasState {
Running,
Recording,
Stopped,
};
enum class TasButton : u32 {
BUTTON_A = 0x000001,
BUTTON_B = 0x000002,
BUTTON_X = 0x000004,
BUTTON_Y = 0x000008,
STICK_L = 0x000010,
STICK_R = 0x000020,
TRIGGER_L = 0x000040,
TRIGGER_R = 0x000080,
TRIGGER_ZL = 0x000100,
TRIGGER_ZR = 0x000200,
BUTTON_PLUS = 0x000400,
BUTTON_MINUS = 0x000800,
BUTTON_LEFT = 0x001000,
BUTTON_UP = 0x002000,
BUTTON_RIGHT = 0x004000,
BUTTON_DOWN = 0x008000,
BUTTON_SL = 0x010000,
BUTTON_SR = 0x020000,
BUTTON_HOME = 0x040000,
BUTTON_CAPTURE = 0x080000,
};
enum class TasAxes : u8 {
StickX,
StickY,
SubstickX,
SubstickY,
Undefined,
};
struct TasData {
u32 buttons{};
std::array<float, 4> axis{};
};
class Tas {
public:
Tas();
~Tas();
void RecordInput(u32 buttons, const std::array<std::pair<float, float>, 2>& axes);
void UpdateThread();
void StartStop();
void Reset();
bool Record();
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, Recording or Stopped ;
* Current playback progress or amount of frames (so far) for Recording ;
* Total length of script file currently loaded or amount of frames (so far) for Recording
*/
std::tuple<TasState, size_t, size_t> GetStatus() const;
InputCommon::ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) const;
InputCommon::AnalogMapping GetAnalogMappingForDevice(const Common::ParamPackage& params) const;
[[nodiscard]] const TasData& GetTasState(std::size_t pad) const;
private:
struct TASCommand {
u32 buttons{};
TasAnalog l_axis{};
TasAnalog r_axis{};
};
void LoadTasFiles();
void LoadTasFile(size_t player_index);
void WriteTasFile(std::u8string file_name);
TasAnalog ReadCommandAxis(const std::string& line) const;
u32 ReadCommandButtons(const std::string& line) const;
std::string WriteCommandButtons(u32 data) const;
std::string WriteCommandAxis(TasAnalog data) const;
std::pair<float, float> FlipAxisY(std::pair<float, float> old);
std::string DebugButtons(u32 buttons) const;
std::string DebugJoystick(float x, float y) const;
std::string DebugInput(const TasData& data) const;
std::string DebugInputs(const std::array<TasData, PLAYER_NUMBER>& arr) const;
std::string ButtonsToString(u32 button) const;
void SwapToTasController();
void SwapToStoredController();
size_t script_length{0};
std::array<TasData, PLAYER_NUMBER> tas_data;
bool is_recording{false};
bool is_running{false};
bool needs_reset{false};
std::array<std::vector<TASCommand>, PLAYER_NUMBER> commands{};
std::vector<TASCommand> record_commands{};
size_t current_command{0};
TASCommand last_input{}; // only used for recording
// Old settings for swapping controllers
std::array<Settings::PlayerInput, 10> player_mappings;
};
} // namespace TasInput
|