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
This commit is contained in:
parent
b494d46fdd
commit
10aeb33a42
6 changed files with 35 additions and 50 deletions
|
@ -597,7 +597,7 @@ bool Console::cmdSetParseNodes(int argc, const char **argv) {
|
||||||
bool Console::cmdRegisters(int argc, const char **argv) {
|
bool Console::cmdRegisters(int argc, const char **argv) {
|
||||||
EngineState *s = _engine->_gamestate;
|
EngineState *s = _engine->_gamestate;
|
||||||
DebugPrintf("Current register values:\n");
|
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()) {
|
if (!s->_executionStack.empty()) {
|
||||||
DebugPrintf("pc=%04x:%04x obj=%04x:%04x fp=ST:%04x sp=ST:%04x\n",
|
DebugPrintf("pc=%04x:%04x obj=%04x:%04x fp=ST:%04x sp=ST:%04x\n",
|
||||||
|
|
|
@ -70,7 +70,6 @@ int script_init_engine(EngineState *s) {
|
||||||
s->_segMan->initSysStrings();
|
s->_segMan->initSysStrings();
|
||||||
|
|
||||||
s->r_acc = s->r_prev = NULL_REG;
|
s->r_acc = s->r_prev = NULL_REG;
|
||||||
s->restAdjust = 0;
|
|
||||||
|
|
||||||
s->_executionStack.clear(); // Start without any execution stack
|
s->_executionStack.clear(); // Start without any execution stack
|
||||||
s->execution_stack_base = -1; // No vm is running yet
|
s->execution_stack_base = -1; // No vm is running yet
|
||||||
|
@ -144,15 +143,6 @@ int game_exit(EngineState *s) {
|
||||||
#endif
|
#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 parser segment here
|
||||||
|
|
||||||
// TODO Free scripts here
|
// TODO Free scripts here
|
||||||
|
|
|
@ -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 (pos == s->xs->addr.pc) { // Extra information if debugging the current opcode
|
||||||
if (opcode == op_callk) {
|
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;
|
int argc = ((s->xs->sp)[- stackframe - 1]).offset;
|
||||||
bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);
|
bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);
|
||||||
|
|
||||||
if (!oldScriptHeader)
|
if (!oldScriptHeader)
|
||||||
argc += (s->restAdjustCur);
|
argc += (s->restAdjust);
|
||||||
|
|
||||||
printf(" Kernel params: (");
|
printf(" Kernel params: (");
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod
|
||||||
}
|
}
|
||||||
printf(")\n");
|
printf(")\n");
|
||||||
} else if ((opcode == op_send) || (opcode == op_self)) {
|
} else if ((opcode == op_send) || (opcode == op_self)) {
|
||||||
int restmod = s->restAdjustCur;
|
int restmod = s->restAdjust;
|
||||||
int stackframe = (scr[pos.offset + 1] >> 1) + restmod;
|
int stackframe = (scr[pos.offset + 1] >> 1) + restmod;
|
||||||
reg_t *sb = s->xs->sp;
|
reg_t *sb = s->xs->sp;
|
||||||
uint16 selector;
|
uint16 selector;
|
||||||
|
|
|
@ -102,7 +102,6 @@ void EngineState::reset(bool isRestoring) {
|
||||||
_executionStackPosChanged = false;
|
_executionStackPosChanged = false;
|
||||||
|
|
||||||
restAdjust = 0;
|
restAdjust = 0;
|
||||||
restAdjustCur = 0;
|
|
||||||
|
|
||||||
r_acc = NULL_REG;
|
r_acc = NULL_REG;
|
||||||
r_prev = NULL_REG;
|
r_prev = NULL_REG;
|
||||||
|
|
|
@ -147,8 +147,7 @@ public:
|
||||||
bool _executionStackPosChanged; /**< Set to true if the execution stack position should be re-evaluated by the vm */
|
bool _executionStackPosChanged; /**< Set to true if the execution stack position should be re-evaluated by the vm */
|
||||||
|
|
||||||
reg_t r_acc; /**< Accumulator */
|
reg_t r_acc; /**< Accumulator */
|
||||||
int16 restAdjust; /**< &rest register (only used for save games) */
|
int16 restAdjust; /**< current &rest register (only used for save games) */
|
||||||
int16 restAdjustCur; /**< current &rest register (only used for save games) */
|
|
||||||
reg_t r_prev; /**< previous comparison result */
|
reg_t r_prev; /**< previous comparison result */
|
||||||
|
|
||||||
StackPtr stack_base; /**< Pointer to the least stack element */
|
StackPtr stack_base; /**< Pointer to the least stack element */
|
||||||
|
|
|
@ -718,7 +718,7 @@ void run_vm(EngineState *s, bool restoring) {
|
||||||
StackPtr s_temp; // Temporary stack pointer
|
StackPtr s_temp; // Temporary stack pointer
|
||||||
int16 opparams[4]; // opcode parameters
|
int16 opparams[4]; // opcode parameters
|
||||||
|
|
||||||
s->restAdjustCur = s->restAdjust;
|
s->restAdjust = 0;
|
||||||
// &rest adjusts the parameter count by this value
|
// &rest adjusts the parameter count by this value
|
||||||
// Current execution data:
|
// Current execution data:
|
||||||
s->xs = &(s->_executionStack.back());
|
s->xs = &(s->_executionStack.back());
|
||||||
|
@ -1116,17 +1116,17 @@ void run_vm(EngineState *s, bool restoring) {
|
||||||
|
|
||||||
case op_call: { // 0x20 (32)
|
case op_call: { // 0x20 (32)
|
||||||
int argc = (opparams[1] >> 1) // Given as offset, but we need count
|
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;
|
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,
|
xs_new = add_exec_stack_entry(s->_executionStack, make_reg(s->xs->addr.pc.segment,
|
||||||
s->xs->addr.pc.offset + opparams[0]),
|
s->xs->addr.pc.offset + opparams[0]),
|
||||||
s->xs->sp, s->xs->objp,
|
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,
|
call_base, NULL_SELECTOR, s->xs->objp,
|
||||||
s->_executionStack.size()-1, s->xs->local_segment);
|
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->xs->sp = call_base;
|
||||||
|
|
||||||
s->_executionStackPosChanged = true;
|
s->_executionStackPosChanged = true;
|
||||||
|
@ -1139,20 +1139,18 @@ void run_vm(EngineState *s, bool restoring) {
|
||||||
s->xs->sp -= (opparams[1] >> 1) + 1;
|
s->xs->sp -= (opparams[1] >> 1) + 1;
|
||||||
|
|
||||||
bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);
|
bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);
|
||||||
if (!oldScriptHeader) {
|
if (!oldScriptHeader)
|
||||||
s->xs->sp -= s->restAdjustCur;
|
s->xs->sp -= s->restAdjust;
|
||||||
s->restAdjust = 0; // We just used up the s->restAdjustCur, remember?
|
|
||||||
}
|
|
||||||
|
|
||||||
int argc = validate_arithmetic(s->xs->sp[0]);
|
int argc = validate_arithmetic(s->xs->sp[0]);
|
||||||
|
|
||||||
if (!oldScriptHeader)
|
if (!oldScriptHeader)
|
||||||
argc += s->restAdjustCur;
|
argc += s->restAdjust;
|
||||||
|
|
||||||
callKernelFunc(s, opparams[0], argc);
|
callKernelFunc(s, opparams[0], argc);
|
||||||
|
|
||||||
if (!oldScriptHeader)
|
if (!oldScriptHeader)
|
||||||
s->restAdjustCur = s->restAdjust;
|
s->restAdjust = 0;
|
||||||
|
|
||||||
// Calculate xs again: The kernel function might
|
// Calculate xs again: The kernel function might
|
||||||
// have spawned a new VM
|
// have spawned a new VM
|
||||||
|
@ -1163,27 +1161,27 @@ void run_vm(EngineState *s, bool restoring) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case op_callb: // 0x22 (34)
|
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_temp = s->xs->sp;
|
||||||
s->xs->sp -= temp;
|
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,
|
xs_new = execute_method(s, 0, opparams[0], s_temp, s->xs->objp,
|
||||||
s->xs->sp[0].offset, s->xs->sp);
|
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
|
if (xs_new) // in case of error, keep old stack
|
||||||
s->_executionStackPosChanged = true;
|
s->_executionStackPosChanged = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case op_calle: // 0x23 (35)
|
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_temp = s->xs->sp;
|
||||||
s->xs->sp -= temp;
|
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,
|
xs_new = execute_method(s, opparams[0], opparams[1], s_temp, s->xs->objp,
|
||||||
s->xs->sp[0].offset, s->xs->sp);
|
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
|
if (xs_new) // in case of error, keep old stack
|
||||||
s->_executionStackPosChanged = true;
|
s->_executionStackPosChanged = true;
|
||||||
|
@ -1201,7 +1199,6 @@ void run_vm(EngineState *s, bool restoring) {
|
||||||
s->_executionStack.pop_back();
|
s->_executionStack.pop_back();
|
||||||
|
|
||||||
s->_executionStackPosChanged = true;
|
s->_executionStackPosChanged = true;
|
||||||
s->restAdjust = s->restAdjustCur; // Update &rest
|
|
||||||
return; // "Hard" return
|
return; // "Hard" return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1234,16 +1231,16 @@ void run_vm(EngineState *s, bool restoring) {
|
||||||
|
|
||||||
case op_send: // 0x25 (37)
|
case op_send: // 0x25 (37)
|
||||||
s_temp = s->xs->sp;
|
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,
|
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)
|
if (xs_new && xs_new != s->xs)
|
||||||
s->_executionStackPosChanged = true;
|
s->_executionStackPosChanged = true;
|
||||||
|
|
||||||
s->restAdjustCur = 0;
|
s->restAdjust = 0;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1263,17 +1260,17 @@ void run_vm(EngineState *s, bool restoring) {
|
||||||
|
|
||||||
case op_self: // 0x2a (42)
|
case op_self: // 0x2a (42)
|
||||||
s_temp = s->xs->sp;
|
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,
|
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);
|
s->xs->sp);
|
||||||
|
|
||||||
if (xs_new && xs_new != s->xs)
|
if (xs_new && xs_new != s->xs)
|
||||||
s->_executionStackPosChanged = true;
|
s->_executionStackPosChanged = true;
|
||||||
|
|
||||||
s->restAdjustCur = 0;
|
s->restAdjust = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case op_super: // 0x2b (43)
|
case op_super: // 0x2b (43)
|
||||||
|
@ -1283,24 +1280,24 @@ void run_vm(EngineState *s, bool restoring) {
|
||||||
error("[VM]: Invalid superclass in object");
|
error("[VM]: Invalid superclass in object");
|
||||||
else {
|
else {
|
||||||
s_temp = s->xs->sp;
|
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,
|
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);
|
s->xs->sp);
|
||||||
|
|
||||||
if (xs_new && xs_new != s->xs)
|
if (xs_new && xs_new != s->xs)
|
||||||
s->_executionStackPosChanged = true;
|
s->_executionStackPosChanged = true;
|
||||||
|
|
||||||
s->restAdjustCur = 0;
|
s->restAdjust = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case op_rest: // 0x2c (44)
|
case op_rest: // 0x2c (44)
|
||||||
temp = (uint16) opparams[0]; // First argument
|
temp = (uint16) opparams[0]; // First argument
|
||||||
s->restAdjustCur = MAX<int16>(s->xs->argc - temp + 1, 0); // +1 because temp counts the paramcount while argc doesn't
|
s->restAdjust = MAX<int16>(s->xs->argc - temp + 1, 0); // +1 because temp counts the paramcount while argc doesn't
|
||||||
|
|
||||||
for (; temp <= s->xs->argc; temp++)
|
for (; temp <= s->xs->argc; temp++)
|
||||||
PUSH32(s->xs->variables_argp[temp]);
|
PUSH32(s->xs->variables_argp[temp]);
|
||||||
|
@ -1715,6 +1712,7 @@ void game_run(EngineState **_s) {
|
||||||
s->abortScriptProcessing = kAbortNone;
|
s->abortScriptProcessing = kAbortNone;
|
||||||
s->_executionStackPosChanged = false;
|
s->_executionStackPosChanged = false;
|
||||||
|
|
||||||
|
s->_segMan->resetSegMan();
|
||||||
script_init_engine(s);
|
script_init_engine(s);
|
||||||
game_init(s);
|
game_init(s);
|
||||||
#ifdef USE_OLD_MUSIC_FUNCTIONS
|
#ifdef USE_OLD_MUSIC_FUNCTIONS
|
||||||
|
@ -1727,8 +1725,7 @@ void game_run(EngineState **_s) {
|
||||||
s->gameWasRestarted = true;
|
s->gameWasRestarted = true;
|
||||||
} else if (s->abortScriptProcessing == kAbortLoadGame) {
|
} else if (s->abortScriptProcessing == kAbortLoadGame) {
|
||||||
s->abortScriptProcessing = kAbortNone;
|
s->abortScriptProcessing = kAbortNone;
|
||||||
debugC(2, kDebugLevelVM, "Restarting with replay()");
|
// Insert a replay selector
|
||||||
// Restart with replay
|
|
||||||
_init_stack_base_with_selector(s, g_sci->getKernel()->_selectorCache.replay);
|
_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);
|
send_selector(s, s->_gameObj, s->_gameObj, s->stack_base, 2, s->stack_base);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue