* implied warranty.
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <ctype.h>
-#include <unistd.h>
-#include <sys/time.h>
#include <math.h>
-
-#ifdef VERMICULATE_STANDALONE
-#include "yarandom.h"
-#include "usleep.h"
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <X11/Xresource.h>
-#else
#include "screenhack.h"
-#include "config.h"
-#endif /* VERMICULATE_STANDALONE */
#define degs 360
#define degs2 (degs/2)
#define thrmax 120
#define tailmax (thrmax * 2 + 1)
#define tmodes '7'
-#define ymax (hei - 1)
+#define ymax (st->hei - 1)
#define ymin 0
-#define xmax (wid - 1)
+#define xmax (st->wid - 1)
#define xmin 0
#define rlmax 200
#define SPEEDINC 10
}
linedata;
-#ifdef VERMICULATE_STANDALONE
-static XEvent myevent;
-static Bool use_root = False;
-static unsigned char rgb[256][3];
-
-#else
-char *progclass = "Vermiculate";
-
-char *defaults[] = {
- ".ticks: 20000",
- 0
-};
-
-XrmOptionDescRec options[] = {
- {"-speed", ".speed", XrmoptionSepArg, 0},
- {"-instring", ".instring", XrmoptionSepArg, 0},
- {0, 0, 0, 0}
-};
-#endif /* VERMICULATE_STANDALONE */
-
-static Display *mydpy;
-static Window mywindow;
-static GC mygc;
-static Colormap mycmap;
-static XWindowAttributes xgwa;
-static Bool neednewkey = True;
-static XColor mycolors[tailmax];
-
-static int hei = 500, wid = 500, speed = 100;
-static Bool erasing = True;
-static char *instring = 0;
-static int max_ticks;
-
-static struct stringAndSpeed
+static const struct stringAndSpeed
{
char *str;
int speed;
}
sampleStrings[] =
{
- { "]]]]]]]]7ces123400-9-8#c123456#s9998880004#ma3#car9ma6#c-#r1", 600} ,
- { "bmarrrr#c1234#lc5678#lyet]", 600} ,
+/* { "]]]]]]]]7ces123400-9-8#c123456#s9998880004#ma3#car9ma6#c-#r1", 600} ,
+ { "bmarrrr#c1234#lc5678#lyet]", 600} , */
{ "AEBMN222222223#CAR9CAD4CAOV", 150} ,
{ "mn333#c23#f1#]]]]]]]]]]]3bc9#r9#c78#f9#ma4#", 600} ,
- { "AEBMN22222#CAD4CAORc1#f2#c1#r6", 100} ,
+ { "AEBMN22222#CAD4CAORc1#f2#c1#r6", 100} ,
/* { "mn6666666#c1i#f1#y2#sy2#vyety1#ry13i#l", 40} , */
- { "aebmnrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr#", 500} ,
- { "bg+++++++++++++++++++++++#mnrrrrrrrrrrrrrrrrrrrrrrr#y1#k", 500} ,
- { "BMN22222223#CAD4CAOVYAS", 150} ,
+ { "aebmnrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr#", 500} ,
+/* { "bg+++++++++++++++++++++++#mnrrrrrrrrrrrrrrrrrrrrrrr#y1#k", 500}, */
+/* { "BMN22222223#CAD4CAOVYAS", 150}, */
/* { "aebmnrrrrrrrrrrrrrrrr#yaryakg--#", 100} , */
- { "mn6rrrrrrrrrrrrrrr#by1i#lcalc1#fnyav", 200 } ,
- { "mn1rrrrrrrrrrrrrrr#by1i#lcalc1#fn", 200 }
+ { "mn6rrrrrrrrrrrrrrr#by1i#lcalc1#fnyav" , 200 } ,
+ { "mn1rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr#by1i#lcalc1#fn", 2000 },
+ { "baeMn333333333333333333333333#CerrYerCal", 800 },
+ { "baeMn1111111111111111111111111111111111111111111111111111111111#Cer9YesYevYerCal", 1200 },
+ { "baMn111111222222333333444444555555#Ct1#lCt2#lCt3#lCt4#lCt5#lCerrYerYet", 1400 },
+ { "baMn111111222222333333444444555555#Ct1#lCt2#lCt3#lCt4#lCt5#lCerrYerYetYt1i#lYt1i#sYt1#v", 1400 }
+};
+
+struct state {
+ Display *dpy;
+ Window window;
+
+ GC mygc;
+ Colormap mycmap;
+ XWindowAttributes xgwa;
+ XColor mycolors[tailmax];
+
+ int hei, wid, speed;
+ Bool erasing, cleared, autopal;
+ char *instring;
+ int max_ticks;
+
+ real sinof[degs], cosof[degs], tanof[degs];
+ unsigned char *point;
+
+ linedata thread[thrmax];
+ banktype bank;
+ int bnkt;
+ int boxw, boxh, curviness, gridden, ogd, bordcorn;
+ unsigned char bordcol, threads;
+ char ch, boolop;
+
+ int reset_p;
+ int cyc;
};
-static real sinof[degs], cosof[degs], tanof[degs];
-static unsigned char *point;
-static linedata thread[thrmax];
-static banktype bank;
-static int bankt, boxw, boxh, curviness, gridden, ogd, bordcorn;
-static unsigned char bordcol, threads;
-static char ch, boolop;
+
+static void
+consume_instring(struct state *st);
static Bool
-wasakeypressed (void)
+wasakeypressed (struct state *st)
{
- if (!neednewkey || *instring != 0)
+ if (*st->instring != 0)
return True;
else
-#ifdef VERMICULATE_STANDALONE
- return !(neednewkey =
- !XCheckWindowEvent (mydpy, mywindow, KeyPressMask, &myevent));
-#else
return False;
-#endif /* VERMICULATE_STANDALONE */
}
static char
-readkey (void)
+readkey (struct state *st)
{
char readkey_result;
- if (*instring == 0)
+ if (*st->instring == 0)
{
-#ifdef VERMICULATE_STANDALONE
- char key_buffer[1];
- KeySym key_sym;
- if (neednewkey)
- XWindowEvent (mydpy, mywindow, KeyPressMask, &myevent);
- XLookupString (&myevent.xkey, key_buffer, 1, &key_sym, NULL);
- readkey_result = key_sym;
-#else
readkey_result = '#';
-#endif /* VERMICULATE_STANDALONE */
- neednewkey = True;
}
else
{
- readkey_result = *instring;
- instring++;
+ readkey_result = *st->instring;
+ st->instring++;
};
return toupper (readkey_result);
}
return (ya_random () % i);
}
-static void
-waitabit (void)
+static unsigned long
+waitabit (struct state *st)
{
- static int cyc = 0;
- cyc += threads;
- while (cyc > speed)
+ int result = 0;
+ st->cyc += st->threads;
+ while (st->cyc > st->speed)
{
- usleep (10000);
- cyc -= speed;
+ result += 10000;
+ st->cyc -= st->speed;
}
+ return result;
}
static void
-clearscreen (void)
+clearscreen (struct state *st)
{
- XClearWindow (mydpy, mywindow);
- memset (point, 0, wid * hei);
+ XClearWindow (st->dpy, st->window);
+ memset (st->point, 0, st->wid * st->hei);
}
static void
-sp (int x, int y, int c)
+sp (struct state *st, int x, int y, int c)
{
- XSetForeground (mydpy, mygc, mycolors[c].pixel);
- XDrawPoint (mydpy, mywindow, mygc, x, y);
- point[(wid * y) + x] = c;
+ XSetForeground (st->dpy, st->mygc, st->mycolors[c].pixel);
+ XDrawPoint (st->dpy, st->window, st->mygc, x, y);
+ st->point[(st->wid * y) + x] = c;
}
static int
-gp (int x, int y)
+gp (struct state *st, int x, int y)
{
- return point[(wid * y) + x];
+ return st->point[(st->wid * y) + x];
}
static void
-redraw (int x, int y, int width, int height)
+redraw (struct state *st, int x, int y, int width, int height)
{
int xc, yc;
for (xc = x; xc <= x + width - 1; xc++)
for (yc = y; yc <= y + height - 1; yc++)
- if (point[wid * yc + xc] != 0)
- sp (xc, yc, point[wid * yc + xc]);
+ if (st->point[st->wid * yc + xc] != 0)
+ sp (st, xc, yc, st->point[st->wid * yc + xc]);
}
static void
-palupdate (Bool forceUpdate)
+palupdate (struct state *st, Bool forceUpdate)
{
- if (forceUpdate || *instring == 0)
+ if (forceUpdate || *st->instring == 0)
{
-#ifdef VERMICULATE_STANDALONE
- int colnum;
- for (colnum = 0; colnum < tailmax; colnum++)
- {
- mycolors[colnum].red = rgb[colnum][0] << 10;
- mycolors[colnum].green = rgb[colnum][1] << 10;
- mycolors[colnum].blue = rgb[colnum][2] << 10;
- mycolors[colnum].flags = DoRed | DoBlue | DoGreen;
- XAllocColor (mydpy, mycmap, &mycolors[colnum]);
- };
-#endif /* VERMICULATE_STANDALONE */
- redraw (xmin, ymin, wid, hei);
+ redraw (st, xmin, ymin, st->wid, st->hei);
}
}
static void
-randpal (void)
+randpal (struct state *st)
{
-#ifdef VERMICULATE_STANDALONE
- int co, ro;
- for (co = 1; co <= 255; co++)
- for (ro = 0; ro <= 2; ro++)
- if (co > tailmax)
- rgb[co][ro] = random1 (20);
- else
- rgb[co][ro] = random1 (64);
- for (ro = 0; ro <= 2; ro++)
- rgb[0][ro] = 0;
-#else
int ncolors = tailmax - 1;
- make_random_colormap (mydpy,
- xgwa.visual,
- mycmap, &mycolors[1], &ncolors, True, True, 0, True);
+ make_random_colormap (st->xgwa.screen, st->xgwa.visual, st->mycmap,
+ &st->mycolors[1], &ncolors, True, True, 0, True);
if (ncolors < tailmax - 1)
{
int c;
for (c = 1; c < tailmax; c++)
- mycolors[c].pixel = WhitePixel (mydpy, DefaultScreen (mydpy));
+ st->mycolors[c].pixel = WhitePixel (st->dpy, DefaultScreen (st->dpy));
}
-#endif /* VERMICULATE_STANDALONE */
}
static void
-gridupdate (Bool interruptible)
+gridupdate (struct state *st, Bool interruptible)
{
int x, y;
- if (gridden > 0)
- for (x = 0; x <= xmax && !(wasakeypressed () && interruptible); x += boxw)
- for (y = 0; y <= ymax; y += boxh)
+ if (st->gridden > 0)
+ for (x = 0; x <= xmax && !(wasakeypressed (st) && interruptible); x += st->boxw)
+ for (y = 0; y <= ymax; y += st->boxh)
{
- if (random1 (15) < gridden)
+ if (random1 (15) < st->gridden)
{
#define lesser(A,B) ( ((A)<(B)) ? (A) : (B) )
- int max = lesser (x + boxw, xmax);
+ int max = lesser (x + st->boxw, xmax);
int xc;
for (xc = x; xc <= max; xc++)
- sp (xc, y, 1);
+ sp (st, xc, y, 1);
}
- if (random1 (15) < gridden)
+ if (random1 (15) < st->gridden)
{
- int max = lesser (y + boxh, ymax);
+ int max = lesser (y + st->boxh, ymax);
int yc;
for (yc = y; yc <= max; yc++)
- sp (x, yc, 1);
+ sp (st, x, yc, 1);
}
}
}
static void
-bordupdate (void)
+bordupdate (struct state *st)
{
int xbord, ybord;
- if (bordcorn == 0 || bordcorn == 1)
+ if (st->bordcorn == 0 || st->bordcorn == 1)
ybord = ymin;
else
ybord = ymax;
- if (bordcorn == 0 || bordcorn == 3)
+ if (st->bordcorn == 0 || st->bordcorn == 3)
xbord = xmin;
else
xbord = xmax;
{
int x, y;
for (x = xmin; x <= xmax; x++)
- sp (x, ybord, bordcol);
+ sp (st, x, ybord, st->bordcol);
for (y = ymin; y <= ymax; y++)
- sp (ybord, y, bordcol);
+ sp (st, xbord, y, st->bordcol);
}
}
static Bool
-inbank (unsigned char thr)
+inbank (struct state *st, unsigned char thr)
{
int c;
- if (bankt > 0)
- for (c = 1; c <= bankt; c++)
- if (bank[c - 1] == thr)
+ if (st->bnkt > 0)
+ for (c = 1; c <= st->bnkt; c++)
+ if (st->bank[c - 1] == thr)
return True;
return False;
}
static void
-pickbank (void)
+pickbank (struct state *st)
{
unsigned char thr = 1;
-#ifdef VERMICULATE_STANDALONE
- int co, ro;
- unsigned char orgb[256][3];
-
- arrcpy (orgb, rgb);
- for (co = 2; co <= tailmax; co++)
- for (ro = 0; ro <= 2; ro++)
- rgb[co][ro] = 25;
-#endif /* VERMICULATE_STANDALONE */
- bankt = 0;
- ch = '\0';
+ st->bnkt = 0;
+ st->ch = '\0';
do
{
- while (inbank (thr))
- thr = thr % threads + 1;
-#ifdef VERMICULATE_STANDALONE
- for (co = 1; co <= threads; co++)
- {
- for (ro = 0; ro <= 2; ro++)
- rgb[co + 1][ro] = 25;
- if (inbank (co))
- for (ro = 0; ro <= 1; ro++)
- rgb[co + 1][ro] = 60;
- }
- for (ro = 0; ro <= 2; ro++)
- rgb[thr + 1][ro] = 60;
-#endif /* VERMICULATE_STANDALONE */
- palupdate (False);
- ch = readkey ();
- palupdate (False);
- switch (ch)
+ while (inbank (st, thr))
+ thr = thr % st->threads + 1;
+
+ palupdate (st, False);
+ st->ch = readkey (st);
+ palupdate (st, False);
+ switch (st->ch)
{
case '+':
case '-':
do
{
- if (ch == '+')
+ if (st->ch == '+')
thr++;
else
thr--;
- wraparound (thr, 1, threads + 1);
+ wraparound (thr, 1, st->threads + 1);
}
- while (inbank (thr));
+ while (inbank (st, thr));
break;
case ' ':
- bank[++bankt - 1] = thr;
+ st->bank[++st->bnkt - 1] = thr;
break;
- case '1'...'9':
- bank[++bankt - 1] = ch - '0';
- if (bank[bankt - 1] > threads)
- bankt--;
+ case '1': case '2': case '3':
+ case '4': case '5': case '6':
+ case '7': case '8': case '9':
+
+ st->bank[++st->bnkt - 1] = st->ch - '0';
+ if (st->bank[st->bnkt - 1] > st->threads)
+ st->bnkt--;
break;
case 'I':
{
banktype tbank;
int tbankt = 0;
int c;
- for (c = 1; c <= threads; c++)
- if (!inbank (c))
+ for (c = 1; c <= st->threads; c++)
+ if (!inbank (st, c))
tbank[++tbankt - 1] = c;
- bankt = tbankt;
- arrcpy (bank, tbank);
+ st->bnkt = tbankt;
+ arrcpy (st->bank, tbank);
}
break;
case 'T':
- ch = readkey ();
- switch (ch)
+ st->ch = readkey (st);
+ switch (st->ch)
{
- case '1'...tmodes:
+ case '1': case '2': case '3':
+ case '4': case '5': case '6':
+ case '7': case '8': case '9':
+
{
int c;
- for (c = 1; c <= threads; c++)
- if (thread[c - 1].tmode == ch - '0')
- bank[++bankt - 1] = c;
+ for (c = 1; c <= st->threads; c++)
+ if (st->thread[c - 1].tmode == st->ch - '0')
+ st->bank[++st->bnkt - 1] = c;
}
break;
}
break;
case 'A':
- for (bankt = 1; bankt <= threads; bankt++)
- bank[bankt - 1] = bankt;
- bankt = threads;
+ for (st->bnkt = 1; st->bnkt <= st->threads; st->bnkt++)
+ st->bank[st->bnkt - 1] = st->bnkt;
+ st->bnkt = st->threads;
break;
case 'E':
- for (bankt = 1; bankt <= thrmax; bankt++)
- bank[bankt - 1] = bankt;
- bankt = thrmax;
+ for (st->bnkt = 1; st->bnkt <= thrmax; st->bnkt++)
+ st->bank[st->bnkt - 1] = st->bnkt;
+ st->bnkt = thrmax;
break;
}
}
- while (!(bankt >= threads || ch == 'N' || ch == '\15' || ch == '#'));
- if (bankt == 0 && ch != 'N')
+ while (!(st->bnkt >= st->threads || st->ch == 'N' || st->ch == '\15' || st->ch == '#'));
+ if (st->bnkt == 0 && st->ch != 'N')
{
- bankt = 1;
- bank[0] = thr;
+ st->bnkt = 1;
+ st->bank[0] = thr;
}
-#ifdef VERMICULATE_STANDALONE
- arrcpy (rgb, orgb);
-#endif /* VERMICULATE_STANDALONE */
- palupdate (False);
+ palupdate (st, False);
}
static void
-bankmod (Bool * Bool_)
+bankmod (char boolop, Bool * Bool_)
{
switch (boolop)
{
}
static void
-newonscreen (unsigned char thr)
+newonscreen (struct state *st, unsigned char thr)
{
- linedata *LP = &thread[thr - 1];
+ linedata *LP = &st->thread[thr - 1];
LP->filled = False;
LP->dead = False;
LP->reclen = (LP->little) ?
random1 (10) + 5 : random1 (rlmax - 30) + 30;
LP->deg = random1 (degs);
- LP->y = random1 (hei);
- LP->x = random1 (wid);
+ LP->y = random1 (st->hei);
+ LP->x = random1 (st->wid);
LP->recpos = 0;
LP->turnco = 2;
LP->turnsize = random1 (4) + 2;
}
static void
-firstinit (unsigned char thr)
+firstinit (struct state *st, unsigned char thr)
{
- linedata *LP = &thread[thr - 1];
+ linedata *LP = &st->thread[thr - 1];
LP->col = thr + 1;
LP->prey = 0;
LP->tmode = 1;
}
static void
-maininit (void)
+maininit (struct state *st)
{
- if (!instring)
+ if (!st->instring)
{
int n = random1 (sizeof (sampleStrings) / sizeof (sampleStrings[0]));
- instring = sampleStrings[n].str;
- speed = sampleStrings[n].speed;
+ st->instring = sampleStrings[n].str;
+ st->speed = sampleStrings[n].speed;
}
- boxh = 10;
- boxw = 10;
- gridden = 0;
- bordcorn = 0;
- threads = 4;
- curviness = 30;
- bordcol = 1;
- ogd = 8;
- ch = '\0';
- erasing = True;
+ st->boxh = 10;
+ st->boxw = 10;
+ st->gridden = 0;
+ st->bordcorn = 0;
+ st->threads = 4;
+ st->curviness = 30;
+ st->bordcol = 1;
+ st->ogd = 8;
+ st->ch = '\0';
+ st->erasing = True;
{
unsigned char thr;
for (thr = 1; thr <= thrmax; thr++)
{
- firstinit (thr);
- newonscreen (thr);
+ firstinit (st, thr);
+ newonscreen (st, thr);
}
}
{
int d;
for (d = degs - 1; d >= 0; d--)
{
- sinof[d] = sin (d * dtor);
- cosof[d] = cos (d * dtor);
+ st->sinof[d] = sin (d * dtor);
+ st->cosof[d] = cos (d * dtor);
if (d % degs4 == 0)
- tanof[d] = tanof[d + 1];
+ st->tanof[d] = st->tanof[d + 1];
else
- tanof[d] = tan (d * dtor);
+ st->tanof[d] = tan (d * dtor);
}
}
- randpal ();
+ randpal (st);
}
static Bool
-move (unsigned char thr)
+move (struct state *st, unsigned char thr)
{
- linedata *LP = &thread[thr - 1];
+ linedata *LP = &st->thread[thr - 1];
if (LP->dead)
return (False);
if (LP->prey == 0)
LP->turnco = abs (LP->turnco) - 1;
if (LP->turnco == 0)
{
- LP->turnco = curviness + random1 (10);
+ LP->turnco = st->curviness + random1 (10);
LP->circturn *= -1;
}
LP->deg += LP->circturn;
real dy, dx;
if (LP->tailfollow || LP->prey == thr)
{
- dx = thread[LP->prey - 1].xrec[thread[LP->prey - 1].recpos] - LP->x;
- dy = thread[LP->prey - 1].yrec[thread[LP->prey - 1].recpos] - LP->y;
+ dx = st->thread[LP->prey - 1].xrec[st->thread[LP->prey - 1].recpos] - LP->x;
+ dy = st->thread[LP->prey - 1].yrec[st->thread[LP->prey - 1].recpos] - LP->y;
}
else
{
- dx = thread[LP->prey - 1].x - LP->x;
- dy = thread[LP->prey - 1].y - LP->y;
+ dx = st->thread[LP->prey - 1].x - LP->x;
+ dy = st->thread[LP->prey - 1].y - LP->y;
}
desdeg =
(LP->vhfollow) ?
}
else
LP->deg +=
- (tanof[LP->deg] >
+ (st->tanof[LP->deg] >
dy / dx) ? -abs (LP->circturn) : abs (LP->circturn);
}
{
unsigned char oldcol;
real oldy = LP->y, oldx = LP->x;
- LP->x += cosof[LP->deg];
+ LP->x += st->cosof[LP->deg];
wraparound (LP->x, xmin, xmax + 1);
- LP->y += sinof[LP->deg];
+ LP->y += st->sinof[LP->deg];
wraparound (LP->y, ymin, ymax + 1);
#define xi ((int) LP->x)
#define yi ((int) LP->y)
- oldcol = gp (xi, yi);
+ oldcol = gp (st, xi, yi);
if (oldcol != 0)
{
Bool vertwall = False, horiwall = False;
- if (oldcol == 1 && ((LP->killwalls && gridden > 0) || LP->realbounce))
+ if (oldcol == 1 && ((LP->killwalls && st->gridden > 0) || LP->realbounce))
{
- vertwall = (gp (xi, (int) oldy) == 1);
- horiwall = (gp ((int) oldx, yi) == 1);
+ vertwall = (gp (st, xi, (int) oldy) == 1);
+ horiwall = (gp (st, (int) oldx, yi) == 1);
}
if (oldcol == 1 && LP->realbounce && (vertwall || horiwall))
{
else if (oldcol != LP->col)
LP->deg += degs2;
}
- if (LP->killwalls && gridden > 0 && oldcol == 1)
+ if (LP->killwalls && st->gridden > 0 && oldcol == 1)
{
if (vertwall && xi + 1 <= xmax)
{
int yy;
- for (yy = yi - yi % boxh;
- yy <= yi - yi % boxh + boxh && yy <= ymax; yy++)
- if (gp (xi + 1, yy) != 1 || yy == ymax)
- sp (xi, yy, 0);
+ for (yy = yi - yi % st->boxh;
+ yy <= yi - yi % st->boxh + st->boxh && yy <= ymax; yy++)
+ if (gp (st, xi + 1, yy) != 1 || yy == ymax)
+ sp (st, xi, yy, 0);
}
if (horiwall && yi + 1 <= ymax)
{
int xx;
- for (xx = xi - xi % boxw;
- xx <= xi - xi % boxw + boxw && xx <= xmax; xx++)
- if (gp (xx, yi + 1) != 1 || xx == xmax)
- sp (xx, yi, 0);
+ for (xx = xi - xi % st->boxw;
+ xx <= xi - xi % st->boxw + st->boxw && xx <= xmax; xx++)
+ if (gp (st, xx, yi + 1) != 1 || xx == xmax)
+ sp (st, xx, yi, 0);
}
}
if (oldcol != LP->col || LP->selfbounce)
}
}
- sp (xi, yi, LP->col);
+ sp (st, xi, yi, LP->col);
if (LP->filled)
{
- if (erasing)
- sp (LP->xrec[LP->recpos], LP->yrec[LP->recpos], 0);
+ if (st->erasing)
+ sp (st, LP->xrec[LP->recpos], LP->yrec[LP->recpos], 0);
else
- sp (LP->xrec[LP->recpos], LP->yrec[LP->recpos], LP->col + thrmax);
+ sp (st, LP->xrec[LP->recpos], LP->yrec[LP->recpos], LP->col + thrmax);
}
LP->yrec[LP->recpos] = yi;
LP->xrec[LP->recpos] = xi;
if (LP->recpos == LP->reclen - 1)
LP->filled = True;
- if (LP->filled && !erasing)
+ if (LP->filled && !st->erasing)
{
int co = LP->recpos;
LP->dead = True;
return (!LP->dead);
}
-static void
-vermiculate_main (void)
+static unsigned long
+vermiculate_draw (Display *dpy, Window window, void *closure)
{
- int had_instring = (instring != 0);
+ struct state *st = (struct state *) closure;
+ int had_instring = (st->instring != 0);
int tick = 0;
- Bool halted = False, autopal = False, cleared;
- point = (unsigned char *) malloc (wid * hei);
- maininit ();
- palupdate (True);
+ int this_delay = 0;
+ int loop = 0;
- do
+
+ AGAIN:
+ if (st->reset_p)
{
- clearscreen ();
+ st->reset_p = 0;
+
+ clearscreen (st);
{
unsigned char thr;
- for (thr = 1; thr <= threads; thr++)
- newonscreen (thr);
+ for (thr = 1; thr <= st->threads; thr++)
+ newonscreen (st, thr);
}
- if (autopal)
+ if (st->autopal)
{
- randpal ();
- palupdate (False);
+ randpal (st);
+ palupdate (st, False);
}
- bordupdate ();
- gridupdate (False);
- cleared = False;
- do
- {
- while (wasakeypressed ())
+ bordupdate (st);
+ gridupdate (st, False);
+ }
+
+ {
+ Bool alltrap = True;
+ unsigned char thr;
+ for (thr = 1; thr <= st->threads; thr++)
+ if (move (st, thr))
+ alltrap = False;
+ if (alltrap) /* all threads are trapped */
+ st->reset_p = True;
+ if (st->speed != SPEEDMAX)
+ this_delay = waitabit (st);
+ }
+
+ if (tick++ > st->max_ticks && !had_instring)
+ {
+ tick = 0;
+ st->instring = 0;
+ maininit(st);
+ st->reset_p = True;
+ st->autopal = False;
+ }
+
+ if (this_delay == 0 && loop++ < 1000)
+ goto AGAIN;
+
+ return this_delay;
+}
+
+static void *
+vermiculate_init (Display *d, Window w)
+{
+ struct state *st = (struct state *) calloc (1, sizeof(*st));
+ st->dpy = d;
+ st->window = w;
+ st->reset_p = 1;
+ st->instring = get_string_resource (st->dpy, "instring", "Instring");
+ if (st->instring && !*st->instring)
+ st->instring = 0;
+
+ st->max_ticks = get_integer_resource (st->dpy, "ticks", "Integer");
+ st->speed = get_integer_resource (st->dpy, "speed", "Speed");
+ if (st->speed <= 0) st->speed = 1;
+ st->mycolors[0].pixel = BlackPixel (st->dpy, DefaultScreen (st->dpy));
+
+ XSetWindowBackground (st->dpy, st->window,
+ BlackPixel (st->dpy, DefaultScreen (st->dpy)));
+ {
+ XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
+ st->wid = st->xgwa.width;
+ st->hei = st->xgwa.height;
+ st->mycmap = st->xgwa.colormap;
+ }
+ {
+ XGCValues mygcv;
+ st->mygc = XCreateGC (st->dpy, st->window, 0, &mygcv);
+ }
+
+ st->point = (unsigned char *) calloc (1, st->wid * st->hei);
+ maininit (st);
+ palupdate (st, True);
+ consume_instring(st);
+ return st;
+}
+
+
+static void
+vermiculate_reshape (Display *dpy, Window window, void *closure,
+ unsigned int w, unsigned int h)
+{
+ struct state *st = (struct state *) closure;
+ st->wid = w;
+ st->hei = h;
+ free (st->point);
+ st->point = (unsigned char *) calloc (1, st->wid * st->hei);
+}
+
+static Bool
+vermiculate_event (Display *dpy, Window window, void *closure, XEvent *event)
+{
+ struct state *st = (struct state *) closure;
+ if (screenhack_event_helper (dpy, window, event))
+ {
+ st->reset_p = 1;
+ return True;
+ }
+ return False;
+}
+
+static void
+consume_instring(struct state *st)
+{
+ char boolop;
+
+ while (wasakeypressed (st))
{
- ch = readkey ();
- switch (ch)
+ st->ch = readkey (st);
+ switch (st->ch)
{
case 'M':
- ch = readkey ();
- switch (ch)
+ st->ch = readkey (st);
+ switch (st->ch)
{
case 'A':
case 'N':
{
- unsigned char othreads = threads;
- if (ch == 'N')
- threads = 0;
+ unsigned char othreads = st->threads;
+ if (st->ch == 'N')
+ st->threads = 0;
do
{
- ch = readkey ();
- switch (ch)
+ st->ch = readkey (st);
+ switch (st->ch)
{
- case '1'...tmodes:
- thread[++threads - 1].tmode = ch - '0';
+ case '1': case '2': case '3':
+ case '4': case '5': case '6':
+ case '7': case '8': case '9':
+ st->thread[++st->threads - 1].tmode = st->ch - '0';
break;
case 'R':
- thread[++threads - 1].tmode =
+ st->thread[++st->threads - 1].tmode =
random1 (tmodes - '0') + 1;
break;
}
}
- while (!(ch == '\15' || ch == '#'
- || threads == thrmax));
- if (threads == 0)
- threads = othreads;
- cleared = True;
+ while (!(st->ch == '\15' || st->ch == '#'
+ || st->threads == thrmax));
+ if (st->threads == 0)
+ st->threads = othreads;
+ st->reset_p = 1;
}
break;
}
break;
case 'C':
- pickbank ();
- if (bankt > 0)
+ pickbank (st);
+ if (st->bnkt > 0)
{
- ch = readkey ();
- switch (ch)
+ st->ch = readkey (st);
+ switch (st->ch)
{
case 'D':
- ch = readkey ();
- switch (ch)
+ st->ch = readkey (st);
+ switch (st->ch)
{
- case '1'...'9':
+ case '1': case '2': case '3':
+ case '4': case '5': case '6':
+ case '7': case '8': case '9':
/* Careful! The following macro needs to be at the beginning of any
block in which it's invoked, since it declares variables: */
#define forallinbank(LDP) linedata *LDP; int bankc; \
for (bankc = 1; \
- (LDP = &thread[bank[bankc - 1] - 1], \
- bankc <= bankt); bankc++)
+ ((bankc <= st->bnkt) ? ( \
+ (LDP = &st->thread[st->bank[bankc - 1] - 1], 1) \
+ ) : 0) ; bankc++)
{
- forallinbank (L) L->slice = degs / (ch - '0');
+ forallinbank (L) L->slice = degs / (st->ch - '0');
}
break;
case 'M':
}
do
{
- char oldch = ch;
- ch = readkey ();
+ char oldch = st->ch;
+ st->ch = readkey (st);
{
forallinbank (L)
{
- switch (ch)
+ switch (st->ch)
{
- case '0'...'9':
+ case '0':
+ case '1': case '2': case '3':
+ case '4': case '5': case '6':
+ case '7': case '8': case '9':
L->tslen++;
- L->turnseq[L->tslen - 1] = ch - '0';
+ L->turnseq[L->tslen - 1] = st->ch - '0';
if (oldch == '-')
L->turnseq[L->tslen - 1] *= -1;
if (bankc % 2 == 0)
}
}
}
- while (!(ch == '\15' || ch == '#'
- || thread[bank[0] - 1].tslen == 50));
+ while (!(st->ch == '\15' || st->ch == '#'
+ || st->thread[st->bank[0] - 1].tslen == 50));
{
forallinbank (L)
{
break;
case 'T':
{
- ch = readkey ();
+ st->ch = readkey (st);
{
forallinbank (L)
{
- switch (ch)
+ switch (st->ch)
{
- case '1'...tmodes:
- L->tmode = ch - '0';
+ case '1': case '2': case '3':
+ case '4': case '5': case '6':
+ case '7': case '8': case '9':
+ L->tmode = st->ch - '0';
break;
case 'R':
L->tmode = random1 (tmodes - '0') + 1;
}
break;
case 'O':
- ch = readkey ();
+ st->ch = readkey (st);
{
- forallinbank (L) L->orichar = ch;
+ forallinbank (L) L->orichar = st->ch;
}
break;
case 'F':
{
banktype fbank;
- arrcpy (fbank, bank);
+ arrcpy (fbank, st->bank);
{
- int fbankt = bankt;
+ int fbnkt = st->bnkt;
int bankc;
- pickbank ();
- for (bankc = 1; bankc <= fbankt; bankc++)
+ pickbank (st);
+ for (bankc = 1; bankc <= fbnkt; bankc++)
{
- linedata *L = &thread[fbank[bankc - 1] - 1];
- if (ch == 'N')
+ linedata *L = &st->thread[fbank[bankc - 1] - 1];
+ if (st->ch == 'N')
L->prey = 0;
else
- L->prey = bank[0 + (bankc - 1) % bankt];
+ L->prey = st->bank[0 + (bankc - 1) % st->bnkt];
}
}
}
break;
case 'L':
{
- forallinbank (L) L->prey = bank[bankc % bankt];
+ forallinbank (L) L->prey = st->bank[bankc % st->bnkt];
}
break;
case 'R':
- ch = readkey ();
+ st->ch = readkey (st);
{
- forallinbank (L) switch (ch)
+ forallinbank (L) switch (st->ch)
{
- case '1'...'9':
- L->circturn = 10 - (ch - '0');
+ case '1': case '2': case '3':
+ case '4': case '5': case '6':
+ case '7': case '8': case '9':
+ L->circturn = 10 - (st->ch - '0');
break;
case 'R':
L->circturn = random1 (7) + 1;
case 'T':
case 'Y':
case 'N':
- boolop = ch;
- pickbank ();
- if (bankt > 0)
+ boolop = st->ch;
+ pickbank (st);
+ if (st->bnkt > 0)
{
- ch = readkey ();
+ st->ch = readkey (st);
{
forallinbank (L)
{
- switch (ch)
+ switch (st->ch)
{
case 'S':
- bankmod (&L->selfbounce);
+ bankmod (boolop, &L->selfbounce);
break;
case 'V':
- bankmod (&L->vhfollow);
+ bankmod (boolop, &L->vhfollow);
break;
case 'R':
- bankmod (&L->realbounce);
+ bankmod (boolop, &L->realbounce);
break;
case 'L':
- bankmod (&L->little);
- cleared = True;
+ bankmod (boolop, &L->little);
+ st->cleared = True;
break;
case 'T':
- bankmod (&L->tailfollow);
+ bankmod (boolop, &L->tailfollow);
break;
case 'K':
- bankmod (&L->killwalls);
+ bankmod (boolop, &L->killwalls);
break;
}
}
}
break;
case 'R':
- if (bordcol == 1)
+ if (st->bordcol == 1)
{
- bordcol = 0;
- bordupdate ();
- bordcorn = (bordcorn + 1) % 4;
- bordcol = 1;
- bordupdate ();
+ st->bordcol = 0;
+ bordupdate (st);
+ st->bordcorn = (st->bordcorn + 1) % 4;
+ st->bordcol = 1;
+ bordupdate (st);
}
break;
- case '\33':
- halted = True;
- break;
- case '1'...tmodes:
+ case '1': case '2': case '3':
+ case '4': case '5': case '6':
+ case '7': case '8': case '9':
{
int c;
for (c = 1; c <= thrmax; c++)
- thread[c - 1].tmode = ch - '0';
+ st->thread[c - 1].tmode = st->ch - '0';
}
break;
case '\40':
- cleared = True;
+ st->cleared = True;
break;
case 'E':
- erasing = !erasing;
+ st->erasing = !st->erasing;
break;
case 'P':
- randpal ();
- palupdate (True);
+ randpal (st);
+ palupdate (st, True);
break;
case 'G':
{
char dimch = 'B';
Bool gridchanged = True;
- if (gridden == 0)
- gridden = ogd;
+ if (st->gridden == 0)
+ st->gridden = st->ogd;
do
{
int msize = 0;
if (gridchanged)
{
- clearscreen ();
- gridupdate (True);
+ clearscreen (st);
+ gridupdate (st, True);
}
- ch = readkey ();
+ st->ch = readkey (st);
gridchanged = True;
- switch (ch)
+ switch (st->ch)
{
case '+':
msize = 1;
msize = -1;
break;
case ']':
- if (gridden < 15)
- gridden++;
+ if (st->gridden < 15)
+ st->gridden++;
break;
case '[':
- if (gridden > 0)
- gridden--;
+ if (st->gridden > 0)
+ st->gridden--;
break;
case 'O':
- ogd = gridden;
- gridden = 0;
+ st->ogd = st->gridden;
+ st->gridden = 0;
break;
case 'S':
- boxw = boxh;
+ st->boxw = st->boxh;
case 'W':
case 'H':
case 'B':
- dimch = ch;
+ dimch = st->ch;
break;
default:
gridchanged = False;
}
if (dimch == 'W' || dimch == 'B')
- boxw += msize;
+ st->boxw += msize;
if (dimch == 'H' || dimch == 'B')
- boxh += msize;
- if (boxw == 0)
- boxw = 1;
- if (boxh == 0)
- boxh = 1;
+ st->boxh += msize;
+ if (st->boxw == 0)
+ st->boxw = 1;
+ if (st->boxh == 0)
+ st->boxh = 1;
}
- while (!(ch == '\15' || ch == '#' || ch == 'O'));
- cleared = True;
+ while (!(st->ch == '\15' || st->ch == '#' || st->ch == 'O'));
+ st->cleared = True;
}
break;
case 'A':
- autopal = !autopal;
+ st->autopal = !st->autopal;
break;
case 'B':
- bordcol = 1 - bordcol;
- bordupdate ();
+ st->bordcol = 1 - st->bordcol;
+ bordupdate (st);
break;
case '-':
- speed -= SPEEDINC;
- if (speed < 1)
- speed = 1;
+ st->speed -= SPEEDINC;
+ if (st->speed < 1)
+ st->speed = 1;
break;
case '+':
- speed += SPEEDINC;
- if (speed > SPEEDMAX)
- speed = SPEEDMAX;
+ st->speed += SPEEDINC;
+ if (st->speed > SPEEDMAX)
+ st->speed = SPEEDMAX;
break;
case '/':
- if (curviness > 5)
- curviness -= 5;
+ if (st->curviness > 5)
+ st->curviness -= 5;
break;
case '*':
- if (curviness < 50)
- curviness += 5;
+ if (st->curviness < 50)
+ st->curviness += 5;
break;
case ']':
- if (threads < thrmax)
- newonscreen (++threads);
+ if (st->threads < thrmax)
+ newonscreen (st, ++st->threads);
break;
case '[':
- if (threads > 1)
+ if (st->threads > 1)
{
- linedata *L = &thread[threads - 1];
+ linedata *L = &st->thread[st->threads - 1];
int lastpos = (L->filled) ? L->reclen - 1 : L->recpos;
int c;
for (c = 0; c <= lastpos; c++)
- sp (L->xrec[c], L->yrec[c], 0);
- threads--;
+ sp (st, L->xrec[c], L->yrec[c], 0);
+ st->threads--;
}
break;
}
}
-
-#ifdef VERMICULATE_STANDALONE
- {
- XEvent xe;
- while (XCheckWindowEvent
- (mydpy, mywindow, StructureNotifyMask | ExposureMask, &xe))
- switch (xe.type)
- {
- case ConfigureNotify:
- wid = xe.xconfigure.width;
- hei = xe.xconfigure.height;
- free (point);
- point = (unsigned char *) malloc (wid * hei);
- cleared = True;
- break;
- case Expose:
- if (!cleared)
- redraw (xe.xexpose.x,
- xe.xexpose.y, xe.xexpose.width,
- xe.xexpose.height);
- break;
- }
- }
-#else
- screenhack_handle_events (mydpy);
-#endif /* VERMICULATE_STANDALONE */
-
- if (!cleared)
- {
- Bool alltrap = True;
- unsigned char thr;
- for (thr = 1; thr <= threads; thr++)
- if (move (thr))
- alltrap = False;
- if (alltrap) /* all threads are trapped */
- cleared = True;
- if (speed != SPEEDMAX)
- waitabit ();
- }
-
- if (tick++ > max_ticks && !had_instring)
- {
- tick = 0;
- instring = 0;
- maininit();
- cleared = True;
- autopal = False;
- }
- }
- while (!(halted || cleared));
- }
- while (!halted);
}
-void
-commonXinit (void)
+static void
+vermiculate_free (Display *dpy, Window window, void *closure)
{
- XSetWindowBackground (mydpy, mywindow,
- BlackPixel (mydpy, DefaultScreen (mydpy)));
- {
- XGetWindowAttributes (mydpy, mywindow, &xgwa);
- wid = xgwa.width;
- hei = xgwa.height;
- mycmap = xgwa.colormap;
- }
- {
- XGCValues mygcv;
- XGetGCValues (mydpy, XDefaultGC (mydpy, XDefaultScreen (mydpy)),
- GCForeground, &mygcv);
- mygc = XCreateGC (mydpy, mywindow, GCForeground, &mygcv);
- }
-}
+ struct state *st = (struct state *) closure;
-#ifdef VERMICULATE_STANDALONE
-/* Function Name: GetVRoot (slightly changed from the X Windows FAQ)
- * Description: Gets the root window, even if it's a virtual root
- * Arguments: the display and the screen
- * Returns: the root window for the client
- */
-static Window
-GetVRoot (Display * dpy, int scr)
-{
- Window rootReturn, parentReturn, *children;
- unsigned int numChildren;
- Window root = RootWindow (dpy, scr);
- Atom __SWM_VROOT = None;
- int i;
-
- __SWM_VROOT = XInternAtom (dpy, "__SWM_VROOT", False);
- XQueryTree (dpy, root, &rootReturn, &parentReturn, &children, &numChildren);
- for (i = 0; i < numChildren; i++)
+ if (st->point)
{
- Atom actual_type;
- int actual_format;
- unsigned long int nitems, bytesafter;
- Window *newRoot = NULL;
-
- if (XGetWindowProperty (dpy, children[i], __SWM_VROOT, 0, 1,
- False, XA_WINDOW, &actual_type, &actual_format,
- &nitems, &bytesafter,
- (unsigned char **) &newRoot) == Success
- && newRoot)
- {
- root = *newRoot;
- break;
- }
+ free(st->point);
}
-
- XFree ((char *) children);
- return root;
+ free (st);
}
-int
-main (int argc, char **argv)
-{
- int argnum;
- if ((mydpy = XOpenDisplay (NULL)) == NULL)
- {
- fprintf (stderr, "%s: cannot connect to X server %s\n", argv[0],
- XDisplayName (NULL));
- exit (1);
- }
- for (argnum = 1; argnum < argc; argnum++)
- {
- if (!strcmp (argv[argnum], "-geometry"))
- {
- int x, y;
- unsigned int uh, uw;
- XParseGeometry (argv[++argnum], &x, &y, &uw, &uh);
- hei = (int) uh;
- wid = (int) uw;
- }
- else if (!strcmp (argv[argnum], "-instring"))
- instring = argv[++argnum];
- else if (!strcmp (argv[argnum], "-root"))
- use_root = True;
- else if (!strcmp (argv[argnum], "-speed"))
- speed = atoi (argv[++argnum]);
- else
- {
- fprintf (stderr,
- "\nvermiculate options are:"
- "\n -speed NUMBER: set speed, can be from 1 to %d."
- "\n -root: use root window."
- "\n -instring STRING: put STRING in kbd buffer."
- "\n -geometry WIDTHxHEIGHT \n", SPEEDMAX);
- exit (1);
- }
- }
+static const char *vermiculate_defaults[] = {
+ ".lowrez: true",
+ ".background: Black",
+ "*ticks: 20000",
+ "*fpsSolid: true",
+ "*speed: 1",
+ "*instring: ",
+#ifdef HAVE_MOBILE
+ "*ignoreRotation: True",
+#endif
+ 0
+};
- if (use_root)
- mywindow = GetVRoot (mydpy, DefaultScreen (mydpy));
- else
- mywindow = XCreateSimpleWindow (mydpy, DefaultRootWindow (mydpy), 0, 0,
- wid, hei, 0, 0, BlackPixel (mydpy,
- DefaultScreen
- (mydpy)));
- XStoreName (mydpy, mywindow, "vermiculate");
- XMapWindow (mydpy, mywindow);
- commonXinit ();
- XSelectInput (mydpy, mywindow,
- KeyPressMask | ExposureMask | StructureNotifyMask);
-
-#undef ya_rand_init
- ya_rand_init (0);
-
- vermiculate_main ();
- return 0;
-}
+static XrmOptionDescRec vermiculate_options[] = {
+ {"-speed", ".speed", XrmoptionSepArg, 0},
+ {"-instring", ".instring", XrmoptionSepArg, 0},
+ {0, 0, 0, 0}
+};
-#else
-void
-screenhack (Display * d, Window w)
-{
- mydpy = d;
- mywindow = w;
- instring = get_string_resource ("instring", "Instring");
- max_ticks = get_integer_resource ("ticks", "Integer");
- {
- int temp = get_integer_resource ("speed", "Speed");
- if (temp != 0)
- speed = temp;
- }
- commonXinit ();
- mycolors[0].pixel = BlackPixel (mydpy, DefaultScreen (mydpy));
- vermiculate_main ();
-}
-#endif /* VERMICULATE_STANDALONE */
+XSCREENSAVER_MODULE ("Vermiculate", vermiculate)