Files

75 lines
2.0 KiB
Python

"""Timeline: which scene draws which bars, plus the global beat-driven post and the stutter glitch."""
import math
import importlib
from anim import *
from engine import LW, LH
# (first bar, end bar, module, function)
TIMELINE = [
(0, 8, 'sc_open', 'cold_open'),
(8, 16, 'sc_open', 'your_app'),
(16, 32, 'sc_drop1', 'drop1'),
(32, 48, 'sc_how', 'how'),
(48, 56, 'sc_pipe', 'pipe'),
(56, 72, 'sc_modes', 'modes'),
(72, 80, 'sc_break', 'breakdown'),
(80, 88, 'sc_build3', 'checklist'),
(88, 104, 'sc_final', 'final_drop'),
(104, 200, 'sc_final', 'outro'),
]
_fns = {}
def _fn(mod, name):
key = (mod, name)
if key not in _fns:
try:
_fns[key] = getattr(importlib.import_module(mod), name)
except (ImportError, AttributeError):
_fns[key] = None
return _fns[key]
STUTTER = [t for t, _ in S.events('stutter')]
PATTERN = [2, 2, 1, 1, 0.5, 0.5, 0.5, 0.5, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25]
def stutter_remap(t):
"""Same slicing as the music's stutter: inside the beat, show the first 8th again and again."""
for ts in STUTTER:
if ts <= t < ts + S.BEAT:
u = t - ts
p = 0.0
for k, s in enumerate(PATTERN):
d = s * S.S16
if u < p + d:
return ts + (u - p), k
p += d
return t, -1
def draw(E, t):
t_src, sk = stutter_remap(t)
bar = t_src / S.BAR
entry = None
for e in TIMELINE:
if e[0] <= bar < e[1]:
entry = e
break
E.begin_sub(INK)
P = {}
if entry:
fn = _fn(entry[2], entry[3])
f = Frame(t_src, entry[0])
if fn:
P = fn(E, f) or {}
else:
E.rect(LW / 2, LH / 2, LW, LH, INK)
E.text(f'{entry[2]}.{entry[3]} bar {bar:.2f}', LW / 2, LH / 2, 60, BONE, font='mono')
E.flush()
if sk >= 0: # glitch dressing on the repeats
P = dict(P)
P['ca'] = P.get('ca', 0) + 3.0 + sk * 0.3
P['scan'] = 0.25
return P