source: trunk/src/input/input.h @ 2617

Last change on this file since 2617 was 2617, checked in by sam, 10 years ago

input: support up to 32 mouse buttons.

  • Property svn:keywords set to Id
File size: 10.9 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://www.wtfpl.net/ for more details.
9//
10
11//
12// The Input static class
13// ----------------------
14//
15
16#if !defined __LOL_INPUT_INPUT_H__
17#define __LOL_INPUT_INPUT_H__
18
19#include <cstring>
20#include <string.h>
21
22#include "core.h"
23
24#include "lol/math/vector.h"
25#include "input/keyboard.h"
26#include "input/stick.h"
27
28namespace lol
29{
30
31typedef std::string Action;
32static inline int ACTION_CMP(Action a, Action b) { return a.compare(b) == 0; }
33
34class WorldEntity;
35
36/*
37 * The key enumeration values match libSDL's so that we can
38 * easily pass information between Lol and SDL.
39 */
40struct Key
41{
42    enum Value
43    {
44        /* ASCII mapped keys */
45        Unknown =     0,
46        First =       0,
47        Backspace =   8,
48        Tab =         (int)'\t',
49        Clear =       12,
50        Return =      13,
51        Pause =       19,
52        Escape =      27,
53        Space =       (int)' ',
54        Exclaim =     (int)'!',
55        DoubleQuote = (int)'"',
56        Hash =        (int)'#',
57        Dollar =      (int)'$',
58        Ampersand =   (int)'&',
59        Quote =       (int)'\'',
60        LeftParen =   (int)'(',
61        RightParen =  (int)')',
62        Asterisk =    (int)'*',
63        Plus =        (int)'+',
64        Comma =       (int)',',
65        Minus =       (int)'-',
66        Period =      (int)'.',
67        Slash =       (int)'/',
68        K0 = (int)'0',
69        K1 = (int)'1',
70        K2 = (int)'2',
71        K3 = (int)'3',
72        K4 = (int)'4',
73        K5 = (int)'5',
74        K6 = (int)'6',
75        K7 = (int)'7',
76        K8 = (int)'8',
77        K9 = (int)'9',
78        Colon =        (int)':',
79        Semicolon =    (int)';',
80        Less =         (int)'<',
81        Equals =       (int)'=',
82        Greater =      (int)'>',
83        Question =     (int)'?',
84        At =           (int)'@',
85        /* XXX: SDL decides to skip uppercase characters */
86        LeftBracket =  (int)'[',
87        BackSlash =    (int)'\\',
88        RightBracket = (int)']',
89        Caret =        (int)'^',
90        Underscore =   (int)'_',
91        Backquote =    (int)'`',
92        A = (int)'a',
93        B = (int)'b',
94        C = (int)'c',
95        D = (int)'d',
96        E = (int)'e',
97        F = (int)'f',
98        G = (int)'g',
99        H = (int)'h',
100        I = (int)'i',
101        J = (int)'j',
102        K = (int)'k',
103        L = (int)'l',
104        M = (int)'m',
105        N = (int)'n',
106        O = (int)'o',
107        P = (int)'p',
108        Q = (int)'q',
109        R = (int)'r',
110        S = (int)'s',
111        T = (int)'t',
112        U = (int)'u',
113        V = (int)'v',
114        W = (int)'w',
115        X = (int)'x',
116        Y = (int)'y',
117        Z = (int)'z',
118        Delete = 127,
119
120        /* International keyboard syms */
121        World0 = 160, /* 0xA0 */
122        World1 = 161,
123        World2 = 162,
124        World3 = 163,
125        World4 = 164,
126        World5 = 165,
127        World6 = 166,
128        World7 = 167,
129        World8 = 168,
130        World9 = 169,
131        World10 = 170,
132        World11 = 171,
133        World12 = 172,
134        World13 = 173,
135        World14 = 174,
136        World15 = 175,
137        World16 = 176,
138        World17 = 177,
139        World18 = 178,
140        World19 = 179,
141        World20 = 180,
142        World21 = 181,
143        World22 = 182,
144        World23 = 183,
145        World24 = 184,
146        World25 = 185,
147        World26 = 186,
148        World27 = 187,
149        World28 = 188,
150        World29 = 189,
151        World30 = 190,
152        World31 = 191,
153        World32 = 192,
154        World33 = 193,
155        World34 = 194,
156        World35 = 195,
157        World36 = 196,
158        World37 = 197,
159        World38 = 198,
160        World39 = 199,
161        World40 = 200,
162        World41 = 201,
163        World42 = 202,
164        World43 = 203,
165        World44 = 204,
166        World45 = 205,
167        World46 = 206,
168        World47 = 207,
169        World48 = 208,
170        World49 = 209,
171        World50 = 210,
172        World51 = 211,
173        World52 = 212,
174        World53 = 213,
175        World54 = 214,
176        World55 = 215,
177        World56 = 216,
178        World57 = 217,
179        World58 = 218,
180        World59 = 219,
181        World60 = 220,
182        World61 = 221,
183        World62 = 222,
184        World63 = 223,
185        World64 = 224,
186        World65 = 225,
187        World66 = 226,
188        World67 = 227,
189        World68 = 228,
190        World69 = 229,
191        World70 = 230,
192        World71 = 231,
193        World72 = 232,
194        World73 = 233,
195        World74 = 234,
196        World75 = 235,
197        World76 = 236,
198        World77 = 237,
199        World78 = 238,
200        World79 = 239,
201        World80 = 240,
202        World81 = 241,
203        World82 = 242,
204        World83 = 243,
205        World84 = 244,
206        World85 = 245,
207        World86 = 246,
208        World87 = 247,
209        World88 = 248,
210        World89 = 249,
211        World90 = 250,
212        World91 = 251,
213        World92 = 252,
214        World93 = 253,
215        World94 = 254,
216        World95 = 255, /* 0xFF */
217
218        /* Numeric keypad */
219        KP0 = 256,
220        KP1 = 257,
221        KP2 = 258,
222        KP3 = 259,
223        KP4 = 260,
224        KP5 = 261,
225        KP6 = 262,
226        KP7 = 263,
227        KP8 = 264,
228        KP9 = 265,
229        KPPeriod = 266,
230        KPDivide = 267,
231        KPMultiply = 268,
232        KPMinus = 269,
233        KPPlus = 270,
234        KPEnter = 271,
235        KPEquals = 272,
236
237        /* Arrows + Home/End pad */
238        Up = 273,
239        Down = 274,
240        Right = 275,
241        Left = 276,
242        Insert = 277,
243        Home = 278,
244        End = 279,
245        PageUp = 280,
246        PageDown = 281,
247
248        /* Function keys */
249        F1 = 282,
250        F2 = 283,
251        F3 = 284,
252        F4 = 285,
253        F5 = 286,
254        F6 = 287,
255        F7 = 288,
256        F8 = 289,
257        F9 = 290,
258        F10 = 291,
259        F11 = 292,
260        F12 = 293,
261        F13 = 294,
262        F14 = 295,
263        F15 = 296,
264
265        /* Modifier keys */
266        NumLock = 300,
267        CapsLock = 301,
268        ScrollLock= 302,
269        RightShift = 303,
270        LeftShift = 304,
271        RightCtrl = 305,
272        LeftCtrl = 306,
273        RightAlt = 307,
274        LeftAlt = 308,
275        RightMeta = 309,
276        LeftMeta = 310,
277        LeftSuper = 311,  /* Left "Windows" key */
278        RightSuper = 312, /* Right "Windows" key */
279        Mode = 313,       /* "Alt Gr" key */
280        Compose = 314,    /* Multi-key compose key */
281
282        /* Miscellaneous function keys */
283        Help = 315,
284        Print = 316,
285        SysReq = 317,
286        Break = 318,
287        Menu = 319,
288        Power = 320, /* Power Macintosh power key */
289        Euro = 321,  /* Some european keyboards */
290        Undo = 322,  /* Atari keyboard has Undo */
291
292        /* Add any other keys here */
293        Last
294
295    }
296    m_value;
297
298    //BH : Removed KMod from main enum, because I don't have any idea about handling them correctly for now.
299    /*
300        //Enumeration of valid key mods (possibly OR'd together)
301        KM_NONE          = 0x0000,
302        KM_LSHIFT        = 0x0001,
303        KM_RSHIFT        = 0x0002,
304        KM_LCTRL         = 0x0040,
305        KM_RCTRL         = 0x0080,
306        KM_LALT          = 0x0100,
307        KM_RALT          = 0x0200,
308        KM_LMETA         = 0x0400,
309        KM_RMETA         = 0x0800,
310        KM_NUM           = 0x1000,
311        KM_CAPS          = 0x2000,
312        KM_MODE          = 0x4000,
313
314        KM_RESERVED        = 0x8000,
315
316        //Left/Right independent key mods definition
317        KM_CTRL            = (KM_LCTRL|KM_RCTRL),
318        KM_SHIFT        = (KM_LSHIFT|KM_RSHIFT),
319        KM_ALT            = (KM_LALT|KM_RALT),
320        KM_META            = (KM_LMETA|KM_RMETA),
321    */
322
323    inline Key(Value v) { m_value = v; }
324    inline operator Value() { return m_value; }
325    inline bool operator==(const Key& val)
326    {
327        return m_value == val.m_value;
328    }
329};
330
331struct ActionSetting
332{
333    Action m_action;
334    float m_buffering_time;
335    float m_buffered_since;
336
337    ActionSetting(Action NewAction)
338      : m_action(NewAction),
339        m_buffering_time(.0f),
340        m_buffered_since(.0f)
341    { }
342};
343
344struct ButtonSetting
345{
346    Key m_raw_button;
347    Array<ActionSetting> m_associated_action_list;
348
349    ButtonSetting(Key NewRawButton)
350      : m_raw_button(NewRawButton)
351    { }
352
353    int GetActionSettingIdx(Action SearchAction);
354};
355
356class InputTracker : public Entity
357{
358    friend class Input;
359
360public:
361    InputTracker();
362
363private:
364    Array<uint8_t> m_input_status;
365    Array<ButtonSetting> m_input_assocation_list;
366
367    int GetButtonSettingIdx(struct Key k);
368    int GetCurrentButtonStatus(struct Key k);
369    int GetPreviousButtonStatus(struct Key k);
370    void UpdateActionStatus(float seconds);
371
372protected:
373    virtual char const * GetName()
374    {
375        return "<InputTracker>";
376    }
377    virtual void TickGame(float seconds)
378    {
379        Entity::TickGame(seconds);
380
381        UpdateActionStatus(seconds);
382    }
383
384    void LinkActionToKey(Action a, struct Key k);
385    void UnlinkAction(Action a);
386    int GetStatus(Action a);
387    bool WasPressed(Action a);
388    bool WasReleased(Action a);
389
390    //You should probably use the Action System
391    int GetStatus(Key k);
392    bool WasPressed(Key k);
393    bool WasReleased(Key k);
394};
395
396class Input
397{
398private:
399    static InputTracker* m_input_tracker;
400
401    static bool CheckInputTrackerInit()
402    {
403        if (Input::m_input_tracker)
404            return true;
405
406        Input::m_input_tracker = new InputTracker();
407        return true;
408    }
409
410public:
411
412    /* These methods are general queries */
413    static ivec2 GetMousePos();
414    static uint32_t GetMouseButtons();
415
416    //BH : Shouldn't use this
417    static int GetButtonState(int button);
418
419    /* Action management */
420    static void LinkActionToKey(Action a, struct Key k);
421    static void UnlinkAction(Action a);
422    static int GetStatus(Action a);
423    static bool WasPressed(Action a);
424    static bool WasReleased(Action a);
425
426    /* Raw Button management. You should use actions. */
427    static int GetStatus(Key k);
428    static bool WasPressed(Key k);
429    static bool WasReleased(Key k);
430
431    /* Entities can subscribe to events */
432    static void TrackMouse(WorldEntity *e);
433    static void UntrackMouse(WorldEntity *e);
434
435    /* These methods are called by the underlying input listeners */
436    /* FIXME: this should disappear and be replaced by an input
437     * system that abstracts mice */
438    static void SetMousePos(ivec2 coord);
439    static void SetMouseButton(int index);
440    static void UnsetMouseButton(int index);
441
442    /* Keyboard handling */
443    static Keyboard *CreateKeyboard();
444    static void DestroyKeyboard(Keyboard *keyboard);
445
446    static Keyboard *TrackKeyboard(int desired);
447    static void UntrackKeyboard(Keyboard *keyboard);
448
449    /* Joystick handling */
450    static Stick *CreateStick();
451    static void DestroyStick(Stick *stick);
452
453    static Stick *TrackStick(int desired);
454    static void UntrackStick(Stick *stick);
455};
456
457} /* namespace lol */
458
459#endif // __LOL_INPUT_INPUT_H__
460
Note: See TracBrowser for help on using the repository browser.