Compare commits

...

5 Commits

Author SHA1 Message Date
Luke Street f5642f3073 UI: Split active/visible concepts & fix nav forwarding 2026-06-16 15:10:09 -06:00
Luke Street cc9c15de54 Hawkeye support in touch controls 2026-06-16 13:51:17 -06:00
Luke Street 1fd8a2ca3c More fixes for clawshot touch controls 2026-06-16 13:37:04 -06:00
Luke Street 0c9c8795ce Update aurora 2026-06-16 13:12:37 -06:00
Luke Street 9eb9acfa11 Move frame limiter after aurora_end_frame 2026-06-16 12:56:02 -06:00
12 changed files with 72 additions and 50 deletions
+1 -1
+1 -1
View File
@@ -4556,7 +4556,7 @@ public:
void handleWolfHowl(); void handleWolfHowl();
void handleQuickTransform(); void handleQuickTransform();
bool checkAimContext(); bool checkAimContext();
bool checkTouchAimCaptureContext(); bool checkAimInputContext();
void onIronBallChainInterpCallback(); void onIronBallChainInterpCallback();
+1 -1
View File
@@ -176,7 +176,7 @@ bool daAlink_c::checkAimContext() {
} }
} }
bool daAlink_c::checkTouchAimCaptureContext() { bool daAlink_c::checkAimInputContext() {
switch (mProcID) { switch (mProcID) {
case PROC_HOOKSHOT_ROOF_WAIT: case PROC_HOOKSHOT_ROOF_WAIT:
case PROC_HOOKSHOT_WALL_WAIT: case PROC_HOOKSHOT_WALL_WAIT:
+3 -3
View File
@@ -123,7 +123,7 @@ BOOL daAlink_c::setBodyAngleToCamera() {
} }
#if TARGET_PC #if TARGET_PC
if (dusk::getSettings().game.enableMouseAim && checkAimContext()) { if (dusk::getSettings().game.enableMouseAim && checkAimInputContext()) {
sp8 = mBodyAngle.x; sp8 = mBodyAngle.x;
} else } else
#endif #endif
@@ -142,7 +142,7 @@ BOOL daAlink_c::setBodyAngleToCamera() {
#if TARGET_PC #if TARGET_PC
if ((dusk::getSettings().game.enableGyroAim || if ((dusk::getSettings().game.enableGyroAim ||
dusk::getSettings().game.enableMouseAim) && dusk::getSettings().game.enableMouseAim) &&
checkAimContext()) checkAimInputContext())
{ {
f32 gyro_scale = 1.0f; f32 gyro_scale = 1.0f;
if (checkWolfEyeUp()) { 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 touchYawDp = 0.0f;
f32 touchPitchDp = 0.0f; f32 touchPitchDp = 0.0f;
if (dusk::touch_camera::consume_delta(touchYawDp, touchPitchDp)) { if (dusk::touch_camera::consume_delta(touchYawDp, touchPitchDp)) {
+1 -1
View File
@@ -7505,7 +7505,7 @@ static bool sTouchFreeCameraActive = false;
bool dCamera_c::isAimActive() { bool dCamera_c::isAimActive() {
auto* link = daAlink_getAlinkActorClass(); auto* link = daAlink_getAlinkActorClass();
return link != nullptr && link->checkAimContext() && return link != nullptr && link->checkAimInputContext() &&
dComIfGp_checkCameraAttentionStatus(link->field_0x317c, 0x10); dComIfGp_checkCameraAttentionStatus(link->field_0x317c, 0x10);
} }
+14 -9
View File
@@ -3,9 +3,7 @@
#include "aurora/rmlui.hpp" #include "aurora/rmlui.hpp"
#include "ui.hpp" #include "ui.hpp"
#include "Z2AudioLib/Z2SeMgr.h"
#include "m_Do/m_Do_audio.h" #include "m_Do/m_Do_audio.h"
#include <imgui.h>
namespace dusk::ui { namespace dusk::ui {
namespace { namespace {
@@ -30,19 +28,19 @@ Document::Document(const Rml::String& source, bool passive)
return; return;
} }
const auto cmd = map_nav_event(event); const auto cmd = map_nav_event(event);
if (cmd != NavCommand::Menu && !visible()) { if (cmd != NavCommand::Menu && (!visible() || !active())) {
event.StopImmediatePropagation(); event.StopImmediatePropagation();
} }
}, },
true); true);
const auto blockUnlessVisible = [this](Rml::Event& event) { const auto blockUnlessActive = [this](Rml::Event& event) {
if (!visible()) { if (!visible() || !active()) {
event.StopImmediatePropagation(); event.StopImmediatePropagation();
} }
}; };
listen(Rml::EventId::Mouseover, blockUnlessVisible, true); listen(Rml::EventId::Mouseover, blockUnlessActive, true);
listen(Rml::EventId::Click, blockUnlessVisible, true); listen(Rml::EventId::Click, blockUnlessActive, true);
listen(Rml::EventId::Scroll, blockUnlessVisible, true); listen(Rml::EventId::Scroll, blockUnlessActive, true);
listen(Rml::EventId::Keydown, [this](Rml::Event& event) { listen(Rml::EventId::Keydown, [this](Rml::Event& event) {
if (mPassive) { if (mPassive) {
@@ -124,9 +122,16 @@ bool Document::visible() const {
return *mDocument->GetProperty(Rml::PropertyId::Visibility) == Rml::Style::Visibility::Visible; 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) { bool Document::handle_nav_event(Rml::Event& event) {
if (!active()) {
return false;
}
const auto cmd = map_nav_event(event); const auto cmd = map_nav_event(event);
if (cmd == NavCommand::None) { if (cmd == NavCommand::None || (cmd != NavCommand::Menu && !visible())) {
return false; return false;
} }
return handle_nav_command(event, cmd); return handle_nav_command(event, cmd);
+3 -3
View File
@@ -18,6 +18,7 @@ public:
virtual void update(); virtual void update();
virtual bool focus(); virtual bool focus();
virtual bool visible() const; virtual bool visible() const;
virtual bool active() const;
void listen(Rml::Element* element, Rml::EventId event, ScopedEventListener::Callback callback, void listen(Rml::Element* element, Rml::EventId event, ScopedEventListener::Callback callback,
bool capture = false); bool capture = false);
@@ -41,12 +42,11 @@ public:
push_document(std::move(document)); push_document(std::move(document));
hide(false); hide(false);
} }
void pop() { void pop(bool show = true) {
hide(true); hide(true);
show_top_document(); focus_top_document(show);
} }
bool pending_close() const { return mPendingClose; }
bool closed() const { return mClosed; } bool closed() const { return mClosed; }
bool handle_nav_event(Rml::Event& event); bool handle_nav_event(Rml::Event& event);
+1 -1
View File
@@ -715,7 +715,7 @@ Prelaunch::Prelaunch() : Document(kDocumentSource), mRoot(mDocument->GetElementB
} }
IsGameLaunched = true; IsGameLaunched = true;
hide(true); pop(false);
}); });
apply_intro_animation(mMenuButtons.back()->root(), "delay-1"); apply_intro_animation(mMenuButtons.back()->root(), "delay-1");
+27 -14
View File
@@ -156,9 +156,8 @@ bool player_attention_locked() noexcept {
return player != nullptr && (player->checkAttentionLock() || player->checkEnemyAttentionLock()); return player != nullptr && (player->checkAttentionLock() || player->checkEnemyAttentionLock());
} }
bool touch_aim_capture_active() noexcept { bool hawkeye_active() noexcept {
auto* player = daAlink_getAlinkActorClass(); return dCamera_c::isAimActive() && dComIfGp_checkPlayerStatus0(0, 0x200000);
return player != nullptr && player->checkTouchAimCaptureContext() && dCamera_c::isAimActive();
} }
bool item_wheel_active() noexcept { bool item_wheel_active() noexcept {
@@ -179,7 +178,7 @@ enum class StickOutput {
}; };
StickOutput stick_output_mode() noexcept { StickOutput stick_output_mode() noexcept {
if (fishing_controls_active()) { if (fishing_controls_active() || hawkeye_active()) {
return StickOutput::CStick; return StickOutput::CStick;
} }
return StickOutput::MainStick; return StickOutput::MainStick;
@@ -697,8 +696,8 @@ void TouchControls::sync_touch_state() noexcept {
} }
sync_l_lock_state(); sync_l_lock_state();
const bool aimActive = touch_aim_capture_active(); const bool aimActive = dCamera_c::isAimActive();
if (aimActive && mMoveTouch.active) { if (aimActive && !hawkeye_active() && mMoveTouch.active) {
if (!mCameraTouch.active) { if (!mCameraTouch.active) {
mCameraTouch = mMoveTouch; mCameraTouch = mMoveTouch;
mCameraTouch.start = mMoveTouch.current; mCameraTouch.start = mMoveTouch.current;
@@ -1213,7 +1212,26 @@ void TouchControls::handle_touch_down(Rml::Event& event) noexcept {
} }
const auto id = touch_event_id(event); const auto id = touch_event_id(event);
if (touch_aim_capture_active()) { const auto dimensions = context->GetDimensions();
const float top = mSafeInsets.top + kAnalogZoneTopDp * touch_dp_scale();
const float bottom = static_cast<float>(dimensions.y) - mSafeInsets.bottom -
kAnalogZoneBottomDp * touch_dp_scale();
const auto width = static_cast<float>(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) { if (!mCameraTouch.active) {
mCameraTouch = { mCameraTouch = {
.id = id, .id = id,
@@ -1225,16 +1243,11 @@ void TouchControls::handle_touch_down(Rml::Event& event) noexcept {
return; return;
} }
const auto dimensions = context->GetDimensions(); if (!inAnalogZone) {
const float top = mSafeInsets.top + kAnalogZoneTopDp * touch_dp_scale();
const float bottom = static_cast<float>(dimensions.y) - mSafeInsets.bottom -
kAnalogZoneBottomDp * touch_dp_scale();
if (position.y < top || position.y > bottom) {
return; return;
} }
const auto width = static_cast<float>(dimensions.x); if (!mMoveTouch.active && inLeftZone) {
if (!mMoveTouch.active && position.x < width * kLeftZoneWidth) {
mMoveTouch = { mMoveTouch = {
.id = id, .id = id,
.start = position, .start = position,
+9 -5
View File
@@ -195,9 +195,13 @@ Document& push_document(std::unique_ptr<Document> doc, bool show, bool passive)
return ret; return ret;
} }
void show_top_document() noexcept { void focus_top_document(bool show) noexcept {
if (auto* doc = top_document()) { if (auto* doc = top_document()) {
doc->show(); if (show) {
doc->show();
} else {
doc->focus();
}
} }
input::sync_input_block(); input::sync_input_block();
} }
@@ -210,13 +214,13 @@ bool any_document_visible() noexcept {
bool is_prelaunch_open() noexcept { bool is_prelaunch_open() noexcept {
return std::any_of(sDocumentStack.begin(), sDocumentStack.end(), [](const auto& doc) { return std::any_of(sDocumentStack.begin(), sDocumentStack.end(), [](const auto& doc) {
const auto* prelaunch = dynamic_cast<const Prelaunch*>(doc.get()); const auto* prelaunch = dynamic_cast<const Prelaunch*>(doc.get());
return prelaunch != nullptr && !prelaunch->pending_close() && !prelaunch->closed(); return prelaunch != nullptr && prelaunch->active();
}); });
} }
Document* top_document() noexcept { Document* top_document() noexcept {
for (auto& doc : std::views::reverse(sDocumentStack)) { for (auto& doc : std::views::reverse(sDocumentStack)) {
if (!doc->closed() && !doc->pending_close()) { if (doc->active()) {
return doc.get(); return doc.get();
} }
} }
@@ -259,7 +263,7 @@ void update() noexcept {
context->GetFocusElement() == context->GetRootElement())) context->GetFocusElement() == context->GetRootElement()))
{ {
for (auto& doc : std::views::reverse(sDocumentStack)) { for (auto& doc : std::views::reverse(sDocumentStack)) {
if (!doc->closed() && !doc->pending_close() && doc->focus()) { if (doc->active() && doc->focus()) {
break; break;
} }
} }
+1 -1
View File
@@ -74,7 +74,7 @@ void update() noexcept;
Document& push_document( Document& push_document(
std::unique_ptr<Document> doc, bool show = true, bool passive = false) noexcept; std::unique_ptr<Document> 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 any_document_visible() noexcept;
bool is_prelaunch_open() noexcept; bool is_prelaunch_open() noexcept;
Document* top_document() noexcept; Document* top_document() noexcept;
+10 -10
View File
@@ -334,11 +334,21 @@ void main01(void) {
mDoAud_Execute(); mDoAud_Execute();
} }
aurora_end_frame();
FrameMark;
#ifdef DUSK_DISCORD
dusk::discord::run_callbacks();
dusk::discord::update_presence();
#endif
static Limiter main_loop_limiter; static Limiter main_loop_limiter;
static double last_fps_setting = 0.0; static double last_fps_setting = 0.0;
static Limiter::duration_t target_ns = 0; static Limiter::duration_t target_ns = 0;
if (dusk::getSettings().game.enableFrameInterpolation.getValue() == dusk::FrameInterpMode::Capped && !dusk::getTransientSettings().skipFrameRateLimit) { if (dusk::getSettings().game.enableFrameInterpolation.getValue() == dusk::FrameInterpMode::Capped && !dusk::getTransientSettings().skipFrameRateLimit) {
ZoneScopedN("Frame limiter");
double current_fps = dusk::getSettings().video.maxFrameRate.getValue(); double current_fps = dusk::getSettings().video.maxFrameRate.getValue();
if (current_fps != last_fps_setting) { if (current_fps != last_fps_setting) {
last_fps_setting = current_fps; last_fps_setting = current_fps;
@@ -350,16 +360,6 @@ void main01(void) {
} else { } else {
main_loop_limiter.Reset(); main_loop_limiter.Reset();
} }
aurora_end_frame();
FrameMark;
#ifdef DUSK_DISCORD
dusk::discord::run_callbacks();
dusk::discord::update_presence();
#endif
} while (dusk::IsRunning); } while (dusk::IsRunning);
exit:; exit:;