ruby-sdl2 0.3.6 → 0.3.7

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f0e0bde3276687797e754fb38566b3c23258a0cabedd2cb1b3b8c89fd20f03b1
4
- data.tar.gz: 18ed3f916732eac3c54978dd251b4a01b86dfb71e33a8a4d105d906edeecf8dc
3
+ metadata.gz: 9a1d841e87d0b4437b0eb204f4062d451ff279a49bbae6b98fc70af51daf36f7
4
+ data.tar.gz: 933024c5bc62bbcb3b7fcdaec2dabdc89a54185a16c82d18a5483dde3c8443c6
5
5
  SHA512:
6
- metadata.gz: c86c17d1f78f2a4d1835221a08490fc3c1cd5d4fb7848e9a926b7c6d89c3afcc758054f667c5242e2773dbe1a554bd92872bf23cc1f214fc58312527f79ffbda
7
- data.tar.gz: e5314ba882de2a93c433b336590286482f9485092da806f711fbabda9e78ee0cb6781310e97f8f11270048bb3acfbcc261628c3bbadf1d17c8a38abb15c9b14c
6
+ metadata.gz: f515b8d0a224220af3feb34e11c47ec8212a9efb24166fccd42469a2d04fc5ec250798ae45d374aed504e68bccf3b18c02fc5a03db0727fcdf8de96ed01e31dc
7
+ data.tar.gz: 32404bacccbd2c18426a90322ca93a112cc9d2e4b247d8b64eac978ce8e23a4e625f37d54d4c0785511dde85f59565ea0896b97a43c20e458e3125d3eae39d3f
data/Gemfile CHANGED
@@ -5,7 +5,6 @@ source "https://rubygems.org"
5
5
  group :development do
6
6
  gem "rake"
7
7
  gem "yard"
8
- gem "sord", path: "../sord/main" # For locally modified sord, PR is already sent.
9
- gem "steep", "~> 1.3.0" # sord depends on rbs 2.x, but steep 1.4.x depends rbs 3.x
10
- gem "parallel", "~> 1.22.0" # parallel >= 1.23.0 breaks compatibility
8
+ gem "sord" # , path: "../sord"
9
+ gem "steep" # , path: "../steep"
11
10
  end
data/README.md CHANGED
@@ -5,7 +5,7 @@ The simple ruby extension library for SDL 2.x.
5
5
  # Install
6
6
  Before installing Ruby/SDL2, you need to install:
7
7
 
8
- * [devkit](http://rubyinstaller.org/add-ons/devkit/) (only for windows)
8
+ * [devkit](https://rubyinstaller.org/add-ons/devkit.html) (only for windows)
9
9
  * M4 (only for installing from git repository)
10
10
  * [SDL 2.x](http://www.libsdl.org/download-2.0.php)
11
11
  * [SDL_image](https://www.libsdl.org/projects/SDL_image/)
@@ -31,6 +31,8 @@ Alternatively You can also install the master version of Ruby/SDL2 from github:
31
31
 
32
32
  LGPL v3 (see {file:COPYING.txt}).
33
33
 
34
+ The API documentation is based on [SDL2 Wiki](https://wiki.libsdl.org/SDL2/FrontPage), which is distributed under CC-BY 4.0.
35
+
34
36
  # Author
35
37
 
36
38
  Ippei Obayashi <ohai@kmc.gr.jp>
data/event.c CHANGED
@@ -86,11 +86,14 @@ static VALUE event_type_to_class[SDL_LASTEVENT];
86
86
  * timestamp of the event
87
87
  * @return [Integer]
88
88
  */
89
+ DEFINE_DATA_TYPE(SDL_Event, free);
90
+
89
91
  static VALUE Event_new(SDL_Event* ev)
90
92
  {
91
- SDL_Event* e = ALLOC(SDL_Event);
93
+ SDL_Event* e;
94
+ VALUE obj = TypedData_Make_Struct(event_type_to_class[ev->type], SDL_Event, &SDL_Event_data_type, e);
92
95
  *e = *ev;
93
- return Data_Wrap_Struct(event_type_to_class[ev->type], 0, free, e);
96
+ return obj;
94
97
  }
95
98
 
96
99
  static VALUE Event_s_allocate(VALUE klass)
@@ -99,11 +102,12 @@ static VALUE Event_s_allocate(VALUE klass)
99
102
  VALUE event_type = rb_iv_get(klass, "event_type");
100
103
  if (event_type == Qnil)
101
104
  rb_raise(rb_eArgError, "Cannot allocate %s", rb_class2name(klass));
102
-
103
- e = ALLOC(SDL_Event);
104
- memset(e, 0, sizeof(SDL_Event));
105
- e->common.type = NUM2INT(event_type);
106
- return Data_Wrap_Struct(klass, 0, free, e);
105
+
106
+ {
107
+ VALUE obj = TypedData_Make_Struct(klass, SDL_Event, &SDL_Event_data_type, e);
108
+ e->common.type = NUM2INT(event_type);
109
+ return obj;
110
+ }
107
111
  }
108
112
 
109
113
  /*
@@ -176,7 +180,7 @@ static void set_string(char* field, VALUE str, int maxlength)
176
180
  static VALUE Ev##classname##_##name(VALUE self) \
177
181
  { \
178
182
  SDL_Event* ev; \
179
- Data_Get_Struct(self, SDL_Event, ev); \
183
+ TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); \
180
184
  return c2ruby(ev->field); \
181
185
  } \
182
186
 
@@ -184,7 +188,7 @@ static void set_string(char* field, VALUE str, int maxlength)
184
188
  static VALUE Ev##classname##_set_##name(VALUE self, VALUE val) \
185
189
  { \
186
190
  SDL_Event* ev; \
187
- Data_Get_Struct(self, SDL_Event, ev); \
191
+ TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev); \
188
192
  ev->field = ruby2c(val); \
189
193
  return Qnil; \
190
194
  }
@@ -214,7 +218,7 @@ EVENT_ACCESSOR_UINT(Event, timestamp, common.timestamp);
214
218
  /* @return [String] inspection string */
215
219
  static VALUE Event_inspect(VALUE self)
216
220
  {
217
- SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev);
221
+ SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
218
222
  return rb_sprintf("<%s: type=%u timestamp=%u>",
219
223
  rb_obj_classname(self), ev->common.type, ev->common.timestamp);
220
224
  }
@@ -303,7 +307,7 @@ EVENT_ACCESSOR_INT(Window, data2, window.data2);
303
307
  /* @return [String] inspection string */
304
308
  static VALUE EvWindow_inspect(VALUE self)
305
309
  {
306
- SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev);
310
+ SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
307
311
  return rb_sprintf("<%s: type=%u timestamp=%u window_id=%u event=%u data1=%d data2=%d>",
308
312
  rb_obj_classname(self), ev->common.type, ev->common.timestamp,
309
313
  ev->window.windowID, ev->window.event,
@@ -357,7 +361,7 @@ EVENT_ACCESSOR_UINT(Keyboard, mod, key.keysym.mod);
357
361
  /* @return [String] inspection string */
358
362
  static VALUE EvKeyboard_inspect(VALUE self)
359
363
  {
360
- SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev);
364
+ SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
361
365
  return rb_sprintf("<%s: type=%u timestamp=%u"
362
366
  " window_id=%u state=%u repeat=%u"
363
367
  " scancode=%u sym=%u mod=%u>",
@@ -407,7 +411,7 @@ EVENT_READER(TextEditing, text, edit.text, utf8str_new_cstr);
407
411
  static VALUE EvTextEditing_set_text(VALUE self, VALUE str)
408
412
  {
409
413
  SDL_Event* ev;
410
- Data_Get_Struct(self, SDL_Event, ev);
414
+ TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
411
415
  set_string(ev->edit.text, str, 30);
412
416
  return str;
413
417
  }
@@ -415,7 +419,7 @@ static VALUE EvTextEditing_set_text(VALUE self, VALUE str)
415
419
  /* @return [String] inspection string */
416
420
  static VALUE EvTextEditing_inspect(VALUE self)
417
421
  {
418
- SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev);
422
+ SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
419
423
  return rb_sprintf("<%s: type=%u timestamp=%u"
420
424
  " window_id=%u text=%s start=%d length=%d>",
421
425
  rb_obj_classname(self), ev->common.type, ev->common.timestamp,
@@ -441,7 +445,7 @@ EVENT_READER(TextInput, text, text.text, utf8str_new_cstr);
441
445
  static VALUE EvTextInput_set_text(VALUE self, VALUE str)
442
446
  {
443
447
  SDL_Event* ev;
444
- Data_Get_Struct(self, SDL_Event, ev);
448
+ TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
445
449
  set_string(ev->text.text, str, 30);
446
450
  return str;
447
451
  }
@@ -449,7 +453,7 @@ static VALUE EvTextInput_set_text(VALUE self, VALUE str)
449
453
  /* @return [String] inspection string */
450
454
  static VALUE EvTextInput_inspect(VALUE self)
451
455
  {
452
- SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev);
456
+ SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
453
457
  return rb_sprintf("<%s: type=%u timestamp=%u window_id=%u text=%s>",
454
458
  rb_obj_classname(self), ev->common.type, ev->common.timestamp,
455
459
  ev->text.windowID, ev->text.text);
@@ -507,7 +511,7 @@ EVENT_ACCESSOR_INT(MouseButton, y, button.y);
507
511
  /* @return [String] inspection string */
508
512
  static VALUE EvMouseButton_inspect(VALUE self)
509
513
  {
510
- SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev);
514
+ SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
511
515
  return rb_sprintf("<%s: type=%u timestamp=%u"
512
516
  " window_id=%u which=%u button=%hhu pressed=%s"
513
517
  #if SDL_VERSION_ATLEAST(2,0,2)
@@ -576,7 +580,7 @@ EVENT_ACCESSOR_INT(MouseMotion, yrel, motion.yrel);
576
580
  /* @return [String] inspection string */
577
581
  static VALUE EvMouseMotion_inspect(VALUE self)
578
582
  {
579
- SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev);
583
+ SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
580
584
  return rb_sprintf("<%s: type=%u timestamp=%u"
581
585
  " window_id=%u which=%u state=%u"
582
586
  " x=%d y=%d xrel=%d yrel=%d>",
@@ -615,7 +619,7 @@ EVENT_ACCESSOR_INT(MouseWheel, y, wheel.y);
615
619
  /* @return [String] inspection string */
616
620
  static VALUE EvMouseWheel_inspect(VALUE self)
617
621
  {
618
- SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev);
622
+ SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
619
623
  return rb_sprintf("<%s: type=%u timestamp=%u"
620
624
  " window_id=%u which=%u x=%d y=%d>",
621
625
  rb_obj_classname(self), ev->common.type, ev->common.timestamp,
@@ -651,7 +655,7 @@ EVENT_ACCESSOR_BOOL(JoyButton, pressed, jbutton.state);
651
655
  /* @return [String] inspection string */
652
656
  static VALUE EvJoyButton_inspect(VALUE self)
653
657
  {
654
- SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev);
658
+ SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
655
659
  return rb_sprintf("<%s: type=%u timestamp=%u"
656
660
  " which=%d button=%u pressed=%s>",
657
661
  rb_obj_classname(self), ev->common.type, ev->common.timestamp,
@@ -693,7 +697,7 @@ EVENT_ACCESSOR_INT(JoyAxisMotion, value, jaxis.value);
693
697
  /* @return [String] inspection string */
694
698
  static VALUE EvJoyAxisMotion_inspect(VALUE self)
695
699
  {
696
- SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev);
700
+ SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
697
701
  return rb_sprintf("<%s: type=%u timestamp=%u"
698
702
  " which=%d axis=%u value=%d>",
699
703
  rb_obj_classname(self), ev->common.type, ev->common.timestamp,
@@ -728,7 +732,7 @@ EVENT_ACCESSOR_INT(JoyBallMotion, yrel, jball.yrel);
728
732
  /* @return [String] inspection string */
729
733
  static VALUE EvJoyBallMotion_inspect(VALUE self)
730
734
  {
731
- SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev);
735
+ SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
732
736
  return rb_sprintf("<%s: type=%u timestamp=%u"
733
737
  " which=%d ball=%u xrel=%d yrel=%d>",
734
738
  rb_obj_classname(self), ev->common.type, ev->common.timestamp,
@@ -758,7 +762,7 @@ EVENT_ACCESSOR_UINT8(JoyHatMotion, value, jhat.value);
758
762
  /* @return [String] inspection string */
759
763
  static VALUE EvJoyHatMotion_inspect(VALUE self)
760
764
  {
761
- SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev);
765
+ SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
762
766
  return rb_sprintf("<%s: type=%u timestamp=%u which=%d hat=%u value=%u>",
763
767
  rb_obj_classname(self), ev->common.type, ev->common.timestamp,
764
768
  ev->jhat.which, ev->jhat.hat, ev->jhat.value);
@@ -775,7 +779,7 @@ EVENT_ACCESSOR_INT(JoyDevice, which, jdevice.which);
775
779
  /* @return [String] inspection string */
776
780
  static VALUE EvJoyDevice_inspect(VALUE self)
777
781
  {
778
- SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev);
782
+ SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
779
783
  return rb_sprintf("<%s: type=%u timestamp=%u which=%d>",
780
784
  rb_obj_classname(self), ev->common.type, ev->common.timestamp,
781
785
  ev->jdevice.which);
@@ -816,7 +820,7 @@ EVENT_ACCESSOR_INT(ControllerAxis, value, caxis.value);
816
820
  /* @return [String] inspection string */
817
821
  static VALUE ControllerAxis_inspect(VALUE self)
818
822
  {
819
- SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev);
823
+ SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
820
824
  return rb_sprintf("<%s: type=%u timestamp=%u"
821
825
  " which=%d axis=%s value=%d>",
822
826
  rb_obj_classname(self), ev->common.type, ev->common.timestamp,
@@ -853,7 +857,7 @@ EVENT_ACCESSOR_BOOL(ControllerButton, pressed, cbutton.state);
853
857
  /* @return [String] inspection string */
854
858
  static VALUE ControllerButton_inspect(VALUE self)
855
859
  {
856
- SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev);
860
+ SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
857
861
  return rb_sprintf("<%s: type=%u timestamp=%u"
858
862
  " which=%d button=%s state=%s>",
859
863
  rb_obj_classname(self), ev->common.type, ev->common.timestamp,
@@ -893,7 +897,7 @@ EVENT_ACCESSOR_INT(ControllerDevice, which, cdevice.which);
893
897
  /* @return [String] inspection string */
894
898
  static VALUE ControllerDevice_inspect(VALUE self)
895
899
  {
896
- SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev);
900
+ SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
897
901
  return rb_sprintf("<%s: type=%u timestamp=%u which=%d>",
898
902
  rb_obj_classname(self), ev->common.type, ev->common.timestamp,
899
903
  ev->cdevice.which);
@@ -953,7 +957,7 @@ EVENT_ACCESSOR_DBL(TouchFinger, pressure, tfinger.pressure);
953
957
  /* @return [String] inspection string */
954
958
  static VALUE EvTouchFinger_inspect(VALUE self)
955
959
  {
956
- SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev);
960
+ SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
957
961
  return rb_sprintf("<%s: type=%u timestamp=%u"
958
962
  " touch_id=%d finger_id=%d"
959
963
  " x=%f y=%f pressure=%f>",
@@ -990,7 +994,7 @@ EVENT_ACCESSOR_DBL(FingerMotion, dy, tfinger.dy);
990
994
  /* @return [String] inspection string */
991
995
  static VALUE EvFingerMotion_inspect(VALUE self)
992
996
  {
993
- SDL_Event* ev; Data_Get_Struct(self, SDL_Event, ev);
997
+ SDL_Event* ev; TypedData_Get_Struct(self, SDL_Event, &SDL_Event_data_type, ev);
994
998
  return rb_sprintf("<%s: type=%u timestamp=%u"
995
999
  " touch_id=%d finger_id=%d"
996
1000
  " x=%f y=%f pressure=%f"
data/gamecontroller.c CHANGED
@@ -17,6 +17,8 @@ static void GameController_free(GameController* g)
17
17
  free(g);
18
18
  }
19
19
 
20
+ DEFINE_DATA_TYPE(GameController, GameController_free);
21
+
20
22
  /*
21
23
  * Document-class: SDL2::GameController
22
24
  *
@@ -60,9 +62,10 @@ static void GameController_free(GameController* g)
60
62
 
61
63
  static VALUE GameController_new(SDL_GameController* controller)
62
64
  {
63
- GameController* g = ALLOC(GameController);
65
+ GameController* g;
66
+ VALUE obj = TypedData_Make_Struct(cGameController, GameController, &GameController_data_type, g);
64
67
  g->controller = controller;
65
- return Data_Wrap_Struct(cGameController, 0, GameController_free, g);
68
+ return obj;
66
69
  }
67
70
 
68
71
  DEFINE_WRAPPER(SDL_GameController, GameController, controller, cGameController,
data/gamecontroller.c.m4 CHANGED
@@ -17,6 +17,8 @@ static void GameController_free(GameController* g)
17
17
  free(g);
18
18
  }
19
19
 
20
+ DEFINE_DATA_TYPE(GameController, GameController_free);
21
+
20
22
  /*
21
23
  * Document-class: SDL2::GameController
22
24
  *
@@ -60,9 +62,10 @@ static void GameController_free(GameController* g)
60
62
 
61
63
  static VALUE GameController_new(SDL_GameController* controller)
62
64
  {
63
- GameController* g = ALLOC(GameController);
65
+ GameController* g;
66
+ VALUE obj = TypedData_Make_Struct(cGameController, GameController, &GameController_data_type, g);
64
67
  g->controller = controller;
65
- return Data_Wrap_Struct(cGameController, 0, GameController_free, g);
68
+ return obj;
66
69
  }
67
70
 
68
71
  DEFINE_WRAPPER(SDL_GameController, GameController, controller, cGameController,
data/gl.c CHANGED
@@ -12,8 +12,6 @@ typedef struct GLContext {
12
12
  SDL_GLContext context;
13
13
  } GLContext;
14
14
 
15
- DEFINE_WRAPPER(SDL_GLContext, GLContext, context, cGLContext, "SDL2::GL::Context");
16
-
17
15
  static void GLContext_free(GLContext* c)
18
16
  {
19
17
  if (c->context)
@@ -21,11 +19,16 @@ static void GLContext_free(GLContext* c)
21
19
  free(c);
22
20
  }
23
21
 
22
+ DEFINE_DATA_TYPE(GLContext, GLContext_free);
23
+
24
+ DEFINE_WRAPPER(SDL_GLContext, GLContext, context, cGLContext, "SDL2::GL::Context");
25
+
24
26
  static VALUE GLContext_new(SDL_GLContext context)
25
27
  {
26
- GLContext* c = ALLOC(GLContext);
28
+ GLContext* c;
29
+ VALUE obj = TypedData_Make_Struct(cGLContext, GLContext, &GLContext_data_type, c);
27
30
  c->context = context;
28
- return Data_Wrap_Struct(cGLContext, 0, GLContext_free, c);
31
+ return obj;
29
32
  }
30
33
 
31
34
  /*
data/gl.c.m4 CHANGED
@@ -12,8 +12,6 @@ typedef struct GLContext {
12
12
  SDL_GLContext context;
13
13
  } GLContext;
14
14
 
15
- DEFINE_WRAPPER(SDL_GLContext, GLContext, context, cGLContext, "SDL2::GL::Context");
16
-
17
15
  static void GLContext_free(GLContext* c)
18
16
  {
19
17
  if (c->context)
@@ -21,11 +19,16 @@ static void GLContext_free(GLContext* c)
21
19
  free(c);
22
20
  }
23
21
 
22
+ DEFINE_DATA_TYPE(GLContext, GLContext_free);
23
+
24
+ DEFINE_WRAPPER(SDL_GLContext, GLContext, context, cGLContext, "SDL2::GL::Context");
25
+
24
26
  static VALUE GLContext_new(SDL_GLContext context)
25
27
  {
26
- GLContext* c = ALLOC(GLContext);
28
+ GLContext* c;
29
+ VALUE obj = TypedData_Make_Struct(cGLContext, GLContext, &GLContext_data_type, c);
27
30
  c->context = context;
28
- return Data_Wrap_Struct(cGLContext, 0, GLContext_free, c);
31
+ return obj;
29
32
  }
30
33
 
31
34
  /*
data/joystick.c CHANGED
@@ -18,11 +18,14 @@ static void Joystick_free(Joystick* j)
18
18
  free(j);
19
19
  }
20
20
 
21
+ DEFINE_DATA_TYPE(Joystick, Joystick_free);
22
+
21
23
  static VALUE Joystick_new(SDL_Joystick* joystick)
22
24
  {
23
- Joystick* j = ALLOC(Joystick);
25
+ Joystick* j;
26
+ VALUE obj = TypedData_Make_Struct(cJoystick, Joystick, &Joystick_data_type, j);
24
27
  j->joystick = joystick;
25
- return Data_Wrap_Struct(cJoystick, 0, Joystick_free, j);
28
+ return obj;
26
29
  }
27
30
 
28
31
  DEFINE_WRAPPER(SDL_Joystick, Joystick, joystick, cJoystick, "SDL2::Joystick");
data/joystick.c.m4 CHANGED
@@ -18,11 +18,14 @@ static void Joystick_free(Joystick* j)
18
18
  free(j);
19
19
  }
20
20
 
21
+ DEFINE_DATA_TYPE(Joystick, Joystick_free);
22
+
21
23
  static VALUE Joystick_new(SDL_Joystick* joystick)
22
24
  {
23
- Joystick* j = ALLOC(Joystick);
25
+ Joystick* j;
26
+ VALUE obj = TypedData_Make_Struct(cJoystick, Joystick, &Joystick_data_type, j);
24
27
  j->joystick = joystick;
25
- return Data_Wrap_Struct(cJoystick, 0, Joystick_free, j);
28
+ return obj;
26
29
  }
27
30
 
28
31
  DEFINE_WRAPPER(SDL_Joystick, Joystick, joystick, cJoystick, "SDL2::Joystick");
data/lib/sdl2/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module SDL2
2
2
  # @return [String] Version string of Ruby/SDL2
3
- VERSION = "0.3.6"
3
+ VERSION = "0.3.7"
4
4
  # @return [Array<Integer>] Version of Ruby/SDL2, [major, minor, patch level]
5
5
  VERSION_NUMBER = VERSION.split(".").map(&:to_i)
6
6
  end
data/mixer.c CHANGED
@@ -27,34 +27,40 @@ typedef struct Music {
27
27
 
28
28
  static void Chunk_free(Chunk* c)
29
29
  {
30
- if (rubysdl2_is_active() && c->chunk)
30
+ if (rubysdl2_is_active() && c->chunk)
31
31
  Mix_FreeChunk(c->chunk);
32
32
  free(c);
33
33
  }
34
34
 
35
+ DEFINE_DATA_TYPE(Chunk, Chunk_free);
36
+
35
37
  static VALUE Chunk_new(Mix_Chunk* chunk)
36
38
  {
37
- Chunk* c = ALLOC(Chunk);
39
+ Chunk* c;
40
+ VALUE obj = TypedData_Make_Struct(cChunk, Chunk, &Chunk_data_type, c);
38
41
  c->chunk = chunk;
39
- return Data_Wrap_Struct(cChunk, 0, Chunk_free, c);
42
+ return obj;
40
43
  }
41
44
 
42
45
  DEFINE_WRAPPER(Mix_Chunk, Chunk, chunk, cChunk, "SDL2::Mixer::Chunk");
43
46
 
44
47
  static void Music_free(Music* m)
45
48
  {
46
- if (rubysdl2_is_active() && m->music)
49
+ if (rubysdl2_is_active() && m->music)
47
50
  Mix_FreeMusic(m->music);
48
51
  free(m);
49
52
  }
50
53
 
54
+ DEFINE_DATA_TYPE(Music, Music_free);
55
+
51
56
  static VALUE Music_new(Mix_Music* music)
52
57
  {
53
- Music* c = ALLOC(Music);
58
+ Music* c;
59
+ VALUE obj = TypedData_Make_Struct(cMusic, Music, &Music_data_type, c);
54
60
  c->music = music;
55
- return Data_Wrap_Struct(cMusic, 0, Music_free, c);
61
+ return obj;
56
62
  }
57
-
63
+
58
64
  DEFINE_WRAPPER(Mix_Music, Music, music, cMusic, "SDL2::Mixer::Music");
59
65
 
60
66
  /*
data/mixer.c.m4 CHANGED
@@ -27,34 +27,40 @@ typedef struct Music {
27
27
 
28
28
  static void Chunk_free(Chunk* c)
29
29
  {
30
- if (rubysdl2_is_active() && c->chunk)
30
+ if (rubysdl2_is_active() && c->chunk)
31
31
  Mix_FreeChunk(c->chunk);
32
32
  free(c);
33
33
  }
34
34
 
35
+ DEFINE_DATA_TYPE(Chunk, Chunk_free);
36
+
35
37
  static VALUE Chunk_new(Mix_Chunk* chunk)
36
38
  {
37
- Chunk* c = ALLOC(Chunk);
39
+ Chunk* c;
40
+ VALUE obj = TypedData_Make_Struct(cChunk, Chunk, &Chunk_data_type, c);
38
41
  c->chunk = chunk;
39
- return Data_Wrap_Struct(cChunk, 0, Chunk_free, c);
42
+ return obj;
40
43
  }
41
44
 
42
45
  DEFINE_WRAPPER(Mix_Chunk, Chunk, chunk, cChunk, "SDL2::Mixer::Chunk");
43
46
 
44
47
  static void Music_free(Music* m)
45
48
  {
46
- if (rubysdl2_is_active() && m->music)
49
+ if (rubysdl2_is_active() && m->music)
47
50
  Mix_FreeMusic(m->music);
48
51
  free(m);
49
52
  }
50
53
 
54
+ DEFINE_DATA_TYPE(Music, Music_free);
55
+
51
56
  static VALUE Music_new(Mix_Music* music)
52
57
  {
53
- Music* c = ALLOC(Music);
58
+ Music* c;
59
+ VALUE obj = TypedData_Make_Struct(cMusic, Music, &Music_data_type, c);
54
60
  c->music = music;
55
- return Data_Wrap_Struct(cMusic, 0, Music_free, c);
61
+ return obj;
56
62
  }
57
-
63
+
58
64
  DEFINE_WRAPPER(Mix_Music, Music, music, cMusic, "SDL2::Mixer::Music");
59
65
 
60
66
  /*
data/rubysdl2_internal.h CHANGED
@@ -71,6 +71,17 @@ void rubysdl2_init_gamecontorller(void);
71
71
  #define UCHAR2NUM UINT2NUM
72
72
  #define rb_str_export_to_utf8(str) rb_str_export_to_enc((str), rb_utf8_encoding())
73
73
 
74
+ /* Helper macro to define a rb_data_type_t for TypedData.
75
+ * Usage: DEFINE_DATA_TYPE(struct_name, free_func)
76
+ * Defines: static const rb_data_type_t struct_name##_data_type
77
+ */
78
+ #define DEFINE_DATA_TYPE(struct_name, free_func) \
79
+ static const rb_data_type_t struct_name##_data_type = { \
80
+ "ruby-sdl2/" #struct_name, \
81
+ { NULL, (void (*)(void*))(free_func), NULL }, \
82
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY \
83
+ };
84
+
74
85
  #define DEFINE_GETTER(scope, ctype, var_class, classname) \
75
86
  scope ctype* Get_##ctype(VALUE obj) \
76
87
  { \
@@ -78,7 +89,7 @@ void rubysdl2_init_gamecontorller(void);
78
89
  if (!rb_obj_is_kind_of(obj, var_class)) \
79
90
  rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", \
80
91
  rb_obj_classname(obj), classname); \
81
- Data_Get_Struct(obj, ctype, s); \
92
+ TypedData_Get_Struct(obj, ctype, &ctype##_data_type, s); \
82
93
  \
83
94
  return s; \
84
95
  }
@@ -0,0 +1,41 @@
1
+ require "sdl2"
2
+
3
+ SDL2.init(SDL2::INIT_VIDEO|SDL2::INIT_EVENTS)
4
+
5
+ window = SDL2::Window.create("read_pixels",
6
+ SDL2::Window::POS_CENTERED, SDL2::Window::POS_CENTERED,
7
+ 320, 240, 0)
8
+ renderer = window.create_renderer(-1, 0)
9
+
10
+ # Draw something
11
+ renderer.draw_color = [0, 128, 255]
12
+ renderer.fill_rect(SDL2::Rect.new(60, 40, 200, 160))
13
+ renderer.draw_color = [255, 255, 0]
14
+ renderer.fill_rect(SDL2::Rect.new(110, 80, 100, 80))
15
+
16
+ # Capture pixels in ARGB8888 format
17
+ pixels = renderer.read_pixels(nil, SDL2::PixelFormat::ARGB8888)
18
+
19
+ renderer.present
20
+
21
+ # Save as BMP
22
+ width, height = 320, 240
23
+ row_size = width * 4
24
+ file_size = 54 + row_size * height
25
+ bmp = String.new(encoding: Encoding::BINARY)
26
+ bmp << ["BM", file_size, 0, 0, 54].pack("A2Vv2V")
27
+ bmp << [40, width, height, 1, 32, 0, 0, 0, 0, 0, 0].pack("VV2v2V6")
28
+ (height - 1).downto(0) {|y| bmp << pixels.byteslice(y * row_size, row_size) }
29
+ File.binwrite("screenshot.bmp", bmp)
30
+ puts "Saved screenshot.bmp (#{File.size("screenshot.bmp")} bytes)"
31
+
32
+ loop do
33
+ while ev = SDL2::Event.poll
34
+ if SDL2::Event::KeyDown === ev && ev.scancode == SDL2::Key::Scan::ESCAPE
35
+ exit
36
+ end
37
+ end
38
+
39
+ renderer.present
40
+ sleep 0.1
41
+ end
data/ttf.c CHANGED
@@ -43,11 +43,14 @@ static void TTF_free(TTF* f)
43
43
  free(f);
44
44
  }
45
45
 
46
+ DEFINE_DATA_TYPE(TTF, TTF_free);
47
+
46
48
  static VALUE TTF_new(TTF_Font* font)
47
49
  {
48
- TTF* f = ALLOC(TTF);
50
+ TTF* f;
51
+ VALUE obj = TypedData_Make_Struct(cTTF, TTF, &TTF_data_type, f);
49
52
  f->font = font;
50
- return Data_Wrap_Struct(cTTF, 0, TTF_free, f);
53
+ return obj;
51
54
  }
52
55
 
53
56
  DEFINE_WRAPPER(TTF_Font, TTF, font, cTTF, "SDL2::TTF");
data/ttf.c.m4 CHANGED
@@ -43,11 +43,14 @@ static void TTF_free(TTF* f)
43
43
  free(f);
44
44
  }
45
45
 
46
+ DEFINE_DATA_TYPE(TTF, TTF_free);
47
+
46
48
  static VALUE TTF_new(TTF_Font* font)
47
49
  {
48
- TTF* f = ALLOC(TTF);
50
+ TTF* f;
51
+ VALUE obj = TypedData_Make_Struct(cTTF, TTF, &TTF_data_type, f);
49
52
  f->font = font;
50
- return Data_Wrap_Struct(cTTF, 0, TTF_free, f);
53
+ return obj;
51
54
  }
52
55
 
53
56
  DEFINE_WRAPPER(TTF_Font, TTF, font, cTTF, "SDL2::TTF");
data/video.c CHANGED
@@ -65,7 +65,20 @@ typedef struct Surface {
65
65
  int need_to_free_pixels;
66
66
  } Surface;
67
67
 
68
+ static void Window_free(Window*);
68
69
  static void Renderer_free(Renderer*);
70
+ static void Texture_free(Texture*);
71
+ static void Surface_free(Surface*);
72
+
73
+ /* Forward-declare TypedData types (need free function declarations above) */
74
+ DEFINE_DATA_TYPE(Window, Window_free);
75
+ DEFINE_DATA_TYPE(SDL_DisplayMode, free);
76
+ DEFINE_DATA_TYPE(Renderer, Renderer_free);
77
+ DEFINE_DATA_TYPE(Texture, Texture_free);
78
+ DEFINE_DATA_TYPE(Surface, Surface_free);
79
+ DEFINE_DATA_TYPE(SDL_Rect, free);
80
+ DEFINE_DATA_TYPE(SDL_Point, free);
81
+
69
82
  static void Window_destroy_internal(Window* w)
70
83
  {
71
84
  int i;
@@ -89,12 +102,13 @@ static void Window_free(Window* w)
89
102
 
90
103
  static VALUE Window_new(SDL_Window* window)
91
104
  {
92
- Window* w = ALLOC(Window);
105
+ Window* w;
106
+ VALUE obj = TypedData_Make_Struct(cWindow, Window, &Window_data_type, w);
93
107
  w->window = window;
94
108
  w->num_renderers = 0;
95
109
  w->max_renderers = 4;
96
110
  w->renderers = ALLOC_N(struct Renderer*, 4);
97
- return Data_Wrap_Struct(cWindow, 0, Window_free, w);
111
+ return obj;
98
112
  }
99
113
 
100
114
  DEFINE_GETTER(static, Window, cWindow, "SDL2::Window");
@@ -111,24 +125,24 @@ static VALUE Display_new(int index)
111
125
 
112
126
  static VALUE DisplayMode_s_allocate(VALUE klass)
113
127
  {
114
- SDL_DisplayMode* mode = ALLOC(SDL_DisplayMode);
128
+ SDL_DisplayMode* mode;
129
+ VALUE obj = TypedData_Make_Struct(klass, SDL_DisplayMode, &SDL_DisplayMode_data_type, mode);
115
130
  mode->format = mode->w = mode->h = mode->refresh_rate = 0;
116
131
  mode->driverdata = NULL;
117
- return Data_Wrap_Struct(klass, 0, free, mode);
132
+ return obj;
118
133
  }
119
134
 
120
135
  static VALUE DisplayMode_new(SDL_DisplayMode* mode)
121
136
  {
122
137
  VALUE display_mode = DisplayMode_s_allocate(cDisplayMode);
123
138
  SDL_DisplayMode* m;
124
- Data_Get_Struct(display_mode, SDL_DisplayMode, m);
139
+ TypedData_Get_Struct(display_mode, SDL_DisplayMode, &SDL_DisplayMode_data_type, m);
125
140
  *m = *mode;
126
141
  return display_mode;
127
142
  }
128
143
 
129
144
  DEFINE_GETTER(static, SDL_DisplayMode, cDisplayMode, "SDL2::Display::Mode");
130
145
 
131
- static void Texture_free(Texture*);
132
146
  static void Renderer_destroy_internal(Renderer* r)
133
147
  {
134
148
  int i;
@@ -167,14 +181,15 @@ static void Window_attach_renderer(Window* w, Renderer* r)
167
181
 
168
182
  static VALUE Renderer_new(SDL_Renderer* renderer, Window* w)
169
183
  {
170
- Renderer* r = ALLOC(Renderer);
184
+ Renderer* r;
185
+ VALUE obj = TypedData_Make_Struct(cRenderer, Renderer, &Renderer_data_type, r);
171
186
  r->renderer = renderer;
172
187
  r->num_textures = 0;
173
188
  r->max_textures = 16;
174
189
  r->textures = ALLOC_N(Texture*, 16);
175
190
  r->refcount = 1;
176
191
  Window_attach_renderer(w, r);
177
- return Data_Wrap_Struct(cRenderer, 0, Renderer_free, r);
192
+ return obj;
178
193
  }
179
194
 
180
195
  DEFINE_WRAPPER(SDL_Renderer, Renderer, renderer, cRenderer, "SDL2::Renderer");
@@ -209,11 +224,12 @@ static void Renderer_attach_texture(Renderer* r, Texture* t)
209
224
 
210
225
  static VALUE Texture_new(SDL_Texture* texture, Renderer* r)
211
226
  {
212
- Texture* t = ALLOC(Texture);
227
+ Texture* t;
228
+ VALUE obj = TypedData_Make_Struct(cTexture, Texture, &Texture_data_type, t);
213
229
  t->texture = texture;
214
230
  t->refcount = 1;
215
231
  Renderer_attach_texture(r, t);
216
- return Data_Wrap_Struct(cTexture, 0, Texture_free, t);
232
+ return obj;
217
233
  }
218
234
 
219
235
  DEFINE_WRAPPER(SDL_Texture, Texture, texture, cTexture, "SDL2::Texture");
@@ -231,10 +247,11 @@ static void Surface_free(Surface* s)
231
247
 
232
248
  VALUE Surface_new(SDL_Surface* surface)
233
249
  {
234
- Surface* s = ALLOC(Surface);
250
+ Surface* s;
251
+ VALUE obj = TypedData_Make_Struct(cSurface, Surface, &Surface_data_type, s);
235
252
  s->surface = surface;
236
253
  s->need_to_free_pixels = 0;
237
- return Data_Wrap_Struct(cSurface, 0, Surface_free, s);
254
+ return obj;
238
255
  }
239
256
 
240
257
  DEFINE_WRAPPER(SDL_Surface, Surface, surface, cSurface, "SDL2::Surface");
@@ -1338,6 +1355,54 @@ static VALUE Renderer_present(VALUE self)
1338
1355
  return Qnil;
1339
1356
  }
1340
1357
 
1358
+ /*
1359
+ * @overload read_pixels(rect, format)
1360
+ * Read pixels from the current rendering target.
1361
+ *
1362
+ * ## Remarks
1363
+ *
1364
+ * **WARNING**: This is a very slow operation, and should not be used frequently.
1365
+ * If you're using this on the main rendering target, it should be called after
1366
+ * rendering and before {#present}.
1367
+ *
1368
+ * @param [SDL2::Rect,nil] rect the area to read, or nil for the entire target
1369
+ * @param [SDL2::PixelFormat,Integer] format the desired pixel format
1370
+ * (0 to use the format of the rendering target)
1371
+ * @return [String] raw pixel data as a binary string
1372
+ */
1373
+ static VALUE Renderer_read_pixels(VALUE self, VALUE rect, VALUE format)
1374
+ {
1375
+ SDL_Renderer* renderer = Get_SDL_Renderer(self);
1376
+ SDL_Rect sdl_rect;
1377
+ SDL_Rect* rect_ptr = NULL;
1378
+ Uint32 fmt = uint32_for_format(format);
1379
+ int w, h, pitch;
1380
+ void* pixels;
1381
+
1382
+ if (rect != Qnil) {
1383
+ sdl_rect = *Get_SDL_Rect(rect);
1384
+ rect_ptr = &sdl_rect;
1385
+ w = sdl_rect.w;
1386
+ h = sdl_rect.h;
1387
+ } else {
1388
+ HANDLE_ERROR(SDL_GetRendererOutputSize(renderer, &w, &h));
1389
+ }
1390
+
1391
+ if (fmt == 0) {
1392
+ SDL_RendererInfo info;
1393
+ HANDLE_ERROR(SDL_GetRendererInfo(renderer, &info));
1394
+ pitch = w * SDL_BYTESPERPIXEL(info.texture_formats[0]);
1395
+ } else {
1396
+ pitch = w * SDL_BYTESPERPIXEL(fmt);
1397
+ }
1398
+
1399
+ pixels = ALLOCA_N(char, pitch * h);
1400
+
1401
+ HANDLE_ERROR(SDL_RenderReadPixels(renderer, rect_ptr, fmt, pixels, pitch));
1402
+
1403
+ return rb_str_new(pixels, pitch * h);
1404
+ }
1405
+
1341
1406
  /*
1342
1407
  * Crear the rendering target with the drawing color.
1343
1408
  * @return [nil]
@@ -2063,6 +2128,7 @@ static VALUE Surface_s_from_string(int argc, VALUE* argv, VALUE self)
2063
2128
  SDL_Surface* surface;
2064
2129
  void* pixels;
2065
2130
  Surface* s;
2131
+ VALUE obj;
2066
2132
 
2067
2133
  rb_scan_args(argc, argv, "45", &string, &width, &height, &depth,
2068
2134
  &pitch, &Rmask, &Gmask, &Bmask, &Amask);
@@ -2089,10 +2155,10 @@ static VALUE Surface_s_from_string(int argc, VALUE* argv, VALUE self)
2089
2155
 
2090
2156
  RB_GC_GUARD(string);
2091
2157
 
2092
- s = ALLOC(Surface);
2158
+ obj = TypedData_Make_Struct(cSurface, Surface, &Surface_data_type, s);
2093
2159
  s->surface = surface;
2094
2160
  s->need_to_free_pixels = 1;
2095
- return Data_Wrap_Struct(cSurface, 0, Surface_free, s);
2161
+ return obj;
2096
2162
  }
2097
2163
 
2098
2164
  /*
@@ -2446,12 +2512,14 @@ static VALUE Surface_s_new(int argc, VALUE* argv, VALUE self)
2446
2512
  #define FIELD_ACCESSOR(classname, typename, field) \
2447
2513
  static VALUE classname##_##field(VALUE self) \
2448
2514
  { \
2449
- typename* r; Data_Get_Struct(self, typename, r); \
2515
+ typename* r; \
2516
+ TypedData_Get_Struct(self, typename, &typename##_data_type, r); \
2450
2517
  return INT2NUM(r->field); \
2451
2518
  } \
2452
2519
  static VALUE classname##_set_##field(VALUE self, VALUE val) \
2453
2520
  { \
2454
- typename* r; Data_Get_Struct(self, typename, r); \
2521
+ typename* r; \
2522
+ TypedData_Get_Struct(self, typename, &typename##_data_type, r); \
2455
2523
  r->field = NUM2INT(val); return val; \
2456
2524
  }
2457
2525
 
@@ -2490,10 +2558,10 @@ static VALUE Surface_s_new(int argc, VALUE* argv, VALUE self)
2490
2558
  */
2491
2559
  static VALUE Rect_s_allocate(VALUE klass)
2492
2560
  {
2493
- SDL_Rect* rect = ALLOC(SDL_Rect);
2561
+ SDL_Rect* rect;
2562
+ VALUE obj = TypedData_Make_Struct(klass, SDL_Rect, &SDL_Rect_data_type, rect);
2494
2563
  rect->x = rect->y = rect->w = rect->h = 0;
2495
-
2496
- return Data_Wrap_Struct(cRect, 0, free, rect);
2564
+ return obj;
2497
2565
  }
2498
2566
 
2499
2567
  /*
@@ -2521,7 +2589,7 @@ static VALUE Rect_initialize(int argc, VALUE* argv, VALUE self)
2521
2589
  /* do nothing*/
2522
2590
  } else if (argc == 4) {
2523
2591
  SDL_Rect* rect;
2524
- Data_Get_Struct(self, SDL_Rect, rect);
2592
+ TypedData_Get_Struct(self, SDL_Rect, &SDL_Rect_data_type, rect);
2525
2593
  rect->x = NUM2INT(x); rect->y = NUM2INT(y);
2526
2594
  rect->w = NUM2INT(w); rect->h = NUM2INT(h);
2527
2595
  } else {
@@ -2596,7 +2664,7 @@ static VALUE Rect_union(VALUE self, VALUE other)
2596
2664
  static VALUE Point_s_allocate(VALUE klass)
2597
2665
  {
2598
2666
  SDL_Point* point;
2599
- return Data_Make_Struct(klass, SDL_Point, 0, free, point);
2667
+ return TypedData_Make_Struct(klass, SDL_Point, &SDL_Point_data_type, point);
2600
2668
  }
2601
2669
 
2602
2670
  /*
@@ -2960,6 +3028,7 @@ void rubysdl2_init_video(void)
2960
3028
  rb_define_method(cRenderer, "copy", Renderer_copy, 3);
2961
3029
  rb_define_method(cRenderer, "copy_ex", Renderer_copy_ex, 6);
2962
3030
  rb_define_method(cRenderer, "present", Renderer_present, 0);
3031
+ rb_define_method(cRenderer, "read_pixels", Renderer_read_pixels, 2);
2963
3032
  rb_define_method(cRenderer, "draw_color",Renderer_draw_color, 0);
2964
3033
  rb_define_method(cRenderer, "draw_color=",Renderer_set_draw_color, 1);
2965
3034
  rb_define_method(cRenderer, "clear", Renderer_clear, 0);
data/video.c.m4 CHANGED
@@ -65,7 +65,20 @@ typedef struct Surface {
65
65
  int need_to_free_pixels;
66
66
  } Surface;
67
67
 
68
+ static void Window_free(Window*);
68
69
  static void Renderer_free(Renderer*);
70
+ static void Texture_free(Texture*);
71
+ static void Surface_free(Surface*);
72
+
73
+ /* Forward-declare TypedData types (need free function declarations above) */
74
+ DEFINE_DATA_TYPE(Window, Window_free);
75
+ DEFINE_DATA_TYPE(SDL_DisplayMode, free);
76
+ DEFINE_DATA_TYPE(Renderer, Renderer_free);
77
+ DEFINE_DATA_TYPE(Texture, Texture_free);
78
+ DEFINE_DATA_TYPE(Surface, Surface_free);
79
+ DEFINE_DATA_TYPE(SDL_Rect, free);
80
+ DEFINE_DATA_TYPE(SDL_Point, free);
81
+
69
82
  static void Window_destroy_internal(Window* w)
70
83
  {
71
84
  int i;
@@ -89,12 +102,13 @@ static void Window_free(Window* w)
89
102
 
90
103
  static VALUE Window_new(SDL_Window* window)
91
104
  {
92
- Window* w = ALLOC(Window);
105
+ Window* w;
106
+ VALUE obj = TypedData_Make_Struct(cWindow, Window, &Window_data_type, w);
93
107
  w->window = window;
94
108
  w->num_renderers = 0;
95
109
  w->max_renderers = 4;
96
110
  w->renderers = ALLOC_N(struct Renderer*, 4);
97
- return Data_Wrap_Struct(cWindow, 0, Window_free, w);
111
+ return obj;
98
112
  }
99
113
 
100
114
  DEFINE_GETTER(static, Window, cWindow, "SDL2::Window");
@@ -111,24 +125,24 @@ static VALUE Display_new(int index)
111
125
 
112
126
  static VALUE DisplayMode_s_allocate(VALUE klass)
113
127
  {
114
- SDL_DisplayMode* mode = ALLOC(SDL_DisplayMode);
128
+ SDL_DisplayMode* mode;
129
+ VALUE obj = TypedData_Make_Struct(klass, SDL_DisplayMode, &SDL_DisplayMode_data_type, mode);
115
130
  mode->format = mode->w = mode->h = mode->refresh_rate = 0;
116
131
  mode->driverdata = NULL;
117
- return Data_Wrap_Struct(klass, 0, free, mode);
132
+ return obj;
118
133
  }
119
134
 
120
135
  static VALUE DisplayMode_new(SDL_DisplayMode* mode)
121
136
  {
122
137
  VALUE display_mode = DisplayMode_s_allocate(cDisplayMode);
123
138
  SDL_DisplayMode* m;
124
- Data_Get_Struct(display_mode, SDL_DisplayMode, m);
139
+ TypedData_Get_Struct(display_mode, SDL_DisplayMode, &SDL_DisplayMode_data_type, m);
125
140
  *m = *mode;
126
141
  return display_mode;
127
142
  }
128
143
 
129
144
  DEFINE_GETTER(static, SDL_DisplayMode, cDisplayMode, "SDL2::Display::Mode");
130
145
 
131
- static void Texture_free(Texture*);
132
146
  static void Renderer_destroy_internal(Renderer* r)
133
147
  {
134
148
  int i;
@@ -167,14 +181,15 @@ static void Window_attach_renderer(Window* w, Renderer* r)
167
181
 
168
182
  static VALUE Renderer_new(SDL_Renderer* renderer, Window* w)
169
183
  {
170
- Renderer* r = ALLOC(Renderer);
184
+ Renderer* r;
185
+ VALUE obj = TypedData_Make_Struct(cRenderer, Renderer, &Renderer_data_type, r);
171
186
  r->renderer = renderer;
172
187
  r->num_textures = 0;
173
188
  r->max_textures = 16;
174
189
  r->textures = ALLOC_N(Texture*, 16);
175
190
  r->refcount = 1;
176
191
  Window_attach_renderer(w, r);
177
- return Data_Wrap_Struct(cRenderer, 0, Renderer_free, r);
192
+ return obj;
178
193
  }
179
194
 
180
195
  DEFINE_WRAPPER(SDL_Renderer, Renderer, renderer, cRenderer, "SDL2::Renderer");
@@ -209,11 +224,12 @@ static void Renderer_attach_texture(Renderer* r, Texture* t)
209
224
 
210
225
  static VALUE Texture_new(SDL_Texture* texture, Renderer* r)
211
226
  {
212
- Texture* t = ALLOC(Texture);
227
+ Texture* t;
228
+ VALUE obj = TypedData_Make_Struct(cTexture, Texture, &Texture_data_type, t);
213
229
  t->texture = texture;
214
230
  t->refcount = 1;
215
231
  Renderer_attach_texture(r, t);
216
- return Data_Wrap_Struct(cTexture, 0, Texture_free, t);
232
+ return obj;
217
233
  }
218
234
 
219
235
  DEFINE_WRAPPER(SDL_Texture, Texture, texture, cTexture, "SDL2::Texture");
@@ -231,10 +247,11 @@ static void Surface_free(Surface* s)
231
247
 
232
248
  VALUE Surface_new(SDL_Surface* surface)
233
249
  {
234
- Surface* s = ALLOC(Surface);
250
+ Surface* s;
251
+ VALUE obj = TypedData_Make_Struct(cSurface, Surface, &Surface_data_type, s);
235
252
  s->surface = surface;
236
253
  s->need_to_free_pixels = 0;
237
- return Data_Wrap_Struct(cSurface, 0, Surface_free, s);
254
+ return obj;
238
255
  }
239
256
 
240
257
  DEFINE_WRAPPER(SDL_Surface, Surface, surface, cSurface, "SDL2::Surface");
@@ -1323,6 +1340,54 @@ static VALUE Renderer_present(VALUE self)
1323
1340
  return Qnil;
1324
1341
  }
1325
1342
 
1343
+ /*
1344
+ * @overload read_pixels(rect, format)
1345
+ * Read pixels from the current rendering target.
1346
+ *
1347
+ * ## Remarks
1348
+ *
1349
+ * **WARNING**: This is a very slow operation, and should not be used frequently.
1350
+ * If you're using this on the main rendering target, it should be called after
1351
+ * rendering and before {#present}.
1352
+ *
1353
+ * @param [SDL2::Rect,nil] rect the area to read, or nil for the entire target
1354
+ * @param [SDL2::PixelFormat,Integer] format the desired pixel format
1355
+ * (0 to use the format of the rendering target)
1356
+ * @return [String] raw pixel data as a binary string
1357
+ */
1358
+ static VALUE Renderer_read_pixels(VALUE self, VALUE rect, VALUE format)
1359
+ {
1360
+ SDL_Renderer* renderer = Get_SDL_Renderer(self);
1361
+ SDL_Rect sdl_rect;
1362
+ SDL_Rect* rect_ptr = NULL;
1363
+ Uint32 fmt = uint32_for_format(format);
1364
+ int w, h, pitch;
1365
+ void* pixels;
1366
+
1367
+ if (rect != Qnil) {
1368
+ sdl_rect = *Get_SDL_Rect(rect);
1369
+ rect_ptr = &sdl_rect;
1370
+ w = sdl_rect.w;
1371
+ h = sdl_rect.h;
1372
+ } else {
1373
+ HANDLE_ERROR(SDL_GetRendererOutputSize(renderer, &w, &h));
1374
+ }
1375
+
1376
+ if (fmt == 0) {
1377
+ SDL_RendererInfo info;
1378
+ HANDLE_ERROR(SDL_GetRendererInfo(renderer, &info));
1379
+ pitch = w * SDL_BYTESPERPIXEL(info.texture_formats[0]);
1380
+ } else {
1381
+ pitch = w * SDL_BYTESPERPIXEL(fmt);
1382
+ }
1383
+
1384
+ pixels = ALLOCA_N(char, pitch * h);
1385
+
1386
+ HANDLE_ERROR(SDL_RenderReadPixels(renderer, rect_ptr, fmt, pixels, pitch));
1387
+
1388
+ return rb_str_new(pixels, pitch * h);
1389
+ }
1390
+
1326
1391
  /*
1327
1392
  * Crear the rendering target with the drawing color.
1328
1393
  * @return [nil]
@@ -2048,6 +2113,7 @@ static VALUE Surface_s_from_string(int argc, VALUE* argv, VALUE self)
2048
2113
  SDL_Surface* surface;
2049
2114
  void* pixels;
2050
2115
  Surface* s;
2116
+ VALUE obj;
2051
2117
 
2052
2118
  rb_scan_args(argc, argv, "45", &string, &width, &height, &depth,
2053
2119
  &pitch, &Rmask, &Gmask, &Bmask, &Amask);
@@ -2074,10 +2140,10 @@ static VALUE Surface_s_from_string(int argc, VALUE* argv, VALUE self)
2074
2140
 
2075
2141
  RB_GC_GUARD(string);
2076
2142
 
2077
- s = ALLOC(Surface);
2143
+ obj = TypedData_Make_Struct(cSurface, Surface, &Surface_data_type, s);
2078
2144
  s->surface = surface;
2079
2145
  s->need_to_free_pixels = 1;
2080
- return Data_Wrap_Struct(cSurface, 0, Surface_free, s);
2146
+ return obj;
2081
2147
  }
2082
2148
 
2083
2149
  /*
@@ -2431,12 +2497,14 @@ static VALUE Surface_s_new(int argc, VALUE* argv, VALUE self)
2431
2497
  #define FIELD_ACCESSOR(classname, typename, field) \
2432
2498
  static VALUE classname##_##field(VALUE self) \
2433
2499
  { \
2434
- typename* r; Data_Get_Struct(self, typename, r); \
2500
+ typename* r; \
2501
+ TypedData_Get_Struct(self, typename, &typename##_data_type, r); \
2435
2502
  return INT2NUM(r->field); \
2436
2503
  } \
2437
2504
  static VALUE classname##_set_##field(VALUE self, VALUE val) \
2438
2505
  { \
2439
- typename* r; Data_Get_Struct(self, typename, r); \
2506
+ typename* r; \
2507
+ TypedData_Get_Struct(self, typename, &typename##_data_type, r); \
2440
2508
  r->field = NUM2INT(val); return val; \
2441
2509
  }
2442
2510
 
@@ -2475,10 +2543,10 @@ static VALUE Surface_s_new(int argc, VALUE* argv, VALUE self)
2475
2543
  */
2476
2544
  static VALUE Rect_s_allocate(VALUE klass)
2477
2545
  {
2478
- SDL_Rect* rect = ALLOC(SDL_Rect);
2546
+ SDL_Rect* rect;
2547
+ VALUE obj = TypedData_Make_Struct(klass, SDL_Rect, &SDL_Rect_data_type, rect);
2479
2548
  rect->x = rect->y = rect->w = rect->h = 0;
2480
-
2481
- return Data_Wrap_Struct(cRect, 0, free, rect);
2549
+ return obj;
2482
2550
  }
2483
2551
 
2484
2552
  /*
@@ -2506,7 +2574,7 @@ static VALUE Rect_initialize(int argc, VALUE* argv, VALUE self)
2506
2574
  /* do nothing*/
2507
2575
  } else if (argc == 4) {
2508
2576
  SDL_Rect* rect;
2509
- Data_Get_Struct(self, SDL_Rect, rect);
2577
+ TypedData_Get_Struct(self, SDL_Rect, &SDL_Rect_data_type, rect);
2510
2578
  rect->x = NUM2INT(x); rect->y = NUM2INT(y);
2511
2579
  rect->w = NUM2INT(w); rect->h = NUM2INT(h);
2512
2580
  } else {
@@ -2581,7 +2649,7 @@ static VALUE Rect_union(VALUE self, VALUE other)
2581
2649
  static VALUE Point_s_allocate(VALUE klass)
2582
2650
  {
2583
2651
  SDL_Point* point;
2584
- return Data_Make_Struct(klass, SDL_Point, 0, free, point);
2652
+ return TypedData_Make_Struct(klass, SDL_Point, &SDL_Point_data_type, point);
2585
2653
  }
2586
2654
 
2587
2655
  /*
@@ -2919,6 +2987,7 @@ void rubysdl2_init_video(void)
2919
2987
  rb_define_method(cRenderer, "copy", Renderer_copy, 3);
2920
2988
  rb_define_method(cRenderer, "copy_ex", Renderer_copy_ex, 6);
2921
2989
  rb_define_method(cRenderer, "present", Renderer_present, 0);
2990
+ rb_define_method(cRenderer, "read_pixels", Renderer_read_pixels, 2);
2922
2991
  rb_define_method(cRenderer, "draw_color",Renderer_draw_color, 0);
2923
2992
  rb_define_method(cRenderer, "draw_color=",Renderer_set_draw_color, 1);
2924
2993
  rb_define_method(cRenderer, "clear", Renderer_clear, 0);
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-sdl2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ippei Obayashi
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2023-05-21 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies: []
13
12
  description: |2
14
13
  Ruby/SDL2 is an extension library to use SDL 2.x
@@ -69,6 +68,7 @@ files:
69
68
  - sample/test_joystick.rb
70
69
  - sample/test_keyboard.rb
71
70
  - sample/test_mouse.rb
71
+ - sample/test_read_pixels.rb
72
72
  - sample/test_surface.rb
73
73
  - sample/test_ttf.rb
74
74
  - sample/test_video.rb
@@ -87,7 +87,6 @@ homepage: https://github.com/ohai/ruby-sdl2
87
87
  licenses:
88
88
  - LGPL-3.0
89
89
  metadata: {}
90
- post_install_message:
91
90
  rdoc_options: []
92
91
  require_paths:
93
92
  - lib
@@ -102,8 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
101
  - !ruby/object:Gem::Version
103
102
  version: '0'
104
103
  requirements: []
105
- rubygems_version: 3.4.10
106
- signing_key:
104
+ rubygems_version: 4.0.3
107
105
  specification_version: 4
108
106
  summary: The simple ruby extension library for SDL 2.x
109
107
  test_files: []