early-access version 3573

This commit is contained in:
pineappleEA 2023-05-09 01:09:44 +02:00
parent 17b9efbffd
commit 8b74a66045
11 changed files with 92 additions and 25 deletions

View file

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

View file

@ -688,6 +688,12 @@ void EmulatedController::SetMotionParam(std::size_t index, Common::ParamPackage
ReloadInput(); 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, void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback, std::size_t index,
Common::UUID uuid) { Common::UUID uuid) {
if (index >= controller.button_values.size()) { if (index >= controller.button_values.size()) {

View file

@ -290,6 +290,9 @@ public:
*/ */
void SetMotionParam(std::size_t index, Common::ParamPackage param); 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 /// Returns the latest button status from the controller with parameters
ButtonValues GetButtonsValues() const; ButtonValues GetButtonsValues() const;

View file

@ -37,11 +37,17 @@ void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) {
gyro.y = std::clamp(gyro.y, -GyroMaxValue, GyroMaxValue); gyro.y = std::clamp(gyro.y, -GyroMaxValue, GyroMaxValue);
gyro.z = std::clamp(gyro.z, -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)) { if (!IsMoving(IsAtRestRelaxed)) {
gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f); 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) { if (gyro.Length() < gyro_threshold * user_gyro_threshold) {
gyro = {}; gyro = {};
} else { } else {
@ -107,6 +113,19 @@ void MotionInput::UpdateRotation(u64 elapsed_time) {
rotations += gyro * sample_period; 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. // 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 // 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) { void MotionInput::UpdateOrientation(u64 elapsed_time) {

View file

@ -23,6 +23,8 @@ public:
static constexpr float GyroMaxValue = 5.0f; static constexpr float GyroMaxValue = 5.0f;
static constexpr float AccelMaxValue = 7.0f; static constexpr float AccelMaxValue = 7.0f;
static constexpr std::size_t CalibrationSamples = 300;
explicit MotionInput(); explicit MotionInput();
MotionInput(const MotionInput&) = default; MotionInput(const MotionInput&) = default;
@ -49,6 +51,8 @@ public:
void UpdateRotation(u64 elapsed_time); void UpdateRotation(u64 elapsed_time);
void UpdateOrientation(u64 elapsed_time); void UpdateOrientation(u64 elapsed_time);
void Calibrate();
[[nodiscard]] std::array<Common::Vec3f, 3> GetOrientation() const; [[nodiscard]] std::array<Common::Vec3f, 3> GetOrientation() const;
[[nodiscard]] Common::Vec3f GetAcceleration() const; [[nodiscard]] Common::Vec3f GetAcceleration() const;
[[nodiscard]] Common::Vec3f GetGyroscope() const; [[nodiscard]] Common::Vec3f GetGyroscope() const;
@ -61,6 +65,7 @@ public:
[[nodiscard]] bool IsCalibrated(f32 sensitivity) const; [[nodiscard]] bool IsCalibrated(f32 sensitivity) const;
private: private:
void StopCalibration();
void ResetOrientation(); void ResetOrientation();
void SetOrientationFromAccelerometer(); void SetOrientationFromAccelerometer();
@ -103,6 +108,12 @@ private:
// Use accelerometer values to calculate position // Use accelerometer values to calculate position
bool only_accelerometer = true; 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 } // namespace Core::HID

View file

@ -109,14 +109,37 @@ public:
} }
bool RumblePlay(const Common::Input::VibrationStatus vibration) { 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) { if (sdl_controller) {
return SDL_GameControllerRumble( return SDL_GameControllerRumble(sdl_controller.get(), static_cast<u16>(low_amplitude),
sdl_controller.get(), static_cast<u16>(vibration.low_amplitude), static_cast<u16>(high_amplitude),
static_cast<u16>(vibration.high_amplitude), rumble_max_duration_ms) != -1; rumble_max_duration_ms) != -1;
} else if (sdl_joystick) { } else if (sdl_joystick) {
return SDL_JoystickRumble(sdl_joystick.get(), static_cast<u16>(vibration.low_amplitude), return SDL_JoystickRumble(sdl_joystick.get(), static_cast<u16>(low_amplitude),
static_cast<u16>(vibration.high_amplitude), static_cast<u16>(high_amplitude),
rumble_max_duration_ms) != -1; rumble_max_duration_ms) != -1;
} }

View file

@ -1284,7 +1284,7 @@ typename BufferCache<P>::OverlapResult BufferCache<P>::ResolveOverlaps(VAddr cpu
const VAddr overlap_cpu_addr = overlap.CpuAddr(); const VAddr overlap_cpu_addr = overlap.CpuAddr();
const bool expands_left = overlap_cpu_addr < begin; const bool expands_left = overlap_cpu_addr < begin;
if (expands_left) { if (expands_left) {
cpu_addr = begin = overlap_cpu_addr; begin = overlap_cpu_addr;
} }
const VAddr overlap_end = overlap_cpu_addr + overlap.SizeBytes(); const VAddr overlap_end = overlap_cpu_addr + overlap.SizeBytes();
const bool expands_right = overlap_end > end; const bool expands_right = overlap_end > end;
@ -1297,8 +1297,10 @@ typename BufferCache<P>::OverlapResult BufferCache<P>::ResolveOverlaps(VAddr cpu
// as a stream buffer. Increase the size to skip constantly recreating buffers. // as a stream buffer. Increase the size to skip constantly recreating buffers.
has_stream_leap = true; has_stream_leap = true;
if (expands_right) { if (expands_right) {
begin -= CACHING_PAGESIZE * 256; begin -= YUZU_PAGESIZE * 256;
cpu_addr = begin; // 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) { if (expands_left) {
end += CACHING_PAGESIZE * 256; end += CACHING_PAGESIZE * 256;
@ -1321,7 +1323,7 @@ void BufferCache<P>::JoinOverlap(BufferId new_buffer_id, BufferId overlap_id,
if (accumulate_stream_score) { if (accumulate_stream_score) {
new_buffer.IncreaseStreamScore(overlap.StreamScore() + 1); new_buffer.IncreaseStreamScore(overlap.StreamScore() + 1);
} }
boost::container::small_vector<BufferCopy, 1> copies; boost::container::small_vector<BufferCopy, 10> copies;
const size_t dst_base_offset = overlap.CpuAddr() - new_buffer.CpuAddr(); const size_t dst_base_offset = overlap.CpuAddr() - new_buffer.CpuAddr();
copies.push_back(BufferCopy{ copies.push_back(BufferCopy{
.src_offset = 0, .src_offset = 0,

View file

@ -12,11 +12,11 @@ ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(const Core::System& system_
ui->setupUi(this); ui->setupUi(this);
ui->enable_compute_pipelines_checkbox->setVisible(false);
SetupPerGameUI(); SetupPerGameUI();
SetConfiguration(); SetConfiguration();
ui->enable_compute_pipelines_checkbox->setVisible(false);
} }
ConfigureGraphicsAdvanced::~ConfigureGraphicsAdvanced() = default; ConfigureGraphicsAdvanced::~ConfigureGraphicsAdvanced() = default;

View file

@ -479,6 +479,9 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
param.Set("threshold", new_threshold / 1000.0f); param.Set("threshold", new_threshold / 1000.0f);
emulated_controller->SetMotionParam(motion_id, param); 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)); context_menu.exec(motion_map[motion_id]->mapToGlobal(menu_location));
}); });

View file

@ -582,9 +582,9 @@ void PlayerControlPreview::DrawDualController(QPainter& p, const QPointF center)
using namespace Settings::NativeMotion; using namespace Settings::NativeMotion;
p.setPen(colors.outline); p.setPen(colors.outline);
p.setBrush(colors.transparent); p.setBrush(colors.transparent);
Draw3dCube(p, center + QPointF(-180, -5), Draw3dCube(p, center + QPointF(-180, 90),
motion_values[Settings::NativeMotion::MotionLeft].euler, 20.0f); 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); 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, void PlayerControlPreview::Draw3dCube(QPainter& p, QPointF center, const Common::Vec3f& euler,
float size) { float size) {
std::array<Common::Vec3f, 8> cube{ std::array<Common::Vec3f, 8> cube{
Common::Vec3f{-1, -1, -1}, Common::Vec3f{-0.7f, -1, -0.5f},
{-1, 1, -1}, {-0.7f, 1, -0.5f},
{1, 1, -1}, {0.7f, 1, -0.5f},
{1, -1, -1}, {0.7f, -1, -0.5f},
{-1, -1, 1}, {-0.7f, -1, 0.5f},
{-1, 1, 1}, {-0.7f, 1, 0.5f},
{1, 1, 1}, {0.7f, 1, 0.5f},
{1, -1, 1}, {0.7f, -1, 0.5f},
}; };
for (Common::Vec3f& point : cube) { for (Common::Vec3f& point : cube) {

View file

@ -8,7 +8,7 @@
#include "core/frontend/emu_window.h" #include "core/frontend/emu_window.h"
#include "yuzu/qt_common.h" #include "yuzu/qt_common.h"
#ifdef __linux__ #if !defined(WIN32) && !defined(__APPLE__)
#include <qpa/qplatformnativeinterface.h> #include <qpa/qplatformnativeinterface.h>
#endif #endif