mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-08-16 04:23:53 -04:00
Add "Touch Targeting" option
This commit is contained in:
Vendored
+1
-1
Submodule extern/aurora updated: e145b9ec20...9087a409da
@@ -46,6 +46,12 @@ enum class FrameInterpMode : u8 {
|
||||
Unlimited = 2,
|
||||
};
|
||||
|
||||
enum class TouchTargeting : u8 {
|
||||
Hybrid = 0,
|
||||
Hold = 1,
|
||||
Switch = 2,
|
||||
};
|
||||
|
||||
enum class MenuScaling : u8 {
|
||||
GameCube = 0,
|
||||
Wii = 1,
|
||||
@@ -97,6 +103,12 @@ struct ConfigEnumRange<FrameInterpMode> {
|
||||
static constexpr auto max = FrameInterpMode::Unlimited;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ConfigEnumRange<TouchTargeting> {
|
||||
static constexpr auto min = TouchTargeting::Hybrid;
|
||||
static constexpr auto max = TouchTargeting::Switch;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ConfigEnumRange<MenuScaling> {
|
||||
static constexpr auto min = MenuScaling::GameCube;
|
||||
@@ -216,6 +228,7 @@ struct UserSettings {
|
||||
ConfigVar<bool> invertMouseY;
|
||||
ConfigVar<bool> freeCamera;
|
||||
ConfigVar<bool> enableTouchControls;
|
||||
ConfigVar<TouchTargeting> touchTargeting;
|
||||
ConfigVar<bool> enableMenuPointer;
|
||||
ConfigVar<ui::ControlLayout> touchControlsLayout;
|
||||
ConfigVar<bool> invertCameraXAxis;
|
||||
|
||||
@@ -378,6 +378,7 @@ nlohmann::json ConfigImpl<ui::ControlLayout>::dumpToJson(const ConfigVar<ui::Con
|
||||
}
|
||||
|
||||
template class ConfigImpl<dusk::FrameInterpMode>;
|
||||
template class ConfigImpl<dusk::TouchTargeting>;
|
||||
template class ConfigImpl<dusk::MenuScaling>;
|
||||
template class ConfigImpl<dusk::Resampler>;
|
||||
template class ConfigImpl<dusk::MagicArmorMode>;
|
||||
|
||||
@@ -96,6 +96,7 @@ UserSettings g_userSettings = {
|
||||
.invertMouseY {"game.invertMouseY", false},
|
||||
.freeCamera {"game.freeCamera", false},
|
||||
.enableTouchControls {"game.enableTouchControls", false},
|
||||
.touchTargeting {"game.touchTargeting", TouchTargeting::Hybrid},
|
||||
.enableMenuPointer {"game.enableMenuPointer", true},
|
||||
.touchControlsLayout {"game.touchControlsLayout", ui::ControlLayout{}},
|
||||
.invertCameraXAxis {"game.invertCameraXAxis", false},
|
||||
@@ -329,6 +330,7 @@ void registerSettings() {
|
||||
Register(g_userSettings.game.invertMouseY);
|
||||
Register(g_userSettings.game.freeCamera);
|
||||
Register(g_userSettings.game.enableTouchControls);
|
||||
Register(g_userSettings.game.touchTargeting);
|
||||
Register(g_userSettings.game.enableMenuPointer);
|
||||
Register(g_userSettings.game.touchControlsLayout);
|
||||
Register(g_userSettings.game.debugFlyCam);
|
||||
|
||||
@@ -77,6 +77,18 @@ constexpr std::array kInterpolationModes = {
|
||||
"Unlimited",
|
||||
};
|
||||
|
||||
constexpr std::array kTouchTargetingLabels = {
|
||||
"Hybrid",
|
||||
"Hold",
|
||||
"Switch",
|
||||
};
|
||||
|
||||
constexpr std::array kTouchTargetingDescriptions = {
|
||||
"Tap once to lock on when a target is found. Double-tap when none is found to hold L.",
|
||||
"L stays held only while your finger is on the button.",
|
||||
"Tap L to keep it held. Tap again to release it.",
|
||||
};
|
||||
|
||||
constexpr std::array kGyroInputModeLabels = {
|
||||
"Sensor",
|
||||
"Mouse",
|
||||
@@ -407,6 +419,14 @@ bool gyro_enabled() {
|
||||
return getSettings().game.enableGyroAim || getSettings().game.enableGyroRollgoal;
|
||||
}
|
||||
|
||||
Rml::String touch_targeting_label(TouchTargeting targeting) {
|
||||
const auto index = static_cast<std::size_t>(targeting);
|
||||
if (index >= kTouchTargetingLabels.size()) {
|
||||
return "Unknown";
|
||||
}
|
||||
return kTouchTargetingLabels[index];
|
||||
}
|
||||
|
||||
struct ConfigBoolProps {
|
||||
Rml::String key;
|
||||
Rml::String icon;
|
||||
@@ -1003,6 +1023,45 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
|
||||
pane.clear();
|
||||
pane.add_text("Open the touch controls layout editor.");
|
||||
});
|
||||
leftPane.register_control(leftPane.add_select_button({
|
||||
.key = "Touch Targeting",
|
||||
.getValue =
|
||||
[] {
|
||||
return touch_targeting_label(
|
||||
getSettings().game.touchTargeting.getValue());
|
||||
},
|
||||
.isDisabled =
|
||||
[] { return !getSettings().game.enableTouchControls; },
|
||||
.isModified =
|
||||
[] {
|
||||
const auto& targeting =
|
||||
getSettings().game.touchTargeting;
|
||||
return targeting.getValue() !=
|
||||
targeting.getDefaultValue();
|
||||
},
|
||||
}),
|
||||
rightPane, [](Pane& pane) {
|
||||
pane.clear();
|
||||
for (int i = 0; i < static_cast<int>(kTouchTargetingLabels.size()); ++i) {
|
||||
pane.add_button({
|
||||
.text = kTouchTargetingLabels[i],
|
||||
.isSelected =
|
||||
[i] {
|
||||
return getSettings().game.touchTargeting.getValue() ==
|
||||
static_cast<TouchTargeting>(i);
|
||||
},
|
||||
})
|
||||
.on_pressed([i] {
|
||||
mDoAud_seStartMenu(kSoundItemChange);
|
||||
getSettings().game.touchTargeting.setValue(
|
||||
static_cast<TouchTargeting>(i));
|
||||
config::Save();
|
||||
});
|
||||
}
|
||||
pane.add_rml(fmt::format("<br/>Hybrid: {}<br/>Hold: {}<br/>Switch: {}",
|
||||
kTouchTargetingDescriptions[0], kTouchTargetingDescriptions[1],
|
||||
kTouchTargetingDescriptions[2]));
|
||||
});
|
||||
config_percent_select(leftPane, rightPane, getSettings().game.touchCameraXSensitivity,
|
||||
"Touch Camera X Sensitivity",
|
||||
"Adjusts touch camera horizontal sensitivity.<br/><br/>Applies to touch input only.",
|
||||
|
||||
@@ -485,43 +485,71 @@ void TouchControls::set_control_pressed(Control control, bool pressed) {
|
||||
mLastLTapTime = {};
|
||||
break;
|
||||
}
|
||||
if (pressed && (mLLatched || mManualLLatched)) {
|
||||
switch (getSettings().game.touchTargeting.getValue()) {
|
||||
case TouchTargeting::Hold:
|
||||
mLPressed = pressed;
|
||||
mLLatched = false;
|
||||
mManualLLatched = false;
|
||||
mLPressed = false;
|
||||
mLReleasePending = true;
|
||||
mLReleasePending = false;
|
||||
mLPressStartTime = {};
|
||||
mLastLTapTime = {};
|
||||
set_control_visual(control, false);
|
||||
} else if (pressed) {
|
||||
const auto now = clock::now();
|
||||
if (!player_attention_locked() && mLastLTapTime != clock::time_point{} &&
|
||||
now - mLastLTapTime <= kLDoubleTapWindow)
|
||||
{
|
||||
mManualLLatched = true;
|
||||
break;
|
||||
case TouchTargeting::Switch:
|
||||
if (pressed) {
|
||||
const bool wasLatched = mLPressed || mLLatched || mManualLLatched;
|
||||
mLPressed = false;
|
||||
mLLatched = false;
|
||||
mManualLLatched = !wasLatched;
|
||||
mLReleasePending = true;
|
||||
} else {
|
||||
mLPressed = false;
|
||||
mLLatched = false;
|
||||
mLReleasePending = false;
|
||||
}
|
||||
mLPressStartTime = {};
|
||||
mLastLTapTime = {};
|
||||
break;
|
||||
case TouchTargeting::Hybrid:
|
||||
default:
|
||||
if (pressed && (mLLatched || mManualLLatched)) {
|
||||
mLLatched = false;
|
||||
mManualLLatched = false;
|
||||
mLPressed = false;
|
||||
mLReleasePending = true;
|
||||
mLPressStartTime = {};
|
||||
mLastLTapTime = {};
|
||||
set_control_visual(control, false);
|
||||
} else if (pressed) {
|
||||
const auto now = clock::now();
|
||||
if (!player_attention_locked() && mLastLTapTime != clock::time_point{} &&
|
||||
now - mLastLTapTime <= kLDoubleTapWindow)
|
||||
{
|
||||
mManualLLatched = true;
|
||||
mLPressed = false;
|
||||
mLReleasePending = true;
|
||||
mLPressStartTime = {};
|
||||
mLastLTapTime = {};
|
||||
} else if (!mLReleasePending) {
|
||||
mLPressed = true;
|
||||
mLPressStartTime = now;
|
||||
}
|
||||
} else if (!mLReleasePending) {
|
||||
mLPressed = true;
|
||||
mLPressStartTime = now;
|
||||
mLPressed = false;
|
||||
}
|
||||
} else if (!mLReleasePending) {
|
||||
mLPressed = false;
|
||||
}
|
||||
if (!pressed) {
|
||||
const auto now = clock::now();
|
||||
if (!mLReleasePending) {
|
||||
const bool wasQuickTap = mLPressStartTime != clock::time_point{} &&
|
||||
now - mLPressStartTime <= kLDoubleTapWindow;
|
||||
mLastLTapTime = wasQuickTap ? now : clock::time_point{};
|
||||
if (!pressed) {
|
||||
const auto now = clock::now();
|
||||
if (!mLReleasePending) {
|
||||
const bool wasQuickTap = mLPressStartTime != clock::time_point{} &&
|
||||
now - mLPressStartTime <= kLDoubleTapWindow;
|
||||
mLastLTapTime = wasQuickTap ? now : clock::time_point{};
|
||||
}
|
||||
mLPressStartTime = {};
|
||||
mLReleasePending = false;
|
||||
}
|
||||
mLPressStartTime = {};
|
||||
mLReleasePending = false;
|
||||
}
|
||||
if (!pressed && !player_attention_locked()) {
|
||||
mLLatched = false;
|
||||
if (!pressed && !player_attention_locked()) {
|
||||
mLLatched = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Control::R:
|
||||
@@ -635,6 +663,17 @@ void TouchControls::apply_control_transform(Control control) noexcept {
|
||||
}
|
||||
|
||||
void TouchControls::sync_l_lock_state() noexcept {
|
||||
const auto targeting = getSettings().game.touchTargeting.getValue();
|
||||
if (targeting == TouchTargeting::Hold) {
|
||||
mLLatched = false;
|
||||
mManualLLatched = false;
|
||||
return;
|
||||
}
|
||||
if (targeting == TouchTargeting::Switch) {
|
||||
mLLatched = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (player_attention_locked()) {
|
||||
if (mLPressed) {
|
||||
mLLatched = true;
|
||||
|
||||
Reference in New Issue
Block a user