Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

336 lines
5.6 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. // wad2lib.c
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <errno.h>
  13. #include <ctype.h>
  14. #include <sys/types.h>
  15. #include <sys/stat.h>
  16. //#include <sys/file.h>
  17. #include <stdarg.h>
  18. #ifdef NeXT
  19. #include <libc.h>
  20. #endif
  21. #include "goldsrc_standin.h"
  22. #include "wadlib.h"
  23. /*
  24. ============================================================================
  25. WAD READING
  26. ============================================================================
  27. */
  28. lumpinfo_t *lumpinfo; // location of each lump on disk
  29. int numlumps;
  30. wadinfo_t header;
  31. FILE *wadhandle;
  32. /*
  33. ====================
  34. W_OpenWad
  35. ====================
  36. */
  37. void W_OpenWad (const char *filename)
  38. {
  39. lumpinfo_t *lump_p;
  40. int i;
  41. int length;
  42. //
  43. // open the file and add to directory
  44. //
  45. wadhandle = SafeOpenRead ((char*)filename);
  46. SafeRead (wadhandle, &header, sizeof(header));
  47. if (strncmp(header.identification,"WAD2",4) &&
  48. strncmp(header.identification, "WAD3", 4))
  49. Error ("Wad file %s doesn't have WAD2/WAD3 id\n",filename);
  50. header.numlumps = LittleLong(header.numlumps);
  51. header.infotableofs = LittleLong(header.infotableofs);
  52. numlumps = header.numlumps;
  53. length = numlumps*sizeof(lumpinfo_t);
  54. lumpinfo = (lumpinfo_t*)malloc (length);
  55. lump_p = lumpinfo;
  56. fseek (wadhandle, header.infotableofs, SEEK_SET);
  57. SafeRead (wadhandle, lumpinfo, length);
  58. //
  59. // Fill in lumpinfo
  60. //
  61. for (i=0 ; i<numlumps ; i++,lump_p++)
  62. {
  63. lump_p->filepos = LittleLong(lump_p->filepos);
  64. lump_p->size = LittleLong(lump_p->size);
  65. }
  66. }
  67. void CleanupName (char *in, char *out)
  68. {
  69. int i;
  70. for (i=0 ; i<sizeof( ((lumpinfo_t *)0)->name ) ; i++ )
  71. {
  72. if (!in[i])
  73. break;
  74. out[i] = toupper(in[i]);
  75. }
  76. for ( ; i<sizeof( ((lumpinfo_t *)0)->name ); i++ )
  77. out[i] = 0;
  78. }
  79. /*
  80. ====================
  81. W_CheckNumForName
  82. Returns -1 if name not found
  83. ====================
  84. */
  85. int W_CheckNumForName (char *name)
  86. {
  87. char cleanname[16];
  88. int v1,v2, v3, v4;
  89. int i;
  90. lumpinfo_t *lump_p;
  91. CleanupName (name, cleanname);
  92. // make the name into four integers for easy compares
  93. v1 = *(int *)cleanname;
  94. v2 = *(int *)&cleanname[4];
  95. v3 = *(int *)&cleanname[8];
  96. v4 = *(int *)&cleanname[12];
  97. // find it
  98. lump_p = lumpinfo;
  99. for (i=0 ; i<numlumps ; i++, lump_p++)
  100. {
  101. if ( *(int *)lump_p->name == v1
  102. && *(int *)&lump_p->name[4] == v2
  103. && *(int *)&lump_p->name[8] == v3
  104. && *(int *)&lump_p->name[12] == v4)
  105. return i;
  106. }
  107. return -1;
  108. }
  109. /*
  110. ====================
  111. W_GetNumForName
  112. Calls W_CheckNumForName, but bombs out if not found
  113. ====================
  114. */
  115. int W_GetNumForName (char *name)
  116. {
  117. int i;
  118. i = W_CheckNumForName (name);
  119. if (i != -1)
  120. return i;
  121. Error ("W_GetNumForName: %s not found!",name);
  122. return -1;
  123. }
  124. /*
  125. ====================
  126. W_LumpLength
  127. Returns the buffer size needed to load the given lump
  128. ====================
  129. */
  130. int W_LumpLength (int lump)
  131. {
  132. if (lump >= numlumps)
  133. Error ("W_LumpLength: %i >= numlumps",lump);
  134. return lumpinfo[lump].size;
  135. }
  136. /*
  137. ====================
  138. W_ReadLumpNum
  139. Loads the lump into the given buffer, which must be >= W_LumpLength()
  140. ====================
  141. */
  142. void W_ReadLumpNum (int lump, void *dest)
  143. {
  144. lumpinfo_t *l;
  145. if (lump >= numlumps)
  146. Error ("W_ReadLump: %i >= numlumps",lump);
  147. l = lumpinfo+lump;
  148. fseek (wadhandle, l->filepos, SEEK_SET);
  149. SafeRead (wadhandle, dest, l->size);
  150. }
  151. /*
  152. ====================
  153. W_LoadLumpNum
  154. ====================
  155. */
  156. void *W_LoadLumpNum (int lump)
  157. {
  158. void *buf;
  159. if ((unsigned)lump >= (unsigned)numlumps)
  160. Error ("W_CacheLumpNum: %i >= numlumps",lump);
  161. buf = malloc (W_LumpLength (lump));
  162. W_ReadLumpNum (lump, buf);
  163. return buf;
  164. }
  165. /*
  166. ====================
  167. W_LoadLumpName
  168. ====================
  169. */
  170. void *W_LoadLumpName (char *name)
  171. {
  172. return W_LoadLumpNum (W_GetNumForName(name));
  173. }
  174. /*
  175. ===============================================================================
  176. WAD CREATION
  177. ===============================================================================
  178. */
  179. FILE *outwad;
  180. lumpinfo_t outinfo[4096];
  181. int outlumps;
  182. short (*wadshort) (short l);
  183. int (*wadlong) (int l);
  184. /*
  185. ===============
  186. NewWad
  187. ===============
  188. */
  189. void NewWad (char *pathname, qboolean bigendien)
  190. {
  191. outwad = SafeOpenWrite (pathname);
  192. fseek (outwad, sizeof(wadinfo_t), SEEK_SET);
  193. memset (outinfo, 0, sizeof(outinfo));
  194. if (bigendien)
  195. {
  196. wadshort = BigShort;
  197. wadlong = BigLong;
  198. }
  199. else
  200. {
  201. wadshort = LittleShort;
  202. wadlong = LittleLong;
  203. }
  204. outlumps = 0;
  205. }
  206. /*
  207. ===============
  208. AddLump
  209. ===============
  210. */
  211. void AddLump (char *name, void *buffer, int length, int type, int compress)
  212. {
  213. lumpinfo_t *info;
  214. int ofs;
  215. info = &outinfo[outlumps];
  216. outlumps++;
  217. memset (info,0,sizeof(info));
  218. strcpy (info->name, name);
  219. strupr (info->name);
  220. ofs = ftell(outwad);
  221. info->filepos = wadlong(ofs);
  222. info->size = info->disksize = wadlong(length);
  223. info->type = type;
  224. info->compression = compress;
  225. // FIXME: do compression
  226. SafeWrite (outwad, buffer, length);
  227. }
  228. /*
  229. ===============
  230. WriteWad
  231. ===============
  232. */
  233. void WriteWad (int wad3)
  234. {
  235. wadinfo_t header;
  236. int ofs;
  237. // write the lumpingo
  238. ofs = ftell(outwad);
  239. SafeWrite (outwad, outinfo, outlumps*sizeof(lumpinfo_t) );
  240. // write the header
  241. // a program will be able to tell the ednieness of a wad by the id
  242. header.identification[0] = 'W';
  243. header.identification[1] = 'A';
  244. header.identification[2] = 'D';
  245. header.identification[3] = wad3 ? '3' : '2';
  246. header.numlumps = wadlong(outlumps);
  247. header.infotableofs = wadlong(ofs);
  248. fseek (outwad, 0, SEEK_SET);
  249. SafeWrite (outwad, &header, sizeof(header));
  250. fclose (outwad);
  251. }