feat(app): add demo mode with HUD effect plugin

- Add --demo flag that runs effect showcase with pygame display
- Add HUD effect plugin (effects_plugins/hud.py) that displays:
  - FPS and frame time
  - Current effect name with intensity bar
  - Pipeline order
- Demo mode cycles through noise, fade, glitch, firehose effects
- Ramps intensity 0→1→0 over 5 seconds per effect
This commit is contained in:
2026-03-16 00:53:13 -07:00
parent 0f2d8bf5c2
commit 3e9c1be6d2
3 changed files with 186 additions and 0 deletions

View File

@@ -351,7 +351,128 @@ def pick_effects_config():
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
def run_demo_mode():
"""Run demo mode - showcases effects with pygame display."""
import random
from engine import config
from engine.display import DisplayRegistry
from engine.effects import (
EffectContext,
PerformanceMonitor,
get_effect_chain,
get_registry,
set_monitor,
)
print(" \033[1;38;5;46mMAINLINE DEMO MODE\033[0m")
print(" \033[38;5;245mInitializing pygame display...\033[0m")
import effects_plugins
effects_plugins.discover_plugins()
registry = get_registry()
chain = get_effect_chain()
chain.set_order(["hud"])
monitor = PerformanceMonitor()
set_monitor(monitor)
chain._monitor = monitor
display = DisplayRegistry.create("pygame")
if not display:
print(" \033[38;5;196mFailed to create pygame display\033[0m")
sys.exit(1)
display.init(80, 24)
display.clear()
effects_to_demo = ["noise", "fade", "glitch", "firehose"]
w, h = 80, 24
base_buffer = []
for row in range(h):
line = ""
for col in range(w):
char = random.choice("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ")
line += char
base_buffer.append(line)
print(" \033[38;5;82mStarting effect demo...\033[0m")
print(" \033[38;5;245mPress Ctrl+C to exit\033[0m\n")
effect_idx = 0
effect_name = effects_to_demo[effect_idx]
effect_start_time = time.time()
current_intensity = 0.0
ramping_up = True
frame_count = 0
try:
while True:
elapsed = time.time() - effect_start_time
duration = config.DEMO_EFFECT_DURATION
if elapsed >= duration:
effect_idx = (effect_idx + 1) % len(effects_to_demo)
effect_name = effects_to_demo[effect_idx]
effect_start_time = time.time()
elapsed = 0
current_intensity = 0.0
ramping_up = True
progress = elapsed / duration
if ramping_up:
current_intensity = progress
if progress >= 1.0:
ramping_up = False
else:
current_intensity = 1.0 - progress
for effect in registry.list_all().values():
if effect.name == effect_name:
effect.config.enabled = True
effect.config.intensity = current_intensity
elif effect.name not in ("hud", effect_name):
effect.config.enabled = False
hud_effect = registry.get("hud")
if hud_effect:
hud_effect.config.params["display_effect"] = effect_name
hud_effect.config.params["display_intensity"] = current_intensity
ctx = EffectContext(
terminal_width=w,
terminal_height=h,
scroll_cam=0,
ticker_height=h,
mic_excess=0.0,
grad_offset=time.time() % 1.0,
frame_number=frame_count,
has_message=False,
items=[],
)
result = chain.process(base_buffer, ctx)
display.show(result)
frame_count += 1
time.sleep(1 / 60)
except KeyboardInterrupt:
pass
finally:
display.cleanup()
print("\n \033[38;5;245mDemo ended\033[0m")
def main():
if config.DEMO:
run_demo_mode()
return
atexit.register(lambda: print(CURSOR_ON, end="", flush=True))
def handle_sigint(*_):