diff options
author | Johannes Schwarz <ubuntuxer@rockbox.org> | 2009-09-17 20:38:44 +0000 |
---|---|---|
committer | Johannes Schwarz <ubuntuxer@rockbox.org> | 2009-09-17 20:38:44 +0000 |
commit | 3ad6ee3fcd0481c37df8cf569dc8a8a5b3cdbf85 (patch) | |
tree | 1f2d3ae508ceb08c75f037660649e5ae41c925af | |
parent | 75e301dabb0f78332f00a1e2520210857c7f71d2 (diff) | |
download | rockbox-3ad6ee3fcd0481c37df8cf569dc8a8a5b3cdbf85.tar.gz rockbox-3ad6ee3fcd0481c37df8cf569dc8a8a5b3cdbf85.zip |
Rename Starting Level to Snake Speed, save the last selected speed, remove highscore list, and clean up the code a little bit
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22719 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/plugins/snake.c | 352 |
1 files changed, 161 insertions, 191 deletions
diff --git a/apps/plugins/snake.c b/apps/plugins/snake.c index 54d1d5dce3..87b68d2055 100644 --- a/apps/plugins/snake.c +++ b/apps/plugins/snake.c | |||
@@ -34,7 +34,7 @@ dir is the current direction of the snake - 0=up, 1=right, 2=down, 3=left; | |||
34 | 34 | ||
35 | #include "plugin.h" | 35 | #include "plugin.h" |
36 | #ifdef HAVE_LCD_BITMAP | 36 | #ifdef HAVE_LCD_BITMAP |
37 | #include "lib/highscore.h" | 37 | #include "lib/configfile.h" |
38 | #include "lib/playback_control.h" | 38 | #include "lib/playback_control.h" |
39 | 39 | ||
40 | PLUGIN_HEADER | 40 | PLUGIN_HEADER |
@@ -154,9 +154,6 @@ PLUGIN_HEADER | |||
154 | 154 | ||
155 | #define SNAKE_RC_QUIT BUTTON_REC | 155 | #define SNAKE_RC_QUIT BUTTON_REC |
156 | 156 | ||
157 | #elif (CONFIG_KEYPAD == COWOND2_PAD) | ||
158 | #define SNAKE_QUIT BUTTON_POWER | ||
159 | |||
160 | #elif CONFIG_KEYPAD == CREATIVEZVM_PAD | 157 | #elif CONFIG_KEYPAD == CREATIVEZVM_PAD |
161 | #define SNAKE_QUIT BUTTON_BACK | 158 | #define SNAKE_QUIT BUTTON_BACK |
162 | #define SNAKE_LEFT BUTTON_LEFT | 159 | #define SNAKE_LEFT BUTTON_LEFT |
@@ -173,6 +170,14 @@ PLUGIN_HEADER | |||
173 | #define SNAKE_DOWN BUTTON_DOWN | 170 | #define SNAKE_DOWN BUTTON_DOWN |
174 | #define SNAKE_PLAYPAUSE BUTTON_MENU | 171 | #define SNAKE_PLAYPAUSE BUTTON_MENU |
175 | 172 | ||
173 | #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD | ||
174 | #define SNAKE_QUIT BUTTON_REC | ||
175 | #define SNAKE_LEFT BUTTON_LEFT | ||
176 | #define SNAKE_RIGHT BUTTON_RIGHT | ||
177 | #define SNAKE_UP BUTTON_UP | ||
178 | #define SNAKE_DOWN BUTTON_DOWN | ||
179 | #define SNAKE_PLAYPAUSE BUTTON_PLAY | ||
180 | |||
176 | #elif CONFIG_KEYPAD == MROBE500_PAD | 181 | #elif CONFIG_KEYPAD == MROBE500_PAD |
177 | #define SNAKE_QUIT BUTTON_POWER | 182 | #define SNAKE_QUIT BUTTON_POWER |
178 | #define SNAKE_RC_QUIT BUTTON_RC_DOWN | 183 | #define SNAKE_RC_QUIT BUTTON_RC_DOWN |
@@ -183,13 +188,8 @@ PLUGIN_HEADER | |||
183 | #elif (CONFIG_KEYPAD == ONDAVX777_PAD) | 188 | #elif (CONFIG_KEYPAD == ONDAVX777_PAD) |
184 | #define SNAKE_QUIT BUTTON_POWER | 189 | #define SNAKE_QUIT BUTTON_POWER |
185 | 190 | ||
186 | #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD | 191 | #elif CONFIG_KEYPAD == COWOND2_PAD |
187 | #define SNAKE_QUIT BUTTON_REC | 192 | #define SNAKE_QUIT BUTTON_POWER |
188 | #define SNAKE_LEFT BUTTON_LEFT | ||
189 | #define SNAKE_RIGHT BUTTON_RIGHT | ||
190 | #define SNAKE_UP BUTTON_UP | ||
191 | #define SNAKE_DOWN BUTTON_DOWN | ||
192 | #define SNAKE_PLAYPAUSE BUTTON_PLAY | ||
193 | 193 | ||
194 | #else | 194 | #else |
195 | #error No keymap defined! | 195 | #error No keymap defined! |
@@ -218,44 +218,44 @@ PLUGIN_HEADER | |||
218 | 218 | ||
219 | #define BOARD_WIDTH (LCD_WIDTH/4) | 219 | #define BOARD_WIDTH (LCD_WIDTH/4) |
220 | #define BOARD_HEIGHT (LCD_HEIGHT/4) | 220 | #define BOARD_HEIGHT (LCD_HEIGHT/4) |
221 | #define NUM_SCORES 5 | ||
222 | #define SCORE_FILE PLUGIN_GAMES_DIR "/snake.score" | ||
223 | 221 | ||
224 | static int board[BOARD_WIDTH][BOARD_HEIGHT],snakelength; | 222 | static int board[BOARD_WIDTH][BOARD_HEIGHT],snakelength; |
225 | static int score,level=1; | 223 | static unsigned int score,hiscore=0,level=1; |
226 | static int dir,dead=0,quit=0; | 224 | static int dir; |
227 | static bool apple; | 225 | static bool apple, dead; |
228 | 226 | ||
229 | static struct highscore highscores[NUM_SCORES]; | 227 | #define CONFIG_FILE_NAME "snake.cfg" |
228 | static struct configdata config[] = { | ||
229 | {TYPE_INT, 0, 10, { .int_p = &level }, "level", NULL}, | ||
230 | {TYPE_INT, 0, 10000, { .int_p = &hiscore }, "hiscore", NULL}, | ||
231 | }; | ||
230 | 232 | ||
231 | void die (void) | 233 | static void snake_die (void) |
232 | { | 234 | { |
233 | char pscore[17]; | 235 | char pscore[17]; |
234 | rb->lcd_clear_display(); | 236 | rb->lcd_clear_display(); |
235 | rb->snprintf(pscore,sizeof(pscore),"Your score: %d",score); | 237 | rb->snprintf(pscore,sizeof(pscore),"Your score: %d",score); |
236 | rb->lcd_puts(0,0,"Oops..."); | 238 | rb->lcd_puts(0,0,"Oops..."); |
237 | rb->lcd_puts(0,1, pscore); | 239 | rb->lcd_puts(0,1, pscore); |
238 | if (highscore_update(score, level, "", highscores, NUM_SCORES) == 0) { | 240 | if (score>hiscore) { |
241 | hiscore=score; | ||
239 | rb->lcd_puts(0,2,"New High Score!"); | 242 | rb->lcd_puts(0,2,"New High Score!"); |
240 | } | 243 | } |
241 | else { | 244 | else { |
242 | rb->snprintf(pscore, sizeof(pscore), | 245 | rb->snprintf(pscore,sizeof(pscore),"High Score: %d",hiscore); |
243 | "High Score: %d", highscores[0].score); | ||
244 | rb->lcd_puts(0,2,pscore); | 246 | rb->lcd_puts(0,2,pscore); |
245 | } | 247 | } |
246 | rb->lcd_update(); | 248 | rb->lcd_update(); |
247 | rb->sleep(3*HZ); | 249 | rb->sleep(3*HZ); |
248 | dead=1; | 250 | dead=true; |
249 | } | 251 | } |
250 | 252 | ||
251 | void colission (short x, short y) | 253 | static void snake_colission (short x, short y) |
252 | { | 254 | { |
253 | if (x==BOARD_WIDTH || x<0 || y==BOARD_HEIGHT || y<0) | 255 | if (x==BOARD_WIDTH || x<0 || y==BOARD_HEIGHT || y<0) { |
254 | { | 256 | snake_die(); |
255 | die(); | ||
256 | return; | 257 | return; |
257 | } | 258 | } |
258 | |||
259 | switch (board[x][y]) { | 259 | switch (board[x][y]) { |
260 | case 0: | 260 | case 0: |
261 | break; | 261 | break; |
@@ -265,12 +265,12 @@ void colission (short x, short y) | |||
265 | apple=false; | 265 | apple=false; |
266 | break; | 266 | break; |
267 | default: | 267 | default: |
268 | die(); | 268 | snake_die(); |
269 | break; | 269 | break; |
270 | } | 270 | } |
271 | } | 271 | } |
272 | 272 | ||
273 | void move_head (short x, short y) | 273 | static void snake_move_head (short x, short y) |
274 | { | 274 | { |
275 | switch (dir) { | 275 | switch (dir) { |
276 | case 0: | 276 | case 0: |
@@ -286,14 +286,36 @@ void move_head (short x, short y) | |||
286 | x-=1; | 286 | x-=1; |
287 | break; | 287 | break; |
288 | } | 288 | } |
289 | colission (x,y); | 289 | snake_colission (x,y); |
290 | if (dead) | 290 | if (dead) |
291 | return; | 291 | return; |
292 | board[x][y]=1; | 292 | board[x][y]=1; |
293 | rb->lcd_fillrect(x*4,y*4,4,4); | 293 | rb->lcd_fillrect(x*4,y*4,4,4); |
294 | } | 294 | } |
295 | 295 | ||
296 | void frame (void) | 296 | static void snake_redraw (void) |
297 | { | ||
298 | short x,y; | ||
299 | rb->lcd_clear_display(); | ||
300 | for (x=0; x<BOARD_WIDTH; x++) { | ||
301 | for (y=0; y<BOARD_HEIGHT; y++) { | ||
302 | switch (board[x][y]) { | ||
303 | case -1: | ||
304 | rb->lcd_fillrect((x*4)+1,y*4,2,4); | ||
305 | rb->lcd_fillrect(x*4,(y*4)+1,4,2); | ||
306 | break; | ||
307 | case 0: | ||
308 | break; | ||
309 | default: | ||
310 | rb->lcd_fillrect(x*4,y*4,4,4); | ||
311 | break; | ||
312 | } | ||
313 | } | ||
314 | } | ||
315 | rb->lcd_update(); | ||
316 | } | ||
317 | |||
318 | static void snake_frame (void) | ||
297 | { | 319 | { |
298 | short x,y,head=0; | 320 | short x,y,head=0; |
299 | for (x=0; x<BOARD_WIDTH; x++) { | 321 | for (x=0; x<BOARD_WIDTH; x++) { |
@@ -301,7 +323,7 @@ void frame (void) | |||
301 | switch (board[x][y]) { | 323 | switch (board[x][y]) { |
302 | case 1: | 324 | case 1: |
303 | if (!head) { | 325 | if (!head) { |
304 | move_head(x,y); | 326 | snake_move_head(x,y); |
305 | if (dead) | 327 | if (dead) |
306 | return; | 328 | return; |
307 | board[x][y]++; | 329 | board[x][y]++; |
@@ -328,92 +350,116 @@ void frame (void) | |||
328 | rb->lcd_update(); | 350 | rb->lcd_update(); |
329 | } | 351 | } |
330 | 352 | ||
331 | void redraw (void) | 353 | static void snake_game_init(void) { |
332 | { | ||
333 | short x,y; | 354 | short x,y; |
334 | rb->lcd_clear_display(); | 355 | rb->lcd_clear_display(); |
356 | |||
335 | for (x=0; x<BOARD_WIDTH; x++) { | 357 | for (x=0; x<BOARD_WIDTH; x++) { |
336 | for (y=0; y<BOARD_HEIGHT; y++) { | 358 | for (y=0; y<BOARD_HEIGHT; y++) { |
337 | switch (board[x][y]) { | 359 | board[x][y]=0; |
338 | case -1: | ||
339 | rb->lcd_fillrect((x*4)+1,y*4,2,4); | ||
340 | rb->lcd_fillrect(x*4,(y*4)+1,4,2); | ||
341 | break; | ||
342 | case 0: | ||
343 | break; | ||
344 | default: | ||
345 | rb->lcd_fillrect(x*4,y*4,4,4); | ||
346 | break; | ||
347 | } | ||
348 | } | 360 | } |
349 | } | 361 | } |
350 | rb->lcd_update(); | 362 | apple=false; |
363 | dead=false; | ||
364 | snakelength=4; | ||
365 | score=0; | ||
366 | board[11][7]=1; | ||
351 | } | 367 | } |
352 | 368 | ||
353 | void game_pause (void) { | 369 | static void snake_choose_level(void) |
354 | int button; | 370 | { |
355 | rb->lcd_clear_display(); | 371 | rb->set_int("Snake Speed", "", UNIT_INT, &level, NULL, 1, 1, 9, NULL); |
356 | rb->lcd_putsxy(3,12,"Game Paused"); | 372 | } |
357 | #if CONFIG_KEYPAD == RECORDER_PAD | 373 | |
358 | rb->lcd_putsxy(3,22,"[Play] to resume"); | 374 | static bool _ingame; |
359 | #elif CONFIG_KEYPAD == ONDIO_PAD | 375 | static int snake_menu_cb(int action, const struct menu_item_ex *this_item) |
360 | rb->lcd_putsxy(3,22,"[Mode] to resume"); | 376 | { |
361 | #endif | 377 | if(action == ACTION_REQUEST_MENUITEM |
362 | rb->lcd_putsxy(3,32,"[Off] to quit"); | 378 | && !_ingame && ((intptr_t)this_item)==0) |
363 | rb->lcd_update(); | 379 | return ACTION_EXIT_MENUITEM; |
364 | while (1) { | 380 | return action; |
365 | button=rb->button_get(true); | 381 | } |
366 | switch (button) { | 382 | |
367 | #ifdef SNAKE_RC_QUIT | 383 | static int snake_game_menu(bool ingame) |
368 | case SNAKE_RC_QUIT: | 384 | { |
369 | #endif | 385 | rb->button_clear_queue(); |
370 | case SNAKE_QUIT: | 386 | int choice = 0; |
371 | dead=1; | 387 | |
372 | quit=1; | 388 | _ingame = ingame; |
373 | return; | 389 | |
374 | case SNAKE_PLAYPAUSE: | 390 | MENUITEM_STRINGLIST(main_menu,"Snake Menu",snake_menu_cb, |
375 | redraw(); | 391 | "Resume Game", |
376 | rb->sleep(HZ/2); | 392 | "Start New Game", |
377 | return; | 393 | "Snake Speed", |
394 | "High Score", | ||
395 | "Playback Control", | ||
396 | "Quit"); | ||
397 | |||
398 | while (true) { | ||
399 | choice = rb->do_menu(&main_menu, &choice, NULL, false); | ||
400 | switch (choice) { | ||
401 | case 0: | ||
402 | snake_redraw(); | ||
403 | return 0; | ||
404 | case 1: | ||
405 | snake_game_init(); | ||
406 | return 0; | ||
407 | case 2: | ||
408 | snake_choose_level(); | ||
409 | break; | ||
410 | case 3: | ||
411 | rb->splashf(HZ*2, "High Score: %d", hiscore); | ||
412 | break; | ||
413 | case 4: | ||
414 | playback_control(NULL); | ||
415 | break; | ||
416 | case 5: | ||
417 | return 1; | ||
418 | case MENU_ATTACHED_USB: | ||
419 | return 1; | ||
378 | default: | 420 | default: |
379 | if (rb->default_event_handler(button)==SYS_USB_CONNECTED) { | ||
380 | dead = 1; | ||
381 | quit = 2; | ||
382 | return; | ||
383 | } | ||
384 | break; | 421 | break; |
385 | } | 422 | } |
386 | } | 423 | } |
387 | } | 424 | } |
388 | 425 | ||
389 | 426 | static int snake_game_loop (void) { | |
390 | void game (void) { | ||
391 | int button; | 427 | int button; |
392 | short x,y; | 428 | short x,y; |
393 | while (1) { | 429 | bool pause = false; |
394 | frame(); | 430 | |
395 | if (dead) | 431 | if (snake_game_menu(false)==1) |
396 | return; | 432 | return 1; |
397 | if (!apple) { | 433 | |
398 | do { | 434 | while (true) { |
399 | x=rb->rand() % BOARD_WIDTH; | 435 | if (!pause) { |
400 | y=rb->rand() % BOARD_HEIGHT; | 436 | snake_frame(); |
401 | } while (board[x][y]); | 437 | if (dead) { |
402 | apple=true; | 438 | if (snake_game_menu(false)==1) |
403 | board[x][y]=-1; | 439 | return 1; |
404 | rb->lcd_fillrect((x*4)+1,y*4,2,4); | 440 | } |
405 | rb->lcd_fillrect(x*4,(y*4)+1,4,2); | 441 | if (!apple) { |
406 | } | 442 | do { |
443 | x=rb->rand() % BOARD_WIDTH; | ||
444 | y=rb->rand() % BOARD_HEIGHT; | ||
445 | } while (board[x][y]); | ||
446 | apple=true; | ||
447 | board[x][y]=-1; | ||
448 | rb->lcd_fillrect((x*4)+1,y*4,2,4); | ||
449 | rb->lcd_fillrect(x*4,(y*4)+1,4,2); | ||
450 | } | ||
407 | 451 | ||
408 | rb->sleep(HZ/level); | 452 | rb->sleep(HZ/level); |
453 | } | ||
409 | 454 | ||
410 | button=rb->button_get(false); | 455 | button=rb->button_get(false); |
411 | 456 | ||
412 | #ifdef HAS_BUTTON_HOLD | 457 | #ifdef HAS_BUTTON_HOLD |
413 | if (rb->button_hold()) | 458 | if (rb->button_hold()) { |
414 | button = SNAKE_PLAYPAUSE; | 459 | pause = true; |
460 | rb->splash (HZ, "Paused"); | ||
461 | } | ||
415 | #endif | 462 | #endif |
416 | |||
417 | switch (button) { | 463 | switch (button) { |
418 | case SNAKE_UP: | 464 | case SNAKE_UP: |
419 | if (dir!=2) dir=0; | 465 | if (dir!=2) dir=0; |
@@ -427,113 +473,37 @@ void game (void) { | |||
427 | case SNAKE_LEFT: | 473 | case SNAKE_LEFT: |
428 | if (dir!=1) dir=3; | 474 | if (dir!=1) dir=3; |
429 | break; | 475 | break; |
476 | case SNAKE_PLAYPAUSE: | ||
477 | pause = !pause; | ||
478 | if (pause) | ||
479 | rb->splash (HZ, "Paused"); | ||
480 | else | ||
481 | snake_redraw(); | ||
482 | break; | ||
430 | #ifdef SNAKE_RC_QUIT | 483 | #ifdef SNAKE_RC_QUIT |
431 | case SNAKE_RC_QUIT: | 484 | case SNAKE_RC_QUIT: |
432 | #endif | 485 | #endif |
433 | case SNAKE_QUIT: | 486 | case SNAKE_QUIT: |
434 | quit = 1; | 487 | pause = false; |
435 | return; | 488 | if (snake_game_menu(true)==1) |
436 | case SNAKE_PLAYPAUSE: | 489 | return 1; |
437 | game_pause(); | ||
438 | break; | ||
439 | default: | ||
440 | if (rb->default_event_handler(button)==SYS_USB_CONNECTED) { | ||
441 | quit = 2; | ||
442 | return; | ||
443 | } | ||
444 | break; | ||
445 | } | ||
446 | } | ||
447 | } | ||
448 | |||
449 | void game_init(void) { | ||
450 | int selection=0; | ||
451 | short x,y; | ||
452 | bool menu_quit = false; | ||
453 | |||
454 | for (x=0; x<BOARD_WIDTH; x++) { | ||
455 | for (y=0; y<BOARD_HEIGHT; y++) { | ||
456 | board[x][y]=0; | ||
457 | } | ||
458 | } | ||
459 | dead=0; | ||
460 | apple=false; | ||
461 | snakelength=4; | ||
462 | score=0; | ||
463 | board[11][7]=1; | ||
464 | |||
465 | #if LCD_DEPTH > 1 | ||
466 | fb_data *backdrop = rb->lcd_get_backdrop(); | ||
467 | #endif | ||
468 | |||
469 | MENUITEM_STRINGLIST(menu, "Snake Menu", NULL, | ||
470 | "Start New Game", "Starting Level", | ||
471 | "High Scores", | ||
472 | "Playback Control", "Quit"); | ||
473 | |||
474 | rb->button_clear_queue(); | ||
475 | |||
476 | while (!menu_quit) { | ||
477 | switch(rb->do_menu(&menu, &selection, NULL, false)) | ||
478 | { | ||
479 | case 0: | ||
480 | menu_quit = true; /* start playing */ | ||
481 | break; | 490 | break; |
482 | |||
483 | case 1: | ||
484 | rb->set_int("Starting Level", "", UNIT_INT, &level, NULL, | ||
485 | 1, 1, 9, NULL ); | ||
486 | break; | ||
487 | |||
488 | case 2: | ||
489 | #if LCD_DEPTH > 1 | ||
490 | rb->lcd_set_backdrop(NULL); | ||
491 | #endif | ||
492 | highscore_show(NUM_SCORES, highscores, NUM_SCORES, true); | ||
493 | |||
494 | rb->lcd_setfont(FONT_UI); | ||
495 | #if LCD_DEPTH > 1 | ||
496 | rb->lcd_set_backdrop(backdrop); | ||
497 | #ifdef HAVE_LCD_COLOR | ||
498 | rb->lcd_set_background(rb->global_settings->bg_color); | ||
499 | rb->lcd_set_foreground(rb->global_settings->fg_color); | ||
500 | #endif | ||
501 | #endif | ||
502 | break; | ||
503 | |||
504 | case 3: | ||
505 | playback_control(NULL); | ||
506 | break; | ||
507 | |||
508 | case MENU_ATTACHED_USB: | ||
509 | quit = 2; | ||
510 | menu_quit = true; | ||
511 | break; | ||
512 | |||
513 | default: | 491 | default: |
514 | quit = 1; /* quit program */ | 492 | if (rb->default_event_handler (button) == SYS_USB_CONNECTED) |
515 | menu_quit = true; | 493 | return PLUGIN_USB_CONNECTED; |
516 | break; | 494 | break; |
517 | |||
518 | } | 495 | } |
519 | } | 496 | } |
520 | } | 497 | } |
521 | 498 | ||
522 | enum plugin_status plugin_start(const void* parameter) | 499 | enum plugin_status plugin_start(const void* parameter) |
523 | { | 500 | { |
524 | (void)(parameter); | 501 | (void)parameter; |
525 | 502 | ||
526 | highscore_load(SCORE_FILE, highscores, NUM_SCORES); | 503 | configfile_load(CONFIG_FILE_NAME,config,2,0); |
527 | while(!quit) | 504 | rb->lcd_clear_display(); |
528 | { | 505 | snake_game_loop(); |
529 | game_init(); | 506 | configfile_save(CONFIG_FILE_NAME,config,2,0); |
530 | if(quit) | 507 | return PLUGIN_OK; |
531 | break; | ||
532 | rb->lcd_clear_display(); | ||
533 | game(); | ||
534 | } | ||
535 | highscore_save(SCORE_FILE, highscores, NUM_SCORES); | ||
536 | return (quit==1)?PLUGIN_OK:PLUGIN_USB_CONNECTED; | ||
537 | } | 508 | } |
538 | |||
539 | #endif | 509 | #endif |