Swadge 2024 2.0.0
APIs to develop games for the Magfest Swadge
|
This component handles both push-buttons and touch-pads. Push-buttons are physical, tactile buttons while touch-pads are touch-sensitive areas on the PCB. Events from push-buttons and touch-pads are processed different ways.
The Swadge mode needs to call checkButtonQueueWrapper(), which calls checkButtonQueue() to receive queued button events. The reason for checkButtonQueueWrapper() is so that the main loop can monitor the button which can be held down to return to the main menu. The event contains which button caused the event, whether it was pressed or released, and the current state of all buttons. This way the Swadge mode is not responsible for high frequency button polling, and can still receive all button inputs.
The individual touch-pads are only represented as a single, larger, circular analog touchpad which reports touches in polar coordinates.
The push-buttons are polled continuously at 1ms intervals in an interrupt, but these readings are not reported to the Swadge modes. The interrupt saves the prior DEBOUNCE_HIST_LEN polled button states and the last reported button state. When all DEBOUNCE_HIST_LEN button states are identical, the interrupt accepts the current state and checks if it different than the last reported state. If there is a difference, the button event is queued in the interrupt to be received by the Swadge mode.
The push-button GPIOs are all read at the same time using Dedicated GPIO.
Originally the push-buttons would trigger an interrupt, but we found that to have less reliable results with more glitches than polling.
Button events used to be delivered to the Swadge mode via a callback. This led to cases where multiple callbacks would occur between a single invocation of that mode's main function. Because the Swadge mode didn't have a separate queue for button events, this caused events to be dropped. Instead of forcing each mode to queue button events, now each mode must dequeue them rather than having a callback called.
Unlike push-buttons, the touch-pads are treated as a single circular area (not discrete touch areas) and are not polled. Events like touches are not queued to be processed later. The individual Swadge mode must poll the current touch state with getTouchJoystick(). The touch state reports the polar coordinates of the touch (angle and radius) as well as the intensity of the touch.
Touch-pad areas are set up and read with Touch Sensor.
You don't need to call initButtons() or deinitButtons(). The system does at the appropriate times.
You do need to call checkButtonQueueWrapper() and should do so in a while-loop to receive all events since the last check. This should be done in the Swadge mode's main function.
You may call getTouchJoystick() to get the analog touch position. This is independent of checkButtonQueueWrapper(). Three utility functions are provided to interpret touch data different ways.
Go to the source code of this file.
Data Structures | |
struct | buttonEvt_t |
A button event containing the button that triggered the event, whether it was pressed or released, and the whole button state. More... | |
Enumerations | |
enum | buttonBit_t { PB_UP = 0x0001 , PB_DOWN = 0x0002 , PB_LEFT = 0x0004 , PB_RIGHT = 0x0008 , PB_A = 0x0010 , PB_B = 0x0020 , PB_START = 0x0040 , PB_SELECT = 0x0080 } |
Bitmask values for all the different buttons. More... | |
Functions | |
void | initButtons (gpio_num_t *pushButtons, uint8_t numPushButtons, touch_pad_t *touchPads, uint8_t numTouchPads) |
Initialize both pushbuttons and touch buttons. | |
void | deinitButtons (void) |
Free memory used by the buttons. | |
bool | checkButtonQueue (buttonEvt_t *) |
Service the queue of button events that caused interrupts This only returns a single event, even if there are multiple in the queue This function may be called multiple times in a row to completely empty the queue. | |
int | getTouchJoystick (int32_t *phi, int32_t *r, int32_t *intensity) |
Get high-level touch input, an analog input. NOTE: You must have touch callbacks enabled to use this. | |
struct buttonEvt_t |
Data Fields | ||
---|---|---|
uint16_t | state | A bitmask for the state of all buttons. |
buttonBit_t | button | The button that caused this event. |
bool | down | True if the button was pressed, false if it was released. |
enum buttonBit_t |
void initButtons | ( | gpio_num_t * | pushButtons, |
uint8_t | numPushButtons, | ||
touch_pad_t * | touchPads, | ||
uint8_t | numTouchPads ) |
Initialize both pushbuttons and touch buttons.
pushButtons | A list of GPIOs with pushbuttons to initialize. The list should be in the same order as buttonBit_t, starting at PB_UP |
numPushButtons | The number of pushbuttons to initialize |
touchPads | A list of touch areas that make up a touchpad to initialize. |
numTouchPads | The number of touch buttons to initialize |
void deinitButtons | ( | void | ) |
Free memory used by the buttons.
bool checkButtonQueue | ( | buttonEvt_t * | evt | ) |
Service the queue of button events that caused interrupts This only returns a single event, even if there are multiple in the queue This function may be called multiple times in a row to completely empty the queue.
evt | If an event occurred, return it through this argument |
int getTouchJoystick | ( | int32_t * | phi, |
int32_t * | r, | ||
int32_t * | intensity ) |
Get high-level touch input, an analog input. NOTE: You must have touch callbacks enabled to use this.
[out] | phi | the angle of the touch. Where 0 is right, 320 is up, 640 is left and 960 is down. |
[out] | r | is how far from center you are. 511 is on the outside edge, 0 is on the inside. |
[out] | intensity | is how hard the user is pressing. |