Index: apps/plugins/CATEGORIES =================================================================== --- apps/plugins/CATEGORIES (Revision 22312) +++ apps/plugins/CATEGORIES (Arbeitskopie) @@ -29,6 +29,7 @@ goban,games greyscale,demos helloworld,demos +icytower,games invadrox,games iriver_flash,apps iriverify,viewers Index: apps/plugins/icytower.c =================================================================== --- apps/plugins/icytower.c (Revision 0) +++ apps/plugins/icytower.c (Revision 0) @@ -0,0 +1,605 @@ +/*************************************************************************** +* __________ __ ___. +* 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 ICYTOWER_BUTTON_QUIT BUTTON_POWER +#define ICYTOWER_BUTTON_SCROLL_RIGHT BUTTON_SCROLL_FWD +#define ICYTOWER_BUTTON_SCROLL_LEFT BUTTON_SCROLL_BACK +#define ICYTOWER_BUTTON_LEFT BUTTON_LEFT +#define ICYTOWER_BUTTON_RIGHT BUTTON_RIGHT +#define ICYTOWER_BUTTON_JUMP BUTTON_SELECT + +#elif (CONFIG_KEYPAD == SANSA_FUZE_PAD) +#define ICYTOWER_BUTTON_QUIT (BUTTON_HOME|BUTTON_REPEAT) +#define ICYTOWER_BUTTON_SCROLL_RIGHT BUTTON_SCROLL_FWD +#define ICYTOWER_BUTTON_SCROLL_LEFT BUTTON_SCROLL_BACK +#define ICYTOWER_BUTTON_LEFT BUTTON_LEFT +#define ICYTOWER_BUTTON_RIGHT BUTTON_RIGHT +#define ICYTOWER_BUTTON_JUMP BUTTON_SELECT + +#elif CONFIG_KEYPAD == SANSA_CLIP_PAD +#define ICYTOWER_BUTTON_QUIT BUTTON_POWER +#define ICYTOWER_BUTTON_LEFT BUTTON_LEFT +#define ICYTOWER_BUTTON_RIGHT BUTTON_RIGHT +#define ICYTOWER_BUTTON_JUMP BUTTON_SELECT + +#elif (CONFIG_KEYPAD == SANSA_C200_PAD) +#define ICYTOWER_BUTTON_QUIT BUTTON_POWER +#define ICYTOWER_BUTTON_LEFT BUTTON_LEFT +#define ICYTOWER_BUTTON_RIGHT BUTTON_RIGHT +#define ICYTOWER_BUTTON_JUMP BUTTON_SELECT + +#elif (CONFIG_KEYPAD == IPOD_4G_PAD) +#define ICYTOWER_BUTTON_QUIT BUTTON_MENU +#define ICYTOWER_BUTTON_JUMP BUTTON_SELECT +#define ICYTOWER_BUTTON_RIGHT BUTTON_RIGHT +#define ICYTOWER_BUTTON_LEFT BUTTON_LEFT + +#elif (CONFIG_KEYPAD == GIGABEAT_PAD) +#define ICYTOWER_BUTTON_QUIT BUTTON_POWER +#define ICYTOWER_BUTTON_LEFT BUTTON_LEFT +#define ICYTOWER_BUTTON_RIGHT BUTTON_RIGHT +#define ICYTOWER_BUTTON_JUMP BUTTON_SELECT + +#elif (CONFIG_KEYPAD == GIGABEAT_S_PAD) +#define ICYTOWER_BUTTON_QUIT BUTTON_BACK +#define ICYTOWER_BUTTON_LEFT BUTTON_LEFT +#define ICYTOWER_BUTTON_RIGHT BUTTON_RIGHT +#define ICYTOWER_BUTTON_JUMP BUTTON_SELECT + +#elif (CONFIG_KEYPAD == IRIVER_H10_PAD) +#define ICYTOWER_BUTTON_QUIT BUTTON_POWER +#define ICYTOWER_BUTTON_LEFT BUTTON_LEFT +#define ICYTOWER_BUTTON_RIGHT BUTTON_RIGHT +#define ICYTOWER_BUTTON_JUMP BUTTON_PLAY + +#elif CONFIG_KEYPAD == IAUDIO67_PAD +#define ICYTOWER_BUTTON_QUIT BUTTON_POWER +#define ICYTOWER_BUTTON_LEFT BUTTON_LEFT +#define ICYTOWER_BUTTON_RIGHT BUTTON_RIGHT +#define ICYTOWER_BUTTON_JUMP BUTTON_PLAY + +#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD +#define ICYTOWER_BUTTON_QUIT BUTTON_POWER +#define ICYTOWER_BUTTON_LEFT BUTTON_LEFT +#define ICYTOWER_BUTTON_RIGHT BUTTON_RIGHT +#define ICYTOWER_BUTTON_JUMP BUTTON_SELECT + +#elif (CONFIG_KEYPAD == IRIVER_H300_PAD) +#define ICYTOWER_BUTTON_QUIT BUTTON_OFF +#define ICYTOWER_BUTTON_LEFT BUTTON_LEFT +#define ICYTOWER_BUTTON_RIGHT BUTTON_RIGHT +#define ICYTOWER_BUTTON_JUMP BUTTON_SELECT + +#elif CONFIG_KEYPAD == CREATIVEZVM_PAD +#define ICYTOWER_BUTTON_QUIT BUTTON_BACK +#define ICYTOWER_BUTTON_LEFT BUTTON_LEFT +#define ICYTOWER_BUTTON_RIGHT BUTTON_RIGHT +#define ICYTOWER_BUTTON_JUMP BUTTON_SELECT + +#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD +#define ICYTOWER_BUTTON_QUIT BUTTON_POWER +#define ICYTOWER_BUTTON_LEFT BUTTON_LEFT +#define ICYTOWER_BUTTON_RIGHT BUTTON_RIGHT +#define ICYTOWER_BUTTON_JUMP BUTTON_SELECT + +#elif CONFIG_KEYPAD == COWOND2_PAD +#define ICYTOWER_BUTTON_QUIT BUTTON_POWER + +#elif (CONFIG_KEYPAD == ONDAVX747_PAD) +#define ICYTOWER_BUTTON_QUIT BUTTON_POWER +#define ICYTOWER_BUTTON_JUMP BUTTON_MENU + +#elif (CONFIG_KEYPAD == MROBE500_PAD) +#define ICYTOWER_BUTTON_QUIT BUTTON_POWER + +#else +#error "no keymap" +#endif + +#ifdef HAVE_TOUCHSCREEN +#ifndef ICYTOWER_BUTTON_LEFT +#define ICYTOWER_BUTTON_LEFT BUTTON_MIDLEFT +#endif +#ifndef ICYTOWER_BUTTON_RIGHT +#define ICYTOWER_BUTTON_RIGHT BUTTON_MIDRIGHT +#endif +#ifndef ICYTOWER_BUTTON_JUMP +#define ICYTOWER_BUTTON_JUMP BUTTON_CENTER +#endif +#endif + +#define HIGHSCORE_FILE PLUGIN_GAMES_DIR "/icytower.score" +#define NUM_SCORES 5 +struct highscore highest[NUM_SCORES]; + +#define PLAYER_HEIGHT 18 +#define PLAYER_WIDTH 10 + +#define CYCLETIME 10 +#define FLOORS 7 + +#if !(LCD_WIDTH % 11) +#define SECTIONS 11 + +#elif !(LCD_WIDTH % 10) +#define SECTIONS 10 + +#elif !(LCD_WIDTH % 8) +#define SECTIONS 8 +#endif + +#define FLOOR_WIDTH LCD_WIDTH/SECTIONS +#define MOVE 1 + +#if (LCD_HEIGHT>= 300) +#define FLOOR_HEIGHT 18 + +#elif (LCD_HEIGHT>= 250) +#define FLOOR_HEIGHT 15 + +#elif (LCD_HEIGHT>= 200) +#define FLOOR_HEIGHT 12 + +#elif (LCD_HEIGHT>= 150) +#define FLOOR_HEIGHT 9 + +#elif (LCD_HEIGHT<= 100) +#define FLOOR_HEIGHT 6 +#endif + +#define FLOOR_SPACING 2*FLOOR_HEIGHT +#define FLOOR_DISTANCE 3*FLOOR_HEIGHT + +#define MARGIN 5 + +enum { RIGHT, LEFT }; + +enum player_status { + FALL, + RUN, + JUMP +}; + +struct icytower_game { + unsigned int floor; + short level; + int score; + int speed; +}; + +struct icytower_player { + int direction; + int xpos; + int tmp_ypos; + int tmp; + int ypos; + int speed; +}; + +struct icytower_levels { + int y_floor; + int x_floor[SECTIONS]; + bool refresh; +}; + +static struct icytower_game game; +static struct icytower_player player; +static struct icytower_levels levels[FLOORS]; + +static enum player_status player_status; + +static void icytower_init_floors(void) +{ + int i; + for (i=0;irand() % SECTIONS; + 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++; + if (levels[k].y_floor > LCD_HEIGHT && !levels[k+1].refresh) + levels[k].refresh = true; + } + } +} + +static void icytower_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 icytower_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 icytower_draw_player(void) +{ + rb->lcd_fillrect(player.xpos, player.ypos, PLAYER_WIDTH, PLAYER_HEIGHT); +} + +static void icytower_init(void) +{ + player.xpos = LCD_WIDTH/2-PLAYER_WIDTH; + player.ypos = LCD_HEIGHT-3*FLOOR_HEIGHT-PLAYER_HEIGHT; + player.tmp_ypos = 0; + player.speed = 50; + player_status = RUN; + + game.floor=0; + game.level=1; + game.score = 0; + rb->lcd_clear_display(); + rb->lcd_set_background(LCD_RGBPACK(0,0,255)); + + icytower_init_floors(); +} + +static int icytower_calculate_jump_high(void) +{ + if (player.speed > 16) + return FLOOR_DISTANCE+MARGIN; + else if (player.speed > 12) + return 2*FLOOR_DISTANCE+MARGIN; + else if (player.speed > 8) + return 3*FLOOR_DISTANCE+MARGIN; + else if (player.speed > 4) + return 4*FLOOR_DISTANCE+MARGIN; + else + return 5*FLOOR_DISTANCE+MARGIN; +} + +static int icytower_help(void) +{ +#define WORDS (sizeof help_text / sizeof (char*)) + static char *help_text[] = { + "Icytower", "", "Aim", "", + "Climb", "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 icytower_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 icytower_menu(bool ingame) +{ + rb->button_clear_queue(); + int choice = 0; + + _ingame = ingame; + + MENUITEM_STRINGLIST (main_menu, "Icytower Menu", icytower_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: + icytower_init(); + return 0; + case 2: + if (icytower_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 icytower_game_loop(void) +{ + int button, button_right, button_left; + int end; + int jump_high; + int delay_player = 0, delay_board = 0; + int position; + + if (icytower_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; + + rb->lcd_clear_display(); + icytower_draw_floors(); + icytower_draw_player(); + + if (player_status == RUN && player.tmp_ypos) { + game.score += 10*(player.tmp_ypos/(FLOOR_DISTANCE)); + player.tmp_ypos = 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 (player.ypos < FLOOR_SPACING) { + game.speed = 1; + } else { + game.speed = 12-game.level; + } + + 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 (icytower_menu(false)==1) + return 1; + } + + button=rb->button_status(); + + if (button & ICYTOWER_BUTTON_QUIT) { + if (icytower_menu(true)==1) + return 1; + } + + if (delay_board >= game.speed) { + delay_board = 0; + icytower_create_floors(); + player.ypos+=1; + } + + if (delay_player >= player.speed) { + delay_player = 0; + +#ifdef ICYTOWER_BUTTON_SCROLL_RIGHT + button_right = (button & ICYTOWER_BUTTON_RIGHT || + button & ICYTOWER_BUTTON_SCROLL_RIGHT); +#else + button_right = (button & ICYTOWER_BUTTON_RIGHT); +#endif +#ifdef ICYTOWER_BUTTON_SCROLL_LEFT + button_left = (button & ICYTOWER_BUTTON_LEFT || + button & ICYTOWER_BUTTON_SCROLL_LEFT); +#else + button_left = (button & ICYTOWER_BUTTON_LEFT); +#endif + if (!button && player_status == RUN) + player.speed = 50; + + + if (button_right) { + if (player.xpos + MOVE <=LCD_WIDTH-PLAYER_WIDTH) { + if (player_status == RUN) { + if (player.direction != RIGHT) { + player.speed = 50; + } else { + if (player.speed > 1) + player.speed-=1; + } + } + player.xpos+=MOVE; + } else { + player.xpos=LCD_WIDTH-PLAYER_WIDTH; + } + player.direction = RIGHT; + } + + if (button_left) { + if (player.xpos - MOVE >= 0) { + if (player_status == RUN) { + if (player.direction != LEFT) { + player.speed = 50; + } else { + if (player.speed > 1) + player.speed-=1; + } + } + player.xpos-=MOVE; + } else { + player.xpos = 0; + } + player.direction = LEFT; + } + + if (button & ICYTOWER_BUTTON_JUMP && player_status == RUN) { + player_status = JUMP; + jump_high = icytower_calculate_jump_high(); + } + + if (player_status == FALL) { + player.ypos+=1; + player.tmp_ypos-=1; + player_status = icytower_player_falling(); + + } else if (player_status == JUMP) { + player.ypos-=1; + player.tmp_ypos+=1; + jump_high--; + if (jump_high < 0) + player_status = FALL; + } else { + player_status = icytower_player_falling(); + } + + } + if (end > *rb->current_tick) { + rb->sleep(end-*rb->current_tick); + } else { + rb->yield(); + } + delay_player+=10; + 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); + + icytower_game_loop(); + + highscore_save(HIGHSCORE_FILE, highest, NUM_SCORES); + backlight_use_settings(); + rb->lcd_setfont(FONT_UI); + return PLUGIN_OK; +} Index: apps/plugins/SOURCES =================================================================== --- apps/plugins/SOURCES (Revision 22312) +++ apps/plugins/SOURCES (Arbeitskopie) @@ -49,6 +49,7 @@ #ifdef HAVE_LCD_BITMAP /* Not for the Player */ rockblox1d.c brickmania.c +icytower.c maze.c mazezam.c text_editor.c