diff --git a/apps/plugins/chopper.c b/apps/plugins/chopper.c index 5c52c91466..90e217b923 100644 --- a/apps/plugins/chopper.c +++ b/apps/plugins/chopper.c @@ -6,10 +6,10 @@ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id: $ - * + * * Originally by Joshua Oreman, improved by Prashant Varanasi * Ported to Rockbox by Ben Basha (Paprica) - * + * * 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. * @@ -43,31 +43,38 @@ PLUGIN_HEADER #define QUIT BUTTON_MENU #define ACTION BUTTON_SELECT +#define ACTIONTEXT "SELECT" #elif CONFIG_KEYPAD == IAUDIO_X5_PAD /* grayscale at the moment */ #define QUIT BUTTON_POWER #define ACTION BUTTON_SELECT +#define ACTIONTEXT "SELECT" #elif CONFIG_KEYPAD == IRIVER_H10_PAD #define QUIT BUTTON_POWER #define ACTION BUTTON_RIGHT +#define ACTIONTEXT "RIGHT" #elif CONFIG_KEYPAD == SANSA_E200_PAD #define QUIT BUTTON_POWER #define ACTION BUTTON_SELECT +#define ACTIONTEXT "SELECT" #elif CONFIG_KEYPAD == GIGABEAT_PAD #define QUIT BUTTON_MENU #define ACTION BUTTON_SELECT +#define ACTIONTEXT "SELECT" #elif CONFIG_KEYPAD == RECORDER_PAD #define QUIT BUTTON_OFF #define ACTION BUTTON_PLAY +#define ACTIONTEXT "PLAY" #elif CONFIG_KEYPAD == ONDIO_PAD #define QUIT BUTTON_MENU #define ACTION BUTTON_RIGHT +#define ACTIONTEXT "RIGHT" #else #error Unsupported keypad @@ -113,10 +120,10 @@ struct CBlock { int iWorldX; int iWorldY; - + int iSizeX; int iSizeY; - + int bIsActive; }; @@ -124,10 +131,10 @@ struct CParticle { int iWorldX; int iWorldY; - + int iSpeedX; int iSpeedY; - + int bIsActive; }; @@ -157,7 +164,6 @@ static void chopRenderTerrain(struct CTerrain *ter); void chopper_load(bool newgame); void cleanup_chopper(void); - static void chopDrawPlayer(int x,int y) /* These are SCREEN coords, not world! */ { @@ -168,7 +174,7 @@ static void chopDrawPlayer(int x,int y) /* These are SCREEN coords, not world! * #endif rb->lcd_fillrect(x+6, y+2, 12, 9); rb->lcd_fillrect(x-3, y+6, 20, 3); - + #if LCD_DEPTH > 2 rb->lcd_set_foreground(LCD_RGBPACK(50,50,50)); #elif LCD_DEPTH == 2 @@ -176,25 +182,23 @@ static void chopDrawPlayer(int x,int y) /* These are SCREEN coords, not world! * #endif rb->lcd_fillrect(x+10, y, 2, 3); rb->lcd_fillrect(x+10, y, 1, 3); - + #if LCD_DEPTH > 2 - rb->lcd_set_foreground(LCD_RGBPACK(30,30,30)); + rb->lcd_set_foreground(LCD_RGBPACK(40,40,100)); #elif LCD_DEPTH == 2 rb->lcd_set_foreground(LCD_BLACK); #endif rb->lcd_drawline(x, y+iRotorOffset, x+20, y-iRotorOffset); - + #if LCD_DEPTH > 2 - rb->lcd_set_foreground(LCD_RGBPACK(10,10,10)); + rb->lcd_set_foreground(LCD_RGBPACK(20,20,50)); #elif LCD_DEPTH == 2 rb->lcd_set_foreground(LCD_BLACK); #endif rb->lcd_fillrect(x - 2, y + 5, 2, 5); - + } - - static void chopClearTerrain(struct CTerrain *ter) { ter->iNodesCount = -1; @@ -206,61 +210,58 @@ int iR(int low,int high) return low+rb->rand()%(high-low+1); } - static void chopCopyTerrain(struct CTerrain *src, struct CTerrain *dest, int xOffset,int yOffset) { int i=0; - + while(i < src->iNodesCount) { dest->mNodes[i].x = src->mNodes[i].x + xOffset; dest->mNodes[i].y = src->mNodes[i].y + yOffset; - + i++; } - + dest->iNodesCount = src->iNodesCount; dest->iLastNodePlacedPosX = src->iLastNodePlacedPosX; } - static void chopAddTerrainNode(struct CTerrain *ter, int x, int y) { int i=0; - + if(ter->iNodesCount + 1 >= MAX_TERRAIN_NODES) { /* DEBUGF("ERROR: Not enough nodes!\n"); */ return; } - + ter->iNodesCount++; - + i = ter->iNodesCount - 1; - + ter->mNodes[i].x = x; ter->mNodes[i].y= y; - - ter->iLastNodePlacedPosX = x; - -} + ter->iLastNodePlacedPosX = x; + +} static void chopTerrainNodeDeleteAndShift(struct CTerrain *ter,int nodeIndex) { int i=nodeIndex; - + while( i < ter->iNodesCount ) { - ter->mNodes[i - 1] = ter->mNodes[i]; + ter->mNodes[i - 1] = ter->mNodes[i]; i++; } - + ter->iNodesCount--; - - + + } int chopUpdateTerrainRecycling(struct CTerrain *ter) @@ -270,28 +271,28 @@ int chopUpdateTerrainRecycling(struct CTerrain *ter) int iNewNodePos,g,v; while(i < ter->iNodesCount) { - + if( iCameraPosX > ter->mNodes[i].x) { chopTerrainNodeDeleteAndShift(ter,i); - + iNewNodePos = ter->iLastNodePlacedPosX + 50; g = iScreenY - 10; - + v = 3*iPlayerSpeedX; - if(v>50) + if(v>50) v=50; if(iLevelMode == LEVEL_MODE_STEEP) v*=5; - + chopAddTerrainNode(ter,iNewNodePos,g - iR(-v,v)); ret=1; - + } i++; - + } return 1; @@ -299,10 +300,10 @@ int chopUpdateTerrainRecycling(struct CTerrain *ter) int chopTerrainHeightAtPoint(struct CTerrain *ter, int pX) { - + int iNodeIndexOne=0,iNodeIndexTwo=0, h, terY1, terY2, terX1, terX2, a, b; float c,d; - + int i=0; for(i=1;imNodes[iNodeIndexOne].y; terY2 = ter->mNodes[iNodeIndexTwo].y; - + terX1 = 0; terX2 = ter->mNodes[iNodeIndexTwo].x - ter->mNodes[iNodeIndexOne].x; - + pX-= ter->mNodes[iNodeIndexOne].x; - + a = terY2 - terY1; b = terX2; c = pX; @@ -334,26 +335,24 @@ int chopTerrainHeightAtPoint(struct CTerrain *ter, int pX) } - int chopPointInTerrain(struct CTerrain *ter, int pX, int pY, int iTestType) { int h = chopTerrainHeightAtPoint(ter, pX); - + if(iTestType == 0) return (pY > h); else return (pY < h); } - static void chopAddBlock(int x,int y,int sx,int sy, int indexOverride) { int i=0; - + if(indexOverride < 0) { while(mBlocks[i].bIsActive && i < NUMBER_OF_BLOCKS) - i++; + i++; if(i==NUMBER_OF_BLOCKS) { DEBUGF("No blocks!\n"); @@ -362,20 +361,20 @@ static void chopAddBlock(int x,int y,int sx,int sy, int indexOverride) } else i = indexOverride; - + mBlocks[i].bIsActive = 1; mBlocks[i].iWorldX = x; mBlocks[i].iWorldY = y; mBlocks[i].iSizeX = sx; mBlocks[i].iSizeY = sy; - + iLastBlockPlacedPosX = x; } static void chopAddParticle(int x,int y,int sx,int sy) { int i=0; - + while(mParticles[i].bIsActive && i < NUMBER_OF_PARTICLES) i++; @@ -387,7 +386,7 @@ static void chopAddParticle(int x,int y,int sx,int sy) mParticles[i].iWorldY = y; mParticles[i].iSpeedX = sx; mParticles[i].iSpeedY = sy; - + } static void chopGenerateBlockIfNeeded(void) @@ -395,24 +394,24 @@ static void chopGenerateBlockIfNeeded(void) int i=0; int DistSpeedX = iPlayerSpeedX * 5; if(DistSpeedX<200) DistSpeedX = 200; - + while(i < NUMBER_OF_BLOCKS) { if(!mBlocks[i].bIsActive) { int iX,iY,sX,sY; - + iX = iLastBlockPlacedPosX + (350-DistSpeedX); sX = blockw; - + iY = iR(0,iScreenY); sY = blockh + iR(1,blockh/3); - + chopAddBlock(iX,iY,sX,sY,i); } - + i++; - } + } } @@ -420,13 +419,13 @@ static int chopBlockCollideWithPlayer(struct CBlock *mBlock) { int px = iPlayerPosX; int py = iPlayerPosY; - + int x = mBlock->iWorldX-17; int y = mBlock->iWorldY-11; int x2 = x + mBlock->iSizeX+17; int y2 = y + mBlock->iSizeY+11; - + if(px>x && pxy && pyiWorldX < iCameraPosX || mParticle->iWorldY < 0 || - mParticle->iWorldY > iScreenY || mParticle->iWorldX > iCameraPosX + + if (mParticle->iWorldX < iCameraPosX || mParticle->iWorldY < 0 || + mParticle->iWorldY > iScreenY || mParticle->iWorldX > iCameraPosX + iScreenX) { return 1; @@ -464,7 +463,7 @@ static void checkHighScore(void) char scoretext[30]; int w; highscore = score; - rb->snprintf(scoretext, sizeof(scoretext), "New High Score: %d", + rb->snprintf(scoretext, sizeof(scoretext), "New High Score: %d", highscore); rb->lcd_getstringsize(scoretext, &w, NULL); rb->lcd_putsxy(LCD_WIDTH/2 - w/2 ,LCD_HEIGHT/2 + 20, scoretext); @@ -476,30 +475,30 @@ static void chopKillPlayer(void) int w, i, button; for (i = 0; i < NUMBER_OF_PARTICLES; i++) { mParticles[i].bIsActive = 0; - chopAddParticle(iPlayerPosX + iR(0,20), iPlayerPosY + iR(0,20), + chopAddParticle(iPlayerPosX + iR(0,20), iPlayerPosY + iR(0,20), iR(-2,2), iR(-2,2)); } - + iPlayerAlive--; - + if (iPlayerAlive == 0) { rb->lcd_set_drawmode(DRMODE_FG); #if LCD_DEPTH >= 2 - rb->lcd_set_foreground(LCD_BLACK); + rb->lcd_set_foreground(LCD_WHITE); #endif checkHighScore(); - + rb->lcd_getstringsize("Game Over", &w, NULL); rb->lcd_putsxy(LCD_WIDTH/2 - w/2 ,LCD_HEIGHT/2 - 20, "Game Over"); - rb->lcd_getstringsize("Press action to continue", &w, NULL); - rb->lcd_putsxy(LCD_WIDTH/2 - w/2 ,LCD_HEIGHT/2, - "Press action to continue"); + rb->lcd_getstringsize("Press " ACTIONTEXT " to continue", &w, NULL); + rb->lcd_putsxy(LCD_WIDTH/2 - w/2 ,LCD_HEIGHT/2, + "Press " ACTIONTEXT " to continue"); rb->lcd_update(); - + rb->lcd_set_drawmode(DRMODE_SOLID); - + rb->sleep(HZ * 0.5); - + while (true) { button = rb->button_get(true); if (button == ACTION @@ -520,17 +519,16 @@ static void chopKillPlayer(void) } } } - - } else + + } else chopper_load(false); } - static void chopDrawTheWorld(void) { - int i=0; - + int i=0; + while(i < NUMBER_OF_BLOCKS) { if(mBlocks[i].bIsActive) @@ -540,12 +538,12 @@ static void chopDrawTheWorld(void) else chopDrawBlock(&mBlocks[i]); } - + i++; } i=0; - + while(i < NUMBER_OF_PARTICLES) { if(mParticles[i].bIsActive) @@ -555,27 +553,26 @@ static void chopDrawTheWorld(void) else chopDrawParticle(&mParticles[i]); } - + i++; } - + chopRenderTerrain(&mGround); chopRenderTerrain(&mRoof); } - static void chopDrawParticle(struct CParticle *mParticle) { - + int iPosX = (mParticle->iWorldX - iCameraPosX); int iPosY = (mParticle->iWorldY); #if LCD_DEPTH > 2 - rb->lcd_set_foreground(LCD_RGBPACK(150,150,150)); + rb->lcd_set_foreground(LCD_RGBPACK(192,192,192)); #elif LCD_DEPTH == 2 rb->lcd_set_foreground(LCD_LIGHTGRAY); #endif - rb->lcd_fillrect(iPosX, iPosY, 3, 3); + rb->lcd_fillrect(iPosX, iPosY, 3, 3); } @@ -584,7 +581,7 @@ static void chopDrawScene(void) char s[30]; int w; #if LCD_DEPTH > 2 - rb->lcd_set_background(LCD_RGBPACK(145,197,255)); + rb->lcd_set_background(LCD_BLACK); #elif LCD_DEPTH == 2 rb->lcd_set_background(LCD_WHITE); #endif @@ -592,11 +589,11 @@ static void chopDrawScene(void) chopDrawTheWorld(); chopDrawPlayer(iPlayerPosX - iCameraPosX, iPlayerPosY); - + score = -20 + iPlayerPosX/3; rb->lcd_set_drawmode(DRMODE_FG); #if LCD_DEPTH > 2 - rb->lcd_set_foreground(LCD_RGBPACK(20,20,20)); + rb->lcd_set_foreground(LCD_BLACK); #elif LCD_DEPTH == 2 rb->lcd_set_foreground(LCD_WHITE); #endif @@ -606,7 +603,7 @@ static void chopDrawScene(void) rb->lcd_getstringsize(s, &w, NULL); rb->lcd_putsxy(LCD_WIDTH - 2 - w, 2, s); rb->lcd_set_drawmode(DRMODE_SOLID); - + rb->lcd_update(); } @@ -616,23 +613,29 @@ static int chopMenu(int menunum) int result; int res = 0; bool menu_quit = false; - + static const struct menu_item items[] = { { "Start New Game", NULL }, { "Resume Game", NULL }, { "Level", NULL }, - { "Help", NULL }, { "Quit", NULL }, }; - + static const struct opt_items levels[2] = { { "Normal", -1 }, { "Steep", -1 }, }; - + +#if HAVE_LCD_COLOR + rb->lcd_set_foreground(LCD_WHITE); + rb->lcd_set_background(LCD_BLACK); +#endif + + rb->lcd_clear_display(); + m = rb->menu_init(items, sizeof(items) / sizeof(*items), NULL, NULL, NULL, NULL); - + while (!menu_quit) { result=rb->menu_show(m); switch (result) @@ -654,9 +657,6 @@ static int chopMenu(int menunum) rb->set_option("Level", &iLevelMode, INT, levels, 2, NULL); break; case 3: - rb->splash(HZ, true, "NOT AVAILABLE"); - break; - case 4: menu_quit=true; res = PLUGIN_OK; break; @@ -676,27 +676,27 @@ static int chopGameLoop(void) int move_button, ret; bool exit=false; int end, i=0, bdelay=0, last_button=BUTTON_NONE; - + if (chopUpdateTerrainRecycling(&mGround) == 1) /* mirror the sky if we've changed the ground */ - chopCopyTerrain(&mGround, &mRoof, 0, -( iScreenY * 0.75)); - + chopCopyTerrain(&mGround, &mRoof, 0, -( iScreenY * 0.75)); + ret = chopMenu(0); if (ret != -1) return PLUGIN_OK; - - chopDrawScene(); - + + chopDrawScene(); + while (!exit) { end = *rb->current_tick + (CYCLETIME * HZ) / 1000; - + if(chopUpdateTerrainRecycling(&mGround) == 1) /* mirror the sky if we've changed the ground */ - chopCopyTerrain(&mGround, &mRoof, 0, -( iScreenY * 0.75)); - + chopCopyTerrain(&mGround, &mRoof, 0, -( iScreenY * 0.75)); + iRotorOffset = iR(-1,1); - + /* We need to have this here so particles move when we're dead */ for (i=0; i < NUMBER_OF_PARTICLES; i++) @@ -707,21 +707,21 @@ static int chopGameLoop(void) } /* Redraw the main window: */ - chopDrawScene(); + chopDrawScene(); + - iGravityTimerCountdown--; - + if(iGravityTimerCountdown <= 0) { iGravityTimerCountdown = 3; chopAddParticle(iPlayerPosX, iPlayerPosY+5, 0, 0); } - + if(iLevelMode == LEVEL_MODE_NORMAL) chopGenerateBlockIfNeeded(); - + move_button=rb->button_status(); if (rb->button_get(false) == QUIT) { ret = chopMenu(1); @@ -756,13 +756,13 @@ static int chopGameLoop(void) bdelay = 3; if (bdelay == 0) iPlayerSpeedY = 4; - + if (rb->default_event_handler(move_button) == SYS_USB_CONNECTED) return PLUGIN_USB_CONNECTED; break; } last_button = move_button; - + if (bdelay < 0) { iPlayerSpeedY = bdelay; bdelay++; @@ -770,11 +770,11 @@ static int chopGameLoop(void) iPlayerSpeedY = bdelay; bdelay--; } - + iCameraPosX = iPlayerPosX - 25; iPlayerPosX += iPlayerSpeedX; iPlayerPosY += iPlayerSpeedY; - + chopCounter++; /* increase speed as we go along */ if (chopCounter == 100){ @@ -782,8 +782,8 @@ static int chopGameLoop(void) chopCounter=0; } - if (iPlayerPosY > iScreenY-10 || iPlayerPosY < -5 || - chopPointInTerrain(&mGround, iPlayerPosX, iPlayerPosY + 10, 0) || + if (iPlayerPosY > iScreenY-10 || iPlayerPosY < -5 || + chopPointInTerrain(&mGround, iPlayerPosX, iPlayerPosY + 10, 0) || chopPointInTerrain(&mRoof, iPlayerPosX ,iPlayerPosY, 1)) { chopKillPlayer(); @@ -792,7 +792,7 @@ static int chopGameLoop(void) if (ret != -1) return ret; } - + for (i=0; i < NUMBER_OF_BLOCKS; i++) if(mBlocks[i].bIsActive == 1) if(chopBlockCollideWithPlayer(&mBlocks[i])) { @@ -807,22 +807,22 @@ static int chopGameLoop(void) rb->sleep(end-*rb->current_tick); else rb->yield(); - + } return PLUGIN_OK; } static void chopDrawBlock(struct CBlock *mBlock) -{ +{ int iPosX = (mBlock->iWorldX - iCameraPosX); int iPosY = (mBlock->iWorldY); #if LCD_DEPTH > 2 - rb->lcd_set_foreground(LCD_RGBPACK(30,30,30)); + rb->lcd_set_foreground(LCD_RGBPACK(100,255,100)); #elif LCD_DEPTH == 2 rb->lcd_set_foreground(LCD_BLACK); #endif - rb->lcd_fillrect(iPosX, iPosY, mBlock->iSizeX, - mBlock->iSizeY); + rb->lcd_fillrect(iPosX, iPosY, mBlock->iSizeX, + mBlock->iSizeY); } @@ -834,21 +834,21 @@ static void chopRenderTerrain(struct CTerrain *ter) int oldx=0; int ay=0; - if(ter->mNodes[0].y < LCD_HEIGHT/2) + if(ter->mNodes[0].y < LCD_HEIGHT/2) ay=0; - else + else ay=LCD_HEIGHT; - + while(i < ter->iNodesCount && oldx < LCD_WIDTH) { - + int x = ter->mNodes[i-1].x - iCameraPosX; int y = ter->mNodes[i-1].y; - + int x2 = ter->mNodes[i].x - iCameraPosX; int y2 = ter->mNodes[i].y; #if LCD_DEPTH > 2 - rb->lcd_set_foreground(LCD_RGBPACK(50,100,250)); + rb->lcd_set_foreground(LCD_RGBPACK(100,255,100)); #elif LCD_DEPTH == 2 rb->lcd_set_foreground(LCD_DARKGRAY); #endif @@ -860,20 +860,20 @@ static void chopRenderTerrain(struct CTerrain *ter) xlcd_filltriangle(x, ay, x, y, x2, y2 / 2); else xlcd_filltriangle(x, ay, x, y, x2, LCD_HEIGHT - (LCD_HEIGHT - y2) / 2); - + oldx = x; i++; - + } } void chopper_load(bool newgame) { - + int i; int g; - + if (newgame) { iScreenX = LCD_WIDTH; iScreenY = LCD_HEIGHT; @@ -890,23 +890,23 @@ void chopper_load(bool newgame) chopCounter = 0; iPlayerSpeedX = 3; iPlayerSpeedY = 0; - iCameraPosX = 30; - + iCameraPosX = 30; + for (i=0; i < NUMBER_OF_PARTICLES; i++) mParticles[i].bIsActive = 0; - + for (i=0; i < NUMBER_OF_BLOCKS; i++) mBlocks[i].bIsActive = 0; - + g = iScreenY - 10; chopClearTerrain(&mGround); - + for (i=0; i < MAX_TERRAIN_NODES; i++) chopAddTerrainNode(&mGround,i * 30,g - iR(0,20)); if (chopUpdateTerrainRecycling(&mGround) == 1) /* mirror the sky if we've changed the ground */ - chopCopyTerrain(&mGround, &mRoof, 0, -( iScreenY * 0.75)); + chopCopyTerrain(&mGround, &mRoof, 0, -( iScreenY * 0.75)); iLevelMode = LEVEL_MODE_NORMAL; if (iLevelMode == LEVEL_MODE_NORMAL) @@ -922,6 +922,14 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) int ret; rb->lcd_setfont(FONT_SYSFIXED); +#if LCD_DEPTH > 1 + rb->lcd_set_backdrop(NULL); +#endif +#if HAVE_LCD_COLOR + rb->lcd_set_background(LCD_BLACK); + rb->lcd_set_foreground(LCD_WHITE); +#endif + /* Permanently enable the backlight (unless the user has turned it off) */ if (rb->global_settings->backlight_timeout > 0) rb->backlight_set_timeout(1); @@ -931,12 +939,12 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) xlcd_init(rb); configfile_init(rb); configfile_load(CFG_FILE, config, 1, 0); - + chopper_load(true); ret = chopGameLoop(); - + configfile_save(CFG_FILE, config, 1, 0); - + /* Restore user's original backlight setting */ rb->lcd_setfont(FONT_UI); rb->backlight_set_timeout(rb->global_settings->backlight_timeout);