summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Estelami <NEstelami@users.noreply.github.com>2023-04-30 20:13:10 -0400
committerGitHub <noreply@github.com>2023-04-30 20:13:10 -0400
commit6f999c77f147f2301ad648b5339db17d03847a37 (patch)
tree79f0398953ad4e4b2216d6ddc0f666283b95959c
parenta71e171748aef62e6f07b9e246e875f5c263eff0 (diff)
Fixed improperly extracted vertices (#281)
-rw-r--r--ZAPD/ZDisplayList.cpp44
-rw-r--r--ZAPD/ZDisplayList.h3
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;