| 
									
										
										
										
											2008-06-12 06:45:51 +00:00
										 |  |  | #define VCMI_DLL
 | 
					
						
							| 
									
										
										
										
											2008-01-09 17:21:31 +00:00
										 |  |  | #include "../stdafx.h"
 | 
					
						
							| 
									
										
										
										
											2008-06-12 06:45:51 +00:00
										 |  |  | #include "zlib.h"
 | 
					
						
							| 
									
										
										
										
											2007-07-01 12:54:59 +00:00
										 |  |  | #include "CLodHandler.h"
 | 
					
						
							|  |  |  | #include <sstream>
 | 
					
						
							| 
									
										
										
										
											2007-07-07 11:09:25 +00:00
										 |  |  | #include <algorithm>
 | 
					
						
							| 
									
										
										
										
											2007-07-17 20:51:49 +00:00
										 |  |  | #include <cctype>
 | 
					
						
							| 
									
										
										
										
											2007-07-07 11:09:25 +00:00
										 |  |  | #include <cstring>
 | 
					
						
							| 
									
										
										
										
											2009-10-10 23:25:34 +00:00
										 |  |  | #include <iostream>
 | 
					
						
							|  |  |  | #include <fstream>
 | 
					
						
							| 
									
										
										
										
											2008-06-14 10:20:18 +00:00
										 |  |  | #include "boost/filesystem/operations.hpp"
 | 
					
						
							|  |  |  | #include <boost/algorithm/string.hpp>
 | 
					
						
							|  |  |  | #include <boost/algorithm/string/replace.hpp>
 | 
					
						
							| 
									
										
										
										
											2008-06-16 10:51:14 +00:00
										 |  |  | #include <boost/thread.hpp>
 | 
					
						
							| 
									
										
										
										
											2009-10-10 23:25:34 +00:00
										 |  |  | #include <SDL_endian.h>
 | 
					
						
							| 
									
										
										
										
											2008-12-07 22:38:04 +00:00
										 |  |  | #ifdef max
 | 
					
						
							|  |  |  | #undef max
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-04-15 14:03:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * CLodHandler.cpp, part of VCMI engine | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Authors: listed in file AUTHORS in main folder | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * License: GNU General Public License v2.0 or later | 
					
						
							|  |  |  |  * Full text of license available in license.txt file, in main folder | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-09 13:48:14 +00:00
										 |  |  | int readNormalNr (const unsigned char * bufor, int pos, int bytCon, bool cyclic) | 
					
						
							| 
									
										
										
										
											2007-07-01 12:54:59 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int ret=0; | 
					
						
							|  |  |  | 	int amp=1; | 
					
						
							| 
									
										
										
										
											2010-02-09 13:48:14 +00:00
										 |  |  | 	for (int ir=0; ir<bytCon; ir++) | 
					
						
							| 
									
										
										
										
											2007-07-01 12:54:59 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-02-09 13:48:14 +00:00
										 |  |  | 		ret+=bufor[pos+ir]*amp; | 
					
						
							|  |  |  | 		amp*=256; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(cyclic && bytCon<4 && ret>=amp/2) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		ret = ret-amp; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char readChar(const unsigned char * bufor, int &i) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return bufor[i++]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::string readString(const unsigned char * bufor, int &i) | 
					
						
							|  |  |  | {					 | 
					
						
							|  |  |  | 	int len = readNormalNr(bufor,i); i+=4; | 
					
						
							|  |  |  | 	std::string ret; ret.reserve(len); | 
					
						
							|  |  |  | 	for(int gg=0; gg<len; ++gg) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		ret += bufor[i++]; | 
					
						
							| 
									
										
										
										
											2007-07-01 12:54:59 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-10-10 23:25:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-12 21:08:04 +00:00
										 |  |  | unsigned char * CLodHandler::giveFile(std::string defName, int * length) | 
					
						
							| 
									
										
										
										
											2007-07-09 05:57:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-07-31 13:09:34 +00:00
										 |  |  | 	std::transform(defName.begin(), defName.end(), defName.begin(), (int(*)(int))toupper); | 
					
						
							| 
									
										
										
										
											2007-07-17 20:51:49 +00:00
										 |  |  | 	Entry * ourEntry = entries.znajdz(Entry(defName)); | 
					
						
							| 
									
										
										
										
											2008-03-03 19:41:10 +00:00
										 |  |  | 	if(!ourEntry) //nothing's been found
 | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-10-05 01:47:48 +00:00
										 |  |  | 		tlog1 << "Cannot find file: " << defName << std::endl; | 
					
						
							| 
									
										
										
										
											2008-06-12 06:45:51 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2008-03-03 19:41:10 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-06-12 06:45:51 +00:00
										 |  |  | 	if(length) *length = ourEntry->realSize; | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 	mutex->lock(); | 
					
						
							| 
									
										
										
										
											2009-10-10 23:25:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-07-17 20:51:49 +00:00
										 |  |  | 	unsigned char * outp; | 
					
						
							| 
									
										
										
										
											2008-06-12 06:45:51 +00:00
										 |  |  | 	if (ourEntry->offset<0) //file is in the sprites/ folder; no compression
 | 
					
						
							| 
									
										
										
										
											2008-02-24 23:06:27 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-10-05 01:47:48 +00:00
										 |  |  | 		int result; | 
					
						
							| 
									
										
										
										
											2008-06-12 06:45:51 +00:00
										 |  |  | 		unsigned char * outp = new unsigned char[ourEntry->realSize]; | 
					
						
							| 
									
										
										
										
											2009-10-05 01:47:48 +00:00
										 |  |  | 		FILE * f = fopen((myDir + "/" + ourEntry->nameStr).c_str(), "rb"); | 
					
						
							|  |  |  | 		if (f) { | 
					
						
							|  |  |  | 			result = fread(outp,1,ourEntry->realSize,f); | 
					
						
							|  |  |  | 			fclose(f); | 
					
						
							|  |  |  | 		} else | 
					
						
							|  |  |  | 			result = -1; | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 		mutex->unlock(); | 
					
						
							| 
									
										
										
										
											2009-10-05 01:47:48 +00:00
										 |  |  | 		if(result<0) { | 
					
						
							|  |  |  | 			tlog1<<"Error in file reading: " << myDir << "/" << ourEntry->nameStr << std::endl; | 
					
						
							|  |  |  | 			delete[] outp; | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} else | 
					
						
							| 
									
										
										
										
											2008-06-12 06:45:51 +00:00
										 |  |  | 			return outp; | 
					
						
							| 
									
										
										
										
											2008-02-24 23:06:27 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 	else if (ourEntry->size==0) //file is not compressed
 | 
					
						
							| 
									
										
										
										
											2007-07-17 20:51:49 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		outp = new unsigned char[ourEntry->realSize]; | 
					
						
							| 
									
										
										
										
											2009-10-10 23:25:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		LOD.seekg(ourEntry->offset, std::ios::beg); | 
					
						
							|  |  |  | 		LOD.read((char*)outp, ourEntry->realSize); | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 		mutex->unlock(); | 
					
						
							| 
									
										
										
										
											2008-06-12 06:45:51 +00:00
										 |  |  | 		return outp; | 
					
						
							| 
									
										
										
										
											2007-07-17 20:51:49 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 	else //we will decompress file
 | 
					
						
							| 
									
										
										
										
											2007-07-17 20:51:49 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 		outp = new unsigned char[ourEntry->size]; | 
					
						
							| 
									
										
										
										
											2009-10-10 23:25:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		LOD.seekg(ourEntry->offset, std::ios::beg); | 
					
						
							|  |  |  | 		LOD.read((char*)outp, ourEntry->size); | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 		mutex->unlock(); | 
					
						
							| 
									
										
										
										
											2007-07-17 20:51:49 +00:00
										 |  |  | 		unsigned char * decomp = NULL; | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 		int decRes = infs2(outp, ourEntry->size, ourEntry->realSize, decomp); | 
					
						
							|  |  |  | 		delete[] outp; | 
					
						
							| 
									
										
										
										
											2008-06-12 06:45:51 +00:00
										 |  |  | 		return decomp; | 
					
						
							| 
									
										
										
										
											2007-07-17 20:51:49 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-06-12 06:45:51 +00:00
										 |  |  | 	return NULL; | 
					
						
							| 
									
										
										
										
											2007-10-16 22:39:11 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-10-10 23:25:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | DLL_EXPORT int CLodHandler::infs2(unsigned char * in, int size, int realSize, unsigned char *& out, int wBits) | 
					
						
							| 
									
										
										
										
											2007-07-07 11:09:25 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int ret; | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 	unsigned have; | 
					
						
							| 
									
										
										
										
											2007-07-07 11:09:25 +00:00
										 |  |  | 	z_stream strm; | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 	out = new unsigned char [realSize]; | 
					
						
							|  |  |  | 	int latPosOut = 0; | 
					
						
							| 
									
										
										
										
											2007-07-07 11:09:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* allocate inflate state */ | 
					
						
							|  |  |  | 	strm.zalloc = Z_NULL; | 
					
						
							|  |  |  | 	strm.zfree = Z_NULL; | 
					
						
							|  |  |  | 	strm.opaque = Z_NULL; | 
					
						
							|  |  |  | 	strm.avail_in = 0; | 
					
						
							|  |  |  | 	strm.next_in = Z_NULL; | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 	ret = inflateInit2(&strm, wBits); | 
					
						
							| 
									
										
										
										
											2007-07-07 11:09:25 +00:00
										 |  |  | 	if (ret != Z_OK) | 
					
						
							|  |  |  | 		return ret; | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 	int chunkNumber = 0; | 
					
						
							|  |  |  | 	do | 
					
						
							| 
									
										
										
										
											2007-07-07 11:09:25 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-09-27 11:37:15 +00:00
										 |  |  | 		if(size < chunkNumber * NLoadHandlerHelp::fCHUNK) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		strm.avail_in = std::min(NLoadHandlerHelp::fCHUNK, size - chunkNumber * NLoadHandlerHelp::fCHUNK); | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 		if (strm.avail_in == 0) | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2009-09-27 11:37:15 +00:00
										 |  |  | 		strm.next_in = in + chunkNumber * NLoadHandlerHelp::fCHUNK; | 
					
						
							| 
									
										
										
										
											2007-07-07 11:09:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 		/* run inflate() on input until output buffer not full */ | 
					
						
							|  |  |  | 		do | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2009-09-27 11:37:15 +00:00
										 |  |  | 			strm.avail_out = realSize - latPosOut; | 
					
						
							|  |  |  | 			strm.next_out = out + latPosOut; | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 			ret = inflate(&strm, Z_NO_FLUSH); | 
					
						
							|  |  |  | 			//assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
 | 
					
						
							| 
									
										
										
										
											2009-09-27 11:37:15 +00:00
										 |  |  | 			bool breakLoop = false; | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 			switch (ret) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2009-09-27 11:37:15 +00:00
										 |  |  | 			case Z_STREAM_END: | 
					
						
							|  |  |  | 				breakLoop = true; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case Z_NEED_DICT: | 
					
						
							|  |  |  | 				ret = Z_DATA_ERROR;	 /* and fall through */ | 
					
						
							|  |  |  | 			case Z_DATA_ERROR: | 
					
						
							|  |  |  | 			case Z_MEM_ERROR: | 
					
						
							|  |  |  | 				(void)inflateEnd(&strm); | 
					
						
							|  |  |  | 				return ret; | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-09-27 11:37:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if(breakLoop) | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			have = realSize - latPosOut - strm.avail_out; | 
					
						
							|  |  |  | 			latPosOut += have; | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 		} while (strm.avail_out == 0); | 
					
						
							| 
									
										
										
										
											2007-07-07 11:09:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-27 11:37:15 +00:00
										 |  |  | 		++chunkNumber; | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 		/* done when inflate() says it's done */ | 
					
						
							|  |  |  | 	} while (ret != Z_STREAM_END); | 
					
						
							| 
									
										
										
										
											2007-07-07 11:09:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | 	/* clean up and return */ | 
					
						
							|  |  |  | 	(void)inflateEnd(&strm); | 
					
						
							|  |  |  | 	return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; | 
					
						
							| 
									
										
										
										
											2007-07-07 11:09:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-12 21:08:04 +00:00
										 |  |  | void CLodHandler::extractFile(std::string FName, std::string name) | 
					
						
							| 
									
										
										
										
											2007-07-07 11:09:25 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-25 14:36:11 +00:00
										 |  |  | 	int len; //length of file to write
 | 
					
						
							|  |  |  | 	unsigned char * outp = giveFile(name, &len); | 
					
						
							|  |  |  | 	std::ofstream out; | 
					
						
							|  |  |  | 	out.open(FName.c_str(), std::ios::binary); | 
					
						
							|  |  |  | 	if(!out.is_open()) | 
					
						
							| 
									
										
										
										
											2007-07-07 11:09:25 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-10-25 14:36:11 +00:00
										 |  |  | 		tlog1<<"Unable to create "<<FName<<std::endl; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		out.write(reinterpret_cast<char*>(outp), len); | 
					
						
							|  |  |  | 		out.close(); | 
					
						
							| 
									
										
										
										
											2007-06-30 16:24:05 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-26 04:52:34 +00:00
										 |  |  | void CLodHandler::init(std::string lodFile, std::string dirName) | 
					
						
							| 
									
										
										
										
											2007-06-30 16:24:05 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-10-03 15:15:23 +00:00
										 |  |  | 	myDir = dirName; | 
					
						
							| 
									
										
										
										
											2007-07-07 16:04:15 +00:00
										 |  |  | 	std::string Ts; | 
					
						
							| 
									
										
										
										
											2009-10-10 23:25:34 +00:00
										 |  |  | 	Uint32 temp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	LOD.open(lodFile.c_str(), std::ios::in | std::ios::binary); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-28 04:08:24 +00:00
										 |  |  | 	if (!LOD.is_open())  | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-02-14 15:00:29 +00:00
										 |  |  | 		tlog1 << "Cannot open " << lodFile << std::endl; | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-10-10 23:25:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	LOD.seekg(8); | 
					
						
							|  |  |  | 	LOD.read((char *)&temp, 4); | 
					
						
							|  |  |  | 	totalFiles = SDL_SwapLE32(temp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	LOD.seekg(0x5c, std::ios::beg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct LodEntry *lodEntries = new struct LodEntry[totalFiles]; | 
					
						
							|  |  |  | 	LOD.read((char *)lodEntries, sizeof(struct LodEntry) * totalFiles); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (unsigned int i=0; i<totalFiles; i++) | 
					
						
							| 
									
										
										
										
											2007-07-07 16:04:15 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2007-07-17 20:51:49 +00:00
										 |  |  | 		Entry entry; | 
					
						
							| 
									
										
										
										
											2009-08-02 15:18:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-10 23:25:34 +00:00
										 |  |  | 		entry.nameStr = lodEntries[i].filename; | 
					
						
							|  |  |  | 		std::transform(entry.nameStr.begin(), entry.nameStr.end(),  | 
					
						
							|  |  |  | 					   entry.nameStr.begin(), toupper); | 
					
						
							| 
									
										
										
										
											2009-08-02 15:18:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-10 23:25:34 +00:00
										 |  |  | 		entry.offset= SDL_SwapLE32(lodEntries[i].offset); | 
					
						
							|  |  |  | 		entry.realSize = SDL_SwapLE32(lodEntries[i].uncompressedSize); | 
					
						
							|  |  |  | 		entry.size = SDL_SwapLE32(lodEntries[i].size); | 
					
						
							| 
									
										
										
										
											2009-08-02 15:18:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-07-17 20:51:49 +00:00
										 |  |  | 		entries.push_back(entry); | 
					
						
							| 
									
										
										
										
											2007-07-07 16:04:15 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-10-10 23:25:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	delete [] lodEntries; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-14 10:20:18 +00:00
										 |  |  | 	boost::filesystem::directory_iterator enddir; | 
					
						
							|  |  |  | 	if(boost::filesystem::exists(dirName)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		for (boost::filesystem::directory_iterator dir(dirName);dir!=enddir;dir++) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if(boost::filesystem::is_regular(dir->status())) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2009-12-30 07:49:25 +00:00
										 |  |  | 				std::string name = dir->path().leaf(); | 
					
						
							| 
									
										
										
										
											2009-12-29 13:40:16 +00:00
										 |  |  | 				std::string realname = name; | 
					
						
							| 
									
										
										
										
											2008-06-14 10:20:18 +00:00
										 |  |  | 				std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))toupper); | 
					
						
							|  |  |  | 				boost::algorithm::replace_all(name,".BMP",".PCX"); | 
					
						
							|  |  |  | 				Entry * e = entries.znajdz(name); | 
					
						
							| 
									
										
										
										
											2008-11-12 18:26:23 +00:00
										 |  |  | 				if(e) //file present in .lod - overwrite its entry
 | 
					
						
							| 
									
										
										
										
											2008-06-14 10:20:18 +00:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2009-12-30 07:49:25 +00:00
										 |  |  | 					e->offset = -1; | 
					
						
							| 
									
										
										
										
											2009-12-29 13:40:16 +00:00
										 |  |  | 					e->realName = realname; | 
					
						
							| 
									
										
										
										
											2008-06-14 10:20:18 +00:00
										 |  |  | 					e->realSize = e->size = boost::filesystem::file_size(dir->path()); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2008-11-12 18:26:23 +00:00
										 |  |  | 				else //file not present in lod - add entry for it
 | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2008-12-07 22:38:04 +00:00
										 |  |  | 					Entry e2; | 
					
						
							|  |  |  | 					e2.offset = -1; | 
					
						
							| 
									
										
										
										
											2009-12-30 07:49:25 +00:00
										 |  |  | 					e2.nameStr = name; | 
					
						
							| 
									
										
										
										
											2009-12-29 13:40:16 +00:00
										 |  |  | 					e2.realName = realname; | 
					
						
							| 
									
										
										
										
											2008-12-07 22:38:04 +00:00
										 |  |  | 					e2.realSize = e2.size = boost::filesystem::file_size(dir->path()); | 
					
						
							|  |  |  | 					entries.push_back(e2); | 
					
						
							| 
									
										
										
										
											2008-11-12 18:26:23 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2008-06-14 10:20:18 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							| 
									
										
										
										
											2009-02-14 15:00:29 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2008-09-19 08:16:19 +00:00
										 |  |  | 		tlog1<<"Warning: No "+dirName+"/ folder!"<<std::endl; | 
					
						
							| 
									
										
										
										
											2009-02-14 15:00:29 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-06-30 16:24:05 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-06-12 21:08:04 +00:00
										 |  |  | std::string CLodHandler::getTextFile(std::string name) | 
					
						
							| 
									
										
										
										
											2007-07-16 14:42:44 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-06-12 06:45:51 +00:00
										 |  |  | 	int length=-1; | 
					
						
							|  |  |  | 	unsigned char* data = giveFile(name,&length); | 
					
						
							| 
									
										
										
										
											2009-10-05 01:47:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!data) { | 
					
						
							| 
									
										
										
										
											2010-02-12 15:04:01 +00:00
										 |  |  | 		tlog1<<"Fatal error. Missing game file: " << name << ". Aborting!"<<std::endl; | 
					
						
							| 
									
										
										
										
											2009-10-05 01:47:48 +00:00
										 |  |  | 		exit(1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-25 14:36:11 +00:00
										 |  |  | 	std::string ret(data, data+length); | 
					
						
							| 
									
										
										
										
											2008-06-12 06:45:51 +00:00
										 |  |  | 	delete [] data; | 
					
						
							|  |  |  | 	return ret; | 
					
						
							| 
									
										
										
										
											2007-07-16 14:42:44 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-06-23 08:14:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | CLodHandler::CLodHandler() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	mutex = new boost::mutex; | 
					
						
							|  |  |  | 	totalFiles = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CLodHandler::~CLodHandler() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	delete mutex; | 
					
						
							| 
									
										
										
										
											2009-08-02 15:18:35 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-02-09 13:48:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | unsigned char * CLodHandler::getUnpackedFile( const std::string & path, int * sizeOut ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const int bufsize = 65536; | 
					
						
							|  |  |  | 	int mapsize = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	gzFile map = gzopen(path.c_str(), "rb"); | 
					
						
							| 
									
										
										
										
											2010-02-18 14:09:16 +00:00
										 |  |  | 	assert(map); | 
					
						
							| 
									
										
										
										
											2010-02-09 13:48:14 +00:00
										 |  |  | 	std::vector<unsigned char *> mapstr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Read a map by chunks
 | 
					
						
							|  |  |  | 	// We could try to read the map size directly (cf RFC 1952) and then read
 | 
					
						
							|  |  |  | 	// directly the whole map, but that would create more problems.
 | 
					
						
							|  |  |  | 	do { | 
					
						
							|  |  |  | 		unsigned char *buf = new unsigned char[bufsize]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		int ret = gzread(map, buf, bufsize); | 
					
						
							|  |  |  | 		if (ret == 0 || ret == -1) { | 
					
						
							|  |  |  | 			delete [] buf; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		mapstr.push_back(buf); | 
					
						
							|  |  |  | 		mapsize += ret; | 
					
						
							|  |  |  | 	} while(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	gzclose(map); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Now that we know the uncompressed size, reassemble the chunks
 | 
					
						
							|  |  |  | 	unsigned char *initTable = new unsigned char[mapsize]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	std::vector<unsigned char *>::iterator it; | 
					
						
							|  |  |  | 	int offset; | 
					
						
							|  |  |  | 	int tocopy = mapsize; | 
					
						
							|  |  |  | 	for (it = mapstr.begin(), offset = 0;  | 
					
						
							|  |  |  | 		it != mapstr.end();  | 
					
						
							|  |  |  | 		it++, offset+=bufsize ) { | 
					
						
							|  |  |  | 			memcpy(&initTable[offset], *it, tocopy > bufsize ? bufsize : tocopy); | 
					
						
							|  |  |  | 			tocopy -= bufsize; | 
					
						
							|  |  |  | 			delete [] *it; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*sizeOut = mapsize; | 
					
						
							|  |  |  | 	return initTable; | 
					
						
							|  |  |  | } |