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:
Andrey Akhmichin
2025-03-31 11:44:49 +05:00
committed by Alibek Omarov
parent c298635728
commit 7bfcd4cef0
7 changed files with 265 additions and 103 deletions

View File

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

View File

@@ -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
View 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

View File

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

View File

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

View File

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

View File

@@ -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