рисовашк текст
This commit is contained in:
parent
e68f41f652
commit
94b03ee1f3
7 changed files with 185 additions and 37 deletions
|
|
@ -24,7 +24,7 @@ ZalupaCalc 2 - это инновационная операционная сис
|
|||
- [x] Вывод на экран попиксельно
|
||||
- [x] Вывод на экран прямоугольников и прочих фигур
|
||||
- [x] Вывод на экран BMP
|
||||
- [ ] Вывод на экран текста
|
||||
- [x] Вывод на экран текста
|
||||
- [ ] Двойная буферизация
|
||||
- [ ] Вывод курсора мыши на экран, движение
|
||||
- [ ] Кнопки (touch zones, массив в памяти где будут координаты областей и действия при нажатии)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "multiboot.h"
|
||||
#include "serial.h"
|
||||
#include "vmm.h" // Для маппинга
|
||||
#include "font.h"
|
||||
#define TRANSPARENT_COLOR 0xFF00FF
|
||||
|
||||
uint32_t* fb_ptr = 0;
|
||||
|
|
@ -132,3 +133,35 @@ void draw_cursor_sprite(uint8_t* bmp_data, int x, int y) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void put_char(char c, int x, int y, uint32_t color) {
|
||||
if (c < 32 || c > 126) c = 32; // Если символ вне диапазона — рисуем пробел
|
||||
|
||||
const uint8_t* glyph = font8x8[c - 32];
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
// Если бит в строке установлен — рисуем пиксель
|
||||
if (glyph[i] & (1 << (7 - j))) {
|
||||
put_pixel(x + j, y + i, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw_string(const char* str, int x, int y, uint32_t color) {
|
||||
int cursor_x = x;
|
||||
int cursor_y = y;
|
||||
|
||||
while (*str != '\0') {
|
||||
// Если встретили символ переноса строки
|
||||
if (*str == '\n') {
|
||||
cursor_x = x;
|
||||
cursor_y += 10; // 8 пикселей высота буквы + 2 пикселя отступ
|
||||
} else {
|
||||
put_char(*str, cursor_x, cursor_y, color);
|
||||
cursor_x += 9; // 8 пикселей ширина буквы + 1 пиксель пробел между ними
|
||||
}
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,5 +15,7 @@ void draw_rect(int x, int y, int w, int h, uint32_t color);
|
|||
void clear_screen(uint32_t color);
|
||||
void draw_bmp(uint8_t* data, int x, int y);
|
||||
void draw_cursor_sprite(uint8_t* bmp_data, int x, int y);
|
||||
void put_char(char c, int x, int y, uint32_t color);
|
||||
void draw_string(const char* str, int x, int y, uint32_t color);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
99
src/font.c
Normal file
99
src/font.c
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
#include <stdint.h>
|
||||
|
||||
const uint8_t font8x8[95][8] = {
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 32
|
||||
{0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00}, // 33 !
|
||||
{0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00}, // 34 "
|
||||
{0x66, 0x66, 0xFF, 0x66, 0xFF, 0x66, 0x66, 0x00}, // 35 #
|
||||
{0x18, 0x7E, 0xFF, 0x1B, 0x1B, 0x1B, 0x1B, 0x00}, // 36 $
|
||||
{0x63, 0x66, 0x0C, 0x18, 0x30, 0x66, 0x63, 0x00}, // 37 %
|
||||
{0x3C, 0x66, 0x3C, 0x6B, 0x33, 0x66, 0x3C, 0x00}, // 38 &
|
||||
{0x06, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00}, // 39 '
|
||||
{0x0C, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00}, // 40 (
|
||||
{0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00}, // 41 )
|
||||
{0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // 42 *
|
||||
{0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00}, // 43 +
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30}, // 44 ,
|
||||
{0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00}, // 45 -
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00}, // 46 .
|
||||
{0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00}, // 47 /
|
||||
{0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00}, // 48 0
|
||||
{0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00}, // 49 1
|
||||
{0x3C, 0x66, 0x06, 0x1C, 0x30, 0x66, 0x7E, 0x00}, // 50 2
|
||||
{0x3C, 0x66, 0x06, 0x1C, 0x06, 0x66, 0x3C, 0x00}, // 51 3
|
||||
{0x0C, 0x1C, 0x3C, 0x6C, 0x7E, 0x0C, 0x0C, 0x00}, // 52 4
|
||||
{0x7E, 0x60, 0x7C, 0x06, 0x06, 0x66, 0x3C, 0x00}, // 53 5
|
||||
{0x3C, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x3C, 0x00}, // 54 6
|
||||
{0x7E, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00}, // 55 7
|
||||
{0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00}, // 56 8
|
||||
{0x3C, 0x66, 0x66, 0x7C, 0x06, 0x66, 0x3C, 0x00}, // 57 9
|
||||
{0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00}, // 58 :
|
||||
{0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30}, // 59 ;
|
||||
{0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x00}, // 60 <
|
||||
{0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00}, // 61 =
|
||||
{0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x00}, // 62 >
|
||||
{0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00}, // 63 ?
|
||||
{0x3C, 0x66, 0x76, 0x76, 0x76, 0x60, 0x3C, 0x00}, // 64 @
|
||||
{0x18, 0x3C, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x00}, // 65 A
|
||||
{0x7C, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x7C, 0x00}, // 66 B
|
||||
{0x3C, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3C, 0x00}, // 67 C
|
||||
{0x78, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0x78, 0x00}, // 68 D
|
||||
{0x7E, 0x60, 0x60, 0x78, 0x60, 0x60, 0x7E, 0x00}, // 69 E
|
||||
{0x7E, 0x60, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00}, // 70 F
|
||||
{0x3C, 0x66, 0x60, 0x6E, 0x66, 0x66, 0x3C, 0x00}, // 71 G
|
||||
{0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00}, // 72 H
|
||||
{0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00}, // 73 I
|
||||
{0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C, 0x38, 0x00}, // 74 J
|
||||
{0x66, 0x6C, 0x78, 0x70, 0x78, 0x6C, 0x66, 0x00}, // 75 K
|
||||
{0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7E, 0x00}, // 76 L
|
||||
{0x63, 0x77, 0x7F, 0x6B, 0x63, 0x63, 0x63, 0x00}, // 77 M
|
||||
{0x63, 0x73, 0x7B, 0x6F, 0x67, 0x63, 0x63, 0x00}, // 78 N
|
||||
{0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00}, // 79 O
|
||||
{0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x00}, // 80 P
|
||||
{0x3C, 0x66, 0x66, 0x66, 0x76, 0x3C, 0x0E, 0x00}, // 81 Q
|
||||
{0x7C, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0x66, 0x00}, // 82 R
|
||||
{0x3C, 0x66, 0x60, 0x3C, 0x06, 0x66, 0x3C, 0x00}, // 83 S
|
||||
{0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00}, // 84 T
|
||||
{0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00}, // 85 U
|
||||
{0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00}, // 86 V
|
||||
{0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // 87 W
|
||||
{0x66, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00}, // 88 X
|
||||
{0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00}, // 89 Y
|
||||
{0x7E, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x7E, 0x00}, // 90 Z
|
||||
{0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00}, // 91 [
|
||||
{0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // 92 \
|
||||
{0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0x00}, // 93 ]
|
||||
{0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00}, // 94 ^
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // 95 _
|
||||
{0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00}, // 96 `
|
||||
{0x00, 0x00, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0x00}, // 97 a
|
||||
{0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x7C, 0x00}, // 98 b
|
||||
{0x00, 0x00, 0x3C, 0x66, 0x60, 0x66, 0x3C, 0x00}, // 99 c
|
||||
{0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x3B, 0x00}, // 100 d
|
||||
{0x00, 0x00, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00}, // 101 e
|
||||
{0x1C, 0x36, 0x30, 0x78, 0x30, 0x30, 0x30, 0x00}, // 102 f
|
||||
{0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x3C}, // 103 g
|
||||
{0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00}, // 104 h
|
||||
{0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00}, // 105 i
|
||||
{0x0C, 0x00, 0x1C, 0x0C, 0x0C, 0x0C, 0x6C, 0x38}, // 106 j
|
||||
{0x60, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0x00}, // 107 k
|
||||
{0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00}, // 108 l
|
||||
{0x00, 0x00, 0x6C, 0xFE, 0xFE, 0xD6, 0xC6, 0x00}, // 109 m
|
||||
{0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00}, // 110 n
|
||||
{0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00}, // 111 o
|
||||
{0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60}, // 112 p
|
||||
{0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x06}, // 113 q
|
||||
{0x00, 0x00, 0x6E, 0x76, 0x60, 0x60, 0x60, 0x00}, // 114 r
|
||||
{0x00, 0x00, 0x3C, 0x60, 0x3C, 0x06, 0x3C, 0x00}, // 115 s
|
||||
{0x30, 0x30, 0x7C, 0x30, 0x30, 0x36, 0x1C, 0x00}, // 116 t
|
||||
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3B, 0x00}, // 117 u
|
||||
{0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00}, // 118 v
|
||||
{0x00, 0x00, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // 119 w
|
||||
{0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00}, // 120 x
|
||||
{0x00, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x3C}, // 121 y
|
||||
{0x00, 0x00, 0x7E, 0x0C, 0x18, 0x30, 0x7E, 0x00}, // 122 z
|
||||
{0x0E, 0x18, 0x18, 0x18, 0x3C, 0x18, 0x18, 0x0E}, // 123 {
|
||||
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, // 124 |
|
||||
{0x70, 0x18, 0x18, 0x18, 0x3C, 0x18, 0x18, 0x70}, // 125 }
|
||||
{0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // 126 ~
|
||||
};
|
||||
10
src/font.h
Normal file
10
src/font.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
// font.h
|
||||
#ifndef FONT_H
|
||||
#define FONT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Массив содержит 95 символов (от пробела до '~'), каждый по 8 байт
|
||||
extern const uint8_t font8x8[95][8];
|
||||
|
||||
#endif
|
||||
27
src/kmain.c
27
src/kmain.c
|
|
@ -22,6 +22,10 @@ extern uint8_t _binary_assets_logo_bmp_start[];
|
|||
extern uint8_t _binary_assets_bg_bmp_start[];
|
||||
extern uint8_t _binary_assets_cursor_bmp_start[];
|
||||
|
||||
uint32_t frame_count = 0; // Сколько раз отрисовали за секунду
|
||||
uint32_t last_fps_ticks = 0; // Когда последний раз обновляли FPS
|
||||
uint32_t current_fps = 0; // Результат (число FPS)
|
||||
|
||||
extern uint32_t _kernel_end; // Символ 'end' прописан в конце любого стандартного linker.ld
|
||||
uint32_t kernel_end = (uint32_t)&_kernel_end;
|
||||
|
||||
|
|
@ -199,16 +203,25 @@ void kernel_main(uint32_t mboot_addr, uint32_t magic) {
|
|||
log_info(LOG_NORMAL, "OK!");
|
||||
int old_mouse_x = 0;
|
||||
int old_mouse_y = 0;
|
||||
char fpsbuf[4];
|
||||
while (1) {
|
||||
if (mouse_x != old_mouse_x || mouse_y != old_mouse_y) {
|
||||
// Стираем старый
|
||||
draw_bmp(_binary_assets_bg_bmp_start, 0, 0);
|
||||
// 1. Всегда рисуем фон и элементы
|
||||
draw_bmp(_binary_assets_bg_bmp_start, 0, 0);
|
||||
draw_cursor_sprite(_binary_assets_cursor_bmp_start, mouse_x, mouse_y);
|
||||
|
||||
// Рисуем новый
|
||||
draw_cursor_sprite(_binary_assets_cursor_bmp_start, mouse_x, mouse_y);
|
||||
// 2. Всегда рисуем FPS
|
||||
draw_string("FPS: ", 0, 0, color_white);
|
||||
itoa(current_fps, fpsbuf, 10);
|
||||
draw_string(fpsbuf, 40, 0, color_white);
|
||||
|
||||
old_mouse_x = mouse_x;
|
||||
old_mouse_y = mouse_y;
|
||||
// 3. Считаем кадр
|
||||
frame_count++;
|
||||
|
||||
// 4. Логика обновления FPS (раз в секунду)
|
||||
if (system_ticks - last_fps_ticks >= 100) {
|
||||
current_fps = frame_count;
|
||||
frame_count = 0;
|
||||
last_fps_ticks = system_ticks;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
45
src/string.c
45
src/string.c
|
|
@ -116,52 +116,43 @@ int atoi(const char* str) {
|
|||
// Число в строку (поддерживает base = 10 и base = 2)
|
||||
char* itoa(int value, char* str, int base) {
|
||||
int i = 0;
|
||||
|
||||
// Используем unsigned, чтобы безопасно обрабатывать MIN_INT
|
||||
unsigned int n;
|
||||
int is_negative = 0;
|
||||
|
||||
// Защита от дурака
|
||||
if (base < 2 || base > 36) {
|
||||
str[0] = '\0';
|
||||
return str;
|
||||
if (base < 2 || base > 36) { str[0] = '\0'; return str; }
|
||||
|
||||
if (value < 0 && base == 10) {
|
||||
is_negative = 1;
|
||||
n = (unsigned int)(-value); // Приводим к unsigned перед инверсией
|
||||
} else {
|
||||
n = (unsigned int)value;
|
||||
}
|
||||
|
||||
// Обрабатываем 0
|
||||
if (value == 0) {
|
||||
if (n == 0) {
|
||||
str[i++] = '0';
|
||||
str[i] = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
// Отрицательные числа обрабатываем только для десятичной системы
|
||||
if (value < 0 && base == 10) {
|
||||
is_negative = 1;
|
||||
value = -value;
|
||||
}
|
||||
|
||||
// Переводим число в строку (но она получится задом наперед)
|
||||
while (value != 0) {
|
||||
int rem = value % base;
|
||||
while (n != 0) {
|
||||
int rem = n % base;
|
||||
str[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
|
||||
value = value / base;
|
||||
}
|
||||
|
||||
// Добавляем минус
|
||||
if (is_negative) {
|
||||
str[i++] = '-';
|
||||
n /= base;
|
||||
}
|
||||
|
||||
if (is_negative) str[i++] = '-';
|
||||
str[i] = '\0';
|
||||
|
||||
// Переворачиваем строку в нормальный вид
|
||||
int start = 0;
|
||||
int end = i - 1;
|
||||
// Разворот (этот кусок у тебя верный)
|
||||
int start = 0, end = i - 1;
|
||||
while (start < end) {
|
||||
char temp = str[start];
|
||||
str[start] = str[end];
|
||||
str[end] = temp;
|
||||
start++;
|
||||
end--;
|
||||
start++; end--;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue