mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-06-19 06:27:02 -04:00
Merge branch 'main' of https://github.com/TwilitRealm/dusk into randomizer
This commit is contained in:
Vendored
+1
-1
Submodule extern/aurora updated: 22351fb0b7...509021de0a
@@ -16,37 +16,37 @@
|
||||
];
|
||||
forAllSystems = lib.genAttrs supportedSystems;
|
||||
|
||||
dawnVersion = "v20260423.175430";
|
||||
nodVersion = "v2.0.0-alpha.8";
|
||||
dawnVersion = "v20260618.032059";
|
||||
nodVersion = "v2.0.0-alpha.10";
|
||||
versionSuffix = "nix-" + (self.shortRev or self.dirtyShortRev or "dirty");
|
||||
|
||||
dawnInfo = {
|
||||
"x86_64-linux" = {
|
||||
triple = "linux-x86_64";
|
||||
hash = "sha256-HXfKTLHtMPwupnFnaflCARtXVPuS/0PoCePXidjE5xs=";
|
||||
hash = "sha256-GFSd573b+VQx/VmFdNQgWDd0V9ayQlcw0Zuopke12ak=";
|
||||
};
|
||||
"aarch64-linux" = {
|
||||
triple = "linux-aarch64";
|
||||
hash = "sha256-34yyFpfqBZUwoFXQ41F0AwAU78FaNihOSY0oriwn6B0=";
|
||||
hash = "sha256-ZaoP7BAjBMnfAv2/AMRi3FNH2ZtyqASCSFyU/oB2Mzg=";
|
||||
};
|
||||
"aarch64-darwin" = {
|
||||
triple = "darwin-arm64";
|
||||
hash = "sha256-eQnzrBp6gjiBek1VYQ9A5W13ClYWrDDKjIqv/7eNTR4=";
|
||||
hash = "sha256-HT+qtlLaSHyoXPrUcXgcTGa877X5YfzbxRD4bJb7i1Y=";
|
||||
};
|
||||
"x86_64-darwin" = {
|
||||
triple = "darwin-x86_64";
|
||||
hash = "sha256-QGWiGdxiI9kci3NPXH6QFFirxn16851zB/w3jqhIBJ4=";
|
||||
hash = "sha256-cUNaCbA7rlKSukDVKGaVEVw0Zt1+mSbaHbmUCMvMVWc=";
|
||||
};
|
||||
};
|
||||
|
||||
nodPrebuiltInfo = {
|
||||
"x86_64-linux" = {
|
||||
triple = "linux-x86_64";
|
||||
hash = "sha256-mUqvLsbsqaZ+HAjMmHYPYO+MgtanGRTw7Gzn5uXR5rE=";
|
||||
hash = "sha256-FVQWECVA2gWdc+n5OQ/Tvwn8z0qdgjSd1WlFt5HKOec=";
|
||||
};
|
||||
"aarch64-darwin" = {
|
||||
triple = "macos-arm64";
|
||||
hash = "sha256-UPy1ywCcv0K6VJOU3uUelJuUdBh3UNaPRlyP5LOBeDw=";
|
||||
hash = "sha256-8ZEejxksVgShNKUVRCBYaLOp9x/qOC9pAeVrElQUGUk=";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
'';
|
||||
|
||||
dawn = pkgs.fetchzip {
|
||||
url = "https://github.com/encounter/dawn-build/releases/download/${dawnVersion}/dawn-${dawnInfo.${system}.triple}.tar.gz";
|
||||
url = "https://github.com/encounter/dawn/releases/download/${dawnVersion}/dawn-${dawnInfo.${system}.triple}.tar.gz";
|
||||
hash = dawnInfo.${system}.hash;
|
||||
stripRoot = false;
|
||||
};
|
||||
@@ -94,7 +94,7 @@
|
||||
owner = "encounter";
|
||||
repo = "nod";
|
||||
rev = nodVersion;
|
||||
hash = "sha256-+zrtVzjo0+X/6uMcNUn1+FaSR+jOhrcQSDNBFjw0NDs=";
|
||||
hash = "sha256-r8qDlOVxv5iKiFjJQrcBuL9HVoOM3yEjRVnQIMqaICs=";
|
||||
};
|
||||
patches = [ ./fix-cmake-paths.patch ];
|
||||
cargoDeps = pkgs.rustPlatform.importCargoLock {
|
||||
@@ -141,12 +141,12 @@
|
||||
XXHASH = pkgs.xxhash.src;
|
||||
ZSTD = pkgs.zstd.src;
|
||||
FMT = pkgs.fetchzip {
|
||||
url = "https://github.com/fmtlib/fmt/archive/refs/tags/11.1.4.tar.gz";
|
||||
hash = "sha256-sUbxlYi/Aupaox3JjWFqXIjcaQa0LFjclQAOleT+FRA=";
|
||||
url = "https://github.com/fmtlib/fmt/archive/refs/tags/12.1.0.tar.gz";
|
||||
hash = "sha256-ZmI1Dv0ZabPlxa02OpERI47jp7zFfjpeWCy1WyuPYZ0=";
|
||||
};
|
||||
TRACY = pkgs.fetchzip {
|
||||
url = "https://github.com/wolfpld/tracy/archive/a64b9a20294d59421a2f57aeca3c6383d8c48169.tar.gz";
|
||||
hash = "sha256-hbNGOsGeyGSvCJ2No8RkwOib1lX2on3vNZSzyVkZdXw=";
|
||||
url = "https://github.com/wolfpld/tracy/archive/6789e7d6f9a65ec98926b602097a33a9676d2606.tar.gz";
|
||||
hash = "sha256-Xxyd7G/mnXEPpN+ehmwl0AkAhS3CwObpJNDgcqbdUJg=";
|
||||
};
|
||||
IMGUI = pkgs.fetchFromGitHub {
|
||||
owner = "ocornut";
|
||||
|
||||
@@ -219,6 +219,7 @@ private:
|
||||
bool mCursorInterpPrevAngular;
|
||||
bool mCursorInterpCurrAngular;
|
||||
bool mCursorInterpInit;
|
||||
bool mPointerTouchPressHoveredCurrent;
|
||||
J2DPicture* mDpadIcon;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -6,6 +6,9 @@ class CPaneMgr;
|
||||
|
||||
namespace dusk::menu_pointer {
|
||||
|
||||
using TargetId = u16;
|
||||
constexpr TargetId InvalidTarget = 0xffff;
|
||||
|
||||
enum class Context {
|
||||
None,
|
||||
FileSelect,
|
||||
@@ -43,12 +46,14 @@ bool active() noexcept;
|
||||
bool enabled() noexcept;
|
||||
bool mouse_capture_active() noexcept;
|
||||
const State& state() noexcept;
|
||||
void set_hover_target(TargetId target) noexcept;
|
||||
bool consume_click() noexcept;
|
||||
bool peek_click() noexcept;
|
||||
void set_dialog_choice(u8 choice, bool clicked) noexcept;
|
||||
bool get_dialog_choice(u8& choice) noexcept;
|
||||
bool consume_dialog_click(u8& choice) noexcept;
|
||||
void defer_activation(Context context, u8 target) noexcept;
|
||||
bool consume_deferred_activation(Context context, u8 target) noexcept;
|
||||
void defer_activation(Context context, TargetId target) noexcept;
|
||||
bool consume_deferred_activation(Context context, TargetId target) noexcept;
|
||||
void clear_deferred_activation(Context context) noexcept;
|
||||
u32 suppressed_pad_buttons(u32 port) noexcept;
|
||||
void finish_pad_suppression_read(u32 port) noexcept;
|
||||
|
||||
+32
-21
@@ -784,6 +784,7 @@ bool dFile_select_c::pointerDataSelect() {
|
||||
if (!dusk::menu_pointer::hit_pane(mSelFilePanes[i], 8.0f)) {
|
||||
continue;
|
||||
}
|
||||
dusk::menu_pointer::set_hover_target(pointer_target(s_pointerDataSelectTarget, i));
|
||||
const bool clicked = dusk::menu_pointer::consume_click();
|
||||
if (mSelectNum != i) {
|
||||
mDoAud_seStart(Z2SE_FILE_SELECT_CURSOR, NULL, 0, 0);
|
||||
@@ -812,6 +813,7 @@ bool dFile_select_c::pointerMenuSelect() {
|
||||
if (!dusk::menu_pointer::hit_pane(m3mSelPane[i], 8.0f)) {
|
||||
continue;
|
||||
}
|
||||
dusk::menu_pointer::set_hover_target(pointer_target(s_pointerMenuSelectTarget, i));
|
||||
const bool clicked = dusk::menu_pointer::consume_click();
|
||||
if (!mIsDataNew[mSelectNum] && mSelectMenuNum != i) {
|
||||
mDoAud_seStart(Z2SE_SY_MENU_CURSOR_COMMON, NULL, 0, 0);
|
||||
@@ -840,6 +842,7 @@ bool dFile_select_c::pointerCopyDataToSelect() {
|
||||
if (!dusk::menu_pointer::hit_pane(mCpSelPane[i], 8.0f)) {
|
||||
continue;
|
||||
}
|
||||
dusk::menu_pointer::set_hover_target(pointer_target(s_pointerCopySelectTarget, i));
|
||||
const bool clicked = dusk::menu_pointer::consume_click();
|
||||
if (field_0x026b != i) {
|
||||
mDoAud_seStart(Z2SE_FILE_SELECT_CURSOR, NULL, 0, 0);
|
||||
@@ -868,6 +871,7 @@ bool dFile_select_c::pointerYesNoSelect(bool errorSelect) {
|
||||
if (!dusk::menu_pointer::hit_pane(mYnSelPane[i], 8.0f)) {
|
||||
continue;
|
||||
}
|
||||
dusk::menu_pointer::set_hover_target(pointer_target(s_pointerYesNoSelectTarget, i));
|
||||
const bool clicked =
|
||||
(!errorSelect || field_0x0268 == i) && dusk::menu_pointer::consume_click();
|
||||
if (field_0x0268 != i) {
|
||||
@@ -1131,12 +1135,13 @@ void dFile_select_c::dataSelectAnmSet() {
|
||||
void dFile_select_c::dataSelectMoveAnime() {
|
||||
#if TARGET_PC
|
||||
dusk::menu_pointer::begin_context(dusk::menu_pointer::Context::FileSelect);
|
||||
if (mSelectNum != 0xFF && dusk::menu_pointer::hit_pane(mSelFilePanes[mSelectNum], 8.0f) &&
|
||||
dusk::menu_pointer::consume_click())
|
||||
{
|
||||
dusk::menu_pointer::defer_activation(
|
||||
dusk::menu_pointer::Context::FileSelect,
|
||||
pointer_target(s_pointerDataSelectTarget, mSelectNum));
|
||||
if (mSelectNum != 0xFF && dusk::menu_pointer::hit_pane(mSelFilePanes[mSelectNum], 8.0f)) {
|
||||
dusk::menu_pointer::set_hover_target(pointer_target(s_pointerDataSelectTarget, mSelectNum));
|
||||
if (dusk::menu_pointer::consume_click()) {
|
||||
dusk::menu_pointer::defer_activation(
|
||||
dusk::menu_pointer::Context::FileSelect,
|
||||
pointer_target(s_pointerDataSelectTarget, mSelectNum));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
bool iVar7 = true;
|
||||
@@ -1609,12 +1614,14 @@ void dFile_select_c::menuSelectMoveAnm() {
|
||||
#if TARGET_PC
|
||||
dusk::menu_pointer::begin_context(dusk::menu_pointer::Context::FileSelect);
|
||||
if (mSelectMenuNum != 0xFF &&
|
||||
dusk::menu_pointer::hit_pane(m3mSelPane[mSelectMenuNum], 8.0f) &&
|
||||
dusk::menu_pointer::consume_click())
|
||||
dusk::menu_pointer::hit_pane(m3mSelPane[mSelectMenuNum], 8.0f))
|
||||
{
|
||||
dusk::menu_pointer::defer_activation(
|
||||
dusk::menu_pointer::Context::FileSelect,
|
||||
pointer_target(s_pointerMenuSelectTarget, mSelectMenuNum));
|
||||
dusk::menu_pointer::set_hover_target(pointer_target(s_pointerMenuSelectTarget, mSelectMenuNum));
|
||||
if (dusk::menu_pointer::consume_click()) {
|
||||
dusk::menu_pointer::defer_activation(
|
||||
dusk::menu_pointer::Context::FileSelect,
|
||||
pointer_target(s_pointerMenuSelectTarget, mSelectMenuNum));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
bool tmp1 = true;
|
||||
@@ -2126,12 +2133,14 @@ void dFile_select_c::copyDataToSelectMoveAnm() {
|
||||
#if TARGET_PC
|
||||
dusk::menu_pointer::begin_context(dusk::menu_pointer::Context::FileSelect);
|
||||
if (field_0x026b != 0xFF &&
|
||||
dusk::menu_pointer::hit_pane(mCpSelPane[field_0x026b], 8.0f) &&
|
||||
dusk::menu_pointer::consume_click())
|
||||
dusk::menu_pointer::hit_pane(mCpSelPane[field_0x026b], 8.0f))
|
||||
{
|
||||
dusk::menu_pointer::defer_activation(
|
||||
dusk::menu_pointer::Context::FileSelect,
|
||||
pointer_target(s_pointerCopySelectTarget, field_0x026b));
|
||||
dusk::menu_pointer::set_hover_target(pointer_target(s_pointerCopySelectTarget, field_0x026b));
|
||||
if (dusk::menu_pointer::consume_click()) {
|
||||
dusk::menu_pointer::defer_activation(
|
||||
dusk::menu_pointer::Context::FileSelect,
|
||||
pointer_target(s_pointerCopySelectTarget, field_0x026b));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
bool iVar7 = true;
|
||||
@@ -2651,12 +2660,14 @@ void dFile_select_c::yesNoCursorMoveAnm() {
|
||||
#if TARGET_PC
|
||||
dusk::menu_pointer::begin_context(dusk::menu_pointer::Context::FileSelect);
|
||||
if (field_0x0268 != 0xFF &&
|
||||
dusk::menu_pointer::hit_pane(mYnSelPane[field_0x0268], 8.0f) &&
|
||||
dusk::menu_pointer::consume_click())
|
||||
dusk::menu_pointer::hit_pane(mYnSelPane[field_0x0268], 8.0f))
|
||||
{
|
||||
dusk::menu_pointer::defer_activation(
|
||||
dusk::menu_pointer::Context::FileSelect,
|
||||
pointer_target(s_pointerYesNoSelectTarget, field_0x0268));
|
||||
dusk::menu_pointer::set_hover_target(pointer_target(s_pointerYesNoSelectTarget, field_0x0268));
|
||||
if (dusk::menu_pointer::consume_click()) {
|
||||
dusk::menu_pointer::defer_activation(
|
||||
dusk::menu_pointer::Context::FileSelect,
|
||||
pointer_target(s_pointerYesNoSelectTarget, field_0x0268));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
bool isYnSelMove = yesnoSelectMoveAnm();
|
||||
|
||||
@@ -1960,6 +1960,7 @@ bool dMenu_Collect2D_c::pointerWait() {
|
||||
if (getItemTag(x, y, true) == 0 || !dusk::menu_pointer::hit_pane(mpSelPm[x][y], 8.0f)) {
|
||||
continue;
|
||||
}
|
||||
dusk::menu_pointer::set_hover_target(static_cast<dusk::menu_pointer::TargetId>(x + y * 7));
|
||||
if (mCursorX != x || mCursorY != y) {
|
||||
mDoAud_seStart(Z2SE_SY_MENU_CURSOR_COMMON, NULL, 0, 0);
|
||||
mCursorX = x;
|
||||
|
||||
@@ -320,6 +320,7 @@ bool dMenu_Insect_c::pointerWait() {
|
||||
if (!isGetInsect(x, y) || !dusk::menu_pointer::hit_pane(mpINSParent[index], 8.0f)) {
|
||||
continue;
|
||||
}
|
||||
dusk::menu_pointer::set_hover_target(index);
|
||||
|
||||
if (field_0xf4 != x || field_0xf5 != y) {
|
||||
field_0xf4 = x;
|
||||
|
||||
@@ -482,6 +482,7 @@ bool dMenu_Letter_c::pointerWait() {
|
||||
if (!dusk::menu_pointer::hit_pane(mpLetterParent[i], 8.0f)) {
|
||||
continue;
|
||||
}
|
||||
dusk::menu_pointer::set_hover_target(i);
|
||||
|
||||
if (mIndex != i) {
|
||||
mIndex = i;
|
||||
|
||||
+45
-5
@@ -83,6 +83,12 @@ enum SelectType {
|
||||
SelectType8,
|
||||
};
|
||||
|
||||
#if TARGET_PC
|
||||
static dusk::menu_pointer::TargetId option_yes_no_target(u8 index) noexcept {
|
||||
return static_cast<dusk::menu_pointer::TargetId>(0x100 + index);
|
||||
}
|
||||
#endif
|
||||
|
||||
dMenu_Option_c::dMenu_Option_c(JKRArchive* i_archive, STControl* i_stick) {
|
||||
mUseFlag = 0;
|
||||
mBarScale[0] = g_drawHIO.mOptionScreen.mBarScale[0];
|
||||
@@ -1098,18 +1104,28 @@ void dMenu_Option_c::confirm_move_move() {
|
||||
if (!dusk::menu_pointer::hit_pane(mpYesNoSelBase_c[i], 8.0f)) {
|
||||
continue;
|
||||
}
|
||||
dusk::menu_pointer::set_hover_target(option_yes_no_target(i));
|
||||
const bool clicked = dusk::menu_pointer::consume_click();
|
||||
if (field_0x3f9 != i) {
|
||||
Z2GetAudioMgr()->seStart(Z2SE_SY_MENU_CURSOR_COMMON, NULL, 0, 0, 1.0f, 1.0f, -1.0f,
|
||||
-1.0f, 0);
|
||||
field_0x3fa = field_0x3f9;
|
||||
field_0x3f9 = i;
|
||||
if (clicked) {
|
||||
yesNoSelectStart();
|
||||
field_0x3ef = SelectType7;
|
||||
dMeter2Info_set2DVibrationM();
|
||||
mpWarning->_move();
|
||||
setAnimation();
|
||||
return;
|
||||
}
|
||||
yesnoSelectAnmSet();
|
||||
field_0x3ef = SelectType6;
|
||||
mpWarning->_move();
|
||||
setAnimation();
|
||||
return;
|
||||
}
|
||||
if (dusk::menu_pointer::consume_click()) {
|
||||
if (clicked) {
|
||||
yesNoSelectStart();
|
||||
field_0x3ef = SelectType7;
|
||||
dMeter2Info_set2DVibrationM();
|
||||
@@ -1156,11 +1172,36 @@ void dMenu_Option_c::confirm_select_init() {
|
||||
}
|
||||
|
||||
void dMenu_Option_c::confirm_select_move() {
|
||||
#if TARGET_PC
|
||||
dusk::menu_pointer::begin_context(dusk::menu_pointer::Context::Options);
|
||||
if (field_0x3f9 != 0xff &&
|
||||
dusk::menu_pointer::hit_pane(mpYesNoSelBase_c[field_0x3f9], 8.0f))
|
||||
{
|
||||
const dusk::menu_pointer::TargetId target = option_yes_no_target(field_0x3f9);
|
||||
dusk::menu_pointer::set_hover_target(target);
|
||||
if (dusk::menu_pointer::consume_click()) {
|
||||
dusk::menu_pointer::defer_activation(dusk::menu_pointer::Context::Options, target);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
u8 selectMoveAnm = yesnoSelectMoveAnm();
|
||||
u8 wakuAlphaAnm = yesnoWakuAlpahAnm(field_0x3fa);
|
||||
|
||||
if (selectMoveAnm == 1 && wakuAlphaAnm == 1) {
|
||||
yesnoCursorShow();
|
||||
#if TARGET_PC
|
||||
if (field_0x3f9 != 0xff &&
|
||||
dusk::menu_pointer::consume_deferred_activation(
|
||||
dusk::menu_pointer::Context::Options, option_yes_no_target(field_0x3f9)))
|
||||
{
|
||||
yesNoSelectStart();
|
||||
field_0x3ef = SelectType7;
|
||||
dMeter2Info_set2DVibrationM();
|
||||
mpWarning->_move();
|
||||
setAnimation();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
field_0x3ef = SelectType5;
|
||||
}
|
||||
mpWarning->_move();
|
||||
@@ -2196,16 +2237,14 @@ bool dMenu_Option_c::isRumbleSupported() {
|
||||
#if TARGET_PC
|
||||
bool dMenu_Option_c::pointerConfirmSelect() {
|
||||
dusk::menu_pointer::begin_context(dusk::menu_pointer::Context::Options);
|
||||
if (!dusk::menu_pointer::state().clicked) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (u8 i = 0; i < SelectType3; ++i) {
|
||||
if (dusk::menu_pointer::hit_pane(mpMenuPane[i], 8.0f)) {
|
||||
dusk::menu_pointer::set_hover_target(i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
dusk::menu_pointer::set_hover_target(0x200);
|
||||
if (!dusk::menu_pointer::consume_click()) {
|
||||
return false;
|
||||
}
|
||||
@@ -2226,6 +2265,7 @@ bool dMenu_Option_c::dpdMenuMove() {
|
||||
if (!dusk::menu_pointer::hit_pane(mpMenuPane[i], 8.0f)) {
|
||||
continue;
|
||||
}
|
||||
dusk::menu_pointer::set_hover_target(i);
|
||||
if (getSelectType() != i) {
|
||||
field_0x3ef = i;
|
||||
setCursorPos(i);
|
||||
|
||||
+23
-1
@@ -202,6 +202,7 @@ dMenu_Ring_c::dMenu_Ring_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i
|
||||
mCursorInterpPrevAngular = false;
|
||||
mCursorInterpCurrAngular = false;
|
||||
mCursorInterpInit = false;
|
||||
mPointerTouchPressHoveredCurrent = false;
|
||||
mDpadIcon = JKR_NEW J2DPicture((ResTIMG*)dComIfGp_getMain2DArchive()->getResource('TIMG', "font_51.bti"));
|
||||
#endif
|
||||
for (int i = 0; i < 4; i++) {
|
||||
@@ -1584,6 +1585,10 @@ bool dMenu_Ring_c::pointerMove() {
|
||||
if (hoveredSlot < 0) {
|
||||
return false;
|
||||
}
|
||||
if (pointer.pressed) {
|
||||
mPointerTouchPressHoveredCurrent = pointer.touch && hoveredSlot == mCurrentSlot;
|
||||
}
|
||||
dusk::menu_pointer::set_hover_target(static_cast<dusk::menu_pointer::TargetId>(hoveredSlot));
|
||||
|
||||
if (mCurrentSlot != hoveredSlot) {
|
||||
mDirectSelectCursorPos.x = mItemSlotPosX[mCurrentSlot];
|
||||
@@ -1596,10 +1601,27 @@ bool dMenu_Ring_c::pointerMove() {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (dusk::menu_pointer::consume_click()) {
|
||||
const bool clickOpensExplain = !pointer.touch || mPointerTouchPressHoveredCurrent;
|
||||
if (clickOpensExplain && dusk::menu_pointer::consume_click()) {
|
||||
const u8 item = dComIfGs_getItem(mItemSlots[mCurrentSlot], false);
|
||||
if (!dMeter2Info_isTouchKeyCheck(0xe) && openExplain(item)) {
|
||||
dMeter2Info_setItemExplainWindowStatus(1);
|
||||
field_0x6c4 = mCurrentSlot;
|
||||
setStatus(STATUS_EXPLAIN);
|
||||
dMeter2Info_set2DVibration();
|
||||
setDoStatus(0);
|
||||
} else {
|
||||
Z2GetAudioMgr()->seStart(Z2SE_SYS_ERROR, NULL, 0, 0, 1.0f, 1.0f, -1.0f,
|
||||
-1.0f, 0);
|
||||
}
|
||||
mPointerTouchPressHoveredCurrent = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pointer.released) {
|
||||
mPointerTouchPressHoveredCurrent = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
+16
-10
@@ -1830,6 +1830,7 @@ bool dMenu_save_c::pointerSaveSelect() {
|
||||
if (!dusk::menu_pointer::hit_pane(mpSelData[i], 8.0f)) {
|
||||
continue;
|
||||
}
|
||||
dusk::menu_pointer::set_hover_target(pointer_target(s_pointerSaveSelectTarget, i));
|
||||
const bool clicked = dusk::menu_pointer::consume_click();
|
||||
if (mSelectedFile != i) {
|
||||
mDoAud_seStart(Z2SE_FILE_SELECT_CURSOR, NULL, 0, 0);
|
||||
@@ -1858,6 +1859,7 @@ bool dMenu_save_c::pointerYesNoSelect(bool errorSelect, u8 errParam, u8 soundPar
|
||||
if (!dusk::menu_pointer::hit_pane(mpNoYes[i], 8.0f)) {
|
||||
continue;
|
||||
}
|
||||
dusk::menu_pointer::set_hover_target(pointer_target(s_pointerYesNoSelectTarget, i));
|
||||
const bool clicked =
|
||||
(!errorSelect || mYesNoCursor == i) && dusk::menu_pointer::consume_click();
|
||||
if (mYesNoCursor != i) {
|
||||
@@ -1962,12 +1964,14 @@ void dMenu_save_c::saveSelectMoveAnime() {
|
||||
#if TARGET_PC
|
||||
dusk::menu_pointer::begin_context(dusk::menu_pointer::Context::Save);
|
||||
if (mSelectedFile != 0xFF &&
|
||||
dusk::menu_pointer::hit_pane(mpSelData[mSelectedFile], 8.0f) &&
|
||||
dusk::menu_pointer::consume_click())
|
||||
dusk::menu_pointer::hit_pane(mpSelData[mSelectedFile], 8.0f))
|
||||
{
|
||||
dusk::menu_pointer::defer_activation(
|
||||
dusk::menu_pointer::Context::Save,
|
||||
pointer_target(s_pointerSaveSelectTarget, mSelectedFile));
|
||||
dusk::menu_pointer::set_hover_target(pointer_target(s_pointerSaveSelectTarget, mSelectedFile));
|
||||
if (dusk::menu_pointer::consume_click()) {
|
||||
dusk::menu_pointer::defer_activation(
|
||||
dusk::menu_pointer::Context::Save,
|
||||
pointer_target(s_pointerSaveSelectTarget, mSelectedFile));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
bool bookWakuAnmComplete = true;
|
||||
@@ -2140,12 +2144,14 @@ void dMenu_save_c::yesNoCursorMoveAnm() {
|
||||
#if TARGET_PC
|
||||
dusk::menu_pointer::begin_context(dusk::menu_pointer::Context::Save);
|
||||
if (mYesNoCursor != 0xFF &&
|
||||
dusk::menu_pointer::hit_pane(mpNoYes[mYesNoCursor], 8.0f) &&
|
||||
dusk::menu_pointer::consume_click())
|
||||
dusk::menu_pointer::hit_pane(mpNoYes[mYesNoCursor], 8.0f))
|
||||
{
|
||||
dusk::menu_pointer::defer_activation(
|
||||
dusk::menu_pointer::Context::Save,
|
||||
pointer_target(s_pointerYesNoSelectTarget, mYesNoCursor));
|
||||
dusk::menu_pointer::set_hover_target(pointer_target(s_pointerYesNoSelectTarget, mYesNoCursor));
|
||||
if (dusk::menu_pointer::consume_click()) {
|
||||
dusk::menu_pointer::defer_activation(
|
||||
dusk::menu_pointer::Context::Save,
|
||||
pointer_target(s_pointerYesNoSelectTarget, mYesNoCursor));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
bool selAnmComplete = yesnoSelectMoveAnm(0);
|
||||
|
||||
@@ -316,6 +316,7 @@ bool dMenu_Skill_c::pointerWait() {
|
||||
if (!dusk::menu_pointer::hit_pane(mpLetterParent[i], 8.0f)) {
|
||||
continue;
|
||||
}
|
||||
dusk::menu_pointer::set_hover_target(i);
|
||||
|
||||
if (mIndex != i) {
|
||||
mIndex = i;
|
||||
|
||||
@@ -560,7 +560,8 @@ bool dMsgScrn3Select_c::pointerMove() {
|
||||
|
||||
mDPDPoint = choice;
|
||||
field_0x110 = paneIndex;
|
||||
dusk::menu_pointer::set_dialog_choice(choice, dusk::menu_pointer::state().clicked);
|
||||
dusk::menu_pointer::set_hover_target(choice);
|
||||
dusk::menu_pointer::set_dialog_choice(choice, dusk::menu_pointer::peek_click());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+142
-14
@@ -1,16 +1,34 @@
|
||||
#include "dusk/menu_pointer.h"
|
||||
|
||||
#include "m_Do/m_Do_graphic.h"
|
||||
#include "d/d_pane_class.h"
|
||||
#include "dusk/settings.h"
|
||||
#include "m_Do/m_Do_graphic.h"
|
||||
|
||||
#include <aurora/rmlui.hpp>
|
||||
#include <dolphin/pad.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
|
||||
namespace dusk::menu_pointer {
|
||||
namespace {
|
||||
using Clock = std::chrono::steady_clock;
|
||||
|
||||
constexpr auto kTapMaxDuration = std::chrono::milliseconds(300);
|
||||
constexpr f32 kTapMoveThresholdDp = 12.0f;
|
||||
|
||||
struct Gesture {
|
||||
bool active = false;
|
||||
bool movedTooFar = false;
|
||||
bool crossedTarget = false;
|
||||
bool pressTargetValid = false;
|
||||
Context pressContext = Context::None;
|
||||
TargetId pressTarget = InvalidTarget;
|
||||
f32 startX = 0.0f;
|
||||
f32 startY = 0.0f;
|
||||
Clock::time_point startedAt{};
|
||||
};
|
||||
|
||||
State s_state;
|
||||
bool s_clickConsumed = false;
|
||||
Context s_lastContext = Context::None;
|
||||
@@ -27,7 +45,14 @@ s32 s_mouseButton = -1;
|
||||
u32 s_suppressedPadHoldMask = 0;
|
||||
u32 s_suppressedPadNextReadMask = 0;
|
||||
Context s_deferredActivationContext = Context::None;
|
||||
u8 s_deferredActivationTarget = 0xFF;
|
||||
TargetId s_deferredActivationTarget = InvalidTarget;
|
||||
Gesture s_gesture;
|
||||
bool s_hoverTargetValid = false;
|
||||
TargetId s_hoverTarget = InvalidTarget;
|
||||
bool s_clickPending = false;
|
||||
Context s_clickContext = Context::None;
|
||||
TargetId s_clickTarget = InvalidTarget;
|
||||
bool s_clickTargetValid = false;
|
||||
|
||||
s32 scancode_from_rml_button(s32 button) noexcept {
|
||||
switch (button) {
|
||||
@@ -104,6 +129,37 @@ void suppress_pad_for_mouse_button(s32 button, bool held) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
f32 tap_move_threshold() noexcept {
|
||||
auto* context = aurora::rmlui::get_context();
|
||||
if (context == nullptr) {
|
||||
return kTapMoveThresholdDp;
|
||||
}
|
||||
|
||||
return kTapMoveThresholdDp * std::max(context->GetDensityIndependentPixelRatio(), 1.0f);
|
||||
}
|
||||
|
||||
void update_gesture_movement(f32 x, f32 y) noexcept {
|
||||
if (!s_gesture.active || s_gesture.movedTooFar) {
|
||||
return;
|
||||
}
|
||||
|
||||
const f32 dx = x - s_gesture.startX;
|
||||
const f32 dy = y - s_gesture.startY;
|
||||
const f32 threshold = tap_move_threshold();
|
||||
if (dx * dx + dy * dy > threshold * threshold) {
|
||||
s_gesture.movedTooFar = true;
|
||||
}
|
||||
}
|
||||
|
||||
void clear_click_state() noexcept {
|
||||
s_clickConsumed = false;
|
||||
s_clickPending = false;
|
||||
s_clickContext = Context::None;
|
||||
s_clickTarget = InvalidTarget;
|
||||
s_clickTargetValid = false;
|
||||
s_state.clicked = false;
|
||||
}
|
||||
|
||||
void set_position_from_rml(f32 x, f32 y) noexcept {
|
||||
auto* context = aurora::rmlui::get_context();
|
||||
if (context == nullptr) {
|
||||
@@ -121,7 +177,7 @@ void set_position_from_rml(f32 x, f32 y) noexcept {
|
||||
|
||||
void clear_input_state() noexcept {
|
||||
s_state = {};
|
||||
s_clickConsumed = false;
|
||||
clear_click_state();
|
||||
s_lastDialogChoice = 0xFF;
|
||||
s_currentDialogChoice = 0xFF;
|
||||
s_lastDialogChoiceValid = false;
|
||||
@@ -134,7 +190,10 @@ void clear_input_state() noexcept {
|
||||
s_suppressedPadHoldMask = 0;
|
||||
s_suppressedPadNextReadMask = 0;
|
||||
s_deferredActivationContext = Context::None;
|
||||
s_deferredActivationTarget = 0xFF;
|
||||
s_deferredActivationTarget = InvalidTarget;
|
||||
s_gesture = {};
|
||||
s_hoverTargetValid = false;
|
||||
s_hoverTarget = InvalidTarget;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -144,8 +203,6 @@ bool handle_fallthrough_pointer(f32 x, f32 y, Phase phase, bool touch, s32 mouse
|
||||
return false;
|
||||
}
|
||||
|
||||
s_clickConsumed = false;
|
||||
|
||||
if (!touch) {
|
||||
if (phase == Phase::Press) {
|
||||
if (!mouse_button_is_menu_confirm(mouseButton)) {
|
||||
@@ -174,21 +231,41 @@ bool handle_fallthrough_pointer(f32 x, f32 y, Phase phase, bool touch, s32 mouse
|
||||
}
|
||||
|
||||
if (phase != Phase::Cancel) {
|
||||
update_gesture_movement(x, y);
|
||||
set_position_from_rml(x, y);
|
||||
}
|
||||
s_state.touch = touch;
|
||||
|
||||
switch (phase) {
|
||||
case Phase::Press:
|
||||
clear_click_state();
|
||||
s_gesture = {
|
||||
.active = true,
|
||||
.startX = x,
|
||||
.startY = y,
|
||||
.startedAt = Clock::now(),
|
||||
};
|
||||
s_state.down = true;
|
||||
s_state.pressed = true;
|
||||
break;
|
||||
case Phase::Release:
|
||||
case Phase::Release: {
|
||||
const bool shortEnough =
|
||||
s_gesture.active && Clock::now() - s_gesture.startedAt <= kTapMaxDuration;
|
||||
const bool stillEnough = s_gesture.active && !s_gesture.movedTooFar;
|
||||
const bool targetClean = s_gesture.active && !s_gesture.crossedTarget;
|
||||
s_clickContext = s_gesture.pressContext;
|
||||
s_clickTarget = s_gesture.pressTarget;
|
||||
s_clickTargetValid = s_gesture.pressTargetValid;
|
||||
s_clickPending = shortEnough && stillEnough && targetClean;
|
||||
s_state.down = false;
|
||||
s_state.released = true;
|
||||
s_state.clicked = true;
|
||||
s_state.clicked = s_clickPending;
|
||||
s_gesture = {};
|
||||
break;
|
||||
}
|
||||
case Phase::Cancel:
|
||||
clear_click_state();
|
||||
s_gesture = {};
|
||||
s_state.down = false;
|
||||
break;
|
||||
case Phase::Move:
|
||||
@@ -211,6 +288,12 @@ void begin_game_frame() noexcept {
|
||||
}
|
||||
|
||||
void end_game_frame() noexcept {
|
||||
if (s_gesture.active && s_gesture.pressTargetValid &&
|
||||
s_currentContext == s_gesture.pressContext && !s_hoverTargetValid)
|
||||
{
|
||||
s_gesture.crossedTarget = true;
|
||||
}
|
||||
|
||||
s_lastContext = s_currentContext;
|
||||
s_lastDialogChoice = s_currentDialogChoice;
|
||||
s_lastDialogChoiceValid = s_currentDialogChoiceValid;
|
||||
@@ -222,6 +305,12 @@ void end_game_frame() noexcept {
|
||||
s_state.valid = false;
|
||||
}
|
||||
s_clickConsumed = false;
|
||||
s_clickPending = false;
|
||||
s_clickContext = Context::None;
|
||||
s_clickTarget = InvalidTarget;
|
||||
s_clickTargetValid = false;
|
||||
s_hoverTargetValid = false;
|
||||
s_hoverTarget = InvalidTarget;
|
||||
}
|
||||
|
||||
void begin_context(Context context) noexcept {
|
||||
@@ -237,7 +326,11 @@ void begin_context(Context context) noexcept {
|
||||
s_suppressedPadHoldMask = 0;
|
||||
s_suppressedPadNextReadMask = 0;
|
||||
s_deferredActivationContext = Context::None;
|
||||
s_deferredActivationTarget = 0xFF;
|
||||
s_deferredActivationTarget = InvalidTarget;
|
||||
s_gesture = {};
|
||||
s_hoverTargetValid = false;
|
||||
s_hoverTarget = InvalidTarget;
|
||||
clear_click_state();
|
||||
}
|
||||
|
||||
s_currentContext = context;
|
||||
@@ -259,15 +352,50 @@ const State& state() noexcept {
|
||||
return s_state;
|
||||
}
|
||||
|
||||
void set_hover_target(TargetId target) noexcept {
|
||||
s_hoverTargetValid = true;
|
||||
s_hoverTarget = target;
|
||||
|
||||
if (s_gesture.active && !s_gesture.pressTargetValid && s_state.down) {
|
||||
s_gesture.pressContext = s_currentContext;
|
||||
s_gesture.pressTarget = target;
|
||||
s_gesture.pressTargetValid = true;
|
||||
}
|
||||
|
||||
if (s_gesture.active && s_gesture.pressTargetValid &&
|
||||
(s_currentContext != s_gesture.pressContext || target != s_gesture.pressTarget))
|
||||
{
|
||||
s_gesture.crossedTarget = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool click_matches_hover_target() noexcept {
|
||||
if (!s_clickPending || !s_hoverTargetValid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!s_clickTargetValid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return s_currentContext == s_clickContext && s_hoverTarget == s_clickTarget;
|
||||
}
|
||||
|
||||
bool consume_click() noexcept {
|
||||
if (!s_state.clicked || s_clickConsumed) {
|
||||
if (s_clickConsumed || !click_matches_hover_target()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
s_clickConsumed = true;
|
||||
s_clickPending = false;
|
||||
s_state.clicked = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool peek_click() noexcept {
|
||||
return !s_clickConsumed && click_matches_hover_target();
|
||||
}
|
||||
|
||||
void set_dialog_choice(u8 choice, bool clicked) noexcept {
|
||||
s_currentDialogChoice = choice;
|
||||
s_currentDialogChoiceValid = true;
|
||||
@@ -300,18 +428,18 @@ bool consume_dialog_click(u8& choice) noexcept {
|
||||
return false;
|
||||
}
|
||||
|
||||
void defer_activation(Context context, u8 target) noexcept {
|
||||
void defer_activation(Context context, TargetId target) noexcept {
|
||||
s_deferredActivationContext = context;
|
||||
s_deferredActivationTarget = target;
|
||||
}
|
||||
|
||||
bool consume_deferred_activation(Context context, u8 target) noexcept {
|
||||
bool consume_deferred_activation(Context context, TargetId target) noexcept {
|
||||
if (s_deferredActivationContext != context || s_deferredActivationTarget != target) {
|
||||
return false;
|
||||
}
|
||||
|
||||
s_deferredActivationContext = Context::None;
|
||||
s_deferredActivationTarget = 0xFF;
|
||||
s_deferredActivationTarget = InvalidTarget;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -321,7 +449,7 @@ void clear_deferred_activation(Context context) noexcept {
|
||||
}
|
||||
|
||||
s_deferredActivationContext = Context::None;
|
||||
s_deferredActivationTarget = 0xFF;
|
||||
s_deferredActivationTarget = InvalidTarget;
|
||||
}
|
||||
|
||||
u32 suppressed_pad_buttons(u32 port) noexcept {
|
||||
|
||||
@@ -668,7 +668,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
|
||||
leftPane.register_control(
|
||||
leftPane.add_select_button({
|
||||
.key = "Graphics Backend",
|
||||
.getValue = [] { return Rml::String{backend_name(configured_backend())}; },
|
||||
.getValue = [] { return Rml::String{backend_name(aurora_get_backend())}; },
|
||||
.isModified =
|
||||
[] {
|
||||
return getSettings().backend.graphicsBackend.getValue() !=
|
||||
|
||||
Reference in New Issue
Block a user