013 Ввод
Для ввода надо иметь информацию о состоянии мыши и клавиатуры. Нужно сунуть всё это в структуру. Данная структура так-же будет использоваться в GUI.
Добавлю файл
inc/badcoiq/[b]input[/b]/bqInput.h
Структура
struct bqInputData
{
// Позиция курсора
bqPointf m_mousePosition;
// старая позиция курсора. для вычисления m_mouseMoveDelta
bqPointf m_mousePositionOld;
// На сколько переместился курсор
bqPointf m_mouseMoveDelta;
// На сколько покрутили колесо мыши
float m_mouseWheelDelta = 0.f;
// Флаги для мышки
uint32_t m_mouseButtonFlags = 0;
// При вводе символа он сохраняется сюда
char32_t m_character = 0;
// состояния для кнопок клаиатуры
uint64_t m_keyFlagsHit[2] = { 0,0 };
uint64_t m_keyFlagsHold[2] = { 0,0 };
uint64_t m_keyFlagsRelease[2] = { 0,0 };
// Модификаторы клавиатуры (моя терминология)
uint8_t m_keyboardModifier = 0;
};
Состояния хранятся в виде флагов. Я бы добавил все эти флаги сюда, но, возникла идея для оптимизации. Для клавиатуры я использую всего несколько uint64_t. Каждый кадр необходимо занулять Hit и Release. Проще сделать что-то типа
m_keyFlagsHit[0] = 0;
m_keyFlagsHit[1] = 0;
m_keyFlagsRelease[0] = 0;
m_keyFlagsRelease[1] = 0;
Все используемые кнопки влезают в 128 бит.
Надо начать объяснение с простого. У каждой клавиши есть свой код.
// keyboard button code
enum : uint32_t {
KEY_NONE = 0,
KEY_BACKSPACE = 8,
KEY_TAB = 9,
KEY_ENTER = 13,
KEY_SHIFT = 16,
KEY_CTRL = 17,
KEY_ALT = 18,
и т.д.
Когда надо проверить, было ли нажатие (например Hit, первое нажатие), то, надо взять бит для нажатой кнопки из m_keyFlagsHit. Для этого есть маски
// masks
enum : uint64_t {
KBIT_NONE = 0,
KBIT_BACKSPACE = 0x1,
KBIT_TAB = 0x2,
KBIT_ENTER = 0x4,
KBIT_SHIFT = 0x8,
KBIT_CTRL = 0x10,
KBIT_ALT = 0x20,
KBIT_PAUSE = 0x40,
KBIT_CAPS_LOCK = 0x80,
KBIT_ESCAPE = 0x100,
KBIT_SPACE = 0x200,
KBIT_PGUP = 0x400,
KBIT_PGDOWN = 0x800,
Напрмер, нажимаем Enter. Код клавиши 13. В m_keyFlagsHit[0] эта клавиша находится на третьей позиции
(00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000100)
Как быстро получить эту маску? Нужен массив, который будет хранить маски.
static const uint64_t g_keyToBin[] =
{
0, //KEY_NONE = 0,
0, 0, 0, 0, 0, 0, 0,
KBIT_BACKSPACE, //KEY_BACKSPACE = 8,
KBIT_TAB, //KEY_TAB = 9,
0, 0, 0,
KBIT_ENTER, //KEY_ENTER = 13,
0, 0,
KBIT_SHIFT, //KEY_SHIFT = 16,
g_keyToBin[13]
даст значение KBIT_ENTER
Третий бит
(00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000100)
Если бит установлен для m_keyFlagsHit, то это означает что кнопка была нажата. Сигнал будет только один раз, так как m_keyFlagsHit обнулится. Если бит установлен для m_keyFlagsRelease, то это означает что кнопка была отжата. Так-же, сигнал будет только один раз, так как m_keyFlagsRelease обнулится. Если бит установлен для m_keyFlagsHold, то это значит что кнопка удерживается в зажатом положении.
Для удобства использования необходимо создать класс, который будет делать всё за нас.
// Класс с помощью которого можно узнать о состоянии клавиатуры и мышки
class bqInput
{
public:
static bqInputData* GetData();
static bqPointf& GetMousePosition();
static void SetKeyHit(uint32_t, bool);
static void SetKeyHold(uint32_t, bool);
static void SetKeyRelease(uint32_t, bool);
static bool IsKeyHit(uint32_t);
static bool IsKeyHold(uint32_t);
static bool IsKeyRelease(uint32_t);
static void EnableLMBDown();
static void EnableLMBHold();
static void EnableLMBUp();
static void EnableRMBDown();
static void EnableRMBHold();
static void EnableRMBUp();
static void EnableMMBDown();
static void EnableMMBHold();
static void EnableMMBUp();
static void EnableX1MBDown();
static void EnableX1MBHold();
static void EnableX1MBUp();
static void EnableX2MBDown();
static void EnableX2MBHold();
static void EnableX2MBUp();
static void DisableLMBDown();
static void DisableLMBHold();
static void DisableLMBUp();
static void DisableRMBDown();
static void DisableRMBHold();
static void DisableRMBUp();
static void DisableMMBDown();
static void DisableMMBHold();
static void DisableMMBUp();
static void DisableX1MBDown();
static void DisableX1MBHold();
static void DisableX1MBUp();
static void DisableX2MBDown();
static void DisableX2MBHold();
static void DisableX2MBUp();
static bool IsLMBHit();
static bool IsLMBHold();
static bool IsLMBRelease();
static bool IsRMBHit();
static bool IsRMBHold();
static bool IsRMBRelease();
static bool IsMMBHit();
static bool IsMMBHold();
static bool IsMMBRelease();
static bool IsX1MBHit();
static bool IsX1MBHold();
static bool IsX1MBRelease();
static bool IsX2MBHit();
static bool IsX2MBHold();
static bool IsX2MBRelease();
static const uint64_t* GetKeyToBin();
// keyboard button code
enum : uint32_t {
KEY_NONE = 0,
KEY_BACKSPACE = 8,
KEY_TAB = 9,
KEY_ENTER = 13,
KEY_SHIFT = 16,
KEY_CTRL = 17,
KEY_ALT = 18,
KEY_PAUSE = 19,
KEY_CAPS_LOCK = 20,
KEY_ESCAPE = 27,
KEY_SPACE = 32,
KEY_PGUP = 33,
KEY_PGDOWN = 34,
KEY_END = 35,
KEY_HOME = 36,
KEY_LEFT = 37,
KEY_UP = 38,
KEY_RIGHT = 39,
KEY_DOWN = 40,
KEY_PRTSCR = 44,
KEY_INSERT = 45,
KEY_DELETE = 46,
KEY_0 = 48,
KEY_1 = 49,
KEY_2 = 50,
KEY_3 = 51,
KEY_4 = 52,
KEY_5 = 53,
KEY_6 = 54,
KEY_7 = 55,
KEY_8 = 56,
KEY_9 = 57,
KEY_A = 65,
KEY_B = 66,
KEY_C = 67,
KEY_D = 68,
KEY_E = 69,
KEY_F = 70,
KEY_G = 71,
KEY_H = 72,
KEY_I = 73,
KEY_J = 74,
KEY_K = 75,
KEY_L = 76,
KEY_M = 77,
KEY_N = 78,
KEY_O = 79,
KEY_P = 80,
KEY_Q = 81,
KEY_R = 82,
KEY_S = 83,
KEY_T = 84,
KEY_U = 85,
KEY_V = 86,
KEY_W = 87,
KEY_X = 88,
KEY_Y = 89,
KEY_Z = 90,
KEY_WIN = 91,
KEY_CONTEXT = 93,
KEY_NUM_0 = 96,
KEY_NUM_1 = 97,
KEY_NUM_2 = 98,
KEY_NUM_3 = 99,
KEY_NUM_4 = 100,
KEY_NUM_5 = 101,
KEY_NUM_6 = 102,
KEY_NUM_7 = 103,
KEY_NUM_8 = 104,
KEY_NUM_9 = 105,
KEY_NUM_MUL = 106, // *
KEY_NUM_ADD = 107, // +
KEY_NUM_SUB = 109, // -
KEY_NUM_DOT = 110, // .
KEY_NUM_SLASH = 111, // /
KEY_F1 = 112,
KEY_F2 = 113,
KEY_F3 = 114,
KEY_F4 = 115,
KEY_F5 = 116,
KEY_F6 = 117,
KEY_F7 = 118,
KEY_F8 = 119,
KEY_F9 = 120,
KEY_F10 = 121,
KEY_F11 = 122,
KEY_F12 = 123,
KEY_NUM_LOCK = 144,
KEY_SCROLL_LOCK = 145,
KEY_LSHIFT = 160,
KEY_RSHIFT = 161,
KEY_LCTRL = 162,
KEY_RCTRL = 163,
KEY_LALT = 164,
KEY_RALT = 165,
KEY_FUNC_MY_COMP = 182, // Function key. open My computer
KEY_FUNC_CALC = 183, // Function key. open Calculator
KEY_COLON = 186, //;:
KEY_ADD = 187, //=+
KEY_COMMA = 188, //,<
KEY_SUB = 189, //-_
KEY_DOT = 190, //.>
KEY_SLASH = 191, // /?
KEY_TILDE = 192, //`~
KEY_FIGURE_OPEN = 219, //[{
KEY_BACKSLASH = 220, //\|
KEY_FIGURE_CLOSE = 221, //]}
KEY_QUOTE = 222, //'"
KEY_end__,
};
};
Коды клавиш так-же будут находится внутри класса.
Суну флаги в отдельный файл, так как может появиться желание использовать флаги напрямую.
inc/badcoiq/[b]input[/b]/bqInputEx.h
#include "badcoiq/input/bqInput.h"
namespace bq
{
// для m_mouseButtonFlags
enum
{
MouseFlag_LMBDOWN = 0x1,
MouseFlag_LMBUP = 0x2,
MouseFlag_RMBDOWN = 0x4,
MouseFlag_RMBUP = 0x8,
MouseFlag_MMBDOWN = 0x10,
MouseFlag_MMBUP = 0x20,
MouseFlag_X1MBDOWN = 0x40,
MouseFlag_X1MBUP = 0x80,
MouseFlag_X2MBDOWN = 0x100,
MouseFlag_X2MBUP = 0x200,
MouseFlag_LMBHOLD = 0x400,
MouseFlag_RMBHOLD = 0x800,
MouseFlag_MMBHOLD = 0x1000,
MouseFlag_X1MBHOLD = 0x2000,
MouseFlag_X2MBHOLD = 0x4000,
};
// для m_keyboardModifier
enum
{
KeyboardMod_Clear = 0,
KeyboardMod_Ctrl,
KeyboardMod_Shift,
KeyboardMod_Alt,
KeyboardMod_CtrlShift,
KeyboardMod_CtrlAlt,
KeyboardMod_ShiftAlt,
KeyboardMod_CtrlShiftAlt,
};
// Маски для получения бита
enum : uint64_t
{
KeyboardBitMask_NONE = 0,
KeyboardBitMask_BACKSPACE = 0x1,
KeyboardBitMask_TAB = 0x2,
KeyboardBitMask_ENTER = 0x4,
KeyboardBitMask_SHIFT = 0x8,
KeyboardBitMask_CTRL = 0x10,
KeyboardBitMask_ALT = 0x20,
KeyboardBitMask_PAUSE = 0x40,
KeyboardBitMask_CAPS_LOCK = 0x80,
KeyboardBitMask_ESCAPE = 0x100,
KeyboardBitMask_SPACE = 0x200,
KeyboardBitMask_PGUP = 0x400,
KeyboardBitMask_PGDOWN = 0x800,
KeyboardBitMask_END = 0x1000,
KeyboardBitMask_HOME = 0x2000,
KeyboardBitMask_LEFT = 0x4000,
KeyboardBitMask_UP = 0x8000,
KeyboardBitMask_RIGHT = 0x10000,
KeyboardBitMask_DOWN = 0x20000,
KeyboardBitMask_PRTSCR = 0x40000,
KeyboardBitMask_INSERT = 0x80000,
KeyboardBitMask_DELETE = 0x100000,
KeyboardBitMask_0 = 0x200000,
KeyboardBitMask_1 = 0x400000,
KeyboardBitMask_2 = 0x800000,
KeyboardBitMask_3 = 0x1000000,
KeyboardBitMask_4 = 0x2000000,
KeyboardBitMask_5 = 0x4000000,
KeyboardBitMask_6 = 0x8000000,
KeyboardBitMask_7 = 0x10000000,
KeyboardBitMask_8 = 0x20000000,
KeyboardBitMask_9 = 0x40000000,
KeyboardBitMask_A = 0x80000000,
KeyboardBitMask_B = 0x100000000,
KeyboardBitMask_C = 0x200000000,
KeyboardBitMask_D = 0x400000000,
KeyboardBitMask_E = 0x800000000,
KeyboardBitMask_F = 0x1000000000,
KeyboardBitMask_G = 0x2000000000,
KeyboardBitMask_H = 0x4000000000,
KeyboardBitMask_I = 0x8000000000,
KeyboardBitMask_J = 0x10000000000,
KeyboardBitMask_K = 0x20000000000,
KeyboardBitMask_L = 0x40000000000,
KeyboardBitMask_M = 0x80000000000,
KeyboardBitMask_N = 0x100000000000,
KeyboardBitMask_O = 0x200000000000,
KeyboardBitMask_P = 0x400000000000,
KeyboardBitMask_Q = 0x800000000000,
KeyboardBitMask_R = 0x1000000000000,
KeyboardBitMask_S = 0x2000000000000,
KeyboardBitMask_T = 0x4000000000000,
KeyboardBitMask_U = 0x8000000000000,
KeyboardBitMask_V = 0x10000000000000,
KeyboardBitMask_W = 0x20000000000000,
KeyboardBitMask_X = 0x40000000000000,
KeyboardBitMask_Y = 0x80000000000000,
KeyboardBitMask_Z = 0x100000000000000,
KeyboardBitMask_WIN = 0x200000000000000,
KeyboardBitMask_CONTEXT = 0x400000000000000,
KeyboardBitMask_NUM_0 = 0x800000000000000,
KeyboardBitMask_NUM_1 = 0x1,
KeyboardBitMask_NUM_2 = 0x2,
KeyboardBitMask_NUM_3 = 0x4,
KeyboardBitMask_NUM_4 = 0x8,
KeyboardBitMask_NUM_5 = 0x10,
KeyboardBitMask_NUM_6 = 0x20,
KeyboardBitMask_NUM_7 = 0x40,
KeyboardBitMask_NUM_8 = 0x80,
KeyboardBitMask_NUM_9 = 0x100,
KeyboardBitMask_NUM_MUL = 0x200, // *
KeyboardBitMask_NUM_ADD = 0x400, // +
KeyboardBitMask_NUM_SUB = 0x800, // -
KeyboardBitMask_NUM_DOT = 0x1000, // .
KeyboardBitMask_NUM_SLASH = 0x2000, // /
KeyboardBitMask_F1 = 0x4000,
KeyboardBitMask_F2 = 0x8000,
KeyboardBitMask_F3 = 0x10000,
KeyboardBitMask_F4 = 0x20000,
KeyboardBitMask_F5 = 0x40000,
KeyboardBitMask_F6 = 0x80000,
KeyboardBitMask_F7 = 0x100000,
KeyboardBitMask_F8 = 0x200000,
KeyboardBitMask_F9 = 0x400000,
KeyboardBitMask_F10 = 0x800000,
KeyboardBitMask_F11 = 0x1000000,
KeyboardBitMask_F12 = 0x2000000,
KeyboardBitMask_NUM_LOCK = 0x4000000,
KeyboardBitMask_SCROLL_LOCK = 0x8000000,
KeyboardBitMask_LSHIFT = 0x10000000,
KeyboardBitMask_RSHIFT = 0x20000000,
KeyboardBitMask_LCTRL = 0x40000000,
KeyboardBitMask_RCTRL = 0x80000000,
KeyboardBitMask_LALT = 0x100000000,
KeyboardBitMask_RALT = 0x200000000,
KeyboardBitMask_FUNC_MY_COMP = 0x400000000, // Function key. open My computer
KeyboardBitMask_FUNC_CALC = 0x800000000, // Function key. open Calculator
KeyboardBitMask_COLON = 0x1000000000, //;:
KeyboardBitMask_ADD = 0x2000000000, //=+
KeyboardBitMask_COMMA = 0x4000000000, //,<
KeyboardBitMask_SUB = 0x8000000000, //-_
KeyboardBitMask_DOT = 0x10000000000, //.>
KeyboardBitMask_SLASH = 0x20000000000, // /?
KeyboardBitMask_TILDE = 0x40000000000, //`~
KeyboardBitMask_FIGURE_OPEN = 0x80000000000, //[{
KeyboardBitMask_BACKSLASH = 0x100000000000, //\|
KeyboardBitMask_FIGURE_CLOSE = 0x200000000000, //]}
KeyboardBitMask_QUOTE = 0x400000000000, //'"
KeyboardBitMask_end__,
};
}
Массив g_keyToBin
src/badcoiq/[b]input[/b]/bqInput.cpp
static const uint64_t g_keyToBin[] =
{
0, //KEY_NONE = 0,
0, 0, 0, 0, 0, 0, 0,
bq::KeyboardBitMask_BACKSPACE, //KEY_BACKSPACE = 8,
bq::KeyboardBitMask_TAB, //KEY_TAB = 9,
0, 0, 0,
bq::KeyboardBitMask_ENTER, //KEY_ENTER = 13,
0, 0,
bq::KeyboardBitMask_SHIFT, //KEY_SHIFT = 16,
bq::KeyboardBitMask_CTRL, //KEY_CTRL = 17,
bq::KeyboardBitMask_ALT, //KEY_ALT = 18,
bq::KeyboardBitMask_PAUSE,//KEY_PAUSE = 19,
bq::KeyboardBitMask_CAPS_LOCK,//KEY_CAPS_LOCK = 20,
0, 0, 0, 0, 0, 0,
bq::KeyboardBitMask_ESCAPE, //KEY_ESCAPE = 27,
0, 0, 0, 0,
bq::KeyboardBitMask_SPACE, //KEY_SPACE = 32,
bq::KeyboardBitMask_PGUP, //KEY_PGUP = 33,
bq::KeyboardBitMask_PGDOWN, //KEY_PGDOWN = 34,
bq::KeyboardBitMask_END, //KEY_END = 35,
bq::KeyboardBitMask_HOME, //KEY_HOME = 36,
bq::KeyboardBitMask_LEFT, //KEY_LEFT = 37,
bq::KeyboardBitMask_UP, //KEY_UP = 38,
bq::KeyboardBitMask_RIGHT, //KEY_RIGHT = 39,
bq::KeyboardBitMask_DOWN, //KEY_DOWN = 40,
0, 0, 0,
bq::KeyboardBitMask_PRTSCR, //KEY_PRTSCR = 44,
bq::KeyboardBitMask_INSERT, //KEY_INSERT = 45,
bq::KeyboardBitMask_DELETE, //KEY_DELETE = 46,
0,
bq::KeyboardBitMask_0, //KEY_0 = 48,
bq::KeyboardBitMask_1, //KEY_1 = 49,
bq::KeyboardBitMask_2, //KEY_2 = 50,
bq::KeyboardBitMask_3, //KEY_3 = 51,
bq::KeyboardBitMask_4, //KEY_4 = 52,
bq::KeyboardBitMask_5, //KEY_5 = 53,
bq::KeyboardBitMask_6, //KEY_6 = 54,
bq::KeyboardBitMask_7, //KEY_7 = 55,
bq::KeyboardBitMask_8, //KEY_8 = 56,
bq::KeyboardBitMask_9, //KEY_9 = 57,
0, 0, 0, 0, 0, 0, 0,
bq::KeyboardBitMask_A, //KEY_A = 65,
bq::KeyboardBitMask_B, //KEY_B = 66,
bq::KeyboardBitMask_C, //KEY_C = 67,
bq::KeyboardBitMask_D, //KEY_D = 68,
bq::KeyboardBitMask_E, //KEY_E = 69,
bq::KeyboardBitMask_F, //KEY_F = 70,
bq::KeyboardBitMask_G, //KEY_G = 71,
bq::KeyboardBitMask_H, //KEY_H = 72,
bq::KeyboardBitMask_I, //KEY_I = 73,
bq::KeyboardBitMask_J, //KEY_J = 74,
bq::KeyboardBitMask_K, //KEY_K = 75,
bq::KeyboardBitMask_L, //KEY_L = 76,
bq::KeyboardBitMask_M, //KEY_M = 77,
bq::KeyboardBitMask_N, //KEY_N = 78,
bq::KeyboardBitMask_O, //KEY_O = 79,
bq::KeyboardBitMask_P, //KEY_P = 80,
bq::KeyboardBitMask_Q, //KEY_Q = 81,
bq::KeyboardBitMask_R, //KEY_R = 82,
bq::KeyboardBitMask_S, //KEY_S = 83,
bq::KeyboardBitMask_T, //KEY_T = 84,
bq::KeyboardBitMask_U, //KEY_U = 85,
bq::KeyboardBitMask_V, //KEY_V = 86,
bq::KeyboardBitMask_W, //KEY_W = 87,
bq::KeyboardBitMask_X, //KEY_X = 88,
bq::KeyboardBitMask_Y, //KEY_Y = 89,
bq::KeyboardBitMask_Z, //KEY_Z = 90,
bq::KeyboardBitMask_WIN, //KEY_WIN = 91,
0,
bq::KeyboardBitMask_CONTEXT, //KEY_CONTEXT = 93,
0, 0,
bq::KeyboardBitMask_NUM_0, //KEY_NUM_0 = 96,
bq::KeyboardBitMask_NUM_1, //KEY_NUM_1 = 97,
bq::KeyboardBitMask_NUM_2, //KEY_NUM_2 = 98,
bq::KeyboardBitMask_NUM_3, //KEY_NUM_3 = 99,
bq::KeyboardBitMask_NUM_4, //KEY_NUM_4 = 100,
bq::KeyboardBitMask_NUM_5, //KEY_NUM_5 = 101,
bq::KeyboardBitMask_NUM_6, //KEY_NUM_6 = 102,
bq::KeyboardBitMask_NUM_7, //KEY_NUM_7 = 103,
bq::KeyboardBitMask_NUM_8, //KEY_NUM_8 = 104,
bq::KeyboardBitMask_NUM_9, //KEY_NUM_9 = 105,
bq::KeyboardBitMask_NUM_MUL,// KEY_NUM_MUL = 106, // *
bq::KeyboardBitMask_NUM_ADD, //KEY_NUM_ADD = 107, // +
0,
bq::KeyboardBitMask_NUM_SUB, //KEY_NUM_SUB = 109, // -
bq::KeyboardBitMask_NUM_DOT, //KEY_NUM_DOT = 110, // .
bq::KeyboardBitMask_NUM_SLASH, //KEY_NUM_SLASH = 111, // /
bq::KeyboardBitMask_F1, //KEY_F1 = 112,
bq::KeyboardBitMask_F2, //KEY_F2 = 113,
bq::KeyboardBitMask_F3, // KEY_F3 = 114,
bq::KeyboardBitMask_F4, //KEY_F4 = 115,
bq::KeyboardBitMask_F5, //KEY_F5 = 116,
bq::KeyboardBitMask_F6, //KEY_F6 = 117,
bq::KeyboardBitMask_F7, //KEY_F7 = 118,
bq::KeyboardBitMask_F8, //KEY_F8 = 119,
bq::KeyboardBitMask_F9, //KEY_F9 = 120,
bq::KeyboardBitMask_F10, //KEY_F10 = 121,
bq::KeyboardBitMask_F11, //KEY_F11 = 122,
bq::KeyboardBitMask_F12, //KEY_F12 = 123,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
bq::KeyboardBitMask_NUM_LOCK,// KEY_NUM_LOCK = 144,
bq::KeyboardBitMask_SCROLL_LOCK, //KEY_SCROLL_LOCK = 145,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
bq::KeyboardBitMask_LSHIFT, //KEY_LSHIFT = 160,
bq::KeyboardBitMask_RSHIFT, //KEY_RSHIFT = 161,
bq::KeyboardBitMask_LCTRL, //KEY_LCTRL = 162,
bq::KeyboardBitMask_RCTRL, //KEY_RCTRL = 163,
bq::KeyboardBitMask_LALT, //KEY_LALT = 164,
bq::KeyboardBitMask_RALT, //KEY_RALT = 165,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
bq::KeyboardBitMask_FUNC_MY_COMP, //KEY_FUNC_MY_COMP = 182, // Function key. open My computer
bq::KeyboardBitMask_FUNC_CALC, //KEY_FUNC_CALC = 183, // Function key. open Calculator
0, 0,
bq::KeyboardBitMask_COLON, //KEY_COLON = 186, //;:
bq::KeyboardBitMask_ADD, //KEY_ADD = 187, //=+
bq::KeyboardBitMask_COMMA, //KEY_COMMA = 188, //,<
bq::KeyboardBitMask_SUB, //KEY_SUB = 189, //-_
bq::KeyboardBitMask_DOT, //KEY_DOT = 190, //.>
bq::KeyboardBitMask_SLASH, //KEY_SLASH = 191, // /?
bq::KeyboardBitMask_TILDE, //KEY_TILDE = 192, //`~
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
bq::KeyboardBitMask_FIGURE_OPEN, //KEY_FIGURE_OPEN = 219, //[{
bq::KeyboardBitMask_BACKSLASH, //KEY_BACKSLASH = 220, //\|
bq::KeyboardBitMask_FIGURE_CLOSE, //KEY_FIGURE_CLOSE = 221, //]}
bq::KeyboardBitMask_QUOTE, //KEY_QUOTE = 222,
};
Реализация bqInput
#include "../framework/bqFrameworkImpl.h"
extern bqFrameworkImpl* g_framework;
static const uint64_t g_keyToBin[] = ...
...
bqInputData* bqInput::GetData()
{
BQ_ASSERT_ST(g_framework);
return &g_framework->m_input;
}
bqPointf& bqInput::GetMousePosition()
{
BQ_ASSERT_ST(g_framework);
return g_framework->m_input.m_mousePosition;
}
void bqInput::SetKeyHit(uint32_t k, bool v)
{
BQ_ASSERT_ST(g_framework);
uint64_t bit = g_keyToBin[k];
if (k < bqInput::KEY_NUM_1)
{
if (v)
g_framework->m_input.m_keyFlagsHit[0] |= bit;
else
g_framework->m_input.m_keyFlagsHit[0] &= ~bit;
}
else
{
if (v)
g_framework->m_input.m_keyFlagsHit[1] |= bit;
else
g_framework->m_input.m_keyFlagsHit[1] &= ~bit;
}
}
void bqInput::SetKeyHold(uint32_t k, bool v)
{
BQ_ASSERT_ST(g_framework);
uint64_t bit = g_keyToBin[k];
if (k < bqInput::KEY_NUM_1)
{
if (v)
g_framework->m_input.m_keyFlagsHold[0] |= bit;
else
g_framework->m_input.m_keyFlagsHold[0] &= ~bit;
}
else
{
if (v)
g_framework->m_input.m_keyFlagsHold[1] |= bit;
else
g_framework->m_input.m_keyFlagsHold[1] &= ~bit;
}
}
void bqInput::SetKeyRelease(uint32_t k, bool v)
{
BQ_ASSERT_ST(g_framework);
uint64_t bit = g_keyToBin[k];
if (k < bqInput::KEY_NUM_1)
{
if (v)
g_framework->m_input.m_keyFlagsRelease[0] |= bit;
else
g_framework->m_input.m_keyFlagsRelease[0] &= ~bit;
}
else
{
if (v)
g_framework->m_input.m_keyFlagsRelease[1] |= bit;
else
g_framework->m_input.m_keyFlagsRelease[1] &= ~bit;
}
}
bool bqInput::IsKeyHit(uint32_t i)
{
BQ_ASSERT_ST(g_framework);
uint64_t bit = g_keyToBin[i];
if (i < bqInput::KEY_NUM_1) // первый uint64_t
return (g_framework->m_input.m_keyFlagsHit[0] & bit);
else
return (g_framework->m_input.m_keyFlagsHit[1] & bit);
}
bool bqInput::IsKeyHold(uint32_t i)
{
BQ_ASSERT_ST(g_framework);
uint64_t bit = g_keyToBin[i];
if (i < bqInput::KEY_NUM_1) // первый uint64_t
return (g_framework->m_input.m_keyFlagsHold[0] & bit);
else
return (g_framework->m_input.m_keyFlagsHold[1] & bit);
}
bool bqInput::IsKeyRelease(uint32_t i)
{
BQ_ASSERT_ST(g_framework);
uint64_t bit = g_keyToBin[i];
if (i < bqInput::KEY_NUM_1) // первый uint64_t
return (g_framework->m_input.m_keyFlagsRelease[0] & bit);
else
return (g_framework->m_input.m_keyFlagsRelease[1] & bit);
}
void bqInput::EnableLMBDown() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_LMBDOWN; }
void bqInput::EnableLMBHold() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_LMBHOLD; }
void bqInput::EnableLMBUp() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_LMBUP; }
void bqInput::EnableRMBDown() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_RMBDOWN; }
void bqInput::EnableRMBHold() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_RMBHOLD; }
void bqInput::EnableRMBUp() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_RMBUP; }
void bqInput::EnableMMBDown() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_MMBDOWN; }
void bqInput::EnableMMBHold() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_MMBHOLD; }
void bqInput::EnableMMBUp() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_MMBUP; }
void bqInput::EnableX1MBDown() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_X1MBDOWN; }
void bqInput::EnableX1MBHold() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_X1MBHOLD; }
void bqInput::EnableX1MBUp() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_X1MBUP; }
void bqInput::EnableX2MBDown() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_X2MBDOWN; }
void bqInput::EnableX2MBHold() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_X2MBHOLD; }
void bqInput::EnableX2MBUp() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_X2MBUP; }
void bqInput::DisableLMBDown() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_LMBDOWN; }
void bqInput::DisableLMBHold() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_LMBHOLD; }
void bqInput::DisableLMBUp() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_LMBUP; }
void bqInput::DisableRMBDown() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_RMBDOWN; }
void bqInput::DisableRMBHold() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_RMBHOLD; }
void bqInput::DisableRMBUp() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_RMBUP; }
void bqInput::DisableMMBDown() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_MMBDOWN; }
void bqInput::DisableMMBHold() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_MMBHOLD; }
void bqInput::DisableMMBUp() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_MMBUP; }
void bqInput::DisableX1MBDown() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_X1MBDOWN; }
void bqInput::DisableX1MBHold() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_X1MBHOLD; }
void bqInput::DisableX1MBUp() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_X1MBUP; }
void bqInput::DisableX2MBDown() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_X2MBDOWN; }
void bqInput::DisableX2MBHold() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_X2MBHOLD; }
void bqInput::DisableX2MBUp() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_X2MBUP; }
bool bqInput::IsLMBHit() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_LMBDOWN) == bq::MouseFlag_LMBDOWN; }
bool bqInput::IsLMBHold() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_LMBHOLD) == bq::MouseFlag_LMBHOLD; }
bool bqInput::IsLMBRelease() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_LMBUP) == bq::MouseFlag_LMBUP; }
bool bqInput::IsRMBHit() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_RMBDOWN) == bq::MouseFlag_RMBDOWN; }
bool bqInput::IsRMBHold() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_RMBHOLD) == bq::MouseFlag_RMBHOLD; }
bool bqInput::IsRMBRelease() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_RMBUP) == bq::MouseFlag_RMBUP; }
bool bqInput::IsMMBHit() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_MMBDOWN) == bq::MouseFlag_MMBDOWN; }
bool bqInput::IsMMBHold() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_MMBHOLD) == bq::MouseFlag_MMBHOLD; }
bool bqInput::IsMMBRelease() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_MMBUP) == bq::MouseFlag_MMBUP; }
bool bqInput::IsX1MBHit() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_X1MBDOWN) == bq::MouseFlag_X1MBDOWN; }
bool bqInput::IsX1MBHold() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_X1MBHOLD) == bq::MouseFlag_X1MBHOLD; }
bool bqInput::IsX1MBRelease() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_X1MBUP) == bq::MouseFlag_X1MBUP; }
bool bqInput::IsX2MBHit() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_X2MBDOWN) == bq::MouseFlag_X2MBDOWN; }
bool bqInput::IsX2MBHold() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_X2MBHOLD) == bq::MouseFlag_X2MBHOLD; }
bool bqInput::IsX2MBRelease() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_X2MBUP) == bq::MouseFlag_X2MBUP; }
static const uint64_t* GetKeyToBin()
{
return g_keyToBin;
}
Так как используется 2 переменные для хранения состояний кнопок, идёт проверка, если код клавиши меньше bqInput::KEY_NUM_1
то далее идёт работа с первой переменной, иначе со второй.
Засунул класс bqFrameworkImpl в свой include, чтобы можно было использовать глобальный g_framework. Так-же в bqFramework добавил объект для хранения ввода
class bqFrameworkImpl
{
public:
...
bqInputData m_input;
...
};
Надо добавить две функции, перед вызовом оконной процедуры, и после.
bqInputUpdatePre();
#ifdef BQ_PLATFORM_WINDOWS
// без этого окно не будет реагировать
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
GetMessage(&msg, NULL, 0, 0);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
#endif
bqInputUpdatePost();
Их реализация (в bqInput.cpp
)
// обнуляем здесь
void bqInputUpdatePre()
{
g_framework->m_input.m_mousePositionOld = g_framework->m_input.m_mousePosition;
g_framework->m_input.m_mouseButtonFlags &= ~0x3FF;
g_framework->m_input.m_mouseWheelDelta = 0;
g_framework->m_input.m_character = 0;
g_framework->m_input.m_keyFlagsHit[0] = 0;
g_framework->m_input.m_keyFlagsHit[1] = 0;
g_framework->m_input.m_keyFlagsRelease[0] = 0;
g_framework->m_input.m_keyFlagsRelease[1] = 0;
}
// тут находим m_mouseMoveDelta и m_keyboardModifier
void bqInputUpdatePost()
{
unsigned int ctrl_shift_alt = 0;
if (bqInput::IsKeyHold(bqInput::KEY_LALT) || bqInput::IsKeyHold(bqInput::KEY_RALT))
ctrl_shift_alt |= 1;
if (bqInput::IsKeyHold(bqInput::KEY_LSHIFT) || bqInput::IsKeyHold(bqInput::KEY_RSHIFT))
ctrl_shift_alt |= 2;
if (bqInput::IsKeyHold(bqInput::KEY_LCTRL) || bqInput::IsKeyHold(bqInput::KEY_RCTRL))
ctrl_shift_alt |= 4;
switch (ctrl_shift_alt)
{
default:
case 0: g_framework->m_input.m_keyboardModifier = bq::KeyboardMod_Clear; break;
case 1: g_framework->m_input.m_keyboardModifier = bq::KeyboardMod_Alt; break;
case 2: g_framework->m_input.m_keyboardModifier = bq::KeyboardMod_Shift; break;
case 3: g_framework->m_input.m_keyboardModifier = bq::KeyboardMod_ShiftAlt; break;
case 4: g_framework->m_input.m_keyboardModifier = bq::KeyboardMod_Ctrl; break;
case 5: g_framework->m_input.m_keyboardModifier = bq::KeyboardMod_CtrlAlt; break;
case 6: g_framework->m_input.m_keyboardModifier = bq::KeyboardMod_CtrlShift; break;
case 7: g_framework->m_input.m_keyboardModifier = bq::KeyboardMod_CtrlShiftAlt; break;
}
g_framework->m_input.m_mouseMoveDelta.x = g_framework->m_input.m_mousePosition.x -
g_framework->m_input.m_mousePositionOld.x;
g_framework->m_input.m_mouseMoveDelta.y = g_framework->m_input.m_mousePosition.y -
g_framework->m_input.m_mousePositionOld.y;
}
Теперь надо пойти в оконную процедуру и получить состояния, заполнить bqInputData.
Для получения состояния о мышки использую Raw Input.
Оконное сообщение.
case WM_INPUT:
{
if (pW)
{
HRAWINPUT hRawInput = (HRAWINPUT)lParam;
UINT dataSize;
GetRawInputData(hRawInput, RID_INPUT, NULL, &dataSize, sizeof(RAWINPUTHEADER));
if (dataSize == 0 || dataSize > 0xff)
break;
bqWindowWin32* w32 = (bqWindowWin32*)pW->GetData()->m_implementation;
void* dataBuf = &w32->m_rawInputData[0];
GetRawInputData(hRawInput, RID_INPUT, dataBuf, &dataSize, sizeof(RAWINPUTHEADER));
const RAWINPUT* raw = (const RAWINPUT*)dataBuf;
if (raw->header.dwType == RIM_TYPEMOUSE)
{
HANDLE deviceHandle = raw->header.hDevice;
const RAWMOUSE& mouseData = raw->data.mouse;
USHORT flags = mouseData.usButtonFlags;
short wheelDelta = (short)mouseData.usButtonData;
LONG x = mouseData.lLastX, y = mouseData.lLastY;
/*wprintf(
L"Mouse: Device=0x%08X, Flags=%04x, WheelDelta=%d, X=%d, Y=%d\n",
deviceHandle, flags, wheelDelta, x, y);*/
bqInputData* id = bqInput::GetData();
if (wheelDelta)
id->m_mouseWheelDelta = (float)wheelDelta / (float)WHEEL_DELTA;
RECT rct;
GetWindowRect(hWnd, &rct);
POINT cursorPoint;
GetCursorPos(&cursorPoint);
//ScreenToClient(hWnd, &cursorPoint);
id->m_mousePosition.x = (float)(cursorPoint.x - rct.left - pW->GetBorderSize()->x);
id->m_mousePosition.y = (float)(cursorPoint.y - rct.top - pW->GetBorderSize()->y);
printf("%i %i\n", cursorPoint.x, cursorPoint.y);
if (flags)
{
if ((flags & 0x1) == 0x1)
{
bqInput::EnableLMBDown();
bqInput::EnableLMBHold();
}
if ((flags & 0x2) == 0x2)
{
bqInput::EnableLMBUp();
bqInput::DisableLMBHold();
}
if ((flags & 0x4) == 0x4)
{
bqInput::EnableRMBDown();
bqInput::EnableRMBHold();
}
if ((flags & 0x8) == 0x8)
{
bqInput::EnableRMBUp();
bqInput::DisableRMBHold();
}
if ((flags & 0x10) == 0x10)
{
bqInput::EnableMMBDown();
bqInput::EnableMMBHold();
}
if ((flags & 0x20) == 0x20)
{
bqInput::EnableMMBUp();
bqInput::DisableMMBHold();
}
if ((flags & 0x100) == 0x100)
{
bqInput::EnableX1MBDown();
bqInput::EnableX1MBHold();
}
if ((flags & 0x200) == 0x200)
{
bqInput::EnableX1MBUp();
bqInput::DisableX1MBHold();
}
if ((flags & 0x40) == 0x40)
{
bqInput::EnableX2MBDown();
bqInput::EnableX2MBHold();
}
if ((flags & 0x80) == 0x80)
{
bqInput::EnableX2MBUp();
bqInput::DisableX2MBHold();
}
}
}
}
}break;
Raw Input надо инициализировать. В bqFramework::Start
добавляю
#ifdef BQ_PLATFORM_WINDOWS
RAWINPUTDEVICE device;
device.usUsagePage = 0x01;
device.usUsage = 0x02;
device.dwFlags = 0;
device.hwndTarget = 0;
RegisterRawInputDevices(&device, 1, sizeof device);
#endif
Возвращаюсь в оконную процедуру и получаю информацию о клавиатуре.
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
case WM_KEYDOWN:
case WM_KEYUP:
{
bool isPress = true;
uint32_t key = (uint32_t)wParam;
if (message == WM_SYSKEYUP) isPress = false;
if (message == WM_KEYUP) isPress = false;
if (key == bqInput::KEY_SHIFT)
{ // shift -> lshift rshift
key = MapVirtualKey(((lParam >> 16) & 255u), 3);
}
if (key == bqInput::KEY_CTRL)
{ // ctrl -> lctrl rctrl
key = MapVirtualKey(((lParam >> 16) & 255), 3);
if (lParam & 0x1000000)
key = 163;
}
if (key == bqInput::KEY_ALT)
{ // alt -> lalt ralt
key = MapVirtualKey(((lParam >> 16) & 255), 3);
if (lParam & 0x1000000)
key = 165;
//printf("alt = %i\n",(int)ev.keyboardEvent.key);
}
if (isPress)
{
if (key < 256)
{
bqInput::SetKeyHold(key, true);
bqInput::SetKeyHit(key, true);
}
}
else
{
if (key < 256)
{
bqInput::SetKeyHold(key, false);
bqInput::SetKeyRelease(key, true);
}
}
if (message == WM_SYSKEYDOWN || message == WM_SYSKEYUP)
{
return DefWindowProc(hWnd, message, wParam, lParam);
}
else
{
return 0;
}
}break;
Надо выключить активацию меню окна когда нажимаешь Alt
case WM_SYSCOMMAND:
if ((wParam & 0xFFF0) == SC_SCREENSAVE ||
(wParam & 0xFFF0) == SC_MONITORPOWER ||
(wParam & 0xFFF0) == SC_KEYMENU
)
{
return 0;
}
Получение вводимого символа
case WM_CHAR:
{
bqInputData* id = bqInput::GetData();
id->m_character = wParam;
}break;
https://github.com/badcoiq/badcoiq/tree/e95238e96dbb36b17d0bef1700681eed96ca4ec6