1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-15 20:03:15 +02:00

VCMI won't crash with invalid video file (should fix #92).

This commit is contained in:
Michał W. Urbańczyk
2010-07-20 10:46:38 +00:00
parent 0e9eb1ab2d
commit cd9ab4cc62
3 changed files with 60 additions and 19 deletions

View File

@@ -2516,3 +2516,4 @@ CSavingScreen::~CSavingScreen()
{ {
} }

View File

@@ -129,7 +129,7 @@ CBIKHandler::CBIKHandler()
bufferSize = 0; bufferSize = 0;
} }
void CBIKHandler::open(std::string name) bool CBIKHandler::open(std::string name)
{ {
hBinkFile = CreateFileA hBinkFile = CreateFileA
( (
@@ -145,8 +145,7 @@ void CBIKHandler::open(std::string name)
if(hBinkFile == INVALID_HANDLE_VALUE) if(hBinkFile == INVALID_HANDLE_VALUE)
{ {
tlog1 << "BIK handler: failed to open " << name << std::endl; tlog1 << "BIK handler: failed to open " << name << std::endl;
checkForError(); goto checkErrorAndClean;
return;
} }
void *waveout = GetProcAddress(dll,"_BinkOpenWaveOut@4"); void *waveout = GetProcAddress(dll,"_BinkOpenWaveOut@4");
@@ -154,8 +153,20 @@ void CBIKHandler::open(std::string name)
binkSetSoundSystem(waveout,NULL); binkSetSoundSystem(waveout,NULL);
hBink = binkOpen(hBinkFile, 0x8a800000); hBink = binkOpen(hBinkFile, 0x8a800000);
if(!hBink)
{
tlog1 << "bink failed to open " << name << std::endl;
goto checkErrorAndClean;
}
allocBuffer(); allocBuffer();
return true;
checkErrorAndClean:
CloseHandle(hBinkFile);
hBinkFile = NULL;
checkForError(false);
return false;
} }
void CBIKHandler::show( int x, int y, SDL_Surface *dst, bool update ) void CBIKHandler::show( int x, int y, SDL_Surface *dst, bool update )
@@ -282,19 +293,21 @@ void CSmackPlayer::close()
data = NULL; data = NULL;
} }
void CSmackPlayer::open( std::string name ) bool CSmackPlayer::open( std::string name )
{ {
Uint32 flags[2] = {0xff400, 0xfe400}; Uint32 flags[2] = {0xff400, 0xfe400};
data = ptrSmackOpen( (void*)name.c_str(), flags[1], -1); data = ptrSmackOpen( (void*)name.c_str(), 0x8600, -1);
if (!data) if (!data)
{ {
tlog1 << "Smack cannot open " << name << std::endl; tlog1 << "Smack cannot open " << name << std::endl;
return; checkForError(false);
return false;
} }
buffer = new char[data->width*data->height*2]; buffer = new char[data->width*data->height*2];
buf = buffer+data->width*(data->height-1)*2; // adjust pointer position for later use by 'SmackToBuffer' buf = buffer+data->width*(data->height-1)*2; // adjust pointer position for later use by 'SmackToBuffer'
return true;
} }
void CSmackPlayer::show( int x, int y, SDL_Surface *dst, bool update) void CSmackPlayer::show( int x, int y, SDL_Surface *dst, bool update)
@@ -368,7 +381,7 @@ CVideoPlayer::~CVideoPlayer()
delete vidh; delete vidh;
} }
void CVideoPlayer::open(std::string name) bool CVideoPlayer::open(std::string name)
{ {
if(boost::algorithm::ends_with(name, ".BIK")) if(boost::algorithm::ends_with(name, ".BIK"))
current = &bikPlayer; current = &bikPlayer;
@@ -380,7 +393,14 @@ void CVideoPlayer::open(std::string name)
//extract video from video.vid so we can play it //extract video from video.vid so we can play it
vidh->extract(name, name); vidh->extract(name, name);
current->open(name); bool opened = current->open(name);
if(!opened)
{
current = NULL;
tlog3 << "Failed to open video file " << name << std::endl;
}
return opened;
} }
void CVideoPlayer::close() void CVideoPlayer::close()
@@ -403,32 +423,45 @@ void CVideoPlayer::close()
void CVideoPlayer::nextFrame() void CVideoPlayer::nextFrame()
{ {
if(current)
current->nextFrame(); current->nextFrame();
} }
void CVideoPlayer::show(int x, int y, SDL_Surface *dst, bool update) void CVideoPlayer::show(int x, int y, SDL_Surface *dst, bool update)
{ {
if(current)
current->show(x, y, dst, update); current->show(x, y, dst, update);
} }
bool CVideoPlayer::wait() bool CVideoPlayer::wait()
{ {
if(current)
return current->wait(); return current->wait();
else
return false;
} }
int CVideoPlayer::curFrame() const int CVideoPlayer::curFrame() const
{ {
if(current)
return current->curFrame(); return current->curFrame();
else
return -1;
} }
int CVideoPlayer::frameCount() const int CVideoPlayer::frameCount() const
{ {
if(current)
return current->frameCount(); return current->frameCount();
else
return -1;
} }
bool CVideoPlayer::openAndPlayVideo(std::string name, int x, int y, SDL_Surface *dst, bool stopOnKey) bool CVideoPlayer::openAndPlayVideo(std::string name, int x, int y, SDL_Surface *dst, bool stopOnKey)
{ {
open(name); if(!open(name))
return false;
bool ret = playVideo(x, y, dst, stopOnKey); bool ret = playVideo(x, y, dst, stopOnKey);
close(); close();
return ret; return ret;
@@ -436,6 +469,9 @@ bool CVideoPlayer::openAndPlayVideo(std::string name, int x, int y, SDL_Surface
void CVideoPlayer::update( int x, int y, SDL_Surface *dst, bool forceRedraw, bool update ) void CVideoPlayer::update( int x, int y, SDL_Surface *dst, bool forceRedraw, bool update )
{ {
if(current)
return;
bool w = false; bool w = false;
if(!first) if(!first)
{ {
@@ -462,11 +498,15 @@ void CVideoPlayer::update( int x, int y, SDL_Surface *dst, bool forceRedraw, boo
void CVideoPlayer::redraw( int x, int y, SDL_Surface *dst, bool update ) void CVideoPlayer::redraw( int x, int y, SDL_Surface *dst, bool update )
{ {
if(current)
current->redraw(x, y, dst, update); current->redraw(x, y, dst, update);
} }
bool CVideoPlayer::playVideo(int x, int y, SDL_Surface *dst, bool stopOnKey) bool CVideoPlayer::playVideo(int x, int y, SDL_Surface *dst, bool stopOnKey)
{ {
if(!current)
return false;
int frame = 0; int frame = 0;
while(frame < frameCount()) //play all frames while(frame < frameCount()) //play all frames
{ {

View File

@@ -61,7 +61,7 @@ typedef si32(__stdcall* BinkCopyToBuffer)(HBINK, void* buffer, int stride, int
class IVideoPlayer class IVideoPlayer
{ {
public: public:
virtual void open(std::string name)=0; virtual bool open(std::string name)=0; //true - succes
virtual void close()=0; virtual void close()=0;
virtual void nextFrame()=0; virtual void nextFrame()=0;
virtual void show(int x, int y, SDL_Surface *dst, bool update = true)=0; virtual void show(int x, int y, SDL_Surface *dst, bool update = true)=0;
@@ -90,7 +90,7 @@ public:
BinkClose binkClose; BinkClose binkClose;
CBIKHandler(); CBIKHandler();
void open(std::string name); bool open(std::string name);
void close(); void close();
void nextFrame(); void nextFrame();
void show(int x, int y, SDL_Surface *dst, bool update = true); void show(int x, int y, SDL_Surface *dst, bool update = true);
@@ -144,7 +144,7 @@ public:
CSmackPlayer(); CSmackPlayer();
~CSmackPlayer(); ~CSmackPlayer();
void open(std::string name); bool open(std::string name);
void close(); void close();
void nextFrame(); void nextFrame();
void show(int x, int y, SDL_Surface *dst, bool update = true); void show(int x, int y, SDL_Surface *dst, bool update = true);
@@ -172,7 +172,7 @@ public:
~CVideoPlayer(); //d-tor ~CVideoPlayer(); //d-tor
void open(std::string name); bool open(std::string name);
void close(); void close();
void nextFrame(); //move animation to the next frame void nextFrame(); //move animation to the next frame
void show(int x, int y, SDL_Surface *dst, bool update = true); //blit current frame void show(int x, int y, SDL_Surface *dst, bool update = true); //blit current frame