-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathjoystick.c.m4
340 lines (307 loc) · 9.63 KB
/
joystick.c.m4
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
/* -*- mode: C -*- */
#include "rubysdl2_internal.h"
#include <SDL_joystick.h>
#include <SDL_gamecontroller.h>
static VALUE cJoystick;
static VALUE cDeviceInfo;
static VALUE mHat;
typedef struct Joystick {
SDL_Joystick* joystick;
} Joystick;
static void Joystick_free(Joystick* j)
{
if (rubysdl2_is_active() && j->joystick)
SDL_JoystickClose(j->joystick);
free(j);
}
static VALUE Joystick_new(SDL_Joystick* joystick)
{
Joystick* j = ALLOC(Joystick);
j->joystick = joystick;
return Data_Wrap_Struct(cJoystick, 0, Joystick_free, j);
}
DEFINE_WRAPPER(SDL_Joystick, Joystick, joystick, cJoystick, "SDL2::Joystick");
/*
* Document-class: SDL2::Joystick
*
* This class represents a joystick connected to the machine.
*
* In order to use joystick subsystem, {SDL2.init} must have been called
* with the SDL2::INIT_JOYSTICK flag.
*
* @!method destroy?
* Return true if the device is alread closed.
* @see #destroy
*/
/*
* Get the number of connected joysticks.
*
* @return [Integer]
*/
static VALUE Joystick_s_num_connected_joysticks(VALUE self)
{
return INT2FIX(HANDLE_ERROR(SDL_NumJoysticks()));
}
static VALUE GUID_to_String(SDL_JoystickGUID guid)
{
char buf[128];
SDL_JoystickGetGUIDString(guid, buf, sizeof(buf));
return rb_usascii_str_new_cstr(buf);
}
/*
* Get the information of connected joysticks
*
* @return [Array<SDL2::Joystick::DeviceInfo>] information of connected devices
*/
static VALUE Joystick_s_devices(VALUE self)
{
int num_joysticks = SDL_NumJoysticks();
int i;
VALUE devices = rb_ary_new2(num_joysticks);
for (i=0; i<num_joysticks; ++i) {
VALUE device = rb_obj_alloc(cDeviceInfo);
rb_iv_set(device, "@GUID", GUID_to_String(SDL_JoystickGetDeviceGUID(i)));
rb_iv_set(device, "@name", utf8str_new_cstr(SDL_JoystickNameForIndex(i)));
rb_ary_push(devices, device);
}
return devices;
}
/*
* @overload open(device_index)
* Open a joystick for use.
*
* @param [Integer] device_index device index
* @return [SDL2::Joystick] opended joystick object
* @raise [SDL2::Error] raised when device open is failed.
* for exmaple, device_index is out of range.
*/
static VALUE Joystick_s_open(VALUE self, VALUE device_index)
{
SDL_Joystick* joystick = SDL_JoystickOpen(NUM2INT(device_index));
if (!joystick)
SDL_ERROR();
return Joystick_new(joystick);
}
/*
* @overload game_controller?(index)
* Return true if the joystick of given index supports the game controller
* interface.
*
* @param [Integer] index the joystick device index
* @return [Boolean]
* @see SDL2::GameController
*
*/
static VALUE Joystick_s_game_controller_p(VALUE self, VALUE index)
{
return INT2BOOL(SDL_IsGameController(NUM2INT(index)));
}
/*
* Return true a joystick has been opened and currently connected.
*/
static VALUE Joystick_attached_p(VALUE self)
{
Joystick* j = Get_Joystick(self);
if (!j->joystick)
return Qfalse;
return INT2BOOL(SDL_JoystickGetAttached(j->joystick));
}
/*
* Get the joystick GUID
*
* @return [String] GUID string
*/
static VALUE Joystick_GUID(VALUE self)
{
SDL_JoystickGUID guid;
char buf[128];
guid = SDL_JoystickGetGUID(Get_SDL_Joystick(self));
SDL_JoystickGetGUIDString(guid, buf, sizeof(buf));
return rb_usascii_str_new_cstr(buf);
}
/*
* Get the index of a joystick
*
* @return [Integer] index
*/
static VALUE Joystick_index(VALUE self)
{
return INT2NUM(HANDLE_ERROR(SDL_JoystickInstanceID(Get_SDL_Joystick(self))));
}
/*
* Close a joystick device.
*
* @return [nil]
* @see #destroy?
*/
static VALUE Joystick_destroy(VALUE self)
{
Joystick* j = Get_Joystick(self);
if (j->joystick)
SDL_JoystickClose(j->joystick);
j->joystick = NULL;
return Qnil;
}
/*
* Get the name of a joystick
*
* @return [String] name
*/
static VALUE Joystick_name(VALUE self)
{
return utf8str_new_cstr(SDL_JoystickName(Get_SDL_Joystick(self)));
}
/*
* Get the number of general axis controls on a joystick.
* @return [Integer]
* @see #axis
*/
static VALUE Joystick_num_axes(VALUE self)
{
return INT2FIX(SDL_JoystickNumAxes(Get_SDL_Joystick(self)));
}
/*
* Get the number of trackball on a joystick
* @return [Integer]
* @see #ball
*/
static VALUE Joystick_num_balls(VALUE self)
{
return INT2FIX(SDL_JoystickNumBalls(Get_SDL_Joystick(self)));
}
/*
* Get the number of button on a joystick
* @return [Integer]
* @see #button
*/
static VALUE Joystick_num_buttons(VALUE self)
{
return INT2FIX(SDL_JoystickNumButtons(Get_SDL_Joystick(self)));
}
/*
* Get the number of POV hats on a joystick
* @return [Integer]
* @see #hat
*/
static VALUE Joystick_num_hats(VALUE self)
{
return INT2FIX(SDL_JoystickNumHats(Get_SDL_Joystick(self)));
}
/*
* @overload axis(which)
* Get the current state of an axis control on a joystick.
*
* @param [Integer] which an index of an axis, started at index 0
* @return [Integer] state value, ranging from -32768 to 32767.
* @see #num_axes
*/
static VALUE Joystick_axis(VALUE self, VALUE which)
{
return INT2FIX(SDL_JoystickGetAxis(Get_SDL_Joystick(self), NUM2INT(which)));
}
/*
* @overload ball(which)
* Get the current state of a trackball on a joystick.
*
* @param [Integer] which an index of a trackball, started at index 0
* @return [Array(Integer,Integer)] dx and dy
* @see #num_balls
*/
static VALUE Joystick_ball(VALUE self, VALUE which)
{
int dx, dy;
HANDLE_ERROR(SDL_JoystickGetBall(Get_SDL_Joystick(self), NUM2INT(which), &dx, &dy));
return rb_ary_new3(2, INT2NUM(dx), INT2NUM(dy));
}
/*
* @overload button(which)
* Get the current state of a button on a joystick.
*
* @param [Integer] which an index of a button, started at index 0
* @return [Boolean] true if the button is pressed
* @see #num_buttons
*/
static VALUE Joystick_button(VALUE self, VALUE which)
{
return INT2BOOL(SDL_JoystickGetButton(Get_SDL_Joystick(self), NUM2INT(which)));
}
/*
* @overload hat(which)
* Get the current state of a POV hat on a joystick.
*
* @param [Integer] which an index of a hat, started at index 0
* @return [Integer] hat state
* @see #num_hats
*/
static VALUE Joystick_hat(VALUE self, VALUE which)
{
return UINT2NUM(SDL_JoystickGetHat(Get_SDL_Joystick(self), NUM2INT(which)));
}
/*
* Document-class: SDL2::Joystick::DeviceInfo
*
* This class represents joystick device information, its name and GUID.
*
* You can get the information with {SDL2::Joystick.devices}.
*/
/*
* Document-module: SDL2::Joystick::Hat
*
* This module provides constants of joysticks's hat positions used by {SDL2::Joystick} class.
* The position of the hat is represented by OR'd bits of {RIGHT}, {LEFT}, {UP}, and {DOWN}.
* This means the center position ({CENTERED}) is represeted by 0 and
* the left up position {LEFTUP} is represeted by ({LEFT}|{UP}).
*/
void rubysdl2_init_joystick(void)
{
cJoystick = rb_define_class_under(mSDL2, "Joystick", rb_cObject);
cDeviceInfo = rb_define_class_under(cJoystick, "DeviceInfo", rb_cObject);
rb_define_singleton_method(cJoystick, "num_connected_joysticks",
Joystick_s_num_connected_joysticks, 0);
rb_define_singleton_method(cJoystick, "devices", Joystick_s_devices, 0);
rb_define_singleton_method(cJoystick, "open", Joystick_s_open, 1);
rb_define_singleton_method(cJoystick, "game_controller?",
Joystick_s_game_controller_p, 1);
rb_define_method(cJoystick, "destroy?", Joystick_destroy_p, 0);
rb_define_alias(cJoystick, "close?", "destroy?");
rb_define_method(cJoystick, "attached?", Joystick_attached_p, 0);
rb_define_method(cJoystick, "GUID", Joystick_GUID, 0);
rb_define_method(cJoystick, "index", Joystick_index, 0);
rb_define_method(cJoystick, "destroy", Joystick_destroy, 0);
rb_define_alias(cJoystick, "close", "destroy");
rb_define_method(cJoystick, "name", Joystick_name, 0);
rb_define_method(cJoystick, "num_axes", Joystick_num_axes, 0);
rb_define_method(cJoystick, "num_balls", Joystick_num_balls, 0);
rb_define_method(cJoystick, "num_buttons", Joystick_num_buttons, 0);
rb_define_method(cJoystick, "num_hats", Joystick_num_hats, 0);
rb_define_method(cJoystick, "axis", Joystick_axis, 1);
rb_define_method(cJoystick, "ball", Joystick_ball, 1);
rb_define_method(cJoystick, "button", Joystick_button, 1);
rb_define_method(cJoystick, "hat", Joystick_hat, 1);
mHat = rb_define_module_under(cJoystick, "Hat");
/* define(`DEFINE_JOY_HAT_CONST',`rb_define_const(mHat, "$1", INT2NUM(SDL_HAT_$1))') */
/* @return [Integer] hat state\: Center position. Equal to 0. */
DEFINE_JOY_HAT_CONST(CENTERED);
/* @return [Integer] hat state\: Up position. */
DEFINE_JOY_HAT_CONST(UP);
/* @return [Integer] hat state\: Right position. */
DEFINE_JOY_HAT_CONST(RIGHT);
/* @return [Integer] hat state\: Down position. */
DEFINE_JOY_HAT_CONST(DOWN);
/* @return [Integer] hat state\: Left position. */
DEFINE_JOY_HAT_CONST(LEFT);
/* @return [Integer] hat state\: Right Up position. Equal to ({RIGHT} | {UP}) */
DEFINE_JOY_HAT_CONST(RIGHTUP);
/* @return [Integer] hat state\: Right Down position. Equal to ({RIGHT} | {DOWN}) */
DEFINE_JOY_HAT_CONST(RIGHTDOWN);
/* @return [Integer] hat state\: Left Up position. Equal to ({LEFT} | {UP}) */
DEFINE_JOY_HAT_CONST(LEFTUP);
/* @return [Integer] hat state\: Left Down position. Equal to ({LEFT} | {DOWN}) */
DEFINE_JOY_HAT_CONST(LEFTDOWN);
/* Device GUID
* @return [String] */
rb_define_attr(cDeviceInfo, "GUID", 1, 0);
/* Device name
* @return [String] */
rb_define_attr(cDeviceInfo, "name", 1, 0);
}