Skip to content

Inverted FETT263_SWING_CLASH_DELAY guard blocks Battle Mode / Multi-Blast toggle and lets a clash toggle them instead #890

Description

@chrisludwig

Version

  • ProffieOS v8.10 (commit 3c991a7)
  • Prop: props/saber_fett263_buttons.h
  • Board: Proffieboard V3.9, 2-button setup

Summary

The FETT263_SWING_CLASH_DELAY guard on the swing-driven Battle Mode and Multi-Blast toggles has its comparison inverted (> where it should be <). As a result the toggle is blocked during normal use and only fires within the short window right after a clash — the exact opposite of the documented intent.

The code

The same guard appears on both swing toggles:

saber_fett263_buttons.h:6137 — Battle Mode toggle (Hold AUX + Swing, active when FETT263_HOLD_BUTTON_LOCKUP is defined):

#if defined(FETT263_HOLD_BUTTON_LOCKUP) && !defined(FETT263_DISABLE_BM_TOGGLE)
      case EVENTID(BUTTON_NONE, EVENT_SWING, MODE_ON | BUTTON_AUX):
        if (menu_ || CheckShowColorCC() || millis() - last_clash_ > FETT263_SWING_CLASH_DELAY) return true;
        ToggleBattleMode();
        return true;
#endif

saber_fett263_buttons.h:5811 — Multi-Blast toggle (Hold PWR + Swing). Note that this
occurrence sits inside the #if NUM_BUTTONS == 1 block (lines 5514–5905), so it only
affects 1-button builds; on 2-button builds Multi-Blast is toggled by Long Click AUX
(line 6297), which has no such guard:

      case EVENTID(BUTTON_NONE, EVENT_SWING, MODE_ON | BUTTON_POWER):
        if (menu_ || CheckShowColorCC() || millis() - last_clash_ > FETT263_SWING_CLASH_DELAY) return true;
        ToggleMultiBlast();
        return true;

Why it is inverted

The documented purpose of the define (saber_fett263_buttons.h:537):

FETT263_SWING_CLASH_DELAY — Set delay timing in MILLIS for Button/Swing Events if a Clash is detected. Prevent trigger for Multi-Blast/Battle Mode where a button hold and swing are used but a Clash was detected, i.e. Lockup trigger. Default is 150.

So the toggle should be suppressed while a clash was recently detected (a clash produces an incidental swing), and allowed otherwise.

last_clash_ (props/prop_base.h:121) starts at 0 and is set to millis() on every clash. Therefore millis() - last_clash_ is:

  • large during normal use (no recent clash),
  • small (< FETT263_SWING_CLASH_DELAY) only for ~150 ms after a clash.

return true consumes the event without toggling, so ToggleBattleMode() / ToggleMultiBlast() runs only when the condition is false:

  • Normal deliberate swing → millis() - last_clash_ > 150 is true → event consumed → toggle never happens.
  • Swing within 150 ms of a clash → condition false → toggle fires.

That is exactly backwards from the intent.

The correct idiom for "recently clashed" is already used elsewhere in the same tree — props/prop_base.h:204:

uint32_t time_since_last_clash = now - last_clash_;
if (time_since_last_clash < clash_timeout_) { ... }

i.e. <, not >.

Proposed fix

Change > to < on both lines (5811 and 6137). Line 6137 is the one that hits 2-button
builds; line 5811 has the same defect in the 1-button branch:

if (menu_ || CheckShowColorCC() || millis() - last_clash_ < FETT263_SWING_CLASH_DELAY) return true;

Observed symptoms (2-button build with FETT263_HOLD_BUTTON_LOCKUP defined — line 6137)

  1. Battle Mode cannot be toggled off. Hold AUX + Swing never registers, because a deliberate toggle has no preceding clash, so the inverted guard always consumes it.
  2. A clash while holding AUX silently toggles Battle Mode. The clash-induced swing lands inside the 150 ms window and passes the guard. Because most fonts have no bmbegin.wav, ToggleBattleMode() (saber_fett263_buttons.h:5244) falls back to hybrid_font.DoEffect(EFFECT_FORCE, 0) and plays a force/*.wav quote — which presents to the user as a random quote firing on clash.

Workaround

Removing FETT263_HOLD_BUTTON_LOCKUP moves the Battle Mode toggle to the EVENTID(BUTTON_AUX, EVENT_HELD_LONG, MODE_ON) handler (saber_fett263_buttons.h:6130), which has no SWING_CLASH_DELAY guard, so Hold AUX toggles reliably. (Trade-off: lockup returns to Hold PWR + Clash.) Alternatively FETT263_DISABLE_BM_TOGGLE compiles the broken branch out entirely.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions