WINTERMUTE: Add hacky, but working video playback

This commit is contained in:
Einar Johan Trøan Sømåen 2012-06-02 19:41:18 +02:00
parent cafdcd1c8a
commit a647ef3afb
6 changed files with 80 additions and 20 deletions

View File

@ -30,6 +30,7 @@
#define WINTERMUTE_BSURFACE_H
#include "engines/wintermute/Base/BBase.h"
#include "graphics/surface.h"
namespace WinterMute {
@ -62,6 +63,7 @@ public:
virtual HRESULT Restore();
virtual HRESULT Create(const char *Filename, bool default_ck, byte ck_red, byte ck_green, byte ck_blue, int LifeTime = -1, bool KeepLoaded = false);
virtual HRESULT Create(int Width, int Height);
virtual HRESULT PutSurface(const Graphics::Surface &surface) { return E_FAIL; }
virtual HRESULT PutPixel(int X, int Y, byte R, byte G, byte B, int A = -1);
virtual HRESULT GetPixel(int X, int Y, byte *R, byte *G, byte *B, byte *A = NULL);
virtual bool ComparePixel(int X, int Y, byte R, byte G, byte B, int A = -1);

View File

@ -456,12 +456,12 @@ HRESULT CBSurfaceSDL::DrawSprite(int X, int Y, RECT *Rect, float ZoomX, float Zo
warning("CBSurfaceSDL::DrawSprite not fully ported yet"); // TODO.
hasWarned = true;
}
#if 0
byte r = D3DCOLGetR(Alpha);
byte g = D3DCOLGetG(Alpha);
byte b = D3DCOLGetB(Alpha);
byte a = D3DCOLGetA(Alpha);
#if 0
SDL_SetTextureColorMod(_texture, r, g, b);
SDL_SetTextureAlphaMod(_texture, a);
@ -499,4 +499,9 @@ HRESULT CBSurfaceSDL::DrawSprite(int X, int Y, RECT *Rect, float ZoomX, float Zo
return S_OK;
}
HRESULT CBSurfaceSDL::PutSurface(const Graphics::Surface &surface) {
_surface->copyFrom(surface);
return S_OK;
}
} // end of namespace WinterMute

View File

@ -58,7 +58,7 @@ public:
HRESULT Display(int X, int Y, RECT rect, TSpriteBlendMode BlendMode = BLEND_NORMAL, bool MirrorX = false, bool MirrorY = false);
HRESULT DisplayZoom(int X, int Y, RECT rect, float ZoomX, float ZoomY, uint32 Alpha = 0xFFFFFFFF, bool Transparent = false, TSpriteBlendMode BlendMode = BLEND_NORMAL, bool MirrorX = false, bool MirrorY = false);
HRESULT DisplayTransform(int X, int Y, int HotX, int HotY, RECT Rect, float ZoomX, float ZoomY, uint32 Alpha, float Rotate, TSpriteBlendMode BlendMode = BLEND_NORMAL, bool MirrorX = false, bool MirrorY = false);
virtual HRESULT PutSurface(const Graphics::Surface &surface);
/* static unsigned DLL_CALLCONV ReadProc(void *buffer, unsigned size, unsigned count, fi_handle handle);
static int DLL_CALLCONV SeekProc(fi_handle handle, long offset, int origin);
static long DLL_CALLCONV TellProc(fi_handle handle);*/

View File

@ -19,7 +19,13 @@
#include "engines/wintermute/dcgf.h"
#include "engines/wintermute/video/vidtheoraplayer.h"
#include "engines/wintermute/Base/BGame.h"
#include "engines/wintermute/Base/BFileManager.h"
#include "engines/wintermute/Base/BSurfaceSDL.h"
#include "engines/wintermute/utils/utils.h"
#include "engines/wintermute/PlatformSDL.h"
#include "engines/wintermute/video/decoders/theora_decoder.h"
#include "common/system.h"
//#pragma comment(lib, "libtheora.lib")
namespace WinterMute {
@ -99,10 +105,10 @@ void CVidTheoraPlayer::SetDefaults() {
CVidTheoraPlayer::~CVidTheoraPlayer(void) {
Cleanup();
SAFE_DELETE_ARRAY(_filename);
/* SAFE_DELETE_ARRAY(_filename);
SAFE_DELETE_ARRAY(_alphaFilename);
SAFE_DELETE(_texture);
SAFE_DELETE(_alphaImage);
SAFE_DELETE(_alphaImage);*/
// SAFE_DELETE(_subtitler);
}
@ -160,6 +166,28 @@ void CVidTheoraPlayer::Cleanup() {
//////////////////////////////////////////////////////////////////////////
HRESULT CVidTheoraPlayer::initialize(const char *Filename, const char *SubtitleFile) {
Cleanup();
_file = Game->_fileManager->OpenFile(Filename);
if (!_file) return E_FAIL;
//if (Filename != _filename) CBUtils::SetString(&_filename, Filename);
_theoraDecoder = new TheoraDecoder();
_theoraDecoder->loadStream(_file);
if (!_theoraDecoder->isVideoLoaded())
return E_FAIL;
_state = THEORA_STATE_PAUSED;
// Additional setup.
_surface.create(_theoraDecoder->getWidth(), _theoraDecoder->getHeight(), _theoraDecoder->getPixelFormat());
_texture = new CBSurfaceSDL(Game);
_texture->Create(_theoraDecoder->getWidth(), _theoraDecoder->getHeight());
_state = THEORA_STATE_PLAYING;
_playZoom = 100;
return S_OK;
#if 0
Cleanup();
@ -346,6 +374,11 @@ HRESULT CVidTheoraPlayer::ResetStream() {
//////////////////////////////////////////////////////////////////////////
HRESULT CVidTheoraPlayer::play(TVideoPlayback Type, int X, int Y, bool FreezeGame, bool FreezeMusic, bool Looping, uint32 StartTime, float ForceZoom, int Volume) {
if (_theoraDecoder) {
_surface.copyFrom(*_theoraDecoder->decodeNextFrame());
_state = THEORA_STATE_PLAYING;
return S_OK;
}
#if 0
if (ForceZoom < 0.0f) ForceZoom = 100.0f;
if (Volume < 0) m_Volume = Game->m_SoundMgr->GetVolumePercent(SOUND_SFX);
@ -412,6 +445,21 @@ HRESULT CVidTheoraPlayer::stop() {
//////////////////////////////////////////////////////////////////////////
HRESULT CVidTheoraPlayer::update() {
if (_theoraDecoder) {
if (_theoraDecoder->endOfVideo()) {
warning("Finished movie");
_state = THEORA_STATE_FINISHED;
}
if (_state == THEORA_STATE_PLAYING) {
if (_theoraDecoder->getTimeToNextFrame() > 0) {
_surface.copyFrom(*_theoraDecoder->decodeNextFrame()->convertTo(g_system->getScreenFormat()));
}
if (_texture) WriteVideo();
_videoFrameReady = true;
return S_OK;
}
}
#if 0
m_CurrentTime = m_FreezeGame ? Game->m_LiveTimer : Game->m_Timer;
@ -623,16 +671,17 @@ HRESULT CVidTheoraPlayer::WriteAudio() {
//////////////////////////////////////////////////////////////////////////
HRESULT CVidTheoraPlayer::WriteVideo() {
#if 0
if (!m_Texture) return E_FAIL;
if (!_texture) return E_FAIL;
#if 0
yuv_buffer yuv;
theora_decode_YUVout(&m_TheoraState, &yuv);
m_Texture->StartPixelOp();
RenderFrame(m_Texture, &yuv);
m_Texture->EndPixelOp();
#endif
_texture->StartPixelOp();
//RenderFrame(_texture, &yuv);
_texture->PutSurface(_surface);
_texture->EndPixelOp();
return S_OK;
}
@ -641,13 +690,13 @@ HRESULT CVidTheoraPlayer::display(uint32 Alpha) {
RECT rc;
HRESULT Res;
#if 0
if (m_Texture) {
SetRect(&rc, 0, 0, m_Texture->GetWidth(), m_Texture->GetHeight());
if (m_PlayZoom == 100.0f) Res = m_Texture->DisplayTrans(m_PosX, m_PosY, rc, Alpha);
else Res = m_Texture->DisplayTransZoom(m_PosX, m_PosY, rc, m_PlayZoom, m_PlayZoom, Alpha);
} else Res = E_FAIL;
if (_texture) {
CBPlatform::SetRect(&rc, 0, 0, _texture->GetWidth(), _texture->GetHeight());
if (_playZoom == 100.0f) Res = _texture->DisplayTrans(_posX, _posY, rc, Alpha);
else Res = _texture->DisplayTransZoom(_posX, _posY, rc, _playZoom, _playZoom, Alpha);
} else Res = E_FAIL;
#if 0
if (m_Subtitler && Game->m_VideoSubtitles) m_Subtitler->Display();
#endif
return Res;

View File

@ -24,6 +24,8 @@
#include "engines/wintermute/Base/file/BFile.h"
#include "engines/wintermute/Base/BSurface.h"
#include "engines/wintermute/Base/BImage.h"
#include "video/video_decoder.h"
#include "common/stream.h"
//#include <theora/theora.h>
namespace WinterMute {
@ -31,6 +33,8 @@ namespace WinterMute {
class CVidTheoraPlayer : public CBBase {
private:
enum { THEORA_STATE_NONE = 0, THEORA_STATE_PLAYING = 1, THEORA_STATE_PAUSED = 2, THEORA_STATE_FINISHED = 3 };
Video::VideoDecoder *_theoraDecoder;
Graphics::Surface _surface;
public:
//DECLARE_PERSISTENT(CVidTheoraPlayer, CBBase);
@ -59,7 +63,7 @@ public:
// external objects
CBFile *_file;
Common::SeekableReadStream *_file;
char *_filename;
//CBSoundTheora *_sound;
@ -86,7 +90,6 @@ public:
return _state == THEORA_STATE_PLAYING;
};
bool IsFinished() {
return true; // HACK
return _state == THEORA_STATE_FINISHED;
};
bool IsPaused() {

View File

@ -48,6 +48,7 @@ namespace WinterMute {
* Decoder for Theora videos.
* Video decoder used in engines:
* - sword25
* - wintermute
*/
class TheoraDecoder : public Video::VideoDecoder {
public: