src/Input.hh
changeset 311 440763821484
parent 300 417183866f35
child 319 9f6a838d58c4
equal deleted inserted replaced
310:7e0cfc5f0944 311:440763821484
     1 #ifndef INPUT_HH
     1 #ifndef INPUT_HH
     2 #define INPUT_HH
     2 #define INPUT_HH
     3 
     3 
     4 #include <stdint.h>
     4 #include "Timer.hh"
       
     5 #include "Types.hh"
       
     6 
     5 #include <ClanLib/Display/input_device.h>
     7 #include <ClanLib/Display/input_device.h>
     6 #include <ClanLib/Display/keys.h>
     8 #include <ClanLib/Display/keys.h>
       
     9 #include <queue>
     7 
    10 
     8 // const TimeMS INPUT_INTERVAL_MS = 20;
    11 // const TimeMS INPUT_INTERVAL_MS = 20;
       
    12 
       
    13 /**
       
    14  * Flags to control input behaviour
       
    15  */
       
    16 enum InputFlagBits {
       
    17     /** Default */
       
    18     INPUT_FLAG_REPEAT   = 0x0000,
       
    19     INPUT_FLAG_NOREPEAT = 0x0001,
       
    20 };
     9 
    21 
    10 /**
    22 /**
    11  * The bits used in the PlayerInput bitmask, each represents a separate action handled by LocalPlayer::handleInput.
    23  * The bits used in the PlayerInput bitmask, each represents a separate action handled by LocalPlayer::handleInput.
    12  *
    24  *
    13  * @see LocalPlayer::handleInput
    25  * @see LocalPlayer::handleInput
    36 
    48 
    37 /**
    49 /**
    38  * The bits used in the GuiInput bitmask, each represents something handled locally by Graphics.
    50  * The bits used in the GuiInput bitmask, each represents something handled locally by Graphics.
    39  */
    51  */
    40 enum GuiInputBit {
    52 enum GuiInputBit {
       
    53     GUI_INPUT_NONE              = 0x0000,
       
    54 
    41     GUI_INPUT_QUIT              = 0x0001,
    55     GUI_INPUT_QUIT              = 0x0001,
    42     GUI_INPUT_DISPLAY_WEAPON    = 0x0002,
    56     GUI_INPUT_DISPLAY_WEAPON    = 0x0002,
    43     GUI_INPUT_DEBUG_PLAYER      = 0x0004,
    57     GUI_INPUT_DEBUG_PLAYER      = 0x0004,
    44 };
    58 };
    45 
    59 
    46 /**
    60 /**
       
    61  * Bitmask of InputFlagBits
       
    62  */
       
    63 typedef uint8_t InputFlags;
       
    64 
       
    65 /**
    47  * Bitmask of PlayerInputBits
    66  * Bitmask of PlayerInputBits
    48  *
    67  *
    49  * @see PlayerInputBit
    68  * @see PlayerInputBit
    50  */
    69  */
    51 typedef uint16_t PlayerInput;
    70 typedef uint16_t PlayerInput;
    56  * @see GuiInputBit
    75  * @see GuiInputBit
    57  */
    76  */
    58 typedef uint16_t GuiInput;
    77 typedef uint16_t GuiInput;
    59 
    78 
    60 /**
    79 /**
    61  * Keymap definition used in Input.cc
    80  * Keymap definition struct
    62  */
    81  */
    63 template <typename BitEnumType> struct InputKeymapEntry;
    82 template <typename BitEnumType> struct InputKeymapEntry {
       
    83     /**
       
    84      * The input bit to set if present
       
    85      */
       
    86     BitEnumType input;
       
    87 
       
    88     /**
       
    89      * Flags to use
       
    90      *
       
    91      * @see InputFlagBits
       
    92      */
       
    93     InputFlags flags;
       
    94 
       
    95     /**
       
    96      * Up to two keycodes to check
       
    97      */
       
    98     int keycodes[2];
       
    99 };
       
   100 
       
   101 
       
   102 /**
       
   103  * A InputKeyRepeatQueue entry, this contains the input bit value itself, and then the remaining expire time
       
   104  */
       
   105 template <typename BitEnumType> struct InputKeyRepeatEntry {
       
   106         BitEnumType value;
       
   107         TimeMS expire;
       
   108 
       
   109     public:
       
   110         InputKeyRepeatEntry (BitEnumType value, TimeMS expire);
       
   111         
       
   112         /**
       
   113          * Since priority_queue always gives the greatest item, the one with the longest expire is the least item
       
   114          */
       
   115         bool operator< (const struct InputKeyRepeatEntry &other);
       
   116         
       
   117         /**
       
   118          * Decrements expire, returning true if it has now expired, false otherwise
       
   119          */
       
   120         bool updateExpired (TimeMS dt);
       
   121 };
       
   122 
       
   123 /**
       
   124  * A InputKeyRepeatQueue maintains a list of InputKeyRepeatEntry's, lets you add new input values, find old ones,
       
   125  * and update the list
       
   126  */
       
   127 template <typename BitEnumType> class InputKeyRepeatQueue {
       
   128     private:
       
   129         TimeMS expire;
       
   130 
       
   131         typedef InputKeyRepeatEntry<BitEnumType> entry_type;
       
   132 
       
   133         std::list<entry_type> list;
       
   134 
       
   135         typedef typename std::list<entry_type>::iterator list_iterator;
       
   136 
       
   137     public:
       
   138         /**
       
   139          * Constructs this queue to contain entries with the given expiry time
       
   140          */
       
   141         InputKeyRepeatQueue (TimeMS expire);
       
   142         
       
   143         /**
       
   144          * Push a new input bit onto the queue
       
   145          */
       
   146         void push (BitEnumType bit);
       
   147 
       
   148         /**
       
   149          * Checks if the given input is in the queue
       
   150          */
       
   151         bool find (BitEnumType bit);
       
   152         
       
   153         /**
       
   154          * Updates the list, removing expired items
       
   155          */
       
   156         void update (TimeMS dt);
       
   157 };
       
   158 
       
   159 /**
       
   160  * An InputHandler uses an InputKeymapEntry to maintain a BitMaskType of current inputs
       
   161  */
       
   162 template <typename BitEnumType, typename BitMaskType> class InputHandler {
       
   163     private:
       
   164         /**
       
   165          * The keyboard that we read input from
       
   166          */
       
   167         CL_InputDevice &keyboard;
       
   168         
       
   169         /**
       
   170          * The keymap that we use
       
   171          */
       
   172         InputKeymapEntry<BitEnumType> *keymap;
       
   173         
       
   174         /**
       
   175          * The current bitmask value
       
   176          */
       
   177         BitMaskType value;
       
   178 
       
   179         /**
       
   180          * How long the bitmask was held...
       
   181          */
       
   182         TimeMS dt;
       
   183         
       
   184         /**
       
   185          * The KeyRepeatQueue
       
   186          */
       
   187         InputKeyRepeatQueue<BitEnumType> queue;
       
   188     
       
   189     public:
       
   190         /**
       
   191          * Constructs the InputHandler using the given keyboard, keymap and key-repeat expire time
       
   192          */
       
   193         InputHandler (CL_InputDevice &keyboard, InputKeymapEntry<BitEnumType> *keymap, TimeMS keyrepeat_expire);
       
   194     
       
   195     private: 
       
   196         /**
       
   197          * Returns true if the keycode is valid, false if not.
       
   198          *
       
   199          * A positive keycode requires that the keycode be active, a negative keycode that the keycode be inactive,
       
   200          * and a zero keycode always returns true.
       
   201          *
       
   202          * @param keycode A positive keycode to check that it's set, negative keycode to check that it's not set, or zero
       
   203          * @returns bool true if positive+set/negavtive+notset/zero, false otherwise
       
   204          */
       
   205         bool checkKeycode (int keycode);
       
   206     
       
   207     public:
       
   208         /**
       
   209          * Updates the keyrepeat queue
       
   210          */
       
   211         void update (TimeMS dt);
       
   212 
       
   213         /**
       
   214          * Reads the current input mask value and length into mask and dt, and reset ours to zero
       
   215          *
       
   216          * @param mask our BitMaskType value is returned using this
       
   217          * @param dt how long the input was held for
       
   218          */
       
   219         void readValue (BitMaskType &mask, TimeMS &dt);
       
   220 
       
   221 };
    64 
   222 
    65 /**
   223 /**
    66  * Handles reading input from a keyboard and mapping it to PlayerInput/GuiInput bitmasks
   224  * Handles reading input from a keyboard and mapping it to PlayerInput/GuiInput bitmasks
    67  */
   225  */
    68 class Input {
   226 class Input {
    69     protected:
   227     protected:
       
   228         /**
       
   229          * The keyboard device that we use
       
   230          */
    70         CL_InputDevice &keyboard;
   231         CL_InputDevice &keyboard;
    71 
   232 
    72     public:
   233         /**
       
   234          * Our update timer
       
   235          */
       
   236         Timer update_timer;
       
   237 
       
   238         CL_SlotContainer slots;
       
   239         
       
   240         /**
       
   241          * Our PlayerInput
       
   242          */
       
   243         InputHandler<PlayerInputBit, PlayerInput> player;
       
   244         
       
   245         /**
       
   246          * Our GuiInput
       
   247          */
       
   248         InputHandler<GuiInputBit, GuiInput> gui;
       
   249 
       
   250     public:
       
   251         /**
       
   252          * Build the input handler using the given keyboard and the default keymaps
       
   253          */
    73         Input (CL_InputDevice &keyboard);
   254         Input (CL_InputDevice &keyboard);
    74     
   255 
    75     private:
   256     public:
    76         bool checkKeycode (int keycode);
   257         /**
    77         template <typename BitEnumType, typename BitMaskType> BitMaskType buildMask (InputKeymapEntry<BitEnumType> *keymap);
   258          * Reads the current PlayerInput value via mask, and the length of the input via dt
    78 
   259          */
    79     public:
   260         void readPlayerInput (PlayerInput &mask, TimeMS &dt);
    80         /*
   261 
    81          * Reads the keyboard to determine current state of the Player/Gui input
   262         /**
    82          */
   263          * Reads the current GuiInput mask and returns it
    83         PlayerInput readPlayerInput (void);
   264          */
    84         GuiInput readGuiInput (void);
   265         GuiInput readGuiInput (void);
    85 };
   266 };
    86 
   267 
    87 #endif
   268 #endif