/* vscreen.c - screen half of the vim editor for the C64 (Power C) * * Draws the text window, the status line and the cursor straight into * the screen matrix at $0400 and colour RAM at $d800. Kept in its own * file because Power C overflows its compiler when the whole editor is * one source. * * This module owns no program state: draw() receives everything it * needs from vim.c as arguments. Sharing variables between Power C * object files proved unreliable, so only functions cross the boundary. */ static char stat[40]; /* status line build buffer */ static int slen; /* ---------- status line text ---------- */ static sclr() { slen = 0; stat[0] = 0; } static sadd(c) char c; { if (slen < 39) { stat[slen] = c; slen = slen + 1; stat[slen] = 0; } } static sstr(s) char *s; { while (*s) { sadd(*s); s = s + 1; } } static snum(n) int n; { char b[6]; int i; if (n < 0) { sadd('-'); n = -n; } if (n == 0) { sadd('0'); return; } i = 0; while (n > 0) { b[i] = '0' + (n % 10); i = i + 1; n = n / 10; } while (i > 0) { i = i - 1; sadd(b[i]); } } /* ---------- PETSCII byte -> screen code ---------- */ static sccode(c) int c; { if (c >= 193 && c <= 218) return c - 192; /* shifted letters $C1-$DA */ if (c >= 96 && c <= 127) return c - 32; if (c >= 64 && c <= 95) return c - 64; /* the C-only characters have no glyph of their own in the ROM */ if (c == 219) return 91; /* { -> [ */ if (c == 221) return 93; /* } -> ] */ if (c == 223) return 94; /* | -> up arrow */ if (c == 175) return 126; /* ~ -> its graphics glyph */ if (c == 164) return 95; /* _ -> left arrow */ return c; } /* ---------- screen output ---------- */ clrscr() { char *s; char *m; int i; s = (char *) 1024; m = (char *) 55296; for (i = 0; i < 1000; i++) { s[i] = 32; m[i] = 1; } } static putchr(x, y, ch, c) int x; int y; int ch; int c; { char *s; char *m; int o; if (x < 0) return; if (x > 39) return; if (y < 0) return; if (y > 24) return; o = y * 40 + x; s = (char *) 1024; m = (char *) 55296; s[o] = ch; m[o] = c; } static putstr(x, y, s, c) int x; int y; char *s; int c; { while (*s && x < 40) { putchr(x, y, sccode(*s), c); x = x + 1; s = s + 1; } } static revchr(o) /* reverse the character in a cell */ int o; { char *s; s = (char *) 1024; if (s[o] < 128) s[o] = s[o] + 128; } /* ---------- buffer scans over the caller's text ---------- */ static lstartx(tp, len, n) /* offset of the first byte of line n */ char *tp; int len; int n; { int i; int c; if (n <= 0) return 0; c = 0; i = 0; while (i < len) { if (tp[i] == 13) { c = c + 1; if (c == n) return i + 1; } i = i + 1; } return len; } static lnofx(tp, cur) /* line holding the cursor */ char *tp; int cur; { int i; int c; c = 0; for (i = 0; i < cur; i++) if (tp[i] == 13) c = c + 1; return c; } /* ---------- full redraw ---------- */ draw(tp, len, cur, md, name, cp, cl, mc) char *tp; int len; int cur; int md; char *name; char *cp; int cl; int mc; { int ln; int top; int r; int i; int to; int c; int cs; int cr; ln = lnofx(tp, cur); top = ln - 11; if (top < 0) top = 0; clrscr(); to = lstartx(tp, len, top); for (r = 0; r < 23; r++) { i = 0; while (to < len && i < 40) { c = tp[to]; if (c == 13) break; putchr(i, r, sccode(c), 1); i = i + 1; to = to + 1; } while (to < len && tp[to] != 13) to = to + 1; if (to < len) to = to + 1; } for (i = 0; i < 40; i++) putchr(i, 24, 32, 11); sclr(); if (md == 1) sstr("INSERT"); else if (md == 2) sstr(": "); else sstr("COMMAND"); sstr(" line "); snum(ln + 1); sstr(" "); sstr(name); if (mc == 1) sstr(" full"); else if (mc == 2) sstr(" save err"); else if (mc == 3) sstr(" saved"); else if (mc == 4) sstr(" ?cmd"); putstr(0, 24, stat, 11); if (md == 2) { putchr(0, 23, sccode(':'), 1); for (i = 0; i < cl; i++) putchr(i + 1, 23, sccode(cp[i]), 1); } cs = cur - lstartx(tp, len, ln); if (cs > 39) cs = 39; if (cs < 0) cs = 0; cr = ln - top; if (cr >= 0 && cr < 23) revchr(cr * 40 + cs); }