summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/display_server_android.cpp4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java6
-rw-r--r--platform/iphone/display_server_iphone.h2
-rw-r--r--platform/iphone/display_server_iphone.mm4
-rw-r--r--platform/iphone/os_iphone.h2
-rw-r--r--platform/iphone/os_iphone.mm2
-rw-r--r--platform/javascript/SCsub62
-rw-r--r--platform/javascript/detect.py25
-rw-r--r--platform/javascript/export/export.cpp106
-rw-r--r--platform/javascript/godot_audio.h2
-rw-r--r--platform/javascript/http_request.h2
-rw-r--r--platform/javascript/javascript_main.cpp2
-rw-r--r--platform/javascript/javascript_runtime.cpp35
-rw-r--r--platform/javascript/js/dynlink.pre.js1
-rw-r--r--platform/javascript/js/engine/engine.js13
-rw-r--r--platform/javascript/js/engine/utils.js2
-rw-r--r--platform/javascript/js/libs/library_godot_audio.js12
-rw-r--r--platform/javascript/js/libs/library_godot_display.js19
-rw-r--r--platform/javascript/js/libs/library_godot_editor_tools.js1
-rw-r--r--platform/javascript/js/libs/library_godot_eval.js1
-rw-r--r--platform/javascript/js/libs/library_godot_http_request.js15
-rw-r--r--platform/javascript/js/libs/library_godot_os.js9
-rw-r--r--platform/javascript/os_javascript.cpp24
-rw-r--r--platform/javascript/os_javascript.h1
-rw-r--r--platform/linuxbsd/display_server_x11.cpp7
-rw-r--r--platform/linuxbsd/display_server_x11.h2
-rw-r--r--platform/linuxbsd/os_linuxbsd.h2
-rw-r--r--platform/osx/display_server_osx.mm4
-rw-r--r--platform/osx/export/export.cpp35
-rw-r--r--platform/server/os_server.cpp4
-rw-r--r--platform/server/os_server.h2
-rw-r--r--platform/uwp/os_uwp.cpp4
-rw-r--r--platform/uwp/os_uwp.h2
-rw-r--r--platform/windows/detect.py17
-rw-r--r--platform/windows/display_server_windows.cpp2
-rw-r--r--platform/windows/display_server_windows.h4
-rw-r--r--platform/windows/joypad_windows.cpp2
-rw-r--r--platform/windows/os_windows.cpp2
-rw-r--r--platform/windows/os_windows.h2
39 files changed, 337 insertions, 106 deletions
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index aab5da4fde..c8ed44d699 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -41,7 +41,7 @@
#if defined(VULKAN_ENABLED)
#include "drivers/vulkan/rendering_device_vulkan.h"
#include "platform/android/vulkan/vulkan_context_android.h"
-#include "servers/rendering/rasterizer_rd/rasterizer_rd.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#endif
DisplayServerAndroid *DisplayServerAndroid::get_singleton() {
@@ -447,7 +447,7 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis
rendering_device_vulkan = memnew(RenderingDeviceVulkan);
rendering_device_vulkan->initialize(context_vulkan);
- RasterizerRD::make_current();
+ RendererCompositorRD::make_current();
}
#endif
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
index f3e985f944..6d5be312f1 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
@@ -181,6 +181,7 @@ public class GodotInputHandler implements InputDeviceListener {
arr[i * 3 + 2] = event.getY(i);
}
final int action = event.getActionMasked();
+ final int pointer_idx = event.getPointerId(event.getActionIndex());
mRenderView.queueOnRenderThread(new Runnable() {
@Override
@@ -189,12 +190,9 @@ public class GodotInputHandler implements InputDeviceListener {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_MOVE: {
- GodotLib.touch(event.getSource(), action, 0, evcount, arr);
- } break;
+ case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_POINTER_DOWN: {
- int pointer_idx = event.getPointerId(event.getActionIndex());
GodotLib.touch(event.getSource(), action, pointer_idx, evcount, arr);
} break;
}
diff --git a/platform/iphone/display_server_iphone.h b/platform/iphone/display_server_iphone.h
index 229b1e80db..2d77e9adff 100644
--- a/platform/iphone/display_server_iphone.h
+++ b/platform/iphone/display_server_iphone.h
@@ -36,7 +36,7 @@
#if defined(VULKAN_ENABLED)
#include "drivers/vulkan/rendering_device_vulkan.h"
-#include "servers/rendering/rasterizer_rd/rasterizer_rd.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "vulkan_context_iphone.h"
diff --git a/platform/iphone/display_server_iphone.mm b/platform/iphone/display_server_iphone.mm
index d47d131719..e8abf1e3fa 100644
--- a/platform/iphone/display_server_iphone.mm
+++ b/platform/iphone/display_server_iphone.mm
@@ -73,7 +73,7 @@ DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, Displ
// return ERR_UNAVAILABLE;
}
- // rendering_server = memnew(RenderingServerRaster);
+ // rendering_server = memnew(RenderingServerDefault);
// // FIXME: Reimplement threaded rendering
// if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
// rendering_server = memnew(RenderingServerWrapMT(rendering_server,
@@ -118,7 +118,7 @@ DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, Displ
rendering_device_vulkan = memnew(RenderingDeviceVulkan);
rendering_device_vulkan->initialize(context_vulkan);
- RasterizerRD::make_current();
+ RendererCompositorRD::make_current();
}
#endif
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index 04a0a478d5..e98f870ba9 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -38,7 +38,7 @@
#include "ios.h"
#include "joypad_iphone.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rasterizer.h"
+#include "servers/rendering/renderer_compositor.h"
#if defined(VULKAN_ENABLED)
#include "drivers/vulkan/rendering_device_vulkan.h"
diff --git a/platform/iphone/os_iphone.mm b/platform/iphone/os_iphone.mm
index b87e6f37a0..dac61f2d9d 100644
--- a/platform/iphone/os_iphone.mm
+++ b/platform/iphone/os_iphone.mm
@@ -47,7 +47,7 @@
#import <dlfcn.h>
#if defined(VULKAN_ENABLED)
-#include "servers/rendering/rasterizer_rd/rasterizer_rd.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#import <QuartzCore/CAMetalLayer.h>
#include <vulkan/vulkan_metal.h>
#endif
diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub
index 627ae778b1..59f3dce3ad 100644
--- a/platform/javascript/SCsub
+++ b/platform/javascript/SCsub
@@ -12,13 +12,8 @@ javascript_files = [
"api/javascript_tools_editor_plugin.cpp",
]
-build_targets = ["#bin/godot${PROGSUFFIX}.js", "#bin/godot${PROGSUFFIX}.wasm"]
-if env["threads_enabled"]:
- build_targets.append("#bin/godot${PROGSUFFIX}.worker.js")
-
-build = env.add_program(build_targets, javascript_files)
-
-env.AddJSLibraries(
+sys_env = env.Clone()
+sys_env.AddJSLibraries(
[
"js/libs/library_godot_audio.js",
"js/libs/library_godot_display.js",
@@ -29,12 +24,48 @@ env.AddJSLibraries(
)
if env["tools"]:
- env.AddJSLibraries(["js/libs/library_godot_editor_tools.js"])
+ sys_env.AddJSLibraries(["js/libs/library_godot_editor_tools.js"])
if env["javascript_eval"]:
- env.AddJSLibraries(["js/libs/library_godot_eval.js"])
-for lib in env["JS_LIBS"]:
- env.Append(LINKFLAGS=["--js-library", lib])
-env.Depends(build, env["JS_LIBS"])
+ sys_env.AddJSLibraries(["js/libs/library_godot_eval.js"])
+for lib in sys_env["JS_LIBS"]:
+ sys_env.Append(LINKFLAGS=["--js-library", lib])
+
+build = []
+if env["gdnative_enabled"]:
+ build_targets = ["#bin/godot${PROGSUFFIX}.js", "#bin/godot${PROGSUFFIX}.wasm"]
+ # 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.
+ sys_env.Append(LIBS=["idbfs.js"])
+ # JS prepended to the module code loading the side library.
+ sys_env.Append(LINKFLAGS=["--pre-js", sys_env.File("js/dynlink.pre.js")])
+ # Configure it as a main module (dynamic linking support).
+ sys_env.Append(CCFLAGS=["-s", "MAIN_MODULE=1"])
+ sys_env.Append(LINKFLAGS=["-s", "MAIN_MODULE=1"])
+ sys_env.Append(CCFLAGS=["-s", "EXPORT_ALL=1"])
+ sys_env.Append(LINKFLAGS=["-s", "EXPORT_ALL=1"])
+ # Force exporting the standard library (printf, malloc, etc.)
+ sys_env["ENV"]["EMCC_FORCE_STDLIBS"] = "libc,libc++,libc++abi"
+ # The main emscripten runtime, with exported standard libraries.
+ sys = sys_env.Program(build_targets, ["javascript_runtime.cpp"])
+ sys_env.Depends(sys, "js/dynlink.pre.js")
+
+ # The side library, containing all Godot code.
+ wasm_env = env.Clone()
+ wasm_env.Append(CPPDEFINES=["WASM_GDNATIVE"]) # So that OS knows it can run GDNative libraries.
+ 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]]
+else:
+ build_targets = ["#bin/godot${PROGSUFFIX}.js", "#bin/godot${PROGSUFFIX}.wasm"]
+ if env["threads_enabled"]:
+ build_targets.append("#bin/godot${PROGSUFFIX}.worker.js")
+ # We use IDBFS. Since Emscripten 1.39.1 it needs to be linked explicitly.
+ sys_env.Append(LIBS=["idbfs.js"])
+ build = sys_env.Program(build_targets, javascript_files + ["javascript_runtime.cpp"])
+
+sys_env.Depends(build[0], sys_env["JS_LIBS"])
engine = [
"js/engine/preloader.js",
@@ -61,8 +92,11 @@ out_files = [
]
html_file = "#misc/dist/html/editor.html" if env["tools"] else "#misc/dist/html/full-size.html"
in_files = [js_wrapped, build[1], html_file, "#platform/javascript/js/libs/audio.worklet.js"]
-if env["threads_enabled"]:
- in_files.append(build[2])
+if env["gdnative_enabled"]:
+ in_files.append(build[2]) # Runtime
+ out_files.append(zip_dir.File(binary_name + ".side.wasm"))
+elif env["threads_enabled"]:
+ in_files.append(build[2]) # Worker
out_files.append(zip_dir.File(binary_name + ".worker.js"))
zip_files = env.InstallAs(out_files, in_files)
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index 9f584d0899..f4fa5fb218 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -23,6 +23,7 @@ def get_opts():
# eval() can be a security concern, so it can be disabled.
BoolVariable("javascript_eval", "Enable JavaScript eval interface", True),
BoolVariable("threads_enabled", "Enable WebAssembly Threads support (limited browser support)", False),
+ BoolVariable("gdnative_enabled", "Enable WebAssembly GDNative support (produces bigger binaries)", False),
BoolVariable("use_closure_compiler", "Use closure compiler to minimize JavaScript code", False),
]
@@ -85,10 +86,8 @@ def configure(env):
# LTO
if env["use_lto"]:
- env.Append(CCFLAGS=["-s", "WASM_OBJECT_FILES=0"])
- env.Append(LINKFLAGS=["-s", "WASM_OBJECT_FILES=0"])
- env.Append(CCFLAGS=["-flto"])
- env.Append(LINKFLAGS=["-flto"])
+ env.Append(CCFLAGS=["-flto=full"])
+ env.Append(LINKFLAGS=["-flto=full"])
# Closure compiler
if env["use_closure_compiler"]:
@@ -135,6 +134,9 @@ def configure(env):
if env["javascript_eval"]:
env.Append(CPPDEFINES=["JAVASCRIPT_EVAL_ENABLED"])
+ if env["threads_enabled"] and env["gdnative_enabled"]:
+ raise Exception("Threads and GDNative support can't be both enabled due to WebAssembly limitations")
+
# Thread support (via SharedArrayBuffer).
if env["threads_enabled"]:
env.Append(CPPDEFINES=["PTHREAD_NO_RENAME"])
@@ -146,14 +148,15 @@ def configure(env):
else:
env.Append(CPPDEFINES=["NO_THREADS"])
+ if env["gdnative_enabled"]:
+ env.Append(CCFLAGS=["-s", "RELOCATABLE=1"])
+ env.Append(LINKFLAGS=["-s", "RELOCATABLE=1"])
+ env.extra_suffix = ".gdnative" + env.extra_suffix
+
# Reduce code size by generating less support code (e.g. skip NodeJS support).
env.Append(LINKFLAGS=["-s", "ENVIRONMENT=web,worker"])
- # We use IDBFS in javascript_main.cpp. Since Emscripten 1.39.1 it needs to
- # be linked explicitly.
- env.Append(LIBS=["idbfs.js"])
-
- env.Append(LINKFLAGS=["-s", "BINARYEN=1"])
+ # Wrap the JavaScript support code around a closure named Godot.
env.Append(LINKFLAGS=["-s", "MODULARIZE=1", "-s", "EXPORT_NAME='Godot'"])
# Allow increasing memory buffer size during runtime. This is efficient
@@ -164,12 +167,14 @@ def configure(env):
# This setting just makes WebGL 2 APIs available, it does NOT disable WebGL 1.
env.Append(LINKFLAGS=["-s", "USE_WEBGL2=1"])
+ # Do not call main immediately when the support code is ready.
env.Append(LINKFLAGS=["-s", "INVOKE_RUN=0"])
# Allow use to take control of swapping WebGL buffers.
env.Append(LINKFLAGS=["-s", "OFFSCREEN_FRAMEBUFFER=1"])
- # callMain for manual start, FS for preloading, PATH and ERRNO_CODES for BrowserFS.
+ # callMain for manual start.
env.Append(LINKFLAGS=["-s", "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']"])
+
# Add code that allow exiting runtime.
env.Append(LINKFLAGS=["-s", "EXIT_RUNTIME=1"])
diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp
index c3b7e0304e..f77bf6ab97 100644
--- a/platform/javascript/export/export.cpp
+++ b/platform/javascript/export/export.cpp
@@ -85,36 +85,44 @@ public:
// Wrong protocol
ERR_FAIL_COND_MSG(req[0] != "GET" || req[2] != "HTTP/1.1", "Invalid method or HTTP version.");
- String filepath = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_js_export");
+ const String cache_path = EditorSettings::get_singleton()->get_cache_dir();
const String basereq = "/tmp_js_export";
- String ctype = "";
+ String filepath;
+ String ctype;
if (req[1] == basereq + ".html") {
- filepath += ".html";
+ filepath = cache_path.plus_file(req[1].get_file());
ctype = "text/html";
} else if (req[1] == basereq + ".js") {
- filepath += ".js";
+ filepath = cache_path.plus_file(req[1].get_file());
ctype = "application/javascript";
} else if (req[1] == basereq + ".audio.worklet.js") {
- filepath += ".audio.worklet.js";
+ filepath = cache_path.plus_file(req[1].get_file());
ctype = "application/javascript";
} else if (req[1] == basereq + ".worker.js") {
- filepath += ".worker.js";
+ filepath = cache_path.plus_file(req[1].get_file());
ctype = "application/javascript";
} else if (req[1] == basereq + ".pck") {
- filepath += ".pck";
+ filepath = cache_path.plus_file(req[1].get_file());
ctype = "application/octet-stream";
} else if (req[1] == basereq + ".png" || req[1] == "/favicon.png") {
// Also allow serving the generated favicon for a smoother loading experience.
if (req[1] == "/favicon.png") {
filepath = EditorSettings::get_singleton()->get_cache_dir().plus_file("favicon.png");
} else {
- filepath += ".png";
+ filepath = basereq + ".png";
}
ctype = "image/png";
+ } else if (req[1] == basereq + ".side.wasm") {
+ filepath = cache_path.plus_file(req[1].get_file());
+ ctype = "application/wasm";
} else if (req[1] == basereq + ".wasm") {
- filepath += ".wasm";
+ filepath = cache_path.plus_file(req[1].get_file());
ctype = "application/wasm";
- } else {
+ } else if (req[1].ends_with(".wasm")) {
+ filepath = cache_path.plus_file(req[1].get_file()); // TODO dangerous?
+ ctype = "application/wasm";
+ }
+ if (filepath.empty() || !FileAccess::exists(filepath)) {
String s = "HTTP/1.1 404 Not Found\r\n";
s += "Connection: Close\r\n";
s += "\r\n";
@@ -205,7 +213,33 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform {
Ref<ImageTexture> stop_icon;
int menu_options;
- void _fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, int p_flags);
+ enum ExportMode {
+ EXPORT_MODE_NORMAL = 0,
+ EXPORT_MODE_THREADS = 1,
+ EXPORT_MODE_GDNATIVE = 2,
+ };
+
+ 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_debug) {
+ name += "_debug.zip";
+ } else {
+ name += "_release.zip";
+ }
+ return name;
+ }
+
+ 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);
private:
Ref<EditorHTTPServer> server;
@@ -250,7 +284,7 @@ public:
~EditorExportPlatformJavaScript();
};
-void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, int p_flags) {
+void EditorExportPlatformJavaScript::_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) {
String str_template = String::utf8(reinterpret_cast<const char *>(p_html.ptr()), p_html.size());
String str_export;
Vector<String> lines = str_template.split("\n");
@@ -258,6 +292,10 @@ void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Re
String flags_json;
gen_export_flags(flags, p_flags);
flags_json = JSON::print(flags);
+ String libs;
+ for (int i = 0; i < p_shared_objects.size(); i++) {
+ libs += "\"" + p_shared_objects[i].path.get_file() + "\",";
+ }
for (int i = 0; i < lines.size(); i++) {
String current_line = lines[i];
@@ -265,6 +303,7 @@ void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Re
current_line = current_line.replace("$GODOT_PROJECT_NAME", ProjectSettings::get_singleton()->get_setting("application/config/name"));
current_line = current_line.replace("$GODOT_HEAD_INCLUDE", p_preset->get("html/head_include"));
current_line = current_line.replace("$GODOT_FULL_WINDOW", p_preset->get("html/full_window_size") ? "true" : "false");
+ current_line = current_line.replace("$GODOT_GDNATIVE_LIBS", libs);
current_line = current_line.replace("$GODOT_DEBUG_ENABLED", p_debug ? "true" : "false");
current_line = current_line.replace("$GODOT_ARGS", flags_json);
str_export += current_line + "\n";
@@ -291,12 +330,19 @@ void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportP
r_features->push_back("etc2");
}
}
+ ExportMode mode = (ExportMode)(int)p_preset->get("variant/export_type");
+ if (mode == EXPORT_MODE_THREADS) {
+ r_features->push_back("threads");
+ } else if (mode == EXPORT_MODE_GDNATIVE) {
+ r_features->push_back("wasm32");
+ }
}
void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_options) {
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "variant/export_type", PROPERTY_HINT_ENUM, "Regular,Threads,GDNative"), 0)); // Export type.
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "vram_texture_compression/for_desktop"), true)); // S3TC
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "vram_texture_compression/for_mobile"), false)); // ETC or ETC2, depending on renderer
@@ -320,11 +366,11 @@ Ref<Texture2D> EditorExportPlatformJavaScript::get_logo() const {
bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
String err;
bool valid = false;
+ ExportMode mode = (ExportMode)(int)p_preset->get("variant/export_type");
// Look for export templates (first official, and if defined custom templates).
-
- bool dvalid = exists_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG, &err);
- bool rvalid = exists_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE, &err);
+ bool dvalid = exists_export_template(_get_template_name(mode, true), &err);
+ bool rvalid = exists_export_template(_get_template_name(mode, false), &err);
if (p_preset->get("custom_template/debug") != "") {
dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
@@ -377,11 +423,8 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
template_path = template_path.strip_edges();
if (template_path == String()) {
- if (p_debug) {
- template_path = find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG);
- } else {
- template_path = find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE);
- }
+ ExportMode mode = (ExportMode)(int)p_preset->get("variant/export_type");
+ template_path = find_export_template(_get_template_name(mode, p_debug));
}
if (!DirAccess::exists(p_path.get_base_dir())) {
@@ -393,12 +436,24 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
return ERR_FILE_NOT_FOUND;
}
+ Vector<SharedObject> shared_objects;
String pck_path = p_path.get_basename() + ".pck";
- Error error = save_pack(p_preset, pck_path);
+ Error error = save_pack(p_preset, pck_path, &shared_objects);
if (error != OK) {
EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + pck_path);
return error;
}
+ DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ for (int i = 0; i < shared_objects.size(); i++) {
+ String dst = p_path.get_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());
+ memdelete(da);
+ return error;
+ }
+ }
+ memdelete(da);
FileAccess *src_f = nullptr;
zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
@@ -437,14 +492,18 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
if (!custom_html.empty()) {
continue;
}
- _fix_html(data, p_preset, p_path.get_file().get_basename(), p_debug, p_flags);
+ _fix_html(data, p_preset, p_path.get_file().get_basename(), p_debug, p_flags, shared_objects);
file = p_path.get_file();
} else if (file == "godot.js") {
file = p_path.get_file().get_basename() + ".js";
+
} else if (file == "godot.worker.js") {
file = p_path.get_file().get_basename() + ".worker.js";
+ } else if (file == "godot.side.wasm") {
+ file = p_path.get_file().get_basename() + ".side.wasm";
+
} else if (file == "godot.audio.worklet.js") {
file = p_path.get_file().get_basename() + ".audio.worklet.js";
@@ -475,7 +534,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
buf.resize(f->get_len());
f->get_buffer(buf.ptrw(), buf.size());
memdelete(f);
- _fix_html(buf, p_preset, p_path.get_file().get_basename(), p_debug, p_flags);
+ _fix_html(buf, p_preset, p_path.get_file().get_basename(), p_debug, p_flags, shared_objects);
f = FileAccess::open(p_path, FileAccess::WRITE);
if (!f) {
@@ -577,6 +636,7 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese
DirAccess::remove_file_or_error(basepath + ".audio.worklet.js");
DirAccess::remove_file_or_error(basepath + ".pck");
DirAccess::remove_file_or_error(basepath + ".png");
+ DirAccess::remove_file_or_error(basepath + ".side.wasm");
DirAccess::remove_file_or_error(basepath + ".wasm");
DirAccess::remove_file_or_error(EditorSettings::get_singleton()->get_cache_dir().plus_file("favicon.png"));
return err;
diff --git a/platform/javascript/godot_audio.h b/platform/javascript/godot_audio.h
index 7ebda3ad39..0ba6849715 100644
--- a/platform/javascript/godot_audio.h
+++ b/platform/javascript/godot_audio.h
@@ -48,7 +48,7 @@ extern void godot_audio_capture_stop();
typedef int32_t GodotAudioState[4];
extern void godot_audio_worklet_create(int p_channels);
extern void godot_audio_worklet_start(float *p_in_buf, int p_in_size, float *p_out_buf, int p_out_size, GodotAudioState p_state);
-extern void godot_audio_worklet_state_add(GodotAudioState p_state, int p_idx, int p_value);
+extern int godot_audio_worklet_state_add(GodotAudioState p_state, int p_idx, int p_value);
extern int godot_audio_worklet_state_get(GodotAudioState p_state, int p_idx);
extern int godot_audio_worklet_state_wait(int32_t *p_state, int p_idx, int32_t p_expected, int p_timeout);
diff --git a/platform/javascript/http_request.h b/platform/javascript/http_request.h
index 54e98c1927..41e4749216 100644
--- a/platform/javascript/http_request.h
+++ b/platform/javascript/http_request.h
@@ -47,7 +47,7 @@ typedef enum {
extern int godot_xhr_new();
extern void godot_xhr_reset(int p_xhr_id);
-extern bool godot_xhr_free(int p_xhr_id);
+extern void godot_xhr_free(int p_xhr_id);
extern int godot_xhr_open(int p_xhr_id, const char *p_method, const char *p_url, const char *p_user = nullptr, const char *p_password = nullptr);
diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp
index 2d28a63566..b4985a4f36 100644
--- a/platform/javascript/javascript_main.cpp
+++ b/platform/javascript/javascript_main.cpp
@@ -75,7 +75,7 @@ void main_loop_callback() {
}
/// When calling main, it is assumed FS is setup and synced.
-int main(int argc, char *argv[]) {
+extern EMSCRIPTEN_KEEPALIVE int godot_js_main(int argc, char *argv[]) {
os = new OS_JavaScript();
// We must override main when testing is enabled
diff --git a/platform/javascript/javascript_runtime.cpp b/platform/javascript/javascript_runtime.cpp
new file mode 100644
index 0000000000..bfe9fbd1bc
--- /dev/null
+++ b/platform/javascript/javascript_runtime.cpp
@@ -0,0 +1,35 @@
+/*************************************************************************/
+/* javascript_runtime.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 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. */
+/*************************************************************************/
+
+extern int godot_js_main(int argc, char *argv[]);
+
+int main(int argc, char *argv[]) {
+ return godot_js_main(argc, argv);
+}
diff --git a/platform/javascript/js/dynlink.pre.js b/platform/javascript/js/dynlink.pre.js
new file mode 100644
index 0000000000..34bc371ea9
--- /dev/null
+++ b/platform/javascript/js/dynlink.pre.js
@@ -0,0 +1 @@
+Module['dynamicLibraries'] = [Module['thisProgram'] + '.side.wasm'].concat(Module['dynamicLibraries'] ? Module['dynamicLibraries'] : []);
diff --git a/platform/javascript/js/engine/engine.js b/platform/javascript/js/engine/engine.js
index 74153b672a..4b8a7dde69 100644
--- a/platform/javascript/js/engine/engine.js
+++ b/platform/javascript/js/engine/engine.js
@@ -34,6 +34,7 @@ const Engine = (function () {
this.onExecute = null;
this.onExit = null;
this.persistentPaths = ['/userfs'];
+ this.gdnativeLibs = [];
}
Engine.prototype.init = /** @param {string=} basePath */ function (basePath) {
@@ -58,6 +59,10 @@ const Engine = (function () {
initPromise = new Promise(function (resolve, reject) {
config['locateFile'] = Utils.createLocateRewrite(loadPath);
config['instantiateWasm'] = Utils.createInstantiatePromise(loadPromise);
+ // Emscripten configuration.
+ config['thisProgram'] = me.executableName;
+ config['noExitRuntime'] = true;
+ config['dynamicLibraries'] = me.gdnativeLibs;
Godot(config).then(function (module) {
module['initFS'](me.persistentPaths).then(function (fs_err) {
me.rtenv = module;
@@ -119,9 +124,6 @@ const Engine = (function () {
locale = navigator.languages ? navigator.languages[0] : navigator.language;
locale = locale.split('.')[0];
}
- // Emscripten configuration.
- me.rtenv['thisProgram'] = me.executableName;
- me.rtenv['noExitRuntime'] = true;
// Godot configuration.
me.rtenv['initConfig']({
'resizeCanvasOnStart': me.resizeCanvasOnStart,
@@ -249,6 +251,10 @@ const Engine = (function () {
this.persistentPaths = persistentPaths;
};
+ Engine.prototype.setGDNativeLibraries = function (gdnativeLibs) {
+ this.gdnativeLibs = gdnativeLibs;
+ };
+
Engine.prototype.requestQuit = function () {
if (this.rtenv) {
this.rtenv['request_quit']();
@@ -277,6 +283,7 @@ const Engine = (function () {
Engine.prototype['setOnExit'] = Engine.prototype.setOnExit;
Engine.prototype['copyToFS'] = Engine.prototype.copyToFS;
Engine.prototype['setPersistentPaths'] = Engine.prototype.setPersistentPaths;
+ Engine.prototype['setGDNativeLibraries'] = Engine.prototype.setGDNativeLibraries;
Engine.prototype['requestQuit'] = Engine.prototype.requestQuit;
return Engine;
}());
diff --git a/platform/javascript/js/engine/utils.js b/platform/javascript/js/engine/utils.js
index d0fca4e1cb..9273bbad42 100644
--- a/platform/javascript/js/engine/utils.js
+++ b/platform/javascript/js/engine/utils.js
@@ -8,6 +8,8 @@ const Utils = { // eslint-disable-line no-unused-vars
return `${execName}.audio.worklet.js`;
} else if (path.endsWith('.js')) {
return `${execName}.js`;
+ } else if (path.endsWith('.side.wasm')) {
+ return `${execName}.side.wasm`;
} else if (path.endsWith('.wasm')) {
return `${execName}.wasm`;
}
diff --git a/platform/javascript/js/libs/library_godot_audio.js b/platform/javascript/js/libs/library_godot_audio.js
index 0c1f477f34..416e987513 100644
--- a/platform/javascript/js/libs/library_godot_audio.js
+++ b/platform/javascript/js/libs/library_godot_audio.js
@@ -137,6 +137,7 @@ const GodotAudio = {
},
},
+ godot_audio_is_available__sig: 'i',
godot_audio_is_available__proxy: 'sync',
godot_audio_is_available: function () {
if (!(window.AudioContext || window.webkitAudioContext)) {
@@ -145,12 +146,14 @@ const GodotAudio = {
return 1;
},
+ godot_audio_init__sig: 'iiiii',
godot_audio_init: function (p_mix_rate, p_latency, p_state_change, p_latency_update) {
const statechange = GodotRuntime.get_func(p_state_change);
const latencyupdate = GodotRuntime.get_func(p_latency_update);
return GodotAudio.init(p_mix_rate, p_latency, statechange, latencyupdate);
},
+ godot_audio_resume__sig: 'v',
godot_audio_resume: function () {
if (GodotAudio.ctx && GodotAudio.ctx.state !== 'running') {
GodotAudio.ctx.resume();
@@ -158,6 +161,7 @@ const GodotAudio = {
},
godot_audio_capture_start__proxy: 'sync',
+ godot_audio_capture_start__sig: 'v',
godot_audio_capture_start: function () {
if (GodotAudio.input) {
return; // Already started.
@@ -168,6 +172,7 @@ const GodotAudio = {
},
godot_audio_capture_stop__proxy: 'sync',
+ godot_audio_capture_stop__sig: 'v',
godot_audio_capture_stop: function () {
if (GodotAudio.input) {
const tracks = GodotAudio.input['mediaStream']['getTracks']();
@@ -241,10 +246,12 @@ const GodotAudioWorklet = {
},
},
+ godot_audio_worklet_create__sig: 'vi',
godot_audio_worklet_create: function (channels) {
GodotAudioWorklet.create(channels);
},
+ godot_audio_worklet_start__sig: 'viiiii',
godot_audio_worklet_start: function (p_in_buf, p_in_size, p_out_buf, p_out_size, p_state) {
const out_buffer = GodotRuntime.heapSub(HEAPF32, p_out_buf, p_out_size);
const in_buffer = GodotRuntime.heapSub(HEAPF32, p_in_buf, p_in_size);
@@ -252,15 +259,18 @@ const GodotAudioWorklet = {
GodotAudioWorklet.start(in_buffer, out_buffer, state);
},
+ godot_audio_worklet_state_wait__sig: 'iiii',
godot_audio_worklet_state_wait: function (p_state, p_idx, p_expected, p_timeout) {
Atomics.wait(HEAP32, (p_state >> 2) + p_idx, p_expected, p_timeout);
return Atomics.load(HEAP32, (p_state >> 2) + p_idx);
},
+ godot_audio_worklet_state_add__sig: 'iiii',
godot_audio_worklet_state_add: function (p_state, p_idx, p_value) {
return Atomics.add(HEAP32, (p_state >> 2) + p_idx, p_value);
},
+ godot_audio_worklet_state_get__sig: 'iii',
godot_audio_worklet_state_get: function (p_state, p_idx) {
return Atomics.load(HEAP32, (p_state >> 2) + p_idx);
},
@@ -330,10 +340,12 @@ const GodotAudioScript = {
},
},
+ godot_audio_script_create__sig: 'iii',
godot_audio_script_create: function (buffer_length, channel_count) {
return GodotAudioScript.create(buffer_length, channel_count);
},
+ godot_audio_script_start__sig: 'viiiii',
godot_audio_script_start: function (p_in_buf, p_in_size, p_out_buf, p_out_size, p_cb) {
const onprocess = GodotRuntime.get_func(p_cb);
GodotAudioScript.start(p_in_buf, p_in_size, p_out_buf, p_out_size, onprocess);
diff --git a/platform/javascript/js/libs/library_godot_display.js b/platform/javascript/js/libs/library_godot_display.js
index 9651b48952..800d6f414f 100644
--- a/platform/javascript/js/libs/library_godot_display.js
+++ b/platform/javascript/js/libs/library_godot_display.js
@@ -280,6 +280,7 @@ const GodotDisplay = {
window_icon: '',
},
+ godot_js_display_is_swap_ok_cancel__sig: 'i',
godot_js_display_is_swap_ok_cancel: function () {
const win = (['Windows', 'Win64', 'Win32', 'WinCE']);
const plat = navigator.platform || '';
@@ -289,10 +290,12 @@ const GodotDisplay = {
return 0;
},
+ godot_js_display_alert__sig: 'vi',
godot_js_display_alert: function (p_text) {
window.alert(GodotRuntime.parseString(p_text)); // eslint-disable-line no-alert
},
+ godot_js_display_pixel_ratio_get__sig: 'f',
godot_js_display_pixel_ratio_get: function () {
return window.devicePixelRatio || 1;
},
@@ -300,14 +303,17 @@ const GodotDisplay = {
/*
* Canvas
*/
+ godot_js_display_canvas_focus__sig: 'v',
godot_js_display_canvas_focus: function () {
GodotConfig.canvas.focus();
},
+ godot_js_display_canvas_is_focused__sig: 'i',
godot_js_display_canvas_is_focused: function () {
return document.activeElement === GodotConfig.canvas;
},
+ godot_js_display_canvas_bounding_rect_position_get__sig: 'vii',
godot_js_display_canvas_bounding_rect_position_get: function (r_x, r_y) {
const brect = GodotConfig.canvas.getBoundingClientRect();
GodotRuntime.setHeapValue(r_x, brect.x, 'i32');
@@ -317,6 +323,7 @@ const GodotDisplay = {
/*
* Touchscreen
*/
+ godot_js_display_touchscreen_is_available__sig: 'i',
godot_js_display_touchscreen_is_available: function () {
return 'ontouchstart' in window;
},
@@ -324,6 +331,7 @@ const GodotDisplay = {
/*
* Clipboard
*/
+ godot_js_display_clipboard_set__sig: 'ii',
godot_js_display_clipboard_set: function (p_text) {
const text = GodotRuntime.parseString(p_text);
if (!navigator.clipboard || !navigator.clipboard.writeText) {
@@ -336,6 +344,7 @@ const GodotDisplay = {
return 0;
},
+ godot_js_display_clipboard_get__sig: 'ii',
godot_js_display_clipboard_get: function (callback) {
const func = GodotRuntime.get_func(callback);
try {
@@ -354,6 +363,7 @@ const GodotDisplay = {
/*
* Window
*/
+ godot_js_display_window_request_fullscreen__sig: 'v',
godot_js_display_window_request_fullscreen: function () {
const canvas = GodotConfig.canvas;
(canvas.requestFullscreen || canvas.msRequestFullscreen
@@ -362,10 +372,12 @@ const GodotDisplay = {
).call(canvas);
},
+ godot_js_display_window_title_set__sig: 'vi',
godot_js_display_window_title_set: function (p_data) {
document.title = GodotRuntime.parseString(p_data);
},
+ godot_js_display_window_icon_set__sig: 'vii',
godot_js_display_window_icon_set: function (p_ptr, p_len) {
let link = document.getElementById('-gd-engine-icon');
if (link === null) {
@@ -386,6 +398,7 @@ const GodotDisplay = {
/*
* Cursor
*/
+ godot_js_display_cursor_set_visible__sig: 'vi',
godot_js_display_cursor_set_visible: function (p_visible) {
const visible = p_visible !== 0;
if (visible === GodotDisplayCursor.visible) {
@@ -399,14 +412,17 @@ const GodotDisplay = {
}
},
+ godot_js_display_cursor_is_hidden__sig: 'i',
godot_js_display_cursor_is_hidden: function () {
return !GodotDisplayCursor.visible;
},
+ godot_js_display_cursor_set_shape__sig: 'vi',
godot_js_display_cursor_set_shape: function (p_string) {
GodotDisplayCursor.set_shape(GodotRuntime.parseString(p_string));
},
+ godot_js_display_cursor_set_custom_shape__sig: 'viiiii',
godot_js_display_cursor_set_custom_shape: function (p_shape, p_ptr, p_len, p_hotspot_x, p_hotspot_y) {
const shape = GodotRuntime.parseString(p_shape);
const old_shape = GodotDisplayCursor.cursors[shape];
@@ -432,6 +448,7 @@ const GodotDisplay = {
/*
* Listeners
*/
+ godot_js_display_notification_cb__sig: 'viiiii',
godot_js_display_notification_cb: function (callback, p_enter, p_exit, p_in, p_out) {
const canvas = GodotConfig.canvas;
const func = GodotRuntime.get_func(callback);
@@ -443,6 +460,7 @@ const GodotDisplay = {
});
},
+ godot_js_display_paste_cb__sig: 'vi',
godot_js_display_paste_cb: function (callback) {
const func = GodotRuntime.get_func(callback);
GodotDisplayListeners.add(window, 'paste', function (evt) {
@@ -453,6 +471,7 @@ const GodotDisplay = {
}, false);
},
+ godot_js_display_drop_files_cb__sig: 'vi',
godot_js_display_drop_files_cb: function (callback) {
const func = GodotRuntime.get_func(callback);
const dropFiles = function (files) {
diff --git a/platform/javascript/js/libs/library_godot_editor_tools.js b/platform/javascript/js/libs/library_godot_editor_tools.js
index f39fed04a8..12edc8e733 100644
--- a/platform/javascript/js/libs/library_godot_editor_tools.js
+++ b/platform/javascript/js/libs/library_godot_editor_tools.js
@@ -30,6 +30,7 @@
const GodotEditorTools = {
godot_js_editor_download_file__deps: ['$FS'],
+ godot_js_editor_download_file__sig: 'viii',
godot_js_editor_download_file: function (p_path, p_name, p_mime) {
const path = GodotRuntime.parseString(p_path);
const name = GodotRuntime.parseString(p_name);
diff --git a/platform/javascript/js/libs/library_godot_eval.js b/platform/javascript/js/libs/library_godot_eval.js
index 33ff231726..1a2440dd24 100644
--- a/platform/javascript/js/libs/library_godot_eval.js
+++ b/platform/javascript/js/libs/library_godot_eval.js
@@ -30,6 +30,7 @@
const GodotEval = {
godot_js_eval__deps: ['$GodotRuntime'],
+ godot_js_eval__sig: 'iiiiiii',
godot_js_eval: function (p_js, p_use_global_ctx, p_union_ptr, p_byte_arr, p_byte_arr_write, p_callback) {
const js_code = GodotRuntime.parseString(p_js);
let eval_ret = null;
diff --git a/platform/javascript/js/libs/library_godot_http_request.js b/platform/javascript/js/libs/library_godot_http_request.js
index 2b9aa88208..d4468bd5aa 100644
--- a/platform/javascript/js/libs/library_godot_http_request.js
+++ b/platform/javascript/js/libs/library_godot_http_request.js
@@ -50,6 +50,7 @@ const GodotHTTPRequest = {
},
},
+ godot_xhr_new__sig: 'i',
godot_xhr_new: function () {
const newId = GodotHTTPRequest.getUnusedRequestId();
GodotHTTPRequest.requests[newId] = new XMLHttpRequest();
@@ -57,30 +58,36 @@ const GodotHTTPRequest = {
return newId;
},
+ godot_xhr_reset__sig: 'vi',
godot_xhr_reset: function (xhrId) {
GodotHTTPRequest.requests[xhrId] = new XMLHttpRequest();
GodotHTTPRequest.setupRequest(GodotHTTPRequest.requests[xhrId]);
},
+ godot_xhr_free__sig: 'vi',
godot_xhr_free: function (xhrId) {
GodotHTTPRequest.requests[xhrId].abort();
GodotHTTPRequest.requests[xhrId] = null;
},
+ godot_xhr_open__sig: 'viiiii',
godot_xhr_open: function (xhrId, method, url, p_user, p_password) {
const user = p_user > 0 ? GodotRuntime.parseString(p_user) : null;
const password = p_password > 0 ? GodotRuntime.parseString(p_password) : null;
GodotHTTPRequest.requests[xhrId].open(GodotRuntime.parseString(method), GodotRuntime.parseString(url), true, user, password);
},
+ godot_xhr_set_request_header__sig: 'viii',
godot_xhr_set_request_header: function (xhrId, header, value) {
GodotHTTPRequest.requests[xhrId].setRequestHeader(GodotRuntime.parseString(header), GodotRuntime.parseString(value));
},
+ godot_xhr_send_null__sig: 'vi',
godot_xhr_send_null: function (xhrId) {
GodotHTTPRequest.requests[xhrId].send();
},
+ godot_xhr_send_string__sig: 'vii',
godot_xhr_send_string: function (xhrId, strPtr) {
if (!strPtr) {
GodotRuntime.error('Failed to send string per XHR: null pointer');
@@ -89,6 +96,7 @@ const GodotHTTPRequest = {
GodotHTTPRequest.requests[xhrId].send(GodotRuntime.parseString(strPtr));
},
+ godot_xhr_send_data__sig: 'viii',
godot_xhr_send_data: function (xhrId, ptr, len) {
if (!ptr) {
GodotRuntime.error('Failed to send data per XHR: null pointer');
@@ -101,23 +109,28 @@ const GodotHTTPRequest = {
GodotHTTPRequest.requests[xhrId].send(HEAPU8.subarray(ptr, ptr + len));
},
+ godot_xhr_abort__sig: 'vi',
godot_xhr_abort: function (xhrId) {
GodotHTTPRequest.requests[xhrId].abort();
},
+ godot_xhr_get_status__sig: 'ii',
godot_xhr_get_status: function (xhrId) {
return GodotHTTPRequest.requests[xhrId].status;
},
+ godot_xhr_get_ready_state__sig: 'ii',
godot_xhr_get_ready_state: function (xhrId) {
return GodotHTTPRequest.requests[xhrId].readyState;
},
+ godot_xhr_get_response_headers_length__sig: 'ii',
godot_xhr_get_response_headers_length: function (xhrId) {
const headers = GodotHTTPRequest.requests[xhrId].getAllResponseHeaders();
return headers === null ? 0 : GodotRuntime.strlen(headers);
},
+ godot_xhr_get_response_headers__sig: 'viii',
godot_xhr_get_response_headers: function (xhrId, dst, len) {
const str = GodotHTTPRequest.requests[xhrId].getAllResponseHeaders();
if (str === null) {
@@ -126,11 +139,13 @@ const GodotHTTPRequest = {
GodotRuntime.stringToHeap(str, dst, len);
},
+ godot_xhr_get_response_length__sig: 'ii',
godot_xhr_get_response_length: function (xhrId) {
const body = GodotHTTPRequest.requests[xhrId].response;
return body === null ? 0 : body.byteLength;
},
+ godot_xhr_get_response__sig: 'viii',
godot_xhr_get_response: function (xhrId, dst, len) {
let buf = GodotHTTPRequest.requests[xhrId].response;
if (buf === null) {
diff --git a/platform/javascript/js/libs/library_godot_os.js b/platform/javascript/js/libs/library_godot_os.js
index 44b104922e..260cfbf97f 100644
--- a/platform/javascript/js/libs/library_godot_os.js
+++ b/platform/javascript/js/libs/library_godot_os.js
@@ -75,14 +75,17 @@ const GodotConfig = {
},
},
+ godot_js_config_canvas_id_get__sig: 'vii',
godot_js_config_canvas_id_get: function (p_ptr, p_ptr_max) {
GodotRuntime.stringToHeap(`#${GodotConfig.canvas.id}`, p_ptr, p_ptr_max);
},
+ godot_js_config_locale_get__sig: 'vii',
godot_js_config_locale_get: function (p_ptr, p_ptr_max) {
GodotRuntime.stringToHeap(GodotConfig.locale, p_ptr, p_ptr_max);
},
+ godot_js_config_is_resize_on_start__sig: 'i',
godot_js_config_is_resize_on_start: function () {
return GodotConfig.resize_on_start ? 1 : 0;
},
@@ -239,19 +242,23 @@ const GodotOS = {
},
},
+ godot_js_os_finish_async__sig: 'vi',
godot_js_os_finish_async: function (p_callback) {
const func = GodotRuntime.get_func(p_callback);
GodotOS.finish_async(func);
},
+ godot_js_os_request_quit_cb__sig: 'vi',
godot_js_os_request_quit_cb: function (p_callback) {
GodotOS.request_quit = GodotRuntime.get_func(p_callback);
},
+ godot_js_os_fs_is_persistent__sig: 'i',
godot_js_os_fs_is_persistent: function () {
return GodotFS.is_persistent();
},
+ godot_js_os_fs_sync__sig: 'vi',
godot_js_os_fs_sync: function (callback) {
const func = GodotRuntime.get_func(callback);
GodotOS._fs_sync_promise = GodotFS.sync();
@@ -260,6 +267,7 @@ const GodotOS = {
});
},
+ godot_js_os_execute__sig: 'ii',
godot_js_os_execute: function (p_json) {
const json_args = GodotRuntime.parseString(p_json);
const args = JSON.parse(json_args);
@@ -270,6 +278,7 @@ const GodotOS = {
return 1;
},
+ godot_js_os_shell_open__sig: 'vi',
godot_js_os_shell_open: function (p_uri) {
window.open(GodotRuntime.parseString(p_uri), '_blank');
},
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 80723d54fc..ebfcd7293e 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -43,6 +43,7 @@
#include "modules/websocket/remote_debugger_peer_websocket.h"
#endif
+#include <dlfcn.h>
#include <emscripten.h>
#include <stdlib.h>
@@ -127,12 +128,24 @@ int OS_JavaScript::get_process_id() const {
}
bool OS_JavaScript::_check_internal_feature_support(const String &p_feature) {
- if (p_feature == "HTML5" || p_feature == "web")
+ if (p_feature == "HTML5" || p_feature == "web") {
return true;
+ }
#ifdef JAVASCRIPT_EVAL_ENABLED
- if (p_feature == "JavaScript")
+ if (p_feature == "JavaScript") {
+ return true;
+ }
+#endif
+#ifndef NO_THREADS
+ if (p_feature == "threads") {
return true;
+ }
+#endif
+#if WASM_GDNATIVE
+ if (p_feature == "wasm32") {
+ return true;
+ }
#endif
return false;
@@ -187,6 +200,13 @@ 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) {
+ 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());
+ return OK;
+}
+
OS_JavaScript *OS_JavaScript::get_singleton() {
return static_cast<OS_JavaScript *>(OS::get_singleton());
}
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index 03a3053367..6682f8fd85 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -87,6 +87,7 @@ public:
String get_user_data_dir() const override;
bool is_userfs_persistent() const override;
+ Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) override;
void resume_audio();
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index 356668a375..136bee68e3 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -40,9 +40,10 @@
#include "scene/resources/texture.h"
#if defined(VULKAN_ENABLED)
-#include "servers/rendering/rasterizer_rd/rasterizer_rd.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#endif
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -4087,12 +4088,12 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
rendering_device_vulkan = memnew(RenderingDeviceVulkan);
rendering_device_vulkan->initialize(context_vulkan);
- RasterizerRD::make_current();
+ RendererCompositorRD::make_current();
}
#endif
/*
- rendering_server = memnew(RenderingServerRaster);
+ rendering_server = memnew(RenderingServerDefault);
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
rendering_server = memnew(RenderingServerWrapMT(rendering_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
}
diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h
index 61fb04cbf3..3c6f462e92 100644
--- a/platform/linuxbsd/display_server_x11.h
+++ b/platform/linuxbsd/display_server_x11.h
@@ -43,7 +43,7 @@
#include "drivers/unix/os_unix.h"
#include "joypad_linux.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rasterizer.h"
+#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
#if defined(OPENGL_ENABLED)
diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h
index cd4fbd9db5..6e93bf6ef2 100644
--- a/platform/linuxbsd/os_linuxbsd.h
+++ b/platform/linuxbsd/os_linuxbsd.h
@@ -39,7 +39,7 @@
#include "drivers/unix/os_unix.h"
#include "joypad_linux.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rasterizer.h"
+#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
class OS_LinuxBSD : public OS_Unix {
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index 3025210195..c4c2426f1f 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -52,7 +52,7 @@
#endif
#if defined(VULKAN_ENABLED)
-#include "servers/rendering/rasterizer_rd/rasterizer_rd.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include <QuartzCore/CAMetalLayer.h>
#endif
@@ -3870,7 +3870,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
rendering_device_vulkan = memnew(RenderingDeviceVulkan);
rendering_device_vulkan->initialize(context_vulkan);
- RasterizerRD::make_current();
+ RendererCompositorRD::make_current();
}
#endif
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index e988e51e72..f5aad91946 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -42,7 +42,7 @@
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "platform/osx/logo.gen.h"
-#include "string.h"
+
#include <sys/stat.h>
class EditorExportPlatformOSX : public EditorExportPlatform {
@@ -572,36 +572,36 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
pkg_name = "Unnamed";
}
- String pkg_name_safe = OS::get_singleton()->get_safe_dir_name(pkg_name);
-
- Error err = OK;
- String tmp_app_path_name = "";
+ pkg_name = OS::get_singleton()->get_safe_dir_name(pkg_name);
- DirAccess *tmp_app_path = nullptr;
String export_format = use_dmg() && p_path.ends_with("dmg") ? "dmg" : "zip";
// Create our application bundle.
- tmp_app_path_name = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".app");
+ String tmp_app_dir_name = pkg_name + ".app";
+ String tmp_app_path_name = EditorSettings::get_singleton()->get_cache_dir().plus_file(tmp_app_dir_name);
print_line("Exporting to " + tmp_app_path_name);
- tmp_app_path = DirAccess::create_for_path(tmp_app_path_name);
- if (!tmp_app_path) {
+
+ Error err = OK;
+
+ DirAccessRef tmp_app_dir = DirAccess::create_for_path(tmp_app_path_name);
+ if (!tmp_app_dir) {
err = ERR_CANT_CREATE;
}
// Create our folder structure.
if (err == OK) {
print_line("Creating " + tmp_app_path_name + "/Contents/MacOS");
- err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/MacOS");
+ err = tmp_app_dir->make_dir_recursive(tmp_app_path_name + "/Contents/MacOS");
}
if (err == OK) {
print_line("Creating " + tmp_app_path_name + "/Contents/Frameworks");
- err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/Frameworks");
+ err = tmp_app_dir->make_dir_recursive(tmp_app_path_name + "/Contents/Frameworks");
}
if (err == OK) {
print_line("Creating " + tmp_app_path_name + "/Contents/Resources");
- err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/Resources");
+ err = tmp_app_dir->make_dir_recursive(tmp_app_path_name + "/Contents/Resources");
}
// Now process our template.
@@ -678,14 +678,14 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
ret = unzGoToNextFile(src_pkg_zip);
continue; // skip
}
- file = file.replace("/data.mono.osx.64.release_debug/", "/data_" + pkg_name_safe + "/");
+ file = file.replace("/data.mono.osx.64.release_debug/", "/data_" + pkg_name + "/");
}
if (file.find("/data.mono.osx.64.release/") != -1) {
if (p_debug) {
ret = unzGoToNextFile(src_pkg_zip);
continue; // skip
}
- file = file.replace("/data.mono.osx.64.release/", "/data_" + pkg_name_safe + "/");
+ file = file.replace("/data.mono.osx.64.release/", "/data_" + pkg_name + "/");
}
print_line("ADDING: " + file + " size: " + itos(data.size()));
@@ -694,7 +694,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
// Write it into our application bundle.
file = tmp_app_path_name.plus_file(file);
if (err == OK) {
- err = tmp_app_path->make_dir_recursive(file.get_base_dir());
+ err = tmp_app_dir->make_dir_recursive(file.get_base_dir());
}
if (err == OK) {
FileAccess *f = FileAccess::open(file, FileAccess::WRITE);
@@ -797,7 +797,10 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
}
// Clean up temporary .app dir.
- OS::get_singleton()->move_to_trash(tmp_app_path_name);
+ tmp_app_dir->change_dir(tmp_app_path_name);
+ tmp_app_dir->erase_contents_recursive();
+ tmp_app_dir->change_dir("..");
+ tmp_app_dir->remove(tmp_app_dir_name);
}
return err;
diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp
index 9937ae5b62..22af8ba985 100644
--- a/platform/server/os_server.cpp
+++ b/platform/server/os_server.cpp
@@ -33,7 +33,7 @@
#include "core/string/print_string.h"
#include "drivers/dummy/rasterizer_dummy.h"
#include "drivers/dummy/texture_loader_dummy.h"
-#include "servers/rendering/rendering_server_raster.h"
+#include "servers/rendering/rendering_server_default.h"
#include "main/main.h"
@@ -76,7 +76,7 @@ Error OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int
video_driver_index = p_video_driver; // unused in server platform, but should still be initialized
- rendering_server = memnew(RenderingServerRaster);
+ rendering_server = memnew(RenderingServerDefault);
rendering_server->init();
AudioDriverManager::initialize(p_audio_driver);
diff --git a/platform/server/os_server.h b/platform/server/os_server.h
index 06ea483fd4..a4ae6a0bf6 100644
--- a/platform/server/os_server.h
+++ b/platform/server/os_server.h
@@ -41,7 +41,7 @@
#include "platform/x11/crash_handler_linuxbsd.h"
#endif
#include "servers/audio_server.h"
-#include "servers/rendering/rasterizer.h"
+#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
#undef CursorShape
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index 79508055e5..780eba8407 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -44,7 +44,7 @@
#include "main/main.h"
#include "platform/windows/windows_terminal_logger.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rendering_server_raster.h"
+#include "servers/rendering/rendering_server_default.h"
#include "servers/rendering/rendering_server_wrap_mt.h"
#include "thread_uwp.h"
@@ -240,7 +240,7 @@ Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
set_video_mode(vm);
- rendering_server = memnew(RenderingServerRaster);
+ rendering_server = memnew(RenderingServerDefault);
// FIXME: Reimplement threaded rendering
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
rendering_server = memnew(RenderingServerWrapMT(rendering_server, false));
diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h
index 88961bf143..c2d1acf8a0 100644
--- a/platform/uwp/os_uwp.h
+++ b/platform/uwp/os_uwp.h
@@ -39,7 +39,7 @@
#include "drivers/xaudio2/audio_driver_xaudio2.h"
#include "joypad_uwp.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rasterizer.h"
+#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
#include <fcntl.h>
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index e0b2a52014..ee13e3c774 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -71,6 +71,7 @@ def get_opts():
BoolVariable("use_mingw", "Use the Mingw compiler, even if MSVC is installed. Only used on Windows.", False),
BoolVariable("use_llvm", "Use the LLVM compiler", False),
BoolVariable("use_thinlto", "Use ThinLTO", False),
+ BoolVariable("use_static_cpp", "Link MinGW/MSVC C++ runtime libraries statically", True),
]
@@ -221,7 +222,11 @@ def configure_msvc(env, manual_msvc_config):
## Compile/link flags
- env.AppendUnique(CCFLAGS=["/MT", "/Gd", "/GR", "/nologo"])
+ if env["use_static_cpp"]:
+ env.AppendUnique(CCFLAGS=["/MT"])
+ else:
+ env.AppendUnique(CCFLAGS=["/MD"])
+ env.AppendUnique(CCFLAGS=["/Gd", "/GR", "/nologo"])
# Force to use Unicode encoding
env.AppendUnique(CCFLAGS=["/utf-8"])
env.AppendUnique(CXXFLAGS=["/TP"]) # assume all sources are C++
@@ -373,12 +378,14 @@ def configure_mingw(env):
mingw_prefix = ""
if env["bits"] == "32":
- env.Append(LINKFLAGS=["-static"])
- env.Append(LINKFLAGS=["-static-libgcc"])
- env.Append(LINKFLAGS=["-static-libstdc++"])
+ if env["use_static_cpp"]:
+ env.Append(LINKFLAGS=["-static"])
+ env.Append(LINKFLAGS=["-static-libgcc"])
+ env.Append(LINKFLAGS=["-static-libstdc++"])
mingw_prefix = env["mingw_prefix_32"]
else:
- env.Append(LINKFLAGS=["-static"])
+ if env["use_static_cpp"]:
+ env.Append(LINKFLAGS=["-static"])
mingw_prefix = env["mingw_prefix_64"]
if env["use_llvm"]:
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 2581cc3af6..62fcd20f61 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -3205,7 +3205,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
rendering_device_vulkan = memnew(RenderingDeviceVulkan);
rendering_device_vulkan->initialize(context_vulkan);
- RasterizerRD::make_current();
+ RendererCompositorRD::make_current();
}
#endif
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index c64a1b3b09..684746919a 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -43,8 +43,8 @@
#include "joypad_windows.h"
#include "key_mapping_windows.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rasterizer.h"
-#include "servers/rendering/rasterizer_rd/rasterizer_rd.h"
+#include "servers/rendering/renderer_compositor.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "servers/rendering_server.h"
#ifdef XAUDIO2_ENABLED
diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp
index 2a5c8a7763..ae5e846dac 100644
--- a/platform/windows/joypad_windows.cpp
+++ b/platform/windows/joypad_windows.cpp
@@ -151,7 +151,7 @@ bool JoypadWindows::setup_dinput_joypad(const DIDEVICEINSTANCE *instance) {
const DWORD devtype = (instance->dwDevType & 0xFF);
- if ((devtype != DI8DEVTYPE_JOYSTICK) && (devtype != DI8DEVTYPE_GAMEPAD) && (devtype != DI8DEVTYPE_1STPERSON)) {
+ if ((devtype != DI8DEVTYPE_JOYSTICK) && (devtype != DI8DEVTYPE_GAMEPAD) && (devtype != DI8DEVTYPE_1STPERSON) && (devtype != DI8DEVTYPE_DRIVING)) {
return false;
}
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 646bc3aa4c..ae6b54513d 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -46,7 +46,7 @@
#include "main/main.h"
#include "platform/windows/display_server_windows.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rendering_server_raster.h"
+#include "servers/rendering/rendering_server_default.h"
#include "servers/rendering/rendering_server_wrap_mt.h"
#include "windows_terminal_logger.h"
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index a3dbb23182..5451e15d36 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -40,7 +40,7 @@
#include "drivers/winmidi/midi_driver_winmidi.h"
#include "key_mapping_windows.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rasterizer.h"
+#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
#ifdef XAUDIO2_ENABLED
#include "drivers/xaudio2/audio_driver_xaudio2.h"