pm-grid Ticker: top-row beat strip + shift name down a row
Free the top row for a beat indicator: faint ticks at each beat (every sub steps) across cols 0-10 with a bright playhead at the master lane's current step. The scrolling name moves down to rows 2-6 (row 1 = separator). BPM block unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e46ff02c0c
commit
512890baa2
2 changed files with 26 additions and 10 deletions
|
|
@ -160,11 +160,12 @@ CircuitPython `Matrix`; per-pixel I²C is too slow to animate), the **polymeter
|
||||||
`track-format::schedule::lane_durs` (the cross-impl contract) with per-lane step clocks + ramp +
|
`track-format::schedule::lane_durs` (the cross-impl contract) with per-lane step clocks + ramp +
|
||||||
gap-trainer, **4-button input** (A tap=play/stop, hold=cycle view; B tap=next track, hold=next set
|
gap-trainer, **4-button input** (A tap=play/stop, hold=cycle view; B tap=next track, hold=next set
|
||||||
list; X/Y=tempo ∓ with auto-repeat), the **built-in set lists**, and three LED views:
|
list; X/Y=tempo ∓ with auto-repeat), the **built-in set lists**, and three LED views:
|
||||||
- **Ticker** (default): track name infinite-scrolls across the left (cols 0–10, full height); BPM is
|
- **Ticker** (default): a **beat strip** on the top row (cols 0–10) — faint ticks at each beat + a
|
||||||
pinned right, **rotated 90° CCW** — a vertical hundreds **dot-bar** in col 11 (one dot per 100) +
|
bright playhead at the master lane's current step; the track name infinite-scrolls below it (cols
|
||||||
the last two digits rotated into cols 12–16 (tens bottom, units top). So `130` → 1 dot + rotated
|
0–10, rows 2–6); BPM is pinned right, **rotated 90° CCW** — a vertical hundreds **dot-bar** in col
|
||||||
"30". This is the user-designed landscape readout. Rotation/geometry verified off-bench with an
|
11 (one dot per 100) + the last two digits rotated into cols 12–16 (tens bottom, units top). So
|
||||||
ASCII replica of `draw_ticker`.
|
`130` → 1 dot + rotated "30". This is the user-designed landscape readout. Layout/rotation verified
|
||||||
|
off-bench with an ASCII replica of `draw_ticker`. Whole matrix strobes white on the downbeat.
|
||||||
- **Grid** (lanes×steps + playhead) and **Pendulum** (bouncing arm + beat ticks) — ports of
|
- **Grid** (lanes×steps + playhead) and **Pendulum** (bouncing arm + beat ticks) — ports of
|
||||||
`_render_grid` / `_render_pendulum`.
|
`_render_grid` / `_render_pendulum`.
|
||||||
Boot splash scrolls "PM-G1 GRID" (liveness + pixel-map check).
|
Boot splash scrolls "PM-G1 GRID" (liveness + pixel-map check).
|
||||||
|
|
|
||||||
|
|
@ -491,11 +491,26 @@ fn render<I: I2c>(m: &mut Matrix<I>, app: &App, now_ns: i64) {
|
||||||
m.show();
|
m.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ticker: track name infinite-scrolls across the left (cols 0..=10, full height), BPM is pinned to
|
/// Ticker: a beat strip runs along the top row (cols 0..=10); the track name infinite-scrolls below
|
||||||
/// the right rotated 90° CCW — a vertical "hundreds dot-bar" in col 11 (one dot per 100) plus the
|
/// it (cols 0..=10, rows 2..=6); BPM is pinned to the right rotated 90° CCW — a vertical "hundreds
|
||||||
/// last two digits rotated into cols 12..=16 (tens at the bottom, units on top; reads bottom→top).
|
/// dot-bar" in col 11 (one dot per 100) plus the last two digits rotated into cols 12..=16 (tens at
|
||||||
|
/// the bottom, units on top; reads bottom→top).
|
||||||
fn draw_ticker<I: I2c>(m: &mut Matrix<I>, app: &App) {
|
fn draw_ticker<I: I2c>(m: &mut Matrix<I>, app: &App) {
|
||||||
// scrolling name on rows 1..=5
|
// top-row beat strip (cols 0..=10): faint marks at each beat (every `sub` steps), a bright
|
||||||
|
// playhead at the master lane's current step — spread across the full name-region width.
|
||||||
|
if let Some(master) = app.track.lanes.first() {
|
||||||
|
let steps = master.levels.len().max(1) as i32;
|
||||||
|
let sub = master.sub.max(1) as i32;
|
||||||
|
for s in 0..steps {
|
||||||
|
if s % sub == 0 {
|
||||||
|
m.set_max(s * 11 / steps, 0, 24); // beat tick
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if app.playing && app.step[0] >= 0 {
|
||||||
|
m.set(app.step[0] * 11 / steps, 0, 255); // live playhead
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// scrolling name on rows 2..=6 (shifted down one to clear the beat strip)
|
||||||
let total = app.scroll_total.max(1);
|
let total = app.scroll_total.max(1);
|
||||||
for sx in 0..=10i32 {
|
for sx in 0..=10i32 {
|
||||||
let i = ((app.scroll_off + sx) % total + total) % total;
|
let i = ((app.scroll_off + sx) % total + total) % total;
|
||||||
|
|
@ -506,7 +521,7 @@ fn draw_ticker<I: I2c>(m: &mut Matrix<I>, app: &App) {
|
||||||
};
|
};
|
||||||
for r in 0..5i32 {
|
for r in 0..5i32 {
|
||||||
if colbits & (1 << r) != 0 {
|
if colbits & (1 << r) != 0 {
|
||||||
m.set(sx, 1 + r, NAME_BRIGHT);
|
m.set(sx, 2 + r, NAME_BRIGHT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue