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

Dependencies:   Joystick N5110 SDFileSystem mbed

Committer:
avi23
Date:
Sun Mar 13 01:00:23 2016 +0000
Revision:
0:427469992efe
Child:
1:b300d052d549
Added joystick, cannon (called ship in code - need to change) movement, drawn small invader

Who changed what in which revision?

UserRevisionLine numberNew contents of line
avi23 0:427469992efe 1 #include "mbed.h"
avi23 0:427469992efe 2 #include "N5110.h"
avi23 0:427469992efe 3
avi23 0:427469992efe 4 #define EMPTY 0
avi23 0:427469992efe 5
avi23 0:427469992efe 6 //Joystick Class
avi23 0:427469992efe 7 class Joystick
avi23 0:427469992efe 8 {
avi23 0:427469992efe 9 public:
avi23 0:427469992efe 10 Joystick(PinName x_axis_pin, PinName y_axis_pin, PinName button_pin) {
avi23 0:427469992efe 11 //Dynamically allocates the pins
avi23 0:427469992efe 12 x_axis_ = new AnalogIn(x_axis_pin);
avi23 0:427469992efe 13 y_axis_ = new AnalogIn(y_axis_pin);
avi23 0:427469992efe 14 button_ = new InterruptIn(button_pin);
avi23 0:427469992efe 15 }
avi23 0:427469992efe 16
avi23 0:427469992efe 17 //Initalises the Joystick
avi23 0:427469992efe 18 //Sets up the ISRs and grabs the offsets for each axis
avi23 0:427469992efe 19 void init() {
avi23 0:427469992efe 20 //Sets up the button ISR
avi23 0:427469992efe 21 //DigitalOut* b = new DigitalOut(LED_BLUE);
avi23 0:427469992efe 22
avi23 0:427469992efe 23 button_->mode(PullUp);
avi23 0:427469992efe 24 //read_ticker_->attach(this, &Joystick::read_ticker_isr, time); //Samples joystick every second
avi23 0:427469992efe 25 button_->fall(this, &Joystick::button_isr);
avi23 0:427469992efe 26
avi23 0:427469992efe 27 //Initalises the vairables and flags
avi23 0:427469992efe 28 x_offset_ = 0;
avi23 0:427469992efe 29 y_offset_ = 0;
avi23 0:427469992efe 30 g_read_flag_ = 0;
avi23 0:427469992efe 31 g_button_flag_ = 0;
avi23 0:427469992efe 32
avi23 0:427469992efe 33 //Samples the joystick 5 times and takes an average to get the offset
avi23 0:427469992efe 34 float x_sum = 0;
avi23 0:427469992efe 35 float y_sum = 0;
avi23 0:427469992efe 36
avi23 0:427469992efe 37 for (int i = 0; i < 5; i++) {
avi23 0:427469992efe 38 x_sum += x_axis_->read();
avi23 0:427469992efe 39 y_sum += y_axis_->read();
avi23 0:427469992efe 40 }
avi23 0:427469992efe 41
avi23 0:427469992efe 42 x_offset_ = 0.5f - x_sum/5.0f;
avi23 0:427469992efe 43 y_offset_ = 0.5f - y_sum/5.0f;
avi23 0:427469992efe 44 }
avi23 0:427469992efe 45
avi23 0:427469992efe 46 //Take 5 readings and returns the average measurement, accounting for joystick offset x and y values
avi23 0:427469992efe 47 float GetXValue() {
avi23 0:427469992efe 48
avi23 0:427469992efe 49 float x_sum = 0;
avi23 0:427469992efe 50
avi23 0:427469992efe 51 for (int i = 0; i < 5; i++) {
avi23 0:427469992efe 52 x_sum += x_axis_->read();
avi23 0:427469992efe 53 }
avi23 0:427469992efe 54
avi23 0:427469992efe 55 float x_value = x_sum/5.0f + x_offset_;
avi23 0:427469992efe 56
avi23 0:427469992efe 57 //Caps the value for the POT between 0 and 1
avi23 0:427469992efe 58 if (x_value < 0.0f) {
avi23 0:427469992efe 59 return 0;
avi23 0:427469992efe 60 } else if (x_value > 1.0f) {
avi23 0:427469992efe 61 return 1;
avi23 0:427469992efe 62 } else {
avi23 0:427469992efe 63 return x_value;
avi23 0:427469992efe 64 }
avi23 0:427469992efe 65 }
avi23 0:427469992efe 66
avi23 0:427469992efe 67 float GetYValue() {
avi23 0:427469992efe 68
avi23 0:427469992efe 69 float y_sum = 0;
avi23 0:427469992efe 70
avi23 0:427469992efe 71 for (int i = 0; i < 5; i++) {
avi23 0:427469992efe 72 y_sum += y_axis_->read();
avi23 0:427469992efe 73 }
avi23 0:427469992efe 74
avi23 0:427469992efe 75 float y_value = y_sum/5.0f + y_offset_;
avi23 0:427469992efe 76
avi23 0:427469992efe 77 //Caps the value for the POT between 0 and 1
avi23 0:427469992efe 78 if (y_value < 0.0f) {
avi23 0:427469992efe 79 return 0;
avi23 0:427469992efe 80 } else if (y_value > 1.0f) {
avi23 0:427469992efe 81 return 1;
avi23 0:427469992efe 82 } else {
avi23 0:427469992efe 83 return y_value;
avi23 0:427469992efe 84 }
avi23 0:427469992efe 85 }
avi23 0:427469992efe 86
avi23 0:427469992efe 87 float ReadXAxis() {
avi23 0:427469992efe 88 return x_axis_->read();
avi23 0:427469992efe 89 }
avi23 0:427469992efe 90
avi23 0:427469992efe 91 float ReadYAxis() {
avi23 0:427469992efe 92 return y_axis_->read();
avi23 0:427469992efe 93 }
avi23 0:427469992efe 94
avi23 0:427469992efe 95 //Getter and setters for flags
avi23 0:427469992efe 96 int get_read_flag() {
avi23 0:427469992efe 97 return g_read_flag_;
avi23 0:427469992efe 98 }
avi23 0:427469992efe 99
avi23 0:427469992efe 100 void set_read_flag(int value) {
avi23 0:427469992efe 101 g_read_flag_ = value;
avi23 0:427469992efe 102 }
avi23 0:427469992efe 103
avi23 0:427469992efe 104 int get_button_flag() {
avi23 0:427469992efe 105 return g_button_flag_;
avi23 0:427469992efe 106 }
avi23 0:427469992efe 107
avi23 0:427469992efe 108 void set_button_flag(int value) {
avi23 0:427469992efe 109 g_button_flag_ = value;
avi23 0:427469992efe 110 }
avi23 0:427469992efe 111
avi23 0:427469992efe 112 //Ticker ISR Method
avi23 0:427469992efe 113 void read_ticker_isr() {
avi23 0:427469992efe 114 g_read_flag_ = 1;
avi23 0:427469992efe 115 }
avi23 0:427469992efe 116
avi23 0:427469992efe 117 private:
avi23 0:427469992efe 118 //Button ISR Method
avi23 0:427469992efe 119 void button_isr() {
avi23 0:427469992efe 120 g_button_flag_ = 1;
avi23 0:427469992efe 121 }
avi23 0:427469992efe 122
avi23 0:427469992efe 123 private:
avi23 0:427469992efe 124 //Pin inputs
avi23 0:427469992efe 125 AnalogIn* x_axis_;
avi23 0:427469992efe 126 AnalogIn* y_axis_;
avi23 0:427469992efe 127 InterruptIn* button_;
avi23 0:427469992efe 128
avi23 0:427469992efe 129 //Ticker
avi23 0:427469992efe 130 Ticker* read_ticker_;
avi23 0:427469992efe 131
avi23 0:427469992efe 132 //Stores X and Y offsets
avi23 0:427469992efe 133 float x_offset_;
avi23 0:427469992efe 134 float y_offset_;
avi23 0:427469992efe 135
avi23 0:427469992efe 136 //Stores interrupt flags
avi23 0:427469992efe 137 volatile int g_read_flag_;
avi23 0:427469992efe 138 volatile int g_button_flag_;
avi23 0:427469992efe 139 };
avi23 0:427469992efe 140
avi23 0:427469992efe 141 // K64F on-board LEDs
avi23 0:427469992efe 142 DigitalOut r_led(LED_RED);
avi23 0:427469992efe 143 DigitalOut g_led(LED_GREEN);
avi23 0:427469992efe 144 DigitalOut b_led(LED_BLUE);
avi23 0:427469992efe 145
avi23 0:427469992efe 146 // K64F on-board switches
avi23 0:427469992efe 147 InterruptIn sw2(SW2);
avi23 0:427469992efe 148 InterruptIn sw3(SW3);
avi23 0:427469992efe 149
avi23 0:427469992efe 150 // UART connection for PC
avi23 0:427469992efe 151 Serial pc(USBTX,USBRX);
avi23 0:427469992efe 152
avi23 0:427469992efe 153 //Joystick
avi23 0:427469992efe 154 Joystick joystick(PTC10, PTC11, PTB11);
avi23 0:427469992efe 155
avi23 0:427469992efe 156 //LCD object
avi23 0:427469992efe 157 // VCC, SCE, RST, D/C, MOSI, SCLK, LED
avi23 0:427469992efe 158 N5110 lcd (PTE26 , PTA0 , PTC4 , PTD0 , PTD2 , PTD1 , PTC3);
avi23 0:427469992efe 159
avi23 0:427469992efe 160 //Ship bit-map and location
avi23 0:427469992efe 161 int ship_xpos = 24;
avi23 0:427469992efe 162 const int ship_ypos = 43;
avi23 0:427469992efe 163 Ticker move_ship;
avi23 0:427469992efe 164 const bool ship_bitmap[5][9] = {
avi23 0:427469992efe 165 {0, 0, 0, 0, 1, 0, 0, 0, 0},
avi23 0:427469992efe 166 {0, 0, 0, 1, 1, 1, 0, 0, 0},
avi23 0:427469992efe 167 {0, 1, 1, 1, 1, 1, 1, 1, 0},
avi23 0:427469992efe 168 {1, 1, 1, 1, 1, 1, 1, 1, 1},
avi23 0:427469992efe 169 {1, 1, 1, 1, 1, 1, 1, 1, 1}
avi23 0:427469992efe 170 };
avi23 0:427469992efe 171
avi23 0:427469992efe 172 //Enemies
avi23 0:427469992efe 173 Ticker move_enemies;
avi23 0:427469992efe 174
avi23 0:427469992efe 175 //Small Invader struct and bitmap
avi23 0:427469992efe 176 struct SmallInvader {
avi23 0:427469992efe 177 int x_pos;
avi23 0:427469992efe 178 int y_pos;
avi23 0:427469992efe 179 bool is_alive;
avi23 0:427469992efe 180 } small_invader[6];
avi23 0:427469992efe 181 int no_of_small_invaders = 6;
avi23 0:427469992efe 182
avi23 0:427469992efe 183 const bool small_invader_bitmap_1[6][8] = {
avi23 0:427469992efe 184 {0, 0, 0, 1, 1, 0, 0, 0},
avi23 0:427469992efe 185 {0, 1, 1, 1, 1, 1, 1, 0},
avi23 0:427469992efe 186 {1, 1, 0, 1, 1, 0, 1, 1},
avi23 0:427469992efe 187 {1, 1, 1, 1, 1, 1, 1, 1},
avi23 0:427469992efe 188 {0, 1, 0, 1, 1, 0, 1, 0},
avi23 0:427469992efe 189 {1, 0, 1, 0, 0, 1, 0, 1}
avi23 0:427469992efe 190 };
avi23 0:427469992efe 191
avi23 0:427469992efe 192 const bool small_invader_bitmap_2[6][8] = {
avi23 0:427469992efe 193 {0, 0, 0, 1, 1, 0, 0, 0},
avi23 0:427469992efe 194 {0, 1, 1, 1, 1, 1, 1, 0},
avi23 0:427469992efe 195 {1, 1, 0, 1, 1, 0, 1, 1},
avi23 0:427469992efe 196 {1, 1, 1, 1, 1, 1, 1, 1},
avi23 0:427469992efe 197 {1, 0, 0, 0, 0, 0, 0, 1},
avi23 0:427469992efe 198 {0, 1, 0, 0, 0, 0, 1, 0}
avi23 0:427469992efe 199 };
avi23 0:427469992efe 200 bool small_invader_in_state2 = true;
avi23 0:427469992efe 201 short screen[84][48];
avi23 0:427469992efe 202
avi23 0:427469992efe 203 //ISR Flags
avi23 0:427469992efe 204 volatile bool g_move_ship_flag = true;
avi23 0:427469992efe 205 volatile bool g_move_enemies_flag = true;
avi23 0:427469992efe 206
avi23 0:427469992efe 207 // function prototypes
avi23 0:427469992efe 208 // error function hangs flashing an LED
avi23 0:427469992efe 209 void error();
avi23 0:427469992efe 210 // setup serial port
avi23 0:427469992efe 211 void init_serial();
avi23 0:427469992efe 212 // set-up the on-board LEDs and switches
avi23 0:427469992efe 213 void init_K64F();
avi23 0:427469992efe 214 // Added functions
avi23 0:427469992efe 215 void MoveShip();
avi23 0:427469992efe 216 void InitSmallInvaders();
avi23 0:427469992efe 217 void DrawSmallInvaders();
avi23 0:427469992efe 218 //ISR's
avi23 0:427469992efe 219 void move_ship_isr();
avi23 0:427469992efe 220 void move_enemies_isr();
avi23 0:427469992efe 221
avi23 0:427469992efe 222
avi23 0:427469992efe 223 int row_no = 6;
avi23 0:427469992efe 224 int col_no = 8;
avi23 0:427469992efe 225
avi23 0:427469992efe 226 int main()
avi23 0:427469992efe 227 {
avi23 0:427469992efe 228 //Initalises the board and perhiperals
avi23 0:427469992efe 229 init_K64F();
avi23 0:427469992efe 230 init_serial();
avi23 0:427469992efe 231 lcd.init();
avi23 0:427469992efe 232 lcd.clear();
avi23 0:427469992efe 233
avi23 0:427469992efe 234 move_ship.attach(&move_ship_isr, 0.1);
avi23 0:427469992efe 235 move_enemies.attach(&move_enemies_isr, 1);
avi23 0:427469992efe 236
avi23 0:427469992efe 237 InitSmallInvaders();
avi23 0:427469992efe 238
avi23 0:427469992efe 239 lcd.refresh();
avi23 0:427469992efe 240
avi23 0:427469992efe 241 while (true) {
avi23 0:427469992efe 242 if (g_move_ship_flag) {
avi23 0:427469992efe 243 g_move_ship_flag = false;
avi23 0:427469992efe 244
avi23 0:427469992efe 245 MoveShip();
avi23 0:427469992efe 246
avi23 0:427469992efe 247 lcd.refresh();
avi23 0:427469992efe 248 }
avi23 0:427469992efe 249
avi23 0:427469992efe 250 if (g_move_enemies_flag) {
avi23 0:427469992efe 251 g_move_enemies_flag = false;
avi23 0:427469992efe 252
avi23 0:427469992efe 253 DrawSmallInvaders();
avi23 0:427469992efe 254
avi23 0:427469992efe 255 lcd.refresh();
avi23 0:427469992efe 256 }
avi23 0:427469992efe 257
avi23 0:427469992efe 258 sleep();
avi23 0:427469992efe 259 }
avi23 0:427469992efe 260 }
avi23 0:427469992efe 261
avi23 0:427469992efe 262 void init_K64F()
avi23 0:427469992efe 263 {
avi23 0:427469992efe 264 // on-board LEDs are active-low, so set pin high to turn them off.
avi23 0:427469992efe 265 r_led = 1;
avi23 0:427469992efe 266 g_led = 1;
avi23 0:427469992efe 267 b_led = 1;
avi23 0:427469992efe 268
avi23 0:427469992efe 269 // since the on-board switches have external pull-ups, we should disable the internal pull-down
avi23 0:427469992efe 270 // resistors that are enabled by default using InterruptIn
avi23 0:427469992efe 271 sw2.mode(PullNone);
avi23 0:427469992efe 272 sw3.mode(PullNone);
avi23 0:427469992efe 273
avi23 0:427469992efe 274 }
avi23 0:427469992efe 275
avi23 0:427469992efe 276 void error()
avi23 0:427469992efe 277 {
avi23 0:427469992efe 278 while(1) { // if error, hang while flashing error message
avi23 0:427469992efe 279 r_led = 0;
avi23 0:427469992efe 280 wait(0.2);
avi23 0:427469992efe 281 r_led = 1;
avi23 0:427469992efe 282 wait(0.2);
avi23 0:427469992efe 283 }
avi23 0:427469992efe 284 }
avi23 0:427469992efe 285
avi23 0:427469992efe 286 void init_serial()
avi23 0:427469992efe 287 {
avi23 0:427469992efe 288 // set to highest baud - ensure terminal software matches
avi23 0:427469992efe 289 pc.baud(115200);
avi23 0:427469992efe 290 }
avi23 0:427469992efe 291
avi23 0:427469992efe 292 void move_ship_isr()
avi23 0:427469992efe 293 {
avi23 0:427469992efe 294 g_move_ship_flag = true;
avi23 0:427469992efe 295 }
avi23 0:427469992efe 296
avi23 0:427469992efe 297 void MoveShip()
avi23 0:427469992efe 298 {
avi23 0:427469992efe 299 //Clears the ship
avi23 0:427469992efe 300 for (int col = 0; col < 9; col++) {
avi23 0:427469992efe 301 for (int row = 0; row < 5; row++) {
avi23 0:427469992efe 302 if(ship_bitmap[row][col]) {
avi23 0:427469992efe 303 lcd.clearPixel(ship_xpos+col, ship_ypos+row);
avi23 0:427469992efe 304 }
avi23 0:427469992efe 305 }
avi23 0:427469992efe 306 }
avi23 0:427469992efe 307
avi23 0:427469992efe 308 //Changes the position of the ship when the joystick is moved, capping at 0 and 75 so it always fits on the screen
avi23 0:427469992efe 309 if (joystick.GetXValue() < 0.25f) {
avi23 0:427469992efe 310 ship_xpos--;
avi23 0:427469992efe 311 if (ship_xpos < 0) {
avi23 0:427469992efe 312 ship_xpos = 0;
avi23 0:427469992efe 313 }
avi23 0:427469992efe 314 } else if (joystick.GetXValue() > 0.75f) {
avi23 0:427469992efe 315 ship_xpos++;
avi23 0:427469992efe 316 if (ship_xpos > 75) {
avi23 0:427469992efe 317 ship_xpos = 75;
avi23 0:427469992efe 318 }
avi23 0:427469992efe 319 }
avi23 0:427469992efe 320
avi23 0:427469992efe 321 //Redraws the ship
avi23 0:427469992efe 322 for (int col = 0; col < 9; col++) {
avi23 0:427469992efe 323 for (int row = 0; row < 5; row++) {
avi23 0:427469992efe 324 if(ship_bitmap[row][col]) {
avi23 0:427469992efe 325 lcd.setPixel(ship_xpos+col, ship_ypos+row);
avi23 0:427469992efe 326 }
avi23 0:427469992efe 327 }
avi23 0:427469992efe 328 }
avi23 0:427469992efe 329 }
avi23 0:427469992efe 330
avi23 0:427469992efe 331 void move_enemies_isr()
avi23 0:427469992efe 332 {
avi23 0:427469992efe 333 g_move_enemies_flag = true;
avi23 0:427469992efe 334 }
avi23 0:427469992efe 335
avi23 0:427469992efe 336 //Sets the position and aliveness of the small invaders
avi23 0:427469992efe 337 void InitSmallInvaders()
avi23 0:427469992efe 338 {
avi23 0:427469992efe 339 for (int i = 0; i < no_of_small_invaders; i++) {
avi23 0:427469992efe 340 small_invader[i].x_pos = 2+ (i*12);
avi23 0:427469992efe 341 small_invader[i].y_pos = 7;
avi23 0:427469992efe 342 small_invader[i].is_alive = true;
avi23 0:427469992efe 343 }
avi23 0:427469992efe 344 }
avi23 0:427469992efe 345
avi23 0:427469992efe 346 void DrawSmallInvaders()
avi23 0:427469992efe 347 {
avi23 0:427469992efe 348 //For each small invader clear and redraws them if they're alive
avi23 0:427469992efe 349 for (int i = 0; i < no_of_small_invaders; i++) {
avi23 0:427469992efe 350 //Clears the enemy position
avi23 0:427469992efe 351 lcd.drawRect(small_invader[i].x_pos, small_invader[i].y_pos, 8, 6, 2);
avi23 0:427469992efe 352
avi23 0:427469992efe 353 //Checks if the invader is alive
avi23 0:427469992efe 354 if (small_invader[i].is_alive) {
avi23 0:427469992efe 355 //Reads off the bitmap and sets the allowed pixels
avi23 0:427469992efe 356 int col = 0;
avi23 0:427469992efe 357 int row = 0;
avi23 0:427469992efe 358 //Flips the bitmap everytime the function is called
avi23 0:427469992efe 359 if (small_invader_in_state2) {
avi23 0:427469992efe 360 for (col = 0; col < col_no; col++) {
avi23 0:427469992efe 361 for (row = 0; row < row_no; row++) {
avi23 0:427469992efe 362 if(small_invader_bitmap_1[row][col]) {
avi23 0:427469992efe 363 lcd.setPixel(small_invader[i].x_pos + col, small_invader[i].y_pos + row);
avi23 0:427469992efe 364 }
avi23 0:427469992efe 365 }
avi23 0:427469992efe 366 }
avi23 0:427469992efe 367 } else {
avi23 0:427469992efe 368 for (col = 0; col < col_no; col++) {
avi23 0:427469992efe 369 for (row = 0; row < row_no; row++) {
avi23 0:427469992efe 370 if(small_invader_bitmap_2[row][col]) {
avi23 0:427469992efe 371 lcd.setPixel(small_invader[i].x_pos + col, small_invader[i].y_pos + row);
avi23 0:427469992efe 372 }
avi23 0:427469992efe 373 }
avi23 0:427469992efe 374 }
avi23 0:427469992efe 375 }
avi23 0:427469992efe 376 }
avi23 0:427469992efe 377 }
avi23 0:427469992efe 378 //Flips the flag so the bitmap can be switched
avi23 0:427469992efe 379 small_invader_in_state2 = !small_invader_in_state2;
avi23 0:427469992efe 380 }