Skip to content

Commit

Permalink
(Emscripten) Modularize the JavaScript and clean up the web build (li…
Browse files Browse the repository at this point in the history
…bretro#15688)

* Increase emscripten stack size and decrease path size to fix emscripten builds broken since de45fc2

* use modularize flags for better-behaved javascript output

* makefile and loader changes

* use specialHTMLTargets to support modular access to canvas

* bind key events to canvas, not document

This way focus means focus and we can have multiple RA instances in
one page.

* Work around an emscripten bug in strict mode

* (Emscripten) Use console.error() for error messages

* increase asyncify stack size

* Fix `-lm` flag-related compile warnings in emscripten

---------

Co-authored-by: Rob Loach <robloach@gmail.com>
  • Loading branch information
JoeOsborn and RobLoach authored Nov 2, 2023
1 parent 8523eaf commit 862bebf
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 136 deletions.
25 changes: 18 additions & 7 deletions Makefile.emscripten
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ HAVE_STATIC_DUMMY ?= 0
ifeq ($(TARGET),)
ifeq ($(LIBRETRO),)
TARGET := retroarch.js
LIBRETRO = dummy
else
TARGET := $(LIBRETRO)_libretro.js
endif
Expand Down Expand Up @@ -48,7 +49,6 @@ HAVE_7ZIP = 1
HAVE_BSV_MOVIE = 1
HAVE_AL = 1


# WARNING -- READ BEFORE ENABLING
# The rwebaudio driver is known to have several audio bugs, such as
# minor crackling, or the entire page freezing/crashing.
Expand Down Expand Up @@ -78,8 +78,11 @@ OBJDIR := obj-emscripten
#if you compile with SDL2 flag add this Emscripten flag "-s USE_SDL=2" to LDFLAGS:

LIBS := -s USE_ZLIB=1
LDFLAGS := -L. --no-heap-copy -s $(LIBS) -s TOTAL_MEMORY=$(MEMORY) -s NO_EXIT_RUNTIME=0 -s FULL_ES2=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']" \
-s ALLOW_MEMORY_GROWTH=1 -s EXPORTED_FUNCTIONS="['_main', '_malloc', '_cmd_savefiles', '_cmd_save_state', '_cmd_load_state', '_cmd_take_screenshot']" \
LDFLAGS := -L. --no-heap-copy -s $(LIBS) -s TOTAL_MEMORY=$(MEMORY) -s NO_EXIT_RUNTIME=0 -s FULL_ES2=1 \
-s "EXPORTED_RUNTIME_METHODS=['callMain', 'FS', 'PATH', 'ERRNO_CODES']" \
-s ALLOW_MEMORY_GROWTH=1 -s "EXPORTED_FUNCTIONS=['_main', '_malloc', '_cmd_savefiles', '_cmd_save_state', '_cmd_load_state', '_cmd_take_screenshot']" \
-s MODULARIZE=1 -s EXPORT_ES6=1 -s EXPORT_NAME="$(LIBRETRO)" \
-s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 \
--js-library emscripten/library_errno_codes.js \
--js-library emscripten/library_rwebcam.js

Expand All @@ -102,7 +105,10 @@ else
endif

ifeq ($(ASYNC), 1)
LDFLAGS += -s ASYNCIFY=$(ASYNC)
LDFLAGS += -s ASYNCIFY=$(ASYNC) -s ASYNCIFY_STACK_SIZE=8192
ifeq ($(DEBUG), 1)
LDFLAGS += -s ASYNCIFY_DEBUG=1 # -s ASYNCIFY_ADVISE
endif
endif

ifeq ($(HAVE_SDL2), 1)
Expand All @@ -127,8 +133,8 @@ ifneq ($(V), 1)
endif

ifeq ($(DEBUG), 1)
LDFLAGS += -O0 -g
CFLAGS += -O0 -g
LDFLAGS += -O0 -g -gsource-map -s SAFE_HEAP=1 -s STACK_OVERFLOW_CHECK=2 -s ASSERTIONS=1
CFLAGS += -O0 -g -gsource-map -s SAFE_HEAP=1 -s SAFE_HEAP_LOG=1 -s STACK_OVERFLOW_CHECK=2 -s ASSERTIONS=1
else
LDFLAGS += -O3 -s WASM=1
# WARNING: some optimizations can break some cores (ex: LTO breaks tyrquake)
Expand All @@ -139,7 +145,12 @@ else
CFLAGS += -O3
endif

CFLAGS += -Wall -I. -Ilibretro-common/include -std=gnu99 $(LIBS) #\
# 128 * 1024, double the usual emscripten stack size
LDFLAGS += -s STACK_SIZE=131072

LDFLAGS += --extern-pre-js emscripten/pre.js

CFLAGS += -Wall -I. -Ilibretro-common/include -std=gnu99 #\
# -s EXPORTED_FUNCTIONS="['_main', '_malloc', '_cmd_savefiles', '_cmd_save_state', '_cmd_take_screenshot']"

RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
Expand Down
4 changes: 2 additions & 2 deletions dist-scripts/dist-cores.sh
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,8 @@ for f in `ls -v *_${platform}.${EXT}`; do
if [ $MAKEFILE_GRIFFIN = "yes" ]; then
make -C ../ -f Makefile.griffin $OPTS platform=${platform} $whole_archive $big_stack -j3 || exit 1
elif [ $PLATFORM = "emscripten" ]; then
echo "BUILD COMMAND: make -C ../ -f Makefile.emscripten PTHREAD=$pthread ASYNC=$async LTO=$lto -j7 TARGET=${name}_libretro.js"
make -C ../ -f Makefile.emscripten $OPTS PTHREAD=$pthread ASYNC=$async LTO=$lto -j7 TARGET=${name}_libretro.js || exit 1
echo "BUILD COMMAND: make -C ../ -f Makefile.emscripten PTHREAD=$pthread ASYNC=$async LTO=$lto -j7 LIBRETRO=${name} TARGET=${name}_libretro.js"
make -C ../ -f Makefile.emscripten $OPTS PTHREAD=$pthread ASYNC=$async LTO=$lto -j7 LIBRETRO=${name} TARGET=${name}_libretro.js || exit 1
elif [ $PLATFORM = "unix" ]; then
make -C ../ -f Makefile LINK=g++ $whole_archive $big_stack -j3 || exit 1
elif [ $PLATFORM = "ctr" ]; then
Expand Down
2 changes: 2 additions & 0 deletions emscripten/pre.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// To work around a bug in emscripten's polyfills for setImmediate in strict mode
var setImmediate;
8 changes: 6 additions & 2 deletions frontend/drivers/platform_emscripten.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,12 @@ int main(int argc, char *argv[])
{
dummyErrnoCodes();

emscripten_set_canvas_element_size("#canvas", 800, 600);
emscripten_set_element_css_size("#canvas", 800.0, 600.0);
EM_ASM({
specialHTMLTargets["!canvas"] = Module.canvas;
});

emscripten_set_canvas_element_size("!canvas", 800, 600);
emscripten_set_element_css_size("!canvas", 800.0, 600.0);
emscripten_set_main_loop(emscripten_mainloop, 0, 0);
rarch_main(argc, argv, NULL);

Expand Down
8 changes: 4 additions & 4 deletions gfx/drivers_context/emscriptenegl_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ static void gfx_ctx_emscripten_get_canvas_size(int *width, int *height)

if (!is_fullscreen)
{
r = emscripten_get_canvas_element_size("#canvas", width, height);
r = emscripten_get_canvas_element_size("!canvas", width, height);

if (r != EMSCRIPTEN_RESULT_SUCCESS)
{
Expand Down Expand Up @@ -105,14 +105,14 @@ static void gfx_ctx_emscripten_check_window(void *data, bool *quit,
if ( (input_width != emscripten->fb_width)
|| (input_height != emscripten->fb_height))
{
r = emscripten_set_canvas_element_size("#canvas",
r = emscripten_set_canvas_element_size("!canvas",
input_width, input_height);

if (r != EMSCRIPTEN_RESULT_SUCCESS)
RARCH_ERR("[EMSCRIPTEN/EGL]: error resizing canvas: %d\n", r);

/* fix Module.requestFullscreen messing with the canvas size */
r = emscripten_set_element_css_size("#canvas",
r = emscripten_set_element_css_size("!canvas",
(double)input_width, (double)input_height);

if (r != EMSCRIPTEN_RESULT_SUCCESS)
Expand Down Expand Up @@ -194,7 +194,7 @@ static void *gfx_ctx_emscripten_init(void *video_driver)
* be grabbed? */
if ( (emscripten->initial_width == 0)
|| (emscripten->initial_height == 0))
emscripten_get_canvas_element_size("#canvas",
emscripten_get_canvas_element_size("!canvas",
&emscripten->initial_width,
&emscripten->initial_height);

Expand Down
16 changes: 8 additions & 8 deletions input/drivers/rwebinput_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ static void *rwebinput_input_init(const char *joypad_driver)
rwebinput_generate_lut();

r = emscripten_set_keydown_callback(
EMSCRIPTEN_EVENT_TARGET_DOCUMENT, rwebinput, false,
"!canvas", rwebinput, false,
rwebinput_keyboard_cb);
if (r != EMSCRIPTEN_RESULT_SUCCESS)
{
Expand All @@ -300,7 +300,7 @@ static void *rwebinput_input_init(const char *joypad_driver)
}

r = emscripten_set_keyup_callback(
EMSCRIPTEN_EVENT_TARGET_DOCUMENT, rwebinput, false,
"!canvas", rwebinput, false,
rwebinput_keyboard_cb);
if (r != EMSCRIPTEN_RESULT_SUCCESS)
{
Expand All @@ -309,31 +309,31 @@ static void *rwebinput_input_init(const char *joypad_driver)
}

r = emscripten_set_keypress_callback(
EMSCRIPTEN_EVENT_TARGET_DOCUMENT, rwebinput, false,
"!canvas", rwebinput, false,
rwebinput_keyboard_cb);
if (r != EMSCRIPTEN_RESULT_SUCCESS)
{
RARCH_ERR(
"[EMSCRIPTEN/INPUT] failed to create keypress callback: %d\n", r);
}

r = emscripten_set_mousedown_callback("#canvas", rwebinput, false,
r = emscripten_set_mousedown_callback("!canvas", rwebinput, false,
rwebinput_mouse_cb);
if (r != EMSCRIPTEN_RESULT_SUCCESS)
{
RARCH_ERR(
"[EMSCRIPTEN/INPUT] failed to create mousedown callback: %d\n", r);
}

r = emscripten_set_mouseup_callback("#canvas", rwebinput, false,
r = emscripten_set_mouseup_callback("!canvas", rwebinput, false,
rwebinput_mouse_cb);
if (r != EMSCRIPTEN_RESULT_SUCCESS)
{
RARCH_ERR(
"[EMSCRIPTEN/INPUT] failed to create mouseup callback: %d\n", r);
}

r = emscripten_set_mousemove_callback("#canvas", rwebinput, false,
r = emscripten_set_mousemove_callback("!canvas", rwebinput, false,
rwebinput_mouse_cb);
if (r != EMSCRIPTEN_RESULT_SUCCESS)
{
Expand All @@ -342,7 +342,7 @@ static void *rwebinput_input_init(const char *joypad_driver)
}

r = emscripten_set_wheel_callback(
EMSCRIPTEN_EVENT_TARGET_DOCUMENT, rwebinput, false,
"!canvas", rwebinput, false,
rwebinput_wheel_cb);
if (r != EMSCRIPTEN_RESULT_SUCCESS)
{
Expand Down Expand Up @@ -651,7 +651,7 @@ static void rwebinput_input_poll(void *data)
static void rwebinput_grab_mouse(void *data, bool state)
{
if (state)
emscripten_request_pointerlock("#canvas", EM_TRUE);
emscripten_request_pointerlock("!canvas", EM_TRUE);
else
emscripten_exit_pointerlock();
}
Expand Down
2 changes: 1 addition & 1 deletion libretro-common/include/retro_miscellaneous.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ static INLINE bool bits_any_different(uint32_t *a, uint32_t *b, uint32_t count)
}

#ifndef PATH_MAX_LENGTH
#if defined(_XBOX1) || defined(_3DS) || defined(PSP) || defined(PS2) || defined(GEKKO)|| defined(WIIU) || defined(__PSL1GHT__) || defined(__PS3__)
#if defined(_XBOX1) || defined(_3DS) || defined(PSP) || defined(PS2) || defined(GEKKO)|| defined(WIIU) || defined(__PSL1GHT__) || defined(__PS3__) || defined(HAVE_EMSCRIPTEN)
#define PATH_MAX_LENGTH 512
#else
#define PATH_MAX_LENGTH 4096
Expand Down
Loading

0 comments on commit 862bebf

Please sign in to comment.