aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorMartin Kiewitz2016-02-08 21:12:37 +0100
committerMartin Kiewitz2016-02-08 21:12:37 +0100
commit050ec1ef31f0606132531dffeb4d3a5042f8b1a8 (patch)
tree9fe7e9016a2c83f74c03f99231a7d1eadb8227bc /engines/sci
parent2a883bdd424a166215eeeecf6876ac1cc30fb8bd (diff)
downloadscummvm-rg350-050ec1ef31f0606132531dffeb4d3a5042f8b1a8.tar.gz
scummvm-rg350-050ec1ef31f0606132531dffeb4d3a5042f8b1a8.tar.bz2
scummvm-rg350-050ec1ef31f0606132531dffeb4d3a5042f8b1a8.zip
SCI: Make kMemory behavior like original SCI
We added 1 to the size as a workaround, but it's not really a workaround, because original SCI allocated at least 2 bytes more. They also made sure the size is even. We now do the same.
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/engine/kmisc.cpp19
1 files changed, 13 insertions, 6 deletions
diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp
index 9d47a37bca..f4bb4ff85b 100644
--- a/engines/sci/engine/kmisc.cpp
+++ b/engines/sci/engine/kmisc.cpp
@@ -268,7 +268,10 @@ reg_t kMemory(EngineState *s, int argc, reg_t *argv) {
switch (argv[0].toUint16()) {
case K_MEMORY_ALLOCATE_CRITICAL: {
int byteCount = argv[1].toUint16();
- // WORKAROUND:
+ // Sierra themselves allocated at least 2 bytes more than requested.
+ // Probably as a safety margin. And they also made size even.
+ //
+ // This behavior is required by at least these:
// - pq3 (multilingual) room 202
// when plotting crimes, allocates the returned bytes from kStrLen
// on "W" and "E" and wants to put a string in there, which doesn't
@@ -276,18 +279,22 @@ reg_t kMemory(EngineState *s, int argc, reg_t *argv) {
// - lsl5 (multilingual) room 280
// allocates memory according to a previous kStrLen for the name of
// the airport ladies (bug #3093818), which isn't enough
-
- // We always allocate 1 byte more, because of this
- byteCount++;
+ byteCount += 2 + (byteCount & 1);
if (!s->_segMan->allocDynmem(byteCount, "kMemory() critical", &s->r_acc)) {
error("Critical heap allocation failed");
}
break;
}
- case K_MEMORY_ALLOCATE_NONCRITICAL:
- s->_segMan->allocDynmem(argv[1].toUint16(), "kMemory() non-critical", &s->r_acc);
+ case K_MEMORY_ALLOCATE_NONCRITICAL: {
+ int byteCount = argv[1].toUint16();
+
+ // See above
+ byteCount += 2 + (byteCount & 1);
+
+ s->_segMan->allocDynmem(byteCount, "kMemory() non-critical", &s->r_acc);
break;
+ }
case K_MEMORY_FREE :
if (!s->_segMan->freeDynmem(argv[1])) {
if (g_sci->getGameId() == GID_QFG1VGA) {