Merge branch 'fixedpath' into 'master'

Replace more sized reads and change path grid loading

See merge request OpenMW/openmw!3475
macos_ci_fix
psi29a 1 year ago
commit 575f43876b

@ -1133,9 +1133,9 @@ namespace EsmTool
{ {
std::cout << " Cell: " << mData.mCell << std::endl; std::cout << " Cell: " << mData.mCell << std::endl;
std::cout << " Coordinates: (" << mData.mData.mX << "," << mData.mData.mY << ")" << std::endl; std::cout << " Coordinates: (" << mData.mData.mX << "," << mData.mData.mY << ")" << std::endl;
std::cout << " Unknown S1: " << mData.mData.mS1 << std::endl; std::cout << " Granularity: " << mData.mData.mGranularity << std::endl;
if (static_cast<size_t>(mData.mData.mS2) != mData.mPoints.size()) if (mData.mData.mPoints != mData.mPoints.size())
std::cout << " Reported Point Count: " << mData.mData.mS2 << std::endl; std::cout << " Reported Point Count: " << mData.mData.mPoints << std::endl;
std::cout << " Point Count: " << mData.mPoints.size() << std::endl; std::cout << " Point Count: " << mData.mPoints.size() << std::endl;
std::cout << " Edge Count: " << mData.mEdges.size() << std::endl; std::cout << " Edge Count: " << mData.mEdges.size() << std::endl;
@ -1154,7 +1154,7 @@ namespace EsmTool
for (const ESM::Pathgrid::Edge& edge : mData.mEdges) for (const ESM::Pathgrid::Edge& edge : mData.mEdges)
{ {
std::cout << " Edge[" << i << "]: " << edge.mV0 << " -> " << edge.mV1 << std::endl; std::cout << " Edge[" << i << "]: " << edge.mV0 << " -> " << edge.mV1 << std::endl;
if (edge.mV0 >= static_cast<size_t>(mData.mData.mS2) || edge.mV1 >= static_cast<size_t>(mData.mData.mS2)) if (edge.mV0 >= mData.mData.mPoints || edge.mV1 >= mData.mData.mPoints)
std::cout << " BAD POINT IN EDGE!" << std::endl; std::cout << " BAD POINT IN EDGE!" << std::endl;
i++; i++;
} }

@ -44,9 +44,9 @@ void CSMTools::PathgridCheckStage::perform(int stage, CSMDoc::Messages& messages
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Pathgrid, pathgrid.mId); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Pathgrid, pathgrid.mId);
// check the number of pathgrid points // check the number of pathgrid points
if (pathgrid.mData.mS2 < static_cast<int>(pathgrid.mPoints.size())) if (pathgrid.mData.mPoints < pathgrid.mPoints.size())
messages.add(id, "Less points than expected", "", CSMDoc::Message::Severity_Error); messages.add(id, "Less points than expected", "", CSMDoc::Message::Severity_Error);
else if (pathgrid.mData.mS2 > static_cast<int>(pathgrid.mPoints.size())) else if (pathgrid.mData.mPoints > pathgrid.mPoints.size())
messages.add(id, "More points than expected", "", CSMDoc::Message::Severity_Error); messages.add(id, "More points than expected", "", CSMDoc::Message::Severity_Error);
std::vector<CSMTools::Point> pointList(pathgrid.mPoints.size()); std::vector<CSMTools::Point> pointList(pathgrid.mPoints.size());

@ -41,7 +41,7 @@ namespace CSMWorld
point.mUnknown = 0; point.mUnknown = 0;
points.insert(points.begin() + position, point); points.insert(points.begin() + position, point);
pathgrid.mData.mS2 = pathgrid.mPoints.size(); pathgrid.mData.mPoints = pathgrid.mPoints.size();
record.setModified(pathgrid); record.setModified(pathgrid);
} }
@ -58,7 +58,7 @@ namespace CSMWorld
// Do not remove dangling edges, does not work with current undo mechanism // Do not remove dangling edges, does not work with current undo mechanism
// Do not automatically adjust indices, what would be done with dangling edges? // Do not automatically adjust indices, what would be done with dangling edges?
points.erase(points.begin() + rowToRemove); points.erase(points.begin() + rowToRemove);
pathgrid.mData.mS2 = pathgrid.mPoints.size(); pathgrid.mData.mPoints = pathgrid.mPoints.size();
record.setModified(pathgrid); record.setModified(pathgrid);
} }
@ -67,7 +67,7 @@ namespace CSMWorld
{ {
Pathgrid pathgrid = record.get(); Pathgrid pathgrid = record.get();
pathgrid.mPoints = static_cast<const NestedTableWrapper<ESM::Pathgrid::PointList>&>(nestedTable).mNestedTable; pathgrid.mPoints = static_cast<const NestedTableWrapper<ESM::Pathgrid::PointList>&>(nestedTable).mNestedTable;
pathgrid.mData.mS2 = pathgrid.mPoints.size(); pathgrid.mData.mPoints = pathgrid.mPoints.size();
record.setModified(pathgrid); record.setModified(pathgrid);
} }

@ -28,7 +28,7 @@ namespace ESM
mName = esm.getHString(); mName = esm.getHString();
break; break;
case fourCC("MCDT"): case fourCC("MCDT"):
esm.getHTSized<12>(mData); esm.getHT(mData.mWeight, mData.mValue, mData.mFlags);
hasData = true; hasData = true;
break; break;
case fourCC("SCRI"): case fourCC("SCRI"):

@ -27,8 +27,8 @@ namespace ESM
struct MCDTstruct struct MCDTstruct
{ {
float mWeight; float mWeight;
int mValue; int32_t mValue;
int mFlags; int32_t mFlags;
}; };
enum Flags enum Flags
@ -38,7 +38,7 @@ namespace ESM
MCDTstruct mData; MCDTstruct mData;
unsigned int mRecordFlags; uint32_t mRecordFlags;
RefId mId, mScript; RefId mId, mScript;
std::string mName, mModel, mIcon; std::string mName, mModel, mIcon;

@ -7,18 +7,18 @@ namespace ESM
{ {
Pathgrid::Point& Pathgrid::Point::operator=(const float rhs[3]) Pathgrid::Point& Pathgrid::Point::operator=(const float rhs[3])
{ {
mX = static_cast<int>(rhs[0]); mX = static_cast<int32_t>(rhs[0]);
mY = static_cast<int>(rhs[1]); mY = static_cast<int32_t>(rhs[1]);
mZ = static_cast<int>(rhs[2]); mZ = static_cast<int32_t>(rhs[2]);
mAutogenerated = 0; mAutogenerated = 0;
mConnectionNum = 0; mConnectionNum = 0;
mUnknown = 0; mUnknown = 0;
return *this; return *this;
} }
Pathgrid::Point::Point(const float rhs[3]) Pathgrid::Point::Point(const float rhs[3])
: mX(static_cast<int>(rhs[0])) : mX(static_cast<int32_t>(rhs[0]))
, mY(static_cast<int>(rhs[1])) , mY(static_cast<int32_t>(rhs[1]))
, mZ(static_cast<int>(rhs[2])) , mZ(static_cast<int32_t>(rhs[2]))
, mAutogenerated(0) , mAutogenerated(0)
, mConnectionNum(0) , mConnectionNum(0)
, mUnknown(0) , mUnknown(0)
@ -42,7 +42,7 @@ namespace ESM
mEdges.clear(); mEdges.clear();
// keep track of total connections so we can reserve edge vector size // keep track of total connections so we can reserve edge vector size
int edgeCount = 0; size_t edgeCount = 0;
bool hasData = false; bool hasData = false;
while (esm.hasMoreSubs()) while (esm.hasMoreSubs())
@ -54,21 +54,20 @@ namespace ESM
mCell = esm.getRefId(); mCell = esm.getRefId();
break; break;
case fourCC("DATA"): case fourCC("DATA"):
esm.getHTSized<12>(mData); esm.getHT(mData.mX, mData.mY, mData.mGranularity, mData.mPoints);
hasData = true; hasData = true;
break; break;
case fourCC("PGRP"): case fourCC("PGRP"):
{ {
esm.getSubHeader(); esm.getSubHeader();
int size = esm.getSubSize(); uint32_t size = esm.getSubSize();
// Check that the sizes match up. Size = 16 * s2 (path points) // Check that the sizes match up. Size = 16 * path points
if (size != static_cast<int>(sizeof(Point) * mData.mS2)) if (size != sizeof(Point) * mData.mPoints)
esm.fail("Path point subrecord size mismatch"); esm.fail("Path point subrecord size mismatch");
else else
{ {
int pointCount = mData.mS2; mPoints.reserve(mData.mPoints);
mPoints.reserve(pointCount); for (uint16_t i = 0; i < mData.mPoints; ++i)
for (int i = 0; i < pointCount; ++i)
{ {
Point p; Point p;
esm.getExact(&p, sizeof(Point)); esm.getExact(&p, sizeof(Point));
@ -81,21 +80,19 @@ namespace ESM
case fourCC("PGRC"): case fourCC("PGRC"):
{ {
esm.getSubHeader(); esm.getSubHeader();
int size = esm.getSubSize(); uint32_t size = esm.getSubSize();
if (size % sizeof(int) != 0) if (size % sizeof(uint32_t) != 0)
esm.fail("PGRC size not a multiple of 4"); esm.fail("PGRC size not a multiple of 4");
else else
{ {
int rawConnNum = size / sizeof(int); size_t rawConnNum = size / sizeof(uint32_t);
std::vector<size_t> rawConnections; std::vector<size_t> rawConnections;
rawConnections.reserve(rawConnNum); rawConnections.reserve(rawConnNum);
for (int i = 0; i < rawConnNum; ++i) for (size_t i = 0; i < rawConnNum; ++i)
{ {
int currentValue; uint32_t currentValue;
esm.getT(currentValue); esm.getT(currentValue);
if (currentValue < 0) rawConnections.push_back(currentValue);
esm.fail("currentValue is less than 0");
rawConnections.push_back(static_cast<size_t>(currentValue));
} }
auto rawIt = rawConnections.begin(); auto rawIt = rawConnections.begin();
@ -138,7 +135,7 @@ namespace ESM
// Correct connection count and sort edges by point // Correct connection count and sort edges by point
// Can probably be optimized // Can probably be optimized
PointList correctedPoints = mPoints; PointList correctedPoints = mPoints;
std::vector<int> sortedEdges; std::vector<uint32_t> sortedEdges;
sortedEdges.reserve(mEdges.size()); sortedEdges.reserve(mEdges.size());
@ -150,7 +147,7 @@ namespace ESM
{ {
if (edge.mV0 == point) if (edge.mV0 == point)
{ {
sortedEdges.push_back(static_cast<int>(edge.mV1)); sortedEdges.push_back(static_cast<uint32_t>(edge.mV1));
++correctedPoints[point].mConnectionNum; ++correctedPoints[point].mConnectionNum;
} }
} }
@ -162,16 +159,16 @@ namespace ESM
if (isDeleted) if (isDeleted)
{ {
esm.writeHNString("DELE", "", 3); esm.writeHNString("DELE", {}, 3);
return; return;
} }
if (!correctedPoints.empty()) if (!correctedPoints.empty())
{ {
esm.startSubRecord("PGRP"); esm.startSubRecord("PGRP");
for (PointList::const_iterator it = correctedPoints.begin(); it != correctedPoints.end(); ++it) for (const Point& point : correctedPoints)
{ {
esm.writeT(*it); esm.writeT(point);
} }
esm.endRecord("PGRP"); esm.endRecord("PGRP");
} }
@ -179,9 +176,9 @@ namespace ESM
if (!sortedEdges.empty()) if (!sortedEdges.empty())
{ {
esm.startSubRecord("PGRC"); esm.startSubRecord("PGRC");
for (std::vector<int>::const_iterator it = sortedEdges.begin(); it != sortedEdges.end(); ++it) for (const uint32_t& edge : sortedEdges)
{ {
esm.writeT(*it); esm.writeT(edge);
} }
esm.endRecord("PGRC"); esm.endRecord("PGRC");
} }
@ -192,8 +189,8 @@ namespace ESM
mCell = ESM::RefId(); mCell = ESM::RefId();
mData.mX = 0; mData.mX = 0;
mData.mY = 0; mData.mY = 0;
mData.mS1 = 0; mData.mGranularity = 0;
mData.mS2 = 0; mData.mPoints = 0;
mPoints.clear(); mPoints.clear();
mEdges.clear(); mEdges.clear();
} }

@ -25,18 +25,17 @@ namespace ESM
struct DATAstruct struct DATAstruct
{ {
int mX, mY; // Grid location, matches cell for exterior cells int32_t mX, mY; // Grid location, matches cell for exterior cells
short mS1; // ?? Usually but not always a power of 2. Doesn't seem int16_t mGranularity; // Granularity with which the graph was autogenerated
// to have any relation to the size of PGRC. uint16_t mPoints; // Number of path points.
short mS2; // Number of path points.
}; // 12 bytes }; // 12 bytes
struct Point // path grid point struct Point // path grid point
{ {
int mX, mY, mZ; // Location of point int32_t mX, mY, mZ; // Location of point
unsigned char mAutogenerated; // autogenerated vs. user coloring flag? unsigned char mAutogenerated; // autogenerated vs. user coloring flag?
unsigned char mConnectionNum; // number of connections for this point unsigned char mConnectionNum; // number of connections for this point
short mUnknown; int16_t mUnknown;
Point& operator=(const float[3]); Point& operator=(const float[3]);
Point(const float[3]); Point(const float[3]);
Point(); Point();

@ -28,7 +28,7 @@ namespace ESM
mName = esm.getHString(); mName = esm.getHString();
break; break;
case fourCC("PBDT"): case fourCC("PBDT"):
esm.getHTSized<16>(mData); esm.getHT(mData.mWeight, mData.mValue, mData.mQuality, mData.mUses);
hasData = true; hasData = true;
break; break;
case fourCC("SCRI"): case fourCC("SCRI"):

@ -22,14 +22,14 @@ namespace ESM
struct Data struct Data
{ {
float mWeight; float mWeight;
int mValue; int32_t mValue;
float mQuality; float mQuality;
int mUses; int32_t mUses;
}; // Size = 16 }; // Size = 16
Data mData; Data mData;
unsigned int mRecordFlags; uint32_t mRecordFlags;
RefId mId, mScript; RefId mId, mScript;
std::string mName, mModel, mIcon; std::string mName, mModel, mIcon;

@ -25,7 +25,7 @@ namespace ESM
mSound = esm.getHString(); mSound = esm.getHString();
break; break;
case fourCC("DATA"): case fourCC("DATA"):
esm.getHTSized<3>(mData); esm.getHT(mData.mVolume, mData.mMinRange, mData.mMaxRange);
hasData = true; hasData = true;
break; break;
case SREC_DELE: case SREC_DELE:

@ -25,7 +25,7 @@ namespace ESM
static std::string_view getRecordType() { return "Sound"; } static std::string_view getRecordType() { return "Sound"; }
SOUNstruct mData; SOUNstruct mData;
unsigned int mRecordFlags; uint32_t mRecordFlags;
std::string mSound; std::string mSound;
RefId mId; RefId mId;

@ -27,13 +27,11 @@ namespace ESM
mName = esm.getHString(); mName = esm.getHString();
break; break;
case fourCC("SPDT"): case fourCC("SPDT"):
esm.getHTSized<12>(mData); esm.getHT(mData.mType, mData.mCost, mData.mFlags);
hasData = true; hasData = true;
break; break;
case fourCC("ENAM"): case fourCC("ENAM"):
ENAMstruct s; mEffects.add(esm);
esm.getHTSized<24>(s);
mEffects.mList.push_back(s);
break; break;
case SREC_DELE: case SREC_DELE:
esm.skipHSub(); esm.skipHSub();

@ -39,13 +39,13 @@ namespace ESM
struct SPDTstruct struct SPDTstruct
{ {
int mType; // SpellType int32_t mType; // SpellType
int mCost; // Mana cost int32_t mCost; // Mana cost
int mFlags; // Flags int32_t mFlags; // Flags
}; };
SPDTstruct mData; SPDTstruct mData;
unsigned int mRecordFlags; uint32_t mRecordFlags;
std::string mName; std::string mName;
RefId mId; RefId mId;
EffectList mEffects; EffectList mEffects;

Loading…
Cancel
Save