add dvd
This commit is contained in:
@@ -23,3 +23,7 @@ MEDIUM_TEXT_WIDTH = 5
|
||||
PROGRAM2_TEXT_ITERATIONS = 5
|
||||
PROGRAM2_TRIGGER_CHANCE = 25
|
||||
PROGRAM2_VEHICLE_COUNT = 25
|
||||
|
||||
DVD_TOP_TEXT_CYCLES = 3
|
||||
DVD_TRIGGER_CHANCE = 15
|
||||
DVD_ITERATIONS = 200
|
||||
|
||||
+121
-2
@@ -79,6 +79,9 @@ bottom_text_state = 0
|
||||
scroll_node_global_id = 0
|
||||
scroll_node_active = False
|
||||
|
||||
top_text_node_global_id = 0
|
||||
top_text_cycle_count = 0
|
||||
|
||||
program2_active = False
|
||||
bottom_text_iteration_count = 0
|
||||
program2_vehicles_spawned = 0
|
||||
@@ -89,6 +92,22 @@ program2_spacing_counter = 0
|
||||
program2_draw_col = 0
|
||||
program2_current_vehicle = None
|
||||
|
||||
dvd_pending = False
|
||||
dvd_active = False
|
||||
dvd_x = 0
|
||||
dvd_y = 0
|
||||
dvd_dx = 1
|
||||
dvd_dy = 1
|
||||
dvd_iteration = 0
|
||||
dvd_move_counter = 0
|
||||
|
||||
DVD_TEXT = "PTI"
|
||||
DVD_TEXT_W = 17 # 3 chars * 5px + 2 gaps
|
||||
DVD_TEXT_H = 7
|
||||
DVD_MAX_X = config.DISPLAY_MAX_X - DVD_TEXT_W + 1 # 31
|
||||
DVD_MAX_Y = config.DISPLAY_MAX_Y - DVD_TEXT_H + 1 # 9
|
||||
DVD_COLOR = (0, 0, 50)
|
||||
|
||||
VEHICLES = [
|
||||
[[0,0,0,0,0,0,0,0],[0,0,1,1,1,1,1,0],[1,1,1,1,1,1,1,1],[0,1,0,0,0,0,1,0]],
|
||||
[[0,0,1,1,0,0,0,0],[0,1,1,1,0,0,0,0],[1,1,1,1,1,1,1,1],[0,1,0,0,0,0,1,0]],
|
||||
@@ -292,9 +311,27 @@ def handle_multi_color_disappear_timers():
|
||||
def handle_program1():
|
||||
global main_animation_started, scroll_node_active, scroll_node_global_id
|
||||
global bottom_text_state, bottom_text_iteration_count, program2_active
|
||||
global top_text_node_global_id, top_text_cycle_count
|
||||
global dvd_pending, dvd_active
|
||||
|
||||
s = server.state
|
||||
|
||||
# --- DVD active: handled entirely in loop() ---
|
||||
if dvd_active:
|
||||
return
|
||||
|
||||
# --- DVD pending: wait for bottom area to clear ---
|
||||
if dvd_pending:
|
||||
if scroll_node_active and not _is_node_existing(scroll_node_global_id):
|
||||
scroll_node_active = False
|
||||
if not scroll_node_active and not program2_active:
|
||||
dvd_pending = False
|
||||
dvd_active = True
|
||||
reset_dvd()
|
||||
low_level.fill_pixels(0, 0, config.DISPLAY_MAX_X, config.DISPLAY_MAX_Y, 0, 0, 0)
|
||||
return
|
||||
|
||||
# --- Top text management ---
|
||||
if not s['program_top_text_enabled']:
|
||||
for node in multi_color_text_nodes:
|
||||
if node['disappear_time'] != 0:
|
||||
@@ -303,12 +340,39 @@ def handle_program1():
|
||||
elif not main_animation_started:
|
||||
if not _is_node_existing(0) and not _is_node_existing(1):
|
||||
main_animation_started = True
|
||||
_add_multi_color_node(
|
||||
node = _add_multi_color_node(
|
||||
"Witamy w PTI",
|
||||
[(40, 40, 40, 0), (0, 0, 50, 9)],
|
||||
0, 0, 3, True, True, -1, True
|
||||
0, 0, 3, True, True, -1, False
|
||||
)
|
||||
if node:
|
||||
top_text_node_global_id = node['global_id']
|
||||
elif not _is_node_existing(top_text_node_global_id):
|
||||
# Top text cycle ended
|
||||
top_text_cycle_count += 1
|
||||
|
||||
force_dvd = s.get('force_dvd', False)
|
||||
if force_dvd:
|
||||
with server._lock:
|
||||
server.state['force_dvd'] = False
|
||||
|
||||
if force_dvd or (top_text_cycle_count >= config.DVD_TOP_TEXT_CYCLES
|
||||
and random.randint(0, 99) < config.DVD_TRIGGER_CHANCE):
|
||||
top_text_cycle_count = 0
|
||||
dvd_pending = True
|
||||
main_animation_started = False
|
||||
return
|
||||
|
||||
# Re-add top text from right edge
|
||||
node = _add_multi_color_node(
|
||||
"Witamy w PTI",
|
||||
[(40, 40, 40, 0), (0, 0, 50, 9)],
|
||||
config.DISPLAY_MAX_X, 0, 3, True, True, -1, False
|
||||
)
|
||||
if node:
|
||||
top_text_node_global_id = node['global_id']
|
||||
|
||||
# --- Bottom text management ---
|
||||
if not s['program_bottom_text_enabled']:
|
||||
if scroll_node_active:
|
||||
for node in text_nodes:
|
||||
@@ -354,6 +418,49 @@ def handle_program1():
|
||||
bottom_text_state = (bottom_text_state + 1) % 4
|
||||
|
||||
|
||||
def reset_dvd():
|
||||
global dvd_x, dvd_y, dvd_dx, dvd_dy, dvd_iteration, dvd_move_counter
|
||||
dvd_x = random.randint(0, DVD_MAX_X)
|
||||
dvd_y = random.randint(0, DVD_MAX_Y)
|
||||
dvd_dx = random.choice([-1, 1])
|
||||
dvd_dy = random.choice([-1, 1])
|
||||
dvd_iteration = 0
|
||||
dvd_move_counter = 0
|
||||
|
||||
|
||||
def handle_dvd():
|
||||
global dvd_x, dvd_y, dvd_dx, dvd_dy, dvd_iteration, dvd_move_counter
|
||||
global dvd_active, main_animation_started
|
||||
|
||||
if dvd_iteration >= config.DVD_ITERATIONS:
|
||||
dvd_active = False
|
||||
main_animation_started = False
|
||||
return
|
||||
|
||||
dvd_iteration += 1
|
||||
|
||||
dvd_move_counter += 1
|
||||
if dvd_move_counter >= 2:
|
||||
dvd_move_counter = 0
|
||||
|
||||
new_x = dvd_x + dvd_dx
|
||||
new_y = dvd_y + dvd_dy
|
||||
|
||||
if new_x < 0 or new_x > DVD_MAX_X:
|
||||
dvd_dx = -dvd_dx
|
||||
new_x = dvd_x + dvd_dx
|
||||
if new_y < 0 or new_y > DVD_MAX_Y:
|
||||
dvd_dy = -dvd_dy
|
||||
new_y = dvd_y + dvd_dy
|
||||
|
||||
dvd_x = new_x
|
||||
dvd_y = new_y
|
||||
|
||||
cursor = {'x': dvd_x, 'y': dvd_y}
|
||||
for ch in DVD_TEXT:
|
||||
_draw_char(ch, config.SMALL_TEXT_HEIGHT, config.SMALL_TEXT_WIDTH, *DVD_COLOR, cursor)
|
||||
|
||||
|
||||
def draw_vehicle(index, pos_x, pos_y):
|
||||
vr, vg, vb = config.VEHICLE_COLOR
|
||||
for row in range(4):
|
||||
@@ -431,9 +538,21 @@ def loop():
|
||||
|
||||
s = server.state
|
||||
|
||||
if dvd_active:
|
||||
low_level.fill_pixels(0, 0, config.DISPLAY_MAX_X, config.DISPLAY_MAX_Y, 0, 0, 0)
|
||||
handle_dvd()
|
||||
strip.show()
|
||||
_send_frame()
|
||||
return
|
||||
|
||||
low_level.fill_pixels(0, 0, config.DISPLAY_MAX_X, 7, 0, 0, 0)
|
||||
handle_program1()
|
||||
|
||||
if dvd_active:
|
||||
strip.show()
|
||||
_send_frame()
|
||||
return
|
||||
|
||||
if s['program_top_text_enabled']:
|
||||
scroll_all_multi_color_texts(split_scroll_mode=True)
|
||||
handle_multi_color_disappear_timers()
|
||||
|
||||
@@ -19,6 +19,7 @@ state = {
|
||||
'program_bottom_text_enabled': True,
|
||||
'program_vehicles_enabled': True,
|
||||
'force_vehicles': False,
|
||||
'force_dvd': False,
|
||||
}
|
||||
_lock = threading.Lock()
|
||||
|
||||
@@ -71,6 +72,9 @@ INDEX_HTML = """<!DOCTYPE HTML><html>
|
||||
.btn-vehicles { background: #2a4a7f; color: #eee; }
|
||||
.btn-vehicles:hover { background: #3a5a9f; }
|
||||
.btn-vehicles:active { background: #1a3a6f; }
|
||||
.btn-dvd { background: #6b2a7f; color: #eee; }
|
||||
.btn-dvd:hover { background: #8b3a9f; }
|
||||
.btn-dvd:active { background: #5b1a6f; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -100,6 +104,7 @@ INDEX_HTML = """<!DOCTYPE HTML><html>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-vehicles" onclick="forceVehicles()">Force Vehicles Next Cycle</button>
|
||||
<button class="btn btn-dvd" onclick="forceDvd()">Force DVD Next Cycle</button>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
@@ -142,6 +147,12 @@ INDEX_HTML = """<!DOCTYPE HTML><html>
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
function forceDvd() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "/force-dvd", true);
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
function toggle(program, enabled) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "/toggle-program", true);
|
||||
@@ -234,6 +245,13 @@ def handle_force_vehicles():
|
||||
return 'OK'
|
||||
|
||||
|
||||
@app.route('/force-dvd', methods=['POST'])
|
||||
def handle_force_dvd():
|
||||
with _lock:
|
||||
state['force_dvd'] = True
|
||||
return 'OK'
|
||||
|
||||
|
||||
@app.route('/program-status', methods=['GET'])
|
||||
def handle_status():
|
||||
with _lock:
|
||||
|
||||
Reference in New Issue
Block a user