Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: N5110 SDFileSystem mbed
main.cpp@4:c2d920b17b14, 2016-04-27 (annotated)
- Committer:
- el14jw
- Date:
- Wed Apr 27 12:43:34 2016 +0000
- Revision:
- 4:c2d920b17b14
- Parent:
- 3:02d9072a2507
- Child:
- 5:ae641b1d04fa
- Added Score displayed to plink game
Who changed what in which revision?
| User | Revision | Line number | New contents of line | 
|---|---|---|---|
| el14jw | 0:23a749719479 | 1 | /** | 
| el14jw | 0:23a749719479 | 2 | 2645 Project Games | 
| el14jw | 0:23a749719479 | 3 | @file main.cpp | 
| el14jw | 0:23a749719479 | 4 | |
| el14jw | 0:23a749719479 | 5 | @brief Program Implementation | 
| el14jw | 0:23a749719479 | 6 | @brief Revision 1.0 | 
| el14jw | 0:23a749719479 | 7 | @author Joel W. Webb | 
| el14jw | 0:23a749719479 | 8 | */ | 
| el14jw | 0:23a749719479 | 9 | |
| el14jw | 0:23a749719479 | 10 | #include "main.h" | 
| el14jw | 0:23a749719479 | 11 | |
| el14jw | 0:23a749719479 | 12 | |
| el14jw | 0:23a749719479 | 13 | // Joystick Polling code taken from joystick example code | 
| el14jw | 0:23a749719479 | 14 | /// Enumerated type to store joystick direction | 
| el14jw | 0:23a749719479 | 15 | enum DirectionName { | 
| el14jw | 0:23a749719479 | 16 | UP, | 
| el14jw | 0:23a749719479 | 17 | DOWN, | 
| el14jw | 0:23a749719479 | 18 | LEFT, | 
| el14jw | 0:23a749719479 | 19 | RIGHT, | 
| el14jw | 0:23a749719479 | 20 | CENTRE, | 
| el14jw | 0:23a749719479 | 21 | UNKNOWN | 
| el14jw | 0:23a749719479 | 22 | }; | 
| el14jw | 0:23a749719479 | 23 | |
| el14jw | 0:23a749719479 | 24 | /// Struct for storing data about default Joystick position and Current position | 
| el14jw | 0:23a749719479 | 25 | struct JoyStick { | 
| el14jw | 0:23a749719479 | 26 | float x; // current x value | 
| el14jw | 0:23a749719479 | 27 | float x0; // 'centred' x value | 
| el14jw | 0:23a749719479 | 28 | float y; // current y value | 
| el14jw | 0:23a749719479 | 29 | float y0; // 'centred' y value | 
| el14jw | 0:23a749719479 | 30 | DirectionName direction; // current direction | 
| el14jw | 0:23a749719479 | 31 | }; | 
| el14jw | 0:23a749719479 | 32 | typedef struct JoyStick Joystick; | 
| el14jw | 0:23a749719479 | 33 | /// Joystick struct for storing data about default Joystick position and Current position | 
| el14jw | 0:23a749719479 | 34 | Joystick joystick; | 
| el14jw | 0:23a749719479 | 35 | /// Ticker interrput for polling the joystick | 
| el14jw | 0:23a749719479 | 36 | Ticker pollJoystick; | 
| el14jw | 4:c2d920b17b14 | 37 | /// Ticker for controlling refresh rate of games | 
| el14jw | 2:80a91a737e17 | 38 | Ticker gametick; | 
| el14jw | 4:c2d920b17b14 | 39 | /// File pointer for accessing SD card locations | 
| el14jw | 1:c4928de1f922 | 40 | FILE *fp; | 
| el14jw | 0:23a749719479 | 41 | |
| el14jw | 0:23a749719479 | 42 | |
| el14jw | 0:23a749719479 | 43 | int main() | 
| el14jw | 0:23a749719479 | 44 | { | 
| el14jw | 0:23a749719479 | 45 | initInputs(); | 
| el14jw | 0:23a749719479 | 46 | playSound(tune_intro); | 
| el14jw | 1:c4928de1f922 | 47 | // Initialise file pointer | 
| el14jw | 0:23a749719479 | 48 | |
| el14jw | 4:c2d920b17b14 | 49 | int snakeDifficulty = 1; | 
| el14jw | 1:c4928de1f922 | 50 | int plinkDifficulty = 0; | 
| el14jw | 0:23a749719479 | 51 | while (true) { | 
| el14jw | 1:c4928de1f922 | 52 | |
| el14jw | 0:23a749719479 | 53 | // Main menu screen | 
| el14jw | 1:c4928de1f922 | 54 | int select = menu(menuList,3); | 
| el14jw | 0:23a749719479 | 55 | |
| el14jw | 0:23a749719479 | 56 | // Selected Snake | 
| el14jw | 0:23a749719479 | 57 | if (select == 0) { | 
| el14jw | 1:c4928de1f922 | 58 | // If select = 3 or -1 then user has chosen 'Back' button | 
| el14jw | 1:c4928de1f922 | 59 | while( !(select == 3 || select ==-1) ) { | 
| el14jw | 0:23a749719479 | 60 | |
| el14jw | 0:23a749719479 | 61 | // Snake selection screen | 
| el14jw | 1:c4928de1f922 | 62 | select = menu(snakeList,5); | 
| el14jw | 1:c4928de1f922 | 63 | if (select == 0) { | 
| el14jw | 1:c4928de1f922 | 64 | // Play Snake game | 
| el14jw | 1:c4928de1f922 | 65 | snake(snakeDifficulty); | 
| el14jw | 1:c4928de1f922 | 66 | } | 
| el14jw | 0:23a749719479 | 67 | // Selected Difficulty | 
| el14jw | 1:c4928de1f922 | 68 | else if (select == 1) { | 
| el14jw | 0:23a749719479 | 69 | // Difficulty selection screen | 
| el14jw | 1:c4928de1f922 | 70 | int tempdiff = snakeDifficulty; | 
| el14jw | 1:c4928de1f922 | 71 | snakeDifficulty = menu(difficultyList,4); | 
| el14jw | 1:c4928de1f922 | 72 | if (snakeDifficulty == -1) { | 
| el14jw | 1:c4928de1f922 | 73 | snakeDifficulty = tempdiff; | 
| el14jw | 1:c4928de1f922 | 74 | } | 
| el14jw | 0:23a749719479 | 75 | } | 
| el14jw | 1:c4928de1f922 | 76 | // Highscore | 
| el14jw | 1:c4928de1f922 | 77 | else if (select == 2) { | 
| el14jw | 1:c4928de1f922 | 78 | fp = fopen("/sd/snakehighscore.txt", "r"); | 
| el14jw | 1:c4928de1f922 | 79 | wait(0.05); | 
| el14jw | 1:c4928de1f922 | 80 | int stored_top_score = -1; // -1 to demonstrate it has changed after reading | 
| el14jw | 1:c4928de1f922 | 81 | |
| el14jw | 1:c4928de1f922 | 82 | lcd.clear(); | 
| el14jw | 1:c4928de1f922 | 83 | if (fp == NULL) { // if it can't open the file then print error message | 
| el14jw | 1:c4928de1f922 | 84 | lcd.printString("No Results",0,0); | 
| el14jw | 1:c4928de1f922 | 85 | wait(2.0); | 
| el14jw | 1:c4928de1f922 | 86 | } else { // opened file so can write | 
| el14jw | 1:c4928de1f922 | 87 | while ( ! (g_buttonA_flag || g_buttonjoy_flag)) { | 
| el14jw | 1:c4928de1f922 | 88 | fscanf(fp,"%d",&stored_top_score); // ensure data type matches - note address operator (&) | 
| el14jw | 1:c4928de1f922 | 89 | fclose(fp); // ensure you close the file after reading | 
| el14jw | 1:c4928de1f922 | 90 | lcd.printString("Highscore:",10,0); | 
| el14jw | 1:c4928de1f922 | 91 | if (stored_top_score != -2) { | 
| el14jw | 1:c4928de1f922 | 92 | char buffer[14]; | 
| el14jw | 1:c4928de1f922 | 93 | sprintf(buffer,"%d",stored_top_score); | 
| el14jw | 1:c4928de1f922 | 94 | lcd.printString(buffer,0,1); | 
| el14jw | 1:c4928de1f922 | 95 | } else { | 
| el14jw | 1:c4928de1f922 | 96 | lcd.printString("No Saved Score",0,1); | 
| el14jw | 1:c4928de1f922 | 97 | } | 
| el14jw | 1:c4928de1f922 | 98 | lcd.printString(">> Back",0,2); | 
| el14jw | 1:c4928de1f922 | 99 | sleep(); | 
| el14jw | 1:c4928de1f922 | 100 | } | 
| el14jw | 1:c4928de1f922 | 101 | g_buttonjoy_flag = 0; | 
| el14jw | 1:c4928de1f922 | 102 | g_buttonA_flag = 0; | 
| el14jw | 1:c4928de1f922 | 103 | } | 
| el14jw | 1:c4928de1f922 | 104 | } | 
| el14jw | 1:c4928de1f922 | 105 | |
| el14jw | 0:23a749719479 | 106 | } | 
| el14jw | 0:23a749719479 | 107 | } | 
| el14jw | 0:23a749719479 | 108 | |
| el14jw | 1:c4928de1f922 | 109 | // Selected Plink | 
| el14jw | 0:23a749719479 | 110 | else if (select == 1) { | 
| el14jw | 1:c4928de1f922 | 111 | // If select = 3 or -1 then user has chosen 'Back' button | 
| el14jw | 1:c4928de1f922 | 112 | while( !(select == 3 || select ==-1) ) { | 
| el14jw | 0:23a749719479 | 113 | |
| el14jw | 1:c4928de1f922 | 114 | select = menu(plinkList,5); | 
| el14jw | 1:c4928de1f922 | 115 | // Start Plink | 
| el14jw | 1:c4928de1f922 | 116 | if (select == 0) { | 
| el14jw | 0:23a749719479 | 117 | playSound(tune_intro); | 
| el14jw | 1:c4928de1f922 | 118 | plink(plinkDifficulty); | 
| el14jw | 1:c4928de1f922 | 119 | } | 
| el14jw | 1:c4928de1f922 | 120 | // Difficulty selection | 
| el14jw | 1:c4928de1f922 | 121 | else if (select == 1) { | 
| el14jw | 1:c4928de1f922 | 122 | int tempdiff = plinkDifficulty; | 
| el14jw | 1:c4928de1f922 | 123 | plinkDifficulty = menu(difficultyList,4); | 
| el14jw | 1:c4928de1f922 | 124 | if (plinkDifficulty == -1) { | 
| el14jw | 1:c4928de1f922 | 125 | plinkDifficulty = tempdiff; | 
| el14jw | 1:c4928de1f922 | 126 | } | 
| el14jw | 1:c4928de1f922 | 127 | } | 
| el14jw | 1:c4928de1f922 | 128 | // Highscore | 
| el14jw | 1:c4928de1f922 | 129 | else if (select == 2) { | 
| el14jw | 1:c4928de1f922 | 130 | fp = fopen("/sd/plinkhighscore.txt", "r"); | 
| el14jw | 1:c4928de1f922 | 131 | wait(0.05); | 
| el14jw | 1:c4928de1f922 | 132 | int stored_top_score = -2; // -2 to demonstrate it has changed after reading | 
| el14jw | 1:c4928de1f922 | 133 | |
| el14jw | 1:c4928de1f922 | 134 | lcd.clear(); | 
| el14jw | 1:c4928de1f922 | 135 | if (fp == NULL) { // if it can't open the file then print error message | 
| el14jw | 1:c4928de1f922 | 136 | lcd.printString("No Results",0,0); | 
| el14jw | 1:c4928de1f922 | 137 | wait(2.0); | 
| el14jw | 1:c4928de1f922 | 138 | } else { // opened file so can read | 
| el14jw | 1:c4928de1f922 | 139 | while ( ! (g_buttonA_flag || g_buttonjoy_flag)) { | 
| el14jw | 1:c4928de1f922 | 140 | fscanf(fp,"%d",&stored_top_score); // ensure data type matches - note address operator (&) | 
| el14jw | 1:c4928de1f922 | 141 | fclose(fp); // ensure you close the file after reading | 
| el14jw | 1:c4928de1f922 | 142 | lcd.printString("Highscore",10,0); | 
| el14jw | 1:c4928de1f922 | 143 | if (stored_top_score !=-2) { | 
| el14jw | 1:c4928de1f922 | 144 | char buffer[14]; | 
| el14jw | 1:c4928de1f922 | 145 | sprintf(buffer,"%d",stored_top_score); | 
| el14jw | 1:c4928de1f922 | 146 | lcd.printString(buffer,0,1); | 
| el14jw | 1:c4928de1f922 | 147 | } else { | 
| el14jw | 1:c4928de1f922 | 148 | lcd.printString("No Saved Score",0,1); | 
| el14jw | 1:c4928de1f922 | 149 | } | 
| el14jw | 1:c4928de1f922 | 150 | lcd.printString(">> Back",0,2); | 
| el14jw | 1:c4928de1f922 | 151 | sleep(); | 
| el14jw | 1:c4928de1f922 | 152 | } | 
| el14jw | 1:c4928de1f922 | 153 | g_buttonjoy_flag = 0; | 
| el14jw | 1:c4928de1f922 | 154 | g_buttonA_flag = 0; | 
| el14jw | 1:c4928de1f922 | 155 | } | 
| el14jw | 0:23a749719479 | 156 | } | 
| el14jw | 0:23a749719479 | 157 | } | 
| el14jw | 0:23a749719479 | 158 | } | 
| el14jw | 0:23a749719479 | 159 | |
| el14jw | 0:23a749719479 | 160 | sleep(); | 
| el14jw | 0:23a749719479 | 161 | } | 
| el14jw | 0:23a749719479 | 162 | |
| el14jw | 0:23a749719479 | 163 | } | 
| el14jw | 0:23a749719479 | 164 | |
| el14jw | 0:23a749719479 | 165 | |
| el14jw | 1:c4928de1f922 | 166 | // SNAKE | 
| el14jw | 0:23a749719479 | 167 | |
| el14jw | 0:23a749719479 | 168 | void snake(int difficulty) | 
| el14jw | 0:23a749719479 | 169 | { | 
| el14jw | 0:23a749719479 | 170 | // Play the snake intro tune | 
| el14jw | 0:23a749719479 | 171 | playSound(tune_snakeintro); | 
| el14jw | 0:23a749719479 | 172 | // Creates an array for storing the snake body x and y data. The snake can be up to 880 cells long | 
| el14jw | 0:23a749719479 | 173 | cell snake[880]; | 
| el14jw | 1:c4928de1f922 | 174 | // Clears data from previous games | 
| el14jw | 1:c4928de1f922 | 175 | for (int i=0; i<880; i++) { | 
| el14jw | 1:c4928de1f922 | 176 | snake[i].x = 0; | 
| el14jw | 1:c4928de1f922 | 177 | snake[i].y = 0; | 
| el14jw | 1:c4928de1f922 | 178 | } | 
| el14jw | 1:c4928de1f922 | 179 | |
| el14jw | 0:23a749719479 | 180 | cell food; | 
| el14jw | 0:23a749719479 | 181 | // Starting length is 5 cells | 
| el14jw | 0:23a749719479 | 182 | int length = 5; | 
| el14jw | 0:23a749719479 | 183 | // Starting 5 cells are x = 20 and y = 11,12,13,14 and 15 | 
| el14jw | 0:23a749719479 | 184 | for (int i=0; i<length; i++) { | 
| el14jw | 0:23a749719479 | 185 | snake[i].x = 20; | 
| el14jw | 0:23a749719479 | 186 | snake[i].y = 11+i; | 
| el14jw | 0:23a749719479 | 187 | } | 
| el14jw | 0:23a749719479 | 188 | |
| el14jw | 0:23a749719479 | 189 | // Creates timer based on how hard you set the difficulty (default Medium) | 
| el14jw | 0:23a749719479 | 190 | gametick.attach(&gametick_isr,(0.4-(difficulty*0.15))); | 
| el14jw | 0:23a749719479 | 191 | // Initialise the snake_direction parameter as UP | 
| el14jw | 0:23a749719479 | 192 | DirectionName snake_direction = UP; | 
| el14jw | 0:23a749719479 | 193 | // Set the game over condition before while loop | 
| el14jw | 0:23a749719479 | 194 | int gameOver = 0; | 
| el14jw | 0:23a749719479 | 195 | |
| el14jw | 1:c4928de1f922 | 196 | // Create the random food location flag (0 if food needs to be randomised and 1 if food still exists) | 
| el14jw | 0:23a749719479 | 197 | int rand_food = 0; | 
| el14jw | 0:23a749719479 | 198 | |
| el14jw | 0:23a749719479 | 199 | while(!gameOver) { | 
| el14jw | 0:23a749719479 | 200 | // When the game ticker updates | 
| el14jw | 0:23a749719479 | 201 | if (g_gametick_flag) { | 
| el14jw | 0:23a749719479 | 202 | // Reset the ticker flag | 
| el14jw | 0:23a749719479 | 203 | g_gametick_flag = 0; | 
| el14jw | 1:c4928de1f922 | 204 | |
| el14jw | 0:23a749719479 | 205 | // If the current snake_direction is the opposite of the joystick direction or the joystick direction is centerd or unknown then keep current direction | 
| el14jw | 0:23a749719479 | 206 | if ( !( (snake_direction == UP && joystick.direction == DOWN) || | 
| el14jw | 0:23a749719479 | 207 | (snake_direction == DOWN && joystick.direction == UP) || | 
| el14jw | 0:23a749719479 | 208 | (snake_direction == LEFT && joystick.direction == RIGHT) || | 
| el14jw | 0:23a749719479 | 209 | (snake_direction == RIGHT && joystick.direction == LEFT) || | 
| el14jw | 0:23a749719479 | 210 | (joystick.direction == CENTRE || joystick.direction == UNKNOWN) )) { | 
| el14jw | 0:23a749719479 | 211 | snake_direction = joystick.direction; | 
| el14jw | 0:23a749719479 | 212 | } | 
| el14jw | 0:23a749719479 | 213 | // Iterate through array and move each cell backwards as far as the length of the snake | 
| el14jw | 0:23a749719479 | 214 | for (int i=(length-1); i>0; i--) { | 
| el14jw | 0:23a749719479 | 215 | snake[i] = snake[i-1]; | 
| el14jw | 0:23a749719479 | 216 | } | 
| el14jw | 0:23a749719479 | 217 | // Then change the x or y coordinate of the first cell of the snake depending on which direction it is moving in | 
| el14jw | 0:23a749719479 | 218 | switch(snake_direction) { | 
| el14jw | 0:23a749719479 | 219 | case UP: | 
| el14jw | 0:23a749719479 | 220 | snake[0].y = snake[0].y - 1; | 
| el14jw | 0:23a749719479 | 221 | break; | 
| el14jw | 0:23a749719479 | 222 | case DOWN: | 
| el14jw | 0:23a749719479 | 223 | snake[0].y = snake[0].y + 1; | 
| el14jw | 0:23a749719479 | 224 | break; | 
| el14jw | 0:23a749719479 | 225 | case LEFT: | 
| el14jw | 0:23a749719479 | 226 | snake[0].x = snake[0].x - 1; | 
| el14jw | 0:23a749719479 | 227 | break; | 
| el14jw | 0:23a749719479 | 228 | case RIGHT: | 
| el14jw | 0:23a749719479 | 229 | snake[0].x = snake[0].x + 1; | 
| el14jw | 0:23a749719479 | 230 | break; | 
| el14jw | 0:23a749719479 | 231 | default: | 
| el14jw | 0:23a749719479 | 232 | error(); | 
| el14jw | 0:23a749719479 | 233 | } | 
| el14jw | 0:23a749719479 | 234 | |
| el14jw | 0:23a749719479 | 235 | // If snake hits wall then game over | 
| el14jw | 0:23a749719479 | 236 | if ( (snake[0].x == 41) || (snake[0].x == 0) || (snake[0].y == 23) || (snake[0].y == 0 ) ) { | 
| el14jw | 0:23a749719479 | 237 | gameOver = 1; | 
| el14jw | 0:23a749719479 | 238 | } | 
| el14jw | 0:23a749719479 | 239 | // If snake hits self then game over | 
| el14jw | 0:23a749719479 | 240 | for (int i=1; i<length; i++) { | 
| el14jw | 0:23a749719479 | 241 | if (snake[0].x == snake[i].x && snake[0].y == snake[i].y) { | 
| el14jw | 0:23a749719479 | 242 | gameOver = 1; | 
| el14jw | 0:23a749719479 | 243 | } | 
| el14jw | 0:23a749719479 | 244 | } | 
| el14jw | 1:c4928de1f922 | 245 | |
| el14jw | 0:23a749719479 | 246 | // If the snake head is at the same value of x and y as the food then play tune and increase length by 2 | 
| el14jw | 0:23a749719479 | 247 | if (food.x == snake[0].x && food.y == snake[0].y) { | 
| el14jw | 0:23a749719479 | 248 | playSound(tune_snakeEat); | 
| el14jw | 0:23a749719479 | 249 | length += 2; | 
| el14jw | 0:23a749719479 | 250 | // Also set new random food to be generated | 
| el14jw | 0:23a749719479 | 251 | rand_food = 0; | 
| el14jw | 0:23a749719479 | 252 | } | 
| el14jw | 1:c4928de1f922 | 253 | |
| el14jw | 0:23a749719479 | 254 | // Create a random location for the food that is not the same as a snake location | 
| el14jw | 0:23a749719479 | 255 | while(rand_food == 0) { | 
| el14jw | 0:23a749719479 | 256 | rand_food = 1; | 
| el14jw | 0:23a749719479 | 257 | food.x = rand(); | 
| el14jw | 0:23a749719479 | 258 | food.x = food.x %40 +1; | 
| el14jw | 0:23a749719479 | 259 | food.y = rand(); | 
| el14jw | 0:23a749719479 | 260 | food.y = food.y %22 +1; | 
| el14jw | 0:23a749719479 | 261 | for (int i=0; i<length; i++) { | 
| el14jw | 0:23a749719479 | 262 | if(food.x == snake[i].x && food.y == snake[i].y) { | 
| el14jw | 0:23a749719479 | 263 | rand_food = 0; | 
| el14jw | 0:23a749719479 | 264 | } | 
| el14jw | 0:23a749719479 | 265 | } | 
| el14jw | 0:23a749719479 | 266 | } | 
| el14jw | 1:c4928de1f922 | 267 | |
| el14jw | 1:c4928de1f922 | 268 | // Drawing Display | 
| el14jw | 1:c4928de1f922 | 269 | lcd.clear(); | 
| el14jw | 1:c4928de1f922 | 270 | // Draws Boundary 2 thick | 
| el14jw | 1:c4928de1f922 | 271 | lcd.drawRect(0,0,83,47,0); | 
| el14jw | 1:c4928de1f922 | 272 | lcd.drawRect(1,1,81,45,0); | 
| el14jw | 1:c4928de1f922 | 273 | // Draws snake | 
| el14jw | 1:c4928de1f922 | 274 | for (int i=0; i<length; i++) { | 
| el14jw | 1:c4928de1f922 | 275 | lcd.drawRect(snake[i].x*2,snake[i].y*2,1,1,1); | 
| el14jw | 1:c4928de1f922 | 276 | } | 
| el14jw | 1:c4928de1f922 | 277 | // Draws food | 
| el14jw | 1:c4928de1f922 | 278 | lcd.drawRect(food.x*2,food.y*2,1,1,1); | 
| el14jw | 0:23a749719479 | 279 | lcd.refresh(); | 
| el14jw | 1:c4928de1f922 | 280 | |
| el14jw | 0:23a749719479 | 281 | } | 
| el14jw | 0:23a749719479 | 282 | sleep(); | 
| el14jw | 0:23a749719479 | 283 | } | 
| el14jw | 1:c4928de1f922 | 284 | // End game ticker | 
| el14jw | 1:c4928de1f922 | 285 | gametick.detach(); | 
| el14jw | 1:c4928de1f922 | 286 | int score = length -5; // length -5 because starting length is 5 and a score without collecting anything should be 0 | 
| el14jw | 1:c4928de1f922 | 287 | lcd.clear(); | 
| el14jw | 2:80a91a737e17 | 288 | |
| el14jw | 1:c4928de1f922 | 289 | // Read previous highscore if one exists | 
| el14jw | 1:c4928de1f922 | 290 | fp = fopen("/sd/snakehighscore.txt", "r"); | 
| el14jw | 1:c4928de1f922 | 291 | int current_high_score = -1; // -1 to demonstrate it has changed after reading | 
| el14jw | 1:c4928de1f922 | 292 | |
| el14jw | 1:c4928de1f922 | 293 | if (fp == NULL) { // if it can't open the file then print error message | 
| el14jw | 1:c4928de1f922 | 294 | lcd.printString("Failed Read",0,5); | 
| el14jw | 1:c4928de1f922 | 295 | } else { // opened file so can write | 
| el14jw | 1:c4928de1f922 | 296 | fscanf(fp,"%d",¤t_high_score); // ensure data type matches - note address operator (&) | 
| el14jw | 1:c4928de1f922 | 297 | fclose(fp); // ensure you close the file after reading | 
| el14jw | 1:c4928de1f922 | 298 | } | 
| el14jw | 1:c4928de1f922 | 299 | |
| el14jw | 1:c4928de1f922 | 300 | // Writing score to sd card if new high score | 
| el14jw | 1:c4928de1f922 | 301 | if (current_high_score < score && current_high_score != -1) { | 
| el14jw | 1:c4928de1f922 | 302 | fp = fopen("/sd/snakehighscore.txt", "w"); | 
| el14jw | 1:c4928de1f922 | 303 | if (fp == NULL) { // if it can't open the file then print error message | 
| el14jw | 1:c4928de1f922 | 304 | lcd.printString("No SD Card",0,5); | 
| el14jw | 1:c4928de1f922 | 305 | } else { // opened file so can write | 
| el14jw | 1:c4928de1f922 | 306 | fprintf(fp,"%d",score); // ensure data type matches | 
| el14jw | 1:c4928de1f922 | 307 | fclose(fp); // ensure you close the file after writing | 
| el14jw | 1:c4928de1f922 | 308 | } | 
| el14jw | 1:c4928de1f922 | 309 | } | 
| el14jw | 1:c4928de1f922 | 310 | |
| el14jw | 1:c4928de1f922 | 311 | // Appropriate strings printed to LCD | 
| el14jw | 1:c4928de1f922 | 312 | lcd.printString("Game Over",20,0); | 
| el14jw | 1:c4928de1f922 | 313 | if (current_high_score != -1 && current_high_score < score) { | 
| el14jw | 1:c4928de1f922 | 314 | lcd.printString("New High Score",0,1); | 
| el14jw | 1:c4928de1f922 | 315 | lcd.printString("Previously",0,3); | 
| el14jw | 1:c4928de1f922 | 316 | } else if (current_high_score != -1 && current_high_score > score) { | 
| el14jw | 1:c4928de1f922 | 317 | lcd.printString("Score",0,1); | 
| el14jw | 1:c4928de1f922 | 318 | lcd.printString("High Score",0,3); | 
| el14jw | 1:c4928de1f922 | 319 | } else { | 
| el14jw | 1:c4928de1f922 | 320 | lcd.printString("Score:",0,1); | 
| el14jw | 1:c4928de1f922 | 321 | lcd.printString("No Previous",0,3); | 
| el14jw | 1:c4928de1f922 | 322 | } | 
| el14jw | 1:c4928de1f922 | 323 | // Print score | 
| el14jw | 1:c4928de1f922 | 324 | char buffer[14]; | 
| el14jw | 1:c4928de1f922 | 325 | sprintf(buffer,"%d",score); | 
| el14jw | 1:c4928de1f922 | 326 | lcd.printString(buffer,20,2); | 
| el14jw | 1:c4928de1f922 | 327 | // Print previous high-score | 
| el14jw | 1:c4928de1f922 | 328 | if (current_high_score != -1) { | 
| el14jw | 1:c4928de1f922 | 329 | char str[14]; | 
| el14jw | 1:c4928de1f922 | 330 | sprintf(str,"%d",current_high_score); | 
| el14jw | 1:c4928de1f922 | 331 | lcd.printString(str,20,4); | 
| el14jw | 1:c4928de1f922 | 332 | } | 
| el14jw | 1:c4928de1f922 | 333 | |
| el14jw | 0:23a749719479 | 334 | playSound(tune_gameOver); | 
| el14jw | 0:23a749719479 | 335 | wait(3.0); | 
| el14jw | 0:23a749719479 | 336 | g_buttonA_flag = 0; | 
| el14jw | 1:c4928de1f922 | 337 | g_buttonB_flag = 0; | 
| el14jw | 0:23a749719479 | 338 | g_buttonjoy_flag = 0; | 
| el14jw | 0:23a749719479 | 339 | } | 
| el14jw | 1:c4928de1f922 | 340 | |
| el14jw | 1:c4928de1f922 | 341 | |
| el14jw | 1:c4928de1f922 | 342 | // PLINK | 
| el14jw | 1:c4928de1f922 | 343 | |
| el14jw | 1:c4928de1f922 | 344 | void plink(int difficulty) | 
| el14jw | 0:23a749719479 | 345 | { | 
| el14jw | 1:c4928de1f922 | 346 | playSound(tune_plinkintro); | 
| el14jw | 1:c4928de1f922 | 347 | lcd.clear(); | 
| el14jw | 3:02d9072a2507 | 348 | // Instead of damaging the program flow with global variables I pass a struct full of variables from one plink function to another. | 
| el14jw | 1:c4928de1f922 | 349 | |
| el14jw | 3:02d9072a2507 | 350 | plinkvar pvar; | 
| el14jw | 3:02d9072a2507 | 351 | pvar.difficulty = difficulty; | 
| el14jw | 2:80a91a737e17 | 352 | |
| el14jw | 3:02d9072a2507 | 353 | // Initialise plink variables | 
| el14jw | 3:02d9072a2507 | 354 | pvar = initpvar(pvar); | 
| el14jw | 1:c4928de1f922 | 355 | |
| el14jw | 2:80a91a737e17 | 356 | // Game ticker | 
| el14jw | 1:c4928de1f922 | 357 | int refreshRate = 100; | 
| el14jw | 1:c4928de1f922 | 358 | float tickerDelay = 1.0/refreshRate; | 
| el14jw | 3:02d9072a2507 | 359 | pvar.tickerDelay = tickerDelay; | 
| el14jw | 1:c4928de1f922 | 360 | gametick.attach(&gametick_isr,tickerDelay); | 
| el14jw | 3:02d9072a2507 | 361 | wait(0.25); | 
| el14jw | 2:80a91a737e17 | 362 | |
| el14jw | 3:02d9072a2507 | 363 | while(!pvar.gameOver) { | 
| el14jw | 1:c4928de1f922 | 364 | if (g_gametick_flag) { | 
| el14jw | 1:c4928de1f922 | 365 | |
| el14jw | 1:c4928de1f922 | 366 | // Screen scrolling | 
| el14jw | 3:02d9072a2507 | 367 | pvar = plinkScroll(pvar); | 
| el14jw | 1:c4928de1f922 | 368 | // Platform generation | 
| el14jw | 3:02d9072a2507 | 369 | pvar = plinkPlatGen(pvar); | 
| el14jw | 1:c4928de1f922 | 370 | // Collisions | 
| el14jw | 3:02d9072a2507 | 371 | pvar = plinkCollisions(pvar); | 
| el14jw | 3:02d9072a2507 | 372 | // Physics Engine | 
| el14jw | 3:02d9072a2507 | 373 | pvar = plinkPhysicsEngine(pvar); | 
| el14jw | 3:02d9072a2507 | 374 | // LCD drawing | 
| el14jw | 3:02d9072a2507 | 375 | pvar = plinkDrawScreen(pvar); | 
| el14jw | 1:c4928de1f922 | 376 | |
| el14jw | 1:c4928de1f922 | 377 | } | 
| el14jw | 3:02d9072a2507 | 378 | // Sleep to conserve power until next interrupt | 
| el14jw | 3:02d9072a2507 | 379 | sleep(); | 
| el14jw | 0:23a749719479 | 380 | } | 
| el14jw | 1:c4928de1f922 | 381 | |
| el14jw | 1:c4928de1f922 | 382 | gametick.detach(); | 
| el14jw | 1:c4928de1f922 | 383 | lcd.clear(); | 
| el14jw | 4:c2d920b17b14 | 384 | |
| el14jw | 4:c2d920b17b14 | 385 | // Handle high scores and printing game over messages to LCD | 
| el14jw | 3:02d9072a2507 | 386 | pvar = plinkGameOver(pvar); | 
| el14jw | 4:c2d920b17b14 | 387 | |
| el14jw | 4:c2d920b17b14 | 388 | } | 
| el14jw | 3:02d9072a2507 | 389 | |
| el14jw | 3:02d9072a2507 | 390 | plinkvar initpvar(plinkvar pvar) | 
| el14jw | 3:02d9072a2507 | 391 | { | 
| el14jw | 3:02d9072a2507 | 392 | // Initial physics conditions | 
| el14jw | 3:02d9072a2507 | 393 | vector pos = {41,47}; | 
| el14jw | 3:02d9072a2507 | 394 | vector vel = {0,-25}; | 
| el14jw | 3:02d9072a2507 | 395 | vector acc = {0,10}; | 
| el14jw | 3:02d9072a2507 | 396 | pvar.pos = pos; | 
| el14jw | 3:02d9072a2507 | 397 | pvar.vel = vel; | 
| el14jw | 3:02d9072a2507 | 398 | pvar.acc = acc; | 
| el14jw | 3:02d9072a2507 | 399 | |
| el14jw | 3:02d9072a2507 | 400 | // Initialising game parameters | 
| el14jw | 3:02d9072a2507 | 401 | pvar.height = 0; // This is the number of pixels that the lcd has 'scrolled' by | 
| el14jw | 3:02d9072a2507 | 402 | pvar.gameOver = 0; // When something consitutes a game over parameter this is set to 1 and the while loop is broken out of | 
| el14jw | 3:02d9072a2507 | 403 | pvar.platformWidth = 7 - (pvar.difficulty * 2); // Platform width is based on difficulty and also changed by power ups | 
| el14jw | 3:02d9072a2507 | 404 | cell powerUp = {42,-100}; // The first power up can be found at these coordinates | 
| el14jw | 3:02d9072a2507 | 405 | pvar.powerUp = powerUp; | 
| el14jw | 3:02d9072a2507 | 406 | pvar.powerUpHeight = 0; // This parameter keeps tabs on the number of pixels scrolled while a power up is active (after 100 picels the power up wears off) | 
| el14jw | 3:02d9072a2507 | 407 | pvar.powerUpRadius = 5; // Helpful parameter for detecting collisions | 
| el14jw | 3:02d9072a2507 | 408 | pvar.ballRadius = 2; // Also helpful parameter for detecting collisions and is changed in 2 power up cases | 
| el14jw | 3:02d9072a2507 | 409 | |
| el14jw | 3:02d9072a2507 | 410 | // Initialising platforms | 
| el14jw | 3:02d9072a2507 | 411 | pvar.platforms[0].x = 42; | 
| el14jw | 3:02d9072a2507 | 412 | pvar.platforms[0].y = 46; | 
| el14jw | 3:02d9072a2507 | 413 | for (int i=1; i<20; i++) { | 
| el14jw | 3:02d9072a2507 | 414 | pvar.platforms[i].x = rand()%(84-pvar.platformWidth) + (pvar.platformWidth-1)/2; | 
| el14jw | 3:02d9072a2507 | 415 | pvar.platforms[i].y = pvar.platforms[i-1].y - (rand()%10 + 5); | 
| el14jw | 3:02d9072a2507 | 416 | } | 
| el14jw | 3:02d9072a2507 | 417 | |
| el14jw | 3:02d9072a2507 | 418 | return pvar; | 
| el14jw | 3:02d9072a2507 | 419 | } | 
| el14jw | 3:02d9072a2507 | 420 | plinkvar plinkScroll(plinkvar pvar) | 
| el14jw | 3:02d9072a2507 | 421 | { | 
| el14jw | 3:02d9072a2507 | 422 | // Scrolling Block | 
| el14jw | 3:02d9072a2507 | 423 | while (pvar.pos.y < 14) { | 
| el14jw | 3:02d9072a2507 | 424 | pvar.pos.y++; | 
| el14jw | 3:02d9072a2507 | 425 | pvar.height++; | 
| el14jw | 3:02d9072a2507 | 426 | pvar.powerUpHeight++; | 
| el14jw | 3:02d9072a2507 | 427 | for (int i=0; i<20; i++) { | 
| el14jw | 3:02d9072a2507 | 428 | pvar.platforms[i].y++; | 
| el14jw | 3:02d9072a2507 | 429 | } | 
| el14jw | 3:02d9072a2507 | 430 | pvar.powerUp.y++; | 
| el14jw | 3:02d9072a2507 | 431 | } | 
| el14jw | 3:02d9072a2507 | 432 | return pvar; | 
| el14jw | 3:02d9072a2507 | 433 | } | 
| el14jw | 3:02d9072a2507 | 434 | plinkvar plinkPlatGen(plinkvar pvar) | 
| el14jw | 3:02d9072a2507 | 435 | { | 
| el14jw | 3:02d9072a2507 | 436 | // Platform generation | 
| el14jw | 3:02d9072a2507 | 437 | for (int i=0; i<20; i++) { | 
| el14jw | 3:02d9072a2507 | 438 | if (pvar.platforms[i].y > 47) { | 
| el14jw | 3:02d9072a2507 | 439 | // Stage 1 | 
| el14jw | 3:02d9072a2507 | 440 | if (pvar.height <= 500) { | 
| el14jw | 3:02d9072a2507 | 441 | if (i == 0) { | 
| el14jw | 3:02d9072a2507 | 442 | pvar.platforms[0].x = rand()%(84-pvar.platformWidth) + (pvar.platformWidth-1)/2; | 
| el14jw | 3:02d9072a2507 | 443 | pvar.platforms[0].y = pvar.platforms[19].y - (rand()%10 + 5); | 
| el14jw | 3:02d9072a2507 | 444 | } else { | 
| el14jw | 3:02d9072a2507 | 445 | pvar.platforms[i].x = rand()%(84-pvar.platformWidth) + (pvar.platformWidth-1)/2; | 
| el14jw | 3:02d9072a2507 | 446 | pvar.platforms[i].y = pvar.platforms[i-1].y - (rand()%10 + 5); | 
| el14jw | 3:02d9072a2507 | 447 | } | 
| el14jw | 3:02d9072a2507 | 448 | } | 
| el14jw | 3:02d9072a2507 | 449 | // Stage 2 | 
| el14jw | 3:02d9072a2507 | 450 | else if (500 < pvar.height <= 1000) { | 
| el14jw | 3:02d9072a2507 | 451 | if (i == 0) { | 
| el14jw | 3:02d9072a2507 | 452 | pvar.platforms[0].x = rand()%(84-pvar.platformWidth) + (pvar.platformWidth-1)/2; | 
| el14jw | 3:02d9072a2507 | 453 | pvar.platforms[0].y = pvar.platforms[19].y - (rand()%10 + 10); | 
| el14jw | 3:02d9072a2507 | 454 | } else { | 
| el14jw | 3:02d9072a2507 | 455 | pvar.platforms[i].x = rand()%(84-pvar.platformWidth) + (pvar.platformWidth-1)/2; | 
| el14jw | 3:02d9072a2507 | 456 | pvar.platforms[i].y = pvar.platforms[i-1].y - (rand()%10 + 10); | 
| el14jw | 3:02d9072a2507 | 457 | } | 
| el14jw | 3:02d9072a2507 | 458 | } | 
| el14jw | 3:02d9072a2507 | 459 | //Stage 3 | 
| el14jw | 3:02d9072a2507 | 460 | else if (pvar.height > 1000) { | 
| el14jw | 3:02d9072a2507 | 461 | if (i == 0) { | 
| el14jw | 3:02d9072a2507 | 462 | pvar.platforms[0].x = rand()%(84-pvar.platformWidth) + (pvar.platformWidth-1)/2; | 
| el14jw | 3:02d9072a2507 | 463 | pvar.platforms[0].y = pvar.platforms[19].y - (rand()%10 + 15); | 
| el14jw | 3:02d9072a2507 | 464 | } else { | 
| el14jw | 3:02d9072a2507 | 465 | pvar.platforms[i].x = rand()%(84-pvar.platformWidth) + (pvar.platformWidth-1)/2; | 
| el14jw | 3:02d9072a2507 | 466 | pvar.platforms[i].y = pvar.platforms[i-1].y - (rand()%10 + 15); | 
| el14jw | 3:02d9072a2507 | 467 | } | 
| el14jw | 3:02d9072a2507 | 468 | } | 
| el14jw | 3:02d9072a2507 | 469 | } | 
| el14jw | 3:02d9072a2507 | 470 | } | 
| el14jw | 3:02d9072a2507 | 471 | return pvar; | 
| el14jw | 3:02d9072a2507 | 472 | } | 
| el14jw | 3:02d9072a2507 | 473 | plinkvar plinkCollisions(plinkvar pvar) | 
| el14jw | 3:02d9072a2507 | 474 | { | 
| el14jw | 3:02d9072a2507 | 475 | // Collisions | 
| el14jw | 3:02d9072a2507 | 476 | // Platforms | 
| el14jw | 3:02d9072a2507 | 477 | for (int i=0; i<20; i++) { | 
| el14jw | 3:02d9072a2507 | 478 | if ( (int)pvar.pos.y == (pvar.platforms[i].y - 1) && (int)pvar.pos.x > pvar.platforms[i].x-pvar.platformWidth-2 && (int)pvar.pos.x < pvar.platforms[i].x+pvar.platformWidth+2 ) { | 
| el14jw | 3:02d9072a2507 | 479 | pvar.vel.y = -25; | 
| el14jw | 3:02d9072a2507 | 480 | // Play appropriate sound when bouncing | 
| el14jw | 3:02d9072a2507 | 481 | switch (pvar.ballRadius) { | 
| el14jw | 3:02d9072a2507 | 482 | case 1: | 
| el14jw | 3:02d9072a2507 | 483 | playSound(tune_plinkjump_small); | 
| el14jw | 3:02d9072a2507 | 484 | break; | 
| el14jw | 3:02d9072a2507 | 485 | case 2: | 
| el14jw | 3:02d9072a2507 | 486 | playSound(tune_plinkjump_normal); | 
| el14jw | 3:02d9072a2507 | 487 | break; | 
| el14jw | 3:02d9072a2507 | 488 | case 4: | 
| el14jw | 3:02d9072a2507 | 489 | playSound(tune_plinkjump_big); | 
| el14jw | 3:02d9072a2507 | 490 | break; | 
| el14jw | 3:02d9072a2507 | 491 | } | 
| el14jw | 3:02d9072a2507 | 492 | } | 
| el14jw | 3:02d9072a2507 | 493 | } | 
| el14jw | 3:02d9072a2507 | 494 | // Walls | 
| el14jw | 3:02d9072a2507 | 495 | if (pvar.pos.x <= pvar.ballRadius) { | 
| el14jw | 3:02d9072a2507 | 496 | pvar.vel.x = abs(pvar.vel.x); | 
| el14jw | 3:02d9072a2507 | 497 | } else if (pvar.pos.x >= 83 - pvar.ballRadius) { | 
| el14jw | 3:02d9072a2507 | 498 | pvar.vel.x = -abs(pvar.vel.x); | 
| el14jw | 3:02d9072a2507 | 499 | } | 
| el14jw | 3:02d9072a2507 | 500 | // Power Up | 
| el14jw | 3:02d9072a2507 | 501 | if ((int)pvar.pos.x+pvar.ballRadius >= (pvar.powerUp.x-pvar.powerUpRadius) | 
| el14jw | 3:02d9072a2507 | 502 | && (int)pvar.pos.x-pvar.ballRadius <= (pvar.powerUp.x+pvar.powerUpRadius) | 
| el14jw | 3:02d9072a2507 | 503 | && (int)pvar.pos.y+pvar.ballRadius >= (pvar.powerUp.y-pvar.powerUpRadius) | 
| el14jw | 3:02d9072a2507 | 504 | && (int)pvar.pos.y-pvar.ballRadius <= (pvar.powerUp.y+pvar.powerUpRadius)) { | 
| el14jw | 3:02d9072a2507 | 505 | // Create new powerUp box at the next 100 mark | 
| el14jw | 3:02d9072a2507 | 506 | pvar.powerUp.x = rand()%(84-1-(pvar.powerUpRadius*2)) + pvar.powerUpRadius; | 
| el14jw | 3:02d9072a2507 | 507 | pvar.powerUp.y = -100; | 
| el14jw | 3:02d9072a2507 | 508 | |
| el14jw | 3:02d9072a2507 | 509 | //reset power up height | 
| el14jw | 3:02d9072a2507 | 510 | pvar.powerUpHeight = 0; | 
| el14jw | 3:02d9072a2507 | 511 | |
| el14jw | 3:02d9072a2507 | 512 | // Choose new power up randomly | 
| el14jw | 3:02d9072a2507 | 513 | switch (rand()%4) { | 
| el14jw | 3:02d9072a2507 | 514 | case 0: | 
| el14jw | 3:02d9072a2507 | 515 | pvar.ballRadius = 4; | 
| el14jw | 3:02d9072a2507 | 516 | break; | 
| el14jw | 3:02d9072a2507 | 517 | case 1: | 
| el14jw | 3:02d9072a2507 | 518 | pvar.ballRadius = 1; | 
| el14jw | 3:02d9072a2507 | 519 | break; | 
| el14jw | 3:02d9072a2507 | 520 | case 2: | 
| el14jw | 3:02d9072a2507 | 521 | pvar.platformWidth = 11; | 
| el14jw | 3:02d9072a2507 | 522 | break; | 
| el14jw | 3:02d9072a2507 | 523 | case 3: | 
| el14jw | 3:02d9072a2507 | 524 | pvar.platformWidth = 5; | 
| el14jw | 3:02d9072a2507 | 525 | break; | 
| el14jw | 3:02d9072a2507 | 526 | default: | 
| el14jw | 3:02d9072a2507 | 527 | error(); | 
| el14jw | 3:02d9072a2507 | 528 | } | 
| el14jw | 4:c2d920b17b14 | 529 | } | 
| el14jw | 4:c2d920b17b14 | 530 | // If the powerup has been missed then generate new one | 
| el14jw | 4:c2d920b17b14 | 531 | else if (pvar.powerUp.y > 47+pvar.powerUpRadius) { | 
| el14jw | 3:02d9072a2507 | 532 | pvar.powerUp.x = rand()%(84-1-(pvar.powerUpRadius*2)) + pvar.powerUpRadius; | 
| el14jw | 3:02d9072a2507 | 533 | pvar.powerUp.y = -150; | 
| el14jw | 3:02d9072a2507 | 534 | } | 
| el14jw | 4:c2d920b17b14 | 535 | // After certain height achieved then cancel power up | 
| el14jw | 3:02d9072a2507 | 536 | if (pvar.powerUpHeight > 100) { | 
| el14jw | 3:02d9072a2507 | 537 | pvar.ballRadius = 2; | 
| el14jw | 3:02d9072a2507 | 538 | pvar.platformWidth = 7 - (pvar.difficulty * 2); | 
| el14jw | 3:02d9072a2507 | 539 | } | 
| el14jw | 3:02d9072a2507 | 540 | return pvar; | 
| el14jw | 3:02d9072a2507 | 541 | } | 
| el14jw | 3:02d9072a2507 | 542 | plinkvar plinkPhysicsEngine(plinkvar pvar) | 
| el14jw | 3:02d9072a2507 | 543 | { | 
| el14jw | 3:02d9072a2507 | 544 | // Physics engine | 
| el14jw | 3:02d9072a2507 | 545 | // Acceleration due to joystick | 
| el14jw | 3:02d9072a2507 | 546 | if (g_joystick_flag) { | 
| el14jw | 3:02d9072a2507 | 547 | if (joystick.direction == LEFT) { | 
| el14jw | 3:02d9072a2507 | 548 | pvar.acc.x = -15; | 
| el14jw | 3:02d9072a2507 | 549 | } else if (joystick.direction == RIGHT) { | 
| el14jw | 3:02d9072a2507 | 550 | pvar.acc.x = 15; | 
| el14jw | 3:02d9072a2507 | 551 | } else { | 
| el14jw | 3:02d9072a2507 | 552 | pvar.acc.x = 0; | 
| el14jw | 3:02d9072a2507 | 553 | } | 
| el14jw | 3:02d9072a2507 | 554 | } | 
| el14jw | 4:c2d920b17b14 | 555 | // physics iteration | 
| el14jw | 3:02d9072a2507 | 556 | pvar.vel.y = pvar.vel.y + (pvar.acc.y * pvar.tickerDelay * 4); | 
| el14jw | 3:02d9072a2507 | 557 | pvar.vel.x = 0.97F*(pvar.vel.x + (pvar.acc.x * pvar.tickerDelay)*4); // 0.97 adds slight damping factor to horizontal movement | 
| el14jw | 3:02d9072a2507 | 558 | pvar.pos.y = pvar.pos.y + (pvar.vel.y * pvar.tickerDelay * 4); | 
| el14jw | 3:02d9072a2507 | 559 | pvar.pos.x = pvar.pos.x + (pvar.vel.x * pvar.tickerDelay * 4); | 
| el14jw | 3:02d9072a2507 | 560 | // Boundaries of physics engine | 
| el14jw | 3:02d9072a2507 | 561 | if (pvar.pos.y > 48) { | 
| el14jw | 3:02d9072a2507 | 562 | pvar.gameOver = 1; | 
| el14jw | 3:02d9072a2507 | 563 | } | 
| el14jw | 4:c2d920b17b14 | 564 | // If ball is out of boundaries then place it back in boundaries | 
| el14jw | 3:02d9072a2507 | 565 | if (pvar.pos.x - pvar.ballRadius < 0) { | 
| el14jw | 3:02d9072a2507 | 566 | pvar.pos.x = pvar.ballRadius; | 
| el14jw | 3:02d9072a2507 | 567 | } else if (pvar.pos.x + pvar.ballRadius > 83) { | 
| el14jw | 3:02d9072a2507 | 568 | pvar.pos.x = 83-pvar.ballRadius; | 
| el14jw | 3:02d9072a2507 | 569 | } | 
| el14jw | 3:02d9072a2507 | 570 | return pvar; | 
| el14jw | 3:02d9072a2507 | 571 | } | 
| el14jw | 3:02d9072a2507 | 572 | plinkvar plinkDrawScreen(plinkvar pvar) | 
| el14jw | 3:02d9072a2507 | 573 | { | 
| el14jw | 3:02d9072a2507 | 574 | // Drawing on lcd | 
| el14jw | 3:02d9072a2507 | 575 | lcd.clear(); | 
| el14jw | 4:c2d920b17b14 | 576 | // Drawing ball/blob | 
| el14jw | 3:02d9072a2507 | 577 | // If second blob stage | 
| el14jw | 3:02d9072a2507 | 578 | int noPlatform = 1; | 
| el14jw | 3:02d9072a2507 | 579 | if (pvar.ballRadius == 2) { | 
| el14jw | 3:02d9072a2507 | 580 | for (int i=0; i<20; i++) { | 
| el14jw | 3:02d9072a2507 | 581 | if ( (int)pvar.pos.y == (pvar.platforms[i].y - 2) && (int)pvar.pos.x > pvar.platforms[i].x-pvar.platformWidth-2 && (int)pvar.pos.x < pvar.platforms[i].x+pvar.platformWidth+2 ) { | 
| el14jw | 3:02d9072a2507 | 582 | noPlatform = 0; | 
| el14jw | 3:02d9072a2507 | 583 | lcd.drawRect(pvar.pos.x-2,pvar.pos.y-1,4,2,1); // X, Y, Width, Height, Fill | 
| el14jw | 3:02d9072a2507 | 584 | lcd.setPixel(pvar.pos.x-1,pvar.pos.y-2); | 
| el14jw | 3:02d9072a2507 | 585 | lcd.setPixel(pvar.pos.x,pvar.pos.y-2); | 
| el14jw | 3:02d9072a2507 | 586 | lcd.setPixel(pvar.pos.x+1,pvar.pos.y-2); | 
| el14jw | 3:02d9072a2507 | 587 | lcd.setPixel(pvar.pos.x-3,pvar.pos.y+1); | 
| el14jw | 3:02d9072a2507 | 588 | lcd.setPixel(pvar.pos.x+3,pvar.pos.y+1); | 
| el14jw | 3:02d9072a2507 | 589 | } | 
| el14jw | 3:02d9072a2507 | 590 | // If third blob stage | 
| el14jw | 3:02d9072a2507 | 591 | else if ( (int)pvar.pos.y == (pvar.platforms[i].y - 1) && (int)pvar.pos.x > pvar.platforms[i].x-pvar.platformWidth-2 && (int)pvar.pos.x < pvar.platforms[i].x+pvar.platformWidth+2 ) { | 
| el14jw | 3:02d9072a2507 | 592 | noPlatform = 0; | 
| el14jw | 3:02d9072a2507 | 593 | lcd.drawRect(pvar.pos.x-3,pvar.pos.y-1,6,1,1); // X, Y, Width, Height, Fill | 
| el14jw | 3:02d9072a2507 | 594 | lcd.setPixel(pvar.pos.x-4,pvar.pos.y); | 
| el14jw | 3:02d9072a2507 | 595 | lcd.setPixel(pvar.pos.x+4,pvar.pos.y); | 
| el14jw | 3:02d9072a2507 | 596 | lcd.setPixel(pvar.pos.x-2,pvar.pos.y-2); | 
| el14jw | 3:02d9072a2507 | 597 | lcd.setPixel(pvar.pos.x-1,pvar.pos.y-2); | 
| el14jw | 3:02d9072a2507 | 598 | lcd.setPixel(pvar.pos.x,pvar.pos.y-2); | 
| el14jw | 3:02d9072a2507 | 599 | lcd.setPixel(pvar.pos.x+1,pvar.pos.y-2); | 
| el14jw | 3:02d9072a2507 | 600 | lcd.setPixel(pvar.pos.x+2,pvar.pos.y-2); | 
| el14jw | 3:02d9072a2507 | 601 | } | 
| el14jw | 3:02d9072a2507 | 602 | } | 
| el14jw | 3:02d9072a2507 | 603 | } | 
| el14jw | 3:02d9072a2507 | 604 | // Else default blob stage | 
| el14jw | 3:02d9072a2507 | 605 | if (noPlatform == 1) { | 
| el14jw | 3:02d9072a2507 | 606 | lcd.drawCircle((int)pvar.pos.x,(int)pvar.pos.y,pvar.ballRadius,1); // X, Y, Radius, Fill | 
| el14jw | 3:02d9072a2507 | 607 | lcd.refresh(); | 
| el14jw | 3:02d9072a2507 | 608 | } | 
| el14jw | 4:c2d920b17b14 | 609 | // Platforms and boundaries drawing | 
| el14jw | 3:02d9072a2507 | 610 | for (int i=0; i<20; i++) { | 
| el14jw | 3:02d9072a2507 | 611 | if (pvar.platforms[i].y > 0) { | 
| el14jw | 3:02d9072a2507 | 612 | lcd.drawRect( pvar.platforms[i].x-pvar.platformWidth ,pvar.platforms[i].y,pvar.platformWidth*2,1,1); // X, Y, Width, Height, Fill | 
| el14jw | 3:02d9072a2507 | 613 | } | 
| el14jw | 3:02d9072a2507 | 614 | } | 
| el14jw | 3:02d9072a2507 | 615 | lcd.drawLine(0,0,0,47,1); // x0,y0,x1,y1,type | 
| el14jw | 3:02d9072a2507 | 616 | lcd.drawLine(83,0,83,47,1); | 
| el14jw | 4:c2d920b17b14 | 617 | // PowerUp drawing | 
| el14jw | 3:02d9072a2507 | 618 | if (pvar.powerUp.y > 0-pvar.powerUpRadius && pvar.powerUp.y < 47+pvar.powerUpRadius) { | 
| el14jw | 3:02d9072a2507 | 619 | lcd.drawRect(pvar.powerUp.x-pvar.powerUpRadius,pvar.powerUp.y-pvar.powerUpRadius,10,10,0); // X, Y, Width, Height, Fill | 
| el14jw | 3:02d9072a2507 | 620 | lcd.setPixel(pvar.powerUp.x,pvar.powerUp.y+3); | 
| el14jw | 3:02d9072a2507 | 621 | lcd.setPixel(pvar.powerUp.x,pvar.powerUp.y+1); | 
| el14jw | 3:02d9072a2507 | 622 | lcd.setPixel(pvar.powerUp.x+1,pvar.powerUp.y); | 
| el14jw | 3:02d9072a2507 | 623 | lcd.setPixel(pvar.powerUp.x+2,pvar.powerUp.y-1); | 
| el14jw | 3:02d9072a2507 | 624 | lcd.setPixel(pvar.powerUp.x+2,pvar.powerUp.y-2); | 
| el14jw | 3:02d9072a2507 | 625 | lcd.setPixel(pvar.powerUp.x+1,pvar.powerUp.y-3); | 
| el14jw | 3:02d9072a2507 | 626 | lcd.setPixel(pvar.powerUp.x,pvar.powerUp.y-3); | 
| el14jw | 3:02d9072a2507 | 627 | lcd.setPixel(pvar.powerUp.x-1,pvar.powerUp.y-3); | 
| el14jw | 3:02d9072a2507 | 628 | lcd.setPixel(pvar.powerUp.x-2,pvar.powerUp.y-2); | 
| el14jw | 3:02d9072a2507 | 629 | } | 
| el14jw | 3:02d9072a2507 | 630 | |
| el14jw | 3:02d9072a2507 | 631 | lcd.refresh(); | 
| el14jw | 3:02d9072a2507 | 632 | // Looks more pleasing when the ball pauses to bounce | 
| el14jw | 3:02d9072a2507 | 633 | if (noPlatform == 0) { | 
| el14jw | 3:02d9072a2507 | 634 | wait(0.03); | 
| el14jw | 3:02d9072a2507 | 635 | } | 
| el14jw | 4:c2d920b17b14 | 636 | char buffer[14]; | 
| el14jw | 4:c2d920b17b14 | 637 | sprintf(buffer,"Score: %d",pvar.height); | 
| el14jw | 4:c2d920b17b14 | 638 | lcd.printString(buffer,0,0); | 
| el14jw | 3:02d9072a2507 | 639 | |
| el14jw | 3:02d9072a2507 | 640 | return pvar; | 
| el14jw | 3:02d9072a2507 | 641 | } | 
| el14jw | 3:02d9072a2507 | 642 | plinkvar plinkGameOver(plinkvar pvar){ | 
| el14jw | 3:02d9072a2507 | 643 | // Handle saving high scores to SD card | 
| el14jw | 1:c4928de1f922 | 644 | // Read previous highscore if one exists | 
| el14jw | 1:c4928de1f922 | 645 | fp = fopen("/sd/plinkhighscore.txt", "r"); | 
| el14jw | 1:c4928de1f922 | 646 | int current_high_score = -1; // -1 to demonstrate it has changed after reading | 
| el14jw | 1:c4928de1f922 | 647 | |
| el14jw | 1:c4928de1f922 | 648 | if (fp == NULL) { // if it can't open the file then print error message | 
| el14jw | 1:c4928de1f922 | 649 | lcd.printString("Failed Read",0,5); | 
| el14jw | 1:c4928de1f922 | 650 | } else { // opened file so can write | 
| el14jw | 1:c4928de1f922 | 651 | fscanf(fp,"%d",¤t_high_score); // ensure data type matches - note address operator (&) | 
| el14jw | 1:c4928de1f922 | 652 | fclose(fp); // ensure you close the file after reading | 
| el14jw | 1:c4928de1f922 | 653 | } | 
| el14jw | 1:c4928de1f922 | 654 | |
| el14jw | 1:c4928de1f922 | 655 | // Writing score to sd card if new high score | 
| el14jw | 3:02d9072a2507 | 656 | if (current_high_score < pvar.height && current_high_score != -1) { | 
| el14jw | 1:c4928de1f922 | 657 | fp = fopen("/sd/plinkhighscore.txt", "w"); | 
| el14jw | 1:c4928de1f922 | 658 | if (fp == NULL) { // if it can't open the file then print error message | 
| el14jw | 1:c4928de1f922 | 659 | lcd.printString("No SD Card ",0,5); | 
| el14jw | 1:c4928de1f922 | 660 | } else { // opened file so can write | 
| el14jw | 3:02d9072a2507 | 661 | fprintf(fp,"%d",pvar.height); // ensure data type matches | 
| el14jw | 1:c4928de1f922 | 662 | fclose(fp); // ensure you close the file after writing | 
| el14jw | 1:c4928de1f922 | 663 | } | 
| el14jw | 1:c4928de1f922 | 664 | } | 
| el14jw | 1:c4928de1f922 | 665 | |
| el14jw | 1:c4928de1f922 | 666 | // Appropriate strings printed to LCD | 
| el14jw | 1:c4928de1f922 | 667 | lcd.printString("Game Over",20,0); | 
| el14jw | 3:02d9072a2507 | 668 | if (current_high_score != -1 && current_high_score < pvar.height) { | 
| el14jw | 1:c4928de1f922 | 669 | lcd.printString("New High Score",0,1); | 
| el14jw | 1:c4928de1f922 | 670 | lcd.printString("Previously",0,3); | 
| el14jw | 3:02d9072a2507 | 671 | } else if (current_high_score != -1 && current_high_score > pvar.height) { | 
| el14jw | 1:c4928de1f922 | 672 | lcd.printString("Score",0,1); | 
| el14jw | 1:c4928de1f922 | 673 | lcd.printString("High Score",0,3); | 
| el14jw | 1:c4928de1f922 | 674 | } else { | 
| el14jw | 1:c4928de1f922 | 675 | lcd.printString("Score:",0,1); | 
| el14jw | 1:c4928de1f922 | 676 | lcd.printString("No Previous",0,3); | 
| el14jw | 1:c4928de1f922 | 677 | } | 
| el14jw | 1:c4928de1f922 | 678 | // Print score | 
| el14jw | 1:c4928de1f922 | 679 | char buffer[14]; | 
| el14jw | 3:02d9072a2507 | 680 | sprintf(buffer,"%d",pvar.height); | 
| el14jw | 1:c4928de1f922 | 681 | lcd.printString(buffer,20,2); | 
| el14jw | 1:c4928de1f922 | 682 | // Print previous high-score | 
| el14jw | 1:c4928de1f922 | 683 | if (current_high_score != -1) { | 
| el14jw | 1:c4928de1f922 | 684 | char str[14]; | 
| el14jw | 1:c4928de1f922 | 685 | sprintf(str,"%d",current_high_score); | 
| el14jw | 1:c4928de1f922 | 686 | lcd.printString(str,20,4); | 
| el14jw | 1:c4928de1f922 | 687 | } | 
| el14jw | 2:80a91a737e17 | 688 | |
| el14jw | 1:c4928de1f922 | 689 | playSound(tune_gameOver); | 
| el14jw | 0:23a749719479 | 690 | lcd.refresh(); | 
| el14jw | 1:c4928de1f922 | 691 | wait(3.0); | 
| el14jw | 4:c2d920b17b14 | 692 | // Reset all flags so no unexpected behaviour occurs | 
| el14jw | 1:c4928de1f922 | 693 | g_buttonA_flag = 0; | 
| el14jw | 1:c4928de1f922 | 694 | g_buttonB_flag = 0; | 
| el14jw | 1:c4928de1f922 | 695 | g_buttonjoy_flag = 0; | 
| el14jw | 3:02d9072a2507 | 696 | return pvar; | 
| el14jw | 0:23a749719479 | 697 | } | 
| el14jw | 0:23a749719479 | 698 | |
| el14jw | 0:23a749719479 | 699 | |
| el14jw | 0:23a749719479 | 700 | // ISR's | 
| el14jw | 1:c4928de1f922 | 701 | void buttonA_isr() | 
| el14jw | 1:c4928de1f922 | 702 | { | 
| el14jw | 1:c4928de1f922 | 703 | g_buttonA_flag = 1; | 
| el14jw | 1:c4928de1f922 | 704 | } | 
| el14jw | 1:c4928de1f922 | 705 | void buttonB_isr() | 
| el14jw | 1:c4928de1f922 | 706 | { | 
| el14jw | 1:c4928de1f922 | 707 | g_buttonB_flag = 1; | 
| el14jw | 1:c4928de1f922 | 708 | } | 
| el14jw | 1:c4928de1f922 | 709 | void buttonjoy_isr() | 
| el14jw | 1:c4928de1f922 | 710 | { | 
| el14jw | 1:c4928de1f922 | 711 | g_buttonjoy_flag = 1; | 
| el14jw | 1:c4928de1f922 | 712 | } | 
| el14jw | 1:c4928de1f922 | 713 | void gametick_isr() | 
| el14jw | 1:c4928de1f922 | 714 | { | 
| el14jw | 1:c4928de1f922 | 715 | g_gametick_flag = 1; | 
| el14jw | 1:c4928de1f922 | 716 | } | 
| el14jw | 0:23a749719479 | 717 | |
| el14jw | 4:c2d920b17b14 | 718 | |
| el14jw | 0:23a749719479 | 719 | // Initialises Inputs | 
| el14jw | 0:23a749719479 | 720 | void initInputs() | 
| el14jw | 0:23a749719479 | 721 | { | 
| el14jw | 0:23a749719479 | 722 | |
| el14jw | 0:23a749719479 | 723 | errorLED = 1; | 
| el14jw | 0:23a749719479 | 724 | |
| el14jw | 0:23a749719479 | 725 | /// Setting up Interrupt service routines for input buttons | 
| el14jw | 0:23a749719479 | 726 | /// PullDown mode is assumed | 
| el14jw | 0:23a749719479 | 727 | buttonA.rise(&buttonA_isr); | 
| el14jw | 0:23a749719479 | 728 | buttonB.rise(&buttonB_isr); | 
| el14jw | 0:23a749719479 | 729 | buttonjoy.rise(&buttonjoy_isr); | 
| el14jw | 0:23a749719479 | 730 | buttonA.mode(PullDown); | 
| el14jw | 0:23a749719479 | 731 | buttonB.mode(PullDown); | 
| el14jw | 0:23a749719479 | 732 | buttonjoy.mode(PullDown); | 
| el14jw | 0:23a749719479 | 733 | |
| el14jw | 0:23a749719479 | 734 | /// Testing LCD display works (splash screen) | 
| el14jw | 0:23a749719479 | 735 | lcd.init(); | 
| el14jw | 2:80a91a737e17 | 736 | wait(0.5); | 
| el14jw | 0:23a749719479 | 737 | lcd.printString("Calibrating",8,0); | 
| el14jw | 0:23a749719479 | 738 | lcd.printString("Do not move",8,1); | 
| el14jw | 0:23a749719479 | 739 | lcd.printString("Joystick",18,2); | 
| el14jw | 0:23a749719479 | 740 | lcd.refresh(); | 
| el14jw | 0:23a749719479 | 741 | |
| el14jw | 0:23a749719479 | 742 | /// Calibrating the Joystick on startup | 
| el14jw | 0:23a749719479 | 743 | calibrateJoystick(); | 
| el14jw | 0:23a749719479 | 744 | /// read joystick 10 times per second | 
| el14jw | 0:23a749719479 | 745 | pollJoystick.attach(&updateJoystick,1.0/10.0); | 
| el14jw | 2:80a91a737e17 | 746 | // Patch for sd casrd access not working first time | 
| el14jw | 2:80a91a737e17 | 747 | fp = fopen("sd/test.txt","w"); | 
| el14jw | 3:02d9072a2507 | 748 | if (fp != NULL) { | 
| el14jw | 3:02d9072a2507 | 749 | fclose(fp); | 
| el14jw | 2:80a91a737e17 | 750 | } | 
| el14jw | 0:23a749719479 | 751 | wait(1.0); | 
| el14jw | 0:23a749719479 | 752 | lcd.clear(); | 
| el14jw | 0:23a749719479 | 753 | } | 
| el14jw | 0:23a749719479 | 754 | // Hangs on an error | 
| el14jw | 0:23a749719479 | 755 | void error() | 
| el14jw | 0:23a749719479 | 756 | { | 
| el14jw | 0:23a749719479 | 757 | while(1) { | 
| el14jw | 0:23a749719479 | 758 | errorLED = !errorLED; | 
| el14jw | 0:23a749719479 | 759 | wait(0.2); | 
| el14jw | 0:23a749719479 | 760 | } | 
| el14jw | 0:23a749719479 | 761 | } | 
| el14jw | 0:23a749719479 | 762 | |
| el14jw | 0:23a749719479 | 763 | // Menu function for handling the printing and selecting of menu screens | 
| el14jw | 0:23a749719479 | 764 | int menu(const stringList* menuList,int lines) | 
| el14jw | 0:23a749719479 | 765 | { | 
| el14jw | 0:23a749719479 | 766 | int select = 0; | 
| el14jw | 1:c4928de1f922 | 767 | // While either joystick button or button A or button B are not on then continue selection process | 
| el14jw | 1:c4928de1f922 | 768 | // Once either button is on the the selected value is returned | 
| el14jw | 1:c4928de1f922 | 769 | while(g_buttonjoy_flag == 0 && g_buttonA_flag == 0 && g_buttonB_flag == 0) { | 
| el14jw | 0:23a749719479 | 770 | |
| el14jw | 0:23a749719479 | 771 | // Changes the value of variable select determined by what the joystick value is | 
| el14jw | 0:23a749719479 | 772 | if (g_joystick_flag) { | 
| el14jw | 0:23a749719479 | 773 | if (joystick.direction == UP) { | 
| el14jw | 0:23a749719479 | 774 | if (select == 0) { | 
| el14jw | 0:23a749719479 | 775 | select = lines-2; | 
| el14jw | 0:23a749719479 | 776 | } else { | 
| el14jw | 0:23a749719479 | 777 | select--; | 
| el14jw | 0:23a749719479 | 778 | } | 
| el14jw | 0:23a749719479 | 779 | } else if(joystick.direction == DOWN) { | 
| el14jw | 0:23a749719479 | 780 | if (select == lines-2) { | 
| el14jw | 0:23a749719479 | 781 | select = 0; | 
| el14jw | 0:23a749719479 | 782 | } else { | 
| el14jw | 0:23a749719479 | 783 | select++; | 
| el14jw | 0:23a749719479 | 784 | } | 
| el14jw | 0:23a749719479 | 785 | } | 
| el14jw | 0:23a749719479 | 786 | } | 
| el14jw | 0:23a749719479 | 787 | |
| el14jw | 0:23a749719479 | 788 | // Prints the correct strings | 
| el14jw | 0:23a749719479 | 789 | drawStrings(menuList,lines); | 
| el14jw | 1:c4928de1f922 | 790 | int line = select + 1; | 
| el14jw | 0:23a749719479 | 791 | char buffer[14]; | 
| el14jw | 1:c4928de1f922 | 792 | sprintf(buffer,">> %s",menuList[line].str); | 
| el14jw | 1:c4928de1f922 | 793 | lcd.printString(buffer,menuList[line].offset,line); | 
| el14jw | 1:c4928de1f922 | 794 | |
| el14jw | 0:23a749719479 | 795 | if (g_joystick_flag) { | 
| el14jw | 0:23a749719479 | 796 | g_joystick_flag = 0; | 
| el14jw | 1:c4928de1f922 | 797 | // Adds acceptable scrolling delay | 
| el14jw | 0:23a749719479 | 798 | wait(0.2); | 
| el14jw | 0:23a749719479 | 799 | } | 
| el14jw | 0:23a749719479 | 800 | sleep(); | 
| el14jw | 0:23a749719479 | 801 | } | 
| el14jw | 0:23a749719479 | 802 | // Debouncing | 
| el14jw | 1:c4928de1f922 | 803 | wait(0.2); | 
| el14jw | 0:23a749719479 | 804 | g_buttonjoy_flag = 0; | 
| el14jw | 0:23a749719479 | 805 | g_buttonA_flag = 0; | 
| el14jw | 1:c4928de1f922 | 806 | // Returns -1 if B is pressed to automatically go back a menu | 
| el14jw | 1:c4928de1f922 | 807 | if (g_buttonB_flag) { | 
| el14jw | 1:c4928de1f922 | 808 | g_buttonB_flag = 0; | 
| el14jw | 1:c4928de1f922 | 809 | select = -1; | 
| el14jw | 1:c4928de1f922 | 810 | } | 
| el14jw | 0:23a749719479 | 811 | return select; | 
| el14jw | 0:23a749719479 | 812 | } | 
| el14jw | 1:c4928de1f922 | 813 | // Draw Strings function used for plotting an array of stringList to the LCD | 
| el14jw | 0:23a749719479 | 814 | void drawStrings(const stringList* list,int lines) | 
| el14jw | 0:23a749719479 | 815 | { | 
| el14jw | 0:23a749719479 | 816 | lcd.clear(); | 
| el14jw | 0:23a749719479 | 817 | for (int i=0; i<lines; i++) { | 
| el14jw | 0:23a749719479 | 818 | lcd.printString(list[i].str,list[i].offset,i); | 
| el14jw | 0:23a749719479 | 819 | } | 
| el14jw | 0:23a749719479 | 820 | } | 
| el14jw | 0:23a749719479 | 821 | |
| el14jw | 0:23a749719479 | 822 | |
| el14jw | 0:23a749719479 | 823 | /// Read default positions of the joystick to calibrate later readings | 
| el14jw | 0:23a749719479 | 824 | void calibrateJoystick() | 
| el14jw | 0:23a749719479 | 825 | { | 
| el14jw | 0:23a749719479 | 826 | // must not move during calibration | 
| el14jw | 0:23a749719479 | 827 | joystick.x0 = xPot; /// initial positions in the range 0.0 to 1.0 (0.5 if centred exactly) | 
| el14jw | 0:23a749719479 | 828 | joystick.y0 = yPot; | 
| el14jw | 0:23a749719479 | 829 | } | 
| el14jw | 0:23a749719479 | 830 | void updateJoystick() | 
| el14jw | 0:23a749719479 | 831 | { | 
| el14jw | 0:23a749719479 | 832 | /// read current joystick values relative to calibrated values (in range -0.5 to 0.5, 0.0 is centred) | 
| el14jw | 0:23a749719479 | 833 | joystick.x = xPot - joystick.x0; | 
| el14jw | 0:23a749719479 | 834 | joystick.y = yPot - joystick.y0; | 
| el14jw | 0:23a749719479 | 835 | |
| el14jw | 0:23a749719479 | 836 | // calculate direction depending on x,y values | 
| el14jw | 0:23a749719479 | 837 | // tolerance allows a little lee-way in case joystick not exactly in the stated direction | 
| el14jw | 0:23a749719479 | 838 | if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { | 
| el14jw | 0:23a749719479 | 839 | joystick.direction = CENTRE; | 
| el14jw | 2:80a91a737e17 | 840 | } else if ( joystick.y < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { | 
| el14jw | 0:23a749719479 | 841 | joystick.direction = UP; | 
| el14jw | 2:80a91a737e17 | 842 | } else if ( joystick.y > DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { | 
| el14jw | 0:23a749719479 | 843 | joystick.direction = DOWN; | 
| el14jw | 0:23a749719479 | 844 | } else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) { | 
| el14jw | 0:23a749719479 | 845 | joystick.direction = RIGHT; | 
| el14jw | 0:23a749719479 | 846 | } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) { | 
| el14jw | 0:23a749719479 | 847 | joystick.direction = LEFT; | 
| el14jw | 0:23a749719479 | 848 | } else { | 
| el14jw | 0:23a749719479 | 849 | joystick.direction = UNKNOWN; | 
| el14jw | 0:23a749719479 | 850 | } | 
| el14jw | 0:23a749719479 | 851 | |
| el14jw | 0:23a749719479 | 852 | // set flag for printing | 
| el14jw | 0:23a749719479 | 853 | g_joystick_flag = 1; | 
| el14jw | 0:23a749719479 | 854 | } |