autowad.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. // AJM: Added this file in
  2. #include "csg.h"
  3. #include "cmdlib.h"
  4. #ifdef SYSTEM_WIN32
  5. #pragma warning(disable:4996)
  6. #endif
  7. #ifdef HLCSG_AUTOWAD
  8. #define MAX_AUTOWAD_TEXNAME 32 // 32 char limit in array size in brush_texture_t struct
  9. int g_numUsedTextures = 0;
  10. typedef struct autowad_texname_s // non-dupicate list of textures used in map
  11. {
  12. char name[MAX_AUTOWAD_TEXNAME];
  13. autowad_texname_s* next;
  14. } autowad_texname_t;
  15. autowad_texname_t* g_autowad_texname;
  16. // =====================================================================================
  17. // Extract File stuff (ExtractFile | ExtractFilePath | ExtractFileBase)
  18. //
  19. // With VS 2005 - and the 64 bit build, i had to pull 3 classes over from
  20. // cmdlib.cpp even with the proper includes to get rid of the lnk2001 error
  21. //
  22. // amckern - [email protected]
  23. // =====================================================================================
  24. #define PATHSEPARATOR(c) ((c) == '\\' || (c) == '/')
  25. void ExtractFileBase(const char* const path, char* dest)
  26. {
  27. hlassert (path != dest);
  28. const char* src;
  29. src = path + strlen(path) - 1;
  30. //
  31. // back up until a \ or the start
  32. //
  33. while (src != path && !PATHSEPARATOR(*(src - 1)))
  34. src--;
  35. while (*src && *src != '.')
  36. {
  37. *dest++ = *src++;
  38. }
  39. *dest = 0;
  40. }
  41. void ExtractFilePath(const char* const path, char* dest)
  42. {
  43. hlassert (path != dest);
  44. const char* src;
  45. src = path + strlen(path) - 1;
  46. //
  47. // back up until a \ or the start
  48. //
  49. while (src != path && !PATHSEPARATOR(*(src - 1)))
  50. src--;
  51. memcpy(dest, path, src - path);
  52. dest[src - path] = 0;
  53. }
  54. void ExtractFile(const char* const path, char* dest)
  55. {
  56. hlassert (path != dest);
  57. const char* src;
  58. src = path + strlen(path) - 1;
  59. while (src != path && !PATHSEPARATOR(*(src - 1)))
  60. src--;
  61. while (*src)
  62. {
  63. *dest++ = *src++;
  64. }
  65. *dest = 0;
  66. }
  67. // =====================================================================================
  68. // autowad_PushName
  69. // adds passed texname as an entry to autowad_wadnames list, without duplicates
  70. // =====================================================================================
  71. void autowad_PushName(const char* const texname)
  72. {
  73. autowad_texname_t* tex;
  74. if (!g_autowad_texname)
  75. {
  76. // first texture, make an entry
  77. tex = (autowad_texname_t*)malloc(sizeof(autowad_texname_t));
  78. tex->next = NULL;
  79. strcpy_s(tex->name, texname);
  80. g_autowad_texname = tex;
  81. g_numUsedTextures++;
  82. #ifdef _DEBUG
  83. Log("[dbg] Used texture: %i[%s]\n", g_numUsedTextures, texname);
  84. #endif
  85. return;
  86. }
  87. // otherwise, see if texname isnt already in the list
  88. for (tex = g_autowad_texname; ;tex = tex->next)
  89. {
  90. if (!strcmp(tex->name, texname))
  91. return; // dont bother adding it again
  92. if (!tex->next)
  93. break; // end of list
  94. }
  95. // unique texname
  96. g_numUsedTextures++;
  97. autowad_texname_t* last;
  98. last = tex;
  99. tex = (autowad_texname_t*)malloc(sizeof(autowad_texname_t));
  100. strcpy_s(tex->name, texname);
  101. tex->next = NULL;
  102. last->next = tex;
  103. #ifdef _DEBUG
  104. Log("[dbg] Used texture: %i[%s]\n", g_numUsedTextures, texname);
  105. #endif
  106. }
  107. // =====================================================================================
  108. // autowad_PurgeName
  109. // =====================================================================================
  110. void autowad_PurgeName(const char* const texname)
  111. {
  112. autowad_texname_t* prev;
  113. autowad_texname_t* current;
  114. if (!g_autowad_texname)
  115. return;
  116. current = g_autowad_texname;
  117. prev = NULL;
  118. for (; ;)
  119. {
  120. if (!strcmp(current->name, texname))
  121. {
  122. if (!prev) // start of the list
  123. {
  124. g_autowad_texname = current->next;
  125. }
  126. else // middle of list
  127. {
  128. prev->next = current->next;
  129. }
  130. free(current);
  131. return;
  132. }
  133. if (!current->next)
  134. {
  135. //Log(" AUTOWAD: Purge Tex: texname '%s' does not exist\n", texname);
  136. return; // end of list
  137. }
  138. // move along
  139. prev = current;
  140. current = current->next;
  141. }
  142. }
  143. // =====================================================================================
  144. // autowad_PopName
  145. // removes a name from the autowad list, puts it in memory and retuns pointer (which
  146. // shoudl be destructed by the calling function later)
  147. // =====================================================================================
  148. char* autowad_PopName()
  149. {
  150. // todo: code
  151. return NULL;
  152. }
  153. // =====================================================================================
  154. // autowad_cleanup
  155. // frees memory used by autowad procedure
  156. // =====================================================================================
  157. void autowad_cleanup()
  158. {
  159. if (g_autowad_texname != NULL)
  160. {
  161. autowad_texname_t* current;
  162. autowad_texname_t* next;
  163. for (current = g_autowad_texname; ; current = next)
  164. {
  165. if (!current)
  166. break;
  167. //Log("[aw] removing tex %s\n", current->name);
  168. next = current->next;
  169. free(current);
  170. }
  171. }
  172. }
  173. // =====================================================================================
  174. // autowad_IsUsedTexture
  175. // is this texture in the autowad list?
  176. // =====================================================================================
  177. bool autowad_IsUsedTexture(const char* const texname)
  178. {
  179. autowad_texname_t* current;
  180. if (!g_autowad_texname)
  181. return false;
  182. for (current = g_autowad_texname; ; current = current->next)
  183. {
  184. //Log("atw: IUT: Comparing: '%s' with '%s'\n", current->name, texname);
  185. if (!strcmp(current->name, texname))
  186. return true;
  187. if (!current->next)
  188. return false; // reached end of list
  189. }
  190. return false;
  191. }
  192. // =====================================================================================
  193. // GetUsedTextures
  194. // =====================================================================================
  195. void GetUsedTextures()
  196. {
  197. int i;
  198. side_t* bs;
  199. for (i = 0; i < g_numbrushsides; i++)
  200. {
  201. bs = &g_brushsides[i];
  202. autowad_PushName(bs->td.name);
  203. }
  204. }
  205. // =====================================================================================
  206. // autowad_UpdateUsedWads
  207. // =====================================================================================
  208. // yes, these should be in a header/common lib, but i cant be bothered
  209. #define MAXWADNAME 16
  210. typedef struct
  211. {
  212. char identification[4]; // should be WAD2/WAD3
  213. int numlumps;
  214. int infotableofs;
  215. } wadinfo_t;
  216. typedef struct
  217. {
  218. int filepos;
  219. int disksize;
  220. int size; // uncompressed
  221. char type;
  222. char compression;
  223. char pad1, pad2;
  224. char name[MAXWADNAME]; // must be null terminated
  225. int iTexFile; // index of the wad this texture is located in
  226. } lumpinfo_t;
  227. static void CleanupName(const char* const in, char* out)
  228. {
  229. int i;
  230. for (i = 0; i < MAXWADNAME; i++)
  231. {
  232. if (!in[i])
  233. {
  234. break;
  235. }
  236. out[i] = toupper(in[i]);
  237. }
  238. for (; i < MAXWADNAME; i++)
  239. {
  240. out[i] = 0;
  241. }
  242. }
  243. void autowad_UpdateUsedWads()
  244. {
  245. // see which wadfiles are needed
  246. // code for this wad loop somewhat copied from below
  247. wadinfo_t thiswad;
  248. lumpinfo_t* thislump = NULL;
  249. wadpath_t* currentwad;
  250. char* pszWadFile;
  251. FILE* texfile;
  252. const char* pszWadroot = getenv("WADROOT");
  253. int i, j;
  254. int nTexLumps = 0;
  255. #ifdef _DEBUG
  256. Log("[dbg] Starting wad dependency check\n");
  257. #endif
  258. // open each wadpath and sort though its contents
  259. for (i = 0; i < g_iNumWadPaths; i++)
  260. {
  261. currentwad = g_pWadPaths[i];
  262. pszWadFile = currentwad->path;
  263. currentwad->usedbymap = false; // guilty until proven innocent
  264. #ifdef _DEBUG
  265. Log(" Parsing wad: '%s'\n", pszWadFile);
  266. #endif
  267. texfile = fopen(pszWadFile, "rb");
  268. #ifdef SYSTEM_WIN32
  269. if (!texfile)
  270. {
  271. // cant find it, maybe this wad file has a hard code drive
  272. if (pszWadFile[1] == ':')
  273. {
  274. pszWadFile += 2; // skip past the drive
  275. texfile = fopen(pszWadFile, "rb");
  276. }
  277. }
  278. #endif
  279. char szTmp[_MAX_PATH];
  280. if (!texfile && pszWadroot)
  281. {
  282. char szFile[_MAX_PATH];
  283. char szSubdir[_MAX_PATH];
  284. ExtractFile(pszWadFile, szFile);
  285. ExtractFilePath(pszWadFile, szTmp);
  286. ExtractFile(szTmp, szSubdir);
  287. // szSubdir will have a trailing separator
  288. safe_snprintf(szTmp, _MAX_PATH, "%s" SYSTEM_SLASH_STR "%s%s", pszWadroot, szSubdir, szFile);
  289. texfile = fopen(szTmp, "rb");
  290. #ifdef SYSTEM_POSIX
  291. if (!texfile)
  292. {
  293. // cant find it, Convert to lower case and try again
  294. strlwr(szTmp);
  295. texfile = fopen(szTmp, "rb");
  296. }
  297. #endif
  298. }
  299. if (!texfile) // still cant find it, skip this one
  300. {
  301. if(pszWadroot)
  302. {
  303. Warning("Wad file '%s' not found, also tried '%s'",pszWadFile,szTmp);
  304. }
  305. else
  306. {
  307. Warning("Wad file '%s' not found",pszWadFile);
  308. }
  309. continue;
  310. }
  311. // look and see if we're supposed to include the textures from this WAD in the bsp.
  312. {
  313. WadInclude_i it;
  314. bool including = false;
  315. for (it = g_WadInclude.begin(); it != g_WadInclude.end(); it++)
  316. {
  317. if (stristr(pszWadFile, it->c_str()))
  318. {
  319. #ifdef _DEBUG
  320. Log(" - including wad\n");
  321. #endif
  322. including = true;
  323. currentwad->usedbymap = true;
  324. break;
  325. }
  326. }
  327. if (including)
  328. {
  329. //fclose(texfile);
  330. //continue;
  331. }
  332. }
  333. // read in this wadfiles information
  334. SafeRead(texfile, &thiswad, sizeof(thiswad));
  335. // make sure its a valid format
  336. if (strncmp(thiswad.identification, "WAD2", 4) && strncmp(thiswad.identification, "WAD3", 4))
  337. {
  338. fclose(texfile);
  339. continue;
  340. }
  341. thiswad.numlumps = LittleLong(thiswad.numlumps);
  342. thiswad.infotableofs = LittleLong(thiswad.infotableofs);
  343. // read in lump
  344. if (fseek(texfile, thiswad.infotableofs, SEEK_SET))
  345. {
  346. fclose(texfile);
  347. continue; // had trouble reading, skip this wad
  348. }
  349. // memalloc for this lump
  350. thislump = (lumpinfo_t*)realloc(thislump, (nTexLumps + thiswad.numlumps) * sizeof(lumpinfo_t));
  351. // BUGBUG: is this destructed?
  352. // for each texlump
  353. for (j = 0; j < thiswad.numlumps; j++, nTexLumps++)
  354. {
  355. SafeRead(texfile, &thislump[nTexLumps], (sizeof(lumpinfo_t) - sizeof(int)) ); // iTexFile is NOT read from file
  356. CleanupName(thislump[nTexLumps].name, thislump[nTexLumps].name);
  357. if (autowad_IsUsedTexture(thislump[nTexLumps].name))
  358. {
  359. currentwad->usedbymap = true;
  360. currentwad->usedtextures++;
  361. #ifdef _DEBUG
  362. Log(" - Used wadfile: [%s]\n", thislump[nTexLumps].name);
  363. #endif
  364. autowad_PurgeName(thislump[nTexLumps].name);
  365. }
  366. }
  367. fclose(texfile);
  368. }
  369. #ifdef _DEBUG
  370. Log("[dbg] End wad dependency check\n\n");
  371. #endif
  372. return;
  373. }
  374. #endif // HLCSG_AUTOWAD