1010#include " StdInc.h"
1111#include " CRenderItem.EffectParameters.h"
1212
13+ #include < cctype>
14+ #include < cstdlib>
15+ #include < limits>
16+
1317IMPLEMENT_ENUM_BEGIN (EStateGroup)
1418ADD_ENUM(STATE_GROUP_RENDER, " renderState" )
1519ADD_ENUM(STATE_GROUP_STAGE, " stageState" )
@@ -361,6 +365,9 @@ const SRegisterInfo BigRegisterInfoList[] = {
361365// //////////////////////////////////////////////////////////////
362366HRESULT CEffectParameters::Begin (UINT* pPasses, DWORD Flags, bool bWorldRender)
363367{
368+ if (!m_pD3DEffect)
369+ return D3DERR_INVALIDCALL;
370+
364371 if (m_bUsesDepthBuffer && !bWorldRender)
365372 {
366373 // Ensure readable depth buffer is ready to be read
@@ -389,17 +396,20 @@ HRESULT CEffectParameters::Begin(UINT* pPasses, DWORD Flags, bool bWorldRender)
389396 D3DXHANDLE hTexture = m_SecondaryRenderTargetList[i];
390397 IDirect3DBaseTexture9* pD3DTexture = nullptr ;
391398 HRESULT hr = m_pD3DEffect->GetTexture (hTexture, &pD3DTexture);
392- if (hr == D3D_OK && pD3DTexture && pD3DTexture-> GetType () == D3DRTYPE_TEXTURE )
399+ if (SUCCEEDED (hr) && pD3DTexture)
393400 {
394- IDirect3DSurface9* pD3DSurface = nullptr ;
395- HRESULT hrSurface = ((IDirect3DTexture9*)pD3DTexture)->GetSurfaceLevel (0 , &pD3DSurface);
396- if (hrSurface == D3D_OK && pD3DSurface)
401+ if (pD3DTexture->GetType () == D3DRTYPE_TEXTURE)
397402 {
398- pDevice->SetRenderTarget (i + 1 , pD3DSurface);
399- SAFE_RELEASE (pD3DSurface);
403+ IDirect3DSurface9* pD3DSurface = nullptr ;
404+ HRESULT hrSurface = ((IDirect3DTexture9*)pD3DTexture)->GetSurfaceLevel (0 , &pD3DSurface);
405+ if (hrSurface == D3D_OK && pD3DSurface)
406+ {
407+ pDevice->SetRenderTarget (i + 1 , pD3DSurface);
408+ SAFE_RELEASE (pD3DSurface);
409+ }
400410 }
401- SAFE_RELEASE (pD3DTexture);
402411 }
412+ SAFE_RELEASE (pD3DTexture);
403413 }
404414 }
405415
@@ -462,8 +472,14 @@ bool CEffectParameters::ApplyCommonHandles()
462472 if (!m_bUsesCommonHandles)
463473 return false ;
464474
465- LPDIRECT3DDEVICE9 pDevice;
466- m_pD3DEffect->GetDevice (&pDevice);
475+ if (!m_pD3DEffect)
476+ return false ;
477+
478+ assert (g_pDeviceState);
479+
480+ LPDIRECT3DDEVICE9 pDevice = nullptr ;
481+ if (FAILED (m_pD3DEffect->GetDevice (&pDevice)) || !pDevice)
482+ return false ;
467483
468484 D3DXMATRIX matWorld, matView, matProjection;
469485 pDevice->GetTransform (D3DTS_WORLD, &matWorld);
@@ -609,6 +625,7 @@ bool CEffectParameters::ApplyCommonHandles()
609625 if (m_CommonHandles.hProjectionMainScene )
610626 m_pD3DEffect->SetMatrix (m_CommonHandles.hProjectionMainScene , (D3DXMATRIX*)&g_pDeviceState->MainSceneState .TransformState .PROJECTION );
611627
628+ SAFE_RELEASE (pDevice);
612629 return true ;
613630};
614631
@@ -620,6 +637,35 @@ void BOUNDS_CHECK(const void* ptr, int ptrsize, const void* bufstart, int bufsiz
620637 assert ((uchar*)ptr + ptrsize <= (uchar*)bufstart + bufsize);
621638}
622639
640+ static SString TrimAsciiWhitespace (const SString& value)
641+ {
642+ size_t start = 0 ;
643+ size_t end = value.length ();
644+
645+ while (start < end && std::isspace (static_cast <unsigned char >(value[start])))
646+ ++start;
647+
648+ while (end > start && std::isspace (static_cast <unsigned char >(value[end - 1 ])))
649+ --end;
650+
651+ return value.substr (start, end - start);
652+ }
653+
654+ static bool DoesStateGroupUseStageIndex (EStateGroup stateGroup)
655+ {
656+ switch (stateGroup)
657+ {
658+ case STATE_GROUP_STAGE:
659+ case STATE_GROUP_SAMPLER:
660+ case STATE_GROUP_TEXTURE:
661+ case STATE_GROUP_LIGHT:
662+ case STATE_GROUP_LIGHT_ENABLE:
663+ return true ;
664+ default :
665+ return false ;
666+ }
667+ }
668+
623669// //////////////////////////////////////////////////////////////
624670//
625671// CEffectParameters::ApplyMappedHandles
@@ -633,6 +679,11 @@ bool CEffectParameters::ApplyMappedHandles()
633679 if (!m_bUsesMappedHandles)
634680 return false ;
635681
682+ if (!m_pD3DEffect)
683+ return false ;
684+
685+ assert (g_pDeviceState);
686+
636687 // ////////////////////////////////////////
637688 //
638689 // RenderState
@@ -888,6 +939,9 @@ const std::set<D3DXHANDLE>& CEffectParameters::GetModifiedParameters()
888939// //////////////////////////////////////////////////////////////
889940void CEffectParameters::RestoreParametersDefaultValue (const std::vector<D3DXHANDLE>& parameterList)
890941{
942+ if (!m_pD3DEffect)
943+ return ;
944+
891945 for (auto hParameter : parameterList)
892946 {
893947 std::vector<char >* pBuffer = MapFind (m_defaultValues, hParameter);
@@ -906,6 +960,9 @@ void CEffectParameters::RestoreParametersDefaultValue(const std::vector<D3DXHAND
906960// //////////////////////////////////////////////////////////////
907961void CEffectParameters::ReadParameterHandles ()
908962{
963+ if (!m_pD3DEffect)
964+ return ;
965+
909966 D3DXEFFECT_DESC EffectDesc;
910967 m_pD3DEffect->GetDesc (&EffectDesc);
911968
@@ -957,12 +1014,21 @@ void CEffectParameters::ReadParameterHandles()
9571014// //////////////////////////////////////////////////////////////
9581015SString CEffectParameters::GetAnnotationNameAndValue (D3DXHANDLE hParameter, uint uiIndex, SString& strOutValue)
9591016{
1017+ if (!m_pD3DEffect)
1018+ return " " ;
1019+
9601020 D3DXHANDLE hAnnotation = m_pD3DEffect->GetAnnotation (hParameter, uiIndex);
1021+ if (!hAnnotation)
1022+ return " " ;
1023+
9611024 D3DXPARAMETER_DESC AnnotDesc;
962- m_pD3DEffect->GetParameterDesc (hAnnotation, &AnnotDesc);
963- LPCSTR szAnnotValue;
964- if (SUCCEEDED (m_pD3DEffect->GetString (hAnnotation, &szAnnotValue)))
1025+ if (FAILED (m_pD3DEffect->GetParameterDesc (hAnnotation, &AnnotDesc)) || !AnnotDesc.Name )
1026+ return " " ;
1027+
1028+ LPCSTR szAnnotValue = nullptr ;
1029+ if (SUCCEEDED (m_pD3DEffect->GetString (hAnnotation, &szAnnotValue)) && szAnnotValue)
9651030 strOutValue = szAnnotValue;
1031+
9661032 return AnnotDesc.Name ;
9671033}
9681034
@@ -975,6 +1041,9 @@ SString CEffectParameters::GetAnnotationNameAndValue(D3DXHANDLE hParameter, uint
9751041// //////////////////////////////////////////////////////////////
9761042bool CEffectParameters::TryParseSpecialParameter (D3DXHANDLE hParameter, const D3DXPARAMETER_DESC& ParameterDesc)
9771043{
1044+ if (!m_pD3DEffect)
1045+ return false ;
1046+
9781047 // Use semantic if it exists
9791048 SString strName = ParameterDesc.Semantic ? ParameterDesc.Semantic : ParameterDesc.Name ;
9801049 if (strName.CompareI (" CUSTOMFLAGS" ))
@@ -1029,6 +1098,9 @@ bool CEffectParameters::IsSecondaryRenderTarget(D3DXHANDLE hParameter, const D3D
10291098// //////////////////////////////////////////////////////////////
10301099bool CEffectParameters::AddStandardParameter (D3DXHANDLE hParameter, const D3DXPARAMETER_DESC& ParameterDesc)
10311100{
1101+ if (!m_pD3DEffect)
1102+ return false ;
1103+
10321104 // Use semantic if it exists
10331105 SString strName = ParameterDesc.Semantic ? ParameterDesc.Semantic : ParameterDesc.Name ;
10341106 // Add to correct lookup map
@@ -1053,8 +1125,10 @@ bool CEffectParameters::AddStandardParameter(D3DXHANDLE hParameter, const D3DXPA
10531125 {
10541126 std::vector<char > buffer;
10551127 buffer.resize (ParameterDesc.Bytes );
1056- m_pD3DEffect->GetValue (hParameter, buffer.data (), buffer.size ());
1057- MapSet (m_defaultValues, hParameter, buffer);
1128+ if (SUCCEEDED (m_pD3DEffect->GetValue (hParameter, buffer.data (), buffer.size ())))
1129+ {
1130+ MapSet (m_defaultValues, hParameter, buffer);
1131+ }
10581132 }
10591133 return true ;
10601134}
@@ -1082,8 +1156,57 @@ bool CEffectParameters::TryMappingParameterToRegister(D3DXHANDLE hParameter, con
10821156 }
10831157
10841158 // Extract prepended stage number, if any
1085- int iStage = atoi (strAnnotValue);
1086- SString strName = strAnnotValue.SplitRight (" ," , NULL , -1 );
1159+ SString strStagePart;
1160+ SString strName;
1161+ const bool bHasStagePart = strAnnotValue.Split (" ," , &strStagePart, &strName, -1 );
1162+ if (!bHasStagePart)
1163+ strName = strAnnotValue;
1164+
1165+ strName = TrimAsciiWhitespace (strName);
1166+ strStagePart = TrimAsciiWhitespace (strStagePart);
1167+
1168+ if (strName.empty ())
1169+ continue ;
1170+
1171+ int iStage = 0 ;
1172+ const bool bGroupUsesStage = DoesStateGroupUseStageIndex (stateGroup);
1173+ if (bHasStagePart)
1174+ {
1175+ if (!bGroupUsesStage)
1176+ {
1177+ // Stage index supplied where it is not expected
1178+ continue ;
1179+ }
1180+
1181+ if (strStagePart.empty ())
1182+ continue ;
1183+
1184+ char * pParseEnd = nullptr ;
1185+ const long parsedStage = strtol (strStagePart.c_str (), &pParseEnd, 10 );
1186+ if (!pParseEnd || *pParseEnd != ' \0 ' )
1187+ continue ;
1188+
1189+ if (parsedStage < 0 || parsedStage > std::numeric_limits<int >::max ())
1190+ continue ;
1191+
1192+ iStage = static_cast <int >(parsedStage);
1193+ }
1194+ else if (!bGroupUsesStage)
1195+ {
1196+ iStage = 0 ;
1197+ }
1198+
1199+ if (bGroupUsesStage)
1200+ {
1201+ const int kMaxFixedStageCount = 8 ;
1202+ if (iStage < 0 || iStage >= kMaxFixedStageCount )
1203+ continue ;
1204+ }
1205+ else if (bHasStagePart)
1206+ {
1207+ // Already handled above, but keep guard for readability
1208+ continue ;
1209+ }
10871210
10881211 // Find D3D register line for this group+name
10891212 const SRegisterInfo* pRegsiterInfo = GetRegisterInfo (stateGroup, strName);
0 commit comments