// Copyright (c) 2021 Dominic Msters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT #pragma once #include #include #include #include #include #include "../util/list.h" #include "../platform.h" /////////////////////////////////// CONSTANTS ////////////////////////////////// #define INPUT_NULL (inputbind_t)0x00 /////////////////////////////// Type Definitions /////////////////////////////// /** * Input Bind, a specific action bind reference for the game engine to use. * e.g. "Jump" or "Walk Forward". */ typedef uint8_t inputbind_t; /** * Input source identifier. It's up to the platform itself to decide what the * hell this number refers to. For most platforms it will be an input, such as a * keyboard scancode or a (pad number * button count) + button. */ typedef uint32_t inputsource_t; /** * Value that represents the state of an input. Defined as 0-1 where 0 is set * to be completely off / netural state, and 1 is completely on / full state. */ typedef float inputval_t; /** * Structure for the entire input mapping. */ typedef struct { /** How many input bindings are in the input managers' scope */ uint32_t inputBindCount; /** Float of the input between 0 and 1. For teh current frame */ inputval_t *current; /** Float of the input between 0 and 1. For the last frame */ inputval_t *previous; /** * Input buffer array. Keeps track of raw values from the inputs. * The engine will read from the buffer when necessary. */ inputval_t *buffer; /** Float of the GameTime that the input was actuated last. */ float *times; /** * Binding Map, Array of lists where index = binding and entry is a list of * input sources. */ list_t **bindMap; } input_t; //////////////////////////////////// Methods /////////////////////////////////// /** * Initializes the input manager. * * @param inputCount The input binding counts to allow for. * @param inputSourceCount The input source count to allow for. * @return The input manager */ input_t * inputInit(uint32_t inputBindCount, uint32_t inputSourceCount); /** * Tick the input manager. * @param input The input to update. */ void inputUpdate(input_t *input); /** * Destroy the input manager and cleanup. * @param input The input to destroy. */ void inputDispose(input_t *input); /** * Binds the given input binding to the input source. Essentially allowing any * time we fetch the state of bind, we will read the value from source. * * @param input The input manager to bind for. * @param bind The binding to bind against. * @param source The source that is being bound. */ void inputBind(input_t *input, inputbind_t bind, inputsource_t source); /** * Unbind a previously bound input source from a binding. This method is costly. * * @param input The input manager to bind for. * @param bind The binding to unbind from. * @param source The source that is being unbound. */ void inputUnbind(input_t *input, inputbind_t bind, inputsource_t source); /** * Is the current input "down", not being pressed, being moved, not in a state * of rest. * * @param state The input state to check against. * @param binding The previously bound input binding. * @return True if the input vector is non-zero. */ bool inputIsDown(input_t *state, inputbind_t binding); /** * Is the current input "up", in a state of rest, not being actioned, moved. * * @param state The input state to check against. * @param binding The previously bound input binding. * @return True if input vector is zero */ bool inputIsUp(input_t *state, inputbind_t binding); /** * Returns true on the first tick that an input was actioned/downed. * * @param input The input manager. * @param binding The previously bound input binding. * @return True if the input vector was non-zeroed this tick but not last. */ bool inputIsPressed(input_t *input, inputbind_t binding); /** * Returns true on the first tick that an input was released/upped. * * @param input The input manager. * @param binding The previously bound input binding. * @return True if the input vector was zeroed this tick but not last. */ bool inputIsReleased(input_t *input, inputbind_t binding); /** * Returns the raw input value as a float between 0 and 1. For digital (buttons) * this will typicall be 0 or 1 only. Other analogue inputs will have anywhere * within the range. * * @param input The input manager to check against. * @param binding The previously bound input binding. * @return Input state of the axis. */ inputval_t inputGetAxis(input_t *input, inputbind_t binding); /** * Returns a raw input value between -1 and 1 between two axis. This would be * indicitive of having an input with an axis that can be moved one direction * for a positive input and another for a negative input, typically a game * controller's analogue sticks. * * @param input The input manager to check against. * @param postitive The positive axis binding. * @param negative The negative axis binding. * @return A float between -1 and 1 representing the result of both. */ float inputGetFullAxis(input_t *input, inputbind_t positive, inputbind_t negative ); /** * Returns the time that an input was actuated at. Actuate would count as a * non-zero input for analogue inputs. * * @param input The input manager to check against. * @param binding The previously bound input binding. * @return Game Engine time that an input was non-zeroed */ float inputGetAccuated(input_t *input, inputbind_t binding);