добавлена графика
This commit is contained in:
parent
417bcb30ef
commit
7573ae15a0
7 changed files with 141 additions and 16 deletions
|
|
@ -21,8 +21,8 @@ ZalupaCalc 2 - это инновационная операционная сис
|
|||
|
||||
### 2. Графика
|
||||
|
||||
- [ ] Вывод на экран попиксельно
|
||||
- [ ] Вывод на экран прямоугольников и прочих фигур
|
||||
- [x] Вывод на экран попиксельно
|
||||
- [x] Вывод на экран прямоугольников и прочих фигур
|
||||
- [ ] Вывод на экран текста
|
||||
- [ ] Двойная буферизация
|
||||
- [ ] Вывод курсора мыши на экран, движение
|
||||
|
|
|
|||
54
src/drawing.c
Normal file
54
src/drawing.c
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#include "drawing.h"
|
||||
#include "multiboot.h"
|
||||
#include "serial.h"
|
||||
#include "vmm.h" // Для маппинга
|
||||
|
||||
uint32_t* fb_ptr = 0;
|
||||
uint32_t screen_width = 0;
|
||||
uint32_t screen_height = 0;
|
||||
|
||||
void draw_init(struct multiboot_info* mbi) {
|
||||
if (!(mbi->flags & (1 << 12))) {
|
||||
kprint_serial("DRAWING: NO FRAMEBUFFER!");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t fb_phys = (uint32_t)mbi->framebuffer_addr;
|
||||
uint32_t width = mbi->framebuffer_width;
|
||||
uint32_t height = mbi->framebuffer_height;
|
||||
|
||||
// Считаем размер и мапим сразу внутри
|
||||
uint32_t size = width * height * 4;
|
||||
uint32_t num_pages = (size + 0xFFF) / 0x1000;
|
||||
|
||||
for (uint32_t i = 0; i < num_pages; i++) {
|
||||
vmm_map_page(fb_phys + (i * 0x1000),
|
||||
fb_phys + (i * 0x1000),
|
||||
0x3 | 0x10); // Present + RW + PCD
|
||||
}
|
||||
|
||||
// Сохраняем в глобальные переменные модуля
|
||||
fb_ptr = (uint32_t*)fb_phys;
|
||||
screen_width = width;
|
||||
screen_height = height;
|
||||
}
|
||||
|
||||
void put_pixel(int x, int y, uint32_t color) {
|
||||
if (x >= 0 && x < (int)screen_width && y >= 0 && y < (int)screen_height) {
|
||||
fb_ptr[y * screen_width + x] = color;
|
||||
}
|
||||
}
|
||||
|
||||
void draw_rect(int x, int y, int w, int h, uint32_t color) {
|
||||
for (int i = y; i < y + h; i++) {
|
||||
for (int j = x; j < x + w; j++) {
|
||||
put_pixel(j, i, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clear_screen(uint32_t color) {
|
||||
for (uint32_t i = 0; i < screen_width * screen_height; i++) {
|
||||
fb_ptr[i] = color;
|
||||
}
|
||||
}
|
||||
17
src/drawing.h
Normal file
17
src/drawing.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef DRAWING_H
|
||||
#define DRAWING_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "multiboot.h"
|
||||
|
||||
// Основные параметры экрана (можно заполнять динамически из multiboot)
|
||||
extern uint32_t* fb_ptr;
|
||||
extern uint32_t screen_width;
|
||||
extern uint32_t screen_height;
|
||||
|
||||
void draw_init(struct multiboot_info* mbi);
|
||||
void put_pixel(int x, int y, uint32_t color);
|
||||
void draw_rect(int x, int y, int w, int h, uint32_t color);
|
||||
void clear_screen(uint32_t color);
|
||||
|
||||
#endif
|
||||
44
src/kmain.c
44
src/kmain.c
|
|
@ -1,4 +1,5 @@
|
|||
#include "serial.h"
|
||||
#include "drawing.h"
|
||||
#include "mouse.h"
|
||||
#include "timer.h"
|
||||
#include "speaker.h"
|
||||
|
|
@ -12,6 +13,12 @@
|
|||
#include "string.h"
|
||||
#include "multiboot.h"
|
||||
|
||||
uint32_t bg_color = 0x00008080;
|
||||
uint32_t color_sky_blue = 0x0087CEEB;
|
||||
uint32_t color_orange = 0x00FFA500;
|
||||
uint32_t color_white = 0x00FFFFFF;
|
||||
uint32_t color_black = 0x00000000;
|
||||
|
||||
extern uint32_t _kernel_end; // Символ 'end' прописан в конце любого стандартного linker.ld
|
||||
uint32_t kernel_end = (uint32_t)&_kernel_end;
|
||||
|
||||
|
|
@ -153,6 +160,26 @@ void kernel_main(uint32_t mboot_addr, uint32_t magic) {
|
|||
kfree(arr2);
|
||||
|
||||
kprint_serial("Kfree done. It don't died twice!\n");
|
||||
if (mbi->flags & (1 << 12)) {
|
||||
log_info(LOG_NORMAL, "Framebuffer detected!");
|
||||
|
||||
uint32_t fb_addr = mbi->framebuffer_addr;
|
||||
uint32_t width = mbi->framebuffer_width;
|
||||
uint32_t height = mbi->framebuffer_height;
|
||||
uint32_t bpp = mbi->framebuffer_bpp;
|
||||
|
||||
char buf[16];
|
||||
kprint_serial("FB Addr: ");
|
||||
kprint_serial_hex(fb_addr);
|
||||
kprint_serial("\nSize: ");
|
||||
kprint_serial_dec(width);
|
||||
kprint_serial("x");
|
||||
kprint_serial_dec(height);
|
||||
kprint_serial("\n");
|
||||
draw_init(mbi);
|
||||
} else {
|
||||
log_error(LOG_NORMAL, "No Framebuffer provided by GRUB!");
|
||||
}
|
||||
log_info(LOG_NORMAL, "Enabling IRQ...");
|
||||
__asm__ __volatile__("sti");
|
||||
speaker_beep(100, 10);
|
||||
|
|
@ -167,5 +194,20 @@ void kernel_main(uint32_t mboot_addr, uint32_t magic) {
|
|||
speaker_beep(325, 10);
|
||||
speaker_beep(350, 400);
|
||||
log_info(LOG_NORMAL, "OK!");
|
||||
while (1);
|
||||
clear_screen(bg_color);
|
||||
int old_mouse_x = 0;
|
||||
int old_mouse_y = 0;
|
||||
while (1) {
|
||||
if (mouse_x != old_mouse_x || mouse_y != old_mouse_y) {
|
||||
// Стираем старый
|
||||
draw_rect(old_mouse_x - 5, old_mouse_y - 5, 10, 10, bg_color);
|
||||
|
||||
// Рисуем новый
|
||||
int color = left_click ? color_orange : (right_click ? color_sky_blue : color_white);
|
||||
draw_rect(mouse_x - 5, mouse_y - 5, 10, 10, color);
|
||||
|
||||
old_mouse_x = mouse_x;
|
||||
old_mouse_y = mouse_y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
15
src/mouse.c
15
src/mouse.c
|
|
@ -62,8 +62,10 @@ void mouse_init(void) {
|
|||
|
||||
static uint8_t mouse_cycle = 0;
|
||||
static uint8_t mouse_packet[3];
|
||||
static int mouse_x = 40; // Стартуем по центру текстового экрана 80x25
|
||||
static int mouse_y = 12;
|
||||
volatile int mouse_x = 200;
|
||||
volatile int mouse_y = 200;
|
||||
volatile int left_click = 0;
|
||||
volatile int right_click = 0;
|
||||
|
||||
void mouse_handler(void) {
|
||||
uint8_t status = inb(PS2_STATUS);
|
||||
|
|
@ -99,15 +101,14 @@ void mouse_handler(void) {
|
|||
mouse_x += offset_x;
|
||||
mouse_y -= offset_y; // Инвертируем Y, так как в VGA координатах 0 верх
|
||||
|
||||
// Ограничиваем рамками консоли 80x25
|
||||
if (mouse_x < 0) mouse_x = 0;
|
||||
if (mouse_x >= 80) mouse_x = 79;
|
||||
if (mouse_x >= 1024) mouse_x = 1023;
|
||||
if (mouse_y < 0) mouse_y = 0;
|
||||
if (mouse_y >= 25) mouse_y = 24;
|
||||
if (mouse_y >= 768) mouse_y = 767;
|
||||
|
||||
// Чек кнопок
|
||||
int left_click = flags & 0x01;
|
||||
int right_click = flags & 0x02;
|
||||
left_click = flags & 0x01;
|
||||
right_click = flags & 0x02;
|
||||
|
||||
// Выводим инфу в UART через itoa
|
||||
char buf[16];
|
||||
|
|
|
|||
|
|
@ -3,6 +3,11 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
extern volatile int mouse_x;
|
||||
extern volatile int mouse_y;
|
||||
extern volatile int left_click;
|
||||
extern volatile int right_click;
|
||||
|
||||
void mouse_init(void);
|
||||
void mouse_handler(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,12 +25,9 @@ struct multiboot_info {
|
|||
uint32_t cmdline;
|
||||
uint32_t mods_count;
|
||||
uint32_t mods_addr;
|
||||
uint32_t num;
|
||||
uint32_t size;
|
||||
uint32_t addr;
|
||||
uint32_t shndx;
|
||||
uint32_t syms[4];
|
||||
uint32_t mmap_length;
|
||||
uint32_t mmap_addr; // <-- Вот это нам нужно! Адрес карты памяти
|
||||
uint32_t mmap_addr;
|
||||
uint32_t drives_length;
|
||||
uint32_t drives_addr;
|
||||
uint32_t config_table;
|
||||
|
|
@ -42,6 +39,15 @@ struct multiboot_info {
|
|||
uint16_t vbe_interface_seg;
|
||||
uint16_t vbe_interface_off;
|
||||
uint16_t vbe_interface_len;
|
||||
} __attribute__((packed));
|
||||
|
||||
// ДОБАВЬ ЭТИ ПОЛЯ САМ, ЕСЛИ ИХ НЕТ:
|
||||
uint64_t framebuffer_addr;
|
||||
uint32_t framebuffer_pitch;
|
||||
uint32_t framebuffer_width;
|
||||
uint32_t framebuffer_height;
|
||||
uint8_t framebuffer_bpp;
|
||||
uint8_t framebuffer_type;
|
||||
uint16_t framebuffer_color_info;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue