diff --git a/Makefile.libretro b/Makefile.libretro index 4e7c6f59..81dfef85 100755 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -41,7 +41,17 @@ else ifeq ($(platform), android) fpic := -fPIC SHARED := -Wl,--fix-cortex-a8 -llog -lz -shared -Wl,--version-script=$(LIBRETRO_DIR)/link.T -Wl,--no-undefined PLATFLAGS := -DAND -DLSB_FIRST -DALIGN_DWORD - +else ifeq ($(platform), emscripten) + pthread=0 + TARGET := $(TARGET_NAME)_libretro_$(platform).bc + EXTERNAL_ZLIB=1 + STATIC_LINKING=1 + STATIC_LINKING_LINK=1 + ifneq ($(pthread),0) + SHARED := -lpthread + CFLAGS += -pthread + endif + # Classic Platforms #################### # Platform affix = classic__<µARCH> # Help at https://modmyclassic.com/comp diff --git a/libretro/libretro-common/libco/emscripten_fiber.c b/libretro/libretro-common/libco/emscripten_fiber.c new file mode 100644 index 00000000..638656d4 --- /dev/null +++ b/libretro/libretro-common/libco/emscripten_fiber.c @@ -0,0 +1,64 @@ +/* + libco.emscripten (2020-02-27) + authors: Toad King + license: public domain +*/ + +#define LIBCO_C +#include +#include +#include +#include +#include + +#define ASYNCIFY_STACK_SIZE (12582912) + +static thread_local emscripten_fiber_t *co_active_; + +static void co_thunk(void *coentry) +{ + ((void (*)(void))coentry)(); +} + +static void co_init(void) +{ + if (!co_active_) + { + emscripten_fiber_t *co_primary = calloc(1, sizeof(emscripten_fiber_t)); + void *asyncify_stack = malloc(ASYNCIFY_STACK_SIZE); + + emscripten_fiber_init_from_current_context(co_primary, asyncify_stack, ASYNCIFY_STACK_SIZE); + co_active_ = co_primary; + } +} + +cothread_t co_active(void) +{ + co_init(); + return co_active_; +} + +cothread_t co_create(unsigned int stacksize, void (*coentry)(void)) +{ + co_init(); + + emscripten_fiber_t *fiber = calloc(1, sizeof(emscripten_fiber_t)); + void *asyncify_stack = malloc(ASYNCIFY_STACK_SIZE); + void *c_stack = memalign(16, stacksize); + emscripten_fiber_init(fiber, co_thunk, coentry, c_stack, stacksize, asyncify_stack, ASYNCIFY_STACK_SIZE); + + return (cothread_t)fiber; +} + +void co_delete(cothread_t cothread) +{ + free(cothread); +} + +void co_switch(cothread_t cothread) +{ + emscripten_fiber_t *old_fiber = co_active_; + co_active_ = (emscripten_fiber_t *)cothread; + + emscripten_fiber_swap(old_fiber, co_active_); +} diff --git a/libretro/libretro-common/libco/libco.c b/libretro/libretro-common/libco/libco.c index 36cd7da8..576b382e 100644 --- a/libretro/libretro-common/libco/libco.c +++ b/libretro/libretro-common/libco/libco.c @@ -9,7 +9,9 @@ void *genode_alloc_secondary_stack(unsigned long stack_size); void genode_free_secondary_stack(void *stack); #endif -#if defined _MSC_VER +#ifdef EMSCRIPTEN + #include "emscripten_fiber.c" +#elif defined _MSC_VER #include #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) #include "fiber.c"