2007-12-20 22:00:00 +01:00
|
|
|
|
//=======================================================================
|
|
|
|
|
// Copyright XashXT Group 2007 <20>
|
|
|
|
|
// wadlib.c.c - wad archive compiler
|
|
|
|
|
//=======================================================================
|
|
|
|
|
|
|
|
|
|
#include "platform.h"
|
|
|
|
|
#include "utils.h"
|
|
|
|
|
|
|
|
|
|
char wadoutname[MAX_SYSPATH];
|
|
|
|
|
static dlumpinfo_t wadlumps[MAX_FILES_IN_PACK];
|
|
|
|
|
static char lumpname[MAX_SYSPATH];
|
|
|
|
|
dwadinfo_t wadfile; // main header
|
|
|
|
|
int wadheader;
|
|
|
|
|
int numlumps = 0;
|
|
|
|
|
bool compress_lumps = false;
|
2007-12-21 22:00:00 +01:00
|
|
|
|
bool allow_compression = false;
|
2007-12-20 22:00:00 +01:00
|
|
|
|
file_t *handle = NULL;
|
|
|
|
|
|
|
|
|
|
void Wad3_NewWad( void )
|
|
|
|
|
{
|
|
|
|
|
handle = FS_Open( wadoutname, "wb" );
|
|
|
|
|
|
|
|
|
|
if(!handle) Sys_Break("Wad3_NewWad: can't create %s\n", wadoutname );
|
|
|
|
|
FS_Write( handle, &wadfile, sizeof(wadfile));
|
|
|
|
|
memset( wadlumps, 0, sizeof(wadlumps));
|
|
|
|
|
numlumps = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2007-12-21 22:00:00 +01:00
|
|
|
|
int Lump_GetFileType( const char *name, byte *buf )
|
|
|
|
|
{
|
|
|
|
|
const char *ext = FS_FileExtension( name );
|
|
|
|
|
|
|
|
|
|
if(!buf) return TYPE_NONE;
|
|
|
|
|
|
2008-01-04 22:00:00 +01:00
|
|
|
|
// get file type by extension
|
2007-12-21 22:00:00 +01:00
|
|
|
|
if(!com.stricmp( ext, "tga" )) return TYPE_MIPTGA;
|
|
|
|
|
else if(!com.stricmp( ext, "mip" ))
|
|
|
|
|
{
|
|
|
|
|
if(wadheader == IDWAD3HEADER)
|
|
|
|
|
return TYPE_MIPTEX2; // half-life texture
|
|
|
|
|
return TYPE_MIPTEX; // quake1 texture
|
|
|
|
|
}
|
2008-01-04 22:00:00 +01:00
|
|
|
|
else if(!com.stricmp( ext, "dds" )) return TYPE_MIPDDS; // ms dds
|
|
|
|
|
else if(!com.stricmp( ext, "mdl" )) return TYPE_STUDIO; // hl mdl
|
|
|
|
|
else if(!com.stricmp( ext, "spr" )) return TYPE_SPRITE; // spr32
|
2007-12-21 22:00:00 +01:00
|
|
|
|
else if(!com.stricmp( ext, "lmp" )) return TYPE_QPIC; // hud pics
|
|
|
|
|
else if(!com.stricmp( ext, "pal" )) return TYPE_QPAL; // palette
|
|
|
|
|
else if(!com.stricmp( ext, "wav" )) return TYPE_SOUND; // wav sound
|
|
|
|
|
else if(!com.stricmp( ext, "txt" )) return TYPE_SCRIPT; // text file
|
|
|
|
|
else if(!com.stricmp( ext, "dat" )) return TYPE_VPROGS; // qc progs
|
|
|
|
|
else if(!com.stricmp( ext, "raw" )) return TYPE_RAW; // raw data
|
|
|
|
|
else if(!com.stricmp( ext, "ent" )) return TYPE_ENTFILE; // ents file
|
|
|
|
|
|
|
|
|
|
// no compares found
|
|
|
|
|
return TYPE_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
2007-12-20 22:00:00 +01:00
|
|
|
|
/*
|
|
|
|
|
===============
|
|
|
|
|
AddLump
|
|
|
|
|
===============
|
|
|
|
|
*/
|
2007-12-21 22:00:00 +01:00
|
|
|
|
void Wad3_AddLump( const char *name, bool compress )
|
2007-12-20 22:00:00 +01:00
|
|
|
|
{
|
|
|
|
|
dlumpinfo_t *info;
|
2007-12-21 22:00:00 +01:00
|
|
|
|
byte *buffer;
|
|
|
|
|
int ofs, type, length;
|
|
|
|
|
|
|
|
|
|
Msg("Add lump %s\n", name );
|
|
|
|
|
|
|
|
|
|
// we can load file from another wad
|
|
|
|
|
buffer = FS_LoadFile( name, &length );
|
|
|
|
|
type = Lump_GetFileType( name, buffer );
|
2007-12-20 22:00:00 +01:00
|
|
|
|
|
2007-12-21 22:00:00 +01:00
|
|
|
|
if(!buffer)
|
2007-12-20 22:00:00 +01:00
|
|
|
|
{
|
|
|
|
|
MsgWarn("Wad3_AddLump: file %s not found\n", name );
|
|
|
|
|
return;
|
|
|
|
|
}
|
2007-12-21 22:00:00 +01:00
|
|
|
|
if(type == TYPE_NONE)
|
|
|
|
|
{
|
|
|
|
|
MsgWarn("Wad3_AddLump: file %s have unsupported type\n", name );
|
|
|
|
|
return;
|
|
|
|
|
}
|
2007-12-20 22:00:00 +01:00
|
|
|
|
|
2008-01-02 22:00:00 +01:00
|
|
|
|
FS_FileBase( name, lumpname );
|
2007-12-20 22:00:00 +01:00
|
|
|
|
if(strlen(lumpname) > WAD3_NAMELEN)
|
|
|
|
|
{
|
|
|
|
|
MsgWarn("Wad3_AddLump: %s have too long name, max %d symbols\n", lumpname, WAD3_NAMELEN );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// create wad file
|
|
|
|
|
if(!handle) Wad3_NewWad();
|
|
|
|
|
|
|
|
|
|
info = &wadlumps[numlumps];
|
|
|
|
|
com.strncpy( info->name, lumpname, WAD3_NAMELEN );
|
|
|
|
|
com.strupr( info->name, info->name );
|
|
|
|
|
ofs = FS_Tell( handle );
|
|
|
|
|
info->filepos = LittleLong( ofs );
|
|
|
|
|
info->type = (char)type;
|
|
|
|
|
numlumps++; // increase lump number
|
|
|
|
|
|
|
|
|
|
if( compress )
|
|
|
|
|
{
|
|
|
|
|
vfile_t *h = VFS_Open( handle, "wz" );
|
|
|
|
|
info->compression = CMP_ZLIB;
|
|
|
|
|
info->size = length; // realsize
|
|
|
|
|
VFS_Write( h, buffer, length );
|
|
|
|
|
handle = VFS_Close( h ); // go back to real filesystem
|
|
|
|
|
ofs = FS_Tell( handle ); // ofs - info->filepos returns compressed size
|
|
|
|
|
info->disksize = LittleLong( ofs - info->filepos );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
info->compression = CMP_NONE;
|
|
|
|
|
info->size = info->disksize = LittleLong( length );
|
|
|
|
|
FS_Write( handle, buffer, length ); // just write file
|
|
|
|
|
}
|
2007-12-21 22:00:00 +01:00
|
|
|
|
Mem_Free( buffer );
|
2007-12-20 22:00:00 +01:00
|
|
|
|
MsgDev(D_NOTE, "AddLump: %s, size %d\n", info->name, info->disksize );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Cmd_WadName( void )
|
|
|
|
|
{
|
|
|
|
|
com.strncpy( wadoutname, Com_GetToken(false), sizeof(wadoutname));
|
|
|
|
|
FS_DefaultExtension( wadoutname, ".wad" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Cmd_WadType( void )
|
|
|
|
|
{
|
|
|
|
|
Com_GetToken( false );
|
|
|
|
|
|
2007-12-21 22:00:00 +01:00
|
|
|
|
if(Com_MatchToken( "Quake1") || Com_MatchToken( "Q1"))
|
|
|
|
|
{
|
|
|
|
|
wadheader = IDWAD2HEADER;
|
|
|
|
|
}
|
|
|
|
|
else if(Com_MatchToken( "Half-Life") || Com_MatchToken( "Hl1"))
|
|
|
|
|
{
|
|
|
|
|
wadheader = IDWAD3HEADER;
|
|
|
|
|
}
|
|
|
|
|
else if(Com_MatchToken( "Xash3D"))
|
|
|
|
|
{
|
|
|
|
|
wadheader = IDWAD4HEADER;
|
|
|
|
|
}
|
2007-12-20 22:00:00 +01:00
|
|
|
|
else wadheader = IDWAD3HEADER; // default
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Cmd_AddLump( void )
|
|
|
|
|
{
|
|
|
|
|
char filename[MAX_SYSPATH];
|
|
|
|
|
bool compress = false;
|
|
|
|
|
|
|
|
|
|
Com_GetToken( false );
|
|
|
|
|
com.strncpy( filename, com_token, sizeof(filename));
|
|
|
|
|
|
2007-12-21 22:00:00 +01:00
|
|
|
|
if( allow_compression )
|
|
|
|
|
{
|
|
|
|
|
if(Com_TryToken()) compress = true;
|
|
|
|
|
if(compress_lumps) compress = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Wad3_AddLump( filename, compress );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Cmd_AddLumps( void )
|
|
|
|
|
{
|
|
|
|
|
int i, compress = false;
|
|
|
|
|
search_t *t;
|
|
|
|
|
|
|
|
|
|
Com_GetToken( false );
|
|
|
|
|
t = FS_Search( com_token, true );
|
|
|
|
|
if(!t) return;
|
|
|
|
|
|
|
|
|
|
if( allow_compression )
|
|
|
|
|
{
|
|
|
|
|
if(Com_TryToken()) compress = true;
|
|
|
|
|
if(compress_lumps) compress = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < t->numfilenames; i++)
|
|
|
|
|
{
|
|
|
|
|
Wad3_AddLump( t->filenames[i], compress );
|
|
|
|
|
}
|
2007-12-20 22:00:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
==============
|
|
|
|
|
Cmd_WadCompress
|
|
|
|
|
|
|
|
|
|
syntax: "$compression"
|
|
|
|
|
==============
|
|
|
|
|
*/
|
|
|
|
|
void Cmd_WadCompress( void )
|
|
|
|
|
{
|
2007-12-21 22:00:00 +01:00
|
|
|
|
if( allow_compression )
|
|
|
|
|
compress_lumps = true;
|
2007-12-20 22:00:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
==============
|
|
|
|
|
Cmd_WadUnknown
|
|
|
|
|
|
|
|
|
|
syntax: "blabla"
|
|
|
|
|
==============
|
|
|
|
|
*/
|
|
|
|
|
void Cmd_WadUnknown( void )
|
|
|
|
|
{
|
|
|
|
|
MsgWarn("Cmd_WadUnknown: skip command \"%s\"\n", com_token);
|
|
|
|
|
while(Com_TryToken());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ResetWADInfo( void )
|
|
|
|
|
{
|
2007-12-21 22:00:00 +01:00
|
|
|
|
FS_FileBase( gs_mapname, wadoutname ); // kill path and ext
|
|
|
|
|
FS_DefaultExtension( wadoutname, ".wad" ); // set new ext
|
2007-12-20 22:00:00 +01:00
|
|
|
|
|
|
|
|
|
memset (&wadheader, 0, sizeof(wadheader));
|
|
|
|
|
wadheader = IDWAD3HEADER;
|
2007-12-21 22:00:00 +01:00
|
|
|
|
compress_lumps = false;
|
|
|
|
|
allow_compression = false;
|
2007-12-20 22:00:00 +01:00
|
|
|
|
numlumps = 0;
|
|
|
|
|
handle = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
===============
|
|
|
|
|
ParseScript
|
|
|
|
|
===============
|
|
|
|
|
*/
|
|
|
|
|
bool ParseWADfileScript( void )
|
|
|
|
|
{
|
|
|
|
|
ResetWADInfo();
|
|
|
|
|
|
|
|
|
|
while( 1 )
|
|
|
|
|
{
|
|
|
|
|
if(!Com_GetToken (true))break;
|
|
|
|
|
|
|
|
|
|
if (Com_MatchToken( "$wadname" )) Cmd_WadName();
|
|
|
|
|
else if (Com_MatchToken( "$wadtype" )) Cmd_WadType();
|
|
|
|
|
else if (Com_MatchToken( "$compression" )) Cmd_WadCompress();
|
|
|
|
|
else if (Com_MatchToken( "$addlump" )) Cmd_AddLump();
|
2007-12-21 22:00:00 +01:00
|
|
|
|
else if (Com_MatchToken( "$addlumps" )) Cmd_AddLumps();
|
2007-12-20 22:00:00 +01:00
|
|
|
|
else if (!Com_ValidScript( QC_WADLIB )) return false;
|
|
|
|
|
else Cmd_WadUnknown();
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2007-12-21 22:00:00 +01:00
|
|
|
|
bool WriteWADFile( void )
|
2007-12-20 22:00:00 +01:00
|
|
|
|
{
|
|
|
|
|
int ofs;
|
|
|
|
|
|
2007-12-21 22:00:00 +01:00
|
|
|
|
if(!handle) return false;
|
2007-12-20 22:00:00 +01:00
|
|
|
|
|
|
|
|
|
// write the lumpingo
|
|
|
|
|
ofs = FS_Tell( handle );
|
|
|
|
|
FS_Write( handle, wadlumps, numlumps * sizeof(dlumpinfo_t));
|
|
|
|
|
|
|
|
|
|
// write the header
|
|
|
|
|
wadfile.ident = wadheader;
|
|
|
|
|
wadfile.numlumps = LittleLong( numlumps );
|
|
|
|
|
wadfile.infotableofs = LittleLong( ofs );
|
|
|
|
|
|
|
|
|
|
FS_Seek( handle, 0, SEEK_SET );
|
|
|
|
|
FS_Write( handle, &wadfile, sizeof(wadfile));
|
|
|
|
|
FS_Close( handle );
|
|
|
|
|
|
2007-12-21 22:00:00 +01:00
|
|
|
|
return true;
|
2007-12-20 22:00:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool BuildCurrentWAD( const char *name )
|
|
|
|
|
{
|
|
|
|
|
bool load = false;
|
|
|
|
|
|
|
|
|
|
if(name) com.strncpy( gs_mapname, name, sizeof(gs_mapname));
|
|
|
|
|
FS_DefaultExtension( gs_mapname, ".qc" );
|
|
|
|
|
load = Com_LoadScript( gs_mapname, NULL, 0 );
|
|
|
|
|
|
|
|
|
|
if(load)
|
|
|
|
|
{
|
|
|
|
|
if(!ParseWADfileScript())
|
|
|
|
|
return false;
|
2007-12-21 22:00:00 +01:00
|
|
|
|
return WriteWADFile();
|
2007-12-20 22:00:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Msg("%s not found\n", gs_mapname );
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CompileWad3Archive( byte *mempool, const char *name, byte parms )
|
|
|
|
|
{
|
|
|
|
|
if(mempool) studiopool = mempool;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Msg("Wadlib: can't allocate memory pool.\nAbort compilation\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return BuildCurrentWAD( name );
|
|
|
|
|
}
|