Index: apps/plugins/pong.c =================================================================== --- apps/plugins/pong.c (revision 19778) +++ apps/plugins/pong.c (working copy) @@ -32,6 +32,8 @@ #define SPEEDX ( LCD_WIDTH * 3 ) / 2 /* Recorder: 168 iRiver: 240 */ #define SPEEDY LCD_HEIGHT * 2 /* Recorder: 128 iRiver: 256 */ +#define CPU_PLAYER_DIST ( (LCD_WIDTH/8 ) * 5 ) /* This is the width of the dead spot where the */ +#define DEM_PLAYER_DIST ( (LCD_WIDTH/8 ) * 3 ) /* cpu player doesnt care about the ball -- 3/8 of the screen */ #define RES 100 @@ -201,12 +203,52 @@ int e_pad[2]; /* existing current Y positions of pads */ int ballspeedx; /* */ int ballspeedy; /* */ - int score[2]; + bool cpu_player[2]; /* Status of AI players */ }; void singlepad(int x, int y, int set) { + +#ifdef HAVE_LCD_COLOR + +#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) /* Get the peaks. ( Borrowed from vu_meter ) */ + int left_peak = rb->mas_codec_readreg(0xC); + int right_peak = rb->mas_codec_readreg(0xD); +#elif (CONFIG_CODEC == SWCODEC) + int left_peak, right_peak; + rb->pcm_calculate_peaks(&left_peak, &right_peak); +#endif + + int left_boost, right_boost; + + left_peak = left_peak/0x80; /* Devide peak data by 128 to bring the max value down from ~32k to 256 */ + right_peak = right_peak/0x80; + left_boost = 0; + right_boost = 0; + if(left_peak<0x80) /* Make sure the pads dont black out with soft music */ + left_peak = 0x80; + if(right_peak<0x80) + right_peak = 0x80; + + if(left_peak>0xFF) /* And make sure they dont go over 255 */ + left_peak = 0xFF; + if(right_peak>0xFF) + right_peak= 0xFF; + + if(left_peak>0xDD) /* Boost the red when needed to make keep loud sounds bright, */ + left_boost = left_peak - 0xDD; /* instead of just very green. */ + if(right_peak>0xDD) + right_boost = right_peak - 0xDD; + + if(xlcd_set_foreground(LCD_RGBPACK( 64 + left_boost, left_peak, 0)); + } + else { + rb->lcd_set_foreground(LCD_RGBPACK( 64 + right_boost, right_peak, 0)); + } +#endif /* HAVE_LCD_COLOR */ + if(set) { rb->lcd_fillrect(x, y, PAD_WIDTH, PAD_HEIGHT); } @@ -236,11 +278,11 @@ the wall */ if(pad) { /* right-side */ - if(p->ballx > LCD_WIDTH*RES) + if(p->ballx > ( LCD_WIDTH*RES ) - PAD_WIDTH ) return true; } else { - if(p->ballx < 0) + if(p->ballx < PAD_WIDTH) return true; } return false; @@ -284,9 +326,15 @@ void bounce(struct pong *p, int pad, int info) { - (void)pad; /* not used right now */ p->ballspeedx = -p->ballspeedx; + if(pad==0) { /* Give ball a little push to keep it from getting stuck between wall and pad */ + p->ballx += PAD_WIDTH; + } + else { + p->ballx -= PAD_WIDTH; + } + /* info is the hit-angle into the pad */ if(p->ballspeedy > 0) { /* downwards */ @@ -334,7 +382,7 @@ /* avoid hitting the pad with the new ball */ p->ballx = (p->ballx < 0) ? (RES * PAD_WIDTH) : (RES * (LCD_WIDTH - PAD_WIDTH - BALL_WIDTH)); - + /* restore Y-speed to default */ p->ballspeedy = (p->ballspeedy > 0) ? SPEEDY : -SPEEDY; @@ -393,6 +441,10 @@ rb->lcd_fillrect(x, y, BALL_WIDTH, BALL_HEIGHT); rb->lcd_set_drawmode(DRMODE_SOLID); +#ifdef HAVE_LCD_COLOR + rb->lcd_set_foreground(LCD_RGBPACK(128, 255, 0)); +#endif + /* draw the new ball position */ rb->lcd_fillrect(newx, newy, BALL_WIDTH, BALL_HEIGHT); } @@ -460,18 +512,54 @@ key = rb->button_status(); /* ignore BUTTON_REPEAT */ - if(key & PONG_LEFT_DOWN) /* player left goes down */ + if(p->cpu_player[1] == true) { + if( (p->bally/RES > p->w_pad[0]) + & (p->ballx/RES < DEM_PLAYER_DIST) ) /* player right goes down */ padmove(&p->w_pad[0], MOVE_STEP); - if(key & PONG_LEFT_UP) /* player left goes up */ - padmove(&p->w_pad[0], -MOVE_STEP); + if( (p->bally/RES < p->w_pad[0]) + & (p->ballx/RES < DEM_PLAYER_DIST) ) /* player right goes up */ + padmove(&p->w_pad[0], -MOVE_STEP); - if(key & PONG_RIGHT_DOWN) /* player right goes down */ - padmove(&p->w_pad[1], MOVE_STEP); + if( (key & PONG_LEFT_DOWN) || (key & PONG_LEFT_UP) ) { + /* if left player presses control keys stop cpu player */ + p->cpu_player[1] = false; + p->score[0] = p->score[1] = 0; /* reset the score */ + rb->lcd_clear_display(); /* get rid of the text */ + } + } + else { + if(key & PONG_LEFT_DOWN) /* player left goes down */ + padmove(&p->w_pad[0], MOVE_STEP); - if(key & PONG_RIGHT_UP) /* player right goes up */ - padmove(&p->w_pad[1], -MOVE_STEP); - + if(key & PONG_LEFT_UP) /* player left goes up */ + padmove(&p->w_pad[0], -MOVE_STEP); + } + + if(p->cpu_player[2] == true) { + if( (p->bally/RES > p->w_pad[1]) + & (p->ballx/RES > CPU_PLAYER_DIST) ) /* player right goes down */ + padmove(&p->w_pad[1], MOVE_STEP); + + if( (p->bally/RES < p->w_pad[1]) + & (p->ballx/RES > CPU_PLAYER_DIST) ) /* player right goes up */ + padmove(&p->w_pad[1], -MOVE_STEP); + + if( (key & PONG_RIGHT_DOWN) || (key & PONG_RIGHT_UP) ) { + /* if right player presses control keys stop cpu player */ + p->cpu_player[2] = false; + p->score[0] = p->score[1] = 0; /* reset the score */ + rb->lcd_clear_display(); /* get rid of the text */ + } + } + else { + if(key & PONG_RIGHT_DOWN) /* player right goes down */ + padmove(&p->w_pad[1], MOVE_STEP); + + if(key & PONG_RIGHT_UP) /* player right goes up */ + padmove(&p->w_pad[1], -MOVE_STEP); + } + if(rb->default_event_handler(key) == SYS_USB_CONNECTED) return -1; /* exit game because of USB */ } @@ -483,17 +571,41 @@ static char buffer[20]; int w; +#ifdef HAVE_LCD_COLOR + rb->lcd_set_foreground(LCD_RGBPACK(128, 255, 0)); +#endif + rb->snprintf(buffer, sizeof(buffer), "%d - %d", p->score[0], p->score[1]); w = rb->lcd_getstringsize((unsigned char *)buffer, NULL, NULL); rb->lcd_putsxy( (LCD_WIDTH / 2) - (w / 2), 0, (unsigned char *)buffer); } +void blink_demo(void) +{ + static char buffer[30]; + int w; + +#ifdef HAVE_LCD_COLOR + rb->lcd_set_foreground(LCD_RGBPACK(128, 255, 0)); +#endif + + rb->snprintf(buffer, sizeof(buffer), "Press Key To Play"); + w = rb->lcd_getstringsize((unsigned char *)buffer, NULL, NULL); + if(LCD_WIDTH > ( (w/8)*7 ) ) /* make sure text isn't too long for screen */ + rb->lcd_putsxy( (LCD_WIDTH / 2) - (w / 2), (LCD_HEIGHT / 2), + (unsigned char *)buffer); +} + /* this is the plugin entry point */ enum plugin_status plugin_start(const void* parameter) { struct pong pong; int game = 1; + int blink_timer = 0; + int blink_rate = 20; + bool blink = true; + /* init the struct with some silly values to start with */ pong.ballx = 20*RES; @@ -503,6 +615,7 @@ pong.w_pad[0] = 7; pong.e_pad[1] = 0; pong.w_pad[1] = 40; + pong.cpu_player[1] = pong.cpu_player[2] = true; /* start every game in demo mode */ pong.ballspeedx = SPEEDX; pong.ballspeedy = SPEEDY; @@ -512,7 +625,12 @@ /* if you don't use the parameter, you can do like this to avoid the compiler warning about it */ (void)parameter; - + +#ifdef HAVE_LCD_COLOR + rb->lcd_set_background(LCD_RGBPACK(0, 0, 0)); + rb->lcd_set_foreground(LCD_RGBPACK(128, 255, 0)); +#endif + /* Clear screen */ rb->lcd_clear_display(); @@ -524,6 +642,24 @@ game = keys(&pong); /* short circuit */ rb->lcd_clear_display(); } + + if( (pong.cpu_player[1]==true) && (pong.cpu_player[2]==true) ) { + if(blink_timerlcd_clear_display(); + } + } + showscore(&pong); pad(&pong, 0); /* draw left pad */ pad(&pong, 1); /* draw right pad */