Untie existing mouse logic from gyro

This commit is contained in:
Irastris
2026-05-11 01:51:11 -04:00
parent ba6ef0d250
commit 320f4558a8
14 changed files with 153 additions and 117 deletions
+1
View File
@@ -1431,6 +1431,7 @@ set(DUSK_FILES
src/dusk/game_clock.cpp
src/dusk/globals.cpp
src/dusk/gyro.cpp
src/dusk/mouse.cpp
src/dusk/gamepad_color.cpp
src/dusk/autosave.cpp
src/dusk/http/http.hpp
+1 -1
View File
@@ -4551,7 +4551,7 @@ public:
#if TARGET_PC
void handleWolfHowl();
void handleQuickTransform();
bool checkGyroAimContext();
bool checkAimContext();
void onIronBallChainInterpCallback();
+1 -4
View File
@@ -1,5 +1,4 @@
#ifndef DUSK_GYRO_H
#define DUSK_GYRO_H
#pragma once
namespace dusk::gyro {
void read(float dt);
@@ -14,5 +13,3 @@ bool get_sensor_keep_alive();
void set_sensor_keep_alive(bool value);
bool rollgoal_gyro_enabled();
} // namespace dusk::gyro
#endif
+6
View File
@@ -0,0 +1,6 @@
#pragma once
namespace dusk::mouse {
void read();
void getAimDeltas(float& out_yaw, float& out_pitch);
} // namespace dusk::mouse
+3 -1
View File
@@ -175,7 +175,6 @@ struct UserSettings {
ConfigVar<bool> midnasLamentNonStop;
// Input
ConfigVar<GyroMode> gyroMode;
ConfigVar<bool> enableGyroAim;
ConfigVar<bool> enableGyroRollgoal;
ConfigVar<float> gyroSensitivityX;
@@ -185,6 +184,9 @@ struct UserSettings {
ConfigVar<float> gyroDeadband;
ConfigVar<bool> gyroInvertPitch;
ConfigVar<bool> gyroInvertYaw;
ConfigVar<bool> enableMouseAim;
ConfigVar<float> mouseSensitivityX;
ConfigVar<float> mouseSensitivityY;
ConfigVar<bool> freeCamera;
ConfigVar<bool> invertCameraXAxis;
ConfigVar<bool> invertCameraYAxis;
+1 -1
View File
@@ -144,7 +144,7 @@ void daAlink_c::handleQuickTransform() {
procCoMetamorphoseInit();
}
bool daAlink_c::checkGyroAimContext() {
bool daAlink_c::checkAimContext() {
switch (mProcID) {
case PROC_SUBJECTIVITY:
case PROC_SWIM_SUBJECTIVITY:
+20 -7
View File
@@ -11,8 +11,9 @@
#include "d/actor/d_a_tag_mhint.h"
#if TARGET_PC
#include "dusk/gyro.h"
#include "dusk/action_bindings.h"
#include "dusk/gyro.h"
#include "dusk/mouse.h"
#endif
bool daAlink_c::checkNoSubjectModeCamera() {
@@ -131,7 +132,10 @@ BOOL daAlink_c::setBodyAngleToCamera() {
}
#if TARGET_PC
if (dusk::getSettings().game.enableGyroAim && checkGyroAimContext()) {
if ((dusk::getSettings().game.enableGyroAim ||
dusk::getSettings().game.enableMouseAim) &&
checkAimContext())
{
f32 gyro_scale = 1.0f;
if (checkWolfEyeUp()) {
gyro_scale *= 0.6f;
@@ -141,12 +145,21 @@ BOOL daAlink_c::setBodyAngleToCamera() {
gyro_scale /= dComIfGp_getCameraZoomScale(field_0x317c);
}
f32 gy_yaw = 0.f;
f32 gy_pitch = 0.f;
dusk::gyro::getAimDeltas(gy_yaw, gy_pitch);
f32 final_yaw = 0.f;
f32 final_pitch = 0.f;
if (dusk::getSettings().game.enableMouseAim) {
dusk::mouse::getAimDeltas(final_yaw, final_pitch);
}
if (dusk::getSettings().game.enableGyroAim) {
f32 gyro_yaw = 0.f;
f32 gyro_pitch = 0.f;
dusk::gyro::getAimDeltas(gyro_yaw, gyro_pitch);
final_yaw += gyro_yaw;
final_pitch += gyro_pitch;
}
shape_angle.y = shape_angle.y + cM_rad2s(gy_yaw * gyro_scale);
sp8 = sp8 + cM_rad2s(gy_pitch * gyro_scale);
shape_angle.y = shape_angle.y + cM_rad2s(final_yaw * gyro_scale * (dusk::getSettings().game.invertFirstPersonXAxis ? -1.0f : 1.0f));
sp8 = sp8 + cM_rad2s(final_pitch * gyro_scale * (dusk::getSettings().game.invertFirstPersonYAxis ? -1.0f : 1.0f));
if (checkNotItemSinkLimit() && sp8 > 0 && sp8 > mBodyAngle.x) {
sp8 = mBodyAngle.x;
+2 -53
View File
@@ -2,8 +2,6 @@
#include "dusk/ui/ui.hpp"
#include "d/actor/d_a_alink.h"
#include <aurora/lib/window.hpp>
#include <SDL3/SDL_mouse.h>
#include <cmath>
namespace dusk::gyro {
@@ -16,14 +14,11 @@ constexpr float kGravityEmaAlpha = 0.1f;
constexpr float kMinGravityProjection = 0.2f;
// Let roll contribute more strongly as the pad approaches an upright posture.
constexpr float kRollAimBoostMax = 2.0f;
constexpr float kMousePixelToRad = 0.0025f;
bool s_sensor_enabled = false;
bool s_accel_enabled = false;
bool s_was_aiming = false;
bool s_have_gravity_baseline = false;
bool s_mouse_enabled = false;
bool s_mouse_relative = false;
float s_smooth_gx = 0.0f;
float s_smooth_gy = 0.0f;
float s_smooth_gz = 0.0f;
@@ -43,7 +38,6 @@ void reset_filter_state() {
s_baseline_gravity_y = s_baseline_gravity_z = 0.0f;
s_was_aiming = false;
s_have_gravity_baseline = false;
s_mouse_enabled = false;
s_yaw_rad = s_pitch_rad = s_roll_rad = 0.0f;
s_rollgoal_ax = s_rollgoal_az = 0;
}
@@ -72,7 +66,7 @@ bool get_sensor_keep_alive() { return s_sensor_keep_alive; }
void set_sensor_keep_alive(bool value) { s_sensor_keep_alive = value; }
bool rollgoal_gyro_enabled() {
return getSettings().game.enableGyroRollgoal && getSettings().game.gyroMode.getValue() != GyroMode::Mouse;
return getSettings().game.enableGyroRollgoal;
}
bool queryGyroAimContext() {
@@ -85,7 +79,7 @@ bool queryGyroAimContext() {
return false;
}
return link->checkGyroAimContext() && dComIfGp_checkCameraAttentionStatus(link->field_0x317c, 0x10);
return link->checkAimContext() && dComIfGp_checkCameraAttentionStatus(link->field_0x317c, 0x10);
}
void read(float dt) {
@@ -94,26 +88,6 @@ void read(float dt) {
const bool aim_just_ended = !aim_active && s_was_aiming;
s_was_aiming = aim_active;
const bool mouse_mode = getSettings().game.gyroMode.getValue() == GyroMode::Mouse;
const bool mouse_gyro_active = !ui::any_document_visible() && mouse_mode && (aim_active || s_sensor_keep_alive);
SDL_Window* window = aurora::window::get_sdl_window();
if (window != nullptr && mouse_gyro_active != s_mouse_relative &&
SDL_SetWindowRelativeMouseMode(window, mouse_gyro_active))
{
s_mouse_relative = mouse_gyro_active;
}
if (mouse_gyro_active && !s_mouse_enabled && window != nullptr) {
const AuroraWindowSize sz = aurora::window::get_window_size();
const float cx = static_cast<float>(sz.width) * 0.5f;
const float cy = static_cast<float>(sz.height) * 0.5f;
SDL_WarpMouseInWindow(window, cx, cy);
float discard_x = 0.0f;
float discard_y = 0.0f;
SDL_GetRelativeMouseState(&discard_x, &discard_y);
}
s_mouse_enabled = mouse_gyro_active;
if (!s_sensor_keep_alive && !aim_active) {
disable_pad_sensors();
reset_filter_state();
@@ -126,31 +100,6 @@ void read(float dt) {
s_have_gravity_baseline = false;
}
if (mouse_mode && !mouse_gyro_active) {
s_pitch_rad = 0.0f;
s_yaw_rad = 0.0f;
s_roll_rad = 0.0f;
return;
}
if (mouse_mode) {
disable_pad_sensors();
float mx_rel = 0.0f;
float my_rel = 0.0f;
SDL_GetRelativeMouseState(&mx_rel, &my_rel);
// Convert pixels to radians
s_pitch_rad = my_rel * kMousePixelToRad * getSettings().game.gyroSensitivityY;
s_yaw_rad = -mx_rel * kMousePixelToRad * getSettings().game.gyroSensitivityX;
s_roll_rad = 0.0f;
s_pitch_rad = getSettings().game.gyroInvertPitch ? -s_pitch_rad : s_pitch_rad;
s_yaw_rad = getSettings().game.gyroInvertYaw ? -s_yaw_rad : s_yaw_rad;
s_yaw_rad = getSettings().game.enableMirrorMode ? -s_yaw_rad : s_yaw_rad;
return;
}
if (!s_sensor_enabled) {
if (!PADHasSensor(PAD_CHAN0, PAD_SENSOR_GYRO)) {
return;
+1 -1
View File
@@ -377,7 +377,7 @@ namespace dusk {
}
// Hide mouse cursor if the F1 menu is not open and the cursor is idle for 3 seconds.
if (dusk::getSettings().game.gyroMode.getValue() != GyroMode::Mouse)
if (!dusk::getSettings().game.enableMouseAim)
{
ImGuiIO& io = ImGui::GetIO();
if (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f) {
+92
View File
@@ -0,0 +1,92 @@
#include "dusk/mouse.h"
#include "dusk/gyro.h"
#include "dusk/settings.h"
#include "dusk/ui/ui.hpp"
#include "d/actor/d_a_alink.h"
#include <aurora/lib/window.hpp>
#include <SDL3/SDL_mouse.h>
namespace dusk::mouse {
namespace {
constexpr float kMousePixelToRad = 0.0025f;
bool s_mouse_enabled = false;
bool s_mouse_relative = false;
float s_yaw_rad = 0.0f;
float s_pitch_rad = 0.0f;
bool queryMouseAimContext() {
if (!static_cast<bool>(getSettings().game.enableMouseAim)) {
return false;
}
daAlink_c* link = daAlink_getAlinkActorClass();
if (link == nullptr) {
return false;
}
return link->checkAimContext() && dComIfGp_checkCameraAttentionStatus(link->field_0x317c, 0x10);
}
void reset_aim_state() {
s_mouse_enabled = false;
s_yaw_rad = s_pitch_rad = 0.0f;
}
} // namespace
void read() {
const bool mouse_aim_active = queryMouseAimContext();
const bool mouse_gyro_active =
!ui::any_document_visible() && getSettings().game.enableMouseAim && mouse_aim_active;
SDL_Window* window = aurora::window::get_sdl_window();
if (window != nullptr && mouse_gyro_active != s_mouse_relative &&
SDL_SetWindowRelativeMouseMode(window, mouse_gyro_active))
{
s_mouse_relative = mouse_gyro_active;
}
if (mouse_gyro_active && !s_mouse_enabled && window != nullptr) {
const AuroraWindowSize sz = aurora::window::get_window_size();
const float cx = static_cast<float>(sz.width) * 0.5f;
const float cy = static_cast<float>(sz.height) * 0.5f;
SDL_WarpMouseInWindow(window, cx, cy);
float discard_x = 0.0f;
float discard_y = 0.0f;
SDL_GetRelativeMouseState(&discard_x, &discard_y);
}
s_mouse_enabled = mouse_gyro_active;
if (!dusk::gyro::get_sensor_keep_alive() && !mouse_aim_active) {
reset_aim_state();
return;
}
if (getSettings().game.enableMouseAim && !mouse_gyro_active) {
s_pitch_rad = 0.0f;
s_yaw_rad = 0.0f;
return;
}
if (!getSettings().game.enableMouseAim) {
s_pitch_rad = 0.0f;
s_yaw_rad = 0.0f;
return;
}
float mx_rel = 0.0f;
float my_rel = 0.0f;
SDL_GetRelativeMouseState(&mx_rel, &my_rel);
s_pitch_rad = my_rel * kMousePixelToRad * getSettings().game.mouseSensitivityY;
s_yaw_rad = -mx_rel * kMousePixelToRad * getSettings().game.mouseSensitivityX;
s_yaw_rad = getSettings().game.enableMirrorMode ? -s_yaw_rad : s_yaw_rad;
}
void getAimDeltas(float& out_yaw, float& out_pitch) {
out_yaw = s_yaw_rad;
out_pitch = s_pitch_rad;
}
} // namespace dusk::mouse
+6 -2
View File
@@ -75,7 +75,6 @@ UserSettings g_userSettings = {
.midnasLamentNonStop {"game.midnasLamentNonStop", false},
// Input
.gyroMode {"game.gyroMode", GyroMode::Sensor},
.enableGyroAim {"game.enableGyroAim", false},
.enableGyroRollgoal {"game.enableGyroRollgoal", false},
.gyroSensitivityX {"game.gyroSensitivityX", 1.0f},
@@ -85,6 +84,9 @@ UserSettings g_userSettings = {
.gyroDeadband {"game.gyroDeadband", 0.04f},
.gyroInvertPitch {"game.gyroInvertPitch", false},
.gyroInvertYaw {"game.gyroInvertYaw", false},
.enableMouseAim {"game.enableMouseAim", false},
.mouseSensitivityX {"game.mouseSensitivityX", 1.0f},
.mouseSensitivityY {"game.mouseSensitivityY", 1.0f},
.freeCamera {"game.freeCamera", false},
.invertCameraXAxis {"game.invertCameraXAxis", false},
.invertCameraYAxis {"game.invertCameraYAxis", false},
@@ -268,7 +270,6 @@ void registerSettings() {
Register(g_userSettings.game.alwaysGreatspin);
Register(g_userSettings.game.invincibleEnemies);
Register(g_userSettings.game.enableFrameInterpolation);
Register(g_userSettings.game.gyroMode);
Register(g_userSettings.game.enableGyroAim);
Register(g_userSettings.game.enableGyroRollgoal);
Register(g_userSettings.game.gyroSensitivityX);
@@ -278,6 +279,9 @@ void registerSettings() {
Register(g_userSettings.game.gyroSmoothing);
Register(g_userSettings.game.gyroInvertPitch);
Register(g_userSettings.game.gyroInvertYaw);
Register(g_userSettings.game.enableMouseAim);
Register(g_userSettings.game.mouseSensitivityX);
Register(g_userSettings.game.mouseSensitivityY);
Register(g_userSettings.game.freeCamera);
Register(g_userSettings.game.debugFlyCam);
Register(g_userSettings.game.debugFlyCamLockEvents);
+1 -1
View File
@@ -116,7 +116,7 @@ bool Document::handle_nav_command(Rml::Event& event, NavCommand cmd) {
}
void Document::toggle_cursor_if_gyro(bool cursor_enabled) {
if (dusk::getSettings().game.gyroMode.getValue() == GyroMode::Mouse)
if (dusk::getSettings().game.enableMouseAim)
{
if (cursor_enabled) {
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NoMouseCursorChange;
+15 -46
View File
@@ -379,9 +379,7 @@ int float_setting_percent(ConfigVar<float>& var) {
}
bool gyro_enabled() {
return getSettings().game.enableGyroAim ||
(getSettings().game.enableGyroRollgoal &&
getSettings().game.gyroMode.getValue() != GyroMode::Mouse);
return getSettings().game.enableGyroAim || getSettings().game.enableGyroRollgoal;
}
struct ConfigBoolProps {
@@ -945,50 +943,12 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
"Invert vertical movement while aiming with items or first person camera. Applies only to the control stick (the gyroscope can be inverted in Input settings).");
leftPane.add_section("Gyro");
leftPane.register_control(
leftPane.add_select_button({
.key = "Gyro Input Method",
.getValue =
[] {
const auto mode = getSettings().game.gyroMode.getValue();
const auto idx = static_cast<size_t>(mode);
return Rml::String{kGyroInputModeLabels[idx]};
},
.isModified =
[] {
return getSettings().game.gyroMode.getValue() !=
getSettings().game.gyroMode.getDefaultValue();
},
}),
rightPane, [](Pane& pane) {
for (size_t i = 0; i < kGyroInputModeLabels.size(); i++) {
pane
.add_button({
.text = Rml::String{kGyroInputModeLabels[i]},
.isSelected =
[i] {
return getSettings().game.gyroMode.getValue() == static_cast<GyroMode>(i);
},
})
.on_pressed([i] {
mDoAud_seStartMenu(kSoundItemChange);
const GyroMode mode = static_cast<GyroMode>(i);
getSettings().game.gyroMode.setValue(mode);
config::Save();
});
}
pane.add_rml(
"<br/><b>Sensor</b> reads motion directly from a supported controller's gyro via SDL.<br/>"
"<br/><b>Mouse</b> treats mouse input as gyro, intended for use with the Steam Deck.<br/>"
"<br/>Mouse input cannot currently be used with Gyro Rollgoal.");
});
addOption("Gyro Aim", getSettings().game.enableGyroAim,
"Enables gyro controls while in look mode, aiming a hawk, and aiming "
"supported items.<br/><br/>Supported items include the Slingshot, Gale Boomerang, "
"Hero's Bow, Clawshot(s), Ball and Chain, and Dominion Rod.");
addOption("Gyro Rollgoal", getSettings().game.enableGyroRollgoal,
"Enables gyro controls for Rollgoal in Hena's Cabin.",
[] { return getSettings().game.gyroMode.getValue() == GyroMode::Mouse; });
"Enables gyro controls for Rollgoal in Hena's Cabin.");
config_percent_select(leftPane, rightPane, getSettings().game.gyroSensitivityY,
"Gyro Pitch Sensitivity", "Controls vertical gyro aiming sensitivity.", 25, 400, 5,
[] { return !gyro_enabled(); });
@@ -998,10 +958,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
config_percent_select(leftPane, rightPane, getSettings().game.gyroSensitivityRollgoal,
"Rollgoal Sensitivity", "Controls how strongly gyro input tilts the Rollgoal table.",
25, 400, 5,
[] {
return !getSettings().game.enableGyroRollgoal ||
getSettings().game.gyroMode.getValue() == GyroMode::Mouse;
});
[] { return !getSettings().game.enableGyroRollgoal; });
config_percent_select(leftPane, rightPane, getSettings().game.gyroDeadband, "Gyro Deadband",
"Ignores small gyro movement to reduce drift and jitter.", 0, 50, 1,
[] { return !gyro_enabled(); });
@@ -1013,6 +970,18 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
addOption("Invert Gyro Yaw", getSettings().game.gyroInvertYaw,
"Invert horizontal gyro aiming.", [] { return !gyro_enabled(); });
leftPane.add_section("Mouse");
addOption("Mouse Aim", getSettings().game.enableMouseAim,
"Enables mouse input while in look mode, aiming a hawk, and aiming "
"supported items.<br/><br/>Supported items include the Slingshot, Gale Boomerang, "
"Hero's Bow, Clawshot(s), Ball and Chain, and Dominion Rod.");
config_percent_select(leftPane, rightPane, getSettings().game.mouseSensitivityX,
"Mouse X Sensitivity", "Controls horizontal mouse sensitivity.", 25, 400, 5,
[] { return !getSettings().game.enableMouseAim; });
config_percent_select(leftPane, rightPane, getSettings().game.mouseSensitivityY,
"Mouse Y Sensitivity", "Controls vertical mouse sensitivity.", 25, 400, 5,
[] { return !getSettings().game.enableMouseAim; });
leftPane.add_section("Tools");
addOption("Turbo Key", getSettings().game.enableTurboKeybind,
"Hold Tab to increase game speed by up to 4x.",
+3
View File
@@ -54,6 +54,7 @@
#include "dusk/frame_interpolation.h"
#include "dusk/game_clock.h"
#include "dusk/gyro.h"
#include "dusk/mouse.h"
#include "dusk/imgui/ImGuiConsole.hpp"
#include "dusk/imgui/ImGuiEngine.hpp"
#include "dusk/iso_validate.hpp"
@@ -286,6 +287,7 @@ void main01(void) {
for (int sim_tick = 0; sim_tick < pacing.sim_ticks_to_run; ++sim_tick) {
dusk::frame_interp::begin_sim_tick();
mDoCPd_c::read();
dusk::mouse::read();
dusk::gyro::read(pacing.sim_pace);
fapGm_Execute();
mDoAud_Execute();
@@ -308,6 +310,7 @@ void main01(void) {
// Game Inputs
mDoCPd_c::read();
dusk::mouse::read();
dusk::gyro::read(pacing.presentation_dt_seconds);
// EXECUTE GAME LOGIC & RENDER