130 static uint16 cargo_disallowed[TOTAL_NUM_ENGINES]; |
126 static uint16 cargo_disallowed[TOTAL_NUM_ENGINES]; |
131 |
127 |
132 /* Contains the GRF ID of the owner of a vehicle if it has been reserved */ |
128 /* Contains the GRF ID of the owner of a vehicle if it has been reserved */ |
133 static uint32 _grm_engines[TOTAL_NUM_ENGINES]; |
129 static uint32 _grm_engines[TOTAL_NUM_ENGINES]; |
134 |
130 |
|
131 /* Contains the GRF ID of the owner of a cargo if it has been reserved */ |
|
132 static uint32 _grm_cargos[NUM_CARGO]; |
|
133 |
135 /** DEBUG() function dedicated to newGRF debugging messages |
134 /** DEBUG() function dedicated to newGRF debugging messages |
136 * Function is essentialy the same as DEBUG(grf, severity, ...) with the |
135 * Function is essentialy the same as DEBUG(grf, severity, ...) with the |
137 * addition of file:line information when parsing grf files. |
136 * addition of file:line information when parsing grf files. |
138 * NOTE: for the above reason(s) grfmsg() should ONLY be used for |
137 * NOTE: for the above reason(s) grfmsg() should ONLY be used for |
139 * loading/parsing grf files, not for runtime debug messages as there |
138 * loading/parsing grf files, not for runtime debug messages as there |
2895 return; |
2894 return; |
2896 } |
2895 } |
2897 replace = SPR_CANALS_BASE + 5; |
2896 replace = SPR_CANALS_BASE + 5; |
2898 break; |
2897 break; |
2899 |
2898 |
|
2899 case 0x09: // One way graphics |
|
2900 if (num != 6) { |
|
2901 grfmsg(1, "GraphicsNew: One way road graphics sprite count must be 6, skipping"); |
|
2902 return; |
|
2903 } |
|
2904 replace = SPR_ONEWAY_BASE; |
|
2905 break; |
|
2906 |
2900 case 0x0A: // 2CC colour maps |
2907 case 0x0A: // 2CC colour maps |
2901 if (num != 256) { |
2908 if (num != 256) { |
2902 grfmsg(1, "GraphicsNew: 2CC colour maps sprite count must be 256, skipping"); |
2909 grfmsg(1, "GraphicsNew: 2CC colour maps sprite count must be 256, skipping"); |
2903 return; |
2910 return; |
2904 } |
2911 } |
2905 replace = SPR_2CCMAP_BASE; |
2912 replace = SPR_2CCMAP_BASE; |
2906 break; |
2913 break; |
2907 |
2914 |
|
2915 case 0x0B: // tramways |
|
2916 if (num != 113) { |
|
2917 grfmsg(1, "GraphicsNew: Tramway graphics sprite count must be 113, skipping"); |
|
2918 return; |
|
2919 } |
|
2920 replace = SPR_TRAMWAY_BASE; |
|
2921 break; |
|
2922 |
2908 case 0x0D: // Coast graphics |
2923 case 0x0D: // Coast graphics |
2909 if (num != 16) { |
2924 if (num != 16) { |
2910 grfmsg(1, "GraphicsNew: Coast graphics sprite count must be 16, skipping"); |
2925 grfmsg(1, "GraphicsNew: Coast graphics sprite count must be 16, skipping"); |
2911 return; |
2926 return; |
2912 } |
2927 } |
2969 return clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR; |
2985 return clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR; |
2970 |
2986 |
2971 case 0x83: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland |
2987 case 0x83: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland |
2972 return _opt.landscape; |
2988 return _opt.landscape; |
2973 |
2989 |
2974 case 0x84: // GRF loading stage |
2990 case 0x84: { // GRF loading stage |
2975 return (_cur_stage > GLS_INIT) | ((_cur_stage == GLS_ACTIVATION) << 9); |
2991 uint32 res = 0; |
|
2992 |
|
2993 if (_cur_stage > GLS_INIT) SETBIT(res, 0); |
|
2994 if (_cur_stage == GLS_RESERVE) SETBIT(res, 8); |
|
2995 if (_cur_stage == GLS_ACTIVATION) SETBIT(res, 9); |
|
2996 return res; |
|
2997 } |
2976 |
2998 |
2977 case 0x85: // TTDPatch flags, only for bit tests |
2999 case 0x85: // TTDPatch flags, only for bit tests |
2978 if (cond_val == NULL) { |
3000 if (cond_val == NULL) { |
2979 /* Supported in Action 0x07 and 0x09, not 0x0D */ |
3001 /* Supported in Action 0x07 and 0x09, not 0x0D */ |
2980 return 0; |
3002 return 0; |
3303 uint32 grfid = grf_load_dword(&buf); |
3325 uint32 grfid = grf_load_dword(&buf); |
3304 const char *name = grf_load_string(&buf, len - 6); |
3326 const char *name = grf_load_string(&buf, len - 6); |
3305 |
3327 |
3306 _cur_grffile->grfid = grfid; |
3328 _cur_grffile->grfid = grfid; |
3307 _cur_grffile->grf_version = version; |
3329 _cur_grffile->grf_version = version; |
3308 _cur_grfconfig->status = _cur_stage < GLS_ACTIVATION ? GCS_INITIALISED : GCS_ACTIVATED; |
3330 _cur_grfconfig->status = _cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED; |
3309 |
3331 |
3310 /* Do swap the GRFID for displaying purposes since people expect that */ |
3332 /* Do swap the GRFID for displaying purposes since people expect that */ |
3311 DEBUG(grf, 1, "GRFInfo: Loaded GRFv%d set %08lX - %s", version, BSWAP32(grfid), name); |
3333 DEBUG(grf, 1, "GRFInfo: Loaded GRFv%d set %08lX - %s", version, BSWAP32(grfid), name); |
3312 } |
3334 } |
3313 |
3335 |
3524 |
3546 |
3525 default: |
3547 default: |
3526 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param); |
3548 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param); |
3527 return 0; |
3549 return 0; |
3528 } |
3550 } |
|
3551 } |
|
3552 |
|
3553 |
|
3554 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type) |
|
3555 { |
|
3556 uint start = 0; |
|
3557 uint size = 0; |
|
3558 |
|
3559 if (op == 6) { |
|
3560 /* Return GRFID of set that reserved ID */ |
|
3561 return grm[_cur_grffile->param[target]]; |
|
3562 } |
|
3563 |
|
3564 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */ |
|
3565 if (op == 2 || op == 3) start = _cur_grffile->param[target]; |
|
3566 |
|
3567 for (uint i = start; i < num_ids; i++) { |
|
3568 if (grm[i] == 0) { |
|
3569 size++; |
|
3570 } else { |
|
3571 if (op == 2 || op == 3) break; |
|
3572 start = i + 1; |
|
3573 size = 0; |
|
3574 } |
|
3575 |
|
3576 if (size == count) break; |
|
3577 } |
|
3578 |
|
3579 if (size == count) { |
|
3580 /* Got the slot... */ |
|
3581 if (op == 0 || op == 3) { |
|
3582 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start); |
|
3583 for (uint i = 0; i < count; i++) grm[start + i] = _cur_grffile->grfid; |
|
3584 } |
|
3585 return start; |
|
3586 } |
|
3587 |
|
3588 /* Unable to allocate */ |
|
3589 if (op != 4 && op != 5) { |
|
3590 /* Deactivate GRF */ |
|
3591 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type); |
|
3592 _cur_grfconfig->status = GCS_DISABLED; |
|
3593 _skip_sprites = -1; |
|
3594 return UINT_MAX; |
|
3595 } |
|
3596 |
|
3597 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type); |
|
3598 return UINT_MAX; |
3529 } |
3599 } |
3530 |
3600 |
3531 |
3601 |
3532 /* Action 0x0D */ |
3602 /* Action 0x0D */ |
3533 static void ParamSet(byte *buf, int len) |
3603 static void ParamSet(byte *buf, int len) |
3597 switch (feature) { |
3667 switch (feature) { |
3598 case 0x00: // Trains |
3668 case 0x00: // Trains |
3599 case 0x01: // Road Vehicles |
3669 case 0x01: // Road Vehicles |
3600 case 0x02: // Ships |
3670 case 0x02: // Ships |
3601 case 0x03: // Aircraft |
3671 case 0x03: // Aircraft |
3602 { |
3672 src1 = PerformGRM(&_grm_engines[_vehshifts[feature]], _vehcounts[feature], count, op, target, "vehicles"); |
3603 uint start = 0; |
3673 if (_skip_sprites == -1) return; |
3604 uint size = 0; |
|
3605 uint shift = _vehshifts[feature]; |
|
3606 |
|
3607 if (op == 6) { |
|
3608 /* Return GRFID of set that reserved ID */ |
|
3609 src1 = _grm_engines[shift + _cur_grffile->param[target]]; |
|
3610 break; |
|
3611 } |
|
3612 |
|
3613 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */ |
|
3614 if (op == 2 || op == 3) start = _cur_grffile->param[target]; |
|
3615 |
|
3616 for (uint i = start; i < _vehcounts[feature]; i++) { |
|
3617 if (_grm_engines[shift + i] == 0) { |
|
3618 size++; |
|
3619 } else { |
|
3620 if (op == 2 || op == 3) break; |
|
3621 start = i + 1; |
|
3622 size = 0; |
|
3623 } |
|
3624 |
|
3625 if (size == count) break; |
|
3626 } |
|
3627 |
|
3628 if (size == count) { |
|
3629 /* Got the slot... */ |
|
3630 if (op == 0 || op == 3) { |
|
3631 grfmsg(2, "ParamSet: GRM: Reserving %d vehicles at %d", count, start); |
|
3632 for (uint i = 0; i < count; i++) _grm_engines[shift + start + i] = _cur_grffile->grfid; |
|
3633 } |
|
3634 src1 = start; |
|
3635 } else { |
|
3636 /* Unable to allocate */ |
|
3637 if (op != 4 && op != 5) { |
|
3638 /* Deactivate GRF */ |
|
3639 grfmsg(0, "ParamSet: GRM: Unable to allocate %d vehicles, deactivating", count); |
|
3640 _cur_grfconfig->status = GCS_DISABLED; |
|
3641 |
|
3642 _skip_sprites = -1; |
|
3643 return; |
|
3644 } |
|
3645 |
|
3646 grfmsg(1, "ParamSet: GRM: Unable to allocate %d vehicles", count); |
|
3647 src1 = UINT_MAX; |
|
3648 } |
|
3649 break; |
3674 break; |
3650 } |
|
3651 |
3675 |
3652 case 0x08: // General sprites |
3676 case 0x08: // General sprites |
3653 switch (op) { |
3677 switch (op) { |
3654 case 0: |
3678 case 0: |
3655 /* Check if the allocated sprites will fit below the original sprite limit */ |
3679 /* Check if the allocated sprites will fit below the original sprite limit */ |
4235 | (1 << 0x0F) // statistics |
4264 | (1 << 0x0F) // statistics |
4236 | (1 << 0x10) // newsounds |
4265 | (1 << 0x10) // newsounds |
4237 | (1 << 0x11) // autoreplace |
4266 | (1 << 0x11) // autoreplace |
4238 | (1 << 0x12) // autoslope |
4267 | (1 << 0x12) // autoslope |
4239 | (0 << 0x13) // followvehicle |
4268 | (0 << 0x13) // followvehicle |
4240 | (0 << 0x14) // trams |
4269 | (1 << 0x14) // trams |
4241 | (0 << 0x15) // enhancetunnels |
4270 | (0 << 0x15) // enhancetunnels |
4242 | (0 << 0x16) // shortrvs |
4271 | (1 << 0x16) // shortrvs |
4243 | (0 << 0x17) // articulatedrvs |
4272 | (1 << 0x17) // articulatedrvs |
4244 | (1 << 0x1E); // variablerunningcosts |
4273 | (1 << 0x1E); // variablerunningcosts |
4245 } |
4274 } |
4246 |
4275 |
4247 static void ResetCustomStations() |
4276 static void ResetCustomStations() |
4248 { |
4277 { |
4287 GRFFile *file; |
4316 GRFFile *file; |
4288 uint i; |
4317 uint i; |
4289 |
4318 |
4290 for (file = _first_grffile; file != NULL; file = file->next) { |
4319 for (file = _first_grffile; file != NULL; file = file->next) { |
4291 if (file->housespec == NULL) continue; |
4320 if (file->housespec == NULL) continue; |
4292 for (i = 0; i < HOUSE_MAX; i++) free(file->housespec[i]); |
4321 for (i = 0; i < HOUSE_MAX; i++) { |
|
4322 free(file->housespec[i]); |
|
4323 } |
4293 |
4324 |
4294 free(file->housespec); |
4325 free(file->housespec); |
4295 file->housespec = NULL; |
4326 file->housespec = NULL; |
4296 } |
4327 } |
4297 } |
4328 } |
4298 |
4329 |
|
4330 static void ResetCustomIndustries() |
|
4331 { |
|
4332 GRFFile *file; |
|
4333 |
|
4334 for (file = _first_grffile; file != NULL; file = file->next) { |
|
4335 uint i; |
|
4336 /* We are verifiying both tiles and industries specs loaded from the grf file |
|
4337 * First, let's deal with industryspec */ |
|
4338 if (file->industryspec != NULL) { |
|
4339 |
|
4340 for (i = 0; i < NUM_INDUSTRYTYPES; i++) { |
|
4341 IndustrySpec *ind = file->industryspec[i]; |
|
4342 |
|
4343 if (ind != NULL) { |
|
4344 /* We need to remove the sounds array */ |
|
4345 if (HASBIT(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) { |
|
4346 free((void*)ind->random_sounds); |
|
4347 } |
|
4348 |
|
4349 /* We need to remove the tiles layouts */ |
|
4350 if (HASBIT(ind->cleanup_flag, CLEAN_TILELSAYOUT) && ind->table != NULL) { |
|
4351 for (int j = 0; j < ind->num_table; j++) { |
|
4352 /* remove the individual layouts */ |
|
4353 if (ind->table[j] != NULL) { |
|
4354 free((IndustryTileTable*)ind->table[j]); |
|
4355 } |
|
4356 } |
|
4357 /* remove the layouts pointers */ |
|
4358 free((IndustryTileTable**)ind->table); |
|
4359 ind->table = NULL; |
|
4360 } |
|
4361 |
|
4362 free(ind); |
|
4363 ind = NULL; |
|
4364 } |
|
4365 } |
|
4366 |
|
4367 free(file->industryspec); |
|
4368 file->industryspec = NULL; |
|
4369 } |
|
4370 |
|
4371 if (file->indtspec != NULL) { |
|
4372 for (i = 0; i < NUM_INDUSTRYTILES; i++) { |
|
4373 if (file->indtspec[i] != NULL) { |
|
4374 free(file->indtspec[i]); |
|
4375 file->indtspec[i] = NULL; |
|
4376 } |
|
4377 } |
|
4378 |
|
4379 free(file->indtspec); |
|
4380 file->indtspec = NULL; |
|
4381 } |
|
4382 } |
|
4383 } |
|
4384 |
4299 static void ResetNewGRF() |
4385 static void ResetNewGRF() |
4300 { |
4386 { |
4301 GRFFile *next; |
4387 GRFFile *next; |
4302 |
4388 |
4303 for (GRFFile *f = _first_grffile; f != NULL; f = next) { |
4389 for (GRFFile *f = _first_grffile; f != NULL; f = next) { |
4304 next = f->next; |
4390 next = f->next; |
4305 |
4391 |
4306 free(f->filename); |
4392 free(f->filename); |
|
4393 free(f->cargo_list); |
4307 free(f); |
4394 free(f); |
4308 } |
4395 } |
4309 |
4396 |
4310 _first_grffile = NULL; |
4397 _first_grffile = NULL; |
4311 _cur_grffile = NULL; |
4398 _cur_grffile = NULL; |
4340 memset(&cargo_allowed, 0, sizeof(cargo_allowed)); |
4427 memset(&cargo_allowed, 0, sizeof(cargo_allowed)); |
4341 memset(&cargo_disallowed, 0, sizeof(cargo_disallowed)); |
4428 memset(&cargo_disallowed, 0, sizeof(cargo_disallowed)); |
4342 |
4429 |
4343 /* Reset GRM reservations */ |
4430 /* Reset GRM reservations */ |
4344 memset(&_grm_engines, 0, sizeof(_grm_engines)); |
4431 memset(&_grm_engines, 0, sizeof(_grm_engines)); |
|
4432 memset(&_grm_cargos, 0, sizeof(_grm_cargos)); |
4345 |
4433 |
4346 /* Unload sprite group data */ |
4434 /* Unload sprite group data */ |
4347 UnloadWagonOverrides(); |
4435 UnloadWagonOverrides(); |
4348 UnloadRotorOverrideSprites(); |
4436 UnloadRotorOverrideSprites(); |
4349 UnloadCustomEngineSprites(); |
4437 UnloadCustomEngineSprites(); |
4667 /* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, }, |
4760 /* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, }, |
4668 /* 0x04 */ { NULL, NULL, NULL, NULL, NULL, FeatureNewName, }, |
4761 /* 0x04 */ { NULL, NULL, NULL, NULL, NULL, FeatureNewName, }, |
4669 /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, }, |
4762 /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, }, |
4670 /* 0x06 */ { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, }, |
4763 /* 0x06 */ { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, }, |
4671 /* 0x07 */ { NULL, NULL, NULL, NULL, SkipIf, SkipIf, }, |
4764 /* 0x07 */ { NULL, NULL, NULL, NULL, SkipIf, SkipIf, }, |
4672 /* 0x08 */ { ScanInfo, NULL, NULL, GRFInfo, NULL, GRFInfo, }, |
4765 /* 0x08 */ { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, }, |
4673 /* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, }, |
4766 /* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, }, |
4674 /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, }, |
4767 /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, }, |
4675 /* 0x0B */ { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, }, |
4768 /* 0x0B */ { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, }, |
4676 /* 0x0C */ { NULL, NULL, NULL, GRFComment, NULL, GRFComment, }, |
4769 /* 0x0C */ { NULL, NULL, NULL, GRFComment, NULL, GRFComment, }, |
4677 /* 0x0D */ { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, }, |
4770 /* 0x0D */ { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, }, |
4736 * carried out. All others are ignored, because they only need to be |
4829 * carried out. All others are ignored, because they only need to be |
4737 * processed once at initialization. */ |
4830 * processed once at initialization. */ |
4738 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) { |
4831 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) { |
4739 _cur_grffile = GetFileByFilename(filename); |
4832 _cur_grffile = GetFileByFilename(filename); |
4740 if (_cur_grffile == NULL) error("File '%s' lost in cache.\n", filename); |
4833 if (_cur_grffile == NULL) error("File '%s' lost in cache.\n", filename); |
|
4834 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return; |
4741 if (stage == GLS_ACTIVATION && config->status != GCS_INITIALISED) return; |
4835 if (stage == GLS_ACTIVATION && config->status != GCS_INITIALISED) return; |
4742 } |
4836 } |
4743 |
4837 |
4744 FioOpenFile(file_index, filename); |
4838 FioOpenFile(file_index, filename); |
4745 _file_index = file_index; // XXX |
4839 _file_index = file_index; // XXX |
4840 _cur_spriteid = load_index; |
4941 _cur_spriteid = load_index; |
4841 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) { |
4942 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) { |
4842 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue; |
4943 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue; |
4843 |
4944 |
4844 /* @todo usererror() */ |
4945 /* @todo usererror() */ |
4845 if (!FileExists(c->full_path)) error("NewGRF file is missing '%s'", c->filename); |
4946 if (!FioCheckFileExists(c->full_path)) error("NewGRF file is missing '%s'", c->filename); |
4846 |
4947 |
4847 if (stage == GLS_LABELSCAN) InitNewGRFFile(c, _cur_spriteid); |
4948 if (stage == GLS_LABELSCAN) InitNewGRFFile(c, _cur_spriteid); |
4848 LoadNewGRFFile(c, slot++, stage); |
4949 LoadNewGRFFile(c, slot++, stage); |
4849 if (stage == GLS_ACTIVATION) { |
4950 if (stage == GLS_RESERVE) { |
|
4951 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED; |
|
4952 } else if (stage == GLS_ACTIVATION) { |
4850 ClearTemporaryNewGRFData(); |
4953 ClearTemporaryNewGRFData(); |
4851 BuildCargoTranslationMap(); |
4954 BuildCargoTranslationMap(); |
4852 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur_spriteid); |
4955 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur_spriteid); |
4853 } |
4956 } |
4854 } |
4957 } |