Files
Sprinter-SDCC/examples/mdview2/mdview2_help.c
T
snark13 ae23d2dea2 mdview2: HEX-режим (F4) — дамп оригинального файла; версия v1.0 (b1)
Новый модуль mdview2_hex.c (WITH_HEX в conf): формат
' 0x012340 │ 16×hex │ 16 print', 30 строк, один атрибут.

- Дамп всегда ОРИГИНАЛЬНОГО файла (orig_file_phys), не активного буфера;
  ряд выровнен на 16 → один bank_read на ряд (не пересекает EMM-страницу),
  fb()/W3 не используются.
- Printable по текущей кодировке: CP866 как есть, CP1251/KOI8 через
  g_remap, UTF-8 — глиф на позиции лид-байта (continuation → '.') через
  новый utf_cp_glyph(), выделенный из конвертера enc-модуля.
- Навигация: ±16 / ±480 / Home / End; одна строка — аппаратный scroll()
  + подрисовка одного ряда (как MD/RAW); процент в статусе.
- F4 — тумблер HEX ↔ прежний вид; F2 из HEX уводит в MD; позиция при
  всех переходах через view_pos/view_reanchor (map_off orig ↔ active).
- F8 в HEX: hex-колонка неизменна, printable перерисовывается в новой
  кодировке; позиция не двигается.
- Help: версия v1.0 (b1), строка F4.

exe 25725 → 27893 (+2168). Проверено в MAME.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 13:19:08 +03:00

107 lines
6.1 KiB
C

/*
* mdview2_help.c — диалог справки (F1).
*
* Модальное окно поверх документа: рамка с заголовком, список горячих
* клавиш и поддерживаемых markdown-элементов. Блокирует до нажатия любой
* клавиши, после чего восстанавливает статус-бар, область документа и меню.
*
* Зависимости от ядра (mdview2.c): render_full_status / draw_viewport_from_cache
* / render_menu для восстановления экрана. Текст справки — в CP866.
*/
#include <stdint.h>
#include <string.h>
#include <conio.h>
#include <bios/text.h>
#include "mdview2.h"
/* Геометрия диалога справки (в символьных координатах 80×32). */
#define HELP_X 8u /* левая граница рамки */
#define HELP_Y 3u /* верхняя граница рамки */
#define HELP_W 64u /* ширина рамки (включая │) */
#define HELP_H 26u /* высота рамки (включая ─) */
/* Заполняет одну внутреннюю строку диалога (r=0 — первая строка за рамкой).
* Строка s в кодировке CP866; остаток до края дополняется пробелами. */
static void help_line(uint8_t r, const char *s, uint8_t attr)
{
uint8_t x = HELP_X + 1u;
uint8_t y = HELP_Y + 1u + r;
uint8_t len = (uint8_t)strlen(s);
if (len > HELP_W - 2u)
len = HELP_W - 2u;
bios_set_place(y, x);
if (len > 0)
bios_writeattr(s, len, attr);
/* place уже продвинут bios_writeattr на len колонок (verified). */
if (len < HELP_W - 2u) {
bios_fillcharattr(' ', ATTR_HELP_BG, (uint8_t)(HELP_W - 2u - len));
}
}
void show_help(void)
{
/* " Помощь " в CP866 (8 байт) */
static const char title[] = " \x8F\xAE\xAC\xAE\xE9\xEC ";
uint8_t tlen = 8u;
uint8_t lft = (uint8_t)((HELP_W - 2u - tlen) / 2u); /* = 27 */
uint8_t rgt = (uint8_t)(HELP_W - 2u - tlen - lft);
/* Верхняя граница рамки с заголовком по центру.
* place продвигается каждым BIOS-вызовом (verified), поэтому
* достаточно одной установки места на всю строку рамки. */
wrchar(HELP_X, HELP_Y, 0xDA, ATTR_HELP_BDR); /* ┌ */
bios_set_place(HELP_Y, (uint8_t)(HELP_X + 1u));
if (lft > 0) bios_fillcharattr(0xC4, ATTR_HELP_BDR, lft);
if (tlen > 0) bios_writeattr(title, tlen, ATTR_HELP_TIT);
if (rgt > 0) bios_fillcharattr(0xC4, ATTR_HELP_BDR, rgt);
wrchar(HELP_X + HELP_W - 1u, HELP_Y, 0xBF, ATTR_HELP_BDR); /* ┐ */
/* Боковые границы (левый и правый │ для каждой строки тела) */
for (uint8_t r = 1u; r < HELP_H - 1u; r++) {
wrchar(HELP_X, HELP_Y + r, 0xB3, ATTR_HELP_BDR); /* │ */
wrchar(HELP_X + HELP_W - 1u, HELP_Y + r, 0xB3, ATTR_HELP_BDR); /* │ */
}
/* Нижняя граница рамки */
wrchar(HELP_X, HELP_Y + HELP_H - 1u, 0xC0, ATTR_HELP_BDR); /* └ */
bios_set_place((uint8_t)(HELP_Y + HELP_H - 1u), (uint8_t)(HELP_X + 1u));
bios_fillcharattr(0xC4, ATTR_HELP_BDR, (uint8_t)(HELP_W - 2u));
wrchar(HELP_X + HELP_W - 1u, HELP_Y + HELP_H - 1u, 0xD9, ATTR_HELP_BDR); /* ┘ */
/* Содержимое (20 внутренних строк) */
uint8_t r = 0;
help_line(r++, "", ATTR_HELP_BG);
help_line(r++, " MDView v1.0 (b1) -- Markdown Viewer for Sprinter", ATTR_HELP_HDR);
help_line(r++, " (c) 2026 \x8F\xA5\xE2\xE0\xAE\xA2 \x80\x2E\x83\x2E",
ATTR_HELP_BG);
help_line(r++, "", ATTR_HELP_BG);
help_line(r++, " Navigation:", ATTR_HELP_HDR);
help_line(r++, " \x18 \x19 Scroll one line up / down", ATTR_HELP_BG);
help_line(r++, " PgUp PgDn Scroll one page up / down", ATTR_HELP_BG);
help_line(r++, " Home End Jump to beginning / end of document", ATTR_HELP_BG);
help_line(r++, " \x1B \x1A Horizontal pan (code blocks/tables/unwrap)", ATTR_HELP_BG);
help_line(r++, " Esc F10 Exit", ATTR_HELP_BG);
help_line(r++, "", ATTR_HELP_BG);
help_line(r++, " Markdown elements:", ATTR_HELP_HDR);
help_line(r++, " # ## ### Headings H1-H6, **bold**, *italic*,", ATTR_HELP_BG);
help_line(r++, " `code`, ``` code ```, ~~strike~~, > quote", ATTR_HELP_BG);
help_line(r++, " - * + 1. 2. Ordered list, |----|----| Tables", ATTR_HELP_BG);
help_line(r++, "", ATTR_HELP_BG);
help_line(r++, " Encoding and View modes:", ATTR_HELP_HDR);
help_line(r++, " F2 RAW Mode", ATTR_HELP_BG);
help_line(r++, " F3 Wrap/Unwrap Mode for RAW View", ATTR_HELP_BG);
help_line(r++, " F4 HEX Mode (dump of original file)", ATTR_HELP_BG);
help_line(r++, " F8 Cycle CP866 / CP1251 / KOI8-R / UTF-8", ATTR_HELP_BG);
help_line(r++, " Auto-detected on open; F8 to override", ATTR_HELP_BG);
help_line(r++, "", ATTR_HELP_BG);
help_line(r++, " File size: up to 256 KB (EMM). Lines: up to 18432.", ATTR_HELP_BG);
(void)getkey();
render_full_status();
draw_viewport_from_cache();
render_menu();
}