/trunk/tools/ddfinwad/wad_io.c

# · C · 375 lines · 235 code · 70 blank · 70 comment · 30 complexity · d40a0b23bc126582d0b98ff5181403c7 MD5 · raw file

  1. //----------------------------------------------------------------------------
  2. // EDGE Tool WAD I/O
  3. //----------------------------------------------------------------------------
  4. //
  5. // Copyright (c) 1999-2000 The EDGE Team.
  6. //
  7. // This program is free software; you can redistribute it and/or
  8. // modify it under the terms of the GNU General Public License
  9. // as published by the Free Software Foundation; either version 2
  10. // of the License, or (at your option) any later version.
  11. //
  12. // This program is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. // GNU General Public License for more details.
  16. //
  17. //----------------------------------------------------------------------------
  18. //
  19. #include "i_defs.h"
  20. #include "wad_io.h"
  21. #define PWAD_HEADER "PWAD"
  22. //
  23. // TYPES
  24. //
  25. //
  26. // Wad Info
  27. //
  28. typedef struct
  29. {
  30. char id[4]; // IWAD (whole) or PWAD (part)
  31. int numlumps; // Number of Lumps
  32. int infotableofs; // Info table offset
  33. }
  34. wadinfo_t;
  35. //
  36. // Lump information struct
  37. //
  38. typedef struct
  39. {
  40. int filepos; // Position in file
  41. int size; // Size
  42. char name[8]; // Name
  43. }
  44. lumpinfo_t;
  45. //
  46. // Lump stuff
  47. //
  48. typedef struct lump_s
  49. {
  50. byte* data; // Data
  51. int filepos; // Position in file
  52. int size; // Size
  53. char name[8]; // Name
  54. }
  55. lump_t;
  56. // Lumpinfo list
  57. static lumpinfo_t **lumpinfolist = NULL;
  58. static int numoflumpinfs = 0;
  59. // Lump list
  60. static lump_t **lumplist = NULL;
  61. static int numoflumps = 0;
  62. //
  63. // PadFile
  64. //
  65. // Pads a file to the nearest 4 bytes.
  66. //
  67. static void PadFile(FILE* fp, int filepos)
  68. {
  69. int num;
  70. num = filepos % 4;
  71. if (!num)
  72. return;
  73. num = 4 - num;
  74. while(num)
  75. {
  76. fwrite(&num, sizeof(byte), 1, fp);
  77. num--;
  78. }
  79. }
  80. //
  81. // AddLumpinfo
  82. //
  83. static boolean_t AddLumpinfo(lumpinfo_t *lpinf)
  84. {
  85. lumpinfo_t **oldlpinflist;
  86. if (numoflumpinfs && lumpinfolist)
  87. {
  88. oldlpinflist = lumpinfolist;
  89. lumpinfolist = malloc(sizeof(lumpinfo_t*)*(numoflumpinfs+1));
  90. if (!lumpinfolist)
  91. return false;
  92. memset(lumpinfolist, 0, sizeof(lumpinfo_t*)*(numoflumpinfs+1));
  93. memcpy(lumpinfolist, oldlpinflist,
  94. sizeof(lumpinfo_t*)*(numoflumpinfs));
  95. free(oldlpinflist);
  96. }
  97. else
  98. {
  99. lumpinfolist = malloc(sizeof(lumpinfo_t*));
  100. if (!lumpinfolist)
  101. return false;
  102. numoflumpinfs = 0;
  103. }
  104. lumpinfolist[numoflumpinfs] = malloc(sizeof(lumpinfo_t));
  105. if (!lumpinfolist[numoflumpinfs])
  106. return false;
  107. lumpinfolist[numoflumpinfs]->filepos = lpinf->filepos;
  108. lumpinfolist[numoflumpinfs]->size = lpinf->size;
  109. strncpy(lumpinfolist[numoflumpinfs]->name, lpinf->name, 8);
  110. numoflumpinfs++;
  111. return true;
  112. }
  113. //
  114. // WAD_AddLump
  115. //
  116. boolean_t WAD_AddLump(byte *data, int size, char *name)
  117. {
  118. lump_t **oldlumplist;
  119. int i;
  120. // Check for existing lump, overwrite if need be.
  121. i=WAD_LumpExists(name);
  122. if (i>=0)
  123. {
  124. free(lumplist[i]->data);
  125. lumplist[i]->size = size;
  126. lumplist[i]->data = data;
  127. return true;
  128. }
  129. if (numoflumps && lumplist)
  130. {
  131. oldlumplist = lumplist;
  132. lumplist = malloc(sizeof(lump_t*)*(numoflumps+1));
  133. if (!lumplist)
  134. return false;
  135. memset(lumplist, 0, sizeof(lump_t*)*(numoflumps+1));
  136. memcpy(lumplist, oldlumplist, sizeof(lump_t*)*(numoflumps));
  137. free(oldlumplist);
  138. }
  139. else
  140. {
  141. lumplist = malloc(sizeof(lump_t*));
  142. if (!lumplist)
  143. return false;
  144. numoflumps = 0;
  145. }
  146. lumplist[numoflumps] = malloc(sizeof(lump_t));
  147. if (!lumplist[numoflumps])
  148. return false;
  149. lumplist[numoflumps]->data = data;
  150. lumplist[numoflumps]->size = size;
  151. strncpy(lumplist[numoflumps]->name, name, 8);
  152. numoflumps++;
  153. return true;
  154. }
  155. //
  156. // WAD_LumpExists
  157. //
  158. int WAD_LumpExists(char *name)
  159. {
  160. int i;
  161. i=0;
  162. while (i<numoflumps)
  163. {
  164. if (!strncmp(lumplist[i]->name, name, 8))
  165. return i;
  166. i++;
  167. }
  168. return -1;
  169. }
  170. //
  171. // WAD_WriteFile
  172. //
  173. boolean_t WAD_WriteFile(char *name)
  174. {
  175. int i;
  176. FILE *fp;
  177. char *pwadstr = PWAD_HEADER;
  178. int infooffset;
  179. int fpos;
  180. // Open File
  181. fp = fopen(name, "wb");
  182. if (!fp)
  183. return false;
  184. // Write Header
  185. fwrite((void*)pwadstr, sizeof(char), 4, fp);
  186. fwrite((void*)&numoflumps, sizeof(int), 1, fp);
  187. fwrite((void*)&numoflumps, sizeof(int), 1, fp); // dummy - write later
  188. // Write Lumps
  189. i=0;
  190. while(i<numoflumps)
  191. {
  192. fpos = ftell(fp);
  193. PadFile(fp, fpos);
  194. lumplist[i]->filepos = ftell(fp);
  195. fwrite((void*)lumplist[i]->data, sizeof(byte), lumplist[i]->size, fp);
  196. i++;
  197. }
  198. fpos = ftell(fp);
  199. PadFile(fp, fpos);
  200. infooffset = ftell(fp);
  201. // Write Lumpinfo(s)
  202. i=0;
  203. while(i<numoflumps)
  204. {
  205. fwrite((void*)&lumplist[i]->filepos, sizeof(int), 1, fp);
  206. fwrite((void*)&lumplist[i]->size, sizeof(int), 1, fp);
  207. fwrite((void*)lumplist[i]->name, sizeof(char), 8, fp);
  208. i++;
  209. }
  210. // Write table offset
  211. fseek(fp, 8, SEEK_SET);
  212. fwrite((void*)&infooffset, sizeof(int), 1, fp); // Now write table offset
  213. // Close File
  214. fclose(fp);
  215. return true;
  216. }
  217. //
  218. // WAD_ReadFile
  219. //
  220. boolean_t WAD_ReadFile(char *name)
  221. {
  222. #ifdef DEVELOPERS
  223. char lumpname[9];
  224. lump_t lump;
  225. #endif
  226. FILE *fp;
  227. wadinfo_t wadinfo;
  228. lumpinfo_t lumpinfo;
  229. int i;
  230. byte* data;
  231. // Open File
  232. fp = fopen(name, "rb");
  233. if (!fp)
  234. return false;
  235. // Read Header
  236. fread((void*)&wadinfo, sizeof(wadinfo_t), 1, fp);
  237. // Check Header is for a PWAD
  238. if (strncmp(wadinfo.id, PWAD_HEADER, 4))
  239. {
  240. printf("Got: %s\n",wadinfo.id);
  241. return false;
  242. }
  243. #ifdef DEVELOPERS
  244. printf("Number of lumps: %d\n", wadinfo.numlumps);
  245. printf("Offset: %d\n", wadinfo.infotableofs);
  246. #endif
  247. // Read and alloc for lumps
  248. fseek(fp, wadinfo.infotableofs, SEEK_SET);
  249. i = wadinfo.numlumps;
  250. while(i)
  251. {
  252. fread((void*)&lumpinfo.filepos, sizeof(int), 1, fp);
  253. fread((void*)&lumpinfo.size, sizeof(int), 1, fp);
  254. fread((void*)lumpinfo.name, sizeof(char), 8, fp);
  255. #ifdef DEVELOPERS
  256. memset(lumpname, ' ', 8);
  257. strncpy(lumpname, lumpinfo.name, 8);
  258. lumpname[8] = '\0';
  259. printf("%s,%d,%d,\n", lumpname, lumpinfo.size, lumpinfo.filepos);
  260. #endif
  261. if (!AddLumpinfo(&lumpinfo))
  262. return false;
  263. i--;
  264. }
  265. // go through lumpinfo list and load lumps
  266. i=0;
  267. while(i<numoflumpinfs)
  268. {
  269. fseek(fp, lumpinfolist[i]->filepos, SEEK_SET);
  270. data = malloc(sizeof(byte)*lumpinfolist[i]->size);
  271. fread((void*)data, sizeof(byte), lumpinfolist[i]->size, fp);
  272. if (!WAD_AddLump(data, lumpinfolist[i]->size, lumpinfolist[i]->name))
  273. return false;
  274. i++;
  275. }
  276. // Close file
  277. fclose(fp);
  278. // go through lumpinfo list and free lumpinfo - we don't need them now
  279. i=0;
  280. while(lumpinfolist && i<numoflumpinfs)
  281. {
  282. free(lumpinfolist[i]);
  283. i++;
  284. }
  285. if (lumpinfolist)
  286. free(lumpinfolist);
  287. return true;
  288. }
  289. //
  290. // WAD_Shutdown
  291. //
  292. void WAD_Shutdown(void)
  293. {
  294. int i;
  295. // go through lump list and free lump
  296. i=0;
  297. while(lumplist && i<numoflumps)
  298. {
  299. free(lumplist[i]);
  300. i++;
  301. }
  302. if (lumplist)
  303. free(lumplist);
  304. return;
  305. }