Upgrade intro: matrix rain, typing effect, glitch transition, scan line
4-phase intro: matrix rain background, character-by-character boot typing with cursor, full-screen glitch transition, wave-based logo decrypt with random reveal order, horizontal scan line finale. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
316
systats.py
316
systats.py
@@ -1245,121 +1245,265 @@ def intro_splash(stdscr):
|
|||||||
"""Animated boot splash inspired by Spectre/Pulse."""
|
"""Animated boot splash inspired by Spectre/Pulse."""
|
||||||
curses.curs_set(0)
|
curses.curs_set(0)
|
||||||
stdscr.nodelay(False)
|
stdscr.nodelay(False)
|
||||||
stdscr.timeout(30)
|
stdscr.timeout(20)
|
||||||
init_colors()
|
init_colors()
|
||||||
|
|
||||||
h, w = stdscr.getmaxyx()
|
h, w = stdscr.getmaxyx()
|
||||||
if h < 15 or w < 60:
|
if h < 15 or w < 60:
|
||||||
return # skip intro on tiny terminals
|
return
|
||||||
|
|
||||||
# Gather system info for boot lines
|
# Gather system info
|
||||||
cores = psutil.cpu_count()
|
cores = psutil.cpu_count()
|
||||||
|
cores_phys = psutil.cpu_count(logical=False)
|
||||||
|
mem = psutil.virtual_memory()
|
||||||
|
mem_str = f"{mem.total / (1024**3):.0f}GB"
|
||||||
gpu_str = "NVIDIA" if NVIDIA_AVAILABLE else ("AMD" if os.path.exists(AMD_GPU_PATH) else "NONE")
|
gpu_str = "NVIDIA" if NVIDIA_AVAILABLE else ("AMD" if os.path.exists(AMD_GPU_PATH) else "NONE")
|
||||||
|
hostname = os.uname().nodename
|
||||||
try:
|
try:
|
||||||
temps_count = sum(len(v) for v in psutil.sensors_temperatures().values())
|
temps_count = sum(len(v) for v in psutil.sensors_temperatures().values())
|
||||||
temps_str = f"{temps_count} sensors"
|
temps_str = f"{temps_count} sensors"
|
||||||
except Exception:
|
except Exception:
|
||||||
temps_str = "N/A"
|
temps_str = "N/A"
|
||||||
|
try:
|
||||||
|
parts = len(psutil.disk_partitions(all=False))
|
||||||
|
disk_str = f"{parts} volumes"
|
||||||
|
except Exception:
|
||||||
|
disk_str = "N/A"
|
||||||
|
|
||||||
glitch_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@#$%&*!?<>/\\|{}[]~^"
|
glitch_chars = "@#$%&*!?<>/\\|{}[]~^=+:;0123456789"
|
||||||
|
|
||||||
# Phase 1: Boot lines
|
# ── Phase 1: Matrix rain background ──
|
||||||
boot_start = time.time()
|
rain_cols = [_random.randint(-h, 0) for _ in range(w)]
|
||||||
shown_lines = []
|
for frame in range(25):
|
||||||
|
|
||||||
for line_tpl, delay in BOOT_LINES:
|
|
||||||
line = line_tpl.format(ver=VERSION, cores=cores, gpu=gpu_str, temps=temps_str)
|
|
||||||
target_time = boot_start + delay
|
|
||||||
while time.time() < target_time:
|
|
||||||
stdscr.getch() # drain input
|
|
||||||
time.sleep(0.02)
|
|
||||||
|
|
||||||
shown_lines.append(line)
|
|
||||||
stdscr.erase()
|
stdscr.erase()
|
||||||
start_y = (h - len(BOOT_LINES) - len(LOGO_ART) - 4) // 2
|
for col in range(w):
|
||||||
for i, sl in enumerate(shown_lines):
|
rain_cols[col] += 1
|
||||||
col = C_LOW if "OK" in sl or "READY" in sl or "ONLINE" in sl or "detected" in sl else C_DIM
|
if rain_cols[col] > h + 5:
|
||||||
if "Electric Entropy" in sl:
|
rain_cols[col] = _random.randint(-5, 0)
|
||||||
col = C_ACCENT
|
for row_off in range(4):
|
||||||
safe_addstr(stdscr, start_y + i, (w - len(sl)) // 2, sl,
|
ry = rain_cols[col] - row_off
|
||||||
curses.color_pair(col))
|
if 0 <= ry < h:
|
||||||
|
ch = _random.choice(glitch_chars)
|
||||||
|
brightness = C_LOW if row_off == 0 else C_DIM
|
||||||
|
if row_off == 0:
|
||||||
|
brightness = C_LOW
|
||||||
|
try:
|
||||||
|
stdscr.addch(ry, col, ch,
|
||||||
|
curses.color_pair(brightness) | (curses.A_BOLD if row_off == 0 else curses.A_DIM))
|
||||||
|
except curses.error:
|
||||||
|
pass
|
||||||
stdscr.refresh()
|
stdscr.refresh()
|
||||||
|
stdscr.getch()
|
||||||
|
time.sleep(0.04)
|
||||||
|
|
||||||
time.sleep(0.3)
|
# ── Phase 2: Boot sequence with typing effect ──
|
||||||
|
boot_lines = [
|
||||||
|
(f"> SYSTATS v{VERSION} // Electric Entropy Lab", C_ACCENT),
|
||||||
|
(f"> host: {hostname}", C_DIM),
|
||||||
|
(f"> scanning CPU... {cores_phys}C/{cores}T detected", C_LOW),
|
||||||
|
(f"> memory probe... {mem_str} OK", C_LOW),
|
||||||
|
(f"> GPU subsystem... {gpu_str}", C_LOW),
|
||||||
|
(f"> thermal sensors... {temps_str}", C_LOW),
|
||||||
|
(f"> disk volumes... {disk_str}", C_LOW),
|
||||||
|
(f"> network interfaces... ONLINE", C_LOW),
|
||||||
|
(f"> process table... READY", C_LOW),
|
||||||
|
("> all systems nominal", C_TITLE),
|
||||||
|
]
|
||||||
|
|
||||||
# Phase 2: Decrypt logo animation
|
start_y = (h - len(boot_lines)) // 2 - 3
|
||||||
logo_start_y = (h - len(LOGO_ART)) // 2
|
typed_lines = []
|
||||||
# Find max logo width
|
|
||||||
max_logo_w = max(len(l) for l in LOGO_ART)
|
|
||||||
|
|
||||||
# Initialize with random chars for non-space positions
|
for line_text, line_col in boot_lines:
|
||||||
logo_state = []
|
typed_lines.append((line_text, line_col))
|
||||||
for line in LOGO_ART:
|
|
||||||
row = []
|
|
||||||
for ch in line:
|
|
||||||
if ch == ' ' or ch == '\u2500':
|
|
||||||
row.append(ch)
|
|
||||||
else:
|
|
||||||
row.append(_random.choice(glitch_chars))
|
|
||||||
logo_state.append(row)
|
|
||||||
|
|
||||||
# Decrypt columns left to right
|
# Type this line character by character
|
||||||
total_cols = max_logo_w
|
for char_idx in range(len(line_text) + 1):
|
||||||
decrypt_steps = 20 # frames for full decrypt
|
stdscr.erase()
|
||||||
chars_per_step = max(1, total_cols // decrypt_steps)
|
|
||||||
|
|
||||||
revealed = [set() for _ in LOGO_ART]
|
# Fading rain in background
|
||||||
|
for col in range(0, w, 3):
|
||||||
for step in range(decrypt_steps + 5):
|
ry = _random.randint(0, h - 1)
|
||||||
stdscr.erase()
|
ch = _random.choice(glitch_chars)
|
||||||
|
|
||||||
# Reveal columns up to this step
|
|
||||||
reveal_up_to = min(step * chars_per_step, total_cols)
|
|
||||||
|
|
||||||
for row_idx, line in enumerate(LOGO_ART):
|
|
||||||
lx = (w - max_logo_w) // 2
|
|
||||||
for col_idx, ch in enumerate(line):
|
|
||||||
if col_idx < reveal_up_to:
|
|
||||||
revealed[row_idx].add(col_idx)
|
|
||||||
|
|
||||||
display = []
|
|
||||||
for col_idx in range(len(line)):
|
|
||||||
if col_idx in revealed[row_idx]:
|
|
||||||
display.append(line[col_idx])
|
|
||||||
elif line[col_idx] == ' ':
|
|
||||||
display.append(' ')
|
|
||||||
else:
|
|
||||||
display.append(_random.choice(glitch_chars))
|
|
||||||
|
|
||||||
text = "".join(display)
|
|
||||||
# Color: revealed chars in cyan, glitch in dim
|
|
||||||
for col_idx, ch in enumerate(text):
|
|
||||||
if col_idx >= w - lx - 1:
|
|
||||||
break
|
|
||||||
if ch == ' ':
|
|
||||||
continue
|
|
||||||
if col_idx in revealed[row_idx]:
|
|
||||||
attr = curses.color_pair(C_TITLE) | curses.A_BOLD
|
|
||||||
else:
|
|
||||||
attr = curses.color_pair(C_DIM) | curses.A_DIM
|
|
||||||
try:
|
try:
|
||||||
stdscr.addch(logo_start_y + row_idx, lx + col_idx, ch, attr)
|
stdscr.addch(ry, col, ch, curses.color_pair(C_DIM) | curses.A_DIM)
|
||||||
except curses.error:
|
except curses.error:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Version + brand below logo
|
# Draw all completed lines
|
||||||
if step > decrypt_steps - 3:
|
for i, (lt, lc) in enumerate(typed_lines[:-1]):
|
||||||
ver_str = f"v{VERSION} // Electric Entropy Lab"
|
safe_addstr(stdscr, start_y + i, 2, lt,
|
||||||
safe_addstr(stdscr, logo_start_y + len(LOGO_ART) + 1, (w - len(ver_str)) // 2,
|
curses.color_pair(lc))
|
||||||
ver_str, curses.color_pair(C_ACCENT) | curses.A_BOLD)
|
|
||||||
|
|
||||||
|
# Draw current line being typed
|
||||||
|
current_y = start_y + len(typed_lines) - 1
|
||||||
|
partial = line_text[:char_idx]
|
||||||
|
safe_addstr(stdscr, current_y, 2, partial, curses.color_pair(line_col))
|
||||||
|
|
||||||
|
# Blinking cursor
|
||||||
|
if char_idx < len(line_text):
|
||||||
|
cursor_x = 2 + char_idx
|
||||||
|
if cursor_x < w:
|
||||||
|
try:
|
||||||
|
stdscr.addch(current_y, cursor_x, "\u2588",
|
||||||
|
curses.color_pair(C_TITLE) | curses.A_BOLD)
|
||||||
|
except curses.error:
|
||||||
|
pass
|
||||||
|
|
||||||
|
stdscr.refresh()
|
||||||
|
stdscr.getch()
|
||||||
|
|
||||||
|
# Variable typing speed
|
||||||
|
if line_text[char_idx - 1:char_idx] in ".:":
|
||||||
|
time.sleep(0.08)
|
||||||
|
elif _random.random() < 0.15:
|
||||||
|
time.sleep(0.06)
|
||||||
|
else:
|
||||||
|
time.sleep(0.015)
|
||||||
|
|
||||||
|
time.sleep(0.15)
|
||||||
|
|
||||||
|
time.sleep(0.4)
|
||||||
|
|
||||||
|
# ── Phase 3: Glitch transition ──
|
||||||
|
for frame in range(6):
|
||||||
|
stdscr.erase()
|
||||||
|
for row in range(h):
|
||||||
|
offset = _random.randint(-3, 3)
|
||||||
|
for col in range(w):
|
||||||
|
try:
|
||||||
|
stdscr.addch(row, col, _random.choice(glitch_chars),
|
||||||
|
curses.color_pair(_random.choice([C_TITLE, C_LOW, C_DIM])) | curses.A_DIM)
|
||||||
|
except curses.error:
|
||||||
|
pass
|
||||||
stdscr.refresh()
|
stdscr.refresh()
|
||||||
stdscr.getch() # drain
|
time.sleep(0.04)
|
||||||
time.sleep(0.05)
|
|
||||||
|
|
||||||
time.sleep(0.5)
|
# ── Phase 4: Logo decrypt ──
|
||||||
|
max_logo_w = max(len(l) for l in LOGO_ART)
|
||||||
|
logo_y = (h - len(LOGO_ART)) // 2 - 1
|
||||||
|
logo_x = (w - max_logo_w) // 2
|
||||||
|
|
||||||
# Phase 3: Flash and clear
|
# Build target grid and scrambled state
|
||||||
|
target = []
|
||||||
|
scrambled = []
|
||||||
|
for line in LOGO_ART:
|
||||||
|
t_row = list(line.ljust(max_logo_w))
|
||||||
|
s_row = []
|
||||||
|
for ch in t_row:
|
||||||
|
if ch == ' ':
|
||||||
|
s_row.append(' ')
|
||||||
|
else:
|
||||||
|
s_row.append(_random.choice(glitch_chars))
|
||||||
|
target.append(t_row)
|
||||||
|
scrambled.append(s_row)
|
||||||
|
|
||||||
|
# Reveal each character with multiple scramble frames before settling
|
||||||
|
total_chars = max_logo_w
|
||||||
|
reveal_order = list(range(total_chars))
|
||||||
|
_random.shuffle(reveal_order)
|
||||||
|
|
||||||
|
# Group into waves
|
||||||
|
wave_size = max(1, total_chars // 12)
|
||||||
|
waves = [reveal_order[i:i + wave_size] for i in range(0, len(reveal_order), wave_size)]
|
||||||
|
|
||||||
|
revealed_cols = set()
|
||||||
|
|
||||||
|
for wave_idx, wave in enumerate(waves):
|
||||||
|
# Several scramble frames per wave
|
||||||
|
for scramble_frame in range(4):
|
||||||
|
stdscr.erase()
|
||||||
|
|
||||||
|
for row_idx in range(len(LOGO_ART)):
|
||||||
|
for col_idx in range(max_logo_w):
|
||||||
|
if logo_x + col_idx >= w - 1:
|
||||||
|
break
|
||||||
|
if col_idx in revealed_cols:
|
||||||
|
ch = target[row_idx][col_idx]
|
||||||
|
if ch != ' ':
|
||||||
|
try:
|
||||||
|
stdscr.addch(logo_y + row_idx, logo_x + col_idx, ch,
|
||||||
|
curses.color_pair(C_TITLE) | curses.A_BOLD)
|
||||||
|
except curses.error:
|
||||||
|
pass
|
||||||
|
elif col_idx in wave and scramble_frame >= 2:
|
||||||
|
ch = target[row_idx][col_idx]
|
||||||
|
if ch != ' ':
|
||||||
|
try:
|
||||||
|
stdscr.addch(logo_y + row_idx, logo_x + col_idx, ch,
|
||||||
|
curses.color_pair(C_TITLE) | curses.A_BOLD)
|
||||||
|
except curses.error:
|
||||||
|
pass
|
||||||
|
elif target[row_idx][col_idx] != ' ':
|
||||||
|
ch = _random.choice(glitch_chars)
|
||||||
|
try:
|
||||||
|
stdscr.addch(logo_y + row_idx, logo_x + col_idx, ch,
|
||||||
|
curses.color_pair(C_LOW if col_idx in wave else C_DIM) | curses.A_DIM)
|
||||||
|
except curses.error:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Show version once past halfway
|
||||||
|
if wave_idx > len(waves) // 2:
|
||||||
|
ver_str = f"v{VERSION}"
|
||||||
|
brand_str = "Electric Entropy Lab"
|
||||||
|
safe_addstr(stdscr, logo_y + len(LOGO_ART) + 1, (w - len(ver_str)) // 2,
|
||||||
|
ver_str, curses.color_pair(C_ACCENT) | curses.A_BOLD)
|
||||||
|
safe_addstr(stdscr, logo_y + len(LOGO_ART) + 2, (w - len(brand_str)) // 2,
|
||||||
|
brand_str, curses.color_pair(C_DIM))
|
||||||
|
|
||||||
|
stdscr.refresh()
|
||||||
|
stdscr.getch()
|
||||||
|
time.sleep(0.035)
|
||||||
|
|
||||||
|
revealed_cols.update(wave)
|
||||||
|
|
||||||
|
# Final clean frame
|
||||||
|
stdscr.erase()
|
||||||
|
for row_idx, line in enumerate(LOGO_ART):
|
||||||
|
safe_addstr(stdscr, logo_y + row_idx, logo_x, line,
|
||||||
|
curses.color_pair(C_TITLE) | curses.A_BOLD)
|
||||||
|
ver_str = f"v{VERSION}"
|
||||||
|
brand_str = "Electric Entropy Lab"
|
||||||
|
lang_str = f"[{current_lang.upper()}]"
|
||||||
|
safe_addstr(stdscr, logo_y + len(LOGO_ART) + 1, (w - len(ver_str)) // 2,
|
||||||
|
ver_str, curses.color_pair(C_ACCENT) | curses.A_BOLD)
|
||||||
|
safe_addstr(stdscr, logo_y + len(LOGO_ART) + 2, (w - len(brand_str)) // 2,
|
||||||
|
brand_str, curses.color_pair(C_DIM))
|
||||||
|
safe_addstr(stdscr, logo_y + len(LOGO_ART) + 3, (w - len(lang_str)) // 2,
|
||||||
|
lang_str, curses.color_pair(C_DIM))
|
||||||
|
|
||||||
|
# Scanning line effect
|
||||||
|
for scan_y in range(h):
|
||||||
|
try:
|
||||||
|
for sx in range(w):
|
||||||
|
stdscr.addch(scan_y, sx, ' ', curses.color_pair(C_HEADER))
|
||||||
|
except curses.error:
|
||||||
|
pass
|
||||||
|
stdscr.refresh()
|
||||||
|
time.sleep(0.008)
|
||||||
|
|
||||||
|
# Restore the line
|
||||||
|
if logo_y <= scan_y < logo_y + len(LOGO_ART):
|
||||||
|
row_idx = scan_y - logo_y
|
||||||
|
safe_addstr(stdscr, scan_y, logo_x, LOGO_ART[row_idx],
|
||||||
|
curses.color_pair(C_TITLE) | curses.A_BOLD)
|
||||||
|
elif scan_y == logo_y + len(LOGO_ART) + 1:
|
||||||
|
safe_addstr(stdscr, scan_y, (w - len(ver_str)) // 2, ver_str,
|
||||||
|
curses.color_pair(C_ACCENT) | curses.A_BOLD)
|
||||||
|
elif scan_y == logo_y + len(LOGO_ART) + 2:
|
||||||
|
safe_addstr(stdscr, scan_y, (w - len(brand_str)) // 2, brand_str,
|
||||||
|
curses.color_pair(C_DIM))
|
||||||
|
elif scan_y == logo_y + len(LOGO_ART) + 3:
|
||||||
|
safe_addstr(stdscr, scan_y, (w - len(lang_str)) // 2, lang_str,
|
||||||
|
curses.color_pair(C_DIM))
|
||||||
|
else:
|
||||||
|
for sx in range(w):
|
||||||
|
try:
|
||||||
|
stdscr.addch(scan_y, sx, ' ')
|
||||||
|
except curses.error:
|
||||||
|
pass
|
||||||
|
stdscr.refresh()
|
||||||
|
|
||||||
|
time.sleep(0.6)
|
||||||
stdscr.erase()
|
stdscr.erase()
|
||||||
stdscr.refresh()
|
stdscr.refresh()
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|||||||
Reference in New Issue
Block a user