mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-07-26 14:58:12 +00:00
fix(ui/input): first melody note duration; OLED joystick reset
UITask: when a key is pressed while the buzzer is playing, defer the next screen refresh by 300 ms instead of triggering it immediately (via _next_refresh = 100). The blocking e-ink endFrame() was extending the first note by the full refresh duration (~150-200 ms). Subsequent notes were unaffected because _next_refresh was already future-dated after the first render. DataStore: for builds where JOYSTICK_ROTATION is not defined and FEAT_JOYSTICK_ROTATION_SETTING is 0 (OLED), always reset joystick_rotation to 0 on prefs load. Without this, stale e-ink prefs (which allow changing joystick rotation in Settings) could silently leave a non-zero value that reversed all joystick directions on OLED. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -211,6 +211,10 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no
|
||||
#endif
|
||||
#ifdef JOYSTICK_ROTATION
|
||||
_prefs.joystick_rotation = JOYSTICK_ROTATION;
|
||||
#elif !FEAT_JOYSTICK_ROTATION_SETTING
|
||||
// OLED: no rotation setting in UI — always reset to 0 so stale e-ink prefs
|
||||
// (which could have a non-zero value) don't silently reverse the joystick.
|
||||
_prefs.joystick_rotation = 0;
|
||||
#endif
|
||||
|
||||
File file = openRead(_fs, filename);
|
||||
@@ -312,6 +316,8 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no
|
||||
rd(&_prefs.trail_interval_idx, sizeof(_prefs.trail_interval_idx));
|
||||
rd(&_prefs.trail_min_delta_idx, sizeof(_prefs.trail_min_delta_idx));
|
||||
rd(&_prefs.trail_units_idx, sizeof(_prefs.trail_units_idx));
|
||||
rd(&_prefs.ch_fav_bitmask, sizeof(_prefs.ch_fav_bitmask));
|
||||
rd(&_prefs.ch_fav_only, sizeof(_prefs.ch_fav_only));
|
||||
|
||||
// Schema sentinel: bumped on layout changes. Mismatch means an older file
|
||||
// (or a different schema); rd() already zero-inits any fields not present,
|
||||
@@ -417,6 +423,8 @@ void DataStore::savePrefs(const NodePrefs& _prefs, double node_lat, double node_
|
||||
file.write((uint8_t *)&_prefs.trail_interval_idx, sizeof(_prefs.trail_interval_idx));
|
||||
file.write((uint8_t *)&_prefs.trail_min_delta_idx, sizeof(_prefs.trail_min_delta_idx));
|
||||
file.write((uint8_t *)&_prefs.trail_units_idx, sizeof(_prefs.trail_units_idx));
|
||||
file.write((uint8_t *)&_prefs.ch_fav_bitmask, sizeof(_prefs.ch_fav_bitmask));
|
||||
file.write((uint8_t *)&_prefs.ch_fav_only, sizeof(_prefs.ch_fav_only));
|
||||
|
||||
// Tail sentinel — must be last. See NodePrefs::SCHEMA_SENTINEL.
|
||||
uint32_t sentinel = NodePrefs::SCHEMA_SENTINEL;
|
||||
|
||||
@@ -1590,7 +1590,18 @@ void UITask::loop() {
|
||||
if (!_locked && curr) {
|
||||
curr->handleInput(c);
|
||||
{ uint32_t aoff = autoOffMillis(); if (aoff > 0) _auto_off = millis() + aoff; } // extend auto-off timer
|
||||
#ifdef PIN_BUZZER
|
||||
if (buzzer.isPlaying()) {
|
||||
// Keep the next render at least 300 ms away so the blocking e-ink endFrame()
|
||||
// doesn't extend the current note. 300 ms covers the slowest note at 120 BPM (1/4).
|
||||
unsigned long deadline = millis() + 300;
|
||||
if (_next_refresh < deadline) _next_refresh = deadline;
|
||||
} else {
|
||||
_next_refresh = 100; // trigger refresh immediately
|
||||
}
|
||||
#else
|
||||
_next_refresh = 100; // trigger refresh
|
||||
#endif
|
||||
} else if (_locked) {
|
||||
// Locked: eat all keys — wake window is set only when display first turns on
|
||||
_next_refresh = 0;
|
||||
|
||||
Reference in New Issue
Block a user