summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile12
-rw-r--r--tekclock.c176
-rw-r--r--tekplot.c496
-rw-r--r--tekplot.h45
4 files changed, 729 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..5e172cc
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,12 @@
+# $Id$
+
+CFLAGS+= -Wall
+PROG= tekclock
+SRCS= tekclock.c tekplot.c
+OBJS= $(SRCS:.c=.o)
+LDFLAGS+= -lm
+
+$(PROG): $(OBJS)
+
+clean:
+ @rm -f $(PROG) *.core core *.o
diff --git a/tekclock.c b/tekclock.c
new file mode 100644
index 0000000..aa8b222
--- /dev/null
+++ b/tekclock.c
@@ -0,0 +1,176 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2010 Dimitri Sokolyuk <demon@dim13.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/time.h>
+#include <time.h>
+#include <assert.h>
+#include <err.h>
+#include <math.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "tekplot.h"
+
+#define MAXX 4096
+#define MAXY 3120
+
+int dflag = 0;
+
+void
+settimer(int sec, int usec)
+{
+ struct itimerval itv;
+
+ itv.it_value.tv_sec = sec;
+ itv.it_value.tv_usec = usec;
+ itv.it_interval = itv.it_value;
+
+ setitimer(ITIMER_REAL, &itv, NULL);
+}
+
+void
+usage(void)
+{
+ extern char *__progname;
+
+ (void)fprintf(stderr, "usage: %s [-d msec] [ILDA]\n", __progname);
+
+ exit(1);
+}
+
+void
+catch(int signo)
+{
+ if (signo != SIGALRM)
+ dflag = 1;
+ return;
+}
+
+#define R ((MAXY) / 2 - 1)
+#define off ((MAXX - MAXY) / 2 - 1)
+
+int
+dot(int k, int r, int *x, int *y)
+{
+ double phy;
+
+ phy = M_PI * (90 - k) / 180;
+ *x = r * cos(phy) + R + off;
+ *y = r * sin(phy) + R;
+
+ return 0;
+}
+
+int
+drawdisk(void)
+{
+ int i, x, y;
+
+ for (i = 0; i <= 60; i++) {
+ dot(6 * i, R, &x, &y);
+ iplot(!!i, x, y);
+ }
+
+ return 0;
+}
+
+int
+drawmarks(void)
+{
+ int i, x, y, u, v;
+
+ for (i = 0; i < 60; i++) {
+ dot(i * 6, R, &x, &y);
+ dot(i * 6, R - 50 * ((i % 5) ? 1 : 3), &u, &v);
+
+ iplot(0, (int)x, (int)y);
+ iplot(1, (int)u, (int)v);
+ }
+ return 0;
+}
+
+
+int
+drawhands(struct tm *tm)
+{
+ int ox, oy;
+ int hx, hy;
+ int mx, my;
+ int sx, sy;
+ int h, m, s;
+
+ h = 30 * (tm->tm_hour % 12) + tm->tm_min / 2;
+ m = 6 * tm->tm_min + tm->tm_sec / 10;
+ s = 6 * tm->tm_sec;
+
+ dot(0, 0, &ox, &oy);
+
+ dot(s, R - 200, &sx, &sy);
+ iplot(0, ox, oy);
+ iplot(1, sx, sy);
+
+ dot(m, R - 400, &mx, &my);
+ iplot(0, ox, oy);
+ iplot(1, mx, my);
+
+ dot(h, R - 800, &hx, &hy);
+ iplot(0, ox, oy);
+ iplot(1, hx, hy);
+
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ struct sigaction sa;
+ int delay = 1;
+ int udelay = 0;
+ time_t t;
+ struct tm *tm;
+
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sa.sa_handler = catch;
+ sigaction(SIGALRM, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGHUP, &sa, NULL);
+
+ settimer(delay, udelay);
+
+ inittek();
+ while (!dflag) {
+ time(&t);
+ tm = localtime(&t);
+
+ page();
+
+ drawdisk();
+ drawmarks();
+ drawhands(tm);
+
+ fflush(stdout);
+
+ sigsuspend(&sa.sa_mask);
+ }
+ endtek();
+
+ return 0;
+}
diff --git a/tekplot.c b/tekplot.c
new file mode 100644
index 0000000..d074f9d
--- /dev/null
+++ b/tekplot.c
@@ -0,0 +1,496 @@
+/* $Id$ */
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include "tekplot.h"
+
+#define EXTRABITS 0x0f
+#define FIVEBITS 0x1f
+#define HIBITS (FIVEBITS << SHIFTHI)
+#define LOBITS (FIVEBITS << SHIFTLO)
+#define SHIFTHI 7
+#define SHIFTLO 2
+#define TWOBITS 0x03
+
+#define ETX 3 /* VT page */
+#define ENQ 5
+#define BELL 7
+#define BS 010 /* dec char spacing */
+#define HT 011 /* inc char spacing */
+#define LF 012 /* dec line spacing */
+#define VT 013 /* inc line spacing */
+#define FF 014 /* TEX page */
+#define CR 015 /* Alpha mode */
+#define SO 016
+#define SI 017
+#define SUB 032 /* Graphics-in mode */
+#define ESC 033
+#define FS 034 /* Point mode */
+#define GS 035 /* Graphic mode */
+#define RS 036 /* IPlot mode */
+#define US 037 /* Alpha mode */
+#define DEL 0177 /* more esc */
+
+#define TEXT US
+#define PEN GS
+#define DOT FS
+#define GIN SUB
+#define PAGE FF
+#define VTPAGE 3
+
+enum { ALPHA, VECTOR, POINT, SPOINT, SPOINTFETCH, IPLOT, CROSSHAIR } plotf;
+
+#define psleep(t) usleep(1000 * (t)) /* Sleep for t milliseconds */
+
+struct disps {
+ int scrnx[2];
+ int scrny[2];
+} dispxy;
+
+int ohy, oly, ohx, oex;
+int lastx, lasty;
+
+int side = 0;
+int teklf = 90;
+int Mechanical = 0;
+
+int Notatty; /* Output is not a tty - likely pipe to phys */
+int waitflash;
+int XTerm; /* running under XTerm */
+
+static int pen, maxx, oldx, oldy;
+#if 0
+static char Zxystring[] = "4507430165672321";
+#endif
+static char xystring[] = "BJAIBFAEHJHIDFDE";
+
+
+static const char pendown[] = "P";
+static const char penup[] = " ";
+
+void
+esc(char c)
+{
+ putchar(ESC);
+ putchar(c);
+ fflush(stdout);
+}
+
+void
+xycvt(int x, int y)
+{
+ int c;
+ char *p;
+ char pbuf[8];
+ p = pbuf;
+ *p++ = 0;
+
+ /* queue low order x */
+ *p++ = ((x >> SHIFTLO) & FIVEBITS) | 0x40;
+
+ /* if hi x changed, queue it and force xmsn of low order y */
+ if (ohx != (c = ((x >> SHIFTHI) & FIVEBITS) | 0x20))
+ *p++ = oly = ohx = c;
+
+ /* calculate extra byte */
+ c = (x & TWOBITS) | ((y & TWOBITS) << SHIFTLO) | 0x60;
+ if (y & 0x1000)
+ c |= 020;
+
+ /* queue lo y and extra if extra changed */
+ if (oex != c) {
+ *p++ = oly = ((y >> SHIFTLO) & FIVEBITS) | 0x60;
+ *p++ = oex = c;
+ } else if (oly != (c = ((y >> SHIFTLO) & FIVEBITS) | 0x60))
+ *p++ = oly = c;
+
+ if (ohy != (c = ((y >> SHIFTHI) & FIVEBITS) | 0x20))
+ *p++ = ohy = c;
+
+ while ((c = *--p))
+ putchar(c);
+
+ if (waitflash) {
+ if (((abs(x - lastx) > 1500) || (abs(y - lasty) > 1500)) && (plotf == VECTOR))
+ ohy = oly = ohx = oex = 0;
+ lastx = x;
+ lasty = y;
+ }
+}
+
+/*
+ * i = 0 dark vector
+ * i = -1 point plot
+ * i = -32 to -126 special point plot z axis setting
+ */
+
+void
+iplot(int i, int ix, int iy)
+{
+
+ if (Mechanical) {
+ xyplot(i, ix, iy);
+ return;
+ }
+ if (iy < 0 || iy > 4095 || ix < 0 || ix > 4095)
+ return; /* crude clip */
+
+ if (i <= 0) {
+ switch (i) {
+ case -1:
+ if (plotf != POINT) {
+ putchar(DOT);
+ plotf = POINT;
+ }
+ break;
+ case 0:
+ if (plotf != VECTOR && plotf != ALPHA)
+ putchar(TEXT);
+ putchar(PEN);
+ plotf = VECTOR;
+ break;
+ default:
+ if (plotf != SPOINT) {
+ if (plotf != ALPHA)
+ putchar(TEXT);
+
+ putchar(ESC);
+ putchar(DOT);
+
+ plotf = SPOINT;
+ }
+ i = -i;
+ if (i > 125)
+ i = 125;
+ if (i < 32)
+ i = 32;
+ putchar(i);
+ break;
+ }
+ }
+ xycvt(ix, iy);
+ return;
+}
+
+void
+alpha(void)
+{
+ if (Mechanical)
+ printf(penup);
+
+ if (waitflash && plotf == VECTOR) {
+ putchar(0);
+ putchar(0);
+ putchar(0);
+ putchar(0);
+ }
+ plotf = ALPHA;
+ pen = 1;
+ lastx = -1;
+ lasty = -1;
+ putchar(TEXT);
+ fflush(stdout);
+}
+
+void
+inittek(void)
+{
+ char *p;
+ int t;
+ static int done = 0;
+ if (done)
+ return;
+
+ p = getenv("TERM");
+
+ if (!p)
+ return;
+
+ if ((strncmp(p, "xterm", 5) == 0) || (strcmp(p, "dumb") == 0)) {
+ teklf = 88;
+ XTerm = 1;
+ waitflash = 0;
+
+ printf("%c[?38h", ESC);
+
+ } else if (strcmp(p, "tek4014") == 0)
+ teklf = 88;
+ else {
+ waitflash = isdigit(*p);
+ t = atoi(p);
+ if ((t > 4012) && (t < 4020))
+ teklf = 56;
+ else
+ teklf = 88;
+ }
+
+ done = 1;
+}
+
+void
+endtek(void)
+{
+ if (XTerm) {
+ putchar(TEXT);
+ esc(VTPAGE);
+ }
+}
+
+void
+page(void)
+{
+ inittek();
+
+ fflush(stderr);
+ fflush(stdout);
+
+ if (!isatty(1))
+ psleep(200);
+
+ dispxy.scrnx[0] = 0;
+ dispxy.scrnx[1] = 2048;
+ dispxy.scrny[0] = 3070;
+ dispxy.scrny[1] = 3070;
+
+ ohy = 0;
+ oly = 0;
+ ohx = 0;
+ oex = 0;
+
+ lastx = -1;
+ lasty = -1;
+
+ esc(PAGE);
+ plotf = ALPHA;
+
+ if (waitflash)
+ psleep(1500);
+}
+
+/* VARARGS */
+void
+disp(char *fmt,...)
+{
+ va_list ap;
+ alpha();
+
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+
+ fflush(stdout);
+}
+
+/* VARARGS */
+void
+spad(char *fmt,...)
+{
+ va_list ap;
+ inittek();
+
+ if ((dispxy.scrny[side] -= teklf) < 0)
+ dispxy.scrny[side] = 0;
+
+ iplot(0, dispxy.scrnx[side], dispxy.scrny[side]);
+
+ alpha();
+
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+
+ fflush(stdout);
+ psleep(40);
+}
+
+void
+dispii(char *s, int *t)
+{
+ printf("%s ", s);
+ fflush(stdout);
+ scanf("%d", t);
+}
+
+void
+spadii(char *s, int *t)
+{
+ char line[80];
+ spad(s);
+ fgets(line, 77, stdin);
+ if (line[0])
+ sscanf(line, "%d", t);
+}
+
+void
+spadiid(char *s, int *t)
+{
+ char line[80];
+ spad(s);
+ printf(" [%d]: ", *t);
+ fflush(stdout);
+ fgets(line, 77, stdin);
+ if (line[0])
+ sscanf(line, "%d", t);
+}
+
+void
+xyplot(int i, int ix, int iy)
+{
+
+ if (i == 0) {
+ if (pen)
+ printf(penup);
+ pen = 0;
+ } else if (i < 0) {
+ if (pen)
+ printf(penup);
+ xymove(ix, iy);
+ printf(pendown);
+ printf("AHBD");
+ pen = 1;
+ return;
+ } else if (pen == 0) {
+ printf(pendown);
+ pen++;
+ }
+ xymove(ix, iy);
+}
+
+void
+xymove(int x, int y)
+{
+ int ix, iy, sindex, idelta;
+ int ch1, ch2;
+ if (Mechanical < 0) {
+ iy = -x;
+ x = y;
+ y = iy;
+ }
+ sindex = 0;
+ if (x > maxx)
+ maxx = x;
+
+ if ((ix = (oldx - x)) < 0) {
+ sindex++;
+ ix = -ix;
+ }
+ if ((iy = (oldy - y)) < 0) {
+ sindex += 2;
+ iy = -iy;
+ }
+ if (iy > ix)
+ sindex += 4;
+ else if (ix > iy) {
+ idelta = ix;
+ ix = iy;
+ iy = idelta;
+ }
+ if (iy == 0)
+ return;
+
+ sindex <<= 1;
+
+ ch1 = xystring[sindex];
+ ch2 = xystring[sindex + 1];
+
+#define iless ix
+#define igreat iy
+#define icount sindex
+ icount = iy;
+
+ iless <<= 1;
+ idelta = iless - igreat;
+ igreat <<= 1;
+
+ while (--icount >= 0) {
+ if (idelta >= 0) {
+ putchar(ch2);
+ idelta -= igreat;
+ } else {
+ putchar(ch1);
+ }
+ idelta += iless;
+ }
+ oldx = x;
+ oldy = y;
+}
+
+/*
+ * mech(n)
+ * 0: vectors
+ * >0: incremental plotting
+ * <0: incremental plotting rotated 90 degrees clockwise
+ * on a drum plotter this makes y axis the long one
+ */
+
+void
+mech(int n)
+{
+ pen = 1;
+ alpha();
+ iplot(-1, 0, 0);
+ alpha();
+
+ if (n)
+ putchar(RS);
+
+ printf(penup);
+ Mechanical = n;
+}
+
+/*
+ * xyres()
+ * tells xymove that the pen is at 0,0
+ */
+
+void
+xyres(void)
+{
+ oldx = 0;
+ oldy = 0;
+ maxx = 0;
+}
+
+/*
+ * mpage(idelta)
+ * performs a move to the coordinate maxx+idelta,0
+ * where maxx is the largest positive x excursion of the
+ * plotter since the last call to mpage.
+ */
+
+void
+mpage(int idelta)
+{
+ iplot(0, maxx + idelta, 0);
+ xyres();
+}
+
+void
+setchsize(int n)
+{ /* set character size */
+ switch (n) {
+ case 4:
+ esc(';');
+ break;
+ case 3:
+ esc(':');
+ break;
+ case 2:
+ esc('9');
+ break;
+ default:
+ esc('8');
+ break;
+ }
+}
+
+void
+setzw(int n)
+{ /* set beam and vector mode */
+ esc(n);
+}
diff --git a/tekplot.h b/tekplot.h
new file mode 100644
index 0000000..107ffb2
--- /dev/null
+++ b/tekplot.h
@@ -0,0 +1,45 @@
+/* $Id$ */
+
+#ifndef _TEKPLOT_H
+#define _TEKPLOT_H
+
+/* arguments to setzw() */
+#define TEKNZNV 96 /* Normal Z axis and Normal vectors */
+#define TEKNZDOT 97 /* Normal Z dotted vectors */
+#define TEKNZDOTDASH 98 /* Normal Z dot-dash vectors */
+#define TEKNZSHORTDASH 99 /* short dash */
+#define TEKNZLONGDASH 100 /* long dash */
+#define TEKWZNV 112 /* Write-thru, Normal vectors */
+#define TEKWZDOT 113 /* Write-thru, Dotted vectors */
+#define TEKDZNV 108 /* Defocused, Normal vectors */
+
+__BEGIN_DECLS
+
+void iplot(int, int, int); /* i x y */
+void alpha(void);
+void page(void);
+void setzw(int);
+int kurse(int *, int *, int *); /* char x y */
+
+void esc(char);
+void xycvt(int, int);
+void alpha(void);
+void inittek(void);
+void endtek(void);
+void page(void);
+void disp(char *,...);
+void spad(char *,...);
+void dispii(char *, int *);
+void spadii(char *, int *);
+void spadiid(char *, int *);
+void xyplot(int, int, int);
+void xymove(int, int);
+void mech(int);
+void xyres(void);
+void mpage(int);
+void setchsize(int);
+void setzw(int);
+
+__END_DECLS
+
+#endif