рисовашк bmp
This commit is contained in:
parent
cff663028a
commit
e68f41f652
7 changed files with 98 additions and 10 deletions
15
Makefile
15
Makefile
|
|
@ -12,18 +12,23 @@ CFLAGS = -m32 -ffreestanding -O2 -Wall -Wextra \
|
|||
-I./src
|
||||
ASFLAGS = -f elf32
|
||||
LDFLAGS = -m elf_i386 -T linker.ld -nostdlib
|
||||
|
||||
BMP_FILES := $(wildcard assets/*.bmp)
|
||||
BMP_OBJS := $(patsubst assets/%.bmp, assets/%.o, $(BMP_FILES))
|
||||
# Файлы
|
||||
SOURCES = $(wildcard src/*.c)
|
||||
ASM_SOURCES = $(wildcard src/*.asm)
|
||||
OBJECTS = src/boot.o $(SOURCES:.c=.o) $(ASM_SOURCES:.asm=.o)
|
||||
OBJECTS = $(patsubst %.c,%.o,$(wildcard src/*.c)) $(patsubst %.asm,%.o,$(wildcard src/*.asm))
|
||||
TARGET = kernel.bin
|
||||
|
||||
all: $(TARGET) iso
|
||||
|
||||
assets/%.o: assets/%.bmp
|
||||
@mkdir -p assets
|
||||
objcopy -I binary -O elf32-i386 -B i386 $< $@
|
||||
|
||||
# Сборка ядра
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(LD) $(LDFLAGS) -o $@ $^
|
||||
$(TARGET): $(OBJECTS) $(BMP_OBJS)
|
||||
$(LD) $(LDFLAGS) -o $@ $(OBJECTS) $(BMP_OBJS)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
|
@ -41,5 +46,5 @@ run: iso
|
|||
qemu-system-i386 -vga std -cdrom zalupa.iso -serial stdio -monitor none #-d int,cpu_reset -no-reboot -no-shutdown
|
||||
|
||||
clean:
|
||||
rm -f src/*.o $(TARGET) zalupa.iso
|
||||
rm -f src/*.o assets/*.o $(TARGET) zalupa.iso
|
||||
rm -rf iso/boot/$(TARGET)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ ZalupaCalc 2 - это инновационная операционная сис
|
|||
|
||||
- [x] Вывод на экран попиксельно
|
||||
- [x] Вывод на экран прямоугольников и прочих фигур
|
||||
- [ ] Вывод на экран BMP
|
||||
- [x] Вывод на экран BMP
|
||||
- [ ] Вывод на экран текста
|
||||
- [ ] Двойная буферизация
|
||||
- [ ] Вывод курсора мыши на экран, движение
|
||||
|
|
|
|||
BIN
assets/bg.bmp
Normal file
BIN
assets/bg.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 MiB |
BIN
assets/cursor.bmp
Normal file
BIN
assets/cursor.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 822 B |
|
|
@ -2,6 +2,7 @@
|
|||
#include "multiboot.h"
|
||||
#include "serial.h"
|
||||
#include "vmm.h" // Для маппинга
|
||||
#define TRANSPARENT_COLOR 0xFF00FF
|
||||
|
||||
uint32_t* fb_ptr = 0;
|
||||
uint32_t screen_width = 0;
|
||||
|
|
@ -52,3 +53,82 @@ void clear_screen(uint32_t color) {
|
|||
fb_ptr[i] = color;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct bmp_header {
|
||||
uint16_t type;
|
||||
uint32_t size;
|
||||
uint16_t reserved1;
|
||||
uint16_t reserved2;
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
struct dib_header {
|
||||
uint32_t size;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
uint16_t planes;
|
||||
uint16_t bpp;
|
||||
uint32_t compression;
|
||||
uint32_t image_size;
|
||||
int32_t x_ppm;
|
||||
int32_t y_ppm;
|
||||
uint32_t colors_used;
|
||||
uint32_t colors_important;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
void draw_bmp(uint8_t* data, int x, int y) {
|
||||
struct bmp_header* bh = (struct bmp_header*)data;
|
||||
struct dib_header* dh = (struct dib_header*)(data + sizeof(struct bmp_header));
|
||||
|
||||
int w = dh->width;
|
||||
int h = dh->height;
|
||||
|
||||
// 24-битный BMP: каждый ряд выровнен по 4 байтам
|
||||
// Считаем размер ряда в байтах
|
||||
int row_size = (w * 3 + 3) & ~3;
|
||||
uint8_t* pixels = data + bh->offset;
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
// BMP хранятся снизу вверх, поэтому i идет от 0 до h,
|
||||
// а рисуем мы начиная с y + h - 1
|
||||
int draw_y = y + (h - 1 - i);
|
||||
|
||||
for (int j = 0; j < w; j++) {
|
||||
// Берем 3 байта BGR
|
||||
uint8_t* pixel_ptr = pixels + (i * row_size) + (j * 3);
|
||||
uint8_t b = pixel_ptr[0];
|
||||
uint8_t g = pixel_ptr[1];
|
||||
uint8_t r = pixel_ptr[2];
|
||||
|
||||
// Собираем в 0x00RRGGBB
|
||||
uint32_t color = (r << 16) | (g << 8) | b;
|
||||
|
||||
put_pixel(x + j, draw_y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw_cursor_sprite(uint8_t* bmp_data, int x, int y) {
|
||||
struct bmp_header* bh = (struct bmp_header*)bmp_data;
|
||||
struct dib_header* dh = (struct dib_header*)(bmp_data + sizeof(struct bmp_header));
|
||||
|
||||
uint8_t* pixels = bmp_data + bh->offset;
|
||||
int w = dh->width;
|
||||
int h = dh->height;
|
||||
int row_size = (w * 3 + 3) & ~3;
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
int draw_y = y + (h - 1 - i);
|
||||
for (int j = 0; j < w; j++) {
|
||||
uint8_t* p = pixels + (i * row_size) + (j * 3);
|
||||
uint32_t color = (p[2] << 16) | (p[1] << 8) | p[0];
|
||||
|
||||
// Если цвет не прозрачный — рисуем
|
||||
if (color != TRANSPARENT_COLOR) {
|
||||
put_pixel(x + j, draw_y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,5 +13,7 @@ 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);
|
||||
void draw_bmp(uint8_t* data, int x, int y);
|
||||
void draw_cursor_sprite(uint8_t* bmp_data, int x, int y);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@ uint32_t color_sky_blue = 0x0087CEEB;
|
|||
uint32_t color_orange = 0x00FFA500;
|
||||
uint32_t color_white = 0x00FFFFFF;
|
||||
uint32_t color_black = 0x00000000;
|
||||
extern uint8_t _binary_assets_logo_bmp_start[];
|
||||
extern uint8_t _binary_assets_bg_bmp_start[];
|
||||
extern uint8_t _binary_assets_cursor_bmp_start[];
|
||||
|
||||
extern uint32_t _kernel_end; // Символ 'end' прописан в конце любого стандартного linker.ld
|
||||
uint32_t kernel_end = (uint32_t)&_kernel_end;
|
||||
|
|
@ -194,17 +197,15 @@ void kernel_main(uint32_t mboot_addr, uint32_t magic) {
|
|||
speaker_beep(325, 10);
|
||||
speaker_beep(350, 400);
|
||||
log_info(LOG_NORMAL, "OK!");
|
||||
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);
|
||||
draw_bmp(_binary_assets_bg_bmp_start, 0, 0);
|
||||
|
||||
// Рисуем новый
|
||||
int color = left_click ? color_orange : (right_click ? color_sky_blue : color_white);
|
||||
draw_rect(mouse_x - 5, mouse_y - 5, 10, 10, color);
|
||||
draw_cursor_sprite(_binary_assets_cursor_bmp_start, mouse_x, mouse_y);
|
||||
|
||||
old_mouse_x = mouse_x;
|
||||
old_mouse_y = mouse_y;
|
||||
|
|
|
|||
Loading…
Reference in a new issue