diff options
author | Andrew Kurushin | 2005-05-12 15:11:32 +0000 |
---|---|---|
committer | Andrew Kurushin | 2005-05-12 15:11:32 +0000 |
commit | 91ff7f7a31e18a42438d08aaea515c38bb319755 (patch) | |
tree | cb1f1b5b620f3666e4de0ee434be50cbd7f9d3d4 /saga | |
parent | b3ec4726391e80be92e6faff68be5e5de495d29a (diff) | |
download | scummvm-rg350-91ff7f7a31e18a42438d08aaea515c38bb319755.tar.gz scummvm-rg350-91ff7f7a31e18a42438d08aaea515c38bb319755.tar.bz2 scummvm-rg350-91ff7f7a31e18a42438d08aaea515c38bb319755.zip |
fixed interpreter bug (negative address offset - may crush system)
implemented inventory save-load
svn-id: r18071
Diffstat (limited to 'saga')
-rw-r--r-- | saga/interface.cpp | 25 | ||||
-rw-r--r-- | saga/interface.h | 4 | ||||
-rw-r--r-- | saga/saveload.cpp | 4 | ||||
-rw-r--r-- | saga/sthread.cpp | 86 |
4 files changed, 68 insertions, 51 deletions
diff --git a/saga/interface.cpp b/saga/interface.cpp index f7077c62c2..b40512c3bf 100644 --- a/saga/interface.cpp +++ b/saga/interface.cpp @@ -642,12 +642,7 @@ void Interface::updateInventory(int pos) { } } -void Interface::addToInventory(int objectId, int pos) { - if (pos != -1) { - _inventory[pos] = objectId; - _inventoryCount = MAX(_inventoryCount, pos + 1); - return; - } +void Interface::addToInventory(int objectId) { if (_inventoryCount >= _inventorySize) { return; @@ -1034,5 +1029,23 @@ void Interface::handleConverseClick(const Point& mousePoint) { } +void Interface::saveState(Common::File& out) { + out.writeUint16LE(_inventoryCount); + + for (int i = 0; i < _inventoryCount; i++) { + out.writeUint16LE(_inventory[i]); + } +} + +void Interface::loadState(Common::File& in) { + _inventoryCount = in.readUint16LE(); + + for (int i = 0; i < _inventoryCount; i++) { + _inventory[i] = in.readUint16LE(); + } + + updateInventory(0); +} + } // End of namespace Saga diff --git a/saga/interface.h b/saga/interface.h index ea0d31f4c0..c01d179dd5 100644 --- a/saga/interface.h +++ b/saga/interface.h @@ -174,7 +174,7 @@ public: updateInventory(_inventoryCount); draw(); } - void addToInventory(int objectId, int pos = -1); + void addToInventory(int objectId); void removeFromInventory(int objectId); void clearInventory(); int inventoryItemPosition(int objectId); @@ -189,6 +189,8 @@ public: PanelButton *inventoryHitTest(const Point& mousePoint) { return _mainPanel.hitTest(mousePoint, kPanelButtonInventory); } + void saveState(Common::File& out); + void loadState(Common::File& in); private: PanelButton *verbHitTest(const Point& mousePoint); void handleCommandUpdate(const Point& mousePoint); diff --git a/saga/saveload.cpp b/saga/saveload.cpp index 2c7dd17a7b..65fe4453d4 100644 --- a/saga/saveload.cpp +++ b/saga/saveload.cpp @@ -53,6 +53,8 @@ void SagaEngine::save(const char *fileName) { uint16 i; + _interface->saveState(out); + _actor->saveState(out); out.writeSint16LE(_script->_commonBufferSize); @@ -88,7 +90,7 @@ void SagaEngine::load(const char *fileName) { debug(0, "scene: #%d inset scene: #%d", sceneNumber, insetSceneNumber); - _interface->clearInventory(); + _interface->loadState(in); _actor->loadState(in); diff --git a/saga/sthread.cpp b/saga/sthread.cpp index f253810f24..9b831506a8 100644 --- a/saga/sthread.cpp +++ b/saga/sthread.cpp @@ -187,10 +187,10 @@ bool Script::runThread(ScriptThread *thread, uint instructionLimit) { uint16 savedInstructionOffset; byte *addr; - uint16 param1; - uint16 param2; + uint16 jmpOffset1; int16 iparam1; int16 iparam2; + int16 iparam3; byte argumentsCount; uint16 functionNumber; @@ -263,10 +263,10 @@ bool Script::runThread(ScriptThread *thread, uint instructionLimit) { // DATA INSTRUCTIONS CASEOP(opGetFlag) addr = thread->baseAddress(scriptS.readByte()); - param1 = scriptS.readUint16LE(); - addr += (param1 >> 3); - param1 = (1 << (param1 & 7)); - thread->push((*addr) & param1 ? 1 : 0); + iparam1 = scriptS.readSint16LE(); + addr += (iparam1 >> 3); + iparam1 = (1 << (iparam1 & 7)); + thread->push((*addr) & iparam1 ? 1 : 0); break; CASEOP(opGetInt) addr = thread->baseAddress(scriptS.readByte()); @@ -277,13 +277,13 @@ bool Script::runThread(ScriptThread *thread, uint instructionLimit) { break; CASEOP(opPutFlag) addr = thread->baseAddress(scriptS.readByte()); - param1 = scriptS.readUint16LE(); - addr += (param1 >> 3); - param1 = (1 << (param1 & 7)); + iparam1 = scriptS.readSint16LE(); + addr += (iparam1 >> 3); + iparam1 = (1 << (iparam1 & 7)); if (thread->stackTop()) { - *addr |= param1; + *addr |= iparam1; } else { - *addr &= ~param1; + *addr &= ~iparam1; } break; CASEOP(opPutInt) @@ -294,13 +294,13 @@ bool Script::runThread(ScriptThread *thread, uint instructionLimit) { break; CASEOP(opPutFlagV) addr = thread->baseAddress(scriptS.readByte()); - param1 = scriptS.readUint16LE(); - addr += (param1 >> 3); - param1 = (1 << (param1 & 7)); + iparam1 = scriptS.readSint16LE(); + addr += (iparam1 >> 3); + iparam1 = (1 << (iparam1 & 7)); if (thread->pop()) { - *addr |= param1; + *addr |= iparam1; } else { - *addr &= ~param1; + *addr &= ~iparam1; } break; CASEOP(opPutIntV) @@ -313,20 +313,20 @@ bool Script::runThread(ScriptThread *thread, uint instructionLimit) { // FUNCTION CALL INSTRUCTIONS CASEOP(opCall) argumentsCount = scriptS.readByte(); - param1 = scriptS.readByte(); - if (param1 != kAddressModule) { - error("Script::runThread param1 != kAddressModule"); + iparam1 = scriptS.readByte(); + if (iparam1 != kAddressModule) { + error("Script::runThread iparam1 != kAddressModule"); } - addr = thread->baseAddress(param1); + addr = thread->baseAddress(iparam1); iparam1 = scriptS.readSint16LE(); addr += iparam1; thread->push(argumentsCount); - param2 = scriptS.pos(); + jmpOffset1 = scriptS.pos(); // NOTE: The original pushes the program // counter as a pointer here. But I don't think // we will have to do that. - thread->push(param2); + thread->push(jmpOffset1); // NOTE2: program counter is 32bit - so we should "emulate" it size - because kAddressStack relies on it thread->push(0); thread->_instructionOffset = iparam1; @@ -385,40 +385,40 @@ bool Script::runThread(ScriptThread *thread, uint instructionLimit) { // BRANCH INSTRUCTIONS CASEOP(opJmp) - param1 = scriptS.readUint16LE(); - thread->_instructionOffset = param1; + jmpOffset1 = scriptS.readUint16LE(); + thread->_instructionOffset = jmpOffset1; break; CASEOP(opJmpTrueV) - param1 = scriptS.readUint16LE(); + jmpOffset1 = scriptS.readUint16LE(); if (thread->pop()) { - thread->_instructionOffset = param1; + thread->_instructionOffset = jmpOffset1; } break; CASEOP(opJmpFalseV) - param1 = scriptS.readUint16LE(); + jmpOffset1 = scriptS.readUint16LE(); if (!thread->pop()) { - thread->_instructionOffset = param1; + thread->_instructionOffset = jmpOffset1; } break; CASEOP(opJmpTrue) - param1 = scriptS.readUint16LE(); + jmpOffset1 = scriptS.readUint16LE(); if (thread->stackTop()) { - thread->_instructionOffset = param1; + thread->_instructionOffset = jmpOffset1; } break; CASEOP(opJmpFalse) - param1 = scriptS.readUint16LE(); + jmpOffset1 = scriptS.readUint16LE(); if (!thread->stackTop()) { - thread->_instructionOffset = param1; + thread->_instructionOffset = jmpOffset1; } break; CASEOP(opJmpSwitch) iparam1 = scriptS.readSint16LE(); - param1 = thread->pop(); + iparam2 = thread->pop(); while (iparam1--) { - param2 = scriptS.readUint16LE(); + iparam3 = scriptS.readUint16LE(); thread->_instructionOffset = scriptS.readUint16LE(); - if (param2 == param1) { + if (iparam3 == iparam2) { break; } } @@ -669,26 +669,26 @@ bool Script::runThread(ScriptThread *thread, uint instructionLimit) { byte flags; replyNum = scriptS.readByte(); flags = scriptS.readByte(); - param1 = 0; + iparam1 = 0; if (flags & kReplyOnce) { - param1 = scriptS.readUint16LE(); - addr = thread->_staticBase + (param1 >> 3); - if (*addr & (1 << (param1 & 7))) { + iparam1 = scriptS.readSint16LE(); + addr = thread->_staticBase + (iparam1 >> 3); + if (*addr & (1 << (iparam1 & 7))) { break; } } str = thread->_strings->getString(thread->pop()); - if (_vm->_interface->converseAddText(str, replyNum, flags, param1)) - warning("Error adding ConverseText (%s, %d, %d, %d)", str, replyNum, flags, param1); + if (_vm->_interface->converseAddText(str, replyNum, flags, iparam1)) + warning("Error adding ConverseText (%s, %d, %d, %d)", str, replyNum, flags, iparam1); } break; CASEOP(opAnimate) scriptS.readUint16LE(); scriptS.readUint16LE(); - param1 = scriptS.readByte(); - thread->_instructionOffset += param1; + jmpOffset1 = scriptS.readByte(); + thread->_instructionOffset += jmpOffset1; break; default: |