Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
241 Kevin 1
#include "defines.h"
2
#include "CONTROLLERS.h"
3
#include "TRON.h"
278 Kevin 4
#include "TIMER4.h"
241 Kevin 5
 
278 Kevin 6
static TRON_DATA *tron_data_p;
241 Kevin 7
 
8
void Tron_Init(TRON_DATA *data) {
278 Kevin 9
    tron_data_p = data;
241 Kevin 10
 
278 Kevin 11
    // Set players 1-4 colors
12
    tron_data_p->Color_Head_R[0] = 0xFF;
13
    tron_data_p->Color_Head_G[0] = 0x00;
14
    tron_data_p->Color_Head_B[0] = 0x00;
15
    tron_data_p->Color_Body_R[0] = 0x20;
16
    tron_data_p->Color_Body_G[0] = 0x00;
17
    tron_data_p->Color_Body_B[0] = 0x00;
241 Kevin 18
 
278 Kevin 19
    tron_data_p->Color_Head_R[1] = 0x00;
20
    tron_data_p->Color_Head_G[1] = 0x00;
21
    tron_data_p->Color_Head_B[1] = 0xFF;
22
    tron_data_p->Color_Body_R[1] = 0x00;
23
    tron_data_p->Color_Body_G[1] = 0x00;
24
    tron_data_p->Color_Body_B[1] = 0x20;
241 Kevin 25
 
278 Kevin 26
    tron_data_p->Color_Head_R[2] = 0x00;
27
    tron_data_p->Color_Head_G[2] = 0xFF;
28
    tron_data_p->Color_Head_B[2] = 0x00;
29
    tron_data_p->Color_Body_R[2] = 0x00;
30
    tron_data_p->Color_Body_G[2] = 0x20;
31
    tron_data_p->Color_Body_B[2] = 0x00;
32
 
33
    tron_data_p->Color_Head_R[3] = 0xFF;
34
    tron_data_p->Color_Head_G[3] = 0x60;
35
    tron_data_p->Color_Head_B[3] = 0x00;
36
    tron_data_p->Color_Body_R[3] = 0x20;
37
    tron_data_p->Color_Body_G[3] = 0x10;
38
    tron_data_p->Color_Body_B[3] = 0x00;
39
 
40
//    // Set starting points for players
41
    tron_data_p->body[0][0] = (TRON_POINT){0,0,7};
42
    tron_data_p->body[1][0] = (TRON_POINT){7,7,7};
43
    tron_data_p->body[2][0] = (TRON_POINT){0,7,7};
44
    tron_data_p->body[3][0] = (TRON_POINT){7,0,7};
45
 
46
    tron_data_p->delay = TRON_DELAY;
47
 
241 Kevin 48
    Cube_Clear();
49
    Cube_Overlay_Clear();
50
 
278 Kevin 51
    // Determine the number of players (connected controllers)
52
    tron_data_p->players = Controller_Get_Connected();
53
    while (tron_data_p->players < 2) {
54
        Delay_MS(100);
55
        Controller_Poll_Connected();
56
        tron_data_p->players = Controller_Get_Connected();
241 Kevin 57
    }
278 Kevin 58
    if (tron_data_p->players > TRON_MAX_PLAYERS)
59
        tron_data_p->players = TRON_MAX_PLAYERS;
60
    tron_data_p->players_alive = tron_data_p->players;
241 Kevin 61
 
278 Kevin 62
    // Draw each player's light trail
63
    uint8_t i;
64
    for (i = 0; i < tron_data_p->players; i++) {
65
        tron_data_p->length[i] = 1;
66
        tron_data_p->dead[i] = 0;
67
        // Draw the head
68
        Cube_Set_Pixel(tron_data_p->body[i][tron_data_p->length[i] - 1].z,
69
                tron_data_p->body[i][tron_data_p->length[i] - 1].x,
70
                tron_data_p->body[i][tron_data_p->length[i] - 1].y,
71
                tron_data_p->Color_Head_R[i], tron_data_p->Color_Head_G[i],
72
                tron_data_p->Color_Head_B[i]);
241 Kevin 73
    }
278 Kevin 74
 
75
    // Set starting direction for players
76
    Tron_Update_Direction(0, (CTRL_BTN_STATUS) (uint8_t) 0x08);
77
    Tron_Update_Direction(1, (CTRL_BTN_STATUS) (uint8_t) 0x10);
78
    Tron_Update_Direction(2, (CTRL_BTN_STATUS) (uint8_t) 0x04);
79
    Tron_Update_Direction(3, (CTRL_BTN_STATUS) (uint8_t) 0x20);
241 Kevin 80
}
81
 
82
void Tron_Main(void) {
83
    // Main function, loops and delays while updating the frame every x milliseconds
278 Kevin 84
    uint8_t i;
85
    for (i = 0; i < tron_data_p->players; i++) {
86
        Controller_Set_Active(i);
87
    }
88
    Delay_MS(20);
89
    // Light up the player indicators
90
    switch (tron_data_p->players) {
91
        case 4:
92
            Controller_Set_Left_Leds(3, 0x02);
93
        case 3:
94
            Controller_Set_Left_Leds(2, 0x04);
95
        case 2:
96
        default:
97
            Controller_Set_Left_Leds(1, 0x08);
98
            Controller_Set_Left_Leds(0, 0x01);
99
            break;
100
    }
101
    TIMER4_Start();
102
    Delay_MS(3000);
241 Kevin 103
    while (1) {
104
        Tron_Update_Frame();
278 Kevin 105
        Delay_MS(tron_data_p->delay);
241 Kevin 106
    }
107
}
108
 
278 Kevin 109
void Tron_Update_Direction(uint8_t controller, CTRL_BTN_STATUS value) {
241 Kevin 110
    // Determine the next direction for the trails based off the last button press
278 Kevin 111
    if (controller < tron_data_p->players) {
112
        // Save the current button value
113
        tron_data_p->last_direction[controller] = value.w;
114
 
115
        // Grab the location of the head
116
        TRON_POINT next_pos = tron_data_p->body[controller][tron_data_p->length[controller] - 1];
117
 
118
        // Determine which next point to move to
119
        if (value.BTN_L_N || value.BTN_L_E) {   // Up
120
            next_pos.z = (next_pos.z == CUBE_LAYER_COUNT - 1) ? 0 : next_pos.z + 1;
121
        } else if (value.BTN_L_S || value.BTN_L_W) {    // Down
122
            next_pos.z = (next_pos.z == 0) ? CUBE_LAYER_COUNT - 1 : next_pos.z - 1;
123
        } else if (value.BTN_R_N) { // Forward
124
            next_pos.x = (next_pos.x == CUBE_ROW_COUNT - 1) ? 0 : next_pos.x + 1;
125
        } else if (value.BTN_R_W) { // Left
126
            next_pos.y = (next_pos.y == CUBE_COLUMN_COUNT - 1) ? 0 : next_pos.y + 1;
127
        } else if (value.BTN_R_S) { // Backwards
128
            next_pos.x = (next_pos.x == 0) ? CUBE_ROW_COUNT - 1 : next_pos.x - 1;
129
//        } else if (value.BTN_R_E) { // Right
130
        } else { // Right
131
            next_pos.y = (next_pos.y== 0) ? CUBE_COLUMN_COUNT - 1 : next_pos.y - 1;
241 Kevin 132
        }
278 Kevin 133
 
134
        // Save the next point to move to
135
        tron_data_p->direction[controller] = next_pos;
241 Kevin 136
    }
137
}
138
 
139
void Tron_Update_Frame(void) {
278 Kevin 140
    uint8_t player, player2;
141
 
142
    // Change the current head color to the body color
143
    for (player = 0; player < tron_data_p->players; player++) {
144
        if (tron_data_p->dead[player] == 0) {
145
            Cube_Set_Pixel(tron_data_p->body[player][tron_data_p->length[player] - 1].z,
146
                    tron_data_p->body[player][tron_data_p->length[player] - 1].x,
147
                    tron_data_p->body[player][tron_data_p->length[player] - 1].y,
148
                    tron_data_p->Color_Body_R[player],
149
                    tron_data_p->Color_Body_G[player],
150
                    tron_data_p->Color_Body_B[player]);
151
        }
241 Kevin 152
    }
153
 
278 Kevin 154
    // Check if there is a head-on collision between any of the players
155
    for (player = 0; player < tron_data_p->players; player++) {
156
        if (tron_data_p->dead[player] == 0) {
157
            for (player2 = 0; player2 < tron_data_p->players; player2++) {
158
                if (player2 == player) continue;
159
                if (tron_data_p->dead[player2] == 0) {
160
                    if (tron_data_p->direction[player].x == tron_data_p->direction[player2].x &&
161
                            tron_data_p->direction[player].y == tron_data_p->direction[player2].y &&
162
                            tron_data_p->direction[player].z == tron_data_p->direction[player2].z) {
163
                        // Indicate the collision point
164
                        Cube_Set_Pixel(tron_data_p->direction[player].z, tron_data_p->direction[player].x,
165
                                tron_data_p->direction[player].y, TRON_COLLISION);
166
                        // Mark the players as dead
167
                        tron_data_p->dead[player] = 1;
168
                        tron_data_p->dead[player2] = 1;
169
                        tron_data_p->players_alive -= 2;
170
                    }
171
                }
172
            }
173
        }
174
    }
175
 
241 Kevin 176
    // Check if the location that we are moving to is overlapping either trails
278 Kevin 177
    uint8_t index;
178
    for (player = 0; player < tron_data_p->players; player++) {
179
        // Check if the player in question is dead
180
        if (tron_data_p->dead[player] == 0) {
181
            // See if the player's next point hits anyone elses trail
182
            for (player2 = 0; player2 < tron_data_p->players; player2++) {
183
                for (index = 0; index < tron_data_p->length[player2]; index++) {
184
                    if (tron_data_p->direction[player].x == tron_data_p->body[player2][index].x &&
185
                            tron_data_p->direction[player].y == tron_data_p->body[player2][index].y &&
186
                            tron_data_p->direction[player].z == tron_data_p->body[player2][index].z) {
187
                        // Indicate the collision point
188
                        Cube_Set_Pixel(tron_data_p->direction[player].z, tron_data_p->direction[player].x,
189
                                tron_data_p->direction[player].y, TRON_COLLISION);
190
                        // Mark the player as dead
191
                        tron_data_p->dead[player] = 1;
192
                        tron_data_p->players_alive -= 1;
193
                    }
194
                }
195
            }
241 Kevin 196
        }
197
    }
198
 
199
    // Save the new head location of each trail
278 Kevin 200
    for (player = 0; player < tron_data_p->players; player++) {
201
        // If player is still alive, extend its body in the next direction
202
        if (tron_data_p->dead[player] == 0) {
203
            tron_data_p->length[player]++;
204
            tron_data_p->body[player][tron_data_p->length[player] - 1] = tron_data_p->direction[player];
205
        }
241 Kevin 206
    }
207
 
278 Kevin 208
    // Update the head to its corresponding color
209
    for (player = 0; player < tron_data_p->players; player++) {
210
        // If player is still alive, recolor its body to indicate its new head
211
        if (tron_data_p->dead[player] == 0) {
212
            // Set the color of the new head
213
            Cube_Set_Pixel(tron_data_p->body[player][tron_data_p->length[player] - 1].z,
214
                    tron_data_p->body[player][tron_data_p->length[player] - 1].x,
215
                    tron_data_p->body[player][tron_data_p->length[player] - 1].y,
216
                    tron_data_p->Color_Head_R[player],
217
                    tron_data_p->Color_Head_G[player],
218
                    tron_data_p->Color_Head_B[player]);
219
        }
241 Kevin 220
    }
221
 
278 Kevin 222
    // End the game if there is one player left alive
223
    if (tron_data_p->players_alive == 1) {
224
        Delay_MS(5000);
225
        // Determine which player is still alive and flash his color
226
        for (player = 0; player < tron_data_p->players; player++) {
227
            if (tron_data_p->dead[player] == 0) {
228
                Animation_Cube_In_Out(200, tron_data_p->Color_Head_R[player],
229
                        tron_data_p->Color_Head_G[player], tron_data_p->Color_Head_B[player]);
230
            }
231
        }
241 Kevin 232
        Reset_Board(BOARD_MODE_IDLE);
278 Kevin 233
    } else if (tron_data_p->players_alive == 0) {
234
        // If no players are alive flash neutral color
235
        Delay_MS(5000);
236
        Animation_Cube_In_Out(200, TRON_COLLISION_2);
237
        Reset_Board(BOARD_MODE_IDLE);
241 Kevin 238
    }
239
 
278 Kevin 240
    // Determine the next direction to move to for each player
241
    for (player = 0; player < tron_data_p->players; player++) {
242
        if (tron_data_p->dead[player] == 0) {
243
            Tron_Update_Direction(player, (CTRL_BTN_STATUS)tron_data_p->last_direction[player]);
244
        }
245
    }
241 Kevin 246
 
247
    // Decrease the delay between frame updates by 5ms
278 Kevin 248
    tron_data_p->delay -= 5;
241 Kevin 249
}