mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 03:24:56 +08:00
utils: mdldec: add options to:
- disable log output. - use separate directories for smd and texture files. - avoid to write paranoia 2 motion types. - ignore filesize checks. - enable UV coords shifting. - show decompiler version. - show help.
This commit is contained in:
committed by
Alibek Omarov
parent
c298635728
commit
7bfcd4cef0
@@ -17,6 +17,7 @@ GNU General Public License for more details.
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "const.h"
|
||||
#include "com_model.h"
|
||||
#include "crtlib.h"
|
||||
@@ -26,12 +27,15 @@ GNU General Public License for more details.
|
||||
#include "texture.h"
|
||||
#include "utils.h"
|
||||
#include "version.h"
|
||||
#include "settings.h"
|
||||
#include "mdldec.h"
|
||||
|
||||
char destdir[MAX_SYSPATH];
|
||||
char modelfile[MAX_SYSPATH];
|
||||
studiohdr_t *model_hdr;
|
||||
studiohdr_t *texture_hdr;
|
||||
studiohdr_t **anim_hdr;
|
||||
int globalsettings;
|
||||
|
||||
/*
|
||||
============
|
||||
@@ -104,17 +108,17 @@ static void TextureNameFix( void )
|
||||
|
||||
if( counter > 0 )
|
||||
{
|
||||
printf( "WARNING: Texture name \"%s\" is repeated %i times.\n", texture->name, counter );
|
||||
LogPrintf( "WARNING: Texture name \"%s\" is repeated %i times.", texture->name, counter );
|
||||
|
||||
hasduplicates = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( protected )
|
||||
printf( "WARNING: Gived name to %i protected texture(s).\n", protected );
|
||||
LogPrintf( "WARNING: Gived name to %i protected texture(s).", protected );
|
||||
|
||||
if( hasduplicates )
|
||||
puts( "WARNING: Added numeric suffix to repeated texture name(s)." );
|
||||
LogPutS( "WARNING: Added numeric suffix to repeated texture name(s)." );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -176,7 +180,7 @@ static void BodypartNameFix( void )
|
||||
|
||||
if( counter > 0 )
|
||||
{
|
||||
printf( "WARNING: Model name \"%s\" is repeated %i times.\n", model->name, counter );
|
||||
LogPrintf( "WARNING: Model name \"%s\" is repeated %i times.", model->name, counter );
|
||||
|
||||
hasduplicates = true;
|
||||
}
|
||||
@@ -185,13 +189,13 @@ static void BodypartNameFix( void )
|
||||
}
|
||||
|
||||
if( protected )
|
||||
printf( "WARNING: Gived name to %i protected bodypart(s).\n", protected );
|
||||
LogPrintf( "WARNING: Gived name to %i protected bodypart(s).", protected );
|
||||
|
||||
if( protected_models )
|
||||
printf( "WARNING: Gived name to %i protected model(s).\n", protected_models );
|
||||
LogPrintf( "WARNING: Gived name to %i protected model(s).", protected_models );
|
||||
|
||||
if( hasduplicates )
|
||||
puts( "WARNING: Added numeric suffix to repeated bodypart name(s)." );
|
||||
LogPutS( "WARNING: Added numeric suffix to repeated bodypart name(s)." );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -234,17 +238,17 @@ static void SequenceNameFix( void )
|
||||
|
||||
if( counter > 0 )
|
||||
{
|
||||
printf( "WARNING: Sequence name \"%s\" is repeated %i times.\n", seqdesc->label, counter );
|
||||
LogPrintf( "WARNING: Sequence name \"%s\" is repeated %i times.", seqdesc->label, counter );
|
||||
|
||||
hasduplicates = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( protected )
|
||||
printf( "WARNING: Gived name to %i protected sequence(s).\n", protected );
|
||||
LogPrintf( "WARNING: Gived name to %i protected sequence(s).", protected );
|
||||
|
||||
if( hasduplicates )
|
||||
puts( "WARNING: Added numeric suffix to repeated sequence name(s)." );
|
||||
LogPutS( "WARNING: Added numeric suffix to repeated sequence name(s)." );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -266,7 +270,7 @@ static void BoneNameFix( void )
|
||||
}
|
||||
|
||||
if( protected )
|
||||
printf( "WARNING: Gived name to %i protected bone(s).\n", protected );
|
||||
LogPrintf( "WARNING: Gived name to %i protected bone(s).", protected );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -285,13 +289,13 @@ static qboolean LoadMDL( const char *modelname )
|
||||
const char id_mdlhdr[] = {'I', 'D', 'S', 'T'};
|
||||
const char id_seqhdr[] = {'I', 'D', 'S', 'Q'};
|
||||
|
||||
printf( "MDL: %s\n", modelname );
|
||||
LogPrintf( "MDL: %s.", modelname );
|
||||
|
||||
len = Q_strlen( modelname );
|
||||
|
||||
if( len > MAX_SYSPATH - 3 )
|
||||
{
|
||||
fputs( "ERROR: Source path is too long.\n", stderr );
|
||||
LogPutS( "ERROR: Source path is too long.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -299,13 +303,13 @@ static qboolean LoadMDL( const char *modelname )
|
||||
|
||||
if( !ext )
|
||||
{
|
||||
fprintf( stderr, "ERROR: Source file does not have extension.\n" );
|
||||
LogPutS( "ERROR: Source file does not have extension." );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( Q_stricmp( ext, "mdl" ) )
|
||||
{
|
||||
fprintf( stderr, "ERROR: Only .mdl-files is supported.\n" );
|
||||
LogPutS( "ERROR: Only .mdl-files is supported." );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -313,35 +317,47 @@ static qboolean LoadMDL( const char *modelname )
|
||||
|
||||
if( !model_hdr )
|
||||
{
|
||||
fprintf( stderr, "ERROR: Can't open %s\n", modelname );
|
||||
LogPrintf( "ERROR: Can't open %s.", modelname );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( filesize < sizeof( studiohdr_t ) || filesize != model_hdr->length )
|
||||
if( filesize < sizeof( studiohdr_t ))
|
||||
{
|
||||
fprintf( stderr, "ERROR: Wrong file size! File %s may be corrupted!\n", modelname );
|
||||
LogPrintf( "ERROR: Wrong file size! File %s may be corrupted!", modelname );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( filesize != model_hdr->length )
|
||||
{
|
||||
// Some bad studio model compiler don't write file length
|
||||
if( globalsettings & SETTINGS_NOVALIDATION )
|
||||
LogPrintf( "WARNING: Wrong file size! File %s may be corrupted!", modelname );
|
||||
else
|
||||
{
|
||||
LogPrintf( "ERROR: Wrong file size! File %s may be corrupted!", modelname );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( memcmp( &model_hdr->ident, id_mdlhdr, sizeof( id_mdlhdr ) ) )
|
||||
{
|
||||
if( !memcmp( &model_hdr->ident, id_seqhdr, sizeof( id_seqhdr ) ) )
|
||||
fprintf( stderr, "ERROR: %s is not a main HL model file.\n", modelname );
|
||||
LogPrintf( "ERROR: %s is not a main HL model file.", modelname );
|
||||
else
|
||||
fprintf( stderr, "ERROR: %s is not a valid HL model file.\n", modelname );
|
||||
LogPrintf( "ERROR: %s is not a valid HL model file.", modelname );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( model_hdr->version != STUDIO_VERSION )
|
||||
{
|
||||
fprintf( stderr, "ERROR: %s has unknown Studio MDL format version %d.\n", modelname, model_hdr->version );
|
||||
LogPrintf( "ERROR: %s has unknown Studio MDL format version %d.", modelname, model_hdr->version );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !model_hdr->numbodyparts )
|
||||
{
|
||||
fprintf( stderr, "ERROR: %s is not a main HL model file.\n", modelname );
|
||||
LogPrintf( "ERROR: %s is not a main HL model file.", modelname );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -376,21 +392,33 @@ static qboolean LoadMDL( const char *modelname )
|
||||
if( !texture_hdr )
|
||||
#endif
|
||||
{
|
||||
fprintf( stderr, "ERROR: Can't open external textures file %s\n", texturename );
|
||||
LogPrintf( "ERROR: Can't open external textures file %s.", texturename );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( filesize < sizeof( studiohdr_t ) || filesize != texture_hdr->length )
|
||||
if( filesize < sizeof( studiohdr_t ) )
|
||||
{
|
||||
fprintf( stderr, "ERROR: Wrong file size! File %s may be corrupted!\n", texturename );
|
||||
LogPrintf( "ERROR: Wrong file size! File %s may be corrupted!", texturename );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( filesize != texture_hdr->length )
|
||||
{
|
||||
// Some bad studio model compiler don't write file length
|
||||
if( globalsettings & SETTINGS_NOVALIDATION )
|
||||
LogPrintf( "WARNING: Wrong file size! File %s may be corrupted!", texturename );
|
||||
else
|
||||
{
|
||||
LogPrintf( "ERROR: Wrong file size! File %s may be corrupted!", texturename );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( memcmp( &texture_hdr->ident, id_mdlhdr, sizeof( id_mdlhdr ) )
|
||||
|| !texture_hdr->numtextures )
|
||||
{
|
||||
fprintf( stderr, "ERROR: %s is not a valid external textures file.\n", texturename );
|
||||
LogPrintf( "ERROR: %s is not a valid external textures file.", texturename );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -401,7 +429,7 @@ static qboolean LoadMDL( const char *modelname )
|
||||
|
||||
if( !anim_hdr )
|
||||
{
|
||||
fputs( "ERROR: Couldn't allocate memory for sequences.\n", stderr );
|
||||
LogPutS( "ERROR: Couldn't allocate memory for sequences." );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -419,19 +447,31 @@ static qboolean LoadMDL( const char *modelname )
|
||||
|
||||
if( !anim_hdr[i] )
|
||||
{
|
||||
fprintf( stderr, "ERROR: Can't open sequence file %s\n", seqgroupname );
|
||||
LogPrintf( "ERROR: Can't open sequence file %s.", seqgroupname );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( filesize < sizeof( studiohdr_t ) || filesize != anim_hdr[i]->length )
|
||||
if( filesize < sizeof( studiohdr_t ))
|
||||
{
|
||||
fprintf( stderr, "ERROR: Wrong file size! File %s may be corrupted!\n", seqgroupname );
|
||||
LogPrintf( "ERROR: Wrong file size! File %s may be corrupted!", seqgroupname );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( filesize != anim_hdr[i]->length )
|
||||
{
|
||||
// Some bad studio model compiler don't write file length
|
||||
if( globalsettings & SETTINGS_NOVALIDATION )
|
||||
LogPrintf( "WARNING: Wrong file size! File %s may be corrupted!", seqgroupname );
|
||||
else
|
||||
{
|
||||
LogPrintf( "ERROR: Wrong file size! File %s may be corrupted!", seqgroupname );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( memcmp( &anim_hdr[i]->ident, id_seqhdr, sizeof( id_seqhdr ) ) )
|
||||
{
|
||||
fprintf( stderr, "ERROR: %s is not a valid sequence file.\n", seqgroupname );
|
||||
LogPrintf( "ERROR: %s is not a valid sequence file.", seqgroupname );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -442,12 +482,12 @@ static qboolean LoadMDL( const char *modelname )
|
||||
// Some validation checks was found in mdldec-golang by Psycrow101
|
||||
if( model_hdr->numhitboxes > model_hdr->numbones * ( MAXSTUDIOSRCBONES / MAXSTUDIOBONES ))
|
||||
{
|
||||
printf( "WARNING: Invalid hitboxes number %d.\n", model_hdr->numhitboxes );
|
||||
LogPrintf( "WARNING: Invalid hitboxes number %d.", model_hdr->numhitboxes );
|
||||
model_hdr->numhitboxes = 0;
|
||||
}
|
||||
else if( model_hdr->hitboxindex + model_hdr->numhitboxes * ( sizeof( mstudiobbox_t ) + sizeof( mstudiohitboxset_t )) > model_hdr->length )
|
||||
{
|
||||
printf( "WARNING: Invalid hitboxes offset %d.\n", model_hdr->hitboxindex );
|
||||
LogPrintf( "WARNING: Invalid hitboxes offset %d.", model_hdr->hitboxindex );
|
||||
model_hdr->numhitboxes = 0;
|
||||
}
|
||||
|
||||
@@ -462,6 +502,18 @@ static qboolean LoadMDL( const char *modelname )
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ShowVersion
|
||||
============
|
||||
*/
|
||||
static void ShowVersion( void )
|
||||
{
|
||||
LogPutS( "\nHalf-Life Studio Model Decompiler " APP_VERSION );
|
||||
LogPutS( "Copyright Flying With Gauss 2020 (c) " );
|
||||
LogPutS( "--------------------------------------------------" );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ShowHelp
|
||||
@@ -469,17 +521,51 @@ ShowHelp
|
||||
*/
|
||||
static void ShowHelp( const char *app_name )
|
||||
{
|
||||
printf( "usage: %s source_file\n", app_name );
|
||||
printf( " %s source_file target_directory\n", app_name );
|
||||
LogPrintf( "usage: %s [-dhlmuVv] <source_file>", app_name );
|
||||
LogPrintf( " %s [-dhlmuVv] <source_file> <target_directory>", app_name );
|
||||
LogPutS( "\nnote:");
|
||||
LogPutS( "\tby default this decompiler aimed to support extended MDL10 format from XashXT/PrimeXT/Paranoia2.");
|
||||
LogPutS( "\tif you use an old GoldSource studio model compiler you may be need to edit .qc-file after decompilation.");
|
||||
LogPutS( "\noptions:");
|
||||
LogPutS( "\t-d\tplace smd and texture files to separate directories." );
|
||||
LogPutS( "\t-m\tuse only GoldSource-compatible motion types and ignore deprecated motion types with \"A\" prefix." );
|
||||
LogPutS( "\t-u\tenable UV coords shifting for DoomMusic's and Sven-Coop's studio model compilers.");
|
||||
LogPutS( "\t-V\tignore some validation checks for broken models.");
|
||||
LogPutS( "\t-l\tdo not output logs.");
|
||||
LogPutS( "\t-v\tshow version.");
|
||||
LogPutS( "\t-h\tthis message.");
|
||||
}
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
int ret = 0;
|
||||
int opt, ret = 0 ;
|
||||
|
||||
puts( "\nHalf-Life Studio Model Decompiler " APP_VERSION );
|
||||
puts( "Copyright Flying With Gauss 2020 (c) " );
|
||||
puts( "--------------------------------------------------" );
|
||||
while( ( opt = getopt( argc, argv, "dhlmuVv" )) != -1 )
|
||||
{
|
||||
switch( opt )
|
||||
{
|
||||
case 'd': globalsettings |= SETTINGS_SEPARATERESOURCES; break;
|
||||
case 'l': globalsettings |= SETTINGS_NOLOGS; break;
|
||||
case 'm': globalsettings |= SETTINGS_LEGACYMOTION; break;
|
||||
case 'u': globalsettings |= SETTINGS_UVSHIFTING; break;
|
||||
case 'V': globalsettings |= SETTINGS_NOVALIDATION; break;
|
||||
case 'h':
|
||||
globalsettings = 0;
|
||||
ShowVersion();
|
||||
ShowHelp( argv[0] );
|
||||
ret = 2;
|
||||
goto end;
|
||||
case 'v':
|
||||
globalsettings = 0;
|
||||
ShowVersion();
|
||||
ret = 2;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
ShowVersion();
|
||||
|
||||
argc -= (optind - 1);
|
||||
|
||||
if( argc == 1 )
|
||||
{
|
||||
@@ -489,17 +575,17 @@ int main( int argc, char *argv[] )
|
||||
}
|
||||
else if( argc == 3 )
|
||||
{
|
||||
if( Q_strlen( argv[2] ) > MAX_SYSPATH - 2 )
|
||||
if( Q_strlen( argv[optind + 1] ) > MAX_SYSPATH - 2 )
|
||||
{
|
||||
fputs( "ERROR: Destination path is too long.\n", stderr );
|
||||
LogPutS( "ERROR: Destination path is too long.");
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
Q_strncpy( destdir, argv[2], sizeof( destdir ));
|
||||
Q_strncpy( destdir, argv[optind + 1], sizeof( destdir ));
|
||||
}
|
||||
|
||||
if( !LoadActivityList( argv[0] ) || !LoadMDL( argv[1] ) )
|
||||
if( !(LoadActivityList( argv[0] ) && LoadMDL( argv[optind] )))
|
||||
{
|
||||
ret = 1;
|
||||
goto end;
|
||||
@@ -509,10 +595,10 @@ int main( int argc, char *argv[] )
|
||||
WriteSMD();
|
||||
WriteTextures();
|
||||
|
||||
puts( "Done." );
|
||||
LogPutS( "Done." );
|
||||
|
||||
end:
|
||||
puts( "--------------------------------------------------" );
|
||||
LogPutS( "--------------------------------------------------" );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ GNU General Public License for more details.
|
||||
#include "utils.h"
|
||||
#include "smd.h"
|
||||
#include "texture.h"
|
||||
#include "settings.h"
|
||||
#include "qc.h"
|
||||
|
||||
static char **activity_names;
|
||||
@@ -49,8 +50,8 @@ qboolean LoadActivityList( const char *appname )
|
||||
|
||||
if( !p )
|
||||
{
|
||||
fprintf( stderr, "ERROR: Couldn't find file " ACTIVITIES_FILE ".\n" \
|
||||
"Place " ACTIVITIES_FILE " beside %s or set MDLDEC_ACT_PATH environment variable.\n", appname );
|
||||
LogPrintf( "ERROR: Couldn't find file " ACTIVITIES_FILE ".\n" \
|
||||
"Place " ACTIVITIES_FILE " beside %s or set MDLDEC_ACT_PATH environment variable.", appname );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -64,7 +65,7 @@ qboolean LoadActivityList( const char *appname )
|
||||
|
||||
if( !fp )
|
||||
{
|
||||
fputs( "ERROR: Couldn't open file " ACTIVITIES_FILE ".\n", stderr );
|
||||
LogPutS( "ERROR: Couldn't open file " ACTIVITIES_FILE "." );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -75,7 +76,7 @@ qboolean LoadActivityList( const char *appname )
|
||||
|
||||
if( !activity_names )
|
||||
{
|
||||
fputs( "ERROR: Couldn't allocate memory for activities strings.\n", stderr );
|
||||
LogPutS( "ERROR: Couldn't allocate memory for activities strings." );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -85,7 +86,7 @@ qboolean LoadActivityList( const char *appname )
|
||||
|
||||
if( !activity_names[activity_count - 1] )
|
||||
{
|
||||
fputs( "ERROR: Couldn't allocate memory for activities strings.\n", stderr );
|
||||
LogPutS( "ERROR: Couldn't allocate memory for activities strings." );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -139,30 +140,32 @@ static void GetMotionTypeString( int type, char *str, size_t size, qboolean is_c
|
||||
if( type & STUDIO_ZR )
|
||||
Q_strncat( str, " ZR", size );
|
||||
|
||||
if( type & STUDIO_LX )
|
||||
Q_strncat( str, " LX", size );
|
||||
if( !( globalsettings & SETTINGS_LEGACYMOTION ))
|
||||
{
|
||||
if( type & STUDIO_LX )
|
||||
Q_strncat( str, " LX", size );
|
||||
|
||||
if( type & STUDIO_LY )
|
||||
Q_strncat( str, " LY", size );
|
||||
if( type & STUDIO_LY )
|
||||
Q_strncat( str, " LY", size );
|
||||
|
||||
if( type & STUDIO_LZ )
|
||||
Q_strncat( str, " LZ", size );
|
||||
if( type & STUDIO_LZ )
|
||||
Q_strncat( str, " LZ", size );
|
||||
|
||||
if( type & STUDIO_LXR )
|
||||
Q_strncat( str, " LXR", size );
|
||||
if( type & STUDIO_LXR )
|
||||
Q_strncat( str, " LXR", size );
|
||||
|
||||
if( type & STUDIO_LYR )
|
||||
Q_strncat( str, " LYR", size );
|
||||
if( type & STUDIO_LYR )
|
||||
Q_strncat( str, " LYR", size );
|
||||
|
||||
if( type & STUDIO_LZR )
|
||||
Q_strncat( str, " LZR", size );
|
||||
if( type & STUDIO_LZR )
|
||||
Q_strncat( str, " LZR", size );
|
||||
|
||||
if( type & STUDIO_LINEAR )
|
||||
Q_strncat( str, " LM", size );
|
||||
|
||||
if( type & STUDIO_QUADRATIC_MOTION )
|
||||
Q_strncat( str, " LQ", size );
|
||||
if( type & STUDIO_LINEAR )
|
||||
Q_strncat( str, " LM", size );
|
||||
|
||||
if( type & STUDIO_QUADRATIC_MOTION )
|
||||
Q_strncat( str, " LQ", size );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -176,17 +179,25 @@ static void GetMotionTypeString( int type, char *str, size_t size, qboolean is_c
|
||||
case STUDIO_XR: p = "XR"; break;
|
||||
case STUDIO_YR: p = "YR"; break;
|
||||
case STUDIO_ZR: p = "ZR"; break;
|
||||
case STUDIO_LX: p = "LX"; break;
|
||||
case STUDIO_LY: p = "LY"; break;
|
||||
case STUDIO_LZ: p = "LZ"; break;
|
||||
case STUDIO_LXR: p = "LXR"; break;
|
||||
case STUDIO_LYR: p = "LYR"; break;
|
||||
case STUDIO_LZR: p = "LZR"; break;
|
||||
case STUDIO_LINEAR: p = "LM"; break;
|
||||
case STUDIO_QUADRATIC_MOTION: p = "LQ"; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if( !( globalsettings & SETTINGS_LEGACYMOTION ))
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case STUDIO_LX: p = "LX"; break;
|
||||
case STUDIO_LY: p = "LY"; break;
|
||||
case STUDIO_LZ: p = "LZ"; break;
|
||||
case STUDIO_LXR: p = "LXR"; break;
|
||||
case STUDIO_LYR: p = "LYR"; break;
|
||||
case STUDIO_LZR: p = "LZR"; break;
|
||||
case STUDIO_LINEAR: p = "LM"; break;
|
||||
case STUDIO_QUADRATIC_MOTION: p = "LQ"; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
if( p )
|
||||
Q_strncpy( str, p, size );
|
||||
}
|
||||
@@ -459,6 +470,7 @@ static void WriteSequenceInfo( FILE *fp )
|
||||
char motion_types[256];
|
||||
mstudioevent_t *event;
|
||||
mstudioseqdesc_t *seqdesc;
|
||||
const char *seq_path;
|
||||
|
||||
if( model_hdr->numseqgroups > 1 )
|
||||
fprintf( fp, "$sequencegroupsize %d\n\n", CalcSequenceGroupSize( ) );
|
||||
@@ -469,6 +481,8 @@ static void WriteSequenceInfo( FILE *fp )
|
||||
|
||||
seqdesc = (mstudioseqdesc_t *)( (byte *)model_hdr + model_hdr->seqindex );
|
||||
|
||||
seq_path = ( globalsettings & SETTINGS_SEPARATERESOURCES ) ? DEFAULT_SEQUENCEPATH : "";
|
||||
|
||||
for( i = 0; i < model_hdr->numseq; ++i, ++seqdesc )
|
||||
{
|
||||
fprintf( fp, "$sequence \"%s\" {\n", seqdesc->label );
|
||||
@@ -476,12 +490,9 @@ static void WriteSequenceInfo( FILE *fp )
|
||||
if( seqdesc->numblends > 1 )
|
||||
{
|
||||
for( j = 0; j < seqdesc->numblends; j++ )
|
||||
fprintf( fp, "\t\"" DEFAULT_SEQUENCEPATH "%s_blend%02i\"\n", seqdesc->label, j + 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( fp, "\t\"" DEFAULT_SEQUENCEPATH "%s\"\n", seqdesc->label );
|
||||
fprintf( fp, "\t\"%s%s_blend%02i\"\n", seq_path, seqdesc->label, j + 1 );
|
||||
}
|
||||
else fprintf( fp, "\t\"%s%s\"\n", seq_path, seqdesc->label );
|
||||
|
||||
if( seqdesc->activity )
|
||||
{
|
||||
@@ -493,7 +504,7 @@ static void WriteSequenceInfo( FILE *fp )
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "WARNING: Sequence %s has a custom activity flag (ACT_%i %i).\n",
|
||||
LogPrintf( "WARNING: Sequence %s has a custom activity flag (ACT_%i %i).",
|
||||
seqdesc->label, seqdesc->activity, seqdesc->actweight );
|
||||
|
||||
fprintf( fp, "\tACT_%i %i\n", seqdesc->activity, seqdesc->actweight );
|
||||
@@ -508,7 +519,7 @@ static void WriteSequenceInfo( FILE *fp )
|
||||
motion_types, seqdesc->blendstart[0], seqdesc->blendend[0] );
|
||||
|
||||
if( !seqdesc->blendtype[0] )
|
||||
printf( "WARNING: Something wrong with blending type for sequence: %s\n", seqdesc->label );
|
||||
LogPrintf( "WARNING: Something wrong with blending type for sequence: %s", seqdesc->label );
|
||||
}
|
||||
|
||||
event = (mstudioevent_t *)( (byte *)model_hdr + seqdesc->eventindex );
|
||||
@@ -567,7 +578,7 @@ void WriteQCScript( void )
|
||||
|
||||
if( len == -1 )
|
||||
{
|
||||
fprintf( stderr, "ERROR: Destination path is too long. Couldn't write %s.qc\n", modelfile );
|
||||
LogPrintf( "ERROR: Destination path is too long. Couldn't write %s.qc.", modelfile );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -575,7 +586,7 @@ void WriteQCScript( void )
|
||||
|
||||
if( !fp )
|
||||
{
|
||||
fprintf( stderr, "ERROR: Couldn't write %s\n", filename );
|
||||
LogPrintf( "ERROR: Couldn't write %s.", filename );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -596,7 +607,9 @@ void WriteQCScript( void )
|
||||
fprintf( fp, "$modelname \"%s.mdl\"\n", modelfile );
|
||||
|
||||
fputs( "$cd \".\"\n", fp );
|
||||
fputs( "$cdtexture \"./" DEFAULT_TEXTUREPATH "\"\n", fp );
|
||||
if( globalsettings & SETTINGS_SEPARATERESOURCES )
|
||||
fputs( "$cdtexture \"./" DEFAULT_TEXTUREPATH "\"\n", fp );
|
||||
else fputs( "$cdtexture \"./\"\n", fp );
|
||||
fputs( "$cliptotextures\n", fp );
|
||||
fputs( "$scale 1.0\n", fp );
|
||||
fputs( "\n", fp );
|
||||
@@ -631,6 +644,6 @@ void WriteQCScript( void )
|
||||
fputs( "// End of QC script.\n", fp );
|
||||
fclose( fp );
|
||||
|
||||
printf( "QC Script: %s\n", filename );
|
||||
LogPrintf( "QC Script: %s", filename );
|
||||
}
|
||||
|
||||
|
||||
16
utils/mdldec/settings.h
Normal file
16
utils/mdldec/settings.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#ifndef SETTINGS_H
|
||||
#define SETTINGS_H
|
||||
|
||||
extern int globalsettings;
|
||||
|
||||
enum
|
||||
{
|
||||
SETTINGS_LEGACYMOTION = BIT(0),
|
||||
SETTINGS_UVSHIFTING = BIT(1),
|
||||
SETTINGS_NOLOGS = BIT(2),
|
||||
SETTINGS_NOVALIDATION = BIT(3),
|
||||
SETTINGS_SEPARATERESOURCES = BIT(4),
|
||||
};
|
||||
|
||||
#endif // VERSION_H
|
||||
@@ -22,8 +22,9 @@ GNU General Public License for more details.
|
||||
#include "crtlib.h"
|
||||
#include "studio.h"
|
||||
#include "mdldec.h"
|
||||
#include "smd.h"
|
||||
#include "utils.h"
|
||||
#include "settings.h"
|
||||
#include "smd.h"
|
||||
|
||||
static matrix3x4 *bonetransform;
|
||||
static matrix3x4 *worldtransform;
|
||||
@@ -39,7 +40,7 @@ static qboolean CreateBoneTransformMatrices( matrix3x4 **matrix )
|
||||
|
||||
if( !*matrix )
|
||||
{
|
||||
fputs( "ERROR: Couldn't allocate memory for bone transformation matrices!\n", stderr );
|
||||
LogPutS( "ERROR: Couldn't allocate memory for bone transformation matrices!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -316,6 +317,11 @@ static void WriteTriangleInfo( FILE *fp, mstudiomodel_t *model, mstudiotexture_t
|
||||
v = 1.0f - (float)triverts[index]->t;
|
||||
}
|
||||
}
|
||||
else if( globalsettings & SETTINGS_UVSHIFTING )
|
||||
{
|
||||
u = (float)triverts[index]->s / texture->width;
|
||||
v = 1.0f - (float)triverts[index]->t / texture->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
u = (float)triverts[index]->s / ( texture->width - 1 );
|
||||
@@ -541,7 +547,7 @@ static void WriteReferences( void )
|
||||
|
||||
if( len == -1 )
|
||||
{
|
||||
fprintf( stderr, "ERROR: Destination path is too long. Couldn't write %s.smd\n", model->name );
|
||||
LogPrintf( "ERROR: Destination path is too long. Couldn't write %s.smd.", model->name );
|
||||
goto _fail;
|
||||
}
|
||||
|
||||
@@ -549,7 +555,7 @@ static void WriteReferences( void )
|
||||
|
||||
if( !fp )
|
||||
{
|
||||
fprintf( stderr, "ERROR: Couldn't write %s\n", filename );
|
||||
LogPrintf( "ERROR: Couldn't write %s.", filename );
|
||||
goto _fail;
|
||||
}
|
||||
|
||||
@@ -561,7 +567,7 @@ static void WriteReferences( void )
|
||||
|
||||
fclose( fp );
|
||||
|
||||
printf( "Reference: %s\n", filename );
|
||||
LogPrintf( "Reference: %s.", filename );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -585,11 +591,11 @@ static void WriteSequences( void )
|
||||
char path[MAX_SYSPATH];
|
||||
mstudioseqdesc_t *seqdesc = (mstudioseqdesc_t *)( (byte *)model_hdr + model_hdr->seqindex );
|
||||
|
||||
len = Q_snprintf( path, MAX_SYSPATH, "%s" DEFAULT_SEQUENCEPATH, destdir );
|
||||
len = Q_snprintf( path, MAX_SYSPATH, ( globalsettings & SETTINGS_SEPARATERESOURCES ) ? "%s" DEFAULT_SEQUENCEPATH : "%s", destdir );
|
||||
|
||||
if( len == -1 || !MakeDirectory( path ))
|
||||
{
|
||||
fputs( "ERROR: Destination path is too long or write permission denied. Couldn't create directory for sequences\n", stderr );
|
||||
LogPutS( "ERROR: Destination path is too long or write permission denied. Couldn't create directory for sequences." );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -606,7 +612,7 @@ static void WriteSequences( void )
|
||||
|
||||
if( namelen == -1 )
|
||||
{
|
||||
fprintf( stderr, "ERROR: Destination path is too long. Couldn't write %s.smd\n", seqdesc->label );
|
||||
LogPrintf( "ERROR: Destination path is too long. Couldn't write %s.smd.", seqdesc->label );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -614,7 +620,7 @@ static void WriteSequences( void )
|
||||
|
||||
if( !fp )
|
||||
{
|
||||
fprintf( stderr, "ERROR: Couldn't write %s\n", path );
|
||||
LogPrintf( "ERROR: Couldn't write %s.", path );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -625,7 +631,7 @@ static void WriteSequences( void )
|
||||
|
||||
fclose( fp );
|
||||
|
||||
printf( "Sequence: %s\n", path );
|
||||
LogPrintf( "Sequence: %s.", path );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,9 @@ GNU General Public License for more details.
|
||||
#include "img_bmp.h"
|
||||
#include "img_tga.h"
|
||||
#include "mdldec.h"
|
||||
#include "texture.h"
|
||||
#include "utils.h"
|
||||
#include "settings.h"
|
||||
#include "texture.h"
|
||||
|
||||
/*
|
||||
============
|
||||
@@ -136,11 +137,11 @@ void WriteTextures( void )
|
||||
mstudiotexture_t *texture = (mstudiotexture_t *)( (byte *)texture_hdr + texture_hdr->textureindex );
|
||||
char path[MAX_SYSPATH];
|
||||
|
||||
len = Q_snprintf( path, MAX_SYSPATH, "%s" DEFAULT_TEXTUREPATH, destdir );
|
||||
len = Q_snprintf( path, MAX_SYSPATH, ( globalsettings & SETTINGS_SEPARATERESOURCES ) ? "%s" DEFAULT_TEXTUREPATH : "%s", destdir );
|
||||
|
||||
if( len == -1 || !MakeDirectory( path ))
|
||||
{
|
||||
fputs( "ERROR: Destination path is too long or write permission denied. Couldn't create directory for textures\n", stderr );
|
||||
LogPutS( "ERROR: Destination path is too long or write permission denied. Couldn't create directory for textures." );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -152,7 +153,7 @@ void WriteTextures( void )
|
||||
|
||||
if( emptyplace - namelen < 0 )
|
||||
{
|
||||
fprintf( stderr, "ERROR: Destination path is too long. Couldn't write %s\n", texture->name );
|
||||
LogPrintf( "ERROR: Destination path is too long. Couldn't write %s.", texture->name );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -160,7 +161,7 @@ void WriteTextures( void )
|
||||
|
||||
if( !fp )
|
||||
{
|
||||
fprintf( stderr, "ERROR: Couldn't write texture file %s\n", path );
|
||||
LogPrintf( "ERROR: Couldn't write texture file %s.", path );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -174,7 +175,7 @@ void WriteTextures( void )
|
||||
|
||||
fclose( fp );
|
||||
|
||||
printf( "Texture: %s\n", path );
|
||||
LogPrintf( "Texture: %s.", path );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ GNU General Public License for more details.
|
||||
#include "xash3d_types.h"
|
||||
#include "port.h"
|
||||
#include "crtlib.h"
|
||||
#include "settings.h"
|
||||
#include "utils.h"
|
||||
|
||||
/*
|
||||
@@ -75,7 +76,7 @@ qboolean MakeFullPath( const char *path )
|
||||
|
||||
if( !MakeDirectory( path ))
|
||||
{
|
||||
fprintf( stderr, "ERROR: Couldn't create directory %s\n", path );
|
||||
LogPrintf( "ERROR: Couldn't create directory %s.", path );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -153,3 +154,40 @@ byte *LoadFile( const char *filename, off_t *size )
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
LogPutS
|
||||
============
|
||||
*/
|
||||
void LogPutS( const char *str )
|
||||
{
|
||||
if( ( globalsettings & SETTINGS_NOLOGS ))
|
||||
return;
|
||||
|
||||
if( Q_strncmp( str, "ERROR:", sizeof( "ERROR:" ) - 1 ))
|
||||
puts( str );
|
||||
else fprintf( stderr, "%s\n", str );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
LogPrintf
|
||||
============
|
||||
*/
|
||||
void LogPrintf( const char *szFmt, ... )
|
||||
{
|
||||
va_list args;
|
||||
static char buffer[2048];
|
||||
|
||||
if( ( globalsettings & SETTINGS_NOLOGS ))
|
||||
return;
|
||||
|
||||
va_start( args, szFmt );
|
||||
Q_vsnprintf( buffer, sizeof( buffer ), szFmt, args );
|
||||
va_end( args );
|
||||
|
||||
if( Q_strncmp( buffer, "ERROR:", sizeof( "ERROR:" ) - 1 ))
|
||||
puts( buffer );
|
||||
else fprintf( stderr, "%s\n", buffer );
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@ qboolean MakeFullPath( const char *path );
|
||||
void ExtractFileName( char *name, size_t size );
|
||||
off_t GetSizeOfFile( FILE *fp );
|
||||
byte *LoadFile( const char *filename, off_t *size );
|
||||
void LogPutS( const char *str );
|
||||
void LogPrintf( const char *szFmt, ... );
|
||||
|
||||
#endif // UTILS_H
|
||||
|
||||
|
||||
Reference in New Issue
Block a user