// 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 #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]; }