Merge branch 'NetHack-3.7' of https://github.com/guillaumebrunerie/NetHack into NetHack-3.7

This commit is contained in:
nhmall
2024-11-30 15:54:21 -05:00
5 changed files with 203 additions and 55 deletions
+3
View File
@@ -482,6 +482,9 @@ extern struct nomakedefs_s nomakedefs;
#if !defined(CROSS_TO_WASM) /* no popen in WASM */ #if !defined(CROSS_TO_WASM) /* no popen in WASM */
#define PANICTRACE_GDB #define PANICTRACE_GDB
#endif #endif
#ifdef CROSS_TO_WASM
#undef COMPRESS
#endif
#endif #endif
/* Supply nethack_enter macro if not supplied by port */ /* Supply nethack_enter macro if not supplied by port */
+1 -1
View File
@@ -2176,7 +2176,7 @@ genl_player_selection(void)
/*NOTREACHED*/ /*NOTREACHED*/
} }
#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS) #if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS) || defined(SHIM_GRAPHICS)
/* ['#else' far below] */ /* ['#else' far below] */
staticfn boolean reset_role_filtering(void); staticfn boolean reset_role_filtering(void);
+161 -13
View File
@@ -12,6 +12,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <signal.h> #include <signal.h>
#include <pwd.h> #include <pwd.h>
#include <func_tab.h>
#ifndef O_RDONLY #ifndef O_RDONLY
#include <fcntl.h> #include <fcntl.h>
#endif #endif
@@ -174,6 +175,12 @@ nhmain(int argc, char *argv[])
chdirx(dir, 1); chdirx(dir, 1);
#endif #endif
#ifdef __EMSCRIPTEN__
js_helpers_init();
js_constants_init();
js_globals_init();
#endif
#ifdef _M_UNIX #ifdef _M_UNIX
check_sco_console(); check_sco_console();
#endif #endif
@@ -201,11 +208,6 @@ nhmain(int argc, char *argv[])
process_options(argc, argv); /* command line options */ process_options(argc, argv); /* command line options */
#ifdef WINCHAIN #ifdef WINCHAIN
commit_windowchain(); commit_windowchain();
#endif
#ifdef __EMSCRIPTEN__
js_helpers_init();
js_constants_init();
js_globals_init();
#endif #endif
init_nhwindows(&argc, argv); /* now we can set up window system */ init_nhwindows(&argc, argv); /* now we can set up window system */
#ifdef _M_UNIX #ifdef _M_UNIX
@@ -781,9 +783,9 @@ EM_JS(void, js_helpers_init, (), {
globalThis.nethackGlobal = globalThis.nethackGlobal || {}; globalThis.nethackGlobal = globalThis.nethackGlobal || {};
globalThis.nethackGlobal.helpers = globalThis.nethackGlobal.helpers || {}; globalThis.nethackGlobal.helpers = globalThis.nethackGlobal.helpers || {};
installHelper(displayInventory); installHelper(displayInventory, "displayInventory");
installHelper(getPointerValue); installHelper(getPointerValue, "getPointerValue");
installHelper(setPointerValue); installHelper(setPointerValue, "setPointerValue");
// used by update_inventory // used by update_inventory
function displayInventory() { function displayInventory() {
@@ -804,6 +806,8 @@ EM_JS(void, js_helpers_init, (), {
return getValue(ptr, "*"); return getValue(ptr, "*");
case "c": // char case "c": // char
return String.fromCharCode(getValue(ptr, "i8")); return String.fromCharCode(getValue(ptr, "i8"));
case "b":
return getValue(ptr, "i8") == 1;
case "0": /* 2^0 = 1 byte */ case "0": /* 2^0 = 1 byte */
return getValue(ptr, "i8"); return getValue(ptr, "i8");
case "1": /* 2^1 = 2 bytes */ case "1": /* 2^1 = 2 bytes */
@@ -816,8 +820,8 @@ EM_JS(void, js_helpers_init, (), {
return getValue(ptr, "float"); return getValue(ptr, "float");
case "d": // double case "d": // double
return getValue(ptr, "double"); return getValue(ptr, "double");
case "o": // overloaded: multiple types case "v": // void
return ptr; return undefined;
default: default:
throw new TypeError ("unknown type:" + type); 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); // console.log("setPointerValue", name, "0x" + ptr.toString(16), type, value);
switch (type) { switch (type) {
case "p": case "p":
throw new Error("not implemented"); setValue(ptr, value, "*");
break;
case "s": case "s":
if(typeof value !== "string") if(typeof value !== "string")
throw new TypeError(`expected ${name} return type to be 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`); throw new TypeError(`expected ${name} return type to be integer`);
setValue(ptr, value, "i32"); setValue(ptr, value, "i32");
break; 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": case "c":
if(typeof value !== "number" || value < 0 || value > 128) if(typeof value !== "number" || value < 0 || value > 128)
throw new TypeError(`expected ${name} return type to be integer representing an ASCII character`); 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`); throw new TypeError(`expected ${name} return type to be double`);
setValue(ptr, value, "double"); setValue(ptr, value, "double");
break; 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": case "v":
break; break;
default: 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] = globalThis.nethackGlobal.constants[scope] || {};
globalThis.nethackGlobal.constants[scope][name] = str; 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() { void js_constants_init() {
EM_ASM({ EM_ASM({
globalThis.nethackGlobal = globalThis.nethackGlobal || {}; globalThis.nethackGlobal = globalThis.nethackGlobal || {};
globalThis.nethackGlobal.constants = globalThis.nethackGlobal.constants || {}; globalThis.nethackGlobal.constants = globalThis.nethackGlobal.constants || {};
globalThis.nethackGlobal.pointers = globalThis.nethackGlobal.pointers || {};
}); });
// create_nhwindow // create_nhwindow
@@ -989,8 +1011,7 @@ void js_constants_init() {
// copyright // copyright
SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_A); SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_A);
SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_B); SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_B);
// XXX: not set for cross-compile set_const_str("COPYRIGHT", "COPYRIGHT_BANNER_C", (char*) COPYRIGHT_BANNER_C);
//SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_C);
SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_D); SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_D);
// glyphs // glyphs
@@ -1042,6 +1063,119 @@ void js_constants_init() {
SET_CONSTANT("COLOR_ATTR", HL_ATTCLR_BLINK); SET_CONSTANT("COLOR_ATTR", HL_ATTCLR_BLINK);
SET_CONSTANT("COLOR_ATTR", HL_ATTCLR_INVERSE); SET_CONSTANT("COLOR_ATTR", HL_ATTCLR_INVERSE);
SET_CONSTANT("COLOR_ATTR", BL_ATTCLR_MAX); 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_MESSAGE, "i");
CREATE_GLOBAL(WIN_INVEN, "i"); CREATE_GLOBAL(WIN_INVEN, "i");
CREATE_GLOBAL(WIN_STATUS, "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), { EM_JS(void, create_global, (char *name_str, void *ptr, char *type_str), {
+6 -3
View File
@@ -217,7 +217,7 @@ ifdef CROSS_TO_WASM
# originally from https://github.com/NetHack/NetHack/pull/385 # originally from https://github.com/NetHack/NetHack/pull/385
#===============-================================================= #===============-=================================================
# #
WASM_DEBUG = 1 #WASM_DEBUG = 1
WASM_DATA_DIR = $(TARGETPFX)wasm-data WASM_DATA_DIR = $(TARGETPFX)wasm-data
WASM_TARGET = $(TARGETPFX)nethack.js WASM_TARGET = $(TARGETPFX)nethack.js
EMCC_LFLAGS = EMCC_LFLAGS =
@@ -228,10 +228,13 @@ EMCC_LFLAGS += -s ALLOW_TABLE_GROWTH
EMCC_LFLAGS += -s ASYNCIFY -s ASYNCIFY_IMPORTS='["local_callback"]' EMCC_LFLAGS += -s ASYNCIFY -s ASYNCIFY_IMPORTS='["local_callback"]'
EMCC_LFLAGS += -O3 EMCC_LFLAGS += -O3
EMCC_LFLAGS += -s MODULARIZE 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", \ 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 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 # 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 # in the root directory, otherwise they will end up in the $(WASM_DATA_DIR) path
EMCC_LFLAGS += --embed-file $(WASM_DATA_DIR)@/ EMCC_LFLAGS += --embed-file $(WASM_DATA_DIR)@/
+32 -38
View File
@@ -115,7 +115,7 @@ void name fn_args { \
#endif /* __EMSCRIPTEN__ */ #endif /* __EMSCRIPTEN__ */
VDECLCB(shim_init_nhwindows,(int *argcp, char **argv), "vpp", P2V argcp, P2V argv) 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_askname,(void), "v")
VDECLCB(shim_get_nh_event,(void), "v") VDECLCB(shim_get_nh_event,(void), "v")
VDECLCB(shim_exit_nhwindows,(const char *str), "vs", P2V str) 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") VDECLCB(shim_resume_nhwindows,(void), "v")
DECLCB(winid, shim_create_nhwindow, (int type), "ii", A2P type) DECLCB(winid, shim_create_nhwindow, (int type), "ii", A2P type)
VDECLCB(shim_clear_nhwindow,(winid window), "vi", A2P window) 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_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_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_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_start_menu,(winid window, unsigned long mbehavior), "vii", A2P window, A2P mbehavior)
VDECLCB(shim_add_menu, 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), (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) 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) VDECLCB(shim_end_menu,(winid window, const char *prompt), "vis", A2P window, P2V prompt)
/* XXX: shim_select_menu menu_list is an output */ /* 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) 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_mark_synch,(void), "v")
VDECLCB(shim_wait_synch,(void), "v") VDECLCB(shim_wait_synch,(void), "v")
VDECLCB(shim_cliparound,(int x, int y), "vii", A2P x, A2P y) VDECLCB(shim_cliparound,(int x, int y), "vii", A2P x, A2P y)
VDECLCB(shim_update_positionbar,(char *posbar), "vp", P2V posbar) 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), "viiipp", A2P w, A2P x, A2P y, P2V glyphinfo, P2V bkglyphinfo) 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,(const char *str), "vs", P2V str)
VDECLCB(shim_raw_print_bold,(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_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") VDECLCB(shim_nhbell,(void), "v")
DECLCB(int, shim_doprev_message,(void),"iv") 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) 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), "vso", P2V query, P2V bufp) VDECLCB(shim_getlin,(const char *query, char *bufp), "vsp", P2V query, P2V bufp)
DECLCB(int,shim_get_ext_cmd,(void),"iv") DECLCB(int,shim_get_ext_cmd,(void),"iv")
VDECLCB(shim_number_pad,(int state), "vi", A2P state) VDECLCB(shim_number_pad,(int state), "vi", A2P state)
VDECLCB(shim_delay_output,(void), "v") 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_start_screen, (void), "v")
VDECLCB(shim_end_screen, (void), "v") VDECLCB(shim_end_screen, (void), "v")
VDECLCB(shim_preference_update, (const char *pref), "vp", P2V pref) VDECLCB(shim_preference_update, (const char *pref), "vp", P2V pref)
DECLCB(char *,shim_getmsghistory, (boolean init), "si", A2P init) DECLCB(char *,shim_getmsghistory, (boolean init), "sb", A2P init)
VDECLCB(shim_putmsghistory, (const char *msg, boolean restoring_msghist), "vsi", P2V msg, A2P restoring_msghist) VDECLCB(shim_putmsghistory, (const char *msg, boolean restoring_msghist), "vsb", P2V msg, A2P restoring_msghist)
VDECLCB(shim_status_init, (void), "v") VDECLCB(shim_status_init, (void), "v")
VDECLCB(shim_status_enablefield, VDECLCB(shim_status_enablefield,
(int fieldidx, const char *nm, const char *fmt, boolean enable), (int fieldidx, const char *nm, const char *fmt, boolean enable),
"vippi", "vippb",
A2P fieldidx, P2V nm, P2V fmt, A2P enable) A2P fieldidx, P2V nm, P2V fmt, A2P enable)
/* XXX: the second argument to shim_status_update is sometimes an integer and sometimes a pointer */ /* XXX: the second argument to shim_status_update is sometimes an integer and sometimes a pointer */
VDECLCB(shim_status_update, VDECLCB(shim_status_update,
(int fldidx, genericptr_t ptr, int chg, int percent, int color, unsigned long *colormasks), (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) A2P fldidx, P2V ptr, A2P chg, A2P percent, A2P color, P2V colormasks)
#ifdef __EMSCRIPTEN__ #ifdef __EMSCRIPTEN__
@@ -183,6 +183,14 @@ void shim_update_inventory(int a1 UNUSED) {
display_inventory(NULL, FALSE); 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 * win_request_info *
shim_ctrl_nhwindow( shim_ctrl_nhwindow(
winid window UNUSED, winid window UNUSED,
@@ -203,6 +211,7 @@ struct window_procs shim_procs = {
WPID(shim), WPID(shim),
(0 (0
| WC_ASCII_MAP | WC_ASCII_MAP
| WC_MOUSE_SUPPORT
| WC_COLOR | WC_HILITE_PET | WC_INVERSE | WC_EIGHT_BIT_IN), | WC_COLOR | WC_HILITE_PET | WC_INVERSE | WC_EIGHT_BIT_IN),
(0 (0
#if defined(SELECTSAVED) #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 // 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. For details, see: https://emscripten.org/docs/porting/asyncify.html#optimizing
Asyncify.handleSleep(wakeUp => { 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 name = UTF8ToString(shim_name);
let fmt = UTF8ToString(fmt_str); let fmt = UTF8ToString(fmt_str);
let cbName = UTF8ToString(cb_name); 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 // do the callback
let userCallback = globalThis[cbName]; let userCallback = globalThis[cbName];
runJsEventLoop(() => userCallback.call(this, name, ... jsArgs)).then((retVal) => { userCallback.call(this, name, ... jsArgs).then((retVal) => {
// save the return value // save the return value
setPointerValue(name, ret_ptr, retType, retVal); setPointerValue(name, ret_ptr, retType, retVal);
// return reentryMutexUnlock();
setTimeout(() => { try {
reentryMutexUnlock();
wakeUp(); wakeUp();
}, 0); } catch (e) {
}
}); });
function getArg(name, ptr, type) { function getArg(name, ptr, type) {
return (type === "o")?ptr:getPointerValue(name, getValue(ptr, "*"), type); return (type === "p") ? getValue(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);
});
} }
function reentryMutexLock(name) { function reentryMutexLock(name) {
globalThis.nethackGlobal = globalThis.nethackGlobal || {}; globalThis.nethackGlobal = globalThis.nethackGlobal || {};
if(globalThis.nethackGlobal.shimFunctionRunning) { 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; globalThis.nethackGlobal.shimFunctionRunning = name;
} }