sfml3-rb 0.2.2 → 0.3.0

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 (137) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +9 -0
  3. data/CHANGELOG.md +43 -17
  4. data/README.md +97 -29
  5. data/ext/audio/audio_enums.c +58 -20
  6. data/ext/audio/listener.c +89 -6
  7. data/ext/audio/music.c +206 -5
  8. data/ext/audio/sound.c +175 -5
  9. data/ext/audio/sound_buffer.c +189 -47
  10. data/ext/audio/sound_buffer_recorder.c +83 -16
  11. data/ext/audio/sound_recorder.c +172 -52
  12. data/ext/audio/sound_source_cone.c +108 -29
  13. data/ext/audio/sound_stream.c +178 -5
  14. data/ext/core/exceptions.c +10 -8
  15. data/ext/core/unicode.c +12 -2
  16. data/ext/ext.c +4 -0
  17. data/ext/graphics/blend_mode.c +203 -53
  18. data/ext/graphics/circle.c +271 -4
  19. data/ext/graphics/color.c +240 -90
  20. data/ext/graphics/drawable.c +15 -4
  21. data/ext/graphics/font.c +138 -25
  22. data/ext/graphics/glyph.c +31 -8
  23. data/ext/graphics/image.c +180 -37
  24. data/ext/graphics/polygon.c +293 -26
  25. data/ext/graphics/rect.c +211 -54
  26. data/ext/graphics/rectangle.c +279 -26
  27. data/ext/graphics/render_state.c +116 -2
  28. data/ext/graphics/render_texture.c +163 -2
  29. data/ext/graphics/shader.c +283 -17
  30. data/ext/graphics/shape.c +252 -26
  31. data/ext/graphics/sprite.c +216 -25
  32. data/ext/graphics/stencil_mode.c +148 -39
  33. data/ext/graphics/target.c +67 -22
  34. data/ext/graphics/target.h +15 -15
  35. data/ext/graphics/text.c +306 -6
  36. data/ext/graphics/texture.c +257 -3
  37. data/ext/graphics/transform.c +178 -5
  38. data/ext/graphics/transformable.c +126 -2
  39. data/ext/graphics/vertex.c +79 -2
  40. data/ext/graphics/vertex_array.c +128 -16
  41. data/ext/graphics/vertex_buffer.c +124 -2
  42. data/ext/graphics/view.c +130 -2
  43. data/ext/network/ftp.c +249 -10
  44. data/ext/network/http.c +156 -38
  45. data/ext/network/ip_address.c +107 -26
  46. data/ext/network/network_enums.c +248 -141
  47. data/ext/network/packet.c +273 -39
  48. data/ext/network/socket_selector.c +91 -19
  49. data/ext/network/tcp_listener.c +75 -16
  50. data/ext/network/tcp_socket.c +128 -25
  51. data/ext/network/udp_socket.c +122 -26
  52. data/ext/ports.rb +7 -0
  53. data/ext/system/buffer.c +41 -12
  54. data/ext/system/clock.c +68 -9
  55. data/ext/system/input_stream.c +94 -42
  56. data/ext/system/sleep.c +10 -2
  57. data/ext/system/time.c +172 -34
  58. data/ext/system/vec2.c +156 -35
  59. data/ext/system/vec3.c +166 -35
  60. data/ext/window/clipboard.c +47 -17
  61. data/ext/window/context.c +59 -9
  62. data/ext/window/context_settings.c +116 -38
  63. data/ext/window/cursor.c +39 -9
  64. data/ext/window/event.c +163 -42
  65. data/ext/window/joystick.c +69 -3
  66. data/ext/window/keyboard.c +168 -116
  67. data/ext/window/mouse.c +36 -2
  68. data/ext/window/sensor.c +28 -2
  69. data/ext/window/touch.c +20 -2
  70. data/ext/window/video_mode.c +90 -19
  71. data/ext/window/vulkan.c +34 -6
  72. data/ext/window/window.c +340 -16
  73. data/lib/sfml/version.rb +1 -1
  74. data/sig/audio/audio_enums.rbs +30 -0
  75. data/sig/audio/listener.rbs +16 -0
  76. data/sig/audio/music.rbs +56 -0
  77. data/sig/audio/sound.rbs +51 -0
  78. data/sig/audio/sound_buffer.rbs +17 -0
  79. data/sig/audio/sound_buffer_recorder.rbs +14 -0
  80. data/sig/audio/sound_recorder.rbs +17 -0
  81. data/sig/audio/sound_source_cone.rbs +14 -0
  82. data/sig/audio/sound_stream.rbs +51 -0
  83. data/sig/graphics/blend_mode.rbs +29 -0
  84. data/sig/graphics/circle.rbs +44 -0
  85. data/sig/graphics/color.rbs +39 -0
  86. data/sig/graphics/drawable.rbs +5 -0
  87. data/sig/graphics/font.rbs +20 -0
  88. data/sig/graphics/glyph.rbs +7 -0
  89. data/sig/graphics/image.rbs +22 -0
  90. data/sig/graphics/polygon.rbs +42 -0
  91. data/sig/graphics/rect.rbs +33 -0
  92. data/sig/graphics/rectangle.rbs +42 -0
  93. data/sig/graphics/render_state.rbs +21 -0
  94. data/sig/graphics/render_texture.rbs +37 -0
  95. data/sig/graphics/shader.rbs +39 -0
  96. data/sig/graphics/shape.rbs +38 -0
  97. data/sig/graphics/sprite.rbs +34 -0
  98. data/sig/graphics/stencil_mode.rbs +18 -0
  99. data/sig/graphics/target.rbs +10 -0
  100. data/sig/graphics/text.rbs +48 -0
  101. data/sig/graphics/texture.rbs +34 -0
  102. data/sig/graphics/transform.rbs +37 -0
  103. data/sig/graphics/transformable.rbs +25 -0
  104. data/sig/graphics/vertex.rbs +17 -0
  105. data/sig/graphics/vertex_array.rbs +17 -0
  106. data/sig/graphics/vertex_buffer.rbs +22 -0
  107. data/sig/graphics/view.rbs +24 -0
  108. data/sig/network/ftp.rbs +46 -0
  109. data/sig/network/http.rbs +27 -0
  110. data/sig/network/ip_address.rbs +22 -0
  111. data/sig/network/network_enums.rbs +95 -0
  112. data/sig/network/packet.rbs +40 -0
  113. data/sig/network/socket_selector.rbs +14 -0
  114. data/sig/network/tcp_listener.rbs +13 -0
  115. data/sig/network/tcp_socket.rbs +18 -0
  116. data/sig/network/udp_socket.rbs +17 -0
  117. data/sig/system/buffer.rbs +11 -0
  118. data/sig/system/clock.rbs +13 -0
  119. data/sig/system/input_stream.rbs +7 -0
  120. data/sig/system/sleep.rbs +3 -0
  121. data/sig/system/time.rbs +28 -0
  122. data/sig/system/vec2.rbs +26 -0
  123. data/sig/system/vec3.rbs +27 -0
  124. data/sig/window/clipboard.rbs +8 -0
  125. data/sig/window/context.rbs +11 -0
  126. data/sig/window/context_settings.rbs +20 -0
  127. data/sig/window/cursor.rbs +6 -0
  128. data/sig/window/event.rbs +20 -0
  129. data/sig/window/joystick.rbs +15 -0
  130. data/sig/window/keyboard.rbs +10 -0
  131. data/sig/window/mouse.rbs +9 -0
  132. data/sig/window/sensor.rbs +8 -0
  133. data/sig/window/touch.rbs +6 -0
  134. data/sig/window/video_mode.rbs +16 -0
  135. data/sig/window/vulkan.rbs +7 -0
  136. data/sig/window/window.rbs +57 -0
  137. metadata +66 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc41a984a71094455d29e95d4c529a1e228e5c5442333aca6eb57b9b7c9d3f5e
4
- data.tar.gz: 835286043ece71ba5dc8c1790cdd6ab0370ae0924823771e03a811cd8acba1af
3
+ metadata.gz: 2ef7284361fdd31619f9f97c920664262125cfb26936bbc8a6425ff6c585e12c
4
+ data.tar.gz: 59baa039d3fa9f7d704469f3204070dc90dc8db48f2be3e9737c7e888554ed7e
5
5
  SHA512:
6
- metadata.gz: f75f7ce8244a36a0a8e93903ea0d323513753cfdf3e82f79364b3081a3d5ac651609897a0d4911c2509aac1e5107c37ab9ea9341eede85bb630a05228273ed3d
7
- data.tar.gz: 68a989c7d4e1147cd5585bf8db85be15c3c1419bbefaeca95791fa37575900d8b841d1b33dd5009f9611e3b5a365b7410c7687ca8eecf96d188a05feb6de269f
6
+ metadata.gz: d2d1dbf0f61b9c418e1aa01e81770158390cb28b9f297157195357463bd7ac6ca2e8ac0d2974f295968f4e762dd6e4affa330bf72df4cba5588a4bc30f459c74
7
+ data.tar.gz: 2b959e3a75e33a5633ec3cdaf64e2d5c95bdaa62ff58d37e981b114a3e52b0a69df5594c1adbf32a47446c3c1d4bd3f961a99ae06f56dde83ce80af2b6468934
data/.yardopts ADDED
@@ -0,0 +1,9 @@
1
+ --markup markdown
2
+ --output-dir doc
3
+ --title sfml3-rb
4
+ --readme README.md
5
+ ext/**/*.c
6
+ -
7
+ CHANGELOG.md
8
+ TODO.md
9
+ LICENSE.md
data/CHANGELOG.md CHANGED
@@ -6,26 +6,52 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
- ### Added
10
- * **Full YARD API documentation and RBS type signatures**, covering every
11
- bound class, module, method and constant. Doc comments live in-place in
12
- the `ext/**/*.c` sources (YARD's C parser, the same convention RDoc uses),
13
- so they're published automatically to
14
- [rubydoc.info](https://rubydoc.info/gems/sfml3-rb) on release; `rake yard`
15
- builds them locally into `doc/`. `sig/**/*.rbs` ships in the gem alongside
16
- the extension sources, for IDE completion (Solargraph, RubyMine) and
17
- static type-checking (Sorbet, Steep). Run `rake rbs` to validate the
18
- signatures.
9
+ ## [0.3.0] - 2026-09-19
19
10
 
20
- ## [0.2.2]
11
+ ### Added
12
+ * **Four more experimental binary-gem targets**: `aarch64-linux-musl`, `arm-linux-gnu`
13
+ (ARMv7 hard-float), `arm-linux-musl`, and `aarch64-mingw-ucrt` (64-bit Windows on ARM).
14
+ All four ride the same rake-compiler-dock cross-compilation this project already uses for
15
+ its other targets; none has been run on its target hardware yet, so all are
16
+ `experimental` in `publish.yaml` like `aarch64-linux-gnu`, `x86_64-darwin` and
17
+ `arm64-darwin` already were. `script/provision.sh` gained matching cases for the two new
18
+ glibc/musl Linux targets.
19
+ * `rakelib/package.rake`'s `EXPECTED_ABIS` gained an entry for `aarch64-mingw-ucrt`: its
20
+ rake-compiler-dock image carries no cross Ruby older than 3.4, so that gem has no floor
21
+ below it — the same kind of upstream gap `x86-mingw32` already has at the top end.
22
+ * `aarch64-linux-gnu` is now additionally run — not just cross-compiled — by a new
23
+ `test-arm64.yaml` workflow, on GitHub's hosted `ubuntu-24.04-arm` runner. It stays
24
+ `experimental` in `publish.yaml` for now; this is the evidence that will eventually
25
+ justify dropping that flag.
26
+ * ARMv6 (32-bit), RISC-V (rv64gc), PowerPC (ppc64le), and any BSD are deliberately not
27
+ covered by a binary gem: rake-compiler-dock ships no cross-compilation image for any of
28
+ them, and building custom cross-toolchain infrastructure for them is a much larger,
29
+ separate undertaking. The source-gem fallback remains the only path there, unchanged.
21
30
 
22
31
  ### Fixed
23
- * **The macOS binary gems now build.** SFML 3.0.2 defaults
24
- `CMAKE_OSX_DEPLOYMENT_TARGET` to 13.0, but the osxcross SDK in the
25
- rake-compiler-dock image is 11.1 and rejects a newer target, so both Darwin
26
- builds aborted while configuring SFML. The ports toolchain now pins the
27
- deployment target to macOS 11.0, which is the floor Apple Silicon requires
28
- anyway.
32
+ * **A GC race in the audio bindings aborted the process on arm64.** `Sound`, `Music` and
33
+ `SoundStream` released the GVL inside their `dfree`, but their data types were marked
34
+ `RUBY_TYPED_FREE_IMMEDIATELY`, so the free could run *during* garbage collection: another
35
+ thread (Ruby's `Timeout` thread, in the test suite) could then allocate while GC was mid-cycle
36
+ and Ruby aborted with "object allocation during garbage collection phase". Dropping the flag
37
+ defers the free to a safe point; releasing the GVL is still what keeps `sf*_destroy` from
38
+ deadlocking against the audio thread.
39
+
40
+ ### Documentation
41
+ * **Every public class, module, method and constant is documented**, with the
42
+ result rendered on [rubydoc.info](https://rubydoc.info/gems/sfml3-rb). The
43
+ comments live beside each binding in `ext/**/*.c`; `rake yard` builds them
44
+ into `doc/`. Previously the comments carried `call-seq` and `@return` tags
45
+ but little prose, so rubydoc.info showed a signature with a blank
46
+ description; every such method now has a sentence of its own.
47
+ * RBS type signatures for the same surface ship in `sig/**/*.rbs`, for IDE
48
+ completion (Solargraph, RubyMine) and static checking (Sorbet, Steep);
49
+ `rake rbs` validates them.
50
+ * `.yardopts` ships in the gem, so rubydoc.info generates with the same title,
51
+ README and extra files as `rake yard`.
52
+ * `rake doc:undoc` fails when a method is left without a description, so the
53
+ coverage cannot regress silently (`yard stats` uses `blank?` and passes for
54
+ tag-only comments, which is how the blanks went unnoticed).
29
55
 
30
56
  ## [0.2.1]
31
57
 
data/README.md CHANGED
@@ -2,17 +2,40 @@
2
2
 
3
3
  Ruby bindings for [SFML 3](https://www.sfml-dev.org/), via its C API, [CSFML](https://github.com/SFML/CSFML).
4
4
 
5
- ## Status
6
-
7
- Latest release: **0.2.2**. Bound against **CSFML 3**. See [TODO.md](TODO.md) for which parts of the
8
- SFML 3 API are ported so far, and [CHANGELOG.md](CHANGELOG.md) for what changed recently.
9
-
10
- API docs (every class, module, method and constant) are on
11
- [rubydoc.info](https://rubydoc.info/gems/sfml3-rb). The gem also ships RBS type signatures
12
- (`sig/**/*.rbs`) alongside the extension sources, for IDE completion (Solargraph, RubyMine) and
13
- static type-checking (Sorbet, Steep).
14
-
15
- ## Install
5
+ [![Ruby](https://img.shields.io/badge/ruby-3.1%2B-red?style=flat-square)](https://www.ruby-lang.org/)
6
+ [![Test](https://github.com/algaves/sfml3.rb/actions/workflows/test.yaml/badge.svg)](https://github.com/algaves/sfml3.rb/actions/workflows/test.yaml)
7
+ [![Check](https://github.com/algaves/sfml3.rb/actions/workflows/check.yaml/badge.svg)](https://github.com/algaves/sfml3.rb/actions/workflows/check.yaml)
8
+ [![Gem Version](https://img.shields.io/gem/v/sfml3-rb?style=flat-square)](https://rubygems.org/gems/sfml3-rb)
9
+ [![Gem Downloads](https://img.shields.io/gem/dt/sfml3-rb?style=flat-square)](https://rubygems.org/gems/sfml3-rb)
10
+ [![License](https://img.shields.io/badge/license-0BSD-green?style=flat-square)](LICENSE.md)
11
+
12
+ Latest release: **0.3.0**, bound against **CSFML 3**.
13
+
14
+ ## Features
15
+
16
+ * **Broad coverage of SFML 3**, bound through CSFML: windows and events, graphics, audio, network,
17
+ and the system layer, with every `sf*` entry point tracked in [TODO.md](TODO.md).
18
+ * **Precompiled binary gems** for common platforms, with FreeType, SFML 3 and CSFML 3 statically
19
+ linked in — no toolchain and nothing to install system-wide.
20
+ * **A source fallback everywhere else**, which downloads and builds the pinned, checksum-verified
21
+ dependencies at install time, so the gem works on macOS, ARM and the BSDs out of the box.
22
+ * **Complete API documentation and types**: every class, module, method and constant is documented
23
+ on [rubydoc.info](https://rubydoc.info/gems/sfml3-rb) and covered by RBS signatures shipped in
24
+ the gem.
25
+ * **A close fit to SFML's own model**: classes mirror the C++ types (Window, Texture, Sprite,
26
+ Sound, ...) minus the parts that only exist in C++, like `std::string` and exceptions.
27
+
28
+ ## Table of Contents
29
+
30
+ * [Installation](#installation)
31
+ * [Quick Start](#quick-start)
32
+ * [Documentation](#documentation)
33
+ * [Development](#development)
34
+ * [Contributing](#contributing)
35
+ * [Acknowledgements](#acknowledgements)
36
+ * [License](#license)
37
+
38
+ ## Installation
16
39
 
17
40
  ```sh
18
41
  gem install sfml3-rb
@@ -29,11 +52,18 @@ already linked in — no toolchain, no build, nothing to install system-wide:
29
52
  | `x86-linux-musl` | 3.1 – 4.0 | 32-bit musl |
30
53
  | `x64-mingw-ucrt` | 3.1 – 4.0 | 64-bit Windows, RubyInstaller 3.1+ |
31
54
  | `x86-mingw32` | 3.1 – **3.4** | 32-bit Windows |
32
- | `aarch64-linux-gnu`, `x86_64-darwin`, `arm64-darwin` | 3.1 – 4.0 | experimental, not yet built |
55
+ | `aarch64-linux-gnu` | 3.1 – 4.0 | experimental, cross-built and run on a native arm64 CI runner |
56
+ | `aarch64-linux-musl`, `arm-linux-gnu`, `arm-linux-musl` | 3.1 – 4.0 | experimental, not yet built |
57
+ | `aarch64-mingw-ucrt` | 3.4 – **4.0** | experimental, 64-bit Windows on ARM |
58
+ | `x86_64-darwin`, `arm64-darwin` | 3.1 – 4.0 | experimental, not yet built |
33
59
 
34
- Each gem carries one extension per Ruby ABI. Two gaps come from upstream rather than from this
35
- project: **RubyInstaller publishes no 32-bit Ruby 4.0**, so `x86-mingw32` stops at 3.4; and 64-bit
36
- Windows before Ruby 3.1 used a different platform (`x64-mingw32`), which is not built.
60
+ Each gem carries one extension per Ruby ABI. Three gaps come from upstream rather than from this
61
+ project: **RubyInstaller publishes no 32-bit Ruby 4.0**, so `x86-mingw32` stops at 3.4; 64-bit
62
+ Windows before Ruby 3.1 used a different platform (`x64-mingw32`), which is not built; and the
63
+ cross-compilation image for `aarch64-mingw-ucrt` carries no cross Ruby older than 3.4, so that
64
+ gem has no floor below it.
65
+
66
+ ### Building from source
37
67
 
38
68
  Anywhere else — macOS, ARM, the BSDs — RubyGems falls back to the source gem, which downloads and
39
69
  builds FreeType, SFML 3 and CSFML 3 from pinned, checksum-verified tarballs at install time. That
@@ -42,36 +72,39 @@ takes a few minutes and needs:
42
72
  * Ruby >= 3.1
43
73
  * A C/C++ toolchain and CMake >= 3.22
44
74
  * On Linux, the X11/udev/OpenGL development headers SFML links against — these can't be bundled.
45
- On Fedora:
46
75
 
47
- ```sh
48
- sudo dnf install cmake gcc-c++ libX11-devel \
49
- libXrandr-devel libXcursor-devel libXi-devel systemd-devel libglvnd-devel
50
- ```
76
+ On Fedora:
51
77
 
52
- or on Debian/Ubuntu:
78
+ ```sh
79
+ sudo dnf install cmake gcc-c++ libX11-devel \
80
+ libXrandr-devel libXcursor-devel libXi-devel systemd-devel libglvnd-devel
81
+ ```
53
82
 
54
- ```sh
55
- sudo apt-get install cmake build-essential libx11-dev \
56
- libxrandr-dev libxcursor-dev libxi-dev libudev-dev libgl1-mesa-dev
57
- ```
83
+ On Debian/Ubuntu:
84
+
85
+ ```sh
86
+ sudo apt-get install cmake build-essential libx11-dev \
87
+ libxrandr-dev libxcursor-dev libxi-dev libudev-dev libgl1-mesa-dev
88
+ ```
58
89
 
59
90
  Each installed gem version builds its own copy; there's no build cache shared across versions.
60
91
 
92
+ ### Linking against system libraries
93
+
61
94
  To link against a system CSFML 3 instead (no download, no build):
62
95
 
63
96
  ```sh
64
97
  gem install sfml3-rb -- --enable-system-libraries
65
98
  ```
66
99
 
67
- ## Usage
100
+ ## Quick Start
68
101
 
69
102
  ```ruby
70
103
  require 'sfml'
71
104
  include SFML
72
105
 
73
106
  window = Window.new VideoMode.new(640, 480, 32), 'SFML'
74
- event = Event.new
107
+ event = Event.new
75
108
 
76
109
  while window.is_open?
77
110
  while window.poll_event! event
@@ -83,7 +116,20 @@ while window.is_open?
83
116
  end
84
117
  ```
85
118
 
86
- See [`test/hello-world.rb`](test/hello-world.rb) for a fuller example with shapes and transforms.
119
+ Event types are strings (`'closed'`, `'resized'`, `'key-pressed'`, ...); keys and buttons are enums.
120
+
121
+ See [`test/hello-world.rb`](test/hello-world.rb) for a fuller example with shapes and transforms,
122
+ and [`test/matrix-transformable.rb`](test/matrix-transformable.rb) for a visual demo. Neither is
123
+ part of the test suite.
124
+
125
+ ## Documentation
126
+
127
+ * [API reference](https://rubydoc.info/gems/sfml3-rb) — every class, module, method and constant,
128
+ built from the YARD comments in `ext/**/*.c`.
129
+ * RBS type signatures (`sig/**/*.rbs`) ship in the gem for IDE completion (Solargraph, RubyMine)
130
+ and static type-checking (Sorbet, Steep). Validate them with `rake rbs`.
131
+ * [CHANGELOG.md](CHANGELOG.md) — what changed in each release.
132
+ * [TODO.md](TODO.md) — module-by-module porting coverage and what is deliberately unbound.
87
133
 
88
134
  ## Development
89
135
 
@@ -138,9 +184,31 @@ mingw toolchain and the osxcross SDK already provide.
138
184
  Binary gems carry one extension per Ruby ABI under `lib/sfml/<major.minor>/`; `lib/sfml.rb` prefers
139
185
  that and falls back to the single `lib/sfml/sfml_ext.so` a source build installs.
140
186
 
187
+ ## Contributing
188
+
189
+ Bug reports and pull requests are welcome on
190
+ [GitHub](https://github.com/algaves/sfml3.rb/issues). Before opening a pull request:
191
+
192
+ ```sh
193
+ bundle install
194
+ bundle exec rake test # build the extension and run the suite
195
+ bundle exec rubocop # lint Ruby (CI enforces this)
196
+ ```
197
+
198
+ Install the pre-commit hook with `bundle exec rake githooks:install` so staged Ruby is linted and
199
+ staged C is formatted automatically. The C build is warning-clean under `SFML_STRICT=1`; keep it
200
+ that way.
201
+
202
+ ## Acknowledgements
203
+
204
+ This gem would not exist without [SFML](https://www.sfml-dev.org/) and its C binding,
205
+ [CSFML](https://github.com/SFML/CSFML), both maintained by the SFML team. The source build also
206
+ vendors and links FreeType, Ogg, Vorbis and FLAC; see [`ext/ports.rb`](ext/ports.rb) and the
207
+ [LICENSE](LICENSE.md) for their terms.
208
+
141
209
  ## License
142
210
 
143
- [0BSD](LICENSE.md)
211
+ This project is licensed under the BSD Zero Clause License (0BSD) - see the [LICENSE](LICENSE.md) file for details.
144
212
 
145
213
  ---
146
214
 
@@ -3,12 +3,12 @@
3
3
  #include <ruby.h>
4
4
  #include <string.h>
5
5
 
6
- static const char *sound_status_names[] = {"stopped", "paused", "playing"};
6
+ static const char* sound_status_names[] = {"stopped", "paused", "playing"};
7
7
 
8
8
  /* Designated initializers, indexed by the enum constant rather than by
9
9
  position: CSFML 3 defines the channel order, and a positional table would
10
10
  silently return the wrong name if a future release inserted a value. */
11
- static const char *sound_channel_names[] = {
11
+ static const char* sound_channel_names[] = {
12
12
  [sfSoundChannelUnspecified] = "unspecified",
13
13
  [sfSoundChannelMono] = "mono",
14
14
  [sfSoundChannelFrontLeft] = "front_left",
@@ -28,11 +28,10 @@ static const char *sound_channel_names[] = {
28
28
  [sfSoundChannelTopFrontCenter] = "top_front_center",
29
29
  [sfSoundChannelTopBackLeft] = "top_back_left",
30
30
  [sfSoundChannelTopBackRight] = "top_back_right",
31
- [sfSoundChannelTopBackCenter] = "top_back_center"
32
- };
31
+ [sfSoundChannelTopBackCenter] = "top_back_center"};
33
32
 
34
- static int symbol_index(VALUE rb_symbol, const char *const *names, size_t count) {
35
- const char *name;
33
+ static int symbol_index(VALUE rb_symbol, const char* const* names, size_t count) {
34
+ const char* name;
36
35
  size_t i;
37
36
 
38
37
  if (!SYMBOL_P(rb_symbol)) {
@@ -43,14 +42,14 @@ static int symbol_index(VALUE rb_symbol, const char *const *names, size_t count)
43
42
 
44
43
  for (i = 0; i < count; i++) {
45
44
  if (names[i] != NULL && strcmp(name, names[i]) == 0) {
46
- return (int) i;
45
+ return (int)i;
47
46
  }
48
47
  }
49
48
 
50
49
  return -1;
51
50
  }
52
51
 
53
- const char *sound_status_name(sfSoundStatus status) {
52
+ const char* sound_status_name(sfSoundStatus status) {
54
53
  if (status >= sfStopped && status <= sfPlaying) {
55
54
  return sound_status_names[status];
56
55
  }
@@ -62,7 +61,7 @@ sfSoundStatus sound_status_from_rb(VALUE rb_status) {
62
61
  int index;
63
62
 
64
63
  if (RB_INTEGER_TYPE_P(rb_status)) {
65
- return (sfSoundStatus) NUM2INT(rb_status);
64
+ return (sfSoundStatus)NUM2INT(rb_status);
66
65
  }
67
66
 
68
67
  index = symbol_index(rb_status, sound_status_names, 3);
@@ -71,10 +70,10 @@ sfSoundStatus sound_status_from_rb(VALUE rb_status) {
71
70
  rb_raise(rb_eArgError, "unknown sound status");
72
71
  }
73
72
 
74
- return (sfSoundStatus) index;
73
+ return (sfSoundStatus)index;
75
74
  }
76
75
 
77
- const char *sound_channel_name(sfSoundChannel channel) {
76
+ const char* sound_channel_name(sfSoundChannel channel) {
78
77
  if (channel >= sfSoundChannelUnspecified && channel <= sfSoundChannelTopBackCenter &&
79
78
  sound_channel_names[channel] != NULL) {
80
79
  return sound_channel_names[channel];
@@ -87,7 +86,7 @@ sfSoundChannel sound_channel_from_rb(VALUE rb_channel) {
87
86
  int index;
88
87
 
89
88
  if (RB_INTEGER_TYPE_P(rb_channel)) {
90
- return (sfSoundChannel) NUM2INT(rb_channel);
89
+ return (sfSoundChannel)NUM2INT(rb_channel);
91
90
  }
92
91
 
93
92
  index = symbol_index(rb_channel, sound_channel_names,
@@ -97,35 +96,74 @@ sfSoundChannel sound_channel_from_rb(VALUE rb_channel) {
97
96
  rb_raise(rb_eArgError, "unknown sound channel");
98
97
  }
99
98
 
100
- return (sfSoundChannel) index;
99
+ return (sfSoundChannel)index;
101
100
  }
102
101
 
103
- void Init_AudioEnums(VALUE rb_module) {
104
- VALUE rb_mSoundStatus = rb_define_module_under(rb_module, "SoundStatus");
105
- VALUE rb_mSoundChannel = rb_define_module_under(rb_module, "SoundChannel");
106
-
102
+ /* Document-module: SFML::SoundStatus
103
+ * Playback state constants returned by SoundSource#status (Sound, Music,
104
+ * SoundStream). Mirrored as symbols (+:stopped+, +:paused+, +:playing+) by
105
+ * that method rather than these Integer constants, but both refer to the
106
+ * same underlying values.
107
+ */
108
+
109
+ /* Document-module: SFML::SoundChannel
110
+ * Speaker position constants used in a channel map (SoundBuffer#channel_map,
111
+ * Music#channel_map, SoundStream#channel_map, SoundRecorder#channel_map),
112
+ * mirrored as symbols (e.g. +:front_left+) rather than these Integer
113
+ * constants in those methods.
114
+ */
115
+ void Init_AudioEnums(VALUE rb_mSFML) {
116
+ VALUE rb_mSoundStatus = rb_define_module_under(rb_mSFML, "SoundStatus");
117
+ VALUE rb_mSoundChannel = rb_define_module_under(rb_mSFML, "SoundChannel");
118
+
119
+ /* The source is not playing. */
107
120
  rb_define_const(rb_mSoundStatus, "STOPPED", INT2NUM(sfStopped));
121
+ /* The source is paused; #playing_offset stays where it was paused. */
108
122
  rb_define_const(rb_mSoundStatus, "PAUSED", INT2NUM(sfPaused));
123
+ /* The source is currently playing. */
109
124
  rb_define_const(rb_mSoundStatus, "PLAYING", INT2NUM(sfPlaying));
110
125
 
126
+ /* No channel position specified. */
111
127
  rb_define_const(rb_mSoundChannel, "UNSPECIFIED", INT2NUM(sfSoundChannelUnspecified));
128
+ /* A single, centered channel. */
112
129
  rb_define_const(rb_mSoundChannel, "MONO", INT2NUM(sfSoundChannelMono));
130
+ /* Front left speaker. */
113
131
  rb_define_const(rb_mSoundChannel, "FRONT_LEFT", INT2NUM(sfSoundChannelFrontLeft));
132
+ /* Front right speaker. */
114
133
  rb_define_const(rb_mSoundChannel, "FRONT_RIGHT", INT2NUM(sfSoundChannelFrontRight));
134
+ /* Front center speaker. */
115
135
  rb_define_const(rb_mSoundChannel, "FRONT_CENTER", INT2NUM(sfSoundChannelFrontCenter));
116
- rb_define_const(rb_mSoundChannel, "FRONT_LEFT_OF_CENTER", INT2NUM(sfSoundChannelFrontLeftOfCenter));
117
- rb_define_const(rb_mSoundChannel, "FRONT_RIGHT_OF_CENTER", INT2NUM(sfSoundChannelFrontRightOfCenter));
118
- rb_define_const(rb_mSoundChannel, "LOW_FREQUENCY_EFFECTS", INT2NUM(sfSoundChannelLowFrequencyEffects));
136
+ /* Front left-of-center speaker. */
137
+ rb_define_const(rb_mSoundChannel, "FRONT_LEFT_OF_CENTER",
138
+ INT2NUM(sfSoundChannelFrontLeftOfCenter));
139
+ /* Front right-of-center speaker. */
140
+ rb_define_const(rb_mSoundChannel, "FRONT_RIGHT_OF_CENTER",
141
+ INT2NUM(sfSoundChannelFrontRightOfCenter));
142
+ /* Low-frequency effects (subwoofer) channel. */
143
+ rb_define_const(rb_mSoundChannel, "LOW_FREQUENCY_EFFECTS",
144
+ INT2NUM(sfSoundChannelLowFrequencyEffects));
145
+ /* Back left speaker. */
119
146
  rb_define_const(rb_mSoundChannel, "BACK_LEFT", INT2NUM(sfSoundChannelBackLeft));
147
+ /* Back right speaker. */
120
148
  rb_define_const(rb_mSoundChannel, "BACK_RIGHT", INT2NUM(sfSoundChannelBackRight));
149
+ /* Back center speaker. */
121
150
  rb_define_const(rb_mSoundChannel, "BACK_CENTER", INT2NUM(sfSoundChannelBackCenter));
151
+ /* Side left speaker. */
122
152
  rb_define_const(rb_mSoundChannel, "SIDE_LEFT", INT2NUM(sfSoundChannelSideLeft));
153
+ /* Side right speaker. */
123
154
  rb_define_const(rb_mSoundChannel, "SIDE_RIGHT", INT2NUM(sfSoundChannelSideRight));
155
+ /* Top center speaker. */
124
156
  rb_define_const(rb_mSoundChannel, "TOP_CENTER", INT2NUM(sfSoundChannelTopCenter));
157
+ /* Top front left speaker. */
125
158
  rb_define_const(rb_mSoundChannel, "TOP_FRONT_LEFT", INT2NUM(sfSoundChannelTopFrontLeft));
159
+ /* Top front right speaker. */
126
160
  rb_define_const(rb_mSoundChannel, "TOP_FRONT_RIGHT", INT2NUM(sfSoundChannelTopFrontRight));
161
+ /* Top front center speaker. */
127
162
  rb_define_const(rb_mSoundChannel, "TOP_FRONT_CENTER", INT2NUM(sfSoundChannelTopFrontCenter));
163
+ /* Top back left speaker. */
128
164
  rb_define_const(rb_mSoundChannel, "TOP_BACK_LEFT", INT2NUM(sfSoundChannelTopBackLeft));
165
+ /* Top back right speaker. */
129
166
  rb_define_const(rb_mSoundChannel, "TOP_BACK_RIGHT", INT2NUM(sfSoundChannelTopBackRight));
167
+ /* Top back center speaker. */
130
168
  rb_define_const(rb_mSoundChannel, "TOP_BACK_CENTER", INT2NUM(sfSoundChannelTopBackCenter));
131
169
  }
data/ext/audio/listener.c CHANGED
@@ -5,68 +5,151 @@
5
5
  #include "audio/sound_source_cone.h"
6
6
  #include "system/vec3.h"
7
7
 
8
+ /* call-seq: global_volume -> Float
9
+ *
10
+ * Returns the global volume applied to every sound source in the scene.
11
+ *
12
+ * @return [Float] 0 to 100
13
+ */
8
14
  static VALUE Listener_global_volume(VALUE module) {
9
15
  return DBL2NUM(sfListener_getGlobalVolume());
10
16
  }
11
17
 
18
+ /* call-seq:
19
+ * global_volume=(value) -> Float
20
+ *
21
+ * Sets the global volume all sound sources are scaled by.
22
+ *
23
+ * @return [Float] +value+
24
+ */
12
25
  static VALUE Listener_set_global_volume(VALUE module, VALUE rb_value) {
13
- sfListener_setGlobalVolume((float) NUM2DBL(rb_value));
26
+ sfListener_setGlobalVolume((float)NUM2DBL(rb_value));
14
27
  return rb_value;
15
28
  }
16
29
 
30
+ /* call-seq: position -> Vector3
31
+ *
32
+ * Returns the listener's position in the 3D audio scene.
33
+ *
34
+ * @return [Vector3]
35
+ */
17
36
  static VALUE Listener_position(VALUE module) {
18
37
  return vec3f_to_rb(sfListener_getPosition());
19
38
  }
20
39
 
40
+ /* call-seq:
41
+ * position=(value) -> Vector3
42
+ *
43
+ * Sets the listener's position in the 3D audio scene.
44
+ *
45
+ * @return [Vector3] +value+
46
+ */
21
47
  static VALUE Listener_set_position(VALUE module, VALUE rb_value) {
22
48
  sfListener_setPosition(vec3f_from_rb(rb_value));
23
49
  return rb_value;
24
50
  }
25
51
 
52
+ /* call-seq: direction -> Vector3
53
+ *
54
+ * Returns the direction the listener is facing, used for spatialization.
55
+ *
56
+ * @return [Vector3]
57
+ */
26
58
  static VALUE Listener_direction(VALUE module) {
27
59
  return vec3f_to_rb(sfListener_getDirection());
28
60
  }
29
61
 
62
+ /* call-seq:
63
+ * direction=(value) -> Vector3
64
+ *
65
+ * Sets the direction the listener is facing.
66
+ *
67
+ * @return [Vector3] +value+
68
+ */
30
69
  static VALUE Listener_set_direction(VALUE module, VALUE rb_value) {
31
70
  sfListener_setDirection(vec3f_from_rb(rb_value));
32
71
  return rb_value;
33
72
  }
34
73
 
74
+ /* call-seq: velocity -> Vector3
75
+ *
76
+ * Returns the listener's velocity, used for Doppler calculations.
77
+ *
78
+ * @return [Vector3]
79
+ */
35
80
  static VALUE Listener_velocity(VALUE module) {
36
81
  return vec3f_to_rb(sfListener_getVelocity());
37
82
  }
38
83
 
84
+ /* call-seq:
85
+ * velocity=(value) -> Vector3
86
+ *
87
+ * Sets the listener's velocity for Doppler calculations.
88
+ *
89
+ * @return [Vector3] +value+
90
+ */
39
91
  static VALUE Listener_set_velocity(VALUE module, VALUE rb_value) {
40
92
  sfListener_setVelocity(vec3f_from_rb(rb_value));
41
93
  return rb_value;
42
94
  }
43
95
 
96
+ /* call-seq: up_vector -> Vector3
97
+ *
98
+ * Returns the listener's up vector, defining its vertical orientation.
99
+ *
100
+ * @return [Vector3]
101
+ */
44
102
  static VALUE Listener_up_vector(VALUE module) {
45
103
  return vec3f_to_rb(sfListener_getUpVector());
46
104
  }
47
105
 
106
+ /* call-seq:
107
+ * up_vector=(value) -> Vector3
108
+ *
109
+ * Sets the listener's up vector, defining its vertical orientation.
110
+ *
111
+ * @return [Vector3] +value+
112
+ */
48
113
  static VALUE Listener_set_up_vector(VALUE module, VALUE rb_value) {
49
114
  sfListener_setUpVector(vec3f_from_rb(rb_value));
50
115
  return rb_value;
51
116
  }
52
117
 
118
+ /* call-seq: cone -> SoundSourceCone
119
+ *
120
+ * Returns the listener's directional attenuation cone.
121
+ *
122
+ * @return [SoundSourceCone]
123
+ */
53
124
  static VALUE Listener_cone(VALUE module) {
54
125
  sfListenerCone cone = sfListener_getCone();
55
126
 
56
- return sound_source_cone_to_rb((sfSoundSourceCone) {cone.innerAngle, cone.outerAngle,
57
- cone.outerGain});
127
+ return sound_source_cone_to_rb(
128
+ (sfSoundSourceCone){cone.innerAngle, cone.outerAngle, cone.outerGain});
58
129
  }
59
130
 
131
+ /* call-seq:
132
+ * cone=(value) -> SoundSourceCone
133
+ *
134
+ * Sets the listener's directional attenuation cone.
135
+ *
136
+ * @return [SoundSourceCone] +value+
137
+ */
60
138
  static VALUE Listener_set_cone(VALUE module, VALUE rb_value) {
61
139
  sfSoundSourceCone cone = sound_source_cone_from_rb(rb_value);
62
140
 
63
- sfListener_setCone((sfListenerCone) {cone.innerAngle, cone.outerAngle, cone.outerGain});
141
+ sfListener_setCone((sfListenerCone){cone.innerAngle, cone.outerAngle, cone.outerGain});
64
142
 
65
143
  return rb_value;
66
144
  }
67
145
 
68
- void Init_Listener(VALUE rb_module) {
69
- VALUE rb_mListener = rb_define_module_under(rb_module, "Listener");
146
+ /* Document-module: SFML::Listener
147
+ * Module functions controlling the single global audio listener: its
148
+ * position, orientation and volume, against which every SoundSource's
149
+ * spatialization is computed.
150
+ */
151
+ void Init_Listener(VALUE rb_mSFML) {
152
+ VALUE rb_mListener = rb_define_module_under(rb_mSFML, "Listener");
70
153
 
71
154
  rb_define_module_function(rb_mListener, "global_volume", Listener_global_volume, 0);
72
155
  rb_define_module_function(rb_mListener, "global_volume=", Listener_set_global_volume, 1);