From 3dd2ff55b1f4bb6716bb44b21cbd4029deb25cba Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Fri, 1 Oct 2010 11:28:07 +0200 Subject: [PATCH] support .skin files for models (modelname_.skin) like Q3A and DP --- tools/quake3/q3map2/model.c | 94 +++++++++++++++++++++++---- tools/quake3/q3map2/q3map2.h | 10 ++- tools/quake3/q3map2/surface.c | 2 +- tools/quake3/q3map2/surface_foliage.c | 2 +- 4 files changed, 94 insertions(+), 14 deletions(-) diff --git a/tools/quake3/q3map2/model.c b/tools/quake3/q3map2/model.c index cbba5c5d..62747b48 100644 --- a/tools/quake3/q3map2/model.c +++ b/tools/quake3/q3map2/model.c @@ -206,7 +206,7 @@ InsertModel() - ydnar adds a picomodel into the bsp */ -void InsertModel( char *name, int frame, m4x4_t transform, remap_t *remap, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle ) +void InsertModel( char *name, int skin, int frame, m4x4_t transform, remap_t *remap, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle ) { int i, j, k, s, numSurfaces; m4x4_t identity, nTransform; @@ -222,14 +222,64 @@ void InsertModel( char *name, int frame, m4x4_t transform, remap_t *remap, shade byte *color; picoIndex_t *indexes; remap_t *rm, *glob; + skinfile_t *sf, *sf2; double normalEpsilon_save; double distanceEpsilon_save; + char skinfilename[ MAX_QPATH ]; + FILE *skinfilehandle; /* get model */ model = LoadModel( name, frame ); if( model == NULL ) return; + + /* load skin file */ + snprintf(skinfilename, sizeof(skinfilename), "%s_%d.skin", name, skin); + skinfilename[sizeof(skinfilename)-1] = 0; + skinfilehandle = fopen(skinfilename, "r"); + if(!skinfilehandle) + { + /* fallback to skin 0 if invalid */ + snprintf(skinfilename, sizeof(skinfilename), "%s_0.skin", name); + skinfilename[sizeof(skinfilename)-1] = 0; + skinfilehandle = fopen(skinfilename, "r"); + if(skinfilehandle) + Sys_Printf( "Skin %d of %s does not exist, using 0 instead\n", skin, name ); + } + sf = NULL; + if(skinfilehandle) + { + Sys_Printf( "Using skin %d of %s\n", skin, name ); + int pos; + for(;;) + { + // for fscanf + char format[64]; + char buf[1024]; + + if(!fgets(buf, sizeof(buf), skinfilehandle)) + break; + + /* create new item */ + sf2 = sf; + sf = safe_malloc( sizeof( *sf ) ); + sf->next = sf2; + + sprintf(format, "replace %%%ds %%%ds%%n", (int)sizeof(sf->name)-1, (int)sizeof(sf->to)-1); + pos = 0; + if(sscanf(buf, format, &sf->name, &sf->to, &pos) > 0 && pos > 0) + continue; + sprintf(format, "%%%ds,%%%ds%%n", (int)sizeof(sf->name)-1, (int)sizeof(sf->to)-1); + pos = 0; + if(sscanf(buf, format, &sf->name, &sf->to, &pos) > 0 && pos > 0) + continue; + + /* invalid input line -> discard sf struct */ + free(sf); + sf = sf2; + } + } /* handle null matrix */ if( transform == NULL ) @@ -283,7 +333,27 @@ void InsertModel( char *name, int frame, m4x4_t transform, remap_t *remap, shade picoShaderName = ""; else picoShaderName = PicoGetShaderName( shader ); - + + /* handle .skin file */ + if(sf) + { + picoShaderName = NULL; + for(sf2 = sf; sf2 != NULL; sf2 = sf2->next) + { + if( !Q_stricmp( surface->name, sf2->name ) ) + { + Sys_FPrintf( SYS_VRB, "Skin file: mapping %s to %s\n", surface->name, sf2->to ); + picoShaderName = sf2->to; + break; + } + } + if(!picoShaderName) + { + Sys_FPrintf( SYS_VRB, "Skin file: not mapping %s\n", surface->name ); + continue; + } + } + /* handle shader remapping */ glob = NULL; for( rm = remap; rm != NULL; rm = rm->next ) @@ -603,7 +673,7 @@ adds misc_model surfaces to the bsp void AddTriangleModels( entity_t *e ) { - int num, frame, castShadows, recvShadows, spawnFlags; + int num, frame, skin, castShadows, recvShadows, spawnFlags; entity_t *e2; const char *targetName; const char *target, *model, *value; @@ -806,21 +876,23 @@ void AddTriangleModels( entity_t *e ) if ( strcmp( "", ValueForKey( e2, "_shadeangle" ) ) ) shadeAngle = FloatForKey( e2, "_shadeangle" ); /* vortex' aliases */ - else if ( strcmp( "", ValueForKey( mapEnt, "_smoothnormals" ) ) ) - shadeAngle = FloatForKey( mapEnt, "_smoothnormals" ); - else if ( strcmp( "", ValueForKey( mapEnt, "_sn" ) ) ) - shadeAngle = FloatForKey( mapEnt, "_sn" ); - else if ( strcmp( "", ValueForKey( mapEnt, "_smooth" ) ) ) - shadeAngle = FloatForKey( mapEnt, "_smooth" ); + else if ( strcmp( "", ValueForKey( e2, "_smoothnormals" ) ) ) + shadeAngle = FloatForKey( e2, "_smoothnormals" ); + else if ( strcmp( "", ValueForKey( e2, "_sn" ) ) ) + shadeAngle = FloatForKey( e2, "_sn" ); + else if ( strcmp( "", ValueForKey( e2, "_smooth" ) ) ) + shadeAngle = FloatForKey( e2, "_smooth" ); if( shadeAngle < 0.0f ) shadeAngle = 0.0f; if( shadeAngle > 0.0f ) Sys_Printf( "misc_model has shading angle of %.4f\n", shadeAngle ); - + + skin = IntForKey(e2, "skin"); + /* insert the model */ - InsertModel( (char*) model, frame, transform, remap, celShader, mapEntityNum, castShadows, recvShadows, spawnFlags, lightmapScale, lightmapSampleSize, shadeAngle ); + InsertModel( (char*) model, skin, frame, transform, remap, celShader, mapEntityNum, castShadows, recvShadows, spawnFlags, lightmapScale, lightmapSampleSize, shadeAngle ); /* free shader remappings */ while( remap != NULL ) diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index 078f46e2..d0f903fb 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -645,6 +645,14 @@ typedef struct remap_s } remap_t; +typedef struct skinfile_s +{ + struct skinfile_s *next; + char name[ 1024 ]; + char to[ MAX_QPATH ]; +} +skinfile_t; + /* wingdi.h hack, it's the same: 0 */ #undef CM_NONE @@ -1651,7 +1659,7 @@ void PicoPrintFunc( int level, const char *str ); void PicoLoadFileFunc( char *name, byte **buffer, int *bufSize ); picoModel_t *FindModel( char *name, int frame ); picoModel_t *LoadModel( char *name, int frame ); -void InsertModel( char *name, int frame, m4x4_t transform, remap_t *remap, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle ); +void InsertModel( char *name, int skin, int frame, m4x4_t transform, remap_t *remap, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle ); void AddTriangleModels( entity_t *e ); diff --git a/tools/quake3/q3map2/surface.c b/tools/quake3/q3map2/surface.c index 76385cb3..920aff35 100644 --- a/tools/quake3/q3map2/surface.c +++ b/tools/quake3/q3map2/surface.c @@ -3173,7 +3173,7 @@ int AddSurfaceModelsToTriangle_r( mapDrawSurface_t *ds, surfaceModel_t *model, b } /* insert the model */ - InsertModel( (char *) model->model, 0, transform, NULL, ds->celShader, ds->entityNum, ds->castShadows, ds->recvShadows, 0, ds->lightmapScale, 0, 0 ); + InsertModel( (char *) model->model, 0, 0, transform, NULL, ds->celShader, ds->entityNum, ds->castShadows, ds->recvShadows, 0, ds->lightmapScale, 0, 0 ); /* return to sender */ return 1; diff --git a/tools/quake3/q3map2/surface_foliage.c b/tools/quake3/q3map2/surface_foliage.c index 71875af0..cc5452ae 100644 --- a/tools/quake3/q3map2/surface_foliage.c +++ b/tools/quake3/q3map2/surface_foliage.c @@ -275,7 +275,7 @@ void Foliage( mapDrawSurface_t *src ) m4x4_scale_for_vec3( transform, scale ); /* add the model to the bsp */ - InsertModel( foliage->model, 0, transform, NULL, NULL, src->entityNum, src->castShadows, src->recvShadows, 0, src->lightmapScale, 0, 0 ); + InsertModel( foliage->model, 0, 0, transform, NULL, NULL, src->entityNum, src->castShadows, src->recvShadows, 0, src->lightmapScale, 0, 0 ); /* walk each new surface */ for( i = oldNumMapDrawSurfs; i < numMapDrawSurfs; i++ ) -- 2.39.2