[Scummvm-git-logs] scummvm master -> e770dc1b92c601a12ac2a7e813cd8d665ce8fd42

neuromancer noreply at scummvm.org
Sun Aug 24 17:16:47 UTC 2025


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

Summary:
108e97f77e FREESCAPE: reimplemented player movement to be smoother, only used in non-driller and non-dark games
e770dc1b92 FREESCAPE: removed unused variable


Commit: 108e97f77ede6a0c0753c91e5fc85016931f621a
    https://github.com/scummvm/scummvm/commit/108e97f77ede6a0c0753c91e5fc85016931f621a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2025-08-24T19:18:53+02:00

Commit Message:
FREESCAPE: reimplemented player movement to be smoother, only used in non-driller and non-dark games

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/detection.h
    engines/freescape/events.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/driller/driller.cpp
    engines/freescape/games/eclipse/eclipse.cpp
    engines/freescape/metaengine.cpp
    engines/freescape/movement.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 47b1dc77e59..475a929c0a5 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -701,7 +701,7 @@ static const ADGameDescription gameDescriptions[] = {
 		Common::EN_ANY,
 		Common::kPlatformDOS,
 		ADGF_NO_FLAGS,
-		GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)
+		GUIO4(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA, GAMEOPTION_MODERN_MOVEMENT)
 	},
 	{
 		// Erbe Software release
@@ -718,7 +718,7 @@ static const ADGameDescription gameDescriptions[] = {
 		Common::EN_ANY,
 		Common::kPlatformDOS,
 		ADGF_NO_FLAGS,
-		GUIO3(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA)
+		GUIO4(GUIO_NOMIDI, GUIO_RENDEREGA, GUIO_RENDERCGA, GAMEOPTION_MODERN_MOVEMENT)
 	},
 	{
 		"totaleclipse", // Tape relese
diff --git a/engines/freescape/detection.h b/engines/freescape/detection.h
index 7c36bb42d4e..0bbc27bba04 100644
--- a/engines/freescape/detection.h
+++ b/engines/freescape/detection.h
@@ -30,6 +30,7 @@
 #define GAMEOPTION_DISABLE_FALLING      GUIO_GAMEOPTIONS5
 #define GAMEOPTION_INVERT_Y             GUIO_GAMEOPTIONS6
 #define GAMEOPTION_AUTHENTIC_GRAPHICS   GUIO_GAMEOPTIONS7
+#define GAMEOPTION_MODERN_MOVEMENT      GUIO_GAMEOPTIONS10
 
 // Driller options
 #define GAMEOPTION_AUTOMATIC_DRILLING   GUIO_GAMEOPTIONS8
diff --git a/engines/freescape/events.cpp b/engines/freescape/events.cpp
index e8b0df0e968..622931cd4fb 100644
--- a/engines/freescape/events.cpp
+++ b/engines/freescape/events.cpp
@@ -102,6 +102,7 @@ void EventManagerWrapper::purgeKeyboardEvents() {
 	_delegate->purgeKeyboardEvents();
 	_currentKeyDown.keycode = Common::KEYCODE_INVALID;
 	_currentActionDown = kActionNone;
+	_keyRepeatTime = 0;
 }
 
 void EventManagerWrapper::purgeMouseEvents() {
@@ -118,4 +119,8 @@ void EventManagerWrapper::clearExitEvents() {
 
 }
 
+bool EventManagerWrapper::isActionActive(const Common::CustomEventType &action) {
+	return _currentActionDown == action;
+}
+
 } // namespace Freescape
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index c81f9d677d5..d4ae7f447ae 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -88,6 +88,13 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	if (!Common::parseBool(ConfMan.get("invert_y"), _invertY))
 		error("Failed to parse bool from invert_y option");
 
+	_smoothMovement = false;
+	if (!Common::parseBool(ConfMan.get("smooth_movement"), _smoothMovement))
+		error("Failed to parse bool from smooth_movement option");
+
+	if (isDriller() || isSpaceStationOblivion() || isDark())
+		_smoothMovement = false;
+
 	_gameStateControl = kFreescapeGameStateStart;
 	_startArea = 0;
 	_startEntrance = 0;
@@ -99,6 +106,9 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	_position = Math::Vector3d(0, 0, 0);
 	_lastPosition = Math::Vector3d(0, 0, 0);
 	_hasFallen = false;
+	_isCollidingWithWall = false;
+	_isStepping = false;
+	_isFalling = false;
 	_maxFallingDistance = 64;
 	_velocity = Math::Vector3d(0, 0, 0);
 	_cameraFront = Math::Vector3d(0, 0, 0);
@@ -116,6 +126,12 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 	_currentDemoMousePosition = _crossairPosition;
 	_flyMode = false;
 	_noClipMode = false;
+	_moveForward = false;
+	_moveBackward = false;
+	_strafeLeft = false;
+	_strafeRight = false;
+	_moveUp = false;
+	_moveDown = false;
 	_playerWasCrushed = false;
 	_forceEndGame = false;
 	_syncSound = false;
@@ -518,8 +534,8 @@ void FreescapeEngine::warpMouseToCrossair() {
 
 void FreescapeEngine::processInput() {
 	float currentFrame = g_system->getMillis();
-	float deltaTime = 20.0;
 	_lastFrame = currentFrame;
+
 	Common::Event event;
 	Common::Point mousePos;
 
@@ -550,17 +566,23 @@ void FreescapeEngine::processInput() {
 			if (_hasFallen || _playerWasCrushed)
 				break;
 			switch (event.customType) {
-			case kActionMoveUp:
-				move(kForwardMovement, _scaleVector.x(), deltaTime);
+				case kActionMoveUp:
+				_moveForward = true;
 				break;
 			case kActionMoveDown:
-				move(kBackwardMovement, _scaleVector.x(), deltaTime);
+				_moveBackward = true;
 				break;
 			case kActionMoveLeft:
-				move(kLeftMovement, _scaleVector.y(), deltaTime);
+				_strafeLeft = true;
 				break;
 			case kActionMoveRight:
-				move(kRightMovement, _scaleVector.y(), deltaTime);
+				_strafeRight = true;
+				break;
+			case kActionRiseOrFlyUp:
+				_moveUp = true;
+				break;
+			case kActionLowerOrFlyDown:
+				_moveDown = true;
 				break;
 			case kActionShoot:
 				shoot();
@@ -613,6 +635,41 @@ void FreescapeEngine::processInput() {
 				break;
 			}
 			break;
+
+		case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
+			if (_hasFallen || _playerWasCrushed)
+				break;
+			switch (event.customType) {
+			case kActionMoveUp:
+				_moveForward = false;
+				break;
+			case kActionMoveDown:
+				_moveBackward = false;
+				break;
+			case kActionMoveLeft:
+				_strafeLeft = false;
+				break;
+			case kActionMoveRight:
+				_strafeRight = false;
+				break;
+			case kActionRiseOrFlyUp:
+				if (!_flyMode)
+					rise();
+				else
+					_moveUp = false;
+				break;
+			case kActionLowerOrFlyDown:
+				if (!_flyMode)
+					lower();
+				else
+					_moveDown = false;
+				break;
+			default:
+				releasedKey(event.customType);
+				break;
+			}
+			break;
+
 		case Common::EVENT_KEYDOWN:
 			if (_hasFallen || _playerWasCrushed)
 				break;
@@ -781,6 +838,10 @@ Common::Error FreescapeEngine::run() {
 	g_system->updateScreen();
 
 	while (!shouldQuit()) {
+		float currentFrame = g_system->getMillis();
+		float deltaTime = (currentFrame - _lastFrame) / 1000.0f;
+		_lastFrame = currentFrame;
+
 		updateTimeVariables();
 		if (_gameStateControl == kFreescapeGameStateRestart) {
 			initGameState();
@@ -789,6 +850,7 @@ Common::Error FreescapeEngine::run() {
 			endGame();
 
 		processInput();
+		updatePlayerMovement(deltaTime);
 		if (_demoMode)
 			generateDemoInput();
 
@@ -974,6 +1036,14 @@ void FreescapeEngine::initGameState() {
 	_yaw = 0;
 	_pitch = 0;
 	_roll = 0;
+
+	_moveForward = false;
+	_moveBackward = false;
+	_strafeLeft = false;
+	_strafeRight = false;
+	_moveUp = false;
+	_moveDown = false;
+
 	_endGameKeyPressed = false;
 	_endGamePlayerEndArea = false;
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 682a7553a83..5d31ad0af6c 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -151,6 +151,7 @@ public:
 	void purgeMouseEvents();
 	void pushEvent(Common::Event &event);
 	void clearExitEvents();
+	bool isActionActive(const Common::CustomEventType &action);
 
 private:
 	// for continuous events (keyDown)
@@ -334,6 +335,16 @@ public:
 	bool _shootMode;
 	bool _noClipMode;
 	bool _invertY;
+
+	bool _smoothMovement;
+	// Player movement state
+	bool _moveForward;
+	bool _moveBackward;
+	bool _strafeLeft;
+	bool _strafeRight;
+	bool _moveUp;
+	bool _moveDown;
+
 	virtual void initKeymaps(Common::Keymap *engineKeyMap, Common::Keymap *infoScreenKeyMap, const char *target);
 	EventManagerWrapper *_eventManager;
 	void processInput();
@@ -343,7 +354,9 @@ public:
 	virtual void releasedKey(const int keycode);
 	Common::Point getNormalizedPosition(Common::Point position);
 	virtual bool onScreenControls(Common::Point mouse);
-	void move(CameraMovement direction, uint8 scale, float deltaTime);
+	void updatePlayerMovement(float deltaTime);
+	void updatePlayerMovementSmooth(float deltaTime);
+	void updatePlayerMovementClassic(float deltaTime);
 	void resolveCollisions(Math::Vector3d newPosition);
 	virtual void checkIfStillInArea();
 	void changePlayerHeight(int index);
@@ -358,6 +371,9 @@ public:
 	bool tryStepUp(Math::Vector3d currentPosition);
 	bool tryStepDown(Math::Vector3d currentPosition);
 	bool _hasFallen;
+	bool _isCollidingWithWall;
+	bool _isStepping;
+	bool _isFalling;
 	int _maxFallingDistance;
 	int _maxShield;
 	int _maxEnergy;
diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp
index af8acda17be..962539b04ba 100644
--- a/engines/freescape/games/driller/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -927,16 +927,16 @@ void DrillerEngine::endGame() {
 
 bool DrillerEngine::onScreenControls(Common::Point mouse) {
 	if (_moveFowardArea.contains(mouse)) {
-		move(kForwardMovement, _scaleVector.x(), 20.0);
+		//move(kForwardMovement, _scaleVector.x(), 20.0);
 		return true;
 	} else if (_moveLeftArea.contains(mouse)) {
-		move(kLeftMovement, _scaleVector.y(), 20.0);
+		//move(kLeftMovement, _scaleVector.y(), 20.0);
 		return true;
 	} else if (_moveRightArea.contains(mouse)) {
-		move(kRightMovement, _scaleVector.y(), 20.0);
+		//move(kRightMovement, _scaleVector.y(), 20.0);
 		return true;
 	} else if (_moveBackArea.contains(mouse)) {
-		move(kBackwardMovement, _scaleVector.x(), 20.0);
+		//move(kBackwardMovement, _scaleVector.x(), 20.0);
 		return true;
 	} else if (_moveUpArea.contains(mouse)) {
 		rise();
diff --git a/engines/freescape/games/eclipse/eclipse.cpp b/engines/freescape/games/eclipse/eclipse.cpp
index fccbcb3848c..9d1d9538806 100644
--- a/engines/freescape/games/eclipse/eclipse.cpp
+++ b/engines/freescape/games/eclipse/eclipse.cpp
@@ -35,9 +35,9 @@ namespace Freescape {
 EclipseEngine::EclipseEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEngine(syst, gd) {
 	// These sounds can be overriden by the class of each platform
 	_soundIndexShoot = 8;
-	_soundIndexCollide = 3;
+	_soundIndexCollide = 4;
 	_soundIndexFall = 3;
-	_soundIndexClimb = 4;
+	_soundIndexClimb = 3;
 	_soundIndexMenu = -1;
 	_soundIndexStart = 9;
 	_soundIndexAreaChange = 5;
diff --git a/engines/freescape/metaengine.cpp b/engines/freescape/metaengine.cpp
index 7a4aee4d24f..198c3f87927 100644
--- a/engines/freescape/metaengine.cpp
+++ b/engines/freescape/metaengine.cpp
@@ -135,6 +135,17 @@ static const ADExtraGuiOptionsMap optionsList[] = {
 			0
 		}
 	},
+	{
+		GAMEOPTION_MODERN_MOVEMENT,
+		{
+			_s("Smoother movement"),
+			_s("Use smoother movements instead of discrete steps"),
+			"smooth_movement",
+			true,
+			0,
+			0
+		}
+	},
 	AD_EXTRA_GUI_OPTIONS_TERMINATOR
 };
 
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 1b330642507..51a7b0fc2e7 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -362,33 +362,54 @@ void FreescapeEngine::checkIfStillInArea() {
 		_position.y() = _lastPosition.z();
 }
 
-void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTime) {
+void FreescapeEngine::updatePlayerMovement(float deltaTime) {
+	if (_smoothMovement)
+		updatePlayerMovementSmooth(deltaTime);
+	else
+		updatePlayerMovementClassic(deltaTime);
+}
+
+void FreescapeEngine::updatePlayerMovementClassic(float deltaTime) {
+	if (!_moveForward && !_moveBackward && !_strafeLeft && !_strafeRight)
+		return;
+
 	debugC(1, kFreescapeDebugMove, "old player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 	int previousAreaID = _currentArea->getAreaID();
 
-	Math::Vector3d stepFront = _cameraFront * (float(_playerSteps[_playerStepIndex]) / 2 / _cameraFront.length());
-	Math::Vector3d stepRight = _cameraRight * (float(_playerSteps[_playerStepIndex]) / 2 / _cameraRight.length());
+	Math::Vector3d stepFront;
+	Math::Vector3d stepRight;
 
-	stepFront.x() = floor(stepFront.x()) + 0.5;
-	stepFront.z() = floor(stepFront.z()) + 0.5;
+	if (_playerSteps[_playerStepIndex] > 2) {
+		stepFront = _cameraFront * (float(_playerSteps[_playerStepIndex]) / 2 / _cameraFront.length());
+		stepRight = _cameraRight * (float(_playerSteps[_playerStepIndex]) / 2 / _cameraRight.length());
 
-	float positionY = _position.y();
-	Math::Vector3d destination;
-	switch (direction) {
-	case kForwardMovement:
-		destination = _position + stepFront;
-		break;
-	case kBackwardMovement:
-		destination = _position - stepFront;
-		break;
-	case kRightMovement:
-		destination = _position - stepRight;
-		break;
-	case kLeftMovement:
-		destination = _position + stepRight;
-		break;
+		stepFront.x() = floor(stepFront.x()) + 0.5;
+		stepFront.z() = floor(stepFront.z()) + 0.5;
+	} else {
+		stepFront = _cameraFront * (float(_playerSteps[_playerStepIndex]) / _cameraFront.length());
+		stepRight = _cameraRight * (float(_playerSteps[_playerStepIndex]) / _cameraRight.length());
+
+		stepFront.x() = ceil(stepFront.x());
+		stepFront.z() = ceil(stepFront.z());
 	}
 
+	float positionY = _position.y();
+	Math::Vector3d destination = _position;
+
+	if (_moveForward)
+		destination += stepFront;
+	if (_moveBackward)
+		destination -= stepFront;
+	if (_strafeRight)
+		destination -= stepRight;
+	if (_strafeLeft)
+		destination += stepRight;
+
+	_moveForward = false;
+	_moveBackward = false;
+	_strafeLeft = false;
+	_strafeRight = false;
+
 	if (!_flyMode)
 		destination.y() = positionY;
 	resolveCollisions(destination);
@@ -403,6 +424,42 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
 	clearGameBit(31);
 }
 
+void FreescapeEngine::updatePlayerMovementSmooth(float deltaTime) {
+	if (!_moveForward && !_moveBackward && !_strafeLeft && !_strafeRight)
+		return;
+
+	const float moveSpeed = _playerSteps[_playerStepIndex] * 5.0f;
+	Math::Vector3d moveDir;
+
+	if (_moveForward)
+		moveDir += _cameraFront;
+	else if (_moveBackward)
+		moveDir -= _cameraFront;
+	else if (_strafeLeft)
+		moveDir += _cameraRight;
+	else if (_strafeRight)
+		moveDir -= _cameraRight;
+
+	if (_flyMode) {
+		if (_moveUp)
+			moveDir.y() += 1.0f;
+		if (_moveDown)
+			moveDir.y() -= 1.0f;
+	}
+
+	moveDir.normalize();
+	moveDir = moveDir * moveSpeed * deltaTime;
+	if (moveDir.length() > 1.0f) {
+		Math::Vector3d destination = _position + moveDir;
+		resolveCollisions(destination);
+		checkIfStillInArea();
+		_lastPosition = _position;
+		executeMovementConditions();
+	}
+	_gotoExecuted = false;
+	clearGameBit(31);
+}
+
 void FreescapeEngine::resolveCollisions(Math::Vector3d const position) {
 	if (_noClipMode) {
 		_position = position;
@@ -414,6 +471,16 @@ void FreescapeEngine::resolveCollisions(Math::Vector3d const position) {
 
 	_gotoExecuted = false;
 	bool executed = runCollisionConditions(lastPosition, newPosition);
+	if (executed) {
+		_moveForward = false;
+		_moveBackward = false;
+		_strafeLeft = false;
+		_strafeRight = false;
+		_moveUp = false;
+		_moveDown = false;
+		_eventManager->purgeKeyboardEvents();
+	}
+
 	if (_gotoExecuted) {
 		_gotoExecuted = false;
 		return;
@@ -431,6 +498,8 @@ void FreescapeEngine::resolveCollisions(Math::Vector3d const position) {
 		return;
 	}
 
+	// If the player has not moved, try to step up
+	bool steppedUp = false;
 	if ((lastPosition - newPosition).length() < 1) { // If the player has not moved
 		// Try to step up
 		newPosition = position;
@@ -448,9 +517,14 @@ void FreescapeEngine::resolveCollisions(Math::Vector3d const position) {
 		if (!executed)
 			setGameBit(31);
 
-		playSound(_soundIndexCollide, false);
-	}
+		debug("Player blocked at position %f %f %f playing collision sound!", newPosition.x(), newPosition.y(), newPosition.z());
+		if (!_isCollidingWithWall)
+			playSound(_soundIndexCollide, false);
+		_isCollidingWithWall = true;
+	} else
+		_isCollidingWithWall = false;
 
+	// Check for falling
 	lastPosition = newPosition;
 	newPosition.y() = -8192;
 	newPosition = _currentArea->resolveCollisions(lastPosition, newPosition, _playerHeight);


Commit: e770dc1b92c601a12ac2a7e813cd8d665ce8fd42
    https://github.com/scummvm/scummvm/commit/e770dc1b92c601a12ac2a7e813cd8d665ce8fd42
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2025-08-24T19:19:59+02:00

Commit Message:
FREESCAPE: removed unused variable

Changed paths:
    engines/freescape/movement.cpp


diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 51a7b0fc2e7..2cb5fa525eb 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -499,7 +499,6 @@ void FreescapeEngine::resolveCollisions(Math::Vector3d const position) {
 	}
 
 	// If the player has not moved, try to step up
-	bool steppedUp = false;
 	if ((lastPosition - newPosition).length() < 1) { // If the player has not moved
 		// Try to step up
 		newPosition = position;




More information about the Scummvm-git-logs mailing list