ruby-sdl2 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+ }