Snake vs Block Game to be run upon K64F.

Dependencies:   mbed

Committer:
AhmedPlaymaker
Date:
Fri Apr 26 18:30:25 2019 +0000
Revision:
51:387249f9b333
Parent:
Gamepad/Gamepad.cpp@0:4b15c2d4aa58
Child:
61:f3c402bc2ad0
Sorted my game classes into folders to make it more organized

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AhmedPlaymaker 0:4b15c2d4aa58 1 #include "Gamepad.h"
AhmedPlaymaker 0:4b15c2d4aa58 2
AhmedPlaymaker 0:4b15c2d4aa58 3 #include "mbed.h"
AhmedPlaymaker 0:4b15c2d4aa58 4
AhmedPlaymaker 0:4b15c2d4aa58 5 //////////// constructor/destructor ////////////
AhmedPlaymaker 0:4b15c2d4aa58 6 Gamepad::Gamepad()
AhmedPlaymaker 0:4b15c2d4aa58 7 :
AhmedPlaymaker 0:4b15c2d4aa58 8 _led1(new PwmOut(PTA1)),
AhmedPlaymaker 0:4b15c2d4aa58 9 _led2(new PwmOut(PTA2)),
AhmedPlaymaker 0:4b15c2d4aa58 10 _led3(new PwmOut(PTC2)),
AhmedPlaymaker 0:4b15c2d4aa58 11 _led4(new PwmOut(PTC3)),
AhmedPlaymaker 0:4b15c2d4aa58 12 _led5(new PwmOut(PTC4)),
AhmedPlaymaker 0:4b15c2d4aa58 13 _led6(new PwmOut(PTD3)),
AhmedPlaymaker 0:4b15c2d4aa58 14
AhmedPlaymaker 0:4b15c2d4aa58 15 _button_A(new InterruptIn(PTB9)),
AhmedPlaymaker 0:4b15c2d4aa58 16 _button_B(new InterruptIn(PTD0)),
AhmedPlaymaker 0:4b15c2d4aa58 17 _button_X(new InterruptIn(PTC17)),
AhmedPlaymaker 0:4b15c2d4aa58 18 _button_Y(new InterruptIn(PTC12)),
AhmedPlaymaker 0:4b15c2d4aa58 19 _button_L(new InterruptIn(PTB18)),
AhmedPlaymaker 0:4b15c2d4aa58 20 _button_R(new InterruptIn(PTB3)),
AhmedPlaymaker 0:4b15c2d4aa58 21 _button_back(new InterruptIn(PTB19)),
AhmedPlaymaker 0:4b15c2d4aa58 22 _button_start(new InterruptIn(PTC5)),
AhmedPlaymaker 0:4b15c2d4aa58 23 _button_joystick(new InterruptIn(PTC16)),
AhmedPlaymaker 0:4b15c2d4aa58 24
AhmedPlaymaker 0:4b15c2d4aa58 25 _vert(new AnalogIn(PTB10)),
AhmedPlaymaker 0:4b15c2d4aa58 26 _horiz(new AnalogIn(PTB11)),
AhmedPlaymaker 0:4b15c2d4aa58 27
AhmedPlaymaker 0:4b15c2d4aa58 28 _buzzer(new PwmOut(PTC10)),
AhmedPlaymaker 0:4b15c2d4aa58 29 _pot(new AnalogIn(PTB2)),
AhmedPlaymaker 0:4b15c2d4aa58 30
AhmedPlaymaker 0:4b15c2d4aa58 31 _timeout(new Timeout()),
AhmedPlaymaker 0:4b15c2d4aa58 32
AhmedPlaymaker 0:4b15c2d4aa58 33 _event_state(0),
AhmedPlaymaker 0:4b15c2d4aa58 34
AhmedPlaymaker 0:4b15c2d4aa58 35 _x0(0),
AhmedPlaymaker 0:4b15c2d4aa58 36 _y0(0)
AhmedPlaymaker 0:4b15c2d4aa58 37 {}
AhmedPlaymaker 0:4b15c2d4aa58 38
AhmedPlaymaker 0:4b15c2d4aa58 39 Gamepad::~Gamepad()
AhmedPlaymaker 0:4b15c2d4aa58 40 {
AhmedPlaymaker 0:4b15c2d4aa58 41 delete _led1,_led2,_led3,_led4,_led5,_led6;
AhmedPlaymaker 0:4b15c2d4aa58 42 delete _button_A,_button_B,_button_joystick,_vert,_horiz;
AhmedPlaymaker 0:4b15c2d4aa58 43 delete _button_X,_button_Y,_button_back,_button_start;
AhmedPlaymaker 0:4b15c2d4aa58 44 delete _button_L,_button_R, _buzzer, _pot, _timeout;
AhmedPlaymaker 0:4b15c2d4aa58 45 }
AhmedPlaymaker 0:4b15c2d4aa58 46
AhmedPlaymaker 0:4b15c2d4aa58 47 ///////////////// public methods /////////////////
AhmedPlaymaker 0:4b15c2d4aa58 48
AhmedPlaymaker 0:4b15c2d4aa58 49 void Gamepad::init()
AhmedPlaymaker 0:4b15c2d4aa58 50 {
AhmedPlaymaker 0:4b15c2d4aa58 51 leds_off();
AhmedPlaymaker 0:4b15c2d4aa58 52 init_buttons();
AhmedPlaymaker 0:4b15c2d4aa58 53
AhmedPlaymaker 0:4b15c2d4aa58 54 // read centred values of joystick
AhmedPlaymaker 0:4b15c2d4aa58 55 _x0 = _horiz->read();
AhmedPlaymaker 0:4b15c2d4aa58 56 _y0 = _vert->read();
AhmedPlaymaker 0:4b15c2d4aa58 57
AhmedPlaymaker 0:4b15c2d4aa58 58 // clear all flags
AhmedPlaymaker 0:4b15c2d4aa58 59 _event_state = 0;
AhmedPlaymaker 0:4b15c2d4aa58 60 }
AhmedPlaymaker 0:4b15c2d4aa58 61
AhmedPlaymaker 0:4b15c2d4aa58 62 void Gamepad::leds_off()
AhmedPlaymaker 0:4b15c2d4aa58 63 {
AhmedPlaymaker 0:4b15c2d4aa58 64 leds(0.0);
AhmedPlaymaker 0:4b15c2d4aa58 65 }
AhmedPlaymaker 0:4b15c2d4aa58 66
AhmedPlaymaker 0:4b15c2d4aa58 67 void Gamepad::leds_on()
AhmedPlaymaker 0:4b15c2d4aa58 68 {
AhmedPlaymaker 0:4b15c2d4aa58 69 leds(1.0);
AhmedPlaymaker 0:4b15c2d4aa58 70 }
AhmedPlaymaker 0:4b15c2d4aa58 71
AhmedPlaymaker 0:4b15c2d4aa58 72 void Gamepad::leds(float val) const
AhmedPlaymaker 0:4b15c2d4aa58 73 {
AhmedPlaymaker 0:4b15c2d4aa58 74 if (val < 0.0f) {
AhmedPlaymaker 0:4b15c2d4aa58 75 val = 0.0f;
AhmedPlaymaker 0:4b15c2d4aa58 76 }
AhmedPlaymaker 0:4b15c2d4aa58 77 if (val > 1.0f) {
AhmedPlaymaker 0:4b15c2d4aa58 78 val = 1.0f;
AhmedPlaymaker 0:4b15c2d4aa58 79 }
AhmedPlaymaker 0:4b15c2d4aa58 80
AhmedPlaymaker 0:4b15c2d4aa58 81 // leds are active-low, so subtract from 1.0
AhmedPlaymaker 0:4b15c2d4aa58 82 // 0.0 corresponds to fully-off, 1.0 to fully-on
AhmedPlaymaker 0:4b15c2d4aa58 83 val = 1.0f - val;
AhmedPlaymaker 0:4b15c2d4aa58 84
AhmedPlaymaker 0:4b15c2d4aa58 85 _led1->write(val);
AhmedPlaymaker 0:4b15c2d4aa58 86 _led2->write(val);
AhmedPlaymaker 0:4b15c2d4aa58 87 _led3->write(val);
AhmedPlaymaker 0:4b15c2d4aa58 88 _led4->write(val);
AhmedPlaymaker 0:4b15c2d4aa58 89 _led5->write(val);
AhmedPlaymaker 0:4b15c2d4aa58 90 _led6->write(val);
AhmedPlaymaker 0:4b15c2d4aa58 91 }
AhmedPlaymaker 0:4b15c2d4aa58 92
AhmedPlaymaker 0:4b15c2d4aa58 93 void Gamepad::led(int n,float val) const
AhmedPlaymaker 0:4b15c2d4aa58 94 {
AhmedPlaymaker 0:4b15c2d4aa58 95 // ensure they are within vlaid range
AhmedPlaymaker 0:4b15c2d4aa58 96 if (val < 0.0f) {
AhmedPlaymaker 0:4b15c2d4aa58 97 val = 0.0f;
AhmedPlaymaker 0:4b15c2d4aa58 98 }
AhmedPlaymaker 0:4b15c2d4aa58 99 if (val > 1.0f) {
AhmedPlaymaker 0:4b15c2d4aa58 100 val = 1.0f;
AhmedPlaymaker 0:4b15c2d4aa58 101 }
AhmedPlaymaker 0:4b15c2d4aa58 102
AhmedPlaymaker 0:4b15c2d4aa58 103 switch (n) {
AhmedPlaymaker 0:4b15c2d4aa58 104
AhmedPlaymaker 0:4b15c2d4aa58 105 // check for valid LED number and set value
AhmedPlaymaker 0:4b15c2d4aa58 106
AhmedPlaymaker 0:4b15c2d4aa58 107 case 1:
AhmedPlaymaker 0:4b15c2d4aa58 108 _led1->write(1.0f-val); // active-low so subtract from 1
AhmedPlaymaker 0:4b15c2d4aa58 109 break;
AhmedPlaymaker 0:4b15c2d4aa58 110 case 2:
AhmedPlaymaker 0:4b15c2d4aa58 111 _led2->write(1.0f-val); // active-low so subtract from 1
AhmedPlaymaker 0:4b15c2d4aa58 112 break;
AhmedPlaymaker 0:4b15c2d4aa58 113 case 3:
AhmedPlaymaker 0:4b15c2d4aa58 114 _led3->write(1.0f-val); // active-low so subtract from 1
AhmedPlaymaker 0:4b15c2d4aa58 115 break;
AhmedPlaymaker 0:4b15c2d4aa58 116 case 4:
AhmedPlaymaker 0:4b15c2d4aa58 117 _led4->write(1.0f-val); // active-low so subtract from 1
AhmedPlaymaker 0:4b15c2d4aa58 118 break;
AhmedPlaymaker 0:4b15c2d4aa58 119 case 5:
AhmedPlaymaker 0:4b15c2d4aa58 120 _led5->write(1.0f-val); // active-low so subtract from 1
AhmedPlaymaker 0:4b15c2d4aa58 121 break;
AhmedPlaymaker 0:4b15c2d4aa58 122 case 6:
AhmedPlaymaker 0:4b15c2d4aa58 123 _led6->write(1.0f-val); // active-low so subtract from 1
AhmedPlaymaker 0:4b15c2d4aa58 124 break;
AhmedPlaymaker 0:4b15c2d4aa58 125
AhmedPlaymaker 0:4b15c2d4aa58 126 }
AhmedPlaymaker 0:4b15c2d4aa58 127 }
AhmedPlaymaker 0:4b15c2d4aa58 128
AhmedPlaymaker 0:4b15c2d4aa58 129 float Gamepad::read_pot() const
AhmedPlaymaker 0:4b15c2d4aa58 130 {
AhmedPlaymaker 0:4b15c2d4aa58 131 return _pot->read();
AhmedPlaymaker 0:4b15c2d4aa58 132 }
AhmedPlaymaker 0:4b15c2d4aa58 133
AhmedPlaymaker 0:4b15c2d4aa58 134 void Gamepad::tone(float frequency, float duration)
AhmedPlaymaker 0:4b15c2d4aa58 135 {
AhmedPlaymaker 0:4b15c2d4aa58 136 _buzzer->period(1.0f/frequency);
AhmedPlaymaker 0:4b15c2d4aa58 137 _buzzer->write(0.5); // 50% duty cycle - square wave
AhmedPlaymaker 0:4b15c2d4aa58 138 _timeout->attach(callback(this, &Gamepad::tone_off), duration );
AhmedPlaymaker 0:4b15c2d4aa58 139 }
AhmedPlaymaker 0:4b15c2d4aa58 140
AhmedPlaymaker 0:4b15c2d4aa58 141 bool Gamepad::check_event(GamepadEvent const id)
AhmedPlaymaker 0:4b15c2d4aa58 142 {
AhmedPlaymaker 0:4b15c2d4aa58 143 // Check whether event flag is set
AhmedPlaymaker 0:4b15c2d4aa58 144 if (_event_state[id]) {
AhmedPlaymaker 0:4b15c2d4aa58 145 _event_state.reset(id); // clear flag
AhmedPlaymaker 0:4b15c2d4aa58 146 return true;
AhmedPlaymaker 0:4b15c2d4aa58 147 } else {
AhmedPlaymaker 0:4b15c2d4aa58 148 return false;
AhmedPlaymaker 0:4b15c2d4aa58 149 }
AhmedPlaymaker 0:4b15c2d4aa58 150 }
AhmedPlaymaker 0:4b15c2d4aa58 151
AhmedPlaymaker 0:4b15c2d4aa58 152 // this method gets the magnitude of the joystick movement
AhmedPlaymaker 0:4b15c2d4aa58 153 float Gamepad::get_mag()
AhmedPlaymaker 0:4b15c2d4aa58 154 {
AhmedPlaymaker 0:4b15c2d4aa58 155 Polar p = get_polar();
AhmedPlaymaker 0:4b15c2d4aa58 156 return p.mag;
AhmedPlaymaker 0:4b15c2d4aa58 157 }
AhmedPlaymaker 0:4b15c2d4aa58 158
AhmedPlaymaker 0:4b15c2d4aa58 159 // this method gets the angle of joystick movement (0 to 360, 0 North)
AhmedPlaymaker 0:4b15c2d4aa58 160 float Gamepad::get_angle()
AhmedPlaymaker 0:4b15c2d4aa58 161 {
AhmedPlaymaker 0:4b15c2d4aa58 162 Polar p = get_polar();
AhmedPlaymaker 0:4b15c2d4aa58 163 return p.angle;
AhmedPlaymaker 0:4b15c2d4aa58 164 }
AhmedPlaymaker 0:4b15c2d4aa58 165
AhmedPlaymaker 0:4b15c2d4aa58 166 Direction Gamepad::get_direction()
AhmedPlaymaker 0:4b15c2d4aa58 167 {
AhmedPlaymaker 0:4b15c2d4aa58 168 float angle = get_angle(); // 0 to 360, -1 for centred
AhmedPlaymaker 0:4b15c2d4aa58 169
AhmedPlaymaker 0:4b15c2d4aa58 170 Direction d;
AhmedPlaymaker 0:4b15c2d4aa58 171 // partition 360 into segments and check which segment the angle is in
AhmedPlaymaker 0:4b15c2d4aa58 172 if (angle < 0.0f) {
AhmedPlaymaker 0:4b15c2d4aa58 173 d = CENTRE; // check for -1.0 angle
AhmedPlaymaker 0:4b15c2d4aa58 174 } else if (angle < 22.5f) { // then keep going in 45 degree increments
AhmedPlaymaker 0:4b15c2d4aa58 175 d = N;
AhmedPlaymaker 0:4b15c2d4aa58 176 } else if (angle < 67.5f) {
AhmedPlaymaker 0:4b15c2d4aa58 177 d = NE;
AhmedPlaymaker 0:4b15c2d4aa58 178 } else if (angle < 112.5f) {
AhmedPlaymaker 0:4b15c2d4aa58 179 d = E;
AhmedPlaymaker 0:4b15c2d4aa58 180 } else if (angle < 157.5f) {
AhmedPlaymaker 0:4b15c2d4aa58 181 d = SE;
AhmedPlaymaker 0:4b15c2d4aa58 182 } else if (angle < 202.5f) {
AhmedPlaymaker 0:4b15c2d4aa58 183 d = S;
AhmedPlaymaker 0:4b15c2d4aa58 184 } else if (angle < 247.5f) {
AhmedPlaymaker 0:4b15c2d4aa58 185 d = SW;
AhmedPlaymaker 0:4b15c2d4aa58 186 } else if (angle < 292.5f) {
AhmedPlaymaker 0:4b15c2d4aa58 187 d = W;
AhmedPlaymaker 0:4b15c2d4aa58 188 } else if (angle < 337.5f) {
AhmedPlaymaker 0:4b15c2d4aa58 189 d = NW;
AhmedPlaymaker 0:4b15c2d4aa58 190 } else {
AhmedPlaymaker 0:4b15c2d4aa58 191 d = N;
AhmedPlaymaker 0:4b15c2d4aa58 192 }
AhmedPlaymaker 0:4b15c2d4aa58 193
AhmedPlaymaker 0:4b15c2d4aa58 194 return d;
AhmedPlaymaker 0:4b15c2d4aa58 195 }
AhmedPlaymaker 0:4b15c2d4aa58 196
AhmedPlaymaker 0:4b15c2d4aa58 197 ///////////////////// private methods ////////////////////////
AhmedPlaymaker 0:4b15c2d4aa58 198
AhmedPlaymaker 0:4b15c2d4aa58 199 void Gamepad::tone_off()
AhmedPlaymaker 0:4b15c2d4aa58 200 {
AhmedPlaymaker 0:4b15c2d4aa58 201 // called after timeout
AhmedPlaymaker 0:4b15c2d4aa58 202 _buzzer->write(0.0);
AhmedPlaymaker 0:4b15c2d4aa58 203 }
AhmedPlaymaker 0:4b15c2d4aa58 204
AhmedPlaymaker 0:4b15c2d4aa58 205 void Gamepad::init_buttons()
AhmedPlaymaker 0:4b15c2d4aa58 206 {
AhmedPlaymaker 0:4b15c2d4aa58 207 // turn on pull-downs as other side of button is connected to 3V3
AhmedPlaymaker 0:4b15c2d4aa58 208 // button is 0 when not pressed and 1 when pressed
AhmedPlaymaker 0:4b15c2d4aa58 209 _button_A->mode(PullDown);
AhmedPlaymaker 0:4b15c2d4aa58 210 _button_B->mode(PullDown);
AhmedPlaymaker 0:4b15c2d4aa58 211 _button_X->mode(PullDown);
AhmedPlaymaker 0:4b15c2d4aa58 212 _button_Y->mode(PullDown);
AhmedPlaymaker 0:4b15c2d4aa58 213 _button_back->mode(PullDown);
AhmedPlaymaker 0:4b15c2d4aa58 214 _button_start->mode(PullDown);
AhmedPlaymaker 0:4b15c2d4aa58 215 _button_L->mode(PullDown);
AhmedPlaymaker 0:4b15c2d4aa58 216 _button_R->mode(PullDown);
AhmedPlaymaker 0:4b15c2d4aa58 217 _button_joystick->mode(PullDown);
AhmedPlaymaker 0:4b15c2d4aa58 218 // therefore setup rising edge interrupts
AhmedPlaymaker 0:4b15c2d4aa58 219 _button_A->rise(callback(this,&Gamepad::a_isr));
AhmedPlaymaker 0:4b15c2d4aa58 220 _button_B->rise(callback(this,&Gamepad::b_isr));
AhmedPlaymaker 0:4b15c2d4aa58 221 _button_X->rise(callback(this,&Gamepad::x_isr));
AhmedPlaymaker 0:4b15c2d4aa58 222 _button_Y->rise(callback(this,&Gamepad::y_isr));
AhmedPlaymaker 0:4b15c2d4aa58 223 _button_L->rise(callback(this,&Gamepad::l_isr));
AhmedPlaymaker 0:4b15c2d4aa58 224 _button_R->rise(callback(this,&Gamepad::r_isr));
AhmedPlaymaker 0:4b15c2d4aa58 225 _button_start->rise(callback(this,&Gamepad::start_isr));
AhmedPlaymaker 0:4b15c2d4aa58 226 _button_back->rise(callback(this,&Gamepad::back_isr));
AhmedPlaymaker 0:4b15c2d4aa58 227 _button_joystick->rise(callback(this,&Gamepad::joy_isr));
AhmedPlaymaker 0:4b15c2d4aa58 228 }
AhmedPlaymaker 0:4b15c2d4aa58 229
AhmedPlaymaker 0:4b15c2d4aa58 230 // button interrupts ISRs
AhmedPlaymaker 0:4b15c2d4aa58 231 // Each of these simply sets the appropriate event bit in the _event_state
AhmedPlaymaker 0:4b15c2d4aa58 232 // variable
AhmedPlaymaker 0:4b15c2d4aa58 233 void Gamepad::a_isr()
AhmedPlaymaker 0:4b15c2d4aa58 234 {
AhmedPlaymaker 0:4b15c2d4aa58 235 _event_state.set(A_PRESSED);
AhmedPlaymaker 0:4b15c2d4aa58 236 }
AhmedPlaymaker 0:4b15c2d4aa58 237 void Gamepad::b_isr()
AhmedPlaymaker 0:4b15c2d4aa58 238 {
AhmedPlaymaker 0:4b15c2d4aa58 239 _event_state.set(B_PRESSED);
AhmedPlaymaker 0:4b15c2d4aa58 240 }
AhmedPlaymaker 0:4b15c2d4aa58 241 void Gamepad::x_isr()
AhmedPlaymaker 0:4b15c2d4aa58 242 {
AhmedPlaymaker 0:4b15c2d4aa58 243 _event_state.set(X_PRESSED);
AhmedPlaymaker 0:4b15c2d4aa58 244 }
AhmedPlaymaker 0:4b15c2d4aa58 245 void Gamepad::y_isr()
AhmedPlaymaker 0:4b15c2d4aa58 246 {
AhmedPlaymaker 0:4b15c2d4aa58 247 _event_state.set(Y_PRESSED);
AhmedPlaymaker 0:4b15c2d4aa58 248 }
AhmedPlaymaker 0:4b15c2d4aa58 249 void Gamepad::l_isr()
AhmedPlaymaker 0:4b15c2d4aa58 250 {
AhmedPlaymaker 0:4b15c2d4aa58 251 _event_state.set(L_PRESSED);
AhmedPlaymaker 0:4b15c2d4aa58 252 }
AhmedPlaymaker 0:4b15c2d4aa58 253 void Gamepad::r_isr()
AhmedPlaymaker 0:4b15c2d4aa58 254 {
AhmedPlaymaker 0:4b15c2d4aa58 255 _event_state.set(R_PRESSED);
AhmedPlaymaker 0:4b15c2d4aa58 256 }
AhmedPlaymaker 0:4b15c2d4aa58 257 void Gamepad::back_isr()
AhmedPlaymaker 0:4b15c2d4aa58 258 {
AhmedPlaymaker 0:4b15c2d4aa58 259 _event_state.set(BACK_PRESSED);
AhmedPlaymaker 0:4b15c2d4aa58 260 }
AhmedPlaymaker 0:4b15c2d4aa58 261 void Gamepad::start_isr()
AhmedPlaymaker 0:4b15c2d4aa58 262 {
AhmedPlaymaker 0:4b15c2d4aa58 263 _event_state.set(START_PRESSED);
AhmedPlaymaker 0:4b15c2d4aa58 264 }
AhmedPlaymaker 0:4b15c2d4aa58 265 void Gamepad::joy_isr()
AhmedPlaymaker 0:4b15c2d4aa58 266 {
AhmedPlaymaker 0:4b15c2d4aa58 267 _event_state.set(JOY_PRESSED);
AhmedPlaymaker 0:4b15c2d4aa58 268 }
AhmedPlaymaker 0:4b15c2d4aa58 269
AhmedPlaymaker 0:4b15c2d4aa58 270 // get raw joystick coordinate in range -1 to 1
AhmedPlaymaker 0:4b15c2d4aa58 271 // Direction (x,y)
AhmedPlaymaker 0:4b15c2d4aa58 272 // North (0,1)
AhmedPlaymaker 0:4b15c2d4aa58 273 // East (1,0)
AhmedPlaymaker 0:4b15c2d4aa58 274 // South (0,-1)
AhmedPlaymaker 0:4b15c2d4aa58 275 // West (-1,0)
AhmedPlaymaker 0:4b15c2d4aa58 276 Vector2D Gamepad::get_coord()
AhmedPlaymaker 0:4b15c2d4aa58 277 {
AhmedPlaymaker 0:4b15c2d4aa58 278 // read() returns value in range 0.0 to 1.0 so is scaled and centre value
AhmedPlaymaker 0:4b15c2d4aa58 279 // substracted to get values in the range -1.0 to 1.0
AhmedPlaymaker 0:4b15c2d4aa58 280 float x = 2.0f*( _horiz->read() - _x0 );
AhmedPlaymaker 0:4b15c2d4aa58 281 float y = 2.0f*( _vert->read() - _y0 );
AhmedPlaymaker 0:4b15c2d4aa58 282
AhmedPlaymaker 0:4b15c2d4aa58 283 // Note: the x value here is inverted to ensure the positive x is to the
AhmedPlaymaker 0:4b15c2d4aa58 284 // right. This is simply due to how the potentiometer on the joystick
AhmedPlaymaker 0:4b15c2d4aa58 285 // I was using was connected up. It could have been corrected in hardware
AhmedPlaymaker 0:4b15c2d4aa58 286 // by swapping the power supply pins. Instead it is done in software so may
AhmedPlaymaker 0:4b15c2d4aa58 287 // need to be changed depending on your wiring setup
AhmedPlaymaker 0:4b15c2d4aa58 288
AhmedPlaymaker 0:4b15c2d4aa58 289 Vector2D coord = {-x,y};
AhmedPlaymaker 0:4b15c2d4aa58 290 return coord;
AhmedPlaymaker 0:4b15c2d4aa58 291 }
AhmedPlaymaker 0:4b15c2d4aa58 292
AhmedPlaymaker 0:4b15c2d4aa58 293 // This maps the raw x,y coord onto a circular grid.
AhmedPlaymaker 0:4b15c2d4aa58 294 // See: http://mathproofs.blogspot.co.uk/2005/07/mapping-square-to-circle.html
AhmedPlaymaker 0:4b15c2d4aa58 295 Vector2D Gamepad::get_mapped_coord()
AhmedPlaymaker 0:4b15c2d4aa58 296 {
AhmedPlaymaker 0:4b15c2d4aa58 297 Vector2D coord = get_coord();
AhmedPlaymaker 0:4b15c2d4aa58 298
AhmedPlaymaker 0:4b15c2d4aa58 299 // do the transformation
AhmedPlaymaker 0:4b15c2d4aa58 300 float x = coord.x*sqrt(1.0f-pow(coord.y,2.0f)/2.0f);
AhmedPlaymaker 0:4b15c2d4aa58 301 float y = coord.y*sqrt(1.0f-pow(coord.x,2.0f)/2.0f);
AhmedPlaymaker 0:4b15c2d4aa58 302
AhmedPlaymaker 0:4b15c2d4aa58 303 Vector2D mapped_coord = {x,y};
AhmedPlaymaker 0:4b15c2d4aa58 304 return mapped_coord;
AhmedPlaymaker 0:4b15c2d4aa58 305 }
AhmedPlaymaker 0:4b15c2d4aa58 306
AhmedPlaymaker 0:4b15c2d4aa58 307 // this function converts the mapped coordinates into polar form
AhmedPlaymaker 0:4b15c2d4aa58 308 Polar Gamepad::get_polar()
AhmedPlaymaker 0:4b15c2d4aa58 309 {
AhmedPlaymaker 0:4b15c2d4aa58 310 // get the mapped coordinate
AhmedPlaymaker 0:4b15c2d4aa58 311 Vector2D coord = get_mapped_coord();
AhmedPlaymaker 0:4b15c2d4aa58 312
AhmedPlaymaker 0:4b15c2d4aa58 313 // at this point, 0 degrees (i.e. x-axis) will be defined to the East.
AhmedPlaymaker 0:4b15c2d4aa58 314 // We want 0 degrees to correspond to North and increase clockwise to 359
AhmedPlaymaker 0:4b15c2d4aa58 315 // like a compass heading, so we need to swap the axis and invert y
AhmedPlaymaker 0:4b15c2d4aa58 316 float x = coord.y;
AhmedPlaymaker 0:4b15c2d4aa58 317 float y = coord.x;
AhmedPlaymaker 0:4b15c2d4aa58 318
AhmedPlaymaker 0:4b15c2d4aa58 319 float mag = sqrt(x*x+y*y); // pythagoras
AhmedPlaymaker 0:4b15c2d4aa58 320 float angle = RAD2DEG*atan2(y,x);
AhmedPlaymaker 0:4b15c2d4aa58 321 // angle will be in range -180 to 180, so add 360 to negative angles to
AhmedPlaymaker 0:4b15c2d4aa58 322 // move to 0 to 360 range
AhmedPlaymaker 0:4b15c2d4aa58 323 if (angle < 0.0f) {
AhmedPlaymaker 0:4b15c2d4aa58 324 angle+=360.0f;
AhmedPlaymaker 0:4b15c2d4aa58 325 }
AhmedPlaymaker 0:4b15c2d4aa58 326
AhmedPlaymaker 0:4b15c2d4aa58 327 // the noise on the ADC causes the values of x and y to fluctuate slightly
AhmedPlaymaker 0:4b15c2d4aa58 328 // around the centred values. This causes the random angle values to get
AhmedPlaymaker 0:4b15c2d4aa58 329 // calculated when the joystick is centred and untouched. This is also when
AhmedPlaymaker 0:4b15c2d4aa58 330 // the magnitude is very small, so we can check for a small magnitude and then
AhmedPlaymaker 0:4b15c2d4aa58 331 // set the angle to -1. This will inform us when the angle is invalid and the
AhmedPlaymaker 0:4b15c2d4aa58 332 // joystick is centred
AhmedPlaymaker 0:4b15c2d4aa58 333
AhmedPlaymaker 0:4b15c2d4aa58 334 if (mag < TOL) {
AhmedPlaymaker 0:4b15c2d4aa58 335 mag = 0.0f;
AhmedPlaymaker 0:4b15c2d4aa58 336 angle = -1.0f;
AhmedPlaymaker 0:4b15c2d4aa58 337 }
AhmedPlaymaker 0:4b15c2d4aa58 338
AhmedPlaymaker 0:4b15c2d4aa58 339 Polar p = {mag,angle};
AhmedPlaymaker 0:4b15c2d4aa58 340 return p;
AhmedPlaymaker 0:4b15c2d4aa58 341 }