1 //========================================================================
2 // Joystick input test
3 // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
4 //
5 // This software is provided 'as-is', without any express or implied
6 // warranty. In no event will the authors be held liable for any damages
7 // arising from the use of this software.
8 //
9 // Permission is granted to anyone to use this software for any purpose,
10 // including commercial applications, and to alter it and redistribute it
11 // freely, subject to the following restrictions:
12 //
13 // 1. The origin of this software must not be misrepresented; you must not
14 // claim that you wrote the original software. If you use this software
15 // in a product, an acknowledgment in the product documentation would
16 // be appreciated but is not required.
17 //
18 // 2. Altered source versions must be plainly marked as such, and must not
19 // be misrepresented as being the original software.
20 //
21 // 3. This notice may not be removed or altered from any source
22 // distribution.
23 //
24 //========================================================================
25 //
26 // This test displays the state of every button and axis of every connected
27 // joystick and/or gamepad
28 //
29 //========================================================================
30
31 #include <glad/glad.h>
32 #include <GLFW/glfw3.h>
33
34 #include <stdio.h>
35 #include <string.h>
36 #include <stdlib.h>
37
38 #ifdef _MSC_VER
39 #define strdup(x) _strdup(x)
40 #endif
41
42 static int joysticks[GLFW_JOYSTICK_LAST + 1];
43 static int joystick_count = 0;
44
error_callback(int error,const char * description)45 static void error_callback(int error, const char* description)
46 {
47 fprintf(stderr, "Error: %s\n", description);
48 }
49
framebuffer_size_callback(GLFWwindow * window,int width,int height)50 static void framebuffer_size_callback(GLFWwindow* window, int width, int height)
51 {
52 glViewport(0, 0, width, height);
53 }
54
draw_joystick(int index,int x,int y,int width,int height)55 static void draw_joystick(int index, int x, int y, int width, int height)
56 {
57 int i;
58 int axis_count, button_count;
59 const float* axes;
60 const unsigned char* buttons;
61 const int axis_height = 3 * height / 4;
62 const int button_height = height / 4;
63
64 axes = glfwGetJoystickAxes(joysticks[index], &axis_count);
65 if (axis_count)
66 {
67 const int axis_width = width / axis_count;
68
69 for (i = 0; i < axis_count; i++)
70 {
71 float value = axes[i] / 2.f + 0.5f;
72
73 glColor3f(0.3f, 0.3f, 0.3f);
74 glRecti(x + i * axis_width,
75 y,
76 x + (i + 1) * axis_width,
77 y + axis_height);
78
79 glColor3f(1.f, 1.f, 1.f);
80 glRecti(x + i * axis_width,
81 y + (int) (value * (axis_height - 5)),
82 x + (i + 1) * axis_width,
83 y + 5 + (int) (value * (axis_height - 5)));
84 }
85 }
86
87 buttons = glfwGetJoystickButtons(joysticks[index], &button_count);
88 if (button_count)
89 {
90 const int button_width = width / button_count;
91
92 for (i = 0; i < button_count; i++)
93 {
94 if (buttons[i])
95 glColor3f(1.f, 1.f, 1.f);
96 else
97 glColor3f(0.3f, 0.3f, 0.3f);
98
99 glRecti(x + i * button_width,
100 y + axis_height,
101 x + (i + 1) * button_width,
102 y + axis_height + button_height);
103 }
104 }
105 }
106
draw_joysticks(GLFWwindow * window)107 static void draw_joysticks(GLFWwindow* window)
108 {
109 int i, width, height, offset = 0;
110
111 glfwGetFramebufferSize(window, &width, &height);
112
113 glMatrixMode(GL_PROJECTION);
114 glLoadIdentity();
115 glOrtho(0.f, width, height, 0.f, 1.f, -1.f);
116 glMatrixMode(GL_MODELVIEW);
117
118 for (i = 0; i < joystick_count; i++)
119 {
120 draw_joystick(i,
121 0, offset * height / joystick_count,
122 width, height / joystick_count);
123 offset++;
124 }
125 }
126
joystick_callback(int joy,int event)127 static void joystick_callback(int joy, int event)
128 {
129 if (event == GLFW_CONNECTED)
130 {
131 int axis_count, button_count;
132
133 glfwGetJoystickAxes(joy, &axis_count);
134 glfwGetJoystickButtons(joy, &button_count);
135
136 printf("Found joystick %i named \'%s\' with %i axes, %i buttons\n",
137 joy + 1,
138 glfwGetJoystickName(joy),
139 axis_count,
140 button_count);
141
142 joysticks[joystick_count++] = joy;
143 }
144 else if (event == GLFW_DISCONNECTED)
145 {
146 int i;
147
148 for (i = 0; i < joystick_count; i++)
149 {
150 if (joysticks[i] == joy)
151 break;
152 }
153
154 for (i = i + 1; i < joystick_count; i++)
155 joysticks[i - 1] = joysticks[i];
156
157 printf("Lost joystick %i\n", joy + 1);
158 joystick_count--;
159 }
160 }
161
find_joysticks(void)162 static void find_joysticks(void)
163 {
164 int joy;
165
166 for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++)
167 {
168 if (glfwJoystickPresent(joy))
169 joystick_callback(joy, GLFW_CONNECTED);
170 }
171 }
172
main(void)173 int main(void)
174 {
175 GLFWwindow* window;
176
177 memset(joysticks, 0, sizeof(joysticks));
178
179 glfwSetErrorCallback(error_callback);
180
181 if (!glfwInit())
182 exit(EXIT_FAILURE);
183
184 find_joysticks();
185 glfwSetJoystickCallback(joystick_callback);
186
187 window = glfwCreateWindow(640, 480, "Joystick Test", NULL, NULL);
188 if (!window)
189 {
190 glfwTerminate();
191 exit(EXIT_FAILURE);
192 }
193
194 glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
195
196 glfwMakeContextCurrent(window);
197 gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
198 glfwSwapInterval(1);
199
200 while (!glfwWindowShouldClose(window))
201 {
202 glClear(GL_COLOR_BUFFER_BIT);
203
204 draw_joysticks(window);
205
206 glfwSwapBuffers(window);
207 glfwPollEvents();
208
209 // Workaround for an issue with msvcrt and mintty
210 fflush(stdout);
211 }
212
213 glfwTerminate();
214 exit(EXIT_SUCCESS);
215 }
216
217