scoutos / prex-0.9.0 / usr / sample / tetris / screen.c @ 03e9c04a
History | View | Annotate | Download (5.06 KB)
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 |
} |