diff options
author | Frank Gevaerts <frank@gevaerts.be> | 2011-01-08 16:32:56 +0000 |
---|---|---|
committer | Frank Gevaerts <frank@gevaerts.be> | 2011-01-08 16:32:56 +0000 |
commit | 17585a991cdd045ea5a166dd78d609262ebf3efb (patch) | |
tree | f2eadff15e53114900b5d0456f2ac877040add88 /apps/plugins/pong.c | |
parent | 1c06d83c1527bb39436c922815e9f9d55318d072 (diff) | |
download | rockbox-17585a991cdd045ea5a166dd78d609262ebf3efb.tar.gz rockbox-17585a991cdd045ea5a166dd78d609262ebf3efb.zip |
Add AI to the pong plugin, to allow single-player operation.
Part of FS#5855 by Travis Hyyppa (the colour changes were removed from the patch)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29007 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/pong.c')
-rw-r--r-- | apps/plugins/pong.c | 103 |
1 files changed, 91 insertions, 12 deletions
diff --git a/apps/plugins/pong.c b/apps/plugins/pong.c index eece69db12..49fc8e1468 100644 --- a/apps/plugins/pong.c +++ b/apps/plugins/pong.c | |||
@@ -28,6 +28,8 @@ | |||
28 | 28 | ||
29 | #define SPEEDX ( LCD_WIDTH * 3 ) / 2 /* Recorder: 168 iRiver: 240 */ | 29 | #define SPEEDX ( LCD_WIDTH * 3 ) / 2 /* Recorder: 168 iRiver: 240 */ |
30 | #define SPEEDY LCD_HEIGHT * 2 /* Recorder: 128 iRiver: 256 */ | 30 | #define SPEEDY LCD_HEIGHT * 2 /* Recorder: 128 iRiver: 256 */ |
31 | #define CPU_PLAYER_DIST ( (LCD_WIDTH/8 ) * 5 ) /* This is the width of the dead spot where the */ | ||
32 | #define DEM_PLAYER_DIST ( (LCD_WIDTH/8 ) * 3 ) /* cpu player doesnt care about the ball -- 3/8 of the screen */ | ||
31 | 33 | ||
32 | #define RES 100 | 34 | #define RES 100 |
33 | 35 | ||
@@ -263,8 +265,8 @@ struct pong { | |||
263 | int e_pad[2]; /* existing current Y positions of pads */ | 265 | int e_pad[2]; /* existing current Y positions of pads */ |
264 | int ballspeedx; /* */ | 266 | int ballspeedx; /* */ |
265 | int ballspeedy; /* */ | 267 | int ballspeedy; /* */ |
266 | |||
267 | int score[2]; | 268 | int score[2]; |
269 | bool cpu_player[2]; /* Status of AI players */ | ||
268 | }; | 270 | }; |
269 | 271 | ||
270 | void singlepad(int x, int y, int set) | 272 | void singlepad(int x, int y, int set) |
@@ -298,11 +300,11 @@ bool wallcollide(struct pong *p, int pad) | |||
298 | the wall */ | 300 | the wall */ |
299 | if(pad) { | 301 | if(pad) { |
300 | /* right-side */ | 302 | /* right-side */ |
301 | if(p->ballx > LCD_WIDTH*RES) | 303 | if(p->ballx > ( LCD_WIDTH*RES ) - PAD_WIDTH ) |
302 | return true; | 304 | return true; |
303 | } | 305 | } |
304 | else { | 306 | else { |
305 | if(p->ballx < 0) | 307 | if(p->ballx < PAD_WIDTH) |
306 | return true; | 308 | return true; |
307 | } | 309 | } |
308 | return false; | 310 | return false; |
@@ -346,9 +348,15 @@ bool padcollide(struct pong *p, int pad, int *info) | |||
346 | 348 | ||
347 | void bounce(struct pong *p, int pad, int info) | 349 | void bounce(struct pong *p, int pad, int info) |
348 | { | 350 | { |
349 | (void)pad; /* not used right now */ | ||
350 | p->ballspeedx = -p->ballspeedx; | 351 | p->ballspeedx = -p->ballspeedx; |
351 | 352 | ||
353 | if(pad==0) { /* Give ball a little push to keep it from getting stuck between wall and pad */ | ||
354 | p->ballx += PAD_WIDTH; | ||
355 | } | ||
356 | else { | ||
357 | p->ballx -= PAD_WIDTH; | ||
358 | } | ||
359 | |||
352 | /* info is the hit-angle into the pad */ | 360 | /* info is the hit-angle into the pad */ |
353 | if(p->ballspeedy > 0) { | 361 | if(p->ballspeedy > 0) { |
354 | /* downwards */ | 362 | /* downwards */ |
@@ -522,17 +530,53 @@ int keys(struct pong *p) | |||
522 | 530 | ||
523 | key = rb->button_status(); /* ignore BUTTON_REPEAT */ | 531 | key = rb->button_status(); /* ignore BUTTON_REPEAT */ |
524 | 532 | ||
525 | if(key & PONG_LEFT_DOWN) /* player left goes down */ | 533 | if(p->cpu_player[1] == true) { |
526 | padmove(&p->w_pad[0], MOVE_STEP); | 534 | if( (p->bally/RES > p->w_pad[0]) |
535 | & (p->ballx/RES < DEM_PLAYER_DIST) ) /* player right goes down */ | ||
536 | padmove(&p->w_pad[0], MOVE_STEP); | ||
537 | |||
538 | if( (p->bally/RES < p->w_pad[0]) | ||
539 | & (p->ballx/RES < DEM_PLAYER_DIST) ) /* player right goes up */ | ||
540 | padmove(&p->w_pad[0], -MOVE_STEP); | ||
541 | |||
542 | if( (key & PONG_LEFT_DOWN) || (key & PONG_LEFT_UP) ) { | ||
543 | /* if left player presses control keys stop cpu player */ | ||
544 | p->cpu_player[1] = false; | ||
545 | p->score[0] = p->score[1] = 0; /* reset the score */ | ||
546 | rb->lcd_clear_display(); /* get rid of the text */ | ||
547 | } | ||
548 | } | ||
549 | else { | ||
550 | if(key & PONG_LEFT_DOWN) /* player left goes down */ | ||
551 | padmove(&p->w_pad[0], MOVE_STEP); | ||
527 | 552 | ||
528 | if(key & PONG_LEFT_UP) /* player left goes up */ | 553 | if(key & PONG_LEFT_UP) /* player left goes up */ |
529 | padmove(&p->w_pad[0], -MOVE_STEP); | 554 | padmove(&p->w_pad[0], -MOVE_STEP); |
555 | } | ||
530 | 556 | ||
531 | if(key & PONG_RIGHT_DOWN) /* player right goes down */ | 557 | if(p->cpu_player[2] == true) { |
532 | padmove(&p->w_pad[1], MOVE_STEP); | 558 | if( (p->bally/RES > p->w_pad[1]) |
559 | & (p->ballx/RES > CPU_PLAYER_DIST) ) /* player right goes down */ | ||
560 | padmove(&p->w_pad[1], MOVE_STEP); | ||
561 | |||
562 | if( (p->bally/RES < p->w_pad[1]) | ||
563 | & (p->ballx/RES > CPU_PLAYER_DIST) ) /* player right goes up */ | ||
564 | padmove(&p->w_pad[1], -MOVE_STEP); | ||
565 | |||
566 | if( (key & PONG_RIGHT_DOWN) || (key & PONG_RIGHT_UP) ) { | ||
567 | /* if right player presses control keys stop cpu player */ | ||
568 | p->cpu_player[2] = false; | ||
569 | p->score[0] = p->score[1] = 0; /* reset the score */ | ||
570 | rb->lcd_clear_display(); /* get rid of the text */ | ||
571 | } | ||
572 | } | ||
573 | else { | ||
574 | if(key & PONG_RIGHT_DOWN) /* player right goes down */ | ||
575 | padmove(&p->w_pad[1], MOVE_STEP); | ||
533 | 576 | ||
534 | if(key & PONG_RIGHT_UP) /* player right goes up */ | 577 | if(key & PONG_RIGHT_UP) /* player right goes up */ |
535 | padmove(&p->w_pad[1], -MOVE_STEP); | 578 | padmove(&p->w_pad[1], -MOVE_STEP); |
579 | } | ||
536 | 580 | ||
537 | if(rb->default_event_handler(key) == SYS_USB_CONNECTED) | 581 | if(rb->default_event_handler(key) == SYS_USB_CONNECTED) |
538 | return -1; /* exit game because of USB */ | 582 | return -1; /* exit game because of USB */ |
@@ -550,12 +594,28 @@ void showscore(struct pong *p) | |||
550 | rb->lcd_putsxy( (LCD_WIDTH / 2) - (w / 2), 0, (unsigned char *)buffer); | 594 | rb->lcd_putsxy( (LCD_WIDTH / 2) - (w / 2), 0, (unsigned char *)buffer); |
551 | } | 595 | } |
552 | 596 | ||
597 | void blink_demo(void) | ||
598 | { | ||
599 | static char buffer[30]; | ||
600 | int w; | ||
601 | |||
602 | rb->snprintf(buffer, sizeof(buffer), "Press Key To Play"); | ||
603 | w = rb->lcd_getstringsize((unsigned char *)buffer, NULL, NULL); | ||
604 | if(LCD_WIDTH > ( (w/8)*7 ) ) /* make sure text isn't too long for screen */ | ||
605 | rb->lcd_putsxy( (LCD_WIDTH / 2) - (w / 2), (LCD_HEIGHT / 2), | ||
606 | (unsigned char *)buffer); | ||
607 | } | ||
608 | |||
553 | /* this is the plugin entry point */ | 609 | /* this is the plugin entry point */ |
554 | enum plugin_status plugin_start(const void* parameter) | 610 | enum plugin_status plugin_start(const void* parameter) |
555 | { | 611 | { |
556 | struct pong pong; | 612 | struct pong pong; |
557 | int game = 1; | 613 | int game = 1; |
558 | 614 | ||
615 | int blink_timer = 0; | ||
616 | int blink_rate = 20; | ||
617 | bool blink = true; | ||
618 | |||
559 | /* init the struct with some silly values to start with */ | 619 | /* init the struct with some silly values to start with */ |
560 | 620 | ||
561 | pong.ballx = 20*RES; | 621 | pong.ballx = 20*RES; |
@@ -565,6 +625,7 @@ enum plugin_status plugin_start(const void* parameter) | |||
565 | pong.w_pad[0] = 7; | 625 | pong.w_pad[0] = 7; |
566 | pong.e_pad[1] = 0; | 626 | pong.e_pad[1] = 0; |
567 | pong.w_pad[1] = 40; | 627 | pong.w_pad[1] = 40; |
628 | pong.cpu_player[1] = pong.cpu_player[2] = true; /* start every game in demo mode */ | ||
568 | 629 | ||
569 | pong.ballspeedx = SPEEDX; | 630 | pong.ballspeedx = SPEEDX; |
570 | pong.ballspeedy = SPEEDY; | 631 | pong.ballspeedy = SPEEDY; |
@@ -586,6 +647,24 @@ enum plugin_status plugin_start(const void* parameter) | |||
586 | game = keys(&pong); /* short circuit */ | 647 | game = keys(&pong); /* short circuit */ |
587 | rb->lcd_clear_display(); | 648 | rb->lcd_clear_display(); |
588 | } | 649 | } |
650 | |||
651 | if( (pong.cpu_player[1]==true) && (pong.cpu_player[2]==true) ) { | ||
652 | if(blink_timer<blink_rate) { | ||
653 | ++blink_timer; | ||
654 | } | ||
655 | else { | ||
656 | blink_timer=0; | ||
657 | blink = !blink; | ||
658 | } | ||
659 | |||
660 | if(blink==true) { | ||
661 | blink_demo(); | ||
662 | } | ||
663 | else { | ||
664 | rb->lcd_clear_display(); | ||
665 | } | ||
666 | } | ||
667 | |||
589 | showscore(&pong); | 668 | showscore(&pong); |
590 | pad(&pong, 0); /* draw left pad */ | 669 | pad(&pong, 0); /* draw left pad */ |
591 | pad(&pong, 1); /* draw right pad */ | 670 | pad(&pong, 1); /* draw right pad */ |