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:
parent
7a10c08af4
commit
c091a77381
2 changed files with 266 additions and 149 deletions
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
@ -28,31 +26,118 @@ PLUGIN_HEADER
|
||||||
#define FIELD_RECT_WIDTH (LCD_WIDTH - 45)
|
#define FIELD_RECT_WIDTH (LCD_WIDTH - 45)
|
||||||
#define FIELD_RECT_HEIGHT (LCD_HEIGHT - 2)
|
#define FIELD_RECT_HEIGHT (LCD_HEIGHT - 2)
|
||||||
|
|
||||||
/* size of the ring of the worm
|
/* size of the ring of the worm
|
||||||
choos a value that is a power of 2 to help
|
choos a value that is a power of 2 to help
|
||||||
the compiler optimize modul operations*/
|
the compiler optimize modul operations*/
|
||||||
#define MAX_WORM_SEGMENTS 64
|
#define MAX_WORM_SEGMENTS 64
|
||||||
|
|
||||||
/* when the game starts */
|
/* when the game starts */
|
||||||
#define INITIAL_WORM_LENGTH 10
|
#define INITIAL_WORM_LENGTH 10
|
||||||
|
|
||||||
/* num of pixel the worm grows per eaten food */
|
/* num of pixel the worm grows per eaten food */
|
||||||
#define WORM_PER_FOOD 7
|
#define WORM_PER_FOOD 7
|
||||||
|
|
||||||
/* num of worms creeping in the FIELD */
|
/* num of worms creeping in the FIELD */
|
||||||
#define MAX_WORMS 3
|
#define MAX_WORMS 3
|
||||||
|
|
||||||
/* minimal distance between a worm and an argh
|
/* minimal distance between a worm and an argh
|
||||||
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 */
|
||||||
|
@ -65,8 +150,8 @@ static struct worm {
|
||||||
|
|
||||||
/* this method is used to fetch the direction the user
|
/* this method is used to fetch the direction the user
|
||||||
has selected. It can be one of the values
|
has selected. It can be one of the values
|
||||||
human_player1, human_player2, remote_player, virtual_player.
|
human_player1, human_player2, remote_player, virtual_player.
|
||||||
All these values are fuctions, that can change the direction
|
All these values are fuctions, that can change the direction
|
||||||
of the worm */
|
of the worm */
|
||||||
void (*fetch_worm_direction)(struct worm *w);
|
void (*fetch_worm_direction)(struct worm *w);
|
||||||
} worms[MAX_WORMS];
|
} worms[MAX_WORMS];
|
||||||
|
@ -74,22 +159,20 @@ static struct worm {
|
||||||
/* stores the highscore - besides it was scored by a virtual player */
|
/* stores the highscore - besides it was scored by a virtual player */
|
||||||
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 */
|
||||||
static char arghx[MAX_ARGH];
|
static char arghx[MAX_ARGH];
|
||||||
static char arghy[MAX_ARGH];
|
static char arghy[MAX_ARGH];
|
||||||
|
|
||||||
/* the number of arghs that are currently in use */
|
/* the number of arghs that are currently in use */
|
||||||
static int argh_count;
|
static int argh_count;
|
||||||
|
|
||||||
#ifdef DEBUG_WORMLET
|
#ifdef DEBUG_WORMLET
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -124,9 +204,9 @@ static bool use_remote = false;
|
||||||
#define SOUTH 3
|
#define SOUTH 3
|
||||||
|
|
||||||
/* direction of human player 1 */
|
/* direction of human player 1 */
|
||||||
static int player1_dir = EAST;
|
static int player1_dir = EAST;
|
||||||
/* direction of human player 2 */
|
/* direction of human player 2 */
|
||||||
static int player2_dir = EAST;
|
static int player2_dir = EAST;
|
||||||
/* direction of human player 3 */
|
/* direction of human player 3 */
|
||||||
static int player3_dir = EAST;
|
static int player3_dir = EAST;
|
||||||
|
|
||||||
|
@ -146,7 +226,7 @@ static void set_debug_out(char *str){
|
||||||
/**
|
/**
|
||||||
* Returns the direction id in which the worm
|
* Returns the direction id in which the worm
|
||||||
* currently is creeping.
|
* currently is creeping.
|
||||||
* @param struct worm *w The worm that is to be investigated.
|
* @param struct worm *w The worm that is to be investigated.
|
||||||
* w Must not be null.
|
* w Must not be null.
|
||||||
* @return int A value 0 <= value < 4
|
* @return int A value 0 <= value < 4
|
||||||
* Note the predefined constants NORTH, SOUTH, EAST, WEST
|
* Note the predefined constants NORTH, SOUTH, EAST, WEST
|
||||||
|
@ -175,7 +255,7 @@ static int get_worm_dir(struct worm *w) {
|
||||||
* to right by 90 degree.
|
* to right by 90 degree.
|
||||||
* @param struct worm *w The worm that is to be altered. w Must not be null.
|
* @param struct worm *w The worm that is to be altered. w Must not be null.
|
||||||
* @param int dir The new direction in which the worm is to creep.
|
* @param int dir The new direction in which the worm is to creep.
|
||||||
* dir must be 0 <= dir < 4. Use predefined constants
|
* dir must be 0 <= dir < 4. Use predefined constants
|
||||||
* NORTH, SOUTH, EAST, WEST
|
* NORTH, SOUTH, EAST, WEST
|
||||||
*/
|
*/
|
||||||
static void set_worm_dir(struct worm *w, int dir) {
|
static void set_worm_dir(struct worm *w, int dir) {
|
||||||
|
@ -255,7 +335,7 @@ static int get_score(struct worm *w) {
|
||||||
/**
|
/**
|
||||||
* Determines wether the line specified by startx, starty, endx, endy intersects
|
* Determines wether the line specified by startx, starty, endx, endy intersects
|
||||||
* the rectangle specified by x, y, width, height. Note that the line must be exactly
|
* the rectangle specified by x, y, width, height. Note that the line must be exactly
|
||||||
* horizontal or vertical (startx == endx or starty == endy).
|
* horizontal or vertical (startx == endx or starty == endy).
|
||||||
* @param int startx The x coordinate of the start point of the line.
|
* @param int startx The x coordinate of the start point of the line.
|
||||||
* @param int starty The y coordinate of the start point of the line.
|
* @param int starty The y coordinate of the start point of the line.
|
||||||
* @param int endx The x coordinate of the end point of the line.
|
* @param int endx The x coordinate of the end point of the line.
|
||||||
|
@ -305,7 +385,7 @@ static bool line_in_rect(int startx, int starty, int endx, int endy, int x, int
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests wether the specified worm intersects with the rect.
|
* Tests wether the specified worm intersects with the rect.
|
||||||
* @param struct worm *w The worm to be investigated
|
* @param struct worm *w The worm to be investigated
|
||||||
* @param int x The x coordinate of the top left corner of the rect
|
* @param int x The x coordinate of the top left corner of the rect
|
||||||
|
@ -433,7 +513,7 @@ static bool worm_food_collision(struct worm *w, int foodIndex)
|
||||||
{
|
{
|
||||||
bool retVal = false;
|
bool retVal = false;
|
||||||
|
|
||||||
retVal = worm_in_rect(w, foodx[foodIndex], foody[foodIndex],
|
retVal = worm_in_rect(w, foodx[foodIndex], foody[foodIndex],
|
||||||
FOOD_SIZE - 1, FOOD_SIZE - 1);
|
FOOD_SIZE - 1, FOOD_SIZE - 1);
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
|
@ -443,7 +523,7 @@ static bool worm_food_collision(struct worm *w, int foodIndex)
|
||||||
* Returns true if the worm hits the argh within the next moves (unless
|
* Returns true if the worm hits the argh within the next moves (unless
|
||||||
* the worm changes it's direction).
|
* the worm changes it's direction).
|
||||||
* @param struct worm *w - The worm to investigate
|
* @param struct worm *w - The worm to investigate
|
||||||
* @param int argh_idx - The index of the argh
|
* @param int argh_idx - The index of the argh
|
||||||
* @param int moves - The number of moves that are considered.
|
* @param int moves - The number of moves that are considered.
|
||||||
* @return Returns false if the specified argh is not hit within the next
|
* @return Returns false if the specified argh is not hit within the next
|
||||||
* moves.
|
* moves.
|
||||||
|
@ -457,7 +537,7 @@ static bool worm_argh_collision_in_moves(struct worm *w, int argh_idx, int moves
|
||||||
x2 = w->x[w->head] + moves * w->dirx;
|
x2 = w->x[w->head] + moves * w->dirx;
|
||||||
y2 = w->y[w->head] + moves * w->diry;
|
y2 = w->y[w->head] + moves * w->diry;
|
||||||
|
|
||||||
retVal = line_in_rect(x1, y1, x2, y2, arghx[argh_idx], arghy[argh_idx],
|
retVal = line_in_rect(x1, y1, x2, y2, arghx[argh_idx], arghy[argh_idx],
|
||||||
ARGH_SIZE, ARGH_SIZE);
|
ARGH_SIZE, ARGH_SIZE);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
@ -472,7 +552,7 @@ static bool worm_argh_collision(struct worm *w, int arghIndex)
|
||||||
{
|
{
|
||||||
bool retVal = false;
|
bool retVal = false;
|
||||||
|
|
||||||
retVal = worm_in_rect(w, arghx[arghIndex], arghy[arghIndex],
|
retVal = worm_in_rect(w, arghx[arghIndex], arghy[arghIndex],
|
||||||
ARGH_SIZE - 1, ARGH_SIZE - 1);
|
ARGH_SIZE - 1, ARGH_SIZE - 1);
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
|
@ -481,7 +561,7 @@ static bool worm_argh_collision(struct worm *w, int arghIndex)
|
||||||
/**
|
/**
|
||||||
* Find new coordinates for the food stored in foodx[index], foody[index]
|
* Find new coordinates for the food stored in foodx[index], foody[index]
|
||||||
* that don't collide with any other food or argh
|
* that don't collide with any other food or argh
|
||||||
* @param int index
|
* @param int index
|
||||||
* Ensure that 0 <= index < MAX_FOOD.
|
* Ensure that 0 <= index < MAX_FOOD.
|
||||||
*/
|
*/
|
||||||
static int make_food(int index) {
|
static int make_food(int index) {
|
||||||
|
@ -504,12 +584,12 @@ static int make_food(int index) {
|
||||||
If one or more corners of the new food hit any existing
|
If one or more corners of the new food hit any existing
|
||||||
argh or food a collision is detected.
|
argh or food a collision is detected.
|
||||||
*/
|
*/
|
||||||
collisionDetected =
|
collisionDetected =
|
||||||
food_collision(x , y ) >= 0 ||
|
food_collision(x , y ) >= 0 ||
|
||||||
food_collision(x , y + FOOD_SIZE - 1) >= 0 ||
|
food_collision(x , y + FOOD_SIZE - 1) >= 0 ||
|
||||||
food_collision(x + FOOD_SIZE - 1, y ) >= 0 ||
|
food_collision(x + FOOD_SIZE - 1, y ) >= 0 ||
|
||||||
food_collision(x + FOOD_SIZE - 1, y + FOOD_SIZE - 1) >= 0 ||
|
food_collision(x + FOOD_SIZE - 1, y + FOOD_SIZE - 1) >= 0 ||
|
||||||
argh_collision(x , y ) >= 0 ||
|
argh_collision(x , y ) >= 0 ||
|
||||||
argh_collision(x , y + FOOD_SIZE - 1) >= 0 ||
|
argh_collision(x , y + FOOD_SIZE - 1) >= 0 ||
|
||||||
argh_collision(x + FOOD_SIZE - 1, y ) >= 0 ||
|
argh_collision(x + FOOD_SIZE - 1, y ) >= 0 ||
|
||||||
argh_collision(x + FOOD_SIZE - 1, y + FOOD_SIZE - 1) >= 0;
|
argh_collision(x + FOOD_SIZE - 1, y + FOOD_SIZE - 1) >= 0;
|
||||||
|
@ -531,7 +611,7 @@ static int make_food(int index) {
|
||||||
/**
|
/**
|
||||||
* Clears a food from the lcd buffer.
|
* Clears a food from the lcd buffer.
|
||||||
* @param int index The index of the food arrays under which
|
* @param int index The index of the food arrays under which
|
||||||
* the coordinates of the desired food can be found. Ensure
|
* the coordinates of the desired food can be found. Ensure
|
||||||
* that the value is 0 <= index <= MAX_FOOD.
|
* that the value is 0 <= index <= MAX_FOOD.
|
||||||
*/
|
*/
|
||||||
static void clear_food(int index)
|
static void clear_food(int index)
|
||||||
|
@ -547,13 +627,16 @@ static void clear_food(int index)
|
||||||
/**
|
/**
|
||||||
* Draws a food in the lcd buffer.
|
* Draws a food in the lcd buffer.
|
||||||
* @param int index The index of the food arrays under which
|
* @param int index The index of the food arrays under which
|
||||||
* the coordinates of the desired food can be found. Ensure
|
* the coordinates of the desired food can be found. Ensure
|
||||||
* that the value is 0 <= index <= MAX_FOOD.
|
* that the value is 0 <= index <= MAX_FOOD.
|
||||||
*/
|
*/
|
||||||
static void draw_food(int index)
|
static void draw_food(int index)
|
||||||
{
|
{
|
||||||
/* draw the food object */
|
/* draw the food object */
|
||||||
rb->lcd_fillrect(foodx[index] + FIELD_RECT_X,
|
#ifdef COLOR_LCD
|
||||||
|
rb->lcd_set_foreground(LCD_RGBPACK(0, 150, 0));
|
||||||
|
#endif
|
||||||
|
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);
|
||||||
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
|
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
|
||||||
|
@ -561,18 +644,21 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find new coordinates for the argh stored in arghx[index], arghy[index]
|
* Find new coordinates for the argh stored in arghx[index], arghy[index]
|
||||||
* that don't collide with any other food or argh.
|
* that don't collide with any other food or argh.
|
||||||
* @param int index
|
* @param int index
|
||||||
* Ensure that 0 <= index < argh_count < MAX_ARGH.
|
* Ensure that 0 <= index < argh_count < MAX_ARGH.
|
||||||
*/
|
*/
|
||||||
static int make_argh(int index)
|
static int make_argh(int index)
|
||||||
{
|
{
|
||||||
int x = -1;
|
int x = -1;
|
||||||
int y = -1;
|
int y = -1;
|
||||||
bool collisionDetected = false;
|
bool collisionDetected = false;
|
||||||
int tries = 0;
|
int tries = 0;
|
||||||
int i;
|
int i;
|
||||||
|
@ -589,12 +675,12 @@ static int make_argh(int index)
|
||||||
If one or more corners of the new argh hit any existing
|
If one or more corners of the new argh hit any existing
|
||||||
argh or food an intersection is detected.
|
argh or food an intersection is detected.
|
||||||
*/
|
*/
|
||||||
collisionDetected =
|
collisionDetected =
|
||||||
food_collision(x , y ) >= 0 ||
|
food_collision(x , y ) >= 0 ||
|
||||||
food_collision(x , y + ARGH_SIZE - 1) >= 0 ||
|
food_collision(x , y + ARGH_SIZE - 1) >= 0 ||
|
||||||
food_collision(x + ARGH_SIZE - 1, y ) >= 0 ||
|
food_collision(x + ARGH_SIZE - 1, y ) >= 0 ||
|
||||||
food_collision(x + ARGH_SIZE - 1, y + ARGH_SIZE - 1) >= 0 ||
|
food_collision(x + ARGH_SIZE - 1, y + ARGH_SIZE - 1) >= 0 ||
|
||||||
argh_collision(x , y ) >= 0 ||
|
argh_collision(x , y ) >= 0 ||
|
||||||
argh_collision(x , y + ARGH_SIZE - 1) >= 0 ||
|
argh_collision(x , y + ARGH_SIZE - 1) >= 0 ||
|
||||||
argh_collision(x + ARGH_SIZE - 1, y ) >= 0 ||
|
argh_collision(x + ARGH_SIZE - 1, y ) >= 0 ||
|
||||||
argh_collision(x + ARGH_SIZE - 1, y + ARGH_SIZE - 1) >= 0;
|
argh_collision(x + ARGH_SIZE - 1, y + ARGH_SIZE - 1) >= 0;
|
||||||
|
@ -606,7 +692,7 @@ static int make_argh(int index)
|
||||||
/* now test wether we accidently hit the worm with argh ;) */
|
/* now test wether we accidently hit the worm with argh ;) */
|
||||||
for (i = 0; i < worm_count && !collisionDetected; i++) {
|
for (i = 0; i < worm_count && !collisionDetected; i++) {
|
||||||
collisionDetected |= worm_argh_collision(&worms[i], index);
|
collisionDetected |= worm_argh_collision(&worms[i], index);
|
||||||
collisionDetected |= worm_argh_collision_in_moves(&worms[i], index,
|
collisionDetected |= worm_argh_collision_in_moves(&worms[i], index,
|
||||||
MIN_ARGH_DIST);
|
MIN_ARGH_DIST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -617,15 +703,21 @@ static int make_argh(int index)
|
||||||
/**
|
/**
|
||||||
* Draws an argh in the lcd buffer.
|
* Draws an argh in the lcd buffer.
|
||||||
* @param int index The index of the argh arrays under which
|
* @param int index The index of the argh arrays under which
|
||||||
* the coordinates of the desired argh can be found. Ensure
|
* the coordinates of the desired argh can be found. Ensure
|
||||||
* that the value is 0 <= index < argh_count <= MAX_ARGH.
|
* that the value is 0 <= index < argh_count <= MAX_ARGH.
|
||||||
*/
|
*/
|
||||||
static void draw_argh(int index)
|
static void draw_argh(int index)
|
||||||
{
|
{
|
||||||
/* draw the new argh */
|
/* draw the new argh */
|
||||||
rb->lcd_fillrect(arghx[index] + FIELD_RECT_X,
|
#ifdef COLOR_LCD
|
||||||
arghy[index] + FIELD_RECT_Y,
|
rb->lcd_set_foreground(LCD_RGBPACK(175, 0, 0));
|
||||||
|
#endif
|
||||||
|
rb->lcd_fillrect(arghx[index] + FIELD_RECT_X,
|
||||||
|
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);
|
||||||
|
@ -659,40 +751,40 @@ static void init_worm(struct worm *w, int x, int y){
|
||||||
w->fetch_worm_direction = virtual_player;
|
w->fetch_worm_direction = virtual_player;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the direction that was stored for
|
* Writes the direction that was stored for
|
||||||
* human player 1 into the specified worm. This function
|
* human player 1 into the specified worm. This function
|
||||||
* may be used to be stored in worm.fetch_worm_direction.
|
* may be used to be stored in worm.fetch_worm_direction.
|
||||||
* The value of
|
* The value of
|
||||||
* the direction is read from player1_dir.
|
* the direction is read from player1_dir.
|
||||||
* @param struct worm *w - The worm of which the direction
|
* @param struct worm *w - The worm of which the direction
|
||||||
* is altered.
|
* is altered.
|
||||||
*/
|
*/
|
||||||
static void human_player1(struct worm *w) {
|
static void human_player1(struct worm *w) {
|
||||||
set_worm_dir(w, player1_dir);
|
set_worm_dir(w, player1_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the direction that was stored for
|
* Writes the direction that was stored for
|
||||||
* human player 2 into the specified worm. This function
|
* human player 2 into the specified worm. This function
|
||||||
* may be used to be stored in worm.fetch_worm_direction.
|
* may be used to be stored in worm.fetch_worm_direction.
|
||||||
* The value of
|
* The value of
|
||||||
* the direction is read from player2_dir.
|
* the direction is read from player2_dir.
|
||||||
* @param struct worm *w - The worm of which the direction
|
* @param struct worm *w - The worm of which the direction
|
||||||
* is altered.
|
* is altered.
|
||||||
*/
|
*/
|
||||||
static void human_player2(struct worm *w) {
|
static void human_player2(struct worm *w) {
|
||||||
set_worm_dir(w, player2_dir);
|
set_worm_dir(w, player2_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the direction that was stored for
|
* Writes the direction that was stored for
|
||||||
* human player using a remote control
|
* human player using a remote control
|
||||||
* into the specified worm. This function
|
* into the specified worm. This function
|
||||||
* may be used to be stored in worm.fetch_worm_direction.
|
* may be used to be stored in worm.fetch_worm_direction.
|
||||||
* The value of
|
* The value of
|
||||||
* the direction is read from player3_dir.
|
* the direction is read from player3_dir.
|
||||||
* @param struct worm *w - The worm of which the direction
|
* @param struct worm *w - The worm of which the direction
|
||||||
* is altered.
|
* is altered.
|
||||||
*/
|
*/
|
||||||
static void remote_player(struct worm *w) {
|
static void remote_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 */
|
||||||
|
@ -758,9 +850,9 @@ static void init_wormlet(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move the worm one step further if it is alive.
|
* Move the worm one step further if it is alive.
|
||||||
* The direction in which the worm moves is taken from dirx and diry.
|
* The direction in which the worm moves is taken from dirx and diry.
|
||||||
* move_worm decreases growing if > 0. While the worm is growing the tail
|
* move_worm decreases growing if > 0. While the worm is growing the tail
|
||||||
* is left untouched.
|
* is left untouched.
|
||||||
* @param struct worm *w The worm to move. w must not be NULL.
|
* @param struct worm *w The worm to move. w must not be NULL.
|
||||||
|
@ -787,7 +879,7 @@ static void move_worm(struct worm *w)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* olddir == dir?
|
/* olddir == dir?
|
||||||
a change of direction means a new segment
|
a change of direction means a new segment
|
||||||
has been opened */
|
has been opened */
|
||||||
if (olddirx != w->dirx ||
|
if (olddirx != w->dirx ||
|
||||||
olddiry != w->diry) {
|
olddiry != w->diry) {
|
||||||
|
@ -804,15 +896,15 @@ static void move_worm(struct worm *w)
|
||||||
/* update the worms grow state */
|
/* update the worms grow state */
|
||||||
w->growing--;
|
w->growing--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if the worm isn't growing the tail has to be dragged */
|
/* if the worm isn't growing the tail has to be dragged */
|
||||||
else {
|
else {
|
||||||
/* index of the end of the tail segment */
|
/* index of the end of the tail segment */
|
||||||
int tail_segment_end = (w->tail + 1) % MAX_WORM_SEGMENTS;
|
int tail_segment_end = (w->tail + 1) % MAX_WORM_SEGMENTS;
|
||||||
|
|
||||||
/* drag the end of the tail */
|
/* drag the end of the tail */
|
||||||
/* only one coordinate has to be altered. Here it is
|
/* only one coordinate has to be altered. Here it is
|
||||||
determined which one */
|
determined which one */
|
||||||
int dir = 0; /* specifies wether the coord has to be in- or decreased */
|
int dir = 0; /* specifies wether the coord has to be in- or decreased */
|
||||||
if (w->x[w->tail] == w->x[tail_segment_end]) {
|
if (w->x[w->tail] == w->x[tail_segment_end]) {
|
||||||
dir = (w->y[w->tail] - w->y[tail_segment_end] < 0) ? 1 : -1;
|
dir = (w->y[w->tail] - w->y[tail_segment_end] < 0) ? 1 : -1;
|
||||||
|
@ -827,7 +919,7 @@ static void move_worm(struct worm *w)
|
||||||
must be freed */
|
must be freed */
|
||||||
if (w->x[w->tail] == w->x[tail_segment_end] &&
|
if (w->x[w->tail] == w->x[tail_segment_end] &&
|
||||||
w->y[w->tail] == w->y[tail_segment_end]){
|
w->y[w->tail] == w->y[tail_segment_end]){
|
||||||
|
|
||||||
/* drop the last tail point */
|
/* drop the last tail point */
|
||||||
w->tail = tail_segment_end;
|
w->tail = tail_segment_end;
|
||||||
}
|
}
|
||||||
|
@ -836,12 +928,15 @@ static void move_worm(struct worm *w)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws the head and clears the tail of the worm in
|
* Draws the head and clears the tail of the worm in
|
||||||
* the display buffer. lcd_update() is NOT called thus
|
* the display buffer. lcd_update() is NOT called thus
|
||||||
* the caller has to take care that the buffer is displayed.
|
* the caller has to take care that the buffer is displayed.
|
||||||
*/
|
*/
|
||||||
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,16 +953,19 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks wether the coordinate is part of the worm. Returns
|
* Checks wether the coordinate is part of the worm. Returns
|
||||||
* true if any part of the worm was hit - including the head.
|
* true if any part of the worm was hit - including the head.
|
||||||
* @param x int The x coordinate
|
* @param x int The x coordinate
|
||||||
* @param y int The y coordinate
|
* @param y int The y coordinate
|
||||||
* @return int The index of the worm arrays that contain x, y.
|
* @return int The index of the worm arrays that contain x, y.
|
||||||
* Returns -1 if the coordinates are not part of the worm.
|
* Returns -1 if the coordinates are not part of the worm.
|
||||||
*/
|
*/
|
||||||
static int specific_worm_collision(struct worm *w, int x, int y)
|
static int specific_worm_collision(struct worm *w, int x, int y)
|
||||||
{
|
{
|
||||||
int retVal = -1;
|
int retVal = -1;
|
||||||
|
@ -891,7 +989,7 @@ static int specific_worm_collision(struct worm *w, int x, int y)
|
||||||
if (samey) {
|
if (samey) {
|
||||||
min = w->x[linestart];
|
min = w->x[linestart];
|
||||||
max = w->x[lineend];
|
max = w->x[lineend];
|
||||||
test = x;
|
test = x;
|
||||||
} else {
|
} else {
|
||||||
min = w->y[linestart];
|
min = w->y[linestart];
|
||||||
max = w->y[lineend];
|
max = w->y[lineend];
|
||||||
|
@ -911,7 +1009,7 @@ static int specific_worm_collision(struct worm *w, int x, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increases the length of the specified worm by marking
|
* Increases the length of the specified worm by marking
|
||||||
* that it may grow by len pixels. Note that the worm has
|
* that it may grow by len pixels. Note that the worm has
|
||||||
* to move to make the growing happen.
|
* to move to make the growing happen.
|
||||||
* @param worm *w The worm that is to be altered.
|
* @param worm *w The worm that is to be altered.
|
||||||
|
@ -926,8 +1024,8 @@ static void add_growing(struct worm *w, int len) {
|
||||||
* Determins the worm that is at the coordinates x, y. The parameter
|
* Determins the worm that is at the coordinates x, y. The parameter
|
||||||
* w is a switch parameter that changes the functionality of worm_collision.
|
* w is a switch parameter that changes the functionality of worm_collision.
|
||||||
* If w is specified and x,y hits the head of w NULL is returned.
|
* If w is specified and x,y hits the head of w NULL is returned.
|
||||||
* This is a useful way to determine wether the head of w hits
|
* This is a useful way to determine wether the head of w hits
|
||||||
* any worm but including itself but excluding its own head.
|
* any worm but including itself but excluding its own head.
|
||||||
* (It hits always its own head ;))
|
* (It hits always its own head ;))
|
||||||
* If w is set to NULL worm_collision returns any worm including all heads
|
* If w is set to NULL worm_collision returns any worm including all heads
|
||||||
* that is at position of x,y.
|
* that is at position of x,y.
|
||||||
|
@ -954,9 +1052,9 @@ static struct worm* worm_collision(struct worm *w, int x, int y){
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the head of the worm just has
|
* Returns true if the head of the worm just has
|
||||||
* crossed the field boundaries.
|
* crossed the field boundaries.
|
||||||
* @return bool true if the worm just has wrapped.
|
* @return bool true if the worm just has wrapped.
|
||||||
*/
|
*/
|
||||||
static bool field_collision(struct worm *w)
|
static bool field_collision(struct worm *w)
|
||||||
{
|
{
|
||||||
bool retVal = false;
|
bool retVal = false;
|
||||||
|
@ -972,11 +1070,11 @@ static bool field_collision(struct worm *w)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the specified coordinates are within the
|
* Returns true if the specified coordinates are within the
|
||||||
* field specified by the FIELD_RECT_XXX constants.
|
* field specified by the FIELD_RECT_XXX constants.
|
||||||
* @param int x The x coordinate of the point that is investigated
|
* @param int x The x coordinate of the point that is investigated
|
||||||
* @param int y The y coordinate of the point that is investigated
|
* @param int y The y coordinate of the point that is investigated
|
||||||
* @return bool Returns false if x,y specifies a point outside the
|
* @return bool Returns false if x,y specifies a point outside the
|
||||||
* field of worms.
|
* field of worms.
|
||||||
*/
|
*/
|
||||||
static bool is_in_field_rect(int x, int y) {
|
static bool is_in_field_rect(int x, int y) {
|
||||||
|
@ -1017,7 +1115,7 @@ static int check_collision(struct worm *w)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the index of the food that is closest to the point
|
* Returns the index of the food that is closest to the point
|
||||||
* specified by x, y. This index may be used in the foodx and
|
* specified by x, y. This index may be used in the foodx and
|
||||||
* foody arrays.
|
* foody arrays.
|
||||||
* @param int x The x coordinate of the point
|
* @param int x The x coordinate of the point
|
||||||
* @param int y The y coordinate of the point
|
* @param int y The y coordinate of the point
|
||||||
|
@ -1045,10 +1143,10 @@ static int get_nearest_food(int x, int y){
|
||||||
return nearestfood;
|
return nearestfood;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns wether the specified position is next to the worm
|
* Returns wether the specified position is next to the worm
|
||||||
* and in the direction the worm looks. Use this method to
|
* and in the direction the worm looks. Use this method to
|
||||||
* test wether this position would be hit with the next move of
|
* test wether this position would be hit with the next move of
|
||||||
* the worm unless the worm changes its direction.
|
* the worm unless the worm changes its direction.
|
||||||
* @param struct worm *w - The worm to be investigated
|
* @param struct worm *w - The worm to be investigated
|
||||||
* @param int x - The x coordinate of the position to test.
|
* @param int x - The x coordinate of the position to test.
|
||||||
|
@ -1083,21 +1181,21 @@ static bool will_worm_collide(struct worm *w) {
|
||||||
if (!retVal) {
|
if (!retVal) {
|
||||||
retVal = (argh_collision(x, y) != -1);
|
retVal = (argh_collision(x, y) != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!retVal) {
|
if (!retVal) {
|
||||||
retVal = (worm_collision(w, x, y) != NULL);
|
retVal = (worm_collision(w, x, y) != NULL);
|
||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function
|
* This function
|
||||||
* may be used to be stored in worm.fetch_worm_direction for
|
* may be used to be stored in worm.fetch_worm_direction for
|
||||||
* worms that are not controlled by humans but by artificial stupidity.
|
* worms that are not controlled by humans but by artificial stupidity.
|
||||||
* A direction is searched that doesn't lead to collision but to the nearest
|
* A direction is searched that doesn't lead to collision but to the nearest
|
||||||
* food - but not very intelligent. The direction is written to the specified
|
* food - but not very intelligent. The direction is written to the specified
|
||||||
* worm.
|
* worm.
|
||||||
* @param struct worm *w - The worm of which the direction
|
* @param struct worm *w - The worm of which the direction
|
||||||
* is altered.
|
* is altered.
|
||||||
*/
|
*/
|
||||||
static void virtual_player(struct worm *w) {
|
static void virtual_player(struct worm *w) {
|
||||||
|
@ -1171,7 +1269,7 @@ static void score_board(void)
|
||||||
rb->lcd_set_drawmode(DRMODE_SOLID);
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
||||||
for (i = 0; i < worm_count; i++) {
|
for (i = 0; i < worm_count; i++) {
|
||||||
int score = get_score(&worms[i]);
|
int score = get_score(&worms[i]);
|
||||||
|
|
||||||
/* high score */
|
/* high score */
|
||||||
if (worms[i].fetch_worm_direction != virtual_player){
|
if (worms[i].fetch_worm_direction != virtual_player){
|
||||||
if (highscore < score) {
|
if (highscore < score) {
|
||||||
|
@ -1184,7 +1282,7 @@ static void score_board(void)
|
||||||
|
|
||||||
/* worm state */
|
/* worm state */
|
||||||
switch (check_collision(&worms[i])) {
|
switch (check_collision(&worms[i])) {
|
||||||
case COLLISION_NONE:
|
case COLLISION_NONE:
|
||||||
if (worms[i].growing > 0)
|
if (worms[i].growing > 0)
|
||||||
buf2 = "Growing";
|
buf2 = "Growing";
|
||||||
else {
|
else {
|
||||||
|
@ -1195,19 +1293,19 @@ static void score_board(void)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COLLISION_WORM:
|
case COLLISION_WORM:
|
||||||
buf2 = "Wormed";
|
buf2 = "Wormed";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COLLISION_FOOD:
|
case COLLISION_FOOD:
|
||||||
buf2 = "Growing";
|
buf2 = "Growing";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COLLISION_ARGH:
|
case COLLISION_ARGH:
|
||||||
buf2 = "Argh";
|
buf2 = "Argh";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COLLISION_FIELD:
|
case COLLISION_FIELD:
|
||||||
buf2 = "Crashed";
|
buf2 = "Crashed";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1248,11 +1346,11 @@ static bool process_collisions(struct worm *w)
|
||||||
index = food_collision(w->x[w->head], w->y[w->head]);
|
index = food_collision(w->x[w->head], w->y[w->head]);
|
||||||
if (index != -1){
|
if (index != -1){
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
clear_food(index);
|
clear_food(index);
|
||||||
make_food(index);
|
make_food(index);
|
||||||
draw_food(index);
|
draw_food(index);
|
||||||
|
|
||||||
for (i = 0; i < ARGHS_PER_FOOD; i++) {
|
for (i = 0; i < ARGHS_PER_FOOD; i++) {
|
||||||
argh_count++;
|
argh_count++;
|
||||||
if (argh_count > MAX_ARGH)
|
if (argh_count > MAX_ARGH)
|
||||||
|
@ -1287,7 +1385,7 @@ static bool process_collisions(struct worm *w)
|
||||||
* @return bool Returns true if the game ended
|
* @return bool Returns true if the game ended
|
||||||
* with a dead worm. Returns false if the user
|
* with a dead worm. Returns false if the user
|
||||||
* aborted the game manually.
|
* aborted the game manually.
|
||||||
*/
|
*/
|
||||||
static bool run(void)
|
static bool run(void)
|
||||||
{
|
{
|
||||||
int button = 0;
|
int button = 0;
|
||||||
|
@ -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;
|
||||||
|
@ -1876,10 +1977,10 @@ static void test_worm_argh_collision_in_moves(void) {
|
||||||
rb->snprintf(buf, sizeof buf, "in 5 moves hits: %d", hit_count);
|
rb->snprintf(buf, sizeof buf, "in 5 moves hits: %d", hit_count);
|
||||||
rb->lcd_putsxy(0, LCD_HEIGHT - 8, buf);
|
rb->lcd_putsxy(0, LCD_HEIGHT - 8, buf);
|
||||||
rb->lcd_update();
|
rb->lcd_update();
|
||||||
}
|
}
|
||||||
if (hit_count != ARGH_SIZE + 5) {
|
if (hit_count != ARGH_SIZE + 5) {
|
||||||
rb->button_get(true);
|
rb->button_get(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* DEBUG_WORMLET */
|
#endif /* DEBUG_WORMLET */
|
||||||
|
|
||||||
|
@ -1892,12 +1993,16 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
||||||
{
|
{
|
||||||
bool worm_dead = false;
|
bool worm_dead = false;
|
||||||
int button;
|
int button;
|
||||||
|
|
||||||
(void)(parameter);
|
(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();
|
||||||
|
@ -1905,47 +2010,65 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
||||||
test_worm_food_collision();
|
test_worm_food_collision();
|
||||||
test_worm_argh_collision();
|
test_worm_argh_collision();
|
||||||
test_specific_worm_collision();
|
test_specific_worm_collision();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 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,56 +2094,49 @@ 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 */
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
/* 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
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue