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