рисовашк bmp

This commit is contained in:
msh356 2026-07-19 16:31:54 +03:00
parent cff663028a
commit e68f41f652
7 changed files with 98 additions and 10 deletions

View file

@ -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)

View file

@ -23,7 +23,7 @@ ZalupaCalc 2 - это инновационная операционная сис
- [x] Вывод на экран попиксельно
- [x] Вывод на экран прямоугольников и прочих фигур
- [ ] Вывод на экран BMP
- [x] Вывод на экран BMP
- [ ] Вывод на экран текста
- [ ] Двойная буферизация
- [ ] Вывод курсора мыши на экран, движение

BIN
assets/bg.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

BIN
assets/cursor.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

View file

@ -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);
}
}
}
}

View file

@ -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

View file

@ -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;