Illusion Engine 08 - Input

Introduction

The input module of a game engine deals with most input from users, such as the keyboard, mouse, buttons, and so on. It builds a bridge between external input and the engine’s internal functionality.

It usually figures out all the important information about an input signal. For key input, we need to determine whether it is pressed or released, and how many times it is repeatedly pressed. For mouse input, we need to figure out the button code and the position of the cursor. Additionally, the Input class must be a static class so that its methods can be called outside of the class.

Implementation

Based on the information above, we can create a file called Input.h inside the Illusion/src/Engine/Core/Input/… folder and enter:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#pragma once

#include "Engine/Core/Core.h"

//--------------------namespace: Illusion starts--------------------
namespace Illusion
{

class Input
{

public:

// Static methods that could be used outside of this class
// Call the virtual function that would be implemented in the inhirated class
static bool IsKeyPressed(int keycode);

static bool IsMouseButtonPressed(int button);
static std::pair<float, float> GetMousePosition();
static float GetMouseX();
static float GetMouseY();

};
//--------------------namespace: Illusion ends--------------------
}

//----------------------- Key Codes -----------------------

/* Printable keys */
#define ILLUSION_KEY_SPACE 32
#define ILLUSION_KEY_APOSTROPHE 39 /* ' */
#define ILLUSION_KEY_COMMA 44 /* , */
#define ILLUSION_KEY_MINUS 45 /* - */
#define ILLUSION_KEY_PERIOD 46 /* . */
#define ILLUSION_KEY_SLASH 47 /* / */
#define ILLUSION_KEY_0 48
#define ILLUSION_KEY_1 49
#define ILLUSION_KEY_2 50
#define ILLUSION_KEY_3 51
#define ILLUSION_KEY_4 52
#define ILLUSION_KEY_5 53
#define ILLUSION_KEY_6 54
#define ILLUSION_KEY_7 55
#define ILLUSION_KEY_8 56
#define ILLUSION_KEY_9 57
#define ILLUSION_KEY_SEMICOLON 59 /* ; */
#define ILLUSION_KEY_EQUAL 61 /* = */
#define ILLUSION_KEY_A 65
#define ILLUSION_KEY_B 66
#define ILLUSION_KEY_C 67
#define ILLUSION_KEY_D 68
#define ILLUSION_KEY_E 69
#define ILLUSION_KEY_F 70
#define ILLUSION_KEY_G 71
#define ILLUSION_KEY_H 72
#define ILLUSION_KEY_I 73
#define ILLUSION_KEY_J 74
#define ILLUSION_KEY_K 75
#define ILLUSION_KEY_L 76
#define ILLUSION_KEY_M 77
#define ILLUSION_KEY_N 78
#define ILLUSION_KEY_O 79
#define ILLUSION_KEY_P 80
#define ILLUSION_KEY_Q 81
#define ILLUSION_KEY_R 82
#define ILLUSION_KEY_S 83
#define ILLUSION_KEY_T 84
#define ILLUSION_KEY_U 85
#define ILLUSION_KEY_V 86
#define ILLUSION_KEY_W 87
#define ILLUSION_KEY_X 88
#define ILLUSION_KEY_Y 89
#define ILLUSION_KEY_Z 90
#define ILLUSION_KEY_LEFT_BRACKET 91 /* [ */
#define ILLUSION_KEY_BACKSLASH 92 /* \ */
#define ILLUSION_KEY_RIGHT_BRACKET 93 /* ] */
#define ILLUSION_KEY_GRAVE_ACCENT 96 /* ` */
#define ILLUSION_KEY_WORLD_1 161 /* non-US #1 */
#define ILLUSION_KEY_WORLD_2 162 /* non-US #2 */

/* Function keys */
#define ILLUSION_KEY_ESCAPE 256
#define ILLUSION_KEY_ENTER 257
#define ILLUSION_KEY_TAB 258
#define ILLUSION_KEY_BACKSPACE 259
#define ILLUSION_KEY_INSERT 260
#define ILLUSION_KEY_DELETE 261
#define ILLUSION_KEY_RIGHT 262
#define ILLUSION_KEY_LEFT 263
#define ILLUSION_KEY_DOWN 264
#define ILLUSION_KEY_UP 265
#define ILLUSION_KEY_PAGE_UP 266
#define ILLUSION_KEY_PAGE_DOWN 267
#define ILLUSION_KEY_HOME 268
#define ILLUSION_KEY_END 269
#define ILLUSION_KEY_CAPS_LOCK 280
#define ILLUSION_KEY_SCROLL_LOCK 281
#define ILLUSION_KEY_NUM_LOCK 282
#define ILLUSION_KEY_PRINT_SCREEN 283
#define ILLUSION_KEY_PAUSE 284
#define ILLUSION_KEY_F1 290
#define ILLUSION_KEY_F2 291
#define ILLUSION_KEY_F3 292
#define ILLUSION_KEY_F4 293
#define ILLUSION_KEY_F5 294
#define ILLUSION_KEY_F6 295
#define ILLUSION_KEY_F7 296
#define ILLUSION_KEY_F8 297
#define ILLUSION_KEY_F9 298
#define ILLUSION_KEY_F10 299
#define ILLUSION_KEY_F11 300
#define ILLUSION_KEY_F12 301
#define ILLUSION_KEY_F13 302
#define ILLUSION_KEY_F14 303
#define ILLUSION_KEY_F15 304
#define ILLUSION_KEY_F16 305
#define ILLUSION_KEY_F17 306
#define ILLUSION_KEY_F18 307
#define ILLUSION_KEY_F19 308
#define ILLUSION_KEY_F20 309
#define ILLUSION_KEY_F21 310
#define ILLUSION_KEY_F22 311
#define ILLUSION_KEY_F23 312
#define ILLUSION_KEY_F24 313
#define ILLUSION_KEY_F25 314
#define ILLUSION_KEY_KP_0 320
#define ILLUSION_KEY_KP_1 321
#define ILLUSION_KEY_KP_2 322
#define ILLUSION_KEY_KP_3 323
#define ILLUSION_KEY_KP_4 324
#define ILLUSION_KEY_KP_5 325
#define ILLUSION_KEY_KP_6 326
#define ILLUSION_KEY_KP_7 327
#define ILLUSION_KEY_KP_8 328
#define ILLUSION_KEY_KP_9 329
#define ILLUSION_KEY_KP_DECIMAL 330
#define ILLUSION_KEY_KP_DIVIDE 331
#define ILLUSION_KEY_KP_MULTIPLY 332
#define ILLUSION_KEY_KP_SUBTRACT 333
#define ILLUSION_KEY_KP_ADD 334
#define ILLUSION_KEY_KP_ENTER 335
#define ILLUSION_KEY_KP_EQUAL 336
#define ILLUSION_KEY_LEFT_SHIFT 340
#define ILLUSION_KEY_LEFT_CONTROL 341
#define ILLUSION_KEY_LEFT_ALT 342
#define ILLUSION_KEY_LEFT_SUPER 343
#define ILLUSION_KEY_RIGHT_SHIFT 344
#define ILLUSION_KEY_RIGHT_CONTROL 345
#define ILLUSION_KEY_RIGHT_ALT 346
#define ILLUSION_KEY_RIGHT_SUPER 347
#define ILLUSION_KEY_MENU 348

//----------------------- Key Codes -----------------------

//------------------ Mouse Button Codes -------------------

// Mouse Button Code
#define ILLUSION_MOUSE_BUTTON_1 0
#define ILLUSION_MOUSE_BUTTON_2 1
#define ILLUSION_MOUSE_BUTTON_3 2
#define ILLUSION_MOUSE_BUTTON_4 3
#define ILLUSION_MOUSE_BUTTON_5 4
#define ILLUSION_MOUSE_BUTTON_6 5
#define ILLUSION_MOUSE_BUTTON_7 6
#define ILLUSION_MOUSE_BUTTON_8 7
#define ILLUSION_MOUSE_BUTTON_LAST ILLUSION_MOUSE_BUTTON_8
#define ILLUSION_MOUSE_BUTTON_LEFT ILLUSION_MOUSE_BUTTON_1
#define ILLUSION_MOUSE_BUTTON_RIGHT ILLUSION_MOUSE_BUTTON_2
#define ILLUSION_MOUSE_BUTTON_MIDDLE ILLUSION_MOUSE_BUTTON_3

//------------------ Mouse Button Codes -------------------
  • All methods in the Input class are static, so they can be called using code like: Illusion::Input::FunctionName(Argument list) without declaring any instance of Input class.
  • Under the definition of the Input class, we’ve defined a list of macros that represent the keycode and mouse button codes. The values of these codes correspond to those in the GLFW library, allowing us to use these macros in our code instead of those from the GLFW library.

To implement these methods, we need to use the interfaces provided by the GLFW library. Inside the same folder, create a file called Input.cpp and enter:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include "pch.h"
#include "Input.h"

#include "Engine/Core/Application/Application.h"

#include <GLFW/glfw3.h>

//--------------------namespace: Illusion starts--------------------

namespace Illusion
{

bool Input::IsKeyPressed(int keycode)
{
auto window = Application::Get().GetWindow().GetNativeWindow();
auto state = glfwGetKey(window, keycode);
return state == GLFW_PRESS || state == GLFW_REPEAT;
}

bool Input::IsMouseButtonPressed(int button)
{
auto window = Application::Get().GetWindow().GetNativeWindow();
auto state = glfwGetMouseButton(window, button);
return state == GLFW_PRESS;
}

std::pair<float, float> Input::GetMousePosition()
{
auto window = Application::Get().GetWindow().GetNativeWindow();
double xpos, ypos;
glfwGetCursorPos(window, &xpos, &ypos);
return { (float)xpos, (float)ypos };

}

float Input::GetMouseX()
{
auto [x, y] = GetMousePosition();
return x;
}

float Input::GetMouseY()
{
auto [x, y] = GetMousePosition();
return y;
}
//--------------------namespace: Illusion ends--------------------
}
  • We use Application::Get() to obtain the application instance, then .GetWindow() to get the previously defined window wrapper, and finally .GetNativeWindow() to get the GLFW window instance.

Utilization

To integrate the input module into the engine, we need to include the header file inside Engine.h.

There are two ways to use the Input module in the code:

  1. Use the code defined with Event dispatcher.
  2. Simply use the functions provided in the module.

For case 1, you can revise the TestLayer like this:

TestLayer.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#pragma once

#include <Engine.h>
class TestLayer : public Illusion::Layer
{
public:
TestLayer();
virtual ~TestLayer() = default;

virtual void OnAttach() override;
virtual void OnDetach() override;

void OnUpdate() override;
void OnEvent(Illusion::Event& event) override;

private:
void OnKeyPressed(Illusion::KeyPressedEvent&);
};

TestLayer.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include "TestLayer.h"
TestLayer::TestLayer()
:Layer("TestLayer"), m_CameraController(2560.0f / 1440.0f, true)
{}
void TestLayer::OnAttach() {}
void TestLayer::OnDetach() {}
void TestLayer::OnUpdate(Illusion::Timestep timestep)
{
// Render
// Set the clear color
// Clear the color buffer with the clear color
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void TestLayer::OnEvent(Illusion::Event& event)
{
Illusion::EventDispatcher dispatcher(e);
dispatcher.Dispatch<Illusion::KeyPressedEvent>(ENGINE_BIND_EVENT_FN(TestLayer::OnKeyPressed));
}

bool TestLayer::OnKeyPressed(Illusion::KeyPressedEvent& e)
{
ENGINE_CORE_TRACE(e.GetKeyCode());
return false;
}
  • The code above implements a function that will print whatever you press on the keyboard.

For case 2, you can revise the TestLayer like this:

TestLayer.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "TestLayer.h"
TestLayer::TestLayer()
:Layer("TestLayer"), m_CameraController(2560.0f / 1440.0f, true)
{}
void TestLayer::OnAttach() {}
void TestLayer::OnDetach() {}
void TestLayer::OnUpdate(Illusion::Timestep timestep)
{
// Render
// Set the clear color
// Clear the color buffer with the clear color
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

if(Illusion::Input::IsMouseButtonPressed(Illusion::ILLUSION_MOUSE_BUTTON_LEFT))
{
ENGINE_CORE_TARCE(Illusion::Input::GetMouseX());
ENGINE_CORE_TARCE(Illusion::Input::GetMouseY());
}
}
void TestLayer::OnEvent(Illusion::Event& event) {}
  • The code above will output the cursor’s position whenever you press the left mouse button.

Illusion Engine 08 - Input
https://rigel.github.io/Input/
Author
Rigel
Posted on
August 30, 2022
Licensed under