]> git.cameronkatri.com Git - bsdgames-darwin.git/blobdiff - tetris/screen.c
Typo patrol
[bsdgames-darwin.git] / tetris / screen.c
index 41e3f4a8b8321c6caa1ebabf055168581b0a37a6..ffb57bb41a8bf80d693ac925a155fb678c6f15ee 100644 (file)
@@ -1,3 +1,5 @@
+/*     $NetBSD: screen.c,v 1.22 2008/01/28 01:38:59 dholland Exp $     */
+
 /*-
  * Copyright (c) 1992, 1993
  *     The Regents of the University of California.  All rights reserved.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -40,7 +38,7 @@
  * Tetris screen control.
  */
 
-#include <sgtty.h>
+#include <sys/cdefs.h>
 #include <sys/ioctl.h>
 
 #include <setjmp.h>
@@ -48,6 +46,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <termcap.h>
+#include <termios.h>
 #include <unistd.h>
 
 #ifndef sigmask
 #include "screen.h"
 #include "tetris.h"
 
-/*
- * XXX - need a <termcap.h>
- */
-int    tgetent __P((char *, const char *));
-int    tgetflag __P((const char *));
-int    tgetnum __P((const char *));
-int    tputs __P((const char *, int, int (*)(int)));
-
 static cell curscreen[B_SIZE]; /* 1 => standout (or otherwise marked) */
 static int curscore;
 static int isset;              /* true => terminal is in game mode */
-static struct sgttyb oldtt;
-static void (*tstp)();
+static struct termios oldtt;
+static void (*tstp)(int);
 
-char   *tgetstr(), *tgoto();
+static void    scr_stop(int);
+static void    stopset(int) __dead;
 
 
 /*
  * Capabilities from TERMCAP.
  */
-char   PC, *BC, *UP;           /* tgoto requires globals: ugh! */
 short  ospeed;
 
 static char
@@ -106,27 +98,26 @@ struct tcsinfo {   /* termcap string info; some abbrevs above */
        char tcname[3];
        char **tcaddr;
 } tcstrings[] = {
-       "bc", &bcstr,
-       "ce", &CEstr,
-       "cl", &CLstr,
-       "cm", &CMstr,
+       {"bc", &bcstr},
+       {"ce", &CEstr},
+       {"cl", &CLstr},
+       {"cm", &CMstr},
 #ifdef unneeded
-       "cr", &CRstr,
+       {"cr", &CRstr},
 #endif
-       "le", &BC,              /* move cursor left one space */
-       "pc", &pcstr,
-       "se", &SEstr,
-       "so", &SOstr,
-       "te", &TEstr,
-       "ti", &TIstr,
-       "up", &UP,              /* cursor up */
-       0
+       {"le", &BC},            /* move cursor left one space */
+       {"pc", &pcstr},
+       {"se", &SEstr},
+       {"so", &SOstr},
+       {"te", &TEstr},
+       {"ti", &TIstr},
+       {"up", &UP},            /* cursor up */
+       { {0}, NULL}
 };
 
 /* This is where we will actually stuff the information */
 
-static char combuf[1024], tbuf[1024];
-
+static struct tinfo *info;
 
 /*
  * Routine used by tputs().
@@ -145,7 +136,15 @@ put(c)
  * count=1.  (See screen.h for putpad().)
  */
 #define        putstr(s)       (void)fputs(s, stdout)
-#define        moveto(r, c)    putpad(tgoto(CMstr, c, r))
+
+void
+moveto(int r, int c)
+{
+       char buf[256];
+
+       if (t_goto(info, CMstr, c, r, buf, 255) == 0)
+               putpad(buf);
+}
 
 /*
  * Set up from termcap.
@@ -157,46 +156,46 @@ scr_init()
 #ifdef unneeded
        static int ncflag;
 #endif
-       char *term, *fill;
+       char *term;
        static struct tcninfo { /* termcap numeric and flag info */
                char tcname[3];
                int *tcaddr;
        } tcflags[] = {
-               "bs", &bsflag,
-               "ms", &MSflag,
+               {"bs", &bsflag},
+               {"ms", &MSflag},
 #ifdef unneeded
-               "nc", &ncflag,
+               {"nc", &ncflag},
 #endif
-               "xs", &xsflag,
-               0
+               {"xs", &xsflag},
+               { {0}, NULL}
        }, tcnums[] = {
-               "co", &COnum,
-               "li", &LInum,
-               "sg", &sgnum,
-               0
+               {"co", &COnum},
+               {"li", &LInum},
+               {"sg", &sgnum},
+               { {0}, NULL}
        };
-       
+       static char backspace[] = "\b";
+
        if ((term = getenv("TERM")) == NULL)
                stop("you must set the TERM environment variable");
-       if (tgetent(tbuf, term) <= 0)
+       if (t_getent(&info, term) <= 0)
                stop("cannot find your termcap");
-       fill = combuf;
        {
-               register struct tcsinfo *p;
+               struct tcsinfo *p;
 
                for (p = tcstrings; p->tcaddr; p++)
-                       *p->tcaddr = tgetstr(p->tcname, &fill);
+                       *p->tcaddr = t_agetstr(info, p->tcname);
        }
        {
-               register struct tcninfo *p;
+               struct tcninfo *p;
 
                for (p = tcflags; p->tcaddr; p++)
-                       *p->tcaddr = tgetflag(p->tcname);
+                       *p->tcaddr = t_getflag(info, p->tcname);
                for (p = tcnums; p->tcaddr; p++)
-                       *p->tcaddr = tgetnum(p->tcname);
+                       *p->tcaddr = t_getnum(info, p->tcname);
        }
        if (bsflag)
-               BC = "\b";
+               BC = backspace;
        else if (BC == NULL && bcstr != NULL)
                BC = bcstr;
        if (CLstr == NULL)
@@ -217,24 +216,31 @@ scr_init()
 /* this foolery is needed to modify tty state `atomically' */
 static jmp_buf scr_onstop;
 
-#define        sigunblock(mask) sigsetmask(sigblock(0) & ~(mask))
-
 static void
 stopset(sig)
        int sig;
 {
+       sigset_t set;
+
        (void) signal(sig, SIG_DFL);
        (void) kill(getpid(), sig);
-       (void) sigunblock(sigmask(sig));
+       sigemptyset(&set);
+       sigaddset(&set, sig);
+       (void) sigprocmask(SIG_UNBLOCK, &set, (sigset_t *)0);
        longjmp(scr_onstop, 1);
 }
 
 static void
-scr_stop()
+scr_stop(sig)
+       int sig;
 {
+       sigset_t set;
+
        scr_end();
-       (void) kill(getpid(), SIGTSTP);
-       (void) sigunblock(sigmask(SIGTSTP));
+       (void) kill(getpid(), sig);
+       sigemptyset(&set);
+       sigaddset(&set, sig);
+       (void) sigprocmask(SIG_UNBLOCK, &set, (sigset_t *)0);
        scr_set();
        scr_msg(key_msg, 1);
 }
@@ -246,22 +252,25 @@ void
 scr_set()
 {
        struct winsize ws;
-       struct sgttyb newtt;
-       volatile int omask;
-       void (*ttou)();
-
-       omask = sigblock(sigmask(SIGTSTP) | sigmask(SIGTTOU));
+       struct termios newtt;
+       sigset_t nsigset, osigset;
+       void (*ttou)(int);
+
+       sigemptyset(&nsigset);
+       sigaddset(&nsigset, SIGTSTP);
+       sigaddset(&nsigset, SIGTTOU);
+       (void) sigprocmask(SIG_BLOCK, &nsigset, &osigset);
        if ((tstp = signal(SIGTSTP, stopset)) == SIG_IGN)
                (void) signal(SIGTSTP, SIG_IGN);
-       if ((ttou = signal(SIGTSTP, stopset)) == SIG_IGN)
-               (void) signal(SIGTSTP, SIG_IGN);
+       if ((ttou = signal(SIGTTOU, stopset)) == SIG_IGN)
+               (void) signal(SIGTTOU, SIG_IGN);
        /*
         * At last, we are ready to modify the tty state.  If
         * we stop while at it, stopset() above will longjmp back
         * to the setjmp here and we will start over.
         */
        (void) setjmp(scr_onstop);
-       (void) sigsetmask(omask);
+       (void) sigprocmask(SIG_SETMASK, &osigset, (sigset_t *)0);
        Rows = 0, Cols = 0;
        if (ioctl(0, TIOCGWINSZ, &ws) == 0) {
                Rows = ws.ws_row;
@@ -273,20 +282,19 @@ scr_set()
        Cols = COnum;
        if (Rows < MINROWS || Cols < MINCOLS) {
                (void) fprintf(stderr,
-                   "the screen is too small: must be at least %d x %d",
-                   MINROWS, MINCOLS);
+                   "the screen is too small: must be at least %dx%d, ",
+                   MINCOLS, MINROWS);
                stop("");       /* stop() supplies \n */
        }
-       if (ioctl(0, TIOCGETP, &oldtt))
-               stop("ioctl(TIOCGETP) fails");
+       if (tcgetattr(0, &oldtt) < 0)
+               stop("tcgetattr() fails");
        newtt = oldtt;
-       newtt.sg_flags = (newtt.sg_flags | CBREAK) & ~(CRMOD | ECHO);
-       if ((newtt.sg_flags & TBDELAY) == XTABS)
-               newtt.sg_flags &= ~TBDELAY;
-       if (ioctl(0, TIOCSETN, &newtt))
-               stop("ioctl(TIOCSETN) fails");
-       ospeed = newtt.sg_ospeed;
-       omask = sigblock(sigmask(SIGTSTP) | sigmask(SIGTTOU));
+       newtt.c_lflag &= ~(ICANON|ECHO);
+       newtt.c_oflag &= ~OXTABS;
+       if (tcsetattr(0, TCSADRAIN, &newtt) < 0)
+               stop("tcsetattr() fails");
+       ospeed = cfgetospeed(&newtt);
+       (void) sigprocmask(SIG_BLOCK, &nsigset, &osigset);
 
        /*
         * We made it.  We are now in screen mode, modulo TIstr
@@ -296,10 +304,11 @@ scr_set()
                putstr(TIstr);  /* termcap(5) says this is not padded */
        if (tstp != SIG_IGN)
                (void) signal(SIGTSTP, scr_stop);
-       (void) signal(SIGTTOU, ttou);
+       if (ttou != SIG_IGN)
+               (void) signal(SIGTTOU, ttou);
 
        isset = 1;
-       (void) sigsetmask(omask);
+       (void) sigprocmask(SIG_SETMASK, &osigset, (sigset_t *)0);
        scr_clear();
 }
 
@@ -309,8 +318,12 @@ scr_set()
 void
 scr_end()
 {
-       int omask = sigblock(sigmask(SIGTSTP) | sigmask(SIGTTOU));
+       sigset_t nsigset, osigset;
 
+       sigemptyset(&nsigset);
+       sigaddset(&nsigset, SIGTSTP);
+       sigaddset(&nsigset, SIGTTOU);
+       (void) sigprocmask(SIG_BLOCK, &nsigset, &osigset);
        /* move cursor to last line */
        if (LLstr)
                putstr(LLstr);  /* termcap(5) says this is not padded */
@@ -320,16 +333,16 @@ scr_end()
        if (TEstr)
                putstr(TEstr);  /* termcap(5) says this is not padded */
        (void) fflush(stdout);
-       (void) ioctl(0, TIOCSETN, &oldtt);
+       (void) tcsetattr(0, TCSADRAIN, &oldtt);
        isset = 0;
        /* restore signals */
        (void) signal(SIGTSTP, tstp);
-       (void) sigsetmask(omask);
+       (void) sigprocmask(SIG_SETMASK, &osigset, (sigset_t *)0);
 }
 
 void
 stop(why)
-       char *why;
+       const char *why;
 {
 
        if (isset)
@@ -347,7 +360,7 @@ scr_clear()
 
        putpad(CLstr);
        curscore = -1;
-       bzero((char *)curscreen, sizeof(curscreen));
+       memset((char *)curscreen, 0, sizeof(curscreen));
 }
 
 #if vax && !__GNUC__
@@ -362,10 +375,15 @@ typedef cell regcell;
 void
 scr_update()
 {
-       register cell *bp, *sp;
-       register regcell so, cur_so = 0;
-       register int i, ccol, j;
-       int omask = sigblock(sigmask(SIGTSTP));
+       cell *bp, *sp;
+       regcell so, cur_so = 0;
+       int i, ccol, j;
+       sigset_t nsigset, osigset;
+       static const struct shape *lastshape;
+
+       sigemptyset(&nsigset);
+       sigaddset(&nsigset, SIGTSTP);
+       (void) sigprocmask(SIG_BLOCK, &nsigset, &osigset);
 
        /* always leave cursor after last displayed point */
        curscreen[D_LAST * B_COLS - 1] = -1;
@@ -375,10 +393,44 @@ scr_update()
                        putpad(HOstr);
                else
                        moveto(0, 0);
-               (void) printf("%d", score);
+               (void) printf("Score: %d", score);
                curscore = score;
        }
 
+       /* draw preview of nextpattern */
+       if (showpreview && (nextshape != lastshape)) {
+               static int r=5, c=2;
+               int tr, tc, t; 
+
+               lastshape = nextshape;
+               
+               /* clean */
+               putpad(SEstr);
+               moveto(r-1, c-1); putstr("          ");
+               moveto(r,   c-1); putstr("          ");
+               moveto(r+1, c-1); putstr("          ");
+               moveto(r+2, c-1); putstr("          ");
+
+               moveto(r-3, c-2);
+               putstr("Next shape:");
+                                               
+               /* draw */
+               putpad(SOstr);
+               moveto(r, 2*c);
+               putstr("  ");
+               for(i=0; i<3; i++) {
+                       t = c + r*B_COLS;
+                       t += nextshape->off[i];
+
+                       tr = t / B_COLS;
+                       tc = t % B_COLS;
+
+                       moveto(tr, 2*tc);
+                       putstr("  ");
+               }
+               putpad(SEstr);
+       }
+       
        bp = &board[D_FIRST * B_COLS];
        sp = &curscreen[D_FIRST * B_COLS];
        for (j = D_FIRST; j < D_LAST; j++) {
@@ -425,7 +477,7 @@ scr_update()
        if (cur_so)
                putpad(SEstr);
        (void) fflush(stdout);
-       (void) sigsetmask(omask);
+       (void) sigprocmask(SIG_SETMASK, &osigset, (sigset_t *)0);
 }
 
 /*
@@ -434,12 +486,12 @@ scr_update()
  */
 void
 scr_msg(s, set)
-       register char *s;
+       char *s;
        int set;
 {
        
        if (set || CEstr == NULL) {
-               register int l = strlen(s);
+               int l = strlen(s);
 
                moveto(Rows - 2, ((Cols - l) >> 1) - 1);
                if (set)