[4057] added: Line of sight (vmaps) [part 2] (last part)
[mangos-git.git] / contrib / vmap_extractor_v2 / vmapextract / vmapexport.cpp
blobd6e0a1c0056e1549e889ce1bee87395579aa3c9f
1 /*****************************************************************************/
2 /* StormLibTest.cpp Copyright (c) Ladislav Zezula 2003 */
3 /*---------------------------------------------------------------------------*/
4 /* This module uses very brutal test methods for StormLib. It extracts all */
5 /* files from the archive with Storm.dll and with stormlib and compares them,*/
6 /* then tries to build a copy of the entire archive, then removes a few files*/
7 /* from the archive and adds them back, then compares the two archives, ... */
8 /*---------------------------------------------------------------------------*/
9 /* Date Ver Who Comment */
10 /* -------- ---- --- ------- */
11 /* 25.03.03 1.00 Lad The first version of StormLibTest.cpp */
12 /*****************************************************************************/
14 #define _CRT_SECURE_NO_DEPRECATE
15 #include <io.h>
16 #include <conio.h>
17 #include <stdio.h>
18 #include <windows.h>
19 #include <mmsystem.h>
20 #include <vector>
21 #include <list>
24 #define __STORMLIB_SELF__ // Don't use StormLib.lib
25 #include "StormLib.h"
27 #pragma warning(disable : 4505)
28 #pragma comment(lib, "Winmm.lib")
30 //From Extractor
31 #include "adtfile.h"
32 #include "wdtfile.h"
33 #include "dbcfile.h"
34 #include "mpq.h"
35 #include "wmo.h"
37 //------------------------------------------------------------------------------
38 // Defines
40 #define MPQ_BLOCK_SIZE 0x1000
42 //-----------------------------------------------------------------------------
43 // from extractor
44 typedef unsigned char uint8;
45 typedef unsigned short uint16;
46 typedef unsigned int uint32;
47 typedef struct{
48 char name[64];
49 unsigned int id;
50 }map_id;
52 map_id * map_ids;
53 uint16 * areas;
54 uint16 *areamax;
55 uint32 map_count;
56 char output_path[128]=".";
57 char input_path[1024]=".";
58 char tmp[512];
59 bool preciseVectorData = true;
60 //char gamepath[1024];
62 //Convert function
63 //bool ConvertADT(char*,char*);
65 // Constants
67 //static const char * szWorkDirMaps = ".\\Maps";
68 static const char * szWorkDirWmo = ".\\buildings";
70 //static LPBYTE pbBuffer1 = NULL;
71 //static LPBYTE pbBuffer2 = NULL;
73 // Local testing functions
75 static void clreol()
77 printf("\r \r");
80 static const char * GetPlainName(const char * szFileName)
82 const char * szTemp;
84 if((szTemp = strrchr(szFileName, '\\')) != NULL)
85 szFileName = szTemp + 1;
86 return szFileName;
88 //------------------------------------------------------------------------------
89 static void ShowProcessedFile(const char * szFileName)
91 char szLine[80];
92 size_t nLength = strlen(szFileName);
94 memset(szLine, 0x20, sizeof(szLine));
95 szLine[sizeof(szLine)-1] = 0;
97 if(nLength > sizeof(szLine)-1)
98 nLength = sizeof(szLine)-1;
99 memcpy(szLine, szFileName, nLength);
100 printf("\r%s\n", szLine);
104 //----------------------------------------------------------------------------------------------------------------------------------------------------------------------
105 int ExtractWmo(const std::vector<std::string>& pArchiveNames)
108 char* szListFile = "";
109 char szLocalFile[MAX_PATH] = "";
110 HANDLE hMpq = "";
111 BOOL bResult = FALSE;
113 //const char* ParsArchiveNames[] = {"patch-2.MPQ", "patch.MPQ", "common.MPQ", "expansion.MPQ"};
115 int nError = ERROR_SUCCESS;
116 if(szListFile == NULL || *szListFile == 0)
117 szListFile = NULL;
118 //char tmp[1024];
119 //for (size_t i=0; i<4; i++)
120 for (size_t i=0; i<pArchiveNames.size(); i++)
123 //sprintf(tmp,"%s\\%s", input_path, ParsArchiveNames[i]);
124 //if(!SFileOpenArchive(tmp, 0, 0, &hMpq))
125 if(!SFileOpenArchive(pArchiveNames[i].c_str(), 0, 0, &hMpq))
126 printf("NOT open!!! %s\n",pArchiveNames[i].c_str());
128 // Copy files from archive
129 if(nError == ERROR_SUCCESS)
131 SFILE_FIND_DATA wf;
132 HANDLE hFind = SFileFindFirstFile(hMpq,"*.wmo*", &wf, szListFile);
133 bResult = TRUE;
135 while(hFind != NULL && bResult == TRUE)
137 ShowProcessedFile(wf.cFileName);
138 SFileSetLocale(wf.lcLocale);
139 sprintf(szLocalFile, "%s\\%s", szWorkDirWmo, GetPlainName(wf.cFileName));
140 fixnamen(szLocalFile,strlen(szLocalFile));
141 FILE * n;
142 if ((n = fopen(szLocalFile, "rb"))== NULL)
144 int p = 0;
145 //Select root wmo files
146 const char * rchr = strrchr(GetPlainName(wf.cFileName),0x5f);
147 if(rchr != NULL)
149 char cpy[4];
150 strncpy((char*)cpy,rchr,4);
151 for (int i=0;i<4;i++)
153 int m = cpy[i];
154 if(isdigit(m))
155 p++;
158 if(p != 3)
160 //printf("RootWmo!\n");
161 string s = wf.cFileName;
162 WMORoot * froot = new WMORoot(s);
163 if(!froot->open())
165 printf("Not open RootWmo!!!\n");
166 bResult = SFileFindNextFile(hFind, &wf);
167 continue;
169 FILE *output=fopen(szLocalFile,"wb");
170 froot->ConvertToVMAPRootWmo(output);
171 int Wmo_nVertices = 0;
172 if(froot->nGroups !=0)
174 for (int i=0; i<froot->nGroups; i++)
176 char temp[512];
177 strcpy(temp, wf.cFileName);
178 temp[strlen(wf.cFileName)-4] = 0;
179 char groupFileName[512];
180 sprintf(groupFileName,"%s_%03d.wmo",temp, i);
181 printf("%s\n",groupFileName);
182 //printf("GroupWmo!\n");
183 string s = groupFileName;
184 WMOGroup * fgroup = new WMOGroup(s);
185 if(!fgroup->open())
187 printf("Not all open Group file for: %s\n",GetPlainName(wf.cFileName));
188 bResult = SFileFindNextFile(hFind, &wf);
189 break;
191 Wmo_nVertices += fgroup->ConvertToVMAPGroupWmo(output, preciseVectorData);
194 fseek(output, 8, SEEK_SET); // store the correct no of vertices
195 fwrite(&Wmo_nVertices,sizeof(int),1,output);
196 fclose(output);
198 } else {
199 fclose(n);
201 wf.dwFileFlags &= ~MPQ_FILE_HAS_EXTRA;
202 wf.dwFileFlags &= ~MPQ_FILE_EXISTS;
203 // Find the next file
204 bResult = SFileFindNextFile(hFind, &wf);
206 // Delete the extracted file in the case of an error
207 if(nError != ERROR_SUCCESS)
208 DeleteFile(szLocalFile);
209 // Close the search handle
210 if(hFind != NULL)
211 SFileFindClose(hFind);
215 // Close both archives
216 if(hMpq != NULL)
217 //SFileCloseArchive(hMpq);
218 if(nError == ERROR_SUCCESS)
219 printf("\nExtract wmo complete (No errors)\n");
221 return nError;
225 void ExtractMapsFromMpq()
229 //-----------------------------------------------------------------------------
230 void ParsMapFiles()
232 char fn[512];
233 char id_filename[64];
234 char id[10];
235 for (unsigned int i=0; i<map_count; i++)
237 sprintf(id,"%03u",map_ids[i].id);
238 sprintf(fn,"World\\Maps\\%s\\%s.wdt", map_ids[i].name, map_ids[i].name);
239 WDTFile WDT(fn,map_ids[i].name);
240 if(WDT.init(id))
242 for (int x=0; x<64; x++)
244 for (int y=0; y<64; y++)
246 if (ADTFile*ADT = WDT.GetMap(x,y))
248 sprintf(id_filename,"%02u %02u %03u",x,y,map_ids[i].id);//!!!!!!!!!
249 ADT->init(id_filename);
250 delete ADT;
258 #if 0
259 void ParsMapFiles()
262 char fn[512];
263 for (unsigned int i=0; i<map_count; i++)
265 sprintf(fn,"World\\Maps\\%s\\%s.wdt", map_ids[i].name, map_ids[i].name);
266 WDTFile WDT(fn,map_ids[i].name);
267 if(WDT.init())
269 for (int x=0; x<64; x++)
271 for (int y=0; y<64; y++)
273 if (ADTFile*ADT = WDT.GetMap(x,y))
275 ADT->init();
276 delete ADT;
284 #endif
285 //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
287 void getGamePath()
289 #ifdef _WIN32
290 HKEY key;
291 DWORD t,s;
292 LONG l;
293 s = sizeof(input_path);
294 memset(input_path,0,s);
295 l = RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Blizzard Entertainment\\World of Warcraft",0,KEY_QUERY_VALUE,&key);
296 //l = RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Blizzard Entertainment\\Burning Crusade Closed Beta",0,KEY_QUERY_VALUE,&key);
297 l = RegQueryValueEx(key,"InstallPath",0,&t,(LPBYTE)input_path,&s);
298 RegCloseKey(key);
299 if (strlen(input_path) > 0)
301 if (input_path[strlen(input_path) - 1] != '\\') strcat(input_path, "\\");
303 strcat(input_path,"Data\\");
304 #else
305 strcpy(input_path,"data/");
306 #endif
309 //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
311 bool scan_patches(char* scanmatch, std::vector<std::string>& pArchiveNames)
313 int i;
314 char path[512];
315 std::list<std::string> matches;
317 WIN32_FIND_DATA ffData;
318 HANDLE hFind;
320 for (i = 1; i <= 99; i++)
322 if (i != 1)
324 sprintf(path, "%s-%d.mpq", scanmatch, i);
326 else
328 sprintf(path, "%s.mpq", scanmatch);
331 hFind = INVALID_HANDLE_VALUE;
332 hFind = FindFirstFile(path, &ffData);
333 if (hFind == INVALID_HANDLE_VALUE) break;
334 FindClose(hFind);
336 matches.push_back(path);
339 matches.reverse();
340 for (std::list<std::string>::iterator i = matches.begin(); i != matches.end(); i++)
342 pArchiveNames.push_back(i->c_str());
345 printf("\n");
347 return(true);
350 //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
352 bool fillArchiveNameVector(std::vector<std::string>& pArchiveNames) {
353 //srand((unsigned int)time(0));
355 getGamePath();
357 printf("\nGame path: %s\n", input_path);
359 char path[512];
360 std::vector<std::string> locales;
362 // scan game directories
363 WIN32_FIND_DATA ffData;
364 HANDLE hFind;
365 DWORD dwError;
367 // first, scan for locales (4-letter directories)
368 printf("Scanning for locales.\n");
369 sprintf(path, "%s*.*", input_path);
370 hFind = INVALID_HANDLE_VALUE;
371 hFind = FindFirstFile(path, &ffData);
372 if (hFind == INVALID_HANDLE_VALUE)
374 printf("\nCould not open data directory for reading. Aborting.\n");
375 return(false);
379 if (ffData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
381 if (ffData.cFileName[0] != '.')
383 if (strlen(ffData.cFileName) == 4)
385 printf("Found locale: %s\n", ffData.cFileName);
386 locales.push_back(ffData.cFileName);
390 } while (FindNextFile(hFind, &ffData) != 0);
391 dwError = GetLastError();
392 FindClose(hFind);
393 if (dwError != ERROR_NO_MORE_FILES)
395 printf("\nError reading data directory while scanning locales. Aborting.\n");
396 return(false);
398 printf("\n");
400 if (locales.size() == 0)
402 printf("Sorry, no locales found. Aborting.\n");
403 return(false);
406 // now, scan for the patch levels in the core dir
407 printf("Loading patch levels from data directory.\n");
408 sprintf(path, "%spatch", input_path);
409 if (!scan_patches(path, pArchiveNames)) return(false);
411 // now, scan for the patch levels in locale dirs
412 printf("Loading patch levels from locale directories.\n");
413 for (std::vector<std::string>::iterator i = locales.begin(); i != locales.end(); i++)
415 printf("Locale: %s\n", i->c_str());
416 sprintf(path, "%s%s\\patch-%s", input_path, i->c_str(), i->c_str());
417 if (!scan_patches(path, pArchiveNames)) return(false);
420 // open expansion and common files
421 printf("Opening data files from data directory.\n");
422 sprintf(path, "%sexpansion.mpq", input_path);
423 pArchiveNames.push_back(path);
424 sprintf(path, "%scommon.mpq", input_path);
425 pArchiveNames.push_back(path);
426 printf("\n");
428 // open locale expansion and common files
429 printf("Opening data files from locale directories.\n");
430 for (std::vector<std::string>::iterator i = locales.begin(); i != locales.end(); i++)
432 printf("Locale: %s\n", i->c_str());
433 sprintf(path, "%s%s\\expansion-locale-%s.mpq", input_path, i->c_str(), i->c_str());
434 pArchiveNames.push_back(path);
435 sprintf(path, "%s%s\\locale-%s.mpq", input_path, i->c_str(), i->c_str());
436 pArchiveNames.push_back(path);
437 printf("\n");
439 return true;
444 //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
445 // Main
447 // The program must be run with two command line arguments
449 // Arg1 - The source MPQ name (for testing reading and file find)
450 // Arg2 - Listfile name
453 int main(int argc, char ** argv)
455 //char tmp[512];
456 // FILE* pDatei;
457 // char tmp[512];
458 // char tmp1[512];
459 //char tmp2[512];
460 // char tmp3[512];
461 // char tmp4[512];
462 char szMpqName[MAX_PATH] = "";
463 char szListFile[MAX_PATH] = "";
464 int nError = ERROR_SUCCESS;
465 char *versionString = "V2.3 2007_07_08";
467 // Use command line arguments, when some
468 if(argc >= 2) {
469 if(strcmp("-s",argv[1]) == 0) {
470 preciseVectorData = false;
471 } else if(strcmp("-?",argv[1]) == 0) {
472 printf("Extract %s.\n",versionString);
473 printf("%s [-s]\n -s : small size (data size optimization, less precise), Will create about 500MB less vmap data.\n", argv[0]);
474 return 0;
477 printf("Extract %s. Beginning work ....\n",versionString);
478 printf("Flags:\n -s : small size (data size optimization, less precise), Will create about 500MB less vmap data.\n");
479 // Set the lowest priority to allow running in the background
480 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
481 //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
482 // Create the working directory
483 if(nError == ERROR_SUCCESS)
485 //if(!CreateDirectory(szWorkDirMaps, NULL))
486 // nError = GetLastError();
487 if(!CreateDirectory(szWorkDirWmo, NULL))
488 nError = GetLastError();
489 if(nError == ERROR_ALREADY_EXISTS)
490 nError = ERROR_SUCCESS;
492 //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
493 // patch goes first -> fake priority handling
494 std::vector<MPQArchive*> archives;
496 //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
497 std::vector<std::string> archiveNames;
499 fillArchiveNameVector(archiveNames);
500 for (size_t i=0; i<archiveNames.size(); i++) {
501 archives.push_back(new MPQArchive(archiveNames[i].c_str()));
503 ExtractWmo(archiveNames);
505 //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
506 //map.dbc
507 if(nError == ERROR_SUCCESS)
509 DBCFile * dbc = new DBCFile("DBFilesClient\\Map.dbc");
510 dbc->open();
511 map_count=dbc->getRecordCount ();
512 map_ids=new map_id[map_count];
513 for(unsigned int x=0;x<map_count;x++)
515 map_ids[x].id=dbc->getRecord (x).getUInt(0);
516 strcpy(map_ids[x].name,dbc->getRecord(x).getString(1));
517 printf("Map - %s\n",map_ids[x].name);
520 delete dbc;
521 ParsMapFiles();
522 delete [] map_ids;
523 nError = ERROR_SUCCESS;
526 clreol();
527 if(nError != ERROR_SUCCESS) {
528 printf("ERROR: Extract %s. Work NOT complete.\n Precise vector data=%d.\nPress any key.\n",versionString, preciseVectorData);
529 _getch();
531 printf("Extract %s. Work complete.\n Precise vector data=%d.\nNo errors.",versionString, preciseVectorData);