fix(gx): fix buffer overruns in TEXTLINETEXTURE::WriteGeometry

This commit is contained in:
fallenoak 2025-12-21 21:24:32 -06:00
parent 1352f0ba50
commit 84b16f2aeb
No known key found for this signature in database
GPG Key ID: 7628F8E61AEA070D

View File

@ -37,78 +37,89 @@ void TEXTLINETEXTURE::WriteGeometry(CGxVertexPCT* buffer, const CImVector& fontC
? this->m_colors.Count() ? this->m_colors.Count()
: 0; : 0;
if (vertexOffset >= this->m_vert.Count()) { // Drop shadows
return;
}
uint32_t v24 = this->m_vert.Count() - vertexOffset;
if (vertexCount >= v24) {
vertexCount = v24;
}
if (hasShadow) { if (hasShadow) {
C3Vector shadowTranslation = { if (vertexOffset < this->m_vert.Count()) {
viewTranslation.x + floor(ScreenToPixelWidth(0, shadowOffset.x)), int32_t availableVertexCount = this->m_vert.Count() - vertexOffset;
viewTranslation.y + floor(ScreenToPixelHeight(0, shadowOffset.y)), int32_t shadowVertexCount = vertexCount >= availableVertexCount ? availableVertexCount : vertexCount;
viewTranslation.z
};
auto color = colorCount ? this->m_colors[vertexOffset] : fontColor; C3Vector shadowTranslation = {
viewTranslation.x + floor(ScreenToPixelWidth(0, shadowOffset.x)),
viewTranslation.y + floor(ScreenToPixelHeight(0, shadowOffset.y)),
viewTranslation.z
};
for (int32_t i = 0; i < vertexCount; i++) { auto color = colorCount ? this->m_colors[vertexOffset] : fontColor;
for (int32_t i = 0; i < shadowVertexCount; i++) {
auto& vertex = this->m_vert[vertexOffset + i];
C3Vector p = {
vertex.vc.x + shadowTranslation.x,
vertex.vc.y + shadowTranslation.y,
vertex.vc.z + shadowTranslation.z
};
buffer->p = p;
buffer->tc[0] = vertex.tc;
auto formattedShadowColor = shadowColor;
if (a8 && colorCount) {
formattedShadowColor.a = static_cast<uint8_t>(
(static_cast<float>(formattedShadowColor.a) * static_cast<float>(color.a)) / 65536.0f
);
}
GxFormatColor(formattedShadowColor);
buffer->c = formattedShadowColor;
buffer++;
}
vertexCount -= shadowVertexCount;
if (vertexOffset + shadowVertexCount >= this->m_vert.Count()) {
vertexOffset = 0;
}
} else {
vertexOffset -= this->m_vert.Count();
}
}
// Characters
if (vertexCount && vertexOffset < this->m_vert.Count()) {
int32_t availableVertexCount = this->m_vert.Count() - vertexOffset;
int32_t characterVertexCount = vertexCount >= availableVertexCount ? availableVertexCount : vertexCount;
// if (BATCHEDRENDERFONTDESC::s_billboarded) {
// // TODO
// }
for (int32_t i = 0; i < characterVertexCount; i++) {
auto& vertex = this->m_vert[vertexOffset + i]; auto& vertex = this->m_vert[vertexOffset + i];
auto color = colorCount ? this->m_colors[vertexOffset + i] : fontColor;
GxFormatColor(color);
// if (BATCHEDRENDERFONTDESC::s_billboarded) {
// // TODO
// continue;
// }
C3Vector p = { C3Vector p = {
vertex.vc.x + shadowTranslation.x, vertex.vc.x + viewTranslation.x,
vertex.vc.y + shadowTranslation.y, vertex.vc.y + viewTranslation.y,
vertex.vc.z + shadowTranslation.z vertex.vc.z + viewTranslation.z
}; };
buffer->p = p; buffer->p = p;
buffer->tc[0] = vertex.tc; buffer->tc[0] = vertex.tc;
auto formattedShadowColor = shadowColor; buffer->c = color;
if (a8 && colorCount) {
formattedShadowColor.a = static_cast<uint8_t>(
(static_cast<float>(formattedShadowColor.a) * static_cast<float>(color.a)) / 65536.0f
);
}
GxFormatColor(formattedShadowColor);
buffer->c = formattedShadowColor;
buffer++; buffer++;
} }
} }
// if (BATCHEDRENDERFONTDESC::s_billboarded) {
// // TODO
// }
for (int32_t i = 0; i < vertexCount; i++) {
auto& vertex = this->m_vert[vertexOffset + i];
auto color = colorCount ? this->m_colors[vertexOffset + i] : fontColor;
GxFormatColor(color);
// if (BATCHEDRENDERFONTDESC::s_billboarded) {
// // TODO
// continue;
// }
C3Vector p = {
vertex.vc.x + viewTranslation.x,
vertex.vc.y + viewTranslation.y,
vertex.vc.z + viewTranslation.z
};
buffer->p = p;
buffer->tc[0] = vertex.tc;
buffer->c = color;
buffer++;
}
} }
CGxString* CGxString::GetNewString(int32_t linkOnList) { CGxString* CGxString::GetNewString(int32_t linkOnList) {