From 8b74a66045dea53f251b52e93761e03dac4a1ee9 Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Tue, 9 May 2023 01:09:44 +0200 Subject: [PATCH] early-access version 3573 --- README.md | 2 +- src/core/hid/emulated_controller.cpp | 6 ++++ src/core/hid/emulated_controller.h | 3 ++ src/core/hid/motion_input.cpp | 21 ++++++++++- src/core/hid/motion_input.h | 11 ++++++ src/input_common/drivers/sdl_driver.cpp | 35 +++++++++++++++---- src/video_core/buffer_cache/buffer_cache.h | 10 +++--- .../configure_graphics_advanced.cpp | 4 +-- .../configuration/configure_input_player.cpp | 3 ++ .../configure_input_player_widget.cpp | 20 +++++------ src/yuzu/qt_common.cpp | 2 +- 11 files changed, 92 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index a17772453..6d31d04d4 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 3571. +This is the source code for early-access 3573. ## Legal Notice diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index 8a78ae617..1be524245 100755 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp @@ -688,6 +688,12 @@ void EmulatedController::SetMotionParam(std::size_t index, Common::ParamPackage ReloadInput(); } +void EmulatedController::StartMotionCalibration() { + for (ControllerMotionInfo& motion : controller.motion_values) { + motion.emulated.Calibrate(); + } +} + void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback, std::size_t index, Common::UUID uuid) { if (index >= controller.button_values.size()) { diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h index 818651a50..23529a3f0 100755 --- a/src/core/hid/emulated_controller.h +++ b/src/core/hid/emulated_controller.h @@ -290,6 +290,9 @@ public: */ void SetMotionParam(std::size_t index, Common::ParamPackage param); + /// Auto calibrates the current motion devices + void StartMotionCalibration(); + /// Returns the latest button status from the controller with parameters ButtonValues GetButtonsValues() const; diff --git a/src/core/hid/motion_input.cpp b/src/core/hid/motion_input.cpp index db60a6e8b..547cce394 100755 --- a/src/core/hid/motion_input.cpp +++ b/src/core/hid/motion_input.cpp @@ -37,11 +37,17 @@ void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) { gyro.y = std::clamp(gyro.y, -GyroMaxValue, GyroMaxValue); gyro.z = std::clamp(gyro.z, -GyroMaxValue, GyroMaxValue); - // Auto adjust drift to minimize drift + // Auto adjust gyro_bias to minimize drift if (!IsMoving(IsAtRestRelaxed)) { gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f); } + // Adjust drift when calibration mode is enabled + if (calibration_mode) { + gyro_bias = (gyro_bias * 0.99f) + (gyroscope * 0.01f); + StopCalibration(); + } + if (gyro.Length() < gyro_threshold * user_gyro_threshold) { gyro = {}; } else { @@ -107,6 +113,19 @@ void MotionInput::UpdateRotation(u64 elapsed_time) { rotations += gyro * sample_period; } +void MotionInput::Calibrate() { + calibration_mode = true; + calibration_counter = 0; +} + +void MotionInput::StopCalibration() { + if (calibration_counter++ > CalibrationSamples) { + calibration_mode = false; + ResetQuaternion(); + ResetRotations(); + } +} + // Based on Madgwick's implementation of Mayhony's AHRS algorithm. // https://github.com/xioTechnologies/Open-Source-AHRS-With-x-IMU/blob/master/x-IMU%20IMU%20and%20AHRS%20Algorithms/x-IMU%20IMU%20and%20AHRS%20Algorithms/AHRS/MahonyAHRS.cs void MotionInput::UpdateOrientation(u64 elapsed_time) { diff --git a/src/core/hid/motion_input.h b/src/core/hid/motion_input.h index 86acbadbd..211d6740a 100755 --- a/src/core/hid/motion_input.h +++ b/src/core/hid/motion_input.h @@ -23,6 +23,8 @@ public: static constexpr float GyroMaxValue = 5.0f; static constexpr float AccelMaxValue = 7.0f; + static constexpr std::size_t CalibrationSamples = 300; + explicit MotionInput(); MotionInput(const MotionInput&) = default; @@ -49,6 +51,8 @@ public: void UpdateRotation(u64 elapsed_time); void UpdateOrientation(u64 elapsed_time); + void Calibrate(); + [[nodiscard]] std::array GetOrientation() const; [[nodiscard]] Common::Vec3f GetAcceleration() const; [[nodiscard]] Common::Vec3f GetGyroscope() const; @@ -61,6 +65,7 @@ public: [[nodiscard]] bool IsCalibrated(f32 sensitivity) const; private: + void StopCalibration(); void ResetOrientation(); void SetOrientationFromAccelerometer(); @@ -103,6 +108,12 @@ private: // Use accelerometer values to calculate position bool only_accelerometer = true; + + // When enabled it will aggressively adjust for gyro drift + bool calibration_mode = false; + + // Used to auto disable calibration mode + std::size_t calibration_counter = 0; }; } // namespace Core::HID diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp index 76790af27..9d2ba757e 100755 --- a/src/input_common/drivers/sdl_driver.cpp +++ b/src/input_common/drivers/sdl_driver.cpp @@ -109,14 +109,37 @@ public: } bool RumblePlay(const Common::Input::VibrationStatus vibration) { - constexpr u32 rumble_max_duration_ms = 1000; + constexpr u32 rumble_max_duration_ms = 2000; + constexpr f32 low_start_sensitivity_limit = 140.0; + constexpr f32 low_width_sensitivity_limit = 400.0; + constexpr f32 high_start_sensitivity_limit = 200.0; + constexpr f32 high_width_sensitivity_limit = 700.0; + // Try to provide some feeling of the frequency by reducing the amplitude depending on it. + f32 low_frequency_scale = 1.0; + if (vibration.low_frequency > low_start_sensitivity_limit) { + low_frequency_scale = + std::max(1.0f - (vibration.low_frequency - low_start_sensitivity_limit) / + low_width_sensitivity_limit, + 0.3f); + } + f32 low_amplitude = vibration.low_amplitude * low_frequency_scale; + + f32 high_frequency_scale = 1.0; + if (vibration.high_frequency > high_start_sensitivity_limit) { + high_frequency_scale = + std::max(1.0f - (vibration.high_frequency - high_start_sensitivity_limit) / + high_width_sensitivity_limit, + 0.3f); + } + f32 high_amplitude = vibration.high_amplitude * high_frequency_scale; + if (sdl_controller) { - return SDL_GameControllerRumble( - sdl_controller.get(), static_cast(vibration.low_amplitude), - static_cast(vibration.high_amplitude), rumble_max_duration_ms) != -1; + return SDL_GameControllerRumble(sdl_controller.get(), static_cast(low_amplitude), + static_cast(high_amplitude), + rumble_max_duration_ms) != -1; } else if (sdl_joystick) { - return SDL_JoystickRumble(sdl_joystick.get(), static_cast(vibration.low_amplitude), - static_cast(vibration.high_amplitude), + return SDL_JoystickRumble(sdl_joystick.get(), static_cast(low_amplitude), + static_cast(high_amplitude), rumble_max_duration_ms) != -1; } diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 224d9cc55..ee1da6a56 100755 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -1284,7 +1284,7 @@ typename BufferCache

::OverlapResult BufferCache

::ResolveOverlaps(VAddr cpu const VAddr overlap_cpu_addr = overlap.CpuAddr(); const bool expands_left = overlap_cpu_addr < begin; if (expands_left) { - cpu_addr = begin = overlap_cpu_addr; + begin = overlap_cpu_addr; } const VAddr overlap_end = overlap_cpu_addr + overlap.SizeBytes(); const bool expands_right = overlap_end > end; @@ -1297,8 +1297,10 @@ typename BufferCache

::OverlapResult BufferCache

::ResolveOverlaps(VAddr cpu // as a stream buffer. Increase the size to skip constantly recreating buffers. has_stream_leap = true; if (expands_right) { - begin -= CACHING_PAGESIZE * 256; - cpu_addr = begin; + begin -= YUZU_PAGESIZE * 256; + // We're about to increment cpu_addr by YUZU_PAGESIZE, but have not yet checked for + // a buffer at the new begin. + cpu_addr = begin - YUZU_PAGESIZE; } if (expands_left) { end += CACHING_PAGESIZE * 256; @@ -1321,7 +1323,7 @@ void BufferCache

::JoinOverlap(BufferId new_buffer_id, BufferId overlap_id, if (accumulate_stream_score) { new_buffer.IncreaseStreamScore(overlap.StreamScore() + 1); } - boost::container::small_vector copies; + boost::container::small_vector copies; const size_t dst_base_offset = overlap.CpuAddr() - new_buffer.CpuAddr(); copies.push_back(BufferCopy{ .src_offset = 0, diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp index 498afa308..8ab6b8be0 100755 --- a/src/yuzu/configuration/configure_graphics_advanced.cpp +++ b/src/yuzu/configuration/configure_graphics_advanced.cpp @@ -12,11 +12,11 @@ ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(const Core::System& system_ ui->setupUi(this); - ui->enable_compute_pipelines_checkbox->setVisible(false); - SetupPerGameUI(); SetConfiguration(); + + ui->enable_compute_pipelines_checkbox->setVisible(false); } ConfigureGraphicsAdvanced::~ConfigureGraphicsAdvanced() = default; diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index e1ad7cbcf..4bc0b6a16 100755 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -479,6 +479,9 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i param.Set("threshold", new_threshold / 1000.0f); emulated_controller->SetMotionParam(motion_id, param); }); + context_menu.addAction(tr("Calibrate sensor"), [&] { + emulated_controller->StartMotionCalibration(); + }); } context_menu.exec(motion_map[motion_id]->mapToGlobal(menu_location)); }); diff --git a/src/yuzu/configuration/configure_input_player_widget.cpp b/src/yuzu/configuration/configure_input_player_widget.cpp index 0b66912f5..b4f6a40f9 100755 --- a/src/yuzu/configuration/configure_input_player_widget.cpp +++ b/src/yuzu/configuration/configure_input_player_widget.cpp @@ -582,9 +582,9 @@ void PlayerControlPreview::DrawDualController(QPainter& p, const QPointF center) using namespace Settings::NativeMotion; p.setPen(colors.outline); p.setBrush(colors.transparent); - Draw3dCube(p, center + QPointF(-180, -5), + Draw3dCube(p, center + QPointF(-180, 90), motion_values[Settings::NativeMotion::MotionLeft].euler, 20.0f); - Draw3dCube(p, center + QPointF(180, -5), + Draw3dCube(p, center + QPointF(180, 90), motion_values[Settings::NativeMotion::MotionRight].euler, 20.0f); } @@ -2926,14 +2926,14 @@ void PlayerControlPreview::DrawArrow(QPainter& p, const QPointF center, const Di void PlayerControlPreview::Draw3dCube(QPainter& p, QPointF center, const Common::Vec3f& euler, float size) { std::array cube{ - Common::Vec3f{-1, -1, -1}, - {-1, 1, -1}, - {1, 1, -1}, - {1, -1, -1}, - {-1, -1, 1}, - {-1, 1, 1}, - {1, 1, 1}, - {1, -1, 1}, + Common::Vec3f{-0.7f, -1, -0.5f}, + {-0.7f, 1, -0.5f}, + {0.7f, 1, -0.5f}, + {0.7f, -1, -0.5f}, + {-0.7f, -1, 0.5f}, + {-0.7f, 1, 0.5f}, + {0.7f, 1, 0.5f}, + {0.7f, -1, 0.5f}, }; for (Common::Vec3f& point : cube) { diff --git a/src/yuzu/qt_common.cpp b/src/yuzu/qt_common.cpp index 5ac9fe310..5d0fd7674 100755 --- a/src/yuzu/qt_common.cpp +++ b/src/yuzu/qt_common.cpp @@ -8,7 +8,7 @@ #include "core/frontend/emu_window.h" #include "yuzu/qt_common.h" -#ifdef __linux__ +#if !defined(WIN32) && !defined(__APPLE__) #include #endif