Space Invaders - Embedded Systems Project 15/16 - Avinash Patel 200860407

Dependencies:   Joystick N5110 SDFileSystem mbed

Committer:
avi23
Date:
Mon May 02 16:28:07 2016 +0000
Revision:
7:babc367a3333
Parent:
6:89d4a7f7588b
Child:
8:b2faec20ed8f
Before main.cpp doxygening

Who changed what in which revision?

UserRevisionLine numberNew contents of line
avi23 1:b300d052d549 1 /*
avi23 1:b300d052d549 2 Space Invaders - Avinash Patel 200860407
avi23 1:b300d052d549 3
avi23 1:b300d052d549 4 Week 19 - Set up joystick class
avi23 1:b300d052d549 5 Week 20 - Changed to space invaders as constrained too much by screen resolution
avi23 1:b300d052d549 6 - Core cannon is drawn and can move, enemies are visible and they switch between states every second
avi23 2:d34c95990605 7 Week 21 - Begun to set up barriers
avi23 5:34855f712350 8 Easter - Barriers work, invader and player can shoot. Begun setting up menus
avi23 7:babc367a3333 9 Week 22 - Most menus work
avi23 7:babc367a3333 10 Week 23 - Menus work
avi23 1:b300d052d549 11 */
avi23 0:427469992efe 12 #include "mbed.h"
avi23 7:babc367a3333 13 #include "main.h"
avi23 0:427469992efe 14
avi23 5:34855f712350 15 int row_no = 5;
avi23 5:34855f712350 16 int col_no = 14;
avi23 0:427469992efe 17
avi23 0:427469992efe 18 int main()
avi23 0:427469992efe 19 {
avi23 5:34855f712350 20 //Wait for 2 seconds to allow power to settle
avi23 5:34855f712350 21 wait(1);
avi23 0:427469992efe 22 //Initalises the board and perhiperals
avi23 0:427469992efe 23 init_K64F();
avi23 0:427469992efe 24 init_serial();
avi23 2:d34c95990605 25 init_shoot();
avi23 5:34855f712350 26 init_rng();
avi23 5:34855f712350 27 joystick.init();
avi23 0:427469992efe 28 lcd.init();
avi23 0:427469992efe 29 lcd.clear();
avi23 0:427469992efe 30
avi23 5:34855f712350 31 //Configures the function pointer for the invaders normal missile
avi23 5:34855f712350 32 move_invader_normal_missile_isr[0] = &move_invader_normal_missile_0_isr;
avi23 5:34855f712350 33 move_invader_normal_missile_isr[1] = &move_invader_normal_missile_1_isr;
avi23 0:427469992efe 34
avi23 5:34855f712350 35 //Samples joystick every 0.05 second
avi23 5:34855f712350 36 move_joystick.attach(&move_joystick_isr, 0.05);
avi23 2:d34c95990605 37
avi23 6:89d4a7f7588b 38
avi23 6:89d4a7f7588b 39
avi23 2:d34c95990605 40 while (true) {
avi23 5:34855f712350 41 if (game_state == menu) { //Menu screen
avi23 2:d34c95990605 42 lcd.clear();
avi23 6:89d4a7f7588b 43 fsm_state = 0; //Sets the fsm state to 0
avi23 6:89d4a7f7588b 44 while (game_state == menu) {
avi23 6:89d4a7f7588b 45 lcd.printString("Space Invaders", 0, 0);
avi23 6:89d4a7f7588b 46 lcd.printString("Menu", 28, 1);
avi23 6:89d4a7f7588b 47 lcd.drawLine(0, 15, 83, 15, 2);
avi23 6:89d4a7f7588b 48
avi23 6:89d4a7f7588b 49 lcd.printString("New Game", 5, 2);
avi23 6:89d4a7f7588b 50 lcd.printString("Load Game", 5, 3);
avi23 6:89d4a7f7588b 51 lcd.printString("High Scores", 5, 4);
avi23 6:89d4a7f7588b 52 lcd.printString("Settings", 5, 5);
avi23 6:89d4a7f7588b 53
avi23 6:89d4a7f7588b 54 //Draws the cursor
avi23 6:89d4a7f7588b 55 cursor_y_pos = ((fsm_state+2)*8)+3; //Adds 2 to the fsm state to get the bank, multiplies it by 8 to get the pixel no and offsets it by 3
avi23 6:89d4a7f7588b 56 lcd.drawRect(74, cursor_y_pos, 2, 2, 1);
avi23 6:89d4a7f7588b 57
avi23 6:89d4a7f7588b 58 if (g_move_joystick_flag) {
avi23 6:89d4a7f7588b 59 g_move_joystick_flag = false;
avi23 6:89d4a7f7588b 60
avi23 6:89d4a7f7588b 61 //Moves the cursor to match the selected option, only if the joystick isn't centred
avi23 6:89d4a7f7588b 62 MoveCursor(fsm_main_menu);
avi23 6:89d4a7f7588b 63 }
avi23 6:89d4a7f7588b 64
avi23 6:89d4a7f7588b 65 if (g_shoot_pressed_flag) {
avi23 6:89d4a7f7588b 66 g_shoot_pressed_flag = false;
avi23 6:89d4a7f7588b 67
avi23 6:89d4a7f7588b 68 game_state = fsm_main_menu[fsm_state].output;
avi23 2:d34c95990605 69
avi23 6:89d4a7f7588b 70 //If the game state is equal to the game initalise it
avi23 6:89d4a7f7588b 71 if (game_state == game) {
avi23 7:babc367a3333 72 InitaliseGame();
avi23 6:89d4a7f7588b 73 }
avi23 6:89d4a7f7588b 74 }
avi23 5:34855f712350 75
avi23 6:89d4a7f7588b 76 if(joystick.get_button_flag()) {
avi23 6:89d4a7f7588b 77 joystick.set_button_flag(0);
avi23 6:89d4a7f7588b 78 }
avi23 6:89d4a7f7588b 79
avi23 6:89d4a7f7588b 80 lcd.refresh();
avi23 6:89d4a7f7588b 81 sleep();
avi23 1:b300d052d549 82 }
avi23 5:34855f712350 83 } else if (game_state == paused) { //Paused screen
avi23 6:89d4a7f7588b 84 //Clears the screen
avi23 6:89d4a7f7588b 85 lcd.clear();
avi23 6:89d4a7f7588b 86 //Resets the fsm state to 0
avi23 6:89d4a7f7588b 87 fsm_state = 0;
avi23 6:89d4a7f7588b 88 PauseScreen();
avi23 5:34855f712350 89 } else if (game_state == game) { //Game screen
avi23 5:34855f712350 90 AttachTickers();
avi23 5:34855f712350 91 Game();
avi23 0:427469992efe 92 }
avi23 2:d34c95990605 93
avi23 0:427469992efe 94 sleep();
avi23 0:427469992efe 95 }
avi23 0:427469992efe 96 }
avi23 0:427469992efe 97
avi23 0:427469992efe 98 void init_K64F()
avi23 0:427469992efe 99 {
avi23 0:427469992efe 100 // on-board LEDs are active-low, so set pin high to turn them off.
avi23 0:427469992efe 101 r_led = 1;
avi23 0:427469992efe 102 g_led = 1;
avi23 0:427469992efe 103 b_led = 1;
avi23 0:427469992efe 104
avi23 0:427469992efe 105 // since the on-board switches have external pull-ups, we should disable the internal pull-down
avi23 0:427469992efe 106 // resistors that are enabled by default using InterruptIn
avi23 0:427469992efe 107 sw2.mode(PullNone);
avi23 0:427469992efe 108 sw3.mode(PullNone);
avi23 0:427469992efe 109 }
avi23 0:427469992efe 110
avi23 0:427469992efe 111 void error()
avi23 0:427469992efe 112 {
avi23 0:427469992efe 113 while(1) { // if error, hang while flashing error message
avi23 0:427469992efe 114 r_led = 0;
avi23 0:427469992efe 115 wait(0.2);
avi23 0:427469992efe 116 r_led = 1;
avi23 0:427469992efe 117 wait(0.2);
avi23 0:427469992efe 118 }
avi23 0:427469992efe 119 }
avi23 0:427469992efe 120
avi23 0:427469992efe 121 void init_serial()
avi23 0:427469992efe 122 {
avi23 0:427469992efe 123 // set to highest baud - ensure terminal software matches
avi23 0:427469992efe 124 pc.baud(115200);
avi23 0:427469992efe 125 }
avi23 0:427469992efe 126
avi23 5:34855f712350 127 //Seeds the random number generator with noise from an analog in pin
avi23 5:34855f712350 128 void init_rng()
avi23 5:34855f712350 129 {
avi23 7:babc367a3333 130 AnalogIn rng_seed(PTC10); //Creates a AnalogIn on a unused pin
avi23 7:babc367a3333 131 srand(floor(10000*rng_seed.read())); //Sets the seed as 10000x the input of the analog in
avi23 5:34855f712350 132 }
avi23 5:34855f712350 133
avi23 2:d34c95990605 134 void init_shoot()
avi23 0:427469992efe 135 {
avi23 2:d34c95990605 136 shoot_button.mode(PullUp);
avi23 2:d34c95990605 137 shoot_button.fall(&shoot_pressed_isr);
avi23 2:d34c95990605 138 }
avi23 2:d34c95990605 139
avi23 2:d34c95990605 140 void update_screen_isr()
avi23 2:d34c95990605 141 {
avi23 2:d34c95990605 142 g_update_screen_flag = true;
avi23 0:427469992efe 143 }
avi23 0:427469992efe 144
avi23 5:34855f712350 145 void move_enemies_isr()
avi23 5:34855f712350 146 {
avi23 5:34855f712350 147 g_move_enemies_flag = true;
avi23 5:34855f712350 148 }
avi23 5:34855f712350 149
avi23 2:d34c95990605 150 void shoot_pressed_isr()
avi23 2:d34c95990605 151 {
avi23 6:89d4a7f7588b 152 //Only sets the shoot pressed flag 0.1s after the last press
avi23 6:89d4a7f7588b 153 if (!g_shoot_button_debounce_flag) {
avi23 6:89d4a7f7588b 154 g_shoot_pressed_flag = true;
avi23 6:89d4a7f7588b 155 g_shoot_button_debounce_flag = true;
avi23 6:89d4a7f7588b 156
avi23 6:89d4a7f7588b 157 //Attaches a timeout to clear the debounce flag 0.125 seconds after it was set
avi23 6:89d4a7f7588b 158 shoot_button_debounce.attach(&shoot_button_debounce_isr, 0.125);
avi23 6:89d4a7f7588b 159 }
avi23 5:34855f712350 160 }
avi23 5:34855f712350 161
avi23 5:34855f712350 162 void move_cannon_missile_isr()
avi23 5:34855f712350 163 {
avi23 5:34855f712350 164 g_move_cannon_missile_flag = true;
avi23 5:34855f712350 165 }
avi23 5:34855f712350 166
avi23 5:34855f712350 167 void move_joystick_isr()
avi23 5:34855f712350 168 {
avi23 5:34855f712350 169 //Always set the move flag in a game
avi23 5:34855f712350 170 if (game_state == game) {
avi23 5:34855f712350 171 g_move_joystick_flag = true;
avi23 5:34855f712350 172 } else if (!g_joystick_cursor_regulator_flag) {
avi23 6:89d4a7f7588b 173 //Only sets the flag if the regulator is not set
avi23 5:34855f712350 174 g_move_joystick_flag = true;
avi23 5:34855f712350 175 g_joystick_cursor_regulator_flag = true;
avi23 5:34855f712350 176
avi23 6:89d4a7f7588b 177 //Attachs a timeout to clear the regulator in 0.1s to prevent the cursor from behaving erratically
avi23 6:89d4a7f7588b 178 joystick_cursor_regulator.attach(&joystick_cursor_regulator_isr, 0.1);
avi23 5:34855f712350 179 }
avi23 5:34855f712350 180 }
avi23 5:34855f712350 181
avi23 6:89d4a7f7588b 182 void joystick_cursor_regulator_isr()
avi23 6:89d4a7f7588b 183 {
avi23 5:34855f712350 184 g_joystick_cursor_regulator_flag = false;
avi23 5:34855f712350 185 }
avi23 5:34855f712350 186
avi23 6:89d4a7f7588b 187 void shoot_button_debounce_isr()
avi23 6:89d4a7f7588b 188 {
avi23 6:89d4a7f7588b 189 g_shoot_button_debounce_flag = false;
avi23 6:89d4a7f7588b 190 }
avi23 6:89d4a7f7588b 191
avi23 5:34855f712350 192 void move_invader_normal_missile_0_isr()
avi23 5:34855f712350 193 {
avi23 5:34855f712350 194 g_move_invader_normal_missile_flag[0] = true;
avi23 5:34855f712350 195 }
avi23 5:34855f712350 196
avi23 5:34855f712350 197 void move_invader_normal_missile_1_isr()
avi23 5:34855f712350 198 {
avi23 5:34855f712350 199 g_move_invader_normal_missile_flag[1] = true;
avi23 5:34855f712350 200 }
avi23 5:34855f712350 201
avi23 5:34855f712350 202 void cannon_hit_isr()
avi23 5:34855f712350 203 {
avi23 5:34855f712350 204 g_cannon_hit_flag = false;
avi23 2:d34c95990605 205 }
avi23 2:d34c95990605 206
avi23 5:34855f712350 207 void Game()
avi23 6:89d4a7f7588b 208 {
avi23 5:34855f712350 209 //Stays within the loop while the selected state is game
avi23 5:34855f712350 210 while (game_state == game) {
avi23 5:34855f712350 211 //If the game is over detach all the tickers
avi23 5:34855f712350 212 if (number_of_lives == 0) {
avi23 5:34855f712350 213 DetachTickers();
avi23 5:34855f712350 214
avi23 5:34855f712350 215 lcd.clear();
avi23 5:34855f712350 216 lcd.printString("Game Over.", 1, 2);
avi23 7:babc367a3333 217 char buffer[14];
avi23 7:babc367a3333 218 sprintf(buffer, "Score: %d", score);
avi23 7:babc367a3333 219 lcd.printString(buffer, 1, 3);
avi23 5:34855f712350 220 } else if (no_of_alive_invaders == 0) { //If the player wins a round
avi23 5:34855f712350 221 //Resets the no of alive invaders
avi23 5:34855f712350 222 no_of_alive_invaders = 15;
avi23 5:34855f712350 223 //Detaches the enemy ticker while reinitalising invaders
avi23 5:34855f712350 224 move_enemies.detach();
avi23 5:34855f712350 225 //Reinitalises objects
avi23 5:34855f712350 226 InitSmallInvaders();
avi23 5:34855f712350 227 InitMediumInvaders();
avi23 5:34855f712350 228 InitLargeInvaders();
avi23 5:34855f712350 229 //Reattaches enemy ticker
avi23 5:34855f712350 230 move_enemies.attach(&move_enemies_isr, 1);
avi23 5:34855f712350 231 } else {
avi23 5:34855f712350 232 //Updates pixels on the screen
avi23 5:34855f712350 233 if (g_update_screen_flag) {
avi23 5:34855f712350 234 g_update_screen_flag = false;
avi23 5:34855f712350 235
avi23 5:34855f712350 236 UpdateScreen();
avi23 5:34855f712350 237 }
avi23 5:34855f712350 238
avi23 5:34855f712350 239 //Controls cannon movement
avi23 5:34855f712350 240 if (g_move_joystick_flag) {
avi23 5:34855f712350 241 g_move_joystick_flag = false;
avi23 5:34855f712350 242
avi23 5:34855f712350 243 MoveCannon();
avi23 5:34855f712350 244 DrawBarriers();
avi23 5:34855f712350 245 }
avi23 5:34855f712350 246
avi23 5:34855f712350 247 //Controls enemy movement
avi23 5:34855f712350 248 if (g_move_enemies_flag) {
avi23 5:34855f712350 249 g_move_enemies_flag = false;
avi23 5:34855f712350 250
avi23 5:34855f712350 251 //Increses the speed the invaders move
avi23 5:34855f712350 252 move_enemies.detach();
avi23 5:34855f712350 253 ticker_period = 0.1+(no_of_alive_invaders*0.06);
avi23 5:34855f712350 254 move_enemies.attach(&move_enemies_isr, ticker_period);
avi23 5:34855f712350 255
avi23 5:34855f712350 256 //Clears the old bitmaps
avi23 5:34855f712350 257 ClearSmallInvaders();
avi23 5:34855f712350 258 ClearMediumInvaders();
avi23 5:34855f712350 259 ClearLargeInvaders();
avi23 5:34855f712350 260
avi23 5:34855f712350 261 MoveInvaderXPositions();
avi23 5:34855f712350 262 //Switches the bitmap state
avi23 5:34855f712350 263 invaders_in_state2 = !invaders_in_state2;
avi23 5:34855f712350 264
avi23 5:34855f712350 265 //Draws the invaders
avi23 5:34855f712350 266 DrawSmallInvaders();
avi23 5:34855f712350 267 DrawMediumInvaders();
avi23 5:34855f712350 268 DrawLargeInvaders();
avi23 5:34855f712350 269
avi23 5:34855f712350 270 //Attemots to fire the invaders missiles
avi23 5:34855f712350 271 AttemptToFireInvaderNormalMissiles();
avi23 5:34855f712350 272 }
avi23 5:34855f712350 273
avi23 5:34855f712350 274 //Spawns a player bullet if the shoot button is pressed and there isn't a bullet on the screen
avi23 5:34855f712350 275 if (g_shoot_pressed_flag) {
avi23 5:34855f712350 276 g_shoot_pressed_flag = false;
avi23 5:34855f712350 277
avi23 5:34855f712350 278 if (!cannon_missile_on_screen) {
avi23 5:34855f712350 279 FireCannonMissile();
avi23 5:34855f712350 280 }
avi23 5:34855f712350 281 }
avi23 5:34855f712350 282
avi23 5:34855f712350 283 //Move the cannon shot
avi23 5:34855f712350 284 if (g_move_cannon_missile_flag) {
avi23 5:34855f712350 285 g_move_cannon_missile_flag = false;
avi23 5:34855f712350 286
avi23 5:34855f712350 287 MoveCannonMissile();
avi23 5:34855f712350 288 }
avi23 5:34855f712350 289
avi23 5:34855f712350 290 //Moves the invaders 1st normal missile
avi23 5:34855f712350 291 if (g_move_invader_normal_missile_flag[0]) {
avi23 5:34855f712350 292 g_move_invader_normal_missile_flag[0] = false;
avi23 5:34855f712350 293
avi23 5:34855f712350 294 MoveInvaderNormalMissile(0);
avi23 5:34855f712350 295 }
avi23 5:34855f712350 296
avi23 5:34855f712350 297 //Moves the invaders 2nd normal missile
avi23 5:34855f712350 298 if (g_move_invader_normal_missile_flag[1]) {
avi23 5:34855f712350 299 g_move_invader_normal_missile_flag[1] = false;
avi23 5:34855f712350 300
avi23 5:34855f712350 301 MoveInvaderNormalMissile(1);
avi23 5:34855f712350 302 }
avi23 5:34855f712350 303
avi23 5:34855f712350 304 if (joystick.get_button_flag()) {
avi23 5:34855f712350 305 joystick.set_button_flag(0);
avi23 5:34855f712350 306
avi23 5:34855f712350 307 //Detach all game tickers
avi23 5:34855f712350 308 DetachTickers();
avi23 5:34855f712350 309 game_state = paused;
avi23 5:34855f712350 310 }
avi23 5:34855f712350 311 }
avi23 5:34855f712350 312
avi23 5:34855f712350 313 sleep();
avi23 5:34855f712350 314 }
avi23 2:d34c95990605 315 }
avi23 2:d34c95990605 316
avi23 7:babc367a3333 317 void InitaliseGame()
avi23 7:babc367a3333 318 {
avi23 7:babc367a3333 319 //Clears the screen buffer and runs init functions
avi23 7:babc367a3333 320 memset(screen_buffer, 0, sizeof(screen_buffer));
avi23 7:babc367a3333 321 no_of_alive_invaders = 15;
avi23 7:babc367a3333 322 score = 0;
avi23 7:babc367a3333 323 number_of_lives = 3;
avi23 7:babc367a3333 324 InitSmallInvaders();
avi23 7:babc367a3333 325 InitMediumInvaders();
avi23 7:babc367a3333 326 InitLargeInvaders();
avi23 7:babc367a3333 327 InitBarriers();
avi23 7:babc367a3333 328 //Sets the flags so enemies pop up straight away
avi23 7:babc367a3333 329 g_update_screen_flag = true;
avi23 7:babc367a3333 330 g_move_joystick_flag = true;
avi23 7:babc367a3333 331 g_move_enemies_flag = true;
avi23 7:babc367a3333 332 //Forces the missiles to have the fired flags to flase
avi23 7:babc367a3333 333 cannon_missile_on_screen = false;
avi23 7:babc367a3333 334 invader_normal_missile[0].fired = false;
avi23 7:babc367a3333 335 invader_normal_missile[1].fired = false;
avi23 7:babc367a3333 336 }
avi23 7:babc367a3333 337
avi23 5:34855f712350 338 void UpdateScreen()
avi23 2:d34c95990605 339 {
avi23 5:34855f712350 340 //Loops through the screen buffer and sets pixels on the LCD
avi23 5:34855f712350 341 for (int col = 0; col < 84; ++col) {
avi23 5:34855f712350 342 for (int row = 0; row < 48; ++row) {
avi23 5:34855f712350 343 if (screen_buffer[col][row]) {
avi23 5:34855f712350 344 lcd.setPixel(col, row);
avi23 5:34855f712350 345 } else {
avi23 5:34855f712350 346 lcd.clearPixel(col, row);
avi23 5:34855f712350 347 }
avi23 5:34855f712350 348 }
avi23 5:34855f712350 349 }
avi23 5:34855f712350 350
avi23 5:34855f712350 351 lcd.refresh();
avi23 2:d34c95990605 352 }
avi23 2:d34c95990605 353
avi23 2:d34c95990605 354 void MoveCannon()
avi23 0:427469992efe 355 {
avi23 7:babc367a3333 356 //Clears the cannon
avi23 5:34855f712350 357 for (int col = 0; col < 9; ++col) {
avi23 5:34855f712350 358 for (int row = 0; row < 5; ++row) {
avi23 1:b300d052d549 359 if(cannon_bitmap[row][col]) {
avi23 5:34855f712350 360 screen_buffer[cannon_xpos+col][cannon_ypos+row] = empty_pixel;
avi23 0:427469992efe 361 }
avi23 0:427469992efe 362 }
avi23 0:427469992efe 363 }
avi23 0:427469992efe 364
avi23 7:babc367a3333 365 //Changes the position of the cannon when the joystick is moved, capping at 0 and 75 so it always fits on the screen
avi23 0:427469992efe 366 if (joystick.GetXValue() < 0.25f) {
avi23 1:b300d052d549 367 cannon_xpos--;
avi23 1:b300d052d549 368 if (cannon_xpos < 0) {
avi23 1:b300d052d549 369 cannon_xpos = 0;
avi23 0:427469992efe 370 }
avi23 0:427469992efe 371 } else if (joystick.GetXValue() > 0.75f) {
avi23 1:b300d052d549 372 cannon_xpos++;
avi23 1:b300d052d549 373 if (cannon_xpos > 75) {
avi23 1:b300d052d549 374 cannon_xpos = 75;
avi23 0:427469992efe 375 }
avi23 0:427469992efe 376 }
avi23 0:427469992efe 377
avi23 7:babc367a3333 378 //Redraws the cannon
avi23 5:34855f712350 379 for (int col = 0; col < 9; ++col) {
avi23 5:34855f712350 380 for (int row = 0; row < 5; ++row) {
avi23 1:b300d052d549 381 if(cannon_bitmap[row][col]) {
avi23 5:34855f712350 382 screen_buffer[cannon_xpos+col][cannon_ypos+row] = cannon_pixel;
avi23 0:427469992efe 383 }
avi23 0:427469992efe 384 }
avi23 0:427469992efe 385 }
avi23 0:427469992efe 386 }
avi23 0:427469992efe 387
avi23 7:babc367a3333 388 //Sets the position and status of the small invaders
avi23 0:427469992efe 389 void InitSmallInvaders()
avi23 0:427469992efe 390 {
avi23 5:34855f712350 391 for (int i = 0; i < 5; ++i) {
avi23 7:babc367a3333 392 small_invader[i].x_pos = 2 + (i*13); // Large invaders are 12 across so add 13 for a gap space
avi23 2:d34c95990605 393 small_invader[i].y_pos = 1;
avi23 5:34855f712350 394 small_invader[i].status = alive;
avi23 0:427469992efe 395 }
avi23 0:427469992efe 396 }
avi23 0:427469992efe 397
avi23 5:34855f712350 398 //Cycles through all the small invaders. If they're not already dead clear them
avi23 2:d34c95990605 399 void ClearSmallInvaders()
avi23 2:d34c95990605 400 {
avi23 5:34855f712350 401 for (int i = 0; i < 5; ++i) {
avi23 5:34855f712350 402 if (small_invader[i].status) {
avi23 5:34855f712350 403 ClearSingleSmallInvader(i);
avi23 5:34855f712350 404 }
avi23 5:34855f712350 405 }
avi23 5:34855f712350 406 }
avi23 5:34855f712350 407
avi23 5:34855f712350 408 //Cycles through the the screen invader bitmap and sets the pixels in the buffer to 0
avi23 5:34855f712350 409 void ClearSingleSmallInvader(int invader_no)
avi23 5:34855f712350 410 {
avi23 5:34855f712350 411 for (int col = 0; col < 8; ++col) {
avi23 5:34855f712350 412 for (int row = 0; row < 6; ++row) {
avi23 5:34855f712350 413 if (invaders_in_state2) {
avi23 5:34855f712350 414 if (small_invader_bitmap_1[row][col]) {
avi23 5:34855f712350 415 screen_buffer[small_invader[invader_no].x_pos + col][small_invader[invader_no].y_pos + row] = empty_pixel;
avi23 2:d34c95990605 416 }
avi23 5:34855f712350 417 } else {
avi23 5:34855f712350 418 if (small_invader_bitmap_2[row][col]) {
avi23 5:34855f712350 419 screen_buffer[small_invader[invader_no].x_pos + col][small_invader[invader_no].y_pos + row] = empty_pixel;
avi23 2:d34c95990605 420 }
avi23 2:d34c95990605 421 }
avi23 2:d34c95990605 422 }
avi23 2:d34c95990605 423 }
avi23 5:34855f712350 424
avi23 5:34855f712350 425 small_invader[invader_no].status = (small_invader[invader_no].status == dying) ? dead : alive;
avi23 2:d34c95990605 426 }
avi23 2:d34c95990605 427
avi23 7:babc367a3333 428 //Cycles through all the small invaders. If they're alive set them in the screen buffer
avi23 0:427469992efe 429 void DrawSmallInvaders()
avi23 0:427469992efe 430 {
avi23 5:34855f712350 431 for (int i = 0; i < 5; ++i) {
avi23 5:34855f712350 432 if (small_invader[i].status == alive) {
avi23 5:34855f712350 433 DrawSingleSmallInvader(i);
avi23 5:34855f712350 434 }
avi23 5:34855f712350 435 }
avi23 5:34855f712350 436 }
avi23 5:34855f712350 437
avi23 5:34855f712350 438 //Cycles through the the screen invader bitmap and sets the pixels in the buffer
avi23 5:34855f712350 439 void DrawSingleSmallInvader(int invader_no)
avi23 5:34855f712350 440 {
avi23 5:34855f712350 441 for (int col = 0; col < 8; ++col) {
avi23 5:34855f712350 442 for (int row = 0; row < 6; ++row) {
avi23 2:d34c95990605 443 if (invaders_in_state2) {
avi23 5:34855f712350 444 if (small_invader_bitmap_1[row][col]) {
avi23 5:34855f712350 445 screen_buffer[small_invader[invader_no].x_pos + col][small_invader[invader_no].y_pos + row] = first_small_invader_pixel + invader_no;
avi23 0:427469992efe 446 }
avi23 0:427469992efe 447 } else {
avi23 5:34855f712350 448 if (small_invader_bitmap_2[row][col]) {
avi23 5:34855f712350 449 screen_buffer[small_invader[invader_no].x_pos + col][small_invader[invader_no].y_pos + row] = first_small_invader_pixel + invader_no;
avi23 0:427469992efe 450 }
avi23 0:427469992efe 451 }
avi23 0:427469992efe 452 }
avi23 0:427469992efe 453 }
avi23 1:b300d052d549 454 }
avi23 1:b300d052d549 455
avi23 1:b300d052d549 456 //Sets the position and aliveness of the medium invaders
avi23 1:b300d052d549 457 void InitMediumInvaders()
avi23 1:b300d052d549 458 {
avi23 5:34855f712350 459 for (int i = 0; i < 5; ++i) {
avi23 7:babc367a3333 460 medium_invader[i].x_pos = 1 + (i*13); // Large invaders are 12 across so add 13 for a gap space
avi23 2:d34c95990605 461 medium_invader[i].y_pos = 8;
avi23 5:34855f712350 462 medium_invader[i].status = alive;
avi23 1:b300d052d549 463 }
avi23 1:b300d052d549 464 }
avi23 1:b300d052d549 465
avi23 7:babc367a3333 466 //Cycles through all the medium invaders. If they're not already dead clear them
avi23 2:d34c95990605 467 void ClearMediumInvaders()
avi23 2:d34c95990605 468 {
avi23 5:34855f712350 469 for (int i = 0; i < 5; ++i) {
avi23 5:34855f712350 470 if (medium_invader[i].status) {
avi23 5:34855f712350 471 ClearSingleMediumInvader(i);
avi23 2:d34c95990605 472 }
avi23 2:d34c95990605 473 }
avi23 2:d34c95990605 474 }
avi23 2:d34c95990605 475
avi23 7:babc367a3333 476 //Cycles through the the screen invader bitmap and sets the pixels in the buffer to 0
avi23 5:34855f712350 477 void ClearSingleMediumInvader(int invader_no)
avi23 5:34855f712350 478 {
avi23 5:34855f712350 479 for (int col = 0; col < 10; ++col) {
avi23 5:34855f712350 480 for (int row = 0; row < 6; ++row) {
avi23 5:34855f712350 481 if (invaders_in_state2) {
avi23 5:34855f712350 482 if (medium_invader_bitmap_1[row][col]) {
avi23 5:34855f712350 483 screen_buffer[medium_invader[invader_no].x_pos + col][medium_invader[invader_no].y_pos + row] = empty_pixel;
avi23 5:34855f712350 484 }
avi23 5:34855f712350 485 } else {
avi23 5:34855f712350 486 if (medium_invader_bitmap_2[row][col]) {
avi23 5:34855f712350 487 screen_buffer[medium_invader[invader_no].x_pos + col][medium_invader[invader_no].y_pos + row] = empty_pixel;
avi23 5:34855f712350 488 }
avi23 5:34855f712350 489 }
avi23 5:34855f712350 490 }
avi23 5:34855f712350 491 }
avi23 5:34855f712350 492
avi23 5:34855f712350 493 medium_invader[invader_no].status = (medium_invader[invader_no].status == dying) ? dead : alive;
avi23 5:34855f712350 494 }
avi23 5:34855f712350 495
avi23 7:babc367a3333 496 //Cycles through all the medium invaders. If they're alive set them in the screen buffer
avi23 1:b300d052d549 497 void DrawMediumInvaders()
avi23 1:b300d052d549 498 {
avi23 5:34855f712350 499 for (int i = 0; i < 5; ++i) {
avi23 5:34855f712350 500 if (medium_invader[i].status == alive) {
avi23 5:34855f712350 501 DrawSingleMediumInvader(i);
avi23 5:34855f712350 502 }
avi23 5:34855f712350 503 }
avi23 5:34855f712350 504 }
avi23 5:34855f712350 505
avi23 7:babc367a3333 506 //Cycles through the the screen invader bitmap and sets the pixels in the buffer
avi23 5:34855f712350 507 void DrawSingleMediumInvader(int invader_no)
avi23 5:34855f712350 508 {
avi23 5:34855f712350 509 for (int col = 0; col < 10; ++col) {
avi23 5:34855f712350 510 for (int row = 0; row < 6; ++row) {
avi23 2:d34c95990605 511 if (invaders_in_state2) {
avi23 5:34855f712350 512 if (medium_invader_bitmap_1[row][col]) {
avi23 5:34855f712350 513 screen_buffer[medium_invader[invader_no].x_pos + col][medium_invader[invader_no].y_pos + row] = first_medium_invader_pixel + invader_no;
avi23 1:b300d052d549 514 }
avi23 1:b300d052d549 515 } else {
avi23 5:34855f712350 516 if (medium_invader_bitmap_2[row][col]) {
avi23 5:34855f712350 517 screen_buffer[medium_invader[invader_no].x_pos + col][medium_invader[invader_no].y_pos + row] = first_medium_invader_pixel + invader_no;
avi23 1:b300d052d549 518 }
avi23 1:b300d052d549 519 }
avi23 1:b300d052d549 520 }
avi23 1:b300d052d549 521 }
avi23 1:b300d052d549 522 }
avi23 1:b300d052d549 523
avi23 7:babc367a3333 524 //Sets the position and status of the large invaders
avi23 1:b300d052d549 525 void InitLargeInvaders()
avi23 1:b300d052d549 526 {
avi23 5:34855f712350 527 for (int i = 0; i < 5; ++i) {
avi23 1:b300d052d549 528 large_invader[i].x_pos = 0 + (i*13);
avi23 2:d34c95990605 529 large_invader[i].y_pos = 15;
avi23 5:34855f712350 530 large_invader[i].status = alive;
avi23 5:34855f712350 531 }
avi23 5:34855f712350 532 }
avi23 5:34855f712350 533
avi23 7:babc367a3333 534 //Cycles through all the large invaders. If they're not already dead clear them
avi23 5:34855f712350 535 void ClearLargeInvaders()
avi23 5:34855f712350 536 {
avi23 5:34855f712350 537 for (int i = 0; i < 5; ++i) {
avi23 5:34855f712350 538 if (large_invader[i].status) {
avi23 5:34855f712350 539 ClearSingleLargeInvader(i);
avi23 5:34855f712350 540 }
avi23 1:b300d052d549 541 }
avi23 1:b300d052d549 542 }
avi23 1:b300d052d549 543
avi23 5:34855f712350 544 //Loops through the large invader bitmap, if the pixel in the bitmap is set to 1, set the pixel in the buffer to 0
avi23 5:34855f712350 545 void ClearSingleLargeInvader(int invader_no)
avi23 2:d34c95990605 546 {
avi23 5:34855f712350 547 for (int col = 0; col < 12; ++col) {
avi23 5:34855f712350 548 for (int row = 0; row < 6; ++row) {
avi23 5:34855f712350 549 if (invaders_in_state2) {
avi23 5:34855f712350 550 if (large_invader_bitmap_1[row][col]) {
avi23 5:34855f712350 551 screen_buffer[large_invader[invader_no].x_pos + col][large_invader[invader_no].y_pos + row] = empty_pixel;
avi23 5:34855f712350 552 }
avi23 5:34855f712350 553 } else {
avi23 5:34855f712350 554 if (large_invader_bitmap_2[row][col]) {
avi23 5:34855f712350 555 screen_buffer[large_invader[invader_no].x_pos + col][large_invader[invader_no].y_pos + row] = empty_pixel;
avi23 2:d34c95990605 556 }
avi23 2:d34c95990605 557 }
avi23 5:34855f712350 558 }
avi23 5:34855f712350 559 }
avi23 5:34855f712350 560
avi23 5:34855f712350 561 large_invader[invader_no].status = (large_invader[invader_no].status == dying) ? dead : alive;
avi23 5:34855f712350 562 }
avi23 5:34855f712350 563
avi23 7:babc367a3333 564 //Cycles through all the large invaders. If they're alive set them in the screen buffer
avi23 5:34855f712350 565 void DrawLargeInvaders()
avi23 5:34855f712350 566 {
avi23 5:34855f712350 567 for (int i = 0; i < 5; ++i) {
avi23 5:34855f712350 568 if (large_invader[i].status == alive) {
avi23 5:34855f712350 569 DrawSingleLargeInvader(i);
avi23 5:34855f712350 570 }
avi23 5:34855f712350 571 }
avi23 5:34855f712350 572 }
avi23 5:34855f712350 573
avi23 7:babc367a3333 574 //Cycles through the the screen invader bitmap and sets the pixels in the buffer
avi23 5:34855f712350 575 void DrawSingleLargeInvader(int invader_no)
avi23 5:34855f712350 576 {
avi23 5:34855f712350 577 for (int col = 0; col < 12; ++col) {
avi23 5:34855f712350 578 for (int row = 0; row < 6; ++row) {
avi23 5:34855f712350 579 if (invaders_in_state2) {
avi23 5:34855f712350 580 if (large_invader_bitmap_1[row][col]) {
avi23 5:34855f712350 581 screen_buffer[large_invader[invader_no].x_pos + col][large_invader[invader_no].y_pos + row] = first_large_invader_pixel + invader_no;
avi23 5:34855f712350 582 }
avi23 5:34855f712350 583 } else {
avi23 5:34855f712350 584 if (large_invader_bitmap_2[row][col]) {
avi23 5:34855f712350 585 screen_buffer[large_invader[invader_no].x_pos + col][large_invader[invader_no].y_pos + row] = first_large_invader_pixel + invader_no;
avi23 2:d34c95990605 586 }
avi23 2:d34c95990605 587 }
avi23 2:d34c95990605 588 }
avi23 2:d34c95990605 589 }
avi23 2:d34c95990605 590 }
avi23 2:d34c95990605 591
avi23 7:babc367a3333 592 //Sets the position and loads the bitmap into the barrier objects
avi23 2:d34c95990605 593 void InitBarriers()
avi23 2:d34c95990605 594 {
avi23 5:34855f712350 595 for (int i = 0; i < 3; ++i) {
avi23 2:d34c95990605 596 barrier[i].x_pos = 10 + (i*25);
avi23 2:d34c95990605 597 barrier[i].y_pos = 33;
avi23 2:d34c95990605 598 //Copies the bitmap into the structs
avi23 2:d34c95990605 599 memcpy(barrier[i].before_bitmap, barrier_bitmap, sizeof(barrier_bitmap));
avi23 2:d34c95990605 600 memcpy(barrier[i].after_bitmap, barrier_bitmap, sizeof(barrier_bitmap));
avi23 2:d34c95990605 601 }
avi23 2:d34c95990605 602 }
avi23 2:d34c95990605 603
avi23 2:d34c95990605 604 void DrawBarriers()
avi23 2:d34c95990605 605 {
avi23 2:d34c95990605 606 //Clears the barrier and redraws it with damage applied
avi23 5:34855f712350 607 for (int i = 0; i < 3; ++i) {
avi23 5:34855f712350 608 for (int col = 0; col < 14; ++col) {
avi23 5:34855f712350 609 for (int row = 0; row < 8; ++row) {
avi23 2:d34c95990605 610 if (barrier[i].before_bitmap[row][col]) {
avi23 5:34855f712350 611 screen_buffer[barrier[i].x_pos + col][barrier[i].y_pos + row] = empty_pixel;
avi23 2:d34c95990605 612 }
avi23 2:d34c95990605 613 if (barrier[i].after_bitmap[row][col]) {
avi23 5:34855f712350 614 screen_buffer[barrier[i].x_pos + col][barrier[i].y_pos + row] = first_barrier_pixel + i;
avi23 2:d34c95990605 615 }
avi23 2:d34c95990605 616 }
avi23 2:d34c95990605 617 }
avi23 2:d34c95990605 618 //Copies the after array to the before array
avi23 2:d34c95990605 619 memcpy(barrier[i].before_bitmap, barrier[i].after_bitmap, sizeof(barrier[i].after_bitmap));
avi23 2:d34c95990605 620 }
avi23 2:d34c95990605 621 }
avi23 2:d34c95990605 622
avi23 5:34855f712350 623 void MoveInvaderXPositions()
avi23 2:d34c95990605 624 {
avi23 7:babc367a3333 625 //Moves the invader in the current direction
avi23 2:d34c95990605 626 if (invader_direction == RIGHT) {
avi23 7:babc367a3333 627 //Checking the right limit
avi23 7:babc367a3333 628 int right_invader_limit = CalculateInvaderRightLimit();
avi23 5:34855f712350 629 MoveInvadersRight(right_invader_limit);
avi23 5:34855f712350 630 } else {
avi23 7:babc367a3333 631 //Checks the left limit
avi23 7:babc367a3333 632 int left_invader_limit = CalculateInvaderLeftLimit();
avi23 5:34855f712350 633 MoveInvadersLeft(left_invader_limit);
avi23 5:34855f712350 634 }
avi23 5:34855f712350 635 }
avi23 5:34855f712350 636
avi23 7:babc367a3333 637 //Checks the status off the invaders per column, starting from the left
avi23 7:babc367a3333 638 //If they're alive return the row number
avi23 5:34855f712350 639 int CalculateInvaderLeftLimit()
avi23 5:34855f712350 640 {
avi23 5:34855f712350 641 for (int i = 0; i < 5; ++i) {
avi23 5:34855f712350 642 if (small_invader[i].status == alive || medium_invader[i].status == alive || large_invader[i].status == alive) {
avi23 5:34855f712350 643 return i;
avi23 5:34855f712350 644 }
avi23 5:34855f712350 645 }
avi23 5:34855f712350 646
avi23 5:34855f712350 647 //Sort gameover out stuff after
avi23 5:34855f712350 648 return 4;
avi23 5:34855f712350 649 }
avi23 5:34855f712350 650
avi23 7:babc367a3333 651 //Checks the status off the invaders per column, starting from the right
avi23 7:babc367a3333 652 //If they're alive return the row number
avi23 5:34855f712350 653 int CalculateInvaderRightLimit()
avi23 5:34855f712350 654 {
avi23 5:34855f712350 655 for (int i = 4; i >= 0; --i) {
avi23 5:34855f712350 656 if (small_invader[i].status == alive || medium_invader[i].status == alive || large_invader[i].status == alive) {
avi23 5:34855f712350 657 return i;
avi23 5:34855f712350 658 }
avi23 5:34855f712350 659 }
avi23 5:34855f712350 660
avi23 5:34855f712350 661 //Sort gameover stuff
avi23 5:34855f712350 662 return 0;
avi23 5:34855f712350 663 }
avi23 5:34855f712350 664
avi23 5:34855f712350 665 void MoveInvadersLeft(int limit)
avi23 5:34855f712350 666 {
avi23 5:34855f712350 667 //Checks the first large invader to see if it can travel anymore
avi23 5:34855f712350 668 if (large_invader[limit].x_pos > 1) {
avi23 5:34855f712350 669 for (int i = 0; i < 5; ++i) {
avi23 7:babc367a3333 670 //Moves the invaders 2 to the left
avi23 5:34855f712350 671 small_invader[i].x_pos -= 2;
avi23 5:34855f712350 672 medium_invader[i].x_pos -= 2;
avi23 5:34855f712350 673 large_invader[i].x_pos -= 2;
avi23 2:d34c95990605 674 }
avi23 2:d34c95990605 675 } else {
avi23 5:34855f712350 676 //Shifts the Invaders down and passes in the new direction
avi23 5:34855f712350 677 MoveInvaderYPositions(RIGHT);
avi23 2:d34c95990605 678 }
avi23 2:d34c95990605 679 }
avi23 2:d34c95990605 680
avi23 5:34855f712350 681 void MoveInvadersRight(int limit)
avi23 2:d34c95990605 682 {
avi23 5:34855f712350 683 //Checks the first large invader to see if it can travel anymore
avi23 5:34855f712350 684 if (large_invader[limit].x_pos < 71) {
avi23 7:babc367a3333 685 //Moves the invaders 2 to the right
avi23 5:34855f712350 686 for (int i = 0; i < 5; ++i) {
avi23 5:34855f712350 687 small_invader[i].x_pos += 2;
avi23 5:34855f712350 688 medium_invader[i].x_pos += 2;
avi23 5:34855f712350 689 large_invader[i].x_pos += 2;
avi23 5:34855f712350 690 }
avi23 2:d34c95990605 691 } else {
avi23 5:34855f712350 692 //Shifts the Invaders down and passes in the new direction
avi23 5:34855f712350 693 MoveInvaderYPositions(LEFT);
avi23 2:d34c95990605 694 }
avi23 5:34855f712350 695 }
avi23 5:34855f712350 696
avi23 5:34855f712350 697 void MoveInvaderYPositions(bool new_direction)
avi23 5:34855f712350 698 {
avi23 5:34855f712350 699 //Finds the invaders lower limit
avi23 5:34855f712350 700 Invader lowest_invader = CalculateInvaderYLimit();
avi23 5:34855f712350 701
avi23 5:34855f712350 702 //When moving down lowest_invader should not equal none
avi23 5:34855f712350 703 if (lowest_invader == none) {
avi23 5:34855f712350 704 error();
avi23 5:34855f712350 705 }
avi23 5:34855f712350 706
avi23 2:d34c95990605 707 //If an invader touches the bottom the game ends, otherwise the invaders descend
avi23 5:34855f712350 708 if (small_invader[0].y_pos < 33 - (7*lowest_invader)) {
avi23 5:34855f712350 709 for (int i = 0; i < 5; ++i) {
avi23 2:d34c95990605 710 small_invader[i].y_pos += 3;
avi23 2:d34c95990605 711 medium_invader[i].y_pos += 3;
avi23 2:d34c95990605 712 large_invader[i].y_pos += 3;
avi23 2:d34c95990605 713 }
avi23 5:34855f712350 714 invader_direction = new_direction;
avi23 5:34855f712350 715 } else {
avi23 5:34855f712350 716 number_of_lives = 0;
avi23 5:34855f712350 717 }
avi23 5:34855f712350 718 }
avi23 5:34855f712350 719
avi23 5:34855f712350 720 Invader CalculateInvaderYLimit()
avi23 5:34855f712350 721 {
avi23 5:34855f712350 722 //Checks to see which row of invaders are still alive to work out maximum y positions
avi23 5:34855f712350 723 if (large_invader[0].status == alive || large_invader[1].status == alive || large_invader[2].status == alive || large_invader[3].status == alive || large_invader[4].status == alive) {
avi23 5:34855f712350 724 return large;
avi23 5:34855f712350 725 } else if (medium_invader[0].status == alive || medium_invader[1].status == alive || medium_invader[2].status == alive || medium_invader[3].status == alive || medium_invader[4].status == alive) {
avi23 5:34855f712350 726 return medium;
avi23 2:d34c95990605 727 } else {
avi23 5:34855f712350 728 return small;
avi23 2:d34c95990605 729 }
avi23 5:34855f712350 730 }
avi23 2:d34c95990605 731
avi23 5:34855f712350 732 //Queries the invaders on their status and returns the type of invader which is alive
avi23 5:34855f712350 733 Invader LowestInvaderInColumn(int column)
avi23 5:34855f712350 734 {
avi23 5:34855f712350 735 if (large_invader[column].status == alive) {
avi23 5:34855f712350 736 return large;
avi23 5:34855f712350 737 } else if (medium_invader[column].status == alive) {
avi23 5:34855f712350 738 return medium;
avi23 5:34855f712350 739 } else if (small_invader[column].status == alive) {
avi23 5:34855f712350 740 return small;
avi23 5:34855f712350 741 } else {
avi23 5:34855f712350 742 return none;
avi23 5:34855f712350 743 }
avi23 2:d34c95990605 744 }
avi23 2:d34c95990605 745
avi23 2:d34c95990605 746 /*
avi23 2:d34c95990605 747 void InitUFO()
avi23 2:d34c95990605 748 {
avi23 2:d34c95990605 749
avi23 2:d34c95990605 750 }
avi23 2:d34c95990605 751 */
avi23 2:d34c95990605 752
avi23 2:d34c95990605 753 void DrawUFO()
avi23 2:d34c95990605 754 {
avi23 2:d34c95990605 755 //Draws the UFO
avi23 2:d34c95990605 756 int x_pos = 20;
avi23 2:d34c95990605 757 int y_pos = 25;
avi23 5:34855f712350 758 for (int col = 0; col < col_no; ++col) {
avi23 5:34855f712350 759 for (int row = 0; row < row_no; ++row) {
avi23 2:d34c95990605 760 if(ufo_bitmap[row][col]) {
avi23 5:34855f712350 761 screen_buffer[x_pos + col][y_pos + row] = ufo_pixel;
avi23 2:d34c95990605 762 }
avi23 2:d34c95990605 763 }
avi23 2:d34c95990605 764 }
avi23 5:34855f712350 765 }
avi23 5:34855f712350 766
avi23 5:34855f712350 767 void FireCannonMissile()
avi23 5:34855f712350 768 {
avi23 7:babc367a3333 769 //Sets the cannon fired flag to true
avi23 5:34855f712350 770 cannon_missile_on_screen = true;
avi23 5:34855f712350 771
avi23 7:babc367a3333 772 //Offset cannon missile x position by 4 of the cannons x pos
avi23 5:34855f712350 773 cannon_missile_x_pos = cannon_xpos + 4;
avi23 7:babc367a3333 774 //Will always have a starting y of 40
avi23 5:34855f712350 775 cannon_missile_y_pos = 40;
avi23 7:babc367a3333 776 //Attach the move cannon missile
avi23 5:34855f712350 777 move_cannon_missile.attach(&move_cannon_missile_isr, 0.05);
avi23 5:34855f712350 778 }
avi23 5:34855f712350 779
avi23 5:34855f712350 780 void MoveCannonMissile()
avi23 5:34855f712350 781 {
avi23 5:34855f712350 782 //Checks bullet will not go beyond the bounds of the screen buffer
avi23 5:34855f712350 783 if (cannon_missile_y_pos > -1) {
avi23 5:34855f712350 784 //Loops throught the shot bitmap and clears the pixels in the screen buffer
avi23 5:34855f712350 785 for (int row = 0; row < 4; ++row) {
avi23 5:34855f712350 786 //Clears the position where the bullet was
avi23 5:34855f712350 787 screen_buffer[cannon_missile_x_pos][cannon_missile_y_pos + row] = empty_pixel;
avi23 5:34855f712350 788 }
avi23 5:34855f712350 789
avi23 5:34855f712350 790 //Increments the shot going up the screen
avi23 5:34855f712350 791 --cannon_missile_y_pos;
avi23 5:34855f712350 792
avi23 5:34855f712350 793 //Checks to see if the shot will hit anything
avi23 5:34855f712350 794 CollisionDetectionCannonMissile();
avi23 5:34855f712350 795 } else {
avi23 5:34855f712350 796 //Loops throught the shot bitmap and clears the pixels in the screen buffer
avi23 5:34855f712350 797 for (int row = 1; row < 4; ++row) {
avi23 5:34855f712350 798 //Clears the position where the bullet was
avi23 5:34855f712350 799 screen_buffer[cannon_missile_x_pos][cannon_missile_y_pos + row] = empty_pixel;
avi23 5:34855f712350 800 }
avi23 5:34855f712350 801
avi23 5:34855f712350 802 cannon_missile_on_screen = false;
avi23 5:34855f712350 803 move_cannon_missile.detach();
avi23 5:34855f712350 804 }
avi23 5:34855f712350 805 }
avi23 5:34855f712350 806
avi23 5:34855f712350 807 //Checks to see what the shot hits. If it hits nothing the shot gets pushed to the screen buffer
avi23 5:34855f712350 808 void CollisionDetectionCannonMissile()
avi23 5:34855f712350 809 {
avi23 5:34855f712350 810 for (int row = 0; row < 4; ++row) {
avi23 5:34855f712350 811 int object_no;
avi23 7:babc367a3333 812 int pixel_check = screen_buffer[cannon_missile_x_pos][cannon_missile_y_pos + row];
avi23 7:babc367a3333 813 pc.printf("Pixel check: %d\n", pixel_check);
avi23 7:babc367a3333 814 if (pixel_check >= first_small_invader_pixel && pixel_check < ufo_pixel) { //Collides with a small invader
avi23 7:babc367a3333 815 //Find the object no of the small invader it hit, clears it and increments the score
avi23 5:34855f712350 816 object_no = CannonMissileHitInvader(first_small_invader_pixel, row, small_invader);
avi23 5:34855f712350 817 ClearSingleSmallInvader(object_no);
avi23 5:34855f712350 818 score += 40;
avi23 5:34855f712350 819 break;
avi23 7:babc367a3333 820 } else if (pixel_check >= first_medium_invader_pixel && pixel_check < first_small_invader_pixel) { //Collides with a medium invader
avi23 7:babc367a3333 821 //Find the object no of the medium invader it hit, clears it and increments the score
avi23 5:34855f712350 822 object_no = CannonMissileHitInvader(first_medium_invader_pixel, row, medium_invader);
avi23 5:34855f712350 823 ClearSingleMediumInvader(object_no);
avi23 5:34855f712350 824 score += 20;
avi23 5:34855f712350 825 break;
avi23 7:babc367a3333 826 } else if (pixel_check >= first_large_invader_pixel && pixel_check < first_medium_invader_pixel) { //Collides with a large invader
avi23 7:babc367a3333 827 //Find the object no of the large invader it hit, clears it and increments the score
avi23 5:34855f712350 828 object_no = CannonMissileHitInvader(first_large_invader_pixel, row, large_invader);
avi23 5:34855f712350 829 ClearSingleLargeInvader(object_no);
avi23 5:34855f712350 830 score += 10;
avi23 5:34855f712350 831 break;
avi23 7:babc367a3333 832 } else if (pixel_check >= first_barrier_pixel && pixel_check < (first_barrier_pixel + 3)) { //Collides with a barrier
avi23 7:babc367a3333 833 //Adds the destruction done to the barrier to the bitmap and redraws the barriers
avi23 7:babc367a3333 834 CannonMissileHitBarrier(row);
avi23 5:34855f712350 835 DrawBarriers();
avi23 5:34855f712350 836 break;
avi23 7:babc367a3333 837 } else if (pixel_check == ufo_pixel) { //Collides with a UFO
avi23 5:34855f712350 838 pc.printf("UFO Hit\n");
avi23 5:34855f712350 839 cannon_missile_on_screen = false;
avi23 5:34855f712350 840 move_cannon_missile.detach();
avi23 5:34855f712350 841 break;
avi23 5:34855f712350 842 } else {
avi23 5:34855f712350 843 screen_buffer[cannon_missile_x_pos][cannon_missile_y_pos + row] = cannon_missile_pixel;
avi23 5:34855f712350 844 }
avi23 5:34855f712350 845 }
avi23 5:34855f712350 846 }
avi23 5:34855f712350 847
avi23 7:babc367a3333 848 //Finds the invader number the missile hits, sets the hit invader to dying, decrements the no_of_alive_invaders and stops the shot from travalling up the screen
avi23 5:34855f712350 849 int CannonMissileHitInvader(int first_pixel, int row, struct Invaders (&invader)[5])
avi23 5:34855f712350 850 {
avi23 5:34855f712350 851 int invader_no = screen_buffer[cannon_missile_x_pos][cannon_missile_y_pos + row] - first_pixel;
avi23 5:34855f712350 852 invader[invader_no].status = dying;
avi23 5:34855f712350 853 cannon_missile_on_screen = false;
avi23 5:34855f712350 854 --no_of_alive_invaders;
avi23 5:34855f712350 855 move_cannon_missile.detach();
avi23 5:34855f712350 856
avi23 5:34855f712350 857 return invader_no;
avi23 5:34855f712350 858 }
avi23 5:34855f712350 859
avi23 5:34855f712350 860 //Calculates where to start drawing the damage bitmap over the barrier bitmap and performs the operation
avi23 7:babc367a3333 861 void CannonMissileHitBarrier(int row)
avi23 5:34855f712350 862 {
avi23 7:babc367a3333 863 int barrier_no = screen_buffer[cannon_missile_x_pos][cannon_missile_y_pos + row] - first_barrier_pixel;
avi23 5:34855f712350 864 //Essentially inverse of barrier init
avi23 5:34855f712350 865 int relative_x_pos = cannon_missile_x_pos - 10 - (barrier_no*25) - 1;
avi23 5:34855f712350 866 int relative_y_pos = (cannon_missile_y_pos + row) - 33 - 1; //Don't know why it's -1 and not -2
avi23 5:34855f712350 867 //Loops through the damage bitmap and modifies the barrier's after bitmap
avi23 5:34855f712350 868 for (int col = 0; col < 3; ++col) {
avi23 5:34855f712350 869 for (int row_bit = 0; row_bit < 3; ++row_bit) {
avi23 5:34855f712350 870 //Makes sure bitmap index does not go out of bounds. If it does go to the next iteration
avi23 7:babc367a3333 871 //Element by element multiplication of the 2 bitmaps to clear the required pixals
avi23 5:34855f712350 872 if (relative_x_pos + col >= 0 && relative_x_pos + col < 14 && relative_y_pos + row_bit >= 0 && relative_y_pos + row_bit < 8) {
avi23 5:34855f712350 873 barrier[barrier_no].after_bitmap[relative_y_pos + row_bit][relative_x_pos + col] *= barrier_cannon_missile_damage_bitmap[row_bit][col];
avi23 5:34855f712350 874 }
avi23 5:34855f712350 875 }
avi23 5:34855f712350 876 }
avi23 5:34855f712350 877 cannon_missile_on_screen = false;
avi23 5:34855f712350 878 move_cannon_missile.detach();
avi23 5:34855f712350 879 }
avi23 5:34855f712350 880
avi23 5:34855f712350 881 void AttemptToFireInvaderNormalMissiles()
avi23 5:34855f712350 882 {
avi23 5:34855f712350 883 //Fires the normal missiles
avi23 5:34855f712350 884 //Loops through the 2 allowed missiles and if they're not on the screen, randomly fire
avi23 5:34855f712350 885 for (int i = 0; i < 2; ++i) {
avi23 5:34855f712350 886 if (!invader_normal_missile[i].fired) {
avi23 5:34855f712350 887 //If the random mumber is 1, fire a missile
avi23 5:34855f712350 888 //Higher chance when there are less invaders on the screen, up to a 1/3 chance
avi23 5:34855f712350 889 if ((rand() % (no_of_alive_invaders + 2)) == 1) {
avi23 5:34855f712350 890 // if ((rand() % 5) == 1) {
avi23 5:34855f712350 891 int fired_column;
avi23 5:34855f712350 892 int loop_limit = 0; //Stops loop from never ending
avi23 5:34855f712350 893 Invader missile_source;
avi23 5:34855f712350 894 do {
avi23 5:34855f712350 895 fired_column = rand() % 5;
avi23 5:34855f712350 896 missile_source = LowestInvaderInColumn(fired_column);
avi23 5:34855f712350 897 ++loop_limit;
avi23 5:34855f712350 898 } while (missile_source == none && loop_limit < 10);
avi23 5:34855f712350 899
avi23 5:34855f712350 900 //Finds the centre point of the chosen invader and fires the missile
avi23 5:34855f712350 901 //If the loop limit is reached, the missile source will be none and the for loop will jump to the next iteration
avi23 5:34855f712350 902 if (missile_source == none) {
avi23 5:34855f712350 903 continue;
avi23 5:34855f712350 904 } else if (missile_source == large) {
avi23 5:34855f712350 905 FireNormalInvaderMissile(i, missile_source, large_invader[fired_column]);
avi23 5:34855f712350 906 } else if (missile_source == medium) {
avi23 5:34855f712350 907 FireNormalInvaderMissile(i, missile_source, medium_invader[fired_column]);
avi23 5:34855f712350 908 } else {
avi23 5:34855f712350 909 FireNormalInvaderMissile(i, missile_source, small_invader[fired_column]);
avi23 5:34855f712350 910 }
avi23 5:34855f712350 911 }
avi23 5:34855f712350 912 }
avi23 5:34855f712350 913 }
avi23 5:34855f712350 914 }
avi23 5:34855f712350 915
avi23 5:34855f712350 916 void FireNormalInvaderMissile(int missile_no, Invader source, const struct Invaders (&invader))
avi23 5:34855f712350 917 {
avi23 5:34855f712350 918 //Finds the centre point of the chosen invader and fires the missile
avi23 5:34855f712350 919 //Enums are implicity converted to ints --> the middle x position of the invader found by offsetting the invader type by 3
avi23 5:34855f712350 920 invader_normal_missile[missile_no].x_pos = invader.x_pos + (3 + source);
avi23 5:34855f712350 921 invader_normal_missile[missile_no].y_pos = invader.y_pos + 6;
avi23 5:34855f712350 922 invader_normal_missile[missile_no].fired = true;
avi23 5:34855f712350 923
avi23 5:34855f712350 924 //Uses a function pointer to attach the ticker
avi23 5:34855f712350 925 move_invader_normal_missile[missile_no].attach(move_invader_normal_missile_isr[missile_no], 0.05);
avi23 5:34855f712350 926 }
avi23 5:34855f712350 927
avi23 7:babc367a3333 928 void MoveInvaderNormalMissile(int missile_no)
avi23 7:babc367a3333 929 {
avi23 7:babc367a3333 930 //Loops through the bitmap and clears the missile from the screen buffer
avi23 7:babc367a3333 931 for (int col = 0; col < 3; ++col) {
avi23 7:babc367a3333 932 for (int row = 0; row < 4; ++row) {
avi23 7:babc367a3333 933 if (invader_normal_missile_bitmap[row][col]) {
avi23 7:babc367a3333 934 screen_buffer[invader_normal_missile[missile_no].x_pos + col][invader_normal_missile[missile_no].y_pos + row] = empty_pixel;
avi23 7:babc367a3333 935 }
avi23 7:babc367a3333 936 }
avi23 7:babc367a3333 937 }
avi23 7:babc367a3333 938
avi23 7:babc367a3333 939 //Checks missile will not exceed screen buffer
avi23 7:babc367a3333 940 if (invader_normal_missile[missile_no].y_pos < 44) {
avi23 7:babc367a3333 941 //Increments the position of the missile
avi23 7:babc367a3333 942 ++invader_normal_missile[missile_no].y_pos;
avi23 7:babc367a3333 943
avi23 7:babc367a3333 944 //Collision detection
avi23 7:babc367a3333 945 CollisionDetectionInvaderNormalMissile(missile_no);
avi23 7:babc367a3333 946
avi23 7:babc367a3333 947 } else {
avi23 7:babc367a3333 948 //Sets the missiles fired flag as false and detaches the tickers
avi23 7:babc367a3333 949 invader_normal_missile[missile_no].fired = false;
avi23 7:babc367a3333 950 move_invader_normal_missile[missile_no].detach();
avi23 7:babc367a3333 951 }
avi23 7:babc367a3333 952 }
avi23 7:babc367a3333 953
avi23 7:babc367a3333 954 //Checks the bottom centre point for a collision. If it doesn't push the bitmap to the screen buffer
avi23 7:babc367a3333 955 void CollisionDetectionInvaderNormalMissile(int missile_no)
avi23 7:babc367a3333 956 {
avi23 7:babc367a3333 957 //Invader missile coordinates shifted to match centre bottom of bitmap
avi23 7:babc367a3333 958 int relative_x_pos = invader_normal_missile[missile_no].x_pos + 1;
avi23 7:babc367a3333 959 int relative_y_pos = invader_normal_missile[missile_no].y_pos + 3;
avi23 7:babc367a3333 960 if (screen_buffer[relative_x_pos][relative_y_pos] == cannon_pixel) {
avi23 7:babc367a3333 961 InvaderNormalMissileHitCannon();
avi23 7:babc367a3333 962 invader_normal_missile[missile_no].fired = false;
avi23 7:babc367a3333 963 move_invader_normal_missile[missile_no].detach();
avi23 7:babc367a3333 964 } else if (screen_buffer[relative_x_pos][relative_y_pos] >= first_barrier_pixel && screen_buffer[relative_x_pos][relative_y_pos] < (first_barrier_pixel + 3)) {
avi23 7:babc367a3333 965 //Finds barrier number
avi23 7:babc367a3333 966 InvaderNormalMissileHitBarrier(invader_normal_missile[missile_no]);
avi23 7:babc367a3333 967 invader_normal_missile[missile_no].fired = false;
avi23 7:babc367a3333 968 move_invader_normal_missile[missile_no].detach();
avi23 7:babc367a3333 969 } else {
avi23 7:babc367a3333 970 for (int col = 0; col < 3; ++col) {
avi23 7:babc367a3333 971 for (int row = 0; row < 4; ++row) {
avi23 7:babc367a3333 972 if (invader_normal_missile_bitmap[row][col]) {
avi23 7:babc367a3333 973 screen_buffer[invader_normal_missile[missile_no].x_pos + col][invader_normal_missile[missile_no].y_pos + row] = invader_normal_missile_pixel;
avi23 7:babc367a3333 974 }
avi23 7:babc367a3333 975 }
avi23 7:babc367a3333 976 }
avi23 7:babc367a3333 977 }
avi23 7:babc367a3333 978 }
avi23 7:babc367a3333 979
avi23 7:babc367a3333 980 void InvaderNormalMissileHitCannon()
avi23 7:babc367a3333 981 {
avi23 7:babc367a3333 982 //Decrements the number of lives, pauses the game for 2 seconds
avi23 7:babc367a3333 983 //Marks the cannon as hit
avi23 7:babc367a3333 984 g_cannon_hit_flag = true;
avi23 7:babc367a3333 985 //Detaches all tickers
avi23 7:babc367a3333 986 DetachTickers();
avi23 7:babc367a3333 987 //Creates a Timeout object on the stack with a period of 2 seconds to pause the game for 2 seconds
avi23 7:babc367a3333 988 Timeout cannon_hit;
avi23 7:babc367a3333 989 cannon_hit.attach(&cannon_hit_isr, 2);
avi23 7:babc367a3333 990 while (g_cannon_hit_flag) {
avi23 7:babc367a3333 991 sleep();
avi23 7:babc367a3333 992 }
avi23 7:babc367a3333 993 AttachTickers();
avi23 7:babc367a3333 994 --number_of_lives;
avi23 7:babc367a3333 995 }
avi23 7:babc367a3333 996
avi23 7:babc367a3333 997 //Calculates where to start drawing the damage bitmap over the barrier bitmap and performs the operation
avi23 7:babc367a3333 998 void InvaderNormalMissileHitBarrier(const struct InvaderNormalMissiles (&missile))
avi23 7:babc367a3333 999 {
avi23 7:babc367a3333 1000 int barrier_no = screen_buffer[missile.x_pos + 1][missile.y_pos + 3] - first_barrier_pixel;
avi23 7:babc367a3333 1001 //Essentially inverse of barrier init
avi23 7:babc367a3333 1002 int relative_x_pos = (missile.x_pos + 1) - 10 - (barrier_no*25) - 1;
avi23 7:babc367a3333 1003 int relative_y_pos = (missile.y_pos + 3) - 33;
avi23 7:babc367a3333 1004 //Loops through the damage bitmap and modifies the barrier's after bitmap
avi23 7:babc367a3333 1005 for (int col = 0; col < 3; ++col) {
avi23 7:babc367a3333 1006 for (int row_bit = 0; row_bit < 2; ++row_bit) {
avi23 7:babc367a3333 1007 //Makes sure bitmap index does not go out of bounds. If it does go to the next iteration
avi23 7:babc367a3333 1008 if (relative_x_pos + col >= 0 && relative_x_pos + col < 14 && relative_y_pos + row_bit >= 0 && relative_y_pos + row_bit < 8) {
avi23 7:babc367a3333 1009 barrier[barrier_no].after_bitmap[relative_y_pos + row_bit][relative_x_pos + col] *= barrier_invader_normal_missile_damage_bitmap[row_bit][col];
avi23 7:babc367a3333 1010 }
avi23 7:babc367a3333 1011 }
avi23 7:babc367a3333 1012 }
avi23 7:babc367a3333 1013 }
avi23 7:babc367a3333 1014
avi23 7:babc367a3333 1015 //Detaches game related tickers
avi23 5:34855f712350 1016 void DetachTickers()
avi23 5:34855f712350 1017 {
avi23 5:34855f712350 1018 update_screen.detach();
avi23 5:34855f712350 1019 move_enemies.detach();
avi23 7:babc367a3333 1020 //Only detaches if missiles are on the screen
avi23 5:34855f712350 1021 if (cannon_missile_on_screen) {
avi23 5:34855f712350 1022 move_cannon_missile.detach();
avi23 5:34855f712350 1023 }
avi23 5:34855f712350 1024 for (int i = 0; i < 2; ++i) {
avi23 5:34855f712350 1025 if (invader_normal_missile[i].fired) {
avi23 5:34855f712350 1026 move_invader_normal_missile[i].detach();
avi23 5:34855f712350 1027 }
avi23 5:34855f712350 1028 }
avi23 5:34855f712350 1029 }
avi23 5:34855f712350 1030
avi23 7:babc367a3333 1031 //Attaches game related tickers
avi23 5:34855f712350 1032 void AttachTickers()
avi23 5:34855f712350 1033 {
avi23 5:34855f712350 1034 update_screen.attach(&update_screen_isr, 0.05);
avi23 5:34855f712350 1035 move_enemies.attach(&move_enemies_isr, ticker_period);
avi23 7:babc367a3333 1036 //Only attaches if missiles were on the screen
avi23 5:34855f712350 1037 if (cannon_missile_on_screen) {
avi23 5:34855f712350 1038 move_cannon_missile.attach(&move_cannon_missile_isr, 0.05);
avi23 5:34855f712350 1039 }
avi23 5:34855f712350 1040 for (int i = 0; i < 2; ++i) {
avi23 5:34855f712350 1041 if (invader_normal_missile[i].fired) {
avi23 5:34855f712350 1042 move_invader_normal_missile[i].attach(move_invader_normal_missile_isr[i], 0.05);
avi23 5:34855f712350 1043 }
avi23 5:34855f712350 1044 }
avi23 6:89d4a7f7588b 1045 }
avi23 6:89d4a7f7588b 1046
avi23 6:89d4a7f7588b 1047 void PauseScreen()
avi23 6:89d4a7f7588b 1048 {
avi23 7:babc367a3333 1049 //Prints the pause screen, score etc
avi23 7:babc367a3333 1050 PrintPauseScreen();
avi23 7:babc367a3333 1051
avi23 6:89d4a7f7588b 1052 while (game_state == paused) {
avi23 6:89d4a7f7588b 1053 //Draws the cursor
avi23 6:89d4a7f7588b 1054 cursor_y_pos = ((fsm_state+3)*8)+3; //Adds 3 to the fsm state to get the bank, multiplies it by 8 to get the pixel no and offsets it by 3
avi23 6:89d4a7f7588b 1055 lcd.drawRect(74, cursor_y_pos, 2, 2, 1); //Draws the cursor
avi23 6:89d4a7f7588b 1056
avi23 6:89d4a7f7588b 1057 if (g_move_joystick_flag) {
avi23 6:89d4a7f7588b 1058 g_move_joystick_flag = false;
avi23 6:89d4a7f7588b 1059
avi23 6:89d4a7f7588b 1060 //Moves the cursor to match the selected option, only if the joystick isn't centred
avi23 6:89d4a7f7588b 1061 MoveCursor(fsm_paused);
avi23 6:89d4a7f7588b 1062 }
avi23 6:89d4a7f7588b 1063
avi23 6:89d4a7f7588b 1064 //If the button is pressed the selected option will appear on the screen
avi23 6:89d4a7f7588b 1065 if (g_shoot_pressed_flag) {
avi23 6:89d4a7f7588b 1066 g_shoot_pressed_flag = false;
avi23 6:89d4a7f7588b 1067 game_state = fsm_paused[fsm_state].output;
avi23 6:89d4a7f7588b 1068 }
avi23 6:89d4a7f7588b 1069
avi23 6:89d4a7f7588b 1070 //Resets the joystick flag to false if pressed
avi23 6:89d4a7f7588b 1071 if (joystick.get_button_flag()) {
avi23 6:89d4a7f7588b 1072 joystick.set_button_flag(0);
avi23 6:89d4a7f7588b 1073 }
avi23 6:89d4a7f7588b 1074
avi23 6:89d4a7f7588b 1075 lcd.refresh();
avi23 6:89d4a7f7588b 1076
avi23 6:89d4a7f7588b 1077 sleep();
avi23 6:89d4a7f7588b 1078 }
avi23 6:89d4a7f7588b 1079 }
avi23 6:89d4a7f7588b 1080
avi23 6:89d4a7f7588b 1081 void PrintPauseScreen()
avi23 6:89d4a7f7588b 1082 {
avi23 6:89d4a7f7588b 1083 //Prints paused and a line underneath
avi23 6:89d4a7f7588b 1084 lcd.printString("Paused", 24, 0);
avi23 6:89d4a7f7588b 1085 //Displays the current score
avi23 6:89d4a7f7588b 1086 char buffer[14];
avi23 6:89d4a7f7588b 1087 sprintf(buffer, "Score: %d", score);
avi23 6:89d4a7f7588b 1088 lcd.printString(buffer, 0, 1);
avi23 6:89d4a7f7588b 1089 //Displays the no of lives
avi23 6:89d4a7f7588b 1090 sprintf(buffer, "Lives: %d", number_of_lives);
avi23 6:89d4a7f7588b 1091 lcd.printString(buffer, 0, 2);
avi23 6:89d4a7f7588b 1092 lcd.drawLine(0, 23, 83, 23, 2);
avi23 6:89d4a7f7588b 1093 //Prints options on pause menu
avi23 6:89d4a7f7588b 1094 lcd.printString("Resume", 5, 3);
avi23 6:89d4a7f7588b 1095 lcd.printString("Save", 5, 4);
avi23 6:89d4a7f7588b 1096 lcd.printString("Quit", 5, 5);
avi23 6:89d4a7f7588b 1097 }
avi23 6:89d4a7f7588b 1098
avi23 6:89d4a7f7588b 1099 void MoveCursor(const struct FSMMenus *fsm)
avi23 6:89d4a7f7588b 1100 {
avi23 6:89d4a7f7588b 1101 //If the joystick is is pushed down half way clear the cursor and set the next state
avi23 6:89d4a7f7588b 1102 if (joystick.GetYValue() < 0.25f) {
avi23 6:89d4a7f7588b 1103 //Clears the cursor
avi23 6:89d4a7f7588b 1104 lcd.drawRect(74, cursor_y_pos, 2, 2, 2);
avi23 6:89d4a7f7588b 1105 //Sets the new state
avi23 6:89d4a7f7588b 1106 fsm_state = fsm[fsm_state].next_state[0];
avi23 6:89d4a7f7588b 1107 } else if (joystick.GetYValue() > 0.75f) {
avi23 6:89d4a7f7588b 1108 //Clears the cursor
avi23 6:89d4a7f7588b 1109 lcd.drawRect(74, cursor_y_pos, 2, 2, 2);
avi23 6:89d4a7f7588b 1110 //Sets the new state
avi23 6:89d4a7f7588b 1111 fsm_state = fsm[fsm_state].next_state[1];
avi23 6:89d4a7f7588b 1112 }
avi23 0:427469992efe 1113 }