#include "Joystick.h" #include "Button.h" #include #include #include using namespace admux; bool operator ==(JoyReport a, JoyReport b){ for (uint8_t i=0; i < JOYSTICK_NUM_AXES; i++) { if (a.axis[i] != b.axis[i]) return false; } for (uint8_t i=0; i < JOYSTICK_NUM_BYTES; i++) { if (a.button[i] != b.button[i]) return false; } return true; } bool operator !=(JoyReport a, JoyReport b){ return !(a == b); } Joystick::Joystick(bool debug) { _debug = debug; _virtual_buttons = 0; _num_axes = 0; _num_buttons = 0; _have_pulsed_button = false; for (uint8_t i=0; i < JOYSTICK_NUM_AXES; i++) { _joyReport.axis[i] = 0; } for (uint8_t i=0; i < JOYSTICK_NUM_BYTES; i++) { _joyReport.button[i] = 0; } } void Joystick::Init() { Serial.begin(115200); delay(100); } void Joystick::AddButton(uint8_t pin, ButtonType type, bool pullup, Mux* mux) { Button *button; switch (type) { case BUTTON_PASSTHRU: button = new PassthruButton(pin, _virtual_buttons, pullup, mux); _virtual_buttons++; break; case BUTTON_PULSED: button = new PulsedButton(pin, _virtual_buttons, false, false, pullup, mux); _virtual_buttons++; break; case BUTTON_PULSED_DOUBLE_ACTION: button = new PulsedButton(pin, _virtual_buttons, true, false, pullup, mux); _virtual_buttons++; break; case BUTTON_PULSED_DOUBLE_ACTION_SPLIT: button = new PulsedButton(pin, _virtual_buttons, true, true, pullup, mux); _virtual_buttons += 2; break; default: return; } _buttons[_num_buttons] = button; _num_buttons++; if (_debug) { char buffer[100]; sprintf(buffer, "Added button %d of type %d", _num_buttons - 1, button->type); Serial.println(buffer); } if (type & _BUTTON_PULSED_TYPES) _have_pulsed_button = true; } void Joystick::AddEncoder(uint8_t pin1, uint8_t pin2, ButtonType type) { Button *button; switch (type) { case ENCODER_PULSED_SPLIT: // add an encoder button. _BuildButton() doesn't do everything we need, however... button = new EncoderButton(pin1, pin2, _virtual_buttons); _buttons[_num_buttons] = button; _num_buttons++; _virtual_buttons += 2; break; default: if (_debug) { Serial.print("DEBUG: Unhandled encoder type: "); Serial.println(type); } } } void Joystick::AddAxis(uint8_t pin) { _axes[_num_axes] = pin; _num_axes++; } void Joystick::Update() { JoyReport oldReport = _joyReport; for (uint8_t i = 0; i < _num_buttons; i++) { bool changed = _buttons[i]->Update(this); if (changed && _debug) { char buffer[25]; sprintf(buffer, "Button %d changed state.", i); Serial.println(buffer); } } // TODO: implement this and also refactor it into a class or classes for (uint8_t i = 0; i < _num_axes; i++) { _UpdateAxis(i); } if (_joyReport != oldReport) { Write(); if (_have_pulsed_button) { _ReleasePulsedButtons(); Write(); } } } void Joystick::SetAxis(uint8_t axis, int16_t value) { if (axis >= JOYSTICK_NUM_AXES) return; _joyReport.axis[axis] = value; } void Joystick::PressButton(uint8_t button) { if (button >= JOYSTICK_NUM_BUTTONS) return; uint8_t byte = button / 8; uint8_t bit = button % 8; _joyReport.button[byte] |= 1 << bit; } void Joystick::ReleaseButton(uint8_t button) { if (button >= JOYSTICK_NUM_BUTTONS) return; uint8_t byte = button / 8; uint8_t bit = button % 8; _joyReport.button[byte] &= ~(1 << bit); } void Joystick::ReleaseAllButtons() { for (uint8_t i = 0; i < JOYSTICK_NUM_BYTES; i++) { _joyReport.button[i] = 0; } } void Joystick::_ReleasePulsedButtons() { for (uint8_t i = 0; i < _num_buttons; i++ ) { Button* button = _buttons[i]; if (button->type & _BUTTON_PULSED_TYPES) button->ReleaseButtons(this); } } void Joystick::Write() { if (!_debug) { Serial.write((uint8_t *)&_joyReport, sizeof(JoyReport)); } else { Serial.print("DEBUG: Writing data: "); for (uint8_t i=0; i < JOYSTICK_NUM_AXES; i++) { Serial.print(_joyReport.axis[i]); Serial.print(" "); } for (uint8_t i=0; i < JOYSTICK_NUM_BYTES; i++) { Serial.print(_joyReport.button[i]); Serial.print(" "); } Serial.println(); } delay(250); } void Joystick::_UpdateAxis(uint8_t index) { if (_debug) Serial.println("STUB: Joystick::_UpdateAxis"); }