Fixes resulting from static code analysis

This commit is contained in:
Walter Julius Hennecke 2011-12-05 10:50:05 +01:00
parent 958501a9e3
commit 12851350a9

View file

@ -398,7 +398,6 @@ static int CG_ParseAnimationSndFile( const char *filename, int animFileIndex )
return i;
}
#else
/* TODO: dynamic file size? */
static int CG_ParseAnimationSndFile( const char *filename, int animFileIndex )
{
char *text_p;
@ -526,6 +525,7 @@ A lot more efficient considering how many freakin more animations we introduced
*/
//
//static qboolean CG_ParseAnimationFile( const char *filename, clientInfo_t *ci ) {
#ifdef QVM
static int CG_ParseAnimationFile( const char* filename/*, clientInfo_t *ci*/ ) {
char *text_p, *prev;
int len;
@ -715,6 +715,208 @@ static int CG_ParseAnimationFile( const char* filename/*, clientInfo_t *ci*/ ) {
return i;
//return qtrue;
}
#else
static int CG_ParseAnimationFile( const char* filename/*, clientInfo_t *ci*/ ) {
char *text_p, *prev;
int len;
int i;
char *token;
float fps;
int skip;
char *text;
fileHandle_t f;
animation_t *animations;
//CG_Printf( "Anim is %s\n", filename );
text = (char *)malloc(sizeof(char)*20000);
if(!text) {
CG_Printf("CG_ParseAnimationFile: couldn't allocate %u bytes\n", sizeof(char)*20000);
return -1;
}
if ( cg_numAnims > 0 ) {
for ( i = 0; i <= cg_numAnims; i++ ) {
if ( !Q_stricmpn( cg_animsList[i].animFileRoute, filename, (int)strlen( filename ) ) ) { //We found a matching anim set
//Com_Printf( S_COLOR_RED "Using index: %i\n", i );
free(text);
return i;
}
}
}
// load the file
len = trap_FS_FOpenFile( filename, &f, FS_READ );
if ( len <= 0 ) {
CG_Printf( S_COLOR_RED "File %s not found\n", filename );
free(text);
return -1; //qfalse
}
if ( len >= sizeof( text ) - 1 ) {
CG_Printf( S_COLOR_RED "File %s too long\n", filename );
free(text);
return -1; //qfalse
}
trap_FS_Read( text, len, f );
text[len] = 0;
trap_FS_FCloseFile( f );
//animations = ci->animations;
animations = cg_animsList[cg_numAnims].animations;
//copy the file name to the gloabl anims array. It doesn't matter
//if it returns false, since the same cell will be flushed on the next call then.
memset( cg_animsList[cg_numAnims].animFileRoute, 0, MAX_QPATH );
Q_strncpyz( cg_animsList[cg_numAnims].animFileRoute, filename, MAX_QPATH );
//flush the anims
memset( animations, 0, sizeof( animations ) );
// parse the text
text_p = text;
skip = 0; // quite the compiler warning
/*
ci->footsteps = FOOTSTEP_NORMAL;
VectorClear( ci->headOffset );
ci->gender = GENDER_MALE;
Q_strncpyz(ci->soundPath, ci->modelName, sizeof(ci->soundPath));*/
// read optional parameters
while ( 1 ) {
prev = text_p; // so we can unget
token = COM_Parse( &text_p );
if ( !token ) {
break;
}
/*if ( !Q_stricmp( token, "footsteps" ) ) {
token = COM_Parse( &text_p );
if ( !token ) {
break;
}
if ( !Q_stricmp( token, "default" ) || !Q_stricmp( token, "normal" ) ) {
ci->footsteps = FOOTSTEP_NORMAL;
} else if ( !Q_stricmp( token, "borg" ) ) {
ci->footsteps = FOOTSTEP_BORG;
} else if ( !Q_stricmp( token, "reaver" ) ) {
ci->footsteps = FOOTSTEP_REAVER;
} else if ( !Q_stricmp( token, "species" ) ) {
ci->footsteps = FOOTSTEP_SPECIES;
} else if ( !Q_stricmp( token, "warbot" ) ) {
ci->footsteps = FOOTSTEP_WARBOT;
} else if ( !Q_stricmp( token, "boot" ) ) {
ci->footsteps = FOOTSTEP_BOOT;
} else if ( !Q_stricmp( token, "flesh" ) ) { // Old Q3 defaults, for compatibility. -PJL
ci->footsteps = FOOTSTEP_SPECIES;
} else if ( !Q_stricmp( token, "mech" ) ) { // Ditto
ci->footsteps = FOOTSTEP_BORG;
} else if ( !Q_stricmp( token, "energy" ) ) { // Ditto
ci->footsteps = FOOTSTEP_BORG;
} else {
CG_Printf( "Bad footsteps parm in %s: %s\n", filename, token );
}
continue;
} else if ( !Q_stricmp( token, "headoffset" ) ) {
for ( i = 0 ; i < 3 ; i++ ) {
token = COM_Parse( &text_p );
if ( !token ) {
break;
}
ci->headOffset[i] = atof( token );
}
continue;
} else if ( !Q_stricmp( token, "sex" ) ) {
token = COM_Parse( &text_p );
if ( !token ) {
break;
}
if ( token[0] == 'f' || token[0] == 'F' ) {
ci->gender = GENDER_FEMALE;
} else if ( token[0] == 'n' || token[0] == 'N' ) {
ci->gender = GENDER_NEUTER;
} else {
ci->gender = GENDER_MALE;
}
continue;
} else if ( !Q_stricmp( token, "soundpath" ) ) {
token = COM_Parse( &text_p );
if ( !token ) {
break;
}
Q_strncpyz(ci->soundPath,token,sizeof (ci->soundPath) );
continue;
} */
// if it is a number, start parsing animations
if ( token[0] >= '0' && token[0] <= '9' ) {
text_p = prev; // unget the token
break;
}
Com_Printf( "unknown token '%s' is %s\n", token, filename );
}
// read information for each frame
for ( i = 0 ; i < MAX_ANIMATIONS ; i++ ) {
token = COM_Parse( &text_p );
if ( !token ) {
break;
}
animations[i].firstFrame = atoi( token );
// leg only frames are adjusted to not count the upper body only frames
if ( i == LEGS_KNEEL1 ) { //LEGS_WALKCR
skip = animations[LEGS_KNEEL1].firstFrame - animations[TORSO_ACTIVATEMEDKIT1].firstFrame; //TORSO_GESTURE
}
if ( i >= LEGS_KNEEL1 ) {
animations[i].firstFrame -= skip;
}
token = COM_Parse( &text_p );
if ( !token ) {
break;
}
animations[i].numFrames = atoi( token );
token = COM_Parse( &text_p );
if ( !token ) {
break;
}
animations[i].loopFrames = atoi( token );
token = COM_Parse( &text_p );
if ( !token ) {
break;
}
fps = atof( token );
if ( fps == 0 ) {
fps = 1;
}
animations[i].frameLerp = 1000 / fps;
animations[i].initialLerp = 1000 / fps;
}
if ( i != MAX_ANIMATIONS ) {
CG_Printf( S_COLOR_RED "Error parsing animation file: %s", filename );
//return qfalse;
free(text);
return -1;
}
//CG_Printf( S_COLOR_RED "Cached File: %s\n", cgs.animsList[cgs.numAnims].animFileRoute );
//return ++cg_numAnims;
i = cg_numAnims;
if ( cg_numAnims < MAX_CLIENTS ) {
cg_numAnims++; //offset for the next time :)
}
free(text);
return i;
//return qtrue;
}
#endif
/*
======================
@ -1050,7 +1252,7 @@ needed to put together
a character model.
======================
*/
#ifdef QVM
static qboolean CG_ParseModelDataFile( clientInfo_t *ci, const char *charName,
const char *modelName, const char *skinName ) {
fileHandle_t file;
@ -1482,6 +1684,458 @@ static qboolean CG_ParseModelDataFile( clientInfo_t *ci, const char *charName,
//model! OWNED!
return qtrue;
}
#else
static qboolean CG_ParseModelDataFile( clientInfo_t *ci, const char *charName,
const char *modelName, const char *skinName ) {
fileHandle_t file;
int file_len;
char *charText;
char *textPtr, *prevValue;
char fileName[MAX_QPATH];
//char animPath[MAX_QPATH];
int i, n;
char *token;
char legsFileRoute[MAX_QPATH];
char animSndFileRoute[MAX_QPATH];
qboolean skinSetFound=qfalse;
//size_t strLen;
charText = (char *)malloc(sizeof(char)*20000);
if(!charText) {
CG_Printf("CG_ParseModelDataFile: couldn't allocate %u byte\n", sizeof(char)*20000);
return qfalse;
}
//create the file route
Com_sprintf( fileName, sizeof(fileName), "models/players_rpgx/%s/%s.model", charName, modelName);
//Okay... gotta get the hang of ANSI C text parsing >.<
//first... I guess load the file
file_len = trap_FS_FOpenFile( fileName, &file, FS_READ );
//Error handle
//if length was 0, ie file not found or was empty
if (file_len <= 0 ) {
free(charText);
return qfalse;
}
//Another error... if text is WAY bigger than our available buffer O_O
if ( file_len >= sizeof( charText ) - 1 ) {
Com_Printf( S_COLOR_RED "Model Data File %s too long... WAY too long\n", fileName );
free(charText);
return qfalse;
}
//initialize the buffer
memset( charText, 0, sizeof( charText ) );
//read data into char array
//i guess we use a char array so we can actually specify size/width.
trap_FS_Read( charText, file_len, file );
//I guess this is needed to mark the EOF.
charText[file_len] = 0;
//Free memory. Close Files
trap_FS_FCloseFile( file );
//default values if needed
CG_InitModelData( ci );
//Used to just clear any previous parse temp data
COM_BeginParseSession();
//transfer our data from a char array to a char ptr.
//needed for the parsing func methinks
textPtr = charText;
token = COM_Parse( &textPtr ); //COM_Parse seems to work by splitting up each line of text by the spaces,
//and then removes that chunk from the original
//Okay, we should have the beginning variable first... which should be a '{'
//from the looks of this, I think we have to do this after
//every parse call. O_O
if ( !token[0] ) {
Com_Printf( S_COLOR_RED "No data found in model data buffer!\n");
free(charText);
return qfalse;
}
if ( Q_stricmp(token, "{" ) ) {
Com_Printf(S_COLOR_RED "Missing { in %s\n", fileName);
free(charText);
return qfalse;
}
while ( 1 ) {
prevValue = textPtr; //set a backup
token = COM_Parse( &textPtr );
if (!token[0] || !token ) { //we've hit the end of the file. w00t! exit!
break;
}
//if we randomly find a brace in here (ie a sub-struct that may have no header)
//just skip it. :P
if ( !Q_stricmpn( token, "{", 1 ) ) {
SkipBracedSection ( &textPtr );
}
if ( !Q_stricmpn( token, "animsConfig", 11 ) ) {
if( COM_ParseString( &textPtr, &token ) ) {
continue;
}
ci->animIndex = CG_ParseAnimationFile( token );
//no valid anim file found. Don't give up hope though.
//We have a backup resort at the end if need be. :)
if ( ci->animIndex == -1 ) {
Com_Printf( S_COLOR_RED "WARNING: Was unable to load file %s.\n", token );
}
continue;
}
//anim sounds config file
else if ( !Q_stricmpn( token, "animSoundsConfig", 16 ) ) {
if ( COM_ParseString( &textPtr, &token ) ) {
continue;
}
//check to see if we have a valid animlist we can sync these
//sounds to. if not, we'll put the file route asside, and
//try again at the end.
if ( ci->animIndex >= 0 ) {
ci->animSndIndex = CG_ParseAnimationSndFile( token, ci->animIndex );
if ( ci->animSndIndex == -1 ) {
Com_Printf( S_COLOR_RED "WARNING: Unable to load file: %s\n", token );
}
}
else {
Q_strncpyz( animSndFileRoute, token, sizeof( animSndFileRoute ) );
}
continue;
}
//character's legs model
else if ( !Q_stricmpn( token, "legsModel", 9 ) ) {
if( COM_ParseString( &textPtr, &token ) ) {
continue;
}
ci->legsModel = trap_R_RegisterModel( token );
if (!ci->legsModel) {
Com_Printf( S_COLOR_RED "ERROR: Unable to load legs model: %s\n", token);
free(charText);
return qfalse;
}
//if loaded no anims yet, copy the legs route to this variable,
//and we'll try again at the end of the function
//if ( ci->animIndex == -1 ) {
Q_strncpyz( legsFileRoute, token, sizeof( legsFileRoute ) );
//} Actually. just copy it regardless. Just in case
continue;
}
//character's torso model
else if ( !Q_stricmpn( token, "torsoModel", 10 ) ) {
if( COM_ParseString( &textPtr, &token ) ) {
continue;
}
ci->torsoModel = trap_R_RegisterModel( token );
//Com_Printf("Torsomodel passed as %s, %i\n", token, (int)ci->torsoModel);
if (!ci->torsoModel) {
Com_Printf( S_COLOR_RED "ERROR: Unable to load torso model: %s\n", token);
return qfalse;
}
continue;
}
//character's headmodel
else if ( !Q_stricmpn( token, "headModel", 9 ) ) {
//return true = no extra text found on this line - bad! O_O!
if( COM_ParseString( &textPtr, &token ) ) {
continue;
}
ci->headModel = trap_R_RegisterModel( token );
if (!ci->headModel) {
Com_Printf( S_COLOR_RED "ERROR: Unable to load head model: %s\n", token);
free(charText);
return qfalse;
}
continue;
}
//holster model (basically just a null md3 with 2 tags: one for phaser, other for tric)
else if ( !Q_stricmpn( token, "holsterModel", 12 ) ) {
if( COM_ParseString( &textPtr, &token ) ) {
continue;
}
ci->holsterModel = trap_R_RegisterModel( token );
//You'd hope like hell this will never happen. :P
if (!ci->holsterModel) {
Com_Printf( S_COLOR_RED "ERROR: Unable to load holster model: %s\n", token);
free(charText);
return qfalse;
}
continue;
}
// Custom bolton models... oi O_o
else if ( !Q_stricmpn( token, "boltonModels", 12 ) ) {
//needed coz '{' could also be on next line
token = COM_Parse( &textPtr );
if ( !token[0] ) { //if that was it
break;
} else { //else, if next character is '{'
if ( !Q_stricmpn( token, "{", 1 ) ) {
token = COM_Parse( &textPtr );
if ( !token[0] ) {
break;
}
//loop till we hit the end of the brackets
i = 0;
while ( Q_stricmp( token, "}" ) ) {
if ( !Q_stricmpn( token, "BOLTON_", 7 ) ) {
ci->boltonTags[i].modelBase = GetIDForString( BoltonTable, token );
if( COM_ParseString( &textPtr, &token ) ) {
continue;
}
if (!Q_stricmpn( token, "tag_", 4 ) ) {
Q_strncpyz(ci->boltonTags[i].tagName, token, sizeof (ci->boltonTags[i].tagName) );
if( COM_ParseString( &textPtr, &token ) ) {
continue;
}
ci->boltonTags[i].tagModel = trap_R_RegisterModel( token );
if (!ci->boltonTags[i].tagModel) {
Com_Printf( S_COLOR_RED "WARNING: Unable to load bolton model: %s\n", token);
}
i++;
if (i > MAX_BOLTONS -1) {
break;
}
}
}
//Com_Printf("Index: %i, Name: %s, Handle: %i\n", ci->boltonTags[ci->numBoltOns].modelBase, ci->boltonTags[ci->numBoltOns].tagName, ci->boltonTags[ci->numBoltOns].tagModel );
token = COM_Parse( &textPtr );
if ( !token[0] ) {
break;
}
}
}
}
}
//whether char is allowed to wear ranks
else if ( !Q_stricmpn( token, "hasRanks", 8 ) ) {
if (COM_ParseInt(&textPtr, &n ) ) {
continue;
}
if ( n > 0 )
ci->hasRanks = qtrue;
else
ci->hasRanks = qfalse;
continue;
}
//player footsteps.
//FIXME: Is it possible to make these things dynamic, so we can
//put in our own footstep sounds?
/*else if ( !Q_stricmp( token, "footsteps" ) ) {
token = COM_Parse( &textPtr );
if ( !token ) {
break;
}
if ( !Q_stricmp( token, "default" ) || !Q_stricmp( token, "normal" ) ) {
ci->footsteps = FOOTSTEP_NORMAL;
} else if ( !Q_stricmp( token, "borg" ) ) {
ci->footsteps = FOOTSTEP_BORG;
} else if ( !Q_stricmp( token, "reaver" ) ) {
ci->footsteps = FOOTSTEP_REAVER;
} else if ( !Q_stricmp( token, "species" ) ) {
ci->footsteps = FOOTSTEP_SPECIES;
} else if ( !Q_stricmp( token, "warbot" ) ) {
ci->footsteps = FOOTSTEP_WARBOT;
} else if ( !Q_stricmp( token, "boot" ) ) {
ci->footsteps = FOOTSTEP_BOOT;
} else if ( !Q_stricmp( token, "flesh" ) ) { // Old Q3 defaults, for compatibility. -PJL
ci->footsteps = FOOTSTEP_SPECIES;
} else if ( !Q_stricmp( token, "mech" ) ) { // Ditto
ci->footsteps = FOOTSTEP_BORG;
} else if ( !Q_stricmp( token, "energy" ) ) { // Ditto
ci->footsteps = FOOTSTEP_BORG;
} else {
CG_Printf( "Bad footsteps parm in %s: %s\n", fileName, token );
}
continue;
} */
//offset for player head in the scoreboard or whatever
else if ( !Q_stricmp( token, "headoffset" ) ) {
for ( i = 0 ; i < 3 ; i++ ) {
token = COM_Parse( &textPtr );
if ( !token ) {
break;
}
ci->headOffset[i] = atof( token );
}
continue;
}
//what gender the character is
else if ( !Q_stricmpn( token, "sex", 3 ) ) {
if (COM_ParseString( &textPtr, &token ) ) {
continue;
}
if ( token[0] == 'f' || token[0] == 'F' ) {
ci->gender = GENDER_FEMALE;
} else if ( token[0] == 'n' || token[0] == 'N' ) {
ci->gender = GENDER_NEUTER;
} else {
ci->gender = GENDER_MALE;
}
continue;
}
//file path to model sound files
else if ( !Q_stricmpn( token, "soundPath", 9 ) ) {
if (COM_ParseString( &textPtr, &token ) ){
continue;
}
Q_strncpyz( ci->soundPath, token, sizeof(ci->soundPath) );
continue;
}
//TiM - The skinset is defined
else if ( !Q_stricmpn( token, "skinSet", 7 ) ) {
if ( COM_ParseString( &textPtr, &token ) ) {
continue;
}
if ( CG_ParseSkinSetDataFile( ci, token, charName, skinName ) )
{
skinSetFound = qtrue;
}
continue;
}
}
//if any of the models or skins were left blank, then output false. Coz we need them. :P
if (!ci->headModel || !ci->torsoModel || !ci->legsModel ) {
Com_Printf( S_COLOR_RED "One or more necessary model files weren't loaded from %s\n", fileName );
free(charText);
return qfalse;
}
if ( !skinSetFound )
{
if ( !CG_ParseSkinSetDataFile( ci, va("%s_*", modelName, skinName ), charName, skinName ) )
{
CG_Printf( S_COLOR_RED "ERROR: Tried loading default skin set, however it failed.\n");
}
}
if (!ci->headSkin || !ci->torsoSkin || !ci->legsSkin ) {
Com_Printf( S_COLOR_RED "One or more necessary skin files weren't loaded from %s\n", fileName );
free(charText);
return qfalse;
}
//if modder specified no animations file route, or they did, and it sucked (ie -1 ),
//Then try looking for one in the same directory as the lower.mdr file
//k... the goal of this is to take a string like
//models/players_rpgx/crewman_male/lower.mdr
//and turn it into
//models/players_rpgx/crewman_male/animation.cfg
if ( ci->animIndex == -1 && strlen( legsFileRoute ) > 0 ) {
//get length of file route
i = (int)strlen(legsFileRoute);
while( 1 ) {
//if we looped all the way to the end.... ie BAD
if (i <= 0) {
//we obviously have no animation directory :(
Com_Printf(S_COLOR_RED "ERROR: Was unable to calculate location of animation.cfg for %s\n", fileName);
free(charText);
return qfalse;
}
//if this is the first '/' we come across from going from the end to the start
if (legsFileRoute[i] == '/' ) {
//copy i bytes of data from token to animpath (effectively giving us the route, with no file)
Q_strncpyz(legsFileRoute, legsFileRoute, (i = i + 2 )); //+2 for the null char these things auto assign at the end... i think
break; //won't work without it anyway :P
}
i--;
}
//add animation.cfg to the end of the string
Q_strcat(legsFileRoute, sizeof(legsFileRoute), "animation.cfg");
//Com_Printf( S_COLOR_RED "WARNING: Failed to load animation file specified in model config, attempting to load %s\n", legsFileRoute );
//parse it ^_^
ci->animIndex = CG_ParseAnimationFile( legsFileRoute );
if ( ci->animIndex < 0 ) {
Com_Printf( "Tried loading anim data from location %s, however nothing was valid.\n", legsFileRoute );
free(charText);
return qfalse;
}
}
else {
if ( !legsFileRoute[0] ) {
Com_Printf( S_COLOR_RED "Couldn't load/locate any player animation data for player: %s.\n", charName );
free(charText);
return qfalse;
}
}
//We'll check again if we can load a sound config file after everything else
if ( ci->animSndIndex == -1 && animSndFileRoute[0] )
{
ci->animSndIndex = CG_ParseAnimationSndFile( animSndFileRoute, ci->animIndex );
if ( ci->animSndIndex == -1 ) {
Com_Printf( S_COLOR_RED "ERROR: Unable to load sound config file: %s.\n", animSndFileRoute );
}
}
ci->animsFlushed = qfalse;
//TiM: Cheap hack - let us specifically check for hazard models
if ( !Q_stricmp( modelName, "hazard" ) )
ci->isHazardModel = qtrue;
//holy fudgenuggets. after all that checking, we actually made it to the end and have a valid freaking
//model! OWNED!
free(charText);
return qtrue;
}
#endif
/*
=============================================================================