#include #include #include namespace hilbert::kernel::framebuffer { static uint64_t paddr; static uint32_t *vaddr; int width; int height; static int dword_pitch; void encode_color_syscall( uint64_t &rax, uint64_t &rdi, uint64_t &rsi, uint64_t &rdx ) { rax = (uint64_t)encode_color( rdi & 0xff, (rdi >> 8) & 0xff, (rdi >> 16) & 0xff); rdi = 0; rsi = 0; rdx = 0; } void get_framebuffer_syscall( uint64_t &rax, uint64_t &rdi, uint64_t &rsi, uint64_t &rdx ) { auto *app = application::running_app; if (app->framebuffer_vaddr == 0) { uint64_t pages_needed = (dword_pitch * height * 4 - 1) / 4096 + 1; uint64_t vaddr = app->get_free_vaddr_pages(pages_needed); for (uint64_t i = 0; i < pages_needed; ++i) app->map_page(vaddr + i * 4096, paddr + i * 4096, true, false, false); app->framebuffer_vaddr = vaddr; } rax = app->framebuffer_vaddr; rdi = (uint64_t)(uint32_t)width | ((uint64_t)(uint32_t)height << 32); rsi = (uint32_t)dword_pitch; rdx = 0; } void init_framebuffer(uint64_t paddr, uint64_t vaddr, uint64_t width, uint64_t height, uint64_t pitch ) { //TODO: assumes 32-bpp rgb framebuffer::paddr = paddr; framebuffer::vaddr = (uint32_t *)vaddr; framebuffer::width = width; framebuffer::height = height; dword_pitch = pitch / 4; syscall::add_syscall(0, &encode_color_syscall); syscall::add_syscall(1, &get_framebuffer_syscall); } color encode_color(uint8_t r, uint8_t g, uint8_t b) { return ((uint32_t)r << 16) | ((uint32_t)g << 8) | (uint32_t)b; } void set_pixel(int x, int y, color c) { vaddr[y * dword_pitch + x] = c; } void move_region( int from_start_x, int from_start_y, int from_end_x, int from_end_y, int to_start_x, int to_start_y ) { int region_width = from_end_x - from_start_x; int region_height = from_end_y - from_start_y; int from_start_offset = from_start_y * dword_pitch + from_start_x; int to_start_offset = to_start_y * dword_pitch + to_start_x; if (from_start_offset > to_start_offset) for (int y = 0; y < region_height; ++y) for (int x = 0; x < region_width; ++x) vaddr[to_start_offset + y * dword_pitch + x] = vaddr[from_start_offset + y * dword_pitch + x]; else if (from_start_offset < to_start_offset) for (int y = region_height - 1; y >= 0; --y) for (int x = region_width - 1; x >= 0; --x) vaddr[to_start_offset + y * dword_pitch + x] = vaddr[from_start_offset + y * dword_pitch + x]; } void fill_region(int start_x, int start_y, int end_x, int end_y, color c) { for (int y = start_y; y < end_y; ++y) for (int x = start_x; x < end_x; ++x) vaddr[y * dword_pitch + x] = c; } }