From 10aeb33a4253b5df05f19a9bfabc3cc374db096c Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 9 Jun 2010 07:32:17 +0000 Subject: [PATCH] Merged restAdjust and restAdjustCur, as we don't save the restAdjust modifier inside saved games (rightfully so). Also, the segment manager is now reset inside the main loop, when the game is restarted, not in game_exit() svn-id: r49533 --- engines/sci/console.cpp | 2 +- engines/sci/engine/game.cpp | 10 ----- engines/sci/engine/scriptdebug.cpp | 6 +-- engines/sci/engine/state.cpp | 1 - engines/sci/engine/state.h | 3 +- engines/sci/engine/vm.cpp | 63 ++++++++++++++---------------- 6 files changed, 35 insertions(+), 50 deletions(-) diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index e7c70a2aedc..9f1d03df25c 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -597,7 +597,7 @@ bool Console::cmdSetParseNodes(int argc, const char **argv) { bool Console::cmdRegisters(int argc, const char **argv) { EngineState *s = _engine->_gamestate; DebugPrintf("Current register values:\n"); - DebugPrintf("acc=%04x:%04x prev=%04x:%04x &rest=%x\n", PRINT_REG(s->r_acc), PRINT_REG(s->r_prev), s->restAdjustCur); + DebugPrintf("acc=%04x:%04x prev=%04x:%04x &rest=%x\n", PRINT_REG(s->r_acc), PRINT_REG(s->r_prev), s->restAdjust); if (!s->_executionStack.empty()) { DebugPrintf("pc=%04x:%04x obj=%04x:%04x fp=ST:%04x sp=ST:%04x\n", diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp index 5fa1fc0558a..4f4ae774e08 100644 --- a/engines/sci/engine/game.cpp +++ b/engines/sci/engine/game.cpp @@ -70,7 +70,6 @@ int script_init_engine(EngineState *s) { s->_segMan->initSysStrings(); s->r_acc = s->r_prev = NULL_REG; - s->restAdjust = 0; s->_executionStack.clear(); // Start without any execution stack s->execution_stack_base = -1; // No vm is running yet @@ -144,15 +143,6 @@ int game_exit(EngineState *s) { #endif } - // Note: It's a bad idea to delete the segment manager here - // when loading a game. - // This function is called right after a game is loaded, and - // the segment manager has already been initialized from the - // save game. Deleting or resetting it here will result in - // invalidating the loaded save state - if (s->abortScriptProcessing == kAbortRestartGame) - s->_segMan->resetSegMan(); - // TODO Free parser segment here // TODO Free scripts here diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index b465ab3d4eb..159c278e8cb 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -205,12 +205,12 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod if (pos == s->xs->addr.pc) { // Extra information if debugging the current opcode if (opcode == op_callk) { - int stackframe = (scr[pos.offset + 2] >> 1) + (s->restAdjustCur); + int stackframe = (scr[pos.offset + 2] >> 1) + (s->restAdjust); int argc = ((s->xs->sp)[- stackframe - 1]).offset; bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY); if (!oldScriptHeader) - argc += (s->restAdjustCur); + argc += (s->restAdjust); printf(" Kernel params: ("); @@ -221,7 +221,7 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod } printf(")\n"); } else if ((opcode == op_send) || (opcode == op_self)) { - int restmod = s->restAdjustCur; + int restmod = s->restAdjust; int stackframe = (scr[pos.offset + 1] >> 1) + restmod; reg_t *sb = s->xs->sp; uint16 selector; diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 0c021863c0c..2410b2666d9 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -102,7 +102,6 @@ void EngineState::reset(bool isRestoring) { _executionStackPosChanged = false; restAdjust = 0; - restAdjustCur = 0; r_acc = NULL_REG; r_prev = NULL_REG; diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index 6b7dc54a242..3fcefd80c40 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -147,8 +147,7 @@ public: bool _executionStackPosChanged; /**< Set to true if the execution stack position should be re-evaluated by the vm */ reg_t r_acc; /**< Accumulator */ - int16 restAdjust; /**< &rest register (only used for save games) */ - int16 restAdjustCur; /**< current &rest register (only used for save games) */ + int16 restAdjust; /**< current &rest register (only used for save games) */ reg_t r_prev; /**< previous comparison result */ StackPtr stack_base; /**< Pointer to the least stack element */ diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index d7e3c794b36..71d6672eb42 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -718,7 +718,7 @@ void run_vm(EngineState *s, bool restoring) { StackPtr s_temp; // Temporary stack pointer int16 opparams[4]; // opcode parameters - s->restAdjustCur = s->restAdjust; + s->restAdjust = 0; // &rest adjusts the parameter count by this value // Current execution data: s->xs = &(s->_executionStack.back()); @@ -1116,17 +1116,17 @@ void run_vm(EngineState *s, bool restoring) { case op_call: { // 0x20 (32) int argc = (opparams[1] >> 1) // Given as offset, but we need count - + 1 + s->restAdjustCur; + + 1 + s->restAdjust; StackPtr call_base = s->xs->sp - argc; - s->xs->sp[1].offset += s->restAdjustCur; + s->xs->sp[1].offset += s->restAdjust; xs_new = add_exec_stack_entry(s->_executionStack, make_reg(s->xs->addr.pc.segment, s->xs->addr.pc.offset + opparams[0]), s->xs->sp, s->xs->objp, - (validate_arithmetic(*call_base)) + s->restAdjustCur, + (validate_arithmetic(*call_base)) + s->restAdjust, call_base, NULL_SELECTOR, s->xs->objp, s->_executionStack.size()-1, s->xs->local_segment); - s->restAdjustCur = 0; // Used up the &rest adjustment + s->restAdjust = 0; // Used up the &rest adjustment s->xs->sp = call_base; s->_executionStackPosChanged = true; @@ -1139,20 +1139,18 @@ void run_vm(EngineState *s, bool restoring) { s->xs->sp -= (opparams[1] >> 1) + 1; bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY); - if (!oldScriptHeader) { - s->xs->sp -= s->restAdjustCur; - s->restAdjust = 0; // We just used up the s->restAdjustCur, remember? - } + if (!oldScriptHeader) + s->xs->sp -= s->restAdjust; int argc = validate_arithmetic(s->xs->sp[0]); if (!oldScriptHeader) - argc += s->restAdjustCur; + argc += s->restAdjust; callKernelFunc(s, opparams[0], argc); if (!oldScriptHeader) - s->restAdjustCur = s->restAdjust; + s->restAdjust = 0; // Calculate xs again: The kernel function might // have spawned a new VM @@ -1163,27 +1161,27 @@ void run_vm(EngineState *s, bool restoring) { } case op_callb: // 0x22 (34) - temp = ((opparams[1] >> 1) + s->restAdjustCur + 1); + temp = ((opparams[1] >> 1) + s->restAdjust + 1); s_temp = s->xs->sp; s->xs->sp -= temp; - s->xs->sp[0].offset += s->restAdjustCur; + s->xs->sp[0].offset += s->restAdjust; xs_new = execute_method(s, 0, opparams[0], s_temp, s->xs->objp, s->xs->sp[0].offset, s->xs->sp); - s->restAdjustCur = 0; // Used up the &rest adjustment + s->restAdjust = 0; // Used up the &rest adjustment if (xs_new) // in case of error, keep old stack s->_executionStackPosChanged = true; break; case op_calle: // 0x23 (35) - temp = ((opparams[2] >> 1) + s->restAdjustCur + 1); + temp = ((opparams[2] >> 1) + s->restAdjust + 1); s_temp = s->xs->sp; s->xs->sp -= temp; - s->xs->sp[0].offset += s->restAdjustCur; + s->xs->sp[0].offset += s->restAdjust; xs_new = execute_method(s, opparams[0], opparams[1], s_temp, s->xs->objp, s->xs->sp[0].offset, s->xs->sp); - s->restAdjustCur = 0; // Used up the &rest adjustment + s->restAdjust = 0; // Used up the &rest adjustment if (xs_new) // in case of error, keep old stack s->_executionStackPosChanged = true; @@ -1201,7 +1199,6 @@ void run_vm(EngineState *s, bool restoring) { s->_executionStack.pop_back(); s->_executionStackPosChanged = true; - s->restAdjust = s->restAdjustCur; // Update &rest return; // "Hard" return } @@ -1234,16 +1231,16 @@ void run_vm(EngineState *s, bool restoring) { case op_send: // 0x25 (37) s_temp = s->xs->sp; - s->xs->sp -= ((opparams[0] >> 1) + s->restAdjustCur); // Adjust stack + s->xs->sp -= ((opparams[0] >> 1) + s->restAdjust); // Adjust stack - s->xs->sp[1].offset += s->restAdjustCur; + s->xs->sp[1].offset += s->restAdjust; xs_new = send_selector(s, s->r_acc, s->r_acc, s_temp, - (int)(opparams[0] >> 1) + (uint16)s->restAdjustCur, s->xs->sp); + (int)(opparams[0] >> 1) + (uint16)s->restAdjust, s->xs->sp); if (xs_new && xs_new != s->xs) s->_executionStackPosChanged = true; - s->restAdjustCur = 0; + s->restAdjust = 0; break; @@ -1263,17 +1260,17 @@ void run_vm(EngineState *s, bool restoring) { case op_self: // 0x2a (42) s_temp = s->xs->sp; - s->xs->sp -= ((opparams[0] >> 1) + s->restAdjustCur); // Adjust stack + s->xs->sp -= ((opparams[0] >> 1) + s->restAdjust); // Adjust stack - s->xs->sp[1].offset += s->restAdjustCur; + s->xs->sp[1].offset += s->restAdjust; xs_new = send_selector(s, s->xs->objp, s->xs->objp, - s_temp, (int)(opparams[0] >> 1) + (uint16)s->restAdjustCur, + s_temp, (int)(opparams[0] >> 1) + (uint16)s->restAdjust, s->xs->sp); if (xs_new && xs_new != s->xs) s->_executionStackPosChanged = true; - s->restAdjustCur = 0; + s->restAdjust = 0; break; case op_super: // 0x2b (43) @@ -1283,24 +1280,24 @@ void run_vm(EngineState *s, bool restoring) { error("[VM]: Invalid superclass in object"); else { s_temp = s->xs->sp; - s->xs->sp -= ((opparams[1] >> 1) + s->restAdjustCur); // Adjust stack + s->xs->sp -= ((opparams[1] >> 1) + s->restAdjust); // Adjust stack - s->xs->sp[1].offset += s->restAdjustCur; + s->xs->sp[1].offset += s->restAdjust; xs_new = send_selector(s, r_temp, s->xs->objp, s_temp, - (int)(opparams[1] >> 1) + (uint16)s->restAdjustCur, + (int)(opparams[1] >> 1) + (uint16)s->restAdjust, s->xs->sp); if (xs_new && xs_new != s->xs) s->_executionStackPosChanged = true; - s->restAdjustCur = 0; + s->restAdjust = 0; } break; case op_rest: // 0x2c (44) temp = (uint16) opparams[0]; // First argument - s->restAdjustCur = MAX(s->xs->argc - temp + 1, 0); // +1 because temp counts the paramcount while argc doesn't + s->restAdjust = MAX(s->xs->argc - temp + 1, 0); // +1 because temp counts the paramcount while argc doesn't for (; temp <= s->xs->argc; temp++) PUSH32(s->xs->variables_argp[temp]); @@ -1715,6 +1712,7 @@ void game_run(EngineState **_s) { s->abortScriptProcessing = kAbortNone; s->_executionStackPosChanged = false; + s->_segMan->resetSegMan(); script_init_engine(s); game_init(s); #ifdef USE_OLD_MUSIC_FUNCTIONS @@ -1727,8 +1725,7 @@ void game_run(EngineState **_s) { s->gameWasRestarted = true; } else if (s->abortScriptProcessing == kAbortLoadGame) { s->abortScriptProcessing = kAbortNone; - debugC(2, kDebugLevelVM, "Restarting with replay()"); - // Restart with replay + // Insert a replay selector _init_stack_base_with_selector(s, g_sci->getKernel()->_selectorCache.replay); send_selector(s, s->_gameObj, s->_gameObj, s->stack_base, 2, s->stack_base); } else {