[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