Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- CLOUDSYNC: Enable WebDAV support for Android
- CLOUDSYNC: Speed up cloudsync on Apple
- DATABASE: Improve multidisk game scanning
- EMSCRIPTEN: Support core switching
- EMSCRIPTEN: Support suspend screensaver
- EMSCRIPTEN/RWEBCAM: Fix camera driver
- EMSCRIPTEN/RWEBINPUT: Add accelerometer/gyroscope support
Expand Down
2 changes: 1 addition & 1 deletion Makefile.emscripten
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ ifeq ($(HAVE_SDL2), 1)
endif

LDFLAGS := -L. --no-heap-copy -s STACK_SIZE=$(STACK_SIZE) -s INITIAL_MEMORY=$(INITIAL_HEAP) \
-s EXPORTED_RUNTIME_METHODS=$(EXPORTS) \
-s EXPORTED_RUNTIME_METHODS=$(EXPORTS) -s EXIT_RUNTIME=1 \
-s ALLOW_MEMORY_GROWTH=1 -s EXPORTED_FUNCTIONS="$(EXPORTED_FUNCTIONS)" \
-s MODULARIZE=1 -s EXPORT_ES6=1 -s EXPORT_NAME="libretro_$(subst -,_,$(LIBRETRO))" \
-s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=0 \
Expand Down
13 changes: 13 additions & 0 deletions audio/drivers/audioworklet.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,19 @@ bool audioworklet_external_block(void)
}
#endif

/* called on program exit */
void audioworklet_close(void)
{
audioworklet_data_t *audioworklet = audioworklet_static_data;

if (!audioworklet)
return;

MAIN_THREAD_EM_ASM({
emscriptenGetAudioObject($0).close();
}, audioworklet->context);
}

static bool audioworklet_stop(void *data)
{
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
Expand Down
9 changes: 9 additions & 0 deletions command.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#include "verbosity.h"
#include "version.h"
#include "version_git.h"
#include "tasks/task_content.h"

#define CMD_BUF_SIZE 4096

Expand Down Expand Up @@ -902,6 +903,14 @@ bool command_version(command_t *cmd, const char* arg)
return true;
}

bool command_load_core(command_t *cmd, const char* arg)
{
content_ctx_info_t content_info = {0};
task_push_load_new_core(arg, NULL,
&content_info, CORE_TYPE_PLAIN, NULL, NULL);
return true;
}

static const rarch_memory_descriptor_t* command_memory_get_descriptor(const rarch_memory_map_t* mmap, unsigned address, size_t* offset)
{
const rarch_memory_descriptor_t* desc = mmap->descriptors;
Expand Down
3 changes: 3 additions & 0 deletions command.h
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@ bool command_write_ram(command_t *cmd, const char *arg);
#endif
bool command_read_memory(command_t *cmd, const char *arg);
bool command_write_memory(command_t *cmd, const char *arg);
bool command_load_core(command_t *cmd, const char* arg);

static const struct cmd_action_map action_map[] = {
#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
Expand All @@ -452,6 +453,8 @@ static const struct cmd_action_map action_map[] = {

{ "SAVE_FILES", command_save_savefiles, "No argument"},
{ "LOAD_FILES", command_load_savefiles, "No argument"},

{ "LOAD_CORE", command_load_core, "<core path>"},
};

static const struct cmd_map map[] = {
Expand Down
122 changes: 94 additions & 28 deletions emscripten/library_platform_emscripten.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,21 @@ var LibraryPlatformEmscripten = {
$RPE: {
canvasWidth: 0,
canvasHeight: 0,
battery: null,
observer: null,
memoryUsageTimeout: null,
sentinelPromise: null,
command_queue: [],
command_reply_queue: []
},

PlatformEmscriptenWatchCanvasSizeAndDpr__deps: ["platform_emscripten_update_canvas_dimensions_cb"],
$PlatformEmscriptenOnWindowResize: function() {
RPE.observer.unobserve(Module.canvas);
RPE.observer.observe(Module.canvas);
},

PlatformEmscriptenWatchCanvasSizeAndDpr__deps: ["platform_emscripten_update_canvas_dimensions_cb", "$PlatformEmscriptenOnWindowResize"],
PlatformEmscriptenWatchCanvasSizeAndDpr__proxy: "sync",
PlatformEmscriptenWatchCanvasSizeAndDpr: function(dpr) {
if (RPE.observer) {
RPE.observer.unobserve(Module.canvas);
Expand All @@ -34,39 +43,57 @@ var LibraryPlatformEmscripten = {
_platform_emscripten_update_canvas_dimensions_cb(width, height, dpr);
});
RPE.observer.observe(Module.canvas);
window.addEventListener("resize", function() {
RPE.observer.unobserve(Module.canvas);
RPE.observer.observe(Module.canvas);
}, false);
window.addEventListener("resize", PlatformEmscriptenOnWindowResize, false);
},

$PlatformEmscriptenOnCanvasPointerDown: function() {
Module.canvas.focus();
},

PlatformEmscriptenWatchWindowVisibility__deps: ["platform_emscripten_update_window_hidden_cb"],
$PlatformEmscriptenOnCanvasContextMenu: function(e) {
e.preventDefault();
},

PlatformEmscriptenCanvasListenersInit__deps: ["$PlatformEmscriptenOnCanvasPointerDown", "$PlatformEmscriptenOnCanvasContextMenu"],
PlatformEmscriptenCanvasListenersInit__proxy: "sync",
PlatformEmscriptenCanvasListenersInit: function() {
Module.canvas.addEventListener("pointerdown", PlatformEmscriptenOnCanvasPointerDown, false);
Module.canvas.addEventListener("contextmenu", PlatformEmscriptenOnCanvasContextMenu, false);
},

$PlatformEmscriptenOnVisibilityChange__deps: ["platform_emscripten_update_window_hidden_cb"],
$PlatformEmscriptenOnVisibilityChange: function() {
_platform_emscripten_update_window_hidden_cb(document.visibilityState == "hidden");
},

PlatformEmscriptenWatchWindowVisibility__deps: ["$PlatformEmscriptenOnVisibilityChange"],
PlatformEmscriptenWatchWindowVisibility__proxy: "sync",
PlatformEmscriptenWatchWindowVisibility: function() {
document.addEventListener("visibilitychange", function() {
_platform_emscripten_update_window_hidden_cb(document.visibilityState == "hidden");
}, false);
document.addEventListener("visibilitychange", PlatformEmscriptenOnVisibilityChange, false);
},

$PlatformEmscriptenPowerStateChange__deps: ["platform_emscripten_update_power_state_cb"],
$PlatformEmscriptenPowerStateChange: function(e) {
$PlatformEmscriptenOnPowerStateChange__deps: ["platform_emscripten_update_power_state_cb"],
$PlatformEmscriptenOnPowerStateChange: function(e) {
_platform_emscripten_update_power_state_cb(true, Number.isFinite(e.target.dischargingTime) ? e.target.dischargingTime : 0x7FFFFFFF, e.target.level, e.target.charging);
},

PlatformEmscriptenPowerStateInit__deps: ["$PlatformEmscriptenPowerStateChange"],
PlatformEmscriptenPowerStateInit__deps: ["$PlatformEmscriptenOnPowerStateChange"],
PlatformEmscriptenPowerStateInit__proxy: "sync",
PlatformEmscriptenPowerStateInit: function() {
if (!navigator.getBattery) return;
navigator.getBattery().then(function(battery) {
battery.addEventListener("chargingchange", PlatformEmscriptenPowerStateChange);
battery.addEventListener("levelchange", PlatformEmscriptenPowerStateChange);
PlatformEmscriptenPowerStateChange({target: battery});
RPE.battery = battery;
battery.addEventListener("chargingchange", PlatformEmscriptenOnPowerStateChange);
battery.addEventListener("levelchange", PlatformEmscriptenOnPowerStateChange);
PlatformEmscriptenOnPowerStateChange({target: battery});
});
},

$PlatformEmscriptenUpdateMemoryUsage__deps: ["platform_emscripten_update_memory_usage_cb"],
$PlatformEmscriptenUpdateMemoryUsage: function() {
// unfortunately this will be inaccurate in threaded (worker) builds
_platform_emscripten_update_memory_usage_cb(BigInt(performance.memory.usedJSHeapSize || 0), BigInt(performance.memory.jsHeapSizeLimit || 0));
setTimeout(PlatformEmscriptenUpdateMemoryUsage, 5000);
RPE.memoryUsageTimeout = setTimeout(PlatformEmscriptenUpdateMemoryUsage, 5000);
},

PlatformEmscriptenMemoryUsageInit__deps: ["$PlatformEmscriptenUpdateMemoryUsage"],
Expand All @@ -75,22 +102,33 @@ var LibraryPlatformEmscripten = {
PlatformEmscriptenUpdateMemoryUsage();
},

PlatformEmscriptenWatchFullscreen__deps: ["platform_emscripten_update_fullscreen_state_cb"],
$PlatformEmscriptenOnFullscreenChange__deps: ["platform_emscripten_update_fullscreen_state_cb"],
$PlatformEmscriptenOnFullscreenChange: function() {
_platform_emscripten_update_fullscreen_state_cb(!!document.fullscreenElement);
},

PlatformEmscriptenWatchFullscreen__deps: ["$PlatformEmscriptenOnFullscreenChange"],
PlatformEmscriptenWatchFullscreen__proxy: "sync",
PlatformEmscriptenWatchFullscreen: function() {
document.addEventListener("fullscreenchange", function() {
_platform_emscripten_update_fullscreen_state_cb(!!document.fullscreenElement);
}, false);
document.addEventListener("fullscreenchange", PlatformEmscriptenOnFullscreenChange, false);
},

PlatformEmscriptenGLContextEventInit__deps: ["platform_emscripten_gl_context_lost_cb", "platform_emscripten_gl_context_restored_cb"],
$PlatformEmscriptenOnGLContextLost__deps: ["platform_emscripten_gl_context_lost_cb"],
$PlatformEmscriptenOnGLContextLost: function(e) {
e.preventDefault();
_platform_emscripten_gl_context_lost_cb();
},

$PlatformEmscriptenOnGLContextRestored__deps: ["platform_emscripten_gl_context_restored_cb"],
$PlatformEmscriptenOnGLContextRestored: function() {
_platform_emscripten_gl_context_restored_cb();
},

PlatformEmscriptenGLContextEventInit__deps: ["$PlatformEmscriptenOnGLContextLost", "$PlatformEmscriptenOnGLContextRestored"],
PlatformEmscriptenGLContextEventInit__proxy: "sync",
PlatformEmscriptenGLContextEventInit: function() {
Module.canvas.addEventListener("webglcontextlost", function(e) {
e.preventDefault();
_platform_emscripten_gl_context_lost_cb();
});
Module.canvas.addEventListener("webglcontextrestored", function() {
_platform_emscripten_gl_context_restored_cb();
});
Module.canvas.addEventListener("webglcontextlost", PlatformEmscriptenOnGLContextLost);
Module.canvas.addEventListener("webglcontextrestored", PlatformEmscriptenOnGLContextRestored);
},

$PlatformEmscriptenDoSetCanvasSize: async function(width, height) {
Expand Down Expand Up @@ -156,6 +194,34 @@ var LibraryPlatformEmscripten = {

$EmscriptenReceiveCommandReply: function() {
return RPE.command_reply_queue.shift();
},

$PlatformEmscriptenFreeBrowser__proxy: "sync",
$PlatformEmscriptenFreeBrowser__deps: ["$PlatformEmscriptenDoSetWakeLock", "$PlatformEmscriptenOnCanvasPointerDown", "$PlatformEmscriptenOnCanvasContextMenu", "$PlatformEmscriptenOnWindowResize", "$PlatformEmscriptenOnVisibilityChange", "$PlatformEmscriptenOnFullscreenChange", "$PlatformEmscriptenOnPowerStateChange"],
$PlatformEmscriptenFreeBrowser: function() {
if (RPE.memoryUsageTimeout) clearTimeout(RPE.memoryUsageTimeout);
PlatformEmscriptenDoSetWakeLock(false);
if (RPE.observer) {
RPE.observer.unobserve(Module.canvas);
RPE.observer = null;
}
Module.canvas.removeEventListener("pointerdown", PlatformEmscriptenOnCanvasPointerDown);
Module.canvas.removeEventListener("contextmenu", PlatformEmscriptenOnCanvasContextMenu);
window.removeEventListener("resize", PlatformEmscriptenOnWindowResize);
document.removeEventListener("visibilitychange", PlatformEmscriptenOnVisibilityChange);
document.removeEventListener("fullscreenchange", PlatformEmscriptenOnFullscreenChange);
if (RPE.battery) {
RPE.battery.removeEventListener("chargingchange", PlatformEmscriptenOnPowerStateChange);
RPE.battery.removeEventListener("levelchange", PlatformEmscriptenOnPowerStateChange);
RPE.battery = null;
}
},

PlatformEmscriptenFree__deps: ["$PlatformEmscriptenFreeBrowser"],
PlatformEmscriptenFree: function() {
Module.canvas.removeEventListener("webglcontextlost", PlatformEmscriptenOnGLContextLost);
Module.canvas.removeEventListener("webglcontextrestored", PlatformEmscriptenOnGLContextRestored);
PlatformEmscriptenFreeBrowser();
}
};

Expand Down
Loading
Loading