Merge branch 'android_branch' into send_in_background

This commit is contained in:
Eric House 2011-09-07 21:44:36 -07:00
commit 84931f34ff
29 changed files with 289 additions and 295 deletions

View file

@ -1,4 +1,4 @@
/* Keep these in sync with the constants in XW_UtilCtxt.java */
/* Keep these in sync with the constants in UtilCtxt.java */
#ifndef _LOCALIZEDSTRINCLUDES_H_
@ -24,10 +24,8 @@
# define STRD_TRADED 18
# define STR_LOSTTURN 19
# define STR_COMMIT_CONFIRM 20
# define STR_LOCAL_NAME 21
# define STR_NONLOCAL_NAME 22
# define STR_BONUS_ALL 23
# define STRD_TURN_SCORE 24
# define STR_BONUS_ALL 21
# define STRD_TURN_SCORE 22
# define N_AND_USER_STRINGS 24
# define N_AND_USER_STRINGS 22
#endif

View file

@ -513,6 +513,7 @@ makeDict( MPFORMAL JNIEnv *env, JNIUtilCtxt* jniutil, jstring jname,
/* copy the name */
anddict->super.name = getStringCopy( MPPARM(mpool) env, jname );
XP_LOGF( "%s: setting dict name: %s", __func__, anddict->super.name );
anddict->super.langName = getStringCopy( MPPARM(mpool) env, jlangname );
return (DictionaryCtxt*)anddict;

View file

@ -390,14 +390,6 @@ and_util_setIsServer(XW_UtilCtxt* uc, XP_Bool isServer )
}
#ifndef XWFEATURE_MINIWIN
static void
and_util_setInTrade( XW_UtilCtxt* uc, XP_U16 turn, XP_Bool entering )
{
UTIL_CBK_HEADER("setInTrade", "(IZ)V" );
(*env)->CallVoidMethod( env, util->jutil, mid, turn, entering );
UTIL_CBK_TAIL();
}
static void
and_util_bonusSquareHeld( XW_UtilCtxt* uc, XWBonusType bonus )
{
@ -407,12 +399,10 @@ and_util_bonusSquareHeld( XW_UtilCtxt* uc, XWBonusType bonus )
}
static void
and_util_playerScoreHeld( XW_UtilCtxt* uc, const XP_UCHAR* txt )
and_util_playerScoreHeld( XW_UtilCtxt* uc, XP_U16 player )
{
UTIL_CBK_HEADER( "playerScoreHeld", "(Ljava/lang/String;)V" );
jstring jmsg = (*env)->NewStringUTF( env, txt );
(*env)->CallVoidMethod( env, util->jutil, mid, jmsg );
(*env)->DeleteLocalRef( env, jmsg );
UTIL_CBK_HEADER( "playerScoreHeld", "(I)V" );
(*env)->CallVoidMethod( env, util->jutil, mid, player );
UTIL_CBK_TAIL();
}
#endif
@ -502,7 +492,6 @@ makeUtil( MPFORMAL JNIEnv** envp, jobject jutil, CurGameInfo* gi,
SET_PROC(setIsServer);
#ifndef XWFEATURE_MINIWIN
SET_PROC(setInTrade);
SET_PROC(bonusSquareHeld);
SET_PROC(playerScoreHeld);
#endif

View file

@ -907,6 +907,25 @@ Java_org_eehouse_android_xw4_jni_XwJNI_model_1getNMoves
return result;
}
JNIEXPORT jstring JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_model_1getPlayersLastScore
(JNIEnv* env, jclass C, jint gamePtr, jint player )
{
jstring result = NULL;
XWJNI_START();
XP_ASSERT( !!state->game.model );
XP_UCHAR buf[64];
XP_U16 buflen = sizeof(buf);
if ( !model_getPlayersLastScore( state->game.model, player, buf,
&buflen ) ) {
buf[0] = '\0';
}
result = (*env)->NewStringUTF( env, buf );
(*env)->DeleteLocalRef( env, result );
XWJNI_END();
return result;
}
JNIEXPORT jstring JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_server_1writeFinalScores
( JNIEnv* env, jclass C, jint gamePtr )

View file

@ -98,8 +98,6 @@
<string name="strsd_summaryscored"></string>
<string name="str_lostturn">Torn perdut</string>
<string name="str_commit_confirm">Voleu fer la jugada?\n</string>
<string name="str_local_name">%s</string>
<string name="str_nonlocal_namef">%s (remot)</string>
<string name="str_bonus_all">Bonificació per usar totes les fitxes: 50\n</string>
<string name="strd_turn_score">Puntuació del torn: %d\n</string>
@ -110,7 +108,6 @@
<string name="str_tiles_must_contact">Les fitxes noves han de tocar alguna de les que ja estan jugades al tauler (o la casella central en la primera jugada).</string>
<string name="str_not_your_turn">No podeu fer això, no és el vostre torn!</string>
<string name="str_no_peek_robot_tiles">No podeu mirar les fitxes del robot!</string>
<string name="str_cant_trade_mid_move">Recolliu les fitxes posades al tauler abans de canviar fitxer.</string>
<string name="str_too_few_tiles_left_to_trade">Hi ha poques fitxes al saquet i ja no podeu canviar-les.</string>
<string name="str_cant_undo_tileassign">L\'assignació de fitxers no es pot desfer.</string>
<string name="str_cant_hint_while_disabled">Les pistes es troben inhabilitades per a aquesta partida. Habiliteu-les per a una partida nova al menú Preferències.</string>

View file

@ -97,8 +97,6 @@
<string name="strsd_summaryscored">%1$s:%2$d</string>
<string name="str_lostturn">Tah byl ztracen</string>
<string name="str_commit_confirm">Potvrdit tento tah?\n</string>
<string name="str_local_name">%s</string>
<string name="str_nonlocal_namef">%s (vzdálený)</string>
<string name="str_bonus_all">Bonus za využití všech kamenů: 50\n</string>
<string name="strd_turn_score">Skóre za tah: %d\n</string>
@ -109,7 +107,6 @@
<string name="str_tiles_must_contact">Nové kameny musí navazovat na již položené kameny (nebo se s nimi křížit).</string>
<string name="str_not_your_turn">To nemůžete udělat; není to váš tah!</string>
<string name="str_no_peek_robot_tiles">Nenakukujte na kameny robota!</string>
<string name="str_cant_trade_mid_move">Vzdálený hráč hrál s kameny před výměnou.</string>
<string name="str_too_few_tiles_left_to_trade">Zbývá příliš málo kamenů pro výměnu.</string>
<string name="str_cant_undo_tileassign">Přiřazení kamene nemůže být vráceno zpět.</string>
<string name="str_cant_hint_while_disabled">Pro tuto hru je zakázána nápověda. Pro novou hru ji můžete povolit v Předvolbách.</string>

View file

@ -96,8 +96,6 @@
<string name="strsd_summaryscored">%1$s:%2$d</string>
<string name="str_lostturn">Ťah bol stratený</string>
<string name="str_commit_confirm">Potvrdiť tento ťah?\n</string>
<string name="str_local_name">%s</string>
<string name="str_nonlocal_namef">%s (vzdialený)</string>
<string name="str_bonus_all">Bonus za využitie všetkých kameňov: 50\n</string>
<string name="strd_turn_score">Skóre za ťah: %d\n</string>
@ -108,7 +106,6 @@
<string name="str_tiles_must_contact">Nové kamene musia naväzovať na už položené kamene (alebo sa s nimi krížiť).</string>
<string name="str_not_your_turn">To nemôžete spraviť; nie je to váš ťah!</string>
<string name="str_no_peek_robot_tiles">Nenakúkajte na kamene robota!</string>
<string name="str_cant_trade_mid_move">Vzdialený hráč hral s kameňmi pred výmenou.</string>
<string name="str_too_few_tiles_left_to_trade">Zostáva príliž málo kameňov na výmenu.</string>
<string name="str_cant_undo_tileassign">Priradenie kameňa nemôže byť vrátené spät.</string>
<string name="str_cant_hint_while_disabled">Pre túto hru je zakázaná nápoveda. Pre novú hru ju môžete povoliť v Predvolbách.</string>

View file

@ -92,6 +92,7 @@
<string name="logging_on">Enable logging</string>
<string name="relay_port">Relay game port</string>
<string name="proxy_port">Relay device port</string>
<string name="name_dict_fmt">%1$s/%2$s</string>
<!--string name="dict_url">http://10.0.2.2/~eehouse/and_dicts</string-->

View file

@ -119,11 +119,9 @@
<string name="strs_new_tiles">New tiles: %s</string>
<string name="str_passed">Passed</string>
<string name="strsd_summaryscored">%1$s:%2$d</string>
<string name="strd_traded">Traded %d</string>
<string name="strd_traded">Exchanged %d tiles</string>
<string name="str_lostturn">Lost turn</string>
<string name="str_commit_confirm">Commit the current move?\n</string>
<string name="str_local_name">%s</string>
<string name="str_nonlocal_name">(remote)</string>
<string name="str_nonlocal_namef">%s (remote)</string>
<string name="vs_join">\u0020vs.\u0020</string>
<string name="str_game_namef">%1$s (%2$s)</string>
@ -137,7 +135,6 @@
<string name="str_tiles_must_contact">New pieces must contact others already in place (or the middle square on the first move)</string>
<string name="str_not_your_turn">You can\'t do that; it\'s not your turn!</string>
<string name="str_no_peek_robot_tiles">No peeking at the robot\'s tiles!</string>
<string name="str_cant_trade_mid_move">Remove played tiles before exchanging.</string>
<string name="str_no_empty_trade">Trade cancelled because no tiles
selected. (It\'s still your turn.)</string>
<string name="str_too_few_tiles_left_to_trade">Too few tiles left to exchange.</string>
@ -545,12 +542,11 @@
as a template.</string>
<string name="not_again_trading">You are entering tile-exchange
mode. Tap tiles to add/remove from the set to be exchanged, and
use the menu to commit your turn or exit exchange mode.</string>
mode. Tap tiles to add/remove them from the set to be
exchanged. Use the buttons to commit your turn or exit exchange
mode.</string>
<string name="entering_trade">Entering trade mode; use menu to
exit</string>
<string name="exiting_trade">Exiting trade mode</string>
<string name="entering_trade">Entering exchange mode</string>
<string name="relay_game_explainf">To start a basic networked two-player
game in %s:</string>
@ -613,4 +609,6 @@
when creating new games. (You can change it later in the \"New
game default\" section of Settings.)</string>
<string name="no_moves_made">(No moves yet)</string>
</resources>

View file

@ -14,11 +14,13 @@
<org.eehouse.android.xw4.XWEditTextPreference
android:key="@string/key_player1_name"
android:title="@string/pref_player1_name"
android:capitalize="words"
android:defaultValue=""
/>
<org.eehouse.android.xw4.XWEditTextPreference
android:key="@string/key_player2_name"
android:title="@string/pref_player2_name"
android:capitalize="words"
android:defaultValue="ignored"
android:summary="@string/tell_unused"
android:enabled="false"
@ -26,6 +28,7 @@
<org.eehouse.android.xw4.XWEditTextPreference
android:key="@string/key_player3_name"
android:title="@string/pref_player3_name"
android:capitalize="words"
android:defaultValue=""
android:summary="@string/tell_unused"
android:enabled="false"
@ -33,6 +36,7 @@
<org.eehouse.android.xw4.XWEditTextPreference
android:key="@string/key_player4_name"
android:title="@string/pref_player4_name"
android:capitalize="words"
android:defaultValue=""
android:summary="@string/tell_unused"
android:enabled="false"

View file

@ -342,8 +342,6 @@ public class BoardActivity extends XWActivity
setContentView( R.layout.board );
m_timers = new TimerRunnable[4]; // needs to be in sync with
// XWTimerReason
m_gi = new CurGameInfo( this );
m_view = (BoardView)findViewById( R.id.board_view );
m_tradeButtons = findViewById( R.id.exchange_buttons );
m_exchCommmitButton = (Button)findViewById( R.id.exchange_commit );
@ -516,7 +514,9 @@ public class BoardActivity extends XWActivity
// cmd = JNIThread.JNICmd.CMD_FLIP;
// break;
case R.id.board_menu_trade:
cmd = JNIThread.JNICmd.CMD_TRADE;
showNotAgainDlgThen( R.string.not_again_trading,
R.string.key_notagain_trading,
START_TRADE_ACTION );
break;
case R.id.board_menu_tray:
@ -595,15 +595,16 @@ public class BoardActivity extends XWActivity
m_gi.nPlayers );
}
} else if ( AlertDialog.BUTTON_POSITIVE == which ) {
JNIThread.JNICmd cmd = JNIThread.JNICmd.CMD_NONE;
switch ( id ) {
case UNDO_LAST_ACTION:
m_jniThread.handle( JNIThread.JNICmd.CMD_UNDO_LAST );
cmd = JNIThread.JNICmd.CMD_UNDO_LAST;
break;
case SYNC_ACTION:
doSyncMenuitem();
break;
case COMMIT_ACTION:
checkAndHandle( JNIThread.JNICmd.CMD_COMMIT );
cmd = JNIThread.JNICmd.CMD_COMMIT;
break;
case SHOW_EXPL_ACTION:
Toast.makeText( BoardActivity.this, m_toastStr,
@ -611,37 +612,38 @@ public class BoardActivity extends XWActivity
m_toastStr = null;
break;
case PREV_HINT_ACTION:
checkAndHandle( JNIThread.JNICmd.CMD_PREV_HINT );
cmd = JNIThread.JNICmd.CMD_PREV_HINT;
break;
case NEXT_HINT_ACTION:
checkAndHandle( JNIThread.JNICmd.CMD_NEXT_HINT );
cmd = JNIThread.JNICmd.CMD_NEXT_HINT;
break;
case JUGGLE_ACTION:
checkAndHandle( JNIThread.JNICmd.CMD_JUGGLE );
cmd = JNIThread.JNICmd.CMD_JUGGLE;
break;
case FLIP_ACTION:
checkAndHandle( JNIThread.JNICmd.CMD_FLIP );
cmd = JNIThread.JNICmd.CMD_FLIP;
break;
case ZOOM_ACTION:
checkAndHandle( JNIThread.JNICmd.CMD_TOGGLEZOOM );
cmd = JNIThread.JNICmd.CMD_TOGGLEZOOM;
break;
case UNDO_ACTION:
checkAndHandle( JNIThread.JNICmd.CMD_UNDO_CUR );
cmd = JNIThread.JNICmd.CMD_UNDO_CUR;
break;
case CHAT_ACTION:
startChatActivity();
break;
case START_TRADE_ACTION:
m_view.setInTrade( m_inTrade );
Toast.makeText( this, getString( m_inTrade?
R.string.entering_trade
: R.string.exiting_trade),
Toast.makeText( this, R.string.entering_trade,
Toast.LENGTH_SHORT).show();
cmd = JNIThread.JNICmd.CMD_TRADE;
break;
default:
Assert.fail();
}
if ( JNIThread.JNICmd.CMD_NONE != cmd ) {
checkAndHandle( cmd );
}
}
}
@ -893,27 +895,6 @@ public class BoardActivity extends XWActivity
}
}
@Override
public void setInTrade( int turn, final boolean entering )
{
if ( m_inTrade != entering ) {
m_inTrade = entering;
post( new Runnable() {
public void run() {
adjustTradeVisibility();
if ( m_inTrade ) {
showNotAgainDlgThen( R.string.not_again_trading,
R.string.key_notagain_trading,
START_TRADE_ACTION );
} else {
dlgButtonClicked( START_TRADE_ACTION,
AlertDialog.BUTTON_POSITIVE );
}
}
} );
}
}
@Override
public void bonusSquareHeld( int bonus )
{
@ -947,8 +928,15 @@ public class BoardActivity extends XWActivity
}
@Override
public void playerScoreHeld( final String text )
public void playerScoreHeld( int player )
{
String expl = XwJNI.model_getPlayersLastScore( m_jniGamePtr,
player );
if ( expl.length() == 0 ) {
expl = getString( R.string.no_moves_made );
}
String name = m_gi.players[player].name;
final String text = String.format( "%s\n%s", name, expl );
post( new Runnable() {
public void run() {
Toast.makeText( BoardActivity.this, text,
@ -1089,9 +1077,6 @@ public class BoardActivity extends XWActivity
case UtilCtxt.ERR_NO_PEEK_ROBOT_TILES:
resid = R.string.str_no_peek_robot_tiles;
break;
case UtilCtxt.ERR_CANT_TRADE_MID_MOVE:
resid = R.string.str_cant_trade_mid_move;
break;
case UtilCtxt.ERR_NO_EMPTY_TRADE:
resid = R.string.str_no_empty_trade;
break;
@ -1184,20 +1169,19 @@ public class BoardActivity extends XWActivity
private void loadGame()
{
if ( 0 == m_jniGamePtr ) {
String[] dictNames = m_gi.dictNames();
String[] dictNames = GameUtils.dictNames( this, m_rowid );
GameUtils.DictPairs pairs = GameUtils.openDicts( this, dictNames );
if ( pairs.anyMissing( dictNames ) ) {
showDictGoneFinish();
} else {
String langName = m_gi.langName();
Assert.assertNull( m_gameLock );
m_gameLock = new GameUtils.GameLock( m_rowid, true ).lock();
byte[] stream = GameUtils.savedGame( this, m_gameLock );
m_gi = new CurGameInfo( this );
XwJNI.gi_from_stream( m_gi, stream );
String langName = m_gi.langName();
m_jniGamePtr = XwJNI.initJNI();
@ -1237,6 +1221,11 @@ public class BoardActivity extends XWActivity
m_gsi =
m_jniThread.getGameStateInfo();
updateToolbar();
if ( m_inTrade != m_gsi.inTrade ) {
m_inTrade = m_gsi.inTrade;
adjustTradeVisibility();
m_view.setInTrade( m_inTrade );
}
}
break;
}
@ -1416,6 +1405,7 @@ public class BoardActivity extends XWActivity
XwJNI.game_dispose( m_jniGamePtr );
m_jniGamePtr = 0;
m_gi = null;
m_gameLock.unlock();
m_gameLock = null;

View file

@ -44,6 +44,7 @@ public class BoardView extends View implements DrawCtx, BoardHandler,
private static final float MIN_FONT_DIPS = 14.0f;
private static Bitmap s_bitmap; // the board
private static final int IN_TRADE_ALPHA = 0x3FFFFFFF;
private Context m_context;
private Paint m_drawPaint;
@ -425,7 +426,11 @@ public class BoardView extends View implements DrawCtx, BoardHandler,
fillRectOther( rOuter, CommonPrefs.COLOR_FOCUS );
}
String[] texts = m_scores[dsi.playerNum];
m_fillPaint.setColor( adjustColor(m_playerColors[dsi.playerNum]) );
int color = m_playerColors[dsi.playerNum];
if ( !CommonPrefs.get(m_context).allowPeek ) {
color = adjustColor( color );
}
m_fillPaint.setColor( color );
Rect rect = new Rect( rOuter );
int height = rect.height() / texts.length;
@ -510,6 +515,7 @@ public class BoardView extends View implements DrawCtx, BoardHandler,
if ( empty ) {
if ( (CELL_ISSTAR & flags) != 0 ) {
m_origin.setBounds( rect );
m_origin.setAlpha( m_inTrade? IN_TRADE_ALPHA >> 24 : 255 );
m_origin.draw( m_canvas );
} else if ( null != bonusStr ) {
int color = m_otherColors[CommonPrefs.COLOR_BONUSHINT];
@ -926,7 +932,7 @@ public class BoardView extends View implements DrawCtx, BoardHandler,
private int adjustColor( int color )
{
if ( m_inTrade ) {
color = color & 0x3FFFFFFF;
color = color & IN_TRADE_ALPHA;
}
return color;
}

View file

@ -128,11 +128,11 @@ public class DBUtils {
setGiFlags( cursor.getInt(cursor.
getColumnIndex(DBHelper.GIFLAGS))
);
summary.players =
parsePlayers( cursor.getString(cursor.
getColumnIndex(DBHelper.
PLAYERS)),
summary.nPlayers );
String players = cursor.
getString(cursor.getColumnIndex( DBHelper.PLAYERS ));
summary.readPlayers( players );
summary.dictLang =
cursor.getInt(cursor.
getColumnIndex(DBHelper.DICTLANG));
@ -761,31 +761,6 @@ public class DBUtils {
}
}
private static String[] parsePlayers( final String players, int nPlayers ){
String[] result = null;
if ( null != players ) {
result = new String[nPlayers];
String sep = "vs. ";
if ( players.contains("\n") ) {
sep = "\n";
}
int ii, nxt;
for ( ii = 0, nxt = 0; ; ++ii ) {
int prev = nxt;
nxt = players.indexOf( sep, nxt );
String name = -1 == nxt ?
players.substring( prev ) : players.substring( prev, nxt );
result[ii] = name;
if ( -1 == nxt ) {
break;
}
nxt += sep.length();
}
}
return result;
}
private static void initDB( Context context )
{
if ( null == s_dbHelper ) {

View file

@ -167,7 +167,7 @@ public class GameConfig extends XWActivity
onClick( DialogInterface dlg,
int button ) {
getPlayerSettings( dlg );
loadPlayers();
loadPlayersList();
}
})
.setNegativeButton( R.string.button_cancel, null )
@ -192,18 +192,19 @@ public class GameConfig extends XWActivity
// break;
case FORCE_REMOTE:
dlpos = new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg,
int whichButton ) {
loadPlayersList();
}
};
dialog = new AlertDialog.Builder( this )
.setTitle( R.string.force_title )
.setView( Utils.inflate( this, layoutForDlg(id) ) )
.setPositiveButton( R.string.button_ok,
new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg,
int whichButton ) {
loadPlayers();
}
})
.setPositiveButton( R.string.button_ok, dlpos )
.create();
dialog.setOnDismissListener( new DialogInterface.OnDismissListener() {
DialogInterface.OnDismissListener dismiss =
new DialogInterface.OnDismissListener() {
@Override
public void onDismiss( DialogInterface di )
{
@ -211,10 +212,11 @@ public class GameConfig extends XWActivity
Toast.makeText( GameConfig.this,
R.string.forced_consistent,
Toast.LENGTH_SHORT).show();
loadPlayers();
loadPlayersList();
}
}
});
};
dialog.setOnDismissListener( dismiss );
break;
case CONFIRM_CHANGE_PLAY:
case CONFIRM_CHANGE:
@ -348,9 +350,11 @@ public class GameConfig extends XWActivity
Spinner spinner =
(Spinner)((Dialog)di).findViewById( R.id.dict_spinner );
int position = spinner.getSelectedItemPosition();
String[] dicts = DictLangCache.getHaveLang( this, m_gi.dictLang );
if ( position < dicts.length ) {
lp.dictName = dicts[position];
ArrayAdapter<String> adapter =
(ArrayAdapter<String>)spinner.getAdapter();
if ( position < adapter.getCount() ) {
lp.dictName = adapter.getItem(position);
}
lp.setIsRobot( Utils.getChecked( dialog, R.id.robot_check ) );
@ -453,7 +457,9 @@ public class GameConfig extends XWActivity
handleLockedChange();
}
m_gi = new CurGameInfo( this, m_giOrig );
if ( null == m_gi ) {
m_gi = new CurGameInfo( this, m_giOrig );
}
m_carOrig = new CommsAddrRec( this );
if ( XwJNI.game_hasComms( gamePtr ) ) {
@ -493,7 +499,7 @@ public class GameConfig extends XWActivity
adjustConnectStuff();
}
loadPlayers();
loadPlayersList();
configLangSpinner();
m_phoniesSpinner.setSelection( m_gi.phoniesAction.ordinal() );
@ -530,7 +536,7 @@ public class GameConfig extends XWActivity
public void deleteCalled( int myPosition, final String name )
{
if ( m_gi.delete( myPosition ) ) {
loadPlayers();
loadPlayersList();
}
}
@ -560,11 +566,11 @@ public class GameConfig extends XWActivity
int curIndex = m_gi.nPlayers;
if ( curIndex < CurGameInfo.MAX_NUM_PLAYERS ) {
m_gi.addPlayer(); // ups nPlayers
loadPlayers();
loadPlayersList();
}
} else if ( m_jugglePlayersButton == view ) {
m_gi.juggle();
loadPlayers();
loadPlayersList();
} else if ( m_joinPublicCheck == view ) {
adjustConnectStuff();
} else if ( m_gameLockedCheck == view ) {
@ -617,11 +623,11 @@ public class GameConfig extends XWActivity
return consumed || super.onKeyDown( keyCode, event );
}
private void loadPlayers()
private void loadPlayersList()
{
m_playerLayout.removeAllViews();
String[] names = m_gi.visibleNames();
String[] names = m_gi.visibleNames( false );
// only enable delete if one will remain (or two if networked)
boolean canDelete = names.length > 2
|| (m_notNetworkedGame && names.length > 1);
@ -667,7 +673,7 @@ public class GameConfig extends XWActivity
showDialog( FORCE_REMOTE );
}
adjustPlayersLabel();
} // loadPlayers
} // loadPlayersList
private String[] buildListWithBrowse( String[] input )
{
@ -683,7 +689,7 @@ public class GameConfig extends XWActivity
return result;
}
private void configDictSpinner( final Dialog dialog, final LocalPlayer lp )
private void configDictSpinner( final Dialog dialog, LocalPlayer lp )
{
Spinner dictsSpinner =
(Spinner)dialog.findViewById( R.id.dict_spinner );
@ -703,8 +709,6 @@ public class GameConfig extends XWActivity
if ( chosen.equals( m_browseText ) ) {
DictsActivity.launchAndDownload( GameConfig.this,
m_gi.dictLang );
} else {
lp.dictName = chosen;
}
}

View file

@ -461,6 +461,23 @@ public class GameUtils {
}
}
public static String[] dictNames( Context context, long rowid,
int[] missingLang )
{
byte[] stream = savedGame( context, rowid );
CurGameInfo gi = new CurGameInfo( context );
XwJNI.gi_from_stream( gi, stream );
if ( null != missingLang ) {
missingLang[0] = gi.dictLang;
}
return gi.dictNames();
}
public static String[] dictNames( Context context, long rowid )
{
return dictNames( context, rowid, null );
}
public static boolean gameDictsHere( Context context, long rowid )
{
return gameDictsHere( context, rowid, null, null );
@ -472,17 +489,10 @@ public class GameUtils {
String[][] missingNames,
int[] missingLang )
{
byte[] stream = savedGame( context, rowid );
CurGameInfo gi = new CurGameInfo( context );
XwJNI.gi_from_stream( gi, stream );
final String[] dictNames = gi.dictNames();
String[] dictNames = dictNames( context, rowid, missingLang );
HashSet<String> missingSet;
String[] installed = dictList( context );
if ( null != missingLang ) {
missingLang[0] = gi.dictLang;
}
missingSet = new HashSet<String>( Arrays.asList( dictNames ) );
missingSet.remove( null );
missingSet.removeAll( Arrays.asList(installed) );

View file

@ -235,18 +235,22 @@ public class CurGameInfo {
return !consistent;
}
public String[] visibleNames()
public String[] visibleNames( boolean withDicts )
{
String nameFmt = withDicts? m_context.getString( R.string.name_dict_fmt )
: "%s";
String[] names = new String[nPlayers];
for ( int ii = 0; ii < nPlayers; ++ii ) {
LocalPlayer lp = players[ii];
if ( lp.isLocal || serverRole == DeviceRole.SERVER_STANDALONE ) {
String name;
if ( lp.isRobot() ) {
String format = m_context.getString( R.string.robot_namef );
names[ii] = String.format( format, lp.name );
name = String.format( format, lp.name );
} else {
names[ii] = lp.name;
name = lp.name;
}
names[ii] = String.format( nameFmt, name, dictName(lp) );
} else {
names[ii] = m_context.getString( R.string.guest_name );
}

View file

@ -97,6 +97,33 @@ public class GameSummary {
return result;
}
public void readPlayers( String playersStr )
{
if ( null != playersStr ) {
players = new String[nPlayers];
String sep;
if ( playersStr.contains("\n") ) {
sep = "\n";
} else {
sep = m_context.getString( R.string.vs_join );
}
int ii, nxt;
for ( ii = 0, nxt = 0; ; ++ii ) {
int prev = nxt;
nxt = playersStr.indexOf( sep, nxt );
String name = -1 == nxt ?
playersStr.substring( prev ) :
playersStr.substring( prev, nxt );
players[ii] = name;
if ( -1 == nxt ) {
break;
}
nxt += sep.length();
}
}
}
public void setPlayerSummary( String summary )
{
m_playersSummary = summary;
@ -213,7 +240,7 @@ public class GameSummary {
{
String[] names = null;
if ( null != m_gi ) {
names = m_gi.visibleNames();
names = m_gi.visibleNames( false );
} else if ( null != m_playersSummary ) {
names = TextUtils.split( m_playersSummary, "\n" );
}

View file

@ -47,9 +47,8 @@ public interface UtilCtxt {
void remSelected();
void setIsServer( boolean isServer );
void setInTrade( int turn, boolean entering );
void bonusSquareHeld( int bonus );
void playerScoreHeld( String text );
void playerScoreHeld( int player );
static final int STRD_ROBOT_TRADED = 1;
static final int STR_ROBOT_MOVED = 2;
@ -71,10 +70,8 @@ public interface UtilCtxt {
static final int STRD_TRADED = 18;
static final int STR_LOSTTURN = 19;
static final int STR_COMMIT_CONFIRM = 20;
static final int STR_LOCAL_NAME = 21;
static final int STR_NONLOCAL_NAME = 22;
static final int STR_BONUS_ALL = 23;
static final int STRD_TURN_SCORE = 24;
static final int STR_BONUS_ALL = 21;
static final int STRD_TURN_SCORE = 22;
String getUserString( int stringCode );
static final int QUERY_COMMIT_TURN = 0;
@ -98,11 +95,10 @@ public interface UtilCtxt {
static final int ERR_REG_UNEXPECTED_USER = 10;
static final int ERR_REG_SERVER_SANS_REMOTE = 11;
static final int STR_NEED_BT_HOST_ADDR = 12;
static final int ERR_CANT_TRADE_MID_MOVE = 13;
static final int ERR_NO_EMPTY_TRADE = 14;
static final int ERR_CANT_UNDO_TILEASSIGN = 15;
static final int ERR_CANT_HINT_WHILE_DISABLED = 16;
static final int ERR_RELAY_BASE = 17;
static final int ERR_NO_EMPTY_TRADE = 13;
static final int ERR_CANT_UNDO_TILEASSIGN = 14;
static final int ERR_CANT_HINT_WHILE_DISABLED = 15;
static final int ERR_RELAY_BASE = 16;
void userError( int id );
void notifyGameOver();

View file

@ -83,15 +83,11 @@ public class UtilCtxtImpl implements UtilCtxt {
subclassOverride( "setIsServer" );
}
public void setInTrade( int turn, boolean entering )
{
}
public void bonusSquareHeld( int bonus )
{
}
public void playerScoreHeld( String text )
public void playerScoreHeld( int player )
{
}
@ -159,12 +155,6 @@ public class UtilCtxtImpl implements UtilCtxt {
case UtilCtxt.STR_COMMIT_CONFIRM:
id = R.string.str_commit_confirm;
break;
case UtilCtxt.STR_LOCAL_NAME:
id = R.string.str_local_name;
break;
case UtilCtxt.STR_NONLOCAL_NAME:
id = R.string.str_nonlocal_name;
break;
case UtilCtxt.STR_BONUS_ALL:
id = R.string.str_bonus_all;
break;

View file

@ -209,6 +209,7 @@ public class XwJNI {
public static native String model_writeGameHistory( int gamePtr,
boolean gameOver );
public static native int model_getNMoves( int gamePtr );
public static native String model_getPlayersLastScore( int gamePtr, int player );
// Server
public static native void server_reset( int gamePtr );

View file

@ -201,16 +201,6 @@ board_destroy( BoardCtxt* board )
XP_FREE( board->mpool, board );
} /* board_destroy */
static void
setTradeInProgress( BoardCtxt* board, XP_U16 turn, XP_Bool inProgress )
{
PerTurnInfo* pti = &board->pti[turn];
pti->tradeInProgress = inProgress;
#ifndef XWFEATURE_MINIWIN
util_setInTrade( board->util, turn, inProgress );
#endif
}
BoardCtxt*
board_makeFromStream( MPFORMAL XWStreamCtxt* stream, ModelCtxt* model,
ServerCtxt* server, DrawCtx* draw, XW_UtilCtxt* util,
@ -258,7 +248,7 @@ board_makeFromStream( MPFORMAL XWStreamCtxt* stream, ModelCtxt* model,
pti->dividerLoc = (XP_U8)stream_getBits( stream, NTILES_NBITS );
pti->traySelBits = (TileBit)stream_getBits( stream,
MAX_TRAY_TILES );
setTradeInProgress( board, ii, (XP_Bool)stream_getBits( stream, 1 ) );
pti->tradeInProgress = (XP_Bool)stream_getBits( stream, 1 );
if ( version >= STREAM_VERS_KEYNAV ) {
#ifdef KEYBOARD_NAV
@ -368,7 +358,7 @@ board_reset( BoardCtxt* board )
for ( ii = 0; ii < MAX_NUM_PLAYERS; ++ii ) {
PerTurnInfo* pti = &board->pti[ii];
pti->traySelBits = 0;
setTradeInProgress( board, ii, XP_FALSE );
pti->tradeInProgress = XP_FALSE;
pti->dividerLoc = 0;
XP_MEMSET( &pti->boardArrow, 0, sizeof(pti->boardArrow) );
}
@ -730,20 +720,21 @@ hideMiniWindow( BoardCtxt* board, XP_Bool destroy, MiniWindowType winType )
#endif
static XP_Bool
warnBadWords( XP_UCHAR* word, void* closure )
warnBadWords( const XP_UCHAR* word, XP_Bool isLegal, void* closure )
{
BadWordInfo bwi;
XP_Bool ok;
BoardCtxt* board = (BoardCtxt*)closure;
XP_S16 turn = server_getCurrentTurn( board->server );
XP_Bool ok = XP_TRUE;
if ( !isLegal ) {
BadWordInfo bwi;
BoardCtxt* board = (BoardCtxt*)closure;
XP_S16 turn = server_getCurrentTurn( board->server );
bwi.nWords = 1;
bwi.words[0] = word;
ok = !board->badWordRejected
&& util_warnIllegalWord( board->util, &bwi, turn, XP_FALSE );
board->badWordRejected = !ok || board->badWordRejected;
bwi.nWords = 1;
bwi.words[0] = word;
ok = !board->badWordRejected
&& util_warnIllegalWord( board->util, &bwi, turn, XP_FALSE );
board->badWordRejected = !ok || board->badWordRejected;
}
return ok;
} /* warnBadWords */
@ -767,17 +758,19 @@ board_commitTurn( BoardCtxt* board )
nothing */
} else if ( checkRevealTray( board ) ) {
if ( pti->tradeInProgress ) {
TileBit traySelBits = pti->traySelBits;
result = XP_TRUE; /* there's at least the window to clean up
after */
/* server_commitTrade() changes selPlayer, so board_endTrade
must be called first() */
(void)board_endTrade( board );
if ( NO_TILES == pti->traySelBits ) {
if ( NO_TILES == traySelBits ) {
util_userError( board->util, ERR_NO_EMPTY_TRADE );
} else if ( util_userQuery( board->util, QUERY_COMMIT_TRADE,
(XWStreamCtxt*)NULL ) ) {
result = server_commitTrade( board->server,
pti->traySelBits );
(void)server_commitTrade( board->server, traySelBits );
}
(void)board_endTrade( board );
} else {
XP_Bool warn, legal;
WordNotifierInfo info;
@ -866,7 +859,7 @@ selectPlayerImpl( BoardCtxt* board, XP_U16 newPlayer, XP_Bool reveal,
there were plenty of tiles but now there aren't. */
if ( newInfo->tradeInProgress &&
server_countTilesInPool(board->server) < MIN_TRADE_TILES ) {
setTradeInProgress( board, newPlayer, XP_FALSE );
newInfo->tradeInProgress = XP_FALSE;
newInfo->traySelBits = 0x00; /* clear any selected */
}
@ -953,7 +946,9 @@ timerFiredForPen( BoardCtxt* board )
{
XP_Bool draw = XP_FALSE;
const XP_UCHAR* text = (XP_UCHAR*)NULL;
#ifdef XWFEATURE_MINIWIN
XP_UCHAR buf[80];
#endif
if ( board->penDownObject == OBJ_BOARD ) {
if ( !dragDropInProgress( board ) || !dragDropHasMoved( board ) ) {
@ -982,7 +977,6 @@ timerFiredForPen( BoardCtxt* board )
board->penTimerFired = XP_TRUE;
}
} else if ( board->penDownObject == OBJ_SCORE ) {
LocalPlayer* lp;
XP_S16 scoreIndex = figureScoreRectTapped( board, board->penDownX,
board->penDownY );
/* I've seen this assert fire on simulator. No log is kept so I can't
@ -990,11 +984,11 @@ timerFiredForPen( BoardCtxt* board )
/* XP_ASSERT( player >= 0 ); */
if ( scoreIndex > CURSOR_LOC_REM ) {
XP_U16 player = scoreIndex - 1;
#ifdef XWFEATURE_MINIWIN
const XP_UCHAR* format;
XP_UCHAR scoreExpl[48];
XP_U16 explLen;
lp = &board->gi->players[player];
LocalPlayer* lp = &board->gi->players[player];
format = util_getUserString( board->util, lp->isLocal?
STR_LOCAL_NAME: STR_NONLOCAL_NAME );
XP_SNPRINTF( buf, sizeof(buf), format, emptyStringIfNull(lp->name) );
@ -1006,10 +1000,9 @@ timerFiredForPen( BoardCtxt* board )
XP_ASSERT( XP_STRLEN(buf) + explLen < sizeof(buf) );
XP_STRCAT( buf, scoreExpl );
}
#ifdef XWFEATURE_MINIWIN
text = buf;
#else
util_playerScoreHeld( board->util, buf );
util_playerScoreHeld( board->util, player );
#endif
}
@ -2085,20 +2078,17 @@ board_beginTrade( BoardCtxt* board )
result = preflight( board );
if ( result ) {
/* check turn before tradeInProgress so I can't tell my opponent's in a
trade */
if ( 0 != model_getCurrentMoveCount( board->model, board->selPlayer )){
util_userError( board->util, ERR_CANT_TRADE_MID_MOVE );
} else if ( server_countTilesInPool(board->server) < MIN_TRADE_TILES){
if ( server_countTilesInPool(board->server) < MIN_TRADE_TILES){
util_userError( board->util, ERR_TOO_FEW_TILES_LEFT_TO_TRADE );
} else {
model_resetCurrentTurn( board->model, board->selPlayer );
XP_ASSERT( 0 == model_getCurrentMoveCount( board->model,
board->selPlayer ) );
#ifdef XWFEATURE_MINIWIN
board->tradingMiniWindowInvalid = XP_TRUE;
#else
util_setInTrade( board->util, board->selPlayer, XP_TRUE );
#endif
board->needsDrawing = XP_TRUE;
setTradeInProgress( board, board->selPlayer, XP_TRUE );
board->selInfo->tradeInProgress = XP_TRUE;
setArrowVisible( board, XP_FALSE );
result = XP_TRUE;
}
@ -2113,7 +2103,7 @@ board_endTrade( BoardCtxt* board )
if ( result ) {
PerTurnInfo* pti = board->selInfo;
invalSelTradeWindow( board );
setTradeInProgress( board, board->selPlayer, XP_FALSE );
pti->tradeInProgress = XP_FALSE;
pti->traySelBits = NO_TILES;
}
return result;
@ -2495,7 +2485,7 @@ exitTradeMode( BoardCtxt* board )
{
PerTurnInfo* pti = board->selInfo;
invalSelTradeWindow( board );
setTradeInProgress( board, board->selPlayer, XP_FALSE );
pti->tradeInProgress = XP_FALSE;
board_invalTrayTiles( board, pti->traySelBits );
pti->traySelBits = 0x00;
return XP_TRUE;

View file

@ -1118,7 +1118,7 @@ considerScoreWordHasBlanks( EngineCtxt* engine, XP_U16 blanksLeft,
score = figureMoveScore( engine->model, engine->turn,
&posmove->moveInfo,
engine, (XWStreamCtxt*)NULL,
(WordNotifierInfo*)NULL, NULL, 0 );
(WordNotifierInfo*)NULL );
/* First, check that the score is even what we're interested in. If
it is, then go to the expense of filling in a PossibleMove to be

View file

@ -1933,6 +1933,23 @@ model_writeGameHistory( ModelCtxt* model, XWStreamCtxt* stream,
}
} /* model_writeGameHistory */
typedef struct _FirstWordData {
XP_UCHAR word[32];
} FirstWordData;
static XP_Bool
getFirstWord( const XP_UCHAR* word, XP_Bool isLegal, void* closure )
{
LOG_FUNC();
if ( isLegal ) {
FirstWordData* data = (FirstWordData*)closure;
if ( '\0' == data->word[0] && '\0' != word[0] ) {
XP_STRCAT( data->word, word );
}
}
return XP_TRUE;
}
static void
scoreLastMove( ModelCtxt* model, MoveInfo* moveInfo, XP_U16 howMany,
XP_UCHAR* buf, XP_U16* bufLen )
@ -1945,8 +1962,9 @@ scoreLastMove( ModelCtxt* model, MoveInfo* moveInfo, XP_U16 howMany,
XP_STRNCPY( buf, str, len + 1 );
} else {
XP_U16 score;
XP_UCHAR wordBuf[MAX_ROWS+1];
const XP_UCHAR* format;
WordNotifierInfo notifyInfo;
FirstWordData data;
ModelCtxt* tmpModel = makeTmpModel( model, NULL, NULL, NULL, NULL );
XP_U16 turn;
@ -1959,14 +1977,16 @@ scoreLastMove( ModelCtxt* model, MoveInfo* moveInfo, XP_U16 howMany,
XP_ASSERT( 0 );
}
data.word[0] = '\0';
notifyInfo.proc = getFirstWord;
notifyInfo.closure = &data;
score = figureMoveScore( tmpModel, turn, moveInfo, (EngineCtxt*)NULL,
(XWStreamCtxt*)NULL, (WordNotifierInfo*)NULL,
wordBuf, VSIZE(wordBuf) );
(XWStreamCtxt*)NULL, &notifyInfo );
model_destroy( tmpModel );
format = util_getUserString( model->vol.util, STRSD_SUMMARYSCORED );
*bufLen = XP_SNPRINTF( buf, *bufLen, format, wordBuf, score );
*bufLen = XP_SNPRINTF( buf, *bufLen, format, data.word, score );
}
} /* scoreLastMove */

View file

@ -238,7 +238,8 @@ void model_countAllTrayTiles( ModelCtxt* model, XP_U16* counts,
/********************* scoring ********************/
typedef XP_Bool (*WordNotifierProc)( XP_UCHAR* word, void* closure );
typedef XP_Bool (*WordNotifierProc)( const XP_UCHAR* word, XP_Bool isLegal,
void* closure );
typedef struct WordNotifierInfo {
WordNotifierProc proc;
void* closure;
@ -265,8 +266,7 @@ void model_figureFinalScores( ModelCtxt* model, ScoresArray* scores,
/* figureMoveScore is meant only for the engine's use */
XP_U16 figureMoveScore( const ModelCtxt* model, XP_U16 turn, MoveInfo* mvInfo,
EngineCtxt* engine, XWStreamCtxt* stream,
WordNotifierInfo* notifyInfo, XP_UCHAR* mainWord,
XP_U16 mainWordLen );
WordNotifierInfo* notifyInfo );
/********************* persistence ********************/
#ifdef INCLUDE_IO_SUPPORT

View file

@ -42,8 +42,7 @@ static XP_S16 checkScoreMove( ModelCtxt* model, XP_S16 turn,
XP_Bool silent, WordNotifierInfo* notifyInfo );
static XP_U16 scoreWord( const ModelCtxt* model, XP_U16 turn, MoveInfo* movei,
EngineCtxt* engine, XWStreamCtxt* stream,
WordNotifierInfo* notifyInfo, XP_UCHAR* mainWord,
XP_U16 mainWordLen );
WordNotifierInfo* notifyInfo );
/* for formatting when caller wants an explanation of the score. These live
in separate function called only when stream != NULL so that they'll have
@ -64,8 +63,7 @@ static void wordScoreFormatterAddTile( WordScoreFormatter* fmtr, Tile tile,
XP_U16 tileMultiplier,
XP_Bool isBlank );
static void wordScoreFormatterFinish( WordScoreFormatter* fmtr, Tile* word,
XWStreamCtxt* stream, XP_UCHAR* mainWord,
XP_U16 mainWordLen );
XWStreamCtxt* stream );
static void formatWordScore( XWStreamCtxt* stream, XP_U16 wordScore,
XP_U16 moveMultiplier );
static void formatSummary( XWStreamCtxt* stream, const ModelCtxt* model,
@ -104,7 +102,7 @@ adjustScoreForUndone( ModelCtxt* model, MoveInfo* mi, XP_U16 turn )
} else {
moveScore = figureMoveScore( model, turn, mi, (EngineCtxt*)NULL,
(XWStreamCtxt*)NULL,
(WordNotifierInfo*)NULL, NULL, 0 );
(WordNotifierInfo*)NULL );
}
player->score -= moveScore;
player->curMoveScore = 0;
@ -241,7 +239,7 @@ checkScoreMove( ModelCtxt* model, XP_S16 turn, EngineCtxt* engine,
if ( isLegalMove( model, &moveInfo, silent ) ) {
score = figureMoveScore( model, turn, &moveInfo, engine, stream,
notifyInfo, NULL, 0 );
notifyInfo );
}
} else if ( !silent ) { /* tiles out of line */
util_userError( model->vol.util, ERR_TILES_NOT_IN_LINE );
@ -450,8 +448,7 @@ isLegalMove( ModelCtxt* model, MoveInfo* mInfo, XP_Bool silent )
XP_U16
figureMoveScore( const ModelCtxt* model, XP_U16 turn, MoveInfo* moveInfo,
EngineCtxt* engine, XWStreamCtxt* stream,
WordNotifierInfo* notifyInfo, XP_UCHAR* mainWord,
XP_U16 mainWordLen )
WordNotifierInfo* notifyInfo )
{
XP_U16 col, row;
XP_U16* incr;
@ -480,7 +477,7 @@ figureMoveScore( const ModelCtxt* model, XP_U16 turn, MoveInfo* moveInfo,
}
oneScore = scoreWord( model, turn, moveInfo, (EngineCtxt*)NULL, stream,
notifyInfo, mainWord, mainWordLen );
notifyInfo );
if ( !!stream ) {
formatWordScore( stream, oneScore, moveMultiplier );
}
@ -494,19 +491,10 @@ figureMoveScore( const ModelCtxt* model, XP_U16 turn, MoveInfo* moveInfo,
for ( i = 0, tiles = moveInfo->tiles; i < nTiles; ++i, ++tiles ) {
/* Moves using only one tile will sometimes score only in the
crosscheck direction. Score may still be 0 after the call to
scoreWord above. Keep trying to get some text in mainWord until
something's been scored. */
if ( score > 0 ) {
mainWord = NULL;
}
tmpMI.commonCoord = tiles->varCoord;
tmpMI.tiles[0].tile = tiles->tile;
oneScore = scoreWord( model, turn, &tmpMI, engine, stream,
notifyInfo, mainWord, mainWordLen );
oneScore = scoreWord( model, turn, &tmpMI, engine, stream, notifyInfo );
if ( !!stream ) {
formatWordScore( stream, oneScore, multipliers[i] );
}
@ -566,8 +554,7 @@ scoreWord( const ModelCtxt* model, XP_U16 turn,
MoveInfo* movei, /* new tiles */
EngineCtxt* engine,/* for crosswise caching */
XWStreamCtxt* stream,
WordNotifierInfo* notifyInfo,
XP_UCHAR* mainWord, XP_U16 mainWordLen )
WordNotifierInfo* notifyInfo )
{
XP_U16 tileMultiplier;
XP_U16 restScore = 0;
@ -599,7 +586,7 @@ scoreWord( const ModelCtxt* model, XP_U16 turn,
if ( (end - start) >= 1 ) { /* one-letter word: score 0 */
WordScoreFormatter fmtr;
if ( !!stream || !!mainWord ) {
if ( !!stream ) {
wordScoreFormatterInit( &fmtr, dict );
}
@ -658,7 +645,7 @@ scoreWord( const ModelCtxt* model, XP_U16 turn,
*curTile++ = tile; /* save in case we're checking phonies */
if ( !!stream || !!mainWord ) {
if ( !!stream ) {
wordScoreFormatterAddTile( &fmtr, tile, tileMultiplier,
isBlank );
}
@ -679,17 +666,14 @@ scoreWord( const ModelCtxt* model, XP_U16 turn,
XP_U16 len = curTile - checkWordBuf;
XP_Bool legal = engine_check( dict, checkWordBuf, len );
if ( !legal ) {
XP_UCHAR buf[(MAX_ROWS*2)+1];
dict_tilesToString( dict, checkWordBuf, len, buf,
sizeof(buf) );
(*notifyInfo->proc)( buf, notifyInfo->closure );
}
XP_UCHAR buf[(MAX_ROWS*2)+1];
dict_tilesToString( dict, checkWordBuf, len, buf,
sizeof(buf) );
(void)(*notifyInfo->proc)( buf, legal, notifyInfo->closure );
}
if ( !!stream || !!mainWord ) {
wordScoreFormatterFinish( &fmtr, checkWordBuf, stream,
mainWord, mainWordLen );
if ( !!stream ) {
wordScoreFormatterFinish( &fmtr, checkWordBuf, stream );
}
#ifdef DEBUG
@ -804,8 +788,7 @@ wordScoreFormatterAddTile( WordScoreFormatter* fmtr, Tile tile,
static void
wordScoreFormatterFinish( WordScoreFormatter* fmtr, Tile* word,
XWStreamCtxt* stream, XP_UCHAR* mainWord,
XP_U16 mainWordLen )
XWStreamCtxt* stream )
{
XP_UCHAR buf[(MAX_ROWS*2)+1];
XP_U16 len = dict_tilesToString( fmtr->dict, word, fmtr->nTiles,
@ -817,11 +800,6 @@ wordScoreFormatterFinish( WordScoreFormatter* fmtr, Tile* word,
stream_putBytes( stream, fmtr->fullBuf, fmtr->bufLen );
stream_putU8( stream, ']' );
}
if ( !!mainWord ) {
XP_STRNCPY( mainWord, fmtr->wordBuf, mainWordLen );
}
} /* wordScoreFormatterFinish */
static void

View file

@ -1719,15 +1719,16 @@ server_setGameOverListener( ServerCtxt* server, GameOverListener gol,
} /* server_setGameOverListener */
static XP_Bool
storeBadWords( XP_UCHAR* word, void* closure )
storeBadWords( const XP_UCHAR* word, XP_Bool isLegal, void* closure )
{
ServerCtxt* server = (ServerCtxt*)closure;
if ( !isLegal ) {
ServerCtxt* server = (ServerCtxt*)closure;
XP_STATUSF( "storeBadWords called with \"%s\"", word );
server->illegalWordInfo.words[server->illegalWordInfo.nWords++]
= copyString( server->mpool, word );
XP_STATUSF( "storeBadWords called with \"%s\"", word );
server->illegalWordInfo.words[server->illegalWordInfo.nWords++]
= copyString( server->mpool, word );
}
return XP_TRUE;
} /* storeBadWords */

View file

@ -52,7 +52,6 @@ typedef enum {
ERR_REG_SERVER_SANS_REMOTE,
STR_NEED_BT_HOST_ADDR,
#endif
ERR_CANT_TRADE_MID_MOVE,
ERR_NO_EMPTY_TRADE,
/* ERR_CANT_ENGINE_MID_MOVE, */
/* ERR_NOT_YOUR_TURN_TO_TRADE, */
@ -159,9 +158,8 @@ typedef struct UtilVtable {
void (*m_util_remSelected)(XW_UtilCtxt* uc);
#ifndef XWFEATURE_MINIWIN
void (*m_util_setInTrade)( XW_UtilCtxt* uc, XP_U16 turn, XP_Bool entering );
void (*m_util_bonusSquareHeld)( XW_UtilCtxt* uc, XWBonusType bonus );
void (*m_util_playerScoreHeld)( XW_UtilCtxt* uc, const XP_UCHAR* txt );
void (*m_util_playerScoreHeld)( XW_UtilCtxt* uc, XP_U16 player );
#endif
#ifndef XWFEATURE_STANDALONE_ONLY
@ -265,12 +263,10 @@ struct XW_UtilCtxt {
(uc)->vtable->m_util_remSelected((uc))
#ifndef XWFEATURE_MINIWIN
# define util_setInTrade( uc, t, e ) \
(uc)->vtable->m_util_setInTrade( (uc), (t), (e) )
# define util_bonusSquareHeld( uc, b ) \
(uc)->vtable->m_util_bonusSquareHeld( (uc), (b) )
# define util_playerScoreHeld( uc, txt ) \
(uc)->vtable->m_util_playerScoreHeld( (uc), (txt) )
# define util_playerScoreHeld( uc, player ) \
(uc)->vtable->m_util_playerScoreHeld( (uc), (player) )
#endif
#ifndef XWFEATURE_STANDALONE_ONLY

View file

@ -897,6 +897,15 @@ handle_trayEditToggle_off( GtkWidget* widget, GtkAppGlobals* globals )
}
#endif
static void
handle_trade_cancel( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals )
{
BoardCtxt* board = globals->cGlobals.game.board;
if ( board_endTrade( board ) ) {
board_draw( board );
}
}
#ifndef XWFEATURE_STANDALONE_ONLY
static void
handle_resend( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals )
@ -992,6 +1001,9 @@ makeMenus( GtkAppGlobals* globals, int XP_UNUSED(argc),
(void)createAddItem( fileMenu, "Load dictionary",
GTK_SIGNAL_FUNC(load_dictionary), globals );
(void)createAddItem( fileMenu, "Cancel trade",
GTK_SIGNAL_FUNC(handle_trade_cancel), globals );
fileMenu = makeAddSubmenu( menubar, "Edit" );
(void)createAddItem( fileMenu, "Undo",
@ -1005,7 +1017,6 @@ makeMenus( GtkAppGlobals* globals, int XP_UNUSED(argc),
(void)createAddItem( fileMenu, "Dis-allow tray edit",
GTK_SIGNAL_FUNC(handle_trayEditToggle_off), globals );
#endif
fileMenu = makeAddSubmenu( menubar, "Network" );
#ifndef XWFEATURE_STANDALONE_ONLY
@ -1683,15 +1694,6 @@ gtk_util_getTraySearchLimits( XW_UtilCtxt* XP_UNUSED(uc),
#endif
#ifndef XWFEATURE_MINIWIN
static void
gtk_util_setInTrade( XW_UtilCtxt* uc, XP_U16 turn, XP_Bool entering )
{
XP_LOGF( "%s(turn=%d; entering=%d)", __func__, turn, entering );
XP_USE( uc );
XP_USE( turn );
XP_USE( entering );
}
static void
gtk_util_bonusSquareHeld( XW_UtilCtxt* uc, XWBonusType bonus )
{
@ -1701,11 +1703,19 @@ gtk_util_bonusSquareHeld( XW_UtilCtxt* uc, XWBonusType bonus )
}
static void
gtk_util_playerScoreHeld( XW_UtilCtxt* uc, const XP_UCHAR* txt )
gtk_util_playerScoreHeld( XW_UtilCtxt* uc, XP_U16 player )
{
LOG_FUNC();
XP_USE( uc );
XP_USE( txt );
GtkAppGlobals* globals = (GtkAppGlobals*)uc->closure;
XP_UCHAR scoreExpl[48];
XP_U16 explLen = sizeof(scoreExpl);
if ( model_getPlayersLastScore( globals->cGlobals.game.model,
player, scoreExpl, &explLen ) ) {
XP_LOGF( "got: %s", scoreExpl );
}
}
#endif
@ -1928,7 +1938,6 @@ setupGtkUtilCallbacks( GtkAppGlobals* globals, XW_UtilCtxt* util )
#endif
#ifndef XWFEATURE_MINIWIN
util->vtable->m_util_setInTrade = gtk_util_setInTrade;
util->vtable->m_util_bonusSquareHeld = gtk_util_bonusSquareHeld;
util->vtable->m_util_playerScoreHeld = gtk_util_playerScoreHeld;
#endif

View file

@ -332,10 +332,6 @@ linux_getErrString( UtilErrID id, XP_Bool* silent )
break;
#endif
case ERR_CANT_TRADE_MID_MOVE:
message = "Remove played tiles before trading.";
break;
case ERR_NO_EMPTY_TRADE:
message = "No tiles selected; trade cancelled.";
break;