aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/gob/inter.cpp5
-rw-r--r--engines/gob/inter.h3
-rw-r--r--engines/gob/inter_v2.cpp32
-rw-r--r--engines/gob/variables.cpp61
-rw-r--r--engines/gob/variables.h17
5 files changed, 88 insertions, 30 deletions
diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp
index 8db42b217c..06bf9a216f 100644
--- a/engines/gob/inter.cpp
+++ b/engines/gob/inter.cpp
@@ -39,7 +39,7 @@
namespace Gob {
-Inter::Inter(GobEngine *vm) : _vm(vm) {
+Inter::Inter(GobEngine *vm) : _vm(vm), _varStack(600) {
_terminate = 0;
_break = false;
@@ -55,9 +55,6 @@ Inter::Inter(GobEngine *vm) : _vm(vm) {
_soundEndTimeKey = 0;
_soundStopVal = 0;
- memset(_varStack, 0, 300);
- _varStackPos = 0;
-
_noBusyWait = false;
_variables = 0;
diff --git a/engines/gob/inter.h b/engines/gob/inter.h
index 4554a0783b..c3567ce7ce 100644
--- a/engines/gob/inter.h
+++ b/engines/gob/inter.h
@@ -129,8 +129,7 @@ protected:
int16 _animPalHighIndex[8];
int16 _animPalDir[8];
- byte _varStack[300];
- int16 _varStackPos;
+ VariableStack _varStack;
// The busy-wait detection in o1_keyFunc breaks fast scrolling in Ween
bool _noBusyWait;
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 1707e614ce..3e8a4903ca 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -609,21 +609,15 @@ void Inter_v2::o2_switchTotSub() {
}
void Inter_v2::o2_pushVars() {
- byte count;
- int16 varOff;
-
- count = _vm->_game->_script->readByte();
- for (int i = 0; i < count; i++, _varStackPos++) {
+ uint8 count = _vm->_game->_script->readByte();
+ for (int i = 0; i < count; i++) {
if ((_vm->_game->_script->peekByte() == 25) ||
(_vm->_game->_script->peekByte() == 28)) {
- varOff = _vm->_game->_script->readVarIndex();
+ int16 varOff = _vm->_game->_script->readVarIndex();
_vm->_game->_script->skip(1);
- _variables->copyTo(varOff, _varStack + _varStackPos, _vm->_global->_inter_animDataSize * 4);
-
- _varStackPos += _vm->_global->_inter_animDataSize * 4;
- _varStack[_varStackPos] = _vm->_global->_inter_animDataSize * 4;
+ _varStack.pushData(*_variables, varOff, _vm->_global->_inter_animDataSize * 4);
} else {
int16 value;
@@ -631,27 +625,17 @@ void Inter_v2::o2_pushVars() {
if (_vm->_game->_script->evalExpr(&value) != 20)
value = 0;
- uint32 value32 = ((uint16) value);
-
- memcpy(_varStack + _varStackPos, &value32, 4);
- _varStackPos += 4;
- _varStack[_varStackPos] = 4;
+ _varStack.pushInt((uint16)value);
}
}
}
void Inter_v2::o2_popVars() {
- byte count;
- int16 varOff;
- int16 size;
-
- count = _vm->_game->_script->readByte();
+ uint8 count = _vm->_game->_script->readByte();
for (int i = 0; i < count; i++) {
- varOff = _vm->_game->_script->readVarIndex();
- size = _varStack[--_varStackPos];
+ int16 varOff = _vm->_game->_script->readVarIndex();
- _varStackPos -= size;
- _variables->copyFrom(varOff, _varStack + _varStackPos, size);
+ _varStack.pop(*_variables, varOff);
}
}
diff --git a/engines/gob/variables.cpp b/engines/gob/variables.cpp
index 4f6bad52f0..7f7ddb023d 100644
--- a/engines/gob/variables.cpp
+++ b/engines/gob/variables.cpp
@@ -286,4 +286,65 @@ VariableReference &VariableReference::operator*=(uint32 value) {
return (*this = (*this * value));
}
+
+VariableStack::VariableStack(uint32 size) : _size(size), _position(0) {
+ _stack = new byte[_size];
+
+ memset(_stack, 0, _size);
+}
+
+VariableStack::~VariableStack() {
+ delete[] _stack;
+}
+
+void VariableStack::pushData(const Variables &vars, uint32 offset, uint32 size) {
+ // Sanity checks
+ assert(size < 256);
+ assert((_position + size) < _size);
+
+ vars.copyTo(offset, _stack + _position, size);
+
+ _position += size;
+ _stack[_position++] = size;
+ _stack[_position++] = 0;
+}
+
+void VariableStack::pushInt(uint32 value) {
+ // Sanity check
+ assert((_position + 4) < _size);
+
+ memcpy(_stack + _position, &value, 4);
+
+ _position += 4;
+ _stack[_position++] = 4;
+ _stack[_position++] = 1;
+}
+
+void VariableStack::pop(Variables &vars, uint32 offset) {
+ // Sanity check
+ assert(_position >= 2);
+
+ bool isInt = _stack[--_position] == 1;
+ uint32 size = _stack[--_position];
+
+ // Sanity check
+ assert(_position >= size);
+
+ _position -= size;
+
+ if (isInt) {
+ // If it's an int, explicitely call the int variable writing method,
+ // to make sure the variable space endianness is preserved.
+
+ assert(size == 4);
+
+ uint32 value;
+ memcpy(&value, _stack + _position, 4);
+
+ vars.writeOff32(offset, value);
+ } else
+ // Otherwise, use do a raw copy
+ vars.copyFrom(offset, _stack + _position, size);
+}
+
} // End of namespace Gob
diff --git a/engines/gob/variables.h b/engines/gob/variables.h
index c3724bc118..d092a8bc4c 100644
--- a/engines/gob/variables.h
+++ b/engines/gob/variables.h
@@ -148,6 +148,23 @@ private:
Variables::Type _type;
};
+class VariableStack {
+public:
+ VariableStack(uint32 size);
+ ~VariableStack();
+
+ void pushData(const Variables &vars, uint32 offset, uint32 size);
+ void pushInt(uint32 value);
+
+ void pop(Variables &vars, uint32 offset);
+
+private:
+ byte *_stack;
+
+ uint32 _size;
+ uint32 _position;
+};
+
} // End of namespace Gob
#endif // GOB_VARIABLES_H