diff options
author | Björn Stenberg <bjorn@haxx.se> | 2003-06-29 16:33:04 +0000 |
---|---|---|
committer | Björn Stenberg <bjorn@haxx.se> | 2003-06-29 16:33:04 +0000 |
commit | ba371fb595affd68c823926b85718d1d613dc7d3 (patch) | |
tree | cfda303d0603d623cdb12f3928905d3ae02f1d87 /apps/recorder/tetris.c | |
parent | 9bcbe3fd723d23a709873a0855f27b86bc5c96f1 (diff) | |
download | rockbox-ba371fb595affd68c823926b85718d1d613dc7d3.tar.gz rockbox-ba371fb595affd68c823926b85718d1d613dc7d3.zip |
Added plugin loader. Moved games, demos and the text viewer to loadable plugins. Copy your *.rock files to /.rockbox/rocks/
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3769 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/recorder/tetris.c')
-rw-r--r-- | apps/recorder/tetris.c | 438 |
1 files changed, 0 insertions, 438 deletions
diff --git a/apps/recorder/tetris.c b/apps/recorder/tetris.c deleted file mode 100644 index 6302e40109..0000000000 --- a/apps/recorder/tetris.c +++ /dev/null | |||
@@ -1,438 +0,0 @@ | |||
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 | #include "config.h" | ||
23 | #include "options.h" | ||
24 | |||
25 | #ifdef USE_GAMES | ||
26 | |||
27 | #include <stdbool.h> | ||
28 | #include <string.h> | ||
29 | #include "lcd.h" | ||
30 | #include "button.h" | ||
31 | #include "kernel.h" | ||
32 | #include "menu.h" | ||
33 | #include "screens.h" | ||
34 | #include "font.h" | ||
35 | |||
36 | #ifdef SIMULATOR | ||
37 | #include <stdio.h> | ||
38 | #endif | ||
39 | #include "sprintf.h" | ||
40 | #include "lang.h" | ||
41 | #define TETRIS_TITLE "Tetris!" | ||
42 | #define TETRIS_TITLE_FONT 1 | ||
43 | #define TETRIS_TITLE_XLOC 43 | ||
44 | #define TETRIS_TITLE_YLOC 15 | ||
45 | |||
46 | static const int start_x = 5; | ||
47 | static const int start_y = 5; | ||
48 | static const int max_x = 4 * 17; | ||
49 | static const int max_y = 3 * 10; | ||
50 | static const short level_speeds[10] = { | ||
51 | 1000, 900, 800, 700, 600, 500, 400, 300, 250, 200 | ||
52 | }; | ||
53 | static const int blocks = 7; | ||
54 | static const int block_frames[7] = {1,2,2,2,4,4,4}; | ||
55 | |||
56 | static int current_x, current_y, current_f, current_b; | ||
57 | static int level, score; | ||
58 | static int next_b, next_f; | ||
59 | static short lines; | ||
60 | static char virtual[LCD_WIDTH * LCD_HEIGHT]; | ||
61 | |||
62 | /* | ||
63 | block_data is built up the following way | ||
64 | |||
65 | first array index specifies the block number | ||
66 | second array index specifies the rotation of the block | ||
67 | third array index specifies: | ||
68 | 0: x-coordinates of pixels | ||
69 | 1: y-coordinates of pixels | ||
70 | fourth array index specifies the coordinate of a pixel | ||
71 | |||
72 | each block consists of four pixels whose relative coordinates are given | ||
73 | with block_data | ||
74 | */ | ||
75 | |||
76 | static const char block_data[7][4][2][4] = | ||
77 | { | ||
78 | { | ||
79 | {{0,1,0,1},{0,0,1,1}} | ||
80 | }, | ||
81 | { | ||
82 | {{0,1,1,2},{1,1,0,0}}, | ||
83 | {{0,0,1,1},{0,1,1,2}} | ||
84 | }, | ||
85 | { | ||
86 | {{0,1,1,2},{0,0,1,1}}, | ||
87 | {{1,1,0,0},{0,1,1,2}} | ||
88 | }, | ||
89 | { | ||
90 | {{1,1,1,1},{0,1,2,3}}, | ||
91 | {{0,1,2,3},{2,2,2,2}} | ||
92 | }, | ||
93 | { | ||
94 | {{1,1,1,2},{2,1,0,0}}, | ||
95 | {{0,1,2,2},{1,1,1,2}}, | ||
96 | {{0,1,1,1},{2,2,1,0}}, | ||
97 | {{0,0,1,2},{0,1,1,1}} | ||
98 | }, | ||
99 | { | ||
100 | {{0,1,1,1},{0,0,1,2}}, | ||
101 | {{0,1,2,2},{1,1,1,0}}, | ||
102 | {{1,1,1,2},{0,1,2,2}}, | ||
103 | {{0,0,1,2},{2,1,1,1}} | ||
104 | }, | ||
105 | { | ||
106 | {{1,0,1,2},{0,1,1,1}}, | ||
107 | {{2,1,1,1},{1,0,1,2}}, | ||
108 | {{1,0,1,2},{2,1,1,1}}, | ||
109 | {{0,1,1,1},{1,0,1,2}} | ||
110 | } | ||
111 | }; | ||
112 | |||
113 | static int t_rand(int range) | ||
114 | { | ||
115 | return current_tick % range; | ||
116 | } | ||
117 | |||
118 | static void draw_frame(int fstart_x,int fstop_x,int fstart_y,int fstop_y) | ||
119 | { | ||
120 | lcd_drawline(fstart_x, fstart_y, fstop_x, fstart_y); | ||
121 | lcd_drawline(fstart_x, fstop_y, fstop_x, fstop_y); | ||
122 | |||
123 | lcd_drawline(fstart_x, fstart_y, fstart_x, fstop_y); | ||
124 | lcd_drawline(fstop_x, fstart_y, fstop_x, fstop_y); | ||
125 | |||
126 | lcd_drawline(fstart_x - 1, fstart_y + 1, fstart_x - 1, fstop_y + 1); | ||
127 | lcd_drawline(fstart_x - 1, fstop_y + 1, fstop_x - 1, fstop_y + 1); | ||
128 | } | ||
129 | |||
130 | static void draw_block(int x, int y, int block, int frame, bool clear) | ||
131 | { | ||
132 | int i, a, b; | ||
133 | for(i=0;i < 4;i++) { | ||
134 | if (clear) | ||
135 | { | ||
136 | for (a = 0; a < 3; a++) | ||
137 | for (b = 0; b < 4; b++) | ||
138 | lcd_clearpixel(start_x + x + block_data[block][frame][1][i] * 4 - b, | ||
139 | start_y + y + block_data[block][frame][0][i] * 3 + a); | ||
140 | } | ||
141 | else | ||
142 | { | ||
143 | for (a = 0; a < 3; a++) | ||
144 | for (b = 0; b < 4; b++) | ||
145 | lcd_drawpixel(start_x+x+block_data[block][frame][1][i] * 4 - b, | ||
146 | start_y+y+block_data[block][frame][0][i] * 3 + a); | ||
147 | } | ||
148 | } | ||
149 | } | ||
150 | |||
151 | static void to_virtual(void) | ||
152 | { | ||
153 | int i, a, b; | ||
154 | |||
155 | for(i = 0; i < 4; i++) | ||
156 | for (a = 0; a < 3; a++) | ||
157 | for (b = 0; b < 4; b++) | ||
158 | *(virtual + | ||
159 | (current_y + block_data[current_b][current_f][0][i] * 3 + a) * | ||
160 | max_x + current_x + block_data[current_b][current_f][1][i] * | ||
161 | 4 - b) = current_b + 1; | ||
162 | } | ||
163 | |||
164 | static bool block_touch (int x, int y) | ||
165 | { | ||
166 | int a,b; | ||
167 | for (a = 0; a < 4; a++) | ||
168 | for (b = 0; b < 3; b++) | ||
169 | if (*(virtual + (y + b) * max_x + (x - a)) != 0) | ||
170 | return true; | ||
171 | return false; | ||
172 | } | ||
173 | |||
174 | static bool gameover(void) | ||
175 | { | ||
176 | int i; | ||
177 | int frame, block, y, x; | ||
178 | |||
179 | x = current_x; | ||
180 | y = current_y; | ||
181 | block = current_b; | ||
182 | frame = current_f; | ||
183 | |||
184 | for(i = 0; i < 4; i++){ | ||
185 | /* Do we have blocks touching? */ | ||
186 | if(block_touch(x + block_data[block][frame][1][i] * 4, | ||
187 | y + block_data[block][frame][0][i] * 3)) | ||
188 | { | ||
189 | /* Are we at the top of the frame? */ | ||
190 | if(x + block_data[block][frame][1][i] * 4 >= max_x - 16) | ||
191 | { | ||
192 | /* Game over ;) */ | ||
193 | return true; | ||
194 | } | ||
195 | } | ||
196 | } | ||
197 | return false; | ||
198 | } | ||
199 | |||
200 | static bool valid_position(int x, int y, int block, int frame) | ||
201 | { | ||
202 | int i; | ||
203 | for(i=0;i < 4;i++) | ||
204 | if ((y + block_data[block][frame][0][i] * 3 > max_y - 3) || | ||
205 | (x + block_data[block][frame][1][i] * 4 > max_x - 4) || | ||
206 | (y + block_data[block][frame][0][i] * 3 < 0) || | ||
207 | (x + block_data[block][frame][1][i] * 4 < 4) || | ||
208 | block_touch (x + block_data[block][frame][1][i] * 4, | ||
209 | y + block_data[block][frame][0][i] * 3)) | ||
210 | { | ||
211 | return false; | ||
212 | } | ||
213 | return true; | ||
214 | } | ||
215 | |||
216 | static void from_virtual(void) | ||
217 | { | ||
218 | int x,y; | ||
219 | for(y = 0; y < max_y; y++) | ||
220 | for(x = 1; x < max_x - 1; x++) | ||
221 | if(*(virtual + (y * max_x) + x) != 0) | ||
222 | lcd_drawpixel(start_x + x, start_y + y); | ||
223 | else | ||
224 | lcd_clearpixel(start_x + x, start_y + y); | ||
225 | } | ||
226 | |||
227 | static void move_block(int x,int y,int f) | ||
228 | { | ||
229 | int last_frame = current_f; | ||
230 | if(f != 0) | ||
231 | { | ||
232 | current_f += f; | ||
233 | if(current_f > block_frames[current_b]-1) | ||
234 | current_f = 0; | ||
235 | if(current_f < 0) | ||
236 | current_f = block_frames[current_b]-1; | ||
237 | } | ||
238 | |||
239 | if(valid_position(current_x + x, current_y + y, current_b, current_f)) | ||
240 | { | ||
241 | draw_block(current_x,current_y,current_b,last_frame,true); | ||
242 | current_x += x; | ||
243 | current_y += y; | ||
244 | draw_block(current_x,current_y,current_b,current_f,false); | ||
245 | lcd_update(); | ||
246 | } | ||
247 | else | ||
248 | current_f = last_frame; | ||
249 | } | ||
250 | |||
251 | static void new_block(void) | ||
252 | { | ||
253 | current_b = next_b; | ||
254 | current_f = next_f; | ||
255 | current_x = max_x - 16; | ||
256 | current_y = (int)12; | ||
257 | next_b = t_rand(blocks); | ||
258 | next_f = t_rand(block_frames[next_b]); | ||
259 | |||
260 | lcd_drawline (max_x + 7, start_y - 1, max_x + 29, start_y - 1); | ||
261 | lcd_drawline (max_x + 29, start_y, max_x + 29, start_y + 14); | ||
262 | lcd_drawline (max_x + 29, start_y + 14, max_x + 7, start_y + 14); | ||
263 | lcd_drawline (max_x + 7, start_y + 14, max_x + 7, start_y - 1); | ||
264 | lcd_drawline (max_x + 6, start_y + 15, max_x + 6, start_y); | ||
265 | lcd_drawline (max_x + 6, start_y + 15, max_x + 28, start_y + 15); | ||
266 | |||
267 | draw_block(max_x + 9, start_y - 4, current_b, current_f, true); | ||
268 | draw_block(max_x + 9, start_y - 4, next_b, next_f, false); | ||
269 | if(!valid_position(current_x, current_y, current_b, current_f)) | ||
270 | { | ||
271 | draw_block(current_x, current_y, current_b, current_f, false); | ||
272 | lcd_update(); | ||
273 | } | ||
274 | else | ||
275 | draw_block(current_x, current_y, current_b, current_f, false); | ||
276 | } | ||
277 | |||
278 | static int check_lines(void) | ||
279 | { | ||
280 | int x,y,i,j; | ||
281 | bool line; | ||
282 | int lines = 0; | ||
283 | for(x = 0; x < max_x; x++) | ||
284 | { | ||
285 | line = true; | ||
286 | for(y = 0; y < max_y; y++) | ||
287 | { | ||
288 | if(*(virtual + y * max_x + x) == 0) | ||
289 | { | ||
290 | line = false; | ||
291 | break; | ||
292 | } | ||
293 | } | ||
294 | |||
295 | if(line) | ||
296 | { | ||
297 | lines++; | ||
298 | /* move rows down */ | ||
299 | for(i = x; i < max_x - 1; i++) | ||
300 | for (j = 0; j < max_y; j++) | ||
301 | *(virtual + j * max_x + i)=*(virtual + j * max_x + (i + 1)); | ||
302 | |||
303 | x--; /* re-check this line */ | ||
304 | } | ||
305 | } | ||
306 | |||
307 | return lines / 4; | ||
308 | } | ||
309 | |||
310 | static void move_down(void) | ||
311 | { | ||
312 | int l; | ||
313 | char s[25]; | ||
314 | |||
315 | if(!valid_position(current_x - 4, current_y, current_b, current_f)) | ||
316 | { | ||
317 | to_virtual(); | ||
318 | l = check_lines(); | ||
319 | if(l) | ||
320 | { | ||
321 | lines += l; | ||
322 | level = (int)lines/10; | ||
323 | if(level > 9) | ||
324 | level = 9; | ||
325 | from_virtual(); | ||
326 | score += l*l; | ||
327 | } | ||
328 | |||
329 | snprintf (s, sizeof(s), "%d %s %d", lines, | ||
330 | str(LANG_TETRIS_LEVEL), level); | ||
331 | lcd_putsxy (2, 42, s); | ||
332 | |||
333 | new_block(); | ||
334 | move_block(0,0,0); | ||
335 | } | ||
336 | else | ||
337 | move_block(-4,0,0); | ||
338 | } | ||
339 | |||
340 | static bool game_loop(void) | ||
341 | { | ||
342 | while(1) | ||
343 | { | ||
344 | int count = 0; | ||
345 | while(count * 300 < level_speeds[level]) | ||
346 | { | ||
347 | switch(button_get_w_tmo(HZ/10)) | ||
348 | { | ||
349 | case BUTTON_OFF: | ||
350 | return false; | ||
351 | |||
352 | case BUTTON_UP: | ||
353 | case BUTTON_UP | BUTTON_REPEAT: | ||
354 | move_block(0,-3,0); | ||
355 | break; | ||
356 | |||
357 | case BUTTON_DOWN: | ||
358 | case BUTTON_DOWN | BUTTON_REPEAT: | ||
359 | move_block(0,3,0); | ||
360 | break; | ||
361 | |||
362 | case BUTTON_RIGHT: | ||
363 | case BUTTON_RIGHT | BUTTON_REPEAT: | ||
364 | move_block(0,0,1); | ||
365 | break; | ||
366 | |||
367 | case BUTTON_LEFT: | ||
368 | case BUTTON_LEFT | BUTTON_REPEAT: | ||
369 | move_down(); | ||
370 | break; | ||
371 | |||
372 | case SYS_USB_CONNECTED: | ||
373 | usb_screen(); | ||
374 | return true; | ||
375 | } | ||
376 | |||
377 | count++; | ||
378 | } | ||
379 | |||
380 | if(gameover()) | ||
381 | { | ||
382 | lcd_clearrect(0, 52, LCD_WIDTH, LCD_HEIGHT - 52); | ||
383 | lcd_putsxy (2, 52, str(LANG_TETRIS_LOSE)); | ||
384 | lcd_update(); | ||
385 | sleep(HZ * 3); | ||
386 | return false; | ||
387 | } | ||
388 | |||
389 | move_down(); | ||
390 | } | ||
391 | |||
392 | return false; | ||
393 | } | ||
394 | |||
395 | static void init_tetris(void) | ||
396 | { | ||
397 | memset(&virtual, 0, sizeof(virtual)); | ||
398 | |||
399 | current_x = 0; | ||
400 | current_y = 0; | ||
401 | current_f = 0; | ||
402 | current_b = 0; | ||
403 | level = 0; | ||
404 | lines = 0; | ||
405 | score = 0; | ||
406 | next_b = 0; | ||
407 | next_f = 0; | ||
408 | } | ||
409 | |||
410 | bool tetris(void) | ||
411 | { | ||
412 | char buf[20]; | ||
413 | bool val; | ||
414 | |||
415 | /* Lets use the default font */ | ||
416 | lcd_setfont(FONT_SYSFIXED); | ||
417 | |||
418 | init_tetris(); | ||
419 | |||
420 | draw_frame(start_x, start_x + max_x - 1, start_y - 1, start_y + max_y); | ||
421 | snprintf(buf, sizeof(buf), "0 %s 0", str(LANG_TETRIS_LEVEL)); | ||
422 | lcd_putsxy (2, 42, buf); | ||
423 | lcd_update(); | ||
424 | |||
425 | next_b = t_rand(blocks); | ||
426 | next_f = t_rand(block_frames[next_b]); | ||
427 | new_block(); | ||
428 | val = game_loop(); | ||
429 | |||
430 | lcd_setfont(FONT_UI); | ||
431 | |||
432 | return val; | ||
433 | } | ||
434 | |||
435 | #endif | ||
436 | |||
437 | |||
438 | |||