From 97a14eebbe760f7205b8a0bbbd4e9a068ffdda4d Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 29 Aug 2020 10:26:58 -0700 Subject: [PATCH] functional shim graphics --- sys/lib/hints/wasm | 12 +++-- win/shim/winshim.c | 115 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 104 insertions(+), 23 deletions(-) diff --git a/sys/lib/hints/wasm b/sys/lib/hints/wasm index 8715104c8..799efe03c 100644 --- a/sys/lib/hints/wasm +++ b/sys/lib/hints/wasm @@ -18,13 +18,14 @@ EMCC_LFLAGS+=-s ALLOW_TABLE_GROWTH EMCC_LFLAGS+=-s ASYNCIFY -s ASYNCIFY_IMPORTS='["_nhmain"]' -O3 EMCC_LFLAGS+=-s MODULARIZE EMCC_LFLAGS+=-s EXPORTED_FUNCTIONS='["_main", "_stub_graphics_set_callback"]' -EMCC_LFLAGS+=-s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall", "addFunction", "removeFunction", "UTF8ToString"]' +EMCC_LFLAGS+=-s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall", "addFunction", "removeFunction", "UTF8ToString", "getValue"]' EMCC_LFLAGS+=-s ERROR_ON_UNDEFINED_SYMBOLS=0 EMCC_LFLAGS+=--embed-file wasm-data@/ # WASM C flags EMCC_CFLAGS= -EMCC_CFLAGS+=-Wall -Werror +EMCC_CFLAGS+=-Wall +EMCC_CFLAGS+=-Werror EMCC_DEBUG_CFLAGS+=-s ASSERTIONS=1 EMCC_DEBUG_CFLAGS+=-s STACK_OVERFLOW_CHECK=2 EMCC_DEBUG_CFLAGS+=-s SAFE_HEAP=1 @@ -32,16 +33,17 @@ EMCC_DEBUG_CFLAGS+=-s LLD_REPORT_UNDEFINED EMCC_PROD_CFLAGS+=-O3 # Nethack C flags -CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"/sysconf\" -DSECURE CFLAGS+=-g -I../include -DNOTPARMDECL -CFLAGS+=-Wall -Werror +CFLAGS+=-Wall +CFLAGS+=-Werror CFLAGS+=-DGCC_WARN # NetHack sources control CFLAGS+=-DDLB CFLAGS+=-DHACKDIR=\"$(HACKDIR)\" CFLAGS+=-DDLB -CFLAGS+=-DGREPPATH=\"/usr/bin/grep\" +#CFLAGS+=-DGREPPATH=\"/usr/bin/grep\" CFLAGS+=-DNOMAIL ifdef WASM_DEBUG diff --git a/win/shim/winshim.c b/win/shim/winshim.c index d82d21334..085a27684 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -7,6 +7,80 @@ #include "hack.h" #ifdef SHIM_GRAPHICS +#include +/* for cross-compiling to WebAssembly (WASM) */ +#ifdef __EMSCRIPTEN__ +#include +#endif + +#define SHIM_DEBUG + +#ifndef __EMSCRIPTEN__ +typedef void(*stub_callback_t)(const char *name, const char *fmt, void *ret_ptr, ...); +#else /* __EMSCRIPTEN__ */ +/* WASM can't handle a variadic callback, so we pass back an array of pointers instead... */ +typedef void(*stub_callback_t)(const char *name, const char *fmt, void *ret_ptr, void *args[]); +#endif /* !__EMSCRIPTEN__ */ + +/* this is the primary interface to shim graphics, + * call this function with your declared callback function + * and you will receive all the windowing calls + */ +static stub_callback_t shim_graphics_callback = NULL; +#ifdef __EMSCRIPTEN__ + EMSCRIPTEN_KEEPALIVE +#endif +void stub_graphics_set_callback(stub_callback_t cb) { + shim_graphics_callback = cb; +} + +#ifdef __EMSCRIPTEN__ +// A2P = Argument to Pointer +#define A2P & +// P2V = Pointer to Void +#define P2V (void *) +#define DECLCB(ret_type, name, fn_args, fmt, ...) \ +ret_type name fn_args { \ + void *args[] = { __VA_ARGS__ }; \ + ret_type ret; \ + debugf("SHIM GRAPHICS: " #name "\n"); \ + if (!shim_graphics_callback) return; \ + shim_graphics_callback(#name, fmt, (void *)&ret, args); \ + return ret; \ +} + +#define VDECLCB(name, fn_args, fmt, ...) \ +void name fn_args { \ + void *args[] = { __VA_ARGS__ }; \ + debugf("SHIM GRAPHICS: " #name "\n"); \ + if (!shim_graphics_callback) return; \ + shim_graphics_callback(#name, fmt, NULL, args); \ +} +#else /* !__EMSCRIPTEN__ */ +#define A2P +#define P2V +#define DECLCB(ret_type, name, args, fmt, ...) \ +ret_type name args { \ + ret_type ret; \ + debugf("SHIM GRAPHICS: " #name "\n"); \ + if (!shim_graphics_callback) return; \ + shim_graphics_callback(#name, fmt, (void *)&ret, __VA_ARGS__); \ + return ret; \ +} + +void name args { \ + debugf("SHIM GRAPHICS: " #name "\n"); \ + if (!shim_graphics_callback) return; \ + shim_graphics_callback(#name, fmt, NULL, __VA_ARGS__); \ +} +#endif /* __EMSCRIPTEN__ */ + +#ifdef SHIM_DEBUG +#define debugf printf +#else /* !SHIM_DEBUG */ +#define debugf(...) +#endif /* SHIM_DEBUG */ + enum win_types { WINSTUB_MESSAGE = 1, @@ -29,6 +103,7 @@ name args { \ #define DECL(name, args) \ void name args; +// void DECLCB(shim_init_nhwindows,(int *argcp, char **argv), "pp", argcp, argv) VSTUB(shim_init_nhwindows,(int *argcp, char **argv)) VSTUB(shim_player_selection,(void)) VSTUB(shim_askname,(void)) @@ -40,8 +115,10 @@ winid STUB(shim_create_nhwindow, WINSTUB_MAP, (int a)) VSTUB(shim_clear_nhwindow,(winid a)) VSTUB(shim_display_nhwindow,(winid a, BOOLEAN_P b)) VSTUB(shim_destroy_nhwindow,(winid a)) -VSTUB(shim_curs,(winid a, int x, int y)) -DECL(shim_putstr,(winid w, int attr, const char *str)) +VDECLCB(shim_curs,(winid a, int x, int y), "viii", A2P a, A2P x, A2P y) +// VSTUB(shim_curs,(winid a, int x, int y)) +// DECL(shim_putstr,(winid w, int attr, const char *str)) +VDECLCB(shim_putstr,(winid w, int attr, const char *str), "viis", A2P w, A2P attr, P2V str) VSTUB(shim_display_file,(const char *a, BOOLEAN_P b)) VSTUB(shim_start_menu,(winid w, unsigned long mbehavior)) VSTUB(shim_add_menu,(winid a, int b, const ANY_P *c, CHAR_P d, CHAR_P e, int f, const char *h, unsigned int k)) @@ -53,8 +130,10 @@ VSTUB(shim_mark_synch,(void)) VSTUB(shim_wait_synch,(void)) VSTUB(shim_cliparound,(int a, int b)) VSTUB(shim_update_positionbar,(char *a)) -DECL(shim_print_glyph,(winid w, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph)) -DECL(shim_raw_print,(const char *str)) +// DECL(shim_print_glyph,(winid w, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph)) +VDECLCB(shim_print_glyph,(winid w, int x, int y, int glyph, int bkglyph), "viiiii", A2P w, A2P x, A2P y, A2P glyph, A2P bkglyph) +// DECL(shim_raw_print,(const char *str)) +VDECLCB(shim_raw_print,(const char *str), "vs", P2V str) VSTUB(shim_raw_print_bold,(const char *a)) int STUB(shim_nhgetch,0,(void)) int STUB(shim_nh_poskey,0,(int *a, int *b, int *c)) @@ -140,22 +219,22 @@ struct window_procs shim_procs = { genl_can_suspend_yes, }; -void shim_print_glyph(winid w, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph) { - /* map glyph to character and color */ - // (void) mapglyph(glyph, &ch, &color, &special, x, y, 0); +// void shim_print_glyph(winid w, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph) { +// /* map glyph to character and color */ +// // (void) mapglyph(glyph, &ch, &color, &special, x, y, 0); - fprintf(stdout, "shim_print_glyph (%d,%d): %c\n", x,y,(char)glyph); - fflush(stdout); -} +// fprintf(stdout, "shim_print_glyph (%d,%d): %c\n", x,y,(char)glyph); +// fflush(stdout); +// } -void shim_raw_print(const char *str) { - fprintf(stdout, "shim_raw_print: %s\n", str); - fflush(stdout); -} +// void shim_raw_print(const char *str) { +// fprintf(stdout, "shim_raw_print: %s\n", str); +// fflush(stdout); +// } -void shim_putstr(winid w, int attr, const char *str) { - fprintf(stdout, "shim_putstr (win %d): %s\n", w, str); - fflush(stdout); -} +// void shim_putstr(winid w, int attr, const char *str) { +// fprintf(stdout, "shim_putstr (win %d): %s\n", w, str); +// fflush(stdout); +// } #endif /* SHIM_GRAPHICS */ \ No newline at end of file