Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (6.15 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
 *        @(#)tetris.c        8.1 (Berkeley) 5/31/93
33
 */
34

    
35
/* Modified for Prex by Kohsuke Ohtani. */
36

    
37
/*
38
 * Tetris (or however it is spelled).
39
 */
40

    
41
#include <sys/time.h>
42
#include <sys/param.h>
43
#ifdef __gba__
44
#include <sys/keycode.h>
45
#endif
46

    
47
#include <signal.h>
48
#include <stdio.h>
49
#include <stdlib.h>
50
#include <string.h>
51
#include <unistd.h>
52

    
53
#include "input.h"
54
#include "screen.h"
55
#include "tetris.h"
56

    
57
#ifdef __gba__
58
static char keys[6] = {K_LEFT, 'A', K_RGHT, K_DOWN, '\n', '\n'};
59
#else
60
static char *keys = "jkl pq";
61
#endif
62

    
63
cell        board[B_SIZE];                /* 1 => occupied, 0 => empty */
64
int        Rows, Cols;                /* current screen size */
65
int        score;                        /* the obvious thing */
66
char        key_msg[100];
67
long        fallrate;                /* less than 1 million; smaller => faster */
68

    
69
void onintr(int);
70
void usage(void);
71

    
72
/*
73
 * Set up the initial board.  The bottom display row is completely set,
74
 * along with another (hidden) row underneath that.  Also, the left and
75
 * right edges are set.
76
 */
77
static void
78
setup_board(void)
79
{
80
        int i;
81
        cell *p;
82

    
83
        p = board;
84
        for (i = B_SIZE; i; i--)
85
                *p++ = i <= (2 * B_COLS) || (i % B_COLS) < 2;
86
}
87

    
88
/*
89
 * Elide any full active rows.
90
 */
91
static void
92
elide(void)
93
{
94
        int i, j, base;
95
        cell *p;
96

    
97
        for (i = A_FIRST; i < A_LAST; i++) {
98
                base = i * B_COLS + 1;
99
                p = &board[base];
100
                for (j = B_COLS - 2; *p++ != 0;) {
101
                        if (--j <= 0) {
102
                                /* this row is to be elided */
103
                                bzero(&board[base], B_COLS - 2);
104
                                scr_update();
105
                                tsleep();
106
                                while (--base != 0)
107
                                        board[base + B_COLS] = board[base];
108
                                scr_update();
109
                                tsleep();
110
                                break;
111
                        }
112
                }
113
        }
114
}
115

    
116
int
117
main(int argc, char *argv[])
118
{
119
        int pos, c;
120
        const struct shape *curshape;
121
        int level = 2;
122
#ifndef __gba__
123
        char key_write[6][10];
124
        int i;
125
#endif
126
        int ch;
127

    
128
        while ((ch = getopt(argc, argv, "l")) != EOF)
129
                switch(ch) {
130
                case 'l':
131
                        level = atoi(optarg);
132
                        if (level < MINLEVEL || level > MAXLEVEL) {
133
                                (void)fprintf(stderr,
134
                                    "tetris: level must be from %d to %d",
135
                                    MINLEVEL, MAXLEVEL);
136
                                exit(1);
137
                        }
138
                        break;
139
                case '?':
140
                default:
141
                        usage();
142
                }
143

    
144
        argc -= optind;
145
        argv += optind;
146

    
147
        if (argc)
148
                usage();
149

    
150
        fallrate = 1000000 / level;
151

    
152
#ifdef __gba__
153
        /* No help line... */
154
#else
155
        for (i = 0; i <= 5; i++) {
156
                if (keys[i] == ' ')
157
                        strcpy(key_write[i], "<space>");
158
                else {
159
                        key_write[i][0] = keys[i];
160
                        key_write[i][1] = '\0';
161
                }
162
        }
163

    
164
        sprintf(key_msg,
165
"%s - left   %s - rotate   %s - right   %s - drop   %s - pause   %s - quit",
166
                key_write[0], key_write[1], key_write[2], key_write[3],
167
                key_write[4], key_write[5]);
168
#endif
169

    
170
        (void)signal(SIGINT, onintr);
171
        scr_init();
172
        setup_board();
173

    
174
        srandom((unsigned long)getpid());
175
        scr_set();
176

    
177
        pos = A_FIRST*B_COLS + (B_COLS/2)-1;
178
        curshape = randshape();
179

    
180
        scr_msg(key_msg, 1);
181

    
182
        for (;;) {
183
                place(curshape, pos, 1);
184
                scr_update();
185

    
186
                place(curshape, pos, 0);
187
                c = tgetchar();
188
                if (c < 0) {
189
                        /*
190
                         * Timeout.  Move down if possible.
191
                         */
192
                        if (fits_in(curshape, pos + B_COLS)) {
193
                                pos += B_COLS;
194
                                continue;
195
                        }
196

    
197
                        /*
198
                         * Put up the current shape `permanently',
199
                         * bump score, and elide any full rows.
200
                         */
201
                        place(curshape, pos, 1);
202
                        score++;
203
                        elide();
204

    
205
                        /*
206
                         * Choose a new shape.  If it does not fit,
207
                         * the game is over.
208
                         */
209
                        curshape = randshape();
210
                        pos = A_FIRST*B_COLS + (B_COLS/2)-1;
211
                        if (!fits_in(curshape, pos))
212
                                break;
213
                        continue;
214
                }
215

    
216
                /*
217
                 * Handle command keys.
218
                 */
219
                if (c == keys[5]) {
220
                        /* quit */
221
                        break;
222
                }
223
                if (c == keys[4]) {
224
                        static char msg[] =
225
                            "paused - press RETURN to continue";
226

    
227
                        place(curshape, pos, 1);
228
                        do {
229
                                scr_update();
230
                                scr_msg(key_msg, 0);
231
                                scr_msg(msg, 1);
232
                                (void) fflush(stdout);
233
                        } while (rwait((struct timeval *)NULL) == -1);
234
                        scr_msg(msg, 0);
235
                        scr_msg(key_msg, 1);
236
                        place(curshape, pos, 0);
237
                        continue;
238
                }
239
                if (c == keys[0]) {
240
                        /* move left */
241
                        if (fits_in(curshape, pos - 1))
242
                                pos--;
243
                        continue;
244
                }
245
                if (c == keys[1]) {
246
                        /* turn */
247
                        const struct shape *new = &shapes[curshape->rot];
248

    
249
                        if (fits_in(new, pos))
250
                                curshape = new;
251
                        continue;
252
                }
253
                if (c == keys[2]) {
254
                        /* move right */
255
                        if (fits_in(curshape, pos + 1))
256
                                pos++;
257
                        continue;
258
                }
259
                if (c == keys[3]) {
260
                        /* move to bottom */
261
                        while (fits_in(curshape, pos + B_COLS)) {
262
                                pos += B_COLS;
263
                                score++;
264
                        }
265
                        continue;
266
                }
267
                if (c == '\f')
268
                        scr_clear();
269
        }
270

    
271
        scr_clear();
272
        scr_end();
273

    
274
        (void)printf("Your score:  %d point%s  x  level %d  =  %d\n",
275
            score, score == 1 ? "" : "s", level, score * level);
276
        exit(0);
277
}
278

    
279
void
280
onintr(int signo)
281
{
282
        scr_clear();
283
        scr_end();
284
        exit(0);
285
}
286

    
287
void
288
usage()
289
{
290
        (void)fprintf(stderr, "usage: tetris [-l level]\n");
291
        exit(1);
292
}