From 050ec1ef31f0606132531dffeb4d3a5042f8b1a8 Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Mon, 8 Feb 2016 21:12:37 +0100 Subject: 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. --- engines/sci/engine/kmisc.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'engines/sci') 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) { -- cgit v1.2.3