240 int term_width = (int)GET_OPTION(width);
241 int term_height = (int)GET_OPTION(height);
244 if (term_width < 50 || term_height < 20) {
246 const char *msg =
"\n[Terminal too small for help screen - try resizing]\n";
253 const int box_width = 48;
254 const int box_height = 24;
258 int start_col = (term_width - box_width) / 2;
264 int start_row = (term_height - box_height) / 2;
270 const size_t BUFFER_SIZE = 8192;
271 char *buffer = SAFE_MALLOC(BUFFER_SIZE,
char *);
274#define APPEND(fmt, ...) \
276 int written = snprintf(buffer + buf_pos, BUFFER_SIZE - buf_pos, fmt, ##__VA_ARGS__); \
278 buf_pos += written; \
290 APPEND(
"\033[%d;%dH", start_row + 1, start_col + 1);
291 APPEND(
"╔══════════════════════════════════════════════╗");
294 APPEND(
"\033[%d;%dH", start_row + 2, start_col + 1);
295 build_help_line(line_buf,
sizeof(line_buf),
"ascii-chat Keyboard Shortcuts");
299 APPEND(
"\033[%d;%dH", start_row + 3, start_col + 1);
300 APPEND(
"╠══════════════════════════════════════════════╣");
303 APPEND(
"\033[%d;%dH", start_row + 4, start_col + 1);
304 build_help_line(line_buf,
sizeof(line_buf),
"Navigation & Control:");
307 APPEND(
"\033[%d;%dH", start_row + 5, start_col + 1);
308 build_help_line(line_buf,
sizeof(line_buf),
"─────────────────────");
311 APPEND(
"\033[%d;%dH", start_row + 6, start_col + 1);
312 build_help_line(line_buf,
sizeof(line_buf),
"? Toggle this help screen");
315 APPEND(
"\033[%d;%dH", start_row + 7, start_col + 1);
316 build_help_line(line_buf,
sizeof(line_buf),
"Space Play/Pause (files only)");
319 APPEND(
"\033[%d;%dH", start_row + 8, start_col + 1);
320 build_help_line(line_buf,
sizeof(line_buf),
"← / → Seek backward/forward 30s");
323 APPEND(
"\033[%d;%dH", start_row + 9, start_col + 1);
324 build_help_line(line_buf,
sizeof(line_buf),
"m Mute/Unmute audio");
327 APPEND(
"\033[%d;%dH", start_row + 10, start_col + 1);
328 build_help_line(line_buf,
sizeof(line_buf),
"↑ / ↓ Volume up/down (10%)");
331 APPEND(
"\033[%d;%dH", start_row + 11, start_col + 1);
332 build_help_line(line_buf,
sizeof(line_buf),
"c Cycle color mode");
335 APPEND(
"\033[%d;%dH", start_row + 12, start_col + 1);
336 build_help_line(line_buf,
sizeof(line_buf),
"f Flip webcam horizontally");
339 APPEND(
"\033[%d;%dH", start_row + 13, start_col + 1);
340 build_help_line(line_buf,
sizeof(line_buf),
"r Cycle render mode");
344 APPEND(
"\033[%d;%dH", start_row + 14, start_col + 1);
345 build_help_line(line_buf,
sizeof(line_buf),
"Ctrl+L Print held lock state");
349 APPEND(
"\033[%d;%dH", start_row + 15, start_col + 1);
350 build_help_line(line_buf,
sizeof(line_buf),
"");
354 APPEND(
"\033[%d;%dH", start_row + 16, start_col + 1);
355 build_help_line(line_buf,
sizeof(line_buf),
"Current Settings:");
358 APPEND(
"\033[%d;%dH", start_row + 17, start_col + 1);
359 build_help_line(line_buf,
sizeof(line_buf),
"───────────────");
363 APPEND(
"\033[%d;%dH", start_row + 14, start_col + 1);
364 build_help_line(line_buf,
sizeof(line_buf),
"");
368 APPEND(
"\033[%d;%dH", start_row + 15, start_col + 1);
369 build_help_line(line_buf,
sizeof(line_buf),
"Current Settings:");
372 APPEND(
"\033[%d;%dH", start_row + 16, start_col + 1);
373 build_help_line(line_buf,
sizeof(line_buf),
"───────────────");
378 APPEND(
"\033[%d;%dH", start_row + 15, start_col + 1);
379 build_help_line(line_buf,
sizeof(line_buf),
"Current Settings:");
382 APPEND(
"\033[%d;%dH", start_row + 16, start_col + 1);
383 build_help_line(line_buf,
sizeof(line_buf),
"───────────────");
387 double current_volume = GET_OPTION(speakers_volume);
388 int current_color_mode = (int)GET_OPTION(color_mode);
389 int current_render_mode = (int)GET_OPTION(render_mode);
390 bool flip_x = (
bool)GET_OPTION(flip_x);
391 bool flip_y = (
bool)GET_OPTION(flip_y);
392 bool current_audio = (
bool)GET_OPTION(audio_enabled);
396 format_volume_bar(current_volume, volume_bar,
sizeof(volume_bar));
403 const char *flip_text =
"None";
404 if (flip_x && flip_y) {
415 const char *audio_text =
420 APPEND(
"\033[%d;%dH", start_row + 18, start_col + 1);
421 build_settings_line(line_buf,
sizeof(line_buf),
"Audio", audio_text);
424 APPEND(
"\033[%d;%dH", start_row + 19, start_col + 1);
425 build_settings_line(line_buf,
sizeof(line_buf),
"Volume", volume_bar);
428 APPEND(
"\033[%d;%dH", start_row + 20, start_col + 1);
429 build_settings_line(line_buf,
sizeof(line_buf),
"Color", color_str);
432 APPEND(
"\033[%d;%dH", start_row + 21, start_col + 1);
433 build_settings_line(line_buf,
sizeof(line_buf),
"Render", render_str);
436 APPEND(
"\033[%d;%dH", start_row + 22, start_col + 1);
437 build_settings_line(line_buf,
sizeof(line_buf),
"Flip", flip_text);
441 APPEND(
"\033[%d;%dH", start_row + 23, start_col + 1);
442 build_help_line(line_buf,
sizeof(line_buf),
"");
446 APPEND(
"\033[%d;%dH", start_row + 24, start_col + 1);
447 build_help_line(line_buf,
sizeof(line_buf),
"Press ? to close");
451 APPEND(
"\033[%d;%dH", start_row + 25, start_col + 1);
452 APPEND(
"╚══════════════════════════════════════════════╝");
454 APPEND(
"\033[%d;%dH", start_row + 17, start_col + 1);
455 build_settings_line(line_buf,
sizeof(line_buf),
"Audio", audio_text);
458 APPEND(
"\033[%d;%dH", start_row + 18, start_col + 1);
459 build_settings_line(line_buf,
sizeof(line_buf),
"Volume", volume_bar);
462 APPEND(
"\033[%d;%dH", start_row + 19, start_col + 1);
463 build_settings_line(line_buf,
sizeof(line_buf),
"Color", color_str);
466 APPEND(
"\033[%d;%dH", start_row + 20, start_col + 1);
467 build_settings_line(line_buf,
sizeof(line_buf),
"Render", render_str);
470 APPEND(
"\033[%d;%dH", start_row + 21, start_col + 1);
471 build_settings_line(line_buf,
sizeof(line_buf),
"Flip", flip_text);
475 APPEND(
"\033[%d;%dH", start_row + 22, start_col + 1);
476 build_help_line(line_buf,
sizeof(line_buf),
"");
480 APPEND(
"\033[%d;%dH", start_row + 23, start_col + 1);
481 build_help_line(line_buf,
sizeof(line_buf),
"Press ? to close");
485 APPEND(
"\033[%d;%dH", start_row + 24, start_col + 1);
486 APPEND(
"╚══════════════════════════════════════════════╝");
491 APPEND(
"\033[%d;%dH", start_row + 26, start_col + 1);
493 APPEND(
"\033[%d;%dH", start_row + 25, start_col + 1);