From 6f999c77f147f2301ad648b5339db17d03847a37 Mon Sep 17 00:00:00 2001 From: Nicholas Estelami Date: Sun, 30 Apr 2023 20:13:10 -0400 Subject: Fixed improperly extracted vertices (#281) --- ZAPD/ZDisplayList.cpp | 44 +++++++++++++++++++++++++++++++++++++++++++- ZAPD/ZDisplayList.h | 3 +++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/ZAPD/ZDisplayList.cpp b/ZAPD/ZDisplayList.cpp index 3b50c1f..50fd09f 100644 --- a/ZAPD/ZDisplayList.cpp +++ b/ZAPD/ZDisplayList.cpp @@ -1642,7 +1642,12 @@ static int32_t GfxdCallback_Vtx(uint32_t seg, int32_t count) vtxList.push_back(vtx); currentPtr += 16; } - self->vertices[vtxOffset] = vtxList; + + bool keyAlreadyOccupied = self->vertices.find(vtxOffset) != self->vertices.end(); + + // In some cases a vtxList already exists at vtxOffset. Only override the existing list if the new one is bigger. + if (!keyAlreadyOccupied || (keyAlreadyOccupied && vtxList.size() > self->vertices[vtxOffset].size())) + self->vertices[vtxOffset] = vtxList; } } @@ -1954,9 +1959,46 @@ std::string ZDisplayList::ProcessGfxDis([[maybe_unused]] const std::string& pref gfxd_execute(); // generate display list sourceOutput += outputformatter.GetOutput(); // write formatted display list + MergeConnectingVertexLists(); + return sourceOutput; } +void ZDisplayList::MergeConnectingVertexLists() +{ + if (vertices.size() > 0) + { + std::vector>> vertexKeys(vertices.begin(), + vertices.end()); + std::pair> lastItem = vertexKeys.at(0); + + for (size_t i = 1; i < vertexKeys.size(); i++) + { + std::pair> curItem = vertexKeys[i]; + + size_t lastItemEnd = lastItem.first + (lastItem.second.size() * 16); + bool lastItemIntersects = lastItemEnd >= curItem.first; + + if (lastItemIntersects) + { + int intersectedVtxStart = (lastItemEnd - curItem.first) / 16; + + for (size_t j = intersectedVtxStart; j < curItem.second.size(); j++) + vertices[lastItem.first].push_back(curItem.second[j]); + + vertices.erase(curItem.first); + vertexKeys.erase(vertexKeys.begin() + i); + + lastItem.second = vertices[lastItem.first]; + + i--; + } + else + lastItem = curItem; + } + } +} + void ZDisplayList::TextureGenCheck() { if (TextureGenCheck(lastTexWidth, lastTexHeight, lastTexAddr, lastTexSeg, lastTexFmt, diff --git a/ZAPD/ZDisplayList.h b/ZAPD/ZDisplayList.h index 9680831..c68713c 100644 --- a/ZAPD/ZDisplayList.h +++ b/ZAPD/ZDisplayList.h @@ -367,6 +367,9 @@ public: std::string ProcessLegacy(const std::string& prefix); std::string ProcessGfxDis(const std::string& prefix); + // Combines vertex lists from the vertices map which touch or intersect + void MergeConnectingVertexLists(); + bool IsExternalResource() const override; std::string GetExternalExtension() const override; std::string GetSourceTypeName() const override; -- cgit v1.2.3