mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-15 15:41:24 +01:00
Break scoreboard code out into a new module. board.o was getting too
big on palm.
This commit is contained in:
parent
ccba050288
commit
a84b519ab7
5 changed files with 363 additions and 280 deletions
281
common/board.c
281
common/board.c
|
@ -47,6 +47,7 @@
|
|||
|
||||
#include "comtypes.h"
|
||||
#include "board.h"
|
||||
#include "scorebdp.h"
|
||||
#include "game.h"
|
||||
#include "server.h"
|
||||
#include "comms.h" /* for CHANNEL_NONE */
|
||||
|
@ -78,8 +79,6 @@ static XP_Bool drawCell( BoardCtxt* board, XP_U16 col, XP_U16 row,
|
|||
static void figureBoardRect( BoardCtxt* board );
|
||||
|
||||
static void drawBoard( BoardCtxt* board );
|
||||
static void drawTimer( BoardCtxt* board );
|
||||
static void drawScoreBoard( BoardCtxt* board );
|
||||
static void invalCell( BoardCtxt* board, XP_U16 col, XP_U16 row );
|
||||
static void invalCellsUnderRect( BoardCtxt* board, XP_Rect* rect );
|
||||
|
||||
|
@ -96,7 +95,6 @@ static void setArrowFor( BoardCtxt* board, XP_U16 player, XP_U16 col,
|
|||
XP_U16 row );
|
||||
static XP_Bool setArrowVisible( BoardCtxt* board, XP_Bool visible );
|
||||
|
||||
static XP_S16 figureScorePlayerTapped( BoardCtxt* board, XP_U16 x, XP_U16 y );
|
||||
static XP_Bool cellOccupied( BoardCtxt* board, XP_U16 col, XP_U16 row,
|
||||
XP_Bool inclPending );
|
||||
static void makeMiniWindowForTrade( BoardCtxt* board );
|
||||
|
@ -122,7 +120,6 @@ static XP_Bool moveKeyTileToBoard( BoardCtxt* board, XP_Key cursorKey,
|
|||
#endif
|
||||
|
||||
#ifdef KEYBOARD_NAV
|
||||
static XP_Bool moveScoreCursor( BoardCtxt* board, XP_Key key );
|
||||
static XP_Bool board_moveCursor( BoardCtxt* board, XP_Key cursorKey );
|
||||
static XP_Bool invalFocusOwner( BoardCtxt* board );
|
||||
#endif
|
||||
|
@ -357,18 +354,6 @@ board_setPos( BoardCtxt* board, XP_U16 left, XP_U16 top,
|
|||
figureBoardRect( board );
|
||||
} /* board_setPos */
|
||||
|
||||
void
|
||||
board_setScoreboardLoc( BoardCtxt* board, XP_U16 scoreLeft, XP_U16 scoreTop,
|
||||
XP_U16 scoreWidth, XP_U16 scoreHeight,
|
||||
XP_Bool divideHorizontally )
|
||||
{
|
||||
board->scoreBdBounds.left = scoreLeft;
|
||||
board->scoreBdBounds.top = scoreTop;
|
||||
board->scoreBdBounds.width = scoreWidth;
|
||||
board->scoreBdBounds.height = scoreHeight;
|
||||
board->scoreSplitHor = divideHorizontally;
|
||||
} /* board_setScoreboardLoc */
|
||||
|
||||
void
|
||||
board_setTimerLoc( BoardCtxt* board,
|
||||
XP_U16 timerLeft, XP_U16 timerTop,
|
||||
|
@ -624,7 +609,7 @@ board_commitTurn( BoardCtxt* board )
|
|||
* cursor and tray traySelBits. Others, such as the miniwindow stuff, are
|
||||
* singletons that may have to be hidden or shown.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
board_selectPlayer( BoardCtxt* board, XP_U16 newPlayer )
|
||||
{
|
||||
if ( !board->gameOver && server_getCurrentTurn(board->server) < 0 ) {
|
||||
|
@ -1167,191 +1152,6 @@ drawBoard( BoardCtxt* board )
|
|||
}
|
||||
} /* drawBoard */
|
||||
|
||||
static XP_S16
|
||||
figureSecondsLeft( BoardCtxt* board )
|
||||
{
|
||||
CurGameInfo* gi = board->gi;
|
||||
XP_U16 secondsUsed = gi->players[board->selPlayer].secondsUsed;
|
||||
XP_U16 secondsAvailable = gi->gameSeconds / gi->nPlayers;
|
||||
XP_ASSERT( gi->timerEnabled );
|
||||
return secondsAvailable - secondsUsed;
|
||||
} /* figureSecondsLeft */
|
||||
|
||||
static void
|
||||
drawTimer( BoardCtxt* board )
|
||||
{
|
||||
if ( board->gi->timerEnabled ) {
|
||||
XP_S16 secondsLeft = figureSecondsLeft( board );
|
||||
|
||||
draw_drawTimer( board->draw, &board->timerBounds, &board->timerBounds,
|
||||
board->selPlayer, secondsLeft );
|
||||
}
|
||||
} /* drawTimer */
|
||||
|
||||
static XP_Bool
|
||||
board_ScoreCallback( void* closure, XP_S16 player, XP_UCHAR* expl,
|
||||
XP_U16* explLen)
|
||||
{
|
||||
ModelCtxt* model = (ModelCtxt*)closure;
|
||||
return model_getPlayersLastScore( model, player,
|
||||
expl, explLen );
|
||||
} /* board_ScoreCallback */
|
||||
|
||||
typedef struct DrawScoreData {
|
||||
DrawScoreInfo dsi;
|
||||
XP_U16 height;
|
||||
XP_U16 width;
|
||||
} DrawScoreData;
|
||||
|
||||
static void
|
||||
drawScoreBoard( BoardCtxt* board )
|
||||
{
|
||||
if ( board->scoreBoardInvalid ) {
|
||||
short i;
|
||||
|
||||
XP_U16 nPlayers = board->gi->nPlayers;
|
||||
|
||||
if ( nPlayers > 0 ) {
|
||||
ModelCtxt* model = board->model;
|
||||
XP_S16 curTurn = server_getCurrentTurn( board->server );
|
||||
XP_U16 selPlayer = board->selPlayer;
|
||||
XP_S16 nTilesInPool = server_countTilesInPool( board->server );
|
||||
XP_Rect scoreRect = board->scoreBdBounds;
|
||||
XP_S16* adjustDim;
|
||||
XP_S16* adjustPt;
|
||||
XP_U16 totalDim, extra, nShares, remWidth, remHeight, remDim;
|
||||
DrawScoreData* dp;
|
||||
DrawScoreData datum[MAX_NUM_PLAYERS];
|
||||
XP_S16 scores[MAX_NUM_PLAYERS];
|
||||
XP_Bool isVertical = !board->scoreSplitHor;
|
||||
#ifdef KEYBOARD_NAV
|
||||
XP_S16 cursorIndex = ( (board->focussed == OBJ_SCORE)
|
||||
&& board->focusHasDived ) ?
|
||||
board->scoreCursorLoc : -1;
|
||||
XP_Rect cursorRect;
|
||||
XP_Rect* cursorRectP = NULL;
|
||||
#endif
|
||||
draw_scoreBegin( board->draw, &board->scoreBdBounds, nPlayers,
|
||||
dfsFor( board, OBJ_SCORE ) );
|
||||
|
||||
/* Let platform decide whether the rem: string should be given any
|
||||
space once there are no tiles left. On Palm that space is
|
||||
clickable to drop a menu, so will probably leave it. */
|
||||
draw_measureRemText( board->draw, &board->scoreBdBounds,
|
||||
nTilesInPool, &remWidth, &remHeight );
|
||||
remDim = isVertical? remHeight : remWidth;
|
||||
|
||||
if ( isVertical ) {
|
||||
adjustPt = &scoreRect.top;
|
||||
adjustDim = &scoreRect.height;
|
||||
} else {
|
||||
adjustPt = &scoreRect.left;
|
||||
adjustDim = &scoreRect.width;
|
||||
}
|
||||
|
||||
/* Get the scores from the model or by calculating them based on
|
||||
the end-of-game state. */
|
||||
if ( board->gameOver ) {
|
||||
model_figureFinalScores( model, scores, (XP_S16*)NULL );
|
||||
} else {
|
||||
for ( i = 0; i < nPlayers; ++i ) {
|
||||
scores[i] = model_getPlayerScore( model, i );
|
||||
}
|
||||
}
|
||||
|
||||
totalDim = remDim;
|
||||
|
||||
/* figure spacing for each scoreboard entry */
|
||||
XP_MEMSET( &datum, 0, sizeof(datum) );
|
||||
for ( dp = datum, i = 0; i < nPlayers; ++i, ++dp ) {
|
||||
LocalPlayer* lp = &board->gi->players[i];
|
||||
|
||||
/* This is a hack! */
|
||||
dp->dsi.lsc = board_ScoreCallback;
|
||||
dp->dsi.lscClosure = model;
|
||||
#ifdef KEYBOARD_NAV
|
||||
if ( i == cursorIndex ) {
|
||||
dp->dsi.flags |= CELL_ISCURSOR;
|
||||
}
|
||||
#endif
|
||||
dp->dsi.playerNum = i;
|
||||
dp->dsi.score = scores[i];
|
||||
dp->dsi.isTurn = (i == curTurn);
|
||||
dp->dsi.name = emptyStringIfNull(lp->name);
|
||||
dp->dsi.selected = board->trayVisState != TRAY_HIDDEN
|
||||
&& i==selPlayer;
|
||||
dp->dsi.isRobot = lp->isRobot;
|
||||
dp->dsi.isRemote = !lp->isLocal;
|
||||
dp->dsi.nTilesLeft = (nTilesInPool > 0)? -1:
|
||||
model_getNumTilesTotal( model, i );
|
||||
draw_measureScoreText( board->draw, &scoreRect,
|
||||
&dp->dsi, &dp->width, &dp->height );
|
||||
totalDim += isVertical ? dp->height : dp->width;
|
||||
}
|
||||
|
||||
/* break extra space into chunks, one to follow REM and another to
|
||||
preceed the timer, and then one for each player. Generally the
|
||||
player's score will be centered in the rect it's given, so in
|
||||
effect we're putting half the chunk on either side. The goal
|
||||
here is for the scores to be closer to each other than they are
|
||||
to the rem: string and timer on the ends. */
|
||||
nShares = nPlayers;
|
||||
XP_ASSERT( *adjustDim >= totalDim );
|
||||
extra = (*adjustDim - totalDim) / nShares;
|
||||
|
||||
/* at this point, the scoreRect should be anchored at the
|
||||
scoreboard rect's upper left. */
|
||||
|
||||
if ( remDim > 0 ) {
|
||||
*adjustDim = remDim;
|
||||
|
||||
draw_drawRemText( board->draw, &scoreRect, &scoreRect,
|
||||
nTilesInPool );
|
||||
|
||||
*adjustPt += remDim;
|
||||
}
|
||||
|
||||
board->remDim = remDim; /* save now so register can be reused */
|
||||
|
||||
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;
|
||||
|
||||
innerRect.width = dp->width;
|
||||
innerRect.height = dp->height;
|
||||
innerRect.left = scoreRect.left +
|
||||
((scoreRect.width - innerRect.width) / 2);
|
||||
innerRect.top = scoreRect.top +
|
||||
((scoreRect.height - innerRect.height) / 2);
|
||||
|
||||
draw_score_drawPlayer( board->draw, &innerRect, &scoreRect,
|
||||
&dp->dsi );
|
||||
#ifdef KEYBOARD_NAV
|
||||
if ( i == cursorIndex ) {
|
||||
cursorRect = scoreRect;
|
||||
cursorRectP = &cursorRect;
|
||||
}
|
||||
#endif
|
||||
*adjustPt += *adjustDim;
|
||||
}
|
||||
|
||||
#ifdef KEYBOARD_NAV
|
||||
if ( !!cursorRectP ) {
|
||||
draw_drawCursor( board->draw, OBJ_SCORE, cursorRectP );
|
||||
}
|
||||
#endif
|
||||
|
||||
draw_objFinished( board->draw, OBJ_SCORE, &board->scoreBdBounds,
|
||||
dfsFor( board, OBJ_SCORE ) );
|
||||
}
|
||||
|
||||
board->scoreBoardInvalid = XP_FALSE;
|
||||
}
|
||||
|
||||
drawTimer( board );
|
||||
} /* drawScoreBoard */
|
||||
|
||||
#ifdef KEYBOARD_NAV
|
||||
DrawFocusState
|
||||
dfsFor( BoardCtxt* board, BoardObjectType obj )
|
||||
|
@ -2464,54 +2264,6 @@ board_handlePenMove( BoardCtxt* board, XP_U16 x, XP_U16 y )
|
|||
return result;
|
||||
} /* board_handlePenMove */
|
||||
|
||||
static XP_S16
|
||||
figureScorePlayerTapped( BoardCtxt* board, XP_U16 x, XP_U16 y )
|
||||
{
|
||||
XP_S16 result = -1;
|
||||
XP_S16 left;
|
||||
XP_U16 nPlayers = board->gi->nPlayers;
|
||||
|
||||
if ( board->scoreSplitHor ) {
|
||||
left = x - board->scoreBdBounds.left;
|
||||
} else {
|
||||
left = y - board->scoreBdBounds.top;
|
||||
}
|
||||
|
||||
left -= board->remDim;
|
||||
if ( left >= 0 ) {
|
||||
for ( result = 0; result < nPlayers; ++result ) {
|
||||
if ( left < board->scoreDims[result] ) {
|
||||
break;
|
||||
}
|
||||
left -= board->scoreDims[result];
|
||||
}
|
||||
}
|
||||
if ( result >= nPlayers ) {
|
||||
result = -1;
|
||||
}
|
||||
return result;
|
||||
} /* figureScorePlayerTapped */
|
||||
|
||||
/* If the pen also went down on the scoreboard, make the selected player the
|
||||
* one closest to the mouse up loc.
|
||||
*/
|
||||
#ifdef POINTER_SUPPORT
|
||||
static XP_Bool
|
||||
handlePenUpScore( BoardCtxt* board, XP_U16 x, XP_U16 y )
|
||||
{
|
||||
XP_Bool result = XP_FALSE;
|
||||
|
||||
XP_S16 playerNum = figureScorePlayerTapped( board, x, y );
|
||||
|
||||
if ( playerNum >= 0 ) {
|
||||
board_selectPlayer( board, playerNum );
|
||||
|
||||
result = XP_TRUE;
|
||||
}
|
||||
return result;
|
||||
} /* handlePenUpScore */
|
||||
#endif
|
||||
|
||||
/* Called when user taps on the board and a tray tile's selected.
|
||||
*/
|
||||
static XP_Bool
|
||||
|
@ -2943,35 +2695,6 @@ shiftFocusUp( BoardCtxt* board, XP_Key key )
|
|||
(void)board_focusChanged( board, next, XP_TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
static XP_Bool
|
||||
moveScoreCursor( BoardCtxt* board, XP_Key key )
|
||||
{
|
||||
XP_Bool result = XP_TRUE;
|
||||
XP_U16 nPlayers = board->gi->nPlayers;
|
||||
XP_S16 scoreCursorLoc = board->scoreCursorLoc;
|
||||
|
||||
switch ( key ) {
|
||||
case XP_CURSOR_KEY_DOWN:
|
||||
case XP_CURSOR_KEY_RIGHT:
|
||||
++scoreCursorLoc;
|
||||
break;
|
||||
case XP_CURSOR_KEY_UP:
|
||||
case XP_CURSOR_KEY_LEFT:
|
||||
--scoreCursorLoc;
|
||||
break;
|
||||
default:
|
||||
result = XP_FALSE;
|
||||
}
|
||||
if ( scoreCursorLoc < 0 || scoreCursorLoc >= nPlayers ) {
|
||||
shiftFocusUp( board, key );
|
||||
} else {
|
||||
board->scoreCursorLoc = scoreCursorLoc;
|
||||
}
|
||||
board->scoreBoardInvalid = XP_TRUE;
|
||||
|
||||
return result;
|
||||
} /* moveScoreCursor */
|
||||
#endif /* KEYBOARD_NAV */
|
||||
|
||||
static XP_Bool
|
||||
|
|
|
@ -195,6 +195,8 @@ XP_Bool checkRevealTray( BoardCtxt* board );
|
|||
void invalTilesUnderRect( BoardCtxt* board, XP_Rect* rect );
|
||||
XP_Bool rectsIntersect( XP_Rect* rect1, XP_Rect* rect2 );
|
||||
|
||||
void board_selectPlayer( BoardCtxt* board, XP_U16 newPlayer );
|
||||
|
||||
#ifdef KEYBOARD_NAV
|
||||
XP_Bool tray_moveCursor( BoardCtxt* board, XP_Key cursorKey );
|
||||
XP_Bool tray_keyAction( BoardCtxt* board );
|
||||
|
|
|
@ -24,6 +24,7 @@ COMMONOBJDIR = ../common/$(PLATFORM)
|
|||
|
||||
COMMONSRC = \
|
||||
$(COMMONDIR)/board.c \
|
||||
$(COMMONDIR)/scorebdp.c \
|
||||
$(COMMONDIR)/tray.c \
|
||||
$(COMMONDIR)/draw.c \
|
||||
$(COMMONDIR)/model.c \
|
||||
|
@ -47,10 +48,11 @@ COMMONSRC = \
|
|||
COMMON1 = \
|
||||
$(COMMONOBJDIR)/board.o \
|
||||
$(COMMONOBJDIR)/tray.o \
|
||||
$(COMMONOBJDIR)/scorebdp.o \
|
||||
$(COMMONOBJDIR)/draw.o \
|
||||
$(COMMONOBJDIR)/model.o \
|
||||
|
||||
COMMON2 = \
|
||||
$(COMMONOBJDIR)/model.o \
|
||||
$(COMMONOBJDIR)/mscore.o \
|
||||
$(COMMONOBJDIR)/server.o \
|
||||
$(COMMONOBJDIR)/pool.o \
|
||||
|
|
319
common/scorebdp.c
Normal file
319
common/scorebdp.c
Normal file
|
@ -0,0 +1,319 @@
|
|||
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
||||
/*
|
||||
* Copyright 1997 - 2006 by Eric House (xwords@eehouse.org). All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "scorebdp.h"
|
||||
#include "boardp.h"
|
||||
#include "model.h"
|
||||
#include "game.h"
|
||||
#include "strutils.h"
|
||||
|
||||
#ifdef CPLUS
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static XP_Bool
|
||||
board_ScoreCallback( void* closure, XP_S16 player, XP_UCHAR* expl,
|
||||
XP_U16* explLen)
|
||||
{
|
||||
ModelCtxt* model = (ModelCtxt*)closure;
|
||||
return model_getPlayersLastScore( model, player,
|
||||
expl, explLen );
|
||||
} /* board_ScoreCallback */
|
||||
|
||||
typedef struct DrawScoreData {
|
||||
DrawScoreInfo dsi;
|
||||
XP_U16 height;
|
||||
XP_U16 width;
|
||||
} DrawScoreData;
|
||||
|
||||
void
|
||||
drawScoreBoard( BoardCtxt* board )
|
||||
{
|
||||
if ( board->scoreBoardInvalid ) {
|
||||
short i;
|
||||
|
||||
XP_U16 nPlayers = board->gi->nPlayers;
|
||||
|
||||
if ( nPlayers > 0 ) {
|
||||
ModelCtxt* model = board->model;
|
||||
XP_S16 curTurn = server_getCurrentTurn( board->server );
|
||||
XP_U16 selPlayer = board->selPlayer;
|
||||
XP_S16 nTilesInPool = server_countTilesInPool( board->server );
|
||||
XP_Rect scoreRect = board->scoreBdBounds;
|
||||
XP_S16* adjustDim;
|
||||
XP_S16* adjustPt;
|
||||
XP_U16 totalDim, extra, nShares, remWidth, remHeight, remDim;
|
||||
DrawScoreData* dp;
|
||||
DrawScoreData datum[MAX_NUM_PLAYERS];
|
||||
XP_S16 scores[MAX_NUM_PLAYERS];
|
||||
XP_Bool isVertical = !board->scoreSplitHor;
|
||||
#ifdef KEYBOARD_NAV
|
||||
XP_Rect cursorRect;
|
||||
XP_Rect* cursorRectP = NULL;
|
||||
XP_Bool focusAll = XP_FALSE;
|
||||
XP_S16 cursorIndex = -1;
|
||||
if ( board->focussed == OBJ_SCORE ) {
|
||||
focusAll = !board->focusHasDived;
|
||||
if ( !focusAll ) {
|
||||
cursorIndex = board->scoreCursorLoc;
|
||||
}
|
||||
}
|
||||
|
||||
/* XP_Bool focusAll = (board->focussed == OBJ_SCORE) */
|
||||
/* && !board->focusHasDived; */
|
||||
/* XP_S16 cursorIndex = ( (board->focussed == OBJ_SCORE) */
|
||||
/* && board->focusHasDived ) ? */
|
||||
/* board->scoreCursorLoc : -1; */
|
||||
#endif
|
||||
draw_scoreBegin( board->draw, &board->scoreBdBounds, nPlayers,
|
||||
dfsFor( board, OBJ_SCORE ) );
|
||||
|
||||
/* Let platform decide whether the rem: string should be given any
|
||||
space once there are no tiles left. On Palm that space is
|
||||
clickable to drop a menu, so will probably leave it. */
|
||||
draw_measureRemText( board->draw, &board->scoreBdBounds,
|
||||
nTilesInPool, &remWidth, &remHeight );
|
||||
remDim = isVertical? remHeight : remWidth;
|
||||
|
||||
if ( isVertical ) {
|
||||
adjustPt = &scoreRect.top;
|
||||
adjustDim = &scoreRect.height;
|
||||
} else {
|
||||
adjustPt = &scoreRect.left;
|
||||
adjustDim = &scoreRect.width;
|
||||
}
|
||||
|
||||
/* Get the scores from the model or by calculating them based on
|
||||
the end-of-game state. */
|
||||
if ( board->gameOver ) {
|
||||
model_figureFinalScores( model, scores, (XP_S16*)NULL );
|
||||
} else {
|
||||
for ( i = 0; i < nPlayers; ++i ) {
|
||||
scores[i] = model_getPlayerScore( model, i );
|
||||
}
|
||||
}
|
||||
|
||||
totalDim = remDim;
|
||||
|
||||
/* figure spacing for each scoreboard entry */
|
||||
XP_MEMSET( &datum, 0, sizeof(datum) );
|
||||
for ( dp = datum, i = 0; i < nPlayers; ++i, ++dp ) {
|
||||
LocalPlayer* lp = &board->gi->players[i];
|
||||
|
||||
/* This is a hack! */
|
||||
dp->dsi.lsc = board_ScoreCallback;
|
||||
dp->dsi.lscClosure = model;
|
||||
#ifdef KEYBOARD_NAV
|
||||
if ( (i == cursorIndex) || focusAll ) {
|
||||
dp->dsi.flags |= CELL_ISCURSOR;
|
||||
}
|
||||
#endif
|
||||
dp->dsi.playerNum = i;
|
||||
dp->dsi.score = scores[i];
|
||||
dp->dsi.isTurn = (i == curTurn);
|
||||
dp->dsi.name = emptyStringIfNull(lp->name);
|
||||
dp->dsi.selected = board->trayVisState != TRAY_HIDDEN
|
||||
&& i==selPlayer;
|
||||
dp->dsi.isRobot = lp->isRobot;
|
||||
dp->dsi.isRemote = !lp->isLocal;
|
||||
dp->dsi.nTilesLeft = (nTilesInPool > 0)? -1:
|
||||
model_getNumTilesTotal( model, i );
|
||||
draw_measureScoreText( board->draw, &scoreRect,
|
||||
&dp->dsi, &dp->width, &dp->height );
|
||||
totalDim += isVertical ? dp->height : dp->width;
|
||||
}
|
||||
|
||||
/* break extra space into chunks, one to follow REM and another to
|
||||
preceed the timer, and then one for each player. Generally the
|
||||
player's score will be centered in the rect it's given, so in
|
||||
effect we're putting half the chunk on either side. The goal
|
||||
here is for the scores to be closer to each other than they are
|
||||
to the rem: string and timer on the ends. */
|
||||
nShares = nPlayers;
|
||||
XP_ASSERT( *adjustDim >= totalDim );
|
||||
extra = (*adjustDim - totalDim) / nShares;
|
||||
|
||||
/* at this point, the scoreRect should be anchored at the
|
||||
scoreboard rect's upper left. */
|
||||
|
||||
if ( remDim > 0 ) {
|
||||
*adjustDim = remDim;
|
||||
|
||||
draw_drawRemText( board->draw, &scoreRect, &scoreRect,
|
||||
nTilesInPool );
|
||||
|
||||
*adjustPt += remDim;
|
||||
}
|
||||
|
||||
board->remDim = remDim; /* save now so register can be reused */
|
||||
|
||||
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;
|
||||
|
||||
innerRect.width = dp->width;
|
||||
innerRect.height = dp->height;
|
||||
innerRect.left = scoreRect.left +
|
||||
((scoreRect.width - innerRect.width) / 2);
|
||||
innerRect.top = scoreRect.top +
|
||||
((scoreRect.height - innerRect.height) / 2);
|
||||
|
||||
draw_score_drawPlayer( board->draw, &innerRect, &scoreRect,
|
||||
&dp->dsi );
|
||||
#ifdef KEYBOARD_NAV
|
||||
if ( i == cursorIndex ) {
|
||||
cursorRect = scoreRect;
|
||||
cursorRectP = &cursorRect;
|
||||
}
|
||||
#endif
|
||||
*adjustPt += *adjustDim;
|
||||
}
|
||||
|
||||
#ifdef KEYBOARD_NAV
|
||||
if ( !!cursorRectP ) {
|
||||
draw_drawCursor( board->draw, OBJ_SCORE, cursorRectP );
|
||||
}
|
||||
#endif
|
||||
|
||||
draw_objFinished( board->draw, OBJ_SCORE, &board->scoreBdBounds,
|
||||
dfsFor( board, OBJ_SCORE ) );
|
||||
}
|
||||
|
||||
board->scoreBoardInvalid = XP_FALSE;
|
||||
}
|
||||
|
||||
drawTimer( board );
|
||||
} /* drawScoreBoard */
|
||||
|
||||
static XP_S16
|
||||
figureSecondsLeft( BoardCtxt* board )
|
||||
{
|
||||
CurGameInfo* gi = board->gi;
|
||||
XP_U16 secondsUsed = gi->players[board->selPlayer].secondsUsed;
|
||||
XP_U16 secondsAvailable = gi->gameSeconds / gi->nPlayers;
|
||||
XP_ASSERT( gi->timerEnabled );
|
||||
return secondsAvailable - secondsUsed;
|
||||
} /* figureSecondsLeft */
|
||||
|
||||
void
|
||||
drawTimer( BoardCtxt* board )
|
||||
{
|
||||
if ( board->gi->timerEnabled ) {
|
||||
XP_S16 secondsLeft = figureSecondsLeft( board );
|
||||
|
||||
draw_drawTimer( board->draw, &board->timerBounds, &board->timerBounds,
|
||||
board->selPlayer, secondsLeft );
|
||||
}
|
||||
} /* drawTimer */
|
||||
|
||||
void
|
||||
board_setScoreboardLoc( BoardCtxt* board, XP_U16 scoreLeft, XP_U16 scoreTop,
|
||||
XP_U16 scoreWidth, XP_U16 scoreHeight,
|
||||
XP_Bool divideHorizontally )
|
||||
{
|
||||
board->scoreBdBounds.left = scoreLeft;
|
||||
board->scoreBdBounds.top = scoreTop;
|
||||
board->scoreBdBounds.width = scoreWidth;
|
||||
board->scoreBdBounds.height = scoreHeight;
|
||||
board->scoreSplitHor = divideHorizontally;
|
||||
} /* board_setScoreboardLoc */
|
||||
|
||||
XP_S16
|
||||
figureScorePlayerTapped( BoardCtxt* board, XP_U16 x, XP_U16 y )
|
||||
{
|
||||
XP_S16 result = -1;
|
||||
XP_S16 left;
|
||||
XP_U16 nPlayers = board->gi->nPlayers;
|
||||
|
||||
if ( board->scoreSplitHor ) {
|
||||
left = x - board->scoreBdBounds.left;
|
||||
} else {
|
||||
left = y - board->scoreBdBounds.top;
|
||||
}
|
||||
|
||||
left -= board->remDim;
|
||||
if ( left >= 0 ) {
|
||||
for ( result = 0; result < nPlayers; ++result ) {
|
||||
if ( left < board->scoreDims[result] ) {
|
||||
break;
|
||||
}
|
||||
left -= board->scoreDims[result];
|
||||
}
|
||||
}
|
||||
if ( result >= nPlayers ) {
|
||||
result = -1;
|
||||
}
|
||||
return result;
|
||||
} /* figureScorePlayerTapped */
|
||||
|
||||
/* If the pen also went down on the scoreboard, make the selected player the
|
||||
* one closest to the mouse up loc.
|
||||
*/
|
||||
#ifdef POINTER_SUPPORT
|
||||
XP_Bool
|
||||
handlePenUpScore( BoardCtxt* board, XP_U16 x, XP_U16 y )
|
||||
{
|
||||
XP_Bool result = XP_FALSE;
|
||||
|
||||
XP_S16 playerNum = figureScorePlayerTapped( board, x, y );
|
||||
|
||||
if ( playerNum >= 0 ) {
|
||||
board_selectPlayer( board, playerNum );
|
||||
|
||||
result = XP_TRUE;
|
||||
}
|
||||
return result;
|
||||
} /* handlePenUpScore */
|
||||
#endif
|
||||
|
||||
#ifdef KEYBOARD_NAV
|
||||
XP_Bool
|
||||
moveScoreCursor( BoardCtxt* board, XP_Key key )
|
||||
{
|
||||
XP_Bool result = XP_TRUE;
|
||||
XP_U16 nPlayers = board->gi->nPlayers;
|
||||
XP_S16 scoreCursorLoc = board->scoreCursorLoc;
|
||||
|
||||
switch ( key ) {
|
||||
case XP_CURSOR_KEY_DOWN:
|
||||
case XP_CURSOR_KEY_RIGHT:
|
||||
++scoreCursorLoc;
|
||||
break;
|
||||
case XP_CURSOR_KEY_UP:
|
||||
case XP_CURSOR_KEY_LEFT:
|
||||
--scoreCursorLoc;
|
||||
break;
|
||||
default:
|
||||
result = XP_FALSE;
|
||||
}
|
||||
if ( scoreCursorLoc < 0 || scoreCursorLoc >= nPlayers ) {
|
||||
shiftFocusUp( board, key );
|
||||
} else {
|
||||
board->scoreCursorLoc = scoreCursorLoc;
|
||||
}
|
||||
board->scoreBoardInvalid = XP_TRUE;
|
||||
|
||||
return result;
|
||||
} /* moveScoreCursor */
|
||||
#endif /* KEYBOARD_NAV */
|
||||
|
||||
#ifdef CPLUS
|
||||
}
|
||||
#endif
|
37
common/scorebdp.h
Normal file
37
common/scorebdp.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
||||
/*
|
||||
* Copyright 1997 - 2006 by Eric House (xwords@eehouse.org). All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _SCOREBDP_H_
|
||||
#define _SCOREBDP_H_
|
||||
|
||||
#include "boardp.h"
|
||||
|
||||
void drawScoreBoard( BoardCtxt* board );
|
||||
XP_S16 figureScorePlayerTapped( BoardCtxt* board, XP_U16 x, XP_U16 y );
|
||||
void drawTimer( BoardCtxt* board );
|
||||
|
||||
#ifdef POINTER_SUPPORT
|
||||
XP_Bool handlePenUpScore( BoardCtxt* board, XP_U16 x, XP_U16 y );
|
||||
#endif
|
||||
|
||||
#ifdef KEYBOARD_NAV
|
||||
XP_Bool moveScoreCursor( BoardCtxt* board, XP_Key key );
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue