Index: rockbox/apps/plugins/antibomb.c =================================================================== --- rockbox/apps/plugins/antibomb.c (revision 0) +++ rockbox/apps/plugins/antibomb.c (revision 0) @@ -0,0 +1,515 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id:$ + * + * Copyright (C) 2008 by Tony Huynh + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +/* Much code was borrowed from other plugins =/ */ +/* Pong, xobox, robotfindskitten */ + + +#include "plugin.h" +#include "fixedpoint.h" +#include "helper.c" + +PLUGIN_HEADER + +/* variable button definitions */ +#if (CONFIG_KEYPAD == RECORDER_PAD) || \ + (CONFIG_KEYPAD == ARCHOS_AV300_PAD) +#define ANTIBOMB_UP BUTTON_UP +#define ANTIBOMB_LEFT BUTTON_LEFT +#define ANTIBOMB_RIGHT BUTTON_RIGHT +#define ANTIBOMB_FIRE BUTTON_PLAY +#define ANTIBOMB_EXIT BUTTON_OFF + +#elif CONFIG_KEYPAD == ONDIO_PAD +#define ANTIBOMB_UP BUTTON_UP +#define ANTIBOMB_LEFT BUTTON_LEFT +#define ANTIBOMB_RIGHT BUTTON_RIGHT +#define ANTIBOMB_FIRE BUTTON_MENU +#define ANTIBOMB_EXIT BUTTON_OFF + +#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ + (CONFIG_KEYPAD == IRIVER_H300_PAD) +#define ANTIBOMB_UP BUTTON_UP +#define ANTIBOMB_LEFT BUTTON_LEFT +#define ANTIBOMB_RIGHT BUTTON_RIGHT +#define ANTIBOMB_FIRE BUTTON_SELECT +#define ANTIBOMB_EXIT (BUTTON_OFF|BUTTON_ON) + +#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ + (CONFIG_KEYPAD == IPOD_3G_PAD) || \ + (CONFIG_KEYPAD == IPOD_1G2G_PAD) +#define ANTIBOMB_UP BUTTON_MENU +#define ANTIBOMB_LEFT (BUTTON_LEFT|BUTTON_SCROLL_BACK) +#define ANTIBOMB_RIGHT (BUTTON_RIGHT|BUTTON_SCROLL_FWD) +#define ANTIBOMB_FIRE BUTTON_SELECT +#define ANTIBOMB_EXIT BUTTON_PLAY + +#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD +#define ANTIBOMB_UP BUTTON_UP +#define ANTIBOMB_LEFT BUTTON_LEFT +#define ANTIBOMB_RIGHT BUTTON_RIGHT +#define ANTIBOMB_FIRE (BUTTON_SELECT|BUTTON_PLAY) +#define ANTIBOMB_EXIT (BUTTON_POWER|BUTTON_REC) + +#elif CONFIG_KEYPAD == IRIVER_H10_PAD +#define ANTIBOMB_UP BUTTON_UP +#define ANTIBOMB_LEFT BUTTON_LEFT +#define ANTIBOMB_RIGHT BUTTON_RIGHT +#define ANTIBOMB_FIRE BUTTON_SELECT +#define ANTIBOMB_EXIT (BUTTON_OFF|BUTTON_ON) + +#elif CONFIG_KEYPAD == GIGABEAT_PAD +#define ANTIBOMB_UP BUTTON_UP +#define ANTIBOMB_LEFT BUTTON_LEFT +#define ANTIBOMB_RIGHT BUTTON_RIGHT +#define ANTIBOMB_FIRE BUTTON_SELECT +#define ANTIBOMB_EXIT BUTTON_POWER + +#elif CONFIG_KEYPAD == SANSA_E200_PAD +#define ANTIBOMB_UP BUTTON_UP +#define ANTIBOMB_LEFT (BUTTON_LEFT|BUTTON_SCROLL_BACK) +#define ANTIBOMB_RIGHT (BUTTON_RIGHT|BUTTON_SCROLL_FWD) +#define ANTIBOMB_FIRE BUTTON_SELECT +#define ANTIBOMB_EXIT BUTTON_POWER + +#elif CONFIG_KEYPAD == SANSA_C200_PAD +#define ANTIBOMB_UP BUTTON_UP +#define ANTIBOMB_LEFT (BUTTON_LEFT|BUTTON_VOL_DOWN) +#define ANTIBOMB_RIGHT (BUTTON_RIGHT|BUTTON_VOL_UP) +#define ANTIBOMB_FIRE (BUTTON_SELECT|BUTTON_REC) +#define ANTIBOMB_EXIT BUTTON_POWER + + +#endif + + + + +# define CANNON_WIDTH 18 +# define CANNON_HEIGHT 15 +# define CANNON_X ( (LCD_WIDTH/2) - (CANNON_WIDTH/2) ) +# define CANNON_Y (LCD_HEIGHT-CANNON_HEIGHT) + +# define TURRET_SPEED 10 +# define TURRET_WIDTH 3 +# define TURRET_HEIGHT 10 +# define TURRET_X ( (LCD_WIDTH/2) - (TURRET_WIDTH/2) ) +# define TURRET_Y (LCD_HEIGHT-CANNON_HEIGHT) +# define TURRET_MIN_ANGLE -80 +# define TURRET_MID_ANGLE 0 +# define TURRET_MAX_ANGLE 80 + +# define BOMB_WIDTH 5 +# define BOMB_HEIGHT 10 +# define BOMB_SPEED 1 + +# define BULLET_WIDTH 2 +# define BULLET_HEIGHT BULLET_WIDTH +# define BULLET_SPEED (BOMB_SPEED*3) + +# define MAX_BOMBS 8 +# define MAX_BULLETS MAX_BOMBS+3 +# define MAX_HP 100 +# define FPS 30 + + + +/* from robotfindskitten.c */ +#if LCD_DEPTH >= 16 +#define USE_COLOUR +const unsigned int red = 0; +const unsigned int green = 1; +const unsigned int blue = 2; +const unsigned int yellow = 3; +const unsigned int black = 4; +const unsigned int white = 5; +const unsigned colours[6] = { + LCD_RGBPACK(255, 0, 0), /* red */ + LCD_RGBPACK(0, 255, 0), /* green */ + LCD_RGBPACK(0, 0, 255), /* blue */ + LCD_RGBPACK(255, 255, 0), /* yellow */ + LCD_RGBPACK(0, 0, 0), /* black */ + LCD_RGBPACK(255, 255, 255) /* white */ +}; +#endif + + + +struct bomb{ + short x,y; + bool landed, dead; +}; + +struct bullet{ + float x,y; + float xVel, yVel; + bool active; +}; + +static struct plugin_api* rb; + +/* Taken from pong.c */ +void showscore(unsigned int score) +{ + static char buffer[20]; + int h; + + rb->snprintf(buffer, sizeof(buffer), "Score: %d", score); + rb->lcd_getstringsize((unsigned char *)buffer, NULL, &h); + rb->lcd_putsxy( 0, LCD_HEIGHT-h, (unsigned char *)buffer); +} + + +enum plugin_status plugin_start(const struct plugin_api* api, + const void* parameter) +{ + (void)parameter; + rb = api; + +#ifndef HAVE_LCD_BITMAP + rb->splash(HZ*2, "incompatible lcd"); + return PLUGIN_OK; +#endif + + /* boost cpu */ + #ifdef HAVE_SCHEDULER_BOOSTCTRL + rb->trigger_cpu_boost(); + #endif + +#if LCD_DEPTH > 1 + rb->lcd_set_drawmode(DRMODE_SOLID); +#else + rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); +#endif + +#if LCD_DEPTH>=2 + rb->lcd_set_backdrop(NULL); +#endif + + rb->lcd_setfont (FONT_SYSFIXED); + /* Turn off backlight timeout */ + backlight_force_on(rb); /* backlight control in lib/helper.c */ + + + /* counters for loops */ + int i = 0; + int j = 0; + int x = 0; + /* start of a cycle (frame) */ + int starttime; + + struct bomb stockpile[MAX_BOMBS]; + struct bullet bullets[MAX_BULLETS]; + short turretangle = TURRET_MID_ANGLE; + int hp = MAX_HP; + unsigned int score = 0; + + bool done = false; + long button; + + + /* initialise troops and bullets to default values */ + for ( i = 0; i < MAX_BULLETS; ++i) + { + bullets[i].x = 0; + bullets[i].y = 0; + bullets[i].xVel = 0; + bullets[i].yVel = 0; + bullets[i].active = false; + } + for ( i = 0; i < MAX_BOMBS; ++i) + { + stockpile[i].x = 0; + stockpile[i].y = 0; + stockpile[i].landed = false; + stockpile[i].dead = true; + } + + + while ( !done ) + { + starttime = *rb->current_tick; + + /* Check input */ + button = rb->button_get_w_tmo (1); + if( button & ANTIBOMB_UP ) + turretangle = TURRET_MID_ANGLE; + + if( button & ANTIBOMB_LEFT ) + { + if ( turretangle < TURRET_MAX_ANGLE ) + turretangle += TURRET_SPEED; + } + + if( button & ANTIBOMB_RIGHT ) + { + if ( turretangle > TURRET_MIN_ANGLE ) + turretangle -= TURRET_SPEED; + } + + if( button & ANTIBOMB_FIRE ) + { + /* if there is a free slot, fire a bullet */ + for ( i = 0; i < MAX_BULLETS; ++i) + { + if ( !bullets[i].active ) + { + bullets[i].x = TURRET_X; + bullets[i].y = TURRET_Y; + bullets[i].xVel = -sin_int(turretangle)/16384.0*BULLET_SPEED; + bullets[i].yVel = -cos_int(turretangle)/16384.0*BULLET_SPEED; + bullets[i].active = true; + break; + } + } + } + + if( button & ANTIBOMB_EXIT ) + done = true; + + if ( rb->default_event_handler(button) == SYS_USB_CONNECTED ) + done = true; + + + /* spawn an enemy */ + if( rb->rand()/10 > rb->rand() ){ + for ( i = 0; i < MAX_BOMBS; ++i) + { + if ( stockpile[i].dead ) + { + stockpile[i].x = rb->rand()%LCD_WIDTH; + stockpile[i].y = 0; + stockpile[i].landed = false; + stockpile[i].dead = false; + break; + } + } + } + + + /* move objects */ + /* bullets */ + for ( i = 0; i < MAX_BULLETS; ++i) + { + if ( bullets[i].active ) + { + bullets[i].x += bullets[i].xVel; + bullets[i].y += bullets[i].yVel; + if ( (bullets[i].x < 0) || (bullets[i].x > LCD_WIDTH) || + (bullets[i].y < 0) ) + { + bullets[i].active = false; + } + } + } + + /* move bombs */ + for ( i = 0; i < MAX_BOMBS; ++i) + { + if( !stockpile[i].dead ) + { + if ( !stockpile[i].landed ) + { + stockpile[i].y += BOMB_SPEED; + if ( (stockpile[i].y + BOMB_HEIGHT) > LCD_HEIGHT ) + { + stockpile[i].y = LCD_HEIGHT - BOMB_HEIGHT; + stockpile[i].landed = true; + } + } else + + if ( stockpile[i].landed ) + { + if ( stockpile[i].x < (LCD_WIDTH/2) ) + { + /* move right */ + stockpile[i].x += 2.5*BOMB_SPEED; + if ( (stockpile[i].x + BOMB_WIDTH) > CANNON_X ) + { + stockpile[i].x = CANNON_X - BOMB_WIDTH; + stockpile[i].dead = true; + hp -= 10; + } + } + else + { + /* move left */ + stockpile[i].x -= 2.5*BOMB_SPEED; + if ( stockpile[i].x < (CANNON_X + CANNON_WIDTH) ) + { + stockpile[i].x = CANNON_X + CANNON_WIDTH; + stockpile[i].dead = true; + hp -= 10; + } + } + } + } + } + + /* check collisons */ + for ( i = 0; i < MAX_BULLETS; ++i ) + { + if ( bullets[i].active ) + { + for ( j = 0; j < MAX_BOMBS; ++j ) + { + if( !stockpile[j].dead ) + { + if ( ((bullets[i].x + BULLET_WIDTH) > stockpile[j].x) && + (bullets[i].x < (stockpile[j].x + BOMB_WIDTH)) && + ((bullets[i].y + BULLET_HEIGHT) > stockpile[j].y) && + (bullets[i].y < (stockpile[j].y + BOMB_HEIGHT)) ) + { + bullets[i].active = false; + stockpile[j].dead = true; + ++score; + } + } + } + } + } + + + + + + /* clear display and redraw frame */ + #ifdef USE_COLOUR + rb->lcd_set_background(colours[black]); + #endif + rb->lcd_clear_display(); + + #ifdef USE_COLOUR + rb->lcd_set_foreground(colours[white]); + #endif + showscore(score); + + /* draw bullets */ + for ( i = 0; i < MAX_BULLETS; ++i) + { + if ( bullets[i].active ) + { + #ifdef USE_COLOUR + rb->lcd_set_foreground(colours[yellow]); + #endif + rb->lcd_fillrect( bullets[i].x, bullets[i].y, + BULLET_WIDTH, BULLET_HEIGHT); + } + } + /* draw soliders */ + for ( i = 0; i < MAX_BOMBS; ++i) + { + if ( !stockpile[i].dead ) + { + #ifdef USE_COLOUR + rb->lcd_set_foreground(colours[white]); + #endif + + /* move down A */ + if( !stockpile[i].landed ){ + /* head */ + rb->lcd_fillrect( stockpile[i].x, stockpile[i].y+(BOMB_HEIGHT/2), + BOMB_WIDTH, BOMB_HEIGHT/2); + /* tail */ + rb->lcd_fillrect( stockpile[i].x+(BOMB_WIDTH/4), stockpile[i].y, + BOMB_WIDTH/2, BOMB_HEIGHT/2); + } else { + /* move right -0 */ + if ( stockpile[i].x < CANNON_X ) + { + /* head */ + rb->lcd_fillrect( stockpile[i].x+(BOMB_HEIGHT/2), stockpile[i].y, + BOMB_HEIGHT/2, BOMB_WIDTH); + /* tail */ + rb->lcd_fillrect( stockpile[i].x, stockpile[i].y+(BOMB_WIDTH/4), + BOMB_HEIGHT/2, BOMB_WIDTH/2); + } + + /* left 0- */ + if ( stockpile[i].x > (CANNON_X + CANNON_WIDTH) ) + { + /* head */ + rb->lcd_fillrect( stockpile[i].x, stockpile[i].y, + BOMB_HEIGHT/2, BOMB_WIDTH); + /* tail */ + rb->lcd_fillrect( stockpile[i].x+(BOMB_HEIGHT/2), stockpile[i].y+(BOMB_WIDTH/4), + BOMB_HEIGHT/2, BOMB_WIDTH/2); + } + } + } + } + /* draw cannon */ + #ifdef USE_COLOUR + rb->lcd_set_foreground(colours[green]); + #endif + rb->lcd_fillrect(CANNON_X, CANNON_Y, CANNON_WIDTH, CANNON_HEIGHT); + /* turret */ + for( x = -TURRET_WIDTH/2; x <= TURRET_WIDTH/2; ++x){ + rb->lcd_drawline( x+ TURRET_X - ((sin_int(turretangle)/16384.0)*TURRET_HEIGHT), + TURRET_Y - ((cos_int(turretangle)/16384.0)*TURRET_HEIGHT), + x+ TURRET_X, + TURRET_Y ); + + } + + /* draw hp bar */ + #ifdef USE_COLOUR + if( hp > MAX_HP/4 ){ + rb->lcd_set_foreground(colours[blue]); + } else { + rb->lcd_set_foreground(colours[red]); + } + #endif + rb->lcd_fillrect(0, 0, ((float)hp/MAX_HP)*LCD_WIDTH, 5); + + + #ifdef USE_COLOUR + rb->lcd_set_foreground(colours[white]); + #endif + + + /* check if dead */ + if( hp < 0 ){ + rb->splash(HZ*2, "Your cannon is destroyed!"); + done = true; + } + + + /* limit fps */ + if ( *rb->current_tick - starttime < HZ/FPS ){ + rb->sleep( (HZ/(FPS+((float)score/2))) - (*rb->current_tick - starttime) ); + } + + + /* update screen */ + rb->lcd_update(); + + } + + /* Turn on backlight timeout (revert to settings) */ + backlight_use_settings(rb); /* backlight control in lib/helper.c */ + rb->lcd_setfont(FONT_UI); + + /* Unboost cpu */ + #ifdef HAVE_SCHEDULER_BOOSTCTRL + rb->cancel_cpu_boost(); + #endif + + return PLUGIN_OK; +} + Property changes on: rockbox/apps/plugins/antibomb.c ___________________________________________________________________ Added: svn:executable + *