summaryrefslogtreecommitdiff
path: root/platform/javascript
diff options
context:
space:
mode:
Diffstat (limited to 'platform/javascript')
-rw-r--r--platform/javascript/SCsub6
-rw-r--r--platform/javascript/api/javascript_tools_editor_plugin.cpp5
-rw-r--r--platform/javascript/detect.py22
-rw-r--r--platform/javascript/display_server_javascript.cpp92
-rw-r--r--platform/javascript/display_server_javascript.h18
-rw-r--r--platform/javascript/emscripten_helpers.py6
-rw-r--r--platform/javascript/export/export_plugin.cpp58
-rw-r--r--platform/javascript/export/export_plugin.h19
-rw-r--r--platform/javascript/export/export_server.h2
-rw-r--r--platform/javascript/godot_js.h10
-rw-r--r--platform/javascript/godot_webgl2.h37
-rw-r--r--platform/javascript/http_client_javascript.cpp2
-rw-r--r--platform/javascript/javascript_singleton.cpp2
-rw-r--r--platform/javascript/js/libs/library_godot_display.js91
-rw-r--r--platform/javascript/js/libs/library_godot_os.js4
-rw-r--r--platform/javascript/os_javascript.cpp11
-rw-r--r--platform/javascript/os_javascript.h3
-rw-r--r--platform/javascript/package-lock.json239
-rw-r--r--platform/javascript/package.json2
-rw-r--r--platform/javascript/platform_config.h2
20 files changed, 476 insertions, 155 deletions
diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub
index 8d9ba82fd4..4827dc4627 100644
--- a/platform/javascript/SCsub
+++ b/platform/javascript/SCsub
@@ -37,6 +37,8 @@ for ext in env["JS_EXTERNS"]:
build = []
if env["gdnative_enabled"]:
build_targets = ["#bin/godot${PROGSUFFIX}.js", "#bin/godot${PROGSUFFIX}.wasm"]
+ if env["threads_enabled"]:
+ build_targets.append("#bin/godot${PROGSUFFIX}.worker.js")
# Reset libraries. The main runtime will only link emscripten libraries, not godot ones.
sys_env["LIBS"] = []
# We use IDBFS. Since Emscripten 1.39.1 it needs to be linked explicitly.
@@ -58,7 +60,7 @@ if env["gdnative_enabled"]:
wasm_env.Append(CCFLAGS=["-s", "SIDE_MODULE=2"])
wasm_env.Append(LINKFLAGS=["-s", "SIDE_MODULE=2"])
wasm = wasm_env.add_program("#bin/godot.side${PROGSUFFIX}.wasm", javascript_files)
- build = [sys[0], sys[1], wasm[0]]
+ build = sys + [wasm[0]]
else:
build_targets = ["#bin/godot${PROGSUFFIX}.js", "#bin/godot${PROGSUFFIX}.wasm"]
if env["threads_enabled"]:
@@ -87,5 +89,5 @@ wrap_list = [
js_wrapped = env.Textfile("#bin/godot", [env.File(f) for f in wrap_list], TEXTFILESUFFIX="${PROGSUFFIX}.wrapped.js")
# Extra will be the thread worker, or the GDNative side, or None
-extra = build[2] if len(build) > 2 else None
+extra = build[2:] if len(build) > 2 else None
env.CreateTemplateZip(js_wrapped, build[1], extra)
diff --git a/platform/javascript/api/javascript_tools_editor_plugin.cpp b/platform/javascript/api/javascript_tools_editor_plugin.cpp
index 31ce71127d..1507f32375 100644
--- a/platform/javascript/api/javascript_tools_editor_plugin.cpp
+++ b/platform/javascript/api/javascript_tools_editor_plugin.cpp
@@ -64,7 +64,8 @@ void JavaScriptToolsEditorPlugin::_download_zip(Variant p_v) {
}
String resource_path = ProjectSettings::get_singleton()->get_resource_path();
- zlib_filefunc_def io = zipio_create_io();
+ Ref<FileAccess> io_fa;
+ zlib_filefunc_def io = zipio_create_io(&io_fa);
// Name the downloaded ZIP file to contain the project name and download date for easier organization.
// Replace characters not allowed (or risky) in Windows file names with safe characters.
@@ -122,7 +123,7 @@ void JavaScriptToolsEditorPlugin::_zip_file(String p_path, String p_base_path, z
void JavaScriptToolsEditorPlugin::_zip_recursive(String p_path, String p_base_path, zipFile p_zip) {
Ref<DirAccess> dir = DirAccess::open(p_path);
- if (!dir) {
+ if (dir.is_null()) {
WARN_PRINT("Unable to open directory for zipping: " + p_path);
return;
}
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index b6be44fbb2..a769260f01 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -48,11 +48,6 @@ def get_flags():
return [
("tools", False),
("builtin_pcre2_with_jit", False),
- # Disabling the mbedtls module reduces file size.
- # The module has little use due to the limited networking functionality
- # in this platform. For the available networking methods, the browser
- # manages TLS.
- ("module_mbedtls_enabled", False),
("vulkan", False),
]
@@ -190,10 +185,6 @@ def configure(env):
if env["javascript_eval"]:
env.Append(CPPDEFINES=["JAVASCRIPT_EVAL_ENABLED"])
- if env["threads_enabled"] and env["gdnative_enabled"]:
- print("Threads and GDNative support can't be both enabled due to WebAssembly limitations")
- sys.exit(255)
-
# Thread support (via SharedArrayBuffer).
if env["threads_enabled"]:
env.Append(CPPDEFINES=["PTHREAD_NO_RENAME"])
@@ -206,12 +197,19 @@ def configure(env):
env.Append(CPPDEFINES=["NO_THREADS"])
if env["gdnative_enabled"]:
- major, minor, patch = get_compiler_version(env)
- if major < 2 or (major == 2 and minor == 0 and patch < 10):
- print("GDNative support requires emscripten >= 2.0.10, detected: %s.%s.%s" % (major, minor, patch))
+ cc_version = get_compiler_version(env)
+ cc_semver = (int(cc_version["major"]), int(cc_version["minor"]), int(cc_version["patch"]))
+ if cc_semver < (2, 0, 10):
+ print("GDNative support requires emscripten >= 2.0.10, detected: %s.%s.%s" % cc_semver)
+ sys.exit(255)
+
+ if env["threads_enabled"] and cc_semver < (3, 1, 14):
+ print("Threads and GDNative requires emscripten >= 3.1.14, detected: %s.%s.%s" % cc_semver)
sys.exit(255)
env.Append(CCFLAGS=["-s", "RELOCATABLE=1"])
env.Append(LINKFLAGS=["-s", "RELOCATABLE=1"])
+ # Weak symbols are broken upstream: https://github.com/emscripten-core/emscripten/issues/12819
+ env.Append(CPPDEFINES=["ZSTD_HAVE_WEAK_SYMBOLS=0"])
env.extra_suffix = ".gdnative" + env.extra_suffix
# Reduce code size by generating less support code (e.g. skip NodeJS support).
diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp
index a38040922d..a96c539a1f 100644
--- a/platform/javascript/display_server_javascript.cpp
+++ b/platform/javascript/display_server_javascript.cpp
@@ -244,9 +244,9 @@ const char *DisplayServerJavaScript::godot2dom_cursor(DisplayServer::CursorShape
case DisplayServer::CURSOR_CROSS:
return "crosshair";
case DisplayServer::CURSOR_WAIT:
- return "progress";
- case DisplayServer::CURSOR_BUSY:
return "wait";
+ case DisplayServer::CURSOR_BUSY:
+ return "progress";
case DisplayServer::CURSOR_DRAG:
return "grab";
case DisplayServer::CURSOR_CAN_DROP:
@@ -274,6 +274,90 @@ const char *DisplayServerJavaScript::godot2dom_cursor(DisplayServer::CursorShape
}
}
+bool DisplayServerJavaScript::tts_is_speaking() const {
+ return godot_js_tts_is_speaking();
+}
+
+bool DisplayServerJavaScript::tts_is_paused() const {
+ return godot_js_tts_is_paused();
+}
+
+void DisplayServerJavaScript::update_voices_callback(int p_size, const char **p_voice) {
+ get_singleton()->voices.clear();
+ for (int i = 0; i < p_size; i++) {
+ Vector<String> tokens = String::utf8(p_voice[i]).split(";", true, 2);
+ if (tokens.size() == 2) {
+ Dictionary voice_d;
+ voice_d["name"] = tokens[1];
+ voice_d["id"] = tokens[1];
+ voice_d["language"] = tokens[0];
+ get_singleton()->voices.push_back(voice_d);
+ }
+ }
+}
+
+Array DisplayServerJavaScript::tts_get_voices() const {
+ godot_js_tts_get_voices(update_voices_callback);
+ return voices;
+}
+
+void DisplayServerJavaScript::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) {
+ if (p_interrupt) {
+ tts_stop();
+ }
+
+ if (p_text.is_empty()) {
+ tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_CANCELED, p_utterance_id);
+ return;
+ }
+
+ CharString string = p_text.utf8();
+ utterance_ids[p_utterance_id] = string;
+
+ godot_js_tts_speak(string.get_data(), p_voice.utf8().get_data(), CLAMP(p_volume, 0, 100), CLAMP(p_pitch, 0.f, 2.f), CLAMP(p_rate, 0.1f, 10.f), p_utterance_id, DisplayServerJavaScript::_js_utterance_callback);
+}
+
+void DisplayServerJavaScript::tts_pause() {
+ godot_js_tts_pause();
+}
+
+void DisplayServerJavaScript::tts_resume() {
+ godot_js_tts_resume();
+}
+
+void DisplayServerJavaScript::tts_stop() {
+ for (const KeyValue<int, CharString> &E : utterance_ids) {
+ tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_CANCELED, E.key);
+ }
+ utterance_ids.clear();
+ godot_js_tts_stop();
+}
+
+void DisplayServerJavaScript::_js_utterance_callback(int p_event, int p_id, int p_pos) {
+ DisplayServerJavaScript *ds = (DisplayServerJavaScript *)DisplayServer::get_singleton();
+ if (ds->utterance_ids.has(p_id)) {
+ int pos = 0;
+ if ((TTSUtteranceEvent)p_event == DisplayServer::TTS_UTTERANCE_BOUNDARY) {
+ // Convert position from UTF-8 to UTF-32.
+ const CharString &string = ds->utterance_ids[p_id];
+ for (int i = 0; i < MIN(p_pos, string.length()); i++) {
+ uint8_t c = string[i];
+ if ((c & 0xe0) == 0xc0) {
+ i += 1;
+ } else if ((c & 0xf0) == 0xe0) {
+ i += 2;
+ } else if ((c & 0xf8) == 0xf0) {
+ i += 3;
+ }
+ pos++;
+ }
+ } else if ((TTSUtteranceEvent)p_event != DisplayServer::TTS_UTTERANCE_STARTED) {
+ ds->utterance_ids.erase(p_id);
+ }
+ ds->tts_post_utterance_event((TTSUtteranceEvent)p_event, p_id, pos);
+ }
+}
+
void DisplayServerJavaScript::cursor_set_shape(CursorShape p_shape) {
ERR_FAIL_INDEX(p_shape, CURSOR_MAX);
if (cursor_shape == p_shape) {
@@ -287,7 +371,7 @@ DisplayServer::CursorShape DisplayServerJavaScript::cursor_get_shape() const {
return cursor_shape;
}
-void DisplayServerJavaScript::cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
+void DisplayServerJavaScript::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
if (p_cursor.is_valid()) {
Ref<Texture2D> texture = p_cursor;
Ref<AtlasTexture> atlas_texture = p_cursor;
@@ -755,6 +839,8 @@ bool DisplayServerJavaScript::has_feature(Feature p_feature) const {
//case FEATURE_ORIENTATION:
case FEATURE_VIRTUAL_KEYBOARD:
return godot_js_display_vk_available() != 0;
+ case FEATURE_TEXT_TO_SPEECH:
+ return godot_js_display_tts_available() != 0;
default:
return false;
}
diff --git a/platform/javascript/display_server_javascript.h b/platform/javascript/display_server_javascript.h
index b50956d91c..79b0fbb652 100644
--- a/platform/javascript/display_server_javascript.h
+++ b/platform/javascript/display_server_javascript.h
@@ -55,6 +55,8 @@ private:
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE webgl_ctx = 0;
#endif
+ HashMap<int, CharString> utterance_ids;
+
WindowMode window_mode = WINDOW_MODE_WINDOWED;
ObjectID window_attached_instance_id = {};
@@ -66,6 +68,8 @@ private:
String clipboard;
Point2 touches[32];
+ Array voices;
+
char canvas_id[256] = { 0 };
bool cursor_inside_canvas = true;
CursorShape cursor_shape = CURSOR_ARROW;
@@ -89,6 +93,7 @@ private:
static void vk_input_text_callback(const char *p_text, int p_cursor);
static void gamepad_callback(int p_index, int p_connected, const char *p_id, const char *p_guid);
void process_joypads();
+ static void _js_utterance_callback(int p_event, int p_id, int p_pos);
static Vector<String> get_rendering_drivers_func();
static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
@@ -97,6 +102,7 @@ private:
static void request_quit_callback();
static void window_blur_callback();
+ static void update_voices_callback(int p_size, const char **p_voice);
static void update_clipboard_callback(const char *p_text);
static void send_window_event_callback(int p_notification);
static void drop_files_js_callback(char **p_filev, int p_filec);
@@ -115,10 +121,20 @@ public:
virtual bool has_feature(Feature p_feature) const override;
virtual String get_name() const override;
+ // tts
+ virtual bool tts_is_speaking() const override;
+ virtual bool tts_is_paused() const override;
+ virtual Array tts_get_voices() const override;
+
+ virtual void tts_speak(const String &p_text, const String &p_voice, int p_volume = 50, float p_pitch = 1.f, float p_rate = 1.f, int p_utterance_id = 0, bool p_interrupt = false) override;
+ virtual void tts_pause() override;
+ virtual void tts_resume() override;
+ virtual void tts_stop() override;
+
// cursor
virtual void cursor_set_shape(CursorShape p_shape) override;
virtual CursorShape cursor_get_shape() const override;
- virtual void cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override;
+ virtual void cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override;
// mouse
virtual void mouse_set_mode(MouseMode p_mode) override;
diff --git a/platform/javascript/emscripten_helpers.py b/platform/javascript/emscripten_helpers.py
index 4dad2d5204..3cb1d75e52 100644
--- a/platform/javascript/emscripten_helpers.py
+++ b/platform/javascript/emscripten_helpers.py
@@ -52,10 +52,10 @@ def create_template_zip(env, js, wasm, extra):
]
# GDNative/Threads specific
if env["gdnative_enabled"]:
- in_files.append(extra) # Runtime
+ in_files.append(extra.pop()) # Runtime
out_files.append(zip_dir.File(binary_name + ".side.wasm"))
- elif env["threads_enabled"]:
- in_files.append(extra) # Worker
+ if env["threads_enabled"]:
+ in_files.append(extra.pop()) # Worker
out_files.append(zip_dir.File(binary_name + ".worker.js"))
service_worker = "#misc/dist/html/service-worker.js"
diff --git a/platform/javascript/export/export_plugin.cpp b/platform/javascript/export/export_plugin.cpp
index 66d93d7c49..901580c140 100644
--- a/platform/javascript/export/export_plugin.cpp
+++ b/platform/javascript/export/export_plugin.cpp
@@ -33,16 +33,17 @@
#include "core/config/project_settings.h"
Error EditorExportPlatformJavaScript::_extract_template(const String &p_template, const String &p_dir, const String &p_name, bool pwa) {
- zlib_filefunc_def io = zipio_create_io();
+ Ref<FileAccess> io_fa;
+ zlib_filefunc_def io = zipio_create_io(&io_fa);
unzFile pkg = unzOpen2(p_template.utf8().get_data(), &io);
if (!pkg) {
- EditorNode::get_singleton()->show_warning(TTR("Could not open template for export:") + "\n" + p_template);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), vformat(TTR("Could not open template for export: \"%s\"."), p_template));
return ERR_FILE_NOT_FOUND;
}
if (unzGoToFirstFile(pkg) != UNZ_OK) {
- EditorNode::get_singleton()->show_warning(TTR("Invalid export template:") + "\n" + p_template);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), vformat(TTR("Invalid export template: \"%s\"."), p_template));
unzClose(pkg);
return ERR_FILE_CORRUPT;
}
@@ -55,6 +56,11 @@ Error EditorExportPlatformJavaScript::_extract_template(const String &p_template
String file = String::utf8(fname);
+ // Skip folders.
+ if (file.ends_with("/")) {
+ continue;
+ }
+
// Skip service worker and offline page if not exporting pwa.
if (!pwa && (file == "godot.service.worker.js" || file == "godot.offline.html")) {
continue;
@@ -71,7 +77,7 @@ Error EditorExportPlatformJavaScript::_extract_template(const String &p_template
String dst = p_dir.plus_file(file.replace("godot", p_name));
Ref<FileAccess> f = FileAccess::open(dst, FileAccess::WRITE);
if (f.is_null()) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + dst);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), vformat(TTR("Could not write file: \"%s\"."), dst));
unzClose(pkg);
return ERR_FILE_CANT_WRITE;
}
@@ -85,14 +91,14 @@ Error EditorExportPlatformJavaScript::_extract_template(const String &p_template
Error EditorExportPlatformJavaScript::_write_or_error(const uint8_t *p_content, int p_size, String p_path) {
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE);
if (f.is_null()) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + p_path);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not write file: \"%s\"."), p_path));
return ERR_FILE_CANT_WRITE;
}
f->store_buffer(p_content, p_size);
return OK;
}
-void EditorExportPlatformJavaScript::_replace_strings(Map<String, String> p_replaces, Vector<uint8_t> &r_template) {
+void EditorExportPlatformJavaScript::_replace_strings(HashMap<String, String> p_replaces, Vector<uint8_t> &r_template) {
String str_template = String::utf8(reinterpret_cast<const char *>(r_template.ptr()), r_template.size());
String out;
Vector<String> lines = str_template.split("\n");
@@ -144,7 +150,7 @@ void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Re
// Replaces HTML string
const String str_config = Variant(config).to_json_string();
const String custom_head_include = p_preset->get("html/head_include");
- Map<String, String> replaces;
+ HashMap<String, String> replaces;
replaces["$GODOT_URL"] = p_name + ".js";
replaces["$GODOT_PROJECT_NAME"] = ProjectSettings::get_singleton()->get_setting("application/config/name");
replaces["$GODOT_HEAD_INCLUDE"] = head_include + custom_head_include;
@@ -162,7 +168,7 @@ Error EditorExportPlatformJavaScript::_add_manifest_icon(const String &p_path, c
icon.instantiate();
const Error err = ImageLoader::load_image(p_icon, icon);
if (err != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not read file:") + "\n" + p_icon);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Icon Creation"), vformat(TTR("Could not read file: \"%s\"."), p_icon));
return err;
}
if (icon->get_width() != p_size || icon->get_height() != p_size) {
@@ -174,7 +180,7 @@ Error EditorExportPlatformJavaScript::_add_manifest_icon(const String &p_path, c
}
const Error err = icon->save_png(icon_dest);
if (err != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + icon_dest);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Icon Creation"), vformat(TTR("Could not write file: \"%s\"."), icon_dest));
return err;
}
Dictionary icon_dict;
@@ -195,7 +201,7 @@ Error EditorExportPlatformJavaScript::_build_pwa(const Ref<EditorExportPreset> &
const String dir = p_path.get_base_dir();
const String name = p_path.get_file().get_basename();
const ExportMode mode = (ExportMode)(int)p_preset->get("variant/export_type");
- Map<String, String> replaces;
+ HashMap<String, String> replaces;
replaces["@GODOT_VERSION@"] = String::num_int64(OS::get_singleton()->get_unix_time()) + "|" + String::num_int64(OS::get_singleton()->get_ticks_usec());
replaces["@GODOT_NAME@"] = proj_name.substr(0, 16);
replaces["@GODOT_OFFLINE_PAGE@"] = name + ".offline.html";
@@ -209,7 +215,7 @@ Error EditorExportPlatformJavaScript::_build_pwa(const Ref<EditorExportPreset> &
cache_files.push_back(name + ".icon.png");
cache_files.push_back(name + ".apple-touch-icon.png");
}
- if (mode == EXPORT_MODE_THREADS) {
+ if (mode & EXPORT_MODE_THREADS) {
cache_files.push_back(name + ".worker.js");
cache_files.push_back(name + ".audio.worklet.js");
}
@@ -219,7 +225,7 @@ Error EditorExportPlatformJavaScript::_build_pwa(const Ref<EditorExportPreset> &
Array opt_cache_files;
opt_cache_files.push_back(name + ".wasm");
opt_cache_files.push_back(name + ".pck");
- if (mode == EXPORT_MODE_GDNATIVE) {
+ if (mode & EXPORT_MODE_GDNATIVE) {
opt_cache_files.push_back(name + ".side.wasm");
for (int i = 0; i < p_shared_objects.size(); i++) {
opt_cache_files.push_back(p_shared_objects[i].path.get_file());
@@ -232,7 +238,7 @@ Error EditorExportPlatformJavaScript::_build_pwa(const Ref<EditorExportPreset> &
{
Ref<FileAccess> f = FileAccess::open(sw_path, FileAccess::READ);
if (f.is_null()) {
- EditorNode::get_singleton()->show_warning(TTR("Could not read file:") + "\n" + sw_path);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("PWA"), vformat(TTR("Could not read file: \"%s\"."), sw_path));
return ERR_FILE_CANT_READ;
}
sw.resize(f->get_length());
@@ -251,7 +257,7 @@ Error EditorExportPlatformJavaScript::_build_pwa(const Ref<EditorExportPreset> &
const String offline_dest = dir.plus_file(name + ".offline.html");
err = da->copy(ProjectSettings::get_singleton()->globalize_path(offline_page), offline_dest);
if (err != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not read file:") + "\n" + offline_dest);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("PWA"), vformat(TTR("Could not read file: \"%s\"."), offline_dest));
return err;
}
}
@@ -311,9 +317,10 @@ void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportP
}
}
ExportMode mode = (ExportMode)(int)p_preset->get("variant/export_type");
- if (mode == EXPORT_MODE_THREADS) {
+ if (mode & EXPORT_MODE_THREADS) {
r_features->push_back("threads");
- } else if (mode == EXPORT_MODE_GDNATIVE) {
+ }
+ if (mode & EXPORT_MODE_GDNATIVE) {
r_features->push_back("wasm32");
}
}
@@ -437,7 +444,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
}
if (!template_path.is_empty() && !FileAccess::exists(template_path)) {
- EditorNode::get_singleton()->show_warning(TTR("Template file not found:") + "\n" + template_path);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), vformat(TTR("Template file not found: \"%s\"."), template_path));
return ERR_FILE_NOT_FOUND;
}
@@ -446,7 +453,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
String pck_path = base_path + ".pck";
Error error = save_pack(p_preset, p_debug, pck_path, &shared_objects);
if (error != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + pck_path);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not write file: \"%s\"."), pck_path));
return error;
}
@@ -456,7 +463,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
String dst = base_dir.plus_file(shared_objects[i].path.get_file());
error = da->copy(shared_objects[i].path, dst);
if (error != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + shared_objects[i].path.get_file());
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not write file: \"%s\"."), shared_objects[i].path.get_file()));
return error;
}
}
@@ -484,7 +491,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
Vector<uint8_t> html;
f = FileAccess::open(html_path, FileAccess::READ);
if (f.is_null()) {
- EditorNode::get_singleton()->show_warning(TTR("Could not read HTML shell:") + "\n" + html_path);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not read HTML shell: \"%s\"."), html_path));
return ERR_FILE_CANT_READ;
}
html.resize(f->get_length());
@@ -502,7 +509,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
Ref<Image> splash = _get_project_splash();
const String splash_png_path = base_path + ".png";
if (splash->save_png(splash_png_path) != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + splash_png_path);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not write file: \"%s\"."), splash_png_path));
return ERR_FILE_CANT_WRITE;
}
@@ -512,13 +519,13 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
Ref<Image> favicon = _get_project_icon();
const String favicon_png_path = base_path + ".icon.png";
if (favicon->save_png(favicon_png_path) != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + favicon_png_path);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not write file: \"%s\"."), favicon_png_path));
return ERR_FILE_CANT_WRITE;
}
favicon->resize(180, 180);
const String apple_icon_png_path = base_path + ".apple-touch-icon.png";
if (favicon->save_png(apple_icon_png_path) != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + apple_icon_png_path);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not write file: \"%s\"."), apple_icon_png_path));
return ERR_FILE_CANT_WRITE;
}
}
@@ -578,10 +585,11 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese
if (!da->dir_exists(dest)) {
Error err = da->make_dir_recursive(dest);
if (err != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not create HTTP server directory:") + "\n" + dest);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Run"), vformat(TTR("Could not create HTTP server directory: %s."), dest));
return err;
}
}
+
const String basepath = dest.plus_file("tmp_js_export");
Error err = export_project(p_preset, true, basepath + ".html", p_debug_flags);
if (err != OK) {
@@ -624,7 +632,7 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese
err = server->listen(bind_port, bind_ip, use_ssl, ssl_key, ssl_cert);
}
if (err != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Error starting HTTP server:") + "\n" + itos(err));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Run"), vformat(TTR("Error starting HTTP server: %d."), err));
return err;
}
diff --git a/platform/javascript/export/export_plugin.h b/platform/javascript/export/export_plugin.h
index d17fd2f674..1aaec5454d 100644
--- a/platform/javascript/export/export_plugin.h
+++ b/platform/javascript/export/export_plugin.h
@@ -61,19 +61,16 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform {
EXPORT_MODE_NORMAL = 0,
EXPORT_MODE_THREADS = 1,
EXPORT_MODE_GDNATIVE = 2,
+ EXPORT_MODE_THREADS_GDNATIVE = 3,
};
String _get_template_name(ExportMode p_mode, bool p_debug) const {
String name = "webassembly";
- switch (p_mode) {
- case EXPORT_MODE_THREADS:
- name += "_threads";
- break;
- case EXPORT_MODE_GDNATIVE:
- name += "_gdnative";
- break;
- default:
- break;
+ if (p_mode & EXPORT_MODE_GDNATIVE) {
+ name += "_gdnative";
+ }
+ if (p_mode & EXPORT_MODE_THREADS) {
+ name += "_threads";
}
if (p_debug) {
name += "_debug.zip";
@@ -104,7 +101,7 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform {
}
Error _extract_template(const String &p_template, const String &p_dir, const String &p_name, bool pwa);
- void _replace_strings(Map<String, String> p_replaces, Vector<uint8_t> &r_template);
+ void _replace_strings(HashMap<String, String> p_replaces, Vector<uint8_t> &r_template);
void _fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, int p_flags, const Vector<SharedObject> p_shared_objects, const Dictionary &p_file_sizes);
Error _add_manifest_icon(const String &p_path, const String &p_icon, int p_size, Array &r_arr);
Error _build_pwa(const Ref<EditorExportPreset> &p_preset, const String p_path, const Vector<SharedObject> &p_shared_objects);
@@ -138,7 +135,7 @@ public:
r_features->push_back(get_os_name().to_lower());
}
- virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, Set<String> &p_features) override {
+ virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) override {
}
String get_debug_protocol() const override { return "ws://"; }
diff --git a/platform/javascript/export/export_server.h b/platform/javascript/export/export_server.h
index f77ac3d1ad..a831b76076 100644
--- a/platform/javascript/export/export_server.h
+++ b/platform/javascript/export/export_server.h
@@ -41,7 +41,7 @@
class EditorHTTPServer : public RefCounted {
private:
Ref<TCPServer> server;
- Map<String, String> mimes;
+ HashMap<String, String> mimes;
Ref<StreamPeerTCP> tcp;
Ref<StreamPeerSSL> ssl;
Ref<StreamPeer> peer;
diff --git a/platform/javascript/godot_js.h b/platform/javascript/godot_js.h
index 2cb5c3025c..1a383c9799 100644
--- a/platform/javascript/godot_js.h
+++ b/platform/javascript/godot_js.h
@@ -67,6 +67,15 @@ extern int godot_js_input_gamepad_sample_get(int p_idx, float r_btns[16], int32_
extern void godot_js_input_paste_cb(void (*p_callback)(const char *p_text));
extern void godot_js_input_drop_files_cb(void (*p_callback)(char **p_filev, int p_filec));
+// TTS
+extern int godot_js_tts_is_speaking();
+extern int godot_js_tts_is_paused();
+extern int godot_js_tts_get_voices(void (*p_callback)(int p_size, const char **p_voices));
+extern void godot_js_tts_speak(const char *p_text, const char *p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, void (*p_callback)(int p_event, int p_id, int p_pos));
+extern void godot_js_tts_pause();
+extern void godot_js_tts_resume();
+extern void godot_js_tts_stop();
+
// Display
extern int godot_js_display_screen_dpi_get();
extern double godot_js_display_pixel_ratio_get();
@@ -109,6 +118,7 @@ extern void godot_js_display_notification_cb(void (*p_callback)(int p_notificati
// Display Virtual Keyboard
extern int godot_js_display_vk_available();
+extern int godot_js_display_tts_available();
extern void godot_js_display_vk_cb(void (*p_input)(const char *p_text, int p_cursor));
extern void godot_js_display_vk_show(const char *p_text, int p_multiline, int p_start, int p_end);
extern void godot_js_display_vk_hide();
diff --git a/platform/javascript/godot_webgl2.h b/platform/javascript/godot_webgl2.h
new file mode 100644
index 0000000000..7c357ff66d
--- /dev/null
+++ b/platform/javascript/godot_webgl2.h
@@ -0,0 +1,37 @@
+/*************************************************************************/
+/* godot_webgl2.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef GODOT_WEBGL2_H
+#define GODOT_WEBGL2_H
+
+#include "GLES3/gl3.h"
+#include "webgl/webgl2.h"
+
+#endif
diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp
index c946302862..32bdfed4c7 100644
--- a/platform/javascript/http_client_javascript.cpp
+++ b/platform/javascript/http_client_javascript.cpp
@@ -76,7 +76,7 @@ void HTTPClientJavaScript::set_connection(const Ref<StreamPeer> &p_connection) {
}
Ref<StreamPeer> HTTPClientJavaScript::get_connection() const {
- ERR_FAIL_V_MSG(REF(), "Accessing an HTTPClientJavaScript's StreamPeer is not supported for the HTML5 platform.");
+ ERR_FAIL_V_MSG(Ref<RefCounted>(), "Accessing an HTTPClientJavaScript's StreamPeer is not supported for the HTML5 platform.");
}
Error HTTPClientJavaScript::request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_len) {
diff --git a/platform/javascript/javascript_singleton.cpp b/platform/javascript/javascript_singleton.cpp
index c9c4d6e1b9..8dc7aba5f8 100644
--- a/platform/javascript/javascript_singleton.cpp
+++ b/platform/javascript/javascript_singleton.cpp
@@ -207,7 +207,7 @@ int JavaScriptObjectImpl::_variant2js(const void **p_args, int p_pos, godot_js_w
break;
case Variant::INT: {
const int64_t tmp = v->operator int64_t();
- if (tmp >= 1 << 31) {
+ if (tmp >= 1LL << 31) {
r_val->r = (double)tmp;
return Variant::FLOAT;
}
diff --git a/platform/javascript/js/libs/library_godot_display.js b/platform/javascript/js/libs/library_godot_display.js
index 2bdf4e56ad..5997631bf8 100644
--- a/platform/javascript/js/libs/library_godot_display.js
+++ b/platform/javascript/js/libs/library_godot_display.js
@@ -330,6 +330,91 @@ const GodotDisplay = {
return 0;
},
+ godot_js_tts_is_speaking__sig: 'i',
+ godot_js_tts_is_speaking: function () {
+ return window.speechSynthesis.speaking;
+ },
+
+ godot_js_tts_is_paused__sig: 'i',
+ godot_js_tts_is_paused: function () {
+ return window.speechSynthesis.paused;
+ },
+
+ godot_js_tts_get_voices__sig: 'vi',
+ godot_js_tts_get_voices: function (p_callback) {
+ const func = GodotRuntime.get_func(p_callback);
+ try {
+ const arr = [];
+ const voices = window.speechSynthesis.getVoices();
+ for (let i = 0; i < voices.length; i++) {
+ arr.push(`${voices[i].lang};${voices[i].name}`);
+ }
+ const c_ptr = GodotRuntime.allocStringArray(arr);
+ func(arr.length, c_ptr);
+ GodotRuntime.freeStringArray(c_ptr, arr.length);
+ } catch (e) {
+ // Fail graciously.
+ }
+ },
+
+ godot_js_tts_speak__sig: 'viiiffii',
+ godot_js_tts_speak: function (p_text, p_voice, p_volume, p_pitch, p_rate, p_utterance_id, p_callback) {
+ const func = GodotRuntime.get_func(p_callback);
+
+ function listener_end(evt) {
+ evt.currentTarget.cb(1 /*TTS_UTTERANCE_ENDED*/, evt.currentTarget.id, 0);
+ }
+
+ function listener_start(evt) {
+ evt.currentTarget.cb(0 /*TTS_UTTERANCE_STARTED*/, evt.currentTarget.id, 0);
+ }
+
+ function listener_error(evt) {
+ evt.currentTarget.cb(2 /*TTS_UTTERANCE_CANCELED*/, evt.currentTarget.id, 0);
+ }
+
+ function listener_bound(evt) {
+ evt.currentTarget.cb(3 /*TTS_UTTERANCE_BOUNDARY*/, evt.currentTarget.id, evt.charIndex);
+ }
+
+ const utterance = new SpeechSynthesisUtterance(GodotRuntime.parseString(p_text));
+ utterance.rate = p_rate;
+ utterance.pitch = p_pitch;
+ utterance.volume = p_volume / 100.0;
+ utterance.addEventListener('end', listener_end);
+ utterance.addEventListener('start', listener_start);
+ utterance.addEventListener('error', listener_error);
+ utterance.addEventListener('boundary', listener_bound);
+ utterance.id = p_utterance_id;
+ utterance.cb = func;
+ const voice = GodotRuntime.parseString(p_voice);
+ const voices = window.speechSynthesis.getVoices();
+ for (let i = 0; i < voices.length; i++) {
+ if (voices[i].name === voice) {
+ utterance.voice = voices[i];
+ break;
+ }
+ }
+ window.speechSynthesis.resume();
+ window.speechSynthesis.speak(utterance);
+ },
+
+ godot_js_tts_pause__sig: 'v',
+ godot_js_tts_pause: function () {
+ window.speechSynthesis.pause();
+ },
+
+ godot_js_tts_resume__sig: 'v',
+ godot_js_tts_resume: function () {
+ window.speechSynthesis.resume();
+ },
+
+ godot_js_tts_stop__sig: 'v',
+ godot_js_tts_stop: function () {
+ window.speechSynthesis.cancel();
+ window.speechSynthesis.resume();
+ },
+
godot_js_display_alert__sig: 'vi',
godot_js_display_alert: function (p_text) {
window.alert(GodotRuntime.parseString(p_text)); // eslint-disable-line no-alert
@@ -377,6 +462,7 @@ const GodotDisplay = {
GodotRuntime.setHeapValue(height, window.screen.height * scale, 'i32');
},
+ godot_js_display_window_size_get__sig: 'vii',
godot_js_display_window_size_get: function (p_width, p_height) {
GodotRuntime.setHeapValue(p_width, GodotConfig.canvas.width, 'i32');
GodotRuntime.setHeapValue(p_height, GodotConfig.canvas.height, 'i32');
@@ -625,6 +711,11 @@ const GodotDisplay = {
return GodotDisplayVK.available();
},
+ godot_js_display_tts_available__sig: 'i',
+ godot_js_display_tts_available: function () {
+ return 'speechSynthesis' in window;
+ },
+
godot_js_display_vk_cb__sig: 'vi',
godot_js_display_vk_cb: function (p_input_cb) {
const input_cb = GodotRuntime.get_func(p_input_cb);
diff --git a/platform/javascript/js/libs/library_godot_os.js b/platform/javascript/js/libs/library_godot_os.js
index 12d06a8d51..377eec3234 100644
--- a/platform/javascript/js/libs/library_godot_os.js
+++ b/platform/javascript/js/libs/library_godot_os.js
@@ -305,7 +305,9 @@ const GodotOS = {
godot_js_os_hw_concurrency_get__sig: 'i',
godot_js_os_hw_concurrency_get: function () {
- return navigator.hardwareConcurrency || 1;
+ // TODO Godot core needs fixing to avoid spawning too many threads (> 24).
+ const concurrency = navigator.hardwareConcurrency || 1;
+ return concurrency < 2 ? concurrency : 2;
},
godot_js_os_download_buffer__sig: 'viiii',
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index da88ea18b0..1686353229 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -131,6 +131,10 @@ int OS_JavaScript::get_process_id() const {
ERR_FAIL_V_MSG(0, "OS::get_process_id() is not available on the HTML5 platform.");
}
+bool OS_JavaScript::is_process_running(const ProcessID &p_pid) const {
+ return false;
+}
+
int OS_JavaScript::get_processor_count() const {
return godot_js_os_hw_concurrency_get();
}
@@ -221,10 +225,15 @@ bool OS_JavaScript::is_userfs_persistent() const {
return idb_available;
}
-Error OS_JavaScript::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {
+Error OS_JavaScript::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
String path = p_path.get_file();
p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW);
ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ". Error: " + dlerror());
+
+ if (r_resolved_path != nullptr) {
+ *r_resolved_path = path;
+ }
+
return OK;
}
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index 9e272f9aa1..0c672111cc 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -79,6 +79,7 @@ public:
Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr, bool p_open_console = false) override;
Error kill(const ProcessID &p_pid) override;
int get_process_id() const override;
+ bool is_process_running(const ProcessID &p_pid) const override;
int get_processor_count() const override;
int get_default_thread_pool_size() const override { return 1; }
@@ -99,7 +100,7 @@ public:
void alert(const String &p_alert, const String &p_title = "ALERT!") override;
- Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) override;
+ Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false, String *r_resolved_path = nullptr) override;
void resume_audio();
diff --git a/platform/javascript/package-lock.json b/platform/javascript/package-lock.json
index f72cde955a..f8c67b206f 100644
--- a/platform/javascript/package-lock.json
+++ b/platform/javascript/package-lock.json
@@ -109,6 +109,28 @@
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
"dev": true
},
+ "node_modules/@types/linkify-it": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz",
+ "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==",
+ "dev": true
+ },
+ "node_modules/@types/markdown-it": {
+ "version": "12.2.3",
+ "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz",
+ "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/linkify-it": "*",
+ "@types/mdurl": "*"
+ }
+ },
+ "node_modules/@types/mdurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz",
+ "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
+ "dev": true
+ },
"node_modules/@zeit/schemas": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.6.0.tgz",
@@ -658,10 +680,13 @@
}
},
"node_modules/entities": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz",
- "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==",
- "dev": true
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
+ "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
},
"node_modules/error-ex": {
"version": "1.3.2",
@@ -1637,34 +1662,35 @@
}
},
"node_modules/js2xmlparser": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz",
- "integrity": "sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz",
+ "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==",
"dev": true,
"dependencies": {
- "xmlcreate": "^2.0.3"
+ "xmlcreate": "^2.0.4"
}
},
"node_modules/jsdoc": {
- "version": "3.6.7",
- "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.7.tgz",
- "integrity": "sha512-sxKt7h0vzCd+3Y81Ey2qinupL6DpRSZJclS04ugHDNmRUXGzqicMJ6iwayhSA0S0DwwX30c5ozyUthr1QKF6uw==",
+ "version": "3.6.10",
+ "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.10.tgz",
+ "integrity": "sha512-IdQ8ppSo5LKZ9o3M+LKIIK8i00DIe5msDvG3G81Km+1dhy0XrOWD0Ji8H61ElgyEj/O9KRLokgKbAM9XX9CJAg==",
"dev": true,
"dependencies": {
"@babel/parser": "^7.9.4",
+ "@types/markdown-it": "^12.2.3",
"bluebird": "^3.7.2",
"catharsis": "^0.9.0",
"escape-string-regexp": "^2.0.0",
- "js2xmlparser": "^4.0.1",
- "klaw": "^3.0.0",
- "markdown-it": "^10.0.0",
- "markdown-it-anchor": "^5.2.7",
- "marked": "^2.0.3",
+ "js2xmlparser": "^4.0.2",
+ "klaw": "^4.0.1",
+ "markdown-it": "^12.3.2",
+ "markdown-it-anchor": "^8.4.1",
+ "marked": "^4.0.10",
"mkdirp": "^1.0.4",
"requizzle": "^0.2.3",
"strip-json-comments": "^3.1.0",
"taffydb": "2.6.2",
- "underscore": "~1.13.1"
+ "underscore": "~1.13.2"
},
"bin": {
"jsdoc": "jsdoc.js"
@@ -1713,12 +1739,12 @@
}
},
"node_modules/klaw": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz",
- "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-4.0.1.tgz",
+ "integrity": "sha512-pgsE40/SvC7st04AHiISNewaIMUbY5V/K8b21ekiPiFoYs/EYSdsGa+FJArB1d441uq4Q8zZyIxvAzkGNlBdRw==",
"dev": true,
- "dependencies": {
- "graceful-fs": "^4.1.9"
+ "engines": {
+ "node": ">=14.14.0"
}
},
"node_modules/levn": {
@@ -1735,9 +1761,9 @@
}
},
"node_modules/linkify-it": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
- "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
+ "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
"dev": true,
"dependencies": {
"uc.micro": "^1.0.1"
@@ -1808,14 +1834,14 @@
}
},
"node_modules/markdown-it": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz",
- "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==",
+ "version": "12.3.2",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
+ "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
"dev": true,
"dependencies": {
- "argparse": "^1.0.7",
- "entities": "~2.0.0",
- "linkify-it": "^2.0.0",
+ "argparse": "^2.0.1",
+ "entities": "~2.1.0",
+ "linkify-it": "^3.0.1",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
},
@@ -1824,24 +1850,31 @@
}
},
"node_modules/markdown-it-anchor": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz",
- "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==",
+ "version": "8.6.4",
+ "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.4.tgz",
+ "integrity": "sha512-Ul4YVYZNxMJYALpKtu+ZRdrryYt/GlQ5CK+4l1bp/gWXOG2QWElt6AqF3Mih/wfUKdZbNAZVXGR73/n6U/8img==",
"dev": true,
"peerDependencies": {
+ "@types/markdown-it": "*",
"markdown-it": "*"
}
},
+ "node_modules/markdown-it/node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ },
"node_modules/marked": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.7.tgz",
- "integrity": "sha512-BJXxkuIfJchcXOJWTT2DOL+yFWifFv2yGYOUzvXg8Qz610QKw+sHCvTMYwA+qWGhlA2uivBezChZ/pBy1tWdkQ==",
+ "version": "4.0.16",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.16.tgz",
+ "integrity": "sha512-wahonIQ5Jnyatt2fn8KqF/nIqZM8mh3oRu2+l5EANGMhu6RFjiSG52QNE2eWzFMI94HqYSgN184NurgNG6CztA==",
"dev": true,
"bin": {
- "marked": "bin/marked"
+ "marked": "bin/marked.js"
},
"engines": {
- "node": ">= 8.16.2"
+ "node": ">= 12"
}
},
"node_modules/mdurl": {
@@ -2834,9 +2867,9 @@
}
},
"node_modules/underscore": {
- "version": "1.13.1",
- "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz",
- "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.3.tgz",
+ "integrity": "sha512-QvjkYpiD+dJJraRA8+dGAU4i7aBbb2s0S3jA45TFOvg2VgqvdCDd/3N6CqA8gluk1W91GLoXg5enMUx560QzuA==",
"dev": true
},
"node_modules/update-check": {
@@ -2992,9 +3025,9 @@
"dev": true
},
"node_modules/xmlcreate": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz",
- "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==",
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz",
+ "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==",
"dev": true
},
"node_modules/yallist": {
@@ -3079,6 +3112,28 @@
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
"dev": true
},
+ "@types/linkify-it": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz",
+ "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==",
+ "dev": true
+ },
+ "@types/markdown-it": {
+ "version": "12.2.3",
+ "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz",
+ "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==",
+ "dev": true,
+ "requires": {
+ "@types/linkify-it": "*",
+ "@types/mdurl": "*"
+ }
+ },
+ "@types/mdurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz",
+ "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
+ "dev": true
+ },
"@zeit/schemas": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.6.0.tgz",
@@ -3493,9 +3548,9 @@
}
},
"entities": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz",
- "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
+ "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
"dev": true
},
"error-ex": {
@@ -4239,34 +4294,35 @@
}
},
"js2xmlparser": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz",
- "integrity": "sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz",
+ "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==",
"dev": true,
"requires": {
- "xmlcreate": "^2.0.3"
+ "xmlcreate": "^2.0.4"
}
},
"jsdoc": {
- "version": "3.6.7",
- "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.7.tgz",
- "integrity": "sha512-sxKt7h0vzCd+3Y81Ey2qinupL6DpRSZJclS04ugHDNmRUXGzqicMJ6iwayhSA0S0DwwX30c5ozyUthr1QKF6uw==",
+ "version": "3.6.10",
+ "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.10.tgz",
+ "integrity": "sha512-IdQ8ppSo5LKZ9o3M+LKIIK8i00DIe5msDvG3G81Km+1dhy0XrOWD0Ji8H61ElgyEj/O9KRLokgKbAM9XX9CJAg==",
"dev": true,
"requires": {
"@babel/parser": "^7.9.4",
+ "@types/markdown-it": "^12.2.3",
"bluebird": "^3.7.2",
"catharsis": "^0.9.0",
"escape-string-regexp": "^2.0.0",
- "js2xmlparser": "^4.0.1",
- "klaw": "^3.0.0",
- "markdown-it": "^10.0.0",
- "markdown-it-anchor": "^5.2.7",
- "marked": "^2.0.3",
+ "js2xmlparser": "^4.0.2",
+ "klaw": "^4.0.1",
+ "markdown-it": "^12.3.2",
+ "markdown-it-anchor": "^8.4.1",
+ "marked": "^4.0.10",
"mkdirp": "^1.0.4",
"requizzle": "^0.2.3",
"strip-json-comments": "^3.1.0",
"taffydb": "2.6.2",
- "underscore": "~1.13.1"
+ "underscore": "~1.13.2"
},
"dependencies": {
"escape-string-regexp": {
@@ -4305,13 +4361,10 @@
}
},
"klaw": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz",
- "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.9"
- }
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-4.0.1.tgz",
+ "integrity": "sha512-pgsE40/SvC7st04AHiISNewaIMUbY5V/K8b21ekiPiFoYs/EYSdsGa+FJArB1d441uq4Q8zZyIxvAzkGNlBdRw==",
+ "dev": true
},
"levn": {
"version": "0.4.1",
@@ -4324,9 +4377,9 @@
}
},
"linkify-it": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
- "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
+ "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
"dev": true,
"requires": {
"uc.micro": "^1.0.1"
@@ -4388,29 +4441,37 @@
}
},
"markdown-it": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz",
- "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==",
+ "version": "12.3.2",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
+ "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
"dev": true,
"requires": {
- "argparse": "^1.0.7",
- "entities": "~2.0.0",
- "linkify-it": "^2.0.0",
+ "argparse": "^2.0.1",
+ "entities": "~2.1.0",
+ "linkify-it": "^3.0.1",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
+ },
+ "dependencies": {
+ "argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ }
}
},
"markdown-it-anchor": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz",
- "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==",
+ "version": "8.6.4",
+ "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.4.tgz",
+ "integrity": "sha512-Ul4YVYZNxMJYALpKtu+ZRdrryYt/GlQ5CK+4l1bp/gWXOG2QWElt6AqF3Mih/wfUKdZbNAZVXGR73/n6U/8img==",
"dev": true,
"requires": {}
},
"marked": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.7.tgz",
- "integrity": "sha512-BJXxkuIfJchcXOJWTT2DOL+yFWifFv2yGYOUzvXg8Qz610QKw+sHCvTMYwA+qWGhlA2uivBezChZ/pBy1tWdkQ==",
+ "version": "4.0.16",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.16.tgz",
+ "integrity": "sha512-wahonIQ5Jnyatt2fn8KqF/nIqZM8mh3oRu2+l5EANGMhu6RFjiSG52QNE2eWzFMI94HqYSgN184NurgNG6CztA==",
"dev": true
},
"mdurl": {
@@ -5188,9 +5249,9 @@
}
},
"underscore": {
- "version": "1.13.1",
- "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz",
- "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.3.tgz",
+ "integrity": "sha512-QvjkYpiD+dJJraRA8+dGAU4i7aBbb2s0S3jA45TFOvg2VgqvdCDd/3N6CqA8gluk1W91GLoXg5enMUx560QzuA==",
"dev": true
},
"update-check": {
@@ -5315,9 +5376,9 @@
"dev": true
},
"xmlcreate": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz",
- "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==",
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz",
+ "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==",
"dev": true
},
"yallist": {
diff --git a/platform/javascript/package.json b/platform/javascript/package.json
index 2ff1544837..8c38bc89e8 100644
--- a/platform/javascript/package.json
+++ b/platform/javascript/package.json
@@ -15,7 +15,7 @@
"format:libs": "npm run lint:libs -- --fix",
"format:modules": "npm run lint:modules -- --fix",
"format:tools": "npm run lint:tools -- --fix",
- "serve": "serve"
+ "serve": "serve"
},
"author": "Godot Engine contributors",
"license": "MIT",
diff --git a/platform/javascript/platform_config.h b/platform/javascript/platform_config.h
index ba1b0d459e..1970fe0fa0 100644
--- a/platform/javascript/platform_config.h
+++ b/platform/javascript/platform_config.h
@@ -29,3 +29,5 @@
/*************************************************************************/
#include <alloca.h>
+
+#define OPENGL_INCLUDE_H "platform/javascript/godot_webgl2.h"