mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-29 09:33:00 +00:00
242 lines
7.2 KiB
C++
242 lines
7.2 KiB
C++
|
//========= 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;
|
||
|
}
|