/* $NetBSD: twinkle2.c,v 1.6 2005/05/23 04:04:49 christos Exp $ */ /* * * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)twinkle2.c 8.1 (Berkeley) 6/8/93 */ #include #include #include #include #define NCOLS 80 #define NLINES 24 #define MAXPATTERNS 4 typedef struct { int y, x; } LOCS; static LOCS Layout[NCOLS * NLINES]; /* current board layout */ static int Pattern, /* current pattern number */ Numstars; /* number of stars in pattern */ static void puton(char); static void die(int); static void makeboard(void); static int ison(int, int); static int AM; static char *VS; static char *TI; static char *CL; int main(void) { char *sp; char buf[1024]; char *ptr = buf; srand(getpid()); /* initialize random sequence */ if (isatty(0)) { initscr(); gettmode(); if ((sp = getenv("TERM")) != NULL) setterm(sp); signal(SIGINT, die); } else { printf("Need a terminal on fd=%d\n", 0); exit(1); } tgetent(buf, sp); AM = tgetflag("am"); TI = tgetstr("ti", &ptr); if (TI == NULL) { printf("terminal does not have the ti capability\n"); exit(1); } VS = tgetstr("vs", &ptr); if (VS == NULL) { printf("terminal does not have the vs capability\n"); exit(1); } CL = tgetstr("cl", &ptr); if (CL == NULL) { printf("terminal does not have the cl capability\n"); exit(1); } puts(TI); puts(VS); noecho(); nonl(); tputs(CL, NLINES, putchar); for (;;) { makeboard(); /* make the board setup */ puton('*'); /* put on '*'s */ puton(' '); /* cover up with ' 's */ } } /* * On program exit, move the cursor to the lower left corner by * direct addressing, since current location is not guaranteed. * We lie and say we used to be at the upper right corner to guarantee * absolute addressing. */ static void die(int n) { signal(SIGINT, SIG_IGN); mvcur(0, COLS - 1, LINES - 1, 0); endwin(); exit(n); } static void puton(char ch) { LOCS *lp; int r; LOCS *end; LOCS temp; static int lasty, lastx; end = &Layout[Numstars]; for (lp = Layout; lp < end; lp++) { r = rand() % Numstars; temp = *lp; *lp = Layout[r]; Layout[r] = temp; } for (lp = Layout; lp < end; lp++) /* prevent scrolling */ if (!AM || (lp->y < NLINES - 1 || lp->x < NCOLS - 1)) { mvcur(lasty, lastx, lp->y, lp->x); putchar(ch); lasty = lp->y; if ((lastx = lp->x + 1) >= NCOLS) if (AM) { lastx = 0; lasty++; } else lastx = NCOLS - 1; } } /* * Make the current board setup. It picks a random pattern and * calls ison() to determine if the character is on that pattern * or not. */ static void makeboard(void) { int y, x; LOCS *lp; Pattern = rand() % MAXPATTERNS; lp = Layout; for (y = 0; y < NLINES; y++) for (x = 0; x < NCOLS; x++) if (ison(y, x)) { lp->y = y; lp->x = x; lp++; } Numstars = lp - Layout; } /* * Return TRUE if (y, x) is on the current pattern. */ static int ison(int y, int x) { switch (Pattern) { case 0: /* alternating lines */ return !(y & 01); case 1: /* box */ if (x >= LINES && y >= NCOLS) return FALSE; if (y < 3 || y >= NLINES - 3) return TRUE; return (x < 3 || x >= NCOLS - 3); case 2: /* holy pattern! */ return ((x + y) & 01); case 3: /* bar across center */ return (y >= 9 && y <= 15); } /* NOTREACHED */ }