Project

General

Profile

Statistics
| Branch: | Revision:

root / prex-0.9.0 / usr / sample / tetris / screen.c @ 03e9c04a

History | View | Annotate | Download (5.06 KB)

1 03e9c04a Brad Neuman
/*-
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
}