Prex Home / Browse Source - Prex Version: 0.9.0

root/usr/sample/tetris/input.c

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

DEFINITIONS

This source file includes following definitions.
  1. rwait
  2. tsleep
  3. eat_input
  4. tgetchar

   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  *      @(#)input.c     8.1 (Berkeley) 5/31/93
  33  */
  34 
  35 /* Modified for Prex by Kohsuke Ohtani. */
  36 
  37 /*
  38  * Tetris input.
  39  */
  40 
  41 #include <sys/types.h>
  42 #include <sys/time.h>
  43 #include <sys/termios.h>
  44 #include <sys/prex.h>
  45 
  46 #include <errno.h>
  47 #include <unistd.h>
  48 
  49 #include "input.h"
  50 #include "tetris.h"
  51 
  52 /* return true if the given timeval is positive */
  53 #define TV_POS(tv) \
  54         ((tv)->tv_sec > 0 || ((tv)->tv_sec == 0 && (tv)->tv_usec > 0))
  55 
  56 /* subtract timeval `sub' from `res' */
  57 #define TV_SUB(res, sub) \
  58         (res)->tv_sec -= (sub)->tv_sec; \
  59         (res)->tv_usec -= (sub)->tv_usec; \
  60         if ((res)->tv_usec < 0) { \
  61                 (res)->tv_usec += 1000000; \
  62                 (res)->tv_sec--; \
  63         }
  64 
  65 /*
  66  * Do a `read wait': select for reading from stdin, with timeout *tvp.
  67  * On return, modify *tvp to reflect the amount of time spent waiting.
  68  * It will be positive only if input appeared before the time ran out;
  69  * otherwise it will be zero or perhaps negative.
  70  *
  71  * If tvp is nil, wait forever, but return if select is interrupted.
  72  *
  73  * Return 0 => no input, 1 => can read() from stdin
  74  */
  75 int
  76 rwait(struct timeval *tvp)
  77 {
  78         int i, ninq, timeout;
  79         struct timeval starttv, endtv;
  80 #define NILTZ ((struct timezone *)0)
  81 
  82         if (tvp) {
  83                 (void) gettimeofday(&starttv, NILTZ);
  84                 endtv = *tvp;
  85                 timeout = tvp->tv_usec / 1000;
  86         } else
  87                 timeout = 1000;
  88 
  89         /*
  90          * We don't have select() or poll() as for now.
  91          * This is replaced by polling TTY input queue via ioctl().
  92          */
  93         for (i = 0; i < timeout; i++) {
  94                 ioctl(1, TIOCINQ, &ninq);
  95                 if (ninq > 0)
  96                         break;
  97                 timer_sleep(1, 0);      /* wait 1ms */
  98         }
  99         if (i >= timeout) {     /* timed out */
 100                 if (tvp == NULL)
 101                         return (-1);
 102                 else {
 103                         tvp->tv_sec = 0;
 104                         tvp->tv_usec = 0;
 105                         return (0);
 106                 }
 107         }
 108         if (tvp) {
 109                 /* since there is input, we may not have timed out */
 110                 (void) gettimeofday(&endtv, NILTZ);
 111                 TV_SUB(&endtv, &starttv);
 112                 TV_SUB(tvp, &endtv);    /* adjust *tvp by elapsed time */
 113         }
 114         return (1);
 115 }
 116 
 117 /*
 118  * `sleep' for the current turn time (using select).
 119  * Eat any input that might be available.
 120  */
 121 void
 122 tsleep(void)
 123 {
 124         struct timeval tv;
 125         char c;
 126 
 127         tv.tv_sec = 0;
 128         tv.tv_usec = fallrate;
 129         while (TV_POS(&tv))
 130                 if (rwait(&tv) && read(0, &c, 1) != 1)
 131                         break;
 132 }
 133 
 134 /*
 135  * Eat up any input (used at end of game).
 136  */
 137 void
 138 eat_input(void)
 139 {
 140         struct timeval tv;
 141         char c;
 142 
 143         do {
 144                 tv.tv_sec = tv.tv_usec = 0;
 145         } while (rwait(&tv) && read(0, &c, 1) == 1);
 146 }
 147 
 148 /*
 149  * getchar with timeout.
 150  */
 151 int
 152 tgetchar(void)
 153 {
 154         static struct timeval timeleft;
 155         char c;
 156 
 157         /*
 158          * Reset timeleft to fallrate whenever it is not positive.
 159          * In any case, wait to see if there is any input.  If so,
 160          * take it, and update timeleft so that the next call to
 161          * tgetchar() will not wait as long.  If there is no input,
 162          * make timeleft zero or negative, and return -1.
 163          *
 164          * Most of the hard work is done by rwait().
 165          */
 166         if (!TV_POS(&timeleft)) {
 167                 faster();       /* go faster */
 168                 timeleft.tv_sec = 0;
 169                 timeleft.tv_usec = fallrate;
 170         }
 171         if (!rwait(&timeleft))
 172                 return (-1);
 173         if (read(0, &c, 1) != 1)
 174                 stop("end of file, help");
 175         return ((int)(unsigned char)c);
 176 }

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