diff options
| author | Nicholas Estelami <NEstelami@users.noreply.github.com> | 2023-04-30 20:13:10 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-30 20:13:10 -0400 |
| commit | 6f999c77f147f2301ad648b5339db17d03847a37 (patch) | |
| tree | 79f0398953ad4e4b2216d6ddc0f666283b95959c | |
| parent | a71e171748aef62e6f07b9e246e875f5c263eff0 (diff) | |
Fixed improperly extracted vertices (#281)
| -rw-r--r-- | ZAPD/ZDisplayList.cpp | 44 | ||||
| -rw-r--r-- | ZAPD/ZDisplayList.h | 3 |
2 files changed, 46 insertions, 1 deletions
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<std::pair<uint32_t, std::vector<ZVtx>>> vertexKeys(vertices.begin(), + vertices.end()); + std::pair<uint32_t, std::vector<ZVtx>> lastItem = vertexKeys.at(0); + + for (size_t i = 1; i < vertexKeys.size(); i++) + { + std::pair<uint32_t, std::vector<ZVtx>> 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; |
