| 134 | } |
| 135 | |
| 136 | bool NFS3::LoadFRD(std::string frd_path, const std::string &track_name, const std::shared_ptr<TRACK> &track) { |
| 137 | ifstream ar(frd_path, ios::in | ios::binary); |
| 138 | |
| 139 | char header[28]; /* file header */ |
| 140 | SAFE_READ(ar, header, 28); // header & numblocks |
| 141 | SAFE_READ(ar, &track->nBlocks, 4); |
| 142 | track->nBlocks++; |
| 143 | if ((track->nBlocks < 1) || (track->nBlocks > 500)) return false; // 1st sanity check |
| 144 | |
| 145 | LOG(INFO) << "Loading FRD File located at " << frd_path; |
| 146 | |
| 147 | track->trk = new TRKBLOCK[track->nBlocks](); |
| 148 | track->poly = new POLYGONBLOCK[track->nBlocks](); |
| 149 | track->xobj = new XOBJBLOCK[4 * track->nBlocks + 1](); |
| 150 | |
| 151 | int l; |
| 152 | SAFE_READ(ar, &l, 4); // choose between NFS3 & NFSHS |
| 153 | if ((l < 0) || (l > 5000)) track->bHSMode = false; |
| 154 | else if (((l + 7) / 8) == track->nBlocks) track->bHSMode = true; |
| 155 | else return false; // unknown file type |
| 156 | |
| 157 | memcpy(track->trk, &l, 4); |
| 158 | if (ar.read(((char *) track->trk) + 4, 80).gcount() != 80) return false; |
| 159 | |
| 160 | // TRKBLOCKs |
| 161 | for (uint32_t block_Idx = 0; block_Idx < track->nBlocks; block_Idx++) { |
| 162 | TRKBLOCK *trackBlock = &(track->trk[block_Idx]); |
| 163 | // ptCentre, ptBounding, 6 nVertices == 84 bytes |
| 164 | if (block_Idx != 0) { SAFE_READ(ar, trackBlock, 84); } |
| 165 | if (trackBlock->nVertices == 0) return false; |
| 166 | trackBlock->vert = new FLOATPT[trackBlock->nVertices];; |
| 167 | |
| 168 | SAFE_READ(ar, trackBlock->vert, 12 * trackBlock->nVertices); |
| 169 | trackBlock->unknVertices = new uint32_t[trackBlock->nVertices]; |
| 170 | SAFE_READ(ar, trackBlock->unknVertices, 4 * trackBlock->nVertices); |
| 171 | SAFE_READ(ar, trackBlock->nbdData, 4 * 0x12c); |
| 172 | // nStartPos & various blk sizes == 32 bytes |
| 173 | SAFE_READ(ar, &(trackBlock->nStartPos), 32); |
| 174 | |
| 175 | if (block_Idx > 0) |
| 176 | if (trackBlock->nStartPos != |
| 177 | track->trk[block_Idx - 1].nStartPos + track->trk[block_Idx - 1].nPositions) |
| 178 | return false; |
| 179 | trackBlock->posData = new POSITIONDATA[trackBlock->nPositions]; |
| 180 | SAFE_READ(ar, trackBlock->posData, 8 * trackBlock->nPositions); |
| 181 | |
| 182 | trackBlock->polyData = new POLYVROADDATA[trackBlock->nPolygons]; |
| 183 | |
| 184 | for (uint32_t j = 0; j < trackBlock->nPolygons; j++) |
| 185 | SAFE_READ(ar, trackBlock->polyData + j, 8); |
| 186 | |
| 187 | trackBlock->vroadData = new VROADDATA[trackBlock->nVRoad]; |
| 188 | SAFE_READ(ar, trackBlock->vroadData, 12 * trackBlock->nVRoad); |
| 189 | |
| 190 | if (trackBlock->nXobj > 0) { |
| 191 | trackBlock->xobj = new REFXOBJ[trackBlock->nXobj]; |
| 192 | SAFE_READ(ar, trackBlock->xobj, 20 * trackBlock->nXobj); |
| 193 | } |
nothing calls this directly
no outgoing calls
no test coverage detected