sfml3-rb 0.0.1 → 0.2.2
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/CHANGELOG.md +342 -0
- data/README.md +51 -14
- data/TODO.md +199 -0
- data/ext/audio/audio_enums.c +131 -0
- data/ext/audio/audio_enums.h +18 -0
- data/ext/audio/effect_processor.c +233 -0
- data/ext/audio/effect_processor.h +25 -0
- data/ext/audio/listener.c +83 -0
- data/ext/audio/listener.h +8 -0
- data/ext/audio/music.c +174 -0
- data/ext/audio/music.h +14 -0
- data/ext/audio/sound.c +139 -0
- data/ext/audio/sound.h +14 -0
- data/ext/audio/sound_buffer.c +274 -0
- data/ext/audio/sound_buffer.h +18 -0
- data/ext/audio/sound_buffer_recorder.c +109 -0
- data/ext/audio/sound_buffer_recorder.h +14 -0
- data/ext/audio/sound_recorder.c +268 -0
- data/ext/audio/sound_recorder.h +14 -0
- data/ext/audio/sound_source.h +13 -0
- data/ext/audio/sound_source.inc +271 -0
- data/ext/audio/sound_source_cone.c +138 -0
- data/ext/audio/sound_source_cone.h +20 -0
- data/ext/audio/sound_stream.c +294 -0
- data/ext/audio/sound_stream.h +14 -0
- data/ext/{exceptions.c → core/exceptions.c} +10 -8
- data/ext/{ext → core}/exceptions.h +3 -3
- data/ext/core/foreign_thread.c +149 -0
- data/ext/core/foreign_thread.h +31 -0
- data/ext/core/macros.h +8 -0
- data/ext/{ext → core}/sfml.h +5 -3
- data/ext/core/unicode.c +46 -0
- data/ext/core/unicode.h +25 -0
- data/ext/ext.c +125 -14
- data/ext/extconf.rb +51 -6
- data/ext/graphics/blend_mode.c +261 -0
- data/ext/graphics/blend_mode.h +18 -0
- data/ext/graphics/circle.c +319 -0
- data/ext/{ext/klass/drawable → graphics}/circle.h +3 -3
- data/ext/graphics/color.c +318 -0
- data/ext/graphics/color.h +37 -0
- data/ext/{drawable.c → graphics/drawable.c} +11 -11
- data/ext/graphics/drawable.h +10 -0
- data/ext/graphics/enums.c +123 -0
- data/ext/graphics/enums.h +20 -0
- data/ext/graphics/font.c +148 -0
- data/ext/graphics/font.h +14 -0
- data/ext/graphics/glyph.c +60 -0
- data/ext/graphics/glyph.h +14 -0
- data/ext/graphics/image.c +205 -0
- data/ext/graphics/image.h +16 -0
- data/ext/graphics/polygon.c +300 -0
- data/ext/graphics/polygon.h +10 -0
- data/ext/graphics/rect.c +287 -0
- data/ext/graphics/rect.h +30 -0
- data/ext/graphics/rectangle.c +302 -0
- data/ext/graphics/rectangle.h +10 -0
- data/ext/graphics/render_state.c +204 -0
- data/ext/graphics/render_state.h +18 -0
- data/ext/graphics/render_target.inc +181 -0
- data/ext/graphics/render_texture.c +182 -0
- data/ext/graphics/render_texture.h +14 -0
- data/ext/graphics/shader.c +540 -0
- data/ext/graphics/shader.h +14 -0
- data/ext/graphics/shape.c +311 -0
- data/ext/graphics/shape.h +10 -0
- data/ext/graphics/sprite.c +249 -0
- data/ext/graphics/sprite.h +10 -0
- data/ext/graphics/stencil_mode.c +211 -0
- data/ext/graphics/stencil_mode.h +18 -0
- data/ext/graphics/target.c +133 -0
- data/ext/graphics/target.h +40 -0
- data/ext/graphics/text.c +344 -0
- data/ext/graphics/text.h +10 -0
- data/ext/graphics/texture.c +379 -0
- data/ext/graphics/texture.h +16 -0
- data/ext/graphics/transform.c +372 -0
- data/ext/graphics/transform.h +35 -0
- data/ext/{transformable.c → graphics/transformable.c} +168 -144
- data/ext/{ext/klass → graphics}/transformable.h +3 -3
- data/ext/graphics/vertex.c +179 -0
- data/ext/graphics/vertex.h +23 -0
- data/ext/graphics/vertex_array.c +127 -0
- data/ext/graphics/vertex_array.h +10 -0
- data/ext/graphics/vertex_buffer.c +211 -0
- data/ext/graphics/vertex_buffer.h +14 -0
- data/ext/{view.c → graphics/view.c} +168 -169
- data/ext/{ext/klass → graphics}/view.h +3 -3
- data/ext/network/ftp.c +405 -0
- data/ext/network/ftp.h +20 -0
- data/ext/network/http.c +243 -0
- data/ext/network/http.h +18 -0
- data/ext/network/ip_address.c +164 -0
- data/ext/network/ip_address.h +20 -0
- data/ext/network/network_enums.c +298 -0
- data/ext/network/network_enums.h +26 -0
- data/ext/network/packet.c +189 -0
- data/ext/network/packet.h +14 -0
- data/ext/network/socket_selector.c +142 -0
- data/ext/network/socket_selector.h +14 -0
- data/ext/network/tcp_listener.c +115 -0
- data/ext/network/tcp_listener.h +14 -0
- data/ext/network/tcp_socket.c +199 -0
- data/ext/network/tcp_socket.h +17 -0
- data/ext/network/udp_socket.c +190 -0
- data/ext/network/udp_socket.h +14 -0
- data/ext/ports.rb +97 -21
- data/ext/system/buffer.c +77 -0
- data/ext/system/buffer.h +14 -0
- data/ext/system/clock.c +100 -0
- data/ext/{ext/klass → system}/clock.h +3 -3
- data/ext/system/input_stream.c +229 -0
- data/ext/system/input_stream.h +23 -0
- data/ext/system/sleep.c +16 -0
- data/ext/system/sleep.h +8 -0
- data/ext/system/time.c +218 -0
- data/ext/system/time.h +18 -0
- data/ext/system/vec2.c +251 -0
- data/ext/system/vec2.h +55 -0
- data/ext/system/vec3.c +219 -0
- data/ext/system/vec3.h +18 -0
- data/ext/window/clipboard.c +89 -0
- data/ext/window/clipboard.h +8 -0
- data/ext/window/context.c +70 -0
- data/ext/window/context.h +8 -0
- data/ext/window/context_settings.c +220 -0
- data/ext/window/context_settings.h +18 -0
- data/ext/window/cursor.c +56 -0
- data/ext/window/cursor.h +14 -0
- data/ext/window/event.c +216 -0
- data/ext/window/event.h +14 -0
- data/ext/{event_name.c → window/event_name.c} +2 -2
- data/ext/window/event_name.h +8 -0
- data/ext/window/input_enums.c +261 -0
- data/ext/window/input_enums.h +36 -0
- data/ext/window/joystick.c +60 -0
- data/ext/window/joystick.h +8 -0
- data/ext/{keyboard.c → window/keyboard.c} +74 -2
- data/ext/window/keyboard.h +12 -0
- data/ext/window/mouse.c +70 -0
- data/ext/window/mouse.h +8 -0
- data/ext/window/sensor.c +30 -0
- data/ext/window/sensor.h +8 -0
- data/ext/window/touch.c +49 -0
- data/ext/window/touch.h +8 -0
- data/ext/window/video_mode.c +133 -0
- data/ext/window/video_mode.h +14 -0
- data/ext/window/vulkan.c +44 -0
- data/ext/window/vulkan.h +8 -0
- data/ext/window/window.c +414 -0
- data/ext/{ext/klass → window}/window.h +3 -3
- data/lib/sfml/version.rb +4 -2
- data/lib/sfml.rb +2 -0
- metadata +163 -56
- data/ext/circle.c +0 -198
- data/ext/clock.c +0 -65
- data/ext/color.c +0 -43
- data/ext/event.c +0 -148
- data/ext/ext/klass/color.h +0 -26
- data/ext/ext/klass/drawable/image.h +0 -4
- data/ext/ext/klass/drawable/polygon.h +0 -4
- data/ext/ext/klass/drawable/rectangle.h +0 -4
- data/ext/ext/klass/drawable/sprite.h +0 -4
- data/ext/ext/klass/drawable/texture.h +0 -4
- data/ext/ext/klass/event/event_name.h +0 -8
- data/ext/ext/klass/event.h +0 -12
- data/ext/ext/klass/keyboard.h +0 -8
- data/ext/ext/klass/render_state.h +0 -16
- data/ext/ext/klass/target.h +0 -18
- data/ext/ext/klass/transform.h +0 -17
- data/ext/ext/klass/video_mode.h +0 -12
- data/ext/ext/module/drawable/drawable.h +0 -10
- data/ext/ext/module/transform.h +0 -18
- data/ext/ext/module.h +0 -10
- data/ext/ext/rect.h +0 -16
- data/ext/ext/style_name.h +0 -11
- data/ext/ext/vec2.h +0 -38
- data/ext/image.c +0 -5
- data/ext/polygon.c +0 -5
- data/ext/rect.c +0 -26
- data/ext/rectangle.c +0 -5
- data/ext/render_state.c +0 -109
- data/ext/sprite.c +0 -5
- data/ext/style_name.c +0 -15
- data/ext/target.c +0 -106
- data/ext/texture.c +0 -5
- data/ext/transform.c +0 -107
- data/ext/vec2.c +0 -42
- data/ext/video_mode.c +0 -78
- data/ext/window.c +0 -274
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#include "audio/listener.h"
|
|
2
|
+
|
|
3
|
+
#include <ruby.h>
|
|
4
|
+
|
|
5
|
+
#include "audio/sound_source_cone.h"
|
|
6
|
+
#include "system/vec3.h"
|
|
7
|
+
|
|
8
|
+
static VALUE Listener_global_volume(VALUE module) {
|
|
9
|
+
return DBL2NUM(sfListener_getGlobalVolume());
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static VALUE Listener_set_global_volume(VALUE module, VALUE rb_value) {
|
|
13
|
+
sfListener_setGlobalVolume((float) NUM2DBL(rb_value));
|
|
14
|
+
return rb_value;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static VALUE Listener_position(VALUE module) {
|
|
18
|
+
return vec3f_to_rb(sfListener_getPosition());
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static VALUE Listener_set_position(VALUE module, VALUE rb_value) {
|
|
22
|
+
sfListener_setPosition(vec3f_from_rb(rb_value));
|
|
23
|
+
return rb_value;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static VALUE Listener_direction(VALUE module) {
|
|
27
|
+
return vec3f_to_rb(sfListener_getDirection());
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static VALUE Listener_set_direction(VALUE module, VALUE rb_value) {
|
|
31
|
+
sfListener_setDirection(vec3f_from_rb(rb_value));
|
|
32
|
+
return rb_value;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static VALUE Listener_velocity(VALUE module) {
|
|
36
|
+
return vec3f_to_rb(sfListener_getVelocity());
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static VALUE Listener_set_velocity(VALUE module, VALUE rb_value) {
|
|
40
|
+
sfListener_setVelocity(vec3f_from_rb(rb_value));
|
|
41
|
+
return rb_value;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static VALUE Listener_up_vector(VALUE module) {
|
|
45
|
+
return vec3f_to_rb(sfListener_getUpVector());
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
static VALUE Listener_set_up_vector(VALUE module, VALUE rb_value) {
|
|
49
|
+
sfListener_setUpVector(vec3f_from_rb(rb_value));
|
|
50
|
+
return rb_value;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static VALUE Listener_cone(VALUE module) {
|
|
54
|
+
sfListenerCone cone = sfListener_getCone();
|
|
55
|
+
|
|
56
|
+
return sound_source_cone_to_rb((sfSoundSourceCone) {cone.innerAngle, cone.outerAngle,
|
|
57
|
+
cone.outerGain});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
static VALUE Listener_set_cone(VALUE module, VALUE rb_value) {
|
|
61
|
+
sfSoundSourceCone cone = sound_source_cone_from_rb(rb_value);
|
|
62
|
+
|
|
63
|
+
sfListener_setCone((sfListenerCone) {cone.innerAngle, cone.outerAngle, cone.outerGain});
|
|
64
|
+
|
|
65
|
+
return rb_value;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
void Init_Listener(VALUE rb_module) {
|
|
69
|
+
VALUE rb_mListener = rb_define_module_under(rb_module, "Listener");
|
|
70
|
+
|
|
71
|
+
rb_define_module_function(rb_mListener, "global_volume", Listener_global_volume, 0);
|
|
72
|
+
rb_define_module_function(rb_mListener, "global_volume=", Listener_set_global_volume, 1);
|
|
73
|
+
rb_define_module_function(rb_mListener, "position", Listener_position, 0);
|
|
74
|
+
rb_define_module_function(rb_mListener, "position=", Listener_set_position, 1);
|
|
75
|
+
rb_define_module_function(rb_mListener, "direction", Listener_direction, 0);
|
|
76
|
+
rb_define_module_function(rb_mListener, "direction=", Listener_set_direction, 1);
|
|
77
|
+
rb_define_module_function(rb_mListener, "velocity", Listener_velocity, 0);
|
|
78
|
+
rb_define_module_function(rb_mListener, "velocity=", Listener_set_velocity, 1);
|
|
79
|
+
rb_define_module_function(rb_mListener, "up_vector", Listener_up_vector, 0);
|
|
80
|
+
rb_define_module_function(rb_mListener, "up_vector=", Listener_set_up_vector, 1);
|
|
81
|
+
rb_define_module_function(rb_mListener, "cone", Listener_cone, 0);
|
|
82
|
+
rb_define_module_function(rb_mListener, "cone=", Listener_set_cone, 1);
|
|
83
|
+
}
|
data/ext/audio/music.c
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
#include "audio/music.h"
|
|
2
|
+
|
|
3
|
+
#include <ruby.h>
|
|
4
|
+
#include <ruby/thread.h>
|
|
5
|
+
#include <stdlib.h>
|
|
6
|
+
|
|
7
|
+
#include "audio/audio_enums.h"
|
|
8
|
+
#include "audio/effect_processor.h"
|
|
9
|
+
#include "audio/sound_source.h"
|
|
10
|
+
#include "core/exceptions.h"
|
|
11
|
+
#include "system/input_stream.h"
|
|
12
|
+
#include "system/time.h"
|
|
13
|
+
|
|
14
|
+
typedef struct {
|
|
15
|
+
SoundSource source;
|
|
16
|
+
/* Music streams from the InputStream lazily, so unlike Font/Image/Shader
|
|
17
|
+
the stream has to outlive the create call. The VALUE is both marked and
|
|
18
|
+
registered as a GC root: the root is what guarantees the InputStream's
|
|
19
|
+
sfInputStream is still alive when sfMusic_destroy runs in dfree, even if
|
|
20
|
+
the Music and the stream become unreachable in the same GC cycle. */
|
|
21
|
+
VALUE rb_stream;
|
|
22
|
+
} Music;
|
|
23
|
+
|
|
24
|
+
static VALUE rb_cMusic;
|
|
25
|
+
|
|
26
|
+
static void Music_mark(void* ptr) {
|
|
27
|
+
Music* music = ptr;
|
|
28
|
+
|
|
29
|
+
rb_gc_mark(music->rb_stream);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* sfMusic_destroy() calls Music::~Music(), which explicitly calls stop() and
|
|
33
|
+
can block waiting on the audio thread; release the GVL for the same reason
|
|
34
|
+
as Sound_free/SS_METHOD(stop). */
|
|
35
|
+
static void* Music_destroy_without_gvl(void* handle) {
|
|
36
|
+
sfMusic_destroy(handle);
|
|
37
|
+
return NULL;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static void Music_free(void* ptr) {
|
|
41
|
+
Music* music = ptr;
|
|
42
|
+
|
|
43
|
+
effect_processor_release(music->source.effect_slot);
|
|
44
|
+
rb_thread_call_without_gvl(Music_destroy_without_gvl, music->source.handle, RUBY_UBF_IO, NULL);
|
|
45
|
+
rb_gc_unregister_address(&music->rb_stream);
|
|
46
|
+
free(music);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static const rb_data_type_t Music_data_type = {
|
|
50
|
+
.wrap_struct_name = "SFML::Music",
|
|
51
|
+
.function = {.dmark = Music_mark, .dfree = Music_free, .dsize = NULL},
|
|
52
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY};
|
|
53
|
+
|
|
54
|
+
static VALUE Music_wrap(VALUE klass, sfMusic* handle, VALUE rb_stream) {
|
|
55
|
+
Music* ptr;
|
|
56
|
+
|
|
57
|
+
if (handle == NULL) {
|
|
58
|
+
rb_raise(rb_eRuntimeError, "failed to create music");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
ptr = malloc(sizeof(Music));
|
|
62
|
+
ptr->source.handle = handle;
|
|
63
|
+
ptr->source.effect_slot = -1;
|
|
64
|
+
ptr->rb_stream = rb_stream;
|
|
65
|
+
|
|
66
|
+
rb_gc_register_address(&ptr->rb_stream);
|
|
67
|
+
|
|
68
|
+
return TypedData_Wrap_Struct(klass, &Music_data_type, ptr);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static VALUE Music_from_file(VALUE klass, VALUE rb_path) {
|
|
72
|
+
return Music_wrap(klass, sfMusic_createFromFile(StringValueCStr(rb_path)), Qnil);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static VALUE Music_from_memory(VALUE klass, VALUE rb_data) {
|
|
76
|
+
StringValue(rb_data);
|
|
77
|
+
|
|
78
|
+
return Music_wrap(
|
|
79
|
+
klass, sfMusic_createFromMemory(RSTRING_PTR(rb_data), (size_t)RSTRING_LEN(rb_data)), Qnil);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
static VALUE Music_from_stream(VALUE klass, VALUE rb_stream) {
|
|
83
|
+
VALUE holder = Qnil;
|
|
84
|
+
sfInputStream* stream = input_stream_from_rb(rb_stream, &holder);
|
|
85
|
+
|
|
86
|
+
return Music_wrap(klass, sfMusic_createFromStream(stream), holder);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
static VALUE Music_duration(VALUE self) {
|
|
90
|
+
return time_to_rb(sfMusic_getDuration(Get_Music_Struct(self)));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
static VALUE Music_channel_count(VALUE self) {
|
|
94
|
+
return UINT2NUM(sfMusic_getChannelCount(Get_Music_Struct(self)));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
static VALUE Music_sample_rate(VALUE self) {
|
|
98
|
+
return UINT2NUM(sfMusic_getSampleRate(Get_Music_Struct(self)));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
static VALUE Music_channel_map(VALUE self) {
|
|
102
|
+
size_t count = 0;
|
|
103
|
+
const sfSoundChannel* map = sfMusic_getChannelMap(Get_Music_Struct(self), &count);
|
|
104
|
+
VALUE rb_array;
|
|
105
|
+
size_t i;
|
|
106
|
+
|
|
107
|
+
if (map == NULL) {
|
|
108
|
+
return rb_ary_new();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
rb_array = rb_ary_new_capa((long)count);
|
|
112
|
+
|
|
113
|
+
for (i = 0; i < count; i++) {
|
|
114
|
+
rb_ary_push(rb_array, ID2SYM(rb_intern(sound_channel_name(map[i]))));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return rb_array;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* Loop points are an offset plus a length, matching sfTimeSpan. Returned as a
|
|
121
|
+
two-element [offset, length] pair of SFML::Time. */
|
|
122
|
+
static VALUE Music_loop_points(VALUE self) {
|
|
123
|
+
sfTimeSpan span = sfMusic_getLoopPoints(Get_Music_Struct(self));
|
|
124
|
+
|
|
125
|
+
return rb_ary_new_from_args(2, time_to_rb(span.offset), time_to_rb(span.length));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
static VALUE Music_set_loop_points(VALUE self, VALUE rb_span) {
|
|
129
|
+
sfTimeSpan span;
|
|
130
|
+
|
|
131
|
+
if (!RB_TYPE_P(rb_span, T_ARRAY) || RARRAY_LEN(rb_span) != 2) {
|
|
132
|
+
rb_raise(rb_eArgError, "loop points must be a two-element [offset, length] array");
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
span.offset = time_from_rb(rb_ary_entry(rb_span, 0));
|
|
136
|
+
span.length = time_from_rb(rb_ary_entry(rb_span, 1));
|
|
137
|
+
|
|
138
|
+
sfMusic_setLoopPoints(Get_Music_Struct(self), span);
|
|
139
|
+
|
|
140
|
+
return rb_span;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
#define SS_FN(name) sfMusic_##name
|
|
144
|
+
#define SS_METHOD(name) Music_##name
|
|
145
|
+
#include "audio/sound_source.inc"
|
|
146
|
+
#undef SS_FN
|
|
147
|
+
#undef SS_METHOD
|
|
148
|
+
|
|
149
|
+
void Init_Music(VALUE rb_module) {
|
|
150
|
+
rb_cMusic = rb_define_class_under(rb_module, "Music", rb_cObject);
|
|
151
|
+
|
|
152
|
+
rb_define_singleton_method(rb_cMusic, "from_file", Music_from_file, 1);
|
|
153
|
+
rb_define_singleton_method(rb_cMusic, "from_memory", Music_from_memory, 1);
|
|
154
|
+
rb_define_singleton_method(rb_cMusic, "from_stream", Music_from_stream, 1);
|
|
155
|
+
|
|
156
|
+
rb_define_method(rb_cMusic, "duration", Music_duration, 0);
|
|
157
|
+
rb_define_method(rb_cMusic, "channel_count", Music_channel_count, 0);
|
|
158
|
+
rb_define_method(rb_cMusic, "sample_rate", Music_sample_rate, 0);
|
|
159
|
+
rb_define_method(rb_cMusic, "channel_map", Music_channel_map, 0);
|
|
160
|
+
rb_define_method(rb_cMusic, "loop_points", Music_loop_points, 0);
|
|
161
|
+
rb_define_method(rb_cMusic, "loop_points=", Music_set_loop_points, 1);
|
|
162
|
+
|
|
163
|
+
Music_define_sound_source_methods(rb_cMusic);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
VALUE Get_Klass_Music(void) {
|
|
167
|
+
return rb_cMusic;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
void* Get_Music_Struct(VALUE self) {
|
|
171
|
+
Music* ptr;
|
|
172
|
+
TypedData_Get_Struct(self, Music, &Music_data_type, ptr);
|
|
173
|
+
return ptr->source.handle;
|
|
174
|
+
}
|
data/ext/audio/music.h
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#ifndef SFML_RB_AUDIO_MUSIC_H
|
|
2
|
+
#define SFML_RB_AUDIO_MUSIC_H
|
|
3
|
+
|
|
4
|
+
#include <ruby.h>
|
|
5
|
+
|
|
6
|
+
#include "core/sfml.h"
|
|
7
|
+
|
|
8
|
+
void Init_Music(VALUE rb_module);
|
|
9
|
+
|
|
10
|
+
VALUE Get_Klass_Music(void);
|
|
11
|
+
|
|
12
|
+
void *Get_Music_Struct(VALUE self);
|
|
13
|
+
|
|
14
|
+
#endif //SFML_RB_AUDIO_MUSIC_H
|
data/ext/audio/sound.c
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
#include "audio/sound.h"
|
|
2
|
+
|
|
3
|
+
#include <ruby.h>
|
|
4
|
+
#include <ruby/thread.h>
|
|
5
|
+
#include <stdlib.h>
|
|
6
|
+
|
|
7
|
+
#include "audio/effect_processor.h"
|
|
8
|
+
#include "audio/sound_buffer.h"
|
|
9
|
+
#include "audio/sound_source.h"
|
|
10
|
+
#include "core/exceptions.h"
|
|
11
|
+
|
|
12
|
+
typedef struct {
|
|
13
|
+
SoundSource source;
|
|
14
|
+
VALUE rb_buffer;
|
|
15
|
+
} Sound;
|
|
16
|
+
|
|
17
|
+
static VALUE rb_cSound;
|
|
18
|
+
|
|
19
|
+
static void Sound_mark(void* ptr) {
|
|
20
|
+
Sound* sound = ptr;
|
|
21
|
+
|
|
22
|
+
rb_gc_mark(sound->rb_buffer);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* sfSound_destroy() calls Sound::stop(), which can block waiting on the audio
|
|
26
|
+
thread (see the matching comment on SS_METHOD(stop) in sound_source.inc);
|
|
27
|
+
release the GVL for the same reason. */
|
|
28
|
+
static void* Sound_destroy_without_gvl(void* handle) {
|
|
29
|
+
sfSound_destroy(handle);
|
|
30
|
+
return NULL;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static void Sound_free(void* ptr) {
|
|
34
|
+
Sound* sound = ptr;
|
|
35
|
+
|
|
36
|
+
effect_processor_release(sound->source.effect_slot);
|
|
37
|
+
rb_thread_call_without_gvl(Sound_destroy_without_gvl, sound->source.handle, RUBY_UBF_IO, NULL);
|
|
38
|
+
free(sound);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static const rb_data_type_t Sound_data_type = {
|
|
42
|
+
.wrap_struct_name = "SFML::Sound",
|
|
43
|
+
.function = {.dmark = Sound_mark, .dfree = Sound_free, .dsize = NULL},
|
|
44
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY};
|
|
45
|
+
|
|
46
|
+
static VALUE Sound_wrap(VALUE klass, sfSound* handle, VALUE rb_buffer) {
|
|
47
|
+
Sound* ptr;
|
|
48
|
+
|
|
49
|
+
if (handle == NULL) {
|
|
50
|
+
rb_raise(rb_eRuntimeError, "failed to create sound");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
ptr = malloc(sizeof(Sound));
|
|
54
|
+
ptr->source.handle = handle;
|
|
55
|
+
ptr->source.effect_slot = -1;
|
|
56
|
+
ptr->rb_buffer = rb_buffer;
|
|
57
|
+
|
|
58
|
+
return TypedData_Wrap_Struct(klass, &Sound_data_type, ptr);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static VALUE Sound_new(VALUE klass, VALUE rb_buffer) {
|
|
62
|
+
if (!rb_obj_is_kind_of(rb_buffer, Get_Klass_SoundBuffer())) {
|
|
63
|
+
raise_invalid_argument_class(Get_Klass_SoundBuffer());
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return Sound_wrap(klass, sfSound_create(Get_SoundBuffer_Struct(rb_buffer)), rb_buffer);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
static VALUE Sound_copy(VALUE self) {
|
|
70
|
+
Sound* sound = (Sound*)Get_Sound_Struct(self);
|
|
71
|
+
|
|
72
|
+
return Sound_wrap(Get_Klass_Sound(), sfSound_copy((const sfSound*)sound->source.handle),
|
|
73
|
+
sound->rb_buffer);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static VALUE Sound_get_buffer(VALUE self) {
|
|
77
|
+
return ((Sound*)Get_Sound_Struct(self))->rb_buffer;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
typedef struct {
|
|
81
|
+
sfSound* handle;
|
|
82
|
+
const sfSoundBuffer* buffer;
|
|
83
|
+
} SoundSetBufferArgs;
|
|
84
|
+
|
|
85
|
+
/* sfSound_setBuffer() calls Sound::stop() when a buffer is already attached,
|
|
86
|
+
which can block waiting on the audio thread; release the GVL for the same
|
|
87
|
+
reason as Sound_free/SS_METHOD(stop). */
|
|
88
|
+
static void* Sound_set_buffer_without_gvl(void* raw) {
|
|
89
|
+
SoundSetBufferArgs* args = raw;
|
|
90
|
+
|
|
91
|
+
sfSound_setBuffer(args->handle, args->buffer);
|
|
92
|
+
|
|
93
|
+
return NULL;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
static VALUE Sound_set_buffer(VALUE self, VALUE rb_buffer) {
|
|
97
|
+
Sound* sound = (Sound*)Get_Sound_Struct(self);
|
|
98
|
+
SoundSetBufferArgs args;
|
|
99
|
+
|
|
100
|
+
if (!rb_obj_is_kind_of(rb_buffer, Get_Klass_SoundBuffer())) {
|
|
101
|
+
raise_invalid_argument_class(Get_Klass_SoundBuffer());
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
args.handle = sound->source.handle;
|
|
105
|
+
args.buffer = Get_SoundBuffer_Struct(rb_buffer);
|
|
106
|
+
|
|
107
|
+
rb_thread_call_without_gvl(Sound_set_buffer_without_gvl, &args, RUBY_UBF_IO, NULL);
|
|
108
|
+
sound->rb_buffer = rb_buffer;
|
|
109
|
+
|
|
110
|
+
return rb_buffer;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
#define SS_FN(name) sfSound_##name
|
|
114
|
+
#define SS_METHOD(name) Sound_##name
|
|
115
|
+
#include "audio/sound_source.inc"
|
|
116
|
+
#undef SS_FN
|
|
117
|
+
#undef SS_METHOD
|
|
118
|
+
|
|
119
|
+
void Init_Sound(VALUE rb_module) {
|
|
120
|
+
rb_cSound = rb_define_class_under(rb_module, "Sound", rb_cObject);
|
|
121
|
+
|
|
122
|
+
rb_define_singleton_method(rb_cSound, "new", Sound_new, 1);
|
|
123
|
+
|
|
124
|
+
rb_define_method(rb_cSound, "copy", Sound_copy, 0);
|
|
125
|
+
rb_define_method(rb_cSound, "buffer", Sound_get_buffer, 0);
|
|
126
|
+
rb_define_method(rb_cSound, "buffer=", Sound_set_buffer, 1);
|
|
127
|
+
|
|
128
|
+
Sound_define_sound_source_methods(rb_cSound);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
VALUE Get_Klass_Sound(void) {
|
|
132
|
+
return rb_cSound;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
void* Get_Sound_Struct(VALUE self) {
|
|
136
|
+
Sound* ptr;
|
|
137
|
+
TypedData_Get_Struct(self, Sound, &Sound_data_type, ptr);
|
|
138
|
+
return ptr;
|
|
139
|
+
}
|
data/ext/audio/sound.h
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#ifndef SFML_RB_AUDIO_SOUND_H
|
|
2
|
+
#define SFML_RB_AUDIO_SOUND_H
|
|
3
|
+
|
|
4
|
+
#include <ruby.h>
|
|
5
|
+
|
|
6
|
+
#include "core/sfml.h"
|
|
7
|
+
|
|
8
|
+
void Init_Sound(VALUE rb_module);
|
|
9
|
+
|
|
10
|
+
VALUE Get_Klass_Sound(void);
|
|
11
|
+
|
|
12
|
+
void *Get_Sound_Struct(VALUE self);
|
|
13
|
+
|
|
14
|
+
#endif //SFML_RB_AUDIO_SOUND_H
|