mdview2: полировка статус-бара/справки/детекции + libc min/max
- status-bar: dirty-tracking (числа/процент/кодировка перерисовываются только при изменении), поле кодировки сдвинуто к DIV1_X-10 (8 симв.) - md_key: HOME/END не перерисовывают экран, если позиция не меняется - help: версия v1.0(a3), добавлены F2/F3 (RAW/Wrap), компактные секции - enc: детекция по 5 частотным буквам и сэмплу 1КБ; ENC_UNSUPPORTED (UTF16/32) - libc: добавлены min()/max() (naked, <stdlib.h>) + сборка в lib/Makefile Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+107
-50
@@ -28,6 +28,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <conio.h>
|
||||
#include <bios/text.h>
|
||||
@@ -269,6 +270,7 @@ static void doc_switch(uint8_t target); /* forward (нужна в progress_tic
|
||||
void put_str_attr(uint8_t x, uint8_t y, const char *s, uint8_t attr)
|
||||
{
|
||||
uint8_t len = (x < SCREEN_W) ? (uint8_t)(SCREEN_W - x) : 0;
|
||||
len = min(len, strlen(s));
|
||||
if (len == 0) return;
|
||||
bios_set_place(y, x);
|
||||
bios_writeattr_until(s, len, attr, 0);
|
||||
@@ -490,7 +492,7 @@ static int alloc_set_storage(void)
|
||||
{
|
||||
uint8_t want;
|
||||
|
||||
want = (uint8_t)(file_pages >> 1 + 1u);
|
||||
want = (uint8_t)((file_pages >> 1) + 1u);
|
||||
if (want > MAX_INDEX_PAGES) want = MAX_INDEX_PAGES;
|
||||
index_blk = mem_alloc_pages(want);
|
||||
if (index_blk == 0) return -5;
|
||||
@@ -499,7 +501,7 @@ static int alloc_set_storage(void)
|
||||
index_phys[i] = mem_get_page(index_blk, i);
|
||||
max_lines = (uint16_t)index_pages * INDEX_RECS_PER_PAGE;
|
||||
|
||||
want = (uint8_t)(file_pages >> 1 + 1u);
|
||||
want = (uint8_t)((file_pages >> 1) + 1u);
|
||||
if (want > MAX_CACHE_DIR_PAGES) want = MAX_CACHE_DIR_PAGES;
|
||||
cache_dir_blk = mem_alloc_pages(want);
|
||||
if (cache_dir_blk == 0) return -6;
|
||||
@@ -616,32 +618,67 @@ static void load_key(uint16_t k)
|
||||
uint16_t maxtop = (dr > VIEW_H) ? (uint16_t)(dr - VIEW_H) : 0;
|
||||
uint16_t nt = top_line;
|
||||
|
||||
if (ascii == 0x1B || scan == KEY_F10) { g_abort = 1; return; } /* Esc/F10 → выход */
|
||||
if (ascii) return; /* прочие ascii игнорируем */
|
||||
if (ascii == 0x1B || scan == KEY_F10) {
|
||||
g_abort = 1;
|
||||
return;
|
||||
} /* Esc/F10 → выход */
|
||||
if (ascii)
|
||||
return; /* прочие ascii игнорируем */
|
||||
|
||||
switch (scan) {
|
||||
case KEY_UP: nt = (top_line >= 1) ? (uint16_t)(top_line - 1) : 0; break;
|
||||
case KEY_DOWN: nt = top_line + 1; break;
|
||||
case KEY_PGUP: nt = (top_line >= VIEW_H) ? (uint16_t)(top_line - VIEW_H) : 0; break;
|
||||
case KEY_PGDN: nt = top_line + VIEW_H; break;
|
||||
case KEY_HOME: top_line = 0; viewport_x = 0; draw_viewport_from_cache(); render_md_status_numbers(); return;
|
||||
case KEY_END: top_line = maxtop; viewport_x = 0; draw_viewport_from_cache(); render_md_status_numbers(); return;
|
||||
case KEY_LEFT: md_scroll_horizon(-(int8_t)HPAN_STEP); render_md_status_numbers(); return;
|
||||
case KEY_RIGHT: md_scroll_horizon(+(int8_t)HPAN_STEP); render_md_status_numbers(); return;
|
||||
case KEY_F1: show_help(); return;
|
||||
case KEY_F8: /* во время сборки крутим ТОЛЬКО 8-бит и только если набор 8-битный
|
||||
* (ремап на отрисовке; индексация не зависит от кодировки) */
|
||||
if (g_f8_enabled && g_active_doc == DOC_8BIT) {
|
||||
uint8_t nx = (g_encoding == ENC_CP866) ? ENC_CP1251 :
|
||||
(g_encoding == ENC_CP1251) ? ENC_KOI8R : ENC_CP866;
|
||||
set_encoding(nx); g_doc[DOC_8BIT].enc = nx;
|
||||
draw_viewport_from_cache();
|
||||
render_full_status();
|
||||
}
|
||||
return;
|
||||
default: return;
|
||||
case KEY_UP:
|
||||
nt = (top_line >= 1) ? (uint16_t)(top_line - 1) : 0;
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
nt = top_line + 1;
|
||||
break;
|
||||
case KEY_PGUP:
|
||||
nt = (top_line >= VIEW_H) ? (uint16_t)(top_line - VIEW_H) : 0;
|
||||
break;
|
||||
case KEY_PGDN:
|
||||
nt = top_line + VIEW_H;
|
||||
break;
|
||||
case KEY_HOME:
|
||||
top_line = 0;
|
||||
viewport_x = 0;
|
||||
draw_viewport_from_cache();
|
||||
render_md_status_numbers();
|
||||
return;
|
||||
case KEY_END:
|
||||
top_line = maxtop;
|
||||
viewport_x = 0;
|
||||
draw_viewport_from_cache();
|
||||
render_md_status_numbers();
|
||||
return;
|
||||
case KEY_LEFT:
|
||||
md_scroll_horizon(-(int8_t)HPAN_STEP);
|
||||
render_md_status_numbers();
|
||||
return;
|
||||
case KEY_RIGHT:
|
||||
md_scroll_horizon(+(int8_t)HPAN_STEP);
|
||||
render_md_status_numbers();
|
||||
return;
|
||||
case KEY_F1:
|
||||
show_help();
|
||||
return;
|
||||
case KEY_F8:
|
||||
/* во время сборки крутим ТОЛЬКО 8-бит и только если набор 8-битный
|
||||
* (ремап на отрисовке; индексация не зависит от кодировки) */
|
||||
if (g_f8_enabled && g_active_doc == DOC_8BIT) {
|
||||
uint8_t nx = (g_encoding == ENC_CP866) ? ENC_CP1251 :
|
||||
(g_encoding == ENC_CP1251) ? ENC_KOI8R : ENC_CP866;
|
||||
set_encoding(nx);
|
||||
g_doc[DOC_8BIT].enc = nx;
|
||||
draw_viewport_from_cache();
|
||||
render_full_status();
|
||||
}
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if (nt > maxtop) nt = maxtop;
|
||||
|
||||
if (nt > maxtop)
|
||||
nt = maxtop;
|
||||
if (nt != top_line) {
|
||||
top_line = nt;
|
||||
draw_viewport_from_cache();
|
||||
@@ -676,10 +713,11 @@ void progress_tick(void)
|
||||
g_first_drawn = 1;
|
||||
touched = 1;
|
||||
}
|
||||
if (n_lines >= (uint16_t)(g_last_prog + 20)) {
|
||||
if (n_lines >= (uint16_t)(g_last_prog + 10)) {
|
||||
g_last_prog = n_lines;
|
||||
spinner_tick();
|
||||
if (g_first_drawn) render_md_status_numbers();
|
||||
if (g_first_drawn)
|
||||
render_md_status_numbers();
|
||||
touched = 1;
|
||||
}
|
||||
if (g_first_drawn && kbhit()) {
|
||||
@@ -688,7 +726,8 @@ void progress_tick(void)
|
||||
}
|
||||
/* Отрисовка/WINREST/BIOS могли сбить маппинг W3, на который опирается fb()
|
||||
* при индексации → форсируем ре-маппинг страницы файла на следующем fb(). */
|
||||
if (touched) cur_page = 0xFF;
|
||||
if (touched)
|
||||
cur_page = 0xFF;
|
||||
}
|
||||
|
||||
/* ==================================================================
|
||||
@@ -710,10 +749,12 @@ static int build_doc(uint8_t slot, uint8_t enc, uint8_t visible)
|
||||
{
|
||||
if (slot == DOC_UTF8) {
|
||||
if (!utf_avail) { /* первый вход: выделить страницы */
|
||||
if (!utf_alloc()) return -7; /* выделяет страницы + сбрасывает конвертер */
|
||||
if (!utf_alloc())
|
||||
return -7; /* выделяет страницы + сбрасывает конвертер */
|
||||
utf_avail = 1;
|
||||
}
|
||||
file_blk = utf_blk; file_pages = utf_pages;
|
||||
file_blk = utf_blk;
|
||||
file_pages = utf_pages;
|
||||
memcpy(file_phys, utf_phys, MAX_PAGES);
|
||||
if (g_utf_building) {
|
||||
file_size = 0;
|
||||
@@ -723,18 +764,25 @@ static int build_doc(uint8_t slot, uint8_t enc, uint8_t visible)
|
||||
file_size = utf_size;
|
||||
}
|
||||
} else {
|
||||
file_blk = orig_file_blk; file_pages = orig_file_pages; file_size = orig_file_size;
|
||||
file_blk = orig_file_blk;
|
||||
file_pages = orig_file_pages;
|
||||
file_size = orig_file_size;
|
||||
memcpy(file_phys, orig_file_phys, MAX_PAGES);
|
||||
}
|
||||
cur_page = 0xFF;
|
||||
|
||||
int rc = alloc_set_storage();
|
||||
if (rc < 0) return rc;
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
set_encoding(enc);
|
||||
top_line = 0; viewport_x = 0;
|
||||
top_line = 0;
|
||||
viewport_x = 0;
|
||||
g_active_doc = slot;
|
||||
if (visible) { g_disp_doc = slot; g_first_drawn = 0; }
|
||||
if (visible) {
|
||||
g_disp_doc = slot;
|
||||
g_first_drawn = 0;
|
||||
}
|
||||
|
||||
g_loading = 1;
|
||||
g_last_prog = 0;
|
||||
@@ -743,7 +791,10 @@ static int build_doc(uint8_t slot, uint8_t enc, uint8_t visible)
|
||||
|
||||
/* Зафиксировать конвертацию (на случай обрыва индекса по max_lines до конца
|
||||
* исходника) — иначе g_utf_building остался бы 1 и сломал бы следующую сборку. */
|
||||
if (g_utf_building) { utf_size = file_size; g_utf_building = 0; }
|
||||
if (g_utf_building) {
|
||||
utf_size = file_size;
|
||||
g_utf_building = 0;
|
||||
}
|
||||
|
||||
g_doc[slot].built = 1;
|
||||
doc_save_live(slot);
|
||||
@@ -762,31 +813,37 @@ static void switch_encoding(uint8_t next)
|
||||
{
|
||||
uint8_t target = (next == ENC_UTF8) ? DOC_UTF8 : DOC_8BIT;
|
||||
|
||||
if (target == g_active_doc) { /* тот же набор — только ремап */
|
||||
set_encoding(next); g_doc[target].enc = next;
|
||||
} else if (g_doc[target].built) { /* набор готов — мгновенный свап */
|
||||
doc_switch(target); g_disp_doc = target;
|
||||
set_encoding(next); g_doc[target].enc = next;
|
||||
} else { /* строим набор лениво */
|
||||
doc_save_live(g_active_doc); /* сохранить текущий (позиция и т.п.) */
|
||||
if (target == g_active_doc) { /* тот же набор — только ремап */
|
||||
set_encoding(next);
|
||||
g_doc[target].enc = next;
|
||||
} else if (g_doc[target].built) { /* набор готов — мгновенный свап */
|
||||
doc_switch(target);
|
||||
g_disp_doc = target;
|
||||
set_encoding(next);
|
||||
g_doc[target].enc = next;
|
||||
} else { /* строим набор лениво */
|
||||
doc_save_live(g_active_doc); /* сохранить текущий (позиция и т.п.) */
|
||||
#if WITH_RAW
|
||||
g_ready = 0; render_menu(); /* идёт индексация — прячем F2 */
|
||||
g_ready = 0;
|
||||
render_menu(); /* идёт индексация — прячем F2 */
|
||||
#endif
|
||||
spinner_show(1);
|
||||
int rc = build_doc(target, next, 1); /* visible: прогрессивный показ первого экрана
|
||||
* (progress_tick рисует по текущему виду — MD/RAW) */
|
||||
int rc = build_doc(target, next, 1); /* visible: прогрессивный показ первого экрана
|
||||
* (progress_tick рисует по текущему виду — MD/RAW) */
|
||||
spinner_show(0);
|
||||
#if WITH_RAW
|
||||
g_ready = 1; render_menu();
|
||||
g_ready = 1;
|
||||
render_menu();
|
||||
#endif
|
||||
if (rc < 0) { /* нет EMM — откат на текущий набор */
|
||||
if (target == DOC_UTF8) g_utf_failed = 1;
|
||||
if (rc < 0) { /* нет EMM — откат на текущий набор */
|
||||
if (target == DOC_UTF8)
|
||||
g_utf_failed = 1;
|
||||
doc_load_live(g_active_doc);
|
||||
return;
|
||||
}
|
||||
g_disp_doc = target; /* build_doc уже выставил active/enc */
|
||||
g_disp_doc = target; /* build_doc уже выставил active/enc */
|
||||
}
|
||||
clamp_top(); /* привести top_line к новому набору (для MD) */
|
||||
clamp_top(); /* привести top_line к новому набору (для MD) */
|
||||
}
|
||||
|
||||
/* ==================================================================
|
||||
|
||||
Reference in New Issue
Block a user