early-access version 2182

main
pineappleEA 2021-11-03 13:04:28 +01:00
parent c5ca895a26
commit ba74a2d4fe
9 changed files with 102 additions and 58 deletions

View File

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 2181. This is the source code for early-access 2182.
## Legal Notice ## Legal Notice

View File

@ -11,6 +11,7 @@
#include <utility> #include <utility>
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/param_package.h" #include "common/param_package.h"
#include "common/uuid.h"
namespace Common::Input { namespace Common::Input {
@ -81,6 +82,7 @@ struct AnalogStatus {
}; };
struct ButtonStatus { struct ButtonStatus {
Common::UUID uuid{};
bool value{}; bool value{};
bool inverted{}; bool inverted{};
bool toggle{}; bool toggle{};
@ -90,6 +92,7 @@ struct ButtonStatus {
using BatteryStatus = BatteryLevel; using BatteryStatus = BatteryLevel;
struct StickStatus { struct StickStatus {
Common::UUID uuid{};
AnalogStatus x{}; AnalogStatus x{};
AnalogStatus y{}; AnalogStatus y{};
bool left{}; bool left{};
@ -99,6 +102,7 @@ struct StickStatus {
}; };
struct TriggerStatus { struct TriggerStatus {
Common::UUID uuid{};
AnalogStatus analog{}; AnalogStatus analog{};
ButtonStatus pressed{}; ButtonStatus pressed{};
}; };

View File

@ -183,8 +183,11 @@ void EmulatedController::ReloadInput() {
if (!button_devices[index]) { if (!button_devices[index]) {
continue; continue;
} }
const auto uuid = Common::UUID{button_params[index].Get("guid", "")};
Common::Input::InputCallback button_callback{ Common::Input::InputCallback button_callback{
[this, index](Common::Input::CallbackStatus callback) { SetButton(callback, index); }}; [this, index, uuid](Common::Input::CallbackStatus callback) {
SetButton(callback, index, uuid);
}};
button_devices[index]->SetCallback(button_callback); button_devices[index]->SetCallback(button_callback);
button_devices[index]->ForceUpdate(); button_devices[index]->ForceUpdate();
} }
@ -193,8 +196,11 @@ void EmulatedController::ReloadInput() {
if (!stick_devices[index]) { if (!stick_devices[index]) {
continue; continue;
} }
const auto uuid = Common::UUID{stick_params[index].Get("guid", "")};
Common::Input::InputCallback stick_callback{ Common::Input::InputCallback stick_callback{
[this, index](Common::Input::CallbackStatus callback) { SetStick(callback, index); }}; [this, index, uuid](Common::Input::CallbackStatus callback) {
SetStick(callback, index, uuid);
}};
stick_devices[index]->SetCallback(stick_callback); stick_devices[index]->SetCallback(stick_callback);
stick_devices[index]->ForceUpdate(); stick_devices[index]->ForceUpdate();
} }
@ -203,8 +209,11 @@ void EmulatedController::ReloadInput() {
if (!trigger_devices[index]) { if (!trigger_devices[index]) {
continue; continue;
} }
const auto uuid = Common::UUID{trigger_params[index].Get("guid", "")};
Common::Input::InputCallback trigger_callback{ Common::Input::InputCallback trigger_callback{
[this, index](Common::Input::CallbackStatus callback) { SetTrigger(callback, index); }}; [this, index, uuid](Common::Input::CallbackStatus callback) {
SetTrigger(callback, index, uuid);
}};
trigger_devices[index]->SetCallback(trigger_callback); trigger_devices[index]->SetCallback(trigger_callback);
trigger_devices[index]->ForceUpdate(); trigger_devices[index]->ForceUpdate();
} }
@ -229,13 +238,18 @@ void EmulatedController::ReloadInput() {
motion_devices[index]->ForceUpdate(); motion_devices[index]->ForceUpdate();
} }
// Use a common UUID for TAS
const auto tas_uuid = Common::UUID{0x0, 0x7A5};
// Register TAS devices. No need to force update // Register TAS devices. No need to force update
for (std::size_t index = 0; index < tas_button_devices.size(); ++index) { for (std::size_t index = 0; index < tas_button_devices.size(); ++index) {
if (!tas_button_devices[index]) { if (!tas_button_devices[index]) {
continue; continue;
} }
Common::Input::InputCallback button_callback{ Common::Input::InputCallback button_callback{
[this, index](Common::Input::CallbackStatus callback) { SetButton(callback, index); }}; [this, index, tas_uuid](Common::Input::CallbackStatus callback) {
SetButton(callback, index, tas_uuid);
}};
tas_button_devices[index]->SetCallback(button_callback); tas_button_devices[index]->SetCallback(button_callback);
} }
@ -244,7 +258,9 @@ void EmulatedController::ReloadInput() {
continue; continue;
} }
Common::Input::InputCallback stick_callback{ Common::Input::InputCallback stick_callback{
[this, index](Common::Input::CallbackStatus callback) { SetStick(callback, index); }}; [this, index, tas_uuid](Common::Input::CallbackStatus callback) {
SetStick(callback, index, tas_uuid);
}};
tas_stick_devices[index]->SetCallback(stick_callback); tas_stick_devices[index]->SetCallback(stick_callback);
} }
} }
@ -423,7 +439,8 @@ void EmulatedController::SetMotionParam(std::size_t index, Common::ParamPackage
ReloadInput(); ReloadInput();
} }
void EmulatedController::SetButton(Common::Input::CallbackStatus callback, std::size_t index) { void EmulatedController::SetButton(Common::Input::CallbackStatus callback, std::size_t index,
Common::UUID uuid) {
if (index >= controller.button_values.size()) { if (index >= controller.button_values.size()) {
return; return;
} }
@ -432,7 +449,16 @@ void EmulatedController::SetButton(Common::Input::CallbackStatus callback, std::
bool value_changed = false; bool value_changed = false;
const auto new_status = TransformToButton(callback); const auto new_status = TransformToButton(callback);
auto& current_status = controller.button_values[index]; auto& current_status = controller.button_values[index];
// Only read button values that have the same uuid or are pressed once
if (current_status.uuid != uuid) {
if (!new_status.value) {
return;
}
}
current_status.toggle = new_status.toggle; current_status.toggle = new_status.toggle;
current_status.uuid = uuid;
// Update button status with current // Update button status with current
if (!current_status.toggle) { if (!current_status.toggle) {
@ -553,12 +579,23 @@ void EmulatedController::SetButton(Common::Input::CallbackStatus callback, std::
TriggerOnChange(ControllerTriggerType::Button, true); TriggerOnChange(ControllerTriggerType::Button, true);
} }
void EmulatedController::SetStick(Common::Input::CallbackStatus callback, std::size_t index) { void EmulatedController::SetStick(Common::Input::CallbackStatus callback, std::size_t index,
Common::UUID uuid) {
if (index >= controller.stick_values.size()) { if (index >= controller.stick_values.size()) {
return; return;
} }
std::lock_guard lock{mutex}; std::lock_guard lock{mutex};
controller.stick_values[index] = TransformToStick(callback); const auto stick_value = TransformToStick(callback);
// Only read stick values that have the same uuid or are over the threshold to avoid flapping
if (controller.stick_values[index].uuid != uuid) {
if (!stick_value.down && !stick_value.up && !stick_value.left && !stick_value.right) {
return;
}
}
controller.stick_values[index] = stick_value;
controller.stick_values[index].uuid = uuid;
if (is_configuring) { if (is_configuring) {
controller.analog_stick_state.left = {}; controller.analog_stick_state.left = {};
@ -592,12 +629,23 @@ void EmulatedController::SetStick(Common::Input::CallbackStatus callback, std::s
TriggerOnChange(ControllerTriggerType::Stick, true); TriggerOnChange(ControllerTriggerType::Stick, true);
} }
void EmulatedController::SetTrigger(Common::Input::CallbackStatus callback, std::size_t index) { void EmulatedController::SetTrigger(Common::Input::CallbackStatus callback, std::size_t index,
Common::UUID uuid) {
if (index >= controller.trigger_values.size()) { if (index >= controller.trigger_values.size()) {
return; return;
} }
std::lock_guard lock{mutex}; std::lock_guard lock{mutex};
controller.trigger_values[index] = TransformToTrigger(callback); const auto trigger_value = TransformToTrigger(callback);
// Only read trigger values that have the same uuid or are pressed once
if (controller.stick_values[index].uuid != uuid) {
if (!trigger_value.pressed.value) {
return;
}
}
controller.trigger_values[index] = trigger_value;
controller.trigger_values[index].uuid = uuid;
if (is_configuring) { if (is_configuring) {
controller.gc_trigger_state.left = 0; controller.gc_trigger_state.left = 0;

View File

@ -313,21 +313,21 @@ private:
* @param callback: A CallbackStatus containing the button status * @param callback: A CallbackStatus containing the button status
* @param index: Button ID of the to be updated * @param index: Button ID of the to be updated
*/ */
void SetButton(Common::Input::CallbackStatus callback, std::size_t index); void SetButton(Common::Input::CallbackStatus callback, std::size_t index, Common::UUID uuid);
/** /**
* Updates the analog stick status of the controller * Updates the analog stick status of the controller
* @param callback: A CallbackStatus containing the analog stick status * @param callback: A CallbackStatus containing the analog stick status
* @param index: stick ID of the to be updated * @param index: stick ID of the to be updated
*/ */
void SetStick(Common::Input::CallbackStatus callback, std::size_t index); void SetStick(Common::Input::CallbackStatus callback, std::size_t index, Common::UUID uuid);
/** /**
* Updates the trigger status of the controller * Updates the trigger status of the controller
* @param callback: A CallbackStatus containing the trigger status * @param callback: A CallbackStatus containing the trigger status
* @param index: trigger ID of the to be updated * @param index: trigger ID of the to be updated
*/ */
void SetTrigger(Common::Input::CallbackStatus callback, std::size_t index); void SetTrigger(Common::Input::CallbackStatus callback, std::size_t index, Common::UUID uuid);
/** /**
* Updates the motion status of the controller * Updates the motion status of the controller

View File

@ -75,9 +75,9 @@ Common::Input::MotionStatus TransformToMotion(const Common::Input::CallbackStatu
switch (callback.type) { switch (callback.type) {
case Common::Input::InputType::Button: { case Common::Input::InputType::Button: {
Common::Input::AnalogProperties properties{ Common::Input::AnalogProperties properties{
.deadzone = 0.0, .deadzone = 0.0f,
.range = 1.0f, .range = 1.0f,
.offset = 0.0, .offset = 0.0f,
}; };
status.delta_timestamp = 5000; status.delta_timestamp = 5000;
status.force_update = true; status.force_update = true;
@ -96,6 +96,21 @@ Common::Input::MotionStatus TransformToMotion(const Common::Input::CallbackStatu
.raw_value = -1.0f, .raw_value = -1.0f,
.properties = properties, .properties = properties,
}; };
status.gyro.x = {
.value = 0.0f,
.raw_value = 0.0f,
.properties = properties,
};
status.gyro.y = {
.value = 0.0f,
.raw_value = 0.0f,
.properties = properties,
};
status.gyro.z = {
.value = 0.0f,
.raw_value = 0.0f,
.properties = properties,
};
if (TransformToButton(callback).value) { if (TransformToButton(callback).value) {
std::random_device device; std::random_device device;
std::mt19937 gen(device()); std::mt19937 gen(device());
@ -103,21 +118,9 @@ Common::Input::MotionStatus TransformToMotion(const Common::Input::CallbackStatu
status.accel.x.raw_value = static_cast<f32>(distribution(gen)) * 0.001f; status.accel.x.raw_value = static_cast<f32>(distribution(gen)) * 0.001f;
status.accel.y.raw_value = static_cast<f32>(distribution(gen)) * 0.001f; status.accel.y.raw_value = static_cast<f32>(distribution(gen)) * 0.001f;
status.accel.z.raw_value = static_cast<f32>(distribution(gen)) * 0.001f; status.accel.z.raw_value = static_cast<f32>(distribution(gen)) * 0.001f;
status.gyro.x = { status.gyro.x.raw_value = static_cast<f32>(distribution(gen)) * 0.001f;
.value = 0, status.gyro.y.raw_value = static_cast<f32>(distribution(gen)) * 0.001f;
.raw_value = static_cast<f32>(distribution(gen)) * 0.001f, status.gyro.z.raw_value = static_cast<f32>(distribution(gen)) * 0.001f;
.properties = properties,
};
status.gyro.y = {
.value = 0,
.raw_value = static_cast<f32>(distribution(gen)) * 0.001f,
.properties = properties,
};
status.gyro.z = {
.value = 0,
.raw_value = static_cast<f32>(distribution(gen)) * 0.001f,
.properties = properties,
};
} }
break; break;
} }

View File

@ -409,7 +409,7 @@ static ResultCode GetProcessId32(Core::System& system, u32* out_process_id_low,
/// Wait for the given handles to synchronize, timeout after the specified nanoseconds /// Wait for the given handles to synchronize, timeout after the specified nanoseconds
static ResultCode WaitSynchronization(Core::System& system, s32* index, VAddr handles_address, static ResultCode WaitSynchronization(Core::System& system, s32* index, VAddr handles_address,
u64 num_handles, s64 nano_seconds) { s32 num_handles, s64 nano_seconds) {
LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, num_handles={}, nano_seconds={}", LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, num_handles={}, nano_seconds={}",
handles_address, num_handles, nano_seconds); handles_address, num_handles, nano_seconds);
@ -434,7 +434,7 @@ static ResultCode WaitSynchronization(Core::System& system, s32* index, VAddr ha
// Ensure handles are closed when we're done. // Ensure handles are closed when we're done.
SCOPE_EXIT({ SCOPE_EXIT({
for (u64 i = 0; i < num_handles; ++i) { for (s32 i = 0; i < num_handles; ++i) {
kernel.UnregisterInUseObject(objs[i]); kernel.UnregisterInUseObject(objs[i]);
objs[i]->Close(); objs[i]->Close();
} }

View File

@ -248,10 +248,10 @@ void SvcWrap64(Core::System& system) {
} }
// Used by WaitSynchronization // Used by WaitSynchronization
template <ResultCode func(Core::System&, s32*, u64, u64, s64)> template <ResultCode func(Core::System&, s32*, u64, s32, s64)>
void SvcWrap64(Core::System& system) { void SvcWrap64(Core::System& system) {
s32 param_1 = 0; s32 param_1 = 0;
const u32 retval = func(system, &param_1, Param(system, 1), static_cast<u32>(Param(system, 2)), const u32 retval = func(system, &param_1, Param(system, 1), static_cast<s32>(Param(system, 2)),
static_cast<s64>(Param(system, 3))) static_cast<s64>(Param(system, 3)))
.raw; .raw;

View File

@ -71,21 +71,21 @@ Tas::~Tas() {
void Tas::LoadTasFiles() { void Tas::LoadTasFiles() {
script_length = 0; script_length = 0;
for (size_t i = 0; i < commands.size(); i++) { for (size_t i = 0; i < commands.size(); i++) {
LoadTasFile(i); LoadTasFile(i, 0);
if (commands[i].size() > script_length) { if (commands[i].size() > script_length) {
script_length = commands[i].size(); script_length = commands[i].size();
} }
} }
} }
void Tas::LoadTasFile(size_t player_index) { void Tas::LoadTasFile(size_t player_index, size_t file_index) {
if (!commands[player_index].empty()) { if (!commands[player_index].empty()) {
commands[player_index].clear(); commands[player_index].clear();
} }
std::string file = std::string file = Common::FS::ReadStringFromFile(
Common::FS::ReadStringFromFile(Common::FS::GetYuzuPath(Common::FS::YuzuPath::TASDir) / Common::FS::GetYuzuPath(Common::FS::YuzuPath::TASDir) /
fmt::format("script0-{}.txt", player_index + 1), fmt::format("script{}-{}.txt", file_index, player_index + 1),
Common::FS::FileType::BinaryFile); Common::FS::FileType::BinaryFile);
std::stringstream command_line(file); std::stringstream command_line(file);
std::string line; std::string line;
int frame_no = 0; int frame_no = 0;
@ -144,15 +144,8 @@ void Tas::WriteTasFile(std::u8string file_name) {
void Tas::RecordInput(u64 buttons, TasAnalog left_axis, TasAnalog right_axis) { void Tas::RecordInput(u64 buttons, TasAnalog left_axis, TasAnalog right_axis) {
last_input = { last_input = {
.buttons = buttons, .buttons = buttons,
.l_axis = FlipAxisY(left_axis), .l_axis = left_axis,
.r_axis = FlipAxisY(right_axis), .r_axis = right_axis,
};
}
TasAnalog Tas::FlipAxisY(TasAnalog old) {
return {
.x = old.x,
.y = -old.y,
}; };
} }
@ -219,6 +212,7 @@ void Tas::UpdateThread() {
} }
} else { } else {
is_running = Settings::values.tas_loop.GetValue(); is_running = Settings::values.tas_loop.GetValue();
LoadTasFiles();
current_command = 0; current_command = 0;
ClearInput(); ClearInput();
} }

View File

@ -138,21 +138,16 @@ private:
void LoadTasFiles(); void LoadTasFiles();
/** Loads TAS file from the specified player /** 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 /** Writes a TAS file from the recorded commands
* @param file_name: name of the file to be written * @param file_name: name of the file to be written
*/ */
void WriteTasFile(std::u8string file_name); 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 * 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" * @param line: string containing axis values with the following format "x;y"