From ee87ae1bd9c41715cd557ece5eb18c425ae5e7de Mon Sep 17 00:00:00 2001 From: Alexander Petrov Date: Fri, 26 Jun 2026 11:15:28 +0300 Subject: [PATCH] =?UTF-8?q?mdview2:=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B8=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=D0=B2=D0=B0=D1=82=D1=8C=20view=E2=86=92md=20?= =?UTF-8?q?=D0=B8=20=D0=BF=D1=80=D0=B8=D1=87=D0=B5=D1=81=D0=B0=D1=82=D1=8C?= =?UTF-8?q?=20=D1=81=D0=B5=D0=BA=D1=86=D0=B8=D0=B8=20=D1=8F=D0=B4=D1=80?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - mdview2_view.c → mdview2_md.c: модуль уже содержит отрисовку MD-документа из рендер-кэша + скролл + статус-бар, т.е. это парный к mdview2_raw.c вид (MD ↔ RAW). Переименование делает пару явной. - mdview2.c: обновлён устаревший заголовок-комментарий («Фаза 0 — копия mdview.c») на описание ядра + карту модулей; убраны осиротевшие после выноса комментарии; нормализованы баннеры секций (рендер-кэш / примитивы экрана+EMM / загрузка файла / doc-slots / loading-loop / точка входа). - mdview2.h: освежён заголовок-комментарий под текущую раскладку модулей. Только переименование и комментарии/баннеры — поведение и размер не меняются (exe 28115, как до). Сборка чистая. Co-Authored-By: Claude Opus 4.8 --- examples/mdview2/Makefile | 2 +- examples/mdview2/mdview2.c | 81 +++++++++---------- examples/mdview2/mdview2.h | 9 ++- .../mdview2/{mdview2_view.c => mdview2_md.c} | 6 +- 4 files changed, 49 insertions(+), 49 deletions(-) rename examples/mdview2/{mdview2_view.c => mdview2_md.c} (97%) diff --git a/examples/mdview2/Makefile b/examples/mdview2/Makefile index 8bb366d..d55b503 100644 --- a/examples/mdview2/Makefile +++ b/examples/mdview2/Makefile @@ -8,7 +8,7 @@ PROJ_ROOT := $(abspath $(CURDIR)/../..) EXAMPLE := mdview2 -EXTRA_SRCS := mdview2_raw.c mdview2_help.c mdview2_table.c mdview2_enc.c mdview2_view.c mdview2_index.c +EXTRA_SRCS := mdview2_raw.c mdview2_help.c mdview2_table.c mdview2_enc.c mdview2_md.c mdview2_index.c MEMORY := small include $(PROJ_ROOT)/app.mk diff --git a/examples/mdview2/mdview2.c b/examples/mdview2/mdview2.c index f789822..400a8ae 100644 --- a/examples/mdview2/mdview2.c +++ b/examples/mdview2/mdview2.c @@ -1,23 +1,29 @@ /* * mdview2 — просмотрщик Markdown для Sprinter (render-cache версия). * - * Фаза 0 (скаффолдинг): этот файл — копия mdview/mdview.c, без изменений - * логики. План переделки на render-cache — docs/mdview2-plan.md. + * Этот файл — ЯДРО (инфраструктура + точка входа). Прикладные подсистемы + * вынесены в отдельные модули (общий интерфейс — mdview2.h): + * mdview2_index.c — парсер/индексатор markdown (построение рендер-кэша) + * mdview2_md.c — представление MD-документа (отрисовка из кэша + скролл) + * mdview2_raw.c — RAW-просмотр исходного текста (F2/F3) + * mdview2_enc.c — кодировки CP866/CP1251/KOI8R + UTF-8 конвертер + * mdview2_table.c — выровненная отрисовка таблиц + * mdview2_help.c — диалог справки (F1) + * + * В ядре остаётся: пул рендер-кэша, доступ к EMM/окну W3 (fb/win_rest), + * примитивы экрана, загрузка файла, наборы документа (doc-slots), кооператив- + * ная loading-loop и диспетчер клавиш, сборка наборов и main(). * * Разметка экрана (80x32): * строка 0 — статус-бар (имя файла / диапазон строк / всего / %) * строки 1..30 — область документа (30 видимых строк текста) - * строка 31 — меню (F1 Help / F2 Reserved / F10 Exit) - * - * Навигация: - * стрелки, PgUp/PgDn, Home/End, F1 (справка), F10/Esc (выход). - * Горизонтальный сдвиг доступен только для nowrap-строк. + * строка 31 — меню (F1 Help / F2 RAW / F3 Wrap / F8 CodePg / F10 Exit) * * Память: * CODE → W1 (режим sprinter-cc --memory small) * STACK/HEAP/DATA → W2 * Буфер файла → страницы EMM (до 8 × 16 КБ = 128 КБ), - * отображаемые в W3 по требованию через fb()/map_page(). + * отображаемые в W3 по требованию через fb(). */ #include @@ -30,7 +36,7 @@ #include #include #include -#include "mdview2.h" /* геометрия, атрибуты, extern для модуля RAW */ +#include "mdview2.h" /* геометрия, атрибуты, общий интерфейс модулей */ /* ---- Палитра атрибутов ------------------------------------------- */ @@ -53,38 +59,19 @@ static const uint8_t md_pallete[16 * 4] = { 0xFF, 0xFF, 0xFF, 0xFF }; -/* Атрибуты экрана/справки и геометрия — в mdview2.h (общие с модулем RAW). - * Диалог справки (F1) вынесен в модуль mdview2_help.c. */ - -/* ---- Глобальное состояние ---------------------------------------- */ - -/* Файл до 128 КБ хранится в наборе EMM-страниц (до 8 шт. по 16 КБ). - * В окно W3 одновременно отображается только одна страница (FILE_BUF): - * функция fb() при необходимости переключает маппинг и кэширует текущую - * страницу в cur_page, чтобы не делать лишние переключения. +/* Атрибуты экрана/справки и геометрия — в mdview2.h (общие со всеми модулями). + * Типы записей (idx_rec_t — в mdview2_index.c, cache_rec_t — в mdview2.h), + * словари флагов/стилей (IF_, CK_, INIT_STYLE_) и константы индекса + * (INDEX_RECS_PER_PAGE, MAX_CACHE_LINE_LEN) — в mdview2.h. * - * Индекс экранных сегментов хранится отдельно в EMM (записи по 8 байт, - * одна запись на видимую строку). Каждая запись содержит: - * - смещение первого байта сегмента в исходном файле, - * - флаги (continuation/nowrap/blank/code), - * - начальный inline-стиль сегмента. - * Правая граница сегмента определяется смещением следующей записи. - * Такой подход освобождает около 11 КБ ближней RAM и снимает старый - * лимит MAX_LINES для near-массивов. - */ + * В SDCC/z80 критично явно инициализировать static-переменные (`= 0`): + * неинициализированные static-объекты могут конфликтовать по размещению + * и перезаписывать друг друга (см. memory/sdcc_static_storage_gotcha). */ -/* В SDCC/z80 критично явно инициализировать static-переменные (`= 0`). - * Неинициализированные static-объекты могут конфликтовать по размещению - * и перезаписывать друг друга. См. заметку memory/sdcc_static_storage_gotcha. */ -/* Компактная запись индекса сегмента. - * Каждый элемент соответствует одной строке рендера в viewport. */ -/* idx_rec_t + INDEX_REC_SIZE — в mdview2_index.c; INDEX_RECS_PER_PAGE — в mdview2.h. */ #define MAX_INDEX_PAGES 8u /* максимум 8 * 2048 = 16384 сегментов индекса */ -/* Флаги IF_* сегмента — в mdview2.h (общие с индексатором/кэшем/вью). */ - /* ================================================================== - * Фаза 1 (mdview2): директория и пул рендер-кэша + * Рендер-кэш: директория и пул EMM-страниц * ================================================================== * Каждая логическая строка экрана рендерится РОВНО ОДИН РАЗ (Фаза 2) * в готовый буфер и больше никогда не парсится повторно при скролле. @@ -276,7 +263,7 @@ static uint8_t spinner_phase = 0; static uint8_t spinner_active = 0; /* ================================================================== - * Вспомогательные функции + * Примитивы экрана, доступ к EMM/окну W3 (fb/win_rest), палитра * ================================================================== */ /* Печатает строку с указанным атрибутом, начиная с позиции (x,y), @@ -586,9 +573,13 @@ static void unload_file(void) /* Таблицы ремапа, set_encoding, кодировки и UTF-8 конвертер — в mdview2_enc.c. */ -/* ---------- Сохранение/восстановление/переключение наборов ---------- - * doc_save_live: живые глобалы → g_doc[i]. doc_load_live: g_doc[i] → живые - * глобалы (+ инвалидация маппинга fb() и активной кодировки). */ +/* ================================================================== + * Наборы документа (doc-slots): сохранение/свап + * ================================================================== + * Два сосуществующих набора (DOC_8BIT / DOC_UTF8) живут как копии всего + * состояния (file/index/cache/позиция) в g_doc[]; «живые» глобалы — это + * активный набор. doc_save_live: живые → g_doc[i]; doc_load_live: g_doc[i] + * → живые (+ инвалидация маппинга fb() и активной кодировки). */ static void doc_save_live(uint8_t i) { docset_t *d = &g_doc[i]; @@ -636,7 +627,7 @@ static void doc_switch(uint8_t target) /* Автоопределение/имя кодировки, ремап-вывод и UTF-8→CP866 конвертер — в mdview2_enc.c. */ -/* Отрисовка области/статус-бара/меню и прокрутка — в модуле mdview2_view.c. */ +/* Отрисовка области/статус-бара/меню и прокрутка — в модуле mdview2_md.c. */ /* ================================================================== @@ -652,7 +643,13 @@ static void die(const char *msg) (void)getkey(); } -/* Диалог справки (F1) — в модуле mdview2_help.c (show_help). */ +/* ================================================================== + * Прогрессивная загрузка и диспетчер клавиш (MD) + * ================================================================== + * index_lines() строит индекс кооперативно и периодически зовёт + * progress_tick(): тот рисует первый готовый экран, крутит спиннер и + * обрабатывает клавиши на лету (load_key). Диалог справки (F1) — в + * mdview2_help.c, RAW-навигация — в mdview2_raw.c. */ /* Обработка клавиши во время прогрессивной загрузки: скролл строго в * пределах готовых строк (drawable_lines); End = последняя готовая страница; diff --git a/examples/mdview2/mdview2.h b/examples/mdview2/mdview2.h index 24adba0..7f22936 100644 --- a/examples/mdview2/mdview2.h +++ b/examples/mdview2/mdview2.h @@ -1,9 +1,10 @@ /* * mdview2.h — общие определения и интерфейс между модулями mdview2. * - * Монолит mdview2.c расщепляется инкрементально; первый отделённый модуль — - * RAW-просмотр (mdview2_raw.c). Здесь живут разделяемые константы экрана/ - * атрибутов, extern-объявления нужных RAW символов из mdview2.c и API RAW. + * Монолит mdview2.c расщеплён на ядро + модули: index (парсер), md/raw (виды), + * enc (кодировки), table, help. Здесь — разделяемые константы экрана/атрибутов, + * словари флагов/стилей, тип cache_rec_t, extern-объявления разделяемого + * состояния ядра и API каждого модуля (сгруппированы по секциям ниже). */ #ifndef MDVIEW2_H #define MDVIEW2_H @@ -161,7 +162,7 @@ extern uint8_t g_ready; /* 1 когда первичный до extern uint8_t g_f8_enabled; /* можно ли сейчас переключать кодировку */ /* ================================================================== * - * Отрисовка области/статус-бара/меню и прокрутка (mdview2_view.c). + * Отрисовка области/статус-бара/меню и прокрутка (mdview2_md.c). * ================================================================== */ void draw_viewport_from_cache(void); /* перерисовать область документа из кэша */ uint16_t drawable_lines(void); /* число строк, готовых к показу */ diff --git a/examples/mdview2/mdview2_view.c b/examples/mdview2/mdview2_md.c similarity index 97% rename from examples/mdview2/mdview2_view.c rename to examples/mdview2/mdview2_md.c index cf02bc6..4a496a9 100644 --- a/examples/mdview2/mdview2_view.c +++ b/examples/mdview2/mdview2_md.c @@ -1,11 +1,13 @@ /* - * mdview2_view.c — представление: отрисовка области документа из рендер-кэша, - * статус-бар, нижнее меню и прокрутка (верт./гориз.). + * mdview2_md.c — представление MD-документа (peer к mdview2_raw.c): отрисовка + * области из рендер-кэша, статус-бар, нижнее меню и прокрутка (верт./гориз.). * * Работает поверх готового рендер-кэша (cache_dir_get → cache_rec_t) и * состояния навигации (top_line/viewport_x/n_lines, см. mdview2.h). Никакого * парсинга/обращения к исходному файлу: всё рисуется из (char,attr)-ячеек кэша * через win_rest_remap (ремап 8-битных кодировок — в mdview2_enc.c). + * + * Пара видов: mdview2_md.c (MD, из кэша) ↔ mdview2_raw.c (RAW, из fb()). */ #include