diff options
author | Travis Howell | 2009-07-09 00:19:00 +0000 |
---|---|---|
committer | Travis Howell | 2009-07-09 00:19:00 +0000 |
commit | bffeaaae76ebe5b5e981f5157e9b806f48c29a4f (patch) | |
tree | e87a4f9827568c7dac1d4ec933e0b54f9f601262 /engines | |
parent | 828ed66555b99363fed62b4cbb83c36de68c3024 (diff) | |
parent | c7eedb573ac3ac1bd4c8f8e64d75ee8ee931bc50 (diff) | |
download | scummvm-rg350-bffeaaae76ebe5b5e981f5157e9b806f48c29a4f.tar.gz scummvm-rg350-bffeaaae76ebe5b5e981f5157e9b806f48c29a4f.tar.bz2 scummvm-rg350-bffeaaae76ebe5b5e981f5157e9b806f48c29a4f.zip |
Merged revisions 42252,42255-42263,42269-42271 via svnmerge from
https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk
........
r42252 | Kirben | 2009-07-08 11:07:41 +1000 (Wed, 08 Jul 2009) | 1 line
Fix recent regression in vc61().
........
r42255 | thebluegr | 2009-07-08 17:09:03 +1000 (Wed, 08 Jul 2009) | 1 line
Synced the MSVC project files of the gob engine
........
r42256 | thebluegr | 2009-07-08 17:11:43 +1000 (Wed, 08 Jul 2009) | 1 line
Updated the MSVC project files of the scummvm project (added graphics/sjis.*)
........
r42257 | thebluegr | 2009-07-08 17:13:56 +1000 (Wed, 08 Jul 2009) | 1 line
The ENABLE_* flags are only checked for *.cpp files in MSVC, so move the ENABLE_* checks to sjis.cpp to fix compilation under MSVC
........
r42258 | thebluegr | 2009-07-08 17:25:09 +1000 (Wed, 08 Jul 2009) | 1 line
Also added the ENABLE_IHNM and ENABLE_SAGA2 preprocessor definitions to the scummvm project files, not only the saga project files
........
r42259 | thebluegr | 2009-07-08 17:28:13 +1000 (Wed, 08 Jul 2009) | 1 line
Added guards to only include the Shorten audio code when the SAGA2 code in the SAGA engine is enabled
........
r42260 | thebluegr | 2009-07-08 20:25:37 +1000 (Wed, 08 Jul 2009) | 3 lines
Some cleanup for the script debugger code:
- Renamed struct DebugState to ScriptState and r_amp_rest to restAdjust inside EngineState. Changed restAdjust to be a uint16 (actually it is a uint16, but it was being casted back and forth from an unsigned integer, so this clears up its type and size)
- Moved the script state variables from inside the run_vm() into the ScriptState struct, so that they can be accessed by the console commands and the script debugger all the time, and removed the weird isValid code
........
r42261 | thebluegr | 2009-07-08 20:35:51 +1000 (Wed, 08 Jul 2009) | 1 line
Fixed saving/loading again (broken with the latest changes for game feature auto-detection)
........
r42262 | thebluegr | 2009-07-08 20:44:25 +1000 (Wed, 08 Jul 2009) | 1 line
Only the kernel needs to be initialized before anything else, when saving/loading
........
r42263 | thebluegr | 2009-07-08 23:08:51 +1000 (Wed, 08 Jul 2009) | 2 lines
- Moved printObject inside the Console class
- Enabled the parts where disassemble() is called
........
r42269 | athrxx | 2009-07-09 06:19:23 +1000 (Thu, 09 Jul 2009) | 1 line
LOL: fix long standing bugs in the battle system (hit chance, damage, etc) by adapting original style random number generator
........
r42270 | athrxx | 2009-07-09 06:32:34 +1000 (Thu, 09 Jul 2009) | 1 line
LOL: rename new function in last commit according to LordHoto's suggestion
........
r42271 | athrxx | 2009-07-09 07:12:03 +1000 (Thu, 09 Jul 2009) | 1 line
LOL: cleanup
........
svn-id: r42275
Diffstat (limited to 'engines')
-rw-r--r-- | engines/agos/vga_ww.cpp | 1 | ||||
-rw-r--r-- | engines/kyra/lol.cpp | 48 | ||||
-rw-r--r-- | engines/kyra/lol.h | 5 | ||||
-rw-r--r-- | engines/kyra/scene_lol.cpp | 4 | ||||
-rw-r--r-- | engines/kyra/script_lol.cpp | 19 | ||||
-rw-r--r-- | engines/kyra/sprites_lol.cpp | 8 | ||||
-rw-r--r-- | engines/kyra/timer_lol.cpp | 4 | ||||
-rw-r--r-- | engines/sci/console.cpp | 119 | ||||
-rw-r--r-- | engines/sci/console.h | 4 | ||||
-rw-r--r-- | engines/sci/debug.h | 20 | ||||
-rw-r--r-- | engines/sci/engine/game.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/kevent.cpp | 12 | ||||
-rw-r--r-- | engines/sci/engine/kmisc.cpp | 4 | ||||
-rw-r--r-- | engines/sci/engine/savegame.cpp | 14 | ||||
-rw-r--r-- | engines/sci/engine/scriptdebug.cpp | 97 | ||||
-rw-r--r-- | engines/sci/engine/state.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/state.h | 2 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 288 | ||||
-rw-r--r-- | engines/sci/engine/vm.h | 46 | ||||
-rw-r--r-- | engines/sci/sci.cpp | 8 |
20 files changed, 329 insertions, 378 deletions
diff --git a/engines/agos/vga_ww.cpp b/engines/agos/vga_ww.cpp index 97c31b299c..e7f2ad7807 100644 --- a/engines/agos/vga_ww.cpp +++ b/engines/agos/vga_ww.cpp @@ -149,6 +149,7 @@ void AGOSEngine::vc61() { if (a == 6) { src = _curVgaFile2 + 800; + dst = dstPtr; for (int i = 0; i < _screenHeight; i++) { memcpy(dst, src, _screenWidth); diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index 7c4b073f29..f2617dc8b4 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -214,8 +214,6 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy _compassBroken = _drainMagic = 0; _dialogueField = false; - _rndSpecial = 0x12349876; - _buttonData = 0; _activeButtons = 0; gui_resetButtonList(); @@ -1082,7 +1080,7 @@ bool LoLEngine::addCharacter(int id) { loadCharFaceShapes(numChars, id); - _characters[numChars].nextAnimUpdateCountdown = (int16) _rnd.getRandomNumberRng(1, 12) + 6; + _characters[numChars].nextAnimUpdateCountdown = rollDice(1, 12) + 6; for (i = 0; i < 11; i++) { if (_characters[numChars].items[i]) { @@ -1176,7 +1174,7 @@ void LoLEngine::updatePortraitSpeechAnim() { } } - int f = _rnd.getRandomNumberRng(1, 6) - 1; + int f = rollDice(1, 6) - 1; if (f == _characters[_updateCharNum].curFaceFrame) f++; if (f > 5) @@ -1404,24 +1402,24 @@ void LoLEngine::increaseExperience(int charNum, int skill, uint32 points) { switch (skill) { case 0: _txt->printMessage(0x8003, getLangString(0x4023), _characters[charNum].name); - inc = _rnd.getRandomNumberRng(4, 6); + inc = rollDice(4, 6); _characters[charNum].hitPointsCur += inc; _characters[charNum].hitPointsMax += inc; break; case 1: _txt->printMessage(0x8003, getLangString(0x4025), _characters[charNum].name); - inc = _rnd.getRandomNumberRng(2, 6); + inc = rollDice(2, 6); _characters[charNum].hitPointsCur += inc; _characters[charNum].hitPointsMax += inc; break; case 2: _txt->printMessage(0x8003, getLangString(0x4024), _characters[charNum].name); - inc = (_characters[charNum].defaultModifiers[6] * (_rnd.getRandomNumberRng(1, 8) + 17)) >> 8; + inc = (_characters[charNum].defaultModifiers[6] * (rollDice(1, 8) + 17)) >> 8; _characters[charNum].magicPointsCur += inc; _characters[charNum].magicPointsMax += inc; - inc = _rnd.getRandomNumberRng(1, 6); + inc = rollDice(1, 6); _characters[charNum].hitPointsCur += inc; _characters[charNum].hitPointsMax += inc; break; @@ -1874,6 +1872,24 @@ void LoLEngine::delay(uint32 millis, bool doUpdate, bool) { } } +int LoLEngine::rollDice(int times, int pips) { + if (times <= 0 || pips <= 0) + return 0; + + int res = 0; + int d = 0; + + do { + int val = (((int)_rnd.getRandomNumber(0x7fff) * pips) / 0x8000) + 1; + if (val > pips) + val -= pips; + res += val; + d++; + } while (d < times); + + return res; +} + void LoLEngine::updateEnvironmentalSfx(int soundId) { snd_processEnvironmentalSoundEffect(soundId, _currentBlock); } @@ -2260,7 +2276,7 @@ int LoLEngine::processMagicIce(int charNum, int spellLevel) { } else { uint16 o = _levelBlockProperties[calcNewBlockPosition(_currentBlock, _currentDirection)].assignedObjects; while (o & 0x8000) { - int might = _rnd.getRandomNumberRng(iceDamageMin[spellLevel], iceDamageMax[spellLevel]) + iceDamageAdd[spellLevel]; + int might = rollDice(iceDamageMin[spellLevel], iceDamageMax[spellLevel]) + iceDamageAdd[spellLevel]; int dmg = calcInflictableDamagePerItem(charNum, 0, might, 3, 2); MonsterInPlay *m = &_monsters[o & 0x7fff]; @@ -3192,7 +3208,7 @@ int LoLEngine::battleHitSkillTest(int16 attacker, int16 target, int skill) { evadeChanceModifier = _characters[target].defaultModifiers[3]; } - int r = _rnd.getRandomNumberRng(1, 100); + int r = rollDice(1, 100); if (r >= sk) return 2; @@ -3230,9 +3246,9 @@ int LoLEngine::inflictDamage(uint16 target, int damage, uint16 attacker, int ski m->hitPoints -= damage; m->damageReceived = 0x8000 | damage; m->flags |= 0x10; - m->hitOffsX = _rnd.getRandomNumberRng(1, 24); + m->hitOffsX = rollDice(1, 24); m->hitOffsX -= 12; - m->hitOffsY = _rnd.getRandomNumberRng(1, 24); + m->hitOffsY = rollDice(1, 24); m->hitOffsY -= 12; m->hitPoints = CLIP<int16>(m->hitPoints, 0, m->properties->hitPoints); @@ -3436,7 +3452,7 @@ void LoLEngine::checkForPartyDeath() { } void LoLEngine::applyMonsterAttackSkill(MonsterInPlay *monster, int16 target, int16 damage) { - if (_rnd.getRandomNumberRng(1, 100) > monster->properties->attackSkillChance) + if (rollDice(1, 100) > monster->properties->attackSkillChance) return; int t = 0; @@ -3506,7 +3522,7 @@ void LoLEngine::applyMonsterAttackSkill(MonsterInPlay *monster, int16 target, in } void LoLEngine::applyMonsterDefenseSkill(MonsterInPlay *monster, int16 attacker, int flags, int skill, int damage) { - if (_rnd.getRandomNumberRng(1, 100) > monster->properties->defenseSkillChance) + if (rollDice(1, 100) > monster->properties->defenseSkillChance) return; int itm = 0; @@ -3593,7 +3609,7 @@ int LoLEngine::paralyzePoisonCharacter(int charNum, int typeFlag, int immunityFl if (!(_characters[charNum].flags & 1) || (_characters[charNum].flags & immunityFlags)) return 0; - if ((int)_rnd.getRandomNumberRng(1, 100) > hitChance) + if (rollDice(1, 100) > hitChance) return 0; int r = 0; @@ -3711,7 +3727,7 @@ void LoLEngine::launchMagicViper() { _screen->copyPage(12, 0); _screen->copyPage(12, 2); - int t = _rnd.getRandomNumberRng(1, 4); + int t = rollDice(1, 4); for (int i = 0; i < 4; i++) { if (!(_characters[i].flags & 1)) { diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index 12000c31fa..f4ac597b5c 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -642,6 +642,7 @@ private: int olol_setWallType(EMCState *script); int olol_getWallType(EMCState *script); int olol_drawScene(EMCState *script); + int olol_rollDice(EMCState *script); int olol_moveParty(EMCState *script); int olol_delay(EMCState *script); int olol_setGameFlag(EMCState *script); @@ -1313,6 +1314,7 @@ private: // misc void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false); + int rollDice(int times, int pips); uint8 _compassBroken; uint8 _drainMagic; @@ -1320,8 +1322,7 @@ private: uint8 *_pageBuffer1; uint8 *_pageBuffer2; - uint32 _rndSpecial; - + // spells typedef Common::Functor1Mem<ActiveSpell*, int, LoLEngine> SpellProc; Common::Array<const SpellProc*> _spellProcs; diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp index 945495517f..32ee7a4d77 100644 --- a/engines/kyra/scene_lol.cpp +++ b/engines/kyra/scene_lol.cpp @@ -552,14 +552,14 @@ void LoLEngine::updateLampStatus() { if (_lampEffect == -1) { if (_screen->_fadeFlag == 0) setPaletteBrightness(_screen->getPalette(0), _brightness, newLampEffect); - _lampStatusTimer = _system->getMillis() + (10 + _rnd.getRandomNumberRng(1, 30)) * _tickLength; + _lampStatusTimer = _system->getMillis() + (10 + rollDice(1, 30)) * _tickLength; } else { if ((_lampEffect & 0xfe) == (newLampEffect & 0xfe)) { if (_system->getMillis() <= _lampStatusTimer) { newLampEffect = _lampEffect; } else { newLampEffect = _lampEffect ^ 1; - _lampStatusTimer = _system->getMillis() + (10 + _rnd.getRandomNumberRng(1, 30)) * _tickLength; + _lampStatusTimer = _system->getMillis() + (10 + rollDice(1, 30)) * _tickLength; } } else { if (_screen->_fadeFlag == 0) diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp index a606419722..611ad8f9ef 100644 --- a/engines/kyra/script_lol.cpp +++ b/engines/kyra/script_lol.cpp @@ -135,6 +135,11 @@ int LoLEngine::olol_drawScene(EMCState *script) { return 1; } +int LoLEngine::olol_rollDice(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_rollDice(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + return rollDice(stackPos(0), stackPos(1)); +} + int LoLEngine::olol_moveParty(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_moveParty(%p) (%d)", (const void *)script, stackPos(0)); int mode = stackPos(0); @@ -831,10 +836,10 @@ int LoLEngine::olol_initMonster(EMCState *script) { l->hitPoints = (l->properties->hitPoints * _monsterModifiers[_monsterDifficulty]) >> 8; if (_currentLevel == 12 && l->type == 2) - l->hitPoints = (l->hitPoints * (_rnd.getRandomNumberRng(1, 128) + 192)) >> 8; + l->hitPoints = (l->hitPoints * (rollDice(1, 128) + 192)) >> 8; l->numDistAttacks = l->properties->numDistAttacks; - l->distAttackTick = _rnd.getRandomNumberRng(1, calcMonsterSkillLevel(l->id | 0x8000, 8)) - 1; + l->distAttackTick = rollDice(1, calcMonsterSkillLevel(l->id | 0x8000, 8)) - 1; l->flyingHeight = 2; l->flags = stackPos(5); l->assignedItems = 0; @@ -1366,18 +1371,18 @@ int LoLEngine::olol_characterSkillTest(EMCState *script){ debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_characterSkillTest(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); int skill = stackPos(0); int n = countActiveCharacters(); - uint m = 0; + int m = 0; int c = 0; for (int i = 0; i < n ; i++) { - uint v = _characters[i].skillModifiers[skill] + _characters[i].skillLevels[skill] + 25; + int v = _characters[i].skillModifiers[skill] + _characters[i].skillLevels[skill] + 25; if (v > m) { m = v; c = i; } } - return (_rnd.getRandomNumberRng(1, 100) > m) ? -1 : c; + return (rollDice(1, 100) > m) ? -1 : c; } int LoLEngine::olol_countAllMonsters(EMCState *script){ @@ -1440,7 +1445,7 @@ int LoLEngine::olol_calcInflictableDamage(EMCState *script) { int LoLEngine::olol_getInflictedDamage(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getInflictedDamage(%p) (%d)", (const void *)script, stackPos(0)); int mx = stackPos(0); - return mx ? _rnd.getRandomNumberRng(2, mx) : 0; + return rollDice(2, mx); } int LoLEngine::olol_checkForCertainPartyMember(EMCState *script) { @@ -2617,7 +2622,7 @@ void LoLEngine::setupOpcodeTable() { Opcode(olol_setWallType); Opcode(olol_getWallType); Opcode(olol_drawScene); - Opcode(o1_getRand); + Opcode(olol_rollDice); // 0x04 Opcode(olol_moveParty); diff --git a/engines/kyra/sprites_lol.cpp b/engines/kyra/sprites_lol.cpp index 8cee1dc5fc..f644feeb65 100644 --- a/engines/kyra/sprites_lol.cpp +++ b/engines/kyra/sprites_lol.cpp @@ -1071,7 +1071,7 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) { monster->speedTick = 0; if (monster->properties->flags & 0x40) { - monster->hitPoints += _rnd.getRandomNumberRng(1, 8); + monster->hitPoints += rollDice(1, 8); if (monster->hitPoints > monster->properties->hitPoints) monster->hitPoints = monster->properties->hitPoints; } @@ -1264,7 +1264,7 @@ bool LoLEngine::chasePartyWithDistanceAttacks(MonsterInPlay *monster) { int s = 0; if (monster->flags & 0x10) { - s = monster->properties->numDistWeapons ? _rnd.getRandomNumberRng(1, monster->properties->numDistWeapons) : 0; + s = monster->properties->numDistWeapons ? rollDice(1, monster->properties->numDistWeapons) : 0; } else { s = monster->curDistWeapon++; if (monster->curDistWeapon >= monster->properties->numDistWeapons) @@ -1344,7 +1344,7 @@ void LoLEngine::chasePartyWithCloseAttacks(MonsterInPlay *monster) { if (hit) { int mx = calcInflictableDamage(m, dst, hit); - int dmg = mx ? _rnd.getRandomNumberRng(2, mx) : 0; + int dmg = rollDice(2, mx ); inflictDamage(dst, dmg, m, 0, 0); applyMonsterAttackSkill(monster, dst, dmg); } @@ -1364,7 +1364,7 @@ void LoLEngine::chasePartyWithCloseAttacks(MonsterInPlay *monster) { walkMonster(monster); } else { setMonsterDirection(monster, monster->destDirection); - setMonsterMode(monster, (_rnd.getRandomNumberRng(1, 100) <= 50) ? 4 : 3); + setMonsterMode(monster, (rollDice(1, 100) <= 50) ? 4 : 3); } } diff --git a/engines/kyra/timer_lol.cpp b/engines/kyra/timer_lol.cpp index 84c4f8b19d..0e43487217 100644 --- a/engines/kyra/timer_lol.cpp +++ b/engines/kyra/timer_lol.cpp @@ -147,7 +147,7 @@ void LoLEngine::timerSpecialCharacterUpdate(int timerNum) { break; case 3: - v = _rnd.getRandomNumberRng(1, 2); + v = rollDice(1, 2); if (inflictDamage(i, v, 0x8000, 0, 0x80)) { _txt->printMessage(2, getLangString(0x4022), _characters[i].name); _characters[i].characterUpdateDelay[ii] = 10; @@ -241,7 +241,7 @@ void LoLEngine::timerUpdatePortraitAnimations(int skipUpdate) { } else { _characters[i].curFaceFrame = 0; gui_drawCharPortraitWithStats(i); - _characters[i].nextAnimUpdateCountdown = (int16) _rnd.getRandomNumberRng(1, 12) + 6; + _characters[i].nextAnimUpdateCountdown = rollDice(1, 12) + 6; } } } diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 2d11f39835..7f20e4013d 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -190,11 +190,10 @@ Console::Console(SciEngine *vm) : GUI::Debugger() { "Dirty frames management\n"); */ - debugState.isValid = false; - debugState.seeking = kDebugSeekNothing; - debugState.seekLevel = 0; - debugState.runningStep = 0; - debugState.stopOnEvent = false; + scriptState.seeking = kDebugSeekNothing; + scriptState.seekLevel = 0; + scriptState.runningStep = 0; + scriptState.stopOnEvent = false; } Console::~Console() { @@ -546,13 +545,13 @@ bool Console::cmdSetParseNodes(int argc, const char **argv) { bool Console::cmdRegisters(int argc, const char **argv) { DebugPrintf("Current register values:\n"); - DebugPrintf("acc=%04x:%04x prev=%04x:%04x &rest=%x\n", PRINT_REG(_vm->_gamestate->r_acc), PRINT_REG(_vm->_gamestate->r_prev), *debugState.p_restadjust); + DebugPrintf("acc=%04x:%04x prev=%04x:%04x &rest=%x\n", PRINT_REG(_vm->_gamestate->r_acc), PRINT_REG(_vm->_gamestate->r_prev), scriptState.restadjust); if (!_vm->_gamestate->_executionStack.empty()) { EngineState *s = _vm->_gamestate; // for PRINT_STK DebugPrintf("pc=%04x:%04x obj=%04x:%04x fp=ST:%04x sp=ST:%04x\n", - PRINT_REG(*debugState.p_pc), PRINT_REG(*debugState.p_objp), - PRINT_STK(*debugState.p_pp), PRINT_STK(*debugState.p_sp)); + PRINT_REG(scriptState.xs->addr.pc), PRINT_REG(scriptState.xs->objp), + PRINT_STK(scriptState.xs->fp), PRINT_STK(scriptState.xs->sp)); } else DebugPrintf("<no execution stack: pc,obj,fp omitted>\n"); @@ -846,7 +845,6 @@ bool Console::cmdRestoreGame(int argc, const char **argv) { _vm->_gamestate->successor = newstate; // Set successor script_abort_flag = 2; // Abort current game with replay - debugState.isValid = false; shrink_execution_stack(_vm->_gamestate, _vm->_gamestate->execution_stack_base + 1); return 0; @@ -877,7 +875,6 @@ bool Console::cmdRestartGame(int argc, const char **argv) { _vm->_gamestate->restarting_flags |= SCI_GAME_IS_RESTARTING_NOW; script_abort_flag = 1; - debugState.isValid = false; return false; } @@ -1705,9 +1702,9 @@ bool Console::cmdVMVarlist(int argc, const char **argv) { DebugPrintf("Addresses of variables in the VM:\n"); for (int i = 0; i < 4; i++) { - DebugPrintf("%s vars at %04x:%04x ", varnames[i], PRINT_REG(make_reg(debugState.p_var_segs[i], debugState.p_vars[i] - debugState.p_var_base[i]))); - if (debugState.p_var_max) - DebugPrintf(" total %d", debugState.p_var_max[i]); + DebugPrintf("%s vars at %04x:%04x ", varnames[i], PRINT_REG(make_reg(scriptState.variables_seg[i], scriptState.variables[i] - scriptState.variables_base[i]))); + if (scriptState.variables_max) + DebugPrintf(" total %d", scriptState.variables_max[i]); DebugPrintf("\n"); } @@ -1743,17 +1740,17 @@ bool Console::cmdVMVars(int argc, const char **argv) { return true; } - if ((debugState.p_var_max) && (debugState.p_var_max[vartype] <= idx)) { - DebugPrintf("Max. index is %d (0x%x)\n", debugState.p_var_max[vartype], debugState.p_var_max[vartype]); + if ((scriptState.variables_max) && (scriptState.variables_max[vartype] <= idx)) { + DebugPrintf("Max. index is %d (0x%x)\n", scriptState.variables_max[vartype], scriptState.variables_max[vartype]); return true; } switch (argc) { case 2: - DebugPrintf("%s var %d == %04x:%04x\n", varnames[vartype], idx, PRINT_REG(debugState.p_vars[vartype][idx])); + DebugPrintf("%s var %d == %04x:%04x\n", varnames[vartype], idx, PRINT_REG(scriptState.variables[vartype][idx])); break; case 3: - if (parse_reg_t(_vm->_gamestate, argv[3], &debugState.p_vars[vartype][idx])) { + if (parse_reg_t(_vm->_gamestate, argv[3], &scriptState.variables[vartype][idx])) { DebugPrintf("Invalid address passed.\n"); DebugPrintf("Check the \"addresses\" command on how to use addresses\n"); return true; @@ -1930,7 +1927,7 @@ bool Console::cmdViewReference(int argc, const char **argv) { break; case KSIG_OBJECT: DebugPrintf("object\n"); - printObject(_vm->_gamestate, reg); + printObject(reg); break; case KSIG_REF: { int size; @@ -1985,21 +1982,21 @@ bool Console::cmdViewObject(int argc, const char **argv) { } DebugPrintf("Information on the object at the given address:\n"); - printObject(_vm->_gamestate, addr); + printObject(addr); return true; } bool Console::cmdViewActiveObject(int argc, const char **argv) { DebugPrintf("Information on the currently active object or class:\n"); - printObject(_vm->_gamestate, *debugState.p_objp); + printObject(scriptState.xs->objp); return true; } bool Console::cmdViewAccumulatorObject(int argc, const char **argv) { DebugPrintf("Information on the currently active object or class at the address indexed by the accumulator:\n"); - printObject(_vm->_gamestate, _vm->_gamestate->r_acc); + printObject(_vm->_gamestate->r_acc); return true; } @@ -2099,24 +2096,21 @@ bool Console::cmdBacktrace(int argc, const char **argv) { } bool Console::cmdStep(int argc, const char **argv) { - debugState.isValid = false; if (argc == 2 && atoi(argv[1]) > 0) - debugState.runningStep = atoi(argv[1]) - 1; + scriptState.runningStep = atoi(argv[1]) - 1; return true; } bool Console::cmdStepEvent(int argc, const char **argv) { - debugState.stopOnEvent = true; - debugState.isValid = false; + scriptState.stopOnEvent = true; return true; } bool Console::cmdStepRet(int argc, const char **argv) { - debugState.seeking = kDebugSeekLevelRet; - debugState.seekLevel = _vm->_gamestate->_executionStack.size() - 1; - debugState.isValid = false; + scriptState.seeking = kDebugSeekLevelRet; + scriptState.seekLevel = _vm->_gamestate->_executionStack.size() - 1; return true; } @@ -2128,9 +2122,8 @@ bool Console::cmdStepGlobal(int argc, const char **argv) { return true; } - debugState.seeking = kDebugSeekGlobal; - debugState.seekSpecial = atoi(argv[1]); - debugState.isValid = false; + scriptState.seeking = kDebugSeekGlobal; + scriptState.seekSpecial = atoi(argv[1]); return true; } @@ -2158,12 +2151,10 @@ bool Console::cmdStepCallk(int argc, const char **argv) { } } - debugState.seeking = kDebugSeekSpecialCallk; - debugState.seekSpecial = callk_index; - debugState.isValid = false; + scriptState.seeking = kDebugSeekSpecialCallk; + scriptState.seekSpecial = callk_index; } else { - debugState.seeking = kDebugSeekCallk; - debugState.isValid = false; + scriptState.seeking = kDebugSeekCallk; } return true; @@ -2204,8 +2195,7 @@ bool Console::cmdDissassemble(int argc, const char **argv) { } do { - // TODO - //addr = disassemble(_vm->_gamestate, addr, 0, 0); + addr = disassemble(_vm->_gamestate, addr, 0, 0); } while (addr.offset > 0); return true; @@ -2256,9 +2246,7 @@ bool Console::cmdDissassembleAddress(int argc, const char **argv) { } do { - // TODO - //vpc = disassemble(_vm->_gamestate, vpc, do_bwc, do_bytes); - + vpc = disassemble(_vm->_gamestate, vpc, do_bwc, do_bytes); } while ((vpc.offset > 0) && (vpc.offset + 6 < size) && (--op_count)); return true; @@ -2339,8 +2327,7 @@ bool Console::cmdSend(int argc, const char **argv) { } bool Console::cmdGo(int argc, const char **argv) { - debugState.seeking = kDebugSeekNothing; - debugState.isValid = false; + scriptState.seeking = kDebugSeekNothing; return true; } @@ -2754,9 +2741,8 @@ bool Console::cmdExit(int argc, const char **argv) { if (!scumm_stricmp(argv[1], "game")) { // Quit gracefully script_abort_flag = 1; // Terminate VM - debugState.isValid = false; - debugState.seeking = kDebugSeekNothing; - debugState.runningStep = 0; + scriptState.seeking = kDebugSeekNothing; + scriptState.runningStep = 0; } else if (!scumm_stricmp(argv[1], "now")) { // Quit ungracefully @@ -3040,47 +3026,47 @@ int Console::printNode(reg_t addr) { return 0; } -int printObject(EngineState *s, reg_t pos) { +int Console::printObject(reg_t pos) { + EngineState *s = _vm->_gamestate; // for the several defines in this function Object *obj = obj_get(s, pos); Object *var_container = obj; int i; - Console *con = ((SciEngine *)g_engine)->getSciDebugger(); if (!obj) { - con->DebugPrintf("[%04x:%04x]: Not an object.", PRINT_REG(pos)); + DebugPrintf("[%04x:%04x]: Not an object.", PRINT_REG(pos)); return 1; } // Object header - printf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(pos), obj_get_name(s, pos), + DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(pos), obj_get_name(s, pos), obj->_variables.size(), obj->methods_nr); if (!(obj->_variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS)) var_container = obj_get(s, obj->_variables[SCRIPT_SUPERCLASS_SELECTOR]); - printf(" -- member variables:\n"); + DebugPrintf(" -- member variables:\n"); for (i = 0; (uint)i < obj->_variables.size(); i++) { printf(" "); if (i < var_container->variable_names_nr) { - printf("[%03x] %s = ", VM_OBJECT_GET_VARSELECTOR(var_container, i), selector_name(s, VM_OBJECT_GET_VARSELECTOR(var_container, i))); + DebugPrintf("[%03x] %s = ", VM_OBJECT_GET_VARSELECTOR(var_container, i), selector_name(s, VM_OBJECT_GET_VARSELECTOR(var_container, i))); } else - printf("p#%x = ", i); + DebugPrintf("p#%x = ", i); reg_t val = obj->_variables[i]; - printf("%04x:%04x", PRINT_REG(val)); + DebugPrintf("%04x:%04x", PRINT_REG(val)); Object *ref = obj_get(s, val); if (ref) - printf(" (%s)", obj_get_name(s, val)); + DebugPrintf(" (%s)", obj_get_name(s, val)); - printf("\n"); + DebugPrintf("\n"); } - printf(" -- methods:\n"); + DebugPrintf(" -- methods:\n"); for (i = 0; i < obj->methods_nr; i++) { reg_t fptr = VM_OBJECT_READ_FUNCTION(obj, i); - printf(" [%03x] %s = %04x:%04x\n", VM_OBJECT_GET_FUNCSELECTOR(obj, i), selector_name(s, VM_OBJECT_GET_FUNCSELECTOR(obj, i)), PRINT_REG(fptr)); + DebugPrintf(" [%03x] %s = %04x:%04x\n", VM_OBJECT_GET_FUNCSELECTOR(obj, i), selector_name(s, VM_OBJECT_GET_FUNCSELECTOR(obj, i)), PRINT_REG(fptr)); } if (s->seg_manager->_heap[pos.segment]->getType() == MEM_OBJ_SCRIPT) - printf("\nOwner script:\t%d\n", s->seg_manager->getScript(pos.segment)->nr); + DebugPrintf("\nOwner script:\t%d\n", s->seg_manager->getScript(pos.segment)->nr); return 0; } @@ -3245,34 +3231,33 @@ int c_stepover(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { return 1; } - debugState.isValid = false; opcode = s->_heap[*p_pc]; opnumber = opcode >> 1; if (opnumber == 0x22 /* callb */ || opnumber == 0x23 /* calle */ || opnumber == 0x25 /* send */ || opnumber == 0x2a /* self */ || opnumber == 0x2b /* super */) { - debugState.seeking = kDebugSeekSO; - debugState.seekLevel = s->_executionStack.size()-1; - // Store in debugState.seekSpecial the offset of the next command after send + scriptState.seeking = kDebugSeekSO; + scriptState.seekLevel = s->_executionStack.size()-1; + // Store in scriptState.seekSpecial the offset of the next command after send switch (opcode) { case 0x46: // calle W - debugState.seekSpecial = *p_pc + 5; + scriptState.seekSpecial = *p_pc + 5; break; case 0x44: // callb W case 0x47: // calle B case 0x56: // super W - debugState.seekSpecial = *p_pc + 4; + scriptState.seekSpecial = *p_pc + 4; break; case 0x45: // callb B case 0x57: // super B case 0x4A: // send W case 0x54: // self W - debugState.seekSpecial = *p_pc + 3; + scriptState.seekSpecial = *p_pc + 3; break; default: - debugState.seekSpecial = *p_pc + 2; + scriptState.seekSpecial = *p_pc + 2; } } diff --git a/engines/sci/console.h b/engines/sci/console.h index bc07ddb530..8d1299dd1e 100644 --- a/engines/sci/console.h +++ b/engines/sci/console.h @@ -37,7 +37,7 @@ struct List; // Refer to the "addresses" command on how to pass address parameters int parse_reg_t(EngineState *s, const char *str, reg_t *dest); -int printObject(EngineState *s, reg_t pos); +reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecode); class Console : public GUI::Debugger { public: @@ -46,6 +46,8 @@ public: void preEnter(); void postEnter(); + int printObject(reg_t pos); + private: // General bool cmdHelp(int argc, const char **argv); diff --git a/engines/sci/debug.h b/engines/sci/debug.h index fbd98e0d6f..ccf0602600 100644 --- a/engines/sci/debug.h +++ b/engines/sci/debug.h @@ -37,8 +37,7 @@ enum DebugSeeking { kDebugSeekGlobal = 5 // Step forward until one specified global variable is modified }; -struct DebugState { - bool isValid; +struct ScriptState { bool stopOnEvent; DebugSeeking seeking; // Stepping forward until some special condition is met int runningStep; // Set to > 0 to allow multiple stepping @@ -46,15 +45,12 @@ struct DebugState { int seekSpecial; // Used for special seeks int old_pc_offset; StackPtr old_sp; - reg_t *p_pc; - StackPtr *p_sp; - StackPtr *p_pp; - reg_t *p_objp; - int *p_restadjust; - SegmentId *p_var_segs; - reg_t **p_vars; - reg_t **p_var_base; - int *p_var_max; // May be NULL even in valid state! + ExecStack *xs; + uint16 restadjust; + reg_t *variables[4]; // global, local, temp, param, as immediate pointers + reg_t *variables_base[4]; // Used for referencing VM ops + SegmentId variables_seg[4]; // Same as above, contains segment IDs + int variables_max[4]; // Max. values for all variables }; // Various global variables used for debugging are declared here @@ -62,7 +58,7 @@ extern int g_debug_sleeptime_factor; extern int g_debug_simulated_key; extern bool g_debug_track_mouse_clicks; extern bool g_debug_weak_validations; -extern DebugState debugState; +extern ScriptState scriptState; } // End of namespace Sci diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp index 861294cfa6..5b4c30f6b3 100644 --- a/engines/sci/engine/game.cpp +++ b/engines/sci/engine/game.cpp @@ -365,7 +365,7 @@ int script_init_engine(EngineState *s) { s->r_acc = s->r_prev = NULL_REG; - s->r_amp_rest = 0; + s->restAdjust = 0; s->_executionStack.clear(); // Start without any execution stack s->execution_stack_base = -1; // No vm is running yet diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp index 744a965ef3..c4b3f5d71a 100644 --- a/engines/sci/engine/kevent.cpp +++ b/engines/sci/engine/kevent.cpp @@ -88,12 +88,12 @@ reg_t kGetEvent(EngineState *s, int funct_nr, int argc, reg_t *argv) { case SCI_EVT_KEYBOARD: if ((e.buckybits & SCI_EVM_LSHIFT) && (e.buckybits & SCI_EVM_RSHIFT) && (e.data == '-')) { printf("Debug mode activated\n"); - debugState.seeking = kDebugSeekNothing; - debugState.runningStep = 0; + scriptState.seeking = kDebugSeekNothing; + scriptState.runningStep = 0; } else if ((e.buckybits & SCI_EVM_CTRL) && (e.data == '`')) { printf("Debug mode activated\n"); - debugState.seeking = kDebugSeekNothing; - debugState.runningStep = 0; + scriptState.seeking = kDebugSeekNothing; + scriptState.runningStep = 0; } else { PUT_SEL32V(obj, type, SCI_EVT_KEYBOARD); // Keyboard event s->r_acc = make_reg(0, 1); @@ -137,8 +137,8 @@ reg_t kGetEvent(EngineState *s, int funct_nr, int argc, reg_t *argv) { s->r_acc = NULL_REG; // Unknown or no event } - if ((s->r_acc.offset) && (debugState.stopOnEvent)) { - debugState.stopOnEvent = false; + if ((s->r_acc.offset) && (scriptState.stopOnEvent)) { + scriptState.stopOnEvent = false; // A SCI event occured, and we have been asked to stop, so open the debug console Console *con = ((Sci::SciEngine*)g_engine)->getSciDebugger(); diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index 8381bc2e13..7e0aca5b7a 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -96,8 +96,8 @@ reg_t kFlushResources(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t kSetDebug(EngineState *s, int funct_nr, int argc, reg_t *argv) { printf("Debug mode activated\n"); - debugState.seeking = kDebugSeekNothing; - debugState.runningStep = 0; + scriptState.seeking = kDebugSeekNothing; + scriptState.runningStep = 0; return s->r_acc; } diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index f44af2b1cd..e167e7eca8 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -756,6 +756,13 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { // FIXME: Do in-place loading at some point, instead of creating a new EngineState instance from scratch. retval = new EngineState(s->resmgr, s->_version, s->_flags); + // static VM/Kernel information: + assert(0 == retval->_kernel); + retval->_kernel = s->_kernel; // needs to be initialized before _reset_graphics_input is called +// s->_kernel = 0; // FIXME: We should set s->_kernel to 0 here, +// else it could be freed when the old EngineState is freed. Luckily, this freeing currently +// never happens, so we don't need to. + // Copy some old data retval->gfx_state = s->gfx_state; retval->sound_mute = s->sound_mute; @@ -822,13 +829,6 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { retval->parser_base = make_reg(s->sys_strings_segment, SYS_STRING_PARSER_BASE); - // static VM/Kernel information: - assert(0 == retval->_kernel); - retval->_kernel = s->_kernel; -// s->_kernel = 0; // FIXME: We should set s->_kernel to 0 here, -// else it could be freed when the old EngineState is freed. Luckily, this freeing currently -// never happens, so we don't need to. - // Copy breakpoint information from current game instance retval->have_bp = s->have_bp; retval->bp_list = s->bp_list; diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index d5f0a21385..9f69d21e2a 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -34,7 +34,7 @@ namespace Sci { extern const char *selector_name(EngineState *s, int selector); -DebugState debugState; +ScriptState scriptState; int propertyOffsetToId(EngineState *s, int prop_ofs, reg_t objp) { Object *obj = obj_get(s, objp); @@ -97,11 +97,6 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod opsize = scr[pos.offset]; opcode = opsize >> 1; - if (!debugState.isValid) { - warning("Not in debug state"); - return retval; - } - opsize &= 1; // byte if true, word if false printf("%04x:%04x: ", PRINT_REG(pos)); @@ -226,11 +221,11 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod } } - if (pos == *debugState.p_pc) { // Extra information if debugging the current opcode + if (pos == scriptState.xs->addr.pc) { // Extra information if debugging the current opcode if ((opcode == op_pTos) || (opcode == op_sTop) || (opcode == op_pToa) || (opcode == op_aTop) || (opcode == op_dpToa) || (opcode == op_ipToa) || (opcode == op_dpTos) || (opcode == op_ipTos)) { int prop_ofs = scr[pos.offset + 1]; - int prop_id = propertyOffsetToId(s, prop_ofs, *debugState.p_objp); + int prop_id = propertyOffsetToId(s, prop_ofs, scriptState.xs->objp); printf(" (%s)", selector_name(s, prop_id)); } @@ -238,38 +233,38 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod printf("\n"); - if (pos == *debugState.p_pc) { // Extra information if debugging the current opcode + if (pos == scriptState.xs->addr.pc) { // Extra information if debugging the current opcode if (opcode == op_callk) { - int stackframe = (scr[pos.offset + 2] >> 1) + (*debugState.p_restadjust); - int argc = ((*debugState.p_sp)[- stackframe - 1]).offset; + int stackframe = (scr[pos.offset + 2] >> 1) + (scriptState.restadjust); + int argc = ((scriptState.xs->sp)[- stackframe - 1]).offset; if (!s->_kernel->hasOldScriptHeader()) - argc += (*debugState.p_restadjust); + argc += (scriptState.restadjust); printf(" Kernel params: ("); for (int j = 0; j < argc; j++) { - printf("%04x:%04x", PRINT_REG((*debugState.p_sp)[j - stackframe])); + printf("%04x:%04x", PRINT_REG((scriptState.xs->sp)[j - stackframe])); if (j + 1 < argc) printf(", "); } printf(")\n"); } else if ((opcode == op_send) || (opcode == op_self)) { - int restmod = *debugState.p_restadjust; + int restmod = scriptState.restadjust; int stackframe = (scr[pos.offset + 1] >> 1) + restmod; - reg_t *sb = *debugState.p_sp; + reg_t *sb = scriptState.xs->sp; uint16 selector; reg_t fun_ref; while (stackframe > 0) { int argc = sb[- stackframe + 1].offset; const char *name = NULL; - reg_t called_obj_addr = *debugState.p_objp; + reg_t called_obj_addr = scriptState.xs->objp; if (opcode == op_send) called_obj_addr = s->r_acc; else if (opcode == op_self) - called_obj_addr = *debugState.p_objp; + called_obj_addr = scriptState.xs->objp; selector = sb[- stackframe].offset; @@ -313,45 +308,30 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod } -void script_debug(EngineState *s, reg_t *pc, StackPtr *sp, StackPtr *pp, reg_t *objp, int *restadjust, - SegmentId *segids, reg_t **variables, reg_t **variables_base, int *variables_nr, int bp) { +void script_debug(EngineState *s, bool bp) { // Do we support a separate console? - bool old_debugstate = debugState.isValid; - - debugState.p_var_segs = segids; - debugState.p_vars = variables; - debugState.p_var_max = variables_nr; - debugState.p_var_base = variables_base; - debugState.p_pc = pc; - debugState.p_sp = sp; - debugState.p_pp = pp; - debugState.p_objp = objp; - debugState.p_restadjust = restadjust; printf("%d: acc=%04x:%04x ", script_step_counter, PRINT_REG(s->r_acc)); - debugState.isValid = true; - disassemble(s, *pc, 0, 1); - if (debugState.seeking == kDebugSeekGlobal) - printf("Global %d (0x%x) = %04x:%04x\n", debugState.seekSpecial, - debugState.seekSpecial, PRINT_REG(s->script_000->locals_block->_locals[debugState.seekSpecial])); - - debugState.isValid = old_debugstate; + disassemble(s, scriptState.xs->addr.pc, 0, 1); + if (scriptState.seeking == kDebugSeekGlobal) + printf("Global %d (0x%x) = %04x:%04x\n", scriptState.seekSpecial, + scriptState.seekSpecial, PRINT_REG(s->script_000->locals_block->_locals[scriptState.seekSpecial])); - if (debugState.seeking && !bp) { // Are we looking for something special? - MemObject *mobj = GET_SEGMENT(*s->seg_manager, pc->segment, MEM_OBJ_SCRIPT); + if (scriptState.seeking && !bp) { // Are we looking for something special? + MemObject *mobj = GET_SEGMENT(*s->seg_manager, scriptState.xs->addr.pc.segment, MEM_OBJ_SCRIPT); if (mobj) { Script *scr = (Script *)mobj; byte *code_buf = scr->buf; int code_buf_size = scr->buf_size; - int opcode = pc->offset >= code_buf_size ? 0 : code_buf[pc->offset]; + int opcode = scriptState.xs->addr.pc.offset >= code_buf_size ? 0 : code_buf[scriptState.xs->addr.pc.offset]; int op = opcode >> 1; - int paramb1 = pc->offset + 1 >= code_buf_size ? 0 : code_buf[pc->offset + 1]; - int paramf1 = (opcode & 1) ? paramb1 : (pc->offset + 2 >= code_buf_size ? 0 : (int16)READ_LE_UINT16(code_buf + pc->offset + 1)); + int paramb1 = scriptState.xs->addr.pc.offset + 1 >= code_buf_size ? 0 : code_buf[scriptState.xs->addr.pc.offset + 1]; + int paramf1 = (opcode & 1) ? paramb1 : (scriptState.xs->addr.pc.offset + 2 >= code_buf_size ? 0 : (int16)READ_LE_UINT16(code_buf + scriptState.xs->addr.pc.offset + 1)); - switch (debugState.seeking) { + switch (scriptState.seeking) { case kDebugSeekSpecialCallk: - if (paramb1 != debugState.seekSpecial) + if (paramb1 != scriptState.seekSpecial) return; case kDebugSeekCallk: { @@ -361,7 +341,7 @@ void script_debug(EngineState *s, reg_t *pc, StackPtr *sp, StackPtr *pp, reg_t * } case kDebugSeekLevelRet: { - if ((op != op_ret) || (debugState.seekLevel < (int)s->_executionStack.size()-1)) + if ((op != op_ret) || (scriptState.seekLevel < (int)s->_executionStack.size()-1)) return; break; } @@ -373,7 +353,7 @@ void script_debug(EngineState *s, reg_t *pc, StackPtr *sp, StackPtr *pp, reg_t * return; // param or temp if ((op & 0x3) && s->_executionStack.back().local_segment > 0) return; // locals and not running in script.000 - if (paramf1 != debugState.seekSpecial) + if (paramf1 != scriptState.seekSpecial) return; // CORRECT global? break; @@ -382,32 +362,17 @@ void script_debug(EngineState *s, reg_t *pc, StackPtr *sp, StackPtr *pp, reg_t * break; case kDebugSeekNothing: - // FIXME: Unhandled? + // We seek nothing, so just continue break; } - debugState.seeking = kDebugSeekNothing; + scriptState.seeking = kDebugSeekNothing; // OK, found whatever we were looking for } } - - debugState.isValid = (debugState.runningStep == 0); - - if (debugState.isValid) { - debugState.p_pc = pc; - debugState.p_sp = sp; - debugState.p_pp = pp; - debugState.p_objp = objp; - debugState.p_restadjust = restadjust; - debugState.p_var_segs = segids; - debugState.p_vars = variables; - debugState.p_var_max = variables_nr; - debugState.p_var_base = variables_base; - - printf("Step #%d\n", script_step_counter); - disassemble(s, *pc, 0, 1); - } - + + printf("Step #%d\n", script_step_counter); + disassemble(s, scriptState.xs->addr.pc, 0, 1); } } // End of namespace Sci diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index e618077d54..c43fe9b6de 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -87,7 +87,7 @@ EngineState::EngineState(ResourceManager *res, sci_version_t version, uint32 fla _executionStackPosChanged = false; r_acc = NULL_REG; - r_amp_rest = 0; + restAdjust = 0; r_prev = NULL_REG; stack_segment = 0; diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index ecfb9fe6f7..92a5b5e411 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -208,7 +208,7 @@ public: bool _executionStackPosChanged; /**< Set to true if the execution stack position should be re-evaluated by the vm */ reg_t r_acc; /**< Accumulator */ - unsigned int r_amp_rest; /**< &rest register (only used for save games) */ + uint16 restAdjust; /**< &rest register (only used for save games) */ reg_t r_prev; /**< previous comparison result */ SegmentId stack_segment; /**< Heap area for the stack to use */ diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index c6643b8a90..e0ac60f152 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -177,8 +177,8 @@ static void validate_write_var(reg_t *r, reg_t *stack_base, int type, int max, i #endif -#define READ_VAR(type, index, def) validate_read_var(variables[type], s->stack_base, type, variables_max[type], index, __LINE__, def) -#define WRITE_VAR(type, index, value) validate_write_var(variables[type], s->stack_base, type, variables_max[type], index, __LINE__, value) +#define READ_VAR(type, index, def) validate_read_var(scriptState.variables[type], s->stack_base, type, scriptState.variables_max[type], index, __LINE__, def) +#define WRITE_VAR(type, index, value) validate_write_var(scriptState.variables[type], s->stack_base, type, scriptState.variables_max[type], index, __LINE__, value) #define WRITE_VAR16(type, index, value) WRITE_VAR(type, index, make_reg(0, value)); #define ACC_ARITHMETIC_L(op) make_reg(0, (op validate_arithmetic(s->r_acc))) @@ -220,15 +220,15 @@ reg_t get_class_address(EngineState *s, int classnr, SCRIPT_GET lock, reg_t call #define PUSH(v) PUSH32(make_reg(0, v)) #define POP() (validate_arithmetic(POP32())) // 32 bit: -#define PUSH32(a) (*(validate_stack_addr(s, (xs->sp)++)) = (a)) -#define POP32() (*(validate_stack_addr(s, --(xs->sp)))) +#define PUSH32(a) (*(validate_stack_addr(s, (scriptState.xs->sp)++)) = (a)) +#define POP32() (*(validate_stack_addr(s, --(scriptState.xs->sp)))) // Getting instruction parameters -#define GET_OP_BYTE() ((uint8)code_buf[(xs->addr.pc.offset)++]) -#define GET_OP_WORD() (READ_LE_UINT16(code_buf + ((xs->addr.pc.offset) += 2) - 2)) +#define GET_OP_BYTE() ((uint8)code_buf[(scriptState.xs->addr.pc.offset)++]) +#define GET_OP_WORD() (READ_LE_UINT16(code_buf + ((scriptState.xs->addr.pc.offset) += 2) - 2)) #define GET_OP_FLEX() ((opcode & 1)? GET_OP_BYTE() : GET_OP_WORD()) -#define GET_OP_SIGNED_BYTE() ((int8)(code_buf[(xs->addr.pc.offset)++])) -#define GET_OP_SIGNED_WORD() (((int16)READ_LE_UINT16(code_buf + ((xs->addr.pc.offset) += 2) - 2))) +#define GET_OP_SIGNED_BYTE() ((int8)(code_buf[(scriptState.xs->addr.pc.offset)++])) +#define GET_OP_SIGNED_WORD() (((int16)READ_LE_UINT16(code_buf + ((scriptState.xs->addr.pc.offset) += 2) - 2))) #define GET_OP_SIGNED_FLEX() ((opcode & 1)? GET_OP_SIGNED_BYTE() : GET_OP_SIGNED_WORD()) ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, StackPtr sp, reg_t calling_obj, uint16 argc, StackPtr argp) { @@ -388,7 +388,7 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt break; #ifdef STRICT_SEND default: - debugState.seeking = debugState.runningStep = 0; + scriptState.seeking = scriptState.runningStep = 0; error("Send error: Variable selector %04x in %04x:%04x called with %04x params", selector, PRINT_REG(send_obj), argc); #endif } @@ -543,11 +543,7 @@ static const byte _fake_return_buffer[2] = {op_ret << 1, op_ret << 1}; void run_vm(EngineState *s, int restoring) { assert(s); - reg_t *variables[4]; // global, local, temp, param, as immediate pointers - reg_t *variables_base[4]; // Used for referencing VM ops - SegmentId variables_seg[4]; // Same as above, contains segment IDs #ifndef DISABLE_VALIDATIONS - int variables_max[4]; // Max. values for all variables unsigned int code_buf_size = 0 ; // (Avoid spurious warning) #endif int temp; @@ -556,13 +552,13 @@ void run_vm(EngineState *s, int restoring) { StackPtr s_temp; // Temporary stack pointer int16 opparams[4]; // opcode parameters - int restadjust = s->r_amp_rest; + scriptState.restadjust = s->restAdjust; // &rest adjusts the parameter count by this value // Current execution data: - ExecStack *xs = &(s->_executionStack.back()); + scriptState.xs = &(s->_executionStack.back()); ExecStack *xs_new = NULL; - Object *obj = obj_get(s, xs->objp); - Script *local_script = script_locate_by_segment(s, xs->local_segment); + Object *obj = obj_get(s, scriptState.xs->objp); + Script *local_script = script_locate_by_segment(s, scriptState.xs->local_segment); int old_execution_stack_base = s->execution_stack_base; // Used to detect the stack bottom, for "physical" returns const byte *code_buf = NULL; // (Avoid spurious warning) @@ -577,22 +573,20 @@ void run_vm(EngineState *s, int restoring) { #ifndef DISABLE_VALIDATIONS // Initialize maximum variable count if (s->script_000->locals_block) - variables_max[VAR_GLOBAL] = s->script_000->locals_block->_locals.size(); + scriptState.variables_max[VAR_GLOBAL] = s->script_000->locals_block->_locals.size(); else - variables_max[VAR_GLOBAL] = 0; + scriptState.variables_max[VAR_GLOBAL] = 0; #endif - variables_seg[VAR_GLOBAL] = s->script_000->locals_segment; - variables_seg[VAR_TEMP] = variables_seg[VAR_PARAM] = s->stack_segment; - variables_base[VAR_TEMP] = variables_base[VAR_PARAM] = s->stack_base; + scriptState.variables_seg[VAR_GLOBAL] = s->script_000->locals_segment; + scriptState.variables_seg[VAR_TEMP] = scriptState.variables_seg[VAR_PARAM] = s->stack_segment; + scriptState.variables_base[VAR_TEMP] = scriptState.variables_base[VAR_PARAM] = s->stack_base; // SCI code reads the zeroeth argument to determine argc if (s->script_000->locals_block) - variables_base[VAR_GLOBAL] = variables[VAR_GLOBAL] = s->script_000->locals_block->_locals.begin(); + scriptState.variables_base[VAR_GLOBAL] = scriptState.variables[VAR_GLOBAL] = s->script_000->locals_block->_locals.begin(); else - variables_base[VAR_GLOBAL] = variables[VAR_GLOBAL] = NULL; - - + scriptState.variables_base[VAR_GLOBAL] = scriptState.variables[VAR_GLOBAL] = NULL; s->_executionStackPosChanged = true; // Force initialization @@ -602,58 +596,58 @@ void run_vm(EngineState *s, int restoring) { int var_type; // See description below int var_number; - debugState.old_pc_offset = xs->addr.pc.offset; - debugState.old_sp = xs->sp; + scriptState.old_pc_offset = scriptState.xs->addr.pc.offset; + scriptState.old_sp = scriptState.xs->sp; if (s->_executionStackPosChanged) { Script *scr; - xs = &(s->_executionStack.back()); + scriptState.xs = &(s->_executionStack.back()); s->_executionStackPosChanged = false; - scr = script_locate_by_segment(s, xs->addr.pc.segment); + scr = script_locate_by_segment(s, scriptState.xs->addr.pc.segment); if (!scr) { // No script? Implicit return via fake instruction buffer - warning("Running on non-existant script in segment %x", xs->addr.pc.segment); + warning("Running on non-existant script in segment %x", scriptState.xs->addr.pc.segment); code_buf = _fake_return_buffer; #ifndef DISABLE_VALIDATIONS code_buf_size = 2; #endif - xs->addr.pc.offset = 1; + scriptState.xs->addr.pc.offset = 1; scr = NULL; obj = NULL; } else { - obj = obj_get(s, xs->objp); + obj = obj_get(s, scriptState.xs->objp); code_buf = scr->buf; #ifndef DISABLE_VALIDATIONS code_buf_size = scr->buf_size; #endif - local_script = script_locate_by_segment(s, xs->local_segment); + local_script = script_locate_by_segment(s, scriptState.xs->local_segment); if (!local_script) { - warning("Could not find local script from segment %x", xs->local_segment); + warning("Could not find local script from segment %x", scriptState.xs->local_segment); local_script = NULL; - variables_base[VAR_LOCAL] = variables[VAR_LOCAL] = NULL; + scriptState.variables_base[VAR_LOCAL] = scriptState.variables[VAR_LOCAL] = NULL; #ifndef DISABLE_VALIDATIONS - variables_max[VAR_LOCAL] = 0; + scriptState.variables_max[VAR_LOCAL] = 0; #endif } else { - variables_seg[VAR_LOCAL] = local_script->locals_segment; + scriptState.variables_seg[VAR_LOCAL] = local_script->locals_segment; if (local_script->locals_block) - variables_base[VAR_LOCAL] = variables[VAR_LOCAL] = local_script->locals_block->_locals.begin(); + scriptState.variables_base[VAR_LOCAL] = scriptState.variables[VAR_LOCAL] = local_script->locals_block->_locals.begin(); else - variables_base[VAR_LOCAL] = variables[VAR_LOCAL] = NULL; + scriptState.variables_base[VAR_LOCAL] = scriptState.variables[VAR_LOCAL] = NULL; #ifndef DISABLE_VALIDATIONS if (local_script->locals_block) - variables_max[VAR_LOCAL] = local_script->locals_block->_locals.size(); + scriptState.variables_max[VAR_LOCAL] = local_script->locals_block->_locals.size(); else - variables_max[VAR_LOCAL] = 0; - variables_max[VAR_TEMP] = xs->sp - xs->fp; - variables_max[VAR_PARAM] = xs->argc + 1; + scriptState.variables_max[VAR_LOCAL] = 0; + scriptState.variables_max[VAR_TEMP] = scriptState.xs->sp - scriptState.xs->fp; + scriptState.variables_max[VAR_PARAM] = scriptState.xs->argc + 1; #endif } - variables[VAR_TEMP] = xs->fp; - variables[VAR_PARAM] = xs->variables_argp; + scriptState.variables[VAR_TEMP] = scriptState.xs->fp; + scriptState.variables[VAR_PARAM] = scriptState.xs->variables_argp; } } @@ -665,24 +659,18 @@ void run_vm(EngineState *s, int restoring) { #if 0 // Debug if this has been requested: if (script_debug_flag || sci_debug_flags) { - script_debug(s, &(xs->addr.pc), &(xs->sp), &(xs->fp), &(xs->objp), &restadjust, variables_seg, variables, variables_base, -#ifdef DISABLE_VALIDATIONS - NULL, -#else - variables_max, -#endif - breakpointFlag); + script_debug(s, breakpointFlag); breakpointFlag = false; } #endif #ifndef DISABLE_VALIDATIONS - if (xs->sp < xs->fp) + if (scriptState.xs->sp < scriptState.xs->fp) error("run_vm(): stack underflow"); - variables_max[VAR_TEMP] = xs->sp - xs->fp; + scriptState.variables_max[VAR_TEMP] = scriptState.xs->sp - scriptState.xs->fp; - if (xs->addr.pc.offset >= code_buf_size) + if (scriptState.xs->addr.pc.offset >= code_buf_size) error("run_vm(): program counter gone astray"); #endif @@ -900,16 +888,16 @@ void run_vm(EngineState *s, int restoring) { case 0x17: // bt if (s->r_acc.offset || s->r_acc.segment) - xs->addr.pc.offset += opparams[0]; + scriptState.xs->addr.pc.offset += opparams[0]; break; case 0x18: // bnt if (!(s->r_acc.offset || s->r_acc.segment)) - xs->addr.pc.offset += opparams[0]; + scriptState.xs->addr.pc.offset += opparams[0]; break; case 0x19: // jmp - xs->addr.pc.offset += opparams[0]; + scriptState.xs->addr.pc.offset += opparams[0]; break; case 0x1a: // ldi @@ -925,33 +913,36 @@ void run_vm(EngineState *s, int restoring) { break; case 0x1d: // toss - xs->sp--; + scriptState.xs->sp--; break; case 0x1e: // dup - r_temp = xs->sp[-1]; + r_temp = scriptState.xs->sp[-1]; PUSH32(r_temp); break; case 0x1f: { // link int i; for (i = 0; i < opparams[0]; i++) - xs->sp[i] = NULL_REG; - xs->sp += opparams[0]; + scriptState.xs->sp[i] = NULL_REG; + scriptState.xs->sp += opparams[0]; break; } case 0x20: { // call int argc = (opparams[1] >> 1) // Given as offset, but we need count - + 1 + restadjust; - StackPtr call_base = xs->sp - argc; - xs->sp[1].offset += restadjust; - - xs_new = add_exec_stack_entry(s, make_reg(xs->addr.pc.segment, xs->addr.pc.offset + opparams[0]), - xs->sp, xs->objp, (validate_arithmetic(*call_base)) + restadjust, - call_base, NULL_SELECTOR, xs->objp, s->_executionStack.size()-1, xs->local_segment); - restadjust = 0; // Used up the &rest adjustment - xs->sp = call_base; + + 1 + scriptState.restadjust; + StackPtr call_base = scriptState.xs->sp - argc; + scriptState.xs->sp[1].offset += scriptState.restadjust; + + xs_new = add_exec_stack_entry(s, make_reg(scriptState.xs->addr.pc.segment, + scriptState.xs->addr.pc.offset + opparams[0]), + scriptState.xs->sp, scriptState.xs->objp, + (validate_arithmetic(*call_base)) + scriptState.restadjust, + call_base, NULL_SELECTOR, scriptState.xs->objp, + s->_executionStack.size()-1, scriptState.xs->local_segment); + scriptState.restadjust = 0; // Used up the &rest adjustment + scriptState.xs->sp = call_base; s->_executionStackPosChanged = true; break; @@ -960,25 +951,28 @@ void run_vm(EngineState *s, int restoring) { case 0x21: // callk gc_countdown(s); - xs->sp -= (opparams[1] >> 1) + 1; + scriptState.xs->sp -= (opparams[1] >> 1) + 1; if (!s->_kernel->hasOldScriptHeader()) { - xs->sp -= restadjust; - s->r_amp_rest = 0; // We just used up the restadjust, remember? + scriptState.xs->sp -= scriptState.restadjust; + s->restAdjust = 0; // We just used up the restadjust, remember? } if (opparams[0] >= (int)s->_kernel->_kernelFuncs.size()) { error("Invalid kernel function 0x%x requested\n", opparams[0]); } else { - int argc = ASSERT_ARITHMETIC(xs->sp[0]); + int argc = ASSERT_ARITHMETIC(scriptState.xs->sp[0]); if (!s->_kernel->hasOldScriptHeader()) - argc += restadjust; + argc += scriptState.restadjust; if (s->_kernel->_kernelFuncs[opparams[0]].signature - && !kernel_matches_signature(s, s->_kernel->_kernelFuncs[opparams[0]].signature, argc, xs->sp + 1)) { + && !kernel_matches_signature(s, + s->_kernel->_kernelFuncs[opparams[0]].signature, argc, + scriptState.xs->sp + 1)) { error("[VM] Invalid arguments to kernel call %x\n", opparams[0]); } else { - s->r_acc = s->_kernel->_kernelFuncs[opparams[0]].fun(s, opparams[0], argc, xs->sp + 1); + s->r_acc = s->_kernel->_kernelFuncs[opparams[0]].fun(s, opparams[0], + argc, scriptState.xs->sp + 1); } // Call kernel function @@ -989,31 +983,33 @@ void run_vm(EngineState *s, int restoring) { s->_executionStackPosChanged = true; if (!s->_kernel->hasOldScriptHeader()) - restadjust = s->r_amp_rest; + scriptState.restadjust = s->restAdjust; } break; case 0x22: // callb - temp = ((opparams[1] >> 1) + restadjust + 1); - s_temp = xs->sp; - xs->sp -= temp; - - xs->sp[0].offset += restadjust; - xs_new = execute_method(s, 0, opparams[0], s_temp, xs->objp, xs->sp[0].offset, xs->sp); - restadjust = 0; // Used up the &rest adjustment + temp = ((opparams[1] >> 1) + scriptState.restadjust + 1); + s_temp = scriptState.xs->sp; + scriptState.xs->sp -= temp; + + scriptState.xs->sp[0].offset += scriptState.restadjust; + xs_new = execute_method(s, 0, opparams[0], s_temp, scriptState.xs->objp, + scriptState.xs->sp[0].offset, scriptState.xs->sp); + scriptState.restadjust = 0; // Used up the &rest adjustment if (xs_new) // in case of error, keep old stack s->_executionStackPosChanged = true; break; case 0x23: // calle - temp = ((opparams[2] >> 1) + restadjust + 1); - s_temp = xs->sp; - xs->sp -= temp; + temp = ((opparams[2] >> 1) + scriptState.restadjust + 1); + s_temp = scriptState.xs->sp; + scriptState.xs->sp -= temp; - xs->sp[0].offset += restadjust; - xs_new = execute_method(s, opparams[0], opparams[1], s_temp, xs->objp, xs->sp[0].offset, xs->sp); - restadjust = 0; // Used up the &rest adjustment + scriptState.xs->sp[0].offset += scriptState.restadjust; + xs_new = execute_method(s, opparams[0], opparams[1], s_temp, scriptState.xs->objp, + scriptState.xs->sp[0].offset, scriptState.xs->sp); + scriptState.restadjust = 0; // Used up the &rest adjustment if (xs_new) // in case of error, keep old stack s->_executionStackPosChanged = true; @@ -1021,8 +1017,8 @@ void run_vm(EngineState *s, int restoring) { case 0x24: // ret do { - StackPtr old_sp2 = xs->sp; - StackPtr old_fp = xs->fp; + StackPtr old_sp2 = scriptState.xs->sp; + StackPtr old_fp = scriptState.xs->fp; ExecStack *old_xs = &(s->_executionStack.back()); if ((int)s->_executionStack.size()-1 == s->execution_stack_base) { // Have we reached the base? @@ -1031,7 +1027,7 @@ void run_vm(EngineState *s, int restoring) { s->_executionStack.pop_back(); s->_executionStackPosChanged = true; - s->r_amp_rest = restadjust; // Update &rest + s->restAdjust = scriptState.restadjust; // Update &rest return; // "Hard" return } @@ -1046,80 +1042,84 @@ void run_vm(EngineState *s, int restoring) { // Not reached the base, so let's do a soft return s->_executionStack.pop_back(); s->_executionStackPosChanged = true; - xs = &(s->_executionStack.back()); + scriptState.xs = &(s->_executionStack.back()); - if (xs->sp == CALL_SP_CARRY // Used in sends to 'carry' the stack pointer - || xs->type != EXEC_STACK_TYPE_CALL) { - xs->sp = old_sp2; - xs->fp = old_fp; + if (scriptState.xs->sp == CALL_SP_CARRY // Used in sends to 'carry' the stack pointer + || scriptState.xs->type != EXEC_STACK_TYPE_CALL) { + scriptState.xs->sp = old_sp2; + scriptState.xs->fp = old_fp; } - } while (xs->type == EXEC_STACK_TYPE_VARSELECTOR); + } while (scriptState.xs->type == EXEC_STACK_TYPE_VARSELECTOR); // Iterate over all varselector accesses s->_executionStackPosChanged = true; - xs_new = xs; + xs_new = scriptState.xs; break; case 0x25: // send - s_temp = xs->sp; - xs->sp -= ((opparams[0] >> 1) + restadjust); // Adjust stack + s_temp = scriptState.xs->sp; + scriptState.xs->sp -= ((opparams[0] >> 1) + scriptState.restadjust); // Adjust stack - xs->sp[1].offset += restadjust; - xs_new = send_selector(s, s->r_acc, s->r_acc, s_temp, (int)(opparams[0] >> 1) + (uint16)restadjust, xs->sp); + scriptState.xs->sp[1].offset += scriptState.restadjust; + xs_new = send_selector(s, s->r_acc, s->r_acc, s_temp, + (int)(opparams[0] >> 1) + scriptState.restadjust, scriptState.xs->sp); - if (xs_new && xs_new != xs) + if (xs_new && xs_new != scriptState.xs) s->_executionStackPosChanged = true; - restadjust = 0; + scriptState.restadjust = 0; break; case 0x28: // class - s->r_acc = get_class_address(s, (unsigned)opparams[0], SCRIPT_GET_LOCK, xs->addr.pc); + s->r_acc = get_class_address(s, (unsigned)opparams[0], SCRIPT_GET_LOCK, + scriptState.xs->addr.pc); break; case 0x2a: // self - s_temp = xs->sp; - xs->sp -= ((opparams[0] >> 1) + restadjust); // Adjust stack + s_temp = scriptState.xs->sp; + scriptState.xs->sp -= ((opparams[0] >> 1) + scriptState.restadjust); // Adjust stack - xs->sp[1].offset += restadjust; - xs_new = send_selector(s, xs->objp, xs->objp, s_temp, (int)(opparams[0] >> 1) + (uint16)restadjust, xs->sp); + scriptState.xs->sp[1].offset += scriptState.restadjust; + xs_new = send_selector(s, scriptState.xs->objp, scriptState.xs->objp, + s_temp, (int)(opparams[0] >> 1) + scriptState.restadjust, + scriptState.xs->sp); - if (xs_new && xs_new != xs) + if (xs_new && xs_new != scriptState.xs) s->_executionStackPosChanged = true; - restadjust = 0; + scriptState.restadjust = 0; break; case 0x2b: // super - r_temp = get_class_address(s, opparams[0], SCRIPT_GET_LOAD, xs->addr.pc); + r_temp = get_class_address(s, opparams[0], SCRIPT_GET_LOAD, scriptState.xs->addr.pc); if (!r_temp.segment) error("[VM]: Invalid superclass in object"); else { - s_temp = xs->sp; - xs->sp -= ((opparams[1] >> 1) + restadjust); // Adjust stack + s_temp = scriptState.xs->sp; + scriptState.xs->sp -= ((opparams[1] >> 1) + scriptState.restadjust); // Adjust stack - xs->sp[1].offset += restadjust; - xs_new = send_selector(s, r_temp, xs->objp, s_temp, (int)(opparams[1] >> 1) + (uint16)restadjust, xs->sp); + scriptState.xs->sp[1].offset += scriptState.restadjust; + xs_new = send_selector(s, r_temp, scriptState.xs->objp, s_temp, + (int)(opparams[1] >> 1) + scriptState.restadjust, + scriptState.xs->sp); - if (xs_new && xs_new != xs) + if (xs_new && xs_new != scriptState.xs) s->_executionStackPosChanged = true; - restadjust = 0; + scriptState.restadjust = 0; } break; case 0x2c: // &rest temp = (uint16) opparams[0]; // First argument - restadjust = xs->argc - temp + 1; // +1 because temp counts the paramcount while argc doesn't - if (restadjust < 0) - restadjust = 0; + scriptState.restadjust = MAX<uint16>(scriptState.xs->argc - temp + 1, 0); // +1 because temp counts the paramcount while argc doesn't - for (; temp <= xs->argc; temp++) - PUSH32(xs->variables_argp[temp]); + for (; temp <= scriptState.xs->argc; temp++) + PUSH32(scriptState.xs->variables_argp[temp]); break; @@ -1128,8 +1128,8 @@ void run_vm(EngineState *s, int restoring) { var_number = temp & 0x03; // Get variable type // Get variable block offset - r_temp.segment = variables_seg[var_number]; - r_temp.offset = variables[var_number] - variables_base[var_number]; + r_temp.segment = scriptState.variables_seg[var_number]; + r_temp.offset = scriptState.variables[var_number] - scriptState.variables_base[var_number]; if (temp & 0x08) // Add accumulator offset if requested r_temp.offset += signed_validate_arithmetic(s->r_acc); @@ -1142,7 +1142,7 @@ void run_vm(EngineState *s, int restoring) { case 0x2e: // selfID - s->r_acc = xs->objp; + s->r_acc = scriptState.xs->objp; break; case 0x30: // pprev @@ -1189,7 +1189,7 @@ void run_vm(EngineState *s, int restoring) { case 0x39: // lofsa - s->r_acc.segment = xs->addr.pc.segment; + s->r_acc.segment = scriptState.xs->addr.pc.segment; if (s->_version >= SCI_VERSION_1_1) { s->r_acc.offset = opparams[0] + local_script->script_size; @@ -1197,7 +1197,7 @@ void run_vm(EngineState *s, int restoring) { if (s->_kernel->hasLofsAbsolute()) s->r_acc.offset = opparams[0]; else - s->r_acc.offset = xs->addr.pc.offset + opparams[0]; + s->r_acc.offset = scriptState.xs->addr.pc.offset + opparams[0]; } #ifndef DISABLE_VALIDATIONS @@ -1209,7 +1209,7 @@ void run_vm(EngineState *s, int restoring) { break; case 0x3a: // lofss - r_temp.segment = xs->addr.pc.segment; + r_temp.segment = scriptState.xs->addr.pc.segment; if (s->_version >= SCI_VERSION_1_1) { r_temp.offset = opparams[0] + local_script->script_size; @@ -1217,7 +1217,7 @@ void run_vm(EngineState *s, int restoring) { if (s->_kernel->hasLofsAbsolute()) r_temp.offset = opparams[0]; else - r_temp.offset = xs->addr.pc.offset + opparams[0]; + r_temp.offset = scriptState.xs->addr.pc.offset + opparams[0]; } #ifndef DISABLE_VALIDATIONS @@ -1242,7 +1242,7 @@ void run_vm(EngineState *s, int restoring) { break; case 0x3e: // pushSelf - PUSH32(xs->objp); + PUSH32(scriptState.xs->objp); break; case 0x40: // lag @@ -1410,12 +1410,12 @@ void run_vm(EngineState *s, int restoring) { } // switch(opcode >> 1) if (s->_executionStackPosChanged) // Force initialization - xs = xs_new; + scriptState.xs = xs_new; //#ifndef DISABLE_VALIDATIONS - if (xs != &(s->_executionStack.back())) { + if (scriptState.xs != &(s->_executionStack.back())) { warning("xs is stale (%p vs %p); last command was %02x", - (void *)xs, (void *)&(s->_executionStack.back()), + (void *)scriptState.xs, (void *)&(s->_executionStack.back()), opnumber); } //#endif @@ -1972,8 +1972,6 @@ static EngineState *_game_run(EngineState *&s, int restoring) { return s; } -int printObject(EngineState *s, reg_t pos); - int game_run(EngineState **_s) { EngineState *s = *_s; @@ -1982,7 +1980,8 @@ int game_run(EngineState **_s) { // Now: Register the first element on the execution stack- if (!send_selector(s, s->game_obj, s->game_obj, s->stack_base, 2, s->stack_base)) { - printObject(s, s->game_obj); + Console *con = ((SciEngine *)g_engine)->getSciDebugger(); + con->printObject(s->game_obj); warning("Failed to run the game! Aborting..."); return 1; } @@ -2037,9 +2036,8 @@ const char *obj_get_name(EngineState *s, reg_t pos) { void quit_vm() { script_abort_flag = 1; // Terminate VM - debugState.isValid = false; - debugState.seeking = kDebugSeekNothing; - debugState.runningStep = 0; + scriptState.seeking = kDebugSeekNothing; + scriptState.runningStep = 0; } void shrink_execution_stack(EngineState *s, uint size) { diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index a3fabbe44b..1472fae97c 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -243,24 +243,23 @@ enum ExecStackType { }; struct ExecStack { - reg_t objp; - reg_t sendp; /**< Pointer to the object containing the invoked method */ + reg_t objp; // Pointer to the beginning of the current object + reg_t sendp; // Pointer to the object containing the invoked method union { - ObjVarRef varp; /**< Variable pointer for r/w access */ - reg_t pc; /**< Not accurate for the TOS element */ + ObjVarRef varp; // Variable pointer for r/w access + reg_t pc; // Pointer to the initial program counter. Not accurate for the TOS element } addr; - StackPtr fp; /**< Frame pointer */ - StackPtr sp; /**< Stack pointer */ + StackPtr fp; // Frame pointer + StackPtr sp; // Stack pointer int argc; - /* former variables[4]: [all other values are derived] */ - StackPtr variables_argp; /**< Argument pointer */ - SegmentId local_segment; /**< local variables etc. */ + StackPtr variables_argp; // Argument pointer + SegmentId local_segment; // local variables etc - Selector selector; /**< The selector which was used to call or -1 if not applicable */ - int origin; /**< The stack frame position the call was made from, or -1 if it was the initial call. */ + Selector selector; // The selector which was used to call or -1 if not applicable + int origin; // The stack frame position the call was made from, or -1 if it was the initial call ExecStackType type; reg_t* getVarPointer(EngineState *s) const; @@ -409,27 +408,10 @@ void vm_handle_fatal_error(EngineState *s, int line, const char *file); /** * Debugger functionality - * @param[in] s The state at which debugging should take - * place - * @param[in] pc Pointer to the program counter - * @param[in] sp Pointer to the stack pointer - * @param[in] pp Pointer to the frame pointer - * @param[in] objp Pointer to the object base pointer - * @param[in] restadjust Pointer to the &rest adjustment value - * @param[in] segids four-element array containing segment IDs - * for locals etc. - * @param[in] variables four-element array referencing registers - * for globals etc. - * @param[in] variables_base four-element array referencing register - * bases for temps etc. - * @param[in] variables_nr four-element array giving sizes for params - * etc. (may be NULL) - * @param[in] bp Flag, set to 1 when a breakpoint is - * triggered - */ -void script_debug(EngineState *s, reg_t *pc, StackPtr *sp, StackPtr *pp, - reg_t *objp, int *restadjust, SegmentId *segids, reg_t **variables, - reg_t **variables_base, int *variables_nr, int bp); + * @param[in] s The state at which debugging should take place + * @param[in] bp Flag, set to true when a breakpoint is triggered + */ +void script_debug(EngineState *s, bool bp); /** * Initializes a EngineState block diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index 2992a1b347..dbb8d4784a 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -247,12 +247,12 @@ Common::Error SciEngine::run() { GUI::Debugger *SciEngine::getDebugger() { if (_gamestate) { ExecStack *xs = &(_gamestate->_executionStack.back()); - xs->addr.pc.offset = debugState.old_pc_offset; - xs->sp = debugState.old_sp; + xs->addr.pc.offset = scriptState.old_pc_offset; + xs->sp = scriptState.old_sp; } - debugState.runningStep = 0; // Stop multiple execution - debugState.seeking = kDebugSeekNothing; // Stop special seeks + scriptState.runningStep = 0; // Stop multiple execution + scriptState.seeking = kDebugSeekNothing; // Stop special seeks return _console; } |