You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
241 lines
7.2 KiB
241 lines
7.2 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
// |
|
//=============================================================================// |
|
#include "cbase.h" |
|
#include "isaverestore.h" |
|
#include "saverestoretypes.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: iterates through a typedescript data block, so it can insert key/value data into the block |
|
// Input : *pObject - pointer to the struct or class the data is to be insterted into |
|
// *pFields - description of the data |
|
// iNumFields - number of fields contained in pFields |
|
// char *szKeyName - name of the variable to look for |
|
// char *szValue - value to set the variable to |
|
// Output : Returns true if the variable is found and set, false if the key is not found. |
|
//----------------------------------------------------------------------------- |
|
bool ParseKeyvalue( void *pObject, typedescription_t *pFields, int iNumFields, const char *szKeyName, const char *szValue ) |
|
{ |
|
int i; |
|
typedescription_t *pField; |
|
|
|
for ( i = 0; i < iNumFields; i++ ) |
|
{ |
|
pField = &pFields[i]; |
|
|
|
int fieldOffset = pField->fieldOffset[ TD_OFFSET_NORMAL ]; |
|
|
|
// Check the nested classes, but only if they aren't in array form. |
|
if ((pField->fieldType == FIELD_EMBEDDED) && (pField->fieldSize == 1)) |
|
{ |
|
for ( datamap_t *dmap = pField->td; dmap != NULL; dmap = dmap->baseMap ) |
|
{ |
|
void *pEmbeddedObject = (void*)((char*)pObject + fieldOffset); |
|
if ( ParseKeyvalue( pEmbeddedObject, dmap->dataDesc, dmap->dataNumFields, szKeyName, szValue) ) |
|
return true; |
|
} |
|
} |
|
|
|
if ( (pField->flags & FTYPEDESC_KEY) && !stricmp(pField->externalName, szKeyName) ) |
|
{ |
|
switch( pField->fieldType ) |
|
{ |
|
case FIELD_MODELNAME: |
|
case FIELD_SOUNDNAME: |
|
case FIELD_STRING: |
|
(*(string_t *)((char *)pObject + fieldOffset)) = AllocPooledString( szValue ); |
|
return true; |
|
|
|
case FIELD_TIME: |
|
case FIELD_FLOAT: |
|
(*(float *)((char *)pObject + fieldOffset)) = atof( szValue ); |
|
return true; |
|
|
|
case FIELD_BOOLEAN: |
|
(*(bool *)((char *)pObject + fieldOffset)) = (bool)(atoi( szValue ) != 0); |
|
return true; |
|
|
|
case FIELD_CHARACTER: |
|
(*(char *)((char *)pObject + fieldOffset)) = (char)atoi( szValue ); |
|
return true; |
|
|
|
case FIELD_SHORT: |
|
(*(short *)((char *)pObject + fieldOffset)) = (short)atoi( szValue ); |
|
return true; |
|
|
|
case FIELD_INTEGER: |
|
case FIELD_TICK: |
|
(*(int *)((char *)pObject + fieldOffset)) = atoi( szValue ); |
|
return true; |
|
|
|
case FIELD_POSITION_VECTOR: |
|
case FIELD_VECTOR: |
|
UTIL_StringToVector( (float *)((char *)pObject + fieldOffset), szValue ); |
|
return true; |
|
|
|
case FIELD_VMATRIX: |
|
case FIELD_VMATRIX_WORLDSPACE: |
|
UTIL_StringToFloatArray( (float *)((char *)pObject + fieldOffset), 16, szValue ); |
|
return true; |
|
|
|
case FIELD_MATRIX3X4_WORLDSPACE: |
|
UTIL_StringToFloatArray( (float *)((char *)pObject + fieldOffset), 12, szValue ); |
|
return true; |
|
|
|
case FIELD_COLOR32: |
|
UTIL_StringToColor32( (color32 *) ((char *)pObject + fieldOffset), szValue ); |
|
return true; |
|
|
|
case FIELD_CUSTOM: |
|
{ |
|
SaveRestoreFieldInfo_t fieldInfo = |
|
{ |
|
(char *)pObject + fieldOffset, |
|
pObject, |
|
pField |
|
}; |
|
pField->pSaveRestoreOps->Parse( fieldInfo, szValue ); |
|
return true; |
|
} |
|
|
|
default: |
|
case FIELD_INTERVAL: // Fixme, could write this if needed |
|
case FIELD_CLASSPTR: |
|
case FIELD_MODELINDEX: |
|
case FIELD_MATERIALINDEX: |
|
case FIELD_EDICT: |
|
Warning( "Bad field in entity!!\n" ); |
|
Assert(0); |
|
break; |
|
} |
|
} |
|
} |
|
|
|
return false; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: iterates through a typedescript data block, so it can insert key/value data into the block |
|
// Input : *pObject - pointer to the struct or class the data is to be insterted into |
|
// *pFields - description of the data |
|
// iNumFields - number of fields contained in pFields |
|
// char *szKeyName - name of the variable to look for |
|
// char *szValue - value to set the variable to |
|
// Output : Returns true if the variable is found and set, false if the key is not found. |
|
//----------------------------------------------------------------------------- |
|
bool ExtractKeyvalue( void *pObject, typedescription_t *pFields, int iNumFields, const char *szKeyName, char *szValue, int iMaxLen ) |
|
{ |
|
int i; |
|
typedescription_t *pField; |
|
|
|
for ( i = 0; i < iNumFields; i++ ) |
|
{ |
|
pField = &pFields[i]; |
|
|
|
int fieldOffset = pField->fieldOffset[ TD_OFFSET_NORMAL ]; |
|
|
|
// Check the nested classes, but only if they aren't in array form. |
|
if ((pField->fieldType == FIELD_EMBEDDED) && (pField->fieldSize == 1)) |
|
{ |
|
for ( datamap_t *dmap = pField->td; dmap != NULL; dmap = dmap->baseMap ) |
|
{ |
|
void *pEmbeddedObject = (void*)((char*)pObject + fieldOffset); |
|
if ( ExtractKeyvalue( pEmbeddedObject, dmap->dataDesc, dmap->dataNumFields, szKeyName, szValue, iMaxLen ) ) |
|
return true; |
|
} |
|
} |
|
|
|
if ( (pField->flags & FTYPEDESC_KEY) && !stricmp(pField->externalName, szKeyName) ) |
|
{ |
|
switch( pField->fieldType ) |
|
{ |
|
case FIELD_MODELNAME: |
|
case FIELD_SOUNDNAME: |
|
case FIELD_STRING: |
|
Q_strncpy( szValue, ((char *)pObject + fieldOffset), iMaxLen ); |
|
return true; |
|
|
|
case FIELD_TIME: |
|
case FIELD_FLOAT: |
|
Q_snprintf( szValue, iMaxLen, "%f", (*(float *)((char *)pObject + fieldOffset)) ); |
|
return true; |
|
|
|
case FIELD_BOOLEAN: |
|
Q_snprintf( szValue, iMaxLen, "%d", (*(bool *)((char *)pObject + fieldOffset)) != 0); |
|
return true; |
|
|
|
case FIELD_CHARACTER: |
|
Q_snprintf( szValue, iMaxLen, "%d", (*(char *)((char *)pObject + fieldOffset)) ); |
|
return true; |
|
|
|
case FIELD_SHORT: |
|
Q_snprintf( szValue, iMaxLen, "%d", (*(short *)((char *)pObject + fieldOffset)) ); |
|
return true; |
|
|
|
case FIELD_INTEGER: |
|
case FIELD_TICK: |
|
Q_snprintf( szValue, iMaxLen, "%d", (*(int *)((char *)pObject + fieldOffset)) ); |
|
return true; |
|
|
|
case FIELD_POSITION_VECTOR: |
|
case FIELD_VECTOR: |
|
Q_snprintf( szValue, iMaxLen, "%f %f %f", |
|
((float *)((char *)pObject + fieldOffset))[0], |
|
((float *)((char *)pObject + fieldOffset))[1], |
|
((float *)((char *)pObject + fieldOffset))[2] ); |
|
return true; |
|
|
|
case FIELD_VMATRIX: |
|
case FIELD_VMATRIX_WORLDSPACE: |
|
//UTIL_StringToFloatArray( (float *)((char *)pObject + fieldOffset), 16, szValue ); |
|
return false; |
|
|
|
case FIELD_MATRIX3X4_WORLDSPACE: |
|
//UTIL_StringToFloatArray( (float *)((char *)pObject + fieldOffset), 12, szValue ); |
|
return false; |
|
|
|
case FIELD_COLOR32: |
|
Q_snprintf( szValue, iMaxLen, "%d %d %d %d", |
|
((int *)((char *)pObject + fieldOffset))[0], |
|
((int *)((char *)pObject + fieldOffset))[1], |
|
((int *)((char *)pObject + fieldOffset))[2], |
|
((int *)((char *)pObject + fieldOffset))[3] ); |
|
return true; |
|
|
|
case FIELD_CUSTOM: |
|
{ |
|
/* |
|
SaveRestoreFieldInfo_t fieldInfo = |
|
{ |
|
(char *)pObject + fieldOffset, |
|
pObject, |
|
pField |
|
}; |
|
pField->pSaveRestoreOps->Parse( fieldInfo, szValue ); |
|
*/ |
|
return false; |
|
} |
|
|
|
default: |
|
case FIELD_INTERVAL: // Fixme, could write this if needed |
|
case FIELD_CLASSPTR: |
|
case FIELD_MODELINDEX: |
|
case FIELD_MATERIALINDEX: |
|
case FIELD_EDICT: |
|
Warning( "Bad field in entity!!\n" ); |
|
Assert(0); |
|
break; |
|
} |
|
} |
|
} |
|
|
|
return false; |
|
}
|
|
|