Kaynağa Gözat

Mostly done .BIK video handling (WIN only).
Refactoring.

Michał W. Urbańczyk 16 yıl önce
ebeveyn
işleme
9ff6501ba3

+ 48 - 43
CConsoleHandler.cpp

@@ -1,14 +1,37 @@
 #define VCMI_DLL
 #include "stdafx.h"
 #include "CConsoleHandler.h"
-#include "boost/function.hpp"
+#include <boost/function.hpp>
+#include <boost/thread.hpp>
 
-#ifdef _WIN32
-#include <windows.h>
-HANDLE handleIn;
-HANDLE handleOut;
+
+#ifndef _WIN32
+	typedef std::string TColor;
+	#define	_kill_thread(a) pthread_cancel(a)
+	typedef pthread_t ThreadHandle;
+	#define CONSOLE_GREEN "\x1b[1;40;32m"
+	#define CONSOLE_RED "\x1b[1;40;32m"
+	#define CONSOLE_MAGENTA "\x1b[1;40;35m"
+	#define CONSOLE_YELLOW "\x1b[1;40;32m"
+	#define CONSOLE_WHITE "\x1b[1;40;39m"
+	#define CONSOLE_GRAY "\x1b[0;40;39m"
+#else
+	typedef WORD TColor;
+	#define _kill_thread(a) TerminateThread(a,0)
+	#include <windows.h>
+	HANDLE handleIn;
+	HANDLE handleOut;
+	typedef void* ThreadHandle;
+	#define CONSOLE_GREEN FOREGROUND_GREEN | FOREGROUND_INTENSITY
+	#define CONSOLE_RED FOREGROUND_RED | FOREGROUND_INTENSITY
+	#define CONSOLE_MAGENTA FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY
+	#define CONSOLE_YELLOW FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY
+	#define CONSOLE_WHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
+	#define CONSOLE_GRAY FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
 #endif
-WORD defColor;
+
+TColor defColor;
+
 
 /*
  * CConsoleHandler.cpp, part of VCMI engine
@@ -22,53 +45,29 @@ WORD defColor;
 
 void CConsoleHandler::setColor(int level)
 {
-	WORD color;
+	TColor color;
 	switch(level)
 	{
 	case -1:
 		color = defColor;
 		break;
 	case 0:
-#ifdef _WIN32
-		color = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
-#else
-		color = "\x1b[1;40;32m";
-#endif
+		color = CONSOLE_GREEN;
 		break;
 	case 1:
-#ifdef _WIN32
-		color = FOREGROUND_RED | FOREGROUND_INTENSITY;
-#else
-		color = "\x1b[1;40;31m";
-#endif
+		color = CONSOLE_RED;
 		break;
 	case 2:
-#ifdef _WIN32
-		color = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
-#else
-		color = "\x1b[1;40;35m";
-#endif
+		color = CONSOLE_MAGENTA;
 		break;
 	case 3:
-#ifdef _WIN32
-		color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
-#else
-		color = "\x1b[1;40;32m";
-#endif
+		color = CONSOLE_YELLOW;
 		break;
 	case 4:
-#ifdef _WIN32
-		color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
-#else
-		color = "\x1b[1;40;39m";
-#endif
+		color = CONSOLE_WHITE;
 		break;
 	case 5:
-#ifdef _WIN32
-		color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
-#else
-		color = "\x1b[0;40;39m";
-#endif
+		color = CONSOLE_GRAY;
 		break;
 	default:
 		color = defColor;
@@ -104,18 +103,24 @@ CConsoleHandler::CConsoleHandler()
 	defColor = "\x1b[0m";
 #endif
 	cb = new boost::function<void(const std::string &)>;
+	thread = NULL;
 }
 CConsoleHandler::~CConsoleHandler()
 {
 	delete cb;
+	delete thread;
 }
-#ifndef _WIN32
-void CConsoleHandler::killConsole(pthread_t hThread)
-#else
-void CConsoleHandler::killConsole(void *hThread)
-#endif
+void CConsoleHandler::end()
 {
 	tlog3 << "Killing console... ";
-	_kill_thread(hThread,0);
+	ThreadHandle th = (ThreadHandle)thread->native_handle();
+	_kill_thread(th);
+	delete thread;
+	thread = NULL;
 	tlog3 << "done!\n";
 }
+
+void CConsoleHandler::start()
+{
+	thread = new boost::thread(boost::bind(&CConsoleHandler::run,console));
+}

+ 8 - 15
CConsoleHandler.h

@@ -1,16 +1,6 @@
 #ifndef __CCONSOLEHANDLER_H__
 #define __CCONSOLEHANDLER_H__
 
-#ifndef _WIN32
-#define WORD std::string
-#endif
-
-#ifndef _WIN32
-#define	_kill_thread(a,b) pthread_cancel(a);
-#else
-#define _kill_thread(a,b) TerminateThread(a,b);
-#endif
-
 /*
  * CConsoleHandler.h, part of VCMI engine
  *
@@ -25,21 +15,24 @@ namespace boost
 {
 	template<typename signature>
 	class function;
+	class thread;
 }
+
 class DLL_EXPORT CConsoleHandler
 {
 public:
 	boost::function<void(const std::string &)> *cb; //function to be called when message is received
 	int curLvl; //logging level
+	boost::thread *thread;
+
 	int run();
 	void setColor(int level); //sets color of text appropriate for given logging level
+
 	CConsoleHandler(); //c-tor
 	~CConsoleHandler(); //d-tor
-#ifndef _WIN32
-	static void killConsole(pthread_t hThread); //for windows only, use native handle to the thread
-#else
-	static void killConsole(void *hThread); //for windows only, use native handle to the thread
-#endif
+	void start(); //starts listening thread
+	void end(); //kills listening thread
+
 	template<typename T> void print(const T &data, int level)
 	{
 		setColor(level);

+ 0 - 4
client/CAdvmapInterface.cpp

@@ -1630,10 +1630,6 @@ void CAdvMapInt::select(const CArmedInstance *sel )
 			else
 				paths.erase(h);
 		}
-		else
-		{
-			terrain.currentPath;
-		}	
 	}
 	townList.draw(screen);
 	heroList.draw(screen);

+ 16 - 8
client/CMT.cpp

@@ -69,6 +69,7 @@ TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX, *GEORM, *GEOR16;
 
 void processCommand(const std::string &message, CClient *&client);
 static void setScreenRes(int w, int h, int bpp, bool fullscreen);
+void dispose();
 
 #ifndef __GNUC__
 int _tmain(int argc, _TCHAR* argv[])
@@ -76,16 +77,15 @@ int _tmain(int argc, _TCHAR* argv[])
 int main(int argc, char** argv)
 #endif
 {
+
 	tlog0 << "Starting... " << std::endl;
 	THC timeHandler tmh, total, pomtime;
 	CClient *client = NULL;
-	boost::thread *console = NULL;
-
 	std::cout.flags(std::ios::unitbuf);
 	logfile = new std::ofstream("VCMI_Client_log.txt");
-	::console = new CConsoleHandler;
-	*::console->cb = boost::bind(processCommand,_1,boost::ref(client));
-	console = new boost::thread(boost::bind(&CConsoleHandler::run,::console));
+	console = new CConsoleHandler;
+	console->start();
+	atexit(dispose);
 	tlog0 <<"Creating console and logfile: "<<pomtime.getDif() << std::endl;
 
 	conf.init();
@@ -100,6 +100,7 @@ int main(int argc, char** argv)
 	{
 		setScreenRes(800,600,conf.cc.bpp,conf.cc.fullscreen);
 		tlog0 <<"\tInitializing screen: "<<pomtime.getDif() << std::endl;
+
 		#if SDL_BYTEORDER == SDL_BIG_ENDIAN
 			int rmask = 0xff000000;int gmask = 0x00ff0000;int bmask = 0x0000ff00;int amask = 0x000000ff;
 		#else
@@ -107,6 +108,7 @@ int main(int argc, char** argv)
 		#endif
 		CSDL_Ext::std32bppSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, 1, 1, 32, rmask, gmask, bmask, amask);
 		tlog0 << "\tInitializing minors: " << pomtime.getDif() << std::endl;
+
 		TTF_Init();
 		TNRB16 = TTF_OpenFont("Fonts" PATHSEPARATOR "tnrb.ttf",16);
 		GEOR13 = TTF_OpenFont("Fonts" PATHSEPARATOR "georgia.ttf",13);
@@ -142,6 +144,7 @@ int main(int argc, char** argv)
 		cgi->soundh->initCreaturesSounds(CGI->creh->creatures);
 		cgi->soundh->initSpellsSounds(CGI->spellh->spells);
 		tlog0<<"Initializing VCMI_Lib: "<<tmh.getDif()<<std::endl;
+
 		pomtime.getDif();
 		cgi->curh = new CCursorHandler;
 		cgi->curh->initCursor();
@@ -152,6 +155,7 @@ int main(int argc, char** argv)
 		graphics->loadHeroAnim();
 		tlog0<<"\tMain graphics: "<<tmh.getDif()<<std::endl;
 		tlog0<<"Initializing game graphics: "<<tmh.getDif()<<std::endl;
+
 		CMessage::init();
 		tlog0<<"Message handler: "<<tmh.getDif()<<std::endl;
 		CPreGame * cpg = new CPreGame(); //main menu and submenus
@@ -222,9 +226,7 @@ int main(int argc, char** argv)
 			{
 				LOCPLINT->pim->lock();
 				cl.close();
-#ifndef __unix__
-				::console->killConsole(console->native_handle());
-#endif
+				console->end();
 				SDL_Delay(750);
 				tlog0 << "Ending...\n";
 				exit(EXIT_SUCCESS);
@@ -352,6 +354,12 @@ void processCommand(const std::string &message, CClient *&client)
 	}
 }
 
+void dispose()
+{
+	delete logfile;
+	delete console;
+}
+
 static void setScreenRes(int w, int h, int bpp, bool fullscreen)
 {
 	if(screen) //screen has been already initialized

+ 6 - 1
client/Client.cpp

@@ -193,12 +193,17 @@ void CClient::load( const std::string & fname )
 	VLC->clear(); //delete old handlers
 	delete CGI->mh;
 	delete CGI->state;
-	//TODO: del callbacks
+
 
 	for(std::map<ui8,CGameInterface *>::iterator i = playerint.begin(); i!=playerint.end(); i++)
 	{
 		delete i->second; //delete player interfaces
 	}
+
+	BOOST_FOREACH(CCallback *cb, callbacks)
+	{
+		delete cb;
+	}
 	tlog0 <<"Deleting old data: "<<tmh.getDif()<<std::endl;
 
 	char portc[10];

+ 1 - 1
client/SDL_Extensions.cpp

@@ -244,7 +244,7 @@ void CSDL_Ext::printToWR(const std::string & text, int x, int y, TTF_Font * font
 	SDL_FreeSurface(temp);
 }
 
-inline void CSDL_Ext::SDL_PutPixel(SDL_Surface *ekran, const int & x, const int & y, const Uint8 & R, const Uint8 & G, const Uint8 & B, Uint8 A)
+void CSDL_Ext::SDL_PutPixel(SDL_Surface *ekran, const int & x, const int & y, const Uint8 & R, const Uint8 & G, const Uint8 & B, Uint8 A)
 {
 	Uint8 *p = (Uint8 *)ekran->pixels + y * ekran->pitch + x * ekran->format->BytesPerPixel;
 

+ 1 - 1
client/SDL_Extensions.h

@@ -38,7 +38,7 @@ inline SDL_Rect genRect(const int & hh, const int & ww, const int & xx, const in
 namespace CSDL_Ext
 {
 	extern SDL_Surface * std32bppSurface;
-	inline void SDL_PutPixel(SDL_Surface *ekran, const int & x, const int & y, const Uint8 & R, const Uint8 & G, const Uint8 & B, Uint8 A = 255); //myC influences the start of reading pixels
+	void SDL_PutPixel(SDL_Surface *ekran, const int & x, const int & y, const Uint8 & R, const Uint8 & G, const Uint8 & B, Uint8 A = 255); //myC influences the start of reading pixels
 	//inline void SDL_PutPixelWithoutRefresh(SDL_Surface *ekran, const int & x, const int & y, const Uint8 & R, const Uint8 & G, const Uint8 & B, Uint8 A = 255); //myC influences the start of reading pixels ; without refreshing
 
 	inline void SDL_PutPixelWithoutRefresh(SDL_Surface *ekran, const int & x, const int & y, const Uint8 & R, const Uint8 & G, const Uint8 & B, Uint8 A = 255)

+ 8 - 0
client/VCMI_client.vcproj

@@ -358,6 +358,10 @@
 				RelativePath="..\CThreadHelper.cpp"
 				>
 			</File>
+			<File
+				RelativePath="..\hch\CVideoHandler.cpp"
+				>
+			</File>
 			<File
 				RelativePath=".\Graphics.cpp"
 				>
@@ -504,6 +508,10 @@
 				RelativePath="..\CThreadHelper.h"
 				>
 			</File>
+			<File
+				RelativePath="..\hch\CVideoHandler.h"
+				>
+			</File>
 			<File
 				RelativePath=".\FunctionList.h"
 				>

+ 15 - 5
hch/CLodHandler.cpp

@@ -343,7 +343,6 @@ int CLodHandler::readNormalNr (unsigned char* bufor, int bytCon, bool cyclic)
 void CLodHandler::init(std::string lodFile, std::string dirName)
 {
 	myDir = dirName;
-	mutex = new boost::mutex;
 	std::string Ts;
 	FLOD = fopen(lodFile.c_str(), "rb");
 	if(!FLOD)
@@ -359,15 +358,15 @@ void CLodHandler::init(std::string lodFile, std::string dirName)
 	for (int i=0; i<totalFiles; i++)
 	{
 		Entry entry;
-		char * bufc = new char;
+		char bufc = -1;
 		bool appending = true;
 		for(int kk=0; kk<12; ++kk)
 		{
 			//FLOD.read(bufc, 1);
-			fread(bufc, 1, 1, FLOD);
+			fread(&bufc, 1, 1, FLOD);
 			if(appending)
 			{
-				entry.name[kk] = toupper(*bufc);
+				entry.name[kk] = toupper(bufc);
 			}
 			else
 			{
@@ -375,7 +374,6 @@ void CLodHandler::init(std::string lodFile, std::string dirName)
 				appending = false;
 			}
 		}
-		delete bufc;
 		fread((char*)entry.hlam_1, 1, 4, FLOD);
 		fread((char*)temp, 1, 4, FLOD);
 		entry.offset=readNormalNr(temp,4);
@@ -435,3 +433,15 @@ std::string CLodHandler::getTextFile(std::string name)
 	delete [] data;
 	return ret;
 }
+
+CLodHandler::CLodHandler()
+{
+	mutex = new boost::mutex;
+	FLOD = NULL;
+	totalFiles = 0;
+}
+
+CLodHandler::~CLodHandler()
+{
+	delete mutex;
+}

+ 2 - 0
hch/CLodHandler.h

@@ -58,6 +58,8 @@ public:
 	boost::mutex *mutex;
 	std::string myDir; //load files from this dir instead of .lod file
 
+	CLodHandler();
+	~CLodHandler();
 	int readNormalNr (unsigned char* bufor, int bytCon, bool cyclic=false); //lod header reading helper
 	int infs(unsigned char * in, int size, int realSize, std::ofstream & out, int wBits=15); //zlib fast handler
 	int infs2(unsigned char * in, int size, int realSize, unsigned char*& out, int wBits=15); //zlib fast handler

+ 2 - 0
hch/CSpellHandler.cpp

@@ -66,6 +66,8 @@ namespace SRSLPraserHelpers
 			return std::make_pair(y%2 ? x-1 : x, y+1);
 		case 5: //left
 			return std::make_pair(x-1, y);
+		default:
+			throw std::string("Disaster: wrong direction in SRSLPraserHelpers::gotoDir!\n");
 		}
 	}
 

+ 113 - 243
hch/CVideoHandler.cpp

@@ -8,115 +8,74 @@
 
 #include "../client/SDL_Extensions.h"
 
+
+
 void DLLHandler::Instantiate(const char *filename)
 {
+	name = filename;
 #ifdef _WIN32
 	dll = LoadLibraryA(filename);
 #else
 	dll = dlopen(filename,RTLD_LOCAL | RTLD_LAZY);
 #endif
 }
-const char *DLLHandler::GetLibExtension()
-{
-#ifdef _WIN32
-	return "dll";
-#elif defined(__APPLE__)
-	return "dylib";
-#else
-	return "so";
-#endif
-}
-
 
-
-void *DLLHandler::FindAddress234(const char *symbol)
+void *DLLHandler::FindAddress(const char *symbol)
 {
 #ifdef _WIN32
-	if ((int)symbol == 0x00001758)
-		return NULL;
-	std::cout<<"co ja tu robie"<<std::endl;
 	return (void*) GetProcAddress(dll,symbol);
 #else
 	return (void *)dlsym(dll, symbol);
 #endif
 }
+
 DLLHandler::~DLLHandler()
 {
-#ifdef _WIN32
-	FreeLibrary(dll);
-#else
-	dlclose(dll);
-#endif
+	if(dll)
+	{
+	#ifdef _WIN32
+		FreeLibrary(dll);
+	#else
+		dlclose(dll);
+	#endif
+	}
 }
 
-
-CBIKHandler::CBIKHandler()
+DLLHandler::DLLHandler()
 {
-	ourLib.Instantiate("BINKW32.DLL");
-	newmode=-1;
-	waveOutOpen=0;
-	///waveOutOpen = ourLib.FindAddress("_BinkOpenWaveOut@4");
+	dll = NULL;
 }
-int readNormalNr2 (unsigned char* bufor, int &iter, int bytCon)
-{
-	int ret=0;
-	int amp=1;
-	for (int i=iter; i<iter+bytCon; i++)
-	{
-		ret+=bufor[i]*amp;
-		amp<<=8;
-	}
-	iter+=bytCon;
-	return ret;
-}
-void RaiseLastOSErrorAt(char * offset)
+
+
+void checkForError()
 {
 #ifdef _WIN32
-	int * lastError = new int;
-	std::exception * error;
-	*lastError = GetLastError();
-	if (*lastError)
-		throw lastError;
-#else
-	throw new std::exception();
+	int error = GetLastError();
+	if(error)
+		tlog1 << "Error " << error << " encountered!\n";
 #endif
 }
-//var
-//  LastError: Integer;
-//  Error: EOSError;
-//begin
-//  LastError := GetLastError;
-//  if LastError <> 0 then
-//    Error := EOSError.CreateResFmt(@SOSError, [LastError,
-//      SysErrorMessage(LastError)])
-//  else
-//    Error := EOSError.CreateRes(@SUnkOSError);
-//  Error.ErrorCode := LastError;
-//  raise Error at Offset;
-//end;
-//void RSRaiseLastOSError()
-//{
-//	__asm
-//	{
-//		mov eax, [esp]
-//		sub eax, 5
-//		jmp RaiseLastOSErrorAt
-//	}
-//}
-//int RSWin32Check(int CheckForZero)
-//{
-//	__asm
-//	{
-//		test eax, eax
-//		jz RSRaiseLastOSError
-//	}
-//}
+
+
+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");
+}
+
 void CBIKHandler::open(std::string name)
 {
-#ifdef _WIN32
-	hBinkFile = CreateFile
+	hBinkFile = CreateFileA
 	(
-		L"CSECRET.BIK",				// file name
+		name.c_str(),				// file name
 		GENERIC_READ,						// access mode
 		FILE_SHARE_READ,	// share mode
 		NULL,								// Security Descriptor
@@ -124,93 +83,58 @@ void CBIKHandler::open(std::string name)
 		FILE_ATTRIBUTE_NORMAL,//FILE_FLAG_SEQUENTIAL_SCAN,			// file attributes
 		0								// handle to template file
 	);
-	//RSWin32Check(hBinkFile!=INVALID_HANDLE_VALUE);
+
 	if(hBinkFile == INVALID_HANDLE_VALUE)
 	{
-		printf("failed to open \"%s\"\n", name.c_str());
+		checkForError();
 		return ;
 	}
 
+	void *waveout = FindAddress("_BinkOpenWaveOut@4");
+	if(waveout)
+		binkSetSoundSystem(waveout,NULL);
 
-	try
-	{
-		BinkGetError = ourLib.FindAddress234("_BinkGetError@0");
-		BinkOpen = ourLib.FindAddress234("_BinkOpen@8");
-		if (!waveOutOpen)
-		{
-			BinkSetSoundSystem = ourLib.FindAddress234("_BinkSetSoundSystem@8");
-			((void(*)(void*,void*))BinkSetSoundSystem)(waveOutOpen,NULL);
-		}
-		std::cout<<"punkt kulminacyjny... "<<std::flush;
-		hBink = ((HBINK(*)(HANDLE)) BinkOpen)(hBinkFile);
-		width = hBink->width;
-		height = hBink->height;
-		BITMAP gg;
-		gg.bmWidth=width;
-		gg.bmHeight=height;
-		gg.bmBitsPixel=24;
-		gg.bmPlanes=1;
-		gg.bmWidthBytes=3*width;
-		gg.bmBits = new unsigned char[width*height*(gg.bmBitsPixel/8)];
-
-		//HBITMAP bitmapa = CreateBitmap(width, height,1,24,NULL);
-		std::cout<<"przeszlo!"<<std::endl;
-	}
-	catch(...)
+	hBink = binkOpen(hBinkFile, 0x8a800000);
+	width = hBink->width;
+	height = hBink->height;
+	buffer = new char[width * height * 3];
+}
+
+void CBIKHandler::show( int x, int y, SDL_Surface *dst )
+{
+	int w = hBink->width, h = hBink->height;
+	//memset(buffer,0,w * h * 3);
+	binkDoFrame(hBink);
+	binkCopyToBuffer(hBink, buffer, w*3, h, 0, 0, 0);
+	char *src = buffer;
+	char *dest;
+	for(int i = h; i > 0; i--)
 	{
-		printf("cos nie tak");
+		dest = (char*)dst->pixels + dst->pitch*(h-i) + x*dst->format->BytesPerPixel;
+		memcpy(dest,src,3*w);
+		src += 3*w;
 	}
-#endif
+
+	SDL_UpdateRect(dst,x,y,hBink->width, hBink->height);
+}
+
+void CBIKHandler::nextFrame()
+{
+	binkNextFrame(hBink);
+}
+
+void CBIKHandler::close()
+{
+	delete [] buffer;
 }
 
-//void CBIKHandler::close()
-//{
-//	void *binkClose;
-//	binkClose = ourLib.FindAddress234("_BinkClose@4");
-//	(( void(*)() ) binkClose )();
-//
-//}
-//void CBIKHandler::preparePic()
-//procedure TRSBinkPlayer.PreparePic(b: TBitmap);
-//var j:int; Pal:array[0..256] of int;
-//begin
-//  inherited;
-//  case RSGetPixelFormat(b) of
-//    pf24bit, pf32bit, pf15bit, pf16bit:;
-//
-//    pf8bit:
-//    begin
-//      if @BinkGetPalette=nil then
-//        @BinkGetPalette:=GetProcAddress(FLib, '_BinkGetPalette@4');
-//      if @BinkGetPalette<>nil then
-//      begin
-//        with PLogPalette(@Pal)^ do
-//        begin
-//          palVersion:=$300;
-//          palNumEntries:=BinkGetPalette(@palPalEntry);
-//          for j:=0 to palNumEntries-1 do
-//            int(palPalEntry[j]):=RSSwapColor(int(palPalEntry[j]));
-//        end;
-//        b.Palette:=CreatePalette(PLogPalette(@Pal)^);
-//      end else
-//        b.PixelFormat:=pf24bit;
-//    end;
-//
-//    else
-//      b.PixelFormat:=pf24bit;
-//  end
-//
-//end;
-
-//////////SMK Player - Windows ///////////////////////////////////////////////////////
-
-void CRADPlayer::loadProc(char* ptrFunc,char* procName)
+bool CBIKHandler::wait()
 {
-	(FARPROC&)(*ptrFunc) =  GetProcAddress(hinstLib, procName);
+	return binkWait(hBink);
 }
 
 // Reference RSGrapics.RSGetPixelFormat
-PixelFormat CRADPlayer::getPixelFormat(TBitmap b)
+PixelFormat getPixelFormat(TBitmap &b)
 {
 	DIBSECTION DS;
 	DS.dsBmih.biBitCount = 2;
@@ -255,7 +179,7 @@ PixelFormat CRADPlayer::getPixelFormat(TBitmap b)
 	return result;
 }
 
-void CSmackPlayer::preparePic(TBitmap b)
+void CSmackPlayer::preparePic(TBitmap &b)
 {
 	switch (getPixelFormat(b))
 	{
@@ -270,87 +194,34 @@ void CSmackPlayer::preparePic(TBitmap b)
 
 void CSmackPlayer::nextFrame()
 {
-	loadProc((char*)&ptrSmackNextFrame, "_SmackNextFrame@4");
 	ptrSmackNextFrame(data);
 }
 
 
 bool CSmackPlayer::wait()
 {
-  loadProc((char*)&ptrSmackWait, "_SmackWait@4");
-  return ptrSmackWait(data);
+	return ptrSmackWait(data);
 }
 
-
-TBitmap CSmackPlayer::extractFrame(TBitmap b)
+void CSmackPlayer::init()
 {
-	int i,j;
-	PixelFormat pf;
-	TBitmap result;
-	loadProc((char*)&ptrSmackDoFrame, "_SmackDoFrame@4");
-	loadProc((char*)&ptrSmackToBuffer, "_SmackToBuffer@28");
-	i=j=0;
-	/*
-	try {
-		pf = getPixelFormat(b);
-		i=j=0;
-		switch(pf){
-			case pf8bit: i = 1; break;
-			case pf15bit:
-			case pf16bit: i=2; break;
-			default:
-				// assert(false)
-				break;
-		}
-		switch(pf) {
-			case pf8bit: 
-				j = 0x10000000;
-				break;
-			case pf15bit:
-				// todo
-				break;
-			case pf16bit:
-				// todo
-				break;
-			default:
-				break;
-		} */
-		int v = -b.width*i;
-		ptrSmackToBuffer(data, 0, 0, v, b.height, (char*)b.buffer, j);
-		ptrSmackDoFrame(data);
-		/*
-	}
-
-	catch ( char * msg) {
-
-	}*/
-  result = b;
-  return result;
-  
+	Instantiate("smackw32.dll");
+	tlog0 << "smackw32.dll loaded" << std::endl;
+
+	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");
+	tlog0 << "Functions located" << std::endl;
 }
 
 CVideoPlayer::CVideoPlayer()
-{
-	// Load DLL file
+{
 	vidh = new CVidHandler(std::string(DATA_DIR "Data" PATHSEPARATOR "VIDEO.VID"));
-
-	smkPlayer = new CSmackPlayer;
-
-    smkPlayer->hinstLib = LoadLibrary(L"smackw32.dll");
-    if (smkPlayer->hinstLib == NULL) {
-		tlog1<<"ERROR: unable to load DLL"<<std::endl;
-			getchar();
-            return;
-    }
-	tlog0<< "smackw32.dll Loaded"<<std::endl;
-	
-	smkPlayer->loadProc( (char*)&smkPlayer->ptrSmackOpen, "_SmackOpen@12");
-	smkPlayer->loadProc((char*)&smkPlayer->ptrSmackDoFrame, "_SmackDoFrame@4");
-	smkPlayer->loadProc((char*)&smkPlayer->ptrSmackToBuffer, "_SmackToBuffer@28");
-	smkPlayer->loadProc((char*)&smkPlayer->ptrSmackToBuffer, "_SmackToBuffer@28");
-	smkPlayer->loadProc((char*)&smkPlayer->ptrSmackSoundOnOff, "_SmackSoundOnOff@8");
-	smkPlayer->loadProc((char*)&smkPlayer->ptrSmackWait, "_SmackWait@4");
-	smkPlayer->loadProc((char*)&smkPlayer->ptrSmackNextFrame, "_SmackNextFrame@4");
+	smkPlayer = new CSmackPlayer;
+	smkPlayer->init();
 }
 
 CVideoPlayer::~CVideoPlayer()
@@ -378,7 +249,7 @@ bool CVideoPlayer::open(std::string fname, int x, int y)
 	}
 
 	buffer = new char[smkPlayer->data->width*smkPlayer->data->height*2];
-	buf = buffer+smkPlayer->data->width*(smkPlayer->data->height-1)*2;	// adjust pointer postition for later use by 'SmackToBuffer'
+	buf = buffer+smkPlayer->data->width*(smkPlayer->data->height-1)*2;	// adjust pointer position for later use by 'SmackToBuffer'
 
 	xPos = x;
 	yPos = y;
@@ -389,7 +260,7 @@ bool CVideoPlayer::open(std::string fname, int x, int y)
 
 void CVideoPlayer::close()
 {
-	delete buffer;
+	delete [] buffer;
 }
 
 bool CVideoPlayer::nextFrame()
@@ -405,36 +276,38 @@ bool CVideoPlayer::nextFrame()
 		// now bitmap is in buffer
 		// but I don't know exactly how to parse these 15bit color and draw it onto 16bit screen
 
+
+		/* Lock the screen for direct access to the pixels */
+		if ( SDL_MUSTLOCK(screen) ) 
+		{
+			if ( SDL_LockSurface(screen) < 0 ) 
+			{
+				fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
+				return 0;
+			}
+		}
+
 		// draw the frame!!
 		Uint16* addr = (Uint16*) (buffer+smkPlayer->data->width*(smkPlayer->data->height-1)*2-2);
 		for( int j=0; j<smkPlayer->data->height-1; j++)	// why -1 ?
+		{
 			for ( int i=smkPlayer->data->width-1; i>=0; i--)
 			{
 				Uint16 pixel = *addr;
 
 				Uint8 *p = (Uint8 *)screen->pixels + (j+yPos) * screen->pitch + (i + xPos) * screen->format->BytesPerPixel;
-
 				p[2] = ((pixel & 0x7c00) >> 10) * 8;
 				p[1] = ((pixel & 0x3e0) >> 5) * 8;
 				p[0] = ((pixel & 0x1F)) * 8;
 
-				/*Uint8 b = ((pixel & 0x7c00) >> 10) * 8;
-				Uint8 g = ((pixel & 0x3e0) >> 5) * 8;
-				Uint8 r = ((pixel & 0x1F)) * 8;*/
-
 				addr--;
-				/* Lock the screen for direct access to the pixels */
-				if ( SDL_MUSTLOCK(screen) ) {
-					if ( SDL_LockSurface(screen) < 0 ) {
-						fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
-						return 0;
-					}
-				}
-				//putpixel(screen, i,j, (Uint32)pixel);
-				if ( SDL_MUSTLOCK(screen) ) {
-					SDL_UnlockSurface(screen);
-				}
 			}
+		}
+
+		if ( SDL_MUSTLOCK(screen) ) 
+		{
+			SDL_UnlockSurface(screen);
+		}
 		/* Update just the part of the display that we've changed */
 		SDL_UpdateRect(screen, xPos, yPos, smkPlayer->data->width, smkPlayer->data->height);
 		SDL_Delay(50);
@@ -685,6 +558,3 @@ CVideoPlayer::~CVideoPlayer()
 }
 
 #endif
-
-
-

+ 87 - 158
hch/CVideoHandler.h

@@ -4,208 +4,131 @@
 
 #ifdef _WIN32
 
-#include <stdio.h>
 #include <windows.h>
-#include <SDL.h>
 
-//
-#define BINKNOTHREADEDIO 0x00800000
-//
-//  protected
-//    FLib: HINST;
-//    FLibName: string;
-//    FFileHandle: HFile;
-//    function GetCurrentFrame: int; virtual; abstract;
-//    function GetFramesCount: int; virtual; abstract;
-//    procedure SetCurrentFrame(v: int); virtual; abstract;
-//    procedure DoOpen(FileHandle: hFile); virtual; abstract;
-//    function NormalizeFrame(i:int):int;
-//    procedure SetPause(v:Boolean); virtual; abstract;
-//
-//    procedure LoadProc(var Proc:Pointer; const ProcName:string);
-//  public
-//    Width:pint;
-//    Height:pint;
-//    constructor Create(const LibName:string);
-//    destructor Destroy; override;
-//    procedure Open(FileHandle:hFile); overload;
-//    procedure Open(FileName:string); overload;
-////    procedure Open(FileData:TRSByteArray); overload;
-//    procedure SetVolume(i: int); virtual;
-//    procedure Close; virtual;
-//    procedure NextFrame; virtual; abstract;
-//    procedure PreparePic(b:TBitmap); virtual;
-//    procedure GotoFrame(Index:int; b:TBitmap); virtual;
-//    function ExtractFrame(b:TBitmap = nil):TBitmap; virtual; abstract;
-//    function Wait:Boolean; virtual; abstract;
-//      // Workaround for Bink and Smack thread synchronization bug
-//    property Frame: int read GetCurrentFrame write SetCurrentFrame;
-//    property FramesCount: int read GetFramesCount;
-//    property LibInstance: HINST read FLib;
-//    property Pause: Boolean write SetPause;
+struct SDL_Surface;
 
-  //TRSSmkStruct = packed record
-  //  Version: int;
-  //  Width: int;
-  //  Height: int;
-  //  FrameCount: int;
-  //  mspf: int;
-  //  Unk1: array[0..87] of byte;
-  //  Palette: array[0..775] of byte;
-  //  CurrentFrame: int; // Starting with 0
-  //   // 72 - Øèï
-  //   // 1060 - interesting
-  //   // 1100 - Mute:Bool
-  //end;
-
-  //TRSBinkStruct = packed record
-  //  Width: int;
-  //  Height: int;
-  //  FrameCount: int;
-  //  CurrentFrame: int; // Starting with 1
-  //  LastFrame: int;
-  //  FPSMul: int; // frames/second multiplier
-  //  FPSDiv: int; // frames/second divisor
-  //  Unk1: int;
-  //  Flags: int;
-  //  Unk2: array[0..259] of byte;
-  //  CurrentPlane: int;
-  //  Plane1: ptr;
-  //  Plane2: ptr;
-  //  Unk3: array[0..1] of int;
-  //  YPlaneWidth: int;
-  //  YPlaneHeight: int;
-  //  UVPlaneWidth: int;
-  //  UVPlaneHeight: int;
-  //end;
-typedef struct
-{
-	int width;
-	int height;
-	int frameCount;
-	int currentFrame;
-	int lastFrame;
-	int FPSMul;
-	int FPSDiv;
-	int unknown0;
-	unsigned char flags;
-	unsigned char unknown1[260];
-	int CurPlane;		// current plane
-	void *plane0;		// pointer to plane 0
-	void *plane1;		// pointer to plane 1
-	int unknown2;
-	int unknown3;
-	int yWidth;			// Y plane width
-	int yHeight;		// Y plane height
-	int uvWidth;		// U&V plane width
-	int uvHeight;		// U&V plane height
-	int d,e,f,g,h,i;
-} BINK_STRUCT, *HBINK;
-
-struct SMKStruct
+#pragma pack(push,1)
+struct BINK_STRUCT
 {
-	int version, width, height, frameCount, mspf, currentFrame;
-	unsigned char unk1[88], palette[776];
+	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:
-#if !defined(__amigaos4__) && !defined(__unix__) && !defined(__APPLE__)
+	std::string name;
 	HINSTANCE dll;
-#else
-	void *dll;
-#endif
 	void Instantiate(const char *filename);
 	const char *GetLibExtension();
-	void *FindAddress234(const char *symbol);
+	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 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);
+
 
-class CBIKHandler
+class CBIKHandler : public DLLHandler
 {
 public:
-	DLLHandler ourLib;
 	int newmode;
-#if !defined(__amigaos4__) && !defined(__unix__) && !defined(__APPLE__)
 	HANDLE hBinkFile;
-#else
-	void *hBinkFile;
-#endif
 	HBINK hBink;
-	BINK_STRUCT data;
-	unsigned char * buffer;
-	void * waveOutOpen, * BinkGetError, *BinkOpen, *BinkSetSoundSystem ;
+	char * buffer;
+	BinkSetSoundSystem binkSetSoundSystem;
+	BinkOpen binkOpen;
+	BinkGetPalette getPalette;
+	BinkNextFrame binkNextFrame;
+	BinkDoFrame binkDoFrame;
+	BinkCopyToBuffer binkCopyToBuffer;
+	BinkWait binkWait;
+
+	void * waveOutOpen, * binkGetError;
 
 	int width, height;
 
 	CBIKHandler();
 	void open(std::string name);
-	void close();
+	void close();
+	void nextFrame();
+	void show(int x, int y, SDL_Surface *dst);
+	bool wait();
 };
 
 //////////SMK Player ///////////////////////////////////////////////////////
-
 
-struct SmackStruct
+typedef enum { bmDIB, bmDDB} BitmapHandleType;
+typedef enum { pfDevice, pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, pf24bit, pf32bit, pfCustom} PixelFormat;
+typedef enum {tmAuto, tmFixed} TransparentMode;
+
+class TBitmap
 {
-    Sint32 version;		//
-    Sint32 width;
-    Sint32 height;
-    Sint32 frameCount;
-    Sint32 mspf;
-    unsigned char unk1[88];
-    unsigned char palette[776];
-    Sint32 currentFrame;	// Starting with 0
+public:
+	ui32	width;
+	ui32 height;
+	PixelFormat pixelFormat;
+	BitmapHandleType handleType;
+	char* buffer;
 
-     // 72 - Øè?
-     // 1060 - interesting
-     // 1100 - Mute:Bool
+};
 
-    unsigned char unk[56];
-    Uint32 fileHandle;  // exact type is HANDLE in windows.h
+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
 };
 
-// defines function pointer type
-typedef SmackStruct* (__stdcall*  SmackOpen)(void* , Uint32, Sint32 );
-// todo default value
+// defines function pointer types
+typedef SmackStruct* (__stdcall*  SmackOpen)(void* , ui32, si32 );
 typedef int (__stdcall* SmackDoFrame)( SmackStruct * );
 typedef void (__stdcall * SmackGoto )(SmackStruct *, int frameNumber);
 typedef void (__stdcall* SmackNextFrame)(SmackStruct*);
 typedef void (__stdcall* SmackClose)(SmackStruct*);
-typedef void (__stdcall* SmackToBuffer) (SmackStruct*, int, int, int, int, char *, Uint32);
+typedef void (__stdcall* SmackToBuffer) (SmackStruct*, int, int, int, int, char *, ui32);
 typedef bool (__stdcall* SmackWait)(SmackStruct*);
 typedef void (__stdcall* SmackSoundOnOff) (SmackStruct*, bool);
 
 
-typedef enum { bmDIB, bmDDB} BitmapHandleType;
-typedef enum { pfDevice, pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, pf24bit, pf32bit, pfCustom} PixelFormat;
-typedef enum {tmAuto, tmFixed} TransparentMode;
-
-class TBitmap
-{
-public:
-    Uint32	width;
-    Uint32 height;
-	PixelFormat pixelFormat;
-	BitmapHandleType handleType;
-	char* buffer;
-	
-};
 
-class CRADPlayer
+class CSmackPlayer: public DLLHandler
 {
-public:
-	HINSTANCE hinstLib;
-	void loadProc(char* ptrFunc,char* procName);
-	PixelFormat getPixelFormat(TBitmap);
-};
-
-class CSmackPlayer: public CRADPlayer{
 public:
 	SmackOpen ptrSmackOpen;
 	SmackDoFrame ptrSmackDoFrame;
@@ -215,8 +138,9 @@ public:
 	SmackSoundOnOff ptrSmackSoundOnOff;
 	SmackStruct* data;
 
-	void preparePic(TBitmap b);
-	TBitmap extractFrame(TBitmap b);
+	void init();
+	void preparePic(TBitmap &b);
+	TBitmap extractFrame(TBitmap &b);
 	void nextFrame();
 	bool wait();
 };
@@ -228,10 +152,15 @@ class CVideoPlayer
 private:
 	CVidHandler * vidh; //.vid file handling
 	CSmackPlayer * smkPlayer;
+
 	int frame;
 	int xPos, yPos;
 	char * buffer;
 	char * buf;
+
+
+	std::string fname; //name of current video file (empty if idle)
+
 public:
 	CVideoPlayer(); //c-tor
 	~CVideoPlayer(); //d-tor

+ 19 - 5
lib/VCMI_Lib.cpp

@@ -166,11 +166,6 @@ DLL_EXPORT void loadToIt(si32 &dest, std::string &src, int &iter, int mode)
 void LibClasses::init()
 {
 	timeHandler pomtime;
-	spriteh = new CLodHandler();
-	spriteh->init("Data" PATHSEPARATOR "H3sprite.lod","Sprites");
-	bitmaph = new CLodHandler;
-	bitmaph->init("Data" PATHSEPARATOR "H3bitmap.lod","Data");
-	tlog0<<"Loading .lod files: "<<pomtime.getDif()<<std::endl;
 
 	generaltexth = new CGeneralTextHandler;
 	generaltexth->load();
@@ -221,6 +216,11 @@ void LibClasses::clear()
 	delete dobjinfo;
 	delete buildh;
 	delete spellh;
+	makeNull();
+}
+
+void LibClasses::makeNull()
+{
 	generaltexth = NULL;
 	heroh = NULL;
 	arth = NULL;
@@ -231,3 +231,17 @@ void LibClasses::clear()
 	buildh = NULL;
 	spellh = NULL;
 }
+
+LibClasses::LibClasses()
+{
+	//load .lod archives
+	timeHandler pomtime;
+	spriteh = new CLodHandler();
+	spriteh->init("Data" PATHSEPARATOR "H3sprite.lod","Sprites");
+	bitmaph = new CLodHandler;
+	bitmaph->init("Data" PATHSEPARATOR "H3bitmap.lod","Data");
+	tlog0<<"Loading .lod files: "<<pomtime.getDif()<<std::endl;
+
+	//init pointers to handlers
+	makeNull();
+}

+ 2 - 1
lib/VCMI_Lib.h

@@ -44,10 +44,11 @@ public:
 	CDefObjInfoHandler * dobjinfo;
 	CTownHandler * townh;
 	CGeneralTextHandler * generaltexth;
-	//CPathfinder * pathf;
 
+	LibClasses(); //c-tor, loads .lods and NULLs handlers
 	void init(); //uses standard config file
 	void clear(); //deletes all handlers and its data
+	void makeNull(); //sets all handler (except of lodhs) pointers to null
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{