00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013
00014 #include <stdarg.h>
00015
00016 #include "debug.h"
00017 #include "fileio_func.h"
00018 #include "engine_func.h"
00019 #include "engine_base.h"
00020 #include "variables.h"
00021 #include "bridge.h"
00022 #include "town.h"
00023 #include "newgrf_engine.h"
00024 #include "newgrf_text.h"
00025 #include "fontcache.h"
00026 #include "currency.h"
00027 #include "landscape.h"
00028 #include "newgrf.h"
00029 #include "newgrf_cargo.h"
00030 #include "newgrf_house.h"
00031 #include "newgrf_sound.h"
00032 #include "newgrf_station.h"
00033 #include "industry.h"
00034 #include "newgrf_canal.h"
00035 #include "newgrf_commons.h"
00036 #include "newgrf_townname.h"
00037 #include "newgrf_industries.h"
00038 #include "rev.h"
00039 #include "fios.h"
00040 #include "rail.h"
00041 #include "strings_func.h"
00042 #include "date_func.h"
00043 #include "string_func.h"
00044 #include "network/network.h"
00045 #include <map>
00046 #include "core/alloc_type.hpp"
00047 #include "core/mem_func.hpp"
00048
00049 #include "table/strings.h"
00050 #include "table/build_industry.h"
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 static int _skip_sprites;
00063 static uint _file_index;
00064
00065 static SmallVector<GRFFile *, 16> _grf_files;
00066
00067 static GRFFile *_cur_grffile;
00068 static SpriteID _cur_spriteid;
00069 static GrfLoadingStage _cur_stage;
00070 static uint32 _nfo_line;
00071
00072 static GRFConfig *_cur_grfconfig;
00073
00074
00075 static byte _misc_grf_features = 0;
00076
00077
00078 static uint32 _ttdpatch_flags[8];
00079
00080
00081 GRFLoadedFeatures _loaded_newgrf_features;
00082
00083 enum GrfDataType {
00084 GDT_SOUND,
00085 };
00086
00087 static byte _grf_data_blocks;
00088 static GrfDataType _grf_data_type;
00089
00090 class OTTDByteReaderSignal { };
00091
00092 class ByteReader {
00093 protected:
00094 byte *data;
00095 byte *end;
00096
00097 public:
00098 ByteReader(byte *data, byte *end) : data(data), end(end) { }
00099
00100 FORCEINLINE byte ReadByte()
00101 {
00102 if (data < end) return *(data)++;
00103 throw OTTDByteReaderSignal();
00104 }
00105
00106 uint16 ReadWord()
00107 {
00108 uint16 val = ReadByte();
00109 return val | (ReadByte() << 8);
00110 }
00111
00112 uint16 ReadExtended()
00113 {
00114 uint16 val = ReadByte();
00115 return val == 0xFF ? ReadWord() : val;
00116 }
00117
00118 uint32 ReadDWord()
00119 {
00120 uint32 val = ReadWord();
00121 return val | (ReadWord() << 16);
00122 }
00123
00124 uint32 ReadVarSize(byte size)
00125 {
00126 switch (size) {
00127 case 1: return ReadByte();
00128 case 2: return ReadWord();
00129 case 4: return ReadDWord();
00130 default:
00131 NOT_REACHED();
00132 return 0;
00133 }
00134 }
00135
00136 const char *ReadString()
00137 {
00138 char *string = reinterpret_cast<char *>(data);
00139 size_t string_length = ttd_strnlen(string, Remaining());
00140
00141 if (string_length == Remaining()) {
00142
00143 string[string_length - 1] = '\0';
00144 grfmsg(7, "String was not terminated with a zero byte.");
00145 } else {
00146
00147 string_length++;
00148 }
00149 Skip(string_length);
00150
00151 return string;
00152 }
00153
00154 FORCEINLINE size_t Remaining() const
00155 {
00156 return end - data;
00157 }
00158
00159 FORCEINLINE bool HasData() const
00160 {
00161 return data < end;
00162 }
00163
00164 FORCEINLINE byte *Data()
00165 {
00166 return data;
00167 }
00168
00169 FORCEINLINE void Skip(size_t len)
00170 {
00171 data += len;
00172
00173
00174 if (data > end) throw OTTDByteReaderSignal();
00175 }
00176 };
00177
00178 typedef void (*SpecialSpriteHandler)(ByteReader *buf);
00179
00180 enum {
00181 MAX_STATIONS = 256,
00182 };
00183
00184
00185 struct GRFTempEngineData {
00186 uint16 cargo_allowed;
00187 uint16 cargo_disallowed;
00188 bool refitmask_valid;
00189 uint8 rv_max_speed;
00190 };
00191
00192 static GRFTempEngineData *_gted;
00193
00194
00195
00196
00197 static uint32 _grm_engines[256];
00198
00199
00200 static uint32 _grm_cargos[NUM_CARGO * 2];
00201
00202 struct GRFLocation {
00203 uint32 grfid;
00204 uint32 nfoline;
00205
00206 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
00207
00208 bool operator<(const GRFLocation &other) const
00209 {
00210 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
00211 }
00212
00213 bool operator == (const GRFLocation &other) const
00214 {
00215 return this->grfid == other.grfid && this->nfoline == other.nfoline;
00216 }
00217 };
00218
00219 static std::map<GRFLocation, SpriteID> _grm_sprites;
00220 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
00221 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
00222
00231 void CDECL grfmsg(int severity, const char *str, ...)
00232 {
00233 char buf[1024];
00234 va_list va;
00235
00236 va_start(va, str);
00237 vsnprintf(buf, sizeof(buf), str, va);
00238 va_end(va);
00239
00240 DEBUG(grf, severity, "[%s:%d] %s", _cur_grfconfig->filename, _nfo_line, buf);
00241 }
00242
00243 static GRFFile *GetFileByGRFID(uint32 grfid)
00244 {
00245 const GRFFile * const *end = _grf_files.End();
00246 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
00247 if ((*file)->grfid == grfid) return *file;
00248 }
00249 return NULL;
00250 }
00251
00252 static GRFFile *GetFileByFilename(const char *filename)
00253 {
00254 const GRFFile * const *end = _grf_files.End();
00255 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
00256 if (strcmp((*file)->filename, filename) == 0) return *file;
00257 }
00258 return NULL;
00259 }
00260
00262 static void ClearTemporaryNewGRFData(GRFFile *gf)
00263 {
00264
00265 for (GRFLabel *l = gf->label; l != NULL;) {
00266 GRFLabel *l2 = l->next;
00267 free(l);
00268 l = l2;
00269 }
00270 gf->label = NULL;
00271
00272
00273 free(gf->spritegroups);
00274 gf->spritegroups = NULL;
00275 gf->spritegroups_count = 0;
00276 }
00277
00278
00279 typedef std::map<StringID *, uint32> StringIDToGRFIDMapping;
00280 static StringIDToGRFIDMapping _string_to_grf_mapping;
00281
00288 StringID MapGRFStringID(uint32 grfid, StringID str)
00289 {
00290
00291
00292
00293
00294 switch (GB(str, 8, 8)) {
00295 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
00296 case 0xDC:
00297 return GetGRFStringID(grfid, str);
00298
00299 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
00300
00301
00302 return GetGRFStringID(grfid, str - 0x400);
00303
00304 default: break;
00305 }
00306
00307 return TTDPStringIDToOTTDStringIDMapping(str);
00308 }
00309
00310 static inline uint8 MapDOSColour(uint8 colour)
00311 {
00312 extern const byte _palmap_d2w[];
00313 return (_use_palette == PAL_DOS ? colour : _palmap_d2w[colour]);
00314 }
00315
00316 static std::map<uint32, uint32> _grf_id_overrides;
00317
00318 static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
00319 {
00320 _grf_id_overrides[source_grfid] = target_grfid;
00321 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
00322 }
00323
00332 static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false)
00333 {
00334
00335
00336 uint32 scope_grfid = INVALID_GRFID;
00337 if (_settings_game.vehicle.dynamic_engines) {
00338
00339 scope_grfid = file->grfid;
00340 uint32 override = _grf_id_overrides[file->grfid];
00341 if (override != 0) {
00342 scope_grfid = override;
00343 const GRFFile *grf_match = GetFileByGRFID(override);
00344 if (grf_match == NULL) {
00345 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
00346 } else {
00347 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
00348 }
00349 }
00350
00351
00352 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
00353 if (engine != INVALID_ENGINE) {
00354 Engine *e = Engine::Get(engine);
00355 if (e->grffile == NULL) e->grffile = file;
00356 return e;
00357 }
00358 }
00359
00360
00361 EngineID engine = _engine_mngr.GetID(type, internal_id, INVALID_GRFID);
00362 if (engine != INVALID_ENGINE) {
00363 Engine *e = Engine::Get(engine);
00364
00365 if (e->grffile == NULL) {
00366 e->grffile = file;
00367 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
00368 }
00369
00370
00371 if (!static_access) {
00372 EngineIDMapping *eid = _engine_mngr.Get(engine);
00373 eid->grfid = scope_grfid;
00374 }
00375
00376 return e;
00377 }
00378
00379 if (static_access) return NULL;
00380
00381 size_t engine_pool_size = Engine::GetPoolSize();
00382
00383
00384 Engine *e = new Engine(type, internal_id);
00385 e->grffile = file;
00386
00387
00388 assert(_engine_mngr.Length() == e->index);
00389 EngineIDMapping *eid = _engine_mngr.Append();
00390 eid->type = type;
00391 eid->grfid = scope_grfid;
00392 eid->internal_id = internal_id;
00393 eid->substitute_id = min(internal_id, _engine_counts[type]);
00394
00395 if (engine_pool_size != Engine::GetPoolSize()) {
00396
00397 _gted = ReallocT(_gted, Engine::GetPoolSize());
00398
00399
00400 size_t len = (Engine::GetPoolSize() - engine_pool_size) * sizeof(*_gted);
00401 memset(_gted + engine_pool_size, 0, len);
00402 }
00403
00404 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
00405
00406 return e;
00407 }
00408
00409 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
00410 {
00411 uint32 scope_grfid = INVALID_GRFID;
00412 if (_settings_game.vehicle.dynamic_engines) {
00413 scope_grfid = file->grfid;
00414 uint32 override = _grf_id_overrides[file->grfid];
00415 if (override != 0) scope_grfid = override;
00416 }
00417
00418 return _engine_mngr.GetID(type, internal_id, scope_grfid);
00419 }
00420
00424 static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
00425 {
00426 if (HasBit(grf_sprite->pal, 14)) {
00427 ClrBit(grf_sprite->pal, 14);
00428 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_OPAQUE);
00429 }
00430
00431 if (HasBit(grf_sprite->sprite, 14)) {
00432 ClrBit(grf_sprite->sprite, 14);
00433 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_TRANSPARENT);
00434 }
00435
00436 if (HasBit(grf_sprite->sprite, 15)) {
00437 ClrBit(grf_sprite->sprite, 15);
00438 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_COLOUR);
00439 }
00440 }
00441
00449 static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
00450 {
00451
00452 if (base_pointer == 0) {
00453 *index = INVALID_PRICE;
00454 return;
00455 }
00456
00457 static const uint32 start = 0x4B34;
00458 static const uint32 size = 6;
00459
00460 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
00461 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
00462 return;
00463 }
00464
00465 *index = (Price)((base_pointer - start) / size);
00466 }
00467
00468 enum ChangeInfoResult {
00469 CIR_SUCCESS,
00470 CIR_UNHANDLED,
00471 CIR_UNKNOWN,
00472 CIR_INVALID_ID,
00473 };
00474
00475 typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
00476
00477 static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader *buf)
00478 {
00479 switch (prop) {
00480 case 0x00:
00481 ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
00482 break;
00483
00484 case 0x02:
00485 ei->decay_speed = buf->ReadByte();
00486 break;
00487
00488 case 0x03:
00489 ei->lifelength = buf->ReadByte();
00490 break;
00491
00492 case 0x04:
00493 ei->base_life = buf->ReadByte();
00494 break;
00495
00496 case 0x06:
00497 ei->climates = buf->ReadByte();
00498
00499
00500 if (ei->climates == 0) ei->climates = 0x80;
00501 break;
00502
00503 case 0x07:
00504
00505 ei->load_amount = buf->ReadByte();
00506 break;
00507
00508 default:
00509 return CIR_UNKNOWN;
00510 }
00511
00512 return CIR_SUCCESS;
00513 }
00514
00515 static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
00516 {
00517 ChangeInfoResult ret = CIR_SUCCESS;
00518
00519 for (int i = 0; i < numinfo; i++) {
00520 Engine *e = GetNewEngine(_cur_grffile, VEH_TRAIN, engine + i);
00521 EngineInfo *ei = &e->info;
00522 RailVehicleInfo *rvi = &e->u.rail;
00523
00524 switch (prop) {
00525 case 0x05: {
00526 uint8 tracktype = buf->ReadByte();
00527
00528 if (tracktype < _cur_grffile->railtype_max) {
00529 RailType railtype = GetRailTypeByLabel(_cur_grffile->railtype_list[tracktype]);
00530 if (railtype == INVALID_RAILTYPE) {
00531
00532 ei[i].climates = 0x80;
00533 } else {
00534 rvi[i].railtype = railtype;
00535 }
00536 break;
00537 }
00538
00539 switch (tracktype) {
00540 case 0: rvi->railtype = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC : RAILTYPE_RAIL; break;
00541 case 1: rvi->railtype = RAILTYPE_MONO; break;
00542 case 2: rvi->railtype = RAILTYPE_MAGLEV; break;
00543 default:
00544 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
00545 break;
00546 }
00547 } break;
00548
00549 case 0x08:
00550
00551
00552 rvi->ai_passenger_only = buf->ReadByte();
00553 break;
00554
00555 case PROP_TRAIN_SPEED: {
00556 uint16 speed = buf->ReadWord();
00557 if (speed == 0xFFFF) speed = 0;
00558
00559 rvi->max_speed = speed;
00560 } break;
00561
00562 case PROP_TRAIN_POWER:
00563 rvi->power = buf->ReadWord();
00564
00565
00566 if (rvi->power != 0) {
00567 if (rvi->railveh_type == RAILVEH_WAGON) {
00568 rvi->railveh_type = RAILVEH_SINGLEHEAD;
00569 }
00570 } else {
00571 rvi->railveh_type = RAILVEH_WAGON;
00572 }
00573 break;
00574
00575 case PROP_TRAIN_RUNNING_COST_FACTOR:
00576 rvi->running_cost = buf->ReadByte();
00577 break;
00578
00579 case 0x0E:
00580 ConvertTTDBasePrice(buf->ReadDWord(), "RailVehicleChangeInfo", &rvi->running_cost_class);
00581 break;
00582
00583 case 0x12: {
00584 uint8 spriteid = buf->ReadByte();
00585
00586
00587
00588 if (spriteid < 0xFD) spriteid >>= 1;
00589
00590 rvi->image_index = spriteid;
00591 } break;
00592
00593 case 0x13: {
00594 uint8 dual = buf->ReadByte();
00595
00596 if (dual != 0) {
00597 rvi->railveh_type = RAILVEH_MULTIHEAD;
00598 } else {
00599 rvi->railveh_type = rvi->power == 0 ?
00600 RAILVEH_WAGON : RAILVEH_SINGLEHEAD;
00601 }
00602 } break;
00603
00604 case PROP_TRAIN_CARGO_CAPACITY:
00605 rvi->capacity = buf->ReadByte();
00606 break;
00607
00608 case 0x15: {
00609 uint8 ctype = buf->ReadByte();
00610
00611 if (ctype < NUM_CARGO && HasBit(_cargo_mask, ctype)) {
00612 ei->cargo_type = ctype;
00613 } else if (ctype == 0xFF) {
00614
00615 ei->cargo_type = CT_INVALID;
00616 } else {
00617 ei->cargo_type = CT_INVALID;
00618 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
00619 }
00620 } break;
00621
00622 case PROP_TRAIN_WEIGHT:
00623 SB(rvi->weight, 0, 8, buf->ReadByte());
00624 break;
00625
00626 case PROP_TRAIN_COST_FACTOR:
00627 rvi->cost_factor = buf->ReadByte();
00628 break;
00629
00630 case 0x18:
00631 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
00632 buf->ReadByte();
00633 break;
00634
00635 case 0x19: {
00636
00637
00638
00639
00640
00641
00642
00643 uint8 traction = buf->ReadByte();
00644 EngineClass engclass;
00645
00646 if (traction <= 0x07) {
00647 engclass = EC_STEAM;
00648 } else if (traction <= 0x27) {
00649 engclass = EC_DIESEL;
00650 } else if (traction <= 0x31) {
00651 engclass = EC_ELECTRIC;
00652 } else if (traction <= 0x37) {
00653 engclass = EC_MONORAIL;
00654 } else if (traction <= 0x41) {
00655 engclass = EC_MAGLEV;
00656 } else {
00657 break;
00658 }
00659
00660 if (_cur_grffile->railtype_max == 0) {
00661
00662
00663 if (rvi->railtype == RAILTYPE_RAIL && engclass >= EC_ELECTRIC) rvi->railtype = RAILTYPE_ELECTRIC;
00664 if (rvi->railtype == RAILTYPE_ELECTRIC && engclass < EC_ELECTRIC) rvi->railtype = RAILTYPE_RAIL;
00665 }
00666
00667 rvi->engclass = engclass;
00668 } break;
00669
00670 case 0x1A:
00671 AlterVehicleListOrder(e->index, buf->ReadExtended());
00672 break;
00673
00674 case 0x1B:
00675 rvi->pow_wag_power = buf->ReadWord();
00676 break;
00677
00678 case 0x1C:
00679 ei->refit_cost = buf->ReadByte();
00680 break;
00681
00682 case 0x1D:
00683 ei->refit_mask = buf->ReadDWord();
00684 _gted[e->index].refitmask_valid = true;
00685 break;
00686
00687 case 0x1E:
00688 ei->callback_mask = buf->ReadByte();
00689 break;
00690
00691 case PROP_TRAIN_TRACTIVE_EFFORT:
00692 rvi->tractive_effort = buf->ReadByte();
00693 break;
00694
00695 case 0x20:
00697 buf->ReadByte();
00698 ret = CIR_UNHANDLED;
00699 break;
00700
00701 case 0x21:
00702 rvi->shorten_factor = buf->ReadByte();
00703 break;
00704
00705 case 0x22:
00707 rvi->visual_effect = buf->ReadByte();
00708 break;
00709
00710 case 0x23:
00711 rvi->pow_wag_weight = buf->ReadByte();
00712 break;
00713
00714 case 0x24: {
00715 byte weight = buf->ReadByte();
00716
00717 if (weight > 4) {
00718 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
00719 } else {
00720 SB(rvi->weight, 8, 8, weight);
00721 }
00722 } break;
00723
00724 case PROP_TRAIN_USER_DATA:
00725 rvi->user_def_data = buf->ReadByte();
00726 break;
00727
00728 case 0x26:
00729 ei->retire_early = buf->ReadByte();
00730 break;
00731
00732 case 0x27:
00733 ei->misc_flags = buf->ReadByte();
00734 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
00735 break;
00736
00737 case 0x28:
00738 _gted[e->index].cargo_allowed = buf->ReadWord();
00739 _gted[e->index].refitmask_valid = true;
00740 break;
00741
00742 case 0x29:
00743 _gted[e->index].cargo_disallowed = buf->ReadWord();
00744 _gted[e->index].refitmask_valid = true;
00745 break;
00746
00747 case 0x2A:
00748 ei->base_intro = buf->ReadDWord();
00749 break;
00750
00751 default:
00752 ret = CommonVehicleChangeInfo(ei, prop, buf);
00753 break;
00754 }
00755 }
00756
00757 return ret;
00758 }
00759
00760 static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
00761 {
00762 ChangeInfoResult ret = CIR_SUCCESS;
00763
00764 for (int i = 0; i < numinfo; i++) {
00765 Engine *e = GetNewEngine(_cur_grffile, VEH_ROAD, engine + i);
00766 EngineInfo *ei = &e->info;
00767 RoadVehicleInfo *rvi = &e->u.road;
00768
00769 switch (prop) {
00770 case 0x08:
00771 rvi->max_speed = buf->ReadByte();
00772 break;
00773
00774 case PROP_ROADVEH_RUNNING_COST_FACTOR:
00775 rvi->running_cost = buf->ReadByte();
00776 break;
00777
00778 case 0x0A:
00779 ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
00780 break;
00781
00782 case 0x0E: {
00783 uint8 spriteid = buf->ReadByte();
00784
00785
00786 if (spriteid == 0xFF) spriteid = 0xFD;
00787
00788 if (spriteid < 0xFD) spriteid >>= 1;
00789
00790 rvi->image_index = spriteid;
00791 } break;
00792
00793 case PROP_ROADVEH_CARGO_CAPACITY:
00794 rvi->capacity = buf->ReadByte();
00795 break;
00796
00797 case 0x10: {
00798 uint8 cargo = buf->ReadByte();
00799
00800 if (cargo < NUM_CARGO && HasBit(_cargo_mask, cargo)) {
00801 ei->cargo_type = cargo;
00802 } else if (cargo == 0xFF) {
00803 ei->cargo_type = CT_INVALID;
00804 } else {
00805 ei->cargo_type = CT_INVALID;
00806 grfmsg(2, "RoadVehicleChangeInfo: Invalid cargo type %d, using first refittable", cargo);
00807 }
00808 } break;
00809
00810 case PROP_ROADVEH_COST_FACTOR:
00811 rvi->cost_factor = buf->ReadByte();
00812 break;
00813
00814 case 0x12:
00815 rvi->sfx = buf->ReadByte();
00816 break;
00817
00818 case 0x13:
00819 rvi->power = buf->ReadByte();
00820 break;
00821
00822 case 0x14:
00823 rvi->weight = buf->ReadByte();
00824 break;
00825
00826 case 0x15:
00827 _gted[e->index].rv_max_speed = buf->ReadByte();
00828 break;
00829
00830 case 0x16:
00831 ei->refit_mask = buf->ReadDWord();
00832 _gted[e->index].refitmask_valid = true;
00833 break;
00834
00835 case 0x17:
00836 ei->callback_mask = buf->ReadByte();
00837 break;
00838
00839 case 0x18:
00840 rvi->tractive_effort = buf->ReadByte();
00841 break;
00842
00843 case 0x19:
00844 rvi->air_drag = buf->ReadByte();
00845 break;
00846
00847 case 0x1A:
00848 ei->refit_cost = buf->ReadByte();
00849 break;
00850
00851 case 0x1B:
00852 ei->retire_early = buf->ReadByte();
00853 break;
00854
00855 case 0x1C:
00856 ei->misc_flags = buf->ReadByte();
00857 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
00858 break;
00859
00860 case 0x1D:
00861 _gted[e->index].cargo_allowed = buf->ReadWord();
00862 _gted[e->index].refitmask_valid = true;
00863 break;
00864
00865 case 0x1E:
00866 _gted[e->index].cargo_disallowed = buf->ReadWord();
00867 _gted[e->index].refitmask_valid = true;
00868 break;
00869
00870 case 0x1F:
00871 ei->base_intro = buf->ReadDWord();
00872 break;
00873
00874 case 0x20:
00875 AlterVehicleListOrder(e->index, buf->ReadExtended());
00876 break;
00877
00878 default:
00879 ret = CommonVehicleChangeInfo(ei, prop, buf);
00880 break;
00881 }
00882 }
00883
00884 return ret;
00885 }
00886
00887 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
00888 {
00889 ChangeInfoResult ret = CIR_SUCCESS;
00890
00891 for (int i = 0; i < numinfo; i++) {
00892 Engine *e = GetNewEngine(_cur_grffile, VEH_SHIP, engine + i);
00893 EngineInfo *ei = &e->info;
00894 ShipVehicleInfo *svi = &e->u.ship;
00895
00896 switch (prop) {
00897 case 0x08: {
00898 uint8 spriteid = buf->ReadByte();
00899
00900
00901 if (spriteid == 0xFF) spriteid = 0xFD;
00902
00903 if (spriteid < 0xFD) spriteid >>= 1;
00904
00905 svi->image_index = spriteid;
00906 } break;
00907
00908 case 0x09:
00909 svi->old_refittable = (buf->ReadByte() != 0);
00910 break;
00911
00912 case PROP_SHIP_COST_FACTOR:
00913 svi->cost_factor = buf->ReadByte();
00914 break;
00915
00916 case PROP_SHIP_SPEED:
00917 svi->max_speed = buf->ReadByte();
00918 break;
00919
00920 case 0x0C: {
00921 uint8 cargo = buf->ReadByte();
00922
00923 if (cargo < NUM_CARGO && HasBit(_cargo_mask, cargo)) {
00924 ei->cargo_type = cargo;
00925 } else if (cargo == 0xFF) {
00926 ei->cargo_type = CT_INVALID;
00927 } else {
00928 ei->cargo_type = CT_INVALID;
00929 grfmsg(2, "ShipVehicleChangeInfo: Invalid cargo type %d, using first refittable", cargo);
00930 }
00931 } break;
00932
00933 case PROP_SHIP_CARGO_CAPACITY:
00934 svi->capacity = buf->ReadWord();
00935 break;
00936
00937 case PROP_SHIP_RUNNING_COST_FACTOR:
00938 svi->running_cost = buf->ReadByte();
00939 break;
00940
00941 case 0x10:
00942 svi->sfx = buf->ReadByte();
00943 break;
00944
00945 case 0x11:
00946 ei->refit_mask = buf->ReadDWord();
00947 _gted[e->index].refitmask_valid = true;
00948 break;
00949
00950 case 0x12:
00951 ei->callback_mask = buf->ReadByte();
00952 break;
00953
00954 case 0x13:
00955 ei->refit_cost = buf->ReadByte();
00956 break;
00957
00958 case 0x14:
00959 case 0x15:
00961 buf->ReadByte();
00962 ret = CIR_UNHANDLED;
00963 break;
00964
00965 case 0x16:
00966 ei->retire_early = buf->ReadByte();
00967 break;
00968
00969 case 0x17:
00970 ei->misc_flags = buf->ReadByte();
00971 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
00972 break;
00973
00974 case 0x18:
00975 _gted[e->index].cargo_allowed = buf->ReadWord();
00976 _gted[e->index].refitmask_valid = true;
00977 break;
00978
00979 case 0x19:
00980 _gted[e->index].cargo_disallowed = buf->ReadWord();
00981 _gted[e->index].refitmask_valid = true;
00982 break;
00983
00984 case 0x1A:
00985 ei->base_intro = buf->ReadDWord();
00986 break;
00987
00988 case 0x1B:
00989 AlterVehicleListOrder(e->index, buf->ReadExtended());
00990 break;
00991
00992 default:
00993 ret = CommonVehicleChangeInfo(ei, prop, buf);
00994 break;
00995 }
00996 }
00997
00998 return ret;
00999 }
01000
01001 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
01002 {
01003 ChangeInfoResult ret = CIR_SUCCESS;
01004
01005 for (int i = 0; i < numinfo; i++) {
01006 Engine *e = GetNewEngine(_cur_grffile, VEH_AIRCRAFT, engine + i);
01007 EngineInfo *ei = &e->info;
01008 AircraftVehicleInfo *avi = &e->u.air;
01009
01010 switch (prop) {
01011 case 0x08: {
01012 uint8 spriteid = buf->ReadByte();
01013
01014
01015 if (spriteid == 0xFF) spriteid = 0xFD;
01016
01017 if (spriteid < 0xFD) spriteid >>= 1;
01018
01019 avi->image_index = spriteid;
01020 } break;
01021
01022 case 0x09:
01023 if (buf->ReadByte() == 0) {
01024 avi->subtype = AIR_HELI;
01025 } else {
01026 SB(avi->subtype, 0, 1, 1);
01027 }
01028 break;
01029
01030 case 0x0A:
01031 SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0));
01032 break;
01033
01034 case PROP_AIRCRAFT_COST_FACTOR:
01035 avi->cost_factor = buf->ReadByte();
01036 break;
01037
01038 case PROP_AIRCRAFT_SPEED:
01039 avi->max_speed = (buf->ReadByte() * 129) / 10;
01040 break;
01041
01042 case 0x0D:
01043 avi->acceleration = (buf->ReadByte() * 129) / 10;
01044 break;
01045
01046 case PROP_AIRCRAFT_RUNNING_COST_FACTOR:
01047 avi->running_cost = buf->ReadByte();
01048 break;
01049
01050 case 0x0F:
01051 avi->passenger_capacity = buf->ReadWord();
01052 break;
01053
01054 case 0x11:
01055 avi->mail_capacity = buf->ReadByte();
01056 break;
01057
01058 case 0x12:
01059 avi->sfx = buf->ReadByte();
01060 break;
01061
01062 case 0x13:
01063 ei->refit_mask = buf->ReadDWord();
01064 _gted[e->index].refitmask_valid = true;
01065 break;
01066
01067 case 0x14:
01068 ei->callback_mask = buf->ReadByte();
01069 break;
01070
01071 case 0x15:
01072 ei->refit_cost = buf->ReadByte();
01073 break;
01074
01075 case 0x16:
01076 ei->retire_early = buf->ReadByte();
01077 break;
01078
01079 case 0x17:
01080 ei->misc_flags = buf->ReadByte();
01081 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
01082 break;
01083
01084 case 0x18:
01085 _gted[e->index].cargo_allowed = buf->ReadWord();
01086 _gted[e->index].refitmask_valid = true;
01087 break;
01088
01089 case 0x19:
01090 _gted[e->index].cargo_disallowed = buf->ReadWord();
01091 _gted[e->index].refitmask_valid = true;
01092 break;
01093
01094 case 0x1A:
01095 ei->base_intro = buf->ReadDWord();
01096 break;
01097
01098 case 0x1B:
01099 AlterVehicleListOrder(e->index, buf->ReadExtended());
01100 break;
01101
01102 default:
01103 ret = CommonVehicleChangeInfo(ei, prop, buf);
01104 break;
01105 }
01106 }
01107
01108 return ret;
01109 }
01110
01111 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
01112 {
01113 ChangeInfoResult ret = CIR_SUCCESS;
01114
01115 if (stid + numinfo > MAX_STATIONS) {
01116 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, MAX_STATIONS);
01117 return CIR_INVALID_ID;
01118 }
01119
01120
01121 if (_cur_grffile->stations == NULL) _cur_grffile->stations = CallocT<StationSpec*>(MAX_STATIONS);
01122
01123 for (int i = 0; i < numinfo; i++) {
01124 StationSpec *statspec = _cur_grffile->stations[stid + i];
01125
01126
01127 if (statspec == NULL && prop != 0x08) {
01128 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
01129 return CIR_INVALID_ID;
01130 }
01131
01132 switch (prop) {
01133 case 0x08: {
01134 StationSpec **spec = &_cur_grffile->stations[stid + i];
01135
01136
01137 if (*spec == NULL) *spec = CallocT<StationSpec>(1);
01138
01139
01140 uint32 classid = buf->ReadDWord();
01141 (*spec)->sclass = AllocateStationClass(BSWAP32(classid));
01142 } break;
01143
01144 case 0x09:
01145 statspec->tiles = buf->ReadExtended();
01146 statspec->renderdata = CallocT<DrawTileSprites>(statspec->tiles);
01147 statspec->copied_renderdata = false;
01148
01149 for (uint t = 0; t < statspec->tiles; t++) {
01150 DrawTileSprites *dts = &statspec->renderdata[t];
01151 uint seq_count = 0;
01152
01153 dts->seq = NULL;
01154 dts->ground.sprite = buf->ReadWord();
01155 dts->ground.pal = buf->ReadWord();
01156 if (dts->ground.sprite == 0) continue;
01157 if (HasBit(dts->ground.pal, 15)) {
01158
01159 ClrBit(dts->ground.pal, 15);
01160 SetBit(dts->ground.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
01161 }
01162
01163 MapSpriteMappingRecolour(&dts->ground);
01164
01165 while (buf->HasData()) {
01166
01167 dts->seq = ReallocT(const_cast<DrawTileSeqStruct *>(dts->seq), ++seq_count);
01168 DrawTileSeqStruct *dtss = const_cast<DrawTileSeqStruct *>(&dts->seq[seq_count - 1]);
01169
01170 dtss->delta_x = buf->ReadByte();
01171 if ((byte) dtss->delta_x == 0x80) break;
01172 dtss->delta_y = buf->ReadByte();
01173 dtss->delta_z = buf->ReadByte();
01174 dtss->size_x = buf->ReadByte();
01175 dtss->size_y = buf->ReadByte();
01176 dtss->size_z = buf->ReadByte();
01177 dtss->image.sprite = buf->ReadWord();
01178 dtss->image.pal = buf->ReadWord();
01179
01180 if (HasBit(dtss->image.pal, 15)) {
01181 ClrBit(dtss->image.pal, 15);
01182 } else {
01183
01184 SetBit(dtss->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
01185 }
01186
01187 MapSpriteMappingRecolour(&dtss->image);
01188 }
01189 }
01190 break;
01191
01192 case 0x0A: {
01193 byte srcid = buf->ReadByte();
01194 const StationSpec *srcstatspec = _cur_grffile->stations[srcid];
01195
01196 if (srcstatspec == NULL) {
01197 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
01198 continue;
01199 }
01200
01201 statspec->tiles = srcstatspec->tiles;
01202 statspec->renderdata = srcstatspec->renderdata;
01203 statspec->copied_renderdata = true;
01204 } break;
01205
01206 case 0x0B:
01207 statspec->callback_mask = buf->ReadByte();
01208 break;
01209
01210 case 0x0C:
01211 statspec->disallowed_platforms = buf->ReadByte();
01212 break;
01213
01214 case 0x0D:
01215 statspec->disallowed_lengths = buf->ReadByte();
01216 break;
01217
01218 case 0x0E:
01219 statspec->copied_layouts = false;
01220
01221 while (buf->HasData()) {
01222 byte length = buf->ReadByte();
01223 byte number = buf->ReadByte();
01224 StationLayout layout;
01225 uint l, p;
01226
01227 if (length == 0 || number == 0) break;
01228
01229 if (length > statspec->lengths) {
01230 statspec->platforms = ReallocT(statspec->platforms, length);
01231 memset(statspec->platforms + statspec->lengths, 0, length - statspec->lengths);
01232
01233 statspec->layouts = ReallocT(statspec->layouts, length);
01234 memset(statspec->layouts + statspec->lengths, 0,
01235 (length - statspec->lengths) * sizeof(*statspec->layouts));
01236
01237 statspec->lengths = length;
01238 }
01239 l = length - 1;
01240
01241 if (number > statspec->platforms[l]) {
01242 statspec->layouts[l] = ReallocT(statspec->layouts[l], number);
01243
01244 memset(statspec->layouts[l] + statspec->platforms[l], 0,
01245 (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
01246
01247 statspec->platforms[l] = number;
01248 }
01249
01250 p = 0;
01251 layout = MallocT<byte>(length * number);
01252 try {
01253 for (l = 0; l < length; l++) {
01254 for (p = 0; p < number; p++) {
01255 layout[l * number + p] = buf->ReadByte();
01256 }
01257 }
01258 } catch (...) {
01259 free(layout);
01260 throw;
01261 }
01262
01263 l--;
01264 p--;
01265 free(statspec->layouts[l][p]);
01266 statspec->layouts[l][p] = layout;
01267 }
01268 break;
01269
01270 case 0x0F: {
01271 byte srcid = buf->ReadByte();
01272 const StationSpec *srcstatspec = _cur_grffile->stations[srcid];
01273
01274 if (srcstatspec == NULL) {
01275 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
01276 continue;
01277 }
01278
01279 statspec->lengths = srcstatspec->lengths;
01280 statspec->platforms = srcstatspec->platforms;
01281 statspec->layouts = srcstatspec->layouts;
01282 statspec->copied_layouts = true;
01283 } break;
01284
01285 case 0x10:
01286 statspec->cargo_threshold = buf->ReadWord();
01287 break;
01288
01289 case 0x11:
01290 statspec->pylons = buf->ReadByte();
01291 break;
01292
01293 case 0x12:
01294 statspec->cargo_triggers = buf->ReadDWord();
01295 break;
01296
01297 case 0x13:
01298 statspec->flags = buf->ReadByte();
01299 break;
01300
01301 case 0x14:
01302 statspec->wires = buf->ReadByte();
01303 break;
01304
01305 case 0x15:
01306 statspec->blocked = buf->ReadByte();
01307 break;
01308
01309 case 0x16:
01310 statspec->anim_frames = buf->ReadByte();
01311 statspec->anim_status = buf->ReadByte();
01312 break;
01313
01314 case 0x17:
01315 statspec->anim_speed = buf->ReadByte();
01316 break;
01317
01318 case 0x18:
01319 statspec->anim_triggers = buf->ReadWord();
01320 break;
01321
01322 default:
01323 ret = CIR_UNKNOWN;
01324 break;
01325 }
01326 }
01327
01328 return ret;
01329 }
01330
01331 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
01332 {
01333 ChangeInfoResult ret = CIR_SUCCESS;
01334
01335 if (id + numinfo > CF_END) {
01336 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoreing", id + numinfo, CF_END);
01337 return CIR_INVALID_ID;
01338 }
01339
01340 for (int i = 0; i < numinfo; i++) {
01341 WaterFeature *wf = &_water_feature[id + i];
01342
01343 switch (prop) {
01344 case 0x08:
01345 wf->callback_mask = buf->ReadByte();
01346 break;
01347
01348 case 0x09:
01349 wf->flags = buf->ReadByte();
01350 break;
01351
01352 default:
01353 ret = CIR_UNKNOWN;
01354 break;
01355 }
01356 }
01357
01358 return ret;
01359 }
01360
01361 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
01362 {
01363 ChangeInfoResult ret = CIR_SUCCESS;
01364
01365 if (brid + numinfo > MAX_BRIDGES) {
01366 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
01367 return CIR_INVALID_ID;
01368 }
01369
01370 for (int i = 0; i < numinfo; i++) {
01371 BridgeSpec *bridge = &_bridge[brid + i];
01372
01373 switch (prop) {
01374 case 0x08: {
01375
01376 byte year = buf->ReadByte();
01377 bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
01378 break;
01379 }
01380
01381 case 0x09:
01382 bridge->min_length = buf->ReadByte();
01383 break;
01384
01385 case 0x0A:
01386 bridge->max_length = buf->ReadByte();
01387 break;
01388
01389 case 0x0B:
01390 bridge->price = buf->ReadByte();
01391 break;
01392
01393 case 0x0C:
01394 bridge->speed = buf->ReadWord();
01395 break;
01396
01397 case 0x0D: {
01398 byte tableid = buf->ReadByte();
01399 byte numtables = buf->ReadByte();
01400
01401 if (bridge->sprite_table == NULL) {
01402
01403 bridge->sprite_table = CallocT<PalSpriteID*>(7);
01404 }
01405
01406 for (; numtables-- != 0; tableid++) {
01407 if (tableid >= 7) {
01408 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
01409 for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
01410 continue;
01411 }
01412
01413 if (bridge->sprite_table[tableid] == NULL) {
01414 bridge->sprite_table[tableid] = MallocT<PalSpriteID>(32);
01415 }
01416
01417 for (byte sprite = 0; sprite < 32; sprite++) {
01418 SpriteID image = buf->ReadWord();
01419 PaletteID pal = buf->ReadWord();
01420
01421 bridge->sprite_table[tableid][sprite].sprite = image;
01422 bridge->sprite_table[tableid][sprite].pal = pal;
01423
01424 MapSpriteMappingRecolour(&bridge->sprite_table[tableid][sprite]);
01425 }
01426 }
01427 } break;
01428
01429 case 0x0E:
01430 bridge->flags = buf->ReadByte();
01431 break;
01432
01433 case 0x0F:
01434 bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
01435 break;
01436
01437 case 0x10: {
01438 StringID newone = GetGRFStringID(_cur_grffile->grfid, buf->ReadWord());
01439 if (newone != STR_UNDEFINED) bridge->material = newone;
01440 } break;
01441
01442 case 0x11:
01443 case 0x12: {
01444 StringID newone = GetGRFStringID(_cur_grffile->grfid, buf->ReadWord());
01445 if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
01446 } break;
01447
01448 case 0x13:
01449 bridge->price = buf->ReadWord();
01450 break;
01451
01452 default:
01453 ret = CIR_UNKNOWN;
01454 break;
01455 }
01456 }
01457
01458 return ret;
01459 }
01460
01461 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
01462 {
01463 ChangeInfoResult ret = CIR_SUCCESS;
01464
01465 if (hid + numinfo > HOUSE_MAX) {
01466 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, HOUSE_MAX);
01467 return CIR_INVALID_ID;
01468 }
01469
01470
01471 if (_cur_grffile->housespec == NULL) {
01472 _cur_grffile->housespec = CallocT<HouseSpec*>(HOUSE_MAX);
01473 }
01474
01475 for (int i = 0; i < numinfo; i++) {
01476 HouseSpec *housespec = _cur_grffile->housespec[hid + i];
01477
01478 if (prop != 0x08 && housespec == NULL) {
01479 grfmsg(2, "TownHouseChangeInfo: Attempt to modify undefined house %u. Ignoring.", hid + i);
01480 return CIR_INVALID_ID;
01481 }
01482
01483 switch (prop) {
01484 case 0x08: {
01485 HouseSpec **house = &_cur_grffile->housespec[hid + i];
01486 byte subs_id = buf->ReadByte();
01487
01488 if (subs_id == 0xFF) {
01489
01490
01491 HouseSpec::Get(hid + i)->enabled = false;
01492 continue;
01493 } else if (subs_id >= NEW_HOUSE_OFFSET) {
01494
01495 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
01496 continue;
01497 }
01498
01499
01500 if (*house == NULL) *house = CallocT<HouseSpec>(1);
01501
01502 housespec = *house;
01503
01504 MemCpyT(housespec, HouseSpec::Get(subs_id));
01505
01506 housespec->enabled = true;
01507 housespec->local_id = hid + i;
01508 housespec->substitute_id = subs_id;
01509 housespec->grffile = _cur_grffile;
01510 housespec->random_colour[0] = 0x04;
01511 housespec->random_colour[1] = 0x08;
01512 housespec->random_colour[2] = 0x0C;
01513 housespec->random_colour[3] = 0x06;
01514
01515
01516
01517
01518
01519 if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
01520 housespec->cargo_acceptance[2] = 0;
01521 }
01522
01528 if (housespec->min_year < 1930) housespec->min_year = 1930;
01529
01530 _loaded_newgrf_features.has_newhouses = true;
01531 } break;
01532
01533 case 0x09:
01534 housespec->building_flags = (BuildingFlags)buf->ReadByte();
01535 break;
01536
01537 case 0x0A: {
01538 uint16 years = buf->ReadWord();
01539 housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
01540 housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
01541 } break;
01542
01543 case 0x0B:
01544 housespec->population = buf->ReadByte();
01545 break;
01546
01547 case 0x0C:
01548 housespec->mail_generation = buf->ReadByte();
01549 break;
01550
01551 case 0x0D:
01552 case 0x0E:
01553 housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
01554 break;
01555
01556 case 0x0F: {
01557 int8 goods = buf->ReadByte();
01558
01559
01560
01561 CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
01562 ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
01563
01564
01565 if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
01566
01567 housespec->accepts_cargo[2] = cid;
01568 housespec->cargo_acceptance[2] = abs(goods);
01569 } break;
01570
01571 case 0x10:
01572 housespec->remove_rating_decrease = buf->ReadWord();
01573 break;
01574
01575 case 0x11:
01576 housespec->removal_cost = buf->ReadByte();
01577 break;
01578
01579 case 0x12:
01580 housespec->building_name = buf->ReadWord();
01581 _string_to_grf_mapping[&housespec->building_name] = _cur_grffile->grfid;
01582 break;
01583
01584 case 0x13:
01585 housespec->building_availability = (HouseZones)buf->ReadWord();
01586 break;
01587
01588 case 0x14:
01589 housespec->callback_mask |= buf->ReadByte();
01590 break;
01591
01592 case 0x15: {
01593 byte override = buf->ReadByte();
01594
01595
01596 if (override >= NEW_HOUSE_OFFSET) {
01597 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
01598 continue;
01599 }
01600
01601 _house_mngr.Add(hid + i, _cur_grffile->grfid, override);
01602 } break;
01603
01604 case 0x16:
01605 housespec->processing_time = buf->ReadByte();
01606 break;
01607
01608 case 0x17:
01609 for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
01610 break;
01611
01612 case 0x18:
01613 housespec->probability = buf->ReadByte();
01614 break;
01615
01616 case 0x19:
01617 housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
01618 break;
01619
01620 case 0x1A:
01621 housespec->animation_frames = buf->ReadByte();
01622 break;
01623
01624 case 0x1B:
01625 housespec->animation_speed = Clamp(buf->ReadByte(), 2, 16);
01626 break;
01627
01628 case 0x1C:
01629 housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur_grffile->grfid);
01630 break;
01631
01632 case 0x1D:
01633 housespec->callback_mask |= (buf->ReadByte() << 8);
01634 break;
01635
01636 case 0x1E: {
01637 uint32 cargotypes = buf->ReadDWord();
01638
01639
01640 if (cargotypes == 0xFFFFFFFF) break;
01641
01642 for (uint j = 0; j < 3; j++) {
01643
01644 uint8 cargo_part = GB(cargotypes, 8 * j, 8);
01645 CargoID cargo = GetCargoTranslation(cargo_part, _cur_grffile);
01646
01647 if (cargo == CT_INVALID) {
01648
01649 housespec->cargo_acceptance[j] = 0;
01650 } else {
01651 housespec->accepts_cargo[j] = cargo;
01652 }
01653 }
01654 } break;
01655
01656 case 0x1F:
01657 housespec->minimum_life = buf->ReadByte();
01658 break;
01659
01660 case 0x20: {
01661 byte count = buf->ReadByte();
01662 for (byte j = 0; j < count; j++) buf->ReadByte();
01663 ret = CIR_UNHANDLED;
01664 } break;
01665
01666 case 0x21:
01667 housespec->min_year = buf->ReadWord();
01668 break;
01669
01670 case 0x22:
01671 housespec->max_year = buf->ReadWord();
01672 break;
01673
01674 default:
01675 ret = CIR_UNKNOWN;
01676 break;
01677 }
01678 }
01679
01680 return ret;
01681 }
01682
01683 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
01684 {
01685 ChangeInfoResult ret = CIR_SUCCESS;
01686
01687 for (int i = 0; i < numinfo; i++) {
01688 switch (prop) {
01689 case 0x08: {
01690 int factor = buf->ReadByte();
01691 uint price = gvid + i;
01692
01693 if (price < PR_END) {
01694 _cur_grffile->price_base_multipliers[price] = min<int>(factor - 8, MAX_PRICE_MODIFIER);
01695 } else {
01696 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
01697 }
01698 } break;
01699
01700 case 0x09:
01701
01702
01703 buf->Skip(4);
01704 break;
01705
01706 case 0x0A: {
01707 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01708 StringID newone = GetGRFStringID(_cur_grffile->grfid, buf->ReadWord());
01709
01710 if ((newone != STR_UNDEFINED) && (curidx < NUM_CURRENCY)) {
01711 _currency_specs[curidx].name = newone;
01712 }
01713 } break;
01714
01715 case 0x0B: {
01716 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01717 uint32 rate = buf->ReadDWord();
01718
01719 if (curidx < NUM_CURRENCY) {
01720
01721
01722
01723 _currency_specs[curidx].rate = rate / 1000;
01724 } else {
01725 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
01726 }
01727 } break;
01728
01729 case 0x0C: {
01730 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01731 uint16 options = buf->ReadWord();
01732
01733 if (curidx < NUM_CURRENCY) {
01734 _currency_specs[curidx].separator[0] = GB(options, 0, 8);
01735 _currency_specs[curidx].separator[1] = '\0';
01736
01737
01738 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
01739 } else {
01740 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
01741 }
01742 } break;
01743
01744 case 0x0D: {
01745 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01746 uint32 tempfix = buf->ReadDWord();
01747
01748 if (curidx < NUM_CURRENCY) {
01749 memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
01750 _currency_specs[curidx].prefix[4] = 0;
01751 } else {
01752 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
01753 }
01754 } break;
01755
01756 case 0x0E: {
01757 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01758 uint32 tempfix = buf->ReadDWord();
01759
01760 if (curidx < NUM_CURRENCY) {
01761 memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
01762 _currency_specs[curidx].suffix[4] = 0;
01763 } else {
01764 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
01765 }
01766 } break;
01767
01768 case 0x0F: {
01769 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01770 Year year_euro = buf->ReadWord();
01771
01772 if (curidx < NUM_CURRENCY) {
01773 _currency_specs[curidx].to_euro = year_euro;
01774 } else {
01775 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
01776 }
01777 } break;
01778
01779 case 0x10:
01780 if (numinfo > 1 || IsSnowLineSet()) {
01781 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
01782 } else if (buf->Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
01783 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
01784 } else {
01785 byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
01786
01787 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
01788 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
01789 table[i][j] = buf->ReadByte();
01790 }
01791 }
01792 SetSnowLine(table);
01793 }
01794 break;
01795
01796 case 0x11:
01797
01798
01799 buf->Skip(8);
01800 break;
01801
01802 case 0x12:
01803
01804
01805 buf->Skip(4);
01806 break;
01807
01808 default:
01809 ret = CIR_UNKNOWN;
01810 break;
01811 }
01812 }
01813
01814 return ret;
01815 }
01816
01817 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
01818 {
01819 ChangeInfoResult ret = CIR_SUCCESS;
01820
01821 for (int i = 0; i < numinfo; i++) {
01822 switch (prop) {
01823 case 0x08:
01824 buf->ReadByte();
01825 break;
01826
01827 case 0x09: {
01828 if (i == 0) {
01829 if (gvid != 0) {
01830 grfmsg(1, "ReserveChangeInfo: Cargo translation table must start at zero");
01831 return CIR_INVALID_ID;
01832 }
01833
01834 free(_cur_grffile->cargo_list);
01835 _cur_grffile->cargo_max = numinfo;
01836 _cur_grffile->cargo_list = MallocT<CargoLabel>(numinfo);
01837 }
01838
01839 CargoLabel cl = buf->ReadDWord();
01840 _cur_grffile->cargo_list[i] = BSWAP32(cl);
01841 break;
01842 }
01843
01844 case 0x0A:
01845 case 0x0C:
01846 case 0x0F:
01847 buf->ReadWord();
01848 break;
01849
01850 case 0x0B:
01851 case 0x0D:
01852 case 0x0E:
01853 buf->ReadDWord();
01854 break;
01855
01856 case 0x10:
01857 buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
01858 break;
01859
01860 case 0x11: {
01861 uint32 s = buf->ReadDWord();
01862 uint32 t = buf->ReadDWord();
01863 SetNewGRFOverride(s, t);
01864 break;
01865 }
01866
01867 case 0x12: {
01868 if (i == 0) {
01869 if (gvid != 0) {
01870 grfmsg(1, "ReserveChangeInfo: Rail type translation table must start at zero");
01871 return CIR_INVALID_ID;
01872 }
01873
01874 free(_cur_grffile->railtype_list);
01875 _cur_grffile->railtype_max = numinfo;
01876 _cur_grffile->railtype_list = MallocT<RailTypeLabel>(numinfo);
01877 }
01878
01879 RailTypeLabel rtl = buf->ReadDWord();
01880 _cur_grffile->railtype_list[i] = BSWAP32(rtl);
01881 break;
01882 }
01883
01884 default:
01885 ret = CIR_UNKNOWN;
01886 break;
01887 }
01888 }
01889
01890 return ret;
01891 }
01892
01893
01894 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
01895 {
01896 ChangeInfoResult ret = CIR_SUCCESS;
01897
01898 if (cid + numinfo > NUM_CARGO) {
01899 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
01900 return CIR_INVALID_ID;
01901 }
01902
01903 for (int i = 0; i < numinfo; i++) {
01904 CargoSpec *cs = CargoSpec::Get(cid + i);
01905
01906 switch (prop) {
01907 case 0x08:
01908 cs->bitnum = buf->ReadByte();
01909 if (cs->IsValid()) {
01910 cs->grffile = _cur_grffile;
01911 SetBit(_cargo_mask, cid + i);
01912 } else {
01913 ClrBit(_cargo_mask, cid + i);
01914 }
01915 break;
01916
01917 case 0x09:
01918 cs->name = buf->ReadWord();
01919 _string_to_grf_mapping[&cs->name] = _cur_grffile->grfid;
01920 break;
01921
01922 case 0x0A:
01923 cs->name_single = buf->ReadWord();
01924 _string_to_grf_mapping[&cs->name_single] = _cur_grffile->grfid;
01925 break;
01926
01927 case 0x0B:
01928
01929
01930 cs->units_volume = buf->ReadWord();
01931 _string_to_grf_mapping[&cs->units_volume] = _cur_grffile->grfid;
01932 break;
01933
01934 case 0x0C:
01935 cs->quantifier = buf->ReadWord();
01936 _string_to_grf_mapping[&cs->quantifier] = _cur_grffile->grfid;
01937 break;
01938
01939 case 0x0D:
01940 cs->abbrev = buf->ReadWord();
01941 _string_to_grf_mapping[&cs->abbrev] = _cur_grffile->grfid;
01942 break;
01943
01944 case 0x0E:
01945 cs->sprite = buf->ReadWord();
01946 break;
01947
01948 case 0x0F:
01949 cs->weight = buf->ReadByte();
01950 break;
01951
01952 case 0x10:
01953 cs->transit_days[0] = buf->ReadByte();
01954 break;
01955
01956 case 0x11:
01957 cs->transit_days[1] = buf->ReadByte();
01958 break;
01959
01960 case 0x12:
01961 cs->initial_payment = buf->ReadDWord();
01962 break;
01963
01964 case 0x13:
01965 cs->rating_colour = MapDOSColour(buf->ReadByte());
01966 break;
01967
01968 case 0x14:
01969 cs->legend_colour = MapDOSColour(buf->ReadByte());
01970 break;
01971
01972 case 0x15:
01973 cs->is_freight = (buf->ReadByte() != 0);
01974 break;
01975
01976 case 0x16:
01977 cs->classes = buf->ReadWord();
01978 break;
01979
01980 case 0x17:
01981 cs->label = buf->ReadDWord();
01982 cs->label = BSWAP32(cs->label);
01983 break;
01984
01985 case 0x18: {
01986 uint8 substitute_type = buf->ReadByte();
01987
01988 switch (substitute_type) {
01989 case 0x00: cs->town_effect = TE_PASSENGERS; break;
01990 case 0x02: cs->town_effect = TE_MAIL; break;
01991 case 0x05: cs->town_effect = TE_GOODS; break;
01992 case 0x09: cs->town_effect = TE_WATER; break;
01993 case 0x0B: cs->town_effect = TE_FOOD; break;
01994 default:
01995 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
01996 case 0xFF: cs->town_effect = TE_NONE; break;
01997 }
01998 } break;
01999
02000 case 0x19:
02001 cs->multipliertowngrowth = buf->ReadWord();
02002 break;
02003
02004 case 0x1A:
02005 cs->callback_mask = buf->ReadByte();
02006 break;
02007
02008 default:
02009 ret = CIR_UNKNOWN;
02010 break;
02011 }
02012 }
02013
02014 return ret;
02015 }
02016
02017
02018 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
02019 {
02020 ChangeInfoResult ret = CIR_SUCCESS;
02021
02022 if (_cur_grffile->sound_offset == 0) {
02023 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
02024 return CIR_INVALID_ID;
02025 }
02026
02027 for (int i = 0; i < numinfo; i++) {
02028 SoundID sound = sid + i + _cur_grffile->sound_offset - ORIGINAL_SAMPLE_COUNT;
02029
02030 if (sound >= GetNumSounds()) {
02031 grfmsg(1, "SoundEffectChangeInfo: Sound %d not defined (max %d)", sound, GetNumSounds());
02032 return CIR_INVALID_ID;
02033 }
02034
02035 switch (prop) {
02036 case 0x08:
02037 GetSound(sound)->volume = buf->ReadByte();
02038 break;
02039
02040 case 0x09:
02041 GetSound(sound)->priority = buf->ReadByte();
02042 break;
02043
02044 case 0x0A: {
02045 SoundID orig_sound = buf->ReadByte();
02046
02047 if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
02048 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
02049 } else {
02050 SoundEntry *new_sound = GetSound(sound);
02051 SoundEntry *old_sound = GetSound(orig_sound);
02052
02053
02054 *old_sound = *new_sound;
02055 }
02056 } break;
02057
02058 default:
02059 ret = CIR_UNKNOWN;
02060 break;
02061 }
02062 }
02063
02064 return ret;
02065 }
02066
02067 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
02068 {
02069 ChangeInfoResult ret = CIR_SUCCESS;
02070
02071 if (indtid + numinfo > NUM_INDUSTRYTILES) {
02072 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES);
02073 return CIR_INVALID_ID;
02074 }
02075
02076
02077 if (_cur_grffile->indtspec == NULL) {
02078 _cur_grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES);
02079 }
02080
02081 for (int i = 0; i < numinfo; i++) {
02082 IndustryTileSpec *tsp = _cur_grffile->indtspec[indtid + i];
02083
02084 if (prop != 0x08 && tsp == NULL) {
02085 grfmsg(2, "IndustryTilesChangeInfo: Attempt to modify undefined industry tile %u. Ignoring.", indtid + i);
02086 return CIR_INVALID_ID;
02087 }
02088
02089 switch (prop) {
02090 case 0x08: {
02091 IndustryTileSpec **tilespec = &_cur_grffile->indtspec[indtid + i];
02092 byte subs_id = buf->ReadByte();
02093
02094 if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
02095
02096 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
02097 continue;
02098 }
02099
02100
02101 if (*tilespec == NULL) {
02102 int tempid;
02103 *tilespec = CallocT<IndustryTileSpec>(1);
02104 tsp = *tilespec;
02105
02106 memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
02107 tsp->enabled = true;
02108
02109
02110
02111
02112 tsp->anim_production = INDUSTRYTILE_NOANIM;
02113 tsp->anim_next = INDUSTRYTILE_NOANIM;
02114
02115 tsp->grf_prop.local_id = indtid + i;
02116 tsp->grf_prop.subst_id = subs_id;
02117 tsp->grf_prop.grffile = _cur_grffile;
02118 tempid = _industile_mngr.AddEntityID(indtid + i, _cur_grffile->grfid, subs_id);
02119 }
02120 } break;
02121
02122 case 0x09: {
02123 byte ovrid = buf->ReadByte();
02124
02125
02126 if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
02127 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
02128 continue;
02129 }
02130
02131 _industile_mngr.Add(indtid + i, _cur_grffile->grfid, ovrid);
02132 } break;
02133
02134 case 0x0A:
02135 case 0x0B:
02136 case 0x0C: {
02137 uint16 acctp = buf->ReadWord();
02138 tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur_grffile);
02139 tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
02140 } break;
02141
02142 case 0x0D:
02143 tsp->slopes_refused = (Slope)buf->ReadByte();
02144 break;
02145
02146 case 0x0E:
02147 tsp->callback_mask = buf->ReadByte();
02148 break;
02149
02150 case 0x0F:
02151 tsp->animation_info = buf->ReadWord();
02152 break;
02153
02154 case 0x10:
02155 tsp->animation_speed = buf->ReadByte();
02156 break;
02157
02158 case 0x11:
02159 tsp->animation_triggers = buf->ReadByte();
02160 break;
02161
02162 case 0x12:
02163 tsp->animation_special_flags = buf->ReadByte();
02164 break;
02165
02166 default:
02167 ret = CIR_UNKNOWN;
02168 break;
02169 }
02170 }
02171
02172 return ret;
02173 }
02174
02181 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
02182 {
02183 for (int i = 0; i < size - 1; i++) {
02184 for (int j = i + 1; j < size; j++) {
02185 if (layout[i].ti.x == layout[j].ti.x &&
02186 layout[i].ti.y == layout[j].ti.y) {
02187 return false;
02188 }
02189 }
02190 }
02191 return true;
02192 }
02193
02194 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
02195 {
02196 ChangeInfoResult ret = CIR_SUCCESS;
02197
02198 if (indid + numinfo > NUM_INDUSTRYTYPES) {
02199 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES);
02200 return CIR_INVALID_ID;
02201 }
02202
02203 grfmsg(1, "IndustriesChangeInfo: newid %u", indid);
02204
02205
02206 if (_cur_grffile->industryspec == NULL) {
02207 _cur_grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES);
02208 }
02209
02210 for (int i = 0; i < numinfo; i++) {
02211 IndustrySpec *indsp = _cur_grffile->industryspec[indid + i];
02212
02213 if (prop != 0x08 && indsp == NULL) {
02214 grfmsg(2, "IndustriesChangeInfo: Attempt to modify undefined industry %u. Ignoring.", indid + i);
02215 return CIR_INVALID_ID;
02216 }
02217
02218 switch (prop) {
02219 case 0x08: {
02220 IndustrySpec **indspec = &_cur_grffile->industryspec[indid + i];
02221 byte subs_id = buf->ReadByte();
02222
02223 if (subs_id == 0xFF) {
02224
02225
02226 _industry_specs[indid + i].enabled = false;
02227 continue;
02228 } else if (subs_id >= NEW_INDUSTRYOFFSET) {
02229
02230 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
02231 continue;
02232 }
02233
02234
02235
02236
02237 if (*indspec == NULL) {
02238 *indspec = CallocT<IndustrySpec>(1);
02239 indsp = *indspec;
02240
02241 memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id]));
02242 indsp->enabled = true;
02243 indsp->grf_prop.local_id = indid + i;
02244 indsp->grf_prop.subst_id = subs_id;
02245 indsp->grf_prop.grffile = _cur_grffile;
02246
02247
02248 indsp->check_proc = CHECK_NOTHING;
02249 }
02250 } break;
02251
02252 case 0x09: {
02253 byte ovrid = buf->ReadByte();
02254
02255
02256 if (ovrid >= NEW_INDUSTRYOFFSET) {
02257 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
02258 continue;
02259 }
02260 indsp->grf_prop.override = ovrid;
02261 _industry_mngr.Add(indid + i, _cur_grffile->grfid, ovrid);
02262 } break;
02263
02264 case 0x0A: {
02265 indsp->num_table = buf->ReadByte();
02266
02267
02268
02269
02270
02271 uint32 def_num_tiles = buf->ReadDWord() / 3 + 1;
02272 IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(indsp->num_table);
02273 IndustryTileTable *itt = CallocT<IndustryTileTable>(def_num_tiles);
02274 uint size;
02275 const IndustryTileTable *copy_from;
02276
02277 try {
02278 for (byte j = 0; j < indsp->num_table; j++) {
02279 for (uint k = 0;; k++) {
02280 if (k >= def_num_tiles) {
02281 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
02282
02283 def_num_tiles *= 2;
02284 itt = ReallocT<IndustryTileTable>(itt, def_num_tiles);
02285 }
02286
02287 itt[k].ti.x = buf->ReadByte();
02288
02289 if (itt[k].ti.x == 0xFE && k == 0) {
02290
02291 IndustryType type = buf->ReadByte();
02292 byte laynbr = buf->ReadByte();
02293
02294 copy_from = _origin_industry_specs[type].table[laynbr];
02295 for (size = 1;; size++) {
02296 if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break;
02297 }
02298 break;
02299 }
02300
02301 itt[k].ti.y = buf->ReadByte();
02302
02303 if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
02304
02305
02306 itt[k].ti.x = -0x80;
02307 itt[k].ti.y = 0;
02308 itt[k].gfx = 0;
02309
02310 size = k + 1;
02311 copy_from = itt;
02312 break;
02313 }
02314
02315 itt[k].gfx = buf->ReadByte();
02316
02317 if (itt[k].gfx == 0xFE) {
02318
02319 int local_tile_id = buf->ReadWord();
02320
02321
02322 int tempid = _industile_mngr.GetID(local_tile_id, _cur_grffile->grfid);
02323
02324 if (tempid == INVALID_INDUSTRYTILE) {
02325 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
02326 } else {
02327
02328 itt[k].gfx = tempid;
02329 size = k + 1;
02330 copy_from = itt;
02331 }
02332 } else if (itt[k].gfx == 0xFF) {
02333 itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
02334 itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
02335 }
02336 }
02337
02338 if (!ValidateIndustryLayout(copy_from, size)) {
02339
02340 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
02341 indsp->num_table--;
02342 j--;
02343 } else {
02344 tile_table[j] = CallocT<IndustryTileTable>(size);
02345 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
02346 }
02347 }
02348 } catch (...) {
02349 for (int i = 0; i < indsp->num_table; i++) {
02350 free(tile_table[i]);
02351 }
02352 free(tile_table);
02353 free(itt);
02354 throw;
02355 }
02356
02357
02358 indsp->table = tile_table;
02359 SetBit(indsp->cleanup_flag, 1);
02360 free(itt);
02361 } break;
02362
02363 case 0x0B:
02364 indsp->life_type = (IndustryLifeType)buf->ReadByte();
02365 break;
02366
02367 case 0x0C:
02368 indsp->closure_text = buf->ReadWord();
02369 _string_to_grf_mapping[&indsp->closure_text] = _cur_grffile->grfid;
02370 break;
02371
02372 case 0x0D:
02373 indsp->production_up_text = buf->ReadWord();
02374 _string_to_grf_mapping[&indsp->production_up_text] = _cur_grffile->grfid;
02375 break;
02376
02377 case 0x0E:
02378 indsp->production_down_text = buf->ReadWord();
02379 _string_to_grf_mapping[&indsp->production_down_text] = _cur_grffile->grfid;
02380 break;
02381
02382 case 0x0F:
02383 indsp->cost_multiplier = buf->ReadByte();
02384 break;
02385
02386 case 0x10:
02387 for (byte j = 0; j < 2; j++) {
02388 indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur_grffile);
02389 }
02390 break;
02391
02392 case 0x11:
02393 for (byte j = 0; j < 3; j++) {
02394 indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur_grffile);
02395 }
02396 buf->ReadByte();
02397 break;
02398
02399 case 0x12:
02400 case 0x13:
02401 indsp->production_rate[prop - 0x12] = buf->ReadByte();
02402 break;
02403
02404 case 0x14:
02405 indsp->minimal_cargo = buf->ReadByte();
02406 break;
02407
02408 case 0x15: {
02409 indsp->number_of_sounds = buf->ReadByte();
02410 uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
02411
02412 try {
02413 for (uint8 j = 0; j < indsp->number_of_sounds; j++) {
02414 sounds[j] = buf->ReadByte();
02415 }
02416 } catch (...) {
02417 free(sounds);
02418 throw;
02419 }
02420
02421 indsp->random_sounds = sounds;
02422 SetBit(indsp->cleanup_flag, 0);
02423 } break;
02424
02425 case 0x16:
02426 for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
02427 break;
02428
02429 case 0x17:
02430 indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
02431 break;
02432
02433 case 0x18:
02434 indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
02435 break;
02436
02437 case 0x19:
02438 indsp->map_colour = MapDOSColour(buf->ReadByte());
02439 break;
02440
02441 case 0x1A:
02442 indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
02443 break;
02444
02445 case 0x1B:
02446 indsp->new_industry_text = buf->ReadWord();
02447 _string_to_grf_mapping[&indsp->new_industry_text] = _cur_grffile->grfid;
02448 break;
02449
02450 case 0x1C:
02451 case 0x1D:
02452 case 0x1E: {
02453 uint32 multiples = buf->ReadDWord();
02454 indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
02455 indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
02456 } break;
02457
02458 case 0x1F:
02459 indsp->name = buf->ReadWord();
02460 _string_to_grf_mapping[&indsp->name] = _cur_grffile->grfid;
02461 break;
02462
02463 case 0x20:
02464 indsp->prospecting_chance = buf->ReadDWord();
02465 break;
02466
02467 case 0x21:
02468 case 0x22: {
02469 byte aflag = buf->ReadByte();
02470 SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
02471 } break;
02472
02473 case 0x23:
02474 indsp->removal_cost_multiplier = buf->ReadDWord();
02475 break;
02476
02477 case 0x24:
02478 indsp->station_name = buf->ReadWord();
02479 _string_to_grf_mapping[&indsp->station_name] = _cur_grffile->grfid;
02480 break;
02481
02482 default:
02483 ret = CIR_UNKNOWN;
02484 break;
02485 }
02486 }
02487
02488 return ret;
02489 }
02490
02491 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
02492 {
02493 ChangeInfoResult ret = CIR_SUCCESS;
02494
02495 extern RailtypeInfo _railtypes[RAILTYPE_END];
02496
02497 if (id + numinfo > RAILTYPE_END) {
02498 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
02499 return CIR_INVALID_ID;
02500 }
02501
02502 for (int i = 0; i < numinfo; i++) {
02503 RailType rt = _cur_grffile->railtype_map[id + i];
02504 if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
02505
02506 RailtypeInfo *rti = &_railtypes[rt];
02507
02508 switch (prop) {
02509 case 0x08:
02510
02511 buf->ReadDWord();
02512 break;
02513
02514 case 0x09:
02515 rti->strings.toolbar_caption = buf->ReadWord();
02516 _string_to_grf_mapping[&rti->strings.toolbar_caption] = _cur_grffile->grfid;
02517 break;
02518
02519 case 0x0A:
02520 rti->strings.menu_text = buf->ReadWord();
02521 _string_to_grf_mapping[&rti->strings.menu_text] = _cur_grffile->grfid;
02522 break;
02523
02524 case 0x0B:
02525 rti->strings.build_caption = buf->ReadWord();
02526 _string_to_grf_mapping[&rti->strings.build_caption] = _cur_grffile->grfid;
02527 break;
02528
02529 case 0x0C:
02530 rti->strings.replace_text = buf->ReadWord();
02531 _string_to_grf_mapping[&rti->strings.replace_text] = _cur_grffile->grfid;
02532 break;
02533
02534 case 0x0D:
02535 rti->strings.new_loco = buf->ReadWord();
02536 _string_to_grf_mapping[&rti->strings.new_loco] = _cur_grffile->grfid;
02537 break;
02538
02539 case 0x0E:
02540 case 0x0F:
02541 {
02542
02543
02544
02545 int n = buf->ReadByte();
02546 for (int j = 0; j != n; j++) {
02547 RailTypeLabel label = buf->ReadDWord();
02548 RailType rt = GetRailTypeByLabel(BSWAP32(label));
02549 if (rt != INVALID_RAILTYPE) {
02550 if (prop == 0x0E) {
02551 SetBit(rti->compatible_railtypes, rt);
02552 } else {
02553 SetBit(rti->powered_railtypes, rt);
02554 }
02555 }
02556 }
02557 break;
02558 }
02559
02560 case 0x10:
02561 rti->flags = (RailTypeFlags)buf->ReadByte();
02562 break;
02563
02564 case 0x11:
02565 rti->curve_speed = buf->ReadByte();
02566 break;
02567
02568 case 0x12:
02569 rti->total_offset = Clamp(buf->ReadByte(), 0, 2) * 88;
02570 break;
02571
02572 case 0x13:
02573 rti->cost_multiplier = buf->ReadByte();
02574 break;
02575
02576 case 0x14:
02577 rti->max_speed = buf->ReadWord();
02578 break;
02579
02580 case 0x15:
02581 rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
02582 break;
02583
02584 default:
02585 ret = CIR_UNKNOWN;
02586 break;
02587 }
02588 }
02589
02590 return ret;
02591 }
02592
02593 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
02594 {
02595 ChangeInfoResult ret = CIR_SUCCESS;
02596
02597 if (id + numinfo > RAILTYPE_END) {
02598 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
02599 return CIR_INVALID_ID;
02600 }
02601
02602 for (int i = 0; i < numinfo; i++) {
02603 switch (prop) {
02604 case 0x08:
02605 {
02606 RailTypeLabel rtl = buf->ReadDWord();
02607 rtl = BSWAP32(rtl);
02608
02609 RailType rt = GetRailTypeByLabel(rtl);
02610 if (rt == INVALID_RAILTYPE) {
02611
02612 rt = AllocateRailType(rtl);
02613 }
02614
02615 _cur_grffile->railtype_map[id + i] = rt;
02616 break;
02617 }
02618
02619 case 0x09:
02620 case 0x0A:
02621 case 0x0B:
02622 case 0x0C:
02623 case 0x0D:
02624 case 0x14:
02625 buf->ReadWord();
02626 break;
02627
02628 case 0x0E:
02629 case 0x0F:
02630 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
02631 break;
02632
02633 case 0x10:
02634 case 0x11:
02635 case 0x12:
02636 case 0x13:
02637 case 0x15:
02638 buf->ReadByte();
02639 break;
02640
02641 default:
02642 ret = CIR_UNKNOWN;
02643 break;
02644 }
02645 }
02646
02647 return ret;
02648 }
02649
02650 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
02651 {
02652 switch (cir) {
02653 default: NOT_REACHED();
02654
02655 case CIR_SUCCESS:
02656 return false;
02657
02658 case CIR_UNHANDLED:
02659 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
02660 return false;
02661
02662 case CIR_UNKNOWN:
02663 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
02664
02665
02666 case CIR_INVALID_ID:
02667
02668 _skip_sprites = -1;
02669 _cur_grfconfig->status = GCS_DISABLED;
02670 _cur_grfconfig->error = CallocT<GRFError>(1);
02671 _cur_grfconfig->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
02672 _cur_grfconfig->error->message = (cir == CIR_INVALID_ID) ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY;
02673 return true;
02674 }
02675 }
02676
02677
02678 static void FeatureChangeInfo(ByteReader *buf)
02679 {
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691 static const VCI_Handler handler[] = {
02692 RailVehicleChangeInfo,
02693 RoadVehicleChangeInfo,
02694 ShipVehicleChangeInfo,
02695 AircraftVehicleChangeInfo,
02696 StationChangeInfo,
02697 CanalChangeInfo,
02698 BridgeChangeInfo,
02699 TownHouseChangeInfo,
02700 GlobalVarChangeInfo,
02701 IndustrytilesChangeInfo,
02702 IndustriesChangeInfo,
02703 NULL,
02704 SoundEffectChangeInfo,
02705 NULL,
02706 NULL,
02707 NULL,
02708 RailTypeChangeInfo,
02709 };
02710
02711 uint8 feature = buf->ReadByte();
02712 uint8 numprops = buf->ReadByte();
02713 uint numinfo = buf->ReadByte();
02714 uint engine = buf->ReadExtended();
02715
02716 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
02717 feature, numprops, engine, numinfo);
02718
02719 if (feature >= lengthof(handler) || handler[feature] == NULL) {
02720 if (feature != GSF_CARGOS) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
02721 return;
02722 }
02723
02724
02725 SetBit(_cur_grffile->grf_features, feature);
02726
02727 while (numprops-- && buf->HasData()) {
02728 uint8 prop = buf->ReadByte();
02729
02730 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
02731 if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
02732 }
02733 }
02734
02735
02736 static void SafeChangeInfo(ByteReader *buf)
02737 {
02738 uint8 feature = buf->ReadByte();
02739 uint8 numprops = buf->ReadByte();
02740 uint numinfo = buf->ReadByte();
02741 buf->ReadExtended();
02742
02743 if (feature == GSF_BRIDGE && numprops == 1) {
02744 uint8 prop = buf->ReadByte();
02745
02746
02747 if (prop == 0x0D) return;
02748 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
02749 uint8 prop = buf->ReadByte();
02750
02751 if (prop == 0x11) {
02752 bool is_safe = true;
02753 for (uint i = 0; i < numinfo; i++) {
02754 uint32 s = buf->ReadDWord();
02755 buf->ReadDWord();
02756 const GRFConfig *grfconfig = GetGRFConfig(s);
02757 if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
02758 is_safe = false;
02759 break;
02760 }
02761 }
02762 if (is_safe) return;
02763 }
02764 }
02765
02766 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
02767
02768
02769 _skip_sprites = -1;
02770 }
02771
02772
02773 static void ReserveChangeInfo(ByteReader *buf)
02774 {
02775 uint8 feature = buf->ReadByte();
02776
02777 if (feature != GSF_CARGOS && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return;
02778
02779 uint8 numprops = buf->ReadByte();
02780 uint8 numinfo = buf->ReadByte();
02781 uint8 index = buf->ReadExtended();
02782
02783 while (numprops-- && buf->HasData()) {
02784 uint8 prop = buf->ReadByte();
02785 ChangeInfoResult cir = CIR_SUCCESS;
02786
02787 switch (feature) {
02788 default: NOT_REACHED();
02789 case GSF_CARGOS:
02790 cir = CargoChangeInfo(index, numinfo, prop, buf);
02791 break;
02792
02793 case GSF_GLOBALVAR:
02794 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
02795 break;
02796
02797 case GSF_RAILTYPES:
02798 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
02799 break;
02800 }
02801
02802 if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
02803 }
02804 }
02805
02806
02807 static void NewSpriteSet(ByteReader *buf)
02808 {
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821 uint8 feature = buf->ReadByte();
02822 uint8 num_sets = buf->ReadByte();
02823 uint16 num_ents = buf->ReadExtended();
02824
02825 _cur_grffile->spriteset_start = _cur_spriteid;
02826 _cur_grffile->spriteset_feature = feature;
02827 _cur_grffile->spriteset_numsets = num_sets;
02828 _cur_grffile->spriteset_numents = num_ents;
02829
02830 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
02831 _cur_spriteid, feature, num_sets, num_ents, num_sets * num_ents
02832 );
02833
02834 for (int i = 0; i < num_sets * num_ents; i++) {
02835 _nfo_line++;
02836 LoadNextSprite(_cur_spriteid++, _file_index, _nfo_line);
02837 }
02838 }
02839
02840
02841 static void SkipAct1(ByteReader *buf)
02842 {
02843 buf->ReadByte();
02844 uint8 num_sets = buf->ReadByte();
02845 uint16 num_ents = buf->ReadExtended();
02846
02847 _skip_sprites = num_sets * num_ents;
02848
02849 grfmsg(3, "SkipAct1: Skipping %d sprites", _skip_sprites);
02850 }
02851
02852
02853
02854 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
02855 {
02856 if (HasBit(groupid, 15)) return new CallbackResultSpriteGroup(groupid);
02857
02858 if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
02859 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
02860 return NULL;
02861 }
02862
02863 return _cur_grffile->spritegroups[groupid];
02864 }
02865
02866
02867 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid, uint16 num_sprites)
02868 {
02869 if (HasBit(spriteid, 15)) return new CallbackResultSpriteGroup(spriteid);
02870
02871 if (spriteid >= _cur_grffile->spriteset_numsets) {
02872 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid, max %u", setid, type, spriteid, _cur_grffile->spriteset_numsets);
02873 return NULL;
02874 }
02875
02876
02877
02878
02879 if (_cur_grffile->spriteset_start + spriteid * num_sprites + num_sprites > _cur_spriteid) {
02880 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Real Sprite IDs 0x%04X - 0x%04X do not (all) exist (max 0x%04X), leaving empty",
02881 setid, type,
02882 _cur_grffile->spriteset_start + spriteid * num_sprites,
02883 _cur_grffile->spriteset_start + spriteid * num_sprites + num_sprites - 1, _cur_spriteid - 1);
02884 return NULL;
02885 }
02886
02887 if (feature != _cur_grffile->spriteset_feature) {
02888 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set feature 0x%02X does not match action feature 0x%02X, skipping",
02889 setid, type,
02890 _cur_grffile->spriteset_feature, feature);
02891 return NULL;
02892 }
02893
02894 return new ResultSpriteGroup(_cur_grffile->spriteset_start + spriteid * num_sprites, num_sprites);
02895 }
02896
02897
02898 static void NewSpriteGroup(ByteReader *buf)
02899 {
02900
02901
02902
02903
02904
02905
02906
02907
02908
02909
02910 SpriteGroup *act_group = NULL;
02911
02912 uint8 feature = buf->ReadByte();
02913 uint8 setid = buf->ReadByte();
02914 uint8 type = buf->ReadByte();
02915
02916 if (setid >= _cur_grffile->spritegroups_count) {
02917
02918 _cur_grffile->spritegroups = ReallocT(_cur_grffile->spritegroups, setid + 1);
02919
02920 for (; _cur_grffile->spritegroups_count < (setid + 1); _cur_grffile->spritegroups_count++) {
02921 _cur_grffile->spritegroups[_cur_grffile->spritegroups_count] = NULL;
02922 }
02923 }
02924
02925
02926
02927
02928
02929 switch (type) {
02930
02931 case 0x81:
02932 case 0x82:
02933 case 0x85:
02934 case 0x86:
02935 case 0x89:
02936 case 0x8A:
02937 {
02938 byte varadjust;
02939 byte varsize;
02940
02941 DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
02942 act_group = group;
02943 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
02944
02945 switch (GB(type, 2, 2)) {
02946 default: NOT_REACHED();
02947 case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
02948 case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
02949 case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
02950 }
02951
02952
02953
02954 do {
02955 DeterministicSpriteGroupAdjust *adjust;
02956
02957 group->num_adjusts++;
02958 group->adjusts = ReallocT(group->adjusts, group->num_adjusts);
02959
02960 adjust = &group->adjusts[group->num_adjusts - 1];
02961
02962
02963 adjust->operation = group->num_adjusts == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
02964 adjust->variable = buf->ReadByte();
02965 if (adjust->variable == 0x7E) {
02966
02967 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
02968 } else {
02969 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
02970 }
02971
02972 varadjust = buf->ReadByte();
02973 adjust->shift_num = GB(varadjust, 0, 5);
02974 adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
02975 adjust->and_mask = buf->ReadVarSize(varsize);
02976
02977 if (adjust->type != DSGA_TYPE_NONE) {
02978 adjust->add_val = buf->ReadVarSize(varsize);
02979 adjust->divmod_val = buf->ReadVarSize(varsize);
02980 } else {
02981 adjust->add_val = 0;
02982 adjust->divmod_val = 0;
02983 }
02984
02985
02986 } while (HasBit(varadjust, 5));
02987
02988 group->num_ranges = buf->ReadByte();
02989 if (group->num_ranges > 0) group->ranges = CallocT<DeterministicSpriteGroupRange>(group->num_ranges);
02990
02991 for (uint i = 0; i < group->num_ranges; i++) {
02992 group->ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
02993 group->ranges[i].low = buf->ReadVarSize(varsize);
02994 group->ranges[i].high = buf->ReadVarSize(varsize);
02995 }
02996
02997 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
02998 break;
02999 }
03000
03001
03002 case 0x80:
03003 case 0x83:
03004 case 0x84:
03005 {
03006 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
03007 act_group = group;
03008 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
03009
03010 if (HasBit(type, 2)) {
03011 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
03012 group->count = buf->ReadByte();
03013 }
03014
03015 uint8 triggers = buf->ReadByte();
03016 group->triggers = GB(triggers, 0, 7);
03017 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
03018 group->lowest_randbit = buf->ReadByte();
03019 group->num_groups = buf->ReadByte();
03020 group->groups = CallocT<const SpriteGroup*>(group->num_groups);
03021
03022 for (uint i = 0; i < group->num_groups; i++) {
03023 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
03024 }
03025
03026 break;
03027 }
03028
03029
03030 default:
03031 {
03032 switch (feature) {
03033 case GSF_TRAIN:
03034 case GSF_ROAD:
03035 case GSF_SHIP:
03036 case GSF_AIRCRAFT:
03037 case GSF_STATION:
03038 case GSF_CANAL:
03039 case GSF_CARGOS:
03040 {
03041 byte sprites = _cur_grffile->spriteset_numents;
03042 byte num_loaded = type;
03043 byte num_loading = buf->ReadByte();
03044
03045 if (_cur_grffile->spriteset_start == 0) {
03046 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
03047 return;
03048 }
03049
03050 RealSpriteGroup *group = new RealSpriteGroup();
03051 act_group = group;
03052
03053 group->num_loaded = num_loaded;
03054 group->num_loading = num_loading;
03055 if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
03056 if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
03057
03058 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u views, %u loaded, %u loading",
03059 setid, sprites, num_loaded, num_loading);
03060
03061 for (uint i = 0; i < num_loaded; i++) {
03062 uint16 spriteid = buf->ReadWord();
03063 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid, sprites);
03064 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
03065 }
03066
03067 for (uint i = 0; i < num_loading; i++) {
03068 uint16 spriteid = buf->ReadWord();
03069 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid, sprites);
03070 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
03071 }
03072
03073 break;
03074 }
03075
03076 case GSF_TOWNHOUSE:
03077 case GSF_INDUSTRYTILES: {
03078 byte num_spriteset_ents = _cur_grffile->spriteset_numents;
03079 byte num_spritesets = _cur_grffile->spriteset_numsets;
03080 byte num_building_sprites = max((uint8)1, type);
03081 uint i;
03082
03083 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
03084 act_group = group;
03085
03086 group->num_building_stages = max((uint8)1, num_spriteset_ents);
03087 group->dts = CallocT<DrawTileSprites>(1);
03088
03089
03090 group->dts->ground.sprite = buf->ReadWord();
03091 group->dts->ground.pal = buf->ReadWord();
03092
03093
03094 MapSpriteMappingRecolour(&group->dts->ground);
03095
03096 if (HasBit(group->dts->ground.pal, 15)) {
03097
03098
03099 uint spriteset = GB(group->dts->ground.sprite, 0, 14);
03100 if (num_spriteset_ents == 0 || spriteset >= num_spritesets) {
03101 grfmsg(1, "NewSpriteGroup: Spritelayout uses undefined custom spriteset %d", spriteset);
03102 group->dts->ground.sprite = SPR_IMG_QUERY;
03103 group->dts->ground.pal = PAL_NONE;
03104 } else {
03105 SpriteID sprite = _cur_grffile->spriteset_start + spriteset * num_spriteset_ents;
03106 SB(group->dts->ground.sprite, 0, SPRITE_WIDTH, sprite);
03107 ClrBit(group->dts->ground.pal, 15);
03108 SetBit(group->dts->ground.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
03109 }
03110 }
03111
03112 group->dts->seq = CallocT<DrawTileSeqStruct>(num_building_sprites + 1);
03113
03114 for (i = 0; i < num_building_sprites; i++) {
03115 DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&group->dts->seq[i]);
03116
03117 seq->image.sprite = buf->ReadWord();
03118 seq->image.pal = buf->ReadWord();
03119 seq->delta_x = buf->ReadByte();
03120 seq->delta_y = buf->ReadByte();
03121
03122 MapSpriteMappingRecolour(&seq->image);
03123
03124 if (HasBit(seq->image.pal, 15)) {
03125
03126
03127 uint spriteset = GB(seq->image.sprite, 0, 14);
03128 if (num_spriteset_ents == 0 || spriteset >= num_spritesets) {
03129 grfmsg(1, "NewSpriteGroup: Spritelayout uses undefined custom spriteset %d", spriteset);
03130 seq->image.sprite = SPR_IMG_QUERY;
03131 seq->image.pal = PAL_NONE;
03132 } else {
03133 SpriteID sprite = _cur_grffile->spriteset_start + spriteset * num_spriteset_ents;
03134 SB(seq->image.sprite, 0, SPRITE_WIDTH, sprite);
03135 ClrBit(seq->image.pal, 15);
03136 SetBit(seq->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
03137 }
03138 }
03139
03140 if (type > 0) {
03141 seq->delta_z = buf->ReadByte();
03142 if ((byte)seq->delta_z == 0x80) continue;
03143 }
03144
03145 seq->size_x = buf->ReadByte();
03146 seq->size_y = buf->ReadByte();
03147 seq->size_z = buf->ReadByte();
03148 }
03149
03150
03151 const_cast<DrawTileSeqStruct *>(group->dts->seq)[i].delta_x = (int8)0x80;
03152
03153 break;
03154 }
03155
03156 case GSF_INDUSTRIES: {
03157 if (type > 1) {
03158 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
03159 break;
03160 }
03161
03162 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
03163 act_group = group;
03164 group->version = type;
03165 if (type == 0) {
03166 for (uint i = 0; i < 3; i++) {
03167 group->subtract_input[i] = (int16)buf->ReadWord();
03168 }
03169 for (uint i = 0; i < 2; i++) {
03170 group->add_output[i] = buf->ReadWord();
03171 }
03172 group->again = buf->ReadByte();
03173 } else {
03174 for (uint i = 0; i < 3; i++) {
03175 group->subtract_input[i] = buf->ReadByte();
03176 }
03177 for (uint i = 0; i < 2; i++) {
03178 group->add_output[i] = buf->ReadByte();
03179 }
03180 group->again = buf->ReadByte();
03181 }
03182 break;
03183 }
03184
03185
03186 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
03187 }
03188 }
03189 }
03190
03191 _cur_grffile->spritegroups[setid] = act_group;
03192 }
03193
03194 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
03195 {
03196
03197 if (feature == GSF_STATION && ctype == 0xFE) return CT_DEFAULT_NA;
03198 if (ctype == 0xFF) return CT_PURCHASE;
03199
03200 if (_cur_grffile->cargo_max == 0) {
03201
03202 if (ctype >= 32) {
03203 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
03204 return CT_INVALID;
03205 }
03206
03207 const CargoSpec *cs;
03208 FOR_ALL_CARGOSPECS(cs) {
03209 if (cs->bitnum == ctype) {
03210 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
03211 return cs->Index();
03212 }
03213 }
03214
03215 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
03216 return CT_INVALID;
03217 }
03218
03219
03220 if (ctype >= _cur_grffile->cargo_max) {
03221 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur_grffile->cargo_max - 1);
03222 return CT_INVALID;
03223 }
03224
03225
03226 CargoLabel cl = _cur_grffile->cargo_list[ctype];
03227 if (cl == 0) {
03228 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
03229 return CT_INVALID;
03230 }
03231
03232 ctype = GetCargoIDByLabel(cl);
03233 if (ctype == CT_INVALID) {
03234 grfmsg(5, "TranslateCargo: Cargo '%c%c%c%c' unsupported, skipping.", GB(cl, 24, 8), GB(cl, 16, 8), GB(cl, 8, 8), GB(cl, 0, 8));
03235 return CT_INVALID;
03236 }
03237
03238 grfmsg(6, "TranslateCargo: Cargo '%c%c%c%c' mapped to cargo type %d.", GB(cl, 24, 8), GB(cl, 16, 8), GB(cl, 8, 8), GB(cl, 0, 8), ctype);
03239 return ctype;
03240 }
03241
03242
03243 static bool IsValidGroupID(uint16 groupid, const char *function)
03244 {
03245 if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
03246 grfmsg(1, "%s: Spriteset 0x%04X out of range (maximum 0x%02X) or empty, skipping.", function, groupid, _cur_grffile->spritegroups_count - 1);
03247 return false;
03248 }
03249
03250 return true;
03251 }
03252
03253 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
03254 {
03255 static EngineID *last_engines;
03256 static uint last_engines_count;
03257 bool wagover = false;
03258
03259
03260 if (HasBit(idcount, 7)) {
03261 wagover = true;
03262
03263 idcount = GB(idcount, 0, 7);
03264
03265 if (last_engines_count == 0) {
03266 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
03267 return;
03268 }
03269
03270 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
03271 last_engines_count, idcount);
03272 } else {
03273 if (last_engines_count != idcount) {
03274 last_engines = ReallocT(last_engines, idcount);
03275 last_engines_count = idcount;
03276 }
03277 }
03278
03279 EngineID *engines = AllocaM(EngineID, idcount);
03280 for (uint i = 0; i < idcount; i++) {
03281 engines[i] = GetNewEngine(_cur_grffile, (VehicleType)feature, buf->ReadExtended())->index;
03282 if (!wagover) last_engines[i] = engines[i];
03283 }
03284
03285 uint8 cidcount = buf->ReadByte();
03286 for (uint c = 0; c < cidcount; c++) {
03287 uint8 ctype = buf->ReadByte();
03288 uint16 groupid = buf->ReadWord();
03289 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
03290
03291 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
03292
03293 ctype = TranslateCargo(feature, ctype);
03294 if (ctype == CT_INVALID) continue;
03295
03296 for (uint i = 0; i < idcount; i++) {
03297 EngineID engine = engines[i];
03298
03299 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
03300
03301 if (wagover) {
03302 SetWagonOverrideSprites(engine, ctype, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
03303 } else {
03304 SetCustomEngineSprites(engine, ctype, _cur_grffile->spritegroups[groupid]);
03305 }
03306 }
03307 }
03308
03309 uint16 groupid = buf->ReadWord();
03310 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
03311
03312 grfmsg(8, "-- Default group id 0x%04X", groupid);
03313
03314 for (uint i = 0; i < idcount; i++) {
03315 EngineID engine = engines[i];
03316
03317 if (wagover) {
03318 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
03319 } else {
03320 SetCustomEngineSprites(engine, CT_DEFAULT, _cur_grffile->spritegroups[groupid]);
03321 SetEngineGRF(engine, _cur_grffile);
03322 }
03323 }
03324 }
03325
03326
03327 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
03328 {
03329 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
03330 for (uint i = 0; i < idcount; i++) {
03331 cfs[i] = (CanalFeature)buf->ReadByte();
03332 }
03333
03334 uint8 cidcount = buf->ReadByte();
03335 buf->Skip(cidcount * 3);
03336
03337 uint16 groupid = buf->ReadWord();
03338 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
03339
03340 for (uint i = 0; i < idcount; i++) {
03341 CanalFeature cf = cfs[i];
03342
03343 if (cf >= CF_END) {
03344 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
03345 continue;
03346 }
03347
03348 _water_feature[cf].grffile = _cur_grffile;
03349 _water_feature[cf].group = _cur_grffile->spritegroups[groupid];
03350 }
03351 }
03352
03353
03354 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
03355 {
03356 uint8 *stations = AllocaM(uint8, idcount);
03357 for (uint i = 0; i < idcount; i++) {
03358 stations[i] = buf->ReadByte();
03359 }
03360
03361 uint8 cidcount = buf->ReadByte();
03362 for (uint c = 0; c < cidcount; c++) {
03363 uint8 ctype = buf->ReadByte();
03364 uint16 groupid = buf->ReadWord();
03365 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
03366
03367 ctype = TranslateCargo(GSF_STATION, ctype);
03368 if (ctype == CT_INVALID) continue;
03369
03370 for (uint i = 0; i < idcount; i++) {
03371 StationSpec *statspec = _cur_grffile->stations == NULL ? NULL : _cur_grffile->stations[stations[i]];
03372
03373 if (statspec == NULL) {
03374 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
03375 continue;
03376 }
03377
03378 statspec->spritegroup[ctype] = _cur_grffile->spritegroups[groupid];
03379 }
03380 }
03381
03382 uint16 groupid = buf->ReadWord();
03383 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
03384
03385 for (uint i = 0; i < idcount; i++) {
03386 StationSpec *statspec = _cur_grffile->stations == NULL ? NULL : _cur_grffile->stations[stations[i]];
03387
03388 if (statspec == NULL) {
03389 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
03390 continue;
03391 }
03392
03393 statspec->spritegroup[CT_DEFAULT] = _cur_grffile->spritegroups[groupid];
03394 statspec->grffile = _cur_grffile;
03395 statspec->localidx = stations[i];
03396 SetCustomStationSpec(statspec);
03397 }
03398 }
03399
03400
03401 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
03402 {
03403 uint8 *houses = AllocaM(uint8, idcount);
03404 for (uint i = 0; i < idcount; i++) {
03405 houses[i] = buf->ReadByte();
03406 }
03407
03408
03409 uint8 cidcount = buf->ReadByte();
03410 buf->Skip(cidcount * 3);
03411
03412 uint16 groupid = buf->ReadWord();
03413 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
03414
03415 if (_cur_grffile->housespec == NULL) {
03416 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
03417 return;
03418 }
03419
03420 for (uint i = 0; i < idcount; i++) {
03421 HouseSpec *hs = _cur_grffile->housespec[houses[i]];
03422
03423 if (hs == NULL) {
03424 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
03425 continue;
03426 }
03427
03428 hs->spritegroup = _cur_grffile->spritegroups[groupid];
03429 }
03430 }
03431
03432 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
03433 {
03434 uint8 *industries = AllocaM(uint8, idcount);
03435 for (uint i = 0; i < idcount; i++) {
03436 industries[i] = buf->ReadByte();
03437 }
03438
03439
03440 uint8 cidcount = buf->ReadByte();
03441 buf->Skip(cidcount * 3);
03442
03443 uint16 groupid = buf->ReadWord();
03444 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
03445
03446 if (_cur_grffile->industryspec == NULL) {
03447 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
03448 return;
03449 }
03450
03451 for (uint i = 0; i < idcount; i++) {
03452 IndustrySpec *indsp = _cur_grffile->industryspec[industries[i]];
03453
03454 if (indsp == NULL) {
03455 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
03456 continue;
03457 }
03458
03459 indsp->grf_prop.spritegroup = _cur_grffile->spritegroups[groupid];
03460 }
03461 }
03462
03463 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
03464 {
03465 uint8 *indtiles = AllocaM(uint8, idcount);
03466 for (uint i = 0; i < idcount; i++) {
03467 indtiles[i] = buf->ReadByte();
03468 }
03469
03470
03471 uint8 cidcount = buf->ReadByte();
03472 buf->Skip(cidcount * 3);
03473
03474 uint16 groupid = buf->ReadWord();
03475 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
03476
03477 if (_cur_grffile->indtspec == NULL) {
03478 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
03479 return;
03480 }
03481
03482 for (uint i = 0; i < idcount; i++) {
03483 IndustryTileSpec *indtsp = _cur_grffile->indtspec[indtiles[i]];
03484
03485 if (indtsp == NULL) {
03486 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
03487 continue;
03488 }
03489
03490 indtsp->grf_prop.spritegroup = _cur_grffile->spritegroups[groupid];
03491 }
03492 }
03493
03494 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
03495 {
03496 CargoID *cargos = AllocaM(CargoID, idcount);
03497 for (uint i = 0; i < idcount; i++) {
03498 cargos[i] = buf->ReadByte();
03499 }
03500
03501
03502 uint8 cidcount = buf->ReadByte();
03503 buf->Skip(cidcount * 3);
03504
03505 uint16 groupid = buf->ReadWord();
03506 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
03507
03508 for (uint i = 0; i < idcount; i++) {
03509 CargoID cid = cargos[i];
03510
03511 if (cid >= NUM_CARGO) {
03512 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
03513 continue;
03514 }
03515
03516 CargoSpec *cs = CargoSpec::Get(cid);
03517 cs->grffile = _cur_grffile;
03518 cs->group = _cur_grffile->spritegroups[groupid];
03519 }
03520 }
03521
03522
03523
03524 static void FeatureMapSpriteGroup(ByteReader *buf)
03525 {
03526
03527
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540 if (_cur_grffile->spritegroups == NULL) {
03541 grfmsg(1, "FeatureMapSpriteGroup: No sprite groups to work on! Skipping");
03542 return;
03543 }
03544
03545 uint8 feature = buf->ReadByte();
03546 uint8 idcount = buf->ReadByte();
03547
03548
03549 if (idcount == 0) {
03550
03551 buf->ReadByte();
03552 uint16 groupid = buf->ReadWord();
03553
03554 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
03555
03556 AddGenericCallback(feature, _cur_grffile, _cur_grffile->spritegroups[groupid]);
03557 return;
03558 }
03559
03560
03561 SetBit(_cur_grffile->grf_features, feature);
03562
03563 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
03564
03565 switch (feature) {
03566 case GSF_TRAIN:
03567 case GSF_ROAD:
03568 case GSF_SHIP:
03569 case GSF_AIRCRAFT:
03570 VehicleMapSpriteGroup(buf, feature, idcount);
03571 return;
03572
03573 case GSF_CANAL:
03574 CanalMapSpriteGroup(buf, idcount);
03575 return;
03576
03577 case GSF_STATION:
03578 StationMapSpriteGroup(buf, idcount);
03579 return;
03580
03581 case GSF_TOWNHOUSE:
03582 TownHouseMapSpriteGroup(buf, idcount);
03583 return;
03584
03585 case GSF_INDUSTRIES:
03586 IndustryMapSpriteGroup(buf, idcount);
03587 return;
03588
03589 case GSF_INDUSTRYTILES:
03590 IndustrytileMapSpriteGroup(buf, idcount);
03591 return;
03592
03593 case GSF_CARGOS:
03594 CargoMapSpriteGroup(buf, idcount);
03595 return;
03596
03597 default:
03598 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
03599 return;
03600 }
03601 }
03602
03603
03604 static void FeatureNewName(ByteReader *buf)
03605 {
03606
03607
03608
03609
03610
03611
03612
03613
03614
03615
03616
03617
03618
03619
03620
03621
03622 bool new_scheme = _cur_grffile->grf_version >= 7;
03623
03624 uint8 feature = buf->ReadByte();
03625 uint8 lang = buf->ReadByte();
03626 uint8 num = buf->ReadByte();
03627 bool generic = HasBit(lang, 7);
03628 uint16 id;
03629 if (generic) {
03630 id = buf->ReadWord();
03631 } else if (feature <= GSF_AIRCRAFT) {
03632 id = buf->ReadExtended();
03633 } else {
03634 id = buf->ReadByte();
03635 }
03636
03637 ClrBit(lang, 7);
03638
03639 uint16 endid = id + num;
03640
03641 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
03642 id, endid, feature, lang);
03643
03644 for (; id < endid && buf->HasData(); id++) {
03645 const char *name = buf->ReadString();
03646 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
03647
03648 switch (feature) {
03649 case GSF_TRAIN:
03650 case GSF_ROAD:
03651 case GSF_SHIP:
03652 case GSF_AIRCRAFT:
03653 if (!generic) {
03654 Engine *e = GetNewEngine(_cur_grffile, (VehicleType)feature, id, HasBit(_cur_grfconfig->flags, GCF_STATIC));
03655 if (e == NULL) break;
03656 StringID string = AddGRFString(_cur_grffile->grfid, e->index, lang, new_scheme, name, e->info.string_id);
03657 e->info.string_id = string;
03658 } else {
03659 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03660 }
03661 break;
03662
03663 case GSF_INDUSTRIES: {
03664 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03665 break;
03666 }
03667
03668 case GSF_TOWNHOUSE:
03669 default:
03670 switch (GB(id, 8, 8)) {
03671 case 0xC4:
03672 if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) {
03673 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
03674 } else {
03675 StationClassID sclass = _cur_grffile->stations[GB(id, 0, 8)]->sclass;
03676 SetStationClassName(sclass, AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED));
03677 }
03678 break;
03679
03680 case 0xC5:
03681 if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) {
03682 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
03683 } else {
03684 _cur_grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03685 }
03686 break;
03687
03688 case 0xC9:
03689 if (_cur_grffile->housespec == NULL || _cur_grffile->housespec[GB(id, 0, 8)] == NULL) {
03690 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
03691 } else {
03692 _cur_grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03693 }
03694 break;
03695
03696 case 0xD0:
03697 case 0xD1:
03698 case 0xD2:
03699 case 0xD3:
03700 case 0xDC:
03701 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03702 break;
03703
03704 default:
03705 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
03706 break;
03707 }
03708 break;
03709
03710 #if 0
03711 case GSF_CANAL :
03712 case GSF_BRIDGE :
03713 AddGRFString(_cur_spriteid, id, lang, name);
03714 switch (GB(id, 8, 8)) {
03715 case 0xC9:
03716 default:
03717 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
03718 }
03719 break;
03720
03721 default :
03722 grfmsg(7, "FeatureNewName: Unsupported feature (0x%02X)", feature);
03723 break;
03724 #endif
03725 }
03726 }
03727 }
03728
03737 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
03738 {
03739
03740 if (offset >= max_sprites) {
03741 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
03742 uint orig_num = num;
03743 num = 0;
03744 return orig_num;
03745 }
03746
03747 if (offset + num > max_sprites) {
03748 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
03749 uint orig_num = num;
03750 num = max(max_sprites - offset, 0);
03751 return orig_num - num;
03752 }
03753
03754 return 0;
03755 }
03756
03757
03758 static void GraphicsNew(ByteReader *buf)
03759 {
03760
03761
03762
03763
03764
03765
03766
03767 enum Action5BlockType {
03768 A5BLOCK_FIXED,
03769 A5BLOCK_ALLOW_OFFSET,
03770 A5BLOCK_INVALID,
03771 };
03772 struct Action5Type {
03773 Action5BlockType block_type;
03774 SpriteID sprite_base;
03775 uint16 min_sprites;
03776 uint16 max_sprites;
03777 const char *name;
03778 };
03779
03780 static const Action5Type action5_types[] = {
03781
03782 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
03783 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
03784 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
03785 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
03786 { A5BLOCK_FIXED, SPR_SIGNALS_BASE, 48, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
03787 { A5BLOCK_FIXED, SPR_ELRAIL_BASE, 48, ELRAIL_SPRITE_COUNT, "Catenary graphics" },
03788 { A5BLOCK_FIXED, SPR_SLOPES_BASE, 74, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
03789 { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" },
03790 { A5BLOCK_FIXED, SPR_CANALS_BASE, 65, CANALS_SPRITE_COUNT, "Canal graphics" },
03791 { A5BLOCK_FIXED, SPR_ONEWAY_BASE, 6, ONEWAY_SPRITE_COUNT, "One way road graphics" },
03792 { A5BLOCK_FIXED, SPR_2CCMAP_BASE, 256, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
03793 { A5BLOCK_FIXED, SPR_TRAMWAY_BASE, 113, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
03794 { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" },
03795 { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
03796 { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" },
03797 { A5BLOCK_FIXED, SPR_TRACKS_FOR_SLOPES_BASE, 12, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
03798 { A5BLOCK_FIXED, SPR_AIRPORTX_BASE, 15, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
03799 { A5BLOCK_FIXED, SPR_ROADSTOP_BASE, 8, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
03800 { A5BLOCK_FIXED, SPR_AQUEDUCT_BASE, 8, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
03801 { A5BLOCK_FIXED, SPR_AUTORAIL_BASE, 55, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
03802 { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
03803 { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
03804 };
03805
03806 uint8 type = buf->ReadByte();
03807 uint16 num = buf->ReadExtended();
03808 uint16 offset = HasBit(type, 7) ? buf->ReadExtended() : 0;
03809 ClrBit(type, 7);
03810
03811 if ((type == 0x0D) && (num == 10) && _cur_grffile->is_ottdfile) {
03812
03813
03814 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from openttd(d/w).grf.");
03815 LoadNextSprite(SPR_SHORE_BASE + 0, _file_index, _nfo_line++);
03816 LoadNextSprite(SPR_SHORE_BASE + 5, _file_index, _nfo_line++);
03817 LoadNextSprite(SPR_SHORE_BASE + 7, _file_index, _nfo_line++);
03818 LoadNextSprite(SPR_SHORE_BASE + 10, _file_index, _nfo_line++);
03819 LoadNextSprite(SPR_SHORE_BASE + 11, _file_index, _nfo_line++);
03820 LoadNextSprite(SPR_SHORE_BASE + 13, _file_index, _nfo_line++);
03821 LoadNextSprite(SPR_SHORE_BASE + 14, _file_index, _nfo_line++);
03822 LoadNextSprite(SPR_SHORE_BASE + 15, _file_index, _nfo_line++);
03823 LoadNextSprite(SPR_SHORE_BASE + 16, _file_index, _nfo_line++);
03824 LoadNextSprite(SPR_SHORE_BASE + 17, _file_index, _nfo_line++);
03825 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
03826 return;
03827 }
03828
03829
03830 if ((type >= lengthof(action5_types)) || (action5_types[type].block_type == A5BLOCK_INVALID)) {
03831 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
03832 _skip_sprites = num;
03833 return;
03834 }
03835
03836 const Action5Type *action5_type = &action5_types[type];
03837
03838
03839 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
03840 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
03841 offset = 0;
03842 }
03843
03844
03845
03846 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
03847 grfmsg(1, "GraphicsNew: %s (type 0x%02X) count must be at least %d. Only %d were specified. Skipping.", action5_type->name, type, action5_type->min_sprites, num);
03848 _skip_sprites = num;
03849 return;
03850 }
03851
03852
03853 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
03854 SpriteID replace = action5_type->sprite_base + offset;
03855
03856
03857 grfmsg(2, "GraphicsNew: Replacing sprites %d to %d of %s (type 0x%02X) at SpriteID 0x%04X", offset, offset + num - 1, action5_type->name, type, replace);
03858
03859 for (; num > 0; num--) {
03860 _nfo_line++;
03861 LoadNextSprite(replace == 0 ? _cur_spriteid++ : replace++, _file_index, _nfo_line);
03862 }
03863
03864 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
03865
03866 _skip_sprites = skip_num;
03867 }
03868
03869
03870 static void SkipAct5(ByteReader *buf)
03871 {
03872
03873 buf->ReadByte();
03874
03875
03876 _skip_sprites = buf->ReadExtended();
03877
03878 grfmsg(3, "SkipAct5: Skipping %d sprites", _skip_sprites);
03879 }
03880
03891 bool GetGlobalVariable(byte param, uint32 *value)
03892 {
03893 switch (param) {
03894 case 0x00:
03895 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
03896 return true;
03897
03898 case 0x01:
03899 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
03900 return true;
03901
03902 case 0x02: {
03903 YearMonthDay ymd;
03904 ConvertDateToYMD(_date, &ymd);
03905 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
03906 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
03907 return true;
03908 }
03909
03910 case 0x03:
03911 *value = _settings_game.game_creation.landscape;
03912 return true;
03913
03914 case 0x06:
03915 *value = _settings_game.vehicle.road_side << 4;
03916 return true;
03917
03918 case 0x09:
03919 *value = _date_fract * 885;
03920 return true;
03921
03922 case 0x0A:
03923 *value = _tick_counter;
03924 return true;
03925
03926 case 0x0B: {
03927 uint major = 2;
03928 uint minor = 6;
03929 uint revision = 1;
03930 uint build = 1382;
03931 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
03932 return true;
03933 }
03934
03935 case 0x0D:
03936 *value = _cur_grfconfig->windows_paletted;
03937 return true;
03938
03939 case 0x0E:
03940 *value = _cur_grffile->traininfo_vehicle_pitch;
03941 return true;
03942
03943 case 0x0F:
03944 *value = 0;
03945 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier);
03946 if (_settings_game.vehicle.disable_elrails) {
03947
03948 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier);
03949 } else {
03950 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier);
03951
03952 }
03953 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier);
03954 return true;
03955
03956 case 0x11:
03957 *value = 0;
03958 return true;
03959
03960 case 0x12:
03961 *value = _game_mode;
03962 return true;
03963
03964
03965
03966
03967
03968
03969
03970 case 0x1A:
03971 *value = UINT_MAX;
03972 return true;
03973
03974 case 0x1B:
03975 *value = GB(_display_opt, 0, 6);
03976 return true;
03977
03978 case 0x1D:
03979 *value = 1;
03980 return true;
03981
03982 case 0x1E:
03983 *value = _misc_grf_features;
03984
03985
03986 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
03987 if (_cur_grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
03988 return true;
03989
03990
03991
03992 case 0x20:
03993 *value = _settings_game.game_creation.landscape == LT_ARCTIC ? GetSnowLine() : 0xFF;
03994 return true;
03995
03996 case 0x21:
03997 *value = _openttd_newgrf_version;
03998 return true;
03999
04000 case 0x22:
04001 *value = _settings_game.difficulty.diff_level;
04002 return true;
04003
04004 case 0x23:
04005 *value = _date;
04006 return true;
04007
04008 case 0x24:
04009 *value = _cur_year;
04010 return true;
04011
04012 default: return false;
04013 }
04014 }
04015
04016 static uint32 GetParamVal(byte param, uint32 *cond_val)
04017 {
04018
04019 uint32 value;
04020 if (GetGlobalVariable(param - 0x80, &value)) return value;
04021
04022
04023 switch (param) {
04024 case 0x84: {
04025 uint32 res = 0;
04026
04027 if (_cur_stage > GLS_INIT) SetBit(res, 0);
04028 if (_cur_stage == GLS_RESERVE) SetBit(res, 8);
04029 if (_cur_stage == GLS_ACTIVATION) SetBit(res, 9);
04030 return res;
04031 }
04032
04033 case 0x85:
04034 if (cond_val == NULL) {
04035
04036 return 0;
04037 } else {
04038 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
04039 *cond_val %= 0x20;
04040 return param_val;
04041 }
04042
04043 case 0x88:
04044 return 0;
04045
04046
04047
04048 default:
04049
04050 if (param < 0x80) return _cur_grffile->GetParam(param);
04051
04052
04053 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
04054 return UINT_MAX;
04055 }
04056 }
04057
04058
04059 static void CfgApply(ByteReader *buf)
04060 {
04061
04062
04063
04064
04065
04066
04067
04068
04069
04070
04071
04072
04073 size_t pos = FioGetPos();
04074 uint16 num = FioReadWord();
04075 uint8 type = FioReadByte();
04076 byte *preload_sprite = NULL;
04077
04078
04079 if (type == 0xFF) {
04080 preload_sprite = MallocT<byte>(num);
04081 FioReadBlock(preload_sprite, num);
04082 }
04083
04084
04085 FioSeekTo(pos, SEEK_SET);
04086
04087 if (type != 0xFF) {
04088 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
04089 free(preload_sprite);
04090 return;
04091 }
04092
04093 GRFLocation location(_cur_grfconfig->grfid, _nfo_line + 1);
04094 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
04095 if (it != _grf_line_to_action6_sprite_override.end()) {
04096 free(preload_sprite);
04097 preload_sprite = _grf_line_to_action6_sprite_override[location];
04098 } else {
04099 _grf_line_to_action6_sprite_override[location] = preload_sprite;
04100 }
04101
04102
04103
04104 for (;;) {
04105 uint i;
04106 uint param_num;
04107 uint param_size;
04108 uint offset;
04109 bool add_value;
04110
04111
04112 param_num = buf->ReadByte();
04113 if (param_num == 0xFF) break;
04114
04115
04116
04117 param_size = buf->ReadByte();
04118
04119
04120
04121 add_value = HasBit(param_size, 7);
04122 param_size = GB(param_size, 0, 7);
04123
04124
04125 offset = buf->ReadExtended();
04126
04127
04128
04129 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur_grffile->param_end) {
04130 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
04131 break;
04132 }
04133
04134 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
04135
04136 bool carry = false;
04137 for (i = 0; i < param_size && offset + i < num; i++) {
04138 uint32 value = GetParamVal(param_num + i / 4, NULL);
04139
04140
04141 if (i == 0) carry = false;
04142
04143 if (add_value) {
04144 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
04145 preload_sprite[offset + i] = GB(new_value, 0, 8);
04146
04147 carry = new_value >= 256;
04148 } else {
04149 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
04150 }
04151 }
04152 }
04153 }
04154
04164 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
04165 {
04166 if (c->error != NULL) {
04167 free(c->error->custom_message);
04168 free(c->error->data);
04169 free(c->error);
04170 }
04171 c->status = GCS_DISABLED;
04172 c->error = CallocT<GRFError>(1);
04173 c->error->data = strdup(_cur_grfconfig->name);
04174 c->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
04175 c->error->message = STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC;
04176
04177 ClearTemporaryNewGRFData(GetFileByGRFID(c->grfid));
04178 }
04179
04180
04181
04182 static void SkipIf(ByteReader *buf)
04183 {
04184
04185
04186
04187
04188
04189
04190
04191
04192 uint32 cond_val = 0;
04193 uint32 mask = 0;
04194 bool result;
04195
04196 uint8 param = buf->ReadByte();
04197 uint8 paramsize = buf->ReadByte();
04198 uint8 condtype = buf->ReadByte();
04199
04200 if (condtype < 2) {
04201
04202 paramsize = 1;
04203 }
04204
04205 switch (paramsize) {
04206 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
04207 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
04208 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
04209 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
04210 default: break;
04211 }
04212
04213 if (param < 0x80 && _cur_grffile->param_end <= param) {
04214 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
04215 return;
04216 }
04217
04218 uint32 param_val = GetParamVal(param, &cond_val);
04219
04220 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
04221
04222
04223
04224
04225
04226
04227
04228
04229 if (param == 0x88 && condtype != 0x0B && condtype != 0x0C) {
04230
04231
04232 GRFConfig *c = GetGRFConfig(cond_val, mask);
04233
04234 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur_grfconfig->flags, GCF_STATIC) && c->status != GCS_DISABLED && _networking) {
04235 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
04236 c = NULL;
04237 }
04238
04239 if (condtype != 10 && c == NULL) {
04240 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
04241 return;
04242 }
04243
04244 switch (condtype) {
04245
04246 case 0x06:
04247 result = c->status == GCS_ACTIVATED;
04248 break;
04249
04250 case 0x07:
04251 result = c->status != GCS_ACTIVATED;
04252 break;
04253
04254 case 0x08:
04255 result = c->status == GCS_INITIALISED;
04256 break;
04257
04258 case 0x09:
04259 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
04260 break;
04261
04262 case 0x0A:
04263
04264 result = c == NULL || c->flags == GCS_DISABLED || c->status == GCS_NOT_FOUND;
04265 break;
04266
04267 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
04268 }
04269 } else {
04270
04271 switch (condtype) {
04272 case 0x00: result = !!(param_val & (1 << cond_val));
04273 break;
04274 case 0x01: result = !(param_val & (1 << cond_val));
04275 break;
04276 case 0x02: result = (param_val & mask) == cond_val;
04277 break;
04278 case 0x03: result = (param_val & mask) != cond_val;
04279 break;
04280 case 0x04: result = (param_val & mask) < cond_val;
04281 break;
04282 case 0x05: result = (param_val & mask) > cond_val;
04283 break;
04284 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
04285 break;
04286 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
04287 break;
04288 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
04289 break;
04290 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
04291 break;
04292
04293 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
04294 }
04295 }
04296
04297 if (!result) {
04298 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
04299 return;
04300 }
04301
04302 uint8 numsprites = buf->ReadByte();
04303
04304
04305
04306
04307
04308 GRFLabel *choice = NULL;
04309 for (GRFLabel *label = _cur_grffile->label; label != NULL; label = label->next) {
04310 if (label->label != numsprites) continue;
04311
04312
04313 if (choice == NULL) choice = label;
04314
04315 if (label->nfo_line > _nfo_line) {
04316 choice = label;
04317 break;
04318 }
04319 }
04320
04321 if (choice != NULL) {
04322 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
04323 FioSeekTo(choice->pos, SEEK_SET);
04324 _nfo_line = choice->nfo_line;
04325 return;
04326 }
04327
04328 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
04329 _skip_sprites = numsprites;
04330 if (_skip_sprites == 0) {
04331
04332
04333
04334 _skip_sprites = -1;
04335
04336
04337 if (_cur_grfconfig->status != (_cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
04338 _cur_grfconfig->status = GCS_DISABLED;
04339 ClearTemporaryNewGRFData(_cur_grffile);
04340 }
04341 }
04342 }
04343
04344
04345
04346 static void ScanInfo(ByteReader *buf)
04347 {
04348 buf->ReadByte();
04349 uint32 grfid = buf->ReadDWord();
04350
04351 _cur_grfconfig->grfid = grfid;
04352
04353
04354 if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur_grfconfig->flags, GCF_SYSTEM);
04355
04356 const char *name = buf->ReadString();
04357 _cur_grfconfig->name = TranslateTTDPatchCodes(grfid, name);
04358
04359 if (buf->HasData()) {
04360 const char *info = buf->ReadString();
04361 _cur_grfconfig->info = TranslateTTDPatchCodes(grfid, info);
04362 }
04363
04364
04365 _skip_sprites = -1;
04366 }
04367
04368
04369 static void GRFInfo(ByteReader *buf)
04370 {
04371
04372
04373
04374
04375
04376
04377
04378 uint8 version = buf->ReadByte();
04379 uint32 grfid = buf->ReadDWord();
04380 const char *name = buf->ReadString();
04381
04382 if (_cur_stage < GLS_RESERVE && _cur_grfconfig->status != GCS_UNKNOWN) {
04383 _cur_grfconfig->status = GCS_DISABLED;
04384 _cur_grfconfig->error = CallocT<GRFError>(1);
04385 _cur_grfconfig->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
04386 _cur_grfconfig->error->message = STR_NEWGRF_ERROR_MULTIPLE_ACTION_8;
04387
04388 _skip_sprites = -1;
04389 return;
04390 }
04391
04392 _cur_grffile->grfid = grfid;
04393 _cur_grffile->grf_version = version;
04394 _cur_grfconfig->status = _cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
04395
04396
04397 DEBUG(grf, 1, "GRFInfo: Loaded GRFv%d set %08X - %s (palette: %s)", version, BSWAP32(grfid), name, _cur_grfconfig->windows_paletted ? "Windows" : "DOS");
04398 }
04399
04400
04401 static void SpriteReplace(ByteReader *buf)
04402 {
04403
04404
04405
04406
04407
04408
04409
04410
04411 uint8 num_sets = buf->ReadByte();
04412
04413 for (uint i = 0; i < num_sets; i++) {
04414 uint8 num_sprites = buf->ReadByte();
04415 uint16 first_sprite = buf->ReadWord();
04416
04417 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
04418 i, num_sprites, first_sprite
04419 );
04420
04421 for (uint j = 0; j < num_sprites; j++) {
04422 int load_index = first_sprite + j;
04423 _nfo_line++;
04424 LoadNextSprite(load_index, _file_index, _nfo_line);
04425
04426
04427
04428 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
04429 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
04430 }
04431 }
04432 }
04433 }
04434
04435
04436 static void SkipActA(ByteReader *buf)
04437 {
04438 uint8 num_sets = buf->ReadByte();
04439
04440 for (uint i = 0; i < num_sets; i++) {
04441
04442 _skip_sprites += buf->ReadByte();
04443
04444 buf->ReadWord();
04445 }
04446
04447 grfmsg(3, "SkipActA: Skipping %d sprites", _skip_sprites);
04448 }
04449
04450
04451 static void GRFLoadError(ByteReader *buf)
04452 {
04453
04454
04455
04456
04457
04458
04459
04460
04461
04462
04463
04464
04465
04466
04467
04468 static const StringID msgstr[] = {
04469 STR_NEWGRF_ERROR_VERSION_NUMBER,
04470 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
04471 STR_NEWGRF_ERROR_UNSET_SWITCH,
04472 STR_NEWGRF_ERROR_INVALID_PARAMETER,
04473 STR_NEWGRF_ERROR_LOAD_BEFORE,
04474 STR_NEWGRF_ERROR_LOAD_AFTER,
04475 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
04476 };
04477
04478 static const StringID sevstr[] = {
04479 STR_NEWGRF_ERROR_MSG_INFO,
04480 STR_NEWGRF_ERROR_MSG_WARNING,
04481 STR_NEWGRF_ERROR_MSG_ERROR,
04482 STR_NEWGRF_ERROR_MSG_FATAL
04483 };
04484
04485
04486 if (_cur_grfconfig->error != NULL) return;
04487
04488 byte severity = buf->ReadByte();
04489 byte lang = buf->ReadByte();
04490 byte message_id = buf->ReadByte();
04491
04492
04493 if (!CheckGrfLangID(lang, _cur_grffile->grf_version)) return;
04494
04495
04496
04497 if (!HasBit(severity, 7) && _cur_stage == GLS_INIT) {
04498 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur_stage);
04499 return;
04500 }
04501 ClrBit(severity, 7);
04502
04503 if (severity >= lengthof(sevstr)) {
04504 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
04505 severity = 2;
04506 } else if (severity == 3) {
04507
04508
04509 _cur_grfconfig->status = GCS_DISABLED;
04510 ClearTemporaryNewGRFData(_cur_grffile);
04511 _skip_sprites = -1;
04512 }
04513
04514 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
04515 grfmsg(7, "GRFLoadError: Invalid message id.");
04516 return;
04517 }
04518
04519 if (buf->Remaining() <= 1) {
04520 grfmsg(7, "GRFLoadError: No message data supplied.");
04521 return;
04522 }
04523
04524 GRFError *error = CallocT<GRFError>(1);
04525
04526 error->severity = sevstr[severity];
04527
04528 if (message_id == 0xFF) {
04529
04530 if (buf->HasData()) {
04531 const char *message = buf->ReadString();
04532
04533 error->custom_message = TranslateTTDPatchCodes(_cur_grffile->grfid, message);
04534 } else {
04535 grfmsg(7, "GRFLoadError: No custom message supplied.");
04536 error->custom_message = strdup("");
04537 }
04538 } else {
04539 error->message = msgstr[message_id];
04540 }
04541
04542 if (buf->HasData()) {
04543 const char *data = buf->ReadString();
04544
04545 error->data = TranslateTTDPatchCodes(_cur_grffile->grfid, data);
04546 } else {
04547 grfmsg(7, "GRFLoadError: No message data supplied.");
04548 error->data = strdup("");
04549 }
04550
04551
04552 uint i = 0;
04553 for (; i < 2 && buf->HasData(); i++) {
04554 uint param_number = buf->ReadByte();
04555 error->param_value[i] = _cur_grffile->GetParam(param_number);
04556 }
04557 error->num_params = i;
04558
04559 _cur_grfconfig->error = error;
04560 }
04561
04562
04563 static void GRFComment(ByteReader *buf)
04564 {
04565
04566
04567
04568
04569 if (!buf->HasData()) return;
04570
04571 const char *text = buf->ReadString();
04572 grfmsg(2, "GRFComment: %s", text);
04573 }
04574
04575
04576 static void SafeParamSet(ByteReader *buf)
04577 {
04578 uint8 target = buf->ReadByte();
04579
04580
04581 if (target < 0x80) return;
04582
04583
04584
04585
04586
04587
04588 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
04589
04590
04591 _skip_sprites = -1;
04592 }
04593
04594
04595 static uint32 GetPatchVariable(uint8 param)
04596 {
04597 switch (param) {
04598
04599 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
04600
04601
04602 case 0x0E: return _settings_game.vehicle.freight_trains;
04603
04604
04605 case 0x0F: return 0;
04606
04607
04608
04609
04610 case 0x10:
04611 switch (_settings_game.vehicle.plane_speed) {
04612 default:
04613 case 4: return 1;
04614 case 3: return 2;
04615 case 2: return 2;
04616 case 1: return 4;
04617 }
04618
04619
04620
04621 case 0x11: return SPR_2CCMAP_BASE;
04622
04623
04624
04625
04626
04627
04628
04629
04630
04631
04632
04633
04634 case 0x13: {
04635 byte map_bits = 0;
04636 byte log_X = MapLogX() - 6;
04637 byte log_Y = MapLogY() - 6;
04638 byte max_edge = max(log_X, log_Y);
04639
04640 if (log_X == log_Y) {
04641 SetBit(map_bits, 0);
04642 } else {
04643 if (max_edge == log_Y) SetBit(map_bits, 1);
04644 }
04645
04646 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
04647 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
04648 }
04649
04650 default:
04651 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
04652 return 0;
04653 }
04654 }
04655
04656
04657 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
04658 {
04659 uint start = 0;
04660 uint size = 0;
04661
04662 if (op == 6) {
04663
04664 return grm[_cur_grffile->GetParam(target)];
04665 }
04666
04667
04668 if (op == 2 || op == 3) start = _cur_grffile->GetParam(target);
04669
04670 for (uint i = start; i < num_ids; i++) {
04671 if (grm[i] == 0) {
04672 size++;
04673 } else {
04674 if (op == 2 || op == 3) break;
04675 start = i + 1;
04676 size = 0;
04677 }
04678
04679 if (size == count) break;
04680 }
04681
04682 if (size == count) {
04683
04684 if (op == 0 || op == 3) {
04685 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
04686 for (uint i = 0; i < count; i++) grm[start + i] = _cur_grffile->grfid;
04687 }
04688 return start;
04689 }
04690
04691
04692 if (op != 4 && op != 5) {
04693
04694 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
04695 _cur_grfconfig->status = GCS_DISABLED;
04696 ClearTemporaryNewGRFData(_cur_grffile);
04697 _skip_sprites = -1;
04698 return UINT_MAX;
04699 }
04700
04701 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
04702 return UINT_MAX;
04703 }
04704
04705
04706
04707 static void ParamSet(ByteReader *buf)
04708 {
04709
04710
04711
04712
04713
04714
04715
04716
04717
04718
04719
04720
04721
04722
04723
04724
04725
04726
04727
04728
04729
04730
04731 uint8 target = buf->ReadByte();
04732 uint8 oper = buf->ReadByte();
04733 uint32 src1 = buf->ReadByte();
04734 uint32 src2 = buf->ReadByte();
04735
04736 uint32 data = 0;
04737 if (buf->Remaining() >= 4) data = buf->ReadDWord();
04738
04739
04740
04741
04742
04743
04744
04745 if (HasBit(oper, 7)) {
04746 if (target < 0x80 && target < _cur_grffile->param_end) {
04747 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
04748 return;
04749 }
04750
04751 oper = GB(oper, 0, 7);
04752 }
04753
04754 if (src2 == 0xFE) {
04755 if (GB(data, 0, 8) == 0xFF) {
04756 if (data == 0x0000FFFF) {
04757
04758 src1 = GetPatchVariable(src1);
04759 } else {
04760
04761 uint8 op = src1;
04762 uint8 feature = GB(data, 8, 8);
04763 uint16 count = GB(data, 16, 16);
04764
04765 if (_cur_stage == GLS_RESERVE) {
04766 if (feature == 0x08) {
04767
04768 if (op == 0) {
04769
04770 if (_cur_spriteid + count >= 16384) {
04771 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
04772 _cur_grfconfig->status = GCS_DISABLED;
04773 ClearTemporaryNewGRFData(_cur_grffile);
04774 _skip_sprites = -1;
04775 return;
04776 }
04777
04778
04779 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur_spriteid);
04780 _grm_sprites[GRFLocation(_cur_grffile->grfid, _nfo_line)] = _cur_spriteid;
04781 _cur_spriteid += count;
04782 }
04783 }
04784
04785 src1 = 0;
04786 } else if (_cur_stage == GLS_ACTIVATION) {
04787 switch (feature) {
04788 case 0x00:
04789 case 0x01:
04790 case 0x02:
04791 case 0x03:
04792 if (!_settings_game.vehicle.dynamic_engines) {
04793 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
04794 if (_skip_sprites == -1) return;
04795 } else {
04796
04797 switch (op) {
04798 case 2:
04799 case 3:
04800 src1 = _cur_grffile->GetParam(target);
04801 break;
04802
04803 default:
04804 src1 = 0;
04805 break;
04806 }
04807 }
04808 break;
04809
04810 case 0x08:
04811 switch (op) {
04812 case 0:
04813
04814 src1 = _grm_sprites[GRFLocation(_cur_grffile->grfid, _nfo_line)];
04815 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
04816 break;
04817
04818 case 1:
04819 src1 = _cur_spriteid;
04820 break;
04821
04822 default:
04823 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
04824 return;
04825 }
04826 break;
04827
04828 case 0x0B:
04829
04830 src1 = PerformGRM(_grm_cargos, NUM_CARGO * 2, count, op, target, "cargos");
04831 if (_skip_sprites == -1) return;
04832 break;
04833
04834 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
04835 }
04836 } else {
04837
04838 src1 = 0;
04839 }
04840 }
04841 } else {
04842
04843 const GRFFile *file = GetFileByGRFID(data);
04844 GRFConfig *c = GetGRFConfig(data);
04845 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur_grfconfig->flags, GCF_STATIC) && _networking) {
04846
04847 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
04848 src1 = 0;
04849 } else if (file == NULL || (c != NULL && c->status == GCS_DISABLED)) {
04850 src1 = 0;
04851 } else {
04852 src1 = file->GetParam(src1);
04853 }
04854 }
04855 } else {
04856
04857
04858
04859
04860
04861 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
04862 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
04863 }
04864
04865
04866
04867
04868
04869
04870
04871 uint32 res;
04872 switch (oper) {
04873 case 0x00:
04874 res = src1;
04875 break;
04876
04877 case 0x01:
04878 res = src1 + src2;
04879 break;
04880
04881 case 0x02:
04882 res = src1 - src2;
04883 break;
04884
04885 case 0x03:
04886 res = src1 * src2;
04887 break;
04888
04889 case 0x04:
04890 res = (int32)src1 * (int32)src2;
04891 break;
04892
04893 case 0x05:
04894 if ((int32)src2 < 0) {
04895 res = src1 >> -(int32)src2;
04896 } else {
04897 res = src1 << src2;
04898 }
04899 break;
04900
04901 case 0x06:
04902 if ((int32)src2 < 0) {
04903 res = (int32)src1 >> -(int32)src2;
04904 } else {
04905 res = (int32)src1 << src2;
04906 }
04907 break;
04908
04909 case 0x07:
04910 res = src1 & src2;
04911 break;
04912
04913 case 0x08:
04914 res = src1 | src2;
04915 break;
04916
04917 case 0x09:
04918 if (src2 == 0) {
04919 res = src1;
04920 } else {
04921 res = src1 / src2;
04922 }
04923 break;
04924
04925 case 0x0A:
04926 if (src2 == 0) {
04927 res = src1;
04928 } else {
04929 res = (int32)src1 / (int32)src2;
04930 }
04931 break;
04932
04933 case 0x0B:
04934 if (src2 == 0) {
04935 res = src1;
04936 } else {
04937 res = src1 % src2;
04938 }
04939 break;
04940
04941 case 0x0C:
04942 if (src2 == 0) {
04943 res = src1;
04944 } else {
04945 res = (int32)src1 % (int32)src2;
04946 }
04947 break;
04948
04949 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
04950 }
04951
04952 switch (target) {
04953 case 0x8E:
04954 _cur_grffile->traininfo_vehicle_pitch = res;
04955 break;
04956
04957 case 0x8F: {
04958 extern RailtypeInfo _railtypes[RAILTYPE_END];
04959 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
04960 if (_settings_game.vehicle.disable_elrails) {
04961 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
04962 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
04963 } else {
04964 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
04965 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
04966 }
04967 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
04968 break;
04969 }
04970
04971
04972 case 0x93:
04973 case 0x94:
04974 case 0x95:
04975 case 0x96:
04976 case 0x97:
04977 case 0x99:
04978 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
04979 break;
04980
04981 case 0x9E:
04982 _misc_grf_features = res;
04983
04984
04985 _cur_grffile->traininfo_vehicle_width = HasGrfMiscBit(GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
04986
04987
04988 ClrBit(_misc_grf_features, GMB_TRAIN_WIDTH_32_PIXELS);
04989 break;
04990
04991 case 0x9F:
04992 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
04993 break;
04994
04995 default:
04996 if (target < 0x80) {
04997 _cur_grffile->param[target] = res;
04998
04999 if (target + 1U > _cur_grffile->param_end) _cur_grffile->param_end = target + 1;
05000 } else {
05001 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
05002 }
05003 break;
05004 }
05005 }
05006
05007
05008 static void SafeGRFInhibit(ByteReader *buf)
05009 {
05010
05011
05012
05013
05014
05015 uint8 num = buf->ReadByte();
05016
05017 for (uint i = 0; i < num; i++) {
05018 uint32 grfid = buf->ReadDWord();
05019
05020
05021 if (grfid != _cur_grfconfig->grfid) {
05022 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
05023
05024
05025 _skip_sprites = -1;
05026
05027 return;
05028 }
05029 }
05030 }
05031
05032
05033 static void GRFInhibit(ByteReader *buf)
05034 {
05035
05036
05037
05038
05039
05040 uint8 num = buf->ReadByte();
05041
05042 for (uint i = 0; i < num; i++) {
05043 uint32 grfid = buf->ReadDWord();
05044 GRFConfig *file = GetGRFConfig(grfid);
05045
05046
05047 if (file != NULL && file != _cur_grfconfig) {
05048 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
05049 file->status = GCS_DISABLED;
05050 }
05051 }
05052 }
05053
05054
05055 static void FeatureTownName(ByteReader *buf)
05056 {
05057
05058
05059
05060
05061
05062
05063
05064 uint32 grfid = _cur_grffile->grfid;
05065
05066 GRFTownName *townname = AddGRFTownName(grfid);
05067
05068 byte id = buf->ReadByte();
05069 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
05070
05071 if (HasBit(id, 7)) {
05072
05073 ClrBit(id, 7);
05074 bool new_scheme = _cur_grffile->grf_version >= 7;
05075
05076 byte lang = buf->ReadByte();
05077
05078 byte nb_gen = townname->nb_gen;
05079 do {
05080 ClrBit(lang, 7);
05081
05082 const char *name = buf->ReadString();
05083
05084 char *lang_name = TranslateTTDPatchCodes(grfid, name);
05085 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
05086 free(lang_name);
05087
05088 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, name, STR_UNDEFINED);
05089
05090 lang = buf->ReadByte();
05091 } while (lang != 0);
05092 townname->id[nb_gen] = id;
05093 townname->nb_gen++;
05094 }
05095
05096 byte nb = buf->ReadByte();
05097 grfmsg(6, "FeatureTownName: %u parts", nb);
05098
05099 townname->nbparts[id] = nb;
05100 townname->partlist[id] = CallocT<NamePartList>(nb);
05101
05102 for (int i = 0; i < nb; i++) {
05103 byte nbtext = buf->ReadByte();
05104 townname->partlist[id][i].bitstart = buf->ReadByte();
05105 townname->partlist[id][i].bitcount = buf->ReadByte();
05106 townname->partlist[id][i].maxprob = 0;
05107 townname->partlist[id][i].partcount = nbtext;
05108 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
05109 grfmsg(6, "FeatureTownName: part %d contains %d texts and will use GB(seed, %d, %d)", i, nbtext, townname->partlist[id][i].bitstart, townname->partlist[id][i].bitcount);
05110
05111 for (int j = 0; j < nbtext; j++) {
05112 byte prob = buf->ReadByte();
05113
05114 if (HasBit(prob, 7)) {
05115 byte ref_id = buf->ReadByte();
05116
05117 if (townname->nbparts[ref_id] == 0) {
05118 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
05119 DelGRFTownName(grfid);
05120 _cur_grfconfig->status = GCS_DISABLED;
05121 ClearTemporaryNewGRFData(_cur_grffile);
05122 _skip_sprites = -1;
05123 return;
05124 }
05125
05126 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
05127 townname->partlist[id][i].parts[j].data.id = ref_id;
05128 } else {
05129 const char *text = buf->ReadString();
05130 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, text);
05131 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
05132 }
05133 townname->partlist[id][i].parts[j].prob = prob;
05134 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
05135 }
05136 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
05137 }
05138 }
05139
05140
05141 static void DefineGotoLabel(ByteReader *buf)
05142 {
05143
05144
05145
05146
05147
05148 byte nfo_label = buf->ReadByte();
05149
05150 GRFLabel *label = MallocT<GRFLabel>(1);
05151 label->label = nfo_label;
05152 label->nfo_line = _nfo_line;
05153 label->pos = FioGetPos();
05154 label->next = NULL;
05155
05156
05157 if (_cur_grffile->label == NULL) {
05158 _cur_grffile->label = label;
05159 } else {
05160
05161 GRFLabel *l;
05162 for (l = _cur_grffile->label; l->next != NULL; l = l->next) {}
05163 l->next = label;
05164 }
05165
05166 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
05167 }
05168
05169
05170 static void GRFSound(ByteReader *buf)
05171 {
05172
05173
05174
05175
05176 uint16 num = buf->ReadWord();
05177
05178 _grf_data_blocks = num;
05179 _grf_data_type = GDT_SOUND;
05180
05181 if (_cur_grffile->sound_offset == 0) _cur_grffile->sound_offset = GetNumSounds();
05182 }
05183
05184
05185 static void SkipAct11(ByteReader *buf)
05186 {
05187
05188
05189
05190
05191 _skip_sprites = buf->ReadWord();
05192
05193 grfmsg(3, "SkipAct11: Skipping %d sprites", _skip_sprites);
05194 }
05195
05196 static void ImportGRFSound(ByteReader *buf)
05197 {
05198 const GRFFile *file;
05199 SoundEntry *sound = AllocateSound();
05200 uint32 grfid = buf->ReadDWord();
05201 SoundID sound_id = buf->ReadWord();
05202
05203 file = GetFileByGRFID(grfid);
05204 if (file == NULL || file->sound_offset == 0) {
05205 grfmsg(1, "ImportGRFSound: Source file not available");
05206 return;
05207 }
05208
05209 if (file->sound_offset + sound_id >= GetNumSounds()) {
05210 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
05211 return;
05212 }
05213
05214 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
05215
05216 *sound = *GetSound(file->sound_offset + sound_id);
05217
05218
05219 sound->volume = 128;
05220 sound->priority = 0;
05221 }
05222
05223
05224 static void GRFImportBlock(ByteReader *buf)
05225 {
05226 if (_grf_data_blocks == 0) {
05227 grfmsg(2, "GRFImportBlock: Unexpected import block, skipping");
05228 return;
05229 }
05230
05231 _grf_data_blocks--;
05232
05233
05234
05235 if (buf->ReadByte() != _grf_data_type) {
05236 grfmsg(1, "GRFImportBlock: Import type mismatch");
05237 }
05238
05239 switch (_grf_data_type) {
05240 case GDT_SOUND: ImportGRFSound(buf); break;
05241 default: NOT_REACHED();
05242 }
05243 }
05244
05245 static void LoadGRFSound(ByteReader *buf)
05246 {
05247
05248
05249 SoundEntry *sound = AllocateSound();
05250
05251 if (buf->ReadDWord() != BSWAP32('RIFF')) {
05252 grfmsg(1, "LoadGRFSound: Missing RIFF header");
05253 return;
05254 }
05255
05256 uint32 total_size = buf->ReadDWord();
05257 if (total_size > buf->Remaining()) {
05258 grfmsg(1, "LoadGRFSound: RIFF was truncated");
05259 return;
05260 }
05261
05262 if (buf->ReadDWord() != BSWAP32('WAVE')) {
05263 grfmsg(1, "LoadGRFSound: Invalid RIFF type");
05264 return;
05265 }
05266
05267 while (total_size >= 8) {
05268 uint32 tag = buf->ReadDWord();
05269 uint32 size = buf->ReadDWord();
05270 total_size -= 8;
05271 if (total_size < size) {
05272 grfmsg(1, "LoadGRFSound: Invalid RIFF");
05273 return;
05274 }
05275 total_size -= size;
05276
05277 switch (tag) {
05278 case ' tmf':
05279
05280 if (size < 16 || buf->ReadWord() != 1) {
05281 grfmsg(1, "LoadGRFSound: Invalid audio format");
05282 return;
05283 }
05284 sound->channels = buf->ReadWord();
05285 sound->rate = buf->ReadDWord();
05286 buf->ReadDWord();
05287 buf->ReadWord();
05288 sound->bits_per_sample = buf->ReadWord();
05289
05290
05291 size -= 16;
05292 break;
05293
05294 case 'atad':
05295 sound->file_size = size;
05296 sound->file_offset = FioGetPos() - buf->Remaining();
05297 sound->file_slot = _file_index;
05298
05299
05300 sound->volume = 0x80;
05301 sound->priority = 0;
05302
05303 grfmsg(2, "LoadGRFSound: channels %u, sample rate %u, bits per sample %u, length %u", sound->channels, sound->rate, sound->bits_per_sample, size);
05304 return;
05305
05306 default:
05307
05308 break;
05309 }
05310
05311
05312 for (; size > 0; size--) buf->ReadByte();
05313 }
05314
05315 grfmsg(1, "LoadGRFSound: RIFF does not contain any sound data");
05316
05317
05318 MemSetT(sound, 0);
05319 }
05320
05321
05322 static void LoadFontGlyph(ByteReader *buf)
05323 {
05324
05325
05326
05327
05328
05329
05330
05331 uint8 num_def = buf->ReadByte();
05332
05333 for (uint i = 0; i < num_def; i++) {
05334 FontSize size = (FontSize)buf->ReadByte();
05335 uint8 num_char = buf->ReadByte();
05336 uint16 base_char = buf->ReadWord();
05337
05338 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
05339
05340 for (uint c = 0; c < num_char; c++) {
05341 SetUnicodeGlyph(size, base_char + c, _cur_spriteid);
05342 _nfo_line++;
05343 LoadNextSprite(_cur_spriteid++, _file_index, _nfo_line);
05344 }
05345 }
05346 }
05347
05348
05349 static void SkipAct12(ByteReader *buf)
05350 {
05351
05352
05353
05354
05355
05356
05357
05358 uint8 num_def = buf->ReadByte();
05359
05360 for (uint i = 0; i < num_def; i++) {
05361
05362 buf->ReadByte();
05363
05364
05365 _skip_sprites += buf->ReadByte();
05366
05367
05368 buf->ReadWord();
05369 }
05370
05371 grfmsg(3, "SkipAct12: Skipping %d sprites", _skip_sprites);
05372 }
05373
05374
05375 static void TranslateGRFStrings(ByteReader *buf)
05376 {
05377
05378
05379
05380
05381
05382
05383
05384 uint32 grfid = buf->ReadDWord();
05385 const GRFConfig *c = GetGRFConfig(grfid);
05386 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
05387 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
05388 return;
05389 }
05390
05391 if (c->status == GCS_INITIALISED) {
05392
05393
05394 GRFError *error = CallocT<GRFError>(1);
05395
05396 char tmp[256];
05397 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
05398 error->data = strdup(tmp);
05399
05400 error->message = STR_NEWGRF_ERROR_LOAD_AFTER;
05401 error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
05402
05403 if (_cur_grfconfig->error != NULL) free(_cur_grfconfig->error);
05404 _cur_grfconfig->error = error;
05405
05406 _cur_grfconfig->status = GCS_DISABLED;
05407 ClearTemporaryNewGRFData(_cur_grffile);
05408 _skip_sprites = -1;
05409 return;
05410 }
05411
05412 byte num_strings = buf->ReadByte();
05413 uint16 first_id = buf->ReadWord();
05414
05415 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
05416 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
05417 return;
05418 }
05419
05420 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
05421 const char *string = buf->ReadString();
05422
05423 if (StrEmpty(string)) {
05424 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
05425 continue;
05426 }
05427
05428
05429
05430
05431
05432
05433 AddGRFString(grfid, first_id + i, 0x7F, true, string, STR_UNDEFINED);
05434 }
05435 }
05436
05437
05438 static void GRFDataBlock(ByteReader *buf)
05439 {
05440
05441
05442 if (_grf_data_blocks == 0) {
05443 grfmsg(2, "GRFDataBlock: unexpected data block, skipping");
05444 return;
05445 }
05446
05447 uint8 name_len = buf->ReadByte();
05448 const char *name = reinterpret_cast<const char *>(buf->Data());
05449 buf->Skip(name_len);
05450
05451
05452 if (buf->ReadByte() != 0) {
05453 grfmsg(2, "GRFDataBlock: Name not properly terminated");
05454 return;
05455 }
05456
05457 grfmsg(2, "GRFDataBlock: block name '%s'...", name);
05458
05459 _grf_data_blocks--;
05460
05461 switch (_grf_data_type) {
05462 case GDT_SOUND: LoadGRFSound(buf); break;
05463 default: NOT_REACHED();
05464 }
05465 }
05466
05467
05468
05469 static void GRFUnsafe(ByteReader *buf)
05470 {
05471 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
05472
05473
05474 _skip_sprites = -1;
05475 }
05476
05477
05478 static void InitializeGRFSpecial()
05479 {
05480 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C)
05481 | (1 << 0x0D)
05482 | (1 << 0x0E)
05483 | ((_settings_game.construction.longbridges ? 1 : 0) << 0x0F)
05484 | (0 << 0x10)
05485 | (1 << 0x12)
05486 | (1 << 0x13)
05487 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16)
05488 | (1 << 0x1B)
05489 | (1 << 0x1D)
05490 | (1 << 0x1E);
05491
05492 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07)
05493 | ((_settings_game.vehicle.mammoth_trains ? 1 : 0) << 0x08)
05494 | (1 << 0x09)
05495 | (0 << 0x0B)
05496 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C)
05497 | (1 << 0x12)
05498 | (1 << 0x13)
05499 | (1 << 0x14)
05500 | (1 << 0x16)
05501 | (1 << 0x17)
05502 | (1 << 0x18)
05503 | (1 << 0x19)
05504 | (1 << 0x1A)
05505 | ((_settings_game.construction.signal_side ? 1 : 0) << 0x1B)
05506 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C);
05507
05508 _ttdpatch_flags[2] = (1 << 0x01)
05509 | (1 << 0x03)
05510 | (0 << 0x0B)
05511 | (0 << 0x0C)
05512 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D)
05513 | (1 << 0x0E)
05514 | (1 << 0x0F)
05515 | (0 << 0x10)
05516 | (0 << 0x11)
05517 | (1 << 0x12)
05518 | (1 << 0x13)
05519 | (1 << 0x14)
05520 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15)
05521 | (1 << 0x16)
05522 | (1 << 0x17)
05523 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18)
05524 | (1 << 0x19)
05525 | (1 << 0x1A)
05526 | (1 << 0x1B)
05527 | (1 << 0x1C)
05528 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D)
05529 | (1 << 0x1E)
05530 | (0 << 0x1F);
05531
05532 _ttdpatch_flags[3] = (0 << 0x00)
05533 | (1 << 0x01)
05534 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02)
05535 | (1 << 0x03)
05536 | (0 << 0x04)
05537 | (1 << 0x05)
05538 | (1 << 0x06)
05539 | (1 << 0x07)
05540 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08)
05541 | (0 << 0x09)
05542 | (0 << 0x0A)
05543 | (1 << 0x0B)
05544 | (1 << 0x0C)
05545 | (1 << 0x0D)
05546 | ((_settings_game.station.nonuniform_stations ? 1 : 0) << 0x0E)
05547 | (1 << 0x0F)
05548 | (1 << 0x10)
05549 | (1 << 0x11)
05550 | (1 << 0x12)
05551 | (0 << 0x13)
05552 | (1 << 0x14)
05553 | (0 << 0x15)
05554 | (1 << 0x16)
05555 | (1 << 0x17)
05556 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18)
05557 | (1 << 0x1E)
05558 | (1 << 0x1F);
05559 }
05560
05561 static void ResetCustomStations()
05562 {
05563 const GRFFile * const *end = _grf_files.End();
05564 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05565 StationSpec **&stations = (*file)->stations;
05566 if (stations == NULL) continue;
05567 for (uint i = 0; i < MAX_STATIONS; i++) {
05568 if (stations[i] == NULL) continue;
05569 StationSpec *statspec = stations[i];
05570
05571
05572 if (!statspec->copied_renderdata) {
05573 for (uint t = 0; t < statspec->tiles; t++) {
05574 free((void*)statspec->renderdata[t].seq);
05575 }
05576 free(statspec->renderdata);
05577 }
05578
05579
05580 if (!statspec->copied_layouts) {
05581 for (uint l = 0; l < statspec->lengths; l++) {
05582 for (uint p = 0; p < statspec->platforms[l]; p++) {
05583 free(statspec->layouts[l][p]);
05584 }
05585 free(statspec->layouts[l]);
05586 }
05587 free(statspec->layouts);
05588 free(statspec->platforms);
05589 }
05590
05591
05592 free(statspec);
05593 }
05594
05595
05596 free(stations);
05597 stations = NULL;
05598 }
05599 }
05600
05601 static void ResetCustomHouses()
05602 {
05603 const GRFFile * const *end = _grf_files.End();
05604 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05605 HouseSpec **&housespec = (*file)->housespec;
05606 if (housespec == NULL) continue;
05607 for (uint i = 0; i < HOUSE_MAX; i++) {
05608 free(housespec[i]);
05609 }
05610
05611 free(housespec);
05612 housespec = NULL;
05613 }
05614 }
05615
05616 static void ResetCustomIndustries()
05617 {
05618 const GRFFile * const *end = _grf_files.End();
05619 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05620 IndustrySpec **&industryspec = (*file)->industryspec;
05621 IndustryTileSpec **&indtspec = (*file)->indtspec;
05622
05623
05624
05625 if (industryspec != NULL) {
05626 for (uint i = 0; i < NUM_INDUSTRYTYPES; i++) {
05627 IndustrySpec *ind = industryspec[i];
05628 if (ind == NULL) continue;
05629
05630
05631 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
05632 free((void*)ind->random_sounds);
05633 }
05634
05635
05636 if (HasBit(ind->cleanup_flag, CLEAN_TILELSAYOUT) && ind->table != NULL) {
05637 for (int j = 0; j < ind->num_table; j++) {
05638
05639 free((void*)ind->table[j]);
05640 }
05641
05642 free((void*)ind->table);
05643 ind->table = NULL;
05644 }
05645
05646 free(ind);
05647 }
05648
05649 free(industryspec);
05650 industryspec = NULL;
05651 }
05652
05653 if (indtspec == NULL) continue;
05654 for (uint i = 0; i < NUM_INDUSTRYTILES; i++) {
05655 free(indtspec[i]);
05656 }
05657
05658 free(indtspec);
05659 indtspec = NULL;
05660 }
05661 }
05662
05663 static void ResetNewGRF()
05664 {
05665 const GRFFile * const *end = _grf_files.End();
05666 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05667 GRFFile *f = *file;
05668 free(f->filename);
05669 free(f->cargo_list);
05670 free(f->railtype_list);
05671 free(f);
05672 }
05673
05674 _grf_files.Clear();
05675 _cur_grffile = NULL;
05676 }
05677
05678 static void ResetNewGRFErrors()
05679 {
05680 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
05681 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
05682 free(c->error->custom_message);
05683 free(c->error->data);
05684 free(c->error);
05685 c->error = NULL;
05686 }
05687 }
05688 }
05689
05694 static void ResetNewGRFData()
05695 {
05696 CleanUpStrings();
05697 CleanUpGRFTownNames();
05698
05699
05700 SetupEngines();
05701
05702
05703 ResetBridges();
05704
05705
05706 ResetRailTypes();
05707
05708
05709 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
05710
05711
05712 memset(&_grm_engines, 0, sizeof(_grm_engines));
05713 memset(&_grm_cargos, 0, sizeof(_grm_cargos));
05714
05715
05716 ResetGenericCallbacks();
05717
05718
05719 ResetPriceBaseMultipliers();
05720
05721
05722 ResetCurrencies();
05723
05724
05725 ResetCustomHouses();
05726 ResetHouses();
05727
05728
05729 ResetCustomIndustries();
05730 ResetIndustries();
05731
05732
05733 ResetStationClasses();
05734 ResetCustomStations();
05735
05736
05737 memset(_water_feature, 0, sizeof(_water_feature));
05738
05739
05740 ClearSnowLine();
05741
05742
05743 ResetNewGRF();
05744
05745
05746 ResetNewGRFErrors();
05747
05748
05749 SetupCargoForClimate(_settings_game.game_creation.landscape);
05750
05751
05752 _misc_grf_features = 0;
05753
05754 _loaded_newgrf_features.has_2CC = false;
05755 _loaded_newgrf_features.has_newhouses = false;
05756 _loaded_newgrf_features.has_newindustries = false;
05757 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
05758
05759
05760 _grf_id_overrides.clear();
05761
05762 InitializeSoundPool();
05763 _spritegroup_pool.CleanPool();
05764 }
05765
05766 static void BuildCargoTranslationMap()
05767 {
05768 memset(_cur_grffile->cargo_map, 0xFF, sizeof(_cur_grffile->cargo_map));
05769
05770 for (CargoID c = 0; c < NUM_CARGO; c++) {
05771 const CargoSpec *cs = CargoSpec::Get(c);
05772 if (!cs->IsValid()) continue;
05773
05774 if (_cur_grffile->cargo_max == 0) {
05775
05776 _cur_grffile->cargo_map[c] = cs->bitnum;
05777 } else {
05778
05779 for (uint i = 0; i < _cur_grffile->cargo_max; i++) {
05780 if (cs->label == _cur_grffile->cargo_list[i]) {
05781 _cur_grffile->cargo_map[c] = i;
05782 break;
05783 }
05784 }
05785 }
05786 }
05787 }
05788
05789 static void InitNewGRFFile(const GRFConfig *config, int sprite_offset)
05790 {
05791 GRFFile *newfile = GetFileByFilename(config->filename);
05792 if (newfile != NULL) {
05793
05794 newfile->sprite_offset = sprite_offset;
05795 _cur_grffile = newfile;
05796 return;
05797 }
05798
05799 newfile = CallocT<GRFFile>(1);
05800
05801 if (newfile == NULL) error ("Out of memory");
05802
05803 newfile->filename = strdup(config->filename);
05804 newfile->sprite_offset = sprite_offset;
05805
05806
05807 newfile->traininfo_vehicle_pitch = 0;
05808 newfile->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
05809
05810
05811 for (Price i = PR_BEGIN; i < PR_END; i++) {
05812 newfile->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
05813 }
05814
05815
05816 memset(newfile->railtype_map, INVALID_RAILTYPE, sizeof newfile->railtype_map);
05817 newfile->railtype_map[0] = RAILTYPE_RAIL;
05818 newfile->railtype_map[1] = RAILTYPE_ELECTRIC;
05819 newfile->railtype_map[2] = RAILTYPE_MONO;
05820 newfile->railtype_map[3] = RAILTYPE_MAGLEV;
05821
05822
05823
05824 assert_compile(lengthof(newfile->param) == lengthof(config->param) && lengthof(config->param) == 0x80);
05825 memset(newfile->param, 0, sizeof(newfile->param));
05826
05827 assert(config->num_params <= lengthof(config->param));
05828 newfile->param_end = config->num_params;
05829 if (newfile->param_end > 0) {
05830 MemCpyT(newfile->param, config->param, newfile->param_end);
05831 }
05832
05833 *_grf_files.Append() = _cur_grffile = newfile;
05834 }
05835
05836
05839 static const CargoLabel _default_refitmasks_rail[] = {
05840 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
05841 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
05842 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
05843 'PLST', 'FZDR',
05844 0 };
05845
05846 static const CargoLabel _default_refitmasks_road[] = {
05847 0 };
05848
05849 static const CargoLabel _default_refitmasks_ships[] = {
05850 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
05851 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
05852 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
05853 'PLST', 'FZDR',
05854 0 };
05855
05856 static const CargoLabel _default_refitmasks_aircraft[] = {
05857 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
05858 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
05859 0 };
05860
05861 static const CargoLabel * const _default_refitmasks[] = {
05862 _default_refitmasks_rail,
05863 _default_refitmasks_road,
05864 _default_refitmasks_ships,
05865 _default_refitmasks_aircraft,
05866 };
05867
05868
05872 static void CalculateRefitMasks()
05873 {
05874 Engine *e;
05875
05876 FOR_ALL_ENGINES(e) {
05877 EngineID engine = e->index;
05878 EngineInfo *ei = &e->info;
05879 uint32 mask = 0;
05880 uint32 not_mask = 0;
05881 uint32 xor_mask = 0;
05882
05883
05884 if (_gted[engine].refitmask_valid) {
05885 if (ei->refit_mask != 0) {
05886 const GRFFile *file = e->grffile;
05887 if (file != NULL && file->cargo_max != 0) {
05888
05889 uint num_cargo = min(32, file->cargo_max);
05890 for (uint i = 0; i < num_cargo; i++) {
05891 if (!HasBit(ei->refit_mask, i)) continue;
05892
05893 CargoID c = GetCargoIDByLabel(file->cargo_list[i]);
05894 if (c == CT_INVALID) continue;
05895
05896 SetBit(xor_mask, c);
05897 }
05898 } else {
05899
05900 const CargoSpec *cs;
05901 FOR_ALL_CARGOSPECS(cs) {
05902 if (HasBit(ei->refit_mask, cs->bitnum)) SetBit(xor_mask, cs->Index());
05903 }
05904 }
05905 }
05906
05907 if (_gted[engine].cargo_allowed != 0) {
05908
05909 const CargoSpec *cs;
05910 FOR_ALL_CARGOSPECS(cs) {
05911 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
05912 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
05913 }
05914 }
05915 } else {
05916
05917 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
05918 const CargoLabel *cl = _default_refitmasks[e->type];
05919 for (uint i = 0;; i++) {
05920 if (cl[i] == 0) break;
05921
05922 CargoID cargo = GetCargoIDByLabel(cl[i]);
05923 if (cargo == CT_INVALID) continue;
05924
05925 SetBit(xor_mask, cargo);
05926 }
05927 }
05928 }
05929
05930 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
05931
05932
05933
05934 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
05935 if (ei->cargo_type == CT_INVALID) ei->climates = 0x80;
05936
05937
05938 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) ei->refit_mask = 0;
05939 }
05940 }
05941
05946 static void FinaliseHouseArray()
05947 {
05948
05949
05950
05951
05952
05953
05954
05955
05956
05957 Year min_year = MAX_YEAR;
05958
05959 const GRFFile * const *end = _grf_files.End();
05960 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05961 HouseSpec **&housespec = (*file)->housespec;
05962 if (housespec == NULL) continue;
05963
05964 for (int i = 0; i < HOUSE_MAX; i++) {
05965 HouseSpec *hs = housespec[i];
05966
05967 if (hs == NULL) continue;
05968
05969 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? housespec[i + 1] : NULL);
05970 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? housespec[i + 2] : NULL);
05971 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? housespec[i + 3] : NULL);
05972
05973 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
05974 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
05975 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
05976 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
05977 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
05978 hs->enabled = false;
05979 DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d as multitile, but no suitable tiles follow. Disabling house.", (*file)->filename, hs->local_id);
05980 continue;
05981 }
05982
05983
05984
05985
05986 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
05987 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
05988 hs->enabled = false;
05989 DEBUG(grf, 1, "FinaliseHouseArray: %s defines multitile house %d with non-zero population on additional tiles. Disabling house.", (*file)->filename, hs->local_id);
05990 continue;
05991 }
05992
05993 _house_mngr.SetEntitySpec(hs);
05994 if (hs->min_year < min_year) min_year = hs->min_year;
05995 }
05996 }
05997
05998 if (min_year != 0) {
05999 for (int i = 0; i < HOUSE_MAX; i++) {
06000 HouseSpec *hs = HouseSpec::Get(i);
06001
06002 if (hs->enabled && hs->min_year == min_year) hs->min_year = 0;
06003 }
06004 }
06005 }
06006
06010 static void FinaliseIndustriesArray()
06011 {
06012 const GRFFile * const *end = _grf_files.End();
06013 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
06014 IndustrySpec **&industryspec = (*file)->industryspec;
06015 IndustryTileSpec **&indtspec = (*file)->indtspec;
06016 if (industryspec != NULL) {
06017 for (int i = 0; i < NUM_INDUSTRYTYPES; i++) {
06018 IndustrySpec *indsp = industryspec[i];
06019
06020 if (indsp != NULL && indsp->enabled) {
06021 StringID strid;
06022
06023
06024
06025 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
06026 if (strid != STR_UNDEFINED) indsp->name = strid;
06027
06028 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
06029 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
06030
06031 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
06032 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
06033
06034 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
06035 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
06036
06037 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
06038 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
06039
06040 if (indsp->station_name != STR_NULL) {
06041
06042
06043 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
06044 if (strid != STR_UNDEFINED) indsp->station_name = strid;
06045 }
06046
06047 _industry_mngr.SetEntitySpec(indsp);
06048 _loaded_newgrf_features.has_newindustries = true;
06049 }
06050 }
06051 }
06052
06053 if (indtspec != NULL) {
06054 for (int i = 0; i < NUM_INDUSTRYTILES; i++) {
06055 IndustryTileSpec *indtsp = indtspec[i];
06056 if (indtsp != NULL) {
06057 _industile_mngr.SetEntitySpec(indtsp);
06058 }
06059 }
06060 }
06061 }
06062
06063 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
06064 IndustrySpec *indsp = &_industry_specs[j];
06065 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
06066 for (uint i = 0; i < 3; i++) {
06067 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
06068 }
06069 }
06070 }
06071 }
06072
06073
06074
06075
06076
06077
06078
06079 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
06080 {
06081
06082
06083
06084
06085
06086
06087
06088
06089
06090
06091
06092
06093 static const SpecialSpriteHandler handlers[][GLS_END] = {
06094 { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
06095 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
06096 { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
06097 { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
06098 { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
06099 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
06100 { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
06101 { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
06102 { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
06103 { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
06104 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
06105 { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
06106 { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
06107 { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
06108 { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
06109 { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
06110 { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
06111 { SkipAct11,GRFUnsafe, SkipAct11, SkipAct11, SkipAct11, GRFSound, },
06112 { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
06113 { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
06114 };
06115
06116 GRFLocation location(_cur_grfconfig->grfid, _nfo_line);
06117
06118 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
06119 if (it == _grf_line_to_action6_sprite_override.end()) {
06120
06121
06122 FioReadBlock(buf, num);
06123 } else {
06124
06125 buf = _grf_line_to_action6_sprite_override[location];
06126 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
06127
06128
06129 FioSeekTo(num, SEEK_CUR);
06130 }
06131
06132 ByteReader br(buf, buf + num);
06133 ByteReader *bufp = &br;
06134
06135 try {
06136 byte action = bufp->ReadByte();
06137
06138 if (action == 0xFF) {
06139 grfmsg(7, "DecodeSpecialSprite: Handling data block in stage %d", stage);
06140 GRFDataBlock(bufp);
06141 } else if (action == 0xFE) {
06142 grfmsg(7, "DecodeSpecialSprite: Handling import block in stage %d", stage);
06143 GRFImportBlock(bufp);
06144 } else if (action >= lengthof(handlers)) {
06145 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
06146 } else if (handlers[action][stage] == NULL) {
06147 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
06148 } else {
06149 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
06150 handlers[action][stage](bufp);
06151 }
06152 } catch (...) {
06153 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
06154
06155 _skip_sprites = -1;
06156 _cur_grfconfig->status = GCS_DISABLED;
06157 _cur_grfconfig->error = CallocT<GRFError>(1);
06158 _cur_grfconfig->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
06159 _cur_grfconfig->error->message = STR_NEWGRF_ERROR_READ_BOUNDS;
06160 }
06161 }
06162
06163
06164 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage)
06165 {
06166 const char *filename = config->filename;
06167 uint16 num;
06168
06169
06170
06171
06172
06173
06174
06175
06176
06177
06178 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
06179 _cur_grffile = GetFileByFilename(filename);
06180 if (_cur_grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
06181 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
06182 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
06183 _cur_grffile->is_ottdfile = config->IsOpenTTDBaseGRF();
06184 }
06185
06186 if (file_index > LAST_GRF_SLOT) {
06187 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
06188 config->status = GCS_DISABLED;
06189 config->error = CallocT<GRFError>(1);
06190 config->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
06191 config->error->message = STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED;
06192 return;
06193 }
06194
06195 FioOpenFile(file_index, filename);
06196 _file_index = file_index;
06197 _palette_remap_grf[_file_index] = (config->windows_paletted != (_use_palette == PAL_WINDOWS));
06198
06199 _cur_grfconfig = config;
06200
06201 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
06202
06203
06204
06205
06206 if (FioReadWord() == 4 && FioReadByte() == 0xFF) {
06207 FioReadDword();
06208 } else {
06209 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
06210 return;
06211 }
06212
06213 _skip_sprites = 0;
06214 _nfo_line = 0;
06215
06216 ReusableBuffer<byte> buf;
06217
06218 while ((num = FioReadWord()) != 0) {
06219 byte type = FioReadByte();
06220 _nfo_line++;
06221
06222 if (type == 0xFF) {
06223 if (_skip_sprites == 0) {
06224 DecodeSpecialSprite(buf.Allocate(num), num, stage);
06225
06226
06227 if (_skip_sprites == -1) break;
06228
06229 continue;
06230 } else {
06231 FioSkipBytes(num);
06232 }
06233 } else {
06234 if (_skip_sprites == 0) {
06235 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
06236 config->status = GCS_DISABLED;
06237 config->error = CallocT<GRFError>(1);
06238 config->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
06239 config->error->message = STR_NEWGRF_ERROR_UNEXPECTED_SPRITE;
06240 break;
06241 }
06242
06243 FioSkipBytes(7);
06244 SkipSpriteData(type, num - 8);
06245 }
06246
06247 if (_skip_sprites > 0) _skip_sprites--;
06248 }
06249 }
06250
06258 static void ActivateOldShore()
06259 {
06260
06261
06262 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
06263
06264 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
06265 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1);
06266 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2);
06267 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3);
06268 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4);
06269 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6);
06270 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8);
06271 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9);
06272 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12);
06273 }
06274
06275 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
06276 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0);
06277 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5);
06278 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7);
06279 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10);
06280 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11);
06281 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13);
06282 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14);
06283 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15);
06284
06285
06286
06287 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16);
06288 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17);
06289 }
06290 }
06291
06295 static void FinalisePriceBaseMultipliers()
06296 {
06297 extern const PriceBaseSpec _price_base_specs[];
06298 static const uint32 override_features = (1 << GSF_TRAIN) | (1 << GSF_ROAD) | (1 << GSF_SHIP) | (1 << GSF_AIRCRAFT);
06299
06300
06301 int num_grfs = _grf_files.Length();
06302 int *grf_overrides = AllocaM(int, num_grfs);
06303 for (int i = 0; i < num_grfs; i++) {
06304 grf_overrides[i] = -1;
06305
06306 GRFFile *source = _grf_files[i];
06307 uint32 override = _grf_id_overrides[source->grfid];
06308 if (override == 0) continue;
06309
06310 GRFFile *dest = GetFileByGRFID(override);
06311 if (dest == NULL) continue;
06312
06313 grf_overrides[i] = _grf_files.FindIndex(dest);
06314 assert(grf_overrides[i] >= 0);
06315 }
06316
06317
06318 for (int i = 0; i < num_grfs; i++) {
06319 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
06320 GRFFile *source = _grf_files[i];
06321 GRFFile *dest = _grf_files[grf_overrides[i]];
06322
06323 uint32 features = (source->grf_features | dest->grf_features) & override_features;
06324 source->grf_features |= features;
06325 dest->grf_features |= features;
06326
06327 for (Price p = PR_BEGIN; p < PR_END; p++) {
06328
06329 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
06330 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
06331 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
06332 }
06333 }
06334
06335
06336 for (int i = num_grfs - 1; i >= 0; i--) {
06337 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
06338 GRFFile *source = _grf_files[i];
06339 GRFFile *dest = _grf_files[grf_overrides[i]];
06340
06341 uint32 features = (source->grf_features | dest->grf_features) & override_features;
06342 source->grf_features |= features;
06343 dest->grf_features |= features;
06344
06345 for (Price p = PR_BEGIN; p < PR_END; p++) {
06346
06347 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
06348 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
06349 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
06350 }
06351 }
06352
06353
06354 for (int i = 0; i < num_grfs; i++) {
06355 if (grf_overrides[i] < 0) continue;
06356 GRFFile *source = _grf_files[i];
06357 GRFFile *dest = _grf_files[grf_overrides[i]];
06358
06359 uint32 features = (source->grf_features | dest->grf_features) & override_features;
06360 source->grf_features |= features;
06361 dest->grf_features |= features;
06362
06363 for (Price p = PR_BEGIN; p < PR_END; p++) {
06364 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
06365 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
06366 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
06367 }
06368 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
06369 }
06370 }
06371
06372
06373 const GRFFile * const *end = _grf_files.End();
06374 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
06375 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
06376 for (Price p = PR_BEGIN; p < PR_END; p++) {
06377 Price fallback_price = _price_base_specs[p].fallback_price;
06378 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
06379
06380
06381 price_base_multipliers[p] = price_base_multipliers[fallback_price];
06382 }
06383 }
06384 }
06385
06386
06387 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
06388 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
06389 for (Price p = PR_BEGIN; p < PR_END; p++) {
06390 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
06391
06392 price_base_multipliers[p] = 0;
06393 } else {
06394 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
06395
06396
06397 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
06398 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
06399 price_base_multipliers[p] = 0;
06400 } else {
06401 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
06402 }
06403 }
06404 }
06405 }
06406 }
06407
06408 void InitDepotWindowBlockSizes();
06409
06410 extern void InitGRFTownGeneratorNames();
06411
06412 static void AfterLoadGRFs()
06413 {
06414 for (StringIDToGRFIDMapping::iterator it = _string_to_grf_mapping.begin(); it != _string_to_grf_mapping.end(); it++) {
06415 *((*it).first) = MapGRFStringID((*it).second, *((*it).first));
06416 }
06417 _string_to_grf_mapping.clear();
06418
06419
06420 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
06421 free((*it).second);
06422 }
06423 _grf_line_to_action6_sprite_override.clear();
06424
06425
06426 CalculateRefitMasks();
06427
06428
06429 InitDepotWindowBlockSizes();
06430
06431
06432 FinaliseHouseArray();
06433
06434
06435 FinaliseIndustriesArray();
06436
06437
06438 BuildIndustriesLegend();
06439
06440
06441 InitGRFTownGeneratorNames();
06442
06443
06444 CommitVehicleListOrderChanges();
06445
06446
06447 ActivateOldShore();
06448
06449 Engine *e;
06450 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
06451 if (_gted[e->index].rv_max_speed != 0) {
06452
06453 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
06454 }
06455 }
06456
06457 SetYearEngineAgingStops();
06458
06459 FinalisePriceBaseMultipliers();
06460
06461
06462 free(_gted);
06463 _grm_sprites.clear();
06464 }
06465
06466 void LoadNewGRF(uint load_index, uint file_index)
06467 {
06468
06469
06470
06471
06472 Date date = _date;
06473 Year year = _cur_year;
06474 DateFract date_fract = _date_fract;
06475 uint16 tick_counter = _tick_counter;
06476 byte display_opt = _display_opt;
06477
06478 if (_networking) {
06479 _cur_year = _settings_game.game_creation.starting_year;
06480 _date = ConvertYMDToDate(_cur_year, 0, 1);
06481 _date_fract = 0;
06482 _tick_counter = 0;
06483 _display_opt = 0;
06484 }
06485
06486 InitializeGRFSpecial();
06487
06488 ResetNewGRFData();
06489
06490
06491
06492
06493
06494
06495
06496
06497 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
06498 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
06499 }
06500
06501 _cur_spriteid = load_index;
06502
06503
06504
06505
06506 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
06507
06508
06509 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
06510 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
06511 }
06512
06513 uint slot = file_index;
06514
06515 _cur_stage = stage;
06516 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
06517 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
06518 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
06519
06520 if (!FioCheckFileExists(c->filename)) {
06521 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
06522 c->status = GCS_NOT_FOUND;
06523 continue;
06524 }
06525
06526 if (stage == GLS_LABELSCAN) InitNewGRFFile(c, _cur_spriteid);
06527 LoadNewGRFFile(c, slot++, stage);
06528 if (stage == GLS_RESERVE) {
06529 SetBit(c->flags, GCF_RESERVED);
06530 } else if (stage == GLS_ACTIVATION) {
06531 ClrBit(c->flags, GCF_RESERVED);
06532 assert(GetFileByGRFID(c->grfid) == _cur_grffile);
06533 ClearTemporaryNewGRFData(_cur_grffile);
06534 BuildCargoTranslationMap();
06535 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur_spriteid);
06536 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
06537
06538 ClearTemporaryNewGRFData(_cur_grffile);
06539 }
06540 }
06541 }
06542
06543
06544 AfterLoadGRFs();
06545
06546
06547 _cur_year = year;
06548 _date = date;
06549 _date_fract = date_fract;
06550 _tick_counter = tick_counter;
06551 _display_opt = display_opt;
06552 }
06553
06554 bool HasGrfMiscBit(GrfMiscBit bit)
06555 {
06556 return HasBit(_misc_grf_features, bit);
06557 }