add dvd
This commit is contained in:
@@ -23,3 +23,7 @@ MEDIUM_TEXT_WIDTH = 5
|
|||||||
PROGRAM2_TEXT_ITERATIONS = 5
|
PROGRAM2_TEXT_ITERATIONS = 5
|
||||||
PROGRAM2_TRIGGER_CHANCE = 25
|
PROGRAM2_TRIGGER_CHANCE = 25
|
||||||
PROGRAM2_VEHICLE_COUNT = 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_global_id = 0
|
||||||
scroll_node_active = False
|
scroll_node_active = False
|
||||||
|
|
||||||
|
top_text_node_global_id = 0
|
||||||
|
top_text_cycle_count = 0
|
||||||
|
|
||||||
program2_active = False
|
program2_active = False
|
||||||
bottom_text_iteration_count = 0
|
bottom_text_iteration_count = 0
|
||||||
program2_vehicles_spawned = 0
|
program2_vehicles_spawned = 0
|
||||||
@@ -89,6 +92,22 @@ program2_spacing_counter = 0
|
|||||||
program2_draw_col = 0
|
program2_draw_col = 0
|
||||||
program2_current_vehicle = None
|
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 = [
|
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,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]],
|
[[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():
|
def handle_program1():
|
||||||
global main_animation_started, scroll_node_active, scroll_node_global_id
|
global main_animation_started, scroll_node_active, scroll_node_global_id
|
||||||
global bottom_text_state, bottom_text_iteration_count, program2_active
|
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
|
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']:
|
if not s['program_top_text_enabled']:
|
||||||
for node in multi_color_text_nodes:
|
for node in multi_color_text_nodes:
|
||||||
if node['disappear_time'] != 0:
|
if node['disappear_time'] != 0:
|
||||||
@@ -303,12 +340,39 @@ def handle_program1():
|
|||||||
elif not main_animation_started:
|
elif not main_animation_started:
|
||||||
if not _is_node_existing(0) and not _is_node_existing(1):
|
if not _is_node_existing(0) and not _is_node_existing(1):
|
||||||
main_animation_started = True
|
main_animation_started = True
|
||||||
_add_multi_color_node(
|
node = _add_multi_color_node(
|
||||||
"Witamy w PTI",
|
"Witamy w PTI",
|
||||||
[(40, 40, 40, 0), (0, 0, 50, 9)],
|
[(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 not s['program_bottom_text_enabled']:
|
||||||
if scroll_node_active:
|
if scroll_node_active:
|
||||||
for node in text_nodes:
|
for node in text_nodes:
|
||||||
@@ -354,6 +418,49 @@ def handle_program1():
|
|||||||
bottom_text_state = (bottom_text_state + 1) % 4
|
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):
|
def draw_vehicle(index, pos_x, pos_y):
|
||||||
vr, vg, vb = config.VEHICLE_COLOR
|
vr, vg, vb = config.VEHICLE_COLOR
|
||||||
for row in range(4):
|
for row in range(4):
|
||||||
@@ -431,9 +538,21 @@ def loop():
|
|||||||
|
|
||||||
s = server.state
|
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)
|
low_level.fill_pixels(0, 0, config.DISPLAY_MAX_X, 7, 0, 0, 0)
|
||||||
handle_program1()
|
handle_program1()
|
||||||
|
|
||||||
|
if dvd_active:
|
||||||
|
strip.show()
|
||||||
|
_send_frame()
|
||||||
|
return
|
||||||
|
|
||||||
if s['program_top_text_enabled']:
|
if s['program_top_text_enabled']:
|
||||||
scroll_all_multi_color_texts(split_scroll_mode=True)
|
scroll_all_multi_color_texts(split_scroll_mode=True)
|
||||||
handle_multi_color_disappear_timers()
|
handle_multi_color_disappear_timers()
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ state = {
|
|||||||
'program_bottom_text_enabled': True,
|
'program_bottom_text_enabled': True,
|
||||||
'program_vehicles_enabled': True,
|
'program_vehicles_enabled': True,
|
||||||
'force_vehicles': False,
|
'force_vehicles': False,
|
||||||
|
'force_dvd': False,
|
||||||
}
|
}
|
||||||
_lock = threading.Lock()
|
_lock = threading.Lock()
|
||||||
|
|
||||||
@@ -71,6 +72,9 @@ INDEX_HTML = """<!DOCTYPE HTML><html>
|
|||||||
.btn-vehicles { background: #2a4a7f; color: #eee; }
|
.btn-vehicles { background: #2a4a7f; color: #eee; }
|
||||||
.btn-vehicles:hover { background: #3a5a9f; }
|
.btn-vehicles:hover { background: #3a5a9f; }
|
||||||
.btn-vehicles:active { background: #1a3a6f; }
|
.btn-vehicles:active { background: #1a3a6f; }
|
||||||
|
.btn-dvd { background: #6b2a7f; color: #eee; }
|
||||||
|
.btn-dvd:hover { background: #8b3a9f; }
|
||||||
|
.btn-dvd:active { background: #5b1a6f; }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -100,6 +104,7 @@ INDEX_HTML = """<!DOCTYPE HTML><html>
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-vehicles" onclick="forceVehicles()">Force Vehicles Next Cycle</button>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
@@ -142,6 +147,12 @@ INDEX_HTML = """<!DOCTYPE HTML><html>
|
|||||||
xhr.send();
|
xhr.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function forceDvd() {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("POST", "/force-dvd", true);
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
|
||||||
function toggle(program, enabled) {
|
function toggle(program, enabled) {
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
xhr.open("POST", "/toggle-program", true);
|
xhr.open("POST", "/toggle-program", true);
|
||||||
@@ -234,6 +245,13 @@ def handle_force_vehicles():
|
|||||||
return 'OK'
|
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'])
|
@app.route('/program-status', methods=['GET'])
|
||||||
def handle_status():
|
def handle_status():
|
||||||
with _lock:
|
with _lock:
|
||||||
|
|||||||
Reference in New Issue
Block a user