2020-01-02 02:41:43 +00:00
|
|
|
//
|
|
|
|
// File: gs_input.h
|
|
|
|
// Author: Peter Slattery
|
|
|
|
// Creation Date: 2020-01-01
|
|
|
|
//
|
|
|
|
#ifndef GS_INPUT_H
|
2020-02-06 04:33:12 +00:00
|
|
|
enum key_code
|
|
|
|
{
|
|
|
|
KeyCode_Invalid,
|
|
|
|
|
|
|
|
KeyCode_Esc,
|
|
|
|
|
|
|
|
KeyCode_Space,
|
|
|
|
KeyCode_Tab,
|
|
|
|
KeyCode_CapsLock,
|
|
|
|
KeyCode_LeftShift, KeyCode_RightShift,
|
|
|
|
KeyCode_LeftCtrl, KeyCode_RightCtrl,
|
|
|
|
KeyCode_Fn,
|
|
|
|
KeyCode_Alt,
|
|
|
|
KeyCode_PageUp, KeyCode_PageDown,
|
|
|
|
KeyCode_Backspace, KeyCode_Delete,
|
|
|
|
KeyCode_Enter,
|
|
|
|
|
|
|
|
// Function Keys
|
|
|
|
KeyCode_F0, KeyCode_F1, KeyCode_F2, KeyCode_F3, KeyCode_F4, KeyCode_F5, KeyCode_F6, KeyCode_F7,
|
|
|
|
KeyCode_F8, KeyCode_F9, KeyCode_F10, KeyCode_F11, KeyCode_F12,
|
|
|
|
|
|
|
|
// Letters
|
|
|
|
KeyCode_a, KeyCode_b, KeyCode_c, KeyCode_d, KeyCode_e, KeyCode_f, KeyCode_g, KeyCode_h,
|
|
|
|
KeyCode_i, KeyCode_j, KeyCode_k, KeyCode_l, KeyCode_m, KeyCode_n, KeyCode_o, KeyCode_p,
|
|
|
|
KeyCode_q, KeyCode_r, KeyCode_s, KeyCode_t, KeyCode_u, KeyCode_v, KeyCode_w, KeyCode_x,
|
|
|
|
KeyCode_y, KeyCode_z,
|
|
|
|
|
|
|
|
KeyCode_A, KeyCode_B, KeyCode_C, KeyCode_D, KeyCode_E, KeyCode_F, KeyCode_G, KeyCode_H,
|
|
|
|
KeyCode_I, KeyCode_J, KeyCode_K, KeyCode_L, KeyCode_M, KeyCode_N, KeyCode_O, KeyCode_P,
|
|
|
|
KeyCode_Q, KeyCode_R, KeyCode_S, KeyCode_T, KeyCode_U, KeyCode_V, KeyCode_W, KeyCode_X,
|
|
|
|
KeyCode_Y, KeyCode_Z,
|
|
|
|
|
|
|
|
// Numbers
|
|
|
|
KeyCode_0, KeyCode_1, KeyCode_2, KeyCode_3, KeyCode_4, KeyCode_5, KeyCode_6, KeyCode_7,
|
|
|
|
KeyCode_8, KeyCode_9,
|
|
|
|
|
|
|
|
KeyCode_Num0, KeyCode_Num1, KeyCode_Num2, KeyCode_Num3, KeyCode_Num4, KeyCode_Num5,
|
|
|
|
KeyCode_Num6, KeyCode_Num7, KeyCode_Num8, KeyCode_Num9,
|
|
|
|
|
|
|
|
// Symbols
|
|
|
|
KeyCode_Bang, KeyCode_At, KeyCode_Pound, KeyCode_Dollar, KeyCode_Percent, KeyCode_Carrot,
|
|
|
|
KeyCode_Ampersand, KeyCode_Star, KeyCode_LeftParen, KeyCode_RightParen, KeyCode_Minus, KeyCode_Plus,
|
|
|
|
KeyCode_Equals, KeyCode_Underscore, KeyCode_LeftBrace, KeyCode_RightBrace, KeyCode_LeftBracket,
|
|
|
|
KeyCode_RightBracket, KeyCode_Colon, KeyCode_SemiColon, KeyCode_SingleQuote, KeyCode_DoubleQuote,
|
|
|
|
KeyCode_ForwardSlash, KeyCode_Backslash, KeyCode_Pipe, KeyCode_Comma, KeyCode_Period,
|
|
|
|
KeyCode_QuestionMark, KeyCode_LessThan, KeyCode_GreaterThan, KeyCode_Tilde, KeyCode_BackQuote,
|
|
|
|
|
|
|
|
// Arrows
|
|
|
|
KeyCode_UpArrow,
|
|
|
|
KeyCode_DownArrow,
|
|
|
|
KeyCode_LeftArrow,
|
|
|
|
KeyCode_RightArrow,
|
|
|
|
|
|
|
|
// Mouse
|
|
|
|
// NOTE(Peter): Including this here so we can utilize the same KeyDown, KeyUp etc. functions
|
|
|
|
KeyCode_MouseLeftButton,
|
|
|
|
KeyCode_MouseMiddleButton,
|
|
|
|
KeyCode_MouseRightButton,
|
|
|
|
|
|
|
|
KeyCode_Count,
|
|
|
|
};
|
|
|
|
|
|
|
|
internal char
|
|
|
|
CharacterFromKeyCode (key_code Code)
|
|
|
|
{
|
|
|
|
char Result = 0;
|
|
|
|
|
|
|
|
switch (Code)
|
|
|
|
{
|
|
|
|
case KeyCode_Space: { Result = ' '; }break;
|
|
|
|
case KeyCode_Tab: { Result = '\t'; }break;
|
|
|
|
|
|
|
|
// Letters
|
|
|
|
case KeyCode_a: { Result = 'a'; }break;
|
|
|
|
case KeyCode_b: { Result = 'b'; }break;
|
|
|
|
case KeyCode_c: { Result = 'c'; }break;
|
|
|
|
case KeyCode_d: { Result = 'd'; }break;
|
|
|
|
case KeyCode_e: { Result = 'e'; }break;
|
|
|
|
case KeyCode_f: { Result = 'f'; }break;
|
|
|
|
case KeyCode_g: { Result = 'g'; }break;
|
|
|
|
case KeyCode_h: { Result = 'h'; }break;
|
|
|
|
case KeyCode_i: { Result = 'i'; }break;
|
|
|
|
case KeyCode_j: { Result = 'j'; }break;
|
|
|
|
case KeyCode_k: { Result = 'k'; }break;
|
|
|
|
case KeyCode_l: { Result = 'l'; }break;
|
|
|
|
case KeyCode_m: { Result = 'm'; }break;
|
|
|
|
case KeyCode_n: { Result = 'n'; }break;
|
|
|
|
case KeyCode_o: { Result = 'o'; }break;
|
|
|
|
case KeyCode_p: { Result = 'p'; }break;
|
|
|
|
case KeyCode_q: { Result = 'q'; }break;
|
|
|
|
case KeyCode_r: { Result = 'r'; }break;
|
|
|
|
case KeyCode_s: { Result = 's'; }break;
|
|
|
|
case KeyCode_t: { Result = 't'; }break;
|
|
|
|
case KeyCode_u: { Result = 'u'; }break;
|
|
|
|
case KeyCode_v: { Result = 'v'; }break;
|
|
|
|
case KeyCode_w: { Result = 'w'; }break;
|
|
|
|
case KeyCode_x: { Result = 'x'; }break;
|
|
|
|
case KeyCode_y: { Result = 'y'; }break;
|
|
|
|
case KeyCode_z: { Result = 'z'; }break;
|
|
|
|
|
|
|
|
case KeyCode_A: { Result = 'A'; }break;
|
|
|
|
case KeyCode_B: { Result = 'B'; }break;
|
|
|
|
case KeyCode_C: { Result = 'C'; }break;
|
|
|
|
case KeyCode_D: { Result = 'D'; }break;
|
|
|
|
case KeyCode_E: { Result = 'E'; }break;
|
|
|
|
case KeyCode_F: { Result = 'F'; }break;
|
|
|
|
case KeyCode_G: { Result = 'G'; }break;
|
|
|
|
case KeyCode_H: { Result = 'H'; }break;
|
|
|
|
case KeyCode_I: { Result = 'I'; }break;
|
|
|
|
case KeyCode_J: { Result = 'J'; }break;
|
|
|
|
case KeyCode_K: { Result = 'K'; }break;
|
|
|
|
case KeyCode_L: { Result = 'L'; }break;
|
|
|
|
case KeyCode_M: { Result = 'M'; }break;
|
|
|
|
case KeyCode_N: { Result = 'N'; }break;
|
|
|
|
case KeyCode_O: { Result = 'O'; }break;
|
|
|
|
case KeyCode_P: { Result = 'P'; }break;
|
|
|
|
case KeyCode_Q: { Result = 'Q'; }break;
|
|
|
|
case KeyCode_R: { Result = 'R'; }break;
|
|
|
|
case KeyCode_S: { Result = 'S'; }break;
|
|
|
|
case KeyCode_T: { Result = 'T'; }break;
|
|
|
|
case KeyCode_U: { Result = 'U'; }break;
|
|
|
|
case KeyCode_V: { Result = 'V'; }break;
|
|
|
|
case KeyCode_W: { Result = 'W'; }break;
|
|
|
|
case KeyCode_X: { Result = 'X'; }break;
|
|
|
|
case KeyCode_Y: { Result = 'Y'; }break;
|
|
|
|
case KeyCode_Z: { Result = 'Z'; }break;
|
|
|
|
|
|
|
|
// Numbers
|
|
|
|
case KeyCode_0: { Result = '0'; }break;
|
|
|
|
case KeyCode_1: { Result = '1'; }break;
|
|
|
|
case KeyCode_2: { Result = '2'; }break;
|
|
|
|
case KeyCode_3: { Result = '3'; }break;
|
|
|
|
case KeyCode_4: { Result = '4'; }break;
|
|
|
|
case KeyCode_5: { Result = '5'; }break;
|
|
|
|
case KeyCode_6: { Result = '6'; }break;
|
|
|
|
case KeyCode_7: { Result = '7'; }break;
|
|
|
|
case KeyCode_8: { Result = '8'; }break;
|
|
|
|
case KeyCode_9: { Result = '9'; }break;
|
|
|
|
|
|
|
|
case KeyCode_Num0: { Result = '0'; }break;
|
|
|
|
case KeyCode_Num1: { Result = '1'; }break;
|
|
|
|
case KeyCode_Num2: { Result = '2'; }break;
|
|
|
|
case KeyCode_Num3: { Result = '3'; }break;
|
|
|
|
case KeyCode_Num4: { Result = '4'; }break;
|
|
|
|
case KeyCode_Num5: { Result = '5'; }break;
|
|
|
|
case KeyCode_Num6: { Result = '6'; }break;
|
|
|
|
case KeyCode_Num7: { Result = '7'; }break;
|
|
|
|
case KeyCode_Num8: { Result = '8'; }break;
|
|
|
|
case KeyCode_Num9: { Result = '9'; }break;
|
|
|
|
|
|
|
|
// Symbols
|
|
|
|
case KeyCode_Bang: { Result = '!'; }break;
|
|
|
|
case KeyCode_At: { Result = '@'; }break;
|
|
|
|
case KeyCode_Pound: { Result = '#'; }break;
|
|
|
|
case KeyCode_Dollar: { Result = '$'; }break;
|
|
|
|
case KeyCode_Percent: { Result = '%'; }break;
|
|
|
|
case KeyCode_Carrot: { Result = '^'; }break;
|
|
|
|
case KeyCode_Ampersand: { Result = '&'; }break;
|
|
|
|
case KeyCode_Star: { Result = '*'; }break;
|
|
|
|
case KeyCode_LeftParen: { Result = '('; }break;
|
|
|
|
case KeyCode_RightParen: { Result = ')'; }break;
|
|
|
|
case KeyCode_Minus: { Result = '-'; }break;
|
|
|
|
case KeyCode_Plus: { Result = '+'; }break;
|
|
|
|
case KeyCode_Equals: { Result = '='; }break;
|
|
|
|
case KeyCode_Underscore: { Result = '_'; }break;
|
|
|
|
case KeyCode_LeftBrace: { Result = '['; }break;
|
|
|
|
case KeyCode_RightBrace: { Result = ']'; }break;
|
|
|
|
case KeyCode_LeftBracket: { Result = '{'; }break;
|
|
|
|
case KeyCode_RightBracket: { Result = '}'; }break;
|
|
|
|
case KeyCode_Colon: { Result = ':'; }break;
|
|
|
|
case KeyCode_SemiColon: { Result = ';'; }break;
|
|
|
|
case KeyCode_SingleQuote: { Result = '\''; }break;
|
|
|
|
case KeyCode_DoubleQuote: { Result = '"'; }break;
|
|
|
|
case KeyCode_ForwardSlash: { Result = '/'; }break;
|
|
|
|
case KeyCode_Backslash: { Result = '\\'; }break;
|
|
|
|
case KeyCode_Pipe: { Result = '|'; }break;
|
|
|
|
case KeyCode_Comma: { Result = ','; }break;
|
|
|
|
case KeyCode_Period: { Result = '.'; }break;
|
|
|
|
case KeyCode_QuestionMark: { Result = '?'; }break;
|
|
|
|
case KeyCode_LessThan: { Result = '<'; }break;
|
|
|
|
case KeyCode_GreaterThan: { Result = '>'; }break;
|
|
|
|
case KeyCode_Tilde: { Result = '~'; }break;
|
|
|
|
case KeyCode_BackQuote: { Result = '`'; }break;
|
|
|
|
}
|
|
|
|
|
|
|
|
Assert(Result != 0);
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
enum modifier_flags
|
|
|
|
{
|
|
|
|
Modifier_Shift = 1 << 0,
|
|
|
|
Modifier_Ctrl = 1 << 1,
|
|
|
|
Modifier_Alt = 1 << 2,
|
|
|
|
Modifier_Sys = 1 << 3, // NOTE(Peter): this is the windows key
|
|
|
|
};
|
|
|
|
|
|
|
|
#define INPUT_FRAME_STRING_LENGTH 32
|
|
|
|
struct input_frame
|
|
|
|
{
|
|
|
|
b32 KeysDown[(int)KeyCode_Count];
|
|
|
|
s32 StringInputUsed;
|
|
|
|
char StringInput[INPUT_FRAME_STRING_LENGTH];
|
|
|
|
s32 MouseX, MouseY, MouseScroll;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct input
|
|
|
|
{
|
|
|
|
input_frame Frames[2];
|
|
|
|
input_frame* New;
|
|
|
|
input_frame* Old;
|
|
|
|
s32 MouseDownX, MouseDownY;
|
|
|
|
};
|
2020-01-02 02:41:43 +00:00
|
|
|
|
2019-10-30 14:28:02 +00:00
|
|
|
enum key_state_flags
|
|
|
|
{
|
|
|
|
KeyState_WasDown = 1 << 0,
|
|
|
|
KeyState_IsDown = 1 << 1,
|
|
|
|
};
|
|
|
|
|
2019-11-11 20:02:24 +00:00
|
|
|
#define KeyWasDown(event) ((event & KeyState_WasDown) > 0)
|
|
|
|
#define KeyIsDown(event) ((event & KeyState_IsDown) > 0)
|
2019-10-30 14:28:02 +00:00
|
|
|
|
|
|
|
struct input_entry
|
|
|
|
{
|
|
|
|
key_code Key;
|
|
|
|
b32 State;
|
|
|
|
b32 Modifiers;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct input_queue
|
|
|
|
{
|
|
|
|
s32 QueueSize;
|
|
|
|
s32 QueueUsed;
|
|
|
|
input_entry* Entries;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct mouse_state
|
|
|
|
{
|
|
|
|
s32 Scroll;
|
|
|
|
|
|
|
|
v2 Pos;
|
|
|
|
v2 OldPos;
|
|
|
|
v2 DeltaPos;
|
|
|
|
v2 DownPos;
|
2019-11-01 14:38:44 +00:00
|
|
|
|
2019-11-11 20:02:24 +00:00
|
|
|
b32 LeftButtonState;
|
|
|
|
b32 MiddleButtonState;
|
|
|
|
b32 RightButtonState;
|
2019-10-30 14:28:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
internal input_queue
|
|
|
|
InitializeInputQueue (u8* Memory, s32 MemorySize)
|
|
|
|
{
|
|
|
|
input_queue Result = {};
|
|
|
|
s32 EntriesCount = MemorySize / sizeof(input_entry);
|
|
|
|
Result.QueueSize = EntriesCount;
|
|
|
|
Result.QueueUsed = 0;
|
|
|
|
Result.Entries = (input_entry*)Memory;
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal void
|
|
|
|
ResetInputQueue (input_queue* Queue)
|
|
|
|
{
|
|
|
|
Queue->QueueUsed = 0;
|
|
|
|
}
|
|
|
|
|
2020-02-06 04:33:12 +00:00
|
|
|
internal void InitializeInput (input* Input);
|
|
|
|
internal void SwapInputBuffers (input* Input);
|
|
|
|
|
|
|
|
internal void
|
|
|
|
InitializeInput (input* Input)
|
|
|
|
{
|
|
|
|
*(Input) = {};
|
|
|
|
Input->New = &Input->Frames[0];
|
|
|
|
Input->Old = &Input->Frames[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
internal void
|
|
|
|
SwapInputBuffers (input* Input)
|
|
|
|
{
|
|
|
|
input_frame* NowOld = Input->New;
|
|
|
|
Input->New = Input->Old;
|
|
|
|
Input->Old = NowOld;
|
|
|
|
|
|
|
|
for (s32 Key = 0; Key < KeyCode_Count; Key++) { Input->New->KeysDown[Key] = Input->Old->KeysDown[Key]; }
|
|
|
|
Input->New->StringInputUsed = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal b32
|
|
|
|
KeyDown (input Input, key_code Key)
|
|
|
|
{
|
|
|
|
return Input.New->KeysDown[Key];
|
|
|
|
}
|
|
|
|
|
|
|
|
internal b32
|
|
|
|
KeyTransitionedDown (input Input, key_code Key)
|
|
|
|
{
|
|
|
|
return Input.New->KeysDown[Key] && !Input.Old->KeysDown[Key];
|
|
|
|
}
|
|
|
|
|
|
|
|
internal b32
|
|
|
|
KeyTransitionedUp (input Input, key_code Key)
|
|
|
|
{
|
|
|
|
return !Input.New->KeysDown[Key] && Input.Old->KeysDown[Key];
|
|
|
|
}
|
|
|
|
|
2019-10-30 14:28:02 +00:00
|
|
|
internal void
|
|
|
|
AddInputEventEntry (input_queue* Queue, key_code Key,
|
|
|
|
b32 WasDown, b32 IsDown, b32 ShiftDown, b32 AltDown, b32 CtrlDown, b32 SysDown)
|
|
|
|
{
|
|
|
|
Assert(Queue->QueueUsed < Queue->QueueSize);
|
|
|
|
|
|
|
|
input_entry* Entry = Queue->Entries + Queue->QueueUsed++;
|
|
|
|
Entry->Key = Key;
|
|
|
|
|
|
|
|
Entry->State = (key_state_flags)0;
|
|
|
|
if (WasDown) { Entry->State |= KeyState_WasDown; }
|
|
|
|
if (IsDown) { Entry->State |= KeyState_IsDown; }
|
|
|
|
|
|
|
|
Entry->Modifiers = 0;
|
|
|
|
if (ShiftDown) { Entry->Modifiers |= Modifier_Shift; }
|
|
|
|
if (CtrlDown) { Entry->Modifiers |= Modifier_Ctrl; }
|
|
|
|
if (AltDown) { Entry->Modifiers |= Modifier_Alt; }
|
|
|
|
if (SysDown) { Entry->Modifiers |= Modifier_Sys; }
|
|
|
|
}
|
|
|
|
|
|
|
|
internal b32
|
|
|
|
KeyTransitionedDown (input_entry Entry)
|
|
|
|
{
|
2019-11-11 20:02:24 +00:00
|
|
|
return (!KeyWasDown(Entry.State) && KeyIsDown(Entry.State));
|
2019-10-30 14:28:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
internal b32
|
|
|
|
KeyTransitionedUp (input_entry Entry)
|
|
|
|
{
|
2019-11-11 20:02:24 +00:00
|
|
|
return (KeyWasDown(Entry.State) && !KeyIsDown(Entry.State));
|
2019-10-30 14:28:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
internal b32
|
|
|
|
KeyHeldDown (input_entry Entry)
|
|
|
|
{
|
2019-11-11 20:02:24 +00:00
|
|
|
return (KeyWasDown(Entry.State) && KeyIsDown(Entry.State));
|
|
|
|
}
|
|
|
|
|
|
|
|
internal b32
|
|
|
|
MouseButtonTransitionedDown (b32 MouseButtonState)
|
|
|
|
{
|
|
|
|
return (!KeyWasDown(MouseButtonState) && KeyIsDown(MouseButtonState));
|
|
|
|
}
|
|
|
|
|
|
|
|
internal b32
|
|
|
|
MouseButtonTransitionedUp (b32 MouseButtonState)
|
|
|
|
{
|
|
|
|
return (KeyWasDown(MouseButtonState) && !KeyIsDown(MouseButtonState));
|
|
|
|
}
|
|
|
|
|
|
|
|
internal b32
|
|
|
|
MouseButtonHeldDown (b32 MouseButtonState)
|
|
|
|
{
|
2019-12-27 00:23:43 +00:00
|
|
|
b32 WasDown = KeyWasDown(MouseButtonState);
|
|
|
|
b32 IsDown = KeyIsDown(MouseButtonState);
|
|
|
|
return (WasDown && IsDown);
|
2020-01-02 02:41:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#define GS_INPUT_H
|
|
|
|
#endif // GS_INPUT_H
|