source: mainline/tetris/screen.c@ e1c4849

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since e1c4849 was b917098, checked in by Ondrej Palkovsky <ondrap@…>, 19 years ago

Slowly porting tetris screen… not yet done.

  • Property mode set to 100644
File size: 7.9 KB
Line 
1/* $OpenBSD: screen.c,v 1.13 2006/04/20 03:25:36 ray Exp $ */
2/* $NetBSD: screen.c,v 1.4 1995/04/29 01:11:36 mycroft Exp $ */
3
4/*-
5 * Copyright (c) 1992, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Chris Torek and Darren F. Provine.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * @(#)screen.c 8.1 (Berkeley) 5/31/93
36 */
37
38/*
39 * Tetris screen control.
40 */
41
42#include <err.h>
43#include <stdio.h>
44#include <stdlib.h>
45#include <string.h>
46#include <unistd.h>
47#include <io/stream.h>
48
49#include "screen.h"
50#include "tetris.h"
51
52static cell curscreen[B_SIZE]; /* 1 => standout (or otherwise marked) */
53static int curscore;
54static int isset; /* true => terminal is in game mode */
55static struct termios oldtt;
56static void (*tstp)(int);
57
58static void scr_stop(int);
59static void stopset(int);
60
61/*
62 * Capabilities from TERMCAP.
63 */
64char PC, *BC, *UP; /* tgoto requires globals: ugh! */
65
66static char
67 *bcstr, /* backspace char */
68 *CEstr, /* clear to end of line */
69 *CLstr, /* clear screen */
70 *CMstr, /* cursor motion string */
71#ifdef unneeded
72 *CRstr, /* "\r" equivalent */
73#endif
74 *HOstr, /* cursor home */
75 *LLstr, /* last line, first column */
76 *pcstr, /* pad character */
77 *TEstr, /* end cursor motion mode */
78 *TIstr; /* begin cursor motion mode */
79char
80 *SEstr, /* end standout mode */
81 *SOstr; /* begin standout mode */
82static int
83 COnum, /* co# value */
84 LInum, /* li# value */
85 MSflag; /* can move in standout mode */
86
87
88struct tcsinfo { /* termcap string info; some abbrevs above */
89 char tcname[3];
90 char **tcaddr;
91} tcstrings[] = {
92 {"bc", &bcstr},
93 {"ce", &CEstr},
94 {"cl", &CLstr},
95 {"cm", &CMstr},
96#ifdef unneeded
97 {"cr", &CRstr},
98#endif
99 {"le", &BC}, /* move cursor left one space */
100 {"pc", &pcstr},
101 {"se", &SEstr},
102 {"so", &SOstr},
103 {"te", &TEstr},
104 {"ti", &TIstr},
105 {"up", &UP}, /* cursor up */
106 { {0}, NULL}
107};
108
109/* This is where we will actually stuff the information */
110
111static char combuf[1024], tbuf[1024];
112
113
114/*
115 * Routine used by tputs().
116 */
117int
118put(int c)
119{
120
121 return (putchar(c));
122}
123
124/*
125 * putstr() is for unpadded strings (either as in termcap(5) or
126 * simply literal strings); putpad() is for padded strings with
127 * count=1. (See screen.h for putpad().)
128 */
129#define putstr(s) (void)fputs(s, stdout)
130#define moveto(r, c) putpad(tgoto(CMstr, c, r))
131
132static int con_phone;
133
134/*
135 * Set up from termcap.
136 */
137void
138scr_init(void)
139{
140 con_phone = get_fd_phone(1);
141}
142
143
144static void
145scr_stop(int sig)
146{
147
148 scr_end();
149 scr_set();
150 scr_msg(key_msg, 1);
151}
152
153/*
154 * Set up screen mode.
155 */
156void
157scr_set(void)
158{
159 struct winsize ws;
160 struct termios newtt;
161 void (*ttou)(int);
162
163 Rows = 0, Cols = 0;
164 if (ioctl(0, TIOCGWINSZ, &ws) == 0) {
165 Rows = ws.ws_row;
166 Cols = ws.ws_col;
167 }
168 if (Rows == 0)
169 Rows = LInum;
170 if (Cols == 0)
171 Cols = COnum;
172 if (Rows < MINROWS || Cols < MINCOLS) {
173 char smallscr[55];
174
175 (void)snprintf(smallscr, sizeof(smallscr),
176 "the screen is too small (must be at least %dx%d)",
177 MINROWS, MINCOLS);
178 stop(smallscr);
179 }
180 if (tcgetattr(0, &oldtt) < 0)
181 stop("tcgetattr() fails");
182 newtt = oldtt;
183 newtt.c_lflag &= ~(ICANON|ECHO);
184 newtt.c_oflag &= ~OXTABS;
185 if (tcsetattr(0, TCSADRAIN, &newtt) < 0)
186 stop("tcsetattr() fails");
187
188 /*
189 * We made it. We are now in screen mode, modulo TIstr
190 * (which we will fix immediately).
191 */
192 if (TIstr)
193 putstr(TIstr); /* termcap(5) says this is not padded */
194
195 isset = 1;
196
197 scr_clear();
198}
199
200/*
201 * End screen mode.
202 */
203void
204scr_end(void)
205{
206}
207
208void
209stop(char *why)
210{
211
212 if (isset)
213 scr_end();
214 errx(1, "aborting: %s", why);
215}
216
217/*
218 * Clear the screen, forgetting the current contents in the process.
219 */
220void
221scr_clear(void)
222{
223
224 putpad(CLstr);
225 curscore = -1;
226 memset((char *)curscreen, 0, sizeof(curscreen));
227}
228
229#if vax && !__GNUC__
230typedef int regcell; /* pcc is bad at `register char', etc */
231#else
232typedef cell regcell;
233#endif
234
235/*
236 * Update the screen.
237 */
238void
239scr_update(void)
240{
241 cell *bp, *sp;
242 regcell so, cur_so = 0;
243 int i, ccol, j;
244 static const struct shape *lastshape;
245
246 /* always leave cursor after last displayed point */
247 curscreen[D_LAST * B_COLS - 1] = -1;
248
249 if (score != curscore) {
250 if (HOstr)
251 putpad(HOstr);
252 else
253 moveto(0, 0);
254 (void) printf("Score: %d", score);
255 curscore = score;
256 }
257
258 /* draw preview of next pattern */
259 if (showpreview && (nextshape != lastshape)) {
260 int i;
261 static int r=5, c=2;
262 int tr, tc, t;
263
264 lastshape = nextshape;
265
266 /* clean */
267 putpad(SEstr);
268 moveto(r-1, c-1); putstr(" ");
269 moveto(r, c-1); putstr(" ");
270 moveto(r+1, c-1); putstr(" ");
271 moveto(r+2, c-1); putstr(" ");
272
273 moveto(r-3, c-2);
274 putstr("Next shape:");
275
276 /* draw */
277 if (SOstr)
278 putpad(SOstr);
279 moveto(r, 2 * c);
280 putstr(SOstr ? " " : "[]");
281 for (i = 0; i < 3; i++) {
282 t = c + r * B_COLS;
283 t += nextshape->off[i];
284
285 tr = t / B_COLS;
286 tc = t % B_COLS;
287
288 moveto(tr, 2*tc);
289 putstr(SOstr ? " " : "[]");
290 }
291 putpad(SEstr);
292 }
293
294 bp = &board[D_FIRST * B_COLS];
295 sp = &curscreen[D_FIRST * B_COLS];
296 for (j = D_FIRST; j < D_LAST; j++) {
297 ccol = -1;
298 for (i = 0; i < B_COLS; bp++, sp++, i++) {
299 if (*sp == (so = *bp))
300 continue;
301 *sp = so;
302 if (i != ccol) {
303 if (cur_so && MSflag) {
304 putpad(SEstr);
305 cur_so = 0;
306 }
307 moveto(RTOD(j), CTOD(i));
308 }
309 if (SOstr) {
310 if (so != cur_so) {
311 putpad(so ? SOstr : SEstr);
312 cur_so = so;
313 }
314 putstr(" ");
315 } else
316 putstr(so ? "[]" : " ");
317 ccol = i + 1;
318 /*
319 * Look ahead a bit, to avoid extra motion if
320 * we will be redrawing the cell after the next.
321 * Motion probably takes four or more characters,
322 * so we save even if we rewrite two cells
323 * `unnecessarily'. Skip it all, though, if
324 * the next cell is a different color.
325 */
326#define STOP (B_COLS - 3)
327 if (i > STOP || sp[1] != bp[1] || so != bp[1])
328 continue;
329 if (sp[2] != bp[2])
330 sp[1] = -1;
331 else if (i < STOP && so == bp[2] && sp[3] != bp[3]) {
332 sp[2] = -1;
333 sp[1] = -1;
334 }
335 }
336 }
337 if (cur_so)
338 putpad(SEstr);
339/* (void) fflush(stdout); */
340/* (void) sigprocmask(SIG_SETMASK, &osigset, (sigset_t *)0); */
341}
342
343/*
344 * Write a message (set!=0), or clear the same message (set==0).
345 * (We need its length in case we have to overwrite with blanks.)
346 */
347void
348scr_msg(char *s, int set)
349{
350
351 if (set || CEstr == NULL) {
352 int l = strlen(s);
353
354 moveto(Rows - 2, ((Cols - l) >> 1) - 1);
355 if (set)
356 putstr(s);
357 else
358 while (--l >= 0)
359 (void) putchar(' ');
360 } else {
361 moveto(Rows - 2, 0);
362 putpad(CEstr);
363 }
364}
Note: See TracBrowser for help on using the repository browser.