From 5a8dd0450b7f8cde3e1d27199e50a27482e3bffb Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Thu, 25 Aug 2011 08:58:52 +0000 Subject: Tek clock --- Makefile | 12 ++ tekclock.c | 176 ++++++++++++++++++++++ tekplot.c | 496 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tekplot.h | 45 ++++++ 4 files changed, 729 insertions(+) create mode 100644 Makefile create mode 100644 tekclock.c create mode 100644 tekplot.c create mode 100644 tekplot.h 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 + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#include +#include +#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 -- cgit v1.2.3