joeylib2/src/core/input.c

172 lines
4.4 KiB
C

// Public input API. Maintains current/previous state buffers for the
// keyboard (gKeyState/gKeyPrev), mouse buttons (gMouseButtonState/
// gMouseButtonPrev), and joystick buttons (gJoyButtonState/
// gJoyButtonPrev). joeyInputPoll snapshots the previous state, then
// asks the port HAL to refresh the current state; the predicates
// derive held/edge values from those two buffers.
//
// Mouse position and joystick axes are plain current state with no
// edge predicates -- games that want deltas track the previous values
// themselves.
#include <string.h>
#include "joey/input.h"
#include "hal.h"
#include "inputInternal.h"
bool gKeyState [KEY_COUNT];
bool gKeyPrev [KEY_COUNT];
int16_t gMouseX = 0;
int16_t gMouseY = 0;
bool gMouseButtonState[MOUSE_BUTTON_COUNT];
bool gMouseButtonPrev [MOUSE_BUTTON_COUNT];
bool gJoyConnected [JOYSTICK_COUNT];
int8_t gJoyAxisX [JOYSTICK_COUNT];
int8_t gJoyAxisY [JOYSTICK_COUNT];
bool gJoyButtonState[JOYSTICK_COUNT][JOY_BUTTON_COUNT];
bool gJoyButtonPrev [JOYSTICK_COUNT][JOY_BUTTON_COUNT];
void joeyInputPoll(void) {
memcpy(gKeyPrev, gKeyState, sizeof(gKeyState));
memcpy(gMouseButtonPrev, gMouseButtonState, sizeof(gMouseButtonState));
memcpy(gJoyButtonPrev, gJoyButtonState, sizeof(gJoyButtonState));
halInputPoll();
}
void joeyWaitForAnyKey(void) {
int16_t i;
// Prime the previous-state snapshot so a key already held when the
// wait starts has to be released and re-pressed (rising edge) to
// satisfy the wait. Otherwise auto-repeat or a key still down from
// the previous frame would exit instantly.
joeyInputPoll();
while (1) {
joeyInputPoll();
for (i = (int16_t)(KEY_NONE + 1); i < (int16_t)KEY_COUNT; i++) {
if (joeyKeyPressed((JoeyKeyE)i)) {
return;
}
}
}
}
bool joeyKeyDown(JoeyKeyE key) {
if (key <= KEY_NONE || key >= KEY_COUNT) {
return false;
}
return gKeyState[key];
}
bool joeyKeyPressed(JoeyKeyE key) {
if (key <= KEY_NONE || key >= KEY_COUNT) {
return false;
}
return gKeyState[key] && !gKeyPrev[key];
}
bool joeyKeyReleased(JoeyKeyE key) {
if (key <= KEY_NONE || key >= KEY_COUNT) {
return false;
}
return !gKeyState[key] && gKeyPrev[key];
}
bool joeyMouseDown(JoeyMouseButtonE button) {
if (button <= MOUSE_BUTTON_NONE || button >= MOUSE_BUTTON_COUNT) {
return false;
}
return gMouseButtonState[button];
}
bool joeyMousePressed(JoeyMouseButtonE button) {
if (button <= MOUSE_BUTTON_NONE || button >= MOUSE_BUTTON_COUNT) {
return false;
}
return gMouseButtonState[button] && !gMouseButtonPrev[button];
}
bool joeyMouseReleased(JoeyMouseButtonE button) {
if (button <= MOUSE_BUTTON_NONE || button >= MOUSE_BUTTON_COUNT) {
return false;
}
return !gMouseButtonState[button] && gMouseButtonPrev[button];
}
int16_t joeyMouseX(void) {
return gMouseX;
}
int16_t joeyMouseY(void) {
return gMouseY;
}
bool joeyJoystickConnected(JoeyJoystickE js) {
if ((int)js < 0 || (int)js >= JOYSTICK_COUNT) {
return false;
}
return gJoyConnected[js];
}
int8_t joeyJoystickX(JoeyJoystickE js) {
if ((int)js < 0 || (int)js >= JOYSTICK_COUNT) {
return 0;
}
return gJoyAxisX[js];
}
int8_t joeyJoystickY(JoeyJoystickE js) {
if ((int)js < 0 || (int)js >= JOYSTICK_COUNT) {
return 0;
}
return gJoyAxisY[js];
}
bool joeyJoyDown(JoeyJoystickE js, JoeyJoyButtonE button) {
if ((int)js < 0 || (int)js >= JOYSTICK_COUNT) {
return false;
}
if ((int)button < 0 || (int)button >= JOY_BUTTON_COUNT) {
return false;
}
return gJoyButtonState[js][button];
}
bool joeyJoyPressed(JoeyJoystickE js, JoeyJoyButtonE button) {
if ((int)js < 0 || (int)js >= JOYSTICK_COUNT) {
return false;
}
if ((int)button < 0 || (int)button >= JOY_BUTTON_COUNT) {
return false;
}
return gJoyButtonState[js][button] && !gJoyButtonPrev[js][button];
}
bool joeyJoyReleased(JoeyJoystickE js, JoeyJoyButtonE button) {
if ((int)js < 0 || (int)js >= JOYSTICK_COUNT) {
return false;
}
if ((int)button < 0 || (int)button >= JOY_BUTTON_COUNT) {
return false;
}
return !gJoyButtonState[js][button] && gJoyButtonPrev[js][button];
}