-
Notifications
You must be signed in to change notification settings - Fork 0
/
input.cpp
133 lines (122 loc) · 3.25 KB
/
input.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
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
#include <set>
#include <vector>
#include <iostream>
#include <cassert>
#include <GLFW/glfw3.h>
#include "input.hpp"
#include "tetris.hpp"
#include "client.hpp"
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
if (action == GLFW_PRESS) {
switch (key) {
case GLFW_KEY_LEFT:
case GLFW_KEY_J:
client::input(tetris::event::left);
break;
case GLFW_KEY_RIGHT:
case GLFW_KEY_L:
client::input(tetris::event::right);
break;
case GLFW_KEY_DOWN:
case GLFW_KEY_K:
client::input(tetris::event::down);
break;
case GLFW_KEY_SPACE:
client::input(tetris::event::drop);
break;
case GLFW_KEY_S:
client::input(tetris::event::spin_ccw);
break;
case GLFW_KEY_F:
client::input(tetris::event::spin_cw);
break;
case GLFW_KEY_E:
client::input(tetris::event::spin_180);
break;
case GLFW_KEY_D:
client::input(tetris::event::swap);
break;
default:
break;
}
}
}
static std::set<int> present;
struct state {
unsigned char buttons[15];
};
static state s[GLFW_JOYSTICK_LAST];
void handle_button(int button) {
switch (button) {
case GLFW_GAMEPAD_BUTTON_A: // X
client::input(tetris::event::drop);
break;
case GLFW_GAMEPAD_BUTTON_B: // O
client::input(tetris::event::spin_cw);
break;
case GLFW_GAMEPAD_BUTTON_X: // square
client::input(tetris::event::spin_ccw);
break;
case GLFW_GAMEPAD_BUTTON_Y: // triangle
client::input(tetris::event::spin_180);
break;
case GLFW_GAMEPAD_BUTTON_DPAD_UP:
client::input(tetris::event::swap);
break;
case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT:
client::input(tetris::event::right);
break;
case GLFW_GAMEPAD_BUTTON_DPAD_DOWN:
client::input(tetris::event::down);
break;
case GLFW_GAMEPAD_BUTTON_DPAD_LEFT:
client::input(tetris::event::left);
break;
default:
break;
}
}
void input::poll_gamepads() {
std::set<int>::iterator it;
int jid;
GLFWgamepadstate gamepad;
for (it = present.begin(); it != present.end(); it++) {
jid = *it;
if (glfwGetGamepadState(jid, &gamepad))
for (int button = 0; button < 15; button++) {
if (gamepad.buttons[button] == GLFW_PRESS && s[jid].buttons[button] != GLFW_PRESS) {
//std::cerr << jid << " press " << button << '\n';
handle_button(button);
}
s[jid].buttons[button] = gamepad.buttons[button];
}
}
}
void reset_buttons(int jid) {
for (int button = 0; button < 15; button++) {
s[jid].buttons[button] = GLFW_RELEASE;
}
}
void joystick_callback(int jid, int event) {
assert(jid < GLFW_JOYSTICK_LAST);
if (event == GLFW_CONNECTED) {
std::cerr << "joystick connected " << jid << '\n';
if (glfwJoystickIsGamepad(jid)) {
reset_buttons(jid);
present.insert(jid);
} else
std::cerr << "not a gamepad " << jid << '\n';
} else if (event == GLFW_DISCONNECTED)
present.erase(jid);
}
void input::init(GLFWwindow *window) {
present.clear();
for (int jid = GLFW_JOYSTICK_1; jid < GLFW_JOYSTICK_LAST; jid++) {
if (glfwJoystickPresent(jid)) {
reset_buttons(jid);
present.insert(jid);
}
}
glfwSetJoystickCallback(joystick_callback);
glfwSetKeyCallback(window, key_callback);
}