2015-11-05 03:02:09 +00:00
# ifndef _JOYSTICK_H_
# define _JOYSTICK_H_
# include <Arduino.h>
2015-11-13 05:45:38 +00:00
# include <Bounce2.h>
2021-11-01 18:49:53 +00:00
# include <list>
using std : : list ;
2015-11-05 03:02:09 +00:00
// If you're using the arduino-big-joystick firmware, these numbers can't be
2015-11-06 15:48:38 +00:00
// changed. If you're writing your own Report Descriptor, tune these to match by
// defining them *before* you include Joystick.h.
# ifndef JOYSTICK_NUM_AXES
2015-11-05 03:02:09 +00:00
# define JOYSTICK_NUM_AXES 8
2015-11-06 15:48:38 +00:00
# endif
# ifndef JOYSTICK_NUM_BUTTONS
2015-11-05 03:02:09 +00:00
# define JOYSTICK_NUM_BUTTONS 40
2015-11-06 15:48:38 +00:00
# endif
2015-11-05 03:02:09 +00:00
# define JOYSTICK_NUM_BYTES (JOYSTICK_NUM_BUTTONS+7) / 8
2015-11-06 15:48:38 +00:00
enum ButtonType {
2021-11-01 18:49:53 +00:00
BUTTON_PASSTHRU = 0x1 , // always use the (debounced) absolute state of the input
BUTTON_PULSED = 0x2 , // on button press, send an on signal followed immediately by an off signal.
BUTTON_PULSED_DOUBLE_ACTION = 0x4 , // Send a button press twice - once for press and once for release.
2021-11-01 19:24:05 +00:00
BUTTON_PULSED_DOUBLE_ACTION_SPLIT = 0x8 , // Send two separate button presses - one button on press, another on release.
BUTTON_LATCHED_MOMENTARY = 0x10
2015-11-06 15:48:38 +00:00
} ;
2015-11-11 05:10:45 +00:00
struct JoyReport {
2015-11-05 03:02:09 +00:00
int16_t axis [ JOYSTICK_NUM_AXES ] ;
uint8_t button [ JOYSTICK_NUM_BYTES ] ;
2015-11-11 05:10:45 +00:00
} ;
struct Button {
ButtonType type ;
2015-11-13 05:50:16 +00:00
Bounce bouncer ;
2021-11-01 18:49:53 +00:00
uint8_t index0 ;
2021-11-01 19:24:05 +00:00
uint8_t index1 ; // only used by BUTTON_PULSED_DOUBLE_ACTION_SPLIT
bool pressed = false ; // only used by BUTTON_LATCHED_MOMENTARY
2021-11-01 18:49:53 +00:00
bool inverted = false ; // if true, send button press on release and vice versa.
2015-11-11 05:10:45 +00:00
} ;
2015-11-05 03:02:09 +00:00
2015-11-09 04:15:58 +00:00
bool operator = = ( JoyReport a , JoyReport b ) ;
bool operator ! = ( JoyReport a , JoyReport b ) ;
2015-11-05 03:02:09 +00:00
class Joystick {
public :
Joystick ( bool debug = false ) ;
void Init ( ) ;
2015-11-06 15:48:38 +00:00
void Update ( ) ;
2015-11-05 03:02:09 +00:00
2021-11-01 18:49:53 +00:00
void AddButton ( uint8_t pin , ButtonType type , bool pullup = true ) ;
2015-11-13 01:54:31 +00:00
void AddAxis ( uint8_t pin ) ; // Axes don't actually work yet!
2015-11-06 15:48:38 +00:00
2021-11-01 18:49:53 +00:00
// Public access to these functions is deprecated and they may become private in a future
2015-11-06 15:48:38 +00:00
// version. Prefer the above API instead.
2015-11-05 03:02:09 +00:00
void SetAxis ( uint8_t axis , int16_t value ) ;
void PressButton ( uint8_t button ) ;
void ReleaseButton ( uint8_t button ) ;
void ReleaseAllButtons ( ) ;
void Write ( ) ;
private :
2015-11-09 04:32:48 +00:00
void _ReleasePulsedButtons ( ) ;
2015-11-13 05:45:38 +00:00
void _UpdateButton ( uint8_t index ) ;
2015-11-11 05:10:45 +00:00
void _UpdateAxis ( uint8_t index ) ;
2015-11-09 04:32:48 +00:00
2021-11-01 19:38:01 +00:00
Button _buttons [ JOYSTICK_NUM_BUTTONS ] ;
uint8_t _num_buttons ;
uint8_t _last_button_index ; // a single physical button can have multiple logical buttons. _last_button_index tracks the number of logical / virtual buttons we have defined.
2015-11-09 04:15:58 +00:00
bool _have_pulsed_button ;
2015-11-06 16:36:33 +00:00
uint8_t _axes [ JOYSTICK_NUM_AXES ] ;
uint8_t _num_axes ;
2015-11-05 03:02:09 +00:00
JoyReport _joyReport ;
bool _debug ;
} ;
2015-11-09 04:32:48 +00:00
// Internal use only.
2021-11-01 18:49:53 +00:00
# define _BUTTON_PULSED_TYPES (BUTTON_PULSED | BUTTON_PULSED_DOUBLE_ACTION | BUTTON_PULSED_DOUBLE_ACTION_SPLIT)
2015-11-09 04:32:48 +00:00
2015-11-05 03:02:09 +00:00
# endif