Prex Home / Browse Source - Prex Version: 0.9.0

root/usr/sample/tetris/screen.c

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

DEFINITIONS

This source file includes following definitions.
  1. scr_init
  2. scr_set
  3. scr_end
  4. stop
  5. scr_clear
  6. scr_update
  7. scr_msg

   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  *      @(#)screen.c    8.1 (Berkeley) 5/31/93
  33  */
  34 
  35 /* Modified for Prex by Kohsuke Ohtani. */
  36 
  37 /*
  38  * Tetris screen control.
  39  */
  40 
  41 #include <sys/termios.h>
  42 #include <sys/ioctl.h>
  43 
  44 #include <setjmp.h>
  45 #include <signal.h>
  46 #include <stdio.h>
  47 #include <stdlib.h>
  48 #include <string.h>
  49 #include <unistd.h>
  50 
  51 #include "screen.h"
  52 #include "tetris.h"
  53 
  54 static cell curscreen[B_SIZE];  /* 1 => standout (or otherwise marked) */
  55 static int curscore;
  56 static int isset;               /* true => terminal is in game mode */
  57 static struct termios oldtt;
  58 
  59 /*
  60  * putstr() is for unpadded strings (either as in termcap(5) or
  61  * simply literal strings); putpad() is for padded strings with
  62  * count=1.  (See screen.h for putpad().)
  63  */
  64 #define putstr(s)       printf("%s", s)
  65 #define moveto(r, c)    printf("\33[%d;%dH", r, c)
  66 
  67 /*
  68  * Set up from termcap.
  69  */
  70 void
  71 scr_init()
  72 {
  73 }
  74 
  75 /*
  76  * Set up screen mode.
  77  */
  78 void
  79 scr_set(void)
  80 {
  81         struct winsize ws;
  82         struct termios newtt;
  83 
  84         Rows = 0, Cols = 0;
  85         if (ioctl(0, TIOCGWINSZ, &ws) == 0) {
  86                 Rows = (int)ws.ws_row;
  87                 Cols = (int)ws.ws_col;
  88         }
  89         if (Rows == 0)
  90                 Rows = 25;
  91         if (Cols == 0)
  92                 Cols = 80;
  93 
  94         if (tcgetattr(0, &oldtt) < 0)
  95                 stop("tcgetattr() fails");
  96         newtt = oldtt;
  97         newtt.c_lflag &= ~(ICANON|ECHO);
  98         newtt.c_oflag &= ~OXTABS;
  99         if (tcsetattr(0, TCSADRAIN, &newtt) < 0)
 100                 stop("tcsetattr() fails");
 101 
 102         isset = 1;
 103         scr_clear();
 104 }
 105 
 106 /*
 107  * End screen mode.
 108  */
 109 void
 110 scr_end(void)
 111 {
 112 
 113         moveto(Rows - 1, 0);
 114 
 115         /* exit screen mode */
 116         (void) fflush(stdout);
 117         (void) tcsetattr(0, TCSADRAIN, &oldtt);
 118         isset = 0;
 119 }
 120 
 121 void
 122 stop(char *why)
 123 {
 124 
 125         if (isset)
 126                 scr_end();
 127         (void) fprintf(stderr, "aborting: %s\n", why);
 128         exit(1);
 129 }
 130 
 131 /*
 132  * Clear the screen, forgetting the current contents in the process.
 133  */
 134 void
 135 scr_clear(void)
 136 {
 137 
 138         printf("\33[2J");
 139         curscore = -1;
 140         bzero((char *)curscreen, sizeof(curscreen));
 141 }
 142 
 143 #if !__GNUC__
 144 typedef int regcell;    /* pcc is bad at `register char', etc */
 145 #else
 146 typedef cell regcell;
 147 #endif
 148 
 149 /*
 150  * Update the screen.
 151  */
 152 void
 153 scr_update(void)
 154 {
 155         cell *bp, *sp;
 156         regcell so, cur_so = 0;
 157         int i, ccol, j;
 158 
 159         /* always leave cursor after last displayed point */
 160         curscreen[D_LAST * B_COLS - 1] = -1;
 161 
 162         if (score != curscore) {
 163                 moveto(0, 0);
 164                 printf("%d", score);
 165                 curscore = score;
 166         }
 167 
 168         bp = &board[D_FIRST * B_COLS];
 169         sp = &curscreen[D_FIRST * B_COLS];
 170         for (j = D_FIRST; j < D_LAST; j++) {
 171                 ccol = -1;
 172                 for (i = 0; i < B_COLS; bp++, sp++, i++) {
 173                         if (*sp == (so = *bp))
 174                                 continue;
 175                         *sp = so;
 176                         if (i != ccol) {
 177                                 if (cur_so) {
 178                                         cur_so = 0;
 179                                 }
 180                                 moveto(RTOD(j), CTOD(i));
 181                         }
 182                         if (so != cur_so) {
 183                                 cur_so = so;
 184                         }
 185                         putstr(so ? "XX" : "  ");
 186 
 187                         ccol = i + 1;
 188                         /*
 189                          * Look ahead a bit, to avoid extra motion if
 190                          * we will be redrawing the cell after the next.
 191                          * Motion probably takes four or more characters,
 192                          * so we save even if we rewrite two cells
 193                          * `unnecessarily'.  Skip it all, though, if
 194                          * the next cell is a different color.
 195                          */
 196 #define STOP (B_COLS - 3)
 197                         if (i > STOP || sp[1] != bp[1] || so != bp[1])
 198                                 continue;
 199                         if (sp[2] != bp[2])
 200                                 sp[1] = -1;
 201                         else if (i < STOP && so == bp[2] && sp[3] != bp[3]) {
 202                                 sp[2] = -1;
 203                                 sp[1] = -1;
 204                         }
 205                 }
 206         }
 207         (void) fflush(stdout);
 208 }
 209 
 210 /*
 211  * Write a message (set!=0), or clear the same message (set==0).
 212  * (We need its length in case we have to overwrite with blanks.)
 213  */
 214 void
 215 scr_msg(char *s, int set)
 216 {
 217 
 218         int l = (int)strlen(s);
 219 
 220         moveto(Rows - 2, ((Cols - l) >> 1) - 1);
 221         if (set)
 222                 putstr(s);
 223         else
 224                 while (--l >= 0)
 225                         (void) putchar(' ');
 226 }

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