Counter Strike : Global Offensive Source Code
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.

278 lines
6.1 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "functionproxy.h"
  9. #include <keyvalues.h>
  10. #include "materialsystem/imaterialvar.h"
  11. #include "materialsystem/imaterial.h"
  12. #include "iclientrenderable.h"
  13. // memdbgon must be the last include file in a .cpp file!!!
  14. #include "tier0/memdbgon.h"
  15. //-----------------------------------------------------------------------------
  16. // Helper class to deal with floating point inputs
  17. //-----------------------------------------------------------------------------
  18. bool CFloatInput::Init( IMaterial *pMaterial, KeyValues *pKeyValues, const char *pKeyName, float flDefault )
  19. {
  20. m_pFloatVar = NULL;
  21. KeyValues *pSection = pKeyValues->FindKey( pKeyName );
  22. if (pSection)
  23. {
  24. if (pSection->GetDataType() == KeyValues::TYPE_STRING)
  25. {
  26. const char *pVarName = pSection->GetString();
  27. // Look for numbers...
  28. float flValue;
  29. int nCount = sscanf( pVarName, "%f", &flValue );
  30. if (nCount == 1)
  31. {
  32. m_flValue = flValue;
  33. return true;
  34. }
  35. // Look for array specification...
  36. char pTemp[256];
  37. if (strchr(pVarName, '['))
  38. {
  39. // strip off the array...
  40. Q_strncpy( pTemp, pVarName, 256 );
  41. char *pArray = strchr( pTemp, '[' );
  42. *pArray++ = 0;
  43. char* pIEnd;
  44. m_FloatVecComp = strtol( pArray, &pIEnd, 10 );
  45. // Use the version without the array...
  46. pVarName = pTemp;
  47. }
  48. else
  49. {
  50. m_FloatVecComp = -1;
  51. }
  52. bool bFoundVar;
  53. m_pFloatVar = pMaterial->FindVar( pVarName, &bFoundVar, true );
  54. if (!bFoundVar)
  55. return false;
  56. }
  57. else
  58. {
  59. m_flValue = pSection->GetFloat();
  60. }
  61. }
  62. else
  63. {
  64. m_flValue = flDefault;
  65. }
  66. return true;
  67. }
  68. float CFloatInput::GetFloat() const
  69. {
  70. if (!m_pFloatVar)
  71. return m_flValue;
  72. if( m_FloatVecComp < 0 )
  73. return m_pFloatVar->GetFloatValue();
  74. int iVecSize = m_pFloatVar->VectorSize();
  75. if ( m_FloatVecComp >= iVecSize )
  76. return 0;
  77. float v[4];
  78. m_pFloatVar->GetVecValue( v, iVecSize );
  79. return v[m_FloatVecComp];
  80. }
  81. //-----------------------------------------------------------------------------
  82. //
  83. // Result proxy; a result (with vector friendliness)
  84. //
  85. //-----------------------------------------------------------------------------
  86. CResultProxy::CResultProxy() : m_pResult(0)
  87. {
  88. }
  89. CResultProxy::~CResultProxy()
  90. {
  91. }
  92. bool CResultProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
  93. {
  94. char const* pResult = pKeyValues->GetString( "resultVar" );
  95. if( !pResult )
  96. return false;
  97. // Look for array specification...
  98. char pTemp[256];
  99. if (strchr(pResult, '['))
  100. {
  101. // strip off the array...
  102. Q_strncpy( pTemp, pResult, 256 );
  103. char *pArray = strchr( pTemp, '[' );
  104. *pArray++ = 0;
  105. char* pIEnd;
  106. m_ResultVecComp = strtol( pArray, &pIEnd, 10 );
  107. // Use the version without the array...
  108. pResult = pTemp;
  109. }
  110. else
  111. {
  112. m_ResultVecComp = -1;
  113. }
  114. bool foundVar;
  115. m_pResult = pMaterial->FindVar( pResult, &foundVar, true );
  116. if( !foundVar )
  117. return false;
  118. if ( !Q_stricmp( pResult, "$alpha" ) )
  119. {
  120. pMaterial->SetMaterialVarFlag( MATERIAL_VAR_ALPHA_MODIFIED_BY_PROXY, true );
  121. }
  122. return true;
  123. }
  124. //-----------------------------------------------------------------------------
  125. // A little code to allow us to set single components of vectors
  126. //-----------------------------------------------------------------------------
  127. void CResultProxy::SetFloatResult( float result )
  128. {
  129. if (m_pResult->GetType() == MATERIAL_VAR_TYPE_VECTOR)
  130. {
  131. if ( m_ResultVecComp >= 0 )
  132. {
  133. m_pResult->SetVecComponentValue( result, m_ResultVecComp );
  134. }
  135. else
  136. {
  137. float v[4];
  138. int vecSize = m_pResult->VectorSize();
  139. for (int i = 0; i < vecSize; ++i)
  140. v[i] = result;
  141. m_pResult->SetVecValue( v, vecSize );
  142. }
  143. }
  144. else
  145. {
  146. m_pResult->SetFloatValue( result );
  147. }
  148. }
  149. void CResultProxy::SetVecResult( float x, float y, float z, float w )
  150. {
  151. if (m_pResult->GetType() == MATERIAL_VAR_TYPE_VECTOR)
  152. {
  153. float v[4] = { x, y, z, w };
  154. int vecSize = m_pResult->VectorSize();
  155. m_pResult->SetVecValue( v, vecSize );
  156. }
  157. else
  158. {
  159. m_pResult->SetFloatValue( x );
  160. }
  161. }
  162. C_BaseEntity *CResultProxy::BindArgToEntity( void *pArg )
  163. {
  164. IClientRenderable *pRend = (IClientRenderable *)pArg;
  165. return pRend->GetIClientUnknown()->GetBaseEntity();
  166. }
  167. IMaterial *CResultProxy::GetMaterial()
  168. {
  169. return m_pResult->GetOwningMaterial();
  170. }
  171. //-----------------------------------------------------------------------------
  172. //
  173. // Base functional proxy; two sources (one is optional) and a result
  174. //
  175. //-----------------------------------------------------------------------------
  176. CFunctionProxy::CFunctionProxy() : m_pSrc1(0), m_pSrc2(0)
  177. {
  178. }
  179. CFunctionProxy::~CFunctionProxy()
  180. {
  181. }
  182. bool CFunctionProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
  183. {
  184. if (!CResultProxy::Init( pMaterial, pKeyValues ))
  185. return false;
  186. char const* pSrcVar1 = pKeyValues->GetString( "srcVar1" );
  187. if( !pSrcVar1 )
  188. return false;
  189. bool foundVar;
  190. m_pSrc1 = pMaterial->FindVar( pSrcVar1, &foundVar, true );
  191. if( !foundVar )
  192. return false;
  193. // Source 2 is optional, some math ops may be single-input
  194. char const* pSrcVar2 = pKeyValues->GetString( "srcVar2" );
  195. if( pSrcVar2 && (*pSrcVar2) )
  196. {
  197. m_pSrc2 = pMaterial->FindVar( pSrcVar2, &foundVar, true );
  198. if( !foundVar )
  199. return false;
  200. }
  201. else
  202. {
  203. m_pSrc2 = 0;
  204. }
  205. return true;
  206. }
  207. void CFunctionProxy::ComputeResultType( MaterialVarType_t& resultType, int& vecSize )
  208. {
  209. // Feh, this is ugly. Basically, don't change the result type
  210. // unless it's undefined.
  211. resultType = m_pResult->GetType();
  212. if (resultType == MATERIAL_VAR_TYPE_VECTOR)
  213. {
  214. if (m_ResultVecComp >= 0)
  215. resultType = MATERIAL_VAR_TYPE_FLOAT;
  216. vecSize = m_pResult->VectorSize();
  217. }
  218. else if (resultType == MATERIAL_VAR_TYPE_UNDEFINED)
  219. {
  220. resultType = m_pSrc1->GetType();
  221. if (resultType == MATERIAL_VAR_TYPE_VECTOR)
  222. {
  223. vecSize = m_pSrc1->VectorSize();
  224. }
  225. else if ((resultType == MATERIAL_VAR_TYPE_UNDEFINED) && m_pSrc2)
  226. {
  227. resultType = m_pSrc2->GetType();
  228. if (resultType == MATERIAL_VAR_TYPE_VECTOR)
  229. {
  230. vecSize = m_pSrc2->VectorSize();
  231. }
  232. }
  233. }
  234. }