1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-30 08:57:00 +02:00

Mostly done .BIK video handling (WIN only).

Refactoring.
This commit is contained in:
Michał W. Urbańczyk 2009-06-23 08:14:49 +00:00
parent 191aebed58
commit 9ff6501ba3
15 changed files with 332 additions and 489 deletions

View File

@ -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));
}

View File

@ -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);

View File

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

View File

@ -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

View File

@ -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];

View File

@ -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;

View File

@ -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)

View File

@ -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"
>

View File

@ -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;
}

View File

@ -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

View File

@ -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");
}
}

View File

@ -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()
void *DLLHandler::FindAddress(const char *symbol)
{
#ifdef _WIN32
return "dll";
#elif defined(__APPLE__)
return "dylib";
#else
return "so";
#endif
}
void *DLLHandler::FindAddress234(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
if(dll)
{
#ifdef _WIN32
FreeLibrary(dll);
#else
#else
dlclose(dll);
#endif
}
}
DLLHandler::DLLHandler()
{
dll = NULL;
}
void checkForError()
{
#ifdef _WIN32
int error = GetLastError();
if(error)
tlog1 << "Error " << error << " encountered!\n";
#endif
}
CBIKHandler::CBIKHandler()
{
ourLib.Instantiate("BINKW32.DLL");
newmode=-1;
waveOutOpen=0;
///waveOutOpen = ourLib.FindAddress("_BinkOpenWaveOut@4");
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");
}
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)
{
#ifdef _WIN32
int * lastError = new int;
std::exception * error;
*lastError = GetLastError();
if (*lastError)
throw lastError;
#else
throw new std::exception();
#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
// }
//}
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);
hBink = binkOpen(hBinkFile, 0x8a800000);
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(...)
{
printf("cos nie tak");
}
#endif
buffer = new char[width * height * 3];
}
//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)
void CBIKHandler::show( int x, int y, SDL_Surface *dst )
{
(FARPROC&)(*ptrFunc) = GetProcAddress(hinstLib, procName);
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--)
{
dest = (char*)dst->pixels + dst->pitch*(h-i) + x*dst->format->BytesPerPixel;
memcpy(dest,src,3*w);
src += 3*w;
}
SDL_UpdateRect(dst,x,y,hBink->width, hBink->height);
}
void CBIKHandler::nextFrame()
{
binkNextFrame(hBink);
}
void CBIKHandler::close()
{
delete [] buffer;
}
bool CBIKHandler::wait()
{
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);
}
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->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) ) {
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

View File

@ -4,184 +4,88 @@
#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
#pragma pack(push,1)
struct BINK_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
{
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
};
class CBIKHandler
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 : 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 nextFrame();
void show(int x, int y, SDL_Surface *dst);
bool wait();
};
//////////SMK Player ///////////////////////////////////////////////////////
struct SmackStruct
{
Sint32 version; //
Sint32 width;
Sint32 height;
Sint32 frameCount;
Sint32 mspf;
unsigned char unk1[88];
unsigned char palette[776];
Sint32 currentFrame; // Starting with 0
// 72 - Øè?
// 1060 - interesting
// 1100 - Mute:Bool
unsigned char unk[56];
Uint32 fileHandle; // exact type is HANDLE in windows.h
};
// defines function pointer type
typedef SmackStruct* (__stdcall* SmackOpen)(void* , Uint32, Sint32 );
// todo default value
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 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;
@ -189,23 +93,42 @@ typedef enum {tmAuto, tmFixed} TransparentMode;
class TBitmap
{
public:
Uint32 width;
Uint32 height;
ui32 width;
ui32 height;
PixelFormat pixelFormat;
BitmapHandleType handleType;
char* buffer;
};
class CRADPlayer
struct SmackStruct
{
public:
HINSTANCE hinstLib;
void loadProc(char* ptrFunc,char* procName);
PixelFormat getPixelFormat(TBitmap);
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
};
class CSmackPlayer: public CRADPlayer{
// 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 *, ui32);
typedef bool (__stdcall* SmackWait)(SmackStruct*);
typedef void (__stdcall* SmackSoundOnOff) (SmackStruct*, bool);
class CSmackPlayer: public DLLHandler
{
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

View File

@ -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();
}

View File

@ -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)
{