gtkradiant/plugins/vfswad/unwad.cpp
TTimo 8037810110 transfer from internal tree r5311 branches/1.4-gpl
git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/branches/ZeroRadiant@177 8a3a26a2-13c4-0310-b231-cf6edde360e5
2007-09-12 18:54:28 +00:00

251 lines
5.8 KiB
C++

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#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;
}
*/