]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - plugins/vfswad/unwad.cpp
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / plugins / vfswad / unwad.cpp
1 #include <stdlib.h>\r
2 #include <stdio.h>\r
3 #include <string.h>\r
4 \r
5 #include "unwad.h"\r
6 \r
7 \r
8 wadFile_t *wadCleanup(wadFile_t *wf)\r
9 {\r
10   if (wf)\r
11   {\r
12     if (wf->fin) fclose(wf->fin);\r
13     if (wf->lpHeader) free(wf->lpHeader);\r
14     if (wf->lpLump) free(wf->lpLump);\r
15     if (wf->lpMip) free(wf->lpMip);\r
16     if (wf->wadfilename) free(wf->wadfilename);\r
17     free (wf);\r
18     wf = NULL;\r
19   }\r
20   return wf;\r
21 }\r
22 \r
23 int wadGetCurrentFileInfo (     wadFile_t *wf, char *szFileName, unsigned long fileNameBufferSize, unsigned long *filesize)\r
24 {\r
25   /* returns 0 if error, or 1 for sucess */\r
26   // if this fails you'll need to re-position the fileposition\r
27   // before attempting any other calls.  e.g. call wadGoToFirstFile()\r
28 \r
29   if (fread(wf->lpLump,sizeof(WAD3_LUMP),1,wf->fin)!=1)\r
30                 return 0;\r
31   strncpy(szFileName, wf->lpLump->name, fileNameBufferSize);\r
32   szFileName[fileNameBufferSize-1] = 0; // null terminate\r
33 \r
34   *filesize = wf->lpLump->size;\r
35 \r
36   return 1;\r
37 }\r
38 \r
39 int wadGoToFile(wadFile_t *wf, unsigned long filenum)\r
40 {\r
41   if (!wf)\r
42     return 0;\r
43 \r
44   if (!wf->fin)\r
45     return 0;\r
46 \r
47   if (filenum >= wf->lpHeader->numlumps)\r
48     return 0;\r
49 \r
50   if (fseek(wf->fin,wf->lpHeader->infotableofs + (filenum * sizeof(WAD3_LUMP)),SEEK_SET) != 0)\r
51                 return 0;\r
52 \r
53   wf->currentfile = filenum;\r
54 \r
55   return 1;\r
56 }\r
57 \r
58 int wadGoToNextFile(wadFile_t *wf)\r
59 {\r
60   return(wadGoToFile(wf, wf->currentfile + 1));\r
61 }\r
62 \r
63 int wadGoToFirstFile(wadFile_t *wf)\r
64 {\r
65   /* returns 0 if error, or 1 for sucess */\r
66 \r
67   if (!wf)\r
68     return 0;\r
69 \r
70   if (!wf->fin)\r
71     return 0;\r
72 \r
73   if (fseek(wf->fin,wf->lpHeader->infotableofs,SEEK_SET) != 0)\r
74                 return 0;\r
75 \r
76   wf->currentfile = 0;\r
77 \r
78   return 1;\r
79 }\r
80 \r
81 wadFile_t *wadOpen(const char* path)\r
82 {\r
83 \r
84   wadFile_t *wf = NULL;\r
85 \r
86   if (!path)\r
87     return NULL;\r
88 \r
89   wf = new wadFile_s;\r
90         memset (wf, 0, sizeof(*wf));\r
91 \r
92   if (!wf)\r
93     return NULL;\r
94 \r
95   wf->fin=fopen(path,"rb");\r
96         if (wf->fin==NULL)\r
97                 return wadCleanup(wf);\r
98 \r
99   // get the file size\r
100         if (fseek(wf->fin,0,SEEK_END) != 0)\r
101                 return wadCleanup(wf);\r
102 \r
103   wf->FileSize = ftell( wf->fin );\r
104 \r
105         // Make sure it's at least big enough to manipulate the header\r
106         if (wf->FileSize < sizeof(WAD3_HEADER))\r
107         {\r
108     // WAD3 file is malformed.\r
109                 return wadCleanup(wf);\r
110         }\r
111 \r
112   // go back to the start\r
113   if (fseek(wf->fin,0,SEEK_SET)!=0)\r
114                 return wadCleanup(wf);\r
115 \r
116   // allocate buffers\r
117   wf->lpHeader = (LPWAD3_HEADER) malloc(sizeof(WAD3_HEADER));\r
118   wf->lpLump = (LPWAD3_LUMP) malloc(sizeof(WAD3_LUMP));\r
119   wf->lpMip = (LPWAD3_MIP) malloc(sizeof(WAD3_MIP));\r
120 \r
121   if (!(wf->lpHeader) || !(wf->lpLump) || !(wf->lpMip))\r
122     return wadCleanup(wf);\r
123 \r
124   // read the header.\r
125   if (fread(wf->lpHeader,sizeof(WAD3_HEADER),1,wf->fin)!=1)\r
126                 return wadCleanup(wf);\r
127 \r
128         if (wf->lpHeader->identification != WAD2_ID && wf->lpHeader->identification != WAD3_ID)\r
129         {\r
130         // Invalid WAD3 header id.\r
131                 return wadCleanup(wf);\r
132         }\r
133 \r
134         // Make sure our table is really there\r
135         if ( ((wf->lpHeader->numlumps * sizeof(WAD3_LUMP)) + wf->lpHeader->infotableofs) > wf->FileSize)\r
136         {\r
137                 // WAD3 file is malformed.\r
138                 return wadCleanup(wf);\r
139         }\r
140 \r
141   // Store the name of the wadfile\r
142   if (!(wf->wadfilename = strdup(path)))\r
143     return wadCleanup(wf);\r
144 \r
145   return wf;\r
146 }\r
147 \r
148 int wadOpenCurrentFileByNum (wadFile_t *wf, unsigned long filenumber)\r
149 {\r
150   /* returns 0 if error, or 1 for sucess */\r
151   return(wadGoToFile(wf, filenumber));\r
152 }\r
153 \r
154 void wadCloseCurrentFile (wadFile_t *wf)\r
155 {\r
156   // nothing to do really...\r
157 }\r
158 \r
159 unsigned long wadReadCurrentFile (wadFile_t *wf , char *bufferptr, unsigned long size)\r
160 {\r
161   // returns 0 if error, or the amount of data read into the buffer\r
162   if (fread(wf->lpLump,sizeof(WAD3_LUMP),1,wf->fin)!=1)\r
163                 return 0;\r
164 \r
165   // dunno how to handle any other image types but this (yet)\r
166   if (wf->lpLump->type != WAD2_TYPE_MIP && wf->lpLump->type != WAD3_TYPE_MIP)\r
167     return 0;\r
168 \r
169   // go to first mip\r
170   if (fseek(wf->fin, wf->lpLump->filepos, SEEK_SET) != 0)\r
171     return 0;\r
172 \r
173   if (fread(bufferptr,size,1,wf->fin) == 1)\r
174     return (size);\r
175   else\r
176     return 0;\r
177 }\r
178 \r
179 /*\r
180 \r
181 .. or we could do it the long way, and process the file as we go..\r
182 \r
183 \r
184 */\r
185 /*\r
186 unsigned long wadReadCurrentFile (wadFile_t *wf , char *bufferptr, unsigned long size)\r
187 {\r
188   // returns 0 if error, or the amount of data read into the buffer\r
189   unsigned long bufferpos;\r
190   unsigned long mipdatasize;\r
191   WORD palettesize;\r
192 \r
193   if (fread(wf->lpLump,sizeof(WAD3_LUMP),1,wf->fin)!=1)\r
194                 return 0;\r
195 \r
196   if (wf->lpLump->type == WAD3_TYPE_MIP) // can we handle it ?\r
197   {\r
198 \r
199     // bounds check.\r
200     if (wf->lpLump->filepos >= wf->FileSize)\r
201       return 0; // malformed wad3\r
202 \r
203     // go to first mip\r
204     if (fseek(wf->fin, wf->lpLump->filepos, SEEK_SET) != 0)\r
205                 return 0;\r
206 \r
207     // and read it\r
208     if (fread(wf->lpMip,sizeof(WAD3_MIP),1,wf->fin)!=1)\r
209       return 0;\r
210 \r
211     // store in buffer.\r
212     memcpy(bufferptr, wf->lpMip, sizeof(WAD3_MIP));\r
213     bufferpos = sizeof(WAD3_MIP);\r
214 \r
215     // now read the MIP data.\r
216     // mip data\r
217     if (fseek(wf->fin, wf->lpLump->filepos + wf->lpMip->offsets[0], SEEK_SET) != 0)\r
218                 return 0;\r
219 \r
220     mipdatasize = GET_MIP_DATA_SIZE(wf->lpMip->width,wf->lpMip->height);\r
221 \r
222     if (fread(bufferptr+bufferpos, mipdatasize, 1, wf->fin)!=1)\r
223       return 0;\r
224 \r
225     bufferpos += mipdatasize;\r
226 \r
227     // ok, that's the mip data itself, now grab the palette size.\r
228     if (fread(bufferptr+bufferpos,sizeof(WORD),1,wf->fin)!=1)\r
229       return 0;\r
230 \r
231     palettesize = *(WORD *)(bufferptr+bufferpos);\r
232 \r
233     bufferpos += sizeof(WORD);\r
234 \r
235     // grab the palette itself\r
236     if (fread(bufferptr+bufferpos,palettesize*3,1,wf->fin)!=1)\r
237       return 0;\r
238 \r
239     bufferpos += palettesize*3;\r
240 \r
241     // and finally the one-word padding.\r
242     if (fread(bufferptr+bufferpos,sizeof(WORD),1,wf->fin)!=1)\r
243       return 0;\r
244 \r
245     bufferpos += sizeof(WORD);\r
246 \r
247     return(bufferpos); // return the amount of bytes read.\r
248   }\r
249   return 0;\r
250 }\r
251 */\r