/** * Copyright (c) 2025 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "input.h" #include "assert/assert.h" #include "util/memory.h" #include "util/string.h" #include "util/math.h" input_t INPUT; void inputInit(void) { memoryZero(&INPUT, sizeof(input_t)); for(uint8_t i = 0; i < INPUT_ACTION_COUNT; i++) { INPUT.actions[i].action = (inputaction_t)i; INPUT.actions[i].lastValue = 0.0f; INPUT.actions[i].currentValue = 0.0f; } INPUT.deadzone = 0.1f; } void inputUpdate(void) { #if INPUT_SDL2 == 1 #if INPUT_GAMEPAD == 1 INPUT.controller = NULL; for(int32_t i = 0; i < SDL_NumJoysticks(); i++) { if(!SDL_IsGameController(i)) continue; INPUT.controller = SDL_GameControllerOpen(i); if(INPUT.controller) break; } #endif #if INPUT_KEYBOARD == 1 INPUT.keyboardState = SDL_GetKeyboardState(NULL); #endif #endif // Reset all actions inputactiondata_t *action = &INPUT.actions[0]; do { action->lastValue = action->currentValue; action->currentValue = 0.0f; action++; } while(action < &INPUT.actions[INPUT_ACTION_COUNT]); // For each button... inputbuttondata_t *cur = &INPUT_BUTTON_DATA[0]; do { cur->lastVal = cur->curVal; cur->curVal = inputButtonGetValue(cur->button); if(cur->curVal == 0.0f) { cur++; continue; } INPUT.actions[cur->action].currentValue = mathMax( cur->curVal, INPUT.actions[cur->action].currentValue ); cur++; } while(cur->name); } float_t inputGetCurrentValue(const inputaction_t action) { assertTrue(action < INPUT_ACTION_COUNT, "Input action out of bounds"); return INPUT.actions[action].currentValue; } float_t inputGetLast(const inputaction_t action) { assertTrue(action < INPUT_ACTION_COUNT, "Input action out of bounds"); return INPUT.actions[action].lastValue; } bool_t inputIsDown(const inputaction_t action) { return inputGetCurrentValue(action) > 0.0f; } bool_t inputWasDown(const inputaction_t action) { return inputGetLast(action) > 0.0f; } bool_t inputPressed(const inputaction_t action) { return inputIsDown(action) && !inputWasDown(action); } bool_t inputReleased(const inputaction_t action) { return !inputIsDown(action) && inputWasDown(action); } float_t inputAxis(const inputaction_t neg, const inputaction_t pos) { assertTrue(neg < INPUT_ACTION_COUNT, "Negative input action out of bounds"); assertTrue(pos < INPUT_ACTION_COUNT, "Positive input action out of bounds"); return inputGetCurrentValue(pos) - inputGetCurrentValue(neg); } void inputBind(const inputbutton_t button, const inputaction_t act) { assertTrue( act < INPUT_ACTION_COUNT, "Invalid input action" ); // Get the button data for this button. inputbuttondata_t *data = INPUT_BUTTON_DATA; do { if(memoryCompare(&data->button, &button, sizeof(inputbutton_t)) == 0) { break; } data++; } while(data->name != NULL); assertNotNull(data->name, "Input button not found"); // Bind the action. data->action = act; }