summaryrefslogtreecommitdiff
path: root/platform/javascript/os_javascript.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/javascript/os_javascript.cpp')
-rw-r--r--platform/javascript/os_javascript.cpp186
1 files changed, 80 insertions, 106 deletions
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 652f6a1ce1..5acdc5f602 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* 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 */
@@ -32,7 +32,6 @@
#include "core/io/file_access_buffered_fa.h"
#include "drivers/gles2/rasterizer_gles2.h"
-#include "drivers/gles3/rasterizer_gles3.h"
#include "drivers/unix/dir_access_unix.h"
#include "drivers/unix/file_access_unix.h"
#include "main/main.h"
@@ -49,6 +48,7 @@
#define DOM_BUTTON_RIGHT 2
#define DOM_BUTTON_XBUTTON1 3
#define DOM_BUTTON_XBUTTON2 4
+#define GODOT_CANVAS_SELECTOR "#canvas"
// Window (canvas)
@@ -70,18 +70,23 @@ static bool is_canvas_focused() {
/* clang-format on */
}
-static Point2 correct_canvas_position(int x, int y) {
+static Point2 compute_position_in_canvas(int x, int y) {
+ int canvas_x = EM_ASM_INT({
+ return document.getElementById('canvas').getBoundingClientRect().x;
+ });
+ int canvas_y = EM_ASM_INT({
+ return document.getElementById('canvas').getBoundingClientRect().y;
+ });
int canvas_width;
int canvas_height;
- emscripten_get_canvas_element_size(NULL, &canvas_width, &canvas_height);
+ emscripten_get_canvas_element_size(GODOT_CANVAS_SELECTOR, &canvas_width, &canvas_height);
double element_width;
double element_height;
- emscripten_get_element_css_size(NULL, &element_width, &element_height);
+ emscripten_get_element_css_size(GODOT_CANVAS_SELECTOR, &element_width, &element_height);
- x = (int)(canvas_width / element_width * x);
- y = (int)(canvas_height / element_height * y);
- return Point2(x, y);
+ return Point2((int)(canvas_width / element_width * (x - canvas_x)),
+ (int)(canvas_height / element_height * (y - canvas_y)));
}
static bool cursor_inside_canvas = true;
@@ -135,14 +140,14 @@ void OS_JavaScript::set_window_size(const Size2 p_size) {
emscripten_exit_soft_fullscreen();
window_maximized = false;
}
- emscripten_set_canvas_element_size(NULL, p_size.x, p_size.y);
+ emscripten_set_canvas_element_size(GODOT_CANVAS_SELECTOR, p_size.x, p_size.y);
}
}
Size2 OS_JavaScript::get_window_size() const {
int canvas[2];
- emscripten_get_canvas_element_size(NULL, canvas, canvas + 1);
+ emscripten_get_canvas_element_size(GODOT_CANVAS_SELECTOR, canvas, canvas + 1);
return Size2(canvas[0], canvas[1]);
}
@@ -162,7 +167,7 @@ void OS_JavaScript::set_window_maximized(bool p_enabled) {
strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF;
strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
strategy.canvasResizedCallback = NULL;
- emscripten_enter_soft_fullscreen(NULL, &strategy);
+ emscripten_enter_soft_fullscreen(GODOT_CANVAS_SELECTOR, &strategy);
window_maximized = p_enabled;
}
}
@@ -191,7 +196,7 @@ void OS_JavaScript::set_window_fullscreen(bool p_enabled) {
strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF;
strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
strategy.canvasResizedCallback = NULL;
- EMSCRIPTEN_RESULT result = emscripten_request_fullscreen_strategy(NULL, false, &strategy);
+ EMSCRIPTEN_RESULT result = emscripten_request_fullscreen_strategy(GODOT_CANVAS_SELECTOR, false, &strategy);
ERR_FAIL_COND_MSG(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED, "Enabling fullscreen is only possible from an input callback for the HTML5 platform.");
ERR_FAIL_COND_MSG(result != EMSCRIPTEN_RESULT_SUCCESS, "Enabling fullscreen is only possible from an input callback for the HTML5 platform.");
// Not fullscreen yet, so prevent "windowed" canvas dimensions from
@@ -214,6 +219,20 @@ void OS_JavaScript::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_scre
p_list->push_back(OS::VideoMode(screen.width, screen.height, true));
}
+bool OS_JavaScript::get_window_per_pixel_transparency_enabled() const {
+ if (!is_layered_allowed()) {
+ return false;
+ }
+ return transparency_enabled;
+}
+
+void OS_JavaScript::set_window_per_pixel_transparency_enabled(bool p_enabled) {
+ if (!is_layered_allowed()) {
+ return;
+ }
+ transparency_enabled = p_enabled;
+}
+
// Keys
template <typename T>
@@ -298,9 +317,10 @@ EM_BOOL OS_JavaScript::mouse_button_callback(int p_event_type, const EmscriptenM
Ref<InputEventMouseButton> ev;
ev.instance();
ev->set_pressed(p_event_type == EMSCRIPTEN_EVENT_MOUSEDOWN);
- ev->set_position(correct_canvas_position(p_event->canvasX, p_event->canvasY));
+ ev->set_position(compute_position_in_canvas(p_event->clientX, p_event->clientY));
ev->set_global_position(ev->get_position());
dom2godot_mod(p_event, ev);
+
switch (p_event->button) {
case DOM_BUTTON_LEFT: ev->set_button_index(BUTTON_LEFT); break;
case DOM_BUTTON_MIDDLE: ev->set_button_index(BUTTON_MIDDLE); break;
@@ -312,7 +332,7 @@ EM_BOOL OS_JavaScript::mouse_button_callback(int p_event_type, const EmscriptenM
if (ev->is_pressed()) {
- uint64_t diff = p_event->timestamp - os->last_click_ms;
+ double diff = emscripten_get_now() - os->last_click_ms;
if (ev->get_button_index() == os->last_click_button_index) {
@@ -362,7 +382,7 @@ EM_BOOL OS_JavaScript::mousemove_callback(int p_event_type, const EmscriptenMous
OS_JavaScript *os = get_singleton();
int input_mask = os->input->get_mouse_button_mask();
- Point2 pos = correct_canvas_position(p_event->canvasX, p_event->canvasY);
+ Point2 pos = compute_position_in_canvas(p_event->clientX, p_event->clientY);
// For motion outside the canvas, only read mouse movement if dragging
// started inside the canvas; imitating desktop app behaviour.
if (!cursor_inside_canvas && !input_mask)
@@ -459,7 +479,7 @@ void OS_JavaScript::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_s
cursors_cache.erase(p_shape);
}
- Ref<Texture> texture = p_cursor;
+ Ref<Texture2D> texture = p_cursor;
Ref<AtlasTexture> atlas_texture = p_cursor;
Ref<Image> image;
Size2 texture_size;
@@ -516,17 +536,17 @@ void OS_JavaScript::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_s
png_meta.height = texture_size.height;
png_meta.format = PNG_FORMAT_RGBA;
- PoolByteArray png;
+ PackedByteArray png;
size_t len;
- PoolByteArray::Read r = image->get_data().read();
+ const uint8_t *r = image->get_data().ptr();
ERR_FAIL_COND(!png_image_write_get_memory_size(png_meta, len, 0, r.ptr(), 0, NULL));
png.resize(len);
- PoolByteArray::Write w = png.write();
+ uint8_t *w = png.ptrw();
ERR_FAIL_COND(!png_image_write_to_memory(&png_meta, w.ptr(), &len, 0, r.ptr(), 0, NULL));
- w = PoolByteArray::Write();
+ w = uint8_t * ();
- r = png.read();
+ r = png.ptr();
char *object_url;
/* clang-format off */
@@ -543,7 +563,7 @@ void OS_JavaScript::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_s
stringToUTF8(url, string_on_wasm_heap, length_bytes);
}, r.ptr(), len, &object_url);
/* clang-format on */
- r = PoolByteArray::Read();
+ r = const uint8_t * ();
String url = String::utf8(object_url) + "?" + itos(p_hotspot.x) + " " + itos(p_hotspot.y);
@@ -696,7 +716,7 @@ EM_BOOL OS_JavaScript::touch_press_callback(int p_event_type, const EmscriptenTo
if (!touch.isChanged)
continue;
ev->set_index(touch.identifier);
- ev->set_position(correct_canvas_position(touch.canvasX, touch.canvasY));
+ ev->set_position(compute_position_in_canvas(touch.clientX, touch.clientY));
os->touches[i] = ev->get_position();
ev->set_pressed(p_event_type == EMSCRIPTEN_EVENT_TOUCHSTART);
@@ -721,7 +741,7 @@ EM_BOOL OS_JavaScript::touchmove_callback(int p_event_type, const EmscriptenTouc
if (!touch.isChanged)
continue;
ev->set_index(touch.identifier);
- ev->set_position(correct_canvas_position(touch.canvasX, touch.canvasY));
+ ev->set_position(compute_position_in_canvas(touch.clientX, touch.clientY));
Point2 &prev = os->touches[i];
ev->set_relative(ev->get_position() - prev);
prev = ev->get_position();
@@ -804,8 +824,6 @@ int OS_JavaScript::get_video_driver_count() const {
const char *OS_JavaScript::get_video_driver_name(int p_driver) const {
switch (p_driver) {
- case VIDEO_DRIVER_GLES3:
- return "GLES3";
case VIDEO_DRIVER_GLES2:
return "GLES2";
}
@@ -879,56 +897,32 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver,
EmscriptenWebGLContextAttributes attributes;
emscripten_webgl_init_context_attributes(&attributes);
- attributes.alpha = false;
+ attributes.alpha = GLOBAL_GET("display/window/per_pixel_transparency/allowed");
attributes.antialias = false;
ERR_FAIL_INDEX_V(p_video_driver, VIDEO_DRIVER_MAX, ERR_INVALID_PARAMETER);
- bool gles3 = true;
- if (p_video_driver == VIDEO_DRIVER_GLES2) {
- gles3 = false;
+ if (p_desired.layered) {
+ set_window_per_pixel_transparency_enabled(true);
}
bool gl_initialization_error = false;
- while (true) {
- if (gles3) {
- if (RasterizerGLES3::is_viable() == OK) {
- attributes.majorVersion = 2;
- RasterizerGLES3::register_config();
- RasterizerGLES3::make_current();
- break;
- } else {
- if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2")) {
- p_video_driver = VIDEO_DRIVER_GLES2;
- gles3 = false;
- continue;
- } else {
- gl_initialization_error = true;
- break;
- }
- }
- } else {
- if (RasterizerGLES2::is_viable() == OK) {
- attributes.majorVersion = 1;
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
- break;
- } else {
- gl_initialization_error = true;
- break;
- }
- }
+ if (RasterizerGLES2::is_viable() == OK) {
+ attributes.majorVersion = 1;
+ RasterizerGLES2::register_config();
+ RasterizerGLES2::make_current();
+ } else {
+ gl_initialization_error = true;
}
- EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(NULL, &attributes);
+ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(GODOT_CANVAS_SELECTOR, &attributes);
if (emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS) {
gl_initialization_error = true;
}
if (gl_initialization_error) {
- OS::get_singleton()->alert("Your browser does not support any of the supported WebGL versions.\n"
- "Please update your browser version.",
- "Unable to initialize Video driver");
+ OS::get_singleton()->alert("Your browser does not seem to support WebGL. Please update your browser version.",
+ "Unable to initialize video driver");
return ERR_UNAVAILABLE;
}
@@ -970,12 +964,10 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver,
VisualServer *visual_server = memnew(VisualServerRaster());
input = memnew(InputDefault);
- camera_server = memnew(CameraServer);
-
EMSCRIPTEN_RESULT result;
#define EM_CHECK(ev) \
if (result != EMSCRIPTEN_RESULT_SUCCESS) \
- ERR_PRINTS("Error while setting " #ev " callback: Code " + itos(result))
+ ERR_PRINT("Error while setting " #ev " callback: Code " + itos(result));
#define SET_EM_CALLBACK(target, ev, cb) \
result = emscripten_set_##ev##_callback(target, NULL, true, &cb); \
EM_CHECK(ev)
@@ -985,21 +977,21 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver,
// These callbacks from Emscripten's html5.h suffice to access most
// JavaScript APIs. For APIs that are not (sufficiently) exposed, EM_ASM
// is used below.
- SET_EM_CALLBACK("#window", mousemove, mousemove_callback)
- SET_EM_CALLBACK("#canvas", mousedown, mouse_button_callback)
- SET_EM_CALLBACK("#window", mouseup, mouse_button_callback)
- SET_EM_CALLBACK("#window", wheel, wheel_callback)
- SET_EM_CALLBACK("#window", touchstart, touch_press_callback)
- SET_EM_CALLBACK("#window", touchmove, touchmove_callback)
- SET_EM_CALLBACK("#window", touchend, touch_press_callback)
- SET_EM_CALLBACK("#window", touchcancel, touch_press_callback)
- SET_EM_CALLBACK("#canvas", keydown, keydown_callback)
- SET_EM_CALLBACK("#canvas", keypress, keypress_callback)
- SET_EM_CALLBACK("#canvas", keyup, keyup_callback)
- SET_EM_CALLBACK(NULL, fullscreenchange, fullscreen_change_callback)
+ SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, mousemove, mousemove_callback)
+ SET_EM_CALLBACK(GODOT_CANVAS_SELECTOR, mousedown, mouse_button_callback)
+ SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, mouseup, mouse_button_callback)
+ SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, wheel, wheel_callback)
+ SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, touchstart, touch_press_callback)
+ SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, touchmove, touchmove_callback)
+ SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, touchend, touch_press_callback)
+ SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, touchcancel, touch_press_callback)
+ SET_EM_CALLBACK(GODOT_CANVAS_SELECTOR, keydown, keydown_callback)
+ SET_EM_CALLBACK(GODOT_CANVAS_SELECTOR, keypress, keypress_callback)
+ SET_EM_CALLBACK(GODOT_CANVAS_SELECTOR, keyup, keyup_callback)
+ SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, fullscreenchange, fullscreen_change_callback)
SET_EM_CALLBACK_NOTARGET(gamepadconnected, gamepad_change_callback)
SET_EM_CALLBACK_NOTARGET(gamepaddisconnected, gamepad_change_callback)
-#undef SET_EM_CALLBACK_NODATA
+#undef SET_EM_CALLBACK_NOTARGET
#undef SET_EM_CALLBACK
#undef EM_CHECK
@@ -1080,15 +1072,15 @@ bool OS_JavaScript::main_loop_iterate() {
strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF;
strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
strategy.canvasResizedCallback = NULL;
- emscripten_enter_soft_fullscreen(NULL, &strategy);
+ emscripten_enter_soft_fullscreen(GODOT_CANVAS_SELECTOR, &strategy);
} else {
- emscripten_set_canvas_element_size(NULL, windowed_size.width, windowed_size.height);
+ emscripten_set_canvas_element_size(GODOT_CANVAS_SELECTOR, windowed_size.width, windowed_size.height);
}
just_exited_fullscreen = false;
}
int canvas[2];
- emscripten_get_canvas_element_size(NULL, canvas, canvas + 1);
+ emscripten_get_canvas_element_size(GODOT_CANVAS_SELECTOR, canvas, canvas + 1);
video_mode.width = canvas[0];
video_mode.height = canvas[1];
if (!window_maximized && !video_mode.fullscreen && !just_exited_fullscreen && !entering_fullscreen) {
@@ -1106,7 +1098,6 @@ void OS_JavaScript::delete_main_loop() {
void OS_JavaScript::finalize() {
- memdelete(camera_server);
memdelete(input);
}
@@ -1187,17 +1178,17 @@ void OS_JavaScript::set_icon(const Ref<Image> &p_icon) {
png_meta.height = icon->get_height();
png_meta.format = PNG_FORMAT_RGBA;
- PoolByteArray png;
+ PackedByteArray png;
size_t len;
- PoolByteArray::Read r = icon->get_data().read();
+ const uint8_t *r = icon->get_data().ptr();
ERR_FAIL_COND(!png_image_write_get_memory_size(png_meta, len, 0, r.ptr(), 0, NULL));
png.resize(len);
- PoolByteArray::Write w = png.write();
+ uint8_t *w = png.ptrw();
ERR_FAIL_COND(!png_image_write_to_memory(&png_meta, w.ptr(), &len, 0, r.ptr(), 0, NULL));
- w = PoolByteArray::Write();
+ w = uint8_t * ();
- r = png.read();
+ r = png.ptr();
/* clang-format off */
EM_ASM_ARGS({
var PNG_PTR = $0;
@@ -1253,24 +1244,6 @@ String OS_JavaScript::get_resource_dir() const {
return "/";
}
-OS::PowerState OS_JavaScript::get_power_state() {
-
- WARN_PRINT("Power management is not supported for the HTML5 platform, defaulting to POWERSTATE_UNKNOWN");
- return OS::POWERSTATE_UNKNOWN;
-}
-
-int OS_JavaScript::get_power_seconds_left() {
-
- WARN_PRINT("Power management is not supported for the HTML5 platform, defaulting to -1");
- return -1;
-}
-
-int OS_JavaScript::get_power_percent_left() {
-
- WARN_PRINT("Power management is not supported for the HTML5 platform, defaulting to -1");
- return -1;
-}
-
void OS_JavaScript::file_access_close_callback(const String &p_file, int p_flags) {
OS_JavaScript *os = get_singleton();
@@ -1311,6 +1284,7 @@ OS_JavaScript::OS_JavaScript(int p_argc, char *p_argv[]) {
window_maximized = false;
entering_fullscreen = false;
just_exited_fullscreen = false;
+ transparency_enabled = false;
main_loop = NULL;