| 1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
| 2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
| 3 | #pragma once |
| 4 | |
| 5 | #include "BsCorePrerequisites.h" |
| 6 | #include "Math/BsVector2I.h" |
| 7 | |
| 8 | namespace bs |
| 9 | { |
| 10 | // Undefine conflicting defines from other libs |
| 11 | #undef None |
| 12 | |
| 13 | /** @addtogroup Input |
| 14 | * @{ |
| 15 | */ |
| 16 | |
| 17 | /** |
| 18 | * Contains all possible input buttons, including keyboard scan codes, mouse buttons and gamepad buttons. |
| 19 | * |
| 20 | * @note |
| 21 | * These codes are only keyboard scan codes. This means that exact scan code identifier might not correspond to that |
| 22 | * exact character on user's keyboard, depending on user's input locale. Only for US locale will these scan code names |
| 23 | * match the actual keyboard input. Think of the US key code names as only a convenience for more easily identifying |
| 24 | * which location on the keyboard a scan code represents. |
| 25 | * @note |
| 26 | * When storing these sequentially make sure to only reference the low order 2 bytes. Two high order bytes are used for |
| 27 | * various flags. |
| 28 | */ |
| 29 | enum ButtonCode : UINT32 |
| 30 | { |
| 31 | BC_UNASSIGNED = 0x00, |
| 32 | BC_ESCAPE = 0x01, |
| 33 | BC_1 = 0x02, |
| 34 | BC_2 = 0x03, |
| 35 | BC_3 = 0x04, |
| 36 | BC_4 = 0x05, |
| 37 | BC_5 = 0x06, |
| 38 | BC_6 = 0x07, |
| 39 | BC_7 = 0x08, |
| 40 | BC_8 = 0x09, |
| 41 | BC_9 = 0x0A, |
| 42 | BC_0 = 0x0B, |
| 43 | BC_MINUS = 0x0C, // - on main keyboard |
| 44 | BC_EQUALS = 0x0D, |
| 45 | BC_BACK = 0x0E, // backspace |
| 46 | BC_TAB = 0x0F, |
| 47 | BC_Q = 0x10, |
| 48 | BC_W = 0x11, |
| 49 | BC_E = 0x12, |
| 50 | BC_R = 0x13, |
| 51 | BC_T = 0x14, |
| 52 | BC_Y = 0x15, |
| 53 | BC_U = 0x16, |
| 54 | BC_I = 0x17, |
| 55 | BC_O = 0x18, |
| 56 | BC_P = 0x19, |
| 57 | BC_LBRACKET = 0x1A, |
| 58 | BC_RBRACKET = 0x1B, |
| 59 | BC_RETURN = 0x1C, // Enter on main keyboard |
| 60 | BC_LCONTROL = 0x1D, |
| 61 | BC_A = 0x1E, |
| 62 | BC_S = 0x1F, |
| 63 | BC_D = 0x20, |
| 64 | BC_F = 0x21, |
| 65 | BC_G = 0x22, |
| 66 | BC_H = 0x23, |
| 67 | BC_J = 0x24, |
| 68 | BC_K = 0x25, |
| 69 | BC_L = 0x26, |
| 70 | BC_SEMICOLON = 0x27, |
| 71 | BC_APOSTROPHE = 0x28, |
| 72 | BC_GRAVE = 0x29, // accent |
| 73 | BC_LSHIFT = 0x2A, |
| 74 | BC_BACKSLASH = 0x2B, |
| 75 | BC_Z = 0x2C, |
| 76 | BC_X = 0x2D, |
| 77 | BC_C = 0x2E, |
| 78 | BC_V = 0x2F, |
| 79 | BC_B = 0x30, |
| 80 | BC_N = 0x31, |
| 81 | BC_M = 0x32, |
| 82 | BC_COMMA = 0x33, |
| 83 | BC_PERIOD = 0x34, // . on main keyboard |
| 84 | BC_SLASH = 0x35, // / on main keyboard |
| 85 | BC_RSHIFT = 0x36, |
| 86 | BC_MULTIPLY = 0x37, // * on numeric keypad |
| 87 | = 0x38, // left Alt |
| 88 | BC_SPACE = 0x39, |
| 89 | BC_CAPITAL = 0x3A, |
| 90 | BC_F1 = 0x3B, |
| 91 | BC_F2 = 0x3C, |
| 92 | BC_F3 = 0x3D, |
| 93 | BC_F4 = 0x3E, |
| 94 | BC_F5 = 0x3F, |
| 95 | BC_F6 = 0x40, |
| 96 | BC_F7 = 0x41, |
| 97 | BC_F8 = 0x42, |
| 98 | BC_F9 = 0x43, |
| 99 | BC_F10 = 0x44, |
| 100 | BC_NUMLOCK = 0x45, |
| 101 | BC_SCROLL = 0x46, // Scroll Lock |
| 102 | BC_NUMPAD7 = 0x47, |
| 103 | BC_NUMPAD8 = 0x48, |
| 104 | BC_NUMPAD9 = 0x49, |
| 105 | BC_SUBTRACT = 0x4A, // - on numeric keypad |
| 106 | BC_NUMPAD4 = 0x4B, |
| 107 | BC_NUMPAD5 = 0x4C, |
| 108 | BC_NUMPAD6 = 0x4D, |
| 109 | BC_ADD = 0x4E, // + on numeric keypad |
| 110 | BC_NUMPAD1 = 0x4F, |
| 111 | BC_NUMPAD2 = 0x50, |
| 112 | BC_NUMPAD3 = 0x51, |
| 113 | BC_NUMPAD0 = 0x52, |
| 114 | BC_DECIMAL = 0x53, // . on numeric keypad |
| 115 | BC_OEM_102 = 0x56, // < > | on UK/Germany keyboards |
| 116 | BC_F11 = 0x57, |
| 117 | BC_F12 = 0x58, |
| 118 | BC_F13 = 0x64, // (NEC PC98) |
| 119 | BC_F14 = 0x65, // (NEC PC98) |
| 120 | BC_F15 = 0x66, // (NEC PC98) |
| 121 | BC_KANA = 0x70, // (Japanese keyboard) |
| 122 | BC_ABNT_C1 = 0x73, // / ? on Portugese (Brazilian) keyboards |
| 123 | BC_CONVERT = 0x79, // (Japanese keyboard) |
| 124 | BC_NOCONVERT = 0x7B, // (Japanese keyboard) |
| 125 | BC_YEN = 0x7D, // (Japanese keyboard) |
| 126 | BC_ABNT_C2 = 0x7E, // Numpad . on Portugese (Brazilian) keyboards |
| 127 | BC_NUMPADEQUALS= 0x8D, // = on numeric keypad (NEC PC98) |
| 128 | BC_PREVTRACK = 0x90, // Previous Track (BC_CIRCUMFLEX on Japanese keyboard) |
| 129 | BC_AT = 0x91, // (NEC PC98) |
| 130 | BC_COLON = 0x92, // (NEC PC98) |
| 131 | BC_UNDERLINE = 0x93, // (NEC PC98) |
| 132 | BC_KANJI = 0x94, // (Japanese keyboard) |
| 133 | BC_STOP = 0x95, // (NEC PC98) |
| 134 | BC_AX = 0x96, // (Japan AX) |
| 135 | BC_UNLABELED = 0x97, // (J3100) |
| 136 | BC_NEXTTRACK = 0x99, // Next Track |
| 137 | BC_NUMPADENTER = 0x9C, // Enter on numeric keypad |
| 138 | BC_RCONTROL = 0x9D, |
| 139 | BC_MUTE = 0xA0, // Mute |
| 140 | BC_CALCULATOR = 0xA1, // Calculator |
| 141 | BC_PLAYPAUSE = 0xA2, // Play / Pause |
| 142 | BC_MEDIASTOP = 0xA4, // Media Stop |
| 143 | BC_VOLUMEDOWN = 0xAE, // Volume - |
| 144 | BC_VOLUMEUP = 0xB0, // Volume + |
| 145 | BC_WEBHOME = 0xB2, // Web home |
| 146 | BC_NUMPADCOMMA = 0xB3, // , on numeric keypad (NEC PC98) |
| 147 | BC_DIVIDE = 0xB5, // / on numeric keypad |
| 148 | BC_SYSRQ = 0xB7, |
| 149 | = 0xB8, // right Alt |
| 150 | BC_PAUSE = 0xC5, // Pause |
| 151 | BC_HOME = 0xC7, // Home on arrow keypad |
| 152 | BC_UP = 0xC8, // UpArrow on arrow keypad |
| 153 | BC_PGUP = 0xC9, // PgUp on arrow keypad |
| 154 | BC_LEFT = 0xCB, // LeftArrow on arrow keypad |
| 155 | BC_RIGHT = 0xCD, // RightArrow on arrow keypad |
| 156 | BC_END = 0xCF, // End on arrow keypad |
| 157 | BC_DOWN = 0xD0, // DownArrow on arrow keypad |
| 158 | BC_PGDOWN = 0xD1, // PgDn on arrow keypad |
| 159 | BC_INSERT = 0xD2, // Insert on arrow keypad |
| 160 | BC_DELETE = 0xD3, // Delete on arrow keypad |
| 161 | BC_LWIN = 0xDB, // Left Windows key |
| 162 | BC_RWIN = 0xDC, // Right Windows key |
| 163 | BC_APPS = 0xDD, // AppMenu key |
| 164 | BC_POWER = 0xDE, // System Power |
| 165 | BC_SLEEP = 0xDF, // System Sleep |
| 166 | BC_WAKE = 0xE3, // System Wake |
| 167 | BC_WEBSEARCH = 0xE5, // Web Search |
| 168 | BC_WEBFAVORITES= 0xE6, // Web Favorites |
| 169 | BC_WEBREFRESH = 0xE7, // Web Refresh |
| 170 | BC_WEBSTOP = 0xE8, // Web Stop |
| 171 | BC_WEBFORWARD = 0xE9, // Web Forward |
| 172 | BC_WEBBACK = 0xEA, // Web Back |
| 173 | BC_MYCOMPUTER = 0xEB, // My Computer |
| 174 | BC_MAIL = 0xEC, // Mail |
| 175 | BC_MEDIASELECT = 0xED, // Media Select |
| 176 | BC_MOUSE_LEFT = 0x800000EE, // Mouse buttons - Most important bit signifies this key is a mouse button |
| 177 | BC_MOUSE_RIGHT, |
| 178 | BC_MOUSE_MIDDLE, |
| 179 | BC_MOUSE_BTN4, |
| 180 | BC_MOUSE_BTN5, |
| 181 | BC_MOUSE_BTN6, |
| 182 | BC_MOUSE_BTN7, |
| 183 | BC_MOUSE_BTN8, |
| 184 | BC_MOUSE_BTN9, |
| 185 | BC_MOUSE_BTN10, |
| 186 | BC_MOUSE_BTN11, |
| 187 | BC_MOUSE_BTN12, |
| 188 | BC_MOUSE_BTN13, |
| 189 | BC_MOUSE_BTN14, |
| 190 | BC_MOUSE_BTN15, |
| 191 | BC_MOUSE_BTN16, |
| 192 | BC_MOUSE_BTN17, |
| 193 | BC_MOUSE_BTN18, |
| 194 | BC_MOUSE_BTN19, |
| 195 | BC_MOUSE_BTN20, |
| 196 | BC_MOUSE_BTN21, |
| 197 | BC_MOUSE_BTN22, |
| 198 | BC_MOUSE_BTN23, |
| 199 | BC_MOUSE_BTN24, |
| 200 | BC_MOUSE_BTN25, |
| 201 | BC_MOUSE_BTN26, |
| 202 | BC_MOUSE_BTN27, |
| 203 | BC_MOUSE_BTN28, |
| 204 | BC_MOUSE_BTN29, |
| 205 | BC_MOUSE_BTN30, |
| 206 | BC_MOUSE_BTN31, |
| 207 | BC_MOUSE_BTN32, |
| 208 | BC_GAMEPAD_A = 0x4000010F, // Joystick/Gamepad buttons- Second most important bit signifies key is a gamepad button |
| 209 | BC_GAMEPAD_B, // Similar to keyboard names, these are for convenience named after Xbox controller buttons |
| 210 | BC_GAMEPAD_X, // but if some other controller is connected you will need to learn yourself which of these |
| 211 | BC_GAMEPAD_Y, // corresponds to which actual button on the controller. |
| 212 | BC_GAMEPAD_LB, |
| 213 | BC_GAMEPAD_RB, |
| 214 | BC_GAMEPAD_LS, |
| 215 | BC_GAMEPAD_RS, |
| 216 | BC_GAMEPAD_BACK, |
| 217 | BC_GAMEPAD_START, |
| 218 | BC_GAMEPAD_DPAD_LEFT, |
| 219 | BC_GAMEPAD_DPAD_RIGHT, |
| 220 | BC_GAMEPAD_DPAD_UP, |
| 221 | BC_GAMEPAD_DPAD_DOWN, |
| 222 | BC_GAMEPAD_BTN1, |
| 223 | BC_GAMEPAD_BTN2, |
| 224 | BC_GAMEPAD_BTN3, |
| 225 | BC_GAMEPAD_BTN4, |
| 226 | BC_GAMEPAD_BTN5, |
| 227 | BC_GAMEPAD_BTN6, |
| 228 | BC_GAMEPAD_BTN7, |
| 229 | BC_GAMEPAD_BTN8, |
| 230 | BC_GAMEPAD_BTN9, |
| 231 | BC_GAMEPAD_BTN10, |
| 232 | BC_GAMEPAD_BTN11, |
| 233 | BC_GAMEPAD_BTN12, |
| 234 | BC_GAMEPAD_BTN13, |
| 235 | BC_GAMEPAD_BTN14, |
| 236 | BC_GAMEPAD_BTN15, |
| 237 | BC_GAMEPAD_BTN16, |
| 238 | BC_GAMEPAD_BTN17, |
| 239 | BC_GAMEPAD_BTN18, |
| 240 | BC_GAMEPAD_BTN19, |
| 241 | BC_GAMEPAD_BTN20, |
| 242 | BC_GAMEPAD_DPAD_UPLEFT, |
| 243 | BC_GAMEPAD_DPAD_UPRIGHT, |
| 244 | BC_GAMEPAD_DPAD_DOWNLEFT, |
| 245 | BC_GAMEPAD_DPAD_DOWNRIGHT, |
| 246 | BC_NumKeys = BC_MEDIASELECT - BC_UNASSIGNED + 1, // IMPORTANT: Make sure to update these if you modify the values above |
| 247 | BC_NumMouse = BC_MOUSE_BTN32 - BC_MOUSE_LEFT + 1, |
| 248 | BC_NumGamepad = BC_GAMEPAD_DPAD_DOWNRIGHT - BC_GAMEPAD_A + 1, |
| 249 | BC_Count = BC_NumKeys + BC_NumMouse + BC_NumGamepad, |
| 250 | }; |
| 251 | |
| 252 | /** Contains data about a button input event. */ |
| 253 | struct ButtonEvent |
| 254 | { |
| 255 | public: |
| 256 | ButtonEvent() |
| 257 | :mIsUsed(false) |
| 258 | { } |
| 259 | |
| 260 | ButtonCode buttonCode; /**< Button code this event is referring to. */ |
| 261 | UINT64 timestamp; /**< Timestamp in ticks when the event happened. */ |
| 262 | UINT32 deviceIdx; /**< Index of the device that the event originated from. */ |
| 263 | |
| 264 | /** Query is the pressed button a keyboard button. */ |
| 265 | bool isKeyboard() const { return (buttonCode & 0xC0000000) == 0; } |
| 266 | |
| 267 | /** Query is the pressed button a mouse button. */ |
| 268 | bool isMouse() const { return (buttonCode & 0x80000000) != 0; } |
| 269 | |
| 270 | /** Query is the pressed button a gamepad button. */ |
| 271 | bool isGamepad() const { return (buttonCode & 0x40000000) != 0; } |
| 272 | |
| 273 | /** |
| 274 | * Check if the event has been marked as used. Internally this means nothing but caller might choose to ignore an |
| 275 | * used event. |
| 276 | */ |
| 277 | bool isUsed() const { return mIsUsed; } |
| 278 | |
| 279 | /** Mark the event as used. Internally this means nothing but caller might choose to ignore an used event. */ |
| 280 | void markAsUsed() const { mIsUsed = true; } |
| 281 | private: |
| 282 | mutable bool mIsUsed; |
| 283 | }; |
| 284 | |
| 285 | /** |
| 286 | * Pointer buttons. Generally these correspond to mouse buttons, but may be used in some form for touch input as well. |
| 287 | */ |
| 288 | enum class PointerEventButton |
| 289 | { |
| 290 | Left, Middle, Right, Count |
| 291 | }; |
| 292 | |
| 293 | /** Type of pointer event.*/ |
| 294 | enum class PointerEventType |
| 295 | { |
| 296 | CursorMoved, |
| 297 | ButtonPressed, |
| 298 | ButtonReleased, |
| 299 | DoubleClick |
| 300 | }; |
| 301 | |
| 302 | /** |
| 303 | * Event that gets sent out when user interacts with the screen in some way, usually by moving the mouse cursor or |
| 304 | * using touch input. |
| 305 | */ |
| 306 | struct PointerEvent |
| 307 | { |
| 308 | public: |
| 309 | PointerEvent() |
| 310 | : button(PointerEventButton::Left), type(PointerEventType::CursorMoved), shift(false) |
| 311 | , control(false), alt(false), mouseWheelScrollAmount(0.0f), mIsUsed(false) |
| 312 | { |
| 313 | buttonStates[0] = false; |
| 314 | buttonStates[1] = false; |
| 315 | buttonStates[2] = false; |
| 316 | } |
| 317 | |
| 318 | Vector2I screenPos; /**< Screen position where the input event occurred. */ |
| 319 | Vector2I delta; /**< Change in movement since last sent event. */ |
| 320 | /** States of the pointer buttons (for example mouse buttons). */ |
| 321 | bool buttonStates[(UINT32)PointerEventButton::Count]; |
| 322 | /** |
| 323 | * Button that triggered the pointer event. Might be irrelevant depending on event type. (for example move events |
| 324 | * don't correspond to a button. |
| 325 | */ |
| 326 | PointerEventButton button; |
| 327 | PointerEventType type; /**< Type of the pointer event. */ |
| 328 | |
| 329 | bool shift; /**< Is shift button on the keyboard being held down. */ |
| 330 | bool control; /**< Is control button on the keyboard being held down. */ |
| 331 | bool alt; /**< Is alt button on the keyboard being held down. */ |
| 332 | |
| 333 | /** If mouse wheel is being scrolled, what is the amount. Only relevant for move events. */ |
| 334 | float mouseWheelScrollAmount; |
| 335 | |
| 336 | /** |
| 337 | * Check if the event has been marked as used. Internally this means nothing but caller might choose to ignore an |
| 338 | * used event. |
| 339 | */ |
| 340 | bool isUsed() const { return mIsUsed; } |
| 341 | |
| 342 | /** Mark the event as used. Internally this means nothing but caller might choose to ignore an used event. */ |
| 343 | void markAsUsed() const { mIsUsed = true; } |
| 344 | |
| 345 | private: |
| 346 | mutable bool mIsUsed; |
| 347 | }; |
| 348 | |
| 349 | /** Types of special input commands. */ |
| 350 | enum class InputCommandType |
| 351 | { |
| 352 | CursorMoveLeft, CursorMoveRight, CursorMoveUp, CursorMoveDown, |
| 353 | SelectLeft, SelectRight, SelectUp, SelectDown, |
| 354 | Escape, Delete, Backspace, Return, Confirm, Tab |
| 355 | }; |
| 356 | |
| 357 | /** |
| 358 | * Event that gets sent out when user inputs some text. These events may be preceeded by normal button events if user |
| 359 | * is typing on a keyboard. |
| 360 | */ |
| 361 | struct TextInputEvent |
| 362 | { |
| 363 | public: |
| 364 | TextInputEvent() |
| 365 | :mIsUsed(false) |
| 366 | { } |
| 367 | |
| 368 | UINT32 textChar; /**< Character the that was input. */ |
| 369 | |
| 370 | /** |
| 371 | * Check if the event has been marked as used. Internally this means nothing but caller might choose to ignore an |
| 372 | * used event. |
| 373 | */ |
| 374 | bool isUsed() const { return mIsUsed; } |
| 375 | |
| 376 | /** Mark the event as used. Internally this means nothing but caller might choose to ignore an used event. */ |
| 377 | void markAsUsed() const { mIsUsed = true; } |
| 378 | |
| 379 | private: |
| 380 | mutable bool mIsUsed; |
| 381 | }; |
| 382 | |
| 383 | /** Types of input devices. */ |
| 384 | enum class InputDevice |
| 385 | { |
| 386 | Keyboard, |
| 387 | Mouse, |
| 388 | Gamepad, |
| 389 | Count // Keep at end |
| 390 | }; |
| 391 | |
| 392 | /** Common input axis types. */ |
| 393 | enum class InputAxis |
| 394 | { |
| 395 | MouseX, /**< Mouse axis X. Provides unnormalized relative movement. */ |
| 396 | MouseY, /**< Mouse axis Y. Provides unnormalized relative movement. */ |
| 397 | MouseZ, /**< Mouse wheel/scroll axis. Provides unnormalized relative movement. */ |
| 398 | LeftStickX, /**< Gamepad left stick X. Provides normalized ([-1, 1] range) absolute position. */ |
| 399 | LeftStickY, /**< Gamepad left stick Y. Provides normalized ([-1, 1] range) absolute position. */ |
| 400 | RightStickX, /**< Gamepad right stick X. Provides normalized ([-1, 1] range) absolute position.*/ |
| 401 | RightStickY, /**< Gamepad right stick Y. Provides normalized ([-1, 1] range) absolute position. */ |
| 402 | LeftTrigger, /**< Gamepad left trigger. Provides normalized ([-1, 1] range) absolute position. */ |
| 403 | RightTrigger, /**< Gamepad right trigger. Provides normalized ([-1, 1] range) absolute position. */ |
| 404 | Count // Keep at end |
| 405 | }; |
| 406 | |
| 407 | /** Modifiers used with along with keyboard buttons. */ |
| 408 | enum class ButtonModifier |
| 409 | { |
| 410 | None = 0x00, |
| 411 | Shift = 0x01, |
| 412 | Ctrl = 0x02, |
| 413 | Alt = 0x04, |
| 414 | ShiftCtrl = 0x03, |
| 415 | CtrlAlt = 0x06, |
| 416 | ShiftAlt = 0x05, |
| 417 | ShiftCtrlAlt = 0x07 |
| 418 | }; |
| 419 | |
| 420 | /** @} */ |
| 421 | } |