early-access version 2182
This commit is contained in:
		@@ -1,7 +1,7 @@
 | 
			
		||||
yuzu emulator early access
 | 
			
		||||
=============
 | 
			
		||||
 | 
			
		||||
This is the source code for early-access 2181.
 | 
			
		||||
This is the source code for early-access 2182.
 | 
			
		||||
 | 
			
		||||
## Legal Notice
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@
 | 
			
		||||
#include <utility>
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "common/param_package.h"
 | 
			
		||||
#include "common/uuid.h"
 | 
			
		||||
 | 
			
		||||
namespace Common::Input {
 | 
			
		||||
 | 
			
		||||
@@ -81,6 +82,7 @@ struct AnalogStatus {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ButtonStatus {
 | 
			
		||||
    Common::UUID uuid{};
 | 
			
		||||
    bool value{};
 | 
			
		||||
    bool inverted{};
 | 
			
		||||
    bool toggle{};
 | 
			
		||||
@@ -90,6 +92,7 @@ struct ButtonStatus {
 | 
			
		||||
using BatteryStatus = BatteryLevel;
 | 
			
		||||
 | 
			
		||||
struct StickStatus {
 | 
			
		||||
    Common::UUID uuid{};
 | 
			
		||||
    AnalogStatus x{};
 | 
			
		||||
    AnalogStatus y{};
 | 
			
		||||
    bool left{};
 | 
			
		||||
@@ -99,6 +102,7 @@ struct StickStatus {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct TriggerStatus {
 | 
			
		||||
    Common::UUID uuid{};
 | 
			
		||||
    AnalogStatus analog{};
 | 
			
		||||
    ButtonStatus pressed{};
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -183,8 +183,11 @@ void EmulatedController::ReloadInput() {
 | 
			
		||||
        if (!button_devices[index]) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        const auto uuid = Common::UUID{button_params[index].Get("guid", "")};
 | 
			
		||||
        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]->ForceUpdate();
 | 
			
		||||
    }
 | 
			
		||||
@@ -193,8 +196,11 @@ void EmulatedController::ReloadInput() {
 | 
			
		||||
        if (!stick_devices[index]) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        const auto uuid = Common::UUID{stick_params[index].Get("guid", "")};
 | 
			
		||||
        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]->ForceUpdate();
 | 
			
		||||
    }
 | 
			
		||||
@@ -203,8 +209,11 @@ void EmulatedController::ReloadInput() {
 | 
			
		||||
        if (!trigger_devices[index]) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        const auto uuid = Common::UUID{trigger_params[index].Get("guid", "")};
 | 
			
		||||
        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]->ForceUpdate();
 | 
			
		||||
    }
 | 
			
		||||
@@ -229,13 +238,18 @@ void EmulatedController::ReloadInput() {
 | 
			
		||||
        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
 | 
			
		||||
    for (std::size_t index = 0; index < tas_button_devices.size(); ++index) {
 | 
			
		||||
        if (!tas_button_devices[index]) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -244,7 +258,9 @@ void EmulatedController::ReloadInput() {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -423,7 +439,8 @@ void EmulatedController::SetMotionParam(std::size_t index, Common::ParamPackage
 | 
			
		||||
    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()) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
@@ -432,7 +449,16 @@ void EmulatedController::SetButton(Common::Input::CallbackStatus callback, std::
 | 
			
		||||
        bool value_changed = false;
 | 
			
		||||
        const auto new_status = TransformToButton(callback);
 | 
			
		||||
        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.uuid = uuid;
 | 
			
		||||
 | 
			
		||||
        // Update button status with current
 | 
			
		||||
        if (!current_status.toggle) {
 | 
			
		||||
@@ -553,12 +579,23 @@ void EmulatedController::SetButton(Common::Input::CallbackStatus callback, std::
 | 
			
		||||
    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()) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    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) {
 | 
			
		||||
        controller.analog_stick_state.left = {};
 | 
			
		||||
@@ -592,12 +629,23 @@ void EmulatedController::SetStick(Common::Input::CallbackStatus callback, std::s
 | 
			
		||||
    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()) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    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) {
 | 
			
		||||
        controller.gc_trigger_state.left = 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -313,21 +313,21 @@ private:
 | 
			
		||||
     * @param callback: A CallbackStatus containing the button status
 | 
			
		||||
     * @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
 | 
			
		||||
     * @param callback: A CallbackStatus containing the analog stick status
 | 
			
		||||
     * @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
 | 
			
		||||
     * @param callback: A CallbackStatus containing the trigger status
 | 
			
		||||
     * @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
 | 
			
		||||
 
 | 
			
		||||
@@ -75,9 +75,9 @@ Common::Input::MotionStatus TransformToMotion(const Common::Input::CallbackStatu
 | 
			
		||||
    switch (callback.type) {
 | 
			
		||||
    case Common::Input::InputType::Button: {
 | 
			
		||||
        Common::Input::AnalogProperties properties{
 | 
			
		||||
            .deadzone = 0.0,
 | 
			
		||||
            .deadzone = 0.0f,
 | 
			
		||||
            .range = 1.0f,
 | 
			
		||||
            .offset = 0.0,
 | 
			
		||||
            .offset = 0.0f,
 | 
			
		||||
        };
 | 
			
		||||
        status.delta_timestamp = 5000;
 | 
			
		||||
        status.force_update = true;
 | 
			
		||||
@@ -96,6 +96,21 @@ Common::Input::MotionStatus TransformToMotion(const Common::Input::CallbackStatu
 | 
			
		||||
            .raw_value = -1.0f,
 | 
			
		||||
            .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) {
 | 
			
		||||
            std::random_device 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.y.raw_value = static_cast<f32>(distribution(gen)) * 0.001f;
 | 
			
		||||
            status.accel.z.raw_value = static_cast<f32>(distribution(gen)) * 0.001f;
 | 
			
		||||
            status.gyro.x = {
 | 
			
		||||
                .value = 0,
 | 
			
		||||
                .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,
 | 
			
		||||
            };
 | 
			
		||||
            status.gyro.x.raw_value = static_cast<f32>(distribution(gen)) * 0.001f;
 | 
			
		||||
            status.gyro.y.raw_value = static_cast<f32>(distribution(gen)) * 0.001f;
 | 
			
		||||
            status.gyro.z.raw_value = static_cast<f32>(distribution(gen)) * 0.001f;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
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={}",
 | 
			
		||||
              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.
 | 
			
		||||
    SCOPE_EXIT({
 | 
			
		||||
        for (u64 i = 0; i < num_handles; ++i) {
 | 
			
		||||
        for (s32 i = 0; i < num_handles; ++i) {
 | 
			
		||||
            kernel.UnregisterInUseObject(objs[i]);
 | 
			
		||||
            objs[i]->Close();
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -248,10 +248,10 @@ void SvcWrap64(Core::System& system) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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) {
 | 
			
		||||
    s32 param_1 = 0;
 | 
			
		||||
    const u32 retval = func(system, ¶m_1, Param(system, 1), static_cast<u32>(Param(system, 2)),
 | 
			
		||||
    const u32 retval = func(system, ¶m_1, Param(system, 1), static_cast<s32>(Param(system, 2)),
 | 
			
		||||
                            static_cast<s64>(Param(system, 3)))
 | 
			
		||||
                           .raw;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -71,21 +71,21 @@ Tas::~Tas() {
 | 
			
		||||
void Tas::LoadTasFiles() {
 | 
			
		||||
    script_length = 0;
 | 
			
		||||
    for (size_t i = 0; i < commands.size(); i++) {
 | 
			
		||||
        LoadTasFile(i);
 | 
			
		||||
        LoadTasFile(i, 0);
 | 
			
		||||
        if (commands[i].size() > script_length) {
 | 
			
		||||
            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()) {
 | 
			
		||||
        commands[player_index].clear();
 | 
			
		||||
    }
 | 
			
		||||
    std::string file =
 | 
			
		||||
        Common::FS::ReadStringFromFile(Common::FS::GetYuzuPath(Common::FS::YuzuPath::TASDir) /
 | 
			
		||||
                                           fmt::format("script0-{}.txt", player_index + 1),
 | 
			
		||||
                                       Common::FS::FileType::BinaryFile);
 | 
			
		||||
    std::string file = Common::FS::ReadStringFromFile(
 | 
			
		||||
        Common::FS::GetYuzuPath(Common::FS::YuzuPath::TASDir) /
 | 
			
		||||
            fmt::format("script{}-{}.txt", file_index, player_index + 1),
 | 
			
		||||
        Common::FS::FileType::BinaryFile);
 | 
			
		||||
    std::stringstream command_line(file);
 | 
			
		||||
    std::string line;
 | 
			
		||||
    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) {
 | 
			
		||||
    last_input = {
 | 
			
		||||
        .buttons = buttons,
 | 
			
		||||
        .l_axis = FlipAxisY(left_axis),
 | 
			
		||||
        .r_axis = FlipAxisY(right_axis),
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TasAnalog Tas::FlipAxisY(TasAnalog old) {
 | 
			
		||||
    return {
 | 
			
		||||
        .x = old.x,
 | 
			
		||||
        .y = -old.y,
 | 
			
		||||
        .l_axis = left_axis,
 | 
			
		||||
        .r_axis = right_axis,
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -219,6 +212,7 @@ void Tas::UpdateThread() {
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        is_running = Settings::values.tas_loop.GetValue();
 | 
			
		||||
        LoadTasFiles();
 | 
			
		||||
        current_command = 0;
 | 
			
		||||
        ClearInput();
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -138,21 +138,16 @@ private:
 | 
			
		||||
    void LoadTasFiles();
 | 
			
		||||
 | 
			
		||||
    /** 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
 | 
			
		||||
     * @param file_name: name of the file to be written
 | 
			
		||||
     */
 | 
			
		||||
    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
 | 
			
		||||
     * @param line: string containing axis values with the following format "x;y"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user