[Scummvm-git-logs] scummvm master -> 0f46495c4f32a56c3660a9c3cdb5f4c9b6345235

neuromancer noreply at scummvm.org
Mon Oct 6 01:20:21 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:
4a69190cfa FREESCAPE: update gate image for castle zx in freescape.dat
0f46495c4f FREESCAPE: thunder effect for castle (zx)


Commit: 4a69190cfa1b2e451a6e00d54b617b37b58e24b3
    https://github.com/scummvm/scummvm/commit/4a69190cfa1b2e451a6e00d54b617b37b58e24b3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2025-10-05T22:18:07-03:00

Commit Message:
FREESCAPE: update gate image for castle zx in freescape.dat

Changed paths:
    devtools/create_freescape/castle_gate_ZX Spectrum.bmp
    dists/engine-data/freescape.dat


diff --git a/devtools/create_freescape/castle_gate_ZX Spectrum.bmp b/devtools/create_freescape/castle_gate_ZX Spectrum.bmp
index 4d36bbc2306..5a8f867f1d5 100644
Binary files a/devtools/create_freescape/castle_gate_ZX Spectrum.bmp and b/devtools/create_freescape/castle_gate_ZX Spectrum.bmp differ
diff --git a/dists/engine-data/freescape.dat b/dists/engine-data/freescape.dat
index 4bbe3ca3a88..8ac681b3a8c 100644
Binary files a/dists/engine-data/freescape.dat and b/dists/engine-data/freescape.dat differ


Commit: 0f46495c4f32a56c3660a9c3cdb5f4c9b6345235
    https://github.com/scummvm/scummvm/commit/0f46495c4f32a56c3660a9c3cdb5f4c9b6345235
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2025-10-05T22:18:07-03:00

Commit Message:
FREESCAPE: thunder effect for castle (zx)

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/games/castle/castle.cpp
    engines/freescape/games/castle/castle.h
    engines/freescape/games/castle/dos.cpp
    engines/freescape/games/castle/zx.cpp
    engines/freescape/gfx.h
    engines/freescape/gfx_opengl.cpp
    engines/freescape/gfx_opengl.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index d1b39f1e3ae..d07c80b0d3e 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -427,12 +427,6 @@ void FreescapeEngine::clearBackground() {
 void FreescapeEngine::drawBackground() {
 	clearBackground();
 	_gfx->drawBackground(_currentArea->_skyColor);
-
-	if (isCastle() && _background) {
-		if (!_skyTexture)
-			_skyTexture = _gfx->createTexture(_background->surfacePtr(), true);
-		_gfx->drawSkybox(_skyTexture, _position);
-	}
 }
 
 void FreescapeEngine::drawFrame() {
diff --git a/engines/freescape/games/castle/castle.cpp b/engines/freescape/games/castle/castle.cpp
index 5912154da05..109bbba3c9c 100644
--- a/engines/freescape/games/castle/castle.cpp
+++ b/engines/freescape/games/castle/castle.cpp
@@ -79,7 +79,6 @@ CastleEngine::CastleEngine(OSystem *syst, const ADGameDescription *gd) : Freesca
 	_spiritsMeterIndicatorSideFrame = nullptr;
 	_strenghtBackgroundFrame = nullptr;
 	_strenghtBarFrame = nullptr;
-	_thunderFrame = nullptr;
 	_menu = nullptr;
 	_menuButtons = nullptr;
 
@@ -101,6 +100,8 @@ CastleEngine::CastleEngine(OSystem *syst, const ADGameDescription *gd) : Freesca
 	_spiritsToKill = 26;
 	_spiritsMeterPosition = 0;
 	_spiritsMeterMax = 64;
+	_thunderTicks = 0;
+	_thunderFrameDuration = 0;
 }
 
 CastleEngine::~CastleEngine() {
@@ -162,9 +163,17 @@ CastleEngine::~CastleEngine() {
 		}
 	}
 
-	if (_thunderFrame) {
-		_thunderFrame->free();
-		delete _thunderFrame;
+	for (int i = 0; i < int(_thunderFrames.size()); i++) {
+		if (_thunderFrames[i]) {
+			_thunderFrames[i]->free();
+			delete _thunderFrames[i];
+		}
+	}
+
+	for (int i = 0; i < int(_thunderTextures.size()); i++) {
+		if (_thunderTextures[i]) {
+			delete _thunderTextures[i];
+		}
 	}
 
 	if (_riddleTopFrame) {
@@ -437,6 +446,7 @@ void CastleEngine::initGameState() {
 	_lastTenSeconds = seconds / 10;
 
 	_droppingGateStartTicks = 0;
+	_thunderFrameDuration = 0;
 }
 
 bool CastleEngine::checkIfGameEnded() {
@@ -1666,4 +1676,53 @@ Common::Error CastleEngine::loadGameStreamExtended(Common::SeekableReadStream *s
 	return Common::kNoError;
 }
 
+
+void CastleEngine::drawBackground() {
+	clearBackground();
+	_gfx->drawBackground(_currentArea->_skyColor);
+
+	if (_background) {
+		if (!_skyTexture)
+			_skyTexture = _gfx->createTexture(_background->surfacePtr(), true);
+		_gfx->drawSkybox(_skyTexture, _position);
+		if (_thunderTextures.empty()) {
+			_thunderTextures.push_back(_gfx->createTexture(_thunderFrames[0]->surfacePtr(), true));
+			_thunderTextures.push_back(_gfx->createTexture(_thunderFrames[1]->surfacePtr(), true));
+		}
+		updateThunder();
+	}
+}
+
+void CastleEngine::updateThunder() {
+	if (!_thunderFrames[0])
+		return;
+
+	if (_thunderFrameDuration > 0) {
+		//debug("Thunder frame duration: %d", _thunderFrameDuration);
+		//debug("Size: %f", 2 * _thunderOffset.length());
+		//debug("Offset: %.1f, %.1f, %.1f", _thunderOffset.x(), _thunderOffset.y(), _thunderOffset.z());
+		_gfx->drawThunder(_thunderTextures[(_thunderFrameDuration - 1) / 5], _position + _thunderOffset, 100);
+		_thunderFrameDuration--;
+		if (_thunderFrameDuration == 0)
+			if (isSpectrum())
+				playSound(8, false, _soundFxHandle);
+		return;
+	}
+
+	if (_thunderTicks > 0) {
+		//debug("Thunder ticks: %d", _thunderTicks);
+		_thunderTicks--;
+		if (_thunderTicks <= 0) {
+			_thunderFrameDuration = 10;
+		}
+	} else {
+		// Schedule next thunder, between 10 and 10 + 10 seconds
+		_thunderTicks = 50 * (10 + _rnd->getRandomNumber(10));
+		_thunderOffset = Math::Vector3d();
+		_thunderOffset.x() += (int(_rnd->getRandomNumber(100)) + 100);
+		_thunderOffset.y() += int(_rnd->getRandomNumber(100)) + 50.0f;
+		_thunderOffset.z() += (int(_rnd->getRandomNumber(100)) + 100);
+	}
+}
+
 } // End of namespace Freescape
diff --git a/engines/freescape/games/castle/castle.h b/engines/freescape/games/castle/castle.h
index 5697ccfd6b4..b5bccfc23f3 100644
--- a/engines/freescape/games/castle/castle.h
+++ b/engines/freescape/games/castle/castle.h
@@ -79,6 +79,7 @@ public:
 	void pressedKey(const int keycode) override;
 	void checkSensors() override;
 	void updateTimeVariables() override;
+	void drawBackground() override;
 
 	bool checkIfGameEnded() override;
 	void drawSensorShoot(Sensor *sensor) override;
@@ -117,7 +118,8 @@ public:
 	Graphics::ManagedSurface *_strenghtBarFrame;
 	Common::Array<Graphics::ManagedSurface *> _strenghtWeightsFrames;
 	Common::Array<Graphics::ManagedSurface *> _flagFrames;
-	Graphics::ManagedSurface *_thunderFrame;
+	Common::Array<Graphics::ManagedSurface *> _thunderFrames;
+
 	Graphics::ManagedSurface *_riddleTopFrame;
 	Graphics::ManagedSurface *_riddleBackgroundFrame;
 	Graphics::ManagedSurface *_riddleBottomFrame;
@@ -146,11 +148,16 @@ private:
 	void tryToCollectKey();
 	void addGhosts();
 	bool ghostInArea();
+	void updateThunder();
 
 	Audio::SoundHandle _soundFxGhostHandle;
 	Texture *_optionTexture;
 	Font _fontRiddle;
 	int _droppingGateStartTicks;
+	int _thunderTicks;
+	int _thunderFrameDuration;
+	Math::Vector3d _thunderOffset;
+	Common::Array<Texture *>_thunderTextures;
 };
 
 }
diff --git a/engines/freescape/games/castle/dos.cpp b/engines/freescape/games/castle/dos.cpp
index ce641c7f7d1..f355f090456 100644
--- a/engines/freescape/games/castle/dos.cpp
+++ b/engines/freescape/games/castle/dos.cpp
@@ -222,8 +222,6 @@ void CastleEngine::loadAssetsDOSFullGame() {
 			_riddleBottomFrame = loadFrameWithHeaderDOS(stream);
 			_endGameThroneFrame = loadFrameWithHeaderDOS(stream);
 			// No header
-			_thunderFrame = loadFrameFromPlanes(stream, 16, 128);
-			_thunderFrame->convertToInPlace(_gfx->_texturePixelFormat, (byte *)&kEGADefaultPalette, 16);
 
 			stream->seek(0x29696);
 			Common::Array<Graphics::ManagedSurface *> chars;
@@ -368,9 +366,6 @@ void CastleEngine::loadAssetsDOSDemo() {
 			_riddleBottomFrame = loadFrameWithHeaderDOS(stream);
 			_endGameThroneFrame = loadFrameWithHeaderDOS(stream);
 			// No header
-			_thunderFrame = loadFrameFromPlanes(stream, 16, 128);
-			_thunderFrame->convertToInPlace(_gfx->_texturePixelFormat, (byte *)&kEGADefaultPalette, 16);
-
 			stream->seek(0x293f6); // TODO: check this
 			Common::Array<Graphics::ManagedSurface *> chars;
 			Common::Array<Graphics::ManagedSurface *> charsRiddle;
diff --git a/engines/freescape/games/castle/zx.cpp b/engines/freescape/games/castle/zx.cpp
index 5881eef7309..d4005ff79ef 100644
--- a/engines/freescape/games/castle/zx.cpp
+++ b/engines/freescape/games/castle/zx.cpp
@@ -191,12 +191,22 @@ void CastleEngine::loadAssetsZXFullGame() {
 
 	_flagFrames = loadFramesWithHeader(&file, (_language == Common::ES_ESP ? 0x10e4 + 15 : 0x10e4), 4, green, black);
 
+	file.skip(24);
 	int thunderWidth = 4;
-	int thunderHeight = 43;
-	_thunderFrame = new Graphics::ManagedSurface();
-	_thunderFrame->create(thunderWidth * 8, thunderHeight, _gfx->_texturePixelFormat);
-	_thunderFrame->fillRect(Common::Rect(0, 0, thunderWidth * 8, thunderHeight), 0);
-	_thunderFrame = loadFrame(&file, _thunderFrame, thunderWidth, thunderHeight, front);
+	int thunderHeight = 44;
+	Graphics::ManagedSurface *thunderFrame = new Graphics::ManagedSurface();
+	thunderFrame->create(thunderWidth * 8, thunderHeight, _gfx->_texturePixelFormat);
+	thunderFrame->fillRect(Common::Rect(0, 0, thunderWidth * 8, thunderHeight), 0);
+	thunderFrame = loadFrame(&file, thunderFrame, thunderWidth, thunderHeight, front);
+
+	_thunderFrames.push_back(new Graphics::ManagedSurface);
+	_thunderFrames.push_back(new Graphics::ManagedSurface);
+
+	_thunderFrames[0]->create(thunderWidth * 8 / 2, thunderHeight, _gfx->_texturePixelFormat);
+	_thunderFrames[1]->create(thunderWidth * 8 / 2, thunderHeight, _gfx->_texturePixelFormat);
+
+	_thunderFrames[0]->copyRectToSurface(*thunderFrame, 0, 0, Common::Rect(0, 0, thunderWidth * 8 / 2, thunderHeight));
+	_thunderFrames[1]->copyRectToSurface(*thunderFrame, 0, 0, Common::Rect(thunderWidth * 8 / 2, 0, thunderWidth * 8, thunderHeight));
 
 	Graphics::Surface *tmp;
 	tmp = loadBundledImage("castle_riddle_top_frame");
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 69edbce0857..11354aa0eba 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -102,6 +102,7 @@ public:
 
 	void drawEclipse(uint8 color1, uint8 color2, float difference);
 	virtual void drawSkybox(Texture *texture, Math::Vector3d camera) {};
+	virtual void drawThunder(Texture *texture, Math::Vector3d camera, float size) {};
 	virtual void drawCelestialBody(Math::Vector3d position, float radius, uint8 color) {};
 
 	Common::Rect viewport() const;
diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
index 375ba4d9ee3..488469c2d2c 100644
--- a/engines/freescape/gfx_opengl.cpp
+++ b/engines/freescape/gfx_opengl.cpp
@@ -199,6 +199,48 @@ void OpenGLRenderer::drawSkybox(Texture *texture, Math::Vector3d camera) {
 	glFlush();
 }
 
+void OpenGLRenderer::drawThunder(Texture *texture, const Math::Vector3d position, const float size) {
+	OpenGLTexture *glTexture = static_cast<OpenGLTexture *>(texture);
+	glPushMatrix();
+	{
+		glTranslatef(position.x(), position.y(), position.z());
+
+		GLfloat m[16];
+		glGetFloatv(GL_MODELVIEW_MATRIX, m);
+		for (int i = 0; i < 3; i++)
+			for (int j = 0; j < 3; j++)
+				m[i * 4 + j] = (i == j) ? 1.0f : 0.0f;
+		glLoadMatrixf(m);
+
+		glRotatef(-90, 0.0f, 0.0f, 1.0f);
+
+		// === Texturing setup ===
+		glEnable(GL_TEXTURE_2D);
+		glBindTexture(GL_TEXTURE_2D, glTexture->_id);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+
+		// === Blending (thunder should glow) ===
+		glEnable(GL_BLEND);
+		glBlendFunc(GL_ONE, GL_ONE);
+
+		// === Draw the billboarded quad ===
+		float half = size * 0.5f;
+		glBegin(GL_QUADS);
+			glTexCoord2f(0.0f, 0.0f); glVertex3f(-half, -half, 0.0f);
+			glTexCoord2f(0.0f, 0.72f); glVertex3f( half, -half, 0.0f);
+			glTexCoord2f(1.0f, 0.72f); glVertex3f( half,  half, 0.0f);
+			glTexCoord2f(1.0f, 0.0f); glVertex3f(-half,  half, 0.0f);
+		glEnd();
+
+		// === Cleanup ===
+		glDisable(GL_BLEND);
+		glBindTexture(GL_TEXTURE_2D, 0);
+		glDisable(GL_TEXTURE_2D);
+	}
+	glPopMatrix();
+}
+
 void OpenGLRenderer::updateProjectionMatrix(float fov, float aspectRatio, float nearClipPlane, float farClipPlane) {
 	glMatrixMode(GL_PROJECTION);
 	glLoadIdentity();
diff --git a/engines/freescape/gfx_opengl.h b/engines/freescape/gfx_opengl.h
index 8c80130fecf..30b1c325827 100644
--- a/engines/freescape/gfx_opengl.h
+++ b/engines/freescape/gfx_opengl.h
@@ -94,6 +94,7 @@ public:
 	virtual void drawFloor(uint8 color) override;
 	void drawCelestialBody(Math::Vector3d position, float radius, uint8 color) override;
 	void drawSkybox(Texture *texture, Math::Vector3d camera) override;
+	void drawThunder(Texture *texture, Math::Vector3d camera, float size) override;
 
 	virtual Graphics::Surface *getScreenshot() override;
 };




More information about the Scummvm-git-logs mailing list