[Scummvm-git-logs] scummvm master -> 82db0f34b1923b91b8ff3fc4d92fde3186f4317a

aquadran noreply at scummvm.org
Sat Aug 9 12:50:44 UTC 2025


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

Summary:
82db0f34b1 WINTERMUTE: Added AVI player


Commit: 82db0f34b1923b91b8ff3fc4d92fde3186f4317a
    https://github.com/scummvm/scummvm/commit/82db0f34b1923b91b8ff3fc4d92fde3186f4317a
Author: Paweł Kołodziejski (aquadran at gmail.com)
Date: 2025-08-09T14:50:39+02:00

Commit Message:
WINTERMUTE: Added AVI player

Changed paths:
    engines/wintermute/base/base_game.cpp
    engines/wintermute/video/video_player.cpp
    engines/wintermute/video/video_player.h


diff --git a/engines/wintermute/base/base_game.cpp b/engines/wintermute/base/base_game.cpp
index 20ac0ee9b0d..593a198892b 100644
--- a/engines/wintermute/base/base_game.cpp
+++ b/engines/wintermute/base/base_game.cpp
@@ -1285,11 +1285,8 @@ bool BaseGame::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack
 	// PlayVideo
 	//////////////////////////////////////////////////////////////////////////
 	else if (strcmp(name, "PlayVideo") == 0) {
-		_gameRef->LOG(0, "Warning: Game.PlayVideo() is now deprecated. Use Game.PlayTheora() instead.");
-
 		stack->correctParams(6);
 		const char *filename = stack->pop()->getString();
-		warning("PlayVideo: %s - not implemented yet", filename);
 		ScValue *valType = stack->pop();
 		int type;
 		if (valType->isNULL()) {
diff --git a/engines/wintermute/video/video_player.cpp b/engines/wintermute/video/video_player.cpp
index 0f3fe6013fe..62b756ddf33 100644
--- a/engines/wintermute/video/video_player.cpp
+++ b/engines/wintermute/video/video_player.cpp
@@ -27,6 +27,11 @@
 
 
 #include "engines/wintermute/video/video_player.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/base_engine.h"
+#include "engines/wintermute/base/base_file_manager.h"
+#include "engines/wintermute/base/gfx/base_renderer.h"
+#include "engines/wintermute/base/gfx/base_surface.h"
 
 namespace Wintermute {
 
@@ -42,19 +47,21 @@ VideoPlayer::VideoPlayer(BaseGame *inGame) : BaseClass(inGame) {
 //////////////////////////////////////////////////////////////////////////
 bool VideoPlayer::setDefaults() {
 	_playing = false;
-	_videoEndTime = 0;
-	_soundAvailable = false;
-	_startTime = 0;
-	_totalVideoTime = 0;
+
+	_aviDecoder = nullptr;
+	
 	_playPosX = _playPosY = 0;
 	_playZoom = 0.0f;
 
-	_filename = nullptr;
+	_texture = nullptr;
+	_videoFrameReady = false;
+	_playbackStarted = false;
+	_freezeGame = false;
 
-	_slowRendering = false;
+	_filename.clear();
 
-	_currentSubtitle = 0;
-	_showSubtitle = false;
+	_subtitler = new VideoSubtitler(_gameRef);
+	_foundSubtitles = false;
 
 	return STATUS_OK;
 }
@@ -62,36 +69,187 @@ bool VideoPlayer::setDefaults() {
 //////////////////////////////////////////////////////////////////////////
 VideoPlayer::~VideoPlayer() {
 	cleanup();
+	delete _subtitler;
+	_subtitler = nullptr;
 }
 
 //////////////////////////////////////////////////////////////////////////
 bool VideoPlayer::cleanup() {
-	return 0;
+	_playing = false;
+
+	if (_aviDecoder) {
+		_aviDecoder->close();
+	}
+	delete _aviDecoder;
+	_aviDecoder = nullptr;
+	delete _texture;
+	_texture = nullptr;
+
+	return setDefaults();
 }
 
 //////////////////////////////////////////////////////////////////////////
-bool VideoPlayer::initialize(const char *inFilename, const char *subtitleFile) {
-	warning("VideoPlayer: %s %s - Not implemented yet", inFilename, subtitleFile);
+bool VideoPlayer::initialize(const Common::String &filename, const Common::String &subtitleFile) {
+	cleanup();
+
+	if (BaseEngine::instance().getGameId() == "sof1" ||
+		BaseEngine::instance().getGameId() == "sof2") {
+		warning("PlayVideo: %s - Xvid support not implemented yet", filename.c_str());
+		return STATUS_FAILED;
+	}
+
+	_filename = filename;
+
+	// Load a file, but avoid having the File-manager handle the disposal of it.
+	Common::SeekableReadStream *file = BaseFileManager::getEngineInstance()->openFile(filename, true, false);
+	if (!file) {
+		return STATUS_FAILED;
+	}
+
+	_aviDecoder = new Video::AVIDecoder();
+	_aviDecoder->loadStream(file);
+
+	_foundSubtitles = _subtitler->loadSubtitles(_filename, subtitleFile);
+
+	if (!_aviDecoder->isVideoLoaded()) {
+		return STATUS_FAILED;
+	}
+
+	// Additional setup.
+	_texture = _gameRef->_renderer->createSurface();
+	_texture->create(_aviDecoder->getWidth(), _aviDecoder->getHeight());
+	_playZoom = 100;
+
 	return STATUS_OK;
 }
 
 //////////////////////////////////////////////////////////////////////////
 bool VideoPlayer::update() {
-	return 0;
+	if (!isPlaying()) {
+		return STATUS_OK;
+	}
+
+	if (_playbackStarted) {
+		return STATUS_OK;
+	}
+
+	if (_playbackStarted && !_freezeGame && _gameRef->_state == GAME_FROZEN) {
+		return STATUS_OK;
+	}
+
+	if (_subtitler && _foundSubtitles && _gameRef->_subtitles) {
+		_subtitler->update(_aviDecoder->getCurFrame());
+	}
+
+	if (_aviDecoder->endOfVideo()) {
+		_playbackStarted = false;
+		if (_freezeGame) {
+			_gameRef->unfreeze();
+		}
+	}
+	if (!_aviDecoder->endOfVideo() && _aviDecoder->getTimeToNextFrame() == 0) {
+		const Graphics::Surface *decodedFrame = _aviDecoder->decodeNextFrame();
+		if (decodedFrame && _texture) {
+			_texture->putSurface(*decodedFrame, false);
+			_videoFrameReady = true;
+		}
+	}
+
+	return STATUS_OK;
 }
 
 //////////////////////////////////////////////////////////////////////////
 bool VideoPlayer::display() {
-	return 0;
+	Rect32 rc;
+	bool res;
+
+	if (_texture && _videoFrameReady) {
+		rc.setRect(0, 0, _texture->getWidth(), _texture->getHeight());
+		if (_playZoom == 100.0f) {
+			res = _texture->display(_playPosX, _playPosY, rc);
+		} else {
+			res = _texture->displayTransZoom(_playPosX, _playPosY, rc, _playZoom, _playZoom);
+		}
+	} else {
+		res = STATUS_FAILED;
+	}
+
+	if (_subtitler && _foundSubtitles && _gameRef->_subtitles) {
+		_subtitler->display();
+	}
+	return res;
 }
 
 //////////////////////////////////////////////////////////////////////////
 bool VideoPlayer::play(TVideoPlayback type, int x, int y, bool freezeMusic) {
+	if (!_aviDecoder)
+		return STATUS_FAILED;
+
+	if (!_playbackStarted && freezeMusic) {
+		_gameRef->freeze(freezeMusic);
+		_freezeGame = freezeMusic;
+	}
+
+	_playbackStarted = false;
+	float width, height;
+	if (_aviDecoder) {
+		if (_subtitler && _foundSubtitles && _gameRef->_subtitles) {
+			_subtitler->update(_aviDecoder->getFrameCount());
+			_subtitler->display();
+		}
+		_playPosX = x;
+		_playPosY = y;
+
+		width = (float)_aviDecoder->getWidth();
+		height = (float)_aviDecoder->getHeight();
+	} else {
+		width = (float)_gameRef->_renderer->getWidth();
+		height = (float)_gameRef->_renderer->getHeight();
+	}
+
+	switch (type) {
+		case VID_PLAY_POS:
+			_playZoom = 100.0f;
+			_playPosX = x;
+			_playPosY = y;
+			break;
+
+		case VID_PLAY_STRETCH: {
+			float zoomX = (float)((float)_gameRef->_renderer->getWidth() / width * 100);
+			float zoomY = (float)((float)_gameRef->_renderer->getHeight() / height * 100);
+			_playZoom = MIN(zoomX, zoomY);
+			_playPosX = (int)((_gameRef->_renderer->getWidth() - width * (_playZoom / 100)) / 2);
+			_playPosX = (int)((_gameRef->_renderer->getHeight() - height * (_playZoom / 100)) / 2);
+		}
+			break;
+
+		case VID_PLAY_CENTER:
+			_playZoom = 100.0f;
+			_playPosX = (int)((_gameRef->_renderer->getWidth() - width) / 2);
+			_playPosY = (int)((_gameRef->_renderer->getHeight() - height) / 2);
+			break;
+
+		default:
+			break;
+	}
+
+	if (_aviDecoder)
+		_aviDecoder->start();
+
+	_playing = true;
+
 	return STATUS_OK;
 }
 
 //////////////////////////////////////////////////////////////////////////
 bool VideoPlayer::stop() {
+	_aviDecoder->close();
+
+	cleanup();
+
+	if (_freezeGame)
+		_gameRef->unfreeze();
+
 	return STATUS_OK;
 }
 
@@ -100,9 +258,4 @@ bool VideoPlayer::isPlaying() {
 	return _playing;
 }
 
-//////////////////////////////////////////////////////////////////////////
-bool VideoPlayer::loadSubtitles(const char *filename, const char *subtitleFile) {
-	return STATUS_OK;
-}
-
 } // End of namespace Wintermute
diff --git a/engines/wintermute/video/video_player.h b/engines/wintermute/video/video_player.h
index b4af5f6c214..6ec012a6d0a 100644
--- a/engines/wintermute/video/video_player.h
+++ b/engines/wintermute/video/video_player.h
@@ -28,60 +28,49 @@
 #ifndef WINTERMUTE_VIDPLAYER_H
 #define WINTERMUTE_VIDPLAYER_H
 
+#include "video/avi_decoder.h"
+
 #include "engines/wintermute/dctypes.h"    // Added by ClassView
 #include "engines/wintermute/base/base.h"
+#include "engines/wintermute/video/video_subtitler.h"
+#include "graphics/surface.h"
 
 #define MAX_AUDIO_STREAMS 5
 #define MAX_VIDEO_STREAMS 5
 
 
 namespace Wintermute {
-
-// AVI-Video-player, currently fully stubbed
+class BaseSurface;
+// AVI-Video-player
 class VideoPlayer : public BaseClass {
 public:
-	bool _showSubtitle;
-	int32 _currentSubtitle;
-	bool loadSubtitles(const char *filename, const char *subtitleFile);
-	bool _slowRendering;
 	bool isPlaying();
-	char *_filename;
+	// external object
+	Common::String _filename;
 	bool stop();
 	bool play(TVideoPlayback Type = VID_PLAY_CENTER, int x = 0, int y = 0, bool freezeMusic = true);
-	uint32 _totalVideoTime;
-	uint32 _startTime;
-	//CVidRenderer *_vidRenderer;
-	//BaseSoundAVI *_sound;
-	bool _soundAvailable;
+	Video::AVIDecoder *_aviDecoder;
 	bool setDefaults();
 	bool _playing;
 	bool display();
 	bool update();
-	bool initialize(const char *inFilename, const char *subtitleFile = nullptr);
+	bool initialize(const Common::String &filename, const Common::String &subtitleFile = Common::String());
 	bool cleanup();
 	VideoPlayer(BaseGame *inGame);
 	~VideoPlayer() override;
 
-	/*PAVIFILE _aviFile;
-
-	LONG _lastSample;
-
-	PAVISTREAM _audioStream;
-	PAVISTREAM _videoStream;
-
-	LPWAVEFORMAT _audioFormat;
-
-	LPBITMAPINFO _videoFormat;
-	PGETFRAME _videoPGF;*/
-	uint32 _videoEndTime;
+	BaseSurface *_texture;
+	VideoSubtitler *_subtitler;
 
 	int32 _playPosX;
 	int32 _playPosY;
 	float _playZoom;
 
-	/*  LPBITMAPV4HEADER _targetFormat;
-
-	    BaseArray<CVidSubtitle *, CVidSubtitle *> _subtitles;*/
+private:
+	bool _foundSubtitles;
+	bool _videoFrameReady;
+	bool _playbackStarted;
+	bool _freezeGame;
 };
 
 } // End of namespace Wintermute




More information about the Scummvm-git-logs mailing list