From 633896292a4a6487a12e6737ff718ec0b8806176 Mon Sep 17 00:00:00 2001 From: Eric House Date: Mon, 1 Feb 2021 20:13:25 -0800 Subject: [PATCH] snapshot: drawing empty board --- xwords4/common/dictnry.c | 3 +- xwords4/common/dictnry.h | 2 +- xwords4/wasm/Makefile | 33 +- xwords4/wasm/assets_dir/CollegeEng_2to8.xwd | 1 + xwords4/wasm/main.c | 95 +++++- xwords4/wasm/wasmdict.c | 167 ++++++++++ xwords4/wasm/wasmdict.h | 9 + xwords4/wasm/wasmdraw.c | 298 ++++++++++++++++++ xwords4/wasm/wasmdraw.h | 5 + xwords4/wasm/wasmdutil.c | 170 ++++++++++ xwords4/wasm/wasmdutil.h | 13 + xwords4/wasm/wasmutil.c | 333 ++++++++++++++++++++ xwords4/wasm/wasmutil.h | 10 + xwords4/wasm/xptypes.h | 106 +++++++ 14 files changed, 1230 insertions(+), 15 deletions(-) create mode 120000 xwords4/wasm/assets_dir/CollegeEng_2to8.xwd create mode 100644 xwords4/wasm/wasmdict.c create mode 100644 xwords4/wasm/wasmdict.h create mode 100644 xwords4/wasm/wasmdraw.c create mode 100644 xwords4/wasm/wasmdraw.h create mode 100644 xwords4/wasm/wasmdutil.c create mode 100644 xwords4/wasm/wasmdutil.h create mode 100644 xwords4/wasm/wasmutil.c create mode 100644 xwords4/wasm/wasmutil.h create mode 100644 xwords4/wasm/xptypes.h diff --git a/xwords4/common/dictnry.c b/xwords4/common/dictnry.c index 78b7f867d..b5e7fa330 100644 --- a/xwords4/common/dictnry.c +++ b/xwords4/common/dictnry.c @@ -1104,8 +1104,9 @@ dict_super_edge_with_tile( const DictionaryCtxt* dict, array_edge* from, } /* edge_with_tile */ void -dict_super_init( DictionaryCtxt* dict ) +dict_super_init( MPFORMAL DictionaryCtxt* dict ) { + dict->mpool = mpool; /* subclass may change these later.... */ dict->func_edge_for_index = dict_super_edge_for_index; dict->func_dict_getTopEdge = dict_super_getTopEdge; diff --git a/xwords4/common/dictnry.h b/xwords4/common/dictnry.h index 7ac7b70d5..71d8d4c8c 100644 --- a/xwords4/common/dictnry.h +++ b/xwords4/common/dictnry.h @@ -231,7 +231,7 @@ XP_Bool parseCommon( DictionaryCtxt* dict, XWEnv xwe, const XP_U8** ptrp, XP_Bool checkSanity( DictionaryCtxt* dict, XP_U32 numEdges ); /* To be called only by subclasses!!! */ -void dict_super_init( DictionaryCtxt* ctxt ); +void dict_super_init( MPFORMAL DictionaryCtxt* ctxt ); /* Must be implemented by subclasses */ void dict_splitFaces( DictionaryCtxt* dict, XWEnv xwe, const XP_U8* bytes, XP_U16 nBytes, XP_U16 nFaceos ); diff --git a/xwords4/wasm/Makefile b/xwords4/wasm/Makefile index 1a375dad0..3e1edb4e2 100644 --- a/xwords4/wasm/Makefile +++ b/xwords4/wasm/Makefile @@ -1,9 +1,32 @@ -INPUTS = main.c +include ../common/config.mk + +INPUTS = main.c wasmdict.c wasmutls.c wasmdraw.c wasmutil.c wasmdutil.c ${COMMONSRC} + +DEFINES += -DMEM_DEBUG -DDEBUG +DEFINES += -DXWFEATURE_CHAT +DEFINES += -DXWFEATURE_BONUSALL +DEFINES += -DMAX_ROWS=32 +DEFINES += -DCOMMON_LAYOUT +DEFINES += -DDROP_BITMAPS +DEFINES += -D__LITTLE_ENDIAN +DEFINES += -DXWFEATURE_RELAY +DEFINES += -DXWFEATURE_DEVID +DEFINES += -D__WORDSIZE=32 +DEFINES += -DCOMMS_CHECKSUM +DEFINES += -DENABLE_LOGGING +DEFINES += -DKEYBOARD_NAV +DEFINES += -DDISABLE_TILE_SEL +DEFINES += -DKEY_SUPPORT +DEFINES += -DSTREAM_VERS_HASHSTREAM +DEFINES += -DXWFEATURE_KNOWNPLAYERS +DEFINES += -DXWFEATURE_DICTSANITY + all: main.html -main.html: ${INPUTS} - emcc -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["png"]' $^ -o $@ - - +main.html: ${INPUTS} Makefile + emcc $(DEFINES) -I . -I ../common -I ../relay -s USE_SDL=2 \ + --preload-file assets_dir \ + -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["png"]' ${INPUTS} -o $@ + scp main.html main.js main.wasm main.data pi4:/tmp diff --git a/xwords4/wasm/assets_dir/CollegeEng_2to8.xwd b/xwords4/wasm/assets_dir/CollegeEng_2to8.xwd new file mode 120000 index 000000000..e048b9eb7 --- /dev/null +++ b/xwords4/wasm/assets_dir/CollegeEng_2to8.xwd @@ -0,0 +1 @@ +../../android/app/src/main/assets/CollegeEng_2to8.xwd \ No newline at end of file diff --git a/xwords4/wasm/main.c b/xwords4/wasm/main.c index 3746a096b..12048a99d 100644 --- a/xwords4/wasm/main.c +++ b/xwords4/wasm/main.c @@ -4,37 +4,116 @@ // found in the LICENSE file. #include +#include #include #include #include #include #include +#include "game.h" +#include "mempool.h" + +#include "wasmdraw.h" +#include "wasmutil.h" +#include "wasmdutil.h" +#include "wasmdict.h" + #ifdef __EMSCRIPTEN__ #include #endif -int main(int argc, char** argv) -{ - SDL_Init(SDL_INIT_VIDEO); +#define WASM_BOARD_LEFT 0 +#define WASM_HOR_SCORE_TOP 0 +#define BDWIDTH 330 +#define BDHEIGHT 330 +typedef struct _Globals { SDL_Window* window; SDL_Renderer* renderer; + XWGame game; + CurGameInfo gi; + VTableMgr* vtMgr; + XW_DUtilCtxt* dutil; + XW_UtilCtxt* util; + DrawCtx* draw; + DictionaryCtxt* dict; + TransportProcs procs; + CommonPrefs cp; - SDL_CreateWindowAndRenderer(600, 400, 0, &window, &renderer); + MemPoolCtx* mpool; +} Globals; - int result = 0; +static void +initGlobals( Globals* globals ) +{ + globals->cp.showBoardArrow = XP_TRUE; + + globals->gi.serverRole = SERVER_STANDALONE; + globals->gi.nPlayers = 2; + globals->gi.boardSize = 15; + globals->gi.dictName = "myDict"; + globals->gi.players[0].name = "Eric"; + globals->gi.players[0].isLocal = XP_TRUE; + globals->gi.players[1].name = "Kati"; + globals->gi.players[1].isLocal = XP_TRUE; + + globals->mpool = mpool_make( "wasm" ); + globals->vtMgr = make_vtablemgr( globals->mpool ); + globals->dutil = wasm_dutil_make( globals->mpool, globals->vtMgr, globals ); + globals->util = wasm_util_make( globals->mpool, &globals->gi, globals->dutil ); + globals->dict = wasm_load_dict( globals->mpool ); + + globals->draw = wasm_draw_make( MPPARM(globals->mpool) globals->renderer ); +} + +static void +makeAndDraw( Globals* globals ) +{ + XP_LOGFF( "calling game_makeNewGame()" ); + game_makeNewGame( MPPARM(globals->mpool) NULL, + &globals->game, &globals->gi, + globals->util, globals->draw, + &globals->cp, &globals->procs ); + + XP_LOGFF( "calling board_figureLayout()" ); + BoardDims dims; + board_figureLayout( globals->game.board, NULL, &globals->gi, + WASM_BOARD_LEFT, WASM_HOR_SCORE_TOP, BDWIDTH, BDHEIGHT, + 110, 150, 200, BDWIDTH-25, 16, 16, XP_FALSE, &dims ); + XP_LOGFF( "calling board_applyLayout()" ); + board_applyLayout( globals->game.board, NULL, &dims ); + XP_LOGFF( "calling board_draw()" ); + + model_setDictionary( globals->game.model, NULL, globals->dict ); + // model_setSquareBonuses( globals->game.model, XWBonusType* bonuses, XP_U16 nBonuses ) + + board_invalAll( globals->game.board ); + board_draw( globals->game.board, NULL ); +} + +int main( int argc, char** argv ) +{ + LOG_FUNC(); + Globals globals = {0}; + SDL_Init(SDL_INIT_VIDEO); + + SDL_CreateWindowAndRenderer(600, 400, 0, + &globals.window, &globals.renderer); /** * Set up a white background */ - SDL_SetRenderDrawColor(renderer, 255, 255, 50, 50); - SDL_RenderClear(renderer); + SDL_SetRenderDrawColor(globals.renderer, 255, 255, 50, 50); + SDL_RenderClear(globals.renderer); + + initGlobals( &globals ); + makeAndDraw( &globals ); /** * Show what is in the renderer */ - SDL_RenderPresent(renderer); + SDL_RenderPresent(globals.renderer); printf("you should see an image.\n"); diff --git a/xwords4/wasm/wasmdict.c b/xwords4/wasm/wasmdict.c new file mode 100644 index 000000000..e48be46bc --- /dev/null +++ b/xwords4/wasm/wasmdict.c @@ -0,0 +1,167 @@ +#include +#include +#include +#include + +#include "wasmdict.h" +#include "strutils.h" + +#define DICTNAME "assets_dir/CollegeEng_2to8.xwd" + +typedef struct _WasmDictionaryCtxt { + DictionaryCtxt super; + size_t dictLength; + XP_U8* dictBase; + XP_Bool useMMap; +} WasmDictionaryCtxt; + +static XP_Bool +initFromDictFile( WasmDictionaryCtxt* dctx, const char* path ) +{ + LOG_FUNC(); + XP_Bool formatOk = XP_TRUE; + XP_U32 topOffset; + + struct stat statbuf; + int err = stat( DICTNAME, &statbuf ); + XP_LOGFF( "stat(%s) => %d; size: %d", DICTNAME, err, statbuf.st_size ); + + if ( 0 == err && 0 != statbuf.st_size ) { + /* do nothing */ + } else { + XP_LOGF( "%s: path=%s", __func__, path ); + goto closeAndExit; + } + dctx->dictLength = statbuf.st_size; + + { + FILE* dictF = fopen( path, "r" ); + XP_ASSERT( !!dictF ); + if ( dctx->useMMap ) { + dctx->dictBase = mmap( NULL, dctx->dictLength, PROT_READ, + MAP_PRIVATE, fileno(dictF), 0 ); + } else { + dctx->dictBase = XP_MALLOC( dctx->super.mpool, dctx->dictLength ); + if ( dctx->dictLength != fread( dctx->dictBase, 1, + dctx->dictLength, dictF ) ) { + XP_ASSERT( 0 ); + } + } + fclose( dictF ); + } + + const XP_U8* ptr = dctx->dictBase; + const XP_U8* end = ptr + dctx->dictLength; + formatOk = parseCommon( &dctx->super, NULL, &ptr, end ); + /* && loadSpecialData( &dctx->super, &ptr, end ); */ + + if ( formatOk ) { + size_t curPos = ptr - dctx->dictBase; + size_t dictLength = dctx->dictLength - curPos; + + if ( dictLength > 0 ) { + memcpy( &topOffset, ptr, sizeof(topOffset) ); + /* it's in big-endian order */ + topOffset = ntohl(topOffset); + dictLength -= sizeof(topOffset); /* first four bytes are offset */ + ptr += sizeof(topOffset); + } + + XP_U32 numEdges; + if ( dictLength > 0 ) { + numEdges = dictLength / dctx->super.nodeSize; +#ifdef DEBUG + XP_ASSERT( (dictLength % dctx->super.nodeSize) == 0 ); + dctx->super.numEdges = numEdges; +#endif + dctx->super.base = (array_edge*)ptr; + + dctx->super.topEdge = dctx->super.base + topOffset; + } else { + dctx->super.base = NULL; + dctx->super.topEdge = NULL; + numEdges = 0; + } + + dctx->super.name = copyString( dctx->super.mpool, path ); + + if ( ! checkSanity( &dctx->super, numEdges ) ) { + goto closeAndExit; + } + } + goto ok; + + closeAndExit: + formatOk = XP_FALSE; + ok: + + LOG_RETURNF( "%d", formatOk ); + return formatOk; +} /* initFromDictFile */ + +void +dict_splitFaces( DictionaryCtxt* dict, XWEnv XP_UNUSED(xwe), const XP_U8* utf8, + XP_U16 nBytes, XP_U16 nFaces ) +{ + XP_UCHAR* faces = XP_MALLOC( dict->mpool, nBytes + nFaces ); + const XP_UCHAR** ptrs = XP_MALLOC( dict->mpool, nFaces * sizeof(ptrs[0])); + XP_U16 ii; + XP_Bool isUTF8 = dict->isUTF8; + XP_UCHAR* next = faces; + const XP_U8* bytesIn = utf8; + const XP_U8* bytesEnd = bytesIn + nBytes; + + for ( ii = 0; ii < nFaces; ++ii ) { + ptrs[ii] = next; + if ( isUTF8 ) { + for ( ; ; ) { + const XP_U8* cp = bytesIn + 1; // g_utf8_offset_to_pointer( bytesIn, 1 ); + size_t len = cp - bytesIn; + XP_MEMCPY( next, bytesIn, len ); + next += len; + bytesIn += len; + if ( bytesIn >= bytesEnd || SYNONYM_DELIM != bytesIn[0] ) { + break; + } + ++bytesIn; /* skip delimiter */ + *next++ = '\0'; + } + } else { + XP_ASSERT( 0 == *bytesIn ); + ++bytesIn; /* skip empty */ + *next++ = *bytesIn++; + } + XP_ASSERT( next < faces + nFaces + nBytes ); + *next++ = '\0'; + } + XP_ASSERT( !dict->faces ); + dict->faces = faces; + dict->facesEnd = faces + nFaces + nBytes; + XP_ASSERT( !dict->facePtrs ); + dict->facePtrs = ptrs; + + for ( int ii = 0; ii < nFaces; ++ii ) { + XP_LOGFF( "face %d: %s", ii, dict->facePtrs[ii] ); + } +} /* dict_splitFaces */ + +void +computeChecksum( DictionaryCtxt* dctx, XWEnv xwe, const XP_U8* ptr, + XP_U32 len, XP_UCHAR* out ) +{ + *out = '\0'; +} + +DictionaryCtxt* +wasm_load_dict( MPFORMAL_NOCOMMA ) +{ + LOG_FUNC(); + + WasmDictionaryCtxt* wdctxt = XP_MALLOC( mpool, sizeof(*wdctxt) ); + dict_super_init( mpool, &wdctxt->super ); + wdctxt->useMMap = XP_TRUE; + + initFromDictFile( wdctxt, DICTNAME ); + + return &wdctxt->super; +} diff --git a/xwords4/wasm/wasmdict.h b/xwords4/wasm/wasmdict.h new file mode 100644 index 000000000..ffbbd109b --- /dev/null +++ b/xwords4/wasm/wasmdict.h @@ -0,0 +1,9 @@ + +#include "dictnry.h" + +#ifndef _WASMDICT_H_ +#define _WASMDICT_H_ + +DictionaryCtxt* wasm_load_dict( MPFORMAL_NOCOMMA ); + +#endif diff --git a/xwords4/wasm/wasmdraw.c b/xwords4/wasm/wasmdraw.c new file mode 100644 index 000000000..8b63c18e9 --- /dev/null +++ b/xwords4/wasm/wasmdraw.c @@ -0,0 +1,298 @@ +#include + +#include "comtypes.h" +#include "wasmdraw.h" + +#define COLOR_BACK 255, 255, 255 +#define COLOR_BLACK 0, 0, 0 + +typedef struct _WasmDrawCtx { + DrawCtxVTable* vtable; + SDL_Renderer* renderer; +} WasmDrawCtx; + +static int sBonusColors[4][3] = { + {0x00, 0xFF, 0x80}, + {0x00, 0x80, 0xFF}, + {0x80, 0x00, 0xFF}, + {0xFF, 0x80, 0x00}, +}; + +static void +clearRect( WasmDrawCtx* wdctx, const XP_Rect* rect ) +{ + SDL_Rect sdl_rect = { .x = rect->left, + .y = rect->top, + .w = rect->width, + .h = rect->height, + }; + SDL_SetRenderDrawColor( wdctx->renderer, COLOR_BACK, 255 ); + SDL_RenderFillRect( wdctx->renderer, &sdl_rect ); +} + +static void +fillRect( WasmDrawCtx* wdctx, const XP_Rect* rect, int colorParts[] ) +{ + SDL_Rect sdl_rect = { .x = rect->left, + .y = rect->top, + .w = rect->width, + .h = rect->height, + }; + SDL_SetRenderDrawColor( wdctx->renderer, colorParts[0], colorParts[1], + colorParts[2], 255 ); + SDL_RenderFillRect( wdctx->renderer, &sdl_rect ); +} + +static void +frameRect( WasmDrawCtx* wdctx, const XP_Rect* rect ) +{ + SDL_Rect sdl_rect = { .x = rect->left, + .y = rect->top, + .w = rect->width, + .h = rect->height, + }; + SDL_SetRenderDrawColor( wdctx->renderer, COLOR_BLACK, 255 ); + SDL_RenderDrawRect( wdctx->renderer, &sdl_rect ); +} + +static void +wasm_draw_dictChanged( DrawCtx* dctx, XWEnv xwe, XP_S16 playerNum, + const DictionaryCtxt* dict ) +{ + LOG_FUNC(); +} + +static XP_Bool +wasm_draw_beginDraw( DrawCtx* dctx, XWEnv xwe ) +{ + LOG_FUNC(); + return XP_TRUE; +} + +static void +wasm_draw_destroyCtxt( DrawCtx* dctx, XWEnv xwe ) +{ + LOG_FUNC(); +} + +static void +wasm_draw_endDraw( DrawCtx* dctx, XWEnv xwe ) +{ + LOG_FUNC(); +} + +static XP_Bool +wasm_draw_boardBegin( DrawCtx* dctx, XWEnv xwe, + const XP_Rect* rect, + XP_U16 hScale, XP_U16 vScale, + DrawFocusState dfs ) +{ + LOG_FUNC(); + /* WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx; */ + /* SDL_SetRenderDrawColor( wdctx->renderer, 255, 0, 0, 0 ); */ + return XP_TRUE; +} + +static void +wasm_draw_objFinished( DrawCtx* dctx, XWEnv xwe, BoardObjectType typ, + const XP_Rect* rect, + DrawFocusState dfs ){ LOG_FUNC(); } + +static XP_Bool +wasm_draw_vertScrollBoard(DrawCtx* dctx, XWEnv xwe, XP_Rect* rect, + XP_S16 dist, DrawFocusState dfs ) +{ + LOG_FUNC(); + return XP_FALSE; +} + +static XP_Bool +wasm_draw_trayBegin( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect, + XP_U16 owner, XP_S16 score, + DrawFocusState dfs ) +{ + LOG_FUNC(); + return XP_TRUE; +} + +static XP_Bool +wasm_draw_scoreBegin( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect, + XP_U16 numPlayers, + const XP_S16* const scores, + XP_S16 remCount, DrawFocusState dfs ) +{ + LOG_FUNC(); + return XP_TRUE; +} + +static XP_Bool +wasm_draw_measureRemText( DrawCtx* dctx, XWEnv xwe, const XP_Rect* r, + XP_S16 nTilesLeft, + XP_U16* width, XP_U16* height ) +{ + LOG_FUNC(); + return XP_FALSE; +} + +static void +wasm_draw_drawRemText( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rInner, + const XP_Rect* rOuter, + XP_S16 nTilesLeft, XP_Bool focussed ) +{ + LOG_FUNC(); +} + +static void +wasm_draw_measureScoreText( DrawCtx* dctx, XWEnv xwe, + const XP_Rect* r, + const DrawScoreInfo* dsi, + XP_U16* width, XP_U16* height ){ LOG_FUNC(); } +static void +wasm_draw_score_drawPlayer( DrawCtx* dctx, XWEnv xwe, + const XP_Rect* rInner, + const XP_Rect* rOuter, + XP_U16 gotPct, + const DrawScoreInfo* dsi ){ LOG_FUNC(); } +static void +wasm_draw_score_pendingScore( DrawCtx* dctx, XWEnv xwe, + const XP_Rect* rect, + XP_S16 score, + XP_U16 playerNum, + XP_Bool curTurn, + CellFlags flags ){ LOG_FUNC(); } + +static void +wasm_draw_drawTimer( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect, + XP_U16 player, XP_S16 secondsLeft, + XP_Bool turnDone ){ LOG_FUNC(); } + +static XP_Bool +wasm_draw_drawCell( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect, + /* at least one of these two will be + null */ + const XP_UCHAR* text, + const XP_Bitmaps* bitmaps, + Tile tile, XP_U16 value, + XP_S16 owner, /* -1 means don't use */ + XWBonusType bonus, HintAtts hintAtts, + CellFlags flags ) +{ + WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx; + if ( BONUS_NONE == bonus ) { + clearRect( wdctx, rect ); + } else { + fillRect( wdctx, rect, sBonusColors[bonus-1] ); + } + frameRect( wdctx, rect ); + + return XP_TRUE; +} + +static void +wasm_draw_invertCell( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect ) +{ + LOG_FUNC(); +} + +static XP_Bool +wasm_draw_drawTile( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect, + /* at least 1 of these 2 will be + null*/ + const XP_UCHAR* text, + const XP_Bitmaps* bitmaps, + XP_U16 val, CellFlags flags ) +{ + XP_LOGFF( "(text=%s)", text ); + WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx; + clearRect( wdctx, rect ); + frameRect( wdctx, rect ); + return XP_TRUE; +} + +#ifdef POINTER_SUPPORT +static XP_Bool +wasm_draw_drawTileMidDrag( DrawCtx* dctx, XWEnv xwe, + const XP_Rect* rect, + /* at least 1 of these 2 will + be null*/ + const XP_UCHAR* text, + const XP_Bitmaps* bitmaps, + XP_U16 val, XP_U16 owner, + CellFlags flags ) +{ + LOG_FUNC(); + return XP_TRUE; +} +#endif + +static XP_Bool +wasm_draw_drawTileBack( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect, + CellFlags flags ) +{ + LOG_FUNC(); + return XP_TRUE; +} + +static void +wasm_draw_drawTrayDivider( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect, + CellFlags flags ) +{ + LOG_FUNC(); +} + +static void +wasm_draw_clearRect( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect ) +{ + WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx; + clearRect( wdctx, rect ); +} + +static void +wasm_draw_drawBoardArrow ( DrawCtx* dctx, XWEnv xwe, + const XP_Rect* rect, + XWBonusType bonus, XP_Bool vert, + HintAtts hintAtts, CellFlags flags) +{ + LOG_FUNC(); +} + +DrawCtx* +wasm_draw_make( MPFORMAL SDL_Renderer* renderer ) +{ + WasmDrawCtx* dctx = XP_MALLOC( mpool, sizeof(*dctx) ); + dctx->renderer = renderer; + + dctx->vtable = XP_MALLOC( mpool, sizeof(*dctx->vtable) ); + + SET_VTABLE_ENTRY( dctx->vtable, draw_clearRect, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_dictChanged, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_beginDraw, wasm ); + + SET_VTABLE_ENTRY( dctx->vtable, draw_clearRect, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_dictChanged, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_beginDraw, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_destroyCtxt, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_endDraw, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_boardBegin, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_objFinished, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_vertScrollBoard, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_trayBegin, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_scoreBegin, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_measureRemText, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_drawRemText, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_measureScoreText, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_score_drawPlayer, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_score_pendingScore, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_drawTimer, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_drawCell, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_invertCell, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_drawTile, wasm ); +#ifdef POINTER_SUPPORT + SET_VTABLE_ENTRY( dctx->vtable, draw_drawTileMidDrag, wasm ); +#endif + SET_VTABLE_ENTRY( dctx->vtable, draw_drawTileBack, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_drawTrayDivider, wasm ); + SET_VTABLE_ENTRY( dctx->vtable, draw_drawBoardArrow, wasm ); + + return (DrawCtx*)dctx; +} diff --git a/xwords4/wasm/wasmdraw.h b/xwords4/wasm/wasmdraw.h new file mode 100644 index 000000000..8503a62e8 --- /dev/null +++ b/xwords4/wasm/wasmdraw.h @@ -0,0 +1,5 @@ + + +#include "draw.h" + +DrawCtx* wasm_draw_make(); diff --git a/xwords4/wasm/wasmdutil.c b/xwords4/wasm/wasmdutil.c new file mode 100644 index 000000000..8f92c9cad --- /dev/null +++ b/xwords4/wasm/wasmdutil.c @@ -0,0 +1,170 @@ +#include + +#include "wasmdutil.h" +#include "dbgutil.h" + +static XP_U32 +wasm_dutil_getCurSeconds( XW_DUtilCtxt* XP_UNUSED(duc), XWEnv XP_UNUSED(xwe) ) +{ + LOG_FUNC(); + return (XP_U32)time(NULL);//tv.tv_sec; +} + +static const XP_UCHAR* +wasm_dutil_getUserString( XW_DUtilCtxt* duc, XWEnv xwe, XP_U16 code ) +{ + LOG_FUNC(); + return "a string"; +} + +static const XP_UCHAR* +wasm_dutil_getUserQuantityString( XW_DUtilCtxt* duc, XWEnv xwe, XP_U16 code, + XP_U16 quantity ) +{ + LOG_FUNC(); + return NULL; +} + +static void +wasm_dutil_storeStream( XW_DUtilCtxt* duc, XWEnv xwe, const XP_UCHAR* key, + XWStreamCtxt* data ) +{ + LOG_FUNC(); +} + +static void +wasm_dutil_loadStream( XW_DUtilCtxt* duc, XWEnv xwe, const XP_UCHAR* key, + const XP_UCHAR* keySuffix, XWStreamCtxt* inOut ) +{ + LOG_FUNC(); +} + +static void +wasm_dutil_storePtr( XW_DUtilCtxt* duc, XWEnv xwe, const XP_UCHAR* key, + const void* data, XP_U16 len ) +{ + LOG_FUNC(); +} + +static void +wasm_dutil_loadPtr( XW_DUtilCtxt* duc, XWEnv xwe, const XP_UCHAR* key, + const XP_UCHAR* keySuffix, void* data, XP_U16* lenp ) +{ + LOG_FUNC(); +} + +static const XP_UCHAR* +wasm_dutil_getDevID( XW_DUtilCtxt* duc, XWEnv XP_UNUSED(xwe), DevIDType* typ ) +{ + LOG_FUNC(); + return NULL; +} + +static void +wasm_dutil_deviceRegistered( XW_DUtilCtxt* duc, XWEnv XP_UNUSED(xwe), DevIDType typ, + const XP_UCHAR* idRelay ) +{ + LOG_FUNC(); +} + +static XP_UCHAR* +wasm_dutil_md5sum( XW_DUtilCtxt* duc, XWEnv xwe, const XP_U8* ptr, + XP_U16 len ) +{ + LOG_FUNC(); + return NULL; +} + +static void +wasm_dutil_notifyPause( XW_DUtilCtxt* XP_UNUSED(duc), XWEnv XP_UNUSED(xwe), + XP_U32 XP_UNUSED_DBG(gameID), + DupPauseType XP_UNUSED_DBG(pauseTyp), + XP_U16 XP_UNUSED_DBG(pauser), + const XP_UCHAR* XP_UNUSED_DBG(name), + const XP_UCHAR* XP_UNUSED_DBG(msg) ) +{ + LOG_FUNC(); +} + +static void +wasm_dutil_onDupTimerChanged( XW_DUtilCtxt* XP_UNUSED(duc), XWEnv XP_UNUSED(xwe), + XP_U32 XP_UNUSED_DBG(gameID), + XP_U32 XP_UNUSED_DBG(oldVal), + XP_U32 XP_UNUSED_DBG(newVal) ) +{ + LOG_FUNC(); +} + +static void +wasm_dutil_onInviteReceived( XW_DUtilCtxt* duc, XWEnv XP_UNUSED(xwe), + const NetLaunchInfo* nli ) +{ + LOG_FUNC(); +} + +static void +wasm_dutil_onMessageReceived( XW_DUtilCtxt* duc, XWEnv XP_UNUSED(xwe), + XP_U32 gameID, const CommsAddrRec* from, + XWStreamCtxt* stream ) +{ + LOG_FUNC(); +} + +static void +wasm_dutil_onGameGoneReceived( XW_DUtilCtxt* duc, XWEnv XP_UNUSED(xwe), + XP_U32 gameID, const CommsAddrRec* from ) +{ + LOG_FUNC(); +} + +XW_DUtilCtxt* +wasm_dutil_make( MPFORMAL VTableMgr* vtMgr, void* closure ) +{ + XW_DUtilCtxt* result = XP_CALLOC( mpool, sizeof(*result) ); + + dutil_super_init( MPPARM(mpool) result ); + + result->vtMgr = vtMgr; + result->closure = closure; + +# define SET_PROC(nam) \ + result->vtable.m_dutil_ ## nam = wasm_dutil_ ## nam; + + SET_PROC(getCurSeconds); + SET_PROC(getUserString); + SET_PROC(getUserQuantityString); + SET_PROC(storeStream); + SET_PROC(loadStream); + SET_PROC(storePtr); + SET_PROC(loadPtr); + +#ifdef XWFEATURE_SMS + SET_PROC(phoneNumbersSame); +#endif + +#ifdef XWFEATURE_DEVID + SET_PROC(getDevID); + SET_PROC(deviceRegistered); +#endif + +#ifdef COMMS_CHECKSUM + SET_PROC(md5sum); +#endif + + SET_PROC(notifyPause); + SET_PROC(onDupTimerChanged); + SET_PROC(onInviteReceived); + SET_PROC(onMessageReceived); + SET_PROC(onGameGoneReceived); + +# undef SET_PROC + + assertTableFull( &result->vtable, sizeof(result->vtable), "wasmutil" ); + + return result; +} + +void +wasm_dutil_destroy( XW_DUtilCtxt* dutil ) +{ +} diff --git a/xwords4/wasm/wasmdutil.h b/xwords4/wasm/wasmdutil.h new file mode 100644 index 000000000..faf50fa48 --- /dev/null +++ b/xwords4/wasm/wasmdutil.h @@ -0,0 +1,13 @@ + +#ifndef _WASMDUTIL_H_ +#define _WASMDUTIL_H_ + +#include + +#include "dutil.h" +#include "mempool.h" + +XW_DUtilCtxt* wasm_dutil_make( MPFORMAL VTableMgr* vtMgr, void* closure ); +void wasm_dutil_destroy( XW_DUtilCtxt* dutil ); + +#endif diff --git a/xwords4/wasm/wasmutil.c b/xwords4/wasm/wasmutil.c new file mode 100644 index 000000000..6d9ab557a --- /dev/null +++ b/xwords4/wasm/wasmutil.c @@ -0,0 +1,333 @@ + +#include "util.h" +#include "comtypes.h" + +typedef struct _WasmUtilCtx { + XW_UtilCtxt super; + + XW_DUtilCtxt* dctxt; +} WasmUtilCtx; + +static XWStreamCtxt* +wasm_util_makeStreamFromAddr(XW_UtilCtxt* uc, XWEnv xwe, + XP_PlayerAddr channelNo ) +{ + LOG_FUNC(); + return NULL; +} + +static XWBonusType +wasm_util_getSquareBonus( XW_UtilCtxt* uc, XWEnv xwe, XP_U16 boardSize, + XP_U16 col, XP_U16 row ) +{ +#define BONUS_DIM 8 + static const int s_buttsBoard[BONUS_DIM][BONUS_DIM] = { + { BONUS_TRIPLE_WORD, BONUS_NONE, BONUS_NONE,BONUS_DOUBLE_LETTER,BONUS_NONE,BONUS_NONE,BONUS_NONE,BONUS_TRIPLE_WORD }, + { BONUS_NONE, BONUS_DOUBLE_WORD, BONUS_NONE,BONUS_NONE,BONUS_NONE,BONUS_TRIPLE_LETTER,BONUS_NONE,BONUS_NONE }, + + { BONUS_NONE, BONUS_NONE, BONUS_DOUBLE_WORD,BONUS_NONE,BONUS_NONE,BONUS_NONE,BONUS_DOUBLE_LETTER,BONUS_NONE }, + { BONUS_DOUBLE_LETTER,BONUS_NONE, BONUS_NONE,BONUS_DOUBLE_WORD,BONUS_NONE,BONUS_NONE,BONUS_NONE,BONUS_DOUBLE_LETTER }, + + { BONUS_NONE, BONUS_NONE, BONUS_NONE,BONUS_NONE,BONUS_DOUBLE_WORD,BONUS_NONE,BONUS_NONE,BONUS_NONE }, + { BONUS_NONE, BONUS_TRIPLE_LETTER,BONUS_NONE,BONUS_NONE,BONUS_NONE,BONUS_TRIPLE_LETTER,BONUS_NONE,BONUS_NONE }, + + { BONUS_NONE, BONUS_NONE, BONUS_DOUBLE_LETTER,BONUS_NONE,BONUS_NONE,BONUS_NONE,BONUS_DOUBLE_LETTER,BONUS_NONE }, + { BONUS_TRIPLE_WORD, BONUS_NONE, BONUS_NONE,BONUS_DOUBLE_LETTER,BONUS_NONE,BONUS_NONE,BONUS_NONE,BONUS_DOUBLE_WORD }, + }; /* buttsBoard */ + + int half = boardSize / 2; + if ( col > half ) { col = (half*2) - col; } + if ( row > half ) { row = (half*2) - row; } + XP_ASSERT( col < BONUS_DIM && row < BONUS_DIM ); + return s_buttsBoard[row][col]; +} + +static void +wasm_util_userError( XW_UtilCtxt* uc, XWEnv xwe, UtilErrID id ) +{ + LOG_FUNC(); +} + +static void +wasm_util_notifyMove( XW_UtilCtxt* uc, XWEnv xwe, XWStreamCtxt* stream ) +{ + LOG_FUNC(); +} + +static void +wasm_util_notifyTrade( XW_UtilCtxt* uc, XWEnv xwe, const XP_UCHAR** tiles, + XP_U16 nTiles ) +{ + LOG_FUNC(); +} +static void +wasm_util_notifyPickTileBlank( XW_UtilCtxt* uc, XWEnv xwe, XP_U16 playerNum, + XP_U16 col, XP_U16 row, + const XP_UCHAR** tileFaces, + XP_U16 nTiles ) +{ + LOG_FUNC(); +} + +static void +wasm_util_informNeedPickTiles( XW_UtilCtxt* uc, XWEnv xwe, XP_Bool isInitial, + XP_U16 player, XP_U16 nToPick, + XP_U16 nFaces, const XP_UCHAR** faces, + const XP_U16* counts ) +{ + LOG_FUNC(); +} + +static void +wasm_util_informNeedPassword( XW_UtilCtxt* uc, XWEnv xwe, XP_U16 playerNum, + const XP_UCHAR* name ) +{ + LOG_FUNC(); +} + +static void +wasm_util_trayHiddenChange(XW_UtilCtxt* uc, XWEnv xwe, + XW_TrayVisState newState, + XP_U16 nVisibleRows ) +{ + LOG_FUNC(); +} + +static void +wasm_util_yOffsetChange( XW_UtilCtxt* uc, XWEnv xwe, XP_U16 maxOffset, + XP_U16 oldOffset, XP_U16 newOffset ) +{ + LOG_FUNC(); +} + +static void +wasm_util_turnChanged(XW_UtilCtxt* uc, XWEnv xwe, XP_S16 newTurn) +{ + LOG_FUNC(); +} + +static void +wasm_util_notifyDupStatus( XW_UtilCtxt* uc, XWEnv xwe, XP_Bool amHost, + const XP_UCHAR* msg ) +{ + LOG_FUNC(); +} + +static void +wasm_util_informMove( XW_UtilCtxt* uc, XWEnv xwe, XP_S16 turn, + XWStreamCtxt* expl, XWStreamCtxt* words ) +{ + LOG_FUNC(); +} + +static void +wasm_util_informUndo( XW_UtilCtxt* uc, XWEnv xwe ) +{ + LOG_FUNC(); +} + +static void +wasm_util_informNetDict( XW_UtilCtxt* uc, XWEnv xwe, XP_LangCode lang, + const XP_UCHAR* oldName, + const XP_UCHAR* newName, + const XP_UCHAR* newSum, + XWPhoniesChoice phoniesAction ) +{ + LOG_FUNC(); +} + +static void +wasm_util_notifyGameOver( XW_UtilCtxt* uc, XWEnv xwe, XP_S16 quitter ) +{ + LOG_FUNC(); +} + +static XP_Bool wasm_util_engineProgressCallback( XW_UtilCtxt* uc, XWEnv xwe ) +{ + LOG_FUNC(); + return XP_FALSE; +} + +static void +wasm_util_setTimer( XW_UtilCtxt* uc, XWEnv xwe, XWTimerReason why, XP_U16 when, + XWTimerProc proc, void* closure ) +{ + LOG_FUNC(); +} + +static void +wasm_util_clearTimer( XW_UtilCtxt* uc, XWEnv xwe, XWTimerReason why ) +{ + LOG_FUNC(); +} + +static void +wasm_util_requestTime( XW_UtilCtxt* uc, XWEnv xwe ) +{ + LOG_FUNC(); +} + +static XP_Bool +wasm_util_altKeyDown( XW_UtilCtxt* uc, XWEnv xwe ) +{ + LOG_FUNC(); + return XP_FALSE; +} + +static DictionaryCtxt* +wasm_util_makeEmptyDict( XW_UtilCtxt* uc, XWEnv xwe ) +{ + LOG_FUNC(); + return NULL; +} + +static void +wasm_util_notifyIllegalWords( XW_UtilCtxt* uc, XWEnv xwe, BadWordInfo* bwi, + XP_U16 turn, XP_Bool turnLost ) +{ + LOG_FUNC(); +} + +static void +wasm_util_remSelected(XW_UtilCtxt* uc, XWEnv xwe) +{ + LOG_FUNC(); +} + +static void +wasm_util_timerSelected(XW_UtilCtxt* uc, XWEnv xwe, XP_Bool inDuplicateMode, + XP_Bool canPause) +{ + LOG_FUNC(); +} + +static void +wasm_util_formatPauseHistory( XW_UtilCtxt* uc, XWEnv xwe, XWStreamCtxt* stream, + DupPauseType typ, XP_S16 turn, + XP_U32 secsPrev, XP_U32 secsCur, + const XP_UCHAR* msg ) +{ + LOG_FUNC(); +} + +#ifdef XWFEATURE_BOARDWORDS +static void +wasm_util_cellSquareHeld( XW_UtilCtxt* uc, XWEnv xwe, XWStreamCtxt* words ) +{ + LOG_FUNC(); +} +#endif + +static void +wasm_util_informMissing(XW_UtilCtxt* uc, XWEnv xwe, XP_Bool isServer, + const CommsAddrRec* addr, XP_U16 nDevs, + XP_U16 nMissing ) +{ + LOG_FUNC(); +} + +static void +wasm_util_addrChange( XW_UtilCtxt* uc, XWEnv xwe, const CommsAddrRec* oldAddr, + const CommsAddrRec* newAddr ) +{ + LOG_FUNC(); +} + +static void +wasm_util_informWordsBlocked( XW_UtilCtxt* uc, XWEnv xwe, XP_U16 nBadWords, + XWStreamCtxt* words, const XP_UCHAR* dictName ) +{ + LOG_FUNC(); +} + +#ifdef XWFEATURE_SEARCHLIMIT +static XP_Bool +wasm_util_getTraySearchLimits( XW_UtilCtxt* uc, XWEnv xwe, + XP_U16* min, XP_U16* max ) +{ + LOG_FUNC(); +} +#endif + +static void +wasm_util_showChat( XW_UtilCtxt* uc, XWEnv xwe, const XP_UCHAR* const msg, + XP_S16 from, XP_U32 timestamp ) +{ + LOG_FUNC(); +} + +static XW_DUtilCtxt* +wasm_util_getDevUtilCtxt( XW_UtilCtxt* uc, XWEnv xwe ) +{ + LOG_FUNC(); + WasmUtilCtx* wuctxt = (WasmUtilCtx*)uc; + LOG_RETURNF( "%p", wuctxt->dctxt ); + return wuctxt->dctxt; +} + +XW_UtilCtxt* +wasm_util_make( MPFORMAL CurGameInfo* gi, XW_DUtilCtxt* dctxt ) +{ + LOG_FUNC(); + WasmUtilCtx* wuctxt = XP_MALLOC( mpool, sizeof(*wuctxt) ); + wuctxt->super.vtable = XP_MALLOC( mpool, sizeof(*wuctxt->super.vtable) ); + wuctxt->super.mpool = mpool; + wuctxt->super.gameInfo = gi; + + wuctxt->dctxt = dctxt; + + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_userError, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_makeStreamFromAddr, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_getSquareBonus, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_userError, wasm ); + + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_notifyMove, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_notifyTrade, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_notifyPickTileBlank, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_informNeedPickTiles, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_informNeedPassword, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_trayHiddenChange, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_yOffsetChange, wasm ); +#ifdef XWFEATURE_TURNCHANGENOTIFY + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_turnChanged, wasm ); +#endif + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_notifyDupStatus, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_informMove, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_informUndo, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_informNetDict, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_notifyGameOver, wasm ); +#ifdef XWFEATURE_HILITECELL + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_hiliteCell, wasm ); +#endif + + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_setTimer, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_clearTimer, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_requestTime, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_altKeyDown, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_makeEmptyDict, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_notifyIllegalWords, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_remSelected, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_timerSelected, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_formatPauseHistory, wasm ); +#ifdef XWFEATURE_BOARDWORDS + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_cellSquareHeld, wasm ); +#endif + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_informMissing, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_addrChange, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_informWordsBlocked, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_showChat, wasm ); + SET_VTABLE_ENTRY( wuctxt->super.vtable, util_getDevUtilCtxt, wasm ); + + LOG_RETURNF( "%p", wuctxt ); + return (XW_UtilCtxt*)wuctxt; +} + +void +wasm_util_destroy( XW_UtilCtxt* util ) +{ + LOG_FUNC(); + XP_ASSERT(0); + WasmUtilCtx* wuctxt = (WasmUtilCtx*)util; + XP_FREEP( wuctxt->super.mpool, &wuctxt->super.vtable ); + XP_FREEP( wuctxt->super.mpool, &wuctxt ); +} diff --git a/xwords4/wasm/wasmutil.h b/xwords4/wasm/wasmutil.h new file mode 100644 index 000000000..ad32abf58 --- /dev/null +++ b/xwords4/wasm/wasmutil.h @@ -0,0 +1,10 @@ + +#ifndef _WASMUTIL_H_ +#define _WASMUTIL_H_ + +#include "dutil.h" + +XW_UtilCtxt* wasm_util_make( MPFORMAL CurGameInfo* gi, XW_DUtilCtxt* dutil ); +void wasm_util_destroy( XW_UtilCtxt* util ); + +#endif diff --git a/xwords4/wasm/xptypes.h b/xwords4/wasm/xptypes.h new file mode 100644 index 000000000..0289d235a --- /dev/null +++ b/xwords4/wasm/xptypes.h @@ -0,0 +1,106 @@ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wasmutls.h" + +typedef bool XP_Bool; + +typedef int8_t XP_S8; +typedef uint8_t XP_U8; +typedef int16_t XP_S16; +typedef uint16_t XP_U16; +typedef int32_t XP_S32; +typedef uint32_t XP_U32; + +typedef char XP_UCHAR; + +typedef void* XWEnv; + +#define XP_TRUE ((XP_Bool)(1==1)) +#define XP_FALSE ((XP_Bool)(1==0)) + + + +#define XP_MEMSET(src, val, nbytes) memset( (src), (val), (nbytes) ) +#define XP_MEMCPY(d,s,l) memcpy((d),(s),(l)) +#define XP_MEMMOVE(d,s,l) memmove((d),(s),(l)) +#define XP_MEMCMP( a1, a2, l ) memcmp((a1),(a2),(l)) +#define XP_STRLEN(s) strlen(s) +#define XP_STRCAT(d,s) strcat((d),(s)) +#define XP_STRNCMP(s1,s2,len) strncmp((s1),(s2),(len)) +#define XP_STRNCPY(s1,s2,len) strncpy((s1),(s2),(len)) +#define XP_STRCMP(s1,s2) strcmp((s1),(s2)) + +#ifdef MEM_DEBUG + +# define XP_PLATMALLOC(nbytes) malloc(nbytes) +# define XP_PLATREALLOC(p,s) realloc((p),(s)) +# define XP_PLATFREE(p) free(p) + +#else + +# define XP_MALLOC(pool,nbytes) malloc(nbytes) +# define XP_CALLOC(pool,nbytes) calloc(1,nbytes) +# define XP_REALLOC(pool,p,s) realloc((p),(s)) +# define XP_FREE(pool,p) free(p) +void linux_freep( void** ptrp ); +# define XP_FREEP(pool,p) linux_freep((void**)p) +#endif + +#ifdef DEBUG +extern void linux_debugf(const char*, ...) + __attribute__ ((format (printf, 1, 2))); +# define XP_DEBUGF(...) wasm_debugf(__VA_ARGS__) + +extern void linux_debugff(const char* func, const char* file, const char* fmt, ...) + __attribute__ ((format (printf, 3, 4))); +# define XP_LOGFF( FMT, ... ) \ + wasm_debugff( __func__, __FILE__, FMT, ##__VA_ARGS__ ) +#define XP_LOG(STR) \ + wasm_debugff( __func__, __FILE__, "%s", STR ) + +#else +# define XP_DEBUGF(ch,...) +# define XP_LOGFF(fmt,...) +# define XP_LOG(fmt) +#endif + +#ifdef DEBUG +# define XP_ASSERT(B) do { if (!(B)) { XP_LOGFF( "firing assert"); } assert(B); } while (0) +void linux_backtrace( void ); +# define XP_BACKTRACE linux_backtrace +#else +# define XP_ASSERT(b) +# define XP_BACKTRACE +#endif + +#define XP_STATUSF XP_DEBUGF +#define XP_LOGF XP_DEBUGF +#define XP_SNPRINTF snprintf +#define XP_WARNF XP_DEBUGF + +#define XP_L(s) s +#define XP_S XP_L("%s") +#define XP_CR XP_L("\n") + +#define XP_RANDOM() random() + +#define XP_NTOHL(l) ntohl(l) +#define XP_NTOHS(s) ntohs(s) +#define XP_HTONL(l) htonl(l) +#define XP_HTONS(s) htons(s) + +#define XP_MIN(a,b) ((a)<(b)?(a):(b)) +#define XP_MAX(a,b) ((a)>(b)?(a):(b)) +#define XP_ABS(a) ((a)>=0?(a):-(a)) + +#define XP_LD "%d" +#define XP_P "%p"