From 9eb9acfa112cbf078147482bcbfebbbe2aa11120 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Tue, 16 Jun 2026 12:56:02 -0600 Subject: [PATCH 1/5] Move frame limiter after aurora_end_frame --- src/m_Do/m_Do_main.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/m_Do/m_Do_main.cpp b/src/m_Do/m_Do_main.cpp index 2cddcd0981..0d1e695524 100644 --- a/src/m_Do/m_Do_main.cpp +++ b/src/m_Do/m_Do_main.cpp @@ -334,11 +334,21 @@ void main01(void) { mDoAud_Execute(); } + aurora_end_frame(); + + FrameMark; + +#ifdef DUSK_DISCORD + dusk::discord::run_callbacks(); + dusk::discord::update_presence(); +#endif + static Limiter main_loop_limiter; static double last_fps_setting = 0.0; static Limiter::duration_t target_ns = 0; if (dusk::getSettings().game.enableFrameInterpolation.getValue() == dusk::FrameInterpMode::Capped && !dusk::getTransientSettings().skipFrameRateLimit) { + ZoneScopedN("Frame limiter"); double current_fps = dusk::getSettings().video.maxFrameRate.getValue(); if (current_fps != last_fps_setting) { last_fps_setting = current_fps; @@ -350,16 +360,6 @@ void main01(void) { } else { main_loop_limiter.Reset(); } - - aurora_end_frame(); - - - FrameMark; - -#ifdef DUSK_DISCORD - dusk::discord::run_callbacks(); - dusk::discord::update_presence(); -#endif } while (dusk::IsRunning); exit:; From 0c9c8795cea50ce65e7cb8923d5f146666a774b2 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Tue, 16 Jun 2026 13:12:37 -0600 Subject: [PATCH 2/5] Update aurora --- extern/aurora | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/aurora b/extern/aurora index 3f1c26f2a6..39933ea02a 160000 --- a/extern/aurora +++ b/extern/aurora @@ -1 +1 @@ -Subproject commit 3f1c26f2a6a6b6a9f58232ba6e8d7394e573cfe0 +Subproject commit 39933ea02a603e841e4635d42ac1d07bd636d870 From 1fd8a2ca3c41234abcf19274f356e48395d229c0 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Tue, 16 Jun 2026 13:37:04 -0600 Subject: [PATCH 3/5] More fixes for clawshot touch controls --- extern/aurora | 2 +- include/d/actor/d_a_alink.h | 2 +- src/d/actor/d_a_alink_dusk.cpp | 2 +- src/d/actor/d_a_alink_link.inc | 6 +++--- src/d/d_camera.cpp | 2 +- src/dusk/ui/touch_controls.cpp | 9 ++------- 6 files changed, 9 insertions(+), 14 deletions(-) diff --git a/extern/aurora b/extern/aurora index 39933ea02a..0acac1320c 160000 --- a/extern/aurora +++ b/extern/aurora @@ -1 +1 @@ -Subproject commit 39933ea02a603e841e4635d42ac1d07bd636d870 +Subproject commit 0acac1320c58d9083f9bbd8bd8b40647c0d52ecf diff --git a/include/d/actor/d_a_alink.h b/include/d/actor/d_a_alink.h index a3cd2cbfed..a1d78c6116 100644 --- a/include/d/actor/d_a_alink.h +++ b/include/d/actor/d_a_alink.h @@ -4556,7 +4556,7 @@ public: void handleWolfHowl(); void handleQuickTransform(); bool checkAimContext(); - bool checkTouchAimCaptureContext(); + bool checkAimInputContext(); void onIronBallChainInterpCallback(); diff --git a/src/d/actor/d_a_alink_dusk.cpp b/src/d/actor/d_a_alink_dusk.cpp index b1d06c089f..8a2bc0025b 100644 --- a/src/d/actor/d_a_alink_dusk.cpp +++ b/src/d/actor/d_a_alink_dusk.cpp @@ -176,7 +176,7 @@ bool daAlink_c::checkAimContext() { } } -bool daAlink_c::checkTouchAimCaptureContext() { +bool daAlink_c::checkAimInputContext() { switch (mProcID) { case PROC_HOOKSHOT_ROOF_WAIT: case PROC_HOOKSHOT_WALL_WAIT: diff --git a/src/d/actor/d_a_alink_link.inc b/src/d/actor/d_a_alink_link.inc index 0cf53edf3e..cf2f2544d6 100644 --- a/src/d/actor/d_a_alink_link.inc +++ b/src/d/actor/d_a_alink_link.inc @@ -123,7 +123,7 @@ BOOL daAlink_c::setBodyAngleToCamera() { } #if TARGET_PC - if (dusk::getSettings().game.enableMouseAim && checkAimContext()) { + if (dusk::getSettings().game.enableMouseAim && checkAimInputContext()) { sp8 = mBodyAngle.x; } else #endif @@ -142,7 +142,7 @@ BOOL daAlink_c::setBodyAngleToCamera() { #if TARGET_PC if ((dusk::getSettings().game.enableGyroAim || dusk::getSettings().game.enableMouseAim) && - checkAimContext()) + checkAimInputContext()) { f32 gyro_scale = 1.0f; if (checkWolfEyeUp()) { @@ -174,7 +174,7 @@ BOOL daAlink_c::setBodyAngleToCamera() { } } - if (dusk::getSettings().game.enableTouchControls && checkAimContext()) { + if (dusk::getSettings().game.enableTouchControls && checkAimInputContext()) { f32 touchYawDp = 0.0f; f32 touchPitchDp = 0.0f; if (dusk::touch_camera::consume_delta(touchYawDp, touchPitchDp)) { diff --git a/src/d/d_camera.cpp b/src/d/d_camera.cpp index 483e052312..cf0f7cbb56 100644 --- a/src/d/d_camera.cpp +++ b/src/d/d_camera.cpp @@ -7505,7 +7505,7 @@ static bool sTouchFreeCameraActive = false; bool dCamera_c::isAimActive() { auto* link = daAlink_getAlinkActorClass(); - return link != nullptr && link->checkAimContext() && + return link != nullptr && link->checkAimInputContext() && dComIfGp_checkCameraAttentionStatus(link->field_0x317c, 0x10); } diff --git a/src/dusk/ui/touch_controls.cpp b/src/dusk/ui/touch_controls.cpp index e10ca399c6..a85a90930f 100644 --- a/src/dusk/ui/touch_controls.cpp +++ b/src/dusk/ui/touch_controls.cpp @@ -156,11 +156,6 @@ bool player_attention_locked() noexcept { return player != nullptr && (player->checkAttentionLock() || player->checkEnemyAttentionLock()); } -bool touch_aim_capture_active() noexcept { - auto* player = daAlink_getAlinkActorClass(); - return player != nullptr && player->checkTouchAimCaptureContext() && dCamera_c::isAimActive(); -} - bool item_wheel_active() noexcept { return dMeter2Info_getWindowStatus() == 2; } @@ -697,7 +692,7 @@ void TouchControls::sync_touch_state() noexcept { } sync_l_lock_state(); - const bool aimActive = touch_aim_capture_active(); + const bool aimActive = dCamera_c::isAimActive(); if (aimActive && mMoveTouch.active) { if (!mCameraTouch.active) { mCameraTouch = mMoveTouch; @@ -1213,7 +1208,7 @@ void TouchControls::handle_touch_down(Rml::Event& event) noexcept { } const auto id = touch_event_id(event); - if (touch_aim_capture_active()) { + if (dCamera_c::isAimActive()) { if (!mCameraTouch.active) { mCameraTouch = { .id = id, From cc9c15de54e465270b212b0a7cc7201806a4c09b Mon Sep 17 00:00:00 2001 From: Luke Street Date: Tue, 16 Jun 2026 13:51:17 -0600 Subject: [PATCH 4/5] Hawkeye support in touch controls --- src/dusk/ui/touch_controls.cpp | 36 +++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/dusk/ui/touch_controls.cpp b/src/dusk/ui/touch_controls.cpp index a85a90930f..6056f0d11d 100644 --- a/src/dusk/ui/touch_controls.cpp +++ b/src/dusk/ui/touch_controls.cpp @@ -156,6 +156,10 @@ bool player_attention_locked() noexcept { return player != nullptr && (player->checkAttentionLock() || player->checkEnemyAttentionLock()); } +bool hawkeye_active() noexcept { + return dCamera_c::isAimActive() && dComIfGp_checkPlayerStatus0(0, 0x200000); +} + bool item_wheel_active() noexcept { return dMeter2Info_getWindowStatus() == 2; } @@ -174,7 +178,7 @@ enum class StickOutput { }; StickOutput stick_output_mode() noexcept { - if (fishing_controls_active()) { + if (fishing_controls_active() || hawkeye_active()) { return StickOutput::CStick; } return StickOutput::MainStick; @@ -693,7 +697,7 @@ void TouchControls::sync_touch_state() noexcept { sync_l_lock_state(); const bool aimActive = dCamera_c::isAimActive(); - if (aimActive && mMoveTouch.active) { + if (aimActive && !hawkeye_active() && mMoveTouch.active) { if (!mCameraTouch.active) { mCameraTouch = mMoveTouch; mCameraTouch.start = mMoveTouch.current; @@ -1208,7 +1212,26 @@ void TouchControls::handle_touch_down(Rml::Event& event) noexcept { } const auto id = touch_event_id(event); + const auto dimensions = context->GetDimensions(); + const float top = mSafeInsets.top + kAnalogZoneTopDp * touch_dp_scale(); + const float bottom = static_cast(dimensions.y) - mSafeInsets.bottom - + kAnalogZoneBottomDp * touch_dp_scale(); + const auto width = static_cast(dimensions.x); + const bool inAnalogZone = position.y >= top && position.y <= bottom; + const bool inLeftZone = position.x < width * kLeftZoneWidth; if (dCamera_c::isAimActive()) { + if (hawkeye_active() && inAnalogZone && inLeftZone) { + if (!mMoveTouch.active) { + mMoveTouch = { + .id = id, + .start = position, + .current = position, + .active = true, + }; + } + return; + } + if (!mCameraTouch.active) { mCameraTouch = { .id = id, @@ -1220,16 +1243,11 @@ void TouchControls::handle_touch_down(Rml::Event& event) noexcept { return; } - const auto dimensions = context->GetDimensions(); - const float top = mSafeInsets.top + kAnalogZoneTopDp * touch_dp_scale(); - const float bottom = static_cast(dimensions.y) - mSafeInsets.bottom - - kAnalogZoneBottomDp * touch_dp_scale(); - if (position.y < top || position.y > bottom) { + if (!inAnalogZone) { return; } - const auto width = static_cast(dimensions.x); - if (!mMoveTouch.active && position.x < width * kLeftZoneWidth) { + if (!mMoveTouch.active && inLeftZone) { mMoveTouch = { .id = id, .start = position, From f5642f307384bd4b7b7a09f690e391152445c815 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Tue, 16 Jun 2026 15:10:09 -0600 Subject: [PATCH 5/5] UI: Split active/visible concepts & fix nav forwarding --- extern/aurora | 2 +- src/dusk/ui/document.cpp | 23 ++++++++++++++--------- src/dusk/ui/document.hpp | 6 +++--- src/dusk/ui/prelaunch.cpp | 2 +- src/dusk/ui/ui.cpp | 14 +++++++++----- src/dusk/ui/ui.hpp | 2 +- 6 files changed, 29 insertions(+), 20 deletions(-) diff --git a/extern/aurora b/extern/aurora index 0acac1320c..22351fb0b7 160000 --- a/extern/aurora +++ b/extern/aurora @@ -1 +1 @@ -Subproject commit 0acac1320c58d9083f9bbd8bd8b40647c0d52ecf +Subproject commit 22351fb0b76a4f4f2c4a4dff95aa300101e861aa diff --git a/src/dusk/ui/document.cpp b/src/dusk/ui/document.cpp index fc8be92a83..1ad03bc1ec 100644 --- a/src/dusk/ui/document.cpp +++ b/src/dusk/ui/document.cpp @@ -3,9 +3,7 @@ #include "aurora/rmlui.hpp" #include "ui.hpp" -#include "Z2AudioLib/Z2SeMgr.h" #include "m_Do/m_Do_audio.h" -#include namespace dusk::ui { namespace { @@ -30,19 +28,19 @@ Document::Document(const Rml::String& source, bool passive) return; } const auto cmd = map_nav_event(event); - if (cmd != NavCommand::Menu && !visible()) { + if (cmd != NavCommand::Menu && (!visible() || !active())) { event.StopImmediatePropagation(); } }, true); - const auto blockUnlessVisible = [this](Rml::Event& event) { - if (!visible()) { + const auto blockUnlessActive = [this](Rml::Event& event) { + if (!visible() || !active()) { event.StopImmediatePropagation(); } }; - listen(Rml::EventId::Mouseover, blockUnlessVisible, true); - listen(Rml::EventId::Click, blockUnlessVisible, true); - listen(Rml::EventId::Scroll, blockUnlessVisible, true); + listen(Rml::EventId::Mouseover, blockUnlessActive, true); + listen(Rml::EventId::Click, blockUnlessActive, true); + listen(Rml::EventId::Scroll, blockUnlessActive, true); listen(Rml::EventId::Keydown, [this](Rml::Event& event) { if (mPassive) { @@ -124,9 +122,16 @@ bool Document::visible() const { return *mDocument->GetProperty(Rml::PropertyId::Visibility) == Rml::Style::Visibility::Visible; } +bool Document::active() const { + return !mClosed && !mPendingClose; +} + bool Document::handle_nav_event(Rml::Event& event) { + if (!active()) { + return false; + } const auto cmd = map_nav_event(event); - if (cmd == NavCommand::None) { + if (cmd == NavCommand::None || (cmd != NavCommand::Menu && !visible())) { return false; } return handle_nav_command(event, cmd); diff --git a/src/dusk/ui/document.hpp b/src/dusk/ui/document.hpp index cf61267ee9..c3428d9fea 100644 --- a/src/dusk/ui/document.hpp +++ b/src/dusk/ui/document.hpp @@ -18,6 +18,7 @@ public: virtual void update(); virtual bool focus(); virtual bool visible() const; + virtual bool active() const; void listen(Rml::Element* element, Rml::EventId event, ScopedEventListener::Callback callback, bool capture = false); @@ -41,12 +42,11 @@ public: push_document(std::move(document)); hide(false); } - void pop() { + void pop(bool show = true) { hide(true); - show_top_document(); + focus_top_document(show); } - bool pending_close() const { return mPendingClose; } bool closed() const { return mClosed; } bool handle_nav_event(Rml::Event& event); diff --git a/src/dusk/ui/prelaunch.cpp b/src/dusk/ui/prelaunch.cpp index 44b73b75ef..998cdb87ea 100644 --- a/src/dusk/ui/prelaunch.cpp +++ b/src/dusk/ui/prelaunch.cpp @@ -715,7 +715,7 @@ Prelaunch::Prelaunch() : Document(kDocumentSource), mRoot(mDocument->GetElementB } IsGameLaunched = true; - hide(true); + pop(false); }); apply_intro_animation(mMenuButtons.back()->root(), "delay-1"); diff --git a/src/dusk/ui/ui.cpp b/src/dusk/ui/ui.cpp index 0d9d0b7e1e..ecff09f6aa 100644 --- a/src/dusk/ui/ui.cpp +++ b/src/dusk/ui/ui.cpp @@ -195,9 +195,13 @@ Document& push_document(std::unique_ptr doc, bool show, bool passive) return ret; } -void show_top_document() noexcept { +void focus_top_document(bool show) noexcept { if (auto* doc = top_document()) { - doc->show(); + if (show) { + doc->show(); + } else { + doc->focus(); + } } input::sync_input_block(); } @@ -210,13 +214,13 @@ bool any_document_visible() noexcept { bool is_prelaunch_open() noexcept { return std::any_of(sDocumentStack.begin(), sDocumentStack.end(), [](const auto& doc) { const auto* prelaunch = dynamic_cast(doc.get()); - return prelaunch != nullptr && !prelaunch->pending_close() && !prelaunch->closed(); + return prelaunch != nullptr && prelaunch->active(); }); } Document* top_document() noexcept { for (auto& doc : std::views::reverse(sDocumentStack)) { - if (!doc->closed() && !doc->pending_close()) { + if (doc->active()) { return doc.get(); } } @@ -259,7 +263,7 @@ void update() noexcept { context->GetFocusElement() == context->GetRootElement())) { for (auto& doc : std::views::reverse(sDocumentStack)) { - if (!doc->closed() && !doc->pending_close() && doc->focus()) { + if (doc->active() && doc->focus()) { break; } } diff --git a/src/dusk/ui/ui.hpp b/src/dusk/ui/ui.hpp index cbfe3dcc9d..a32bfbbcbc 100644 --- a/src/dusk/ui/ui.hpp +++ b/src/dusk/ui/ui.hpp @@ -74,7 +74,7 @@ void update() noexcept; Document& push_document( std::unique_ptr doc, bool show = true, bool passive = false) noexcept; -void show_top_document() noexcept; +void focus_top_document(bool show) noexcept; bool any_document_visible() noexcept; bool is_prelaunch_open() noexcept; Document* top_document() noexcept;