From c20e85eccdb02b17e222b5cea99f80fe330e511f Mon Sep 17 00:00:00 2001 From: ehouse Date: Fri, 18 Jul 2008 07:49:00 +0000 Subject: [PATCH] combine all per-player arrays in board into a single array of structs. access can then be via a ptr, more effecient and faster. The change seems to save 1K of generated code. No changes to algorithms, only to field access. --- xwords4/common/board.c | 193 ++++++++++++++++++++------------------ xwords4/common/boarddrw.c | 10 +- xwords4/common/boardp.h | 52 ++++++---- xwords4/common/dragdrpp.c | 13 ++- xwords4/common/scorebdp.c | 11 ++- xwords4/common/tray.c | 85 ++++++++--------- 6 files changed, 192 insertions(+), 172 deletions(-) diff --git a/xwords4/common/board.c b/xwords4/common/board.c index b1acf0453..558dcd98b 100644 --- a/xwords4/common/board.c +++ b/xwords4/common/board.c @@ -1,4 +1,4 @@ -/* -*-mode: C; fill-column: 78; c-basic-offset: 4; compile-command: "cd ../linux && make MEMDEBUG=TRUE"; -*- */ +/* -*-mode: C; fill-column: 78; compile-command: "cd ../linux && make MEMDEBUG=TRUE"; -*- */ /* * Copyright 1997 - 2008 by Eric House (xwords@eehouse.org). All rights * reserved. @@ -164,9 +164,10 @@ board_make( MPFORMAL ModelCtxt* model, ServerCtxt* server, DrawCtx* draw, /* set up some useful initial values */ XP_U16 i; for ( i = 0; i < MAX_NUM_PLAYERS; ++i ) { - result->trayCursorLoc[i] = 1; - result->bdCursor[i].col = 5; - result->bdCursor[i].row = 7; + PerTurnInfo* pti = result->pti + i; + pti->trayCursorLoc = 1; + pti->bdCursor.col = 5; + pti->bdCursor.row = 7; } } #endif @@ -209,41 +210,43 @@ board_makeFromStream( MPFORMAL XWStreamCtxt* stream, ModelCtxt* model, XP_ASSERT( !!server ); for ( i = 0; i < nPlayers; ++i ) { - BoardArrow* arrow = &board->boardArrow[i]; + PerTurnInfo* pti = &board->pti[i]; + BoardArrow* arrow = &pti->boardArrow; arrow->col = (XP_U8)stream_getBits( stream, NUMCOLS_NBITS ); arrow->row = (XP_U8)stream_getBits( stream, NUMCOLS_NBITS ); arrow->vert = (XP_Bool)stream_getBits( stream, 1 ); arrow->visible = (XP_Bool)stream_getBits( stream, 1 ); - board->dividerLoc[i] = (XP_U8)stream_getBits( stream, NTILES_NBITS ); - board->traySelBits[i] = (TileBit)stream_getBits( stream, - MAX_TRAY_TILES ); - board->tradeInProgress[i] = (XP_Bool)stream_getBits( stream, 1 ); + pti->dividerLoc = (XP_U8)stream_getBits( stream, NTILES_NBITS ); + pti->traySelBits = (TileBit)stream_getBits( stream, + MAX_TRAY_TILES ); + pti->tradeInProgress = (XP_Bool)stream_getBits( stream, 1 ); #ifdef KEYBOARD_NAV if ( version >= STREAM_VERS_KEYNAV ) { - board->bdCursor[i].col = stream_getBits( stream, 4 ); - board->bdCursor[i].row = stream_getBits( stream, 4 ); - board->trayCursorLoc[i] = stream_getBits( stream, 3 ); + pti->bdCursor.col = stream_getBits( stream, 4 ); + pti->bdCursor.row = stream_getBits( stream, 4 ); + pti->trayCursorLoc = stream_getBits( stream, 3 ); } #endif #ifdef XWFEATURE_SEARCHLIMIT if ( version >= STREAM_VERS_41B4 ) { - board->hasHintRect[i] = stream_getBits( stream, 1 ); + pti->hasHintRect = stream_getBits( stream, 1 ); } else { - board->hasHintRect[i] = XP_FALSE; + pti->hasHintRect = XP_FALSE; } - if ( board->hasHintRect[i] ) { - board->limits[i].left = stream_getBits( stream, 4 ); - board->limits[i].top = stream_getBits( stream, 4 ); - board->limits[i].right = stream_getBits( stream, 4 ); - board->limits[i].bottom = stream_getBits( stream, 4 ); + if ( pti->hasHintRect ) { + pti->limits.left = stream_getBits( stream, 4 ); + pti->limits.top = stream_getBits( stream, 4 ); + pti->limits.right = stream_getBits( stream, 4 ); + pti->limits.bottom = stream_getBits( stream, 4 ); } #endif } board->selPlayer = (XP_U8)stream_getBits( stream, PLAYERNUM_NBITS ); + board->selInfo = &board->pti[board->selPlayer]; board->trayVisState = (XW_TrayVisState)stream_getBits( stream, 2 ); XP_ASSERT( stream_getU32( stream ) == bEND ); @@ -270,28 +273,29 @@ board_writeToStream( BoardCtxt* board, XWStreamCtxt* stream ) nPlayers = board->gi->nPlayers; for ( i = 0; i < nPlayers; ++i ) { - BoardArrow* arrow = &board->boardArrow[i]; + PerTurnInfo* pti = &board->pti[i]; + BoardArrow* arrow = &pti->boardArrow; stream_putBits( stream, NUMCOLS_NBITS, arrow->col ); stream_putBits( stream, NUMCOLS_NBITS, arrow->row ); stream_putBits( stream, 1, arrow->vert ); stream_putBits( stream, 1, arrow->visible ); - stream_putBits( stream, NTILES_NBITS, board->dividerLoc[i] ); - stream_putBits( stream, MAX_TRAY_TILES, board->traySelBits[i] ); - stream_putBits( stream, 1, board->tradeInProgress[i] ); + stream_putBits( stream, NTILES_NBITS, pti->dividerLoc ); + stream_putBits( stream, MAX_TRAY_TILES, pti->traySelBits ); + stream_putBits( stream, 1, pti->tradeInProgress ); #ifdef KEYBOARD_NAV - stream_putBits( stream, 4, board->bdCursor[i].col ); - stream_putBits( stream, 4, board->bdCursor[i].row ); - stream_putBits( stream, 3, board->trayCursorLoc[i] ); + stream_putBits( stream, 4, pti->bdCursor.col ); + stream_putBits( stream, 4, pti->bdCursor.row ); + stream_putBits( stream, 3, pti->trayCursorLoc ); #endif #ifdef XWFEATURE_SEARCHLIMIT - stream_putBits( stream, 1, board->hasHintRect[i] ); - if ( board->hasHintRect[i] ) { - stream_putBits( stream, 4, board->limits[i].left ); - stream_putBits( stream, 4, board->limits[i].top ); - stream_putBits( stream, 4, board->limits[i].right ); - stream_putBits( stream, 4, board->limits[i].bottom ); + stream_putBits( stream, 1, pti->hasHintRect ); + if ( pti->hasHintRect ) { + stream_putBits( stream, 4, pti->limits.left ); + stream_putBits( stream, 4, pti->limits.top ); + stream_putBits( stream, 4, pti->limits.right ); + stream_putBits( stream, 4, pti->limits.bottom ); } #endif } @@ -314,13 +318,15 @@ board_reset( BoardCtxt* board ) /* This is appropriate for a new game *ONLY*. reset */ for ( i = 0; i < MAX_NUM_PLAYERS; ++i ) { - board->traySelBits[i] = 0; - board->tradeInProgress[i] = XP_FALSE; - board->dividerLoc[i] = 0; + PerTurnInfo* pti = &board->pti[i]; + pti->traySelBits = 0; + pti->tradeInProgress = XP_FALSE; + pti->dividerLoc = 0; + XP_MEMSET( &pti->boardArrow, 0, sizeof(pti->boardArrow) ); } - XP_MEMSET( &board->boardArrow, 0, sizeof(board->boardArrow) ); board->gameOver = XP_FALSE; board->selPlayer = 0; + board->selInfo = board->pti; board->star_row = (XP_U16)(model_numRows(board->model) / 2); newState = board->boardObscuresTray? TRAY_HIDDEN:TRAY_REVERSED; @@ -388,8 +394,7 @@ board_prefsChanged( BoardCtxt* board, CommonPrefs* cp ) } #ifdef XWFEATURE_SEARCHLIMIT - if ( !board->gi->allowHintRect - && board->hasHintRect[board->selPlayer] ) { + if ( !board->gi->allowHintRect && board->selInfo->hasHintRect ) { EngineCtxt* engine = server_getEngineFor( board->server, board->selPlayer ); @@ -470,14 +475,14 @@ board_getFocusOwner( BoardCtxt* board ) static void invalArrowCell( BoardCtxt* board ) { - BoardArrow* arrow = &board->boardArrow[board->selPlayer]; + BoardArrow* arrow = &board->selInfo->boardArrow; invalCell( board, arrow->col, arrow->row ); } /* invalArrowCell */ static void flipArrow( BoardCtxt* board ) { - BoardArrow* arrow = &board->boardArrow[board->selPlayer]; + BoardArrow* arrow = &board->selInfo->boardArrow; XP_U16 tmp = arrow->col; arrow->col = arrow->row; arrow->row = tmp; @@ -488,7 +493,7 @@ flipArrow( BoardCtxt* board ) static void invalCursorCell( BoardCtxt* board ) { - BdCursorLoc loc = board->bdCursor[board->selPlayer]; + BdCursorLoc loc = board->selInfo->bdCursor; invalCell( board, loc.col, loc.row ); } /* invalCursorCell */ #endif @@ -498,7 +503,7 @@ invalTradeWindow( BoardCtxt* board, XP_S16 turn, XP_Bool redraw ) { XP_ASSERT( turn >= 0 ); - if ( board->tradeInProgress[turn] ) { + if ( board->pti[turn].tradeInProgress ) { MiniWindowStuff* stuff = &board->miniWindowStuff[MINIWINDOW_TRADING]; invalCellsUnderRect( board, &stuff->rect ); if ( redraw ) { @@ -549,31 +554,32 @@ XP_Bool board_commitTurn( BoardCtxt* board ) { XP_Bool result = XP_FALSE; - XP_S16 turn = server_getCurrentTurn( board->server ); + const XP_S16 turn = server_getCurrentTurn( board->server ); + PerTurnInfo* pti = board->pti + turn; if ( board->gameOver || turn < 0 ) { /* do nothing */ } else if ( turn != board->selPlayer ) { - if ( board->tradeInProgress[board->selPlayer] ) { + if ( board->selInfo->tradeInProgress ) { result = exitTradeMode( board ); } else { util_userError( board->util, ERR_NOT_YOUR_TURN ); } } else if ( checkRevealTray( board ) ) { - if ( board->tradeInProgress[turn] ) { + if ( pti->tradeInProgress ) { result = XP_TRUE; /* there's at least the window to clean up after */ invalSelTradeWindow( board ); - board->tradeInProgress[turn] = XP_FALSE; + pti->tradeInProgress = XP_FALSE; if ( util_userQuery( board->util, QUERY_COMMIT_TRADE, (XWStreamCtxt*)NULL ) ) { result = server_commitTrade( board->server, - board->traySelBits[turn] ); + pti->traySelBits ); /* XP_DEBUGF( "server_commitTrade returned %d\n", result ); */ } - board->traySelBits[turn] = 0x00; + pti->traySelBits = 0x00; } else { XP_Bool warn, legal; WordNotifierInfo info; @@ -612,8 +618,8 @@ board_commitTurn( BoardCtxt* board ) /* invalidate any selected tiles in case we'll be drawing this tray again rather than some other -- as is the case in a two-player game where one's a robot. */ - board_invalTrayTiles( board, board->traySelBits[turn] ); - board->traySelBits[turn] = 0x00; + board_invalTrayTiles( board, pti->traySelBits ); + pti->traySelBits = 0x00; } } stream_destroy( stream ); @@ -641,6 +647,7 @@ selectPlayerImpl( BoardCtxt* board, XP_U16 newPlayer, XP_Bool reveal ) checkRevealTray( board ); } } else { + PerTurnInfo* newInfo = &board->pti[newPlayer]; XP_U16 oldPlayer = board->selPlayer; model_foreachPendingCell( board->model, newPlayer, boardCellChanged, board ); @@ -657,26 +664,26 @@ selectPlayerImpl( BoardCtxt* board, XP_U16 newPlayer, XP_Bool reveal ) /* Just in case somebody started a trade when it wasn't his turn and there were plenty of tiles but now there aren't. */ - if ( board->tradeInProgress[newPlayer] && + if ( newInfo->tradeInProgress && server_countTilesInPool(board->server) < MIN_TRADE_TILES ) { - board->tradeInProgress[newPlayer] = XP_FALSE; - board->traySelBits[newPlayer] = 0x00; /* clear any selected */ + newInfo->tradeInProgress = XP_FALSE; + newInfo->traySelBits = 0x00; /* clear any selected */ } - invalTradeWindow( board, oldPlayer, - board->tradeInProgress[newPlayer] ); + invalTradeWindow( board, oldPlayer, newInfo->tradeInProgress ); #ifdef XWFEATURE_SEARCHLIMIT - if ( board->hasHintRect[oldPlayer] ) { + if ( board->pti[oldPlayer].hasHintRect ) { invalCurHintRect( board, oldPlayer ); } - if ( board->hasHintRect[newPlayer] ) { + if ( newInfo->hasHintRect ) { invalCurHintRect( board, newPlayer ); } #endif invalArrowCell( board ); board->selPlayer = (XP_U8)newPlayer; + board->selInfo = newInfo; invalArrowCell( board ); board_invalTrayTiles( board, ALLTILES ); @@ -970,7 +977,7 @@ flipAllLimits( BoardCtxt* board ) XP_U16 nPlayers = board->gi->nPlayers; XP_U16 i; for ( i = 0; i < nPlayers; ++i ) { - flipLimits( &board->limits[i] ); + flipLimits( &board->pti[i].limits ); } } #endif @@ -1402,14 +1409,15 @@ board_requestHint( BoardCtxt* board, XP_Bool result = XP_FALSE; XP_S16 nTiles; const Tile* tiles; - XP_U16 selPlayer; + const XP_U16 selPlayer = board->selPlayer; + PerTurnInfo* pti; EngineCtxt* engine; XP_Bool searchComplete = XP_TRUE; XP_Bool redraw = XP_FALSE; *workRemainsP = XP_FALSE; /* in case we exit without calling engine */ - selPlayer = board->selPlayer; + pti = board->pti + selPlayer; engine = server_getEngineFor( board->server, selPlayer ); /* engine may be null, if e.g. hint menu's chosen for a remote player */ result = !!engine && !board->gi->hintsNotAllowed && preflight( board ); @@ -1436,7 +1444,7 @@ board_requestHint( BoardCtxt* board, } tileSet = model_getPlayerTiles( model, selPlayer ); - nTiles = tileSet->nTiles - board->dividerLoc[selPlayer]; + nTiles = tileSet->nTiles - pti->dividerLoc; result = nTiles > 0; if ( result ) { #ifdef XWFEATURE_SEARCHLIMIT @@ -1450,15 +1458,14 @@ board_requestHint( BoardCtxt* board, (void)board_replaceTiles( board ); - tiles = tileSet->tiles + board->dividerLoc[selPlayer]; + tiles = tileSet->tiles + pti->dividerLoc; board_pushTimerSave( board ); #ifdef XWFEATURE_SEARCHLIMIT - XP_ASSERT( board->gi->allowHintRect - || !board->hasHintRect[selPlayer] ); - if ( board->gi->allowHintRect && board->hasHintRect[selPlayer] ) { - limits = board->limits[selPlayer]; + XP_ASSERT( board->gi->allowHintRect || !pti->hasHintRect ); + if ( board->gi->allowHintRect && pti->hasHintRect ) { + limits = pti->limits; lp = &limits; if ( board->isFlipped ) { flipLimits( lp ); @@ -1632,7 +1639,7 @@ XP_Bool moveTileToArrowLoc( BoardCtxt* board, XP_U8 index ) { XP_Bool result; - BoardArrow* arrow = &board->boardArrow[board->selPlayer]; + BoardArrow* arrow = &board->selInfo->boardArrow; if ( arrow->visible ) { result = moveTileToBoard( board, arrow->col, arrow->row, (XP_U16)index, EMPTY_TILE ); @@ -1682,7 +1689,7 @@ board_beginTrade( BoardCtxt* board ) } else { board->tradingMiniWindowInvalid = XP_TRUE; board->needsDrawing = XP_TRUE; - board->tradeInProgress[board->selPlayer] = XP_TRUE; + board->selInfo->tradeInProgress = XP_TRUE; setArrowVisible( board, XP_FALSE ); result = XP_TRUE; } @@ -1738,7 +1745,7 @@ invalCellRegion( BoardCtxt* board, XP_U16 colA, XP_U16 rowA, XP_U16 colB, void invalCurHintRect( BoardCtxt* board, XP_U16 player ) { - BdHintLimits* limits = &board->limits[player]; + BdHintLimits* limits = &board->pti[player].limits; invalCellRegion( board, limits->left, limits->top, limits->right, limits->bottom ); } /* invalCurHintRect */ @@ -1747,7 +1754,7 @@ static void clearCurHintRect( BoardCtxt* board ) { invalCurHintRect( board, board->selPlayer ); - board->hasHintRect[board->selPlayer] = XP_FALSE; + board->selInfo->hasHintRect = XP_FALSE; } /* clearCurHintRect */ #endif /* XWFEATURE_SEARCHLIMIT */ @@ -1762,7 +1769,7 @@ handlePenDownOnBoard( BoardCtxt* board, XP_U16 xx, XP_U16 yy ) util_setTimer( board->util, TIMER_PENDOWN, 0, p_board_timerFired, board ); - if ( !board->tradeInProgress[board->selPlayer] ) { + if ( !board->selInfo->tradeInProgress ) { result = dragDropStart( board, OBJ_BOARD, xx, yy ); } } @@ -1851,7 +1858,7 @@ handleLikeDown( BoardCtxt* board, BoardObjectType onWhich, XP_U16 x, XP_U16 y ) case OBJ_TRAY: if ( checkRevealTray(board) - && !board->tradeInProgress[board->selPlayer] ) { + && !board->selInfo->tradeInProgress ) { result = dragDropStart( board, OBJ_TRAY, x, y ) || result; } break; @@ -1920,7 +1927,7 @@ moveSelTileToBoardXY( BoardCtxt* board, XP_U16 col, XP_U16 row ) { XP_Bool result; XP_U16 selPlayer = board->selPlayer; - TileBit bits = board->traySelBits[selPlayer]; + TileBit bits = board->selInfo->traySelBits; XP_U16 tileIndex; if ( bits == NO_TILES ) { @@ -1942,7 +1949,7 @@ moveSelTileToBoardXY( BoardCtxt* board, XP_U16 col, XP_U16 row ) bits = 1 << (tileIndex-1); board_invalTrayTiles( board, bits ); } - board->traySelBits[selPlayer] = bits; + board->selInfo->traySelBits = bits; } return result; @@ -1973,7 +1980,7 @@ tryMoveArrow( BoardCtxt* board, XP_U16 col, XP_U16 row ) if ( !cellOccupied( board, col, row, board->trayVisState == TRAY_REVEALED ) ) { - BoardArrow* arrow = &board->boardArrow[board->selPlayer]; + BoardArrow* arrow = &board->selInfo->boardArrow; if ( arrow->visible && arrow->col == col && arrow->row == row ) { /* change it; if vertical, hide; else if horizontal make @@ -2049,11 +2056,11 @@ handleActionInCell( BoardCtxt* board, XP_U16 col, XP_U16 row, XP_Bool isPen ) static XP_Bool exitTradeMode( BoardCtxt* board ) { - XP_U16 selPlayer = board->selPlayer; + PerTurnInfo* pti = board->selInfo; invalSelTradeWindow( board ); - board->tradeInProgress[selPlayer] = XP_FALSE; - board_invalTrayTiles( board, board->traySelBits[selPlayer] ); - board->traySelBits[selPlayer] = 0x00; + pti->tradeInProgress = XP_FALSE; + board_invalTrayTiles( board, pti->traySelBits ); + pti->traySelBits = 0x00; return XP_TRUE; } /* exitTradeMode */ @@ -2143,8 +2150,7 @@ static void getFocussedCellCenter( BoardCtxt* board, XP_U16* xp, XP_U16* yp ) { XP_Rect rect; - XP_U16 selPlayer = board->selPlayer; - BdCursorLoc* cursorLoc = &board->bdCursor[selPlayer]; + BdCursorLoc* cursorLoc = &board->selInfo->bdCursor; getCellRect( board, cursorLoc->col, cursorLoc->row, &rect ); getRectCenter( &rect, xp, yp ); @@ -2153,7 +2159,7 @@ getFocussedCellCenter( BoardCtxt* board, XP_U16* xp, XP_U16* yp ) static void getFocussedScoreCenter( BoardCtxt* board, XP_U16* xp, XP_U16* yp ) { - getRectCenter( &board->scoreRects[board->scoreCursorLoc], xp, yp ); + getRectCenter( &board->pti[board->scoreCursorLoc].scoreRects, xp, yp ); } static XP_Bool @@ -2361,14 +2367,14 @@ static XP_Bool invalFocusOwner( BoardCtxt* board ) { XP_Bool draw = XP_TRUE; - XP_S16 selPlayer = board->selPlayer; + PerTurnInfo* pti = board->selInfo; switch( board->focussed ) { case OBJ_SCORE: board->scoreBoardInvalid = XP_TRUE; break; case OBJ_BOARD: if ( board->focusHasDived ) { - BdCursorLoc loc = board->bdCursor[selPlayer]; + BdCursorLoc loc = pti->bdCursor; invalCell( board, loc.col, loc.row ); } else { #ifdef PERIMETER_FOCUS @@ -2380,7 +2386,7 @@ invalFocusOwner( BoardCtxt* board ) break; case OBJ_TRAY: if ( board->focusHasDived ) { - XP_U16 loc = board->trayCursorLoc[selPlayer]; + XP_U16 loc = pti->trayCursorLoc; board_invalTrayTiles( board, 1 << loc ); } else { board_invalTrayTiles( board, ALLTILES ); @@ -2446,7 +2452,7 @@ board_focusChanged( BoardCtxt* board, BoardObjectType typ, XP_Bool gained ) XP_Bool board_toggle_arrowDir( BoardCtxt* board ) { - BoardArrow* arrow = &board->boardArrow[board->selPlayer]; + BoardArrow* arrow = &board->selInfo->boardArrow; if ( arrow->visible ) { arrow->vert = !arrow->vert; invalArrowCell( board ); @@ -2461,7 +2467,7 @@ board_toggle_arrowDir( BoardCtxt* board ) static XP_Bool advanceArrow( BoardCtxt* board ) { - XP_Key key = board->boardArrow[board->selPlayer].vert ? + XP_Key key = board->selInfo->boardArrow.vert ? XP_CURSOR_KEY_DOWN : XP_CURSOR_KEY_RIGHT; XP_ASSERT( board->trayVisState == TRAY_REVEALED ); @@ -2584,7 +2590,8 @@ static XP_Bool board_moveCursor( BoardCtxt* board, XP_Key cursorKey, XP_Bool preflightOnly, XP_Bool* up ) { - BdCursorLoc loc = board->bdCursor[board->selPlayer]; + PerTurnInfo* pti = board->selInfo; + BdCursorLoc loc = pti->bdCursor; XP_U16 col = loc.col; XP_U16 row = loc.row; XP_Bool changed; @@ -2599,7 +2606,7 @@ board_moveCursor( BoardCtxt* board, XP_Key cursorKey, XP_Bool preflightOnly, invalCell( board, col, row ); loc.col = col; loc.row = row; - board->bdCursor[board->selPlayer] = loc; + pti->bdCursor = loc; checkScrollCell( board, col, row ); } return changed; @@ -2730,7 +2737,7 @@ moveKeyTileToBoard( BoardCtxt* board, XP_Key cursorKey, XP_Bool* gotArrow ) *gotArrow = haveDest; #ifdef KEYBOARD_NAV if ( !haveDest && (board->focussed == OBJ_BOARD) && board->focusHasDived ) { - BdCursorLoc loc = board->bdCursor[board->selPlayer]; + BdCursorLoc loc = board->selInfo->bdCursor; col = loc.col; row = loc.row; haveDest = XP_TRUE; @@ -2752,7 +2759,7 @@ moveKeyTileToBoard( BoardCtxt* board, XP_Key cursorKey, XP_Bool* gotArrow ) static void setArrowFor( BoardCtxt* board, XP_U16 player, XP_U16 col, XP_U16 row ) { - BoardArrow* arrow = &board->boardArrow[player]; + BoardArrow* arrow = &board->pti[player].boardArrow; invalCell( board, arrow->col, arrow->row ); invalCell( board, col, row ); @@ -2771,7 +2778,7 @@ setArrow( BoardCtxt* board, XP_U16 col, XP_U16 row ) static XP_Bool getArrowFor( BoardCtxt* board, XP_U16 player, XP_U16* col, XP_U16* row ) { - BoardArrow* arrow = &board->boardArrow[player]; + BoardArrow* arrow = &board->pti[player].boardArrow; *col = arrow->col; *row = arrow->row; return arrow->visible; @@ -2792,7 +2799,7 @@ setArrowVisible( BoardCtxt* board, XP_Bool visible ) static XP_Bool setArrowVisibleFor( BoardCtxt* board, XP_U16 player, XP_Bool visible ) { - BoardArrow* arrow = &board->boardArrow[player]; + BoardArrow* arrow = &board->pti[player].boardArrow; XP_Bool result = arrow->visible; if ( arrow->visible != visible ) { arrow->visible = visible; diff --git a/xwords4/common/boarddrw.c b/xwords4/common/boarddrw.c index 344dbe8fa..2b8f82c72 100644 --- a/xwords4/common/boarddrw.c +++ b/xwords4/common/boarddrw.c @@ -172,8 +172,8 @@ figureHintAtts( BoardCtxt* board, XP_U16 col, XP_U16 row ) BdHintLimits limits; if ( dragDropGetHintLimits( board, &limits ) ) { /* do nothing */ - } else if ( board->hasHintRect[board->selPlayer] ) { - limits = board->limits[board->selPlayer]; + } else if ( board->selInfo->hasHintRect ) { + limits = board->selInfo->limits; } else { break; } @@ -278,7 +278,7 @@ drawBoard( BoardCtxt* board ) } if ( board->trayVisState == TRAY_REVEALED ) { - BoardArrow* arrow = &board->boardArrow[board->selPlayer]; + BoardArrow* arrow = &board->selInfo->boardArrow; if ( arrow->visible ) { XP_U16 col = arrow->col; @@ -440,8 +440,8 @@ cellFocused( const BoardCtxt* board, XP_U16 col, XP_U16 row ) if ( board->focussed == OBJ_BOARD ) { if ( board->focusHasDived ) { - if ( (col == board->bdCursor[board->selPlayer].col) - && (row == board->bdCursor[board->selPlayer].row) ) { + if ( (col == board->selInfo->bdCursor.col) + && (row == board->selInfo->bdCursor.row) ) { focussed = XP_TRUE; } } else { diff --git a/xwords4/common/boardp.h b/xwords4/common/boardp.h index c7e3e84c0..1226bfb54 100644 --- a/xwords4/common/boardp.h +++ b/xwords4/common/boardp.h @@ -1,4 +1,4 @@ -/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */ +/* -*-mode: C; fill-column: 78; -*- */ /* * Copyright 1997 - 2007 by Eric House (xwords@eehouse.org). All rights reserved. * @@ -54,7 +54,7 @@ typedef enum { } DragType; -typedef struct DragState { +typedef struct _DragState { DragType dtype; XP_Bool didMove; /* there was change during the drag; not a tap */ @@ -65,7 +65,7 @@ typedef struct DragState { DragObjInfo cur; } DragState; -typedef struct BoardArrow { /* gets flipped along with board */ +typedef struct _BoardArrow { /* gets flipped along with board */ XP_U8 col; XP_U8 row; XP_Bool vert; @@ -73,7 +73,7 @@ typedef struct BoardArrow { /* gets flipped along with board */ } BoardArrow; #ifdef KEYBOARD_NAV -typedef struct BdCursorLoc { +typedef struct _BdCursorLoc { XP_U8 col; XP_U8 row; } BdCursorLoc; @@ -83,7 +83,7 @@ typedef struct BdCursorLoc { trading window. There's never more than of the former since it lives only as long as the pen is down. There are, in theory, as many trading windows as there are (local) players, but they can all use the same window. */ -typedef struct MiniWindowStuff { +typedef struct _MiniWindowStuff { void* closure; const XP_UCHAR* text; XP_Rect rect; @@ -92,6 +92,29 @@ typedef struct MiniWindowStuff { enum { MINIWINDOW_VALHINT, MINIWINDOW_TRADING }; typedef XP_U16 MiniWindowType; /* one of the two above */ +typedef struct _PerTurnInfo { +#ifdef KEYBOARD_NAV + XP_Rect scoreRects; + BdCursorLoc bdCursor; +#endif + BoardArrow boardArrow; + XP_U16 scoreDims; + XP_U8 dividerLoc; /* 0 means left of 0th tile, etc. */ + TileBit traySelBits; +#ifdef XWFEATURE_SEARCHLIMIT + BdHintLimits limits; +#endif +#ifdef KEYBOARD_NAV + XP_U8 trayCursorLoc; /* includes divider!!! */ +#endif + XP_Bool dividerSelected; /* probably need to save this */ + XP_Bool tradeInProgress; +#ifdef XWFEATURE_SEARCHLIMIT + XP_Bool hasHintRect; +#endif +} PerTurnInfo; + + struct BoardCtxt { /* BoardVTable* vtable; */ ModelCtxt* model; @@ -133,7 +156,6 @@ struct BoardCtxt { XP_Bool disableArrow; XP_Bool hideValsInTray; - XP_Bool tradeInProgress[MAX_NUM_PLAYERS]; XP_Bool eraseTray; XP_Bool boardObscuresTray; XP_Bool boardHidesTray; @@ -144,22 +166,18 @@ struct BoardCtxt { /* Unless KEYBOARD_NAV is defined, this does not change */ BoardObjectType focussed; - BoardArrow boardArrow[MAX_NUM_PLAYERS]; #ifdef KEYBOARD_NAV - XP_Rect scoreRects[MAX_NUM_PLAYERS]; - BdCursorLoc bdCursor[MAX_NUM_PLAYERS]; XP_Bool focusHasDived; #endif - XP_U8 dividerLoc[MAX_NUM_PLAYERS]; /* 0 means left of 0th tile, etc. */ - XP_Bool dividerSelected[MAX_NUM_PLAYERS]; /* probably need to save this */ - - XP_U16 scoreDims[MAX_NUM_PLAYERS]; /* scoreboard state */ XP_Rect scoreBdBounds; XP_Rect timerBounds; XP_U8 selPlayer; /* which player is selected (!= turn) */ + PerTurnInfo pti[MAX_NUM_PLAYERS]; + PerTurnInfo* selInfo; + /* tray state */ XP_U8 trayScaleH; XP_U8 trayScaleV; @@ -175,9 +193,7 @@ struct BoardCtxt { XP_Bool tradingMiniWindowInvalid; TileBit trayInvalBits; - TileBit traySelBits[MAX_NUM_PLAYERS]; #ifdef KEYBOARD_NAV - XP_U8 trayCursorLoc[MAX_NUM_PLAYERS]; /* includes divider!!! */ XP_U8 scoreCursorLoc; #endif @@ -186,10 +202,6 @@ struct BoardCtxt { XP_Bool showCellValues; XP_Bool showColors; -#ifdef XWFEATURE_SEARCHLIMIT - XP_Bool hasHintRect[MAX_NUM_PLAYERS]; - BdHintLimits limits[MAX_NUM_PLAYERS]; -#endif MPSLOT }; @@ -197,7 +209,7 @@ struct BoardCtxt { #define valHintMiniWindowActive( board ) \ ((XP_Bool)((board)->miniWindowStuff[MINIWINDOW_VALHINT].text != NULL)) #define MY_TURN(b) ((b)->selPlayer == server_getCurrentTurn( (b)->server )) -#define TRADE_IN_PROGRESS(b) ((b)->tradeInProgress[(b)->selPlayer]==XP_TRUE) +#define TRADE_IN_PROGRESS(b) ((b)->selInfo->tradeInProgress==XP_TRUE) /* tray-related functions */ XP_Bool handlePenUpTray( BoardCtxt* board, XP_U16 x, XP_U16 y ); diff --git a/xwords4/common/dragdrpp.c b/xwords4/common/dragdrpp.c index e111d57ed..fb2f4cacb 100644 --- a/xwords4/common/dragdrpp.c +++ b/xwords4/common/dragdrpp.c @@ -1,4 +1,4 @@ -/* -*-mode: C; fill-column: 78; c-basic-offset: 4; compile-command: "cd ../linux && make MEMDEBUG=TRUE"; -*- */ +/* -*-mode: C; fill-column: 78; compile-command: "cd ../linux && make MEMDEBUG=TRUE"; -*- */ /* * Copyright 1997 - 2008 by Eric House (xwords@eehouse.org). All rights * reserved. @@ -114,15 +114,14 @@ ddStartTray( BoardCtxt* board, XP_U16 x, XP_U16 y ) XP_S16 index = pointToTileIndex( board, x, y, &onDivider ); canDrag = onDivider || index >= 0; if ( canDrag ) { - XP_S16 selPlayer = board->selPlayer; if ( onDivider ) { board->dividerInvalid = XP_TRUE; - ds->start.u.tray.index = board->dividerLoc[selPlayer]; + ds->start.u.tray.index = board->selInfo->dividerLoc; ds->dtype = DT_DIVIDER; } else { Tile tile; - tile = model_getPlayerTile( board->model, selPlayer, index ); + tile = model_getPlayerTile( board->model, board->selPlayer, index ); ds->isBlank = tile == dict_getBlankTile( model_getDictionary(board->model) ); ds->tile = tile; @@ -131,7 +130,7 @@ ddStartTray( BoardCtxt* board, XP_U16 x, XP_U16 y ) /* during drag the moving tile is drawn as selected, so inval currently selected tile. */ - board_invalTrayTiles( board, board->traySelBits[selPlayer] ); + board_invalTrayTiles( board, board->selInfo->traySelBits ); ds->dtype = DT_TILE; } @@ -218,9 +217,9 @@ dragDropEnd( BoardCtxt* board, XP_U16 xx, XP_U16 yy, XP_Bool* dragged ) } else if ( ds->dtype == DT_HINTRGN ) { if ( OBJ_BOARD == newObj && ds->didMove ) { XP_Bool makeActive = ds->start.u.board.row <= ds->cur.u.board.row; - board->hasHintRect[board->selPlayer] = makeActive; + board->selInfo->hasHintRect = makeActive; if ( makeActive ) { - setLimitsFrom( board, &board->limits[board->selPlayer] ); + setLimitsFrom( board, &board->selInfo->limits ); } else { invalHintRectDiffs( board, &ds->cur, NULL ); } diff --git a/xwords4/common/scorebdp.c b/xwords4/common/scorebdp.c index 7d8a4ff24..c4228a6b3 100644 --- a/xwords4/common/scorebdp.c +++ b/xwords4/common/scorebdp.c @@ -1,4 +1,4 @@ -/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */ +/* -*-mode: C; fill-column: 78; compile-command: "cd ../linux && make MEMDEBUG=TRUE"; -*- */ /* * Copyright 1997 - 2007 by Eric House (xwords@eehouse.org). All rights reserved. * @@ -164,7 +164,7 @@ drawScoreBoard( BoardCtxt* board ) for ( dp = datum, i = 0; i < nPlayers; ++dp, ++i ) { XP_Rect innerRect; XP_U16 dim = isVertical? dp->height:dp->width; - *adjustDim = board->scoreDims[i] = dim + extra; + *adjustDim = board->pti[i].scoreDims = dim + extra; innerRect.width = dp->width; innerRect.height = dp->height; @@ -176,7 +176,7 @@ drawScoreBoard( BoardCtxt* board ) draw_score_drawPlayer( board->draw, &innerRect, &scoreRect, &dp->dsi ); #ifdef KEYBOARD_NAV - XP_MEMCPY( &board->scoreRects[i], &scoreRect, + XP_MEMCPY( &board->pti[i].scoreRects, &scoreRect, sizeof(scoreRect) ); if ( i == cursorIndex ) { cursorRect = scoreRect; @@ -245,10 +245,11 @@ figureScorePlayerTapped( BoardCtxt* board, XP_U16 x, XP_U16 y ) left -= board->remDim; if ( left >= 0 ) { for ( result = 0; result < nPlayers; ++result ) { - if ( left < board->scoreDims[result] ) { + PerTurnInfo* pti = board->pti + result; + if ( left < pti->scoreDims ) { break; } - left -= board->scoreDims[result]; + left -= pti->scoreDims; } } if ( result >= nPlayers ) { diff --git a/xwords4/common/tray.c b/xwords4/common/tray.c index c93f3f9bd..fa83108f7 100644 --- a/xwords4/common/tray.c +++ b/xwords4/common/tray.c @@ -95,7 +95,7 @@ figureTrayTileRect( BoardCtxt* board, XP_U16 index, XP_Rect* rect ) rect->width = board->trayScaleH; rect->height = board->trayScaleV; - if ( board->dividerLoc[board->selPlayer] <= index ) { + if ( board->selInfo->dividerLoc <= index ) { rect->left += board->dividerWidth; } } /* figureTileRect */ @@ -128,7 +128,8 @@ drawTray( BoardCtxt* board ) XP_Rect tileRect; if ( (board->trayInvalBits != 0) || board->dividerInvalid ) { - XP_S16 turn = board->selPlayer; + const XP_S16 turn = board->selPlayer; + PerTurnInfo* pti = board->selInfo; if ( draw_trayBegin( board->draw, &board->trayBounds, turn, dfsFor( board, OBJ_TRAY ) ) ) { @@ -136,9 +137,9 @@ drawTray( BoardCtxt* board ) XP_S16 cursorBits = 0; XP_Bool cursorOnDivider = XP_FALSE; #ifdef KEYBOARD_NAV - XP_S16 cursorTile = board->trayCursorLoc[turn]; + XP_S16 cursorTile = pti->trayCursorLoc; if ( board->focussed == OBJ_TRAY ) { - cursorOnDivider = board->dividerLoc[turn] == cursorTile; + cursorOnDivider = pti->dividerLoc == cursorTile; if ( board->focusHasDived ) { if ( !cursorOnDivider ) { adjustForDivider( board, &cursorTile ); @@ -187,7 +188,7 @@ drawTray( BoardCtxt* board ) XP_UCHAR buf[4]; XP_Bitmap bitmap = NULL; XP_UCHAR* textP = (XP_UCHAR*)NULL; - XP_U8 traySelBits = board->traySelBits[turn]; + XP_U8 traySelBits = pti->traySelBits; XP_S16 value; Tile tile; @@ -240,7 +241,7 @@ drawTray( BoardCtxt* board ) CellFlags flags = cursorOnDivider? CELL_ISCURSOR : CELL_NONE; XP_Rect divider; figureDividerRect( board, ÷r ); - if ( board->dividerSelected[turn] + if ( pti->dividerSelected || dragDropIsDividerDrag(board) ) { flags |= CELL_HIGHLIGHT; } @@ -327,7 +328,7 @@ drawPendingScore( BoardCtxt* board, XP_Bool hasCursor ) static void figureDividerRect( BoardCtxt* board, XP_Rect* rect ) { - figureTrayTileRect( board, board->dividerLoc[board->selPlayer], rect ); + figureTrayTileRect( board, board->selInfo->dividerLoc, rect ); rect->left -= board->dividerWidth; rect->width = board->dividerWidth; } /* figureDividerRect */ @@ -365,7 +366,7 @@ handleTrayDuringTrade( BoardCtxt* board, XP_S16 index ) XP_ASSERT( index >= 0 ); bits = 1 << index; - board->traySelBits[board->selPlayer] ^= bits; + board->selInfo->traySelBits ^= bits; board_invalTrayTiles( board, bits ); return XP_TRUE; } /* handleTrayDuringTrade */ @@ -374,15 +375,16 @@ static XP_Bool handleActionInTray( BoardCtxt* board, XP_S16 index, XP_Bool onDivider ) { XP_Bool result = XP_FALSE; - XP_U16 selPlayer = board->selPlayer; + const XP_U16 selPlayer = board->selPlayer; + PerTurnInfo* pti = board->selInfo; if ( onDivider ) { /* toggle divider sel state */ - board->dividerSelected[selPlayer] = !board->dividerSelected[selPlayer]; + pti->dividerSelected = !pti->dividerSelected; board->dividerInvalid = XP_TRUE; - board->traySelBits[selPlayer] = NO_TILES; + pti->traySelBits = NO_TILES; result = XP_TRUE; - } else if ( board->tradeInProgress[selPlayer] ) { + } else if ( pti->tradeInProgress ) { if ( index >= 0 ) { result = handleTrayDuringTrade( board, index ); } @@ -390,25 +392,25 @@ handleActionInTray( BoardCtxt* board, XP_S16 index, XP_Bool onDivider ) result = moveTileToArrowLoc( board, (XP_U8)index ); if ( !result ) { TileBit newBits = 1 << index; - XP_U8 selBits = board->traySelBits[selPlayer]; + XP_U8 selBits = pti->traySelBits; /* Tap on selected tile unselects. If we don't do this, then there's no way to unselect and so no way to turn off the placement arrow */ if ( newBits == selBits ) { board_invalTrayTiles( board, selBits ); - board->traySelBits[selPlayer] = NO_TILES; + pti->traySelBits = NO_TILES; } else if ( selBits != 0 ) { XP_U16 selIndex = indexForBits( selBits ); - model_moveTileOnTray( board->model, board->selPlayer, + model_moveTileOnTray( board->model, selPlayer, selIndex, index ); - board->traySelBits[selPlayer] = NO_TILES; + pti->traySelBits = NO_TILES; } else { board_invalTrayTiles( board, newBits ); - board->traySelBits[selPlayer] = newBits; + pti->traySelBits = newBits; } board->dividerInvalid = - board->dividerInvalid || board->dividerSelected[selPlayer]; - board->dividerSelected[selPlayer] = XP_FALSE; + board->dividerInvalid || pti->dividerSelected; + pti->dividerSelected = XP_FALSE; result = XP_TRUE; } } else if ( index == -(MAX_TRAY_TILES) ) { /* pending score tile */ @@ -447,10 +449,10 @@ indexForBits( XP_U8 bits ) XP_Bool dividerMoved( BoardCtxt* board, XP_U8 newLoc ) { - XP_U8 oldLoc = board->dividerLoc[board->selPlayer]; + XP_U8 oldLoc = board->selInfo->dividerLoc; XP_Bool moved = oldLoc != newLoc; if ( moved ) { - board->dividerLoc[board->selPlayer] = newLoc; + board->selInfo->dividerLoc = newLoc; /* This divider's index corresponds to the tile it's to the left of, and there's no need to invalidate any tiles to the left of the uppermore @@ -508,11 +510,11 @@ XP_Bool board_juggleTray( BoardCtxt* board ) { XP_Bool result = XP_FALSE; - XP_S16 turn = board->selPlayer; + const XP_S16 turn = board->selPlayer; if ( checkRevealTray( board ) ) { XP_S16 nTiles; - XP_U16 dividerLoc = board->dividerLoc[board->selPlayer]; + XP_U16 dividerLoc = board->selInfo->dividerLoc; ModelCtxt* model = board->model; nTiles = model_getNumTilesInTray( model, turn ) - dividerLoc; @@ -536,7 +538,7 @@ board_juggleTray( BoardCtxt* board ) (void)model_removePlayerTile( model, turn, -1 ); model_addPlayerTile( model, turn, dividerLoc, tmpT[i] ); } - board->traySelBits[turn] = 0; + board->selInfo->traySelBits = 0; result = XP_TRUE; } } @@ -547,7 +549,7 @@ board_juggleTray( BoardCtxt* board ) static void adjustForDivider( const BoardCtxt* board, XP_S16* index ) { - XP_U16 dividerLoc = board->dividerLoc[board->selPlayer]; + XP_U16 dividerLoc = board->selInfo->dividerLoc; if ( dividerLoc <= *index ) { --*index; } @@ -566,8 +568,9 @@ tray_moveCursor( BoardCtxt* board, XP_Key cursorKey, XP_Bool preflightOnly, } else if ( cursorKey == XP_CURSOR_KEY_RIGHT || cursorKey == XP_CURSOR_KEY_LEFT ) { XP_S16 delta = cursorKey == XP_CURSOR_KEY_RIGHT ? 1 : -1; - XP_U16 selPlayer = board->selPlayer; - XP_S16 trayCursorLoc = board->trayCursorLoc[selPlayer]; + const XP_U16 selPlayer = board->selPlayer; + PerTurnInfo* pti = board->selInfo; + XP_S16 trayCursorLoc = pti->trayCursorLoc; XP_S16 newLoc = trayCursorLoc + delta; if ( newLoc < 0 || newLoc > MAX_TRAY_TILES ) { XP_LOGF( "moving up: newLoc: %d", newLoc ); @@ -575,27 +578,25 @@ tray_moveCursor( BoardCtxt* board, XP_Key cursorKey, XP_Bool preflightOnly, } else if ( !preflightOnly ) { XP_S16 tileLoc = trayCursorLoc; XP_U16 nTiles = model_getNumTilesInTray( board->model, selPlayer ); - XP_Bool cursorOnDivider - = trayCursorLoc == board->dividerLoc[selPlayer]; + XP_Bool cursorOnDivider = trayCursorLoc == pti->dividerLoc; XP_Bool cursorObjSelected; adjustForDivider( board, &tileLoc ); cursorObjSelected = cursorOnDivider? - board->dividerSelected[selPlayer] - : board->traySelBits[selPlayer] == (1 << tileLoc); + pti->dividerSelected : pti->traySelBits == (1 << tileLoc); if ( !cursorObjSelected ) { /* nothing to do */ } else if ( cursorOnDivider ) { /* just drag the divider */ - board->dividerLoc[selPlayer] = newLoc; - } else if ( board->tradeInProgress[selPlayer] ) { + pti->dividerLoc = newLoc; + } else if ( pti->tradeInProgress ) { /* nothing to do */ } else { XP_S16 newTileLoc; /* drag the tile, skipping over the divider if needed */ - if ( (newLoc == board->dividerLoc[selPlayer]) && (newLoc > 0) ) { + if ( (newLoc == pti->dividerLoc) && (newLoc > 0) ) { newLoc += delta; } newTileLoc = newLoc; @@ -606,13 +607,13 @@ tray_moveCursor( BoardCtxt* board, XP_Key cursorKey, XP_Bool preflightOnly, if ( newTileLoc < nTiles ) { model_moveTileOnTray( board->model, selPlayer, tileLoc, newTileLoc ); - board->traySelBits[selPlayer] = (1 << newTileLoc); + pti->traySelBits = (1 << newTileLoc); } else { - board->traySelBits[selPlayer] = 0; /* clear selection */ + pti->traySelBits = 0; /* clear selection */ } } } - board->trayCursorLoc[selPlayer] = newLoc; + pti->trayCursorLoc = newLoc; /* fix this!!! */ board->dividerInvalid = XP_TRUE; @@ -700,14 +701,14 @@ void getFocussedTileCenter( BoardCtxt* board, XP_U16* xp, XP_U16* yp ) { XP_Rect rect; - XP_S16 selPlayer = board->selPlayer; - XP_S16 cursorTile = board->trayCursorLoc[selPlayer]; - XP_Bool cursorOnDivider = board->dividerLoc[selPlayer] == cursorTile; + PerTurnInfo* pti = board->selInfo; + XP_S16 cursorTile = pti->trayCursorLoc; + XP_Bool cursorOnDivider = pti->dividerLoc == cursorTile; if ( cursorOnDivider ) { figureDividerRect( board, &rect ); } else { - XP_S16 indx = board->trayCursorLoc[selPlayer]; + XP_S16 indx = pti->trayCursorLoc; adjustForDivider( board, &indx ); XP_ASSERT( indx >= 0 ); figureTrayTileRect( board, indx, &rect ); @@ -723,7 +724,7 @@ board_moveDivider( BoardCtxt* board, XP_Bool right ) { XP_Bool result = board->trayVisState == TRAY_REVEALED; if ( result ) { - XP_U8 loc = board->dividerLoc[board->selPlayer]; + XP_U8 loc = board->selInfo->dividerLoc; loc += MAX_TRAY_TILES + 1; loc += right? 1:-1; loc %= MAX_TRAY_TILES + 1;