[Scummvm-git-logs] scummvm master -> 8a4e6e36cc2fc6a89fcc068180a84b89f7e8b242

mgerhardy noreply at scummvm.org
Thu Feb 13 12:57:53 UTC 2025


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

Summary:
f13f308a35 TWINE: The movement of the meca penguin is different from dos version
71668787d7 TWINE: fixed memory leak in fla sample handling
9c2de6ded6 TWINE: fixed Audio::makeVOCStream call and fixed memory leak in vox samples
8a4e6e36cc TWINE: fixed missing pitchbend parameter for environmental sounds


Commit: f13f308a35a1decd7083ee9837bbd58db12cd2b6
    https://github.com/scummvm/scummvm/commit/f13f308a35a1decd7083ee9837bbd58db12cd2b6
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2025-02-13T13:57:38+01:00

Commit Message:
TWINE: The movement of the meca penguin is different from dos version

fixed issue 13731 (https://bugs.scummvm.org/ticket/13731)

Changed paths:
    engines/twine/debugger/debugtools.cpp
    engines/twine/parser/body.h
    engines/twine/renderer/redraw.cpp
    engines/twine/scene/actor.cpp
    engines/twine/scene/actor.h
    engines/twine/scene/animations.cpp
    engines/twine/scene/collision.cpp
    engines/twine/scene/gamestate.cpp
    engines/twine/scene/movements.cpp
    engines/twine/scene/scene.cpp
    engines/twine/script/script_life.cpp
    engines/twine/shared.h


diff --git a/engines/twine/debugger/debugtools.cpp b/engines/twine/debugger/debugtools.cpp
index 151a81bdb4c..a6b52a33831 100644
--- a/engines/twine/debugger/debugtools.cpp
+++ b/engines/twine/debugger/debugtools.cpp
@@ -538,7 +538,7 @@ static void actorDetailsWindow(int &actorIdx, TwinEEngine *engine) {
 				ImGui::TableNextColumn();
 				ImGui::Text("Strength");
 				ImGui::TableNextColumn();
-				ImGui::Text("%i", actor->_strengthOfHit);
+				ImGui::Text("%i", actor->_hitForce);
 				ImGui::TableNextColumn();
 				ImGui::Text("Hit by");
 				ImGui::TableNextColumn();
diff --git a/engines/twine/parser/body.h b/engines/twine/parser/body.h
index 76b10c7d49e..685d5eff664 100644
--- a/engines/twine/parser/body.h
+++ b/engines/twine/parser/body.h
@@ -32,6 +32,12 @@
 
 namespace TwinE {
 
+/** Actors animation timer structure */
+struct AnimTimerDataStruct {
+	const KeyFrame *ptr = nullptr;
+	int32 time = 0; // keyframe time
+};
+
 class BodyData : public Parser {
 private:
 	void loadVertices(Common::SeekableReadStream &stream);
@@ -55,6 +61,7 @@ protected:
 
 public:
 	bool animated = false;
+	AnimTimerDataStruct _animTimerData;
 
 	BoundingBox bbox;
 	int16 offsetToData = 0;
diff --git a/engines/twine/renderer/redraw.cpp b/engines/twine/renderer/redraw.cpp
index cfff95a7a80..084bb8f7bb3 100644
--- a/engines/twine/renderer/redraw.cpp
+++ b/engines/twine/renderer/redraw.cpp
@@ -30,6 +30,7 @@
 #include "twine/input.h"
 #include "twine/menu/interface.h"
 #include "twine/menu/menu.h"
+#include "twine/parser/body.h"
 #include "twine/parser/sprite.h"
 #include "twine/renderer/renderer.h"
 #include "twine/renderer/screens.h"
@@ -404,7 +405,8 @@ void Redraw::processDrawListActors(const DrawListStruct &drawCmd, bool flagflip)
 	ActorStruct *actor = _engine->_scene->getActor(actorIdx);
 	if (actor->_anim >= 0) {
 		const AnimData &animData = _engine->_resources->_animData[actor->_anim];
-		_engine->_animations->setInterAnimObjet2(actor->_frame, animData, actor->_entityDataPtr->getBody(actor->_body), &actor->_animTimerData);
+		BodyData &bodyData = actor->_entityDataPtr->getBody(actor->_body);
+		_engine->_animations->setInterAnimObjet2(actor->_frame, animData, bodyData, &bodyData._animTimerData);
 	}
 
 	const IVec3 &delta = actor->posObj() - _engine->_grid->_worldCube;
diff --git a/engines/twine/scene/actor.cpp b/engines/twine/scene/actor.cpp
index 9578a89034d..69bafc003aa 100644
--- a/engines/twine/scene/actor.cpp
+++ b/engines/twine/scene/actor.cpp
@@ -125,7 +125,7 @@ void Actor::setBehaviour(HeroBehaviourType behaviour) {
 	sceneHero->_genAnim = AnimationTypes::kAnimNone;
 	sceneHero->_flagAnim = AnimType::kAnimationTypeRepeat;
 
-	_engine->_animations->initAnim(AnimationTypes::kStanding, AnimType::kAnimationTypeRepeat, AnimationTypes::kAnimInvalid, OWN_ACTOR_SCENE_INDEX);
+	_engine->_animations->initAnim(AnimationTypes::kStanding, AnimType::kAnimationTypeRepeat, AnimationTypes::kNoAnim, OWN_ACTOR_SCENE_INDEX);
 }
 
 void Actor::setFrame(int32 actorIdx, uint32 frame) {
@@ -207,7 +207,8 @@ void Actor::setFrame(int32 actorIdx, uint32 frame) {
 void Actor::initSprite(int32 spriteNum, int32 actorIdx) {
 	ActorStruct *localActor = _engine->_scene->getActor(actorIdx);
 
-	localActor->_sprite = spriteNum;
+	localActor->_sprite = spriteNum; // lba2
+
 	if (!localActor->_flags.bSprite3D) {
 		return;
 	}
@@ -240,25 +241,25 @@ int32 Actor::searchBody(BodyType bodyIdx, int32 actorIdx, ActorBoundingBox &acto
 	return (int)bodyIdx;
 }
 
-void Actor::initBody(BodyType bodyIdx, int16 actorIdx) {
+void Actor::initBody(BodyType gennewbody, int16 actorIdx) {
 	ActorStruct *localActor = _engine->_scene->getActor(actorIdx);
 	if (localActor->_flags.bSprite3D) {
 		return;
 	}
 
-	debug(1, "Load body %i for actor %i", (int)bodyIdx, actorIdx);
+	debug(1, "Load body %i for actor %i", (int)gennewbody, actorIdx);
 
-	if (IS_HERO(actorIdx) && _heroBehaviour == HeroBehaviourType::kProtoPack && bodyIdx != BodyType::btTunic && bodyIdx != BodyType::btNormal) {
+	if (IS_HERO(actorIdx) && _heroBehaviour == HeroBehaviourType::kProtoPack && gennewbody != BodyType::btTunic && gennewbody != BodyType::btNormal) {
 		setBehaviour(HeroBehaviourType::kNormal);
 	}
 
 	ActorBoundingBox actorBoundingBox;
-	const int32 newBody = searchBody(bodyIdx, actorIdx, actorBoundingBox);
+	const int32 newBody = searchBody(gennewbody, actorIdx, actorBoundingBox);
 	if (newBody == -1) {
 		localActor->_genBody = BodyType::btNone;
 		localActor->_body = -1;
 		localActor->_boundingBox = BoundingBox();
-		debug("Failed to initialize body %i for actor %i", (int)bodyIdx, actorIdx);
+		debug("Failed to initialize body %i for actor %i", (int)gennewbody, actorIdx);
 		return;
 	}
 
@@ -268,7 +269,7 @@ void Actor::initBody(BodyType bodyIdx, int16 actorIdx) {
 
 	const int32 oldBody = localActor->_body;
 	localActor->_body = newBody;
-	localActor->_genBody = bodyIdx;
+	localActor->_genBody = gennewbody;
 
 	if (actorBoundingBox.hasBoundingBox) {
 		localActor->_boundingBox = actorBoundingBox.bbox;
@@ -305,6 +306,8 @@ void Actor::copyInterAnim(const BodyData &src, BodyData &dest) {
 		return;
 	}
 
+	dest._animTimerData = src._animTimerData;
+
 	const int16 numBones = MIN<int16>((int16)src.getNumBones(), (int16)dest.getNumBones());
 	for (int16 i = 0; i < numBones; ++i) {
 		const BoneFrame *srcBoneFrame = src.getBoneState(i);
@@ -317,7 +320,7 @@ void Actor::startInitObj(int16 actorIdx) {
 	ActorStruct *actor = _engine->_scene->getActor(actorIdx);
 
 	if (actor->_flags.bSprite3D) {
-		if (actor->_strengthOfHit != 0) {
+		if (actor->_hitForce != 0) {
 			actor->_workFlags.bIsHitting = 1;
 		}
 
@@ -340,7 +343,7 @@ void Actor::startInitObj(int16 actorIdx) {
 		actor->_flagAnim = AnimType::kAnimationTypeRepeat;
 
 		if (actor->_body != -1) {
-			_engine->_animations->initAnim(actor->_genAnim, AnimType::kAnimationTypeRepeat, AnimationTypes::kAnimInvalid, actorIdx);
+			_engine->_animations->initAnim(actor->_genAnim, AnimType::kAnimationTypeRepeat, AnimationTypes::kNoAnim, actorIdx);
 		}
 
 		_engine->_movements->initRealAngle(actor->_beta, actor->_beta, LBAAngles::ANGLE_0, &actor->realAngle);
@@ -393,9 +396,9 @@ void Actor::hitObj(int32 actorIdx, int32 actorIdxAttacked, int32 hitforce, int32
 			}
 
 			if (_engine->getRandomNumber() & 1) {
-				_engine->_animations->initAnim(AnimationTypes::kHit2, AnimType::kAnimationInsert, AnimationTypes::kAnimInvalid, actorIdxAttacked);
+				_engine->_animations->initAnim(AnimationTypes::kHit2, AnimType::kAnimationInsert, AnimationTypes::kNoAnim, actorIdxAttacked);
 			} else {
-				_engine->_animations->initAnim(AnimationTypes::kBigHit, AnimType::kAnimationInsert, AnimationTypes::kAnimInvalid, actorIdxAttacked);
+				_engine->_animations->initAnim(AnimationTypes::kBigHit, AnimType::kAnimationInsert, AnimationTypes::kNoAnim, actorIdxAttacked);
 			}
 		}
 
@@ -412,7 +415,7 @@ void Actor::hitObj(int32 actorIdx, int32 actorIdxAttacked, int32 hitforce, int32
 			actor->_lifePoint = 0;
 		}
 	} else {
-		_engine->_animations->initAnim(AnimationTypes::kHit, AnimType::kAnimationInsert, AnimationTypes::kAnimInvalid, actorIdxAttacked);
+		_engine->_animations->initAnim(AnimationTypes::kHit, AnimType::kAnimationInsert, AnimationTypes::kNoAnim, actorIdxAttacked);
 	}
 }
 
diff --git a/engines/twine/scene/actor.h b/engines/twine/scene/actor.h
index a806b4819e8..72e5d550dab 100644
--- a/engines/twine/scene/actor.h
+++ b/engines/twine/scene/actor.h
@@ -51,12 +51,6 @@ struct RealValue {
 	int16 getRealAngle(int32 time);
 };
 
-/** Actors animation timer structure */
-struct AnimTimerDataStruct {
-	const KeyFrame *ptr = nullptr;
-	int32 time = 0;
-};
-
 /** Actors static flags structure */
 struct StaticFlagsStruct {
 	uint32 bComputeCollisionWithObj : 1;    // 0x000001 CHECK_OBJ_COL
@@ -189,7 +183,7 @@ public:
 		int32 Fin;
 	} A3DS;
 
-	int32 _strengthOfHit = 0;
+	int32 _hitForce = 0;
 	int32 _hitBy = -1;
 	BonusParameter _bonusParameter;
 	int32 _beta = 0; // facing angle of actor. Minumum is 0 (SW). Going counter clock wise
@@ -251,7 +245,6 @@ public:
 
 	BoundingBox _boundingBox; // Xmin, YMin, Zmin, Xmax, Ymax, Zmax
 	RealValue realAngle;
-	AnimTimerDataStruct _animTimerData;
 };
 
 inline const IVec3 &ActorStruct::posObj() const {
diff --git a/engines/twine/scene/animations.cpp b/engines/twine/scene/animations.cpp
index e5ef81e0449..44d335c7992 100644
--- a/engines/twine/scene/animations.cpp
+++ b/engines/twine/scene/animations.cpp
@@ -289,7 +289,7 @@ void Animations::processAnimActions(int32 actorIdx) { // GereAnimAction
 		switch (action.type) {
 		case ActionType::ACTION_HITTING:
 			if (action.animFrame - 1 == actor->_frame) {
-				actor->_strengthOfHit = action.strength;
+				actor->_hitForce = action.strength;
 				actor->_workFlags.bIsHitting = 1;
 			}
 			break;
@@ -350,7 +350,7 @@ void Animations::processAnimActions(int32 actorIdx) { // GereAnimAction
 			break;
 		case ActionType::ACTION_HERO_HITTING:
 			if (action.animFrame - 1 == actor->_frame) {
-				actor->_strengthOfHit = magicLevelStrengthOfHit[_engine->_gameState->_magicLevelIdx];
+				actor->_hitForce = magicLevelStrengthOfHit[_engine->_gameState->_magicLevelIdx];
 				actor->_workFlags.bIsHitting = 1;
 			}
 			break;
@@ -421,7 +421,7 @@ bool Animations::initAnim(AnimationTypes genNewAnim, AnimType flag, AnimationTyp
 		return true;
 	}
 
-	if (genNextAnim == AnimationTypes::kAnimInvalid && actor->_flagAnim != AnimType::kAnimationAllThen) {
+	if (genNextAnim == AnimationTypes::kNoAnim && actor->_flagAnim != AnimType::kAnimationAllThen) {
 		genNextAnim = actor->_genAnim;
 	}
 
@@ -453,12 +453,13 @@ bool Animations::initAnim(AnimationTypes genNewAnim, AnimType flag, AnimationTyp
 		flag = AnimType::kAnimationAllThen;
 	}
 
+	BodyData &bodyData = actor->_entityDataPtr->getBody(actor->_body);
 	if (actor->_anim == -1) {
 		// if no previous animation
-		setAnimObjet(0, _engine->_resources->_animData[newanim], actor->_entityDataPtr->getBody(actor->_body), &actor->_animTimerData);
+		setAnimObjet(0, _engine->_resources->_animData[newanim], bodyData, &bodyData._animTimerData);
 	} else {
 		// interpolation between animations
-		stockInterAnim(actor->_entityDataPtr->getBody(actor->_body), &actor->_animTimerData);
+		stockInterAnim(bodyData, &bodyData._animTimerData);
 	}
 
 	actor->_anim = newanim;
@@ -494,7 +495,7 @@ void Animations::doAnim(int32 actorIdx) {
 
 	IVec3 &processActor = actor->_processActor;
 	if (actor->_flags.bSprite3D) {
-		if (actor->_strengthOfHit) {
+		if (actor->_hitForce) {
 			actor->_workFlags.bIsHitting = 1;
 		}
 
@@ -585,8 +586,9 @@ void Animations::doAnim(int32 actorIdx) {
 			const AnimData &animData = _engine->_resources->_animData[actor->_anim];
 
 			bool keyFramePassed = false;
-			if (actor->_entityDataPtr->getBody(actor->_body).isAnimated()) {
-				keyFramePassed = setInterDepObjet(actor->_frame, animData, &actor->_animTimerData);
+			BodyData &bodyData = actor->_entityDataPtr->getBody(actor->_body);
+			if (bodyData.isAnimated()) {
+				keyFramePassed = setInterDepObjet(actor->_frame, animData, &bodyData._animTimerData);
 			}
 
 			if (_animMasterRot) {
@@ -636,7 +638,7 @@ void Animations::doAnim(int32 actorIdx) {
 
 						actor->_flagAnim = AnimType::kAnimationTypeRepeat;
 						actor->_frame = 0;
-						actor->_strengthOfHit = 0;
+						actor->_hitForce = 0;
 					}
 
 					processAnimActions(actorIdx);
@@ -795,10 +797,10 @@ void Animations::doAnim(int32 actorIdx) {
 							if (fallHeight <= (2 * SIZE_BRICK_Y) && actor->_genAnim == AnimationTypes::kForward) {
 								actor->_workFlags.bWasWalkingBeforeFalling = 1;
 							} else {
-								initAnim(AnimationTypes::kFall, AnimType::kAnimationTypeRepeat, AnimationTypes::kAnimInvalid, actorIdx);
+								initAnim(AnimationTypes::kFall, AnimType::kAnimationTypeRepeat, AnimationTypes::kNoAnim, actorIdx);
 							}
 						} else {
-							initAnim(AnimationTypes::kFall, AnimType::kAnimationTypeRepeat, AnimationTypes::kAnimInvalid, actorIdx);
+							initAnim(AnimationTypes::kFall, AnimType::kAnimationTypeRepeat, AnimationTypes::kNoAnim, actorIdx);
 						}
 					}
 				}
diff --git a/engines/twine/scene/collision.cpp b/engines/twine/scene/collision.cpp
index 736205fc3a6..e12e7de8db9 100644
--- a/engines/twine/scene/collision.cpp
+++ b/engines/twine/scene/collision.cpp
@@ -328,7 +328,7 @@ int32 Collision::checkObjCol(int32 actorIdx) {
 				const IVec3 minsTest = actorTest->posObj() + actorTest->_boundingBox.mins;
 				const IVec3 maxsTest = actorTest->posObj() + actorTest->_boundingBox.maxs;
 				if (mins.x < maxsTest.x && maxs.x > minsTest.x && mins.y < maxsTest.y && maxs.y > minsTest.y && mins.z < maxsTest.z && maxs.z > minsTest.z) {
-					_engine->_actor->hitObj(actorIdx, a, ptrobj->_strengthOfHit, ptrobj->_beta + LBAAngles::ANGLE_180);
+					_engine->_actor->hitObj(actorIdx, a, ptrobj->_hitForce, ptrobj->_beta + LBAAngles::ANGLE_180);
 					ptrobj->_workFlags.bIsHitting = 0;
 				}
 			}
diff --git a/engines/twine/scene/gamestate.cpp b/engines/twine/scene/gamestate.cpp
index 95557a15cbf..0982f330c60 100644
--- a/engines/twine/scene/gamestate.cpp
+++ b/engines/twine/scene/gamestate.cpp
@@ -383,7 +383,7 @@ void GameState::doFoundObj(InventoryItems item) {
 	const int32 bodyAnimIdx = _engine->_animations->searchAnim(AnimationTypes::kFoundItem, OWN_ACTOR_SCENE_INDEX);
 	const AnimData &ptranim = _engine->_resources->_animData[bodyAnimIdx];
 
-	_engine->_animations->stockInterAnim(bodyData, &_engine->_scene->_sceneHero->_animTimerData);
+	_engine->_animations->stockInterAnim(bodyData, &bodyData._animTimerData);
 
 	uint frameanim = 0;
 
diff --git a/engines/twine/scene/movements.cpp b/engines/twine/scene/movements.cpp
index 73a90243d63..bc6a7efce54 100644
--- a/engines/twine/scene/movements.cpp
+++ b/engines/twine/scene/movements.cpp
@@ -282,7 +282,7 @@ void Movements::processBehaviourExecution(int actorIdx) {
 		}
 		break;
 	case HeroBehaviourType::kDiscrete:
-		_engine->_animations->initAnim(AnimationTypes::kHide, AnimType::kAnimationTypeRepeat, AnimationTypes::kAnimInvalid, actorIdx);
+		_engine->_animations->initAnim(AnimationTypes::kHide, AnimType::kAnimationTypeRepeat, AnimationTypes::kNoAnim, actorIdx);
 		break;
 	case HeroBehaviourType::kProtoPack:
 	case HeroBehaviourType::kMax:
@@ -332,7 +332,7 @@ void Movements::processManualMovementExecution(int actorIdx) {
 		// if walking should get stopped
 		if (!_engine->_input->isActionActive(TwinEActionType::MoveForward) && !_engine->_input->isActionActive(TwinEActionType::MoveBackward)) {
 			if (_lastJoyFlag && (_heroActionKey != _previousLoopActionKey || _changedCursorKeys != _previousChangedCursorKeys)) {
-				_engine->_animations->initAnim(AnimationTypes::kStanding, AnimType::kAnimationTypeRepeat, AnimationTypes::kAnimInvalid, actorIdx);
+				_engine->_animations->initAnim(AnimationTypes::kStanding, AnimType::kAnimationTypeRepeat, AnimationTypes::kNoAnim, actorIdx);
 			}
 		}
 
@@ -340,17 +340,17 @@ void Movements::processManualMovementExecution(int actorIdx) {
 
 		if (_engine->_input->isActionActive(TwinEActionType::MoveForward)) {
 			if (!_engine->_scene->_flagClimbing) {
-				_engine->_animations->initAnim(AnimationTypes::kForward, AnimType::kAnimationTypeRepeat, AnimationTypes::kAnimInvalid, actorIdx);
+				_engine->_animations->initAnim(AnimationTypes::kForward, AnimType::kAnimationTypeRepeat, AnimationTypes::kNoAnim, actorIdx);
 			}
 			_lastJoyFlag = true;
 		} else if (_engine->_input->isActionActive(TwinEActionType::MoveBackward)) {
-			_engine->_animations->initAnim(AnimationTypes::kBackward, AnimType::kAnimationTypeRepeat, AnimationTypes::kAnimInvalid, actorIdx);
+			_engine->_animations->initAnim(AnimationTypes::kBackward, AnimType::kAnimationTypeRepeat, AnimationTypes::kNoAnim, actorIdx);
 			_lastJoyFlag = true;
 		}
 
 		if (_engine->_input->isActionActive(TwinEActionType::TurnLeft)) {
 			if (actor->_genAnim == AnimationTypes::kStanding) {
-				_engine->_animations->initAnim(AnimationTypes::kTurnLeft, AnimType::kAnimationTypeRepeat, AnimationTypes::kAnimInvalid, actorIdx);
+				_engine->_animations->initAnim(AnimationTypes::kTurnLeft, AnimType::kAnimationTypeRepeat, AnimationTypes::kNoAnim, actorIdx);
 			} else {
 				if (!actor->_workFlags.bIsRotationByAnim) {
 					actor->_beta = actor->realAngle.getRealAngle(_engine->timerRef);
@@ -359,7 +359,7 @@ void Movements::processManualMovementExecution(int actorIdx) {
 			_lastJoyFlag = true;
 		} else if (_engine->_input->isActionActive(TwinEActionType::TurnRight)) {
 			if (actor->_genAnim == AnimationTypes::kStanding) {
-				_engine->_animations->initAnim(AnimationTypes::kTurnRight, AnimType::kAnimationTypeRepeat, AnimationTypes::kAnimInvalid, actorIdx);
+				_engine->_animations->initAnim(AnimationTypes::kTurnRight, AnimType::kAnimationTypeRepeat, AnimationTypes::kNoAnim, actorIdx);
 			} else {
 				if (!actor->_workFlags.bIsRotationByAnim) {
 					actor->_beta = actor->realAngle.getRealAngle(_engine->timerRef);
@@ -430,11 +430,11 @@ void Movements::processRandomAction(int actorIdx) {
 		const int32 angle = ClampAngle(actor->_beta + (_engine->getRandomNumber() & (LBAAngles::ANGLE_180 - 1)) - LBAAngles::ANGLE_90 + LBAAngles::ANGLE_180);
 		initRealAngleConst(actor->_beta, angle, actor->_srot, &actor->realAngle);
 		actor->_delayInMillis = _engine->timerRef + _engine->getRandomNumber(_engine->toSeconds(6)) + _engine->toSeconds(6);
-		_engine->_animations->initAnim(AnimationTypes::kStanding, AnimType::kAnimationTypeRepeat, AnimationTypes::kAnimInvalid, actorIdx);
+		_engine->_animations->initAnim(AnimationTypes::kStanding, AnimType::kAnimationTypeRepeat, AnimationTypes::kNoAnim, actorIdx);
 	}
 
 	if (!actor->realAngle.timeValue) {
-		_engine->_animations->initAnim(AnimationTypes::kForward, AnimType::kAnimationTypeRepeat, AnimationTypes::kAnimInvalid, actorIdx);
+		_engine->_animations->initAnim(AnimationTypes::kForward, AnimType::kAnimationTypeRepeat, AnimationTypes::kNoAnim, actorIdx);
 		if (_engine->timerRef > actor->_delayInMillis) {
 			const int32 angle = ClampAngle(actor->_beta + (_engine->getRandomNumber() & (LBAAngles::ANGLE_180 - 1)) - LBAAngles::ANGLE_90);
 			initRealAngleConst(actor->_beta, angle, actor->_srot, &actor->realAngle);
diff --git a/engines/twine/scene/scene.cpp b/engines/twine/scene/scene.cpp
index c9c587724ca..2cb3456d851 100644
--- a/engines/twine/scene/scene.cpp
+++ b/engines/twine/scene/scene.cpp
@@ -248,7 +248,7 @@ bool Scene::loadSceneLBA2() {
 		act->_posObj.y = (int16)stream.readUint16LE();
 		act->_posObj.z = (int16)stream.readUint16LE();
 		act->_oldPos = act->posObj();
-		act->_strengthOfHit = stream.readByte();
+		act->_hitForce = stream.readByte();
 		setBonusParameterFlags(act, stream.readUint16LE());
 		act->_beta = (int16)stream.readUint16LE();
 		act->_srot = (int16)stream.readUint16LE();
@@ -382,7 +382,7 @@ bool Scene::loadSceneLBA1() {
 		act->_posObj.y = (int16)stream.readUint16LE();
 		act->_posObj.z = (int16)stream.readUint16LE();
 		act->_oldPos = act->posObj();
-		act->_strengthOfHit = stream.readByte();
+		act->_hitForce = stream.readByte();
 		setBonusParameterFlags(act, stream.readUint16LE());
 		act->_bonusParameter.givenNothing = 0;
 		act->_beta = (int16)stream.readUint16LE();
@@ -854,7 +854,7 @@ void Scene::checkZoneSce(int32 actorIdx) {
 							if (actor->_posObj.y >= (zone->mins.y + zone->maxs.y) / 2) {
 								_engine->_animations->initAnim(AnimationTypes::kTopLadder, AnimType::kAnimationAllThen, AnimationTypes::kStanding, actorIdx); // reached end of ladder
 							} else {
-								_engine->_animations->initAnim(AnimationTypes::kClimbLadder, AnimType::kAnimationTypeRepeat, AnimationTypes::kAnimInvalid, actorIdx); // go up in ladder
+								_engine->_animations->initAnim(AnimationTypes::kClimbLadder, AnimType::kAnimationTypeRepeat, AnimationTypes::kNoAnim, actorIdx); // go up in ladder
 							}
 						}
 					}
diff --git a/engines/twine/script/script_life.cpp b/engines/twine/script/script_life.cpp
index d52bcd89958..6cbcf327371 100644
--- a/engines/twine/script/script_life.cpp
+++ b/engines/twine/script/script_life.cpp
@@ -927,7 +927,7 @@ int32 ScriptLife::lMESSAGE(TwinEEngine *engine, LifeScriptContext &ctx) {
 	// if we are in sporty mode, we might have triggered a jump with the special action binding
 	// see https://bugs.scummvm.org/ticket/13676 for more details.
 	if (ctx.actor->isJumpAnimationActive()) {
-		engine->_animations->initAnim(AnimationTypes::kStanding, AnimType::kAnimationTypeRepeat, AnimationTypes::kAnimInvalid, OWN_ACTOR_SCENE_INDEX);
+		engine->_animations->initAnim(AnimationTypes::kStanding, AnimType::kAnimationTypeRepeat, AnimationTypes::kNoAnim, OWN_ACTOR_SCENE_INDEX);
 	}
 
 	engine->_text->drawTextProgressive(textIdx);
@@ -1015,7 +1015,7 @@ int32 ScriptLife::lSET_BEHAVIOUR(TwinEEngine *engine, LifeScriptContext &ctx) {
 	const HeroBehaviourType behavior = (HeroBehaviourType)ctx.stream.readByte();
 	debugC(3, kDebugLevels::kDebugScriptsLife, "LIFE::SET_BEHAVIOUR(%i)", (int)behavior);
 
-	engine->_animations->initAnim(AnimationTypes::kStanding, AnimType::kAnimationTypeRepeat, AnimationTypes::kAnimInvalid, OWN_ACTOR_SCENE_INDEX);
+	engine->_animations->initAnim(AnimationTypes::kStanding, AnimType::kAnimationTypeRepeat, AnimationTypes::kNoAnim, OWN_ACTOR_SCENE_INDEX);
 	engine->_actor->setBehaviour(behavior);
 
 	return 0;
diff --git a/engines/twine/shared.h b/engines/twine/shared.h
index 431630334e3..d7ce54de6fa 100644
--- a/engines/twine/shared.h
+++ b/engines/twine/shared.h
@@ -321,7 +321,7 @@ enum class AnimationTypes {
 	kCarDrivingBackwards = 305,
 	kCarStopping = 306,
 	kCarFrozen = 307,
-	kAnimInvalid = 255 // NO_ANIM
+	kNoAnim = 255 // NO_ANIM
 };
 
 enum class AnimType {


Commit: 71668787d7361e73f1ab10f190f2c6e9d0b86d49
    https://github.com/scummvm/scummvm/commit/71668787d7361e73f1ab10f190f2c6e9d0b86d49
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2025-02-13T13:57:38+01:00

Commit Message:
TWINE: fixed memory leak in fla sample handling

Changed paths:
    engines/twine/audio/sound.cpp


diff --git a/engines/twine/audio/sound.cpp b/engines/twine/audio/sound.cpp
index cbac347ffb6..0119d177096 100644
--- a/engines/twine/audio/sound.cpp
+++ b/engines/twine/audio/sound.cpp
@@ -109,7 +109,7 @@ void Sound::playFlaSample(int32 index, int32 repeat, uint8 balance, int32 volume
 	}
 
 	Common::MemoryReadStream *stream = new Common::MemoryReadStream(sampPtr, sampSize, DisposeAfterUse::YES);
-	Audio::SeekableAudioStream *audioStream = Audio::makeVOCStream(stream, DisposeAfterUse::YES);
+	Audio::SeekableAudioStream *audioStream = Audio::makeVOCStream(stream, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES);
 	playSample(channelIdx, index, audioStream, repeat, Resources::HQR_FLASAMP_FILE);
 }
 


Commit: 9c2de6ded60ac2a31c8b7280f4b54f6a98ecf6fb
    https://github.com/scummvm/scummvm/commit/9c2de6ded60ac2a31c8b7280f4b54f6a98ecf6fb
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2025-02-13T13:57:38+01:00

Commit Message:
TWINE: fixed Audio::makeVOCStream call and fixed memory leak in vox samples

Changed paths:
    engines/twine/audio/sound.cpp


diff --git a/engines/twine/audio/sound.cpp b/engines/twine/audio/sound.cpp
index 0119d177096..210d71ee1b2 100644
--- a/engines/twine/audio/sound.cpp
+++ b/engines/twine/audio/sound.cpp
@@ -183,7 +183,7 @@ bool Sound::playVoxSample(const TextEntry *text) {
 		*sampPtr = 'C';
 	}
 	Common::MemoryReadStream *stream = new Common::MemoryReadStream(sampPtr, sampSize, DisposeAfterUse::YES);
-	Audio::SeekableAudioStream *audioStream = Audio::makeVOCStream(stream, DisposeAfterUse::YES);
+	Audio::SeekableAudioStream *audioStream = Audio::makeVOCStream(stream, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES);
 	return playSample(channelIdx, text->index, audioStream, 1, _engine->_text->_currentVoxBankFile.c_str(), Audio::Mixer::kSpeechSoundType);
 }
 


Commit: 8a4e6e36cc2fc6a89fcc068180a84b89f7e8b242
    https://github.com/scummvm/scummvm/commit/8a4e6e36cc2fc6a89fcc068180a84b89f7e8b242
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2025-02-13T13:57:38+01:00

Commit Message:
TWINE: fixed missing pitchbend parameter for environmental sounds

Changed paths:
    engines/twine/audio/sound.cpp
    engines/twine/scene/scene.cpp


diff --git a/engines/twine/audio/sound.cpp b/engines/twine/audio/sound.cpp
index 210d71ee1b2..09a6beaaf7b 100644
--- a/engines/twine/audio/sound.cpp
+++ b/engines/twine/audio/sound.cpp
@@ -192,6 +192,8 @@ bool Sound::playSample(int channelIdx, int index, Audio::SeekableAudioStream *au
 		warning("Failed to create audio stream for %s: %i", name, index);
 		return false;
 	}
+
+	// infinite loop
 	if (loop == -1) {
 		loop = 0;
 	}
diff --git a/engines/twine/scene/scene.cpp b/engines/twine/scene/scene.cpp
index 2cb3456d851..8bfb351416b 100644
--- a/engines/twine/scene/scene.cpp
+++ b/engines/twine/scene/scene.cpp
@@ -722,10 +722,11 @@ void Scene::processEnvironmentSound() {
 
 			const int16 sampleIdx = _sampleAmbiance[currentAmb];
 			if (sampleIdx != -1) {
-				/*int16 decal = _sampleRound[currentAmb];*/
+				int16 decal = _sampleRound[currentAmb];
 				int16 repeat = _sampleRepeat[currentAmb];
 
-				_engine->_sound->playSample(sampleIdx, repeat, 110, -1, 110);
+				const uint16 pitchbend = 0x1000 + _engine->getRandomNumber(decal) - (decal / 2);
+				_engine->_sound->playSample(sampleIdx, pitchbend, repeat, 110, 110);
 				break;
 			}
 		}




More information about the Scummvm-git-logs mailing list