| 293 | } |
| 294 | |
| 295 | bool NFS3::LoadCOL(std::string col_path, const std::shared_ptr<TRACK> &track) { |
| 296 | ifstream coll(col_path, ios::in | ios::binary); |
| 297 | |
| 298 | COLOBJECT *o; |
| 299 | |
| 300 | track->col.hs_extra = NULL; |
| 301 | if (coll.read((char *) &track->col, 16).gcount() != 16) return false; |
| 302 | if (memcmp(track->col.collID, "COLL", sizeof(track->col.collID[0])) != 0) { |
| 303 | LOG(WARNING) << "Invalid COL file"; |
| 304 | return false; |
| 305 | } |
| 306 | |
| 307 | LOG(INFO) << "Loading COL File located at " << col_path; |
| 308 | |
| 309 | if (track->col.version != 11) return false; |
| 310 | if ((track->col.nBlocks != 2) && (track->col.nBlocks != 4) && (track->col.nBlocks != 5)) return false; |
| 311 | SAFE_READ(coll, track->col.xbTable, 4 * track->col.nBlocks); |
| 312 | |
| 313 | // texture XB |
| 314 | SAFE_READ(coll, &track->col.textureHead, 8); |
| 315 | if (track->col.textureHead.xbid != XBID_TEXTUREINFO) return false; |
| 316 | |
| 317 | track->col.texture = new COLTEXTUREINFO[track->col.textureHead.nrec]; |
| 318 | SAFE_READ(coll, track->col.texture, 8 * track->col.textureHead.nrec); |
| 319 | |
| 320 | // struct3D XB |
| 321 | if (track->col.nBlocks >= 4) { |
| 322 | SAFE_READ(coll, &track->col.struct3DHead, 8); |
| 323 | if (track->col.struct3DHead.xbid != XBID_STRUCT3D) return false; |
| 324 | COLSTRUCT3D *s = track->col.struct3D = new COLSTRUCT3D[track->col.struct3DHead.nrec]; |
| 325 | int delta; |
| 326 | for (uint32_t colRec_Idx = 0; colRec_Idx < track->col.struct3DHead.nrec; colRec_Idx++, s++) { |
| 327 | SAFE_READ(coll, s, 8); |
| 328 | delta = (8 + 16 * s->nVert + 6 * s->nPoly) % 4; |
| 329 | delta = (4 - delta) % 4; |
| 330 | if (s->size != 8 + 16 * s->nVert + 6 * s->nPoly + delta) return false; |
| 331 | s->vertex = new COLVERTEX[s->nVert]; |
| 332 | SAFE_READ(coll, s->vertex, 16 * s->nVert); |
| 333 | s->polygon = new COLPOLYGON[s->nPoly]; |
| 334 | SAFE_READ(coll, s->polygon, 6 * s->nPoly); |
| 335 | int dummy; |
| 336 | if (delta > 0) SAFE_READ(coll, &dummy, delta); |
| 337 | } |
| 338 | |
| 339 | // object XB |
| 340 | SAFE_READ(coll, &track->col.objectHead, 8); |
| 341 | if ((track->col.objectHead.xbid != XBID_OBJECT) && (track->col.objectHead.xbid != XBID_OBJECT2)) |
| 342 | return false; |
| 343 | o = track->col.object = new COLOBJECT[track->col.objectHead.nrec]; |
| 344 | |
| 345 | for (uint32_t colRec_Idx = 0; colRec_Idx < track->col.objectHead.nrec; colRec_Idx++, o++) { |
| 346 | SAFE_READ(coll, o, 4); |
| 347 | if (o->type == 1) { |
| 348 | if (o->size != 16) return false; |
| 349 | SAFE_READ(coll, &(o->ptRef), 12); |
| 350 | } else if (o->type == 3) { |
| 351 | SAFE_READ(coll, &(o->animLength), 4); |
| 352 | if (o->size != 8 + 20 * o->animLength) return false; |
nothing calls this directly
no outgoing calls
no test coverage detected