Prex Home / Browse Source - Prex Version: 0.9.0

root/usr/sample/tetris/tetris.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. setup_board
  2. elide
  3. main
  4. onintr
  5. usage

   1 /*-
   2  * Copyright (c) 1992, 1993
   3  *      The Regents of the University of California.  All rights reserved.
   4  *
   5  * This code is derived from software contributed to Berkeley by
   6  * Chris Torek and Darren F. Provine.
   7  *
   8  * Redistribution and use in source and binary forms, with or without
   9  * modification, are permitted provided that the following conditions
  10  * are met:
  11  * 1. Redistributions of source code must retain the above copyright
  12  *    notice, this list of conditions and the following disclaimer.
  13  * 2. Redistributions in binary form must reproduce the above copyright
  14  *    notice, this list of conditions and the following disclaimer in the
  15  *    documentation and/or other materials provided with the distribution.
  16  * 3. Neither the name of the University nor the names of its contributors
  17  *    may be used to endorse or promote products derived from this software
  18  *    without specific prior written permission.
  19  *
  20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30  * SUCH DAMAGE.
  31  *
  32  *      @(#)tetris.c    8.1 (Berkeley) 5/31/93
  33  */
  34 
  35 /* Modified for Prex by Kohsuke Ohtani. */
  36 
  37 /*
  38  * Tetris (or however it is spelled).
  39  */
  40 
  41 #include <sys/time.h>
  42 #include <sys/param.h>
  43 #ifdef __gba__
  44 #include <sys/keycode.h>
  45 #endif
  46 
  47 #include <signal.h>
  48 #include <stdio.h>
  49 #include <stdlib.h>
  50 #include <string.h>
  51 #include <unistd.h>
  52 
  53 #include "input.h"
  54 #include "screen.h"
  55 #include "tetris.h"
  56 
  57 #ifdef __gba__
  58 static char keys[6] = {K_LEFT, 'A', K_RGHT, K_DOWN, '\n', '\n'};
  59 #else
  60 static char *keys = "jkl pq";
  61 #endif
  62 
  63 cell    board[B_SIZE];          /* 1 => occupied, 0 => empty */
  64 int     Rows, Cols;             /* current screen size */
  65 int     score;                  /* the obvious thing */
  66 char    key_msg[100];
  67 long    fallrate;               /* less than 1 million; smaller => faster */
  68 
  69 void onintr(int);
  70 void usage(void);
  71 
  72 /*
  73  * Set up the initial board.  The bottom display row is completely set,
  74  * along with another (hidden) row underneath that.  Also, the left and
  75  * right edges are set.
  76  */
  77 static void
  78 setup_board(void)
  79 {
  80         int i;
  81         cell *p;
  82 
  83         p = board;
  84         for (i = B_SIZE; i; i--)
  85                 *p++ = i <= (2 * B_COLS) || (i % B_COLS) < 2;
  86 }
  87 
  88 /*
  89  * Elide any full active rows.
  90  */
  91 static void
  92 elide(void)
  93 {
  94         int i, j, base;
  95         cell *p;
  96 
  97         for (i = A_FIRST; i < A_LAST; i++) {
  98                 base = i * B_COLS + 1;
  99                 p = &board[base];
 100                 for (j = B_COLS - 2; *p++ != 0;) {
 101                         if (--j <= 0) {
 102                                 /* this row is to be elided */
 103                                 bzero(&board[base], B_COLS - 2);
 104                                 scr_update();
 105                                 tsleep();
 106                                 while (--base != 0)
 107                                         board[base + B_COLS] = board[base];
 108                                 scr_update();
 109                                 tsleep();
 110                                 break;
 111                         }
 112                 }
 113         }
 114 }
 115 
 116 int
 117 main(int argc, char *argv[])
 118 {
 119         int pos, c;
 120         const struct shape *curshape;
 121         int level = 2;
 122 #ifndef __gba__
 123         char key_write[6][10];
 124         int i;
 125 #endif
 126         int ch;
 127 
 128         while ((ch = getopt(argc, argv, "l")) != EOF)
 129                 switch(ch) {
 130                 case 'l':
 131                         level = atoi(optarg);
 132                         if (level < MINLEVEL || level > MAXLEVEL) {
 133                                 (void)fprintf(stderr,
 134                                     "tetris: level must be from %d to %d",
 135                                     MINLEVEL, MAXLEVEL);
 136                                 exit(1);
 137                         }
 138                         break;
 139                 case '?':
 140                 default:
 141                         usage();
 142                 }
 143 
 144         argc -= optind;
 145         argv += optind;
 146 
 147         if (argc)
 148                 usage();
 149 
 150         fallrate = 1000000 / level;
 151 
 152 #ifdef __gba__
 153         /* No help line... */
 154 #else
 155         for (i = 0; i <= 5; i++) {
 156                 if (keys[i] == ' ')
 157                         strcpy(key_write[i], "<space>");
 158                 else {
 159                         key_write[i][0] = keys[i];
 160                         key_write[i][1] = '\0';
 161                 }
 162         }
 163 
 164         sprintf(key_msg,
 165 "%s - left   %s - rotate   %s - right   %s - drop   %s - pause   %s - quit",
 166                 key_write[0], key_write[1], key_write[2], key_write[3],
 167                 key_write[4], key_write[5]);
 168 #endif
 169 
 170         (void)signal(SIGINT, onintr);
 171         scr_init();
 172         setup_board();
 173 
 174         srandom((unsigned long)getpid());
 175         scr_set();
 176 
 177         pos = A_FIRST*B_COLS + (B_COLS/2)-1;
 178         curshape = randshape();
 179 
 180         scr_msg(key_msg, 1);
 181 
 182         for (;;) {
 183                 place(curshape, pos, 1);
 184                 scr_update();
 185 
 186                 place(curshape, pos, 0);
 187                 c = tgetchar();
 188                 if (c < 0) {
 189                         /*
 190                          * Timeout.  Move down if possible.
 191                          */
 192                         if (fits_in(curshape, pos + B_COLS)) {
 193                                 pos += B_COLS;
 194                                 continue;
 195                         }
 196 
 197                         /*
 198                          * Put up the current shape `permanently',
 199                          * bump score, and elide any full rows.
 200                          */
 201                         place(curshape, pos, 1);
 202                         score++;
 203                         elide();
 204 
 205                         /*
 206                          * Choose a new shape.  If it does not fit,
 207                          * the game is over.
 208                          */
 209                         curshape = randshape();
 210                         pos = A_FIRST*B_COLS + (B_COLS/2)-1;
 211                         if (!fits_in(curshape, pos))
 212                                 break;
 213                         continue;
 214                 }
 215 
 216                 /*
 217                  * Handle command keys.
 218                  */
 219                 if (c == keys[5]) {
 220                         /* quit */
 221                         break;
 222                 }
 223                 if (c == keys[4]) {
 224                         static char msg[] =
 225                             "paused - press RETURN to continue";
 226 
 227                         place(curshape, pos, 1);
 228                         do {
 229                                 scr_update();
 230                                 scr_msg(key_msg, 0);
 231                                 scr_msg(msg, 1);
 232                                 (void) fflush(stdout);
 233                         } while (rwait((struct timeval *)NULL) == -1);
 234                         scr_msg(msg, 0);
 235                         scr_msg(key_msg, 1);
 236                         place(curshape, pos, 0);
 237                         continue;
 238                 }
 239                 if (c == keys[0]) {
 240                         /* move left */
 241                         if (fits_in(curshape, pos - 1))
 242                                 pos--;
 243                         continue;
 244                 }
 245                 if (c == keys[1]) {
 246                         /* turn */
 247                         const struct shape *new = &shapes[curshape->rot];
 248 
 249                         if (fits_in(new, pos))
 250                                 curshape = new;
 251                         continue;
 252                 }
 253                 if (c == keys[2]) {
 254                         /* move right */
 255                         if (fits_in(curshape, pos + 1))
 256                                 pos++;
 257                         continue;
 258                 }
 259                 if (c == keys[3]) {
 260                         /* move to bottom */
 261                         while (fits_in(curshape, pos + B_COLS)) {
 262                                 pos += B_COLS;
 263                                 score++;
 264                         }
 265                         continue;
 266                 }
 267                 if (c == '\f')
 268                         scr_clear();
 269         }
 270 
 271         scr_clear();
 272         scr_end();
 273 
 274         (void)printf("Your score:  %d point%s  x  level %d  =  %d\n",
 275             score, score == 1 ? "" : "s", level, score * level);
 276         exit(0);
 277 }
 278 
 279 void
 280 onintr(int signo)
 281 {
 282         scr_clear();
 283         scr_end();
 284         exit(0);
 285 }
 286 
 287 void
 288 usage()
 289 {
 290         (void)fprintf(stderr, "usage: tetris [-l level]\n");
 291         exit(1);
 292 }

/* [<][>][^][v][top][bottom][index][help] */