mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-11-22 09:22:18 -05:00
Add Collision Header XML parser (#3396)
* Add Collision Header XML parser * Update CollisionHeaderFactory.cpp * Remove "Num" attributes * Fix crashes Prevent crash when the camera setting is negative Change some IntAttributes to UnsignedAttributes
This commit is contained in:
parent
ecdf74161b
commit
db2ccd95b7
@ -24,6 +24,27 @@ CollisionHeaderFactory::ReadResource(std::shared_ptr<ResourceInitData> initData,
|
|||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<IResource>
|
||||||
|
CollisionHeaderFactory::ReadResourceXML(std::shared_ptr<ResourceInitData> initData, tinyxml2::XMLElement *reader) {
|
||||||
|
auto resource = std::make_shared<CollisionHeader>(initData);
|
||||||
|
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||||
|
|
||||||
|
switch (resource->GetInitData()->ResourceVersion) {
|
||||||
|
case 0:
|
||||||
|
factory = std::make_shared<CollisionHeaderFactoryV0>();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (factory == nullptr) {
|
||||||
|
SPDLOG_ERROR("Failed to load Collision Header with version {}", resource->GetInitData()->ResourceVersion);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
factory->ParseFileXML(reader, resource);
|
||||||
|
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
void LUS::CollisionHeaderFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
void LUS::CollisionHeaderFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||||
std::shared_ptr<IResource> resource)
|
std::shared_ptr<IResource> resource)
|
||||||
{
|
{
|
||||||
@ -139,4 +160,119 @@ void LUS::CollisionHeaderFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader
|
|||||||
}
|
}
|
||||||
collisionHeader->collisionHeaderData.waterBoxes = collisionHeader->waterBoxes.data();
|
collisionHeader->collisionHeaderData.waterBoxes = collisionHeader->waterBoxes.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LUS::CollisionHeaderFactoryV0::ParseFileXML(tinyxml2::XMLElement* reader, std::shared_ptr<IResource> resource) {
|
||||||
|
std::shared_ptr<CollisionHeader> collisionHeader = std::static_pointer_cast<CollisionHeader>(resource);
|
||||||
|
|
||||||
|
collisionHeader->collisionHeaderData.minBounds.x = reader->IntAttribute("MinBoundsX");
|
||||||
|
collisionHeader->collisionHeaderData.minBounds.y = reader->IntAttribute("MinBoundsY");
|
||||||
|
collisionHeader->collisionHeaderData.minBounds.z = reader->IntAttribute("MinBoundsZ");
|
||||||
|
|
||||||
|
collisionHeader->collisionHeaderData.maxBounds.x = reader->IntAttribute("MaxBoundsX");
|
||||||
|
collisionHeader->collisionHeaderData.maxBounds.y = reader->IntAttribute("MaxBoundsY");
|
||||||
|
collisionHeader->collisionHeaderData.maxBounds.z = reader->IntAttribute("MaxBoundsZ");
|
||||||
|
|
||||||
|
Vec3s zero;
|
||||||
|
zero.x = 0;
|
||||||
|
zero.y = 0;
|
||||||
|
zero.z = 0;
|
||||||
|
collisionHeader->camPosDataZero = zero;
|
||||||
|
|
||||||
|
auto child = reader->FirstChildElement();
|
||||||
|
|
||||||
|
while (child != nullptr) {
|
||||||
|
std::string childName = child->Name();
|
||||||
|
if (childName == "Vertex") {
|
||||||
|
Vec3s vtx;
|
||||||
|
vtx.x = child->IntAttribute("X");
|
||||||
|
vtx.y = child->IntAttribute("Y");
|
||||||
|
vtx.z = child->IntAttribute("Z");
|
||||||
|
collisionHeader->vertices.push_back(vtx);
|
||||||
|
} else if (childName == "Polygon") {
|
||||||
|
CollisionPoly polygon;
|
||||||
|
|
||||||
|
polygon.type = child->UnsignedAttribute("Type");
|
||||||
|
|
||||||
|
polygon.flags_vIA = child->UnsignedAttribute("VertexA");
|
||||||
|
polygon.flags_vIB = child->UnsignedAttribute("VertexB");
|
||||||
|
polygon.vIC = child->UnsignedAttribute("VertexC");
|
||||||
|
|
||||||
|
polygon.normal.x = child->IntAttribute("NormalX");
|
||||||
|
polygon.normal.y = child->IntAttribute("NormalY");
|
||||||
|
polygon.normal.z = child->IntAttribute("NormalZ");
|
||||||
|
|
||||||
|
polygon.dist = child->IntAttribute("Dist");
|
||||||
|
|
||||||
|
collisionHeader->polygons.push_back(polygon);
|
||||||
|
} else if (childName == "PolygonType") {
|
||||||
|
SurfaceType surfaceType;
|
||||||
|
|
||||||
|
surfaceType.data[0] = child->UnsignedAttribute("Data1");
|
||||||
|
surfaceType.data[1] = child->UnsignedAttribute("Data2");
|
||||||
|
|
||||||
|
collisionHeader->surfaceTypes.push_back(surfaceType);
|
||||||
|
} else if (childName == "CameraData") {
|
||||||
|
CamData camDataEntry;
|
||||||
|
camDataEntry.cameraSType = child->UnsignedAttribute("SType");
|
||||||
|
camDataEntry.numCameras = child->IntAttribute("NumData");
|
||||||
|
collisionHeader->camData.push_back(camDataEntry);
|
||||||
|
|
||||||
|
int32_t camPosDataIdx = child->IntAttribute("CameraPosDataSeg");
|
||||||
|
collisionHeader->camPosDataIndices.push_back(camPosDataIdx);
|
||||||
|
} else if (childName == "CameraPositionData") {
|
||||||
|
//each camera position data is made up of 3 Vec3s
|
||||||
|
Vec3s pos;
|
||||||
|
pos.x = child->IntAttribute("PosX");
|
||||||
|
pos.y = child->IntAttribute("PosY");
|
||||||
|
pos.z = child->IntAttribute("PosZ");
|
||||||
|
collisionHeader->camPosData.push_back(pos);
|
||||||
|
Vec3s rot;
|
||||||
|
rot.x = child->IntAttribute("RotX");
|
||||||
|
rot.y = child->IntAttribute("RotY");
|
||||||
|
rot.z = child->IntAttribute("RotZ");
|
||||||
|
collisionHeader->camPosData.push_back(rot);
|
||||||
|
Vec3s other;
|
||||||
|
other.x = child->IntAttribute("FOV");
|
||||||
|
other.y = child->IntAttribute("JfifID");
|
||||||
|
other.z = child->IntAttribute("Unknown");
|
||||||
|
collisionHeader->camPosData.push_back(other);
|
||||||
|
} else if (childName == "WaterBox") {
|
||||||
|
WaterBox waterBox;
|
||||||
|
waterBox.xMin = child->IntAttribute("XMin");
|
||||||
|
waterBox.ySurface = child->IntAttribute("Ysurface");
|
||||||
|
waterBox.zMin = child->IntAttribute("ZMin");
|
||||||
|
waterBox.xLength = child->IntAttribute("XLength");
|
||||||
|
waterBox.zLength = child->IntAttribute("ZLength");
|
||||||
|
waterBox.properties = child->IntAttribute("Properties");
|
||||||
|
|
||||||
|
collisionHeader->waterBoxes.push_back(waterBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
child = child->NextSiblingElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < collisionHeader->camData.size(); i++) {
|
||||||
|
int32_t idx = collisionHeader->camPosDataIndices[i];
|
||||||
|
|
||||||
|
if (collisionHeader->camPosData.size() > 0) {
|
||||||
|
collisionHeader->camData[i].camPosData = &collisionHeader->camPosData[idx];
|
||||||
|
} else {
|
||||||
|
collisionHeader->camData[i].camPosData = &collisionHeader->camPosDataZero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
collisionHeader->collisionHeaderData.numVertices = collisionHeader->vertices.size();
|
||||||
|
collisionHeader->collisionHeaderData.numPolygons = collisionHeader->polygons.size();
|
||||||
|
collisionHeader->surfaceTypesCount = collisionHeader->surfaceTypes.size();
|
||||||
|
collisionHeader->camDataCount = collisionHeader->camData.size();
|
||||||
|
collisionHeader->camPosCount = collisionHeader->camPosData.size();
|
||||||
|
collisionHeader->collisionHeaderData.numWaterBoxes = collisionHeader->waterBoxes.size();
|
||||||
|
|
||||||
|
collisionHeader->collisionHeaderData.vtxList = collisionHeader->vertices.data();
|
||||||
|
collisionHeader->collisionHeaderData.polyList = collisionHeader->polygons.data();
|
||||||
|
collisionHeader->collisionHeaderData.surfaceTypeList = collisionHeader->surfaceTypes.data();
|
||||||
|
collisionHeader->collisionHeaderData.cameraDataList = collisionHeader->camData.data();
|
||||||
|
collisionHeader->collisionHeaderData.cameraDataListLen = collisionHeader->camDataCount;
|
||||||
|
collisionHeader->collisionHeaderData.waterBoxes = collisionHeader->waterBoxes.data();
|
||||||
}
|
}
|
||||||
|
}
|
@ -8,10 +8,13 @@ class CollisionHeaderFactory : public ResourceFactory {
|
|||||||
public:
|
public:
|
||||||
std::shared_ptr<IResource>
|
std::shared_ptr<IResource>
|
||||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||||
|
std::shared_ptr<IResource>
|
||||||
|
ReadResourceXML(std::shared_ptr<ResourceInitData> initData, tinyxml2::XMLElement *reader) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CollisionHeaderFactoryV0 : public ResourceVersionFactory {
|
class CollisionHeaderFactoryV0 : public ResourceVersionFactory {
|
||||||
public:
|
public:
|
||||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||||
|
void ParseFileXML(tinyxml2::XMLElement* reader, std::shared_ptr<IResource> resource) override;
|
||||||
};
|
};
|
||||||
}; // namespace LUS
|
}; // namespace LUS
|
||||||
|
@ -7933,7 +7933,8 @@ s16 Camera_ChangeSettingFlags(Camera* camera, s16 setting, s16 flags) {
|
|||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setting == CAM_SET_NONE || setting >= CAM_SET_MAX) {
|
//modified from "==" to "<=" to not crash when "setting" is a negative value
|
||||||
|
if (setting <= CAM_SET_NONE || setting >= CAM_SET_MAX) {
|
||||||
osSyncPrintf(VT_COL(RED, WHITE) "camera: error: illegal camera set (%d) !!!!\n" VT_RST, setting);
|
osSyncPrintf(VT_COL(RED, WHITE) "camera: error: illegal camera set (%d) !!!!\n" VT_RST, setting);
|
||||||
return -99;
|
return -99;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user