diff -r 7e0cfc5f0944 -r 440763821484 src/Input.hh --- a/src/Input.hh Mon Dec 08 21:15:52 2008 +0000 +++ b/src/Input.hh Mon Dec 08 21:18:08 2008 +0000 @@ -1,13 +1,25 @@ #ifndef INPUT_HH #define INPUT_HH -#include +#include "Timer.hh" +#include "Types.hh" + #include #include +#include // const TimeMS INPUT_INTERVAL_MS = 20; /** + * Flags to control input behaviour + */ +enum InputFlagBits { + /** Default */ + INPUT_FLAG_REPEAT = 0x0000, + INPUT_FLAG_NOREPEAT = 0x0001, +}; + +/** * The bits used in the PlayerInput bitmask, each represents a separate action handled by LocalPlayer::handleInput. * * @see LocalPlayer::handleInput @@ -38,12 +50,19 @@ * The bits used in the GuiInput bitmask, each represents something handled locally by Graphics. */ enum GuiInputBit { + GUI_INPUT_NONE = 0x0000, + GUI_INPUT_QUIT = 0x0001, GUI_INPUT_DISPLAY_WEAPON = 0x0002, GUI_INPUT_DEBUG_PLAYER = 0x0004, }; /** + * Bitmask of InputFlagBits + */ +typedef uint8_t InputFlags; + +/** * Bitmask of PlayerInputBits * * @see PlayerInputBit @@ -58,29 +77,191 @@ typedef uint16_t GuiInput; /** - * Keymap definition used in Input.cc + * Keymap definition struct */ -template struct InputKeymapEntry; +template struct InputKeymapEntry { + /** + * The input bit to set if present + */ + BitEnumType input; + + /** + * Flags to use + * + * @see InputFlagBits + */ + InputFlags flags; + + /** + * Up to two keycodes to check + */ + int keycodes[2]; +}; + + +/** + * A InputKeyRepeatQueue entry, this contains the input bit value itself, and then the remaining expire time + */ +template struct InputKeyRepeatEntry { + BitEnumType value; + TimeMS expire; + + public: + InputKeyRepeatEntry (BitEnumType value, TimeMS expire); + + /** + * Since priority_queue always gives the greatest item, the one with the longest expire is the least item + */ + bool operator< (const struct InputKeyRepeatEntry &other); + + /** + * Decrements expire, returning true if it has now expired, false otherwise + */ + bool updateExpired (TimeMS dt); +}; + +/** + * A InputKeyRepeatQueue maintains a list of InputKeyRepeatEntry's, lets you add new input values, find old ones, + * and update the list + */ +template class InputKeyRepeatQueue { + private: + TimeMS expire; + + typedef InputKeyRepeatEntry entry_type; + + std::list list; + + typedef typename std::list::iterator list_iterator; + + public: + /** + * Constructs this queue to contain entries with the given expiry time + */ + InputKeyRepeatQueue (TimeMS expire); + + /** + * Push a new input bit onto the queue + */ + void push (BitEnumType bit); + + /** + * Checks if the given input is in the queue + */ + bool find (BitEnumType bit); + + /** + * Updates the list, removing expired items + */ + void update (TimeMS dt); +}; + +/** + * An InputHandler uses an InputKeymapEntry to maintain a BitMaskType of current inputs + */ +template class InputHandler { + private: + /** + * The keyboard that we read input from + */ + CL_InputDevice &keyboard; + + /** + * The keymap that we use + */ + InputKeymapEntry *keymap; + + /** + * The current bitmask value + */ + BitMaskType value; + + /** + * How long the bitmask was held... + */ + TimeMS dt; + + /** + * The KeyRepeatQueue + */ + InputKeyRepeatQueue queue; + + public: + /** + * Constructs the InputHandler using the given keyboard, keymap and key-repeat expire time + */ + InputHandler (CL_InputDevice &keyboard, InputKeymapEntry *keymap, TimeMS keyrepeat_expire); + + private: + /** + * Returns true if the keycode is valid, false if not. + * + * A positive keycode requires that the keycode be active, a negative keycode that the keycode be inactive, + * and a zero keycode always returns true. + * + * @param keycode A positive keycode to check that it's set, negative keycode to check that it's not set, or zero + * @returns bool true if positive+set/negavtive+notset/zero, false otherwise + */ + bool checkKeycode (int keycode); + + public: + /** + * Updates the keyrepeat queue + */ + void update (TimeMS dt); + + /** + * Reads the current input mask value and length into mask and dt, and reset ours to zero + * + * @param mask our BitMaskType value is returned using this + * @param dt how long the input was held for + */ + void readValue (BitMaskType &mask, TimeMS &dt); + +}; /** * Handles reading input from a keyboard and mapping it to PlayerInput/GuiInput bitmasks */ class Input { protected: + /** + * The keyboard device that we use + */ CL_InputDevice &keyboard; + /** + * Our update timer + */ + Timer update_timer; + + CL_SlotContainer slots; + + /** + * Our PlayerInput + */ + InputHandler player; + + /** + * Our GuiInput + */ + InputHandler gui; + public: + /** + * Build the input handler using the given keyboard and the default keymaps + */ Input (CL_InputDevice &keyboard); - - private: - bool checkKeycode (int keycode); - template BitMaskType buildMask (InputKeymapEntry *keymap); public: - /* - * Reads the keyboard to determine current state of the Player/Gui input + /** + * Reads the current PlayerInput value via mask, and the length of the input via dt */ - PlayerInput readPlayerInput (void); + void readPlayerInput (PlayerInput &mask, TimeMS &dt); + + /** + * Reads the current GuiInput mask and returns it + */ GuiInput readGuiInput (void); };