This repository has been archived on 2022-06-27. You can view files and clone it, but cannot push or open issues or pull requests.
Xash3DArchive/common/wadlib.c

300 lines
7.0 KiB
C
Raw Normal View History

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 );
}