diff options
-rw-r--r-- | apps/recorder/tetris.c | 189 |
1 files changed, 92 insertions, 97 deletions
diff --git a/apps/recorder/tetris.c b/apps/recorder/tetris.c index 804e4a4546..e0a92076ae 100644 --- a/apps/recorder/tetris.c +++ b/apps/recorder/tetris.c | |||
@@ -38,9 +38,9 @@ | |||
38 | #define TETRIS_TITLE_XLOC 43 | 38 | #define TETRIS_TITLE_XLOC 43 |
39 | #define TETRIS_TITLE_YLOC 15 | 39 | #define TETRIS_TITLE_YLOC 15 |
40 | 40 | ||
41 | static const int start_x = 2; | 41 | static const int start_x = 1; |
42 | static const int start_y = 1; | 42 | static const int start_y = 2; |
43 | static const int max_x = 28; | 43 | static const int max_x = 104; |
44 | static const int max_y = 48; | 44 | static const int max_y = 48; |
45 | static const short level_speeds[10] = {1000,900,800,700,600,500,400,300,250,200}; | 45 | static const short level_speeds[10] = {1000,900,800,700,600,500,400,300,250,200}; |
46 | static const int blocks = 7; | 46 | static const int blocks = 7; |
@@ -50,7 +50,7 @@ static int current_x, current_y, current_f, current_b; | |||
50 | static int level, score; | 50 | static int level, score; |
51 | static int next_b, next_f; | 51 | static int next_b, next_f; |
52 | static short lines; | 52 | static short lines; |
53 | static char virtual[LCD_WIDTH*LCD_HEIGHT]; | 53 | static char virtual[LCD_WIDTH * LCD_HEIGHT]; |
54 | 54 | ||
55 | /* | 55 | /* |
56 | block_data is built up the following way | 56 | block_data is built up the following way |
@@ -117,62 +117,47 @@ void draw_frame(int fstart_x,int fstop_x,int fstart_y,int fstop_y) | |||
117 | lcd_drawline(fstop_x, fstart_y, fstop_x, fstop_y); | 117 | lcd_drawline(fstop_x, fstart_y, fstop_x, fstop_y); |
118 | } | 118 | } |
119 | 119 | ||
120 | void draw_block(int x,int y,int block,int frame,bool clear) | 120 | void draw_block(int x, int y, int block, int frame, bool clear) |
121 | { | 121 | { |
122 | int i; | 122 | int i, a, b; |
123 | for(i=0;i < 4;i++) { | 123 | for(i=0;i < 4;i++) { |
124 | if (clear) | 124 | if (clear) |
125 | { | 125 | { |
126 | lcd_clearpixel(start_x+x+block_data[block][frame][0][i] * 2, | 126 | for (a = 0; a < 4; a++) |
127 | start_y+y+block_data[block][frame][1][i] * 2); | 127 | for (b = 0; b < 4; b++) |
128 | lcd_clearpixel(start_x+x+block_data[block][frame][0][i] * 2 + 1, | 128 | lcd_clearpixel(start_x + x + block_data[block][frame][1][i] * 4 + b, |
129 | start_y+y+block_data[block][frame][1][i] * 2); | 129 | start_y + y + block_data[block][frame][0][i] * 4 + a); |
130 | lcd_clearpixel(start_x+x+block_data[block][frame][0][i] * 2, | ||
131 | start_y+y+block_data[block][frame][1][i] * 2 + 1); | ||
132 | lcd_clearpixel(start_x+x+block_data[block][frame][0][i] * 2 + 1, | ||
133 | start_y+y+block_data[block][frame][1][i] * 2 + 1); | ||
134 | } | 130 | } |
135 | else | 131 | else |
136 | { | 132 | { |
137 | lcd_drawpixel(start_x+x+block_data[block][frame][0][i] * 2, | 133 | for (a = 0; a < 4; a++) |
138 | start_y+y+block_data[block][frame][1][i] * 2); | 134 | for (b = 0; b < 4; b++) |
139 | lcd_drawpixel(start_x+x+block_data[block][frame][0][i] * 2 + 1, | 135 | lcd_drawpixel(start_x+x+block_data[block][frame][1][i] * 4 + b, |
140 | start_y+y+block_data[block][frame][1][i] * 2); | 136 | start_y+y+block_data[block][frame][0][i] * 4 + a); |
141 | lcd_drawpixel(start_x+x+block_data[block][frame][0][i] * 2, | ||
142 | start_y+y+block_data[block][frame][1][i] * 2 + 1); | ||
143 | lcd_drawpixel(start_x+x+block_data[block][frame][0][i] * 2 + 1, | ||
144 | start_y+y+block_data[block][frame][1][i] * 2 + 1); | ||
145 | } | 137 | } |
146 | } | 138 | } |
147 | } | 139 | } |
148 | 140 | ||
149 | void to_virtual(void) | 141 | void to_virtual(void) |
150 | { | 142 | { |
151 | int i; | 143 | int i,a,b; |
152 | for(i = 0; i < 4; i++) | 144 | for(i = 0; i < 4; i++) |
153 | { | 145 | { |
154 | *(virtual + | 146 | for (a = 0; a < 4; a++) |
155 | (current_y + block_data[current_b][current_f][1][i] * 2) * max_x + | 147 | for (b = 0; b < 4; b++) |
156 | current_x + block_data[current_b][current_f][0][i] * 2) = current_b + 1; | 148 | *(virtual + |
157 | *(virtual + | 149 | (current_y + block_data[current_b][current_f][0][i] * 4 + a) * max_x + |
158 | (current_y + block_data[current_b][current_f][1][i] * 2 + 1) * max_x + | 150 | current_x + block_data[current_b][current_f][1][i] * 4 + b) = current_b + 1; |
159 | current_x + block_data[current_b][current_f][0][i] * 2) = current_b + 1; | ||
160 | *(virtual + | ||
161 | (current_y + block_data[current_b][current_f][1][i] * 2) * max_x + | ||
162 | current_x + block_data[current_b][current_f][0][i] * 2 + 1) = current_b + 1; | ||
163 | *(virtual + | ||
164 | (current_y + block_data[current_b][current_f][1][i] * 2 + 1) * max_x + | ||
165 | current_x + block_data[current_b][current_f][0][i] * 2 + 1) = current_b + 1; | ||
166 | } | 151 | } |
167 | } | 152 | } |
168 | 153 | ||
169 | bool block_touch (int x, int y) | 154 | bool block_touch (int x, int y) |
170 | { | 155 | { |
171 | if (*(virtual + y * max_x + x) != 0 || | 156 | int a,b; |
172 | *(virtual + y * max_x + x + 1) != 0 || | 157 | for (a = 0; a < 4; a++) |
173 | *(virtual + (y + 1) * max_x + x) != 0 || | 158 | for (b = 0; b < 4; b++) |
174 | *(virtual + (y + 1) * max_x + x + 1) != 0) | 159 | if (*(virtual + (y + b) * max_x + (x + a)) != 0) |
175 | return true; | 160 | return true; |
176 | return false; | 161 | return false; |
177 | } | 162 | } |
178 | 163 | ||
@@ -186,12 +171,12 @@ bool gameover(void) | |||
186 | block = current_b; | 171 | block = current_b; |
187 | frame = current_f; | 172 | frame = current_f; |
188 | 173 | ||
189 | for(i=0;i < 4; i++){ | 174 | for(i = 0; i < 4; i++){ |
190 | /* Do we have blocks touching? */ | 175 | /* Do we have blocks touching? */ |
191 | if(block_touch(x + block_data[block][frame][0][i] * 2, y + block_data[block][frame][1][i] * 2)) | 176 | if(block_touch(x + block_data[block][frame][1][i] * 4, y + block_data[block][frame][0][i] * 4)) |
192 | { | 177 | { |
193 | /* Are we at the top of the frame? */ | 178 | /* Are we at the top of the frame? */ |
194 | if(y + block_data[block][frame][1][i] * 2 < start_y) | 179 | if(y + block_data[block][frame][1][i] * 4 < start_y) |
195 | { | 180 | { |
196 | /* Game over ;) */ | 181 | /* Game over ;) */ |
197 | return true; | 182 | return true; |
@@ -201,15 +186,15 @@ bool gameover(void) | |||
201 | return false; | 186 | return false; |
202 | } | 187 | } |
203 | 188 | ||
204 | bool valid_position(int x,int y,int block,int frame) | 189 | bool valid_position(int x, int y, int block, int frame) |
205 | { | 190 | { |
206 | int i; | 191 | int i; |
207 | for(i=0;i < 4;i++) | 192 | for(i=0;i < 4;i++) |
208 | if ((y + block_data[block][frame][1][i] * 2 > max_y - 2) || | 193 | if ((y + block_data[block][frame][0][i] * 4 > max_y - 4) || |
209 | (x + block_data[block][frame][0][i] * 2 > max_x - 2) || | 194 | (x + block_data[block][frame][1][i] * 4 > max_x) || |
210 | (y + block_data[block][frame][1][i] * 2 < 0) || | 195 | (y + block_data[block][frame][0][i] * 4 < 0) || |
211 | (x + block_data[block][frame][0][i] * 2 < 0) || | 196 | (x + block_data[block][frame][1][i] * 4 < 0) || |
212 | block_touch (x + block_data[block][frame][0][i] * 2, y + block_data[block][frame][1][i] * 2)) | 197 | block_touch (x + block_data[block][frame][1][i] * 4, y + block_data[block][frame][0][i] * 4)) |
213 | return false; | 198 | return false; |
214 | return true; | 199 | return true; |
215 | } | 200 | } |
@@ -218,7 +203,7 @@ void from_virtual(void) | |||
218 | { | 203 | { |
219 | int x,y; | 204 | int x,y; |
220 | for(y = 0; y < max_y; y++) | 205 | for(y = 0; y < max_y; y++) |
221 | for(x = 1; x < max_x - 1; x ++) | 206 | for(x = 1; x < max_x - 1; x++) |
222 | if(*(virtual + (y * max_x) + x) != 0) | 207 | if(*(virtual + (y * max_x) + x) != 0) |
223 | lcd_drawpixel(start_x + x, start_y + y); | 208 | lcd_drawpixel(start_x + x, start_y + y); |
224 | else | 209 | else |
@@ -237,7 +222,7 @@ void move_block(int x,int y,int f) | |||
237 | current_f = block_frames[current_b]-1; | 222 | current_f = block_frames[current_b]-1; |
238 | } | 223 | } |
239 | 224 | ||
240 | if(valid_position(current_x+x,current_y+y,current_b,current_f)) | 225 | if(valid_position(current_x + x, current_y + y, current_b, current_f)) |
241 | { | 226 | { |
242 | draw_block(current_x,current_y,current_b,last_frame,true); | 227 | draw_block(current_x,current_y,current_b,last_frame,true); |
243 | current_x += x; | 228 | current_x += x; |
@@ -253,51 +238,59 @@ void new_block(void) | |||
253 | { | 238 | { |
254 | current_b = next_b; | 239 | current_b = next_b; |
255 | current_f = next_f; | 240 | current_f = next_f; |
256 | current_x = (int)((max_x)/2)-1; | 241 | current_x = max_x - 15; |
257 | current_y = 0; | 242 | current_y = (int)((max_y)/2); |
258 | next_b = t_rand(blocks); | 243 | next_b = t_rand(blocks); |
259 | next_f = t_rand(block_frames[next_b]); | 244 | next_f = t_rand(block_frames[next_b]); |
260 | draw_block(max_x+2,start_y-1,current_b,current_f,true); | 245 | // draw_block(max_x + 2, start_y - 1, current_b, current_f, true); |
261 | draw_block(max_x+2,start_y-1,next_b,next_f,false); | 246 | // draw_block(max_x + 2, start_y - 1, next_b, next_f, false); |
262 | if(!valid_position(current_x,current_y,current_b,current_f)) | 247 | if(!valid_position(current_x, current_y, current_b, current_f)) |
263 | { | 248 | { |
264 | draw_block(current_x,current_y,current_b,current_f,false); | 249 | draw_block(current_x, current_y, current_b, current_f, false); |
265 | lcd_update(); | 250 | lcd_update(); |
266 | } | 251 | } |
267 | else | 252 | else |
268 | draw_block(current_x,current_y,current_b,current_f,false); | 253 | draw_block(current_x, current_y, current_b, current_f, false); |
269 | } | 254 | } |
270 | 255 | ||
271 | int check_lines(void) | 256 | int check_lines(void) |
272 | { | 257 | { |
273 | int x,y,i; | 258 | int x,y,i,j,a,b; |
274 | bool line; | 259 | bool line; |
275 | int lines = 0; | 260 | int lines = 0; |
276 | for(y = 0; y < max_y; y++) | 261 | for(x = 0; x < max_x; x++) |
277 | { | 262 | { |
278 | line = true; | 263 | line = true; |
279 | for(x = 1; x < max_x - 1; x++) | 264 | for(y = 0; y < max_y; y++) |
265 | { | ||
280 | if(*(virtual + y * max_x + x) == 0) | 266 | if(*(virtual + y * max_x + x) == 0) |
281 | { | 267 | { |
282 | line = false; | 268 | line = false; |
283 | break; | 269 | break; |
284 | } | 270 | } |
271 | } | ||
272 | |||
285 | if(line) | 273 | if(line) |
286 | { | 274 | { |
287 | lines++; | 275 | lines++; |
288 | for(i = y; i > 1; i--) | 276 | // move rows down |
289 | memcpy(virtual + i * max_x + 1, virtual + (i-1) * max_x + 1, max_x - 2); | 277 | for(i = x; i < max_x - 1; i++) |
290 | memset (&virtual[max_x] + 1, 0, max_x - 2); | 278 | for (j = 0; j < max_y; j++) |
279 | *(virtual + j * max_x + i) = *(virtual + j * max_x + (i + 1)); | ||
280 | |||
281 | x--; // re-check this line | ||
291 | } | 282 | } |
292 | } | 283 | } |
293 | return lines / 2; | 284 | |
285 | return lines / 4; | ||
294 | } | 286 | } |
295 | 287 | ||
296 | void move_down(void) | 288 | void move_down(void) |
297 | { | 289 | { |
298 | int l; | 290 | int l; |
299 | char s[25]; | 291 | char s[25]; |
300 | if(!valid_position(current_x,current_y+1,current_b,current_f)) | 292 | |
293 | if(!valid_position(current_x - 4, current_y, current_b, current_f)) | ||
301 | { | 294 | { |
302 | to_virtual(); | 295 | to_virtual(); |
303 | l = check_lines(); | 296 | l = check_lines(); |
@@ -310,62 +303,68 @@ void move_down(void) | |||
310 | from_virtual(); | 303 | from_virtual(); |
311 | score += l*l; | 304 | score += l*l; |
312 | } | 305 | } |
306 | |||
313 | snprintf (s, sizeof(s), "%d Rows - Level %d", lines, level); | 307 | snprintf (s, sizeof(s), "%d Rows - Level %d", lines, level); |
314 | lcd_putsxy (2, 52, s, 0); | 308 | lcd_putsxy (2, 52, s, 0); |
309 | |||
315 | new_block(); | 310 | new_block(); |
316 | move_block(0,0,0); | 311 | move_block(0,0,0); |
317 | } | 312 | } |
318 | else | 313 | else |
319 | move_block(0,2,0); | 314 | move_block(-4,0,0); |
320 | } | 315 | } |
321 | 316 | ||
322 | void game_loop(void) | 317 | void game_loop(void) |
323 | { | 318 | { |
324 | while(1) | 319 | while(1) |
325 | { | 320 | { |
326 | int b=0; | 321 | int b=0; |
327 | int count = 0; | 322 | int count = 0; |
328 | while(count*300 < level_speeds[level]) | 323 | while(count * 300 < level_speeds[level]) |
329 | { | 324 | { |
330 | b = button_get(false); | 325 | b = button_get(false); |
331 | if ( b & BUTTON_OFF ) | 326 | if ( b & BUTTON_OFF ) |
332 | return; /* get out of here */ | 327 | return; /* get out of here */ |
333 | 328 | ||
334 | if ( b & BUTTON_LEFT ) { | 329 | if ( b & BUTTON_UP ) |
335 | move_block(-2,0,0); | 330 | move_block(0,-4,0); |
336 | } | 331 | |
337 | if ( b & BUTTON_RIGHT ) { | 332 | if ( b & BUTTON_DOWN ) |
338 | move_block(2,0,0); | 333 | move_block(0,4,0); |
339 | } | 334 | |
340 | if ( b & BUTTON_UP ) { | 335 | if ( b & BUTTON_RIGHT ) |
341 | move_block(0,0,-1); | 336 | move_block(0,0,-1); |
342 | } | 337 | |
343 | if ( b & BUTTON_DOWN ) { | 338 | if ( b & BUTTON_LEFT ) |
344 | move_down(); | 339 | move_down(); |
340 | |||
341 | count++; | ||
342 | sleep(HZ/10); | ||
345 | } | 343 | } |
346 | count++; | 344 | |
347 | sleep(HZ/10); | 345 | if(gameover()) |
348 | } | 346 | { |
349 | if(gameover()) { | ||
350 | int w, h; | 347 | int w, h; |
351 | 348 | ||
352 | lcd_getfontsize(TETRIS_TITLE_FONT, &w, &h); | 349 | lcd_getfontsize(TETRIS_TITLE_FONT, &w, &h); |
353 | lcd_clearrect(TETRIS_TITLE_XLOC, TETRIS_TITLE_YLOC, | 350 | lcd_clearrect(TETRIS_TITLE_XLOC, TETRIS_TITLE_YLOC, |
354 | TETRIS_TITLE_XLOC+(w*sizeof(TETRIS_TITLE)), | 351 | TETRIS_TITLE_XLOC+(w*sizeof(TETRIS_TITLE)), |
355 | TETRIS_TITLE_YLOC-h); | 352 | TETRIS_TITLE_YLOC-h); |
356 | lcd_putsxy(TETRIS_TITLE_XLOC, TETRIS_TITLE_YLOC, "You lose!", | 353 | lcd_putsxy(TETRIS_TITLE_XLOC, TETRIS_TITLE_YLOC, "You lose!", |
357 | TETRIS_TITLE_FONT); | 354 | TETRIS_TITLE_FONT); |
358 | lcd_update(); | 355 | lcd_update(); |
359 | sleep(HZ); | 356 | sleep(HZ); |
360 | return; | 357 | return; |
361 | } | 358 | } |
362 | move_down(); | 359 | |
360 | move_down(); | ||
363 | } | 361 | } |
364 | } | 362 | } |
365 | 363 | ||
366 | void init_tetris(void) | 364 | void init_tetris(void) |
367 | { | 365 | { |
368 | memset(&virtual, 0, sizeof(virtual)); | 366 | memset(&virtual, 0, sizeof(virtual)); |
367 | |||
369 | current_x = 0; | 368 | current_x = 0; |
370 | current_y = 0; | 369 | current_y = 0; |
371 | current_f = 0; | 370 | current_f = 0; |
@@ -381,11 +380,7 @@ void tetris(void) | |||
381 | { | 380 | { |
382 | init_tetris(); | 381 | init_tetris(); |
383 | 382 | ||
384 | draw_frame(start_x,start_x + max_x - 1, start_y - 1, start_y + max_y); | 383 | draw_frame(start_x, start_x + max_x - 1, start_y - 1, start_y + max_y); |
385 | lcd_putsxy(TETRIS_TITLE_XLOC, TETRIS_TITLE_YLOC, TETRIS_TITLE, | ||
386 | TETRIS_TITLE_FONT); | ||
387 | lcd_putsxy(TETRIS_TITLE_XLOC, TETRIS_TITLE_YLOC + 16, "*******", | ||
388 | TETRIS_TITLE_FONT); | ||
389 | lcd_putsxy (2, 52, "0 Rows - Level 0", 0); | 384 | lcd_putsxy (2, 52, "0 Rows - Level 0", 0); |
390 | lcd_update(); | 385 | lcd_update(); |
391 | 386 | ||