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

Prawie działający CLodHandler - z moich testów wynika, że ma tylko problemy z wydajnością (nie wiem, ile tu można zrobić, być może i dużo) oraz z obrazkami (coś dziwnego z nimi zrobiono...). Wszystko powinno dobrze działać (pamiętaj o dostarczeniu odpowiednich plików i stworzenie folderów: po jednym dla każdego rozpakowywanego loda, o nazwie będącej nazwą tego loda bez rozszerzenia, plus jeden dodatkowy dla rozpakowywacza o nazwie lodbuf)

This commit is contained in:
mateuszb 2007-06-30 16:24:05 +00:00
parent eabac43509
commit b3e892a989
7 changed files with 296 additions and 107 deletions

1
CDefHandler.cpp Normal file
View File

@ -0,0 +1 @@
#include "CDefHandler.h"

10
CDefHandler.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef CDEFHANDLER_H
#define CDEFHANDLER_H
class CDefHandler
{
};
#endif //CDEFHANDLER_H

216
CLodHandler.cpp Normal file
View File

@ -0,0 +1,216 @@
#include "CLodHandler.h"
#include "stdafx.h"
int CLodHandler::decompress (unsigned char * source, int size, int realSize, std::ofstream & dest)
{
std::ofstream lb;
lb.open("lodbuf\\buf.gz", std::ios::out|std::ios::binary);
for(int i=0; i<size; ++i)
{
lb<<source[i];
}
lb.close();
FILE * inputf = fopen("lodbuf\\buf.gz", "rb+");
FILE * outputf = fopen("lodbuf\\buf.un", "wb+");
int ret = infm(inputf, outputf);
fclose(inputf);
fclose(outputf);
return ret;
}
int CLodHandler::decompress (unsigned char * source, int size, int realSize, std::string & dest)
{
std::ofstream lb;
lb.open("lodbuf\\buf.gz", std::ios::out|std::ios::binary);
for(int i=0; i<size; ++i)
{
lb<<source[i];
}
lb.close();
FILE * inputf = fopen("lodbuf\\buf.gz", "rb+");
FILE * outputf = fopen(dest.c_str(), "wb+");
int ret = infm(inputf, outputf);
fclose(inputf);
fclose(outputf);
return ret;
}
int CLodHandler::infm(FILE *source, FILE *dest, int wBits)
{
int ret;
unsigned have;
z_stream strm;
unsigned char in[NLoadHandlerHelp::fCHUNK];
unsigned char out[NLoadHandlerHelp::fCHUNK];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm, wBits);
if (ret != Z_OK)
return ret;
/* decompress until deflate stream ends or end of file */
do
{
strm.avail_in = fread(in, 1, NLoadHandlerHelp::fCHUNK, source);
if (ferror(source)) {
(void)inflateEnd(&strm);
return Z_ERRNO;
}
if (strm.avail_in == 0)
break;
strm.next_in = in;
/* run inflate() on input until output buffer not full */
do
{
strm.avail_out = NLoadHandlerHelp::fCHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
//assert(ret != Z_STREAM_ERROR); /* state not clobbered */
switch (ret)
{
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return ret;
}
have = NLoadHandlerHelp::fCHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest))
{
(void)inflateEnd(&strm);
return Z_ERRNO;
}
} while (strm.avail_out == 0);
/* done when inflate() says it's done */
} while (ret != Z_STREAM_END);
/* clean up and return */
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
void CLodHandler::extract(std::string FName)
{
std::ifstream FLOD;
std::ofstream FOut;
int i;
std::string Ts;
//std::cout<<"*** Loading FAT ... \n";
FLOD.open(FName.c_str(),std::ios::binary);
//std::cout<<"*** Archive: "+FName+" loaded\n";
FLOD.seekg(8,std::ios_base::beg);
unsigned char temp[4];
FLOD.read((char*)temp,4);
totalFiles = readNormalNr(temp,4);
FLOD.seekg(0x5c,std::ios_base::beg);
entries.reserve(totalFiles);
//std::cout<<"*** Loading FAT ...\n";
for (int i=0; i<totalFiles; i++)
{
entries.push_back(Entry());
//FLOD.read((char*)entries[i].name,12);
char * bufc = new char;
bool appending = true;
for(int kk=0; kk<12; ++kk)
{
FLOD.read(bufc, 1);
if(appending)
{
entries[i].name[kk] = *bufc;
}
else
{
entries[i].name[kk] = 0;
appending = false;
}
}
delete bufc;
FLOD.read((char*)entries[i].hlam_1,4);
FLOD.read((char*)temp,4);
entries[i].offset=readNormalNr(temp,4);
FLOD.read((char*)temp,4);
entries[i].realSize=readNormalNr(temp,4);
FLOD.read((char*)entries[i].hlam_2,4);
FLOD.read((char*)temp,4);
entries[i].size=readNormalNr(temp,4);
}
//std::cout<<" done\n";
for (int i=0;i<totalFiles;i++)
{
FLOD.seekg(entries[i].offset,std::ios_base::beg);
std::string bufff = (FName.substr(0, FName.size()-4) + "\\" + (char*)entries[i].name);
unsigned char * outp;
if (entries[i].size==0) //file is not compressed
{
outp = new unsigned char[entries[i].realSize];
FLOD.read((char*)outp, entries[i].realSize);
std::ofstream out;
out.open(bufff.c_str(), std::ios::binary);
if(!out.is_open())
{
std::cout<<"Unable to create "<<bufff;
}
else
{
for(int hh=0; hh<entries[i].realSize; ++hh)
{
out<<*(outp+hh);
}
out.close();
}
}
else
{
outp = new unsigned char[entries[i].size];
FLOD.read((char*)outp, entries[i].size);
FLOD.seekg(0, std::ios_base::beg);
int decRes = decompress(outp, entries[i].size, entries[i].realSize, bufff);
if(decRes!=0)
{
std::cout<<"LOD Extraction error"<<" "<<decRes<<" while extracting to "<<bufff<<std::endl;
}
}
//for (int j=0; j<entries[i].size; j++)
// FOut << outp[j];
//FOut.flush();
delete outp;
//FOut.close();
//std::cout<<"*** done\n";
}
FLOD.close();
//std::cout<<"*** Archive: "+FName+" closed\n";
}
int CLodHandler::readNormalNr (unsigned char* bufor, int bytCon, bool cyclic)
{
int ret=0;
int amp=1;
for (int i=0; i<bytCon; i++)
{
ret+=bufor[i]*amp;
amp*=256;
}
if(cyclic && bytCon<4 && ret>=amp/2)
{
ret = ret-amp;
}
return ret;
}
void CLodHandler::init(std::string lodFile)
{
extract(lodFile);
}

42
CLodHandler.h Normal file
View File

@ -0,0 +1,42 @@
#ifndef CLODHANDLER_H
#define CLODHANDLER_H
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include "zlib.h"
namespace NLoadHandlerHelp
{
const int dmHelp=0, dmNoExtractingMask=1;
//std::string P1,P2,CurDir;
const int fCHUNK = 50000;
};
struct Entry
{
unsigned char name[12], //filename
hlam_1[4], //
hlam_2[4]; //
int offset, //from beginning
realSize, //size without compression
size; //and with
};
class CLodHandler
{
public:
std::vector<Entry> entries;
unsigned int totalFiles;
int readNormalNr (unsigned char* bufor, int bytCon, bool cyclic=false); //lod header reading helper
int decompress (unsigned char * source, int size, int realSize, std::ofstream & dest); //main decompression function
int decompress (unsigned char * source, int size, int realSize, std::string & dest); //main decompression function
int infm(FILE *source, FILE *dest, int wBits = 15); //zlib handler
void extract(std::string FName);
void init(std::string lodFile);
};
#endif //CLODHANDLER_H

20
CMT.cpp
View File

@ -25,6 +25,7 @@
#include "CGameInfo.h"
#include "CMusicHandler.h"
#include "CSemiLodHandler.h"
#include "CLodHandler.h"
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
# include <fcntl.h>
# include <io.h>
@ -262,6 +263,20 @@ int _tmain(int argc, _TCHAR* argv[])
CGameInfo * cgi = new CGameInfo;
CGameInfo::mainObj = cgi;
cgi->mush = mush;
//////////////////////////////////////////////////////////////////////////////// lod testing
//CLodHandler * clod = new CLodHandler;
//clod->loadLod("h3abp_bm.lod");
CLodHandler * test = new CLodHandler;
test->init(std::string("h3abp_bm.lod"));
CLodHandler * bitmapLod = new CLodHandler;
test->init(std::string("newH3sprite.lod"));
//////////////////////////////////////////////////////////////////////////////// lod testing end
cgi->sspriteh = new CSemiLodHandler();
cgi->sspriteh->openLod("H3sprite.lod");
CArtHandler * arth = new CArtHandler;
@ -286,8 +301,9 @@ int _tmain(int argc, _TCHAR* argv[])
objh->loadObjects();
cgi->objh = objh;
std::string mapname;
if (CPG) mapname = CPG->ourScenSel->mapsel.ourMaps[CPG->ourScenSel->mapsel.selected].filename;
else mapname = "4gryf";
//if (CPG) mapname = CPG->ourScenSel->mapsel.ourMaps[CPG->ourScenSel->mapsel.selected].filename;
//else mapname = "4gryf";
mapname = "4gryf";
CAmbarCendamo * ac = new CAmbarCendamo(mapname.c_str()); //4gryf
CMapHeader * mmhh = new CMapHeader(ac->bufor); //czytanie nag³ówka
cgi->ac = ac;

View File

@ -1,101 +0,0 @@
//TSearchRec
#include <iostream>
#include <fstream>
#include <vector>
const int dmHelp=0, dmNoExtractingMask=1;
std::string P1,P2,CurDir;
struct TSearchRec
{
}sr;
struct Entry
{
unsigned char name[12], //filename
hlam_1[4], //
hlam_2[4]; //
int offset, //from beginning
realSize, //size without compression
size; //and with
} ;
std::vector<Entry> Entries;
long TotalFiles;
int readNormalNr (unsigned char* bufor, int bytCon, bool cyclic=false)
{
int ret=0;
int amp=1;
for (int i=0; i<bytCon; i++)
{
ret+=bufor[i]*amp;
amp*=256;
}
if(cyclic && bytCon<4 && ret>=amp/2)
{
ret = ret-amp;
}
return ret;
}
int Decompress (unsigned char * source, int size, int realSize, std::ofstream & dest);
void Extract(std::string FName)
{
std::ifstream FLOD;
std::ofstream FOut;
long i;
std::string Ts;
std::cout<<"*** Loading FAT ... \n";
FLOD.open(FName.c_str(),std::ios::binary);
std::cout<<"*** Archive: "+FName+" loaded\n";
FLOD.seekg(8,std::ios_base::beg);
unsigned char temp[4];
FLOD.read((char*)temp,4);
TotalFiles = readNormalNr(temp,4);
FLOD.seekg(0x5c,std::ios_base::beg);
Entries.reserve(TotalFiles);
std::cout<<"*** Loading FAT ...\n";
for (int i=0;i<TotalFiles;i++)
{
Entries.push_back(Entry());
FLOD.read((char*)Entries[i].name,12);
FLOD.read((char*)Entries[i].hlam_1,4);
FLOD.read((char*)temp,4);
Entries[i].offset=readNormalNr(temp,4);
FLOD.read((char*)temp,4);
Entries[i].realSize=readNormalNr(temp,4);
FLOD.read((char*)Entries[i].hlam_2,4);
FLOD.read((char*)temp,4);
Entries[i].size=readNormalNr(temp,4);
}
std::cout<<" done\n";
if (TotalFiles>6) TotalFiles=6;
for (int i=0;i<TotalFiles;i++)
{
FLOD.seekg(Entries[i].offset,std::ios_base::beg);
FOut.open((char*)Entries[i].name,std::ios_base::binary);
unsigned char* outp ;
if (Entries[i].size==0)
{
outp = new unsigned char[Entries[i].realSize];
FLOD.read((char*)outp,Entries[i].realSize);
}
else
{
outp = new unsigned char[Entries[i].size];
//unsigned char * outd = new unsigned char[Entries[i].realSize];
FLOD.read((char*)outp,Entries[i].size);
FLOD.seekg(0,std::ios_base::beg);
//Decompress(outp,Entries[i].size,Entries[i].realSize,FOut);
}
for (int j=0;j<Entries[i].size;j++)
FOut << outp[j];
FOut.flush();
delete outp;
FOut.close();
std::cout<<"*** done\n";
}
FLOD.close();
std::cout<<"*** Archive: "+FName+" closed\n";
}
int Decompress (unsigned char * source, int size, int realSize, std::ofstream & dest)
{
return -1;
}

View File

@ -1,7 +1,12 @@
#ifndef _NODRZE_H
#define _NODRZE_H
#include <iostream>
#include <string>
#define LOGUJ ;
#define CLOG ;
#ifndef LOGUJ
#define LOGUJ(a) (std::cout<<a)
#define CLOG(a) (std::cout<<a)
@ -599,7 +604,7 @@ template <typename T> wezel<T> * nodrze<T>::usunRBT (wezel<T> * nowy)
};
template <typename T> void nodrze<T>::naprawWstaw (wezel<T> * nowy)
{
CLOG ("Naprawiam po wstawieniu"<<std::endl);
//CLOG ("Naprawiam po wstawieniu"<<std::endl);
while (nowy->ojciec->kolor==CZERWONY)
{
if (nowy->ojciec == nowy->ojciec->ojciec->lewy) // ojciec nowego lest lewy
@ -651,7 +656,7 @@ template <typename T> void nodrze<T>::naprawWstaw (wezel<T> * nowy)
}
template <typename T> void nodrze<T>::dodajRBT (wezel<T> * nowy)
{
CLOG("Dodaje do drzewa "<<nowy->zawart<<std::endl);
//CLOG("Dodaje do drzewa "<<nowy->zawart<<std::endl);
ile++;
if ((*nowy->zawart) < (*ostatnio->zawart))
{
@ -717,7 +722,7 @@ template <typename T> bool nodrze<T>::sprawdzW(wezel<T> * w)
}
template <typename T> void nodrze<T>::rotacjaLewa (wezel<T> * x)
{
CLOG("Wykonuje lewš rotację na "<<x->zawart<<std::endl);
//CLOG("Wykonuje lew¹ rotacjê na "<<x->zawart<<std::endl);
wezel<T> * y = x->prawy;
x->prawy = y->lewy; // zamiana lewego poddrzewa y na prawe poddrzewo x
if (y->lewy != NIL) y->lewy->ojciec = x; // i przypisanie ojcostwa temu poddrzewu
@ -733,7 +738,7 @@ template <typename T> void nodrze<T>::rotacjaLewa (wezel<T> * x)
};
template <typename T> void nodrze<T>::rotacjaPrawa (wezel<T> * y)
{
CLOG("Wykonuje prawa rotację na "<<y->zawart<<std::endl);
//CLOG("Wykonuje prawa rotacjê na "<<y->zawart<<std::endl);
wezel<T> * x = y->lewy;
y->lewy = x->prawy; // zamiana prawe poddrzewa x na lewe poddrzewo y
if (x->prawy != NIL) x->prawy->ojciec = y; // i przypisanie ojcostwa temu poddrzewu