The canvas_id is `#`-prefixed to work with emscripten as a CSS selector.
When comparing to an event target ID (e.g. when checking if the canvas
is fullscreen, or is locking the mouse) we need to skip the first char
(the hash).
No longer use emscripten functions for gamepads, implement them as
library functions in library_godot_display.js instead.
This allows us to do a better job at "guessing" vendorId, productId, OS,
etc. thus allowing us to better find the remapping for the controller.
Happy new year to the wonderful Godot community!
2020 has been a tough year for most of us personally, but a good year for
Godot development nonetheless with a huge amount of work done towards Godot
4.0 and great improvements backported to the long-lived 3.2 branch.
We've had close to 400 contributors to engine code this year, authoring near
7,000 commit! (And that's only for the `master` branch and for the engine code,
there's a lot more when counting docs, demos and other first-party repos.)
Here's to a great year 2021 for all Godot users 🎆
(cherry picked from commit b5334d14f7)
Working, with emscripten > 2.0.9
Yes, the unreleased version. 2.0.9 works, but throws and error due to a
bug in emscripten with the thirdparty ENet library.
The issue is fixed upstream so newer releases will work.
This was caused by the devicePixelRatio being applied twice, once by the
HTML code, once by the OS code.
More specifically, OS.get_window_size() would return the canvas element
size, while OS.set_window_size() would set the element size to the
specified value times the devicePixelRatio.
Calling OS.set_window_size(OS.get_window_size()) would reapply the
devicePixelRatio every time.
This commit changes the behaviour so that OS.set_window_size() do not
apply the devicePixelRatio to the canvas element size, by it divides the
CSS size instead.
Applies to javascript files inside the platform library folder, the
exposed Engine code, and any javascript files in modules.
Files ending with ".externs.js" will be ignored, you can create a
".eslintignore" file to specify extra files to be ignored.
Initial work to make liniting easier.
This includes:
- Rename http_request.js to library_godot_http_request.js.
- Rename externs.js to engine.externs.js.
- New library_godot_runtime.js (GodotRuntime) wraps around emscripten
functions.
- Refactor of XMLHttpRequest handler in engine/preloader.js.
- Few fixes to bugs spotted by early stage linting.
Rewrote AudioDriverJavaScript to support multiple processor nodes.
The old (and deprecated) ScriptProcessorNode when threads are not
available, and the new AudioWorklet API when threads are enabled.
The new implementation uses two ring buffers and a shared state to
communicated with the AudioWorklet thread.
The audio.worklet.js JavaScript file is always added to the export
template, but only really used (and download) in the thread build.
The API is implemented in javascript, and generates C functions that can
be called from godot.
This allows much cleaner code replacing all `EM_ASM` calls in our C++
code with plain C function calls.
This also gets rid of few hacks and comes with few optimizations (e.g.
custom cursor shapes should be much faster now).
The size of the audio buffer was incorrectly doubled when creating the
script processor.
latencyHint is expressed in seconds, not milliseconds.
Additionally, on some browsers it actually affect the performance and
stability of the audio driver.
For this reason it has been completely disabled (interactive) and a not
has been left for future reference.
A new editor plugin, specific to HTML5, that provide some extra features
needed to make the editor usable on that platform.
For now, it adds a "Download project sources" option in the "Tool" menu,
so the user can download the work done as a zip file (from the browser
storage).
This should be made available in emscripten in a decent way.
Possibly after unmount, to free the database lock and allow performing
operations on it from javascript after the Emscripten Runtime has
exited.
This fixes a "random" deadlock when quitting the editor.
I still haven't figure out the root cause, but having a bigger seems to
greatly mitigate the issue.
The new pool size (pre-allocated threads) is now 8.
No longer parse emscripten/emsdk config to detect emcc/node paths.
Use WhereIs to find "emcc" and "node", look for "node_modules" in "emcc"
path.
(cherry picked from commit 7998745237)
This should fix some of the audio stuttering issues when the HTML5
export is compiled with threads support.
The API should be ported to AudioWorklet to (hopefully) be perfect.
That though, cannot be backported to 3.2 due to extra restriction of
AudioWorklet (which only runs in SecureContext, and needs a polyfill for
Safari).
This allow the page to be considered a SecureContext if the address is
localhost (127.0.0.1/::1) and let Firefox (and future Chrome versions)
enable extra features needed for the HTML5 threaded export.
The engine now expects to emscripten FS to be setup and sync-ed before
main is called. This is exposed via `Module["initFS"]` which also allows
to setup multiple persistence paths (internal use only for now).
Additionally, FS syncing is done **once** for every loop if at least one
file in a persistent path was open for writing and closed, and if the FS
is not syncing already.
This should potentially fix issues reported by users where "autosave"
would not work on the web (never calling `syncfs` because of too many
writes).
- Refactored the Engine code, splitted across files.
- Use MODULARIZE option to build emscripten code into it's own closure.
- Optional closure compiler run for JS and generated code.
- Enable lto support (saves ~2MiB in release).
- Can now build with tools=yes (not much to see yet).
- Dropped some deprecated code for older toolchains.
- Add onExit, and onExecute JS function.
- Add files drag and drop support.
- Add support for low precessor usage mode (via offscreen render, swap).
Make the first iteration as soon as the canvas is setup, avoiding a
black screen before the next animation frame is requested.
Also create OS and do setup before syncing FS to avoid crash when IDBFS
access is denied.
Configured for a max line length of 120 characters.
psf/black is very opinionated and purposely doesn't leave much room for
configuration. The output is mostly OK so that should be fine for us,
but some things worth noting:
- Manually wrapped strings will be reflowed, so by using a line length
of 120 for the sake of preserving readability for our long command
calls, it also means that some manually wrapped strings are back on
the same line and should be manually merged again.
- Code generators using string concatenation extensively look awful,
since black puts each operand on a single line. We need to refactor
these generators to use more pythonic string formatting, for which
many options are available (`%`, `format` or f-strings).
- CI checks and a pre-commit hook will be added to ensure that future
buildsystem changes are well-formatted.
(cherry picked from commit cd4e46ee65)
The value of this, does not include the layout.
The code has extra logic to map the unicode value to our keylist,
supporting ASCII and Latin-1.
(cherry picked from commit 0a35b97b62
with help of https://github.com/Faless/godot/tree/js/keyCode)
Each driver used to define the (same) project settings value, but the
setting names are not driver specific. Ovverriding is still possible via
platform tags.
(cherry picked from commit 90c7102b51)
Similar to https://github.com/godotengine/godot/pull/36557
At least in chrome, the following error is printed for each mouse wheel
rotation:
[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/6662647093133312
This PR moves the handler to the canvas and thereby fixes the error.
Tested on: Chrome and Firefox (MacOS), Firefox, Chrome(Android), Safari (IPad + MacOS)
(cherry picked from commit b1e8ac7b08)
Without this patch, the following exception is thrown when the touch
screen is used: TypeError: e.getBoundingClientRect is not a function.
No touch events arrive in the engine.
From my testing, this PR fixes the issue and behaves as expected.
Tested with godot-demo-projects/misc/multitouch_view/, emscripten 1.39.8
and Firefox mobile emulator as well as FF on Android
(cherry picked from commit 5134317afc)
This makes the project icon display immediately as a favicon when
opening the page, without having to wait for the project to finish
loading.
(cherry picked from commit 4492cf856b)
Fixes compatibility with emscripten 1.39.5+ .
Most input callbacks now require a target and no longer support NULL
defaults.
This commit changes all required null targets to the expected default in
the binding phase.
Since for canvas-related callbacks there is no default, the "#canvas"
selector is used instead.
Additionally, since canvasX and canvasY event properties are no longer
supported, event positions are computed from "clientX" and "clientY" and
the "#canvas" bounding client rect.
It was removed as noted in the changelog:
https://github.com/emscripten-core/emscripten/blob/1.39.5/ChangeLog.md#v1395-12202019
> Removed `timestamp` field from mouse, wheel, devicemotion and
> deviceorientation events. The presence of a `timestamp` on these
> events was slightly arbitrary, and populating this field caused
> a small profileable overhead that all users might not care about.
> It is easy to get a timestamp of an event by calling
> `emscripten_get_now()` or `emscripten_performance_now()` inside
> the event handler function of any event.
Fixes#34648.
I'm barely scratching the surface of the changes needed to make the
--export command line interface easy to use, but this should already
improve things somewhat.
- Streamline `can_export()` templates check in all platforms, checking
first for the presence of official templates, then of any defined
custom template, and reporting on the absence of any.
Shouldn't change the actual return value much which is still true if
either release or debug is usable - we might want to change that
eventually and better validate against the requested target.
- Fix discrepancy between platforms using `custom_package/debug` and
`custom_template/debug` (resp. `release`).
All now use `custom_template`, which will break compatibility for
`export_presets.cfg` with earlier projects (but is easy to fix).
- Use `can_export()` when attempting a command line export and report
the same errors that would be shown in the editor.
- Improve error reporting after a failed export attempt, handling
missing template and invalid path more gracefully.
- Cleanup of unused stuff in EditorNode around the export workflow.
- Improve --export documentation in --help a bit.
Fixes#16949 (at least many of the misunderstandings listed there).
Fixes#18470.
Happy new year to the wonderful Godot community!
We're starting a new decade with a well-established, non-profit, free
and open source game engine, and tons of further improvements in the
pipeline from hundreds of contributors.
Godot will keep getting better, and we're looking forward to all the
games that the community will keep developing and releasing with it.
The option is needed when using the 'fastcomp' backend (default before
1.39.0), and must not be defined when using 'upstream' (new default).
So we define it conditionally to support both backends.
Follow-up to #30751.
This allows setting the `read_chunk_size` of the internal HTTPClient.
This is important to reduce the allocation overhead and number of file
writes when downloading large files, allowing for better download speed.
Third-party platforms (e.g. console ports) need to be able to
disable JIT support in the regex module too, so it can't be
hardcoded in the module SCsub. This is cleaner this way anyway.
Fixes#19316.
Upstream Emscripten changed this in 1.39.1+, so IDBFS is no longer
included by default and has to be linked manually.
The explicit linking doesn't seem to be problematic on earlier
versions (tested `1.38.47-upstream`).
Fixes#33724.
A change in upstream Emscripten 1.39.1+ made our buildsystem error
out where it was previously only issuing a warning:
```
[ 5%] Linking Static Library ==> main/libmain.javascript.opt.bc
shared:WARNING: Assuming object file output in the absence of `-c`, based on output filename. Please add with `-c` or `-r` to avoid this warning
Ranlib Library ==> main/libmain.javascript.opt.bc
/opt/emsdk/upstream/bin/llvm-ranlib: error: unable to load 'main/libmain.javascript.opt.bc': file too small to be an archive
```
As advised on emscripten-core/emscripten#9806, we should be using
`emar` here to create the static library and not `emcc`.
This was apparently done to workaround Emscripten issues in the past,
but evidently this is no longer necessary.
The rest of the `env` redefinitions should probably be re-assessed
against the current state of Emscripten.
Fixes#33374.
Since most browsers no longer allow making async requests from a page
loaded from `file://`, we now need a proper HTTP server to load the
exported HTML5 game.
This should also allow us to get the debugger to work over a WebSocket
connection.
- Add or remove the necessary subdirectorires to the includes to remove
dependency on the editor directory being in the build's include path.
- Ensure includes in modified files conform to style guideline.
- Remove editor from the build include path.
So far we left most temporary files lying around, so this attempts to
fix that.
I added a helper method to DirAccess to factor out the boilerplate of
creating a DirAccess, checking if the file exists, remove it or print
an error on failure.
It is not supported in Emscripten's `latest-upstream` LLVM backend,
and doesn't seem necessary in the `latest` backend either.
It was initially added in #22857 to solve a compilation error with the latter.
Part of #30270.
Emscripten is apparently changing the variables in its config file,
causing potential breakage of our build system.
Binaries of the latest/latest-upstream releases are located in a
subfolder of BINARYEN_ROOT called emscripten.
Binaries of the other releases (e.g. sdk-1.38.31-64bit) are instead
placed under the EMSCRIPTEN_ROOT folder.
This PR checks if BINARYEN_ROOT has a subfolder called emscripten, if
that does not exists, it falls back to checking the EMSCRIPTEN_ROOT.
This way we give precedence to the new releases, given that activating
multiple releases sequentially might result in having mismatching
BINARYEN_ROOT and EMSCRIPTEN_ROOT.
Recent Emscripten SDK versions seem to only include the
`BINARYEN_ROOT` variable in the Emscripten configuration file,
whereas the platform's `detect.py` only looked at `EMSCRIPTEN_ROOT`.
Warnings raised by Emscripten 1.38.0 and MinGW64 5.0.4 / GCC 8.3.0.
JS can now build with `werror=yes warnings=extra`.
MinGW64 still has a few warnings to resolve with `warnings=extra`,
and only one with `warnings=all`.
Part of #29033 and #29801.
This is a new singleton where camera sources such as webcams or cameras on a mobile phone can register themselves with the Server.
Other parts of Godot can interact with this to obtain images from the camera as textures.
This work includes additions to the Visual Server to use this functionality to present the camera image in the background. This is specifically targetted at AR applications.
It's not necessary, but the vast majority of calls of error macros
do have an ending semicolon, so it's best to be consistent.
Most WARN_DEPRECATED calls did *not* have a semicolon, but there's
no reason for them to be treated differently.
Being async, the first time a value is pasted GUI elements will still
return the previous one.
This at least until 'clipboardchange' window event gets implemented by
user agents.
Listen to paste events to update local clipboard.
CTRL+V still not working out of the box.
To do that, We would need to change how we handle keypress, most likely
making it worse and less safe. In the end, I'm not sure we can fix it
properly for now. Maybe in the future, with the Clipboard API, support
of which is still pretty limited on chrome, and only available to
extensions in Firefox.
For now, you can paste via:
- Browser bar -> Edit -> Paste.
- Middle mouse click (Linux only, copies secondary clipboard).
And THEN press CTRL+V
Those were disable to keep size small, and on Android avoid the dependency on the STL,
but for tools build (editor) this is not really a concern.
Note: as of today it's not possible to build tools=yes for those platforms, but this
change is one of the necessary steps to enable it.
Fixes#25262.
Include paths are processed from left to right, so we use Prepend to
ensure that paths to bundled thirdparty files will have precedence over
system paths (e.g. `/usr/include` should have lowest priority).
GLES2 is not designed to be a drop-in replacement for the GLES3 backend,
so the fallback mode has to be used knowingly. It *can* make sense for
simple projects which make sure to handle the differences between both
rendering backends, but most users should stick to one supported backend.
By making it opt-in, we can now use this parameter to define whether to
export ETC textures to Android and iOS when using GLES3 + Fallback.
When using GLES3 without Fallback on Android, set the proper min GLES
version in the AndroidManifest.
Also made the option boolean and renamed it for clarity and to avoid
conflict with the previous String option (which would always evaluate as
"true" otherwise).
Fixes#26569.
For HTML5, we need to support S3TC if running on desktop,
and ETC or ETC2 for mobile, so make this explicit.
Add logic to check for ETC2 support on GLES3,
and remove incorrect ETC feature for GLES3 on Android.
Fix ETC check invalidating templates on HTML5.
Fixes#26476.
The code in pre.js and engine.js is a bit confusing to see in isolation,
since the files aren't valid JS files by themselves. This just adds some
explanatory text to both files.
Fixes#22937.
This allows more consistency in the manner we include core headers,
where previously there would be a mix of absolute, relative and
include path-dependent includes.
This adds a static is_viable() method to all rasterizers which has to be
called before initializing the rasterizer. This allows us to check what
rasterizer to use in OS::initialize together with the GL context
initialization.
This commit also adds a new project setting
"rendering/quality/driver/driver_fallback" which allows the creator of a
project to specify whether or not fallback to GLES2 is allowed. This
setting is ignored for the editor so the editor will always open even if
the project itself cannot run. This will hopefully reduce confusion for
users downloading projects from the internet.
We also no longer crash when GLES3 is not functioning on a platform.
This fixes#15324
This commit makes operator[] on Vector const and adds a write proxy to it. From
now on writes to Vectors need to happen through the .write proxy. So for
instance:
Vector<int> vec;
vec.push_back(10);
std::cout << vec[0] << std::endl;
vec.write[0] = 20;
Failing to use the .write proxy will cause a compilation error.
In addition COWable datatypes can now embed a CowData pointer to their data.
This means that String, CharString, and VMap no longer use or derive from
Vector.
_ALWAYS_INLINE_ and _FORCE_INLINE_ are now equivalent for debug and non-debug
builds. This is a lot faster for Vector in the editor and while running tests.
The reason why this difference used to exist is because force-inlined methods
used to give a bad debugging experience. After extensive testing with modern
compilers this is no longer the case.
-Project/Editor settings now show tooltips properly
-Settings thar require restart now will show a restart warning
-Video driver is now visible all the time, can be changed easily
-Added function to request current video driver
Allows using startGame() with main packs exported as .zip, but also any
other custom extension, for example if a web game host does not allow
the .pck filename extension.
Some web game hosts only allow certain filename extensions. If .wasm is
not allowed, this function allows overriding the WebAssembly filename
extension to work around that restriction.
Now generating mouse events from touch is optional (on by default) and it's performed by `InputDefault` instead of having each OS abstraction doing it. (*)
The translation algorithm waits for a touch index to be pressed and tracks it translating its events to mouse events until it is raised, while ignoring other pointers.
Furthermore, to avoid an stuck "touch mouse", since not all platforms may report touches raised when the window is unfocused, it checks if touches are still down by the time it's focused again and if so it resets the state of the emulated mouse.
*: In the case of Windows, since it already provides touch-to-mouse translation by itself, "echo" mouse events are filtered out to have it working like the rest.
On X11 a little hack has been needed to avoid a case of a spurious mouse motion event that is generated during touch interaction.
Plus: Improve/fix tracking of current mouse position.
** Summary of changes to settings: **
- `display/window/handheld/emulate_touchscreen` becomes `input/pointing_devices/emulate_touch_from_mouse`
- New setting: `input/pointing_devices/emulate_mouse_from_touch`