ref: 16515f9ca461ed66b3b5f706f38f8c95c65d7ba6
parent: f944d6f355cce5ebc947a440ce3f811f2db76282
author: glenda <glenda@narshaddaa>
date: Mon Apr 24 03:07:30 EDT 2023
code all commented and cleaned up
--- a/mkfile
+++ b/mkfile
@@ -1,6 +1,6 @@
</$objtype/mkfile
-TARG=textimg
+TARG=olednews
OFILES=textimg.$O
</sys/src/cmd/mkone
--- a/textimg.c
+++ b/textimg.c
@@ -7,56 +7,29 @@
void
usage(void)
{
- sysfatal("usage: %s [ -f subfont ] text", argv0);
+ sysfatal("usage: %s [-f subfont] [-p reformfs/] [-m ms] [-h y] [-w x] < text", argv0);
}
-void
-writeuncompressed(int fd, Memimage *m)
-{
- char chanstr[32];
- int bpl, y, j;
- uchar *buf;
+// Stolen from `iconv -u`.
+void writeuncompressed(int fd, Memimage *m);
- if(chantostr(chanstr, m->chan) == nil)
- sysfatal("can't convert channel descriptor: %r");
- fprint(fd, "%11s %11d %11d %11d %11d ",
- chanstr, m->r.min.x, m->r.min.y, m->r.max.x, m->r.max.y);
- bpl = bytesperline(m->r, m->depth);
- buf = malloc(bpl+1);
- if(buf == nil)
- sysfatal("malloc failed: %r");
- for(y=m->r.min.y; y<m->r.max.y; y++){
- j = unloadmemimage(m, Rect(m->r.min.x, y, m->r.max.x, y+1), buf, bpl);
- if(j != bpl)
- sysfatal("image unload failed: %r");
- if(write(fd, buf, bpl) != bpl)
- sysfatal("write failed: %r");
- }
- free(buf);
-}
-
-
+// Scroll text in two lines across the MNT Reform (v2) keyboard OLED display.
void
main(int argc, char **argv)
{
- char *s;
+ char *s, *path, *bufbot, *buftop;
Memsubfont *f;
Point p;
- char *path;
- int fd;
+ int fd, i, w, h, ms, lineh;
Biobufhdr *in;
- int ncharspline;//, nlines;
- int h = 32;
- int w = 126;
- int y = 0;
- int i;
- int ms = 100;
+ int ncharspline;
long n;
- //nlines = 2; // i guess?
- char *buf, *buftop;
- int lineh;
+ w = 126;
+ h = 32;
+ ms = 100;
+
s = "/lib/font/bit/vga/vga.0000-007F";
f = nil;
path = "/mnt/reform/kbdoled";
@@ -71,48 +44,61 @@
break;
}ARGEND;
- if (memimageinit())
+ // I'm not convinced this is mandatory.
+ if(memimageinit())
sysfatal("memimageinit failed: %r");
-
- if (s)
+
+ if(s)
f = openmemsubfont(s);
- if (!f){
- fprint(2, "cannot load subfont. Falling back to default.\n");
+ if(!f){
+ fprint(2, "cannot load subfont. Falling back to memdraw default.\n");
f = getmemdefont();
}
- // Read text in - one OLED line width at a time
- // 2 lines on the OLED display
- // p.x = width of one char in pixels
- // 126 x 32 oled
+ /*
+ Read text in - one OLED line width at a time.
+ 2 lines on the OLED display @ height 8 font, like vga.
+ p.x = max(?) width of one character in pixels.
+ 126 x 32 oled.
+ Q is arbitrary.
+ */
p = memsubfontwidth(f, "Q");
if (p.x == 0)
- sysfatal("no length");
+ sysfatal("font has no width, not wide enough to ride");
+ // The height of the text line ≡ the font's height
lineh = f->height;
+ // Number of characters that can be on a line.
ncharspline = w / p.x;
- buf = calloc(ncharspline, sizeof (char));
- n = Bread(in, buf, ncharspline-1);
+
+ // Initialize our buffers.
+ bufbot = calloc(ncharspline, sizeof (char));
+ n = Bread(in, bufbot, ncharspline-1);
if(n <= 0)
sysfatal("no bread in the bread box");
- buf[n] = '\0';
+ bufbot[n] = '\0';
for(i = 0; i < n; i++)
- if(buf[i] == '\n' || buf[i] == '\r')
- buf[i] = ' ';
+ if(bufbot[i] == '\n' || bufbot[i] == '\r')
+ bufbot[i] = ' ';
buftop = calloc(ncharspline, sizeof (char));
memset(buftop, ' ', ncharspline*sizeof (char));
buftop[n] = '\0';
+ // Primary loop routine.
for(;;){
Memimage *img;
+ char c;
+ // Not entirely sure if open/close every time is necessary.
fd = open(path, OWRITE);
if(fd < 0){
sysfatal("could not open kbdoled file → %r");
}
+ // White background for the whole OLED.
+ // This might be incorrect, but it works cosmetically.
img = allocmemimage(Rect(0, 0, p.x*ncharspline, f->height+lineh), GREY1);
if (!img)
sysfatal("cannot allocate memimage: %r");
@@ -122,36 +108,67 @@
memimagestring(img, Pt(0, 0), memblack, ZP, f, buftop);
// Bottom line
- memimagestring(img, Pt(0, 16), memblack, ZP, f, buf);
+ memimagestring(img, Pt(0, h/2), memblack, ZP, f, bufbot);
+
+ // Reform/pm requires an uncompressed plan9 bitmap image
writeuncompressed(fd, img);
close(fd);
- if(y == 0)
- y = 16;
- else
- y = 0;
- char c;
+ // Read one character at a time in for 'text scroll' effect.
c = Bgetc(in);
+
+ // EOF
if(c <= 0)
break;
+
+ // Don't print whitespace symbols other than spaces.
if(c == '\n' || c == '\r')
c = ' ';
- // Shift the top in
- for(i = 0; i < n-1; i++){
+ // Shift the top values in from the bottom row.
+ for(i = 0; i < n-1; i++)
buftop[i] = buftop[i+1];
- }
- buftop[n-1] = buf[0];
+
+ buftop[n-1] = bufbot[0];
- // Shift the bottom in
- for(i = 0; i < n-1; i++){
- buf[i] = buf[i+1];
- }
- buf[n-1] = c;
+ // Shift the bottom values over and the new char in.
+ for(i = 0; i < n-1; i++)
+ bufbot[i] = bufbot[i+1];
+
+ bufbot[n-1] = c;
freememimage(img);
sleep(ms);
+ }
+
+ free(bufbot);
+ free(buftop);
+}
+
+
+void
+writeuncompressed(int fd, Memimage *m)
+{
+ char chanstr[32];
+ int bpl, y, j;
+ uchar *buf;
+
+ if(chantostr(chanstr, m->chan) == nil)
+ sysfatal("can't convert channel descriptor: %r");
+ fprint(fd, "%11s %11d %11d %11d %11d ",
+ chanstr, m->r.min.x, m->r.min.y, m->r.max.x, m->r.max.y);
+
+ bpl = bytesperline(m->r, m->depth);
+ buf = malloc(bpl+1);
+ if(buf == nil)
+ sysfatal("malloc failed: %r");
+ for(y=m->r.min.y; y<m->r.max.y; y++){
+ j = unloadmemimage(m, Rect(m->r.min.x, y, m->r.max.x, y+1), buf, bpl);
+ if(j != bpl)
+ sysfatal("image unload failed: %r");
+ if(write(fd, buf, bpl) != bpl)
+ sysfatal("write failed: %r");
}
free(buf);
}