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.
Files changed (191) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +342 -0
  3. data/README.md +51 -14
  4. data/TODO.md +199 -0
  5. data/ext/audio/audio_enums.c +131 -0
  6. data/ext/audio/audio_enums.h +18 -0
  7. data/ext/audio/effect_processor.c +233 -0
  8. data/ext/audio/effect_processor.h +25 -0
  9. data/ext/audio/listener.c +83 -0
  10. data/ext/audio/listener.h +8 -0
  11. data/ext/audio/music.c +174 -0
  12. data/ext/audio/music.h +14 -0
  13. data/ext/audio/sound.c +139 -0
  14. data/ext/audio/sound.h +14 -0
  15. data/ext/audio/sound_buffer.c +274 -0
  16. data/ext/audio/sound_buffer.h +18 -0
  17. data/ext/audio/sound_buffer_recorder.c +109 -0
  18. data/ext/audio/sound_buffer_recorder.h +14 -0
  19. data/ext/audio/sound_recorder.c +268 -0
  20. data/ext/audio/sound_recorder.h +14 -0
  21. data/ext/audio/sound_source.h +13 -0
  22. data/ext/audio/sound_source.inc +271 -0
  23. data/ext/audio/sound_source_cone.c +138 -0
  24. data/ext/audio/sound_source_cone.h +20 -0
  25. data/ext/audio/sound_stream.c +294 -0
  26. data/ext/audio/sound_stream.h +14 -0
  27. data/ext/{exceptions.c → core/exceptions.c} +10 -8
  28. data/ext/{ext → core}/exceptions.h +3 -3
  29. data/ext/core/foreign_thread.c +149 -0
  30. data/ext/core/foreign_thread.h +31 -0
  31. data/ext/core/macros.h +8 -0
  32. data/ext/{ext → core}/sfml.h +5 -3
  33. data/ext/core/unicode.c +46 -0
  34. data/ext/core/unicode.h +25 -0
  35. data/ext/ext.c +125 -14
  36. data/ext/extconf.rb +51 -6
  37. data/ext/graphics/blend_mode.c +261 -0
  38. data/ext/graphics/blend_mode.h +18 -0
  39. data/ext/graphics/circle.c +319 -0
  40. data/ext/{ext/klass/drawable → graphics}/circle.h +3 -3
  41. data/ext/graphics/color.c +318 -0
  42. data/ext/graphics/color.h +37 -0
  43. data/ext/{drawable.c → graphics/drawable.c} +11 -11
  44. data/ext/graphics/drawable.h +10 -0
  45. data/ext/graphics/enums.c +123 -0
  46. data/ext/graphics/enums.h +20 -0
  47. data/ext/graphics/font.c +148 -0
  48. data/ext/graphics/font.h +14 -0
  49. data/ext/graphics/glyph.c +60 -0
  50. data/ext/graphics/glyph.h +14 -0
  51. data/ext/graphics/image.c +205 -0
  52. data/ext/graphics/image.h +16 -0
  53. data/ext/graphics/polygon.c +300 -0
  54. data/ext/graphics/polygon.h +10 -0
  55. data/ext/graphics/rect.c +287 -0
  56. data/ext/graphics/rect.h +30 -0
  57. data/ext/graphics/rectangle.c +302 -0
  58. data/ext/graphics/rectangle.h +10 -0
  59. data/ext/graphics/render_state.c +204 -0
  60. data/ext/graphics/render_state.h +18 -0
  61. data/ext/graphics/render_target.inc +181 -0
  62. data/ext/graphics/render_texture.c +182 -0
  63. data/ext/graphics/render_texture.h +14 -0
  64. data/ext/graphics/shader.c +540 -0
  65. data/ext/graphics/shader.h +14 -0
  66. data/ext/graphics/shape.c +311 -0
  67. data/ext/graphics/shape.h +10 -0
  68. data/ext/graphics/sprite.c +249 -0
  69. data/ext/graphics/sprite.h +10 -0
  70. data/ext/graphics/stencil_mode.c +211 -0
  71. data/ext/graphics/stencil_mode.h +18 -0
  72. data/ext/graphics/target.c +133 -0
  73. data/ext/graphics/target.h +40 -0
  74. data/ext/graphics/text.c +344 -0
  75. data/ext/graphics/text.h +10 -0
  76. data/ext/graphics/texture.c +379 -0
  77. data/ext/graphics/texture.h +16 -0
  78. data/ext/graphics/transform.c +372 -0
  79. data/ext/graphics/transform.h +35 -0
  80. data/ext/{transformable.c → graphics/transformable.c} +168 -144
  81. data/ext/{ext/klass → graphics}/transformable.h +3 -3
  82. data/ext/graphics/vertex.c +179 -0
  83. data/ext/graphics/vertex.h +23 -0
  84. data/ext/graphics/vertex_array.c +127 -0
  85. data/ext/graphics/vertex_array.h +10 -0
  86. data/ext/graphics/vertex_buffer.c +211 -0
  87. data/ext/graphics/vertex_buffer.h +14 -0
  88. data/ext/{view.c → graphics/view.c} +168 -169
  89. data/ext/{ext/klass → graphics}/view.h +3 -3
  90. data/ext/network/ftp.c +405 -0
  91. data/ext/network/ftp.h +20 -0
  92. data/ext/network/http.c +243 -0
  93. data/ext/network/http.h +18 -0
  94. data/ext/network/ip_address.c +164 -0
  95. data/ext/network/ip_address.h +20 -0
  96. data/ext/network/network_enums.c +298 -0
  97. data/ext/network/network_enums.h +26 -0
  98. data/ext/network/packet.c +189 -0
  99. data/ext/network/packet.h +14 -0
  100. data/ext/network/socket_selector.c +142 -0
  101. data/ext/network/socket_selector.h +14 -0
  102. data/ext/network/tcp_listener.c +115 -0
  103. data/ext/network/tcp_listener.h +14 -0
  104. data/ext/network/tcp_socket.c +199 -0
  105. data/ext/network/tcp_socket.h +17 -0
  106. data/ext/network/udp_socket.c +190 -0
  107. data/ext/network/udp_socket.h +14 -0
  108. data/ext/ports.rb +97 -21
  109. data/ext/system/buffer.c +77 -0
  110. data/ext/system/buffer.h +14 -0
  111. data/ext/system/clock.c +100 -0
  112. data/ext/{ext/klass → system}/clock.h +3 -3
  113. data/ext/system/input_stream.c +229 -0
  114. data/ext/system/input_stream.h +23 -0
  115. data/ext/system/sleep.c +16 -0
  116. data/ext/system/sleep.h +8 -0
  117. data/ext/system/time.c +218 -0
  118. data/ext/system/time.h +18 -0
  119. data/ext/system/vec2.c +251 -0
  120. data/ext/system/vec2.h +55 -0
  121. data/ext/system/vec3.c +219 -0
  122. data/ext/system/vec3.h +18 -0
  123. data/ext/window/clipboard.c +89 -0
  124. data/ext/window/clipboard.h +8 -0
  125. data/ext/window/context.c +70 -0
  126. data/ext/window/context.h +8 -0
  127. data/ext/window/context_settings.c +220 -0
  128. data/ext/window/context_settings.h +18 -0
  129. data/ext/window/cursor.c +56 -0
  130. data/ext/window/cursor.h +14 -0
  131. data/ext/window/event.c +216 -0
  132. data/ext/window/event.h +14 -0
  133. data/ext/{event_name.c → window/event_name.c} +2 -2
  134. data/ext/window/event_name.h +8 -0
  135. data/ext/window/input_enums.c +261 -0
  136. data/ext/window/input_enums.h +36 -0
  137. data/ext/window/joystick.c +60 -0
  138. data/ext/window/joystick.h +8 -0
  139. data/ext/{keyboard.c → window/keyboard.c} +74 -2
  140. data/ext/window/keyboard.h +12 -0
  141. data/ext/window/mouse.c +70 -0
  142. data/ext/window/mouse.h +8 -0
  143. data/ext/window/sensor.c +30 -0
  144. data/ext/window/sensor.h +8 -0
  145. data/ext/window/touch.c +49 -0
  146. data/ext/window/touch.h +8 -0
  147. data/ext/window/video_mode.c +133 -0
  148. data/ext/window/video_mode.h +14 -0
  149. data/ext/window/vulkan.c +44 -0
  150. data/ext/window/vulkan.h +8 -0
  151. data/ext/window/window.c +414 -0
  152. data/ext/{ext/klass → window}/window.h +3 -3
  153. data/lib/sfml/version.rb +4 -2
  154. data/lib/sfml.rb +2 -0
  155. metadata +163 -56
  156. data/ext/circle.c +0 -198
  157. data/ext/clock.c +0 -65
  158. data/ext/color.c +0 -43
  159. data/ext/event.c +0 -148
  160. data/ext/ext/klass/color.h +0 -26
  161. data/ext/ext/klass/drawable/image.h +0 -4
  162. data/ext/ext/klass/drawable/polygon.h +0 -4
  163. data/ext/ext/klass/drawable/rectangle.h +0 -4
  164. data/ext/ext/klass/drawable/sprite.h +0 -4
  165. data/ext/ext/klass/drawable/texture.h +0 -4
  166. data/ext/ext/klass/event/event_name.h +0 -8
  167. data/ext/ext/klass/event.h +0 -12
  168. data/ext/ext/klass/keyboard.h +0 -8
  169. data/ext/ext/klass/render_state.h +0 -16
  170. data/ext/ext/klass/target.h +0 -18
  171. data/ext/ext/klass/transform.h +0 -17
  172. data/ext/ext/klass/video_mode.h +0 -12
  173. data/ext/ext/module/drawable/drawable.h +0 -10
  174. data/ext/ext/module/transform.h +0 -18
  175. data/ext/ext/module.h +0 -10
  176. data/ext/ext/rect.h +0 -16
  177. data/ext/ext/style_name.h +0 -11
  178. data/ext/ext/vec2.h +0 -38
  179. data/ext/image.c +0 -5
  180. data/ext/polygon.c +0 -5
  181. data/ext/rect.c +0 -26
  182. data/ext/rectangle.c +0 -5
  183. data/ext/render_state.c +0 -109
  184. data/ext/sprite.c +0 -5
  185. data/ext/style_name.c +0 -15
  186. data/ext/target.c +0 -106
  187. data/ext/texture.c +0 -5
  188. data/ext/transform.c +0 -107
  189. data/ext/vec2.c +0 -42
  190. data/ext/video_mode.c +0 -78
  191. data/ext/window.c +0 -274
@@ -0,0 +1,17 @@
1
+ #ifndef SFML_RB_NETWORK_TCP_SOCKET_H
2
+ #define SFML_RB_NETWORK_TCP_SOCKET_H
3
+
4
+ #include <ruby.h>
5
+
6
+ #include "core/sfml.h"
7
+
8
+ void Init_TcpSocket(VALUE rb_module);
9
+
10
+ VALUE Get_Klass_TcpSocket(void);
11
+
12
+ void *Get_TcpSocket_Struct(VALUE self);
13
+
14
+ /* Wraps a socket returned by sfTcpListener_accept, taking ownership. */
15
+ VALUE tcp_socket_from_handle(sfTcpSocket *socket);
16
+
17
+ #endif //SFML_RB_NETWORK_TCP_SOCKET_H
@@ -0,0 +1,190 @@
1
+ #include "network/udp_socket.h"
2
+
3
+ #include <ruby.h>
4
+ #include <stdlib.h>
5
+
6
+ #include "core/macros.h"
7
+ #include "network/ip_address.h"
8
+ #include "network/network_enums.h"
9
+ #include "network/packet.h"
10
+
11
+ typedef struct {
12
+ sfUdpSocket *handle;
13
+ } UdpSocket;
14
+
15
+ static VALUE rb_cUdpSocket;
16
+
17
+ static void UdpSocket_free(void *ptr) {
18
+ UdpSocket *socket = ptr;
19
+
20
+ if (socket->handle != NULL) {
21
+ sfUdpSocket_destroy(socket->handle);
22
+ }
23
+
24
+ free(socket);
25
+ }
26
+
27
+ static const rb_data_type_t UdpSocket_data_type = {
28
+ .wrap_struct_name = "SFML::UdpSocket",
29
+ .function = {.dmark = NULL, .dfree = UdpSocket_free, .dsize = NULL},
30
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
31
+ };
32
+
33
+ static VALUE UdpSocket_wrap(VALUE klass, sfUdpSocket *handle) {
34
+ UdpSocket *ptr;
35
+
36
+ if (handle == NULL) {
37
+ rb_raise(rb_eRuntimeError, "failed to create UDP socket");
38
+ }
39
+
40
+ ptr = malloc(sizeof(UdpSocket));
41
+ ptr->handle = handle;
42
+
43
+ return TypedData_Wrap_Struct(klass, &UdpSocket_data_type, ptr);
44
+ }
45
+
46
+ static VALUE UdpSocket_new(VALUE klass) {
47
+ return UdpSocket_wrap(klass, sfUdpSocket_create());
48
+ }
49
+
50
+ static VALUE UdpSocket_any_port(VALUE klass) {
51
+ return UINT2NUM(sfUdpSocket_anyPort());
52
+ }
53
+
54
+ static VALUE UdpSocket_max_datagram_size(VALUE klass) {
55
+ return UINT2NUM(sfUdpSocket_maxDatagramSize());
56
+ }
57
+
58
+ static VALUE UdpSocket_blocking(VALUE self) {
59
+ return BOOL2RB(sfUdpSocket_isBlocking(Get_UdpSocket_Struct(self)));
60
+ }
61
+
62
+ static VALUE UdpSocket_set_blocking(VALUE self, VALUE rb_value) {
63
+ sfUdpSocket_setBlocking(Get_UdpSocket_Struct(self), RTEST(rb_value));
64
+ return rb_value;
65
+ }
66
+
67
+ static VALUE UdpSocket_local_port(VALUE self) {
68
+ return UINT2NUM(sfUdpSocket_getLocalPort(Get_UdpSocket_Struct(self)));
69
+ }
70
+
71
+ static VALUE UdpSocket_bind(int argc, VALUE *argv, VALUE self) {
72
+ VALUE rb_port, rb_address;
73
+
74
+ rb_scan_args(argc, argv, "11", &rb_port, &rb_address);
75
+
76
+ return ID2SYM(rb_intern(socket_status_name(sfUdpSocket_bind(
77
+ Get_UdpSocket_Struct(self), (unsigned short) NUM2INT(rb_port),
78
+ ip_address_from_rb(rb_address, sfIpAddress_Any)))));
79
+ }
80
+
81
+ static VALUE UdpSocket_unbind(VALUE self) {
82
+ sfUdpSocket_unbind(Get_UdpSocket_Struct(self));
83
+ return self;
84
+ }
85
+
86
+ static VALUE UdpSocket_send(VALUE self, VALUE rb_data, VALUE rb_address, VALUE rb_port) {
87
+ StringValue(rb_data);
88
+
89
+ return ID2SYM(rb_intern(socket_status_name(sfUdpSocket_send(
90
+ Get_UdpSocket_Struct(self), RSTRING_PTR(rb_data), (size_t) RSTRING_LEN(rb_data),
91
+ ip_address_from_rb(rb_address, sfIpAddress_None), (unsigned short) NUM2INT(rb_port)))));
92
+ }
93
+
94
+ /* Returns [data, IpAddress, port, status]; the address and port are those of
95
+ the sender. */
96
+ static VALUE UdpSocket_receive(int argc, VALUE *argv, VALUE self) {
97
+ VALUE rb_max_length;
98
+ long max_length = 1024;
99
+ char *buffer;
100
+ size_t received = 0;
101
+ sfIpAddress remote_address = sfIpAddress_None;
102
+ unsigned short remote_port = 0;
103
+ sfSocketStatus status;
104
+ VALUE rb_result;
105
+
106
+ rb_scan_args(argc, argv, "01", &rb_max_length);
107
+
108
+ if (!NIL_P(rb_max_length)) {
109
+ max_length = NUM2LONG(rb_max_length);
110
+ }
111
+
112
+ if (max_length <= 0) {
113
+ rb_raise(rb_eArgError, "maximum length must be positive");
114
+ }
115
+
116
+ buffer = malloc((size_t) max_length);
117
+
118
+ status = sfUdpSocket_receive(Get_UdpSocket_Struct(self), buffer, (size_t) max_length, &received,
119
+ &remote_address, &remote_port);
120
+
121
+ rb_result = rb_ary_new_capa(4);
122
+ rb_ary_push(rb_result, rb_str_new(buffer, (long) received));
123
+ rb_ary_push(rb_result, ip_address_to_rb(remote_address));
124
+ rb_ary_push(rb_result, UINT2NUM(remote_port));
125
+ rb_ary_push(rb_result, ID2SYM(rb_intern(socket_status_name(status))));
126
+
127
+ free(buffer);
128
+
129
+ return rb_result;
130
+ }
131
+
132
+ static VALUE UdpSocket_send_packet(VALUE self, VALUE rb_packet, VALUE rb_address, VALUE rb_port) {
133
+ if (!rb_obj_is_kind_of(rb_packet, Get_Klass_Packet())) {
134
+ rb_raise(rb_eTypeError, "expected an SFML::Packet");
135
+ }
136
+
137
+ return ID2SYM(rb_intern(socket_status_name(sfUdpSocket_sendPacket(
138
+ Get_UdpSocket_Struct(self), Get_Packet_Struct(rb_packet),
139
+ ip_address_from_rb(rb_address, sfIpAddress_None), (unsigned short) NUM2INT(rb_port)))));
140
+ }
141
+
142
+ /* Returns [IpAddress, port, status]. */
143
+ static VALUE UdpSocket_receive_packet(VALUE self, VALUE rb_packet) {
144
+ sfIpAddress remote_address = sfIpAddress_None;
145
+ unsigned short remote_port = 0;
146
+ sfSocketStatus status;
147
+ VALUE rb_result;
148
+
149
+ if (!rb_obj_is_kind_of(rb_packet, Get_Klass_Packet())) {
150
+ rb_raise(rb_eTypeError, "expected an SFML::Packet");
151
+ }
152
+
153
+ status = sfUdpSocket_receivePacket(Get_UdpSocket_Struct(self), Get_Packet_Struct(rb_packet),
154
+ &remote_address, &remote_port);
155
+
156
+ rb_result = rb_ary_new_capa(3);
157
+ rb_ary_push(rb_result, ip_address_to_rb(remote_address));
158
+ rb_ary_push(rb_result, UINT2NUM(remote_port));
159
+ rb_ary_push(rb_result, ID2SYM(rb_intern(socket_status_name(status))));
160
+
161
+ return rb_result;
162
+ }
163
+
164
+ void Init_UdpSocket(VALUE rb_module) {
165
+ rb_cUdpSocket = rb_define_class_under(rb_module, "UdpSocket", rb_cObject);
166
+
167
+ rb_define_singleton_method(rb_cUdpSocket, "new", UdpSocket_new, 0);
168
+ rb_define_singleton_method(rb_cUdpSocket, "any_port", UdpSocket_any_port, 0);
169
+ rb_define_singleton_method(rb_cUdpSocket, "max_datagram_size", UdpSocket_max_datagram_size, 0);
170
+
171
+ rb_define_method(rb_cUdpSocket, "blocking?", UdpSocket_blocking, 0);
172
+ rb_define_method(rb_cUdpSocket, "blocking=", UdpSocket_set_blocking, 1);
173
+ rb_define_method(rb_cUdpSocket, "local_port", UdpSocket_local_port, 0);
174
+ rb_define_method(rb_cUdpSocket, "bind", UdpSocket_bind, -1);
175
+ rb_define_method(rb_cUdpSocket, "unbind", UdpSocket_unbind, 0);
176
+ rb_define_method(rb_cUdpSocket, "send", UdpSocket_send, 3);
177
+ rb_define_method(rb_cUdpSocket, "receive", UdpSocket_receive, -1);
178
+ rb_define_method(rb_cUdpSocket, "send_packet", UdpSocket_send_packet, 3);
179
+ rb_define_method(rb_cUdpSocket, "receive_packet", UdpSocket_receive_packet, 1);
180
+ }
181
+
182
+ VALUE Get_Klass_UdpSocket(void) {
183
+ return rb_cUdpSocket;
184
+ }
185
+
186
+ void *Get_UdpSocket_Struct(VALUE self) {
187
+ UdpSocket *ptr;
188
+ TypedData_Get_Struct(self, UdpSocket, &UdpSocket_data_type, ptr);
189
+ return ptr->handle;
190
+ }
@@ -0,0 +1,14 @@
1
+ #ifndef SFML_RB_NETWORK_UDP_SOCKET_H
2
+ #define SFML_RB_NETWORK_UDP_SOCKET_H
3
+
4
+ #include <ruby.h>
5
+
6
+ #include "core/sfml.h"
7
+
8
+ void Init_UdpSocket(VALUE rb_module);
9
+
10
+ VALUE Get_Klass_UdpSocket(void);
11
+
12
+ void *Get_UdpSocket_Struct(VALUE self);
13
+
14
+ #endif //SFML_RB_NETWORK_UDP_SOCKET_H
data/ext/ports.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'digest'
2
4
  require 'etc'
3
5
  require 'fileutils'
@@ -23,11 +25,19 @@ module Ports
23
25
  # Cross targets, keyed by the RubyGems platform name that rake-compiler and
24
26
  # rake-compiler-dock use for them. `triple` is the GNU host triple whose
25
27
  # toolchain the matching rake-compiler-dock image installs as <triple>-gcc.
28
+ #
29
+ # `multiarch` is the Debian multiarch directory name, which is only sometimes
30
+ # the same string as the triple: i686 compiles with i686-linux-gnu-gcc but its
31
+ # libraries live in /usr/lib/i386-linux-gnu. Only set it where they differ.
26
32
  TARGETS = {
27
33
  'x86_64-linux-gnu' => { triple: 'x86_64-linux-gnu', os: :linux, cpu: 'x86_64' },
34
+ 'x86-linux-gnu' => { triple: 'i686-linux-gnu', multiarch: 'i386-linux-gnu',
35
+ os: :linux, cpu: 'i686' },
28
36
  'aarch64-linux-gnu' => { triple: 'aarch64-linux-gnu', os: :linux, cpu: 'aarch64' },
29
37
  'x86_64-linux-musl' => { triple: 'x86_64-unknown-linux-musl', os: :linux, cpu: 'x86_64' },
38
+ 'x86-linux-musl' => { triple: 'i686-unknown-linux-musl', os: :linux, cpu: 'i686' },
30
39
  'x64-mingw-ucrt' => { triple: 'x86_64-w64-mingw32', os: :windows, cpu: 'x86_64' },
40
+ 'x86-mingw32' => { triple: 'i686-w64-mingw32', os: :windows, cpu: 'i686' },
31
41
  'x86_64-darwin' => { triple: 'x86_64-apple-darwin', os: :darwin, cpu: 'x86_64' },
32
42
  'arm64-darwin' => { triple: 'aarch64-apple-darwin', os: :darwin, cpu: 'arm64' }
33
43
  }.freeze
@@ -41,32 +51,88 @@ module Ports
41
51
  windows: %w[gcc g++]
42
52
  }.freeze
43
53
 
44
- # What the extension links on top of the static SFML/CSFML/FreeType archives.
45
- # SFML resolves GL entry points through its own loader, so on Linux libGL is
46
- # only needed for the handful of symbols SFML references directly.
54
+ # What the extension links on top of the static SFML/CSFML/FreeType/codec
55
+ # archives. SFML resolves GL entry points through its own loader, so on Linux
56
+ # libGL is only needed for the handful of symbols SFML references directly.
57
+ # Network links ws2_32 on Windows; audio needs no OpenAL, because SFML 3 uses
58
+ # the vendored miniaudio backend and resolves ALSA/Pulse at run time via dl.
47
59
  SYSTEM_LIBS = {
48
60
  linux: %w[GL X11 Xrandr Xcursor Xi udev pthread dl rt m],
49
- windows: %w[opengl32 winmm gdi32 user32 advapi32 ole32],
61
+ windows: %w[opengl32 winmm gdi32 user32 advapi32 ole32 ws2_32],
50
62
  darwin: %w[]
51
63
  }.freeze
52
64
 
53
65
  # Clang wants -framework, not -l, and SFML's macOS backend is Objective-C++.
54
- FRAMEWORKS = { darwin: %w[Cocoa OpenGL IOKit Carbon], linux: [], windows: [] }.freeze
66
+ # Audio reaches CoreAudio/CoreFoundation from miniaudio, and the network
67
+ # stack needs nothing beyond the system libc.
68
+ FRAMEWORKS = {
69
+ darwin: %w[Cocoa OpenGL IOKit Carbon CoreFoundation CoreAudio AudioToolbox],
70
+ linux: [], windows: []
71
+ }.freeze
55
72
 
56
- # Order matters. CSFML does find_package(SFML 3 ... REQUIRED) and does not
57
- # fetch SFML itself, and SFML does find_package(Freetype REQUIRED) once
58
- # SFML_USE_SYSTEM_DEPS is on -- so each has to be installed into PREFIX
59
- # before the next configures.
73
+ # Order matters. The Ogg/Vorbis/FLAC codecs and FreeType must be installed
74
+ # before SFML configures, because SFML's find_package(Vorbis)/find_package(FLAC)
75
+ # run with SFML_USE_SYSTEM_DEPS=ON and must find our static archives rather
76
+ # than the build host's shared ones. CSFML then does find_package(SFML 3 ...)
77
+ # and does not fetch SFML itself.
60
78
  #
61
79
  # FreeType is built here rather than left to SFML because SFML's own
62
80
  # FetchContent path clones it from git (no checksum, needs git at configure
63
81
  # time) and then does not install the resulting archive -- which leaves
64
82
  # libsfml-graphics-s.a with an undefined FT_Init_FreeType that only stays
65
- # latent while nothing binds sf::Font. Pinning it as a port fixes both.
66
- #
67
- # Audio and network are off because the binding wraps neither, which also
68
- # drops the FLAC/Ogg/Vorbis and mbedtls dependency families.
83
+ # latent while nothing binds sf::Font. Pinning it as a port fixes both. The
84
+ # same reasoning applies to the codecs: vendoring them keeps the binary gems
85
+ # free of libvorbis/libFLAC/libogg runtime dependencies and makes the audio
86
+ # module buildable on the mingw/darwin/musl images, which ship no codec
87
+ # development files at all.
69
88
  RECIPES = [
89
+ {
90
+ name: 'libogg',
91
+ version: '1.3.5',
92
+ sha256: '0eb4b4b9420a0f51db142ba3f9c64b333f826532dc0f48c6410ae51f4799b664',
93
+ url: 'https://downloads.xiph.org/releases/ogg/libogg-%<version>s.tar.gz',
94
+ flags: %w[
95
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5
96
+ -DBUILD_SHARED_LIBS=OFF
97
+ -DBUILD_TESTING=OFF
98
+ -DINSTALL_DOCS=OFF
99
+ -DINSTALL_CMAKE_PACKAGE_MODULE=ON
100
+ -DINSTALL_PKG_CONFIG_MODULE=OFF
101
+ ]
102
+ },
103
+ {
104
+ name: 'libvorbis',
105
+ version: '1.3.7',
106
+ sha256: '0e982409a9c3fc82ee06e08205b1355e5c6aa4c36bca58146ef399621b0ce5ab',
107
+ url: 'https://downloads.xiph.org/releases/vorbis/libvorbis-%<version>s.tar.gz',
108
+ flags: %w[
109
+ -DCMAKE_POLICY_VERSION_MINIMUM=3.5
110
+ -DBUILD_SHARED_LIBS=OFF
111
+ -DBUILD_TESTING=OFF
112
+ -DINSTALL_CMAKE_PACKAGE_MODULE=ON
113
+ ]
114
+ },
115
+ {
116
+ name: 'flac',
117
+ version: '1.4.3',
118
+ sha256: '6c58e69cd22348f441b861092b825e591d0b822e106de6eb0ee4d05d27205b70',
119
+ url: 'https://downloads.xiph.org/releases/flac/flac-%<version>s.tar.xz',
120
+ ext: 'tar.xz',
121
+ flags: %w[
122
+ -DBUILD_SHARED_LIBS=OFF
123
+ -DBUILD_CXXLIBS=OFF
124
+ -DBUILD_PROGRAMS=OFF
125
+ -DBUILD_EXAMPLES=OFF
126
+ -DBUILD_TESTING=OFF
127
+ -DBUILD_DOCS=OFF
128
+ -DWITH_OGG=OFF
129
+ -DWITH_FORTIFY_SOURCE=OFF
130
+ -DWITH_STACK_PROTECTOR=OFF
131
+ -DINSTALL_MANPAGES=OFF
132
+ -DINSTALL_CMAKE_CONFIG_MODULE=ON
133
+ -DINSTALL_PKGCONFIG_MODULES=ON
134
+ ]
135
+ },
70
136
  {
71
137
  name: 'freetype',
72
138
  version: '2.13.2',
@@ -89,8 +155,6 @@ module Ports
89
155
  sha256: '0034e05f95509e5d3fb81b1625713e06da7b068f210288ce3fd67106f8f46995',
90
156
  flags: %w[
91
157
  -DSFML_USE_SYSTEM_DEPS=ON
92
- -DSFML_BUILD_AUDIO=OFF
93
- -DSFML_BUILD_NETWORK=OFF
94
158
  -DSFML_BUILD_EXAMPLES=OFF
95
159
  -DSFML_BUILD_DOC=OFF
96
160
  -DSFML_BUILD_TEST_SUITE=OFF
@@ -101,15 +165,13 @@ module Ports
101
165
  version: '3.0.0',
102
166
  sha256: '903cd4a782fb0b233f732dc5b37861b552998e93ae8f268c40bd4ce50b2e88ca',
103
167
  flags: %w[
104
- -DCSFML_BUILD_AUDIO=OFF
105
- -DCSFML_BUILD_NETWORK=OFF
106
168
  -DCSFML_BUILD_EXAMPLES=OFF
107
169
  -DCSFML_LINK_SFML_STATICALLY=ON
108
170
  ]
109
171
  }
110
172
  ].freeze
111
173
 
112
- TOOLCHAIN_HINT = <<~HINT.freeze
174
+ TOOLCHAIN_HINT = <<~HINT
113
175
  Building SFML from source needs CMake >= 3.22, a C++17 compiler, and the
114
176
  X11/udev/OpenGL development headers. SFML links those from the system and
115
177
  they cannot be bundled.
@@ -210,8 +272,11 @@ module Ports
210
272
  end
211
273
  end
212
274
 
275
+ # The local archive keeps a fixed <name>-<version>.<ext> name regardless of
276
+ # what the upstream release calls it, so recipes can point at libogg-1.3.5.tar.gz
277
+ # or flac-1.4.3.tar.xz without the rest of the code caring.
213
278
  def tarball(recipe)
214
- File.join(ARCHIVES, "#{recipe[:name]}-#{recipe[:version]}.tar.gz")
279
+ File.join(ARCHIVES, "#{recipe[:name]}-#{recipe[:version]}.#{recipe[:ext] || 'tar.gz'}")
215
280
  end
216
281
 
217
282
  def source_dir(recipe)
@@ -273,6 +338,15 @@ module Ports
273
338
  -DCMAKE_INSTALL_LIBDIR=lib
274
339
  ]
275
340
  flags << "-DCMAKE_TOOLCHAIN_FILE=#{toolchain_file}" if cross?
341
+
342
+ # SFML 3.0.2 defaults CMAKE_OSX_DEPLOYMENT_TARGET to 13.0 in its own
343
+ # CMakeLists.txt, but the macOS SDK osxcross ships in the
344
+ # rake-compiler-dock image is 11.1, and osxcross refuses a target newer
345
+ # than its SDK ("targeted macOS version must be <= 11.1.0"). Pass it as a
346
+ # -D rather than writing it into the toolchain file because SFML's
347
+ # sfml_set_option() only supplies its default when the variable is not
348
+ # already defined -- a command-line cache entry always is.
349
+ flags << '-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0' if os == :darwin
276
350
  flags
277
351
  end
278
352
 
@@ -328,7 +402,7 @@ module Ports
328
402
  else
329
403
  # Debian multiarch: without this CMake searches /usr/lib, finds the
330
404
  # container's own amd64 libraries and hands them to an aarch64 linker.
331
- lines << "set(CMAKE_LIBRARY_ARCHITECTURE #{spec[:triple]})"
405
+ lines << "set(CMAKE_LIBRARY_ARCHITECTURE #{spec[:multiarch] || spec[:triple]})"
332
406
  end
333
407
  end
334
408
 
@@ -351,7 +425,9 @@ module Ports
351
425
 
352
426
  unless Dir.exist?(source)
353
427
  FileUtils.mkdir_p(build_root)
354
- run('tar', 'xzf', tarball(recipe), '-C', build_root)
428
+ # Plain `xf`, not `xzf`: GNU tar, bsdtar and mingw's tar all sniff the
429
+ # compression, which is what lets gzip and xz recipes share this path.
430
+ run('tar', 'xf', tarball(recipe), '-C', build_root)
355
431
  end
356
432
 
357
433
  puts "Building #{recipe[:name]} #{recipe[:version]} for #{target}"
@@ -0,0 +1,77 @@
1
+ #include "system/buffer.h"
2
+
3
+ #include <ruby.h>
4
+
5
+ #include "core/exceptions.h"
6
+ #include "core/macros.h"
7
+
8
+ static VALUE rb_cBuffer;
9
+
10
+ static void Buffer_free(void *ptr) {
11
+ sfBuffer_destroy(ptr);
12
+ }
13
+
14
+ static const rb_data_type_t Buffer_data_type = {
15
+ .wrap_struct_name = "SFML::Buffer",
16
+ .function = {.dmark = NULL, .dfree = Buffer_free, .dsize = NULL},
17
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
18
+ };
19
+
20
+ static VALUE Buffer_wrap(VALUE klass, sfBuffer *buffer) {
21
+ return TypedData_Wrap_Struct(klass, &Buffer_data_type, buffer);
22
+ }
23
+
24
+ static VALUE Buffer_new(VALUE klass) {
25
+ VALUE self;
26
+ sfBuffer *buffer = sfBuffer_create();
27
+
28
+ if (buffer == NULL) {
29
+ rb_raise(rb_eNoMemError, "could not create buffer");
30
+ }
31
+
32
+ self = Buffer_wrap(klass, buffer);
33
+
34
+ return self;
35
+ }
36
+
37
+ static VALUE Buffer_get_size(VALUE self) {
38
+ return SIZET2NUM(sfBuffer_getSize(Get_Buffer_Struct(self)));
39
+ }
40
+
41
+ static VALUE Buffer_get_data(VALUE self) {
42
+ sfBuffer *buffer = Get_Buffer_Struct(self);
43
+ size_t size = sfBuffer_getSize(buffer);
44
+ const uint8_t *data = sfBuffer_getData(buffer);
45
+
46
+ if (data == NULL || size == 0) {
47
+ return rb_str_new("", 0);
48
+ }
49
+
50
+ return rb_str_new((const char *) data, (long) size);
51
+ }
52
+
53
+ static VALUE Buffer_is_empty(VALUE self) {
54
+ return BOOL2RB(sfBuffer_getSize(Get_Buffer_Struct(self)) == 0);
55
+ }
56
+
57
+ void Init_Buffer(VALUE rb_module) {
58
+ rb_cBuffer = rb_define_class_under(rb_module, "Buffer", rb_cObject);
59
+
60
+ rb_define_singleton_method(rb_cBuffer, "new", Buffer_new, 0);
61
+
62
+ rb_define_method(rb_cBuffer, "size", Buffer_get_size, 0);
63
+ rb_define_method(rb_cBuffer, "length", Buffer_get_size, 0);
64
+ rb_define_method(rb_cBuffer, "data", Buffer_get_data, 0);
65
+ rb_define_method(rb_cBuffer, "to_s", Buffer_get_data, 0);
66
+ rb_define_method(rb_cBuffer, "empty?", Buffer_is_empty, 0);
67
+ }
68
+
69
+ VALUE Get_Klass_Buffer(void) {
70
+ return rb_cBuffer;
71
+ }
72
+
73
+ void *Get_Buffer_Struct(VALUE self) {
74
+ sfBuffer *ptr;
75
+ TypedData_Get_Struct(self, sfBuffer, &Buffer_data_type, ptr);
76
+ return ptr;
77
+ }
@@ -0,0 +1,14 @@
1
+ #ifndef SFML_RB_SYSTEM_BUFFER_H
2
+ #define SFML_RB_SYSTEM_BUFFER_H
3
+
4
+ #include <ruby.h>
5
+
6
+ #include "core/sfml.h"
7
+
8
+ void Init_Buffer(VALUE rb_module);
9
+
10
+ VALUE Get_Klass_Buffer(void);
11
+
12
+ void *Get_Buffer_Struct(VALUE self);
13
+
14
+ #endif //SFML_RB_SYSTEM_BUFFER_H
@@ -0,0 +1,100 @@
1
+ #include "system/clock.h"
2
+
3
+ #include <stdio.h>
4
+
5
+ #include "system/time.h"
6
+ #include "system/vec2.h"
7
+ #include "core/macros.h"
8
+ #include "core/sfml.h"
9
+
10
+ static VALUE rb_cClock;
11
+
12
+ static sfClock *Clock_create() {
13
+ return sfClock_create();
14
+ }
15
+
16
+ static void Clock_free(void *ptr) {
17
+ sfClock_destroy(ptr);
18
+ }
19
+
20
+ static const rb_data_type_t Clock_data_type = {
21
+ .wrap_struct_name = "SFML::Clock",
22
+ .function = {.dmark = NULL, .dfree = Clock_free, .dsize = NULL},
23
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
24
+ };
25
+
26
+ static VALUE Clock_new_from(VALUE klass, sfClock *clock) {
27
+ VALUE self;
28
+
29
+ self = TypedData_Wrap_Struct(klass, &Clock_data_type, clock);
30
+
31
+ rb_obj_call_init(self, 0, NULL);
32
+
33
+ return self;
34
+ }
35
+
36
+ static VALUE Clock_new(VALUE klass) {
37
+ return Clock_new_from(klass, Clock_create());
38
+ }
39
+
40
+ static VALUE Clock_init(VALUE self) {
41
+ return self;
42
+ }
43
+
44
+ static VALUE Clock_get_elapsed_time(VALUE self) {
45
+ return time_to_rb(sfClock_getElapsedTime(Get_Clock_Struct(self)));
46
+ }
47
+
48
+ static VALUE Clock_restart(VALUE self) {
49
+ return time_to_rb(sfClock_restart(Get_Clock_Struct(self)));
50
+ }
51
+
52
+ static VALUE Clock_reset(VALUE self) {
53
+ return time_to_rb(sfClock_reset(Get_Clock_Struct(self)));
54
+ }
55
+
56
+ static VALUE Clock_is_running(VALUE self) {
57
+ return BOOL2RB(sfClock_isRunning(Get_Clock_Struct(self)));
58
+ }
59
+
60
+ static VALUE Clock_start(VALUE self) {
61
+ sfClock_start(Get_Clock_Struct(self));
62
+ return self;
63
+ }
64
+
65
+ static VALUE Clock_stop(VALUE self) {
66
+ sfClock_stop(Get_Clock_Struct(self));
67
+ return self;
68
+ }
69
+
70
+ static VALUE Clock_copy(VALUE self) {
71
+ return Clock_new_from(Get_Klass_Clock(), sfClock_copy(Get_Clock_Struct(self)));
72
+ }
73
+
74
+ void Init_Clock(VALUE rb_module) {
75
+ rb_cClock = rb_define_class_under(rb_module, "Clock", rb_cObject);
76
+
77
+ rb_define_singleton_method(rb_cClock, "new", Clock_new, 0);
78
+
79
+ // methods
80
+ rb_define_method(rb_cClock, "initialize", Clock_init, 0);
81
+ rb_define_method(rb_cClock, "restart!", Clock_restart, 0);
82
+ rb_define_method(rb_cClock, "reset!", Clock_reset, 0);
83
+ rb_define_method(rb_cClock, "start!", Clock_start, 0);
84
+ rb_define_method(rb_cClock, "stop!", Clock_stop, 0);
85
+ rb_define_method(rb_cClock, "copy", Clock_copy, 0);
86
+
87
+ // getters
88
+ rb_define_method(rb_cClock, "elapsed_time", Clock_get_elapsed_time, 0);
89
+ rb_define_method(rb_cClock, "running?", Clock_is_running, 0);
90
+ }
91
+
92
+ void *Get_Clock_Struct(VALUE self) {
93
+ sfClock *clock;
94
+ TypedData_Get_Struct(self, sfClock, &Clock_data_type, clock);
95
+ return clock;
96
+ }
97
+
98
+ VALUE Get_Klass_Clock() {
99
+ return rb_cClock;
100
+ }
@@ -1,5 +1,5 @@
1
- #ifndef SFML_RB_CLOCK_H
2
- #define SFML_RB_CLOCK_H
1
+ #ifndef SFML_RB_SYSTEM_CLOCK_H
2
+ #define SFML_RB_SYSTEM_CLOCK_H
3
3
 
4
4
  #include <ruby.h>
5
5
 
@@ -9,4 +9,4 @@ void *Get_Clock_Struct(VALUE self);
9
9
 
10
10
  VALUE Get_Klass_Clock();
11
11
 
12
- #endif //SFML_RB_CLOCK_H
12
+ #endif //SFML_RB_SYSTEM_CLOCK_H