// // Lol Engine // // Copyright: (c) 2010-2012 Sam Hocevar // This program is free software; you can redistribute it and/or // modify it under the terms of the Do What The Fuck You Want To // Public License, Version 2, as published by Sam Hocevar. See // http://sam.zoy.org/projects/COPYING.WTFPL for more details. // // // The Input static class // ---------------------- // #if !defined __LOL_INPUT_INPUT_H__ #define __LOL_INPUT_INPUT_H__ #include #include #include "core.h" #include "lol/math/vector.h" #include "input/keyboard.h" #include "input/stick.h" namespace lol { typedef std::string Action; static inline int ACTION_CMP(Action a, Action b) { return a.compare(b) == 0; } class WorldEntity; /* * The key enumeration values match libSDL's so that we can * easily pass information between Lol and SDL. */ struct Key { enum Value { /* ASCII mapped keys */ Unknown = 0, First = 0, Backspace = 8, Tab = 9, Clear = 12, Return = 13, Pause = 19, Escape = 27, Space = 32, Exclaim = 33, DoubleQuote = 34, Hash = 35, Dollar = 36, Ampersand = 38, Quote = 39, LeftParen = 40, RightParen = 41, Asterisk = 42, Plus = 43, Comma = 44, Minus = 45, Period = 46, Slash = 47, K0 = 48, K1 = 49, K2 = 50, K3 = 51, K4 = 52, K5 = 53, K6 = 54, K7 = 55, K8 = 56, K9 = 57, Colon = 58, Semicolon = 59, Less = 60, Equals = 61, Greater = 62, Question = 63, At = 64, /* XXX: SDL decides to skip uppercase characters */ LeftBracket = 91, BackSlash = 92, RightBracket = 93, Caret = 94, Underscore = 95, Backquote = 96, A = 97, B = 98, C = 99, D = 100, E = 101, F = 102, G = 103, H = 104, I = 105, J = 106, K = 107, L = 108, M = 109, N = 110, O = 111, P = 112, Q = 113, R = 114, S = 115, T = 116, U = 117, V = 118, W = 119, X = 120, Y = 121, Z = 122, Delete = 127, /* International keyboard syms */ World0 = 160, /* 0xA0 */ World1 = 161, World2 = 162, World3 = 163, World4 = 164, World5 = 165, World6 = 166, World7 = 167, World8 = 168, World9 = 169, World10 = 170, World11 = 171, World12 = 172, World13 = 173, World14 = 174, World15 = 175, World16 = 176, World17 = 177, World18 = 178, World19 = 179, World20 = 180, World21 = 181, World22 = 182, World23 = 183, World24 = 184, World25 = 185, World26 = 186, World27 = 187, World28 = 188, World29 = 189, World30 = 190, World31 = 191, World32 = 192, World33 = 193, World34 = 194, World35 = 195, World36 = 196, World37 = 197, World38 = 198, World39 = 199, World40 = 200, World41 = 201, World42 = 202, World43 = 203, World44 = 204, World45 = 205, World46 = 206, World47 = 207, World48 = 208, World49 = 209, World50 = 210, World51 = 211, World52 = 212, World53 = 213, World54 = 214, World55 = 215, World56 = 216, World57 = 217, World58 = 218, World59 = 219, World60 = 220, World61 = 221, World62 = 222, World63 = 223, World64 = 224, World65 = 225, World66 = 226, World67 = 227, World68 = 228, World69 = 229, World70 = 230, World71 = 231, World72 = 232, World73 = 233, World74 = 234, World75 = 235, World76 = 236, World77 = 237, World78 = 238, World79 = 239, World80 = 240, World81 = 241, World82 = 242, World83 = 243, World84 = 244, World85 = 245, World86 = 246, World87 = 247, World88 = 248, World89 = 249, World90 = 250, World91 = 251, World92 = 252, World93 = 253, World94 = 254, World95 = 255, /* 0xFF */ /* Numeric keypad */ KP0 = 256, KP1 = 257, KP2 = 258, KP3 = 259, KP4 = 260, KP5 = 261, KP6 = 262, KP7 = 263, KP8 = 264, KP9 = 265, KPPeriod = 266, KPDivide = 267, KPMultiply = 268, KPMinus = 269, KPPlus = 270, KPEnter = 271, KPEquals = 272, /* Arrows + Home/End pad */ Up = 273, Down = 274, Right = 275, Left = 276, Insert = 277, Home = 278, End = 279, PageUp = 280, PageDown = 281, /* Function keys */ F1 = 282, F2 = 283, F3 = 284, F4 = 285, F5 = 286, F6 = 287, F7 = 288, F8 = 289, F9 = 290, F10 = 291, F11 = 292, F12 = 293, F13 = 294, F14 = 295, F15 = 296, /* Modifier keys */ NumLock = 300, CapsLock = 301, ScrollLock= 302, RightShift = 303, LeftShift = 304, RightCtrl = 305, LeftCtrl = 306, RightAlt = 307, LeftAlt = 308, RightMeta = 309, LeftMeta = 310, LeftSuper = 311, /* Left "Windows" key */ RightSuper = 312, /* Right "Windows" key */ Mode = 313, /* "Alt Gr" key */ Compose = 314, /* Multi-key compose key */ /* Miscellaneous function keys */ Help = 315, Print = 316, SysReq = 317, Break = 318, Menu = 319, Power = 320, /* Power Macintosh power key */ Euro = 321, /* Some european keyboards */ Undo = 322, /* Atari keyboard has Undo */ /* Add any other keys here */ Last } m_value; //BH : Removed KMod from main enum, because I don't have any idea about handling them correctly for now. /* //Enumeration of valid key mods (possibly OR'd together) KM_NONE = 0x0000, KM_LSHIFT = 0x0001, KM_RSHIFT = 0x0002, KM_LCTRL = 0x0040, KM_RCTRL = 0x0080, KM_LALT = 0x0100, KM_RALT = 0x0200, KM_LMETA = 0x0400, KM_RMETA = 0x0800, KM_NUM = 0x1000, KM_CAPS = 0x2000, KM_MODE = 0x4000, KM_RESERVED = 0x8000, //Left/Right independent key mods definition KM_CTRL = (KM_LCTRL|KM_RCTRL), KM_SHIFT = (KM_LSHIFT|KM_RSHIFT), KM_ALT = (KM_LALT|KM_RALT), KM_META = (KM_LMETA|KM_RMETA), */ inline Key(Value v) { m_value = v; } inline operator Value() { return m_value; } inline bool operator==(const Key& val) { return m_value == val.m_value; } }; struct ActionSetting { Action m_action; float m_buffering_time; float m_buffered_since; ActionSetting(Action NewAction) : m_action(NewAction), m_buffering_time(.0f), m_buffered_since(.0f) { } }; struct ButtonSetting { Key m_raw_button; Array m_associated_action_list; ButtonSetting(Key NewRawButton) : m_raw_button(NewRawButton) { } int GetActionSettingIdx(Action SearchAction); }; class InputTracker : public Entity { friend class Input; public: InputTracker(); private: Array m_input_status; Array m_input_assocation_list; int GetButtonSettingIdx(struct Key k); int GetCurrentButtonStatus(struct Key k); int GetPreviousButtonStatus(struct Key k); void UpdateActionStatus(float seconds); protected: virtual char const * GetName() { return ""; } virtual void TickGame(float seconds) { Entity::TickGame(seconds); UpdateActionStatus(seconds); } void LinkActionToKey(Action a, struct Key k); void UnlinkAction(Action a); int GetStatus(Action a); bool WasPressed(Action a); bool WasReleased(Action a); //You should probably use the Action System int GetStatus(Key k); bool WasPressed(Key k); bool WasReleased(Key k); }; class Input { private: static InputTracker* m_input_tracker; static bool CheckInputTrackerInit() { if (Input::m_input_tracker) return true; Input::m_input_tracker = new InputTracker(); return true; } public: /* These methods are general queries */ static ivec2 GetMousePos(); static ivec3 GetMouseButtons(); //BH : Shouldn't use this static int GetButtonState(int button); /* Action management */ static void LinkActionToKey(Action a, struct Key k); static void UnlinkAction(Action a); static int GetStatus(Action a); static bool WasPressed(Action a); static bool WasReleased(Action a); /* Raw Button management. You should use actions. */ static int GetStatus(Key k); static bool WasPressed(Key k); static bool WasReleased(Key k); /* Entities can subscribe to events */ static void TrackMouse(WorldEntity *e); static void UntrackMouse(WorldEntity *e); /* These methods are called by the underlying input listeners */ /* FIXME: this should disappear and be replaced by an input * system that abstracts mice */ static void SetMousePos(ivec2 coord); static void SetMouseButton(int index); static void UnsetMouseButton(int index); /* Keyboard handling */ static Keyboard *CreateKeyboard(); static void DestroyKeyboard(Keyboard *keyboard); static Keyboard *TrackKeyboard(int desired); static void UntrackKeyboard(Keyboard *keyboard); /* Joystick handling */ static Stick *CreateStick(); static void DestroyStick(Stick *stick); static Stick *TrackStick(int desired); static void UntrackStick(Stick *stick); }; } /* namespace lol */ #endif // __LOL_INPUT_INPUT_H__