mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-15 15:41:24 +01:00
Merge branch 'android_branch' into send_in_background
This commit is contained in:
commit
84931f34ff
29 changed files with 289 additions and 295 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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-->
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) );
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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" );
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, ¬ifyInfo );
|
||||
|
||||
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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue