|
|
//========= Copyright � 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); }
|