* Load a particular NewGRF from a SpriteFile. * @param config The configuration of the to be loaded NewGRF. * @param stage The loading stage of the NewGRF. * @param file The file to load the GRF data from. */
| 1293 | * @param file The file to load the GRF data from. |
| 1294 | */ |
| 1295 | static void LoadNewGRFFileFromFile(GRFConfig &config, GrfLoadingStage stage, SpriteFile &file) |
| 1296 | { |
| 1297 | AutoRestoreBackup cur_file(_cur_gps.file, &file); |
| 1298 | AutoRestoreBackup cur_config(_cur_gps.grfconfig, &config); |
| 1299 | |
| 1300 | Debug(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '{}'", config.filename); |
| 1301 | |
| 1302 | uint8_t grf_container_version = file.GetContainerVersion(); |
| 1303 | if (grf_container_version == 0) { |
| 1304 | Debug(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format"); |
| 1305 | return; |
| 1306 | } |
| 1307 | |
| 1308 | if (stage == GLS_INIT || stage == GLS_ACTIVATION) { |
| 1309 | /* We need the sprite offsets in the init stage for NewGRF sounds |
| 1310 | * and in the activation stage for real sprites. */ |
| 1311 | ReadGRFSpriteOffsets(file); |
| 1312 | } else { |
| 1313 | /* Skip sprite section offset if present. */ |
| 1314 | if (grf_container_version >= 2) file.ReadDword(); |
| 1315 | } |
| 1316 | |
| 1317 | if (grf_container_version >= 2) { |
| 1318 | /* Read compression value. */ |
| 1319 | uint8_t compression = file.ReadByte(); |
| 1320 | if (compression != 0) { |
| 1321 | Debug(grf, 7, "LoadNewGRFFile: Unsupported compression format"); |
| 1322 | return; |
| 1323 | } |
| 1324 | } |
| 1325 | |
| 1326 | /* Skip the first sprite; we don't care about how many sprites this |
| 1327 | * does contain; newest TTDPatches and George's longvehicles don't |
| 1328 | * neither, apparently. */ |
| 1329 | uint32_t num = grf_container_version >= 2 ? file.ReadDword() : file.ReadWord(); |
| 1330 | if (num == 4 && file.ReadByte() == 0xFF) { |
| 1331 | file.ReadDword(); |
| 1332 | } else { |
| 1333 | Debug(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format"); |
| 1334 | return; |
| 1335 | } |
| 1336 | |
| 1337 | _cur_gps.ClearDataForNextFile(); |
| 1338 | |
| 1339 | ReusableBuffer<uint8_t> allocator; |
| 1340 | |
| 1341 | while ((num = (grf_container_version >= 2 ? file.ReadDword() : file.ReadWord())) != 0) { |
| 1342 | uint8_t type = file.ReadByte(); |
| 1343 | _cur_gps.nfo_line++; |
| 1344 | |
| 1345 | if (type == 0xFF) { |
| 1346 | if (_cur_gps.skip_sprites == 0) { |
| 1347 | /* Limit the special sprites to 1 MiB. */ |
| 1348 | if (num > 1024 * 1024) { |
| 1349 | GrfMsg(0, "LoadNewGRFFile: Unexpectedly large sprite, disabling"); |
| 1350 | DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE); |
| 1351 | break; |
| 1352 | } |
no test coverage detected