1 /* 2 * Copyright (c) 1980 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 char copyright[] = 20 "@(#) Copyright (c) 1980 The Regents of the University of California.\n\ 21 All rights reserved.\n"; 22 #endif /* not lint */ 23 24 #ifndef lint 25 static char sccsid[] = "@(#)life.c 6.2 (Berkeley) 03/17/89"; 26 #endif /* not lint */ 27 28 # include <curses.h> 29 # include <signal.h> 30 31 /* 32 * Run a life game. This is a demonstration program for 33 * the Screen Updating section of the -lcurses cursor package. 34 */ 35 36 typedef struct lst_st { /* linked list element */ 37 int y, x; /* (y, x) position of piece */ 38 struct lst_st *next, *last; /* doubly linked */ 39 } LIST; 40 41 LIST *Head; /* head of linked list */ 42 43 int die(); 44 45 main(ac, av) 46 int ac; 47 char *av[]; 48 { 49 evalargs(ac, av); /* evaluate arguments */ 50 51 initscr(); /* initialize screen package */ 52 signal(SIGINT, die); /* set to restore tty stats */ 53 cbreak(); /* set for char-by-char */ 54 noecho(); /* input */ 55 nonl(); /* for optimization */ 56 57 getstart(); /* get starting position */ 58 for (;;) { 59 prboard(); /* print out current board */ 60 update(); /* update board position */ 61 } 62 } 63 64 /* 65 * This is the routine which is called when rubout is hit. 66 * It resets the tty stats to their original values. This 67 * is the normal way of leaving the program. 68 */ 69 die() 70 { 71 signal(SIGINT, SIG_IGN); /* ignore rubouts */ 72 mvcur(0, COLS - 1, LINES - 1, 0); /* go to bottom of screen */ 73 endwin(); /* set terminal to good state */ 74 exit(0); 75 } 76 77 /* 78 * Get the starting position from the user. They keys u, i, o, j, l, 79 * m, ,, and . are used for moving their relative directions from the 80 * k key. Thus, u move diagonally up to the left, , moves directly down, 81 * etc. x places a piece at the current position, " " takes it away. 82 * The input can also be from a file. The list is built after the 83 * board setup is ready. 84 */ 85 getstart() 86 { 87 reg char c; 88 reg int x, y; 89 auto char buf[100]; 90 91 box(stdscr, '|', '_'); /* box in the screen */ 92 move(1, 1); /* move to upper left corner */ 93 94 for (;;) { 95 refresh(); /* print current position */ 96 if ((c = getch()) == 'q') 97 break; 98 switch (c) { 99 case 'u': 100 case 'i': 101 case 'o': 102 case 'j': 103 case 'l': 104 case 'm': 105 case ',': 106 case '.': 107 adjustyx(c); 108 break; 109 case 'f': 110 mvaddstr(0, 0, "File name: "); 111 getstr(buf); 112 readfile(buf); 113 break; 114 case 'x': 115 addch('X'); 116 break; 117 case ' ': 118 addch(' '); 119 break; 120 } 121 } 122 123 if (Head != NULL) /* start new list */ 124 dellist(Head); 125 Head = malloc(sizeof (LIST)); 126 127 /* 128 * loop through the screen looking for 'x's, and add a list 129 * element for each one 130 */ 131 for (y = 1; y < LINES - 1; y++) 132 for (x = 1; x < COLS - 1; x++) { 133 move(y, x); 134 if (inch() == 'x') 135 addlist(y, x); 136 } 137 } 138 139 /* 140 * Print out the current board position from the linked list 141 */ 142 prboard() { 143 144 reg LIST *hp; 145 146 erase(); /* clear out last position */ 147 box(stdscr, '|', '_'); /* box in the screen */ 148 149 /* 150 * go through the list adding each piece to the newly 151 * blank board 152 */ 153 for (hp = Head; hp; hp = hp->next) 154 mvaddch(hp->y, hp->x, 'X'); 155 156 refresh(); 157 } 158