mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-05-27 07:37:24 -04:00
Gyro: Revisions & Rollgoal Mirror Mode
This commit is contained in:
+2
-2
@@ -3,11 +3,11 @@
|
||||
|
||||
namespace dusk::gyro {
|
||||
void read(float dt);
|
||||
void consumeAimDeltas(float& out_yaw_rad, float& out_pitch_rad);
|
||||
void getAimDeltas(float& out_yaw, float& out_pitch);
|
||||
bool queryGyroAimItemContext();
|
||||
|
||||
void rollgoalTick(bool play_active, s16 camera_yaw);
|
||||
void rollgoalTableOffset(s16& out_add_x, s16& out_add_z);
|
||||
void rollgoalTableOffset(s16& out_ax, s16& out_az);
|
||||
|
||||
extern bool s_sensor_keep_alive;
|
||||
bool get_sensor_keep_alive();
|
||||
|
||||
@@ -82,11 +82,13 @@ struct UserSettings {
|
||||
// Input
|
||||
ConfigVar<bool> enableGyroAim;
|
||||
ConfigVar<bool> enableGyroRollgoal;
|
||||
ConfigVar<float> gyroAimSensitivityX;
|
||||
ConfigVar<float> gyroAimSensitivityY;
|
||||
ConfigVar<float> gyroRollgoalSensitivity;
|
||||
ConfigVar<bool> gyroAimInvertPitch;
|
||||
ConfigVar<bool> gyroAimInvertYaw;
|
||||
ConfigVar<float> gyroSensitivityX;
|
||||
ConfigVar<float> gyroSensitivityY;
|
||||
ConfigVar<float> gyroSensitivityRollgoal;
|
||||
ConfigVar<float> gyroSmoothing;
|
||||
ConfigVar<float> gyroDeadband;
|
||||
ConfigVar<bool> gyroInvertPitch;
|
||||
ConfigVar<bool> gyroInvertYaw;
|
||||
|
||||
// Cheats
|
||||
ConfigVar<bool> enableFastIronBoots;
|
||||
|
||||
@@ -142,17 +142,7 @@ BOOL daAlink_c::setBodyAngleToCamera() {
|
||||
|
||||
f32 gy_yaw = 0.f;
|
||||
f32 gy_pitch = 0.f;
|
||||
dusk::gyro::consumeAimDeltas(gy_yaw, gy_pitch);
|
||||
|
||||
if (dusk::getSettings().game.gyroAimInvertPitch) {
|
||||
gy_pitch = -gy_pitch;
|
||||
}
|
||||
if (dusk::getSettings().game.gyroAimInvertYaw) {
|
||||
gy_yaw = -gy_yaw;
|
||||
}
|
||||
if (dusk::getSettings().game.enableMirrorMode) {
|
||||
gy_yaw = -gy_yaw;
|
||||
}
|
||||
dusk::gyro::getAimDeltas(gy_yaw, gy_pitch);
|
||||
|
||||
shape_angle.y = shape_angle.y + cM_rad2s(gy_yaw * gyro_scale);
|
||||
sp8 = sp8 + cM_rad2s(gy_pitch * gyro_scale);
|
||||
|
||||
+27
-27
@@ -3,31 +3,28 @@
|
||||
|
||||
namespace dusk::gyro {
|
||||
namespace {
|
||||
// TODO: Make deadband and smoothing configurable
|
||||
constexpr float kDeadbandRadS = 0.04f;
|
||||
constexpr float kSmoothAlpha = 0.35f;
|
||||
constexpr s32 kRollgoalTableMaxOffset = 12000;
|
||||
constexpr float kGyroEmaAlphaMin = 0.05f;
|
||||
constexpr float kGyroEmaAlphaMax = 1.0f;
|
||||
|
||||
bool s_sensor_enabled = false;
|
||||
float s_smooth_gx = 0.0f;
|
||||
float s_smooth_gy = 0.0f;
|
||||
float s_smooth_gz = 0.0f;
|
||||
float s_yaw_rad = 0.0f;
|
||||
float s_yaw_rad_pending = 0.0f;
|
||||
float s_pitch_rad = 0.0f;
|
||||
float s_pitch_rad_pending = 0.0f;
|
||||
float s_roll_rad = 0.0f;
|
||||
s32 s_rollgoal_ax = 0;
|
||||
s32 s_rollgoal_az = 0;
|
||||
|
||||
void reset_filter_state() {
|
||||
s_smooth_gx = s_smooth_gy = s_smooth_gz = 0.0f;
|
||||
s_yaw_rad_pending = s_pitch_rad_pending = s_roll_rad = 0.0f;
|
||||
s_yaw_rad = s_pitch_rad = s_roll_rad = 0.0f;
|
||||
s_rollgoal_ax = s_rollgoal_az = 0;
|
||||
}
|
||||
|
||||
float apply_deadband(float v) {
|
||||
if (v > -kDeadbandRadS && v < kDeadbandRadS) {
|
||||
float apply_deadband(float v, float deadband_rad_s) {
|
||||
if (v > -deadband_rad_s && v < deadband_rad_s) {
|
||||
return 0.0f;
|
||||
}
|
||||
return v;
|
||||
@@ -35,7 +32,6 @@ float apply_deadband(float v) {
|
||||
} // namespace
|
||||
|
||||
bool s_sensor_keep_alive = false;
|
||||
|
||||
bool get_sensor_keep_alive() { return s_sensor_keep_alive; }
|
||||
void set_sensor_keep_alive(bool value) { s_sensor_keep_alive = value; }
|
||||
|
||||
@@ -77,22 +73,25 @@ void read(float dt) {
|
||||
return;
|
||||
}
|
||||
|
||||
s_smooth_gx += kSmoothAlpha * (gyro[0] - s_smooth_gx);
|
||||
s_smooth_gy += kSmoothAlpha * (gyro[1] - s_smooth_gy);
|
||||
s_smooth_gz += kSmoothAlpha * (gyro[2] - s_smooth_gz);
|
||||
const float smooth_alpha = kGyroEmaAlphaMax + dusk::getSettings().game.gyroSmoothing * (kGyroEmaAlphaMin - kGyroEmaAlphaMax);
|
||||
const float deadband = dusk::getSettings().game.gyroDeadband;
|
||||
|
||||
s_pitch_rad = apply_deadband(s_smooth_gx) * dt * dusk::getSettings().game.gyroAimSensitivityX;
|
||||
s_yaw_rad = apply_deadband(s_smooth_gy) * dt * dusk::getSettings().game.gyroAimSensitivityY;
|
||||
s_roll_rad = apply_deadband(s_smooth_gz) * dt * dusk::getSettings().game.gyroAimSensitivityX; // GYRO NOTE: Exposing Z sensitivity seems unusual, so I'm just using X
|
||||
s_smooth_gx += smooth_alpha * (gyro[0] - s_smooth_gx);
|
||||
s_smooth_gy += smooth_alpha * (gyro[1] - s_smooth_gy);
|
||||
s_smooth_gz += smooth_alpha * (gyro[2] - s_smooth_gz);
|
||||
|
||||
s_pitch_rad_pending += s_pitch_rad;
|
||||
s_yaw_rad_pending += s_yaw_rad;
|
||||
s_pitch_rad = -apply_deadband(s_smooth_gx, deadband) * dt * dusk::getSettings().game.gyroSensitivityX;
|
||||
s_yaw_rad = apply_deadband(s_smooth_gy, deadband) * dt * dusk::getSettings().game.gyroSensitivityY;
|
||||
s_roll_rad = apply_deadband(s_smooth_gz, deadband) * dt * dusk::getSettings().game.gyroSensitivityX; // GYRO NOTE: Exposing Z sensitivity seems unusual, so I'm just using X
|
||||
|
||||
s_pitch_rad = dusk::getSettings().game.gyroInvertPitch ? -s_pitch_rad : s_pitch_rad;
|
||||
s_yaw_rad = dusk::getSettings().game.gyroInvertYaw ? -s_yaw_rad : s_yaw_rad;
|
||||
s_yaw_rad = dusk::getSettings().game.enableMirrorMode ? -s_yaw_rad : s_yaw_rad;
|
||||
}
|
||||
|
||||
void consumeAimDeltas(float& out_yaw_rad, float& out_pitch_rad) {
|
||||
out_yaw_rad = s_yaw_rad_pending;
|
||||
out_pitch_rad = s_pitch_rad_pending;
|
||||
s_yaw_rad_pending = s_pitch_rad_pending = 0.0f;
|
||||
void getAimDeltas(float& out_yaw, float& out_pitch) {
|
||||
out_yaw = s_yaw_rad;
|
||||
out_pitch = s_pitch_rad;
|
||||
}
|
||||
|
||||
void rollgoalTick(bool play_active, s16 camera_yaw) {
|
||||
@@ -101,13 +100,14 @@ void rollgoalTick(bool play_active, s16 camera_yaw) {
|
||||
return;
|
||||
}
|
||||
|
||||
const float pitch_rad = s_pitch_rad * dusk::getSettings().game.gyroRollgoalSensitivity;
|
||||
const float roll_rad = s_roll_rad * dusk::getSettings().game.gyroRollgoalSensitivity;
|
||||
float pitch_rad = -s_pitch_rad * dusk::getSettings().game.gyroSensitivityRollgoal;
|
||||
float roll_rad = s_roll_rad * dusk::getSettings().game.gyroSensitivityRollgoal;
|
||||
roll_rad = dusk::getSettings().game.enableMirrorMode ? -roll_rad : roll_rad;
|
||||
|
||||
s_rollgoal_az += cM_rad2s(roll_rad);
|
||||
cXyz in(roll_rad, 0.0f, pitch_rad);
|
||||
cXyz out;
|
||||
cMtx_YrotS(*calc_mtx, static_cast<s16>(-camera_yaw));
|
||||
cMtx_YrotS(*calc_mtx, -camera_yaw);
|
||||
MtxPosition(&in, &out);
|
||||
|
||||
s_rollgoal_ax += cM_rad2s(out.z);
|
||||
@@ -116,8 +116,8 @@ void rollgoalTick(bool play_active, s16 camera_yaw) {
|
||||
s_rollgoal_az = std::clamp(s_rollgoal_az, -kRollgoalTableMaxOffset, kRollgoalTableMaxOffset);
|
||||
}
|
||||
|
||||
void rollgoalTableOffset(s16& out_add_x, s16& out_add_z) {
|
||||
out_add_x = static_cast<s16>(s_rollgoal_ax);
|
||||
out_add_z = static_cast<s16>(s_rollgoal_az);
|
||||
void rollgoalTableOffset(s16& out_ax, s16& out_az) {
|
||||
out_ax = static_cast<s16>(s_rollgoal_ax);
|
||||
out_az = static_cast<s16>(s_rollgoal_az);
|
||||
}
|
||||
} // namespace dusk::gyro
|
||||
|
||||
@@ -154,22 +154,32 @@ namespace dusk {
|
||||
"tilt the Rollgoal table in Hena's Cabin.");
|
||||
}
|
||||
|
||||
if (getSettings().game.enableGyroAim) {
|
||||
config::ImGuiSliderFloat("Gyro Pitch Sensitivity", getSettings().game.gyroAimSensitivityY, 0.25f, 4.0f, "%.2f");
|
||||
config::ImGuiSliderFloat("Gyro Yaw Sensitivity", getSettings().game.gyroAimSensitivityX, 0.25f, 4.0f, "%.2f");
|
||||
}
|
||||
if (getSettings().game.enableGyroAim || getSettings().game.enableGyroRollgoal) {
|
||||
config::ImGuiSliderFloat("Gyro Pitch Sensitivity", getSettings().game.gyroSensitivityY, 0.25f, 4.0f, "%.2f");
|
||||
config::ImGuiSliderFloat("Gyro Yaw Sensitivity", getSettings().game.gyroSensitivityX, 0.25f, 4.0f, "%.2f");
|
||||
|
||||
if (getSettings().game.enableGyroRollgoal) {
|
||||
config::ImGuiSliderFloat("Rollgoal Sensitivity", getSettings().game.gyroRollgoalSensitivity, 0.25f, 4.0f, "%.2f");
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Additional multiplier for scaling how strongly\n"
|
||||
"the gyroscope affects the Rollgoal table.");
|
||||
if (getSettings().game.enableGyroRollgoal) {
|
||||
config::ImGuiSliderFloat("Rollgoal Sensitivity", getSettings().game.gyroSensitivityRollgoal, 0.25f, 4.0f, "%.2f");
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Additional multiplier for scaling how strongly\n"
|
||||
"the gyroscope affects the Rollgoal table.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getSettings().game.enableGyroAim) {
|
||||
config::ImGuiCheckbox("Invert Gyro Pitch", getSettings().game.gyroAimInvertPitch);
|
||||
config::ImGuiCheckbox("Invert Gyro Yaw", getSettings().game.gyroAimInvertYaw);
|
||||
config::ImGuiSliderFloat("Gyro Deadband", getSettings().game.gyroDeadband, 0.0f, 0.5f, "%.3f");
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Angular rates below this magnitude are treated as zero,\n"
|
||||
"reducing drift and jitter when the controller is still.");
|
||||
}
|
||||
|
||||
config::ImGuiSliderFloat("Gyro Smoothing", getSettings().game.gyroSmoothing, 0.0f, 1.0f, "%.2f");
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Low values track raw gyro input more closely,\n"
|
||||
"while higher values smooth out input over time.");
|
||||
}
|
||||
|
||||
config::ImGuiCheckbox("Invert Gyro Pitch", getSettings().game.gyroInvertPitch);
|
||||
config::ImGuiCheckbox("Invert Gyro Yaw", getSettings().game.gyroInvertYaw);
|
||||
}
|
||||
|
||||
ImGui::SeparatorText("Tools");
|
||||
|
||||
+14
-10
@@ -56,11 +56,13 @@ UserSettings g_userSettings = {
|
||||
// Input
|
||||
.enableGyroAim {"game.enableGyroAim", false},
|
||||
.enableGyroRollgoal {"game.enableGyroRollgoal", false},
|
||||
.gyroAimSensitivityX {"game.gyroAimSensitivityX", 1.0f},
|
||||
.gyroAimSensitivityY {"game.gyroAimSensitivityY", 1.0f},
|
||||
.gyroRollgoalSensitivity {"game.gyroRollgoalSensitivity", 1.0f},
|
||||
.gyroAimInvertPitch {"game.gyroAimInvertPitch", false},
|
||||
.gyroAimInvertYaw {"game.gyroAimInvertYaw", false},
|
||||
.gyroSensitivityX {"game.gyroSensitivityX", 1.0f},
|
||||
.gyroSensitivityY {"game.gyroSensitivityY", 1.0f},
|
||||
.gyroSensitivityRollgoal {"game.gyroSensitivityRollgoal", 1.0f},
|
||||
.gyroSmoothing {"game.gyroSmoothing", 0.65f},
|
||||
.gyroDeadband {"game.gyroDeadband", 0.04f},
|
||||
.gyroInvertPitch {"game.gyroInvertPitch", false},
|
||||
.gyroInvertYaw {"game.gyroInvertYaw", false},
|
||||
|
||||
// Cheats
|
||||
.enableFastIronBoots {"game.enableFastIronBoots", false},
|
||||
@@ -137,11 +139,13 @@ void registerSettings() {
|
||||
Register(g_userSettings.game.enableFrameInterpolation);
|
||||
Register(g_userSettings.game.enableGyroAim);
|
||||
Register(g_userSettings.game.enableGyroRollgoal);
|
||||
Register(g_userSettings.game.gyroAimSensitivityX);
|
||||
Register(g_userSettings.game.gyroAimSensitivityY);
|
||||
Register(g_userSettings.game.gyroRollgoalSensitivity);
|
||||
Register(g_userSettings.game.gyroAimInvertPitch);
|
||||
Register(g_userSettings.game.gyroAimInvertYaw);
|
||||
Register(g_userSettings.game.gyroSensitivityX);
|
||||
Register(g_userSettings.game.gyroSensitivityY);
|
||||
Register(g_userSettings.game.gyroSensitivityRollgoal);
|
||||
Register(g_userSettings.game.gyroDeadband);
|
||||
Register(g_userSettings.game.gyroSmoothing);
|
||||
Register(g_userSettings.game.gyroInvertPitch);
|
||||
Register(g_userSettings.game.gyroInvertYaw);
|
||||
|
||||
Register(g_userSettings.backend.isoPath);
|
||||
Register(g_userSettings.backend.graphicsBackend);
|
||||
|
||||
Reference in New Issue
Block a user