]> granicus.if.org Git - nethack/commitdiff
functional shim graphics
authorAdam Powers <apowers@ato.ms>
Sat, 29 Aug 2020 17:26:58 +0000 (10:26 -0700)
committerAdam Powers <apowers@ato.ms>
Sat, 29 Aug 2020 17:26:58 +0000 (10:26 -0700)
sys/lib/hints/wasm
win/shim/winshim.c

index 8715104c84073a1edda92650665d2c9af55f4b71..799efe03cdaa216a546e8d59d7987ebeac959b8f 100644 (file)
@@ -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
index d82d21334de6ec04f779045dec7b5cd862eecc20..085a27684b2241b2ce4a46e5ec17ad487cfe909e 100644 (file)
@@ -7,6 +7,80 @@
 #include "hack.h"
 
 #ifdef SHIM_GRAPHICS
+#include <stdarg.h>
+/* for cross-compiling to WebAssembly (WASM) */
+#ifdef __EMSCRIPTEN__
+#include <emscripten/emscripten.h>
+#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