source: mainline/uspace/app/tetris/screen.c@ 8ccd2ea

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8ccd2ea was ff9244a, checked in by Jakub Jermar <jakub@…>, 18 years ago

Move the open(), read() and write() provided by streams.c away so that
these functions won't clash with the real open(), read() and write(), which are
soon to be provided by a libvfs library. Applications can now use open_stdin(),
open_stdout(), read_stdin() and write_stdout(). Later, there might be an option
of providing a custom console file system, which will work similarly to how
streams' open(), read() and write() worked.

  • Property mode set to 100644
File size: 6.3 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/** @addtogroup tetris
39 * @{
40 */
41/** @file
42 */
43
44/*
45 * Tetris screen control.
46 */
47
48#include <err.h>
49#include <stdio.h>
50#include <stdlib.h>
51#include <string.h>
52#include <unistd.h>
53#include <io/stream.h>
54
55
56#include <async.h>
57#include "screen.h"
58#include "tetris.h"
59#include "../../srv/console/console.h"
60
61static cell curscreen[B_SIZE]; /* 1 => standout (or otherwise marked) */
62static int curscore;
63static int isset; /* true => terminal is in game mode */
64
65
66/*
67 * putstr() is for unpadded strings (either as in termcap(5) or
68 * simply literal strings);
69 */
70static inline void putstr(char *s)
71{
72 while (*s)
73 putchar(*(s++));
74}
75
76static int con_phone;
77
78
79
80static void set_style(int fgcolor, int bgcolor)
81{
82 async_msg_2(con_phone, CONSOLE_SET_STYLE, fgcolor, bgcolor);
83}
84
85static void start_standout(void)
86{
87 set_style(0xf0f0f0, 0);
88}
89
90static void resume_normal(void)
91{
92 set_style(0, 0xf0f0f0);
93}
94
95
96void clear_screen(void)
97{
98 async_msg_0(con_phone, CONSOLE_CLEAR);
99 moveto(0, 0);
100}
101
102/*
103 * Clear the screen, forgetting the current contents in the process.
104 */
105void
106scr_clear(void)
107{
108
109 resume_normal();
110 async_msg_0(con_phone, CONSOLE_CLEAR);
111 curscore = -1;
112 memset((char *)curscreen, 0, sizeof(curscreen));
113}
114
115/*
116 * Set up screen
117 */
118void
119scr_init(void)
120{
121 con_phone = get_cons_phone();
122 async_msg_1(con_phone, CONSOLE_CURSOR_VISIBILITY, 0);
123 resume_normal();
124 scr_clear();
125}
126
127void moveto(int r, int c)
128{
129 async_msg_2(con_phone, CONSOLE_GOTO, r, c);
130}
131
132static void fflush(void)
133{
134 async_msg_0(con_phone, CONSOLE_FLUSH);
135}
136
137winsize_t winsize;
138
139static int get_display_size(winsize_t *ws)
140{
141 return async_req_0_2(con_phone, CONSOLE_GETSIZE, &ws->ws_row,
142 &ws->ws_col);
143}
144
145/*
146 * Set up screen mode.
147 */
148void
149scr_set(void)
150{
151 winsize_t ws;
152
153 Rows = 0, Cols = 0;
154 if (get_display_size(&ws) == 0) {
155 Rows = ws.ws_row;
156 Cols = ws.ws_col;
157 }
158 if (Rows < MINROWS || Cols < MINCOLS) {
159 char smallscr[55];
160
161 snprintf(smallscr, sizeof(smallscr),
162 "the screen is too small (must be at least %dx%d)",
163 MINROWS, MINCOLS);
164 stop(smallscr);
165 }
166 isset = 1;
167
168 scr_clear();
169}
170
171/*
172 * End screen mode.
173 */
174void
175scr_end(void)
176{
177}
178
179void
180stop(char *why)
181{
182
183 if (isset)
184 scr_end();
185 errx(1, "aborting: %s", why);
186}
187
188
189/*
190 * Update the screen.
191 */
192void
193scr_update(void)
194{
195 cell *bp, *sp;
196 cell so, cur_so = 0;
197 int i, ccol, j;
198 static const struct shape *lastshape;
199
200 /* always leave cursor after last displayed point */
201 curscreen[D_LAST * B_COLS - 1] = -1;
202
203 if (score != curscore) {
204 moveto(0, 0);
205 printf("Score: %d", score);
206 curscore = score;
207 }
208
209 /* draw preview of next pattern */
210 if (showpreview && (nextshape != lastshape)) {
211 int i;
212 static int r=5, c=2;
213 int tr, tc, t;
214
215 lastshape = nextshape;
216
217 /* clean */
218 resume_normal();
219 moveto(r-1, c-1); putstr(" ");
220 moveto(r, c-1); putstr(" ");
221 moveto(r+1, c-1); putstr(" ");
222 moveto(r+2, c-1); putstr(" ");
223
224 moveto(r-3, c-2);
225 putstr("Next shape:");
226
227 /* draw */
228 start_standout();
229 moveto(r, 2 * c);
230 putstr(" ");
231 for (i = 0; i < 3; i++) {
232 t = c + r * B_COLS;
233 t += nextshape->off[i];
234
235 tr = t / B_COLS;
236 tc = t % B_COLS;
237
238 moveto(tr, 2*tc);
239 putstr(" ");
240 }
241 resume_normal();
242 }
243
244 bp = &board[D_FIRST * B_COLS];
245 sp = &curscreen[D_FIRST * B_COLS];
246 for (j = D_FIRST; j < D_LAST; j++) {
247 ccol = -1;
248 for (i = 0; i < B_COLS; bp++, sp++, i++) {
249 if (*sp == (so = *bp))
250 continue;
251 *sp = so;
252 if (i != ccol) {
253 if (cur_so) {
254 resume_normal();
255 cur_so = 0;
256 }
257 moveto(RTOD(j), CTOD(i));
258 }
259 if (so != cur_so) {
260 if (so)
261 start_standout();
262 else
263 resume_normal();
264 cur_so = so;
265 }
266 putstr(" ");
267
268 ccol = i + 1;
269 /*
270 * Look ahead a bit, to avoid extra motion if
271 * we will be redrawing the cell after the next.
272 * Motion probably takes four or more characters,
273 * so we save even if we rewrite two cells
274 * `unnecessarily'. Skip it all, though, if
275 * the next cell is a different color.
276 */
277#define STOP (B_COLS - 3)
278 if (i > STOP || sp[1] != bp[1] || so != bp[1])
279 continue;
280 if (sp[2] != bp[2])
281 sp[1] = -1;
282 else if (i < STOP && so == bp[2] && sp[3] != bp[3]) {
283 sp[2] = -1;
284 sp[1] = -1;
285 }
286 }
287 }
288 if (cur_so)
289 resume_normal();
290 fflush();
291}
292
293/*
294 * Write a message (set!=0), or clear the same message (set==0).
295 * (We need its length in case we have to overwrite with blanks.)
296 */
297void
298scr_msg(char *s, int set)
299{
300
301 int l = strlen(s);
302
303 moveto(Rows - 2, ((Cols - l) >> 1) - 1);
304 if (set)
305 putstr(s);
306 else
307 while (--l >= 0)
308 (void) putchar(' ');
309}
310
311/** @}
312 */
313
Note: See TracBrowser for help on using the repository browser.