87 lines
2.6 KiB
Python
87 lines
2.6 KiB
Python
import time
|
|
import math
|
|
import random
|
|
from imgui_bundle import imgui
|
|
|
|
class CRTFilter:
|
|
def __init__(self):
|
|
self.enabled = True
|
|
|
|
def render(self, width: float, height: float):
|
|
if not self.enabled:
|
|
return
|
|
draw_list = imgui.get_foreground_draw_list()
|
|
|
|
# 1. Enhanced Scanlines (Horizontal)
|
|
# Vary thickness and alpha for a more "analog" feel
|
|
for y in range(0, int(height), 2):
|
|
# Thicker/Darker every 4 pixels
|
|
is_major = (y % 4 == 0)
|
|
alpha = 0.08 if is_major else 0.04
|
|
thickness = 1.2 if is_major else 0.8
|
|
s_color = imgui.get_color_u32((0.0, 0.0, 0.0, alpha))
|
|
draw_list.add_line((0.0, float(y)), (float(width), float(y)), s_color, thickness)
|
|
|
|
# 2. Shadow Mask (Vertical)
|
|
# Simulates aperture grille / phosphor strips
|
|
m_color = imgui.get_color_u32((0.0, 0.0, 0.0, 0.05))
|
|
for x in range(0, int(width), 3):
|
|
draw_list.add_line((float(x), 0.0), (float(x), float(height)), m_color, 1.0)
|
|
|
|
# 3. Enhanced Curved Vignette / Tube Curvature
|
|
# Multiple rounded rectangles with increasing thickness and alpha
|
|
v_steps = 20
|
|
for i in range(v_steps):
|
|
# Exponential alpha for smoother falloff
|
|
alpha = (i / v_steps) ** 3.0 * 0.25
|
|
v_color = imgui.get_color_u32((0.0, 0.0, 0.0, alpha))
|
|
|
|
# Inset and rounding grow to simulate tube curvature
|
|
inset = (v_steps - i) * 4.5
|
|
rounding = 60.0 + (v_steps - i) * 8.0
|
|
thickness = 15.0
|
|
|
|
if width > inset * 2.0 and height > inset * 2.0:
|
|
draw_list.add_rect(
|
|
(inset, inset),
|
|
(width - inset, height - inset),
|
|
v_color,
|
|
rounding,
|
|
0,
|
|
thickness
|
|
)
|
|
|
|
# 4. Subtle Random Noise / Static
|
|
t = time.time()
|
|
for _ in range(40):
|
|
nx = random.uniform(0.0, width)
|
|
ny = random.uniform(0.0, height)
|
|
# Flickering noise
|
|
n_alpha = random.uniform(0.01, 0.04) * (0.8 + 0.2 * math.sin(t * 60.0))
|
|
n_color = imgui.get_color_u32((1.0, 1.0, 1.0, n_alpha))
|
|
draw_list.add_rect_filled((nx, ny), (nx + 1.2, ny + 1.2), n_color)
|
|
|
|
class StatusFlicker:
|
|
def get_alpha(self) -> float:
|
|
# Modulate between 0.7 and 1.0 using sin wave
|
|
return 0.85 + 0.15 * math.sin(time.time() * 20.0)
|
|
|
|
class AlertPulsing:
|
|
def __init__(self):
|
|
self.active = False
|
|
|
|
def update(self, status: str):
|
|
self.active = status.lower().startswith("error")
|
|
|
|
def render(self, width: float, height: float):
|
|
if not self.active:
|
|
return
|
|
draw_list = imgui.get_foreground_draw_list()
|
|
# sin(t) is between -1 and 1
|
|
# scale to 0 to 1: (sin(t) + 1) / 2
|
|
# multiply by (0.2 - 0.05) = 0.15 and add 0.05
|
|
alpha = 0.05 + 0.15 * ((math.sin(time.time() * 4.0) + 1.0) / 2.0)
|
|
color = imgui.get_color_u32((1.0, 0.0, 0.0, alpha))
|
|
draw_list.add_rect((0.0, 0.0), (width, height), color, 0.0, 0, 10.0)
|
|
|