3,36 → 3,38 |
#include "SNAKE.h" |
#include "TIMER4.h" |
|
static SNAKE_DATA *data_p; |
static SNAKE_DATA *snake_data_p; |
static uint32_t rand_value __attribute__((persistent)); |
|
void Snake_Init(SNAKE_DATA *data) { |
data_p = data; |
snake_data_p = data; |
|
// Set starting point |
data_p->body[0] = (SNAKE_POINT){0,0,7}; |
snake_data_p->body[0] = (SNAKE_POINT){0,0,7}; |
|
data_p->pos_head = 0; |
data_p->pos_tail = 0; |
data_p->length = 1; |
data_p->level = 0; |
data_p->delay = SNAKE_MAXIMUM_DELAY; |
data_p->direction = (SNAKE_POINT){1,0,7}; |
data_p->last_direction = 0x08; |
snake_data_p->pos_head = 0; |
snake_data_p->pos_tail = 0; |
snake_data_p->length = 1; |
snake_data_p->level = 0; |
snake_data_p->delay = SNAKE_MAXIMUM_DELAY; |
|
// Initialize the starting direction |
snake_data_p->direction = (SNAKE_POINT){1,0,7}; |
snake_data_p->last_direction = 0x08; |
|
srand(rand_value); |
|
// Generate a starting location for the candy |
data_p->candy_loc = Snake_Generate_Candy(); |
snake_data_p->candy_loc = Snake_Generate_Candy(); |
|
// Draw the snake (head) |
Cube_Clear(); |
uint32_t index = data_p->pos_head; |
Cube_Set_Pixel(data_p->body[index].z, data_p->body[index].x, data_p->body[index].y, SNAKE_HEAD_COLOR); |
while (index != data_p->pos_tail) { |
if (data_p->length > 1) { |
uint32_t index = snake_data_p->pos_head; |
Cube_Set_Pixel(snake_data_p->body[index].z, snake_data_p->body[index].x, snake_data_p->body[index].y, SNAKE_HEAD_COLOR); |
while (index != snake_data_p->pos_tail) { |
if (snake_data_p->length > 1) { |
index = (index == 0) ? CUBE_PIXELS - 1 : index - 1; |
Cube_Set_Pixel(data_p->body[index].z, data_p->body[index].x, data_p->body[index].y, SNAKE_BODY_COLOR); |
Cube_Set_Pixel(snake_data_p->body[index].z, snake_data_p->body[index].x, snake_data_p->body[index].y, SNAKE_BODY_COLOR); |
} |
} |
} |
40,11 → 42,13 |
void Snake_Main(void) { |
// Main function, loops and delays while updating the frame every x milliseconds |
|
// Ensure that a controller is connected before starting |
while(!Controller_Get_Connected()) { |
Delay_MS(100); |
Controller_Poll_Connected(); |
} |
|
// Set the first controller as active and indicate it on its LEDs |
Controller_Set_Active(0); |
Delay_MS(20); |
Controller_Set_Left_Leds(0, 0x1); |
55,7 → 59,7 |
rand_value = rand(); |
|
Snake_Update_Frame(); |
Delay_MS(data_p->delay); |
Delay_MS(snake_data_p->delay); |
} |
} |
|
62,8 → 66,8 |
void Snake_Update_Direction(uint8_t controller, CTRL_BTN_STATUS value) { |
// Determine the next direction for the snake based off the last button press |
if (controller == 0) { |
data_p->last_direction = value.w; |
SNAKE_POINT point = data_p->body[data_p->pos_head]; |
snake_data_p->last_direction = value.w; |
SNAKE_POINT point = snake_data_p->body[snake_data_p->pos_head]; |
|
if (value.BTN_L_N || value.BTN_L_E) { // Up |
point.z = (point.z == CUBE_LAYER_COUNT - 1) ? 0 : point.z + 1; |
79,12 → 83,12 |
point.y = (point.y== 0) ? CUBE_COLUMN_COUNT - 1 : point.y - 1; |
} |
|
data_p->direction = point; |
snake_data_p->direction = point; |
} |
|
// Update the overlay with the candy location |
Cube_Overlay_Clear(); |
Cube_Overlay_Set_Pixel(data_p->candy_loc.z, data_p->candy_loc.x, data_p->candy_loc.y, SNAKE_CANDY_COLOR); |
Cube_Overlay_Set_Pixel(snake_data_p->candy_loc.z, snake_data_p->candy_loc.x, snake_data_p->candy_loc.y, SNAKE_CANDY_COLOR); |
} |
|
void Snake_Update_Frame(void) { |
91,24 → 95,24 |
uint8_t om_nom_nom = 0; |
|
// Check if we are moving onto a candy, if so extend body |
if (data_p->direction.x == data_p->candy_loc.x && |
data_p->direction.y == data_p->candy_loc.y && |
data_p->direction.z == data_p->candy_loc.z) { |
data_p->pos_head = (data_p->pos_head == CUBE_PIXELS - 1) ? 0 : data_p->pos_head + 1; |
data_p->body[data_p->pos_head] = data_p->direction; |
data_p->length++; |
data_p->candy_loc = Snake_Generate_Candy(); |
if (snake_data_p->direction.x == snake_data_p->candy_loc.x && |
snake_data_p->direction.y == snake_data_p->candy_loc.y && |
snake_data_p->direction.z == snake_data_p->candy_loc.z) { |
snake_data_p->pos_head = (snake_data_p->pos_head == CUBE_PIXELS - 1) ? 0 : snake_data_p->pos_head + 1; |
snake_data_p->body[snake_data_p->pos_head] = snake_data_p->direction; |
snake_data_p->length++; |
snake_data_p->candy_loc = Snake_Generate_Candy(); |
om_nom_nom = 1; |
} |
|
// Check if the location that we are moving to is overlapping the body |
uint32_t pos = data_p->pos_tail; |
while (pos != data_p->pos_head) { |
if (data_p->direction.x == data_p->body[pos].x && |
data_p->direction.y == data_p->body[pos].y && |
data_p->direction.z == data_p->body[pos].z) { |
uint32_t pos = snake_data_p->pos_tail; |
while (pos != snake_data_p->pos_head) { |
if (snake_data_p->direction.x == snake_data_p->body[pos].x && |
snake_data_p->direction.y == snake_data_p->body[pos].y && |
snake_data_p->direction.z == snake_data_p->body[pos].z) { |
// Indicate the overlapping pixel, delay, then return to idle state |
Cube_Set_Pixel(data_p->direction.z, data_p->direction.x, data_p->direction.y, SNAKE_COLLISION_COLOR); |
Cube_Set_Pixel(snake_data_p->direction.z, snake_data_p->direction.x, snake_data_p->direction.y, SNAKE_COLLISION_COLOR); |
Delay_MS(3000); |
Cube_Overlay_Clear(); |
Animation_Cube_In_Out(200, ORANGE); |
119,39 → 123,39 |
|
// If we didnt eat a candy, increment the frame to move the body along |
if (!om_nom_nom) { |
data_p->pos_head = (data_p->pos_head == CUBE_PIXELS - 1) ? 0 : data_p->pos_head + 1; |
data_p->pos_tail = (data_p->pos_tail == CUBE_PIXELS - 1) ? 0 : data_p->pos_tail + 1; |
data_p->body[data_p->pos_head] = data_p->direction; |
snake_data_p->pos_head = (snake_data_p->pos_head == CUBE_PIXELS - 1) ? 0 : snake_data_p->pos_head + 1; |
snake_data_p->pos_tail = (snake_data_p->pos_tail == CUBE_PIXELS - 1) ? 0 : snake_data_p->pos_tail + 1; |
snake_data_p->body[snake_data_p->pos_head] = snake_data_p->direction; |
} |
|
// Draw updated snake location |
Cube_Clear(); |
uint32_t index = data_p->pos_head; |
Cube_Set_Pixel(data_p->body[index].z, data_p->body[index].x, data_p->body[index].y, SNAKE_HEAD_COLOR); |
while (index != data_p->pos_tail) { |
if (data_p->length > 1) { |
uint32_t index = snake_data_p->pos_head; |
Cube_Set_Pixel(snake_data_p->body[index].z, snake_data_p->body[index].x, snake_data_p->body[index].y, SNAKE_HEAD_COLOR); |
while (index != snake_data_p->pos_tail) { |
if (snake_data_p->length > 1) { |
index = (index == 0) ? CUBE_PIXELS - 1 : index - 1; |
Cube_Set_Pixel(data_p->body[index].z, data_p->body[index].x, data_p->body[index].y, SNAKE_BODY_COLOR); |
Cube_Set_Pixel(snake_data_p->body[index].z, snake_data_p->body[index].x, snake_data_p->body[index].y, SNAKE_BODY_COLOR); |
} |
} |
|
// Determine the next direction to take |
Snake_Update_Direction(0, (CTRL_BTN_STATUS)data_p->last_direction); |
// Determine the next point to move to |
Snake_Update_Direction(0, (CTRL_BTN_STATUS)snake_data_p->last_direction); |
|
// If we ate a candy, delay for a bit to rest |
if (om_nom_nom) { |
// Increase the level by one |
data_p->level += 1; |
snake_data_p->level += 1; |
|
TIMER4_Stop(); |
Controller_Set_Middle_Leds(0, data_p->level); |
if (data_p->level >= 256) |
Controller_Set_Middle_Leds(0, snake_data_p->level); |
if (snake_data_p->level >= 256) |
Controller_Set_Left_Leds(0, 0x9); |
TIMER4_Start(); |
|
// Decrease the delay between frame updates by 5ms |
if (data_p->delay > SNAKE_MINIMUM_DELAY) |
data_p->delay -= 5; |
if (snake_data_p->delay > SNAKE_MINIMUM_DELAY) |
snake_data_p->delay -= 5; |
// Clear the watchdog timer to prevent resets in a middle of a game |
ClearWDT(); |
} |
166,14 → 170,14 |
y = rand() % 8; |
z = rand() % 8; |
|
if (data_p->length != 1) { |
uint32_t pos = data_p->pos_tail; |
if (snake_data_p->length != 1) { |
uint32_t pos = snake_data_p->pos_tail; |
uint32_t overlap = 0; |
// Iterate through the frame till we finish or find an overlap |
while (pos != data_p->pos_head) { |
if (data_p->body[pos].x == x && |
data_p->body[pos].y == y && |
data_p->body[pos].z == z) { |
while (pos != snake_data_p->pos_head) { |
if (snake_data_p->body[pos].x == x && |
snake_data_p->body[pos].y == y && |
snake_data_p->body[pos].z == z) { |
overlap = 1; |
break; |
} else { |
183,10 → 187,10 |
if (!overlap) |
brk = 1; |
} else { |
uint32_t pos = data_p->pos_tail; |
if (data_p->body[pos].x != x && |
data_p->body[pos].y != y && |
data_p->body[pos].z != z) { |
uint32_t pos = snake_data_p->pos_tail; |
if (snake_data_p->body[pos].x != x && |
snake_data_p->body[pos].y != y && |
snake_data_p->body[pos].z != z) { |
brk = 1; |
} |
} |