[Scummvm-git-logs] scummvm master -> 5c1ad5c78601b3f42e8c0e95f7fb731aaee9ceae

mgerhardy noreply at scummvm.org
Tue Jun 14 18:33:26 UTC 2022


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

Summary:
47e858392e TWINE: extract to local variable
6fbf032fc7 TWINE: fixed regression introduced in 3d5d5317a8
a90fef32dc TWINE: more collision fixes from original source code
4384040be5 TWINE: this variable is reset in worldColBrick anyway
93e9b1f080 TWINE: use correct defines
b7a19a5247 TWINE: fixed copy and paste error
5c1ad5c786 TWINE: Black and white palette


Commit: 47e858392e8ec244c04bbd23743d2d97f24b2245
    https://github.com/scummvm/scummvm/commit/47e858392e8ec244c04bbd23743d2d97f24b2245
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2022-06-14T20:27:10+02:00

Commit Message:
TWINE: extract to local variable

Changed paths:
    engines/twine/scene/animations.cpp
    engines/twine/scene/collision.cpp
    engines/twine/scene/collision.h


diff --git a/engines/twine/scene/animations.cpp b/engines/twine/scene/animations.cpp
index 5bb651b00c4..766b6caba29 100644
--- a/engines/twine/scene/animations.cpp
+++ b/engines/twine/scene/animations.cpp
@@ -628,13 +628,14 @@ void Animations::doAnim(int32 actorIdx) {
 		}
 	}
 
+	Collision* collision = _engine->_collision;
 	// actor standing on another actor
 	if (actor->_carryBy != -1) {
 		const ActorStruct *standOnActor = _engine->_scene->getActor(actor->_carryBy);
 		processActor -= standOnActor->_collisionPos;
 		processActor += standOnActor->pos();
 
-		if (!_engine->_collision->standingOnActor(actorIdx, actor->_carryBy)) {
+		if (!collision->standingOnActor(actorIdx, actor->_carryBy)) {
 			actor->_carryBy = -1; // no longer standing on other actor
 		}
 	}
@@ -647,7 +648,7 @@ void Animations::doAnim(int32 actorIdx) {
 
 	// actor collisions with bricks
 	if (actor->_staticFlags.bComputeCollisionWithBricks) {
-		_engine->_collision->_collision.y = 0;
+		collision->_collision.y = 0;
 
 		ShapeType brickShape = _engine->_grid->worldColBrick(previousActor);
 
@@ -655,39 +656,39 @@ void Animations::doAnim(int32 actorIdx) {
 			if (brickShape == ShapeType::kSolid) {
 				actor->_pos.y = processActor.y = (processActor.y / SIZE_BRICK_Y) * SIZE_BRICK_Y + SIZE_BRICK_Y; // go upper
 			} else {
-				_engine->_collision->reajustPos(processActor, brickShape);
+				collision->reajustPos(processActor, brickShape);
 			}
 		}
 
 		if (actor->_staticFlags.bComputeCollisionWithObj) {
-			_engine->_collision->checkObjCol(actorIdx);
+			collision->checkObjCol(actorIdx);
 		}
 
 		if (actor->_carryBy != -1 && actor->_dynamicFlags.bIsFalling) {
-			_engine->_collision->receptionObj();
+			collision->receptionObj();
 		}
 
-		_engine->_collision->_causeActorDamage = 0;
+		collision->_causeActorDamage = 0;
 
 		const IVec3 processActorSave = processActor;
 
 		if (IS_HERO(actorIdx) && !actor->_staticFlags.bComputeLowCollision) {
 			// check hero collisions with bricks
-			_engine->_collision->doCornerReajustTwinkel(actor, actor->_boundingBox.mins.x, actor->_boundingBox.mins.y, actor->_boundingBox.mins.z, 1);
-			_engine->_collision->doCornerReajustTwinkel(actor, actor->_boundingBox.maxs.x, actor->_boundingBox.mins.y, actor->_boundingBox.mins.z, 2);
-			_engine->_collision->doCornerReajustTwinkel(actor, actor->_boundingBox.maxs.x, actor->_boundingBox.mins.y, actor->_boundingBox.maxs.z, 4);
-			_engine->_collision->doCornerReajustTwinkel(actor, actor->_boundingBox.mins.x, actor->_boundingBox.mins.y, actor->_boundingBox.maxs.z, 8);
+			collision->doCornerReajustTwinkel(actor, actor->_boundingBox.mins.x, actor->_boundingBox.mins.y, actor->_boundingBox.mins.z, 1);
+			collision->doCornerReajustTwinkel(actor, actor->_boundingBox.maxs.x, actor->_boundingBox.mins.y, actor->_boundingBox.mins.z, 2);
+			collision->doCornerReajustTwinkel(actor, actor->_boundingBox.maxs.x, actor->_boundingBox.mins.y, actor->_boundingBox.maxs.z, 4);
+			collision->doCornerReajustTwinkel(actor, actor->_boundingBox.mins.x, actor->_boundingBox.mins.y, actor->_boundingBox.maxs.z, 8);
 		} else {
 			// check other actors collisions with bricks
-			_engine->_collision->doCornerReajust(actor, actor->_boundingBox.mins.x, actor->_boundingBox.mins.y, actor->_boundingBox.mins.z, 1);
-			_engine->_collision->doCornerReajust(actor, actor->_boundingBox.maxs.x, actor->_boundingBox.mins.y, actor->_boundingBox.mins.z, 2);
-			_engine->_collision->doCornerReajust(actor, actor->_boundingBox.maxs.x, actor->_boundingBox.mins.y, actor->_boundingBox.maxs.z, 4);
-			_engine->_collision->doCornerReajust(actor, actor->_boundingBox.mins.x, actor->_boundingBox.mins.y, actor->_boundingBox.maxs.z, 8);
+			collision->doCornerReajust(actor, actor->_boundingBox.mins.x, actor->_boundingBox.mins.y, actor->_boundingBox.mins.z, 1);
+			collision->doCornerReajust(actor, actor->_boundingBox.maxs.x, actor->_boundingBox.mins.y, actor->_boundingBox.mins.z, 2);
+			collision->doCornerReajust(actor, actor->_boundingBox.maxs.x, actor->_boundingBox.mins.y, actor->_boundingBox.maxs.z, 4);
+			collision->doCornerReajust(actor, actor->_boundingBox.mins.x, actor->_boundingBox.mins.y, actor->_boundingBox.maxs.z, 8);
 		}
 		processActor = processActorSave;
 
 		// process wall hit while running
-		if (_engine->_collision->_causeActorDamage && !actor->_dynamicFlags.bIsFalling && IS_HERO(_currentlyProcessedActorIdx) && _engine->_actor->_heroBehaviour == HeroBehaviourType::kAthletic && actor->_genAnim == AnimationTypes::kForward) {
+		if (collision->_causeActorDamage && !actor->_dynamicFlags.bIsFalling && IS_HERO(_currentlyProcessedActorIdx) && _engine->_actor->_heroBehaviour == HeroBehaviourType::kAthletic && actor->_genAnim == AnimationTypes::kForward) {
 			IVec3 destPos = _engine->_movements->rotateActor(actor->_boundingBox.mins.x, actor->_boundingBox.mins.z, actor->_angle + ANGLE_360 + ANGLE_135);
 
 			destPos.x += processActor.x;
@@ -713,8 +714,8 @@ void Animations::doAnim(int32 actorIdx) {
 		if (brickShape != ShapeType::kNone) {
 			if (brickShape == ShapeType::kSolid) {
 				if (actor->_dynamicFlags.bIsFalling) {
-					_engine->_collision->receptionObj();
-					processActor.y = (_engine->_collision->_collision.y * SIZE_BRICK_Y) + SIZE_BRICK_Y;
+					collision->receptionObj();
+					processActor.y = (collision->_collision.y * SIZE_BRICK_Y) + SIZE_BRICK_Y;
 				} else {
 					if (IS_HERO(actorIdx) && _engine->_actor->_heroBehaviour == HeroBehaviourType::kAthletic && actor->_genAnim == AnimationTypes::kForward && _engine->_cfgfile.WallCollision) { // avoid wall hit damage
 						_engine->_extra->initSpecial(actor->_pos.x, actor->_pos.y + 1000, actor->_pos.z, ExtraSpecialType::kHitStars);
@@ -736,10 +737,10 @@ void Animations::doAnim(int32 actorIdx) {
 				}
 			} else {
 				if (actor->_dynamicFlags.bIsFalling) {
-					_engine->_collision->receptionObj();
+					collision->receptionObj();
 				}
 
-				_engine->_collision->reajustPos(processActor, brickShape);
+				collision->reajustPos(processActor, brickShape);
 			}
 
 			actor->_dynamicFlags.bIsFalling = 0;
@@ -749,10 +750,10 @@ void Animations::doAnim(int32 actorIdx) {
 
 				if (brickShape != ShapeType::kNone) {
 					if (actor->_dynamicFlags.bIsFalling) {
-						_engine->_collision->receptionObj();
+						collision->receptionObj();
 					}
 
-					_engine->_collision->reajustPos(processActor, brickShape);
+					collision->reajustPos(processActor, brickShape);
 				} else {
 					if (!actor->_dynamicFlags.bIsRotationByAnim) {
 						actor->_dynamicFlags.bIsFalling = 1;
@@ -781,16 +782,16 @@ void Animations::doAnim(int32 actorIdx) {
 		}
 
 		// if under the map, than die
-		if (_engine->_collision->_collision.y == -1) {
+		if (collision->_collision.y == -1) {
 			actor->setLife(0);
 		}
 	} else {
 		if (actor->_staticFlags.bComputeCollisionWithObj) {
-			_engine->_collision->checkObjCol(actorIdx);
+			collision->checkObjCol(actorIdx);
 		}
 	}
 
-	if (_engine->_collision->_causeActorDamage) {
+	if (collision->_causeActorDamage) {
 		actor->setBrickCausesDamage();
 	}
 
diff --git a/engines/twine/scene/collision.cpp b/engines/twine/scene/collision.cpp
index e8050e1f485..3af999d41b6 100644
--- a/engines/twine/scene/collision.cpp
+++ b/engines/twine/scene/collision.cpp
@@ -189,6 +189,7 @@ void Collision::handlePushing(const IVec3 &minsTest, const IVec3 &maxsTest, Acto
 
 	const int32 newAngle = _engine->_movements->getAngleAndSetTargetActorDistance(processActor, actorTest->pos());
 
+	// protect against chain reactions
 	if (actorTest->_staticFlags.bCanBePushed && !actor->_staticFlags.bCanBePushed) {
 		actorTest->_animStep.y = 0;
 
diff --git a/engines/twine/scene/collision.h b/engines/twine/scene/collision.h
index db8f3af74dc..5c55464ad26 100644
--- a/engines/twine/scene/collision.h
+++ b/engines/twine/scene/collision.h
@@ -38,7 +38,7 @@ private:
 	void handlePushing(const IVec3 &minsTest, const IVec3 &maxsTest, ActorStruct *actor, ActorStruct *actorTest);
 
 	/** Actor collision coordinate */
-	IVec3 _processCollision;
+	IVec3 _processCollision; // SaveNxw, SaveNyw, SaveNzw
 public:
 	Collision(TwinEEngine *engine);
 	/** Actor collision coordinate */


Commit: 6fbf032fc78bfa5972e6b0710cec52a25c1a9b1a
    https://github.com/scummvm/scummvm/commit/6fbf032fc78bfa5972e6b0710cec52a25c1a9b1a
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2022-06-14T20:32:38+02:00

Commit Message:
TWINE: fixed regression introduced in 3d5d5317a8

the modification of the processActor values from checkActorCollisionWithBricks and checkHeroCollisionWithBricks were
lost. The bug is that you could move crates into walls in the 'sokoban'-scene (scene 35).

See https://bugs.scummvm.org/ticket/13177

Once we remove the processActorSave hack, this would re-introduced the tank bug in scene 63 - that's why the fix
is non functional yet.

Changed paths:
    engines/twine/scene/animations.cpp
    engines/twine/scene/collision.cpp
    engines/twine/scene/collision.h


diff --git a/engines/twine/scene/animations.cpp b/engines/twine/scene/animations.cpp
index 766b6caba29..66a655d98a9 100644
--- a/engines/twine/scene/animations.cpp
+++ b/engines/twine/scene/animations.cpp
@@ -671,6 +671,7 @@ void Animations::doAnim(int32 actorIdx) {
 		collision->_causeActorDamage = 0;
 
 		const IVec3 processActorSave = processActor;
+		collision->setCollisionPos(processActor);
 
 		if (IS_HERO(actorIdx) && !actor->_staticFlags.bComputeLowCollision) {
 			// check hero collisions with bricks
diff --git a/engines/twine/scene/collision.cpp b/engines/twine/scene/collision.cpp
index 3af999d41b6..d3bee402c00 100644
--- a/engines/twine/scene/collision.cpp
+++ b/engines/twine/scene/collision.cpp
@@ -293,6 +293,10 @@ int32 Collision::checkObjCol(int32 actorIdx) {
 	return actor->_collision;
 }
 
+void Collision::setCollisionPos(const IVec3 &pos) {
+	_processCollision = pos;
+}
+
 void Collision::doCornerReajustTwinkel(ActorStruct *actor, int32 x, int32 y, int32 z, int32 damageMask) {
 	IVec3 &processActor = actor->_processActor;
 	IVec3 &previousActor = actor->_previousActor;
diff --git a/engines/twine/scene/collision.h b/engines/twine/scene/collision.h
index 5c55464ad26..060aad4d43f 100644
--- a/engines/twine/scene/collision.h
+++ b/engines/twine/scene/collision.h
@@ -68,6 +68,7 @@ public:
 	 */
 	int32 checkObjCol(int32 actorIdx);
 
+	void setCollisionPos(const IVec3 &pos);
 	/**
 	 * Check Hero collision with bricks
 	 * @param x Hero X coordinate


Commit: a90fef32dc0e764c53a934e3fbb60ad9ff39aad4
    https://github.com/scummvm/scummvm/commit/a90fef32dc0e764c53a934e3fbb60ad9ff39aad4
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2022-06-14T20:33:00+02:00

Commit Message:
TWINE: more collision fixes from original source code

Changed paths:
    engines/twine/scene/actor.h
    engines/twine/scene/collision.cpp
    engines/twine/scene/collision.h
    engines/twine/scene/grid.cpp
    engines/twine/scene/grid.h
    engines/twine/twine.cpp


diff --git a/engines/twine/scene/actor.h b/engines/twine/scene/actor.h
index 98a27542449..78d330f26a7 100644
--- a/engines/twine/scene/actor.h
+++ b/engines/twine/scene/actor.h
@@ -70,7 +70,7 @@ struct StaticFlagsStruct {
 	uint32 bCanBePushed : 1;                // 0x000010 PUSHABLE
 	uint32 bComputeLowCollision : 1;        // 0x000020 COL_BASSE
 	uint32 bCanDrown : 1;                   // 0x000040 CHECK_CODE_JEU
-	uint32 bComputeCollisionWithFloor : 1;  // 0x000080
+	uint32 bComputeCollisionWithFloor : 1;  // 0x000080 CHECK_WATER_COL
 	uint32 bUnk0100 : 1;                    // 0x000100
 	uint32 bIsHidden : 1;                   // 0x000200 INVISIBLE - not drawn but all computed
 	uint32 bIsSpriteActor : 1;              // 0x000400 SPRITE_3D - a sprite not a 3D object
diff --git a/engines/twine/scene/collision.cpp b/engines/twine/scene/collision.cpp
index d3bee402c00..a16f9ad5ac5 100644
--- a/engines/twine/scene/collision.cpp
+++ b/engines/twine/scene/collision.cpp
@@ -231,6 +231,61 @@ void Collision::handlePushing(const IVec3 &minsTest, const IVec3 &maxsTest, Acto
 	}
 }
 
+bool Collision::checkValidObjPos(int32 actorIdx) {
+	const ActorStruct *actor = _engine->_scene->getActor(actorIdx);
+
+	const int16 x0 = actor->pos().x + actor->_boundingBox.mins.x;
+	const int16 x1 = actor->pos().x + actor->_boundingBox.maxs.x;
+	const int16 y0 = actor->pos().y + actor->_boundingBox.mins.y;
+	const int16 y1 = actor->pos().y + actor->_boundingBox.maxs.y;
+	const int16 z0 = actor->pos().z + actor->_boundingBox.mins.z;
+	const int16 z1 = actor->pos().z + actor->_boundingBox.maxs.z;
+
+	if (x0 < 0 || x0 > SIZE_BRICK_XZ * 63) {
+		return false;
+	}
+	if (x1 < 0 || x1 > SIZE_BRICK_XZ * 63) {
+		return false;
+	}
+	if (z0 < 0 || z0 > SIZE_BRICK_XZ * 63) {
+		return false;
+	}
+	if (z1 < 0 || z1 > SIZE_BRICK_XZ * 63) {
+		return false;
+	}
+
+	Grid *grid = _engine->_grid;
+	if (grid->worldColBrickFull(x0, y0, z0, actor->_boundingBox.maxs.y, actorIdx) != ShapeType::kNone) {
+		return false;
+	}
+	if (grid->worldColBrickFull(x1, y0, z0, actor->_boundingBox.maxs.y, actorIdx) != ShapeType::kNone) {
+		return false;
+	}
+	if (grid->worldColBrickFull(x1, y0, z1, actor->_boundingBox.maxs.y, actorIdx) != ShapeType::kNone) {
+		return false;
+	}
+	if (grid->worldColBrickFull(x0, y0, z1, actor->_boundingBox.maxs.y, actorIdx) != ShapeType::kNone) {
+		return false;
+	}
+
+	for (int32 n = 0; n < _engine->_scene->_sceneNumActors; ++n) {
+		const ActorStruct *actorTest = _engine->_scene->getActor(n);
+		if (n != actorIdx && actorTest->_body != -1 && !actor->_staticFlags.bIsHidden && actorTest->_carryBy != actorIdx) {
+			const int16 xt0 = actorTest->pos().x + actorTest->_boundingBox.mins.x;
+			const int16 xt1 = actorTest->pos().x + actorTest->_boundingBox.maxs.x;
+			const int16 yt0 = actorTest->pos().y + actorTest->_boundingBox.mins.y;
+			const int16 yt1 = actorTest->pos().y + actorTest->_boundingBox.maxs.y;
+			const int16 zt0 = actorTest->pos().z + actorTest->_boundingBox.mins.z;
+			const int16 zt1 = actorTest->pos().z + actorTest->_boundingBox.maxs.z;
+
+			if (x0 < xt1 && x1 > xt0 && y0 < yt1 && y1 > yt0 && z0 < zt1 && z1 > zt0) {
+				return false;
+			}
+		}
+	}
+	return true;
+}
+
 int32 Collision::checkObjCol(int32 actorIdx) {
 	ActorStruct *actor = _engine->_scene->getActor(actorIdx);
 
@@ -309,14 +364,14 @@ void Collision::doCornerReajustTwinkel(ActorStruct *actor, int32 x, int32 y, int
 	if (processActor.x >= 0 && processActor.z >= 0 && processActor.x <= SCENE_SIZE_MAX && processActor.z <= SCENE_SIZE_MAX) {
 		const BoundingBox &bbox = _engine->_actor->_processActorPtr->_boundingBox;
 		reajustPos(processActor, brickShape);
-		brickShape = _engine->_grid->fullWorldColBrick(processActor, bbox.maxs.y);
+		brickShape = _engine->_grid->worldColBrickFull(processActor, bbox.maxs.y, OWN_ACTOR_SCENE_INDEX);
 
 		if (brickShape == ShapeType::kSolid) {
 			_causeActorDamage |= damageMask;
-			brickShape = _engine->_grid->fullWorldColBrick(processActor.x, processActor.y, previousActor.z + z, bbox.maxs.y);
+			brickShape = _engine->_grid->worldColBrickFull(processActor.x, processActor.y, previousActor.z + z, bbox.maxs.y, OWN_ACTOR_SCENE_INDEX);
 
 			if (brickShape == ShapeType::kSolid) {
-				brickShape = _engine->_grid->fullWorldColBrick(x + previousActor.x, processActor.y, processActor.z, bbox.maxs.y);
+				brickShape = _engine->_grid->worldColBrickFull(x + previousActor.x, processActor.y, processActor.z, bbox.maxs.y, OWN_ACTOR_SCENE_INDEX);
 
 				if (brickShape != ShapeType::kSolid) {
 					_processCollision.x = previousActor.x;
diff --git a/engines/twine/scene/collision.h b/engines/twine/scene/collision.h
index 060aad4d43f..eae368c416f 100644
--- a/engines/twine/scene/collision.h
+++ b/engines/twine/scene/collision.h
@@ -67,6 +67,7 @@ public:
 	 * @param actorIx Current process actor index
 	 */
 	int32 checkObjCol(int32 actorIdx);
+	bool checkValidObjPos(int32 actorIdx);
 
 	void setCollisionPos(const IVec3 &pos);
 	/**
diff --git a/engines/twine/scene/grid.cpp b/engines/twine/scene/grid.cpp
index b9610d8a2bc..2df7f4029ce 100644
--- a/engines/twine/scene/grid.cpp
+++ b/engines/twine/scene/grid.cpp
@@ -33,6 +33,7 @@
 #include "twine/scene/actor.h"
 #include "twine/scene/collision.h"
 #include "twine/scene/scene.h"
+#include "twine/shared.h"
 #include "twine/twine.h"
 
 #define CELLING_GRIDS_START_INDEX 120
@@ -41,11 +42,11 @@ namespace TwinE {
 
 Grid::Grid(TwinEEngine *engine) : _engine(engine) {
 	_blockBufferSize = SIZE_CUBE_X * SIZE_CUBE_Z * SIZE_CUBE_Y * sizeof(BlockEntry);
-	_blockBuffer = (uint8 *)malloc(_blockBufferSize);
+	_bufCube = (uint8 *)malloc(_blockBufferSize);
 }
 
 Grid::~Grid() {
-	free(_blockBuffer);
+	free(_bufCube);
 	for (int32 i = 0; i < ARRAYSIZE(_brickMaskTable); i++) {
 		free(_brickMaskTable[i]);
 	}
@@ -400,7 +401,7 @@ void Grid::createGridMap() {
 
 		for (int32 x = 0; x < SIZE_CUBE_X; x++) {
 			const int32 gridOffset = READ_LE_UINT16(_currentGrid + 2 * (x + gridIdx));
-			createGridColumn(_currentGrid + gridOffset, _currentGridSize - gridOffset, _blockBuffer + blockOffset, _blockBufferSize - blockOffset);
+			createGridColumn(_currentGrid + gridOffset, _currentGridSize - gridOffset, _bufCube + blockOffset, _blockBufferSize - blockOffset);
 			blockOffset += 2 * SIZE_CUBE_Y;
 		}
 	}
@@ -416,7 +417,7 @@ void Grid::createCellingGridMap(const uint8 *gridPtr, int32 gridPtrSize) {
 		for (int32 x = 0; x < SIZE_CUBE_X; x++) {
 			const int gridOffset = READ_LE_UINT16(tempGridPtr);
 			tempGridPtr += 2;
-			createCellingGridColumn(gridPtr + gridOffset, gridPtrSize - gridOffset, _blockBuffer + blockOffset, _blockBufferSize - blockOffset);
+			createCellingGridColumn(gridPtr + gridOffset, gridPtrSize - gridOffset, _bufCube + blockOffset, _blockBufferSize - blockOffset);
 			blockOffset += 2 * SIZE_CUBE_Y;
 		}
 		currGridOffset += SIZE_CUBE_X + SIZE_CUBE_Z;
@@ -583,7 +584,7 @@ bool Grid::drawBrickSprite(int32 index, int32 posX, int32 posY, const uint8 *ptr
 
 const uint8 *Grid::getBlockBufferGround(const IVec3 &pos, int32 &ground) {
 	const IVec3 &collision = updateCollisionCoordinates(pos.x, pos.y, pos.z);
-	const uint8 *ptr = _blockBuffer
+	const uint8 *ptr = _bufCube
 					   + collision.y * 2
 					   + collision.x * SIZE_CUBE_Y * 2
 					   + collision.z * SIZE_CUBE_X * SIZE_CUBE_Y * 2;
@@ -691,15 +692,15 @@ void Grid::redrawGrid() { // AffGrille
 	}
 }
 
-BlockEntry Grid::getBlockEntry(int32 x, int32 y, int32 z) const {
-	const uint8 *blockBufferPtr = _blockBuffer;
-	blockBufferPtr += x * SIZE_CUBE_Y * 2;
-	blockBufferPtr += y * 2;
-	blockBufferPtr += (z * SIZE_CUBE_X * 2) * SIZE_CUBE_Y;
+BlockEntry Grid::getBlockEntry(int32 xmap, int32 ymap, int32 zmap) const {
+	const uint8 *pCube = _bufCube;
+	pCube += xmap * SIZE_CUBE_Y * 2;
+	pCube += ymap * 2;
+	pCube += (zmap * SIZE_CUBE_X * 2) * SIZE_CUBE_Y;
 
 	BlockEntry entry;
-	entry.blockIdx = *blockBufferPtr;
-	entry.brickBlockIdx = *(blockBufferPtr + 1);
+	entry.blockIdx = *pCube;
+	entry.brickBlockIdx = *(pCube + 1);
 	return entry;
 }
 
@@ -737,7 +738,22 @@ const IVec3 &Grid::updateCollisionCoordinates(int32 x, int32 y, int32 z) {
 	return _engine->_collision->_collision;
 }
 
-ShapeType Grid::fullWorldColBrick(int32 x, int32 y, int32 z, int32 y2) {
+bool Grid::shouldCheckWaterCol(int32 actorIdx) const {
+	if (actorIdx == OWN_ACTOR_SCENE_INDEX) {
+		ActorStruct *ptrobj = _engine->_scene->getActor(actorIdx);
+		if (_engine->_actor->_heroBehaviour != HeroBehaviourType::kProtoPack
+		 && ptrobj->_staticFlags.bComputeCollisionWithFloor
+		 && !ptrobj->_staticFlags.bIsHidden
+		 && !ptrobj->_dynamicFlags.bIsFalling
+		 && ptrobj->_carryBy == -1) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+ShapeType Grid::worldColBrickFull(int32 x, int32 y, int32 z, int32 y2, int32 actorIdx) {
 	const IVec3 &collision = updateCollisionCoordinates(x, y, z);
 
 	if (collision.y <= -1) {
@@ -748,7 +764,8 @@ ShapeType Grid::fullWorldColBrick(int32 x, int32 y, int32 z, int32 y2) {
 		return ShapeType::kNone;
 	}
 
-	uint8 *pCube = _blockBuffer;
+	bool checkWater = shouldCheckWaterCol(actorIdx);
+	uint8 *pCube = _bufCube;
 	pCube += collision.x * SIZE_CUBE_Y * 2;
 	pCube += collision.y * 2;
 	pCube += collision.z * (SIZE_CUBE_X * SIZE_CUBE_Y * 2);
@@ -756,12 +773,34 @@ ShapeType Grid::fullWorldColBrick(int32 x, int32 y, int32 z, int32 y2) {
 	uint8 block = *pCube;
 
 	ShapeType brickShape;
+	const uint8 tmpBrickIdx = *(pCube + 1);
 	if (block) {
-		const uint8 tmpBrickIdx = *(pCube + 1);
 		const BlockDataEntry *blockPtr = getBlockPointer(block, tmpBrickIdx);
-		brickShape = (ShapeType)blockPtr->brickShape;
+		if (checkWater && blockPtr->brickType == WATER_BRICK) {
+			brickShape = ShapeType::kSolid; // full collision
+		} else {
+			brickShape = (ShapeType)blockPtr->brickShape;
+		}
 	} else {
-		brickShape = (ShapeType) * (pCube + 1);
+		brickShape = (ShapeType)tmpBrickIdx; // maybe transparency
+		if (checkWater) {
+			uint8 *pCode = pCube;
+			for (y = collision.y - 1; y >= 0; y--) {
+				pCode -= 2;
+				uint8 code = *pCode;
+				if (code) {
+					const BlockDataEntry *blockPtr = getBlockPointer(block, 0);
+					if (blockPtr->brickType == WATER_BRICK) {
+						// Special check mount funfrock
+						if (_engine->_scene->_currentSceneIdx != LBA1SceneId::Polar_Island_on_the_rocky_peak) {
+							// full collision
+							return brickShape = ShapeType::kSolid;
+						}
+					}
+					break; // stop parsing at first encountered brick
+				}
+			}
+		}
 	}
 
 	int32 ymax = (y2 + (SIZE_BRICK_Y - 1)) / SIZE_BRICK_Y;
@@ -777,27 +816,18 @@ ShapeType Grid::fullWorldColBrick(int32 x, int32 y, int32 z, int32 y2) {
 }
 
 uint8 Grid::worldCodeBrick(int32 x, int32 y, int32 z) {
-	const IVec3 &collision = updateCollisionCoordinates(x, y, z);
-
-	if (collision.x < 0 || collision.x >= SIZE_CUBE_X) {
-		return 0; // none
-	}
-
-	if (collision.y <= -1) {
-		return 1; // solid
-	}
-
-	if (collision.y < 0 || collision.y >= SIZE_CUBE_Y || collision.z < 0 || collision.z >= SIZE_CUBE_Z) {
-		return 0; // none
-	}
-
-	const BlockEntry entry = getBlockEntry(collision.x, collision.y, collision.z);
-	if (entry.blockIdx) {
-		const BlockDataEntry *blockPtr = getBlockPointer(entry.blockIdx, entry.brickBlockIdx);
-		return blockPtr->brickType;
+	uint8 code = 0xF0U;
+	if (y > -1) {
+		const IVec3 &collision = updateCollisionCoordinates(x, y, z);
+
+		const BlockEntry entry = getBlockEntry(collision.x, collision.y, collision.z);
+		if (entry.blockIdx) {
+			const BlockDataEntry *blockPtr = getBlockPointer(entry.blockIdx, entry.brickBlockIdx);
+			code = blockPtr->brickType;
+		}
 	}
 
-	return 0xF0U;
+	return code;
 }
 
 void Grid::centerOnActor(const ActorStruct* actor) {
diff --git a/engines/twine/scene/grid.h b/engines/twine/scene/grid.h
index 96574d1b0cc..7b6b4900330 100644
--- a/engines/twine/scene/grid.h
+++ b/engines/twine/scene/grid.h
@@ -173,13 +173,15 @@ private:
 
 	/** Celling grid brick block buffer */
 	int32 _blockBufferSize = 0;
-	uint8 *_blockBuffer = nullptr;
+	uint8 *_bufCube = nullptr;
 
 	const BrickEntry* getBrickEntry(int32 j, int32 i) const;
 
 	const IVec3 &updateCollisionCoordinates(int32 x, int32 y, int32 z);
 
-	BlockEntry getBlockEntry(int32 x, int32 y, int32 z) const;
+	BlockEntry getBlockEntry(int32 xmap, int32 ymap, int32 zmap) const;
+
+	bool shouldCheckWaterCol(int32 actorIdx) const;
 public:
 	Grid(TwinEEngine *engine);
 	~Grid();
@@ -287,7 +289,7 @@ public:
 
 	ShapeType worldColBrick(int32 x, int32 y, int32 z);
 
-	ShapeType fullWorldColBrick(int32 x, int32 y, int32 z, int32 y2);
+	ShapeType worldColBrickFull(int32 x, int32 y, int32 z, int32 y2, int32 actorIdx);
 
 	uint8 worldCodeBrick(int32 x, int32 y, int32 z);
 
@@ -295,8 +297,8 @@ public:
 		return worldColBrick(pos.x, pos.y, pos.z);
 	}
 
-	inline ShapeType fullWorldColBrick(const IVec3 &pos, int32 y2) {
-		return fullWorldColBrick(pos.x, pos.y, pos.z, y2);
+	inline ShapeType worldColBrickFull(const IVec3 &pos, int32 y2, int32 actorIdx) {
+		return worldColBrickFull(pos.x, pos.y, pos.z, y2, actorIdx);
 	}
 };
 
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 40fe1178393..c7c30d02525 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -712,7 +712,7 @@ void TwinEEngine::processInventoryAction() {
 
 		penguin->_angle = _scene->_sceneHero->_angle;
 
-		if (!_collision->checkObjCol(_scene->_mecaPenguinIdx)) {
+		if (!_collision->checkValidObjPos(_scene->_mecaPenguinIdx)) {
 			penguin->setLife(kActorMaxLife);
 			penguin->_genBody = BodyType::btNone;
 			_actor->initModelActor(BodyType::btNormal, _scene->_mecaPenguinIdx);


Commit: 4384040be565747981d264387a402687dc998d50
    https://github.com/scummvm/scummvm/commit/4384040be565747981d264387a402687dc998d50
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2022-06-14T20:33:00+02:00

Commit Message:
TWINE: this variable is reset in worldColBrick anyway

Changed paths:
    engines/twine/scene/animations.cpp


diff --git a/engines/twine/scene/animations.cpp b/engines/twine/scene/animations.cpp
index 66a655d98a9..dd06eb73917 100644
--- a/engines/twine/scene/animations.cpp
+++ b/engines/twine/scene/animations.cpp
@@ -648,8 +648,6 @@ void Animations::doAnim(int32 actorIdx) {
 
 	// actor collisions with bricks
 	if (actor->_staticFlags.bComputeCollisionWithBricks) {
-		collision->_collision.y = 0;
-
 		ShapeType brickShape = _engine->_grid->worldColBrick(previousActor);
 
 		if (brickShape != ShapeType::kNone) {


Commit: 93e9b1f080308b4f0f916b0fd32c630ce63a3961
    https://github.com/scummvm/scummvm/commit/93e9b1f080308b4f0f916b0fd32c630ce63a3961
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2022-06-14T20:33:00+02:00

Commit Message:
TWINE: use correct defines

Changed paths:
    engines/twine/scene/collision.cpp


diff --git a/engines/twine/scene/collision.cpp b/engines/twine/scene/collision.cpp
index a16f9ad5ac5..0b85525397f 100644
--- a/engines/twine/scene/collision.cpp
+++ b/engines/twine/scene/collision.cpp
@@ -99,9 +99,9 @@ void Collision::reajustPos(IVec3 &processActor, ShapeType brickShape) const {
 		return;
 	}
 
-	const int32 xw = (_collision.x * SIZE_BRICK_XZ) - SIZE_BRICK_Y;
+	const int32 xw = (_collision.x * SIZE_BRICK_XZ) - DEMI_BRICK_XZ;
 	const int32 yw = _collision.y * SIZE_BRICK_Y;
-	const int32 zw = (_collision.z * SIZE_BRICK_XZ) - SIZE_BRICK_Y;
+	const int32 zw = (_collision.z * SIZE_BRICK_XZ) - DEMI_BRICK_XZ;
 
 	// double-side stairs
 	switch (brickShape) {


Commit: b7a19a524768c05f19aa76c308a6f3e482a9332c
    https://github.com/scummvm/scummvm/commit/b7a19a524768c05f19aa76c308a6f3e482a9332c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2022-06-14T20:33:00+02:00

Commit Message:
TWINE: fixed copy and paste error

Changed paths:
    engines/twine/scene/grid.cpp


diff --git a/engines/twine/scene/grid.cpp b/engines/twine/scene/grid.cpp
index 2df7f4029ce..f612e0da8e7 100644
--- a/engines/twine/scene/grid.cpp
+++ b/engines/twine/scene/grid.cpp
@@ -794,7 +794,7 @@ ShapeType Grid::worldColBrickFull(int32 x, int32 y, int32 z, int32 y2, int32 act
 						// Special check mount funfrock
 						if (_engine->_scene->_currentSceneIdx != LBA1SceneId::Polar_Island_on_the_rocky_peak) {
 							// full collision
-							return brickShape = ShapeType::kSolid;
+							return ShapeType::kSolid;
 						}
 					}
 					break; // stop parsing at first encountered brick


Commit: 5c1ad5c78601b3f42e8c0e95f7fb731aaee9ceae
    https://github.com/scummvm/scummvm/commit/5c1ad5c78601b3f42e8c0e95f7fb731aaee9ceae
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2022-06-14T20:33:00+02:00

Commit Message:
TWINE: Black and white palette

this fixes https://bugs.scummvm.org/ticket/13166

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


diff --git a/engines/twine/scene/scene.cpp b/engines/twine/scene/scene.cpp
index c97bb7a8ecc..24a5e204e06 100644
--- a/engines/twine/scene/scene.cpp
+++ b/engines/twine/scene/scene.cpp
@@ -455,7 +455,7 @@ void Scene::resetScene() {
 		_engine->_redraw->overlayList[i].info0 = -1;
 	}
 
-	_engine->_screens->_useAlternatePalette = false;
+	_engine->_screens->setNormalPal();
 }
 
 void Scene::reloadCurrentScene() {
@@ -583,7 +583,6 @@ void Scene::changeScene() {
 	_engine->_gameState->_inventoryNumKeys = 0;
 	_engine->_disableScreenRecenter = false;
 
-
 	ActorStruct *followedActor = getActor(_currentlyFollowedActor);
 	_engine->_grid->centerOnActor(followedActor);
 




More information about the Scummvm-git-logs mailing list