Compare commits

...

3 Commits

Author SHA1 Message Date
Irastris 42910ab2fd Restore simultaneous gyro and joystick input for first person aiming (#2164) 2026-07-02 00:13:22 -06:00
Olivia!! f54892b2c2 do not disable regular touch input if menu touch is disabled (#2152) 2026-07-02 00:03:53 -06:00
Luke Street f32e069c4b Improve mouse hiding logic (#2163)
* Improve mouse hiding logic

* Restore ImGui logic
2026-07-02 02:03:18 -04:00
6 changed files with 87 additions and 72 deletions
+4 -4
View File
@@ -4,9 +4,9 @@
namespace dusk::mouse { namespace dusk::mouse {
void read(); void read();
void getAimDeltas(float& out_yaw, float& out_pitch); void get_aim_deltas(float& out_yaw, float& out_pitch);
void getCameraDeltas(float& out_yaw, float& out_pitch); void get_camera_deltas(float& out_yaw, float& out_pitch);
void handle_event(const SDL_Event& event) noexcept; void handle_event(const SDL_Event& event) noexcept;
void onFocusLost(); void on_focus_lost();
void onFocusGained(); void on_focus_gained();
} // namespace dusk::mouse } // namespace dusk::mouse
+5 -12
View File
@@ -122,18 +122,11 @@ BOOL daAlink_c::setBodyAngleToCamera() {
var_f31 /= dComIfGp_getCameraZoomScale(field_0x317c); var_f31 /= dComIfGp_getCameraZoomScale(field_0x317c);
} }
#if TARGET_PC shape_angle.y = shape_angle.y + (var_f31 * cM_ssin(mStickAngle) IF_DUSK(* (dusk::getSettings().game.invertFirstPersonXAxis ? -1.0f : 1.0f)));
if (dusk::getSettings().game.enableMouseAim && checkAimInputContext()) { sp8 = mBodyAngle.x + (var_f31 * cM_scos(mStickAngle) IF_DUSK(* (dusk::getSettings().game.invertFirstPersonYAxis ? -1.0f : 1.0f)));
sp8 = mBodyAngle.x;
} else
#endif
{
shape_angle.y = shape_angle.y + (var_f31 * cM_ssin(mStickAngle) IF_DUSK(* (dusk::getSettings().game.invertFirstPersonXAxis ? -1.0f : 1.0f)));
sp8 = mBodyAngle.x + (var_f31 * cM_scos(mStickAngle) IF_DUSK(* (dusk::getSettings().game.invertFirstPersonYAxis ? -1.0f : 1.0f)));
if (checkNotItemSinkLimit() && sp8 > 0 && sp8 > mBodyAngle.x) { if (checkNotItemSinkLimit() && sp8 > 0 && sp8 > mBodyAngle.x) {
sp8 = mBodyAngle.x; sp8 = mBodyAngle.x;
}
} }
} else { } else {
sp8 = mBodyAngle.x; sp8 = mBodyAngle.x;
@@ -156,7 +149,7 @@ BOOL daAlink_c::setBodyAngleToCamera() {
f32 final_yaw = 0.f; f32 final_yaw = 0.f;
f32 final_pitch = 0.f; f32 final_pitch = 0.f;
if (dusk::getSettings().game.enableMouseAim) { if (dusk::getSettings().game.enableMouseAim) {
dusk::mouse::getAimDeltas(final_yaw, final_pitch); dusk::mouse::get_aim_deltas(final_yaw, final_pitch);
} }
if (dusk::getSettings().game.enableGyroAim) { if (dusk::getSettings().game.enableGyroAim) {
f32 gyro_yaw = 0.f; f32 gyro_yaw = 0.f;
+1 -1
View File
@@ -7716,7 +7716,7 @@ bool dCamera_c::freeCamera() {
f32 yaw_rad = 0.0f; f32 yaw_rad = 0.0f;
f32 pitch_rad = 0.0f; f32 pitch_rad = 0.0f;
dusk::mouse::getCameraDeltas(yaw_rad, pitch_rad); dusk::mouse::get_camera_deltas(yaw_rad, pitch_rad);
if (dusk::getSettings().game.enableMouseCamera && (yaw_rad != 0.0f || pitch_rad != 0.0f) && if (dusk::getSettings().game.enableMouseCamera && (yaw_rad != 0.0f || pitch_rad != 0.0f) &&
!dComIfGp_checkCameraAttentionStatus(dComIfGp_getPlayerCameraID(0), 0x8)) !dComIfGp_checkCameraAttentionStatus(dComIfGp_getPlayerCameraID(0), 0x8))
{ {
+1 -1
View File
@@ -314,7 +314,7 @@ void end_game_frame() noexcept {
} }
void begin_context(Context context) noexcept { void begin_context(Context context) noexcept {
if (context == Context::None) { if (context == Context::None || !enabled()) {
return; return;
} }
+74 -52
View File
@@ -1,54 +1,69 @@
#include "dusk/mouse.h" #include "dusk/mouse.h"
#include "d/actor/d_a_alink.h"
#include "d/d_com_inf_game.h"
#include "dusk/menu_pointer.h" #include "dusk/menu_pointer.h"
#include "dusk/settings.h" #include "dusk/settings.h"
#include "dusk/ui/ui.hpp" #include "dusk/ui/ui.hpp"
#include "d/actor/d_a_alink.h"
#include "d/d_com_inf_game.h"
#include <aurora/lib/window.hpp>
#include <imgui.h>
#include <SDL3/SDL_mouse.h> #include <SDL3/SDL_mouse.h>
#include <SDL3/SDL_video.h> #include <SDL3/SDL_video.h>
#include <aurora/lib/window.hpp>
#include <imgui.h>
#include <chrono>
namespace dusk::mouse { namespace dusk::mouse {
namespace { namespace {
constexpr float kMousePixelToRad = 0.0025f; using Clock = std::chrono::steady_clock;
constexpr int kIdleHideFrames = 99; // Approx. 3 seconds with 33ms ticks
float s_aim_yaw_rad = 0.0f; constexpr float kMousePixelToRad = 0.0025f;
float s_aim_pitch_rad = 0.0f; constexpr auto kCursorIdleDuration = std::chrono::seconds(1);
float s_camera_yaw_rad = 0.0f;
float s_aim_yaw_rad = 0.0f;
float s_aim_pitch_rad = 0.0f;
float s_camera_yaw_rad = 0.0f;
float s_camera_pitch_rad = 0.0f; float s_camera_pitch_rad = 0.0f;
int s_idle_frames = 0; Clock::time_point s_last_cursor_motion = Clock::now();
void reset_deltas() { void reset_deltas() {
s_aim_yaw_rad = s_aim_pitch_rad = 0.0f; s_aim_yaw_rad = s_aim_pitch_rad = 0.0f;
s_camera_yaw_rad = s_camera_pitch_rad = 0.0f; s_camera_yaw_rad = s_camera_pitch_rad = 0.0f;
} }
bool queryMouseAimContext() { bool query_mouse_aim_context() {
return getSettings().game.enableMouseAim.getValue() && dCamera_c::isAimActive(); return getSettings().game.enableMouseAim.getValue() && dCamera_c::isAimActive();
} }
bool wantMouseCapture() { bool want_mouse_capture() {
return getSettings().game.enableMouseCamera.getValue() || queryMouseAimContext(); return getSettings().game.enableMouseCamera.getValue() || query_mouse_aim_context();
} }
bool isWindowFocused(SDL_Window* window) { bool mouse_input_enabled() {
const auto& game = getSettings().game;
return game.enableMouseAim.getValue() || game.enableMouseCamera.getValue();
}
bool is_window_focused(SDL_Window* window) {
if (window == nullptr) { if (window == nullptr) {
return false; return false;
} }
return (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) != 0; return (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) != 0;
} }
bool shouldCaptureMouse(SDL_Window* window) { bool imgui_windows_visible() {
if (window == nullptr || ui::any_document_visible() || menu_pointer::active()) { return ImGui::GetIO().MetricsRenderWindows > 0;
return false;
}
return wantMouseCapture() && isWindowFocused(window);
} }
bool syncCaptureState(SDL_Window* window, bool should_capture) { bool should_capture_mouse(SDL_Window* window) {
if (window == nullptr || ui::any_document_visible() || imgui_windows_visible() ||
menu_pointer::active())
{
return false;
}
return want_mouse_capture() && is_window_focused(window);
}
bool sync_capture_state(SDL_Window* window, bool should_capture) {
if (window == nullptr) { if (window == nullptr) {
reset_deltas(); reset_deltas();
return false; return false;
@@ -78,7 +93,7 @@ bool syncCaptureState(SDL_Window* window, bool should_capture) {
return is_captured; return is_captured;
} }
void accumulateDeltas(float mx_rel, float my_rel, bool camera_active, bool aim_active) { void accumulate_deltas(float mx_rel, float my_rel, bool camera_active, bool aim_active) {
const auto& game = getSettings().game; const auto& game = getSettings().game;
const bool mirror_mode = game.enableMirrorMode.getValue(); const bool mirror_mode = game.enableMirrorMode.getValue();
const bool invert_y = game.invertMouseY.getValue(); const bool invert_y = game.invertMouseY.getValue();
@@ -114,57 +129,62 @@ void set_cursor_visible(bool visible) {
} }
} }
void update_cursor_visibility(SDL_Window* window, bool captured) { bool cursor_idle() {
if (window == nullptr || !isWindowFocused(window)) { return Clock::now() - s_last_cursor_motion >= kCursorIdleDuration;
return; }
}
bool should_show_cursor(bool captured) {
if (captured) { if (captured) {
s_idle_frames = 0; return false;
set_cursor_visible(false); }
if (ui::any_document_visible()) {
return true;
}
if (imgui_windows_visible()) {
return true;
}
if (menu_pointer::enabled() && menu_pointer::active()) {
return true;
}
if (mouse_input_enabled()) {
return false;
}
return !cursor_idle();
}
void update_cursor_visibility(SDL_Window* window, bool captured) {
if (window == nullptr || !is_window_focused(window)) {
return; return;
} }
const ImGuiIO& io = ImGui::GetIO(); set_cursor_visible(should_show_cursor(captured));
if (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f) {
s_idle_frames = 0;
set_cursor_visible(true);
return;
}
if (s_idle_frames < kIdleHideFrames) {
++s_idle_frames;
set_cursor_visible(true);
} else {
set_cursor_visible(false);
}
} }
} // namespace } // namespace
void read() { void read() {
SDL_Window* window = aurora::window::get_sdl_window(); SDL_Window* window = aurora::window::get_sdl_window();
const bool capture_active = syncCaptureState(window, shouldCaptureMouse(window)); const bool capture_active = sync_capture_state(window, should_capture_mouse(window));
update_cursor_visibility(window, capture_active); update_cursor_visibility(window, capture_active);
if (!capture_active) { if (!capture_active) {
return; return;
} }
const bool aim_active = capture_active && queryMouseAimContext(); const bool aim_active = capture_active && query_mouse_aim_context();
const bool camera_active = capture_active && getSettings().game.enableMouseCamera; const bool camera_active = capture_active && getSettings().game.enableMouseCamera;
float mx_rel = 0.0f; float mx_rel = 0.0f;
float my_rel = 0.0f; float my_rel = 0.0f;
SDL_GetRelativeMouseState(&mx_rel, &my_rel); SDL_GetRelativeMouseState(&mx_rel, &my_rel);
accumulateDeltas(mx_rel, my_rel, camera_active, aim_active); accumulate_deltas(mx_rel, my_rel, camera_active, aim_active);
} }
void getAimDeltas(float& out_yaw, float& out_pitch) { void get_aim_deltas(float& out_yaw, float& out_pitch) {
out_yaw = s_aim_yaw_rad; out_yaw = s_aim_yaw_rad;
out_pitch = s_aim_pitch_rad; out_pitch = s_aim_pitch_rad;
} }
void getCameraDeltas(float& out_yaw, float& out_pitch) { void get_camera_deltas(float& out_yaw, float& out_pitch) {
out_yaw = 0.0f; out_yaw = 0.0f;
out_pitch = 0.0f; out_pitch = 0.0f;
@@ -178,26 +198,28 @@ void getCameraDeltas(float& out_yaw, float& out_pitch) {
void handle_event(const SDL_Event& event) noexcept { void handle_event(const SDL_Event& event) noexcept {
switch (event.type) { switch (event.type) {
case SDL_EVENT_MOUSE_MOTION:
s_last_cursor_motion = Clock::now();
break;
case SDL_EVENT_WINDOW_FOCUS_LOST: case SDL_EVENT_WINDOW_FOCUS_LOST:
onFocusLost(); on_focus_lost();
break; break;
case SDL_EVENT_WINDOW_FOCUS_GAINED: case SDL_EVENT_WINDOW_FOCUS_GAINED:
onFocusGained(); on_focus_gained();
break; break;
} }
} }
void onFocusLost() { void on_focus_lost() {
SDL_Window* window = aurora::window::get_sdl_window(); SDL_Window* window = aurora::window::get_sdl_window();
if (window != nullptr) { if (window != nullptr) {
syncCaptureState(window, false); sync_capture_state(window, false);
} }
s_idle_frames = 0;
set_cursor_visible(true); set_cursor_visible(true);
} }
void onFocusGained() { void on_focus_gained() {
SDL_Window* window = aurora::window::get_sdl_window(); SDL_Window* window = aurora::window::get_sdl_window();
syncCaptureState(window, shouldCaptureMouse(window)); sync_capture_state(window, should_capture_mouse(window));
} }
} // namespace dusk::mouse } // namespace dusk::mouse
+2 -2
View File
@@ -249,12 +249,12 @@ void main01(void) {
goto eventsDone; goto eventsDone;
case AURORA_PAUSED: case AURORA_PAUSED:
dusk::audio::SetPaused(true); dusk::audio::SetPaused(true);
dusk::mouse::onFocusLost(); dusk::mouse::on_focus_lost();
break; break;
case AURORA_UNPAUSED: case AURORA_UNPAUSED:
dusk::audio::SetPaused(false); dusk::audio::SetPaused(false);
dusk::game_clock::reset_frame_timer(); dusk::game_clock::reset_frame_timer();
dusk::mouse::onFocusGained(); dusk::mouse::on_focus_gained();
break; break;
case AURORA_SDL_EVENT: case AURORA_SDL_EVENT:
dusk::mouse::handle_event(event->sdl); dusk::mouse::handle_event(event->sdl);