source: mainline/tetris/tetris.c@ e9073f2

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since e9073f2 was 9996ed5, checked in by Josef Cejka <malyzelenyhnus@…>, 19 years ago

Tetris has now a new menu.
Hiscore table added.

  • Property mode set to 100644
File size: 9.5 KB
Line 
1/* $OpenBSD: tetris.c,v 1.21 2006/04/20 03:24:12 ray Exp $ */
2/* $NetBSD: tetris.c,v 1.2 1995/04/22 07:42:47 cgd 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 * @(#)tetris.c 8.1 (Berkeley) 5/31/93
36 */
37
38#ifndef lint
39static const char copyright[] =
40"@(#) Copyright (c) 1992, 1993\n\
41 The Regents of the University of California. All rights reserved.\n";
42#endif /* not lint */
43
44/*
45 * Tetris (or however it is spelled).
46 */
47
48#include <sys/time.h>
49#include <sys/types.h>
50
51#include <err.h>
52#include <stdio.h>
53#include <stdlib.h>
54#include <string.h>
55#include <unistd.h>
56
57#include "input.h"
58#include "scores.h"
59#include "screen.h"
60#include "tetris.h"
61
62cell board[B_SIZE];
63int Rows, Cols;
64const struct shape *curshape;
65const struct shape *nextshape;
66long fallrate;
67int score;
68//gid_t gid, egid;
69char key_msg[100];
70int showpreview, classic;
71
72static void elide(void);
73static void setup_board(void);
74const struct shape *randshape(void);
75void onintr(int);
76void usage(void);
77
78/*
79 * Set up the initial board. The bottom display row is completely set,
80 * along with another (hidden) row underneath that. Also, the left and
81 * right edges are set.
82 */
83static void
84setup_board(void)
85{
86 int i;
87 cell *p;
88
89 p = board;
90 for (i = B_SIZE; i; i--)
91 *p++ = i <= (2 * B_COLS) || (i % B_COLS) < 2;
92}
93
94/*
95 * Elide any full active rows.
96 */
97static void
98elide(void)
99{
100 int rows = 0;
101 int i, j, base;
102 cell *p;
103
104 for (i = A_FIRST; i < A_LAST; i++) {
105 base = i * B_COLS + 1;
106 p = &board[base];
107 for (j = B_COLS - 2; *p++ != 0;) {
108 if (--j <= 0) {
109 /* this row is to be elided */
110 rows++;
111 memset(&board[base], 0, B_COLS - 2);
112 scr_update();
113 tsleep();
114 while (--base != 0)
115 board[base + B_COLS] = board[base];
116 scr_update();
117 tsleep();
118 break;
119 }
120 }
121 }
122 switch (rows) {
123 case 1:
124 score += 10;
125 break;
126 case 2:
127 score += 30;
128 break;
129 case 3:
130 score += 70;
131 break;
132 case 4:
133 score += 150;
134 break;
135 default:
136 break;
137 }
138}
139
140const struct shape *
141randshape(void)
142{
143 const struct shape *tmp;
144 int i, j;
145
146 tmp = &shapes[random() % 7];
147 j = random() % 4;
148 for (i = 0; i < j; i++)
149 tmp = &shapes[classic? tmp->rotc : tmp->rot];
150 return (tmp);
151}
152
153static void srandomdev(void)
154{
155 struct timeval tv;
156
157 gettimeofday(&tv, NULL);
158 srandom(tv.tv_sec + tv.tv_usec / 100000);
159}
160
161static void tetris_scores(int firstgame)
162{
163}
164
165static void tetris_menu_draw(int level)
166{
167 clear_screen();
168 moveto(5,10);
169 puts("Tetris\n\n");
170
171 moveto(8,10);
172 printf("Level = %d (press keys 1 - 9 to change)",level);
173 moveto(9,10);
174 printf("Preview is %s (press 'p' to change)", (showpreview?"on ":"off"));
175 moveto(12,10);
176 printf("Press 'h' to show hiscore table.");
177 moveto(13,10);
178 printf("Press 's' to start game.");
179 moveto(14,10);
180 printf("Press 'q' to quit game.");
181 moveto(20,10);
182 printf("In game controls:");
183 moveto(21,0);
184 puts(key_msg);
185}
186
187static int tetris_menu(int *level)
188{
189 static int firstgame = 1;
190 int i;
191/* if (showpreview == 0)
192 (void)printf("Your score: %d point%s x level %d = %d\n",
193 score, score == 1 ? "" : "s", level, score * level);
194 else {
195 (void)printf("Your score: %d point%s x level %d x preview penalty %0.3f = %d\n",
196 score, score == 1 ? "" : "s", level, (double)PRE_PENALTY,
197 (int)(score * level * PRE_PENALTY));
198 score = score * PRE_PENALTY;
199 }
200 savescore(level);
201
202 showscores(level);
203
204 printf("\nHit 's' to new game, 'q' to quit.\n");
205*/
206 tetris_menu_draw(*level);
207 while (1) {
208
209 i = getchar();
210
211 switch(i) {
212 case 'p':
213 showpreview = !showpreview;
214 moveto(9,21);
215 if (showpreview)
216 printf("on ");
217 else
218 printf("off");
219
220 break;
221 case 'h':
222 showscores(firstgame);
223 tetris_menu_draw(*level);
224 break;
225 case 's':
226 firstgame = 0;
227 return 1;
228 case 'q':
229 return 0;
230 case '1':
231 case '2':
232 case '3':
233 case '4':
234 case '5':
235 case '6':
236 case '7':
237 case '8':
238 case '9':
239 *level = i - '0';
240 moveto(8,18);
241 printf("%d", *level);
242 break;
243 }
244 }
245
246}
247
248int
249main(int argc, char *argv[])
250{
251 int pos, c;
252 char *keys;
253 int level = 2;
254 char key_write[6][10];
255 const char *errstr;
256 int ch, i, j;
257
258 keys = "jkl pq";
259
260// gid = getgid();
261// egid = getegid();
262// setegid(gid);
263
264 classic = 0;
265 showpreview = 1;
266
267/* while ((ch = getopt(argc, argv, "ck:l:ps")) != -1) */
268/* switch(ch) { */
269/* case 'c': */
270/* /\* */
271/* * this means: */
272/* * - rotate the other way; */
273/* * - no reverse video. */
274/* *\/ */
275/* classic = 1; */
276/* break; */
277/* case 'k': */
278/* if (strlen(keys = optarg) != 6) */
279/* usage(); */
280/* break; */
281/* case 'l': */
282/* level = (int)strtonum(optarg, MINLEVEL, MAXLEVEL, */
283/* &errstr); */
284/* if (errstr) */
285/* errx(1, "level must be from %d to %d", */
286/* MINLEVEL, MAXLEVEL); */
287/* break; */
288/* case 'p': */
289/* showpreview = 1; */
290/* break; */
291/* case 's': */
292/* showscores(0); */
293/* exit(0); */
294/* default: */
295/* usage(); */
296/* } */
297
298/* argc -= optind; */
299/* argv += optind; */
300
301/* if (argc) */
302/* usage(); */
303
304 fallrate = 1000000 / level;
305
306 for (i = 0; i <= 5; i++) {
307 for (j = i+1; j <= 5; j++) {
308 if (keys[i] == keys[j])
309 errx(1, "duplicate command keys specified.");
310 }
311 if (keys[i] == ' ')
312 strncpy(key_write[i], "<space>", sizeof key_write[i]);
313 else {
314 key_write[i][0] = keys[i];
315 key_write[i][1] = '\0';
316 }
317 }
318
319 snprintf(key_msg, sizeof key_msg,
320"%s - left %s - rotate %s - right %s - drop %s - pause %s - quit",
321 key_write[0], key_write[1], key_write[2], key_write[3],
322 key_write[4], key_write[5]);
323
324 scr_init();
325 initscores();
326 while (tetris_menu(&level)) {
327
328
329 scr_clear();
330 setup_board();
331
332 srandomdev();
333 scr_set();
334
335 pos = A_FIRST*B_COLS + (B_COLS/2)-1;
336 nextshape = randshape();
337 curshape = randshape();
338
339 scr_msg(key_msg, 1);
340
341 for (;;) {
342 place(curshape, pos, 1);
343 scr_update();
344 place(curshape, pos, 0);
345 c = tgetchar();
346 if (c < 0) {
347 /*
348 * Timeout. Move down if possible.
349 */
350 if (fits_in(curshape, pos + B_COLS)) {
351 pos += B_COLS;
352 continue;
353 }
354
355 /*
356 * Put up the current shape `permanently',
357 * bump score, and elide any full rows.
358 */
359 place(curshape, pos, 1);
360 score++;
361 elide();
362
363 /*
364 * Choose a new shape. If it does not fit,
365 * the game is over.
366 */
367 curshape = nextshape;
368 nextshape = randshape();
369 pos = A_FIRST*B_COLS + (B_COLS/2)-1;
370 if (!fits_in(curshape, pos))
371 break;
372 continue;
373 }
374
375 /*
376 * Handle command keys.
377 */
378 if (c == keys[5]) {
379 /* quit */
380 break;
381 }
382 if (c == keys[4]) {
383 static char msg[] =
384 "paused - press RETURN to continue";
385
386 place(curshape, pos, 1);
387 do {
388 scr_update();
389 scr_msg(key_msg, 0);
390 scr_msg(msg, 1);
391 // (void) fflush(stdout);
392 } while (rwait((struct timeval *)NULL) == -1);
393 scr_msg(msg, 0);
394 scr_msg(key_msg, 1);
395 place(curshape, pos, 0);
396 continue;
397 }
398 if (c == keys[0]) {
399 /* move left */
400 if (fits_in(curshape, pos - 1))
401 pos--;
402 continue;
403 }
404 if (c == keys[1]) {
405 /* turn */
406 const struct shape *new = &shapes[
407 classic? curshape->rotc : curshape->rot];
408
409 if (fits_in(new, pos))
410 curshape = new;
411 continue;
412 }
413 if (c == keys[2]) {
414 /* move right */
415 if (fits_in(curshape, pos + 1))
416 pos++;
417 continue;
418 }
419 if (c == keys[3]) {
420 /* move to bottom */
421 while (fits_in(curshape, pos + B_COLS)) {
422 pos += B_COLS;
423 score++;
424 }
425 continue;
426 }
427 if (c == '\f') {
428 scr_clear();
429 scr_msg(key_msg, 1);
430 }
431 }
432
433 scr_clear();
434 insertscore(score, level);
435 }
436
437 scr_clear();
438 printf("\n\n\n\t\tGame over.\n");
439/*
440 while ((i = getchar()) != '\n')
441 if (i == EOF)
442 break
443*/
444 scr_end();
445 exit(0);
446}
447
448/* void */
449/* onintr(int signo) */
450/* { */
451/* scr_clear(); /\* XXX signal race *\/ */
452/* scr_end(); /\* XXX signal race *\/ */
453/* _exit(0); */
454/* } */
455
456void
457usage(void)
458{
459 (void)fprintf(stderr, "usage: tetris [-ps] [-k keys] [-l level]\n");
460 exit(1);
461}
Note: See TracBrowser for help on using the repository browser.