#include "aplos.h" #define FOREGROUND 0x442A13 #define BACKGROUND 0xE3DFD7 static struct framebuffer *fb; static volatile uint32_t *fb_mem; static uint32_t row; static uint32_t col; static void screen_clear(void); static int print_fmt(char8_t *, va_list); void screen_init(struct framebuffer *framebuffer) { fb = framebuffer; fb_mem = fb->addr; screen_clear(); font_init(); } void screen_draw_pixel(uint32_t x, uint32_t y, uint32_t c) { fb_mem[x + y * (fb->pitch/4)] = c; } void print(char8_t *fmt, ...) { va_list args; va_start(args, fmt); int n; for(char8_t *p = fmt; *p; p += utf8_char_length(p)){ switch(*p){ default: print_char: font_draw(p, row, col, BACKGROUND, FOREGROUND); col++; break; case '\n': row++; col = 0; break; case '%': n = print_fmt(p, args); if(n == 0) goto print_char; while(n-- > 1) p += utf8_char_length(p); break; } } va_end(args); } static void screen_clear(void) { for(uint64_t y = 0; y < fb->height; y++){ for(uint64_t x = 0; x < fb->width; x++){ fb_mem[x + y * (fb->pitch/4)] = BACKGROUND; } } } static int print_fmt(char8_t *fmt, va_list args) { char8_t digits[] = u8"0123456789ABCDEF"; char8_t *prefixes[17] = {0}; char8_t buf[65]; char8_t *p = &buf[nelem(buf)-1]; prefixes[2] = u8"0b"; prefixes[8] = u8"0o"; prefixes[16] = u8"0x"; *p = 0; #define UINT(spec, n, base, min, type) \ if(utf8_cmp_n(fmt, spec, 2+n) == 0){ \ type v = va_arg(args, type); \ int w = min; \ do{ \ p--; \ *p = digits[v%base]; \ v = v / base; \ if(w) \ w--; \ }while(v || w); \ if(prefixes[base]) \ print(prefixes[base]); \ print(p); \ return 2+n; \ } #define UINTS(bits, n, type) \ UINT(u8"%b" #bits, n, 2, 0, type) \ UINT(u8"%o" #bits, n, 8, 0, type) \ UINT(u8"%u" #bits, n, 10, 0, type) \ UINT(u8"%x" #bits, n, 16, 0, type) \ UINTS(64, 2, uint64_t); UINTS(32, 2, uint32_t); UINTS(16, 2, int); UINTS(8, 1, int); UINT(u8"%p", 0, 16, 16, uintptr_t); return 0; }