2011-12-14 00:23:17 +03:00
# pragma once
2009-06-28 02:33:59 +03:00
struct SDL_Surface ;
2011-08-08 17:20:22 +03:00
class IVideoPlayer
{
public :
virtual bool open ( std : : string name ) = 0 ; //true - succes
virtual void close ( ) = 0 ;
virtual bool nextFrame ( ) = 0 ;
virtual void show ( int x , int y , SDL_Surface * dst , bool update = true ) = 0 ;
virtual void redraw ( int x , int y , SDL_Surface * dst , bool update = true ) = 0 ; //reblits buffer
virtual bool wait ( ) = 0 ;
virtual int curFrame ( ) const = 0 ;
virtual int frameCount ( ) const = 0 ;
} ;
class IMainVideoPlayer : public IVideoPlayer
{
public :
std : : string fname ; //name of current video file (empty if idle)
virtual void update ( int x , int y , SDL_Surface * dst , bool forceRedraw , bool update = true ) { }
virtual bool openAndPlayVideo ( std : : string name , int x , int y , SDL_Surface * dst , bool stopOnKey = false )
{
return false ;
}
} ;
class CEmptyVideoPlayer : public IMainVideoPlayer
{
public :
virtual int curFrame ( ) const { return - 1 ; } ;
virtual int frameCount ( ) const { return - 1 ; } ;
virtual void redraw ( int x , int y , SDL_Surface * dst , bool update = true ) { } ;
virtual void show ( int x , int y , SDL_Surface * dst , bool update = true ) { } ;
virtual bool nextFrame ( ) { return false ; } ;
virtual void close ( ) { } ;
virtual bool wait ( ) { return false ; } ;
virtual bool open ( std : : string name ) { return false ; } ;
} ;
2009-06-24 15:14:48 +03:00
# ifdef _WIN32
2009-08-17 16:08:05 +03:00
# define WIN32_LEAN_AND_MEAN //excludes rarely used stuff from windows headers - delete this line if something is missing
2009-06-24 15:14:48 +03:00
# include <windows.h>
# pragma pack(push,1)
struct BINK_STRUCT
{
si32 width ;
si32 height ;
si32 frameCount ;
si32 currentFrame ;
si32 lastFrame ;
si32 FPSMul ;
si32 FPSDiv ;
si32 unknown0 ;
ui8 flags ;
ui8 unknown1 [ 260 ] ;
si32 CurPlane ; // current plane
void * plane0 ; // posi32er to plane 0
void * plane1 ; // posi32er to plane 1
si32 unknown2 ;
si32 unknown3 ;
si32 yWidth ; // Y plane width
si32 yHeight ; // Y plane height
si32 uvWidth ; // U&V plane width
si32 uvHeight ; // U&V plane height
} ;
# pragma pack(pop)
typedef BINK_STRUCT * HBINK ;
class DLLHandler
{
public :
std : : string name ;
HINSTANCE dll ;
void Instantiate ( const char * filename ) ;
const char * GetLibExtension ( ) ;
void * FindAddress ( const char * symbol ) ;
DLLHandler ( ) ;
virtual ~ DLLHandler ( ) ; //d-tor
} ;
typedef void * ( __stdcall * BinkSetSoundSystem ) ( void * soundfun , void * ) ;
typedef HBINK ( __stdcall * BinkOpen ) ( HANDLE bikfile , int flags ) ;
typedef void ( __stdcall * BinkClose ) ( HBINK ) ;
//typedef si32(__stdcall* BinkGetPalette)(HBINK);
typedef void ( __stdcall * BinkNextFrame ) ( HBINK ) ;
typedef void ( __stdcall * BinkDoFrame ) ( HBINK ) ;
typedef ui8 ( __stdcall * BinkWait ) ( HBINK ) ;
typedef si32 ( __stdcall * BinkCopyToBuffer ) ( HBINK , void * buffer , int stride , int height , int x , int y , int mode ) ;
2009-06-23 11:14:49 +03:00
2009-06-24 15:14:48 +03:00
class CBIKHandler : public DLLHandler , public IVideoPlayer
{
2009-08-01 13:08:16 +03:00
void allocBuffer ( int Bpp = 0 ) ;
void freeBuffer ( ) ;
2009-06-24 15:14:48 +03:00
public :
HANDLE hBinkFile ;
HBINK hBink ;
char * buffer ;
2009-08-01 13:08:16 +03:00
int bufferSize ;
2009-06-24 15:14:48 +03:00
BinkSetSoundSystem binkSetSoundSystem ;
BinkOpen binkOpen ;
//BinkGetPalette getPalette;
BinkNextFrame binkNextFrame ;
BinkDoFrame binkDoFrame ;
BinkCopyToBuffer binkCopyToBuffer ;
BinkWait binkWait ;
BinkClose binkClose ;
CBIKHandler ( ) ;
2010-07-20 13:46:38 +03:00
bool open ( std : : string name ) ;
2009-06-23 11:14:49 +03:00
void close ( ) ;
2011-08-08 17:20:22 +03:00
bool nextFrame ( ) ;
2009-06-24 09:56:36 +03:00
void show ( int x , int y , SDL_Surface * dst , bool update = true ) ;
2009-06-24 12:17:33 +03:00
void redraw ( int x , int y , SDL_Surface * dst , bool update = true ) ; //reblits buffer
2009-06-24 15:14:48 +03:00
bool wait ( ) ;
int curFrame ( ) const ;
int frameCount ( ) const ;
} ;
//////////SMK Player ///////////////////////////////////////////////////////
2009-06-22 14:12:40 +03:00
2009-06-23 11:14:49 +03:00
struct SmackStruct
{
si32 version ;
si32 width ;
si32 height ;
si32 frameCount ;
si32 mspf ;
ui8 unk1 [ 88 ] ;
ui8 palette [ 776 ] ;
si32 currentFrame ; // Starting with 0
ui8 unk [ 56 ] ;
ui32 fileHandle ; // exact type is HANDLE in windows.h
2009-06-22 14:12:40 +03:00
} ;
2009-06-23 11:14:49 +03:00
// defines function pointer types
typedef SmackStruct * ( __stdcall * SmackOpen ) ( void * , ui32 , si32 ) ;
2009-06-22 14:12:40 +03:00
typedef int ( __stdcall * SmackDoFrame ) ( SmackStruct * ) ;
typedef void ( __stdcall * SmackGoto ) ( SmackStruct * , int frameNumber ) ;
typedef void ( __stdcall * SmackNextFrame ) ( SmackStruct * ) ;
typedef void ( __stdcall * SmackClose ) ( SmackStruct * ) ;
2009-06-23 11:14:49 +03:00
typedef void ( __stdcall * SmackToBuffer ) ( SmackStruct * , int , int , int , int , char * , ui32 ) ;
2009-06-22 14:12:40 +03:00
typedef bool ( __stdcall * SmackWait ) ( SmackStruct * ) ;
typedef void ( __stdcall * SmackSoundOnOff ) ( SmackStruct * , bool ) ;
2010-07-28 14:34:26 +03:00
typedef int ( __stdcall * SmackVolumePan ) ( SmackStruct * , int SmackTrack , int volume , int pan ) ;
2009-06-22 14:12:40 +03:00
2009-06-24 15:14:48 +03:00
class CSmackPlayer : public DLLHandler , public IVideoPlayer
2009-06-22 14:12:40 +03:00
{
public :
SmackOpen ptrSmackOpen ;
SmackDoFrame ptrSmackDoFrame ;
SmackToBuffer ptrSmackToBuffer ;
SmackNextFrame ptrSmackNextFrame ;
SmackWait ptrSmackWait ;
SmackSoundOnOff ptrSmackSoundOnOff ;
2009-06-24 09:56:36 +03:00
SmackClose ptrSmackClose ;
2010-07-28 14:34:26 +03:00
SmackVolumePan ptrVolumePan ;
2009-06-24 09:56:36 +03:00
char * buffer , * buf ;
2009-06-22 14:12:40 +03:00
SmackStruct * data ;
2009-06-24 09:56:36 +03:00
CSmackPlayer ( ) ;
2009-06-24 15:14:48 +03:00
~ CSmackPlayer ( ) ;
2010-07-20 13:46:38 +03:00
bool open ( std : : string name ) ;
2009-06-24 09:56:36 +03:00
void close ( ) ;
2011-08-08 17:20:22 +03:00
bool nextFrame ( ) ;
2009-06-24 09:56:36 +03:00
void show ( int x , int y , SDL_Surface * dst , bool update = true ) ;
2009-06-24 12:17:33 +03:00
void redraw ( int x , int y , SDL_Surface * dst , bool update = true ) ; //reblits buffer
2009-06-24 15:14:48 +03:00
bool wait ( ) ;
int curFrame ( ) const ;
2009-06-24 09:56:36 +03:00
int frameCount ( ) const ;
2009-06-22 14:12:40 +03:00
} ;
2009-06-24 15:14:48 +03:00
class CVidHandler ;
2011-08-08 10:12:18 +03:00
class CVideoPlayer : public IMainVideoPlayer
2009-06-24 15:14:48 +03:00
{
private :
CSmackPlayer smkPlayer ; //for .SMK
CBIKHandler bikPlayer ; //for .BIK
IVideoPlayer * current ; //points to bik or smk player, appropriate to type of currently played video
bool first ; //are we about to display the first frame (blocks update)
public :
2011-03-15 16:35:36 +02:00
2009-06-24 15:14:48 +03:00
CVideoPlayer ( ) ; //c-tor
~ CVideoPlayer ( ) ; //d-tor
2010-07-20 13:46:38 +03:00
bool open ( std : : string name ) ;
2009-06-24 09:56:36 +03:00
void close ( ) ;
2011-08-08 17:20:22 +03:00
bool nextFrame ( ) ; //move animation to the next frame
2009-06-24 09:56:36 +03:00
void show ( int x , int y , SDL_Surface * dst , bool update = true ) ; //blit current frame
2009-06-24 12:17:33 +03:00
void redraw ( int x , int y , SDL_Surface * dst , bool update = true ) ; //reblits buffer
void update ( int x , int y , SDL_Surface * dst , bool forceRedraw , bool update = true ) ; //moves to next frame if appropriate, and blits it or blits only if redraw paremeter is set true
2009-06-24 15:14:48 +03:00
bool wait ( ) ; //true if we should wait before displaying next frame (for keeping FPS)
int curFrame ( ) const ; //current frame number <1, framecount>
int frameCount ( ) const ;
bool openAndPlayVideo ( std : : string name , int x , int y , SDL_Surface * dst , bool stopOnKey = false ) ; //opens video, calls playVideo, closes video; returns playVideo result (if whole video has been played)
bool playVideo ( int x , int y , SDL_Surface * dst , bool stopOnKey = false ) ; //plays whole opened video; returns: true when whole video has been shown, false when it has been interrupted
} ;
# else
2012-08-18 13:29:54 +03:00
# ifndef DISABLE_VIDEO
2013-04-07 13:48:07 +03:00
# include "../lib/filesystem/CInputStream.h"
2013-02-06 02:11:48 +03:00
2011-11-17 03:24:27 +03:00
# include <SDL.h>
2009-06-24 15:14:48 +03:00
# include <SDL_video.h>
2011-11-17 03:24:27 +03:00
# if SDL_VERSION_ATLEAST(1,3,0)
# include <SDL_compat.h>
# endif
2009-06-24 15:14:48 +03:00
2012-08-21 20:37:06 +03:00
extern " C " {
# include <libavformat/avformat.h>
# include <libswscale/swscale.h>
}
2009-06-24 15:14:48 +03:00
2011-08-08 17:20:22 +03:00
class CVideoPlayer : public IMainVideoPlayer
2009-06-24 15:14:48 +03:00
{
int stream ; // stream index in video
AVFormatContext * format ;
AVCodecContext * codecContext ; // codec context for stream
AVCodec * codec ;
AVFrame * frame ;
struct SwsContext * sws ;
2012-08-21 20:37:06 +03:00
AVIOContext * context ;
2009-06-28 02:33:59 +03:00
// Destination. Either overlay or dest.
2009-06-24 15:14:48 +03:00
SDL_Overlay * overlay ;
2009-06-28 02:33:59 +03:00
SDL_Surface * dest ;
SDL_Rect destRect ; // valid when dest is used
SDL_Rect pos ; // destination on screen
2009-06-24 15:14:48 +03:00
2009-06-28 02:33:59 +03:00
int refreshWait ; // Wait several refresh before updating the image
int refreshCount ;
bool doLoop ; // loop through video
2011-08-08 17:20:22 +03:00
bool playVideo ( int x , int y , SDL_Surface * dst , bool stopOnKey ) ;
bool open ( std : : string fname , bool loop , bool useOverlay = false ) ;
2009-06-24 15:14:48 +03:00
public :
CVideoPlayer ( ) ;
~ CVideoPlayer ( ) ;
bool init ( ) ;
2011-08-08 17:20:22 +03:00
bool open ( std : : string fname ) ;
2009-06-24 15:14:48 +03:00
void close ( ) ;
bool nextFrame ( ) ; // display next frame
2009-06-28 02:33:59 +03:00
void show ( int x , int y , SDL_Surface * dst , bool update = true ) ; //blit current frame
void redraw ( int x , int y , SDL_Surface * dst , bool update = true ) ; //reblits buffer
void update ( int x , int y , SDL_Surface * dst , bool forceRedraw , bool update = true ) ; //moves to next frame if appropriate, and blits it or blits only if redraw parameter is set true
// Opens video, calls playVideo, closes video; returns playVideo result (if whole video has been played)
bool openAndPlayVideo ( std : : string name , int x , int y , SDL_Surface * dst , bool stopOnKey = false ) ;
2011-08-08 17:20:22 +03:00
//TODO:
bool wait ( ) { return false ; } ;
int curFrame ( ) const { return - 1 ; } ;
int frameCount ( ) const { return - 1 ; } ;
2013-02-06 02:11:48 +03:00
// public to allow access from ffmpeg IO functions
std : : unique_ptr < CInputStream > data ;
2009-06-24 15:14:48 +03:00
} ;
2012-08-18 13:29:54 +03:00
# endif
2009-06-24 15:14:48 +03:00
# endif