// Defines the colors that a terminal is expected to implement. // These are the classical VGA colors. export type color = enum { BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LGRAY, DGRAY, LBLUE, LGREEN, LCYAN, LRED, YELLOW, LMAGENTA, WHITE }; export type vtable = struct { setpos: *fn(_: *term, _: (size, size)) void, getpos: *fn(_: *term) (size, size), setcolors: *fn(_: *term, _: (color, color)) void, getcolors: *fn(_: *term) (color, color), putchar: *fn(_: *term, _: u8) void, getdim: *fn(_: *term) (size, size), }; export type term = *vtable; export fn setpos(ctrl: *term, pos: (size, size)) void = { ctrl.setpos(ctrl, pos); }; export fn getpos(ctrl: *term) (size, size) = { return ctrl.getpos(ctrl); }; export fn setcolors(ctrl: *term, colors: (color, color)) void = { ctrl.setcolors(ctrl, colors); }; export fn getcolors(ctrl: *term) (color, color) = { return ctrl.getcolors(ctrl); }; export fn putchar(ctrl: *term, c: u8) void = { ctrl.putchar(ctrl, c); }; export fn getdim(ctrl: *term) (size, size) = { return ctrl.getdim(ctrl); }; fn advancex(ctrl: *term) void = { let dim = getdim(ctrl); let pos = getpos(ctrl); pos.0 += 1; if (pos.0 >= dim.0) { newline(ctrl); } else { setpos(ctrl, pos); }; }; fn newline(ctrl: *term) void = { let dim = getdim(ctrl); let pos = getpos(ctrl); pos.0 = 0; pos.1 += 1; if (pos.1 >= dim.1) { clear(ctrl); setpos(ctrl, (0, 0)); } else { setpos(ctrl, pos); }; }; fn carriage(ctrl: *term) void = { let pos = getpos(ctrl); pos.0 = 0; setpos(ctrl, pos); }; export fn print(ctrl: *term, msg: str) void = { let msg = *(&msg: *[]u8); for (let i = 0z; i < len(msg); i += 1) { switch (msg[i]) { case '\n' => newline(ctrl); case '\r' => carriage(ctrl); case => putchar(ctrl, msg[i]); advancex(ctrl); }; }; }; export fn clear(ctrl: *term) void = { let colors = getcolors(ctrl); setcolors(ctrl, (colors.1, colors.1)); let dim = getdim(ctrl); let pos = getpos(ctrl); for (let j = 0z; j < dim.1; j += 1) { for (let i = 0z; i < dim.0; i += 1) { setpos(ctrl, (i, j)); putchar(ctrl, ' '); }; }; setpos(ctrl, pos); setcolors(ctrl, colors); };