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/ripper/conv_main.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;
}