diff options
author | Sven Hesse | 2011-01-17 13:37:14 +0000 |
---|---|---|
committer | Sven Hesse | 2011-01-17 13:37:14 +0000 |
commit | db13af5337e06472c82684cbf362598598d158d3 (patch) | |
tree | cfc6fec7fe251bb8591c321127aeca8f4da9f249 /engines/gob/variables.cpp | |
parent | 6c6d85908fd475eb6c32031f3fdfa16bd5bae3d9 (diff) | |
download | scummvm-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.cpp | 61 |
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 |