mirror of
https://github.com/UberGames/GtkRadiant.git
synced 2024-12-19 08:51:34 +00:00
33efc90892
git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/branches/ZeroRadiant@185 8a3a26a2-13c4-0310-b231-cf6edde360e5
251 lines
5.5 KiB
C++
251 lines
5.5 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;
|
|
}
|
|
*/
|