247 lines
6.5 KiB
C
247 lines
6.5 KiB
C
//=======================================================================
|
|
// Copyright XashXT Group 2007 ©
|
|
// conv_main.c - resource converter
|
|
//=======================================================================
|
|
|
|
#include "ripper.h"
|
|
#include "pal_utils.h"
|
|
|
|
bool host_debug = false;
|
|
stdlib_api_t com;
|
|
byte *basepool;
|
|
byte *zonepool;
|
|
static double start, end;
|
|
uint app_name = 0;
|
|
string gs_gamedir;
|
|
string gs_searchmask;
|
|
|
|
#define MAX_SEARCHMASK 128
|
|
string searchmask[MAX_SEARCHMASK];
|
|
int num_searchmask = 0;
|
|
|
|
typedef struct convformat_s
|
|
{
|
|
char *formatstring;
|
|
char *ext;
|
|
bool (*convfunc)( const char *name, char *buffer, int filesize );
|
|
} convformat_t;
|
|
|
|
convformat_t convert_formats[] =
|
|
{
|
|
{"%s.%s", "spr", ConvSPR}, // quake1/half-life sprite
|
|
{"%s.%s","spr32",ConvSPR}, // spr32 sprite
|
|
{"%s.%s", "sp2", ConvSP2}, // quake2 sprite
|
|
{"%s.%s", "jpg", ConvJPG}, // quake3 textures
|
|
{"%s.%s", "pcx", ConvPCX}, // quake2 pics
|
|
{"%s.%s", "pal", ConvPAL}, // q1\q2\hl\d1 palette
|
|
{"%s.%s", "flt", ConvFLT}, // doom1 textures
|
|
{"%s.%s", "flp", ConvFLP}, // doom1 menu pics
|
|
{"%s.%s", "mip", ConvMIP}, // Quake1/Half-Life textures
|
|
{"%s.%s", "lmp", ConvLMP}, // Quake1/Half-Life graphics
|
|
{"%s.%s", "fnt", ConvFNT}, // Half-Life fonts
|
|
{"%s.%s", "wal", ConvWAL}, // Quake2 textures
|
|
{"%s.%s", "skn", ConvSKN}, // doom1 sprite models
|
|
{"%s.%s", "bsp", ConvBSP}, // Quake1\Half-Life map textures
|
|
{"%s.%s", "mus", ConvMID}, // Quake1\Half-Life map textures
|
|
{"%s.%s", "snd", ConvSND}, // Quake1\Half-Life map textures
|
|
{"%s.%s", "txt", ConvRAW}, // (hidden) Xash-extract scripts
|
|
{"%s.%s", "dat", ConvRAW}, // (hidden) Xash-extract progs
|
|
{NULL, NULL } // list terminator
|
|
};
|
|
|
|
bool ConvertResource( const char *filename )
|
|
{
|
|
convformat_t *format;
|
|
const char *ext = FS_FileExtension( filename );
|
|
char path[128], convname[128], basename[128];
|
|
bool anyformat = !com.stricmp(ext, "") ? true : false;
|
|
int filesize = 0;
|
|
byte *buffer = NULL;
|
|
|
|
com.strncpy( convname, filename, sizeof(convname)-1);
|
|
FS_StripExtension( convname ); //remove extension if needed
|
|
|
|
// now try all the formats in the selected list
|
|
for (format = convert_formats; format->formatstring; format++)
|
|
{
|
|
if( anyformat || !com.stricmp( ext, format->ext ))
|
|
{
|
|
com.sprintf (path, format->formatstring, convname, format->ext );
|
|
buffer = FS_LoadFile( path, &filesize );
|
|
FS_FileBase( path, basename );
|
|
if(buffer && filesize > 0)
|
|
{
|
|
// this path may contains wadname: wadfile/lumpname
|
|
if( format->convfunc( path, buffer, filesize ))
|
|
{
|
|
Mem_Free( buffer ); // release buffer
|
|
return true; // converted ok
|
|
}
|
|
}
|
|
}
|
|
}
|
|
MsgDev(D_WARN, "ConvertResource: couldn't load \"%s\"\n", basename );
|
|
return false;
|
|
}
|
|
|
|
void ClrMask( void )
|
|
{
|
|
num_searchmask = 0;
|
|
Mem_Set( searchmask, 0, MAX_STRING * MAX_SEARCHMASK );
|
|
}
|
|
|
|
void AddMask( const char *mask )
|
|
{
|
|
if( num_searchmask >= MAX_SEARCHMASK )
|
|
{
|
|
MsgDev(D_WARN, "AddMask: searchlist is full\n");
|
|
return;
|
|
}
|
|
com.strncpy( searchmask[num_searchmask], mask, MAX_STRING );
|
|
num_searchmask++;
|
|
}
|
|
|
|
/*
|
|
==================
|
|
CommonInit
|
|
|
|
idconv.dll needs for some setup operations
|
|
so do it manually
|
|
==================
|
|
*/
|
|
void InitConvertor ( uint funcname, int argc, char **argv )
|
|
{
|
|
// init pools
|
|
basepool = Mem_AllocPool( "Temp" );
|
|
zonepool = Mem_AllocPool( "Zone" );
|
|
app_name = funcname;
|
|
|
|
FS_InitRootDir(".");
|
|
start = Sys_DoubleTime();
|
|
Msg("Converting ...\n\n");
|
|
}
|
|
|
|
void RunConvertor ( void )
|
|
{
|
|
search_t *search;
|
|
string errorstring;
|
|
int i, j, numConvertedRes = 0;
|
|
|
|
Mem_Set( errorstring, 0, MAX_STRING );
|
|
ClrMask();
|
|
|
|
switch(app_name)
|
|
{
|
|
case RIPP_MIPDEC:
|
|
search = FS_Search("textures/*", true );
|
|
if( search )
|
|
{
|
|
// find subdirectories
|
|
for(i = 0; i < search->numfilenames; i++)
|
|
{
|
|
AddMask(va("%s/*.wal", search->filenames[i]));
|
|
AddMask(va("%s/*.jpg", search->filenames[i]));
|
|
}
|
|
Mem_Free( search );
|
|
}
|
|
AddMask( "maps/*.bsp" ); // textures from bsp
|
|
AddMask( "*.flt" ); // Doom1 textures
|
|
AddMask( "*.mip" ); // Quake1\Hl1 textures
|
|
AddMask( "*.jpg" ); // Quake3 textures
|
|
AddMask( "*.wal" ); // Quake2 textures
|
|
break;
|
|
case RIPP_SPRDEC:
|
|
AddMask( "sprites/*.spr32"); // QW 32bit sprites
|
|
AddMask( "sprites/*.sp2" ); // Quake2 sprites
|
|
AddMask( "sprites/*.spr" ); // Quake1 and Half-Life sprites
|
|
AddMask( "progs/*.spr32" );
|
|
AddMask( "progs/*.spr" );
|
|
AddMask( "*.spr" );
|
|
AddMask( "*.sp2" );
|
|
AddMask( "*.sp32");
|
|
break;
|
|
case RIPP_MDLDEC:
|
|
AddMask( "*.skn" ); // Doom1 sprite models
|
|
break;
|
|
case RIPP_LMPDEC:
|
|
AddMask( "pics/*.pcx"); // Quake2 pics
|
|
AddMask( "gfx/*.lmp" ); // Quake1 pics
|
|
AddMask( "*.fnt" ); // Half-Life fonts
|
|
AddMask( "*.flp" ); // Doom1 pics
|
|
AddMask( "*.pcx" );
|
|
AddMask( "*.lmp" );
|
|
break;
|
|
case RIPP_SNDDEC:
|
|
AddMask( "*.snd" );
|
|
AddMask( "*.mus" );
|
|
break;
|
|
case RIPP_BSPDEC:
|
|
case RIPP_QCCDEC:
|
|
Sys_Break(" not implemented\n");
|
|
case HOST_OFFLINE:
|
|
default: return;
|
|
}
|
|
|
|
if(FS_GetParmFromCmdLine("-file", gs_searchmask ))
|
|
{
|
|
ClrMask(); // clear all previous masks
|
|
AddMask( gs_searchmask ); // custom mask
|
|
}
|
|
|
|
// directory to extract
|
|
com.strncpy(gs_gamedir, "~tmpXash", sizeof(gs_gamedir));
|
|
|
|
// search by mask
|
|
for( i = 0; i < num_searchmask; i++)
|
|
{
|
|
// skip blank mask
|
|
if(!com.strlen(searchmask[i])) continue;
|
|
search = FS_Search( searchmask[i], true );
|
|
if(!search) continue; // try next mask
|
|
|
|
for( j = 0; j < search->numfilenames; j++ )
|
|
{
|
|
if(ConvertResource( search->filenames[j] ))
|
|
numConvertedRes++;
|
|
}
|
|
Mem_Free( search );
|
|
}
|
|
if(numConvertedRes == 0)
|
|
{
|
|
for(j = 0; j < 16; j++)
|
|
{
|
|
if(!com.strlen(searchmask[j])) continue;
|
|
com.strncat(errorstring, va("%s ", searchmask[j]), MAX_STRING );
|
|
}
|
|
Sys_Break("no %sfound in this folder!\n", errorstring );
|
|
}
|
|
|
|
end = Sys_DoubleTime();
|
|
Msg ("%5.3f seconds elapsed\n", end - start);
|
|
if(numConvertedRes > 1) Msg("total %d files compiled\n", numConvertedRes );
|
|
}
|
|
|
|
void CloseConvertor( void )
|
|
{
|
|
// finalize qc-script
|
|
Skin_FinalizeScript();
|
|
Mem_Check(); // check for leaks
|
|
Mem_FreePool( &basepool );
|
|
Mem_FreePool( &zonepool );
|
|
}
|
|
|
|
launch_exp_t DLLEXPORT *CreateAPI( stdlib_api_t *input, void *unused )
|
|
{
|
|
static launch_exp_t Com;
|
|
|
|
com = *input;
|
|
|
|
// generic functions
|
|
Com.api_size = sizeof(launch_exp_t);
|
|
|
|
Com.Init = InitConvertor;
|
|
Com.Main = RunConvertor;
|
|
Com.Free = CloseConvertor;
|
|
|
|
return &Com;
|
|
} |