sfml3-rb 0.2.2 → 0.3.1
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/.yardopts +9 -0
- data/CHANGELOG.md +67 -16
- data/README.md +123 -32
- data/TODO.md +18 -11
- data/ext/audio/audio_enums.c +58 -20
- data/ext/audio/listener.c +89 -6
- data/ext/audio/music.c +212 -5
- data/ext/audio/sound.c +218 -9
- data/ext/audio/sound_buffer.c +197 -47
- data/ext/audio/sound_buffer_recorder.c +90 -18
- data/ext/audio/sound_recorder.c +188 -58
- data/ext/audio/sound_source_cone.c +127 -33
- data/ext/audio/sound_stream.c +204 -21
- data/ext/core/exceptions.c +10 -8
- data/ext/core/unicode.c +12 -2
- data/ext/ext.c +8 -0
- data/ext/graphics/blend_mode.c +218 -60
- data/ext/graphics/circle.c +300 -16
- data/ext/graphics/color.c +253 -94
- data/ext/graphics/drawable.c +16 -4
- data/ext/graphics/font.c +144 -25
- data/ext/graphics/glyph.c +38 -8
- data/ext/graphics/image.c +205 -41
- data/ext/graphics/polygon.c +317 -30
- data/ext/graphics/rect.c +225 -60
- data/ext/graphics/rectangle.c +307 -35
- data/ext/graphics/render_state.c +124 -12
- data/ext/graphics/render_texture.c +191 -14
- data/ext/graphics/render_window.c +55 -0
- data/ext/graphics/render_window.h +10 -0
- data/ext/graphics/shader.c +289 -17
- data/ext/graphics/shape.c +265 -32
- data/ext/graphics/sprite.c +245 -30
- data/ext/graphics/stencil_mode.c +163 -46
- data/ext/graphics/target.c +121 -43
- data/ext/graphics/target.h +31 -17
- data/ext/graphics/text.c +339 -19
- data/ext/graphics/texture.c +291 -6
- data/ext/graphics/transform.c +178 -5
- data/ext/graphics/transformable.c +127 -12
- data/ext/graphics/vertex.c +98 -6
- data/ext/graphics/vertex_array.c +142 -21
- data/ext/graphics/vertex_buffer.c +154 -12
- data/ext/graphics/view.c +140 -6
- data/ext/network/ftp.c +278 -12
- data/ext/network/http.c +179 -44
- data/ext/network/ip_address.c +127 -35
- data/ext/network/network_enums.c +248 -141
- data/ext/network/packet.c +280 -41
- data/ext/network/socket_selector.c +98 -21
- data/ext/network/tcp_listener.c +82 -18
- data/ext/network/tcp_socket.c +135 -27
- data/ext/network/udp_socket.c +129 -28
- data/ext/ports.rb +7 -0
- data/ext/system/buffer.c +47 -16
- data/ext/system/clock.c +77 -12
- data/ext/system/input_stream.c +113 -51
- data/ext/system/sleep.c +10 -2
- data/ext/system/time.c +182 -40
- data/ext/system/vec2.c +166 -39
- data/ext/system/vec3.c +177 -39
- data/ext/window/clipboard.c +47 -17
- data/ext/window/context.c +66 -13
- data/ext/window/context_settings.c +132 -42
- data/ext/window/cursor.c +45 -9
- data/ext/window/event.c +164 -53
- data/ext/window/joystick.c +69 -3
- data/ext/window/keyboard.c +168 -116
- data/ext/window/mouse.c +64 -13
- data/ext/window/sensor.c +28 -2
- data/ext/window/touch.c +32 -12
- data/ext/window/video_mode.c +93 -31
- data/ext/window/vulkan.c +34 -6
- data/ext/window/window.c +228 -229
- data/ext/window/window.h +4 -4
- data/ext/window/window_base.c +251 -0
- data/ext/window/window_base.h +43 -0
- data/ext/window/window_base.inc +236 -0
- data/lib/sfml/version.rb +1 -1
- data/sig/audio/audio_enums.rbs +30 -0
- data/sig/audio/listener.rbs +16 -0
- data/sig/audio/music.rbs +56 -0
- data/sig/audio/sound.rbs +51 -0
- data/sig/audio/sound_buffer.rbs +17 -0
- data/sig/audio/sound_buffer_recorder.rbs +14 -0
- data/sig/audio/sound_recorder.rbs +17 -0
- data/sig/audio/sound_source_cone.rbs +14 -0
- data/sig/audio/sound_stream.rbs +51 -0
- data/sig/graphics/blend_mode.rbs +29 -0
- data/sig/graphics/circle.rbs +44 -0
- data/sig/graphics/color.rbs +39 -0
- data/sig/graphics/drawable.rbs +5 -0
- data/sig/graphics/font.rbs +20 -0
- data/sig/graphics/glyph.rbs +7 -0
- data/sig/graphics/image.rbs +22 -0
- data/sig/graphics/polygon.rbs +42 -0
- data/sig/graphics/rect.rbs +33 -0
- data/sig/graphics/rectangle.rbs +42 -0
- data/sig/graphics/render_state.rbs +21 -0
- data/sig/graphics/render_target.rbs +18 -0
- data/sig/graphics/render_texture.rbs +39 -0
- data/sig/graphics/render_window.rbs +7 -0
- data/sig/graphics/shader.rbs +39 -0
- data/sig/graphics/shape.rbs +38 -0
- data/sig/graphics/sprite.rbs +34 -0
- data/sig/graphics/stencil_mode.rbs +18 -0
- data/sig/graphics/target.rbs +8 -0
- data/sig/graphics/text.rbs +48 -0
- data/sig/graphics/texture.rbs +34 -0
- data/sig/graphics/transform.rbs +37 -0
- data/sig/graphics/transformable.rbs +25 -0
- data/sig/graphics/vertex.rbs +17 -0
- data/sig/graphics/vertex_array.rbs +17 -0
- data/sig/graphics/vertex_buffer.rbs +22 -0
- data/sig/graphics/view.rbs +23 -0
- data/sig/network/ftp.rbs +46 -0
- data/sig/network/http.rbs +27 -0
- data/sig/network/ip_address.rbs +22 -0
- data/sig/network/network_enums.rbs +95 -0
- data/sig/network/packet.rbs +40 -0
- data/sig/network/socket_selector.rbs +14 -0
- data/sig/network/tcp_listener.rbs +13 -0
- data/sig/network/tcp_socket.rbs +18 -0
- data/sig/network/udp_socket.rbs +17 -0
- data/sig/sfml/version.rbs +3 -0
- data/sig/system/buffer.rbs +11 -0
- data/sig/system/clock.rbs +13 -0
- data/sig/system/input_stream.rbs +7 -0
- data/sig/system/sleep.rbs +3 -0
- data/sig/system/time.rbs +28 -0
- data/sig/system/vec2.rbs +26 -0
- data/sig/system/vec3.rbs +27 -0
- data/sig/window/clipboard.rbs +8 -0
- data/sig/window/context.rbs +11 -0
- data/sig/window/context_settings.rbs +20 -0
- data/sig/window/cursor.rbs +6 -0
- data/sig/window/event.rbs +20 -0
- data/sig/window/joystick.rbs +15 -0
- data/sig/window/keyboard.rbs +10 -0
- data/sig/window/mouse.rbs +9 -0
- data/sig/window/sensor.rbs +8 -0
- data/sig/window/touch.rbs +6 -0
- data/sig/window/video_mode.rbs +16 -0
- data/sig/window/vulkan.rbs +7 -0
- data/sig/window/window.rbs +34 -0
- data/sig/window/window_base.rbs +33 -0
- metadata +76 -3
|
@@ -12,86 +12,182 @@ typedef struct {
|
|
|
12
12
|
|
|
13
13
|
static VALUE rb_cSoundSourceCone;
|
|
14
14
|
|
|
15
|
-
static void SoundSourceCone_free(void
|
|
15
|
+
static void SoundSourceCone_free(void* ptr) {
|
|
16
16
|
free(ptr);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
static const rb_data_type_t SoundSourceCone_data_type = {
|
|
20
20
|
.wrap_struct_name = "SFML::SoundSourceCone",
|
|
21
21
|
.function = {.dmark = NULL, .dfree = SoundSourceCone_free, .dsize = NULL},
|
|
22
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
23
|
-
};
|
|
22
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY};
|
|
24
23
|
|
|
25
24
|
static VALUE SoundSourceCone_wrap(sfSoundSourceCone cone) {
|
|
26
|
-
SoundSourceCone
|
|
25
|
+
SoundSourceCone* ptr = malloc(sizeof(SoundSourceCone));
|
|
27
26
|
|
|
28
27
|
ptr->cone = cone;
|
|
29
28
|
|
|
30
29
|
return TypedData_Wrap_Struct(rb_cSoundSourceCone, &SoundSourceCone_data_type, ptr);
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
static VALUE
|
|
34
|
-
|
|
35
|
-
.innerAngle = (float) NUM2DBL(rb_inner),
|
|
36
|
-
.outerAngle = (float) NUM2DBL(rb_outer),
|
|
37
|
-
.outerGain = (float) NUM2DBL(rb_gain)
|
|
38
|
-
};
|
|
32
|
+
static VALUE SoundSourceCone_alloc(VALUE klass) {
|
|
33
|
+
SoundSourceCone* ptr = malloc(sizeof(SoundSourceCone));
|
|
39
34
|
|
|
40
|
-
|
|
35
|
+
if (ptr == NULL) {
|
|
36
|
+
rb_raise(rb_eNoMemError, "failed to allocate sound source cone");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
ptr->cone = (sfSoundSourceCone){0.0f, 0.0f, 0.0f};
|
|
40
|
+
|
|
41
|
+
return TypedData_Wrap_Struct(klass, &SoundSourceCone_data_type, ptr);
|
|
41
42
|
}
|
|
42
43
|
|
|
44
|
+
/* call-seq:
|
|
45
|
+
* SoundSourceCone.new(inner_angle, outer_angle, outer_gain) -> SoundSourceCone
|
|
46
|
+
*
|
|
47
|
+
* Creates a directional attenuation cone with the given angles and gain.
|
|
48
|
+
*
|
|
49
|
+
* @return [SoundSourceCone]
|
|
50
|
+
*/
|
|
51
|
+
static VALUE SoundSourceCone_initialize(VALUE self, VALUE rb_inner, VALUE rb_outer, VALUE rb_gain) {
|
|
52
|
+
sfSoundSourceCone cone = {.innerAngle = (float)NUM2DBL(rb_inner),
|
|
53
|
+
.outerAngle = (float)NUM2DBL(rb_outer),
|
|
54
|
+
.outerGain = (float)NUM2DBL(rb_gain)};
|
|
55
|
+
|
|
56
|
+
((SoundSourceCone*)Get_SoundSourceCone_Struct(self))->cone = cone;
|
|
57
|
+
|
|
58
|
+
return self;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* call-seq: inner_angle -> Float
|
|
62
|
+
*
|
|
63
|
+
* Returns the inner cone angle in degrees.
|
|
64
|
+
*
|
|
65
|
+
* @return [Float] angle, in degrees, of the inner cone within which the
|
|
66
|
+
* source is heard at full volume
|
|
67
|
+
*/
|
|
43
68
|
static VALUE SoundSourceCone_get_inner_angle(VALUE self) {
|
|
44
|
-
return DBL2NUM(((SoundSourceCone
|
|
69
|
+
return DBL2NUM(((SoundSourceCone*)Get_SoundSourceCone_Struct(self))->cone.innerAngle);
|
|
45
70
|
}
|
|
46
71
|
|
|
72
|
+
/* call-seq: outer_angle -> Float
|
|
73
|
+
*
|
|
74
|
+
* Returns the outer cone angle in degrees.
|
|
75
|
+
*
|
|
76
|
+
* @return [Float] angle, in degrees, of the outer cone beyond which the
|
|
77
|
+
* source is heard at +outer_gain+ volume
|
|
78
|
+
*/
|
|
47
79
|
static VALUE SoundSourceCone_get_outer_angle(VALUE self) {
|
|
48
|
-
return DBL2NUM(((SoundSourceCone
|
|
80
|
+
return DBL2NUM(((SoundSourceCone*)Get_SoundSourceCone_Struct(self))->cone.outerAngle);
|
|
49
81
|
}
|
|
50
82
|
|
|
83
|
+
/* call-seq: outer_gain -> Float
|
|
84
|
+
*
|
|
85
|
+
* Returns the gain applied outside the outer cone.
|
|
86
|
+
*
|
|
87
|
+
* @return [Float] volume factor applied outside the outer cone
|
|
88
|
+
*/
|
|
51
89
|
static VALUE SoundSourceCone_get_outer_gain(VALUE self) {
|
|
52
|
-
return DBL2NUM(((SoundSourceCone
|
|
90
|
+
return DBL2NUM(((SoundSourceCone*)Get_SoundSourceCone_Struct(self))->cone.outerGain);
|
|
53
91
|
}
|
|
54
92
|
|
|
93
|
+
/* call-seq:
|
|
94
|
+
* inner_angle=(value) -> Float
|
|
95
|
+
*
|
|
96
|
+
* Sets the inner cone angle in degrees.
|
|
97
|
+
*
|
|
98
|
+
* @return [Float] +value+
|
|
99
|
+
*/
|
|
55
100
|
static VALUE SoundSourceCone_set_inner_angle(VALUE self, VALUE rb_value) {
|
|
56
|
-
((SoundSourceCone
|
|
101
|
+
((SoundSourceCone*)Get_SoundSourceCone_Struct(self))->cone.innerAngle =
|
|
102
|
+
(float)NUM2DBL(rb_value);
|
|
57
103
|
return rb_value;
|
|
58
104
|
}
|
|
59
105
|
|
|
106
|
+
/* call-seq:
|
|
107
|
+
* outer_angle=(value) -> Float
|
|
108
|
+
*
|
|
109
|
+
* Sets the outer cone angle in degrees.
|
|
110
|
+
*
|
|
111
|
+
* @return [Float] +value+
|
|
112
|
+
*/
|
|
60
113
|
static VALUE SoundSourceCone_set_outer_angle(VALUE self, VALUE rb_value) {
|
|
61
|
-
((SoundSourceCone
|
|
114
|
+
((SoundSourceCone*)Get_SoundSourceCone_Struct(self))->cone.outerAngle =
|
|
115
|
+
(float)NUM2DBL(rb_value);
|
|
62
116
|
return rb_value;
|
|
63
117
|
}
|
|
64
118
|
|
|
119
|
+
/* call-seq:
|
|
120
|
+
* outer_gain=(value) -> Float
|
|
121
|
+
*
|
|
122
|
+
* Sets the gain applied outside the outer cone.
|
|
123
|
+
*
|
|
124
|
+
* @return [Float] +value+
|
|
125
|
+
*/
|
|
65
126
|
static VALUE SoundSourceCone_set_outer_gain(VALUE self, VALUE rb_value) {
|
|
66
|
-
((SoundSourceCone
|
|
127
|
+
((SoundSourceCone*)Get_SoundSourceCone_Struct(self))->cone.outerGain = (float)NUM2DBL(rb_value);
|
|
67
128
|
return rb_value;
|
|
68
129
|
}
|
|
69
130
|
|
|
131
|
+
/* call-seq: to_a -> [Float, Float, Float]
|
|
132
|
+
*
|
|
133
|
+
* Returns the cone's three components as an Array.
|
|
134
|
+
*
|
|
135
|
+
* @return [Array<Float>] +[inner_angle, outer_angle, outer_gain]+
|
|
136
|
+
*/
|
|
70
137
|
static VALUE SoundSourceCone_to_a(VALUE self) {
|
|
71
|
-
sfSoundSourceCone cone = ((SoundSourceCone
|
|
138
|
+
sfSoundSourceCone cone = ((SoundSourceCone*)Get_SoundSourceCone_Struct(self))->cone;
|
|
72
139
|
|
|
73
140
|
return rb_ary_new_from_args(3, DBL2NUM(cone.innerAngle), DBL2NUM(cone.outerAngle),
|
|
74
141
|
DBL2NUM(cone.outerGain));
|
|
75
142
|
}
|
|
76
143
|
|
|
144
|
+
/* call-seq:
|
|
145
|
+
* self == other -> true or false
|
|
146
|
+
*
|
|
147
|
+
* Returns +true+ if +other+ is a cone with the same angles and gain.
|
|
148
|
+
*
|
|
149
|
+
* @return [Boolean]
|
|
150
|
+
*/
|
|
77
151
|
static VALUE SoundSourceCone_eql(VALUE self, VALUE rb_other) {
|
|
78
|
-
sfSoundSourceCone a = ((SoundSourceCone
|
|
152
|
+
sfSoundSourceCone a = ((SoundSourceCone*)Get_SoundSourceCone_Struct(self))->cone;
|
|
79
153
|
sfSoundSourceCone b;
|
|
80
154
|
|
|
81
155
|
if (!rb_obj_is_kind_of(rb_other, rb_cSoundSourceCone)) {
|
|
82
156
|
return Qfalse;
|
|
83
157
|
}
|
|
84
158
|
|
|
85
|
-
b = ((SoundSourceCone
|
|
159
|
+
b = ((SoundSourceCone*)Get_SoundSourceCone_Struct(rb_other))->cone;
|
|
86
160
|
|
|
87
161
|
return BOOL2RB(a.innerAngle == b.innerAngle && a.outerAngle == b.outerAngle &&
|
|
88
162
|
a.outerGain == b.outerGain);
|
|
89
163
|
}
|
|
90
164
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
165
|
+
/* Document-class: SFML::SoundSourceCone
|
|
166
|
+
* A directional attenuation cone for a SoundSource (SoundSource#cone) or the
|
|
167
|
+
* Listener (Listener.cone): within +inner_angle+ degrees of the facing
|
|
168
|
+
* direction the source is heard at full volume; beyond +outer_angle+
|
|
169
|
+
* degrees it is heard at +outer_gain+ volume, with a smooth transition in
|
|
170
|
+
* between.
|
|
171
|
+
*
|
|
172
|
+
* @!attribute inner_angle
|
|
173
|
+
* Angle, in degrees, of the inner cone within which the source is heard at
|
|
174
|
+
* full volume.
|
|
175
|
+
* @return [Float] angle, in degrees, of the inner cone within which the
|
|
176
|
+
* source is heard at full volume
|
|
177
|
+
* @!attribute outer_angle
|
|
178
|
+
* Angle, in degrees, of the outer cone beyond which the source is heard at
|
|
179
|
+
* +outer_gain+ volume.
|
|
180
|
+
* @return [Float] angle, in degrees, of the outer cone beyond which the
|
|
181
|
+
* source is heard at +outer_gain+ volume
|
|
182
|
+
* @!attribute outer_gain
|
|
183
|
+
* Volume factor applied outside the outer cone.
|
|
184
|
+
* @return [Float] volume factor applied outside the outer cone
|
|
185
|
+
*/
|
|
186
|
+
void Init_SoundSourceCone(VALUE rb_mSFML) {
|
|
187
|
+
rb_cSoundSourceCone = rb_define_class_under(rb_mSFML, "SoundSourceCone", rb_cObject);
|
|
188
|
+
|
|
189
|
+
rb_define_alloc_func(rb_cSoundSourceCone, SoundSourceCone_alloc);
|
|
190
|
+
rb_define_method(rb_cSoundSourceCone, "initialize", SoundSourceCone_initialize, 3);
|
|
95
191
|
|
|
96
192
|
rb_define_method(rb_cSoundSourceCone, "inner_angle", SoundSourceCone_get_inner_angle, 0);
|
|
97
193
|
rb_define_method(rb_cSoundSourceCone, "outer_angle", SoundSourceCone_get_outer_angle, 0);
|
|
@@ -107,30 +203,28 @@ VALUE Get_Klass_SoundSourceCone(void) {
|
|
|
107
203
|
return rb_cSoundSourceCone;
|
|
108
204
|
}
|
|
109
205
|
|
|
110
|
-
void
|
|
111
|
-
SoundSourceCone
|
|
206
|
+
void* Get_SoundSourceCone_Struct(VALUE self) {
|
|
207
|
+
SoundSourceCone* ptr;
|
|
112
208
|
TypedData_Get_Struct(self, SoundSourceCone, &SoundSourceCone_data_type, ptr);
|
|
113
209
|
return ptr;
|
|
114
210
|
}
|
|
115
211
|
|
|
116
212
|
sfSoundSourceCone sound_source_cone_from_rb(VALUE rb_cone) {
|
|
117
213
|
if (rb_obj_is_kind_of(rb_cone, rb_cSoundSourceCone)) {
|
|
118
|
-
return ((SoundSourceCone
|
|
214
|
+
return ((SoundSourceCone*)Get_SoundSourceCone_Struct(rb_cone))->cone;
|
|
119
215
|
}
|
|
120
216
|
|
|
121
217
|
if (RB_TYPE_P(rb_cone, T_ARRAY) && RARRAY_LEN(rb_cone) == 3) {
|
|
122
|
-
sfSoundSourceCone cone = {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
.outerGain = (float) NUM2DBL(rb_ary_entry(rb_cone, 2))
|
|
126
|
-
};
|
|
218
|
+
sfSoundSourceCone cone = {.innerAngle = (float)NUM2DBL(rb_ary_entry(rb_cone, 0)),
|
|
219
|
+
.outerAngle = (float)NUM2DBL(rb_ary_entry(rb_cone, 1)),
|
|
220
|
+
.outerGain = (float)NUM2DBL(rb_ary_entry(rb_cone, 2))};
|
|
127
221
|
|
|
128
222
|
return cone;
|
|
129
223
|
}
|
|
130
224
|
|
|
131
225
|
raise_invalid_argument_class(rb_cSoundSourceCone);
|
|
132
226
|
|
|
133
|
-
return (sfSoundSourceCone)
|
|
227
|
+
return (sfSoundSourceCone){0.0f, 0.0f, 0.0f};
|
|
134
228
|
}
|
|
135
229
|
|
|
136
230
|
VALUE sound_source_cone_to_rb(sfSoundSourceCone cone) {
|
data/ext/audio/sound_stream.c
CHANGED
|
@@ -49,17 +49,25 @@ static void* SoundStream_destroy_without_gvl(void* handle) {
|
|
|
49
49
|
static void SoundStream_free(void* ptr) {
|
|
50
50
|
SoundStream* stream = ptr;
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
/* Destroy (which blocks until CSFML guarantees no in-flight audio-thread
|
|
53
|
+
callback still references this source) before releasing the effect
|
|
54
|
+
slot, not after -- see the matching comment in sound.c's Sound_free. */
|
|
53
55
|
rb_thread_call_without_gvl(SoundStream_destroy_without_gvl, stream->source.handle, RUBY_UBF_IO,
|
|
54
56
|
NULL);
|
|
57
|
+
effect_processor_release(stream->source.effect_slot);
|
|
55
58
|
free(stream->samples);
|
|
56
59
|
free(stream);
|
|
57
60
|
}
|
|
58
61
|
|
|
62
|
+
/* Deliberately no RUBY_TYPED_FREE_IMMEDIATELY: SoundStream_free releases the
|
|
63
|
+
GVL for sfSoundStream_destroy, and freeing during GC (which the flag
|
|
64
|
+
requests) would let another thread allocate while GC is mid-cycle, which
|
|
65
|
+
Ruby aborts on as "object allocation during garbage collection phase".
|
|
66
|
+
Deferred finalization runs the same free with the GVL held and no GC in
|
|
67
|
+
progress. */
|
|
59
68
|
static const rb_data_type_t SoundStream_data_type = {
|
|
60
69
|
.wrap_struct_name = "SFML::SoundStream",
|
|
61
|
-
.function = {.dmark = SoundStream_mark, .dfree = SoundStream_free, .dsize = NULL}
|
|
62
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY};
|
|
70
|
+
.function = {.dmark = SoundStream_mark, .dfree = SoundStream_free, .dsize = NULL}};
|
|
63
71
|
|
|
64
72
|
/* Expands the stream's sample buffer if needed, then copies either a packed
|
|
65
73
|
String of int16 or an Array of Integers into it. Returns the sample count. */
|
|
@@ -185,14 +193,48 @@ static void SoundStream_on_seek(sfTime time, void* userData) {
|
|
|
185
193
|
run_on_ruby_thread(SoundStream_seek_run, &ctx, SOUND_STREAM_CALLBACK_TIMEOUT_MS);
|
|
186
194
|
}
|
|
187
195
|
|
|
188
|
-
static VALUE
|
|
196
|
+
static VALUE SoundStream_alloc(VALUE klass) {
|
|
197
|
+
SoundStream* ptr = malloc(sizeof(SoundStream));
|
|
198
|
+
VALUE self;
|
|
199
|
+
|
|
200
|
+
if (ptr == NULL) {
|
|
201
|
+
rb_raise(rb_eNoMemError, "failed to allocate sound stream");
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
ptr->source.handle = NULL;
|
|
205
|
+
ptr->source.effect_slot = -1;
|
|
206
|
+
ptr->rb_self = Qnil;
|
|
207
|
+
ptr->samples = NULL;
|
|
208
|
+
ptr->samples_capacity = 0;
|
|
209
|
+
|
|
210
|
+
self = TypedData_Wrap_Struct(klass, &SoundStream_data_type, ptr);
|
|
211
|
+
ptr->rb_self = self;
|
|
212
|
+
|
|
213
|
+
return self;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/* call-seq:
|
|
217
|
+
* SoundStream.new(channel_count, sample_rate) -> SoundStream
|
|
218
|
+
* SoundStream.new(channel_count, sample_rate, channel_map) -> SoundStream
|
|
219
|
+
*
|
|
220
|
+
* SoundStream must be subclassed: the subclass is required to implement
|
|
221
|
+
* +#on_get_data+, called from a foreign audio thread whenever more samples
|
|
222
|
+
* are needed, and may optionally implement +#on_seek+. +channel_map+, if
|
|
223
|
+
* given, is an Array of channel Symbols (see SoundChannel), one per channel.
|
|
224
|
+
*
|
|
225
|
+
* @return [SoundStream]
|
|
226
|
+
* @raise [NotImplementedError] if the subclass does not define #on_get_data
|
|
227
|
+
* @raise [RuntimeError] if the underlying stream could not be created
|
|
228
|
+
*/
|
|
229
|
+
static VALUE SoundStream_initialize(int argc, VALUE* argv, VALUE self) {
|
|
189
230
|
VALUE rb_channel_count, rb_sample_rate, rb_channel_map;
|
|
190
231
|
sfSoundChannel* channel_map = NULL;
|
|
191
232
|
size_t channel_map_size = 0;
|
|
192
233
|
SoundStream* ptr;
|
|
193
|
-
VALUE self;
|
|
194
234
|
long i;
|
|
195
235
|
|
|
236
|
+
TypedData_Get_Struct(self, SoundStream, &SoundStream_data_type, ptr);
|
|
237
|
+
|
|
196
238
|
rb_scan_args(argc, argv, "21", &rb_channel_count, &rb_sample_rate, &rb_channel_map);
|
|
197
239
|
|
|
198
240
|
if (!NIL_P(rb_channel_map)) {
|
|
@@ -208,19 +250,7 @@ static VALUE SoundStream_new(int argc, VALUE* argv, VALUE klass) {
|
|
|
208
250
|
}
|
|
209
251
|
}
|
|
210
252
|
|
|
211
|
-
ptr = malloc(sizeof(SoundStream));
|
|
212
|
-
ptr->source.handle = NULL;
|
|
213
|
-
ptr->source.effect_slot = -1;
|
|
214
|
-
ptr->rb_self = Qnil;
|
|
215
|
-
ptr->samples = NULL;
|
|
216
|
-
ptr->samples_capacity = 0;
|
|
217
|
-
|
|
218
|
-
self = TypedData_Wrap_Struct(klass, &SoundStream_data_type, ptr);
|
|
219
|
-
ptr->rb_self = self;
|
|
220
|
-
|
|
221
253
|
if (!rb_respond_to(self, rb_intern("on_get_data"))) {
|
|
222
|
-
/* The wrapper is already owned by Ruby; its dfree tolerates a NULL
|
|
223
|
-
handle, so raising here just leaves it to be collected. */
|
|
224
254
|
free(channel_map);
|
|
225
255
|
rb_raise(rb_eNotImpError, "subclass must define #on_get_data");
|
|
226
256
|
}
|
|
@@ -238,14 +268,33 @@ static VALUE SoundStream_new(int argc, VALUE* argv, VALUE klass) {
|
|
|
238
268
|
return self;
|
|
239
269
|
}
|
|
240
270
|
|
|
271
|
+
/* call-seq: channel_count -> Integer
|
|
272
|
+
*
|
|
273
|
+
* Returns the number of audio channels the stream produces.
|
|
274
|
+
*
|
|
275
|
+
* @return [Integer]
|
|
276
|
+
*/
|
|
241
277
|
static VALUE SoundStream_channel_count(VALUE self) {
|
|
242
278
|
return UINT2NUM(sfSoundStream_getChannelCount(Get_SoundStream_Struct(self)));
|
|
243
279
|
}
|
|
244
280
|
|
|
281
|
+
/* call-seq: sample_rate -> Integer
|
|
282
|
+
*
|
|
283
|
+
* Returns the stream's sample rate in samples per second.
|
|
284
|
+
*
|
|
285
|
+
* @return [Integer]
|
|
286
|
+
*/
|
|
245
287
|
static VALUE SoundStream_sample_rate(VALUE self) {
|
|
246
288
|
return UINT2NUM(sfSoundStream_getSampleRate(Get_SoundStream_Struct(self)));
|
|
247
289
|
}
|
|
248
290
|
|
|
291
|
+
/* call-seq: channel_map -> Array<Symbol>
|
|
292
|
+
*
|
|
293
|
+
* Returns the channel layout of the stream.
|
|
294
|
+
*
|
|
295
|
+
* @return [Array<Symbol>] one entry per channel, e.g.
|
|
296
|
+
* +[:front_left, :front_right]+
|
|
297
|
+
*/
|
|
249
298
|
static VALUE SoundStream_channel_map(VALUE self) {
|
|
250
299
|
size_t count = 0;
|
|
251
300
|
sfSoundChannel* map = sfSoundStream_getChannelMap(Get_SoundStream_Struct(self), &count);
|
|
@@ -271,10 +320,144 @@ static VALUE SoundStream_channel_map(VALUE self) {
|
|
|
271
320
|
#undef SS_FN
|
|
272
321
|
#undef SS_METHOD
|
|
273
322
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
323
|
+
/* Document-class: SFML::SoundStream
|
|
324
|
+
* Base class for a custom audio source that generates or decodes its own
|
|
325
|
+
* samples on demand. Subclasses must implement +#on_get_data+, returning an
|
|
326
|
+
* Array of Integer samples or a packed String of int16 samples for the next
|
|
327
|
+
* chunk (or +nil+/+false+ to signal end of stream), and may implement
|
|
328
|
+
* +#on_seek(time)+ to support seeking.
|
|
329
|
+
*
|
|
330
|
+
* @!method play
|
|
331
|
+
* Starts playback, or resumes it when paused.
|
|
332
|
+
* @return [self]
|
|
333
|
+
* @!method pause
|
|
334
|
+
* Pauses playback, keeping the current playing offset.
|
|
335
|
+
* @return [self]
|
|
336
|
+
* @!method stop
|
|
337
|
+
* Stops playback and rewinds to the beginning. May briefly block the
|
|
338
|
+
* calling thread if an audio-thread callback for this source is in
|
|
339
|
+
* flight.
|
|
340
|
+
* @return [self]
|
|
341
|
+
* @!method status
|
|
342
|
+
* Returns the current playback status.
|
|
343
|
+
* @return [Symbol] one of +:stopped+, +:paused+, +:playing+
|
|
344
|
+
* @!method looping?
|
|
345
|
+
* Returns +true+ if playback loops back to the start on completion.
|
|
346
|
+
* @return [Boolean]
|
|
347
|
+
* @!method looping=(value)
|
|
348
|
+
* Enables or disables looping.
|
|
349
|
+
* @return [Boolean]
|
|
350
|
+
* @!method pitch
|
|
351
|
+
* Returns the pitch scaling factor.
|
|
352
|
+
* @return [Float]
|
|
353
|
+
* @!method pitch=(value)
|
|
354
|
+
* Sets the pitch scaling factor.
|
|
355
|
+
* @return [Float]
|
|
356
|
+
* @!method pan
|
|
357
|
+
* Returns the source's stereo pan.
|
|
358
|
+
* @return [Float] stereo pan, -1 (left) to 1 (right)
|
|
359
|
+
* @!method pan=(value)
|
|
360
|
+
* Sets the source's stereo pan.
|
|
361
|
+
* @return [Float]
|
|
362
|
+
* @!method volume
|
|
363
|
+
* Returns the source's volume.
|
|
364
|
+
* @return [Float] 0 to 100
|
|
365
|
+
* @!method volume=(value)
|
|
366
|
+
* Sets the source's volume.
|
|
367
|
+
* @return [Float]
|
|
368
|
+
* @!method spatialization_enabled?
|
|
369
|
+
* Returns +true+ if 3D spatialization is enabled.
|
|
370
|
+
* @return [Boolean]
|
|
371
|
+
* @!method spatialization_enabled=(value)
|
|
372
|
+
* Enables or disables 3D spatialization.
|
|
373
|
+
* @return [Boolean]
|
|
374
|
+
* @!method position
|
|
375
|
+
* Returns the source's position in 3D space.
|
|
376
|
+
* @return [Vector3]
|
|
377
|
+
* @!method position=(value)
|
|
378
|
+
* Sets the source's position in 3D space.
|
|
379
|
+
* @return [Vector3]
|
|
380
|
+
* @!method direction
|
|
381
|
+
* Returns the direction the source is facing.
|
|
382
|
+
* @return [Vector3]
|
|
383
|
+
* @!method direction=(value)
|
|
384
|
+
* Sets the direction the source is facing.
|
|
385
|
+
* @return [Vector3]
|
|
386
|
+
* @!method velocity
|
|
387
|
+
* Returns the source's velocity, used for Doppler calculations.
|
|
388
|
+
* @return [Vector3]
|
|
389
|
+
* @!method velocity=(value)
|
|
390
|
+
* Sets the source's velocity for Doppler calculations.
|
|
391
|
+
* @return [Vector3]
|
|
392
|
+
* @!method cone
|
|
393
|
+
* Returns the source's directional attenuation cone.
|
|
394
|
+
* @return [SoundSourceCone]
|
|
395
|
+
* @!method cone=(value)
|
|
396
|
+
* Sets the source's directional attenuation cone.
|
|
397
|
+
* @return [SoundSourceCone]
|
|
398
|
+
* @!method doppler_factor
|
|
399
|
+
* Returns the factor by which the Doppler effect is scaled.
|
|
400
|
+
* @return [Float]
|
|
401
|
+
* @!method doppler_factor=(value)
|
|
402
|
+
* Sets the factor by which the Doppler effect is scaled.
|
|
403
|
+
* @return [Float]
|
|
404
|
+
* @!method directional_attenuation_factor
|
|
405
|
+
* Returns the factor controlling directional attenuation.
|
|
406
|
+
* @return [Float]
|
|
407
|
+
* @!method directional_attenuation_factor=(value)
|
|
408
|
+
* Sets the factor controlling directional attenuation.
|
|
409
|
+
* @return [Float]
|
|
410
|
+
* @!method relative_to_listener?
|
|
411
|
+
* Returns +true+ if the source is positioned relative to the listener.
|
|
412
|
+
* @return [Boolean]
|
|
413
|
+
* @!method relative_to_listener=(value)
|
|
414
|
+
* Makes the source relative to, or independent of, the listener.
|
|
415
|
+
* @return [Boolean]
|
|
416
|
+
* @!method min_distance
|
|
417
|
+
* Returns the minimum distance of the distance-attenuation model.
|
|
418
|
+
* @return [Float]
|
|
419
|
+
* @!method min_distance=(value)
|
|
420
|
+
* Sets the minimum distance of the distance-attenuation model.
|
|
421
|
+
* @return [Float]
|
|
422
|
+
* @!method max_distance
|
|
423
|
+
* Returns the maximum distance of the distance-attenuation model.
|
|
424
|
+
* @return [Float]
|
|
425
|
+
* @!method max_distance=(value)
|
|
426
|
+
* Sets the maximum distance of the distance-attenuation model.
|
|
427
|
+
* @return [Float]
|
|
428
|
+
* @!method min_gain
|
|
429
|
+
* Returns the minimum gain of the distance-attenuation model.
|
|
430
|
+
* @return [Float]
|
|
431
|
+
* @!method min_gain=(value)
|
|
432
|
+
* Sets the minimum gain of the distance-attenuation model.
|
|
433
|
+
* @return [Float]
|
|
434
|
+
* @!method max_gain
|
|
435
|
+
* Returns the maximum gain of the distance-attenuation model.
|
|
436
|
+
* @return [Float]
|
|
437
|
+
* @!method max_gain=(value)
|
|
438
|
+
* Sets the maximum gain of the distance-attenuation model.
|
|
439
|
+
* @return [Float]
|
|
440
|
+
* @!method attenuation
|
|
441
|
+
* Returns the distance-attenuation factor.
|
|
442
|
+
* @return [Float]
|
|
443
|
+
* @!method attenuation=(value)
|
|
444
|
+
* Sets the distance-attenuation factor.
|
|
445
|
+
* @return [Float]
|
|
446
|
+
* @!method playing_offset
|
|
447
|
+
* Returns the current playing offset.
|
|
448
|
+
* @return [Time]
|
|
449
|
+
* @!method playing_offset=(value)
|
|
450
|
+
* Seeks to the given playing offset.
|
|
451
|
+
* @return [Time]
|
|
452
|
+
* @!method effect_processor=(proc)
|
|
453
|
+
* Installs a Proc that post-processes this source's audio in real time.
|
|
454
|
+
* @return [Proc] +proc+
|
|
455
|
+
*/
|
|
456
|
+
void Init_SoundStream(VALUE rb_mSFML) {
|
|
457
|
+
rb_cSoundStream = rb_define_class_under(rb_mSFML, "SoundStream", rb_cObject);
|
|
458
|
+
|
|
459
|
+
rb_define_alloc_func(rb_cSoundStream, SoundStream_alloc);
|
|
460
|
+
rb_define_method(rb_cSoundStream, "initialize", SoundStream_initialize, -1);
|
|
278
461
|
|
|
279
462
|
rb_define_method(rb_cSoundStream, "channel_count", SoundStream_channel_count, 0);
|
|
280
463
|
rb_define_method(rb_cSoundStream, "sample_rate", SoundStream_sample_rate, 0);
|
data/ext/core/exceptions.c
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
#include <string.h>
|
|
4
4
|
|
|
5
|
-
#define MSG_LENGTH
|
|
5
|
+
#define MSG_LENGTH 86
|
|
6
6
|
|
|
7
|
-
void raise_invalid_argument_type(const char
|
|
7
|
+
void raise_invalid_argument_type(const char* type) {
|
|
8
8
|
char msg[MSG_LENGTH];
|
|
9
9
|
|
|
10
10
|
snprintf(msg, MSG_LENGTH, "invalid argument, expected a %s object", type);
|
|
@@ -13,31 +13,33 @@ void raise_invalid_argument_type(const char *type) {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
void raise_invalid_argument_class(VALUE rb_cKlass) {
|
|
16
|
-
|
|
16
|
+
VALUE rb_name = rb_funcall(rb_cKlass, rb_intern("name"), 0);
|
|
17
|
+
|
|
18
|
+
raise_invalid_argument_type(NIL_P(rb_name) ? "anonymous class" : RSTRING_PTR(rb_name));
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
void raise_invalid_arguments_excepted(int expected, size_t given) {
|
|
20
22
|
char msg[MSG_LENGTH];
|
|
21
23
|
|
|
22
24
|
if (expected > 0) {
|
|
23
|
-
snprintf(msg, MSG_LENGTH, "wrong number of arguments (given %
|
|
25
|
+
snprintf(msg, MSG_LENGTH, "wrong number of arguments (given %zu, expected %i)", given,
|
|
26
|
+
expected);
|
|
24
27
|
} else {
|
|
25
|
-
snprintf(msg, MSG_LENGTH, "wrong number of arguments (given %
|
|
28
|
+
snprintf(msg, MSG_LENGTH, "wrong number of arguments (given %zu)", given);
|
|
26
29
|
}
|
|
27
30
|
|
|
28
|
-
|
|
29
31
|
rb_raise(rb_eArgError, "%s", msg);
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
void raise_invalid_array_length(size_t length) {
|
|
33
35
|
char msg[MSG_LENGTH];
|
|
34
36
|
|
|
35
|
-
snprintf(msg, MSG_LENGTH, "invalid array length, expected length of %
|
|
37
|
+
snprintf(msg, MSG_LENGTH, "invalid array length, expected length of %zu", length);
|
|
36
38
|
|
|
37
39
|
rb_raise(rb_eArgError, "%s", msg);
|
|
38
40
|
}
|
|
39
41
|
|
|
40
|
-
void raise_method_no_implemented(const char
|
|
42
|
+
void raise_method_no_implemented(const char* method) {
|
|
41
43
|
if (method != NULL && strlen(method) > 0) {
|
|
42
44
|
rb_raise(rb_eNotImpError, "method not implemented: %s", method);
|
|
43
45
|
} else {
|
data/ext/core/unicode.c
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#include "core/unicode.h"
|
|
2
2
|
|
|
3
|
+
#include <limits.h>
|
|
3
4
|
#include <ruby.h>
|
|
4
5
|
#include <ruby/encoding.h>
|
|
5
6
|
|
|
@@ -8,12 +9,21 @@ VALUE utf32_from_rb(VALUE rb_string) {
|
|
|
8
9
|
VALUE string = rb_str_export_to_enc(rb_string, utf8);
|
|
9
10
|
const char* cursor = RSTRING_PTR(string);
|
|
10
11
|
const char* end = cursor + RSTRING_LEN(string);
|
|
12
|
+
long source_length = RSTRING_LEN(string);
|
|
11
13
|
VALUE buffer;
|
|
12
14
|
sfChar32* out;
|
|
13
15
|
long length = 0;
|
|
14
16
|
|
|
15
|
-
/* One code point per byte is the worst case, plus the terminator.
|
|
16
|
-
|
|
17
|
+
/* One code point per byte is the worst case, plus the terminator. On a
|
|
18
|
+
32-bit long (the 32-bit targets this gem ships), a large enough string
|
|
19
|
+
would overflow (source_length + 1) * sizeof(sfChar32) and allocate a
|
|
20
|
+
buffer far too small for the write loop below -- check the bound
|
|
21
|
+
before multiplying rather than after. */
|
|
22
|
+
if (source_length > (LONG_MAX / (long)sizeof(sfChar32)) - 1) {
|
|
23
|
+
rb_raise(rb_eArgError, "string too long to convert to UTF-32");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
buffer = rb_str_tmp_new((source_length + 1) * (long)sizeof(sfChar32));
|
|
17
27
|
out = (sfChar32*)RSTRING_PTR(buffer);
|
|
18
28
|
|
|
19
29
|
while (cursor < end) {
|
data/ext/ext.c
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
#include "graphics/target.h"
|
|
23
23
|
#include "graphics/render_state.h"
|
|
24
24
|
#include "window/event.h"
|
|
25
|
+
#include "window/window_base.h"
|
|
25
26
|
#include "window/window.h"
|
|
26
27
|
#include "window/keyboard.h"
|
|
27
28
|
#include "window/mouse.h"
|
|
@@ -47,6 +48,7 @@
|
|
|
47
48
|
#include "graphics/font.h"
|
|
48
49
|
#include "graphics/text.h"
|
|
49
50
|
#include "graphics/render_texture.h"
|
|
51
|
+
#include "graphics/render_window.h"
|
|
50
52
|
#include "graphics/shader.h"
|
|
51
53
|
#include "audio/effect_processor.h"
|
|
52
54
|
#include "audio/audio_enums.h"
|
|
@@ -84,6 +86,10 @@
|
|
|
84
86
|
|
|
85
87
|
static VALUE rb_mExt;
|
|
86
88
|
|
|
89
|
+
/* Document-module: SFML
|
|
90
|
+
* Ruby bindings for SFML 3, via its C API, CSFML. Every class and module in
|
|
91
|
+
* this library lives under this namespace.
|
|
92
|
+
*/
|
|
87
93
|
void Init_sfml_ext(void) {
|
|
88
94
|
rb_mExt = rb_define_module("SFML");
|
|
89
95
|
|
|
@@ -123,7 +129,9 @@ void Init_sfml_ext(void) {
|
|
|
123
129
|
Init_Event(rb_mExt);
|
|
124
130
|
Init_VideoMode(rb_mExt);
|
|
125
131
|
Init_View(rb_mExt);
|
|
132
|
+
Init_WindowBase(rb_mExt);
|
|
126
133
|
Init_Window(rb_mExt);
|
|
134
|
+
Init_RenderWindow(rb_mExt);
|
|
127
135
|
Init_Keyboard(rb_mExt);
|
|
128
136
|
Init_Mouse(rb_mExt);
|
|
129
137
|
Init_Joystick(rb_mExt);
|