Stop reconstructing the engine state when restoring, but reset it instead

svn-id: r49376
This commit is contained in:
Filippos Karapetis 2010-06-01 15:48:17 +00:00
parent 1f54cdf90d
commit 65f3cfcbd8
5 changed files with 74 additions and 80 deletions

View File

@ -111,7 +111,7 @@ int game_init(EngineState *s) {
if (g_sci->_gfxMenu)
g_sci->_gfxMenu->reset();
s->successor = NULL; // No successor
s->restoring = false;
s->game_start_time = g_system->getMillis();
s->last_wait_time = s->game_start_time;
@ -134,9 +134,8 @@ int game_init(EngineState *s) {
}
int game_exit(EngineState *s) {
s->_executionStack.clear();
if (!s->successor) {
if (!s->restoring) {
s->_executionStack.clear();
#ifdef USE_OLD_MUSIC_FUNCTIONS
s->_sound.sfx_exit();
// Reinit because some other code depends on having a valid state

View File

@ -821,7 +821,6 @@ static void reconstruct_sounds(EngineState *s) {
#endif
void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
EngineState *retval;
#ifdef USE_OLD_MUSIC_FUNCTIONS
SongLibrary temp;
#endif
@ -856,76 +855,66 @@ void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
thumbnail = 0;
}
// Create a new EngineState object
retval = new EngineState(s->_segMan);
retval->_event = s->_event;
// Copy some old data
retval->_soundCmd = s->_soundCmd;
// Copy memory segment
retval->_memorySegmentSize = s->_memorySegmentSize;
memcpy(retval->_memorySegment, s->_memorySegment, s->_memorySegmentSize);
retval->saveLoadWithSerializer(ser); // FIXME: Error handling?
s->reset(true);
s->saveLoadWithSerializer(ser); // FIXME: Error handling?
#ifdef USE_OLD_MUSIC_FUNCTIONS
s->_sound.sfx_exit();
#endif
// Set exec stack base to zero
retval->execution_stack_base = 0;
s->execution_stack_base = 0;
// Now copy all current state information
#ifdef USE_OLD_MUSIC_FUNCTIONS
temp = retval->_sound._songlib;
retval->_sound.sfx_init(g_sci->getResMan(), s->sfx_init_flags, g_sci->_features->detectDoSoundType());
retval->sfx_init_flags = s->sfx_init_flags;
retval->_sound._songlib.freeSounds();
retval->_sound._songlib = temp;
retval->_soundCmd->updateSfxState(&retval->_sound);
temp = s->_sound._songlib;
s->_sound.sfx_init(g_sci->getResMan(), s->sfx_init_flags, g_sci->_features->detectDoSoundType());
s->sfx_init_flags = s->sfx_init_flags;
s->_sound._songlib.freeSounds();
s->_sound._songlib = temp;
s->_soundCmd->updateSfxState(&retval->_sound);
#endif
reconstruct_stack(retval);
retval->_segMan->reconstructScripts(retval);
retval->_segMan->reconstructClones();
retval->_gameObj = s->_gameObj;
retval->script_000 = retval->_segMan->getScript(retval->_segMan->getScriptSegment(0, SCRIPT_GET_DONT_LOAD));
retval->gc_countdown = GC_INTERVAL - 1;
reconstruct_stack(s);
s->_segMan->reconstructScripts(s);
s->_segMan->reconstructClones();
s->_gameObj = s->_gameObj;
s->script_000 = s->_segMan->getScript(s->_segMan->getScriptSegment(0, SCRIPT_GET_DONT_LOAD));
s->gc_countdown = GC_INTERVAL - 1;
// Time state:
retval->last_wait_time = g_system->getMillis();
retval->game_start_time = g_system->getMillis();
s->last_wait_time = g_system->getMillis();
s->game_start_time = g_system->getMillis();
retval->successor = NULL;
s->restoring = false;
#ifdef USE_OLD_MUSIC_FUNCTIONS
retval->_sound._it = NULL;
retval->_sound._flags = s->_sound._flags;
retval->_sound._song = NULL;
retval->_sound._suspended = s->_sound._suspended;
reconstruct_sounds(retval);
s->_sound._it = NULL;
s->_sound._flags = s->_sound._flags;
s->_sound._song = NULL;
s->_sound._suspended = s->_sound._suspended;
reconstruct_sounds(s);
#else
retval->_soundCmd->reconstructPlayList(meta.savegame_version);
s->_soundCmd->reconstructPlayList(meta.savegame_version);
#endif
// Message state:
retval->_msgState = new MessageState(retval->_segMan);
s->_msgState = new MessageState(s->_segMan);
#ifdef ENABLE_SCI32
if (g_sci->_gui32) {
g_sci->_gui32->init();
} else {
#endif
g_sci->_gui->resetEngineState(retval);
g_sci->_gui->resetEngineState(s);
g_sci->_gui->init(g_sci->_features->usesOldGfxFunctions());
#ifdef ENABLE_SCI32
}
#endif
s->successor = retval; // Set successor
s->restoring = true;
script_abort_flag = 2; // Abort current game with replay
s->shrinkStackToBase();
}

View File

@ -72,45 +72,49 @@ static const uint16 s_halfWidthSJISMap[256] = {
EngineState::EngineState(SegManager *segMan)
: _segMan(segMan), _dirseeker() {
reset(false);
}
EngineState::~EngineState() {
delete _msgState;
}
void EngineState::reset(bool isRestoring) {
#ifdef USE_OLD_MUSIC_FUNCTIONS
sfx_init_flags = 0;
#endif
restarting_flags = 0;
if (!isRestoring) {
script_000 = 0;
_gameObj = NULL_REG;
_memorySegmentSize = 0;
_soundCmd = 0;
restarting_flags = 0;
execution_stack_base = 0;
_executionStackPosChanged = false;
_fileHandles.resize(5);
r_acc = NULL_REG;
restAdjust = 0;
r_prev = NULL_REG;
stack_base = 0;
stack_top = 0;
}
last_wait_time = 0;
_fileHandles.resize(5);
execution_stack_base = 0;
_executionStackPosChanged = false;
r_acc = NULL_REG;
restAdjust = 0;
r_prev = NULL_REG;
stack_base = 0;
stack_top = 0;
script_000 = 0;
_gameObj = NULL_REG;
gc_countdown = 0;
successor = 0;
_throttleCounter = 0;
_throttleLastTime = 0;
_throttleTrigger = false;
_memorySegmentSize = 0;
_soundCmd = 0;
}
EngineState::~EngineState() {
delete _msgState;
restoring = false;
}
void EngineState::wait(int16 ticks) {

View File

@ -174,7 +174,12 @@ public:
uint _memorySegmentSize;
byte _memorySegment[kMemorySegmentMax];
EngineState *successor; /**< Successor of this state: Used for restoring */
/**
* Resets the engine state.
*/
void reset(bool isRestoring);
bool restoring; /**< A flag to indicate if a game is being restored */
};
} // End of namespace Sci

View File

@ -1695,17 +1695,16 @@ static void _init_stack_base_with_selector(EngineState *s, Selector selector) {
}
static EngineState *_game_run(EngineState *&s) {
EngineState *successor = NULL;
int game_is_finished = 0;
bool restoring = false;
if (DebugMan.isDebugChannelEnabled(kDebugLevelOnStartup))
g_sci->getSciDebugger()->attach();
do {
s->_executionStackPosChanged = false;
run_vm(s, successor ? true : false);
run_vm(s, restoring);
if (s->restarting_flags & SCI_GAME_IS_RESTARTING_NOW) { // Restart was requested?
successor = NULL;
restoring = false;
s->_executionStack.clear();
s->_executionStackPosChanged = false;
@ -1723,12 +1722,10 @@ static EngineState *_game_run(EngineState *&s) {
s->restarting_flags = SCI_GAME_WAS_RESTARTED;
} else {
successor = s->successor;
if (successor) {
restoring = s->restoring;
if (restoring) {
game_exit(s);
delete s;
s = successor;
s->restoring = false;
if (script_abort_flag == 2) {
debugC(2, kDebugLevelVM, "Restarting with replay()");
s->_executionStack.clear(); // Restart with replay
@ -1741,9 +1738,9 @@ static EngineState *_game_run(EngineState *&s) {
script_abort_flag = 0;
} else
game_is_finished = 1;
break; // exit loop
}
} while (!game_is_finished);
} while (true);
return s;
}