Subversion Repositories Code-Repo

Compare Revisions

Ignore whitespace Rev 277 → Rev 278

/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>