154 lines
5.6 KiB
C
154 lines
5.6 KiB
C
/**
|
||
* @file txtlib.h
|
||
* @brief 䇃䇐䈜䈛 для вывода текста в окна WC — динамические буферы и печать строк
|
||
* @version 1.0
|
||
*
|
||
* Зависимости: wc_api.h (wc_prsrw, wc_window_t).
|
||
* Реализация: lib/txtlib.c.
|
||
*
|
||
* Формат буфера:
|
||
* buf[0] = capacity — максимальная емкость в символах (задаётся ОДИН РАЗ при buf_init)
|
||
* buf[1] = len — текущая длина (количество символов)
|
||
* buf[2..] = символы — не завершается \0!
|
||
*
|
||
* Объявление буфера:
|
||
* char work_buf[66]; // capacity = 64 символа
|
||
*
|
||
* Типичное использование:
|
||
* buf_init(work_buf, 64);
|
||
* buf_clear(work_buf);
|
||
* buf_append_str(work_buf, "Time: ");
|
||
* buf_append_u16_dec(work_buf, seconds);
|
||
* print_line(&win, 5, work_buf, WC_COLOR(WC_BLACK, WC_BRIGHT_WHITE));
|
||
*/
|
||
|
||
#ifndef TXTLIB_H
|
||
#define TXTLIB_H
|
||
|
||
#include "wc_api.h"
|
||
|
||
#define FS_SCREEN_COLS 96U /* макс. ширина экрана (90x36, запас) */
|
||
|
||
/**
|
||
* Вернуть (ширина окна - 4) = полезная ширина содержимого.
|
||
* Если win->width == 0, используется FS_SCREEN_COLS.
|
||
*/
|
||
static inline uint8_t get_content_width(const wc_window_t *win) {
|
||
uint8_t w = win->width;
|
||
return (w ? w : FS_SCREEN_COLS) - 4U;
|
||
}
|
||
|
||
/* ================================================================== */
|
||
/* ИНИЦИАЛИЗАЦИЯ И БАЗОВЫЕ ОПЕРАЦИИ */
|
||
/* ================================================================== */
|
||
|
||
/** Инициализировать буфер: записать capacity, len=0. Вызывать ОДИН РАЗ! */
|
||
static inline void buf_init(char *buf, uint8_t capacity) {
|
||
buf[0] = capacity;
|
||
buf[1] = 0;
|
||
}
|
||
|
||
/** Очистить буфер: len=0 (емкость не меняется). */
|
||
static inline void buf_clear(char *buf) {
|
||
buf[1] = 0;
|
||
}
|
||
|
||
/** Вернуть текущую длину буфера (количество символов). */
|
||
static inline uint8_t buf_len(const char *buf) {
|
||
return buf[1];
|
||
}
|
||
|
||
/* ================================================================== */
|
||
/* APPEND */
|
||
/* ================================================================== */
|
||
|
||
/**
|
||
* Добавить строку (\0-terminated) в конец буфера.
|
||
* Тихо усекается при переполнении (len не превышает capacity).
|
||
* @return len после добавления
|
||
*/
|
||
uint8_t buf_append_str(char *buf, const char *src);
|
||
|
||
/**
|
||
* Добавить один символ c в буфер.
|
||
* @return len после добавления
|
||
*/
|
||
uint8_t buf_append_char(char *buf, char c);
|
||
|
||
/**
|
||
* Добавить двухсимвольное hex-представление байта ("00".."FF").
|
||
* @param val значение 0..255
|
||
* @return len после добавления (+2)
|
||
*/
|
||
uint8_t buf_append_u8_hex(char *buf, uint8_t val);
|
||
|
||
/**
|
||
* Добавить uint16 в десятичном формате (без ведущих нулей).
|
||
* @return len после добавления
|
||
*/
|
||
uint8_t buf_append_u16_dec(char *buf, uint16_t val);
|
||
|
||
/**
|
||
* Добавить uint32 в десятичном формате.
|
||
* @return len после добавления
|
||
*/
|
||
uint8_t buf_append_u32_dec(char *buf, uint32_t val);
|
||
|
||
/**
|
||
* Добавить "MM:SS" (5 символов) в буфер. Без деления — вычитание.
|
||
* @param sec секунды (0..5999)
|
||
*/
|
||
void buf_append_mmss(char *buf, uint16_t sec);
|
||
|
||
|
||
/* ================================================================== */
|
||
/* ВЫВОД */
|
||
/* ================================================================== */
|
||
|
||
/**
|
||
* Вывести одну строку из буфера в окно win заполняя до ширины окна.
|
||
* Передаётся атрибут цвета attr (EGA: bg[7:4] | fg[3:0]).
|
||
*
|
||
* @param win окно WC
|
||
* @param y строка внутри окна (1-базированное)
|
||
* @param buf буфер с длиной в buf[1] (формат buf[])
|
||
* @param attr EGA-атрибут: WC_COLOR(bg, fg)
|
||
*/
|
||
void print_line(wc_window_t *win, uint8_t y, const char *buf, uint8_t attr);
|
||
|
||
/* ================================================================== */
|
||
/* ИНИЦИАЛИЗАЦИЯ И ПРИМЕР ИСПОЛЬЗОВАНИЯ */
|
||
/* ================================================================== */
|
||
|
||
/*
|
||
// В начале плагина (например в init)
|
||
char meta_buf[122];
|
||
char work_buf[66]; // 64 символа
|
||
|
||
buf_init(meta_buf, 120);
|
||
buf_init(work_buf, 64); // или больше, если используешь для marquee
|
||
|
||
// Заполнение метаданных
|
||
buf_clear(meta_buf);
|
||
buf_append_str(meta_buf, "Artist - Super Long Track Name 2025 (Remix)");
|
||
|
||
// В цикле отрисовки:
|
||
uint8_t cw = get_content_width(my_win);
|
||
|
||
// Бегущая строка (используем work_buf как временный)
|
||
build_marquee(work_buf, meta_buf + 2, meta_buf[1], scroll_pos, cw);
|
||
print_marquee(my_win, 3, work_buf, 0x0F); // белый
|
||
|
||
scroll_pos++;
|
||
|
||
// Обычная строка (время)
|
||
buf_clear(work_buf);
|
||
buf_append_str(work_buf, "Time: ");
|
||
buf_append_u16_dec(work_buf, minutes);
|
||
buf_append_char(work_buf, ':');
|
||
buf_append_u16_dec(work_buf, seconds);
|
||
print_line(my_win, 5, work_buf, 0x0A);
|
||
*/
|
||
|
||
#endif // TXTLIB_H
|