|  | @@ -23,553 +23,7 @@ static bool keyDown()
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -#if defined(_WIN32)  &&  (_MSC_VER < 1800 ||  !defined(USE_FFMPEG))
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -void checkForError(bool throwing = true)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	int error = GetLastError();
 | 
	
		
			
				|  |  | -	if(!error)
 | 
	
		
			
				|  |  | -		return;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	logGlobal->errorStream() << "Error " << error << " encountered!";
 | 
	
		
			
				|  |  | -	std::string msg;
 | 
	
		
			
				|  |  | -	char* pTemp = nullptr;
 | 
	
		
			
				|  |  | -	FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
 | 
	
		
			
				|  |  | -		nullptr, error,  MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), (LPSTR)&pTemp, 1, nullptr );
 | 
	
		
			
				|  |  | -	logGlobal->errorStream() << "Error: " << pTemp;
 | 
	
		
			
				|  |  | -	msg = pTemp;
 | 
	
		
			
				|  |  | -	LocalFree( pTemp );
 | 
	
		
			
				|  |  | -	pTemp = nullptr;
 | 
	
		
			
				|  |  | -	if(throwing)
 | 
	
		
			
				|  |  | -		throw std::runtime_error(msg);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -void blitBuffer(char *buffer, int x, int y, int w, int h, SDL_Surface *dst)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	const int bpp = dst->format->BytesPerPixel;
 | 
	
		
			
				|  |  | -	char *dest;
 | 
	
		
			
				|  |  | -	for(int i = h; i > 0; i--)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		dest = (char*)dst->pixels + dst->pitch*(y+h-i) + x*dst->format->BytesPerPixel;
 | 
	
		
			
				|  |  | -		memcpy(dest, buffer, bpp*w);
 | 
	
		
			
				|  |  | -		buffer += bpp*w;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -void DLLHandler::Instantiate(const char *filename)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	name = filename;
 | 
	
		
			
				|  |  | -	dll = LoadLibraryA(filename);
 | 
	
		
			
				|  |  | -	if(!dll)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		logGlobal->errorStream() << "Failed loading " << filename;
 | 
	
		
			
				|  |  | -		checkForError(true);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -void *DLLHandler::FindAddress(const char *symbol)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	void *ret;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if(!dll)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		logGlobal->errorStream() << "Cannot look for " << symbol << " because DLL hasn't been appropriately loaded!";
 | 
	
		
			
				|  |  | -		return nullptr;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	ret = (void*) GetProcAddress(dll,symbol);
 | 
	
		
			
				|  |  | -	if(!ret)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		logGlobal->errorStream() << "Failed to find " << symbol << " in " << name;
 | 
	
		
			
				|  |  | -		checkForError();
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return ret;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -DLLHandler::~DLLHandler()
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	if(dll)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		if(!FreeLibrary(dll))
 | 
	
		
			
				|  |  | -		{
 | 
	
		
			
				|  |  | -			logGlobal->errorStream() << "Failed to free " << name;
 | 
	
		
			
				|  |  | -			checkForError();
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -DLLHandler::DLLHandler()
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	dll = nullptr;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -CBIKHandler::CBIKHandler()
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	Instantiate("BINKW32.DLL");
 | 
	
		
			
				|  |  | -	//binkGetError = FindAddress("_BinkGetError@0");
 | 
	
		
			
				|  |  | -	binkOpen = (BinkOpen)FindAddress("_BinkOpen@8");
 | 
	
		
			
				|  |  | -	binkSetSoundSystem = (BinkSetSoundSystem)FindAddress("_BinkSetSoundSystem@8");
 | 
	
		
			
				|  |  | -	//getPalette = (BinkGetPalette)FindAddress("_BinkGetPalette@4");
 | 
	
		
			
				|  |  | -	binkNextFrame = (BinkNextFrame)FindAddress("_BinkNextFrame@4");
 | 
	
		
			
				|  |  | -	binkDoFrame = (BinkDoFrame)FindAddress("_BinkDoFrame@4");
 | 
	
		
			
				|  |  | -	binkCopyToBuffer = (BinkCopyToBuffer)FindAddress("_BinkCopyToBuffer@28");
 | 
	
		
			
				|  |  | -	binkWait = (BinkWait)FindAddress("_BinkWait@4");
 | 
	
		
			
				|  |  | -	binkClose =  (BinkClose)FindAddress("_BinkClose@4");
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	hBinkFile = nullptr;
 | 
	
		
			
				|  |  | -	hBink = nullptr;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	buffer = nullptr;
 | 
	
		
			
				|  |  | -	bufferSize = 0;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -bool CBIKHandler::open(std::string name)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	hBinkFile = CreateFileA
 | 
	
		
			
				|  |  | -	(
 | 
	
		
			
				|  |  | -		name.c_str(),				// file name
 | 
	
		
			
				|  |  | -		GENERIC_READ,						// access mode
 | 
	
		
			
				|  |  | -		FILE_SHARE_READ,	// share mode
 | 
	
		
			
				|  |  | -		nullptr,								// Security Descriptor
 | 
	
		
			
				|  |  | -		OPEN_EXISTING,						// how to create
 | 
	
		
			
				|  |  | -		FILE_ATTRIBUTE_NORMAL,//FILE_FLAG_SEQUENTIAL_SCAN,			// file attributes
 | 
	
		
			
				|  |  | -		0								// handle to template file
 | 
	
		
			
				|  |  | -	);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if(hBinkFile == INVALID_HANDLE_VALUE)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		logGlobal->errorStream() << "BIK handler: failed to open " << name;
 | 
	
		
			
				|  |  | -		goto checkErrorAndClean;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	//GCC wants scope of waveout to don`t cross labels/swith/goto
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		void *waveout = GetProcAddress(dll,"_BinkOpenWaveOut@4");
 | 
	
		
			
				|  |  | -		if(waveout)
 | 
	
		
			
				|  |  | -			binkSetSoundSystem(waveout,nullptr);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	hBink = binkOpen(hBinkFile, 0x8a800000);
 | 
	
		
			
				|  |  | -	if(!hBink)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		logGlobal->errorStream() << "bink failed to open " << name;
 | 
	
		
			
				|  |  | -		goto checkErrorAndClean;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	allocBuffer();
 | 
	
		
			
				|  |  | -	return true;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -checkErrorAndClean:
 | 
	
		
			
				|  |  | -	CloseHandle(hBinkFile);
 | 
	
		
			
				|  |  | -	hBinkFile = nullptr;
 | 
	
		
			
				|  |  | -	checkForError();
 | 
	
		
			
				|  |  | -	throw std::runtime_error("BIK failed opening video!");
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -void CBIKHandler::show( int x, int y, SDL_Surface *dst, bool update )
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	const int w = hBink->width,
 | 
	
		
			
				|  |  | -		h = hBink->height,
 | 
	
		
			
				|  |  | -		Bpp = dst->format->BytesPerPixel;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	int mode = -1;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	//screen color depth might have changed... (eg. because F4)
 | 
	
		
			
				|  |  | -	if(bufferSize != w * h * Bpp)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		freeBuffer();
 | 
	
		
			
				|  |  | -		allocBuffer(Bpp);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	switch(Bpp)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -	case 2:
 | 
	
		
			
				|  |  | -		mode = 3; //565, mode 2 is 555 probably
 | 
	
		
			
				|  |  | -		break;
 | 
	
		
			
				|  |  | -	case 3:
 | 
	
		
			
				|  |  | -		mode = 0;
 | 
	
		
			
				|  |  | -		break;
 | 
	
		
			
				|  |  | -	case 4:
 | 
	
		
			
				|  |  | -		mode = 1;
 | 
	
		
			
				|  |  | -		break;
 | 
	
		
			
				|  |  | -	default:
 | 
	
		
			
				|  |  | -		return; //not supported screen depth
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	binkDoFrame(hBink);
 | 
	
		
			
				|  |  | -	binkCopyToBuffer(hBink, buffer, w*Bpp, h, 0, 0, mode);
 | 
	
		
			
				|  |  | -	blitBuffer(buffer, x, y, w, h, dst);
 | 
	
		
			
				|  |  | -	if(update)
 | 
	
		
			
				|  |  | -		SDL_UpdateRect(dst, x, y, w, h);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -bool CBIKHandler::nextFrame()
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	binkNextFrame(hBink);
 | 
	
		
			
				|  |  | -	return true;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -void CBIKHandler::close()
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	binkClose(hBink);
 | 
	
		
			
				|  |  | -	hBink = nullptr;
 | 
	
		
			
				|  |  | -	CloseHandle(hBinkFile);
 | 
	
		
			
				|  |  | -	hBinkFile = nullptr;
 | 
	
		
			
				|  |  | -	delete [] buffer;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	buffer = nullptr;
 | 
	
		
			
				|  |  | -	bufferSize = 0;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -bool CBIKHandler::wait()
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	return binkWait(hBink);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -int CBIKHandler::curFrame() const
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	return hBink->currentFrame;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -int CBIKHandler::frameCount() const
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	return hBink->frameCount;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -void CBIKHandler::redraw( int x, int y, SDL_Surface *dst, bool update )
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	int w = hBink->width, h = hBink->height;
 | 
	
		
			
				|  |  | -	blitBuffer(buffer, x, y, w, h, dst);
 | 
	
		
			
				|  |  | -	if(update)
 | 
	
		
			
				|  |  | -		SDL_UpdateRect(dst, x, y, w, h);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -void CBIKHandler::allocBuffer(int Bpp)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	if(!Bpp) Bpp = screen->format->BytesPerPixel;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	bufferSize = hBink->width * hBink->height * Bpp;
 | 
	
		
			
				|  |  | -	buffer = new char[bufferSize];
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -void CBIKHandler::freeBuffer()
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	delete [] buffer;
 | 
	
		
			
				|  |  | -	buffer = nullptr;
 | 
	
		
			
				|  |  | -	bufferSize = 0;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -bool CSmackPlayer::nextFrame()
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	ptrSmackNextFrame(data);
 | 
	
		
			
				|  |  | -	return true;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -bool CSmackPlayer::wait()
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	return ptrSmackWait(data);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -CSmackPlayer::CSmackPlayer() : data(nullptr)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	Instantiate("smackw32.dll");
 | 
	
		
			
				|  |  | -	ptrSmackNextFrame = (SmackNextFrame)FindAddress("_SmackNextFrame@4");
 | 
	
		
			
				|  |  | -	ptrSmackWait = (SmackWait)FindAddress("_SmackWait@4");
 | 
	
		
			
				|  |  | -	ptrSmackDoFrame = (SmackDoFrame)FindAddress("_SmackDoFrame@4");
 | 
	
		
			
				|  |  | -	ptrSmackToBuffer = (SmackToBuffer)FindAddress("_SmackToBuffer@28");
 | 
	
		
			
				|  |  | -	ptrSmackOpen = (SmackOpen)FindAddress("_SmackOpen@12");
 | 
	
		
			
				|  |  | -	ptrSmackSoundOnOff = (SmackSoundOnOff)FindAddress("_SmackSoundOnOff@8");
 | 
	
		
			
				|  |  | -	ptrSmackClose = (SmackClose)FindAddress("_SmackClose@4");
 | 
	
		
			
				|  |  | -	ptrVolumePan = (SmackVolumePan)FindAddress("_SmackVolumePan@16");
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -CSmackPlayer::~CSmackPlayer()
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	if(data)
 | 
	
		
			
				|  |  | -		close();
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -void CSmackPlayer::close()
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	ptrSmackClose(data);
 | 
	
		
			
				|  |  | -	data = nullptr;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -bool CSmackPlayer::open( std::string name )
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	Uint32 flags[2] = {0xff400, 0xfe400};
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	data = ptrSmackOpen( (void*)name.c_str(), flags[1], -1);
 | 
	
		
			
				|  |  | -	if (!data)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		logGlobal->errorStream() << "Smack cannot open " << name;
 | 
	
		
			
				|  |  | -		checkForError();
 | 
	
		
			
				|  |  | -		throw std::runtime_error("SMACK failed opening video");
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	buffer = new char[data->width*data->height*2];
 | 
	
		
			
				|  |  | -	buf = buffer+data->width*(data->height-1)*2;	// adjust pointer position for later use by 'SmackToBuffer'
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	//ptrVolumePan(data, 0xfe000, 3640 * GDefaultOptions.musicVolume / 11, 0x8000); //set volume
 | 
	
		
			
				|  |  | -	return true;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -void CSmackPlayer::show( int x, int y, SDL_Surface *dst, bool update)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	int w = data->width;
 | 
	
		
			
				|  |  | -	int stripe = (-w*2) & (~3);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	//put frame to the buffer
 | 
	
		
			
				|  |  | -	ptrSmackToBuffer(data, 0, 0, stripe, w, buf, 0x80000000);
 | 
	
		
			
				|  |  | -	ptrSmackDoFrame(data);
 | 
	
		
			
				|  |  | -	redraw(x, y, dst, update);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -int CSmackPlayer::curFrame() const
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	return data->currentFrame;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -int CSmackPlayer::frameCount() const
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	return data->frameCount;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -void CSmackPlayer::redraw( int x, int y, SDL_Surface *dst, bool update )
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	int w = std::min<int>(data->width, dst->w - x), h = std::min<int>(data->height, dst->h - y);
 | 
	
		
			
				|  |  | -	/* Lock the screen for direct access to the pixels */
 | 
	
		
			
				|  |  | -	if ( SDL_MUSTLOCK(dst) )
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		if ( SDL_LockSurface(dst) < 0 )
 | 
	
		
			
				|  |  | -		{
 | 
	
		
			
				|  |  | -			fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
 | 
	
		
			
				|  |  | -			return;
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	// draw the frame
 | 
	
		
			
				|  |  | -	Uint16* addr = (Uint16*) (buffer+w*(h-1)*2-2);
 | 
	
		
			
				|  |  | -	if(dst->format->BytesPerPixel >= 3)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		for( int j=0; j<h-1; j++)	// why -1 ?
 | 
	
		
			
				|  |  | -		{
 | 
	
		
			
				|  |  | -			for ( int i=w-1; i>=0; i--)
 | 
	
		
			
				|  |  | -			{
 | 
	
		
			
				|  |  | -				Uint16 pixel = *addr;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -				Uint8 *p = (Uint8 *)dst->pixels + (j+y) * dst->pitch + (i + x) * dst->format->BytesPerPixel;
 | 
	
		
			
				|  |  | -				p[2] = ((pixel & 0x7c00) >> 10) * 8;
 | 
	
		
			
				|  |  | -				p[1] = ((pixel & 0x3e0) >> 5) * 8;
 | 
	
		
			
				|  |  | -				p[0] = ((pixel & 0x1F)) * 8;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -				addr--;
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	else if(dst->format->BytesPerPixel == 2)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		for( int j=0; j<h-1; j++)	// why -1 ?
 | 
	
		
			
				|  |  | -		{
 | 
	
		
			
				|  |  | -			for ( int i=w-1; i>=0; i--)
 | 
	
		
			
				|  |  | -			{
 | 
	
		
			
				|  |  | -				//convert rgb 555 to 565
 | 
	
		
			
				|  |  | -				Uint16 pixel = *addr;
 | 
	
		
			
				|  |  | -				Uint16 *p = (Uint16 *)((Uint8 *)dst->pixels + (j+y) * dst->pitch + (i + x) * dst->format->BytesPerPixel);
 | 
	
		
			
				|  |  | -				*p =	(pixel & 0x1F)
 | 
	
		
			
				|  |  | -					  +	((pixel & 0x3e0) << 1)
 | 
	
		
			
				|  |  | -					  +	((pixel & 0x7c00) << 1);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -				addr--;
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if ( SDL_MUSTLOCK(dst) )
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		SDL_UnlockSurface(dst);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if(update)
 | 
	
		
			
				|  |  | -		SDL_UpdateRect(dst, x, y, w, h);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -CVideoPlayer::CVideoPlayer()
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	current = nullptr;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -CVideoPlayer::~CVideoPlayer()
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -bool CVideoPlayer::open(std::string name)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	fname = name;
 | 
	
		
			
				|  |  | -	first = true;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	try
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		// Extract video from video.vid so we can play it.
 | 
	
		
			
				|  |  | -		// We can handle only videos in form of single file, no archive support yet.
 | 
	
		
			
				|  |  | -		{
 | 
	
		
			
				|  |  | -			ResourceID videoID = ResourceID("VIDEO/" + name, EResType::VIDEO);
 | 
	
		
			
				|  |  | -			auto data = CResourceHandler::get()->load(videoID)->readAll();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -			// try to determine video format using magic number from header (3 bytes, SMK or BIK)
 | 
	
		
			
				|  |  | -			std::string magic(reinterpret_cast<char*>(data.first.get()), 3);
 | 
	
		
			
				|  |  | -			if (magic == "BIK")
 | 
	
		
			
				|  |  | -				current = &bikPlayer;
 | 
	
		
			
				|  |  | -			else if (magic == "SMK")
 | 
	
		
			
				|  |  | -				current = &smkPlayer;
 | 
	
		
			
				|  |  | -			else
 | 
	
		
			
				|  |  | -				throw std::runtime_error("Unknown video format: " + magic);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -			std::ofstream out(name, std::ofstream::binary);
 | 
	
		
			
				|  |  | -			out.exceptions(std::ifstream::failbit | std::ifstream::badbit);
 | 
	
		
			
				|  |  | -			out.write(reinterpret_cast<char*>(data.first.get()), data.second);
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		current->open(name);
 | 
	
		
			
				|  |  | -		return true;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	catch(std::exception &e)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		current = nullptr;
 | 
	
		
			
				|  |  | -		logGlobal->warnStream() << "Failed to open video file " << name << ": " << e.what();
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	return false;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -void CVideoPlayer::close()
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	if(!current)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		logGlobal->warnStream() << "Closing no opened player...?";
 | 
	
		
			
				|  |  | -		return;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	current->close();
 | 
	
		
			
				|  |  | -	current = nullptr;
 | 
	
		
			
				|  |  | -	if(!DeleteFileA(fname.c_str()))
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		logGlobal->errorStream() << "Cannot remove temporarily extracted video file: " << fname;
 | 
	
		
			
				|  |  | -		checkForError(false);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	fname.clear();
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -bool CVideoPlayer::nextFrame()
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	if(current)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		current->nextFrame();
 | 
	
		
			
				|  |  | -		return true;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	else
 | 
	
		
			
				|  |  | -		return false;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -void CVideoPlayer::show(int x, int y, SDL_Surface *dst, bool update)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	if(current)
 | 
	
		
			
				|  |  | -		current->show(x, y, dst, update);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -bool CVideoPlayer::wait()
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	if(current)
 | 
	
		
			
				|  |  | -		return current->wait();
 | 
	
		
			
				|  |  | -	else
 | 
	
		
			
				|  |  | -		return false;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -int CVideoPlayer::curFrame() const
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	if(current)
 | 
	
		
			
				|  |  | -		return current->curFrame();
 | 
	
		
			
				|  |  | -	else
 | 
	
		
			
				|  |  | -		return -1;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -int CVideoPlayer::frameCount() const
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	if(current)
 | 
	
		
			
				|  |  | -		return current->frameCount();
 | 
	
		
			
				|  |  | -	else
 | 
	
		
			
				|  |  | -		return -1;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -bool CVideoPlayer::openAndPlayVideo(std::string name, int x, int y, SDL_Surface *dst, bool stopOnKey)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	if(!open(name))
 | 
	
		
			
				|  |  | -		return false;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	bool ret = playVideo(x, y, dst, stopOnKey);
 | 
	
		
			
				|  |  | -	close();
 | 
	
		
			
				|  |  | -	return ret;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -void CVideoPlayer::update( int x, int y, SDL_Surface *dst, bool forceRedraw, bool update )
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	if(!current)
 | 
	
		
			
				|  |  | -		return;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	bool w = false;
 | 
	
		
			
				|  |  | -	if(!first)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		w = wait(); //check if should keep current frame
 | 
	
		
			
				|  |  | -		if(!w)
 | 
	
		
			
				|  |  | -			nextFrame();
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	else
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		first = false;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if(!w)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		show(x,y,dst,update);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	else if (forceRedraw)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		redraw(x, y, dst, update);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -void CVideoPlayer::redraw( int x, int y, SDL_Surface *dst, bool update )
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	if(current)
 | 
	
		
			
				|  |  | -		current->redraw(x, y, dst, update);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -bool CVideoPlayer::playVideo(int x, int y, SDL_Surface *dst, bool stopOnKey)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -	if(!current)
 | 
	
		
			
				|  |  | -		return false;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	int frame = 0;
 | 
	
		
			
				|  |  | -	while(frame < frameCount()) //play all frames
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		if(stopOnKey && keyDown())
 | 
	
		
			
				|  |  | -			return false;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		if(!wait())
 | 
	
		
			
				|  |  | -		{
 | 
	
		
			
				|  |  | -			show(x, y, dst);
 | 
	
		
			
				|  |  | -			nextFrame();
 | 
	
		
			
				|  |  | -			frame++;
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		SDL_Delay(20);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	return true;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -#else
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #ifdef _MSC_VER
 | 
	
		
			
				|  |  |  #pragma comment(lib, "avcodec.lib")
 | 
	
	
		
			
				|  | @@ -1029,4 +483,3 @@ CVideoPlayer::~CVideoPlayer()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -#endif
 |