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