2012-06-05 04:42:31 +00:00
|
|
|
/*
|
|
|
|
Copyright (C) 1999-2007 id Software, Inc. and contributors.
|
|
|
|
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
|
|
|
|
|
|
|
This file is part of GtkRadiant.
|
|
|
|
|
|
|
|
GtkRadiant is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
GtkRadiant is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with GtkRadiant; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
2007-11-04 03:51:54 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "unwad.h"
|
|
|
|
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
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;
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
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()
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( fread( wf->lpLump,sizeof( WAD3_LUMP ),1,wf->fin ) != 1 ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
return 0;
|
2012-03-17 20:01:54 +00:00
|
|
|
}
|
|
|
|
strncpy( szFileName, wf->lpLump->name, fileNameBufferSize );
|
|
|
|
szFileName[fileNameBufferSize - 1] = 0; // null terminate
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
*filesize = wf->lpLump->size;
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
return 1;
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
int wadGoToFile( wadFile_t *wf, unsigned long filenum ){
|
|
|
|
if ( !wf ) {
|
|
|
|
return 0;
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( !wf->fin ) {
|
|
|
|
return 0;
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( filenum >= wf->lpHeader->numlumps ) {
|
|
|
|
return 0;
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( fseek( wf->fin,wf->lpHeader->infotableofs + ( filenum * sizeof( WAD3_LUMP ) ),SEEK_SET ) != 0 ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
return 0;
|
2012-03-17 20:01:54 +00:00
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
wf->currentfile = filenum;
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
return 1;
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
int wadGoToNextFile( wadFile_t *wf ){
|
|
|
|
return( wadGoToFile( wf, wf->currentfile + 1 ) );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
int wadGoToFirstFile( wadFile_t *wf ){
|
|
|
|
/* returns 0 if error, or 1 for sucess */
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( !wf ) {
|
|
|
|
return 0;
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( !wf->fin ) {
|
|
|
|
return 0;
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( fseek( wf->fin,wf->lpHeader->infotableofs,SEEK_SET ) != 0 ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
return 0;
|
2012-03-17 20:01:54 +00:00
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
wf->currentfile = 0;
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
return 1;
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
wadFile_t *wadOpen( const char* path ){
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
wadFile_t *wf = NULL;
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( !path ) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
wf = new wadFile_s;
|
|
|
|
memset( wf, 0, sizeof( *wf ) );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( !wf ) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
wf->fin = fopen( path,"rb" );
|
|
|
|
if ( wf->fin == NULL ) {
|
|
|
|
return wadCleanup( wf );
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
// get the file size
|
|
|
|
if ( fseek( wf->fin,0,SEEK_END ) != 0 ) {
|
|
|
|
return wadCleanup( wf );
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
wf->FileSize = ftell( wf->fin );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
// Make sure it's at least big enough to manipulate the header
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( wf->FileSize < sizeof( WAD3_HEADER ) ) {
|
|
|
|
// WAD3 file is malformed.
|
|
|
|
return wadCleanup( wf );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
// go back to the start
|
|
|
|
if ( fseek( wf->fin,0,SEEK_SET ) != 0 ) {
|
|
|
|
return wadCleanup( wf );
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
// 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 ) );
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( !( wf->lpHeader ) || !( wf->lpLump ) || !( wf->lpMip ) ) {
|
|
|
|
return wadCleanup( wf );
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
// read the header.
|
|
|
|
if ( fread( wf->lpHeader,sizeof( WAD3_HEADER ),1,wf->fin ) != 1 ) {
|
|
|
|
return wadCleanup( wf );
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( wf->lpHeader->identification != WAD2_ID && wf->lpHeader->identification != WAD3_ID ) {
|
|
|
|
// Invalid WAD3 header id.
|
|
|
|
return wadCleanup( wf );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure our table is really there
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( ( ( wf->lpHeader->numlumps * sizeof( WAD3_LUMP ) ) + wf->lpHeader->infotableofs ) > wf->FileSize ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
// WAD3 file is malformed.
|
2012-03-17 20:01:54 +00:00
|
|
|
return wadCleanup( wf );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
// Store the name of the wadfile
|
|
|
|
if ( !( wf->wadfilename = strdup( path ) ) ) {
|
|
|
|
return wadCleanup( wf );
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
return wf;
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
int wadOpenCurrentFileByNum( wadFile_t *wf, unsigned long filenumber ){
|
|
|
|
/* returns 0 if error, or 1 for sucess */
|
|
|
|
return( wadGoToFile( wf, filenumber ) );
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
void wadCloseCurrentFile( wadFile_t *wf ){
|
|
|
|
// nothing to do really...
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
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 ) {
|
2007-11-04 03:51:54 +00:00
|
|
|
return 0;
|
2012-03-17 20:01:54 +00:00
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
// 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;
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
// go to first mip
|
|
|
|
if ( fseek( wf->fin, wf->lpLump->filepos, SEEK_SET ) != 0 ) {
|
|
|
|
return 0;
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if ( fread( bufferptr,size,1,wf->fin ) == 1 ) {
|
|
|
|
return ( size );
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
return 0;
|
|
|
|
}
|
2007-11-04 03:51:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
.. or we could do it the long way, and process the file as we go..
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
*/
|
2007-11-04 03:51:54 +00:00
|
|
|
/*
|
2012-03-17 20:01:54 +00:00
|
|
|
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;
|
2007-11-04 03:51:54 +00:00
|
|
|
|
2012-03-17 20:01:54 +00:00
|
|
|
if (fread(wf->lpLump,sizeof(WAD3_LUMP),1,wf->fin)!=1)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (wf->lpLump->type == WAD3_TYPE_MIP) // can we handle it ?
|
|
|
|
{
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
// 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)
|
2012-03-17 20:01:54 +00:00
|
|
|
return 0;
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
// 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)
|
2012-03-17 20:01:54 +00:00
|
|
|
return 0;
|
2007-11-04 03:51:54 +00:00
|
|
|
|
|
|
|
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.
|
2012-03-17 20:01:54 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
*/
|