Index: apps/plugins/CATEGORIES =================================================================== --- apps/plugins/CATEGORIES (Revision 22594) +++ apps/plugins/CATEGORIES (Arbeitskopie) @@ -78,6 +78,7 @@ settings_dumper,apps shortcuts_append,viewers shortcuts_view,viewers +skyrider,games sliding_puzzle,games snake,games snake2,games Index: apps/plugins/SOURCES =================================================================== --- apps/plugins/SOURCES (Revision 22594) +++ apps/plugins/SOURCES (Arbeitskopie) @@ -49,6 +49,7 @@ #ifdef HAVE_LCD_BITMAP /* Not for the Player */ rockblox1d.c brickmania.c +skyrider.c maze.c mazezam.c text_editor.c Index: apps/plugins/skyrider.c =================================================================== --- apps/plugins/skyrider.c (Revision 0) +++ apps/plugins/skyrider.c (Revision 0) @@ -0,0 +1,667 @@ +/*************************************************************************** +* __________ __ ___. +* Open \______ \ ____ ____ | | _\_ |__ _______ ___ +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +* \/ \/ \/ \/ \/ +* $Id:$ +* +* Copyright (C) 2009 Johannes Schwarz +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +* KIND, either express or implied. +* +****************************************************************************/ +#include "plugin.h" +#include "lib/helper.h" +#include "lib/highscore.h" +#include "lib/playback_control.h" +#include "lib/display_text.h" + +PLUGIN_HEADER + +#if (CONFIG_KEYPAD == SANSA_E200_PAD) +#define SKYRIDER_BUTTON_QUIT BUTTON_POWER +#define SKYRIDER_BUTTON_SCROLL_RIGHT BUTTON_SCROLL_FWD +#define SKYRIDER_BUTTON_SCROLL_LEFT BUTTON_SCROLL_BACK +#define SKYRIDER_BUTTON_LEFT BUTTON_LEFT +#define SKYRIDER_BUTTON_RIGHT BUTTON_RIGHT +#define SKYRIDER_BUTTON_JUMP BUTTON_SELECT + +#elif (CONFIG_KEYPAD == SANSA_FUZE_PAD) +#define SKYRIDER_BUTTON_QUIT (BUTTON_HOME|BUTTON_REPEAT) +#define SKYRIDER_BUTTON_SCROLL_RIGHT BUTTON_SCROLL_FWD +#define SKYRIDER_BUTTON_SCROLL_LEFT BUTTON_SCROLL_BACK +#define SKYRIDER_BUTTON_LEFT BUTTON_LEFT +#define SKYRIDER_BUTTON_RIGHT BUTTON_RIGHT +#define SKYRIDER_BUTTON_JUMP BUTTON_SELECT + +#elif (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \ + (CONFIG_KEYPAD == SANSA_C200_PAD) +#define SKYRIDER_BUTTON_QUIT BUTTON_POWER +#define SKYRIDER_BUTTON_LEFT BUTTON_LEFT +#define SKYRIDER_BUTTON_RIGHT BUTTON_RIGHT +#define SKYRIDER_BUTTON_JUMP BUTTON_SELECT + +#elif (CONFIG_KEYPAD == IPOD_4G_PAD) +#define SKYRIDER_BUTTON_QUIT BUTTON_MENU +#define SKYRIDER_BUTTON_SCROLL_RIGHT BUTTON_SCROLL_FWD +#define SKYRIDER_BUTTON_SCROLL_LEFT BUTTON_SCROLL_BACK +#define SKYRIDER_BUTTON_JUMP BUTTON_SELECT +#define SKYRIDER_BUTTON_RIGHT BUTTON_RIGHT +#define SKYRIDER_BUTTON_LEFT BUTTON_LEFT + +#elif (CONFIG_KEYPAD == GIGABEAT_PAD) +#define SKYRIDER_BUTTON_QUIT BUTTON_POWER +#define SKYRIDER_BUTTON_LEFT BUTTON_LEFT +#define SKYRIDER_BUTTON_RIGHT BUTTON_RIGHT +#define SKYRIDER_BUTTON_JUMP BUTTON_SELECT + +#elif (CONFIG_KEYPAD == GIGABEAT_S_PAD) +#define SKYRIDER_BUTTON_QUIT BUTTON_BACK +#define SKYRIDER_BUTTON_LEFT BUTTON_LEFT +#define SKYRIDER_BUTTON_RIGHT BUTTON_RIGHT +#define SKYRIDER_BUTTON_JUMP BUTTON_SELECT + +#elif (CONFIG_KEYPAD == IRIVER_H10_PAD) +#define SKYRIDER_BUTTON_QUIT BUTTON_POWER +#define SKYRIDER_BUTTON_LEFT BUTTON_LEFT +#define SKYRIDER_BUTTON_RIGHT BUTTON_RIGHT +#define SKYRIDER_BUTTON_JUMP BUTTON_PLAY + +#elif CONFIG_KEYPAD == IAUDIO67_PAD +#define SKYRIDER_BUTTON_QUIT BUTTON_POWER +#define SKYRIDER_BUTTON_LEFT BUTTON_LEFT +#define SKYRIDER_BUTTON_RIGHT BUTTON_RIGHT +#define SKYRIDER_BUTTON_JUMP BUTTON_PLAY + +#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD +#define SKYRIDER_BUTTON_QUIT BUTTON_POWER +#define SKYRIDER_BUTTON_LEFT BUTTON_LEFT +#define SKYRIDER_BUTTON_RIGHT BUTTON_RIGHT +#define SKYRIDER_BUTTON_JUMP BUTTON_SELECT + +#elif (CONFIG_KEYPAD == IRIVER_H300_PAD) +#define SKYRIDER_BUTTON_QUIT BUTTON_OFF +#define SKYRIDER_BUTTON_LEFT BUTTON_LEFT +#define SKYRIDER_BUTTON_RIGHT BUTTON_RIGHT +#define SKYRIDER_BUTTON_JUMP BUTTON_SELECT + +#elif CONFIG_KEYPAD == CREATIVEZVM_PAD +#define SKYRIDER_BUTTON_QUIT BUTTON_BACK +#define SKYRIDER_BUTTON_LEFT BUTTON_LEFT +#define SKYRIDER_BUTTON_RIGHT BUTTON_RIGHT +#define SKYRIDER_BUTTON_JUMP BUTTON_SELECT + +#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD +#define SKYRIDER_BUTTON_QUIT BUTTON_POWER +#define SKYRIDER_BUTTON_LEFT BUTTON_LEFT +#define SKYRIDER_BUTTON_RIGHT BUTTON_RIGHT +#define SKYRIDER_BUTTON_JUMP BUTTON_SELECT + +#elif CONFIG_KEYPAD == COWOND2_PAD +#define SKYRIDER_BUTTON_QUIT BUTTON_POWER + +#elif (CONFIG_KEYPAD == ONDAVX747_PAD) +#define SKYRIDER_BUTTON_QUIT BUTTON_POWER +#define SKYRIDER_BUTTON_JUMP BUTTON_MENU + +#elif (CONFIG_KEYPAD == MROBE500_PAD) +#define SKYRIDER_BUTTON_QUIT BUTTON_POWER + +#else +#error "no keymap" +#endif + +#ifdef HAVE_TOUCHSCREEN +#ifndef SKYRIDER_BUTTON_LEFT +#define SKYRIDER_BUTTON_LEFT BUTTON_MIDLEFT +#endif +#ifndef SKYRIDER_BUTTON_RIGHT +#define SKYRIDER_BUTTON_RIGHT BUTTON_MIDRIGHT +#endif +#ifndef SKYRIDER_BUTTON_JUMP +#define SKYRIDER_BUTTON_JUMP BUTTON_CENTER +#endif +#endif + +#define HIGHSCORE_FILE PLUGIN_GAMES_DIR "/skyrider.score" +#define NUM_SCORES 5 +struct highscore highest[NUM_SCORES]; + + +#define CYCLETIME 10 /* time (in ms) for one iteration through the game loop */ +#define FLOORS 7 + +/* #if !(LCD_WIDTH % 11) +#define SECTIONS 11 */ + +#if !(LCD_WIDTH % 10) +#define SECTIONS 10 + +#elif !(LCD_WIDTH % 8) +#define SECTIONS 8 +#endif + +#if LCD_WIDTH >= 300 +#define SPEED 70 +#elif LCD_WIDTH >= 200 +#define SPEED 60 +#elif LCD_WIDTH >= 100 +#define SPEED 50 +#endif + +#define FLOOR_WIDTH LCD_WIDTH/SECTIONS + + +#if LCD_HEIGHT >= 400 +#define FLOOR_HEIGHT 24 +#define PLAYER_HEIGHT 32 +#define PLAYER_WIDTH 16 +#define MOVE_Y 4 +#define MOVE_X 3 + +/* (iPod Video) */ +#elif LCD_HEIGHT >= 320 +#define FLOOR_HEIGHT 16 +#define PLAYER_HEIGHT 24 +#define PLAYER_WIDTH 16 +#define MOVE_Y 3 +#define MOVE_X 2 + +#elif LCD_HEIGHT >= 240 +#define FLOOR_HEIGHT 12 +#define PLAYER_HEIGHT 21 +#define PLAYER_WIDTH 15 +#define MOVE_Y 3 +#define MOVE_X 2 + +/* (Sansa E200) */ +#elif LCD_HEIGHT >= 220 +#define FLOOR_HEIGHT 12 +#define PLAYER_HEIGHT 20 +#define PLAYER_WIDTH 14 +#define MOVE_Y 2 +#define MOVE_X 1 + +/* (Sansa Fuze) */ +#elif LCD_HEIGHT >= 176 +#define FLOOR_HEIGHT 10 +#define PLAYER_HEIGHT 18 +#define PLAYER_WIDTH 10 +#define MOVE_Y 2 +#define MOVE_X 1 + +/* (iPod Nano) */ +#elif LCD_HEIGHT >= 132 +#define FLOOR_HEIGHT 8 +#define PLAYER_HEIGHT 16 +#define PLAYER_WIDTH 12 +#define MOVE_Y 2 +#define MOVE_X 1 + +#elif LCD_HEIGHT >= 128 +#define FLOOR_HEIGHT 6 +#define PLAYER_HEIGHT 12 +#define PLAYER_WIDTH 8 +#define MOVE_Y 2 +#define MOVE_X 1 + +/* (Sansa C200) */ +#elif LCD_HEIGHT >= 80 +#define FLOOR_HEIGHT 5 +#define PLAYER_HEIGHT 9 +#define PLAYER_WIDTH 6 +#define MOVE_Y 2 +#define MOVE_X 1 + +#endif + +#define FLOOR_SPACING 2*FLOOR_HEIGHT +#define FLOOR_DISTANCE 3*FLOOR_HEIGHT + +#define MARGIN 5 + +enum { RIGHT, LEFT }; + +/* the main status of the player */ +enum player_status { + FALL, + RUN, + JUMP +}; + +struct skyrider_game { + unsigned int floor; + short level; + int score; + short speed; + bool scroll; +}; + +struct skyrider_player { + int direction; + int xpos; + int ypos; + int y_movement; + short speed; +}; + +struct skyrider_levels { + short y_floor; /* y position of the floor */ + short x_floor[SECTIONS]; + bool refresh; +}; + +static struct skyrider_game game; +static struct skyrider_player player; +static struct skyrider_levels levels[FLOORS]; + +static enum player_status player_status; + +static void skyrider_create_floors(void) +{ + int initial_block; + int i; + int k; + for (k=0;krand() % (SECTIONS-2)) + 1; + i = initial_block; + levels[k].x_floor[i]= true; + for (i=initial_block+1;irand() % 2) { + levels[k].x_floor[i]= true; + } else { + while (i < SECTIONS) { + levels[k].x_floor[i]= false; + i++; + } + break; + } + } + for (i=initial_block-1;i>=0;i--) { + if (rb->rand() % 2) { + levels[k].x_floor[i]= true; + } else { + while (i >= 0) { + levels[k].x_floor[i]= false; + i--; + } + break; + } + } + } + } else { + levels[k].y_floor+=MOVE_Y; + if (levels[k].y_floor > LCD_HEIGHT && !levels[k+1].refresh) + levels[k].refresh = true; + } + } +} + +/* readout the array of the struct levels and if need be draw the floor */ +static void skyrider_draw_floors(void) +{ + rb->lcd_set_foreground(LCD_RGBPACK(200,10,45)); + int k,l; + for (k=0;klcd_fillrect(l*FLOOR_WIDTH,levels[k].y_floor,FLOOR_WIDTH, + FLOOR_HEIGHT); + } + } + rb->lcd_set_foreground(LCD_WHITE); +} + +/* check wether the player stands on a block */ +static enum player_status skyrider_player_falling(void) +{ + int k, l; + for (k=FLOORS-1;k>=0;k--) { + if (player.ypos+PLAYER_HEIGHT == levels[k].y_floor) { + for (l=0;l= l*FLOOR_WIDTH && + player.xpos+PLAYER_WIDTH/2 <= l*FLOOR_WIDTH+FLOOR_WIDTH) { + return RUN; + } + } + } + } + } + return FALL; +} + +static void skyrider_draw_player(void) +{ + rb->lcd_fillrect(player.xpos, player.ypos, PLAYER_WIDTH, PLAYER_HEIGHT); +} + +/* create the first floor */ +static void skyrider_init_floors(void) +{ + int i; + for (i=0;ilcd_clear_display(); + rb->lcd_set_background(LCD_RGBPACK(0,0,255)); + + skyrider_init_floors(); +} + +static int skyrider_calculate_jump_high(void) +{ + return ((SPEED+10) / 10 * FLOOR_DISTANCE - player.speed / 10 * FLOOR_DISTANCE); +} + +static int skyrider_help(void) +{ +#define WORDS (sizeof help_text / sizeof (char*)) + static char *help_text[] = { + "Skyrider", "", "Aim", "", + "Climp", "the", "tower", "as", "high", "as", "possible", "with", + "your", "character." + }; + static struct style_text formation[]={ + { 0, TEXT_CENTER|TEXT_UNDERLINE }, + { 2, C_RED }, + { -1, 0 } + }; + int button; + + rb->lcd_setfont(FONT_UI); +#ifdef HAVE_LCD_COLOR + rb->lcd_set_background(LCD_BLACK); + rb->lcd_set_foreground(LCD_WHITE); +#endif + if (display_text(WORDS, help_text, formation, NULL)) + return true; + do { + button = rb->button_get(true); + if ( rb->default_event_handler( button ) == SYS_USB_CONNECTED ) + return true; + } while( ( button == BUTTON_NONE ) + || ( button & (BUTTON_REL|BUTTON_REPEAT) ) ); + rb->lcd_setfont(FONT_SYSFIXED); + return 0; +} + +static bool _ingame; +static int skyrider_menu_cb(int action, const struct menu_item_ex *this_item) +{ + if(action == ACTION_REQUEST_MENUITEM + && !_ingame && ((intptr_t)this_item)==0) + return ACTION_EXIT_MENUITEM; + return action; +} + +static int skyrider_menu(bool ingame) +{ + rb->button_clear_queue(); + int choice = 0; + + _ingame = ingame; + + MENUITEM_STRINGLIST (main_menu, "skyrider Menu", skyrider_menu_cb, + "Resume Game", + "Start New Game", + "Help", + "High Score", + "Playback Control", + "Quit"); + + while (true) { + switch (rb->do_menu(&main_menu, &choice, NULL, false)) { + case 0: + return 0; + case 1: + skyrider_init(); + return 0; + case 2: + if (skyrider_help()) + return 1; + break; + case 3: + highscore_show(NUM_SCORES, highest, NUM_SCORES,true); + break; + case 4: + playback_control(NULL); + break; + case 5: + case MENU_ATTACHED_USB: + return 1; + default: + break; + } + } +} + +static int skyrider_game_loop(void) +{ + int button, button_right, button_left; + int end; + int jump_high = 0; + int delay_player = 0, delay_board = 0; + int position; + + if (skyrider_menu(false)==1) + return 1; + + rb->srand( *rb->current_tick ); + + int w, h; + char *title = "Score:"; + char str[10]; + + while(true) { + end = *rb->current_tick + (CYCLETIME * HZ) / 1000; + + if ((delay_board >= game.speed && game.scroll) || + (delay_player >= player.speed)) { + + rb->lcd_clear_display(); + skyrider_draw_floors(); + skyrider_draw_player(); + + /* calculate score */ + if (player_status == RUN && player.y_movement) { + game.score += 10*(player.y_movement/(FLOOR_DISTANCE)); + player.y_movement = 0; + } + + rb->lcd_getstringsize(title, &w, &h); + rb->lcd_putsxy(MARGIN, LCD_HEIGHT-MARGIN-h, title); + rb->snprintf(str, 6, "%d", game.score); + rb->lcd_putsxy(2*MARGIN + w, LCD_HEIGHT-MARGIN-h, str); + + rb->lcd_update(); + + /* if the player threatens to jump out of the screen, + * set scrolling speed to maximum */ + if (player.ypos < FLOOR_SPACING) { + game.speed = 1; + game.scroll = true; + } else { + game.speed = 12-game.level; + } + + /* check wether the player fall out of the screen */ + if (player.ypos > LCD_HEIGHT) { + rb->splash(HZ*2, "Game Over!"); + rb->lcd_clear_display(); + position=highscore_update(game.score, game.level, "", + highest, NUM_SCORES); + if (position == 0) + rb->splash(HZ*2, "New High Score"); + if (position != -1) + highscore_show(position, highest, NUM_SCORES, true); + if (skyrider_menu(false)==1) + return 1; + } + } + + button=rb->button_status(); + + if (button & SKYRIDER_BUTTON_QUIT) { + if (skyrider_menu(true)==1) + return 1; + } + + /* the screens scroll downwards */ + if (delay_board >= game.speed && game.scroll) { + delay_board = 0; + skyrider_create_floors(); + player.ypos+=MOVE_Y; + } + + /* the player can move */ + if (delay_player >= player.speed) { + delay_player = 0; + +#ifdef SKYRIDER_BUTTON_SCROLL_RIGHT + button_right = (button & SKYRIDER_BUTTON_RIGHT || \ + button & SKYRIDER_BUTTON_SCROLL_RIGHT); +#else + button_right = (button & SKYRIDER_BUTTON_RIGHT); +#endif +#ifdef SKYRIDER_BUTTON_SCROLL_LEFT + button_left = (button & SKYRIDER_BUTTON_LEFT || \ + button & SKYRIDER_BUTTON_SCROLL_LEFT); +#else + button_left = (button & SKYRIDER_BUTTON_LEFT); +#endif + /* set player speed to slow, if player doesn't run on floor */ + if (!button && player_status == RUN) + player.speed = SPEED; + + + if (button_right) { + if (player.xpos + MOVE_X <=LCD_WIDTH-PLAYER_WIDTH) { + if (player_status == RUN) { + if (player.direction != RIGHT) { + player.speed = SPEED; + } else { + if (player.speed > 1) + player.speed-=1; + } + } + player.xpos+=MOVE_X; + } else { + player.xpos=LCD_WIDTH-PLAYER_WIDTH; + if (player_status == RUN || player.speed == SPEED) + player.speed = SPEED; + } + player.direction = RIGHT; + } + + if (button_left) { + if (player.xpos - MOVE_X >= 0) { + if (player_status == RUN) { + if (player.direction != LEFT) { + player.speed = SPEED; + } else { + if (player.speed > 1) + player.speed-=1; + } + } + player.xpos-=MOVE_X; + } else { + player.xpos = 0; + if (player_status == RUN) + player.speed = SPEED; + } + player.direction = LEFT; + } + + if (button & SKYRIDER_BUTTON_JUMP && player_status == RUN) { + player_status = JUMP; + jump_high = skyrider_calculate_jump_high(); + } + + if (player_status == FALL) { + player.ypos+=MOVE_Y; + player.y_movement-=MOVE_Y; + player_status = skyrider_player_falling(); + + } else if (player_status == JUMP) { + player.ypos-=MOVE_Y; + player.y_movement+=MOVE_Y; + jump_high-=MOVE_Y; + if (jump_high < 0) + player_status = FALL; + } else { + player_status = skyrider_player_falling(); + } + + } + if (end > *rb->current_tick) { + rb->sleep(end-*rb->current_tick); + } else { + rb->yield(); + } + delay_player+=(SPEED/MARGIN); + delay_board++; + } + return 0; +} + +enum plugin_status plugin_start(const void* parameter) +{ + (void)parameter; + + rb->lcd_set_backdrop(NULL); + rb->lcd_setfont(FONT_SYSFIXED); + rb->lcd_set_foreground(LCD_WHITE); + rb->lcd_set_background(LCD_BLACK); + backlight_force_on(); + highscore_load(HIGHSCORE_FILE, highest, NUM_SCORES); + + skyrider_game_loop(); + + highscore_save(HIGHSCORE_FILE, highest, NUM_SCORES); + backlight_use_settings(); + rb->lcd_setfont(FONT_UI); + return PLUGIN_OK; +}