10
10
#include " StdInc.h"
11
11
#include " CRenderItem.EffectParameters.h"
12
12
13
+ #include < cctype>
14
+ #include < cstdlib>
15
+ #include < limits>
16
+
13
17
IMPLEMENT_ENUM_BEGIN (EStateGroup)
14
18
ADD_ENUM(STATE_GROUP_RENDER, " renderState" )
15
19
ADD_ENUM(STATE_GROUP_STAGE, " stageState" )
@@ -361,6 +365,9 @@ const SRegisterInfo BigRegisterInfoList[] = {
361
365
// //////////////////////////////////////////////////////////////
362
366
HRESULT CEffectParameters::Begin (UINT* pPasses, DWORD Flags, bool bWorldRender)
363
367
{
368
+ if (!m_pD3DEffect)
369
+ return D3DERR_INVALIDCALL;
370
+
364
371
if (m_bUsesDepthBuffer && !bWorldRender)
365
372
{
366
373
// Ensure readable depth buffer is ready to be read
@@ -389,17 +396,20 @@ HRESULT CEffectParameters::Begin(UINT* pPasses, DWORD Flags, bool bWorldRender)
389
396
D3DXHANDLE hTexture = m_SecondaryRenderTargetList[i];
390
397
IDirect3DBaseTexture9* pD3DTexture = nullptr ;
391
398
HRESULT hr = m_pD3DEffect->GetTexture (hTexture, &pD3DTexture);
392
- if (hr == D3D_OK && pD3DTexture && pD3DTexture-> GetType () == D3DRTYPE_TEXTURE )
399
+ if (SUCCEEDED (hr) && pD3DTexture)
393
400
{
394
- IDirect3DSurface9* pD3DSurface = nullptr ;
395
- HRESULT hrSurface = ((IDirect3DTexture9*)pD3DTexture)->GetSurfaceLevel (0 , &pD3DSurface);
396
- if (hrSurface == D3D_OK && pD3DSurface)
401
+ if (pD3DTexture->GetType () == D3DRTYPE_TEXTURE)
397
402
{
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
+ }
400
410
}
401
- SAFE_RELEASE (pD3DTexture);
402
411
}
412
+ SAFE_RELEASE (pD3DTexture);
403
413
}
404
414
}
405
415
@@ -462,8 +472,14 @@ bool CEffectParameters::ApplyCommonHandles()
462
472
if (!m_bUsesCommonHandles)
463
473
return false ;
464
474
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 ;
467
483
468
484
D3DXMATRIX matWorld, matView, matProjection;
469
485
pDevice->GetTransform (D3DTS_WORLD, &matWorld);
@@ -609,6 +625,7 @@ bool CEffectParameters::ApplyCommonHandles()
609
625
if (m_CommonHandles.hProjectionMainScene )
610
626
m_pD3DEffect->SetMatrix (m_CommonHandles.hProjectionMainScene , (D3DXMATRIX*)&g_pDeviceState->MainSceneState .TransformState .PROJECTION );
611
627
628
+ SAFE_RELEASE (pDevice);
612
629
return true ;
613
630
};
614
631
@@ -620,6 +637,35 @@ void BOUNDS_CHECK(const void* ptr, int ptrsize, const void* bufstart, int bufsiz
620
637
assert ((uchar*)ptr + ptrsize <= (uchar*)bufstart + bufsize);
621
638
}
622
639
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
+
623
669
// //////////////////////////////////////////////////////////////
624
670
//
625
671
// CEffectParameters::ApplyMappedHandles
@@ -633,6 +679,11 @@ bool CEffectParameters::ApplyMappedHandles()
633
679
if (!m_bUsesMappedHandles)
634
680
return false ;
635
681
682
+ if (!m_pD3DEffect)
683
+ return false ;
684
+
685
+ assert (g_pDeviceState);
686
+
636
687
// ////////////////////////////////////////
637
688
//
638
689
// RenderState
@@ -888,6 +939,9 @@ const std::set<D3DXHANDLE>& CEffectParameters::GetModifiedParameters()
888
939
// //////////////////////////////////////////////////////////////
889
940
void CEffectParameters::RestoreParametersDefaultValue (const std::vector<D3DXHANDLE>& parameterList)
890
941
{
942
+ if (!m_pD3DEffect)
943
+ return ;
944
+
891
945
for (auto hParameter : parameterList)
892
946
{
893
947
std::vector<char >* pBuffer = MapFind (m_defaultValues, hParameter);
@@ -906,6 +960,9 @@ void CEffectParameters::RestoreParametersDefaultValue(const std::vector<D3DXHAND
906
960
// //////////////////////////////////////////////////////////////
907
961
void CEffectParameters::ReadParameterHandles ()
908
962
{
963
+ if (!m_pD3DEffect)
964
+ return ;
965
+
909
966
D3DXEFFECT_DESC EffectDesc;
910
967
m_pD3DEffect->GetDesc (&EffectDesc);
911
968
@@ -957,12 +1014,21 @@ void CEffectParameters::ReadParameterHandles()
957
1014
// //////////////////////////////////////////////////////////////
958
1015
SString CEffectParameters::GetAnnotationNameAndValue (D3DXHANDLE hParameter, uint uiIndex, SString& strOutValue)
959
1016
{
1017
+ if (!m_pD3DEffect)
1018
+ return " " ;
1019
+
960
1020
D3DXHANDLE hAnnotation = m_pD3DEffect->GetAnnotation (hParameter, uiIndex);
1021
+ if (!hAnnotation)
1022
+ return " " ;
1023
+
961
1024
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)
965
1030
strOutValue = szAnnotValue;
1031
+
966
1032
return AnnotDesc.Name ;
967
1033
}
968
1034
@@ -975,6 +1041,9 @@ SString CEffectParameters::GetAnnotationNameAndValue(D3DXHANDLE hParameter, uint
975
1041
// //////////////////////////////////////////////////////////////
976
1042
bool CEffectParameters::TryParseSpecialParameter (D3DXHANDLE hParameter, const D3DXPARAMETER_DESC& ParameterDesc)
977
1043
{
1044
+ if (!m_pD3DEffect)
1045
+ return false ;
1046
+
978
1047
// Use semantic if it exists
979
1048
SString strName = ParameterDesc.Semantic ? ParameterDesc.Semantic : ParameterDesc.Name ;
980
1049
if (strName.CompareI (" CUSTOMFLAGS" ))
@@ -1029,6 +1098,9 @@ bool CEffectParameters::IsSecondaryRenderTarget(D3DXHANDLE hParameter, const D3D
1029
1098
// //////////////////////////////////////////////////////////////
1030
1099
bool CEffectParameters::AddStandardParameter (D3DXHANDLE hParameter, const D3DXPARAMETER_DESC& ParameterDesc)
1031
1100
{
1101
+ if (!m_pD3DEffect)
1102
+ return false ;
1103
+
1032
1104
// Use semantic if it exists
1033
1105
SString strName = ParameterDesc.Semantic ? ParameterDesc.Semantic : ParameterDesc.Name ;
1034
1106
// Add to correct lookup map
@@ -1053,8 +1125,10 @@ bool CEffectParameters::AddStandardParameter(D3DXHANDLE hParameter, const D3DXPA
1053
1125
{
1054
1126
std::vector<char > buffer;
1055
1127
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
+ }
1058
1132
}
1059
1133
return true ;
1060
1134
}
@@ -1082,8 +1156,57 @@ bool CEffectParameters::TryMappingParameterToRegister(D3DXHANDLE hParameter, con
1082
1156
}
1083
1157
1084
1158
// 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
+ }
1087
1210
1088
1211
// Find D3D register line for this group+name
1089
1212
const SRegisterInfo* pRegsiterInfo = GetRegisterInfo (stateGroup, strName);
0 commit comments