diff options
Diffstat (limited to 'platform/web')
-rw-r--r-- | platform/web/SCsub | 2 | ||||
-rw-r--r-- | platform/web/audio_driver_web.cpp | 20 | ||||
-rw-r--r-- | platform/web/audio_driver_web.h | 1 | ||||
-rw-r--r-- | platform/web/detect.py | 1 | ||||
-rw-r--r-- | platform/web/godot_audio.h | 1 | ||||
-rw-r--r-- | platform/web/js/libs/library_godot_audio.js | 37 | ||||
-rw-r--r-- | platform/web/js/libs/library_godot_input.js | 1 | ||||
-rw-r--r-- | platform/web/js/libs/library_godot_javascript_singleton.js | 16 | ||||
-rw-r--r-- | platform/web/web_main.cpp | 4 |
9 files changed, 68 insertions, 15 deletions
diff --git a/platform/web/SCsub b/platform/web/SCsub index 3d36a888d6..e81f2ec516 100644 --- a/platform/web/SCsub +++ b/platform/web/SCsub @@ -71,8 +71,6 @@ if env["dlink_enabled"]: sys_env.Append(LINKFLAGS=["-s", "MAIN_MODULE=1"]) sys_env.Append(LINKFLAGS=["-s", "EXPORT_ALL=1"]) sys_env.Append(LINKFLAGS=["-s", "WARN_ON_UNDEFINED_SYMBOLS=0"]) - # Force exporting the standard library (printf, malloc, etc.) - sys_env["ENV"]["EMCC_FORCE_STDLIBS"] = "libc,libc++,libc++abi" sys_env["CCFLAGS"].remove("-fvisibility=hidden") sys_env["LINKFLAGS"].remove("-fvisibility=hidden") diff --git a/platform/web/audio_driver_web.cpp b/platform/web/audio_driver_web.cpp index dd986e650c..22487d2756 100644 --- a/platform/web/audio_driver_web.cpp +++ b/platform/web/audio_driver_web.cpp @@ -33,6 +33,8 @@ #include "godot_audio.h" #include "core/config/project_settings.h" +#include "core/object/object.h" +#include "scene/main/node.h" #include "servers/audio/audio_stream.h" #include <emscripten.h> @@ -51,6 +53,21 @@ void AudioDriverWeb::_latency_update_callback(float p_latency) { AudioDriverWeb::audio_context.output_latency = p_latency; } +void AudioDriverWeb::_sample_playback_finished_callback(const char *p_playback_object_id) { + const ObjectID playback_id = ObjectID(String::to_int(p_playback_object_id)); + + Object *playback_object = ObjectDB::get_instance(playback_id); + if (playback_object == nullptr) { + return; + } + Ref<AudioSamplePlayback> playback = Object::cast_to<AudioSamplePlayback>(playback_object); + if (playback.is_null()) { + return; + } + + AudioServer::get_singleton()->stop_sample_playback(playback); +} + void AudioDriverWeb::_audio_driver_process(int p_from, int p_samples) { int32_t *stream_buffer = reinterpret_cast<int32_t *>(output_rb); const int max_samples = memarr_len(output_rb); @@ -132,6 +149,9 @@ Error AudioDriverWeb::init() { if (!input_rb) { return ERR_OUT_OF_MEMORY; } + + godot_audio_sample_set_finished_callback(&_sample_playback_finished_callback); + return OK; } diff --git a/platform/web/audio_driver_web.h b/platform/web/audio_driver_web.h index 298ad90fae..46c5ce4de1 100644 --- a/platform/web/audio_driver_web.h +++ b/platform/web/audio_driver_web.h @@ -58,6 +58,7 @@ private: WASM_EXPORT static void _state_change_callback(int p_state); WASM_EXPORT static void _latency_update_callback(float p_latency); + WASM_EXPORT static void _sample_playback_finished_callback(const char *p_playback_object_id); static AudioDriverWeb *singleton; diff --git a/platform/web/detect.py b/platform/web/detect.py index cb4dac1125..79485ea28a 100644 --- a/platform/web/detect.py +++ b/platform/web/detect.py @@ -78,6 +78,7 @@ def get_flags(): # -Os reduces file size by around 5 MiB over -O3. -Oz only saves about # 100 KiB over -Os, which does not justify the negative impact on # run-time performance. + # Note that this overrides the "auto" behavior for target/dev_build. "optimize": "size", } diff --git a/platform/web/godot_audio.h b/platform/web/godot_audio.h index 8bebbcf7de..dd5bec00cf 100644 --- a/platform/web/godot_audio.h +++ b/platform/web/godot_audio.h @@ -57,6 +57,7 @@ extern void godot_audio_sample_set_pause(const char *p_playback_object_id, bool extern int godot_audio_sample_is_active(const char *p_playback_object_id); extern void godot_audio_sample_update_pitch_scale(const char *p_playback_object_id, float p_pitch_scale); extern void godot_audio_sample_set_volumes_linear(const char *p_playback_object_id, int *p_buses_buf, int p_buses_size, float *p_volumes_buf, int p_volumes_size); +extern void godot_audio_sample_set_finished_callback(void (*p_callback)(const char *)); extern void godot_audio_sample_bus_set_count(int p_count); extern void godot_audio_sample_bus_remove(int p_index); diff --git a/platform/web/js/libs/library_godot_audio.js b/platform/web/js/libs/library_godot_audio.js index 4bca13d2d6..0b16b07261 100644 --- a/platform/web/js/libs/library_godot_audio.js +++ b/platform/web/js/libs/library_godot_audio.js @@ -142,7 +142,7 @@ class Sample { * @returns {void} */ clear() { - this.audioBuffer = null; + this.setAudioBuffer(null); GodotAudio.Sample.delete(this.id); } @@ -432,7 +432,7 @@ class SampleNode { /** @type {number} */ this._playbackRate = 44100; /** @type {LoopMode} */ - this.loopMode = 'disabled'; + this.loopMode = options.loopMode ?? this.getSample().loopMode ?? 'disabled'; /** @type {number} */ this._pitchScale = 1; /** @type {number} */ @@ -445,7 +445,6 @@ class SampleNode { this._onended = null; this.setPlaybackRate(options.playbackRate ?? 44100); - this.loopMode = options.loopMode ?? this.getSample().loopMode ?? 'disabled'; this._source.buffer = this.getSample().getAudioBuffer(); this._addEndedListener(); @@ -688,9 +687,15 @@ class SampleNode { } switch (self.getSample().loopMode) { - case 'disabled': + case 'disabled': { + const id = this.id; self.stop(); - break; + if (GodotAudio.sampleFinishedCallback != null) { + const idCharPtr = GodotRuntime.allocString(id); + GodotAudio.sampleFinishedCallback(idCharPtr); + GodotRuntime.free(idCharPtr); + } + } break; case 'forward': case 'backward': self.restart(); @@ -777,8 +782,7 @@ class Bus { */ static move(fromIndex, toIndex) { const movedBus = GodotAudio.Bus.getBus(fromIndex); - let buses = GodotAudio.buses; - buses = buses.filter((_, i) => i !== fromIndex); + const buses = GodotAudio.buses.filter((_, i) => i !== fromIndex); // Inserts at index. buses.splice(toIndex - 1, 0, movedBus); GodotAudio.buses = buses; @@ -1092,6 +1096,12 @@ const _GodotAudio = { busSolo: null, Bus, + /** + * Callback to signal that a sample has finished. + * @type {(playbackObjectIdPtr: number) => void | null} + */ + sampleFinishedCallback: null, + /** @type {AudioContext} */ ctx: null, input: null, @@ -1369,7 +1379,7 @@ const _GodotAudio = { */ set_sample_bus_volume_db: function (busIndex, volumeDb) { const bus = GodotAudio.Bus.getBus(busIndex); - bus.volumeDb = volumeDb; + bus.setVolumeDb(volumeDb); }, /** @@ -1766,6 +1776,17 @@ const _GodotAudio = { godot_audio_sample_bus_set_mute: function (bus, enable) { GodotAudio.set_sample_bus_mute(bus, Boolean(enable)); }, + + godot_audio_sample_set_finished_callback__proxy: 'sync', + godot_audio_sample_set_finished_callback__sig: 'vi', + /** + * Sets the finished callback + * @param {Number} callbackPtr Finished callback pointer + * @returns {void} + */ + godot_audio_sample_set_finished_callback: function (callbackPtr) { + GodotAudio.sampleFinishedCallback = GodotRuntime.get_func(callbackPtr); + }, }; autoAddDeps(_GodotAudio, '$GodotAudio'); diff --git a/platform/web/js/libs/library_godot_input.js b/platform/web/js/libs/library_godot_input.js index 7ea89d553f..6e3b97023d 100644 --- a/platform/web/js/libs/library_godot_input.js +++ b/platform/web/js/libs/library_godot_input.js @@ -112,6 +112,7 @@ const GodotIME = { ime.style.top = '0px'; ime.style.width = '100%'; ime.style.height = '40px'; + ime.style.pointerEvents = 'none'; ime.style.display = 'none'; ime.contentEditable = 'true'; diff --git a/platform/web/js/libs/library_godot_javascript_singleton.js b/platform/web/js/libs/library_godot_javascript_singleton.js index b17fde1544..6bb69bca95 100644 --- a/platform/web/js/libs/library_godot_javascript_singleton.js +++ b/platform/web/js/libs/library_godot_javascript_singleton.js @@ -81,11 +81,16 @@ const GodotJSWrapper = { case 0: return null; case 1: - return !!GodotRuntime.getHeapValue(val, 'i64'); - case 2: - return GodotRuntime.getHeapValue(val, 'i64'); + return Boolean(GodotRuntime.getHeapValue(val, 'i64')); + case 2: { + // `heap_value` may be a bigint. + const heap_value = GodotRuntime.getHeapValue(val, 'i64'); + return heap_value >= Number.MIN_SAFE_INTEGER && heap_value <= Number.MAX_SAFE_INTEGER + ? Number(heap_value) + : heap_value; + } case 3: - return GodotRuntime.getHeapValue(val, 'double'); + return Number(GodotRuntime.getHeapValue(val, 'double')); case 4: return GodotRuntime.parseString(GodotRuntime.getHeapValue(val, '*')); case 24: // OBJECT @@ -110,6 +115,9 @@ const GodotJSWrapper = { } GodotRuntime.setHeapValue(p_exchange, p_val, 'double'); return 3; // FLOAT + } else if (type === 'bigint') { + GodotRuntime.setHeapValue(p_exchange, p_val, 'i64'); + return 2; // INT } else if (type === 'string') { const c_str = GodotRuntime.allocString(p_val); GodotRuntime.setHeapValue(p_exchange, c_str, '*'); diff --git a/platform/web/web_main.cpp b/platform/web/web_main.cpp index 04513f6d57..d0c3bd7c0e 100644 --- a/platform/web/web_main.cpp +++ b/platform/web/web_main.cpp @@ -35,6 +35,8 @@ #include "core/config/engine.h" #include "core/io/resource_loader.h" #include "main/main.h" +#include "scene/main/scene_tree.h" +#include "scene/main/window.h" // SceneTree only forward declares it. #include <emscripten/emscripten.h> #include <stdlib.h> @@ -130,7 +132,7 @@ extern EMSCRIPTEN_KEEPALIVE int godot_web_main(int argc, char *argv[]) { if (Engine::get_singleton()->is_project_manager_hint() && FileAccess::exists("/tmp/preload.zip")) { PackedStringArray ps; ps.push_back("/tmp/preload.zip"); - os->get_main_loop()->emit_signal(SNAME("files_dropped"), ps, -1); + SceneTree::get_singleton()->get_root()->emit_signal(SNAME("files_dropped"), ps); } #endif emscripten_set_main_loop(main_loop_callback, -1, false); |