Index: apps/plugins/fingersofrock.c =================================================================== --- apps/plugins/fingersofrock.c (revision 0) +++ apps/plugins/fingersofrock.c (revision 0) @@ -0,0 +1,815 @@ +/*************************************************************************** + * __________ __ ___. + * 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. + * + ****************************************************************************/ +#include "plugin.h" +#include "lib/fixedpoint.h" +#include "lib/helper.h" + +PLUGIN_HEADER + +/* variable button definitions */ +#if (CONFIG_KEYPAD == SANSA_C200_PAD) || \ + (CONFIG_KEYPAD == SANSA_E200_PAD) || \ + (CONFIG_KEYPAD == MROBE100_PAD) || \ + (CONFIG_KEYPAD == GIGABEAT_S_PAD) || \ + (CONFIG_KEYPAD == GIGABEAT_F_PAD) || \ + (CONFIG_KEYPAD == GIGABEAT_PAD) || \ + (CONFIG_KEYPAD == COWOND2_PAD) || \ + (CONFIG_KEYPAD == CREATIVEZVM_PAD) || \ + (CONFIG_KEYPAD == IAUDIO_X5M5_PAD) +#define FOR_UP BUTTON_UP +#define FOR_LEFT BUTTON_LEFT +#define FOR_RIGHT BUTTON_RIGHT +#define FOR_DOWN BUTTON_DOWN +#define FOR_EXIT BUTTON_POWER + +#elif (CONFIG_KEYPAD == RECORDER_PAD) || \ + (CONFIG_KEYPAD == ARCHOS_AV300_PAD) || \ + (CONFIG_KEYPAD == ONDIO_PAD) || \ + (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ + (CONFIG_KEYPAD == IRIVER_H300_PAD) +#define FOR_UP BUTTON_UP +#define FOR_LEFT BUTTON_LEFT +#define FOR_RIGHT BUTTON_RIGHT +#define FOR_DOWN BUTTON_DOWN +#define FOR_EXIT BUTTON_OFF + +#elif CONFIG_KEYPAD == IRIVER_H10_PAD +#define FOR_UP BUTTON_SCROLL_UP +#define FOR_LEFT BUTTON_LEFT +#define FOR_RIGHT BUTTON_RIGHT +#define FOR_DOWN BUTTON_SCROLL_DOWN +#define FOR_EXIT BUTTON_POWER + +#elif (CONFIG_KEYPAD == PLAYER_PAD) +#define FOR_UP BUTTON_PLAY +#define FOR_LEFT BUTTON_LEFT +#define FOR_RIGHT BUTTON_RIGHT +#define FOR_DOWN BUTTON_STOP +#define FOR_EXIT BUTTON_ON + +#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ + (CONFIG_KEYPAD == IPOD_3G_PAD) || \ + (CONFIG_KEYPAD == IPOD_1G2G_PAD) +#define FOR_UP BUTTON_MENU +#define FOR_LEFT BUTTON_LEFT +#define FOR_RIGHT BUTTON_RIGHT +#define FOR_DOWN BUTTON_PLAY +#define FOR_EXIT BUTTON_SELECT + +#elif (ONFIG_KEYPAD == IRIVER_H10_PAD) +#define FOR_UP BUTTON_FF +#define FOR_LEFT BUTTON_LEFT +#define FOR_RIGHT BUTTON_RIGHT +#define FOR_DOWN BUTTON_REW +#define FOR_EXIT BUTTON_POWER + +#elif (CONFIG_KEYPAD == IRIVER_IFP7XX_PAD) +#define FOR_UP BUTTON_FF +#define FOR_LEFT BUTTON_LEFT +#define FOR_RIGHT BUTTON_RIGHT +#define FOR_DOWN BUTTON_REW +#define FOR_EXIT (BUTTON_MODE|BUTTON_EQ) + +#elif CONFIG_KEYPAD == IRIVER_H10_PAD +#define FOR_UP BUTTON_UP +#define FOR_LEFT BUTTON_LEFT +#define FOR_RIGHT BUTTON_RIGHT +#define FOR_DOWN BUTTON_DOWN +#define FOR_EXIT (BUTTON_OFF|BUTTON_ON) + + +#else +/* Guess and hope for the best */ +#warning No key mapping. Please add one. +#define FOR_UP BUTTON_UP +#define FOR_LEFT BUTTON_LEFT +#define FOR_RIGHT BUTTON_RIGHT +#define FOR_DOWN BUTTON_DOWN +#define FOR_EXIT BUTTON_OFF + + +#endif + + + + +# define ARROW_SPACING 4 /* Pixels between arrows */ + +# define HORIZONTAL 0 +# define VERTICAL 1 + +/* if the width is at least 1/4 larger than the height, rotate the screen */ +# if LCD_WIDTH > LCD_HEIGHT + # define ARROW_DIRECTION HORIZONTAL + # define ARROW_SIZE ((LCD_HEIGHT-(4*ARROW_SPACING))/4) + # define MAX_ARROWS (LCD_WIDTH/ARROW_SIZE*2) + # define HP_BAR_WIDTH 5 + # define HP_BAR_HEIGHT LCD_HEIGHT + /*arrow (spawn) positions + / |--| U ^ | + / |hp| R > | <----- ARROWS + / | | L < | + / |__| D V \ + / / \ \_____ + / / \ \ + / Perfect Almost Miss-threshold */ + + # define UP_ARROW_Y (ARROW_SPACING/2) + # define RIGHT_ARROW_Y (UP_ARROW_Y + ARROW_SPACING + ARROW_SIZE) + # define LEFT_ARROW_Y (RIGHT_ARROW_Y + ARROW_SPACING + ARROW_SIZE) + # define DOWN_ARROW_Y (LEFT_ARROW_Y + ARROW_SPACING + ARROW_SIZE) + + # define FRAME_ARROW_X HP_BAR_WIDTH + # define SPAWN_ARROW_X LCD_WIDTH + +# else + # define ARROW_DIRECTION VERTICAL + # define ARROW_SIZE ((LCD_WIDTH-(4*ARROW_SPACING))/4) + # define MAX_ARROWS (LCD_HEIGHT-(4*ARROW_SPACING)/ARROW_SIZE*2) + # define HP_BAR_WIDTH LCD_WIDTH + # define HP_BAR_HEIGHT 5 + /*arrow (spawn) positions + / ------- + / | HP | + / ------- + / < ^ V > + / L U D R + / + / /\ + / //\\ + / || + / || + / ARROWS */ + + # define LEFT_ARROW_X (ARROW_SPACING/2) + # define UP_ARROW_X (LEFT_ARROW_X + ARROW_SPACING + ARROW_SIZE) + # define DOWN_ARROW_X (UP_ARROW_X + ARROW_SPACING + ARROW_SIZE) + # define RIGHT_ARROW_X (DOWN_ARROW_X + ARROW_SPACING + ARROW_SIZE) + + # define FRAME_ARROW_Y HP_BAR_HEIGHT + # define SPAWN_ARROW_Y LCD_HEIGHT +# endif + +/* +- Pixels when checking collision with frame */ +# define PRESS_PERFECT_BUFFER (ARROW_SIZE/4) +# define PRESS_GOOD_BUFFER (ARROW_SIZE/2) +# define PRESS_MISS_BUFFER ARROW_SIZE + +# define ARROW_SPEED 2.5 /* pixels per frame */ +# define MAX_HP 100 +# define FPS 30 /* base fps. automaticaly increases with score */ + + + + + +/* from robotfindskitten.c */ +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 int grey = 6; +const unsigned int orange = 7; +const unsigned int colours[8] = { +#if LCD_DEPTH >= 16 + 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 */ + LCD_RGBPACK(192, 192, 192), /* grey */ + LCD_RGBPACK(255, 128, 0) /* orange */ +#endif +}; + +void setColour(unsigned int colour){ + #if LCD_DEPTH >= 16 + rb->lcd_set_foreground(colours[colour]); + #endif +} + + +enum Directions{ LEFT, RIGHT, UP, DOWN, NONE }; +enum ArrowState{ ACTIVE, MISSED, OFF }; /* for drawing */ +enum Accuracy{ PERFECT, GOOD, MISS, IGNORE }; /* for awarding points */ + +struct Arrow{ + /* since the rest of the code is so wasteful, thought i would */ + /* try to be economical... =( */ + #if ARROW_DIRECTION == VERTICAL + short x; + float y; + #else + float x; + short y; + #endif + int direction; + int state; +}; + +void deployArrow( struct Arrow *arrow ){ + arrow->state = ACTIVE; +#if ARROW_DIRECTION == VERTICAL + arrow->y = SPAWN_ARROW_Y; + switch( rb->rand() % 4 ){ + /* Left */ + case 0: + arrow->x = LEFT_ARROW_X; + arrow->direction = LEFT; + break; + + /* Up */ + case 1: + arrow->x = UP_ARROW_X; + arrow->direction = UP; + break; + + /* Down */ + case 2: + arrow->x = DOWN_ARROW_X; + arrow->direction = DOWN; + break; + + /* Right */ + case 3: + arrow->x = RIGHT_ARROW_X; + arrow->direction = RIGHT; + break; + } +#else + arrow->x = SPAWN_ARROW_X; + switch( rb->rand() % 4 ){ + /* Left */ + case 0: + arrow->y = LEFT_ARROW_Y; + arrow->direction = LEFT; + break; + + /* Up */ + case 1: + arrow->y = UP_ARROW_Y; + arrow->direction = UP; + break; + + /* Down */ + case 2: + arrow->y = DOWN_ARROW_Y; + arrow->direction = DOWN; + break; + + /* Right */ + case 3: + arrow->y = RIGHT_ARROW_Y; + arrow->direction = RIGHT; + break; + } +#endif +} + +int handleInput(struct Arrow *arrow){ + #if ARROW_DIRECTION == VERTICAL + /* approaching frame */ + if( arrow->y > FRAME_ARROW_Y ){ + if( arrow->y < FRAME_ARROW_Y+PRESS_MISS_BUFFER ){ + if( arrow->y < FRAME_ARROW_Y+PRESS_GOOD_BUFFER ){ + if( arrow->y < FRAME_ARROW_Y+PRESS_PERFECT_BUFFER ){ + arrow->state = OFF; + return PERFECT; + } + arrow->state = OFF; + return GOOD; + } + arrow->state = MISSED; + return MISS; + } + return IGNORE; + } else { + /* leaving frame */ + if( arrow->y < FRAME_ARROW_Y-PRESS_MISS_BUFFER ){ + if( arrow->y < FRAME_ARROW_Y-PRESS_GOOD_BUFFER ){ + if( arrow->y < FRAME_ARROW_Y-PRESS_PERFECT_BUFFER ){ + arrow->state = OFF; + return PERFECT; + } + arrow->state = OFF; + return GOOD; + } + arrow->state = MISSED; + return MISS; + } + return IGNORE; + } + #else + /* approaching frame */ + if( arrow->x > FRAME_ARROW_X ){ + if( arrow->x < FRAME_ARROW_X+PRESS_MISS_BUFFER ){ + if( arrow->x < FRAME_ARROW_X+PRESS_GOOD_BUFFER ){ + if( arrow->x < FRAME_ARROW_X+PRESS_PERFECT_BUFFER ){ + arrow->state = OFF; + return PERFECT; + } + arrow->state = OFF; + return GOOD; + } + arrow->state = MISSED; + return MISS; + } + return IGNORE; + } else { + /* leaving frame */ + if( arrow->x < FRAME_ARROW_X-PRESS_MISS_BUFFER ){ + if( arrow->x < FRAME_ARROW_X-PRESS_GOOD_BUFFER ){ + if( arrow->x < FRAME_ARROW_X-PRESS_PERFECT_BUFFER ){ + arrow->state = OFF; + return PERFECT; + } + arrow->state = OFF; + return GOOD; + } + arrow->state = MISSED; + return MISS; + } + return IGNORE; + } + #endif +} + +int awardPoints(int hitAccuracy){ + switch(hitAccuracy){ + case PERFECT: return 5; + case GOOD: return 2; + case MISS: return 0; + case IGNORE: return 0; + default: + rb->splash(HZ*2, "Bad Arrow"); + return 0; + } +} + +int awardHp(int hitAccuracy){ + switch(hitAccuracy){ + case PERFECT: return 8; + case GOOD: return 4; + case MISS: return -4 ; + case IGNORE: return 0; + default: + rb->splash(HZ*2, "Bad Arrow"); + return 0; + } +} + + +/* Taken from pong.c */ +void showscore(unsigned int score){ + static char buffer[20]; + int w,h; + + rb->snprintf(buffer, sizeof(buffer), "%d", score); + rb->lcd_getstringsize((unsigned char *)buffer, &w, &h); + rb->lcd_putsxy( LCD_WIDTH-w, LCD_HEIGHT-h, (unsigned char *)buffer); +} + +void showAccuracy(int hitAccuracy){ + static char buffer[20]; + int w,h; + + switch( hitAccuracy ){ + case PERFECT: + rb->snprintf(buffer, sizeof(buffer), "Perfect!"); + rb->lcd_getstringsize((unsigned char *)buffer, &w, &h); + break; + + case GOOD: + rb->snprintf(buffer, sizeof(buffer), "Good"); + rb->lcd_getstringsize((unsigned char *)buffer, &w, &h); + break; + + case MISS: + rb->snprintf(buffer, sizeof(buffer), "Miss"); + rb->lcd_getstringsize((unsigned char *)buffer, &w, &h); + break; + } + + rb->lcd_putsxy( (LCD_WIDTH/2)-(w/2), (LCD_HEIGHT/2)-(h/2), + (unsigned char *)buffer); +} + +void drawBasicArrow( int direction, + signed int x, signed int y, + unsigned int w, unsigned int h){ + switch( direction ){ + case LEFT: + /* tip */ + rb->lcd_drawline( x+(w/2), y, x, y+(h/2) ); + rb->lcd_drawline( x, y+(h/2), x+(w/2), y+h ); + /* mid : */ + rb->lcd_drawline( x+(w/2), y, x+(w/2), y+(h/3) ); + rb->lcd_drawline( x+(w/2), y+(h*2/3), x+(w/2), y+h ); + /* end */ + rb->lcd_drawline( x+(w/2), y+(h/3), x+w, y+(h/3) ); + rb->lcd_drawline( x+(w/2), y+(h*2/3), x+w, y+(h*2/3) ); + rb->lcd_drawline( x+w, y+(h/3), x+w, y+(h*2/3) ); + break; + + case UP: + /* tip */ + rb->lcd_drawline( x+(w/2), y, x, y+(h/2) ); + rb->lcd_drawline( x+(w/2), y, x+w, y+(h/2) ); + /* mid */ + rb->lcd_drawline( x, y+(h/2), x+(w/3), y+(h/2) ); + rb->lcd_drawline( x+(w*2/3), y+(h/2), x+w, y+(h/2) ); + /* end */ + rb->lcd_drawline( x+(w/3), y+(h/2), x+(w/3), y+h ); + rb->lcd_drawline( x+(w*2/3), y+(h/2), x+(w*2/3), y+h ); + rb->lcd_drawline( x+(w/3), y+h, x+(w*2/3), y+h ); + break; + + case DOWN: + /* tip */ + rb->lcd_drawline( x, y+(h/2), x+(w/2), y+h ); + rb->lcd_drawline( x+w, y+(h/2), x+(w/2), y+h ); + /* mid */ + rb->lcd_drawline( x, y+(h/2), x+(w/3), y+(h/2) ); + rb->lcd_drawline( x+(w*2/3), y+(h/2), x+w, y+(h/2) ); + /* end */ + rb->lcd_drawline( x+(w/3), y, x+(w/3), y+(h/2) ); + rb->lcd_drawline( x+(w*2/3), y, x+(w*2/3), y+(h/2) ); + rb->lcd_drawline( x+(w/3), y, x+(w*2/3), y ); + break; + + case RIGHT: + /* tip */ + rb->lcd_drawline( x+(w/2), y, x+w, y+(h/2) ); + rb->lcd_drawline( x+(w/2), y+h, x+w, y+(h/2) ); + /* mid */ + rb->lcd_drawline( x+(w/2), y, x+(w/2), y+(h/3) ); + rb->lcd_drawline( x+(w/2), y+(h*2/3), x+(w/2), y+h ); + /* end */ + rb->lcd_drawline( x, y+(h/3), x+(w/2), y+(h/3) ); + rb->lcd_drawline( x, y+(h*2/3), x+(w/2), y+(h*2/3) ); + rb->lcd_drawline( x, y+(h/3), x, y+(h*2/3) ); + break; + default: + rb->splash(HZ*2, "Bad Arrow"); + } +} + +/* Hopefully, in the future there will be a variety of */ +/* in-built arrows for users to choose from. Users will also be able to */ +/* load custom images to use as arrows */ +/* Image strip, accompanied by info file(detailing width/height) */ + +void drawArrow1( unsigned int direction, + signed int x, signed int y, + unsigned int w, unsigned int h){ + switch( direction ){ + case LEFT: + drawBasicArrow( LEFT, x, y, w, h); + drawBasicArrow( LEFT, x+1, y+1, w-2, h-2); + drawBasicArrow( LEFT, x+2, y+2, w-4, h-4); + break; + + case UP: + drawBasicArrow( UP, x, y, w, h); + drawBasicArrow( UP, x+1, y+1, w-2, h-2); + drawBasicArrow( UP, x+2, y+2, w-4, h-4); + break; + + case DOWN: + drawBasicArrow( DOWN, x, y, w, h); + drawBasicArrow( DOWN, x+1, y+1, w-2, h-2); + drawBasicArrow( DOWN, x+2, y+2, w-4, h-4); + break; + + case RIGHT: + drawBasicArrow( RIGHT, x, y, w, h); + drawBasicArrow( RIGHT, x+1, y+1, w-2, h-2); + drawBasicArrow( RIGHT, x+2, y+2, w-4, h-4); + return; + default: + rb->splash(HZ*2, "Bad Arrow"); + } +} + + +enum plugin_status plugin_start(const void* parameter) +{ + (void)parameter; + + #ifndef HAVE_LCD_BITMAP + rb->splash(HZ*2, "incompatible lcd"); + return PLUGIN_OK; + #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(); /* backlight control in lib/helper.c */ + rb->srand (*rb->current_tick); + /* boost cpu */ + #ifdef HAVE_ADJUSTABLE_CPU_FREQ + rb->cpu_boost(true); + #endif + + + /* iuno, intro thingy + disclaimer */ + rb->splash(HZ*4, "Rockbox will not be responsible for button \ + damage resulting from the use of this plugin"); + rb->lcd_clear_display(); + rb->splash(HZ*3, "Fingers Of Rock. BYO music edition"); + rb->lcd_clear_display(); + #if ARROW_DIRECTION == HORIZONTAL + rb->splash(HZ*3, "Please physically rotate player 90* clockwise"); + rb->lcd_clear_display(); + #endif + rb->splash(HZ*1, "Ready"); + rb->lcd_clear_display(); + rb->splash(HZ*1, "Set"); + rb->lcd_clear_display(); + rb->splash(HZ*1, "GO!"); + + + int i = 0; + /* Ticks, at the start of a cycle */ + int sTime; + int hitAccuracy; + /* previous hit hit acc. */ + int prevAccuracy; + /* am = accuracy message */ + int amMaxTime = HZ; + int amTimeLeft = 0; + float percentHP = 100; + + + struct Arrow arrows[MAX_ARROWS]; + for( i = 0; i < MAX_ARROWS; ++i ){ + arrows[i].x = 0; + arrows[i].y = 0; + arrows[i].direction = NONE; + arrows[i].state = OFF; + } + int hp = MAX_HP; + unsigned int score = 0; + bool done = false; + long button; + + + while ( !done ){ + sTime = *rb->current_tick; + + hitAccuracy = IGNORE; + /* Check input */ + button = rb->button_get_w_tmo (1); + if( button & FOR_LEFT ){ + for( i = 0; i < MAX_ARROWS; ++i ){ + if( arrows[i].state == ACTIVE ){ + if( arrows[i].direction == LEFT ){ + hitAccuracy = handleInput(&arrows[i]); + score += awardPoints( hitAccuracy ); + hp += awardHp( hitAccuracy ); + if( hitAccuracy != IGNORE ){ + prevAccuracy = hitAccuracy; + amTimeLeft = amMaxTime; + } + } + } + } + } + + if( button & FOR_UP ){ + for( i = 0; i < MAX_ARROWS; ++i ){ + if( arrows[i].state == ACTIVE ){ + if( arrows[i].direction == UP ){ + hitAccuracy = handleInput(&arrows[i]); + score += awardPoints( hitAccuracy ); + hp += awardHp( hitAccuracy ); + if( hitAccuracy != IGNORE ){ + prevAccuracy = hitAccuracy; + amTimeLeft = amMaxTime; + } + } + } + } + } + + if( button & FOR_DOWN ){ + for( i = 0; i < MAX_ARROWS; ++i ){ + if( arrows[i].state == ACTIVE ){ + if( arrows[i].direction == DOWN){ + hitAccuracy = handleInput(&arrows[i]); + score += awardPoints( hitAccuracy ); + hp += awardHp( hitAccuracy ); + if( hitAccuracy != IGNORE ){ + prevAccuracy = hitAccuracy; + amTimeLeft = amMaxTime; + } + } + } + } + } + + if( button & FOR_RIGHT ){ + for( i = 0; i < MAX_ARROWS; ++i ){ + if( arrows[i].state == ACTIVE ){ + if( arrows[i].direction == RIGHT ){ + hitAccuracy = handleInput(&arrows[i]); + score += awardPoints( hitAccuracy ); + hp += awardHp( hitAccuracy ); + if( hitAccuracy != IGNORE ){ + prevAccuracy = hitAccuracy; + amTimeLeft = amMaxTime; + } + } + } + } + } + + if( button & FOR_EXIT ) + done = true; + + if ( rb->default_event_handler(button) == SYS_USB_CONNECTED ) + done = true; + + + /* spawn arrow */ + if( rb->rand()/10 > rb->rand() ){ + for ( i = 0; i < MAX_ARROWS; ++i){ + if ( arrows[i].state == OFF ){ + deployArrow(&arrows[i]); + break; + } + } + } + + + /* move arrows */ + for ( i = 0; i < MAX_ARROWS; ++i){ + if ( arrows[i].state != OFF ){ + #if ARROW_DIRECTION == VERTICAL + arrows[i].y -= ARROW_SPEED; + /* check if it has moved off the screen */ + if( arrows[i].y < FRAME_ARROW_Y-PRESS_MISS_BUFFER ){ + if( arrows[i].state == ACTIVE ){ + hp -= 15; + } + arrows[i].state = OFF; + } + #else + arrows[i].x -= ARROW_SPEED; + /* check if it has moved off the screen */ + if( arrows[i].x < FRAME_ARROW_X-PRESS_MISS_BUFFER ){ + if( arrows[i].state == ACTIVE ){ + hp -= 15; + } + arrows[i].state = OFF; + } + #endif + } + } + + + + /* clear display and redraw frame */ + #ifdef USE_COLOUR + rb->lcd_set_background(colours[black]); + #endif + rb->lcd_clear_display(); + + setColour(white); + showscore(score); + + /* draw accuracy messeges */ + setColour(yellow); + if( amTimeLeft > 0 ){ + showAccuracy( prevAccuracy ); + } + + /* draw hp bar */ + if( hp > MAX_HP/4 ){ + setColour(blue); + } else { + setColour(red); + } + + percentHP = ((float)hp/MAX_HP); + if(percentHP>1){percentHP=1;} + #if ARROW_DIRECTION == VERTICAL + /* arrows run up */ + /* bar is horizontal, drains to left */ + rb->lcd_fillrect(0,0,percentHP*HP_BAR_WIDTH,HP_BAR_HEIGHT); + #else + /* arrows run across, horizontal */ + /* Bar is vertical, drains down */ + rb->lcd_fillrect(0,HP_BAR_HEIGHT-(percentHP*HP_BAR_HEIGHT),HP_BAR_WIDTH,HP_BAR_HEIGHT); + #endif + + /* draw arrow frames */ + setColour(grey); + #if ARROW_DIRECTION == VERTICAL + drawArrow1( LEFT, LEFT_ARROW_X, FRAME_ARROW_Y, + ARROW_SIZE, ARROW_SIZE); + drawArrow1( UP, UP_ARROW_X, FRAME_ARROW_Y, + ARROW_SIZE, ARROW_SIZE); + drawArrow1( DOWN, DOWN_ARROW_X, FRAME_ARROW_Y, + ARROW_SIZE, ARROW_SIZE); + drawArrow1( RIGHT, RIGHT_ARROW_X, FRAME_ARROW_Y, + ARROW_SIZE, ARROW_SIZE); + #else + drawArrow1( LEFT, FRAME_ARROW_X, LEFT_ARROW_Y, + ARROW_SIZE, ARROW_SIZE); + drawArrow1( UP, FRAME_ARROW_X, UP_ARROW_Y, + ARROW_SIZE, ARROW_SIZE); + drawArrow1( DOWN, FRAME_ARROW_X, DOWN_ARROW_Y, + ARROW_SIZE, ARROW_SIZE); + drawArrow1( RIGHT, FRAME_ARROW_X, RIGHT_ARROW_Y, + ARROW_SIZE, ARROW_SIZE); + #endif + + /* draw arrows */ + for ( i = 0; i < MAX_ARROWS; ++i){ + if ( arrows[i].state != OFF ){ + if( arrows[i].state == ACTIVE ){ + setColour(green); + } else { + /* missed */ + setColour(grey); + } + switch( arrows[i].direction ){ + case LEFT: + drawArrow1( LEFT, arrows[i].x, arrows[i].y, + ARROW_SIZE, ARROW_SIZE); + break; + case UP: + drawArrow1( UP, arrows[i].x, arrows[i].y, + ARROW_SIZE, ARROW_SIZE); + break; + case DOWN: + drawArrow1( DOWN, arrows[i].x, arrows[i].y, + ARROW_SIZE, ARROW_SIZE); + break; + case RIGHT: + drawArrow1( RIGHT, arrows[i].x, arrows[i].y, + ARROW_SIZE, ARROW_SIZE); + break; + } + } + } + + + if( amTimeLeft > 0 ) + amTimeLeft -= *rb->current_tick-sTime; + + /* check if lost */ + if( hp < 0 ){ + rb->splash(HZ*3, "FAIL."); + done = true; + } + + /* control fps */ + if ( *rb->current_tick - sTime < HZ/FPS ){ + rb->sleep( (HZ/(FPS+((float)score/4))) - (*rb->current_tick - sTime) ); + } + + /* update screen */ + rb->lcd_update(); + } + + /* Turn on backlight timeout (revert to settings) */ + backlight_use_settings(); /* backlight control in lib/helper.c */ + rb->lcd_setfont (FONT_UI); + /* unoost cpu */ + #ifdef HAVE_ADJUSTABLE_CPU_FREQ + rb->cpu_boost(false); + #endif + + return PLUGIN_OK; +} + Property changes on: apps/plugins/fingersofrock.c ___________________________________________________________________ Added: svn:executable + * Index: apps/plugins/SOURCES =================================================================== --- apps/plugins/SOURCES (revision 20605) +++ apps/plugins/SOURCES (working copy) @@ -3,6 +3,7 @@ credits.c cube.c dict.c +fingersofrock.c jackpot.c keybox.c logo.c Index: apps/plugins/CATEGORIES =================================================================== --- apps/plugins/CATEGORIES (revision 20605) +++ apps/plugins/CATEGORIES (working copy) @@ -20,6 +20,7 @@ disktidy,apps doom,games euroconverter,apps +fingersofrock,games fire,demos fireworks,demos firmware_flash,apps