Fix nasty crashers: restore previous game when unable to open new,

e.g. because it was created with a dict that's no longer available (in
which case warn to that effect.)
This commit is contained in:
ehouse 2008-09-28 16:48:30 +00:00
parent a72e4d0c13
commit d2afc68ba8

View file

@ -148,7 +148,7 @@ static XP_Bool ceSaveCurGame( CEAppGlobals* globals, XP_Bool autoSave );
static void closeGame( CEAppGlobals* globals ); static void closeGame( CEAppGlobals* globals );
static void ceInitPrefs( CEAppGlobals* globals, CEAppPrefs* prefs ); static void ceInitPrefs( CEAppGlobals* globals, CEAppPrefs* prefs );
static void updateForColors( CEAppGlobals* globals ); static void updateForColors( CEAppGlobals* globals );
static XWStreamCtxt* make_generic_stream( CEAppGlobals* globals ); static XWStreamCtxt* make_generic_stream( const CEAppGlobals* globals );
#ifdef XWFEATURE_RELAY #ifdef XWFEATURE_RELAY
static void ce_send_on_close( XWStreamCtxt* stream, void* closure ); static void ce_send_on_close( XWStreamCtxt* stream, void* closure );
#endif #endif
@ -919,14 +919,14 @@ ceLoadPrefs( CEAppGlobals* globals )
} /* ceLoadPrefs */ } /* ceLoadPrefs */
static XWStreamCtxt* static XWStreamCtxt*
make_generic_stream( CEAppGlobals* globals ) make_generic_stream( const CEAppGlobals* globals )
{ {
return mem_stream_make( MPPARM(globals->mpool) globals->vtMgr, return mem_stream_make( MPPARM(globals->mpool) globals->vtMgr,
globals, 0, NULL ); (void*)globals, 0, NULL );
} /* make_generic_stream */ } /* make_generic_stream */
static XWStreamCtxt* static XWStreamCtxt*
fileToStream( CEAppGlobals* globals, const XP_UCHAR* path ) fileToStream( const CEAppGlobals* globals, const XP_UCHAR* path )
{ {
XWStreamCtxt* stream = NULL; XWStreamCtxt* stream = NULL;
HANDLE fileH; HANDLE fileH;
@ -982,31 +982,42 @@ ceLoadSavedGame( CEAppGlobals* globals )
#ifdef STUBBED_DICT #ifdef STUBBED_DICT
XP_ASSERT(0); /* just don't do this!!!! */ XP_ASSERT(0); /* just don't do this!!!! */
#else #else
XP_UCHAR* name = stringFromStream( globals->mpool, stream ); XP_UCHAR* dictName = stringFromStream( globals->mpool, stream );
dict = ce_dictionary_make( globals, name ); dict = ce_dictionary_make( globals, dictName );
XP_FREE( globals->mpool, name );
success = dict != NULL; success = dict != NULL;
if ( !success ) {
XP_UCHAR buf[128];
snprintf( buf, VSIZE(buf), "Unable to open dictionary: %s",
dictName );
buf[VSIZE(buf)-1] = '\0';
messageBoxChar( globals, buf, L"Oops!", MB_OK );
}
XP_FREE( globals->mpool, dictName );
#endif #endif
} else { } else {
dict = NULL; dict = NULL;
} }
if ( flags >= CE_GAMEFILE_VERSION ) {
ce_draw_fromStream( globals->draw, stream );
}
if ( success ) { if ( success ) {
if ( flags >= CE_GAMEFILE_VERSION ) {
ce_draw_fromStream( globals->draw, stream );
}
XP_DEBUGF( "calling game_makeFromStream" ); XP_DEBUGF( "calling game_makeFromStream" );
game_makeFromStream( MEMPOOL stream, &globals->game, success = game_makeFromStream( MEMPOOL stream, &globals->game,
&globals->gameInfo, &globals->gameInfo, dict,
dict, &globals->util, (DrawCtx*)globals->draw, &globals->util,
&globals->appPrefs.cp, CE_SEND_PROC, (DrawCtx*)globals->draw,
CE_RESET_PROC globals ); &globals->appPrefs.cp, CE_SEND_PROC,
CE_RESET_PROC globals );
if ( success ) {
ceSetTitleFromName( globals );
} else if ( !!dict ) {
dict_destroy( dict );
}
} }
stream_destroy( stream ); stream_destroy( stream );
ceSetTitleFromName( globals );
} }
return success; return success;
@ -1470,13 +1481,16 @@ static void
ceChooseAndOpen( CEAppGlobals* globals ) ceChooseAndOpen( CEAppGlobals* globals )
{ {
// Save in case we'll be duplicating it // Save in case we'll be duplicating it
if ( ceSaveCurGame( globals, XP_FALSE ) ) { if ( ceSaveCurGame( globals, XP_FALSE )
|| queryBoxChar( globals, "Do you really want to "
"overwrite the current game?" ) ) {
wchar_t path[256]; wchar_t path[256];
path[0] = 0; path[0] = 0;
ceSetTitleFromName( globals ); /* in case we named it above */ ceSetTitleFromName( globals ); /* in case we named it above */
if ( ceSavedGamesDlg( globals, globals->curGameName, path, VSIZE(path) )) { if ( ceSavedGamesDlg( globals, globals->curGameName,
path, VSIZE(path) )) {
XP_UCHAR* name; XP_UCHAR* name;
XP_U16 len; XP_U16 len;
@ -1487,19 +1501,35 @@ ceChooseAndOpen( CEAppGlobals* globals )
name, len + 1, NULL, NULL ); name, len + 1, NULL, NULL );
if ( globals->curGameName != NULL if ( globals->curGameName != NULL
&& 0 == XP_STRCMP( name, globals->curGameName ) ){ /*already open*/ && 0 == XP_STRCMP( name, globals->curGameName ) ){
/* User chose already-open game; no-op */
XP_FREE( globals->mpool, name ); XP_FREE( globals->mpool, name );
} else if ( ceSaveCurGame( globals, XP_FALSE ) } else {
|| queryBoxChar( globals, "Do you really want to " /* Save old name in case fail to open new, e.g. because dict
"overwrite the current game?" ) ) { not there */
XP_UCHAR* oldName;
/* Need to save a second time, with auto-save, in case user
wants to overwrite yet chooses a game whose dict is
missing -- since then we'll be re-opening this game! */
ceSaveCurGame( globals, XP_TRUE ); /* may change curGameName */
oldName = globals->curGameName;
globals->curGameName = NULL; /* prevent being destroyed */
closeGame( globals ); closeGame( globals );
globals->curGameName = name; globals->curGameName = name;
if ( ceLoadSavedGame( globals ) ) { if ( ceLoadSavedGame( globals ) ) {
ceInitAndStartBoard( globals, XP_FALSE, NULL ); XP_FREE( globals->mpool, oldName );
} else { } else {
XP_LOGF( "failed to open chosen game" ); XP_LOGF( "failed to open chosen game" );
XP_FREE( globals->mpool, globals->curGameName );
globals->curGameName = oldName;
if ( !ceLoadSavedGame( globals ) ) {
XP_LOGF( "failed to open old game too!!!" );
}
} }
ceInitAndStartBoard( globals, XP_FALSE, NULL );
} }
} else { } else {
XP_LOGF( "GetOpenFileName() failed" ); XP_LOGF( "GetOpenFileName() failed" );
@ -1688,7 +1718,7 @@ closeGame( CEAppGlobals* globals )
game_dispose( &globals->game ); game_dispose( &globals->game );
gi_disposePlayerInfo( MPPARM(globals->mpool) &globals->gameInfo ); gi_disposePlayerInfo( MPPARM(globals->mpool) &globals->gameInfo );
if ( globals->curGameName ) { if ( !!globals->curGameName ) {
XP_FREE( globals->mpool, globals->curGameName ); XP_FREE( globals->mpool, globals->curGameName );
} }
} }