1
0
Fork 0
forked from len0rd/rockbox

Adapted Wormlet to all other models with bitmap LCDs - fullscreen on all of them - with colors where possible. Untested on all models except Recorder and iPod 5G; might be a bit buggy.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9020 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Zakk Roberts 2006-03-13 03:13:05 +00:00
parent 7a10c08af4
commit c091a77381
2 changed files with 266 additions and 149 deletions

View file

@ -32,6 +32,8 @@ plasma.c
bejeweled.c bejeweled.c
bounce.c bounce.c
wormlet.c
#if (LCD_WIDTH != 138) && (LCD_WIDTH != 128) #if (LCD_WIDTH != 138) && (LCD_WIDTH != 128)
/* These need adjusting for the Mini's and iRiver if'p screen */ /* These need adjusting for the Mini's and iRiver if'p screen */
brickmania.c brickmania.c
@ -59,9 +61,6 @@ sudoku.c
video.c video.c
#endif #endif
vu_meter.c vu_meter.c
#if CONFIG_KEYPAD == RECORDER_PAD /* Recorder models only for now */
wormlet.c
#endif
#ifdef CONFIG_RTC #ifdef CONFIG_RTC
clock.c clock.c

View file

@ -18,8 +18,6 @@
****************************************************************************/ ****************************************************************************/
#include "plugin.h" #include "plugin.h"
#if defined(HAVE_LCD_BITMAP) && (CONFIG_KEYPAD == RECORDER_PAD)
PLUGIN_HEADER PLUGIN_HEADER
/* size of the field the worm lives in */ /* size of the field the worm lives in */
@ -46,13 +44,100 @@ PLUGIN_HEADER
when a new argh is made */ when a new argh is made */
#define MIN_ARGH_DIST 5 #define MIN_ARGH_DIST 5
#if (CONFIG_KEYPAD == RECORDER_PAD)
#define BTN_DIR_UP BUTTON_UP
#define BTN_DIR_DOWN BUTTON_DOWN
#define BTN_DIR_LEFT BUTTON_LEFT
#define BTN_DIR_RIGHT BUTTON_RIGHT
#define BTN_PLAYER2_DIR1 BUTTON_F2
#define BTN_PLAYER2_DIR2 BUTTON_F3
#define BTN_RC_UP BUTTON_RC_VOL_UP
#define BTN_RC_DOWN BUTTON_RC_VOL_DOWN
#define BTN_STARTPAUSE BUTTON_PLAY
#define BTN_QUIT BUTTON_OFF
#define BTN_STOPRESET BUTTON_ON
#define BTN_TOGGLE_KEYS BUTTON_F1
#define REMOTE
#define MULTIPLAYER
#define PLAYERS_TEXT "UP/DN"
#define WORMS_TEXT "L/R"
#define KEY_CONTROL_TEXT "F1"
#elif (CONFIG_KEYPAD == ONDIO_PAD)
#define BTN_DIR_UP BUTTON_UP
#define BTN_DIR_DOWN BUTTON_DOWN
#define BTN_DIR_LEFT BUTTON_LEFT
#define BTN_DIR_RIGHT BUTTON_RIGHT
#define BTN_STARTPAUSE (BUTTON_MODE|BUTTON_REL)
#define BTN_QUIT (BUTTON_ONOFF|BUTTON_REL)
#define BTN_STOPRESET (BUTTON_ONOFF|BUTTON_MODE)
#define PLAYERS_TEXT "UP/DN"
#define WORMS_TEXT "L/R"
#elif (CONFIG_KEYPAD == IPOD_4G_PAD)
#define BTN_DIR_UP BUTTON_MENU
#define BTN_DIR_DOWN BUTTON_PLAY
#define BTN_DIR_LEFT BUTTON_LEFT
#define BTN_DIR_RIGHT BUTTON_RIGHT
#define BTN_STARTPAUSE (BUTTON_SELECT|BUTTON_REL)
#define BTN_QUIT (BUTTON_SELECT|BUTTON_MENU)
#define BTN_STOPRESET (BUTTON_SELECT|BUTTON_PLAY)
#define PLAYERS_TEXT "Menu/Play"
#define WORMS_TEXT "Left/Right"
#elif (CONFIG_KEYPAD == IRIVER_H300_PAD) ||
(CONFIG_KEYPAD == IRIVER_H100_PAD)
#define BTN_DIR_UP BUTTON_UP
#define BTN_DIR_DOWN BUTTON_DOWN
#define BTN_DIR_LEFT BUTTON_LEFT
#define BTN_DIR_RIGHT BUTTON_RIGHT
#define BTN_STARTPAUSE (BUTTON_SELECT|BUTTON_REL)
#define BTN_QUIT BUTTON_OFF
#define BTN_STOPRESET BUTTON_ON
#define PLAYERS_TEXT "Up/Down"
#define WORMS_TEXT "Left/Right"
#endif
#if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
#define FOOD_SIZE 3
#define ARGH_SIZE 4
#define SPEED 14
#elif (LCD_WIDTH == 160) && (LCD_HEIGHT == 128)
#define FOOD_SIZE 4
#define ARGH_SIZE 5
#define SPEED 8
#elif (LCD_WIDTH == 176) && (LCD_HEIGHT == 132)
#define COLOR_LCD
#define FOOD_SIZE 4
#define ARGH_SIZE 5
#define SPEED 6
#elif (LCD_WIDTH == 220) && (LCD_HEIGHT == 176)
#define COLOR_LCD
#define FOOD_SIZE 5
#define ARGH_SIZE 6
#define SPEED 4
#elif (LCD_WIDTH == 320) && (LCD_HEIGHT == 240)
#define COLOR_LCD
#define FOOD_SIZE 7
#define ARGH_SIZE 8
#define SPEED 4
#endif
/** /**
* All the properties that a worm has. * All the properties that a worm has.
*/ */
static struct worm { static struct worm {
/* The worm is stored in a ring of xy coordinates */ /* The worm is stored in a ring of xy coordinates */
char x[MAX_WORM_SEGMENTS]; int x[MAX_WORM_SEGMENTS];
char y[MAX_WORM_SEGMENTS]; int y[MAX_WORM_SEGMENTS];
int head; /* index of the head within the buffer */ int head; /* index of the head within the buffer */
int tail; /* index of the tail within the buffer */ int tail; /* index of the tail within the buffer */
@ -75,14 +160,12 @@ static struct worm {
static int highscore; static int highscore;
#define MAX_FOOD 5 /* maximal number of food items */ #define MAX_FOOD 5 /* maximal number of food items */
#define FOOD_SIZE 3 /* the width and height of a food */
/* The arrays store the food coordinates */ /* The arrays store the food coordinates */
static char foodx[MAX_FOOD]; static char foodx[MAX_FOOD];
static char foody[MAX_FOOD]; static char foody[MAX_FOOD];
#define MAX_ARGH 100 /* maximal number of argh items */ #define MAX_ARGH 100 /* maximal number of argh items */
#define ARGH_SIZE 4 /* the width and height of a argh */
#define ARGHS_PER_FOOD 2 /* number of arghs produced per eaten food */ #define ARGHS_PER_FOOD 2 /* number of arghs produced per eaten food */
/* The arrays store the argh coordinates */ /* The arrays store the argh coordinates */
@ -97,9 +180,6 @@ static int argh_count;
static char debugout[15]; static char debugout[15];
#endif #endif
/* the number of ticks each game cycle should take */
#define SPEED 14
/* the number of active worms (dead or alive) */ /* the number of active worms (dead or alive) */
static int worm_count = MAX_WORMS; static int worm_count = MAX_WORMS;
@ -553,6 +633,9 @@ static void clear_food(int index)
static void draw_food(int index) static void draw_food(int index)
{ {
/* draw the food object */ /* draw the food object */
#ifdef COLOR_LCD
rb->lcd_set_foreground(LCD_RGBPACK(0, 150, 0));
#endif
rb->lcd_fillrect(foodx[index] + FIELD_RECT_X, rb->lcd_fillrect(foodx[index] + FIELD_RECT_X,
foody[index] + FIELD_RECT_Y, foody[index] + FIELD_RECT_Y,
FOOD_SIZE, FOOD_SIZE); FOOD_SIZE, FOOD_SIZE);
@ -561,6 +644,9 @@ static void draw_food(int index)
foody[index] + FIELD_RECT_Y + 1, foody[index] + FIELD_RECT_Y + 1,
FOOD_SIZE - 2, FOOD_SIZE - 2); FOOD_SIZE - 2, FOOD_SIZE - 2);
rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_set_drawmode(DRMODE_SOLID);
#ifdef COLOR_LCD
rb->lcd_set_foreground(LCD_RGBPACK(0, 0, 0));
#endif
} }
/** /**
@ -623,9 +709,15 @@ static int make_argh(int index)
static void draw_argh(int index) static void draw_argh(int index)
{ {
/* draw the new argh */ /* draw the new argh */
#ifdef COLOR_LCD
rb->lcd_set_foreground(LCD_RGBPACK(175, 0, 0));
#endif
rb->lcd_fillrect(arghx[index] + FIELD_RECT_X, rb->lcd_fillrect(arghx[index] + FIELD_RECT_X,
arghy[index] + FIELD_RECT_Y, arghy[index] + FIELD_RECT_Y,
ARGH_SIZE, ARGH_SIZE); ARGH_SIZE, ARGH_SIZE);
#ifdef COLOR_LCD
rb->lcd_set_foreground(LCD_RGBPACK(0, 0, 0));
#endif
} }
static void virtual_player(struct worm *w); static void virtual_player(struct worm *w);
@ -735,7 +827,7 @@ static void init_wormlet(void)
worms[2].fetch_worm_direction = human_player2; worms[2].fetch_worm_direction = human_player2;
} }
/* Needed when the game is restarted using BUTTON_ON */ /* Needed when the game is restarted using BTN_STOPRESET */
rb->lcd_clear_display(); rb->lcd_clear_display();
/* make and display some food and argh */ /* make and display some food and argh */
@ -842,6 +934,9 @@ static void move_worm(struct worm *w)
*/ */
static void draw_worm(struct worm *w) static void draw_worm(struct worm *w)
{ {
#ifdef COLOR_LCD
rb->lcd_set_foreground(LCD_RGBPACK(80, 40, 0));
#endif
/* draw the new head */ /* draw the new head */
int x = w->x[w->head]; int x = w->x[w->head];
int y = w->y[w->head]; int y = w->y[w->head];
@ -858,6 +953,9 @@ static void draw_worm(struct worm *w)
rb->lcd_drawpixel(x + FIELD_RECT_X, y + FIELD_RECT_Y); rb->lcd_drawpixel(x + FIELD_RECT_X, y + FIELD_RECT_Y);
} }
rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_set_drawmode(DRMODE_SOLID);
#ifdef COLOR_LCD
rb->lcd_set_foreground(LCD_RGBPACK(0, 0, 0));
#endif
} }
/** /**
@ -1306,24 +1404,24 @@ static bool run(void)
cycle_start = *rb->current_tick; cycle_start = *rb->current_tick;
/* change the direction of the worm */ /* change the direction of the worm */
while (button != BUTTON_OFF && ! wormDead) while (button != BTN_QUIT && ! wormDead)
{ {
int i; int i;
long cycle_duration ; long cycle_duration ;
switch (button) { switch (button) {
case BUTTON_UP: case BTN_DIR_UP:
if (players == 1 && !use_remote) { if (players == 1 && !use_remote) {
player1_dir = NORTH; player1_dir = NORTH;
} }
break; break;
case BUTTON_DOWN: case BTN_DIR_DOWN:
if (players == 1 && !use_remote) { if (players == 1 && !use_remote) {
player1_dir = SOUTH; player1_dir = SOUTH;
} }
break; break;
case BUTTON_LEFT: case BTN_DIR_LEFT:
if (players != 1 || use_remote) { if (players != 1 || use_remote) {
player1_dir = (player1_dir + 3) % 4; player1_dir = (player1_dir + 3) % 4;
} else { } else {
@ -1331,7 +1429,7 @@ static bool run(void)
} }
break; break;
case BUTTON_RIGHT: case BTN_DIR_RIGHT:
if (players != 1 || use_remote) { if (players != 1 || use_remote) {
player1_dir = (player1_dir + 1) % 4; player1_dir = (player1_dir + 1) % 4;
} else { } else {
@ -1339,28 +1437,32 @@ static bool run(void)
} }
break; break;
case BUTTON_F2: #ifdef MULTIPLAYER
case BTN_PLAYER2_DIR1:
player2_dir = (player2_dir + 3) % 4; player2_dir = (player2_dir + 3) % 4;
break; break;
case BUTTON_F3: case BTN_PLAYER2_DIR2:
player2_dir = (player2_dir + 1) % 4; player2_dir = (player2_dir + 1) % 4;
break; break;
#endif
case BUTTON_RC_VOL_UP: #ifdef REMOTE
case BTN_RC_UP:
player3_dir = (player3_dir + 1) % 4; player3_dir = (player3_dir + 1) % 4;
break; break;
case BUTTON_RC_VOL_DOWN: case BTN_RC_DOWN:
player3_dir = (player3_dir + 3) % 4; player3_dir = (player3_dir + 3) % 4;
break; break;
#endif
case BUTTON_PLAY: case BTN_STARTPAUSE:
do { do {
button = rb->button_get(true); button = rb->button_get(true);
} while (button != BUTTON_PLAY && } while (button != BTN_STARTPAUSE &&
button != BUTTON_OFF && button != BTN_QUIT &&
button != BUTTON_ON); button != BTN_STOPRESET);
break; break;
} }
@ -1377,7 +1479,7 @@ static bool run(void)
} }
score_board(); score_board();
rb->lcd_update(); rb->lcd_update();
if (button == BUTTON_ON) { if (button == BTN_STOPRESET) {
wormDead = true; wormDead = true;
} }
@ -1478,7 +1580,6 @@ static void test_worm_food_collision(void) {
} }
static bool expensive_worm_in_rect(struct worm *w, int rx, int ry, int rw, int rh){ static bool expensive_worm_in_rect(struct worm *w, int rx, int ry, int rw, int rh){
int x, y; int x, y;
bool retVal = false; bool retVal = false;
@ -1898,6 +1999,10 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
rb = api; rb = api;
rb->lcd_setfont(FONT_SYSFIXED); rb->lcd_setfont(FONT_SYSFIXED);
#ifdef COLOR_LCD
rb->lcd_set_background(LCD_RGBPACK(200, 210, 230));
#endif
#ifdef DEBUG_WORMLET #ifdef DEBUG_WORMLET
testline_in_rect(); testline_in_rect();
test_worm_argh_collision_in_moves(); test_worm_argh_collision_in_moves();
@ -1909,43 +2014,61 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
/* Setup screen */ /* Setup screen */
do { do {
char buf[20]; char buf[40];
char* ptr; char* ptr;
rb->lcd_clear_display(); rb->lcd_clear_display();
/* first line players */ /* first line players */
rb->snprintf(buf, sizeof buf, "%d Players UP/DN", players); #ifdef MULTIPLAYER
rb->snprintf(buf, sizeof buf, "%d Players (%s)", players, PLAYERS_TEXT);
#else
rb->snprintf(buf, sizeof buf, "1 Player");
#endif
rb->lcd_puts(0, 0, buf); rb->lcd_puts(0, 0, buf);
/* second line worms */ /* second line worms */
rb->snprintf(buf, sizeof buf, "%d Worms L/R", worm_count); rb->snprintf(buf, sizeof buf, "%d Worms (%s)", worm_count, WORMS_TEXT);
rb->lcd_puts(0, 1, buf); rb->lcd_puts(0, 1, buf);
#if defined MULTIPLAYER && defined REMOTE
/* third line control */ /* third line control */
if (players > 1) { if (players > 1) {
if (use_remote) { if (use_remote) {
ptr = "Remote Control F1"; rb->snprintf(buf, sizeof(buf), "Remote Control (%s)", KEY_CONTROL_TEXT);
ptr = buf;
} else { } else {
ptr = "No Rem. Control F1"; rb->snprintf(buf, sizeof(buf), "No Rem. Control (%s)", KEY_CONTROL_TEXT);
ptr = buf;
} }
} else { } else {
if (players > 0) { if (players > 0) {
if (use_remote) { if (use_remote) {
ptr = "2 Key Control F1"; rb->snprintf(buf, sizeof(buf), "2 Key Control (%s)", KEY_CONTROL_TEXT);
ptr = buf;
} else { } else {
ptr = "4 Key Control F1"; rb->snprintf(buf, sizeof(buf), "4 Key Control (%s)", KEY_CONTROL_TEXT);
ptr = buf;
} }
} else { } else {
ptr = "Out Of Control"; ptr = "Out Of Control";
} }
} }
rb->lcd_puts(0, 2, ptr); rb->lcd_puts(0, 2, ptr);
#endif
rb->lcd_update(); rb->lcd_update();
/* user selection */ /* user selection */
button = rb->button_get(true); button = rb->button_get(true);
switch (button) { switch (button) {
case BUTTON_UP: #ifdef MULTIPLAYER
case BTN_TOGGLE_KEYS:
use_remote = !use_remote;
if (players > 2) {
use_remote = true;
}
break;
case BTN_DIR_UP:
if (players < 3) { if (players < 3) {
players ++; players ++;
if (players > worm_count) { if (players > worm_count) {
@ -1956,12 +2079,14 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
} }
} }
break; break;
case BUTTON_DOWN:
case BTN_DIR_DOWN:
if (players > 0) { if (players > 0) {
players --; players --;
} }
break; break;
case BUTTON_LEFT: #endif
case BTN_DIR_LEFT:
if (worm_count > 1) { if (worm_count > 1) {
worm_count--; worm_count--;
if (worm_count < players) { if (worm_count < players) {
@ -1969,25 +2094,20 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
} }
} }
break; break;
case BUTTON_RIGHT:
case BTN_DIR_RIGHT:
if (worm_count < MAX_WORMS) { if (worm_count < MAX_WORMS) {
worm_count ++; worm_count ++;
} }
break; break;
case BUTTON_F1:
use_remote = !use_remote;
if (players > 2) {
use_remote = true;
}
break;
default: default:
if (rb->default_event_handler(button) == SYS_USB_CONNECTED) if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
return PLUGIN_USB_CONNECTED; return PLUGIN_USB_CONNECTED;
break; break;
} }
} while (button != BUTTON_PLAY && } while (button != BTN_STARTPAUSE &&
button != BUTTON_OFF && button != BUTTON_ON); button != BTN_QUIT && button != BTN_STOPRESET);
rb->lcd_clear_display(); rb->lcd_clear_display();
/* end of setup */ /* end of setup */
@ -1996,29 +2116,27 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
/* button state will be overridden if /* button state will be overridden if
the game quits with the death of the worm. the game quits with the death of the worm.
Initializing button to BUTTON_OFF ensures Initializing button to BTN_QUIT ensures
that the user can hit BUTTON_OFF during the that the user can hit BTN_QUIT during the
game to return to the menu. game to return to the menu.
*/ */
button = BUTTON_OFF; button = BTN_QUIT;
/* start the game */ /* start the game */
worm_dead = run(); worm_dead = run();
/* if worm isn't dead the game was quit /* if worm isn't dead the game was quit
via BUTTON_OFF -> no need to wait for buttons. */ via BTN_QUIT -> no need to wait for buttons. */
if (worm_dead) { if (worm_dead) {
do { do {
button = rb->button_get(true); button = rb->button_get(true);
} }
/* BUTTON_ON -> start new game */ /* BTN_STOPRESET -> start new game */
/* BUTTON_OFF -> back to game menu */ /* BTN_QUIT -> back to game menu */
while (button != BUTTON_OFF && button != BUTTON_ON); while (button != BTN_QUIT && button != BTN_STOPRESET);
} }
} }
while (button != BUTTON_OFF); while (button != BTN_QUIT);
return PLUGIN_OK; return PLUGIN_OK;
} }
#endif