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 +4 -4
- data/Gemfile +2 -3
- data/README.md +3 -1
- data/event.c +33 -29
- data/gamecontroller.c +5 -2
- data/gamecontroller.c.m4 +5 -2
- data/gl.c +7 -4
- data/gl.c.m4 +7 -4
- data/joystick.c +5 -2
- data/joystick.c.m4 +5 -2
- data/lib/sdl2/version.rb +1 -1
- data/mixer.c +13 -7
- data/mixer.c.m4 +13 -7
- data/rubysdl2_internal.h +12 -1
- data/sample/test_read_pixels.rb +41 -0
- data/ttf.c +5 -2
- data/ttf.c.m4 +5 -2
- data/video.c +90 -21
- data/video.c.m4 +90 -21
- metadata +4 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9a1d841e87d0b4437b0eb204f4062d451ff279a49bbae6b98fc70af51daf36f7
|
|
4
|
+
data.tar.gz: 933024c5bc62bbcb3b7fcdaec2dabdc89a54185a16c82d18a5483dde3c8443c6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
9
|
-
gem "steep"
|
|
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](
|
|
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
|
|
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
|
|
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
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
|
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;
|
|
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;
|
|
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
|
-
|
|
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;
|
|
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
|
-
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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
|
|
65
|
+
GameController* g;
|
|
66
|
+
VALUE obj = TypedData_Make_Struct(cGameController, GameController, &GameController_data_type, g);
|
|
64
67
|
g->controller = controller;
|
|
65
|
-
return
|
|
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
|
|
65
|
+
GameController* g;
|
|
66
|
+
VALUE obj = TypedData_Make_Struct(cGameController, GameController, &GameController_data_type, g);
|
|
64
67
|
g->controller = controller;
|
|
65
|
-
return
|
|
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
|
|
28
|
+
GLContext* c;
|
|
29
|
+
VALUE obj = TypedData_Make_Struct(cGLContext, GLContext, &GLContext_data_type, c);
|
|
27
30
|
c->context = context;
|
|
28
|
-
return
|
|
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
|
|
28
|
+
GLContext* c;
|
|
29
|
+
VALUE obj = TypedData_Make_Struct(cGLContext, GLContext, &GLContext_data_type, c);
|
|
27
30
|
c->context = context;
|
|
28
|
-
return
|
|
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
|
|
25
|
+
Joystick* j;
|
|
26
|
+
VALUE obj = TypedData_Make_Struct(cJoystick, Joystick, &Joystick_data_type, j);
|
|
24
27
|
j->joystick = joystick;
|
|
25
|
-
return
|
|
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
|
|
25
|
+
Joystick* j;
|
|
26
|
+
VALUE obj = TypedData_Make_Struct(cJoystick, Joystick, &Joystick_data_type, j);
|
|
24
27
|
j->joystick = joystick;
|
|
25
|
-
return
|
|
28
|
+
return obj;
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
DEFINE_WRAPPER(SDL_Joystick, Joystick, joystick, cJoystick, "SDL2::Joystick");
|
data/lib/sdl2/version.rb
CHANGED
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
|
|
39
|
+
Chunk* c;
|
|
40
|
+
VALUE obj = TypedData_Make_Struct(cChunk, Chunk, &Chunk_data_type, c);
|
|
38
41
|
c->chunk = chunk;
|
|
39
|
-
return
|
|
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
|
|
58
|
+
Music* c;
|
|
59
|
+
VALUE obj = TypedData_Make_Struct(cMusic, Music, &Music_data_type, c);
|
|
54
60
|
c->music = music;
|
|
55
|
-
return
|
|
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
|
|
39
|
+
Chunk* c;
|
|
40
|
+
VALUE obj = TypedData_Make_Struct(cChunk, Chunk, &Chunk_data_type, c);
|
|
38
41
|
c->chunk = chunk;
|
|
39
|
-
return
|
|
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
|
|
58
|
+
Music* c;
|
|
59
|
+
VALUE obj = TypedData_Make_Struct(cMusic, Music, &Music_data_type, c);
|
|
54
60
|
c->music = music;
|
|
55
|
-
return
|
|
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
|
-
|
|
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
|
|
50
|
+
TTF* f;
|
|
51
|
+
VALUE obj = TypedData_Make_Struct(cTTF, TTF, &TTF_data_type, f);
|
|
49
52
|
f->font = font;
|
|
50
|
-
return
|
|
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
|
|
50
|
+
TTF* f;
|
|
51
|
+
VALUE obj = TypedData_Make_Struct(cTTF, TTF, &TTF_data_type, f);
|
|
49
52
|
f->font = font;
|
|
50
|
-
return
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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;
|
|
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;
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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;
|
|
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;
|
|
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
|
|
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
|
-
|
|
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
|
|
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.
|
|
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:
|
|
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:
|
|
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: []
|