From e46ff02c0c95319912ed873ed0fea31aacee3a54 Mon Sep 17 00:00:00 2001 From: Me Here Date: Wed, 3 Jun 2026 14:52:04 -0500 Subject: [PATCH] pm-grid: swap X/Y tempo buttons + full-screen strobe on the downbeat MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Swap X/Y: X now tempo-up, Y tempo-down (match the physical Scroll Pack layout). - On the master lane's step 0 (the '1'), flash the entire 17x7 matrix at full brightness for 80ms — a visual downbeat strobe. Co-Authored-By: Claude Opus 4.8 (1M context) --- rust/pm-grid/src/main.rs | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/rust/pm-grid/src/main.rs b/rust/pm-grid/src/main.rs index 90ec697..684e89d 100644 --- a/rust/pm-grid/src/main.rs +++ b/rust/pm-grid/src/main.rs @@ -145,6 +145,12 @@ impl Matrix { } } + fn fill(&mut self, v: u8) { + for b in self.fb[1..].iter_mut() { + *b = v; + } + } + fn get(&self, x: i32, y: i32) -> u8 { if (0..17).contains(&x) && (0..7).contains(&y) { self.fb[1 + pixel_addr(x, y)] @@ -238,7 +244,8 @@ struct App { scroll_total: i32, beatflash: u8, beatflash_off: i64, - bpm_flash_off: i64, // while >0 and active, Grid/Pendulum briefly show the Ticker so nudges are visible + bpm_flash_off: i64, // while >0 and active, Grid/Pendulum briefly show the Ticker so nudges are visible + full_flash_off: i64, // strobe the WHOLE matrix bright on the downbeat ("the 1") } fn master_bar_ns(track: &track_format::Track, tempo: i64) -> i64 { @@ -294,6 +301,7 @@ impl App { beatflash: 0, beatflash_off: 0, bpm_flash_off: 0, + full_flash_off: 0, }; app.load(0, 0, now_ns); app @@ -405,6 +413,10 @@ impl App { while now_ns >= self.next[li] { self.step[li] = (self.step[li] + 1) % steps; if li == 0 { + if self.step[li] == 0 { + // the downbeat — strobe the entire matrix bright + self.full_flash_off = now_ns + 80_000_000; + } self.m_steps += 1; let bar = (self.m_steps - 1) / steps as i64; if bar != self.lastbar { @@ -458,6 +470,12 @@ fn lvl_bright(lvl: u8) -> u8 { // ============================== RENDERING ============================== fn render(m: &mut Matrix, app: &App, now_ns: i64) { + // downbeat strobe: the whole matrix at full brightness on "the 1" + if now_ns < app.full_flash_off { + m.fill(255); + m.show(); + return; + } m.clear(); // a tempo nudge briefly forces the Ticker (so X/Y is visible from Grid/Pendulum) let view = if app.view != View::Ticker && now_ns < app.bpm_flash_off { @@ -708,24 +726,24 @@ fn main() -> ! { app.next_track(now_ns); } } - // X: tempo down (tap -1, auto-repeat; -5 after 1.5s held) + // X: tempo up (tap +1, auto-repeat; +5 after 1.5s held) [X/Y swapped per hardware layout] if x && !px { held_x = us; nextrep_x = us + 350_000; - app.set_bpm(app.tempo - 1, now_ns); + app.set_bpm(app.tempo + 1, now_ns); } else if x && px && us >= nextrep_x { nextrep_x = us + 120_000; - let d = if us - held_x > 1_500_000 { -5 } else { -1 }; + let d = if us - held_x > 1_500_000 { 5 } else { 1 }; app.set_bpm(app.tempo + d, now_ns); } - // Y: tempo up + // Y: tempo down if y && !py { held_y = us; nextrep_y = us + 350_000; - app.set_bpm(app.tempo + 1, now_ns); + app.set_bpm(app.tempo - 1, now_ns); } else if y && py && us >= nextrep_y { nextrep_y = us + 120_000; - let d = if us - held_y > 1_500_000 { 5 } else { 1 }; + let d = if us - held_y > 1_500_000 { -5 } else { -1 }; app.set_bpm(app.tempo + d, now_ns); } pa = a;