[Scummvm-git-logs] scummvm master -> 869d57f042ff924c7edda6764021e159c63d05b5

mgerhardy martin.gerhardy at gmail.com
Tue Nov 3 21:34:13 UTC 2020


This automated email contains information about 6 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
15cb01c18c TWINE: fixed memory leak in holomap location loading
d2d49d398c TWINE: replaced magic number with constant and leave a todo comment
a45fa2d1b8 TWINE: prepare to move the life script parsing to stream
8e341f12b9 TWINE: additional sanity check
b89ed87578 TWINE: renamed script context classes
869d57f042 TWINE: converted the life script parsing to endian safe MemorySeekableReadWriteStream


Commit: 15cb01c18c7a01934aa521263789fe23786b0403
    https://github.com/scummvm/scummvm/commit/15cb01c18c7a01934aa521263789fe23786b0403
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T20:09:31+01:00

Commit Message:
TWINE: fixed memory leak in holomap location loading

Changed paths:
    engines/twine/holomap.cpp


diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index 04412e3dc8..6023515992 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -22,6 +22,7 @@
 
 #include "twine/holomap.h"
 #include "common/memstream.h"
+#include "common/types.h"
 #include "twine/gamestate.h"
 #include "twine/hqr.h"
 #include "twine/interface.h"
@@ -45,7 +46,7 @@ bool Holomap::loadLocations() {
 		return false;
 	}
 
-	Common::MemoryReadStream stream(locationsPtr, locationsSize);
+	Common::MemoryReadStream stream(locationsPtr, locationsSize, DisposeAfterUse::YES);
 	_numLocations = locationsSize / sizeof(Location);
 	if (_numLocations > NUM_LOCATIONS) {
 		warning("Amount of locations (%i) exceeds the maximum of %i", _numLocations, NUM_LOCATIONS);


Commit: d2d49d398c0699925c3e704b94be8457ddb79fbb
    https://github.com/scummvm/scummvm/commit/d2d49d398c0699925c3e704b94be8457ddb79fbb
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T20:12:15+01:00

Commit Message:
TWINE: replaced magic number with constant and leave a todo comment

Changed paths:
    engines/twine/script_life_v1.cpp


diff --git a/engines/twine/script_life_v1.cpp b/engines/twine/script_life_v1.cpp
index ef08c1cc15..4b3a6f60ee 100644
--- a/engines/twine/script_life_v1.cpp
+++ b/engines/twine/script_life_v1.cpp
@@ -1063,7 +1063,7 @@ static int32 lINC_CLOVER_BOX(TwinEEngine *engine, ScriptContext& ctx) {
 /*0x43*/
 static int32 lSET_USED_INVENTORY(TwinEEngine *engine, ScriptContext& ctx) {
 	int32 item = *(scriptPtr++);
-	if (item < 24) {
+	if (item < InventoryItems::kKeypad) { // TODO: this looks wrong - why only up to keypad?
 		engine->_gameState->inventoryFlags[item] = 1;
 	}
 	return 0;


Commit: a45fa2d1b87b659e6d326c7dbe709400ca6ad0a8
    https://github.com/scummvm/scummvm/commit/a45fa2d1b87b659e6d326c7dbe709400ca6ad0a8
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T20:19:33+01:00

Commit Message:
TWINE: prepare to move the life script parsing to stream

Changed paths:
    engines/twine/script_life_v1.cpp


diff --git a/engines/twine/script_life_v1.cpp b/engines/twine/script_life_v1.cpp
index 4b3a6f60ee..035ae03b2e 100644
--- a/engines/twine/script_life_v1.cpp
+++ b/engines/twine/script_life_v1.cpp
@@ -45,22 +45,21 @@
 
 namespace TwinE {
 
-static uint8 *scriptPtr; // local script pointer
-static uint8 *opcodePtr; // local opcode script pointer
-
 static int32 drawVar1;
 static char textStr[256]; // string
 
 struct ScriptContext {
 	int32 actorIdx;
 	ActorStruct *actor;
+	uint8 *scriptPtr; // local script pointer
+	uint8 *opcodePtr; // local opcode script pointer
 };
 
 /** Returns:
 	   -1 - Need implementation
 		0 - Completed
 		1 - Break script */
-typedef int32 ScriptLifeFunc(TwinEEngine *engine, ScriptContext& ctx);
+typedef int32 ScriptLifeFunc(TwinEEngine *engine, ScriptContext &ctx);
 
 struct ScriptLifeFunction {
 	const char *name;
@@ -118,9 +117,9 @@ enum LifeScriptConditions {
 	   -1 - Need implementation
 		1 - Condition value size (1 byte)
 		2 - Condition value size (2 byes) */
-static int32 processLifeConditions(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 processLifeConditions(TwinEEngine *engine, ScriptContext &ctx) {
 	int32 conditionValueSize = 1;
-	int32 conditionOpcode = *(scriptPtr++);
+	int32 conditionOpcode = *(ctx.scriptPtr++);
 
 	switch (conditionOpcode) {
 	case kcCOL:
@@ -131,7 +130,7 @@ static int32 processLifeConditions(TwinEEngine *engine, ScriptContext& ctx) {
 		}
 		break;
 	case kcCOL_OBJ: {
-		int32 actorIdx = *(scriptPtr++);
+		int32 actorIdx = *(ctx.scriptPtr++);
 		if (engine->_scene->getActor(actorIdx)->life <= 0) {
 			engine->_scene->currentScriptValue = -1;
 		} else {
@@ -140,7 +139,7 @@ static int32 processLifeConditions(TwinEEngine *engine, ScriptContext& ctx) {
 		break;
 	}
 	case kcDISTANCE: {
-		int32 actorIdx = *(scriptPtr++);
+		int32 actorIdx = *(ctx.scriptPtr++);
 		conditionValueSize = 2;
 		ActorStruct *otherActor = engine->_scene->getActor(actorIdx);
 		if (!otherActor->dynamicFlags.bIsDead) {
@@ -164,7 +163,7 @@ static int32 processLifeConditions(TwinEEngine *engine, ScriptContext& ctx) {
 		engine->_scene->currentScriptValue = ctx.actor->zone;
 		break;
 	case kcZONE_OBJ: {
-		int32 actorIdx = *(scriptPtr++);
+		int32 actorIdx = *(ctx.scriptPtr++);
 		engine->_scene->currentScriptValue = engine->_scene->getActor(actorIdx)->zone;
 		break;
 	}
@@ -172,7 +171,7 @@ static int32 processLifeConditions(TwinEEngine *engine, ScriptContext& ctx) {
 		engine->_scene->currentScriptValue = ctx.actor->body;
 		break;
 	case kcBODY_OBJ: {
-		int32 actorIdx = *(scriptPtr++);
+		int32 actorIdx = *(ctx.scriptPtr++);
 		engine->_scene->currentScriptValue = engine->_scene->getActor(actorIdx)->body;
 		break;
 	}
@@ -180,7 +179,7 @@ static int32 processLifeConditions(TwinEEngine *engine, ScriptContext& ctx) {
 		engine->_scene->currentScriptValue = ctx.actor->anim;
 		break;
 	case kcANIM_OBJ: {
-		int32 actorIdx = *(scriptPtr++);
+		int32 actorIdx = *(ctx.scriptPtr++);
 		engine->_scene->currentScriptValue = engine->_scene->getActor(actorIdx)->anim;
 		break;
 	}
@@ -188,18 +187,18 @@ static int32 processLifeConditions(TwinEEngine *engine, ScriptContext& ctx) {
 		engine->_scene->currentScriptValue = ctx.actor->labelIdx;
 		break;
 	case kcL_TRACK_OBJ: {
-		int32 actorIdx = *(scriptPtr++);
+		int32 actorIdx = *(ctx.scriptPtr++);
 		engine->_scene->currentScriptValue = engine->_scene->getActor(actorIdx)->labelIdx;
 		break;
 	}
 	case kcFLAG_CUBE: {
-		int32 flagIdx = *(scriptPtr++);
+		int32 flagIdx = *(ctx.scriptPtr++);
 		engine->_scene->currentScriptValue = engine->_scene->sceneFlags[flagIdx];
 		break;
 	}
 	case kcCONE_VIEW: {
 		int32 newAngle = 0;
-		int32 targetActorIdx = *(scriptPtr++);
+		int32 targetActorIdx = *(ctx.scriptPtr++);
 		ActorStruct *targetActor = engine->_scene->getActor(targetActorIdx);
 
 		conditionValueSize = 2;
@@ -252,7 +251,7 @@ static int32 processLifeConditions(TwinEEngine *engine, ScriptContext& ctx) {
 		engine->_scene->currentScriptValue = engine->_movements->heroAction ? 1 : 0;
 		break;
 	case kcFLAG_GAME: {
-		int32 flagIdx = *(scriptPtr++);
+		int32 flagIdx = *(ctx.scriptPtr++);
 		if (!engine->_gameState->gameFlags[GAMEFLAG_INVENTORY_DISABLED] ||
 		    (engine->_gameState->gameFlags[GAMEFLAG_INVENTORY_DISABLED] && flagIdx >= MaxInventoryItems)) {
 			engine->_scene->currentScriptValue = engine->_gameState->gameFlags[flagIdx];
@@ -269,7 +268,7 @@ static int32 processLifeConditions(TwinEEngine *engine, ScriptContext& ctx) {
 		engine->_scene->currentScriptValue = ctx.actor->life;
 		break;
 	case kcLIFE_POINT_OBJ: {
-		int32 actorIdx = *(scriptPtr++);
+		int32 actorIdx = *(ctx.scriptPtr++);
 		engine->_scene->currentScriptValue = engine->_scene->getActor(actorIdx)->life;
 		break;
 	}
@@ -290,7 +289,7 @@ static int32 processLifeConditions(TwinEEngine *engine, ScriptContext& ctx) {
 		int32 targetActorIdx;
 		ActorStruct *targetActor;
 
-		targetActorIdx = *(scriptPtr++);
+		targetActorIdx = *(ctx.scriptPtr++);
 		targetActor = engine->_scene->getActor(targetActorIdx);
 
 		conditionValueSize = 2;
@@ -312,7 +311,7 @@ static int32 processLifeConditions(TwinEEngine *engine, ScriptContext& ctx) {
 	case 24:
 		break;
 	case kcUSE_INVENTORY: {
-		int32 item = *(scriptPtr++);
+		int32 item = *(ctx.scriptPtr++);
 
 		if (!engine->_gameState->gameFlags[GAMEFLAG_INVENTORY_DISABLED]) {
 			if (item == engine->loopInventoryItem) {
@@ -358,15 +357,15 @@ static int32 processLifeConditions(TwinEEngine *engine, ScriptContext& ctx) {
 	   -1 - Need implementation
 		0 - Condition false
 		1 - Condition true */
-static int32 processLifeOperators(TwinEEngine *engine, int32 valueSize) {
-	const int32 operatorCode = *(scriptPtr++);
+static int32 processLifeOperators(TwinEEngine *engine, ScriptContext &ctx, int32 valueSize) {
+	const int32 operatorCode = *(ctx.scriptPtr++);
 
 	int32 conditionValue;
 	if (valueSize == 1) {
-		conditionValue = *(scriptPtr++);
+		conditionValue = *(ctx.scriptPtr++);
 	} else if (valueSize == 2) {
-		conditionValue = *((int16 *)scriptPtr);
-		scriptPtr += 2;
+		conditionValue = *((int16 *)ctx.scriptPtr);
+		ctx.scriptPtr += 2;
 	} else {
 		error("Unknown operator value size %d\n", valueSize);
 		return 0;
@@ -414,171 +413,171 @@ static int32 processLifeOperators(TwinEEngine *engine, int32 valueSize) {
 /** Life script command definitions */
 
 /* For unused opcodes */
-static int32 lEMPTY(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lEMPTY(TwinEEngine *engine, ScriptContext &ctx) {
 	return 0;
 }
 
 /*0x00*/
-static int32 lEND(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lEND(TwinEEngine *engine, ScriptContext &ctx) {
 	ctx.actor->positionInLifeScript = -1;
 	return 1; // break script
 }
 
 /*0x01*/
-static int32 lNOP(TwinEEngine *engine, ScriptContext& ctx) {
-	scriptPtr++;
+static int32 lNOP(TwinEEngine *engine, ScriptContext &ctx) {
+	ctx.scriptPtr++;
 	return 0;
 }
 
 /*0x02*/
-static int32 lSNIF(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lSNIF(TwinEEngine *engine, ScriptContext &ctx) {
 	const int32 valueSize = processLifeConditions(engine, ctx);
-	if (!processLifeOperators(engine, valueSize)) {
-		*opcodePtr = 0x0D; // SWIF
+	if (!processLifeOperators(engine, ctx, valueSize)) {
+		*ctx.opcodePtr = 0x0D; // SWIF
 	}
-	scriptPtr = ctx.actor->lifeScript + *((int16 *)scriptPtr); // condition offset
+	ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // condition offset
 	return 0;
 }
 
 /*0x03*/
-static int32 lOFFSET(TwinEEngine *engine, ScriptContext& ctx) {
-	scriptPtr = ctx.actor->lifeScript + *((int16 *)scriptPtr); // offset
+static int32 lOFFSET(TwinEEngine *engine, ScriptContext &ctx) {
+	ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // offset
 	return 0;
 }
 
 /*0x04*/
-static int32 lNEVERIF(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lNEVERIF(TwinEEngine *engine, ScriptContext &ctx) {
 	int32 valueSize = processLifeConditions(engine, ctx);
-	processLifeOperators(engine, valueSize);
-	scriptPtr = ctx.actor->lifeScript + *((int16 *)scriptPtr); // condition offset
+	processLifeOperators(engine, ctx, valueSize);
+	ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // condition offset
 	return 0;
 }
 
 /*0x06*/
-static int32 lNO_IF(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lNO_IF(TwinEEngine *engine, ScriptContext &ctx) {
 	return 0;
 }
 
 /*0x0A*/
-static int32 lLABEL(TwinEEngine *engine, ScriptContext& ctx) {
-	scriptPtr++;
+static int32 lLABEL(TwinEEngine *engine, ScriptContext &ctx) {
+	ctx.scriptPtr++;
 	return 0;
 }
 
 /*0x0B*/
-static int32 lRETURN(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lRETURN(TwinEEngine *engine, ScriptContext &ctx) {
 	return 1; // break script
 }
 
 /*0x0C*/
-static int32 lIF(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lIF(TwinEEngine *engine, ScriptContext &ctx) {
 	int32 valueSize = processLifeConditions(engine, ctx);
-	if (!processLifeOperators(engine, valueSize)) {
-		scriptPtr = ctx.actor->lifeScript + *((int16 *)scriptPtr); // condition offset
+	if (!processLifeOperators(engine, ctx, valueSize)) {
+		ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // condition offset
 	} else {
-		scriptPtr += 2;
+		ctx.scriptPtr += 2;
 	}
 
 	return 0;
 }
 
 /*0x0D*/
-static int32 lSWIF(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lSWIF(TwinEEngine *engine, ScriptContext &ctx) {
 	int32 valueSize = processLifeConditions(engine, ctx);
-	if (!processLifeOperators(engine, valueSize)) {
-		scriptPtr = ctx.actor->lifeScript + *((int16 *)scriptPtr); // condition offset
+	if (!processLifeOperators(engine, ctx, valueSize)) {
+		ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // condition offset
 	} else {
-		scriptPtr += 2;
-		*opcodePtr = 0x02; // SNIF
+		ctx.scriptPtr += 2;
+		*ctx.opcodePtr = 0x02; // SNIF
 	}
 
 	return 0;
 }
 
 /*0x0E*/
-static int32 lONEIF(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lONEIF(TwinEEngine *engine, ScriptContext &ctx) {
 	int32 valueSize = processLifeConditions(engine, ctx);
-	if (!processLifeOperators(engine, valueSize)) {
-		scriptPtr = ctx.actor->lifeScript + *((int16 *)scriptPtr); // condition offset
+	if (!processLifeOperators(engine, ctx, valueSize)) {
+		ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // condition offset
 	} else {
-		scriptPtr += 2;
-		*opcodePtr = 0x04; // NEVERIF
+		ctx.scriptPtr += 2;
+		*ctx.opcodePtr = 0x04; // NEVERIF
 	}
 
 	return 0;
 }
 
 /*0x0F*/
-static int32 lELSE(TwinEEngine *engine, ScriptContext& ctx) {
-	scriptPtr = ctx.actor->lifeScript + *((int16 *)scriptPtr); // offset
+static int32 lELSE(TwinEEngine *engine, ScriptContext &ctx) {
+	ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // offset
 	return 0;
 }
 
 /*0x11*/
-static int32 lBODY(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 bodyIdx = *(scriptPtr);
+static int32 lBODY(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 bodyIdx = *(ctx.scriptPtr);
 	engine->_actor->initModelActor(bodyIdx, ctx.actorIdx);
-	scriptPtr++;
+	ctx.scriptPtr++;
 	return 0;
 }
 
 /*0x12*/
-static int32 lBODY_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 otherActorIdx = *(scriptPtr++);
-	int32 otherBodyIdx = *(scriptPtr++);
+static int32 lBODY_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 otherActorIdx = *(ctx.scriptPtr++);
+	int32 otherBodyIdx = *(ctx.scriptPtr++);
 	engine->_actor->initModelActor(otherBodyIdx, otherActorIdx);
 	return 0;
 }
 
 /*0x13*/
-static int32 lANIM(TwinEEngine *engine, ScriptContext& ctx) {
-	AnimationTypes animIdx = (AnimationTypes)*(scriptPtr++);
+static int32 lANIM(TwinEEngine *engine, ScriptContext &ctx) {
+	AnimationTypes animIdx = (AnimationTypes) * (ctx.scriptPtr++);
 	engine->_animations->initAnim(animIdx, 0, 0, ctx.actorIdx);
 	return 0;
 }
 
 /*0x14*/
-static int32 lANIM_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 otherActorIdx = *(scriptPtr++);
-	AnimationTypes otherAnimIdx = (AnimationTypes)*(scriptPtr++);
+static int32 lANIM_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 otherActorIdx = *(ctx.scriptPtr++);
+	AnimationTypes otherAnimIdx = (AnimationTypes) * (ctx.scriptPtr++);
 	engine->_animations->initAnim(otherAnimIdx, 0, 0, otherActorIdx);
 	return 0;
 }
 
 /*0x15*/
-static int32 lSET_LIFE(TwinEEngine *engine, ScriptContext& ctx) {
-	ctx.actor->positionInLifeScript = *((int16 *)scriptPtr); // offset
-	scriptPtr += 2;
+static int32 lSET_LIFE(TwinEEngine *engine, ScriptContext &ctx) {
+	ctx.actor->positionInLifeScript = *((int16 *)ctx.scriptPtr); // offset
+	ctx.scriptPtr += 2;
 	return 0;
 }
 
 /*0x16*/
-static int32 lSET_LIFE_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 otherActorIdx = *(scriptPtr++);
-	engine->_scene->getActor(otherActorIdx)->positionInLifeScript = *((int16 *)scriptPtr); // offset
-	scriptPtr += 2;
+static int32 lSET_LIFE_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 otherActorIdx = *(ctx.scriptPtr++);
+	engine->_scene->getActor(otherActorIdx)->positionInLifeScript = *((int16 *)ctx.scriptPtr); // offset
+	ctx.scriptPtr += 2;
 	return 0;
 }
 
 /*0x17*/
-static int32 lSET_TRACK(TwinEEngine *engine, ScriptContext& ctx) {
-	ctx.actor->positionInMoveScript = *((int16 *)scriptPtr); // offset
-	scriptPtr += 2;
+static int32 lSET_TRACK(TwinEEngine *engine, ScriptContext &ctx) {
+	ctx.actor->positionInMoveScript = *((int16 *)ctx.scriptPtr); // offset
+	ctx.scriptPtr += 2;
 	return 0;
 }
 
 /*0x18*/
-static int32 lSET_TRACK_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 otherActorIdx = *(scriptPtr++);
-	engine->_scene->getActor(otherActorIdx)->positionInMoveScript = *((int16 *)scriptPtr); // offset
-	scriptPtr += 2;
+static int32 lSET_TRACK_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 otherActorIdx = *(ctx.scriptPtr++);
+	engine->_scene->getActor(otherActorIdx)->positionInMoveScript = *((int16 *)ctx.scriptPtr); // offset
+	ctx.scriptPtr += 2;
 	return 0;
 }
 
 /*0x19*/
-static int32 lMESSAGE(TwinEEngine *engine, ScriptContext& ctx) {
-	const int32 textIdx = *((int16 *)scriptPtr);
-	scriptPtr += 2;
+static int32 lMESSAGE(TwinEEngine *engine, ScriptContext &ctx) {
+	const int32 textIdx = *((int16 *)ctx.scriptPtr);
+	ctx.scriptPtr += 2;
 
 	engine->freezeTime();
 	if (engine->_text->showDialogueBubble) {
@@ -594,41 +593,41 @@ static int32 lMESSAGE(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x1A*/
-static int32 lFALLABLE(TwinEEngine *engine, ScriptContext& ctx) {
-	const int32 flag = *(scriptPtr++);
+static int32 lFALLABLE(TwinEEngine *engine, ScriptContext &ctx) {
+	const int32 flag = *(ctx.scriptPtr++);
 	ctx.actor->staticFlags.bCanFall = flag & 1;
 	return 0;
 }
 
 /*0x1B*/
-static int32 lSET_DIRMODE(TwinEEngine *engine, ScriptContext& ctx) {
-	const int32 controlMode = *(scriptPtr++);
+static int32 lSET_DIRMODE(TwinEEngine *engine, ScriptContext &ctx) {
+	const int32 controlMode = *(ctx.scriptPtr++);
 
 	ctx.actor->controlMode = (ControlMode)controlMode;
 	if (ctx.actor->controlMode == ControlMode::kFollow) {
-		ctx.actor->followedActor = *(scriptPtr++);
+		ctx.actor->followedActor = *(ctx.scriptPtr++);
 	}
 
 	return 0;
 }
 
 /*0x1C*/
-static int32 lSET_DIRMODE_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
-	const int32 otherActorIdx = *(scriptPtr++);
-	const int32 controlMode = *(scriptPtr++);
+static int32 lSET_DIRMODE_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+	const int32 otherActorIdx = *(ctx.scriptPtr++);
+	const int32 controlMode = *(ctx.scriptPtr++);
 
 	ActorStruct *otherActor = engine->_scene->getActor(otherActorIdx);
 	otherActor->controlMode = (ControlMode)controlMode;
 	if (otherActor->controlMode == ControlMode::kFollow) {
-		otherActor->followedActor = *(scriptPtr++);
+		otherActor->followedActor = *(ctx.scriptPtr++);
 	}
 
 	return 0;
 }
 
 /*0x1D*/
-static int32 lCAM_FOLLOW(TwinEEngine *engine, ScriptContext& ctx) {
-	const int32 followedActorIdx = *(scriptPtr++);
+static int32 lCAM_FOLLOW(TwinEEngine *engine, ScriptContext &ctx) {
+	const int32 followedActorIdx = *(ctx.scriptPtr++);
 
 	if (engine->_scene->currentlyFollowedActor != followedActorIdx) {
 		const ActorStruct *followedActor = engine->_scene->getActor(followedActorIdx);
@@ -644,8 +643,8 @@ static int32 lCAM_FOLLOW(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x1E*/
-static int32 lSET_BEHAVIOUR(TwinEEngine *engine, ScriptContext& ctx) {
-	const int32 behavior = *(scriptPtr++);
+static int32 lSET_BEHAVIOUR(TwinEEngine *engine, ScriptContext &ctx) {
+	const int32 behavior = *(ctx.scriptPtr++);
 
 	engine->_animations->initAnim(kStanding, 0, 255, 0);
 	engine->_actor->setBehaviour(behavior);
@@ -654,9 +653,9 @@ static int32 lSET_BEHAVIOUR(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x1F*/
-static int32 lSET_FLAG_CUBE(TwinEEngine *engine, ScriptContext& ctx) {
-	const int32 flagIdx = *(scriptPtr++);
-	const int32 flagValue = *(scriptPtr++);
+static int32 lSET_FLAG_CUBE(TwinEEngine *engine, ScriptContext &ctx) {
+	const int32 flagIdx = *(ctx.scriptPtr++);
+	const int32 flagValue = *(ctx.scriptPtr++);
 
 	engine->_scene->sceneFlags[flagIdx] = flagValue;
 
@@ -664,37 +663,37 @@ static int32 lSET_FLAG_CUBE(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x20*/
-static int32 lCOMPORTEMENT(TwinEEngine *engine, ScriptContext& ctx) {
-	scriptPtr++;
+static int32 lCOMPORTEMENT(TwinEEngine *engine, ScriptContext &ctx) {
+	ctx.scriptPtr++;
 	return 0;
 }
 
 /*0x21*/
-static int32 lSET_COMPORTEMENT(TwinEEngine *engine, ScriptContext& ctx) {
-	ctx.actor->positionInLifeScript = *((int16 *)scriptPtr);
-	scriptPtr += 2;
+static int32 lSET_COMPORTEMENT(TwinEEngine *engine, ScriptContext &ctx) {
+	ctx.actor->positionInLifeScript = *((int16 *)ctx.scriptPtr);
+	ctx.scriptPtr += 2;
 	return 0;
 }
 
 /*0x22*/
-static int32 lSET_COMPORTEMENT_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
-	const int32 otherActorIdx = *(scriptPtr++);
+static int32 lSET_COMPORTEMENT_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+	const int32 otherActorIdx = *(ctx.scriptPtr++);
 
-	engine->_scene->getActor(otherActorIdx)->positionInLifeScript = *((int16 *)scriptPtr);
-	scriptPtr += 2;
+	engine->_scene->getActor(otherActorIdx)->positionInLifeScript = *((int16 *)ctx.scriptPtr);
+	ctx.scriptPtr += 2;
 
 	return 0;
 }
 
 /*0x23*/
-static int32 lEND_COMPORTEMENT(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lEND_COMPORTEMENT(TwinEEngine *engine, ScriptContext &ctx) {
 	return 1; // break
 }
 
 /*0x24*/
-static int32 lSET_FLAG_GAME(TwinEEngine *engine, ScriptContext& ctx) {
-	const int32 flagIdx = *(scriptPtr++);
-	const int32 flagValue = *(scriptPtr++);
+static int32 lSET_FLAG_GAME(TwinEEngine *engine, ScriptContext &ctx) {
+	const int32 flagIdx = *(ctx.scriptPtr++);
+	const int32 flagValue = *(ctx.scriptPtr++);
 
 	engine->_gameState->gameFlags[flagIdx] = flagValue;
 
@@ -702,11 +701,11 @@ static int32 lSET_FLAG_GAME(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x25*/
-static int32 lKILL_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
-	const int32 otherActorIdx = *(scriptPtr++);
+static int32 lKILL_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+	const int32 otherActorIdx = *(ctx.scriptPtr++);
 
 	engine->_actor->processActorCarrier(otherActorIdx);
-	ActorStruct* otherActor = engine->_scene->getActor(otherActorIdx);
+	ActorStruct *otherActor = engine->_scene->getActor(otherActorIdx);
 	otherActor->dynamicFlags.bIsDead = 1;
 	otherActor->entity = -1;
 	otherActor->zone = -1;
@@ -716,7 +715,7 @@ static int32 lKILL_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x26*/
-static int32 lSUICIDE(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lSUICIDE(TwinEEngine *engine, ScriptContext &ctx) {
 	engine->_actor->processActorCarrier(ctx.actorIdx);
 	ctx.actor->dynamicFlags.bIsDead = 1;
 	ctx.actor->entity = -1;
@@ -727,7 +726,7 @@ static int32 lSUICIDE(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x27*/
-static int32 lUSE_ONE_LITTLE_KEY(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lUSE_ONE_LITTLE_KEY(TwinEEngine *engine, ScriptContext &ctx) {
 	engine->_gameState->inventoryNumKeys--;
 
 	if (engine->_gameState->inventoryNumKeys < 0) {
@@ -740,11 +739,11 @@ static int32 lUSE_ONE_LITTLE_KEY(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x28*/
-static int32 lGIVE_GOLD_PIECES(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lGIVE_GOLD_PIECES(TwinEEngine *engine, ScriptContext &ctx) {
 	int16 oldNumKashes = engine->_gameState->inventoryNumKashes;
 	bool hideRange = false;
-	int16 kashes = *((int16 *)scriptPtr);
-	scriptPtr += 2;
+	int16 kashes = *((int16 *)ctx.scriptPtr);
+	ctx.scriptPtr += 2;
 
 	engine->_gameState->inventoryNumKashes -= kashes;
 	if (engine->_gameState->inventoryNumKashes < 0) {
@@ -772,29 +771,29 @@ static int32 lGIVE_GOLD_PIECES(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x29*/
-static int32 lEND_LIFE(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lEND_LIFE(TwinEEngine *engine, ScriptContext &ctx) {
 	ctx.actor->positionInLifeScript = -1;
 	return 1; // break;
 }
 
 /*0x2A*/
-static int32 lSTOP_L_TRACK(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lSTOP_L_TRACK(TwinEEngine *engine, ScriptContext &ctx) {
 	ctx.actor->pausedTrackPtr = ctx.actor->currentLabelPtr;
 	ctx.actor->positionInMoveScript = -1;
 	return 0;
 }
 
 /*0x2B*/
-static int32 lRESTORE_L_TRACK(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lRESTORE_L_TRACK(TwinEEngine *engine, ScriptContext &ctx) {
 	ctx.actor->positionInMoveScript = ctx.actor->pausedTrackPtr;
 	return 0;
 }
 
 /*0x2C*/
-static int32 lMESSAGE_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
-	const int32 otherActorIdx = *(scriptPtr++);
-	const int32 textIdx = *((int16 *)scriptPtr);
-	scriptPtr += 2;
+static int32 lMESSAGE_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+	const int32 otherActorIdx = *(ctx.scriptPtr++);
+	const int32 textIdx = *((int16 *)ctx.scriptPtr);
+	ctx.scriptPtr += 2;
 
 	engine->freezeTime();
 	if (engine->_text->showDialogueBubble) {
@@ -810,14 +809,14 @@ static int32 lMESSAGE_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x2D*/
-static int32 lINC_CHAPTER(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lINC_CHAPTER(TwinEEngine *engine, ScriptContext &ctx) {
 	engine->_gameState->gameChapter++;
 	return 0;
 }
 
 /*0x2E*/
-static int32 lFOUND_OBJECT(TwinEEngine *engine, ScriptContext& ctx) {
-	const int32 item = *(scriptPtr++);
+static int32 lFOUND_OBJECT(TwinEEngine *engine, ScriptContext &ctx) {
+	const int32 item = *(ctx.scriptPtr++);
 
 	engine->freezeTime();
 	engine->_gameState->processFoundItem(item);
@@ -828,9 +827,9 @@ static int32 lFOUND_OBJECT(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x2F*/
-static int32 lSET_DOOR_LEFT(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 distance = *((int16 *)scriptPtr);
-	scriptPtr += 2;
+static int32 lSET_DOOR_LEFT(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 distance = *((int16 *)ctx.scriptPtr);
+	ctx.scriptPtr += 2;
 
 	ctx.actor->angle = 0x300;
 	ctx.actor->x = ctx.actor->lastX - distance;
@@ -841,9 +840,9 @@ static int32 lSET_DOOR_LEFT(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x30*/
-static int32 lSET_DOOR_RIGHT(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 distance = *((int16 *)scriptPtr);
-	scriptPtr += 2;
+static int32 lSET_DOOR_RIGHT(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 distance = *((int16 *)ctx.scriptPtr);
+	ctx.scriptPtr += 2;
 
 	ctx.actor->angle = 0x100;
 	ctx.actor->x = ctx.actor->lastX + distance;
@@ -854,9 +853,9 @@ static int32 lSET_DOOR_RIGHT(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x31*/
-static int32 lSET_DOOR_UP(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 distance = *((int16 *)scriptPtr);
-	scriptPtr += 2;
+static int32 lSET_DOOR_UP(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 distance = *((int16 *)ctx.scriptPtr);
+	ctx.scriptPtr += 2;
 
 	ctx.actor->angle = 0x200;
 	ctx.actor->z = ctx.actor->lastZ - distance;
@@ -867,9 +866,9 @@ static int32 lSET_DOOR_UP(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x32*/
-static int32 lSET_DOOR_DOWN(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 distance = *((int16 *)scriptPtr);
-	scriptPtr += 2;
+static int32 lSET_DOOR_DOWN(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 distance = *((int16 *)ctx.scriptPtr);
+	ctx.scriptPtr += 2;
 
 	ctx.actor->angle = 0;
 	ctx.actor->z = ctx.actor->lastZ + distance;
@@ -880,8 +879,8 @@ static int32 lSET_DOOR_DOWN(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x33*/
-static int32 lGIVE_BONUS(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 flag = *(scriptPtr++);
+static int32 lGIVE_BONUS(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 flag = *(ctx.scriptPtr++);
 
 	if (ctx.actor->bonusParameter & 0x1F0) {
 		engine->_actor->processActorExtraBonus(ctx.actorIdx);
@@ -895,16 +894,16 @@ static int32 lGIVE_BONUS(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x34*/
-static int32 lCHANGE_CUBE(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 sceneIdx = *(scriptPtr++);
+static int32 lCHANGE_CUBE(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 sceneIdx = *(ctx.scriptPtr++);
 	engine->_scene->needChangeScene = sceneIdx;
 	engine->_scene->heroPositionType = ScenePositionType::kScene;
 	return 0;
 }
 
 /*0x35*/
-static int32 lOBJ_COL(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 collision = *(scriptPtr++);
+static int32 lOBJ_COL(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 collision = *(ctx.scriptPtr++);
 	if (collision != 0) {
 		ctx.actor->staticFlags.bComputeCollisionWithObj = 1;
 	} else {
@@ -914,8 +913,8 @@ static int32 lOBJ_COL(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x36*/
-static int32 lBRICK_COL(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 collision = *(scriptPtr++);
+static int32 lBRICK_COL(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 collision = *(ctx.scriptPtr++);
 
 	ctx.actor->staticFlags.bComputeCollisionWithBricks = 0;
 	ctx.actor->staticFlags.bComputeLowCollision = 0;
@@ -930,26 +929,26 @@ static int32 lBRICK_COL(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x37*/
-static int32 lOR_IF(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lOR_IF(TwinEEngine *engine, ScriptContext &ctx) {
 	int32 valueSize = processLifeConditions(engine, ctx);
-	if (processLifeOperators(engine, valueSize)) {
-		scriptPtr = ctx.actor->lifeScript + *((int16 *)scriptPtr); // condition offset
+	if (processLifeOperators(engine, ctx, valueSize)) {
+		ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // condition offset
 	} else {
-		scriptPtr += 2;
+		ctx.scriptPtr += 2;
 	}
 
 	return 0;
 }
 
 /*0x38*/
-static int32 lINVISIBLE(TwinEEngine *engine, ScriptContext& ctx) {
-	ctx.actor->staticFlags.bIsHidden = *(scriptPtr++);
+static int32 lINVISIBLE(TwinEEngine *engine, ScriptContext &ctx) {
+	ctx.actor->staticFlags.bIsHidden = *(ctx.scriptPtr++);
 	return 0;
 }
 
 /*0x39*/
-static int32 lZOOM(TwinEEngine *engine, ScriptContext& ctx) {
-	engine->zoomScreen = *(scriptPtr++);
+static int32 lZOOM(TwinEEngine *engine, ScriptContext &ctx) {
+	engine->zoomScreen = *(ctx.scriptPtr++);
 
 	if (engine->zoomScreen && !engine->_redraw->drawInGameTransBox && engine->cfgfile.SceZoom) {
 		engine->_screens->fadeToBlack(engine->_screens->mainPaletteRGBA);
@@ -968,8 +967,8 @@ static int32 lZOOM(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x3A*/
-static int32 lPOS_POINT(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 trackIdx = *(scriptPtr++);
+static int32 lPOS_POINT(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 trackIdx = *(ctx.scriptPtr++);
 
 	const ScenePoint &sp = engine->_scene->sceneTracks[trackIdx];
 	engine->_renderer->destX = sp.x;
@@ -984,15 +983,15 @@ static int32 lPOS_POINT(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x3B*/
-static int32 lSET_MAGIC_LEVEL(TwinEEngine *engine, ScriptContext& ctx) {
-	engine->_gameState->magicLevelIdx = *(scriptPtr++);
+static int32 lSET_MAGIC_LEVEL(TwinEEngine *engine, ScriptContext &ctx) {
+	engine->_gameState->magicLevelIdx = *(ctx.scriptPtr++);
 	engine->_gameState->inventoryMagicPoints = engine->_gameState->magicLevelIdx * 20;
 	return 0;
 }
 
 /*0x3C*/
-static int32 lSUB_MAGIC_POINT(TwinEEngine *engine, ScriptContext& ctx) {
-	engine->_gameState->inventoryMagicPoints = *(scriptPtr++);
+static int32 lSUB_MAGIC_POINT(TwinEEngine *engine, ScriptContext &ctx) {
+	engine->_gameState->inventoryMagicPoints = *(ctx.scriptPtr++);
 	if (engine->_gameState->inventoryMagicPoints < 0) {
 		engine->_gameState->inventoryMagicPoints = 0;
 	}
@@ -1000,9 +999,9 @@ static int32 lSUB_MAGIC_POINT(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x3D*/
-static int32 lSET_LIFE_POINT_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 otherActorIdx = *(scriptPtr++);
-	static int32 lifeValue = *(scriptPtr++);
+static int32 lSET_LIFE_POINT_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 otherActorIdx = *(ctx.scriptPtr++);
+	static int32 lifeValue = *(ctx.scriptPtr++);
 
 	engine->_scene->getActor(otherActorIdx)->life = lifeValue;
 
@@ -1010,9 +1009,9 @@ static int32 lSET_LIFE_POINT_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x3E*/
-static int32 lSUB_LIFE_POINT_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 otherActorIdx = *(scriptPtr++);
-	static int32 lifeValue = *(scriptPtr++);
+static int32 lSUB_LIFE_POINT_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 otherActorIdx = *(ctx.scriptPtr++);
+	static int32 lifeValue = *(ctx.scriptPtr++);
 
 	engine->_scene->getActor(otherActorIdx)->life -= lifeValue;
 
@@ -1024,18 +1023,18 @@ static int32 lSUB_LIFE_POINT_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x3F*/
-static int32 lHIT_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 otherActorIdx = *(scriptPtr++);
-	int32 strengthOfHit = *(scriptPtr++);
+static int32 lHIT_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 otherActorIdx = *(ctx.scriptPtr++);
+	int32 strengthOfHit = *(ctx.scriptPtr++);
 	engine->_actor->hitActor(ctx.actorIdx, otherActorIdx, strengthOfHit, engine->_scene->getActor(otherActorIdx)->angle);
 	return 0;
 }
 
 /*0x40*/
-static int32 lPLAY_FLA(TwinEEngine *engine, ScriptContext& ctx) {
-	const char *movie = (const char *)scriptPtr;
+static int32 lPLAY_FLA(TwinEEngine *engine, ScriptContext &ctx) {
+	const char *movie = (const char *)ctx.scriptPtr;
 	int32 nameSize = strlen(movie);
-	scriptPtr += nameSize + 1;
+	ctx.scriptPtr += nameSize + 1;
 
 	engine->_flaMovies->playFlaMovie(movie);
 	engine->setPalette(engine->_screens->paletteRGBA);
@@ -1046,14 +1045,14 @@ static int32 lPLAY_FLA(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x41*/
-static int32 lPLAY_MIDI(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 midiIdx = *(scriptPtr++);
+static int32 lPLAY_MIDI(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 midiIdx = *(ctx.scriptPtr++);
 	engine->_music->playMidiMusic(midiIdx); // TODO: improve this
 	return 0;
 }
 
 /*0x42*/
-static int32 lINC_CLOVER_BOX(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lINC_CLOVER_BOX(TwinEEngine *engine, ScriptContext &ctx) {
 	if (engine->_gameState->inventoryNumLeafsBox < 10) {
 		engine->_gameState->inventoryNumLeafsBox++;
 	}
@@ -1061,8 +1060,8 @@ static int32 lINC_CLOVER_BOX(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x43*/
-static int32 lSET_USED_INVENTORY(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 item = *(scriptPtr++);
+static int32 lSET_USED_INVENTORY(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 item = *(ctx.scriptPtr++);
 	if (item < InventoryItems::kKeypad) { // TODO: this looks wrong - why only up to keypad?
 		engine->_gameState->inventoryFlags[item] = 1;
 	}
@@ -1070,17 +1069,17 @@ static int32 lSET_USED_INVENTORY(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x44*/
-static int32 lADD_CHOICE(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 choiceIdx = *((int16 *)scriptPtr);
-	scriptPtr += 2;
+static int32 lADD_CHOICE(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 choiceIdx = *((int16 *)ctx.scriptPtr);
+	ctx.scriptPtr += 2;
 	engine->_gameState->gameChoices[engine->_gameState->numChoices++] = choiceIdx;
 	return 0;
 }
 
 /*0x45*/
-static int32 lASK_CHOICE(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 choiceIdx = *((int16 *)scriptPtr);
-	scriptPtr += 2;
+static int32 lASK_CHOICE(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 choiceIdx = *((int16 *)ctx.scriptPtr);
+	ctx.scriptPtr += 2;
 
 	engine->freezeTime();
 	if (engine->_text->showDialogueBubble) {
@@ -1096,9 +1095,9 @@ static int32 lASK_CHOICE(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x46*/
-static int32 lBIG_MESSAGE(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 textIdx = *((int16 *)scriptPtr);
-	scriptPtr += 2;
+static int32 lBIG_MESSAGE(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 textIdx = *((int16 *)ctx.scriptPtr);
+	ctx.scriptPtr += 2;
 
 	engine->freezeTime();
 	engine->_text->textClipFull();
@@ -1116,8 +1115,8 @@ static int32 lBIG_MESSAGE(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x47*/
-static int32 lINIT_PINGOUIN(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 pingouinActor = *(scriptPtr++);
+static int32 lINIT_PINGOUIN(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 pingouinActor = *(ctx.scriptPtr++);
 	engine->_scene->mecaPinguinIdx = pingouinActor;
 	ActorStruct *mecaPinguin = engine->_scene->getActor(pingouinActor);
 	mecaPinguin->dynamicFlags.bIsDead = 1;
@@ -1127,8 +1126,8 @@ static int32 lINIT_PINGOUIN(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x48*/
-static int32 lSET_HOLO_POS(TwinEEngine *engine, ScriptContext& ctx) {
-	static int32 location = *(scriptPtr++);
+static int32 lSET_HOLO_POS(TwinEEngine *engine, ScriptContext &ctx) {
+	static int32 location = *(ctx.scriptPtr++);
 	engine->_holomap->setHolomapPosition(location);
 	if (engine->_gameState->gameFlags[InventoryItems::kiHolomap]) {
 		engine->_redraw->addOverlay(koInventoryItem, 0, 0, 0, 0, koNormal, 3);
@@ -1138,15 +1137,15 @@ static int32 lSET_HOLO_POS(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x49*/
-static int32 lCLR_HOLO_POS(TwinEEngine *engine, ScriptContext& ctx) {
-	static int32 location = *(scriptPtr++);
+static int32 lCLR_HOLO_POS(TwinEEngine *engine, ScriptContext &ctx) {
+	static int32 location = *(ctx.scriptPtr++);
 	engine->_holomap->clearHolomapPosition(location);
 	return 0;
 }
 
 /*0x4A*/
-static int32 lADD_FUEL(TwinEEngine *engine, ScriptContext& ctx) {
-	engine->_gameState->inventoryNumGas += *(scriptPtr++);
+static int32 lADD_FUEL(TwinEEngine *engine, ScriptContext &ctx) {
+	engine->_gameState->inventoryNumGas += *(ctx.scriptPtr++);
 	if (engine->_gameState->inventoryNumGas > 100) {
 		engine->_gameState->inventoryNumGas = 100;
 	}
@@ -1154,8 +1153,8 @@ static int32 lADD_FUEL(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x4B*/
-static int32 lSUB_FUEL(TwinEEngine *engine, ScriptContext& ctx) {
-	engine->_gameState->inventoryNumGas -= *(scriptPtr++);
+static int32 lSUB_FUEL(TwinEEngine *engine, ScriptContext &ctx) {
+	engine->_gameState->inventoryNumGas -= *(ctx.scriptPtr++);
 	if (engine->_gameState->inventoryNumGas < 0) {
 		engine->_gameState->inventoryNumGas = 0;
 	}
@@ -1163,16 +1162,16 @@ static int32 lSUB_FUEL(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x4C*/
-static int32 lSET_GRM(TwinEEngine *engine, ScriptContext& ctx) {
-	engine->_grid->cellingGridIdx = *(scriptPtr++);
+static int32 lSET_GRM(TwinEEngine *engine, ScriptContext &ctx) {
+	engine->_grid->cellingGridIdx = *(ctx.scriptPtr++);
 	engine->_grid->initCellingGrid(engine->_grid->cellingGridIdx);
 	return 0;
 }
 
 /*0x4D*/
-static int32 lSAY_MESSAGE(TwinEEngine *engine, ScriptContext& ctx) {
-	int16 textEntry = *((int16 *)scriptPtr);
-	scriptPtr += 2;
+static int32 lSAY_MESSAGE(TwinEEngine *engine, ScriptContext &ctx) {
+	int16 textEntry = *((int16 *)ctx.scriptPtr);
+	ctx.scriptPtr += 2;
 
 	engine->_redraw->addOverlay(koText, textEntry, 0, 0, ctx.actorIdx, koFollowActor, 2);
 
@@ -1183,10 +1182,10 @@ static int32 lSAY_MESSAGE(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*04E*/
-static int32 lSAY_MESSAGE_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 otherActorIdx = *(scriptPtr++);
-	int16 textEntry = *((int16 *)scriptPtr);
-	scriptPtr += 2;
+static int32 lSAY_MESSAGE_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 otherActorIdx = *(ctx.scriptPtr++);
+	int16 textEntry = *((int16 *)ctx.scriptPtr);
+	ctx.scriptPtr += 2;
 
 	engine->_redraw->addOverlay(koText, textEntry, 0, 0, otherActorIdx, koFollowActor, 2);
 
@@ -1197,23 +1196,23 @@ static int32 lSAY_MESSAGE_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x4F*/
-static int32 lFULL_POINT(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lFULL_POINT(TwinEEngine *engine, ScriptContext &ctx) {
 	engine->_scene->sceneHero->life = 50;
 	engine->_gameState->inventoryMagicPoints = engine->_gameState->magicLevelIdx * 20;
 	return 0;
 }
 
 /*0x50*/
-static int32 lBETA(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 newAngle = *((int16 *)scriptPtr);
-	scriptPtr += 2;
+static int32 lBETA(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 newAngle = *((int16 *)ctx.scriptPtr);
+	ctx.scriptPtr += 2;
 	ctx.actor->angle = newAngle;
 	engine->_movements->clearRealAngle(ctx.actor);
 	return 0;
 }
 
 /*0x51*/
-static int32 lGRM_OFF(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lGRM_OFF(TwinEEngine *engine, ScriptContext &ctx) {
 	if (engine->_grid->cellingGridIdx != -1) {
 		engine->_grid->useCellingGrid = -1;
 		engine->_grid->cellingGridIdx = -1;
@@ -1225,7 +1224,7 @@ static int32 lGRM_OFF(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x52*/
-static int32 lFADE_PAL_RED(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lFADE_PAL_RED(TwinEEngine *engine, ScriptContext &ctx) {
 	ScopedEngineFreeze scoped(engine);
 	engine->_screens->fadePalRed(engine->_screens->mainPaletteRGBA);
 	engine->_screens->useAlternatePalette = false;
@@ -1233,7 +1232,7 @@ static int32 lFADE_PAL_RED(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x53*/
-static int32 lFADE_ALARM_RED(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lFADE_ALARM_RED(TwinEEngine *engine, ScriptContext &ctx) {
 	ScopedEngineFreeze scoped(engine);
 	HQR::getEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
 	engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
@@ -1243,7 +1242,7 @@ static int32 lFADE_ALARM_RED(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x54*/
-static int32 lFADE_ALARM_PAL(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lFADE_ALARM_PAL(TwinEEngine *engine, ScriptContext &ctx) {
 	ScopedEngineFreeze scoped(engine);
 	HQR::getEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
 	engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
@@ -1253,7 +1252,7 @@ static int32 lFADE_ALARM_PAL(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x55*/
-static int32 lFADE_RED_PAL(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lFADE_RED_PAL(TwinEEngine *engine, ScriptContext &ctx) {
 	ScopedEngineFreeze scoped(engine);
 	engine->_screens->fadeRedPal(engine->_screens->mainPaletteRGBA);
 	engine->_screens->useAlternatePalette = false;
@@ -1261,7 +1260,7 @@ static int32 lFADE_RED_PAL(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x56*/
-static int32 lFADE_RED_ALARM(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lFADE_RED_ALARM(TwinEEngine *engine, ScriptContext &ctx) {
 	ScopedEngineFreeze scoped(engine);
 	HQR::getEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
 	engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
@@ -1271,7 +1270,7 @@ static int32 lFADE_RED_ALARM(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x57*/
-static int32 lFADE_PAL_ALARM(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lFADE_PAL_ALARM(TwinEEngine *engine, ScriptContext &ctx) {
 	ScopedEngineFreeze scoped(engine);
 	HQR::getEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
 	engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
@@ -1281,8 +1280,8 @@ static int32 lFADE_PAL_ALARM(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x58*/
-static int32 lEXPLODE_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 otherActorIdx = *(scriptPtr++);
+static int32 lEXPLODE_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 otherActorIdx = *(ctx.scriptPtr++);
 	ActorStruct *otherActor = engine->_scene->getActor(otherActorIdx);
 
 	engine->_extra->addExtraExplode(otherActor->x, otherActor->y, otherActor->z); // RECHECK this
@@ -1291,22 +1290,22 @@ static int32 lEXPLODE_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x59*/
-static int32 lBUBBLE_ON(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lBUBBLE_ON(TwinEEngine *engine, ScriptContext &ctx) {
 	engine->_text->showDialogueBubble = 1;
 	return 0;
 }
 
 /*0x5A*/
-static int32 lBUBBLE_OFF(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lBUBBLE_OFF(TwinEEngine *engine, ScriptContext &ctx) {
 	engine->_text->showDialogueBubble = 1;
 	return 0;
 }
 
 /*0x5B*/
-static int32 lASK_CHOICE_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 otherActorIdx = *(scriptPtr++);
-	int32 choiceIdx = *((int16 *)scriptPtr);
-	scriptPtr += 2;
+static int32 lASK_CHOICE_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 otherActorIdx = *(ctx.scriptPtr++);
+	int32 choiceIdx = *((int16 *)ctx.scriptPtr);
+	ctx.scriptPtr += 2;
 
 	engine->freezeTime();
 	if (engine->_text->showDialogueBubble) {
@@ -1322,7 +1321,7 @@ static int32 lASK_CHOICE_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x5C*/
-static int32 lSET_DARK_PAL(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lSET_DARK_PAL(TwinEEngine *engine, ScriptContext &ctx) {
 	ScopedEngineFreeze scoped(engine);
 	HQR::getEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_DARKPAL);
 	if (!engine->_screens->lockPalette) {
@@ -1334,7 +1333,7 @@ static int32 lSET_DARK_PAL(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x5D*/
-static int32 lSET_NORMAL_PAL(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lSET_NORMAL_PAL(TwinEEngine *engine, ScriptContext &ctx) {
 	engine->_screens->useAlternatePalette = false;
 	if (!engine->_screens->lockPalette) {
 		engine->setPalette(engine->_screens->mainPaletteRGBA);
@@ -1343,7 +1342,7 @@ static int32 lSET_NORMAL_PAL(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x5E*/
-static int32 lMESSAGE_SENDELL(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lMESSAGE_SENDELL(TwinEEngine *engine, ScriptContext &ctx) {
 	ScopedEngineFreeze scoped(engine);
 	engine->_screens->fadeToBlack(engine->_screens->paletteRGBA);
 	engine->_screens->loadImage(25);
@@ -1369,8 +1368,8 @@ static int32 lMESSAGE_SENDELL(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x5F*/
-static int32 lANIM_SET(TwinEEngine *engine, ScriptContext& ctx) {
-	AnimationTypes animIdx = (AnimationTypes)*(scriptPtr++);
+static int32 lANIM_SET(TwinEEngine *engine, ScriptContext &ctx) {
+	AnimationTypes animIdx = (AnimationTypes) * (ctx.scriptPtr++);
 
 	ctx.actor->anim = kAnimNone;
 	ctx.actor->previousAnimIdx = -1;
@@ -1380,13 +1379,13 @@ static int32 lANIM_SET(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x60*/
-static int32 lHOLOMAP_TRAJ(TwinEEngine *engine, ScriptContext& ctx) {
-	scriptPtr++; // TODO
+static int32 lHOLOMAP_TRAJ(TwinEEngine *engine, ScriptContext &ctx) {
+	ctx.scriptPtr++; // TODO
 	return -1;
 }
 
 /*0x61*/
-static int32 lGAME_OVER(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lGAME_OVER(TwinEEngine *engine, ScriptContext &ctx) {
 	engine->_scene->sceneHero->dynamicFlags.bAnimEnded = 1;
 	engine->_scene->sceneHero->life = 0;
 	engine->_gameState->inventoryNumLeafs = 0;
@@ -1394,7 +1393,7 @@ static int32 lGAME_OVER(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x62*/
-static int32 lTHE_END(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lTHE_END(TwinEEngine *engine, ScriptContext &ctx) {
 	engine->quitGame = 1;
 	engine->_gameState->inventoryNumLeafs = 0;
 	engine->_scene->sceneHero->life = 50;
@@ -1408,20 +1407,20 @@ static int32 lTHE_END(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x63*/
-static int32 lMIDI_OFF(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lMIDI_OFF(TwinEEngine *engine, ScriptContext &ctx) {
 	engine->_music->stopMidiMusic();
 	return 0;
 }
 
 /*0x64*/
-static int32 lPLAY_CD_TRACK(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 track = *(scriptPtr++);
+static int32 lPLAY_CD_TRACK(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 track = *(ctx.scriptPtr++);
 	engine->_music->playTrackMusic(track);
 	return 0;
 }
 
 /*0x65*/
-static int32 lPROJ_ISO(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lPROJ_ISO(TwinEEngine *engine, ScriptContext &ctx) {
 	engine->_renderer->setOrthoProjection(311, 240, 512);
 	engine->_renderer->setBaseTranslation(0, 0, 0);
 	engine->_renderer->setBaseRotation(0, 0, 0);
@@ -1430,7 +1429,7 @@ static int32 lPROJ_ISO(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x66*/
-static int32 lPROJ_3D(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lPROJ_3D(TwinEEngine *engine, ScriptContext &ctx) {
 	engine->_screens->copyScreen(engine->frontVideoBuffer, engine->workVideoBuffer);
 	engine->flip();
 	engine->_scene->changeRoomVar10 = 0;
@@ -1445,9 +1444,9 @@ static int32 lPROJ_3D(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x67*/
-static int32 lTEXT(TwinEEngine *engine, ScriptContext& ctx) {
-	int32 textIdx = *((int16 *)scriptPtr);
-	scriptPtr += 2;
+static int32 lTEXT(TwinEEngine *engine, ScriptContext &ctx) {
+	int32 textIdx = *((int16 *)ctx.scriptPtr);
+	ctx.scriptPtr += 2;
 
 	if (drawVar1 < 440) {
 		if (engine->cfgfile.Version == USA_VERSION) {
@@ -1473,7 +1472,7 @@ static int32 lTEXT(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x68*/
-static int32 lCLEAR_TEXT(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lCLEAR_TEXT(TwinEEngine *engine, ScriptContext &ctx) {
 	drawVar1 = 0;
 	engine->_interface->drawSplittedBox(0, 0, 639, 240, 0);
 	engine->copyBlockPhys(0, 0, 639, 240);
@@ -1481,7 +1480,7 @@ static int32 lCLEAR_TEXT(TwinEEngine *engine, ScriptContext& ctx) {
 }
 
 /*0x69*/
-static int32 lBRUTAL_EXIT(TwinEEngine *engine, ScriptContext& ctx) {
+static int32 lBRUTAL_EXIT(TwinEEngine *engine, ScriptContext &ctx) {
 	engine->quitGame = 0;
 	return 1; // break
 }
@@ -1595,23 +1594,19 @@ static const ScriptLifeFunction function_map[] = {
     /*0x69*/ MAPFUNC("BRUTAL_EXIT", lBRUTAL_EXIT)};
 
 ScriptLife::ScriptLife(TwinEEngine *engine) : _engine(engine) {
-	scriptPtr = nullptr;
-	opcodePtr = nullptr;
 	drawVar1 = 0;
 	textStr[0] = '\0';
 }
 
 void ScriptLife::processLifeScript(int32 actorIdx) {
 	ActorStruct *actor = _engine->_scene->getActor(actorIdx);
-	// TODO: use Common::MemoryReadStream for the script parsing
-	scriptPtr = actor->lifeScript + actor->positionInLifeScript;
-
 	int32 end = -2;
 
-	ScriptContext ctx{actorIdx, actor};
+	// TODO: use Common::MemoryReadStream for the script parsing
+	ScriptContext ctx{actorIdx, actor, actor->lifeScript + actor->positionInLifeScript, nullptr};
 	do {
-		opcodePtr = scriptPtr;
-		int32 scriptOpcode = *(scriptPtr++);
+		ctx.opcodePtr = ctx.scriptPtr;
+		int32 scriptOpcode = *(ctx.scriptPtr++);
 
 		if (scriptOpcode >= 0 && scriptOpcode < ARRAYSIZE(function_map)) {
 			end = function_map[scriptOpcode].function(_engine, ctx);


Commit: 8e341f12b97b234dfb25887f7feb5385bfd98c40
    https://github.com/scummvm/scummvm/commit/8e341f12b97b234dfb25887f7feb5385bfd98c40
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T22:12:00+01:00

Commit Message:
TWINE: additional sanity check

Changed paths:
    engines/twine/hqr.cpp


diff --git a/engines/twine/hqr.cpp b/engines/twine/hqr.cpp
index 1bac915968..9ae75ebd3e 100644
--- a/engines/twine/hqr.cpp
+++ b/engines/twine/hqr.cpp
@@ -43,25 +43,27 @@ namespace HQR {
  * @param decompsize real file size after decompression
  * @param mode compression mode used
  */
-static void decompressEntry(uint8 *dst, uint8 *src, int32 decompsize, int32 mode) {
+static void decompressEntry(uint8 *dst, const uint8 *src, int32 decompsize, int32 mode) {
 	do {
 		uint8 b = *(src++);
 		for (int32 d = 0; d < 8; d++) {
 			int32 length;
 			if (!(b & (1 << d))) {
-				const uint16 offset = *(uint16 *)(src);
+				const uint16 offset = *(const uint16 *)(src);
 				src += 2;
 				length = (offset & 0x0F) + (mode + 1);
 				const uint8 *ptr = dst - (offset >> 4) - 1;
-				for (int32 i = 0; i < length; i++)
+				for (int32 i = 0; i < length; i++) {
 					*(dst++) = *(ptr++);
+				}
 			} else {
 				length = 1;
 				*(dst++) = *(src++);
 			}
 			decompsize -= length;
-			if (decompsize <= 0)
+			if (decompsize <= 0) {
 				return;
+			}
 		}
 	} while (decompsize);
 }
@@ -143,8 +145,7 @@ int32 getEntry(uint8 *ptr, const char *filename, int32 index) {
 	}
 	// compressed: modes (1 & 2)
 	else if (mode == 1 || mode == 2) {
-		uint8 *compDataPtr = nullptr;
-		compDataPtr = (uint8 *)malloc(compSize);
+		uint8 *compDataPtr = (uint8 *)malloc(compSize);
 		wrap(file.read(compDataPtr, compSize))
 		decompressEntry(ptr, compDataPtr, realSize, mode);
 		free(compDataPtr);
@@ -196,7 +197,7 @@ int32 numEntries(const char *filename) {
 
 int32 getAllocEntry(uint8 **ptr, const char *filename, int32 index) {
 	const int32 size = entrySize(filename, index);
-	if (size == 0) {
+	if (size <= 0) {
 		warning("HQR: failed to get entry for index %i from file: %s", index, filename);
 		return 0;
 	}
@@ -205,9 +206,9 @@ int32 getAllocEntry(uint8 **ptr, const char *filename, int32 index) {
 		warning("HQR: unable to allocate entry memory");
 		return 0;
 	}
-	getEntry(*ptr, filename, index);
-
-	return size;
+	const int32 entrySize = getEntry(*ptr, filename, index);
+	assert(entrySize == size);
+	return entrySize;
 }
 
 int32 getVoxEntry(uint8 *ptr, const char *filename, int32 index, int32 hiddenIndex) {
@@ -272,9 +273,9 @@ int32 getAllocVoxEntry(uint8 **ptr, const char *filename, int32 index, int32 hid
 		warning("HQR: unable to allocate entry memory");
 		return 0;
 	}
-	getVoxEntry(*ptr, filename, index, hiddenIndex);
-
-	return size;
+	const int32 entrySize = getVoxEntry(*ptr, filename, index, hiddenIndex);
+	assert(entrySize == size);
+	return entrySize;
 }
 
 #undef wrap


Commit: b89ed875789755a7a176bb574a2d8d4a0272d869
    https://github.com/scummvm/scummvm/commit/b89ed875789755a7a176bb574a2d8d4a0272d869
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T22:29:51+01:00

Commit Message:
TWINE: renamed script context classes

for whatever reason this caused a segfault in the life script when using the same names

Changed paths:
    engines/twine/script_life_v1.cpp
    engines/twine/script_move_v1.cpp


diff --git a/engines/twine/script_life_v1.cpp b/engines/twine/script_life_v1.cpp
index 035ae03b2e..555570a1f9 100644
--- a/engines/twine/script_life_v1.cpp
+++ b/engines/twine/script_life_v1.cpp
@@ -48,7 +48,7 @@ namespace TwinE {
 static int32 drawVar1;
 static char textStr[256]; // string
 
-struct ScriptContext {
+struct LifeScriptContext {
 	int32 actorIdx;
 	ActorStruct *actor;
 	uint8 *scriptPtr; // local script pointer
@@ -59,7 +59,7 @@ struct ScriptContext {
 	   -1 - Need implementation
 		0 - Completed
 		1 - Break script */
-typedef int32 ScriptLifeFunc(TwinEEngine *engine, ScriptContext &ctx);
+typedef int32 ScriptLifeFunc(TwinEEngine *engine, LifeScriptContext &ctx);
 
 struct ScriptLifeFunction {
 	const char *name;
@@ -117,7 +117,7 @@ enum LifeScriptConditions {
 	   -1 - Need implementation
 		1 - Condition value size (1 byte)
 		2 - Condition value size (2 byes) */
-static int32 processLifeConditions(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 processLifeConditions(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 conditionValueSize = 1;
 	int32 conditionOpcode = *(ctx.scriptPtr++);
 
@@ -357,7 +357,7 @@ static int32 processLifeConditions(TwinEEngine *engine, ScriptContext &ctx) {
 	   -1 - Need implementation
 		0 - Condition false
 		1 - Condition true */
-static int32 processLifeOperators(TwinEEngine *engine, ScriptContext &ctx, int32 valueSize) {
+static int32 processLifeOperators(TwinEEngine *engine, LifeScriptContext &ctx, int32 valueSize) {
 	const int32 operatorCode = *(ctx.scriptPtr++);
 
 	int32 conditionValue;
@@ -413,24 +413,24 @@ static int32 processLifeOperators(TwinEEngine *engine, ScriptContext &ctx, int32
 /** Life script command definitions */
 
 /* For unused opcodes */
-static int32 lEMPTY(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lEMPTY(TwinEEngine *engine, LifeScriptContext &ctx) {
 	return 0;
 }
 
 /*0x00*/
-static int32 lEND(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lEND(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ctx.actor->positionInLifeScript = -1;
 	return 1; // break script
 }
 
 /*0x01*/
-static int32 lNOP(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lNOP(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ctx.scriptPtr++;
 	return 0;
 }
 
 /*0x02*/
-static int32 lSNIF(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSNIF(TwinEEngine *engine, LifeScriptContext &ctx) {
 	const int32 valueSize = processLifeConditions(engine, ctx);
 	if (!processLifeOperators(engine, ctx, valueSize)) {
 		*ctx.opcodePtr = 0x0D; // SWIF
@@ -440,13 +440,13 @@ static int32 lSNIF(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x03*/
-static int32 lOFFSET(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lOFFSET(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // offset
 	return 0;
 }
 
 /*0x04*/
-static int32 lNEVERIF(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lNEVERIF(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 valueSize = processLifeConditions(engine, ctx);
 	processLifeOperators(engine, ctx, valueSize);
 	ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // condition offset
@@ -454,23 +454,23 @@ static int32 lNEVERIF(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x06*/
-static int32 lNO_IF(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lNO_IF(TwinEEngine *engine, LifeScriptContext &ctx) {
 	return 0;
 }
 
 /*0x0A*/
-static int32 lLABEL(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lLABEL(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ctx.scriptPtr++;
 	return 0;
 }
 
 /*0x0B*/
-static int32 lRETURN(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lRETURN(TwinEEngine *engine, LifeScriptContext &ctx) {
 	return 1; // break script
 }
 
 /*0x0C*/
-static int32 lIF(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lIF(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 valueSize = processLifeConditions(engine, ctx);
 	if (!processLifeOperators(engine, ctx, valueSize)) {
 		ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // condition offset
@@ -482,7 +482,7 @@ static int32 lIF(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x0D*/
-static int32 lSWIF(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSWIF(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 valueSize = processLifeConditions(engine, ctx);
 	if (!processLifeOperators(engine, ctx, valueSize)) {
 		ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // condition offset
@@ -495,7 +495,7 @@ static int32 lSWIF(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x0E*/
-static int32 lONEIF(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lONEIF(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 valueSize = processLifeConditions(engine, ctx);
 	if (!processLifeOperators(engine, ctx, valueSize)) {
 		ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // condition offset
@@ -508,13 +508,13 @@ static int32 lONEIF(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x0F*/
-static int32 lELSE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lELSE(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // offset
 	return 0;
 }
 
 /*0x11*/
-static int32 lBODY(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lBODY(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 bodyIdx = *(ctx.scriptPtr);
 	engine->_actor->initModelActor(bodyIdx, ctx.actorIdx);
 	ctx.scriptPtr++;
@@ -522,7 +522,7 @@ static int32 lBODY(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x12*/
-static int32 lBODY_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lBODY_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 otherActorIdx = *(ctx.scriptPtr++);
 	int32 otherBodyIdx = *(ctx.scriptPtr++);
 	engine->_actor->initModelActor(otherBodyIdx, otherActorIdx);
@@ -530,14 +530,14 @@ static int32 lBODY_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x13*/
-static int32 lANIM(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lANIM(TwinEEngine *engine, LifeScriptContext &ctx) {
 	AnimationTypes animIdx = (AnimationTypes) * (ctx.scriptPtr++);
 	engine->_animations->initAnim(animIdx, 0, 0, ctx.actorIdx);
 	return 0;
 }
 
 /*0x14*/
-static int32 lANIM_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lANIM_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 otherActorIdx = *(ctx.scriptPtr++);
 	AnimationTypes otherAnimIdx = (AnimationTypes) * (ctx.scriptPtr++);
 	engine->_animations->initAnim(otherAnimIdx, 0, 0, otherActorIdx);
@@ -545,14 +545,14 @@ static int32 lANIM_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x15*/
-static int32 lSET_LIFE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_LIFE(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ctx.actor->positionInLifeScript = *((int16 *)ctx.scriptPtr); // offset
 	ctx.scriptPtr += 2;
 	return 0;
 }
 
 /*0x16*/
-static int32 lSET_LIFE_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_LIFE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 otherActorIdx = *(ctx.scriptPtr++);
 	engine->_scene->getActor(otherActorIdx)->positionInLifeScript = *((int16 *)ctx.scriptPtr); // offset
 	ctx.scriptPtr += 2;
@@ -560,14 +560,14 @@ static int32 lSET_LIFE_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x17*/
-static int32 lSET_TRACK(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_TRACK(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ctx.actor->positionInMoveScript = *((int16 *)ctx.scriptPtr); // offset
 	ctx.scriptPtr += 2;
 	return 0;
 }
 
 /*0x18*/
-static int32 lSET_TRACK_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_TRACK_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 otherActorIdx = *(ctx.scriptPtr++);
 	engine->_scene->getActor(otherActorIdx)->positionInMoveScript = *((int16 *)ctx.scriptPtr); // offset
 	ctx.scriptPtr += 2;
@@ -575,7 +575,7 @@ static int32 lSET_TRACK_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x19*/
-static int32 lMESSAGE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lMESSAGE(TwinEEngine *engine, LifeScriptContext &ctx) {
 	const int32 textIdx = *((int16 *)ctx.scriptPtr);
 	ctx.scriptPtr += 2;
 
@@ -593,14 +593,14 @@ static int32 lMESSAGE(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x1A*/
-static int32 lFALLABLE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lFALLABLE(TwinEEngine *engine, LifeScriptContext &ctx) {
 	const int32 flag = *(ctx.scriptPtr++);
 	ctx.actor->staticFlags.bCanFall = flag & 1;
 	return 0;
 }
 
 /*0x1B*/
-static int32 lSET_DIRMODE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_DIRMODE(TwinEEngine *engine, LifeScriptContext &ctx) {
 	const int32 controlMode = *(ctx.scriptPtr++);
 
 	ctx.actor->controlMode = (ControlMode)controlMode;
@@ -612,7 +612,7 @@ static int32 lSET_DIRMODE(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x1C*/
-static int32 lSET_DIRMODE_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_DIRMODE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
 	const int32 otherActorIdx = *(ctx.scriptPtr++);
 	const int32 controlMode = *(ctx.scriptPtr++);
 
@@ -626,7 +626,7 @@ static int32 lSET_DIRMODE_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x1D*/
-static int32 lCAM_FOLLOW(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lCAM_FOLLOW(TwinEEngine *engine, LifeScriptContext &ctx) {
 	const int32 followedActorIdx = *(ctx.scriptPtr++);
 
 	if (engine->_scene->currentlyFollowedActor != followedActorIdx) {
@@ -643,7 +643,7 @@ static int32 lCAM_FOLLOW(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x1E*/
-static int32 lSET_BEHAVIOUR(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_BEHAVIOUR(TwinEEngine *engine, LifeScriptContext &ctx) {
 	const int32 behavior = *(ctx.scriptPtr++);
 
 	engine->_animations->initAnim(kStanding, 0, 255, 0);
@@ -653,7 +653,7 @@ static int32 lSET_BEHAVIOUR(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x1F*/
-static int32 lSET_FLAG_CUBE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_FLAG_CUBE(TwinEEngine *engine, LifeScriptContext &ctx) {
 	const int32 flagIdx = *(ctx.scriptPtr++);
 	const int32 flagValue = *(ctx.scriptPtr++);
 
@@ -663,20 +663,20 @@ static int32 lSET_FLAG_CUBE(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x20*/
-static int32 lCOMPORTEMENT(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lCOMPORTEMENT(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ctx.scriptPtr++;
 	return 0;
 }
 
 /*0x21*/
-static int32 lSET_COMPORTEMENT(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_COMPORTEMENT(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ctx.actor->positionInLifeScript = *((int16 *)ctx.scriptPtr);
 	ctx.scriptPtr += 2;
 	return 0;
 }
 
 /*0x22*/
-static int32 lSET_COMPORTEMENT_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_COMPORTEMENT_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
 	const int32 otherActorIdx = *(ctx.scriptPtr++);
 
 	engine->_scene->getActor(otherActorIdx)->positionInLifeScript = *((int16 *)ctx.scriptPtr);
@@ -686,12 +686,12 @@ static int32 lSET_COMPORTEMENT_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x23*/
-static int32 lEND_COMPORTEMENT(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lEND_COMPORTEMENT(TwinEEngine *engine, LifeScriptContext &ctx) {
 	return 1; // break
 }
 
 /*0x24*/
-static int32 lSET_FLAG_GAME(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_FLAG_GAME(TwinEEngine *engine, LifeScriptContext &ctx) {
 	const int32 flagIdx = *(ctx.scriptPtr++);
 	const int32 flagValue = *(ctx.scriptPtr++);
 
@@ -701,7 +701,7 @@ static int32 lSET_FLAG_GAME(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x25*/
-static int32 lKILL_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lKILL_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
 	const int32 otherActorIdx = *(ctx.scriptPtr++);
 
 	engine->_actor->processActorCarrier(otherActorIdx);
@@ -715,7 +715,7 @@ static int32 lKILL_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x26*/
-static int32 lSUICIDE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSUICIDE(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->_actor->processActorCarrier(ctx.actorIdx);
 	ctx.actor->dynamicFlags.bIsDead = 1;
 	ctx.actor->entity = -1;
@@ -726,7 +726,7 @@ static int32 lSUICIDE(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x27*/
-static int32 lUSE_ONE_LITTLE_KEY(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lUSE_ONE_LITTLE_KEY(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->_gameState->inventoryNumKeys--;
 
 	if (engine->_gameState->inventoryNumKeys < 0) {
@@ -739,7 +739,7 @@ static int32 lUSE_ONE_LITTLE_KEY(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x28*/
-static int32 lGIVE_GOLD_PIECES(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lGIVE_GOLD_PIECES(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int16 oldNumKashes = engine->_gameState->inventoryNumKashes;
 	bool hideRange = false;
 	int16 kashes = *((int16 *)ctx.scriptPtr);
@@ -771,26 +771,26 @@ static int32 lGIVE_GOLD_PIECES(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x29*/
-static int32 lEND_LIFE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lEND_LIFE(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ctx.actor->positionInLifeScript = -1;
 	return 1; // break;
 }
 
 /*0x2A*/
-static int32 lSTOP_L_TRACK(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSTOP_L_TRACK(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ctx.actor->pausedTrackPtr = ctx.actor->currentLabelPtr;
 	ctx.actor->positionInMoveScript = -1;
 	return 0;
 }
 
 /*0x2B*/
-static int32 lRESTORE_L_TRACK(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lRESTORE_L_TRACK(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ctx.actor->positionInMoveScript = ctx.actor->pausedTrackPtr;
 	return 0;
 }
 
 /*0x2C*/
-static int32 lMESSAGE_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lMESSAGE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
 	const int32 otherActorIdx = *(ctx.scriptPtr++);
 	const int32 textIdx = *((int16 *)ctx.scriptPtr);
 	ctx.scriptPtr += 2;
@@ -809,13 +809,13 @@ static int32 lMESSAGE_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x2D*/
-static int32 lINC_CHAPTER(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lINC_CHAPTER(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->_gameState->gameChapter++;
 	return 0;
 }
 
 /*0x2E*/
-static int32 lFOUND_OBJECT(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lFOUND_OBJECT(TwinEEngine *engine, LifeScriptContext &ctx) {
 	const int32 item = *(ctx.scriptPtr++);
 
 	engine->freezeTime();
@@ -827,7 +827,7 @@ static int32 lFOUND_OBJECT(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x2F*/
-static int32 lSET_DOOR_LEFT(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_DOOR_LEFT(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 distance = *((int16 *)ctx.scriptPtr);
 	ctx.scriptPtr += 2;
 
@@ -840,7 +840,7 @@ static int32 lSET_DOOR_LEFT(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x30*/
-static int32 lSET_DOOR_RIGHT(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_DOOR_RIGHT(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 distance = *((int16 *)ctx.scriptPtr);
 	ctx.scriptPtr += 2;
 
@@ -853,7 +853,7 @@ static int32 lSET_DOOR_RIGHT(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x31*/
-static int32 lSET_DOOR_UP(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_DOOR_UP(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 distance = *((int16 *)ctx.scriptPtr);
 	ctx.scriptPtr += 2;
 
@@ -866,7 +866,7 @@ static int32 lSET_DOOR_UP(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x32*/
-static int32 lSET_DOOR_DOWN(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_DOOR_DOWN(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 distance = *((int16 *)ctx.scriptPtr);
 	ctx.scriptPtr += 2;
 
@@ -879,7 +879,7 @@ static int32 lSET_DOOR_DOWN(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x33*/
-static int32 lGIVE_BONUS(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lGIVE_BONUS(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 flag = *(ctx.scriptPtr++);
 
 	if (ctx.actor->bonusParameter & 0x1F0) {
@@ -894,7 +894,7 @@ static int32 lGIVE_BONUS(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x34*/
-static int32 lCHANGE_CUBE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lCHANGE_CUBE(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 sceneIdx = *(ctx.scriptPtr++);
 	engine->_scene->needChangeScene = sceneIdx;
 	engine->_scene->heroPositionType = ScenePositionType::kScene;
@@ -902,7 +902,7 @@ static int32 lCHANGE_CUBE(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x35*/
-static int32 lOBJ_COL(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lOBJ_COL(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 collision = *(ctx.scriptPtr++);
 	if (collision != 0) {
 		ctx.actor->staticFlags.bComputeCollisionWithObj = 1;
@@ -913,7 +913,7 @@ static int32 lOBJ_COL(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x36*/
-static int32 lBRICK_COL(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lBRICK_COL(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 collision = *(ctx.scriptPtr++);
 
 	ctx.actor->staticFlags.bComputeCollisionWithBricks = 0;
@@ -929,7 +929,7 @@ static int32 lBRICK_COL(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x37*/
-static int32 lOR_IF(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lOR_IF(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 valueSize = processLifeConditions(engine, ctx);
 	if (processLifeOperators(engine, ctx, valueSize)) {
 		ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // condition offset
@@ -941,13 +941,13 @@ static int32 lOR_IF(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x38*/
-static int32 lINVISIBLE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lINVISIBLE(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ctx.actor->staticFlags.bIsHidden = *(ctx.scriptPtr++);
 	return 0;
 }
 
 /*0x39*/
-static int32 lZOOM(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lZOOM(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->zoomScreen = *(ctx.scriptPtr++);
 
 	if (engine->zoomScreen && !engine->_redraw->drawInGameTransBox && engine->cfgfile.SceZoom) {
@@ -967,7 +967,7 @@ static int32 lZOOM(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x3A*/
-static int32 lPOS_POINT(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lPOS_POINT(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 trackIdx = *(ctx.scriptPtr++);
 
 	const ScenePoint &sp = engine->_scene->sceneTracks[trackIdx];
@@ -983,14 +983,14 @@ static int32 lPOS_POINT(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x3B*/
-static int32 lSET_MAGIC_LEVEL(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_MAGIC_LEVEL(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->_gameState->magicLevelIdx = *(ctx.scriptPtr++);
 	engine->_gameState->inventoryMagicPoints = engine->_gameState->magicLevelIdx * 20;
 	return 0;
 }
 
 /*0x3C*/
-static int32 lSUB_MAGIC_POINT(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSUB_MAGIC_POINT(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->_gameState->inventoryMagicPoints = *(ctx.scriptPtr++);
 	if (engine->_gameState->inventoryMagicPoints < 0) {
 		engine->_gameState->inventoryMagicPoints = 0;
@@ -999,7 +999,7 @@ static int32 lSUB_MAGIC_POINT(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x3D*/
-static int32 lSET_LIFE_POINT_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_LIFE_POINT_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 otherActorIdx = *(ctx.scriptPtr++);
 	static int32 lifeValue = *(ctx.scriptPtr++);
 
@@ -1009,7 +1009,7 @@ static int32 lSET_LIFE_POINT_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x3E*/
-static int32 lSUB_LIFE_POINT_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSUB_LIFE_POINT_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 otherActorIdx = *(ctx.scriptPtr++);
 	static int32 lifeValue = *(ctx.scriptPtr++);
 
@@ -1023,7 +1023,7 @@ static int32 lSUB_LIFE_POINT_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x3F*/
-static int32 lHIT_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lHIT_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 otherActorIdx = *(ctx.scriptPtr++);
 	int32 strengthOfHit = *(ctx.scriptPtr++);
 	engine->_actor->hitActor(ctx.actorIdx, otherActorIdx, strengthOfHit, engine->_scene->getActor(otherActorIdx)->angle);
@@ -1031,7 +1031,7 @@ static int32 lHIT_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x40*/
-static int32 lPLAY_FLA(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lPLAY_FLA(TwinEEngine *engine, LifeScriptContext &ctx) {
 	const char *movie = (const char *)ctx.scriptPtr;
 	int32 nameSize = strlen(movie);
 	ctx.scriptPtr += nameSize + 1;
@@ -1045,14 +1045,14 @@ static int32 lPLAY_FLA(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x41*/
-static int32 lPLAY_MIDI(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lPLAY_MIDI(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 midiIdx = *(ctx.scriptPtr++);
 	engine->_music->playMidiMusic(midiIdx); // TODO: improve this
 	return 0;
 }
 
 /*0x42*/
-static int32 lINC_CLOVER_BOX(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lINC_CLOVER_BOX(TwinEEngine *engine, LifeScriptContext &ctx) {
 	if (engine->_gameState->inventoryNumLeafsBox < 10) {
 		engine->_gameState->inventoryNumLeafsBox++;
 	}
@@ -1060,7 +1060,7 @@ static int32 lINC_CLOVER_BOX(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x43*/
-static int32 lSET_USED_INVENTORY(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_USED_INVENTORY(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 item = *(ctx.scriptPtr++);
 	if (item < InventoryItems::kKeypad) { // TODO: this looks wrong - why only up to keypad?
 		engine->_gameState->inventoryFlags[item] = 1;
@@ -1069,7 +1069,7 @@ static int32 lSET_USED_INVENTORY(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x44*/
-static int32 lADD_CHOICE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lADD_CHOICE(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 choiceIdx = *((int16 *)ctx.scriptPtr);
 	ctx.scriptPtr += 2;
 	engine->_gameState->gameChoices[engine->_gameState->numChoices++] = choiceIdx;
@@ -1077,7 +1077,7 @@ static int32 lADD_CHOICE(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x45*/
-static int32 lASK_CHOICE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lASK_CHOICE(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 choiceIdx = *((int16 *)ctx.scriptPtr);
 	ctx.scriptPtr += 2;
 
@@ -1095,7 +1095,7 @@ static int32 lASK_CHOICE(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x46*/
-static int32 lBIG_MESSAGE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lBIG_MESSAGE(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 textIdx = *((int16 *)ctx.scriptPtr);
 	ctx.scriptPtr += 2;
 
@@ -1115,7 +1115,7 @@ static int32 lBIG_MESSAGE(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x47*/
-static int32 lINIT_PINGOUIN(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lINIT_PINGOUIN(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 pingouinActor = *(ctx.scriptPtr++);
 	engine->_scene->mecaPinguinIdx = pingouinActor;
 	ActorStruct *mecaPinguin = engine->_scene->getActor(pingouinActor);
@@ -1126,7 +1126,7 @@ static int32 lINIT_PINGOUIN(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x48*/
-static int32 lSET_HOLO_POS(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_HOLO_POS(TwinEEngine *engine, LifeScriptContext &ctx) {
 	static int32 location = *(ctx.scriptPtr++);
 	engine->_holomap->setHolomapPosition(location);
 	if (engine->_gameState->gameFlags[InventoryItems::kiHolomap]) {
@@ -1137,14 +1137,14 @@ static int32 lSET_HOLO_POS(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x49*/
-static int32 lCLR_HOLO_POS(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lCLR_HOLO_POS(TwinEEngine *engine, LifeScriptContext &ctx) {
 	static int32 location = *(ctx.scriptPtr++);
 	engine->_holomap->clearHolomapPosition(location);
 	return 0;
 }
 
 /*0x4A*/
-static int32 lADD_FUEL(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lADD_FUEL(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->_gameState->inventoryNumGas += *(ctx.scriptPtr++);
 	if (engine->_gameState->inventoryNumGas > 100) {
 		engine->_gameState->inventoryNumGas = 100;
@@ -1153,7 +1153,7 @@ static int32 lADD_FUEL(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x4B*/
-static int32 lSUB_FUEL(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSUB_FUEL(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->_gameState->inventoryNumGas -= *(ctx.scriptPtr++);
 	if (engine->_gameState->inventoryNumGas < 0) {
 		engine->_gameState->inventoryNumGas = 0;
@@ -1162,14 +1162,14 @@ static int32 lSUB_FUEL(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x4C*/
-static int32 lSET_GRM(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_GRM(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->_grid->cellingGridIdx = *(ctx.scriptPtr++);
 	engine->_grid->initCellingGrid(engine->_grid->cellingGridIdx);
 	return 0;
 }
 
 /*0x4D*/
-static int32 lSAY_MESSAGE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSAY_MESSAGE(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int16 textEntry = *((int16 *)ctx.scriptPtr);
 	ctx.scriptPtr += 2;
 
@@ -1182,7 +1182,7 @@ static int32 lSAY_MESSAGE(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*04E*/
-static int32 lSAY_MESSAGE_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSAY_MESSAGE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 otherActorIdx = *(ctx.scriptPtr++);
 	int16 textEntry = *((int16 *)ctx.scriptPtr);
 	ctx.scriptPtr += 2;
@@ -1196,14 +1196,14 @@ static int32 lSAY_MESSAGE_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x4F*/
-static int32 lFULL_POINT(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lFULL_POINT(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->_scene->sceneHero->life = 50;
 	engine->_gameState->inventoryMagicPoints = engine->_gameState->magicLevelIdx * 20;
 	return 0;
 }
 
 /*0x50*/
-static int32 lBETA(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lBETA(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 newAngle = *((int16 *)ctx.scriptPtr);
 	ctx.scriptPtr += 2;
 	ctx.actor->angle = newAngle;
@@ -1212,7 +1212,7 @@ static int32 lBETA(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x51*/
-static int32 lGRM_OFF(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lGRM_OFF(TwinEEngine *engine, LifeScriptContext &ctx) {
 	if (engine->_grid->cellingGridIdx != -1) {
 		engine->_grid->useCellingGrid = -1;
 		engine->_grid->cellingGridIdx = -1;
@@ -1224,7 +1224,7 @@ static int32 lGRM_OFF(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x52*/
-static int32 lFADE_PAL_RED(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lFADE_PAL_RED(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ScopedEngineFreeze scoped(engine);
 	engine->_screens->fadePalRed(engine->_screens->mainPaletteRGBA);
 	engine->_screens->useAlternatePalette = false;
@@ -1232,7 +1232,7 @@ static int32 lFADE_PAL_RED(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x53*/
-static int32 lFADE_ALARM_RED(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lFADE_ALARM_RED(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ScopedEngineFreeze scoped(engine);
 	HQR::getEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
 	engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
@@ -1242,7 +1242,7 @@ static int32 lFADE_ALARM_RED(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x54*/
-static int32 lFADE_ALARM_PAL(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lFADE_ALARM_PAL(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ScopedEngineFreeze scoped(engine);
 	HQR::getEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
 	engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
@@ -1252,7 +1252,7 @@ static int32 lFADE_ALARM_PAL(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x55*/
-static int32 lFADE_RED_PAL(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lFADE_RED_PAL(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ScopedEngineFreeze scoped(engine);
 	engine->_screens->fadeRedPal(engine->_screens->mainPaletteRGBA);
 	engine->_screens->useAlternatePalette = false;
@@ -1260,7 +1260,7 @@ static int32 lFADE_RED_PAL(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x56*/
-static int32 lFADE_RED_ALARM(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lFADE_RED_ALARM(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ScopedEngineFreeze scoped(engine);
 	HQR::getEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
 	engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
@@ -1270,7 +1270,7 @@ static int32 lFADE_RED_ALARM(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x57*/
-static int32 lFADE_PAL_ALARM(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lFADE_PAL_ALARM(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ScopedEngineFreeze scoped(engine);
 	HQR::getEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
 	engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
@@ -1280,7 +1280,7 @@ static int32 lFADE_PAL_ALARM(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x58*/
-static int32 lEXPLODE_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lEXPLODE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 otherActorIdx = *(ctx.scriptPtr++);
 	ActorStruct *otherActor = engine->_scene->getActor(otherActorIdx);
 
@@ -1290,19 +1290,19 @@ static int32 lEXPLODE_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x59*/
-static int32 lBUBBLE_ON(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lBUBBLE_ON(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->_text->showDialogueBubble = 1;
 	return 0;
 }
 
 /*0x5A*/
-static int32 lBUBBLE_OFF(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lBUBBLE_OFF(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->_text->showDialogueBubble = 1;
 	return 0;
 }
 
 /*0x5B*/
-static int32 lASK_CHOICE_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lASK_CHOICE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 otherActorIdx = *(ctx.scriptPtr++);
 	int32 choiceIdx = *((int16 *)ctx.scriptPtr);
 	ctx.scriptPtr += 2;
@@ -1321,7 +1321,7 @@ static int32 lASK_CHOICE_OBJ(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x5C*/
-static int32 lSET_DARK_PAL(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_DARK_PAL(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ScopedEngineFreeze scoped(engine);
 	HQR::getEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_DARKPAL);
 	if (!engine->_screens->lockPalette) {
@@ -1333,7 +1333,7 @@ static int32 lSET_DARK_PAL(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x5D*/
-static int32 lSET_NORMAL_PAL(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lSET_NORMAL_PAL(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->_screens->useAlternatePalette = false;
 	if (!engine->_screens->lockPalette) {
 		engine->setPalette(engine->_screens->mainPaletteRGBA);
@@ -1342,7 +1342,7 @@ static int32 lSET_NORMAL_PAL(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x5E*/
-static int32 lMESSAGE_SENDELL(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lMESSAGE_SENDELL(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ScopedEngineFreeze scoped(engine);
 	engine->_screens->fadeToBlack(engine->_screens->paletteRGBA);
 	engine->_screens->loadImage(25);
@@ -1368,7 +1368,7 @@ static int32 lMESSAGE_SENDELL(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x5F*/
-static int32 lANIM_SET(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lANIM_SET(TwinEEngine *engine, LifeScriptContext &ctx) {
 	AnimationTypes animIdx = (AnimationTypes) * (ctx.scriptPtr++);
 
 	ctx.actor->anim = kAnimNone;
@@ -1379,13 +1379,13 @@ static int32 lANIM_SET(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x60*/
-static int32 lHOLOMAP_TRAJ(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lHOLOMAP_TRAJ(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ctx.scriptPtr++; // TODO
 	return -1;
 }
 
 /*0x61*/
-static int32 lGAME_OVER(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lGAME_OVER(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->_scene->sceneHero->dynamicFlags.bAnimEnded = 1;
 	engine->_scene->sceneHero->life = 0;
 	engine->_gameState->inventoryNumLeafs = 0;
@@ -1393,7 +1393,7 @@ static int32 lGAME_OVER(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x62*/
-static int32 lTHE_END(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lTHE_END(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->quitGame = 1;
 	engine->_gameState->inventoryNumLeafs = 0;
 	engine->_scene->sceneHero->life = 50;
@@ -1407,20 +1407,20 @@ static int32 lTHE_END(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x63*/
-static int32 lMIDI_OFF(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lMIDI_OFF(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->_music->stopMidiMusic();
 	return 0;
 }
 
 /*0x64*/
-static int32 lPLAY_CD_TRACK(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lPLAY_CD_TRACK(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 track = *(ctx.scriptPtr++);
 	engine->_music->playTrackMusic(track);
 	return 0;
 }
 
 /*0x65*/
-static int32 lPROJ_ISO(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lPROJ_ISO(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->_renderer->setOrthoProjection(311, 240, 512);
 	engine->_renderer->setBaseTranslation(0, 0, 0);
 	engine->_renderer->setBaseRotation(0, 0, 0);
@@ -1429,7 +1429,7 @@ static int32 lPROJ_ISO(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x66*/
-static int32 lPROJ_3D(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lPROJ_3D(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->_screens->copyScreen(engine->frontVideoBuffer, engine->workVideoBuffer);
 	engine->flip();
 	engine->_scene->changeRoomVar10 = 0;
@@ -1444,7 +1444,7 @@ static int32 lPROJ_3D(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x67*/
-static int32 lTEXT(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lTEXT(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 textIdx = *((int16 *)ctx.scriptPtr);
 	ctx.scriptPtr += 2;
 
@@ -1472,7 +1472,7 @@ static int32 lTEXT(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x68*/
-static int32 lCLEAR_TEXT(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lCLEAR_TEXT(TwinEEngine *engine, LifeScriptContext &ctx) {
 	drawVar1 = 0;
 	engine->_interface->drawSplittedBox(0, 0, 639, 240, 0);
 	engine->copyBlockPhys(0, 0, 639, 240);
@@ -1480,7 +1480,7 @@ static int32 lCLEAR_TEXT(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x69*/
-static int32 lBRUTAL_EXIT(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 lBRUTAL_EXIT(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->quitGame = 0;
 	return 1; // break
 }
@@ -1603,7 +1603,7 @@ void ScriptLife::processLifeScript(int32 actorIdx) {
 	int32 end = -2;
 
 	// TODO: use Common::MemoryReadStream for the script parsing
-	ScriptContext ctx{actorIdx, actor, actor->lifeScript + actor->positionInLifeScript, nullptr};
+	LifeScriptContext ctx{actorIdx, actor, actor->lifeScript + actor->positionInLifeScript, nullptr};
 	do {
 		ctx.opcodePtr = ctx.scriptPtr;
 		int32 scriptOpcode = *(ctx.scriptPtr++);
diff --git a/engines/twine/script_move_v1.cpp b/engines/twine/script_move_v1.cpp
index 4fcb390e71..e579f1c3da 100644
--- a/engines/twine/script_move_v1.cpp
+++ b/engines/twine/script_move_v1.cpp
@@ -37,12 +37,12 @@ namespace TwinE {
 
 static int32 numRepeatSample = 1;
 
-struct ScriptContext {
+struct MoveScriptContext {
 	int32 actorIdx;
 	ActorStruct *actor;
 	Common::MemorySeekableReadWriteStream stream;
 
-	ScriptContext(int32 _actorIdx, ActorStruct *_actor) : actorIdx(_actorIdx), actor(_actor), stream(actor->moveScript, actor->moveScriptSize) {
+	MoveScriptContext(int32 _actorIdx, ActorStruct *_actor) : actorIdx(_actorIdx), actor(_actor), stream(actor->moveScript, actor->moveScriptSize) {
 		assert(actor->positionInMoveScript >= 0);
 		stream.skip(actor->positionInMoveScript);
 	}
@@ -58,7 +58,7 @@ struct ScriptContext {
 	   -1 - Need implementation
 		0 - Completed
 		1 - Break script */
-typedef int32 ScriptMoveFunc(TwinEEngine *engine, ScriptContext &ctx);
+typedef int32 ScriptMoveFunc(TwinEEngine *engine, MoveScriptContext &ctx);
 
 struct ScriptMoveFunction {
 	const char *name;
@@ -69,25 +69,25 @@ struct ScriptMoveFunction {
 	{ name, func }
 
 /*0x00*/
-static int32 mEND(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mEND(TwinEEngine *engine, MoveScriptContext &ctx) {
 	ctx.actor->positionInMoveScript = -1;
 	return 1;
 }
 
 /*0x01*/
-static int32 mNOP(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mNOP(TwinEEngine *engine, MoveScriptContext &ctx) {
 	return 0;
 }
 
 /*0x02*/
-static int32 mBODY(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mBODY(TwinEEngine *engine, MoveScriptContext &ctx) {
 	int32 bodyIdx = ctx.stream.readByte();
 	engine->_actor->initModelActor(bodyIdx, ctx.actorIdx);
 	return 0;
 }
 
 /*0x03*/
-static int32 mANIM(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mANIM(TwinEEngine *engine, MoveScriptContext &ctx) {
 	AnimationTypes animIdx = (AnimationTypes)ctx.stream.readByte();
 	if (engine->_animations->initAnim(animIdx, 0, 0, ctx.actorIdx)) {
 		return 0;
@@ -97,7 +97,7 @@ static int32 mANIM(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x04*/
-static int32 mGOTO_POINT(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mGOTO_POINT(TwinEEngine *engine, MoveScriptContext &ctx) {
 	engine->_scene->currentScriptValue = ctx.stream.readByte();
 
 	const ScenePoint &sp = engine->_scene->sceneTracks[engine->_scene->currentScriptValue];
@@ -122,7 +122,7 @@ static int32 mGOTO_POINT(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x05*/
-static int32 mWAIT_ANIM(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mWAIT_ANIM(TwinEEngine *engine, MoveScriptContext &ctx) {
 	if (!ctx.actor->dynamicFlags.bAnimEnded) {
 		ctx.undo(0);
 	} else {
@@ -132,13 +132,13 @@ static int32 mWAIT_ANIM(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x06*/
-static int32 mLOOP(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mLOOP(TwinEEngine *engine, MoveScriptContext &ctx) {
 	// TODO
 	return -1;
 }
 
 /*0x07*/
-static int32 mANGLE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mANGLE(TwinEEngine *engine, MoveScriptContext &ctx) {
 	const int16 angle = ctx.stream.readSint16LE();
 	if (ctx.actor->staticFlags.bIsSpriteActor) {
 		return 0;
@@ -156,7 +156,7 @@ static int32 mANGLE(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x08*/
-static int32 mPOS_POINT(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mPOS_POINT(TwinEEngine *engine, MoveScriptContext &ctx) {
 	engine->_scene->currentScriptValue = ctx.stream.readByte();
 
 	const ScenePoint &sp = engine->_scene->sceneTracks[engine->_scene->currentScriptValue];
@@ -176,26 +176,26 @@ static int32 mPOS_POINT(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x09*/
-static int32 mLABEL(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mLABEL(TwinEEngine *engine, MoveScriptContext &ctx) {
 	ctx.actor->labelIdx = ctx.stream.readByte();
 	ctx.actor->currentLabelPtr = ctx.stream.pos() - 2;
 	return 0;
 }
 
 /*0x0A*/
-static int32 mGOTO(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mGOTO(TwinEEngine *engine, MoveScriptContext &ctx) {
 	ctx.stream.seek(ctx.stream.readSint16LE());
 	return 0;
 }
 
 /*0x0B*/
-static int32 mSTOP(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mSTOP(TwinEEngine *engine, MoveScriptContext &ctx) {
 	ctx.actor->positionInMoveScript = -1;
 	return 1;
 }
 
 /*0x0C*/
-static int32 mGOTO_SYM_POINT(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mGOTO_SYM_POINT(TwinEEngine *engine, MoveScriptContext &ctx) {
 	engine->_scene->currentScriptValue = ctx.stream.readByte();
 
 	const ScenePoint &sp = engine->_scene->sceneTracks[engine->_scene->currentScriptValue];
@@ -220,7 +220,7 @@ static int32 mGOTO_SYM_POINT(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x0D*/
-static int32 mWAIT_NUM_ANIM(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mWAIT_NUM_ANIM(TwinEEngine *engine, MoveScriptContext &ctx) {
 	bool abortMove = false;
 	const int32 animRepeats = ctx.stream.readByte();
 	int32 animPos = ctx.stream.readByte();
@@ -247,14 +247,14 @@ static int32 mWAIT_NUM_ANIM(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x0E*/
-static int32 mSAMPLE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mSAMPLE(TwinEEngine *engine, MoveScriptContext &ctx) {
 	int32 sampleIdx = ctx.stream.readSint16LE();
 	engine->_sound->playSample(sampleIdx, 0x1000, 1, ctx.actor->x, ctx.actor->y, ctx.actor->z, ctx.actorIdx);
 	return 0;
 }
 
 /*0x0F*/
-static int32 mGOTO_POINT_3D(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mGOTO_POINT_3D(TwinEEngine *engine, MoveScriptContext &ctx) {
 	const int32 trackId = ctx.stream.readByte();
 	if (!ctx.actor->staticFlags.bIsSpriteActor) {
 		return 0;
@@ -282,7 +282,7 @@ static int32 mGOTO_POINT_3D(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x10*/
-static int32 mSPEED(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mSPEED(TwinEEngine *engine, MoveScriptContext &ctx) {
 	ctx.actor->speed = ctx.stream.readSint16LE();
 
 	if (ctx.actor->staticFlags.bIsSpriteActor) {
@@ -293,7 +293,7 @@ static int32 mSPEED(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x11*/
-static int32 mBACKGROUND(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mBACKGROUND(TwinEEngine *engine, MoveScriptContext &ctx) {
 	if (ctx.stream.readByte() != 0) {
 		if (!ctx.actor->staticFlags.bIsBackgrounded) {
 			ctx.actor->staticFlags.bIsBackgrounded = 1;
@@ -314,7 +314,7 @@ static int32 mBACKGROUND(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x12*/
-static int32 mWAIT_NUM_SECOND(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mWAIT_NUM_SECOND(TwinEEngine *engine, MoveScriptContext &ctx) {
 	const int32 numSeconds = ctx.stream.readByte();
 	int32 currentTime = ctx.stream.readSint32LE();
 
@@ -336,13 +336,13 @@ static int32 mWAIT_NUM_SECOND(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x13*/
-static int32 mNO_BODY(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mNO_BODY(TwinEEngine *engine, MoveScriptContext &ctx) {
 	engine->_actor->initModelActor(-1, ctx.actorIdx);
 	return 0;
 }
 
 /*0x14*/
-static int32 mBETA(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mBETA(TwinEEngine *engine, MoveScriptContext &ctx) {
 	const int16 beta = ctx.stream.readSint16LE();
 
 	ctx.actor->angle = beta;
@@ -355,7 +355,7 @@ static int32 mBETA(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x15*/
-static int32 mOPEN_LEFT(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mOPEN_LEFT(TwinEEngine *engine, MoveScriptContext &ctx) {
 	const int16 doorStatus = ctx.stream.readSint16LE();
 	if (ctx.actor->staticFlags.bIsSpriteActor && ctx.actor->staticFlags.bUsesClipping) {
 		ctx.actor->angle = 0x300;
@@ -368,7 +368,7 @@ static int32 mOPEN_LEFT(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x16*/
-static int32 mOPEN_RIGHT(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mOPEN_RIGHT(TwinEEngine *engine, MoveScriptContext &ctx) {
 	const int16 doorStatus = ctx.stream.readSint16LE();
 	if (ctx.actor->staticFlags.bIsSpriteActor && ctx.actor->staticFlags.bUsesClipping) {
 		ctx.actor->angle = 0x100;
@@ -381,7 +381,7 @@ static int32 mOPEN_RIGHT(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x17*/
-static int32 mOPEN_UP(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mOPEN_UP(TwinEEngine *engine, MoveScriptContext &ctx) {
 	const int16 doorStatus = ctx.stream.readSint16LE();
 	if (ctx.actor->staticFlags.bIsSpriteActor && ctx.actor->staticFlags.bUsesClipping) {
 		ctx.actor->angle = 0x200;
@@ -394,7 +394,7 @@ static int32 mOPEN_UP(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x18*/
-static int32 mOPEN_DOWN(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mOPEN_DOWN(TwinEEngine *engine, MoveScriptContext &ctx) {
 	const int16 doorStatus = ctx.stream.readSint16LE();
 	if (ctx.actor->staticFlags.bIsSpriteActor && ctx.actor->staticFlags.bUsesClipping) {
 		ctx.actor->angle = 0;
@@ -407,7 +407,7 @@ static int32 mOPEN_DOWN(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x19*/
-static int32 mCLOSE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mCLOSE(TwinEEngine *engine, MoveScriptContext &ctx) {
 	if (ctx.actor->staticFlags.bIsSpriteActor && ctx.actor->staticFlags.bUsesClipping) {
 		ctx.actor->doorStatus = 0;
 		ctx.actor->dynamicFlags.bIsSpriteMoving = 1;
@@ -418,7 +418,7 @@ static int32 mCLOSE(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x1A*/
-static int32 mWAIT_DOOR(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mWAIT_DOOR(TwinEEngine *engine, MoveScriptContext &ctx) {
 	if (ctx.actor->staticFlags.bIsSpriteActor && ctx.actor->staticFlags.bUsesClipping) {
 		if (ctx.actor->speed) {
 			ctx.undo(0);
@@ -429,7 +429,7 @@ static int32 mWAIT_DOOR(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x1B*/
-static int32 mSAMPLE_RND(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mSAMPLE_RND(TwinEEngine *engine, MoveScriptContext &ctx) {
 	int32 freq = engine->getRandomNumber(2048) + 2048;
 	int32 sampleIdx = ctx.stream.readSint16LE();
 	engine->_sound->playSample(sampleIdx, freq, 1, ctx.actor->x, ctx.actor->y, ctx.actor->z, ctx.actorIdx);
@@ -437,7 +437,7 @@ static int32 mSAMPLE_RND(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x1C*/
-static int32 mSAMPLE_ALWAYS(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mSAMPLE_ALWAYS(TwinEEngine *engine, MoveScriptContext &ctx) {
 	int32 sampleIdx = ctx.stream.readSint16LE();
 	if (!engine->_sound->isSamplePlaying(sampleIdx)) { // if its not playing
 		engine->_sound->playSample(sampleIdx, 0x1000, -1, ctx.actor->x, ctx.actor->y, ctx.actor->z, ctx.actorIdx);
@@ -446,26 +446,26 @@ static int32 mSAMPLE_ALWAYS(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x1D*/
-static int32 mSAMPLE_STOP(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mSAMPLE_STOP(TwinEEngine *engine, MoveScriptContext &ctx) {
 	int32 sampleIdx = ctx.stream.readSint16LE();
 	engine->_sound->stopSample(sampleIdx);
 	return 0;
 }
 
 /*0x1E*/
-static int32 mPLAY_FLA(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mPLAY_FLA(TwinEEngine *engine, MoveScriptContext &ctx) {
 	// TODO
 	return -1;
 }
 
 /*0x1F*/
-static int32 mREPEAT_SAMPLE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mREPEAT_SAMPLE(TwinEEngine *engine, MoveScriptContext &ctx) {
 	numRepeatSample = ctx.stream.readSint16LE();
 	return 0;
 }
 
 /*0x20*/
-static int32 mSIMPLE_SAMPLE(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mSIMPLE_SAMPLE(TwinEEngine *engine, MoveScriptContext &ctx) {
 	int32 sampleIdx = ctx.stream.readSint16LE();
 	engine->_sound->playSample(sampleIdx, 0x1000, numRepeatSample, ctx.actor->x, ctx.actor->y, ctx.actor->z, ctx.actorIdx);
 	numRepeatSample = 1;
@@ -473,7 +473,7 @@ static int32 mSIMPLE_SAMPLE(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x21*/
-static int32 mFACE_HERO(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mFACE_HERO(TwinEEngine *engine, MoveScriptContext &ctx) {
 	const int16 angle = ctx.stream.readSint16LE();
 	if (ctx.actor->staticFlags.bIsSpriteActor) {
 		return 0;
@@ -497,7 +497,7 @@ static int32 mFACE_HERO(TwinEEngine *engine, ScriptContext &ctx) {
 }
 
 /*0x22*/
-static int32 mANGLE_RND(TwinEEngine *engine, ScriptContext &ctx) {
+static int32 mANGLE_RND(TwinEEngine *engine, MoveScriptContext &ctx) {
 	const int16 val1 = ctx.stream.readSint16LE();
 	const int16 val2 = ctx.stream.readSint16LE();
 	if (ctx.actor->staticFlags.bIsSpriteActor) {
@@ -579,7 +579,7 @@ void ScriptMove::processMoveScript(int32 actorIdx) {
 
 	int32 end = -2;
 
-	ScriptContext ctx(actorIdx, actor);
+	MoveScriptContext ctx(actorIdx, actor);
 	do {
 		const byte scriptOpcode = ctx.stream.readByte();
 		if (scriptOpcode < ARRAYSIZE(function_map)) {


Commit: 869d57f042ff924c7edda6764021e159c63d05b5
    https://github.com/scummvm/scummvm/commit/869d57f042ff924c7edda6764021e159c63d05b5
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T22:33:21+01:00

Commit Message:
TWINE: converted the life script parsing to endian safe MemorySeekableReadWriteStream

Changed paths:
    engines/twine/script_life_v1.cpp


diff --git a/engines/twine/script_life_v1.cpp b/engines/twine/script_life_v1.cpp
index 555570a1f9..5c8acd7538 100644
--- a/engines/twine/script_life_v1.cpp
+++ b/engines/twine/script_life_v1.cpp
@@ -39,6 +39,7 @@
 #include "twine/resources.h"
 #include "twine/scene.h"
 #include "twine/screens.h"
+#include "common/memstream.h"
 #include "twine/sound.h"
 #include "twine/text.h"
 #include "twine/twine.h"
@@ -51,8 +52,22 @@ static char textStr[256]; // string
 struct LifeScriptContext {
 	int32 actorIdx;
 	ActorStruct *actor;
-	uint8 *scriptPtr; // local script pointer
+	Common::MemorySeekableReadWriteStream stream;
 	uint8 *opcodePtr; // local opcode script pointer
+
+	LifeScriptContext(int32 _actorIdx, ActorStruct *_actor) : actorIdx(_actorIdx), actor(_actor), stream(_actor->lifeScript, _actor->lifeScriptSize) {
+		assert(actor->positionInLifeScript >= 0);
+		stream.skip(_actor->positionInLifeScript);
+		updateOpcodePos();
+	}
+
+	void setOpcode(uint8 opcode) {
+		*opcodePtr = opcode;
+	}
+
+	void updateOpcodePos() {
+		opcodePtr = actor->lifeScript + stream.pos();
+	}
 };
 
 /** Returns:
@@ -119,7 +134,7 @@ enum LifeScriptConditions {
 		2 - Condition value size (2 byes) */
 static int32 processLifeConditions(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 conditionValueSize = 1;
-	int32 conditionOpcode = *(ctx.scriptPtr++);
+	int32 conditionOpcode = ctx.stream.readByte();
 
 	switch (conditionOpcode) {
 	case kcCOL:
@@ -130,7 +145,7 @@ static int32 processLifeConditions(TwinEEngine *engine, LifeScriptContext &ctx)
 		}
 		break;
 	case kcCOL_OBJ: {
-		int32 actorIdx = *(ctx.scriptPtr++);
+		int32 actorIdx = ctx.stream.readByte();
 		if (engine->_scene->getActor(actorIdx)->life <= 0) {
 			engine->_scene->currentScriptValue = -1;
 		} else {
@@ -139,7 +154,7 @@ static int32 processLifeConditions(TwinEEngine *engine, LifeScriptContext &ctx)
 		break;
 	}
 	case kcDISTANCE: {
-		int32 actorIdx = *(ctx.scriptPtr++);
+		int32 actorIdx = ctx.stream.readByte();
 		conditionValueSize = 2;
 		ActorStruct *otherActor = engine->_scene->getActor(actorIdx);
 		if (!otherActor->dynamicFlags.bIsDead) {
@@ -163,7 +178,7 @@ static int32 processLifeConditions(TwinEEngine *engine, LifeScriptContext &ctx)
 		engine->_scene->currentScriptValue = ctx.actor->zone;
 		break;
 	case kcZONE_OBJ: {
-		int32 actorIdx = *(ctx.scriptPtr++);
+		int32 actorIdx = ctx.stream.readByte();
 		engine->_scene->currentScriptValue = engine->_scene->getActor(actorIdx)->zone;
 		break;
 	}
@@ -171,7 +186,7 @@ static int32 processLifeConditions(TwinEEngine *engine, LifeScriptContext &ctx)
 		engine->_scene->currentScriptValue = ctx.actor->body;
 		break;
 	case kcBODY_OBJ: {
-		int32 actorIdx = *(ctx.scriptPtr++);
+		int32 actorIdx = ctx.stream.readByte();
 		engine->_scene->currentScriptValue = engine->_scene->getActor(actorIdx)->body;
 		break;
 	}
@@ -179,7 +194,7 @@ static int32 processLifeConditions(TwinEEngine *engine, LifeScriptContext &ctx)
 		engine->_scene->currentScriptValue = ctx.actor->anim;
 		break;
 	case kcANIM_OBJ: {
-		int32 actorIdx = *(ctx.scriptPtr++);
+		int32 actorIdx = ctx.stream.readByte();
 		engine->_scene->currentScriptValue = engine->_scene->getActor(actorIdx)->anim;
 		break;
 	}
@@ -187,18 +202,18 @@ static int32 processLifeConditions(TwinEEngine *engine, LifeScriptContext &ctx)
 		engine->_scene->currentScriptValue = ctx.actor->labelIdx;
 		break;
 	case kcL_TRACK_OBJ: {
-		int32 actorIdx = *(ctx.scriptPtr++);
+		int32 actorIdx = ctx.stream.readByte();
 		engine->_scene->currentScriptValue = engine->_scene->getActor(actorIdx)->labelIdx;
 		break;
 	}
 	case kcFLAG_CUBE: {
-		int32 flagIdx = *(ctx.scriptPtr++);
+		int32 flagIdx = ctx.stream.readByte();
 		engine->_scene->currentScriptValue = engine->_scene->sceneFlags[flagIdx];
 		break;
 	}
 	case kcCONE_VIEW: {
 		int32 newAngle = 0;
-		int32 targetActorIdx = *(ctx.scriptPtr++);
+		int32 targetActorIdx = ctx.stream.readByte();
 		ActorStruct *targetActor = engine->_scene->getActor(targetActorIdx);
 
 		conditionValueSize = 2;
@@ -251,7 +266,7 @@ static int32 processLifeConditions(TwinEEngine *engine, LifeScriptContext &ctx)
 		engine->_scene->currentScriptValue = engine->_movements->heroAction ? 1 : 0;
 		break;
 	case kcFLAG_GAME: {
-		int32 flagIdx = *(ctx.scriptPtr++);
+		int32 flagIdx = ctx.stream.readByte();
 		if (!engine->_gameState->gameFlags[GAMEFLAG_INVENTORY_DISABLED] ||
 		    (engine->_gameState->gameFlags[GAMEFLAG_INVENTORY_DISABLED] && flagIdx >= MaxInventoryItems)) {
 			engine->_scene->currentScriptValue = engine->_gameState->gameFlags[flagIdx];
@@ -268,7 +283,7 @@ static int32 processLifeConditions(TwinEEngine *engine, LifeScriptContext &ctx)
 		engine->_scene->currentScriptValue = ctx.actor->life;
 		break;
 	case kcLIFE_POINT_OBJ: {
-		int32 actorIdx = *(ctx.scriptPtr++);
+		int32 actorIdx = ctx.stream.readByte();
 		engine->_scene->currentScriptValue = engine->_scene->getActor(actorIdx)->life;
 		break;
 	}
@@ -289,7 +304,7 @@ static int32 processLifeConditions(TwinEEngine *engine, LifeScriptContext &ctx)
 		int32 targetActorIdx;
 		ActorStruct *targetActor;
 
-		targetActorIdx = *(ctx.scriptPtr++);
+		targetActorIdx = ctx.stream.readByte();
 		targetActor = engine->_scene->getActor(targetActorIdx);
 
 		conditionValueSize = 2;
@@ -311,7 +326,7 @@ static int32 processLifeConditions(TwinEEngine *engine, LifeScriptContext &ctx)
 	case 24:
 		break;
 	case kcUSE_INVENTORY: {
-		int32 item = *(ctx.scriptPtr++);
+		int32 item = ctx.stream.readByte();
 
 		if (!engine->_gameState->gameFlags[GAMEFLAG_INVENTORY_DISABLED]) {
 			if (item == engine->loopInventoryItem) {
@@ -358,17 +373,15 @@ static int32 processLifeConditions(TwinEEngine *engine, LifeScriptContext &ctx)
 		0 - Condition false
 		1 - Condition true */
 static int32 processLifeOperators(TwinEEngine *engine, LifeScriptContext &ctx, int32 valueSize) {
-	const int32 operatorCode = *(ctx.scriptPtr++);
+	const int32 operatorCode = ctx.stream.readByte();
 
 	int32 conditionValue;
 	if (valueSize == 1) {
-		conditionValue = *(ctx.scriptPtr++);
+		conditionValue = ctx.stream.readByte();
 	} else if (valueSize == 2) {
-		conditionValue = *((int16 *)ctx.scriptPtr);
-		ctx.scriptPtr += 2;
+		conditionValue = ctx.stream.readSint16LE();
 	} else {
-		error("Unknown operator value size %d\n", valueSize);
-		return 0;
+		error("Unknown operator value size %d", valueSize);
 	}
 
 	switch (operatorCode) {
@@ -425,7 +438,7 @@ static int32 lEND(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x01*/
 static int32 lNOP(TwinEEngine *engine, LifeScriptContext &ctx) {
-	ctx.scriptPtr++;
+	ctx.stream.skip(1);
 	return 0;
 }
 
@@ -433,15 +446,15 @@ static int32 lNOP(TwinEEngine *engine, LifeScriptContext &ctx) {
 static int32 lSNIF(TwinEEngine *engine, LifeScriptContext &ctx) {
 	const int32 valueSize = processLifeConditions(engine, ctx);
 	if (!processLifeOperators(engine, ctx, valueSize)) {
-		*ctx.opcodePtr = 0x0D; // SWIF
+		ctx.setOpcode(0x0D); // SWIF
 	}
-	ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // condition offset
+	ctx.stream.seek(ctx.stream.readSint16LE()); // condition offset
 	return 0;
 }
 
 /*0x03*/
 static int32 lOFFSET(TwinEEngine *engine, LifeScriptContext &ctx) {
-	ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // offset
+	ctx.stream.seek(ctx.stream.readSint16LE()); // offset
 	return 0;
 }
 
@@ -449,7 +462,7 @@ static int32 lOFFSET(TwinEEngine *engine, LifeScriptContext &ctx) {
 static int32 lNEVERIF(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 valueSize = processLifeConditions(engine, ctx);
 	processLifeOperators(engine, ctx, valueSize);
-	ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // condition offset
+	ctx.stream.seek(ctx.stream.readSint16LE()); // condition offset
 	return 0;
 }
 
@@ -460,7 +473,7 @@ static int32 lNO_IF(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x0A*/
 static int32 lLABEL(TwinEEngine *engine, LifeScriptContext &ctx) {
-	ctx.scriptPtr++;
+	ctx.stream.skip(1);
 	return 0;
 }
 
@@ -473,9 +486,9 @@ static int32 lRETURN(TwinEEngine *engine, LifeScriptContext &ctx) {
 static int32 lIF(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 valueSize = processLifeConditions(engine, ctx);
 	if (!processLifeOperators(engine, ctx, valueSize)) {
-		ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // condition offset
+		ctx.stream.seek(ctx.stream.readSint16LE()); // condition offset
 	} else {
-		ctx.scriptPtr += 2;
+		ctx.stream.skip(2);
 	}
 
 	return 0;
@@ -485,10 +498,10 @@ static int32 lIF(TwinEEngine *engine, LifeScriptContext &ctx) {
 static int32 lSWIF(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 valueSize = processLifeConditions(engine, ctx);
 	if (!processLifeOperators(engine, ctx, valueSize)) {
-		ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // condition offset
+		ctx.stream.seek(ctx.stream.readSint16LE()); // condition offset
 	} else {
-		ctx.scriptPtr += 2;
-		*ctx.opcodePtr = 0x02; // SNIF
+		ctx.stream.skip(2);
+		ctx.setOpcode(0x02); // SNIF
 	}
 
 	return 0;
@@ -498,10 +511,10 @@ static int32 lSWIF(TwinEEngine *engine, LifeScriptContext &ctx) {
 static int32 lONEIF(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 valueSize = processLifeConditions(engine, ctx);
 	if (!processLifeOperators(engine, ctx, valueSize)) {
-		ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // condition offset
+		ctx.stream.seek(ctx.stream.readSint16LE()); // condition offset
 	} else {
-		ctx.scriptPtr += 2;
-		*ctx.opcodePtr = 0x04; // NEVERIF
+		ctx.stream.skip(2);
+		ctx.setOpcode(0x04); // NEVERIF
 	}
 
 	return 0;
@@ -509,75 +522,69 @@ static int32 lONEIF(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x0F*/
 static int32 lELSE(TwinEEngine *engine, LifeScriptContext &ctx) {
-	ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // offset
+	ctx.stream.seek(ctx.stream.readSint16LE()); // offset
 	return 0;
 }
 
 /*0x11*/
 static int32 lBODY(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 bodyIdx = *(ctx.scriptPtr);
+	int32 bodyIdx = ctx.stream.readByte();
 	engine->_actor->initModelActor(bodyIdx, ctx.actorIdx);
-	ctx.scriptPtr++;
 	return 0;
 }
 
 /*0x12*/
 static int32 lBODY_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 otherActorIdx = *(ctx.scriptPtr++);
-	int32 otherBodyIdx = *(ctx.scriptPtr++);
+	int32 otherActorIdx = ctx.stream.readByte();
+	int32 otherBodyIdx = ctx.stream.readByte();
 	engine->_actor->initModelActor(otherBodyIdx, otherActorIdx);
 	return 0;
 }
 
 /*0x13*/
 static int32 lANIM(TwinEEngine *engine, LifeScriptContext &ctx) {
-	AnimationTypes animIdx = (AnimationTypes) * (ctx.scriptPtr++);
+	AnimationTypes animIdx = (AnimationTypes)ctx.stream.readByte();
 	engine->_animations->initAnim(animIdx, 0, 0, ctx.actorIdx);
 	return 0;
 }
 
 /*0x14*/
 static int32 lANIM_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 otherActorIdx = *(ctx.scriptPtr++);
-	AnimationTypes otherAnimIdx = (AnimationTypes) * (ctx.scriptPtr++);
+	int32 otherActorIdx = ctx.stream.readByte();
+	AnimationTypes otherAnimIdx = (AnimationTypes)ctx.stream.readByte();
 	engine->_animations->initAnim(otherAnimIdx, 0, 0, otherActorIdx);
 	return 0;
 }
 
 /*0x15*/
 static int32 lSET_LIFE(TwinEEngine *engine, LifeScriptContext &ctx) {
-	ctx.actor->positionInLifeScript = *((int16 *)ctx.scriptPtr); // offset
-	ctx.scriptPtr += 2;
+	ctx.actor->positionInLifeScript = ctx.stream.readSint16LE(); // offset
 	return 0;
 }
 
 /*0x16*/
 static int32 lSET_LIFE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 otherActorIdx = *(ctx.scriptPtr++);
-	engine->_scene->getActor(otherActorIdx)->positionInLifeScript = *((int16 *)ctx.scriptPtr); // offset
-	ctx.scriptPtr += 2;
+	int32 otherActorIdx = ctx.stream.readByte();
+	engine->_scene->getActor(otherActorIdx)->positionInLifeScript = ctx.stream.readSint16LE(); // offset
 	return 0;
 }
 
 /*0x17*/
 static int32 lSET_TRACK(TwinEEngine *engine, LifeScriptContext &ctx) {
-	ctx.actor->positionInMoveScript = *((int16 *)ctx.scriptPtr); // offset
-	ctx.scriptPtr += 2;
+	ctx.actor->positionInMoveScript = ctx.stream.readSint16LE(); // offset
 	return 0;
 }
 
 /*0x18*/
 static int32 lSET_TRACK_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 otherActorIdx = *(ctx.scriptPtr++);
-	engine->_scene->getActor(otherActorIdx)->positionInMoveScript = *((int16 *)ctx.scriptPtr); // offset
-	ctx.scriptPtr += 2;
+	int32 otherActorIdx = ctx.stream.readByte();
+	engine->_scene->getActor(otherActorIdx)->positionInMoveScript = ctx.stream.readSint16LE(); // offset
 	return 0;
 }
 
 /*0x19*/
 static int32 lMESSAGE(TwinEEngine *engine, LifeScriptContext &ctx) {
-	const int32 textIdx = *((int16 *)ctx.scriptPtr);
-	ctx.scriptPtr += 2;
+	const int32 textIdx = ctx.stream.readSint16LE();
 
 	engine->freezeTime();
 	if (engine->_text->showDialogueBubble) {
@@ -594,18 +601,18 @@ static int32 lMESSAGE(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x1A*/
 static int32 lFALLABLE(TwinEEngine *engine, LifeScriptContext &ctx) {
-	const int32 flag = *(ctx.scriptPtr++);
+	const int32 flag = ctx.stream.readByte();
 	ctx.actor->staticFlags.bCanFall = flag & 1;
 	return 0;
 }
 
 /*0x1B*/
 static int32 lSET_DIRMODE(TwinEEngine *engine, LifeScriptContext &ctx) {
-	const int32 controlMode = *(ctx.scriptPtr++);
+	const int32 controlMode = ctx.stream.readByte();
 
 	ctx.actor->controlMode = (ControlMode)controlMode;
 	if (ctx.actor->controlMode == ControlMode::kFollow) {
-		ctx.actor->followedActor = *(ctx.scriptPtr++);
+		ctx.actor->followedActor = ctx.stream.readByte();
 	}
 
 	return 0;
@@ -613,13 +620,13 @@ static int32 lSET_DIRMODE(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x1C*/
 static int32 lSET_DIRMODE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
-	const int32 otherActorIdx = *(ctx.scriptPtr++);
-	const int32 controlMode = *(ctx.scriptPtr++);
+	const int32 otherActorIdx = ctx.stream.readByte();
+	const int32 controlMode = ctx.stream.readByte();
 
 	ActorStruct *otherActor = engine->_scene->getActor(otherActorIdx);
 	otherActor->controlMode = (ControlMode)controlMode;
 	if (otherActor->controlMode == ControlMode::kFollow) {
-		otherActor->followedActor = *(ctx.scriptPtr++);
+		otherActor->followedActor = ctx.stream.readByte();
 	}
 
 	return 0;
@@ -627,7 +634,7 @@ static int32 lSET_DIRMODE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x1D*/
 static int32 lCAM_FOLLOW(TwinEEngine *engine, LifeScriptContext &ctx) {
-	const int32 followedActorIdx = *(ctx.scriptPtr++);
+	const int32 followedActorIdx = ctx.stream.readByte();
 
 	if (engine->_scene->currentlyFollowedActor != followedActorIdx) {
 		const ActorStruct *followedActor = engine->_scene->getActor(followedActorIdx);
@@ -644,7 +651,7 @@ static int32 lCAM_FOLLOW(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x1E*/
 static int32 lSET_BEHAVIOUR(TwinEEngine *engine, LifeScriptContext &ctx) {
-	const int32 behavior = *(ctx.scriptPtr++);
+	const int32 behavior = ctx.stream.readByte();
 
 	engine->_animations->initAnim(kStanding, 0, 255, 0);
 	engine->_actor->setBehaviour(behavior);
@@ -654,8 +661,8 @@ static int32 lSET_BEHAVIOUR(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x1F*/
 static int32 lSET_FLAG_CUBE(TwinEEngine *engine, LifeScriptContext &ctx) {
-	const int32 flagIdx = *(ctx.scriptPtr++);
-	const int32 flagValue = *(ctx.scriptPtr++);
+	const int32 flagIdx = ctx.stream.readByte();
+	const int32 flagValue = ctx.stream.readByte();
 
 	engine->_scene->sceneFlags[flagIdx] = flagValue;
 
@@ -664,24 +671,20 @@ static int32 lSET_FLAG_CUBE(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x20*/
 static int32 lCOMPORTEMENT(TwinEEngine *engine, LifeScriptContext &ctx) {
-	ctx.scriptPtr++;
+	ctx.stream.skip(1);
 	return 0;
 }
 
 /*0x21*/
 static int32 lSET_COMPORTEMENT(TwinEEngine *engine, LifeScriptContext &ctx) {
-	ctx.actor->positionInLifeScript = *((int16 *)ctx.scriptPtr);
-	ctx.scriptPtr += 2;
+	ctx.actor->positionInLifeScript = ctx.stream.readSint16LE();
 	return 0;
 }
 
 /*0x22*/
 static int32 lSET_COMPORTEMENT_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
-	const int32 otherActorIdx = *(ctx.scriptPtr++);
-
-	engine->_scene->getActor(otherActorIdx)->positionInLifeScript = *((int16 *)ctx.scriptPtr);
-	ctx.scriptPtr += 2;
-
+	const int32 otherActorIdx = ctx.stream.readByte();
+	engine->_scene->getActor(otherActorIdx)->positionInLifeScript = ctx.stream.readSint16LE();
 	return 0;
 }
 
@@ -692,8 +695,8 @@ static int32 lEND_COMPORTEMENT(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x24*/
 static int32 lSET_FLAG_GAME(TwinEEngine *engine, LifeScriptContext &ctx) {
-	const int32 flagIdx = *(ctx.scriptPtr++);
-	const int32 flagValue = *(ctx.scriptPtr++);
+	const int32 flagIdx = ctx.stream.readByte();
+	const int32 flagValue = ctx.stream.readByte();
 
 	engine->_gameState->gameFlags[flagIdx] = flagValue;
 
@@ -702,7 +705,7 @@ static int32 lSET_FLAG_GAME(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x25*/
 static int32 lKILL_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
-	const int32 otherActorIdx = *(ctx.scriptPtr++);
+	const int32 otherActorIdx = ctx.stream.readByte();
 
 	engine->_actor->processActorCarrier(otherActorIdx);
 	ActorStruct *otherActor = engine->_scene->getActor(otherActorIdx);
@@ -742,8 +745,7 @@ static int32 lUSE_ONE_LITTLE_KEY(TwinEEngine *engine, LifeScriptContext &ctx) {
 static int32 lGIVE_GOLD_PIECES(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int16 oldNumKashes = engine->_gameState->inventoryNumKashes;
 	bool hideRange = false;
-	int16 kashes = *((int16 *)ctx.scriptPtr);
-	ctx.scriptPtr += 2;
+	int16 kashes = ctx.stream.readSint16LE();
 
 	engine->_gameState->inventoryNumKashes -= kashes;
 	if (engine->_gameState->inventoryNumKashes < 0) {
@@ -791,9 +793,8 @@ static int32 lRESTORE_L_TRACK(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x2C*/
 static int32 lMESSAGE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
-	const int32 otherActorIdx = *(ctx.scriptPtr++);
-	const int32 textIdx = *((int16 *)ctx.scriptPtr);
-	ctx.scriptPtr += 2;
+	const int32 otherActorIdx = ctx.stream.readByte();
+	const int32 textIdx = ctx.stream.readSint16LE();
 
 	engine->freezeTime();
 	if (engine->_text->showDialogueBubble) {
@@ -816,7 +817,7 @@ static int32 lINC_CHAPTER(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x2E*/
 static int32 lFOUND_OBJECT(TwinEEngine *engine, LifeScriptContext &ctx) {
-	const int32 item = *(ctx.scriptPtr++);
+	const int32 item = ctx.stream.readByte();
 
 	engine->freezeTime();
 	engine->_gameState->processFoundItem(item);
@@ -828,8 +829,7 @@ static int32 lFOUND_OBJECT(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x2F*/
 static int32 lSET_DOOR_LEFT(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 distance = *((int16 *)ctx.scriptPtr);
-	ctx.scriptPtr += 2;
+	int32 distance = ctx.stream.readSint16LE();
 
 	ctx.actor->angle = 0x300;
 	ctx.actor->x = ctx.actor->lastX - distance;
@@ -841,8 +841,7 @@ static int32 lSET_DOOR_LEFT(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x30*/
 static int32 lSET_DOOR_RIGHT(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 distance = *((int16 *)ctx.scriptPtr);
-	ctx.scriptPtr += 2;
+	int32 distance = ctx.stream.readSint16LE();
 
 	ctx.actor->angle = 0x100;
 	ctx.actor->x = ctx.actor->lastX + distance;
@@ -854,8 +853,7 @@ static int32 lSET_DOOR_RIGHT(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x31*/
 static int32 lSET_DOOR_UP(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 distance = *((int16 *)ctx.scriptPtr);
-	ctx.scriptPtr += 2;
+	int32 distance = ctx.stream.readSint16LE();
 
 	ctx.actor->angle = 0x200;
 	ctx.actor->z = ctx.actor->lastZ - distance;
@@ -867,8 +865,7 @@ static int32 lSET_DOOR_UP(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x32*/
 static int32 lSET_DOOR_DOWN(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 distance = *((int16 *)ctx.scriptPtr);
-	ctx.scriptPtr += 2;
+	int32 distance = ctx.stream.readSint16LE();
 
 	ctx.actor->angle = 0;
 	ctx.actor->z = ctx.actor->lastZ + distance;
@@ -880,7 +877,7 @@ static int32 lSET_DOOR_DOWN(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x33*/
 static int32 lGIVE_BONUS(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 flag = *(ctx.scriptPtr++);
+	int32 flag = ctx.stream.readByte();
 
 	if (ctx.actor->bonusParameter & 0x1F0) {
 		engine->_actor->processActorExtraBonus(ctx.actorIdx);
@@ -895,7 +892,7 @@ static int32 lGIVE_BONUS(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x34*/
 static int32 lCHANGE_CUBE(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 sceneIdx = *(ctx.scriptPtr++);
+	int32 sceneIdx = ctx.stream.readByte();
 	engine->_scene->needChangeScene = sceneIdx;
 	engine->_scene->heroPositionType = ScenePositionType::kScene;
 	return 0;
@@ -903,7 +900,7 @@ static int32 lCHANGE_CUBE(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x35*/
 static int32 lOBJ_COL(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 collision = *(ctx.scriptPtr++);
+	int32 collision = ctx.stream.readByte();
 	if (collision != 0) {
 		ctx.actor->staticFlags.bComputeCollisionWithObj = 1;
 	} else {
@@ -914,7 +911,7 @@ static int32 lOBJ_COL(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x36*/
 static int32 lBRICK_COL(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 collision = *(ctx.scriptPtr++);
+	int32 collision = ctx.stream.readByte();
 
 	ctx.actor->staticFlags.bComputeCollisionWithBricks = 0;
 	ctx.actor->staticFlags.bComputeLowCollision = 0;
@@ -932,9 +929,9 @@ static int32 lBRICK_COL(TwinEEngine *engine, LifeScriptContext &ctx) {
 static int32 lOR_IF(TwinEEngine *engine, LifeScriptContext &ctx) {
 	int32 valueSize = processLifeConditions(engine, ctx);
 	if (processLifeOperators(engine, ctx, valueSize)) {
-		ctx.scriptPtr = ctx.actor->lifeScript + *((int16 *)ctx.scriptPtr); // condition offset
+		ctx.stream.seek(ctx.stream.readSint16LE()); // condition offset
 	} else {
-		ctx.scriptPtr += 2;
+		ctx.stream.skip(2);
 	}
 
 	return 0;
@@ -942,13 +939,13 @@ static int32 lOR_IF(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x38*/
 static int32 lINVISIBLE(TwinEEngine *engine, LifeScriptContext &ctx) {
-	ctx.actor->staticFlags.bIsHidden = *(ctx.scriptPtr++);
+	ctx.actor->staticFlags.bIsHidden = ctx.stream.readByte();
 	return 0;
 }
 
 /*0x39*/
 static int32 lZOOM(TwinEEngine *engine, LifeScriptContext &ctx) {
-	engine->zoomScreen = *(ctx.scriptPtr++);
+	engine->zoomScreen = ctx.stream.readByte();
 
 	if (engine->zoomScreen && !engine->_redraw->drawInGameTransBox && engine->cfgfile.SceZoom) {
 		engine->_screens->fadeToBlack(engine->_screens->mainPaletteRGBA);
@@ -968,7 +965,7 @@ static int32 lZOOM(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x3A*/
 static int32 lPOS_POINT(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 trackIdx = *(ctx.scriptPtr++);
+	int32 trackIdx = ctx.stream.readByte();
 
 	const ScenePoint &sp = engine->_scene->sceneTracks[trackIdx];
 	engine->_renderer->destX = sp.x;
@@ -984,14 +981,14 @@ static int32 lPOS_POINT(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x3B*/
 static int32 lSET_MAGIC_LEVEL(TwinEEngine *engine, LifeScriptContext &ctx) {
-	engine->_gameState->magicLevelIdx = *(ctx.scriptPtr++);
+	engine->_gameState->magicLevelIdx = ctx.stream.readByte();
 	engine->_gameState->inventoryMagicPoints = engine->_gameState->magicLevelIdx * 20;
 	return 0;
 }
 
 /*0x3C*/
 static int32 lSUB_MAGIC_POINT(TwinEEngine *engine, LifeScriptContext &ctx) {
-	engine->_gameState->inventoryMagicPoints = *(ctx.scriptPtr++);
+	engine->_gameState->inventoryMagicPoints = ctx.stream.readByte();
 	if (engine->_gameState->inventoryMagicPoints < 0) {
 		engine->_gameState->inventoryMagicPoints = 0;
 	}
@@ -1000,8 +997,8 @@ static int32 lSUB_MAGIC_POINT(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x3D*/
 static int32 lSET_LIFE_POINT_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 otherActorIdx = *(ctx.scriptPtr++);
-	static int32 lifeValue = *(ctx.scriptPtr++);
+	int32 otherActorIdx = ctx.stream.readByte();
+	static int32 lifeValue = ctx.stream.readByte();
 
 	engine->_scene->getActor(otherActorIdx)->life = lifeValue;
 
@@ -1010,8 +1007,8 @@ static int32 lSET_LIFE_POINT_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x3E*/
 static int32 lSUB_LIFE_POINT_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 otherActorIdx = *(ctx.scriptPtr++);
-	static int32 lifeValue = *(ctx.scriptPtr++);
+	int32 otherActorIdx = ctx.stream.readByte();
+	static int32 lifeValue = ctx.stream.readByte();
 
 	engine->_scene->getActor(otherActorIdx)->life -= lifeValue;
 
@@ -1024,17 +1021,26 @@ static int32 lSUB_LIFE_POINT_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x3F*/
 static int32 lHIT_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 otherActorIdx = *(ctx.scriptPtr++);
-	int32 strengthOfHit = *(ctx.scriptPtr++);
+	int32 otherActorIdx = ctx.stream.readByte();
+	int32 strengthOfHit = ctx.stream.readByte();
 	engine->_actor->hitActor(ctx.actorIdx, otherActorIdx, strengthOfHit, engine->_scene->getActor(otherActorIdx)->angle);
 	return 0;
 }
 
 /*0x40*/
 static int32 lPLAY_FLA(TwinEEngine *engine, LifeScriptContext &ctx) {
-	const char *movie = (const char *)ctx.scriptPtr;
-	int32 nameSize = strlen(movie);
-	ctx.scriptPtr += nameSize + 1;
+	int strIdx = 0;
+	char movie[64];
+	do {
+		const byte c = ctx.stream.readByte();
+		if (c == '\0') {
+			break;
+		}
+		movie[strIdx++] = c;
+		if (strIdx >= ARRAYSIZE(movie)) {
+			error("Max string size exceeded for fla name");
+		}
+	} while (true);
 
 	engine->_flaMovies->playFlaMovie(movie);
 	engine->setPalette(engine->_screens->paletteRGBA);
@@ -1046,7 +1052,7 @@ static int32 lPLAY_FLA(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x41*/
 static int32 lPLAY_MIDI(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 midiIdx = *(ctx.scriptPtr++);
+	int32 midiIdx = ctx.stream.readByte();
 	engine->_music->playMidiMusic(midiIdx); // TODO: improve this
 	return 0;
 }
@@ -1061,7 +1067,7 @@ static int32 lINC_CLOVER_BOX(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x43*/
 static int32 lSET_USED_INVENTORY(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 item = *(ctx.scriptPtr++);
+	int32 item = ctx.stream.readByte();
 	if (item < InventoryItems::kKeypad) { // TODO: this looks wrong - why only up to keypad?
 		engine->_gameState->inventoryFlags[item] = 1;
 	}
@@ -1070,16 +1076,14 @@ static int32 lSET_USED_INVENTORY(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x44*/
 static int32 lADD_CHOICE(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 choiceIdx = *((int16 *)ctx.scriptPtr);
-	ctx.scriptPtr += 2;
+	int32 choiceIdx = ctx.stream.readSint16LE();
 	engine->_gameState->gameChoices[engine->_gameState->numChoices++] = choiceIdx;
 	return 0;
 }
 
 /*0x45*/
 static int32 lASK_CHOICE(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 choiceIdx = *((int16 *)ctx.scriptPtr);
-	ctx.scriptPtr += 2;
+	int32 choiceIdx = ctx.stream.readSint16LE();
 
 	engine->freezeTime();
 	if (engine->_text->showDialogueBubble) {
@@ -1096,8 +1100,7 @@ static int32 lASK_CHOICE(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x46*/
 static int32 lBIG_MESSAGE(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 textIdx = *((int16 *)ctx.scriptPtr);
-	ctx.scriptPtr += 2;
+	int32 textIdx = ctx.stream.readSint16LE();
 
 	engine->freezeTime();
 	engine->_text->textClipFull();
@@ -1116,7 +1119,7 @@ static int32 lBIG_MESSAGE(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x47*/
 static int32 lINIT_PINGOUIN(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 pingouinActor = *(ctx.scriptPtr++);
+	int32 pingouinActor = ctx.stream.readByte();
 	engine->_scene->mecaPinguinIdx = pingouinActor;
 	ActorStruct *mecaPinguin = engine->_scene->getActor(pingouinActor);
 	mecaPinguin->dynamicFlags.bIsDead = 1;
@@ -1127,7 +1130,7 @@ static int32 lINIT_PINGOUIN(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x48*/
 static int32 lSET_HOLO_POS(TwinEEngine *engine, LifeScriptContext &ctx) {
-	static int32 location = *(ctx.scriptPtr++);
+	static int32 location = ctx.stream.readByte();
 	engine->_holomap->setHolomapPosition(location);
 	if (engine->_gameState->gameFlags[InventoryItems::kiHolomap]) {
 		engine->_redraw->addOverlay(koInventoryItem, 0, 0, 0, 0, koNormal, 3);
@@ -1138,14 +1141,14 @@ static int32 lSET_HOLO_POS(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x49*/
 static int32 lCLR_HOLO_POS(TwinEEngine *engine, LifeScriptContext &ctx) {
-	static int32 location = *(ctx.scriptPtr++);
+	static int32 location = ctx.stream.readByte();
 	engine->_holomap->clearHolomapPosition(location);
 	return 0;
 }
 
 /*0x4A*/
 static int32 lADD_FUEL(TwinEEngine *engine, LifeScriptContext &ctx) {
-	engine->_gameState->inventoryNumGas += *(ctx.scriptPtr++);
+	engine->_gameState->inventoryNumGas += ctx.stream.readByte();
 	if (engine->_gameState->inventoryNumGas > 100) {
 		engine->_gameState->inventoryNumGas = 100;
 	}
@@ -1154,7 +1157,7 @@ static int32 lADD_FUEL(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x4B*/
 static int32 lSUB_FUEL(TwinEEngine *engine, LifeScriptContext &ctx) {
-	engine->_gameState->inventoryNumGas -= *(ctx.scriptPtr++);
+	engine->_gameState->inventoryNumGas -= ctx.stream.readByte();
 	if (engine->_gameState->inventoryNumGas < 0) {
 		engine->_gameState->inventoryNumGas = 0;
 	}
@@ -1163,15 +1166,14 @@ static int32 lSUB_FUEL(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x4C*/
 static int32 lSET_GRM(TwinEEngine *engine, LifeScriptContext &ctx) {
-	engine->_grid->cellingGridIdx = *(ctx.scriptPtr++);
+	engine->_grid->cellingGridIdx = ctx.stream.readByte();
 	engine->_grid->initCellingGrid(engine->_grid->cellingGridIdx);
 	return 0;
 }
 
 /*0x4D*/
 static int32 lSAY_MESSAGE(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int16 textEntry = *((int16 *)ctx.scriptPtr);
-	ctx.scriptPtr += 2;
+	int16 textEntry = ctx.stream.readSint16LE();
 
 	engine->_redraw->addOverlay(koText, textEntry, 0, 0, ctx.actorIdx, koFollowActor, 2);
 
@@ -1183,9 +1185,8 @@ static int32 lSAY_MESSAGE(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*04E*/
 static int32 lSAY_MESSAGE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 otherActorIdx = *(ctx.scriptPtr++);
-	int16 textEntry = *((int16 *)ctx.scriptPtr);
-	ctx.scriptPtr += 2;
+	int32 otherActorIdx = ctx.stream.readByte();
+	int16 textEntry = ctx.stream.readSint16LE();
 
 	engine->_redraw->addOverlay(koText, textEntry, 0, 0, otherActorIdx, koFollowActor, 2);
 
@@ -1204,8 +1205,7 @@ static int32 lFULL_POINT(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x50*/
 static int32 lBETA(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 newAngle = *((int16 *)ctx.scriptPtr);
-	ctx.scriptPtr += 2;
+	int32 newAngle = ctx.stream.readSint16LE();
 	ctx.actor->angle = newAngle;
 	engine->_movements->clearRealAngle(ctx.actor);
 	return 0;
@@ -1281,7 +1281,7 @@ static int32 lFADE_PAL_ALARM(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x58*/
 static int32 lEXPLODE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 otherActorIdx = *(ctx.scriptPtr++);
+	int32 otherActorIdx = ctx.stream.readByte();
 	ActorStruct *otherActor = engine->_scene->getActor(otherActorIdx);
 
 	engine->_extra->addExtraExplode(otherActor->x, otherActor->y, otherActor->z); // RECHECK this
@@ -1303,9 +1303,8 @@ static int32 lBUBBLE_OFF(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x5B*/
 static int32 lASK_CHOICE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 otherActorIdx = *(ctx.scriptPtr++);
-	int32 choiceIdx = *((int16 *)ctx.scriptPtr);
-	ctx.scriptPtr += 2;
+	int32 otherActorIdx = ctx.stream.readByte();
+	int32 choiceIdx = ctx.stream.readSint16LE();
 
 	engine->freezeTime();
 	if (engine->_text->showDialogueBubble) {
@@ -1369,7 +1368,7 @@ static int32 lMESSAGE_SENDELL(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x5F*/
 static int32 lANIM_SET(TwinEEngine *engine, LifeScriptContext &ctx) {
-	AnimationTypes animIdx = (AnimationTypes) * (ctx.scriptPtr++);
+	AnimationTypes animIdx = (AnimationTypes)ctx.stream.readByte();
 
 	ctx.actor->anim = kAnimNone;
 	ctx.actor->previousAnimIdx = -1;
@@ -1380,7 +1379,7 @@ static int32 lANIM_SET(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x60*/
 static int32 lHOLOMAP_TRAJ(TwinEEngine *engine, LifeScriptContext &ctx) {
-	ctx.scriptPtr++; // TODO
+	ctx.stream.skip(1);
 	return -1;
 }
 
@@ -1414,7 +1413,7 @@ static int32 lMIDI_OFF(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x64*/
 static int32 lPLAY_CD_TRACK(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 track = *(ctx.scriptPtr++);
+	int32 track = ctx.stream.readByte();
 	engine->_music->playTrackMusic(track);
 	return 0;
 }
@@ -1445,8 +1444,7 @@ static int32 lPROJ_3D(TwinEEngine *engine, LifeScriptContext &ctx) {
 
 /*0x67*/
 static int32 lTEXT(TwinEEngine *engine, LifeScriptContext &ctx) {
-	int32 textIdx = *((int16 *)ctx.scriptPtr);
-	ctx.scriptPtr += 2;
+	int32 textIdx = ctx.stream.readSint16LE();
 
 	if (drawVar1 < 440) {
 		if (engine->cfgfile.Version == USA_VERSION) {
@@ -1602,21 +1600,19 @@ void ScriptLife::processLifeScript(int32 actorIdx) {
 	ActorStruct *actor = _engine->_scene->getActor(actorIdx);
 	int32 end = -2;
 
-	// TODO: use Common::MemoryReadStream for the script parsing
-	LifeScriptContext ctx{actorIdx, actor, actor->lifeScript + actor->positionInLifeScript, nullptr};
+	LifeScriptContext ctx(actorIdx, actor);
 	do {
-		ctx.opcodePtr = ctx.scriptPtr;
-		int32 scriptOpcode = *(ctx.scriptPtr++);
-
-		if (scriptOpcode >= 0 && scriptOpcode < ARRAYSIZE(function_map)) {
+		const byte scriptOpcode = ctx.stream.readByte();
+		if (scriptOpcode < ARRAYSIZE(function_map)) {
 			end = function_map[scriptOpcode].function(_engine, ctx);
 		} else {
-			error("Actor %d with wrong offset/opcode - Offset: %d (opcode: %i)", actorIdx, actor->positionInLifeScript, scriptOpcode);
+			error("Actor %d with wrong offset/opcode - Offset: %d (opcode: %i)", actorIdx, ctx.stream.pos() - 1, scriptOpcode);
 		}
 
-		if (end < 0) { // show error message
+		if (end < 0) {
 			warning("Actor %d Life script [%s] not implemented", actorIdx, function_map[scriptOpcode].name);
 		}
+		ctx.updateOpcodePos();
 	} while (end != 1);
 }
 




More information about the Scummvm-git-logs mailing list