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