diff --git a/xwords4/android/XWords4/jni/Android.mk b/xwords4/android/XWords4/jni/Android.mk index 057f89440..97b046bb8 100644 --- a/xwords4/android/XWords4/jni/Android.mk +++ b/xwords4/android/XWords4/jni/Android.mk @@ -16,7 +16,6 @@ local_DEFINES += \ -DXWFEATURE_RELAY \ -DXWFEATURE_TURNCHANGENOTIFY \ -DXWFEATURE_CHAT \ - -DSHOW_PROGRESS \ -DKEY_SUPPORT \ -DXWFEATURE_CROSSHAIRS \ -DPOINTER_SUPPORT \ diff --git a/xwords4/android/XWords4/res/raw/changes b/xwords4/android/XWords4/res/raw/changes index 9f58881d2..1861e77a5 100644 --- a/xwords4/android/XWords4/res/raw/changes +++ b/xwords4/android/XWords4/res/raw/changes @@ -10,14 +10,20 @@ diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java index 79e7942c7..8bb49f9fa 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java @@ -72,6 +72,10 @@ public class BoardActivity extends XWActivity private static final int CHAT_REQUEST = 1; private static final int SCREEN_ON_TIME = 10 * 60 * 1000; // 10 mins + private static final String DLG_TITLE = "DLG_TITLE"; + private static final String DLG_TITLESTR = "DLG_TITLESTR"; + private static final String DLG_BYTES = "DLG_BYTES"; + private BoardView m_view; private int m_jniGamePtr; private GameUtils.GameLock m_gameLock; @@ -104,8 +108,6 @@ public class BoardActivity extends XWActivity private JNIThread.GameStateInfo m_gsi; private boolean m_blockingDlgPosted = false; - private ProgressDialog m_progress; - private boolean m_isVisible; private String m_room; private int m_missing; private boolean m_haveInvited = false; @@ -141,7 +143,6 @@ public class BoardActivity extends XWActivity case DLG_BADWORDS: case DLG_RETRY: ab = new AlertDialog.Builder( BoardActivity.this ) - //.setIcon( R.drawable.alert_dialog_icon ) .setTitle( m_dlgTitle ) .setMessage( m_dlgBytes ) .setPositiveButton( R.string.button_ok, null ); @@ -316,6 +317,7 @@ public class BoardActivity extends XWActivity protected void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState ); + getBundledData( savedInstanceState ); if ( CommonPrefs.getHideTitleBar( this ) ) { requestWindowFeature( Window.FEATURE_NO_TITLE ); @@ -352,10 +354,31 @@ public class BoardActivity extends XWActivity { super.onResume(); m_handler = new Handler(); + m_blockingDlgPosted = false; + setKeepScreenOn(); + loadGame(); } + @Override + protected void onSaveInstanceState( Bundle outState ) + { + super.onSaveInstanceState( outState ); + outState.putInt( DLG_TITLESTR, m_dlgTitle ); + outState.putString( DLG_TITLESTR, m_dlgTitleStr ); + outState.putString( DLG_BYTES, m_dlgBytes ); + } + + private void getBundledData( Bundle bundle ) + { + if ( null != bundle ) { + m_dlgTitleStr = bundle.getString( DLG_TITLESTR ); + m_dlgTitle = bundle.getInt( DLG_TITLE ); + m_dlgBytes = bundle.getString( DLG_BYTES ); + } + } + @Override protected void onActivityResult( int requestCode, int resultCode, Intent data ) { @@ -541,7 +564,7 @@ public class BoardActivity extends XWActivity break; default: - Utils.logf( "menuitem " + item.getItemId() + " not handled" ); + Utils.logf( "menuitem %d not handled", id ); handled = false; } @@ -780,7 +803,7 @@ public class BoardActivity extends XWActivity public void setIsServer( boolean isServer ) { - Utils.logf( "setIsServer(%s)", isServer?"true":"false" ); + Utils.logf( "setIsServer(%b)", isServer ); DeviceRole newRole = isServer? DeviceRole.SERVER_ISSERVER : DeviceRole.SERVER_ISCLIENT; if ( newRole != m_gi.serverRole ) { @@ -868,37 +891,6 @@ public class BoardActivity extends XWActivity return ! m_jniThread.busy(); } - public void engineStarting( int nBlanks ) - { - if ( nBlanks > 0 ) { - post( new Runnable() { - // Need to keep this from running after activity dies!! - public void run() { - if ( m_isVisible ) { - String title = - getString( R.string.progress_title ); - m_progress = - ProgressDialog.show( BoardActivity.this, - title, null, true, - true ); - } - } - } ); - } - } - - public void engineStopping() - { - post( new Runnable() { - public void run() { - if ( null != m_progress ) { - m_progress.cancel(); - m_progress = null; - } - } - } ); - } - public boolean userQuery( int id, String query ) { boolean result; @@ -1002,7 +994,8 @@ public class BoardActivity extends XWActivity // m_view.setVerticalScrollBarEnabled( maxOffset > 0 ); // } - public boolean warnIllegalWord( String[] words, int turn, boolean turnLost ) + public boolean warnIllegalWord( String[] words, int turn, + boolean turnLost ) { Utils.logf( "warnIllegalWord" ); boolean accept = turnLost; @@ -1028,7 +1021,7 @@ public class BoardActivity extends XWActivity accept = 0 != waitBlockingDialog( QUERY_REQUEST_BLK, 0 ); } - Utils.logf( "warnIllegalWord=>" + accept ); + Utils.logf( "warnIllegalWord=>%b", accept ); return accept; } @@ -1050,9 +1043,6 @@ public class BoardActivity extends XWActivity private void loadGame() { - Assert.assertFalse( m_blockingDlgPosted ); // found the problem! - m_blockingDlgPosted = false; - if ( 0 == m_jniGamePtr ) { Assert.assertNull( m_gameLock ); m_gameLock = new GameUtils.GameLock( m_name, true ).lock(); @@ -1235,25 +1225,27 @@ public class BoardActivity extends XWActivity Utils.logf( "waitBlockingDialog: dropping dlgID %d", dlgID ); } else { setBlockingThread(); + m_resultCode = cancelResult; - post( new Runnable() { + if ( post( new Runnable() { public void run() { - showDialog( dlgID ); // crash + showDialog( dlgID ); m_blockingDlgPosted = true; } - } ); + } ) ) { - try { - m_forResultWait.acquire(); - m_blockingDlgPosted = false; - } catch ( java.lang.InterruptedException ie ) { - Utils.logf( "waitBlockingDialog: got " + ie.toString() ); - m_resultCode = cancelResult; - if ( m_blockingDlgPosted ) { - dismissDialog( dlgID ); + try { + m_forResultWait.acquire(); m_blockingDlgPosted = false; + } catch ( java.lang.InterruptedException ie ) { + Utils.logf( "waitBlockingDialog: got %s", ie.toString() ); + if ( m_blockingDlgPosted ) { + dismissDialog( dlgID ); + m_blockingDlgPosted = false; + } } } + clearBlockingThread(); result = m_resultCode; } @@ -1308,11 +1300,7 @@ public class BoardActivity extends XWActivity interruptBlockingThread(); if ( null != m_jniThread ) { - if ( save ) { - Utils.logf( "posting CMD_SAVE" ); - m_jniThread.handle( JNIThread.JNICmd.CMD_SAVE ); - } - m_jniThread.waitToStop(); + m_jniThread.waitToStop( save ); m_jniThread = null; } @@ -1373,13 +1361,15 @@ public class BoardActivity extends XWActivity } } - private void post( Runnable runnable ) + private boolean post( Runnable runnable ) { - if ( null != m_handler ) { + boolean canPost = null != m_handler; + if ( canPost ) { m_handler.post( runnable ); } else { Utils.logf( "post: dropping because handler null" ); } + return canPost; } private void postDelayed( Runnable runnable, int when ) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardView.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardView.java index 6db8e6156..db9f4b930 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardView.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardView.java @@ -187,7 +187,7 @@ public class BoardView extends View implements DrawCtx, BoardHandler, m_jniThread.handle( JNIThread.JNICmd.CMD_PEN_UP, xx, yy ); break; default: - Utils.logf( "unknown action: " + action ); + Utils.logf( "unknown action: %d", action ); Utils.logf( event.toString() ); } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/CommsTransport.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/CommsTransport.java index 17a628c61..368cde608 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/CommsTransport.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/CommsTransport.java @@ -143,11 +143,11 @@ public class CommsTransport implements TransportProcs, // we get this when relay goes down. Need to notify! failed = true; closeSocket(); - Utils.logf( "exiting: " + cce.toString() ); + Utils.logf( "exiting: %s", cce.toString() ); break; // don't try again } catch ( java.io.IOException ioe ) { closeSocket(); - Utils.logf( "exiting: " + ioe.toString() ); + Utils.logf( "exiting: %s", ioe.toString() ); Utils.logf( ioe.toString() ); } catch ( java.nio.channels.NoConnectionPendingException ncp ) { Utils.logf( "%s", ncp.toString() ); @@ -318,7 +318,7 @@ public class CommsTransport implements TransportProcs, try { m_thread.join(100); // wait up to 1/10 second } catch ( java.lang.InterruptedException ie ) { - Utils.logf( "got InterruptedException: " + ie.toString() ); + Utils.logf( "got InterruptedException: %s", ie.toString() ); } m_thread = null; } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java index 3be7c42f7..7bca9a168 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java @@ -38,6 +38,8 @@ import org.eehouse.android.xw4.jni.*; public class DBUtils { + private static final String ROW_ID = "rowid"; + public static interface DBChangeListener { public void pathSaved( String path ); } @@ -87,7 +89,8 @@ public class DBUtils { synchronized( s_dbHelper ) { SQLiteDatabase db = s_dbHelper.getReadableDatabase(); - String[] columns = { DBHelper.NUM_MOVES, DBHelper.NUM_PLAYERS, + String[] columns = { ROW_ID, + DBHelper.NUM_MOVES, DBHelper.NUM_PLAYERS, DBHelper.MISSINGPLYRS, DBHelper.GAME_OVER, DBHelper.PLAYERS, DBHelper.TURN, DBHelper.GIFLAGS, @@ -103,6 +106,9 @@ public class DBUtils { Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns, selection, null, null, null, null ); if ( 1 == cursor.getCount() && cursor.moveToFirst() ) { + Utils.logf( "got rowid: %d", + cursor.getLong( cursor.getColumnIndex(ROW_ID) ) ); + summary = new GameSummary(); summary.nMoves = cursor.getInt(cursor. getColumnIndex(DBHelper.NUM_MOVES)); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictImportActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictImportActivity.java index 5c281f8bb..34155b7ec 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictImportActivity.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictImportActivity.java @@ -65,11 +65,11 @@ public class DictImportActivity extends XWActivity { m_saved = saveDict( is, uri.getPath() ); is.close(); } catch ( java.net.URISyntaxException use ) { - Utils.logf( "URISyntaxException: %s" + use.toString() ); + Utils.logf( "URISyntaxException: %s", use.toString() ); } catch ( java.net.MalformedURLException mue ) { - Utils.logf( "MalformedURLException: %s" + mue.toString() ); + Utils.logf( "MalformedURLException: %s", mue.toString() ); } catch ( java.io.IOException ioe ) { - Utils.logf( "IOException: %s" + ioe.toString() ); + Utils.logf( "IOException: %s", ioe.toString() ); } } return totalSize; diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictsActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictsActivity.java index a3527e02b..594e3bd91 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictsActivity.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictsActivity.java @@ -397,7 +397,7 @@ public class DictsActivity extends ExpandableListActivity try { info = (ExpandableListContextMenuInfo)item.getMenuInfo(); } catch (ClassCastException e) { - Utils.logf( "bad menuInfo:" + e.toString() ); + Utils.logf( "bad menuInfo: %s", e.toString() ); return false; } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfig.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfig.java index 38934e3cd..0082e5b6b 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfig.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfig.java @@ -919,8 +919,8 @@ public class GameConfig extends XWActivity if ( !m_notNetworkedGame ) { m_car.ip_relay_seeksPublicRoom = m_joinPublicCheck.isChecked(); - Utils.logf( "ip_relay_seeksPublicRoom: %s", - m_car.ip_relay_seeksPublicRoom?"true":"false" ); + Utils.logf( "ip_relay_seeksPublicRoom: %b", + m_car.ip_relay_seeksPublicRoom ); m_car.ip_relay_advertiseRoom = Utils.getChecked( this, R.id.advertise_new_room_check ); if ( m_car.ip_relay_seeksPublicRoom ) { diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java index 16ae51237..5be253ca6 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java @@ -634,8 +634,8 @@ public class GameUtils { bytes = new byte[len]; int nRead = dict.read( bytes, 0, len ); if ( nRead != len ) { - Utils.logf( "**** warning ****; read only " + nRead + " of " - + len + " bytes." ); + Utils.logf( "**** warning ****; read only %d of %d bytes.", + nRead, len ); } // check that with len bytes we've read the whole file Assert.assertTrue( -1 == dict.read() ); @@ -831,7 +831,7 @@ public class GameUtils { lock.unlock(); } } - Utils.logf( "feedMessages=>%s", draw?"true":"false" ); + Utils.logf( "feedMessages=>%b", draw ); return draw; } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java index 5032ee794..f524cd32e 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java @@ -361,7 +361,7 @@ public class GamesList extends XWListActivity try { info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); } catch (ClassCastException e) { - Utils.logf( "bad menuInfo:" + e.toString() ); + Utils.logf( "bad menuInfo: %s", e.toString() ); return false; } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/ReceiveNBS.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/ReceiveNBS.java index c2e879be0..924d2aac9 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/ReceiveNBS.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/ReceiveNBS.java @@ -31,7 +31,7 @@ public class ReceiveNBS extends BroadcastReceiver { @Override public void onReceive( Context context, Intent intent ) { - Utils.logf( "onReceive called: " + intent.toString() ); + Utils.logf( "onReceive called: %s", intent.toString() ); Bundle bundle = intent.getExtras(); SmsMessage[] smsarr = null; @@ -40,7 +40,7 @@ public class ReceiveNBS extends BroadcastReceiver { smsarr = new SmsMessage[pdus.length]; for ( int ii = 0; ii < pdus.length; ii++){ smsarr[ii] = SmsMessage.createFromPdu((byte[])pdus[ii]); - Utils.logf( "from " + smsarr[ii].getOriginatingAddress() ); + Utils.logf( "from %s", smsarr[ii].getOriginatingAddress() ); // buf.append( smsarr[ii].getMessageBody() ); // XwJni.handle( XwJni.JNICmd.CMD_RECEIVE, // smsarr[ii].getMessageBody() ); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/StatusReceiver.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/StatusReceiver.java index 556f1b96d..1c6b1de85 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/StatusReceiver.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/StatusReceiver.java @@ -29,7 +29,7 @@ public class StatusReceiver extends BroadcastReceiver { @Override public void onReceive( Context context, Intent intent ) { - Utils.logf( "StatusReceiver::onReceive called: " + intent.toString() ); + Utils.logf( "StatusReceiver.onReceive called: %s", intent.toString() ); } } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java index a5ca73983..cd733cfef 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java @@ -108,6 +108,7 @@ public class JNIThread extends Thread { private GameStateInfo m_gsi = new GameStateInfo(); private boolean m_stopped = false; + private boolean m_saveOnStop = false; private int m_jniGamePtr; private GameUtils.GameLock m_lock; private Context m_context; @@ -143,8 +144,12 @@ public class JNIThread extends Thread { m_queue = new LinkedBlockingQueue(); } - public void waitToStop() { - m_stopped = true; + public void waitToStop( boolean save ) + { + synchronized ( this ) { + m_stopped = true; + m_saveOnStop = save; + } handle( JNICmd.CMD_NONE ); // tickle it try { // Can't pass timeout to join. There's no way to kill @@ -154,7 +159,7 @@ public class JNIThread extends Thread { join(); // Assert.assertFalse( isAlive() ); } catch ( java.lang.InterruptedException ie ) { - Utils.logf( "got InterruptedException: " + ie.toString() ); + Utils.logf( "JNIThread.waitToStop() got %s", ie.toString() ); } } @@ -251,10 +256,31 @@ public class JNIThread extends Thread { Message.obtain( m_handler, TOOLBAR_STATES ).sendToTarget(); } + private void save_jni() + { + // If server has any work to do, e.g. clean up after showing a + // remote- or robot-moved dialog, let it do so before saving + // state. In some cases it'll otherwise drop the move. + XwJNI.server_do( m_jniGamePtr ); + + XwJNI.game_getGi( m_jniGamePtr, m_gi ); + GameSummary summary = new GameSummary( m_gi ); + XwJNI.game_summarize( m_jniGamePtr, summary ); + byte[] state = XwJNI.game_saveToStream( m_jniGamePtr, null ); + GameUtils.saveGame( m_context, state, m_lock, false ); + DBUtils.saveSummary( m_context, m_lock, summary ); + } + public void run() { boolean[] barr = new boolean[2]; // scratch boolean - while ( !m_stopped ) { + for ( ; ; ) { + synchronized ( this ) { + if ( m_stopped ) { + break; + } + } + QueueElem elem; Object[] args; try { @@ -271,18 +297,7 @@ public class JNIThread extends Thread { if ( nextSame( JNICmd.CMD_SAVE ) ) { continue; } - // If server has any work to do, e.g. clean up after - // showing a remote- or robot-moved dialog, let it do - // so before saving state. In some cases it'll - // otherwise drop the move. - XwJNI.server_do( m_jniGamePtr ); - - XwJNI.game_getGi( m_jniGamePtr, m_gi ); - GameSummary summary = new GameSummary( m_gi ); - XwJNI.game_summarize( m_jniGamePtr, summary ); - byte[] state = XwJNI.game_saveToStream( m_jniGamePtr, null ); - GameUtils.saveGame( m_context, state, m_lock, false ); - DBUtils.saveSummary( m_context, m_lock, summary ); + save_jni(); break; case CMD_DRAW: @@ -531,13 +546,17 @@ public class JNIThread extends Thread { checkButtons(); } + } // for + + if ( m_saveOnStop ) { + save_jni(); } } // run public void handle( JNICmd cmd, boolean isUI, Object... args ) { QueueElem elem = new QueueElem( cmd, isUI, args ); - // Utils.logf( "adding: " + cmd.toString() ); + // Utils.logf( "adding: %s", cmd.toString() ); m_queue.add( elem ); } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/UtilCtxt.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/UtilCtxt.java index 15c18c900..21861b886 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/UtilCtxt.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/UtilCtxt.java @@ -34,8 +34,6 @@ public interface UtilCtxt { void turnChanged(); boolean engineProgressCallback(); - void engineStarting( int nBlanks ); - void engineStopping(); // Values for why; should be enums public static final int TIMER_PENDOWN = 1; diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/UtilCtxtImpl.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/UtilCtxtImpl.java index 2662b86ea..7521bef1a 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/UtilCtxtImpl.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/UtilCtxtImpl.java @@ -63,16 +63,6 @@ public class UtilCtxtImpl implements UtilCtxt { return true; } - public void engineStarting( int nBlanks ) - { - subclassOverride( "engineStarting" ); - } - - public void engineStopping() - { - subclassOverride( "engineStopping" ); - } - public void setTimer( int why, int when, int handle ) { subclassOverride( "setTimer" ); @@ -170,7 +160,7 @@ public class UtilCtxtImpl implements UtilCtxt { id = R.string.strd_turn_score; break; default: - Utils.logf( "no such stringCode: " + stringCode ); + Utils.logf( "no such stringCode: %d", stringCode ); } String result; diff --git a/xwords4/common/comms.c b/xwords4/common/comms.c index 00acaab08..9d2f2aabf 100644 --- a/xwords4/common/comms.c +++ b/xwords4/common/comms.c @@ -278,7 +278,11 @@ CommsCtxt* comms_make( MPFORMAL XW_UtilCtxt* util, XP_Bool isServer, XP_U16 XP_UNUSED_RELAY(nPlayersHere), XP_U16 XP_UNUSED_RELAY(nPlayersTotal), - const TransportProcs* procs ) + const TransportProcs* procs +#ifdef SET_GAMESEED + , XP_U16 gameSeed +#endif + ) { CommsCtxt* result = (CommsCtxt*)XP_MALLOC( mpool, sizeof(*result) ); XP_MEMSET( result, 0, sizeof(*result) ); @@ -293,6 +297,9 @@ comms_make( MPFORMAL XW_UtilCtxt* util, XP_Bool isServer, #ifdef XWFEATURE_RELAY init_relay( result, nPlayersHere, nPlayersTotal ); +# ifdef SET_GAMESEED + result->channelSeed = gameSeed; +# endif #endif return result; } /* comms_make */ @@ -527,7 +534,11 @@ comms_makeFromStream( MPFORMAL XWStreamCtxt* stream, XW_UtilCtxt* util, nPlayersTotal = 0; } comms = comms_make( MPPARM(mpool) util, isServer, - nPlayersHere, nPlayersTotal, procs ); + nPlayersHere, nPlayersTotal, procs +#ifdef SET_GAMESEED + , 0 +#endif + ); XP_MEMCPY( &comms->addr, &addr, sizeof(comms->addr) ); comms->connID = stream_getU32( stream ); diff --git a/xwords4/common/comms.h b/xwords4/common/comms.h index 34370956a..1abf90ae9 100644 --- a/xwords4/common/comms.h +++ b/xwords4/common/comms.h @@ -142,7 +142,11 @@ typedef struct _TransportProcs { CommsCtxt* comms_make( MPFORMAL XW_UtilCtxt* util, XP_Bool isServer, XP_U16 nPlayersHere, XP_U16 nPlayersTotal, - const TransportProcs* procs ); + const TransportProcs* procs +#ifdef SET_GAMESEED + ,XP_U16 gameSeed +#endif + ); void comms_reset( CommsCtxt* comms, XP_Bool isServer, XP_U16 nPlayersHere, XP_U16 nPlayersTotal ); @@ -174,7 +178,8 @@ CommsConnType comms_getConType( const CommsCtxt* comms ); XP_Bool comms_getIsServer( const CommsCtxt* comms ); CommsCtxt* comms_makeFromStream( MPFORMAL XWStreamCtxt* stream, - XW_UtilCtxt* util, const TransportProcs* procs ); + XW_UtilCtxt* util, + const TransportProcs* procs ); void comms_start( CommsCtxt* comms ); void comms_writeToStream( const CommsCtxt* comms, XWStreamCtxt* stream ); diff --git a/xwords4/common/game.c b/xwords4/common/game.c index 15cb1191a..12137b899 100644 --- a/xwords4/common/game.c +++ b/xwords4/common/game.c @@ -72,7 +72,11 @@ checkServerRole( CurGameInfo* gi, XP_U16* nPlayersHere, XP_U16* nPlayersTotal ) void game_makeNewGame( MPFORMAL XWGame* game, CurGameInfo* gi, XW_UtilCtxt* util, DrawCtx* draw, - CommonPrefs* cp, const TransportProcs* procs ) + CommonPrefs* cp, const TransportProcs* procs +#ifdef SET_GAMESEED + ,XP_U16 gameSeed +#endif + ) { XP_U16 gameID = 0; XP_U16 nPlayersHere, nPlayersTotal; @@ -92,7 +96,12 @@ game_makeNewGame( MPFORMAL XWGame* game, CurGameInfo* gi, if ( gi->serverRole != SERVER_STANDALONE ) { game->comms = comms_make( MPPARM(mpool) util, gi->serverRole != SERVER_ISCLIENT, - nPlayersHere, nPlayersTotal, procs ); + nPlayersHere, nPlayersTotal, + procs +#ifdef SET_GAMESEED + , gameSeed +#endif + ); } else { game->comms = (CommsCtxt*)NULL; } @@ -141,7 +150,11 @@ game_reset( MPFORMAL XWGame* game, CurGameInfo* gi, } else if ( gi->serverRole != SERVER_STANDALONE ) { game->comms = comms_make( MPPARM(mpool) util, gi->serverRole != SERVER_ISCLIENT, - nPlayersHere, nPlayersTotal, procs ); + nPlayersHere, nPlayersTotal, procs +#ifdef SET_GAMESEED + , 0 +#endif + ); } #else # ifdef DEBUG diff --git a/xwords4/common/game.h b/xwords4/common/game.h index 17d02311a..d8fcbff15 100644 --- a/xwords4/common/game.h +++ b/xwords4/common/game.h @@ -108,7 +108,11 @@ typedef struct XWGame { void game_makeNewGame( MPFORMAL XWGame* game, CurGameInfo* gi, XW_UtilCtxt* util, DrawCtx* draw, - CommonPrefs* cp, const TransportProcs* procs ); + CommonPrefs* cp, const TransportProcs* procs +#ifdef SET_GAMESEED + ,XP_U16 gameSeed +#endif + ); void game_reset( MPFORMAL XWGame* game, CurGameInfo* gi, XW_UtilCtxt* util, CommonPrefs* cp, const TransportProcs* procs ); diff --git a/xwords4/linux/Makefile b/xwords4/linux/Makefile index 228050428..802372670 100644 --- a/xwords4/linux/Makefile +++ b/xwords4/linux/Makefile @@ -87,6 +87,7 @@ DEFINES += -DFEATURE_TRAY_EDIT DEFINES += -DXWFEATURE_CROSSHAIRS DEFINES += -DXWFEATURE_CHAT DEFINES += -DDISABLE_TILE_SEL +DEFINES += -DSET_GAMESEED DEFINES += -DTEXT_MODEL ifdef CURSES_CELL_HT diff --git a/xwords4/linux/cursesmain.c b/xwords4/linux/cursesmain.c index 03cb09f62..337164a69 100644 --- a/xwords4/linux/cursesmain.c +++ b/xwords4/linux/cursesmain.c @@ -1528,7 +1528,7 @@ cursesmain( XP_Bool isServer, LaunchParams* params ) } else { game_makeNewGame( MEMPOOL &g_globals.cGlobals.game, ¶ms->gi, params->util, (DrawCtx*)g_globals.draw, - &g_globals.cGlobals.cp, &procs ); + &g_globals.cGlobals.cp, &procs, params->gameSeed ); } #ifndef XWFEATURE_STANDALONE_ONLY diff --git a/xwords4/linux/gtkmain.c b/xwords4/linux/gtkmain.c index 641aeea74..5602fb285 100644 --- a/xwords4/linux/gtkmain.c +++ b/xwords4/linux/gtkmain.c @@ -443,7 +443,7 @@ createOrLoadObjects( GtkAppGlobals* globals ) game_makeNewGame( MEMPOOL &globals->cGlobals.game, ¶ms->gi, params->util, (DrawCtx*)globals->draw, - &globals->cGlobals.cp, &procs ); + &globals->cGlobals.cp, &procs, params->gameSeed ); addr.conType = params->conType; if ( 0 ) { diff --git a/xwords4/linux/linuxmain.c b/xwords4/linux/linuxmain.c index 146ab6521..46fc72319 100644 --- a/xwords4/linux/linuxmain.c +++ b/xwords4/linux/linuxmain.c @@ -250,6 +250,7 @@ typedef enum { ,CMD_DICT ,CMD_PLAYERDICT ,CMD_SEED + ,CMD_GAMESEED ,CMD_GAMEFILE ,CMD_MMAP ,CMD_PRINTHISORY @@ -323,6 +324,7 @@ static CmdInfoRec CmdInfoRecs[] = { ,{ CMD_DICT, true, "game-dict", "dictionary name for game" } ,{ CMD_PLAYERDICT, true, "player-dict", "dictionary name for player (in sequence)" } ,{ CMD_SEED, true, "seed", "random seed" } + ,{ CMD_GAMESEED, true, "game-seed", "game seed (for relay play)" } ,{ CMD_GAMEFILE, true, "file", "file to save to/read from" } ,{ CMD_MMAP, false, "use-mmap", "mmap dicts rather than copy them to memory" } ,{ CMD_PRINTHISORY, false, "print-history", "print history on game over" } @@ -1026,6 +1028,9 @@ main( int argc, char** argv ) case CMD_SEED: seed = atoi(optarg); break; + case CMD_GAMESEED: + mainParams.gameSeed = atoi(optarg); + break; case CMD_GAMEFILE: mainParams.fileName = optarg; break; diff --git a/xwords4/linux/main.h b/xwords4/linux/main.h index 9a234d748..98b031f9a 100644 --- a/xwords4/linux/main.h +++ b/xwords4/linux/main.h @@ -54,6 +54,7 @@ typedef struct LaunchParams { VTableMgr* vtMgr; XP_U16 nLocalPlayers; XP_U16 nHidden; + XP_U16 gameSeed; XP_S16 dropNthRcvd; /* negative means use for random calc */ XP_U16 nPacketsRcvd; /* toward dropNthRcvd */ XP_Bool askNewGame;