From 52876c4798cb8368451b6c94986e54cffd6dc536 Mon Sep 17 00:00:00 2001 From: Guillaume Brunerie Date: Sat, 30 Nov 2024 14:06:13 +0100 Subject: [PATCH] WASM fixes --- include/global.h | 3 + src/role.c | 2 +- sys/libnh/libnhmain.c | 174 ++++++++++++++++++++++++-- sys/unix/hints/include/cross-pre2.370 | 9 +- win/shim/winshim.c | 70 +++++------ 5 files changed, 203 insertions(+), 55 deletions(-) diff --git a/include/global.h b/include/global.h index d2651b3b8..7a32d105f 100644 --- a/include/global.h +++ b/include/global.h @@ -482,6 +482,9 @@ extern struct nomakedefs_s nomakedefs; #if !defined(CROSS_TO_WASM) /* no popen in WASM */ #define PANICTRACE_GDB #endif +#ifdef CROSS_TO_WASM +#undef COMPRESS +#endif #endif /* Supply nethack_enter macro if not supplied by port */ diff --git a/src/role.c b/src/role.c index 7055ff5b7..3fd57d887 100644 --- a/src/role.c +++ b/src/role.c @@ -2175,7 +2175,7 @@ genl_player_selection(void) /*NOTREACHED*/ } -#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS) +#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS) || defined(SHIM_GRAPHICS) /* ['#else' far below] */ staticfn boolean reset_role_filtering(void); diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index 81ae866cb..56ee3cb58 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -12,6 +12,7 @@ #include #include #include +#include #ifndef O_RDONLY #include #endif @@ -174,6 +175,12 @@ nhmain(int argc, char *argv[]) chdirx(dir, 1); #endif +#ifdef __EMSCRIPTEN__ + js_helpers_init(); + js_constants_init(); + js_globals_init(); +#endif + #ifdef _M_UNIX check_sco_console(); #endif @@ -201,11 +208,6 @@ nhmain(int argc, char *argv[]) process_options(argc, argv); /* command line options */ #ifdef WINCHAIN commit_windowchain(); -#endif -#ifdef __EMSCRIPTEN__ - js_helpers_init(); - js_constants_init(); - js_globals_init(); #endif init_nhwindows(&argc, argv); /* now we can set up window system */ #ifdef _M_UNIX @@ -781,9 +783,9 @@ EM_JS(void, js_helpers_init, (), { globalThis.nethackGlobal = globalThis.nethackGlobal || {}; globalThis.nethackGlobal.helpers = globalThis.nethackGlobal.helpers || {}; - installHelper(displayInventory); - installHelper(getPointerValue); - installHelper(setPointerValue); + installHelper(displayInventory, "displayInventory"); + installHelper(getPointerValue, "getPointerValue"); + installHelper(setPointerValue, "setPointerValue"); // used by update_inventory function displayInventory() { @@ -804,6 +806,8 @@ EM_JS(void, js_helpers_init, (), { return getValue(ptr, "*"); case "c": // char return String.fromCharCode(getValue(ptr, "i8")); + case "b": + return getValue(ptr, "i8") == 1; case "0": /* 2^0 = 1 byte */ return getValue(ptr, "i8"); case "1": /* 2^1 = 2 bytes */ @@ -816,8 +820,8 @@ EM_JS(void, js_helpers_init, (), { return getValue(ptr, "float"); case "d": // double return getValue(ptr, "double"); - case "o": // overloaded: multiple types - return ptr; + case "v": // void + return undefined; default: throw new TypeError ("unknown type:" + type); } @@ -828,7 +832,8 @@ EM_JS(void, js_helpers_init, (), { // console.log("setPointerValue", name, "0x" + ptr.toString(16), type, value); switch (type) { case "p": - throw new Error("not implemented"); + setValue(ptr, value, "*"); + break; case "s": if(typeof value !== "string") throw new TypeError(`expected ${name} return type to be string`); @@ -841,6 +846,11 @@ EM_JS(void, js_helpers_init, (), { throw new TypeError(`expected ${name} return type to be integer`); setValue(ptr, value, "i32"); break; + case "1": + if(typeof value !== "number" || !Number.isInteger(value)) + throw new TypeError(`expected ${name} return type to be integer`); + setValue(ptr, value, "i16"); + break; case "c": if(typeof value !== "number" || value < 0 || value > 128) throw new TypeError(`expected ${name} return type to be integer representing an ASCII character`); @@ -857,6 +867,10 @@ EM_JS(void, js_helpers_init, (), { throw new TypeError(`expected ${name} return type to be double`); setValue(ptr, value, "double"); break; + case "b": + if (typeof value !== "boolean") + throw new TypeError(`expected ${name} return type to be boolean`); + setValue(ptr, value ? 1 : 0, "i8"); case "v": break; default: @@ -896,11 +910,19 @@ EM_JS(void, set_const_str, (char *scope_str, char *name_str, char *input_str), { globalThis.nethackGlobal.constants[scope] = globalThis.nethackGlobal.constants[scope] || {}; globalThis.nethackGlobal.constants[scope][name] = str; }); +#define SET_POINTER(name) set_const_ptr(#name, (void *)&name); +EM_JS(void, set_const_ptr, (char *name_str, void* ptr), { + let name = UTF8ToString(name_str); + + globalThis.nethackGlobal.pointers = globalThis.nethackGlobal.pointers || {}; + globalThis.nethackGlobal.pointers[name] = ptr; +}); void js_constants_init() { EM_ASM({ globalThis.nethackGlobal = globalThis.nethackGlobal || {}; globalThis.nethackGlobal.constants = globalThis.nethackGlobal.constants || {}; + globalThis.nethackGlobal.pointers = globalThis.nethackGlobal.pointers || {}; }); // create_nhwindow @@ -989,8 +1011,7 @@ void js_constants_init() { // copyright SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_A); SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_B); - // XXX: not set for cross-compile - //SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_C); + set_const_str("COPYRIGHT", "COPYRIGHT_BANNER_C", (char*) COPYRIGHT_BANNER_C); SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_D); // glyphs @@ -1042,6 +1063,119 @@ void js_constants_init() { SET_CONSTANT("COLOR_ATTR", HL_ATTCLR_BLINK); SET_CONSTANT("COLOR_ATTR", HL_ATTCLR_INVERSE); SET_CONSTANT("COLOR_ATTR", BL_ATTCLR_MAX); + + SET_CONSTANT("BL_MASK", BL_MASK_BAREH); + SET_CONSTANT("BL_MASK", BL_MASK_BLIND); + SET_CONSTANT("BL_MASK", BL_MASK_BUSY); + SET_CONSTANT("BL_MASK", BL_MASK_CONF); + SET_CONSTANT("BL_MASK", BL_MASK_DEAF); + SET_CONSTANT("BL_MASK", BL_MASK_ELF_IRON); + SET_CONSTANT("BL_MASK", BL_MASK_FLY); + SET_CONSTANT("BL_MASK", BL_MASK_FOODPOIS); + SET_CONSTANT("BL_MASK", BL_MASK_GLOWHANDS); + SET_CONSTANT("BL_MASK", BL_MASK_GRAB); + SET_CONSTANT("BL_MASK", BL_MASK_HALLU); + SET_CONSTANT("BL_MASK", BL_MASK_HELD); + SET_CONSTANT("BL_MASK", BL_MASK_ICY); + SET_CONSTANT("BL_MASK", BL_MASK_INLAVA); + SET_CONSTANT("BL_MASK", BL_MASK_LEV); + SET_CONSTANT("BL_MASK", BL_MASK_PARLYZ); + SET_CONSTANT("BL_MASK", BL_MASK_RIDE); + SET_CONSTANT("BL_MASK", BL_MASK_SLEEPING); + SET_CONSTANT("BL_MASK", BL_MASK_SLIME); + SET_CONSTANT("BL_MASK", BL_MASK_SLIPPERY); + SET_CONSTANT("BL_MASK", BL_MASK_STONE); + SET_CONSTANT("BL_MASK", BL_MASK_STRNGL); + SET_CONSTANT("BL_MASK", BL_MASK_STUN); + SET_CONSTANT("BL_MASK", BL_MASK_SUBMERGED); + SET_CONSTANT("BL_MASK", BL_MASK_TERMILL); + SET_CONSTANT("BL_MASK", BL_MASK_TETHERED); + SET_CONSTANT("BL_MASK", BL_MASK_TRAPPED); + SET_CONSTANT("BL_MASK", BL_MASK_UNCONSC); + SET_CONSTANT("BL_MASK", BL_MASK_WOUNDEDL); + SET_CONSTANT("BL_MASK", BL_MASK_HOLDING); + + SET_CONSTANT("ROLE_RACEMASK", MH_HUMAN); + SET_CONSTANT("ROLE_RACEMASK", MH_ELF); + SET_CONSTANT("ROLE_RACEMASK", MH_DWARF); + SET_CONSTANT("ROLE_RACEMASK", MH_GNOME); + SET_CONSTANT("ROLE_RACEMASK", MH_ORC); + + SET_CONSTANT("ROLE_GENDMASK", ROLE_MALE); + SET_CONSTANT("ROLE_GENDMASK", ROLE_FEMALE); + SET_CONSTANT("ROLE_GENDMASK", ROLE_NEUTER); + + SET_CONSTANT("ROLE_ALIGNMASK", ROLE_LAWFUL); + SET_CONSTANT("ROLE_ALIGNMASK", ROLE_NEUTRAL); + SET_CONSTANT("ROLE_ALIGNMASK", ROLE_CHAOTIC); + + SET_CONSTANT("blconditions", bl_bareh); + SET_CONSTANT("blconditions", bl_blind); + SET_CONSTANT("blconditions", bl_busy); + SET_CONSTANT("blconditions", bl_conf); + SET_CONSTANT("blconditions", bl_deaf); + SET_CONSTANT("blconditions", bl_elf_iron); + SET_CONSTANT("blconditions", bl_fly); + SET_CONSTANT("blconditions", bl_foodpois); + SET_CONSTANT("blconditions", bl_glowhands); + SET_CONSTANT("blconditions", bl_grab); + SET_CONSTANT("blconditions", bl_hallu); + SET_CONSTANT("blconditions", bl_held); + SET_CONSTANT("blconditions", bl_icy); + SET_CONSTANT("blconditions", bl_inlava); + SET_CONSTANT("blconditions", bl_lev); + SET_CONSTANT("blconditions", bl_parlyz); + SET_CONSTANT("blconditions", bl_ride); + SET_CONSTANT("blconditions", bl_sleeping); + SET_CONSTANT("blconditions", bl_slime); + SET_CONSTANT("blconditions", bl_slippery); + SET_CONSTANT("blconditions", bl_stone); + SET_CONSTANT("blconditions", bl_strngl); + SET_CONSTANT("blconditions", bl_stun); + SET_CONSTANT("blconditions", bl_submerged); + SET_CONSTANT("blconditions", bl_termill); + SET_CONSTANT("blconditions", bl_tethered); + SET_CONSTANT("blconditions", bl_trapped); + SET_CONSTANT("blconditions", bl_unconsc); + SET_CONSTANT("blconditions", bl_woundedl); + SET_CONSTANT("blconditions", bl_holding); + SET_CONSTANT("blconditions", CONDITION_COUNT); + + SET_CONSTANT("HL", HL_UNDEF); + SET_CONSTANT("HL", HL_NONE); + SET_CONSTANT("HL", HL_BOLD); + SET_CONSTANT("HL", HL_DIM); + SET_CONSTANT("HL", HL_ITALIC); + SET_CONSTANT("HL", HL_ULINE); + SET_CONSTANT("HL", HL_BLINK); + SET_CONSTANT("HL", HL_INVERSE); + + SET_CONSTANT("MG", MG_HERO); + SET_CONSTANT("MG", MG_CORPSE); + SET_CONSTANT("MG", MG_INVIS); + SET_CONSTANT("MG", MG_DETECT); + SET_CONSTANT("MG", MG_PET); + SET_CONSTANT("MG", MG_RIDDEN); + SET_CONSTANT("MG", MG_STATUE); + SET_CONSTANT("MG", MG_OBJPILE); + SET_CONSTANT("MG", MG_BW_LAVA); + SET_CONSTANT("MG", MG_BW_ICE); + SET_CONSTANT("MG", MG_BW_SINK); + SET_CONSTANT("MG", MG_BW_ENGR); + SET_CONSTANT("MG", MG_NOTHING); + SET_CONSTANT("MG", MG_UNEXPL); + SET_CONSTANT("MG", MG_MALE); + SET_CONSTANT("MG", MG_FEMALE); + + SET_POINTER(extcmdlist); + SET_POINTER(conditions); + SET_POINTER(condtests); + + /* roles/races/genders/alignments */ + SET_POINTER(roles); + SET_POINTER(races); + SET_POINTER(genders); + SET_POINTER(aligns); } /*** @@ -1073,6 +1207,20 @@ void js_globals_init() { CREATE_GLOBAL(WIN_MESSAGE, "i"); CREATE_GLOBAL(WIN_INVEN, "i"); CREATE_GLOBAL(WIN_STATUS, "i"); + + /* instance flags */ + CREATE_GLOBAL(iflags.window_inited, "b"); + CREATE_GLOBAL(iflags.wc2_hitpointbar, "b"); + CREATE_GLOBAL(iflags.wc_hilite_pet, "b"); + CREATE_GLOBAL(iflags.hilite_pile, "b"); + + /* flags */ + CREATE_GLOBAL(flags.initrole, "i"); + CREATE_GLOBAL(flags.initrace, "i"); + CREATE_GLOBAL(flags.initgend, "i"); + CREATE_GLOBAL(flags.initalign, "i"); + CREATE_GLOBAL(flags.showexp, "b"); + CREATE_GLOBAL(flags.time, "b"); } EM_JS(void, create_global, (char *name_str, void *ptr, char *type_str), { diff --git a/sys/unix/hints/include/cross-pre2.370 b/sys/unix/hints/include/cross-pre2.370 index fa5f0911c..94fce7142 100644 --- a/sys/unix/hints/include/cross-pre2.370 +++ b/sys/unix/hints/include/cross-pre2.370 @@ -216,7 +216,7 @@ ifdef CROSS_TO_WASM # originally from https://github.com/NetHack/NetHack/pull/385 #===============-================================================= # -WASM_DEBUG = 1 +#WASM_DEBUG = 1 WASM_DATA_DIR = $(TARGETPFX)wasm-data WASM_TARGET = $(TARGETPFX)nethack.js EMCC_LFLAGS = @@ -227,10 +227,13 @@ EMCC_LFLAGS += -s ALLOW_TABLE_GROWTH EMCC_LFLAGS += -s ASYNCIFY -s ASYNCIFY_IMPORTS='["local_callback"]' EMCC_LFLAGS += -O3 EMCC_LFLAGS += -s MODULARIZE -EMCC_LFLAGS += -s EXPORTED_FUNCTIONS='["_main", "_shim_graphics_set_callback", "_display_inventory"]' +EMCC_LFLAGS += -s EXPORTED_FUNCTIONS='["_main", "_shim_graphics_set_callback", "_display_inventory", "_malloc"]' EMCC_LFLAGS += -s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall", "addFunction", \ - "removeFunction", "UTF8ToString", "getValue", "setValue"]' + "removeFunction", "UTF8ToString", "stringToUTF8", "getValue", \ + "setValue", "ENV", "FS", "IDBFS"]' EMCC_LFLAGS += -s ERROR_ON_UNDEFINED_SYMBOLS=0 +EMCC_LFLAGS += -s EXPORT_ES6=1 +EMCC_LFLAGS += -lidbfs.js # XXX: the "@/" at the end of "--embed-file" tells emscripten to embed the files # in the root directory, otherwise they will end up in the $(WASM_DATA_DIR) path EMCC_LFLAGS += --embed-file $(WASM_DATA_DIR)@/ diff --git a/win/shim/winshim.c b/win/shim/winshim.c index d83c62a45..dbc3ef5d7 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -115,7 +115,7 @@ void name fn_args { \ #endif /* __EMSCRIPTEN__ */ VDECLCB(shim_init_nhwindows,(int *argcp, char **argv), "vpp", P2V argcp, P2V argv) -VDECLCB(shim_player_selection,(void), "v") +DECLCB(boolean, shim_player_selection_or_tty,(void), "b") VDECLCB(shim_askname,(void), "v") VDECLCB(shim_get_nh_event,(void), "v") VDECLCB(shim_exit_nhwindows,(const char *str), "vs", P2V str) @@ -123,33 +123,33 @@ VDECLCB(shim_suspend_nhwindows,(const char *str), "vs", P2V str) VDECLCB(shim_resume_nhwindows,(void), "v") DECLCB(winid, shim_create_nhwindow, (int type), "ii", A2P type) VDECLCB(shim_clear_nhwindow,(winid window), "vi", A2P window) -VDECLCB(shim_display_nhwindow,(winid window, boolean blocking), "vii", A2P window, A2P blocking) +VDECLCB(shim_display_nhwindow,(winid window, boolean blocking), "vib", A2P window, A2P blocking) VDECLCB(shim_destroy_nhwindow,(winid window), "vi", A2P window) VDECLCB(shim_curs,(winid a, int x, int y), "viii", A2P a, A2P x, A2P y) VDECLCB(shim_putstr,(winid w, int attr, const char *str), "viis", A2P w, A2P attr, P2V str) -VDECLCB(shim_display_file,(const char *name, boolean complain), "vsi", P2V name, A2P complain) +VDECLCB(shim_display_file,(const char *name, boolean complain), "vsb", P2V name, A2P complain) VDECLCB(shim_start_menu,(winid window, unsigned long mbehavior), "vii", A2P window, A2P mbehavior) VDECLCB(shim_add_menu, (winid window, const glyph_info *glyphinfo, const ANY_P *identifier, char ch, char gch, int attr, int clr, const char *str, unsigned int itemflags), - "vippiiiisi", + "vipi00iisi", A2P window, P2V glyphinfo, P2V identifier, A2P ch, A2P gch, A2P attr, A2P clr, P2V str, A2P itemflags) VDECLCB(shim_end_menu,(winid window, const char *prompt), "vis", A2P window, P2V prompt) /* XXX: shim_select_menu menu_list is an output */ -DECLCB(int, shim_select_menu,(winid window, int how, MENU_ITEM_P **menu_list), "iiio", A2P window, A2P how, P2V menu_list) +DECLCB(int, shim_select_menu,(winid window, int how, MENU_ITEM_P **menu_list), "iiip", A2P window, A2P how, P2V menu_list) DECLCB(char, shim_message_menu,(char let, int how, const char *mesg), "ciis", A2P let, A2P how, P2V mesg) VDECLCB(shim_mark_synch,(void), "v") VDECLCB(shim_wait_synch,(void), "v") VDECLCB(shim_cliparound,(int x, int y), "vii", A2P x, A2P y) -VDECLCB(shim_update_positionbar,(char *posbar), "vp", P2V posbar) -VDECLCB(shim_print_glyph,(winid w, coordxy x, coordxy y, const glyph_info *glyphinfo, const glyph_info *bkglyphinfo), "viiipp", A2P w, A2P x, A2P y, P2V glyphinfo, P2V bkglyphinfo) +VDECLCB(shim_update_positionbar,(char *posbar), "vs", P2V posbar) +VDECLCB(shim_print_glyph,(winid w, coordxy x, coordxy y, const glyph_info *glyphinfo, const glyph_info *bkglyphinfo), "vi11pp", A2P w, A2P x, A2P y, P2V glyphinfo, P2V bkglyphinfo) VDECLCB(shim_raw_print,(const char *str), "vs", P2V str) VDECLCB(shim_raw_print_bold,(const char *str), "vs", P2V str) DECLCB(int, shim_nhgetch,(void), "i") -DECLCB(int, shim_nh_poskey,(coordxy *x, coordxy *y, int *mod), "iooo", P2V x, P2V y, P2V mod) +DECLCB(int, shim_nh_poskey,(coordxy *x, coordxy *y, int *mod), "ippp", P2V x, P2V y, P2V mod) VDECLCB(shim_nhbell,(void), "v") DECLCB(int, shim_doprev_message,(void),"iv") -DECLCB(char, shim_yn_function,(const char *query, const char *resp, char def), "cssi", P2V query, P2V resp, A2P def) -VDECLCB(shim_getlin,(const char *query, char *bufp), "vso", P2V query, P2V bufp) +DECLCB(char, shim_yn_function,(const char *query, const char *resp, char def), "css0", P2V query, P2V resp, A2P def) +VDECLCB(shim_getlin,(const char *query, char *bufp), "vsp", P2V query, P2V bufp) DECLCB(int,shim_get_ext_cmd,(void),"iv") VDECLCB(shim_number_pad,(int state), "vi", A2P state) VDECLCB(shim_delay_output,(void), "v") @@ -162,17 +162,17 @@ DECLCB(char *,shim_get_color_string,(void),"sv") VDECLCB(shim_start_screen, (void), "v") VDECLCB(shim_end_screen, (void), "v") VDECLCB(shim_preference_update, (const char *pref), "vp", P2V pref) -DECLCB(char *,shim_getmsghistory, (boolean init), "si", A2P init) -VDECLCB(shim_putmsghistory, (const char *msg, boolean restoring_msghist), "vsi", P2V msg, A2P restoring_msghist) +DECLCB(char *,shim_getmsghistory, (boolean init), "sb", A2P init) +VDECLCB(shim_putmsghistory, (const char *msg, boolean restoring_msghist), "vsb", P2V msg, A2P restoring_msghist) VDECLCB(shim_status_init, (void), "v") VDECLCB(shim_status_enablefield, (int fieldidx, const char *nm, const char *fmt, boolean enable), - "vippi", + "vippb", A2P fieldidx, P2V nm, P2V fmt, A2P enable) /* XXX: the second argument to shim_status_update is sometimes an integer and sometimes a pointer */ VDECLCB(shim_status_update, (int fldidx, genericptr_t ptr, int chg, int percent, int color, unsigned long *colormasks), - "vioiiip", + "vipiiip", A2P fldidx, P2V ptr, A2P chg, A2P percent, A2P color, P2V colormasks) #ifdef __EMSCRIPTEN__ @@ -183,6 +183,14 @@ void shim_update_inventory(int a1 UNUSED) { display_inventory(NULL, FALSE); } } + +void shim_player_selection() { + boolean do_genl_player_setup = shim_player_selection_or_tty(); + if (do_genl_player_setup) { + genl_player_setup(80); + } +} + win_request_info * shim_ctrl_nhwindow( winid window UNUSED, @@ -203,6 +211,7 @@ struct window_procs shim_procs = { WPID(shim), (0 | WC_ASCII_MAP + | WC_MOUSE_SUPPORT | WC_COLOR | WC_HILITE_PET | WC_INVERSE | WC_EIGHT_BIT_IN), (0 #if defined(SELECTSAVED) @@ -262,7 +271,7 @@ EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *r // unrolling and it crashes. Thus we use Asyncify.handleSleep() and wakeUp() to make sure that async doesn't break // Asyncify. For details, see: https://emscripten.org/docs/porting/asyncify.html#optimizing Asyncify.handleSleep(wakeUp => { - // convert callback arguments to proper JavaScript varaidic arguments + // convert callback arguments to proper JavaScript variadic arguments let name = UTF8ToString(shim_name); let fmt = UTF8ToString(fmt_str); let cbName = UTF8ToString(cb_name); @@ -287,40 +296,25 @@ EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *r // do the callback let userCallback = globalThis[cbName]; - runJsEventLoop(() => userCallback.call(this, name, ... jsArgs)).then((retVal) => { + userCallback.call(this, name, ... jsArgs).then((retVal) => { // save the return value setPointerValue(name, ret_ptr, retType, retVal); - // return - setTimeout(() => { - reentryMutexUnlock(); + reentryMutexUnlock(); + try { wakeUp(); - }, 0); + } catch (e) { + + } }); function getArg(name, ptr, type) { - return (type === "o")?ptr:getPointerValue(name, getValue(ptr, "*"), type); - } - - // setTimeout() with value of '0' is similar to setImmediate() (but setImmediate isn't standard) - // this lets the JS loop run for a tick so that other events can occur - // XXX: I also tried replacing the for(;;) in allmain.c:moveloop() with emscripten_set_main_loop() - // unfortunately that won't work -- if the simulate_infinite_loop arg is false, it falls through - // and the program ends; - // if is true, it throws an exception to break out of main(), but doesn't get caught because - // the stack isn't running under main() anymore... - // I think this is suboptimal, but we will have to live with it (for now?) - async function runJsEventLoop(cb) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(cb()); - }, 0); - }); + return (type === "p") ? getValue(ptr, "*") : getPointerValue(name, getValue(ptr, "*"), type); } function reentryMutexLock(name) { globalThis.nethackGlobal = globalThis.nethackGlobal || {}; if(globalThis.nethackGlobal.shimFunctionRunning) { - throw new Error(`'${name}' attempting second call to 'local_callback' before '${globalThis.nethackGlobal.shimFunctionRunning}' has finished, will crash emscripten Asyncify. For details see: emscripten.org/docs/porting/asyncify.html#reentrancy`); + console.error(`'${name}' attempting second call to 'local_callback' before '${globalThis.nethackGlobal.shimFunctionRunning}' has finished, will crash emscripten Asyncify. For details see: emscripten.org/docs/porting/asyncify.html#reentrancy`); } globalThis.nethackGlobal.shimFunctionRunning = name; }