1 1.6 christos /* $NetBSD: twinkle2.c,v 1.6 2005/05/23 04:04:49 christos Exp $ */ 2 1.1 cgd 3 1.6 christos /* 4 1.6 christos * 5 1.6 christos * Copyright (c) 1980, 1993 6 1.6 christos * The Regents of the University of California. All rights reserved. 7 1.6 christos * 8 1.6 christos * Redistribution and use in source and binary forms, with or without 9 1.6 christos * modification, are permitted provided that the following conditions 10 1.6 christos * are met: 11 1.6 christos * 1. Redistributions of source code must retain the above copyright 12 1.6 christos * notice, this list of conditions and the following disclaimer. 13 1.6 christos * 2. Redistributions in binary form must reproduce the above copyright 14 1.6 christos * notice, this list of conditions and the following disclaimer in the 15 1.6 christos * documentation and/or other materials provided with the distribution. 16 1.6 christos * 3. Neither the name of the University nor the names of its contributors 17 1.6 christos * may be used to endorse or promote products derived from this software 18 1.6 christos * without specific prior written permission. 19 1.6 christos * 20 1.6 christos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 1.6 christos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 1.6 christos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 1.6 christos * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 1.6 christos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 1.6 christos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 1.6 christos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 1.6 christos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 1.6 christos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 1.6 christos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 1.6 christos * SUCH DAMAGE. 31 1.6 christos * 32 1.6 christos * @(#)twinkle2.c 8.1 (Berkeley) 6/8/93 33 1.6 christos */ 34 1.6 christos 35 1.6 christos #include <stdlib.h> 36 1.6 christos #include <unistd.h> 37 1.6 christos #include <curses.h> 38 1.6 christos #include <signal.h> 39 1.6 christos 40 1.6 christos #define NCOLS 80 41 1.6 christos #define NLINES 24 42 1.6 christos #define MAXPATTERNS 4 43 1.6 christos 44 1.6 christos typedef struct { 45 1.6 christos int y, x; 46 1.6 christos } LOCS; 47 1.6 christos 48 1.6 christos static LOCS Layout[NCOLS * NLINES]; /* current board layout */ 49 1.6 christos 50 1.6 christos static int Pattern, /* current pattern number */ 51 1.6 christos Numstars; /* number of stars in pattern */ 52 1.6 christos 53 1.6 christos static void puton(char); 54 1.6 christos static void die(int); 55 1.6 christos static void makeboard(void); 56 1.6 christos static int ison(int, int); 57 1.6 christos 58 1.6 christos static int AM; 59 1.6 christos static char *VS; 60 1.6 christos static char *TI; 61 1.6 christos static char *CL; 62 1.6 christos 63 1.6 christos int 64 1.6 christos main(void) 65 1.1 cgd { 66 1.6 christos char *sp; 67 1.6 christos char buf[1024]; 68 1.6 christos char *ptr = buf; 69 1.1 cgd 70 1.1 cgd srand(getpid()); /* initialize random sequence */ 71 1.1 cgd 72 1.1 cgd if (isatty(0)) { 73 1.6 christos initscr(); 74 1.6 christos gettmode(); 75 1.6 christos if ((sp = getenv("TERM")) != NULL) 76 1.6 christos setterm(sp); 77 1.1 cgd signal(SIGINT, die); 78 1.1 cgd } 79 1.1 cgd else { 80 1.6 christos printf("Need a terminal on fd=%d\n", 0); 81 1.6 christos exit(1); 82 1.6 christos } 83 1.6 christos 84 1.6 christos tgetent(buf, sp); 85 1.6 christos 86 1.6 christos AM = tgetflag("am"); 87 1.6 christos TI = tgetstr("ti", &ptr); 88 1.6 christos if (TI == NULL) { 89 1.6 christos printf("terminal does not have the ti capability\n"); 90 1.1 cgd exit(1); 91 1.1 cgd } 92 1.6 christos VS = tgetstr("vs", &ptr); 93 1.6 christos if (VS == NULL) { 94 1.6 christos printf("terminal does not have the vs capability\n"); 95 1.6 christos exit(1); 96 1.6 christos } 97 1.6 christos CL = tgetstr("cl", &ptr); 98 1.6 christos if (CL == NULL) { 99 1.6 christos printf("terminal does not have the cl capability\n"); 100 1.6 christos exit(1); 101 1.6 christos } 102 1.6 christos puts(TI); 103 1.6 christos puts(VS); 104 1.1 cgd 105 1.1 cgd noecho(); 106 1.1 cgd nonl(); 107 1.6 christos tputs(CL, NLINES, putchar); 108 1.1 cgd for (;;) { 109 1.1 cgd makeboard(); /* make the board setup */ 110 1.1 cgd puton('*'); /* put on '*'s */ 111 1.1 cgd puton(' '); /* cover up with ' 's */ 112 1.1 cgd } 113 1.1 cgd } 114 1.1 cgd 115 1.6 christos /* 116 1.6 christos * On program exit, move the cursor to the lower left corner by 117 1.6 christos * direct addressing, since current location is not guaranteed. 118 1.6 christos * We lie and say we used to be at the upper right corner to guarantee 119 1.6 christos * absolute addressing. 120 1.6 christos */ 121 1.6 christos static void 122 1.6 christos die(int n) 123 1.6 christos { 124 1.6 christos signal(SIGINT, SIG_IGN); 125 1.6 christos mvcur(0, COLS - 1, LINES - 1, 0); 126 1.6 christos endwin(); 127 1.6 christos exit(n); 128 1.6 christos } 129 1.6 christos 130 1.6 christos static void 131 1.6 christos puton(char ch) 132 1.1 cgd { 133 1.6 christos LOCS *lp; 134 1.6 christos int r; 135 1.6 christos LOCS *end; 136 1.1 cgd LOCS temp; 137 1.1 cgd static int lasty, lastx; 138 1.1 cgd 139 1.1 cgd end = &Layout[Numstars]; 140 1.1 cgd for (lp = Layout; lp < end; lp++) { 141 1.1 cgd r = rand() % Numstars; 142 1.1 cgd temp = *lp; 143 1.1 cgd *lp = Layout[r]; 144 1.1 cgd Layout[r] = temp; 145 1.1 cgd } 146 1.1 cgd 147 1.1 cgd for (lp = Layout; lp < end; lp++) 148 1.1 cgd /* prevent scrolling */ 149 1.1 cgd if (!AM || (lp->y < NLINES - 1 || lp->x < NCOLS - 1)) { 150 1.1 cgd mvcur(lasty, lastx, lp->y, lp->x); 151 1.1 cgd putchar(ch); 152 1.1 cgd lasty = lp->y; 153 1.1 cgd if ((lastx = lp->x + 1) >= NCOLS) 154 1.1 cgd if (AM) { 155 1.1 cgd lastx = 0; 156 1.1 cgd lasty++; 157 1.1 cgd } 158 1.1 cgd else 159 1.1 cgd lastx = NCOLS - 1; 160 1.1 cgd } 161 1.1 cgd } 162 1.6 christos 163 1.6 christos /* 164 1.6 christos * Make the current board setup. It picks a random pattern and 165 1.6 christos * calls ison() to determine if the character is on that pattern 166 1.6 christos * or not. 167 1.6 christos */ 168 1.6 christos static void 169 1.6 christos makeboard(void) 170 1.6 christos { 171 1.6 christos int y, x; 172 1.6 christos LOCS *lp; 173 1.6 christos 174 1.6 christos Pattern = rand() % MAXPATTERNS; 175 1.6 christos lp = Layout; 176 1.6 christos for (y = 0; y < NLINES; y++) 177 1.6 christos for (x = 0; x < NCOLS; x++) 178 1.6 christos if (ison(y, x)) { 179 1.6 christos lp->y = y; 180 1.6 christos lp->x = x; 181 1.6 christos lp++; 182 1.6 christos } 183 1.6 christos Numstars = lp - Layout; 184 1.6 christos } 185 1.6 christos 186 1.6 christos /* 187 1.6 christos * Return TRUE if (y, x) is on the current pattern. 188 1.6 christos */ 189 1.6 christos static int 190 1.6 christos ison(int y, int x) 191 1.6 christos { 192 1.6 christos switch (Pattern) { 193 1.6 christos case 0: /* alternating lines */ 194 1.6 christos return !(y & 01); 195 1.6 christos case 1: /* box */ 196 1.6 christos if (x >= LINES && y >= NCOLS) 197 1.6 christos return FALSE; 198 1.6 christos if (y < 3 || y >= NLINES - 3) 199 1.6 christos return TRUE; 200 1.6 christos return (x < 3 || x >= NCOLS - 3); 201 1.6 christos case 2: /* holy pattern! */ 202 1.6 christos return ((x + y) & 01); 203 1.6 christos case 3: /* bar across center */ 204 1.6 christos return (y >= 9 && y <= 15); 205 1.6 christos } 206 1.6 christos /* NOTREACHED */ 207 1.6 christos } 208