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:
@@ -2516,3 +2516,4 @@ CSavingScreen::~CSavingScreen()
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
{
|
{
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user