|
|
|
|
//========= Copyright <EFBFBD> 1996-2005, Valve LLC, All rights reserved. ============//
|
|
|
|
|
//
|
|
|
|
|
// Purpose:
|
|
|
|
|
//
|
|
|
|
|
// $NoKeywords: $
|
|
|
|
|
//
|
|
|
|
|
//=============================================================================//
|
|
|
|
|
// wad2lib.c
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <ctype.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
//#include <sys/file.h>
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
|
|
|
|
|
#ifdef NeXT
|
|
|
|
|
#include <libc.h>
|
|
|
|
|
#endif
|
|
|
|
|
#include "cmdlib.h"
|
|
|
|
|
#include "wadlib.h"
|
|
|
|
|
#include "commonmacros.h"
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
============================================================================
|
|
|
|
|
|
|
|
|
|
WAD READING
|
|
|
|
|
|
|
|
|
|
============================================================================
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lumpinfo_t *lumpinfo; // location of each lump on disk
|
|
|
|
|
int numlumps;
|
|
|
|
|
|
|
|
|
|
wadinfo_t header;
|
|
|
|
|
FILE *wadhandle;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
====================
|
|
|
|
|
W_OpenWad
|
|
|
|
|
====================
|
|
|
|
|
*/
|
|
|
|
|
void W_OpenWad (char *filename)
|
|
|
|
|
{
|
|
|
|
|
lumpinfo_t *lump_p;
|
|
|
|
|
unsigned i;
|
|
|
|
|
int length;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// open the file and add to directory
|
|
|
|
|
//
|
|
|
|
|
wadhandle = SafeOpenRead (filename);
|
|
|
|
|
SafeRead (wadhandle, &header, sizeof(header));
|
|
|
|
|
|
|
|
|
|
if (!STRING_MATCHES_ID(header.identification,WAD_ID))
|
|
|
|
|
Error ("Wad file %s doesn't have %s identifier\n",filename, WAD_IDNAME);
|
|
|
|
|
|
|
|
|
|
header.numlumps = LittleLong(header.numlumps);
|
|
|
|
|
header.infotableofs = LittleLong(header.infotableofs);
|
|
|
|
|
|
|
|
|
|
numlumps = header.numlumps;
|
|
|
|
|
|
|
|
|
|
length = numlumps*sizeof(lumpinfo_t);
|
|
|
|
|
lumpinfo = malloc (length);
|
|
|
|
|
lump_p = lumpinfo;
|
|
|
|
|
|
|
|
|
|
fseek (wadhandle, header.infotableofs, SEEK_SET);
|
|
|
|
|
SafeRead (wadhandle, lumpinfo, length);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Fill in lumpinfo
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
for (i=0 ; i<numlumps ; i++,lump_p++)
|
|
|
|
|
{
|
|
|
|
|
lump_p->filepos = LittleLong(lump_p->filepos);
|
|
|
|
|
lump_p->size = LittleLong(lump_p->size);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CleanupName (char *in, char *out)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i=0 ; i<sizeof( ((lumpinfo_t *)0)->name ) ; i++ )
|
|
|
|
|
{
|
|
|
|
|
if (!in[i])
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
out[i] = toupper(in[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for ( ; i<sizeof( ((lumpinfo_t *)0)->name ); i++ )
|
|
|
|
|
out[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
====================
|
|
|
|
|
W_CheckNumForName
|
|
|
|
|
|
|
|
|
|
Returns -1 if name not found
|
|
|
|
|
====================
|
|
|
|
|
*/
|
|
|
|
|
int W_CheckNumForName (char *name)
|
|
|
|
|
{
|
|
|
|
|
char cleanname[TEXTURE_NAME_LENGTH];
|
|
|
|
|
int v1,v2, v3, v4;
|
|
|
|
|
int i;
|
|
|
|
|
lumpinfo_t *lump_p;
|
|
|
|
|
|
|
|
|
|
CleanupName (name, cleanname);
|
|
|
|
|
|
|
|
|
|
// make the name into four integers for easy compares
|
|
|
|
|
|
|
|
|
|
v1 = *(int *)cleanname;
|
|
|
|
|
v2 = *(int *)&cleanname[4];
|
|
|
|
|
v3 = *(int *)&cleanname[8];
|
|
|
|
|
v4 = *(int *)&cleanname[12];
|
|
|
|
|
|
|
|
|
|
// find it
|
|
|
|
|
|
|
|
|
|
lump_p = lumpinfo;
|
|
|
|
|
for (i=0 ; i<numlumps ; i++, lump_p++)
|
|
|
|
|
{
|
|
|
|
|
if ( *(int *)lump_p->name == v1
|
|
|
|
|
&& *(int *)&lump_p->name[4] == v2
|
|
|
|
|
&& *(int *)&lump_p->name[8] == v3
|
|
|
|
|
&& *(int *)&lump_p->name[12] == v4
|
|
|
|
|
&& !strcmp( lump_p->name, cleanname ) )
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
====================
|
|
|
|
|
W_GetNumForName
|
|
|
|
|
|
|
|
|
|
Calls W_CheckNumForName, but bombs out if not found
|
|
|
|
|
====================
|
|
|
|
|
*/
|
|
|
|
|
int W_GetNumForName (char *name)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
i = W_CheckNumForName (name);
|
|
|
|
|
if (i != -1)
|
|
|
|
|
return i;
|
|
|
|
|
|
|
|
|
|
Error ("W_GetNumForName: %s not found!",name);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
====================
|
|
|
|
|
W_LumpLength
|
|
|
|
|
|
|
|
|
|
Returns the buffer size needed to load the given lump
|
|
|
|
|
====================
|
|
|
|
|
*/
|
|
|
|
|
int W_LumpLength (int lump)
|
|
|
|
|
{
|
|
|
|
|
if (lump >= numlumps)
|
|
|
|
|
Error ("W_LumpLength: %i >= numlumps",lump);
|
|
|
|
|
return lumpinfo[lump].size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
====================
|
|
|
|
|
W_ReadLumpNum
|
|
|
|
|
|
|
|
|
|
Loads the lump into the given buffer, which must be >= W_LumpLength()
|
|
|
|
|
====================
|
|
|
|
|
*/
|
|
|
|
|
void W_ReadLumpNum (int lump, void *dest)
|
|
|
|
|
{
|
|
|
|
|
lumpinfo_t *l;
|
|
|
|
|
|
|
|
|
|
if (lump >= numlumps)
|
|
|
|
|
Error ("W_ReadLump: %i >= numlumps",lump);
|
|
|
|
|
l = lumpinfo+lump;
|
|
|
|
|
|
|
|
|
|
fseek (wadhandle, l->filepos, SEEK_SET);
|
|
|
|
|
SafeRead (wadhandle, dest, l->size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
====================
|
|
|
|
|
W_LoadLumpNum
|
|
|
|
|
====================
|
|
|
|
|
*/
|
|
|
|
|
void *W_LoadLumpNum (int lump)
|
|
|
|
|
{
|
|
|
|
|
void *buf;
|
|
|
|
|
|
|
|
|
|
if ((unsigned)lump >= numlumps)
|
|
|
|
|
Error ("W_CacheLumpNum: %i >= numlumps",lump);
|
|
|
|
|
|
|
|
|
|
buf = malloc (W_LumpLength (lump));
|
|
|
|
|
W_ReadLumpNum (lump, buf);
|
|
|
|
|
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
====================
|
|
|
|
|
W_LoadLumpName
|
|
|
|
|
====================
|
|
|
|
|
*/
|
|
|
|
|
void *W_LoadLumpName (char *name)
|
|
|
|
|
{
|
|
|
|
|
return W_LoadLumpNum (W_GetNumForName(name));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
===============================================================================
|
|
|
|
|
|
|
|
|
|
WAD CREATION
|
|
|
|
|
|
|
|
|
|
===============================================================================
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
FILE *outwad;
|
|
|
|
|
|
|
|
|
|
lumpinfo_t outinfo[4096];
|
|
|
|
|
int outlumps;
|
|
|
|
|
|
|
|
|
|
short (*wadshort) (short l);
|
|
|
|
|
int (*wadlong) (int l);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
===============
|
|
|
|
|
NewWad
|
|
|
|
|
===============
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void NewWad (char *pathname, qboolean bigendien)
|
|
|
|
|
{
|
|
|
|
|
outwad = SafeOpenWrite (pathname);
|
|
|
|
|
fseek (outwad, sizeof(wadinfo_t), SEEK_SET);
|
|
|
|
|
memset (outinfo, 0, sizeof(outinfo));
|
|
|
|
|
|
|
|
|
|
if (bigendien)
|
|
|
|
|
{
|
|
|
|
|
wadshort = BigShort;
|
|
|
|
|
wadlong = BigLong;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
wadshort = LittleShort;
|
|
|
|
|
wadlong = LittleLong;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
outlumps = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
===============
|
|
|
|
|
AddLump
|
|
|
|
|
===============
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void AddLump (char *name, void *buffer, int length, int type, int compress)
|
|
|
|
|
{
|
|
|
|
|
lumpinfo_t *info;
|
|
|
|
|
int ofs;
|
|
|
|
|
|
|
|
|
|
info = &outinfo[outlumps];
|
|
|
|
|
outlumps++;
|
|
|
|
|
|
|
|
|
|
memset (info,0,sizeof(info));
|
|
|
|
|
|
|
|
|
|
strcpy (info->name, name);
|
|
|
|
|
Q_strupr (info->name);
|
|
|
|
|
|
|
|
|
|
ofs = ftell(outwad);
|
|
|
|
|
info->filepos = wadlong(ofs);
|
|
|
|
|
info->size = info->disksize = wadlong(length);
|
|
|
|
|
info->type = type;
|
|
|
|
|
info->compression = compress;
|
|
|
|
|
|
|
|
|
|
// FIXME: do compression
|
|
|
|
|
|
|
|
|
|
SafeWrite (outwad, buffer, length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
===============
|
|
|
|
|
WriteWad
|
|
|
|
|
===============
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void WriteWad (int wad3)
|
|
|
|
|
{
|
|
|
|
|
wadinfo_t header;
|
|
|
|
|
int ofs;
|
|
|
|
|
|
|
|
|
|
// write the lumpingo
|
|
|
|
|
ofs = ftell(outwad);
|
|
|
|
|
|
|
|
|
|
SafeWrite (outwad, outinfo, outlumps*sizeof(lumpinfo_t) );
|
|
|
|
|
|
|
|
|
|
// write the header
|
|
|
|
|
|
|
|
|
|
// a program will be able to tell the ednieness of a wad by the id
|
|
|
|
|
ID_TO_STRING( WAD_ID, header.identification );
|
|
|
|
|
|
|
|
|
|
header.numlumps = wadlong(outlumps);
|
|
|
|
|
header.infotableofs = wadlong(ofs);
|
|
|
|
|
|
|
|
|
|
fseek (outwad, 0, SEEK_SET);
|
|
|
|
|
SafeWrite (outwad, &header, sizeof(header));
|
|
|
|
|
fclose (outwad);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|