Skip to content

Instantly share code, notes, and snippets.

@benanil
Last active November 20, 2023 15:58
Show Gist options
  • Save benanil/f66aadcb46390a5479f19c691fbf4034 to your computer and use it in GitHub Desktop.
Save benanil/f66aadcb46390a5479f19c691fbf4034 to your computer and use it in GitHub Desktop.
Windows Keyboard & Mouse Input like glfw
enum KeyboardKey_
{
Key_BACK = 0x08,
Key_TAB = 0x09,
Key_CLEAR = 0x0C,
Key_RETURN = 0x0D,
Key_SHIFT = 0x10,
Key_CONTROL = 0x11,
Key_MENU = 0x12,
Key_PAUSE = 0x13,
Key_CAPITAL = 0x14,
Key_ESCAPE = 0x1B,
Key_CONVERT = 0x1C,
Key_NONCONVERT = 0x1D,
Key_ACCEPT = 0x1E,
Key_MODECHANGE = 0x1F,
Key_SPACE = 0x20,
Key_PRIOR = 0x21,
Key_NEXT = 0x22,
Key_END = 0x23,
Key_HOME = 0x24,
Key_LEFT = 0x25,
Key_UP = 0x26,
Key_RIGHT = 0x27,
Key_DOWN = 0x28,
Key_SELECT = 0x29,
Key_PRINT = 0x2A,
Key_EXECUTE = 0x2B,
Key_SNAPSHOT = 0x2C,
Key_INSERT = 0x2D,
Key_DELETE = 0x2E,
Key_HELP = 0x2F,
Key_LWIN = 0x5B,
Key_RWIN = 0x5C,
Key_APPS = 0x5D,
Key_SLEEP = 0x5F,
Key_NUMPAD0 = 0x60,
Key_NUMPAD1 = 0x61,
Key_NUMPAD2 = 0x62,
Key_NUMPAD3 = 0x63,
Key_NUMPAD4 = 0x64,
Key_NUMPAD5 = 0x65,
Key_NUMPAD6 = 0x66,
Key_NUMPAD7 = 0x67,
Key_NUMPAD8 = 0x68,
Key_NUMPAD9 = 0x69,
Key_MULTIPLY = 0x6A,
Key_ADD = 0x6B,
Key_SEPARATOR = 0x6C,
Key_SUBTRACT = 0x6D,
Key_DECIMAL = 0x6E,
Key_DIVIDE = 0x6F,
Key_F1 = 0x70,
Key_F2 = 0x71,
Key_F3 = 0x72,
Key_F4 = 0x73,
Key_F5 = 0x74,
Key_F6 = 0x75,
Key_F7 = 0x76,
Key_F8 = 0x77,
Key_F9 = 0x78,
Key_F10 = 0x79,
Key_F11 = 0x7A,
Key_F12 = 0x7B,
};
typedef int KeyboardKey;
enum MouseButton_
{
MouseButton_Left = 1,
MouseButton_Right = 2,
MouseButton_Middle = 4
};
typedef int MouseButton;
// public functions that are callable from different cpp files,
// you might want to write these to header file.
// use KeyboardKey enum or asci char 'X'
bool GetKeyDown(char c);
bool GetKeyPressed(char c);
bool GetKeyReleased(char c);
bool GetMouseDown(MouseButton button);
bool GetMouseReleased(MouseButton button);
bool GetMousePressed(MouseButton button);
// set these callbacks or leave it as nullptr
static void(*WindowMoveCallback)(int, int) = nullptr;
static void(*WindowResizeCallback)(int, int) = nullptr;
static void(*MouseMoveCallback)(float, float) = nullptr;
static void(*KeyPressCallback)(wchar_t) = nullptr;
static void(*FocusChangedCallback)(bool) = nullptr;
// 128bit bitfield storage for keyboard keys
unsigned long g_axDownKeys[2]{};
unsigned long g_axLastKeys[2]{};
unsigned long g_axPressedKeys[2]{};
unsigned long g_axReleasedKeys[2]{};
// mouse
int g_axMouseDown = 0, g_axMouseLast = 0, g_axMousePressed = 0, g_axMouseReleased = 0;
inline bool GetBit128(unsigned long bits[2], int idx) { return !!(bits[idx > 63] & (1ul << (idx & 63ul))); }
inline void SetBit128(unsigned long bits[2], int idx) { bits[idx > 63] |= 1ul << (idx & 63); }
inline void ResetBit128(unsigned long bits[2], int idx) { bits[idx > 63] &= ~(1ul << (idx & 63)); }
bool GetKeyDown(char c) { return GetBit128(g_axDownKeys, c); }
bool GetKeyReleased(char c) { return GetBit128(g_axReleasedKeys, c); }
bool GetKeyPressed(char c) { return GetBit128(g_axPressedKeys, c); }
static void SetPressedAndReleasedKeys()
{
g_axReleasedKeys[0] = g_axLastKeys[0] & ~g_axDownKeys[0];
g_axReleasedKeys[1] = g_axLastKeys[1] & ~g_axDownKeys[1];
g_axPressedKeys[0] = ~g_axLastKeys[0] & g_axDownKeys[0];
g_axPressedKeys[1] = ~g_axLastKeys[1] & g_axDownKeys[1];
// Mouse
g_axMouseReleased = g_axMouseLast & ~g_axMouseDown;
g_axMousePressed = ~g_axMouseLast & g_axMouseDown;
}
static void RecordLastKeys() {
g_axLastKeys[0] = g_axDownKeys[0];
g_axLastKeys[1] = g_axDownKeys[1];
g_axMouseLast = g_axMouseDown;
}
bool GetMouseDown(MouseButton button) { return !!(g_axMouseDown & button); }
bool GetMouseReleased(MouseButton button) { return !!(g_axMouseReleased & button); }
bool GetMousePressed(MouseButton button) { return !!(g_axMousePressed & button); }
void GetMousePos(float* x, float* y)
{
ASSERT((uint64_t)x & (uint64_t)y); // shouldn't be nullptr
POINT point;
GetCursorPos(&point);
*x = (float)point.x;
*y = (float)point.y;
}
void SetMousePos(float x, float y)
{
SetCursorPos((int)x, (int)y);
}
float g_axMousePosX = 0.0, g_axMousePosY = 0.0f;
void GetMouseWindowPos(float* x, float* y)
{
*x = g_axMousePosX; *y = g_axMousePosY;
}
void SetMouseWindowPos(float x, float y)
{
SetMousePos(windowPosX_ + x, windowPosY_ + y);
}
static LRESULT CALLBACK WindowCallback(HWND window, UINT msg, WPARAM wparam, LPARAM lparam)
{
LRESULT result = 0;
wchar_t wch = 0;
switch (msg)
{
case WM_MOUSEMOVE:
g_axMousePosX = (float)LOWORD(lparam);
g_axMousePosY = (float)HIWORD(lparam);
if (MouseMoveCallback) MouseMoveCallback(g_axMousePosX, g_axMousePosY);
break;
case WM_LBUTTONDOWN: g_axMouseDown |= MouseButton_Left; break;
case WM_RBUTTONDOWN: g_axMouseDown |= MouseButton_Right; break;
case WM_MBUTTONDOWN: g_axMouseDown |= MouseButton_Middle; break;
case WM_LBUTTONUP: g_axMouseDown &= ~MouseButton_Left; break;
case WM_RBUTTONUP: g_axMouseDown &= ~MouseButton_Right; break;
case WM_MBUTTONUP: g_axMouseDown &= ~MouseButton_Middle; break;
case WM_XBUTTONUP: g_axMouseDown &= ~MouseButton_Middle; break;
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
{
if (wparam > 127) break;
SetBit128(g_axDownKeys, wparam);
break;
}
case WM_SETFOCUS:
case WM_KILLFOCUS:
if (FocusChangedCallback) FocusChangedCallback(msg == WM_SETFOCUS);
break;
case WM_KEYUP:
case WM_SYSKEYUP:
{
if (wparam > 127) break;
ResetBit128(g_axDownKeys, wparam);
break;
}
case WM_CHAR:
::MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, (char*)&wparam, 1, &wch, 1);
if (KeyPressCallback) KeyPressCallback(wch);
break;
case WM_SIZE:
windowWidth_ = LOWORD(lparam);
windowHeight_ = HIWORD(lparam);
// UpdateRenderArea();
if (WindowResizeCallback) WindowResizeCallback(windowWidth_, windowHeight_);
break;
case WM_MOVE:
windowPosX_ = LOWORD(lparam);
windowPosY_ = HIWORD(lparam);
break;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
result = DefWindowProcA(window, msg, wparam, lparam);
break;
}
return result;
}
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmd_line, int show)
{
// Initialize your window here...
bool running = true;
while (running)
{
MSG msg;
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
running = false;
}
else
{
TranslateMessage(&msg);
DispatchMessageA(&msg);
}
}
SetPressedAndReleasedKeys();
// Do rendering and calculations here...
RecordLastKeys();
}
// finalize here...
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment