@@ -823,8 +823,24 @@ Try improving the fit to vertical surfaces like cliffs.
823823 // check if there is anything to draw and fill vertex buffer
824824 if (m_edgesToFlush >= 2 )
825825 {
826+ // Guard against a null vertex buffer (e.g. if ReleaseResources() was called
827+ // without a matching ReAcquireResources() during a device reset).
828+ if (!m_vertexBuffer)
829+ {
830+ m_edgesToFlush = 0 ;
831+ return ;
832+ }
833+
826834 DX8VertexBufferClass::WriteLockClass lockVtxBuffer (m_vertexBuffer);
827835 VertexFormatXYZDUV1 *verts = (VertexFormatXYZDUV1*)lockVtxBuffer.Get_Vertex_Array ();
836+
837+ // Guard against a failed buffer lock returning a null pointer.
838+ if (!verts)
839+ {
840+ m_edgesToFlush = 0 ;
841+ return ;
842+ }
843+
828844 trackStartIndex=0 ;
829845
830846 mod=m_usedModules;
@@ -835,9 +851,17 @@ Try improving the fit to vertical surfaces like cliffs.
835851 Vector3 *endPoint;
836852 Vector2 *endPointUV;
837853
838- if (mod->m_activeEdgeCount >= 2 && mod->Is_Really_Visible ())
854+ // Clamp activeEdgeCount to m_maxTankTrackEdges to prevent writing past the
855+ // end of the vertex buffer when m_maxTankTrackEdges was reduced (e.g. by a
856+ // graphics-detail change) while tracks still hold edges from the old, larger
857+ // limit. This also keeps index within the fixed-size m_edges[] array.
858+ Int activeEdgeCount = mod->m_activeEdgeCount ;
859+ if (activeEdgeCount > m_maxTankTrackEdges)
860+ activeEdgeCount = m_maxTankTrackEdges;
861+
862+ if (activeEdgeCount >= 2 && mod->Is_Really_Visible ())
839863 {
840- for (i=0 ,index=mod->m_bottomIndex ; i<mod-> m_activeEdgeCount ; i++,index++)
864+ for (i=0 ,index=mod->m_bottomIndex ; i<activeEdgeCount ; i++,index++)
841865 {
842866 if (index >= m_maxTankTrackEdges)
843867 index=0 ;
@@ -847,10 +871,10 @@ Try improving the fit to vertical surfaces like cliffs.
847871
848872 distanceFade=1 .0f ;
849873
850- if ((mod-> m_activeEdgeCount -1 -i) >= m_maxTankTrackOpaqueEdges)// && i < (MAX_PER_TRACK_EDGE_COUNT-FORCE_FADE_AT_EDGE))
874+ if ((activeEdgeCount -1 -i) >= m_maxTankTrackOpaqueEdges)// && i < (MAX_PER_TRACK_EDGE_COUNT-FORCE_FADE_AT_EDGE))
851875 { // we're getting close to the limit on the number of track pieces allowed
852876 // so force it to fade out.
853- distanceFade=1 .0f -(float )((mod-> m_activeEdgeCount -i)-m_maxTankTrackOpaqueEdges)/numFadedEdges;
877+ distanceFade=1 .0f -(float )((activeEdgeCount -i)-m_maxTankTrackOpaqueEdges)/numFadedEdges;
854878 }
855879
856880 distanceFade *= mod->m_edges [index].alpha ; // adjust fade with distance from start of track
@@ -898,13 +922,20 @@ Try improving the fit to vertical surfaces like cliffs.
898922 DX8Wrapper::Set_Transform (D3DTS_WORLD ,mod->Transform );
899923 while (mod)
900924 {
901- if (mod->m_activeEdgeCount >= 2 && mod->Is_Really_Visible ())
925+ // Use the same clamped edge count as the vertex-fill pass above so that
926+ // trackStartIndex stays consistent and we don't read past the index buffer
927+ // (which is only allocated for m_maxTankTrackEdges-1 segments).
928+ Int activeEdgeCount = mod->m_activeEdgeCount ;
929+ if (activeEdgeCount > m_maxTankTrackEdges)
930+ activeEdgeCount = m_maxTankTrackEdges;
931+
932+ if (activeEdgeCount >= 2 && mod->Is_Really_Visible ())
902933 {
903934 DX8Wrapper::Set_Texture (0 ,mod->m_stageZeroTexture );
904935 DX8Wrapper::Set_Index_Buffer_Index_Offset (trackStartIndex);
905- DX8Wrapper::Draw_Triangles ( 0 ,(mod-> m_activeEdgeCount - 1 )*2 , 0 , mod-> m_activeEdgeCount *2 );
936+ DX8Wrapper::Draw_Triangles ( 0 ,(activeEdgeCount- 1 )*2 , 0 , activeEdgeCount *2 );
906937
907- trackStartIndex += mod-> m_activeEdgeCount *2 ;
938+ trackStartIndex += activeEdgeCount *2 ;
908939 }
909940 mod=mod->m_nextSystem ;
910941 }
0 commit comments