@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,315 @@
1
+ import { spawn, parallelMap } from 'perry/thread';
2
+ import { Sound, Music } from '../core/types';
3
+
4
+ // FFI declarations
5
+ declare function bloom_init_audio(): void;
6
+ declare function bloom_close_audio(): void;
7
+ declare function bloom_load_sound(path: number): number;
8
+ declare function bloom_play_sound(handle: number): void;
9
+ declare function bloom_stop_sound(handle: number): void;
10
+ declare function bloom_set_sound_volume(handle: number, volume: number): void;
11
+ declare function bloom_set_master_volume(volume: number): void;
12
+ declare function bloom_load_music(path: number): number;
13
+ declare function bloom_play_music(handle: number): void;
14
+ declare function bloom_stop_music(handle: number): void;
15
+ declare function bloom_update_music_stream(handle: number): void;
16
+ declare function bloom_set_music_volume(handle: number, volume: number): void;
17
+ declare function bloom_is_music_playing(handle: number): number;
18
+ declare function bloom_play_sound_3d(handle: number, x: number, y: number, z: number): void;
19
+ declare function bloom_set_listener_position(x: number, y: number, z: number, fx: number, fy: number, fz: number): void;
20
+
21
+ export function initAudio(): void {
22
+ bloom_init_audio();
23
+ }
24
+
25
+ export function closeAudio(): void {
26
+ bloom_close_audio();
27
+ }
28
+
29
+ // Spec-compliant aliases
30
+ export function initAudioDevice(): void { bloom_init_audio(); }
31
+ export function closeAudioDevice(): void { bloom_close_audio(); }
32
+
33
+ export function loadSound(path: string): Sound {
34
+ const handle = bloom_load_sound(path as any);
35
+ return { handle };
36
+ }
37
+
38
+ export function playSound(sound: Sound): void {
39
+ bloom_play_sound(sound.handle);
40
+ }
41
+
42
+ export function stopSound(sound: Sound): void {
43
+ bloom_stop_sound(sound.handle);
44
+ }
45
+
46
+ export function setSoundVolume(sound: Sound, volume: number): void {
47
+ bloom_set_sound_volume(sound.handle, volume);
48
+ }
49
+
50
+ export function setMasterVolume(volume: number): void {
51
+ bloom_set_master_volume(volume);
52
+ }
53
+
54
+ // Music functions
55
+
56
+ export function loadMusic(path: string): Music {
57
+ const handle = bloom_load_music(path as any);
58
+ return { handle };
59
+ }
60
+
61
+ /// Returns the raw numeric handle. Prefer this on Android (aarch64): Perry 0.5.x
62
+ /// miscompiles `music.handle` field reads that feed straight into an f64 FFI slot,
63
+ /// producing NaN and dropping the music.
64
+ export function loadMusicRaw(path: string): number {
65
+ return bloom_load_music(path as any);
66
+ }
67
+
68
+ export function playMusic(music: Music): void {
69
+ bloom_play_music(music.handle);
70
+ }
71
+
72
+ /**
73
+ * @internal Compiler workaround — not part of the public API.
74
+ * Identical to the non-Raw version but takes primitives instead of
75
+ * reading object fields (aarch64 Android Perry miscompilation where
76
+ * obj.field reads feeding f64 FFI args arrive as NaN). Use the
77
+ * non-Raw version; these disappear when the Perry fix ships.
78
+ */
79
+ export function playMusicRaw(handle: number): void {
80
+ bloom_play_music(handle);
81
+ }
82
+
83
+ export function stopMusic(music: Music): void {
84
+ bloom_stop_music(music.handle);
85
+ }
86
+
87
+ /**
88
+ * @internal Compiler workaround — not part of the public API.
89
+ * Identical to the non-Raw version but takes primitives instead of
90
+ * reading object fields (aarch64 Android Perry miscompilation where
91
+ * obj.field reads feeding f64 FFI args arrive as NaN). Use the
92
+ * non-Raw version; these disappear when the Perry fix ships.
93
+ */
94
+ export function stopMusicRaw(handle: number): void {
95
+ bloom_stop_music(handle);
96
+ }
97
+
98
+ export function updateMusicStream(music: Music): void {
99
+ bloom_update_music_stream(music.handle);
100
+ }
101
+
102
+ /**
103
+ * @internal Compiler workaround — not part of the public API.
104
+ * Identical to the non-Raw version but takes primitives instead of
105
+ * reading object fields (aarch64 Android Perry miscompilation where
106
+ * obj.field reads feeding f64 FFI args arrive as NaN). Use the
107
+ * non-Raw version; these disappear when the Perry fix ships.
108
+ */
109
+ export function updateMusicStreamRaw(handle: number): void {
110
+ bloom_update_music_stream(handle);
111
+ }
112
+
113
+ // Spec-compliant alias
114
+ export function updateMusic(music: Music): void { bloom_update_music_stream(music.handle); }
115
+
116
+ export function setMusicVolume(music: Music, volume: number): void {
117
+ bloom_set_music_volume(music.handle, volume);
118
+ }
119
+
120
+ /**
121
+ * @internal Compiler workaround — not part of the public API.
122
+ * Identical to the non-Raw version but takes primitives instead of
123
+ * reading object fields (aarch64 Android Perry miscompilation where
124
+ * obj.field reads feeding f64 FFI args arrive as NaN). Use the
125
+ * non-Raw version; these disappear when the Perry fix ships.
126
+ */
127
+ export function setMusicVolumeRaw(handle: number, volume: number): void {
128
+ bloom_set_music_volume(handle, volume);
129
+ }
130
+
131
+ export function isMusicPlaying(music: Music): boolean {
132
+ return bloom_is_music_playing(music.handle) !== 0;
133
+ }
134
+
135
+ /**
136
+ * @internal Compiler workaround — not part of the public API.
137
+ * Identical to the non-Raw version but takes primitives instead of
138
+ * reading object fields (aarch64 Android Perry miscompilation where
139
+ * obj.field reads feeding f64 FFI args arrive as NaN). Use the
140
+ * non-Raw version; these disappear when the Perry fix ships.
141
+ */
142
+ export function isMusicPlayingRaw(handle: number): boolean {
143
+ return bloom_is_music_playing(handle) !== 0;
144
+ }
145
+
146
+ // Spatial audio
147
+
148
+ export function playSound3D(sound: Sound, x: number, y: number, z: number): void {
149
+ bloom_play_sound_3d(sound.handle, x, y, z);
150
+ }
151
+
152
+ export function setListenerPosition(x: number, y: number, z: number, forwardX: number, forwardY: number, forwardZ: number): void {
153
+ bloom_set_listener_position(x, y, z, forwardX, forwardY, forwardZ);
154
+ }
155
+
156
+ // ---- EN-062: live spatial voices --------------------------------------------
157
+ //
158
+ // playSound3D is fire-and-forget — it cannot loop and it cannot move. These
159
+ // calls are the *emitter* API: play returns a voice id you hold onto and
160
+ // steer per frame. A river you walk along, wind in a treeline, a creature
161
+ // skittering closer — each is one looping voice plus a position/volume ride.
162
+ //
163
+ // What the mixer does with a spatial voice (all of it engine-side, free to
164
+ // the game): equal-power panning, inverse-distance attenuation shaped by
165
+ // refDist/rolloff, distance air-absorption, a rear-hemisphere head-shadow
166
+ // cue, and doppler derived from the motion you feed voiceSetPosition.
167
+
168
+ declare function bloom_play_sound_3d_ex(handle: number, x: number, y: number, z: number,
169
+ looping: number, refDist: number, maxDist: number, rolloff: number): number;
170
+ declare function bloom_voice_set_position(voice: number, x: number, y: number, z: number): void;
171
+ declare function bloom_voice_stop(voice: number): void;
172
+ declare function bloom_voice_set_volume(voice: number, volume: number): void;
173
+ declare function bloom_voice_set_pitch(voice: number, pitch: number): void;
174
+ declare function bloom_voice_set_lowpass(voice: number, cutoffHz: number): void;
175
+
176
+ /// Play a sound as a controllable 3D voice; returns its voice id (0 = the
177
+ /// sound was not loaded — every voice* call ignores id 0, so the null-object
178
+ /// pattern costs nothing at the call site).
179
+ ///
180
+ /// `refDist` — range that plays at full volume. `rolloff` — how hard the
181
+ /// level falls past it (1 = physical inverse law; < 1 gentler, audible
182
+ /// farther). `maxDist` — the mixer culls past this (0 = never); a culled
183
+ /// looping voice keeps its playback head moving and comes back mid-phrase,
184
+ /// not from the top. refDist=1, rolloff=1 is exactly playSound3D's curve.
185
+ export function playSound3DEx(sound: Sound, x: number, y: number, z: number,
186
+ looping: boolean, refDist: number, maxDist: number, rolloff: number): number {
187
+ return bloom_play_sound_3d_ex(sound.handle, x, y, z, looping ? 1 : 0, refDist, maxDist, rolloff);
188
+ }
189
+
190
+ /// Move a live voice. Feed it real motion — doppler is derived from how the
191
+ /// emitter-to-listener distance changes, so a moving voice bends pitch the
192
+ /// way a moving thing should. (Teleporting a pool voice to a new owner is
193
+ /// fine too: impossible speeds are detected and skipped, not chirped.)
194
+ export function voiceSetPosition(voice: number, x: number, y: number, z: number): void {
195
+ if (voice !== 0) bloom_voice_set_position(voice, x, y, z);
196
+ }
197
+
198
+ /// Stop a voice click-free: it fades over one mix block (~10 ms) and drops.
199
+ export function voiceStop(voice: number): void {
200
+ if (voice !== 0) bloom_voice_stop(voice);
201
+ }
202
+
203
+ /// Per-voice volume (multiplies the sound's base volume and the bus). Ride it
204
+ /// per frame — gains are ramped inside the mixer, so it never zippers.
205
+ export function voiceSetVolume(voice: number, volume: number): void {
206
+ if (voice !== 0) bloom_voice_set_volume(voice, volume);
207
+ }
208
+
209
+ /// Playback-rate multiplier, clamped 0.25..4. Detune copies of one asset
210
+ /// (three wind emitters at 0.94/1.0/1.07 stop sounding like one file) or
211
+ /// size a creature (small = up, big = down).
212
+ export function voiceSetPitch(voice: number, pitch: number): void {
213
+ if (voice !== 0) bloom_voice_set_pitch(voice, pitch);
214
+ }
215
+
216
+ /// Per-VOICE occlusion low-pass (Hz; 0 = bypass). Unlike setSoundLowpass this
217
+ /// muffles ONE emitter, not every voice sharing the asset.
218
+ export function voiceSetLowpass(voice: number, cutoffHz: number): void {
219
+ if (voice !== 0) bloom_voice_set_lowpass(voice, cutoffHz);
220
+ }
221
+
222
+ // Async / threaded loading
223
+
224
+ declare function bloom_stage_sound(path: number): number;
225
+ declare function bloom_commit_sound(handle: number): number;
226
+ declare function bloom_commit_music(handle: number): number;
227
+
228
+ export async function loadSoundAsync(path: string): Promise<Sound> {
229
+ const stagingHandle = await spawn(() => bloom_stage_sound(path as any));
230
+ const handle = bloom_commit_sound(stagingHandle);
231
+ return { handle };
232
+ }
233
+
234
+ export async function loadMusicAsync(path: string): Promise<Music> {
235
+ const stagingHandle = await spawn(() => bloom_stage_sound(path as any));
236
+ const handle = bloom_commit_music(stagingHandle);
237
+ return { handle };
238
+ }
239
+
240
+ export function stageSounds(paths: string[]): number[] {
241
+ return parallelMap(paths, (path: string) => bloom_stage_sound(path as any));
242
+ }
243
+
244
+ export function commitSound(stagingHandle: number): Sound {
245
+ const handle = bloom_commit_sound(stagingHandle);
246
+ return { handle };
247
+ }
248
+
249
+ export function commitMusic(stagingHandle: number): Music {
250
+ const handle = bloom_commit_music(stagingHandle);
251
+ return { handle };
252
+ }
253
+
254
+ // ---- EN-029: mix buses, reverb send, occlusion low-pass ---------------------
255
+ //
256
+ // The mixer used to be master gain + per-voice gain. That plays sounds; it
257
+ // does not make a space sound like a place. Three additions cover the moves a
258
+ // shooter actually needs:
259
+ //
260
+ // - a bus you can duck ("drop the music when the player is hit")
261
+ // - a tail you can send to ("this gunshot is indoors")
262
+ // - a filter per source ("that shriek is behind the building")
263
+ //
264
+ // Routing is per *sound*, set once at load — a footstep is always SFX, a menu
265
+ // blip is always UI — so the per-shot call sites stay unchanged.
266
+
267
+ declare function bloom_set_sound_bus(handle: number, bus: number): void;
268
+ declare function bloom_set_sound_reverb_send(handle: number, send: number): void;
269
+ declare function bloom_set_sound_lowpass(handle: number, cutoff: number): void;
270
+ declare function bloom_set_bus_gain(bus: number, gain: number): void;
271
+ declare function bloom_duck_bus(bus: number, amount: number, attack: number, release: number, hold: number): void;
272
+ declare function bloom_set_reverb(size: number, damp: number, wet: number): void;
273
+
274
+ export const BUS_SFX = 0;
275
+ export const BUS_MUSIC = 1;
276
+ export const BUS_UI = 2;
277
+
278
+ /// Route a sound to a mix bus. Music loaded via `loadMusic` is already on
279
+ /// BUS_MUSIC; this is for sound effects that belong somewhere other than SFX
280
+ /// (menu clicks → BUS_UI, so they never duck with the rest of the mix).
281
+ export function setSoundBus(sound: Sound, bus: number): void {
282
+ bloom_set_sound_bus(sound.handle, bus);
283
+ }
284
+
285
+ /// How much of this sound feeds the reverb, 0..1. This is what gives a weapon
286
+ /// its tail — and raising it near walls is what makes a fight "indoors".
287
+ export function setSoundReverbSend(sound: Sound, send: number): void {
288
+ bloom_set_sound_reverb_send(sound.handle, send);
289
+ }
290
+
291
+ /// Low-pass this sound at `cutoffHz` (0 = bypass). The occlusion primitive:
292
+ /// the game raycasts to the emitter and muffles what it can't see. Muffling
293
+ /// reads as geometry in a way that simply lowering the volume never does.
294
+ export function setSoundLowpass(sound: Sound, cutoffHz: number): void {
295
+ bloom_set_sound_lowpass(sound.handle, cutoffHz);
296
+ }
297
+
298
+ export function setBusGain(bus: number, gain: number): void {
299
+ bloom_set_bus_gain(bus, gain);
300
+ }
301
+
302
+ /// Momentarily pull a bus down — `amount` 0..1 — over `attack` seconds, hold
303
+ /// it for `hold`, then recover over `release`. Call it again to re-trigger;
304
+ /// the hold restarts, so repeated hits keep the music down.
305
+ export function duckBus(bus: number, amount: number, attack: number, release: number, hold: number): void {
306
+ bloom_duck_bus(bus, amount, attack, release, hold);
307
+ }
308
+
309
+ /// Global reverb: `size` 0..1 (tail length), `damp` 0..1 (HF absorption),
310
+ /// `wet` 0..1 (how much returns to the mix). wet = 0 bypasses the entire
311
+ /// reverb path, so it is free until you ask for it — ramp it up as the player
312
+ /// moves indoors.
313
+ export function setReverb(size: number, damp: number, wet: number): void {
314
+ bloom_set_reverb(size, damp, wet);
315
+ }
@@ -0,0 +1,63 @@
1
+ import { Color as ColorType } from './types';
2
+
3
+ // Canonical color palette. Re-exported as `Color` from `bloom/core` and
4
+ // declared as a real top-level binding (not an alias re-export) so Perry
5
+ // emits a `_perry_fn_src_core_colors_ts__Color` symbol that examples
6
+ // importing `Color` from `bloom/core` can link against.
7
+ export const Color: Record<string, ColorType> = {
8
+ Snow: { r: 245, g: 245, b: 245, a: 255 },
9
+ White: { r: 255, g: 255, b: 255, a: 255 },
10
+ Black: { r: 0, g: 0, b: 0, a: 255 },
11
+ Red: { r: 230, g: 41, b: 55, a: 255 },
12
+ Green: { r: 0, g: 228, b: 48, a: 255 },
13
+ Blue: { r: 0, g: 121, b: 241, a: 255 },
14
+ Yellow: { r: 253, g: 249, b: 0, a: 255 },
15
+ Orange: { r: 255, g: 161, b: 0, a: 255 },
16
+ Pink: { r: 255, g: 109, b: 194, a: 255 },
17
+ Purple: { r: 200, g: 122, b: 255, a: 255 },
18
+ DarkGray: { r: 80, g: 80, b: 80, a: 255 },
19
+ LightGray: { r: 200, g: 200, b: 200, a: 255 },
20
+ Gray: { r: 130, g: 130, b: 130, a: 255 },
21
+ DarkBlue: { r: 0, g: 82, b: 172, a: 255 },
22
+ SkyBlue: { r: 102, g: 191, b: 255, a: 255 },
23
+ Lime: { r: 0, g: 158, b: 47, a: 255 },
24
+ DarkGreen: { r: 0, g: 117, b: 44, a: 255 },
25
+ Gold: { r: 255, g: 203, b: 0, a: 255 },
26
+ Maroon: { r: 190, g: 33, b: 55, a: 255 },
27
+ Brown: { r: 127, g: 106, b: 79, a: 255 },
28
+ Beige: { r: 211, g: 176, b: 131, a: 255 },
29
+ Magenta: { r: 255, g: 0, b: 255, a: 255 },
30
+ Violet: { r: 135, g: 60, b: 190, a: 255 },
31
+ Blank: { r: 0, g: 0, b: 0, a: 0 },
32
+ };
33
+
34
+ // Backward-compatible alias — same object, kept for older imports.
35
+ export const ColorConstants = Color;
36
+
37
+ // Backward-compatible alias with SCREAMING_SNAKE keys
38
+ export const Colors: Record<string, ColorType> = {
39
+ WHITE: Color.White,
40
+ BLACK: Color.Black,
41
+ RED: Color.Red,
42
+ GREEN: Color.Green,
43
+ BLUE: Color.Blue,
44
+ YELLOW: Color.Yellow,
45
+ ORANGE: Color.Orange,
46
+ PINK: Color.Pink,
47
+ PURPLE: Color.Purple,
48
+ DARKGRAY: Color.DarkGray,
49
+ LIGHTGRAY: Color.LightGray,
50
+ GRAY: Color.Gray,
51
+ DARKBLUE: Color.DarkBlue,
52
+ SKYBLUE: Color.SkyBlue,
53
+ LIME: Color.Lime,
54
+ DARKGREEN: Color.DarkGreen,
55
+ GOLD: Color.Gold,
56
+ MAROON: Color.Maroon,
57
+ BROWN: Color.Brown,
58
+ BEIGE: Color.Beige,
59
+ MAGENTA: Color.Magenta,
60
+ VIOLET: Color.Violet,
61
+ SNOW: Color.Snow,
62
+ BLANK: Color.Blank,
63
+ };