summaryrefslogtreecommitdiff
path: root/src/screen.c
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2025-07-26 16:03:00 +0200
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2025-07-26 16:03:00 +0200
commitf199eae0154f354c37750c8cd3037f94dbfe70db (patch)
tree90938c26bdbe388745a0c3bbd074af92fd49ae13 /src/screen.c
Initial commit
Diffstat (limited to 'src/screen.c')
-rw-r--r--src/screen.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/src/screen.c b/src/screen.c
new file mode 100644
index 0000000..1ce4192
--- /dev/null
+++ b/src/screen.c
@@ -0,0 +1,116 @@
+#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;
+}