From 7bfcd4cef07c3ae173450a1a2cbacda1cb21c461 Mon Sep 17 00:00:00 2001 From: Andrey Akhmichin <15944199+nekonomicon@users.noreply.github.com> Date: Mon, 31 Mar 2025 11:44:49 +0500 Subject: [PATCH] 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. --- utils/mdldec/mdldec.c | 176 ++++++++++++++++++++++++++++++---------- utils/mdldec/qc.c | 95 ++++++++++++---------- utils/mdldec/settings.h | 16 ++++ utils/mdldec/smd.c | 26 +++--- utils/mdldec/texture.c | 13 +-- utils/mdldec/utils.c | 40 ++++++++- utils/mdldec/utils.h | 2 + 7 files changed, 265 insertions(+), 103 deletions(-) create mode 100644 utils/mdldec/settings.h diff --git a/utils/mdldec/mdldec.c b/utils/mdldec/mdldec.c index 8c55ab2e..e90fc694 100644 --- a/utils/mdldec/mdldec.c +++ b/utils/mdldec/mdldec.c @@ -17,6 +17,7 @@ GNU General Public License for more details. #include #include #include +#include #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] ", app_name ); + LogPrintf( " %s [-dhlmuVv] ", 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; } diff --git a/utils/mdldec/qc.c b/utils/mdldec/qc.c index a5bc4476..2f46a5ae 100644 --- a/utils/mdldec/qc.c +++ b/utils/mdldec/qc.c @@ -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 ); } diff --git a/utils/mdldec/settings.h b/utils/mdldec/settings.h new file mode 100644 index 00000000..03c175bf --- /dev/null +++ b/utils/mdldec/settings.h @@ -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 diff --git a/utils/mdldec/smd.c b/utils/mdldec/smd.c index e7da491d..f0534cbf 100644 --- a/utils/mdldec/smd.c +++ b/utils/mdldec/smd.c @@ -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 ); } } } diff --git a/utils/mdldec/texture.c b/utils/mdldec/texture.c index ef85f5c0..98a6c997 100644 --- a/utils/mdldec/texture.c +++ b/utils/mdldec/texture.c @@ -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 ); } } diff --git a/utils/mdldec/utils.c b/utils/mdldec/utils.c index 21dcd9a1..c888955e 100644 --- a/utils/mdldec/utils.c +++ b/utils/mdldec/utils.c @@ -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 ); +} + diff --git a/utils/mdldec/utils.h b/utils/mdldec/utils.h index da6d2d2c..812081a1 100644 --- a/utils/mdldec/utils.h +++ b/utils/mdldec/utils.h @@ -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