#include #include #include #include "unwad.h" wadFile_t *wadCleanup(wadFile_t *wf) { if (wf) { if (wf->fin) fclose(wf->fin); if (wf->lpHeader) free(wf->lpHeader); if (wf->lpLump) free(wf->lpLump); if (wf->lpMip) free(wf->lpMip); if (wf->wadfilename) free(wf->wadfilename); free (wf); wf = NULL; } return wf; } int wadGetCurrentFileInfo ( wadFile_t *wf, char *szFileName, unsigned long fileNameBufferSize, unsigned long *filesize) { /* returns 0 if error, or 1 for sucess */ // if this fails you'll need to re-position the fileposition // before attempting any other calls. e.g. call wadGoToFirstFile() if (fread(wf->lpLump,sizeof(WAD3_LUMP),1,wf->fin)!=1) return 0; strncpy(szFileName, wf->lpLump->name, fileNameBufferSize); szFileName[fileNameBufferSize-1] = 0; // null terminate *filesize = wf->lpLump->size; return 1; } int wadGoToFile(wadFile_t *wf, unsigned long filenum) { if (!wf) return 0; if (!wf->fin) return 0; if (filenum >= wf->lpHeader->numlumps) return 0; if (fseek(wf->fin,wf->lpHeader->infotableofs + (filenum * sizeof(WAD3_LUMP)),SEEK_SET) != 0) return 0; wf->currentfile = filenum; return 1; } int wadGoToNextFile(wadFile_t *wf) { return(wadGoToFile(wf, wf->currentfile + 1)); } int wadGoToFirstFile(wadFile_t *wf) { /* returns 0 if error, or 1 for sucess */ if (!wf) return 0; if (!wf->fin) return 0; if (fseek(wf->fin,wf->lpHeader->infotableofs,SEEK_SET) != 0) return 0; wf->currentfile = 0; return 1; } wadFile_t *wadOpen(const char* path) { wadFile_t *wf = NULL; if (!path) return NULL; wf = new wadFile_s; memset (wf, 0, sizeof(*wf)); if (!wf) return NULL; wf->fin=fopen(path,"rb"); if (wf->fin==NULL) return wadCleanup(wf); // get the file size if (fseek(wf->fin,0,SEEK_END) != 0) return wadCleanup(wf); wf->FileSize = ftell( wf->fin ); // Make sure it's at least big enough to manipulate the header if (wf->FileSize < sizeof(WAD3_HEADER)) { // WAD3 file is malformed. return wadCleanup(wf); } // go back to the start if (fseek(wf->fin,0,SEEK_SET)!=0) return wadCleanup(wf); // allocate buffers wf->lpHeader = (LPWAD3_HEADER) malloc(sizeof(WAD3_HEADER)); wf->lpLump = (LPWAD3_LUMP) malloc(sizeof(WAD3_LUMP)); wf->lpMip = (LPWAD3_MIP) malloc(sizeof(WAD3_MIP)); if (!(wf->lpHeader) || !(wf->lpLump) || !(wf->lpMip)) return wadCleanup(wf); // read the header. if (fread(wf->lpHeader,sizeof(WAD3_HEADER),1,wf->fin)!=1) return wadCleanup(wf); if (wf->lpHeader->identification != WAD2_ID && wf->lpHeader->identification != WAD3_ID) { // Invalid WAD3 header id. return wadCleanup(wf); } // Make sure our table is really there if ( ((wf->lpHeader->numlumps * sizeof(WAD3_LUMP)) + wf->lpHeader->infotableofs) > wf->FileSize) { // WAD3 file is malformed. return wadCleanup(wf); } // Store the name of the wadfile if (!(wf->wadfilename = strdup(path))) return wadCleanup(wf); return wf; } int wadOpenCurrentFileByNum (wadFile_t *wf, unsigned long filenumber) { /* returns 0 if error, or 1 for sucess */ return(wadGoToFile(wf, filenumber)); } void wadCloseCurrentFile (wadFile_t *wf) { // nothing to do really... } unsigned long wadReadCurrentFile (wadFile_t *wf , char *bufferptr, unsigned long size) { // returns 0 if error, or the amount of data read into the buffer if (fread(wf->lpLump,sizeof(WAD3_LUMP),1,wf->fin)!=1) return 0; // dunno how to handle any other image types but this (yet) if (wf->lpLump->type != WAD2_TYPE_MIP && wf->lpLump->type != WAD3_TYPE_MIP) return 0; // go to first mip if (fseek(wf->fin, wf->lpLump->filepos, SEEK_SET) != 0) return 0; if (fread(bufferptr,size,1,wf->fin) == 1) return (size); else return 0; } /* .. or we could do it the long way, and process the file as we go.. */ /* unsigned long wadReadCurrentFile (wadFile_t *wf , char *bufferptr, unsigned long size) { // returns 0 if error, or the amount of data read into the buffer unsigned long bufferpos; unsigned long mipdatasize; WORD palettesize; if (fread(wf->lpLump,sizeof(WAD3_LUMP),1,wf->fin)!=1) return 0; if (wf->lpLump->type == WAD3_TYPE_MIP) // can we handle it ? { // bounds check. if (wf->lpLump->filepos >= wf->FileSize) return 0; // malformed wad3 // go to first mip if (fseek(wf->fin, wf->lpLump->filepos, SEEK_SET) != 0) return 0; // and read it if (fread(wf->lpMip,sizeof(WAD3_MIP),1,wf->fin)!=1) return 0; // store in buffer. memcpy(bufferptr, wf->lpMip, sizeof(WAD3_MIP)); bufferpos = sizeof(WAD3_MIP); // now read the MIP data. // mip data if (fseek(wf->fin, wf->lpLump->filepos + wf->lpMip->offsets[0], SEEK_SET) != 0) return 0; mipdatasize = GET_MIP_DATA_SIZE(wf->lpMip->width,wf->lpMip->height); if (fread(bufferptr+bufferpos, mipdatasize, 1, wf->fin)!=1) return 0; bufferpos += mipdatasize; // ok, that's the mip data itself, now grab the palette size. if (fread(bufferptr+bufferpos,sizeof(WORD),1,wf->fin)!=1) return 0; palettesize = *(WORD *)(bufferptr+bufferpos); bufferpos += sizeof(WORD); // grab the palette itself if (fread(bufferptr+bufferpos,palettesize*3,1,wf->fin)!=1) return 0; bufferpos += palettesize*3; // and finally the one-word padding. if (fread(bufferptr+bufferpos,sizeof(WORD),1,wf->fin)!=1) return 0; bufferpos += sizeof(WORD); return(bufferpos); // return the amount of bytes read. } return 0; } */