Compare commits
2 Commits
977e2d3d4a
...
3a33b30c07
| Author | SHA1 | Date | |
|---|---|---|---|
| 3a33b30c07 | |||
| fabbc8129c |
@@ -284,6 +284,23 @@ void fill_row(uint8_t y, uint8_t attr)
|
|||||||
bios_clearwin(y, 0, 1, SCREEN_W, attr);
|
bios_clearwin(y, 0, 1, SCREEN_W, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Процент 0..100 = num*100/den на чистой 16-битной арифметике — чтобы НЕ
|
||||||
|
* тянуть 32-битное деление __divulong (~760 Б) ради показа процента в статусе.
|
||||||
|
* Оба вызова (MD/RAW) дают операнды, влезающие в 16 бит (≤18432 и ≤1024),
|
||||||
|
* переполняет только *100 — поэтому масштабируем оба вниз, пока num*100 не
|
||||||
|
* влезёт в uint16, затем считаем долю циклом-вычитанием (без div-хелпера).
|
||||||
|
* Инвариант вызовов: num ≤ den; результат всё равно ограничен 100. */
|
||||||
|
uint8_t pct16(uint16_t num, uint16_t den)
|
||||||
|
{
|
||||||
|
if (den == 0) return 0;
|
||||||
|
while (num > 655) { num >>= 1; den >>= 1; } /* num*100 ≤ 65500 < 65536 */
|
||||||
|
if (den == 0) return 100; /* страховка от num>den */
|
||||||
|
uint16_t n = (uint16_t)(num * 100u);
|
||||||
|
uint8_t p = 0;
|
||||||
|
while (n >= den && p < 100) { n = (uint16_t)(n - den); p++; }
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Отображает указанную EMM-страницу файла в окно W3.
|
/* Отображает указанную EMM-страницу файла в окно W3.
|
||||||
* Если эта страница уже активна, переключение не выполняется. */
|
* Если эта страница уже активна, переключение не выполняется. */
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ extern uint8_t g_scratch_phys; /* scratch EMM-страница для wi
|
|||||||
char fb(uint32_t p); /* байт активного буфера (W3-маппинг) */
|
char fb(uint32_t p); /* байт активного буфера (W3-маппинг) */
|
||||||
void win_rest(uint8_t row, uint8_t col, uint8_t h, uint8_t w, uint8_t page, uint16_t off);
|
void win_rest(uint8_t row, uint8_t col, uint8_t h, uint8_t w, uint8_t page, uint16_t off);
|
||||||
void fill_row(uint8_t y, uint8_t attr);
|
void fill_row(uint8_t y, uint8_t attr);
|
||||||
|
uint8_t pct16(uint16_t num, uint16_t den); /* num*100/den (0..100), 16-бит, без __divulong */
|
||||||
uint32_t seg_off(uint16_t idx); /* offset исходника для логической строки idx */
|
uint32_t seg_off(uint16_t idx); /* offset исходника для логической строки idx */
|
||||||
|
|
||||||
/* ================================================================== *
|
/* ================================================================== *
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ static uint8_t calc_md_pct(void)
|
|||||||
{
|
{
|
||||||
uint16_t total = drawable_lines();
|
uint16_t total = drawable_lines();
|
||||||
if (total <= VIEW_H) return 100;
|
if (total <= VIEW_H) return 100;
|
||||||
return (uint8_t)((uint32_t)top_line * 100UL / (uint32_t)(total - VIEW_H));
|
return pct16(top_line, (uint16_t)(total - VIEW_H));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- навигация MD после загрузки (peer к raw_key) ---------------- */
|
/* ---- навигация MD после загрузки (peer к raw_key) ---------------- */
|
||||||
|
|||||||
@@ -161,15 +161,14 @@ static uint32_t raw_prev(uint32_t off)
|
|||||||
/* ---- статус-бар: % по байтам (отрисовка — render_raw_status_numbers
|
/* ---- статус-бар: % по байтам (отрисовка — render_raw_status_numbers
|
||||||
* в mdview2_status.c, читает позицию через этот raw_pct) ---- */
|
* в mdview2_status.c, читает позицию через этот raw_pct) ---- */
|
||||||
|
|
||||||
/* Процент по байтам без 32-битного деления: масштабируем offset'ы (>>8),
|
/* Процент по байтам без 32-битного деления: масштабируем offset'ы (>>8 →
|
||||||
* дальше 32-битная арифметика. raw_top приватен модулю, поэтому % считаем
|
* ≤1024), дальше 16-битный pct16 (без __divulong). raw_top приватен модулю,
|
||||||
* здесь и отдаём готовым числом в статус-модуль. */
|
* поэтому % считаем здесь и отдаём готовым числом в статус-модуль. */
|
||||||
uint8_t calc_raw_pct(void)
|
uint8_t calc_raw_pct(void)
|
||||||
{
|
{
|
||||||
uint16_t a = (uint16_t)(raw_top >> 8);
|
uint16_t a = (uint16_t)(raw_top >> 8);
|
||||||
uint16_t b = (uint16_t)(file_size >> 8);
|
uint16_t b = (uint16_t)(file_size >> 8);
|
||||||
if (b == 0) return 0; /* файл < 1 КБ */
|
return pct16(a, b); /* den==0 (файл < 1 КБ) → pct16 вернёт 0 */
|
||||||
return (uint8_t)(a * 100UL / b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- посев позиции / пересев при смене активного буфера ----------- */
|
/* ---- посев позиции / пересев при смене активного буфера ----------- */
|
||||||
|
|||||||
@@ -79,15 +79,16 @@ void status_encoding(void)
|
|||||||
bios_write_until(enc_name(g_encoding), 8, 0);
|
bios_write_until(enc_name(g_encoding), 8, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint16_t local_total = UINT_MAX;
|
||||||
|
static uint16_t local_last = UINT_MAX;
|
||||||
|
static uint8_t local_loading = UCHAR_MAX;
|
||||||
|
static uint8_t local_pct = UCHAR_MAX;
|
||||||
|
|
||||||
/* Числовая часть (MD): "L a-b / total" между разделителями + "pct%" справа.
|
/* Числовая часть (MD): "L a-b / total" между разделителями + "pct%" справа.
|
||||||
* Перезаписывает ТОЛЬКО области между/после разделителей, сами │ и фикс.
|
* Перезаписывает ТОЛЬКО области между/после разделителей, сами │ и фикс.
|
||||||
* хром не трогает. */
|
* хром не трогает. */
|
||||||
void render_md_status_numbers(void)
|
void render_md_status_numbers(void)
|
||||||
{
|
{
|
||||||
static uint16_t local_total = UINT_MAX;
|
|
||||||
static uint16_t local_last = UINT_MAX;
|
|
||||||
static uint8_t local_loading = UCHAR_MAX;
|
|
||||||
|
|
||||||
uint16_t total = drawable_lines();
|
uint16_t total = drawable_lines();
|
||||||
uint16_t last = top_line + VIEW_H;
|
uint16_t last = top_line + VIEW_H;
|
||||||
if (last > total)
|
if (last > total)
|
||||||
@@ -113,12 +114,12 @@ void render_md_status_numbers(void)
|
|||||||
/* Полное обновление переменной части (MD): кодировка + числа. */
|
/* Полное обновление переменной части (MD): кодировка + числа. */
|
||||||
void render_full_status(void)
|
void render_full_status(void)
|
||||||
{
|
{
|
||||||
|
local_loading = UCHAR_MAX;
|
||||||
status_encoding();
|
status_encoding();
|
||||||
render_md_status_numbers();
|
render_md_status_numbers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_percent_progress(uint8_t pct) {
|
void render_percent_progress(uint8_t pct) {
|
||||||
static uint8_t local_pct = UCHAR_MAX;
|
|
||||||
if (local_pct != pct) {
|
if (local_pct != pct) {
|
||||||
local_pct = pct;
|
local_pct = pct;
|
||||||
gotoxy(DIV2_X + 2, 0);
|
gotoxy(DIV2_X + 2, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user