@bornengine/engine 0.4.16

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 (213) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +231 -0
  3. package/native/android/Cargo.lock +1848 -0
  4. package/native/android/Cargo.toml +24 -0
  5. package/native/android/src/lib.rs +702 -0
  6. package/native/ios/Cargo.lock +1690 -0
  7. package/native/ios/Cargo.toml +32 -0
  8. package/native/ios/src/lib.rs +1267 -0
  9. package/native/linux/Cargo.lock +3279 -0
  10. package/native/linux/Cargo.toml +29 -0
  11. package/native/linux/src/lib.rs +1331 -0
  12. package/native/macos/Cargo.lock +3310 -0
  13. package/native/macos/Cargo.toml +46 -0
  14. package/native/macos/src/lib.rs +1302 -0
  15. package/native/shared/Cargo.lock +1899 -0
  16. package/native/shared/Cargo.toml +62 -0
  17. package/native/shared/assets/default_font.ttf +0 -0
  18. package/native/shared/build.rs +270 -0
  19. package/native/shared/shaders/common/clouds.wgsl +122 -0
  20. package/native/shared/shaders/common/fog.wgsl +16 -0
  21. package/native/shared/shaders/common/foliage_wind.wgsl +98 -0
  22. package/native/shared/shaders/common/imposter.wgsl +112 -0
  23. package/native/shared/shaders/common/pbr.wgsl +186 -0
  24. package/native/shared/shaders/common/shadows.wgsl +186 -0
  25. package/native/shared/shaders/common/sky.wgsl +8 -0
  26. package/native/shared/shaders/common/tonemap.wgsl +25 -0
  27. package/native/shared/shaders/impulse_field.wgsl +57 -0
  28. package/native/shared/shaders/material_abi.wgsl +383 -0
  29. package/native/shared/shaders/materials/test_minimal.wgsl +42 -0
  30. package/native/shared/src/anim_mixer.rs +61 -0
  31. package/native/shared/src/attach.rs +263 -0
  32. package/native/shared/src/audio/decode.rs +123 -0
  33. package/native/shared/src/audio/mod.rs +863 -0
  34. package/native/shared/src/audio/render.rs +892 -0
  35. package/native/shared/src/audio/spsc.rs +156 -0
  36. package/native/shared/src/audio/stream.rs +226 -0
  37. package/native/shared/src/custom_shaders.rs +104 -0
  38. package/native/shared/src/decals.rs +245 -0
  39. package/native/shared/src/drs.rs +211 -0
  40. package/native/shared/src/engine.rs +261 -0
  41. package/native/shared/src/ffi.rs +116 -0
  42. package/native/shared/src/ffi_core/assets.rs +388 -0
  43. package/native/shared/src/ffi_core/audio_ffi.rs +184 -0
  44. package/native/shared/src/ffi_core/draw.rs +334 -0
  45. package/native/shared/src/ffi_core/game_loop.rs +577 -0
  46. package/native/shared/src/ffi_core/input.rs +234 -0
  47. package/native/shared/src/ffi_core/mod.rs +127 -0
  48. package/native/shared/src/ffi_core/models.rs +1154 -0
  49. package/native/shared/src/ffi_core/ragdoll_ffi.rs +261 -0
  50. package/native/shared/src/ffi_core/scene.rs +626 -0
  51. package/native/shared/src/ffi_core/vfx.rs +212 -0
  52. package/native/shared/src/ffi_core/visual.rs +691 -0
  53. package/native/shared/src/frame_callbacks.rs +122 -0
  54. package/native/shared/src/geometry.rs +236 -0
  55. package/native/shared/src/handles.rs +182 -0
  56. package/native/shared/src/input.rs +448 -0
  57. package/native/shared/src/jolt_sys.rs +822 -0
  58. package/native/shared/src/lib.rs +55 -0
  59. package/native/shared/src/models.rs +1093 -0
  60. package/native/shared/src/models_gltf.rs +1280 -0
  61. package/native/shared/src/particles.rs +391 -0
  62. package/native/shared/src/physics_jolt.rs +1908 -0
  63. package/native/shared/src/picking.rs +298 -0
  64. package/native/shared/src/postfx.rs +345 -0
  65. package/native/shared/src/profiler.rs +492 -0
  66. package/native/shared/src/ragdoll.rs +474 -0
  67. package/native/shared/src/renderer/atmosphere_lut.rs +573 -0
  68. package/native/shared/src/renderer/brdf_lut.rs +154 -0
  69. package/native/shared/src/renderer/draw2d.rs +143 -0
  70. package/native/shared/src/renderer/formats.rs +822 -0
  71. package/native/shared/src/renderer/froxel.rs +421 -0
  72. package/native/shared/src/renderer/gi_bake.rs +653 -0
  73. package/native/shared/src/renderer/graph.rs +462 -0
  74. package/native/shared/src/renderer/hiz.rs +269 -0
  75. package/native/shared/src/renderer/hot_reload.rs +390 -0
  76. package/native/shared/src/renderer/impulse_field.rs +456 -0
  77. package/native/shared/src/renderer/lighting.rs +154 -0
  78. package/native/shared/src/renderer/material_instancing.rs +171 -0
  79. package/native/shared/src/renderer/material_pipeline.rs +700 -0
  80. package/native/shared/src/renderer/material_system.rs +1996 -0
  81. package/native/shared/src/renderer/material_system_tests.rs +601 -0
  82. package/native/shared/src/renderer/material_system_wasm.rs +41 -0
  83. package/native/shared/src/renderer/mod.rs +12556 -0
  84. package/native/shared/src/renderer/model_draw.rs +641 -0
  85. package/native/shared/src/renderer/occlusion.rs +429 -0
  86. package/native/shared/src/renderer/planar_pass.rs +593 -0
  87. package/native/shared/src/renderer/planar_reflection.rs +499 -0
  88. package/native/shared/src/renderer/post_pass.rs +249 -0
  89. package/native/shared/src/renderer/postfx_chain.rs +728 -0
  90. package/native/shared/src/renderer/pt_pass.rs +577 -0
  91. package/native/shared/src/renderer/scene_pass.rs +607 -0
  92. package/native/shared/src/renderer/shader_include.rs +205 -0
  93. package/native/shared/src/renderer/shader_library.rs +135 -0
  94. package/native/shared/src/renderer/shaders/ao.rs +570 -0
  95. package/native/shared/src/renderer/shaders/core.rs +1243 -0
  96. package/native/shared/src/renderer/shaders/env.rs +907 -0
  97. package/native/shared/src/renderer/shaders/gi.rs +810 -0
  98. package/native/shared/src/renderer/shaders/mod.rs +19 -0
  99. package/native/shared/src/renderer/shaders/post.rs +1558 -0
  100. package/native/shared/src/renderer/shaders/pt.rs +1859 -0
  101. package/native/shared/src/renderer/shaders/ssgi.rs +1586 -0
  102. package/native/shared/src/renderer/shadow_pass.rs +731 -0
  103. package/native/shared/src/renderer/ssgi_pass.rs +392 -0
  104. package/native/shared/src/renderer/ssr_pass.rs +188 -0
  105. package/native/shared/src/renderer/texture_store.rs +473 -0
  106. package/native/shared/src/renderer/transient.rs +591 -0
  107. package/native/shared/src/renderer/types.rs +941 -0
  108. package/native/shared/src/renderer/util.rs +152 -0
  109. package/native/shared/src/scene.rs +1362 -0
  110. package/native/shared/src/sdf_cache.rs +274 -0
  111. package/native/shared/src/shadows.rs +1036 -0
  112. package/native/shared/src/staging.rs +102 -0
  113. package/native/shared/src/string_header.rs +266 -0
  114. package/native/shared/src/text_renderer.rs +502 -0
  115. package/native/shared/src/textures.rs +197 -0
  116. package/native/tvos/Cargo.lock +1693 -0
  117. package/native/tvos/Cargo.toml +36 -0
  118. package/native/tvos/metal-patched/Cargo.toml +178 -0
  119. package/native/tvos/metal-patched/LICENSE-APACHE +201 -0
  120. package/native/tvos/metal-patched/LICENSE-MIT +25 -0
  121. package/native/tvos/metal-patched/src/acceleration_structure.rs +667 -0
  122. package/native/tvos/metal-patched/src/acceleration_structure_pass.rs +108 -0
  123. package/native/tvos/metal-patched/src/argument.rs +366 -0
  124. package/native/tvos/metal-patched/src/blitpass.rs +102 -0
  125. package/native/tvos/metal-patched/src/buffer.rs +71 -0
  126. package/native/tvos/metal-patched/src/capturedescriptor.rs +76 -0
  127. package/native/tvos/metal-patched/src/capturemanager.rs +113 -0
  128. package/native/tvos/metal-patched/src/commandbuffer.rs +192 -0
  129. package/native/tvos/metal-patched/src/commandqueue.rs +44 -0
  130. package/native/tvos/metal-patched/src/computepass.rs +107 -0
  131. package/native/tvos/metal-patched/src/constants.rs +152 -0
  132. package/native/tvos/metal-patched/src/counters.rs +119 -0
  133. package/native/tvos/metal-patched/src/depthstencil.rs +190 -0
  134. package/native/tvos/metal-patched/src/device.rs +2134 -0
  135. package/native/tvos/metal-patched/src/drawable.rs +39 -0
  136. package/native/tvos/metal-patched/src/encoder.rs +2041 -0
  137. package/native/tvos/metal-patched/src/heap.rs +281 -0
  138. package/native/tvos/metal-patched/src/indirect_encoder.rs +344 -0
  139. package/native/tvos/metal-patched/src/lib.rs +657 -0
  140. package/native/tvos/metal-patched/src/library.rs +902 -0
  141. package/native/tvos/metal-patched/src/mps.rs +575 -0
  142. package/native/tvos/metal-patched/src/pipeline/compute.rs +475 -0
  143. package/native/tvos/metal-patched/src/pipeline/mod.rs +71 -0
  144. package/native/tvos/metal-patched/src/pipeline/render.rs +762 -0
  145. package/native/tvos/metal-patched/src/renderpass.rs +443 -0
  146. package/native/tvos/metal-patched/src/resource.rs +182 -0
  147. package/native/tvos/metal-patched/src/sampler.rs +165 -0
  148. package/native/tvos/metal-patched/src/sync.rs +178 -0
  149. package/native/tvos/metal-patched/src/texture.rs +352 -0
  150. package/native/tvos/metal-patched/src/types.rs +90 -0
  151. package/native/tvos/metal-patched/src/vertexdescriptor.rs +250 -0
  152. package/native/tvos/src/audio_backend.rs +197 -0
  153. package/native/tvos/src/lib.rs +1891 -0
  154. package/native/visionos/Cargo.lock +1693 -0
  155. package/native/visionos/Cargo.toml +40 -0
  156. package/native/visionos/src/audio_backend.rs +197 -0
  157. package/native/visionos/src/lib.rs +1887 -0
  158. package/native/watchos/Cargo.lock +16 -0
  159. package/native/watchos/Cargo.toml +19 -0
  160. package/native/watchos/shaders/bloom_postfx.metal +99 -0
  161. package/native/watchos/src/BloomWatchApp.swift +1267 -0
  162. package/native/watchos/src/BloomWatchAudio.swift +179 -0
  163. package/native/watchos/src/audio.rs +55 -0
  164. package/native/watchos/src/draw_list.rs +229 -0
  165. package/native/watchos/src/ffi_stubs.rs +915 -0
  166. package/native/watchos/src/ffi_stubs_manual.rs +35 -0
  167. package/native/watchos/src/lib.rs +1124 -0
  168. package/native/watchos/src/models.rs +746 -0
  169. package/native/watchos/src/postfx.rs +95 -0
  170. package/native/watchos/src/scene.rs +534 -0
  171. package/native/watchos/src/textures.rs +184 -0
  172. package/native/web/Cargo.lock +1657 -0
  173. package/native/web/Cargo.toml +43 -0
  174. package/native/web/bloom_glue.js +695 -0
  175. package/native/web/build.sh +131 -0
  176. package/native/web/index.html +35 -0
  177. package/native/web/jolt_bridge.js +1519 -0
  178. package/native/web/src/input_ffi.rs +286 -0
  179. package/native/web/src/lib.rs +1796 -0
  180. package/native/web/src/material_ffi.rs +710 -0
  181. package/native/web/src/parity_ffi.rs +343 -0
  182. package/native/web/src/physics_ffi.rs +643 -0
  183. package/native/web/src/ragdoll_ffi.rs +250 -0
  184. package/native/web/src/render_settings.rs +98 -0
  185. package/native/windows/Cargo.lock +1815 -0
  186. package/native/windows/Cargo.toml +68 -0
  187. package/native/windows/src/lib.rs +1486 -0
  188. package/package.json +4279 -0
  189. package/src/audio/index.ts +315 -0
  190. package/src/core/colors.ts +63 -0
  191. package/src/core/index.ts +1206 -0
  192. package/src/core/keys.ts +63 -0
  193. package/src/core/types.ts +104 -0
  194. package/src/index.ts +171 -0
  195. package/src/math/index.ts +516 -0
  196. package/src/mobile/index.ts +294 -0
  197. package/src/models/index.ts +1258 -0
  198. package/src/physics/index.ts +1134 -0
  199. package/src/scene/index.ts +698 -0
  200. package/src/shapes/index.ts +120 -0
  201. package/src/text/index.ts +48 -0
  202. package/src/textures/index.ts +187 -0
  203. package/src/vfx/index.ts +191 -0
  204. package/src/world/index.ts +24 -0
  205. package/src/world/loader.ts +423 -0
  206. package/src/world/prefab.ts +217 -0
  207. package/src/world/render.ts +172 -0
  208. package/src/world/saver.ts +108 -0
  209. package/src/world/serialize.ts +301 -0
  210. package/src/world/terrain.ts +355 -0
  211. package/src/world/types.ts +160 -0
  212. package/src/world/validate.ts +319 -0
  213. package/src/world/version.ts +114 -0
@@ -0,0 +1,234 @@
1
+ //! Keyboard, mouse, touch, and gamepad state (single-pad InputState model).
2
+ //!
3
+ //! Section of [`define_core_ffi!`](crate::define_core_ffi) — see
4
+ //! `ffi_core/mod.rs` for the architecture and the invoking-crate contract.
5
+ //! Internal: platform crates must invoke `define_core_ffi!()`, never the
6
+ //! section macros directly.
7
+
8
+ #[doc(hidden)]
9
+ #[macro_export]
10
+ macro_rules! __bloom_ffi_input {
11
+ () => {
12
+
13
+ // bloom_is_key_pressed [source: macos]
14
+ #[no_mangle]
15
+ pub extern "C" fn bloom_is_key_pressed(key: f64) -> f64 {
16
+ $crate::ffi::guard("bloom_is_key_pressed", move || {
17
+ if engine().input.is_key_pressed(key as usize) { 1.0 } else { 0.0 }
18
+ })
19
+ }
20
+
21
+ // bloom_is_key_down [source: macos]
22
+ #[no_mangle]
23
+ pub extern "C" fn bloom_is_key_down(key: f64) -> f64 {
24
+ $crate::ffi::guard("bloom_is_key_down", move || {
25
+ if engine().input.is_key_down(key as usize) { 1.0 } else { 0.0 }
26
+ })
27
+ }
28
+
29
+ // bloom_is_key_released [source: macos]
30
+ #[no_mangle]
31
+ pub extern "C" fn bloom_is_key_released(key: f64) -> f64 {
32
+ $crate::ffi::guard("bloom_is_key_released", move || {
33
+ if engine().input.is_key_released(key as usize) { 1.0 } else { 0.0 }
34
+ })
35
+ }
36
+
37
+ // bloom_is_key_repeated — OS auto-repeat as its own edge. isKeyPressed
38
+ // stays initial-press-only (a held jump key must not machine-gun);
39
+ // caret navigation in text fields is the consumer.
40
+ #[no_mangle]
41
+ pub extern "C" fn bloom_is_key_repeated(key: f64) -> f64 {
42
+ $crate::ffi::guard("bloom_is_key_repeated", move || {
43
+ if engine().input.is_key_repeated(key as usize) { 1.0 } else { 0.0 }
44
+ })
45
+ }
46
+
47
+ // bloom_get_mouse_x [source: macos]
48
+ #[no_mangle]
49
+ pub extern "C" fn bloom_get_mouse_x() -> f64 {
50
+ $crate::ffi::guard("bloom_get_mouse_x", move || {
51
+ engine().input.mouse_x
52
+ })
53
+ }
54
+
55
+ // bloom_get_mouse_y [source: macos]
56
+ #[no_mangle]
57
+ pub extern "C" fn bloom_get_mouse_y() -> f64 {
58
+ $crate::ffi::guard("bloom_get_mouse_y", move || {
59
+ engine().input.mouse_y
60
+ })
61
+ }
62
+
63
+ // bloom_is_mouse_button_pressed [source: macos]
64
+ #[no_mangle]
65
+ pub extern "C" fn bloom_is_mouse_button_pressed(btn: f64) -> f64 {
66
+ $crate::ffi::guard("bloom_is_mouse_button_pressed", move || {
67
+ if engine().input.is_mouse_button_pressed(btn as usize) { 1.0 } else { 0.0 }
68
+ })
69
+ }
70
+
71
+ // bloom_is_mouse_button_down [source: macos]
72
+ #[no_mangle]
73
+ pub extern "C" fn bloom_is_mouse_button_down(btn: f64) -> f64 {
74
+ $crate::ffi::guard("bloom_is_mouse_button_down", move || {
75
+ if engine().input.is_mouse_button_down(btn as usize) { 1.0 } else { 0.0 }
76
+ })
77
+ }
78
+
79
+ // bloom_is_mouse_button_released [source: macos]
80
+ #[no_mangle]
81
+ pub extern "C" fn bloom_is_mouse_button_released(btn: f64) -> f64 {
82
+ $crate::ffi::guard("bloom_is_mouse_button_released", move || {
83
+ if engine().input.is_mouse_button_released(btn as usize) { 1.0 } else { 0.0 }
84
+ })
85
+ }
86
+
87
+ // bloom_get_crown_rotation [source: macos]
88
+ #[no_mangle]
89
+ pub extern "C" fn bloom_get_crown_rotation() -> f64 {
90
+ $crate::ffi::guard("bloom_get_crown_rotation", move || {
91
+ engine().input.consume_crown_rotation()
92
+ })
93
+ }
94
+
95
+ // bloom_is_gamepad_available [source: macos]
96
+ #[no_mangle]
97
+ pub extern "C" fn bloom_is_gamepad_available() -> f64 {
98
+ $crate::ffi::guard("bloom_is_gamepad_available", move || {
99
+ if engine().input.is_gamepad_available() { 1.0 } else { 0.0 }
100
+ })
101
+ }
102
+
103
+ // bloom_get_gamepad_axis [source: macos]
104
+ #[no_mangle]
105
+ pub extern "C" fn bloom_get_gamepad_axis(axis: f64) -> f64 {
106
+ $crate::ffi::guard("bloom_get_gamepad_axis", move || {
107
+ engine().input.get_gamepad_axis(axis as usize) as f64
108
+ })
109
+ }
110
+
111
+ // bloom_gamepad_rumble [EN-031]
112
+ // low/high motor 0..1, duration in seconds. The platform's input poll
113
+ // consumes this and drives its own vibration API; on platforms with no
114
+ // vibration it is simply ignored (the state is written, nobody reads
115
+ // it) — which is why the symbol exists everywhere and the behaviour
116
+ // does not have to.
117
+ #[no_mangle]
118
+ pub extern "C" fn bloom_gamepad_rumble(low: f64, high: f64, seconds: f64) {
119
+ $crate::ffi::guard("bloom_gamepad_rumble", move || {
120
+ let inp = &mut engine().input;
121
+ inp.rumble = [
122
+ (low as f32).clamp(0.0, 1.0),
123
+ (high as f32).clamp(0.0, 1.0),
124
+ (seconds as f32).clamp(0.0, 10.0),
125
+ ];
126
+ })
127
+ }
128
+
129
+ // bloom_is_gamepad_button_pressed [source: macos]
130
+ #[no_mangle]
131
+ pub extern "C" fn bloom_is_gamepad_button_pressed(btn: f64) -> f64 {
132
+ $crate::ffi::guard("bloom_is_gamepad_button_pressed", move || {
133
+ if engine().input.is_gamepad_button_pressed(btn as usize) { 1.0 } else { 0.0 }
134
+ })
135
+ }
136
+
137
+ // bloom_is_gamepad_button_down [source: macos]
138
+ #[no_mangle]
139
+ pub extern "C" fn bloom_is_gamepad_button_down(btn: f64) -> f64 {
140
+ $crate::ffi::guard("bloom_is_gamepad_button_down", move || {
141
+ if engine().input.is_gamepad_button_down(btn as usize) { 1.0 } else { 0.0 }
142
+ })
143
+ }
144
+
145
+ // bloom_is_gamepad_button_released [source: macos]
146
+ #[no_mangle]
147
+ pub extern "C" fn bloom_is_gamepad_button_released(btn: f64) -> f64 {
148
+ $crate::ffi::guard("bloom_is_gamepad_button_released", move || {
149
+ if engine().input.is_gamepad_button_released(btn as usize) { 1.0 } else { 0.0 }
150
+ })
151
+ }
152
+
153
+ // bloom_get_gamepad_axis_count [source: macos]
154
+ #[no_mangle]
155
+ pub extern "C" fn bloom_get_gamepad_axis_count() -> f64 {
156
+ $crate::ffi::guard("bloom_get_gamepad_axis_count", move || {
157
+ engine().input.get_gamepad_axis_count() as f64
158
+ })
159
+ }
160
+
161
+ // bloom_get_mouse_delta_x [source: macos]
162
+ #[no_mangle]
163
+ pub extern "C" fn bloom_get_mouse_delta_x() -> f64 {
164
+ $crate::ffi::guard("bloom_get_mouse_delta_x", move || {
165
+ engine().input.mouse_delta_x
166
+ })
167
+ }
168
+
169
+ // bloom_get_mouse_delta_y [source: macos]
170
+ #[no_mangle]
171
+ pub extern "C" fn bloom_get_mouse_delta_y() -> f64 {
172
+ $crate::ffi::guard("bloom_get_mouse_delta_y", move || {
173
+ engine().input.mouse_delta_y
174
+ })
175
+ }
176
+
177
+ // bloom_get_mouse_wheel [source: macos]
178
+ #[no_mangle]
179
+ pub extern "C" fn bloom_get_mouse_wheel() -> f64 {
180
+ $crate::ffi::guard("bloom_get_mouse_wheel", move || {
181
+ engine().input.consume_mouse_wheel()
182
+ })
183
+ }
184
+
185
+ // bloom_get_char_pressed [source: macos]
186
+ #[no_mangle]
187
+ pub extern "C" fn bloom_get_char_pressed() -> f64 {
188
+ $crate::ffi::guard("bloom_get_char_pressed", move || {
189
+ engine().input.pop_char() as f64
190
+ })
191
+ }
192
+
193
+ // bloom_get_touch_x [source: macos]
194
+ #[no_mangle]
195
+ pub extern "C" fn bloom_get_touch_x(index: f64) -> f64 {
196
+ $crate::ffi::guard("bloom_get_touch_x", move || {
197
+ engine().input.get_touch_x(index as usize)
198
+ })
199
+ }
200
+
201
+ // bloom_get_touch_y [source: macos]
202
+ #[no_mangle]
203
+ pub extern "C" fn bloom_get_touch_y(index: f64) -> f64 {
204
+ $crate::ffi::guard("bloom_get_touch_y", move || {
205
+ engine().input.get_touch_y(index as usize)
206
+ })
207
+ }
208
+
209
+ // bloom_get_touch_count [source: macos]
210
+ #[no_mangle]
211
+ pub extern "C" fn bloom_get_touch_count() -> f64 {
212
+ $crate::ffi::guard("bloom_get_touch_count", move || {
213
+ engine().input.get_touch_count() as f64
214
+ })
215
+ }
216
+
217
+ // bloom_is_touch_active [source: macos]
218
+ #[no_mangle]
219
+ pub extern "C" fn bloom_is_touch_active(index: f64) -> f64 {
220
+ $crate::ffi::guard("bloom_is_touch_active", move || {
221
+ if engine().input.is_touch_active(index as usize) { 1.0 } else { 0.0 }
222
+ })
223
+ }
224
+
225
+ // bloom_get_max_touch_points [source: macos]
226
+ #[no_mangle]
227
+ pub extern "C" fn bloom_get_max_touch_points() -> f64 {
228
+ $crate::ffi::guard("bloom_get_max_touch_points", move || {
229
+ engine().input.max_touch_points() as f64
230
+ })
231
+ }
232
+
233
+ };
234
+ }
@@ -0,0 +1,127 @@
1
+ //! `define_core_ffi!` — the shared, non-physics `bloom_*` FFI surface.
2
+ //!
3
+ //! # Why this exists
4
+ //!
5
+ //! Every platform crate must export the full FFI surface declared in
6
+ //! `package.json` (`perry.nativeLibrary.functions`); a missing symbol is a
7
+ //! link error or dlopen crash in shipped games. Before this macro the ~250
8
+ //! non-physics functions were hand-copied into six platform crates
9
+ //! (~9,000 duplicated lines) and drifted constantly:
10
+ //!
11
+ //! - Android shipped 60 functions behind (dlopen crash, PR #59), then
12
+ //! "fixed" part of the gap with silent no-op stubs.
13
+ //! - Windows stubbed the entire scene-graph / lighting / picking /
14
+ //! post-FX surface with silent no-ops.
15
+ //! - iOS/tvOS declared gamepad functions with an extra leading
16
+ //! `gamepad` parameter the manifest doesn't have, so every axis and
17
+ //! button read was off by one argument register.
18
+ //! - `bloom_create_mesh` / `bloom_gen_mesh_spline_ribbon` read `*const
19
+ //! f32` on some platforms; Perry passes arrays as pointers to inline
20
+ //! f64 data (see perry-codegen `lower_call/extern_func.rs`), so those
21
+ //! reads were garbage.
22
+ //!
23
+ //! One macro, expanded once per platform crate, makes per-platform drift
24
+ //! in this surface structurally impossible — the same fix the physics
25
+ //! surface got with `define_physics_ffi!`. `tools/validate-ffi.js`
26
+ //! cross-checks the macro, the platform crates, and package.json in CI.
27
+ //!
28
+ //! # Contract for the invoking crate
29
+ //!
30
+ //! The platform crate must define, before invoking the macro:
31
+ //!
32
+ //! ```ignore
33
+ //! /// Engine-state accessor. It must provide exclusive mutable access to the
34
+ //! /// state for the duration of each FFI operation. A platform can return a
35
+ //! /// direct mutable reference or a synchronization guard.
36
+ //! fn engine() -> impl std::ops::DerefMut<Target = bloom_shared::engine::EngineState> { ... }
37
+ //!
38
+ //! /// Asset-path resolver: identity on desktop; prepends the app asset
39
+ //! /// dir on Android/iOS/tvOS where relative paths don't resolve.
40
+ //! fn bloom_resolve_asset_path(path: &str) -> std::borrow::Cow<'_, str> { ... }
41
+ //!
42
+ //! bloom_shared::define_core_ffi!();
43
+ //! ```
44
+ //!
45
+ //! Functions NOT generated here (platform crates implement them by hand,
46
+ //! validated by tools/validate-ffi.js): window + event loop
47
+ //! (`bloom_init_window`, `bloom_begin/end_drawing`, ...), audio backend
48
+ //! init/teardown, fullscreen, cursor capture, clipboard, file dialogs,
49
+ //! window title/icon, `bloom_get_platform`, `bloom_get_language`.
50
+ //!
51
+ //! # Conventions inside the macro
52
+ //!
53
+ //! - Every body is wrapped in [`crate::ffi::guard`] — panics log once
54
+ //! and return a default instead of crossing the C boundary.
55
+ //! - `models3d` / `image-extras` gated functions compile to a
56
+ //! once-warning stub when the feature is off. Symbols never silently
57
+ //! vanish and never silently no-op.
58
+ //! - String params are Perry StringHeader pointers
59
+ //! (`crate::string_header`); array params are pointers to inline f64
60
+ //! data (the compiler skips the 8-byte ArrayHeader at the callsite).
61
+
62
+ mod game_loop;
63
+ mod input;
64
+ mod draw;
65
+ mod assets;
66
+ mod audio_ffi;
67
+ mod models;
68
+ mod scene;
69
+ mod visual;
70
+ mod vfx;
71
+ mod ragdoll_ffi;
72
+
73
+ /// Expand the full shared (non-physics) FFI surface. Composed from the
74
+ /// per-subsystem section macros in this directory; platform crates invoke
75
+ /// only this. Nested `$crate::__bloom_ffi_*` invocations expand at THIS
76
+ /// macro's call site, so the `engine()` / `bloom_resolve_asset_path()`
77
+ /// hooks still resolve in the invoking crate.
78
+ #[macro_export]
79
+ macro_rules! define_core_ffi {
80
+ () => {
81
+ $crate::__bloom_ffi_game_loop!();
82
+ $crate::__bloom_ffi_input!();
83
+ $crate::__bloom_ffi_draw!();
84
+ $crate::__bloom_ffi_assets!();
85
+ $crate::__bloom_ffi_audio_ffi!();
86
+ $crate::__bloom_ffi_models!();
87
+ $crate::__bloom_ffi_scene!();
88
+ $crate::__bloom_ffi_visual!();
89
+ $crate::__bloom_ffi_vfx!();
90
+ $crate::__bloom_ffi_ragdoll!();
91
+ };
92
+ }
93
+
94
+
95
+ // Compile-coverage for the macro body: expand it against mock hooks so
96
+ // `cargo test -p bloom-shared` catches breakage without building any
97
+ // platform crate. Nothing here runs — the hooks panic if called.
98
+ #[cfg(all(test, not(target_arch = "wasm32")))]
99
+ mod macro_expansion_compile_check {
100
+ #![allow(dead_code, unused_variables)]
101
+
102
+ struct EngineGuard(&'static mut crate::engine::EngineState);
103
+
104
+ impl std::ops::Deref for EngineGuard {
105
+ type Target = crate::engine::EngineState;
106
+
107
+ fn deref(&self) -> &Self::Target {
108
+ self.0
109
+ }
110
+ }
111
+
112
+ impl std::ops::DerefMut for EngineGuard {
113
+ fn deref_mut(&mut self) -> &mut Self::Target {
114
+ self.0
115
+ }
116
+ }
117
+
118
+ fn engine() -> EngineGuard {
119
+ unreachable!("compile-coverage mock — never called")
120
+ }
121
+
122
+ fn bloom_resolve_asset_path(path: &str) -> std::borrow::Cow<'_, str> {
123
+ std::borrow::Cow::Borrowed(path)
124
+ }
125
+
126
+ crate::define_core_ffi!();
127
+ }