add and use path_set_extension()

fix -bsp crash with .bsp sent as map path
	* fix: qer_editorimage, q3map_lightImage etc work with file names, containing period
(i.e. 'file.name.ext' names; don't StripExtension() twice in ImageLoad() for that)
This commit is contained in:
Garux 2020-01-24 02:47:33 +03:00
parent 80e95ac165
commit 25d94dbd2f
22 changed files with 76 additions and 128 deletions

View File

@ -739,6 +739,11 @@ void path_add_slash( char *path ){
strcat( end, "/" );
}
/// \brief Appends or replaces .EXT part of \p path with \p extension.
void path_set_extension( char *path, const char *extension ){
strcpy( path_get_filename_base_end( path ), extension );
}
//
// if path doesnt have a .EXT, append extension
// (extension should include the .)

View File

@ -155,6 +155,7 @@ char* path_get_filename_start( const char* path );
char* path_get_filename_base_end( const char* path );
char* path_get_extension( const char* path );
void path_add_slash( char *path );
void path_set_extension( char *path, const char *extension );
void DefaultExtension( char *path, const char *extension );
void DefaultPath( char *path, const char *basepath );
void StripFilename( char *path );

View File

@ -453,8 +453,7 @@ void FinishModel( int type ){
if ( type == TYPE_PLAYER ) {
sprintf( name, "%s%s", writedir, g_modelname );
StripExtension( name );
strcat( name, "_default.skin" );
path_set_extension( name, "_default.skin" );
defaultSkinHandle = fopen( name, "wt" );
for ( i = 0; i < g_data.model.numSurfaces; i++ )
@ -1285,8 +1284,7 @@ void Cmd_Modelname( void ){
GetToken( qfalse );
strcpy( g_modelname, token );
StripExtension( g_modelname );
strcat( g_modelname, ".md3" );
path_set_extension( g_modelname, ".md3" );
strcpy( g_data.model.name, g_modelname );
}
@ -1340,8 +1338,7 @@ void Cmd_3DSConvert(){
sprintf( file, "%s%s", gamedir, token );
strcpy( g_modelname, token );
StripExtension( g_modelname );
strcat( g_modelname, ".md3" );
path_set_extension( g_modelname, ".md3" );
if ( FileTime( file ) == -1 ) {
Error( "%s doesn't exist", file );
@ -1371,8 +1368,7 @@ void Cmd_ASEConvert( qboolean grabAnims ){
sprintf( filename, "%s%s", gamedir, token );
strcpy( g_modelname, token );
StripExtension( g_modelname );
strcat( g_modelname, ".md3" );
path_set_extension( g_modelname, ".md3" );
strcpy( g_data.model.name, g_modelname );
if ( !strstr( filename, ".ase" ) && !strstr( filename, ".ASE" ) ) {
@ -1842,8 +1838,7 @@ static void ConvertASE( const char *filename, int type, qboolean grabAnims ){
}
strcpy( outfilename, filename );
StripExtension( outfilename );
strcat( outfilename, ".md3" );
path_set_extension( outfilename, ".md3" );
BuildAnimationFromOAFs( outfilename, objectAnimationFrames, numFrames, type );
// free memory
@ -1991,8 +1986,7 @@ static void ConvertASE( const char *filename, int type, qboolean grabAnims ){
numFrames = SurfaceOrderToFrameOrder( surfaceAnimations, objectAnimationFrames, numSurfaces );
strcpy( outfilename, filename );
StripExtension( outfilename );
strcat( outfilename, ".md3" );
path_set_extension( outfilename, ".md3" );
BuildAnimationFromOAFs( outfilename, objectAnimationFrames, numFrames, type );
// free memory
@ -2013,8 +2007,7 @@ static void ConvertASE( const char *filename, int type, qboolean grabAnims ){
numFrames = SurfaceOrderToFrameOrder( surfaceAnimations, objectAnimationFrames, numSurfaces );
strcpy( outfilename, filename );
StripExtension( outfilename );
strcat( outfilename, "_flash.md3" );
path_set_extension( outfilename, "_flash.md3" );
BuildAnimationFromOAFs( outfilename, objectAnimationFrames, numFrames, TYPE_ITEM );
// free memory
@ -2036,8 +2029,7 @@ static void ConvertASE( const char *filename, int type, qboolean grabAnims ){
numFrames = SurfaceOrderToFrameOrder( surfaceAnimations, objectAnimationFrames, numSurfaces );
strcpy( outfilename, filename );
StripExtension( outfilename );
strcat( outfilename, "_hand.md3" );
path_set_extension( outfilename, "_hand.md3" );
BuildAnimationFromOAFs( outfilename, objectAnimationFrames, numFrames, TYPE_HAND );
// free memory

View File

@ -126,8 +126,7 @@ void FindShaderFiles( char *filename ){
s_shaderFiles.num = 0;
strcpy( stripped, filename );
StripExtension( stripped );
strcat( stripped, ".shader" );
path_set_extension( stripped, ".shader" );
if ( FileExists( stripped ) ) {
char *p;

View File

@ -79,9 +79,9 @@ static inline void tex2list( StrList* texlist, StrList* EXtex, StrList* rEXtex )
if ( token[0] == '\0')
return;
//StripExtension( token );
char* dot = token - 4 + strlen( token );
if( dot >= token && ( !Q_stricmp( dot, ".tga" ) || !Q_stricmp( dot, ".jpg" ) || !Q_stricmp( dot, ".png" ) ) ){ //? might want to also warn on png in non png run
*dot = '\0';
char* dot = path_get_filename_base_end( token );
if( !Q_stricmp( dot, ".tga" ) || !Q_stricmp( dot, ".jpg" ) || !Q_stricmp( dot, ".png" ) ){ //? might want to also warn on png in non png run
strclear( dot );
}
else{
Sys_FPrintf( SYS_WRN, "WARNING4: %s : weird or missing extension in shader image path\n", token );
@ -107,7 +107,7 @@ static inline void res2list( StrList* list, const char* res ){
while ( path_separator( *res ) ){ // kill prepended slashes
++res;
}
if ( *res == '\0') // empty
if ( strempty( res ) )
return;
if( !StrList_find( list, res ) )
StrList_append( list, res );
@ -269,8 +269,7 @@ int pk3BSPMain( int argc, char **argv ){
/* do some path mangling */
strcpy( source, ExpandArg( argv[ argc - 1 ] ) );
StripExtension( source );
DefaultExtension( source, ".bsp" );
path_set_extension( source, ".bsp" );
/* load the bsp */
Sys_Printf( "Loading %s\n", source );
@ -903,7 +902,7 @@ int repackBSPMain( int argc, char **argv ){
/* do some path mangling */
strcpy( source, ExpandArg( argv[ argc - 1 ] ) );
if ( strlen( source ) >= 4 && !Q_stricmp( source + strlen( source ) - 4, ".bsp" ) ){
if ( !Q_stricmp( path_get_filename_base_end( source ), ".bsp" ) ){
strcpy( bspList[bspListN], source );
bspListN++;
}
@ -954,8 +953,7 @@ int repackBSPMain( int argc, char **argv ){
int pk3ShadersNold = pk3Shaders->n;
strcpy( source, bspList[j] );
StripExtension( source );
DefaultExtension( source, ".bsp" );
path_set_extension( source, ".bsp" );
/* load the bsp */
Sys_Printf( "\nLoading %s\n", source );

View File

@ -1091,11 +1091,11 @@ int BSPMain( int argc, char **argv ){
/* expand mapname */
strcpy( name, ExpandArg( argv[ i ] ) );
if ( strcmp( name + strlen( name ) - 4, ".reg" ) ) {
if ( Q_stricmp( path_get_filename_base_end( name ), ".reg" ) ) { /* not .reg */
/* if we are doing a full map, delete the last saved region map */
sprintf( path, "%s.reg", source );
remove( path );
DefaultExtension( name, ".map" ); /* might be .reg */
path_set_extension( name, ".map" ); /* might be .reg */
}
/* if onlyents, just grab the entites and resave */

View File

@ -355,8 +355,7 @@ int ConvertBSPToASE( char *bspName ){
strcpy( dirname, bspName );
StripExtension( dirname );
strcpy( name, bspName );
StripExtension( name );
strcat( name, ".ase" );
path_set_extension( name, ".ase" );
Sys_Printf( "writing %s\n", name );
ExtractFileBase( bspName, base );

View File

@ -60,8 +60,7 @@ int FixAAS( int argc, char **argv ){
/* do some path mangling */
strcpy( source, ExpandArg( argv[ argc - 1 ] ) );
StripExtension( source );
DefaultExtension( source, ".bsp" );
path_set_extension( source, ".bsp" );
/* note it */
Sys_Printf( "--- FixAAS ---\n" );
@ -80,8 +79,7 @@ int FixAAS( int argc, char **argv ){
{
/* mangle name */
strcpy( aas, source );
StripExtension( aas );
strcat( aas, *ext );
path_set_extension( aas, *ext );
Sys_Printf( "Trying %s\n", aas );
ext++;
@ -293,10 +291,7 @@ int BSPInfo( int count, char **fileNames ){
/* mangle filename and get size */
strcpy( source, fileNames[ i ] );
if ( !Q_stricmp( path_get_extension( source ), "map" ) ) {
StripExtension( source );
}
DefaultExtension( source, ".bsp" );
path_set_extension( source, ".bsp" );
f = fopen( source, "rb" );
if ( f ) {
size = Q_filelength( f );
@ -450,8 +445,7 @@ int ScaleBSPMain( int argc, char **argv ){
/* do some path mangling */
strcpy( source, ExpandArg( argv[ argc - 1 ] ) );
StripExtension( source );
DefaultExtension( source, ".bsp" );
path_set_extension( source, ".bsp" );
/* load the bsp */
Sys_Printf( "Loading %s\n", source );
@ -637,8 +631,7 @@ int ScaleBSPMain( int argc, char **argv ){
/* write the bsp */
UnparseEntities();
StripExtension( source );
DefaultExtension( source, "_s.bsp" );
path_set_extension( source, "_s.bsp" );
Sys_Printf( "Writing %s\n", source );
WriteBSPFile( source );
@ -692,8 +685,7 @@ int ShiftBSPMain( int argc, char **argv ){
/* do some path mangling */
strcpy( source, ExpandArg( argv[ argc - 1 ] ) );
StripExtension( source );
DefaultExtension( source, ".bsp" );
path_set_extension( source, ".bsp" );
/* load the bsp */
Sys_Printf( "Loading %s\n", source );
@ -806,8 +798,7 @@ int ShiftBSPMain( int argc, char **argv ){
/* write the bsp */
UnparseEntities();
StripExtension( source );
DefaultExtension( source, "_sh.bsp" );
path_set_extension( source, "_sh.bsp" );
Sys_Printf( "Writing %s\n", source );
WriteBSPFile( source );
@ -1017,16 +1008,14 @@ int ConvertBSPMain( int argc, char **argv ){
if ( !map_allowed ) {
Sys_Warning( "the requested conversion should not be done from .map files. Compile a .bsp first.\n" );
}
StripExtension( source );
DefaultExtension( source, ".map" );
path_set_extension( source, ".map" );
Sys_Printf( "Loading %s\n", source );
LoadMapFile( source, qfalse, convertGame == NULL );
PseudoCompileBSP( convertGame != NULL );
}
else
{
StripExtension( source );
DefaultExtension( source, ".bsp" );
path_set_extension( source, ".bsp" );
Sys_Printf( "Loading %s\n", source );
LoadBSPFile( source );
ParseEntities();
@ -1038,8 +1027,7 @@ int ConvertBSPMain( int argc, char **argv ){
game = convertGame;
/* write bsp */
StripExtension( source );
DefaultExtension( source, "_c.bsp" );
path_set_extension( source, "_c.bsp" );
Sys_Printf( "Writing %s\n", source );
WriteBSPFile( source );

View File

@ -1018,8 +1018,7 @@ int ConvertBSPToMap_Ext( char *bspName, qboolean brushPrimitives ){
/* create the bsp filename from the bsp name */
strcpy( name, bspName );
StripExtension( name );
strcat( name, "_converted.map" );
path_set_extension( name, "_converted.map" );
Sys_Printf( "writing %s\n", name );
/* open it */

View File

@ -319,12 +319,10 @@ int ConvertBSPToOBJ( char *bspName ){
strcpy( dirname, bspName );
StripExtension( dirname );
strcpy( name, bspName );
StripExtension( name );
strcat( name, ".obj" );
path_set_extension( name, ".obj" );
Sys_Printf( "writing %s\n", name );
strcpy( mtlname, bspName );
StripExtension( mtlname );
strcat( mtlname, ".mtl" );
path_set_extension( mtlname, ".mtl" );
Sys_Printf( "writing %s\n", mtlname );
ExtractFileBase( bspName, base );

View File

@ -59,8 +59,7 @@ void ExportEntities( void ){
/* do some path mangling */
strcpy( filename, source );
StripExtension( filename );
strcat( filename, ".ent" );
path_set_extension( filename, ".ent" );
/* sanity check */
if ( bspEntData == NULL || bspEntDataSize == 0 ) {
@ -97,8 +96,7 @@ int ExportEntitiesMain( int argc, char **argv ){
/* do some path mangling */
strcpy( source, ExpandArg( argv[ argc - 1 ] ) );
StripExtension( source );
DefaultExtension( source, ".bsp" );
path_set_extension( source, ".bsp" );
/* load the bsp */
Sys_Printf( "Loading %s\n", source );

View File

@ -283,27 +283,20 @@ void ImageFree( image_t *image ){
/*
ImageFind()
finds an existing rgba image and returns a pointer to the image_t struct or NULL if not found
name is name without extension, as in images[ i ].name
*/
image_t *ImageFind( const char *filename ){
int i;
char name[ 1024 ];
image_t *ImageFind( const char *name ){
/* init */
ImageInit();
/* dummy check */
if ( filename == NULL || filename[ 0 ] == '\0' ) {
if ( name == NULL || name[ 0 ] == '\0' ) {
return NULL;
}
/* strip file extension off name */
strcpy( name, filename );
StripExtension( name );
/* search list */
for ( i = 0; i < MAX_IMAGES; i++ )
for ( int i = 0; i < MAX_IMAGES; ++i )
{
if ( images[ i ].name != NULL && !strcmp( name, images[ i ].name ) ) {
return &images[ i ];
@ -322,7 +315,6 @@ image_t *ImageFind( const char *filename ){
*/
image_t *ImageLoad( const char *filename ){
int i;
image_t *image;
char name[ 1024 ];
int size;
@ -349,12 +341,12 @@ image_t *ImageLoad( const char *filename ){
return image;
}
/* none found, so find first non-null image */
image = NULL;
for ( i = 0; i < MAX_IMAGES; i++ )
/* none found, so find first empty image slot */
for ( int i = 0; i < MAX_IMAGES; ++i )
{
if ( images[ i ].name == NULL ) {
image = &images[ i ];
image->name = copystring( name ); /* set it up */
break;
}
}
@ -364,31 +356,25 @@ image_t *ImageLoad( const char *filename ){
Error( "MAX_IMAGES (%d) exceeded, there are too many image files referenced by the map.", MAX_IMAGES );
}
/* set it up */
image->name = copystring( name );
/* attempt to load tga */
StripExtension( name );
strcat( name, ".tga" );
size = vfsLoadFile( (const char*) name, (void**) &buffer, 0 );
strcat( name, ".tga" ); // StripExtension( name ); already
size = vfsLoadFile( name, (void**) &buffer, 0 );
if ( size > 0 ) {
LoadTGABuffer( buffer, buffer + size, &image->pixels, &image->width, &image->height );
}
else
{
/* attempt to load png */
StripExtension( name );
strcat( name, ".png" );
size = vfsLoadFile( (const char*) name, (void**) &buffer, 0 );
path_set_extension( name, ".png" );
size = vfsLoadFile( name, (void**) &buffer, 0 );
if ( size > 0 ) {
LoadPNGBuffer( buffer, size, &image->pixels, &image->width, &image->height );
}
else
{
/* attempt to load jpg */
StripExtension( name );
strcat( name, ".jpg" );
size = vfsLoadFile( (const char*) name, (void**) &buffer, 0 );
path_set_extension( name, ".jpg" );
size = vfsLoadFile( name, (void**) &buffer, 0 );
if ( size > 0 ) {
if ( LoadJPGBuff( buffer, size, &image->pixels, &image->width, &image->height ) == -1 && image->pixels != NULL ) {
// On error, LoadJPGBuff might store a pointer to the error message in image->pixels
@ -399,9 +385,8 @@ image_t *ImageLoad( const char *filename ){
else
{
/* attempt to load dds */
StripExtension( name );
strcat( name, ".dds" );
size = vfsLoadFile( (const char*) name, (void**) &buffer, 0 );
path_set_extension( name, ".dds" );
size = vfsLoadFile( name, (void**) &buffer, 0 );
if ( size > 0 ) {
LoadDDSBuffer( buffer, size, &image->pixels, &image->width, &image->height );
@ -412,8 +397,7 @@ image_t *ImageLoad( const char *filename ){
DDSGetInfo( (ddsBuffer_t*) buffer, NULL, NULL, &pf );
Sys_Printf( "pf = %d\n", pf );
if ( image->width > 0 ) {
StripExtension( name );
strcat( name, "_converted.tga" );
path_set_extension( name, "_converted.tga" );
WriteTGA( "C:\\games\\quake3\\baseq3\\textures\\rad\\dds_converted.tga", image->pixels, image->width, image->height );
}
}
@ -443,8 +427,7 @@ image_t *ImageLoad( const char *filename ){
numImages++;
if ( alphaHack ) {
StripExtension( name );
strcat( name, "_alpha.jpg" );
path_set_extension( name, "_alpha.jpg" );
size = vfsLoadFile( (const char*) name, (void**) &buffer, 0 );
if ( size > 0 ) {
unsigned char *pixels;
@ -456,8 +439,7 @@ image_t *ImageLoad( const char *filename ){
}
} else {
if ( width == image->width && height == image->height ) {
int i;
for ( i = 0; i < width * height; ++i )
for ( int i = 0; i < width * height; ++i )
image->pixels[4 * i + 3] = pixels[4 * i + 2]; // copy alpha from blue channel
}
free( pixels );

View File

@ -2992,13 +2992,11 @@ int LightMain( int argc, char **argv ){
/* clean up map name */
strcpy( source, ExpandArg( argv[ i ] ) );
StripExtension( source );
DefaultExtension( source, ".bsp" );
path_set_extension( source, ".bsp" );
strcpy( name, ExpandArg( argv[ i ] ) );
if ( strcmp( name + strlen( name ) - 4, ".reg" ) ) { /* not .reg */
StripExtension( name );
DefaultExtension( name, ".map" );
if ( Q_stricmp( path_get_filename_base_end( name ), ".reg" ) ) { /* not .reg */
path_set_extension( name, ".map" );
}
/* ydnar: set default sample size */

View File

@ -978,9 +978,8 @@ void RadCreateDiffuseLights( void ){
light_t *light;
strcpy( dumpName, source );
StripExtension( dumpName );
sprintf( ext, "_bounce_%03d.map", iterations );
strcat( dumpName, ext );
path_set_extension( dumpName, ext );
file = fopen( dumpName, "wb" );
Sys_Printf( "Writing %s...\n", dumpName );
if ( file ) {

View File

@ -1303,8 +1303,7 @@ void SetupTraceNodes( void ){
/* open the file */
strcpy( filename, source );
StripExtension( filename );
strcat( filename, ".lin" );
path_set_extension( filename, ".lin" );
Sys_Printf( "Opening light trace file %s...\n", filename );
file = fopen( filename, "w" );
if ( file == NULL ) {

View File

@ -161,8 +161,7 @@ int ExportLightmapsMain( int argc, char **argv ){
/* do some path mangling */
strcpy( source, ExpandArg( argv[ argc - 1 ] ) );
StripExtension( source );
DefaultExtension( source, ".bsp" );
path_set_extension( source, ".bsp" );
/* load the bsp */
Sys_Printf( "Loading %s\n", source );
@ -196,8 +195,7 @@ int ImportLightmapsMain( int argc, char **argv ){
/* do some path mangling */
strcpy( source, ExpandArg( argv[ argc - 1 ] ) );
StripExtension( source );
DefaultExtension( source, ".bsp" );
path_set_extension( source, ".bsp" );
/* load the bsp */
Sys_Printf( "Loading %s\n", source );

View File

@ -480,8 +480,7 @@ int MiniMapBSPMain( int argc, char **argv ){
/* load the BSP first */
strcpy( source, ExpandArg( argv[ argc - 1 ] ) );
StripExtension( source );
DefaultExtension( source, ".bsp" );
path_set_extension( source, ".bsp" );
Sys_Printf( "Loading %s\n", source );
//BeginMapShaderFile( source ); //do not delete q3map2_*.shader on minimap generation
LoadShaderInfo();

View File

@ -400,12 +400,11 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap
/* shader renaming for sof2 */
if ( renameModelShaders ) {
strcpy( shaderName, picoShaderName );
StripExtension( shaderName );
if ( spawnFlags & 1 ) {
strcat( shaderName, "_RMG_BSP" );
path_set_extension( shaderName, "_RMG_BSP" );
}
else{
strcat( shaderName, "_BSP" );
path_set_extension( shaderName, "_BSP" );
}
si = ShaderInfoForShader( shaderName );
}

View File

@ -1854,7 +1854,7 @@ int ExportEntitiesMain( int argc, char **argv );
/* image.c */
void ImageFree( image_t *image );
image_t *ImageFind( const char *filename );
image_t *ImageFind( const char *name );
image_t *ImageLoad( const char *filename );

View File

@ -778,9 +778,10 @@ static void LoadShaderImages( shaderInfo_t *si ){
}
}
/* if no light image, use shader image */
/* if no light image, reuse shader image */
if ( si->lightImage == NULL ) {
si->lightImage = ImageLoad( si->shaderImage->name );
si->lightImage = si->shaderImage;
si->lightImage->refCount++;
}
/* create default and average colors */

View File

@ -216,8 +216,7 @@ void WriteSurfaceExtraFile( const char *path ){
/* open the file */
strcpy( srfPath, path );
StripExtension( srfPath );
strcat( srfPath, ".srf" );
path_set_extension( srfPath, ".srf" );
Sys_Printf( "Writing %s\n", srfPath );
sf = fopen( srfPath, "w" );
if ( sf == NULL ) {
@ -323,8 +322,7 @@ void LoadSurfaceExtraFile( const char *path ){
/* load the file */
strcpy( srfPath, path );
StripExtension( srfPath );
strcat( srfPath, ".srf" );
path_set_extension( srfPath, ".srf" );
Sys_Printf( "Loading %s\n", srfPath );
size = LoadFile( srfPath, (void**) &buffer );
if ( size <= 0 ) {

View File

@ -1164,15 +1164,13 @@ int VisMain( int argc, char **argv ){
/* load the bsp */
sprintf( source, "%s%s", inbase, ExpandArg( argv[ i ] ) );
StripExtension( source );
strcat( source, ".bsp" );
path_set_extension( source, ".bsp" );
Sys_Printf( "Loading %s\n", source );
LoadBSPFile( source );
/* load the portal file */
sprintf( portalfile, "%s%s", inbase, ExpandArg( argv[ i ] ) );
StripExtension( portalfile );
strcat( portalfile, ".prt" );
path_set_extension( portalfile, ".prt" );
Sys_Printf( "Loading %s\n", portalfile );
LoadPortals( portalfile );