aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kurushin2005-05-12 15:11:32 +0000
committerAndrew Kurushin2005-05-12 15:11:32 +0000
commit91ff7f7a31e18a42438d08aaea515c38bb319755 (patch)
treecb1f1b5b620f3666e4de0ee434be50cbd7f9d3d4
parentb3ec4726391e80be92e6faff68be5e5de495d29a (diff)
downloadscummvm-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
-rw-r--r--saga/interface.cpp25
-rw-r--r--saga/interface.h4
-rw-r--r--saga/saveload.cpp4
-rw-r--r--saga/sthread.cpp86
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: