diff --git a/xwords4/common/model.c b/xwords4/common/model.c index a6a946922..e1c85902b 100644 --- a/xwords4/common/model.c +++ b/xwords4/common/model.c @@ -173,6 +173,42 @@ model_writeToStream( ModelCtxt* model, XWStreamCtxt* stream ) } /* model_writeToStream */ #ifdef TEXT_MODEL +#include +#include + +# define EMPTY_CHAR '.' +void +model_setFromTextStream( ModelCtxt* model, XWStreamCtxt* stream ) +{ + const DictionaryCtxt* dict = model_getDictionary( model ); + XP_U16 col, row; + + for ( row = 0; row < model->nRows; ++row ) { + for ( col = 0; col < model->nCols; ++col ) { + gchar ch = stream_getU8( stream ); + if ( EMPTY_CHAR == ch ) { + setModelTileRaw( model, col, row, TILE_EMPTY_BIT ); + } else { + XP_Bool isBlank = g_ascii_islower( ch ); + XP_UCHAR face[2] = { ch, '\0' }; + if ( isBlank ) { + XP_UPPERSTR( face ); + } + Tile tile = dict_tileForString( dict, face ); + CellTile raw = tile & TILE_VALUE_MASK; + if ( isBlank ) { + raw |= TILE_BLANK_BIT; + } + setModelTileRaw( model, col, row, raw ); + notifyBoardListeners( model, 0, col, row, XP_TRUE ); + ++model->vol.nTilesOnBoard; + /* Need to remove from pool too!!! */ + } + } + (void)stream_getU8( stream ); /* skip \n */ + } +} + void model_writeToTextStream( const ModelCtxt* model, XWStreamCtxt* stream ) { @@ -183,7 +219,7 @@ model_writeToTextStream( const ModelCtxt* model, XWStreamCtxt* stream ) XP_U16 col, row; for ( ii = 0; ii < width; ++ii ) { - empty[ii] = '.'; + empty[ii] = EMPTY_CHAR; } for ( row = 0; row < model->nRows; ++row ) { @@ -572,7 +608,7 @@ setModelTileRaw( ModelCtxt* model, XP_U16 col, XP_U16 row, CellTile tile ) XP_ASSERT( col < MAX_COLS ); XP_ASSERT( row < MAX_ROWS ); model->tiles[col][row] = tile; -} /* model_setTile */ +} /* setModelTileRaw */ static CellTile getModelTileRaw( const ModelCtxt* model, XP_U16 col, XP_U16 row ) diff --git a/xwords4/common/model.h b/xwords4/common/model.h index e0ec0d495..31d6fd7ce 100644 --- a/xwords4/common/model.h +++ b/xwords4/common/model.h @@ -111,6 +111,7 @@ void model_writeToStream( ModelCtxt* model, XWStreamCtxt* stream ); #ifdef TEXT_MODEL void model_writeToTextStream( const ModelCtxt* model, XWStreamCtxt* stream ); +void model_setFromTextStream( ModelCtxt* model, XWStreamCtxt* stream ); #endif void model_init( ModelCtxt* model, XP_U16 nCols, XP_U16 nRows ); diff --git a/xwords4/linux/gtkmain.c b/xwords4/linux/gtkmain.c index 803fbf858..589a1c94c 100644 --- a/xwords4/linux/gtkmain.c +++ b/xwords4/linux/gtkmain.c @@ -504,6 +504,15 @@ createOrLoadObjects( GtkAppGlobals* globals ) } } +#ifdef TEXT_MODEL + if ( !!params->boardFile ) { + XWStreamCtxt* stream = + streamFromFile( &globals->cGlobals, params->boardFile, globals ); + model_setFromTextStream( globals->cGlobals.game.model, stream ); + stream_destroy( stream ); + } +#endif + #ifndef XWFEATURE_STANDALONE_ONLY if ( !!globals->cGlobals.game.comms ) { comms_start( globals->cGlobals.game.comms ); diff --git a/xwords4/linux/linuxmain.c b/xwords4/linux/linuxmain.c index 9fbe9c944..578a02b49 100644 --- a/xwords4/linux/linuxmain.c +++ b/xwords4/linux/linuxmain.c @@ -272,6 +272,7 @@ typedef enum { ,CMD_CLOSESTDIN ,CMD_QUITAFTER ,CMD_BOARDSIZE + ,CMD_BOARDFILE ,CMD_HIDEVALUES ,CMD_SKIPCONFIRM ,CMD_VERTICALSCORE @@ -343,6 +344,7 @@ static CmdInfoRec CmdInfoRecs[] = { ,{ CMD_CLOSESTDIN, false, "close-stdin", "close stdin on start" } ,{ CMD_QUITAFTER, true, "quit-after", "exit seconds after game's done" } ,{ CMD_BOARDSIZE, true, "board-size", "board is by cells" } + ,{ CMD_BOARDFILE, true, "board-file", "file holding 15x15 record of model" } ,{ CMD_HIDEVALUES, false, "hide-values", "show letters, not nums, on tiles" } ,{ CMD_SKIPCONFIRM, false, "skip-confirm", "don't confirm before commit" } ,{ CMD_VERTICALSCORE, false, "vertical", "scoreboard is vertical" } @@ -1133,6 +1135,9 @@ main( int argc, char** argv ) case CMD_BOARDSIZE: mainParams.gi.boardSize = atoi(optarg); break; + case CMD_BOARDFILE: + mainParams.boardFile = optarg; + break; #ifdef XWFEATURE_BLUETOOTH case CMD_BTADDR: XP_ASSERT( conType == COMMS_CONN_NONE || diff --git a/xwords4/linux/linuxutl.c b/xwords4/linux/linuxutl.c index cf72e12a8..2cb81afff 100644 --- a/xwords4/linux/linuxutl.c +++ b/xwords4/linux/linuxutl.c @@ -421,4 +421,13 @@ linux_lowerstr( XP_UCHAR* str ) ++str; } } + +void +linux_upperstr( XP_UCHAR* str ) +{ + while ( *str ) { + *str = toupper( *str ); + ++str; + } +} #endif diff --git a/xwords4/linux/main.h b/xwords4/linux/main.h index 53ac57ee6..b872fac4a 100644 --- a/xwords4/linux/main.h +++ b/xwords4/linux/main.h @@ -79,6 +79,9 @@ typedef struct LaunchParams { #ifdef XWFEATURE_SLOW_ROBOT XP_U16 robotThinkMin, robotThinkMax; #endif +#ifdef TEXT_MODEL + char* boardFile; +#endif DeviceRole serverRole; diff --git a/xwords4/linux/xptypes.h b/xwords4/linux/xptypes.h index 075120e11..6f49e2e52 100644 --- a/xwords4/linux/xptypes.h +++ b/xwords4/linux/xptypes.h @@ -26,6 +26,7 @@ #include /* memset */ #include /* memset */ #include +#include #include #ifdef PLATFORM_GTK @@ -105,7 +106,10 @@ void linux_freep( void** ptrp ); #define XP_STRNCPY(s1,s2,len) strncpy((s1),(s2),(len)) #define XP_STRCMP(s1,s2) strcmp((s1),(s2)) void linux_lowerstr( XP_UCHAR* str ); +void linux_upperstr( XP_UCHAR* str ); #define XP_LOWERSTR(str) linux_lowerstr(str) +#define XP_UPPERSTR(str) linux_upperstr(str) +#define XP_ISLOWER( ch ) islower(ch) #define XP_RANDOM() random() #define XP_SNPRINTF snprintf