From 5b598dc3f11e1480f3f8a66408ff7a4d25caabee Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Tue, 24 Oct 2023 22:31:10 +0200 Subject: [PATCH 1/4] Add Collision Header XML parser --- .../importer/CollisionHeaderFactory.cpp | 134 ++++++++++++++++++ .../importer/CollisionHeaderFactory.h | 3 + 2 files changed, 137 insertions(+) diff --git a/soh/soh/resource/importer/CollisionHeaderFactory.cpp b/soh/soh/resource/importer/CollisionHeaderFactory.cpp index 3707229e337..1534233e2be 100644 --- a/soh/soh/resource/importer/CollisionHeaderFactory.cpp +++ b/soh/soh/resource/importer/CollisionHeaderFactory.cpp @@ -24,6 +24,27 @@ CollisionHeaderFactory::ReadResource(std::shared_ptr initData, return resource; } +std::shared_ptr +CollisionHeaderFactory::ReadResourceXML(std::shared_ptr initData, tinyxml2::XMLElement *reader) { + auto resource = std::make_shared(initData); + std::shared_ptr factory = nullptr; + + switch (resource->GetInitData()->ResourceVersion) { + case 0: + factory = std::make_shared(); + 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 reader, std::shared_ptr resource) { @@ -140,3 +161,116 @@ void LUS::CollisionHeaderFactoryV0::ParseFileBinary(std::shared_ptrcollisionHeaderData.waterBoxes = collisionHeader->waterBoxes.data(); } } + +void LUS::CollisionHeaderFactoryV0::ParseFileXML(tinyxml2::XMLElement* reader, std::shared_ptr resource) { + std::shared_ptr collisionHeader = std::static_pointer_cast(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"); + + collisionHeader->collisionHeaderData.numVertices = reader->IntAttribute("NumVertices"); + collisionHeader->collisionHeaderData.numPolygons = reader->IntAttribute("NumPolygons"); + collisionHeader->surfaceTypesCount = reader->IntAttribute("NumPolygonTypes"); + collisionHeader->camDataCount = reader->IntAttribute("NumCameraDatas"); + collisionHeader->camPosCount = reader->IntAttribute("NumCameraPositionDatas"); + collisionHeader->collisionHeaderData.numWaterBoxes = reader->IntAttribute("NumWaterBoxes"); + + collisionHeader->vertices.reserve(collisionHeader->collisionHeaderData.numVertices); + collisionHeader->polygons.reserve(collisionHeader->collisionHeaderData.numPolygons); + collisionHeader->surfaceTypes.reserve(collisionHeader->surfaceTypesCount); + collisionHeader->camData.reserve(collisionHeader->camDataCount); + collisionHeader->camPosDataIndices.reserve(collisionHeader->camDataCount); + collisionHeader->camPosData.reserve(collisionHeader->camPosCount); + collisionHeader->waterBoxes.reserve(collisionHeader->collisionHeaderData.numWaterBoxes); + + 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->IntAttribute("Type"); + + polygon.flags_vIA = child->IntAttribute("VertexA"); + polygon.flags_vIB = child->IntAttribute("VertexB"); + polygon.vIC = child->IntAttribute("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; + + //might be swapped but idk + surfaceType.data[1] = child->IntAttribute("Data1"); + surfaceType.data[0] = child->IntAttribute("Data2"); + + collisionHeader->surfaceTypes.push_back(surfaceType); + } else if (childName == "CameraData") { + CamData camDataEntry; + camDataEntry.cameraSType = child->IntAttribute("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") { + Vec3s pos; + pos.x = child->IntAttribute("X"); + pos.y = child->IntAttribute("Y"); + pos.z = child->IntAttribute("Z"); + collisionHeader->camPosData.push_back(pos); + } 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->camDataCount; i++) { + int32_t idx = collisionHeader->camPosDataIndices[i]; + + if (collisionHeader->camPosCount > 0) { + collisionHeader->camData[i].camPosData = &collisionHeader->camPosData[idx]; + } else { + collisionHeader->camData[i].camPosData = &collisionHeader->camPosDataZero; + } + } + + 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(); +} \ No newline at end of file diff --git a/soh/soh/resource/importer/CollisionHeaderFactory.h b/soh/soh/resource/importer/CollisionHeaderFactory.h index 09d6ba4c514..e0276b38ff2 100644 --- a/soh/soh/resource/importer/CollisionHeaderFactory.h +++ b/soh/soh/resource/importer/CollisionHeaderFactory.h @@ -8,10 +8,13 @@ class CollisionHeaderFactory : public ResourceFactory { public: std::shared_ptr ReadResource(std::shared_ptr initData, std::shared_ptr reader) override; + std::shared_ptr + ReadResourceXML(std::shared_ptr initData, tinyxml2::XMLElement *reader) override; }; class CollisionHeaderFactoryV0 : public ResourceVersionFactory { public: void ParseFileBinary(std::shared_ptr reader, std::shared_ptr resource) override; + void ParseFileXML(tinyxml2::XMLElement* reader, std::shared_ptr resource) override; }; }; // namespace LUS From 434b6988938829e5808017fb664b1e98e8efa5ed Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Thu, 26 Oct 2023 18:54:30 +0200 Subject: [PATCH 2/4] Update CollisionHeaderFactory.cpp --- .../importer/CollisionHeaderFactory.cpp | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/soh/soh/resource/importer/CollisionHeaderFactory.cpp b/soh/soh/resource/importer/CollisionHeaderFactory.cpp index 1534233e2be..6aa6b1c2a85 100644 --- a/soh/soh/resource/importer/CollisionHeaderFactory.cpp +++ b/soh/soh/resource/importer/CollisionHeaderFactory.cpp @@ -223,9 +223,8 @@ void LUS::CollisionHeaderFactoryV0::ParseFileXML(tinyxml2::XMLElement* reader, s } else if (childName == "PolygonType") { SurfaceType surfaceType; - //might be swapped but idk - surfaceType.data[1] = child->IntAttribute("Data1"); - surfaceType.data[0] = child->IntAttribute("Data2"); + surfaceType.data[0] = child->IntAttribute("Data1"); + surfaceType.data[1] = child->IntAttribute("Data2"); collisionHeader->surfaceTypes.push_back(surfaceType); } else if (childName == "CameraData") { @@ -237,11 +236,22 @@ void LUS::CollisionHeaderFactoryV0::ParseFileXML(tinyxml2::XMLElement* reader, s 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("X"); - pos.y = child->IntAttribute("Y"); - pos.z = child->IntAttribute("Z"); + 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"); @@ -266,7 +276,7 @@ void LUS::CollisionHeaderFactoryV0::ParseFileXML(tinyxml2::XMLElement* reader, s collisionHeader->camData[i].camPosData = &collisionHeader->camPosDataZero; } } - + collisionHeader->collisionHeaderData.vtxList = collisionHeader->vertices.data(); collisionHeader->collisionHeaderData.polyList = collisionHeader->polygons.data(); collisionHeader->collisionHeaderData.surfaceTypeList = collisionHeader->surfaceTypes.data(); From 1eec31f89dfbce163e75ee7e2046841072bcf5f6 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Sun, 29 Oct 2023 00:00:46 +0200 Subject: [PATCH 3/4] Remove "Num" attributes --- .../importer/CollisionHeaderFactory.cpp | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/soh/soh/resource/importer/CollisionHeaderFactory.cpp b/soh/soh/resource/importer/CollisionHeaderFactory.cpp index 6aa6b1c2a85..934eadc351f 100644 --- a/soh/soh/resource/importer/CollisionHeaderFactory.cpp +++ b/soh/soh/resource/importer/CollisionHeaderFactory.cpp @@ -173,21 +173,6 @@ void LUS::CollisionHeaderFactoryV0::ParseFileXML(tinyxml2::XMLElement* reader, s collisionHeader->collisionHeaderData.maxBounds.y = reader->IntAttribute("MaxBoundsY"); collisionHeader->collisionHeaderData.maxBounds.z = reader->IntAttribute("MaxBoundsZ"); - collisionHeader->collisionHeaderData.numVertices = reader->IntAttribute("NumVertices"); - collisionHeader->collisionHeaderData.numPolygons = reader->IntAttribute("NumPolygons"); - collisionHeader->surfaceTypesCount = reader->IntAttribute("NumPolygonTypes"); - collisionHeader->camDataCount = reader->IntAttribute("NumCameraDatas"); - collisionHeader->camPosCount = reader->IntAttribute("NumCameraPositionDatas"); - collisionHeader->collisionHeaderData.numWaterBoxes = reader->IntAttribute("NumWaterBoxes"); - - collisionHeader->vertices.reserve(collisionHeader->collisionHeaderData.numVertices); - collisionHeader->polygons.reserve(collisionHeader->collisionHeaderData.numPolygons); - collisionHeader->surfaceTypes.reserve(collisionHeader->surfaceTypesCount); - collisionHeader->camData.reserve(collisionHeader->camDataCount); - collisionHeader->camPosDataIndices.reserve(collisionHeader->camDataCount); - collisionHeader->camPosData.reserve(collisionHeader->camPosCount); - collisionHeader->waterBoxes.reserve(collisionHeader->collisionHeaderData.numWaterBoxes); - Vec3s zero; zero.x = 0; zero.y = 0; @@ -267,16 +252,23 @@ void LUS::CollisionHeaderFactoryV0::ParseFileXML(tinyxml2::XMLElement* reader, s child = child->NextSiblingElement(); } - for (size_t i = 0; i < collisionHeader->camDataCount; i++) { + for (size_t i = 0; i < collisionHeader->camData.size(); i++) { int32_t idx = collisionHeader->camPosDataIndices[i]; - if (collisionHeader->camPosCount > 0) { + 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(); From f9bf84e6a1c0326fe1feec9d3e85d3d085f904b0 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Tue, 14 Nov 2023 14:16:47 +0100 Subject: [PATCH 4/4] Fix crashes Prevent crash when the camera setting is negative Change some IntAttributes to UnsignedAttributes --- .../resource/importer/CollisionHeaderFactory.cpp | 16 ++++++++-------- soh/src/code/z_camera.c | 3 ++- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/soh/soh/resource/importer/CollisionHeaderFactory.cpp b/soh/soh/resource/importer/CollisionHeaderFactory.cpp index 934eadc351f..9300efdf0fe 100644 --- a/soh/soh/resource/importer/CollisionHeaderFactory.cpp +++ b/soh/soh/resource/importer/CollisionHeaderFactory.cpp @@ -160,7 +160,6 @@ void LUS::CollisionHeaderFactoryV0::ParseFileBinary(std::shared_ptrcollisionHeaderData.waterBoxes = collisionHeader->waterBoxes.data(); } -} void LUS::CollisionHeaderFactoryV0::ParseFileXML(tinyxml2::XMLElement* reader, std::shared_ptr resource) { std::shared_ptr collisionHeader = std::static_pointer_cast(resource); @@ -192,11 +191,11 @@ void LUS::CollisionHeaderFactoryV0::ParseFileXML(tinyxml2::XMLElement* reader, s } else if (childName == "Polygon") { CollisionPoly polygon; - polygon.type = child->IntAttribute("Type"); + polygon.type = child->UnsignedAttribute("Type"); - polygon.flags_vIA = child->IntAttribute("VertexA"); - polygon.flags_vIB = child->IntAttribute("VertexB"); - polygon.vIC = child->IntAttribute("VertexC"); + 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"); @@ -208,13 +207,13 @@ void LUS::CollisionHeaderFactoryV0::ParseFileXML(tinyxml2::XMLElement* reader, s } else if (childName == "PolygonType") { SurfaceType surfaceType; - surfaceType.data[0] = child->IntAttribute("Data1"); - surfaceType.data[1] = child->IntAttribute("Data2"); + 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->IntAttribute("SType"); + camDataEntry.cameraSType = child->UnsignedAttribute("SType"); camDataEntry.numCameras = child->IntAttribute("NumData"); collisionHeader->camData.push_back(camDataEntry); @@ -275,4 +274,5 @@ void LUS::CollisionHeaderFactoryV0::ParseFileXML(tinyxml2::XMLElement* reader, s collisionHeader->collisionHeaderData.cameraDataList = collisionHeader->camData.data(); collisionHeader->collisionHeaderData.cameraDataListLen = collisionHeader->camDataCount; collisionHeader->collisionHeaderData.waterBoxes = collisionHeader->waterBoxes.data(); +} } \ No newline at end of file diff --git a/soh/src/code/z_camera.c b/soh/src/code/z_camera.c index 783731506ed..0797ddfd6b3 100644 --- a/soh/src/code/z_camera.c +++ b/soh/src/code/z_camera.c @@ -7926,7 +7926,8 @@ s16 Camera_ChangeSettingFlags(Camera* camera, s16 setting, s16 flags) { 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); return -99; }