From 42d9dd23c0db36ce34b40025418e71b49554af08 Mon Sep 17 00:00:00 2001 From: Olivia!! Date: Thu, 28 May 2026 07:35:29 +0200 Subject: [PATCH] Add option for inverting Direct Select (#1841) Adds a new subheading under Input for gameplay-related settings. It's at the bottom because players probably will want to configure their camera more than they care about ornery gameplay details. The one and only toggle there right now is to invert the function of the L-trigger on the Item Wheel. It renders the on-screen text properly if inverted too, meaning with it on the game does tell you that holding L will rotate and moving the stick without holding L will direct select. --- include/dusk/settings.h | 1 + src/d/d_menu_ring.cpp | 55 ++++++++++++++++++++++++++++++++++++++++ src/dusk/settings.cpp | 2 ++ src/dusk/ui/settings.cpp | 4 +++ 4 files changed, 62 insertions(+) diff --git a/include/dusk/settings.h b/include/dusk/settings.h index 923a1e9fc6..c002f3b65b 100644 --- a/include/dusk/settings.h +++ b/include/dusk/settings.h @@ -208,6 +208,7 @@ struct UserSettings { ConfigVar debugFlyCam; ConfigVar debugFlyCamLockEvents; ConfigVar allowBackgroundInput; + ConfigVar swapDirectSelect; // Cheats ConfigVar infiniteHearts; diff --git a/src/d/d_menu_ring.cpp b/src/d/d_menu_ring.cpp index 5cdb8fbc04..a468ba889e 100644 --- a/src/d/d_menu_ring.cpp +++ b/src/d/d_menu_ring.cpp @@ -31,6 +31,7 @@ #if TARGET_PC #include "dusk/game_clock.h" +#include "dusk/settings.h" #endif typedef void (dMenu_Ring_c::*initFunc)(); @@ -349,11 +350,33 @@ dMenu_Ring_c::dMenu_Ring_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i } for (i = 0; i < 5; i++) { #if VERSION == VERSION_GCN_JPN + #if TARGET_PC + J2DTextBox* fc_TextBox; + if (dusk::getSettings().game.swapDirectSelect) { + fc_TextBox = (J2DTextBox*)mpScreen->search(c_text1[i]); + mpScreen->search(fc_text1[i])->hide(); + } else { + fc_TextBox = (J2DTextBox*)mpScreen->search(c_text[i]); + mpScreen->search(fc_text[i])->hide(); + } + #else J2DTextBox* fc_TextBox = (J2DTextBox*)mpScreen->search(c_text[i]); mpScreen->search(fc_text[i])->hide(); + #endif #else + #if TARGET_PC + J2DTextBox* fc_TextBox; + if (dusk::getSettings().game.swapDirectSelect) { + fc_TextBox = (J2DTextBox*)mpScreen->search(fc_text1[i]); + mpScreen->search(c_text1[i])->hide(); + } else { + fc_TextBox = (J2DTextBox*)mpScreen->search(fc_text[i]); + mpScreen->search(c_text[i])->hide(); + } + #else J2DTextBox* fc_TextBox = (J2DTextBox*)mpScreen->search(fc_text[i]); mpScreen->search(c_text[i])->hide(); + #endif #endif fc_TextBox->setFont(mDoExt_getMesgFont()); fc_TextBox->setString(0x40, ""); @@ -361,11 +384,33 @@ dMenu_Ring_c::dMenu_Ring_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i } for (i = 0; i < 5; i++) { #if VERSION == VERSION_GCN_JPN + #if TARGET_PC + J2DTextBox* fc1_TextBox; + if (dusk::getSettings().game.swapDirectSelect) { + fc1_TextBox = (J2DTextBox*)mpScreen->search(c_text[i]); + mpScreen->search(fc_text[i])->hide(); + } else { + fc1_TextBox = (J2DTextBox*)mpScreen->search(c_text1[i]); + mpScreen->search(fc_text1[i])->hide(); + } + #else J2DTextBox* fc1_TextBox = (J2DTextBox*)mpScreen->search(c_text1[i]); mpScreen->search(fc_text1[i])->hide(); + #endif #else + #if TARGET_PC + J2DTextBox* fc1_TextBox; + if (dusk::getSettings().game.swapDirectSelect) { + fc1_TextBox = (J2DTextBox*)mpScreen->search(fc_text[i]); + mpScreen->search(c_text[i])->hide(); + } else { + fc1_TextBox = (J2DTextBox*)mpScreen->search(fc_text1[i]); + mpScreen->search(c_text1[i])->hide(); + } + #else J2DTextBox* fc1_TextBox = (J2DTextBox*)mpScreen->search(fc_text1[i]); mpScreen->search(c_text1[i])->hide(); + #endif #endif fc1_TextBox->setFont(mDoExt_getMesgFont()); fc1_TextBox->setString(0x40, ""); @@ -852,7 +897,12 @@ u8 dMenu_Ring_c::getStickInfo(STControl* i_stick) { } if (mCurrentSlot != val2) { + #ifdef TARGET_PC + if ((mDoCPd_c::getHoldL(PAD_1) && !dusk::getSettings().game.swapDirectSelect) || + (!mDoCPd_c::getHoldL(PAD_1) && dusk::getSettings().game.swapDirectSelect)) { + #else if (mDoCPd_c::getHoldL(PAD_1)) { + #endif mDirectSelectCursorPos.x = mItemSlotPosX[mCurrentSlot]; mDirectSelectCursorPos.z = mItemSlotPosY[mCurrentSlot]; mCurrentSlot = val2; @@ -1433,7 +1483,12 @@ void dMenu_Ring_c::drawItem2() { } void dMenu_Ring_c::stick_wait_init() { + #ifdef TARGET_PC + if ((mDoCPd_c::getHoldL(PAD_1) && !dusk::getSettings().game.swapDirectSelect) || + (!mDoCPd_c::getHoldL(PAD_1) && dusk::getSettings().game.swapDirectSelect)) { + #else if (mDoCPd_c::getHoldL(PAD_1) != 0) { + #endif if (mDirectSelectActive) { mWaitFrames = g_ringHIO.mDirectSelectWaitFrames; } else { diff --git a/src/dusk/settings.cpp b/src/dusk/settings.cpp index ef639e2b05..2aa628887d 100644 --- a/src/dusk/settings.cpp +++ b/src/dusk/settings.cpp @@ -96,6 +96,7 @@ UserSettings g_userSettings = { .debugFlyCam {"game.debugFlyCam", false}, .debugFlyCamLockEvents {"game.debugFlyCamLockEvents", true}, .allowBackgroundInput {"game.allowBackgroundInput", true}, + .swapDirectSelect {"game.swapDirectSelect", false}, // Cheats .infiniteHearts {"game.infiniteHearts", false}, @@ -286,6 +287,7 @@ void registerSettings() { Register(g_userSettings.game.debugFlyCam); Register(g_userSettings.game.debugFlyCamLockEvents); Register(g_userSettings.game.allowBackgroundInput); + Register(g_userSettings.game.swapDirectSelect); Register(g_userSettings.backend.isoPath); Register(g_userSettings.backend.isoVerification); diff --git a/src/dusk/ui/settings.cpp b/src/dusk/ui/settings.cpp index 0a3cf26a1f..185bf5681d 100644 --- a/src/dusk/ui/settings.cpp +++ b/src/dusk/ui/settings.cpp @@ -1030,6 +1030,10 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) { "Invert vertical gyro aiming.", [] { return !gyro_enabled(); }); addOption("Invert Gyro Yaw", getSettings().game.gyroInvertYaw, "Invert horizontal gyro aiming.", [] { return !gyro_enabled(); }); + + leftPane.add_section("Gameplay"); + addOption("Swap Direct Select Input", getSettings().game.swapDirectSelect, + "Swap the controls for using Direct Select on the item wheel, making Direct Select the default and holding L to scroll the wheel."); leftPane.add_section("Tools"); addOption("Turbo Key", getSettings().game.enableTurboKeybind,