ruby-sdl2 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,10 @@
1
+ /* -*- mode: C -*- */
1
2
  #include "rubysdl2_internal.h"
2
3
  #include <SDL_gamecontroller.h>
3
4
 
4
5
  static VALUE cGameController;
6
+ static VALUE mAxis;
7
+ static VALUE mButton;
5
8
 
6
9
  typedef struct GameController {
7
10
  SDL_GameController* controller;
@@ -14,6 +17,47 @@ static void GameController_free(GameController* g)
14
17
  free(g);
15
18
  }
16
19
 
20
+ /*
21
+ * Document-class: SDL2::GameController
22
+ *
23
+ * This class represents a "Game Controller".
24
+ *
25
+ * In SDL2, there is a gamecontroller framework to
26
+ * hide the details of joystick types. This framework
27
+ * is built on the existing joystick API.
28
+ *
29
+ * The framework consists of two parts:
30
+ *
31
+ * * Mapping joysticks to game controllers
32
+ * * Aquire input from game controllers
33
+ *
34
+ * Mapping information is a string, and described as:
35
+ *
36
+ * GUID,name,mapping
37
+ *
38
+ * GUID is a unique ID of a type of joystick and
39
+ * given by {Joystick#GUID}. name is the human readable
40
+ * string for the device, and mappings are contorller mappings
41
+ * to joystick ones.
42
+ *
43
+ * This mappings abstract the details of joysticks, for exmaple,
44
+ * the number of buttons, the number of axes, and the position
45
+ * of these buttons a on pad.
46
+ * You can use unified interface
47
+ * with this framework theoretically.
48
+ * Howerver, we need to prepare the
49
+ * database of many joysticks that users will use. A database
50
+ * is available at https://github.com/gabomdq/SDL_GameControllerDB,
51
+ * but perhaps this is not sufficient for your usage.
52
+ * In fact, Steam prepares its own database for Steam games,
53
+ * so if you will create a game for Steam, this framework is
54
+ * useful. Otherwise, it is a better way to use joystick API
55
+ * directly.
56
+ *
57
+ * @!method destroy?
58
+ * Return true if the gamecontroller is already closed.
59
+ */
60
+
17
61
  static VALUE GameController_new(SDL_GameController* controller)
18
62
  {
19
63
  GameController* g = ALLOC(GameController);
@@ -25,12 +69,44 @@ DEFINE_WRAPPER(SDL_GameController, GameController, controller, cGameController,
25
69
  "SDL2::GameController");
26
70
 
27
71
 
72
+ /*
73
+ * @overload add_mapping(string)
74
+ *
75
+ * Add suuport for controolers that SDL is unaware of or to cause an
76
+ * existing controller to have a different binding.
77
+ *
78
+ * "GUID,name,mapping", where GUID is
79
+ * the string value from SDL_JoystickGetGUIDString(), name is the human
80
+ * readable string for the device and mappings are controller mappings to
81
+ * joystick ones. Under Windows there is a reserved GUID of "xinput" that
82
+ * covers all XInput devices. The mapping format for joystick is:
83
+ *
84
+ * * bX: a joystick button, index X
85
+ * * hX.Y: hat X with value Y
86
+ * * aX: axis X of the joystick
87
+ *
88
+ * Buttons can be used as a controller axes and vice versa.
89
+ *
90
+ * This string shows an example of a valid mapping for a controller:
91
+ * "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7"
92
+ *
93
+ * @param string [String] mapping string
94
+ * @return [Integer] 1 if a new mapping, 0 if an existing mapping is updated.
95
+ */
28
96
  static VALUE GameController_s_add_mapping(VALUE self, VALUE string)
29
97
  {
30
98
  int ret = HANDLE_ERROR(SDL_GameControllerAddMapping(StringValueCStr(string)));
31
99
  return INT2NUM(ret);
32
100
  }
33
101
 
102
+ /*
103
+ * @overload axis_name_of(axis)
104
+ *
105
+ * Get a string representing **axis**.
106
+ *
107
+ * @param axis [Integer] axis constant in {Axis}
108
+ * @return [String]
109
+ */
34
110
  static VALUE GameController_s_axis_name_of(VALUE self, VALUE axis)
35
111
  {
36
112
  const char* name = SDL_GameControllerGetStringForAxis(NUM2INT(axis));
@@ -41,6 +117,14 @@ static VALUE GameController_s_axis_name_of(VALUE self, VALUE axis)
41
117
  return utf8str_new_cstr(name);
42
118
  }
43
119
 
120
+ /*
121
+ * @overload button_name_of(button)
122
+ *
123
+ * Get a string representing **button**.
124
+ *
125
+ * @param button [Integer] button constant in {Button}
126
+ * @return [String]
127
+ */
44
128
  static VALUE GameController_s_button_name_of(VALUE self, VALUE button)
45
129
  {
46
130
  const char* name = SDL_GameControllerGetStringForButton(NUM2INT(button));
@@ -51,6 +135,17 @@ static VALUE GameController_s_button_name_of(VALUE self, VALUE button)
51
135
  return utf8str_new_cstr(name);
52
136
  }
53
137
 
138
+ /*
139
+ * @overload axis_from_name(name)
140
+ *
141
+ * Get a integer representation of the axis
142
+ * whose string representation is **name**.
143
+ *
144
+ * The return value is the value of one of the constants in {Axis}
145
+ *
146
+ * @param name [String] a string representing an axis
147
+ * @return [Integer]
148
+ */
54
149
  static VALUE GameController_s_axis_from_name(VALUE self, VALUE name)
55
150
  {
56
151
  int axis = SDL_GameControllerGetAxisFromString(StringValueCStr(name));
@@ -61,6 +156,17 @@ static VALUE GameController_s_axis_from_name(VALUE self, VALUE name)
61
156
  return INT2FIX(axis);
62
157
  }
63
158
 
159
+ /*
160
+ * @overload button_from_name(name)
161
+ *
162
+ * Get a integer representation of the button
163
+ * whose string representation is **name**.
164
+ *
165
+ * The return value is the value of one of the constants in {Button}
166
+ *
167
+ * @param name [String] a string representing a button
168
+ * @return [Integer]
169
+ */
64
170
  static VALUE GameController_s_button_from_name(VALUE self, VALUE name)
65
171
  {
66
172
  int button = SDL_GameControllerGetButtonFromString(StringValueCStr(name));
@@ -71,6 +177,15 @@ static VALUE GameController_s_button_from_name(VALUE self, VALUE name)
71
177
  return INT2FIX(button);
72
178
  }
73
179
 
180
+ /*
181
+ * Get the implementation dependent name for the game controllers
182
+ * connected to the machine.
183
+ *
184
+ * The number of elements of returning array is same as
185
+ * {Joystick.num_connected_joysticks}.
186
+ *
187
+ * @return [Array<String,nil>]
188
+ */
74
189
  static VALUE GameController_s_device_names(VALUE self)
75
190
  {
76
191
  int num_joysticks = SDL_NumJoysticks();
@@ -86,12 +201,30 @@ static VALUE GameController_s_device_names(VALUE self)
86
201
  return device_names;
87
202
  }
88
203
 
204
+ /*
205
+ * @overload mapping_for(guid_string)
206
+ * Get the game controller mapping string for a given GUID.
207
+ *
208
+ * @param guid_string [String] GUID string
209
+ *
210
+ * @return [String]
211
+ */
89
212
  static VALUE GameController_s_mapping_for(VALUE self, VALUE guid_string)
90
213
  {
91
214
  SDL_JoystickGUID guid = SDL_JoystickGetGUIDFromString(StringValueCStr(guid_string));
92
215
  return utf8str_new_cstr(SDL_GameControllerMappingForGUID(guid));
93
216
  }
94
217
 
218
+ /*
219
+ * @overload open(index)
220
+ * Open a game controller and return the opened GameController object.
221
+ *
222
+ * @param index [Integer] device index, up to the return value of {Joystick.num_connected_joysticks}.
223
+ * @return [SDL2::GameController]
224
+ *
225
+ * @raise [SDL2::Error] raised when device open is failed.
226
+ * For exmaple, **index** is out of range.
227
+ */
95
228
  static VALUE GameController_s_open(VALUE self, VALUE index)
96
229
  {
97
230
  SDL_GameController* controller = SDL_GameControllerOpen(NUM2INT(index));
@@ -100,16 +233,33 @@ static VALUE GameController_s_open(VALUE self, VALUE index)
100
233
  return GameController_new(controller);
101
234
  }
102
235
 
236
+ /*
237
+ * Get the name of an opened game controller.
238
+ *
239
+ * @return [String]
240
+ */
103
241
  static VALUE GameController_name(VALUE self)
104
242
  {
105
- return utf8str_new_cstr(SDL_GameControllerName(Get_SDL_GameController(self)));
243
+ const char* name = SDL_GameControllerName(Get_SDL_GameController(self));
244
+ if (!name)
245
+ SDL_ERROR();
246
+
247
+ return utf8str_new_cstr(name);
106
248
  }
107
249
 
250
+ /*
251
+ * Return true if **self** is opened and attached.
252
+ */
108
253
  static VALUE GameController_attached_p(VALUE self)
109
254
  {
110
255
  return INT2BOOL(SDL_GameControllerGetAttached(Get_SDL_GameController(self)));
111
256
  }
112
257
 
258
+ /*
259
+ * Close the game controller.
260
+ *
261
+ * @return nil
262
+ */
113
263
  static VALUE GameController_destroy(VALUE self)
114
264
  {
115
265
  GameController* g = Get_GameController(self);
@@ -119,23 +269,59 @@ static VALUE GameController_destroy(VALUE self)
119
269
  return Qnil;
120
270
  }
121
271
 
272
+ /*
273
+ * Get the mapping string of **self**.
274
+ *
275
+ * @return [String]
276
+ * @see .add_mapping
277
+ * @see .mapping_for
278
+ */
122
279
  static VALUE GameController_mapping(VALUE self)
123
280
  {
124
281
  return utf8str_new_cstr(SDL_GameControllerMapping(Get_SDL_GameController(self)));
125
282
  }
126
283
 
284
+ /*
285
+ * @overload axis(axis)
286
+ * Get the state of an axis control.
287
+ *
288
+ * The state is an integer from -32768 to 32767.
289
+ * The state of trigger never returns negative value (from 0 to 32767).
290
+ *
291
+ * @param axis [Integer] the index of an axis, one of the constants in {Axis}
292
+ * @return [Integer]
293
+ */
127
294
  static VALUE GameController_axis(VALUE self, VALUE axis)
128
295
  {
129
296
  return INT2FIX(SDL_GameControllerGetAxis(Get_SDL_GameController(self),
130
297
  NUM2INT(axis)));
131
298
  }
132
299
 
300
+ /*
301
+ * @overload button_pressed?(button)
302
+ * Return true if a button is pressed.
303
+ *
304
+ * @param button [Integer] the index of a button, one of the constants in {Button}
305
+ */
133
306
  static VALUE GameController_button_pressed_p(VALUE self, VALUE button)
134
307
  {
135
308
  return INT2BOOL(SDL_GameControllerGetButton(Get_SDL_GameController(self),
136
309
  NUM2INT(button)));
137
310
  }
138
311
 
312
+ /*
313
+ * Document-module: SDL2::GameController::Axis
314
+ *
315
+ * This module provides constants of gamecontroller's axis indices used by
316
+ * {SDL2::GameController} class.
317
+ */
318
+
319
+ /*
320
+ * Document-module: SDL2::GameController::Button
321
+ *
322
+ * This module provides constants of gamecontroller's button indices used by
323
+ * {SDL2::GameController} class.
324
+ */
139
325
  void rubysdl2_init_gamecontorller(void)
140
326
  {
141
327
  cGameController = rb_define_class_under(mSDL2, "GameController", rb_cObject);
@@ -162,33 +348,61 @@ void rubysdl2_init_gamecontorller(void)
162
348
  rb_define_method(cGameController, "mapping", GameController_mapping, 0);
163
349
  rb_define_method(cGameController, "axis", GameController_axis, 1);
164
350
  rb_define_method(cGameController, "button_pressed?", GameController_button_pressed_p, 1);
165
- #define DEFINE_CONTROLLER_AXIS_CONST(type) \
166
- rb_define_const(cGameController, "AXIS_" #type, INT2NUM(SDL_CONTROLLER_AXIS_##type))
167
- DEFINE_CONTROLLER_AXIS_CONST(INVALID);
168
- DEFINE_CONTROLLER_AXIS_CONST(LEFTX);
169
- DEFINE_CONTROLLER_AXIS_CONST(LEFTY);
170
- DEFINE_CONTROLLER_AXIS_CONST(RIGHTX);
171
- DEFINE_CONTROLLER_AXIS_CONST(RIGHTY);
172
- DEFINE_CONTROLLER_AXIS_CONST(TRIGGERLEFT);
173
- DEFINE_CONTROLLER_AXIS_CONST(TRIGGERRIGHT);
174
- DEFINE_CONTROLLER_AXIS_CONST(MAX);
175
- #define DEFINE_CONTROLLER_BUTTON_CONST(type) \
176
- rb_define_const(cGameController, "BUTTON_" #type, INT2NUM(SDL_CONTROLLER_BUTTON_##type))
177
- DEFINE_CONTROLLER_BUTTON_CONST(INVALID);
178
- DEFINE_CONTROLLER_BUTTON_CONST(A);
179
- DEFINE_CONTROLLER_BUTTON_CONST(B);
180
- DEFINE_CONTROLLER_BUTTON_CONST(X);
181
- DEFINE_CONTROLLER_BUTTON_CONST(Y);
182
- DEFINE_CONTROLLER_BUTTON_CONST(BACK);
183
- DEFINE_CONTROLLER_BUTTON_CONST(GUIDE);
184
- DEFINE_CONTROLLER_BUTTON_CONST(START);
185
- DEFINE_CONTROLLER_BUTTON_CONST(LEFTSTICK);
186
- DEFINE_CONTROLLER_BUTTON_CONST(RIGHTSTICK);
187
- DEFINE_CONTROLLER_BUTTON_CONST(LEFTSHOULDER);
188
- DEFINE_CONTROLLER_BUTTON_CONST(RIGHTSHOULDER);
189
- DEFINE_CONTROLLER_BUTTON_CONST(DPAD_UP);
190
- DEFINE_CONTROLLER_BUTTON_CONST(DPAD_DOWN);
191
- DEFINE_CONTROLLER_BUTTON_CONST(DPAD_LEFT);
192
- DEFINE_CONTROLLER_BUTTON_CONST(DPAD_RIGHT);
193
- DEFINE_CONTROLLER_BUTTON_CONST(MAX);
351
+
352
+ mAxis = rb_define_module_under(cGameController, "Axis");
353
+ mButton = rb_define_module_under(cGameController, "Button");
354
+
355
+ /* */
356
+ /* Invalid axis index */
357
+ rb_define_const(mAxis, "INVALID", INT2NUM(SDL_CONTROLLER_AXIS_INVALID));
358
+ /* Left X axis */
359
+ rb_define_const(mAxis, "LEFTX", INT2NUM(SDL_CONTROLLER_AXIS_LEFTX));
360
+ /* Left Y axis */
361
+ rb_define_const(mAxis, "LEFTY", INT2NUM(SDL_CONTROLLER_AXIS_LEFTY));
362
+ /* Right X axis */
363
+ rb_define_const(mAxis, "RIGHTX", INT2NUM(SDL_CONTROLLER_AXIS_RIGHTX));
364
+ /* Right Y axis */
365
+ rb_define_const(mAxis, "RIGHTY", INT2NUM(SDL_CONTROLLER_AXIS_RIGHTY));
366
+ /* Left trigger axis */
367
+ rb_define_const(mAxis, "TRIGGERLEFT", INT2NUM(SDL_CONTROLLER_AXIS_TRIGGERLEFT));
368
+ /* Right trigger axis */
369
+ rb_define_const(mAxis, "TRIGGERRIGHT", INT2NUM(SDL_CONTROLLER_AXIS_TRIGGERRIGHT));
370
+ /* The max of an axis index */
371
+ rb_define_const(mAxis, "MAX", INT2NUM(SDL_CONTROLLER_AXIS_MAX));
372
+
373
+ /* */
374
+ /* Invalid button index */
375
+ rb_define_const(mButton, "INVALID", INT2NUM(SDL_CONTROLLER_BUTTON_INVALID));
376
+ /* Button A */
377
+ rb_define_const(mButton, "A", INT2NUM(SDL_CONTROLLER_BUTTON_A));
378
+ /* Button B */
379
+ rb_define_const(mButton, "B", INT2NUM(SDL_CONTROLLER_BUTTON_B));
380
+ /* Button X */
381
+ rb_define_const(mButton, "X", INT2NUM(SDL_CONTROLLER_BUTTON_X));
382
+ /* Button Y */
383
+ rb_define_const(mButton, "Y", INT2NUM(SDL_CONTROLLER_BUTTON_Y));
384
+ /* Back Button */
385
+ rb_define_const(mButton, "BACK", INT2NUM(SDL_CONTROLLER_BUTTON_BACK));
386
+ /* Guide Button */
387
+ rb_define_const(mButton, "GUIDE", INT2NUM(SDL_CONTROLLER_BUTTON_GUIDE));
388
+ /* Start Button */
389
+ rb_define_const(mButton, "START", INT2NUM(SDL_CONTROLLER_BUTTON_START));
390
+ /* Left stick Button */
391
+ rb_define_const(mButton, "LEFTSTICK", INT2NUM(SDL_CONTROLLER_BUTTON_LEFTSTICK));
392
+ /* Right stick Button */
393
+ rb_define_const(mButton, "RIGHTSTICK", INT2NUM(SDL_CONTROLLER_BUTTON_RIGHTSTICK));
394
+ /* Left shoulder Button */
395
+ rb_define_const(mButton, "LEFTSHOULDER", INT2NUM(SDL_CONTROLLER_BUTTON_LEFTSHOULDER));
396
+ /* Right shoulder Button */
397
+ rb_define_const(mButton, "RIGHTSHOULDER", INT2NUM(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER));
398
+ /* D-pad UP Button */
399
+ rb_define_const(mButton, "DPAD_UP", INT2NUM(SDL_CONTROLLER_BUTTON_DPAD_UP));
400
+ /* D-pad DOWN Button */
401
+ rb_define_const(mButton, "DPAD_DOWN", INT2NUM(SDL_CONTROLLER_BUTTON_DPAD_DOWN));
402
+ /* D-pad LEFT Button */
403
+ rb_define_const(mButton, "DPAD_LEFT", INT2NUM(SDL_CONTROLLER_BUTTON_DPAD_LEFT));
404
+ /* D-pad RIGHT Button */
405
+ rb_define_const(mButton, "DPAD_RIGHT", INT2NUM(SDL_CONTROLLER_BUTTON_DPAD_RIGHT));
406
+ /* The max of a button index */
407
+ rb_define_const(mButton, "MAX", INT2NUM(SDL_CONTROLLER_BUTTON_MAX));
194
408
  }
@@ -0,0 +1,408 @@
1
+ /* -*- mode: C -*- */
2
+ #include "rubysdl2_internal.h"
3
+ #include <SDL_gamecontroller.h>
4
+
5
+ static VALUE cGameController;
6
+ static VALUE mAxis;
7
+ static VALUE mButton;
8
+
9
+ typedef struct GameController {
10
+ SDL_GameController* controller;
11
+ } GameController;
12
+
13
+ static void GameController_free(GameController* g)
14
+ {
15
+ if (rubysdl2_is_active() && g->controller)
16
+ SDL_GameControllerClose(g->controller);
17
+ free(g);
18
+ }
19
+
20
+ /*
21
+ * Document-class: SDL2::GameController
22
+ *
23
+ * This class represents a "Game Controller".
24
+ *
25
+ * In SDL2, there is a gamecontroller framework to
26
+ * hide the details of joystick types. This framework
27
+ * is built on the existing joystick API.
28
+ *
29
+ * The framework consists of two parts:
30
+ *
31
+ * * Mapping joysticks to game controllers
32
+ * * Aquire input from game controllers
33
+ *
34
+ * Mapping information is a string, and described as:
35
+ *
36
+ * GUID,name,mapping
37
+ *
38
+ * GUID is a unique ID of a type of joystick and
39
+ * given by {Joystick#GUID}. name is the human readable
40
+ * string for the device, and mappings are contorller mappings
41
+ * to joystick ones.
42
+ *
43
+ * This mappings abstract the details of joysticks, for exmaple,
44
+ * the number of buttons, the number of axes, and the position
45
+ * of these buttons a on pad.
46
+ * You can use unified interface
47
+ * with this framework theoretically.
48
+ * Howerver, we need to prepare the
49
+ * database of many joysticks that users will use. A database
50
+ * is available at https://github.com/gabomdq/SDL_GameControllerDB,
51
+ * but perhaps this is not sufficient for your usage.
52
+ * In fact, Steam prepares its own database for Steam games,
53
+ * so if you will create a game for Steam, this framework is
54
+ * useful. Otherwise, it is a better way to use joystick API
55
+ * directly.
56
+ *
57
+ * @!method destroy?
58
+ * Return true if the gamecontroller is already closed.
59
+ */
60
+
61
+ static VALUE GameController_new(SDL_GameController* controller)
62
+ {
63
+ GameController* g = ALLOC(GameController);
64
+ g->controller = controller;
65
+ return Data_Wrap_Struct(cGameController, 0, GameController_free, g);
66
+ }
67
+
68
+ DEFINE_WRAPPER(SDL_GameController, GameController, controller, cGameController,
69
+ "SDL2::GameController");
70
+
71
+
72
+ /*
73
+ * @overload add_mapping(string)
74
+ *
75
+ * Add suuport for controolers that SDL is unaware of or to cause an
76
+ * existing controller to have a different binding.
77
+ *
78
+ * "GUID,name,mapping", where GUID is
79
+ * the string value from SDL_JoystickGetGUIDString(), name is the human
80
+ * readable string for the device and mappings are controller mappings to
81
+ * joystick ones. Under Windows there is a reserved GUID of "xinput" that
82
+ * covers all XInput devices. The mapping format for joystick is:
83
+ *
84
+ * * bX: a joystick button, index X
85
+ * * hX.Y: hat X with value Y
86
+ * * aX: axis X of the joystick
87
+ *
88
+ * Buttons can be used as a controller axes and vice versa.
89
+ *
90
+ * This string shows an example of a valid mapping for a controller:
91
+ * "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7"
92
+ *
93
+ * @param string [String] mapping string
94
+ * @return [Integer] 1 if a new mapping, 0 if an existing mapping is updated.
95
+ */
96
+ static VALUE GameController_s_add_mapping(VALUE self, VALUE string)
97
+ {
98
+ int ret = HANDLE_ERROR(SDL_GameControllerAddMapping(StringValueCStr(string)));
99
+ return INT2NUM(ret);
100
+ }
101
+
102
+ /*
103
+ * @overload axis_name_of(axis)
104
+ *
105
+ * Get a string representing **axis**.
106
+ *
107
+ * @param axis [Integer] axis constant in {Axis}
108
+ * @return [String]
109
+ */
110
+ static VALUE GameController_s_axis_name_of(VALUE self, VALUE axis)
111
+ {
112
+ const char* name = SDL_GameControllerGetStringForAxis(NUM2INT(axis));
113
+ if (!name) {
114
+ SDL_SetError("Unknown axis %d", NUM2INT(axis));
115
+ SDL_ERROR();
116
+ }
117
+ return utf8str_new_cstr(name);
118
+ }
119
+
120
+ /*
121
+ * @overload button_name_of(button)
122
+ *
123
+ * Get a string representing **button**.
124
+ *
125
+ * @param button [Integer] button constant in {Button}
126
+ * @return [String]
127
+ */
128
+ static VALUE GameController_s_button_name_of(VALUE self, VALUE button)
129
+ {
130
+ const char* name = SDL_GameControllerGetStringForButton(NUM2INT(button));
131
+ if (!name) {
132
+ SDL_SetError("Unknown axis %d", NUM2INT(button));
133
+ SDL_ERROR();
134
+ }
135
+ return utf8str_new_cstr(name);
136
+ }
137
+
138
+ /*
139
+ * @overload axis_from_name(name)
140
+ *
141
+ * Get a integer representation of the axis
142
+ * whose string representation is **name**.
143
+ *
144
+ * The return value is the value of one of the constants in {Axis}
145
+ *
146
+ * @param name [String] a string representing an axis
147
+ * @return [Integer]
148
+ */
149
+ static VALUE GameController_s_axis_from_name(VALUE self, VALUE name)
150
+ {
151
+ int axis = SDL_GameControllerGetAxisFromString(StringValueCStr(name));
152
+ if (axis < 0) {
153
+ SDL_SetError("Unknown axis name \"%s\"", StringValueCStr(name));
154
+ SDL_ERROR();
155
+ }
156
+ return INT2FIX(axis);
157
+ }
158
+
159
+ /*
160
+ * @overload button_from_name(name)
161
+ *
162
+ * Get a integer representation of the button
163
+ * whose string representation is **name**.
164
+ *
165
+ * The return value is the value of one of the constants in {Button}
166
+ *
167
+ * @param name [String] a string representing a button
168
+ * @return [Integer]
169
+ */
170
+ static VALUE GameController_s_button_from_name(VALUE self, VALUE name)
171
+ {
172
+ int button = SDL_GameControllerGetButtonFromString(StringValueCStr(name));
173
+ if (button < 0) {
174
+ SDL_SetError("Unknown button name \"%s\"", StringValueCStr(name));
175
+ SDL_ERROR();
176
+ }
177
+ return INT2FIX(button);
178
+ }
179
+
180
+ /*
181
+ * Get the implementation dependent name for the game controllers
182
+ * connected to the machine.
183
+ *
184
+ * The number of elements of returning array is same as
185
+ * {Joystick.num_connected_joysticks}.
186
+ *
187
+ * @return [Array<String,nil>]
188
+ */
189
+ static VALUE GameController_s_device_names(VALUE self)
190
+ {
191
+ int num_joysticks = SDL_NumJoysticks();
192
+ int i;
193
+ VALUE device_names = rb_ary_new2(num_joysticks);
194
+ for (i=0; i<num_joysticks; ++i) {
195
+ const char* name = SDL_GameControllerNameForIndex(i);
196
+ if (name)
197
+ rb_ary_push(device_names, utf8str_new_cstr(name));
198
+ else
199
+ rb_ary_push(device_names, Qnil);
200
+ }
201
+ return device_names;
202
+ }
203
+
204
+ /*
205
+ * @overload mapping_for(guid_string)
206
+ * Get the game controller mapping string for a given GUID.
207
+ *
208
+ * @param guid_string [String] GUID string
209
+ *
210
+ * @return [String]
211
+ */
212
+ static VALUE GameController_s_mapping_for(VALUE self, VALUE guid_string)
213
+ {
214
+ SDL_JoystickGUID guid = SDL_JoystickGetGUIDFromString(StringValueCStr(guid_string));
215
+ return utf8str_new_cstr(SDL_GameControllerMappingForGUID(guid));
216
+ }
217
+
218
+ /*
219
+ * @overload open(index)
220
+ * Open a game controller and return the opened GameController object.
221
+ *
222
+ * @param index [Integer] device index, up to the return value of {Joystick.num_connected_joysticks}.
223
+ * @return [SDL2::GameController]
224
+ *
225
+ * @raise [SDL2::Error] raised when device open is failed.
226
+ * For exmaple, **index** is out of range.
227
+ */
228
+ static VALUE GameController_s_open(VALUE self, VALUE index)
229
+ {
230
+ SDL_GameController* controller = SDL_GameControllerOpen(NUM2INT(index));
231
+ if (!controller)
232
+ SDL_ERROR();
233
+ return GameController_new(controller);
234
+ }
235
+
236
+ /*
237
+ * Get the name of an opened game controller.
238
+ *
239
+ * @return [String]
240
+ */
241
+ static VALUE GameController_name(VALUE self)
242
+ {
243
+ const char* name = SDL_GameControllerName(Get_SDL_GameController(self));
244
+ if (!name)
245
+ SDL_ERROR();
246
+
247
+ return utf8str_new_cstr(name);
248
+ }
249
+
250
+ /*
251
+ * Return true if **self** is opened and attached.
252
+ */
253
+ static VALUE GameController_attached_p(VALUE self)
254
+ {
255
+ return INT2BOOL(SDL_GameControllerGetAttached(Get_SDL_GameController(self)));
256
+ }
257
+
258
+ /*
259
+ * Close the game controller.
260
+ *
261
+ * @return nil
262
+ */
263
+ static VALUE GameController_destroy(VALUE self)
264
+ {
265
+ GameController* g = Get_GameController(self);
266
+ if (g->controller)
267
+ SDL_GameControllerClose(g->controller);
268
+ g->controller = NULL;
269
+ return Qnil;
270
+ }
271
+
272
+ /*
273
+ * Get the mapping string of **self**.
274
+ *
275
+ * @return [String]
276
+ * @see .add_mapping
277
+ * @see .mapping_for
278
+ */
279
+ static VALUE GameController_mapping(VALUE self)
280
+ {
281
+ return utf8str_new_cstr(SDL_GameControllerMapping(Get_SDL_GameController(self)));
282
+ }
283
+
284
+ /*
285
+ * @overload axis(axis)
286
+ * Get the state of an axis control.
287
+ *
288
+ * The state is an integer from -32768 to 32767.
289
+ * The state of trigger never returns negative value (from 0 to 32767).
290
+ *
291
+ * @param axis [Integer] the index of an axis, one of the constants in {Axis}
292
+ * @return [Integer]
293
+ */
294
+ static VALUE GameController_axis(VALUE self, VALUE axis)
295
+ {
296
+ return INT2FIX(SDL_GameControllerGetAxis(Get_SDL_GameController(self),
297
+ NUM2INT(axis)));
298
+ }
299
+
300
+ /*
301
+ * @overload button_pressed?(button)
302
+ * Return true if a button is pressed.
303
+ *
304
+ * @param button [Integer] the index of a button, one of the constants in {Button}
305
+ */
306
+ static VALUE GameController_button_pressed_p(VALUE self, VALUE button)
307
+ {
308
+ return INT2BOOL(SDL_GameControllerGetButton(Get_SDL_GameController(self),
309
+ NUM2INT(button)));
310
+ }
311
+
312
+ /*
313
+ * Document-module: SDL2::GameController::Axis
314
+ *
315
+ * This module provides constants of gamecontroller's axis indices used by
316
+ * {SDL2::GameController} class.
317
+ */
318
+
319
+ /*
320
+ * Document-module: SDL2::GameController::Button
321
+ *
322
+ * This module provides constants of gamecontroller's button indices used by
323
+ * {SDL2::GameController} class.
324
+ */
325
+ void rubysdl2_init_gamecontorller(void)
326
+ {
327
+ cGameController = rb_define_class_under(mSDL2, "GameController", rb_cObject);
328
+
329
+ rb_define_singleton_method(cGameController, "add_mapping",
330
+ GameController_s_add_mapping, 1);
331
+ rb_define_singleton_method(cGameController, "device_names",
332
+ GameController_s_device_names, 0);
333
+ rb_define_singleton_method(cGameController, "axis_name_of",
334
+ GameController_s_axis_name_of, 1);
335
+ rb_define_singleton_method(cGameController, "button_name_of",
336
+ GameController_s_button_name_of, 1);
337
+ rb_define_singleton_method(cGameController, "mapping_for",
338
+ GameController_s_mapping_for, 1);
339
+ rb_define_singleton_method(cGameController, "button_from_name",
340
+ GameController_s_button_from_name, 1);
341
+ rb_define_singleton_method(cGameController, "axis_from_name",
342
+ GameController_s_axis_from_name, 1);
343
+ rb_define_singleton_method(cGameController, "open", GameController_s_open, 1);
344
+ rb_define_method(cGameController, "destroy?", GameController_destroy_p, 0);
345
+ rb_define_method(cGameController, "destroy", GameController_destroy, 0);
346
+ rb_define_method(cGameController, "name", GameController_name, 0);
347
+ rb_define_method(cGameController, "attached?", GameController_attached_p, 0);
348
+ rb_define_method(cGameController, "mapping", GameController_mapping, 0);
349
+ rb_define_method(cGameController, "axis", GameController_axis, 1);
350
+ rb_define_method(cGameController, "button_pressed?", GameController_button_pressed_p, 1);
351
+
352
+ mAxis = rb_define_module_under(cGameController, "Axis");
353
+ mButton = rb_define_module_under(cGameController, "Button");
354
+
355
+ /* define(`DEFINE_CONTROLLER_AXIS_CONST',`rb_define_const(mAxis, "$1", INT2NUM(SDL_CONTROLLER_AXIS_$1))') */
356
+ /* Invalid axis index */
357
+ DEFINE_CONTROLLER_AXIS_CONST(INVALID);
358
+ /* Left X axis */
359
+ DEFINE_CONTROLLER_AXIS_CONST(LEFTX);
360
+ /* Left Y axis */
361
+ DEFINE_CONTROLLER_AXIS_CONST(LEFTY);
362
+ /* Right X axis */
363
+ DEFINE_CONTROLLER_AXIS_CONST(RIGHTX);
364
+ /* Right Y axis */
365
+ DEFINE_CONTROLLER_AXIS_CONST(RIGHTY);
366
+ /* Left trigger axis */
367
+ DEFINE_CONTROLLER_AXIS_CONST(TRIGGERLEFT);
368
+ /* Right trigger axis */
369
+ DEFINE_CONTROLLER_AXIS_CONST(TRIGGERRIGHT);
370
+ /* The max of an axis index */
371
+ DEFINE_CONTROLLER_AXIS_CONST(MAX);
372
+
373
+ /* define(`DEFINE_CONTROLLER_BUTTON_CONST',`rb_define_const(mButton, "$1", INT2NUM(SDL_CONTROLLER_BUTTON_$1))') */
374
+ /* Invalid button index */
375
+ DEFINE_CONTROLLER_BUTTON_CONST(INVALID);
376
+ /* Button A */
377
+ DEFINE_CONTROLLER_BUTTON_CONST(A);
378
+ /* Button B */
379
+ DEFINE_CONTROLLER_BUTTON_CONST(B);
380
+ /* Button X */
381
+ DEFINE_CONTROLLER_BUTTON_CONST(X);
382
+ /* Button Y */
383
+ DEFINE_CONTROLLER_BUTTON_CONST(Y);
384
+ /* Back Button */
385
+ DEFINE_CONTROLLER_BUTTON_CONST(BACK);
386
+ /* Guide Button */
387
+ DEFINE_CONTROLLER_BUTTON_CONST(GUIDE);
388
+ /* Start Button */
389
+ DEFINE_CONTROLLER_BUTTON_CONST(START);
390
+ /* Left stick Button */
391
+ DEFINE_CONTROLLER_BUTTON_CONST(LEFTSTICK);
392
+ /* Right stick Button */
393
+ DEFINE_CONTROLLER_BUTTON_CONST(RIGHTSTICK);
394
+ /* Left shoulder Button */
395
+ DEFINE_CONTROLLER_BUTTON_CONST(LEFTSHOULDER);
396
+ /* Right shoulder Button */
397
+ DEFINE_CONTROLLER_BUTTON_CONST(RIGHTSHOULDER);
398
+ /* D-pad UP Button */
399
+ DEFINE_CONTROLLER_BUTTON_CONST(DPAD_UP);
400
+ /* D-pad DOWN Button */
401
+ DEFINE_CONTROLLER_BUTTON_CONST(DPAD_DOWN);
402
+ /* D-pad LEFT Button */
403
+ DEFINE_CONTROLLER_BUTTON_CONST(DPAD_LEFT);
404
+ /* D-pad RIGHT Button */
405
+ DEFINE_CONTROLLER_BUTTON_CONST(DPAD_RIGHT);
406
+ /* The max of a button index */
407
+ DEFINE_CONTROLLER_BUTTON_CONST(MAX);
408
+ }