//PIC Stuff/Cerebot_32MX7_LED_Cube/CONTROLLERS.c |
---|
24,6 → 24,7 |
} |
ctrl_data_p->connected_count = 0x0; |
ctrl_data_p->next_poll = 0x0; |
// Poll to see which controllers are connected |
Controller_Poll_Connected(); |
48,7 → 49,7 |
} |
// A small delay is needed between polls |
Delay_MS(1); |
Delay_US(500); |
} |
// Show the number of controllers connected |
64,36 → 65,38 |
void Controller_Update(void) { |
uint8_t buffer[2]; |
uint8_t result, length, i, j; |
uint8_t result, length; |
CTRL_BTN_STATUS btn_change; |
for (i = 0; i < ctrl_data_p->connected_count; i++) { |
// Store the last read values |
ctrl_data_p->btn_prev[i] = ctrl_data_p->btn_curr[i]; |
// Read in the button values for each controller |
I2C1_Master_Restart(ctrl_data_p->connected_controllers[i], CONTROLLER_CMD_READ, 1); |
do { |
result = I2C1_Get_Status(); |
} while (!result); |
// Save the read values |
length = I2C1_Read_Buffer(buffer); |
ctrl_data_p->btn_curr[i].w = buffer[0]; |
uint8_t controller = ctrl_data_p->next_poll; |
// Determine if a change was made between the current and previous values |
if (ctrl_data_p->btn_curr[i].w != ctrl_data_p->btn_prev[i].w) { |
// Determine if a button was pressed (unpressed->pressed) |
btn_change.w = ctrl_data_p->btn_prev[i].w ^ ctrl_data_p->btn_curr[i].w; |
btn_change.w &= ctrl_data_p->btn_curr[i].w; |
// Store the last read values |
ctrl_data_p->btn_prev[controller] = ctrl_data_p->btn_curr[controller]; |
// If a button was pressed, call the saved callback |
if (btn_change.w) { |
if (ctrl_data_p->change_callback != NULL) { |
ctrl_data_p->change_callback(i, btn_change); |
} |
// Read in the button values for each controller |
I2C1_Master_Restart(ctrl_data_p->connected_controllers[controller], CONTROLLER_CMD_READ, 1); |
do { |
result = I2C1_Get_Status(); |
} while (!result); |
// Save the read values |
length = I2C1_Read_Buffer(buffer); |
ctrl_data_p->btn_curr[controller].w = buffer[0]; |
// Determine if a change was made between the current and previous values |
if (ctrl_data_p->btn_curr[controller].w != ctrl_data_p->btn_prev[controller].w) { |
// Determine if a button was pressed (unpressed->pressed) |
btn_change.w = ctrl_data_p->btn_prev[controller].w ^ ctrl_data_p->btn_curr[controller].w; |
btn_change.w &= ctrl_data_p->btn_curr[controller].w; |
// If a button was pressed, call the saved callback |
if (btn_change.w) { |
if (ctrl_data_p->change_callback != NULL) { |
ctrl_data_p->change_callback(controller, btn_change); |
} |
} |
} |
ctrl_data_p->next_poll = (controller == ctrl_data_p->connected_count - 1) ? 0x0 : controller+1; |
} |
void Controller_Set_Left_Leds(uint8_t controller, uint8_t value) { |
//PIC Stuff/Cerebot_32MX7_LED_Cube/CONTROLLERS.h |
---|
10,7 → 10,7 |
#define CONTROLLER_START_ADDRESS 0x01 |
#define CONTROLLER_END_ADDRESS 0x08 |
#define CONTROLLER_MAX_COUNT 4 |
#define CONTROLLER_MAX_COUNT 8 |
#define CONTROLLER_BRIGHTNESS_HIGH 0x80 |
54,6 → 54,7 |
void (*change_callback)(uint8_t controller, CTRL_BTN_STATUS values); |
uint8_t connected_count; |
uint8_t next_poll; |
uint8_t connected_controllers[CONTROLLER_MAX_COUNT]; |
CTRL_LED_VALUES led_status[CONTROLLER_MAX_COUNT]; |
CTRL_BTN_STATUS btn_prev[CONTROLLER_MAX_COUNT]; |
//PIC Stuff/Cerebot_32MX7_LED_Cube/SNAKE.c |
---|
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; |
} |
} |
//PIC Stuff/Cerebot_32MX7_LED_Cube/TRON.c |
---|
1,165 → 1,249 |
#include "defines.h" |
#include "CONTROLLERS.h" |
#include "TRON.h" |
#include "TIMER4.h" |
static TRON_DATA *data_p; |
static TRON_DATA *tron_data_p; |
void Tron_Init(TRON_DATA *data) { |
data_p = data; |
tron_data_p = data; |
// Set starting point |
data_p->p1_body[0] = (TRON_POINT){0,0,7}; |
data_p->p2_body[0] = (TRON_POINT){7,7,7}; |
// Set players 1-4 colors |
tron_data_p->Color_Head_R[0] = 0xFF; |
tron_data_p->Color_Head_G[0] = 0x00; |
tron_data_p->Color_Head_B[0] = 0x00; |
tron_data_p->Color_Body_R[0] = 0x20; |
tron_data_p->Color_Body_G[0] = 0x00; |
tron_data_p->Color_Body_B[0] = 0x00; |
data_p->length = 1; |
data_p->delay = 800; |
tron_data_p->Color_Head_R[1] = 0x00; |
tron_data_p->Color_Head_G[1] = 0x00; |
tron_data_p->Color_Head_B[1] = 0xFF; |
tron_data_p->Color_Body_R[1] = 0x00; |
tron_data_p->Color_Body_G[1] = 0x00; |
tron_data_p->Color_Body_B[1] = 0x20; |
tron_data_p->Color_Head_R[2] = 0x00; |
tron_data_p->Color_Head_G[2] = 0xFF; |
tron_data_p->Color_Head_B[2] = 0x00; |
tron_data_p->Color_Body_R[2] = 0x00; |
tron_data_p->Color_Body_G[2] = 0x20; |
tron_data_p->Color_Body_B[2] = 0x00; |
tron_data_p->Color_Head_R[3] = 0xFF; |
tron_data_p->Color_Head_G[3] = 0x60; |
tron_data_p->Color_Head_B[3] = 0x00; |
tron_data_p->Color_Body_R[3] = 0x20; |
tron_data_p->Color_Body_G[3] = 0x10; |
tron_data_p->Color_Body_B[3] = 0x00; |
// // Set starting points for players |
tron_data_p->body[0][0] = (TRON_POINT){0,0,7}; |
tron_data_p->body[1][0] = (TRON_POINT){7,7,7}; |
tron_data_p->body[2][0] = (TRON_POINT){0,7,7}; |
tron_data_p->body[3][0] = (TRON_POINT){7,0,7}; |
tron_data_p->delay = TRON_DELAY; |
Cube_Clear(); |
Cube_Overlay_Clear(); |
// Draw player 1 light trail |
uint32_t index; |
for (index = 0; index < data_p->length - 1; index++) { |
Cube_Set_Pixel(data_p->p1_body[index].z, data_p->p1_body[index].x, data_p->p1_body[index].y, TRON_PLAYER_1_COLOR); |
// Determine the number of players (connected controllers) |
tron_data_p->players = Controller_Get_Connected(); |
while (tron_data_p->players < 2) { |
Delay_MS(100); |
Controller_Poll_Connected(); |
tron_data_p->players = Controller_Get_Connected(); |
} |
Cube_Set_Pixel(data_p->p1_body[data_p->length-1].z, data_p->p1_body[data_p->length-1].x, data_p->p1_body[data_p->length-1].y, TRON_PLAYER_1_HEAD); |
if (tron_data_p->players > TRON_MAX_PLAYERS) |
tron_data_p->players = TRON_MAX_PLAYERS; |
tron_data_p->players_alive = tron_data_p->players; |
// Draw player 2 light trail |
for (index = 0; index < data_p->length - 1; index++) { |
Cube_Set_Pixel(data_p->p2_body[index].z, data_p->p2_body[index].x, data_p->p2_body[index].y, TRON_PLAYER_2_COLOR); |
// Draw each player's light trail |
uint8_t i; |
for (i = 0; i < tron_data_p->players; i++) { |
tron_data_p->length[i] = 1; |
tron_data_p->dead[i] = 0; |
// Draw the head |
Cube_Set_Pixel(tron_data_p->body[i][tron_data_p->length[i] - 1].z, |
tron_data_p->body[i][tron_data_p->length[i] - 1].x, |
tron_data_p->body[i][tron_data_p->length[i] - 1].y, |
tron_data_p->Color_Head_R[i], tron_data_p->Color_Head_G[i], |
tron_data_p->Color_Head_B[i]); |
} |
Cube_Set_Pixel(data_p->p2_body[data_p->length-1].z, data_p->p2_body[data_p->length-1].x, data_p->p2_body[data_p->length-1].y, TRON_PLAYER_2_HEAD); |
// Set starting direction for players |
Tron_Update_Direction(0, (CTRL_BTN_STATUS) (uint8_t) 0x08); |
Tron_Update_Direction(1, (CTRL_BTN_STATUS) (uint8_t) 0x10); |
Tron_Update_Direction(2, (CTRL_BTN_STATUS) (uint8_t) 0x04); |
Tron_Update_Direction(3, (CTRL_BTN_STATUS) (uint8_t) 0x20); |
} |
void Tron_Main(void) { |
// Main function, loops and delays while updating the frame every x milliseconds |
Tron_Update_Direction(0x04,0x04); |
// Controller_Set_Leds(0x01,0x01); |
Delay_MS(2000); |
uint8_t i; |
for (i = 0; i < tron_data_p->players; i++) { |
Controller_Set_Active(i); |
} |
Delay_MS(20); |
// Light up the player indicators |
switch (tron_data_p->players) { |
case 4: |
Controller_Set_Left_Leds(3, 0x02); |
case 3: |
Controller_Set_Left_Leds(2, 0x04); |
case 2: |
default: |
Controller_Set_Left_Leds(1, 0x08); |
Controller_Set_Left_Leds(0, 0x01); |
break; |
} |
TIMER4_Start(); |
Delay_MS(3000); |
while (1) { |
Tron_Update_Frame(); |
Delay_MS(data_p->delay); |
Delay_MS(tron_data_p->delay); |
} |
} |
void Tron_Update_Direction(uint8_t p1, uint8_t p2) { |
void Tron_Update_Direction(uint8_t controller, CTRL_BTN_STATUS value) { |
// Determine the next direction for the trails based off the last button press |
if (p1) { |
TRON_P1_DIRECTION p1_dir; |
p1_dir.value = p1; |
data_p->p1_last_direction = p1_dir.value; |
TRON_POINT p1_point = data_p->p1_body[data_p->length - 1]; |
if (p1_dir.up) { |
p1_point.z = (p1_point.z == CUBE_LAYER_COUNT - 1) ? 0 : p1_point.z + 1; |
} else if (p1_dir.down) { |
p1_point.z = (p1_point.z == 0) ? CUBE_LAYER_COUNT - 1 : p1_point.z - 1; |
} else if (p1_dir.forward) { |
p1_point.x = (p1_point.x == CUBE_ROW_COUNT - 1) ? 0 : p1_point.x + 1; |
} else if (p1_dir.right) { |
p1_point.y = (p1_point.y == CUBE_COLUMN_COUNT - 1) ? 0 : p1_point.y + 1; |
} else if (p1_dir.backward) { |
p1_point.x = (p1_point.x == 0) ? CUBE_ROW_COUNT - 1 : p1_point.x - 1; |
} else if (p1_dir.left) { |
p1_point.y = (p1_point.y== 0) ? CUBE_COLUMN_COUNT - 1 : p1_point.y - 1; |
if (controller < tron_data_p->players) { |
// Save the current button value |
tron_data_p->last_direction[controller] = value.w; |
// Grab the location of the head |
TRON_POINT next_pos = tron_data_p->body[controller][tron_data_p->length[controller] - 1]; |
// Determine which next point to move to |
if (value.BTN_L_N || value.BTN_L_E) { // Up |
next_pos.z = (next_pos.z == CUBE_LAYER_COUNT - 1) ? 0 : next_pos.z + 1; |
} else if (value.BTN_L_S || value.BTN_L_W) { // Down |
next_pos.z = (next_pos.z == 0) ? CUBE_LAYER_COUNT - 1 : next_pos.z - 1; |
} else if (value.BTN_R_N) { // Forward |
next_pos.x = (next_pos.x == CUBE_ROW_COUNT - 1) ? 0 : next_pos.x + 1; |
} else if (value.BTN_R_W) { // Left |
next_pos.y = (next_pos.y == CUBE_COLUMN_COUNT - 1) ? 0 : next_pos.y + 1; |
} else if (value.BTN_R_S) { // Backwards |
next_pos.x = (next_pos.x == 0) ? CUBE_ROW_COUNT - 1 : next_pos.x - 1; |
// } else if (value.BTN_R_E) { // Right |
} else { // Right |
next_pos.y = (next_pos.y== 0) ? CUBE_COLUMN_COUNT - 1 : next_pos.y - 1; |
} |
data_p->p1_direction = p1_point; |
// Save the next point to move to |
tron_data_p->direction[controller] = next_pos; |
} |
if (p2) { |
TRON_P2_DIRECTION p2_dir; |
p2_dir.value = p2; |
data_p->p2_last_direction = p2_dir.value; |
TRON_POINT p2_point = data_p->p2_body[data_p->length - 1]; |
if (p2_dir.up) { |
p2_point.z = (p2_point.z == CUBE_LAYER_COUNT - 1) ? 0 : p2_point.z + 1; |
} else if (p2_dir.down) { |
p2_point.z = (p2_point.z == 0) ? CUBE_LAYER_COUNT - 1 : p2_point.z - 1; |
} else if (p2_dir.forward) { |
p2_point.x = (p2_point.x == CUBE_ROW_COUNT - 1) ? 0 : p2_point.x + 1; |
} else if (p2_dir.right) { |
p2_point.y = (p2_point.y == CUBE_COLUMN_COUNT - 1) ? 0 : p2_point.y + 1; |
} else if (p2_dir.backward) { |
p2_point.x = (p2_point.x == 0) ? CUBE_ROW_COUNT - 1 : p2_point.x - 1; |
} else if (p2_dir.left) { |
p2_point.y = (p2_point.y== 0) ? CUBE_COLUMN_COUNT - 1 : p2_point.y - 1; |
} |
data_p->p2_direction = p2_point; |
} |
} |
void Tron_Update_Frame(void) { |
// Check if there is a head-on collision |
if (data_p->p1_direction.x == data_p->p2_direction.x && |
data_p->p1_direction.y == data_p->p2_direction.y && |
data_p->p1_direction.z == data_p->p2_direction.z) { |
Cube_Set_Pixel(data_p->p1_direction.z, data_p->p1_direction.x, data_p->p1_direction.y, TRON_COLLISION); |
Delay_MS(3000); |
Animation_Cube_In_Out(200, TRON_COLLISION); |
Reset_Board(BOARD_MODE_IDLE); |
uint8_t player, player2; |
// Change the current head color to the body color |
for (player = 0; player < tron_data_p->players; player++) { |
if (tron_data_p->dead[player] == 0) { |
Cube_Set_Pixel(tron_data_p->body[player][tron_data_p->length[player] - 1].z, |
tron_data_p->body[player][tron_data_p->length[player] - 1].x, |
tron_data_p->body[player][tron_data_p->length[player] - 1].y, |
tron_data_p->Color_Body_R[player], |
tron_data_p->Color_Body_G[player], |
tron_data_p->Color_Body_B[player]); |
} |
} |
// Check if there is a head-on collision between any of the players |
for (player = 0; player < tron_data_p->players; player++) { |
if (tron_data_p->dead[player] == 0) { |
for (player2 = 0; player2 < tron_data_p->players; player2++) { |
if (player2 == player) continue; |
if (tron_data_p->dead[player2] == 0) { |
if (tron_data_p->direction[player].x == tron_data_p->direction[player2].x && |
tron_data_p->direction[player].y == tron_data_p->direction[player2].y && |
tron_data_p->direction[player].z == tron_data_p->direction[player2].z) { |
// Indicate the collision point |
Cube_Set_Pixel(tron_data_p->direction[player].z, tron_data_p->direction[player].x, |
tron_data_p->direction[player].y, TRON_COLLISION); |
// Mark the players as dead |
tron_data_p->dead[player] = 1; |
tron_data_p->dead[player2] = 1; |
tron_data_p->players_alive -= 2; |
} |
} |
} |
} |
} |
// Check if the location that we are moving to is overlapping either trails |
uint32_t index, p1_collision = 0, p2_collision = 0; |
for (index = 0; index < data_p->length; index++) { |
if (data_p->p1_direction.x == data_p->p1_body[index].x && |
data_p->p1_direction.y == data_p->p1_body[index].y && |
data_p->p1_direction.z == data_p->p1_body[index].z) { |
p1_collision = 1; |
uint8_t index; |
for (player = 0; player < tron_data_p->players; player++) { |
// Check if the player in question is dead |
if (tron_data_p->dead[player] == 0) { |
// See if the player's next point hits anyone elses trail |
for (player2 = 0; player2 < tron_data_p->players; player2++) { |
for (index = 0; index < tron_data_p->length[player2]; index++) { |
if (tron_data_p->direction[player].x == tron_data_p->body[player2][index].x && |
tron_data_p->direction[player].y == tron_data_p->body[player2][index].y && |
tron_data_p->direction[player].z == tron_data_p->body[player2][index].z) { |
// Indicate the collision point |
Cube_Set_Pixel(tron_data_p->direction[player].z, tron_data_p->direction[player].x, |
tron_data_p->direction[player].y, TRON_COLLISION); |
// Mark the player as dead |
tron_data_p->dead[player] = 1; |
tron_data_p->players_alive -= 1; |
} |
} |
} |
} |
if (data_p->p1_direction.x == data_p->p2_body[index].x && |
data_p->p1_direction.y == data_p->p2_body[index].y && |
data_p->p1_direction.z == data_p->p2_body[index].z) { |
p1_collision = 1; |
} |
if (data_p->p2_direction.x == data_p->p2_body[index].x && |
data_p->p2_direction.y == data_p->p2_body[index].y && |
data_p->p2_direction.z == data_p->p2_body[index].z) { |
p2_collision = 1; |
} |
if (data_p->p2_direction.x == data_p->p1_body[index].x && |
data_p->p2_direction.y == data_p->p1_body[index].y && |
data_p->p2_direction.z == data_p->p1_body[index].z) { |
p2_collision = 1; |
} |
} |
// Save the new head location of each trail |
data_p->length++; |
data_p->p1_body[data_p->length - 1] = data_p->p1_direction; |
data_p->p2_body[data_p->length - 1] = data_p->p2_direction; |
Cube_Clear(); |
// Draw player 1 light trail |
for (index = 0; index < data_p->length - 1; index++) { |
Cube_Set_Pixel(data_p->p1_body[index].z, data_p->p1_body[index].x, data_p->p1_body[index].y, TRON_PLAYER_1_COLOR); |
for (player = 0; player < tron_data_p->players; player++) { |
// If player is still alive, extend its body in the next direction |
if (tron_data_p->dead[player] == 0) { |
tron_data_p->length[player]++; |
tron_data_p->body[player][tron_data_p->length[player] - 1] = tron_data_p->direction[player]; |
} |
} |
Cube_Set_Pixel(data_p->p1_body[data_p->length-1].z, data_p->p1_body[data_p->length-1].x, data_p->p1_body[data_p->length-1].y, TRON_PLAYER_1_HEAD); |
// Draw player 2 light trail |
for (index = 0; index < data_p->length - 1; index++) { |
Cube_Set_Pixel(data_p->p2_body[index].z, data_p->p2_body[index].x, data_p->p2_body[index].y, TRON_PLAYER_2_COLOR); |
// Update the head to its corresponding color |
for (player = 0; player < tron_data_p->players; player++) { |
// If player is still alive, recolor its body to indicate its new head |
if (tron_data_p->dead[player] == 0) { |
// Set the color of the new head |
Cube_Set_Pixel(tron_data_p->body[player][tron_data_p->length[player] - 1].z, |
tron_data_p->body[player][tron_data_p->length[player] - 1].x, |
tron_data_p->body[player][tron_data_p->length[player] - 1].y, |
tron_data_p->Color_Head_R[player], |
tron_data_p->Color_Head_G[player], |
tron_data_p->Color_Head_B[player]); |
} |
} |
Cube_Set_Pixel(data_p->p2_body[data_p->length-1].z, data_p->p2_body[data_p->length-1].x, data_p->p2_body[data_p->length-1].y, TRON_PLAYER_2_HEAD); |
// Indicate the point of collision and reset to idle mode |
if (p1_collision || p2_collision) { |
uint32_t ind = data_p->length - 1; |
if (p1_collision) |
Cube_Set_Pixel(data_p->p1_body[ind].z, data_p->p1_body[ind].x, data_p->p1_body[ind].y, TRON_COLLISION); |
if (p2_collision) |
Cube_Set_Pixel(data_p->p2_body[ind].z, data_p->p2_body[ind].x, data_p->p2_body[ind].y, TRON_COLLISION); |
Delay_MS(3000); |
if (p1_collision && p2_collision) |
Animation_Cube_In_Out(200, TRON_COLLISION); |
else if (p1_collision) |
Animation_Cube_In_Out(200, TRON_PLAYER_2_HEAD); |
else if (p2_collision) |
Animation_Cube_In_Out(200, TRON_PLAYER_1_HEAD); |
// End the game if there is one player left alive |
if (tron_data_p->players_alive == 1) { |
Delay_MS(5000); |
// Determine which player is still alive and flash his color |
for (player = 0; player < tron_data_p->players; player++) { |
if (tron_data_p->dead[player] == 0) { |
Animation_Cube_In_Out(200, tron_data_p->Color_Head_R[player], |
tron_data_p->Color_Head_G[player], tron_data_p->Color_Head_B[player]); |
} |
} |
Reset_Board(BOARD_MODE_IDLE); |
} else if (tron_data_p->players_alive == 0) { |
// If no players are alive flash neutral color |
Delay_MS(5000); |
Animation_Cube_In_Out(200, TRON_COLLISION_2); |
Reset_Board(BOARD_MODE_IDLE); |
} |
// Determine the next direction to take |
Tron_Update_Direction(data_p->p1_last_direction, data_p->p2_last_direction); |
// Determine the next direction to move to for each player |
for (player = 0; player < tron_data_p->players; player++) { |
if (tron_data_p->dead[player] == 0) { |
Tron_Update_Direction(player, (CTRL_BTN_STATUS)tron_data_p->last_direction[player]); |
} |
} |
// Decrease the delay between frame updates by 5ms |
data_p->delay -= 5; |
tron_data_p->delay -= 5; |
} |
//PIC Stuff/Cerebot_32MX7_LED_Cube/TRON.h |
---|
3,61 → 3,40 |
#include "CUBE.h" |
#define TRON_PLAYER_1_COLOR GREEN |
#define TRON_PLAYER_2_COLOR PURPLE |
#define TRON_PLAYER_1_HEAD BLUE |
#define TRON_PLAYER_2_HEAD RED |
#define TRON_COLLISION ORANGE |
#define TRON_MAX_PLAYERS 4 |
#define TRON_COLLISION WHITE |
#define TRON_COLLISION_2 ORANGE |
#define TRON_DELAY 800 |
typedef struct { |
unsigned x :8; |
unsigned y :8; |
unsigned z :8; |
unsigned :8; |
uint8_t x; |
uint8_t y; |
uint8_t z; |
} TRON_POINT; |
typedef union { |
struct { |
unsigned up :1; |
unsigned down :1; |
unsigned right :1; |
unsigned forward :1; |
unsigned left :1; |
unsigned backward :1; |
unsigned :2; |
}; |
uint8_t value; |
} TRON_P1_DIRECTION; |
typedef struct { |
uint8_t Color_Head_R[TRON_MAX_PLAYERS]; |
uint8_t Color_Head_G[TRON_MAX_PLAYERS]; |
uint8_t Color_Head_B[TRON_MAX_PLAYERS]; |
typedef union { |
struct { |
unsigned up :1; |
unsigned down :1; |
unsigned left :1; |
unsigned backward :1; |
unsigned right :1; |
unsigned forward :1; |
unsigned :2; |
}; |
uint8_t value; |
} TRON_P2_DIRECTION; |
uint8_t Color_Body_R[TRON_MAX_PLAYERS]; |
uint8_t Color_Body_G[TRON_MAX_PLAYERS]; |
uint8_t Color_Body_B[TRON_MAX_PLAYERS]; |
typedef struct { |
TRON_POINT p1_body[CUBE_PIXELS]; |
TRON_POINT p1_direction; |
uint8_t p1_last_direction; |
TRON_POINT body[TRON_MAX_PLAYERS][CUBE_PIXELS]; |
TRON_POINT direction[TRON_MAX_PLAYERS]; |
uint8_t last_direction[TRON_MAX_PLAYERS]; |
uint8_t dead[TRON_MAX_PLAYERS]; |
uint32_t length[TRON_MAX_PLAYERS]; |
TRON_POINT p2_body[CUBE_PIXELS]; |
TRON_POINT p2_direction; |
uint8_t p2_last_direction; |
uint32_t length; |
uint8_t players; |
uint8_t players_alive; |
uint32_t delay; |
} TRON_DATA; |
void Tron_Init(TRON_DATA *data); |
void Tron_Main(void); |
void Tron_Update_Direction(uint8_t p1, uint8_t p2); |
void Tron_Update_Direction(uint8_t controller, CTRL_BTN_STATUS value); |
void Tron_Update_Frame(void); |
#endif /* TRON_H */ |
//PIC Stuff/Cerebot_32MX7_LED_Cube/main.c |
---|
178,7 → 178,7 |
// Initialize the I2C1 module |
I2C1_DATA i2c_1_data; |
I2C1_Init(&i2c_1_data, I2C1_200KHZ, 0x20); |
I2C1_Init(&i2c_1_data, I2C1_400KHZ, 0x20); |
// // Initialize the UART1 module |
// UART1_DATA uart_data; |
245,11 → 245,10 |
TIMER5_Init(NULL, &Cube_Timer_Interrupt, 2000); |
TIMER5_Start(); |
// Poll the controllers at 1kHz |
Controller_Init(&ctrl_data, NULL); |
Controller_Init(NULL, &Tron_Update_Direction); |
TIMER4_Init(NULL, &Controller_Update, NULL, 0); |
// Initialize and start the game |
Tron_Init(&tron_data); |
TIMER4_Start(); |
Tron_Main(); |
break; |
case BOARD_MODE_ETHERNET: |
//PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/Makefile-genesis.properties |
---|
1,5 → 1,5 |
# |
#Mon Mar 17 03:54:28 EDT 2014 |
#Tue Mar 18 21:04:27 EDT 2014 |
default.com-microchip-mplab-nbide-toolchainXC32-XC32LanguageToolchain.md5=83f4565fa27ad9b8015f63d69ef74f66 |
default.languagetoolchain.dir=C\:\\Program Files (x86)\\Microchip\\xc32\\v1.31\\bin |
com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=1f98a0eed69cb2a45c12981fa9470927 |
//PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/private/private.xml |
---|
1,3 → 1,12 |
<?xml version="1.0" encoding="UTF-8"?><project-private xmlns="http://www.netbeans.org/ns/project-private/1"> |
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/> |
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/1"> |
<file>file:/C:/Users/Kevin/Documents/Code/Cerebot_32MX7_LED_Cube/CONTROLLERS.h</file> |
<file>file:/C:/Users/Kevin/Documents/Code/Cerebot_32MX7_LED_Cube/SNAKE.h</file> |
<file>file:/C:/Users/Kevin/Documents/Code/Cerebot_32MX7_LED_Cube/TRON.h</file> |
<file>file:/C:/Users/Kevin/Documents/Code/Cerebot_32MX7_LED_Cube/main.c</file> |
<file>file:/C:/Users/Kevin/Documents/Code/Cerebot_32MX7_LED_Cube/CONTROLLERS.c</file> |
<file>file:/C:/Users/Kevin/Documents/Code/Cerebot_32MX7_LED_Cube/TRON.c</file> |
<file>file:/C:/Users/Kevin/Documents/Code/Cerebot_32MX7_LED_Cube/SNAKE.c</file> |
</open-files> |
</project-private> |