summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/fs/path_util.h2
-rw-r--r--src/input_common/main.h20
-rw-r--r--src/input_common/tas/tas_input.cpp63
-rw-r--r--src/input_common/tas/tas_input.h9
-rw-r--r--src/yuzu/configuration/config.cpp5
-rw-r--r--src/yuzu/configuration/configure_input_player_widget.cpp34
-rw-r--r--src/yuzu/configuration/configure_tas.ui3
-rw-r--r--src/yuzu/main.cpp2
8 files changed, 99 insertions, 39 deletions
diff --git a/src/common/fs/path_util.h b/src/common/fs/path_util.h
index 52e4670e2..0a9e3a145 100644
--- a/src/common/fs/path_util.h
+++ b/src/common/fs/path_util.h
@@ -23,7 +23,7 @@ enum class YuzuPath {
ScreenshotsDir, // Where yuzu screenshots are stored.
SDMCDir, // Where the emulated SDMC is stored.
ShaderDir, // Where shaders are stored.
- TASDir, // Where the current script file is stored.
+ TASDir, // Where TAS scripts are stored.
};
/**
diff --git a/src/input_common/main.h b/src/input_common/main.h
index 1d06fc5f5..6390d3f09 100644
--- a/src/input_common/main.h
+++ b/src/input_common/main.h
@@ -155,28 +155,28 @@ public:
/// Retrieves the underlying udp touch handler.
[[nodiscard]] const UDPTouchFactory* GetUDPTouch() const;
- /// Retrieves the underlying GameCube button handler.
+ /// Retrieves the underlying mouse button handler.
[[nodiscard]] MouseButtonFactory* GetMouseButtons();
- /// Retrieves the underlying GameCube button handler.
+ /// Retrieves the underlying mouse button handler.
[[nodiscard]] const MouseButtonFactory* GetMouseButtons() const;
- /// Retrieves the underlying udp touch handler.
+ /// Retrieves the underlying mouse analog handler.
[[nodiscard]] MouseAnalogFactory* GetMouseAnalogs();
- /// Retrieves the underlying udp touch handler.
+ /// Retrieves the underlying mouse analog handler.
[[nodiscard]] const MouseAnalogFactory* GetMouseAnalogs() const;
- /// Retrieves the underlying udp motion handler.
+ /// Retrieves the underlying mouse motion handler.
[[nodiscard]] MouseMotionFactory* GetMouseMotions();
- /// Retrieves the underlying udp motion handler.
+ /// Retrieves the underlying mouse motion handler.
[[nodiscard]] const MouseMotionFactory* GetMouseMotions() const;
- /// Retrieves the underlying udp touch handler.
+ /// Retrieves the underlying mouse touch handler.
[[nodiscard]] MouseTouchFactory* GetMouseTouch();
- /// Retrieves the underlying udp touch handler.
+ /// Retrieves the underlying mouse touch handler.
[[nodiscard]] const MouseTouchFactory* GetMouseTouch() const;
/// Retrieves the underlying tas button handler.
@@ -185,10 +185,10 @@ public:
/// Retrieves the underlying tas button handler.
[[nodiscard]] const TasButtonFactory* GetTasButtons() const;
- /// Retrieves the underlying tas touch handler.
+ /// Retrieves the underlying tas analogs handler.
[[nodiscard]] TasAnalogFactory* GetTasAnalogs();
- /// Retrieves the underlying tas touch handler.
+ /// Retrieves the underlying tas analogs handler.
[[nodiscard]] const TasAnalogFactory* GetTasAnalogs() const;
/// Reloads the input devices
diff --git a/src/input_common/tas/tas_input.cpp b/src/input_common/tas/tas_input.cpp
index eb3327520..aceb13adc 100644
--- a/src/input_common/tas/tas_input.cpp
+++ b/src/input_common/tas/tas_input.cpp
@@ -61,8 +61,8 @@ void Tas::LoadTasFile(size_t player_index) {
commands[player_index].clear();
}
std::string file =
- Common::FS::ReadStringFromFile(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::TASDir) +
- "script0-" + std::to_string(player_index + 1) + ".txt",
+ Common::FS::ReadStringFromFile(Common::FS::GetYuzuPath(Common::FS::YuzuPath::TASDir) /
+ fmt::format("script0-{}.txt", player_index + 1),
Common::FS::FileType::BinaryFile);
std::stringstream command_line(file);
std::string line;
@@ -102,7 +102,7 @@ void Tas::LoadTasFile(size_t player_index) {
LOG_INFO(Input, "TAS file loaded! {} frames", frame_no);
}
-void Tas::WriteTasFile(std::string file_name) {
+void Tas::WriteTasFile(std::u8string file_name) {
std::string output_text;
for (size_t frame = 0; frame < record_commands.size(); frame++) {
if (!output_text.empty()) {
@@ -112,8 +112,8 @@ void Tas::WriteTasFile(std::string file_name) {
output_text += std::to_string(frame) + " " + WriteCommandButtons(line.buttons) + " " +
WriteCommandAxis(line.l_axis) + " " + WriteCommandAxis(line.r_axis);
}
- const size_t bytes_written = Common::FS::WriteStringToFile(
- Common::FS::GetYuzuPathString(Common::FS::YuzuPath::TASDir) + file_name,
+ const auto bytes_written = Common::FS::WriteStringToFile(
+ Common::FS::GetYuzuPath(Common::FS::YuzuPath::TASDir) / file_name,
Common::FS::FileType::TextFile, output_text);
if (bytes_written == output_text.size()) {
LOG_INFO(Input, "TAS file written to file!");
@@ -217,6 +217,9 @@ void Tas::UpdateThread() {
is_running = Settings::values.tas_loop;
current_command = 0;
tas_data.fill({});
+ if (!is_running) {
+ SwapToStoredController();
+ }
}
} else {
tas_data.fill({});
@@ -290,6 +293,52 @@ std::string Tas::WriteCommandButtons(u32 data) const {
void Tas::StartStop() {
is_running = !is_running;
+ if (is_running) {
+ SwapToTasController();
+ } else {
+ SwapToStoredController();
+ }
+}
+
+void Tas::SwapToTasController() {
+ if (!Settings::values.tas_swap_controllers) {
+ return;
+ }
+ auto& players = Settings::values.players.GetValue();
+ for (std::size_t index = 0; index < players.size(); index++) {
+ auto& player = players[index];
+ player_mappings[index] = player;
+
+ // Only swap active controllers
+ if (!player.connected) {
+ continue;
+ }
+
+ auto tas_param = Common::ParamPackage{{"pad", static_cast<u8>(index)}};
+ auto button_mapping = GetButtonMappingForDevice(tas_param);
+ auto analog_mapping = GetAnalogMappingForDevice(tas_param);
+ auto& buttons = player.buttons;
+ auto& analogs = player.analogs;
+
+ for (std::size_t i = 0; i < buttons.size(); ++i) {
+ buttons[i] = button_mapping[static_cast<Settings::NativeButton::Values>(i)].Serialize();
+ }
+ for (std::size_t i = 0; i < analogs.size(); ++i) {
+ analogs[i] = analog_mapping[static_cast<Settings::NativeAnalog::Values>(i)].Serialize();
+ }
+ }
+ Settings::values.is_device_reload_pending.store(true);
+}
+
+void Tas::SwapToStoredController() {
+ if (!Settings::values.tas_swap_controllers) {
+ return;
+ }
+ auto& players = Settings::values.players.GetValue();
+ for (std::size_t index = 0; index < players.size(); index++) {
+ players[index] = player_mappings[index];
+ }
+ Settings::values.is_device_reload_pending.store(true);
}
void Tas::Reset() {
@@ -308,9 +357,9 @@ void Tas::SaveRecording(bool overwrite_file) {
if (record_commands.empty()) {
return;
}
- WriteTasFile("record.txt");
+ WriteTasFile(u8"record.txt");
if (overwrite_file) {
- WriteTasFile("script0-1.txt");
+ WriteTasFile(u8"script0-1.txt");
}
needs_reset = true;
record_commands.clear();
diff --git a/src/input_common/tas/tas_input.h b/src/input_common/tas/tas_input.h
index e0462e858..e1f351251 100644
--- a/src/input_common/tas/tas_input.h
+++ b/src/input_common/tas/tas_input.h
@@ -7,6 +7,7 @@
#include <array>
#include "common/common_types.h"
+#include "common/settings_input.h"
#include "core/frontend/input.h"
#include "input_common/main.h"
@@ -91,7 +92,7 @@ private:
};
void LoadTasFiles();
void LoadTasFile(size_t player_index);
- void WriteTasFile(std::string file_name);
+ 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;
@@ -105,6 +106,9 @@ private:
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};
@@ -114,5 +118,8 @@ private:
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
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 99e318a8f..a0dfa06df 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -1205,6 +1205,11 @@ void Config::SaveControlValues() {
WriteBasicSetting(Settings::values.emulate_analog_keyboard);
WriteBasicSetting(Settings::values.mouse_panning_sensitivity);
+ WriteSetting(QStringLiteral("enable_tas"), Settings::values.tas_enable, false);
+ WriteSetting(QStringLiteral("loop_tas"), Settings::values.tas_loop, false);
+ WriteSetting(QStringLiteral("swap_tas_controllers"), Settings::values.tas_swap_controllers,
+ true);
+ WriteSetting(QStringLiteral("tas_pause_on_load"), Settings::values.pause_tas_on_load, true);
qt_config->endGroup();
}
diff --git a/src/yuzu/configuration/configure_input_player_widget.cpp b/src/yuzu/configuration/configure_input_player_widget.cpp
index b905fc73d..ba3720c03 100644
--- a/src/yuzu/configuration/configure_input_player_widget.cpp
+++ b/src/yuzu/configuration/configure_input_player_widget.cpp
@@ -175,10 +175,7 @@ void PlayerControlPreview::ResetInputs() {
}
void PlayerControlPreview::UpdateInput() {
- if (controller_callback.update != nullptr) {
- controller_callback.update(std::move(true));
- }
- if (!is_enabled && !mapping_active) {
+ if (!is_enabled && !mapping_active && !Settings::values.tas_enable) {
return;
}
bool input_changed = false;
@@ -223,20 +220,25 @@ void PlayerControlPreview::UpdateInput() {
}
}
- ControllerInput input{};
if (input_changed) {
update();
- input.changed = true;
- }
- input.axis_values[Settings::NativeAnalog::LStick] = {
- axis_values[Settings::NativeAnalog::LStick].value.x(),
- axis_values[Settings::NativeAnalog::LStick].value.y()};
- input.axis_values[Settings::NativeAnalog::RStick] = {
- axis_values[Settings::NativeAnalog::RStick].value.x(),
- axis_values[Settings::NativeAnalog::RStick].value.y()};
- input.button_values = button_values;
- if (controller_callback.input != nullptr) {
- controller_callback.input(std::move(input));
+ ControllerInput input{
+ .axis_values =
+ {std::pair<float, float>{axis_values[Settings::NativeAnalog::LStick].value.x(),
+ axis_values[Settings::NativeAnalog::LStick].value.y()},
+ std::pair<float, float>{axis_values[Settings::NativeAnalog::RStick].value.x(),
+ axis_values[Settings::NativeAnalog::RStick].value.y()}},
+ .button_values = button_values,
+ .changed = true,
+ };
+
+ if (controller_callback.input != nullptr) {
+ controller_callback.input(std::move(input));
+ }
+ }
+
+ if (controller_callback.update != nullptr) {
+ controller_callback.update(std::move(true));
}
if (mapping_active) {
diff --git a/src/yuzu/configuration/configure_tas.ui b/src/yuzu/configuration/configure_tas.ui
index 906e073ff..445904d8f 100644
--- a/src/yuzu/configuration/configure_tas.ui
+++ b/src/yuzu/configuration/configure_tas.ui
@@ -31,9 +31,6 @@
</item>
<item row="1" column="0" colspan="4">
<widget class="QCheckBox" name="tas_control_swap">
- <property name="enabled">
- <bool>false</bool>
- </property>
<property name="text">
<string>Automatic controller profile swapping</string>
</property>
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 560de89af..7d12fcca7 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -2921,7 +2921,7 @@ QString GMainWindow::GetTasStateDescription() const {
case TasInput::TasState::Stopped:
return tr("TAS state: Idle %1/%2").arg(current_tas_frame).arg(total_tas_frames);
default:
- return tr("INVALID TAS STATE");
+ return tr("TAS State: Invalid");
}
}