[Scummvm-git-logs] scummvm branch-2-6 -> add7b76f31bad7a85f4c444b0ebc744f422ee1e2

sev- noreply at scummvm.org
Sun Jun 12 12:42:19 UTC 2022


This automated email contains information about 9 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
c6a8afa105 DIRECTOR: EMSCRIPTEN: Yield back to the browser in the mail loop
aa3a5d5dee STARK: Switch to glTexParameteri instead of glTexParameterf where integer enums are used
95c6e3a11f CREDITS: Add myself to the backend credits
efb746f792 TESTBED: Don't write to disk if WriteStream can't be created (e.g. read-only filesystem or permission issue)
42e500dd32 EMSCRIPTEN: Merging parts of scummvm/scummvm#3686 for fullscreen support, disabling exit buttons (openURL has been fixed
6a90a32a1f EMSCRIPTEN: Major build improvements
5999281d02 EMSCRIPTEN: Automatically bundle icons from scummvm/scummvm-icons repository
ef72778b26 EMSCRIPTEN: Clean up patches and update readme
add7b76f31 EMSCRIPTEN: Remove patches from this repo


Commit: c6a8afa105ec779a6f935562cc8284bdfb430250
    https://github.com/scummvm/scummvm/commit/c6a8afa105ec779a6f935562cc8284bdfb430250
Author: Christian Kündig (christian at kuendig.info)
Date: 2022-06-12T14:40:21+02:00

Commit Message:
DIRECTOR: EMSCRIPTEN: Yield back to the browser in the mail loop

Changed paths:
    engines/director/director.cpp


diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index d6d7ebe1e21..ca573241a7a 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -214,6 +214,14 @@ Common::Error DirectorEngine::run() {
 	bool loop = true;
 
 	while (loop) {
+#if defined(__EMSCRIPTEN__)
+		// If SDL_HINT_EMSCRIPTEN_ASYNCIFY is enabled, SDL pauses the application and gives 
+		// back control to the browser automatically by calling emscripten_sleep via SDL_Delay. 
+		// Without this the page would completely lock up. 
+		_system->delayMillis(0);
+#endif
+
+
 		if (_stage->getCurrentMovie())
 			processEvents();
 


Commit: aa3a5d5dee49400fb1638da0c0042dc7ce67c248
    https://github.com/scummvm/scummvm/commit/aa3a5d5dee49400fb1638da0c0042dc7ce67c248
Author: Christian Kündig (christian at kuendig.info)
Date: 2022-06-12T14:40:33+02:00

Commit Message:
STARK: Switch to glTexParameteri instead of glTexParameterf where integer enums are used

Changed paths:
    engines/stark/gfx/opengltexture.cpp


diff --git a/engines/stark/gfx/opengltexture.cpp b/engines/stark/gfx/opengltexture.cpp
index 15e98462ec2..adef004dd69 100644
--- a/engines/stark/gfx/opengltexture.cpp
+++ b/engines/stark/gfx/opengltexture.cpp
@@ -107,15 +107,15 @@ void OpenGlTexture::setLevelCount(uint32 count) {
 		// It expects all the levels to be provided, which is not the case in TLJ.
 		// FIXME: Enable mipmapping on GLES2
 		if (OpenGLContext.type != OpenGL::kOGLContextGLES2) {
-			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, count - 1);
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, count - 1);
 
-			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
-			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 		}
 #endif
 
-		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
-		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
 	}
 }
 


Commit: 95c6e3a11f99a962c3189cb1120a15c0242616a6
    https://github.com/scummvm/scummvm/commit/95c6e3a11f99a962c3189cb1120a15c0242616a6
Author: Christian Kündig (christian at kuendig.info)
Date: 2022-06-12T14:40:47+02:00

Commit Message:
CREDITS: Add myself to the backend credits

Changed paths:
    AUTHORS
    devtools/credits.pl
    doc/docportal/help/credits.rst
    gui/credits.h


diff --git a/AUTHORS b/AUTHORS
index daa30d354d7..6c8360fc3d1 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -623,6 +623,9 @@ ScummVM Team
     Tizen / BADA:
        Chris Warren-Smith
 
+    Webassembly / Emscripten:
+       Christian Kuendig
+
     WebOS:
        Klaus Reimer
 
diff --git a/devtools/credits.pl b/devtools/credits.pl
index d7436568a2e..7d93932b3c7 100755
--- a/devtools/credits.pl
+++ b/devtools/credits.pl
@@ -639,6 +639,10 @@ begin_credits("Credits");
 				add_person("Chris Warren-Smith", "", "");
 			end_section();
 
+			begin_section("Webassembly / Emscripten");
+				add_person("Christian Kündig", "chkuendig", "");
+			end_section();
+
 			begin_section("WebOS");
 				add_person("Klaus Reimer", "kayahr", "");
 			end_section();
diff --git a/doc/docportal/help/credits.rst b/doc/docportal/help/credits.rst
index 47eb1073e0c..77ad9adb085 100644
--- a/doc/docportal/help/credits.rst
+++ b/doc/docportal/help/credits.rst
@@ -1580,6 +1580,15 @@ Tizen / BADA
    * - Chris Warren-Smith
      -
 
+Webassembly / Emscripten
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. list-table::
+   :widths: 35 65
+
+   * - Christian Kündig
+     -
+
 WebOS
 ^^^^^
 
diff --git a/gui/credits.h b/gui/credits.h
index 91e255acf3d..78aba11c6ae 100644
--- a/gui/credits.h
+++ b/gui/credits.h
@@ -764,6 +764,9 @@ static const char *credits[] = {
 "C1""Tizen / BADA",
 "C0""Chris Warren-Smith",
 "",
+"C1""Webassembly / Emscripten",
+"C0""Christian K\303\274ndig",
+"",
 "C1""WebOS",
 "C0""Klaus Reimer",
 "",


Commit: efb746f79294f1daf53b6ed74718b516911e28a9
    https://github.com/scummvm/scummvm/commit/efb746f79294f1daf53b6ed74718b516911e28a9
Author: Christian Kündig (christian at kuendig.info)
Date: 2022-06-12T14:40:56+02:00

Commit Message:
TESTBED: Don't write to disk if WriteStream can't be created (e.g. read-only filesystem or permission issue)

Changed paths:
    engines/testbed/config.cpp


diff --git a/engines/testbed/config.cpp b/engines/testbed/config.cpp
index 7124d75d168..808e828fd42 100644
--- a/engines/testbed/config.cpp
+++ b/engines/testbed/config.cpp
@@ -124,8 +124,10 @@ void TestbedOptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd,
 	case GUI::kCloseCmd:
 		// This is final selected state, write it to config file.
 		ws = _testbedConfMan->getConfigWriteStream();
-		_testbedConfMan->writeTestbedConfigToStream(ws);
-		delete ws;
+		if (ws) {
+			_testbedConfMan->writeTestbedConfigToStream(ws);
+			delete ws;
+		}
 		break;
 
 	default:


Commit: 42e500dd320681e4b2d7ba3ccec833d385385a47
    https://github.com/scummvm/scummvm/commit/42e500dd320681e4b2d7ba3ccec833d385385a47
Author: Christian Kündig (christian at kuendig.info)
Date: 2022-06-12T14:41:08+02:00

Commit Message:
EMSCRIPTEN: Merging parts of scummvm/scummvm#3686 for fullscreen support, disabling exit buttons (openURL has been fixed in libsdl-org/SDL at 15ebad6e7d0ede2d811cc83100ddcd258a052ca8 and is not needed anymore)

Changed paths:
  A backends/platform/sdl/emscripten/emscripten-main.cpp
  A backends/platform/sdl/emscripten/emscripten.cpp
  A backends/platform/sdl/emscripten/emscripten.h
    backends/platform/sdl/module.mk
    backends/platform/sdl/posix/posix-main.cpp
    configure


diff --git a/backends/platform/sdl/emscripten/emscripten-main.cpp b/backends/platform/sdl/emscripten/emscripten-main.cpp
new file mode 100644
index 00000000000..8727d36459b
--- /dev/null
+++ b/backends/platform/sdl/emscripten/emscripten-main.cpp
@@ -0,0 +1,50 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#if defined(__EMSCRIPTEN__) 
+#include "backends/platform/sdl/emscripten/emscripten.h"
+#include "backends/plugins/sdl/sdl-provider.h"
+#include "base/main.h"
+
+int main(int argc, char *argv[]) {
+
+	// Create our OSystem instance
+	g_system = new OSystem_Emscripten();
+	assert(g_system);
+
+	// Pre initialize the backend
+	g_system->init();
+
+#ifdef DYNAMIC_MODULES
+	PluginManager::instance().addPluginProvider(new SDLPluginProvider());
+#endif
+
+	// Invoke the actual ScummVM main entry point:
+	int res = scummvm_main(argc, argv);
+
+	// Free OSystem
+	g_system->destroy();
+
+	return res;
+}
+#endif
diff --git a/backends/platform/sdl/emscripten/emscripten.cpp b/backends/platform/sdl/emscripten/emscripten.cpp
new file mode 100644
index 00000000000..0570eada84a
--- /dev/null
+++ b/backends/platform/sdl/emscripten/emscripten.cpp
@@ -0,0 +1,71 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef __EMSCRIPTEN__
+
+
+#define FORBIDDEN_SYMBOL_EXCEPTION_FILE
+#include <emscripten.h>
+
+#include "backends/platform/sdl/emscripten/emscripten.h"
+
+// Inline JavaScript, see https://emscripten.org/docs/api_reference/emscripten.h.html#inline-assembly-javascript for details
+EM_JS(bool, isFullscreen, (), {
+	return !!document.fullscreenElement;
+});
+
+EM_JS(void, toggleFullscreen, (bool enable), {
+	let canvas = document.getElementById('canvas');
+	if (enable && !document.fullscreenElement) {
+		canvas.requestFullscreen();
+	}
+	if (!enable && document.fullscreenElement) {
+		document.exitFullscreen();
+	}
+});
+
+
+// Overridden functions
+bool OSystem_Emscripten::hasFeature(Feature f) {
+	if (f == kFeatureFullscreenMode)
+		return true;
+	if (f == kFeatureNoQuit)
+		return true;
+	return OSystem_POSIX::hasFeature(f);
+}
+
+bool OSystem_Emscripten::getFeatureState(Feature f) {
+	if (f == kFeatureFullscreenMode) {
+		return isFullscreen();
+	} else {
+		return OSystem_POSIX::getFeatureState(f);
+	}
+}
+
+void OSystem_Emscripten::setFeatureState(Feature f, bool enable) {
+	if (f == kFeatureFullscreenMode) {
+		toggleFullscreen(enable);
+	} else {
+		OSystem_POSIX::setFeatureState(f, enable);
+	}
+}
+
+#endif
diff --git a/backends/platform/sdl/emscripten/emscripten.h b/backends/platform/sdl/emscripten/emscripten.h
new file mode 100644
index 00000000000..bb3aa33328f
--- /dev/null
+++ b/backends/platform/sdl/emscripten/emscripten.h
@@ -0,0 +1,35 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef PLATFORM_SDL_EMSCRIPTEN_H
+#define PLATFORM_SDL_EMSCRIPTEN_H
+
+#include "backends/platform/sdl/posix/posix.h"
+
+class OSystem_Emscripten : public OSystem_POSIX {
+public:
+	bool hasFeature(Feature f) override;
+	void setFeatureState(Feature f, bool enable) override;
+	bool getFeatureState(Feature f) override;
+
+};
+
+#endif
diff --git a/backends/platform/sdl/module.mk b/backends/platform/sdl/module.mk
index 68f5db876ca..e3d1795796f 100644
--- a/backends/platform/sdl/module.mk
+++ b/backends/platform/sdl/module.mk
@@ -72,6 +72,12 @@ MODULE_OBJS += \
 	switch/switch.o
 endif
 
+ifdef EMSCRIPTEN
+MODULE_OBJS += \
+	emscripten/emscripten-main.o \
+	emscripten/emscripten.o
+endif
+
 # We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
 MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
 OBJS := $(MODULE_OBJS) $(OBJS)
diff --git a/backends/platform/sdl/posix/posix-main.cpp b/backends/platform/sdl/posix/posix-main.cpp
index 5960df37919..852731ff8a1 100644
--- a/backends/platform/sdl/posix/posix-main.cpp
+++ b/backends/platform/sdl/posix/posix-main.cpp
@@ -21,7 +21,7 @@
 
 #include "common/scummsys.h"
 
-#if defined(POSIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(MAEMO) && !defined(GPH_DEVICE) && !defined(GP2X) && !defined(DINGUX) && !defined(OPENPANDORA) && !defined(PLAYSTATION3) && !defined(PSP2) && !defined(NINTENDO_SWITCH)
+#if defined(POSIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(MAEMO) && !defined(GPH_DEVICE) && !defined(GP2X) && !defined(DINGUX) && !defined(OPENPANDORA) && !defined(PLAYSTATION3) && !defined(PSP2) && !defined(NINTENDO_SWITCH)  && !defined(__EMSCRIPTEN__)
 
 #include "backends/platform/sdl/posix/posix.h"
 #include "backends/plugins/sdl/sdl-provider.h"
diff --git a/configure b/configure
index 2c534b5a0e6..259b0927f48 100755
--- a/configure
+++ b/configure
@@ -2900,6 +2900,10 @@ EOF
 		_freetype_found="true"
 		if test "$_debug_build" = no; then
 			_optimization_level=-O3 -g4
+	
+		append_var DEFINES "-DEMSCRIPTEN"
+		add_line_to_config_mk 'EMSCRIPTEN = 1'
+
 		else
 			_optimization_level=-O2
 		fi


Commit: 6a90a32a1f2e301c57b1dd7840eda62814081c28
    https://github.com/scummvm/scummvm/commit/6a90a32a1f2e301c57b1dd7840eda62814081c28
Author: Christian Kündig (christian at kuendig.info)
Date: 2022-06-12T14:41:32+02:00

Commit Message:
EMSCRIPTEN: Major build improvements

- Updated Emscripten to version 3.1.8 (+ additional patches)
- Support for dynamic plugins
- Adding ScummvmFS with support for HTTP Range Requests for game data
- Automated games/demos bundling and ini config generation during build
- Allow passing CLI arguments via fragment identifier of the website (i.e. scummvm.html#—debuglevel=9 )
- UI improvements with nicer status messages, splash screen + favicon
- Fixed HiDPI handling and responsiveness
- Bugfix: Don't crash if gamepad support isn't available

Changed paths:
  A dists/emscripten/assets/manifest.json
  A dists/emscripten/assets/scummvm-192.png
  A dists/emscripten/assets/scummvm-512.png
  A dists/emscripten/assets/scummvm.ini
  A dists/emscripten/assets/scummvm_fs.js
  A dists/emscripten/build-add_games.js
  A dists/emscripten/build-download_games.js
  A dists/emscripten/build-make_http_index.js
  A dists/emscripten/custom_shell-post.js
  A dists/emscripten/custom_shell-pre.js
  A dists/emscripten/emscripten-15893-fix.patch
  A dists/emscripten/emscripten-15893.patch
  A dists/emscripten/emscripten-16559.patch
  A dists/emscripten/emscripten-16687.patch
  R dists/emscripten/manifest.json
  R dists/emscripten/post.js
  R dists/emscripten/pre.js
  R dists/emscripten/scummvm-192.png
  R dists/emscripten/scummvm-512.png
    configure
    dists/emscripten/README.md
    dists/emscripten/build.sh
    dists/emscripten/custom_shell.html


diff --git a/configure b/configure
index 259b0927f48..5d6f3f84f30 100755
--- a/configure
+++ b/configure
@@ -838,6 +838,7 @@ Special configuration feature:
                                            psp for PlayStation Portable
                                            samsungtv for Samsung TV
                                            switch for Nintendo Switch
+                                           wasm32-unknown-emscripten for WebAssembly
                                            wii for Nintendo Wii
 
 Game engines:
@@ -1709,7 +1710,7 @@ wasm32-*)
 	_endian=little # the endian check below fails, but emscripten is always little endian anyway
 	_host_os=emscripten
 	_host_cpu=wasm32
-	datadir='/scummvm'
+	datadir='/data'
 	CXX="em++"
 	;;
 wii)
@@ -2888,24 +2889,46 @@ EOF
 		;;
 	emscripten)
 		# mandatory emscripten flags
-		append_var LDFLAGS "-s FULL_ES2=1 -s MAX_WEBGL_VERSION=1 -s ASYNCIFY -s FORCE_FILESYSTEM=1 -s ALLOW_MEMORY_GROWTH=1"
-		# enable emscripten-ports and set up paths accordingly
-		append_var LDFLAGS "-s USE_SDL=2 -s USE_SDL_MIXER=2  -s USE_OGG=1 -s USE_VORBIS=1  -s USE_LIBJPEG=1  -s USE_FREETYPE=1 -s USE_ZLIB"
-		_sdlpath="$EMSDK/upstream/emscripten/system/bin/"
-		_pngpath="$EMSDK/upstream/emscripten/cache/"
-		_freetypepath="$EMSDK/upstream/emscripten/cache/ports-builds/freetype/"
-		VORBIS_CFLAGS="-I$EMSDK/upstream/emscripten/cache//ports-builds/vorbis/include"
-		VORBIS_LIBS="-L$EMSDK/upstream/emscripten/cache/ports-builds/vorbis/lib"
-		FREETYPE2_CFLAGS="-I$_freetypepath/include"
-		_freetype_found="true"
-		if test "$_debug_build" = no; then
-			_optimization_level=-O3 -g4
+		append_var LDFLAGS "-s ALLOW_MEMORY_GROWTH=1 -s ASYNCIFY -s FORCE_FILESYSTEM=1"
 	
 		append_var DEFINES "-DEMSCRIPTEN"
 		add_line_to_config_mk 'EMSCRIPTEN = 1'
 
+		if test "$_debug_build" = yes; then
+			_optimization_level=-O2 
+			append_var LDFLAGS "-O2 -g3 -s ASSERTIONS=2"
 		else
-			_optimization_level=-O2
+			_optimization_level=-O3
+			append_var LDFLAGS "-O3"
+		fi
+
+		# activate emscripten-ports
+		if test "$_freetype2" != no; then
+			append_var LDFLAGS "-s USE_FREETYPE=1 -s SUPPORT_LONGJMP=1" # freetype requires setjmp
+			# neither pkg-config nor freetype-config work, so we setup freetype manually
+			_freetypepath="$EMSCRIPTEN/cache/ports-builds/freetype/"
+			FREETYPE2_CFLAGS="-I$_freetypepath/include" # there were link errors / missing symbols without this
+			_freetype_found="true"
+		else 
+			#use link time optimization to further reduce exe size (this can't be used with setjmp whcih freetype requires)
+			# TODO: Figure out why this is a conflict and/or if freetype can be built without setjmp
+			append_var CXXFLAGS "-flto"
+			append_var LDFLAGS "-flto"
+		fi
+		if test "$_jpeg" != no; then 
+			append_var LDFLAGS "-s USE_LIBJPEG=1"
+		fi
+		if test "$_png" != no; then
+			append_var LDFLAGS "-s USE_LIBPNG=1"
+		fi
+		if test "$_sdl" != no; then
+			append_var LDFLAGS "-s USE_SDL=2 "
+		fi 
+		if test "$_vorbis" != no; then 
+			append_var LDFLAGS "-s USE_OGG=1" # vorbis needs to be linked against OGG (even if we use an external vorbis lib)
+		fi
+		if test "$_zlib" != no; then
+			append_var LDFLAGS "-s USE_ZLIB=1"
 		fi
 	;;
 	freebsd*)
@@ -3247,8 +3270,11 @@ if test -n "$_host"; then
 			;;
 		wasm*-emscripten)
 			_backend="sdl"
-			HOSTEXEPRE=
-			HOSTEXEEXT=.html
+			# Disable cloud and SDL_Net as this is handled in the browser
+			_cloud=no
+			_sdlnet=no
+			_libcurl=no
+			_curl=no
 			_ar="emar cr"
 			_ranlib="emranlib"
 			;;
@@ -4127,12 +4153,13 @@ PLUGIN_LDFLAGS		+= -Wl,-T$(srcdir)/backends/plugins/ds/plugin.ld -mthumb -mthumb
 		;;
 	emscripten)
 		_plugin_prefix="lib"
-		_plugin_suffix=".wasm"
+		_plugin_suffix=".so"
+		append_var DEFINES "-DUNCACHED_PLUGINS"
 		append_var CXXFLAGS "-fPIC"
 		append_var LIBS ""
 _mak_plugins='
 PLUGIN_EXTRA_DEPS =
-PLUGIN_LDFLAGS  += -s SIDE_MODULE=1 -s EXPORT_ALL=1
+PLUGIN_LDFLAGS  += $(LDFLAGS) -s SIDE_MODULE=1 -s ASYNCIFY_IMPORTS=["*"] -s EXPORT_ALL=1
 PRE_OBJS_FLAGS  := -s MAIN_MODULE=1 -s EXPORT_ALL=1
 POST_OBJS_FLAGS :=
 '
@@ -5389,7 +5416,11 @@ if test "$_opengl_mode" != none ; then
 						darwin*)
 							_opengl_mode=gl
 							;;
-
+						emscripten)
+							_opengl_mode=gles2
+							_opengl_glad=no
+							append_var LDFLAGS "-s FULL_ES2=1 -s MAX_WEBGL_VERSION=1"
+							;;
 						*)
 							# As SDL2 supports everything, let the user choose if he wants to
 							test "$_opengl_mode" = "auto" && _opengl_mode=any
@@ -5403,9 +5434,6 @@ if test "$_opengl_mode" != none ; then
 			_opengl_mode=gles2
 			_opengl_glad=yes
 			;;
-		wasm*-emscripten)
-			_opengl_mode=gles2
-			;;
 		*)
 			# On all other platforms, by default don't enable OpenGL
 			test "$_opengl_mode" = "auto" && _opengl_mode=none
@@ -6185,6 +6213,22 @@ case $_host_os in
 			# append_var LDFLAGS "-Wl,--retain-symbols-file,ds.syms"
 		fi
 		;;
+	emscripten)
+		append_var LDFLAGS "--pre-js ./dists/emscripten/custom_shell-pre.js --post-js ./dists/emscripten/custom_shell-post.js --shell-file ./dists/emscripten/custom_shell.html"
+		# we remove some linker flags for libs which will be added by emscripten from emscripten-ports to avoid duplicate symbols
+		if test "${LDFLAGS#*-s USE_LIBJPEG=1}" != "$LDFLAGS"; then
+    		LIBS=`echo ${LIBS} | sed 's/-ljpeg//g'`
+		fi
+		if test "${LDFLAGS#*-s USE_LIBPNG=1}" != "$LDFLAGS"; then
+			LIBS=`echo ${LIBS} | sed 's/-lpng -lz//g'`
+		fi
+		if test "${LDFLAGS#*-s USE_OGG=1}" != "$LDFLAGS"; then
+			LIBS=`echo ${LIBS} | sed 's/-logg//g'`
+		fi
+		if test "${LDFLAGS#*-s USE_ZLIB=1}" != "$LDFLAGS"; then
+			LIBS=`echo ${LIBS} | sed 's/-lz//g'`
+		fi
+		;;
 	mingw*)
 		if test "$_windows_unicode" = yes; then
 			append_var DEFINES "-DUNICODE -D_UNICODE"
diff --git a/dists/emscripten/README.md b/dists/emscripten/README.md
index 5b70d104bdd..4e00f53273e 100644
--- a/dists/emscripten/README.md
+++ b/dists/emscripten/README.md
@@ -1,66 +1,93 @@
+
 # Building ScummVM for Webassembly
 The [Emscripten](https://emscripten.org/) target provides a script to build ScummVM as a single page browser app.
-> Emscripten is an LLVM/Clang-based compiler that compiles C and C++ source code to WebAssembly for execution in web browsers. 
 
-## Current State
-*   All engines compile (though I didn't test all of them), including ResidualVM with WebGL acceleration and shaders.
-*   Audio works and 3rd-party libraries for sound and video decoding are integrated.
-*   Proof of concept integration with [BrowserFS](https://github.com/jvilk/browserfs) to download game data lazily when required and to support local savegames.
+## Goals
+This port of ScummVM has two primary use cases as its goals:
+
+- **Demo App**: The goal of this use case is to provide an easy way for people to discover ScummVM and old adventure games. Game preservation is not just about archival but also accessibility. The primary goal is to make it as easy as possible to play any game which can legally be made available, and there's probably nothing easier than opening a webpage to do so.
+
+- **ScummVM as a PWA** (progressive web app): There are platforms where native ScummVM is not readily available (primarily iOS/iPadOS). A PWA can work around these limitations. To really make this work, a few more features beyond what's in a Demo App would be required: 
+  * Offline Support: PWAs can run offline. This means we have to find a way to cache some data which is downloaded on demand (engine plugins, game data etc.) 
+  * Cloud Storage Integration: Users will have to have a way to bring their own games and export savegame data. This is best possible through cloud storage integration. This already exists in ScummVM, but a few adjustments will be necessary to make this work in a PWA.
+  
+See [chkuendig/scummvm-demo](http://github.com/chkuendig/scummvm-demo/) on how a ScummVM demo app can be built (incl. playable demo).
+  
+## About Webassembly and Emscripten
+Emscripten is an LLVM/Clang-based compiler that compiles C and C++ source code to WebAssembly for execution in web browsers. 
+
+**Note:** In general most code can be crosscompiled to webassembly just fine. There's a few minor things which are different, but the mayor difference comnes down to how instructions are processed: Javascript and webassembly do support asynchronous/non-blocking code, but in general everything is running in the same [event loop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop). This means also that webassembly code has to pause for the browser to do it's operations - render the page, process inputs, run I/O and so on. One consequence of this is that the page is not re-drawn until the webassembly code "yields" to the browser. Emscripten provides as much tooling as possible for this, but there's sometimes still a need to manually add a call to sleep into some engines.
 
 ## How to build for Webassembly
 This folder contains a script to help build scummvm with Emscripten, it automatically downloads the correct emsdk version and also takes care of bundling the data and setting up a few demo games.
 
-### Running `emscripten/build.sh`
+### Running build.sh
 
-`emscripten/build.sh` needs to be run from the root of the project. 
+`build.sh` needs to be run from the root of the project. 
 ```Shell
-./dists/emscripten/build.sh libs|configure|make|data|dist|all|clean
+./dists/emscripten/build.sh [Tasks] [Options]
 ```
-It accepts a single parameter with 7 valid commands:
-*   `libs`: Download and compile the required 3rd-party libraries required to build certain engines (libmad, a52dec etc)
-*   `configure`: Run the configure script with emconfigure with the recommended settings for a simple demo page 
-*   `make`: Run the make scripts with emmake
-*   `data`: Download some demos and set up all data require for the demo page 
-*   `dist`: Copy all files into a single build-emscripten folder to bring it all together
-*   `all`: Run all of the above commands
-*   `clean`: Remove all object files, built libs, bundled data etc
+
+**Tasks:** space separated list of tasks to run. These can be:  
+* `build`: Run all tasks to build the complete app. These tasks are:
+  *  `setup`: Download + install EMSDK and emscripten
+  *  `libs`: Download and compile the required 3rd-party libraries required to build certain engines (libmad, a52dec etc)
+  *   `configure`: Run the configure script with emconfigure with the recommended settings for a simple demo page 
+  *   `make`: Run the make scripts with emmake
+  *   `games`: Download some demos and set up all data require for the demo page. See `--bundle-games=` below.
+  *   `dist`: Copy all files into a single build-emscripten folder to bring it all together
+  *   `add-games`: Runs ScummVM once to add all bundled games to the default `scummvm.ini`
+* `clean`: Cleanup build artifacts (keeps libs + emsdk in place)
+* `run`: Start webserver and launch ScummVM in Chrome  
+  
+**Options:**
+*  `-h`, `--help`: print a short help text
+*  `--bundle-games=<games>`: comma-separated list of demos and freeware games to bundle. Either specify a target (e.g. `comi` or a target and a specific file after a `/` , e.g. `comi/comi-win-large-demo-en.zip`)
+*  `-v`, `--verbose`: print all commands run by the script
+*  `--*`: all other options are passed on to the scummvm configure script
 
 Independent of the command executed, the script sets up a pre-defined emsdk environment in the subfolder `./dists/emscripten/build.sh`
 
+**Example:**
+
+See e.g. [chkuendig/scummvm-demo/.github/workflows/main.yml](https://github.com/chkuendig/scummvm-demo/blob/main/.github/workflows/main.yml) for an example:
+```
+./dists/emscripten/build.sh build --verbose --disable-all-engines --enable-plugins --default-dynamic  --enable-engine=adl,testbed,scumm,scumm_7_8,grim,monkey4,mohawk,myst,riven,sci32,agos2,sword2,drascula,sky,lure,queen,testbed,director,stark --bundle-games=testbed,comi/comi-win-large-demo-en.zip,warlock,sky/BASS-Floppy-1.3.zip,drascula/drascula-audio-mp3-2.0.zip,monkey4,feeble,queen/FOTAQ_Floppy.zip,ft,grim/grim-win-demo2-en.zip,lsl7,lure,myst,phantasmagoria,riven,hires1,tlj,sword2
+```
+
+## Current Status of Port
+In general, ScummVM runs in the browser sufficiently to run all demos and freeware games.
+
+* All engines compile (though I didn't test all of them), including ResidualVM with WebGL acceleration and shaders work as plugins (which means the initial page load is somewhat limited)
+* Audio works and 3rd-party libraries for sound and video decoding are integrated.
+* All data can be downloaded on demand (or in the case of the testbed generated as part of the build script)
+
 ## Known Issues + Possible Improvements
-Some ideas for possible improvements:
 
 ### Emscripten Optimizations
-*   Optimize asyncify behaviour (we only have SDL functions calling wait currently), e.g with [SDL_HINT_EMSCRIPTEN_ASYNCIFY](https://wiki.libsdl.org/SDL_HINT_EMSCRIPTEN_ASYNCIFY).
-*   Specify a `ASYNCIFY_ONLY` list to to make asyncify only instrument functions in the call path as described in [emscripten.org: Asyncify](https://emscripten.org/docs/porting/asyncify.html)
+*   Optimize asyncify behaviour (we only have SDL functions calling wait currently), e.g with [SDL_HINT_EMSCRIPTEN_ASYNCIFY](https://wiki.libsdl.org/SDL_HINT_EMSCRIPTEN_ASYNCIFY)
+*   Specify a `ASYNCIFY_ONLY` list in `configure` to  make asyncify only instrument functions in the call path as described in [emscripten.org: Asyncify](https://emscripten.org/docs/porting/asyncify.html)
+*   Limit asyncify overhead by having a more specific setting for `ASYNCIFY_IMPORTS` in `configure`.
 *   Don't use asyncify but rewrite main loop to improve performance
-*   Shrink code size or execution speed with `-Os` or `-Oz` [emcc arguments](https://emscripten.org/docs/tools_reference/emcc.html#emcc-compiler-optimization-options).
 
 ### Storage Integration
-*   BrowserFS seems abandoned and never did a stable 2.0.0 release. Maybe there's a better way to handle storage?
-
-*   File loading improvements:
-    *   Load assets with HTTP Range request headers.
-    *   Load assets asynchronously (not blocking) via a worker.
+*   BrowserFS seems abandoned and never did a stable 2.0.0 release. It's worth replacing it.  
+    * `scummvm_fs.js` is an early prototype for a custom FS which can be adopted for ScummVM specific needs, i.e.
+      * Download all game assets in background once the game has started
+      * Presist last game and last plugin for offline use
+      * Implement support for range requests (currently not supported with `emrun` so another development server would have to be included as well)
+      * Pre-load assets asynchronously (not blocking) - i.e. rest of the data of a game which has been launched
+      * Loading indicators
 
 *   Add support for save games (and game data?) on personal cloud storage (Dropbox, Google Drive).
 
 ### UI Integration
-*   Responsiveness: Adjust the canvas size when resizing the browser. 
-
-*   Bug: Fullscreen mode doesn't work.
-
 *   Build a nice webpage around the canvas.
-    *   Allow hiding of console, replace buttons/checkboxes from default emscripten template.
+    *   Allow showing/hiding of console, replace buttons/checkboxes from default emscripten template.
     *   Bonus: Adapt page padding/background color to theme (black when in game)
 
-*   ScummVM shouldn't be able to "close" (there's no concept for that:
-    *   Remove "exit" buttons from all menus.
-    *   Change any programmatic "exits" to cause a restart of Scummvm (or refresh of the page).
-
-*   Pass CLI parameters for ScummVM via URL parameters to allow for "deep-linking" to a specific game.
+*   Automatically show console in case of exceptions
 
-### Other Bugs + Tasks
-*   Bug: Vorbis support is broken - parts seems to have been patched out so  `-lvorbisfile` triggers an error during configure (and [emscripten-core/emscripten#9849](https://github.com/emscripten-core/emscripten/pull/9849) doesn't seem to fix this).
-*   Bug: Going back to main menu from Grim (and other Residual Games?) messes up the render context and the UI is unusable.
-*   Check all disabled features (e.g. TiMidity++) and see if they could be enabled (some might never make sense, e.g. anything requiring MIDI Hardware, Update Checking etc).
\ No newline at end of file
+* Aspect Ratio is broken when starting a game until the window is resized once. Good starting points might be  https://github.com/emscripten-ports/SDL2/issues/47 or https://github.com/emscripten-core/emscripten/issues/10285
+    * doesn't seem to affect 3d engines in opengl mode
+    * definitely affects testbed in opengl or other modes
\ No newline at end of file
diff --git a/dists/emscripten/manifest.json b/dists/emscripten/assets/manifest.json
similarity index 100%
rename from dists/emscripten/manifest.json
rename to dists/emscripten/assets/manifest.json
diff --git a/dists/emscripten/assets/scummvm-192.png b/dists/emscripten/assets/scummvm-192.png
new file mode 100644
index 00000000000..f522677c432
Binary files /dev/null and b/dists/emscripten/assets/scummvm-192.png differ
diff --git a/dists/emscripten/assets/scummvm-512.png b/dists/emscripten/assets/scummvm-512.png
new file mode 100644
index 00000000000..6710facaf6d
Binary files /dev/null and b/dists/emscripten/assets/scummvm-512.png differ
diff --git a/dists/emscripten/assets/scummvm.ini b/dists/emscripten/assets/scummvm.ini
new file mode 100644
index 00000000000..e8441905942
--- /dev/null
+++ b/dists/emscripten/assets/scummvm.ini
@@ -0,0 +1,6 @@
+[scummvm]
+gfx_mode=opengl
+pluginspath=/plugins
+grouping=company
+renderer=opengl_shaders
+
diff --git a/dists/emscripten/assets/scummvm_fs.js b/dists/emscripten/assets/scummvm_fs.js
new file mode 100644
index 00000000000..bdae7e67bcc
--- /dev/null
+++ b/dists/emscripten/assets/scummvm_fs.js
@@ -0,0 +1,496 @@
+
+/*
+ * ScummvmFS - A custom Emscripten filesystem for ScummVM
+ * 
+ * This is the filesystem used to load any read-only files used by ScummVM: data, games and 
+ * plugins. It supports range-requests and caches data in memory to minimize latency when loading
+ * data from the network. 
+ * 
+ * Adapted from Emscripten's NodeFS and BrowserFS' EmscriptenFS + XHR backend:
+ * https://github.com/emscripten-core/emscripten/blob/main/src/library_nodefs.js
+ * https://github.com/jvilk/BrowserFS/blob/master/src/generic/emscripten_fs.ts
+ * https://github.com/jvilk/BrowserFS/blob/master/src/generic/xhr.ts
+ */
+const DIR_MODE = 16895; // 040777
+const FILE_MODE = 33206; // 100666
+const SEEK_SET = 0;
+const SEEK_CUR = 1;
+const SEEK_END = 2;
+const RANGE_REQUEST_BLOCK_SIZE = 1024 * 1024
+const ERRNO_CODES = {
+    // TODO: We should get these from Emscripten - see https://github.com/emscripten-core/emscripten/issues/10061 and https://github.com/emscripten-core/emscripten/issues/14783
+    EPERM: 1, // Operation not permitted
+    ENOENT: 2, // No such file or directory
+    EINVAL: 22 // I©nvalid argument
+};
+
+
+const DEBUG = false
+
+
+export class ScummvmFS {
+    url;
+    fs_index;
+    stream_ops;
+    node_ops;
+    FS;
+    constructor(_FS, _url) {
+        this.FS = _FS;
+        this.url = _url
+        var req = new XMLHttpRequest(); // a new request
+        req.open("GET", _url + "/index.json", false);
+        req.send(null);
+        var json_index = JSON.parse(req.responseText)
+        this.fs_index = {}
+        var walk_index = function (path, dir) {
+            logger(path, "walk_index")
+            this.fs_index[path] = null
+            if (path != "/") {
+                path = path + "/"
+            }
+            for (var key in dir) {
+                if (typeof dir[key] === 'object') {
+                    walk_index(path + key, dir[key]) // toLowerCase to simulate a case-insensitive filesystem
+                } else {
+                    if (key !== "index.json") {
+                        this.fs_index[path + key] = dir[key] // toLowerCase to simulate a case-insensitive filesystem
+                    }
+                }
+
+            }
+        }.bind(this)
+
+        walk_index("/", json_index)
+    }
+
+    listDirectory(_path) {
+        const path = _path.path
+        var result = []
+        for (var node in this.fs_index) {
+            if (node.startsWith(path) && node.lastIndexOf("/") <= path.length && node !== path && node.substr(path.length + 1).length > 0 && node.charAt(path.length) == "/") {
+                result.push(node.substr(path.length + 1))
+            }
+        }
+        return { ok: true, data: result };
+    }
+
+    // used for open
+    get(_path) {
+        const path = _path.path
+        logger(path, "get")
+        if (path in this.fs_index) {
+            // if  this.fs_index[path] is still a integer (hence a file), we now initialize the array to store any file data
+            if (Number.isInteger(this.fs_index[path])) { // if not a number we either already have iniitalized the data or it's a folder
+                const size = this.fs_index[path];
+                var data;
+                data = new Array(Math.ceil(size / RANGE_REQUEST_BLOCK_SIZE)) // data will be an array of blocks
+
+                this.fs_index[path] = { size: this.fs_index[path], data: data }
+                return { ok: true, data: data, size: size };
+            } else if (typeof this.fs_index[path] == "object" && this.fs_index[path] !== null) {
+                return { ok: true, data: this.fs_index[path].data, size: this.fs_index[path].size }; // already initialized
+            } else {
+                return { ok: true, data: null }; // directory
+            }
+        } else {
+            return { ok: false }
+        }
+    }
+
+    // used for close, mknod
+    put(args) {
+        const path = args.path
+        logger(path, "put")
+        if (!this.fs_index[path]) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
+        }
+
+        return { ok: true, data: this.fs_index[path].data };
+    }
+
+    read(args) {
+        const path = args.path;
+        logger(path, "read, args:" + JSON.stringify(args))
+
+        if (typeof this.fs_index[path] !== "object") {
+            console.error("File hasn't been opened yet")
+            throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        const start = args.start;
+        const end = (args.end > (this.fs_index[path].size)) ? (this.fs_index[path].size) : args.end // sometimes we get requests beyond the end of the file (????)
+        var first_block = Math.floor(start / RANGE_REQUEST_BLOCK_SIZE)
+        var last_block = Math.floor(end / RANGE_REQUEST_BLOCK_SIZE)
+        if (start > end) {
+            return { ok: true, data: [] };
+        }
+        var alreadyLoaded = false;
+        if (Array.isArray(this.fs_index[path].data)) {
+            alreadyLoaded = true
+            for (var idx = first_block; idx <= last_block; idx++) {
+                if (this.fs_index[path].data[idx] == undefined) {
+                    logger(path, "block " + idx + " missing")
+                    alreadyLoaded = false
+                    break;
+                }
+            }
+        }
+
+        let data = null;
+        logger(path, "file alreadyLoaded=" + alreadyLoaded)
+        if (alreadyLoaded) {
+            data = new Uint8Array(end - start + 1);
+            for (var block = first_block; block <= last_block; block++) {
+                // TODO: we should start at start at the request start and not block start (same for end)
+                for (var idx = Math.max(start, block * RANGE_REQUEST_BLOCK_SIZE); idx <= Math.min(end, block * RANGE_REQUEST_BLOCK_SIZE + this.fs_index[path].data[block].length - 1); idx++) {
+                    if (idx >= start && idx <= end) {
+                        data[idx - start] = this.fs_index[path].data[block][idx - block * RANGE_REQUEST_BLOCK_SIZE]
+                    }
+                }
+            }
+            logger(path, "cache loaded ")
+        } else {
+
+            data = this.download(path, this.url, first_block, last_block, start, end);
+        }
+        return { ok: true, data: data };
+    }
+    download(path, _url, first_block, last_block, start, end) {
+        self = this;
+        let data = null;
+        const req = new XMLHttpRequest();
+        const url = _url + path;
+        req.open('GET', url, false);
+
+        let err = null;
+        // On most platforms, we cannot set the responseType of synchronous downloads.
+        // Classic hack to download binary data as a string.
+        req.overrideMimeType('text/plain; charset=x-user-defined');
+
+        // Trying to use range requests where possible
+        // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range
+        var range_start = first_block * RANGE_REQUEST_BLOCK_SIZE
+        var range_end = Math.min((last_block + 1) * RANGE_REQUEST_BLOCK_SIZE, this.fs_index[path].size) - 1
+        if (this.fs_index[path].size > (range_start - range_end + 1)) {
+            req.setRequestHeader('Range', 'bytes=' + range_start + '-' + range_end);
+        }
+
+        if (this.fs_index[path].data === null) {
+            this.fs_index[path].data = new Array(Math.ceil(this.fs_index[path].size / RANGE_REQUEST_BLOCK_SIZE));
+        }
+        req.onreadystatechange = function (e) {
+            if (req.readyState === 4) {
+                var text = req.responseText;
+                logger(path, "Downloaded " + text.length + " bytes");
+                data = new Uint8Array(end - start + 1);
+                if (req.status === 200) { // range request wasn't respected or requested
+                    for (let i = 0; i < text.length; i++) {
+                        if (i >= start && i <= end) {
+                            // This will automatically throw away the upper bit of each
+                            // character for us.
+                            data[i - start] = text.charCodeAt(i);
+                        }
+                        var block = Math.floor(i / RANGE_REQUEST_BLOCK_SIZE)
+                        if (self.fs_index[path].data[block] === undefined) {
+                            self.fs_index[path].data[block] = new Uint8Array(RANGE_REQUEST_BLOCK_SIZE)
+                        }
+                        self.fs_index[path].data[block][i - block * RANGE_REQUEST_BLOCK_SIZE] = text.charCodeAt(i)
+                    }
+                    logger(path, "Downloaded [full download]");
+                } else if (req.status === 206) { // partial response to range request
+                    var start_offset = start - range_start
+                    var end_offset = range_end - end
+
+                    logger(path, "First block: " + first_block + " last block: " + last_block + "Text length: " + text.length)
+                    var char_length = Math.round((range_end - range_start + 1) / text.length);
+                    if (char_length == 2 && text.length == (range_end - range_start + 1) / 2 - 1) {
+                        // The above hack to get binary data as text breaks if the first two bytes of the range are U+FEFF which is a BOM 
+                        // for UTF16 and the browsers convert the data into a UTF16 string. I initially tied to fix this by breaking up 
+                        // the UTF16 characters into 2 bytes and prepend the stripped BOM again,  but it turned out that there were other 
+                        // issues how browsers handle UTF16 (e.g. 0xDFC3, 0xDFAD, 0xDFFB, 0xDF5B all somehow getting converted to 0xFFFD 
+                        // - i.e. "REPLACEMENT CHARACTER") so this now just reruns shifts the start of the download. 
+                        // That's wasting some data, but it's a rare enough occurance
+                        //
+                        // TODO: The only proper fix for this is to implement a asynchronous filesystem for emscripten. Something which currently
+                        // isn't possible
+                        data = self.download(path, _url, first_block - 1, last_block, start, end)
+                    } else if (char_length == 1) {
+
+                        for (let i = 0; i < (range_end - range_start + 1); i++) {
+                            var block = Math.floor((range_start + i) / RANGE_REQUEST_BLOCK_SIZE)
+                            if (self.fs_index[path].data[block] === undefined) {
+                                self.fs_index[path].data[block] = new Uint8Array(RANGE_REQUEST_BLOCK_SIZE)
+                            }
+                            var block_pos = (range_start + i) - (block * RANGE_REQUEST_BLOCK_SIZE)
+                            // This will automatically throw away the upper bit of each
+                            // character for us.
+                            self.fs_index[path].data[block][block_pos] = text.charCodeAt(i)
+
+
+
+                        }
+                        logger(path, "First block length: " + self.fs_index[path].data[block] + " last block length: " + self.fs_index[path].data[block] + "Text length: " + text.length)
+                        for (var block = first_block; block <= last_block; block++) {
+                            // TODO: we should start at start at the request start and not block start (same for end)
+                            for (var idx = Math.max(start, block * RANGE_REQUEST_BLOCK_SIZE); idx <= Math.min(end, block * RANGE_REQUEST_BLOCK_SIZE + self.fs_index[path].data[block].length - 1); idx++) {
+                                if (idx >= start && idx <= end) {
+                                    data[idx - start] = self.fs_index[path].data[block][idx - block * RANGE_REQUEST_BLOCK_SIZE]
+                                }
+                            }
+                        }
+                        logger(path, "Downloaded [range request]");
+                    }
+                } else {
+                    console.error(req);
+                    throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+                }
+            }
+        };
+        req.send();
+        if (err) {
+            throw err;
+        }
+        return data;
+    }
+
+    mount(mount) {
+        return this.createNode(null, "/", DIR_MODE, 0);
+    }
+
+    createNode(parent, name, mode, size) {
+        logger(name, "createNode")
+        if (!this.FS.isDir(mode) && !this.FS.isFile(mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        let node = this.FS.createNode(parent, name, mode);
+        node.node_ops = this.node_ops;
+        node.stream_ops = this.stream_ops;
+        node.size = size
+        return node;
+    }
+
+    convertResult(result) {
+        if (result.ok) {
+            return result.data;
+        }
+        else {
+            let error;
+            if (result.status === 404) {
+                error = new FS.ErrnoError(ERRNO_CODES.ENOENT);
+            }
+            else {
+                error = new FS.ErrnoError(ERRNO_CODES.EPERM);
+            }
+            error.cause = result.error;
+            throw error;
+        }
+    }
+
+    node_ops = {
+        getattr: (node) => {
+            return {
+                dev: 1,
+                ino: node.id,
+                mode: node.mode,
+                nlink: 1,
+                uid: 0,
+                gid: 0,
+                rdev: undefined,
+                size: node.size,
+                atime: new Date(node.timestamp),
+                mtime: new Date(node.timestamp),
+                ctime: new Date(node.timestamp),
+                blksize: 4096,
+                blocks: 0,
+            };
+        },
+        setattr: (node, attr) => {
+            // Doesn't really do anything
+            if (attr.mode !== undefined) {
+                node.mode = attr.mode;
+            }
+            if (attr.timestamp !== undefined) {
+                node.timestamp = attr.timestamp;
+            }
+        },
+        lookup: (parent, name) => {
+            logger(name, "lookup ")
+            if (parent instanceof FS.FSStream) { //sometimes we get a stream instead of a node
+                parent = parent.node;
+            }
+            const path = realPath(parent, name);
+            const result = this.get({ path });
+            if (!result.ok) {
+                // I wish Javascript had inner exceptions
+                throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
+            }
+            return this.createNode(parent, name, result.data === null ? DIR_MODE : FILE_MODE, result.data ? result.size : null);
+        },
+        mknod: (parent, name, mode, dev) => {
+            logger(name, "mknod ")
+            const node = this.createNode(parent, name, mode, 0);
+            const path = realPath(node);
+            if (this.FS.isDir(node.mode)) {
+                this.convertResult(this.put({ path, value: null }));
+            }
+            else {
+                this.convertResult(this.put({ path, value: "" }));
+            }
+            return node;
+        },
+
+        rename: (oldNode, newDir, newName) => {
+            throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+            const oldPath = realPath(oldNode);
+            const newPath = realPath(newDir, newName);
+            this.convertResult(this.move({ path: oldPath, newPath: newPath }));
+            oldNode.name = newName;
+        },
+
+        unlink: (parent, name) => {
+            throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+            const path = realPath(parent, name);
+            this.convertResult(this.delete({ path }));
+        },
+
+        rmdir: (parent, name) => {
+            throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+            const path = realPath(parent, name);
+            this.convertResult(this.delete({ path }));
+        },
+
+        readdir: (node) => {
+            const path = realPath(node);
+            let result = this.convertResult(this.listDirectory({ path }));
+            if (!result.includes(".")) {
+                result.push(".");
+            }
+            if (!result.includes("..")) {
+                result.push("..");
+            }
+            return result;
+        },
+
+        symlink: (parent, newName, oldPath) => {
+            throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        },
+
+        readlink: (node) => {
+            throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+    }
+
+    stream_ops = {
+        open: (stream) => {
+            logger(stream.path, "Open stream ")
+            const path = realPath(stream.node);
+            if (FS.isFile(stream.node.mode)) {
+                const result = this.get({ path });
+                if (result.data === null || result.data === undefined) {
+                    return;
+                }
+                stream.fileData = result.data;
+                stream.fileSize = result.size;
+            }
+        },
+
+        close: (stream) => {
+            logger(stream.path, "close stream ")
+            const path = realPath(stream.node);
+            if (FS.isFile(stream.node.mode) && stream.fileData) {
+                const fileData = stream.fileData
+                // TODO: Track open/closed files differently so we can warn but don't lose the cached data
+                //stream.fileData = undefined;
+                this.convertResult(this.put({ path, value: fileData }));
+            }
+        },
+
+        read: (stream, buffer, offset, length, position) => {
+            if (!position) {
+                position = stream.position
+            }
+            // logger(stream.path, "read stream - offset:" + offset + " length:" + length + " position:" + position)
+            const path = realPath(stream.node);
+            var _a, _b;
+            if (length <= 0)
+                return 0;
+
+            var size = length
+            if (typeof stream.fileData === 'object' && stream.fileSize < position + length) {
+                size = stream.fileSize - position
+            }
+
+            // logger(stream.path, "Length, Position " + length + "," + position)
+            // logger(stream.path, "Size " + size)
+            // logger(stream.path, "stream.fileSize " + stream.fileSize)
+            if (size < 0) {
+                throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+            }
+            if (size > 0) {
+                var fileData = this.convertResult(this.read({ path: path, start: position, end: position + size - 1 }));
+                logger(stream.path, "fileData (start: " + (position) + " end: " + (position + size - 1).toString() + " (length: " + fileData.length + ")")
+
+                if (DEBUG) {
+                    logger(stream.path, Uint8Array2hex(fileData))
+                }
+                buffer.set(fileData, offset);
+            }
+            //    buffer.set(stream.fileData.subarray(position, position + size), offset);
+
+            return size;
+        },
+
+        write: (stream, buffer, offset, length, position) => {
+            // this FS actually can't write
+            throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        },
+
+        llseek: (stream, offset, whence) => {
+            let position = offset; // SEEK_SET
+            if (whence === SEEK_CUR) {
+                position += stream.position;
+            }
+            else if (whence === SEEK_END) {
+                if (this.FS.isFile(stream.node.mode)) {
+                    position += stream.fileSize;
+                }
+            } else if (whence !== SEEK_SET) {
+                console.error("Illegal Whence: " + whence)
+                throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+            }
+            if (position < 0) {
+                console.error("CRITICAL: Position < 0")
+                throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+            }
+            stream.position = position
+            return position;
+        }
+    }
+
+
+}
+
+function realPath(node, fileName) {
+    const parts = [];
+    while (node.parent !== node) {
+        parts.push(node.name);
+        node = node.parent;
+    }
+    parts.push(node.mount.opts.root);
+    parts.reverse();
+    if (fileName !== undefined && fileName !== null) {
+        parts.push(fileName);
+    }
+    return parts.join("/");
+}
+
+
+function logger(path, message) {
+    if (DEBUG) {
+        console.log(path + ": " + message)
+    }
+}
+function Uint8Array2hex(byteArray) {
+    return Array.prototype.map.call(byteArray, function (byte) {
+        return ('0' + (byte & 0xFF).toString(16)).slice(-2).toUpperCase();
+    }).join(' ');
+}
\ No newline at end of file
diff --git a/dists/emscripten/build-add_games.js b/dists/emscripten/build-add_games.js
new file mode 100644
index 00000000000..dc110fc7410
--- /dev/null
+++ b/dists/emscripten/build-add_games.js
@@ -0,0 +1,45 @@
+
+const http = require('http');
+const fs = require('fs');
+const puppeteer = require('puppeteer');
+const static = require('node-static');
+
+var file = new (static.Server)("./");
+const server = http.createServer(function (req, res) {
+    file.serve(req, res);
+}).listen(8080, async () => {
+    const browser = await puppeteer.launch({ headless: true });
+    const page = await browser.newPage();
+
+    await page.goto('http://localhost:8080/scummvm.html#--add --path=/games --recursive');
+
+    await page.screenshot({ path: 'example.png' });
+    const regex = /Added ([0-9]+) games/;
+    page.on('console', async msg => {
+        const text = msg.text()
+        console.log(text)
+        const match = text.match(regex);
+        if (match != null && match.length > 0) {
+            console.log("Detection finished, exporting ini file for " + match[1] + " detected games.")
+            const localStorage = await page.evaluate(() => Object.assign({}, window.localStorage));
+
+            const ini_inode_id = "1b4a97d1-4ce0-417f-985c-e0f22ca21aef"  // defined in custom_shell.html
+            const ini_lines = Buffer.from(localStorage[ini_inode_id], 'base64').toString().split('\n');
+            // GRIM games check data consistency by reading all files. That's an expensive operation over
+            // the network. Since we anyway should have known good data at build time, this script disables
+            // that check.
+            for (var i = 0; i < ini_lines.length; i++) {
+                if (ini_lines[i] == "engineid=grim") {
+                    ini_lines[i] = "check_gamedata=false\n" + ini_lines[i]
+                }
+            }
+            fs.writeFileSync("scummvm.ini", ini_lines.join('\n'));
+            browser.close();
+            server.close();
+
+            console.log('Done');
+        }
+    });
+
+
+});
\ No newline at end of file
diff --git a/dists/emscripten/build-download_games.js b/dists/emscripten/build-download_games.js
new file mode 100644
index 00000000000..824d8e97eba
--- /dev/null
+++ b/dists/emscripten/build-download_games.js
@@ -0,0 +1,177 @@
+const request = require('request');
+const fs = require('fs');
+const fsprocess = require('process');
+const { url } = require('inspector');
+
+process.on('uncaughtException', (err, origin) => {
+    console.error(err)
+    console.error(origin)
+    process.exitCode = 2
+})
+const args_games = process.argv.slice(2);
+
+/*
+ Copied from https://github.com/scummvm/scummvm-web/blob/master/include/DataUtils.php
+ */
+const SHEET_URL = 'https://docs.google.com/spreadsheets/d/e/2PACX-1vQamumX0p-DYQa5Umi3RxX-pHM6RZhAj1qvUP0jTmaqutN9FwzyriRSXlO9rq6kR60pGIuPvCDzZL3s/pub?output=tsv';
+const SHEET_IDS = {
+    'platforms': '1061029686',
+    'compatibility': '854570757',
+    'games': '1946612063',
+    'engines': '0',
+    'companies': '226191984',
+    'versions': '1225902887',
+    'game_demos': '713475305',
+    'series': '1095671818',
+    'screenshots': '1985243204',
+    'scummvm_downloads': '1057392663',
+    'game_downloads': '1287892109',
+    'director_demos': '1256563740',
+}
+
+// Small Helper function as having followRedirect:true sometimes lead to ECONNRESET errors 
+function getGoogleSheet(url, callback) {
+    request({
+        url: url,
+        followRedirect: function (response) {
+            return false
+        }
+    }, function (error, response, body) {
+        if (response.headers && response.headers.location) {
+            request({
+                url: response.headers.location,
+                followRedirect: false
+            }, callback);
+        } else {
+            callback(error, response, body)
+        }
+    });
+}
+function parseTSV(text) {
+    const lines = text.split("\r\n")
+    const headers = lines[0].split("\t")
+    var ret = []
+    for (var i = 1; i < lines.length; i++) {
+        ret[i - 1] = {}
+        lines[i].split("\t").forEach((value, col) => ret[i - 1][headers[col]] = value)
+    }
+    return ret
+}
+
+var games = {}
+// Get Freeware Games
+function get_freeware_games() {
+    console.error("download_games.js: Fetching list of freeware games")
+    return new Promise((resolve, reject) => {
+        var url = SHEET_URL + "&gid=" + SHEET_IDS['game_downloads'];
+        getGoogleSheet(url, (error, response, body) => {
+            if (error) {
+                reject(error)
+                return
+            }
+            parseTSV(body).forEach((downloads) => {
+                if (downloads['category'] == "games" && !(downloads['game_id'] in games)) {
+                    games[downloads['game_id']] = "/frs/extras/" + downloads['url']
+                }
+                filename = downloads['url'].substring(downloads['url'].lastIndexOf("/"))
+                games[downloads['game_id'] + filename] = "/frs/extras/" + downloads['url']
+            })
+            resolve()
+        })
+    });
+}
+// Get Demos Games
+function get_demos() {
+    console.error("download_games.js: Fetching list of game demos")
+    return new Promise((resolve, reject) => {
+        var url = SHEET_URL + "&gid=" + SHEET_IDS['game_demos'];
+        getGoogleSheet(url, (error, response, body) => {
+            if (error) {
+                reject(error)
+                return
+            }
+            parseTSV(body).forEach((downloads) => {
+                if (!(downloads['id'] in games)) {
+                    games[downloads['id']] = downloads['url']
+                }
+                filename = downloads['url'].substring(downloads['url'].lastIndexOf("/"))
+                games[downloads['id'] + filename] = downloads['url']
+            })
+            resolve()
+        })
+    });
+}
+// Get Director Demos 
+function get_director_demos() {
+    console.error("download_games.js: Fetching list of director demos")
+    return new Promise((resolve, reject) => {
+        var url = SHEET_URL + "&gid=" + SHEET_IDS['director_demos'];
+        getGoogleSheet(url, (error, response, body) => {
+            if (error || body == undefined) {
+                reject(error)
+                return
+            }
+            parseTSV(body).forEach((downloads) => {
+                if (!(downloads['id'] in games)) {
+                    games[downloads['id']] = downloads['url']
+                }
+                filename = downloads['url'].substring(downloads['url'].lastIndexOf("/"))
+                games[downloads['id'] + filename] = downloads['url']
+            });
+            resolve()
+        });
+    });
+}
+
+// Download a file
+var download_file = function (uri, filename) {
+    // TODO: Rewrite as promise to serialize this (easier to return status updates)
+    return request.get(uri).on('error', function (err) {
+        throw err
+    }).on('response', function (response) {
+        if (response.statusCode == 200) {
+            console.error("download_games.js: Downloading " + uri)
+        } else {
+            console.error(response)
+            throw new Error(response.statusCode)
+        }
+    }).pipe(fs.createWriteStream(filename))
+
+}
+
+const download_all_games = async (gameIds) => {
+    for (var gameId of gameIds) {
+        if (gameId.startsWith("http")) {
+            var  url = gameId
+            var filename = url.substring(url.lastIndexOf("/") + 1)
+
+            console.log(filename)
+            if (!fs.existsSync(filename)) {
+                await download_file(url, filename)
+            }
+        } else if (!(gameId in games)) {
+            console.error("download_games.js: GameID " + gameId + " not known")
+            process.exit(1)
+        } else {
+            var url = "https://downloads.scummvm.org" + games[gameId]
+            if (gameId.includes("/")) {
+                gameId = gameId.substring(0, gameId.lastIndexOf("/"))
+            }
+            var filename = url.substring(url.lastIndexOf("/") + 1)
+            if (!filename.startsWith(gameId)) { filename = gameId + "-" + filename }
+            console.log(filename)
+            if (!fs.existsSync(filename)) {
+                await download_file(url, filename)
+            }
+        }
+    }
+}
+
+// start everything
+get_freeware_games()
+    .then(get_demos)
+    .then(get_director_demos)
+    .then(() => {
+        download_all_games(args_games)
+
+    });
diff --git a/dists/emscripten/build-make_http_index.js b/dists/emscripten/build-make_http_index.js
new file mode 100644
index 00000000000..6dbc9c0aa21
--- /dev/null
+++ b/dists/emscripten/build-make_http_index.js
@@ -0,0 +1,59 @@
+/* 
+ * Based on https://github.com/jvilk/BrowserFS/blob/master/scripts/make_http_index.ts
+ * Copyright (c) 2013, 2014, 2015, 2016, 2017 John Vilk and other BrowserFS contributors.
+ * MIT License  https://github.com/jvilk/BrowserFS/blob/master/LICENSE
+ */
+"use strict";
+const fs = require("fs");
+const path = require("path");
+const symLinks = {};
+const ignoreFiles = ['.git', 'node_modules', 'bower_components', 'build', 'index.json'];
+function rdSync(dpath, tree, name) {
+    const files = fs.readdirSync(dpath);
+    files.forEach((file) => {
+        // ignore non-essential directories / files
+        if (ignoreFiles.indexOf(file) !== -1 || file[0] === '.') {
+            return;
+        }
+        const fpath = `${dpath}/${file}`;
+        try {
+            // Avoid infinite loops.
+            const lstat = fs.lstatSync(fpath);
+            if (lstat.isSymbolicLink()) {
+                if (!symLinks[lstat.dev]) {
+                    symLinks[lstat.dev] = {};
+                }
+                // Ignore if we've seen it before
+                if (symLinks[lstat.dev][lstat.ino]) {
+                    return;
+                }
+                symLinks[lstat.dev][lstat.ino] = true;
+            }
+            const fstat = fs.statSync(fpath);
+            if (fstat.isDirectory()) {
+                const child = tree[file] = {};
+                rdSync(fpath, child, file);
+            }
+            else {
+                tree[file] = fstat.size;
+            }
+        }
+        catch (e) {
+            // Ignore and move on.
+        }
+    });
+    return tree;
+}
+const fsListing = JSON.stringify(rdSync(process.cwd(), {}, '/'));
+if (process.argv.length === 3) {
+    const fname = process.argv[2];
+    let parent = path.dirname(fname);
+    while (!fs.existsSync(parent)) {
+        fs.mkdirSync(parent);
+        parent = path.dirname(parent);
+    }
+    fs.writeFileSync(fname, fsListing, { encoding: 'utf8' });
+}
+else {
+    console.log(fsListing);
+}
\ No newline at end of file
diff --git a/dists/emscripten/build.sh b/dists/emscripten/build.sh
index 7e1f69a1bbc..9c28deee875 100755
--- a/dists/emscripten/build.sh
+++ b/dists/emscripten/build.sh
@@ -1,206 +1,357 @@
 #!/bin/bash
+#
+# .dists/emscripten/build.sh -- Sets up an emscripten build environment and builds ScummVM for webassembly
+#
+# ScummVM is the legal property of its developers, whose names
+# are too numerous to list here. Please refer to the COPYRIGHT
+# file distributed with this source distribution.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
 # print commands
-set -o xtrace
+if [[ "$_verbose" = true ]]; then
+  set -o xtrace
+fi
+
 # exit when any command fails
 set -e
-if [ "$#" -ne 1 ]; then
-  echo "$0: exactly 1 arguments expected: configure, make, data, all"
-  exit 3
-fi
 
-EMSDK_VERSION="2.0.26"
+EMSDK_VERSION="3.1.8"
 ROOT_FOLDER=$(pwd)
 DIST_FOLDER="$ROOT_FOLDER/dists/emscripten"
 LIBS_FOLDER="$DIST_FOLDER/libs"
-if [[ ! -d "$DIST_FOLDER" ]]; then
-  echo "/dists/emscripten/ not found. Please make sure to run this script from the root of the project - ./dists/emscripten/build.sh "
-  exit 1
-fi
-if [[ "$1" =~ ^(clean)$ ]]; then
-  make clean
-  make distclean
-  rm -rf ./dists/emscripten/libs/build
-  rm -rf ./dists/emscripten/libs/*/
-  rm -rf ./dists/emscripten/emsdk*/
-  rm scummvm.debug.wasm
-  find . -name "*.o"
-  find . -name "*.a"
-  find . -name "*.wasm"
-  exit 0
-fi
+TASKS=()
+CONFIGURE_ARGS=()
+_bundle_games=()
+_verbose=false
+EMSCRIPTEN_VERSION=$EMSDK_VERSION
 
-# Activate Emscripten
-if [[ ! -d "$DIST_FOLDER/emsdk-$EMSDK_VERSION" ]]; then
-  echo "$DIST_FOLDER/emsdk-$EMSDK_VERSION not found. Installing Emscripten"
-  cd "$DIST_FOLDER"
-  wget -nc --content-disposition "https://github.com/emscripten-core/emsdk/archive/refs/tags/${EMSDK_VERSION}.tar.gz"
-  tar xzvf "emsdk-${EMSDK_VERSION}.tar.gz"
-  cd "emsdk-${EMSDK_VERSION}"
-  ./emsdk install ${EMSDK_VERSION}
-  ./emsdk activate ${EMSDK_VERSION}
+usage="\
+Usage: ./dists/emscripten/build.sh [TASKS] [OPTIONS]
+
+Output the configuration name of the system \`$me' is run on.
+
+Tasks: 
+  (space separated) List of tasks to run. See ./dists/emscripten/README.md for details.    
+
+Options:
+  -h, --help         print this help, then exit
+  --bundle-games=    comma-separated list of demos and freeware games to bundle. 
+  -v, --verbose          print all commands run by the script
+  --*                all other options are passed on to the configure script
+"
+
+# parse inputs
+for i in "$@"; do
+  case $i in
+  --bundle-games=*)
+    str="${i#*=}"
+    _bundle_games="${str//,/ }"
+    shift # past argument=value
+    ;;
+  -h | --help)
+    echo "$usage"
+    exit
+    ;;
+  -v | --verbose)
+    _verbose=true
+    ;;
+  -* | --*)
+    CONFIGURE_ARGS+=" $i"
+    ;;
+  *)
+    TASKS+="|$i" # save positional arg
+    shift        # past argument
+    ;;
+  esac
+done
+
+TASKS="${TASKS:1}"
+if [[ -z "$TASKS" ]]; then
+  echo "$usage"
+  exit
 fi
-source "$DIST_FOLDER/emsdk-$EMSDK_VERSION/emsdk_env.sh"
 
-# Download + Install Libraries
-mkdir -p "$LIBS_FOLDER"
-if [[ ! -d "$LIBS_FOLDER/build" ]]; then
-  echo "$LIBS_FOLDER/build/ not found. Building plugins..."
-  echo "build libtheora-1.1.1"
-  cd "$LIBS_FOLDER"
-  pwd
-  wget -nc "https://downloads.xiph.org/releases/theora/libtheora-1.1.1.tar.xz"
-  tar -xf libtheora-1.1.1.tar.xz
-  cd "./libtheora-1.1.1/"
-  CFLAGS="-fPIC -s USE_OGG=1 -s USE_VORBIS=1 " emconfigure ./configure --host=wasm32-unknown-none --prefix="$LIBS_FOLDER/build/" --disable-asm
-  emmake make -j 3
-  emmake make install
-
-  echo "building faad2-2.8.8"
-  cd "$LIBS_FOLDER"
-  wget -nc "https://sourceforge.net/projects/faac/files/faad2-src/faad2-2.8.0/faad2-2.8.8.tar.gz"
-  tar -xf faad2-2.8.8.tar.gz
-  cd "./faad2-2.8.8/"
-  CFLAGS="-fPIC" emconfigure ./configure --host=wasm32-unknown-none --prefix="$LIBS_FOLDER/build/"
-  emmake make
-  emmake make install
-
-  echo "building libmad-0.15.1b"
-  cd "$LIBS_FOLDER"
-  # libmad needs patching: https://stackoverflow.com/questions/14015747/gccs-fforce-mem-option
-  wget -nc "http://www.linuxfromscratch.org/patches/blfs/svn/libmad-0.15.1b-fixes-1.patch"
-  wget -nc "https://downloads.sourceforge.net/mad/libmad-0.15.1b.tar.gz"
-  tar -xf libmad-0.15.1b.tar.gz
-  cd "$LIBS_FOLDER/libmad-0.15.1b/"
-  patch -Np1 -i ../libmad-0.15.1b-fixes-1.patch
-  emconfigure ./configure --host=wasm32-unknown-none --prefix="$LIBS_FOLDER/build/" --with-pic --enable-fpm=no
-  emmake make
-  emmake make install
+#################################
+# Setup Toolchain
+#################################
 
-  echo "building libmpeg2-0.5.1"
-  cd "$LIBS_FOLDER"
-  wget -nc "http://libmpeg2.sourceforge.net/files/libmpeg2-0.5.1.tar.gz"
-  tar -xf libmpeg2-0.5.1.tar.gz
-  cd "$LIBS_FOLDER/libmpeg2-0.5.1/"
+if [[ "setup" =~ $(echo ^\(${TASKS}\)$) || "build" =~ $(echo ^\(${TASKS}\)$) ]]; then
 
-  CFLAGS="-fPIC" emconfigure ./configure --host=wasm32-unknown-none --prefix="$LIBS_FOLDER/build/" --disable-sdl
-  emmake make
-  emmake make install
-
-  echo "building a52dec-0.7.4"
-  cd "$LIBS_FOLDER"
-  wget -nc "https://liba52.sourceforge.io/files/a52dec-0.7.4.tar.gz"
-  tar -xf a52dec-0.7.4.tar.gz
-  cd "$LIBS_FOLDER/a52dec-0.7.4/"
-  CFLAGS="-fPIC" emconfigure ./configure --host=wasm32-unknown-none --prefix="$LIBS_FOLDER/build/"
-  emmake make -j 3
-  emmake make install
+  # Activate Emscripten
+  if [[ ! -d "$DIST_FOLDER/emsdk-$EMSDK_VERSION" ]]; then
+    echo "$DIST_FOLDER/emsdk-$EMSDK_VERSION not found. Installing Emscripten"
+    cd "$DIST_FOLDER"
+    if [[ "$EMSDK_VERSION" = "tot" ]]; then
+      git clone "https://github.com/emscripten-core/emsdk/" emsdk-tot
+    else
+      wget -nc --content-disposition "https://github.com/emscripten-core/emsdk/archive/refs/tags/${EMSDK_VERSION}.tar.gz"
+      tar -xf "emsdk-${EMSDK_VERSION}.tar.gz"
+    fi
+    cd "$DIST_FOLDER/emsdk-${EMSDK_VERSION}"
+    ./emsdk install ${EMSCRIPTEN_VERSION}
+    # We currently require a few patches for unreleased changes in SDL2 and Emscripten
+    if [[ "$EMSCRIPTEN_VERSION" == "3.1.8" ]]; then
+      cd upstream/emscripten
+      # until https://github.com/emscripten-core/emscripten/pull/15893 gets merged and released, we need to manually patch it
+      patch -p1 --verbose <"$DIST_FOLDER/emscripten-15893.patch"
+      # some additional fixes on top of 15893:
+      patch -p1 --verbose <"$DIST_FOLDER/emscripten-15893-fix.patch"
+
+      # until https://github.com/emscripten-core/emscripten/pull/16559 gets merged and released, we need to manually patch it
+      patch -p1 --verbose <"$DIST_FOLDER/emscripten-16559.patch"
+      # until https://github.com/emscripten-core/emscripten/pull/16687 gets merged and released, we need to manually patch it
+      patch -p1 --verbose <"$DIST_FOLDER/emscripten-16687.patch"
+    fi
+
+    cd "$DIST_FOLDER/emsdk-${EMSDK_VERSION}"
+    ./emsdk activate ${EMSCRIPTEN_VERSION}
+
+    # install some required npm packages
+    source "$DIST_FOLDER/emsdk-$EMSDK_VERSION/emsdk_env.sh"
+    EMSDK_NPM=$(dirname $EMSDK_NODE)/npm
+    export NODE_PATH=$(dirname $EMSDK_NODE)/../lib/node_modules/
+    "$EMSDK_NPM" -g install "puppeteer at 13.5.1"
+    "$EMSDK_NPM" -g install "request at 2.88.2"
+    "$EMSDK_NPM" -g install "node-static at 0.7.11"
+  fi
 fi
+source "$DIST_FOLDER/emsdk-$EMSDK_VERSION/emsdk_env.sh"
+
+# export node_path - so we can use all node_modules bundled with emscripten (e.g. requests)
+EMSDK_NPM=$(dirname $EMSDK_NODE)/npm
+export NODE_PATH=$(dirname $EMSDK_NODE)/../lib/node_modules/
+LIBS_FLAGS=""
 
 cd "$ROOT_FOLDER"
+#################################
+# Clean
+#################################
+if [[ "clean" =~ $(echo ^\(${TASKS}\)$) ]]; then
+  emmake make clean || true
+  emmake make distclean || true
+  rm -rf ./dists/emscripten/libs/build || true
+  rm -rf ./dists/emscripten/libs/*/ || true
+  rm -rf ./build-emscripten/ || true
+  rm scummvm.debug.wasm || true
+  find . -name "*.o" || true
+  find . -name "*.a" || true
+  find . -name "*.wasm" || true
+  exit 0
+fi
 
-## Emscripten configuration (should probably go into the configure file)
-## IMPORTANT: ASYNCIFY WITH -O0 doesnt work (presumably because the stack gets too big)
-export LDFLAGS="-O2 -s ASSERTIONS=1 -s GL_ASSERTIONS=1 -s LLD_REPORT_UNDEFINED -s INITIAL_MEMORY=33554432"
+#################################
+# Download + Install Libraries
+#################################
+if [[ "libs" =~ $(echo ^\(${TASKS}\)$) || "build" =~ $(echo ^\(${TASKS}\)$) ]]; then
 
-#debugging
-export LDFLAGS="${LDFLAGS} -g -gseparate-dwarf=scummvm.debug.wasm -s SEPARATE_DWARF_URL=\"http://localhost:8080/scummvm.debug.wasm\""
+  if [[ ! -d "$LIBS_FOLDER/build" ]]; then
+    mkdir -p "$LIBS_FOLDER/build"
+  fi
 
-# linker flags (bundle JS and default assets)
-export LDFLAGS_LINKER=" --pre-js ./dists/emscripten/pre.js --post-js ./dists/emscripten/post.js --shell-file ./dists/emscripten/custom_shell.html "
+  # Emscripten has an official port for vorbis, but it doesn't properly link vorbisfile https://github.com/emscripten-core/emscripten/pull/14005
+  if [[ ! -f "$LIBS_FOLDER/build/lib/libvorbis.a" ]]; then
+    echo "building libvorbis-1.3.7"
+    cd "$LIBS_FOLDER"
+    wget -nc "https://downloads.xiph.org/releases/vorbis/libvorbis-1.3.7.tar.gz"
+    tar -xf libvorbis-1.3.7.tar.gz
+    cd "$LIBS_FOLDER/libvorbis-1.3.7"
+    CFLAGS="-fPIC -s USE_OGG=1" emconfigure ./configure --host=wasm32-unknown-none --build=wasm32-unknown-none --prefix="$LIBS_FOLDER/build/"
+    emmake make -j 3
+    emmake make install
+  fi
+  LIBS_FLAGS="${LIBS_FLAGS} --with-vorbis-prefix=$LIBS_FOLDER/build/"
 
-if [[ "$1" =~ ^(configure|all)$ ]]; then
+  if [[ ! -f "$LIBS_FOLDER/build/lib/libtheora.a" ]]; then
+    echo "build libtheora-1.1.1"
+    cd "$LIBS_FOLDER"
+    wget -nc "https://downloads.xiph.org/releases/theora/libtheora-1.1.1.tar.xz"
+    tar -xf libtheora-1.1.1.tar.xz
+    cd "./libtheora-1.1.1/"
+    CFLAGS="-fPIC -s USE_OGG=1" emconfigure ./configure --host=wasm32-unknown-none --build=wasm32-unknown-none --prefix="$LIBS_FOLDER/build/" --disable-asm
+    emmake make -j 3
+    emmake make install
+  fi
+  LIBS_FLAGS="${LIBS_FLAGS} --with-theoradec-prefix=$LIBS_FOLDER/build/"
 
-  echo "clean, & configure"
-  make clean || true
-  emconfigure ./configure --enable-debug --enable-verbose-build --host=wasm32-unknown-emscripten \
-    --disable-all-engines \
-    --enable-engine=testbed,scumm,scumm_7_8,grim,monkey4,mohawk,myst,riven,sci32,agos2,sword2,drascula,sky,lure,queen,testbed \
-    --with-theoradec-prefix="$LIBS_FOLDER/build/" \
-    --with-faad-prefix="$LIBS_FOLDER/build/" \
-    --with-mad-prefix="$LIBS_FOLDER/build/" \
-    --with-mpeg2-prefix="$LIBS_FOLDER/build/" \
-    --with-a52-prefix="$LIBS_FOLDER/build/"
+  if [[ ! -f "$LIBS_FOLDER/build/lib/libfaad.a" ]]; then
+    echo "building faad2-2.8.8"
+    cd "$LIBS_FOLDER"
+    wget -nc "https://sourceforge.net/projects/faac/files/faad2-src/faad2-2.8.0/faad2-2.8.8.tar.gz"
+    tar -xf faad2-2.8.8.tar.gz
+    cd "./faad2-2.8.8/"
+    CFLAGS="-fPIC" emconfigure ./configure --host=wasm32-unknown-none --build=wasm32-unknown-none --prefix="$LIBS_FOLDER/build/"
+    emmake make
+    emmake make install
+  fi
+  LIBS_FLAGS="${LIBS_FLAGS} --with-faad-prefix=$LIBS_FOLDER/build/"
 
-  # TODO: enable dynamic linking so we can enable more plugins
-  # https://forums.scummvm.org/viewtopic.php?t=14918
-  # https://github.com/emscripten-core/emscripten/wiki/Linking
-  # https://freecontent.manning.com/dynamic-linking-a-crash-course/
-  # https://iandouglasscott.com/2019/07/18/experimenting-with-webassembly-dynamic-linking-with-clang/
+  if [[ ! -f "$LIBS_FOLDER/build/lib/libmad.a" ]]; then
+    echo "building libmad-0.15.1b"
+    cd "$LIBS_FOLDER"
+    # libmad needs patching: https://stackoverflow.com/questions/14015747/gccs-fforce-mem-option
+    wget -nc "http://www.linuxfromscratch.org/patches/blfs/svn/libmad-0.15.1b-fixes-1.patch"
+    wget -nc "https://downloads.sourceforge.net/mad/libmad-0.15.1b.tar.gz"
+    rm -rf "$LIBS_FOLDER/libmad-0.15.1b/"
+    tar -xf libmad-0.15.1b.tar.gz
+    cd "$LIBS_FOLDER/libmad-0.15.1b/"
+    patch -Np1 -i ../libmad-0.15.1b-fixes-1.patch &&
+      emconfigure ./configure --host=wasm32-unknown-none --build=wasm32-unknown-none --prefix="$LIBS_FOLDER/build/" --with-pic --enable-fpm=no
+    emmake make
+    emmake make install
+  fi
+  LIBS_FLAGS="${LIBS_FLAGS} --with-mad-prefix=$LIBS_FOLDER/build/"
 
-  # HACK: the preload flags break emcc during configure as emcc enables NODERAWFS when run as part of configure
-  # which doesn't support preloading assets, so we have to manually add those after configure to the config.mk file
-  echo "LDFLAGS += ${LDFLAGS_LINKER}" >>config.mk
+  if [[ ! -f "$LIBS_FOLDER/build/lib/libmpeg2.a" ]]; then
+    echo "building libmpeg2-0.5.1"
+    cd "$LIBS_FOLDER"
+    wget -nc "http://libmpeg2.sourceforge.net/files/libmpeg2-0.5.1.tar.gz"
+    tar -xf libmpeg2-0.5.1.tar.gz
+    cd "$LIBS_FOLDER/libmpeg2-0.5.1/"
+    CFLAGS="-fPIC" emconfigure ./configure --host=wasm32-unknown-none --prefix="$LIBS_FOLDER/build/" --disable-sdl
+    emmake make
+    emmake make install
+  fi
+  LIBS_FLAGS="${LIBS_FLAGS} --with-mpeg2-prefix=$LIBS_FOLDER/build/"
 
-  # configure currently doesn't clean up all files it created
+  if [[ ! -f "$LIBS_FOLDER/build/lib/liba52.a" ]]; then
+    echo "building a52dec-0.7.4"
+    cd "$LIBS_FOLDER"
+    wget -nc "https://liba52.sourceforge.io/files/a52dec-0.7.4.tar.gz"
+    tar -xf a52dec-0.7.4.tar.gz
+    cd "$LIBS_FOLDER/a52dec-0.7.4/"
+    CFLAGS="-fPIC" emconfigure ./configure --host=wasm32-unknown-none --build=wasm32-unknown-none --prefix="$LIBS_FOLDER/build/"
+    emmake make -j 3
+    emmake make install
+  fi
+  LIBS_FLAGS="${LIBS_FLAGS} --with-a52-prefix=$LIBS_FOLDER/build/"
+fi
+
+#################################
+# Configure
+#################################
+if [[ "configure" =~ $(echo ^\(${TASKS}\)$) || "build" =~ $(echo ^\(${TASKS}\)$) ]]; then
+  cd "${ROOT_FOLDER}"
+  echo "Running configure"
+  # TODO: Figure out how configure could guess the host
+  emconfigure ./configure --host=wasm32-unknown-emscripten --build=wasm32-unknown-emscripten ${CONFIGURE_ARGS} ${LIBS_FLAGS}
+
+  # TODO: configure currently doesn't clean up all files it creates
   rm scummvm-conf.*
+fi
 
+#################################
+# Make / Compile
+#################################
+if [[ "make" =~ $(echo ^\(${TASKS}\)$) || "build" =~ $(echo ^\(${TASKS}\)$) ]]; then
+  cd "${ROOT_FOLDER}"
+  echo "Running make"
+  emmake make
+  emmake make dist-generic
 fi
 
-if [[ "$1" =~ ^(data|all)$ ]]; then
+# The following steps copy stuff to build-emscripten:
+mkdir -p "${ROOT_FOLDER}/build-emscripten/"
+
+#################################
+# Create Games & Testbed Data
+#################################
+if [[ "games" =~ $(echo ^\(${TASKS}\)$) || "build" =~ $(echo ^\(${TASKS}\)$) ]]; then
   cd "${ROOT_FOLDER}"
-  rm -rf ./build-emscripten/games/
-  mkdir -p ./build-emscripten/games/
-  cd dists/engine-data
-  ./create-testbed-data.sh
-  mv testbed "${ROOT_FOLDER}/build-emscripten/games/testbed"
-
-  games=true
-  if [ "$games" = true ]; then
-    mkdir -p ./dists/emscripten/games/
-    cd "${ROOT_FOLDER}/dists/emscripten/games/"
-    wget -nc https://downloads.scummvm.org/frs/demos/scumm/ft-dos-demo-en.zip
-    unzip -n ft-dos-demo-en -d "${ROOT_FOLDER}/build-emscripten/games/ft-dos-demo-en/"
-    wget -nc https://downloads.scummvm.org/frs/demos/mohawk/myst-win-demo-en.zip
-    unzip -n myst-win-demo-en.zip -d "${ROOT_FOLDER}/build-emscripten/games/myst-win-demo-en/"
-    wget -nc https://downloads.scummvm.org/frs/demos/mohawk/riven-win-demo-en.zip
-    unzip -n riven-win-demo-en.zip -d "${ROOT_FOLDER}/build-emscripten/games/riven-win-demo-en/" -x DXSETUP/* -x QTWSETUP/*
-    wget -nc https://downloads.scummvm.org/frs/demos/sword2/sword2-win-demo-en.zip
-    unzip -n sword2-win-demo-en.zip -d "${ROOT_FOLDER}/build-emscripten/games/sword2-win-demo-en/"
-    wget -nc https://downloads.scummvm.org/frs/demos/scumm/comi-win-large-demo-en.zip
-    unzip -n comi-win-large-demo-en.zip -d "${ROOT_FOLDER}/build-emscripten/games/comi-win-large-demo-en/"
-    wget -nc https://downloads.scummvm.org/frs/demos/grim/emi-win-demo-en.zip
-    unzip -n emi-win-demo-en.zip -d "${ROOT_FOLDER}/build-emscripten/games/emi-win-demo-en/"
-    wget -nc https://downloads.scummvm.org/frs/demos/grim/grim-win-demo2-en.zip
-    unzip -n grim-win-demo2-en.zip -d "${ROOT_FOLDER}/build-emscripten/games/grim-win-demo2-en/"
-    wget -nc https://downloads.scummvm.org/frs/demos/agos/feeble-dos-ni-demo-en.zip
-    unzip -n feeble-dos-ni-demo-en.zip -d "${ROOT_FOLDER}/build-emscripten/games/feeble-dos-ni-demo-en/"
-    wget -nc https://downloads.scummvm.org/frs/demos/sci/lsl7-dos-demo-en.zip
-    unzip -n lsl7-dos-demo-en.zip -d "${ROOT_FOLDER}/build-emscripten/games/lsl7-dos-demo-en/"
-    wget -nc https://downloads.scummvm.org/frs/demos/sci/phantasmagoria-dos-win-demo-en.zip
-    unzip -n phantasmagoria-dos-win-demo-en -d "${ROOT_FOLDER}/build-emscripten/games/phantasmagoria-dos-win-demo-en/"
-    wget -nc https://downloads.scummvm.org/frs/extras/Beneath%20a%20Steel%20Sky/BASS-Floppy-1.3.zip
-    unzip -n BASS-Floppy-1.3.zip -d "${ROOT_FOLDER}/build-emscripten/games/bass-floppy/"
-    wget -nc https://downloads.scummvm.org/frs/extras/Drascula_%20The%20Vampire%20Strikes%20Back/drascula-1.0.zip
-    unzip -n drascula-1.0.zip -d "${ROOT_FOLDER}/build-emscripten/games/drascula/"
-    wget -nc https://downloads.scummvm.org/frs/extras/Drascula_%20The%20Vampire%20Strikes%20Back/drascula-audio-mp3-2.0.zip
-    unzip -n drascula-audio-mp3-2.0.zip -d "${ROOT_FOLDER}/build-emscripten/games/drascula/"
-    wget -nc https://downloads.scummvm.org/frs/extras/Flight%20of%20the%20Amazon%20Queen/FOTAQ_Floppy.zip
-    unzip -n FOTAQ_Floppy.zip -d "${ROOT_FOLDER}/build-emscripten/games/fotaq-floppy/"
-    wget -nc https://downloads.scummvm.org/frs/extras/Lure%20of%20the%20Temptress/lure-1.1.zip
-    unzip -n lure-1.1.zip -d "${ROOT_FOLDER}/build-emscripten/games/lure/"
+  echo "Creating Games + Testbed Data"
+  mkdir -p "${ROOT_FOLDER}/build-emscripten/games/"
+
+  if [[ "testbed" =~ $(echo ^\(${_bundle_games// /|}\)$) ]]; then
+    _bundle_games="${_bundle_games//testbed/}"
+    rm -rf "${ROOT_FOLDER}/build-emscripten/games/testbed"
+    cd "${ROOT_FOLDER}/dists/engine-data"
+    ./create-testbed-data.sh
+    mv testbed "${ROOT_FOLDER}/build-emscripten/games/testbed"
   fi
 
+  if [ -n "$_bundle_games" ]; then
+    mkdir -p "${DIST_FOLDER}/games/"
+    cd "${DIST_FOLDER}/games/"
+    files=$("$EMSDK_NODE" --unhandled-rejections=strict --trace-warnings "$DIST_FOLDER/build-download_games.js" ${_bundle_games})
+    for dir in "${ROOT_FOLDER}/build-emscripten/games/"*; do # cleanup games folder
+      if [ $(basename $dir) != "testbed" ]; then
+        rm -rf "$dir"
+      fi
+    done
+    for f in $files; do # unpack into games folder
+      echo "Unzipping $f ..."
+      unzip -q -n "$f" -d "${ROOT_FOLDER}/build-emscripten/games/${f%.zip}"
+      # some zip files have weird permissions, this fixes that:
+      find "${ROOT_FOLDER}/build-emscripten/games/${f%.zip}" -type d -exec chmod 0755 {} \;
+      find "${ROOT_FOLDER}/build-emscripten/games/${f%.zip}" -type f -exec chmod 0644 {} \;
+    done
+  fi
   cd "${ROOT_FOLDER}/build-emscripten/games/"
-  NODE_DIR=$(dirname "$EMSDK_NODE")
-  "$NODE_DIR/npx" -p browserfs make_xhrfs_index >index.json
+  "$EMSDK_NODE" "$DIST_FOLDER/build-make_http_index.js" >index.json
 fi
 
-if [[ "$1" =~ ^(make|all)$ ]]; then
+#################################
+# Bundle everything into a neat package
+#################################
+if [[ "dist" =~ $(echo ^\(${TASKS}\)$) || "build" =~ $(echo ^\(${TASKS}\)$) ]]; then
   cd "${ROOT_FOLDER}"
-  emmake make
-  emmake make dist-generic
-  # preload data
-  "$EMSDK_PYTHON" "$EMSDK/upstream/emscripten/tools/file_packager.py" files.data --preload ./dist-generic/scummvm/data@/scummvm --use-preload-cache --js-output=files.js
-  rm -rf dist-generic/
+  mv "${ROOT_FOLDER}"/scummvm.* "${ROOT_FOLDER}"/build-emscripten/ || true
+
+  # prepare data
+  if [[ -d "${ROOT_FOLDER}/dist-generic/scummvm/data" ]]; then
+    echo "Bundle ScummVM + Data"
+    rm -rf "${ROOT_FOLDER}/build-emscripten/data"
+    mv "${ROOT_FOLDER}/dist-generic/scummvm/data" "${ROOT_FOLDER}/build-emscripten/"
+    cd "${ROOT_FOLDER}/build-emscripten/data"
+    "$EMSDK_NODE" "$DIST_FOLDER/build-make_http_index.js" >index.json
+    rm -rf "${ROOT_FOLDER}/dist-generic/"
+  fi
+
+  # bundle plugins
+  echo "Bundle Plugins"
+  mkdir -p "${ROOT_FOLDER}/build-emscripten/plugins"
+  mv "${ROOT_FOLDER}/plugins/"* "${ROOT_FOLDER}/build-emscripten/plugins/" || true
+  cd "${ROOT_FOLDER}/build-emscripten/plugins"
+  "$EMSDK_NODE" "$DIST_FOLDER/build-make_http_index.js" >index.json
+
+  # add logos and other assets
+  cd "${ROOT_FOLDER}"
+  cp "$DIST_FOLDER/assets/"* "${ROOT_FOLDER}/build-emscripten/"
+  cp "$ROOT_FOLDER/gui/themes/common-svg/logo.svg" "${ROOT_FOLDER}/build-emscripten/"
+  cp "$ROOT_FOLDER/icons/scummvm.ico" "${ROOT_FOLDER}/build-emscripten/favicon.ico"
 fi
 
-if [[ "$1" =~ ^(dist|all)$ ]]; then
+#################################
+# Automatically detect games and create scummvm.ini file
+#################################
+if [[ "add-games" =~ $(echo ^\(${TASKS}\)$) || "build" =~ $(echo ^\(${TASKS}\)$) ]]; then
   cd "${ROOT_FOLDER}"
-  mkdir -p build-emscripten
-  mv scummvm.* build-emscripten/
-  mv files.* build-emscripten/
-  cp dists/emscripten/scummvm-512.png build-emscripten/
-  cp dists/emscripten/scummvm-192.png build-emscripten/
-  cp dists/emscripten/manifest.json build-emscripten/
+  cp "$DIST_FOLDER/assets/scummvm.ini" "${ROOT_FOLDER}/build-emscripten/"
+  cd "${ROOT_FOLDER}/build-emscripten/"
+  "$EMSDK_NODE" "$DIST_FOLDER/build-add_games.js"
+fi
+
+#################################
+# Run Development Server
+#################################
+if [[ "run" =~ $(echo ^\(${TASKS}\)$) ]]; then
+  echo "Run ScummVM"
+  cd "${ROOT_FOLDER}/build-emscripten/"
+  # emrun doesn't support range requests. Once it will, we don't need node-static anymore
+  # emrun --browser=chrome scummvm.html
 
+  EMSDK_NPX=$(dirname $EMSDK_NODE)/npx
+  $EMSDK_NPX -p node-static static .
 fi
diff --git a/dists/emscripten/post.js b/dists/emscripten/custom_shell-post.js
similarity index 100%
rename from dists/emscripten/post.js
rename to dists/emscripten/custom_shell-post.js
diff --git a/dists/emscripten/custom_shell-pre.js b/dists/emscripten/custom_shell-pre.js
new file mode 100644
index 00000000000..af6ed9490ac
--- /dev/null
+++ b/dists/emscripten/custom_shell-pre.js
@@ -0,0 +1,17 @@
+/*global Module*/
+Module["arguments"] = [];
+Module["arguments"].push("--config=/local/scummvm.ini");
+
+// https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API only works in secure contexts and supported browsers. 
+// This disables joystick support to avoid a crash when initializing the sdl subsystem without the gamepad API being available.
+if (!navigator.getGamepads && !navigator.webkitGetGamepads) {
+    Module["arguments"].push("--joystick=-1")
+}
+
+// Add all parameters passed via the fragment identifier
+if (window.location.hash.length > 0) {
+    params = decodeURI(window.location.hash.substring(1)).split(" ")
+    params.forEach((param) => {
+        Module["arguments"].push(param);
+    })
+}
diff --git a/dists/emscripten/custom_shell.html b/dists/emscripten/custom_shell.html
index c577ed33e53..a1be6e017c9 100644
--- a/dists/emscripten/custom_shell.html
+++ b/dists/emscripten/custom_shell.html
@@ -4,6 +4,7 @@
 <head>
   <meta charset="utf-8">
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+  <meta content="width=device-width,initial-scale=1,viewport-fit=cover" name=viewport>
   <link rel="manifest" href="manifest.json">
   <link rel="apple-touch-icon" href="scummvm-192.png">
   <title>ScummVM</title>
@@ -11,7 +12,8 @@
   <style>
     body {
       margin: 0;
-      padding: none
+      padding: none;
+      background-color: #000;
     }
 
     .emscripten {
@@ -32,13 +34,16 @@
 
     div.emscripten_border {
       border: 1px solid black;
+      padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
     }
 
     /* the canvas *must not* have any border or padding, or mouse coords will be wrong */
     canvas.emscripten {
       border: 0px none;
-      background-color: #c60;
-
+      background: url("logo.svg");
+      background-position: center;
+      background-repeat: no-repeat;
+      background-color: #cc6600;
       position: absolute;
       top: 0px;
       left: 0px;
@@ -49,6 +54,17 @@
       display: block;
     }
 
+    @media (orientation: landscape) {
+      canvas.emscripten {
+        background-size: auto 33%;
+      }
+    }
+
+    @media (orientation: portrait) {
+      canvas.emscripten {
+        background-size: 80% auto;
+      }
+    }
 
     #progress {
       top: 0px;
@@ -77,15 +93,21 @@
 
     #status {
       position: absolute;
-      top: 10px;
-      width: 100%;
-      text-align: center;
+      bottom: 5em;
+      right: 0px;
+      padding: 5px;
+      text-align: right;
+      border-top-left-radius: 1em;
+      border-bottom-left-radius: 1em;
+      padding-left: 1em;
+      padding-right: 1em;
       z-index: 3;
+      border: 3px solid black;
+      border-right: none;
       background: #f6e08a;
       font: bold large/1.4 "Trebuchet MS", Verdana, Tahoma, Sans-Serif;
     }
 
-
     #status.error {
       background: red
     }
@@ -96,7 +118,7 @@
   <div class=emscripten>
     <progress hidden id=progress max=100 value=0></progress>
   </div>
-  <div class="emscripten" id="status">Downloading...</div>
+  <div class="emscripten" id="status">Downloading ScummVM...</div>
 
   <div class=emscripten_border>
     <canvas class=emscripten id=canvas oncontextmenu=event.preventDefault() tabindex=-1></canvas>
@@ -108,7 +130,12 @@
   <script src="https://cdnjs.cloudflare.com/ajax/libs/BrowserFS/2.0.0/browserfs.min.js"
     integrity="sha512-mz0EI+Ay1uIJP7rZEX8C/JlTAcHRIQ8Sny4vxmmj8MSzDJgG9NxxY2pUmOGv1lO7imFIFMyjjCzEXEywNgaUdQ=="
     crossorigin="anonymous"></script>
+  <script type="module">
+    import { ScummvmFS } from './scummvm_fs.js'
+    window.ScummvmFS = ScummvmFS
+  </script>
   <script type='text/javascript'>
+
     var statusElement = document.getElementById('status');
     var progressElement = document.getElementById('progress');
 
@@ -116,47 +143,144 @@
       document.getElementById("progress").style.zIndex = 0;
       return "All downloads complete."
     }
-    function setupBrowserFS() {
-      addRunDependency('browserfs-setup');
-      // default values, created by running scummvm with --add --recursive --path=/data/games
-      defaultLocalStorage = {
-        "/": btoa("\u0000\u0010\u0000\u0000ÿA\u0000p\u0005àJ\u009bwB\u0000p\u0005àJ\u009bwB\u0000p\u0005àJ\u009bwBb3da6754-64c0-40f0-92ad-83b6ca6ffec9"),
-        "70879b79-8d58-400c-8143-332242320b34": btoa("©\u000f\u0000\u0000¶\u0081\u0000\u0010ï\u0083B\u009cwB\u0000\u0090<Ú\u0081\u000ewB\u0000\u0010ï\u0083B\u009cwB1b4a97d1-4ce0-417f-985c-e0f22ca21aef"),
-        "b3da6754-64c0-40f0-92ad-83b6ca6ffec9": btoa("{\"scummvm.ini\":\"70879b79-8d58-400c-8143-332242320b34\"}"),
-        "1b4a97d1-4ce0-417f-985c-e0f22ca21aef": "W3NjdW1tdm1dCmZpbHRlcmluZz1mYWxzZQptaWRpX2dhaW49MTAwCm11dGU9ZmFsc2UKZ3VpX3VzZV9nYW1lX2xhbmd1YWdlPWZhbHNlCnNwZWVjaF92b2x1bWU9MTkyCm5hdGl2ZV9tdDMyPWZhbHNlCm9wbF9kcml2ZXI9YXV0bwptdDMyX2RldmljZT1udWxsCmxhc3Rfd2luZG93X3dpZHRoPTM0MjYKdGFsa3NwZWVkPTYwCmNvbmZpcm1fZXhpdD1mYWxzZQpnZnhfbW9kZT1vcGVuZ2wKZ3VpX2Jhc2U9MApndWlfcmV0dXJuX3RvX2xhdW5jaGVyX2F0X2V4aXQ9ZmFsc2UKc3VidGl0bGVzPWZhbHNlCm11bHRpX21pZGk9ZmFsc2UKZnVsbHNjcmVlbj1mYWxzZQpndWlfYnJvd3Nlcl9zaG93X2hpZGRlbj1mYWxzZQpsYXN0X3dpbmRvd19oZWlnaHQ9NTI0CmJyb3dzZXJfbGFzdHBhdGg9L2RhdGEvZ2FtZXMvdGVzdGJlZApnbV9kZXZpY2U9bnVsbApzZnhfdm9sdW1lPTE5MgptdXNpY192b2x1bWU9MTkyCmF1dG9zYXZlX3BlcmlvZD0zMDAKbGFzdHNlbGVjdGVkZ2FtZT1sc2w3LWRlbW8KbXVzaWNfZHJpdmVyPWF1dG8Kc3RyZXRjaF9tb2RlPWZpdApyZW5kZXJlcj1vcGVuZ2xfc2hhZGVycwp2c3luYz1mYWxzZQphc3BlY3RfcmF0aW89dHJ1ZQp2ZXJzaW9uaW5mbz0yLjMuMGdpdDE4NTYyLWc1MGU2OTk1YzY2LWRpcnR5CnNwZWVjaF9tdXRlPWZhbHNlCmVuYWJsZV9ncz1mYWxzZQoKW3Rlc3RiZWRdCmRlc2NyaXB0aW9uPVRlc3RiZWQ6IFRoZSBCYWNrZW5kIFRlc3RpbmcgRnJhbWV3b3JrIChET1MvRW5nbGlzaCkKcGF0aD0vZGF0YS9nYW1lcy90ZXN0YmVkCmVuZ2luZWlkPXRlc3RiZWQKZ2FtZWlkPXRlc3RiZWQKbGFuZ3VhZ2U9ZW4KcGxhdGZvcm09cGMKZ3Vpb3B0aW9ucz1sYXVuY2hOb0xvYWQgbGFuZ19FbmdsaXNoCgpbc2t5XQpkZXNjcmlwdGlvbj1CZW5lYXRoIGEgU3RlZWwgU2t5ICh2MC4wMzQ4IGZsb3BweSkKZXh0cmE9djAuMDM0OCBmbG9wcHkKcGF0aD0vZGF0YS9nYW1lcy9iYXNzLWZsb3BweQplbmdpbmVpZD1za3kKZ2FtZWlkPXNreQpndWlvcHRpb25zPXNuZE5vU3BlZWNoCgpbY29taS1kZW1vXQpkZXNjcmlwdGlvbj1UaGUgQ3Vyc2Ugb2YgTW9ua2V5IElzbGFuZCAoRGVtby9XaW5kb3dzKQpleHRyYT1EZW1vCnBhdGg9L2RhdGEvZ2FtZXMvY29taS13aW4tbGFyZ2UtZGVtby1lbgplbmdpbmVpZD1zY3VtbQpnYW1laWQ9Y29taQpwbGF0Zm9ybT13aW5kb3dzCmd1aW9wdGlvbnM9c25kTm9NSURJIG5vQXNwZWN0CgpbZHJhc2N1bGFdCmRlc2NyaXB0aW9uPURyYXNjdWxhOiBUaGUgVmFtcGlyZSBTdHJpa2VzIEJhY2sgKERPUy9FbmdsaXNoKQpwYXRoPS9kYXRhL2dhbWVzL2RyYXNjdWxhCmVuZ2luZWlkPWRyYXNjdWxhCmdhbWVpZD1kcmFzY3VsYQpsYW5ndWFnZT1lbgpwbGF0Zm9ybT1wYwpndWlvcHRpb25zPXNuZE5vTUlESSBzbmRMaW5rU3BlZWNoVG9TZnggbGFuZ19FbmdsaXNoCgpbbW9ua2V5NC1kZW1vLXdpbl0KZGVzY3JpcHRpb249RXNjYXBlIEZyb20gTW9ua2V5IElzbGFuZCAoRGVtby9XaW5kb3dzL0VuZ2xpc2gpCmV4dHJhPURlbW8KY2hlY2tfZ2FtZWRhdGE9ZmFsc2UKZGF0YXVzcl9sb2FkPWZhbHNlCnBhdGg9L2RhdGEvZ2FtZXMvZW1pLXdpbi1kZW1vLWVuCmVuZ2luZWlkPWdyaW0KZ2FtZWlkPW1vbmtleTQKbGFuZ3VhZ2U9ZW4Kc2hvd19mcHM9dHJ1ZQpwbGF0Zm9ybT13aW5kb3dzCmd1aW9wdGlvbnM9c25kTm9NSURJIGdhbWVPcHRpb24xIGdhbWVPcHRpb24yIGxhbmdfRW5nbGlzaAoKW2ZlZWJsZS1kZW1vXQpkZXNjcmlwdGlvbj1UaGUgRmVlYmxlIEZpbGVzIChEZW1vL0RPUy9FbmdsaXNoKQpleHRyYT1EZW1vCnBhdGg9L2RhdGEvZ2FtZXMvZmVlYmxlLWRvcy1uaS1kZW1vLWVuCmVuZ2luZWlkPWFnb3MKZ2FtZWlkPWZlZWJsZQpsYW5ndWFnZT1lbgpwbGF0Zm9ybT1wYwpndWlvcHRpb25zPXNuZE5vU3VicyBzbmROb011c2ljIGxhdW5jaE5vTG9hZCBub0FzcGVjdCBsYW5nX0VuZ2xpc2gKCltxdWVlbl0KZGVzY3JpcHRpb249RmxpZ2h0IG9mIHRoZSBBbWF6b24gUXVlZW4gKEZsb3BweS9ET1MvRW5nbGlzaCkKZXh0cmE9RmxvcHB5CnBhdGg9L2RhdGEvZ2FtZXMvZm90YXEtZmxvcHB5L0ZPVEFRX0Zsb3BweQplbmdpbmVpZD1xdWVlbgpnYW1laWQ9cXVlZW4KbGFuZ3VhZ2U9ZW4KcGxhdGZvcm09cGMKZ3Vpb3B0aW9ucz1zbmROb1NwZWVjaCBsYW5nX0VuZ2xpc2gKCltmdC1kZW1vXQpkaW11c2VfdGVtcG89MTAKZGVzY3JpcHRpb249RnVsbCBUaHJvdHRsZSAoRGVtby9ET1MvRW5nbGlzaCkKZXh0cmE9RGVtbwpwYXRoPS9kYXRhL2dhbWVzL2Z0LWRvcy1kZW1vLWVuCmVuZ2luZWlkPXNjdW1tCmdhbWVpZD1mdApsYW5ndWFnZT1lbgpwbGF0Zm9ybT1wYwpndWlvcHRpb25zPXNuZE5vTUlESSBsYW5nX0VuZ2xpc2gKCltsc2w3LWRlbW9dCmRlc2NyaXB0aW9uPUxlaXN1cmUgU3VpdCBMYXJyeSA3OiBMb3ZlIGZvciBTYWlsISAoRGVtby9ET1MvRW5nbGlzaCkKZXh0cmE9RGVtbwpwYXRoPS9kYXRhL2dhbWVzL2xzbDctZG9zLWRlbW8tZW4KZW5naW5laWQ9c2NpCmdhbWVpZD1sc2w3Cmxhbmd1YWdlPWVuCnBsYXRmb3JtPXBjCmd1aW9wdGlvbnM9c25kTm9NSURJIGxhdW5jaE5vTG9hZCBub0FzcGVjdCBnYW1lT3B0aW9uQyBsYW5nX0VuZ2xpc2gKCltsdXJlXQpkZXNjcmlwdGlvbj1MdXJlIG9mIHRoZSBUZW1wdHJlc3MgKFZHQS9ET1MvRW5nbGlzaCkKZXh0cmE9VkdBCnBhdGg9L2RhdGEvZ2FtZXMvbHVyZS9sdXJlCmVuZ2luZWlkPWx1cmUKZ2FtZWlkPWx1cmUKbGFuZ3VhZ2U9ZW4KcGxhdGZvcm09cGMKZ3Vpb3B0aW9ucz1zbmROb1NwZWVjaCBsYW5nX0VuZ2xpc2gKCltteXN0LWRlbW8td2luXQpkZXNjcmlwdGlvbj1NeXN0IChEZW1vL1dpbmRvd3MvRW5nbGlzaCkKZXh0cmE9RGVtbwpwYXRoPS9kYXRhL2dhbWVzL215c3Qtd2luLWRlbW8tZW4vTVlTVAplbmdpbmVpZD1tb2hhd2sKZ2FtZWlkPW15c3QKbGFuZ3VhZ2U9ZW4KcGxhdGZvcm09d2luZG93cwpndWlvcHRpb25zPXNuZE5vU3VicyBzbmROb01JREkgbGF1bmNoTm9Mb2FkIG5vQXNwZWN0IGdhbWVPcHRpb24zIGxhbmdfRW5nbGlzaAoKW3BoYW50YXNtYWdvcmlhLWRlbW9dCmRlc2NyaXB0aW9uPVBoYW50YXNtYWdvcmlhIChEZW1vL0RPUy9FbmdsaXNoKQpleHRyYT1EZW1vCnBhdGg9L2RhdGEvZ2FtZXMvcGhhbnRhc21hZ29yaWEtZG9zLXdpbi1kZW1vLWVuCmVuZ2luZWlkPXNjaQpnYW1laWQ9cGhhbnRhc21hZ29yaWEKbGFuZ3VhZ2U9ZW4KcGxhdGZvcm09cGMKZ3Vpb3B0aW9ucz1zbmROb1N1YnMgc25kTGlua1NwZWVjaFRvU2Z4IGxhdW5jaE5vTG9hZCBub0FzcGVjdCBnYW1lT3B0aW9uOSBnYW1lT3B0aW9uQSBsYW5nX0VuZ2xpc2gKCltyaXZlbi1kZW1vXQpkZXNjcmlwdGlvbj1SaXZlbjogVGhlIFNlcXVlbCB0byBNeXN0IChEZW1vL1dpbmRvd3MvRW5nbGlzaCkKZXh0cmE9RGVtbwpwYXRoPS9kYXRhL2dhbWVzL3JpdmVuLXdpbi1kZW1vLWVuCmVuZ2luZWlkPW1vaGF3awpnYW1laWQ9cml2ZW4KbGFuZ3VhZ2U9ZW4KcGxhdGZvcm09d2luZG93cwpndWlvcHRpb25zPXNuZE5vU3VicyBzbmROb1NwZWVjaCBzbmROb01JREkgbGF1bmNoTm9Mb2FkIG5vQXNwZWN0IGdhbWVPcHRpb24zIGxhbmdfRW5nbGlzaAoKW3N3b3JkMmRlbW9dCmRlc2NyaXB0aW9uPUJyb2tlbiBTd29yZCBJSTogVGhlIFNtb2tpbmcgTWlycm9yIChEZW1vKQpwYXRoPS9kYXRhL2dhbWVzL3N3b3JkMi13aW4tZGVtby1lbgplbmdpbmVpZD1zd29yZDIKZ2FtZWlkPXN3b3JkMmRlbW8KZ3Vpb3B0aW9ucz1zbmROb01JREkgbm9Bc3BlY3QKCltncmltLWRlbW8td2luLTFdCmRlc2NyaXB0aW9uPUdyaW0gRmFuZGFuZ28gKERlbW8vV2luZG93cy9FbmdsaXNoKQpleHRyYT1EZW1vCmRhdGF1c3JfbG9hZD1mYWxzZQpwYXRoPS9kYXRhL2dhbWVzL2dyaW0td2luLWRlbW8yLWVuCmVuZ2luZWlkPWdyaW0KZ2FtZWlkPWdyaW0KbGFuZ3VhZ2U9ZW4Kc2hvd19mcHM9ZmFsc2UKcGxhdGZvcm09d2luZG93cwpndWlvcHRpb25zPXNuZE5vTUlESSBnYW1lT3B0aW9uMSBnYW1lT3B0aW9uMiBsYW5nX0VuZ2xpc2gKCg=="
+
+    function decodeInode(base64str) {
+      _readUInt16LE = function readUInt16LE(byteArray, offset) {
+        offset = offset >>> 0
+        return byteArray[offset] | (byteArray[offset + 1] << 8)
+      }
+      _readUInt32LE = function (byteArray, offset) {
+        return ((byteArray[offset]) |
+          (byteArray[offset + 1] << 8) |
+          (byteArray[offset + 2] << 16)) +
+          (byteArray[offset + 3] * 0x1000000)
+      }
+      var binary_string = window.atob(base64str);
+      var bytes = new Uint8Array(binary_string.length);
+      for (var i = 0; i < binary_string.length; i++) {
+        bytes[i] = binary_string.charCodeAt(i);
+      }
+      return {
+        'id': binary_string.substr(30),
+        'size': _readUInt32LE(bytes, 0),
+        'mode': _readUInt16LE(bytes, 4),
+        'atime': 0, // don't feel like implementing ieee754 (maybe we could piggyback on BrowserFS here?)
+        'mtime': 0, // don't feel like implementing ieee754 (maybe we could piggyback on BrowserFS here?)
+        'ctime': 0 // don't feel like implementing ieee754 (maybe we could piggyback on BrowserFS here?)
+      }
+    }
+
+    function encodeInode(id, size, mode, atime, mtime, ctime) {
+      _writeUInt16LE = function (byteArray, value, offset) {
+        value = +value
+        offset = offset >>> 0
+        byteArray[offset] = (value & 0xff)
+        byteArray[offset + 1] = (value >>> 8)
+        return offset + 2
       }
+      _writeUInt32LE = function (byteArray, value, offset) {
+        value = +value
+        offset = offset >>> 0
+        byteArray[offset + 3] = (value >>> 24)
+        byteArray[offset + 2] = (value >>> 16)
+        byteArray[offset + 1] = (value >>> 8)
+        byteArray[offset] = (value & 0xff)
+        return offset + 4
+      }
+      var bytes = new Uint8Array(30 + id.length);
+      _writeUInt32LE(bytes, size, 0);
+      _writeUInt16LE(bytes, mode, 4);
+      //buff.writeDoubleLE(this.atime, 6);  don't feel like implementing ieee754 (maybe we could piggyback on BrowserFS here?)
+      //buff.writeDoubleLE(this.mtime, 14);  don't feel like implementing ieee754 (maybe we could piggyback on BrowserFS here?)
+      //.writeDoubleLE(this.ctime, 22);  don't feel like implementing ieee754 (maybe we could piggyback on BrowserFS here?)
+      for (var i = 0; i < id.length; i++) {
+        bytes[30 + i] = id.charCodeAt(i);
+      }
+      var binary_string = ""
+      for (var i = 0; i < bytes.length; i++) {
+        binary_string += String.fromCharCode(bytes[i]);
+      }
+      return btoa(binary_string)
+    }
+    function setupDefaultLocalData() {
       if (localStorage.getItem("/") === null) {
-        for (key in defaultLocalStorage) {
-          localStorage.setItem(key, defaultLocalStorage[key]);
-        }
+        return fetch("scummvm.ini").then((response) => {
+          return response.text().then(function (text) {
+            // default values, created by running scummvm with --add --recursive --path=/data/games
+            //var req = new XMLHttpRequest(); // a new request
+            //req.open("GET", , false);
+            //req.send(null);
+            ini_data = btoa(text)
+
+            folder_inode_id = "b3da6754-64c0-40f0-92ad-83b6ca6ffec9"
+            folder_inode = {
+              "id": folder_inode_id,
+              "size": 4096,
+              "mode": 16895
+            }
+            ini_inode_id = "1b4a97d1-4ce0-417f-985c-e0f22ca21aef"
+            ini_inode = {
+              "id": ini_inode_id,
+              "size": atob(ini_data).length,
+              "mode": 33206
+            }
+            folder_entry_id = "70879b79-8d58-400c-8143-332242320b34"
+            folder_listing = { "scummvm.ini": folder_entry_id }
+            defaultLocalStorage = {}
+            defaultLocalStorage["/"] = encodeInode(folder_inode['id'], folder_inode['size'], folder_inode['mode'], 0, 0, 0)
+            defaultLocalStorage[folder_inode_id] = btoa(JSON.stringify(folder_listing))
+            defaultLocalStorage[folder_entry_id] = encodeInode(ini_inode['id'], ini_inode['size'], ini_inode['mode'], 0, 0, 0)
+            defaultLocalStorage[ini_inode_id] = ini_data
+            for (key in defaultLocalStorage) {
+              localStorage.setItem(key, defaultLocalStorage[key]);
+            }
+          })
+        })
       }
-      BrowserFS.FileSystem.HTTPRequest.Create({
-        index: "/games/index.json",
-        baseUrl: "/games/"
-      }, function (err, xhrfs) {
-        if (err) throw err
-        BrowserFS.FileSystem.LocalStorage.Create(function (err, lsfs) {
-          if (err) throw err
-          BrowserFS.FileSystem.MountableFileSystem.Create({
-            '/games': xhrfs,
-            '/local': lsfs
-          }, function (err, mfs) {
-            if (err) throw err
-            BrowserFS.initialize(mfs);
-            // BFS is now ready to use!
-
-            var BFS = new BrowserFS.EmscriptenFS();
-            // Mount the file system into Emscripten.
-            FS.mkdir('/data');
-            FS.mount(BFS, { root: '/' }, '/data');
-            removeRunDependency('browserfs-setup');
-          });
+      return Promise.resolve()
+    }
+
+    function setupLocalFilesystem() {
+      return setupDefaultLocalData().then(() => {
+        return new Promise((resolve, reject) => {
+          BrowserFS.FileSystem.LocalStorage.Create(function (err, lsfs) {
+            if (err) return reject(err)
+            BrowserFS.FileSystem.MountableFileSystem.Create({
+              '/': lsfs
+            }, function (err, mfs) {
+              if (err) return reject(err)
+              BrowserFS.initialize(mfs);
+              // BrowserFS is now ready to use!
+              var BFS = new BrowserFS.EmscriptenFS();
+              // Mount the file systems into Emscripten.
+              FS.mkdir('/local');
+              FS.mount(BFS, { root: '/' }, '/local');
+              return resolve()
+            })
+          })
         });
       });
     }
+    function setupHTTPFilesystem(folder_name) {
+
+      FS.mkdir("/" + folder_name)
+      FS.mount(new ScummvmFS(FS, folder_name), {}, "/" + folder_name + "/");
+    }
+    function setupFilesystem() {
+      addRunDependency('scummvm-fs-setup');
+      setupLocalFilesystem().then(() => {
+
+        setupHTTPFilesystem("games")
+        setupHTTPFilesystem("plugins")
+        setupHTTPFilesystem("data")
+
+        removeRunDependency('scummvm-fs-setup');
+
+      });
+    }
 
     var Module = {
-      preRun: [setupBrowserFS],
+      preRun: [setupFilesystem],
       postRun: [],
       print: (function () {
         var element = document.getElementById('output');
@@ -190,6 +314,7 @@
         return canvas;
       })(),
       setStatus: function (text) {
+        console.log((new Date()).toLocaleTimeString() + " " + text)
         if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
         if (text === Module.setStatus.last.text) return;
         var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
@@ -208,6 +333,12 @@
           progressElement.max = null;
           progressElement.hidden = true;
         }
+        if (text && text.length > 0) {
+          text += "⚡️"
+          statusElement.style.display = "block";
+        } else {
+          statusElement.style.display = "none";
+        }
         statusElement.innerHTML = text;
       },
       totalDependencies: 0,
@@ -216,7 +347,7 @@
         Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies - left) + '/' + this.totalDependencies + ')' : loadingDoneMessage());
       }
     };
-    Module.setStatus('Downloading...');
+    Module.setStatus('Downloading ScummVM...');
     window.onerror = function () {
       statusElement.classList.add("error")
       Module.setStatus('Exception thrown, see JavaScript console');
@@ -227,7 +358,6 @@
 
   </script>
 
-  <script async type="text/javascript" src="files.js"></script>
   {{{ SCRIPT }}}
 </body>
 
diff --git a/dists/emscripten/emscripten-15893-fix.patch b/dists/emscripten/emscripten-15893-fix.patch
new file mode 100644
index 00000000000..85c65c3a86f
--- /dev/null
+++ b/dists/emscripten/emscripten-15893-fix.patch
@@ -0,0 +1,44 @@
+From 2ea11b4734de5656aaf3285145831e2bb9ad53ae Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20Ku=CC=88ndig?= <kuendig at scandit.com>
+Date: Sun, 24 Apr 2022 18:55:51 +0200
+Subject: [PATCH] Keeping a reference to the original function in
+ instrumentWasmExports and using that in _dlsym_js to pass the right method to
+ addFunction.
+
+---
+ src/library_async.js  | 3 +++
+ src/library_dylink.js | 4 ++--
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/src/library_async.js b/src/library_async.js
+index 14511ba05..32ce7abd3 100644
+--- a/src/library_async.js
++++ b/src/library_async.js
+@@ -130,6 +130,9 @@ mergeInto(LibraryManager.library, {
+                 }
+               }
+             };
++#if MAIN_MODULE
++            ret[x].orig = original;
++#endif
+           } else {
+             ret[x] = original;
+           }
+diff --git a/src/library_dylink.js b/src/library_dylink.js
+index 291c50ef2..3c70cfca7 100644
+--- a/src/library_dylink.js
++++ b/src/library_dylink.js
+@@ -964,8 +967,8 @@ var LibraryDylink = {
+ #endif
+ 
+ #if ASYNCIFY
+-      if(symbol in GOT && GOT[symbol].value != 0) {
+-        return GOT[symbol].value 
++      if ('orig' in result) {
++        result = result.orig;
+       }
+ #endif
+       // Insert the function into the wasm table.  If its a direct wasm function
+-- 
+2.31.0
+
diff --git a/dists/emscripten/emscripten-15893.patch b/dists/emscripten/emscripten-15893.patch
new file mode 100644
index 00000000000..e8bcbd303db
--- /dev/null
+++ b/dists/emscripten/emscripten-15893.patch
@@ -0,0 +1,386 @@
+From 33d2935283bdf734dff5f5a2560571480f47b6b7 Mon Sep 17 00:00:00 2001
+From: kamenokonokotan <kamenokonokotan at gmail.com>
+Date: Thu, 6 Jan 2022 14:55:48 +0900
+Subject: [PATCH 01/10] import mutable globals used in Asyncify pass
+
+---
+ emcc.py        | 9 +++++++++
+ emscripten.py  | 1 +
+ src/library.js | 6 ++++++
+ 3 files changed, 16 insertions(+)
+
+diff --git a/emcc.py b/emcc.py
+index 34df446434c..e5a425d1f31 100755
+--- a/emcc.py
++++ b/emcc.py
+@@ -554,6 +554,8 @@ def get_binaryen_passes():
+     passes += ['--fpcast-emu']
+   if settings.ASYNCIFY:
+     passes += ['--asyncify']
++    if settings.MAIN_MODULE or settings.SIDE_MODULE:
++      passes += ['--pass-arg=asyncify-side-module']
+     if settings.ASSERTIONS:
+       passes += ['--pass-arg=asyncify-asserts']
+     if settings.ASYNCIFY_ADVISE:
+@@ -1854,6 +1856,13 @@ def phase_linker_setup(options, state, newargs, user_settings):
+         '__heap_base',
+         '__stack_pointer',
+     ]
++
++    if settings.ASYNCIFY:
++      settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += [
++        '__asyncify_state',
++        '__asyncify_data'
++      ]
++    
+     # Unconditional dependency in library_dylink.js
+     settings.REQUIRED_EXPORTS += ['setThrew']
+ 
+diff --git a/emscripten.py b/emscripten.py
+index cd0c27dc2f3..b7d1bff3994 100644
+--- a/emscripten.py
++++ b/emscripten.py
+@@ -344,6 +344,7 @@ def emscript(in_wasm, out_wasm, outfile_js, memfile):
+ 
+   if settings.ASYNCIFY:
+     exports += ['asyncify_start_unwind', 'asyncify_stop_unwind', 'asyncify_start_rewind', 'asyncify_stop_rewind']
++    metadata['globalImports'] += ['__asyncify_state', '__asyncify_data']
+ 
+   report_missing_symbols(forwarded_json['libraryFunctions'])
+ 
+diff --git a/src/library.js b/src/library.js
+index 401e17d086a..2c4d375d52e 100644
+--- a/src/library.js
++++ b/src/library.js
+@@ -3521,6 +3521,12 @@ LibraryManager.library = {
+   __c_longjmp: "new WebAssembly.Tag({'parameters': ['{{{ POINTER_TYPE }}}']})",
+   __c_longjmp_import: true,
+ #endif
++#if ASYNCIFY
++  __asyncify_state: "new WebAssembly.Global({'value': 'i32', 'mutable': true}, 0)",
++  __asyncify_state__import: true,
++  __asyncify_data: "new WebAssembly.Global({'value': 'i32', 'mutable': true}, 0)",
++  __asyncify_data__import: true,
++#endif
+ #endif
+ };
+ 
+
+From 065cb3c3aef101b8b8e249e32a44843830e5fa73 Mon Sep 17 00:00:00 2001
+From: nokotan <kamenokonokotan at gmail.com>
+Date: Sun, 23 Jan 2022 21:54:03 +0900
+Subject: [PATCH 02/10] move globals metadata modification
+
+---
+ emscripten.py | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/emscripten.py b/emscripten.py
+index b7d1bff3994..810eeb93dda 100644
+--- a/emscripten.py
++++ b/emscripten.py
+@@ -324,6 +324,9 @@ def emscript(in_wasm, out_wasm, outfile_js, memfile):
+     if settings.INITIAL_TABLE == -1:
+       settings.INITIAL_TABLE = dylink_sec.table_size + 1
+ 
++    if settings.ASYNCIFY:
++      metadata['globalImports'] += ['__asyncify_state', '__asyncify_data']
++
+   glue, forwarded_data = compile_settings()
+   if DEBUG:
+     logger.debug('  emscript: glue took %s seconds' % (time.time() - t))
+@@ -344,7 +347,6 @@ def emscript(in_wasm, out_wasm, outfile_js, memfile):
+ 
+   if settings.ASYNCIFY:
+     exports += ['asyncify_start_unwind', 'asyncify_stop_unwind', 'asyncify_start_rewind', 'asyncify_stop_rewind']
+-    metadata['globalImports'] += ['__asyncify_state', '__asyncify_data']
+ 
+   report_missing_symbols(forwarded_json['libraryFunctions'])
+ 
+
+From fc1edebd9df7e1c84e0fd7d700dd80dbf5a6e83b Mon Sep 17 00:00:00 2001
+From: kamenokonokotan <kamenokonokotan at gmail.com>
+Date: Tue, 25 Jan 2022 22:00:21 +0900
+Subject: [PATCH 03/10] Remove redundant spaces
+
+---
+ emcc.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/emcc.py b/emcc.py
+index e5a425d1f31..2c51a6d4264 100755
+--- a/emcc.py
++++ b/emcc.py
+@@ -1862,7 +1862,7 @@ def phase_linker_setup(options, state, newargs, user_settings):
+         '__asyncify_state',
+         '__asyncify_data'
+       ]
+-    
++
+     # Unconditional dependency in library_dylink.js
+     settings.REQUIRED_EXPORTS += ['setThrew']
+ 
+
+From 163609c529d31d9c6a07866ffb6f0d6a2901d8c9 Mon Sep 17 00:00:00 2001
+From: kamenokonokotan <kamenokonokotan at gmail.com>
+Date: Tue, 25 Jan 2022 22:10:36 +0900
+Subject: [PATCH 04/10] Add test_asyncify_side_module
+
+---
+ tests/test_core.py | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/tests/test_core.py b/tests/test_core.py
+index 6eeee235e5b..e004def18e6 100644
+--- a/tests/test_core.py
++++ b/tests/test_core.py
+@@ -7903,6 +7903,34 @@ def test_asyncify_indirect_lists(self, args, should_pass):
+       if should_pass:
+         raise
+ 
++  @needs_dylink
++  @no_memory64('TODO: asyncify for wasm64')
++  def test_asyncify_side_module(self):
++    self.set_setting('ASYNCIFY')
++    self.emcc_args += ['-sASYNCIFY_IMPORTS=["_Z8my_sleepi"]']
++    self.dylink_test(r'''
++      #include <stdio.h>
++      #include "header.h"
++
++      int main() {
++        my_sleep(1);     
++        return 0;
++      }
++    ''', r'''
++      #include <emscripten.h>
++      #include <stdio.h>
++      #include "header.h"
++
++      void my_sleep(int milli_seconds) {
++        // put variable onto stack
++        volatile int value = 42;
++        printf("%d ", value);
++        emscripten_sleep(milli_seconds);
++        // variable on stack in side module function should be restored.
++        printf("%d\n", value);
++      }
++    ''', '42 42', header='void my_sleep(int);')
++
+   @no_asan('asyncify stack operations confuse asan')
+   @no_memory64('TODO: asyncify for wasm64')
+   def test_emscripten_scan_registers(self):
+
+From 8066f18bf46c2d694bba624e00cb6f38c11499a5 Mon Sep 17 00:00:00 2001
+From: kamenokonokotan <kamenokonokotan at gmail.com>
+Date: Wed, 26 Jan 2022 01:29:14 +0900
+Subject: [PATCH 05/10] flake8, add EXIT_RUNTIME
+
+---
+ tests/test_core.py | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tests/test_core.py b/tests/test_core.py
+index e004def18e6..b30806192ab 100644
+--- a/tests/test_core.py
++++ b/tests/test_core.py
+@@ -7907,13 +7907,14 @@ def test_asyncify_indirect_lists(self, args, should_pass):
+   @no_memory64('TODO: asyncify for wasm64')
+   def test_asyncify_side_module(self):
+     self.set_setting('ASYNCIFY')
++    self.set_setting('EXIT_RUNTIME', 1)
+     self.emcc_args += ['-sASYNCIFY_IMPORTS=["_Z8my_sleepi"]']
+     self.dylink_test(r'''
+       #include <stdio.h>
+       #include "header.h"
+ 
+       int main() {
+-        my_sleep(1);     
++        my_sleep(1);
+         return 0;
+       }
+     ''', r'''
+
+From 2f451abf5fa81f6bc08a9a671d7251f630c5ea67 Mon Sep 17 00:00:00 2001
+From: kamenokonokotan <kamenokonokotan at gmail.com>
+Date: Sun, 30 Jan 2022 02:39:01 +0900
+Subject: [PATCH 06/10] add instrumentWasmExports
+
+---
+ src/library_dylink.js | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/library_dylink.js b/src/library_dylink.js
+index e71ceb1b65b..8a0a3df9469 100644
+--- a/src/library_dylink.js
++++ b/src/library_dylink.js
+@@ -583,6 +583,9 @@ var LibraryDylink = {
+         // add new entries to functionsInTableMap
+         updateTableMap(tableBase, metadata.tableSize);
+         moduleExports = relocateExports(instance.exports, memoryBase);
++#if ASYNCIFY
++        moduleExports = Asyncify.instrumentWasmExports(moduleExports);
++#endif
+         if (!flags.allowUndefined) {
+           reportUndefinedSymbols();
+         }
+
+From d09570de2e65ead70ab31f4a843ecde29512436c Mon Sep 17 00:00:00 2001
+From: kamenokonokotan <kamenokonokotan at gmail.com>
+Date: Sun, 30 Jan 2022 02:39:56 +0900
+Subject: [PATCH 07/10] add searched symbols in getDataRewindFunc
+
+---
+ src/library_async.js | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/src/library_async.js b/src/library_async.js
+index da09a1ae2d8..0ceb072dd37 100644
+--- a/src/library_async.js
++++ b/src/library_async.js
+@@ -205,6 +205,11 @@ mergeInto(LibraryManager.library, {
+       var id = {{{ makeGetValue('ptr', C_STRUCTS.asyncify_data_s.rewind_id, 'i32') }}};
+       var name = Asyncify.callStackIdToName[id];
+       var func = Module['asm'][name];
++#if RELOCATABLE
++      if (!func) {
++        func = Module[asmjsMangle(name)];
++      }
++#endif
+       return func;
+     },
+ 
+
+From 3a71ca6d2d93f1d933dc43b9aa34e56086a30534 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=BCndig?= <christian at kuendig.info>
+Date: Fri, 18 Feb 2022 18:15:53 +0100
+Subject: [PATCH 08/10] Fixing dlsym for emscripten-core/emscripten#15893
+
+---
+ src/library_dylink.js | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/src/library_dylink.js b/src/library_dylink.js
+index 8a0a3df9469..9fca8adf488 100644
+--- a/src/library_dylink.js
++++ b/src/library_dylink.js
+@@ -965,6 +965,12 @@ var LibraryDylink = {
+ #if DYLINK_DEBUG
+       err('dlsym: ' + symbol + ' getting table slot for: ' + result);
+ #endif
++
++#if ASYNCIFY
++      if(symbol in GOT && GOT[symbol].value != 0) {
++        return GOT[symbol].value 
++      }
++#endif
+       // Insert the function into the wasm table.  If its a direct wasm function
+       // the second argument will not be needed.  If its a JS function we rely
+       // on the `sig` attribute being set based on the `<func>__sig` specified
+
+From 7e451a8df7144c6293a57c8563538d409b904fe0 Mon Sep 17 00:00:00 2001
+From: kamenokonokotan <kamenokonokotan at gmail.com>
+Date: Sun, 6 Mar 2022 00:05:00 +0900
+Subject: [PATCH 09/10] Add test case test_asyncify_dlfcn
+
+---
+ tests/test_core.py | 33 +++++++++++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+diff --git a/tests/test_core.py b/tests/test_core.py
+index b30806192ab..0c978f39343 100644
+--- a/tests/test_core.py
++++ b/tests/test_core.py
+@@ -7932,6 +7932,39 @@ def test_asyncify_side_module(self):
+       }
+     ''', '42 42', header='void my_sleep(int);')
+ 
++  @needs_dylink
++  @no_memory64('TODO: asyncify for wasm64')
++  def test_asyncify_dlfcn(self):
++    self.set_setting('ASYNCIFY')
++    self.set_setting('EXIT_RUNTIME', 1)
++    self.emcc_args += ['-sASYNCIFY_IGNORE_INDIRECT=0']
++    self.dylink_test(r'''
++      #include <iostream>
++      #include <dlfcn.h>
++
++      typedef int (*func_t)();
++
++      int main(int argc, char **argv)
++      {
++        void *_dlHandle = dlopen("liblib.so", RTLD_NOW | RTLD_LOCAL);
++        func_t my_func = (func_t)dlsym(_dlHandle, "side_module_run");
++        printf("%d\n", my_func());
++        return 0;
++      }
++    ''', r'''
++      #include <iostream>
++      #include <emscripten/emscripten.h>
++
++      extern "C"
++      {
++        int side_module_run()
++        {
++          emscripten_sleep(1000);
++          return 42;
++        }
++      }
++    ''', '42', need_reverse=False)
++
+   @no_asan('asyncify stack operations confuse asan')
+   @no_memory64('TODO: asyncify for wasm64')
+   def test_emscripten_scan_registers(self):
+
+From 1b85abaab0186939a36207f2480cf836b096840f Mon Sep 17 00:00:00 2001
+From: kamenokonokotan <kamenokonokotan at gmail.com>
+Date: Wed, 6 Apr 2022 01:40:08 +0900
+Subject: [PATCH 10/10] Update test case
+
+---
+ tests/test_core.py | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/tests/test_core.py b/tests/test_core.py
+index 0c978f39343..7009c539f12 100644
+--- a/tests/test_core.py
++++ b/tests/test_core.py
+@@ -7914,7 +7914,9 @@ def test_asyncify_side_module(self):
+       #include "header.h"
+ 
+       int main() {
++        printf("before sleep\n");
+         my_sleep(1);
++        printf("after sleep\n");
+         return 0;
+       }
+     ''', r'''
+@@ -7925,12 +7927,12 @@ def test_asyncify_side_module(self):
+       void my_sleep(int milli_seconds) {
+         // put variable onto stack
+         volatile int value = 42;
+-        printf("%d ", value);
++        printf("%d\n", value);
+         emscripten_sleep(milli_seconds);
+         // variable on stack in side module function should be restored.
+         printf("%d\n", value);
+       }
+-    ''', '42 42', header='void my_sleep(int);')
++    ''', 'before sleep\n42\n42\nafter sleep\n', header='void my_sleep(int);')
+ 
+   @needs_dylink
+   @no_memory64('TODO: asyncify for wasm64')
+@@ -7959,11 +7961,13 @@ def test_asyncify_dlfcn(self):
+       {
+         int side_module_run()
+         {
++          printf("before sleep\n");
+           emscripten_sleep(1000);
++          printf("after sleep\n");
+           return 42;
+         }
+       }
+-    ''', '42', need_reverse=False)
++    ''', 'before sleep\nafter sleep\n42', need_reverse=False)
+ 
+   @no_asan('asyncify stack operations confuse asan')
+   @no_memory64('TODO: asyncify for wasm64')
diff --git a/dists/emscripten/emscripten-16559.patch b/dists/emscripten/emscripten-16559.patch
new file mode 100644
index 00000000000..122229220b6
--- /dev/null
+++ b/dists/emscripten/emscripten-16559.patch
@@ -0,0 +1,61 @@
+From 229c16de0b827321a0c3e55975e980017d234d43 Mon Sep 17 00:00:00 2001
+From: Charlie Birks <charlie at daft.games>
+Date: Tue, 22 Mar 2022 13:13:34 +0000
+Subject: [PATCH 1/2] Update SDL2 for #16462
+
+---
+ tools/ports/sdl2.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/ports/sdl2.py b/tools/ports/sdl2.py
+index f499ca8fa15..7c0a30cbd71 100644
+--- a/tools/ports/sdl2.py
++++ b/tools/ports/sdl2.py
+@@ -5,8 +5,8 @@
+ 
+ import os
+ 
+-TAG = 'release-2.0.20'
+-HASH = '67e1abe1183b04836b35d724fd495c83c9559b4530d4a5c9bcc89648af0ac7cc51c02f7055a1664fe5f5f90953d22a6c431fa8bc5cdd77c94a97f107c47e2d62'
++TAG = '4b8d69a41687e5f6f4b05f7fd9804dd9fcac0347'
++HASH = '2d4d577c7584da22306b05a44bc08200460a33cd414fed2dc948e2a86e7b2d1a5cbc13bacadb63618823ba63c210f21c570adbab39f7645bf902196fa91c6b4e'
+ SUBDIR = 'SDL-' + TAG
+ 
+ 
+
+From 1eb16caf951bf0a38dda07d3335b4fdeb397ebc7 Mon Sep 17 00:00:00 2001
+From: Charlie Birks <charlie at daft.games>
+Date: Fri, 25 Mar 2022 11:24:00 +0000
+Subject: [PATCH 2/2] Add an extra move to the SDL2 mouse test
+
+The "first" event now has valid relative motion, so don't need that workaround either.
+---
+ tests/sdl2_mouse.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/tests/sdl2_mouse.c b/tests/sdl2_mouse.c
+index f7786cdb02d..6ec8871d427 100644
+--- a/tests/sdl2_mouse.c
++++ b/tests/sdl2_mouse.c
+@@ -26,11 +26,10 @@ void one() {
+         printf("motion : %d,%d  %d,%d\n", m->x, m->y, m->xrel, m->yrel);
+ 
+         if (mouse_motions == 0) {
+-          // xrel/yrel will be zero for the first motion
+ #ifdef TEST_SDL_MOUSE_OFFSETS
+-          assert(eq(m->x, 5) && eq(m->y, 15) && eq(m->xrel, 0) && eq(m->yrel, 0));
++          assert(eq(m->x, 5) && eq(m->y, 15) && eq(m->xrel, 5) && eq(m->yrel, 15));
+ #else
+-          assert(eq(m->x, 10) && eq(m->y, 20) && eq(m->xrel, 0) && eq(m->yrel, 0));
++          assert(eq(m->x, 10) && eq(m->y, 20) && eq(m->xrel, 10) && eq(m->yrel, 20));
+ #endif
+         } else if (mouse_motions == 1) {
+ #ifdef TEST_SDL_MOUSE_OFFSETS
+@@ -93,6 +92,7 @@ int main() {
+ }
+ 
+ void main_2(void* arg) {
++  emscripten_run_script("window.simulateMouseEvent(0, 0, -1)");
+   emscripten_run_script("window.simulateMouseEvent(10, 20, -1)"); // move from 0,0 to 10,20
+   emscripten_run_script("window.simulateMouseEvent(10, 20, 0)"); // click
+   emscripten_run_script("window.simulateMouseEvent(10, 20, 0)"); // click some more, but this one should be ignored through PeepEvent
diff --git a/dists/emscripten/emscripten-16687.patch b/dists/emscripten/emscripten-16687.patch
new file mode 100644
index 00000000000..94b86bd1254
--- /dev/null
+++ b/dists/emscripten/emscripten-16687.patch
@@ -0,0 +1,22 @@
+From 5ed10829c6d806d630d98943432c222cf8f02017 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=BCndig?= <christian at kuendig.info>
+Date: Sat, 9 Apr 2022 16:12:40 +0200
+Subject: [PATCH] SDL2: Fix SDL_OpenURL
+
+---
+ tools/ports/sdl2.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/ports/sdl2.py b/tools/ports/sdl2.py
+index 7c0a30cbd71..fb6ea398bfd 100644
+--- a/tools/ports/sdl2.py
++++ b/tools/ports/sdl2.py
+@@ -58,7 +58,7 @@ def create(final):
+     power/emscripten/SDL_syspower.c joystick/emscripten/SDL_sysjoystick.c
+     filesystem/emscripten/SDL_sysfilesystem.c timer/unix/SDL_systimer.c haptic/dummy/SDL_syshaptic.c
+     main/dummy/SDL_dummy_main.c locale/SDL_locale.c locale/emscripten/SDL_syslocale.c misc/SDL_url.c
+-    misc/dummy/SDL_sysurl.c'''.split()
++    misc/emscripten/SDL_sysurl.c'''.split()
+     thread_srcs = ['SDL_syscond.c', 'SDL_sysmutex.c', 'SDL_syssem.c', 'SDL_systhread.c', 'SDL_systls.c']
+     thread_backend = 'generic' if not settings.USE_PTHREADS else 'pthread'
+     srcs += ['thread/%s/%s' % (thread_backend, s) for s in thread_srcs]
diff --git a/dists/emscripten/pre.js b/dists/emscripten/pre.js
deleted file mode 100644
index db4c2357871..00000000000
--- a/dists/emscripten/pre.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/*global Module*/
-Module["arguments"] = [];
-Module["arguments"].push("--config=/data/local/scummvm.ini");
-
diff --git a/dists/emscripten/scummvm-192.png b/dists/emscripten/scummvm-192.png
deleted file mode 100644
index efb3c245291..00000000000
Binary files a/dists/emscripten/scummvm-192.png and /dev/null differ
diff --git a/dists/emscripten/scummvm-512.png b/dists/emscripten/scummvm-512.png
deleted file mode 100644
index e97ff52e5ef..00000000000
Binary files a/dists/emscripten/scummvm-512.png and /dev/null differ


Commit: 5999281d029ebb11910b1afbf99c6029ef06e065
    https://github.com/scummvm/scummvm/commit/5999281d029ebb11910b1afbf99c6029ef06e065
Author: Christian Kündig (christian at kuendig.info)
Date: 2022-06-12T14:41:44+02:00

Commit Message:
EMSCRIPTEN: Automatically bundle icons from scummvm/scummvm-icons repository

Changed paths:
    dists/emscripten/README.md
    dists/emscripten/assets/scummvm.ini
    dists/emscripten/build.sh


diff --git a/dists/emscripten/README.md b/dists/emscripten/README.md
index 4e00f53273e..fe9db1a9596 100644
--- a/dists/emscripten/README.md
+++ b/dists/emscripten/README.md
@@ -37,6 +37,7 @@ This folder contains a script to help build scummvm with Emscripten, it automati
   *   `games`: Download some demos and set up all data require for the demo page. See `--bundle-games=` below.
   *   `dist`: Copy all files into a single build-emscripten folder to bring it all together
   *   `add-games`: Runs ScummVM once to add all bundled games to the default `scummvm.ini`
+  *   `icons`: Adds additional icons to the `gui-icons.dat` file. Please note that the `scummvm-icons` repository needs to be located in the parent folder of the project.
 * `clean`: Cleanup build artifacts (keeps libs + emsdk in place)
 * `run`: Start webserver and launch ScummVM in Chrome  
   
diff --git a/dists/emscripten/assets/scummvm.ini b/dists/emscripten/assets/scummvm.ini
index e8441905942..95125efb8cb 100644
--- a/dists/emscripten/assets/scummvm.ini
+++ b/dists/emscripten/assets/scummvm.ini
@@ -3,4 +3,5 @@ gfx_mode=opengl
 pluginspath=/plugins
 grouping=company
 renderer=opengl_shaders
+gui_launcher_chooser=grid
 
diff --git a/dists/emscripten/build.sh b/dists/emscripten/build.sh
index 9c28deee875..687e43be928 100755
--- a/dists/emscripten/build.sh
+++ b/dists/emscripten/build.sh
@@ -333,6 +333,29 @@ if [[ "dist" =~ $(echo ^\(${TASKS}\)$) || "build" =~ $(echo ^\(${TASKS}\)$) ]];
   cp "$ROOT_FOLDER/icons/scummvm.ico" "${ROOT_FOLDER}/build-emscripten/favicon.ico"
 fi
 
+#################################
+# Add icons
+#################################
+if [[ "icons" =~ $(echo ^\(${TASKS}\)$) || "build" =~ $(echo ^\(${TASKS}\)$) ]]; then
+
+  if [[ -d "${ROOT_FOLDER}/../scummvm-icons/" ]]; then
+    echo "Adding files from icons repository "
+    cp "${ROOT_FOLDER}/gui/themes/gui-icons.dat" "${ROOT_FOLDER}/build-emscripten/data"
+    cd "${ROOT_FOLDER}/../scummvm-icons/"
+    ${EMSDK_PYTHON:-'python3'} gen-set.py
+    echo "add icons"
+    zip -q -u "${ROOT_FOLDER}/build-emscripten/data/gui-icons.dat" icons/*
+    echo "add xml"
+    zip -q -u "${ROOT_FOLDER}/build-emscripten/data/gui-icons.dat" *.xml
+    echo "update index"
+    cd "${ROOT_FOLDER}/build-emscripten/data"
+    "$EMSDK_NODE" "$DIST_FOLDER/build-make_http_index.js" >index.json
+  else
+    echo "Icons repository not found"
+  fi
+
+fi
+
 #################################
 # Automatically detect games and create scummvm.ini file
 #################################


Commit: ef72778b26fcc246f1ecb0cc8b10a2190d54f644
    https://github.com/scummvm/scummvm/commit/ef72778b26fcc246f1ecb0cc8b10a2190d54f644
Author: Christian Kündig (christian at kuendig.info)
Date: 2022-06-12T14:41:57+02:00

Commit Message:
EMSCRIPTEN: Clean up patches and update readme

Changed paths:
  A dists/emscripten/libmad-0.15.1b-fixes-1.patch
  R dists/emscripten/emscripten-15893-fix.patch
    dists/emscripten/README.md
    dists/emscripten/build.sh
    dists/emscripten/emscripten-15893.patch


diff --git a/dists/emscripten/README.md b/dists/emscripten/README.md
index fe9db1a9596..a3aa333d311 100644
--- a/dists/emscripten/README.md
+++ b/dists/emscripten/README.md
@@ -59,36 +59,37 @@ See e.g. [chkuendig/scummvm-demo/.github/workflows/main.yml](https://github.com/
 ## Current Status of Port
 In general, ScummVM runs in the browser sufficiently to run all demos and freeware games.
 
-* All engines compile (though I didn't test all of them), including ResidualVM with WebGL acceleration and shaders work as plugins (which means the initial page load is somewhat limited)
+* All engines compile (though I didn't test all of them), including ResidualVM with WebGL acceleration and shaders and run as plugins (which means the initial page load is somewhat limited)
 * Audio works and 3rd-party libraries for sound and video decoding are integrated.
 * All data can be downloaded on demand (or in the case of the testbed generated as part of the build script)
 
 ## Known Issues + Possible Improvements
 
-### Emscripten Optimizations
-*   Optimize asyncify behaviour (we only have SDL functions calling wait currently), e.g with [SDL_HINT_EMSCRIPTEN_ASYNCIFY](https://wiki.libsdl.org/SDL_HINT_EMSCRIPTEN_ASYNCIFY)
+### Emscripten Asyncify Optimizations
+ScummVM relies heavily on Asyncify (see note above), and this comes with a quite heavy performance penalty. Possible optimizations in this regard could be:
 *   Specify a `ASYNCIFY_ONLY` list in `configure` to  make asyncify only instrument functions in the call path as described in [emscripten.org: Asyncify](https://emscripten.org/docs/porting/asyncify.html)
-*   Limit asyncify overhead by having a more specific setting for `ASYNCIFY_IMPORTS` in `configure`.
+*   Limit asyncify overhead by having a more specific setting for `ASYNCIFY_IMPORTS` in `configure`. This is especailly critical for plugins as when plugins are enabled, we currently add all functions as imports. 
+*   🐞 We currently can't update beyond Emscripten 3.1.8 as the build fails since WebAssembly/binaryen#4567  if plugins enabled (because all functions become locals with `ASYNCIFY_IMPORTS=[*]`)
 *   Don't use asyncify but rewrite main loop to improve performance
+*   Look into emscripten-core/emscripten#16779 as an alternative
 
 ### Storage Integration
 *   BrowserFS seems abandoned and never did a stable 2.0.0 release. It's worth replacing it.  
     * `scummvm_fs.js` is an early prototype for a custom FS which can be adopted for ScummVM specific needs, i.e.
       * Download all game assets in background once the game has started
       * Presist last game and last plugin for offline use
-      * Implement support for range requests (currently not supported with `emrun` so another development server would have to be included as well)
       * Pre-load assets asynchronously (not blocking) - i.e. rest of the data of a game which has been launched
-      * Loading indicators
-
+      * Loading indicators (doesn't work with the current synchronous/blocking filesystem)
 *   Add support for save games (and game data?) on personal cloud storage (Dropbox, Google Drive).
 
+
+Emscripten is currently re-doing their filesystem code, which could help address some of the above issues ( emscripten-core/emscripten#15041 ).
+
 ### UI Integration
 *   Build a nice webpage around the canvas.
-    *   Allow showing/hiding of console, replace buttons/checkboxes from default emscripten template.
+    *   Allow showing/hiding of console (at the moment there's only the browser console)
     *   Bonus: Adapt page padding/background color to theme (black when in game)
-
 *   Automatically show console in case of exceptions
-
-* Aspect Ratio is broken when starting a game until the window is resized once. Good starting points might be  https://github.com/emscripten-ports/SDL2/issues/47 or https://github.com/emscripten-core/emscripten/issues/10285
-    * doesn't seem to affect 3d engines in opengl mode
-    * definitely affects testbed in opengl or other modes
\ No newline at end of file
+* 🐞 Aspect Ratio is broken when starting a game until the window is resized once. Good starting points might be  https://github.com/emscripten-ports/SDL2/issues/47 or https://github.com/emscripten-core/emscripten/issues/10285
+    * doesn't seem to affect 3D engines in opengl mode
+    * definitely affects testbed in OpenGL or other modes
\ No newline at end of file
diff --git a/dists/emscripten/build.sh b/dists/emscripten/build.sh
index 687e43be928..b791d02680c 100755
--- a/dists/emscripten/build.sh
+++ b/dists/emscripten/build.sh
@@ -104,15 +104,17 @@ if [[ "setup" =~ $(echo ^\(${TASKS}\)$) || "build" =~ $(echo ^\(${TASKS}\)$) ]];
     ./emsdk install ${EMSCRIPTEN_VERSION}
     # We currently require a few patches for unreleased changes in SDL2 and Emscripten
     if [[ "$EMSCRIPTEN_VERSION" == "3.1.8" ]]; then
+      echo "Patching Emscripten"
       cd upstream/emscripten
       # until https://github.com/emscripten-core/emscripten/pull/15893 gets merged and released, we need to manually patch it
+      # as the upstream PR has been rebased against an incompatible main,  we'll actually use https://github.com/chkuendig/emscripten/pull/2
+      wget -nc https://github.com/chkuendig/emscripten/pull/2.patch  -O "$DIST_FOLDER/emscripten-15893.patch" || true 
       patch -p1 --verbose <"$DIST_FOLDER/emscripten-15893.patch"
-      # some additional fixes on top of 15893:
-      patch -p1 --verbose <"$DIST_FOLDER/emscripten-15893-fix.patch"
-
       # until https://github.com/emscripten-core/emscripten/pull/16559 gets merged and released, we need to manually patch it
+      wget -nc https://github.com/emscripten-core/emscripten/pull/16559.patch  -O "$DIST_FOLDER/emscripten-16559.patch" || true 
       patch -p1 --verbose <"$DIST_FOLDER/emscripten-16559.patch"
       # until https://github.com/emscripten-core/emscripten/pull/16687 gets merged and released, we need to manually patch it
+      wget -nc https://github.com/emscripten-core/emscripten/pull/16559.patch  -O "$DIST_FOLDER/emscripten-16559.patch" || true 
       patch -p1 --verbose <"$DIST_FOLDER/emscripten-16687.patch"
     fi
 
@@ -179,7 +181,7 @@ if [[ "libs" =~ $(echo ^\(${TASKS}\)$) || "build" =~ $(echo ^\(${TASKS}\)$) ]];
     cd "$LIBS_FOLDER"
     wget -nc "https://downloads.xiph.org/releases/theora/libtheora-1.1.1.tar.xz"
     tar -xf libtheora-1.1.1.tar.xz
-    cd "./libtheora-1.1.1/"
+    cd "$LIBS_FOLDER/libtheora-1.1.1/"
     CFLAGS="-fPIC -s USE_OGG=1" emconfigure ./configure --host=wasm32-unknown-none --build=wasm32-unknown-none --prefix="$LIBS_FOLDER/build/" --disable-asm
     emmake make -j 3
     emmake make install
@@ -191,7 +193,7 @@ if [[ "libs" =~ $(echo ^\(${TASKS}\)$) || "build" =~ $(echo ^\(${TASKS}\)$) ]];
     cd "$LIBS_FOLDER"
     wget -nc "https://sourceforge.net/projects/faac/files/faad2-src/faad2-2.8.0/faad2-2.8.8.tar.gz"
     tar -xf faad2-2.8.8.tar.gz
-    cd "./faad2-2.8.8/"
+    cd "$LIBS_FOLDER/faad2-2.8.8/"
     CFLAGS="-fPIC" emconfigure ./configure --host=wasm32-unknown-none --build=wasm32-unknown-none --prefix="$LIBS_FOLDER/build/"
     emmake make
     emmake make install
@@ -201,14 +203,14 @@ if [[ "libs" =~ $(echo ^\(${TASKS}\)$) || "build" =~ $(echo ^\(${TASKS}\)$) ]];
   if [[ ! -f "$LIBS_FOLDER/build/lib/libmad.a" ]]; then
     echo "building libmad-0.15.1b"
     cd "$LIBS_FOLDER"
-    # libmad needs patching: https://stackoverflow.com/questions/14015747/gccs-fforce-mem-option
-    wget -nc "http://www.linuxfromscratch.org/patches/blfs/svn/libmad-0.15.1b-fixes-1.patch"
     wget -nc "https://downloads.sourceforge.net/mad/libmad-0.15.1b.tar.gz"
+    # libmad needs patching: https://stackoverflow.com/questions/14015747/gccs-fforce-mem-option
+    wget -nc "http://www.linuxfromscratch.org/patches/blfs/svn/libmad-0.15.1b-fixes-1.patch" -O "$DIST_FOLDER/libmad-0.15.1b-fixes-1.patch" || true
     rm -rf "$LIBS_FOLDER/libmad-0.15.1b/"
     tar -xf libmad-0.15.1b.tar.gz
     cd "$LIBS_FOLDER/libmad-0.15.1b/"
-    patch -Np1 -i ../libmad-0.15.1b-fixes-1.patch &&
-      emconfigure ./configure --host=wasm32-unknown-none --build=wasm32-unknown-none --prefix="$LIBS_FOLDER/build/" --with-pic --enable-fpm=no
+    patch -Np1 -i "$DIST_FOLDER/libmad-0.15.1b-fixes-1.patch"
+    emconfigure ./configure --host=wasm32-unknown-none --build=wasm32-unknown-none --prefix="$LIBS_FOLDER/build/" --with-pic --enable-fpm=no
     emmake make
     emmake make install
   fi
diff --git a/dists/emscripten/emscripten-15893-fix.patch b/dists/emscripten/emscripten-15893-fix.patch
deleted file mode 100644
index 85c65c3a86f..00000000000
--- a/dists/emscripten/emscripten-15893-fix.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 2ea11b4734de5656aaf3285145831e2bb9ad53ae Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Christian=20Ku=CC=88ndig?= <kuendig at scandit.com>
-Date: Sun, 24 Apr 2022 18:55:51 +0200
-Subject: [PATCH] Keeping a reference to the original function in
- instrumentWasmExports and using that in _dlsym_js to pass the right method to
- addFunction.
-
----
- src/library_async.js  | 3 +++
- src/library_dylink.js | 4 ++--
- 2 files changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/src/library_async.js b/src/library_async.js
-index 14511ba05..32ce7abd3 100644
---- a/src/library_async.js
-+++ b/src/library_async.js
-@@ -130,6 +130,9 @@ mergeInto(LibraryManager.library, {
-                 }
-               }
-             };
-+#if MAIN_MODULE
-+            ret[x].orig = original;
-+#endif
-           } else {
-             ret[x] = original;
-           }
-diff --git a/src/library_dylink.js b/src/library_dylink.js
-index 291c50ef2..3c70cfca7 100644
---- a/src/library_dylink.js
-+++ b/src/library_dylink.js
-@@ -964,8 +967,8 @@ var LibraryDylink = {
- #endif
- 
- #if ASYNCIFY
--      if(symbol in GOT && GOT[symbol].value != 0) {
--        return GOT[symbol].value 
-+      if ('orig' in result) {
-+        result = result.orig;
-       }
- #endif
-       // Insert the function into the wasm table.  If its a direct wasm function
--- 
-2.31.0
-
diff --git a/dists/emscripten/emscripten-15893.patch b/dists/emscripten/emscripten-15893.patch
index e8bcbd303db..dc48d9f7c04 100644
--- a/dists/emscripten/emscripten-15893.patch
+++ b/dists/emscripten/emscripten-15893.patch
@@ -1,7 +1,7 @@
-From 33d2935283bdf734dff5f5a2560571480f47b6b7 Mon Sep 17 00:00:00 2001
+From df4dbbb38ae315ee2e77f5efd38e36c201e9ccde Mon Sep 17 00:00:00 2001
 From: kamenokonokotan <kamenokonokotan at gmail.com>
 Date: Thu, 6 Jan 2022 14:55:48 +0900
-Subject: [PATCH 01/10] import mutable globals used in Asyncify pass
+Subject: [PATCH 01/12] import mutable globals used in Asyncify pass
 
 ---
  emcc.py        | 9 +++++++++
@@ -10,7 +10,7 @@ Subject: [PATCH 01/10] import mutable globals used in Asyncify pass
  3 files changed, 16 insertions(+)
 
 diff --git a/emcc.py b/emcc.py
-index 34df446434c..e5a425d1f31 100755
+index 6b8791473366..daaf3b9e47ce 100755
 --- a/emcc.py
 +++ b/emcc.py
 @@ -554,6 +554,8 @@ def get_binaryen_passes():
@@ -37,7 +37,7 @@ index 34df446434c..e5a425d1f31 100755
      settings.REQUIRED_EXPORTS += ['setThrew']
  
 diff --git a/emscripten.py b/emscripten.py
-index cd0c27dc2f3..b7d1bff3994 100644
+index cd0c27dc2f3d..b7d1bff39949 100644
 --- a/emscripten.py
 +++ b/emscripten.py
 @@ -344,6 +344,7 @@ def emscript(in_wasm, out_wasm, outfile_js, memfile):
@@ -49,10 +49,10 @@ index cd0c27dc2f3..b7d1bff3994 100644
    report_missing_symbols(forwarded_json['libraryFunctions'])
  
 diff --git a/src/library.js b/src/library.js
-index 401e17d086a..2c4d375d52e 100644
+index ffe87297b599..684f412f5a24 100644
 --- a/src/library.js
 +++ b/src/library.js
-@@ -3521,6 +3521,12 @@ LibraryManager.library = {
+@@ -3527,6 +3527,12 @@ LibraryManager.library = {
    __c_longjmp: "new WebAssembly.Tag({'parameters': ['{{{ POINTER_TYPE }}}']})",
    __c_longjmp_import: true,
  #endif
@@ -66,17 +66,17 @@ index 401e17d086a..2c4d375d52e 100644
  };
  
 
-From 065cb3c3aef101b8b8e249e32a44843830e5fa73 Mon Sep 17 00:00:00 2001
+From 079ba7cd0fada458e141d556e2e3ae745999f688 Mon Sep 17 00:00:00 2001
 From: nokotan <kamenokonokotan at gmail.com>
 Date: Sun, 23 Jan 2022 21:54:03 +0900
-Subject: [PATCH 02/10] move globals metadata modification
+Subject: [PATCH 02/12] move globals metadata modification
 
 ---
  emscripten.py | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)
 
 diff --git a/emscripten.py b/emscripten.py
-index b7d1bff3994..810eeb93dda 100644
+index b7d1bff39949..810eeb93dda6 100644
 --- a/emscripten.py
 +++ b/emscripten.py
 @@ -324,6 +324,9 @@ def emscript(in_wasm, out_wasm, outfile_js, memfile):
@@ -98,17 +98,17 @@ index b7d1bff3994..810eeb93dda 100644
    report_missing_symbols(forwarded_json['libraryFunctions'])
  
 
-From fc1edebd9df7e1c84e0fd7d700dd80dbf5a6e83b Mon Sep 17 00:00:00 2001
+From 6344d619dfba2edfb3ff0be7de5c578e58ebe33c Mon Sep 17 00:00:00 2001
 From: kamenokonokotan <kamenokonokotan at gmail.com>
 Date: Tue, 25 Jan 2022 22:00:21 +0900
-Subject: [PATCH 03/10] Remove redundant spaces
+Subject: [PATCH 03/12] Remove redundant spaces
 
 ---
  emcc.py | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/emcc.py b/emcc.py
-index e5a425d1f31..2c51a6d4264 100755
+index daaf3b9e47ce..b4af26e3eb1b 100755
 --- a/emcc.py
 +++ b/emcc.py
 @@ -1862,7 +1862,7 @@ def phase_linker_setup(options, state, newargs, user_settings):
@@ -121,20 +121,20 @@ index e5a425d1f31..2c51a6d4264 100755
      settings.REQUIRED_EXPORTS += ['setThrew']
  
 
-From 163609c529d31d9c6a07866ffb6f0d6a2901d8c9 Mon Sep 17 00:00:00 2001
+From 090cffcc082ed2c66604eeb783914601499dc598 Mon Sep 17 00:00:00 2001
 From: kamenokonokotan <kamenokonokotan at gmail.com>
 Date: Tue, 25 Jan 2022 22:10:36 +0900
-Subject: [PATCH 04/10] Add test_asyncify_side_module
+Subject: [PATCH 04/12] Add test_asyncify_side_module
 
 ---
  tests/test_core.py | 28 ++++++++++++++++++++++++++++
  1 file changed, 28 insertions(+)
 
 diff --git a/tests/test_core.py b/tests/test_core.py
-index 6eeee235e5b..e004def18e6 100644
+index 0941edabc466..082a95347e44 100644
 --- a/tests/test_core.py
 +++ b/tests/test_core.py
-@@ -7903,6 +7903,34 @@ def test_asyncify_indirect_lists(self, args, should_pass):
+@@ -7918,6 +7918,34 @@ def test_asyncify_indirect_lists(self, args, should_pass):
        if should_pass:
          raise
  
@@ -170,20 +170,20 @@ index 6eeee235e5b..e004def18e6 100644
    @no_memory64('TODO: asyncify for wasm64')
    def test_emscripten_scan_registers(self):
 
-From 8066f18bf46c2d694bba624e00cb6f38c11499a5 Mon Sep 17 00:00:00 2001
+From c590e6729c29e5a16ce8a451400c533ceb414580 Mon Sep 17 00:00:00 2001
 From: kamenokonokotan <kamenokonokotan at gmail.com>
 Date: Wed, 26 Jan 2022 01:29:14 +0900
-Subject: [PATCH 05/10] flake8, add EXIT_RUNTIME
+Subject: [PATCH 05/12] flake8, add EXIT_RUNTIME
 
 ---
  tests/test_core.py | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/tests/test_core.py b/tests/test_core.py
-index e004def18e6..b30806192ab 100644
+index 082a95347e44..692da917e7d4 100644
 --- a/tests/test_core.py
 +++ b/tests/test_core.py
-@@ -7907,13 +7907,14 @@ def test_asyncify_indirect_lists(self, args, should_pass):
+@@ -7922,13 +7922,14 @@ def test_asyncify_indirect_lists(self, args, should_pass):
    @no_memory64('TODO: asyncify for wasm64')
    def test_asyncify_side_module(self):
      self.set_setting('ASYNCIFY')
@@ -200,20 +200,20 @@ index e004def18e6..b30806192ab 100644
        }
      ''', r'''
 
-From 2f451abf5fa81f6bc08a9a671d7251f630c5ea67 Mon Sep 17 00:00:00 2001
+From 904a6d89123e635b9df39d37dd580024c1745624 Mon Sep 17 00:00:00 2001
 From: kamenokonokotan <kamenokonokotan at gmail.com>
 Date: Sun, 30 Jan 2022 02:39:01 +0900
-Subject: [PATCH 06/10] add instrumentWasmExports
+Subject: [PATCH 06/12] add instrumentWasmExports
 
 ---
  src/library_dylink.js | 3 +++
  1 file changed, 3 insertions(+)
 
 diff --git a/src/library_dylink.js b/src/library_dylink.js
-index e71ceb1b65b..8a0a3df9469 100644
+index 8ed167529122..9d1c69ec768a 100644
 --- a/src/library_dylink.js
 +++ b/src/library_dylink.js
-@@ -583,6 +583,9 @@ var LibraryDylink = {
+@@ -570,6 +570,9 @@ var LibraryDylink = {
          // add new entries to functionsInTableMap
          updateTableMap(tableBase, metadata.tableSize);
          moduleExports = relocateExports(instance.exports, memoryBase);
@@ -224,17 +224,17 @@ index e71ceb1b65b..8a0a3df9469 100644
            reportUndefinedSymbols();
          }
 
-From d09570de2e65ead70ab31f4a843ecde29512436c Mon Sep 17 00:00:00 2001
+From bd1f2e66ef762185daccaf57d4d8b18e710bfdaa Mon Sep 17 00:00:00 2001
 From: kamenokonokotan <kamenokonokotan at gmail.com>
 Date: Sun, 30 Jan 2022 02:39:56 +0900
-Subject: [PATCH 07/10] add searched symbols in getDataRewindFunc
+Subject: [PATCH 07/12] add searched symbols in getDataRewindFunc
 
 ---
  src/library_async.js | 5 +++++
  1 file changed, 5 insertions(+)
 
 diff --git a/src/library_async.js b/src/library_async.js
-index da09a1ae2d8..0ceb072dd37 100644
+index da09a1ae2d80..0ceb072dd372 100644
 --- a/src/library_async.js
 +++ b/src/library_async.js
 @@ -205,6 +205,11 @@ mergeInto(LibraryManager.library, {
@@ -250,20 +250,20 @@ index da09a1ae2d8..0ceb072dd37 100644
      },
  
 
-From 3a71ca6d2d93f1d933dc43b9aa34e56086a30534 Mon Sep 17 00:00:00 2001
+From 9b3e6adef7285c37e231612868ac7f2c0e4a5739 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Christian=20K=C3=BCndig?= <christian at kuendig.info>
 Date: Fri, 18 Feb 2022 18:15:53 +0100
-Subject: [PATCH 08/10] Fixing dlsym for emscripten-core/emscripten#15893
+Subject: [PATCH 08/12] Fixing dlsym for emscripten-core/emscripten#15893
 
 ---
  src/library_dylink.js | 6 ++++++
  1 file changed, 6 insertions(+)
 
 diff --git a/src/library_dylink.js b/src/library_dylink.js
-index 8a0a3df9469..9fca8adf488 100644
+index 9d1c69ec768a..e2ed388a1fcc 100644
 --- a/src/library_dylink.js
 +++ b/src/library_dylink.js
-@@ -965,6 +965,12 @@ var LibraryDylink = {
+@@ -962,6 +962,12 @@ var LibraryDylink = {
  #if DYLINK_DEBUG
        err('dlsym: ' + symbol + ' getting table slot for: ' + result);
  #endif
@@ -277,20 +277,20 @@ index 8a0a3df9469..9fca8adf488 100644
        // the second argument will not be needed.  If its a JS function we rely
        // on the `sig` attribute being set based on the `<func>__sig` specified
 
-From 7e451a8df7144c6293a57c8563538d409b904fe0 Mon Sep 17 00:00:00 2001
+From 203d3aabb5cc57761ba0fb94a62baa47a5c69da5 Mon Sep 17 00:00:00 2001
 From: kamenokonokotan <kamenokonokotan at gmail.com>
 Date: Sun, 6 Mar 2022 00:05:00 +0900
-Subject: [PATCH 09/10] Add test case test_asyncify_dlfcn
+Subject: [PATCH 09/12] Add test case test_asyncify_dlfcn
 
 ---
  tests/test_core.py | 33 +++++++++++++++++++++++++++++++++
  1 file changed, 33 insertions(+)
 
 diff --git a/tests/test_core.py b/tests/test_core.py
-index b30806192ab..0c978f39343 100644
+index 692da917e7d4..c4458819d471 100644
 --- a/tests/test_core.py
 +++ b/tests/test_core.py
-@@ -7932,6 +7932,39 @@ def test_asyncify_side_module(self):
+@@ -7947,6 +7947,39 @@ def test_asyncify_side_module(self):
        }
      ''', '42 42', header='void my_sleep(int);')
  
@@ -331,20 +331,20 @@ index b30806192ab..0c978f39343 100644
    @no_memory64('TODO: asyncify for wasm64')
    def test_emscripten_scan_registers(self):
 
-From 1b85abaab0186939a36207f2480cf836b096840f Mon Sep 17 00:00:00 2001
+From c609b8f230a1e8ec0d30803361c8aa058dd7e5b1 Mon Sep 17 00:00:00 2001
 From: kamenokonokotan <kamenokonokotan at gmail.com>
 Date: Wed, 6 Apr 2022 01:40:08 +0900
-Subject: [PATCH 10/10] Update test case
+Subject: [PATCH 10/12] Update test case
 
 ---
  tests/test_core.py | 10 +++++++---
  1 file changed, 7 insertions(+), 3 deletions(-)
 
 diff --git a/tests/test_core.py b/tests/test_core.py
-index 0c978f39343..7009c539f12 100644
+index c4458819d471..8b6f81bedd30 100644
 --- a/tests/test_core.py
 +++ b/tests/test_core.py
-@@ -7914,7 +7914,9 @@ def test_asyncify_side_module(self):
+@@ -7929,7 +7929,9 @@ def test_asyncify_side_module(self):
        #include "header.h"
  
        int main() {
@@ -354,7 +354,7 @@ index 0c978f39343..7009c539f12 100644
          return 0;
        }
      ''', r'''
-@@ -7925,12 +7927,12 @@ def test_asyncify_side_module(self):
+@@ -7940,12 +7942,12 @@ def test_asyncify_side_module(self):
        void my_sleep(int milli_seconds) {
          // put variable onto stack
          volatile int value = 42;
@@ -369,7 +369,7 @@ index 0c978f39343..7009c539f12 100644
  
    @needs_dylink
    @no_memory64('TODO: asyncify for wasm64')
-@@ -7959,11 +7961,13 @@ def test_asyncify_dlfcn(self):
+@@ -7974,11 +7976,13 @@ def test_asyncify_dlfcn(self):
        {
          int side_module_run()
          {
@@ -384,3 +384,108 @@ index 0c978f39343..7009c539f12 100644
  
    @no_asan('asyncify stack operations confuse asan')
    @no_memory64('TODO: asyncify for wasm64')
+
+From c7306d61a60957363d692df0d93db39eb33ed57c Mon Sep 17 00:00:00 2001
+From: nokotan <kamenokonokotan at gmail.com>
+Date: Wed, 13 Apr 2022 23:25:27 +0900
+Subject: [PATCH 11/12] updates
+
+---
+ src/library_async.js  | 3 +++
+ src/library_dylink.js | 4 ++--
+ tests/test_core.py    | 4 ++--
+ 3 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/src/library_async.js b/src/library_async.js
+index 0ceb072dd372..14511ba05f98 100644
+--- a/src/library_async.js
++++ b/src/library_async.js
+@@ -206,6 +206,9 @@ mergeInto(LibraryManager.library, {
+       var name = Asyncify.callStackIdToName[id];
+       var func = Module['asm'][name];
+ #if RELOCATABLE
++      // Exported functions in side modules are not listed in `Module["asm"]`,
++      // but are added as a form of `Module["(asmjs mangled name)"]`.
++      // So we should find a rewind function from `Module["asm"]` and `Module["(asmjs mangled name)"]`.
+       if (!func) {
+         func = Module[asmjsMangle(name)];
+       }
+diff --git a/src/library_dylink.js b/src/library_dylink.js
+index e2ed388a1fcc..9381d6e0dd19 100644
+--- a/src/library_dylink.js
++++ b/src/library_dylink.js
+@@ -964,8 +964,8 @@ var LibraryDylink = {
+ #endif
+ 
+ #if ASYNCIFY
+-      if(symbol in GOT && GOT[symbol].value != 0) {
+-        return GOT[symbol].value 
++      if (symbol in GOT && GOT[symbol].value != 0) {
++        return GOT[symbol].value;
+       }
+ #endif
+       // Insert the function into the wasm table.  If its a direct wasm function
+diff --git a/tests/test_core.py b/tests/test_core.py
+index 8b6f81bedd30..8946bc795842 100644
+--- a/tests/test_core.py
++++ b/tests/test_core.py
+@@ -7923,7 +7923,7 @@ def test_asyncify_indirect_lists(self, args, should_pass):
+   def test_asyncify_side_module(self):
+     self.set_setting('ASYNCIFY')
+     self.set_setting('EXIT_RUNTIME', 1)
+-    self.emcc_args += ['-sASYNCIFY_IMPORTS=["_Z8my_sleepi"]']
++    self.emcc_args += ['-sASYNCIFY_IMPORTS=["my_sleep"]']
+     self.dylink_test(r'''
+       #include <stdio.h>
+       #include "header.h"
+@@ -7947,7 +7947,7 @@ def test_asyncify_side_module(self):
+         // variable on stack in side module function should be restored.
+         printf("%d\n", value);
+       }
+-    ''', 'before sleep\n42\n42\nafter sleep\n', header='void my_sleep(int);')
++    ''', 'before sleep\n42\n42\nafter sleep\n', header='void my_sleep(int);', force_c=True)
+ 
+   @needs_dylink
+   @no_memory64('TODO: asyncify for wasm64')
+
+From 24ebc02cefaf901e865dab1b11f5caa8e835e9cd Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20Ku=CC=88ndig?= <kuendig at scandit.com>
+Date: Sun, 24 Apr 2022 18:55:51 +0200
+Subject: [PATCH 12/12] Keeping a reference to the original function in
+ instrumentWasmExports and using that in _dlsym_js to pass the right method to
+ addFunction.
+
+---
+ src/library_async.js  | 3 +++
+ src/library_dylink.js | 4 ++--
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/src/library_async.js b/src/library_async.js
+index 14511ba05f98..32ce7abd38bb 100644
+--- a/src/library_async.js
++++ b/src/library_async.js
+@@ -130,6 +130,9 @@ mergeInto(LibraryManager.library, {
+                 }
+               }
+             };
++#if MAIN_MODULE
++            ret[x].orig = original;
++#endif
+           } else {
+             ret[x] = original;
+           }
+diff --git a/src/library_dylink.js b/src/library_dylink.js
+index 9381d6e0dd19..a136d78a8bd0 100644
+--- a/src/library_dylink.js
++++ b/src/library_dylink.js
+@@ -964,8 +964,8 @@ var LibraryDylink = {
+ #endif
+ 
+ #if ASYNCIFY
+-      if (symbol in GOT && GOT[symbol].value != 0) {
+-        return GOT[symbol].value;
++      if ('orig' in result) {
++        result = result.orig;
+       }
+ #endif
+       // Insert the function into the wasm table.  If its a direct wasm function
diff --git a/dists/emscripten/libmad-0.15.1b-fixes-1.patch b/dists/emscripten/libmad-0.15.1b-fixes-1.patch
new file mode 100644
index 00000000000..aa408816d92
--- /dev/null
+++ b/dists/emscripten/libmad-0.15.1b-fixes-1.patch
@@ -0,0 +1,91 @@
+Submitted By:            Igor Živković <contact at igor hyphen zivkovic dot from dot hr>
+Date:                    2013-07-04
+Initial Package Version: 0.15.1b
+Upstream Status:         Reported
+Origin:                  Arch Linux packages repository
+Description:             Fixes compilation on x86-64 and optimization issues.
+
+diff -Naur libmad-0.15.1b.orig/configure.ac libmad-0.15.1b/configure.ac
+--- libmad-0.15.1b.orig/configure.ac	2004-01-23 10:41:32.000000000 +0100
++++ libmad-0.15.1b/configure.ac	2013-07-04 15:55:09.323764417 +0200
+@@ -124,71 +124,7 @@
+ 
+ if test "$GCC" = yes
+ then
+-    if test -z "$arch"
+-    then
+-	case "$host" in
+-	    i386-*)           ;;
+-	    i?86-*)           arch="-march=i486" ;;
+-	    arm*-empeg-*)     arch="-march=armv4 -mtune=strongarm1100" ;;
+-	    armv4*-*)         arch="-march=armv4 -mtune=strongarm" ;;
+-	    powerpc-*)        ;;
+-	    mips*-agenda-*)   arch="-mcpu=vr4100" ;;
+-	    mips*-luxsonor-*) arch="-mips1 -mcpu=r3000 -Wa,-m4010" ;;
+-	esac
+-    fi
+-
+-    case "$optimize" in
+-	-O|"-O "*)
+-	    optimize="-O"
+-	    optimize="$optimize -fforce-mem"
+-	    optimize="$optimize -fforce-addr"
+-	    : #x optimize="$optimize -finline-functions"
+-	    : #- optimize="$optimize -fstrength-reduce"
+-	    optimize="$optimize -fthread-jumps"
+-	    optimize="$optimize -fcse-follow-jumps"
+-	    optimize="$optimize -fcse-skip-blocks"
+-	    : #x optimize="$optimize -frerun-cse-after-loop"
+-	    : #x optimize="$optimize -frerun-loop-opt"
+-	    : #x optimize="$optimize -fgcse"
+-	    optimize="$optimize -fexpensive-optimizations"
+-	    optimize="$optimize -fregmove"
+-	    : #* optimize="$optimize -fdelayed-branch"
+-	    : #x optimize="$optimize -fschedule-insns"
+-	    optimize="$optimize -fschedule-insns2"
+-	    : #? optimize="$optimize -ffunction-sections"
+-	    : #? optimize="$optimize -fcaller-saves"
+-	    : #> optimize="$optimize -funroll-loops"
+-	    : #> optimize="$optimize -funroll-all-loops"
+-	    : #x optimize="$optimize -fmove-all-movables"
+-	    : #x optimize="$optimize -freduce-all-givs"
+-	    : #? optimize="$optimize -fstrict-aliasing"
+-	    : #* optimize="$optimize -fstructure-noalias"
+-
+-	    case "$host" in
+-		arm*-*)
+-		    optimize="$optimize -fstrength-reduce"
+-		    ;;
+-		mips*-*)
+-		    optimize="$optimize -fstrength-reduce"
+-		    optimize="$optimize -finline-functions"
+-		    ;;
+-		i?86-*)
+-		    optimize="$optimize -fstrength-reduce"
+-		    ;;
+-		powerpc-apple-*)
+-		    # this triggers an internal compiler error with gcc2
+-		    : #optimize="$optimize -fstrength-reduce"
+-
+-		    # this is really only beneficial with gcc3
+-		    : #optimize="$optimize -finline-functions"
+-		    ;;
+-		*)
+-		    # this sometimes provokes bugs in gcc 2.95.2
+-		    : #optimize="$optimize -fstrength-reduce"
+-		    ;;
+-	    esac
+-	    ;;
+-    esac
++    optimize="-O2"
+ fi
+ 
+ case "$host" in
+@@ -297,6 +233,7 @@
+ then
+     case "$host" in
+ 	i?86-*)     FPM="INTEL"  ;;
++	x86_64*)    FPM="64BIT"  ;;
+ 	arm*-*)     FPM="ARM"    ;;
+ 	mips*-*)    FPM="MIPS"   ;;
+ 	sparc*-*)   FPM="SPARC"  ;;


Commit: add7b76f31bad7a85f4c444b0ebc744f422ee1e2
    https://github.com/scummvm/scummvm/commit/add7b76f31bad7a85f4c444b0ebc744f422ee1e2
Author: Christian Kündig (christian at kuendig.info)
Date: 2022-06-12T14:42:08+02:00

Commit Message:
EMSCRIPTEN: Remove patches from this repo

Changed paths:
  R dists/emscripten/emscripten-15893.patch
  R dists/emscripten/emscripten-16559.patch
  R dists/emscripten/emscripten-16687.patch
  R dists/emscripten/libmad-0.15.1b-fixes-1.patch
    dists/emscripten/build.sh


diff --git a/dists/emscripten/build.sh b/dists/emscripten/build.sh
index b791d02680c..e91c0796ab7 100755
--- a/dists/emscripten/build.sh
+++ b/dists/emscripten/build.sh
@@ -102,19 +102,18 @@ if [[ "setup" =~ $(echo ^\(${TASKS}\)$) || "build" =~ $(echo ^\(${TASKS}\)$) ]];
     fi
     cd "$DIST_FOLDER/emsdk-${EMSDK_VERSION}"
     ./emsdk install ${EMSCRIPTEN_VERSION}
-    # We currently require a few patches for unreleased changes in SDL2 and Emscripten
+    # We currently require a few patches for unreleased changes Emscripten, see https://github.com/chkuendig/scummvm-demo/tree/main/patches
     if [[ "$EMSCRIPTEN_VERSION" == "3.1.8" ]]; then
       echo "Patching Emscripten"
       cd upstream/emscripten
       # until https://github.com/emscripten-core/emscripten/pull/15893 gets merged and released, we need to manually patch it
-      # as the upstream PR has been rebased against an incompatible main,  we'll actually use https://github.com/chkuendig/emscripten/pull/2
-      wget -nc https://github.com/chkuendig/emscripten/pull/2.patch  -O "$DIST_FOLDER/emscripten-15893.patch" || true 
+      wget -nc https://raw.githubusercontent.com/chkuendig/scummvm-demo/main/patches/emscripten-15893.patch  -O "$DIST_FOLDER/emscripten-15893.patch" || true 
       patch -p1 --verbose <"$DIST_FOLDER/emscripten-15893.patch"
       # until https://github.com/emscripten-core/emscripten/pull/16559 gets merged and released, we need to manually patch it
-      wget -nc https://github.com/emscripten-core/emscripten/pull/16559.patch  -O "$DIST_FOLDER/emscripten-16559.patch" || true 
+      wget -nc https://raw.githubusercontent.com/chkuendig/scummvm-demo/main/patches/emscripten-16559.patch  -O "$DIST_FOLDER/emscripten-16559.patch" || true 
       patch -p1 --verbose <"$DIST_FOLDER/emscripten-16559.patch"
       # until https://github.com/emscripten-core/emscripten/pull/16687 gets merged and released, we need to manually patch it
-      wget -nc https://github.com/emscripten-core/emscripten/pull/16559.patch  -O "$DIST_FOLDER/emscripten-16559.patch" || true 
+      wget -nc https://raw.githubusercontent.com/chkuendig/scummvm-demo/main/patches/emscripten-16687.patch  -O "$DIST_FOLDER/emscripten-16687.patch" || true 
       patch -p1 --verbose <"$DIST_FOLDER/emscripten-16687.patch"
     fi
 
@@ -205,7 +204,7 @@ if [[ "libs" =~ $(echo ^\(${TASKS}\)$) || "build" =~ $(echo ^\(${TASKS}\)$) ]];
     cd "$LIBS_FOLDER"
     wget -nc "https://downloads.sourceforge.net/mad/libmad-0.15.1b.tar.gz"
     # libmad needs patching: https://stackoverflow.com/questions/14015747/gccs-fforce-mem-option
-    wget -nc "http://www.linuxfromscratch.org/patches/blfs/svn/libmad-0.15.1b-fixes-1.patch" -O "$DIST_FOLDER/libmad-0.15.1b-fixes-1.patch" || true
+    wget -nc "https://raw.githubusercontent.com/chkuendig/scummvm-demo/main/patches/libmad-0.15.1b-fixes-1.patch" -O "$DIST_FOLDER/libmad-0.15.1b-fixes-1.patch" || true
     rm -rf "$LIBS_FOLDER/libmad-0.15.1b/"
     tar -xf libmad-0.15.1b.tar.gz
     cd "$LIBS_FOLDER/libmad-0.15.1b/"
diff --git a/dists/emscripten/emscripten-15893.patch b/dists/emscripten/emscripten-15893.patch
deleted file mode 100644
index dc48d9f7c04..00000000000
--- a/dists/emscripten/emscripten-15893.patch
+++ /dev/null
@@ -1,491 +0,0 @@
-From df4dbbb38ae315ee2e77f5efd38e36c201e9ccde Mon Sep 17 00:00:00 2001
-From: kamenokonokotan <kamenokonokotan at gmail.com>
-Date: Thu, 6 Jan 2022 14:55:48 +0900
-Subject: [PATCH 01/12] import mutable globals used in Asyncify pass
-
----
- emcc.py        | 9 +++++++++
- emscripten.py  | 1 +
- src/library.js | 6 ++++++
- 3 files changed, 16 insertions(+)
-
-diff --git a/emcc.py b/emcc.py
-index 6b8791473366..daaf3b9e47ce 100755
---- a/emcc.py
-+++ b/emcc.py
-@@ -554,6 +554,8 @@ def get_binaryen_passes():
-     passes += ['--fpcast-emu']
-   if settings.ASYNCIFY:
-     passes += ['--asyncify']
-+    if settings.MAIN_MODULE or settings.SIDE_MODULE:
-+      passes += ['--pass-arg=asyncify-side-module']
-     if settings.ASSERTIONS:
-       passes += ['--pass-arg=asyncify-asserts']
-     if settings.ASYNCIFY_ADVISE:
-@@ -1854,6 +1856,13 @@ def phase_linker_setup(options, state, newargs, user_settings):
-         '__heap_base',
-         '__stack_pointer',
-     ]
-+
-+    if settings.ASYNCIFY:
-+      settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += [
-+        '__asyncify_state',
-+        '__asyncify_data'
-+      ]
-+    
-     # Unconditional dependency in library_dylink.js
-     settings.REQUIRED_EXPORTS += ['setThrew']
- 
-diff --git a/emscripten.py b/emscripten.py
-index cd0c27dc2f3d..b7d1bff39949 100644
---- a/emscripten.py
-+++ b/emscripten.py
-@@ -344,6 +344,7 @@ def emscript(in_wasm, out_wasm, outfile_js, memfile):
- 
-   if settings.ASYNCIFY:
-     exports += ['asyncify_start_unwind', 'asyncify_stop_unwind', 'asyncify_start_rewind', 'asyncify_stop_rewind']
-+    metadata['globalImports'] += ['__asyncify_state', '__asyncify_data']
- 
-   report_missing_symbols(forwarded_json['libraryFunctions'])
- 
-diff --git a/src/library.js b/src/library.js
-index ffe87297b599..684f412f5a24 100644
---- a/src/library.js
-+++ b/src/library.js
-@@ -3527,6 +3527,12 @@ LibraryManager.library = {
-   __c_longjmp: "new WebAssembly.Tag({'parameters': ['{{{ POINTER_TYPE }}}']})",
-   __c_longjmp_import: true,
- #endif
-+#if ASYNCIFY
-+  __asyncify_state: "new WebAssembly.Global({'value': 'i32', 'mutable': true}, 0)",
-+  __asyncify_state__import: true,
-+  __asyncify_data: "new WebAssembly.Global({'value': 'i32', 'mutable': true}, 0)",
-+  __asyncify_data__import: true,
-+#endif
- #endif
- };
- 
-
-From 079ba7cd0fada458e141d556e2e3ae745999f688 Mon Sep 17 00:00:00 2001
-From: nokotan <kamenokonokotan at gmail.com>
-Date: Sun, 23 Jan 2022 21:54:03 +0900
-Subject: [PATCH 02/12] move globals metadata modification
-
----
- emscripten.py | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/emscripten.py b/emscripten.py
-index b7d1bff39949..810eeb93dda6 100644
---- a/emscripten.py
-+++ b/emscripten.py
-@@ -324,6 +324,9 @@ def emscript(in_wasm, out_wasm, outfile_js, memfile):
-     if settings.INITIAL_TABLE == -1:
-       settings.INITIAL_TABLE = dylink_sec.table_size + 1
- 
-+    if settings.ASYNCIFY:
-+      metadata['globalImports'] += ['__asyncify_state', '__asyncify_data']
-+
-   glue, forwarded_data = compile_settings()
-   if DEBUG:
-     logger.debug('  emscript: glue took %s seconds' % (time.time() - t))
-@@ -344,7 +347,6 @@ def emscript(in_wasm, out_wasm, outfile_js, memfile):
- 
-   if settings.ASYNCIFY:
-     exports += ['asyncify_start_unwind', 'asyncify_stop_unwind', 'asyncify_start_rewind', 'asyncify_stop_rewind']
--    metadata['globalImports'] += ['__asyncify_state', '__asyncify_data']
- 
-   report_missing_symbols(forwarded_json['libraryFunctions'])
- 
-
-From 6344d619dfba2edfb3ff0be7de5c578e58ebe33c Mon Sep 17 00:00:00 2001
-From: kamenokonokotan <kamenokonokotan at gmail.com>
-Date: Tue, 25 Jan 2022 22:00:21 +0900
-Subject: [PATCH 03/12] Remove redundant spaces
-
----
- emcc.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/emcc.py b/emcc.py
-index daaf3b9e47ce..b4af26e3eb1b 100755
---- a/emcc.py
-+++ b/emcc.py
-@@ -1862,7 +1862,7 @@ def phase_linker_setup(options, state, newargs, user_settings):
-         '__asyncify_state',
-         '__asyncify_data'
-       ]
--    
-+
-     # Unconditional dependency in library_dylink.js
-     settings.REQUIRED_EXPORTS += ['setThrew']
- 
-
-From 090cffcc082ed2c66604eeb783914601499dc598 Mon Sep 17 00:00:00 2001
-From: kamenokonokotan <kamenokonokotan at gmail.com>
-Date: Tue, 25 Jan 2022 22:10:36 +0900
-Subject: [PATCH 04/12] Add test_asyncify_side_module
-
----
- tests/test_core.py | 28 ++++++++++++++++++++++++++++
- 1 file changed, 28 insertions(+)
-
-diff --git a/tests/test_core.py b/tests/test_core.py
-index 0941edabc466..082a95347e44 100644
---- a/tests/test_core.py
-+++ b/tests/test_core.py
-@@ -7918,6 +7918,34 @@ def test_asyncify_indirect_lists(self, args, should_pass):
-       if should_pass:
-         raise
- 
-+  @needs_dylink
-+  @no_memory64('TODO: asyncify for wasm64')
-+  def test_asyncify_side_module(self):
-+    self.set_setting('ASYNCIFY')
-+    self.emcc_args += ['-sASYNCIFY_IMPORTS=["_Z8my_sleepi"]']
-+    self.dylink_test(r'''
-+      #include <stdio.h>
-+      #include "header.h"
-+
-+      int main() {
-+        my_sleep(1);     
-+        return 0;
-+      }
-+    ''', r'''
-+      #include <emscripten.h>
-+      #include <stdio.h>
-+      #include "header.h"
-+
-+      void my_sleep(int milli_seconds) {
-+        // put variable onto stack
-+        volatile int value = 42;
-+        printf("%d ", value);
-+        emscripten_sleep(milli_seconds);
-+        // variable on stack in side module function should be restored.
-+        printf("%d\n", value);
-+      }
-+    ''', '42 42', header='void my_sleep(int);')
-+
-   @no_asan('asyncify stack operations confuse asan')
-   @no_memory64('TODO: asyncify for wasm64')
-   def test_emscripten_scan_registers(self):
-
-From c590e6729c29e5a16ce8a451400c533ceb414580 Mon Sep 17 00:00:00 2001
-From: kamenokonokotan <kamenokonokotan at gmail.com>
-Date: Wed, 26 Jan 2022 01:29:14 +0900
-Subject: [PATCH 05/12] flake8, add EXIT_RUNTIME
-
----
- tests/test_core.py | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/tests/test_core.py b/tests/test_core.py
-index 082a95347e44..692da917e7d4 100644
---- a/tests/test_core.py
-+++ b/tests/test_core.py
-@@ -7922,13 +7922,14 @@ def test_asyncify_indirect_lists(self, args, should_pass):
-   @no_memory64('TODO: asyncify for wasm64')
-   def test_asyncify_side_module(self):
-     self.set_setting('ASYNCIFY')
-+    self.set_setting('EXIT_RUNTIME', 1)
-     self.emcc_args += ['-sASYNCIFY_IMPORTS=["_Z8my_sleepi"]']
-     self.dylink_test(r'''
-       #include <stdio.h>
-       #include "header.h"
- 
-       int main() {
--        my_sleep(1);     
-+        my_sleep(1);
-         return 0;
-       }
-     ''', r'''
-
-From 904a6d89123e635b9df39d37dd580024c1745624 Mon Sep 17 00:00:00 2001
-From: kamenokonokotan <kamenokonokotan at gmail.com>
-Date: Sun, 30 Jan 2022 02:39:01 +0900
-Subject: [PATCH 06/12] add instrumentWasmExports
-
----
- src/library_dylink.js | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/src/library_dylink.js b/src/library_dylink.js
-index 8ed167529122..9d1c69ec768a 100644
---- a/src/library_dylink.js
-+++ b/src/library_dylink.js
-@@ -570,6 +570,9 @@ var LibraryDylink = {
-         // add new entries to functionsInTableMap
-         updateTableMap(tableBase, metadata.tableSize);
-         moduleExports = relocateExports(instance.exports, memoryBase);
-+#if ASYNCIFY
-+        moduleExports = Asyncify.instrumentWasmExports(moduleExports);
-+#endif
-         if (!flags.allowUndefined) {
-           reportUndefinedSymbols();
-         }
-
-From bd1f2e66ef762185daccaf57d4d8b18e710bfdaa Mon Sep 17 00:00:00 2001
-From: kamenokonokotan <kamenokonokotan at gmail.com>
-Date: Sun, 30 Jan 2022 02:39:56 +0900
-Subject: [PATCH 07/12] add searched symbols in getDataRewindFunc
-
----
- src/library_async.js | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/src/library_async.js b/src/library_async.js
-index da09a1ae2d80..0ceb072dd372 100644
---- a/src/library_async.js
-+++ b/src/library_async.js
-@@ -205,6 +205,11 @@ mergeInto(LibraryManager.library, {
-       var id = {{{ makeGetValue('ptr', C_STRUCTS.asyncify_data_s.rewind_id, 'i32') }}};
-       var name = Asyncify.callStackIdToName[id];
-       var func = Module['asm'][name];
-+#if RELOCATABLE
-+      if (!func) {
-+        func = Module[asmjsMangle(name)];
-+      }
-+#endif
-       return func;
-     },
- 
-
-From 9b3e6adef7285c37e231612868ac7f2c0e4a5739 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Christian=20K=C3=BCndig?= <christian at kuendig.info>
-Date: Fri, 18 Feb 2022 18:15:53 +0100
-Subject: [PATCH 08/12] Fixing dlsym for emscripten-core/emscripten#15893
-
----
- src/library_dylink.js | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/src/library_dylink.js b/src/library_dylink.js
-index 9d1c69ec768a..e2ed388a1fcc 100644
---- a/src/library_dylink.js
-+++ b/src/library_dylink.js
-@@ -962,6 +962,12 @@ var LibraryDylink = {
- #if DYLINK_DEBUG
-       err('dlsym: ' + symbol + ' getting table slot for: ' + result);
- #endif
-+
-+#if ASYNCIFY
-+      if(symbol in GOT && GOT[symbol].value != 0) {
-+        return GOT[symbol].value 
-+      }
-+#endif
-       // Insert the function into the wasm table.  If its a direct wasm function
-       // the second argument will not be needed.  If its a JS function we rely
-       // on the `sig` attribute being set based on the `<func>__sig` specified
-
-From 203d3aabb5cc57761ba0fb94a62baa47a5c69da5 Mon Sep 17 00:00:00 2001
-From: kamenokonokotan <kamenokonokotan at gmail.com>
-Date: Sun, 6 Mar 2022 00:05:00 +0900
-Subject: [PATCH 09/12] Add test case test_asyncify_dlfcn
-
----
- tests/test_core.py | 33 +++++++++++++++++++++++++++++++++
- 1 file changed, 33 insertions(+)
-
-diff --git a/tests/test_core.py b/tests/test_core.py
-index 692da917e7d4..c4458819d471 100644
---- a/tests/test_core.py
-+++ b/tests/test_core.py
-@@ -7947,6 +7947,39 @@ def test_asyncify_side_module(self):
-       }
-     ''', '42 42', header='void my_sleep(int);')
- 
-+  @needs_dylink
-+  @no_memory64('TODO: asyncify for wasm64')
-+  def test_asyncify_dlfcn(self):
-+    self.set_setting('ASYNCIFY')
-+    self.set_setting('EXIT_RUNTIME', 1)
-+    self.emcc_args += ['-sASYNCIFY_IGNORE_INDIRECT=0']
-+    self.dylink_test(r'''
-+      #include <iostream>
-+      #include <dlfcn.h>
-+
-+      typedef int (*func_t)();
-+
-+      int main(int argc, char **argv)
-+      {
-+        void *_dlHandle = dlopen("liblib.so", RTLD_NOW | RTLD_LOCAL);
-+        func_t my_func = (func_t)dlsym(_dlHandle, "side_module_run");
-+        printf("%d\n", my_func());
-+        return 0;
-+      }
-+    ''', r'''
-+      #include <iostream>
-+      #include <emscripten/emscripten.h>
-+
-+      extern "C"
-+      {
-+        int side_module_run()
-+        {
-+          emscripten_sleep(1000);
-+          return 42;
-+        }
-+      }
-+    ''', '42', need_reverse=False)
-+
-   @no_asan('asyncify stack operations confuse asan')
-   @no_memory64('TODO: asyncify for wasm64')
-   def test_emscripten_scan_registers(self):
-
-From c609b8f230a1e8ec0d30803361c8aa058dd7e5b1 Mon Sep 17 00:00:00 2001
-From: kamenokonokotan <kamenokonokotan at gmail.com>
-Date: Wed, 6 Apr 2022 01:40:08 +0900
-Subject: [PATCH 10/12] Update test case
-
----
- tests/test_core.py | 10 +++++++---
- 1 file changed, 7 insertions(+), 3 deletions(-)
-
-diff --git a/tests/test_core.py b/tests/test_core.py
-index c4458819d471..8b6f81bedd30 100644
---- a/tests/test_core.py
-+++ b/tests/test_core.py
-@@ -7929,7 +7929,9 @@ def test_asyncify_side_module(self):
-       #include "header.h"
- 
-       int main() {
-+        printf("before sleep\n");
-         my_sleep(1);
-+        printf("after sleep\n");
-         return 0;
-       }
-     ''', r'''
-@@ -7940,12 +7942,12 @@ def test_asyncify_side_module(self):
-       void my_sleep(int milli_seconds) {
-         // put variable onto stack
-         volatile int value = 42;
--        printf("%d ", value);
-+        printf("%d\n", value);
-         emscripten_sleep(milli_seconds);
-         // variable on stack in side module function should be restored.
-         printf("%d\n", value);
-       }
--    ''', '42 42', header='void my_sleep(int);')
-+    ''', 'before sleep\n42\n42\nafter sleep\n', header='void my_sleep(int);')
- 
-   @needs_dylink
-   @no_memory64('TODO: asyncify for wasm64')
-@@ -7974,11 +7976,13 @@ def test_asyncify_dlfcn(self):
-       {
-         int side_module_run()
-         {
-+          printf("before sleep\n");
-           emscripten_sleep(1000);
-+          printf("after sleep\n");
-           return 42;
-         }
-       }
--    ''', '42', need_reverse=False)
-+    ''', 'before sleep\nafter sleep\n42', need_reverse=False)
- 
-   @no_asan('asyncify stack operations confuse asan')
-   @no_memory64('TODO: asyncify for wasm64')
-
-From c7306d61a60957363d692df0d93db39eb33ed57c Mon Sep 17 00:00:00 2001
-From: nokotan <kamenokonokotan at gmail.com>
-Date: Wed, 13 Apr 2022 23:25:27 +0900
-Subject: [PATCH 11/12] updates
-
----
- src/library_async.js  | 3 +++
- src/library_dylink.js | 4 ++--
- tests/test_core.py    | 4 ++--
- 3 files changed, 7 insertions(+), 4 deletions(-)
-
-diff --git a/src/library_async.js b/src/library_async.js
-index 0ceb072dd372..14511ba05f98 100644
---- a/src/library_async.js
-+++ b/src/library_async.js
-@@ -206,6 +206,9 @@ mergeInto(LibraryManager.library, {
-       var name = Asyncify.callStackIdToName[id];
-       var func = Module['asm'][name];
- #if RELOCATABLE
-+      // Exported functions in side modules are not listed in `Module["asm"]`,
-+      // but are added as a form of `Module["(asmjs mangled name)"]`.
-+      // So we should find a rewind function from `Module["asm"]` and `Module["(asmjs mangled name)"]`.
-       if (!func) {
-         func = Module[asmjsMangle(name)];
-       }
-diff --git a/src/library_dylink.js b/src/library_dylink.js
-index e2ed388a1fcc..9381d6e0dd19 100644
---- a/src/library_dylink.js
-+++ b/src/library_dylink.js
-@@ -964,8 +964,8 @@ var LibraryDylink = {
- #endif
- 
- #if ASYNCIFY
--      if(symbol in GOT && GOT[symbol].value != 0) {
--        return GOT[symbol].value 
-+      if (symbol in GOT && GOT[symbol].value != 0) {
-+        return GOT[symbol].value;
-       }
- #endif
-       // Insert the function into the wasm table.  If its a direct wasm function
-diff --git a/tests/test_core.py b/tests/test_core.py
-index 8b6f81bedd30..8946bc795842 100644
---- a/tests/test_core.py
-+++ b/tests/test_core.py
-@@ -7923,7 +7923,7 @@ def test_asyncify_indirect_lists(self, args, should_pass):
-   def test_asyncify_side_module(self):
-     self.set_setting('ASYNCIFY')
-     self.set_setting('EXIT_RUNTIME', 1)
--    self.emcc_args += ['-sASYNCIFY_IMPORTS=["_Z8my_sleepi"]']
-+    self.emcc_args += ['-sASYNCIFY_IMPORTS=["my_sleep"]']
-     self.dylink_test(r'''
-       #include <stdio.h>
-       #include "header.h"
-@@ -7947,7 +7947,7 @@ def test_asyncify_side_module(self):
-         // variable on stack in side module function should be restored.
-         printf("%d\n", value);
-       }
--    ''', 'before sleep\n42\n42\nafter sleep\n', header='void my_sleep(int);')
-+    ''', 'before sleep\n42\n42\nafter sleep\n', header='void my_sleep(int);', force_c=True)
- 
-   @needs_dylink
-   @no_memory64('TODO: asyncify for wasm64')
-
-From 24ebc02cefaf901e865dab1b11f5caa8e835e9cd Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Christian=20Ku=CC=88ndig?= <kuendig at scandit.com>
-Date: Sun, 24 Apr 2022 18:55:51 +0200
-Subject: [PATCH 12/12] Keeping a reference to the original function in
- instrumentWasmExports and using that in _dlsym_js to pass the right method to
- addFunction.
-
----
- src/library_async.js  | 3 +++
- src/library_dylink.js | 4 ++--
- 2 files changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/src/library_async.js b/src/library_async.js
-index 14511ba05f98..32ce7abd38bb 100644
---- a/src/library_async.js
-+++ b/src/library_async.js
-@@ -130,6 +130,9 @@ mergeInto(LibraryManager.library, {
-                 }
-               }
-             };
-+#if MAIN_MODULE
-+            ret[x].orig = original;
-+#endif
-           } else {
-             ret[x] = original;
-           }
-diff --git a/src/library_dylink.js b/src/library_dylink.js
-index 9381d6e0dd19..a136d78a8bd0 100644
---- a/src/library_dylink.js
-+++ b/src/library_dylink.js
-@@ -964,8 +964,8 @@ var LibraryDylink = {
- #endif
- 
- #if ASYNCIFY
--      if (symbol in GOT && GOT[symbol].value != 0) {
--        return GOT[symbol].value;
-+      if ('orig' in result) {
-+        result = result.orig;
-       }
- #endif
-       // Insert the function into the wasm table.  If its a direct wasm function
diff --git a/dists/emscripten/emscripten-16559.patch b/dists/emscripten/emscripten-16559.patch
deleted file mode 100644
index 122229220b6..00000000000
--- a/dists/emscripten/emscripten-16559.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 229c16de0b827321a0c3e55975e980017d234d43 Mon Sep 17 00:00:00 2001
-From: Charlie Birks <charlie at daft.games>
-Date: Tue, 22 Mar 2022 13:13:34 +0000
-Subject: [PATCH 1/2] Update SDL2 for #16462
-
----
- tools/ports/sdl2.py | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/tools/ports/sdl2.py b/tools/ports/sdl2.py
-index f499ca8fa15..7c0a30cbd71 100644
---- a/tools/ports/sdl2.py
-+++ b/tools/ports/sdl2.py
-@@ -5,8 +5,8 @@
- 
- import os
- 
--TAG = 'release-2.0.20'
--HASH = '67e1abe1183b04836b35d724fd495c83c9559b4530d4a5c9bcc89648af0ac7cc51c02f7055a1664fe5f5f90953d22a6c431fa8bc5cdd77c94a97f107c47e2d62'
-+TAG = '4b8d69a41687e5f6f4b05f7fd9804dd9fcac0347'
-+HASH = '2d4d577c7584da22306b05a44bc08200460a33cd414fed2dc948e2a86e7b2d1a5cbc13bacadb63618823ba63c210f21c570adbab39f7645bf902196fa91c6b4e'
- SUBDIR = 'SDL-' + TAG
- 
- 
-
-From 1eb16caf951bf0a38dda07d3335b4fdeb397ebc7 Mon Sep 17 00:00:00 2001
-From: Charlie Birks <charlie at daft.games>
-Date: Fri, 25 Mar 2022 11:24:00 +0000
-Subject: [PATCH 2/2] Add an extra move to the SDL2 mouse test
-
-The "first" event now has valid relative motion, so don't need that workaround either.
----
- tests/sdl2_mouse.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/tests/sdl2_mouse.c b/tests/sdl2_mouse.c
-index f7786cdb02d..6ec8871d427 100644
---- a/tests/sdl2_mouse.c
-+++ b/tests/sdl2_mouse.c
-@@ -26,11 +26,10 @@ void one() {
-         printf("motion : %d,%d  %d,%d\n", m->x, m->y, m->xrel, m->yrel);
- 
-         if (mouse_motions == 0) {
--          // xrel/yrel will be zero for the first motion
- #ifdef TEST_SDL_MOUSE_OFFSETS
--          assert(eq(m->x, 5) && eq(m->y, 15) && eq(m->xrel, 0) && eq(m->yrel, 0));
-+          assert(eq(m->x, 5) && eq(m->y, 15) && eq(m->xrel, 5) && eq(m->yrel, 15));
- #else
--          assert(eq(m->x, 10) && eq(m->y, 20) && eq(m->xrel, 0) && eq(m->yrel, 0));
-+          assert(eq(m->x, 10) && eq(m->y, 20) && eq(m->xrel, 10) && eq(m->yrel, 20));
- #endif
-         } else if (mouse_motions == 1) {
- #ifdef TEST_SDL_MOUSE_OFFSETS
-@@ -93,6 +92,7 @@ int main() {
- }
- 
- void main_2(void* arg) {
-+  emscripten_run_script("window.simulateMouseEvent(0, 0, -1)");
-   emscripten_run_script("window.simulateMouseEvent(10, 20, -1)"); // move from 0,0 to 10,20
-   emscripten_run_script("window.simulateMouseEvent(10, 20, 0)"); // click
-   emscripten_run_script("window.simulateMouseEvent(10, 20, 0)"); // click some more, but this one should be ignored through PeepEvent
diff --git a/dists/emscripten/emscripten-16687.patch b/dists/emscripten/emscripten-16687.patch
deleted file mode 100644
index 94b86bd1254..00000000000
--- a/dists/emscripten/emscripten-16687.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From 5ed10829c6d806d630d98943432c222cf8f02017 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Christian=20K=C3=BCndig?= <christian at kuendig.info>
-Date: Sat, 9 Apr 2022 16:12:40 +0200
-Subject: [PATCH] SDL2: Fix SDL_OpenURL
-
----
- tools/ports/sdl2.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/tools/ports/sdl2.py b/tools/ports/sdl2.py
-index 7c0a30cbd71..fb6ea398bfd 100644
---- a/tools/ports/sdl2.py
-+++ b/tools/ports/sdl2.py
-@@ -58,7 +58,7 @@ def create(final):
-     power/emscripten/SDL_syspower.c joystick/emscripten/SDL_sysjoystick.c
-     filesystem/emscripten/SDL_sysfilesystem.c timer/unix/SDL_systimer.c haptic/dummy/SDL_syshaptic.c
-     main/dummy/SDL_dummy_main.c locale/SDL_locale.c locale/emscripten/SDL_syslocale.c misc/SDL_url.c
--    misc/dummy/SDL_sysurl.c'''.split()
-+    misc/emscripten/SDL_sysurl.c'''.split()
-     thread_srcs = ['SDL_syscond.c', 'SDL_sysmutex.c', 'SDL_syssem.c', 'SDL_systhread.c', 'SDL_systls.c']
-     thread_backend = 'generic' if not settings.USE_PTHREADS else 'pthread'
-     srcs += ['thread/%s/%s' % (thread_backend, s) for s in thread_srcs]
diff --git a/dists/emscripten/libmad-0.15.1b-fixes-1.patch b/dists/emscripten/libmad-0.15.1b-fixes-1.patch
deleted file mode 100644
index aa408816d92..00000000000
--- a/dists/emscripten/libmad-0.15.1b-fixes-1.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-Submitted By:            Igor Živković <contact at igor hyphen zivkovic dot from dot hr>
-Date:                    2013-07-04
-Initial Package Version: 0.15.1b
-Upstream Status:         Reported
-Origin:                  Arch Linux packages repository
-Description:             Fixes compilation on x86-64 and optimization issues.
-
-diff -Naur libmad-0.15.1b.orig/configure.ac libmad-0.15.1b/configure.ac
---- libmad-0.15.1b.orig/configure.ac	2004-01-23 10:41:32.000000000 +0100
-+++ libmad-0.15.1b/configure.ac	2013-07-04 15:55:09.323764417 +0200
-@@ -124,71 +124,7 @@
- 
- if test "$GCC" = yes
- then
--    if test -z "$arch"
--    then
--	case "$host" in
--	    i386-*)           ;;
--	    i?86-*)           arch="-march=i486" ;;
--	    arm*-empeg-*)     arch="-march=armv4 -mtune=strongarm1100" ;;
--	    armv4*-*)         arch="-march=armv4 -mtune=strongarm" ;;
--	    powerpc-*)        ;;
--	    mips*-agenda-*)   arch="-mcpu=vr4100" ;;
--	    mips*-luxsonor-*) arch="-mips1 -mcpu=r3000 -Wa,-m4010" ;;
--	esac
--    fi
--
--    case "$optimize" in
--	-O|"-O "*)
--	    optimize="-O"
--	    optimize="$optimize -fforce-mem"
--	    optimize="$optimize -fforce-addr"
--	    : #x optimize="$optimize -finline-functions"
--	    : #- optimize="$optimize -fstrength-reduce"
--	    optimize="$optimize -fthread-jumps"
--	    optimize="$optimize -fcse-follow-jumps"
--	    optimize="$optimize -fcse-skip-blocks"
--	    : #x optimize="$optimize -frerun-cse-after-loop"
--	    : #x optimize="$optimize -frerun-loop-opt"
--	    : #x optimize="$optimize -fgcse"
--	    optimize="$optimize -fexpensive-optimizations"
--	    optimize="$optimize -fregmove"
--	    : #* optimize="$optimize -fdelayed-branch"
--	    : #x optimize="$optimize -fschedule-insns"
--	    optimize="$optimize -fschedule-insns2"
--	    : #? optimize="$optimize -ffunction-sections"
--	    : #? optimize="$optimize -fcaller-saves"
--	    : #> optimize="$optimize -funroll-loops"
--	    : #> optimize="$optimize -funroll-all-loops"
--	    : #x optimize="$optimize -fmove-all-movables"
--	    : #x optimize="$optimize -freduce-all-givs"
--	    : #? optimize="$optimize -fstrict-aliasing"
--	    : #* optimize="$optimize -fstructure-noalias"
--
--	    case "$host" in
--		arm*-*)
--		    optimize="$optimize -fstrength-reduce"
--		    ;;
--		mips*-*)
--		    optimize="$optimize -fstrength-reduce"
--		    optimize="$optimize -finline-functions"
--		    ;;
--		i?86-*)
--		    optimize="$optimize -fstrength-reduce"
--		    ;;
--		powerpc-apple-*)
--		    # this triggers an internal compiler error with gcc2
--		    : #optimize="$optimize -fstrength-reduce"
--
--		    # this is really only beneficial with gcc3
--		    : #optimize="$optimize -finline-functions"
--		    ;;
--		*)
--		    # this sometimes provokes bugs in gcc 2.95.2
--		    : #optimize="$optimize -fstrength-reduce"
--		    ;;
--	    esac
--	    ;;
--    esac
-+    optimize="-O2"
- fi
- 
- case "$host" in
-@@ -297,6 +233,7 @@
- then
-     case "$host" in
- 	i?86-*)     FPM="INTEL"  ;;
-+	x86_64*)    FPM="64BIT"  ;;
- 	arm*-*)     FPM="ARM"    ;;
- 	mips*-*)    FPM="MIPS"   ;;
- 	sparc*-*)   FPM="SPARC"  ;;




More information about the Scummvm-git-logs mailing list