| 735 | |
| 736 | template<typename Platform> |
| 737 | bool NFS2<Platform>::LoadCOL(std::string col_path, const shared_ptr<typename Platform::TRACK> &track) { |
| 738 | LOG(INFO) << "Loading COL File located at " << col_path; |
| 739 | ifstream col(col_path, ios::in | ios::binary); |
| 740 | // Check we're in a valid TRK file |
| 741 | unsigned char header[4]; |
| 742 | if (col.read(((char *) header), sizeof(unsigned char) * 4).gcount() != sizeof(unsigned char) * 4) return false; |
| 743 | if (memcmp(header, "COLL", sizeof(header)) != 0) return false; |
| 744 | |
| 745 | uint32_t version; |
| 746 | col.read((char *) &version, sizeof(uint32_t)); |
| 747 | if (version != 11) return false; |
| 748 | |
| 749 | streampos colSize; |
| 750 | col.read((char *) &colSize, sizeof(uint32_t)); |
| 751 | |
| 752 | uint32_t nExtraBlocks; |
| 753 | col.read((char *) &nExtraBlocks, sizeof(uint32_t)); |
| 754 | |
| 755 | uint32_t *extraBlockOffsets = (uint32_t *) calloc(nExtraBlocks, sizeof(uint32_t)); |
| 756 | col.read((char *) extraBlockOffsets, nExtraBlocks * sizeof(uint32_t)); |
| 757 | |
| 758 | LOG(INFO) << "Version: " << version << " nExtraBlocks: " << nExtraBlocks; |
| 759 | LOG(DEBUG) << "Parsing COL Extrablocks"; |
| 760 | |
| 761 | for (uint32_t xBlock_Idx = 0; xBlock_Idx < nExtraBlocks; ++xBlock_Idx) { |
| 762 | col.seekg(16 + extraBlockOffsets[xBlock_Idx], ios_base::beg); |
| 763 | |
| 764 | auto *xblockHeader = static_cast<EXTRABLOCK_HEADER *>(calloc(1, sizeof(EXTRABLOCK_HEADER))); |
| 765 | col.read((char *) xblockHeader, sizeof(EXTRABLOCK_HEADER)); |
| 766 | |
| 767 | LOG(DEBUG) << " XBID " << (int) xblockHeader->XBID << " (XBlock " << xBlock_Idx + 1 << " of " << nExtraBlocks << ")"; |
| 768 | |
| 769 | switch (xblockHeader->XBID) { |
| 770 | case 2: // First xbock always texture table |
| 771 | track->nTextures = xblockHeader->nRecords; |
| 772 | track->polyToQFStexTable = static_cast<TEXTURE_BLOCK *>(calloc(track->nTextures, sizeof(TEXTURE_BLOCK))); |
| 773 | col.read((char *) track->polyToQFStexTable, track->nTextures * sizeof(TEXTURE_BLOCK)); |
| 774 | break; |
| 775 | case 8: // XBID 8 3D Structure data: This block is only present if nExtraBlocks != 2 |
| 776 | track->nColStructures = xblockHeader->nRecords; |
| 777 | track->colStructures = static_cast<typename Platform::GEOM_BLOCK *>(calloc(track->nColStructures, sizeof(typename Platform::GEOM_BLOCK))); |
| 778 | for (uint32_t structure_Idx = 0; structure_Idx < track->nColStructures; ++structure_Idx) { |
| 779 | streamoff padCheck = col.tellg(); |
| 780 | col.read((char *) &track->colStructures[structure_Idx].recSize, sizeof(uint32_t)); |
| 781 | col.read((char *) &track->colStructures[structure_Idx].nVerts, sizeof(uint16_t)); |
| 782 | col.read((char *) &track->colStructures[structure_Idx].nPoly, sizeof(uint16_t)); |
| 783 | track->colStructures[structure_Idx].vertexTable = static_cast<typename Platform::VERT *>(calloc(track->colStructures[structure_Idx].nVerts, sizeof(typename Platform::VERT))); |
| 784 | for (uint32_t vert_Idx = 0; vert_Idx < track->colStructures[structure_Idx].nVerts; ++vert_Idx) { |
| 785 | col.read((char *) &track->colStructures[structure_Idx].vertexTable[vert_Idx], sizeof(typename Platform::VERT)); |
| 786 | } |
| 787 | track->colStructures[structure_Idx].polygonTable = static_cast<typename Platform::POLYGONDATA *>(calloc(track->colStructures[structure_Idx].nPoly, sizeof(typename Platform::POLYGONDATA))); |
| 788 | for (uint32_t poly_Idx = 0; poly_Idx < track->colStructures[structure_Idx].nPoly; ++poly_Idx) { |
| 789 | col.read((char *) &track->colStructures[structure_Idx].polygonTable[poly_Idx], sizeof(typename Platform::POLYGONDATA)); |
| 790 | } |
| 791 | col.seekg(track->colStructures[structure_Idx].recSize - (col.tellg() - padCheck), ios_base::cur); // Eat possible padding |
| 792 | } |
| 793 | break; |
| 794 | case 7: // XBID 7 3D Structure Reference: This block is only present if nExtraBlocks != 2 |
nothing calls this directly
no outgoing calls
no test coverage detected