#include "StdAfx.h"
#include ".\mapterrain.h"
CMapTerrain::CMapTerrain(void)
: nbMapFiles(0)
, W3eSource(NULL)
{
}
CMapTerrain::~CMapTerrain(void)
{
}
// Name: LoadAndConvertTGA
// in:
// char* TGAPath -- the path of the TGA
// return:
// true -- if there wasn't any problem
// false -- if there was a problem
// Discription:
// First this function load the TGA-File with the CxImage-Class,
// then it gets every pixel, converts the pixelcolor into the
// height of a mappoint and store it into a MapPoint-Class.
bool CMapTerrain::LoadAndConvertTGA(char* TGAPath)
{
RGBQUAD ColorBuffer;
int Height;
int Width;
int MapPointsNum;
//Thats the TGA
CxImage File(TGAPath, CXIMAGE_SUPPORT_TGA);
//Get the height...
Height = File.GetHeight();
//...and width
Width = File.GetWidth();
if(!Height || !Width)
{
return false;
}
/*
* The number of points in a map is always
* Height (min. 33) * Width (min. 33) - 1
* the height (width) of the bmp is always
* mapheight (mapwidth) + 1
*/
MapPointsNum = Height*Width-1;
//That are the points of the map
Points = new MapPoint[MapPointsNum];
//The counter for the mappoints
int Counter = 0;
for(int y = 1; y <= Height; y++)
{
for(int x = 1; x <= Width; x++)
{
int Red;
int Green;
int Blue;
int Color;
//Get the pixel color
ColorBuffer = File.GetPixelColor(x, y, false);
//...and convert it into red, green and blue
Red = ColorBuffer.rgbRed;
Green = ColorBuffer.rgbGreen;
Blue = ColorBuffer.rgbBlue;
//Get the gray color
Color = (Red + Blue + Green)/3;
//Convert the color into height
Points[Counter].Hight = Color*25+8192;
Counter++;
}
}
return true;
}
// Name: CreatePoints
// in:
// char* szInhalt -- the value of the file
// int FileSize -- the size of the file
// char* TGAPath -- the path of the TGA
// char* MapFilePath -- the path of the new w3e
// return:
// true -- if there wasn't any problem
// false -- if there was a problem
//
// Discription:
// First this function calls the LoadAndConvert-Function.
// Then it read the header of the sourcefile (69 byte).
// After that it reads the mappoints and replace the height
// with the height of the MapPoint-Class.
// If this is done the function calls the WriteW3e-Function.
bool CMapTerrain::CreatePoints(char* szInhalt, int FileSize, char* TGAPath, char* MapFilePath)
{
char* InhaltBuffer = new char[FileSize];
InhaltBuffer = szInhalt;
CMapTerrain::LoadAndConvertTGA(TGAPath);
//Make a new buffer for the new file
char* Buffer = new char[FileSize];
for(int i = 0; i < 69; i++)
{
Buffer[i] = InhaltBuffer[i];
}
//Set the counter to 0
//and use it for the
int Counter = 0;
int PointCounter = 0;
for(int i = 69; i < FileSize; i++)
{
switch(Counter)
{
case 1:
{
Buffer[i] = (Points[PointCounter-1].Hight & 0xFF00) / 0x0100;
//I don't now why, but if it wasn't here, the editor would get an error ;)
Counter++;
break;
}
case 0:
{
Points[PointCounter].Hight;
Buffer[i] = (Points[PointCounter].Hight & 0xFF00);
PointCounter++;
break;
}
default:
{
Buffer[i] = szInhalt[i];
break;
}
}
if(Counter < 7)
{
Counter++;
}
else
{
Counter = 0;
}
}
CMapTerrain::WriteW3e(Buffer, MapFilePath, FileSize);
return true;
}
// Name: CreatePoints
// in:
// char* szInhalt -- the value of the file
// int FileSize -- the size of the file
// char* MapFilePath -- the path of the new w3e
// return:
// true -- if there wasn't any problem
// false -- if there was a problem
//
// Discription:
// This function writes the value szInahlt into a file.
bool CMapTerrain::WriteW3e(char* szInhalt, char* MapFilePath, int FileSize)
{
//Create the file and write the buffer into it
HANDLE hWrite;
DWORD w;
hWrite = CreateFile(MapFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if(!hWrite)
return false;
WriteFile(hWrite, szInhalt, FileSize, &w, NULL);
CloseHandle(hWrite);
//CMapTerrain::ImportW3e(MapFilePath, "D:\\Testmap.w3m");
return true;
}
// Name: GetPathOfModule
// in:
// char* szModulePath -- The pointer to your char
// return:
// true -- if there wasn't any problem
// false -- if there was a problem
// Discription:
// Gets the path of the tool
bool CMapTerrain::GetPathOfModule(char* szModulePath)
{
char szCompletePath[MAX_PATH] = "";
char szPath[MAX_PATH] = "";
LPSTR pFileName = "";
*szModulePath = '\0';
GetModuleFileName(NULL, szCompletePath, MAX_PATH);
GetFullPathName(szCompletePath, sizeof(szCompletePath), szPath, &pFileName);
szPath[pFileName - szPath] = '\0';
strcat(szModulePath, szPath);
return true;
}
//Don't used... is bugged
// Name: ExportTemp
// in:
// char* Wc3Map -- the path of the map
// char* TempPath -- the path of temp diretory
// return:
// true -- if there wasn't any problem
// false -- if there was a problem
// Discription:
// Exports all files of a map to a temp directory.
// First it opens a map. Then it get the size of
// the hash-table and create a new FILELISTTRY.
// After that it egts all files, store them into
// the CMapList-Class and write them in a file.
bool CMapTerrain::ExportTemp(char* Wc3Map, char* TempPath)
{
MPQHANDLE hMPQ = NULL;
DWORD dwPriority = 666;
if(SFileOpenArchive(Wc3Map, dwPriority, SFILE_OPEN_HARD_DISK_FILE, &hMPQ) == true)
{
//Get the size of the hash-table
DWORD dwHashTableSize = SFileGetFileInfo(hMPQ, SFILE_INFO_HASH_TABLE_SIZE);
FILELISTENTRY *lpListBuffer = new FILELISTENTRY[dwHashTableSize];
//A tempfile
char ListFilePath[MAX_PATH] = "";
strcpy(ListFilePath, TempPath);
strcat(ListFilePath, "FileList.txt");
SFileListFiles(hMPQ, ListFilePath, lpListBuffer, SFILE_LIST_ONLY_KNOWN);
nbMapFiles = dwHashTableSize;
for(int i = 0; i < dwHashTableSize; i++)
{
if(lpListBuffer[i].dwFileExists != 0)
{
//Create the winpath
char WinBuffer[MAX_PATH] = "";
strcpy(WinBuffer, TempPath);
strcat(WinBuffer, CMapTerrain::GetWinFileName(lpListBuffer[i].szFileName));
//Add file to the filelist
Files.AddFile(WinBuffer, lpListBuffer[i].szFileName);
MPQHANDLE hFile;
HANDLE hWrite;
DWORD w;
hWrite = CreateFile(WinBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
SFileOpenFile(lpListBuffer[i].szFileName, &hFile);
if(hFile)
{
//Create a buffer for the file
char szBuffer[0x10000];
DWORD dwBytes = 1;
while ( dwBytes > 0 )
{
SFileReadFile(hFile, szBuffer, sizeof(szBuffer), &dwBytes, NULL);
if ( dwBytes > 0 )
{
//Write the file
WriteFile(hWrite, szBuffer, dwBytes, &dwBytes, NULL);
}
}
}
else {
//If error, then exit
return false;
}
CloseHandle(hWrite);
SFileCloseFile(hFile);
}
}
}
else {
//If error, then exit
return false;
}
SFileCloseArchive(hMPQ);
return true;
}
//Don't used... is bugged
// Name: ImportW3e
// in:
// char* MapFilePath -- that's the w3e-file
// char* Wc3Map -- the path of the map
// return:
// true -- if there wasn't any problem
// false -- if there was a problem
// Discription:
// First at all the function create a temp directory
// and export all files of the map into it. After
// that the function opens the map for a update and
// import all temp files into it, even the new w3e.
bool CMapTerrain::ImportW3e(char* MapFilePath, char* Wc3Map)
{
MPQHANDLE hMPQ = NULL;
char Path[MAX_PATH] = "";
CMapTerrain::GetPathOfModule(Path);
strcat(Path, "Temp\\");
//For the temp-files
CreateDirectory(Path, 0);
CMapTerrain::ExportTemp(Wc3Map, Path);
hMPQ = MpqOpenArchiveForUpdate(Wc3Map, MOAU_CREATE_ALWAYS | MOAU_MAINTAIN_LISTFILE , 0x800);
if(hMPQ == NULL) {
//If the file does not exist, exit.
return false;
}
for(int i = 0; i < nbMapFiles; i++)
{
bool IsW3e = CMapTerrain::CompareChar("war3map.w3e", Files.GetWc3Path(i));
if(IsW3e == false)
{
//Import all exported files
MpqAddFileToArchiveEx(hMPQ, Files.GetWinPath(i), Files.GetWc3Path(i), MAFA_COMPRESS2, MAFA_COMPRESS_DEFLATE, Z_BEST_COMPRESSION);
}
else
{
char MapFilePath[MAX_PATH] = "";
strcat(MapFilePath, Path);
strcat(MapFilePath, "war3map_temp.w3e");
MpqAddFileToArchiveEx(hMPQ, MapFilePath, Files.GetWc3Path(i), MAFA_COMPRESS2, MAFA_COMPRESS_DEFLATE, Z_BEST_COMPRESSION);
}
}
//Compact and Close
MpqCompactArchive(hMPQ);
MpqCloseUpdatedArchive(hMPQ, 0);
return true;
}
// Name: GetWinFileName
// in:
// char* FilePath -- the path that should be converted
// return:
// char* -- the windows path
// Discription:
// This small function get the filename without
// the path and return it. For an example:
// In: Test\Bla\Huhu\Dumdidum.w3g
// Out: Dumdidum.w3g
char* CMapTerrain::GetWinFileName(char* FilePath)
{
if(FilePath == "")
{
CMapTerrain::ErrorMessage("Filepath is to small!");
}
int Max = 0;
std::string StringBuffer = FilePath;
int Pos = StringBuffer.find_last_of("\\");
StringBuffer = StringBuffer.substr(Pos+1, StringBuffer.length());
char* Buffer = new char[StringBuffer.length()];
strcpy(Buffer, StringBuffer.c_str());
return Buffer;
}
// Name: ErrorMessage
// in:
// char* Message -- the message...
// return:
// nothing
// Discription:
// This function is used in the devlopment.
void CMapTerrain::ErrorMessage(char* Message)
{
#ifdef CONSOLE
std::cout << "Error: " << Message << std::endl;
#endif
#ifdef WINDOW
MessageBox(NULL, Message, "Error", MB_ICONERROR);
#endif
}
// Name: CompareChar
// in:
// char* Sourcechar -- the source char
// char* CompareableChar -- a char that should be compareable
// return:
// true -- if the chars are compareable
// false -- if the chars are'nt compareable
// Discription:
// This function compares 2 char's.
bool CMapTerrain::CompareChar(char* SourceChar, char* CompareableChar)
{
std::string Buffer1 = SourceChar;
std::string Buffer2 = CompareableChar;
for(int i = 0; i < Buffer2.length(); i++)
{
if(Buffer1[i] != Buffer2[i])
{
return false;
}
}
return true;
}
// Name: ExportSourceW3e
// in:
// char* Wc3Map -- thats the path of the map
// return:
// true -- if there was no problem
// false -- if thete was a problem
// Discription:
// This function export the source w3e form a
// map. Firstit opens the map an create a new
// w3e file. Then it opens the w3e in the mpq
// and read the file. After that it writes
// the readed byes into the new w3e file.
bool CMapTerrain::ExportSourceW3e(char* Wc3Map)
{
MPQHANDLE hFile;
HANDLE hWrite;
DWORD w;
MPQHANDLE hMPQ = NULL;
DWORD dwPriority = 666;
SFileOpenArchive(Wc3Map, dwPriority, SFILE_OPEN_HARD_DISK_FILE, &hMPQ);
char SourcePath[MAX_PATH] = "";
GetPathOfModule(SourcePath);
strcat(SourcePath, "war3map.w3e");
hWrite = CreateFile(SourcePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
SFileOpenFile("war3map.w3e", &hFile);
if(hFile)
{
//Create a buffer for the file
char szBuffer[0x10000];
DWORD dwBytes = 1;
while ( dwBytes > 0 )
{
SFileReadFile(hFile, szBuffer, sizeof(szBuffer), &dwBytes, NULL);
if ( dwBytes > 0 )
{
//Write the file
WriteFile(hWrite, szBuffer, dwBytes, &dwBytes, NULL);
}
}
}
else {
//If error, then exit
return false;
}
CloseHandle(hWrite);
SFileCloseFile(hFile);
SFileCloseArchive(hMPQ);
W3eSource = SourcePath;
return true;
}