Merge branch 'android_branch' into android_invite

This commit is contained in:
eehouse@eehouse.org 2011-08-03 06:20:08 -07:00 committed by Andy2
commit 19ce482a43
25 changed files with 169 additions and 121 deletions

View file

@ -16,7 +16,6 @@ local_DEFINES += \
-DXWFEATURE_RELAY \
-DXWFEATURE_TURNCHANGENOTIFY \
-DXWFEATURE_CHAT \
-DSHOW_PROGRESS \
-DKEY_SUPPORT \
-DXWFEATURE_CROSSHAIRS \
-DPOINTER_SUPPORT \

View file

@ -11,11 +11,17 @@
<ul>
<li>Redesign of how new games -- in particular networked games --
are created. You can now \"invite\" somebody to a game you're
are created. You can now "invite" somebody to a game you're
creating, or to an existing game that's missing players.</li>
<li>Add a setting for default player name, and on startup ask for it
-- but only once.</li>
<li>Make name fields assume upper-case</li>
<li>Sort games by creation date not name. (Soon you'll be able to
rename them.)</li>
<li>Fix/reduce impact of java memory leaks</li>
</ul>

View file

@ -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;
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 )

View file

@ -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() );
}

View file

@ -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;
}

View file

@ -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));

View file

@ -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;

View file

@ -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;
}

View file

@ -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 ) {

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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() );

View file

@ -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() );
}
}

View file

@ -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<QueueElem>();
}
public void waitToStop() {
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 );
}

View file

@ -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;

View file

@ -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;

View file

@ -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 );

View file

@ -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 );

View file

@ -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

View file

@ -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 );

View file

@ -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

View file

@ -1528,7 +1528,7 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
} else {
game_makeNewGame( MEMPOOL &g_globals.cGlobals.game, &params->gi,
params->util, (DrawCtx*)g_globals.draw,
&g_globals.cGlobals.cp, &procs );
&g_globals.cGlobals.cp, &procs, params->gameSeed );
}
#ifndef XWFEATURE_STANDALONE_ONLY

View file

@ -443,7 +443,7 @@ createOrLoadObjects( GtkAppGlobals* globals )
game_makeNewGame( MEMPOOL &globals->cGlobals.game, &params->gi,
params->util, (DrawCtx*)globals->draw,
&globals->cGlobals.cp, &procs );
&globals->cGlobals.cp, &procs, params->gameSeed );
addr.conType = params->conType;
if ( 0 ) {

View file

@ -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;

View file

@ -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;