From f755b6afc5cbac3f24f3d438a8675dfb455172fb Mon Sep 17 00:00:00 2001 From: hzqst <113660872@qq.com> Date: Sat, 20 Jan 2024 00:44:54 +0800 Subject: [PATCH] Fix a bug that unloaded studiomodel structures were sometimes used by StudioDrawVBO. --- Plugins/Renderer/gl_studio.cpp | 23 +++++++----- Plugins/Renderer/gl_studio.h | 13 ++++--- tools/studiocheck.exe | Bin 14848 -> 14848 bytes toolsrc/studiocheck/studiocheck.cpp | 54 ++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 13 deletions(-) diff --git a/Plugins/Renderer/gl_studio.cpp b/Plugins/Renderer/gl_studio.cpp index 6a4c50db..d2cb73c6 100644 --- a/Plugins/Renderer/gl_studio.cpp +++ b/Plugins/Renderer/gl_studio.cpp @@ -220,7 +220,8 @@ void R_PrepareStudioVBOSubmodel( vIndices.emplace_back(iStartVertex + iNumVertex); VBOMesh.iIndiceCount++; VBOMesh.iPolyCount++; - VBOMesh.mesh = pmesh; + //VBOMesh.mesh = pmesh; + VBOMesh.iMeshIndex = k; if (first == -1) first = iNumVertex; @@ -260,7 +261,8 @@ void R_PrepareStudioVBOSubmodel( vIndices.emplace_back(iStartVertex + iNumVertex); VBOMesh.iIndiceCount++; VBOMesh.iPolyCount++; - VBOMesh.mesh = pmesh; + //VBOMesh.mesh = pmesh; + VBOMesh.iMeshIndex = k; iNumTri++; @@ -340,7 +342,9 @@ studio_vbo_t* R_PrepareStudioVBO(studiohdr_t* studiohdr) auto submodel = (mstudiomodel_t*)((byte*)studiohdr + bodypart->modelindex) + j; studio_vbo_submodel_t* vboSubmodel = new studio_vbo_submodel_t; - vboSubmodel->submodel = submodel; + //vboSubmodel->submodel = submodel; + + vboSubmodel->iSubmodelIndex = j; R_PrepareStudioVBOSubmodel(studiohdr, submodel, vVertex, vIndices, vboSubmodel); @@ -1882,6 +1886,7 @@ void R_StudioDrawVBOMesh_AnalyzePass( studio_vbo_t* VBOData, studio_vbo_submodel_t* VBOSubmodel, studio_vbo_mesh_t* VBOMesh, + mstudiomesh_t* pmesh, studiohdr_t* ptexturehdr, mstudiotexture_t* ptexture, short* pskinref, @@ -1936,13 +1941,12 @@ void R_StudioDrawVBOMesh_DrawPass( studio_vbo_t* VBOData, studio_vbo_submodel_t* VBOSubmodel, studio_vbo_mesh_t* VBOMesh, + mstudiomesh_t* pmesh, studiohdr_t* ptexturehdr, mstudiotexture_t* ptexture, short* pskinref, const int flags) { - auto pmesh = VBOMesh->mesh; - program_state_t StudioProgramState = flags; if (r_draw_shadowcaster) @@ -2337,12 +2341,11 @@ void R_StudioDrawVBOMesh( studio_vbo_t* VBOData, studio_vbo_submodel_t* VBOSubmodel, studio_vbo_mesh_t* VBOMesh, + mstudiomesh_t*pmesh, studiohdr_t* ptexturehdr, mstudiotexture_t* ptexture, short* pskinref) { - auto pmesh = VBOMesh->mesh; - int flags = ptexture[pskinref[pmesh->skinref]].flags; //Lighting related flags are ignored when r_fullbright >= 2 @@ -2378,6 +2381,7 @@ void R_StudioDrawVBOMesh( R_StudioDrawVBOMesh_AnalyzePass(VBOData, VBOSubmodel, VBOMesh, + pmesh, ptexturehdr, ptexture, pskinref, @@ -2388,6 +2392,7 @@ void R_StudioDrawVBOMesh( R_StudioDrawVBOMesh_DrawPass(VBOData, VBOSubmodel, VBOMesh, + pmesh, ptexturehdr, ptexture, pskinref, @@ -2406,7 +2411,9 @@ void R_StudioDrawVBOSubmodel( { auto VBOMesh = &VBOSubmodel->vMesh[i]; - R_StudioDrawVBOMesh(VBOData, VBOSubmodel, VBOMesh, ptexturehdr, ptexture, pskinref); + auto pmesh = (mstudiomesh_t*)((byte*)(*pstudiohdr) + (*psubmodel)->meshindex) + VBOMesh->iMeshIndex; + + R_StudioDrawVBOMesh(VBOData, VBOSubmodel, VBOMesh, pmesh, ptexturehdr, ptexture, pskinref); } } diff --git a/Plugins/Renderer/gl_studio.h b/Plugins/Renderer/gl_studio.h index 89bfa3ba..2b983cc9 100644 --- a/Plugins/Renderer/gl_studio.h +++ b/Plugins/Renderer/gl_studio.h @@ -98,13 +98,14 @@ typedef struct studio_vbo_mesh_s { studio_vbo_mesh_s() { - mesh = NULL; + iMeshIndex = -1; + //memset(&mesh, 0, sizeof(mesh)); iStartIndex = -1; iIndiceCount = 0; iPolyCount = 0; } - - mstudiomesh_t *mesh; + int iMeshIndex; + //mstudiomesh_t mesh; int iStartIndex; int iIndiceCount; int iPolyCount; @@ -114,9 +115,11 @@ typedef struct studio_vbo_submodel_s { struct studio_vbo_submodel_s() { - submodel = NULL; + //memset(&submodel, 0, sizeof(submodel)); + iSubmodelIndex = -1; } - mstudiomodel_t *submodel; + //mstudiomodel_t submodel; + int iSubmodelIndex; std::vector vMesh; }studio_vbo_submodel_t; diff --git a/tools/studiocheck.exe b/tools/studiocheck.exe index ea7eb03a7532b64b77811c59b59a386aab88806f..7e3ed0fbb9d5ad82a6dcf3d579652333c99f0a25 100644 GIT binary patch delta 4418 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 + printf("numskinref %d\n", studiohdr->numskinref); + + auto pskinref = (short*)((byte*)studiohdr + studiohdr->skinindex); + + for (int i = 0; i < studiohdr->numskinfamilies; ++i) + { + pskinref += i * studiohdr->numskinref; + + if ((byte*)pskinref < (byte*)buffer) + { + printf("Error: invalid pskinref at pskinref[%d], (%p < %p)\n", i, pskinref, (byte*)buffer); + free(buffer); + return 0; + } + + if (((byte*)pskinref + sizeof(short) * studiohdr->numskinref) > (byte*)buffer + studiohdr->length) + { + printf("Error: invalid pskinref at pskinref[%d], (%p > %p)\n", i, ((byte*)pskinref + sizeof(short)), (byte*)buffer + studiohdr->length); + free(buffer); + return 0; + } + + for (int j = 0; j < studiohdr->numskinref; ++j) + { + auto skinref = pskinref[j]; + + printf("skinref[%d][%d]=%d\n", i, j, skinref); + + if (skinref < 0 || skinref >= studiohdr->numtextures) + { + printf("Error: invalid skinref value (%d) at pskinref[%d][%d]\n", skinref, i, j); + free(buffer); + return 0; + } + } } } @@ -169,6 +209,20 @@ int main(int argc, const char **argv) return 0; } + for (int k = 0; k < psubmodel[j].nummesh; ++k) + { + auto skinref = pmesh[k].skinref; + + printf("skinref value = (%d) at pmesh[%d].skinref\n", skinref, k); + + if (skinref < 0 || skinref >= studiohdr->numtextures) + { + printf("Error: invalid skinref value (%d) at pmesh[%d].skinref\n", skinref, k); + free(buffer); + return 0; + } + } + for (int k = 0; k < psubmodel[j].nummesh; ++k) { auto ptricmds = (short *)((byte *)studiohdr + pmesh[k].triindex);