1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Re-enabled video player, should now work with SDL 2

This commit is contained in:
Ivan Savenko 2014-05-24 20:12:07 +03:00 committed by AlexVinS
parent 47979d28bb
commit 6205d07223
4 changed files with 67 additions and 22 deletions

View File

@ -16,8 +16,6 @@
// Fixed width bool data type is important for serialization // Fixed width bool data type is important for serialization
static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size."); static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
# define DISABLE_VIDEO
#if defined _M_X64 && defined _WIN32 //Win64 -> cannot load 32-bit DLLs for video handling #if defined _M_X64 && defined _WIN32 //Win64 -> cannot load 32-bit DLLs for video handling
# define DISABLE_VIDEO # define DISABLE_VIDEO
#endif #endif

View File

@ -31,12 +31,12 @@ void checkForError(bool throwing = true)
if(!error) if(!error)
return; return;
logGlobal->errorStream() << "Error " << error << " encountered!"; logGlobal->errorStream() << "Error " << error << " encountered!";
std::string msg; std::string msg;
char* pTemp = nullptr; char* pTemp = nullptr;
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
nullptr, error, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), (LPSTR)&pTemp, 1, nullptr ); nullptr, error, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), (LPSTR)&pTemp, 1, nullptr );
logGlobal->errorStream() << "Error: " << pTemp; logGlobal->errorStream() << "Error: " << pTemp;
msg = pTemp; msg = pTemp;
LocalFree( pTemp ); LocalFree( pTemp );
pTemp = nullptr; pTemp = nullptr;
@ -62,7 +62,7 @@ void DLLHandler::Instantiate(const char *filename)
dll = LoadLibraryA(filename); dll = LoadLibraryA(filename);
if(!dll) if(!dll)
{ {
logGlobal->errorStream() << "Failed loading " << filename; logGlobal->errorStream() << "Failed loading " << filename;
checkForError(true); checkForError(true);
} }
} }
@ -73,13 +73,13 @@ void *DLLHandler::FindAddress(const char *symbol)
if(!dll) if(!dll)
{ {
logGlobal->errorStream() << "Cannot look for " << symbol << " because DLL hasn't been appropriately loaded!"; logGlobal->errorStream() << "Cannot look for " << symbol << " because DLL hasn't been appropriately loaded!";
return nullptr; return nullptr;
} }
ret = (void*) GetProcAddress(dll,symbol); ret = (void*) GetProcAddress(dll,symbol);
if(!ret) if(!ret)
{ {
logGlobal->errorStream() << "Failed to find " << symbol << " in " << name; logGlobal->errorStream() << "Failed to find " << symbol << " in " << name;
checkForError(); checkForError();
} }
return ret; return ret;
@ -91,7 +91,7 @@ DLLHandler::~DLLHandler()
{ {
if(!FreeLibrary(dll)) if(!FreeLibrary(dll))
{ {
logGlobal->errorStream() << "Failed to free " << name; logGlobal->errorStream() << "Failed to free " << name;
checkForError(); checkForError();
} }
} }
@ -138,21 +138,21 @@ bool CBIKHandler::open(std::string name)
if(hBinkFile == INVALID_HANDLE_VALUE) if(hBinkFile == INVALID_HANDLE_VALUE)
{ {
logGlobal->errorStream() << "BIK handler: failed to open " << name; logGlobal->errorStream() << "BIK handler: failed to open " << name;
goto checkErrorAndClean; goto checkErrorAndClean;
} }
//GCC wants scope of waveout to don`t cross labels/swith/goto //GCC wants scope of waveout to don`t cross labels/swith/goto
{ {
void *waveout = GetProcAddress(dll,"_BinkOpenWaveOut@4"); void *waveout = GetProcAddress(dll,"_BinkOpenWaveOut@4");
if(waveout) if(waveout)
binkSetSoundSystem(waveout,nullptr); binkSetSoundSystem(waveout,nullptr);
} }
hBink = binkOpen(hBinkFile, 0x8a800000); hBink = binkOpen(hBinkFile, 0x8a800000);
if(!hBink) if(!hBink)
{ {
logGlobal->errorStream() << "bink failed to open " << name; logGlobal->errorStream() << "bink failed to open " << name;
goto checkErrorAndClean; goto checkErrorAndClean;
} }
@ -302,7 +302,7 @@ bool CSmackPlayer::open( std::string name )
data = ptrSmackOpen( (void*)name.c_str(), flags[1], -1); data = ptrSmackOpen( (void*)name.c_str(), flags[1], -1);
if (!data) if (!data)
{ {
logGlobal->errorStream() << "Smack cannot open " << name; logGlobal->errorStream() << "Smack cannot open " << name;
checkForError(); checkForError();
throw std::runtime_error("SMACK failed opening video"); throw std::runtime_error("SMACK failed opening video");
} }
@ -436,7 +436,7 @@ bool CVideoPlayer::open(std::string name)
catch(std::exception &e) catch(std::exception &e)
{ {
current = nullptr; current = nullptr;
logGlobal->warnStream() << "Failed to open video file " << name << ": " << e.what(); logGlobal->warnStream() << "Failed to open video file " << name << ": " << e.what();
} }
return false; return false;
@ -446,7 +446,7 @@ void CVideoPlayer::close()
{ {
if(!current) if(!current)
{ {
logGlobal->warnStream() << "Closing no opened player...?"; logGlobal->warnStream() << "Closing no opened player...?";
return; return;
} }
@ -454,7 +454,7 @@ void CVideoPlayer::close()
current = nullptr; current = nullptr;
if(!DeleteFileA(fname.c_str())) if(!DeleteFileA(fname.c_str()))
{ {
logGlobal->errorStream() << "Cannot remove temporarily extracted video file: " << fname; logGlobal->errorStream() << "Cannot remove temporarily extracted video file: " << fname;
checkForError(false); checkForError(false);
} }
fname.clear(); fname.clear();
@ -605,7 +605,11 @@ CVideoPlayer::CVideoPlayer()
frame = nullptr; frame = nullptr;
codec = nullptr; codec = nullptr;
sws = nullptr; sws = nullptr;
#ifdef VCMI_SDL1
overlay = nullptr; overlay = nullptr;
#else
texture = nullptr;
#endif
dest = nullptr; dest = nullptr;
context = nullptr; context = nullptr;
@ -635,7 +639,7 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
if (!CResourceHandler::get()->existsResource(resource)) if (!CResourceHandler::get()->existsResource(resource))
{ {
logGlobal->errorStream() << "Error: video " << resource.getName() << " was not found"; logGlobal->errorStream() << "Error: video " << resource.getName() << " was not found";
return false; return false;
} }
@ -708,8 +712,13 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
// Allocate a place to put our YUV image on that screen // Allocate a place to put our YUV image on that screen
if (useOverlay) if (useOverlay)
{ {
#ifdef VCMI_SDL1
overlay = SDL_CreateYUVOverlay(codecContext->width, codecContext->height, overlay = SDL_CreateYUVOverlay(codecContext->width, codecContext->height,
SDL_YV12_OVERLAY, screen); SDL_YV12_OVERLAY, screen);
#else
texture = SDL_CreateTexture( mainRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STATIC, codecContext->width, codecContext->height);
#endif
} }
else else
{ {
@ -718,13 +727,18 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
destRect.w = codecContext->width; destRect.w = codecContext->width;
destRect.h = codecContext->height; destRect.h = codecContext->height;
} }
#ifdef VCMI_SDL1
if (overlay == nullptr && dest == nullptr) if (overlay == nullptr && dest == nullptr)
return false; return false;
// Convert the image into YUV format that SDL uses
if (overlay) if (overlay)
{ #else
if (texture == nullptr && dest == nullptr)
return false;
if (texture)
#endif
{ // Convert the image into YUV format that SDL uses
sws = sws_getContext(codecContext->width, codecContext->height, sws = sws_getContext(codecContext->width, codecContext->height,
codecContext->pix_fmt, codecContext->width, codecContext->height, codecContext->pix_fmt, codecContext->width, codecContext->height,
PIX_FMT_YUV420P, SWS_BICUBIC, nullptr, nullptr, nullptr); PIX_FMT_YUV420P, SWS_BICUBIC, nullptr, nullptr, nullptr);
@ -812,6 +826,7 @@ bool CVideoPlayer::nextFrame()
{ {
AVPicture pict; AVPicture pict;
#ifdef VCMI_SDL1
if (overlay) { if (overlay) {
SDL_LockYUVOverlay(overlay); SDL_LockYUVOverlay(overlay);
@ -827,6 +842,18 @@ bool CVideoPlayer::nextFrame()
0, codecContext->height, pict.data, pict.linesize); 0, codecContext->height, pict.data, pict.linesize);
SDL_UnlockYUVOverlay(overlay); SDL_UnlockYUVOverlay(overlay);
#else
if (texture) {
avpicture_alloc(&pict, AV_PIX_FMT_YUV420P, codecContext->width, codecContext->height);
sws_scale(sws, frame->data, frame->linesize,
0, codecContext->height, pict.data, pict.linesize);
SDL_UpdateYUVTexture(texture, NULL, pict.data[0], pict.linesize[0],
pict.data[1], pict.linesize[1],
pict.data[2], pict.linesize[2]);
avpicture_free(&pict);
#endif
} }
else else
{ {
@ -902,11 +929,21 @@ void CVideoPlayer::close()
sws = nullptr; sws = nullptr;
} }
#ifdef VCMI_SDL1
if (overlay) if (overlay)
{ {
SDL_FreeYUVOverlay(overlay); SDL_FreeYUVOverlay(overlay);
overlay = nullptr; overlay = nullptr;
} }
#else
if (texture)
{
SDL_DestroyTexture(texture);
texture = nullptr;
}
#endif
if (dest) if (dest)
{ {
@ -960,7 +997,13 @@ bool CVideoPlayer::playVideo(int x, int y, SDL_Surface *dst, bool stopOnKey)
if(stopOnKey && keyDown()) if(stopOnKey && keyDown())
return false; return false;
#ifdef VCMI_SDL1
SDL_DisplayYUVOverlay(overlay, &pos); SDL_DisplayYUVOverlay(overlay, &pos);
#else
SDL_RenderCopy(mainRenderer, texture, NULL, NULL);
SDL_RenderPresent(mainRenderer);
#endif
// Wait 3 frames // Wait 3 frames
GH.mainFPSmng->framerateDelay(); GH.mainFPSmng->framerateDelay();

View File

@ -242,7 +242,12 @@ class CVideoPlayer : public IMainVideoPlayer
AVIOContext * context; AVIOContext * context;
// Destination. Either overlay or dest. // Destination. Either overlay or dest.
SDL_Overlay *overlay; #ifdef VCMI_SDL1
SDL_Overlay overlay;
#else
SDL_Texture *texture;
#endif
SDL_Surface *dest; SDL_Surface *dest;
SDL_Rect destRect; // valid when dest is used SDL_Rect destRect; // valid when dest is used
SDL_Rect pos; // destination on screen SDL_Rect pos; // destination on screen

View File

@ -222,7 +222,6 @@ std::vector<std::string> VCMIDirs::dataPaths() const
{ {
std::string dataDirsEnv = getenv("XDG_DATA_DIRS"); std::string dataDirsEnv = getenv("XDG_DATA_DIRS");
std::vector<std::string> dataDirs; std::vector<std::string> dataDirs;
std::cout << dataDirsEnv;
boost::split(dataDirs, dataDirsEnv, boost::is_any_of(":")); boost::split(dataDirs, dataDirsEnv, boost::is_any_of(":"));
for (auto & entry : boost::adaptors::reverse(dataDirs)) for (auto & entry : boost::adaptors::reverse(dataDirs))
ret.push_back(entry + "/vcmi"); ret.push_back(entry + "/vcmi");