summaryrefslogtreecommitdiff
path: root/apps/recorder/tetris.c
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-05-17 13:53:41 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-05-17 13:53:41 +0000
commit37a7c25caa5ebf4756e72a4b4c0db3293e7e13c9 (patch)
treeefea44184feaf9c074d3a1581aa5c6e3b93c8591 /apps/recorder/tetris.c
parente146da9a37adff6fb9d10682a9ca850fe9c05fda (diff)
downloadrockbox-37a7c25caa5ebf4756e72a4b4c0db3293e7e13c9.tar.gz
rockbox-37a7c25caa5ebf4756e72a4b4c0db3293e7e13c9.zip
Moving recorder code to recorder/
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@618 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/recorder/tetris.c')
-rw-r--r--apps/recorder/tetris.c362
1 files changed, 362 insertions, 0 deletions
diff --git a/apps/recorder/tetris.c b/apps/recorder/tetris.c
new file mode 100644
index 0000000000..24090eb67e
--- /dev/null
+++ b/apps/recorder/tetris.c
@@ -0,0 +1,362 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 1999 Mattis Wadman (nappe@sudac.org)
11 *
12 * Heavily modified for embedded use by Björn Stenberg (bjorn@haxx.se)
13 *
14 * All files in this archive are subject to the GNU General Public License.
15 * See the file COPYING in the source tree root for full license agreement.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifdef HAVE_LCD_BITMAP
23#include <stdbool.h>
24#include "lcd.h"
25#include "button.h"
26#include "kernel.h"
27
28#ifdef SIMULATOR
29#include <stdio.h>
30#endif
31
32#define TETRIS_TITLE "Tetris!"
33#define TETRIS_TITLE_FONT 2
34#define TETRIS_TITLE_XLOC 10
35#define TETRIS_TITLE_YLOC 32
36
37int start_x = 1;
38int start_y = 1;
39int max_x = 14;
40int max_y = 24;
41int current_x = 0;
42int current_y = 0;
43int current_f = 0;
44int current_b = 0;
45int level = 0;
46short lines = 0;
47int score = 0;
48int next_b = 0;
49int next_f = 0;
50char virtual[LCD_WIDTH*LCD_HEIGHT];
51short level_speeds[10] = {1000,900,800,700,600,500,400,300,250,200};
52int blocks = 7;
53int block_frames[7] = {1,2,2,2,4,4,4};
54
55/*
56 block_data is built up the following way
57
58 first array index specifies the block number
59 second array index specifies the rotation of the block
60 third array index specifies:
61 0: x-coordinates of pixels
62 1: y-coordinates of pixels
63 fourth array index specifies the coordinate of a pixel
64
65 each block consists of four pixels whose relative coordinates are given
66 with block_data
67*/
68
69int block_data[7][4][2][4] =
70{
71 {
72 {{0,1,0,1},{0,0,1,1}}
73 },
74 {
75 {{0,1,1,2},{1,1,0,0}},
76 {{0,0,1,1},{0,1,1,2}}
77 },
78 {
79 {{0,1,1,2},{0,0,1,1}},
80 {{1,1,0,0},{0,1,1,2}}
81 },
82 {
83 {{1,1,1,1},{0,1,2,3}},
84 {{0,1,2,3},{2,2,2,2}}
85 },
86 {
87 {{1,1,1,2},{2,1,0,0}},
88 {{0,1,2,2},{1,1,1,2}},
89 {{0,1,1,1},{2,2,1,0}},
90 {{0,0,1,2},{0,1,1,1}}
91 },
92 {
93 {{0,1,1,1},{0,0,1,2}},
94 {{0,1,2,2},{1,1,1,0}},
95 {{1,1,1,2},{0,1,2,2}},
96 {{0,0,1,2},{2,1,1,1}}
97 },
98 {
99 {{1,0,1,2},{0,1,1,1}},
100 {{2,1,1,1},{1,0,1,2}},
101 {{1,0,1,2},{2,1,1,1}},
102 {{0,1,1,1},{1,0,1,2}}
103 }
104};
105
106/* not even pseudo random :) */
107int t_rand(int range)
108{
109 static int count;
110 count++;
111 return count % range;
112}
113
114void draw_frame(int fstart_x,int fstop_x,int fstart_y,int fstop_y)
115{
116 lcd_drawline(fstart_x, fstart_y, fstop_x, fstart_y);
117 lcd_drawline(fstart_x, fstop_y, fstop_x, fstop_y);
118
119 lcd_drawline(fstart_x, fstart_y, fstart_x, fstop_y);
120 lcd_drawline(fstop_x, fstart_y, fstop_x, fstop_y);
121}
122
123void draw_block(int x,int y,int block,int frame,bool clear)
124{
125 int i;
126 for(i=0;i < 4;i++) {
127 if (clear)
128 lcd_clearpixel(start_x+x+block_data[block][frame][0][i],
129 start_y+y+block_data[block][frame][1][i]);
130 else
131 lcd_drawpixel(start_x+x+block_data[block][frame][0][i],
132 start_y+y+block_data[block][frame][1][i]);
133 }
134}
135
136void to_virtual()
137{
138 int i;
139 for(i=0;i < 4;i++)
140 *(virtual+
141 ((current_y+block_data[current_b][current_f][1][i])*max_x)+
142 (current_x+block_data[current_b][current_f][0][i])) = current_b+1;
143}
144
145bool gameover()
146{
147 int i;
148 int frame, block, y, x;
149
150 x = current_x;
151 y = current_y;
152 block = current_b;
153 frame = current_f;
154
155 for(i=0;i < 4; i++){
156 /* Do we have blocks touching? */
157 if(*(virtual+((y+block_data[block][frame][1][i])*max_x)+x+
158 block_data[block][frame][0][i]) != 0)
159 {
160 /* Are we at the top of the frame? */
161 if(y+block_data[block][frame][1][i] < start_y)
162 {
163 /* Game over ;) */
164 return true;
165 }
166 }
167 }
168 return false;
169}
170
171bool valid_position(int x,int y,int block,int frame)
172{
173 int i;
174 for(i=0;i < 4;i++)
175 if( (*(virtual+((y+block_data[block][frame][1][i])*max_x)+x+
176 block_data[block][frame][0][i]) != 0) ||
177 (x+block_data[block][frame][0][i] < 0) ||
178 (x+block_data[block][frame][0][i] > max_x-1) ||
179 (y+block_data[block][frame][1][i] < 0) ||
180 (y+block_data[block][frame][1][i] > max_y-1))
181 return false;
182 return true;
183}
184
185void from_virtual()
186{
187 int x,y;
188 for(y=0;y < max_y;y++)
189 for(x=0;x < max_x;x++)
190 if(*(virtual+(y*max_x)+x))
191 lcd_drawpixel(start_x+x,start_y+y);
192 else
193 lcd_clearpixel(start_x+x,start_y+y);
194}
195
196void move_block(int x,int y,int f)
197{
198 int last_frame = current_f;
199 if(f != 0)
200 {
201 current_f += f;
202 if(current_f > block_frames[current_b]-1)
203 current_f = 0;
204 if(current_f < 0)
205 current_f = block_frames[current_b]-1;
206 }
207 if(valid_position(current_x+x,current_y+y,current_b,current_f))
208 {
209 draw_block(current_x,current_y,current_b,last_frame,true);
210 current_x += x;
211 current_y += y;
212 draw_block(current_x,current_y,current_b,current_f,false);
213 lcd_update();
214 }
215 else
216 current_f = last_frame;
217}
218
219void new_block()
220{
221 current_b = next_b;
222 current_f = next_f;
223 current_x = (int)((max_x)/2)-1;
224 current_y = 0;
225 next_b = t_rand(blocks);
226 next_f = t_rand(block_frames[next_b]);
227 draw_block(max_x+2,start_y-1,current_b,current_f,true);
228 draw_block(max_x+2,start_y-1,next_b,next_f,false);
229 if(!valid_position(current_x,current_y,current_b,current_f))
230 {
231 draw_block(current_x,current_y,current_b,current_f,false);
232 lcd_update();
233 }
234 else
235 draw_block(current_x,current_y,current_b,current_f,false);
236}
237
238int check_lines()
239{
240 int x,y,i;
241 bool line;
242 int lines = 0;
243 for(y=0;y < max_y;y++)
244 {
245 line = true;
246 for(x=0;x < max_x;x++)
247 if(virtual[y*max_x+x] == 0)
248 line = false;
249 if(line)
250 {
251 lines++;
252 for(i=y;i > 1;i--)
253 for (x=0;x<max_x;x++)
254 virtual[i*max_x] = virtual[((i-1)*max_x)];
255 for (x=0;x<max_x;x++)
256 virtual[max_x] = 0;
257 }
258 }
259 return lines;
260}
261
262void move_down()
263{
264 int l;
265 if(!valid_position(current_x,current_y+1,current_b,current_f))
266 {
267 to_virtual();
268 l = check_lines();
269 if(l)
270 {
271 lines += l;
272 level = (int)lines/10;
273 if(level > 9)
274 level = 9;
275 from_virtual();
276 score += l*l;
277 }
278 new_block();
279 move_block(0,0,0);
280 }
281 else
282 move_block(0,1,0);
283}
284
285void game_loop(void)
286{
287 while(1)
288 {
289 int b=0;
290 int count = 0;
291 /* while(count*20 < level_speeds[level]) */
292 {
293 b = button_get();
294 if ( b & BUTTON_OFF )
295 return; /* get out of here */
296
297 if ( b & BUTTON_LEFT ) {
298 move_block(-1,0,0);
299 }
300 if ( b & BUTTON_RIGHT ) {
301 move_block(1,0,0);
302 }
303 if ( b & BUTTON_UP ) {
304 move_block(0,0,1);
305 }
306 if ( b & BUTTON_DOWN ) {
307 move_down();
308 }
309 count++;
310 sleep(10);
311 }
312 if(gameover()) {
313 int w, h;
314
315 lcd_getfontsize(TETRIS_TITLE_FONT, &w, &h);
316 lcd_clearrect(TETRIS_TITLE_XLOC, TETRIS_TITLE_YLOC,
317 TETRIS_TITLE_XLOC+(w*sizeof(TETRIS_TITLE)),
318 TETRIS_TITLE_YLOC-h);
319 lcd_putsxy(TETRIS_TITLE_XLOC, TETRIS_TITLE_YLOC, "You lose!",
320 TETRIS_TITLE_FONT);
321 lcd_update();
322 sleep(2);
323 return;
324 }
325 move_down();
326 }
327}
328
329void init_tetris()
330{
331 memset(&virtual, 0, sizeof(virtual));
332 start_x = 1;
333 start_y = 1;
334 max_x = 14;
335 max_y = 24;
336 current_x = 0;
337 current_y = 0;
338 current_f = 0;
339 current_b = 0;
340 level = 0;
341 lines = 0;
342 score = 0;
343 next_b = 0;
344 next_f = 0;
345}
346
347void tetris(void)
348{
349 init_tetris();
350
351 draw_frame(start_x-1,start_x+max_x,start_y-1,start_y+max_y);
352 lcd_putsxy(TETRIS_TITLE_XLOC, TETRIS_TITLE_YLOC, TETRIS_TITLE,
353 TETRIS_TITLE_FONT);
354 lcd_update();
355
356 next_b = t_rand(blocks);
357 next_f = t_rand(block_frames[next_b]);
358 new_block();
359 game_loop();
360}
361
362#endif