aboutsummaryrefslogtreecommitdiff
path: root/engines/gob/variables.cpp
diff options
context:
space:
mode:
authorSven Hesse2011-01-17 13:37:14 +0000
committerSven Hesse2011-01-17 13:37:14 +0000
commitdb13af5337e06472c82684cbf362598598d158d3 (patch)
treecfc6fec7fe251bb8591c321127aeca8f4da9f249 /engines/gob/variables.cpp
parent6c6d85908fd475eb6c32031f3fdfa16bd5bae3d9 (diff)
downloadscummvm-rg350-db13af5337e06472c82684cbf362598598d158d3.tar.gz
scummvm-rg350-db13af5337e06472c82684cbf362598598d158d3.tar.bz2
scummvm-rg350-db13af5337e06472c82684cbf362598598d158d3.zip
GOB: Make the variable stack endianness-independent
Since Urban Runner casts int16s to uint32 before pushing them onto the stack and after popping assumes it's little endian, we have explicitely preserve the variable space endianness while pushing/popping. svn-id: r55277
Diffstat (limited to 'engines/gob/variables.cpp')
-rw-r--r--engines/gob/variables.cpp61
1 files changed, 61 insertions, 0 deletions
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